X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffg_internal.h;h=c98e520d33f9a9d4542f5c6ade4352d33efa1e4e;hb=f4b802a47ef27c25a283a68932956fb7898771f1;hp=69401d0f89931bdd8570f75274daaf825ff27841;hpb=831749819dcdc1ea884c18607c2b447bbf5fca72;p=freeglut diff --git a/src/fg_internal.h b/src/fg_internal.h index 69401d0..c98e520 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,7 +217,14 @@ /* -- 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 ); @@ -568,6 +577,12 @@ typedef void (*SFG_Proc)(); * 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. + * + * If the function-pointer is the same, the data will be the only + * value updated. If the function-pointer changes, the data will + * be changed as well, preventing stail data from being passed in. + * Just updating the data does nothing unless a function-pointer + * exists, as the data is otherwise already allocated. */ #define SET_WCB(window,cbname,func,udata) \ do \ @@ -577,6 +592,10 @@ do \ (((window).CallBacks[WCB_ ## cbname]) = (SFG_Proc)(func)); \ (((window).CallbackDatas[WCB_ ## cbname]) = (udata)); \ } \ + else if( FETCH_USER_DATA_WCB( window, cbname ) != udata ) \ + { \ + (((window).CallbackDatas[WCB_ ## cbname]) = (udata)); \ + } \ } while( 0 ) /* @@ -602,14 +621,6 @@ do \ * {cbname} is the window-specific callback to be invoked, * * This expects a variable named "window" of type tagSFG_Window to exist. - */ -/* - * FETCH_USER_DATA_WCB() is used as: - * - * FETCH_USER_DATA_WCB( window, cbname ); - * - * ...where {window} is the freeglut window to fetch the callback data from, - * {cbname} is the window-specific callback data to fetch. * * The result is the callback data pointer. */ @@ -619,55 +630,20 @@ do \ /* * EXPAND_WCB() is used as: * - * EXPAND_WCB arg_list + * EXPAND_WCB( cbname )(( arg_list, userData )) * - * ... where {(arg_list)} is the parameter list. + * ... 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. - * - * 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 + * All of this is defined in fg_callback_macros.h * - * 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" + * See that header for more info. + * + * ------------------------------------------------------------------ */ -#define EXPAND_WCB(...) (__VA_ARGS__) - -#else // #if TARGET_HOST_MS_WINDOWS - -#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 // #if TARGET_HOST_MS_WINDOWS /* * INVOKE_WCB() is used as: @@ -680,9 +656,10 @@ do \ * * The callback is invoked as: * - * callback( arg_list ); + * callback( arg_list, userData ); * - * ...so the parentheses are REQUIRED in the {arg_list}. + * ...where userData is added to the arg_list, but the parentheses + * are REQUIRED in the {arg_list}. * * NOTE that it does a sanity-check and also sets the * current window. @@ -697,7 +674,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 +685,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