}\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
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
}
-/* 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