From: Diederick Niehorster Date: Sun, 7 Apr 2013 12:21:03 +0000 (+0000) Subject: part of dealing with work is platform independent, so moved it to platform independen... X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=c2de6d3474dc0c697fa0d5c9fd84988896a077ef;p=freeglut part of dealing with work is platform independent, so moved it to platform independent part of code git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1615 7f0cb862-5218-0410-a997-914c9d46530a --- diff --git a/src/android/fg_main_android.c b/src/android/fg_main_android.c index 1fa41d6..77e43b3 100644 --- a/src/android/fg_main_android.c +++ b/src/android/fg_main_android.c @@ -488,45 +488,24 @@ 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; + /* notify windowStatus/visibility */ + INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) ); - 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. + /* Position callback, always at 0,0 */ + fghOnPositionNotify(window, 0, 0, GL_TRUE); + + /* Size gets notified on window creation with size detection in mainloop above + * XXX CHECK: does this 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? */ - if (workMask & GLUT_INIT_WORK) - { - /* notify windowStatus/visibility */ - INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) ); - - /* Position callback, always at 0,0 */ - fghOnPositionNotify(window, 0, 0, GL_TRUE); - - /* Size gets notified on window creation with size detection in mainloop above - * XXX CHECK: does this 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 ); - } +} +void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) +{ if (workMask & GLUT_FULL_SCREEN_WORK) fgPlatformFullScreenToggle( window ); if (workMask & GLUT_POSITION_WORK) @@ -540,39 +519,29 @@ void fgPlatformProcessWork(SFG_Window *window) else fgPlatformPopWindow( window ); } +} - if (workMask & GLUT_VISIBILITY_WORK) - { - /* Visibility status of window should get updated in the window message handlers - * For now, none of these functions called below do anything, so don't worry - * about it - */ - 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 should get updated in the window message handlers + * For now, none of these functions called below do anything, so don't worry + * about it + */ + 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; } } diff --git a/src/fg_main.c b/src/fg_main.c index 4dee9b9..3b32f06 100644 --- a/src/fg_main.c +++ b/src/fg_main.c @@ -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 -------------------------------------------------- */ /* diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index dccb8dd..8162a5f 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -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 diff --git a/src/x11/fg_main_x11.c b/src/x11/fg_main_x11.c index 897b7ee..20cb37c 100644 --- a/src/x11/fg_main_x11.c +++ b/src/x11/fg_main_x11.c @@ -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; } }