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 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)
{
#if TARGET_HOST_POSIX_X11
int result;
result = 0;
if (fgDisplay.StateFullScreen != None)
{
result = fgHintPresent(fgStructure.CurrentWindow->Window.Handle,
fgDisplay.State,
fgDisplay.StateFullScreen);
}
return result;
return fgStructure.CurrentWindow->State.IsFullscreen;
#else
return 0;
#endif
}

View File

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

View File

@ -1559,29 +1559,67 @@ void FGAPIENTRY glutPopWindow( void )
#endif
}
/*
* Resize the current window so that it fits the whole screen
*/
void FGAPIENTRY glutFullScreen( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreen" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreen" );
#if TARGET_HOST_POSIX_X11
static int ewmh_fullscr_toggle(void);
static int resize_fullscr_toogle(void);
if (glutGet(GLUT_FULL_SCREEN))
static int toggle_fullscreen(void)
{
/* Leave full screen state before resizing. */
glutFullScreenToggle();
/* first try the EWMH (_NET_WM_STATE) method ... */
if(ewmh_fullscr_toggle() != -1) {
return 0;
}
{
#if TARGET_HOST_POSIX_X11
/* fall back to resizing the window */
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;
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,
&attributes);
/*
* The "x" and "y" members of "attributes" are the window's coordinates
* relative to its parent, i.e. to the decoration window.
@ -1592,8 +1630,40 @@ void FGAPIENTRY glutFullScreen( void )
-attributes.y,
fgDisplay.ScreenWidth,
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 */
if (glutGet(GLUT_FULL_SCREEN))
{
/* Leave full screen state before resizing. */
glutFullScreenToggle();
}
{
RECT rect;
/* 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_NOZORDER
);
#endif
win->State.IsFullscreen = GL_TRUE;
}
#endif
}
/*
@ -1634,54 +1706,21 @@ void FGAPIENTRY glutFullScreen( void )
*/
void FGAPIENTRY glutFullScreenToggle( void )
{
SFG_Window *win;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutFullScreenToggle" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutFullScreenToggle" );
{
win = fgStructure.CurrentWindow;
#if TARGET_HOST_POSIX_X11
if (fgDisplay.StateFullScreen != None)
{
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");
if(toggle_fullscreen() != -1) {
win->State.IsFullscreen = !win->State.IsFullscreen;
}
else
#endif
{
/*
* If the window manager is not Net WM compliant, fall back to legacy
* behaviour.
*/
#elif TARGET_HOST_MS_WINDOWS
glutFullScreen();
}
}
win->State.IsFullscreen = !win->State.IsFullscreen;
#endif
}
/*