summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Jackson <[email protected]>2019-03-05 15:31:51 -0500
committerDave Airlie <[email protected]>2019-04-09 09:50:24 +1000
commit52426ce4a929f7e1389baf490967fc02357b3f5e (patch)
treeffe79243fcaafba92cefb16091068619de126ae4
parent50f3535d1fb7c377b800e80a838dcfcbda4699df (diff)
drisw: Try harder to probe whether MIT-SHM works
XQueryExtension merely tells you whether the extension exists, it doesn't tell you whether you're local enough for it to work. XShmQueryVersion is not enough to discover this either, you need to provoke the server to do actual work, and if it thinks you're remote it will throw BadRequest at you. So send an invalid ShmDetach and use the error code to distinguish local from remote. [airlied: fixed bug not resetting xshm_error to 0 on success, which made later stuff fail completely.] Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Dave Airlie <[email protected]> Signed-off-by: Adam Jackson <[email protected]>
-rw-r--r--src/glx/drisw_glx.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index c63b097a71a..f38dbbca2df 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -73,11 +73,10 @@ handle_xerror(Display *dpy, XErrorEvent *event)
(void) dpy;
assert(xshm_opcode != -1);
- if (event->request_code != xshm_opcode ||
- event->minor_code != X_ShmAttach)
+ if (event->request_code != xshm_opcode)
return 0;
- xshm_error = 1;
+ xshm_error = event->error_code;
return 0;
}
@@ -826,9 +825,27 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
static int
check_xshm(Display *dpy)
{
+ int (*old_handler)(Display *, XErrorEvent *);
+
int ignore;
+ XShmSegmentInfo info = { 0, };
+
+ if (!XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore))
+ return False;
+
+ old_handler = XSetErrorHandler(handle_xerror);
+ XShmDetach(dpy, &info);
+ XSync(dpy, False);
+ (void) XSetErrorHandler(old_handler);
- return XQueryExtension(dpy, "MIT-SHM", &xshm_opcode, &ignore, &ignore);
+ /* BadRequest means we're a remote client. If we were local we'd
+ * expect BadValue since 'info' has an invalid segment name.
+ */
+ if (xshm_error == BadRequest)
+ return False;
+
+ xshm_error = 0;
+ return True;
}
static struct glx_screen *