From 3915f0fbcabf8f2bb4fbf69cf57d9788eef3a1f0 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Mon, 8 Feb 2010 04:30:01 +0000 Subject: [PATCH] Enable dynamic fullscreen switching in linux. Toggle fullscreen mode with the escape key. Unfortunately this fullscreen mode is separate from the fullscreen mode obtained from the OGL config dialog. To close that fullscreen mode you must use Alt-F4 for now (not escape). This is not how we want this to end up but there is a mode switching issue I can't figure out. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5029 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp | 59 +++++++++++++++++-- Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h | 7 +++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index b467bf1e90..2c27a21372 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -274,7 +274,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight int dpyWidth, dpyHeight; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; - Atom wmDelete; + Atom wmProtocols[3]; // attributes for a single buffered visual in RGBA format with at least // 8 bits per color and a 24 bit depth buffer @@ -393,9 +393,11 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), 0, 0, _twidth, _theight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr); - // only set window title and handle wm_delete_events if in windowed mode - wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True); - XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1); + // only set window title and handle WM_PROTOCOLS if in windowed mode + wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True); + wmProtocols[1] = XInternAtom(GLWin.dpy, "_NET_WM_STATE", False); + wmProtocols[2] = XInternAtom(GLWin.dpy, "_NET_WM_STATE_FULLSCREEN", False); + XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 3); XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); XMapRaised(GLWin.dpy, GLWin.win); @@ -416,6 +418,37 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight return true; } +#if defined(HAVE_X11) && HAVE_X11 +void X11_EWMH_Fullscreen(int action) +{ + assert(action == _NET_WM_STATE_REMOVE || + action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); + + XEvent xev; + + // Init X event structure for _NET_WM_STATE_FULLSCREEN client message + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.message_type = XInternAtom(GLWin.dpy, "_NET_WM_STATE", False); + xev.xclient.window = GLWin.win; + xev.xclient.format = 32; + xev.xclient.data.l[0] = action; + xev.xclient.data.l[1] = XInternAtom(GLWin.dpy, "_NET_WM_STATE_FULLSCREEN", False); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + // Send the event + if (!XSendEvent(GLWin.dpy, DefaultRootWindow(GLWin.dpy), False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev)) + { + ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode.\n"); + } +} +#endif + bool OpenGL_MakeCurrent() { #if defined(USE_WX) && USE_WX @@ -521,9 +554,23 @@ void OpenGL_Update() case KeyPress: key = XLookupKeysym((XKeyEvent*)&event, 0); if(key >= XK_F1 && key <= XK_F9) - FKeyPressed = key - 0xff4e; - else if (key == XK_Escape) + { + if(key == XK_F4 && ((event.xkey.state & Mod1Mask) == Mod1Mask)) FKeyPressed = 0x1b; + else + FKeyPressed = key - 0xff4e; + } + else if (key == XK_Escape) + { + if (!GLWin.fs) + { + X11_EWMH_Fullscreen(_NET_WM_STATE_TOGGLE); + XWithdrawWindow(GLWin.dpy,GLWin.win,GLWin.screen); + XMapRaised(GLWin.dpy,GLWin.win); + XRaiseWindow(GLWin.dpy,GLWin.win); + XFlush(GLWin.dpy); + } + } else { if(key == XK_Shift_L || key == XK_Shift_R) ShiftPressed = true; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h index 98a769606e..0b14e16b39 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h @@ -69,6 +69,13 @@ #include #include #include + +// EWMH state actions, see +// http://freedesktop.org/wiki/Specifications/wm-spec?action=show&redirect=Standards%2Fwm-spec +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ + #if defined(HAVE_XXF86VM) && HAVE_XXF86VM #include #endif // XXF86VM