Propogated a pointer-check from menu-attach to menu-detach. (Apparently,
[freeglut] / src / freeglut_window.c
index 9e4a9e3..14733e2 100644 (file)
@@ -63,6 +63,7 @@
  * Chooses a visual basing on the current display mode settings
  */
 #if TARGET_HOST_UNIX_X11
+
 XVisualInfo* fgChooseVisual( void )
 {
     int bufferSize[] = { 16, 12, 8, 4, 2, 1 };
@@ -233,7 +234,7 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned
         * It might be the case for us to use double buffering
         */
   if( fgState.DisplayMode & GLUT_DOUBLE )
-       flags |= PFD_DOUBLEBUFFER;
+    flags |= PFD_DOUBLEBUFFER;
 
   /*
    * Specify which pixel format do we opt for...
@@ -305,6 +306,8 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned
 void fgSetWindow ( SFG_Window *window )
 {
 #if TARGET_HOST_UNIX_X11
+  if ( window )
+  {
     /*
         * Make the selected window's GLX context the current one
      */
@@ -313,7 +316,7 @@ void fgSetWindow ( SFG_Window *window )
         window->Window.Handle,
         window->Window.Context
     );
-
+  }
 #elif TARGET_HOST_WIN32
        /*
         * Release the previous' context's device context
@@ -363,7 +366,24 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
     /*
      * Here we are upon the stage. Have the visual selected.
      */
