emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9394027fd6: Improve atom interning in `x-change-window-property'


From: Po Lu
Subject: master 9394027fd6: Improve atom interning in `x-change-window-property'
Date: Wed, 25 May 2022 02:55:32 -0400 (EDT)

branch: master
commit 9394027fd64b26f9a7b9db5128180638d98af13a
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Improve atom interning in `x-change-window-property'
    
    * src/xfns.c (Fx_change_window_property): Improve doc string and
    use `x_intern_cached_atom'.
    * src/xterm.c (x_intern_cached_atom): New argument
    `predefined_only'.  All callers changed.
    * src/xterm.h: Update prototypes.
---
 src/xfns.c  | 104 +++++++++++++++++++++++++++++++++++++++---------------------
 src/xterm.c |   8 +++--
 src/xterm.h |   3 +-
 3 files changed, 76 insertions(+), 39 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index 912af0fa5a..47321a1d6b 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -7246,19 +7246,28 @@ converted to an atom and the value of the atom is used. 
 If an element
 is a cons, it is converted to a 32 bit number where the car is the 16
 top bits and the cdr is the lower 16 bits.
 
-FRAME nil or omitted means use the selected frame.
-If TYPE is given and non-nil, it is the name of the type of VALUE.
- If TYPE is not given or nil, the type is STRING.
-FORMAT gives the size in bits of each element if VALUE is a list.
- It must be one of 8, 16 or 32.
- If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
-If OUTER-P is non-nil, the property is changed for the outer X window of
- FRAME.  Default is to change on the edit X window.
-If WINDOW-ID is non-nil, change the property of that window instead
- of FRAME's X window; the number 0 denotes the root window.  This argument
- is separate from FRAME because window IDs are not unique across X
- displays or screens on the same display, so FRAME provides context
- for the window ID. */)
+FRAME nil or omitted means use the selected frame.  If TYPE is given
+and non-nil, it is the name of the type of VALUE.  If TYPE is not
+given or nil, the type is STRING.
+
+FORMAT gives the size in bits of each element if VALUE is a list.  It
+must be one of 8, 16 or 32.
+
+If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to
+8.  If OUTER-P is non-nil, the property is changed for the outer X
+window of FRAME.  Default is to change on the edit X window.
+
+If WINDOW-ID is non-nil, change the property of that window instead of
+FRAME's X window; the number 0 denotes the root window.  This argument
+is separate from FRAME because window IDs are not unique across X
+displays or screens on the same display, so FRAME provides context for
+the window ID.
+
+If VALUE is a string and FORMAT is 32, then the format of VALUE is
+system-specific.  VALUE must contain unsigned integer data in native
+endian-ness in multiples of the size of the C type 'long': the low 32
+bits of each such number are used as the value of each element of the
+property.  */)
   (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
    Lisp_Object type, Lisp_Object format, Lisp_Object outer_p,
    Lisp_Object window_id)
@@ -7271,6 +7280,8 @@ If WINDOW-ID is non-nil, change the property of that 
window instead
   int nelements;
   Window target_window;
 #ifdef USE_XCB
+  bool intern_prop;
+  bool intern_target;
   xcb_intern_atom_cookie_t prop_atom_cookie;
   xcb_intern_atom_cookie_t target_type_cookie;
   xcb_intern_atom_reply_t *reply;
@@ -7341,41 +7352,62 @@ If WINDOW-ID is non-nil, change the property of that 
window instead
 
   block_input ();
 #ifndef USE_XCB
-  prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
+  prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
+                                   SSDATA (prop), false);
   if (! NILP (type))
     {
       CHECK_STRING (type);
-      target_type = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (type), False);
+      target_type = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
+                                         SSDATA (type), false);
     }
 #else
   rc = true;
-  prop_atom_cookie
-    = xcb_intern_atom (FRAME_DISPLAY_INFO (f)->xcb_connection,
-                      0, SBYTES (prop), SSDATA (prop));
+  intern_target = true;
+  intern_prop = true;
+
+  prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
+                                   SSDATA (prop), true);
+
+  if (prop_atom != None)
+    intern_prop = false;
+  else
+    prop_atom_cookie
+      = xcb_intern_atom (FRAME_DISPLAY_INFO (f)->xcb_connection,
+                        0, SBYTES (prop), SSDATA (prop));
 
   if (!NILP (type))
     {
       CHECK_STRING (type);
-      target_type_cookie
-       = xcb_intern_atom (FRAME_DISPLAY_INFO (f)->xcb_connection,
-                          0, SBYTES (type), SSDATA (type));
-    }
 
-  reply = xcb_intern_atom_reply (FRAME_DISPLAY_INFO (f)->xcb_connection,
-                                prop_atom_cookie, &generic_error);
+      target_type = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
+                                         SSDATA (type), true);
 
-  if (reply)
-    {
-      prop_atom = (Atom) reply->atom;
-      free (reply);
+      if (target_type)
+       intern_target = false;
+      else
+       target_type_cookie
+         = xcb_intern_atom (FRAME_DISPLAY_INFO (f)->xcb_connection,
+                            0, SBYTES (type), SSDATA (type));
     }
-  else
+
+  if (intern_prop)
     {
-      free (generic_error);
-      rc = false;
+      reply = xcb_intern_atom_reply (FRAME_DISPLAY_INFO (f)->xcb_connection,
+                                    prop_atom_cookie, &generic_error);
+
+      if (reply)
+       {
+         prop_atom = (Atom) reply->atom;
+         free (reply);
+       }
+      else
+       {
+         free (generic_error);
+         rc = false;
+       }
     }
 
-  if (!NILP (type))
+  if (!NILP (type) && intern_target)
     {
       reply = xcb_intern_atom_reply (FRAME_DISPLAY_INFO (f)->xcb_connection,
                                     target_type_cookie, &generic_error);
@@ -7439,7 +7471,7 @@ Value is PROP.  */)
 
   block_input ();
   prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
-                                   SSDATA (prop));
+                                   SSDATA (prop), false);
 
   x_catch_errors (FRAME_X_DISPLAY (f));
   XDeleteProperty (FRAME_X_DISPLAY (f), target_window, prop_atom);
@@ -7575,11 +7607,11 @@ if PROP has no value of TYPE (always a string in the MS 
Windows case). */)
         target_type = AnyPropertyType;
       else
         target_type = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
-                                           SSDATA (type));
+                                           SSDATA (type), false);
     }
 
   prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
-                                   SSDATA (prop));
+                                   SSDATA (prop), false);
   prop_value = x_window_property_intern (f,
                                          target_window,
                                          prop_atom,
@@ -7651,7 +7683,7 @@ Otherwise, the return value is a vector with the 
following fields:
 
   x_catch_errors (FRAME_X_DISPLAY (f));
   prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
-                                   SSDATA (prop));
+                                   SSDATA (prop), false);
   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
                           prop_atom, 0, 0, False, AnyPropertyType,
                           &actual_type, &actual_format, &actual_size,
diff --git a/src/xterm.c b/src/xterm.c
index 5c8221201b..ae2f4528af 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -23599,10 +23599,11 @@ x_destroy_window (struct frame *f)
 }
 
 /* Intern NAME in DPYINFO, but check to see if the atom was already
-   interned, and use that instead.  */
+   interned, and use that instead.  If PREDEFINED_ONLY, return None if
+   the atom was not already interned at connection setup.  */
 Atom
 x_intern_cached_atom (struct x_display_info *dpyinfo,
-                     const char *name)
+                     const char *name, bool predefined_only)
 {
   int i;
   char *ptr;
@@ -23649,6 +23650,9 @@ x_intern_cached_atom (struct x_display_info *dpyinfo,
        }
     }
 
+  if (predefined_only)
+    return None;
+
   return XInternAtom (dpyinfo->display, name, False);
 }
 
diff --git a/src/xterm.h b/src/xterm.h
index 5780f88bbc..fba775d96b 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1536,7 +1536,8 @@ extern Lisp_Object x_timestamp_for_selection (struct 
x_display_info *,
                                              Lisp_Object);
 extern void x_set_pending_dnd_time (Time);
 extern void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object);
-extern Atom x_intern_cached_atom (struct x_display_info *, const char *);
+extern Atom x_intern_cached_atom (struct x_display_info *, const char *,
+                                 bool);
 
 #ifdef USE_GTK
 extern bool xg_set_icon (struct frame *, Lisp_Object);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]