]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
Document what does mouse-3 do on the mode line if there's only one window.
[gnu-emacs] / src / keyboard.c
index 16df84b80f51466730aad048f2044c1be769b024..15c05e8f44e9c324fbef9aeeb38b73178a816962 100644 (file)
@@ -70,6 +70,10 @@ Boston, MA 02111-1307, USA.  */
 #include "w32term.h"
 #endif /* HAVE_NTGUI */
 
+#ifdef macintosh
+#include "macterm.h"
+#endif
+
 /* Include systime.h after xterm.h to avoid double inclusion of time.h. */
 #include "systime.h"
 
@@ -93,7 +97,7 @@ extern int input_fd;
 #ifdef HAVE_WINDOW_SYSTEM
 /* Make all keyboard buffers much bigger when using X windows.  */
 #ifdef macintosh
-/* But not too big (local data > 32K error) if on macintosh */
+/* But not too big (local data > 32K error) if on macintosh */
 #define KBD_BUFFER_SIZE 512
 #else
 #define KBD_BUFFER_SIZE 4096
@@ -247,6 +251,10 @@ Lisp_Object Vmenu_bar_final_items;
    If the value is non-nil and not a number, we wait 2 seconds.  */
 Lisp_Object Vsuggest_key_bindings;
 
+/* How long to display an echo-area message when the minibuffer is active.
+   If the value is not a number, such messages don't time out.  */
+Lisp_Object Vminibuffer_message_timeout;
+
 /* Character that causes a quit.  Normally C-g.
 
    If we are running on an ordinary terminal, this must be an ordinary
@@ -515,7 +523,7 @@ static struct input_event * volatile kbd_store_ptr;
 /* If this flag is non-nil, we check mouse_moved to see when the
    mouse moves, and motion events will appear in the input stream.
    Otherwise, mouse motion is ignored.  */
-static Lisp_Object do_mouse_tracking;
+Lisp_Object do_mouse_tracking;
 
 /* Symbols to head events.  */
 Lisp_Object Qmouse_movement;
@@ -682,17 +690,39 @@ static int cannot_suspend;
 
 void
 echo_prompt (str)
-     char *str;
+     Lisp_Object str;
 {
-  int len = strlen (str);
+  int nbytes = STRING_BYTES (XSTRING (str));
+  int multibyte_p = STRING_MULTIBYTE (str);
 
-  if (len > ECHOBUFSIZE - 4)
-    len = ECHOBUFSIZE - 4;
-  bcopy (str, current_kboard->echobuf, len);
-  current_kboard->echoptr = current_kboard->echobuf + len;
-  *current_kboard->echoptr = '\0';
+  if (nbytes > ECHOBUFSIZE - 4)
+    {
+      if (multibyte_p)
+       {
+         /* Have to find the last character that fit's into the 
+            echo buffer.  */
+         unsigned char *p = XSTRING (str)->data;
+         unsigned char *pend = p + ECHOBUFSIZE - 4;
+         int char_len;
+
+         do 
+           {
+             PARSE_MULTIBYTE_SEQ (p, pend - p, char_len);
+             p += char_len;
+           }
+         while (p < pend);
 
-  current_kboard->echo_after_prompt = len;
+         nbytes = p - XSTRING (str)->data - char_len;
+       }
+      else
+       nbytes = ECHOBUFSIZE - 4;
+    }
+
+  nbytes = copy_text (XSTRING (str)->data, current_kboard->echobuf, nbytes,
+                     STRING_MULTIBYTE (str), 1);
+  current_kboard->echoptr = current_kboard->echobuf + nbytes;
+  *current_kboard->echoptr = '\0';
+  current_kboard->echo_after_prompt = nbytes;
 
   echo_now ();
 }
