Putting in the "glutFullScreen" support for Gnome and other X window managers per e-mail with patch file from John Tsiombikas dated 2:14 AM, 11/16/09

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@849 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
fayjf 2009-11-18 01:52:13 +00:00
parent 77dda48064
commit ee3f0e0680
4 changed files with 111 additions and 83 deletions

View File

@ -436,6 +436,8 @@ struct tagSFG_WindowState
GLboolean KeyRepeating; /* Currently in repeat mode */ GLboolean KeyRepeating; /* Currently in repeat mode */
GLboolean NeedToResize; /* Do we need to resize the window? */ GLboolean NeedToResize; /* Do we need to resize the window? */
GLboolean IsFullscreen; /* is the window fullscreen? */
}; };

View File

@ -68,23 +68,9 @@ static int fghGetConfig( int attribute )
static int fghCheckFullScreen(void) static int fghCheckFullScreen(void)
{ {
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
return fgStructure.CurrentWindow->State.IsFullscreen;
int result;
result = 0;
if (fgDisplay.StateFullScreen != None)
{
result = fgHintPresent(fgStructure.CurrentWindow->Window.Handle,
fgDisplay.State,
fgDisplay.StateFullScreen);
}
return result;
#else #else
return 0; return 0;
#endif #endif
} }

View File

@ -97,6 +97,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
window->State.IgnoreKeyRepeat = GL_FALSE; window->State.IgnoreKeyRepeat = GL_FALSE;
window->State.KeyRepeating = GL_FALSE; window->State.KeyRepeating = GL_FALSE;
window->State.IsFullscreen = GL_FALSE;
/* /*
* Open the window now. The fgOpenWindow() function is system * Open the window now. The fgOpenWindow() function is system

View File

@ -1559,29 +1559,67 @@ void FGAPIENTRY glutPopWindow( void )
#endif #endif
} }
/* #if TARGET_HOST_POSIX_X11
* Resize the current window so that it fits the whole screen static int ewmh_fullscr_toggle(void);
*/ static int resize_fullscr_toogle(void);
void FGAPIENTRY glutFullScreen( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
if (glutGet(GLUT_FULL_SCREEN)) static int toggle_fullscreen(void)
{ {
/* Leave full screen state before resizing. */ /* first try the EWMH (_NET_WM_STATE) method ... */
glutFullScreenToggle(); if(ewmh_fullscr_toggle() != -1) {
return 0;
} }
{ /* fall back to resizing the window */
#if TARGET_HOST_POSIX_X11 if(resize_fullscr_toogle() != -1) {
return 0;
}
return -1;
}
Status status; /* Returned by XGetWindowAttributes(), not checked. */ #define _NET_WM_STATE_TOGGLE 2
static int ewmh_fullscr_toggle(void)
{
XEvent xev;
long evmask = SubstructureRedirectMask | SubstructureNotifyMask;
if(!fgDisplay.State || !fgDisplay.StateFullScreen) {
return -1;
}
xev.type = ClientMessage;
xev.xclient.window = fgStructure.CurrentWindow->Window.Handle;
xev.xclient.message_type = fgDisplay.State;
xev.xclient.format = 32;
xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
xev.xclient.data.l[1] = fgDisplay.StateFullScreen;
xev.xclient.data.l[2] = 0; /* no second property to toggle */
xev.xclient.data.l[3] = 1; /* source indication: application */
xev.xclient.data.l[4] = 0; /* unused */
if(!XSendEvent(fgDisplay.Display, fgDisplay.RootWindow, 0, evmask, &xev)) {
return -1;
}
return 0;
}
static int resize_fullscr_toogle(void)
{
XWindowAttributes attributes; XWindowAttributes attributes;
status = XGetWindowAttributes(fgDisplay.Display, if(glutGet(GLUT_FULL_SCREEN)) {
/* restore original window size */
SFG_Window *win = fgStructure.CurrentWindow;
fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
fgStructure.CurrentWindow->State.Width = win->State.OldWidth;
fgStructure.CurrentWindow->State.Height = win->State.OldHeight;
} else {
/* resize the window to cover the entire screen */
XGetWindowAttributes(fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle, fgStructure.CurrentWindow->Window.Handle,
&attributes); &attributes);
/* /*
* The "x" and "y" members of "attributes" are the window's coordinates * The "x" and "y" members of "attributes" are the window's coordinates
* relative to its parent, i.e. to the decoration window. * relative to its parent, i.e. to the decoration window.
@ -1592,8 +1630,40 @@ void FGAPIENTRY glutFullScreen( void )
-attributes.y, -attributes.y,
fgDisplay.ScreenWidth, fgDisplay.ScreenWidth,
fgDisplay.ScreenHeight); fgDisplay.ScreenHeight);
}
return 0;
}
#endif /* TARGET_HOST_POSIX_X11 */
/*
* Resize the current window so that it fits the whole screen
*/
void FGAPIENTRY glutFullScreen( 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(toggle_fullscreen() != -1) {
win->State.IsFullscreen = GL_TRUE;
}
}
#elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: what about WinCE */ #elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: what about WinCE */
if (glutGet(GLUT_FULL_SCREEN))
{
/* Leave full screen state before resizing. */
glutFullScreenToggle();
}
{
RECT rect; RECT rect;
/* For fullscreen mode, force the top-left corner to 0,0 /* For fullscreen mode, force the top-left corner to 0,0
@ -1625,8 +1695,10 @@ void FGAPIENTRY glutFullScreen( void )
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |
SWP_NOZORDER SWP_NOZORDER
); );
#endif
win->State.IsFullscreen = GL_TRUE;
} }
#endif
} }
/* /*
@ -1634,54 +1706,21 @@ void FGAPIENTRY glutFullScreen( void )
*/ */
void FGAPIENTRY glutFullScreenToggle( void ) void FGAPIENTRY glutFullScreenToggle( void )
{ {
SFG_Window *win;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreenToggle" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreenToggle" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreenToggle" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreenToggle" );
{ win = fgStructure.CurrentWindow;
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
if(toggle_fullscreen() != -1) {
if (fgDisplay.StateFullScreen != None) win->State.IsFullscreen = !win->State.IsFullscreen;
{
XEvent xevent;
long event_mask;
int status;
xevent.type = ClientMessage;
xevent.xclient.type = ClientMessage;
xevent.xclient.serial = 0;
xevent.xclient.send_event = True;
xevent.xclient.display = fgDisplay.Display;
xevent.xclient.window = fgStructure.CurrentWindow->Window.Handle;
xevent.xclient.message_type = fgDisplay.State;
xevent.xclient.format = 32;
xevent.xclient.data.l[0] = 2; /* _NET_WM_STATE_TOGGLE */
xevent.xclient.data.l[1] = fgDisplay.StateFullScreen;
xevent.xclient.data.l[2] = 0;
xevent.xclient.data.l[3] = 0;
xevent.xclient.data.l[4] = 0;
/*** Don't really understand how event masks work... ***/
event_mask = SubstructureRedirectMask | SubstructureNotifyMask;
status = XSendEvent(fgDisplay.Display,
fgDisplay.RootWindow,
False,
event_mask,
&xevent);
FREEGLUT_INTERNAL_ERROR_EXIT(status != 0,
"XSendEvent failed",
"glutFullScreenToggle");
} }
else #elif TARGET_HOST_MS_WINDOWS
#endif
{
/*
* If the window manager is not Net WM compliant, fall back to legacy
* behaviour.
*/
glutFullScreen(); glutFullScreen();
} win->State.IsFullscreen = !win->State.IsFullscreen;
} #endif
} }
/* /*