{
struct x_client_list_window *last;
struct x_client_list_window *tem = x_dnd_toplevels;
+ ptrdiff_t n_windows, i, buffer_size;
+ Window *destroy_windows;
+ unsigned long *prev_masks;
+ specpdl_ref count;
+ Display *dpy;
+
+ if (!x_dnd_toplevels)
+ /* Probably called inside an IO error handler. */
+ return;
+ /* Pacify GCC. */
+ prev_masks = NULL;
+ destroy_windows = NULL;
+
+ if (display_alive)
+ {
+ buffer_size = 1024;
+ destroy_windows = xmalloc (sizeof *destroy_windows
+ * buffer_size);
+ prev_masks = xmalloc (sizeof *prev_masks *
+ buffer_size);
+ n_windows = 0;
+ }
+
+ block_input ();
while (tem)
{
last = tem;
if (display_alive)
{
- x_catch_errors (last->dpy);
- XSelectInput (last->dpy, last->window,
- last->previous_event_mask);
-#ifdef HAVE_XSHAPE
- XShapeSelectInput (last->dpy, last->window, None);
-#endif
- x_uncatch_errors ();
+ if (++n_windows >= buffer_size)
+ {
+ buffer_size += 1024;
+ destroy_windows
+ = xrealloc (destroy_windows, (sizeof *destroy_windows
+ * buffer_size));
+ prev_masks
+ = xrealloc (prev_masks, (sizeof *prev_masks
+ * buffer_size));
+ }
+
+ dpy = last->dpy;
+ prev_masks[n_windows - 1] = last->previous_event_mask;
+ destroy_windows[n_windows - 1] = last->window;
}
#ifdef HAVE_XSHAPE
}
x_dnd_toplevels = NULL;
+
+ if (!display_alive)
+ {
+ unblock_input ();
+ return;
+ }
+
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (xfree, destroy_windows);
+ record_unwind_protect_ptr (xfree, prev_masks);
+
+ if (display_alive)
+ {
+ x_catch_errors (dpy);
+
+ for (i = 0; i < n_windows; ++i)
+ {
+ XSelectInput (dpy, destroy_windows[i], prev_masks[i]);
+#ifdef HAVE_XSHAPE
+ XShapeSelectInput (dpy, destroy_windows[i], None);
+#endif
+ }
+
+ x_uncatch_errors ();
+ }
+
+ unbind_to (count, Qnil);
+ unblock_input ();
}
static int
unblock_input ();
}
+ /* This shouldn't happen. */
+ if (x_dnd_toplevels)
+ x_dnd_free_toplevels (true);
+
x_dnd_in_progress = true;
x_dnd_frame = f;
x_dnd_last_seen_window = None;
FRAME_DISPLAY_INFO (f)->Xatom_XdndSelection);
unblock_input ();
+ if (x_dnd_use_toplevels)
+ x_dnd_free_toplevels (true);
+
if (x_dnd_return_frame == 3
&& FRAME_LIVE_P (x_dnd_return_frame_object))
{
}
x_dnd_return_frame_object = NULL;
-
- if (x_dnd_use_toplevels)
- x_dnd_free_toplevels (true);
FRAME_DISPLAY_INFO (f)->grabbed = 0;
/* Emacs can't respond to DND events inside the nested event