@@ -705,8 +735,6 @@ void
 echo_char (c)
      Lisp_Object c;
 {
-  extern char *push_key_description ();
-
   if (current_kboard->immediate_echo)
     {
       char *ptr = current_kboard->echoptr;
@@ -719,11 +747,13 @@ echo_char (c)
 
       if (INTEGERP (c))
        {
+         int ch = XINT (c);
+
          if (ptr - current_kboard->echobuf
              > ECHOBUFSIZE - KEY_DESCRIPTION_SIZE)
            return;
 
-         ptr = push_key_description (XINT (c), ptr);
+         ptr = push_key_description (ch, ptr, 1);
        }
       else if (SYMBOLP (c))
        {
@@ -731,8 +761,8 @@ echo_char (c)
          if ((ptr - current_kboard->echobuf) + STRING_BYTES (name) + 4
              > ECHOBUFSIZE)
            return;
-         bcopy (name->data, ptr, STRING_BYTES (name));
-         ptr += STRING_BYTES (name);
+         ptr += copy_text (name->data, ptr, STRING_BYTES (name),
+                           name->size_byte >= 0, 1);
        }
 
       if (current_kboard->echoptr == current_kboard->echobuf
@@ -798,7 +828,7 @@ echo_now ()
 
   echoing = 1;
   message2_nolog (current_kboard->echobuf, strlen (current_kboard->echobuf),
-                 ! NILP (current_buffer->enable_multibyte_characters));
+                 1);
   echoing = 0;
 
   /* Record in what buffer we echoed, and from which kboard.  */
@@ -1329,18 +1359,19 @@ command_loop_1 ()
       Vdeactivate_mark = Qnil;
 
       /* If minibuffer on and echo area in use,
-        wait 2 sec and redraw minibuffer.  */
+        wait a short time and redraw minibuffer.  */
 
       if (minibuf_level
          && !NILP (echo_area_buffer[0])
-         && EQ (minibuf_window, echo_area_window))
+         && EQ (minibuf_window, echo_area_window)
+         && NUMBERP (Vminibuffer_message_timeout))
        {
          /* Bind inhibit-quit to t so that C-g gets read in
             rather than quitting back to the minibuffer.  */
          int count = specpdl_ptr - specpdl;
          specbind (Qinhibit_quit, Qt);
 
-         Fsit_for (make_number (2), Qnil, Qnil);
+         Fsit_for (Vminibuffer_message_timeout, Qnil, Qnil);
          /* Clear the echo area.  */
          message2 (0, 0, 0);
          safe_run_hooks (Qecho_area_clear_hook);
@@ -1997,7 +2028,7 @@ show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo)
            {
              int count = specpdl_ptr - specpdl;
              specbind (Qmessage_truncate_lines, Qt);
-             message3_nolog (help, XSTRING (help)->size,
+             message3_nolog (help, STRING_BYTES (XSTRING (help)),
                              STRING_MULTIBYTE (help));
              unbind_to (count, Qnil);
            }
@@ -2190,7 +2221,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       while (!input_pending)
        {
          if (help_echo_showing_p && !EQ (selected_window, minibuf_window))
-           redisplay_preserve_echo_area ();
+           redisplay_preserve_echo_area (5);
          else
            redisplay ();
 
@@ -2500,6 +2531,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
       /* Actually read a character, waiting if necessary.  */
       save_getcjmp (save_jump);
       restore_getcjmp (local_getcjmp);
+      timer_start_idle ();
       c = kbd_buffer_get_event (&kb, used_mouse_menu);
       restore_getcjmp (save_jump);
 
@@ -2546,7 +2578,6 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
  non_reread:
 
   timer_stop_idle ();
-
   start_polling ();
 
   if (NILP (c))
@@ -2570,8 +2601,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
      and loop around to read another event.  */
   save = Vquit_flag;
   Vquit_flag = Qnil;
-  tem = get_keyelt (access_keymap (get_keymap_1 (Vspecial_event_map, 0, 0),
-                                  c, 0, 0), 1);
+  tem = access_keymap (get_keymap (Vspecial_event_map, 0, 1), c, 0, 0, 1);
   Vquit_flag = save;
 
   if (!NILP (tem))
@@ -2883,11 +2913,44 @@ static void
 record_char (c)
      Lisp_Object c;
 {
-  total_keys++;
-  XVECTOR (recent_keys)->contents[recent_keys_index] = c;
-  if (++recent_keys_index >= NUM_RECENT_KEYS)
-    recent_keys_index = 0;
+  /* Don't record `help-echo' in recent_keys unless it shows some help
+     message, and a different help than the previoiusly recorded
+     event.  */
+  if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
+    {
+      Lisp_Object help;
 
+      help = Fnth (make_number (2), c);
+      if (STRINGP (help))
+       {
+         int last_idx;
+         Lisp_Object last_c, last_help;
+         
+         last_idx = recent_keys_index - 1;
+         if (last_idx < 0)
+           last_idx = NUM_RECENT_KEYS - 1;
+         last_c = AREF (recent_keys, last_idx);
+         
+         if (!CONSP (last_c)
+             || !EQ (XCAR (last_c), Qhelp_echo)
+             || (last_help = Fnth (make_number (2), last_c),
+                 !EQ (last_help, help)))
+           {
+             total_keys++;
+             ASET (recent_keys, recent_keys_index, c);
+             if (++recent_keys_index >= NUM_RECENT_KEYS)
+               recent_keys_index = 0;
+           }
+       }
+    }
+  else
+    {
+      total_keys++;
+      ASET (recent_keys, recent_keys_index, c);
+      if (++recent_keys_index >= NUM_RECENT_KEYS)
+       recent_keys_index = 0;
+    }
+      
   /* Write c to the dribble file.  If c is a lispy event, write
      the event's symbol to the dribble file, in <brackets>.  Bleaugh.
      If you, dear reader, have a better idea, you've got the source.  :-) */
@@ -2920,7 +2983,8 @@ record_char (c)
       fflush (dribble);
     }
 
-  store_kbd_macro_char (c);
+  if (!CONSP (c) || !EQ (Qhelp_echo, XCAR (c)))
+    store_kbd_macro_char (c);
 
   num_nonmacro_input_events++;
 }
@@ -2975,7 +3039,7 @@ tracking_off (old_value)
         redisplay.  */
       if (!readable_events (1))
        {
-         redisplay_preserve_echo_area ();
+         redisplay_preserve_echo_area (6);
          get_input_pending (&input_pending, 1);
        }
     }
@@ -3475,7 +3539,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
          abort ();
 #endif
        }
