Removed %T in mode-line-format. Trivial documentation changes.
[bpt/emacs.git] / src / keyboard.c
index 7b9ee45..b6f1dfa 100644 (file)
@@ -1,5 +1,5 @@
 /* Keyboard and mouse input; editor command loop.
-   Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03
+   Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03,04
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -470,36 +470,6 @@ extern char *pending_malloc_warning;
 
 static struct input_event kbd_buffer[KBD_BUFFER_SIZE];
 
-/* Vector to GCPRO the Lisp objects referenced from kbd_buffer.
-
-   The interrupt-level event handlers will never enqueue an event on a
-   frame which is not in Vframe_list, and once an event is dequeued,
-   internal_last_event_frame or the event itself points to the frame.
-   So that's all fine.
-
-   But while the event is sitting in the queue, it's completely
-   unprotected.  Suppose the user types one command which will run for
-   a while and then delete a frame, and then types another event at
-   the frame that will be deleted, before the command gets around to
-   it.  Suppose there are no references to this frame elsewhere in
-   Emacs, and a GC occurs before the second event is dequeued.  Now we
-   have an event referring to a freed frame, which will crash Emacs
-   when it is dequeued.
-
-   Similar things happen when an event on a scroll bar is enqueued; the
-   window may be deleted while the event is in the queue.
-
-   So, we use this vector to protect the Lisp_Objects in the event
-   queue.  That way, they'll be dequeued as dead frames or windows,
-   but still valid Lisp objects.
-
-   If kbd_buffer[i].kind != NO_EVENT, then
-
-   AREF (kbd_buffer_gcpro, 2 * i) == kbd_buffer[i].frame_or_window.
-   AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg.  */
-
-static Lisp_Object kbd_buffer_gcpro;
-
 /* Pointer to next available character in kbd_buffer.
    If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty.
    This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the
@@ -3630,7 +3600,6 @@ kbd_buffer_store_event (event)
      Discard the event if it would fill the last slot.  */
   if (kbd_fetch_ptr - 1 != kbd_store_ptr)
     {
-      int idx;
 
 #if 0 /* The SELECTION_REQUEST_EVENT case looks bogus, and it's error
         prone to assign individual members for other events, in case
@@ -3660,9 +3629,6 @@ kbd_buffer_store_event (event)
       *kbd_store_ptr = *event;
 #endif
 
-      idx = 2 * (kbd_store_ptr - kbd_buffer);
-      ASET (kbd_buffer_gcpro, idx, event->frame_or_window);
-      ASET (kbd_buffer_gcpro, idx + 1, event->arg);
       ++kbd_store_ptr;
     }
 }
@@ -3778,9 +3744,6 @@ static INLINE void
 clear_event (event)
      struct input_event *event;
 {
-  int idx = 2 * (event - kbd_buffer);
-  ASET (kbd_buffer_gcpro, idx, Qnil);
-  ASET (kbd_buffer_gcpro, idx + 1, Qnil);
   event->kind = NO_EVENT;
 }
 
@@ -6617,14 +6580,36 @@ read_avail_input (expected)
   for (i = 0; i < KBD_BUFFER_SIZE; i++)
     EVENT_INIT (buf[i]);
 
-  for (d = display_list; d; d = d->next_display)
+  d = display_list;
+  while (d)
     {
+      struct display *next = 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;
+      if (nread == -2)
+        {
+          /* The display device terminated; it should be closed. */
+
+          /* Kill Emacs if this was our last display. */
+          if (! display_list->next_display)
+            kill (getpid (), SIGHUP);
+
+          /* XXX Is calling delete_display safe here?  It calls Fdelete_frame. */
+          if (d->delete_display_hook)
+            (*d->delete_display_hook) (d);
+          else
+            delete_display (d);
+        }
+      else if (nread > 0)
+        {
+          /* We've got input. */
+          break;
+        }
+
+      d = next;
     }
 
   /* Scan the chars for C-g and store them in kbd_buffer.  */
@@ -6646,6 +6631,7 @@ read_avail_input (expected)
    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,
