]> git.eshelyaron.com Git - emacs.git/commitdiff
Avoid calling XGetAtomName in a loop when fetching monitor attributes
authorPo Lu <luangruo@yahoo.com>
Wed, 30 Mar 2022 01:17:58 +0000 (09:17 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 30 Mar 2022 01:17:58 +0000 (09:17 +0800)
* src/xfns.c (x_get_monitor_attributes_xrandr): Avoid syncing on
each monitor when waiting for XGetAtomName when built with XCB.

src/xfns.c

index 37e0628464fa058ad7ea1eee495979172ecd9149..4fa919f36a5b968e665cd2d53247fb07b5341f5e 100644 (file)
@@ -5768,6 +5768,12 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
 
 #if RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 5)
   XRRMonitorInfo *rr_monitors;
+#ifdef USE_XCB
+  xcb_get_atom_name_cookie_t *atom_name_cookies;
+  xcb_get_atom_name_reply_t *reply;
+  xcb_generic_error_t *error;
+  int length;
+#endif
 
   /* If RandR 1.5 or later is available, use that instead, as some
      video drivers don't report correct dimensions via other versions
@@ -5786,6 +5792,9 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
        goto fallback;
 
       monitors = xzalloc (n_monitors * sizeof *monitors);
+#ifdef USE_XCB
+      atom_name_cookies = alloca (n_monitors * sizeof *atom_name_cookies);
+#endif
 
       for (int i = 0; i < n_monitors; ++i)
        {
@@ -5796,6 +5805,7 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
          monitors[i].mm_width = rr_monitors[i].mwidth;
          monitors[i].mm_height = rr_monitors[i].mheight;
 
+#ifndef USE_XCB
          name = XGetAtomName (dpyinfo->display, rr_monitors[i].name);
          if (name)
            {
@@ -5804,6 +5814,11 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
            }
          else
            monitors[i].name = xstrdup ("Unknown Monitor");
+#else
+         atom_name_cookies[i]
+           = xcb_get_atom_name (dpyinfo->xcb_connection,
+                                (xcb_atom_t) rr_monitors[i].name);
+#endif
 
          if (rr_monitors[i].primary)
            primary = i;
@@ -5821,6 +5836,29 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
            monitors[i].work = monitors[i].geom;
        }
 
+#ifdef USE_XCB
+      for (int i = 0; i < n_monitors; ++i)
+       {
+         reply = xcb_get_atom_name_reply (dpyinfo->xcb_connection,
+                                          atom_name_cookies[i], &error);
+
+         if (!reply)
+           {
+             monitors[i].name = xstrdup ("Unknown monitor");
+             free (error);
+           }
+         else
+           {
+             length = xcb_get_atom_name_name_length (reply);
+             name = xmalloc (length + 1);
+             memcpy (name, xcb_get_atom_name_name (reply), length);
+             name[length] = '\0';
+             monitors[i].name = name;
+             free (reply);
+           }
+       }
+#endif
+
       XRRFreeMonitors (rr_monitors);
       randr15_p = true;
       goto out;