Initial work on callbacks with user data parameters.

-glutCreateMenuUcall
-glutTimerFuncUcall
-glutIdleFuncUcall

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1808 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2017-06-30 23:20:57 +00:00
parent 1941df93b9
commit 3c3e3cd234
9 changed files with 173 additions and 21 deletions

View File

@ -274,6 +274,9 @@ FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int));
#define GLUT_BORDERLESS 0x0800 #define GLUT_BORDERLESS 0x0800
#define GLUT_SRGB 0x1000 #define GLUT_SRGB 0x1000
/* User-argument callbacks and implementation */
#include "freeglut_ucall.h"
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -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 <stdarg.h>
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__ */

View File

@ -35,18 +35,31 @@
* Global callbacks. * Global callbacks.
*/ */
/* Sets the global idle callback */ /* 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 ) void FGAPIENTRY glutIdleFunc( FGCBIdle callback )
{ {
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
fgState.IdleCallback = callback; glutIdleFuncUcall( glutIdleFuncCallback, (FGCBUserData)callback );
} }
/* Creates a timer and sets its 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; SFG_Timer *timer, *node;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFuncUcall" );
if( (timer = fgState.FreeTimers.Last) ) if( (timer = fgState.FreeTimers.Last) )
{ {
@ -59,9 +72,10 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim
"Memory allocation failure in glutTimerFunc()" ); "Memory allocation failure in glutTimerFunc()" );
} }
timer->Callback = callback; timer->Callback = callback;
timer->ID = timerID; timer->CallbackData = userData;
timer->TriggerTime = fgElapsedTime() + timeOut; timer->ID = timerID;
timer->TriggerTime = fgElapsedTime() + timeOut;
/* Insert such that timers are sorted by end-time */ /* Insert such that timers are sorted by end-time */
for( node = fgState.Timers.First; node; node = node->Node.Next ) 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 ); 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 */ /* Deprecated version of glutMenuStatusFunc callback setting method */
void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback ) void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback )
{ {

View File

@ -210,6 +210,12 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
CHECK_NAME(glutSetVertexAttribCoord3); CHECK_NAME(glutSetVertexAttribCoord3);
CHECK_NAME(glutSetVertexAttribNormal); CHECK_NAME(glutSetVertexAttribNormal);
CHECK_NAME(glutSetVertexAttribTexCoord2); CHECK_NAME(glutSetVertexAttribTexCoord2);
/* freeglut user callback functions */
CHECK_NAME(glutCreateMenuUcall);
CHECK_NAME(glutTimerFuncUcall);
CHECK_NAME(glutIdleFuncUcall);
//TODO
#undef CHECK_NAME #undef CHECK_NAME
return NULL; return NULL;

View File

@ -70,6 +70,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
{ NULL, NULL }, /* Timers */ { NULL, NULL }, /* Timers */
{ NULL, NULL }, /* FreeTimers */ { NULL, NULL }, /* FreeTimers */
NULL, /* IdleCallback */ NULL, /* IdleCallback */
NULL, /* IdleCallbackData */
0, /* ActiveMenus */ 0, /* ActiveMenus */
NULL, /* MenuStateCallback */ NULL, /* MenuStateCallback */
NULL, /* MenuStatusCallback */ NULL, /* MenuStatusCallback */
@ -299,6 +300,7 @@ void fgDeinitialize( void )
fgListInit( &fgState.FreeTimers ); fgListInit( &fgState.FreeTimers );
fgState.IdleCallback = NULL; fgState.IdleCallback = NULL;
fgState.IdleCallbackData = NULL;
fgState.MenuStateCallback = ( FGCBMenuState )NULL; fgState.MenuStateCallback = ( FGCBMenuState )NULL;
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL; fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;

View File

@ -216,6 +216,8 @@
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* Freeglut callbacks type definitions */ /* Freeglut callbacks type definitions */
typedef void* FGCBUserData;
typedef void (* FGCBDisplay )( void ); typedef void (* FGCBDisplay )( void );
typedef void (* FGCBReshape )( int, int ); typedef void (* FGCBReshape )( int, int );
typedef void (* FGCBPosition )( int, int ); typedef void (* FGCBPosition )( int, int );
@ -251,12 +253,15 @@ typedef void (* FGCBAppStatus)(int);
/* The global callbacks type definitions */ /* The global callbacks type definitions */
typedef void (* FGCBIdle )( void ); typedef void (* FGCBIdle )( void );
typedef void (* FGCBIdleUC )( FGCBUserData );
typedef void (* FGCBTimer )( int ); typedef void (* FGCBTimer )( int );
typedef void (* FGCBTimerUC )( int, FGCBUserData );
typedef void (* FGCBMenuState )( int ); typedef void (* FGCBMenuState )( int );
typedef void (* FGCBMenuStatus )( int, int, int ); typedef void (* FGCBMenuStatus )( int, int, int );
/* The callback used when creating/using menus */ /* The callback used when creating/using menus */
typedef void (* FGCBMenu )( int ); typedef void (* FGCBMenu )( int );
typedef void (* FGCBMenuUC )( int, FGCBUserData );
/* The FreeGLUT error/warning handler type definition */ /* The FreeGLUT error/warning handler type definition */
typedef void (* FGError ) ( const char *fmt, va_list ap); 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 Timers; /* The freeglut timer hooks */
SFG_List FreeTimers; /* The unused 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 */ int ActiveMenus; /* Num. of currently active menus */
FGCBMenuState MenuStateCallback; /* Menu callbacks are global */ FGCBMenuState MenuStateCallback; /* Menu callbacks are global */
@ -384,7 +390,8 @@ struct tagSFG_Timer
{ {
SFG_Node Node; SFG_Node Node;
int ID; /* The timer ID integer */ 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 */ fg_time_t TriggerTime; /* The timer trigger time */
}; };
@ -662,7 +669,8 @@ struct tagSFG_Menu
void *UserData; /* User data passed back at callback */ void *UserData; /* User data passed back at callback */
int ID; /* The global menu ID */ int ID; /* The global menu ID */
SFG_List Entries; /* The menu entries list */ 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 */ FGCBDestroy Destroy; /* Destruction callback */
GLboolean IsActive; /* Is the menu selected? */ GLboolean IsActive; /* Is the menu selected? */
void* Font; /* Font to be used for displaying this menu */ void* Font; /* Font to be used for displaying this menu */
@ -970,7 +978,7 @@ void fgCloseWindows ();
void fgDestroyWindow( SFG_Window* window ); void fgDestroyWindow( SFG_Window* window );
/* Menu creation and destruction. Defined in fg_structure.c */ /* 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 ); void fgDestroyMenu( SFG_Menu* menu );
/* Joystick device management functions, defined in fg_joystick.c */ /* Joystick device management functions, defined in fg_joystick.c */

View File

@ -233,7 +233,7 @@ static void fghCheckTimers( void )
fgListRemove( &fgState.Timers, &timer->Node ); fgListRemove( &fgState.Timers, &timer->Node );
fgListAppend( &fgState.FreeTimers, &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 ) fgStructure.CurrentWindow->IsMenu )
/* fail safe */ /* fail safe */
fgSetWindow( window ); fgSetWindow( window );
fgState.IdleCallback( ); fgState.IdleCallback( fgState.IdleCallbackData );
} }
else else
fghSleepForEvents( ); fghSleepForEvents( );

