update.
[chise/xemacs-chise.git.1] / src / keymap.c
index 6d5f603..3752f0f 100644 (file)
@@ -189,7 +189,7 @@ static Lisp_Object Vvertical_divider_map;
    so that things which care (such as the menubar code) can recompute
    privately-cached data when the user has changed keybindings.
  */
-int keymap_tick;
+Fixnum keymap_tick;
 
 /* Prefixing a key with this character is the same as sending a meta bit. */
 Lisp_Object Vmeta_prefix_char;
@@ -221,9 +221,13 @@ Lisp_Object Qbutton4up, Qbutton5up, Qbutton6up, Qbutton7up;
 
 Lisp_Object Qmenu_selection;
 /* Emacs compatibility */
-Lisp_Object Qdown_mouse_1, Qdown_mouse_2, Qdown_mouse_3, Qdown_mouse_4,
-  Qdown_mouse_5;
-Lisp_Object Qmouse_1, Qmouse_2, Qmouse_3, Qmouse_4, Qmouse_5;
+Lisp_Object Qdown_mouse_1, Qmouse_1;
+Lisp_Object Qdown_mouse_2, Qmouse_2;
+Lisp_Object Qdown_mouse_3, Qmouse_3;
+Lisp_Object Qdown_mouse_4, Qmouse_4;
+Lisp_Object Qdown_mouse_5, Qmouse_5;
+Lisp_Object Qdown_mouse_6, Qmouse_6;
+Lisp_Object Qdown_mouse_7, Qmouse_7;
 
 /* Kludge kludge kludge */
 Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS;
@@ -463,9 +467,12 @@ keymap_lookup_directly (Lisp_Object keymap,
 {
   Lisp_Keymap *k;
 
-  if ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META | XEMACS_MOD_SUPER | XEMACS_MOD_HYPER
-                     | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT)) != 0)
-    abort ();
+  modifiers &= ~(XEMACS_MOD_BUTTON1 | XEMACS_MOD_BUTTON2 | XEMACS_MOD_BUTTON3
+                | XEMACS_MOD_BUTTON4 | XEMACS_MOD_BUTTON5);
+  if ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META | XEMACS_MOD_SUPER
+                    | XEMACS_MOD_HYPER | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT))
+      != 0)
+    ABORT ();
 
   k = XKEYMAP (keymap);
 
@@ -540,7 +547,7 @@ keymap_delete_inverse_internal (Lisp_Object inverse_table,
   Lisp_Object *prev;
 
   if (UNBOUNDP (keys))
-    abort ();
+    ABORT ();
 
   for (prev = &new_keys, tail = new_keys;
        ;
@@ -641,6 +648,8 @@ keymap_store (Lisp_Object keymap, const struct key_data *key,
   int modifiers = key->modifiers;
   Lisp_Keymap *k = XKEYMAP (keymap);
 
+  modifiers &= ~(XEMACS_MOD_BUTTON1 | XEMACS_MOD_BUTTON2 | XEMACS_MOD_BUTTON3
+                | XEMACS_MOD_BUTTON4 | XEMACS_MOD_BUTTON5);
   assert ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META
                         | XEMACS_MOD_SUPER | XEMACS_MOD_HYPER
                         | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT)) == 0);
@@ -790,9 +799,9 @@ it is not used except when printing the keymap.
 DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, 0, 1, 0, /*
 Construct and return a new keymap object.
 All entries in it are nil, meaning "command undefined".  The only
-difference between this function and make-keymap is that this function
+difference between this function and `make-keymap' is that this function
 returns a "smaller" keymap (one that is expected to contain fewer
-entries).  As keymaps dynamically resize, the distinction is not great.
+entries).  As keymaps dynamically resize, this distinction is not great.
 
 Optional argument NAME specifies a name to assign to the keymap,
 as in `set-keymap-name'.  This name is only a debugging convenience;
@@ -963,7 +972,7 @@ parents nor the current global map are searched for key bindings.
 }
 
 DEFUN ("keymapp", Fkeymapp, 1, 1, 0, /*
-Return t if ARG is a keymap object.
+Return t if OBJECT is a keymap object.
 The keymap may be autoloaded first if necessary.
 */
        (object))
