changeset 69152:f2147c1027b6

* xterm.h (x_catch_errors) Return value changed to void. (x_uncatch_errors): Unused count argument deleted. * xterm.c (x_catch_errors): Don't use record_unwind_protect, since it can be called in a signal handler. (x_catch_errors_unwind): Function deleted. (x_uncatch_errors): Deallocate last x_error_message_stack struct. (x_check_errors): Call x_uncatch_errors before signalling error. (x_load_font, x_term_init, XTmouse_position, handle_one_xevent) (x_connection_closed, x_list_fonts): Use new versions of x_catch_errors and x_uncatch_errors. * xselect.c (x_own_selection, x_decline_selection_request) (x_reply_selection_request, x_get_foreign_selection) (Fx_get_atom_name, Fx_send_client_event): Likewise. * xfns.c (x_real_positions, x_set_mouse_color, Fx_focus_frame): Likewise. * eval.c (record_unwind_protect): Add an assertion.
author Chong Yidong <cyd@stupidchicken.com>
date Sat, 25 Feb 2006 23:20:10 +0000
parents 08c9c1760e1c
children 1f7111323584
files src/ChangeLog src/eval.c src/xfns.c src/xselect.c src/xterm.c src/xterm.h
diffstat 6 files changed, 95 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Feb 25 16:49:00 2006 +0000
+++ b/src/ChangeLog	Sat Feb 25 23:20:10 2006 +0000
@@ -1,3 +1,27 @@
+2006-02-25  Chong Yidong  <cyd@stupidchicken.com>
+
+	* xterm.h (x_catch_errors) Return value changed to void.
+	(x_uncatch_errors): Unused count argument deleted.
+	
+	* xterm.c (x_catch_errors): Don't use record_unwind_protect, since
+	it can be called in a signal handler.
+	(x_catch_errors_unwind): Function deleted.
+	(x_uncatch_errors): Deallocate last x_error_message_stack struct.
+	(x_check_errors): Call x_uncatch_errors before signalling error.
+
+	(x_load_font, x_term_init, XTmouse_position, handle_one_xevent)
+	(x_connection_closed, x_list_fonts): Use new versions of
+	x_catch_errors and x_uncatch_errors.
+
+	* xselect.c (x_own_selection, x_decline_selection_request)
+	(x_reply_selection_request, x_get_foreign_selection)
+	(Fx_get_atom_name, Fx_send_client_event): Likewise.
+
+	* xfns.c (x_real_positions, x_set_mouse_color, Fx_focus_frame):
+	Likewise.
+
+	* eval.c (record_unwind_protect): Add an assertion.
+
 2006-02-25  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* process.c (Fmake_network_process): Init the process's mark.
--- a/src/eval.c	Sat Feb 25 16:49:00 2006 +0000
+++ b/src/eval.c	Sat Feb 25 23:20:10 2006 +0000
@@ -3199,6 +3199,8 @@
      Lisp_Object (*function) P_ ((Lisp_Object));
      Lisp_Object arg;
 {
+  eassert (!handling_signal);
+
   if (specpdl_ptr == specpdl + specpdl_size)
     grow_specpdl ();
   specpdl_ptr->func = function;
--- a/src/xfns.c	Sat Feb 25 16:49:00 2006 +0000
+++ b/src/xfns.c	Sat Feb 25 23:20:10 2006 +0000
@@ -577,11 +577,9 @@
   int had_errors = 0;
   Window win = f->output_data.x->parent_desc;
 
-  int count;
-
   BLOCK_INPUT;
 
-  count = x_catch_errors (FRAME_X_DISPLAY (f));
+  x_catch_errors (FRAME_X_DISPLAY (f));
 
   if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
     win = FRAME_OUTER_WINDOW (f);
@@ -668,7 +666,7 @@
       had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
     }
 
-  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+  x_uncatch_errors (FRAME_X_DISPLAY (f));
 
   UNBLOCK_INPUT;
 
@@ -946,7 +944,6 @@
   Display *dpy = FRAME_X_DISPLAY (f);
   Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
   Cursor hourglass_cursor, horizontal_drag_cursor;
-  int count;
   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   unsigned long mask_color = x->background_pixel;
 
