From 607a59f2922b1261920bae94efe4dc87da18d576 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 5 Mar 2019 15:31:51 -0500 Subject: [PATCH] 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. Signed-off-by: Adam Jackson --- src/glx/drisw_glx.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index c63b097a71a..67698d1c450 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,28 @@ 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; + + /* reset this as others read it later */ + xshm_error = 0; + return True; } static struct glx_screen * -- 2.20.1