@@ -1006,10 +1015,8 @@ get_keymap (Lisp_Object object, int errorp, int autoload)
                && EQ (XCAR (tem), Qautoload)
                && EQ (Fcar (Fcdr (Fcdr (Fcdr (Fcdr (tem))))), Qkeymap))
        {
-         struct gcpro gcpro1, gcpro2;
-         GCPRO2 (tem, object);
+         /* do_autoload GCPROs both arguments */
          do_autoload (tem, object);
-         UNGCPRO;
        }
       else if (errorp)
        object = wrong_type_argument (Qkeymapp, object);
@@ -1361,6 +1368,10 @@ define_key_check_and_coerce_keysym (Lisp_Object spec,
        *keysym = Qbutton4;
       else if (EQ(*keysym, Qdown_mouse_5))
        *keysym = Qbutton5;
+      else if (EQ(*keysym, Qdown_mouse_6))
+       *keysym = Qbutton6;
+      else if (EQ(*keysym, Qdown_mouse_7))
+       *keysym = Qbutton7;
       else if (EQ(*keysym, Qmouse_1))
        *keysym = Qbutton1up;
       else if (EQ(*keysym, Qmouse_2))
@@ -1371,6 +1382,10 @@ define_key_check_and_coerce_keysym (Lisp_Object spec,
        *keysym = Qbutton4up;
       else if (EQ(*keysym, Qmouse_5))
        *keysym = Qbutton5up;
+      else if (EQ(*keysym, Qmouse_6))
+       *keysym = Qbutton6up;
+      else if (EQ(*keysym, Qmouse_7))
+       *keysym = Qbutton7up;
     }
 }
 
