]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
Merged in changes from CVS trunk.
[gnu-emacs] / src / keyboard.c
index 39891b1a95d185bef01edda96745bdb61324760b..74f8d7d51e0763a1a516dfc4e4154585fef6c47b 100644 (file)
@@ -1,6 +1,7 @@
 /* Keyboard and mouse input; editor command loop.
-   Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1996, 1997,
-     1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995,
+                 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
+                 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 #include <signal.h>
@@ -417,13 +418,6 @@ Lisp_Object Vtop_level;
 /* User-supplied table to translate input characters.  */
 Lisp_Object Vkeyboard_translate_table;
 
-/* Keymap mapping ASCII function key sequences onto their preferred forms.  */
-extern Lisp_Object Vfunction_key_map;
-
-/* Another keymap that maps key sequences into key sequences.
-   This one takes precedence over ordinary definitions.  */
-extern Lisp_Object Vkey_translation_map;
-
 /* If non-nil, this implements the current input method.  */
 Lisp_Object Vinput_method_function;
 Lisp_Object Qinput_method_function;
@@ -446,11 +440,12 @@ Lisp_Object Qecho_area_clear_hook;
 Lisp_Object Qpre_command_hook, Vpre_command_hook;
 Lisp_Object Qpost_command_hook, Vpost_command_hook;
 Lisp_Object Qcommand_hook_internal, Vcommand_hook_internal;
-/* Hook run after a command if there's no more input soon.  */
-Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook;
 
-/* Delay time in microseconds before running post-command-idle-hook.  */
-EMACS_INT post_command_idle_delay;
+/* Parent keymap of terminal-local function-key-map instances.  */
+Lisp_Object Vfunction_key_map;
+
+/* Parent keymap of terminal-local key-translation-map instances.  */
+Lisp_Object Vkey_translation_map;
 
 /* List of deferred actions to be performed at a later time.
    The precise format isn't relevant here; we just check whether it is nil.  */
@@ -521,7 +516,7 @@ Lisp_Object Qmouse_fixup_help_message;
 /* Symbols to denote kinds of events.  */
 Lisp_Object Qfunction_key;
 Lisp_Object Qmouse_click;
-#ifdef WINDOWSNT
+#if defined (WINDOWSNT) || defined (MAC_OS)
 Lisp_Object Qlanguage_change;
 #endif
 Lisp_Object Qdrag_n_drop;
@@ -1014,7 +1009,7 @@ DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
        doc: /* Invoke the editor command loop recursively.
 To get out of the recursive edit, a command can do `(throw 'exit nil)';
 that tells this function to return.
-Alternately, `(throw 'exit t)' makes this function signal an error.
+Alternatively, `(throw 'exit t)' makes this function signal an error.
 This function is called by the editor initialization to begin editing.  */)
      ()
 {
@@ -1120,6 +1115,22 @@ struct kboard_stack
 
 static struct kboard_stack *kboard_stack;
 
+void
+push_device_kboard (d)
+     struct device *d;
+{
+#ifdef MULTI_KBOARD
+  struct kboard_stack *p
+    = (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack));
+
+  p->next = kboard_stack;
+  p->kboard = current_kboard;
+  kboard_stack = p;
+
+  current_kboard = d->kboard;
+#endif
+}
+
 void
 push_frame_kboard (f)
      FRAME_PTR f;
@@ -1162,21 +1173,21 @@ cmd_error (data)
     cancel_hourglass ();
 #endif
 
-  if (!NILP (executing_macro))
+  if (!NILP (executing_kbd_macro))
     {
-      if (executing_macro_iterations == 1)
+      if (executing_kbd_macro_iterations == 1)
        sprintf (macroerror, "After 1 kbd macro iteration: ");
       else
        sprintf (macroerror, "After %d kbd macro iterations: ",
-                executing_macro_iterations);
+                executing_kbd_macro_iterations);
     }
   else
     *macroerror = 0;
 
   Vstandard_output = Qt;
   Vstandard_input = Qt;
