# New Ticket Created by Geoffrey Broadwell
# Please include the string: [perl #53802]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=53802 >
The attached patch mainly cleans up the implementation of GLUT
callbacks, simplifying code both internally and in the PIR-visible API.
It also includes two other small cleanups in the OpenGL code:
1. a missing libglutcb build dependency that may fix a 'make -j2'
problem on Mac OS X, as per tetragon
2. use the 'die string' opcode rather than a manually generated
string exception in OpenGL.pir, as per pmichaud
-'f
=== config/gen/call_list/opengl.in
==================================================================
--- config/gen/call_list/opengl.in (revision 5082)
+++ config/gen/call_list/opengl.in (local)
@@ -1,7 +1,7 @@
# Used by OpenGL (including GLU and GLUT)
v 3p
-v PP
-v PPi
-v PPii
+v JP
+v JPi
+v JPii
v fff
v ffff
=== config/gen/makefiles/root.in
==================================================================
--- config/gen/makefiles/root.in (revision 5082)
+++ config/gen/makefiles/root.in (local)
@@ -2185,7 +2185,7 @@
@[EMAIL PROTECTED]@ $(SRC_DIR)/nci_test$(O) $(C_LIBS)
# for use by runtime/parrot/library/OpenGL.pir
-$(LIBGLUTCB_SO): $(SRC_DIR)/glut_callbacks$(O)
+$(LIBGLUTCB_SO): $(LIBPARROT) $(SRC_DIR)/glut_callbacks$(O)
$(LD) $(LD_LOAD_FLAGS) @ncilib_link_extra@ $(LDFLAGS) \
@[EMAIL PROTECTED]@ $(SRC_DIR)/glut_callbacks$(O) $(C_LIBS)
=== config/gen/opengl.pm
==================================================================
--- config/gen/opengl.pm (revision 5082)
+++ config/gen/opengl.pm (local)
@@ -251,8 +251,8 @@
foreach (@callbacks) {
$enums .= " $_->{enum},\n";
- $thunks .= " void $_->{thunk}($_->{proto});\n";
- $reg_funcs .= "PARROT_API void $_->{glutcb}(PMC *, PMC *);\n";
+ $thunks .= " void $_->{thunk}($_->{proto});\n";
+ $reg_funcs .= "PARROT_API void $_->{glutcb}(Parrot_Interp, PMC *);\n";
}
my $header = <<HEADER;
@@ -299,49 +299,36 @@
} GLUT_CALLBACKS;
typedef struct GLUT_CB_data {
- PMC *sub;
- PMC *interp_pmc;
+ Parrot_Interp interp;
+ PMC *sub;
} GLUT_CB_data;
GLUT_CB_data callback_data[GLUT_NUM_CALLBACKS];
- Parrot_Interp verify_safe(PMC *, PMC *);
- void check_notnull_cb(PMC *, PMC *);
+ int is_safe(Parrot_Interp, PMC *);
- void glut_timer_func(int);
-PARROT_API void glutcbTimerFunc(PMC *, PMC *, unsigned int, int);
+ void glut_timer_func(int);
+PARROT_API void glutcbTimerFunc(Parrot_Interp, PMC *, unsigned int, int);
#if GLUT_API_VERSION >= 4
- void glut_joystick_func(unsigned int, int, int, int);
-PARROT_API void glutcbJoystickFunc(PMC *, PMC *, int);
+ void glut_joystick_func(unsigned int, int, int, int);
+PARROT_API void glutcbJoystickFunc(Parrot_Interp, PMC *, int);
#endif
$thunks
$reg_funcs
-/* Never store a null interp in callback_data */
-void
-check_notnull_cb(PMC *interp_pmc, PMC *sub)
+/* Make sure that interp and sub are sane before running callback sub */
+/* XXXX: Should this do the moral equivalent of PANIC? */
+int
+is_safe(PARROT_INTERP, PMC *sub)
{
- if (PMC_IS_NULL(interp_pmc) || (Parrot_Interp) PMC_data(interp_pmc) == NULL)
- PANIC((Parrot_Interp) PMC_data(interp_pmc),
- "cannot register callback with null interpreter");
-}
-
-
-/* PANIC before running callback sub if interp or sub are insane;
- return unwrapped Parrot_Interp if everything OK */
-Parrot_Interp
-verify_safe(PMC *interp_pmc, PMC *sub)
-{
- Parrot_Interp interp = (Parrot_Interp) PMC_data(interp_pmc);
-
/* XXXX: Verify that interp still exists */
/* XXXX: Verify that sub exists in interp */
-
- return PMC_IS_NULL(sub) ? NULL : interp;
+
+ return PMC_IS_NULL(sub) ? 0 : 1;
}
@@ -351,7 +338,7 @@
# special timer-related arguments that do not follow the template of all
# of the other GLUT callbacks
-=item C<void glutcbTimerFunc(interp_pmc, sub, milliseconds, data)>
+=item C<void glutcbTimerFunc(PARROT_INTERP, sub, milliseconds, data)>
Register a Sub PMC to handle GLUT Timer callbacks.
@@ -362,24 +349,20 @@
void
glut_timer_func(int data)
{
- PMC *sub = callback_data[GLUT_CB_TIMER].sub;
- PMC *interp_pmc = callback_data[GLUT_CB_TIMER].interp_pmc;
+ Parrot_Interp interp = callback_data[GLUT_CB_TIMER].interp;
+ PMC *sub = callback_data[GLUT_CB_TIMER].sub;
- Parrot_Interp interp = verify_safe(interp_pmc, sub);
-
- if (interp)
+ if (is_safe(interp, sub))
Parrot_runops_fromc_args_event(interp, sub, "vi", data);
}
PARROT_API
void
-glutcbTimerFunc(PMC *interp_pmc, PMC *sub, unsigned int milliseconds, int data)
+glutcbTimerFunc(PARROT_INTERP, PMC *sub, unsigned int milliseconds, int data)
{
- check_notnull_cb(interp_pmc, sub);
+ callback_data[GLUT_CB_TIMER].interp = interp;
+ callback_data[GLUT_CB_TIMER].sub = sub;
- callback_data[GLUT_CB_TIMER].sub = sub;
- callback_data[GLUT_CB_TIMER].interp_pmc = interp_pmc;
-
if (sub == PMCNULL)
glutTimerFunc(0, NULL, 0);
else
@@ -390,7 +373,7 @@
#if GLUT_API_VERSION >= 4
/*
-=item C<void glutcbJoystickFunc(interp_pmc, sub, pollinterval)>
+=item C<void glutcbJoystickFunc(PARROT_INTERP, sub, pollinterval)>
Register a Sub PMC to handle GLUT Joystick callbacks.
@@ -401,31 +384,26 @@
void
glut_joystick_func(unsigned int buttons, int xaxis, int yaxis, int zaxis)
{
- PMC *sub = callback_data[GLUT_CB_JOYSTICK].sub;
- PMC *interp_pmc = callback_data[GLUT_CB_JOYSTICK].interp_pmc;
+ Parrot_Interp interp = callback_data[GLUT_CB_JOYSTICK].interp;
+ PMC *sub = callback_data[GLUT_CB_JOYSTICK].sub;
- Parrot_Interp interp = verify_safe(interp_pmc, sub);
-
- if (interp)
+ if (is_safe(interp, sub))
Parrot_runops_fromc_args_event(interp, sub, "viiii", buttons, xaxis, yaxis, zaxis);
}
PARROT_API
void
-glutcbJoystickFunc(PMC *interp_pmc, PMC *sub, int pollinterval)
+glutcbJoystickFunc(PARROT_INTERP, PMC *sub, int pollinterval)
{
- check_notnull_cb(interp_pmc, sub);
+ callback_data[GLUT_CB_JOYSTICK].interp = interp;
+ callback_data[GLUT_CB_JOYSTICK].sub = sub;
- callback_data[GLUT_CB_JOYSTICK].sub = sub;
- callback_data[GLUT_CB_JOYSTICK].interp_pmc = interp_pmc;
-
if (sub == PMCNULL)
glutJoystickFunc(NULL, 0);
else
glutJoystickFunc(glut_joystick_func, pollinterval);
}
#endif
-
HEADER
@@ -435,7 +413,7 @@
/*
-=item C<void $_->{glutcb}(interp_pmc, sub)>
+=item C<void $_->{glutcb}(PARROT_INTERP, sub)>
Register a Sub PMC to handle GLUT $_->{friendly} callbacks.
@@ -446,24 +424,20 @@
void
$_->{thunk}($_->{params})
{
- PMC *sub = callback_data[$_->{enum}].sub;
- PMC *interp_pmc = callback_data[$_->{enum}].interp_pmc;
+ Parrot_Interp interp = callback_data[$_->{enum}].interp;
+ PMC *sub = callback_data[$_->{enum}].sub;
- Parrot_Interp interp = verify_safe(interp_pmc, sub);
-
- if (interp)
+ if (is_safe(interp, sub))
Parrot_runops_fromc_args_event(interp, sub, "$_->{sig}"$_->{args});
}
PARROT_API
void
-$_->{glutcb}(PMC *interp_pmc, PMC *sub)
+$_->{glutcb}(PARROT_INTERP, PMC *sub)
{
- check_notnull_cb(interp_pmc, sub);
+ callback_data[$_->{enum}].interp = interp;
+ callback_data[$_->{enum}].sub = sub;
- callback_data[$_->{enum}].sub = sub;
- callback_data[$_->{enum}].interp_pmc = interp_pmc;
-
if (sub == PMCNULL)
$_->{glut}(NULL);
else
=== examples/opengl/triangle.pir
==================================================================
--- examples/opengl/triangle.pir (revision 5082)
+++ examples/opengl/triangle.pir (local)
@@ -55,15 +55,12 @@
window = glutCreateWindow('Test')
set_global 'glut_window', window
- .local pmc interp
- interp = getinterp
-
.const .Sub draw = 'draw'
.const .Sub idle = 'idle'
.const .Sub keyboard = 'keyboard'
- glutcbDisplayFunc (interp, draw)
- glutcbIdleFunc (interp, idle)
- glutcbKeyboardFunc(interp, keyboard)
+ glutcbDisplayFunc (draw)
+ glutcbIdleFunc (idle)
+ glutcbKeyboardFunc(keyboard)
.local pmc rotating
rotating = new 'Integer'
=== runtime/parrot/library/OpenGL.pir
==================================================================
--- runtime/parrot/library/OpenGL.pir (revision 5082)
+++ runtime/parrot/library/OpenGL.pir (local)
@@ -115,11 +115,7 @@
message = 'Could not find a suitable '
message .= friendly_name
message .= ' shared library!'
-
- .local pmc exception
- exception = new 'Exception'
- exception['_message'] = message
- throw exception
+ die message
.end
@@ -204,63 +200,63 @@
.local pmc glutcb_funcs
glutcb_funcs = new 'ResizableStringArray'
push glutcb_funcs, 'glutcbCloseFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbDisplayFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbIdleFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbMenuDestroyFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbOverlayDisplayFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbWMCloseFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbEntryFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbMenuStateFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbVisibilityFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbWindowStatusFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbButtonBoxFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbDialsFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbMotionFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbPassiveMotionFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbReshapeFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbSpaceballButtonFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbTabletMotionFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbKeyboardFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbKeyboardUpFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbMenuStatusFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbSpaceballMotionFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbSpaceballRotateFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbSpecialFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbSpecialUpFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbMouseFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbMouseWheelFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbTabletButtonFunc'
- push glutcb_funcs, 'vPP'
+ push glutcb_funcs, 'vJP'
push glutcb_funcs, 'glutcbTimerFunc'
- push glutcb_funcs, 'vPPii'
+ push glutcb_funcs, 'vJPii'
push glutcb_funcs, 'glutcbJoystickFunc'
- push glutcb_funcs, 'vPPi'
+ push glutcb_funcs, 'vJPi'
.return (glutcb_funcs)
.end