From: Rcmaniac25 Date: Fri, 30 Jun 2017 23:21:14 +0000 (+0000) Subject: Changed EXPAND_WCB so it works with MSVC and GCC X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=freeglut;a=commitdiff_plain;h=cf2ecefe0a6a352339294c01a5188667f3650496 Changed EXPAND_WCB so it works with MSVC and GCC - Required adding an "argument expansion macro" for each callback (hope to remove eventually) - Fixed MSVC linking error where glutMenuStatusFuncUCall had the incorrect case and should've been glutMenuStatusFuncUcall - Updated formatting of some freeglut_ext.h functions git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1810 7f0cb862-5218-0410-a997-914c9d46530a --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 190964f..17e05b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ ENDIF() SET(FREEGLUT_HEADERS include/GL/freeglut.h + include/GL/freeglut_ucall.h include/GL/freeglut_ext.h include/GL/freeglut_std.h ) diff --git a/include/GL/freeglut_ext.h b/include/GL/freeglut_ext.h index 255edea..9b0ac50 100644 --- a/include/GL/freeglut_ext.h +++ b/include/GL/freeglut_ext.h @@ -256,13 +256,13 @@ FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt, FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) ); /* OpenGL >= 2.0 support */ -FGAPI void FGAPIENTRY glutSetVertexAttribCoord3(GLint attrib); -FGAPI void FGAPIENTRY glutSetVertexAttribNormal(GLint attrib); -FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2(GLint attrib); +FGAPI void FGAPIENTRY glutSetVertexAttribCoord3( GLint attrib ); +FGAPI void FGAPIENTRY glutSetVertexAttribNormal( GLint attrib ); +FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2( GLint attrib ); /* Mobile platforms lifecycle */ -FGAPI void FGAPIENTRY glutInitContextFunc(void (* callback)()); -FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int)); +FGAPI void FGAPIENTRY glutInitContextFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutAppStatusFunc( void (* callback)( int ) ); /* state flags that can be passed to callback set by glutAppStatusFunc */ #define GLUT_APPSTATUS_PAUSE 0x0001 #define GLUT_APPSTATUS_RESUME 0x0002 diff --git a/src/fg_callbacks.c b/src/fg_callbacks.c index 5f94b65..684c934 100644 --- a/src/fg_callbacks.c +++ b/src/fg_callbacks.c @@ -113,9 +113,9 @@ void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback ) } /* Sets the global menu status callback for the current window */ -void FGAPIENTRY glutMenuStatusFuncUCall( FGCBMenuStatusUC callback, FGCBUserData userData ) +void FGAPIENTRY glutMenuStatusFuncUcall( FGCBMenuStatusUC callback, FGCBUserData userData ) { - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFuncUCall" ); + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFuncUcall" ); fgState.MenuStatusCallback = callback; fgState.MenuStatusCallbackData = userData; } @@ -130,12 +130,11 @@ void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback ) { FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" ); if( callback ) - glutMenuStatusFuncUCall( glutMenuStatusFuncCallback, (FGCBUserData)callback ); + glutMenuStatusFuncUcall( glutMenuStatusFuncCallback, (FGCBUserData)callback ); else - glutMenuStatusFuncUCall( NULL, NULL ); + glutMenuStatusFuncUcall( NULL, NULL ); } - /* * Menu specific callbacks. */ @@ -180,7 +179,7 @@ do \ * Types need to be defined for callbacks. It's not ideal, but it works for this. */ #define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \ -static void glut##a##FuncCallback( FGCBUserData userData ) \ +static void glut##a##FuncCallback( FGCBUserData userData ) \ { \ FGCB##b callback = (FGCB##b)userData; \ callback(); \ diff --git a/src/fg_internal.h b/src/fg_internal.h index 69401d0..7afb400 100644 --- a/src/fg_internal.h +++ b/src/fg_internal.h @@ -220,66 +220,96 @@ typedef void* FGCBUserData; typedef void (* FGCBDisplay )( void ); typedef void (* FGCBDisplayUC )( FGCBUserData ); +#define EXPAND_WCB_SUB_Display(args, userData) EXPAND_WCB_ZERO(args, userData) typedef void (* FGCBReshape )( int, int ); typedef void (* FGCBReshapeUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Reshape(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBPosition )( int, int ); typedef void (* FGCBPositionUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Position(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBVisibility )( int ); typedef void (* FGCBVisibilityUC )( int, FGCBUserData ); +#define EXPAND_WCB_SUB_Visibility(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBKeyboard )( unsigned char, int, int ); typedef void (* FGCBKeyboardUC )( unsigned char, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Keyboard(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBKeyboardUp )( unsigned char, int, int ); typedef void (* FGCBKeyboardUpUC )( unsigned char, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_KeyboardUp(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBSpecial )( int, int, int ); typedef void (* FGCBSpecialUC )( int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Special(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBSpecialUp )( int, int, int ); typedef void (* FGCBSpecialUpUC )( int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_SpecialUp(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBMouse )( int, int, int, int ); typedef void (* FGCBMouseUC )( int, int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Mouse(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBMouseWheel )( int, int, int, int ); typedef void (* FGCBMouseWheelUC )( int, int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_MouseWheel(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBMotion )( int, int ); typedef void (* FGCBMotionUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Motion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBPassive )( int, int ); typedef void (* FGCBPassiveUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Passive(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBEntry )( int ); typedef void (* FGCBEntryUC )( int, FGCBUserData ); +#define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBWindowStatus )( int ); typedef void (* FGCBWindowStatusUC )( int, FGCBUserData ); +#define EXPAND_WCB_SUB_WindowStatus(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBJoystick )( unsigned int, int, int, int ); typedef void (* FGCBJoystickUC )( unsigned int, int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Joystick(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBOverlayDisplay )( void ); typedef void (* FGCBOverlayDisplayUC)( FGCBUserData ); +#define EXPAND_WCB_SUB_OverlayDisplay(args, userData) EXPAND_WCB_ZERO(args, userData) typedef void (* FGCBSpaceMotion )( int, int, int ); typedef void (* FGCBSpaceMotionUC )( int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_SpaceMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBSpaceRotation )( int, int, int ); typedef void (* FGCBSpaceRotationUC )( int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_SpaceRotation(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBSpaceButton )( int, int ); typedef void (* FGCBSpaceButtonUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_SpaceButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBDials )( int, int ); typedef void (* FGCBDialsUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_Dials(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBButtonBox )( int, int ); typedef void (* FGCBButtonBoxUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_ButtonBox(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBTabletMotion )( int, int ); typedef void (* FGCBTabletMotionUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_TabletMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBTabletButton )( int, int, int, int ); typedef void (* FGCBTabletButtonUC )( int, int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_TabletButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */ typedef void (* FGCBDestroyUC )( FGCBUserData ); +#define EXPAND_WCB_SUB_Destroy(args, userData) EXPAND_WCB_ZERO(args, userData) typedef void (* FGCBMultiEntry )( int, int ); typedef void (* FGCBMultiEntryUC )( int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_MultiEntry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBMultiButton )( int, int, int, int, int ); typedef void (* FGCBMultiButtonUC )( int, int, int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_MultiButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBMultiMotion )( int, int, int ); typedef void (* FGCBMultiMotionUC )( int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_MultiMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBMultiPassive )( int, int, int ); typedef void (* FGCBMultiPassiveUC )( int, int, int, FGCBUserData ); +#define EXPAND_WCB_SUB_MultiPassive(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) typedef void (* FGCBInitContext )( void ); typedef void (* FGCBInitContextUC )( FGCBUserData ); +#define EXPAND_WCB_SUB_InitContext(args, userData) EXPAND_WCB_ZERO(args, userData) typedef void (* FGCBAppStatus )( int ); typedef void (* FGCBAppStatusUC )( int, FGCBUserData ); +#define EXPAND_WCB_SUB_AppStatus(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) /* The global callbacks type definitions */ typedef void (* FGCBIdle )( void ); \ @@ -616,6 +646,7 @@ do \ #define FETCH_USER_DATA_WCB(window,cbname) \ ((window).CallbackDatas[WCB_ ## cbname]) +#if 0 /* * EXPAND_WCB() is used as: * @@ -634,17 +665,8 @@ do \ * * Supports up to five arguments */ -#if TARGET_HOST_MS_WINDOWS - -/* FIXME: Does VC6 support variadic macros? I don't think so (variadic macros came with C99. VC6 came out in 1998) */ -/* FIXME: VC++ has a greedy preprocessor. - * The preprocessor resolves the macros on use instead of after on argument completion/token usage. - * e.g.: PP_HAS_ARGS_IMPL2(ONE_OR_MORE, ...) -> PP_HAS_ARGS_IMPL2(, ...) -> "Error, not enough tokens for PP_HAS_ARGS_IMPL2" - */ -#define EXPAND_WCB(...) (__VA_ARGS__) - -#else // #if TARGET_HOST_MS_WINDOWS +/* GCC-specific design that doesn't require per-callback defines */ #define PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N #define PP_HAS_ARGS_SOURCE() \ @@ -667,7 +689,36 @@ do \ #define EXPAND_WCB(...) \ EXPAND_WCB_DISAMBIGUATE(PP_HAS_ARGS(__VA_ARGS__), __VA_ARGS__) -#endif // #if TARGET_HOST_MS_WINDOWS +#else +/* + * EXPAND_WCB() is used as: + * + * EXPAND_WCB( cbname )( arg_list, userData ) + * + * ... where {(arg_list)} is the parameter list and userData is user + * provided data. + * + * This will take the arg_list and extend it by one argument, adding + * the argument "userData" to the end of the list. + * + * In order for this to work, each callback must have a define that + * properly handles the arguments as needed by the callback. + * This callback is in the format of EXPAND_WCB_SUB_. + * Two helper defines exist: EXPAND_WCB_ZERO and EXPAND_WCB_ONE_OR_MORE, + * each to handle callbacks that take zero-params (but take userData) and + * to take one or more params (along with userData). + * + * An example for the "Entry" callback, where "Entry" is the cbname: + * typedef void (* FGCBEntry )( int ); + * typedef void (* FGCBEntryUC)( int, FGCBUserData ); + * #define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData) + */ +#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__ +#define EXPAND_WCB_ZERO(args, userData) ( userData ) +#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData ) + +#define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname +#endif /* * INVOKE_WCB() is used as: @@ -697,7 +748,7 @@ do \ FGCB ## cbname ## UC func = (FGCB ## cbname ## UC)(FETCH_WCB( window, cbname )); \ FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \ fgSetWindow( &window ); \ - func EXPAND_WCB arg_list; \ + func EXPAND_WCB( cbname )( arg_list, userData ); \ } \ } while( 0 ) #else @@ -708,7 +759,7 @@ do \ { \ fgSetWindow( &window ); \ FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \ - ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB arg_list; \ + ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )( arg_list, userData ); \ } \ } while( 0 ) #endif