aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1997-05-01 01:57:25 +0000
committerRichard M. Stallman1997-05-01 01:57:25 +0000
commite99db5a15cc84acda9f2a94285115bd68c11f507 (patch)
treea3b0958f7f5b3c969eacb50665edff297df8d1f2 /src
parent610c1c68c1dd1fecd07cabd24d9ea8341e768c74 (diff)
downloademacs-e99db5a15cc84acda9f2a94285115bd68c11f507.tar.gz
emacs-e99db5a15cc84acda9f2a94285115bd68c11f507.zip
(XTmouse_position, x_term_init):
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.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c284
1 files changed, 159 insertions, 125 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 15dbe02a59b..e199af2302d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -268,7 +268,7 @@ static void do_line_dance ();
268static int XTcursor_to (); 268static int XTcursor_to ();
269static int XTclear_end_of_line (); 269static int XTclear_end_of_line ();
270static int x_io_error_quitter (); 270static int x_io_error_quitter ();
271void x_catch_errors (); 271int x_catch_errors ();
272void x_uncatch_errors (); 272void x_uncatch_errors ();
273 273
274#if 0 274#if 0
@@ -2705,6 +2705,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
2705 Window win, child; 2705 Window win, child;
2706 int win_x, win_y; 2706 int win_x, win_y;
2707 int parent_x, parent_y; 2707 int parent_x, parent_y;
2708 int count;
2708 2709
2709 win = root; 2710 win = root;
2710 2711
@@ -2712,7 +2713,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
2712 structure is changing at the same time this function 2713 structure is changing at the same time this function
2713 is running. So at least we must not crash from them. */ 2714 is running. So at least we must not crash from them. */
2714 2715
2715 x_catch_errors (FRAME_X_DISPLAY (*fp)); 2716 count = x_catch_errors (FRAME_X_DISPLAY (*fp));
2716 2717
2717 if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame 2718 if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
2718 && FRAME_LIVE_P (last_mouse_frame)) 2719 && FRAME_LIVE_P (last_mouse_frame))
@@ -2772,7 +2773,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
2772 if (x_had_errors_p (FRAME_X_DISPLAY (*fp))) 2773 if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
2773 f1 = 0; 2774 f1 = 0;
2774 2775
2775 x_uncatch_errors (FRAME_X_DISPLAY (*fp)); 2776 x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
2776 2777
2777 /* If not, is it one of our scroll bars? */ 2778 /* If not, is it one of our scroll bars? */
2778 if (! f1) 2779 if (! f1)
@@ -4938,6 +4939,138 @@ x_text_icon (f, icon_name)
4938 return 0; 4939 return 0;
4939} 4940}
4940 4941
4942#define X_ERROR_MESSAGE_SIZE 200
4943
4944/* If non-nil, this should be a string.
4945 It means catch X errors and store the error message in this string. */
4946
4947static Lisp_Object x_error_message_string;
4948
4949/* An X error handler which stores the error message in
4950 x_error_message_string. This is called from x_error_handler if
4951 x_catch_errors is in effect. */
4952
4953static int
4954x_error_catcher (display, error)
4955 Display *display;
4956 XErrorEvent *error;
4957{
4958 XGetErrorText (display, error->error_code,
4959 XSTRING (x_error_message_string)->data,
4960 X_ERROR_MESSAGE_SIZE);
4961}
4962
4963/* Begin trapping X errors for display DPY. Actually we trap X errors
4964 for all displays, but DPY should be the display you are actually
4965 operating on.
4966
4967 After calling this function, X protocol errors no longer cause
4968 Emacs to exit; instead, they are recorded in the string
4969 stored in x_error_message_string.
4970
4971 Calling x_check_errors signals an Emacs error if an X error has
4972 occurred since the last call to x_catch_errors or x_check_errors.
4973
4974 Calling x_uncatch_errors resumes the normal error handling. */
4975
4976void x_check_errors ();
4977static Lisp_Object x_catch_errors_unwind ();
4978
4979int
4980x_catch_errors (dpy)
4981 Display *dpy;
4982{
4983 int count = specpdl_ptr - specpdl;
4984
4985 /* Make sure any errors from previous requests have been dealt with. */
4986 XSync (dpy, False);
4987
4988 record_unwind_protect (x_catch_errors_unwind, x_error_message_string);
4989
4990 x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE);
4991 XSTRING (x_error_message_string)->data[0] = 0;
4992
4993 return count;
4994}
4995
4996/* Unbind the binding that we made to check for X errors. */
4997
4998static Lisp_Object
4999x_catch_errors_unwind (old_val)
5000 Lisp_Object old_val;
5001{
5002 x_error_message_string = old_val;
5003 return Qnil;
5004}
5005
5006/* If any X protocol errors have arrived since the last call to
5007 x_catch_errors or x_check_errors, signal an Emacs error using
5008 sprintf (a buffer, FORMAT, the x error message text) as the text. */
5009
5010void
5011x_check_errors (dpy, format)
5012 Display *dpy;
5013 char *format;
5014{
5015 /* Make sure to catch any errors incurred so far. */
5016 XSync (dpy, False);
5017
5018 if (XSTRING (x_error_message_string)->data[0])
5019 error (format, XSTRING (x_error_message_string)->data);
5020}
5021
5022/* Nonzero if we had any X protocol errors on DPY
5023 since we did x_catch_errors. */
5024
5025int
5026x_had_errors_p (dpy)
5027 Display *dpy;
5028{
5029 /* Make sure to catch any errors incurred so far. */
5030 XSync (dpy, False);
5031
5032 return XSTRING (x_error_message_string)->data[0] != 0;
5033}
5034
5035/* Stop catching X protocol errors and let them make Emacs die.
5036 DPY should be the display that was passed to x_catch_errors.
5037 COUNT should be the value that was returned by
5038 the corresponding call to x_catch_errors. */
5039
5040void
5041x_uncatch_errors (dpy, count)
5042 Display *dpy;
5043 int count;
5044{
5045 unbind_to (count, Qnil);
5046}
5047
5048#if 0
5049static unsigned int x_wire_count;
5050x_trace_wire ()
5051{
5052 fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
5053}
5054#endif /* ! 0 */
5055
5056
5057/* Handle SIGPIPE, which can happen when the connection to a server
5058 simply goes away. SIGPIPE is handled by x_connection_signal.
5059 Don't need to do anything, because the write which caused the
5060 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
5061 which will do the appropriate cleanup for us. */
5062
5063static SIGTYPE
5064x_connection_signal (signalnum) /* If we don't have an argument, */
5065 int signalnum; /* some compilers complain in signal calls. */
5066{
5067#ifdef USG
5068 /* USG systems forget handlers when they are used;
5069 must reestablish each time */
5070 signal (signalnum, x_connection_signal);
5071#endif /* USG */
5072}
5073
4941/* Handling X errors. */ 5074/* Handling X errors. */
4942 5075
4943/* Handle the loss of connection to display DISPLAY. */ 5076/* Handle the loss of connection to display DISPLAY. */
@@ -5026,138 +5159,35 @@ x_error_quitter (display, error)
5026 x_connection_closed (display, buf1); 5159 x_connection_closed (display, buf1);
5027} 5160}
5028 5161
5029/* This is the handler for X IO errors, always. 5162/* This is the first-level handler for X protocol errors.
5030 It kills all frames on the display that we lost touch with. 5163 It calls x_error_quitter or x_error_catcher. */
5031 If that was the only one, it prints an error message and kills Emacs. */
5032 5164
5033static int 5165static int
5034x_io_error_quitter (display) 5166x_error_handler (display, error)
5035 Display *display; 5167 Display *display;
5168 XErrorEvent *error;
5036{ 5169{
5037 char buf[256]; 5170 char buf[256], buf1[356];
5038 5171
5039 sprintf (buf, "Connection lost to X server `%s'", DisplayString (display)); 5172 if (! NILP (x_error_message_string))
5040 x_connection_closed (display, buf); 5173 x_error_catcher (display, error);
5041} 5174 else
5042 5175 x_error_quitter (display, error);
5043/* Handle SIGPIPE, which can happen when the connection to a server
5044 simply goes away. SIGPIPE is handled by x_connection_signal.
5045 Don't need to do anything, because the write which caused the
5046 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
5047 which will do the appropriate cleanup for us. */
5048
5049static SIGTYPE
5050x_connection_signal (signalnum) /* If we don't have an argument, */
5051 int signalnum; /* some compilers complain in signal calls. */
5052{
5053#ifdef USG
5054 /* USG systems forget handlers when they are used;
5055 must reestablish each time */
5056 signal (signalnum, x_connection_signal);
5057#endif /* USG */
5058} 5176}
5059
5060/* A buffer for storing X error messages. */
5061static char *x_caught_error_message;
5062#define X_CAUGHT_ERROR_MESSAGE_SIZE 200
5063 5177
5064/* An X error handler which stores the error message in 5178/* This is the handler for X IO errors, always.
5065 x_caught_error_message. This is what's installed when 5179 It kills all frames on the display that we lost touch with.
5066 x_catch_errors is in effect. */ 5180 If that was the only one, it prints an error message and kills Emacs. */
5067 5181
5068static int 5182static int
5069x_error_catcher (display, error) 5183x_io_error_quitter (display)
5070 Display *display; 5184 Display *display;
5071 XErrorEvent *error;
5072{
5073 XGetErrorText (display, error->error_code,
5074 x_caught_error_message, X_CAUGHT_ERROR_MESSAGE_SIZE);
5075}
5076
5077
5078/* Begin trapping X errors for display DPY. Actually we trap X errors
5079 for all displays, but DPY should be the display you are actually
5080 operating on.
5081
5082 After calling this function, X protocol errors no longer cause
5083 Emacs to exit; instead, they are recorded in x_cfc_error_message.
5084
5085 Calling x_check_errors signals an Emacs error if an X error has
5086 occurred since the last call to x_catch_errors or x_check_errors.
5087
5088 Calling x_uncatch_errors resumes the normal error handling. */
5089
5090void x_catch_errors (), x_check_errors (), x_uncatch_errors ();
5091
5092void
5093x_catch_errors (dpy)
5094 Display *dpy;
5095{
5096 /* Make sure any errors from previous requests have been dealt with. */
5097 XSync (dpy, False);
5098
5099 /* Set up the error buffer. */
5100 x_caught_error_message
5101 = (char*) xmalloc (X_CAUGHT_ERROR_MESSAGE_SIZE);
5102 x_caught_error_message[0] = '\0';
5103
5104 /* Install our little error handler. */
5105 XSetErrorHandler (x_error_catcher);
5106}
5107
5108/* If any X protocol errors have arrived since the last call to
5109 x_catch_errors or x_check_errors, signal an Emacs error using
5110 sprintf (a buffer, FORMAT, the x error message text) as the text. */
5111
5112void
5113x_check_errors (dpy, format)
5114 Display *dpy;
5115 char *format;
5116{ 5185{
5117 /* Make sure to catch any errors incurred so far. */ 5186 char buf[256];
5118 XSync (dpy, False);
5119
5120 if (x_caught_error_message[0])
5121 {
5122 char buf[X_CAUGHT_ERROR_MESSAGE_SIZE + 56];
5123
5124 sprintf (buf, format, x_caught_error_message);
5125 x_uncatch_errors (dpy);
5126 error (buf);
5127 }
5128}
5129
5130/* Nonzero if we had any X protocol errors since we did x_catch_errors. */
5131
5132int
5133x_had_errors_p (dpy)
5134 Display *dpy;
5135{
5136 /* Make sure to catch any errors incurred so far. */
5137 XSync (dpy, False);
5138
5139 return x_caught_error_message[0] != 0;
5140}
5141
5142/* Stop catching X protocol errors and let them make Emacs die. */
5143
5144void
5145x_uncatch_errors (dpy)
5146 Display *dpy;
5147{
5148 xfree (x_caught_error_message);
5149 x_caught_error_message = 0;
5150 XSetErrorHandler (x_error_quitter);
5151}
5152 5187
5153#if 0 5188 sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
5154static unsigned int x_wire_count; 5189 x_connection_closed (display, buf);
5155x_trace_wire ()
5156{
5157 fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
5158} 5190}
5159#endif /* ! 0 */
5160
5161 5191
5162/* Changing the font of the frame. */ 5192/* Changing the font of the frame. */
5163 5193
@@ -6831,6 +6861,7 @@ x_term_init (display_name, xrm_option, resource_name)
6831 Display *dpy = dpyinfo->display; 6861 Display *dpy = dpyinfo->display;
6832 XrmValue d, fr, to; 6862 XrmValue d, fr, to;
6833 Font font; 6863 Font font;
6864 int count;
6834 6865
6835 d.addr = (XPointer)&dpy; 6866 d.addr = (XPointer)&dpy;
6836 d.size = sizeof (Display *); 6867 d.size = sizeof (Display *);
@@ -6838,12 +6869,12 @@ x_term_init (display_name, xrm_option, resource_name)
6838 fr.size = sizeof (XtDefaultFont); 6869 fr.size = sizeof (XtDefaultFont);
6839 to.size = sizeof (Font *); 6870 to.size = sizeof (Font *);
6840 to.addr = (XPointer)&font; 6871 to.addr = (XPointer)&font;
6841 x_catch_errors (dpy); 6872 count = x_catch_errors (dpy);
6842 if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL)) 6873 if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
6843 abort (); 6874 abort ();
6844 if (x_had_errors_p (dpy) || !XQueryFont (dpy, font)) 6875 if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
6845 XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15"); 6876 XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
6846 x_uncatch_errors (dpy); 6877 x_uncatch_errors (dpy, count);
6847 } 6878 }
6848#endif 6879#endif
6849 6880
@@ -6959,7 +6990,7 @@ x_initialize ()
6959 6990
6960 /* Note that there is no real way portable across R3/R4 to get the 6991 /* Note that there is no real way portable across R3/R4 to get the
6961 original error handler. */ 6992 original error handler. */
6962 XSetErrorHandler (x_error_quitter); 6993 XSetErrorHandler (x_error_handler);
6963 XSetIOErrorHandler (x_io_error_quitter); 6994 XSetIOErrorHandler (x_io_error_quitter);
6964 6995
6965 /* Disable Window Change signals; they are handled by X events. */ 6996 /* Disable Window Change signals; they are handled by X events. */
@@ -6973,6 +7004,9 @@ x_initialize ()
6973void 7004void
6974syms_of_xterm () 7005syms_of_xterm ()
6975{ 7006{
7007 staticpro (&x_error_message_string);
7008 x_error_message_string = Qnil;
7009
6976 staticpro (&x_display_name_list); 7010 staticpro (&x_display_name_list);
6977 x_display_name_list = Qnil; 7011 x_display_name_list = Qnil;
6978 7012