-#if defined (HAVE_X11) || defined (HAVE_NTGUI)
+#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (macintosh)
       else if (event->kind == delete_window_event)
        {
          /* Make an event (delete-frame (FRAME)).  */
@@ -3483,6 +3547,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
          obj = Fcons (Qdelete_frame, Fcons (obj, Qnil));
          kbd_fetch_ptr = event + 1;
        }
+#endif
+#if defined (HAVE_X11) || defined (HAVE_NTGUI)
       else if (event->kind == iconify_event)
        {
          /* Make an event (iconify-frame (FRAME)).  */
@@ -3504,7 +3570,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
          XSETBUFFER (obj, current_buffer);
          kbd_fetch_ptr = event + 1;
        }
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
       else if (event->kind == menu_bar_activate_event)
        {
          kbd_fetch_ptr = event + 1;
@@ -3604,8 +3670,6 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
 
          if (NILP (obj))
            {
-             int idx;
-             
              obj = make_lispy_event (event);
              
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
@@ -3746,7 +3810,7 @@ swallow_events (do_display)
   get_input_pending (&input_pending, 1);
 
   if (timers_run != old_timers_run && do_display)
-    redisplay_preserve_echo_area ();
+    redisplay_preserve_echo_area (7);
 }
 \f
 static EMACS_TIME timer_idleness_start_time;
@@ -4694,7 +4758,7 @@ make_lispy_event (event)
 
                if (part == 1 || part == 3)
                  {
-                   /* Mode line or top line.  Look for a string under
+                   /* Mode line or header line.  Look for a string under
                       the mouse that may have a `local-map' property.  */
                    Lisp_Object string;
                    int charpos;
@@ -4965,7 +5029,8 @@ make_lispy_event (event)
          return Qnil;
        pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
                               &column, &row, NULL, 1);
-       window = window_from_coordinates (f, column, row, &part, 0);
+       window = window_from_coordinates (f, XINT (event->x),
+                                          XINT (event->y), &part, 0);
 
        if (!WINDOWP (window))
          {
@@ -5023,7 +5088,6 @@ make_lispy_event (event)
        Lisp_Object window;
        Lisp_Object posn;
        Lisp_Object files;
-       int row, column;
 
        /* The frame_or_window field should be a cons of the frame in
           which the event occurred and a list of the filenames
@@ -5038,9 +5102,9 @@ make_lispy_event (event)
           have been deleted.  */
        if (! FRAME_LIVE_P (f))
          return Qnil;
-       pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
-                              &column, &row, NULL, 1);
-       window = window_from_coordinates (f, column, row, &part, 0);
+
+       window = window_from_coordinates (f, XINT (event->x),
+                                          XINT (event->y), &part, 0);
 
        if (!WINDOWP (window))
          {
@@ -5094,7 +5158,7 @@ make_lispy_event (event)
       }
 #endif /* HAVE_MOUSE */
 
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
     case MENU_BAR_EVENT:
       if (EQ (event->arg, event->frame_or_window))
        /* This is the prefix key.  We translate this to
@@ -5814,6 +5878,12 @@ lucid_event_type_list_p (object)
   if (! CONSP (object))
     return 0;
 
+  if (EQ (XCAR (object), Qhelp_echo)
+      || EQ (XCAR (object), Qvertical_line)
+      || EQ (XCAR (object), Qmode_line)
+      || EQ (XCAR (object), Qheader_line))
+    return 0;
+
   for (tail = object; CONSP (tail); tail = XCDR (tail))
     {
       Lisp_Object elt;
@@ -6182,7 +6252,7 @@ menu_bar_items (old)
      in the current keymaps, or nil where it is not a prefix.  */
   Lisp_Object *maps;
 
-  Lisp_Object def, tem, tail;
+  Lisp_Object def, tail;
 
   Lisp_Object result;
 
@@ -6233,7 +6303,7 @@ menu_bar_items (old)
       {
        /* No, so use major and minor mode keymaps and keymap property.  */
        int extra_maps = 2;
-       Lisp_Object map = get_local_map (PT, current_buffer, keymap);
+       Lisp_Object map = get_local_map (PT, current_buffer, Qkeymap);
        if (!NILP (map))
          extra_maps = 3;
        nmaps = current_minor_maps (NULL, &tmaps);
@@ -6242,7 +6312,7 @@ menu_bar_items (old)
        bcopy (tmaps, maps, nmaps * sizeof (maps[0]));
        if (!NILP (map))
          maps[nmaps++] = map;
-       maps[nmaps++] = get_local_map (PT, current_buffer, local_map);
+       maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
       }
     maps[nmaps++] = current_global_map;
   }