-  Vexecuting_macro = Qnil;
-  executing_macro = Qnil;
+  Vexecuting_kbd_macro = Qnil;
+  executing_kbd_macro = Qnil;
   current_kboard->Vprefix_arg = Qnil;
   current_kboard->Vlast_prefix_arg = Qnil;
   cancel_echoing ();
@@ -1273,7 +1284,7 @@ command_loop ()
     {
       Lisp_Object val;
       val = internal_catch (Qexit, command_loop_2, Qnil);
-      executing_macro = Qnil;
+      executing_kbd_macro = Qnil;
       return val;
     }
   else
@@ -1285,7 +1296,7 @@ command_loop ()
            other reason. */
         any_kboard_state ();
        internal_catch (Qtop_level, command_loop_2, Qnil);
-       executing_macro = Qnil;
+       executing_kbd_macro = Qnil;
 
        /* End of file in -batch run causes exit here.  */
        if (noninteractive)
@@ -1432,16 +1443,6 @@ command_loop_1 ()
 
       if (!NILP (Vdeferred_action_list))
        safe_run_hooks (Qdeferred_action_function);
-
-      if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
-       {
-         if (NILP (Vunread_command_events)
-             && NILP (Vunread_input_method_events)
-             && NILP (Vunread_post_input_method_events)
-             && NILP (Vexecuting_macro)
-             && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
-           safe_run_hooks (Qpost_command_idle_hook);
-       }
     }
 
   Vmemory_full = Qnil;
@@ -1509,7 +1510,7 @@ command_loop_1 ()
         Is this a good idea?  */
       if (FRAMEP (internal_last_event_frame)
          && !EQ (internal_last_event_frame, selected_frame))
-       Fselect_frame (internal_last_event_frame, Qnil);
+       Fselect_frame (internal_last_event_frame);
 #endif
       /* If it has changed current-menubar from previous value,
         really recompute the menubar from the value.  */
@@ -1522,6 +1523,7 @@ command_loop_1 ()
 
       Vthis_command = Qnil;
       real_this_command = Qnil;
+      Vthis_original_command = Qnil;
 
       /* Read next key sequence; i gets its length.  */
       i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
@@ -1567,11 +1569,11 @@ command_loop_1 ()
        }
 
       cmd = read_key_sequence_cmd;
-      if (!NILP (Vexecuting_macro))
+      if (!NILP (Vexecuting_kbd_macro))
        {
          if (!NILP (Vquit_flag))
            {
-             Vexecuting_macro = Qt;
+             Vexecuting_kbd_macro = Qt;
              QUIT;             /* Make some noise. */
                                /* Will return since macro now empty. */
            }
@@ -1670,7 +1672,7 @@ command_loop_1 ()
                      && EQ (current_buffer->selective_display, Qnil)
                      && !detect_input_pending ()
                      && NILP (XWINDOW (selected_window)->column_number_displayed)
-                     && NILP (Vexecuting_macro))
+                     && NILP (Vexecuting_kbd_macro))
                    direct_output_forward_char (1);
                  goto directly_done;
                }
@@ -1705,7 +1707,7 @@ command_loop_1 ()
                      && EQ (current_buffer->selective_display, Qnil)
                      && !detect_input_pending ()
                      && NILP (XWINDOW (selected_window)->column_number_displayed)
-                     && NILP (Vexecuting_macro))
+                     && NILP (Vexecuting_kbd_macro))
                    direct_output_forward_char (-1);
                  goto directly_done;
                }
@@ -1718,7 +1720,7 @@ command_loop_1 ()
                    = translate_char (Vtranslation_table_for_input,
                                      XFASTINT (last_command_char), 0, 0, 0);
                  int value;
-                 if (NILP (Vexecuting_macro)
+                 if (NILP (Vexecuting_kbd_macro)
                      && !EQ (minibuf_window, selected_window))
                    {
                      if (!nonundocount || nonundocount >= 20)
@@ -1740,7 +1742,7 @@ command_loop_1 ()
                          || !EQ (current_buffer->selective_display, Qnil)
                          || detect_input_pending ()
                          || !NILP (XWINDOW (selected_window)->column_number_displayed)
-                         || !NILP (Vexecuting_macro));
+                         || !NILP (Vexecuting_kbd_macro));
 
                  value = internal_self_insert (c, 0);
 
