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_SRGB 0x1000
/* User-argument callbacks and implementation */
#include "freeglut_ucall.h"
#ifdef __cplusplus
}
#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.
*/
/* 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) )
{
@ -60,6 +73,7 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim
}
timer->Callback = callback;
timer->CallbackData = userData;
timer->ID = timerID;
timer->TriggerTime = fgElapsedTime() + timeOut;
@ -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 )
{

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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( );

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) */
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 );
}
/*

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
*/
SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
SFG_Menu* fgCreateMenu( FGCBMenuUC menuCallback, FGCBUserData userData )
{
SFG_Window *current_window = fgStructure.CurrentWindow;
@ -136,6 +136,7 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
/* Initialize the object properties: */
menu->ID = ++fgStructure.MenuID;
menu->Callback = menuCallback;
menu->CallbackData = userData;
menu->ActiveEntry = NULL;
menu->Font = fgState.MenuFont;