@@ -6254,9 +6324,9 @@ menu_bar_items (old)
   for (mapno = nmaps - 1; mapno >= 0; mapno--)
     if (!NILP (maps[mapno]))
       {
-       def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1, 0), 0);
-       tem = Fkeymapp (def);
-       if (!NILP (tem))
+       def = get_keymap (access_keymap (maps[mapno], Qmenu_bar, 1, 0, 1),
+                         0, 1);
+       if (CONSP (def))
          menu_bar_one_keymap (def);
       }
 
@@ -6322,11 +6392,6 @@ menu_bar_one_keymap (keymap)
 {
   Lisp_Object tail, item;
 
-  /* If KEYMAP is a symbol, its function definition is the keymap
-     to use.  */
-  if (SYMBOLP (keymap))
-    keymap = indirect_function (keymap);
-
   menu_bar_one_keymap_changed_items = Qnil;
 
   /* Loop over all keymap entries that have menu strings.  */
@@ -6656,9 +6721,9 @@ parse_menu_item (item, notreal, inmenubar)
 
   /* See if this is a separate pane or a submenu.  */
   def = AREF (item_properties, ITEM_PROPERTY_DEF);
-  tem = get_keymap_1 (def, 0, 1);
+  tem = get_keymap (def, 0, 1);
   /* For a subkeymap, just record its details and exit.  */
-  if (!NILP (tem))
+  if (CONSP (tem))
     {
       AREF (item_properties, ITEM_PROPERTY_MAP) = tem;
       AREF (item_properties, ITEM_PROPERTY_DEF) = tem;
@@ -6890,7 +6955,7 @@ tool_bar_items (reuse, nitems)
     {
       /* No, so use major and minor mode keymaps and keymap property.  */
       int extra_maps = 2;
-      Lisp_Object map = get_local_map (PT, current_buffer, keymap);
+      Lisp_Object map = get_local_map (PT, current_buffer, Qkeymap);
       if (!NILP (map))
        extra_maps = 3;
       nmaps = current_minor_maps (NULL, &tmaps);
@@ -6899,7 +6964,7 @@ tool_bar_items (reuse, nitems)
       bcopy (tmaps, maps, nmaps * sizeof (maps[0]));
       if (!NILP (map))
        maps[nmaps++] = map;
-      maps[nmaps++] = get_local_map (PT, current_buffer, local_map);
+      maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
     }
 
   /* Add global keymap at the end.  */
@@ -6911,17 +6976,12 @@ tool_bar_items (reuse, nitems)
     if (!NILP (maps[i]))
       {
        Lisp_Object keymap;
-      
-       keymap = get_keyelt (access_keymap (maps[i], Qtool_bar, 1, 1), 0);
-       if (!NILP (Fkeymapp (keymap)))
+
+       keymap = get_keymap (access_keymap (maps[i], Qtool_bar, 1, 0, 1), 0, 1);
+       if (CONSP (keymap))
          {
            Lisp_Object tail;
            
-           /* If KEYMAP is a symbol, its function definition is the
-              keymap to use.  */
-           if (SYMBOLP (keymap))
-             keymap = indirect_function (keymap);
-
            /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'.  */
            for (tail = keymap; CONSP (tail); tail = XCDR (tail))
              {
@@ -7138,7 +7198,7 @@ parse_tool_bar_item (key, item)
                                               PROP (TOOL_BAR_ITEM_BINDING))));
 
   /* See if the binding is a keymap.  Give up if it is.  */
-  if (!NILP (get_keymap_1 (PROP (TOOL_BAR_ITEM_BINDING), 0, 1)))
+  if (CONSP (get_keymap (PROP (TOOL_BAR_ITEM_BINDING), 0, 1)))
     return 0;
 
   /* Enable or disable selection of item.  */
@@ -7599,31 +7659,6 @@ follow_key (key, nmaps, current, defs, next)
   int i, first_binding;
   int did_meta = 0;
 
-  /* If KEY is a meta ASCII character, treat it like meta-prefix-char
-     followed by the corresponding non-meta character.
-     Put the results into DEFS, since we are going to alter that anyway.
-     Do not alter CURRENT or NEXT.  */
-  if (INTEGERP (key) && (XUINT (key) & CHAR_META))
-    {
-      for (i = 0; i < nmaps; i++)
-       if (! NILP (current[i]))
-         {
-           Lisp_Object def;
-           def = get_keyelt (access_keymap (current[i],
-                                            meta_prefix_char, 1, 0), 0);
-
-           /* Note that since we pass the resulting bindings through
-              get_keymap_1, non-prefix bindings for meta-prefix-char
-              disappear.  */
-           defs[i] = get_keymap_1 (def, 0, 1);
-         }
-       else
-         defs[i] = Qnil;
-
-      did_meta = 1;
-      XSETINT (key, XFASTINT (key) & ~CHAR_META);
-    }
-
   first_binding = nmaps;
   for (i = nmaps - 1; i >= 0; i--)
     {
@@ -7635,7 +7670,7 @@ follow_key (key, nmaps, current, defs, next)
          else
            map = current[i];
 
-         defs[i] = get_keyelt (access_keymap (map, key, 1, 0), 1);
+         defs[i] = access_keymap (map, key, 1, 0, 1);
          if (! NILP (defs[i]))
            first_binding = i;
        }
@@ -7646,7 +7681,7 @@ follow_key (key, nmaps, current, defs, next)
   /* Given the set of bindings we've found, produce the next set of maps.  */
   if (first_binding < nmaps)
     for (i = 0; i < nmaps; i++)
-      next[i] = NILP (defs[i]) ? Qnil : get_keymap_1 (defs[i], 0, 1);
+      next[i] = NILP (defs[i]) ? Qnil : get_keymap (defs[i], 0, 1);
 
   return first_binding;
 }
@@ -7812,17 +7847,17 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
   keytran_map = Vkey_translation_map;
 
   /* If there is no function-key-map, turn off function key scanning.  */
-  if (NILP (Fkeymapp (Vfunction_key_map)))
+  if (!KEYMAPP (Vfunction_key_map))
     fkey_start = fkey_end = bufsize + 1;
 
   /* If there is no key-translation-map, turn off scanning.  */
-  if (NILP (Fkeymapp (Vkey_translation_map)))
+  if (!KEYMAPP (Vkey_translation_map))
     keytran_start = keytran_end = bufsize + 1;
 
   if (INTERACTIVE)
     {
       if (!NILP (prompt))
-       echo_prompt (XSTRING (prompt)->data);
+       echo_prompt (prompt);
       else if (cursor_in_echo_area
               && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
               && NILP (Fzerop (Vecho_keystrokes)))
@@ -7849,8 +7884,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                           &junk);
 #endif /* GOBBLE_FIRST_EVENT */
 
-  orig_local_map = get_local_map (PT, current_buffer, local_map);
-  orig_keymap = get_local_map (PT, current_buffer, keymap);
+  orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
+  orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
 
   /* We jump here when the key sequence has been thoroughly changed, and
      we need to rescan it starting from the beginning.  When we jump here,
@@ -8019,8 +8054,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                               interrupted_kboard->kbd_queue);
                  }
                mock_input = 0;
-               orig_local_map = get_local_map (PT, current_buffer, local_map);
-               orig_keymap = get_local_map (PT, current_buffer, keymap);
+               orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
+               orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
                goto replay_sequence;
              }
 #endif
@@ -8066,8 +8101,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                    Fset_buffer (XWINDOW (selected_window)->buffer);
                }
 
-             orig_local_map = get_local_map (PT, current_buffer, local_map);
-             orig_keymap = get_local_map (PT, current_buffer, keymap);
+             orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
+             orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
              goto replay_sequence;
            }
 
@@ -8081,8 +8116,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
              keybuf[t++] = key;
              mock_input = t;
              Vquit_flag = Qnil;
-             orig_local_map = get_local_map (PT, current_buffer, local_map);
-             orig_keymap = get_local_map (PT, current_buffer, keymap);
+             orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
+             orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
              goto replay_sequence;
            }
 
@@ -8167,12 +8202,10 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
 
                  if (! FRAME_LIVE_P (XFRAME (selected_frame)))
                    Fkill_emacs (Qnil);
-                 set_buffer_internal (XBUFFER (XWINDOW
-                 (window)->buffer)
-);
+                 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
                  orig_local_map = get_local_map (PT, current_buffer,
-                                                 local_map);
-                 orig_keymap = get_local_map (PT, current_buffer, keymap);
+                                                 Qlocal_map);
+                 orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
                  goto replay_sequence;
                }
              
@@ -8194,7 +8227,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                          && XINT (pos) >= BEG && XINT (pos) <= Z)
                        {
                          map_here = get_local_map (XINT (pos),
-                                                   current_buffer, local_map);
+                                                   current_buffer, Qlocal_map);
                          if (!EQ (map_here, orig_local_map))
                            {
                              orig_local_map = map_here;
@@ -8204,7 +8237,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                              goto replay_sequence;
                            }
                          map_here = get_local_map (XINT (pos),
-                                                    current_buffer, keymap);
+                                                    current_buffer, Qkeymap);
                          if (!EQ (map_here, orig_keymap))
                            {
                              orig_keymap = map_here;
@@ -8457,22 +8490,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
              Lisp_Object key;
 
              key = keybuf[fkey_end++];
-             /* Look up meta-characters by prefixing them
-                with meta_prefix_char.  I hate this.  */
-             if (INTEGERP (key) && XUINT (key) & meta_modifier)
-               {
-                 fkey_next
-                   = get_keymap_1
-                     (get_keyelt
-                      (access_keymap (fkey_map, meta_prefix_char, 1, 0), 0),
-                      0, 1);
-                 XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
-               }
-             else
-               fkey_next = fkey_map;
-
              fkey_next
-               = get_keyelt (access_keymap (fkey_next, key, 1, 0), 1);
+               = access_keymap (fkey_map, key, 1, 0, 1);
 
              /* Handle symbol with autoload definition.  */
              if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))
