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:
parent
42235dfaa1
commit
cf91891cf8
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,7 @@ EXPORTS
|
||||
glutGetProcAddress
|
||||
glutExit
|
||||
glutFullScreenToggle
|
||||
glutLeaveFullScreen
|
||||
glutGetModeValues
|
||||
glutInitContextFlags
|
||||
glutInitContextVersion
|
||||
|
Reference in New Issue
Block a user