From: Po Lu Date: Sat, 19 Feb 2022 12:05:18 +0000 (+0800) Subject: Improve portability of alpha channel visual detection X-Git-Tag: emacs-29.0.90~2235 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=88f591f389ba4ac13dd5aebfffa7863805758bcb;p=emacs.git Improve portability of alpha channel visual detection * src/xfns.c (select_visual): Look for PictVisuals with an alpha channel instead of blindly assuming that 32 bit visuals have an alpha channel. (Fx_show_tip): Fix crash on some displays where child is None. * src/xterm.c (x_term_init): Initialize Xrender before calling select_visual. --- diff --git a/src/xfns.c b/src/xfns.c index 0a8d18d9187..b0e7af9d8fa 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -6574,28 +6574,45 @@ select_visual (struct x_display_info *dpyinfo) vinfo_template.screen = XScreenNumberOfScreen (screen); -#if !defined USE_X_TOOLKIT && !(defined USE_GTK && !defined HAVE_GTK3) - /* First attempt to use 32-bit visual if available */ - - vinfo_template.depth = 32; - vinfo_template.class = TrueColor; +#if !defined USE_X_TOOLKIT && !(defined USE_GTK && !defined HAVE_GTK3) \ + && defined HAVE_XRENDER + int i; + XRenderPictFormat *format; - vinfo = XGetVisualInfo (dpy, (VisualScreenMask - | VisualDepthMask - | VisualClassMask), - &vinfo_template, &n_visuals); + /* First attempt to find a visual with an alpha mask if + available. That information is only available when the + render extension is present, and we cannot do much with such + a visual if it isn't. */ - if (n_visuals > 0 && vinfo) + if (dpyinfo->xrender_supported_p) { - dpyinfo->n_planes = vinfo->depth; - dpyinfo->visual = vinfo->visual; - XFree (vinfo); - return; - } + vinfo = XGetVisualInfo (dpy, VisualScreenMask, + &vinfo_template, &n_visuals); + + for (i = 0; i < n_visuals; ++i) + { + format = XRenderFindVisualFormat (dpy, vinfo[i].visual); + + if (format && format->type == PictTypeDirect + && format->direct.alphaMask) + { + dpyinfo->n_planes = vinfo[i].depth; + dpyinfo->visual = vinfo[i].visual; + dpyinfo->pict_format = format; + + XFree (vinfo); + return; + } + } + + if (vinfo) + XFree (vinfo); + } #endif /* !USE_X_TOOLKIT */ - /* 32-bit visual not available, fallback to default visual */ + /* Visual with alpha channel (or the Render extension) not + available, fallback to default visual. */ dpyinfo->visual = DefaultVisualOfScreen (screen); vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual); vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask, @@ -8091,7 +8108,8 @@ Text larger than the specified size is clipped. */) FRAME_DISPLAY_INFO (f)->root_window, FRAME_DISPLAY_INFO (f)->root_window, root_x, root_y, &dest_x_return, - &dest_y_return, &child)) + &dest_y_return, &child) + && child != None) { /* But only if the child is not override-redirect, which can happen if the pointer is above a menu. */ diff --git a/src/xterm.c b/src/xterm.c index 2dc420a8dee..e2ad0b48f58 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -15989,6 +15989,18 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) #else dpyinfo->display->db = xrdb; #endif + +#ifdef HAVE_XRENDER + int event_base, error_base; + dpyinfo->xrender_supported_p + = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base); + + if (dpyinfo->xrender_supported_p) + dpyinfo->xrender_supported_p + = XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major, + &dpyinfo->xrender_minor); +#endif + /* Put the rdb where we can find it in a way that works on all versions. */ dpyinfo->rdb = xrdb; @@ -16004,19 +16016,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) reset_mouse_highlight (&dpyinfo->mouse_highlight); #ifdef HAVE_XRENDER - int event_base, error_base; - dpyinfo->xrender_supported_p - = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base); - - if (dpyinfo->xrender_supported_p) - { - if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major, - &dpyinfo->xrender_minor)) - dpyinfo->xrender_supported_p = false; - else - dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display, - dpyinfo->visual); - } + if (dpyinfo->xrender_supported_p + /* This could already have been initialized by + `select_visual'. */ + && !dpyinfo->pict_format) + dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display, + dpyinfo->visual); #endif #ifdef HAVE_XSYNC