@@ -8485,7 +8504,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                 or an array.  */
              if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))
                  && (!NILP (Farrayp (XSYMBOL (fkey_next)->function))
-                     || !NILP (Fkeymapp (XSYMBOL (fkey_next)->function))))
+                     || KEYMAPP (XSYMBOL (fkey_next)->function)))
                fkey_next = XSYMBOL (fkey_next)->function;
 
 #if 0 /* I didn't turn this on, because it might cause trouble
@@ -8558,11 +8577,11 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                  goto replay_sequence;
                }
 
-             fkey_map = get_keymap_1 (fkey_next, 0, 1);
+             fkey_map = get_keymap (fkey_next, 0, 1);
 
              /* If we no longer have a bound suffix, try a new positions for
                 fkey_start.  */
-             if (NILP (fkey_map))
+             if (!CONSP (fkey_map))
                {
                  fkey_end = ++fkey_start;
                  fkey_map = Vfunction_key_map;
@@ -8581,22 +8600,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
            Lisp_Object key;
 
            key = keybuf[keytran_end++];
-           /* Look up meta-characters by prefixing them
-              with meta_prefix_char.  I hate this.  */
-           if (INTEGERP (key) && XUINT (key) & meta_modifier)
-             {
-               keytran_next
-                 = get_keymap_1
-                   (get_keyelt
-                    (access_keymap (keytran_map, meta_prefix_char, 1, 0), 0),
-                    0, 1);
-               XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
-             }
-           else
-             keytran_next = keytran_map;
-
            keytran_next
-             = get_keyelt (access_keymap (keytran_next, key, 1, 0), 1);
+             = access_keymap (keytran_map, key, 1, 0, 1);
 
            /* Handle symbol with autoload definition.  */
            if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))
