return false;
}
\f
-#define X_ERROR_MESSAGE_SIZE 200
struct x_error_message_stack
{
- /* Buffer containing the error message of any error that was
- generated. */
- char string[X_ERROR_MESSAGE_SIZE];
+ /* Pointer to the error message of any error that was generated, or
+ NULL. */
+ char *string;
/* The display this error handler applies to. */
Display *dpy;
placed before 2006. */
static struct x_error_message_stack *x_error_message;
+/* The amount of items (depth) in that stack. */
+int x_error_message_count;
+
static struct x_error_message_stack *
x_find_error_handler (Display *dpy, XErrorEvent *event)
{
return NULL;
}
+void
+x_unwind_errors_to (int depth)
+{
+ while (x_error_message_count > depth)
+ /* This is safe to call because we check whether or not
+ x_error_message->dpy is still alive before calling XSync. */
+ x_uncatch_errors ();
+}
+
+#define X_ERROR_MESSAGE_SIZE 200
+
/* An X error handler which stores the error message in the first
applicable handler in the x_error_message stack. This is called
from *x_error_handler if an x_catch_errors for DISPLAY is in
x_error_catcher (Display *display, XErrorEvent *event,
struct x_error_message_stack *stack)
{
+ char buf[X_ERROR_MESSAGE_SIZE];
+
XGetErrorText (display, event->error_code,
- stack->string, X_ERROR_MESSAGE_SIZE);
+ buf, X_ERROR_MESSAGE_SIZE);
+
+ if (stack->string)
+ xfree (stack->string);
+
+ stack->string = xstrdup (buf);
if (stack->handler)
stack->handler (display, event, stack->string,
x_catch_errors_with_handler (Display *dpy, x_special_error_handler handler,
void *handler_data)
{
- struct x_error_message_stack *data = xmalloc (sizeof *data);
+ struct x_error_message_stack *data;
+ data = xzalloc (sizeof *data);
data->dpy = dpy;
- data->string[0] = 0;
data->handler = handler;
data->handler_data = handler_data;
data->prev = x_error_message;
data->first_request = NextRequest (dpy);
x_error_message = data;
+
+ ++x_error_message_count;
}
void
block_input ();
tmp = x_error_message;
x_error_message = x_error_message->prev;
+ --x_error_message_count;
+ if (tmp->string)
+ xfree (tmp->string);
xfree (tmp);
unblock_input ();
}
tmp = x_error_message;
x_error_message = x_error_message->prev;
+ --x_error_message_count;
+ if (tmp->string)
+ xfree (tmp->string);
xfree (tmp);
unblock_input ();
}
void
x_check_errors (Display *dpy, const char *format)
{
- char string[X_ERROR_MESSAGE_SIZE];
+ char *string;
/* This shouldn't happen, since x_check_errors should be called
immediately inside an x_catch_errors block. */
> x_error_message->first_request))
XSync (dpy, False);
- if (x_error_message->string[0])
+ if (x_error_message->string)
{
- memcpy (string, x_error_message->string,
- X_ERROR_MESSAGE_SIZE);
- x_uncatch_errors ();
+ string = alloca (strlen (x_error_message->string) + 1);
+ strcpy (string, x_error_message->string);
+
error (format, string);
}
}
> x_error_message->first_request))
XSync (dpy, False);
- return x_error_message->string[0] != 0;
+ return x_error_message->string;
}
/* Forget about any errors we have had, since we did x_catch_errors on
if (dpy != x_error_message->dpy)
emacs_abort ();
- x_error_message->string[0] = 0;
+ xfree (x_error_message->string);
+ x_error_message->string = NULL;
}
#if false
dpyinfo->display = 0;
}
+ /* delete_frame can still try to read async input (even though we
+ tell pass `noelisp'), because looking up the `delete-before'
+ parameter calls Fassq which then calls maybe_quit. So block
+ input while deleting frames. */
+ block_input ();
+
/* First delete frames whose mini-buffers are on frames
that are on the dead display. */
FOR_EACH_FRAME (tail, frame)
}
}
+ unblock_input ();
+
if (terminal_list == 0)
{
fprintf (stderr, "%s\n", error_msg);