diff options
-rw-r--r-- | client/x11/platform.cpp | 17 | ||||
-rw-r--r-- | client/x11/red_pixmap_cairo.cpp | 9 | ||||
-rw-r--r-- | client/x11/x_platform.h | 2 |
3 files changed, 25 insertions, 3 deletions
diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp index 217664a4..d00092be 100644 --- a/client/x11/platform.cpp +++ b/client/x11/platform.cpp @@ -26,7 +26,9 @@ #include <X11/extensions/render.h> #include <X11/extensions/XKB.h> #include <X11/extensions/Xrender.h> +#include <X11/extensions/XShm.h> #include <unistd.h> +#include <sys/socket.h> #include <sys/epoll.h> #include <sys/resource.h> #include <sys/types.h> @@ -63,6 +65,7 @@ #endif static Display* x_display = NULL; +static bool x_shm_avail = false; static XVisualInfo **vinfo = NULL; static GLXFBConfig **fb_config; @@ -183,6 +186,11 @@ Display* XPlatform::get_display() return x_display; } +bool XPlatform::is_x_shm_avail() +{ + return x_shm_avail; +} + XVisualInfo** XPlatform::get_vinfo() { return vinfo; @@ -2069,6 +2077,9 @@ void Platform::init() { int err, ev; int threads_enable; + int connection_fd; + socklen_t sock_len; + struct sockaddr sock_addr; DBG(0, ""); @@ -2079,6 +2090,12 @@ void Platform::init() THROW("open X display failed"); } + connection_fd = ConnectionNumber(x_display); + if (!getsockname(connection_fd, &sock_addr, &sock_len) && + XShmQueryExtension(x_display) && sock_addr.sa_family == AF_UNIX ) { + x_shm_avail = true; + } + vinfo = new XVisualInfo *[ScreenCount(x_display)]; memset(vinfo, 0, sizeof(XVisualInfo *) * ScreenCount(x_display)); fb_config = new GLXFBConfig *[ScreenCount(x_display)]; diff --git a/client/x11/red_pixmap_cairo.cpp b/client/x11/red_pixmap_cairo.cpp index d15c35c3..795c8a0d 100644 --- a/client/x11/red_pixmap_cairo.cpp +++ b/client/x11/red_pixmap_cairo.cpp @@ -36,6 +36,7 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, XShmSegmentInfo *shminfo = NULL; _data = NULL; XVisualInfo *vinfo = NULL; + bool using_shm = false; try { @@ -45,7 +46,9 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, vinfo = XPlatform::get_vinfo()[win->get_screen_num()]; } - if (vinfo && XShmQueryExtension(XPlatform::get_display())) { + using_shm = vinfo && XPlatform::is_x_shm_avail(); + + if (using_shm) { int depth; switch (format) { @@ -146,14 +149,14 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS) { THROW("cairo create failed failed"); } - if (!(vinfo && XShmQueryExtension(XPlatform::get_display()))) { + if (!using_shm) { ((PixelsSource_p*)get_opaque())->pixmap.cairo_surf = cairo_surf; } else { ((PixelsSource_p*)get_opaque())->x_shm_drawable.cairo_surf = cairo_surf; } ((RedDrawable_p*)get_opaque())->cairo = cairo; } catch (...) { - if (vinfo && XShmQueryExtension(XPlatform::get_display())) { + if (using_shm) { if (image) { XDestroyImage(image); } diff --git a/client/x11/x_platform.h b/client/x11/x_platform.h index bc2f691f..eafa02d3 100644 --- a/client/x11/x_platform.h +++ b/client/x11/x_platform.h @@ -30,6 +30,8 @@ public: static void on_focus_in(); static void on_focus_out(); + + static bool is_x_shm_avail(); }; #endif |