OpenGL context is not made current on Win32 until fgSetWindow is called.
[freeglut] / src / freeglut_window.c
index 907696d..c92fbcb 100644 (file)
@@ -162,7 +162,9 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
     if( fgState.DisplayMode & GLUT_DOUBLE )
         flags |= PFD_DOUBLEBUFFER;
 
+#if defined(_MSC_VER)
 #pragma message( "fgSetupPixelFormat(): there is still some work to do here!" )
+#endif
 
     /*
      * Specify which pixel format do we opt for...
@@ -265,7 +267,7 @@ void fgOpenWindow( SFG_Window* window, const char* title,
      * XXX With a little thought, we should be able to greatly
      * XXX simplify this.
      */
-    if ( !fgState.BuildingAMenu )
+    if ( !window->IsMenu )
       window->Window.VisualInfo = fgChooseVisual();
     else if ( fgStructure.MenuContext )
         window->Window.VisualInfo = fgChooseVisual();
@@ -327,7 +329,7 @@ void fgOpenWindow( SFG_Window* window, const char* title,
 
     mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
 
-    if ( fgState.BuildingAMenu )
+    if ( window->IsMenu )
     {
         winAttr.override_redirect = True;
         mask |= CWOverrideRedirect;
@@ -347,7 +349,7 @@ void fgOpenWindow( SFG_Window* window, const char* title,
      * The GLX context creation, possibly trying the direct context rendering
      *  or else use the current context if the user has so specified
      */
-    if ( fgState.BuildingAMenu )
+    if ( window->IsMenu )
     {
         /*
          * If there isn't already an OpenGL rendering context for menu
@@ -528,15 +530,16 @@ void fgOpenWindow( SFG_Window* window, const char* title,
 
 #endif
 
+    fgSetWindow( window );
+
     window->Window.DoubleBuffered =
-        ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0 ;
+        ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0;
 
     if ( ! window->Window.DoubleBuffered )
     {
-        glDrawBuffer ( GL_FRONT ) ;
-        glReadBuffer ( GL_FRONT ) ;
+        glDrawBuffer ( GL_FRONT );
+        glReadBuffer ( GL_FRONT );
     }
-    fgSetWindow( window );
 }
 
 /*
@@ -554,13 +557,34 @@ void fgCloseWindow( SFG_Window* window )
 
 #elif TARGET_HOST_WIN32
 
-    SendMessage( 
-        window->Window.Handle,
-        WM_CLOSE,
-        0,
-        0
-    );
+    /*
+     * Make sure we don't close a window with current context active
+     */
+    if( fgStructure.Window == window )
+        wglMakeCurrent( NULL, NULL );
+
+    /*
+     * Step through the list of windows.  If the rendering context
+     * is not being used by another window, then we delete it.
+     */
+    {
+        int used = FALSE ;
+        SFG_Window *iter ;
+
+        for( iter = (SFG_Window *)fgStructure.Windows.First;
+             iter;
+             iter = (SFG_Window *)iter->Node.Next )
+        {
+            if( ( iter->Window.Context == window->Window.Context ) &&
+                ( iter != window ) )
+                used = TRUE;
+        }
 
+        if( ! used )
+            wglDeleteContext( window->Window.Context );
+    }
+
+    DestroyWindow( window->Window.Handle );
 #endif
 }
 
@@ -573,7 +597,8 @@ void fgCloseWindow( SFG_Window* window )
 int FGAPIENTRY glutCreateWindow( const char* title )
 {
     return fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y,
-                           fgState.Size.X, fgState.Size.Y, GL_FALSE )->ID;
+                           fgState.Size.X, fgState.Size.Y, GL_FALSE,
+                           GL_FALSE )->ID;
 }
 
 /*
@@ -587,7 +612,7 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
     freeglut_assert_ready;
     parent = fgWindowByID( parentID );
     freeglut_return_val_if_fail( parent != NULL, 0 );
-    window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE );
+    window = fgCreateWindow( parent, "", x, y, w, h, GL_FALSE, GL_FALSE );
     return window->ID;
 }
 
@@ -600,7 +625,7 @@ void FGAPIENTRY glutDestroyWindow( int windowID )
     freeglut_return_if_fail( window != NULL );
     {
         fgExecutionState ExecState = fgState.ExecState;
-        fgAddToWindowDestroyList( window, GL_TRUE );
+        fgAddToWindowDestroyList( window );
         fgState.ExecState = ExecState;
     }
 }
@@ -624,7 +649,7 @@ void FGAPIENTRY glutSetWindow( int ID )
         return;
     }
 
-    fgSetWindow( window ) ;
+    fgSetWindow( window );
 }
 
 /*
@@ -792,68 +817,9 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
     freeglut_assert_ready;
     freeglut_assert_window;
 
-#if TARGET_HOST_UNIX_X11
-
-    XResizeWindow( fgDisplay.Display, fgStructure.Window->Window.Handle,
-                   width, height );
-    XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */
-    /*
-     * XXX REALLY shouldn't be done.  GLUT docs state that this
-     * XXX isn't even processed immediately, but rather waits
-     * XXX for return to the mainloop.  "This allows multiple
-     * XXX glutReshapeWindow, glutPositionWindow, and glutFullScreen
-     * XXX requests to the same window to be coalesced."  (This is
-     * XXX having some deleterious effect on a sample program of mine.)
-     * XXX Not only does GLUT not flush at this point, GLUT doesn't even
-     * XXX *do* the reshape at this point!  We should probably rip this
-     * XXX out and do what GLUT promises.  It would be more efficient, and
-     * XXX might be more compatible.
-     */
-
-#elif TARGET_HOST_WIN32
-
-    {
-        RECT winRect;
-        int x, y;
-
-        GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
-        x = winRect.left;
-        y = winRect.top;
-
-        if ( fgStructure.Window->Parent == NULL )
-        {
-            /*
-             * Adjust the size of the window to allow for the size of the
-             * frame, if we are not a menu
-             */
-            if ( ! fgStructure.Window->IsMenu )
-            {
-                width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
-                height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
-                    GetSystemMetrics( SM_CYCAPTION );
-            }
-        }
-        else
-        {
-            GetWindowRect( fgStructure.Window->Parent->Window.Handle,
-                           &winRect );
-            x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME );
-            y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) +
-                GetSystemMetrics( SM_CYCAPTION );
-        }
-
-        MoveWindow(
-            fgStructure.Window->Window.Handle,
-            x,
-            y,
-            width,
-            height,
-            TRUE
-        );
-    }
-
-#endif
-
+    fgStructure.Window->State.NeedToResize = GL_TRUE;
+    fgStructure.Window->State.Width  = width ;
+    fgStructure.Window->State.Height = height;
 }
 
 /*
@@ -980,13 +946,39 @@ void FGAPIENTRY glutFullScreen( void )
         }
     }
 #elif TARGET_HOST_WIN32
-    MoveWindow(
-        fgStructure.Window->Window.Handle,
-        0, 0,
-        fgDisplay.ScreenWidth,
-        fgDisplay.ScreenHeight,
-        TRUE
-    );
+    {
+        RECT rect;
+
+        /* For fullscreen mode, force the top-left corner to 0,0
+         * and adjust the window rectangle so that the client area
+         * covers the whole screen.
+         */
+
+        rect.left   = 0;
+        rect.top    = 0;
+        rect.right  = fgDisplay.ScreenWidth;
+        rect.bottom = fgDisplay.ScreenHeight;
+
+        AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
+                                  WS_CLIPCHILDREN, FALSE );
+
+        /*
+         * SWP_NOACTIVATE     Do not activate the window
+         * SWP_NOOWNERZORDER  Do not change position in z-order
+         * SWP_NOSENDCHANGING Supress WM_WINDOWPOSCHANGING message
+         * SWP_NOZORDER       Retains the current Z order (ignore 2nd param)
+         */
+
+        SetWindowPos( fgStructure.Window->Window.Handle,
+                      HWND_TOP,
+                      rect.left,
+                      rect.top,
+                      rect.right  - rect.left,
+                      rect.bottom - rect.top,
+                      SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
+                      SWP_NOZORDER
+                    );
+    }
 #endif
 }