diff src/keyboard.c @ 53229:33c3c7c16e13

lib-src/emacsclient.c: Implemented --here option (open a new Emacs tty). Needs more work. (here): New variable. (decode_options): Use it. (ec_get_tty, ec_set_tty, init_tty, window_change, hang_up_signal): New functions. (window_change_signal, init_signals, reset_tty, init_pty, copy_from_to): Ditto. (pty_conversation): Ditto. (main): Use them. (master, pty_name, old_tty, tty, old_tty_valid, tty_erase_char): New variables. (flow_control, meta_key, _sobuf, in_conversation, quit_conversation): Ditto. lisp/server.el (server-process-filter): Added support for opening a new terminal frame. dispextern.h (get_frame_size): Renamed to get_tty_size, added tty_output parameter. dispnew.c (Fredraw_frame): fflush the current terminal instead of stdout. (direct_output_for_insert, direct_output_forward_char, update_frame_1): Ditto. (Fding, bitch_at_user): Ditto. (update_frame_1): Count pending output for current terminal instead of stdout. (window_change_signal): Resize all terminals. (change_frame_size): Don't resize all terminals to the same size. frame.c (Vterminal_frame): Removed. (syms_of_frame): Removed declaration of Vterminal_frame. (make_terminal_frame): Set the top frame of the terminal to the new frame. (Fmake_terminal_frame): Get a new frame size from get_tty_size, don't copy it. (do_switch_frame): Handle terminal frame visibility. (next_frame, prev_frame): Skip over frames on different terminals. frame.h (Vterminal_frame): Removed. keyboard.c (input_fd): Removed. (read_avail_input): Removed first argument from read_socket_hook. Try to read from each available tty, until one succeeds. (Fsuspend_emacs): Don't suspend if there are multiple terminals. lisp.h (get_frame_size): Removed superflous declaration. xterm.c (Xtread_socket): Removed first parameter. macterm.h (XTread_socket): Ditto. w32inevt.c (w32_console_read_socket): Ditto. w32term.c (w32_read_socket): Ditto. sysdep.c (input_fd): Removed. (change_input_fd): Removed. (discard_tty_input): Discard pending input on _all_ input descriptors. (stuff_char, tabs_safe_p): Use current terminal instead of input_fd. (init_baud_rate, request_sigio, unrequest_sigio): Ditto. (init_sys_modes, reset_sys_modes): Ditto. (narrow_foreground_group, widen_foreground_group): Use stdin. (init_sys_modes, reset_sys_modes): otty parameter renamed to tty_out. (get_frame_size): Renamed to get_tty_size, added tty_out parameter. term.c (read_socket_hook): Removed first parameter. (clear_end_of_line): Use updating_frame, if possible. (write_glyphs, insert_glyphs, ins_del_lines): Ditto. (term_init): Renamed get_frame_size to get_tty_size. termchar.h (struct tty_output): New entries: top_frame, previous_terminal_frame. termhooks.h (read_socket_hook): Removed first parameter. window.c (init_window_once): Removed reference to Vterminal_frame. xdisp.c (previous_terminal_frame): Moved to struct tty_output. (redisplay_internal): Updated to use previous_terminal_frame in tty_output. Allow for simultaneous refresh of multiple ttys. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-5
author Karoly Lorentey <lorentey@elte.hu>
date Fri, 26 Dec 2003 04:24:54 +0000
parents dd3018b4785b
children 22aaf1e5fbe6
line wrap: on
line diff
--- a/src/keyboard.c	Thu Dec 25 07:36:05 2003 +0000
+++ b/src/keyboard.c	Fri Dec 26 04:24:54 2003 +0000
@@ -22,10 +22,10 @@
 #include <config.h>
 #include <signal.h>
 #include <stdio.h>
+#include "lisp.h"
 #include "systty.h" /* This must be included befor termchar.h. */
 #include "termchar.h"
 #include "termopts.h"
-#include "lisp.h"
 #include "termhooks.h"
 #include "macros.h"
 #include "keyboard.h"
@@ -89,9 +89,6 @@
 int interrupt_input_pending;
 
 
-/* File descriptor to use for input.  */
-extern int input_fd;
-
 #ifdef HAVE_WINDOW_SYSTEM
 /* Make all keyboard buffers much bigger when using X windows.  */
 #ifdef MAC_OS8
