Skip to content
This repository was archived by the owner on Mar 19, 2025. It is now read-only.

Commit 4a0657c

Browse files
committed
apply Debian-provided fix for glutTimerFunc - fix #10
1 parent 4edea62 commit 4a0657c

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

Changes

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
- fix header clash on MacOS (#11) - thanks @deriamis
2+
- apply Debian-provided fix for glutTimerFunc (#10) - thanks @kevinxie4c for report, Thomas Kremer for fix
23

34
0.72 2022-01-09
45
- re-enable glutCloseFunc

GLUT.xs

+36-2
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,27 @@ static void generic_glut_Close_handler(void)
484484
DO_perl_call_sv(handler, G_DISCARD);
485485
}
486486

487+
/* glut_timer_handlers is an allocation buffer.
488+
All unused elements are SVivs forming a linked-list,
489+
starting at glut_timer_handlers_next_free.
490+
The end of the list is marked by a -1.
491+
If no element is free when one is needed, the buffer will grow.
492+
*/
493+
static AV * glut_timer_handlers = 0;
494+
static int glut_timer_handlers_next_free = -1;
495+
487496
/* Callback for glutTimerFunc */
488497
static void generic_glut_timer_handler(int value)
489498
{
490-
AV * handler_data = (AV*)value;
499+
if (!glut_timer_handlers)
500+
croak("Timer handler called, but no timers have ever been set up");
501+
SV** h = av_fetch(glut_timer_handlers,value,FALSE);
502+
if (!h || !SvOK(*h) || !SvROK(*h))
503+
croak("Timer handler called for unregistered timer");
504+
AV * handler_data = (AV*)SvRV(*h);
505+
sv_setiv(*h,glut_timer_handlers_next_free);
506+
glut_timer_handlers_next_free = value;
507+
491508
SV * handler;
492509
int i;
493510
dSP;
@@ -1081,7 +1098,24 @@ glutTimerFunc(msecs, handler=0, ...)
10811098

10821099
PackCallbackST(handler_data, 1);
10831100

1084-
glutTimerFunc(msecs, generic_glut_timer_handler, (int)handler_data);
1101+
SV * handler_data_sv = newRV_inc((SV*)handler_data);
1102+
1103+
if (!glut_timer_handlers)
1104+
glut_timer_handlers = newAV();
1105+
1106+
int handler_id = glut_timer_handlers_next_free;
1107+
if (handler_id == -1) {
1108+
handler_id = ((int) av_len(glut_timer_handlers))+1;
1109+
if (handler_id < 0)
1110+
croak("Limit of concurrent timers reached (MAX_INT)");
1111+
av_push(glut_timer_handlers, handler_data_sv);
1112+
} else {
1113+
SV** entry = av_fetch(glut_timer_handlers,handler_id,FALSE);
1114+
glut_timer_handlers_next_free = SvIV(*entry);
1115+
sv_setsv(*entry,sv_2mortal(handler_data_sv));
1116+
}
1117+
1118+
glutTimerFunc(msecs, generic_glut_timer_handler, handler_id);
10851119
}
10861120
ENSURE_callback_thread;}
10871121

0 commit comments

Comments
 (0)