@@ -8609,7 +8614,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
               or an array.  */
            if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))
                && (!NILP (Farrayp (XSYMBOL (keytran_next)->function))
-                   || !NILP (Fkeymapp (XSYMBOL (keytran_next)->function))))
+                   || KEYMAPP (XSYMBOL (keytran_next)->function)))
              keytran_next = XSYMBOL (keytran_next)->function;
            
            /* If the key translation map gives a function, not an
@@ -8673,11 +8678,11 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                goto replay_sequence;
              }
 
-           keytran_map = get_keymap_1 (keytran_next, 0, 1);
+           keytran_map = get_keymap (keytran_next, 0, 1);
 
            /* If we no longer have a bound suffix, try a new positions for
               keytran_start.  */
-           if (NILP (keytran_map))
+           if (!CONSP (keytran_map))
              {
                keytran_end = ++keytran_start;
                keytran_map = Vkey_translation_map;
@@ -8893,9 +8898,13 @@ DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0,
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
+#if 0  /* The following is fine for code reading a key sequence and
+         then proceeding with a lenghty compuation, but it's not good
+         for code reading keys in a loop, like an input method.  */
 #ifdef HAVE_X_WINDOWS
   if (display_busy_cursor_p)
     start_busy_cursor ();
+#endif
 #endif
 
   if (i == -1)
@@ -9059,6 +9068,8 @@ a special event, so ignore the prefix argument and don't clear it.")
     }
   return Qnil;
 }
