From: Rcmaniac25 Date: Fri, 30 Jun 2017 23:21:28 +0000 (+0000) Subject: Initial refactoring of callback macros to make sure all compilers are supported X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=freeglut;a=commitdiff_plain;h=753583368738a67f00d8f27adb1c8b6cff4bdfd3 Initial refactoring of callback macros to make sure all compilers are supported git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1812 7f0cb862-5218-0410-a997-914c9d46530a --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 17e05b0..55f48ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,7 @@ SET(FREEGLUT_SRCS src/fg_init.c src/fg_init.h src/fg_internal.h + src/fg_callback_macros.h src/fg_input_devices.c src/fg_joystick.c src/fg_main.c diff --git a/src/fg_callback_macros.h b/src/fg_callback_macros.h new file mode 100644 index 0000000..1c70587 --- /dev/null +++ b/src/fg_callback_macros.h @@ -0,0 +1,226 @@ +/* + * fg_callback_macros.h + * + * The freeglut library callback macro file. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef FREEGLUT_CALLBACK_MACROS_H +#define FREEGLUT_CALLBACK_MACROS_H + +#ifndef FREEGLUT_INTERNAL_H +#error "fg_internal.h needs to be included before this header" +#endif + +#if 0 /* old. Remove once other testing is complete */ +/* + * EXPAND_WCB() is used as: + * + * EXPAND_WCB arg_list + * + * ... where {(arg_list)} is the parameter list. + * + * This will take the arg_list and extend it by one argument, adding + * the argument "userData" to the end of the list. + * + * All additional args are to get around trailing ',', argument counts, + * and not needing a GCC extension to make this work. + * + * Minor modification of: + * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946 + * + * Supports up to five arguments + */ + +/* 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() \ + ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ZERO + +#define PP_HAS_ARGS_IMPL(...) \ + PP_HAS_ARGS_IMPL2(__VA_ARGS__) +#define PP_HAS_ARGS(...) \ + PP_HAS_ARGS_IMPL(NOT_EXIST, ##__VA_ARGS__, PP_HAS_ARGS_SOURCE()) + +#define EXPAND_WCB_ZERO(x) \ + (userData) +#define EXPAND_WCB_ONE_OR_MORE(...) \ + (__VA_ARGS__, userData) + +#define EXPAND_WCB_DISAMBIGUATE2(has_args, ...) \ + EXPAND_WCB_ ## has_args (__VA_ARGS__) +#define EXPAND_WCB_DISAMBIGUATE(has_args, ...) \ + EXPAND_WCB_DISAMBIGUATE2(has_args, __VA_ARGS__) +#define EXPAND_WCB(...) \ + EXPAND_WCB_DISAMBIGUATE(PP_HAS_ARGS(__VA_ARGS__), __VA_ARGS__) +#endif + +/* + * Compiler defines: + * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's varadic macro implementation (AKA, ##__VA_ARGS__) + * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports varadic macros + */ + +#ifdef FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK + + /* + * EXPAND_WCB() is used as: + * + * EXPAND_WCB arg_list + * + * ... where {(arg_list)} is the parameter list. + * + * This will take the arg_list and extend it by one argument, adding + * the argument "userData" to the end of the list. + * + * All additional args are to get around trailing ',', argument counts, + * and not needing a GCC extension to make this work. + * + * Modification of: + * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946 + * + * -------------- + * + * GCC-specific design that doesn't require per-callback defines + * + * The naming is terrible... and it's very convuluted and complex, but + * should not require any modification unless additional arguments are to + * be supported. + * + * Supports callbacks up to 5 args (follow the pattern of PP_HAS_ARGS_IMPL2 + * and PP_HAS_ARGS_SOURCE to add more) + * + * Edit with care. + */ + +#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__ + +#define PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N +#define PP_HAS_ARGS_SOURCE() ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ZERO + +#define PP_HAS_ARGS_IMPL(...) PP_HAS_ARGS_IMPL2( __VA_ARGS__ ) +#define PP_HAS_ARGS(...) PP_HAS_ARGS_IMPL( NOT_EXIST, ##__VA_ARGS__, PP_HAS_ARGS_SOURCE() ) + +#define EXPAND_WCB_ZERO(args, userData) ( userData ) +#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData ) + +#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData ) + +#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( PP_HAS_ARGS args, args, userData ) +#define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args + +#define EXPAND_WCB(cbname) EXPAND_WCB_UNWRAP_ARGS + +#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_. + * Helper functions exist for zero to five parameters: EXPAND_WCB_ZERO, + * EXPAND_WCB_ONE, EXPAND_WCB_TWO, EXPAND_WCB_THREE< EXPAND_WCB_FOUR, + * and EXPAND_WCB_FIVE. Each handle the callback argument counts. + * + * 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) EXPAND_WCB_ONE args + */ + +#define FG_COMPILER_SUPPORTS_VA_ARGS //XXX (should be compiler defined) +#ifdef FG_COMPILER_SUPPORTS_VA_ARGS + +#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__ +#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData ) + +#define EXPAND_WCB_ONE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData ) +#define EXPAND_WCB_TWO(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData ) +#define EXPAND_WCB_THREE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData ) +#define EXPAND_WCB_FOUR(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData ) +#define EXPAND_WCB_FIVE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData ) + +#else + +//TODO +#error "Compiler does not support varadic argument macros" + +#endif + +#define EXPAND_WCB_ZERO(args, userData) ( userData ) + +#define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname + +/* + * Freeglut callbacks type definitions macros + * + * Every time a callback is updated in fg_internal.h is updated, this needs updated + * if argument counts change, new callbacks are added, or callbacks are removed. + */ + +#define EXPAND_WCB_SUB_Display(args) EXPAND_WCB_ZERO args +#define EXPAND_WCB_SUB_Reshape(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_Position(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_Visibility(args) EXPAND_WCB_ONE args +#define EXPAND_WCB_SUB_Keyboard(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_KeyboardUp(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_Special(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_SpecialUp(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_Mouse(args) EXPAND_WCB_FOUR args +#define EXPAND_WCB_SUB_MouseWheel(args) EXPAND_WCB_FOUR args +#define EXPAND_WCB_SUB_Motion(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_Passive(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args +#define EXPAND_WCB_SUB_WindowStatus(args) EXPAND_WCB_ONE args +#define EXPAND_WCB_SUB_Joystick(args) EXPAND_WCB_FOUR args +#define EXPAND_WCB_SUB_OverlayDisplay(args) EXPAND_WCB_ZERO args +#define EXPAND_WCB_SUB_SpaceMotion(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_SpaceRotation(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_SpaceButton(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_Dials(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_ButtonBox(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_TabletMotion(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_TabletButton(args) EXPAND_WCB_FOUR args +#define EXPAND_WCB_SUB_Destroy(args) EXPAND_WCB_ZERO args +#define EXPAND_WCB_SUB_MultiEntry(args) EXPAND_WCB_TWO args +#define EXPAND_WCB_SUB_MultiButton(args) EXPAND_WCB_FIVE args +#define EXPAND_WCB_SUB_MultiMotion(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_MultiPassive(args) EXPAND_WCB_THREE args +#define EXPAND_WCB_SUB_InitContext(args) EXPAND_WCB_ZERO args +#define EXPAND_WCB_SUB_AppStatus(args) EXPAND_WCB_ONE args + +#endif + +#endif /* FREEGLUT_CALLBACK_MACROS_H */ + +/*** END OF FILE ***/ diff --git a/src/fg_internal.h b/src/fg_internal.h index 93ea3bc..bce77ca 100644 --- a/src/fg_internal.h +++ b/src/fg_internal.h @@ -33,12 +33,14 @@ #endif #include "fg_version.h" +#include "fg_callback_macros.h" /* Freeglut is intended to function under all Unix/X11 and Win32 platforms. */ /* XXX: Don't all MS-Windows compilers (except Cygwin) have _WIN32 defined? * XXX: If so, remove the first set of defined()'s below. */ -#if !defined(TARGET_HOST_POSIX_X11) && !defined(TARGET_HOST_MS_WINDOWS) && !defined(TARGET_HOST_MAC_OSX) && !defined(TARGET_HOST_SOLARIS) +#if !defined(TARGET_HOST_POSIX_X11) && !defined(TARGET_HOST_MS_WINDOWS) && !defined(TARGET_HOST_MAC_OSX) && !defined(TARGET_HOST_SOLARIS) && \ + !defined(TARGET_HOST_ANDROID) && !defined(TARGET_HOST_BLACKBERRY) && !defined(TARGET_HOST_POSIX_WAYLAND) #if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__) \ || defined(_WIN32) || defined(_WIN32_WCE) \ || ( defined(__CYGWIN__) && defined(X_DISPLAY_MISSING) ) @@ -215,101 +217,78 @@ /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ -/* Freeglut callbacks type definitions */ +/* + * Freeglut callbacks type definitions + * + * If anything here is modified or added, update fg_callback_macros.h functions. + * + * This is not ideal, but freeglut needs to either define minimal compiler specs, + * or update header every time this is changed or updated. + */ 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 ); \ @@ -646,54 +625,10 @@ do \ #define FETCH_USER_DATA_WCB(window,cbname) \ ((window).CallbackDatas[WCB_ ## cbname]) -#if 0 /* * EXPAND_WCB() is used as: * - * EXPAND_WCB arg_list - * - * ... where {(arg_list)} is the parameter list. - * - * This will take the arg_list and extend it by one argument, adding - * the argument "userData" to the end of the list. - * - * All additional args are to get around trailing ',', argument counts, - * and not needing a GCC extension to make this work. - * - * Minor modification of: - * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946 - * - * Supports up to five arguments - */ - -/* 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() \ - ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ZERO - -#define PP_HAS_ARGS_IMPL(...) \ - PP_HAS_ARGS_IMPL2(__VA_ARGS__) -#define PP_HAS_ARGS(...) \ - PP_HAS_ARGS_IMPL(NOT_EXIST, ##__VA_ARGS__, PP_HAS_ARGS_SOURCE()) - -#define EXPAND_WCB_ZERO(x) \ - (userData) -#define EXPAND_WCB_ONE_OR_MORE(...) \ - (__VA_ARGS__, userData) - -#define EXPAND_WCB_DISAMBIGUATE2(has_args, ...) \ - EXPAND_WCB_ ## has_args (__VA_ARGS__) -#define EXPAND_WCB_DISAMBIGUATE(has_args, ...) \ - EXPAND_WCB_DISAMBIGUATE2(has_args, __VA_ARGS__) -#define EXPAND_WCB(...) \ - EXPAND_WCB_DISAMBIGUATE(PP_HAS_ARGS(__VA_ARGS__), __VA_ARGS__) - -#else -/* - * EXPAND_WCB() is used as: - * - * EXPAND_WCB( cbname )( arg_list, userData ) + * EXPAND_WCB( cbname )(( arg_list, userData )) * * ... where {(arg_list)} is the parameter list and userData is user * provided data. @@ -701,30 +636,12 @@ do \ * 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) + * All of this is defined in fg_callback_macros.h + * + * See that header for more info. + * + * ------------------------------------------------------------------ */ -#define FG_COMPILER_SUPPORTS_VA_ARGS -#ifdef FG_COMPILER_SUPPORTS_VA_ARGS -#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__ -#else -#error "Compiler does not support varadic argument macros" -#endif - -#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: @@ -755,7 +672,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( cbname )( arg_list, userData ); \ + func EXPAND_WCB( cbname )(( arg_list, userData )); \ } \ } while( 0 ) #else @@ -766,7 +683,7 @@ do \ { \ fgSetWindow( &window ); \ FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \ - ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )( arg_list, userData ); \ + ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )(( arg_list, userData )); \ } \ } while( 0 ) #endif