From: Po Lu Date: Wed, 25 May 2022 06:54:47 +0000 (+0800) Subject: Improve atom interning in `x-change-window-property' X-Git-Tag: emacs-29.0.90~1910^2~437 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=9394027fd64b26f9a7b9db5128180638d98af13a;p=emacs.git 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. --- diff --git a/src/xfns.c b/src/xfns.c index 912af0fa5a5..47321a1d6b2 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 5c8221201b1..ae2f4528aff 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 5780f88bbc9..fba775d96b6 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);