diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp index 1ac45ef8..d13c9fe6 100644 --- a/client/x11/platform.cpp +++ b/client/x11/platform.cpp @@ -26,7 +26,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -63,6 +65,7 @@ #endif static Display* x_display = NULL; +static bool x_shm_avail = false; static XVisualInfo **vinfo = NULL; static GLXFBConfig **fb_config = NULL; static XIM x_input_method = NULL; @@ -185,6 +188,11 @@ Display* XPlatform::get_display() return x_display; } +bool XPlatform::is_x_shm_avail() +{ + return x_shm_avail; +} + XVisualInfo** XPlatform::get_vinfo() { return vinfo; @@ -2095,6 +2103,9 @@ void Platform::init() { int err, ev; int threads_enable; + int connection_fd; + socklen_t sock_len; + struct sockaddr sock_addr; DBG(0, ""); @@ -2107,6 +2118,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 3d3fd8f9..8423e667 100644 --- a/client/x11/x_platform.h +++ b/client/x11/x_platform.h @@ -31,6 +31,8 @@ public: static void on_focus_in(); static void on_focus_out(); + + static bool is_x_shm_avail(); }; #endif