]> code.delx.au - gnu-emacs/commitdiff
(XTmouse_position, x_term_init):
authorRichard M. Stallman <rms@gnu.org>
Thu, 1 May 1997 01:57:25 +0000 (01:57 +0000)
committerRichard M. Stallman <rms@gnu.org>
Thu, 1 May 1997 01:57:25 +0000 (01:57 +0000)
Save value of x_catch_errors and pass to x_uncatch_errors.

(x_catch_errors): Use specpdl so can be nested.
Use a Lisp string to as the buffer for the X message.
(x_uncatch_errors, x_had_errors_p, x_check_errors): Related changes.
(x_catch_errors_unwind): New function.
(x_error_quitter): Call x_error_catcher if appropriate.
(x_error_message_string): New variable.
(syms_of_xterm): Defvar it.
(x_caught_error_message): Variable deleted.
(X_ERROR_MESSAGE_SIZE): Renamed from X_CAUGHT_ERROR_MESSAGE_SIZE.
(x_error_handler): New function, calls x_error_quitter or ..._checker.
(x_initialize): Use x_error_handler as error handler for X.

src/xterm.c

index 15dbe02a59be9c42aba9585551e7c91338670d86..e199af2302d01b98425e487d0378099516f5f6ce 100644 (file)
@@ -268,7 +268,7 @@ static void do_line_dance ();
 static int XTcursor_to ();
 static int XTclear_end_of_line ();
 static int x_io_error_quitter ();
-void x_catch_errors ();
+int x_catch_errors ();
 void x_uncatch_errors ();
 \f
 #if 0
@@ -2705,6 +2705,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
        Window win, child;
        int win_x, win_y;
        int parent_x, parent_y;
+       int count;
 
        win = root;
 
@@ -2712,7 +2713,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
           structure is changing at the same time this function
           is running.  So at least we must not crash from them.  */
 
-       x_catch_errors (FRAME_X_DISPLAY (*fp));
+       count = x_catch_errors (FRAME_X_DISPLAY (*fp));
 
        if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
            && FRAME_LIVE_P (last_mouse_frame))
@@ -2772,7 +2773,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
        if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
          f1 = 0;
 
-       x_uncatch_errors (FRAME_X_DISPLAY (*fp));
+       x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
 
        /* If not, is it one of our scroll bars?  */
        if (! f1)
@@ -4938,6 +4939,138 @@ x_text_icon (f, icon_name)
   return 0;
 }
 \f
