part of dealing with work is platform independent, so moved it to platform independen...
authorDiederick Niehorster <dcnieho@gmail.com>
Sun, 7 Apr 2013 12:21:03 +0000 (12:21 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Sun, 7 Apr 2013 12:21:03 +0000 (12:21 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1615 7f0cb862-5218-0410-a997-914c9d46530a

src/android/fg_main_android.c
src/fg_main.c
src/mswin/fg_main_mswin.c
src/x11/fg_main_x11.c

index 1fa41d6..77e43b3 100644 (file)
@@ -488,45 +488,24 @@ void fgPlatformMainLoopPreliminaryWork ( void )
 }\r
 \r
 \r
-/* Step through the work list */\r
-void fgPlatformProcessWork(SFG_Window *window)\r
+/* deal with work list items */\r
+void fgPlatformInitWork(SFG_Window* window)\r
 {\r
-    unsigned int workMask = window->State.WorkMask;\r
-    /* Now clear it so that any callback generated by the actions below can set work again */\r
-    window->State.WorkMask = 0;\r
+    /* notify windowStatus/visibility */\r
+    INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );\r
 \r
-    if (workMask&~GLUT_DISPLAY_WORK)    /* Display work is the common case, skip all the below at once */\r
-    {\r
-    /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc\r
-     * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when\r
-     * they are opened, and work is done before displaying in the mainloop.\r
+    /* Position callback, always at 0,0 */\r
+    fghOnPositionNotify(window, 0, 0, GL_TRUE);\r
+\r
+    /* Size gets notified on window creation with size detection in mainloop above\r
+     * XXX CHECK: does this messages happen too early like on windows,\r
+     * so client code cannot have registered a callback yet and the message\r
+     * is thus never received by client?\r
      */\r
-    if (workMask & GLUT_INIT_WORK)\r
-    {\r
-        /* notify windowStatus/visibility */\r
-        INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );\r
-\r
-        /* Position callback, always at 0,0 */\r
-        fghOnPositionNotify(window, 0, 0, GL_TRUE);\r
-\r
-        /* Size gets notified on window creation with size detection in mainloop above\r
-         * XXX CHECK: does this messages happen too early like on windows,\r
-         * so client code cannot have registered a callback yet and the message\r
-         * is thus never received by client?\r
-         */\r
-\r
-        /* Call init context callback */\r
-        INVOKE_WCB( *window, InitContext, ());\r
-\r
-        /* Lastly, check if we have a display callback, error out if not\r
-         * This is the right place to do it, as the redisplay will be\r
-         * next right after we exit this function, so there is no more\r
-         * opportunity for the user to register a callback for this window.\r
-         */\r
-        if (!FETCH_WCB(*window, Display))\r
-            fgError ( "ERROR:  No display callback registered for window %d\n", window->ID );\r
-    }\r
+}\r
 \r
+void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)\r
+{\r
     if (workMask & GLUT_FULL_SCREEN_WORK)\r
         fgPlatformFullScreenToggle( window );\r
     if (workMask & GLUT_POSITION_WORK)\r
@@ -540,39 +519,29 @@ void fgPlatformProcessWork(SFG_Window *window)
         else\r
             fgPlatformPopWindow( window );\r
     }\r
+}\r
 \r
-    if (workMask & GLUT_VISIBILITY_WORK)\r
-    {\r
-        /* Visibility status of window should get updated in the window message handlers\r
-         * For now, none of these functions called below do anything, so don't worry\r
-         * about it\r
-         */\r
-        SFG_Window *win = window;\r
-        switch (window->State.DesiredVisibility)\r
-        {\r
-        case DesireHiddenState:\r
-            fgPlatformHideWindow( window );\r
-            break;\r
-        case DesireIconicState:\r
-            /* Call on top-level window */\r
-            while (win->Parent)\r
-                win = win->Parent;\r
-            fgPlatformIconifyWindow( win );\r
-            break;\r
-        case DesireNormalState:\r
-            fgPlatformShowWindow( window );\r
-            break;\r
-        }\r
-    }\r
-    }\r
-\r
-    if (workMask & GLUT_DISPLAY_WORK)\r
+void fgPlatformVisibilityWork(SFG_Window* window)\r
+{\r
+    /* Visibility status of window should get updated in the window message handlers\r
+     * For now, none of these functions called below do anything, so don't worry\r
+     * about it\r
+     */\r
+    SFG_Window *win = window;\r
+    switch (window->State.DesiredVisibility)\r
     {\r
-        if( window->State.Visible )\r
-            fghRedrawWindow ( window );\r
-\r
-        /* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */\r
-        window->State.WorkMask &= ~GLUT_DISPLAY_WORK;\r
+    case DesireHiddenState:\r
+        fgPlatformHideWindow( window );\r
+        break;\r
+    case DesireIconicState:\r
+        /* Call on top-level window */\r
+        while (win->Parent)\r
+            win = win->Parent;\r
+        fgPlatformIconifyWindow( win );\r
+        break;\r
+    case DesireNormalState:\r
+        fgPlatformShowWindow( window );\r
+        break;\r
     }\r
 }\r
 \r
