Changed EXPAND_WCB so it works with MSVC and GCC
authorRcmaniac25 <rcmaniac25@hotmail.com>
Fri, 30 Jun 2017 23:21:14 +0000 (23:21 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Fri, 30 Jun 2017 23:21:14 +0000 (23:21 +0000)
- 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

CMakeLists.txt
include/GL/freeglut_ext.h
src/fg_callbacks.c
src/fg_internal.h

index 190964f..17e05b0 100644 (file)
@@ -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
 )
index 255edea..9b0ac50 100644 (file)
@@ -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
index 5f94b65..684c934 100644 (file)
@@ -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();                                                 \
index 69401d0..7afb400 100644 (file)
@@ -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_<cbname>.
+ * 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