Fixed issue where setting the same callback with different user pointer wouldn't...
[freeglut] / src / fg_menu.c
index d3c435f..ae7405c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * freeglut_menu.c
+ * fg_menu.c
  *
  * Pull-down menu creation and handling.
  *
@@ -65,7 +65,7 @@
  * These variables are for rendering the freeglut menu items.
  *
  * The choices are fore- and background, with and without h for Highlighting.
- * Old GLUT appeared to be system-dependant for its colors (sigh) so we are
+ * Old GLUT appeared to be system-dependent for its colors (sigh) so we are
  * too.  These variables should be stuffed into global state and initialized
  * via the glutInit*() system.
  */
@@ -207,7 +207,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
 
         if( menuEntry != menu->ActiveEntry )
         {
-            menu->Window->State.Redisplay = GL_TRUE;
+            menu->Window->State.WorkMask |= GLUT_DISPLAY_WORK;
             if( menu->ActiveEntry )
                 menu->ActiveEntry->IsActive = GL_FALSE;
         }
@@ -277,7 +277,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
         ( !menu->ActiveEntry->SubMenu ||
           !menu->ActiveEntry->SubMenu->IsActive ) )
     {
-        menu->Window->State.Redisplay = GL_TRUE;
+        menu->Window->State.WorkMask |= GLUT_DISPLAY_WORK;
         menu->ActiveEntry->IsActive = GL_FALSE;
         menu->ActiveEntry = NULL;
     }
@@ -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 );
@@ -607,9 +607,9 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
                 fgSetWindow( parent_window );
                 fgStructure.CurrentMenu = active_menu;
 
-                /* Deactivate menu and then call callback (we don't want menu to stay in view while callback is executing) */
+                /* 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 );
@@ -632,7 +632,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
 
         is_handled = GL_TRUE;
     }
-    else if ( fgStructure.Menus.First ) /* Don't have to check whether this was a downpress or an uppress, there is no way to get an uppress in another window before a downpress... */
+    else if ( fgState.ActiveMenus ) /* Don't have to check whether this was a downpress or an uppress, there is no way to get an uppress in another window before a downpress... */
     {
         /* if another window than the one clicked in has an open menu, close it */
         SFG_Menu *menu = fgGetActiveMenu();
@@ -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);
         }
     }
 }
@@ -780,14 +780,33 @@ void fghCalculateMenuBoxSize( void )
 /*
  * Creates a new menu object, adding it to the freeglut structure
  */
+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." );
+       }
+
+    return fgCreateMenu( callback, userData )->ID;
+}
+
+/* Standard glutCreateMenu */
+static void fghCreateMenuCallback( int menu, FGCBUserData userData )
+{
+    FGCBMenu callback = (FGCBMenu)userData;
+    callback( menu );
+}
+
 int FGAPIENTRY glutCreateMenu( FGCBMenu callback )
 {
-    /* The menu object creation code resides in freeglut_structure.c */
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
-    if (fgGetActiveMenu())
-        fgError("Menu manipulation not allowed while menus in use.");
-
-    return fgCreateMenu( callback )->ID;
+    if (!callback)
+       {
+        return glutCreateMenuUcall( NULL, NULL );
+       }
+    return glutCreateMenuUcall( fghCreateMenuCallback, (FGCBUserData)callback );
 }
 
 /*
@@ -801,10 +820,10 @@ void FGAPIENTRY glutDestroyMenu( int menuID )
     menu = fgMenuByID( menuID );
 
     freeglut_return_if_fail( menu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
-    /* The menu object destruction code resides in freeglut_structure.c */
+    /* The menu object destruction code resides in fg_structure.c */
     fgDestroyMenu( menu );
 }
 
@@ -846,7 +865,7 @@ void FGAPIENTRY glutAddMenuEntry( const char* label, int value )
     menuEntry = (SFG_MenuEntry *)calloc( sizeof(SFG_MenuEntry), 1 );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     menuEntry->Text = strdup( label );
@@ -871,7 +890,7 @@ void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID )
     subMenu = fgMenuByID( subMenuID );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     freeglut_return_if_fail( subMenu );
@@ -895,7 +914,7 @@ void FGAPIENTRY glutSetMenuFont( int menuID, void* fontID )
     menu = fgMenuByID( menuID );
     freeglut_return_if_fail( menu );
 
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     font = fghFontByID( fontID );
@@ -919,7 +938,7 @@ void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value )
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutChangeToMenuEntry" );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     /* Get n-th menu entry in the current menu, starting from one: */
@@ -949,7 +968,7 @@ void FGAPIENTRY glutChangeToSubMenu( int item, const char* label,
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutChangeToSubMenu" );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     /* Get handle to sub menu */
@@ -982,7 +1001,7 @@ void FGAPIENTRY glutRemoveMenuItem( int item )
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutRemoveMenuItem" );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     /* Get n-th menu entry in the current menu, starting from one: */
@@ -1008,7 +1027,7 @@ void FGAPIENTRY glutAttachMenu( int button )
     freeglut_return_if_fail( fgStructure.CurrentWindow );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     freeglut_return_if_fail( button >= 0 );
@@ -1027,7 +1046,7 @@ void FGAPIENTRY glutDetachMenu( int button )
     freeglut_return_if_fail( fgStructure.CurrentWindow );
 
     freeglut_return_if_fail( fgStructure.CurrentMenu );
-    if (fgGetActiveMenu())
+    if (fgState.ActiveMenus)
         fgError("Menu manipulation not allowed while menus in use.");
 
     freeglut_return_if_fail( button >= 0 );