]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve portability of alpha channel visual detection
authorPo Lu <luangruo@yahoo.com>
Sat, 19 Feb 2022 12:05:18 +0000 (20:05 +0800)
committerPo Lu <luangruo@yahoo.com>
Sat, 19 Feb 2022 12:07:54 +0000 (20:07 +0800)
* 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.

src/xfns.c
src/xterm.c

index 0a8d18d91875ea55c1c4e5c901fa08e19572b2a7..b0e7af9d8fa6b51000507d7be6020e974037407b 100644 (file)
@@ -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.  */
index 2dc420a8deefd39be1e75511d55d3a602130b9c4..e2ad0b48f581e156f1336cc24af8bcd1f2352231 100644 (file)
@@ -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