changeset 83012:4aa172a45af1

Fix C-g handling with multiple ttys. src/sysdep.c (init_sys_modes): Disable interrupt and quit keys on secondary terminals. Added a big fat comment about this. lib-src/emacsclient.c (init_signals): Don't pass SIGINT and SIGQUIT to Emacs. src/keyboard.c (interrupt_signal): Exit Emacs if there are no frames on the controlling tty. Otherwise set internal_last_event_frame to the controlling tty's top frame. src/term.c (ring_bell, tty_ring_bell): Don't look at updating_frame. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-52
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 11 Jan 2004 02:45:44 +0000
parents c4d4cbf86260
children e77d1a63471b
files README.multi-tty lib-src/emacsclient.c src/keyboard.c src/sysdep.c src/term.c
diffstat 5 files changed, 87 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Sun Jan 11 01:18:45 2004 +0000
+++ b/README.multi-tty	Sun Jan 11 02:45:44 2004 +0000
@@ -133,14 +133,12 @@
    the fly in write_glyphs, which might be problematic, as color
    approximation is currently done in lisp (term/tty-colors.el).)
 
-** frame-creation-function should always create a frame that is on the
-   same display as the selected frame.  Maybe frame-creation-function
-   should simply be removed and make-frame changed to do the right
-   thing.
-
 ** Fix interactive use of temacs.  There are face-related SEGVs, most
    likely because of changes in realize_default_face, realize_face.
 
+** Very strange bug: visible-bell does not work on secondary
+   terminals.  This might be something xterm (konsole) specific.
+
 ** Allow opening an X session after -nw.
 
 ** Find out the best way to support suspending Emacs with multiple
@@ -149,7 +147,7 @@
    extend emacsclient to handle suspend/resume.  A `kill -STOP' almost
    works right now.)
 
-** Exiting Emacs while there are emacsclient frames don't restore the
+** Exiting Emacs while there are emacsclient frames doesn't restore the
    ttys to their default states.
 
 ** Move baud_rate to struct display.
@@ -182,9 +180,6 @@
    why raw terminal support is broken again.  I really do need to
    understand input.)
 
-** Make sure C-g goes to the right frame with ttys.  This is hard, as
-   SIGINT doesn't have a tty parameter. :-(
-
 ** I have seen a case when Emacs with multiple ttys fell into a loop
    eating 100% of CPU time.  Strace showed this loop:
 
@@ -212,7 +207,8 @@
    about face problems.  This can even lock up Emacs (if the recursive
    frame sets single_kboard).  Update: the face problems are caused by
    bugs in term.el, not in multi-tty.  The lockup is caused by
-   single_kboard mode.
+   single_kboard mode, and is not easily solvable.  The best thing to
+   do is to simply refuse to create a tty frame of type `eterm'.
 
 DIARY OF CHANGES
 ----------------
@@ -520,4 +516,26 @@
 
    (Fixed.)
 
+-- frame-creation-function should always create a frame that is on the
+   same display as the selected frame.  Maybe frame-creation-function
+   should simply be removed and make-frame changed to do the right
+   thing.
+
+   (Done, with a nice hack.  frame-creation-function is now frame-local.)
+
+-- Fix C-g on raw ttys.
+
+   (Done.  I disabled the interrupt/quit keys on all secondary
+   terminals, so Emacs sees C-g as normal input.  This looks like an
+   overkill, because emacsclient has extra code to pass SIGINT to
+   Emacs, so C-g should remain the interrupt/quit key on emacsclient
+   frames.  See the next entry why implementing this distinction would
+   be a bad idea.)
+
+-- Make sure C-g goes to the right frame with ttys.  This is hard, as
+   SIGINT doesn't have a tty parameter. :-(
+
+   (Done, the previous change fixes this as a pleasant side effect.)
+
+
 ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
--- a/lib-src/emacsclient.c	Sun Jan 11 01:18:45 2004 +0000
+++ b/lib-src/emacsclient.c	Sun Jan 11 02:45:44 2004 +0000
@@ -299,8 +299,14 @@
 {
   /* Set up signal handlers. */
   signal (SIGWINCH, pass_signal_to_emacs);
+
+  /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
+     deciding which terminal the signal came from.  C-g is now a
+     normal input event on secondary terminals.  */
+#if 0
   signal (SIGINT, pass_signal_to_emacs);
   signal (SIGQUIT, pass_signal_to_emacs);
+#endif
 }
 
 