@@ -6588,7 +6585,7 @@
 
   if (read_socket_hook)
     /* No need for FIONREAD or fcntl; just say don't wait.  */
-    nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE, expected);
+    nread = (*read_socket_hook) (buf, KBD_BUFFER_SIZE, expected);
   else
     {
       /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
@@ -6597,7 +6594,6 @@
       unsigned char cbuf[KBD_BUFFER_SIZE - 1];
       int n_to_read;
 
-      /* Determine how many characters we should *try* to read.  */
 #ifdef WINDOWSNT
       return 0;
 #else /* not WINDOWSNT */
@@ -6605,88 +6601,121 @@
       n_to_read = dos_keysns ();
       if (n_to_read == 0)
 	return 0;
+
+      cbuf[0] = dos_keyread ();
+      nread = 1;
+
 #else /* not MSDOS */
+
+      struct tty_output *tty;
+      nread = 0;
+
+      /* Try to read from each available tty, until one succeeds. */
+      for (tty = tty_list; tty && !nread; tty = tty->next) {
+        
+        /* Determine how many characters we should *try* to read.  */
 #ifdef FIONREAD
-      /* Find out how much input is available.  */
-      if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
-	/* Formerly simply reported no input, but that sometimes led to
-	   a failure of Emacs to terminate.
-	   SIGHUP seems appropriate if we can't reach the terminal.  */
-	/* ??? Is it really right to send the signal just to this process
-	   rather than to the whole process group?
-	   Perhaps on systems with FIONREAD Emacs is alone in its group.  */
-	{
-	  if (! noninteractive)
-	    kill (getpid (), SIGHUP);
-	  else
-	    n_to_read = 0;
-	}
-      if (n_to_read == 0)
-	return 0;
-      if (n_to_read > sizeof cbuf)
-	n_to_read = sizeof cbuf;
+        /* Find out how much input is available.  */
+        if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
+          {
+            /* Formerly simply reported no input, but that sometimes led to
+               a failure of Emacs to terminate.
+               SIGHUP seems appropriate if we can't reach the terminal.  */
+            /* ??? Is it really right to send the signal just to this process
+               rather than to the whole process group?
+               Perhaps on systems with FIONREAD Emacs is alone in its group.  */
+            if (! noninteractive)
+              {
+                if (! tty_list->next)
+                  kill (getpid (), SIGHUP); /* This was the last terminal. */
+                else
+                  n_to_read = 0; /* XXX tty should be closed here. */
+              }
+            else
+              {
+                n_to_read = 0;
+              }
+          }
+        if (n_to_read == 0)
+          continue;
+        if (n_to_read > sizeof cbuf)
+          n_to_read = sizeof cbuf;
 #else /* no FIONREAD */
 #if defined (USG) || defined (DGUX) || defined(CYGWIN)
-      /* Read some input if available, but don't wait.  */
-      n_to_read = sizeof cbuf;
-      fcntl (input_fd, F_SETFL, O_NDELAY);
+        /* Read some input if available, but don't wait.  */
+        n_to_read = sizeof cbuf;
+        fcntl (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
 #else
-      you lose;
-#endif
-#endif
+        you lose;
+#endif
+#endif
+
+        /* Now read; for one reason or another, this will not block.
+           NREAD is set to the number of chars read.  */
+        do
+          {
+            nread = emacs_read (fileno (TTY_INPUT (tty)), cbuf, n_to_read);
+            /* POSIX infers that processes which are not in the session leader's
+               process group won't get SIGHUP's at logout time.  BSDI adheres to
+               this part standard and returns -1 from read (0) with errno==EIO
+               when the control tty is taken away.
+               Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
+            if (nread == -1 && errno == EIO)
+              {
+                if (! tty_list->next)
+                  kill (0, SIGHUP); /* This was the last terminal. */
+                else
+                  ;             /* XXX tty should be closed here. */
+              }
+#if defined (AIX) && (! defined (aix386) && defined (_BSD))
+            /* The kernel sometimes fails to deliver SIGHUP for ptys.
+               This looks incorrect, but it isn't, because _BSD causes
+               O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
+               and that causes a value other than 0 when there is no input.  */
+            if (nread == 0)
+              {
+                if (! tty_list->next)
+                  kill (0, SIGHUP); /* This was the last terminal. */
+                else
+                  ;             /* XXX tty should be closed here. */
+              }
+#endif
+          }
+        while (
+               /* We used to retry the read if it was interrupted.
+                  But this does the wrong thing when O_NDELAY causes
+                  an EAGAIN error.  Does anybody know of a situation
+                  where a retry is actually needed?  */
+#if 0
+               nread < 0 && (errno == EAGAIN
+#ifdef EFAULT
+                             || errno == EFAULT
+#endif
+#ifdef EBADSLT
+                             || errno == EBADSLT
+#endif
+                             )
+#else
+               0
+#endif
+               );
+        
+#ifndef FIONREAD
+#if defined (USG) || defined (DGUX) || defined (CYGWIN)
+        fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0);
+#endif /* USG or DGUX or CYGWIN */
+#endif /* no FIONREAD */
+
+      } /* for each tty */
+      
+      if (! nread)
+        return 0;
+      
 #endif /* not MSDOS */
 #endif /* not WINDOWSNT */
 