index 4dee9b9..3b32f06 100644 (file)
@@ -60,7 +60,9 @@ extern void fgPlatformSleepForEvents( fg_time_t msec );
 extern void fgPlatformProcessSingleEvent ( void );
 extern void fgPlatformMainLoopPreliminaryWork ( void );
 
-
+extern void fgPlatformInitWork(SFG_Window* window);
+extern void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask);
+extern void fgPlatformVisibilityWork(SFG_Window* window);
 
 
 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
@@ -390,6 +392,57 @@ static void fghSleepForEvents( void )
 }
 
 
+/* Step through the work list */
+void fgPlatformProcessWork(SFG_Window *window)
+{
+    unsigned int workMask = window->State.WorkMask;
+    /* Now clear it so that any callback generated by the actions below can set work again */
+    window->State.WorkMask = 0;
+
+    if (workMask&~GLUT_DISPLAY_WORK)    /* Display work is the common case, skip all the below at once */
+    {
+        if (workMask & GLUT_INIT_WORK)
+        {
+            /* This is before the first display callback: if needed for the platform,
+             * call a few callbacks to inform user of window size, position, etc
+             */
+            fgPlatformInitWork(window);
+
+            /* Call init context callback */
+            INVOKE_WCB( *window, InitContext, ());
+
+            /* Lastly, check if we have a display callback, error out if not
+             * This is the right place to do it, as the redisplay will be
+             * next right after we exit this function, so there is no more
+             * opportunity for the user to register a callback for this window.
+             */
+            if (!FETCH_WCB(*window, Display))
+                fgError ( "ERROR:  No display callback registered for window %d\n", window->ID );
+        }
+
+        /* On windows we can position, resize and change z order at the same time */
+        if (workMask & (GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK|GLUT_FULL_SCREEN_WORK))
+        {
+            fgPlatformPosResZordWork(window,workMask);
+        }
+
+        if (workMask & GLUT_VISIBILITY_WORK)
+        {
+            fgPlatformVisibilityWork(window);
+        }
+    }
+
+    if (workMask & GLUT_DISPLAY_WORK)
+    {
+        if( window->State.Visible )
+            fghRedrawWindow ( window );
+
+        /* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
+        window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
+    }
+}
+
+
 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
 
 /*
index dccb8dd..8162a5f 100644 (file)
@@ -1541,251 +1541,218 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
 }
 
 
-/* Step through the work list */
-void fgPlatformProcessWork(SFG_Window *window)
+/* deal with work list items */
+void fgPlatformInitWork(SFG_Window* window)
 {
-    unsigned int workMask = window->State.WorkMask;
-    /* Now clear it so that any callback generated by the actions below can set work again */
-    window->State.WorkMask = 0;
+    RECT windowRect;
 
-    if (workMask&~GLUT_DISPLAY_WORK)    /* Display work is the common case, skip all the below at once */
-    {
-    /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc
-     * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when
-     * they are opened, and work is done before displaying in the mainloop.
-     */
-    if (workMask & GLUT_INIT_WORK)
-    {
-        RECT windowRect;
-
-        /* Notify windowStatus/visibility */
-        fghPlatformOnWindowStatusNotify(window, window->State.Visible, GL_TRUE);
-
-        /* get and notify window's position */
-        GetWindowRect(window->Window.Handle,&windowRect);
-        fghOnPositionNotify(window, windowRect.left, windowRect.top, GL_TRUE);
+    /* Notify windowStatus/visibility */
+    fghPlatformOnWindowStatusNotify(window, window->State.Visible, GL_TRUE);
 
-        /* get and notify window's size */
-        GetClientRect(window->Window.Handle,&windowRect);
-        fghOnReshapeNotify(window, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, GL_TRUE);
+    /* get and notify window's position */
+    GetWindowRect(window->Window.Handle,&windowRect);
+    fghOnPositionNotify(window, windowRect.left, windowRect.top, GL_TRUE);
 
-        /* Call init context callback */
-        INVOKE_WCB( *window, InitContext, ());
+    /* get and notify window's size */
+    GetClientRect(window->Window.Handle,&windowRect);
+    fghOnReshapeNotify(window, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, GL_TRUE);
+}
 
-        /* Lastly, check if we have a display callback, error out if not
-         * This is the right place to do it, as the redisplay will be
-         * next right after we exit this function, so there is no more
-         * opportunity for the user to register a callback for this window.
-         */
-        if (!FETCH_WCB(*window, Display))
-            fgError ( "ERROR:  No display callback registered for window %d\n", window->ID );
-    }
+/* On windows we can position, resize and change z order at the same time */
+void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)
+{
+    UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER;
+    HWND insertAfter = HWND_TOP;
+    RECT clientRect;
 
-    /* On windows we can position, resize and change z order at the same time */
-    if (workMask & (GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK|GLUT_FULL_SCREEN_WORK))
+#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
+    if (workMask & GLUT_FULL_SCREEN_WORK)
     {
-        UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER;
-        HWND insertAfter = HWND_TOP;
-        RECT clientRect;
+        /* This asks us to toggle fullscreen mode */
+        flags |= SWP_FRAMECHANGED;
 
-#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
-        if (workMask & GLUT_FULL_SCREEN_WORK)
+        if (window->State.IsFullscreen)
         {
-            /* This asks us to toggle fullscreen mode */
-            flags |= SWP_FRAMECHANGED;
-
-            if (window->State.IsFullscreen)
-            {
-                /* If we are fullscreen, resize the current window back to its original size */
-                /* printf("OldRect %i,%i to %i,%i\n",window->State.pWState.OldRect.left,window->State.pWState.OldRect.top,window->State.pWState.OldRect.right,window->State.pWState.OldRect.bottom); */
+            /* If we are fullscreen, resize the current window back to its original size */
+            /* printf("OldRect %i,%i to %i,%i\n",window->State.pWState.OldRect.left,window->State.pWState.OldRect.top,window->State.pWState.OldRect.right,window->State.pWState.OldRect.bottom); */
 
-                /* restore style of window before making it fullscreen */
-                SetWindowLong(window->Window.Handle, GWL_STYLE, window->State.pWState.OldStyle);
-                SetWindowLong(window->Window.Handle, GWL_EXSTYLE, window->State.pWState.OldStyleEx);
+            /* restore style of window before making it fullscreen */
+            SetWindowLong(window->Window.Handle, GWL_STYLE, window->State.pWState.OldStyle);
+            SetWindowLong(window->Window.Handle, GWL_EXSTYLE, window->State.pWState.OldStyleEx);
 
-                /* Then set up resize/reposition, unless user already queued up reshape/position work */
-                if (!(workMask & GLUT_POSITION_WORK))
-                {
-                    workMask |= GLUT_POSITION_WORK;
-                    window->State.DesiredXpos   = window->State.pWState.OldRect.left;
-                    window->State.DesiredYpos   = window->State.pWState.OldRect.top;
-                }
-                if (!(workMask & GLUT_SIZE_WORK))
-                {
-                    workMask |= GLUT_SIZE_WORK;
-                    window->State.DesiredWidth  = window->State.pWState.OldRect.right  - window->State.pWState.OldRect.left;
-                    window->State.DesiredHeight = window->State.pWState.OldRect.bottom - window->State.pWState.OldRect.top;
-                }
-                
-                /* We'll finish off the fullscreen operation below after the other GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK */
+            /* Then set up resize/reposition, unless user already queued up reshape/position work */
+            if (!(workMask & GLUT_POSITION_WORK))
+            {
+                workMask |= GLUT_POSITION_WORK;
+                window->State.DesiredXpos   = window->State.pWState.OldRect.left;
+                window->State.DesiredYpos   = window->State.pWState.OldRect.top;
             }
-            else
+            if (!(workMask & GLUT_SIZE_WORK))
             {
-                /* we are currently not fullscreen, go to fullscreen:
-                 * remove window decoration and then maximize
-                 */
-                RECT rect;
-                HMONITOR hMonitor;
-                MONITORINFO mi;
-        
-                /* save current window rect, style, exstyle and maximized state */
-                window->State.pWState.OldMaximized = !!IsZoomed(window->Window.Handle);
-                if (window->State.pWState.OldMaximized)
-                    /* We force the window into restored mode before going
-                     * fullscreen because Windows doesn't seem to hide the
-                     * taskbar if the window is in the maximized state.
-                     */
-                    SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
-
-                fghGetClientArea( &window->State.pWState.OldRect, window, GL_TRUE );
-                window->State.pWState.OldStyle   = GetWindowLong(window->Window.Handle, GWL_STYLE);
-                window->State.pWState.OldStyleEx = GetWindowLong(window->Window.Handle, GWL_EXSTYLE);
-
-                /* remove decorations from style */
-                SetWindowLong(window->Window.Handle, GWL_STYLE,
-                              window->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME));
-                SetWindowLong(window->Window.Handle, GWL_EXSTYLE,
-                              window->State.pWState.OldStyleEx & ~(WS_EX_DLGMODALFRAME |
-                              WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
-
-                /* For fullscreen mode, find the monitor that is covered the most
-                 * by the window and get its rect as the resize target.
-                    */
-                GetWindowRect(window->Window.Handle, &rect);
-                hMonitor= MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
-                mi.cbSize = sizeof(mi);
-                GetMonitorInfo(hMonitor, &mi);
-                rect = mi.rcMonitor;
-
-                /* then setup window resize, overwriting other work queued on the window */
-                window->State.WorkMask |= GLUT_POSITION_WORK | GLUT_SIZE_WORK;
-                window->State.WorkMask &= ~GLUT_ZORDER_WORK;
-                window->State.DesiredXpos   = rect.left;
-                window->State.DesiredYpos   = rect.top;
-                window->State.DesiredWidth  = rect.right  - rect.left;
-                window->State.DesiredHeight = rect.bottom - rect.top;
+                workMask |= GLUT_SIZE_WORK;
+                window->State.DesiredWidth  = window->State.pWState.OldRect.right  - window->State.pWState.OldRect.left;
+                window->State.DesiredHeight = window->State.pWState.OldRect.bottom - window->State.pWState.OldRect.top;
             }
+                
+            /* We'll finish off the fullscreen operation below after the other GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK */
+        }
+        else
+        {
+            /* we are currently not fullscreen, go to fullscreen:
+                * remove window decoration and then maximize
+                */
+            RECT rect;
+            HMONITOR hMonitor;
+            MONITORINFO mi;
+        
+            /* save current window rect, style, exstyle and maximized state */
+            window->State.pWState.OldMaximized = !!IsZoomed(window->Window.Handle);
+            if (window->State.pWState.OldMaximized)
+                /* We force the window into restored mode before going
+                    * fullscreen because Windows doesn't seem to hide the
+                    * taskbar if the window is in the maximized state.
+                    */
+                SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
+
+            fghGetClientArea( &window->State.pWState.OldRect, window, GL_TRUE );
+            window->State.pWState.OldStyle   = GetWindowLong(window->Window.Handle, GWL_STYLE);
+            window->State.pWState.OldStyleEx = GetWindowLong(window->Window.Handle, GWL_EXSTYLE);
+
+            /* remove decorations from style */
+            SetWindowLong(window->Window.Handle, GWL_STYLE,
+                            window->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME));
+            SetWindowLong(window->Window.Handle, GWL_EXSTYLE,
+                            window->State.pWState.OldStyleEx & ~(WS_EX_DLGMODALFRAME |
+                            WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
+
+            /* For fullscreen mode, find the monitor that is covered the most
+                * by the window and get its rect as the resize target.
+                   */
+            GetWindowRect(window->Window.Handle, &rect);
+            hMonitor= MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
+            mi.cbSize = sizeof(mi);
+            GetMonitorInfo(hMonitor, &mi);
+            rect = mi.rcMonitor;
+
+            /* then setup window resize, overwriting other work queued on the window */
+            window->State.WorkMask |= GLUT_POSITION_WORK | GLUT_SIZE_WORK;
+            window->State.WorkMask &= ~GLUT_ZORDER_WORK;
+            window->State.DesiredXpos   = rect.left;
+            window->State.DesiredYpos   = rect.top;
+            window->State.DesiredWidth  = rect.right  - rect.left;
+            window->State.DesiredHeight = rect.bottom - rect.top;
         }
+    }
 #endif /*!defined(_WIN32_WCE) */
 
-        /* Now deal with normal position, reshape and z order requests (some might have been set when handling GLUT_FULLSCREEN_WORK above */
+    /* Now deal with normal position, reshape and z order requests (some might have been set when handling GLUT_FULLSCREEN_WORK above */
+    {
+        /* get rect describing window's current position and size, 
+            * in screen coordinates and in FreeGLUT format
+            * (size (right-left, bottom-top) is client area size, top and left
+            * are outside of window including decorations).
+            */
+        fghGetClientArea( &clientRect, window, TRUE );
+
+        if (workMask & GLUT_POSITION_WORK)
         {
-            /* get rect describing window's current position and size, 
-             * in screen coordinates and in FreeGLUT format
-             * (size (right-left, bottom-top) is client area size, top and left
-             * are outside of window including decorations).
-             */
-            fghGetClientArea( &clientRect, window, TRUE );
-
-            if (workMask & GLUT_POSITION_WORK)
-            {
-                flags &= ~SWP_NOMOVE;
+            flags &= ~SWP_NOMOVE;
                 
-                /* Move rect so that top-left is at requested position */
-                /* This also automatically makes sure that child window requested coordinates are relative
-                 * to top-left of parent's client area (needed input for SetWindowPos on child windows),
-                 * so no need to further correct rect for child windows below (childs don't have decorations either).
-                 */
-                OffsetRect(&clientRect,window->State.DesiredXpos-clientRect.left,window->State.DesiredYpos-clientRect.top);
-            }
-            if (workMask & GLUT_SIZE_WORK)
-            {
-                flags &= ~SWP_NOSIZE;
+            /* Move rect so that top-left is at requested position */
+            /* This also automatically makes sure that child window requested coordinates are relative
+                * to top-left of parent's client area (needed input for SetWindowPos on child windows),
+                * so no need to further correct rect for child windows below (childs don't have decorations either).
+                */
+            OffsetRect(&clientRect,window->State.DesiredXpos-clientRect.left,window->State.DesiredYpos-clientRect.top);
+        }
+        if (workMask & GLUT_SIZE_WORK)
+        {
+            flags &= ~SWP_NOSIZE;
                 
-                /* Note on maximizing behavior of Windows: the resize borders are off
-                 * the screen such that the client area extends all the way from the
-                 * leftmost corner to the rightmost corner to maximize screen real
-                 * estate. A caption is still shown however to allow interaction with
-                 * the window controls. This is default behavior of Windows that
-                 * FreeGLUT sticks with. To alter, one would have to check if
-                 * WS_MAXIMIZE style is set when a resize event is triggered, and
-                 * then manually correct the windowRect to put the borders back on
-                 * screen.
-                 */
-
-                /* Set new size of window, WxH specify client area */
-                clientRect.right    = clientRect.left + window->State.DesiredWidth;
-                clientRect.bottom   = clientRect.top  + window->State.DesiredHeight;
-            }
-            if (workMask & GLUT_ZORDER_WORK)
-            {
-                flags &= ~SWP_NOZORDER;
-
-                /* Could change this to push it down or up one window at a time with some
-                 * more code using GetWindow with GW_HWNDPREV and GW_HWNDNEXT.
-                 * What would be consistent with X11? Win32 GLUT does what we do here...
-                 */
-                if (window->State.DesiredZOrder < 0)
-                    insertAfter = HWND_BOTTOM;
-            }
+            /* Note on maximizing behavior of Windows: the resize borders are off
+                * the screen such that the client area extends all the way from the
+                * leftmost corner to the rightmost corner to maximize screen real
+                * estate. A caption is still shown however to allow interaction with
+                * the window controls. This is default behavior of Windows that
+                * FreeGLUT sticks with. To alter, one would have to check if
+                * WS_MAXIMIZE style is set when a resize event is triggered, and
+                * then manually correct the windowRect to put the borders back on
+                * screen.
+                */
+
+            /* Set new size of window, WxH specify client area */
+            clientRect.right    = clientRect.left + window->State.DesiredWidth;
+            clientRect.bottom   = clientRect.top  + window->State.DesiredHeight;
         }
-
-        /* Adjust for window decorations
-         * Child windows don't have decoration, so no need to correct
-         */
-        if (!window->Parent)
-            /* get the window rect from this to feed to SetWindowPos, correct for window decorations */
-            fghComputeWindowRectFromClientArea_QueryWindow(&clientRect,window,TRUE);
-    
-        /* Do the requested positioning, moving, and z order push/pop. */
-        SetWindowPos( window->Window.Handle,
-                      insertAfter,
-                      clientRect.left, clientRect.top,
-                      clientRect.right - clientRect.left,
-                      clientRect.bottom- clientRect.top,
-                      flags
-        );
-
-        /* Finish off the fullscreen operation we were doing, if any */
-        if (workMask & GLUT_FULL_SCREEN_WORK)
+        if (workMask & GLUT_ZORDER_WORK)
         {
-            if (window->State.IsFullscreen)
-            {
-                /* leaving fullscreen, restore maximized state, if any */
-                if (window->State.pWState.OldMaximized)
-                    SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
-
-                window->State.IsFullscreen = GL_FALSE;
-            }
-            else
-                window->State.IsFullscreen = GL_TRUE;
+            flags &= ~SWP_NOZORDER;
+
+            /* Could change this to push it down or up one window at a time with some
+                * more code using GetWindow with GW_HWNDPREV and GW_HWNDNEXT.
+                * What would be consistent with X11? Win32 GLUT does what we do here...
+                */
+            if (window->State.DesiredZOrder < 0)
+                insertAfter = HWND_BOTTOM;
         }
     }
 
-    if (workMask & GLUT_VISIBILITY_WORK)
+    /* Adjust for window decorations
+        * Child windows don't have decoration, so no need to correct
+        */
+    if (!window->Parent)
+        /* get the window rect from this to feed to SetWindowPos, correct for window decorations */
+        fghComputeWindowRectFromClientArea_QueryWindow(&clientRect,window,TRUE);
+    
+    /* Do the requested positioning, moving, and z order push/pop. */
+    SetWindowPos( window->Window.Handle,
+                    insertAfter,
+                    clientRect.left, clientRect.top,
+                    clientRect.right - clientRect.left,
+                    clientRect.bottom- clientRect.top,
+                    flags
+    );
+
+    /* Finish off the fullscreen operation we were doing, if any */
+    if (workMask & GLUT_FULL_SCREEN_WORK)
     {
-        /* Visibility status of window gets updated in the WM_SHOWWINDOW and WM_SIZE handlers */
-        int cmdShow = 0;
-        SFG_Window *win = window;
-        switch (window->State.DesiredVisibility)
+        if (window->State.IsFullscreen)
         {
-        case DesireHiddenState:
-            cmdShow = SW_HIDE;
-            break;
-        case DesireIconicState:
-            cmdShow = SW_MINIMIZE;
-            /* Call on top-level window */
-            while (win->Parent)
-                win = win->Parent;
-            break;
-        case DesireNormalState:
-            if (win->IsMenu && (!fgStructure.GameModeWindow || win->ActiveMenu->ParentWindow != fgStructure.GameModeWindow))
-                cmdShow = SW_SHOWNA;    /* Just show, don't activate window if its a menu. Only exception is when the parent is a gamemode window as the menu would pop under it when we do this... */
-            else
-                cmdShow = SW_SHOW;
-            break;
-        }
+            /* leaving fullscreen, restore maximized state, if any */
+            if (window->State.pWState.OldMaximized)
+                SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
 
-        ShowWindow( win->Window.Handle, cmdShow );
-    }
+            window->State.IsFullscreen = GL_FALSE;
+        }
+        else
+            window->State.IsFullscreen = GL_TRUE;
     }
+}
 
-    if (workMask & GLUT_DISPLAY_WORK)
-    {
-        if( window->State.Visible )
-            fghRedrawWindow ( window );
 
-        /* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
-        window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
+void fgPlatformVisibilityWork(SFG_Window* window)
+{
+    /* Visibility status of window gets updated in the WM_SHOWWINDOW and WM_SIZE handlers */
+    int cmdShow = 0;
+    SFG_Window *win = window;
+    switch (window->State.DesiredVisibility)
+    {
+    case DesireHiddenState:
+        cmdShow = SW_HIDE;
+        break;
+    case DesireIconicState:
+        cmdShow = SW_MINIMIZE;
+        /* Call on top-level window */
+        while (win->Parent)
+            win = win->Parent;
+        break;
+    case DesireNormalState:
+        if (win->IsMenu && (!fgStructure.GameModeWindow || win->ActiveMenu->ParentWindow != fgStructure.GameModeWindow))
+            cmdShow = SW_SHOWNA;    /* Just show, don't activate window if its a menu. Only exception is when the parent is a gamemode window as the menu would pop under it when we do this... */
+        else
+            cmdShow = SW_SHOW;
+        break;
     }
+
+    ShowWindow( win->Window.Handle, cmdShow );
 }
\ No newline at end of file
index 897b7ee..20cb37c 100644 (file)
@@ -1078,38 +1078,19 @@ void fgPlatformMainLoopPreliminaryWork ( void )
 }
 
 
-/* Step through the work list */
-void fgPlatformProcessWork(SFG_Window *window)
+/* deal with work list items */
+void fgPlatformInitWork(SFG_Window* window)
 {
-    unsigned int workMask = window->State.WorkMask;
-    /* Now clear it so that any callback generated by the actions below can set work again */
-    window->State.WorkMask = 0;
-
-    if (workMask&~GLUT_DISPLAY_WORK)    /* Display work is the common case, skip all the below at once */
-    {    
-    /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc
-     * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when
-     * they are opened, and work is done before displaying in the mainloop.
+    /* Notify windowStatus/visibility, position and size get notified on window creation with message handlers above 
+     * XXX CHECK: do the messages happen too early like on windows, so client code cannot have registered
+     * a callback yet and the message is thus never received by client?
+     * -> this is a no-op
      */
-    if (workMask & GLUT_INIT_WORK)
-    {
-        /* Notify windowStatus/visibility, position and size get notified on window creation with message handlers above 
-         * XXX CHECK: do the messages happen too early like on windows, so client code cannot have registered
-         * a callback yet and the message is thus never received by client?
-         */
-
-        /* Call init context callback */
-        INVOKE_WCB( *window, InitContext, ());
-
-        /* Lastly, check if we have a display callback, error out if not
-         * This is the right place to do it, as the redisplay will be
-         * next right after we exit this function, so there is no more
-         * opportunity for the user to register a callback for this window.
-         */
-        if (!FETCH_WCB(*window, Display))
-            fgError ( "ERROR:  No display callback registered for window %d\n", window->ID );
-    }
+     return;
+}
 
+void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)
+{
     if (workMask & GLUT_FULL_SCREEN_WORK)
         fgPlatformFullScreenToggle( window );
     if (workMask & GLUT_POSITION_WORK)
@@ -1123,38 +1104,28 @@ void fgPlatformProcessWork(SFG_Window *window)
         else
             fgPlatformPopWindow( window );
     }
+}
 
-    if (workMask & GLUT_VISIBILITY_WORK)
-    {
-        /* Visibility status of window gets updated in the window message handlers above 
-         * XXX: is this really the case? check
-         */
-        SFG_Window *win = window;
-        switch (window->State.DesiredVisibility)
-        {
-        case DesireHiddenState:
-            fgPlatformHideWindow( window );
-            break;
-        case DesireIconicState:
-            /* Call on top-level window */
-            while (win->Parent)
-                win = win->Parent;
-            fgPlatformIconifyWindow( win );
-            break;
-        case DesireNormalState:
-            fgPlatformShowWindow( window );
-            break;
-        }
-    }
-    }
-
-    if (workMask & GLUT_DISPLAY_WORK)
+void fgPlatformVisibilityWork(SFG_Window* window)
+{
+    /* Visibility status of window gets updated in the window message handlers above 
+     * XXX: is this really the case? check
+     */
+    SFG_Window *win = window;
+    switch (window->State.DesiredVisibility)
     {
-        if( window->State.Visible )
-            fghRedrawWindow ( window );
-
-        /* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
-        window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
+    case DesireHiddenState:
+        fgPlatformHideWindow( window );
+        break;
+    case DesireIconicState:
+        /* Call on top-level window */
+        while (win->Parent)
+            win = win->Parent;
+        fgPlatformIconifyWindow( win );
+        break;
+    case DesireNormalState:
+        fgPlatformShowWindow( window );
+        break;
     }
 }