[cairo-commit] 2 commits - src/cairo-xlib-display.c src/cairo-xlib-private.h src/cairo-xlib-surface-shm.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Oct 26 03:33:37 PDT 2012
src/cairo-xlib-display.c | 2 -
src/cairo-xlib-private.h | 7 +++
src/cairo-xlib-surface-shm.c | 77 ++++++++++++++++++++++++++++++++++++++-----
3 files changed, 77 insertions(+), 9 deletions(-)
New commits:
commit fdd2082f923012a1354be7086d03f78fb166695b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 26 10:51:31 2012 +0100
xlib: Check for both X.org and Xorg ServerVendors
Martin Husemann reported that on his NetBSD machine the vendor was being
reported as "The Xorg Foundation", a non-conformist separatist split of
the Peoples' Liberation Army^W^W^W "The X.Org Foundation". Simply check
for both during initialisation.
Reported-by: Martin Husemann <martin at duskware.de>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 67c0673..04c89b2 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -315,7 +315,7 @@ _cairo_xlib_device_create (Display *dpy)
* safest to just blacklist all old-versioning-scheme X servers,
* (just using VendorRelease < 70000000), as buggy_repeat=TRUE.
*/
- if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
+ if (_cairo_xlib_vendor_is_xorg (dpy)) {
if (VendorRelease (dpy) >= 60700000) {
if (VendorRelease (dpy) < 70000000)
display->buggy_repeat = TRUE;
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index d2bd588..c328302 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -216,6 +216,13 @@ struct _cairo_xlib_proxy {
cairo_surface_t *owner;
};
+inline static cairo_bool_t
+_cairo_xlib_vendor_is_xorg (Display *dpy)
+{
+ const char *const vendor = ServerVendor (dpy);
+ return strstr (vendor, "X.Org") || strstr (vendor, "Xorg");
+}
+
cairo_private cairo_status_t
_cairo_xlib_surface_get_gc (cairo_xlib_display_t *display,
cairo_xlib_surface_t *surface,
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index 17594b1..89f51a9 100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -1193,7 +1193,7 @@ xorg_has_buggy_send_shm_completion_event(cairo_xlib_display_t *display,
*
* Remove the SendEvent bit (0x80) before doing range checks on event type.
*/
- if (strstr (ServerVendor (dpy), "X.Org") != NULL &&
+ if (_cairo_xlib_vendor_is_xorg (dpy) &&
VendorRelease (dpy) < XORG_VERSION_ENCODE(1,11,0,1))
return TRUE;
commit 00feb8ce530a472abbde445b52d9ae8c99ec97f0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 26 10:51:31 2012 +0100
xlib/shm: Sanity check that the server handles XSendEvent with ShmCompletion
Uli Schlachter suggested it would be wiser to complement our blacklist
of known broken X/libXext with an explicit roundtrip to check for a
BadValue error return when we try to use XSendEvent.
Suggested-by: Uli Schlachter <psychon at znc.in>
Reported-by: Martin Husemann <martin at duskware.de>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index ec0d334..17594b1 100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -1128,8 +1128,60 @@ _cairo_xlib_shm_surface_is_idle (cairo_surface_t *surface)
(((major) * 10000000) + ((minor) * 100000) + ((patch) * 1000) + snap)
static cairo_bool_t
-xorg_has_buggy_send_shm_completion_event(Display *dpy)
+has_broken_send_shm_event (cairo_xlib_display_t *display,
+ cairo_xlib_shm_display_t *shm)
{
+ Display *dpy = display->display;
+ int (*old_handler) (Display *display, XErrorEvent *event);
+ XShmCompletionEvent ev;
+ XShmSegmentInfo info;
+
+ info.shmid = shmget (IPC_PRIVATE, 0x1000, IPC_CREAT | 0600);
+ if (info.shmid == -1)
+ return TRUE;
+
+ info.readOnly = FALSE;
+ info.shmaddr = shmat (info.shmid, NULL, 0);
+ if (info.shmaddr == (char *) -1) {
+ shmctl (info.shmid, IPC_RMID, NULL);
+ return TRUE;
+ }
+
+ ev.type = shm->event;
+ ev.drawable = shm->window;
+ ev.major_code = shm->opcode;
+ ev.minor_code = X_ShmPutImage;
+
+ ev.shmseg = info.shmid;
+ ev.offset = 0;
+
+ assert (CAIRO_MUTEX_IS_LOCKED (_cairo_xlib_display_mutex));
+ _x_error_occurred = FALSE;
+
+ XLockDisplay (dpy);
+ XSync (dpy, False);
+ old_handler = XSetErrorHandler (_check_error_handler);
+
+ XShmAttach (dpy, &info);
+ XSendEvent (dpy, ev.drawable, False, 0, (XEvent *)&ev);
+ XShmDetach (dpy, &info);
+
+ XSync (dpy, False);
+ XSetErrorHandler (old_handler);
+ XUnlockDisplay (dpy);
+
+ shmctl (info.shmid, IPC_RMID, NULL);
+ shmdt (info.shmaddr);
+
+ return _x_error_occurred;
+}
+
+static cairo_bool_t
+xorg_has_buggy_send_shm_completion_event(cairo_xlib_display_t *display,
+ cairo_xlib_shm_display_t *shm)
+{
+ Display *dpy = display->display;
+
/* As libXext sets the SEND_EVENT bit in the ShmCompletionEvent,
* the Xserver may crash if it does not take care when processing
* the event type. For instance versions of Xorg prior to 1.11.1
@@ -1141,8 +1193,12 @@ xorg_has_buggy_send_shm_completion_event(Display *dpy)
*
* Remove the SendEvent bit (0x80) before doing range checks on event type.
*/
- return (strstr (ServerVendor (dpy), "X.Org") != NULL &&
- VendorRelease (dpy) < XORG_VERSION_ENCODE(1,11,0,1));
+ if (strstr (ServerVendor (dpy), "X.Org") != NULL &&
+ VendorRelease (dpy) < XORG_VERSION_ENCODE(1,11,0,1))
+ return TRUE;
+
+ /* For everyone else check that no error is generated */
+ return has_broken_send_shm_event (display, shm);
}
void
@@ -1162,6 +1218,15 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display)
if (unlikely (shm == NULL))
return;
+ codes = XInitExtension (display->display, SHMNAME);
+ if (codes == NULL) {
+ free (shm);
+ return;
+ }
+
+ shm->opcode = codes ->major_opcode;
+ shm->event = codes->first_event;
+
if (unlikely (_pqueue_init (&shm->info))) {
free (shm);
return;
@@ -1177,16 +1242,12 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display)
DefaultVisual (display->display, scr),
CWOverrideRedirect, &attr);
- if (xorg_has_buggy_send_shm_completion_event(display->display))
+ if (xorg_has_buggy_send_shm_completion_event(display, shm))
has_pixmap = 0;
shm->has_pixmaps = has_pixmap ? MIN_PIXMAP_SIZE : 0;
cairo_list_init (&shm->pool);
- codes = XInitExtension (display->display, SHMNAME);
- shm->opcode = codes ->major_opcode;
- shm->event = codes->first_event;
-
cairo_list_init (&shm->surfaces);
display->shm = shm;
More information about the cairo-commit
mailing list