From 2a75782553e46e8c59601d51f28edb977f52fcdc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 28 May 2015 00:30:21 -0400 Subject: [PATCH] X11: Add Xdbe support to message boxes (thanks, Melker!). Without this, message boxes with a lot of text will noticibly flicker as you mouse over buttons. Fixes Bugzilla #2343. --- configure | 27 +++++++++++++ configure.in | 14 +++++++ include/SDL_config.h.cmake | 1 + include/SDL_config.h.in | 1 + include/SDL_config_macosx.h | 1 + premake/Linux/SDL_config_premake.h | 3 ++ premake/Xcode/Xcode3/SDL_config_premake.h | 1 + premake/Xcode/Xcode4/SDL_config_premake.h | 1 + premake/config/SDL_config_macosx.template.h | 1 + premake/projects/SDL2.lua | 1 + src/video/x11/SDL_x11dyn.h | 3 ++ src/video/x11/SDL_x11messagebox.c | 45 ++++++++++++++++++++- src/video/x11/SDL_x11sym.h | 14 +++++++ src/video/x11/SDL_x11video.h | 3 ++ 14 files changed, 114 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 3049e0c2fb609..23142da8a2aac 100755 --- a/configure +++ b/configure @@ -826,6 +826,7 @@ enable_video_x11 with_x enable_x11_shared enable_video_x11_xcursor +enable_video_x11_xdbe enable_video_x11_xinerama enable_video_x11_xinput enable_video_x11_xrandr @@ -1551,6 +1552,7 @@ Optional Features: --enable-x11-shared dynamically load X11 support [[default=maybe]] --enable-video-x11-xcursor enable X11 Xcursor support [[default=yes]] + --enable-video-x11-xdbe enable X11 Xdbe support [[default=yes]] --enable-video-x11-xinerama enable X11 Xinerama support [[default=yes]] --enable-video-x11-xinput @@ -20123,6 +20125,31 @@ $as_echo "#define SDL_VIDEO_DRIVER_X11_XCURSOR 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xcursor" fi + # Check whether --enable-video-x11-xdbe was given. +if test "${enable_video_x11_xdbe+set}" = set; then : + enableval=$enable_video_x11_xdbe; +else + enable_video_x11_xdbe=yes +fi + + if test x$enable_video_x11_xdbe = xyes; then + ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xdbe.h" "ac_cv_header_X11_extensions_Xdbe_h" "#include + +" +if test "x$ac_cv_header_X11_extensions_Xdbe_h" = xyes; then : + have_dbe_h_hdr=yes +else + have_dbe_h_hdr=no +fi + + + if test x$have_dbe_h_hdr = xyes; then + +$as_echo "#define SDL_VIDEO_DRIVER_X11_XDBE 1" >>confdefs.h + + SUMMARY_video_x11="${SUMMARY_video_x11} xdbe" + fi + fi # Check whether --enable-video-x11-xinerama was given. if test "${enable_video_x11_xinerama+set}" = set; then : enableval=$enable_video_x11_xinerama; diff --git a/configure.in b/configure.in index 1cf3f96516fb4..7aaac171e1d37 100644 --- a/configure.in +++ b/configure.in @@ -1552,6 +1552,20 @@ AC_HELP_STRING([--enable-video-x11-xcursor], [enable X11 Xcursor support [[defau AC_DEFINE(SDL_VIDEO_DRIVER_X11_XCURSOR, 1, [ ]) SUMMARY_video_x11="${SUMMARY_video_x11} xcursor" fi + AC_ARG_ENABLE(video-x11-xdbe, +AC_HELP_STRING([--enable-video-x11-xdbe], [enable X11 Xdbe support [[default=yes]]]), + , enable_video_x11_xdbe=yes) + if test x$enable_video_x11_xdbe = xyes; then + AC_CHECK_HEADER(X11/extensions/Xdbe.h, + have_dbe_h_hdr=yes, + have_dbe_h_hdr=no, + [#include + ]) + if test x$have_dbe_h_hdr = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_X11_XDBE, 1, [ ]) + SUMMARY_video_x11="${SUMMARY_video_x11} xdbe" + fi + fi AC_ARG_ENABLE(video-x11-xinerama, AC_HELP_STRING([--enable-video-x11-xinerama], [enable X11 Xinerama support [[default=yes]]]), , enable_video_x11_xinerama=yes) diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 5a56a9607b1b0..52d9c92b82ae5 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -296,6 +296,7 @@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS @SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE @SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE@ #cmakedefine SDL_VIDEO_DRIVER_X11_XCURSOR @SDL_VIDEO_DRIVER_X11_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XDBE @SDL_VIDEO_DRIVER_X11_XDBE@ #cmakedefine SDL_VIDEO_DRIVER_X11_XINERAMA @SDL_VIDEO_DRIVER_X11_XINERAMA@ #cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2 @SDL_VIDEO_DRIVER_X11_XINPUT2@ #cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH @SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index fe628bf511a31..d9fd622564838 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -299,6 +299,7 @@ #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE #undef SDL_VIDEO_DRIVER_X11_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_XDBE #undef SDL_VIDEO_DRIVER_X11_XINERAMA #undef SDL_VIDEO_DRIVER_X11_XINPUT2 #undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 83628cee002df..e4ce82fc26a0f 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -139,6 +139,7 @@ #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/usr/X11R6/lib/libXrandr.2.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/usr/X11R6/lib/libXss.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 #define SDL_VIDEO_DRIVER_X11_XINERAMA 1 #define SDL_VIDEO_DRIVER_X11_XRANDR 1 #define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 diff --git a/premake/Linux/SDL_config_premake.h b/premake/Linux/SDL_config_premake.h index 7f2b250340fc8..c865684b6d73d 100644 --- a/premake/Linux/SDL_config_premake.h +++ b/premake/Linux/SDL_config_premake.h @@ -229,6 +229,9 @@ #ifndef SDL_VIDEO_DRIVER_X11_XCURSOR #define SDL_VIDEO_DRIVER_X11_XCURSOR 1 #endif +#ifndef SDL_VIDEO_DRIVER_X11_XDBE +#define SDL_VIDEO_DRIVER_X11_XDBE 1 +#endif #ifndef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM #define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 #endif diff --git a/premake/Xcode/Xcode3/SDL_config_premake.h b/premake/Xcode/Xcode3/SDL_config_premake.h index 5708c0854e54f..878b3c207f975 100644 --- a/premake/Xcode/Xcode3/SDL_config_premake.h +++ b/premake/Xcode/Xcode3/SDL_config_premake.h @@ -162,6 +162,7 @@ #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/usr/X11R6/lib/libXrandr.2.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/usr/X11R6/lib/libXss.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 #define SDL_VIDEO_DRIVER_X11_XINERAMA 1 #define SDL_VIDEO_DRIVER_X11_XRANDR 1 #define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 diff --git a/premake/Xcode/Xcode4/SDL_config_premake.h b/premake/Xcode/Xcode4/SDL_config_premake.h index 5708c0854e54f..878b3c207f975 100644 --- a/premake/Xcode/Xcode4/SDL_config_premake.h +++ b/premake/Xcode/Xcode4/SDL_config_premake.h @@ -162,6 +162,7 @@ #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/usr/X11R6/lib/libXrandr.2.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/usr/X11R6/lib/libXss.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 #define SDL_VIDEO_DRIVER_X11_XINERAMA 1 #define SDL_VIDEO_DRIVER_X11_XRANDR 1 #define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 diff --git a/premake/config/SDL_config_macosx.template.h b/premake/config/SDL_config_macosx.template.h index 2a8bc1fab1e00..1a4d8d56b3822 100644 --- a/premake/config/SDL_config_macosx.template.h +++ b/premake/config/SDL_config_macosx.template.h @@ -118,6 +118,7 @@ #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/usr/X11R6/lib/libXrandr.2.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/usr/X11R6/lib/libXss.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 #define SDL_VIDEO_DRIVER_X11_XINERAMA 1 #define SDL_VIDEO_DRIVER_X11_XRANDR 1 #define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 diff --git a/premake/projects/SDL2.lua b/premake/projects/SDL2.lua index 6f63debfdaace..1452164b687dd 100755 --- a/premake/projects/SDL2.lua +++ b/premake/projects/SDL2.lua @@ -293,6 +293,7 @@ SDL_project "SDL2" ["SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS"] = '"libXss.so"', ["SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE"] = '"libXxf86vm.so"', ["SDL_VIDEO_DRIVER_X11_XCURSOR"] = 1, + ["SDL_VIDEO_DRIVER_X11_XDBE"] = 1, ["SDL_VIDEO_DRIVER_X11_XINERAMA"] = 1, ["SDL_VIDEO_DRIVER_X11_XINPUT2"] = 1, ["SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH"] = 1, diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index 5acffe9f6e40f..2d729b7080203 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -50,6 +50,9 @@ #if SDL_VIDEO_DRIVER_X11_XCURSOR #include #endif +#if SDL_VIDEO_DRIVER_X11_XDBE +#include +#endif #if SDL_VIDEO_DRIVER_X11_XINERAMA #include #endif diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index 3484c1485c571..a2440906e0d4f 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -83,6 +83,10 @@ typedef struct SDL_MessageBoxDataX11 Display *display; int screen; Window window; +#if SDL_VIDEO_DRIVER_X11_XDBE + XdbeBackBuffer buf; + SDL_bool xdbe; /* Whether Xdbe is present or not */ +#endif long event_mask; Atom wm_protocols; Atom wm_delete_message; @@ -347,6 +351,12 @@ X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data ) data->font_struct = NULL; } +#if SDL_VIDEO_DRIVER_X11_XDBE + if ( SDL_X11_HAVE_XDBE && data->xdbe ) { + X11_XdbeDeallocateBackBufferName(data->display, data->buf); + } +#endif + if ( data->display ) { if ( data->window != None ) { X11_XWithdrawWindow( data->display, data->window, data->screen ); @@ -445,6 +455,20 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data ) } X11_XMapRaised( display, data->window ); + +#if SDL_VIDEO_DRIVER_X11_XDBE + /* Initialise a back buffer for double buffering */ + if (SDL_X11_HAVE_XDBE) { + int xdbe_major, xdbe_minor; + if (X11_XdbeQueryExtension(display, &xdbe_major, &xdbe_minor) != 0) { + data->xdbe = SDL_TRUE; + data->buf = X11_XdbeAllocateBackBufferName(display, data->window, XdbeUndefined); + } else { + data->xdbe = SDL_FALSE; + } + } +#endif + return 0; } @@ -453,9 +477,16 @@ static void X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx ) { int i; - Window window = data->window; + Drawable window = data->window; Display *display = data->display; +#if SDL_VIDEO_DRIVER_X11_XDBE + if (SDL_X11_HAVE_XDBE && data->xdbe) { + window = data->buf; + X11_XdbeBeginIdiom(data->display); + } +#endif + X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ] ); X11_XFillRectangle( display, window, ctx, 0, 0, data->dialog_width, data->dialog_height ); @@ -505,6 +536,16 @@ X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx ) buttondata->text, buttondatax11->length ); } } + +#if SDL_VIDEO_DRIVER_X11_XDBE + if (SDL_X11_HAVE_XDBE && data->xdbe) { + XdbeSwapInfo swap_info; + swap_info.swap_window = data->window; + swap_info.swap_action = XdbeUndefined; + X11_XdbeSwapBuffers(data->display, &swap_info, 1); + X11_XdbeEndIdiom(data->display); + } +#endif } /* Loop and handle message box event messages until something kills it. */ @@ -568,7 +609,7 @@ X11_MessageBoxLoop( SDL_MessageBoxDataX11 *data ) case MotionNotify: if ( has_focus ) { /* Mouse moved... */ - int previndex = data->mouse_over_index; + const int previndex = data->mouse_over_index; data->mouse_over_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y ); if (data->mouse_over_index == previndex) { draw = SDL_FALSE; diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 27342e03ea39f..c424b512a0726 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -230,6 +230,20 @@ SDL_X11_SYM(void,XcursorImageDestroy,(XcursorImage *a),(a),) SDL_X11_SYM(Cursor,XcursorImageLoadCursor,(Display *a,const XcursorImage *b),(a,b),return) #endif +/* Xdbe support */ +#if SDL_VIDEO_DRIVER_X11_XDBE +SDL_X11_MODULE(XDBE) +SDL_X11_SYM(Status,XdbeQueryExtension,(Display *dpy,int *major_version_return,int *minor_version_return),(dpy,major_version_return,minor_version_return),return) +SDL_X11_SYM(XdbeBackBuffer,XdbeAllocateBackBufferName,(Display *dpy,Window window,XdbeSwapAction swap_action),(dpy,window,swap_action),return) +SDL_X11_SYM(Status,XdbeDeallocateBackBufferName,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return) +SDL_X11_SYM(Status,XdbeSwapBuffers,(Display *dpy,XdbeSwapInfo *swap_info,int num_windows),(dpy,swap_info,num_windows),return) +SDL_X11_SYM(Status,XdbeBeginIdiom,(Display *dpy),(dpy),return) +SDL_X11_SYM(Status,XdbeEndIdiom,(Display *dpy),(dpy),return) +SDL_X11_SYM(XdbeScreenVisualInfo*,XdbeGetVisualInfo,(Display *dpy,Drawable *screen_specifiers,int *num_screens),(dpy,screen_specifiers,num_screens),return) +SDL_X11_SYM(void,XdbeFreeVisualInfo,(XdbeScreenVisualInfo *visual_info),(visual_info),) +SDL_X11_SYM(XdbeBackBufferAttributes*,XdbeGetBackBufferAttributes,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return) +#endif + /* Xinerama support */ #if SDL_VIDEO_DRIVER_X11_XINERAMA SDL_X11_MODULE(XINERAMA) diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 60ed199fd4491..3fc273e2f1ef4 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -34,6 +34,9 @@ #if SDL_VIDEO_DRIVER_X11_XCURSOR #include #endif +#if SDL_VIDEO_DRIVER_X11_XDBE +#include +#endif #if SDL_VIDEO_DRIVER_X11_XINERAMA #include #endif