part of dealing with work is platform independent, so moved it to platform independent part of code
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1615 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
5658b01337
commit
8d979f3c7e
@ -488,45 +488,24 @@ void fgPlatformMainLoopPreliminaryWork ( void )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Step through the work list */
|
/* deal with work list items */
|
||||||
void fgPlatformProcessWork(SFG_Window *window)
|
void fgPlatformInitWork(SFG_Window* window)
|
||||||
{
|
{
|
||||||
unsigned int workMask = window->State.WorkMask;
|
/* notify windowStatus/visibility */
|
||||||
/* Now clear it so that any callback generated by the actions below can set work again */
|
INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );
|
||||||
window->State.WorkMask = 0;
|
|
||||||
|
|
||||||
if (workMask&~GLUT_DISPLAY_WORK) /* Display work is the common case, skip all the below at once */
|
/* Position callback, always at 0,0 */
|
||||||
{
|
fghOnPositionNotify(window, 0, 0, GL_TRUE);
|
||||||
/* 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
|
/* Size gets notified on window creation with size detection in mainloop above
|
||||||
* they are opened, and work is done before displaying in the mainloop.
|
* 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)
|
if (workMask & GLUT_FULL_SCREEN_WORK)
|
||||||
fgPlatformFullScreenToggle( window );
|
fgPlatformFullScreenToggle( window );
|
||||||
if (workMask & GLUT_POSITION_WORK)
|
if (workMask & GLUT_POSITION_WORK)
|
||||||
@ -540,39 +519,29 @@ void fgPlatformProcessWork(SFG_Window *window)
|
|||||||
else
|
else
|
||||||
fgPlatformPopWindow( window );
|
fgPlatformPopWindow( window );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (workMask & GLUT_VISIBILITY_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)
|
||||||
{
|
{
|
||||||
/* Visibility status of window should get updated in the window message handlers
|
case DesireHiddenState:
|
||||||
* For now, none of these functions called below do anything, so don't worry
|
fgPlatformHideWindow( window );
|
||||||
* about it
|
break;
|
||||||
*/
|
case DesireIconicState:
|
||||||
SFG_Window *win = window;
|
/* Call on top-level window */
|
||||||
switch (window->State.DesiredVisibility)
|
while (win->Parent)
|
||||||
{
|
win = win->Parent;
|
||||||
case DesireHiddenState:
|
fgPlatformIconifyWindow( win );
|
||||||
fgPlatformHideWindow( window );
|
break;
|
||||||
break;
|
case DesireNormalState:
|
||||||
case DesireIconicState:
|
fgPlatformShowWindow( window );
|
||||||
/* Call on top-level window */
|
break;
|
||||||
while (win->Parent)
|
|
||||||
win = win->Parent;
|
|
||||||
fgPlatformIconifyWindow( win );
|
|
||||||
break;
|
|
||||||
case DesireNormalState:
|
|
||||||
fgPlatformShowWindow( window );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,9 @@ extern void fgPlatformSleepForEvents( fg_time_t msec );
|
|||||||
extern void fgPlatformProcessSingleEvent ( void );
|
extern void fgPlatformProcessSingleEvent ( void );
|
||||||
extern void fgPlatformMainLoopPreliminaryWork ( 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 ---------------------------------------------------- */
|
/* -- 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 -------------------------------------------------- */
|
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1541,251 +1541,218 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Step through the work list */
|
/* deal with work list items */
|
||||||
void fgPlatformProcessWork(SFG_Window *window)
|
void fgPlatformInitWork(SFG_Window* window)
|
||||||
{
|
{
|
||||||
unsigned int workMask = window->State.WorkMask;
|
RECT windowRect;
|
||||||
/* 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 */
|
/* Notify windowStatus/visibility */
|
||||||
{
|
fghPlatformOnWindowStatusNotify(window, window->State.Visible, GL_TRUE);
|
||||||
/* 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 */
|
/* get and notify window's position */
|
||||||
fghPlatformOnWindowStatusNotify(window, window->State.Visible, GL_TRUE);
|
GetWindowRect(window->Window.Handle,&windowRect);
|
||||||
|
fghOnPositionNotify(window, windowRect.left, windowRect.top, GL_TRUE);
|
||||||
|
|
||||||
/* get and notify window's position */
|
/* get and notify window's size */
|
||||||
GetWindowRect(window->Window.Handle,&windowRect);
|
GetClientRect(window->Window.Handle,&windowRect);
|
||||||
fghOnPositionNotify(window, windowRect.left, windowRect.top, GL_TRUE);
|
fghOnReshapeNotify(window, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/* get and notify window's size */
|
/* On windows we can position, resize and change z order at the same time */
|
||||||
GetClientRect(window->Window.Handle,&windowRect);
|
void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)
|
||||||
fghOnReshapeNotify(window, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, GL_TRUE);
|
{
|
||||||
|
UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER;
|
||||||
/* Call init context callback */
|
HWND insertAfter = HWND_TOP;
|
||||||
INVOKE_WCB( *window, InitContext, ());
|
RECT clientRect;
|
||||||
|
|
||||||
/* 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))
|
|
||||||
{
|
|
||||||
UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER;
|
|
||||||
HWND insertAfter = HWND_TOP;
|
|
||||||
RECT clientRect;
|
|
||||||
|
|
||||||
#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
|
#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */
|
||||||
if (workMask & GLUT_FULL_SCREEN_WORK)
|
if (workMask & GLUT_FULL_SCREEN_WORK)
|
||||||
|
{
|
||||||
|
/* This asks us to toggle fullscreen mode */
|
||||||
|
flags |= SWP_FRAMECHANGED;
|
||||||
|
|
||||||
|
if (window->State.IsFullscreen)
|
||||||
{
|
{
|
||||||
/* This asks us to toggle fullscreen mode */
|
/* If we are fullscreen, resize the current window back to its original size */
|
||||||
flags |= SWP_FRAMECHANGED;
|
/* 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 (window->State.IsFullscreen)
|
/* 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))
|
||||||
{
|
{
|
||||||
/* If we are fullscreen, resize the current window back to its original size */
|
workMask |= GLUT_POSITION_WORK;
|
||||||
/* 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); */
|
window->State.DesiredXpos = window->State.pWState.OldRect.left;
|
||||||
|
window->State.DesiredYpos = window->State.pWState.OldRect.top;
|
||||||
/* 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 */
|
|
||||||
}
|
}
|
||||||
else
|
if (!(workMask & GLUT_SIZE_WORK))
|
||||||
{
|
{
|
||||||
/* we are currently not fullscreen, go to fullscreen:
|
workMask |= GLUT_SIZE_WORK;
|
||||||
* remove window decoration and then maximize
|
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;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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) */
|
#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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 (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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (workMask & GLUT_VISIBILITY_WORK)
|
|
||||||
{
|
{
|
||||||
/* Visibility status of window gets updated in the WM_SHOWWINDOW and WM_SIZE handlers */
|
/* get rect describing window's current position and size,
|
||||||
int cmdShow = 0;
|
* in screen coordinates and in FreeGLUT format
|
||||||
SFG_Window *win = window;
|
* (size (right-left, bottom-top) is client area size, top and left
|
||||||
switch (window->State.DesiredVisibility)
|
* are outside of window including decorations).
|
||||||
|
*/
|
||||||
|
fghGetClientArea( &clientRect, window, TRUE );
|
||||||
|
|
||||||
|
if (workMask & GLUT_POSITION_WORK)
|
||||||
{
|
{
|
||||||
case DesireHiddenState:
|
flags &= ~SWP_NOMOVE;
|
||||||
cmdShow = SW_HIDE;
|
|
||||||
break;
|
/* Move rect so that top-left is at requested position */
|
||||||
case DesireIconicState:
|
/* This also automatically makes sure that child window requested coordinates are relative
|
||||||
cmdShow = SW_MINIMIZE;
|
* to top-left of parent's client area (needed input for SetWindowPos on child windows),
|
||||||
/* Call on top-level window */
|
* so no need to further correct rect for child windows below (childs don't have decorations either).
|
||||||
while (win->Parent)
|
*/
|
||||||
win = win->Parent;
|
OffsetRect(&clientRect,window->State.DesiredXpos-clientRect.left,window->State.DesiredYpos-clientRect.top);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
if (workMask & GLUT_SIZE_WORK)
|
||||||
|
{
|
||||||
|
flags &= ~SWP_NOSIZE;
|
||||||
|
|
||||||
ShowWindow( win->Window.Handle, cmdShow );
|
/* 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workMask & GLUT_DISPLAY_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)
|
||||||
{
|
{
|
||||||
if( window->State.Visible )
|
if (window->State.IsFullscreen)
|
||||||
fghRedrawWindow ( window );
|
{
|
||||||
|
/* leaving fullscreen, restore maximized state, if any */
|
||||||
|
if (window->State.pWState.OldMaximized)
|
||||||
|
SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
|
||||||
|
|
||||||
/* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
|
window->State.IsFullscreen = GL_FALSE;
|
||||||
window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
|
}
|
||||||
|
else
|
||||||
|
window->State.IsFullscreen = GL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
@ -1078,38 +1078,19 @@ void fgPlatformMainLoopPreliminaryWork ( void )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Step through the work list */
|
/* deal with work list items */
|
||||||
void fgPlatformProcessWork(SFG_Window *window)
|
void fgPlatformInitWork(SFG_Window* window)
|
||||||
{
|
{
|
||||||
unsigned int workMask = window->State.WorkMask;
|
/* Notify windowStatus/visibility, position and size get notified on window creation with message handlers above
|
||||||
/* Now clear it so that any callback generated by the actions below can set work again */
|
* XXX CHECK: do the messages happen too early like on windows, so client code cannot have registered
|
||||||
window->State.WorkMask = 0;
|
* a callback yet and the message is thus never received by client?
|
||||||
|
* -> this is a no-op
|
||||||
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)
|
return;
|
||||||
{
|
}
|
||||||
/* 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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)
|
||||||
|
{
|
||||||
if (workMask & GLUT_FULL_SCREEN_WORK)
|
if (workMask & GLUT_FULL_SCREEN_WORK)
|
||||||
fgPlatformFullScreenToggle( window );
|
fgPlatformFullScreenToggle( window );
|
||||||
if (workMask & GLUT_POSITION_WORK)
|
if (workMask & GLUT_POSITION_WORK)
|
||||||
@ -1123,38 +1104,28 @@ void fgPlatformProcessWork(SFG_Window *window)
|
|||||||
else
|
else
|
||||||
fgPlatformPopWindow( window );
|
fgPlatformPopWindow( window );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (workMask & GLUT_VISIBILITY_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)
|
||||||
{
|
{
|
||||||
/* Visibility status of window gets updated in the window message handlers above
|
case DesireHiddenState:
|
||||||
* XXX: is this really the case? check
|
fgPlatformHideWindow( window );
|
||||||
*/
|
break;
|
||||||
SFG_Window *win = window;
|
case DesireIconicState:
|
||||||
switch (window->State.DesiredVisibility)
|
/* Call on top-level window */
|
||||||
{
|
while (win->Parent)
|
||||||
case DesireHiddenState:
|
win = win->Parent;
|
||||||
fgPlatformHideWindow( window );
|
fgPlatformIconifyWindow( win );
|
||||||
break;
|
break;
|
||||||
case DesireIconicState:
|
case DesireNormalState:
|
||||||
/* Call on top-level window */
|
fgPlatformShowWindow( window );
|
||||||
while (win->Parent)
|
break;
|
||||||
win = win->Parent;
|
|
||||||
fgPlatformIconifyWindow( win );
|
|
||||||
break;
|
|
||||||
case DesireNormalState:
|
|
||||||
fgPlatformShowWindow( window );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user