+#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.  */
+
+static Lisp_Object x_error_message_string;
+
+/* An X error handler which stores the error message in
+   x_error_message_string.  This is called from x_error_handler if
+   x_catch_errors is in effect.  */
+
+static int
+x_error_catcher (display, error)
+     Display *display;
+     XErrorEvent *error;
+{
+  XGetErrorText (display, error->error_code,
+                XSTRING (x_error_message_string)->data,
+                X_ERROR_MESSAGE_SIZE);
+}
+
+/* Begin trapping X errors for display DPY.  Actually we trap X errors
+   for all displays, but DPY should be the display you are actually
+   operating on.
+
+   After calling this function, X protocol errors no longer cause
+   Emacs to exit; instead, they are recorded in the string
+   stored in x_error_message_string.
+
+   Calling x_check_errors signals an Emacs error if an X error has
+   occurred since the last call to x_catch_errors or x_check_errors.
+
+   Calling x_uncatch_errors resumes the normal error handling.  */
+
+void x_check_errors ();
+static Lisp_Object x_catch_errors_unwind ();
+
+int
+x_catch_errors (dpy)
+     Display *dpy;
+{
+  int count = specpdl_ptr - specpdl;
+
+  /* Make sure any errors from previous requests have been dealt with.  */
+  XSync (dpy, False);
+
+  record_unwind_protect (x_catch_errors_unwind, x_error_message_string);
+
+  x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE);
+  XSTRING (x_error_message_string)->data[0] = 0;
+
+  return count;
+}
+
+/* Unbind the binding that we made to check for X errors.  */
+
+static Lisp_Object
+x_catch_errors_unwind (old_val)
+     Lisp_Object old_val;
+{
+  x_error_message_string = old_val;
+  return Qnil;
+}
+
+/* If any X protocol errors have arrived since the last call to
+   x_catch_errors or x_check_errors, signal an Emacs error using
+   sprintf (a buffer, FORMAT, the x error message text) as the text.  */
+
+void
+x_check_errors (dpy, format)
+     Display *dpy;
+     char *format;
+{
+  /* Make sure to catch any errors incurred so far.  */
+  XSync (dpy, False);
+
+  if (XSTRING (x_error_message_string)->data[0])
+    error (format, XSTRING (x_error_message_string)->data);
+}
+
+/* Nonzero if we had any X protocol errors on DPY
+   since we did x_catch_errors.  */
+
+int
+x_had_errors_p (dpy)
+     Display *dpy;
+{
+  /* Make sure to catch any errors incurred so far.  */
+  XSync (dpy, False);
+
+  return XSTRING (x_error_message_string)->data[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 ()
+{
+  fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
+}
+#endif /* ! 0 */
+
+\f
+/* Handle SIGPIPE, which can happen when the connection to a server
+   simply goes away.  SIGPIPE is handled by x_connection_signal.
+   Don't need to do anything, because the write which caused the 
+   SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
+   which will do the appropriate cleanup for us. */
+   
+static SIGTYPE
+x_connection_signal (signalnum)        /* If we don't have an argument, */
+     int signalnum;            /* some compilers complain in signal calls. */
+{
+#ifdef USG
+  /* USG systems forget handlers when they are used;
+     must reestablish each time */
+  signal (signalnum, x_connection_signal);
+#endif /* USG */
+}
+\f
 /* Handling X errors.  */
 
 /* Handle the loss of connection to display DISPLAY.  */
@@ -5026,138 +5159,35 @@ x_error_quitter (display, error)
   x_connection_closed (display, buf1);
 }
 
-/* This is the handler for X IO errors, always.
-   It kills all frames on the display that we lost touch with.
-   If that was the only one, it prints an error message and kills Emacs.  */
+/* This is the first-level handler for X protocol errors.
+   It calls x_error_quitter or x_error_catcher.  */
 
 static int
-x_io_error_quitter (display)
+x_error_handler (display, error)
      Display *display;
+     XErrorEvent *error;
 {
-  char buf[256];
+  char buf[256], buf1[356];
 
-  sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
-  x_connection_closed (display, buf);
-}
-\f
-/* Handle SIGPIPE, which can happen when the connection to a server
-   simply goes away.  SIGPIPE is handled by x_connection_signal.
-   Don't need to do anything, because the write which caused the 
-   SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
-   which will do the appropriate cleanup for us. */
-   
-static SIGTYPE
-x_connection_signal (signalnum)        /* If we don't have an argument, */
-     int signalnum;            /* some compilers complain in signal calls. */
-{
-#ifdef USG
-  /* USG systems forget handlers when they are used;
-     must reestablish each time */
-  signal (signalnum, x_connection_signal);
-#endif /* USG */
+  if (! NILP (x_error_message_string))
+    x_error_catcher (display, error);
+  else
+    x_error_quitter (display, error);
 }
-\f
-/* A buffer for storing X error messages.  */
-static char *x_caught_error_message;
-#define X_CAUGHT_ERROR_MESSAGE_SIZE 200
 
-/* An X error handler which stores the error message in
-   x_caught_error_message.  This is what's installed when
-   x_catch_errors is in effect.  */
+/* This is the handler for X IO errors, always.
+   It kills all frames on the display that we lost touch with.
+   If that was the only one, it prints an error message and kills Emacs.  */
 
 static int
-x_error_catcher (display, error)
+x_io_error_quitter (display)
      Display *display;
-     XErrorEvent *error;
-{
-  XGetErrorText (display, error->error_code,
-                x_caught_error_message, X_CAUGHT_ERROR_MESSAGE_SIZE);
-}
-
-
-/* Begin trapping X errors for display DPY.  Actually we trap X errors
-   for all displays, but DPY should be the display you are actually
-   operating on.
-
-   After calling this function, X protocol errors no longer cause
-   Emacs to exit; instead, they are recorded in x_cfc_error_message.
-
-   Calling x_check_errors signals an Emacs error if an X error has
-   occurred since the last call to x_catch_errors or x_check_errors.
-
-   Calling x_uncatch_errors resumes the normal error handling.  */
-
-void x_catch_errors (), x_check_errors (), x_uncatch_errors ();
-
-void
-x_catch_errors (dpy)
-     Display *dpy;
-{
-  /* Make sure any errors from previous requests have been dealt with.  */
-  XSync (dpy, False);
-
-  /* Set up the error buffer.  */
-  x_caught_error_message
-    = (char*) xmalloc (X_CAUGHT_ERROR_MESSAGE_SIZE);
-  x_caught_error_message[0] = '\0';
-
-  /* Install our little error handler.  */
-  XSetErrorHandler (x_error_catcher);
-}
-
-/* If any X protocol errors have arrived since the last call to
-   x_catch_errors or x_check_errors, signal an Emacs error using
-   sprintf (a buffer, FORMAT, the x error message text) as the text.  */
-
-void
-x_check_errors (dpy, format)
-     Display *dpy;
-     char *format;
 {
-  /* Make sure to catch any errors incurred so far.  */
-  XSync (dpy, False);
-
-  if (x_caught_error_message[0])
-    {
-      char buf[X_CAUGHT_ERROR_MESSAGE_SIZE + 56];
-
-      sprintf (buf, format, x_caught_error_message);
-      x_uncatch_errors (dpy);
-      error (buf);
-    }
-}
-
-/* Nonzero if we had any X protocol errors since we did x_catch_errors.  */
-
-int
-x_had_errors_p (dpy)
-     Display *dpy;
-{
-  /* Make sure to catch any errors incurred so far.  */
-  XSync (dpy, False);
-
-  return x_caught_error_message[0] != 0;
-}
-
-/* Stop catching X protocol errors and let them make Emacs die.  */
-
-void
-x_uncatch_errors (dpy)
-     Display *dpy;
-{
-  xfree (x_caught_error_message);
-  x_caught_error_message = 0;
-  XSetErrorHandler (x_error_quitter);
-}
+  char buf[256];
 
-#if 0
-static unsigned int x_wire_count;
-x_trace_wire ()
-{
-  fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
+  sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
+  x_connection_closed (display, buf);
 }
-#endif /* ! 0 */
-
 \f
 /* Changing the font of the frame.  */
 
@@ -6831,6 +6861,7 @@ x_term_init (display_name, xrm_option, resource_name)
     Display *dpy = dpyinfo->display;
     XrmValue d, fr, to;
     Font font;
+    int count;
     
     d.addr = (XPointer)&dpy;
     d.size = sizeof (Display *);
@@ -6838,12 +6869,12 @@ x_term_init (display_name, xrm_option, resource_name)
     fr.size = sizeof (XtDefaultFont);
     to.size = sizeof (Font *);
     to.addr = (XPointer)&font;
-    x_catch_errors (dpy);
+    count = 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);
+    x_uncatch_errors (dpy, count);
   }
 #endif
 
@@ -6959,7 +6990,7 @@ x_initialize ()
 
   /* Note that there is no real way portable across R3/R4 to get the
      original error handler.  */
-  XSetErrorHandler (x_error_quitter);
+  XSetErrorHandler (x_error_handler);
   XSetIOErrorHandler (x_io_error_quitter);
 
   /* Disable Window Change signals;  they are handled by X events. */
@@ -6973,6 +7004,9 @@ x_initialize ()
 void
 syms_of_xterm ()
 {
+  staticpro (&x_error_message_string);
+  x_error_message_string = Qnil;
+
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;