More behind the scenes transparent speedups around xselect.c
* src/xdisp.c (display_menu_bar): Fix compiler warning about NULL pointer dereference. * src/xfns.c (Fx_begin_drag): Use x_intern_atoms. (Fx_change_window_property): Pass dpyinfo to x_fill_property_data. * src/xselect.c (lisp_data_to_selection_data): Use x_intern_atoms instead of syncing for each atom. (x_fill_property_data, x_send_client_event): Use x_intern_cached_atom. * src/xterm.c (x_intern_atoms): New function. * src/xterm.h: Update prototypes.
This commit is contained in:
parent
a67ed9a403
commit
64044f545a
5 changed files with 98 additions and 26 deletions
23
src/xdisp.c
23
src/xdisp.c
|
@ -26312,13 +26312,17 @@ display_menu_bar (struct window *w)
|
|||
it.first_visible_x = 0;
|
||||
it.last_visible_x = FRAME_PIXEL_WIDTH (f);
|
||||
#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
|
||||
struct window *menu_w;
|
||||
struct window *menu_window;
|
||||
|
||||
menu_window = NULL;
|
||||
|
||||
if (FRAME_WINDOW_P (f))
|
||||
{
|
||||
/* Menu bar lines are displayed in the desired matrix of the
|
||||
dummy window menu_bar_window. */
|
||||
menu_w = XWINDOW (f->menu_bar_window);
|
||||
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
|
||||
menu_window = XWINDOW (f->menu_bar_window);
|
||||
init_iterator (&it, menu_window, -1, -1,
|
||||
menu_window->desired_matrix->rows,
|
||||
MENU_FACE_ID);
|
||||
it.first_visible_x = 0;
|
||||
it.last_visible_x = FRAME_PIXEL_WIDTH (f);
|
||||
|
@ -26379,11 +26383,16 @@ display_menu_bar (struct window *w)
|
|||
#if defined (HAVE_X_WINDOWS) && !defined (USE_X_TOOLKIT) && !defined (USE_GTK)
|
||||
/* With the non-toolkit version, modify the menu bar window height
|
||||
accordingly. */
|
||||
if (FRAME_WINDOW_P (it.f))
|
||||
if (FRAME_WINDOW_P (it.f) && menu_window)
|
||||
{
|
||||
struct glyph_row *row = it.glyph_row;
|
||||
int delta_height = ((row->y + row->height)
|
||||
- WINDOW_BOX_HEIGHT_NO_MODE_LINE (menu_w));
|
||||
struct glyph_row *row;
|
||||
int delta_height;
|
||||
|
||||
row = it.glyph_row;
|
||||
delta_height
|
||||
= ((row->y + row->height)
|
||||
- WINDOW_BOX_HEIGHT_NO_MODE_LINE (menu_window));
|
||||
|
||||
if (delta_height != 0)
|
||||
{
|
||||
FRAME_MENU_BAR_HEIGHT (it.f) += delta_height;
|
||||
|
|
|
@ -7079,8 +7079,8 @@ that mouse buttons are being held down, such as immediately after a
|
|||
/* Catch errors since interning lots of targets can potentially
|
||||
generate a BadAlloc error. */
|
||||
x_catch_errors (FRAME_X_DISPLAY (f));
|
||||
XInternAtoms (FRAME_X_DISPLAY (f), target_names,
|
||||
ntargets, False, target_atoms);
|
||||
x_intern_atoms (FRAME_DISPLAY_INFO (f), target_names,
|
||||
ntargets, target_atoms);
|
||||
x_check_errors (FRAME_X_DISPLAY (f),
|
||||
"Failed to intern target atoms: %s");
|
||||
x_uncatch_errors_after_check ();
|
||||
|
@ -7484,7 +7484,7 @@ silently ignored. */)
|
|||
elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
|
||||
data = xnmalloc (nelements, elsize);
|
||||
|
||||
x_fill_property_data (FRAME_X_DISPLAY (f), value, data, nelements,
|
||||
x_fill_property_data (FRAME_DISPLAY_INFO (f), value, data, nelements,
|
||||
element_format);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2216,7 +2216,12 @@ static void
|
|||
lisp_data_to_selection_data (struct x_display_info *dpyinfo,
|
||||
Lisp_Object obj, struct selection_data *cs)
|
||||
{
|
||||
Lisp_Object type = Qnil;
|
||||
Lisp_Object type;
|
||||
char **name_buffer;
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
type = Qnil;
|
||||
|
||||
eassert (cs != NULL);
|
||||
|
||||
|
@ -2321,8 +2326,19 @@ lisp_data_to_selection_data (struct x_display_info *dpyinfo,
|
|||
x_atoms = data;
|
||||
cs->format = 32;
|
||||
cs->size = size;
|
||||
for (i = 0; i < size; i++)
|
||||
x_atoms[i] = symbol_to_x_atom (dpyinfo, AREF (obj, i));
|
||||
|
||||
if (size == 1)
|
||||
x_atoms[0] = symbol_to_x_atom (dpyinfo, AREF (obj, i));
|
||||
else
|
||||
{
|
||||
SAFE_NALLOCA (name_buffer, sizeof *x_atoms, size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
name_buffer[i] = SSDATA (SYMBOL_NAME (AREF (obj, i)));
|
||||
|
||||
x_intern_atoms (dpyinfo, name_buffer, size,
|
||||
x_atoms);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* This vector is an INTEGER set, or something like it */
|
||||
|
@ -2364,6 +2380,8 @@ lisp_data_to_selection_data (struct x_display_info *dpyinfo,
|
|||
signal_error (/* Qselection_error */ "Unrecognized selection data", obj);
|
||||
|
||||
cs->type = symbol_to_x_atom (dpyinfo, type);
|
||||
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
|
@ -2891,8 +2909,8 @@ x_check_property_data (Lisp_Object data)
|
|||
XClientMessageEvent). */
|
||||
|
||||
void
|
||||
x_fill_property_data (Display *dpy, Lisp_Object data, void *ret,
|
||||
int nelements_max, int format)
|
||||
x_fill_property_data (struct x_display_info *dpyinfo, Lisp_Object data,
|
||||
void *ret, int nelements_max, int format)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned long *d32 = (unsigned long *) ret;
|
||||
|
@ -2927,7 +2945,7 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret,
|
|||
else if (STRINGP (o))
|
||||
{
|
||||
block_input ();
|
||||
val = XInternAtom (dpy, SSDATA (o), False);
|
||||
val = x_intern_cached_atom (dpyinfo, SSDATA (o), false);
|
||||
unblock_input ();
|
||||
}
|
||||
else
|
||||
|
@ -3215,7 +3233,7 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
|
|||
|
||||
memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
|
||||
/* event.xclient.data can hold 20 chars, 10 shorts, or 5 longs. */
|
||||
x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
|
||||
x_fill_property_data (dpyinfo, values, event.xclient.data.b,
|
||||
5 * 32 / event.xclient.format,
|
||||
event.xclient.format);
|
||||
|
||||
|
|
47
src/xterm.c
47
src/xterm.c
|
@ -28875,6 +28875,53 @@ x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
|
|||
return value;
|
||||
}
|
||||
|
||||
/* Intern an array of atoms, and do so quickly, avoiding extraneous
|
||||
roundtrips to the X server.
|
||||
|
||||
Avoid sending atoms that have already been found to the X server.
|
||||
This cannot do anything that will end up triggering garbage
|
||||
collection. */
|
||||
|
||||
void
|
||||
x_intern_atoms (struct x_display_info *dpyinfo, char **names, int count,
|
||||
Atom *atoms_return)
|
||||
{
|
||||
int i, j, indices[256];
|
||||
char *new_names[256];
|
||||
Atom results[256], candidate;
|
||||
|
||||
if (count > 256)
|
||||
/* Atoms array too big to inspect reasonably, just send it to the
|
||||
server and back. */
|
||||
XInternAtoms (dpyinfo->display, new_names, count, False, atoms_return);
|
||||
else
|
||||
{
|
||||
for (i = 0, j = 0; i < count; ++i)
|
||||
{
|
||||
candidate = x_intern_cached_atom (dpyinfo, names[i],
|
||||
true);
|
||||
|
||||
if (candidate)
|
||||
atoms_return[i] = candidate;
|
||||
else
|
||||
{
|
||||
indices[j++] = i;
|
||||
new_names[j - 1] = names[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!j)
|
||||
return;
|
||||
|
||||
/* Now, get the results back from the X server. */
|
||||
XInternAtoms (dpyinfo->display, new_names, j, False,
|
||||
results);
|
||||
|
||||
for (i = 0; i < j; ++i)
|
||||
atoms_return[indices[i]] = results[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_GTK
|
||||
|
||||
/* Set up XEmbed for F, and change its save set to handle the parent
|
||||
|
|
16
src/xterm.h
16
src/xterm.h
|
@ -1723,6 +1723,11 @@ extern Lisp_Object x_handle_translate_coordinates (struct frame *, Lisp_Object,
|
|||
|
||||
extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *,
|
||||
int *, int *, int *, unsigned int *);
|
||||
extern Atom x_intern_cached_atom (struct x_display_info *, const char *,
|
||||
bool);
|
||||
extern void x_intern_atoms (struct x_display_info *, char **, int, Atom *);
|
||||
extern char *x_get_atom_name (struct x_display_info *, Atom, bool *)
|
||||
ATTRIBUTE_MALLOC ATTRIBUTE_DEALLOC_FREE;
|
||||
|
||||
#ifdef HAVE_GTK3
|
||||
extern void x_scroll_bar_configure (GdkEvent *);
|
||||
|
@ -1815,11 +1820,8 @@ extern bool x_handle_dnd_message (struct frame *,
|
|||
struct input_event *,
|
||||
bool, int, int);
|
||||
extern int x_check_property_data (Lisp_Object);
|
||||
extern void x_fill_property_data (Display *,
|
||||
Lisp_Object,
|
||||
void *,
|
||||
int,
|
||||
int);
|
||||
extern void x_fill_property_data (struct x_display_info *, Lisp_Object,
|
||||
void *, int, int);
|
||||
extern Lisp_Object x_property_data_to_lisp (struct frame *,
|
||||
const unsigned char *,
|
||||
Atom,
|
||||
|
@ -1832,10 +1834,6 @@ extern Lisp_Object x_timestamp_for_selection (struct x_display_info *,
|
|||
Lisp_Object);
|
||||
extern void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object,
|
||||
Lisp_Object, Time);
|
||||
extern Atom x_intern_cached_atom (struct x_display_info *, const char *,
|
||||
bool);
|
||||
extern char *x_get_atom_name (struct x_display_info *, Atom, bool *)
|
||||
ATTRIBUTE_MALLOC ATTRIBUTE_DEALLOC_FREE;
|
||||
|
||||
extern void mark_xselect (void);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue