From 76bb5e2f2b60a3cb15fe7fa0142d80a89065cf30 Mon Sep 17 00:00:00 2001 From: Rcmaniac25 Date: Fri, 30 Jun 2017 23:20:57 +0000 Subject: [PATCH] Initial work on callbacks with user data parameters. -glutCreateMenuUcall -glutTimerFuncUcall -glutIdleFuncUcall git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1808 7f0cb862-5218-0410-a997-914c9d46530a --- include/GL/freeglut_ext.h | 3 ++ include/GL/freeglut_ucall.h | 93 +++++++++++++++++++++++++++++++++++++++++++ src/fg_callbacks.c | 38 +++++++++++++++--- src/fg_ext.c | 6 +++ src/fg_init.c | 2 + src/fg_internal.h | 16 ++++++-- src/fg_main.c | 4 +- src/fg_menu.c | 21 ++++++++-- src/fg_structure.c | 11 ++--- 9 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 include/GL/freeglut_ucall.h diff --git a/include/GL/freeglut_ext.h b/include/GL/freeglut_ext.h index 2ef96c2..255edea 100644 --- a/include/GL/freeglut_ext.h +++ b/include/GL/freeglut_ext.h @@ -274,6 +274,9 @@ FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int)); #define GLUT_BORDERLESS 0x0800 #define GLUT_SRGB 0x1000 +/* User-argument callbacks and implementation */ +#include "freeglut_ucall.h" + #ifdef __cplusplus } #endif diff --git a/include/GL/freeglut_ucall.h b/include/GL/freeglut_ucall.h new file mode 100644 index 0000000..9cbe82a --- /dev/null +++ b/include/GL/freeglut_ucall.h @@ -0,0 +1,93 @@ +#ifndef __FREEGLUT_UCALL_H__ +#define __FREEGLUT_UCALL_H__ + +/* + * freeglut_ucall.h + * + * Callbacks with user data arguments. + * + * 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. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Menu stuff, see fg_menu.c + */ +FGAPI int FGAPIENTRY glutCreateMenuUcall( void (* callback)( int menu, void* user_data ), void* user_data ); + +/* + * Global callback functions, see fg_callbacks.c + */ +FGAPI void FGAPIENTRY glutTimerFuncUcall( unsigned int time, void (* callback)( int, void* ), int value, void* user_data ); +FGAPI void FGAPIENTRY glutIdleFuncUcall( void (* callback)( void* ), void* user_data ); + +/* + * Window-specific callback functions, see fg_callbacks.c + */ +FGAPI void FGAPIENTRY glutKeyboardFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutSpecialFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutReshapeFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutVisibilityFuncUcall( void (* callback)( int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutDisplayFuncUcall( void (* callback)( void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMouseFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutPassiveMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutEntryFuncUcall( void (* callback)( int, void* ), void* user_data ); + +FGAPI void FGAPIENTRY glutKeyboardUpFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutSpecialUpFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutJoystickFuncUcall( void (* callback)( unsigned int, int, int, int, void* ), int pollInterval, void* user_data ); +FGAPI void FGAPIENTRY glutMenuStateFuncUcall( void (* callback)( int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMenuStatusFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutOverlayDisplayFuncUcall( void (* callback)( void* ), void* user_data ); +FGAPI void FGAPIENTRY glutWindowStatusFuncUcall( void (* callback)( int, void* ), void* user_data ); + +FGAPI void FGAPIENTRY glutSpaceballMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutSpaceballRotateFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutSpaceballButtonFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutButtonBoxFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutDialsFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutTabletMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutTabletButtonFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data ); + +FGAPI void FGAPIENTRY glutMouseWheelFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutPositionFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutCloseFuncUcall( void (* callback)( void* ), void* user_data ); +FGAPI void FGAPIENTRY glutWMCloseFuncUcall( void (* callback)( void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMenuDestroyFuncUcall( void (* callback)( void* ), void* user_data ); + +/* + * Multi-touch/multi-pointer extensions + */ +FGAPI void FGAPIENTRY glutMultiEntryFuncUcall( void (* callback)( int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMultiButtonFuncUcall( void (* callback)( int, int, int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMultiMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutMultiPassiveFuncUcall( void (* callback)( int, int, int, void* ), void* user_data ); + +/* + * Initialization functions, see fg_init.c + */ +#include +FGAPI void FGAPIENTRY glutInitErrorFuncUcall( void (* callback)( const char *fmt, va_list ap, void* ), void* user_data ); +FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *fmt, va_list ap, void* ), void* user_data ); + +/* Mobile platforms lifecycle */ +FGAPI void FGAPIENTRY glutInitContextFuncUcall(void (* callback)(void*), void* user_data); +FGAPI void FGAPIENTRY glutAppStatusFuncUcall(void (* callback)(int, void*), void* user_data); + +#ifdef __cplusplus + } +#endif + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_UCALL_H__ */ + diff --git a/src/fg_callbacks.c b/src/fg_callbacks.c index 11924b3..b09f421 100644 --- a/src/fg_callbacks.c +++ b/src/fg_callbacks.c @@ -35,18 +35,31 @@ * Global callbacks. */ /* Sets the global idle callback */ +void FGAPIENTRY glutIdleFuncUcall( FGCBIdleUC callback, FGCBUserData userData ) +{ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFuncUcall" ); + fgState.IdleCallback = callback; + fgState.IdleCallbackData = userData; +} + +void glutIdleFuncCallback( void* userData ) +{ + FGCBIdle callback = (FGCBIdle)userData; + callback(); +} + void FGAPIENTRY glutIdleFunc( FGCBIdle callback ) { FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" ); - fgState.IdleCallback = callback; + glutIdleFuncUcall( glutIdleFuncCallback, (FGCBUserData)callback ); } /* Creates a timer and sets its callback */ -void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int timerID ) +void FGAPIENTRY glutTimerFuncUcall( unsigned int timeOut, FGCBTimerUC callback, int timerID, FGCBUserData userData ) { SFG_Timer *timer, *node; - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" ); + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFuncUcall" ); if( (timer = fgState.FreeTimers.Last) ) { @@ -59,9 +72,10 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim "Memory allocation failure in glutTimerFunc()" ); } - timer->Callback = callback; - timer->ID = timerID; - timer->TriggerTime = fgElapsedTime() + timeOut; + timer->Callback = callback; + timer->CallbackData = userData; + timer->ID = timerID; + timer->TriggerTime = fgElapsedTime() + timeOut; /* Insert such that timers are sorted by end-time */ for( node = fgState.Timers.First; node; node = node->Node.Next ) @@ -73,6 +87,18 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim fgListInsert( &fgState.Timers, &node->Node, &timer->Node ); } +void glutTimerFuncCallback( int ID, FGCBUserData userData ) +{ + FGCBTimer callback = (FGCBTimer)userData; + callback( ID ); +} + +void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int timerID ) +{ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" ); + glutTimerFuncUcall( timeOut, glutTimerFuncCallback, timerID, (FGCBUserData)callback ); +} + /* Deprecated version of glutMenuStatusFunc callback setting method */ void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback ) { diff --git a/src/fg_ext.c b/src/fg_ext.c index d96849a..4c1f9c9 100644 --- a/src/fg_ext.c +++ b/src/fg_ext.c @@ -210,6 +210,12 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName ) CHECK_NAME(glutSetVertexAttribCoord3); CHECK_NAME(glutSetVertexAttribNormal); CHECK_NAME(glutSetVertexAttribTexCoord2); + + /* freeglut user callback functions */ + CHECK_NAME(glutCreateMenuUcall); + CHECK_NAME(glutTimerFuncUcall); + CHECK_NAME(glutIdleFuncUcall); + //TODO #undef CHECK_NAME return NULL; diff --git a/src/fg_init.c b/src/fg_init.c index ae87212..ffd3f99 100644 --- a/src/fg_init.c +++ b/src/fg_init.c @@ -70,6 +70,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ { NULL, NULL }, /* Timers */ { NULL, NULL }, /* FreeTimers */ NULL, /* IdleCallback */ + NULL, /* IdleCallbackData */ 0, /* ActiveMenus */ NULL, /* MenuStateCallback */ NULL, /* MenuStatusCallback */ @@ -299,6 +300,7 @@ void fgDeinitialize( void ) fgListInit( &fgState.FreeTimers ); fgState.IdleCallback = NULL; + fgState.IdleCallbackData = NULL; fgState.MenuStateCallback = ( FGCBMenuState )NULL; fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL; diff --git a/src/fg_internal.h b/src/fg_internal.h index 2cecf71..8e27f54 100644 --- a/src/fg_internal.h +++ b/src/fg_internal.h @@ -216,6 +216,8 @@ /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ /* Freeglut callbacks type definitions */ +typedef void* FGCBUserData; + typedef void (* FGCBDisplay )( void ); typedef void (* FGCBReshape )( int, int ); typedef void (* FGCBPosition )( int, int ); @@ -251,12 +253,15 @@ typedef void (* FGCBAppStatus)(int); /* The global callbacks type definitions */ typedef void (* FGCBIdle )( void ); +typedef void (* FGCBIdleUC )( FGCBUserData ); typedef void (* FGCBTimer )( int ); +typedef void (* FGCBTimerUC )( int, FGCBUserData ); typedef void (* FGCBMenuState )( int ); typedef void (* FGCBMenuStatus )( int, int, int ); /* The callback used when creating/using menus */ typedef void (* FGCBMenu )( int ); +typedef void (* FGCBMenuUC )( int, FGCBUserData ); /* The FreeGLUT error/warning handler type definition */ typedef void (* FGError ) ( const char *fmt, va_list ap); @@ -327,7 +332,8 @@ struct tagSFG_State SFG_List Timers; /* The freeglut timer hooks */ SFG_List FreeTimers; /* The unused timer hooks */ - FGCBIdle IdleCallback; /* The global idle callback */ + FGCBIdleUC IdleCallback; /* The global idle callback */ + FGCBUserData IdleCallbackData; /* The global idle callback data */ int ActiveMenus; /* Num. of currently active menus */ FGCBMenuState MenuStateCallback; /* Menu callbacks are global */ @@ -384,7 +390,8 @@ struct tagSFG_Timer { SFG_Node Node; int ID; /* The timer ID integer */ - FGCBTimer Callback; /* The timer callback */ + FGCBTimerUC Callback; /* The timer callback */ + FGCBUserData CallbackData; /* The timer callback user data */ fg_time_t TriggerTime; /* The timer trigger time */ }; @@ -662,7 +669,8 @@ struct tagSFG_Menu void *UserData; /* User data passed back at callback */ int ID; /* The global menu ID */ SFG_List Entries; /* The menu entries list */ - FGCBMenu Callback; /* The menu callback */ + FGCBMenuUC Callback; /* The menu callback */ + FGCBUserData CallbackData; /* The menu callback user data */ FGCBDestroy Destroy; /* Destruction callback */ GLboolean IsActive; /* Is the menu selected? */ void* Font; /* Font to be used for displaying this menu */ @@ -970,7 +978,7 @@ void fgCloseWindows (); void fgDestroyWindow( SFG_Window* window ); /* Menu creation and destruction. Defined in fg_structure.c */ -SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ); +SFG_Menu* fgCreateMenu( FGCBMenuUC menuCallback, FGCBUserData userData ); void fgDestroyMenu( SFG_Menu* menu ); /* Joystick device management functions, defined in fg_joystick.c */ diff --git a/src/fg_main.c b/src/fg_main.c index 0f47c8d..6e9ff48 100644 --- a/src/fg_main.c +++ b/src/fg_main.c @@ -233,7 +233,7 @@ static void fghCheckTimers( void ) fgListRemove( &fgState.Timers, &timer->Node ); fgListAppend( &fgState.FreeTimers, &timer->Node ); - timer->Callback( timer->ID ); + timer->Callback( timer->ID, timer->CallbackData ); } } @@ -509,7 +509,7 @@ void FGAPIENTRY glutMainLoop( void ) fgStructure.CurrentWindow->IsMenu ) /* fail safe */ fgSetWindow( window ); - fgState.IdleCallback( ); + fgState.IdleCallback( fgState.IdleCallbackData ); } else fghSleepForEvents( ); diff --git a/src/fg_menu.c b/src/fg_menu.c index 36b24ce..cad5b83 100644 --- a/src/fg_menu.c +++ b/src/fg_menu.c @@ -609,7 +609,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed, /* Deactivate menu and then call callback (we don't want menu to stay in view while callback is executing, and user should be able to change menus in callback) */ fgDeactivateMenu( parent_window ); - active_menu->Callback( active_entry->ID ); + active_menu->Callback( active_entry->ID, active_menu->CallbackData ); /* Restore the current window and menu */ fgSetWindow( save_window ); @@ -780,14 +780,27 @@ void fghCalculateMenuBoxSize( void ) /* * Creates a new menu object, adding it to the freeglut structure */ -int FGAPIENTRY glutCreateMenu( FGCBMenu callback ) +int FGAPIENTRY glutCreateMenuUcall( FGCBMenuUC callback, FGCBUserData userData ) { /* The menu object creation code resides in fg_structure.c */ - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" ); + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenuUcall" ); if (fgState.ActiveMenus) fgError("Menu manipulation not allowed while menus in use."); - return fgCreateMenu( callback )->ID; + return fgCreateMenu( callback, userData )->ID; +} + +/* Standard glutCreateMenu */ +void glutCreateMenuCallback( int menu, FGCBUserData userData ) +{ + FGCBMenu callback = (FGCBMenu)userData; + callback( menu ); +} + +int FGAPIENTRY glutCreateMenu( FGCBMenu callback ) +{ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" ); + return glutCreateMenuUcall( glutCreateMenuCallback, (FGCBUserData)callback ); } /* diff --git a/src/fg_structure.c b/src/fg_structure.c index f0bc9a2..c279b4a 100644 --- a/src/fg_structure.c +++ b/src/fg_structure.c @@ -116,7 +116,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, /* * This private function creates a menu and adds it to the menus list */ -SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) +SFG_Menu* fgCreateMenu( FGCBMenuUC menuCallback, FGCBUserData userData ) { SFG_Window *current_window = fgStructure.CurrentWindow; @@ -134,10 +134,11 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) fgSetWindow( current_window ); /* Initialize the object properties: */ - menu->ID = ++fgStructure.MenuID; - menu->Callback = menuCallback; - menu->ActiveEntry = NULL; - menu->Font = fgState.MenuFont; + menu->ID = ++fgStructure.MenuID; + menu->Callback = menuCallback; + menu->CallbackData = userData; + menu->ActiveEntry = NULL; + menu->Font = fgState.MenuFont; fgListInit( &menu->Entries ); fgListAppend( &fgStructure.Menus, &menu->Node ); -- 1.7.10.4