Commit 2a75782553e46e8c59601d51f28edb977f52fcdc

Ryan C. Gordon 2015-05-28T00:30:21

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.

diff --git a/configure b/configure
index 3049e0c..23142da 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 <X11/Xlib.h>
+
+"
+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 1cf3f96..7aaac17 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 <X11/Xlib.h>
+                                ])
+                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 5a56a96..52d9c92 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 fe628bf..d9fd622 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 83628ce..e4ce82f 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 7f2b250..c865684 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 5708c08..878b3c2 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 5708c08..878b3c2 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 2a8bc1f..1a4d8d5 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 6f63deb..1452164 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 5acffe9..2d729b7 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 <X11/Xcursor/Xcursor.h>
 #endif
+#if SDL_VIDEO_DRIVER_X11_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
 #include <X11/extensions/Xinerama.h>
 #endif
diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c
index 3484c14..a244090 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 27342e0..c424b51 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 60ed199..3fc273e 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 <X11/Xcursor/Xcursor.h>
 #endif
+#if SDL_VIDEO_DRIVER_X11_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
 #if SDL_VIDEO_DRIVER_X11_XINERAMA
 #include <X11/extensions/Xinerama.h>
 #endif