@@ -6687,23 +6673,9 @@ tty_read_avail_input (struct display *display,
   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. */
-        }
+        return -2;          /* Close this display. */
       else
-        {
-          n_to_read = 0;
-        }
+        n_to_read = 0;
     }
   if (n_to_read == 0)
     return 0;
@@ -6731,10 +6703,7 @@ tty_read_avail_input (struct display *display,
          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. */
+          return -2;          /* Close this display. */
         }
 #if defined (AIX) && (! defined (aix386) && defined (_BSD))
       /* The kernel sometimes fails to deliver SIGHUP for ptys.
@@ -6743,10 +6712,7 @@ tty_read_avail_input (struct display *display,
          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. */
+          return -2;          /* Close this display. */
         }
 #endif
     }
@@ -6805,6 +6771,30 @@ tty_read_avail_input (struct display *display,
 
 #endif /* not VMS */
 \f
+void
+handle_async_input ()
+{
+#ifdef BSD4_1
+  extern int select_alarmed;
+#endif
+  interrupt_input_pending = 0;
+
+  while (1)
+    {
+      int nread;
+      nread = read_avail_input (1);
+      /* -1 means it's not ok to read the input now.
+        UNBLOCK_INPUT will read it later; now, avoid infinite loop.
+        0 means there was no keyboard input available.  */
+      if (nread <= 0)
+       break;
+
+#ifdef BSD4_1
+      select_alarmed = 1;  /* Force the select emulator back to life */
+#endif
+    }
+}
+
 #ifdef SIGIO   /* for entire page */
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
 
@@ -6814,9 +6804,6 @@ input_available_signal (signo)
 {
   /* Must preserve main program's value of errno.  */
   int old_errno = errno;
-#ifdef BSD4_1
-  extern int select_alarmed;
-#endif
 
 #if defined (USG) && !defined (POSIX_SIGNALS)
   /* USG systems forget handlers when they are used;
@@ -6831,20 +6818,11 @@ input_available_signal (signo)
   if (input_available_clear_time)
     EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
 
-  while (1)
-    {
-      int nread;
-      nread = read_avail_input (1);
-      /* -1 means it's not ok to read the input now.
-        UNBLOCK_INPUT will read it later; now, avoid infinite loop.
-        0 means there was no keyboard input available.  */
-      if (nread <= 0)
-       break;
-
-#ifdef BSD4_1
-      select_alarmed = 1;  /* Force the select emulator back to life */
+#ifdef SYNC_INPUT
+  interrupt_input_pending = 1;
+#else
+  handle_async_input ();
 #endif
-    }
 
 #ifdef BSD4_1
   sigfree ();
@@ -6863,7 +6841,7 @@ void
 reinvoke_input_signal ()
 {
 #ifdef SIGIO
-  kill (getpid (), SIGIO);
+  handle_async_input ();
 #endif
 }
 
@@ -10123,7 +10101,6 @@ Also end any kbd macro being defined.  */)
   discard_tty_input ();
 
   kbd_fetch_ptr =  kbd_store_ptr;
-  Ffillarray (kbd_buffer_gcpro, Qnil);
   input_pending = 0;
 
   return Qnil;
@@ -10217,17 +10194,13 @@ stuff_buffered_input (stuffstring)
      Should we ignore anything that was typed in at the "wrong" kboard?  */
   for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++)
     {
-      int idx;
 
       if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
        kbd_fetch_ptr = kbd_buffer;
       if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
        stuff_char (kbd_fetch_ptr->code);
 
-      kbd_fetch_ptr->kind = NO_EVENT;
-      idx = 2 * (kbd_fetch_ptr - kbd_buffer);
-      ASET (kbd_buffer_gcpro, idx, Qnil);
-      ASET (kbd_buffer_gcpro, idx + 1, Qnil);
+      clear_event (kbd_fetch_ptr);
     }
 
   input_pending = 0;
@@ -10258,20 +10231,11 @@ clear_waiting_for_input ()
   input_available_clear_time = 0;
 }
 