--- a/src/keyboard.c	Sun Jan 11 01:18:45 2004 +0000
+++ b/src/keyboard.c	Sun Jan 11 02:45:44 2004 +0000
@@ -10279,6 +10279,7 @@
 {
   /* Must preserve main program's value of errno.  */
   int old_errno = errno;
+  struct display *display;
 
 #if defined (USG) && !defined (POSIX_SIGNALS)
   /* USG systems forget handlers when they are used;
@@ -10287,24 +10288,27 @@
   signal (SIGQUIT, interrupt_signal);
 #endif /* USG */
 
-  if (! tty_list)
-    {
-      /* If there are no tty frames, exit Emacs.
-
-         Emacs should exit on SIGINT if and only if there are no
-         frames on its controlling tty and the signal came from there.
-         We can check for the first condition, but (alas) not for the
-         second.  The best we can do is that we only exit if we are
-         sure that the SIGINT was from the controlling tty, i.e., if
-         there are no termcap frames.
-      */
+  /* See if we have a display on our controlling terminal. */
+  display = get_named_tty_display (NULL);
+  if (!display)
+    {
+      /* If there are no frames there, let's pretend that we are a
+         well-behaving UN*X program and quit. */
       Fkill_emacs (Qnil);
+    }
+  else
+    {
+      /* Otherwise, the SIGINT was probably generated by C-g.  */
       
-      errno = old_errno;
-      return;
-    }
-
-  handle_interrupt ();
+      /* Set internal_last_event_frame to the top frame of the
+         controlling tty, if we have a frame there.  We disable the
+         interrupt key on secondary ttys, so the SIGINT must have come
+         from the controlling tty.  */
+      internal_last_event_frame = display->display_info.tty->top_frame;
+
+      handle_interrupt ();
+
+    }
 
   errno = old_errno;
 }
@@ -10437,7 +10441,7 @@
     }
 
   if (waiting_for_input && !echoing)
-    quit_throw_to_read_char ();
+      quit_throw_to_read_char ();
 }
 
 /* Handle a C-g by making read_char return C-g.  */
@@ -10700,7 +10704,8 @@
          only if the current session was a tty session.  Now an Emacs
          session may have multiple display types, so we always handle
          SIGINT.  There is special code in interrupt_signal to exit
-         Emacs on SIGINT when there are no termcap frames. */
+         Emacs on SIGINT when there are no termcap frames on the
+         controlling terminal. */
       signal (SIGINT, interrupt_signal);
 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
       /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
--- a/src/sysdep.c	Sun Jan 11 01:18:45 2004 +0000
+++ b/src/sysdep.c	Sun Jan 11 02:45:44 2004 +0000
@@ -1453,11 +1453,34 @@
 	  tty.main.c_cflag &= ~PARENB;/* Don't check parity */
 	}
 #endif
-      tty.main.c_cc[VINTR] = quit_char;	/* C-g (usually) gives SIGINT */
-      /* Set up C-g for both SIGQUIT and SIGINT.
-	 We don't know which we will get, but we handle both alike
-	 so which one it really gives us does not matter.  */
-      tty.main.c_cc[VQUIT] = quit_char;
+      if (tty_out->input == stdin)
+        {
+          tty.main.c_cc[VINTR] = quit_char;	/* C-g (usually) gives SIGINT */
+          /* Set up C-g for both SIGQUIT and SIGINT.
+             We don't know which we will get, but we handle both alike
+             so which one it really gives us does not matter.  */
+          tty.main.c_cc[VQUIT] = quit_char;
+        }
+      else
+        {
+          /* We normally don't get interrupt or quit signals from tty
+             devices other than our controlling terminal; therefore,
+             we must handle C-g as normal input.  Unfortunately, this
+             means that the interrupt and quit feature must be
+             disabled on secondary ttys, or we would not even see the
+             keypress.
+
+             Note that even though emacsclient could have special code
+             to pass SIGINT to Emacs, we should _not_ enable
+             interrupt/quit keys for emacsclient frames.  This means
+             that we can't break out of loops in C code from a
+             secondary tty frame, but we can always decide what
+             display the C-g came from, which is more important from a
+             usability point of view.  (Consider the case when two
+             people work together using the same Emacs instance.)  */
+          tty.main.c_cc[VINTR] = CDISABLE;
+          tty.main.c_cc[VQUIT] = CDISABLE;
+        }
       tty.main.c_cc[VMIN] = 1;	/* Input should wait for at least 1 char */
       tty.main.c_cc[VTIME] = 0;	/* no matter how long that takes.  */
 #ifdef VSWTCH
--- a/src/term.c	Sun Jan 11 01:18:45 2004 +0000
+++ b/src/term.c	Sun Jan 11 02:45:44 2004 +0000
@@ -176,9 +176,7 @@
 void
 ring_bell ()
 {
-  struct frame *f = (updating_frame
-                     ? updating_frame
-                     : XFRAME (selected_frame));
+  struct frame *f = XFRAME (selected_frame);
 
   if (!NILP (Vring_bell_function))
     {
@@ -206,10 +204,7 @@
 void
 tty_ring_bell ()
 {
-  struct frame *f = (updating_frame
-                     ? updating_frame
-                     : XFRAME (selected_frame));
-
+  struct frame *f = XFRAME (selected_frame);
   struct tty_display_info *tty = FRAME_TTY (f);
 
   OUTPUT (tty, (tty->TS_visible_bell && visible_bell