@@ -963,7 +960,7 @@
   BLOCK_INPUT;
 
   /* It's not okay to crash if the user selects a screwy cursor.  */
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   if (!NILP (Vx_pointer_shape))
     {
@@ -1024,7 +1021,7 @@
 
   /* Check and report errors with the above calls.  */
   x_check_errors (dpy, "can't set cursor shape: %s");
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
 
   {
     XColor fore_color, back_color;
@@ -3441,13 +3438,12 @@
 {
   struct frame *f = check_x_frame (frame);
   Display *dpy = FRAME_X_DISPLAY (f);
-  int count;
 
   BLOCK_INPUT;
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
   XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 		  RevertToParent, CurrentTime);
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
   UNBLOCK_INPUT;
 
   return Qnil;
--- a/src/xselect.c	Sat Feb 25 16:49:00 2006 +0000
+++ b/src/xselect.c	Sat Feb 25 23:20:10 2006 +0000
@@ -402,16 +402,15 @@
   Time time = last_event_timestamp;
   Atom selection_atom;
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
-  int count;
 
   CHECK_SYMBOL (selection_name);
   selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
 
   BLOCK_INPUT;
-  count = x_catch_errors (display);
+  x_catch_errors (display);
   XSetSelectionOwner (display, selection_atom, selecting_window, time);
   x_check_errors (display, "Can't set selection: %s");
-  x_uncatch_errors (display, count);
+  x_uncatch_errors (display);
   UNBLOCK_INPUT;
 
   /* Now update the local cache */
@@ -572,7 +571,6 @@
      struct input_event *event;
 {
   XSelectionEvent reply;
-  int count;
 
   reply.type = SelectionNotify;
   reply.display = SELECTION_EVENT_DISPLAY (event);
@@ -585,10 +583,10 @@
   /* The reason for the error may be that the receiver has
      died in the meantime.  Handle that case.  */
   BLOCK_INPUT;
-  count = x_catch_errors (reply.display);
+  x_catch_errors (reply.display);
   XSendEvent (reply.display, reply.requestor, False, 0L, (XEvent *) &reply);
   XFlush (reply.display);
-  x_uncatch_errors (reply.display, count);
+  x_uncatch_errors (reply.display);
   UNBLOCK_INPUT;
 }
 
@@ -690,7 +688,7 @@
   int format_bytes = format/8;
   int max_bytes = SELECTION_QUANTUM (display);
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
-  int count;
+  int count = SPECPDL_INDEX ();
 
   if (max_bytes > MAX_SELECTION_QUANTUM)
     max_bytes = MAX_SELECTION_QUANTUM;
@@ -707,7 +705,7 @@
 
   /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
   BLOCK_INPUT;
-  count = x_catch_errors (display);
+  x_catch_errors (display);
 
 #ifdef TRACE_SELECTION
   {
@@ -860,7 +858,9 @@
      UNBLOCK to enter the event loop and get possible errors delivered,
      and then BLOCK again because x_uncatch_errors requires it.  */
   BLOCK_INPUT;
-  x_uncatch_errors (display, count);
+
+  unbind_to (count, Qnil);
+  x_uncatch_errors (display);
   UNBLOCK_INPUT;
 }
 
@@ -1392,7 +1392,7 @@
 
   BLOCK_INPUT;
 
-  count = x_catch_errors (display);
+  x_catch_errors (display);
 
   TRACE2 ("Get selection %s, type %s",
 	  XGetAtomName (display, type_atom),
@@ -1409,6 +1409,8 @@
 
   frame = some_frame_on_display (dpyinfo);
 
+  count = SPECPDL_INDEX ();
+
   /* If the display no longer has frames, we can't expect
      to get many more selection requests from it, so don't
      bother trying to queue them.  */
@@ -1430,8 +1432,9 @@
   TRACE1 ("  Got event = %d", !NILP (XCAR (reading_selection_reply)));
 
   BLOCK_INPUT;
+  unbind_to (count, Qnil);
   x_check_errors (display, "Cannot get selection: %s");
-  x_uncatch_errors (display, count);
+  x_uncatch_errors (display);
   UNBLOCK_INPUT;
 
   if (NILP (XCAR (reading_selection_reply)))
@@ -2650,7 +2653,6 @@
   struct frame *f = check_x_frame (frame);
   char *name = 0;
   Lisp_Object ret = Qnil;
-  int count;
   Display *dpy = FRAME_X_DISPLAY (f);
   Atom atom;
 
@@ -2664,14 +2666,14 @@
     error ("Wrong type, value must be number or cons");
 
   BLOCK_INPUT;
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   name = atom ? XGetAtomName (dpy, atom) : "";
 
   if (! x_had_errors_p (dpy))
     ret = make_string (name, strlen (name));
 
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
 
   if (atom && name) XFree (name);
   if (NILP (ret)) ret = make_string ("", 0);
@@ -2771,7 +2773,6 @@
   Lisp_Object cons;
   int size;
   struct frame *f = check_x_frame (from);
-  int count;
   int to_root;
 
   CHECK_STRING (message_type);
@@ -2841,14 +2842,14 @@
      the destination window.  But if we are sending to the root window,
      there is no such client.  Then we set the event mask to 0xffff.  The
      event then goes to clients selecting for events on the root window.  */
-  count = x_catch_errors (dpyinfo->display);
+  x_catch_errors (dpyinfo->display);
   {
     int propagate = to_root ? False : True;
     unsigned mask = to_root ? 0xffff : 0;
     XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
     XFlush (dpyinfo->display);
   }
-  x_uncatch_errors (dpyinfo->display, count);
+  x_uncatch_errors (dpyinfo->display);
   UNBLOCK_INPUT;
 
   return Qnil;
--- a/src/xterm.c	Sat Feb 25 16:49:00 2006 +0000
+++ b/src/xterm.c	Sat Feb 25 23:20:10 2006 +0000
@@ -324,8 +324,8 @@
 void x_delete_display P_ ((struct x_display_info *));
 
 static int x_io_error_quitter P_ ((Display *));
-int x_catch_errors P_ ((Display *));
-void x_uncatch_errors P_ ((Display *, int));
+void x_catch_errors P_ ((Display *));
+void x_uncatch_errors P_ ((Display *));
 void x_lower_frame P_ ((struct frame *));
 void x_scroll_bar_clear P_ ((struct frame *));
 int x_had_errors_p P_ ((Display *));
@@ -3719,7 +3719,6 @@
 	Window win, child;
 	int win_x, win_y;
 	int parent_x = 0, parent_y = 0;
-	int count;
 
 	win = root;
 
@@ -3727,7 +3726,7 @@
 	   structure is changing at the same time this function
 	   is running.  So at least we must not crash from them.  */
 
-	count = x_catch_errors (FRAME_X_DISPLAY (*fp));
+	x_catch_errors (FRAME_X_DISPLAY (*fp));
 
 	if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
 	    && FRAME_LIVE_P (last_mouse_frame))
@@ -3796,7 +3795,7 @@
 	if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
 	  f1 = 0;
 
-	x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
+	x_uncatch_errors (FRAME_X_DISPLAY (*fp));
 
 	/* If not, is it one of our scroll bars?  */
 	if (! f1)
@@ -5713,7 +5712,7 @@
                     Display *d = event.xclient.display;
                     /* Catch and ignore errors, in case window has been
                        iconified by a window manager such as GWM.  */
-                    int count = x_catch_errors (d);
+                    x_catch_errors (d);
                     XSetInputFocus (d, event.xclient.window,
                                     /* The ICCCM says this is
                                        the only valid choice.  */
@@ -5722,7 +5721,7 @@
                     /* This is needed to detect the error
                        if there is an error.  */
                     XSync (d, False);
-                    x_uncatch_errors (d, count);
+                    x_uncatch_errors (d);
                   }
                 /* Not certain about handling scroll bars here */
 #endif /* 0 */
@@ -7469,7 +7468,11 @@
 #define X_ERROR_MESSAGE_SIZE 200
 
 /* If non-nil, this should be a string.
-   It means catch X errors  and store the error message in this string.  */
+   It means catch X errors  and store the error message in this string.
+
+   The reason we use a stack is that x_catch_error/x_uncatch_error can
+   be called from a signal handler.
+*/
 
 struct x_error_message_stack {
   char string[X_ERROR_MESSAGE_SIZE];
@@ -7506,20 +7509,12 @@
    Calling x_uncatch_errors resumes the normal error handling.  */
 
 void x_check_errors ();
-static Lisp_Object x_catch_errors_unwind ();
-
-int
+
+void
 x_catch_errors (dpy)
      Display *dpy;
 {
-  int count = SPECPDL_INDEX ();
   struct x_error_message_stack *data = xmalloc (sizeof (*data));
-  Lisp_Object dummy;
-#ifdef ENABLE_CHECKING
-  dummy = make_number ((EMACS_INT)dpy + (EMACS_INT)x_error_message);
-#else
-  dummy = Qnil;
-#endif
 
   /* Make sure any errors from previous requests have been dealt with.  */
   XSync (dpy, False);
@@ -7528,21 +7523,19 @@
   data->string[0] = 0;
   data->prev = x_error_message;
   x_error_message = data;
-
-  record_unwind_protect (x_catch_errors_unwind, dummy);
-
-  return count;
-}
-
-/* Unbind the binding that we made to check for X errors.  */
-
-static Lisp_Object
-x_catch_errors_unwind (dummy)
-     Lisp_Object dummy;
-{
-  Display *dpy = x_error_message->dpy;
+}
+
+/* Undo the last x_catch_errors call.
+   DPY should be the display that was passed to x_catch_errors.  */
+
+void
+x_uncatch_errors (dpy)
+     Display *dpy;
+{
   struct x_error_message_stack *tmp;
 
+  eassert (x_error_message && dpy == x_error_message->dpy);
+
   /* The display may have been closed before this function is called.
      Check if it is still open before calling XSync.  */
   if (x_display_info_for_display (dpy) != 0)
@@ -7554,12 +7547,7 @@
 
   tmp = x_error_message;
   x_error_message = x_error_message->prev;
-  free (tmp);
-
-  eassert (EQ (dummy,
-	       make_number ((EMACS_INT)dpy + (EMACS_INT)x_error_message)));
-
-  return Qnil;
+  xfree (tmp);
 }
 
 /* If any X protocol errors have arrived since the last call to
@@ -7575,7 +7563,12 @@
   XSync (dpy, False);
 
   if (x_error_message->string[0])
-    error (format, x_error_message->string);
+    {
+      char string[X_ERROR_MESSAGE_SIZE];
+      bcopy (x_error_message->string, string, X_ERROR_MESSAGE_SIZE);
+      x_uncatch_errors (dpy);
+      error (format, string);
+    }
 }
 
 /* Nonzero if we had any X protocol errors
@@ -7600,19 +7593,6 @@
   x_error_message->string[0] = 0;
 }
 
-/* Stop catching X protocol errors and let them make Emacs die.
-   DPY should be the display that was passed to x_catch_errors.
-   COUNT should be the value that was returned by
-   the corresponding call to x_catch_errors.  */
-
-void
-x_uncatch_errors (dpy, count)
-     Display *dpy;
-     int count;
-{
-  unbind_to (count, Qnil);
-}
-
 #if 0
 static unsigned int x_wire_count;
 x_trace_wire ()
@@ -7669,7 +7649,6 @@
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
-  int count;
 
   error_msg = (char *) alloca (strlen (error_message) + 1);
   strcpy (error_msg, error_message);
@@ -7679,7 +7658,7 @@
      below.  Otherwise, we might end up with printing ``can't find per
      display information'' in the recursive call instead of printing
      the original message here.  */
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   /* We have to close the display to inform Xt that it doesn't
      exist anymore.  If we don't, Xt will continue to wait for
@@ -7747,7 +7726,7 @@
   if (dpyinfo)
     x_delete_display (dpyinfo);
 
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
 
   if (x_display_list == 0)
     {
@@ -9353,7 +9332,6 @@
     = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list;
   Display *dpy = dpyinfo->display;
   int try_XLoadQueryFont = 0;
-  int count;
   int allow_auto_scaled_font = 0;
 
   if (size < 0)
@@ -9393,7 +9371,7 @@
       /* At first, put PATTERN in the cache.  */
 
       BLOCK_INPUT;
-      count = x_catch_errors (dpy);
+      x_catch_errors (dpy);
 
       if (try_XLoadQueryFont)
 	{
@@ -9474,7 +9452,7 @@
 	    }
 	}
 
-      x_uncatch_errors (dpy, count);
+      x_uncatch_errors (dpy);
       UNBLOCK_INPUT;
 
       if (names)
@@ -9565,7 +9543,7 @@
 	      XFontStruct *thisinfo;
 
 	      BLOCK_INPUT;
-	      count = x_catch_errors (dpy);
+	      x_catch_errors (dpy);
 	      thisinfo = XLoadQueryFont (dpy,
 					 SDATA (XCAR (tem)));
 	      if (x_had_errors_p (dpy))
@@ -9575,7 +9553,7 @@
 		  thisinfo = NULL;
 		  x_clear_errors (dpy);
 		}
-	      x_uncatch_errors (dpy, count);
+	      x_uncatch_errors (dpy);
 	      UNBLOCK_INPUT;
 
 	      if (thisinfo)
@@ -9731,7 +9709,6 @@
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object font_names;
-  int count;
 
   /* Get a list of all the fonts that match this name.  Once we
      have a list of matching fonts, we compare them against the fonts
@@ -9770,7 +9747,7 @@
       fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
-    count = x_catch_errors (FRAME_X_DISPLAY (f));
+    x_catch_errors (FRAME_X_DISPLAY (f));
     font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
     if (x_had_errors_p (FRAME_X_DISPLAY (f)))
       {
@@ -9779,7 +9756,7 @@
 	font = NULL;
 	x_clear_errors (FRAME_X_DISPLAY (f));
       }
-    x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+    x_uncatch_errors (FRAME_X_DISPLAY (f));
     UNBLOCK_INPUT;
     if (!font)
       return NULL;
@@ -10552,7 +10529,6 @@
     Display *dpy = dpyinfo->display;
     XrmValue d, fr, to;
     Font font;
-    int count;
 
     d.addr = (XPointer)&dpy;
     d.size = sizeof (Display *);
@@ -10560,12 +10536,12 @@
     fr.size = sizeof (XtDefaultFont);
     to.size = sizeof (Font *);
     to.addr = (XPointer)&font;
-    count = x_catch_errors (dpy);
+    x_catch_errors (dpy);
     if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
       abort ();
     if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
-    x_uncatch_errors (dpy, count);
+    x_uncatch_errors (dpy);
   }
 #endif
 #endif
--- a/src/xterm.h	Sat Feb 25 16:49:00 2006 +0000
+++ b/src/xterm.h	Sat Feb 25 23:20:10 2006 +0000
@@ -958,9 +958,9 @@
 void x_make_frame_visible P_ ((struct frame *));
 void x_iconify_frame P_ ((struct frame *));
 void x_wm_set_size_hint P_ ((struct frame *, long, int));
-int x_catch_errors P_ ((Display *));
+void x_catch_errors P_ ((Display *));
 int x_had_errors_p P_ ((Display *));
-void x_uncatch_errors P_ ((Display *, int));
+void x_uncatch_errors P_ ((Display *));
 void x_check_errors P_ ((Display *, char *));
 int x_text_icon P_ ((struct frame *, char *));
 int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
@@ -974,10 +974,10 @@
 extern void x_scroll_bar_clear P_ ((struct frame *));
 extern int x_text_icon P_ ((struct frame *, char *));
 extern int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
-extern int x_catch_errors P_ ((Display *));
+extern void x_catch_errors P_ ((Display *));
 extern void x_check_errors P_ ((Display *, char *));
 extern int x_had_errors_p P_ ((Display *));
-extern void x_uncatch_errors P_ ((Display *, int));
+extern void x_uncatch_errors P_ ((Display *));
 extern void x_set_window_size P_ ((struct frame *, int, int, int));
 extern void x_set_mouse_position P_ ((struct frame *, int, int));
 extern void x_set_mouse_pixel_position P_ ((struct frame *, int, int));