Putting in Diederick Niehorster's fullstreen patch per e-mail from him dated 6/9/2011, updated 9/4/2011 with modified patch.

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@929 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
fayjf 2011-09-04 19:38:32 +00:00
parent 42235dfaa1
commit cf91891cf8
8 changed files with 438 additions and 179 deletions

View File

@ -127,6 +127,7 @@ FGAPI void FGAPIENTRY glutExit ( void );
* Window management functions, see freeglut_window.c
*/
FGAPI void FGAPIENTRY glutFullScreenToggle( void );
FGAPI void FGAPIENTRY glutLeaveFullScreen( void );
/*
* Window-specific callback functions, see freeglut_callbacks.c

View File

@ -166,6 +166,7 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
CHECK_NAME(glutWMCloseFunc);
CHECK_NAME(glutMenuDestroyFunc);
CHECK_NAME(glutFullScreenToggle);
CHECK_NAME(glutLeaveFullScreen);
CHECK_NAME(glutSetOption);
CHECK_NAME(glutGetModeValues);
CHECK_NAME(glutSetWindowData);

View File

@ -449,10 +449,16 @@ struct tagSFG_Context
typedef struct tagSFG_WindowState SFG_WindowState;
struct tagSFG_WindowState
{
/* Note that on Windows, sizes always refer to the client area, thus without the window decorations */
int Width; /* Window's width in pixels */
int Height; /* The same about the height */
#if TARGET_HOST_POSIX_X11
int OldWidth; /* Window width from before a resize */
int OldHeight; /* " height " " " " */
#elif TARGET_HOST_MS_WINDOWS
RECT OldRect; /* window rect - stored before the window is made fullscreen */
DWORD OldStyle; /* window style - stored before the window is made fullscreen */
#endif
GLboolean Redisplay; /* Do we have to redisplay? */
GLboolean Visible; /* Is the window visible now */
@ -926,6 +932,17 @@ void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator );
void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback,
SFG_Enumerator* enumerator );
/*
* Helper functions for getting client area from the window rect
* and the window rect from the client area given the style of the window
* (or a valid window pointer from which the style can be queried).
*/
void fghComputeWindowRectFromClientArea_UseStyle ( const DWORD windowStyle , RECT *clientRect, BOOL posIsOutside );
void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside );
void fghComputeClientAreaFromWindowRect ( const SFG_Window *window, RECT *windowRect, BOOL wantPosOutside );
RECT fghGetClientArea ( const SFG_Window *window, BOOL wantPosOutside );
void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
/*
* fgWindowByHandle returns a (SFG_Window *) value pointing to the
* first window in the queue matching the specified window handle.

View File

@ -109,8 +109,7 @@ static void fghReshapeWindow ( SFG_Window *window, int width, int height )
#elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)
{
RECT winRect;
int x, y, w, h;
RECT windowRect;
/*
* For windowed mode, get the current position of the
@ -119,51 +118,43 @@ static void fghReshapeWindow ( SFG_Window *window, int width, int height )
*/
/* "GetWindowRect" returns the pixel coordinates of the outside of the window */
GetWindowRect( window->Window.Handle, &winRect );
x = winRect.left;
y = winRect.top;
w = width;
h = height;
GetWindowRect( window->Window.Handle, &windowRect );
if ( window->Parent == NULL )
{
if ( ! window->IsMenu && (window != fgStructure.GameModeWindow) &&
!( fgState.DisplayMode & GLUT_BORDERLESS ))
{
w += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
h += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
GetSystemMetrics( SM_CYCAPTION );
}
}
/* Create rect in FreeGLUT format, (X,Y) topleft outside window, WxH of client area */
windowRect.right = windowRect.left+width;
windowRect.bottom = windowRect.top+height;
if (window->Parent == NULL)
/* get the window rect from this to feed to SetWindowPos, correct for window decorations */
fghComputeWindowRectFromClientArea_QueryWindow(window,&windowRect,TRUE);
else
{
/* correct rect for position client area of parent window
* (SetWindowPos input for child windows is in coordinates
* relative to the parent's client area).
* Child windows don't have decoration, so no need to correct
* for them.
*/
RECT parentRect;
GetWindowRect( window->Parent->Window.Handle, &parentRect );
x -= parentRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
y -= parentRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
GetSystemMetrics( SM_CYCAPTION );
parentRect = fghGetClientArea( window->Parent, FALSE );
windowRect.left -= parentRect.left;
windowRect.right -= parentRect.left;
windowRect.top -= parentRect.top;
windowRect.bottom -= parentRect.top;
}
/*
* SWP_NOACTIVATE Do not activate the window
* SWP_NOOWNERZORDER Do not change position in z-order
* SWP_NOSENDCHANGING Supress WM_WINDOWPOSCHANGING message
* SWP_NOZORDER Retains the current Z order (ignore 2nd param)
*/
/* Do the actual resizing */
SetWindowPos( window->Window.Handle,
HWND_TOP,
x, y, w, h,
windowRect.left, windowRect.top,
windowRect.right - windowRect.left,
windowRect.bottom- windowRect.top,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
SWP_NOZORDER
);
}
#endif
/*
* XXX Should update {window->State.OldWidth, window->State.OldHeight}
* XXX to keep in lockstep with POSIX_X11 code.
*/
if( FETCH_WCB( *window, Reshape ) )
INVOKE_WCB( *window, Reshape, ( width, height ) );
else

