From 3c3e3cd234acc4129a114a7b2ee606bd075e3c3f Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:20:57 +0000
Subject: [PATCH 01/20] 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
---
freeglut/freeglut/include/GL/freeglut_ext.h | 3 +
freeglut/freeglut/include/GL/freeglut_ucall.h | 93 +++++++++++++++++++
freeglut/freeglut/src/fg_callbacks.c | 38 ++++++--
freeglut/freeglut/src/fg_ext.c | 6 ++
freeglut/freeglut/src/fg_init.c | 2 +
freeglut/freeglut/src/fg_internal.h | 16 +++-
freeglut/freeglut/src/fg_main.c | 4 +-
freeglut/freeglut/src/fg_menu.c | 21 ++++-
freeglut/freeglut/src/fg_structure.c | 11 ++-
9 files changed, 173 insertions(+), 21 deletions(-)
create mode 100644 freeglut/freeglut/include/GL/freeglut_ucall.h
diff --git a/freeglut/freeglut/include/GL/freeglut_ext.h b/freeglut/freeglut/include/GL/freeglut_ext.h
index 2ef96c2..255edea 100644
--- a/freeglut/freeglut/include/GL/freeglut_ext.h
+++ b/freeglut/freeglut/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/freeglut/freeglut/include/GL/freeglut_ucall.h b/freeglut/freeglut/include/GL/freeglut_ucall.h
new file mode 100644
index 0000000..9cbe82a
--- /dev/null
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_callbacks.c b/freeglut/freeglut/src/fg_callbacks.c
index 11924b3..b09f421 100644
--- a/freeglut/freeglut/src/fg_callbacks.c
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_ext.c b/freeglut/freeglut/src/fg_ext.c
index d96849a..4c1f9c9 100644
--- a/freeglut/freeglut/src/fg_ext.c
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_init.c b/freeglut/freeglut/src/fg_init.c
index ae87212..ffd3f99 100644
--- a/freeglut/freeglut/src/fg_init.c
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index 2cecf71..8e27f54 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_main.c b/freeglut/freeglut/src/fg_main.c
index 0f47c8d..6e9ff48 100644
--- a/freeglut/freeglut/src/fg_main.c
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_menu.c b/freeglut/freeglut/src/fg_menu.c
index 36b24ce..cad5b83 100644
--- a/freeglut/freeglut/src/fg_menu.c
+++ b/freeglut/freeglut/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/freeglut/freeglut/src/fg_structure.c b/freeglut/freeglut/src/fg_structure.c
index f0bc9a2..c279b4a 100644
--- a/freeglut/freeglut/src/fg_structure.c
+++ b/freeglut/freeglut/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 );
From 827f593d96c466e182676a78387b55c376220933 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:06 +0000
Subject: [PATCH 02/20] Finished implementing all user-data callbacks (GCC-only
for now). Updated glutCreateMenu, glutIdleFunc, and glutTimerFunc so they
handle NULL callback cases. Removed glutMenuStateFuncUcall (as
glutMenuStateFunc is a depreciated function).
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1809 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/include/GL/freeglut_ucall.h | 9 +-
freeglut/freeglut/src/fg_callbacks.c | 353 +++++++++++++++---
freeglut/freeglut/src/fg_ext.c | 36 +-
freeglut/freeglut/src/fg_init.c | 48 ++-
freeglut/freeglut/src/fg_internal.h | 238 +++++++++---
freeglut/freeglut/src/fg_main.c | 4 +-
freeglut/freeglut/src/fg_menu.c | 8 +-
freeglut/freeglut/src/fg_structure.c | 14 +-
8 files changed, 569 insertions(+), 141 deletions(-)
diff --git a/freeglut/freeglut/include/GL/freeglut_ucall.h b/freeglut/freeglut/include/GL/freeglut_ucall.h
index 9cbe82a..bbbd32d 100644
--- a/freeglut/freeglut/include/GL/freeglut_ucall.h
+++ b/freeglut/freeglut/include/GL/freeglut_ucall.h
@@ -45,7 +45,6 @@ FGAPI void FGAPIENTRY glutEntryFuncUcall( void (* callback)( int, void* ), void*
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 );
@@ -76,12 +75,12 @@ FGAPI void FGAPIENTRY glutMultiPassiveFuncUcall( void (* callback)( int, int, in
* 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 );
+FGAPI void FGAPIENTRY glutInitErrorFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
+FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), 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);
+FGAPI void FGAPIENTRY glutInitContextFuncUcall( void (* callback)( void* ), void* user_data );
+FGAPI void FGAPIENTRY glutAppStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
#ifdef __cplusplus
}
diff --git a/freeglut/freeglut/src/fg_callbacks.c b/freeglut/freeglut/src/fg_callbacks.c
index b09f421..5f94b65 100644
--- a/freeglut/freeglut/src/fg_callbacks.c
+++ b/freeglut/freeglut/src/fg_callbacks.c
@@ -42,7 +42,7 @@ void FGAPIENTRY glutIdleFuncUcall( FGCBIdleUC callback, FGCBUserData userData )
fgState.IdleCallbackData = userData;
}
-void glutIdleFuncCallback( void* userData )
+static void glutIdleFuncCallback( FGCBUserData userData )
{
FGCBIdle callback = (FGCBIdle)userData;
callback();
@@ -51,7 +51,10 @@ void glutIdleFuncCallback( void* userData )
void FGAPIENTRY glutIdleFunc( FGCBIdle callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
- glutIdleFuncUcall( glutIdleFuncCallback, (FGCBUserData)callback );
+ if( callback )
+ glutIdleFuncUcall( glutIdleFuncCallback, (FGCBUserData)callback );
+ else
+ glutIdleFuncUcall( NULL, NULL );
}
/* Creates a timer and sets its callback */
@@ -87,7 +90,7 @@ void FGAPIENTRY glutTimerFuncUcall( unsigned int timeOut, FGCBTimerUC callback,
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
}
-void glutTimerFuncCallback( int ID, FGCBUserData userData )
+static void glutTimerFuncCallback( int ID, FGCBUserData userData )
{
FGCBTimer callback = (FGCBTimer)userData;
callback( ID );
@@ -96,7 +99,10 @@ void glutTimerFuncCallback( int ID, FGCBUserData userData )
void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int timerID )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );
- glutTimerFuncUcall( timeOut, glutTimerFuncCallback, timerID, (FGCBUserData)callback );
+ if( callback )
+ glutTimerFuncUcall( timeOut, glutTimerFuncCallback, timerID, (FGCBUserData)callback );
+ else
+ glutTimerFuncUcall( timeOut, NULL, timerID, NULL );
}
/* Deprecated version of glutMenuStatusFunc callback setting method */
@@ -107,10 +113,26 @@ void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback )
}
/* Sets the global menu status callback for the current window */
+void FGAPIENTRY glutMenuStatusFuncUCall( FGCBMenuStatusUC callback, FGCBUserData userData )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFuncUCall" );
+ fgState.MenuStatusCallback = callback;
+ fgState.MenuStatusCallbackData = userData;
+}
+
+static void glutMenuStatusFuncCallback( int menuState, int mouseX, int mouseY, FGCBUserData userData )
+{
+ FGCBMenuStatus callback = (FGCBMenuStatus)userData;
+ callback( menuState, mouseX, mouseY );
+}
+
void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
- fgState.MenuStatusCallback = callback;
+ if( callback )
+ glutMenuStatusFuncUCall( glutMenuStatusFuncCallback, (FGCBUserData)callback );
+ else
+ glutMenuStatusFuncUCall( NULL, NULL );
}
@@ -118,11 +140,29 @@ void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback )
* Menu specific callbacks.
*/
/* Callback upon menu destruction */
+void FGAPIENTRY glutMenuDestroyFuncUcall( FGCBDestroyUC callback, FGCBUserData userData )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFuncUcall" );
+ if( fgStructure.CurrentMenu )
+ {
+ fgStructure.CurrentMenu->Destroy = callback;
+ fgStructure.CurrentMenu->DestroyData = userData;
+ }
+}
+
+static void glutMenuDestroyFuncCallback( FGCBUserData userData )
+{
+ FGCBDestroy callback = (FGCBDestroy)userData;
+ callback();
+}
+
void FGAPIENTRY glutMenuDestroyFunc( FGCBDestroy callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );
- if( fgStructure.CurrentMenu )
- fgStructure.CurrentMenu->Destroy = callback;
+ if( callback )
+ glutMenuDestroyFuncUcall( glutMenuDestroyFuncCallback, (FGCBUserData)callback );
+ else
+ glutMenuDestroyFuncUcall( NULL, NULL );
}
@@ -134,73 +174,189 @@ do \
{ \
if( fgStructure.CurrentWindow == NULL ) \
return; \
- SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \
+ SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback, userData ); \
} while( 0 )
+/*
+ * Types need to be defined for callbacks. It's not ideal, but it works for this.
+ */
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
+static void glut##a##FuncCallback( FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback(); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,b) \
+static void glut##a##FuncCallback( int arg1val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
+static void glut##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,arg1,arg2,arg3) \
+static void glut##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val, arg3val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,int,int,int)
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,b) \
+static void glut##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val, arg3val, arg4val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,b) \
+static void glut##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val, arg3val, arg4val, arg5val ); \
+}
/*
* And almost every time the callback setter function can be implemented like this:
*/
-#define IMPLEMENT_CALLBACK_FUNC_2NAME(a,b) \
+#define IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,b) \
+void FGAPIENTRY glut##a##FuncUcall( FGCB##b##UC callback, FGCBUserData userData ) \
+{ \
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"FuncUcall" ); \
+ SET_CALLBACK( b ); \
+} \
void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
{ \
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
- SET_CALLBACK( b ); \
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
+ if( callback ) \
+ glut##a##FuncUcall( glut##a##FuncCallback, (FGCBUserData)callback ); \
+ else \
+ glut##a##FuncUcall( NULL, NULL ); \
}
-#define IMPLEMENT_CALLBACK_FUNC(a) IMPLEMENT_CALLBACK_FUNC_2NAME(a,a)
+/*
+ * Combine _glut and _cb macros:
+ */
+#define IMPLEMENT_CALLBACK_FUNC_ARG0(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG0_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,b)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG1(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG2(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG2_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,b)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG3(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG3_USER(a,arg1,arg2,arg3) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,a,arg1,arg2,arg3)\
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG4(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CALLBACK_FUNC_ARG5(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
/* Implement all these callback setter functions... */
-IMPLEMENT_CALLBACK_FUNC(Position)
-IMPLEMENT_CALLBACK_FUNC(Keyboard)
-IMPLEMENT_CALLBACK_FUNC(KeyboardUp)
-IMPLEMENT_CALLBACK_FUNC(Special)
-IMPLEMENT_CALLBACK_FUNC(SpecialUp)
-IMPLEMENT_CALLBACK_FUNC(Mouse)
-IMPLEMENT_CALLBACK_FUNC(MouseWheel)
-IMPLEMENT_CALLBACK_FUNC(Motion)
-IMPLEMENT_CALLBACK_FUNC_2NAME(PassiveMotion,Passive)
-IMPLEMENT_CALLBACK_FUNC(Entry)
+IMPLEMENT_CALLBACK_FUNC_ARG2(Position)
+IMPLEMENT_CALLBACK_FUNC_ARG3_USER(Keyboard,unsigned char,int,int)
+IMPLEMENT_CALLBACK_FUNC_ARG3_USER(KeyboardUp,unsigned char,int,int)
+IMPLEMENT_CALLBACK_FUNC_ARG3(Special)
+IMPLEMENT_CALLBACK_FUNC_ARG3(SpecialUp)
+IMPLEMENT_CALLBACK_FUNC_ARG4(Mouse)
+IMPLEMENT_CALLBACK_FUNC_ARG4(MouseWheel)
+IMPLEMENT_CALLBACK_FUNC_ARG2(Motion)
+IMPLEMENT_CALLBACK_FUNC_ARG2_2NAME(PassiveMotion,Passive)
+IMPLEMENT_CALLBACK_FUNC_ARG1(Entry)
/* glutWMCloseFunc is an alias for glutCloseFunc; both set the window's Destroy callback */
-IMPLEMENT_CALLBACK_FUNC_2NAME(Close,Destroy)
-IMPLEMENT_CALLBACK_FUNC_2NAME(WMClose,Destroy)
-IMPLEMENT_CALLBACK_FUNC(OverlayDisplay)
-IMPLEMENT_CALLBACK_FUNC(WindowStatus)
-IMPLEMENT_CALLBACK_FUNC(ButtonBox)
-IMPLEMENT_CALLBACK_FUNC(Dials)
-IMPLEMENT_CALLBACK_FUNC(TabletMotion)
-IMPLEMENT_CALLBACK_FUNC(TabletButton)
-IMPLEMENT_CALLBACK_FUNC(MultiEntry)
-IMPLEMENT_CALLBACK_FUNC(MultiButton)
-IMPLEMENT_CALLBACK_FUNC(MultiMotion)
-IMPLEMENT_CALLBACK_FUNC(MultiPassive)
-IMPLEMENT_CALLBACK_FUNC(InitContext)
-IMPLEMENT_CALLBACK_FUNC(AppStatus)
-
-
+IMPLEMENT_CALLBACK_FUNC_ARG0_2NAME(Close,Destroy)
+IMPLEMENT_CALLBACK_FUNC_ARG0_2NAME(WMClose,Destroy)
+IMPLEMENT_CALLBACK_FUNC_ARG0(OverlayDisplay)
+IMPLEMENT_CALLBACK_FUNC_ARG1(WindowStatus)
+IMPLEMENT_CALLBACK_FUNC_ARG2(ButtonBox)
+IMPLEMENT_CALLBACK_FUNC_ARG2(Dials)
+IMPLEMENT_CALLBACK_FUNC_ARG2(TabletMotion)
+IMPLEMENT_CALLBACK_FUNC_ARG4(TabletButton)
+IMPLEMENT_CALLBACK_FUNC_ARG2(MultiEntry)
+IMPLEMENT_CALLBACK_FUNC_ARG5(MultiButton)
+IMPLEMENT_CALLBACK_FUNC_ARG3(MultiMotion)
+IMPLEMENT_CALLBACK_FUNC_ARG3(MultiPassive)
+IMPLEMENT_CALLBACK_FUNC_ARG0(InitContext)
+IMPLEMENT_CALLBACK_FUNC_ARG1(AppStatus)
/*
* Sets the Display callback for the current window
*/
-void FGAPIENTRY glutDisplayFunc( FGCBDisplay callback )
+void FGAPIENTRY glutDisplayFuncUcall( FGCBDisplayUC callback, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFuncUcall" );
if( !callback )
fgError( "Fatal error in program. NULL display callback not "
"permitted in GLUT 3.0+ or freeglut 2.0.1+" );
SET_CALLBACK( Display );
}
-void fghDefaultReshape(int width, int height)
+static void glutDisplayFuncCallback( FGCBUserData userData )
+{
+ FGCBDisplay callback = (FGCBDisplay)userData;
+ callback();
+}
+
+void FGAPIENTRY glutDisplayFunc( FGCBDisplay callback )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
+ if( callback )
+ glutDisplayFuncUcall( glutDisplayFuncCallback, (FGCBUserData)callback );
+ else
+ glutDisplayFuncUcall( NULL, NULL );
+}
+
+void fghDefaultReshape( int width, int height, FGCBUserData userData )
{
glViewport( 0, 0, width, height );
}
+void FGAPIENTRY glutReshapeFuncUcall( FGCBReshapeUC callback, FGCBUserData userData )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFuncUcall" );
+
+ if( !callback )
+ {
+ callback = fghDefaultReshape;
+ userData = NULL;
+ }
+
+ SET_CALLBACK( Reshape );
+}
+
+static void glutReshapeFuncCallback( int width, int height, FGCBUserData userData )
+{
+ FGCBReshape callback = (FGCBReshape)userData;
+ callback( width, height );
+}
+
void FGAPIENTRY glutReshapeFunc( FGCBReshape callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );
-
- if( !callback )
- callback = fghDefaultReshape;
-
- SET_CALLBACK( Reshape );
+ if( callback )
+ glutReshapeFuncUcall( glutReshapeFuncCallback, (FGCBUserData)callback );
+ else
+ glutReshapeFuncUcall( NULL, NULL );
}
/*
@@ -218,7 +374,7 @@ void FGAPIENTRY glutReshapeFunc( FGCBReshape callback )
* http://stackoverflow.com/questions/5445889/get-which-process-window-is-actually-visible-in-c-sharp
* for an implementation outline (but it would be polling based, not push based).
*/
-static void fghVisibility( int status )
+static void fghVisibility( int status, FGCBUserData userData )
{
int vis_status;
@@ -234,23 +390,44 @@ static void fghVisibility( int status )
INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( vis_status ) );
}
-void FGAPIENTRY glutVisibilityFunc( FGCBVisibility callback )
+void FGAPIENTRY glutVisibilityFuncUcall( FGCBVisibilityUC callback, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFuncUcall" );
+
+ if ( !callback )
+ {
+ userData = NULL;
+ }
+
SET_CALLBACK( Visibility );
if( callback )
- glutWindowStatusFunc( fghVisibility );
+ glutWindowStatusFuncUcall( fghVisibility, NULL );
else
- glutWindowStatusFunc( NULL );
+ glutWindowStatusFuncUcall( NULL, NULL );
+}
+
+static void glutVisibilityFuncCallback( int visibility, FGCBUserData userData )
+{
+ FGCBVisibility callback = (FGCBVisibility)userData;
+ callback( visibility );
+}
+
+void FGAPIENTRY glutVisibilityFunc( FGCBVisibility callback )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
+ if( callback )
+ glutVisibilityFuncUcall( glutVisibilityFuncCallback, (FGCBUserData)callback );
+ else
+ glutVisibilityFuncUcall( NULL, NULL );
}
/*
* Sets the joystick callback and polling rate for the current window
*/
-void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
+void FGAPIENTRY glutJoystickFuncUcall( FGCBJoystickUC callback, int pollInterval, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFuncUcall" );
fgInitialiseJoysticks ();
if ( (
@@ -281,39 +458,97 @@ void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
fgStructure.CurrentWindow->State.JoystickLastPoll -= pollInterval;
}
+static void glutJoystickFuncCallback( unsigned int buttons, int axis0, int axis1, int axis2, FGCBUserData userData )
+{
+ FGCBJoystick callback = (FGCBJoystick)userData;
+ callback( buttons, axis0, axis1, axis2 );
+}
+void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
+ if( callback )
+ glutJoystickFuncUcall( glutJoystickFuncCallback, pollInterval, (FGCBUserData)callback );
+ else
+ glutJoystickFuncUcall( NULL, pollInterval, NULL );
+}
/*
* Sets the spaceball motion callback for the current window
*/
-void FGAPIENTRY glutSpaceballMotionFunc( FGCBSpaceMotion callback )
+void FGAPIENTRY glutSpaceballMotionFuncUcall( FGCBSpaceMotionUC callback, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFuncUcall" );
fgInitialiseSpaceball();
SET_CALLBACK( SpaceMotion );
}
+static void glutSpaceballMotionFuncCallback( int x, int y, int z, FGCBUserData userData )
+{
+ FGCBSpaceMotion callback = (FGCBSpaceMotion)userData;
+ callback( x, y, z );
+}
+
+void FGAPIENTRY glutSpaceballMotionFunc( FGCBSpaceMotion callback )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
+ if( callback )
+ glutSpaceballMotionFuncUcall( glutSpaceballMotionFuncCallback, (FGCBUserData)callback );
+ else
+ glutSpaceballMotionFuncUcall( NULL, NULL );
+}
+
/*
* Sets the spaceball rotate callback for the current window
*/
-void FGAPIENTRY glutSpaceballRotateFunc( FGCBSpaceRotation callback )
+void FGAPIENTRY glutSpaceballRotateFuncUcall( FGCBSpaceRotationUC callback, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFuncUcall" );
fgInitialiseSpaceball();
SET_CALLBACK( SpaceRotation );
}
+static void glutSpaceballRotateFuncCallback( int x, int y, int z, FGCBUserData userData )
+{
+ FGCBSpaceRotation callback = (FGCBSpaceRotation)userData;
+ callback( x, y, z );
+}
+
+void FGAPIENTRY glutSpaceballRotateFunc( FGCBSpaceRotation callback )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
+ if( callback )
+ glutSpaceballRotateFuncUcall( glutSpaceballRotateFuncCallback, (FGCBUserData)callback );
+ else
+ glutSpaceballRotateFuncUcall( NULL, NULL );
+}
+
/*
* Sets the spaceball button callback for the current window
*/
-void FGAPIENTRY glutSpaceballButtonFunc( FGCBSpaceButton callback )
+void FGAPIENTRY glutSpaceballButtonFuncUcall( FGCBSpaceButtonUC callback, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFuncUcall" );
fgInitialiseSpaceball();
SET_CALLBACK( SpaceButton );
}
+static void glutSpaceballButtonFuncCallback( int button, int buttonState, FGCBUserData userData )
+{
+ FGCBSpaceButton callback = (FGCBSpaceButton)userData;
+ callback( button, buttonState );
+}
+
+void FGAPIENTRY glutSpaceballButtonFunc( FGCBSpaceButton callback )
+{
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
+ if( callback )
+ glutSpaceballButtonFuncUcall( glutSpaceballButtonFuncCallback, (FGCBUserData)callback );
+ else
+ glutSpaceballButtonFuncUcall( NULL, NULL );
+}
+
/*** END OF FILE ***/
diff --git a/freeglut/freeglut/src/fg_ext.c b/freeglut/freeglut/src/fg_ext.c
index 4c1f9c9..0ddb560 100644
--- a/freeglut/freeglut/src/fg_ext.c
+++ b/freeglut/freeglut/src/fg_ext.c
@@ -215,7 +215,41 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
CHECK_NAME(glutCreateMenuUcall);
CHECK_NAME(glutTimerFuncUcall);
CHECK_NAME(glutIdleFuncUcall);
- //TODO
+ CHECK_NAME(glutKeyboardFuncUcall);
+ CHECK_NAME(glutSpecialFuncUcall);
+ CHECK_NAME(glutReshapeFuncUcall);
+ CHECK_NAME(glutVisibilityFuncUcall);
+ CHECK_NAME(glutDisplayFuncUcall);
+ CHECK_NAME(glutMouseFuncUcall);
+ CHECK_NAME(glutMotionFuncUcall);
+ CHECK_NAME(glutPassiveMotionFuncUcall);
+ CHECK_NAME(glutEntryFuncUcall);
+ CHECK_NAME(glutKeyboardUpFuncUcall);
+ CHECK_NAME(glutSpecialUpFuncUcall);
+ CHECK_NAME(glutJoystickFuncUcall);
+ CHECK_NAME(glutMenuStatusFuncUcall);
+ CHECK_NAME(glutOverlayDisplayFuncUcall);
+ CHECK_NAME(glutWindowStatusFuncUcall);
+ CHECK_NAME(glutSpaceballMotionFuncUcall);
+ CHECK_NAME(glutSpaceballRotateFuncUcall);
+ CHECK_NAME(glutSpaceballButtonFuncUcall);
+ CHECK_NAME(glutButtonBoxFuncUcall);
+ CHECK_NAME(glutDialsFuncUcall);
+ CHECK_NAME(glutTabletMotionFuncUcall);
+ CHECK_NAME(glutTabletButtonFuncUcall);
+ CHECK_NAME(glutMouseWheelFuncUcall);
+ CHECK_NAME(glutPositionFuncUcall);
+ CHECK_NAME(glutCloseFuncUcall);
+ CHECK_NAME(glutWMCloseFuncUcall);
+ CHECK_NAME(glutMenuDestroyFuncUcall);
+ CHECK_NAME(glutMultiEntryFuncUcall);
+ CHECK_NAME(glutMultiButtonFuncUcall);
+ CHECK_NAME(glutMultiMotionFuncUcall);
+ CHECK_NAME(glutMultiPassiveFuncUcall);
+ CHECK_NAME(glutInitErrorFuncUcall);
+ CHECK_NAME(glutInitWarningFuncUcall);
+ CHECK_NAME(glutInitContextFuncUcall);
+ CHECK_NAME(glutAppStatusFuncUcall);
#undef CHECK_NAME
return NULL;
diff --git a/freeglut/freeglut/src/fg_init.c b/freeglut/freeglut/src/fg_init.c
index ffd3f99..a408bbe 100644
--- a/freeglut/freeglut/src/fg_init.c
+++ b/freeglut/freeglut/src/fg_init.c
@@ -74,6 +74,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
0, /* ActiveMenus */
NULL, /* MenuStateCallback */
NULL, /* MenuStatusCallback */
+ NULL, /* MenuStatusCallbackData */
FREEGLUT_MENU_FONT,
{ -1, -1, GL_TRUE }, /* GameModeSize */
-1, /* GameModeDepth */
@@ -96,7 +97,9 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
0, /* OpenGL ContextProfile */
0, /* HasOpenGL20 */
NULL, /* ErrorFunc */
- NULL /* WarningFunc */
+ NULL, /* ErrorFuncData */
+ NULL, /* WarningFunc */
+ NULL /* WarningFuncData */
};
@@ -299,10 +302,11 @@ void fgDeinitialize( void )
fgListInit( &fgState.Timers );
fgListInit( &fgState.FreeTimers );
- fgState.IdleCallback = NULL;
- fgState.IdleCallbackData = NULL;
- fgState.MenuStateCallback = ( FGCBMenuState )NULL;
- fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
+ fgState.IdleCallback = ( FGCBIdleUC )NULL;
+ fgState.IdleCallbackData = NULL;
+ fgState.MenuStateCallback = ( FGCBMenuState )NULL;
+ fgState.MenuStatusCallback = ( FGCBMenuStatusUC )NULL;
+ fgState.MenuStatusCallbackData = NULL;
fgState.SwapCount = 0;
fgState.SwapTime = 0;
@@ -670,19 +674,49 @@ void FGAPIENTRY glutInitContextProfile( int profile )
/*
* Sets the user error handler (note the use of va_list for the args to the fmt)
*/
-void FGAPIENTRY glutInitErrorFunc( FGError callback )
+void FGAPIENTRY glutInitErrorFuncUcall( FGErrorUC callback, FGCBUserData userData )
{
/* This allows user programs to handle freeglut errors */
fgState.ErrorFunc = callback;
+ fgState.ErrorFuncData = userData;
+}
+
+static void glutInitErrorFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
+{
+ FGError callback = (FGError)userData;
+ callback( fmt, ap );
+}
+
+void FGAPIENTRY glutInitErrorFunc( FGError callback )
+{
+ if (callback)
+ glutInitErrorFuncUcall( glutInitErrorFuncCallback, (FGCBUserData)callback );
+ else
+ glutInitErrorFuncUcall( NULL, NULL );
}
/*
* Sets the user warning handler (note the use of va_list for the args to the fmt)
*/
-void FGAPIENTRY glutInitWarningFunc( FGWarning callback )
+void FGAPIENTRY glutInitWarningFuncUcall( FGWarningUC callback, FGCBUserData userData )
{
/* This allows user programs to handle freeglut warnings */
fgState.WarningFunc = callback;
+ fgState.WarningFuncData = userData;
+}
+
+static void glutInitWarningFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
+{
+ FGWarning callback = (FGWarning)userData;
+ callback( fmt, ap );
+}
+
+void FGAPIENTRY glutInitWarningFunc( FGWarning callback )
+{
+ if (callback)
+ glutInitWarningFuncUcall( glutInitWarningFuncCallback, (FGCBUserData)callback );
+ else
+ glutInitWarningFuncUcall( NULL, NULL );
}
/*** END OF FILE ***/
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index 8e27f54..69401d0 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/src/fg_internal.h
@@ -218,54 +218,87 @@
/* Freeglut callbacks type definitions */
typedef void* FGCBUserData;
-typedef void (* FGCBDisplay )( void );
-typedef void (* FGCBReshape )( int, int );
-typedef void (* FGCBPosition )( int, int );
-typedef void (* FGCBVisibility )( int );
-typedef void (* FGCBKeyboard )( unsigned char, int, int );
-typedef void (* FGCBKeyboardUp )( unsigned char, int, int );
-typedef void (* FGCBSpecial )( int, int, int );
-typedef void (* FGCBSpecialUp )( int, int, int );
-typedef void (* FGCBMouse )( int, int, int, int );
-typedef void (* FGCBMouseWheel )( int, int, int, int );
-typedef void (* FGCBMotion )( int, int );
-typedef void (* FGCBPassive )( int, int );
-typedef void (* FGCBEntry )( int );
-typedef void (* FGCBWindowStatus )( int );
-typedef void (* FGCBJoystick )( unsigned int, int, int, int );
-typedef void (* FGCBOverlayDisplay)( void );
-typedef void (* FGCBSpaceMotion )( int, int, int );
-typedef void (* FGCBSpaceRotation )( int, int, int );
-typedef void (* FGCBSpaceButton )( int, int );
-typedef void (* FGCBDials )( int, int );
-typedef void (* FGCBButtonBox )( int, int );
-typedef void (* FGCBTabletMotion )( int, int );
-typedef void (* FGCBTabletButton )( int, int, int, int );
-typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */
+typedef void (* FGCBDisplay )( void );
+typedef void (* FGCBDisplayUC )( FGCBUserData );
+typedef void (* FGCBReshape )( int, int );
+typedef void (* FGCBReshapeUC )( int, int, FGCBUserData );
+typedef void (* FGCBPosition )( int, int );
+typedef void (* FGCBPositionUC )( int, int, FGCBUserData );
+typedef void (* FGCBVisibility )( int );
+typedef void (* FGCBVisibilityUC )( int, FGCBUserData );
+typedef void (* FGCBKeyboard )( unsigned char, int, int );
+typedef void (* FGCBKeyboardUC )( unsigned char, int, int, FGCBUserData );
+typedef void (* FGCBKeyboardUp )( unsigned char, int, int );
+typedef void (* FGCBKeyboardUpUC )( unsigned char, int, int, FGCBUserData );
+typedef void (* FGCBSpecial )( int, int, int );
+typedef void (* FGCBSpecialUC )( int, int, int, FGCBUserData );
+typedef void (* FGCBSpecialUp )( int, int, int );
+typedef void (* FGCBSpecialUpUC )( int, int, int, FGCBUserData );
+typedef void (* FGCBMouse )( int, int, int, int );
+typedef void (* FGCBMouseUC )( int, int, int, int, FGCBUserData );
+typedef void (* FGCBMouseWheel )( int, int, int, int );
+typedef void (* FGCBMouseWheelUC )( int, int, int, int, FGCBUserData );
+typedef void (* FGCBMotion )( int, int );
+typedef void (* FGCBMotionUC )( int, int, FGCBUserData );
+typedef void (* FGCBPassive )( int, int );
+typedef void (* FGCBPassiveUC )( int, int, FGCBUserData );
+typedef void (* FGCBEntry )( int );
+typedef void (* FGCBEntryUC )( int, FGCBUserData );
+typedef void (* FGCBWindowStatus )( int );
+typedef void (* FGCBWindowStatusUC )( int, FGCBUserData );
+typedef void (* FGCBJoystick )( unsigned int, int, int, int );
+typedef void (* FGCBJoystickUC )( unsigned int, int, int, int, FGCBUserData );
+typedef void (* FGCBOverlayDisplay )( void );
+typedef void (* FGCBOverlayDisplayUC)( FGCBUserData );
+typedef void (* FGCBSpaceMotion )( int, int, int );
+typedef void (* FGCBSpaceMotionUC )( int, int, int, FGCBUserData );
+typedef void (* FGCBSpaceRotation )( int, int, int );
+typedef void (* FGCBSpaceRotationUC )( int, int, int, FGCBUserData );
+typedef void (* FGCBSpaceButton )( int, int );
+typedef void (* FGCBSpaceButtonUC )( int, int, FGCBUserData );
+typedef void (* FGCBDials )( int, int );
+typedef void (* FGCBDialsUC )( int, int, FGCBUserData );
+typedef void (* FGCBButtonBox )( int, int );
+typedef void (* FGCBButtonBoxUC )( int, int, FGCBUserData );
+typedef void (* FGCBTabletMotion )( int, int );
+typedef void (* FGCBTabletMotionUC )( int, int, FGCBUserData );
+typedef void (* FGCBTabletButton )( int, int, int, int );
+typedef void (* FGCBTabletButtonUC )( int, int, int, int, FGCBUserData );
+typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */
+typedef void (* FGCBDestroyUC )( FGCBUserData );
-typedef void (* FGCBMultiEntry )( int, int );
-typedef void (* FGCBMultiButton )( int, int, int, int, int );
-typedef void (* FGCBMultiMotion )( int, int, int );
-typedef void (* FGCBMultiPassive )( int, int, int );
+typedef void (* FGCBMultiEntry )( int, int );
+typedef void (* FGCBMultiEntryUC )( int, int, FGCBUserData );
+typedef void (* FGCBMultiButton )( int, int, int, int, int );
+typedef void (* FGCBMultiButtonUC )( int, int, int, int, int, FGCBUserData );
+typedef void (* FGCBMultiMotion )( int, int, int );
+typedef void (* FGCBMultiMotionUC )( int, int, int, FGCBUserData );
+typedef void (* FGCBMultiPassive )( int, int, int );
+typedef void (* FGCBMultiPassiveUC )( int, int, int, FGCBUserData );
-typedef void (* FGCBInitContext)();
-typedef void (* FGCBAppStatus)(int);
+typedef void (* FGCBInitContext )( void );
+typedef void (* FGCBInitContextUC )( FGCBUserData );
+typedef void (* FGCBAppStatus )( int );
+typedef void (* FGCBAppStatusUC )( int, FGCBUserData );
/* 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 );
+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 );
+typedef void (* FGCBMenuStatusUC )( int, int, int, FGCBUserData );
/* The callback used when creating/using menus */
-typedef void (* FGCBMenu )( int );
-typedef void (* FGCBMenuUC )( int, FGCBUserData );
+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);
-typedef void (* FGWarning ) ( const char *fmt, va_list ap);
+typedef void (* FGError )( const char *fmt, va_list ap );
+typedef void (* FGErrorUC )( const char *fmt, va_list ap, FGCBUserData userData );
+typedef void (* FGWarning )( const char *fmt, va_list ap );
+typedef void (* FGWarningUC )( const char *fmt, va_list ap, FGCBUserData userData );
/* A list structure */
@@ -337,24 +370,25 @@ struct tagSFG_State
int ActiveMenus; /* Num. of currently active menus */
FGCBMenuState MenuStateCallback; /* Menu callbacks are global */
- FGCBMenuStatus MenuStatusCallback;
+ FGCBMenuStatusUC MenuStatusCallback;
+ FGCBUserData MenuStatusCallbackData;
void* MenuFont; /* Font to be used for newly created menus */
SFG_XYUse GameModeSize; /* Game mode screen's dimensions */
int GameModeDepth; /* The pixel depth for game mode */
int GameModeRefresh; /* The refresh rate for game mode */
- int ActionOnWindowClose; /* Action when user closes window */
+ int ActionOnWindowClose; /* Action when user closes window */
- fgExecutionState ExecState; /* Used for GLUT termination */
- char *ProgramName; /* Name of the invoking program */
- GLboolean JoysticksInitialised; /* Only initialize if application calls for them */
- int NumActiveJoysticks; /* Number of active joysticks (callback defined and positive pollrate) -- if zero, don't poll joysticks */
- GLboolean InputDevsInitialised; /* Only initialize if application calls for them */
+ fgExecutionState ExecState; /* Used for GLUT termination */
+ char *ProgramName; /* Name of the invoking program */
+ GLboolean JoysticksInitialised; /* Only initialize if application calls for them */
+ int NumActiveJoysticks; /* Number of active joysticks (callback defined and positive pollrate) -- if zero, don't poll joysticks */
+ GLboolean InputDevsInitialised; /* Only initialize if application calls for them */
int MouseWheelTicks; /* Number of ticks the mouse wheel has turned */
- int AuxiliaryBufferNumber; /* Number of auxiliary buffers */
+ int AuxiliaryBufferNumber;/* Number of auxiliary buffers */
int SampleNumber; /* Number of samples per pixel */
GLboolean SkipStaleMotion; /* skip stale motion events */
@@ -367,8 +401,10 @@ struct tagSFG_State
int ContextFlags; /* OpenGL context flags */
int ContextProfile; /* OpenGL context profile */
int HasOpenGL20; /* fgInitGL2 could find all OpenGL 2.0 functions */
- FGError ErrorFunc; /* User defined error handler */
- FGWarning WarningFunc; /* User defined warning handler */
+ FGErrorUC ErrorFunc; /* User defined error handler */
+ FGCBUserData ErrorFuncData; /* User defined error handler user data */
+ FGWarningUC WarningFunc; /* User defined warning handler */
+ FGCBUserData WarningFuncData; /* User defined warning handler user data */
};
/* The structure used by display initialization in fg_init.c */
@@ -518,11 +554,12 @@ typedef void (*SFG_Proc)();
/*
* SET_WCB() is used as:
*
- * SET_WCB( window, cbname, func );
+ * SET_WCB( window, cbname, func, udata );
*
* ...where {window} is the freeglut window to set the callback,
* {cbname} is the window-specific callback to set,
- * {func} is a function-pointer.
+ * {func} is a function-pointer,
+ * {udata} is a void* pointer for user data.
*
* Originally, {FETCH_WCB( ... ) = func} was rather sloppily used,
* but this can cause warnings because the FETCH_WCB() macro type-
@@ -532,11 +569,14 @@ typedef void (*SFG_Proc)();
* and for no other reason. Since it's hidden in the macro, the
* ugliness is felt to be rather benign.
*/
-#define SET_WCB(window,cbname,func) \
+#define SET_WCB(window,cbname,func,udata) \
do \
{ \
if( FETCH_WCB( window, cbname ) != (SFG_Proc)(func) ) \
+ { \
(((window).CallBacks[WCB_ ## cbname]) = (SFG_Proc)(func)); \
+ (((window).CallbackDatas[WCB_ ## cbname]) = (udata)); \
+ } \
} while( 0 )
/*
@@ -553,6 +593,82 @@ do \
#define FETCH_WCB(window,cbname) \
((window).CallBacks[WCB_ ## cbname])
+/*
+ * FETCH_USER_DATA_WCB() is used as:
+ *
+ * FETCH_USER_DATA_WCB( window, cbname );
+ *
+ * ...where {window} is the freeglut window,
+ * {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.
+ */
+#define FETCH_USER_DATA_WCB(window,cbname) \
+ ((window).CallbackDatas[WCB_ ## cbname])
+
+/*
+ * EXPAND_WCB() is used as:
+ *
+ * EXPAND_WCB arg_list
+ *
+ * ... where {(arg_list)} is the parameter list.
+ *
+ * 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
+ *
+ * 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"
+ */
+#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:
*
@@ -578,9 +694,10 @@ do \
{ \
if( FETCH_WCB( window, cbname ) ) \
{ \
- FGCB ## cbname func = (FGCB ## cbname)(FETCH_WCB( window, cbname )); \
+ FGCB ## cbname ## UC func = (FGCB ## cbname ## UC)(FETCH_WCB( window, cbname )); \
+ FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \
fgSetWindow( &window ); \
- func arg_list; \
+ func EXPAND_WCB arg_list; \
} \
} while( 0 )
#else
@@ -590,7 +707,8 @@ do \
if( FETCH_WCB( window, cbname ) ) \
{ \
fgSetWindow( &window ); \
- ((FGCB ## cbname)FETCH_WCB( window, cbname )) arg_list; \
+ FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \
+ ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB arg_list; \
} \
} while( 0 )
#endif
@@ -671,7 +789,8 @@ struct tagSFG_Menu
SFG_List Entries; /* The menu entries list */
FGCBMenuUC Callback; /* The menu callback */
FGCBUserData CallbackData; /* The menu callback user data */
- FGCBDestroy Destroy; /* Destruction callback */
+ FGCBDestroyUC Destroy; /* Destruction callback */
+ FGCBUserData DestroyData; /* Destruction callback user data */
GLboolean IsActive; /* Is the menu selected? */
void* Font; /* Font to be used for displaying this menu */
int Width; /* Menu box width in pixels */
@@ -709,10 +828,11 @@ struct tagSFG_Window
SFG_Context Window; /* Window and OpenGL context */
SFG_WindowState State; /* The window state */
SFG_Proc CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */
+ FGCBUserData CallbackDatas[ TOTAL_CALLBACKS ]; /* Array of window callback datas */
void *UserData ; /* For use by user */
- SFG_Menu* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */
- SFG_Menu* ActiveMenu; /* The window's active menu */
+ SFG_Menu* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */
+ SFG_Menu* ActiveMenu; /* The window's active menu */
SFG_Window* Parent; /* The parent to this window */
SFG_List Children; /* The subwindows d.l. list */
diff --git a/freeglut/freeglut/src/fg_main.c b/freeglut/freeglut/src/fg_main.c
index 6e9ff48..45f13f5 100644
--- a/freeglut/freeglut/src/fg_main.c
+++ b/freeglut/freeglut/src/fg_main.c
@@ -269,7 +269,7 @@ void fgError( const char *fmt, ... )
va_start( ap, fmt );
/* call user set error handler here */
- fgState.ErrorFunc(fmt, ap);
+ fgState.ErrorFunc(fmt, ap, fgState.ErrorFuncData);
va_end( ap );
@@ -302,7 +302,7 @@ void fgWarning( const char *fmt, ... )
va_start( ap, fmt );
/* call user set warning handler here */
- fgState.WarningFunc(fmt, ap);
+ fgState.WarningFunc(fmt, ap, fgState.WarningFuncData);
va_end( ap );
diff --git a/freeglut/freeglut/src/fg_menu.c b/freeglut/freeglut/src/fg_menu.c
index cad5b83..1b07b1a 100644
--- a/freeglut/freeglut/src/fg_menu.c
+++ b/freeglut/freeglut/src/fg_menu.c
@@ -531,7 +531,7 @@ static void fghActivateMenu( SFG_Window* window, int button )
fgState.MenuStateCallback(GLUT_MENU_IN_USE);
if (fgState.MenuStatusCallback)
/* window->State.MouseX and window->State.MouseY are relative to client area origin, as needed */
- fgState.MenuStatusCallback(GLUT_MENU_IN_USE, window->State.MouseX, window->State.MouseY);
+ fgState.MenuStatusCallback(GLUT_MENU_IN_USE, window->State.MouseX, window->State.MouseY, fgState.MenuStatusCallbackData);
}
fgSetWindow( menu->Window );
@@ -725,7 +725,7 @@ void fgDeactivateMenu( SFG_Window *window )
SFG_XYUse mouse_pos;
fghPlatformGetCursorPos(parent_window, GL_TRUE, &mouse_pos);
- fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y);
+ fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y, fgState.MenuStatusCallbackData);
}
}
}
@@ -791,7 +791,7 @@ int FGAPIENTRY glutCreateMenuUcall( FGCBMenuUC callback, FGCBUserData userData )
}
/* Standard glutCreateMenu */
-void glutCreateMenuCallback( int menu, FGCBUserData userData )
+static void glutCreateMenuCallback( int menu, FGCBUserData userData )
{
FGCBMenu callback = (FGCBMenu)userData;
callback( menu );
@@ -800,6 +800,8 @@ void glutCreateMenuCallback( int menu, FGCBUserData userData )
int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
+ if (!callback)
+ return glutCreateMenuUcall( NULL, NULL );
return glutCreateMenuUcall( glutCreateMenuCallback, (FGCBUserData)callback );
}
diff --git a/freeglut/freeglut/src/fg_structure.c b/freeglut/freeglut/src/fg_structure.c
index c279b4a..4274667 100644
--- a/freeglut/freeglut/src/fg_structure.c
+++ b/freeglut/freeglut/src/fg_structure.c
@@ -49,7 +49,7 @@ SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
extern void fgPlatformCreateWindow ( SFG_Window *window );
-extern void fghDefaultReshape(int width, int height);
+extern void fghDefaultReshape(int width, int height, FGCBUserData userData);
static void fghClearCallBacks( SFG_Window *window )
{
@@ -57,7 +57,10 @@ static void fghClearCallBacks( SFG_Window *window )
{
int i;
for( i = 0; i < TOTAL_CALLBACKS; ++i )
+ {
window->CallBacks[ i ] = NULL;
+ window->CallbackDatas[ i ] = NULL;
+ }
}
}
@@ -83,7 +86,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
fgPlatformCreateWindow ( window );
fghClearCallBacks( window );
- SET_WCB( *window, Reshape, fghDefaultReshape);
+ SET_WCB( *window, Reshape, fghDefaultReshape, NULL);
/* Initialize the object properties */
window->ID = ++fgStructure.WindowID;
@@ -174,9 +177,10 @@ void fgAddToWindowDestroyList( SFG_Window* window )
* to ensure that they are no longer called after this point.
*/
{
- FGCBDestroy destroy = (FGCBDestroy)FETCH_WCB( *window, Destroy );
+ FGCBDestroyUC destroy = (FGCBDestroyUC)FETCH_WCB( *window, Destroy );
+ FGCBUserData destroyData = FETCH_USER_DATA_WCB( *window, Destroy );
fghClearCallBacks( window );
- SET_WCB( *window, Destroy, destroy );
+ SET_WCB( *window, Destroy, destroy, destroyData );
}
}
@@ -303,7 +307,7 @@ void fgDestroyMenu( SFG_Menu* menu )
{
SFG_Menu *activeMenu=fgStructure.CurrentMenu;
fgStructure.CurrentMenu = menu;
- menu->Destroy( );
+ menu->Destroy( menu->DestroyData );
fgStructure.CurrentMenu = activeMenu;
}
From da0b7b3369ced228d4953cff9b324d3e564c6722 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:14 +0000
Subject: [PATCH 03/20] Changed EXPAND_WCB so it works with MSVC and GCC
- Required adding an "argument expansion macro" for each callback (hope to remove eventually)
- Fixed MSVC linking error where glutMenuStatusFuncUCall had the incorrect case and should've been glutMenuStatusFuncUcall
- Updated formatting of some freeglut_ext.h functions
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1810 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/CMakeLists.txt | 1 +
freeglut/freeglut/include/GL/freeglut_ext.h | 10 +--
freeglut/freeglut/src/fg_callbacks.c | 11 ++-
freeglut/freeglut/src/fg_internal.h | 77 +++++++++++++++++----
4 files changed, 75 insertions(+), 24 deletions(-)
diff --git a/freeglut/freeglut/CMakeLists.txt b/freeglut/freeglut/CMakeLists.txt
index 190964f..17e05b0 100644
--- a/freeglut/freeglut/CMakeLists.txt
+++ b/freeglut/freeglut/CMakeLists.txt
@@ -68,6 +68,7 @@ ENDIF()
SET(FREEGLUT_HEADERS
include/GL/freeglut.h
+ include/GL/freeglut_ucall.h
include/GL/freeglut_ext.h
include/GL/freeglut_std.h
)
diff --git a/freeglut/freeglut/include/GL/freeglut_ext.h b/freeglut/freeglut/include/GL/freeglut_ext.h
index 255edea..9b0ac50 100644
--- a/freeglut/freeglut/include/GL/freeglut_ext.h
+++ b/freeglut/freeglut/include/GL/freeglut_ext.h
@@ -256,13 +256,13 @@ FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt,
FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) );
/* OpenGL >= 2.0 support */
-FGAPI void FGAPIENTRY glutSetVertexAttribCoord3(GLint attrib);
-FGAPI void FGAPIENTRY glutSetVertexAttribNormal(GLint attrib);
-FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2(GLint attrib);
+FGAPI void FGAPIENTRY glutSetVertexAttribCoord3( GLint attrib );
+FGAPI void FGAPIENTRY glutSetVertexAttribNormal( GLint attrib );
+FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2( GLint attrib );
/* Mobile platforms lifecycle */
-FGAPI void FGAPIENTRY glutInitContextFunc(void (* callback)());
-FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int));
+FGAPI void FGAPIENTRY glutInitContextFunc( void (* callback)( void ) );
+FGAPI void FGAPIENTRY glutAppStatusFunc( void (* callback)( int ) );
/* state flags that can be passed to callback set by glutAppStatusFunc */
#define GLUT_APPSTATUS_PAUSE 0x0001
#define GLUT_APPSTATUS_RESUME 0x0002
diff --git a/freeglut/freeglut/src/fg_callbacks.c b/freeglut/freeglut/src/fg_callbacks.c
index 5f94b65..684c934 100644
--- a/freeglut/freeglut/src/fg_callbacks.c
+++ b/freeglut/freeglut/src/fg_callbacks.c
@@ -113,9 +113,9 @@ void FGAPIENTRY glutMenuStateFunc( FGCBMenuState callback )
}
/* Sets the global menu status callback for the current window */
-void FGAPIENTRY glutMenuStatusFuncUCall( FGCBMenuStatusUC callback, FGCBUserData userData )
+void FGAPIENTRY glutMenuStatusFuncUcall( FGCBMenuStatusUC callback, FGCBUserData userData )
{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFuncUCall" );
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFuncUcall" );
fgState.MenuStatusCallback = callback;
fgState.MenuStatusCallbackData = userData;
}
@@ -130,12 +130,11 @@ void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
if( callback )
- glutMenuStatusFuncUCall( glutMenuStatusFuncCallback, (FGCBUserData)callback );
+ glutMenuStatusFuncUcall( glutMenuStatusFuncCallback, (FGCBUserData)callback );
else
- glutMenuStatusFuncUCall( NULL, NULL );
+ glutMenuStatusFuncUcall( NULL, NULL );
}
-
/*
* Menu specific callbacks.
*/
@@ -180,7 +179,7 @@ do \
* Types need to be defined for callbacks. It's not ideal, but it works for this.
*/
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
-static void glut##a##FuncCallback( FGCBUserData userData ) \
+static void glut##a##FuncCallback( FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback(); \
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index 69401d0..7afb400 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/src/fg_internal.h
@@ -220,66 +220,96 @@ typedef void* FGCBUserData;
typedef void (* FGCBDisplay )( void );
typedef void (* FGCBDisplayUC )( FGCBUserData );
+#define EXPAND_WCB_SUB_Display(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBReshape )( int, int );
typedef void (* FGCBReshapeUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Reshape(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBPosition )( int, int );
typedef void (* FGCBPositionUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Position(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBVisibility )( int );
typedef void (* FGCBVisibilityUC )( int, FGCBUserData );
+#define EXPAND_WCB_SUB_Visibility(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBKeyboard )( unsigned char, int, int );
typedef void (* FGCBKeyboardUC )( unsigned char, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Keyboard(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBKeyboardUp )( unsigned char, int, int );
typedef void (* FGCBKeyboardUpUC )( unsigned char, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_KeyboardUp(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpecial )( int, int, int );
typedef void (* FGCBSpecialUC )( int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Special(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpecialUp )( int, int, int );
typedef void (* FGCBSpecialUpUC )( int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_SpecialUp(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMouse )( int, int, int, int );
typedef void (* FGCBMouseUC )( int, int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Mouse(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMouseWheel )( int, int, int, int );
typedef void (* FGCBMouseWheelUC )( int, int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_MouseWheel(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMotion )( int, int );
typedef void (* FGCBMotionUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Motion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBPassive )( int, int );
typedef void (* FGCBPassiveUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Passive(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBEntry )( int );
typedef void (* FGCBEntryUC )( int, FGCBUserData );
+#define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBWindowStatus )( int );
typedef void (* FGCBWindowStatusUC )( int, FGCBUserData );
+#define EXPAND_WCB_SUB_WindowStatus(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBJoystick )( unsigned int, int, int, int );
typedef void (* FGCBJoystickUC )( unsigned int, int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Joystick(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBOverlayDisplay )( void );
typedef void (* FGCBOverlayDisplayUC)( FGCBUserData );
+#define EXPAND_WCB_SUB_OverlayDisplay(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBSpaceMotion )( int, int, int );
typedef void (* FGCBSpaceMotionUC )( int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_SpaceMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpaceRotation )( int, int, int );
typedef void (* FGCBSpaceRotationUC )( int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_SpaceRotation(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpaceButton )( int, int );
typedef void (* FGCBSpaceButtonUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_SpaceButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBDials )( int, int );
typedef void (* FGCBDialsUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_Dials(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBButtonBox )( int, int );
typedef void (* FGCBButtonBoxUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_ButtonBox(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBTabletMotion )( int, int );
typedef void (* FGCBTabletMotionUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_TabletMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBTabletButton )( int, int, int, int );
typedef void (* FGCBTabletButtonUC )( int, int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_TabletButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */
typedef void (* FGCBDestroyUC )( FGCBUserData );
+#define EXPAND_WCB_SUB_Destroy(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBMultiEntry )( int, int );
typedef void (* FGCBMultiEntryUC )( int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_MultiEntry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMultiButton )( int, int, int, int, int );
typedef void (* FGCBMultiButtonUC )( int, int, int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_MultiButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMultiMotion )( int, int, int );
typedef void (* FGCBMultiMotionUC )( int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_MultiMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMultiPassive )( int, int, int );
typedef void (* FGCBMultiPassiveUC )( int, int, int, FGCBUserData );
+#define EXPAND_WCB_SUB_MultiPassive(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBInitContext )( void );
typedef void (* FGCBInitContextUC )( FGCBUserData );
+#define EXPAND_WCB_SUB_InitContext(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBAppStatus )( int );
typedef void (* FGCBAppStatusUC )( int, FGCBUserData );
+#define EXPAND_WCB_SUB_AppStatus(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
/* The global callbacks type definitions */
typedef void (* FGCBIdle )( void ); \
@@ -616,6 +646,7 @@ do \
#define FETCH_USER_DATA_WCB(window,cbname) \
((window).CallbackDatas[WCB_ ## cbname])
+#if 0
/*
* EXPAND_WCB() is used as:
*
@@ -634,17 +665,8 @@ do \
*
* 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"
- */
-#define EXPAND_WCB(...) (__VA_ARGS__)
-
-#else // #if TARGET_HOST_MS_WINDOWS
+/* GCC-specific design that doesn't require per-callback defines */
#define PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N
#define PP_HAS_ARGS_SOURCE() \
@@ -667,7 +689,36 @@ do \
#define EXPAND_WCB(...) \
EXPAND_WCB_DISAMBIGUATE(PP_HAS_ARGS(__VA_ARGS__), __VA_ARGS__)
-#endif // #if TARGET_HOST_MS_WINDOWS
+#else
+/*
+ * EXPAND_WCB() is used as:
+ *
+ * EXPAND_WCB( cbname )( arg_list, userData )
+ *
+ * ... 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.
+ *
+ * In order for this to work, each callback must have a define that
+ * properly handles the arguments as needed by the callback.
+ * This callback is in the format of EXPAND_WCB_SUB_.
+ * Two helper defines exist: EXPAND_WCB_ZERO and EXPAND_WCB_ONE_OR_MORE,
+ * each to handle callbacks that take zero-params (but take userData) and
+ * to take one or more params (along with userData).
+ *
+ * An example for the "Entry" callback, where "Entry" is the cbname:
+ * typedef void (* FGCBEntry )( int );
+ * typedef void (* FGCBEntryUC)( int, FGCBUserData );
+ * #define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
+ */
+#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
+#define EXPAND_WCB_ZERO(args, userData) ( userData )
+#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
+
+#define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname
+#endif
/*
* INVOKE_WCB() is used as:
@@ -697,7 +748,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 +759,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
From f0150de08d59878468aedba8a039cb6e163a31cf Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:21 +0000
Subject: [PATCH 04/20] More explicit argument list for INVOKE_WCB callbacks
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1811 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_internal.h | 15 +++++++++++----
freeglut/freeglut/src/fg_main.c | 2 +-
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index 7afb400..93ea3bc 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/src/fg_internal.h
@@ -713,7 +713,13 @@ do \
* typedef void (* FGCBEntryUC)( int, FGCBUserData );
* #define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
*/
+#define FG_COMPILER_SUPPORTS_VA_ARGS
+#ifdef FG_COMPILER_SUPPORTS_VA_ARGS
#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
+#else
+#error "Compiler does not support varadic argument macros"
+#endif
+
#define EXPAND_WCB_ZERO(args, userData) ( userData )
#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
@@ -731,9 +737,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.
@@ -748,7 +755,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( cbname )( arg_list, userData ); \
+ func EXPAND_WCB( cbname )( arg_list, userData ); \
} \
} while( 0 )
#else
@@ -759,7 +766,7 @@ do \
{ \
fgSetWindow( &window ); \
FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \
- ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )( arg_list, userData ); \
+ ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )( arg_list, userData ); \
} \
} while( 0 )
#endif
diff --git a/freeglut/freeglut/src/fg_main.c b/freeglut/freeglut/src/fg_main.c
index 45f13f5..97c7a32 100644
--- a/freeglut/freeglut/src/fg_main.c
+++ b/freeglut/freeglut/src/fg_main.c
@@ -400,7 +400,7 @@ void fgProcessWork(SFG_Window *window)
fgPlatformInitWork(window);
/* Call init context callback */
- INVOKE_WCB( *window, InitContext, ());
+ INVOKE_WCB( *window, InitContext, ( ) );
/* Lastly, check if we have a display callback, error out if not
* This is the right place to do it, as the redisplay will be
From 658edf902d6d887324c0695399c5bd8cac72cf38 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:28 +0000
Subject: [PATCH 05/20] Initial refactoring of callback macros to make sure all
compilers are supported
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1812 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/CMakeLists.txt | 1 +
freeglut/freeglut/src/fg_callback_macros.h | 226 +++++++++++++++++++++
freeglut/freeglut/src/fg_internal.h | 121 ++---------
3 files changed, 246 insertions(+), 102 deletions(-)
create mode 100644 freeglut/freeglut/src/fg_callback_macros.h
diff --git a/freeglut/freeglut/CMakeLists.txt b/freeglut/freeglut/CMakeLists.txt
index 17e05b0..55f48ba 100644
--- a/freeglut/freeglut/CMakeLists.txt
+++ b/freeglut/freeglut/CMakeLists.txt
@@ -91,6 +91,7 @@ SET(FREEGLUT_SRCS
src/fg_init.c
src/fg_init.h
src/fg_internal.h
+ src/fg_callback_macros.h
src/fg_input_devices.c
src/fg_joystick.c
src/fg_main.c
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
new file mode 100644
index 0000000..1c70587
--- /dev/null
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -0,0 +1,226 @@
+/*
+ * fg_callback_macros.h
+ *
+ * The freeglut library callback macro file.
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta,
+ * Creation date: Thu Dec 2 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * 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.
+ */
+
+#ifndef FREEGLUT_CALLBACK_MACROS_H
+#define FREEGLUT_CALLBACK_MACROS_H
+
+#ifndef FREEGLUT_INTERNAL_H
+#error "fg_internal.h needs to be included before this header"
+#endif
+
+#if 0 /* old. Remove once other testing is complete */
+/*
+ * EXPAND_WCB() is used as:
+ *
+ * EXPAND_WCB arg_list
+ *
+ * ... where {(arg_list)} is the parameter list.
+ *
+ * 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
+ *
+ * Supports up to five arguments
+ */
+
+/* GCC-specific design that doesn't require per-callback defines */
+
+#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
+
+/*
+ * Compiler defines:
+ * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's varadic macro implementation (AKA, ##__VA_ARGS__)
+ * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports varadic macros
+ */
+
+#ifdef FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK
+
+ /*
+ * EXPAND_WCB() is used as:
+ *
+ * EXPAND_WCB arg_list
+ *
+ * ... where {(arg_list)} is the parameter list.
+ *
+ * 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.
+ *
+ * Modification of:
+ * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946
+ *
+ * --------------
+ *
+ * GCC-specific design that doesn't require per-callback defines
+ *
+ * The naming is terrible... and it's very convuluted and complex, but
+ * should not require any modification unless additional arguments are to
+ * be supported.
+ *
+ * Supports callbacks up to 5 args (follow the pattern of PP_HAS_ARGS_IMPL2
+ * and PP_HAS_ARGS_SOURCE to add more)
+ *
+ * Edit with care.
+ */
+
+#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
+
+#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(args, userData) ( userData )
+#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
+
+#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData )
+
+#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( PP_HAS_ARGS args, args, userData )
+#define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args
+
+#define EXPAND_WCB(cbname) EXPAND_WCB_UNWRAP_ARGS
+
+#else
+
+/*
+ * EXPAND_WCB() is used as:
+ *
+ * EXPAND_WCB( cbname )(( arg_list, userData ))
+ *
+ * ... 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.
+ *
+ * In order for this to work, each callback must have a define that
+ * properly handles the arguments as needed by the callback.
+ * This callback is in the format of EXPAND_WCB_SUB_.
+ * Helper functions exist for zero to five parameters: EXPAND_WCB_ZERO,
+ * EXPAND_WCB_ONE, EXPAND_WCB_TWO, EXPAND_WCB_THREE< EXPAND_WCB_FOUR,
+ * and EXPAND_WCB_FIVE. Each handle the callback argument counts.
+ *
+ * An example for the "Entry" callback, where "Entry" is the cbname:
+ * typedef void (* FGCBEntry )( int );
+ * typedef void (* FGCBEntryUC)( int, FGCBUserData );
+ * #define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
+ */
+
+#define FG_COMPILER_SUPPORTS_VA_ARGS //XXX (should be compiler defined)
+#ifdef FG_COMPILER_SUPPORTS_VA_ARGS
+
+#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
+#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
+
+#define EXPAND_WCB_ONE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
+#define EXPAND_WCB_TWO(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
+#define EXPAND_WCB_THREE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
+#define EXPAND_WCB_FOUR(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
+#define EXPAND_WCB_FIVE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
+
+#else
+
+//TODO
+#error "Compiler does not support varadic argument macros"
+
+#endif
+
+#define EXPAND_WCB_ZERO(args, userData) ( userData )
+
+#define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname
+
+/*
+ * Freeglut callbacks type definitions macros
+ *
+ * Every time a callback is updated in fg_internal.h is updated, this needs updated
+ * if argument counts change, new callbacks are added, or callbacks are removed.
+ */
+
+#define EXPAND_WCB_SUB_Display(args) EXPAND_WCB_ZERO args
+#define EXPAND_WCB_SUB_Reshape(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_Position(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_Visibility(args) EXPAND_WCB_ONE args
+#define EXPAND_WCB_SUB_Keyboard(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_KeyboardUp(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_Special(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_SpecialUp(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_Mouse(args) EXPAND_WCB_FOUR args
+#define EXPAND_WCB_SUB_MouseWheel(args) EXPAND_WCB_FOUR args
+#define EXPAND_WCB_SUB_Motion(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_Passive(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
+#define EXPAND_WCB_SUB_WindowStatus(args) EXPAND_WCB_ONE args
+#define EXPAND_WCB_SUB_Joystick(args) EXPAND_WCB_FOUR args
+#define EXPAND_WCB_SUB_OverlayDisplay(args) EXPAND_WCB_ZERO args
+#define EXPAND_WCB_SUB_SpaceMotion(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_SpaceRotation(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_SpaceButton(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_Dials(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_ButtonBox(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_TabletMotion(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_TabletButton(args) EXPAND_WCB_FOUR args
+#define EXPAND_WCB_SUB_Destroy(args) EXPAND_WCB_ZERO args
+#define EXPAND_WCB_SUB_MultiEntry(args) EXPAND_WCB_TWO args
+#define EXPAND_WCB_SUB_MultiButton(args) EXPAND_WCB_FIVE args
+#define EXPAND_WCB_SUB_MultiMotion(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_MultiPassive(args) EXPAND_WCB_THREE args
+#define EXPAND_WCB_SUB_InitContext(args) EXPAND_WCB_ZERO args
+#define EXPAND_WCB_SUB_AppStatus(args) EXPAND_WCB_ONE args
+
+#endif
+
+#endif /* FREEGLUT_CALLBACK_MACROS_H */
+
+/*** END OF FILE ***/
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index 93ea3bc..bce77ca 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/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,101 +217,78 @@
/* -- 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 );
typedef void (* FGCBDisplayUC )( FGCBUserData );
-#define EXPAND_WCB_SUB_Display(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBReshape )( int, int );
typedef void (* FGCBReshapeUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Reshape(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBPosition )( int, int );
typedef void (* FGCBPositionUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Position(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBVisibility )( int );
typedef void (* FGCBVisibilityUC )( int, FGCBUserData );
-#define EXPAND_WCB_SUB_Visibility(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBKeyboard )( unsigned char, int, int );
typedef void (* FGCBKeyboardUC )( unsigned char, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Keyboard(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBKeyboardUp )( unsigned char, int, int );
typedef void (* FGCBKeyboardUpUC )( unsigned char, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_KeyboardUp(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpecial )( int, int, int );
typedef void (* FGCBSpecialUC )( int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Special(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpecialUp )( int, int, int );
typedef void (* FGCBSpecialUpUC )( int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_SpecialUp(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMouse )( int, int, int, int );
typedef void (* FGCBMouseUC )( int, int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Mouse(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMouseWheel )( int, int, int, int );
typedef void (* FGCBMouseWheelUC )( int, int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_MouseWheel(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMotion )( int, int );
typedef void (* FGCBMotionUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Motion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBPassive )( int, int );
typedef void (* FGCBPassiveUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Passive(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBEntry )( int );
typedef void (* FGCBEntryUC )( int, FGCBUserData );
-#define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBWindowStatus )( int );
typedef void (* FGCBWindowStatusUC )( int, FGCBUserData );
-#define EXPAND_WCB_SUB_WindowStatus(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBJoystick )( unsigned int, int, int, int );
typedef void (* FGCBJoystickUC )( unsigned int, int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Joystick(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBOverlayDisplay )( void );
typedef void (* FGCBOverlayDisplayUC)( FGCBUserData );
-#define EXPAND_WCB_SUB_OverlayDisplay(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBSpaceMotion )( int, int, int );
typedef void (* FGCBSpaceMotionUC )( int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_SpaceMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpaceRotation )( int, int, int );
typedef void (* FGCBSpaceRotationUC )( int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_SpaceRotation(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBSpaceButton )( int, int );
typedef void (* FGCBSpaceButtonUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_SpaceButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBDials )( int, int );
typedef void (* FGCBDialsUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_Dials(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBButtonBox )( int, int );
typedef void (* FGCBButtonBoxUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_ButtonBox(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBTabletMotion )( int, int );
typedef void (* FGCBTabletMotionUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_TabletMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBTabletButton )( int, int, int, int );
typedef void (* FGCBTabletButtonUC )( int, int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_TabletButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */
typedef void (* FGCBDestroyUC )( FGCBUserData );
-#define EXPAND_WCB_SUB_Destroy(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBMultiEntry )( int, int );
typedef void (* FGCBMultiEntryUC )( int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_MultiEntry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMultiButton )( int, int, int, int, int );
typedef void (* FGCBMultiButtonUC )( int, int, int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_MultiButton(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMultiMotion )( int, int, int );
typedef void (* FGCBMultiMotionUC )( int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_MultiMotion(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBMultiPassive )( int, int, int );
typedef void (* FGCBMultiPassiveUC )( int, int, int, FGCBUserData );
-#define EXPAND_WCB_SUB_MultiPassive(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
typedef void (* FGCBInitContext )( void );
typedef void (* FGCBInitContextUC )( FGCBUserData );
-#define EXPAND_WCB_SUB_InitContext(args, userData) EXPAND_WCB_ZERO(args, userData)
typedef void (* FGCBAppStatus )( int );
typedef void (* FGCBAppStatusUC )( int, FGCBUserData );
-#define EXPAND_WCB_SUB_AppStatus(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
/* The global callbacks type definitions */
typedef void (* FGCBIdle )( void ); \
@@ -646,54 +625,10 @@ do \
#define FETCH_USER_DATA_WCB(window,cbname) \
((window).CallbackDatas[WCB_ ## cbname])
-#if 0
/*
* EXPAND_WCB() is used as:
*
- * EXPAND_WCB arg_list
- *
- * ... where {(arg_list)} is the parameter list.
- *
- * 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
- *
- * Supports up to five arguments
- */
-
-/* GCC-specific design that doesn't require per-callback defines */
-
-#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__)
-
-#else
-/*
- * EXPAND_WCB() is used as:
- *
- * EXPAND_WCB( cbname )( arg_list, userData )
+ * EXPAND_WCB( cbname )(( arg_list, userData ))
*
* ... where {(arg_list)} is the parameter list and userData is user
* provided data.
@@ -701,30 +636,12 @@ do \
* This will take the arg_list and extend it by one argument, adding
* the argument "userData" to the end of the list.
*
- * In order for this to work, each callback must have a define that
- * properly handles the arguments as needed by the callback.
- * This callback is in the format of EXPAND_WCB_SUB_.
- * Two helper defines exist: EXPAND_WCB_ZERO and EXPAND_WCB_ONE_OR_MORE,
- * each to handle callbacks that take zero-params (but take userData) and
- * to take one or more params (along with userData).
- *
- * An example for the "Entry" callback, where "Entry" is the cbname:
- * typedef void (* FGCBEntry )( int );
- * typedef void (* FGCBEntryUC)( int, FGCBUserData );
- * #define EXPAND_WCB_SUB_Entry(args, userData) EXPAND_WCB_ONE_OR_MORE(args, userData)
+ * All of this is defined in fg_callback_macros.h
+ *
+ * See that header for more info.
+ *
+ * ------------------------------------------------------------------
*/
-#define FG_COMPILER_SUPPORTS_VA_ARGS
-#ifdef FG_COMPILER_SUPPORTS_VA_ARGS
-#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
-#else
-#error "Compiler does not support varadic argument macros"
-#endif
-
-#define EXPAND_WCB_ZERO(args, userData) ( userData )
-#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
-
-#define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname
-#endif
/*
* INVOKE_WCB() is used as:
@@ -755,7 +672,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( cbname )( arg_list, userData ); \
+ func EXPAND_WCB( cbname )(( arg_list, userData )); \
} \
} while( 0 )
#else
@@ -766,7 +683,7 @@ do \
{ \
fgSetWindow( &window ); \
FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \
- ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )( arg_list, userData ); \
+ ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )(( arg_list, userData )); \
} \
} while( 0 )
#endif
From 0209cd1ef5b1830203793fd2459b00b11b7484b0 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:34 +0000
Subject: [PATCH 06/20] Bug fix for GCC compiler usage Removed old/original GCC
implementation of EXPAND_WCB
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1813 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callback_macros.h | 47 +---------------------
1 file changed, 2 insertions(+), 45 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
index 1c70587..a5fa7b5 100644
--- a/freeglut/freeglut/src/fg_callback_macros.h
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -32,50 +32,6 @@
#error "fg_internal.h needs to be included before this header"
#endif
-#if 0 /* old. Remove once other testing is complete */
-/*
- * EXPAND_WCB() is used as:
- *
- * EXPAND_WCB arg_list
- *
- * ... where {(arg_list)} is the parameter list.
- *
- * 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
- *
- * Supports up to five arguments
- */
-
-/* GCC-specific design that doesn't require per-callback defines */
-
-#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
-
/*
* Compiler defines:
* FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's varadic macro implementation (AKA, ##__VA_ARGS__)
@@ -125,7 +81,8 @@
#define EXPAND_WCB_ZERO(args, userData) ( userData )
#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
-#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData )
+#define EXPAND_WCB_DISAMBIGUATE2(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData )
+#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_DISAMBIGUATE2( has_args, args, userData )
#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( PP_HAS_ARGS args, args, userData )
#define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args
From dbbf2e5f08036f0b65a8c957932bebb4bbaf2a26 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:40 +0000
Subject: [PATCH 07/20] Implemented pre-C99 support for macro expansion for
callbacks.
Note: not tested with a pre-C99 compiler as I (the author) don't have any compiler that doesn't C99.
Fixed copyright too.
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1814 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callback_macros.h | 82 ++++++++++++++++++----
1 file changed, 67 insertions(+), 15 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
index a5fa7b5..2406243 100644
--- a/freeglut/freeglut/src/fg_callback_macros.h
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -3,9 +3,8 @@
*
* The freeglut library callback macro file.
*
- * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
- * Written by Pawel W. Olszta,
- * Creation date: Thu Dec 2 1999
+ * Copyright (C) 2016 Vincent Simonetti
+ * Creation date: Sat Jan 16 2016
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -38,20 +37,65 @@
* FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports varadic macros
*/
+/*
+ * Info:
+ *
+ * This took a while to figure out, so be sure try to understand what is happening so that you can ensure that whatever you
+ * change won't break other areas.
+ *
+ * If you are just adding a new callback/changing it's argument count, just go to the bottom of the file.
+ *
+ * This whole file exists purely for the sake of preventing the need to implement additional parsing logic for each callback
+ * to pass user arguments. Of course, the necessity to support older compilers means that, as seen in the line above, there
+ * is still a requirement to add/modify code to handle callbacks. If freeglut ever requires newer compilers (at minimum, ones
+ * that support C99 or higher), code can very slowly be removed from this file. Even better would be if the C standard eventually
+ * supports something similar to what GCC has implemented or offers an alternative. Another option is if C++ would be "allowed" by
+ * project maintaners, as then templates can be used and function overloading. Ironically, the template would probably look worse
+ * then the GCC macro, so maybe it's good to stay as is.
+ *
+ * Onto the different "versions" of macros:
+ *
+ * There is one for GCC/Clang(/and supposedly the Intel compiler) which supports the non-standard ##__VA_ARGS__ token. The code may
+ * look ugly, but the result is, if this was standard, no one would ever need to open this file unless they were curious (or needed
+ * more then 5 arguments for a callback, but that's trivial to add). It works by adding many fake macros to a "picker" macro
+ * (PP_HAS_ARGS_IMPL2) which then indictaes which macro counter to use. As we can already use varadic macros (the VA in __VA_ARGS__),
+ * this just becomes a "reuse the arguments*.
+ *
+ * The next is for any non-GCC/Clang/etc. compiler *cough* MSVC/compiler you probably shouldn't be using *cough* that supports C99
+ * by default. It requires each callback to have a specific argument count passthrough macro. The only reason there are specific
+ * count macros is so that (see paraghraph below) don't need have their own set of callback macros. Ideally, there would only be
+ * ZERO and ONE_OR_MORE. This works by having callback-specific macros call a specific handler macro to return user data (ZERO) or
+ * return one or more arguments along with userData (ONE_OR_MORE) where, with varadic macros, it just reuses the arguments.
+ *
+ * The last set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support it at
+ * all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without the
+ * parathesis.
+ *
+ * A note on parathesis, as earlier mentioned, if the GCC varadic macro element was standard, then instead of needing:
+ *
+ * func EXPAND_WCB(Mouse)(( (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30), userData));
+ *
+ * ...you can do the following:
+ *
+ * func EXPAND_WCB (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30);
+ *
+ * Wow... so much nice and easier to understand. Sub-note: I have not worked on a version that explicitly takes userData, so for now
+ * if you can get to that version, look in the version control change history for this file and you'll find that version which
+ * implicitly passes "userData" and only works on GCC vardiac macro supporting compilers.
+ */
+
#ifdef FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK
/*
* EXPAND_WCB() is used as:
+ *
+ * EXPAND_WCB( cbname )(( arg_list, userData ))
+ *
+ * ... where {(arg_list)} is the parameter list and userData is user
+ * provided data.
*
- * EXPAND_WCB arg_list
- *
- * ... where {(arg_list)} is the parameter list.
- *
- * 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.
+ * All additional macros are to get around trailing ',' for zero-arg
+ * callbacks.
*
* Modification of:
* http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946
@@ -115,7 +159,6 @@
* #define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
*/
-#define FG_COMPILER_SUPPORTS_VA_ARGS //XXX (should be compiler defined)
#ifdef FG_COMPILER_SUPPORTS_VA_ARGS
#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
@@ -129,8 +172,17 @@
#else
-//TODO
-#error "Compiler does not support varadic argument macros"
+#define EXTRACT_ONE_ARGS(arg1) arg1
+#define EXTRACT_TWO_ARGS(arg1, arg2) arg1, arg2
+#define EXTRACT_THREE_ARGS(arg1, arg2, arg3) arg1, arg2, arg3
+#define EXTRACT_FOUR_ARGS(arg1, arg2, arg3, arg4) arg1, arg2, arg3, arg4
+#define EXTRACT_FIVE_ARGS(arg1, arg2, arg3, arg4, arg5) arg1, arg2, arg3, arg4, arg5
+
+#define EXPAND_WCB_ONE(args, userData) (EXTRACT_ONE_ARGS args, userData)
+#define EXPAND_WCB_TWO(args, userData) (EXTRACT_TWO_ARGS args, userData)
+#define EXPAND_WCB_THREE(args, userData) (EXTRACT_THREE_ARGS args, userData)
+#define EXPAND_WCB_FOUR(args, userData) (EXTRACT_FOUR_ARGS args, userData)
+#define EXPAND_WCB_FIVE(args, userData) (EXTRACT_FIVE_ARGS args, userData)
#endif
From 16d920d56a7bf9e0989f3774504cd19054c8faee Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:46 +0000
Subject: [PATCH 08/20] Added compiler feature detection for __VA_ARGS__ and
GCC ##__VA_ARGS__
Made macro names more explicit to prevent name conflicts
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1815 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callback_macros.h | 73 +++++++++++++---------
1 file changed, 45 insertions(+), 28 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
index 2406243..76c7227 100644
--- a/freeglut/freeglut/src/fg_callback_macros.h
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -27,16 +27,33 @@
#ifndef FREEGLUT_CALLBACK_MACROS_H
#define FREEGLUT_CALLBACK_MACROS_H
-#ifndef FREEGLUT_INTERNAL_H
-#error "fg_internal.h needs to be included before this header"
-#endif
-
/*
* Compiler defines:
- * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's varadic macro implementation (AKA, ##__VA_ARGS__)
- * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports varadic macros
+ * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's variadic macro implementation (AKA, ##__VA_ARGS__)
+ * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros
*/
+/* What supports variadic macros based off Wikipedia article on it */
+#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
+ (defined(__GNUC__) && (__GNUC__ >= 3)) || \
+ (defined(__clang__)) || \
+ (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \
+ (defined(__BORLANDC__) && (__BORLANDC__ >= 0x570)) || \
+ (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x530))
+#define FG_COMPILER_SUPPORTS_VA_ARGS 1
+#else
+#define FG_COMPILER_SUPPORTS_VA_ARGS 0
+#endif
+
+/* If __VA_ARGS__ is supported, it needs to be GCC(-like) or Clang (since Clang mimics GCC) */
+#if FG_COMPILER_SUPPORTS_VA_ARGS && \
+ (defined(__GNUC__)) || \
+ (defined(__clang__))
+#define FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK 1
+#else
+#define FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK 0
+#endif
+
/*
* Info:
*
@@ -58,20 +75,20 @@
* There is one for GCC/Clang(/and supposedly the Intel compiler) which supports the non-standard ##__VA_ARGS__ token. The code may
* look ugly, but the result is, if this was standard, no one would ever need to open this file unless they were curious (or needed
* more then 5 arguments for a callback, but that's trivial to add). It works by adding many fake macros to a "picker" macro
- * (PP_HAS_ARGS_IMPL2) which then indictaes which macro counter to use. As we can already use varadic macros (the VA in __VA_ARGS__),
+ * (PP_HAS_ARGS_IMPL2) which then indictaes which macro counter to use. As we can already use variadic macros (the VA in __VA_ARGS__),
* this just becomes a "reuse the arguments*.
*
* The next is for any non-GCC/Clang/etc. compiler *cough* MSVC/compiler you probably shouldn't be using *cough* that supports C99
* by default. It requires each callback to have a specific argument count passthrough macro. The only reason there are specific
* count macros is so that (see paraghraph below) don't need have their own set of callback macros. Ideally, there would only be
* ZERO and ONE_OR_MORE. This works by having callback-specific macros call a specific handler macro to return user data (ZERO) or
- * return one or more arguments along with userData (ONE_OR_MORE) where, with varadic macros, it just reuses the arguments.
+ * return one or more arguments along with userData (ONE_OR_MORE) where, with variadic macros, it just reuses the arguments.
*
* The last set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support it at
* all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without the
* parathesis.
*
- * A note on parathesis, as earlier mentioned, if the GCC varadic macro element was standard, then instead of needing:
+ * A note on parathesis, as earlier mentioned, if the GCC variadic macro element was standard, then instead of needing:
*
* func EXPAND_WCB(Mouse)(( (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30), userData));
*
@@ -84,7 +101,7 @@
* implicitly passes "userData" and only works on GCC vardiac macro supporting compilers.
*/
-#ifdef FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK
+#if FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK
/*
* EXPAND_WCB() is used as:
@@ -108,19 +125,19 @@
* should not require any modification unless additional arguments are to
* be supported.
*
- * Supports callbacks up to 5 args (follow the pattern of PP_HAS_ARGS_IMPL2
- * and PP_HAS_ARGS_SOURCE to add more)
+ * Supports callbacks up to 5 args (follow the pattern of
+ * EXPAND_WCB_PP_HAS_ARGS_IMPL2 and EXPAND_WCB_PP_HAS_ARGS_SOURCE to add more)
*
* Edit with care.
*/
#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
-#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 EXPAND_WCB_PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N
+#define EXPAND_WCB_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_PP_HAS_ARGS_IMPL(...) EXPAND_WCB_PP_HAS_ARGS_IMPL2( __VA_ARGS__ )
+#define EXPAND_WCB_PP_HAS_ARGS(...) EXPAND_WCB_PP_HAS_ARGS_IMPL( NOT_EXIST, ##__VA_ARGS__, EXPAND_WCB_PP_HAS_ARGS_SOURCE() )
#define EXPAND_WCB_ZERO(args, userData) ( userData )
#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
@@ -128,7 +145,7 @@
#define EXPAND_WCB_DISAMBIGUATE2(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData )
#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_DISAMBIGUATE2( has_args, args, userData )
-#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( PP_HAS_ARGS args, args, userData )
+#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( EXPAND_WCB_PP_HAS_ARGS args, args, userData )
#define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args
#define EXPAND_WCB(cbname) EXPAND_WCB_UNWRAP_ARGS
@@ -159,7 +176,7 @@
* #define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
*/
-#ifdef FG_COMPILER_SUPPORTS_VA_ARGS
+#if FG_COMPILER_SUPPORTS_VA_ARGS
#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
@@ -172,17 +189,17 @@
#else
-#define EXTRACT_ONE_ARGS(arg1) arg1
-#define EXTRACT_TWO_ARGS(arg1, arg2) arg1, arg2
-#define EXTRACT_THREE_ARGS(arg1, arg2, arg3) arg1, arg2, arg3
-#define EXTRACT_FOUR_ARGS(arg1, arg2, arg3, arg4) arg1, arg2, arg3, arg4
-#define EXTRACT_FIVE_ARGS(arg1, arg2, arg3, arg4, arg5) arg1, arg2, arg3, arg4, arg5
+#define EXPAND_WCB_EXTRACT_ONE_ARGS(arg1) arg1
+#define EXPAND_WCB_EXTRACT_TWO_ARGS(arg1, arg2) arg1, arg2
+#define EXPAND_WCB_EXTRACT_THREE_ARGS(arg1, arg2, arg3) arg1, arg2, arg3
+#define EXPAND_WCB_EXTRACT_FOUR_ARGS(arg1, arg2, arg3, arg4) arg1, arg2, arg3, arg4
+#define EXPAND_WCB_EXTRACT_FIVE_ARGS(arg1, arg2, arg3, arg4, arg5) arg1, arg2, arg3, arg4, arg5
-#define EXPAND_WCB_ONE(args, userData) (EXTRACT_ONE_ARGS args, userData)
-#define EXPAND_WCB_TWO(args, userData) (EXTRACT_TWO_ARGS args, userData)
-#define EXPAND_WCB_THREE(args, userData) (EXTRACT_THREE_ARGS args, userData)
-#define EXPAND_WCB_FOUR(args, userData) (EXTRACT_FOUR_ARGS args, userData)
-#define EXPAND_WCB_FIVE(args, userData) (EXTRACT_FIVE_ARGS args, userData)
+#define EXPAND_WCB_ONE(args, userData) (EXPAND_WCB_EXTRACT_ONE_ARGS args, userData)
+#define EXPAND_WCB_TWO(args, userData) (EXPAND_WCB_EXTRACT_TWO_ARGS args, userData)
+#define EXPAND_WCB_THREE(args, userData) (EXPAND_WCB_EXTRACT_THREE_ARGS args, userData)
+#define EXPAND_WCB_FOUR(args, userData) (EXPAND_WCB_EXTRACT_FOUR_ARGS args, userData)
+#define EXPAND_WCB_FIVE(args, userData) (EXPAND_WCB_EXTRACT_FIVE_ARGS args, userData)
#endif
From da3e00905e1ed7d10464bfdd9f96964c5354ca6b Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:53 +0000
Subject: [PATCH 09/20] Fixed issue where setting the same callback with
different user pointer wouldn't change the user pointer. Removed extra
comment on FETCH_USER_DATA_WCB Renamed helper callbacks from glutXXXCalback
to fghXXXCallback
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1816 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callbacks.c | 58 ++++++++++++++--------------
freeglut/freeglut/src/fg_init.c | 28 +++++++++-----
freeglut/freeglut/src/fg_internal.h | 18 +++++----
freeglut/freeglut/src/fg_menu.c | 12 ++++--
4 files changed, 65 insertions(+), 51 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callbacks.c b/freeglut/freeglut/src/fg_callbacks.c
index 684c934..4fc0089 100644
--- a/freeglut/freeglut/src/fg_callbacks.c
+++ b/freeglut/freeglut/src/fg_callbacks.c
@@ -42,7 +42,7 @@ void FGAPIENTRY glutIdleFuncUcall( FGCBIdleUC callback, FGCBUserData userData )
fgState.IdleCallbackData = userData;
}
-static void glutIdleFuncCallback( FGCBUserData userData )
+static void fghIdleFuncCallback( FGCBUserData userData )
{
FGCBIdle callback = (FGCBIdle)userData;
callback();
@@ -52,7 +52,7 @@ void FGAPIENTRY glutIdleFunc( FGCBIdle callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
if( callback )
- glutIdleFuncUcall( glutIdleFuncCallback, (FGCBUserData)callback );
+ glutIdleFuncUcall( fghIdleFuncCallback, (FGCBUserData)callback );
else
glutIdleFuncUcall( NULL, NULL );
}
@@ -90,7 +90,7 @@ void FGAPIENTRY glutTimerFuncUcall( unsigned int timeOut, FGCBTimerUC callback,
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
}
-static void glutTimerFuncCallback( int ID, FGCBUserData userData )
+static void fghTimerFuncCallback( int ID, FGCBUserData userData )
{
FGCBTimer callback = (FGCBTimer)userData;
callback( ID );
@@ -100,7 +100,7 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int tim
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );
if( callback )
- glutTimerFuncUcall( timeOut, glutTimerFuncCallback, timerID, (FGCBUserData)callback );
+ glutTimerFuncUcall( timeOut, fghTimerFuncCallback, timerID, (FGCBUserData)callback );
else
glutTimerFuncUcall( timeOut, NULL, timerID, NULL );
}
@@ -120,7 +120,7 @@ void FGAPIENTRY glutMenuStatusFuncUcall( FGCBMenuStatusUC callback, FGCBUserData
fgState.MenuStatusCallbackData = userData;
}
-static void glutMenuStatusFuncCallback( int menuState, int mouseX, int mouseY, FGCBUserData userData )
+static void fghMenuStatusFuncCallback( int menuState, int mouseX, int mouseY, FGCBUserData userData )
{
FGCBMenuStatus callback = (FGCBMenuStatus)userData;
callback( menuState, mouseX, mouseY );
@@ -130,7 +130,7 @@ void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
if( callback )
- glutMenuStatusFuncUcall( glutMenuStatusFuncCallback, (FGCBUserData)callback );
+ glutMenuStatusFuncUcall( fghMenuStatusFuncCallback, (FGCBUserData)callback );
else
glutMenuStatusFuncUcall( NULL, NULL );
}
@@ -149,7 +149,7 @@ void FGAPIENTRY glutMenuDestroyFuncUcall( FGCBDestroyUC callback, FGCBUserData u
}
}
-static void glutMenuDestroyFuncCallback( FGCBUserData userData )
+static void fghMenuDestroyFuncCallback( FGCBUserData userData )
{
FGCBDestroy callback = (FGCBDestroy)userData;
callback();
@@ -159,7 +159,7 @@ void FGAPIENTRY glutMenuDestroyFunc( FGCBDestroy callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );
if( callback )
- glutMenuDestroyFuncUcall( glutMenuDestroyFuncCallback, (FGCBUserData)callback );
+ glutMenuDestroyFuncUcall( fghMenuDestroyFuncCallback, (FGCBUserData)callback );
else
glutMenuDestroyFuncUcall( NULL, NULL );
}
@@ -179,38 +179,38 @@ do \
* Types need to be defined for callbacks. It's not ideal, but it works for this.
*/
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
-static void glut##a##FuncCallback( FGCBUserData userData ) \
+static void fgh##a##FuncCallback( FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback(); \
}
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,b) \
-static void glut##a##FuncCallback( int arg1val, FGCBUserData userData ) \
+static void fgh##a##FuncCallback( int arg1val, FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback( arg1val ); \
}
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
-static void glut##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \
+static void fgh##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback( arg1val, arg2val ); \
}
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,arg1,arg2,arg3) \
-static void glut##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \
+static void fgh##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback( arg1val, arg2val, arg3val ); \
}
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,int,int,int)
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,b) \
-static void glut##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \
+static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback( arg1val, arg2val, arg3val, arg4val ); \
}
#define IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,b) \
-static void glut##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \
+static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \
{ \
FGCB##b callback = (FGCB##b)userData; \
callback( arg1val, arg2val, arg3val, arg4val, arg5val ); \
@@ -228,7 +228,7 @@ void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
{ \
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
if( callback ) \
- glut##a##FuncUcall( glut##a##FuncCallback, (FGCBUserData)callback ); \
+ glut##a##FuncUcall( fgh##a##FuncCallback, (FGCBUserData)callback ); \
else \
glut##a##FuncUcall( NULL, NULL ); \
}
@@ -310,7 +310,7 @@ void FGAPIENTRY glutDisplayFuncUcall( FGCBDisplayUC callback, FGCBUserData userD
SET_CALLBACK( Display );
}
-static void glutDisplayFuncCallback( FGCBUserData userData )
+static void fghDisplayFuncCallback( FGCBUserData userData )
{
FGCBDisplay callback = (FGCBDisplay)userData;
callback();
@@ -320,7 +320,7 @@ void FGAPIENTRY glutDisplayFunc( FGCBDisplay callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
if( callback )
- glutDisplayFuncUcall( glutDisplayFuncCallback, (FGCBUserData)callback );
+ glutDisplayFuncUcall( fghDisplayFuncCallback, (FGCBUserData)callback );
else
glutDisplayFuncUcall( NULL, NULL );
}
@@ -343,7 +343,7 @@ void FGAPIENTRY glutReshapeFuncUcall( FGCBReshapeUC callback, FGCBUserData userD
SET_CALLBACK( Reshape );
}
-static void glutReshapeFuncCallback( int width, int height, FGCBUserData userData )
+static void fghReshapeFuncCallback( int width, int height, FGCBUserData userData )
{
FGCBReshape callback = (FGCBReshape)userData;
callback( width, height );
@@ -353,7 +353,7 @@ void FGAPIENTRY glutReshapeFunc( FGCBReshape callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );
if( callback )
- glutReshapeFuncUcall( glutReshapeFuncCallback, (FGCBUserData)callback );
+ glutReshapeFuncUcall( fghReshapeFuncCallback, (FGCBUserData)callback );
else
glutReshapeFuncUcall( NULL, NULL );
}
@@ -406,7 +406,7 @@ void FGAPIENTRY glutVisibilityFuncUcall( FGCBVisibilityUC callback, FGCBUserData
glutWindowStatusFuncUcall( NULL, NULL );
}
-static void glutVisibilityFuncCallback( int visibility, FGCBUserData userData )
+static void fghVisibilityFuncCallback( int visibility, FGCBUserData userData )
{
FGCBVisibility callback = (FGCBVisibility)userData;
callback( visibility );
@@ -416,7 +416,7 @@ void FGAPIENTRY glutVisibilityFunc( FGCBVisibility callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
if( callback )
- glutVisibilityFuncUcall( glutVisibilityFuncCallback, (FGCBUserData)callback );
+ glutVisibilityFuncUcall( fghVisibilityFuncCallback, (FGCBUserData)callback );
else
glutVisibilityFuncUcall( NULL, NULL );
}
@@ -457,7 +457,7 @@ void FGAPIENTRY glutJoystickFuncUcall( FGCBJoystickUC callback, int pollInterval
fgStructure.CurrentWindow->State.JoystickLastPoll -= pollInterval;
}
-static void glutJoystickFuncCallback( unsigned int buttons, int axis0, int axis1, int axis2, FGCBUserData userData )
+static void fghJoystickFuncCallback( unsigned int buttons, int axis0, int axis1, int axis2, FGCBUserData userData )
{
FGCBJoystick callback = (FGCBJoystick)userData;
callback( buttons, axis0, axis1, axis2 );
@@ -467,7 +467,7 @@ void FGAPIENTRY glutJoystickFunc( FGCBJoystick callback, int pollInterval )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
if( callback )
- glutJoystickFuncUcall( glutJoystickFuncCallback, pollInterval, (FGCBUserData)callback );
+ glutJoystickFuncUcall( fghJoystickFuncCallback, pollInterval, (FGCBUserData)callback );
else
glutJoystickFuncUcall( NULL, pollInterval, NULL );
}
@@ -483,7 +483,7 @@ void FGAPIENTRY glutSpaceballMotionFuncUcall( FGCBSpaceMotionUC callback, FGCBUs
SET_CALLBACK( SpaceMotion );
}
-static void glutSpaceballMotionFuncCallback( int x, int y, int z, FGCBUserData userData )
+static void fghSpaceballMotionFuncCallback( int x, int y, int z, FGCBUserData userData )
{
FGCBSpaceMotion callback = (FGCBSpaceMotion)userData;
callback( x, y, z );
@@ -493,7 +493,7 @@ void FGAPIENTRY glutSpaceballMotionFunc( FGCBSpaceMotion callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
if( callback )
- glutSpaceballMotionFuncUcall( glutSpaceballMotionFuncCallback, (FGCBUserData)callback );
+ glutSpaceballMotionFuncUcall( fghSpaceballMotionFuncCallback, (FGCBUserData)callback );
else
glutSpaceballMotionFuncUcall( NULL, NULL );
}
@@ -509,7 +509,7 @@ void FGAPIENTRY glutSpaceballRotateFuncUcall( FGCBSpaceRotationUC callback, FGCB
SET_CALLBACK( SpaceRotation );
}
-static void glutSpaceballRotateFuncCallback( int x, int y, int z, FGCBUserData userData )
+static void fghSpaceballRotateFuncCallback( int x, int y, int z, FGCBUserData userData )
{
FGCBSpaceRotation callback = (FGCBSpaceRotation)userData;
callback( x, y, z );
@@ -519,7 +519,7 @@ void FGAPIENTRY glutSpaceballRotateFunc( FGCBSpaceRotation callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
if( callback )
- glutSpaceballRotateFuncUcall( glutSpaceballRotateFuncCallback, (FGCBUserData)callback );
+ glutSpaceballRotateFuncUcall( fghSpaceballRotateFuncCallback, (FGCBUserData)callback );
else
glutSpaceballRotateFuncUcall( NULL, NULL );
}
@@ -535,7 +535,7 @@ void FGAPIENTRY glutSpaceballButtonFuncUcall( FGCBSpaceButtonUC callback, FGCBUs
SET_CALLBACK( SpaceButton );
}
-static void glutSpaceballButtonFuncCallback( int button, int buttonState, FGCBUserData userData )
+static void fghSpaceballButtonFuncCallback( int button, int buttonState, FGCBUserData userData )
{
FGCBSpaceButton callback = (FGCBSpaceButton)userData;
callback( button, buttonState );
@@ -545,7 +545,7 @@ void FGAPIENTRY glutSpaceballButtonFunc( FGCBSpaceButton callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
if( callback )
- glutSpaceballButtonFuncUcall( glutSpaceballButtonFuncCallback, (FGCBUserData)callback );
+ glutSpaceballButtonFuncUcall( fghSpaceballButtonFuncCallback, (FGCBUserData)callback );
else
glutSpaceballButtonFuncUcall( NULL, NULL );
}
diff --git a/freeglut/freeglut/src/fg_init.c b/freeglut/freeglut/src/fg_init.c
index a408bbe..c3c00e5 100644
--- a/freeglut/freeglut/src/fg_init.c
+++ b/freeglut/freeglut/src/fg_init.c
@@ -681,7 +681,7 @@ void FGAPIENTRY glutInitErrorFuncUcall( FGErrorUC callback, FGCBUserData userDat
fgState.ErrorFuncData = userData;
}
-static void glutInitErrorFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
+static void fghInitErrorFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
{
FGError callback = (FGError)userData;
callback( fmt, ap );
@@ -689,10 +689,14 @@ static void glutInitErrorFuncCallback( const char *fmt, va_list ap, FGCBUserData
void FGAPIENTRY glutInitErrorFunc( FGError callback )
{
- if (callback)
- glutInitErrorFuncUcall( glutInitErrorFuncCallback, (FGCBUserData)callback );
- else
- glutInitErrorFuncUcall( NULL, NULL );
+ if (callback)
+ {
+ glutInitErrorFuncUcall( fghInitErrorFuncCallback, (FGCBUserData)callback );
+ }
+ else
+ {
+ glutInitErrorFuncUcall( NULL, NULL );
+ }
}
/*
@@ -705,7 +709,7 @@ void FGAPIENTRY glutInitWarningFuncUcall( FGWarningUC callback, FGCBUserData use
fgState.WarningFuncData = userData;
}
-static void glutInitWarningFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
+static void fghInitWarningFuncCallback( const char *fmt, va_list ap, FGCBUserData userData )
{
FGWarning callback = (FGWarning)userData;
callback( fmt, ap );
@@ -713,10 +717,14 @@ static void glutInitWarningFuncCallback( const char *fmt, va_list ap, FGCBUserDa
void FGAPIENTRY glutInitWarningFunc( FGWarning callback )
{
- if (callback)
- glutInitWarningFuncUcall( glutInitWarningFuncCallback, (FGCBUserData)callback );
- else
- glutInitWarningFuncUcall( NULL, NULL );
+ if (callback)
+ {
+ glutInitWarningFuncUcall( fghInitWarningFuncCallback, (FGCBUserData)callback );
+ }
+ else
+ {
+ glutInitWarningFuncUcall( NULL, NULL );
+ }
}
/*** END OF FILE ***/
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index bce77ca..c98e520 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/src/fg_internal.h
@@ -577,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 \
@@ -586,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 )
/*
@@ -611,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.
*/
diff --git a/freeglut/freeglut/src/fg_menu.c b/freeglut/freeglut/src/fg_menu.c
index 1b07b1a..ae7405c 100644
--- a/freeglut/freeglut/src/fg_menu.c
+++ b/freeglut/freeglut/src/fg_menu.c
@@ -784,14 +784,16 @@ int FGAPIENTRY glutCreateMenuUcall( FGCBMenuUC callback, FGCBUserData userData )
{
/* The menu object creation code resides in fg_structure.c */
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenuUcall" );
- if (fgState.ActiveMenus)
- fgError("Menu manipulation not allowed while menus in use.");
+ if (fgState.ActiveMenus)
+ {
+ fgError( "Menu manipulation not allowed while menus in use." );
+ }
return fgCreateMenu( callback, userData )->ID;
}
/* Standard glutCreateMenu */
-static void glutCreateMenuCallback( int menu, FGCBUserData userData )
+static void fghCreateMenuCallback( int menu, FGCBUserData userData )
{
FGCBMenu callback = (FGCBMenu)userData;
callback( menu );
@@ -801,8 +803,10 @@ int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
if (!callback)
+ {
return glutCreateMenuUcall( NULL, NULL );
- return glutCreateMenuUcall( glutCreateMenuCallback, (FGCBUserData)callback );
+ }
+ return glutCreateMenuUcall( fghCreateMenuCallback, (FGCBUserData)callback );
}
/*
From 8ac335fa7ff8a8e99535a07fa5eb1f9a9a716fd0 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:21:59 +0000
Subject: [PATCH 10/20] Removed unneeded line optimization for INVOKE_WCB macro
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1817 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_internal.h | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index c98e520..a61b121 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/src/fg_internal.h
@@ -665,7 +665,6 @@ do \
* current window.
*
*/
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: also WinCE? */
#define INVOKE_WCB(window,cbname,arg_list) \
do \
{ \
@@ -677,18 +676,6 @@ do \
func EXPAND_WCB( cbname )(( arg_list, userData )); \
} \
} while( 0 )
-#else
-#define INVOKE_WCB(window,cbname,arg_list) \
-do \
-{ \
- if( FETCH_WCB( window, cbname ) ) \
- { \
- fgSetWindow( &window ); \
- FGCBUserData userData = FETCH_USER_DATA_WCB( window, cbname ); \
- ((FGCB ## cbname ## UC)FETCH_WCB( window, cbname )) EXPAND_WCB( cbname )(( arg_list, userData )); \
- } \
-} while( 0 )
-#endif
/*
* The window callbacks the user can supply us with. Should be kept portable.
From 9f0eaf1a9269cda21136a352f3f05daa3845714d Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:06 +0000
Subject: [PATCH 11/20] Fixed bug where, under c89 mode, callback macros
wouldn't work
Under c89 (only applies to GCC-like compilers), the variadic macro version would be used and compilation would fail.
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1818 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callback_macros.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
index 76c7227..0c574d7 100644
--- a/freeglut/freeglut/src/fg_callback_macros.h
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -33,10 +33,10 @@
* FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros
*/
-/* What supports variadic macros based off Wikipedia article on it */
-#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
- (defined(__GNUC__) && (__GNUC__ >= 3)) || \
- (defined(__clang__)) || \
+/* What supports variadic macros based off Wikipedia article on it (GCC-like must support C99 or higher to use variadic macros) */
+#if (((defined(__GNUC__) && (__GNUC__ >= 3)) || \
+ (defined(__clang__))) && \
+ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))) || \
(defined(_MSC_VER) && (_MSC_VER >= 1400)) || \
(defined(__BORLANDC__) && (__BORLANDC__ >= 0x570)) || \
(defined(__SUNPRO_C) && (__SUNPRO_C >= 0x530))
From 1925fca03062b9602ff86529409c9d2b14b626e0 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:12 +0000
Subject: [PATCH 12/20] Updated documentation to mention and discuss user-data
callbacks.
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1819 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/web-src/docs/api.php | 106 +++++++++++++++++++++++++++++++---
1 file changed, 99 insertions(+), 7 deletions(-)
diff --git a/freeglut/web-src/docs/api.php b/freeglut/web-src/docs/api.php
index faeb433..e7a6d0f 100644
--- a/freeglut/web-src/docs/api.php
+++ b/freeglut/web-src/docs/api.php
@@ -301,7 +301,7 @@ and their compatibility with GLUT, are made explicit.
There is considerable confusion about the "right thing to do" concerning
-window size and position. GLUT itself is not consistent between
+window size and position. GLUT itself is not consistent between
Windows and UNIX/X11; since platform independence is a virtue for
freeglut, we decided to break with GLUT's behaviour.
Under UNIX/X11, it is apparently not possible to get the window border
@@ -327,6 +327,40 @@ area--which is NOT the (x,y) position of the window you specified
when you created it.
+3.2.2 User-data callbacks
+
+
+GLUT was created as a tool to help teach OpenGL programming. To simplify
+development, callbacks were used for handling display, input, and other
+events. But the time it was developed, the purpose, or for some other
+unknown reason, the callbacks lacked any user-provided data argument.
+This has caused considerable difficulties for any significantly advanced
+usage of GLUT, and now freeglut. This has prevented any attempt to
+wrap freeglut in a C++ wrapper, make per-window, per-callback data
+structure, and potentially made it undesirable to modern C developers who
+tend to be well versed in "don't use globals". To combat these
+complaints and issues, many callbacks (with some deprecated
+callbacks excluded) support user-data callbacks provided through additional
+functions provided in freeglut. All callbacks that support user-data
+callbacks are marked as such.
+
+
+
+The general rule to follow is to take the freeglut callback function
+and append "Ucall" to the end of the function, add an additional void*
+argument to the end of the argument list of both the freeglut function
+and the callback function. This will pass the user-data to the callback when it's
+invoked.
+
+
+Examples
+
+void glutPositionFunc ( void (* func)( int x, int y ) );
+void glutPositionFuncUcall ( void (* func)( int x, int y, void* user_data ), void* user_data );
+
+void glutKeyboardUpFunc ( void (* func)( unsigned char key, int x, int y ) );
+void glutKeyboardUpFuncUcall ( void (* func)( unsigned char key, int x, int y, void* user_data ), void* user_data );
+
3.3 Terminology
3.4 Differences from GLUT 3.7
@@ -524,6 +558,8 @@ from the library can be handled by the user.
void glutInitErrorFunc ( void (* callback)( const char *fmt, va_list ap) );
void glutInitWarningFunc ( void (* callback)( const char *fmt, va_list ap) );
+These functions have user-data callback functions.
+
Description
The users callback is passed a format string and a variable argument
@@ -943,6 +979,8 @@ The glutShowOverlay and glutHideOverlay functions are not impl
10.1 glutCreateMenu
+Has user-data callback function.
+
10.2 glutDestroyMenu
10.3 glutGetMenu, glutSetMenu
@@ -985,10 +1023,14 @@ stroke font, or an unknown font.
10.11 glutMenuDestroyFunc
+Has user-data callback function.
+
11. Global Callback Registration Functions
11.1 glutTimerFunc
+Has user-data callback function.
+
11.2 glutIdleFunc
@@ -998,11 +1040,11 @@ freeglut calls the idle callback when there are no inputs from the user.
Usage
-void glutIdleFunc ( void (*func)
-( void ) );
+void glutIdleFunc ( void (*func ) ( void ) );
-funcThe new
-global idle callback function
+func The new global idle callback function
+
+Has user-data callback function.
Description
@@ -1042,16 +1084,24 @@ the idle callback.
11.3 glutMenuStatusFunc
+Has user-data callback function.
+
11.4 glutMenuStateFunc
12. Window-Specific Callback Registration Functions
12.1 glutDisplayFunc
+Has user-data callback function.
+
12.2 glutOverlayDisplayFunc
+Has user-data callback function.
+
12.3 glutReshapeFunc
+Has user-data callback function.
+
12.4 glutPositionFunc
@@ -1065,6 +1115,8 @@ repositioned/moved programatically or by the user.
void glutPositionFunc ( void
(* func)( int x, int y) );
+Has user-data callback function.
+
Description
When freeglut calls this callback, it provides the new
@@ -1094,6 +1146,8 @@ about to be destroyed.
func The window's new closure callback function
+Has user-data callback function.
+
Description
@@ -1121,6 +1175,8 @@ alias to glutCloseFunc.
12.6 glutKeyboardFunc
+Has user-data callback function.
+
12.7 glutSpecialFunc
@@ -1145,6 +1201,8 @@ to the window at the time the key is pressed
The y-coordinate of the mouse relative
to the window at the time the key is pressed
+Has user-data callback function.
+
Description
@@ -1200,6 +1258,8 @@ to the window at the time the key is released
The y-coordinate of the mouse relative
to the window at the time the key is released
+Has user-data callback function.
+
Description
@@ -1252,6 +1312,8 @@ to the window at the time the key is released
The y-coordinate of the mouse relative
to the window at the time the key is released
+Has user-data callback function.
+
Description
@@ -1289,8 +1351,12 @@ have them fixed.
12.10 glutMotionFunc, glutPassiveMotionFunc
+Both functions have user-data callback functions.
+
12.11 glutMouseFunc
+Has user-data callback function.
+
12.12 glutMouseWheelFunc
@@ -1304,6 +1370,8 @@ spins the mouse wheel.
void glutMouseWheelFunc ( void( *callback )( int wheel, int
direction, int x, int y ));
+Has user-data callback function.
+
Description
If the mouse wheel is spun over your (sub)window, freeglut
@@ -1320,8 +1388,12 @@ as mouse buttons.
12.13 glutEntryFunc
+Has user-data callback function.
+
12.14 glutJoystickFunc
+Has user-data callback function.
+
12.15 glutSpaceballMotionFunc
@@ -1337,6 +1409,8 @@ provided so that GLUT-based programs can compile and link against
void glutSpaceballMotionFunc ( void (* callback)( int x, int y, int z ) );
+Has user-data callback function.
+
Description
The x, y, and z arguments indicate the amount of translation in integer along x, y, and z axis respectively.
@@ -1357,6 +1431,8 @@ provided so that GLUT-based programs can compile and link against
void glutSpaceballRotateFunc ( void (* callback)( int rx, int ry, int rz ) );
+Has user-data callback function.
+
Description
The rx, ry, and rz arguments indicate the amount of rotation in integer with respect to x, y, and z axis respectively.
@@ -1379,6 +1455,8 @@ The glutSpaceballButtonFunc function sets the window's Spaceball button
void glutSpaceballButtonFunc ( void
(* callback)( int button, int updown ) );
+Has user-data callback function.
+
Description
The button argument may take one of the following defined
@@ -1418,6 +1496,8 @@ The glutDialsFunc function sets the global dials&buttons box callback.
void glutButtonBoxFunc ( void (* callback)( int button, int updown ) );
+Has user-data callback function.
+
Description
@@ -1442,6 +1522,8 @@ The glutDialsFunc function sets the global dials&buttons box callback.
void glutDialsFunc ( void (* callback)(
int dial, int value ) );
+Has user-data callback function.
+
Description
@@ -1469,6 +1551,8 @@ that a call to the function will not produce an error..
void glutTabletMotionFunc ( void (* callback)( int x, int y ) );
+Has user-data callback function.
+
Description
The glutTabletMotionFunc function
@@ -1491,6 +1575,8 @@ that a call to the function will not produce an error..
void glutTabletButtonFunc ( void
(* callback)( int button, int updown, int x, int y ) );
+Has user-data callback function.
+
Description
@@ -1517,6 +1603,8 @@ these callbacks when the visibility status of a window changes.
void glutWindowStatusFunc ( void( *callback )( int state ));
+Both functions have user-data callback functions.
+
Description
@@ -2701,6 +2789,8 @@ Currently, under windows, the first (oldest) touch point also controls
the mouse cursor, which triggers the non-multi callbacks as
usual.
+All these functions have user-data callback functions.
+
Limitation: currently on the cursor id is provided. It may be
@@ -2729,9 +2819,11 @@ whether/how to implement it.
glutInitContextFunc ← void
: called when the context
-is initialized or re-initialized (e.g. after a pause)
+is initialized or re-initialized (e.g. after a pause). Has user-data callback
+function.
glutAppStatusFunc ← event
: called when the
-application's status changes, with event identifying the state entered.
+application's status changes, with event identifying the state entered. Has
+user-data callback function.
Possible states:
- application goes on a pause (or a stop) → GLUT_APPSTATUS_PAUSE
From 2646c0c9f8ecfb9d1ca62eb7af6bd609ef8b1879 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:19 +0000
Subject: [PATCH 13/20] Moved as many callback setters as possible to macro
function generators
Moved macro function generators to fg_callback_macros.h
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1820 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callback_macros.h | 160 +++++++++++
freeglut/freeglut/src/fg_callbacks.c | 314 +++------------------
2 files changed, 203 insertions(+), 271 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
index 0c574d7..2aa6ccd 100644
--- a/freeglut/freeglut/src/fg_callback_macros.h
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -27,6 +27,12 @@
#ifndef FREEGLUT_CALLBACK_MACROS_H
#define FREEGLUT_CALLBACK_MACROS_H
+/*
+ * ----------------------------------------------------------------------------------------------------------------------
+ * There are two sets of macros here. One is for executing window callbacks, the others are for setting window callbacks.
+ * ----------------------------------------------------------------------------------------------------------------------
+ */
+
/*
* Compiler defines:
* FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's variadic macro implementation (AKA, ##__VA_ARGS__)
@@ -55,6 +61,10 @@
#endif
/*
+ * --------------------------
+ * Executing window callbacks
+ * --------------------------
+ *
* Info:
*
* This took a while to figure out, so be sure try to understand what is happening so that you can ensure that whatever you
@@ -247,6 +257,156 @@
#endif
+/*
+ * ------------------------
+ * Setting window callbacks
+ * ------------------------
+ *
+ * These originally existed in fg_callbacks.c
+ */
+
+/*
+ * All of the window-specific callbacks setting methods can be generalized to this:
+ */
+#define SET_CURRENT_WINDOW_CALLBACK(a) \
+do \
+{ \
+ if( fgStructure.CurrentWindow == NULL ) \
+ return; \
+ SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback, userData ); \
+} while( 0 )
+
+/*
+ * Types need to be defined for callbacks. It's not ideal, but it works for this.
+ */
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
+static void fgh##a##FuncCallback( FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback(); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,b) \
+static void fgh##a##FuncCallback( int arg1val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
+static void fgh##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,arg1,arg2,arg3) \
+static void fgh##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val, arg3val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,int,int,int)
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,b) \
+static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val, arg3val, arg4val ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,b) \
+static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \
+{ \
+ FGCB##b callback = (FGCB##b)userData; \
+ callback( arg1val, arg2val, arg3val, arg4val, arg5val ); \
+}
+
+/*
+ * And almost every time the callback setter function can be implemented with these:
+ */
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT_UCALL(a,b) \
+void FGAPIENTRY glut##a##FuncUcall( FGCB##b##UC callback, FGCBUserData userData ) \
+{ \
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"FuncUcall" ); \
+ SET_CURRENT_WINDOW_CALLBACK( b ); \
+}
+#define IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b) \
+void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
+{ \
+ FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
+ if( callback ) \
+ glut##a##FuncUcall( fgh##a##FuncCallback, (FGCBUserData)callback ); \
+ else \
+ glut##a##FuncUcall( NULL, NULL ); \
+}
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT_UCALL(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
+
+/*
+ * Combine _glut and _cb macros:
+ */
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG1(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,b)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3_USER(a,arg1,arg2,arg3) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,a,arg1,arg2,arg3) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,a)
+
+#define IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) \
+ IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT_BASE(a,b)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,a) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
+#define IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG5(a) \
+ IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,a) \
+ IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_2NAME_GLUT(a,a)
+
#endif /* FREEGLUT_CALLBACK_MACROS_H */
/*** END OF FILE ***/
diff --git a/freeglut/freeglut/src/fg_callbacks.c b/freeglut/freeglut/src/fg_callbacks.c
index 4fc0089..0e656a8 100644
--- a/freeglut/freeglut/src/fg_callbacks.c
+++ b/freeglut/freeglut/src/fg_callbacks.c
@@ -30,10 +30,10 @@
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
-
/*
* Global callbacks.
*/
+
/* Sets the global idle callback */
void FGAPIENTRY glutIdleFuncUcall( FGCBIdleUC callback, FGCBUserData userData )
{
@@ -42,20 +42,7 @@ void FGAPIENTRY glutIdleFuncUcall( FGCBIdleUC callback, FGCBUserData userData )
fgState.IdleCallbackData = userData;
}
-static void fghIdleFuncCallback( FGCBUserData userData )
-{
- FGCBIdle callback = (FGCBIdle)userData;
- callback();
-}
-
-void FGAPIENTRY glutIdleFunc( FGCBIdle callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
- if( callback )
- glutIdleFuncUcall( fghIdleFuncCallback, (FGCBUserData)callback );
- else
- glutIdleFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(Idle)
/* Creates a timer and sets its callback */
void FGAPIENTRY glutTimerFuncUcall( unsigned int timeOut, FGCBTimerUC callback, int timerID, FGCBUserData userData )
@@ -90,11 +77,7 @@ void FGAPIENTRY glutTimerFuncUcall( unsigned int timeOut, FGCBTimerUC callback,
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
}
-static void fghTimerFuncCallback( int ID, FGCBUserData userData )
-{
- FGCBTimer callback = (FGCBTimer)userData;
- callback( ID );
-}
+IMPLEMENT_CALLBACK_FUNC_CB_ARG1(Timer, Timer)
void FGAPIENTRY glutTimerFunc( unsigned int timeOut, FGCBTimer callback, int timerID )
{
@@ -120,20 +103,7 @@ void FGAPIENTRY glutMenuStatusFuncUcall( FGCBMenuStatusUC callback, FGCBUserData
fgState.MenuStatusCallbackData = userData;
}
-static void fghMenuStatusFuncCallback( int menuState, int mouseX, int mouseY, FGCBUserData userData )
-{
- FGCBMenuStatus callback = (FGCBMenuStatus)userData;
- callback( menuState, mouseX, mouseY );
-}
-
-void FGAPIENTRY glutMenuStatusFunc( FGCBMenuStatus callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
- if( callback )
- glutMenuStatusFuncUcall( fghMenuStatusFuncCallback, (FGCBUserData)callback );
- else
- glutMenuStatusFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3(MenuStatus)
/*
* Menu specific callbacks.
@@ -149,154 +119,34 @@ void FGAPIENTRY glutMenuDestroyFuncUcall( FGCBDestroyUC callback, FGCBUserData u
}
}
-static void fghMenuDestroyFuncCallback( FGCBUserData userData )
-{
- FGCBDestroy callback = (FGCBDestroy)userData;
- callback();
-}
-
-void FGAPIENTRY glutMenuDestroyFunc( FGCBDestroy callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );
- if( callback )
- glutMenuDestroyFuncUcall( fghMenuDestroyFuncCallback, (FGCBUserData)callback );
- else
- glutMenuDestroyFuncUcall( NULL, NULL );
-}
-
-
-/*
- * All of the window-specific callbacks setting methods can be generalized to this:
- */
-#define SET_CALLBACK(a) \
-do \
-{ \
- if( fgStructure.CurrentWindow == NULL ) \
- return; \
- SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback, userData ); \
-} while( 0 )
-/*
- * Types need to be defined for callbacks. It's not ideal, but it works for this.
- */
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
-static void fgh##a##FuncCallback( FGCBUserData userData ) \
-{ \
- FGCB##b callback = (FGCB##b)userData; \
- callback(); \
-}
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,b) \
-static void fgh##a##FuncCallback( int arg1val, FGCBUserData userData ) \
-{ \
- FGCB##b callback = (FGCB##b)userData; \
- callback( arg1val ); \
-}
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
-static void fgh##a##FuncCallback( int arg1val, int arg2val, FGCBUserData userData ) \
-{ \
- FGCB##b callback = (FGCB##b)userData; \
- callback( arg1val, arg2val ); \
-}
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,arg1,arg2,arg3) \
-static void fgh##a##FuncCallback( arg1 arg1val, arg2 arg2val, arg3 arg3val, FGCBUserData userData ) \
-{ \
- FGCB##b callback = (FGCB##b)userData; \
- callback( arg1val, arg2val, arg3val ); \
-}
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,b) IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,b,int,int,int)
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,b) \
-static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, FGCBUserData userData ) \
-{ \
- FGCB##b callback = (FGCB##b)userData; \
- callback( arg1val, arg2val, arg3val, arg4val ); \
-}
-#define IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,b) \
-static void fgh##a##FuncCallback( int arg1val, int arg2val, int arg3val, int arg4val, int arg5val, FGCBUserData userData ) \
-{ \
- FGCB##b callback = (FGCB##b)userData; \
- callback( arg1val, arg2val, arg3val, arg4val, arg5val ); \
-}
-/*
- * And almost every time the callback setter function can be implemented like this:
- */
-#define IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,b) \
-void FGAPIENTRY glut##a##FuncUcall( FGCB##b##UC callback, FGCBUserData userData ) \
-{ \
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"FuncUcall" ); \
- SET_CALLBACK( b ); \
-} \
-void FGAPIENTRY glut##a##Func( FGCB##b callback ) \
-{ \
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glut"#a"Func" ); \
- if( callback ) \
- glut##a##FuncUcall( fgh##a##FuncCallback, (FGCBUserData)callback ); \
- else \
- glut##a##FuncUcall( NULL, NULL ); \
-}
-/*
- * Combine _glut and _cb macros:
- */
-#define IMPLEMENT_CALLBACK_FUNC_ARG0(a) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,a) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG0_2NAME(a,b) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG0(a,b) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,b)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG1(a) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG1(a,a) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG2(a) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,a) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG2_2NAME(a,b) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG2(a,b) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,b)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG3(a) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG3(a,a) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG3_USER(a,arg1,arg2,arg3) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG3_USER(a,a,arg1,arg2,arg3)\
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG4(a) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG4(a,a) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
-
-#define IMPLEMENT_CALLBACK_FUNC_ARG5(a) \
- IMPLEMENT_CALLBACK_FUNC_CB_ARG5(a,a) \
- IMPLEMENT_CALLBACK_FUNC_2NAME_GLUT(a,a)
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0_2NAME(MenuDestroy, Destroy)
/* Implement all these callback setter functions... */
-IMPLEMENT_CALLBACK_FUNC_ARG2(Position)
-IMPLEMENT_CALLBACK_FUNC_ARG3_USER(Keyboard,unsigned char,int,int)
-IMPLEMENT_CALLBACK_FUNC_ARG3_USER(KeyboardUp,unsigned char,int,int)
-IMPLEMENT_CALLBACK_FUNC_ARG3(Special)
-IMPLEMENT_CALLBACK_FUNC_ARG3(SpecialUp)
-IMPLEMENT_CALLBACK_FUNC_ARG4(Mouse)
-IMPLEMENT_CALLBACK_FUNC_ARG4(MouseWheel)
-IMPLEMENT_CALLBACK_FUNC_ARG2(Motion)
-IMPLEMENT_CALLBACK_FUNC_ARG2_2NAME(PassiveMotion,Passive)
-IMPLEMENT_CALLBACK_FUNC_ARG1(Entry)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(Position)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3_USER(Keyboard,unsigned char,int,int)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3_USER(KeyboardUp,unsigned char,int,int)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(Special)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(SpecialUp)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(Mouse)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(MouseWheel)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(Motion)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2_2NAME(PassiveMotion,Passive)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(Entry)
/* glutWMCloseFunc is an alias for glutCloseFunc; both set the window's Destroy callback */
-IMPLEMENT_CALLBACK_FUNC_ARG0_2NAME(Close,Destroy)
-IMPLEMENT_CALLBACK_FUNC_ARG0_2NAME(WMClose,Destroy)
-IMPLEMENT_CALLBACK_FUNC_ARG0(OverlayDisplay)
-IMPLEMENT_CALLBACK_FUNC_ARG1(WindowStatus)
-IMPLEMENT_CALLBACK_FUNC_ARG2(ButtonBox)
-IMPLEMENT_CALLBACK_FUNC_ARG2(Dials)
-IMPLEMENT_CALLBACK_FUNC_ARG2(TabletMotion)
-IMPLEMENT_CALLBACK_FUNC_ARG4(TabletButton)
-IMPLEMENT_CALLBACK_FUNC_ARG2(MultiEntry)
-IMPLEMENT_CALLBACK_FUNC_ARG5(MultiButton)
-IMPLEMENT_CALLBACK_FUNC_ARG3(MultiMotion)
-IMPLEMENT_CALLBACK_FUNC_ARG3(MultiPassive)
-IMPLEMENT_CALLBACK_FUNC_ARG0(InitContext)
-IMPLEMENT_CALLBACK_FUNC_ARG1(AppStatus)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0_2NAME(Close,Destroy)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0_2NAME(WMClose,Destroy)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0(OverlayDisplay)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(WindowStatus)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(ButtonBox)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(Dials)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(TabletMotion)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG4(TabletButton)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG2(MultiEntry)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG5(MultiButton)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(MultiMotion)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG3(MultiPassive)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG0(InitContext)
+IMPLEMENT_CURRENT_WINDOW_CALLBACK_FUNC_ARG1(AppStatus)
/*
* Sets the Display callback for the current window
@@ -307,23 +157,10 @@ void FGAPIENTRY glutDisplayFuncUcall( FGCBDisplayUC callback, FGCBUserData userD
if( !callback )
fgError( "Fatal error in program. NULL display callback not "
"permitted in GLUT 3.0+ or freeglut 2.0.1+" );
- SET_CALLBACK( Display );
+ SET_CURRENT_WINDOW_CALLBACK( Display );
}
-static void fghDisplayFuncCallback( FGCBUserData userData )
-{
- FGCBDisplay callback = (FGCBDisplay)userData;
- callback();
-}
-
-void FGAPIENTRY glutDisplayFunc( FGCBDisplay callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
- if( callback )
- glutDisplayFuncUcall( fghDisplayFuncCallback, (FGCBUserData)callback );
- else
- glutDisplayFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG0(Display)
void fghDefaultReshape( int width, int height, FGCBUserData userData )
{
@@ -340,23 +177,10 @@ void FGAPIENTRY glutReshapeFuncUcall( FGCBReshapeUC callback, FGCBUserData userD
userData = NULL;
}
- SET_CALLBACK( Reshape );
+ SET_CURRENT_WINDOW_CALLBACK( Reshape );
}
-static void fghReshapeFuncCallback( int width, int height, FGCBUserData userData )
-{
- FGCBReshape callback = (FGCBReshape)userData;
- callback( width, height );
-}
-
-void FGAPIENTRY glutReshapeFunc( FGCBReshape callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );
- if( callback )
- glutReshapeFuncUcall( fghReshapeFuncCallback, (FGCBUserData)callback );
- else
- glutReshapeFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2(Reshape)
/*
* Sets the Visibility callback for the current window.
@@ -381,7 +205,7 @@ static void fghVisibility( int status, FGCBUserData userData )
freeglut_return_if_fail( fgStructure.CurrentWindow );
/* Translate window status func states to visibility states */
- if( ( GLUT_HIDDEN == status ) || ( GLUT_FULLY_COVERED == status ) )
+ if( ( status == GLUT_HIDDEN) || ( status == GLUT_FULLY_COVERED) )
vis_status = GLUT_NOT_VISIBLE;
else /* GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED */
vis_status = GLUT_VISIBLE;
@@ -398,7 +222,7 @@ void FGAPIENTRY glutVisibilityFuncUcall( FGCBVisibilityUC callback, FGCBUserData
userData = NULL;
}
- SET_CALLBACK( Visibility );
+ SET_CURRENT_WINDOW_CALLBACK( Visibility );
if( callback )
glutWindowStatusFuncUcall( fghVisibility, NULL );
@@ -406,20 +230,7 @@ void FGAPIENTRY glutVisibilityFuncUcall( FGCBVisibilityUC callback, FGCBUserData
glutWindowStatusFuncUcall( NULL, NULL );
}
-static void fghVisibilityFuncCallback( int visibility, FGCBUserData userData )
-{
- FGCBVisibility callback = (FGCBVisibility)userData;
- callback( visibility );
-}
-
-void FGAPIENTRY glutVisibilityFunc( FGCBVisibility callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
- if( callback )
- glutVisibilityFuncUcall( fghVisibilityFuncCallback, (FGCBUserData)callback );
- else
- glutVisibilityFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG1(Visibility)
/*
* Sets the joystick callback and polling rate for the current window
@@ -446,7 +257,7 @@ void FGAPIENTRY glutJoystickFuncUcall( FGCBJoystickUC callback, int pollInterval
) )
--fgState.NumActiveJoysticks;
- SET_CALLBACK( Joystick );
+ SET_CURRENT_WINDOW_CALLBACK( Joystick );
fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval;
/* set last poll time such that joystick will be polled asap */
@@ -480,23 +291,10 @@ void FGAPIENTRY glutSpaceballMotionFuncUcall( FGCBSpaceMotionUC callback, FGCBUs
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFuncUcall" );
fgInitialiseSpaceball();
- SET_CALLBACK( SpaceMotion );
+ SET_CURRENT_WINDOW_CALLBACK( SpaceMotion );
}
-static void fghSpaceballMotionFuncCallback( int x, int y, int z, FGCBUserData userData )
-{
- FGCBSpaceMotion callback = (FGCBSpaceMotion)userData;
- callback( x, y, z );
-}
-
-void FGAPIENTRY glutSpaceballMotionFunc( FGCBSpaceMotion callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
- if( callback )
- glutSpaceballMotionFuncUcall( fghSpaceballMotionFuncCallback, (FGCBUserData)callback );
- else
- glutSpaceballMotionFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(SpaceballMotion, SpaceMotion)
/*
* Sets the spaceball rotate callback for the current window
@@ -506,23 +304,10 @@ void FGAPIENTRY glutSpaceballRotateFuncUcall( FGCBSpaceRotationUC callback, FGCB
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFuncUcall" );
fgInitialiseSpaceball();
- SET_CALLBACK( SpaceRotation );
+ SET_CURRENT_WINDOW_CALLBACK( SpaceRotation );
}
-static void fghSpaceballRotateFuncCallback( int x, int y, int z, FGCBUserData userData )
-{
- FGCBSpaceRotation callback = (FGCBSpaceRotation)userData;
- callback( x, y, z );
-}
-
-void FGAPIENTRY glutSpaceballRotateFunc( FGCBSpaceRotation callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
- if( callback )
- glutSpaceballRotateFuncUcall( fghSpaceballRotateFuncCallback, (FGCBUserData)callback );
- else
- glutSpaceballRotateFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG3_2NAME(SpaceballRotate, SpaceRotation)
/*
* Sets the spaceball button callback for the current window
@@ -532,22 +317,9 @@ void FGAPIENTRY glutSpaceballButtonFuncUcall( FGCBSpaceButtonUC callback, FGCBUs
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFuncUcall" );
fgInitialiseSpaceball();
- SET_CALLBACK( SpaceButton );
+ SET_CURRENT_WINDOW_CALLBACK( SpaceButton );
}
-static void fghSpaceballButtonFuncCallback( int button, int buttonState, FGCBUserData userData )
-{
- FGCBSpaceButton callback = (FGCBSpaceButton)userData;
- callback( button, buttonState );
-}
-
-void FGAPIENTRY glutSpaceballButtonFunc( FGCBSpaceButton callback )
-{
- FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
- if( callback )
- glutSpaceballButtonFuncUcall( fghSpaceballButtonFuncCallback, (FGCBUserData)callback );
- else
- glutSpaceballButtonFuncUcall( NULL, NULL );
-}
+IMPLEMENT_GLUT_CALLBACK_FUNC_ARG2_2NAME(SpaceballButton, SpaceButton)
/*** END OF FILE ***/
From deaa5b843ab5e6ceaf80dfe334178f8f12cb1375 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:26 +0000
Subject: [PATCH 14/20] Added "hack" function for glutCreateMenuUcall
Not desired, but potentially needed as with the other "hack" functions
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1821 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/include/GL/freeglut_ucall.h | 21 +++++++++++++++++++
freeglut/freeglut/src/mswin/fg_menu_mswin.c | 5 +++++
2 files changed, 26 insertions(+)
diff --git a/freeglut/freeglut/include/GL/freeglut_ucall.h b/freeglut/freeglut/include/GL/freeglut_ucall.h
index bbbd32d..f6fc99a 100644
--- a/freeglut/freeglut/include/GL/freeglut_ucall.h
+++ b/freeglut/freeglut/include/GL/freeglut_ucall.h
@@ -82,6 +82,27 @@ FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *f
FGAPI void FGAPIENTRY glutInitContextFuncUcall( void (* callback)( void* ), void* user_data );
FGAPI void FGAPIENTRY glutAppStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
+/*
+ * Continued "hack" from GLUT applied to Ucall functions.
+ * For more info, see bottom of freeglut_std.h
+ */
+
+/* to get the prototype for exit() */
+#include
+
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
+FGAPI int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*func)(int, void*), void(__cdecl *exitfunc)(int), void* user_data);
+#ifndef FREEGLUT_BUILDING_LIB
+#if defined(__GNUC__)
+#define FGUNUSED __attribute__((unused))
+#else
+#define FGUNUSED
+#endif
+static int FGAPIENTRY FGUNUSED glutCreateMenuUcall_ATEXIT_HACK(void(*func)(int, void*), void* user_data) { return __glutCreateMenuUcallWithExit(func, exit, user_data); }
+#define glutCreateMenuUcall glutCreateMenuUcall_ATEXIT_HACK
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/freeglut/freeglut/src/mswin/fg_menu_mswin.c b/freeglut/freeglut/src/mswin/fg_menu_mswin.c
index 27bc356..42d056b 100644
--- a/freeglut/freeglut/src/mswin/fg_menu_mswin.c
+++ b/freeglut/freeglut/src/mswin/fg_menu_mswin.c
@@ -106,3 +106,8 @@ int FGAPIENTRY __glutCreateMenuWithExit( void(* callback)( int ), void (__cdecl
return glutCreateMenu( callback );
}
+int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*callback)(int, void*), void(__cdecl *exit_function)(int), void* user_data)
+{
+ __glutExitFunc = exit_function;
+ return glutCreateMenuUcall(callback, user_data);
+}
From 850d80554a2e0952bbe2918b2380e32d083aae56 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:39 +0000
Subject: [PATCH 15/20] Added timer_callback sample for user callbacks
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1822 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/CMakeLists.txt | 1 +
.../progs/demos/timer_callback/timer.c | 174 ++++++++++++++++++
2 files changed, 175 insertions(+)
create mode 100644 freeglut/freeglut/progs/demos/timer_callback/timer.c
diff --git a/freeglut/freeglut/CMakeLists.txt b/freeglut/freeglut/CMakeLists.txt
index 55f48ba..58b1b46 100644
--- a/freeglut/freeglut/CMakeLists.txt
+++ b/freeglut/freeglut/CMakeLists.txt
@@ -551,6 +551,7 @@ IF(UNIX)
ENDIF()
ADD_DEMO(subwin progs/demos/subwin/subwin.c)
ADD_DEMO(timer progs/demos/timer/timer.c)
+ADD_DEMO(timer_callback progs/demos/timer_callback/timer.c)
diff --git a/freeglut/freeglut/progs/demos/timer_callback/timer.c b/freeglut/freeglut/progs/demos/timer_callback/timer.c
new file mode 100644
index 0000000..03acd40
--- /dev/null
+++ b/freeglut/freeglut/progs/demos/timer_callback/timer.c
@@ -0,0 +1,174 @@
+/* Timer (callback) demo
+ *
+ * Written by John Tsiombikas
+ * Modified by Vincent Simonetti
+ *
+ * A modification of the timer sample, but with this
+ * offering a use of the user-data callback.
+ */
+#include
+#include
+
+struct display_index_s
+{
+ /* color index will be advanced every time the timer expires */
+ int surround_color_index;
+ int center_color_index;
+};
+typedef struct display_index_s display_index_t;
+
+struct timer_state_s
+{
+ int* color_index_ptr;
+ int* timer_time_ptr;
+};
+typedef struct timer_state_s timer_state_t;
+
+struct menu_state_s
+{
+ int* timer_time_ptr;
+ int menu_id;
+};
+typedef struct menu_state_s menu_state_t;
+
+void disp(void* uptr);
+void timer_func(int which, void* uptr);
+
+const float color[][3] = {
+ {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1},
+ {1, 1, 0},
+ {0, 1, 1},
+ {1, 0, 1}
+};
+const int timerInts[] = {
+ 250,
+ 500,
+ 1000
+};
+
+void createMenuEntries(menu_state_t* menuState)
+{
+ int i;
+ for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
+ {
+ char temp[10] = {'\0'};
+ /* flag current value */
+ if ((*menuState->timer_time_ptr) == timerInts[i])
+ temp[0] = '+';
+ else
+ temp[0] = '-';
+
+ sprintf(temp + 1, " %4d ms", timerInts[i]);
+
+ glutAddMenuEntry(temp, timerInts[i]);
+ }
+}
+
+void updateMenuEntries(menu_state_t* menuState)
+{
+ int i;
+ for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
+ {
+ char temp[10] = { '\0' };
+ /* flag current value */
+ if ((*menuState->timer_time_ptr) == timerInts[i])
+ temp[0] = '+';
+ else
+ temp[0] = '-';
+
+ sprintf(temp + 1, " %4d ms", timerInts[i]);
+
+ glutChangeToMenuEntry(i+1, temp, timerInts[i]);
+ }
+}
+
+void MenuHandler(int timerInt, void* user_ptr)
+{
+ menu_state_t* menuState;
+
+ if (!user_ptr)
+ {
+ /* In case main menu is selected somehow */
+ return;
+ }
+
+ menuState = (menu_state_t*)user_ptr;
+
+ *menuState->timer_time_ptr = timerInt;
+ glutSetMenu(menuState->menu_id);
+ updateMenuEntries(menuState);
+}
+
+int main(int argc, char **argv)
+{
+ int timerSurroundInt = 1000, timerCenterInt = 500;
+ display_index_t displayIndex = { 0, 2 };
+ timer_state_t surroundTimerState = { &displayIndex.surround_color_index, &timerSurroundInt };
+ timer_state_t centerTimerState = { &displayIndex.center_color_index, &timerCenterInt };
+ menu_state_t surroundMenuState = { &timerSurroundInt, 0 };
+ menu_state_t centerMenuState = { &timerCenterInt, 0 };
+
+ glutInit(&argc, argv);
+ glutInitWindowSize(128, 128);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ glutCreateWindow("timer test");
+
+ glutDisplayFuncUcall(disp, &displayIndex);
+
+ /* get timer started, its reset in the timer function itself */
+ glutTimerFuncUcall(timerSurroundInt, timer_func, 1, &surroundTimerState);
+ glutTimerFuncUcall(timerCenterInt, timer_func, 2, ¢erTimerState);
+
+ /* menus for setting timing */
+ surroundMenuState.menu_id = glutCreateMenuUcall(MenuHandler, &surroundMenuState);
+ createMenuEntries(&surroundMenuState);
+
+ centerMenuState.menu_id = glutCreateMenuUcall(MenuHandler, ¢erMenuState);
+ createMenuEntries(¢erMenuState);
+
+ glutCreateMenuUcall(MenuHandler, NULL); /* doesn't matter, no clickable entries in this menu */
+ glutAddSubMenu("Center", centerMenuState.menu_id);
+ glutAddSubMenu("Surround", surroundMenuState.menu_id);
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+ glutMainLoop();
+ return 0;
+}
+
+void disp(void* user_ptr)
+{
+ const display_index_t* displayIndex;
+ int cidx, pcidx;
+
+ displayIndex = (display_index_t*)user_ptr;
+
+ cidx = displayIndex->surround_color_index;
+ glClearColor(color[cidx][0], color[cidx][1], color[cidx][2], 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ pcidx = displayIndex->center_color_index;
+ glPointSize(10.f);
+ glColor3f(color[pcidx][0], color[pcidx][1], color[pcidx][2]);
+ glBegin(GL_POINTS);
+ glVertex2i(0,0);
+ glEnd();
+
+ glutSwapBuffers();
+}
+
+void timer_func(int which, void* user_ptr)
+{
+ const timer_state_t* timerState;
+
+ timerState = (timer_state_t*)user_ptr;
+
+ /* advance the color index and trigger a redisplay */
+ *timerState->color_index_ptr = (*timerState->color_index_ptr + 1) % (sizeof color / sizeof *color);
+
+ glutPostRedisplay();
+
+ /* (re)set the timer callback and ask glut to call it in x ms */
+ glutTimerFuncUcall(*timerState->timer_time_ptr, timer_func, which, user_ptr);
+}
From cc6830131a14f14d72c2c0a29e27a7bbc93d51be Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:45 +0000
Subject: [PATCH 16/20] Fixed x11 and Wayland not using INVOKE_WCB
...since INVOKE_WCB handled user data. Now they handle user data.
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1823 7f0cb862-5218-0410-a997-914c9d46530a
---
.../src/wayland/fg_input_devices_wl.c | 22 +++++++++++-------
freeglut/freeglut/src/x11/fg_main_x11.c | 23 ++++++++++++-------
2 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/freeglut/freeglut/src/wayland/fg_input_devices_wl.c b/freeglut/freeglut/src/wayland/fg_input_devices_wl.c
index 0aaa91e..bb32f98 100644
--- a/freeglut/freeglut/src/wayland/fg_input_devices_wl.c
+++ b/freeglut/freeglut/src/wayland/fg_input_devices_wl.c
@@ -71,8 +71,10 @@ void fghKeyboardInterpretKeysym( SFG_Window* window,
xkb_keysym_t sym,
uint32_t state )
{
- FGCBKeyboard keyboard_cb;
- FGCBSpecial special_cb;
+ FGCBKeyboardUC keyboard_cb;
+ FGCBSpecialUC special_cb;
+ FGCBUserData keyboard_ud;
+ FGCBUserData special_ud;
char string[16];
int special = -1;
@@ -81,13 +83,17 @@ void fghKeyboardInterpretKeysym( SFG_Window* window,
* others, which need to be translated to GLUT_KEY_Xs... */
if( state )
{
- keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
- special_cb = (FGCBSpecial) ( FETCH_WCB( *window, Special ));
+ keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, Keyboard ));
+ special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, Special ));
+ keyboard_ud = FETCH_USER_DATA_WCB( *window, Keyboard );
+ special_ud = FETCH_USER_DATA_WCB( *window, Special );
}
else
{
- keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
- special_cb = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp ));
+ keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, KeyboardUp ));
+ special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, SpecialUp ));
+ keyboard_ud = FETCH_USER_DATA_WCB( *window, KeyboardUp );
+ special_ud = FETCH_USER_DATA_WCB( *window, SpecialUp );
}
switch( sym )
@@ -127,13 +133,13 @@ void fghKeyboardInterpretKeysym( SFG_Window* window,
if( special_cb && (special != -1) )
{
fgSetWindow( window );
- special_cb( special, window->State.MouseX, window->State.MouseY );
+ special_cb( special, window->State.MouseX, window->State.MouseY, special_ud );
}
else if( keyboard_cb && (special == -1) )
{
fgSetWindow( window );
xkb_keysym_to_utf8( sym, string, sizeof( string ) );
- keyboard_cb( string[0], window->State.MouseX, window->State.MouseY );
+ keyboard_cb( string[0], window->State.MouseX, window->State.MouseY, keyboard_ud );
}
}
diff --git a/freeglut/freeglut/src/x11/fg_main_x11.c b/freeglut/freeglut/src/x11/fg_main_x11.c
index 0e54253..80fd2c8 100644
--- a/freeglut/freeglut/src/x11/fg_main_x11.c
+++ b/freeglut/freeglut/src/x11/fg_main_x11.c
@@ -890,8 +890,10 @@ void fgPlatformProcessSingleEvent ( void )
case KeyRelease:
case KeyPress:
{
- FGCBKeyboard keyboard_cb;
- FGCBSpecial special_cb;
+ FGCBKeyboardUC keyboard_cb;
+ FGCBSpecialUC special_cb;
+ FGCBUserData keyboard_ud;
+ FGCBUserData special_ud;
GETWINDOW( xkey );
GETMOUSE( xkey );
@@ -932,13 +934,17 @@ void fgPlatformProcessSingleEvent ( void )
if( event.type == KeyPress )
{
- keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, Keyboard ));
- special_cb = (FGCBSpecial) ( FETCH_WCB( *window, Special ));
+ keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, Keyboard ));
+ special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, Special ));
+ keyboard_ud = FETCH_USER_DATA_WCB( *window, Keyboard );
+ special_ud = FETCH_USER_DATA_WCB( *window, Special );
}
else
{
- keyboard_cb = (FGCBKeyboard)( FETCH_WCB( *window, KeyboardUp ));
- special_cb = (FGCBSpecial) ( FETCH_WCB( *window, SpecialUp ));
+ keyboard_cb = (FGCBKeyboardUC)( FETCH_WCB( *window, KeyboardUp ));
+ special_cb = (FGCBSpecialUC) ( FETCH_WCB( *window, SpecialUp ));
+ keyboard_ud = FETCH_USER_DATA_WCB( *window, KeyboardUp );
+ special_ud = FETCH_USER_DATA_WCB( *window, SpecialUp );
}
/* Is there a keyboard/special callback hooked for this window? */
@@ -963,7 +969,8 @@ void fgPlatformProcessSingleEvent ( void )
fgSetWindow( window );
fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
keyboard_cb( asciiCode[ 0 ],
- event.xkey.x, event.xkey.y
+ event.xkey.x, event.xkey.y,
+ keyboard_ud
);
fgState.Modifiers = INVALID_MODIFIERS;
}
@@ -1031,7 +1038,7 @@ void fgPlatformProcessSingleEvent ( void )
{
fgSetWindow( window );
fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state );
- special_cb( special, event.xkey.x, event.xkey.y );
+ special_cb( special, event.xkey.x, event.xkey.y, special_ud );
fgState.Modifiers = INVALID_MODIFIERS;
}
}
From 1fec35a406a210f9eb4b73accf8d03e7e2b986ab Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:52 +0000
Subject: [PATCH 17/20] Corrected phrasing in docs and unneeded \ in code
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1824 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_internal.h | 2 +-
freeglut/web-src/docs/api.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h
index a61b121..a95027b 100644
--- a/freeglut/freeglut/src/fg_internal.h
+++ b/freeglut/freeglut/src/fg_internal.h
@@ -291,7 +291,7 @@ typedef void (* FGCBAppStatus )( int );
typedef void (* FGCBAppStatusUC )( int, FGCBUserData );
/* The global callbacks type definitions */
-typedef void (* FGCBIdle )( void ); \
+typedef void (* FGCBIdle )( void );
typedef void (* FGCBIdleUC )( FGCBUserData );
typedef void (* FGCBTimer )( int );
typedef void (* FGCBTimerUC )( int, FGCBUserData );
diff --git a/freeglut/web-src/docs/api.php b/freeglut/web-src/docs/api.php
index e7a6d0f..8603eb2 100644
--- a/freeglut/web-src/docs/api.php
+++ b/freeglut/web-src/docs/api.php
@@ -332,7 +332,7 @@ when you created it.
GLUT was created as a tool to help teach OpenGL programming. To simplify
development, callbacks were used for handling display, input, and other
-events. But the time it was developed, the purpose, or for some other
+events. But at the time it was developed, the purpose, or for some other
unknown reason, the callbacks lacked any user-provided data argument.
This has caused considerable difficulties for any significantly advanced
usage of GLUT, and now freeglut. This has prevented any attempt to
From 47fb7d5f28545d0f22438b6e580a5248096a9136 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:22:59 +0000
Subject: [PATCH 18/20] Removed "hack" macro set
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1825 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/src/fg_callback_macros.h | 101 +++------------------
1 file changed, 11 insertions(+), 90 deletions(-)
diff --git a/freeglut/freeglut/src/fg_callback_macros.h b/freeglut/freeglut/src/fg_callback_macros.h
index 2aa6ccd..76d76b1 100644
--- a/freeglut/freeglut/src/fg_callback_macros.h
+++ b/freeglut/freeglut/src/fg_callback_macros.h
@@ -34,9 +34,7 @@
*/
/*
- * Compiler defines:
- * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's variadic macro implementation (AKA, ##__VA_ARGS__)
- * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros
+ * Compiler define: FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports variadic macros
*/
/* What supports variadic macros based off Wikipedia article on it (GCC-like must support C99 or higher to use variadic macros) */
@@ -51,15 +49,6 @@
#define FG_COMPILER_SUPPORTS_VA_ARGS 0
#endif
-/* If __VA_ARGS__ is supported, it needs to be GCC(-like) or Clang (since Clang mimics GCC) */
-#if FG_COMPILER_SUPPORTS_VA_ARGS && \
- (defined(__GNUC__)) || \
- (defined(__clang__))
-#define FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK 1
-#else
-#define FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK 0
-#endif
-
/*
* --------------------------
* Executing window callbacks
@@ -82,86 +71,20 @@
*
* Onto the different "versions" of macros:
*
- * There is one for GCC/Clang(/and supposedly the Intel compiler) which supports the non-standard ##__VA_ARGS__ token. The code may
- * look ugly, but the result is, if this was standard, no one would ever need to open this file unless they were curious (or needed
- * more then 5 arguments for a callback, but that's trivial to add). It works by adding many fake macros to a "picker" macro
- * (PP_HAS_ARGS_IMPL2) which then indictaes which macro counter to use. As we can already use variadic macros (the VA in __VA_ARGS__),
- * this just becomes a "reuse the arguments*.
- *
- * The next is for any non-GCC/Clang/etc. compiler *cough* MSVC/compiler you probably shouldn't be using *cough* that supports C99
- * by default. It requires each callback to have a specific argument count passthrough macro. The only reason there are specific
- * count macros is so that (see paraghraph below) don't need have their own set of callback macros. Ideally, there would only be
- * ZERO and ONE_OR_MORE. This works by having callback-specific macros call a specific handler macro to return user data (ZERO) or
- * return one or more arguments along with userData (ONE_OR_MORE) where, with variadic macros, it just reuses the arguments.
+ * The first is for any compiler that supports C99 by default. It requires each callback to have a specific argument count
+ * passthrough macro. The only reason there are specific count macros is so that (see paraghraph below) don't need have their own
+ * set of callback macros. Ideally, there would only be ZERO and ONE_OR_MORE. This works by having callback-specific macros call a
+ * specific handler macro to return user data (ZERO) or return one or more arguments along with userData (ONE_OR_MORE) where, with
+ * variadic macros, it just reuses the arguments.
*
- * The last set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support it at
- * all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without the
- * parathesis.
+ * The last macro set is for the poor individual who has to use a compiler that doesn't support C99 by default, or may not support
+ * it at all. Stuff like MSVC6... It works by having a specific-count macro that "extracts" each argument to have them reused without
+ * the parathesis.
*
- * A note on parathesis, as earlier mentioned, if the GCC variadic macro element was standard, then instead of needing:
- *
- * func EXPAND_WCB(Mouse)(( (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30), userData));
- *
- * ...you can do the following:
- *
- * func EXPAND_WCB (GLUT_LEFT_BUTTON, GLUT_DOWN, 10, 30);
- *
- * Wow... so much nice and easier to understand. Sub-note: I have not worked on a version that explicitly takes userData, so for now
- * if you can get to that version, look in the version control change history for this file and you'll find that version which
- * implicitly passes "userData" and only works on GCC vardiac macro supporting compilers.
+ * There is a 3rd macro set that only worked on GCC/Clang, and thus was removed (last seen in revision e9676fc of the GIT mirror.
+ * Not sure at this time what the SVN number is.) as it's a non-standard functionality.
*/
-#if FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK
-
- /*
- * EXPAND_WCB() is used as:
- *
- * EXPAND_WCB( cbname )(( arg_list, userData ))
- *
- * ... where {(arg_list)} is the parameter list and userData is user
- * provided data.
- *
- * All additional macros are to get around trailing ',' for zero-arg
- * callbacks.
- *
- * Modification of:
- * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946
- *
- * --------------
- *
- * GCC-specific design that doesn't require per-callback defines
- *
- * The naming is terrible... and it's very convuluted and complex, but
- * should not require any modification unless additional arguments are to
- * be supported.
- *
- * Supports callbacks up to 5 args (follow the pattern of
- * EXPAND_WCB_PP_HAS_ARGS_IMPL2 and EXPAND_WCB_PP_HAS_ARGS_SOURCE to add more)
- *
- * Edit with care.
- */
-
-#define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
-
-#define EXPAND_WCB_PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N
-#define EXPAND_WCB_PP_HAS_ARGS_SOURCE() ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ZERO
-
-#define EXPAND_WCB_PP_HAS_ARGS_IMPL(...) EXPAND_WCB_PP_HAS_ARGS_IMPL2( __VA_ARGS__ )
-#define EXPAND_WCB_PP_HAS_ARGS(...) EXPAND_WCB_PP_HAS_ARGS_IMPL( NOT_EXIST, ##__VA_ARGS__, EXPAND_WCB_PP_HAS_ARGS_SOURCE() )
-
-#define EXPAND_WCB_ZERO(args, userData) ( userData )
-#define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
-
-#define EXPAND_WCB_DISAMBIGUATE2(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData )
-#define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_DISAMBIGUATE2( has_args, args, userData )
-
-#define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( EXPAND_WCB_PP_HAS_ARGS args, args, userData )
-#define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args
-
-#define EXPAND_WCB(cbname) EXPAND_WCB_UNWRAP_ARGS
-
-#else
-
/*
* EXPAND_WCB() is used as:
*
@@ -255,8 +178,6 @@
#define EXPAND_WCB_SUB_InitContext(args) EXPAND_WCB_ZERO args
#define EXPAND_WCB_SUB_AppStatus(args) EXPAND_WCB_ONE args
-#endif
-
/*
* ------------------------
* Setting window callbacks
From 5df98e73df94020bf7f3a3db616e9d8bc5fd29d4 Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:23:05 +0000
Subject: [PATCH 19/20] CMake produces an error if XInput.h is not found
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1826 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/CMakeLists.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/freeglut/freeglut/CMakeLists.txt b/freeglut/freeglut/CMakeLists.txt
index 58b1b46..b4db0fd 100644
--- a/freeglut/freeglut/CMakeLists.txt
+++ b/freeglut/freeglut/CMakeLists.txt
@@ -326,6 +326,8 @@ IF(UNIX AND NOT(ANDROID OR BLACKBERRY OR FREEGLUT_WAYLAND))
# Needed for multi-touch:
CHECK_INCLUDE_FILES("${X11_Xinput_INCLUDE_PATH}/X11/extensions/XInput2.h" HAVE_X11_EXTENSIONS_XINPUT2_H)
LIST(APPEND LIBS ${X11_Xinput_LIB})
+ ELSE()
+ MESSAGE(FATAL_ERROR, "Missing X11's XInput.h (X11/extensions/XInput.h)")
ENDIF()
ENDIF()
IF(ANDROID)
From fbd61be1ddb2004c6ac793cc13a7fddec550ccdb Mon Sep 17 00:00:00 2001
From: dcnieho
Date: Fri, 30 Jun 2017 23:23:11 +0000
Subject: [PATCH 20/20] Fixed incorrect MESSAGE usage
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1827 7f0cb862-5218-0410-a997-914c9d46530a
---
freeglut/freeglut/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/freeglut/freeglut/CMakeLists.txt b/freeglut/freeglut/CMakeLists.txt
index b4db0fd..c86d4ce 100644
--- a/freeglut/freeglut/CMakeLists.txt
+++ b/freeglut/freeglut/CMakeLists.txt
@@ -327,7 +327,7 @@ IF(UNIX AND NOT(ANDROID OR BLACKBERRY OR FREEGLUT_WAYLAND))
CHECK_INCLUDE_FILES("${X11_Xinput_INCLUDE_PATH}/X11/extensions/XInput2.h" HAVE_X11_EXTENSIONS_XINPUT2_H)
LIST(APPEND LIBS ${X11_Xinput_LIB})
ELSE()
- MESSAGE(FATAL_ERROR, "Missing X11's XInput.h (X11/extensions/XInput.h)")
+ MESSAGE(FATAL_ERROR "Missing X11's XInput.h (X11/extensions/XInput.h)")
ENDIF()
ENDIF()
IF(ANDROID)