@@ -1768,7 +1770,7 @@ command_loop_1 ()
             int scount = SPECPDL_INDEX ();
 
             if (display_hourglass_p
-                && NILP (Vexecuting_macro))
+                && NILP (Vexecuting_kbd_macro))
               {
                 record_unwind_protect (cancel_hourglass_unwind, Qnil);
                 start_hourglass ();
@@ -1786,7 +1788,7 @@ command_loop_1 ()
             hourglass cursor anyway.
             But don't cancel the hourglass within a macro
             just because a command in the macro finishes.  */
-         if (NILP (Vexecuting_macro))
+         if (NILP (Vexecuting_kbd_macro))
             unbind_to (scount, Qnil);
 #endif
           }
@@ -1807,16 +1809,6 @@ command_loop_1 ()
       if (!NILP (Vdeferred_action_list))
        safe_run_hooks (Qdeferred_action_function);
 
-      if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
-       {
-         if (NILP (Vunread_command_events)
-             && NILP (Vunread_input_method_events)
-             && NILP (Vunread_post_input_method_events)
-             && NILP (Vexecuting_macro)
-             && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
-           safe_run_hooks (Qpost_command_idle_hook);
-       }
-
       /* If there is a prefix argument,
         1) We don't want Vlast_command to be ``universal-argument''
         (that would be dumb), so don't set Vlast_command,
@@ -1932,10 +1924,13 @@ adjust_point_for_property (last_pt, modified)
              ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil)
              : (beg = OVERLAY_POSITION (OVERLAY_START (overlay)),
                 end = OVERLAY_POSITION (OVERLAY_END (overlay))))
-         && beg < PT) /* && end > PT   <- It's always the case.  */
+         && (beg < PT /* && end > PT   <- It's always the case.  */
+             || (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
        {
          xassert (end > PT);
-         SET_PT (PT < last_pt ? beg : end);
+         SET_PT (PT < last_pt
+                 ? (STRINGP (val) && SCHARS (val) == 0 ? beg - 1 : beg)
+                 : end);
          check_composition = check_invisible = 1;
        }
       check_display = 0;
@@ -2100,7 +2095,11 @@ poll_for_input (timer)
      struct atimer *timer;
 {
   if (poll_suppress_count == 0)
+#ifdef SYNC_INPUT
+    interrupt_input_pending = 1;
+#else
     poll_for_input_1 ();
+#endif
 }
 
 #endif /* POLL_FOR_INPUT */
@@ -2252,12 +2251,16 @@ make_ctrl_char (c)
   return c;
 }
 
-/* Display help echo in the echo area.
+/* Display the help-echo property of the character after the mouse pointer.
+   Either show it in the echo area, or call show-help-function to display
+   it by other means (maybe in a tooltip).
+
+   If HELP is nil, that means clear the previous help echo.
 
-   HELP a string means display that string, HELP nil means clear the
-   help echo.  If HELP is a function, call it with OBJECT and POS as
-   arguments; the function should return a help string or nil for
-   none.  For all other types of HELP evaluate it to obtain a string.
+   If HELP is a string, display that string.  If HELP is a function,
+   call it with OBJECT and POS as arguments; the function should
+   return a help string or nil for none.  For all other types of HELP,
+   evaluate it to obtain a string.
 
    WINDOW is the window in which the help was generated, if any.
    It is nil if not in a window.
@@ -2485,7 +2488,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
   this_command_key_count_reset = 0;
 
-  if (!NILP (Vexecuting_macro))
+  if (!NILP (Vexecuting_kbd_macro))
     {
       /* We set this to Qmacro; since that's not a frame, nobody will
         try to switch frames on us, and the selected window will
@@ -2502,19 +2505,19 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       /* Exit the macro if we are at the end.
         Also, some things replace the macro with t
         to force an early exit.  */
-      if (EQ (Vexecuting_macro, Qt)
-         || executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))
+      if (EQ (Vexecuting_kbd_macro, Qt)
+         || executing_kbd_macro_index >= XFASTINT (Flength (Vexecuting_kbd_macro)))
        {
          XSETINT (c, -1);
          goto exit;
        }
 
-      c = Faref (Vexecuting_macro, make_number (executing_macro_index));
-      if (STRINGP (Vexecuting_macro)
+      c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index));
+      if (STRINGP (Vexecuting_kbd_macro)
          && (XINT (c) & 0x80) && (XUINT (c) <= 0xff))
        XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
 