-/* This routine is called at interrupt level in response to C-g.
+/* The SIGINT handler.
 
-   If interrupt_input, this is the handler for SIGINT.  Otherwise, it
-   is called from kbd_buffer_store_event, in handling SIGIO or
-   SIGTINT.
-
-   If `waiting_for_input' is non zero, then unless `echoing' is
-   nonzero, immediately throw back to read_char.
-
-   Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
-   eval to throw, when it gets a chance.  If quit-flag is already
-   non-nil, it stops the job right away.
-
-   XXX This comment needs to be updated.  */
+   If we have a frame on the controlling tty, the SIGINT was generated
+   by C-g, so we call handle_interrupt.  Otherwise, the handler kills
+   Emacs.  */
 
 static SIGTYPE
 interrupt_signal (signalnum)   /* If we don't have an argument, */
@@ -10279,6 +10243,7 @@ interrupt_signal (signalnum)    /* If we don't have an argument, */
 {
   /* 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,31 +10252,41 @@ interrupt_signal (signalnum)  /* If we don't have an argument, */
   signal (SIGQUIT, interrupt_signal);
 #endif /* USG */
 
-  if (! tty_list)
+  /* See if we have a display on our controlling terminal. */
+  display = get_named_tty_display (NULL);
+  if (!display)
     {
-      /* 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.
-      */
+      /* If there are no frames there, let's pretend that we are a
+         well-behaving UN*X program and quit. */
       Fkill_emacs (Qnil);
-      
-      errno = old_errno;
-      return;
     }
+  else
+    {
+      /* Otherwise, the SIGINT was probably generated by C-g.  */
+      
+      /* 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 ();
+      handle_interrupt ();
+    }
 
   errno = old_errno;
 }
 
-/* C-g processing, signal independent code.
+/* This routine is called at interrupt level in response to C-g.
+   
+   It is called from the SIGINT handler or kbd_buffer_store_event.
+
+   If `waiting_for_input' is non zero, then unless `echoing' is
+   nonzero, immediately throw back to read_char.
+
+   Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
+   eval to throw, when it gets a chance.  If quit-flag is already
+   non-nil, it stops the job right away. */
 
-   XXX Expand this comment.  */
 static void
 handle_interrupt ()
 {
@@ -10437,7 +10412,7 @@ handle_interrupt ()
     }
 
   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.  */
@@ -10499,8 +10474,7 @@ See also `current-input-mode'.  */)
 
 #ifndef DOS_NT
   /* this causes startup screen to be restored and messes with the mouse */
-  if (FRAME_TERMCAP_P (SELECTED_FRAME ()))
-    reset_sys_modes (CURTTY ());
+  reset_all_sys_modes ();
 #endif
 
 #ifdef SIGIO
@@ -10538,13 +10512,12 @@ See also `current-input-mode'.  */)
         tty->meta_key = 2;
     }
   
-  if (FRAME_TERMCAP_P (XFRAME (selected_frame)) && !NILP (quit))
+  if (!NILP (quit))
     /* Don't let this value be out of range.  */
-    quit_char = XINT (quit) & (CURTTY ()->meta_key ? 0377 : 0177);
+    quit_char = XINT (quit) & (NILP (meta) ? 0177 : 0377);
 
 #ifndef DOS_NT
-  if (FRAME_TERMCAP_P (XFRAME (selected_frame)) && CURTTY ()->type)
-    init_sys_modes (CURTTY ());
+  init_all_sys_modes ();
 #endif
 
 #ifdef POLL_FOR_INPUT
@@ -10677,7 +10650,6 @@ init_keyboard ()
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;
   kbd_store_ptr = kbd_buffer;
-  kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
 #ifdef HAVE_MOUSE
   do_mouse_tracking = Qnil;
 #endif
@@ -10700,7 +10672,8 @@ init_keyboard ()
          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
@@ -10973,9 +10946,6 @@ syms_of_keyboard ()
   Fset (Qextended_command_history, Qnil);
   staticpro (&Qextended_command_history);
 
-  kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
-  staticpro (&kbd_buffer_gcpro);
-
   accent_key_syms = Qnil;
   staticpro (&accent_key_syms);