From f8de693eefaef1ad3ada3ab7ebde462bdbea888c Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 29 Sep 2012 10:47:55 +0200 Subject: [PATCH] Use true fullscreen in X/EGL. --- Makefile | 4 ++-- gfx/context/x11_common.c | 48 ++++++++++++++++++++++++++++++++++++++++ gfx/context/x11_common.h | 4 ++++ gfx/context/xegl_ctx.c | 30 ++++++++++++++++++++++--- input/x11_input.c | 4 ++-- qb/config.libs.sh | 10 +++++---- 6 files changed, 89 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 9a46ab2297..2c80a2069f 100644 --- a/Makefile +++ b/Makefile @@ -207,8 +207,8 @@ endif ifeq ($(HAVE_X11), 1) OBJ += input/x11_input.o gfx/context/x11_common.o - LIBS += $(X11_LIBS) $(XEXT_LIBS) - DEFINES += $(X11_CFLAGS) $(XEXT_CFLAGS) + LIBS += $(X11_LIBS) $(XEXT_LIBS) $(XF86VM_LIBS) + DEFINES += $(X11_CFLAGS) $(XEXT_CFLAGS) $(XF86VM_CFLAGS) endif ifeq ($(HAVE_CG), 1) diff --git a/gfx/context/x11_common.c b/gfx/context/x11_common.c index 639932472c..094c0144c2 100644 --- a/gfx/context/x11_common.c +++ b/gfx/context/x11_common.c @@ -89,3 +89,51 @@ void x11_suspend_screensaver(Window wnd) RARCH_WARN("Could not suspend screen saver.\n"); } +static bool get_video_mode(Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *mode, XF86VidModeModeInfo *desktop_mode) +{ + XF86VidModeModeInfo **modes = NULL; + int num_modes = 0; + XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &num_modes, &modes); + + if (!num_modes) + { + XFree(modes); + return false; + } + + *desktop_mode = *modes[0]; + + bool ret = false; + for (int i = 0; i < num_modes; i++) + { + if (modes[i]->hdisplay == width && modes[i]->vdisplay == height) + { + *mode = *modes[i]; + ret = true; + break; + } + } + + XFree(modes); + return ret; +} + +bool x11_enter_fullscreen(Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *desktop_mode) +{ + XF86VidModeModeInfo mode; + if (get_video_mode(dpy, width, height, &mode, desktop_mode)) + { + XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), &mode); + XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0); + return true; + } + else + return false; +} + +void x11_exit_fullscreen(Display *dpy, XF86VidModeModeInfo *desktop_mode) +{ + XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), desktop_mode); + XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0); +} + diff --git a/gfx/context/x11_common.h b/gfx/context/x11_common.h index 0c4c0a849c..2d4bafa1c0 100644 --- a/gfx/context/x11_common.h +++ b/gfx/context/x11_common.h @@ -19,10 +19,14 @@ #include #include +#include +#include "../../boolean.h" void x11_hide_mouse(Display *dpy, Window win); void x11_windowed_fullscreen(Display *dpy, Window win); void x11_suspend_screensaver(Window win); +bool x11_enter_fullscreen(Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *desktop_mode); +void x11_exit_fullscreen(Display *dpy, XF86VidModeModeInfo *desktop_mode); #endif diff --git a/gfx/context/xegl_ctx.c b/gfx/context/xegl_ctx.c index 25f49d20a2..023aa5d4dd 100644 --- a/gfx/context/xegl_ctx.c +++ b/gfx/context/xegl_ctx.c @@ -41,6 +41,9 @@ static EGLSurface g_egl_surf; static EGLDisplay g_egl_dpy; static EGLConfig g_config; +static XF86VidModeModeInfo g_desktop_mode; +static bool g_should_reset_mode; + static volatile sig_atomic_t g_quit; static bool g_inited; static unsigned g_interval; @@ -52,6 +55,13 @@ static void sighandler(int sig) g_quit = 1; } +static Bool egl_wait_notify(Display *d, XEvent *e, char *arg) +{ + (void)d; + (void)e; + return e->type == MapNotify && e->xmap.window == g_win; +} + static void gfx_ctx_get_video_size(unsigned *width, unsigned *height); static void gfx_ctx_destroy(void); @@ -264,11 +274,18 @@ static bool gfx_ctx_set_video_mode( swa.colormap = g_cmap = XCreateColormap(g_dpy, RootWindow(g_dpy, vi->screen), vi->visual, AllocNone); swa.event_mask = StructureNotifyMask; + swa.override_redirect = fullscreen ? True : False; + + if (fullscreen) + { + if (x11_enter_fullscreen(g_dpy, width, height, &g_desktop_mode)) + g_should_reset_mode = true; + } g_win = XCreateWindow(g_dpy, RootWindow(g_dpy, vi->screen), 0, 0, width ? width : 200, height ? height : 200, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask, &swa); + CWBorderPixel | CWColormap | CWEventMask | (fullscreen ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(g_dpy, g_win, 0); // GLES 2.0. Don't use for any other API. @@ -294,8 +311,9 @@ static bool gfx_ctx_set_video_mode( x11_hide_mouse(g_dpy, g_win); XMapWindow(g_dpy, g_win); - if (fullscreen) - x11_windowed_fullscreen(g_dpy, g_win); + XEvent event; + XIfEvent(g_dpy, &event, egl_wait_notify, NULL); + XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False); if (g_quit_atom) @@ -354,6 +372,12 @@ static void gfx_ctx_destroy(void) g_cmap = None; } + if (g_should_reset_mode) + { + x11_exit_fullscreen(g_dpy, &g_desktop_mode); + g_should_reset_mode = false; + } + if (g_dpy) { XCloseDisplay(g_dpy); diff --git a/input/x11_input.c b/input/x11_input.c index 804a626acb..177251f06b 100644 --- a/input/x11_input.c +++ b/input/x11_input.c @@ -295,8 +295,8 @@ static void x_input_poll(void *data) { x11_input_t *x11 = (x11_input_t*)data; - Window win; - int rev; + Window win = None; + int rev = 0; XGetInputFocus(x11->display, &win, &rev); if (win == x11->win) diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 5cd0cf5751..9dcd74d43d 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -163,13 +163,15 @@ fi check_pkgconf XML libxml-2.0 check_pkgconf FREETYPE freetype2 check_pkgconf X11 x11 -[ "$HAVE_X11" = "no" ] && HAVE_XEXT=no +[ "$HAVE_X11" = "no" ] && HAVE_XEXT=no && HAVE_XF86VM=no check_pkgconf XEXT xext -if [ "$HAVE_X11" = 'yes' ] && [ "$HAVE_XEXT" = 'yes' ]; then +check_pkgconf XF86VM xxf86vm +if [ "$HAVE_X11" = 'yes' ] && [ "$HAVE_XEXT" = 'yes' ] && [ "$HAVE_XF86VM" = 'yes' ]; then check_pkgconf XVIDEO xv else - echo "X11 or Xext not present. Skipping XVideo." + echo "X11, Xext or xf86vm not present. Skipping X11." + HAVE_X11='no' HAVE_XVIDEO='no' fi @@ -180,6 +182,6 @@ check_pkgconf PYTHON python3 add_define_make OS "$OS" # Creates config.mk and config.h. -VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL GLES VG EGL KMS GBM DRM DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO PBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC FIXED_POINT BSV_MOVIE VIDEOCORE" +VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL GLES VG EGL KMS GBM DRM DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL CONFIGFILE FREETYPE XVIDEO X11 XEXT XF86VM NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO PBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC FIXED_POINT BSV_MOVIE VIDEOCORE" create_config_make config.mk $VARS create_config_header config.h $VARS