View File

@ -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) */ /* 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 ); fgDeactivateMenu( parent_window );
active_menu->Callback( active_entry->ID ); active_menu->Callback( active_entry->ID, active_menu->CallbackData );
/* Restore the current window and menu */ /* Restore the current window and menu */
fgSetWindow( save_window ); fgSetWindow( save_window );
@ -780,14 +780,27 @@ void fghCalculateMenuBoxSize( void )
/* /*
* Creates a new menu object, adding it to the freeglut structure * 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 */ /* 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) if (fgState.ActiveMenus)
fgError("Menu manipulation not allowed while menus in use."); 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 );
} }
/* /*

View File

@ -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 * 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; SFG_Window *current_window = fgStructure.CurrentWindow;
@ -134,10 +134,11 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
fgSetWindow( current_window ); fgSetWindow( current_window );
/* Initialize the object properties: */ /* Initialize the object properties: */
menu->ID = ++fgStructure.MenuID; menu->ID = ++fgStructure.MenuID;
menu->Callback = menuCallback; menu->Callback = menuCallback;
menu->ActiveEntry = NULL; menu->CallbackData = userData;
menu->Font = fgState.MenuFont; menu->ActiveEntry = NULL;
menu->Font = fgState.MenuFont;
fgListInit( &menu->Entries ); fgListInit( &menu->Entries );
fgListAppend( &fgStructure.Menus, &menu->Node ); fgListAppend( &fgStructure.Menus, &menu->Node );