-      executing_macro_index++;
+      executing_kbd_macro_index++;
 
       goto from_macro;
     }
@@ -2623,6 +2626,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
 
   if (_setjmp (local_getcjmp))
     {
+      /* We must have saved the outer value of getcjmp here,
+        so restore it now.  */
+      restore_getcjmp (save_jump);
       XSETINT (c, quit_char);
       internal_last_event_frame = selected_frame;
       Vlast_event_frame = internal_last_event_frame;
@@ -3517,9 +3523,11 @@ readable_events (flags)
      READABLE_EVENTS_FILTER_EVENTS is set, report it as empty.  */
   if (kbd_fetch_ptr != kbd_store_ptr)
     {
-      int have_live_event = 1;
-
-      if (flags & READABLE_EVENTS_FILTER_EVENTS)
+      if (flags & (READABLE_EVENTS_FILTER_EVENTS
+#ifdef USE_TOOLKIT_SCROLL_BARS
+                  | READABLE_EVENTS_IGNORE_SQUEEZABLES
+#endif
+                  ))
         {
           struct input_event *event;
 
@@ -3527,16 +3535,29 @@ readable_events (flags)
                    ? kbd_fetch_ptr
                    : kbd_buffer);
 
-          while (have_live_event && event->kind == FOCUS_IN_EVENT)
-            {
-              event++;
+         do
+           {
+             if (!(
+#ifdef USE_TOOLKIT_SCROLL_BARS
+                   (flags & READABLE_EVENTS_FILTER_EVENTS) &&
+#endif
+                   event->kind == FOCUS_IN_EVENT)
+#ifdef USE_TOOLKIT_SCROLL_BARS
+                 && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
+                      && event->kind == SCROLL_BAR_CLICK_EVENT
+                      && event->part == scroll_bar_handle
+                      && event->modifiers == 0)
+#endif
+                 )
+               return 1;
+             event++;
               if (event == kbd_buffer + KBD_BUFFER_SIZE)
                 event = kbd_buffer;
-              if (event == kbd_store_ptr)
-                have_live_event = 0;
-            }
+           }
+         while (event != kbd_store_ptr);
         }
-      if (have_live_event) return 1;
+      else
+       return 1;
     }
 
 #ifdef HAVE_MOUSE
@@ -3990,7 +4011,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
          kbd_fetch_ptr = event + 1;
        }
 #endif
-#if defined (HAVE_X11) || defined (HAVE_NTGUI)
+#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)
       else if (event->kind == ICONIFY_EVENT)
        {
          /* Make an event (iconify-frame (FRAME)).  */
@@ -4022,11 +4043,16 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
            x_activate_menubar (XFRAME (event->frame_or_window));
        }
 #endif
-#ifdef WINDOWSNT
+#if defined (WINDOWSNT) || defined (MAC_OS)
       else if (event->kind == LANGUAGE_CHANGE_EVENT)
        {
+#ifdef MAC_OS
+         /* Make an event (language-change (KEY_SCRIPT)).  */
+         obj = Fcons (make_number (event->code), Qnil);
+#else
          /* Make an event (language-change (FRAME CHARSET LCID)).  */
          obj = Fcons (event->frame_or_window, Qnil);
+#endif
          obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
          kbd_fetch_ptr = event + 1;
        }
@@ -4147,9 +4173,9 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
       x = Qnil;
 
       /* XXX Can f or mouse_position_hook be NULL here? */
