Initial work on callbacks with user data parameters.
authorRcmaniac25 <rcmaniac25@hotmail.com>
Fri, 30 Jun 2017 23:20:57 +0000 (23:20 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Fri, 30 Jun 2017 23:20:57 +0000 (23:20 +0000)
-glutCreateMenuUcall
-glutTimerFuncUcall
-glutIdleFuncUcall

git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1808 7f0cb862-5218-0410-a997-914c9d46530a

include/GL/freeglut_ext.h
include/GL/freeglut_ucall.h [new file with mode: 0644]
src/fg_callbacks.c
src/fg_ext.c
src/fg_init.c
src/fg_internal.h
src/fg_main.c
src/fg_menu.c
src/fg_structure.c

index 2ef96c2..255edea 100644 (file)
@@ -274,6 +274,9 @@ FGAPI void    FGAPIENTRY glutAppStatusFunc(void (* callback)(int));
 #define  GLUT_BORDERLESS                    0x0800
 #define  GLUT_SRGB                          0x1000
 
+/* User-argument callbacks and implementation */
+#include "freeglut_ucall.h"
+
 #ifdef __cplusplus
     }
 #endif
diff --git a/include/GL/freeglut_ucall.h b/include/GL/freeglut_ucall.h
new file mode 100644 (file)
index 0000000..9cbe82a
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef  __FREEGLUT_UCALL_H__
+#define  __FREEGLUT_UCALL_H__
+
+/*
+ * freeglut_ucall.h
+ *
+ * Callbacks with user data arguments.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/*
+ * Menu stuff, see fg_menu.c
+ */
+FGAPI int  FGAPIENTRY glutCreateMenuUcall( void (* callback)( int menu, void* user_data ), void* user_data );
+
+/*
+ * Global callback functions, see fg_callbacks.c
+ */
+FGAPI void FGAPIENTRY glutTimerFuncUcall( unsigned int time, void (* callback)( int, void* ), int value, void* user_data );
+FGAPI void FGAPIENTRY glutIdleFuncUcall( void (* callback)( void* ), void* user_data );
+
+/*
+ * Window-specific callback functions, see fg_callbacks.c
+ */
+FGAPI void FGAPIENTRY glutKeyboardFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutSpecialFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutReshapeFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutVisibilityFuncUcall( void (* callback)( int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutDisplayFuncUcall( void (* callback)( void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMouseFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutPassiveMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutEntryFuncUcall( void (* callback)( int, void* ), void* user_data );
+
+FGAPI void FGAPIENTRY glutKeyboardUpFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutSpecialUpFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutJoystickFuncUcall( void (* callback)( unsigned int, int, int, int, void* ), int pollInterval, void* user_data );
+FGAPI void FGAPIENTRY glutMenuStateFuncUcall( void (* callback)( int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMenuStatusFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutOverlayDisplayFuncUcall( void (* callback)( void* ), void* user_data );
+FGAPI void FGAPIENTRY glutWindowStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
+
+FGAPI void FGAPIENTRY glutSpaceballMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutSpaceballRotateFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutSpaceballButtonFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutButtonBoxFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutDialsFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutTabletMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutTabletButtonFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
+
+FGAPI void FGAPIENTRY glutMouseWheelFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutPositionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutCloseFuncUcall( void (* callback)( void* ), void* user_data );
+FGAPI void FGAPIENTRY glutWMCloseFuncUcall( void (* callback)( void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMenuDestroyFuncUcall( void (* callback)( void* ), void* user_data );
+
+/*
+ * Multi-touch/multi-pointer extensions
+ */
+FGAPI void FGAPIENTRY glutMultiEntryFuncUcall( void (* callback)( int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMultiButtonFuncUcall( void (* callback)( int, int, int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMultiMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutMultiPassiveFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
+
+/*
+ * Initialization functions, see fg_init.c
+ */
+#include <stdarg.h>
+FGAPI void FGAPIENTRY glutInitErrorFuncUcall( void (* callback)( const char *fmt, va_list ap, void* ), void* user_data );
+FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *fmt, va_list ap, void* ), void* user_data );
+
+/* Mobile platforms lifecycle */
+FGAPI void FGAPIENTRY glutInitContextFuncUcall(void (* callback)(void*), void* user_data);
+FGAPI void FGAPIENTRY glutAppStatusFuncUcall(void (* callback)(int, void*), void* user_data);
+
+#ifdef __cplusplus
+    }
+#endif
+
+/*** END OF FILE ***/
+
+#endif /* __FREEGLUT_UCALL_H__ */
+
index 11924b3..b09f421 100644 (file)
  * 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 )
 {
index d96849a..4c1f9c9 100644 (file)
@@ -210,6 +210,12 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
     CHECK_NAME(glutSetVertexAttribCoord3);
     CHECK_NAME(glutSetVertexAttribNormal);
     CHECK_NAME(glutSetVertexAttribTexCoord2);
+
+    /* freeglut user callback functions */
+    CHECK_NAME(glutCreateMenuUcall);
+    CHECK_NAME(glutTimerFuncUcall);
+    CHECK_NAME(glutIdleFuncUcall);
+    //TODO
 #undef CHECK_NAME
 
     return NULL;
index ae87212..ffd3f99 100644 (file)
@@ -70,6 +70,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE },  /* Position */
                       { NULL, NULL },         /* Timers */
                       { NULL, NULL },         /* FreeTimers */
                       NULL,                   /* IdleCallback */
+                      NULL,                   /* IdleCallbackData */
                       0,                      /* ActiveMenus */
                       NULL,                   /* MenuStateCallback */
                       NULL,                   /* MenuStatusCallback */
@@ -299,6 +300,7 @@ void fgDeinitialize( void )
     fgListInit( &fgState.FreeTimers );
 
     fgState.IdleCallback = NULL;
+    fgState.IdleCallbackData = NULL;
     fgState.MenuStateCallback = ( FGCBMenuState )NULL;
     fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
 
index 2cecf71..8e27f54 100644 (file)
 /* -- 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 */
index 0f47c8d..6e9ff48 100644 (file)
@@ -233,7 +233,7 @@ static void fghCheckTimers( void )
         fgListRemove( &fgState.Timers, &timer->Node );
         fgListAppend( &fgState.FreeTimers, &timer->Node );
 
-        timer->Callback( timer->ID );
+        timer->Callback( timer->ID, timer->CallbackData );
     }
 }
 
@@ -509,7 +509,7 @@ void FGAPIENTRY glutMainLoop( void )
                     fgStructure.CurrentWindow->IsMenu )
                     /* fail safe */
                     fgSetWindow( window );
-                fgState.IdleCallback( );
+                fgState.IdleCallback( fgState.IdleCallbackData );
             }
             else
                 fghSleepForEvents( );
index 36b24ce..cad5b83 100644 (file)
@@ -609,7 +609,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
 
                 /* Deactivate menu and then call callback (we don't want menu to stay in view while callback is executing, and user should be able to change menus in callback) */
                 fgDeactivateMenu( parent_window );
-                active_menu->Callback( active_entry->ID );
+                active_menu->Callback( active_entry->ID, active_menu->CallbackData );
 
                 /* Restore the current window and menu */
                 fgSetWindow( save_window );
@@ -780,14 +780,27 @@ void fghCalculateMenuBoxSize( void )
 /*
  * Creates a new menu object, adding it to the freeglut structure
  */
-int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
+int FGAPIENTRY glutCreateMenuUcall( FGCBMenuUC callback, FGCBUserData userData )
 {
     /* The menu object creation code resides in fg_structure.c */
-    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenuUcall" );
     if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
-    return fgCreateMenu( callback )->ID;
+    return fgCreateMenu( callback, userData )->ID;
+}
+
+/* Standard glutCreateMenu */
+void glutCreateMenuCallback( int menu, FGCBUserData userData )
+{
+    FGCBMenu callback = (FGCBMenu)userData;
+    callback( menu );
+}
+
+int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
+{
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
+    return glutCreateMenuUcall( glutCreateMenuCallback, (FGCBUserData)callback );
 }
 
 /*
index f0bc9a2..c279b4a 100644 (file)
@@ -116,7 +116,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
 /*
  * This private function creates a menu and adds it to the menus list
  */
-SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
+SFG_Menu* fgCreateMenu( FGCBMenuUC menuCallback, FGCBUserData userData )
 {
     SFG_Window *current_window = fgStructure.CurrentWindow;
 
@@ -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 );