Tidy nested if/else to suppress gcc -Wall -pedantic noise
[freeglut] / src / freeglut_main.c
index 95efa18..6375448 100644 (file)
@@ -87,45 +87,56 @@ static void fghReshapeWindowByHandle ( SFG_WindowHandleType handle,
 #elif TARGET_HOST_WIN32
 
     {
-        RECT winRect;
-        int x, y;
+        RECT rect;
 
-        GetWindowRect( window->Window.Handle, &winRect );
-        x = winRect.left;
-        y = winRect.top;
+        /*
+         * For windowed mode, get the current position of the
+         * window and resize taking the size of the frame
+         * decorations into account.
+         */
+
+        GetWindowRect( window->Window.Handle, &rect );
+        rect.right  = rect.left + width;
+        rect.bottom = rect.top  + height;
 
         if ( window->Parent == NULL )
         {
-            /*
-             * Adjust the size of the window to allow for the size of the
-             * frame, if we are not a menu
-             */
-            if ( ! window->IsMenu )
+            if ( ! window->IsMenu && !window->State.IsGameMode )
             {
-                width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
-                height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
-                    GetSystemMetrics( SM_CYCAPTION );
+                rect.right  += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
+                rect.bottom += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
+                               GetSystemMetrics( SM_CYCAPTION );
             }
         }
         else
         {
-            GetWindowRect( window->Parent->Window.Handle,
-                           &winRect );
-            x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME );
-            y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) +
-                GetSystemMetrics( SM_CYCAPTION );
+            GetWindowRect( window->Parent->Window.Handle, &rect );
+            AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
+                                      WS_CLIPCHILDREN, FALSE );
         }
 