-      if (f && FRAME_DISPLAY (f)->mouse_position_hook)
-        (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, 0, &bar_window,
-                                                   &part, &x, &y, &time);
+      if (f && FRAME_DEVICE (f)->mouse_position_hook)
+        (*FRAME_DEVICE (f)->mouse_position_hook) (&f, 0, &bar_window,
+                                                  &part, &x, &y, &time);
 
       obj = Qnil;
 
@@ -6530,7 +6556,7 @@ lucid_event_type_list_p (object)
    If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
    events (FOCUS_IN_EVENT).
    If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
-   movements. */
+   movements and toolkit scroll bar thumb drags. */
 
 static void
 get_input_pending (addr, flags)
@@ -6648,13 +6674,13 @@ read_avail_input (expected)
 {
   int nread = 0;
   int err = 0;
-  struct display *d;
+  struct device *d;
 
-  /* Loop through the available displays, and call their input hooks. */
-  d = display_list;
+  /* Loop through the available devices, and call their input hooks. */
+  d = device_list;
   while (d)
     {
-      struct display *next = d->next_display;
+      struct device *next = d->next_device;
 
       if (d->read_socket_hook)
         {
@@ -6680,7 +6706,7 @@ read_avail_input (expected)
               /* The display device terminated; it should be closed. */
               
               /* Kill Emacs if this was our last display. */
-              if (! display_list->next_display)
+              if (! device_list->next_device)
                 /* 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
@@ -6691,11 +6717,11 @@ read_avail_input (expected)
                    alone in its group.  */
                 kill (getpid (), SIGHUP);
               
-              /* XXX Is calling delete_display safe here?  It calls Fdelete_frame. */
-              if (d->delete_display_hook)
-                (*d->delete_display_hook) (d);
+              /* XXX Is calling delete_device safe here?  It calls Fdelete_frame. */
+              if (d->delete_device_hook)
+                (*d->delete_device_hook) (d);
               else
-                delete_display (d);
+                delete_device (d);
             }
 
           if (hold_quit.kind != NO_EVENT)
@@ -6713,12 +6739,12 @@ read_avail_input (expected)
 
 /* This is the tty way of reading available input.
 
-   Note that each terminal device has its own `struct display' object,
+   Note that each terminal device has its own `struct device' 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,
+tty_read_avail_input (struct device *device,
                       int expected,
                       struct input_event *hold_quit)
 {
@@ -6727,10 +6753,10 @@ tty_read_avail_input (struct display *display,
      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;
+  struct tty_display_info *tty = device->display_info.tty;
   int nread = 0;
 
-  if (display->type != output_termcap)
+  if (device->type != output_termcap)
     abort ();
 
   /* XXX I think the following code should be moved to separate hook
@@ -6760,7 +6786,7 @@ tty_read_avail_input (struct display *display,
   if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
     {
       if (! noninteractive)
-        return -2;          /* Close this display. */
+        return -2;          /* Close this device. */
       else
         n_to_read = 0;
     }
@@ -6789,14 +6815,14 @@ tty_read_avail_input (struct display *display,
          when the control tty is taken away.
          Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
       if (nread == -1 && errno == EIO)
-        return -2;          /* Close this display. */
+        return -2;          /* Close this device. */
 #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)
-        return -2;          /* Close this display. */
+        return -2;          /* Close this device. */
 #endif
     }
   while (
@@ -6976,8 +7002,6 @@ menu_bar_items (old)
 
   int i;
 
-  struct gcpro gcpro1;
-
   /* In order to build the menus, we need to call the keymap
      accessors.  They all call QUIT.  But this function is called
      during redisplay, during which a quit is fatal.  So inhibit
@@ -6993,8 +7017,6 @@ menu_bar_items (old)
     menu_bar_items_vector = Fmake_vector (make_number (24), Qnil);
   menu_bar_items_index = 0;
 
-  GCPRO1 (menu_bar_items_vector);
-
   /* Build our list of keymaps.
      If we recognize a function key and replace its escape sequence in
      keybuf with its symbol, or if the sequence starts with a mouse
@@ -7098,7 +7120,6 @@ menu_bar_items (old)
   menu_bar_items_index = i;
 
   Vinhibit_quit = oquit;
-  UNGCPRO;
   return menu_bar_items_vector;
 }
 \f
@@ -8644,8 +8665,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
   last_nonmenu_event = Qnil;
 
   delayed_switch_frame = Qnil;
-  fkey.map = fkey.parent = Vfunction_key_map;
-  keytran.map = keytran.parent = Vkey_translation_map;
+  fkey.map = fkey.parent = current_kboard->Vlocal_function_key_map;
+  keytran.map = keytran.parent = current_kboard->Vlocal_key_translation_map;
   /* If there is no translation-map, turn off scanning.  */
   fkey.start = fkey.end = KEYMAPP (fkey.map) ? 0 : bufsize + 1;
   keytran.start = keytran.end = KEYMAPP (keytran.map) ? 0 : bufsize + 1;
@@ -9873,7 +9894,7 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
 
   /* If enabled, show which key runs this command.  */
   if (!NILP (Vsuggest_key_bindings)
-      && NILP (Vexecuting_macro)
+      && NILP (Vexecuting_kbd_macro)
       && SYMBOLP (function))
     bindings = Fwhere_is_internal (function, Voverriding_local_map,
                                   Qt, Qnil, Qnil);
@@ -10343,7 +10364,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;
+  struct device *device;
 
 #if defined (USG) && !defined (POSIX_SIGNALS)
   /* USG systems forget handlers when they are used;
@@ -10355,8 +10376,8 @@ interrupt_signal (signalnum)    /* If we don't have an argument, */
   SIGNAL_THREAD_CHECK (signalnum);
 
   /* See if we have an active display on our controlling terminal. */
-  display = get_named_tty_display (NULL);
-  if (!display)
+  device = get_named_tty (NULL);
+  if (!device)
     {
       /* If there are no frames there, let's pretend that we are a
          well-behaving UN*X program and quit. */
@@ -10370,7 +10391,7 @@ interrupt_signal (signalnum)    /* If we don't have an argument, */
          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;
+      internal_last_event_frame = device->display_info.tty->top_frame;
 
       handle_interrupt ();
     }
@@ -10399,7 +10420,7 @@ handle_interrupt ()
   /* XXX This code needs to be revised for multi-tty support. */
   if (!NILP (Vquit_flag)
 #ifndef MSDOS
-      && get_named_tty_display (NULL)
+      && get_named_tty (NULL)
 #endif
       )
     {
@@ -10577,13 +10598,14 @@ See also `current-input-mode'.  */)
 #endif
 
 #ifndef DOS_NT
-  /* this causes startup screen to be restored and messes with the mouse */
-  reset_all_sys_modes ();
+  if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+    /* this causes startup screen to be restored and messes with the mouse */
+    reset_sys_modes (CURTTY ());
 #endif
 
 #ifdef SIGIO
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
-  if (FRAME_DISPLAY (SELECTED_FRAME ())->read_socket_hook)
+  if (FRAME_DEVICE (SELECTED_FRAME ())->read_socket_hook)
     {
       /* When using X, don't give the user a real choice,
         because we haven't implemented the mechanisms to support it.  */
@@ -10621,7 +10643,8 @@ See also `current-input-mode'.  */)
     quit_char = XINT (quit) & (NILP (meta) ? 0177 : 0377);
 
 #ifndef DOS_NT
-  init_all_sys_modes ();
+  if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+    init_sys_modes (CURTTY ());
 #endif
 
 #ifdef POLL_FOR_INPUT
@@ -10671,7 +10694,7 @@ The elements of this list correspond to the arguments of
 DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0,
        doc: /* Return position information for pixel coordinates X and Y.
 By default, X and Y are relative to text area of the selected window.
-Optional third arg FRAME_OR_WINDOW non-nil specifies frame or window.
+Optional third arg FRAME-OR-WINDOW non-nil specifies frame or window.
 If optional fourth arg WHOLE is non-nil, X is relative to the left
 edge of the window.
 
@@ -10756,6 +10779,10 @@ init_kboard (kb)
   kb->reference_count = 0;
   kb->Vsystem_key_alist = Qnil;
   kb->system_key_syms = Qnil;
+  kb->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
+  Fset_keymap_parent (kb->Vlocal_function_key_map, Vfunction_key_map);
+  kb->Vlocal_key_translation_map = Fmake_sparse_keymap (Qnil);
+  Fset_keymap_parent (kb->Vlocal_key_translation_map, Vkey_translation_map);
   kb->Vdefault_minibuffer_frame = Qnil;
 }
 
@@ -10792,7 +10819,7 @@ delete_kboard (kb)
       && FRAMEP (selected_frame)
       && FRAME_LIVE_P (XFRAME (selected_frame)))
     {
-      current_kboard = XFRAME (selected_frame)->kboard;
+      current_kboard = XFRAME (selected_frame)->device->kboard;
       if (current_kboard == kb)
        abort ();
     }
@@ -10959,9 +10986,6 @@ syms_of_keyboard ()
   Qpost_command_hook = intern ("post-command-hook");
   staticpro (&Qpost_command_hook);
 
-  Qpost_command_idle_hook = intern ("post-command-idle-hook");
-  staticpro (&Qpost_command_idle_hook);
-
   Qdeferred_action_function = intern ("deferred-action-function");
   staticpro (&Qdeferred_action_function);
 
@@ -10972,7 +10996,7 @@ syms_of_keyboard ()
   staticpro (&Qfunction_key);
   Qmouse_click = intern ("mouse-click");
   staticpro (&Qmouse_click);
-#ifdef WINDOWSNT
+#if defined (WINDOWSNT) || defined (MAC_OS)
   Qlanguage_change = intern ("language-change");
   staticpro (&Qlanguage_change);
 #endif
@@ -10980,7 +11004,7 @@ syms_of_keyboard ()
   staticpro (&Qdrag_n_drop);
 
   Qsave_session = intern ("save-session");
-  staticpro(&Qsave_session);
+  staticpro (&Qsave_session);
 
   Qusr1_signal = intern ("usr1-signal");
   staticpro (&Qusr1_signal);
@@ -11139,6 +11163,9 @@ syms_of_keyboard ()
   menu_bar_one_keymap_changed_items = Qnil;
   staticpro (&menu_bar_one_keymap_changed_items);
 
+  menu_bar_items_vector = Qnil;
+  staticpro (&menu_bar_items_vector);
+
   defsubr (&Sevent_convert_list);
   defsubr (&Sread_key_sequence);
   defsubr (&Sread_key_sequence_vector);
@@ -11223,7 +11250,10 @@ In other words, the present command is the event that made the previous
 command exit.
 
 The value `kill-region' is special; it means that the previous command
-was a kill command.  */);
+was a kill command.
+
+`last-command' has a separate binding for each display device.
+See Info node `(elisp)Multiple displays'.  */);
 
   DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
                 doc: /* Same as `last-command', but never altered by Lisp code.  */);
@@ -11407,21 +11437,12 @@ the hook value is set to nil, since otherwise the error
 might happen repeatedly and make Emacs nonfunctional.  */);
   Vpost_command_hook = Qnil;
 
