aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c85
1 files changed, 64 insertions, 21 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 2c995dc6ed0..0908153ea1b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2765,15 +2765,18 @@ static void
2765XTcondemn_scroll_bars (frame) 2765XTcondemn_scroll_bars (frame)
2766 FRAME_PTR frame; 2766 FRAME_PTR frame;
2767{ 2767{
2768 /* The condemned list should be empty at this point; if it's not, 2768 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
2769 then the rest of Emacs isn't using the condemn/redeem/judge 2769 while (! NILP (FRAME_SCROLL_BARS (frame)))
2770 protocol correctly. */ 2770 {
2771 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) 2771 Lisp_Object bar;
2772 abort (); 2772 bar = FRAME_SCROLL_BARS (frame);
2773 2773 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
2774 /* Move them all to the "condemned" list. */ 2774 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
2775 FRAME_CONDEMNED_SCROLL_BARS (frame) = FRAME_SCROLL_BARS (frame); 2775 XSCROLL_BAR (bar)->prev = Qnil;
2776 FRAME_SCROLL_BARS (frame) = Qnil; 2776 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
2777 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
2778 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
2779 }
2777} 2780}
2778 2781
2779/* Unmark WINDOW's scroll bar for deletion in this judgement cycle. 2782/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
@@ -3796,6 +3799,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
3796 dpyinfo->x_focus_event_frame = f; 3799 dpyinfo->x_focus_event_frame = f;
3797 if (f) 3800 if (f)
3798 x_new_focus_frame (dpyinfo, f); 3801 x_new_focus_frame (dpyinfo, f);
3802
3799#ifdef USE_X_TOOLKIT 3803#ifdef USE_X_TOOLKIT
3800 goto OTHER; 3804 goto OTHER;
3801#endif /* USE_X_TOOLKIT */ 3805#endif /* USE_X_TOOLKIT */
@@ -3833,6 +3837,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
3833 dpyinfo->x_focus_event_frame = 0; 3837 dpyinfo->x_focus_event_frame = 0;
3834 if (f && f == dpyinfo->x_focus_frame) 3838 if (f && f == dpyinfo->x_focus_frame)
3835 x_new_focus_frame (dpyinfo, 0); 3839 x_new_focus_frame (dpyinfo, 0);
3840
3836#ifdef USE_X_TOOLKIT 3841#ifdef USE_X_TOOLKIT
3837 goto OTHER; 3842 goto OTHER;
3838#endif /* USE_X_TOOLKIT */ 3843#endif /* USE_X_TOOLKIT */
@@ -4530,18 +4535,6 @@ x_connection_closed (display, error_message)
4530 error ("%s", error_message); 4535 error ("%s", error_message);
4531} 4536}
4532 4537
4533static SIGTYPE
4534x_connection_signal (signalnum) /* If we don't have an argument, */
4535 int signalnum; /* some compilers complain in signal calls. */
4536{
4537 /* We really ought to close the connection to the display
4538 that actually failed.
4539 But do we actually get this signal ever with X11? */
4540 fprintf (stderr, "X connection closed");
4541 shut_down_emacs (0, 0, Qnil);
4542 exit (70);
4543}
4544
4545/* This is the usual handler for X protocol errors. 4538/* This is the usual handler for X protocol errors.
4546 It kills all frames on the display that we got the error for. 4539 It kills all frames on the display that we got the error for.
4547 If that was the only one, it prints an error message and kills Emacs. */ 4540 If that was the only one, it prints an error message and kills Emacs. */
@@ -4576,6 +4569,56 @@ x_io_error_quitter (display)
4576 x_connection_closed (display, buf); 4569 x_connection_closed (display, buf);
4577} 4570}
4578 4571
4572/* Handle SIGPIPE, which can happen when the connection to a server
4573 simply goes away. SIGPIPE is handled by x_connection_signal.
4574 It works by sending a no-op command to each X server connection.
4575 When we try a connection that has closed, we get SIGPIPE again.
4576 But this time, it is handled by x_connection_signal_1.
4577 That function knows which connection we were testing,
4578 so it closes that one.
4579
4580 x_connection_closed never returns,
4581 so if more than one connection was lost at once,
4582 we only find one. But XTread_socket keeps trying them all,
4583 so it will notice the other closed one sooner or later. */
4584
4585
4586static struct x_display_info *x_connection_signal_dpyinfo;
4587
4588static SIGTYPE x_connection_signal ();
4589
4590static SIGTYPE
4591x_connection_signal_1 (signalnum) /* If we don't have an argument, */
4592 int signalnum; /* some compilers complain in signal calls. */
4593{
4594 signal (SIGPIPE, x_connection_signal);
4595 x_connection_closed (x_connection_signal_dpyinfo,
4596 "connection was lost");
4597}
4598
4599static SIGTYPE
4600x_connection_signal (signalnum) /* If we don't have an argument, */
4601 int signalnum; /* some compilers complain in signal calls. */
4602{
4603 x_connection_signal_dpyinfo = x_display_list;
4604
4605 sigunblock (SIGPIPE);
4606
4607 while (x_connection_signal_dpyinfo)
4608 {
4609 signal (SIGPIPE, x_connection_signal_1);
4610
4611 XNoOp (x_connection_signal_dpyinfo->display);
4612 XSync (x_connection_signal_dpyinfo->display, False);
4613
4614 /* Each time we get here, cycle through the displays now open. */
4615 x_connection_signal_dpyinfo = x_connection_signal_dpyinfo->next;
4616 }
4617
4618 /* We should have found some closed connection. */
4619 abort ();
4620}
4621
4579/* A buffer for storing X error messages. */ 4622/* A buffer for storing X error messages. */
4580static char *x_caught_error_message; 4623static char *x_caught_error_message;
4581#define X_CAUGHT_ERROR_MESSAGE_SIZE 200 4624#define X_CAUGHT_ERROR_MESSAGE_SIZE 200