changeset 83011:c4d4cbf86260

Changed tty input code to use read_socket_hook. src/keyboard.c (read_avail_input): Removed tty-related code. (tty_read_avail_input): New function. src/keyboard.h (tty_read_avail_input): New prototype. src/term.c (term_init): Set read_socket_hook. Removed bogus baud rate initialization. src/termhooks.h (read_socket_hook): Added display parameter. src/xterm.c (XTread_socket): Added display parameter (unused). git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-51
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 11 Jan 2004 01:18:45 +0000
parents 82554ed1aed8
children 4aa172a45af1
files src/keyboard.c src/keyboard.h src/sysdep.c src/term.c src/termhooks.h src/xterm.c
diffstat 6 files changed, 183 insertions(+), 180 deletions(-) [+]
line wrap: on
line diff
--- a/src/keyboard.c	Sat Jan 10 13:27:38 2004 +0000
+++ b/src/keyboard.c	Sun Jan 11 01:18:45 2004 +0000
@@ -6611,181 +6611,20 @@
 {
   struct input_event buf[KBD_BUFFER_SIZE];
   register int i;
+  struct display *d;
   int nread = 0;
   
   for (i = 0; i < KBD_BUFFER_SIZE; i++)
     EVENT_INIT (buf[i]);
 
-  {
-    struct display *d;
-
-    for (d = display_list; d; d = d->next_display)
-      {
-        if (d->read_socket_hook)
-          /* No need for FIONREAD or fcntl; just say don't wait.  */
-          nread = (*d->read_socket_hook) (buf, KBD_BUFFER_SIZE, expected);
-        
-        if (nread > 0)
-          break;
-      }
-  }
-
-  if (nread <= 0 && tty_list)
-    {
-      /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
-	 the kbd_buffer can really hold.  That may prevent loss
-	 of characters on some systems when input is stuffed at us.  */
-      unsigned char cbuf[KBD_BUFFER_SIZE - 1];
-      int n_to_read;
-      struct tty_display_info *tty;
-      Lisp_Object frame;
-      
-#ifdef WINDOWSNT
-      return 0;
-#else /* not WINDOWSNT */
-#ifdef MSDOS
-      n_to_read = dos_keysns ();
-      if (n_to_read == 0)
-	return 0;
-
-      cbuf[0] = dos_keyread ();
-      nread = 1;
-
-#else /* not MSDOS */
-
-      nread = 0;
-
-      /* Try to read from each available tty, until one succeeds. */
-      for (tty = tty_list; tty; tty = tty->next) {
-
-        if (! tty->term_initted)
-          continue;
-        
-        /* Determine how many characters we should *try* to read.  */
-#ifdef FIONREAD
-        /* 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.  */
-            /* It appears to be the case, see narrow_foreground_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 (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
-#else
-        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
-                  delete_tty (tty); /* XXX I wonder if this is safe 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
-                  delete_tty (tty); /* XXX I wonder if this is safe 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 */
-
-        if (nread > 0)
-          break;
-      } /* for each tty */
-      
-      if (nread <= 0)
-        return 0;
-      
-#endif /* not MSDOS */
-#endif /* not WINDOWSNT */
-
-      if (!tty)
-        abort ();
-      
-      /* Select frame corresponding to the active tty.  Note that the
-         value of selected_frame is not reliable here, redisplay tends
-         to temporarily change it.  But tty should always be non-NULL. */
-      frame = tty->top_frame;
-
-      for (i = 0; i < nread; i++)
-	{
-	  buf[i].kind = ASCII_KEYSTROKE_EVENT;
-	  buf[i].modifiers = 0;
-	  if (tty->meta_key == 1 && (cbuf[i] & 0x80))
-	    buf[i].modifiers = meta_modifier;
-	  if (tty->meta_key != 2)
-	    cbuf[i] &= ~0x80;
-
-          buf[i].code = cbuf[i];
-	  buf[i].frame_or_window = frame;
-	  buf[i].arg = Qnil;
-	}
+  for (d = display_list; d; d = d->next_display)
+    {
+      if (d->read_socket_hook)
+        /* No need for FIONREAD or fcntl; just say don't wait.  */
+        nread = (*d->read_socket_hook) (d, buf, KBD_BUFFER_SIZE, expected);
+
+      if (nread > 0)
+        break;
     }
 
   /* Scan the chars for C-g and store them in kbd_buffer.  */
@@ -6801,6 +6640,169 @@
 
   return nread;
 }
+
+/* This is the tty way of reading available input.
+
+   Note that each terminal device has its own `struct display' object,
+   and so this function is called once for each individual termcap
+   display.  The first parameter indicates which device to read from.  */
+int
+tty_read_avail_input (struct display *display,
+                      struct input_event *buf,
+                      int numchars, int expected)
+{
+  /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
+     the kbd_buffer can really hold.  That may prevent loss
+     of characters on some systems when input is stuffed at us.  */
+  unsigned char cbuf[KBD_BUFFER_SIZE - 1];
+  int n_to_read, i;
+  struct tty_display_info *tty = display->display_info.tty;
+  Lisp_Object frame;
+  int nread = 0;
+  
+  if (display->type != output_termcap)
+    abort ();
+  
+  /* XXX I think the following code should be moved to separate
+     functions in system-dependent files. */
+#ifdef WINDOWSNT
+  return 0;
+#else /* not WINDOWSNT */
+#ifdef MSDOS
+  n_to_read = dos_keysns ();
+  if (n_to_read == 0)
+    return 0;
+  
+  cbuf[0] = dos_keyread ();
+  nread = 1;
+  
+#else /* not MSDOS */
+
+  if (! tty->term_initted)
+    return 0;
+        
+  /* Determine how many characters we should *try* to read.  */
+#ifdef FIONREAD
+  /* Find out how much input is available.  */
+  if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
+    {
+      if (! noninteractive)
+        {
+          delete_tty (tty); /* XXX I wonder if this is safe here. */
+          
+          /* 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.  */
+          /* It appears to be the case, see narrow_foreground_group. */
+          if (! tty_list->next)
+            kill (getpid (), SIGHUP); /* This was the last terminal. */
+        }
+      else
+        {
+          n_to_read = 0;
+        }
+    }
+  if (n_to_read == 0)
+    return 0;
+  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 (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
+#else
+  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
+            delete_tty (tty); /* XXX I wonder if this is safe 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
+            delete_tty (tty); /* XXX I wonder if this is safe 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 */
+  
+  if (nread <= 0)
+    return nread;
+  
+#endif /* not MSDOS */
+#endif /* not WINDOWSNT */
+  
+  /* Select the frame corresponding to the active tty.  Note that the
+     value of selected_frame is not reliable here, redisplay tends to
+     temporarily change it. */
+  frame = tty->top_frame;
+  
+  for (i = 0; i < nread; i++)
+    {
+      buf[i].kind = ASCII_KEYSTROKE_EVENT;
+      buf[i].modifiers = 0;
+      if (tty->meta_key == 1 && (cbuf[i] & 0x80))
+        buf[i].modifiers = meta_modifier;
+      if (tty->meta_key != 2)
+        cbuf[i] &= ~0x80;
+      
+      buf[i].code = cbuf[i];
+      buf[i].frame_or_window = frame;
+      buf[i].arg = Qnil;
+    }
+
+  return nread;
+}
+
 #endif /* not VMS */
 
 #ifdef SIGIO   /* for entire page */
--- a/src/keyboard.h	Sat Jan 10 13:27:38 2004 +0000
+++ b/src/keyboard.h	Sun Jan 11 01:18:45 2004 +0000
@@ -340,5 +340,8 @@
 extern Lisp_Object menu_item_eval_property P_ ((Lisp_Object));
 extern int  kbd_buffer_events_waiting P_ ((int));
 
+extern int tty_read_avail_input P_ ((struct display *,
+                                     struct input_event *, int, int));
+
 /* arch-tag: 769cbade-1ba9-4950-b886-db265b061aa3
    (do not change this comment) */
--- a/src/sysdep.c	Sat Jan 10 13:27:38 2004 +0000
+++ b/src/sysdep.c	Sun Jan 11 01:18:45 2004 +0000
@@ -2694,6 +2694,8 @@
 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;
 
--- a/src/term.c	Sat Jan 10 13:27:38 2004 +0000
+++ b/src/term.c	Sun Jan 11 01:18:45 2004 +0000
@@ -2273,7 +2273,7 @@
   display->redeem_scroll_bar_hook = 0; /* Not needed. */
   display->judge_scroll_bars_hook = 0; /* Not needed. */
 
-  display->read_socket_hook = 0; /* Not needed. */
+  display->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
   display->frame_up_to_date_hook = 0; /* Not needed. */
   
   display->delete_frame_hook = &delete_tty_output;
@@ -2707,11 +2707,6 @@
 
   init_baud_rate (fileno (TTY_INPUT (tty)));
 
-  /* XXX This condition sounds bogus. */
-  if (display->read_socket_hook) /* Baudrate is somewhat
-                                             meaningless in this case */
-    baud_rate = 9600;
-
 #ifdef AIXHFT
   /* The HFT system on AIX doesn't optimize for scrolling, so it's
      really ugly at times.  */
--- a/src/termhooks.h	Sat Jan 10 13:27:38 2004 +0000
+++ b/src/termhooks.h	Sun Jan 11 01:18:45 2004 +0000
@@ -473,7 +473,7 @@
 
 
   /* Called to read input events.  */
-  int (*read_socket_hook) P_ ((struct input_event *, int, int));
+  int (*read_socket_hook) P_ ((struct display *, struct input_event *, int, int));
 
   /* Called when a frame's display becomes entirely up to date.  */
   void (*frame_up_to_date_hook) P_ ((struct frame *));
--- a/src/xterm.c	Sat Jan 10 13:27:38 2004 +0000
+++ b/src/xterm.c	Sun Jan 11 01:18:45 2004 +0000
@@ -7066,9 +7066,10 @@
    EXPECTED is nonzero if the caller knows input is available.  */
 
 static int
-XTread_socket (bufp, numchars, expected)
-     /* register */ struct input_event *bufp;
-     /* register */ int numchars;
+XTread_socket (display, bufp, numchars, expected)
+     struct display *display;
+     struct input_event *bufp;
+     int numchars;
      int expected;
 {
   int count = 0;