X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_callbacks.c;h=4f6ad86ce38772ebe2c2b379c9aa25f031bee7e8;hb=18b1e0286e6a2a23b05a1955f5fe99f61ebfa2a8;hp=da06283cd91cc101d519677ce2a4eaaf8c9024e1;hpb=cbca8ac9cefa125bd877871b9236845d1262263e;p=freeglut diff --git a/src/freeglut_callbacks.c b/src/freeglut_callbacks.c index da06283..4f6ad86 100644 --- a/src/freeglut_callbacks.c +++ b/src/freeglut_callbacks.c @@ -25,39 +25,32 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define G_LOG_DOMAIN "freeglut-callbacks" - -#include "../include/GL/freeglut.h" +#include #include "freeglut_internal.h" - /* -- INTERFACE FUNCTIONS -------------------------------------------------- */ /* * All of the callbacks setting methods can be generalized to this: */ -#define SET_CALLBACK(a) if( fgStructure.Window == NULL ) return;\ - fgStructure.Window->Callbacks.a = callback; +#define SET_CALLBACK(a) \ +do \ +{ \ + if( fgStructure.CurrentWindow == NULL ) \ + return; \ + SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \ +} while( 0 ) /* * Sets the Display callback for the current window */ void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" ); if( !callback ) - fgError ("Fatal error in program. NULL display callback not " - "permitted in GLUT 3.0+ or freeglut 2.0.1+\n"); + fgError( "Fatal error in program. NULL display callback not " + "permitted in GLUT 3.0+ or freeglut 2.0.1+" ); SET_CALLBACK( Display ); - - /* - * Force a redisplay with the new callback - */ - fgStructure.Window->State.Redisplay = TRUE; - } /* @@ -65,14 +58,17 @@ void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ) */ void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" ); SET_CALLBACK( Reshape ); } /* * Sets the Keyboard callback for the current window */ -void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ) +void FGAPIENTRY glutKeyboardFunc( void (* callback) + ( unsigned char, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardFunc" ); SET_CALLBACK( Keyboard ); } @@ -81,6 +77,7 @@ void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ) */ void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialFunc" ); SET_CALLBACK( Special ); } @@ -89,64 +86,62 @@ void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ) */ void FGAPIENTRY glutIdleFunc( void (* callback)( void ) ) { - freeglut_assert_ready; - - /* - * The global idle callback pointer is stored in fgState structure - */ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" ); fgState.IdleCallback = callback; } /* * Sets the Timer callback for the current window */ -void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ), int timerID ) +void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ), + int timerID ) { - SFG_Timer* timer; + SFG_Timer *timer, *node; - freeglut_assert_ready; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" ); - /* - * Create a new freeglut timer hook structure - */ - timer = (SFG_Timer *)calloc( sizeof(SFG_Timer), 1 ); + if( (timer = fgState.FreeTimers.Last) ) + { + fgListRemove( &fgState.FreeTimers, &timer->Node ); + } + else + { + if( ! (timer = malloc(sizeof(SFG_Timer))) ) + fgError( "Fatal error: " + "Memory allocation failure in glutTimerFunc()" ); + } - /* - * Remember the callback address and timer hook's ID - */ timer->Callback = callback; timer->ID = timerID; - - /* - * When will the time out happen (in terms of window's timer) - */ timer->TriggerTime = fgElapsedTime() + timeOut; - /* - * Have the new hook attached to the current window - */ - fgListAppend( &fgState.Timers, &timer->Node ); + for( node = fgState.Timers.First; node; node = node->Node.Next ) + { + if( node->TriggerTime > timer->TriggerTime ) + break; + } + + fgListInsert( &fgState.Timers, &node->Node, &timer->Node ); } /* * Sets the Visibility callback for the current window. - * - * I had to peer to GLUT sources to clean up the mess. - * Can anyone please explain me what is going on here?!? */ static void fghVisibility( int status ) { - freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Window != NULL ); - freeglut_return_if_fail( fgStructure.Window->Callbacks.Visibility != NULL ); + int glut_status = GLUT_VISIBLE; - if( status == GLUT_HIDDEN || status == GLUT_FULLY_COVERED ) - fgStructure.Window->Callbacks.Visibility( GLUT_NOT_VISIBLE ); - else - fgStructure.Window->Callbacks.Visibility( GLUT_VISIBLE ); + FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Visibility Callback" ); + freeglut_return_if_fail( fgStructure.CurrentWindow ); + + if( ( GLUT_HIDDEN == status ) || ( GLUT_FULLY_COVERED == status ) ) + glut_status = GLUT_NOT_VISIBLE; + INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( glut_status ) ); } void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" ); SET_CALLBACK( Visibility ); if( callback ) @@ -158,8 +153,10 @@ void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ) /* * Sets the keyboard key release callback for the current window */ -void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) ) +void FGAPIENTRY glutKeyboardUpFunc( void (* callback) + ( unsigned char, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardUpFunc" ); SET_CALLBACK( KeyboardUp ); } @@ -168,31 +165,37 @@ void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) */ void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialUpFunc" ); SET_CALLBACK( SpecialUp ); } /* * Sets the joystick callback and polling rate for the current window */ -void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval ) +void FGAPIENTRY glutJoystickFunc( void (* callback) + ( unsigned int, int, int, int ), + int pollInterval ) { - SET_CALLBACK( Joystick ); + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" ); + fgInitialiseJoysticks (); + + if ( ( ( fgStructure.CurrentWindow->State.JoystickPollRate < 0 ) || + !FETCH_WCB(*fgStructure.CurrentWindow,Joystick) ) && /* Joystick callback was disabled */ + ( callback && ( pollInterval >= 0 ) ) ) /* but is now enabled */ + ++fgState.NumActiveJoysticks; + else if ( ( ( fgStructure.CurrentWindow->State.JoystickPollRate >= 0 ) && + FETCH_WCB(*fgStructure.CurrentWindow,Joystick) ) && /* Joystick callback was enabled */ + ( !callback || ( pollInterval < 0 ) ) ) /* but is now disabled */ + --fgState.NumActiveJoysticks; - freeglut_return_if_fail( fgStructure.Window != NULL ); - - /* - * Do not forget setting the joystick poll rate - */ - fgStructure.Window->State.JoystickPollRate = pollInterval; + SET_CALLBACK( Joystick ); + fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval; - /* - * Make sure the joystick polling routine gets called as early as possible: - */ - fgStructure.Window->State.JoystickLastPoll = - fgElapsedTime() - fgStructure.Window->State.JoystickPollRate; + fgStructure.CurrentWindow->State.JoystickLastPoll = + fgElapsedTime() - fgStructure.CurrentWindow->State.JoystickPollRate; - if( fgStructure.Window->State.JoystickLastPoll < 0 ) - fgStructure.Window->State.JoystickLastPoll = 0; + if( fgStructure.CurrentWindow->State.JoystickLastPoll < 0 ) + fgStructure.CurrentWindow->State.JoystickLastPoll = 0; } /* @@ -200,22 +203,36 @@ void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int */ void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseFunc" ); SET_CALLBACK( Mouse ); } /* - * Sets the mouse motion callback for the current window (one or more buttons are pressed) + * Sets the mouse wheel callback for the current window + */ +void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) ) +{ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseWheelFunc" ); + SET_CALLBACK( MouseWheel ); +} + +/* + * Sets the mouse motion callback for the current window (one or more buttons + * are pressed) */ void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMotionFunc" ); SET_CALLBACK( Motion ); } /* - * Sets the passive mouse motion callback for the current window (no mouse buttons are pressed) + * Sets the passive mouse motion callback for the current window (no mouse + * buttons are pressed) */ void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPassiveMotionFunc" ); SET_CALLBACK( Passive ); } @@ -224,6 +241,7 @@ void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ) */ void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEntryFunc" ); SET_CALLBACK( Entry ); } @@ -232,19 +250,22 @@ void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ) */ void FGAPIENTRY glutCloseFunc( void (* callback)( void ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCloseFunc" ); SET_CALLBACK( Destroy ); } void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWMCloseFunc" ); glutCloseFunc( callback ); } /* A. Donev: Destruction callback for menus */ void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) ) { - if( fgStructure.Menu == NULL ) return; - fgStructure.Menu->Destroy = callback; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" ); + if( fgStructure.CurrentMenu ) + fgStructure.CurrentMenu->Destroy = callback; } /* @@ -252,8 +273,7 @@ void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) ) */ void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ) { - freeglut_assert_ready; - + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStateFunc" ); fgState.MenuStateCallback = callback; } @@ -262,8 +282,7 @@ void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ) */ void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ) { - freeglut_assert_ready; - + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" ); fgState.MenuStatusCallback = callback; } @@ -272,6 +291,7 @@ void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ) */ void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutOverlayDisplayFunc" ); SET_CALLBACK( OverlayDisplay ); } @@ -280,6 +300,7 @@ void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ) */ void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWindowStatusFunc" ); SET_CALLBACK( WindowStatus ); } @@ -288,6 +309,9 @@ void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ) */ void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" ); + fgInitialiseSpaceball(); + SET_CALLBACK( SpaceMotion ); } @@ -296,6 +320,9 @@ void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ) */ void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" ); + fgInitialiseSpaceball(); + SET_CALLBACK( SpaceRotation ); } @@ -304,6 +331,9 @@ void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ) */ void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" ); + fgInitialiseSpaceball(); + SET_CALLBACK( SpaceButton ); } @@ -312,6 +342,7 @@ void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ) */ void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutButtonBoxFunc" ); SET_CALLBACK( ButtonBox ); } @@ -320,6 +351,7 @@ void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ) */ void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDialsFunc" ); SET_CALLBACK( Dials ); } @@ -328,6 +360,7 @@ void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ) */ void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletMotionFunc" ); SET_CALLBACK( TabletMotion ); } @@ -336,6 +369,7 @@ void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ) */ void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) ) { + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletButtonFunc" ); SET_CALLBACK( TabletButton ); }