Fix C-g handling with multiple ttys.
[bpt/emacs.git] / src / sysdep.c
index 502671b..5a2bb44 100644 (file)
@@ -272,11 +272,6 @@ discard_tty_input ()
   if (noninteractive)
     return;
 
-  /* Discarding input is not safe when the input could contain
-     replies from the X server.  So don't do it.  */
-  if (read_socket_hook)
-    return;
-
 #ifdef VMS
   end_kbd_input ();
   SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
@@ -322,7 +317,7 @@ discard_tty_input ()
 void
 stuff_char (char c)
 {
-  if (read_socket_hook)
+  if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
     return;
 
 /* Should perhaps error if in batch mode */
@@ -913,6 +908,29 @@ restore_signal_handlers (saved_handlers)
     }
 }
 \f
+#ifndef SIGIO
+/* If SIGIO is broken, don't do anything. */
+void
+init_sigio (int fd)
+{
+}
+
+void
+reset_sigio (int fd)
+{
+}
+
+void
+request_sigio (void)
+{
+}
+
+void
+unrequest_sigio (void)
+{
+}
+
+#else
 #ifdef F_SETFL
 
 int old_fcntl_flags[MAXDESC];
@@ -932,16 +950,23 @@ void
 reset_sigio (fd)
      int fd;
 {
+#ifdef FASYNC
   fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
+#endif
 }
 
 #ifdef FASYNC          /* F_SETFL does not imply existence of FASYNC */
+/* XXX Uhm, FASYNC is not used anymore here. */
 
 void
 request_sigio ()
 {
+  /* XXX read_socket_hook is not global anymore.  Is blocking SIGIO
+     bad under X? */
+#if 0
   if (read_socket_hook)
     return;
+#endif
 
 #ifdef SIGWINCH
   sigunblock (sigmask (SIGWINCH));
@@ -953,10 +978,14 @@ request_sigio ()
 
 void
 unrequest_sigio (void)
-{
+{ 
+  /* XXX read_socket_hook is not global anymore.  Is blocking SIGIO
+     bad under X? */
+#if 0
   if (read_socket_hook)
     return;
-
+#endif
+  
 #ifdef SIGWINCH
   sigblock (sigmask (SIGWINCH));
 #endif
@@ -1053,6 +1082,7 @@ unrequest_sigio ()
 #endif /* STRIDE */
 #endif /* FASYNC */
 #endif /* F_SETFL */
+#endif /* SIGIO */
 \f
 /* Saving and restoring the process group of Emacs's terminal.  */
 
@@ -1361,14 +1391,18 @@ nil means don't delete them until `list-processes' is run.  */);
 #endif /* VMS */
 
 #ifdef BSD_PGRPS
+#if 0
+  /* read_socket_hook is not global anymore.  I think doing this
+     unconditionally will not cause any problems. */
   if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+#endif
     narrow_foreground_group (fileno (TTY_INPUT (tty_out)));
 #endif
 
 #ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the initialization code below.  */
-  if (tty_out->input != stdin || (!read_socket_hook && EQ (Vwindow_system, Qnil)))
+  if (tty_out->input != stdin || EQ (Vwindow_system, Qnil))
 #endif
     {
       if (! tty_out->old_tty)
@@ -1419,11 +1453,34 @@ nil means don't delete them until `list-processes' is run.  */);
          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
@@ -1614,7 +1671,7 @@ nil means don't delete them until `list-processes' is run.  */);
 #ifndef F_SETOWN_BUG
 #ifdef F_GETOWN                /* F_SETFL does not imply existence of F_GETOWN */
   if (interrupt_input
-      && ! read_socket_hook && EQ (Vwindow_system, Qnil))
+      && (tty_out->input != stdin || EQ (Vwindow_system, Qnil)))
     {
       old_fcntl_owner[fileno (TTY_INPUT (tty_out))] =
         fcntl (fileno (TTY_INPUT (tty_out)), F_GETOWN, 0);
@@ -1641,6 +1698,8 @@ nil means don't delete them until `list-processes' is run.  */);
 #else
   setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
 #endif
+
+#if 0                /* We always need this with multi-tty support. */
 #ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the initialization code below.  */
@@ -1652,6 +1711,8 @@ nil means don't delete them until `list-processes' is run.  */);
 #endif
       )
 #endif
+#endif
+    tty_set_terminal_modes (tty_out->display);
 
   if (!tty_out->term_initted)
     {
@@ -1750,7 +1811,6 @@ get_tty_size (int fd, int *widthp, int *heightp)
   *widthp = 0;
   *heightp = 0;
 #endif
-
 #endif /* not VMS */
 #endif /* not SunOS-style */
 #endif /* not BSD-style */
@@ -1815,6 +1875,7 @@ reset_sys_modes (tty_out)
     }
   if (!tty_out->term_initted)
     return;
+#if 0                           /* We always need to do this with multi-tty support. */
 #ifdef HAVE_WINDOW_SYSTEM
   /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
      needs the clean-up code below.  */
@@ -1828,9 +1889,12 @@ reset_sys_modes (tty_out)
           ))
     return;
 #endif
-
+#endif
+  
   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
+#if 0  /* XXX This doesn't work anymore, the signature has changed. */
   tty_clear_end_of_line (tty_out, FrameCols (tty_out));
+#endif
   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
   fflush (tty_out->output);
   
@@ -1845,7 +1909,7 @@ reset_sys_modes (tty_out)
   }
 #endif
 
-  tty_reset_terminal_modes (tty_out);
+  tty_reset_terminal_modes (tty_out->display);
   fflush (TTY_OUTPUT (tty_out));
 #ifdef BSD_SYSTEM
 #ifndef BSD4_1
@@ -2653,6 +2717,8 @@ sys_select (nfds, rfds, wfds, efds, timeout)
 void
 read_input_waiting ()
 {
+  /* XXX This needs to be updated for multi-tty support.  Does
+     anybody need to emulate select these days?  */
   int nread, i;
   extern int quit_char;