-  DEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook,
-              doc: /* Normal hook run after each command is executed, if idle.
-Errors running the hook are caught and ignored.  */);
-  Vpost_command_idle_hook = Qnil;
-
-  DEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay,
-             doc: /* Delay time before running `post-command-idle-hook'.
-This is measured in microseconds.  */);
-  post_command_idle_delay = 100000;
-
 #if 0
   DEFVAR_LISP ("echo-area-clear-hook", ...,
               doc: /* Normal hook run when clearing the echo area.  */);
 #endif
   Qecho_area_clear_hook = intern ("echo-area-clear-hook");
+  staticpro (&Qecho_area_clear_hook);
   SET_SYMBOL_VALUE (Qecho_area_clear_hook, Qnil);
 
   DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag,
@@ -11441,7 +11462,10 @@ buffer's local map, and the minor mode keymaps and text property keymaps.
 It also replaces `overriding-local-map'.
 
 This variable is intended to let commands such as `universal-argument'
-set up a different keymap for reading the next command.  */);
+set up a different keymap for reading the next command.
+
+`overriding-terminal-local-map' has a separate binding for each display device.
+See Info node `(elisp)Multiple displays'.  */);
 
   DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map,
               doc: /* Keymap that overrides all other local keymaps.
@@ -11466,7 +11490,70 @@ and the minor mode maps regardless of `overriding-local-map'.  */);
                 doc: /* Alist of system-specific X windows key symbols.
 Each element should have the form (N . SYMBOL) where N is the
 numeric keysym code (sans the \"system-specific\" bit 1<<28)
-and SYMBOL is its name.  */);
+and SYMBOL is its name.
+
+`system-key-alist' has a separate binding for each display device.
+See Info node `(elisp)Multiple displays'.
+
+Note that the currently selected frame has very little to do with
+which binding of this variable is active at any given moment.  If you
+need set or get the binding on a specific display, use
+`terminal-local-value' and `set-terminal-local-value'.  */);
+
+  DEFVAR_KBOARD ("local-function-key-map", Vlocal_function_key_map,
+                 doc: /* Keymap mapping ASCII function key sequences onto their preferred forms.
+This allows Emacs to recognize function keys sent from ASCII
+terminals at any point in a key sequence.
+
+The `read-key-sequence' function replaces any subsequence bound by
+`function-key-map' with its binding.  More precisely, when the active
+keymaps have no binding for the current key sequence but
+`function-key-map' binds a suffix of the sequence to a vector or string,
+`read-key-sequence' replaces the matching suffix with its binding, and
+continues with the new sequence.
+
+The events that come from bindings in `function-key-map' are not
+themselves looked up in `function-key-map'.
+
+For example, suppose `function-key-map' binds `ESC O P' to [f1].
+Typing `ESC O P' to `read-key-sequence' would return [f1].  Typing
+`C-x ESC O P' would return [?\\C-x f1].  If [f1] were a prefix
+key, typing `ESC O P x' would return [f1 x].
+
+`function-key-map' has a separate binding for each display device.
+See Info node `(elisp)Multiple displays'.  If you need to define a
+binding on all display devices, change `global-function-key-map'
+instead.
+
+Note that the currently selected frame has very little to do with
+which binding of this variable is active at any given moment.  If you
+need set or get the binding on a specific display, use
+`terminal-local-value' and `set-terminal-local-value'.  */);
+
+  DEFVAR_LISP ("function-key-map", &Vfunction_key_map,
+               doc: /* The parent keymap of all `local-function-key-map' instances.
+Function key definitions that apply to all display devices should go
+here.  */);
+  Vfunction_key_map = Fmake_sparse_keymap (Qnil);
+                    
+  DEFVAR_KBOARD ("local-key-translation-map", Vlocal_key_translation_map,
+              doc: /* Keymap of key translations that can override keymaps.
+This keymap works like `function-key-map', but comes after that,
+and its non-prefix bindings override ordinary bindings.
+
+`key-translation-map' has a separate binding for each display device.
+(See Info node `(elisp)Multiple displays'.)  If you need to set a key
+translation on all devices, change `global-key-translation-map' instead.
+
+Note that the currently selected frame has very little to do with
+which binding of this variable is active at any given moment.  If you
+need set or get the binding on a specific display, use
+`terminal-local-value' and `set-terminal-local-value'.  */);
+
+  DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
+               doc: /* The parent keymap of all `local-key-translation-map' instances.
+Key translations that apply to all display devices should go here.  */);
+  Vkey_translation_map = Fmake_sparse_keymap (Qnil);
 
   DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list,
               doc: /* List of deferred actions to be performed at a later time.
@@ -11631,6 +11718,8 @@ mark_kboards ()
       mark_object (kb->Vlast_kbd_macro);
       mark_object (kb->Vsystem_key_alist);
       mark_object (kb->system_key_syms);
+      mark_object (kb->Vlocal_function_key_map);
+      mark_object (kb->Vlocal_key_translation_map);
       mark_object (kb->Vdefault_minibuffer_frame);
       mark_object (kb->echo_string);
     }