#define GLUT_BORDERLESS 0x0800
#define GLUT_SRGB 0x1000
+/* User-argument callbacks and implementation */
+#include "freeglut_ucall.h"
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+#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__ */
+
* 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) )
{
"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 )
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 )
{
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;
{ NULL, NULL }, /* Timers */
{ NULL, NULL }, /* FreeTimers */
NULL, /* IdleCallback */
+ NULL, /* IdleCallbackData */
0, /* ActiveMenus */
NULL, /* MenuStateCallback */
NULL, /* MenuStatusCallback */
fgListInit( &fgState.FreeTimers );
fgState.IdleCallback = NULL;
+ fgState.IdleCallbackData = NULL;
fgState.MenuStateCallback = ( FGCBMenuState )NULL;
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* Freeglut callbacks type definitions */
+typedef void* FGCBUserData;
+
typedef void (* FGCBDisplay )( void );
typedef void (* FGCBReshape )( int, int );
typedef void (* FGCBPosition )( int, 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);
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 */
{
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 */
};
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 */
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 */
fgListRemove( &fgState.Timers, &timer->Node );
fgListAppend( &fgState.FreeTimers, &timer->Node );
- timer->Callback( timer->ID );
+ timer->Callback( timer->ID, timer->CallbackData );
}
}
fgStructure.CurrentWindow->IsMenu )
/* fail safe */
fgSetWindow( window );
- fgState.IdleCallback( );
+ fgState.IdleCallback( fgState.IdleCallbackData );
}
else
fghSleepForEvents( );
/* 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 );
/*
* 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 );
}
/*
/*
* 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;
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 );