-    window->Window.VisualInfo = fgChooseVisual();
+    if ( fgState.BuildingAMenu )
+    {
+      /*
+       * If there isn't already an OpenGL rendering context for menu windows, make one
+       */
+      if ( !fgStructure.MenuContext )
+      {
+        unsigned int current_DisplayMode = fgState.DisplayMode ;
+        fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ;
+        window->Window.VisualInfo = fgChooseVisual();
+        fgState.DisplayMode = current_DisplayMode ;
+      }
+      else
+        window->Window.VisualInfo = fgChooseVisual();
+    }
+    else
+      window->Window.VisualInfo = fgChooseVisual();
+
     if ( ! window->Window.VisualInfo )
     {
       /*
@@ -377,6 +397,10 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
          */
         fgState.DisplayMode |= GLUT_DOUBLE ;
         window->Window.VisualInfo = fgChooseVisual();
+       /* OK, we got a double-buffered window, but we only wanted
+        * single-buffered.  Clear the double-buffer flag now.
+        */
+       fgState.DisplayMode &= ~GLUT_DOUBLE ;
       }
 
       /*
@@ -415,6 +439,15 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
     mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
 
     /*
+     * If this is a menu window we want the window manager to ignore it.
+     */
+    if ( fgState.BuildingAMenu )
+    {
+        winAttr.override_redirect = True;
+       mask |= CWOverrideRedirect;
+    }
+
+    /*
      * Have the window created now
      */
     window->Window.Handle = XCreateWindow(
@@ -428,11 +461,44 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
 
     /*
      * The GLX context creation, possibly trying the direct context rendering
+     *  or else use the current context if the user has so specified
      */
-    window->Window.Context = glXCreateContext(
-        fgDisplay.Display, window->Window.VisualInfo,
-        NULL, fgState.ForceDirectContext | fgState.TryDirectContext
-    );
+    if ( fgState.BuildingAMenu )
+    {
+      /*
+       * If there isn't already an OpenGL rendering context for menu windows, make one
+       */
+      if ( !fgStructure.MenuContext )
+      {
+        fgStructure.MenuContext = (SFG_MenuContext *)malloc ( sizeof(SFG_MenuContext) ) ;
+        fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo ;
+        fgStructure.MenuContext->Context = glXCreateContext(
+            fgDisplay.Display, fgStructure.MenuContext->VisualInfo,
+            NULL, fgState.ForceDirectContext | fgState.TryDirectContext
+        );
+      }
+
+/*      window->Window.Context = fgStructure.MenuContext->Context ; */
+      window->Window.Context = glXCreateContext(
+            fgDisplay.Display, window->Window.VisualInfo,
+            NULL, fgState.ForceDirectContext | fgState.TryDirectContext
+        );
+    }
+    else if ( fgState.UseCurrentContext == TRUE )
+    {
+      window->Window.Context = glXGetCurrentContext();
+
+      if ( ! window->Window.Context )
+        window->Window.Context = glXCreateContext(
+            fgDisplay.Display, window->Window.VisualInfo,
+            NULL, fgState.ForceDirectContext | fgState.TryDirectContext
+        );
+    }
+    else
+      window->Window.Context = glXCreateContext(
+          fgDisplay.Display, window->Window.VisualInfo,
+          NULL, fgState.ForceDirectContext | fgState.TryDirectContext
+      );
 
     /*
      * Make sure the context is direct when the user wants it forced
@@ -505,37 +571,6 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
      */
     XMapWindow( fgDisplay.Display, window->Window.Handle );
 
-    /*
-     * In game mode, move the viewport a bit to hide the decorations.
-     * This code depends on the XFree86 video mode extensions.
-     */
-    if( gameMode == TRUE )
-    {
-        /*
-         * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem...
-         */
-        XMoveWindow( fgDisplay.Display, window->Window.Handle, x, y );
-
-#       ifdef X_XF86VidModeSetViewPort
-
-        /*
-         * Set the newly created window as the current one...
-         */
-        fgSetWindow( window );
-
-        /*
-         * Move the viewport a bit down and right from top-left corner to hide the decorations
-         */
-        XF86VidModeSetViewPort(
-            fgDisplay.Display,
-            fgDisplay.Screen,
-            glutGet( GLUT_WINDOW_X ),
-            glutGet( GLUT_WINDOW_Y )
-        );
-
-#       endif
-    }
-
 #elif TARGET_HOST_WIN32
 
        WNDCLASS wc;
@@ -552,7 +587,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
 
     if( gameMode == FALSE )
     {
-      if ( !isSubWindow )
+      if ( ( !isSubWindow ) && ( ! window->IsMenu ) )
       {
         /*
          * Update the window dimensions, taking account of window decorations.
@@ -574,7 +609,12 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
             */
            flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
 
-           if( window->Parent == NULL )
+      /*
+       * If we're a menu, set our flags to include WS_POPUP to remove decorations
+       */
+      if ( window->IsMenu )
+        flags |= WS_POPUP ;
+           else if( window->Parent == NULL )
                    flags |= WS_OVERLAPPEDWINDOW;
            else
                    flags |= WS_CHILD;
@@ -833,6 +873,12 @@ void FGAPIENTRY glutShowWindow( void )
        ShowWindow( fgStructure.Window->Window.Handle, SW_SHOW );
 
 #endif
+
+  /*
+   * Since the window is visible, we need to redisplay it ...
+   */
+  fgStructure.Window->State.Redisplay = TRUE;
+
 }
 
 /*
@@ -874,6 +920,11 @@ void FGAPIENTRY glutHideWindow( void )
        ShowWindow( fgStructure.Window->Window.Handle, SW_HIDE );
 
 #endif
+
+  /*
+   * Since the window is hidden, we don't need to redisplay it ...
+   */
+  fgStructure.Window->State.Redisplay = FALSE;
 }
 
 /*
@@ -897,6 +948,12 @@ void FGAPIENTRY glutIconifyWindow( void )
        ShowWindow( fgStructure.Window->Window.Handle, SW_MINIMIZE );
 
 #endif
+
+  /*
+   * Since the window is just an icon, we don't need to redisplay it ...
+   */
+  fgStructure.Window->State.Redisplay = FALSE;
+
 }
 
 /*
@@ -1026,10 +1083,13 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
     if ( fgStructure.Window->Parent == NULL )  /* If this is not a subwindow ... */
     {
       /*
-       * Adjust the size of the window to allow for the size of the frame
+       * Adjust the size of the window to allow for the size of the frame, if we are not a menu
        */
-               width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
-               height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION );
+      if ( ! fgStructure.Window->IsMenu )
+      {
+               width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
+               height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION );
+      }
     }
     else  /* This is a subwindow, get the parent window's position and subtract it off */
     {