View File

@ -64,16 +64,6 @@ static int fghGetConfig( int attribute )
}
#endif
/* Check if the window is in full screen state. */
static int fghCheckFullScreen(void)
{
#if TARGET_HOST_POSIX_X11
return fgStructure.CurrentWindow->State.IsFullscreen;
#else
return 0;
#endif
}
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
@ -458,25 +448,11 @@ int FGAPIENTRY glutGet( GLenum eWhat )
freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
/*
* We need to call GetWindowRect() first...
* (this returns the pixel coordinates of the outside of the window)
*/
#if defined(_WIN32_WCE)
GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
/* ...then we've got to correct the results we've just received... */
#if !defined(_WIN32_WCE)
if ( ( fgStructure.GameModeWindow != fgStructure.CurrentWindow ) && ( fgStructure.CurrentWindow->Parent == NULL ) &&
( ! fgStructure.CurrentWindow->IsMenu ) &&
!( fgState.DisplayMode & GLUT_BORDERLESS ))
{
winRect.left += GetSystemMetrics( SM_CXSIZEFRAME );
winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME );
winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
}
#endif /* !defined(_WIN32_WCE) */
#else
winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);
#endif /* defined(_WIN32_WCE) */
switch( eWhat )
{
@ -489,21 +465,32 @@ int FGAPIENTRY glutGet( GLenum eWhat )
break;
case GLUT_WINDOW_BORDER_WIDTH :
#if defined(_WIN32_WCE)
return 0;
#else
if ( fgState.DisplayMode & GLUT_BORDERLESS )
return 0;
return GetSystemMetrics( SM_CXSIZEFRAME );
#endif /* !defined(_WIN32_WCE) */
case GLUT_WINDOW_HEADER_HEIGHT :
#if defined(_WIN32_WCE)
return 0;
#else
if ( fgState.DisplayMode & GLUT_BORDERLESS )
return 0;
return GetSystemMetrics( SM_CYCAPTION );
{
DWORD windowStyle;
if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)
windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);
else
/* If no window, return sizes for a default window with title bar and border */
windowStyle = WS_OVERLAPPEDWINDOW;
switch( eWhat )
{
case GLUT_WINDOW_BORDER_WIDTH:
{
int xBorderWidth, yBorderWidth;
fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
return xBorderWidth;
}
case GLUT_WINDOW_HEADER_HEIGHT:
/* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0;
}
}
#endif /* defined(_WIN32_WCE) */
case GLUT_DISPLAY_MODE_POSSIBLE:
@ -559,7 +546,7 @@ int FGAPIENTRY glutGet( GLenum eWhat )
return fgState.DirectContext;
case GLUT_FULL_SCREEN:
return fghCheckFullScreen();
return fgStructure.CurrentWindow->State.IsFullscreen;
case GLUT_AUX:
return fgState.AuxiliaryBufferNumber;

View File

@ -79,7 +79,9 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
/* Initialize the object properties */
window->ID = ++fgStructure.WindowID;
#if TARGET_HOST_POSIX_X11
window->State.OldHeight = window->State.OldWidth = -1;
#endif
fgListInit( &window->Children );
if( parent )

View File

@ -850,12 +850,167 @@ void fgSetWindow ( SFG_Window *window )
#if TARGET_HOST_MS_WINDOWS
/* Computes position of corners of window Rect (outer position including
* decorations) based on the provided client rect and based on the style
* of the window in question.
* If posIsOutside is set to true, the input client Rect is taken to follow
* freeGLUT's window specification convention in which the top-left corner
* is at the outside of the window, while the size
* (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
* area.
*/
void fghComputeWindowRectFromClientArea_UseStyle( const DWORD windowStyle, RECT *clientRect, BOOL posIsOutside )
{
int xBorderWidth = 0, yBorderWidth = 0;
/* If window has title bar, correct rect for it */
if (windowStyle & WS_MAXIMIZEBOX) /* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
if (posIsOutside)
clientRect->bottom += GetSystemMetrics( SM_CYCAPTION );
else
clientRect->top -= GetSystemMetrics( SM_CYCAPTION );
/* get width of window's borders (frame), correct rect for it.
* Note, borders can be of zero width if style does not specify borders
*/
fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
if (posIsOutside)
{
clientRect->right += xBorderWidth * 2;
clientRect->bottom += yBorderWidth * 2;
}
else
{
clientRect->left -= xBorderWidth;
clientRect->right += xBorderWidth;
clientRect->top -= yBorderWidth;
clientRect->bottom += yBorderWidth;
}
}
/* Computes position of corners of window Rect (outer position including
* decorations) based on the provided client rect and based on the style
* of the window in question. If the window pointer or the window handle
* is NULL, a fully decorated window (caption and border) is assumed.
* Furthermore, if posIsOutside is set to true, the input client Rect is
* taken to follow freeGLUT's window specification convention in which the
* top-left corner is at the outside of the window, while the size
* (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
* area.
*/
void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside )
{
DWORD windowStyle = 0;
if (window && window->Window.Handle)
windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
else
windowStyle = WS_OVERLAPPEDWINDOW;
fghComputeWindowRectFromClientArea_UseStyle(windowStyle, clientRect, posIsOutside);
}
/* Computes position of corners of client area (drawable area) of a window
* based on the provided window Rect (outer position including decorations)
* and based on the style of the window in question. If the window pointer
* or the window handle is NULL, a fully decorated window (caption and
* border) is assumed.
* Furthermore, if wantPosOutside is set to true, the output client Rect
* will follow freeGLUT's window specification convention in which the
* top-left corner is at the outside of the window, the size
* (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
* area.
*/
void fghComputeClientAreaFromWindowRect( const SFG_Window *window, RECT *windowRect, BOOL wantPosOutside )
{
DWORD windowStyle = 0;
int xBorderWidth = 0, yBorderWidth = 0;
if (window && window->Window.Handle)
windowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
else
windowStyle = WS_OVERLAPPEDWINDOW;
/* If window has title bar, correct rect for it */
if (windowStyle & WS_MAXIMIZEBOX) /* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
if (wantPosOutside)
windowRect->bottom -= GetSystemMetrics( SM_CYCAPTION );
else
windowRect->top += GetSystemMetrics( SM_CYCAPTION );
/* get width of window's borders (frame), correct rect for it.
* Note, borders can be of zero width if style does not specify borders
*/
fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
if (wantPosOutside)
{
windowRect->right -= xBorderWidth * 2;
windowRect->bottom -= yBorderWidth * 2;
}
else
{
windowRect->left += xBorderWidth;
windowRect->right -= xBorderWidth;
windowRect->top += yBorderWidth;
windowRect->bottom -= yBorderWidth;
}
}
/* Gets the rect describing the client area (drawable area) of the
* specified window.
* Returns an empty rect if window pointer or window handle is NULL.
* If wantPosOutside is set to true, the output client Rect
* will follow freeGLUT's window specification convention in which the
* top-left corner is at the outside of the window, while the size
* (rect.right-rect.left,rect.bottom-rect.top) is the size of the drawable
* area.
*/
RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside )
{
RECT windowRect = {0,0,0,0};
freeglut_return_val_if_fail((window && window->Window.Handle),windowRect);
/*
* call GetWindowRect()
* (this returns the pixel coordinates of the outside of the window)
*/
GetWindowRect( window->Window.Handle, &windowRect );
/* Then correct the results */
fghComputeClientAreaFromWindowRect(window, &windowRect, wantPosOutside);
return windowRect;
}
/* Returns the width of the window borders based on the window's style.
*/
void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth)
{
if (windowStyle & WS_THICKFRAME)
{
*xBorderWidth = GetSystemMetrics(SM_CXSIZEFRAME);
*yBorderWidth = GetSystemMetrics(SM_CYSIZEFRAME);
}
else if (windowStyle & WS_DLGFRAME)
{
*xBorderWidth = GetSystemMetrics(SM_CXFIXEDFRAME);
*yBorderWidth = GetSystemMetrics(SM_CYFIXEDFRAME);
}
else
{
*xBorderWidth = 0;
*yBorderWidth = 0;
}
}
#if(WINVER >= 0x500)
typedef struct {
typedef struct
{
int *x;
int *y;
const char *name;
}m_proc_t ;
} m_proc_t;
static BOOL CALLBACK m_proc(HMONITOR mon,
HDC hdc,
@ -869,7 +1024,7 @@ static BOOL CALLBACK m_proc(HMONITOR mon,
res=GetMonitorInfo(mon,(LPMONITORINFO)&info);
if( res )
{
if( !strcmp(dp->name,info.szDevice) )
if( strcmp(dp->name,info.szDevice)==0 )
{
*(dp->x)=info.rcMonitor.left;
*(dp->y)=info.rcMonitor.top;
@ -880,13 +1035,18 @@ static BOOL CALLBACK m_proc(HMONITOR mon,
}
/*
* this function is only used in fgOpenWindow. Currently it only sets
* its output parameters, if the DisplayName is set in fgDisplay
* (and if it is able to recognize the display)
* this function returns the origin of the screen identified by
* fgDisplay.DisplayName, and 0 otherwise.
* This is used in fgOpenWindow to open the gamemode window on the screen
* identified by the -display command line argument. The function should
* not be called otherwise.
*/
static void get_display_origin(int *xp,int *yp)
{
*xp = 0;
*yp = 0;
if( fgDisplay.DisplayName )
{
m_proc_t st;
@ -901,6 +1061,9 @@ static void get_display_origin(int *xp,int *yp)
static void get_display_origin(int *xp,int *yp)
{
*xp = 0;
*yp = 0;
if( fgDisplay.DisplayName )
{
fgWarning( "for working -display support FreeGLUT must be compiled with WINVER >= 0x0500");
@ -1139,16 +1302,16 @@ void fgOpenWindow( SFG_Window* window, const char* title,
#elif TARGET_HOST_MS_WINDOWS
WNDCLASS wc;
DWORD flags;
DWORD flags = 0;
DWORD exFlags = 0;
ATOM atom;
int WindowStyle = 0;
/* Grab the window class we have registered on glutInit(): */
atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found",
"fgOpenWindow" );
/* Determine window style flags*/
if( gameMode )
{
FREEGLUT_INTERNAL_ERROR_EXIT ( window->Parent == NULL,
@ -1163,29 +1326,63 @@ void fgOpenWindow( SFG_Window* window, const char* title,
}
else
{
int worig = w, horig = h;
flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
#if !defined(_WIN32_WCE)
if ( ( ! isSubWindow ) && ( ! window->IsMenu ) )
{
/*
* Update the window dimensions, taking account of window
* decorations. "freeglut" is to create the window with the
* outside of its border at (x,y) and with dimensions (w,h).
* There's a small difference between creating the top, child and
* menu windows
*/
w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2;
h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 +
GetSystemMetrics( SM_CYCAPTION );
if ( window->IsMenu )
{
flags |= WS_POPUP;
exFlags |= WS_EX_TOOLWINDOW;
}
#if defined(_WIN32_WCE)
/* no decorations for windows CE */
#else
/* if this is not a subwindow (child), set its style based on the requested display mode */
else if( window->Parent == NULL )
if ( fgState.DisplayMode & GLUT_BORDERLESS )
{
/* no window decorations needed */
}
else if ( fgState.DisplayMode & GLUT_CAPTIONLESS )
/* only window decoration is a border, no title bar or buttons */
flags |= WS_DLGFRAME;
else
/* window decoration are a border, title bar and buttons.
* NB: we later query whether the window has a title bar or
* not by testing for the maximize button, as the test for
* WS_CAPTION can be true without the window having a title
* bar. This style WS_OVERLAPPEDWINDOW gives you a maximize
* button. */
flags |= WS_OVERLAPPEDWINDOW;
#endif
else
/* subwindows always have no decoration, but are marked as a child window to the OS */
flags |= WS_CHILD;
}
#endif /* defined(_WIN32_WCE) */
if( ! positionUse )
/* determine window size and position */
if( gameMode )
{
/* if in gamemode, query the origin of specified by the -display
* parameter command line (if any) and offset the upper-left corner
* of the window so we create the window on that screen.
* The -display argument doesn't do anything if not trying to enter
* gamemode.
*/
int xoff=0, yoff=0;
get_display_origin(&xoff,&yoff);
x += xoff;
y += yoff;
}
if( !positionUse )
{
x = CW_USEDEFAULT;
y = CW_USEDEFAULT;
}
/* setting State.Width/Height to call resize callback later */
if( ! sizeUse )
if( !sizeUse )
{
if( ! window->IsMenu )
{
@ -1194,32 +1391,34 @@ void fgOpenWindow( SFG_Window* window, const char* title,
}
else /* fail safe - Windows can make a window of size (0, 0) */
w = h = 300; /* default window size */
window->State.Width = window->State.Height = -1;
}
else
{
window->State.Width = worig;
window->State.Height = horig;
}
/* store requested client area width and height */
window->State.Width = w;
window->State.Height = h;
#if !defined(_WIN32_WCE) /* no decorations for windows CE */
if( sizeUse )
{
RECT windowRect;
/*
* There's a small difference between creating the top, child and
* game mode windows
* Update the window dimensions, taking the window decorations
* into account. FreeGLUT is to create the window with the
* topleft outside corner at (x,y) and with client area
* dimensions (w,h).
* note: don't need to do this when w=h=CW_USEDEFAULT, so in the
* if( sizeUse ) here is convenient.
*/
flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
windowRect.left = x;
windowRect.top = y;
windowRect.right = x+w;
windowRect.bottom = y+h;
if ( window->IsMenu )
{
flags |= WS_POPUP;
exFlags |= WS_EX_TOOLWINDOW;
}
#if !defined(_WIN32_WCE)
else if( window->Parent == NULL )
flags |= WS_OVERLAPPEDWINDOW;
#endif
else
flags |= WS_CHILD;
fghComputeWindowRectFromClientArea_UseStyle(flags,&windowRect,TRUE);
w = windowRect.right - windowRect.left;
h = windowRect.bottom- windowRect.top;
}
#endif /* !defined(_WIN32_WCE) */
#if defined(_WIN32_WCE)
{
@ -1246,29 +1445,28 @@ void fgOpenWindow( SFG_Window* window, const char* title,
UpdateWindow(window->Window.Handle);
}
#else
{
/* xoff and yoff are used to place window relative to current display */
/* The operation of gamemode also depends on this */
int xoff=0,yoff=0;
get_display_origin(&xoff,&yoff);
window->Window.Handle = CreateWindowEx(
exFlags,
_T("FREEGLUT"),
title,
flags,
x+xoff, y+yoff, w, h,
x, y, w, h,
(HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
(HMENU) NULL,
fgDisplay.Instance,
(LPVOID) window
);
}
#endif /* defined(_WIN32_WCE) */
if( !( window->Window.Handle ) )
fgError( "Failed to create a window (%s)!", title );
#if !defined(_WIN32_WCE)
/* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */
SetWindowLong(window->Window.Handle, GWL_STYLE, flags);
SetWindowPos(window->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
#endif /* defined(_WIN32_WCE) */
/* Make a menu window always on top - fix Feature Request 947118 */
if( window->IsMenu || gameMode )
SetWindowPos(
@ -1278,23 +1476,6 @@ void fgOpenWindow( SFG_Window* window, const char* title,
SWP_NOMOVE | SWP_NOSIZE
);
/* Hack to remove the caption (title bar) and/or border
* and all the system menu controls.
*/
WindowStyle = GetWindowLong(window->Window.Handle, GWL_STYLE);
if ( fgState.DisplayMode & GLUT_CAPTIONLESS )
{
SetWindowLong ( window->Window.Handle, GWL_STYLE,
WindowStyle & ~(WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX));
}
else if ( fgState.DisplayMode & GLUT_BORDERLESS )
{
SetWindowLong ( window->Window.Handle, GWL_STYLE,
WindowStyle & ~(WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_DLGFRAME | WS_SIZEBOX));
}
/* SetWindowPos(window->Window.Handle, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); */
/* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */
#ifdef WM_TOUCH
if (fghRegisterTouchWindow == (pRegisterTouchWindow)0xDEADBEEF)
@ -1680,7 +1861,7 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
if (glutGet(GLUT_FULL_SCREEN))
{
/* Leave full screen state before resizing. */
glutFullScreenToggle();
glutLeaveFullScreen();
}
fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
@ -1699,7 +1880,7 @@ void FGAPIENTRY glutPositionWindow( int x, int y )
if (glutGet(GLUT_FULL_SCREEN))
{
/* Leave full screen state before moving. */
glutFullScreenToggle();
glutLeaveFullScreen();
}
#if TARGET_HOST_POSIX_X11
@ -1788,6 +1969,21 @@ void FGAPIENTRY glutFullScreen( void )
win = fgStructure.CurrentWindow;
if (win->Parent)
{
/* Child windows cannot be made fullscreen, consistent with GLUT's behavior
* Also, what would it mean for a child window to be fullscreen, given that it
* is confined to its parent?
*/
fgWarning("glutFullScreen called on a child window, ignoring...");
return;
}
else if (fgStructure.GameModeWindow != NULL && fgStructure.GameModeWindow->ID==win->ID)
{
/* Ignore fullscreen call on GameMode window, those are always fullscreen already */
return;
}
#if TARGET_HOST_POSIX_X11
if(!glutGet(GLUT_FULL_SCREEN)) {
if(fghToggleFullscreen() != -1) {
@ -1799,34 +1995,50 @@ void FGAPIENTRY glutFullScreen( void )
if (glutGet(GLUT_FULL_SCREEN))
{
/* Leave full screen state before resizing. */
glutFullScreenToggle();
/* Leave full screen state before entering fullscreen again (resizing?) */
glutLeaveFullScreen();
}
{
DWORD s;
RECT rect;
HMONITOR hMonitor;
MONITORINFO mi;
/* For fullscreen mode, force the top-left corner to 0,0
* and adjust the window rectangle so that the client area
* covers the whole screen.
/* For fullscreen mode, first remove all window decoration
* and set style to popup so it will overlap the taskbar
* then force to maximize on the screen on which it has the most
* overlap.
*/
rect.left = 0;
rect.top = 0;
get_display_origin(&rect.left,&rect.top);
rect.right = fgDisplay.ScreenWidth+rect.left;
rect.bottom = fgDisplay.ScreenHeight+rect.top;
AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN, FALSE );
/* store current window rect */
GetWindowRect( win->Window.Handle, &win->State.OldRect );
/* store current window style */
win->State.OldStyle = s = GetWindowLong(win->Window.Handle, GWL_STYLE);
/* remove decorations from style and add popup style*/
s &= ~WS_OVERLAPPEDWINDOW;
s |= WS_POPUP;
SetWindowLong(win->Window.Handle, GWL_STYLE, s);
SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
/* For fullscreen mode, find the monitor that is covered the most
* by the window and get its rect as the resize target.
*/
hMonitor= MonitorFromRect(&win->State.OldRect, MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi);
rect = mi.rcMonitor;
/*
* then resize window
* SWP_NOACTIVATE Do not activate the window
* SWP_NOOWNERZORDER Do not change position in z-order
* SWP_NOSENDCHANGING Supress WM_WINDOWPOSCHANGING message
* SWP_NOSENDCHANGING Suppress WM_WINDOWPOSCHANGING message
* SWP_NOZORDER Retains the current Z order (ignore 2nd param)
*/
SetWindowPos( fgStructure.CurrentWindow->Window.Handle,
HWND_TOP,
rect.left,
@ -1842,6 +2054,51 @@ void FGAPIENTRY glutFullScreen( void )
#endif
}
/*
* If we are fullscreen, resize the current window back to its original size
*/
void FGAPIENTRY glutLeaveFullScreen( void )
{
SFG_Window *win;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
win = fgStructure.CurrentWindow;
#if TARGET_HOST_POSIX_X11
if(glutGet(GLUT_FULL_SCREEN)) {
if(fghToggleFullscreen() != -1) {
win->State.IsFullscreen = GL_FALSE;
}
}
#elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: what about WinCE */
if (!glutGet(GLUT_FULL_SCREEN))
{
/* nothing to do */
return;
}
/* restore style of window before making it fullscreen */
SetWindowLong(win->Window.Handle, GWL_STYLE, win->State.OldStyle);
SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
/* Then resize */
SetWindowPos(win->Window.Handle,
HWND_TOP,
win->State.OldRect.left,
win->State.OldRect.top,
win->State.OldRect.right - win->State.OldRect.left,
win->State.OldRect.bottom - win->State.OldRect.top,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
SWP_NOZORDER
);
win->State.IsFullscreen = GL_FALSE;
#endif
}
/*
* Toggle the window's full screen state.
*/
@ -1859,8 +2116,10 @@ void FGAPIENTRY glutFullScreenToggle( void )
win->State.IsFullscreen = !win->State.IsFullscreen;
}
#elif TARGET_HOST_MS_WINDOWS
if (!win->State.IsFullscreen)
glutFullScreen();
win->State.IsFullscreen = !win->State.IsFullscreen;
else
glutLeaveFullScreen();
#endif
}

View File

@ -139,6 +139,7 @@ EXPORTS
glutGetProcAddress
glutExit
glutFullScreenToggle
glutLeaveFullScreen
glutGetModeValues
glutInitContextFlags
glutInitContextVersion