+
+
 \f
 DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
   1, 1, "P",
@@ -9181,7 +9192,9 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
          Lisp_Object binding;
          char *newmessage;
          int message_p = push_message ();
+         int count = BINDING_STACK_SIZE ();
 
+         record_unwind_protect (push_message_unwind, Qnil);
          binding = Fkey_description (bindings);
 
          newmessage
@@ -9200,7 +9213,7 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
              && message_p)
            restore_message ();
 
-         pop_message ();
+         unbind_to (count, Qnil);
        }
     }
 
@@ -9234,7 +9247,7 @@ current_active_maps (maps_p)
     {
       /* No, so use major and minor mode keymaps and keymap property.  */
       int extra_maps = 2;
-      Lisp_Object map = get_local_map (PT, current_buffer, keymap);
+      Lisp_Object map = get_local_map (PT, current_buffer, Qkeymap);
       if (!NILP (map))
        extra_maps = 3;
       nmaps = current_minor_maps (NULL, &tmaps);
@@ -9243,7 +9256,7 @@ current_active_maps (maps_p)
       bcopy (tmaps, maps, nmaps * sizeof (maps[0]));
       if (!NILP (map))
        maps[nmaps++] = map;
-      maps[nmaps++] = get_local_map (PT, current_buffer, local_map);
+      maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
     }
   maps[nmaps++] = current_global_map;
 