@@ -1537,7 +1552,7 @@ key_desc_list_to_event (Lisp_Object list, Lisp_Object event,
 int
 event_matches_key_specifier_p (Lisp_Event *event, Lisp_Object key_specifier)
 {
-  Lisp_Object event2;
+  Lisp_Object event2 = Qnil;
   int retval;
   struct gcpro gcpro1;
 
@@ -1632,7 +1647,7 @@ define_key_alternate_name (struct key_data *key,
   returned_value->modifiers = 0;
   if (modifiers_sans_meta == XEMACS_MOD_CONTROL)
     {
-      if EQ (keysym, QKspace)
+      if (EQ (keysym, QKspace))
         MACROLET (make_char ('@'), modifiers);
       else if (!CHARP (keysym))
         return;
@@ -1702,7 +1717,10 @@ ensure_meta_prefix_char_keymapp (Lisp_Object keys, int indx,
        XVECTOR_DATA (new_keys) [i] = XVECTOR_DATA (keys) [i];
     }
   else
-    abort ();
+    {
+      new_keys = Qnil;
+      ABORT ();
+    }
 
   if (EQ (keys, new_keys))
     error_with_frob (mpc_binding,
@@ -2071,7 +2089,8 @@ raw_lookup_key_mapper (Lisp_Object k, void *arg)
            {
              struct key_data metified;
              metified.keysym = raw_keys[1].keysym;
-             metified.modifiers = raw_keys[1].modifiers | XEMACS_MOD_META;
+             metified.modifiers = raw_keys[1].modifiers |
+               (unsigned char) XEMACS_MOD_META;
 
              /* Search for meta-next-char sequence directly */
              cmd = keymap_lookup_1 (k, &metified, accept_default);
@@ -2172,8 +2191,8 @@ Nil is returned if KEYS is unbound.  See documentation of `define-key'
 for valid key definitions and key-sequence specifications.
 A number is returned if KEYS is "too long"; that is, the leading
 characters fail to be a valid sequence of prefix characters in KEYMAP.
-The number is how many characters at the front of KEYS
-it takes to reach a non-prefix command.
+The number is how many key strokes at the front of KEYS it takes to
+reach a non-prefix command.
 */
        (keymap, keys, accept_default))
 {
@@ -2526,7 +2545,7 @@ the documentation for `lookup-key' for more information.
 For key-presses, the order of keymaps searched is:
   - the `keymap' property of any extent(s) at point;
   - any applicable minor-mode maps;
-  - the current-local-map of the current-buffer;
+  - the current local map of the current-buffer;
   - the current global map.
 
 For mouse-clicks, the order of keymaps searched is:
@@ -2536,9 +2555,9 @@ For mouse-clicks, the order of keymaps searched is:
     (this includes modeline extents);
   - the modeline-map of the buffer corresponding to the modeline under
     the mouse (if the click happened over a modeline);
-  - the value of toolbar-map in the current-buffer (if the click
+  - the value of `toolbar-map' in the current-buffer (if the click
     happened over a toolbar);
-  - the current-local-map of the buffer under the mouse (does not
+  - the current local map of the buffer under the mouse (does not
     apply to toolbar clicks);
   - any applicable minor-mode maps;
   - the current global map.
@@ -2969,7 +2988,8 @@ faster.
      (function, keymap, sort_first))
 {
   /* This function can GC */
-  struct gcpro gcpro1, gcpro2;
+  struct gcpro gcpro1, gcpro2, gcpro3;
+  Lisp_Object table = Qnil;
 
  /* tolerate obviously transposed args */
   if (!NILP (Fkeymapp (function)))
@@ -2978,9 +2998,17 @@ faster.
       function = keymap;
       keymap = tmp;
     }
-  GCPRO2 (function, keymap);
+
+  GCPRO3 (function, keymap, table);
   keymap = get_keymap (keymap, 1, 1);
-  map_keymap (XKEYMAP (keymap)->table, !NILP (sort_first),
+
+  /* elisp_maphash does not allow mapping functions to modify the hash
+     table being mapped over.  Since map-keymap explicitly allows a
+     mapping function to modify KEYMAP, we map over a copy of the hash
+     table instead.  */
+  table = Fcopy_hash_table (XKEYMAP (keymap)->table);
+
+  map_keymap (table, !NILP (sort_first),
              map_keymap_mapper, LISP_TO_VOID (function));
   UNGCPRO;
   return Qnil;
@@ -3032,10 +3060,10 @@ accessible_keymaps_mapper_1 (Lisp_Object keysym, Lisp_Object contents,
       key.modifiers = modifiers;
 
       if (NILP (cmd))
-       abort ();
+       ABORT ();
       cmd = get_keymap (cmd, 0, 1);
       if (!KEYMAPP (cmd))
-       abort ();
+       ABORT ();
 
       vec = make_vector (XVECTOR_LENGTH (thisseq) + 1, Qnil);
       len = XVECTOR_LENGTH (thisseq);
@@ -3561,7 +3589,7 @@ where_is_recursive_mapper (Lisp_Object map, void *arg)
          /* OK, the key is for real */
          if (target_buffer)
            {
-             if (!firstonly) abort ();
+             if (!firstonly) ABORT ();
              format_raw_keys (so_far, keys_count + 1, target_buffer);
              return make_int (1);
            }
@@ -3635,6 +3663,8 @@ where_is_recursive_mapper (Lisp_Object map, void *arg)
              struct key_data *new = xnew_array (struct key_data, size);
              memcpy ((void *)new, (const void *)c->keys_so_far,
                      c->keys_so_far_total_size * sizeof (struct key_data));
+             xfree (c->keys_so_far);
+             c->keys_so_far = new;
            }
          else
            XREALLOC_ARRAY (c->keys_so_far, struct key_data, size);
@@ -4122,12 +4152,18 @@ describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
          if (!NILP (elt_prefix))
            buffer_insert_lisp_string (buf, elt_prefix);
 
-         if (modifiers & XEMACS_MOD_META)    buffer_insert_c_string (buf, "M-");
-         if (modifiers & XEMACS_MOD_CONTROL) buffer_insert_c_string (buf, "C-");
-         if (modifiers & XEMACS_MOD_SUPER)   buffer_insert_c_string (buf, "S-");
-         if (modifiers & XEMACS_MOD_HYPER)   buffer_insert_c_string (buf, "H-");
-         if (modifiers & XEMACS_MOD_ALT)     buffer_insert_c_string (buf, "Alt-");
-         if (modifiers & XEMACS_MOD_SHIFT)   buffer_insert_c_string (buf, "Sh-");
+         if (modifiers & XEMACS_MOD_META)
+           buffer_insert_c_string (buf, "M-");
+         if (modifiers & XEMACS_MOD_CONTROL)
+           buffer_insert_c_string (buf, "C-");
+         if (modifiers & XEMACS_MOD_SUPER)
+           buffer_insert_c_string (buf, "S-");
+         if (modifiers & XEMACS_MOD_HYPER)
+           buffer_insert_c_string (buf, "H-");
+         if (modifiers & XEMACS_MOD_ALT)
+           buffer_insert_c_string (buf, "Alt-");
+         if (modifiers & XEMACS_MOD_SHIFT)
+           buffer_insert_c_string (buf, "Sh-");
          if (SYMBOLP (keysym))
            {
              Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
@@ -4266,11 +4302,15 @@ syms_of_keymap (void)
   defsymbol (&Qmouse_3, "mouse-3");
   defsymbol (&Qmouse_4, "mouse-4");
   defsymbol (&Qmouse_5, "mouse-5");
+  defsymbol (&Qmouse_6, "mouse-6");
+  defsymbol (&Qmouse_7, "mouse-7");
   defsymbol (&Qdown_mouse_1, "down-mouse-1");
   defsymbol (&Qdown_mouse_2, "down-mouse-2");
   defsymbol (&Qdown_mouse_3, "down-mouse-3");
   defsymbol (&Qdown_mouse_4, "down-mouse-4");
   defsymbol (&Qdown_mouse_5, "down-mouse-5");
+  defsymbol (&Qdown_mouse_6, "down-mouse-6");
+  defsymbol (&Qdown_mouse_7, "down-mouse-7");
   defsymbol (&Qmenu_selection, "menu-selection");
   defsymbol (&QLFD, "LFD");
   defsymbol (&QTAB, "TAB");
@@ -4314,8 +4354,28 @@ You should *bind* this, not set it.
 
   DEFVAR_LISP ("key-translation-map", &Vkey_translation_map /*
 Keymap of key translations that can override keymaps.
-This keymap works like `function-key-map', but comes after that,
+
+This keymap works like `function-key-map', but is searched before it,
 and applies even for keys that have ordinary bindings.
+
+The `read-key-sequence' function replaces any subsequence bound by
+`key-translation-map' with its binding.  More precisely, when the active
+keymaps have no binding for the current key sequence but
+`key-translation-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.  See `key-binding' for details.
+
+The events that come from bindings in `key-translation-map' are not
+themselves looked up in `key-translation-map'.
+
+#### FIXME: stolen from `function-key-map'; need better example.
+#### I guess you could implement a Dvorak keyboard with this?
+For example, suppose `key-translation-map' binds `ESC O P' to [f1].
+Typing `ESC O P' to `read-key-sequence' would return
+\[#<keypress-event f1>].  Typing `C-x ESC O P' would return
+\[#<keypress-event control-X> #<keypress-event f1>].  If [f1]
+were a prefix key, typing `ESC O P x' would return
+\[#<keypress-event f1> #<keypress-event x>].
 */ );
   Vkey_translation_map = Qnil;