-        MoveWindow(
-            window->Window.Handle,
-            x,
-            y,
-            width,
-            height,
-            TRUE
+        /*
+         * 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( 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
         );
     }
 
+    /*
+     * XXX Should update {window->State.OldWidth, window->State.OldHeight}
+     * XXX to keep in lockstep with UNIX_X11 code.
+     */
     if( FETCH_WCB( *window, Reshape ) )
         INVOKE_WCB( *window, Reshape, ( width, height ) );
     else
@@ -188,40 +199,25 @@ static void fghRedrawWindowByHandle ( SFG_WindowHandleType handle )
 static void fghcbDisplayWindow( SFG_Window *window,
                                 SFG_Enumerator *enumerator )
 {
+    if( window->State.NeedToResize )
+    {
+        SFG_Window *current_window = fgStructure.Window;
+        
+        fgSetWindow( window );
+        
+        fghReshapeWindowByHandle( 
+            window->Window.Handle,
+            window->State.Width,
+            window->State.Height
+        );
+        
+        window->State.NeedToResize = GL_FALSE;
+        fgSetWindow( current_window );
+    }
+
     if( window->State.Redisplay &&
         window->State.Visible )
     {
-        /*
-         * XXX Resizing should *not* depend upon whether there
-         * XXX is a pending redisplay flag, as far as I can tell.
-         * XXX
-         * XXX Note, too, that the {NeedToResize} flag is a little
-         * XXX fuzzy in its meaning, since for WIN32, this also
-         * XXX means "we need to tell the application that the window has
-         * XXX changed size", while in X11, it only means "we need
-         * XXX to ask the window system to resize the window.
-         * XXX Splitting the flag's meaning might be desirable, but
-         * XXX that could complicate the code more.  (On X11, the
-         * XXX user callback is called as soon as the event is
-         * XXX discovered, but resizing the window is postponed
-         * XXX until after other events.)
-         */
-        if( window->State.NeedToResize )
-        {
-            SFG_Window *current_window = fgStructure.Window;
-
-            fgSetWindow( window );
-
-            fghReshapeWindowByHandle( 
-                window->Window.Handle,
-                window->State.Width,
-                window->State.Height
-            );
-
-            window->State.NeedToResize = GL_FALSE;
-            fgSetWindow ( current_window );
-        }
-
         window->State.Redisplay = GL_FALSE;
 
 #if TARGET_HOST_UNIX_X11
@@ -292,10 +288,11 @@ static void fghCheckJoystickPolls( void )
 static void fghCheckTimers( void )
 {
     long checkTime = fgElapsedTime( );
-    SFG_Timer *timer;
 
-    while( timer = fgState.Timers.First )
+    while( fgState.Timers.First )
     {
+        SFG_Timer *timer = fgState.Timers.First;
+
         if( timer->TriggerTime > checkTime )
             break;
 
@@ -561,6 +558,13 @@ void FGAPIENTRY glutMainLoopEvent( void )
              *
              * GLUT presumably does this because it generally tries to treat
              * sub-windows the same as windows.
+             *
+             * XXX Technically, GETWINDOW( xconfigure ) and
+             * XXX {event.xconfigure} may not be legit ways to get at
+             * XXX data for CreateNotify events.  In practice, the data
+             * XXX is in a union which is laid out much the same either
+             * XXX way.  But if you want to split hairs, this isn't legit,
+             * XXX and we should instead duplicate some code.
              */
         case CreateNotify:
         case ConfigureNotify:
@@ -597,10 +601,15 @@ void FGAPIENTRY glutMainLoopEvent( void )
         case Expose:
             /*
              * We are too dumb to process partial exposes...
+             *
              * XXX Well, we could do it.  However, it seems to only
              * XXX be potentially useful for single-buffered (since
              * XXX double-buffered does not respect viewport when we
              * XXX do a buffer-swap).
+             *
+             * XXX GETWINDOW( xexpose );
+             * XXX fgSetWindow( window );
+             * XXX glutPostRedisplay( );
              */
             if( event.xexpose.count == 0 )
                 fghRedrawWindowByHandle( event.xexpose.window );
@@ -625,6 +634,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
         case VisibilityNotify:
         {
             GETWINDOW( xvisibility ); 
+            /*
+             * XXX INVOKE_WCB() does this check for us.
+             */
             if( ! FETCH_WCB( *window, WindowStatus ) )
                 break;
             fgSetWindow( window );
@@ -692,7 +704,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
 
             /*
              * XXX For more than 5 buttons, just check {event.xmotion.state},
-             * XXX rather than a host of bit-masks?
+             * XXX rather than a host of bit-masks?  Or maybe we need to
+             * XXX track ButtonPress/ButtonRelease events in our own
+             * XXX bit-mask?
              */
 #define BUTTON_MASK \
   ( Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
@@ -762,7 +776,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
                     window->ActiveMenu->Window->State.MouseY =
                         event.xbutton.y_root - window->ActiveMenu->Y;
                 }
-              
+                
                 /* In the menu, invoke the callback and deactivate the menu*/
                 if( fgCheckActiveMenu( window->ActiveMenu->Window,
                                        window->ActiveMenu ) )
@@ -789,12 +803,19 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 else if( pressed )
                     /*
                      * Outside the menu, deactivate if it's a downclick
+                     *
                      * XXX This isn't enough.  A downclick outside of
                      * XXX the interior of our freeglut windows should also
                      * XXX deactivate the menu.  This is more complicated.
                      */
                     fgDeactivateMenu( window->ActiveMenu->ParentWindow );
-              
+
+                /*
+                 * XXX Why does an active menu require a redisplay at
+                 * XXX this point?  If this can come out cleanly, then
+                 * XXX it probably should do so; if not, a comment should
+                 * XXX explain it.
+                 */
                 window->State.Redisplay = GL_TRUE;
                 break;
             }
@@ -807,6 +828,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 ( window->Menu[ button ] ) &&
                 pressed )
             {
+                /*
+                 * XXX Posting a requisite Redisplay seems bogus.
+                 */
                 window->State.Redisplay = GL_TRUE;
                 fgSetWindow( window );
                 fgActivateMenu( window, button );
@@ -826,7 +850,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
             /*
              * Finally execute the mouse or mouse wheel callback
              *
-             * XXX Use a symbolic constant, *not* "4"!
+             * XXX Use a symbolic constant, *not* "4"!  ("3, sire!")
              */
             if( ( button < 3 ) || ( ! FETCH_WCB( *window, MouseWheel ) ) )
                 INVOKE_WCB( *window, Mouse, ( button,
@@ -1057,16 +1081,27 @@ void FGAPIENTRY glutMainLoop( void )
     fgState.ExecState = GLUT_EXEC_STATE_RUNNING ;
     while( fgState.ExecState == GLUT_EXEC_STATE_RUNNING )
     {
-        glutMainLoopEvent( );
+        SFG_Window *window;
 
-        if( fgStructure.Windows.First == NULL )
+        glutMainLoopEvent( );
+        /*
+         * Step through the list of windows, seeing if there are any
+         * that are not menus
+         */ 
+        for( window = ( SFG_Window * )fgStructure.Windows.First;
+             window;
+             window = ( SFG_Window * )window->Node.Next )
+            if ( ! ( window->IsMenu ) )
+                break;
+        
+        if( ! window )
             fgState.ExecState = GLUT_EXEC_STATE_STOP;
         else
         {
             if( fgState.IdleCallback )
                 fgState.IdleCallback( );
 
-            fgSleepForEvents();
+            fgSleepForEvents( );
         }
     }
 
@@ -1075,6 +1110,8 @@ void FGAPIENTRY glutMainLoop( void )
      * of a freeglut session, so that another glutInit() call can happen
      */
     fgDeinitialize( );
+    if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT )
+        exit( 0 );
 }
 
 /*
@@ -1340,11 +1377,14 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
         }
 
-        if( GetSystemMetrics( SM_SWAPBUTTON ) )
-            if( button == GLUT_LEFT_BUTTON )
+        if ( GetSystemMetrics( SM_SWAPBUTTON ) )
+        {
+            if ( button == GLUT_LEFT_BUTTON )
                 button = GLUT_RIGHT_BUTTON;
-            else if( button == GLUT_RIGHT_BUTTON )
+            else
+                if ( button == GLUT_RIGHT_BUTTON )
                 button = GLUT_LEFT_BUTTON;
+        }
 
         if( button == -1 )
             return DefWindowProc( hWnd, uMsg, lParam, wParam );
@@ -1409,7 +1449,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
         }
 
-        if ( window->Menu[ button ] && pressed )
+        if( window->Menu[ button ] && pressed )
         {
             window->State.Redisplay = GL_TRUE;
             fgSetWindow( window );