@@ -9275,7 +9288,7 @@ detect_input_pending_run_timers (do_display)
 
   if (old_timers_run != timers_run && do_display)
     {
-      redisplay_preserve_echo_area ();
+      redisplay_preserve_echo_area (8);
       /* The following fixes a bug when using lazy-lock with
         lazy-lock-defer-on-the-fly set to t, i.e.  when fontifying
         from an idle timer function.  The symptom of the bug is that
@@ -10643,11 +10656,16 @@ suppressed only after special commands that set\n\
 `disable-point-adjustment' (which see) to non-nil.");
   Vglobal_disable_point_adjustment = Qnil;
 
-  DEFVAR_LISP ("update-menu-bindings", &update_menu_bindings,
+  DEFVAR_BOOL ("update-menu-bindings", &update_menu_bindings,
     "Non-nil means updating menu bindings is allowed.\n\
 A value of nil means menu bindings should not be updated.\n\
 Used during Emacs' startup.");
   update_menu_bindings = 1;
+
+  DEFVAR_LISP ("minibuffer-message-timeout", &Vminibuffer_message_timeout,
+    "*How long to display an echo-area message when the minibuffer is active.\n\
+If the value is not a number, such messages don't time out.");
+  Vminibuffer_message_timeout = make_number (2);
 }
 
 void