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:
parent
77dda48064
commit
ee3f0e0680
@ -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? */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user