* All of the window-specific callbacks setting methods can be generalized to this:
*/
#define SET_CALLBACK(a) \
do \
{ \
if( fgStructure.CurrentWindow == NULL ) \
return; \
SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \
} while( 0 )
/*
* And almost every time the callback setter function can be implemented like this:
*/
#define IMPLEMENT_CALLBACK_FUNC_2NAME(a,b) \
void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
{ \
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
SET_CALLBACK( b ); \
}
#define IMPLEMENT_CALLBACK_FUNC(a) IMPLEMENT_CALLBACK_FUNC_2NAME(a,a)
/* Implement all these callback setter functions... */
IMPLEMENT_CALLBACK_FUNC(Position)
IMPLEMENT_CALLBACK_FUNC(Keyboard)
IMPLEMENT_CALLBACK_FUNC(KeyboardUp)
IMPLEMENT_CALLBACK_FUNC(Special)
IMPLEMENT_CALLBACK_FUNC(SpecialUp)
IMPLEMENT_CALLBACK_FUNC(Mouse)
IMPLEMENT_CALLBACK_FUNC(MouseWheel)
IMPLEMENT_CALLBACK_FUNC(Motion)
IMPLEMENT_CALLBACK_FUNC_2NAME(PassiveMotion,Passive)
IMPLEMENT_CALLBACK_FUNC(Entry)
/* glutWMCloseFunc is an alias for glutCloseFunc; both set the window's Destroy callback */
IMPLEMENT_CALLBACK_FUNC_2NAME(Close,Destroy)
IMPLEMENT_CALLBACK_FUNC_2NAME(WMClose,Destroy)
IMPLEMENT_CALLBACK_FUNC(OverlayDisplay)
IMPLEMENT_CALLBACK_FUNC(WindowStatus)
IMPLEMENT_CALLBACK_FUNC(ButtonBox)
IMPLEMENT_CALLBACK_FUNC(Dials)
IMPLEMENT_CALLBACK_FUNC(TabletMotion)
IMPLEMENT_CALLBACK_FUNC(TabletButton)
IMPLEMENT_CALLBACK_FUNC(MultiEntry)
IMPLEMENT_CALLBACK_FUNC(MultiButton)
IMPLEMENT_CALLBACK_FUNC(MultiMotion)
IMPLEMENT_CALLBACK_FUNC(MultiPassive)
IMPLEMENT_CALLBACK_FUNC(InitContext)
IMPLEMENT_CALLBACK_FUNC(AppStatus)
#############################################################################
* SET_WCB() is used as:
*
* SET_WCB( window, cbname, func );
*
* ...where {window} is the freeglut window to set the callback,
* {cbname} is the window-specific callback to set,
* {func} is a function-pointer.
*
* Originally, {FETCH_WCB( ... ) = func} was rather sloppily used,
* but this can cause warnings because the FETCH_WCB() macro type-
* casts its result, and a type-cast value shouldn't be an lvalue.
*
* The {if( FETCH_WCB( ... ) != func )} test is to do type-checking
* and for no other reason. Since it's hidden in the macro, the
* ugliness is felt to be rather benign.
*/
#define SET_WCB(window,cbname,func) \
do \
{ \
if( FETCH_WCB( window, cbname ) != (SFG_Proc)(func) ) \
(((window).CallBacks[WCB_ ## cbname]) = (SFG_Proc)(func)); \
} while( 0 )
/*
* FETCH_WCB() is used as:
*
* FETCH_WCB( window, cbname );
*
* ...where {window} is the freeglut window to fetch the callback from,
* {cbname} is the window-specific callback to fetch.
*
* The result is correctly type-cast to the callback function pointer
* type.
*/
#define FETCH_WCB(window,cbname) \
((window).CallBacks[WCB_ ## cbname])