-      /* Now read; for one reason or another, this will not block.
-	 NREAD is set to the number of chars read.  */
-      do
-	{
-#ifdef MSDOS
-	  cbuf[0] = dos_keyread ();
-	  nread = 1;
-#else
-	  nread = emacs_read (input_fd, cbuf, n_to_read);
-#endif
-	  /* POSIX infers that processes which are not in the session leader's
-	     process group won't get SIGHUP's at logout time.  BSDI adheres to
-	     this part standard and returns -1 from read (0) with errno==EIO
-	     when the control tty is taken away.
-	     Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
-	  if (nread == -1 && errno == EIO)
-	    kill (0, SIGHUP);
-#if defined (AIX) && (! defined (aix386) && defined (_BSD))
-	  /* The kernel sometimes fails to deliver SIGHUP for ptys.
-	     This looks incorrect, but it isn't, because _BSD causes
-	     O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
-	     and that causes a value other than 0 when there is no input.  */
-	  if (nread == 0)
-	    kill (0, SIGHUP);
-#endif
-	}
-      while (
-	     /* We used to retry the read if it was interrupted.
-		But this does the wrong thing when O_NDELAY causes
-		an EAGAIN error.  Does anybody know of a situation
-		where a retry is actually needed?  */
-#if 0
-	     nread < 0 && (errno == EAGAIN
-#ifdef EFAULT
-			   || errno == EFAULT
-#endif
-#ifdef EBADSLT
-			   || errno == EBADSLT
-#endif
-			   )
-#else
-	     0
-#endif
-	     );
-
-#ifndef FIONREAD
-#if defined (USG) || defined (DGUX) || defined (CYGWIN)
-      fcntl (input_fd, F_SETFL, 0);
-#endif /* USG or DGUX or CYGWIN */
-#endif /* no FIONREAD */
+      /* XXX Select frame corresponding to the tty. */
+      
       for (i = 0; i < nread; i++)
 	{
 	  buf[i].kind = ASCII_KEYSTROKE_EVENT;
@@ -10058,6 +10087,9 @@
   int width, height;
   struct gcpro gcpro1;
 
+  if (tty_list && tty_list->next)
+    error ("Suspend is not supported with multiple ttys");
+  
   if (!NILP (stuffstring))
     CHECK_STRING (stuffstring);
 
@@ -10066,7 +10098,7 @@
     call1 (Vrun_hooks, intern ("suspend-hook"));
 
   GCPRO1 (stuffstring);
-  get_frame_size (&old_width, &old_height);
+  get_tty_size (CURTTY (), &old_width, &old_height);
   reset_all_sys_modes ();
   /* sys_suspend can get an error if it tries to fork a subshell
      and the system resources aren't available for that.  */
@@ -10082,7 +10114,7 @@
   /* Check if terminal/window size has changed.
      Note that this is not useful when we are running directly
      with a window system; but suspend should be disabled in that case.  */
-  get_frame_size (&width, &height);
+  get_tty_size (CURTTY (), &width, &height);
   if (width != old_width || height != old_height)
     change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);