XEmacs 21.2.44 "Thalia".
[chise/xemacs-chise.git.1] / src / keymap.c
1 /* Manipulation of keymaps
2    Copyright (C) 1985, 1991-1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Board of Trustees, University of Illinois.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5    Totally redesigned by jwz in 1991.
6
7 This file is part of XEmacs.
8
9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with XEmacs; see the file COPYING.  If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24 /* Synched up with: Mule 2.0.  Not synched with FSF.  Substantially
25    different from FSF. */
26
27
28 #include <config.h>
29 #include "lisp.h"
30
31 #include "buffer.h"
32 #include "bytecode.h"
33 #include "console.h"
34 #include "elhash.h"
35 #include "events.h"
36 #include "frame.h"
37 #include "insdel.h"
38 #include "keymap.h"
39 #include "window.h"
40 #include "events-mod.h"
41
42 \f
43 /* A keymap contains six slots:
44
45    parents         Ordered list of keymaps to search after
46                    this one if no match is found.
47                    Keymaps can thus be arranged in a hierarchy.
48
49    table           A hash table, hashing keysyms to their bindings.
50                    It will be one of the following:
51
52                    -- a symbol, e.g. 'home
53                    -- a character, representing something printable
54                       (not ?\C-c meaning C-c, for instance)
55                    -- an integer representing a modifier combination
56
57    inverse_table   A hash table, hashing bindings to the list of keysyms
58                    in this keymap which are bound to them.  This is to make
59                    the Fwhere_is_internal() function be fast.  It needs to be
60                    fast because we want to be able to call it in realtime to
61                    update the keyboard-equivalents on the pulldown menus.
62                    Values of the table are either atoms (keysyms)
63                    or a dotted list of keysyms.
64
65    sub_maps_cache  An alist; for each entry in this keymap whose binding is
66                    a keymap (that is, Fkeymapp()) this alist associates that
67                    keysym with that binding.  This is used to optimize both
68                    Fwhere_is_internal() and Faccessible_keymaps().  This slot
69                    gets set to the symbol `t' every time a change is made to
70                    this keymap, causing it to be recomputed when next needed.
71
72    prompt          See `set-keymap-prompt'.
73
74    default_binding See `set-keymap-default-binding'.
75
76    Sequences of keys are stored in the obvious way: if the sequence of keys
77    "abc" was bound to some command `foo', the hierarchy would look like
78
79       keymap-1: associates "a" with keymap-2
80       keymap-2: associates "b" with keymap-3
81       keymap-3: associates "c" with foo
82
83    However, bucky bits ("modifiers" to the X-minded) are represented in the
84    keymap hierarchy as well. (This lets us use EQable objects as hash keys.)
85    Each combination of modifiers (e.g. control-hyper) gets its own submap
86    off of the main map.  The hash key for a modifier combination is
87    an integer, computed by MAKE_MODIFIER_HASH_KEY().
88
89    If the key `C-a' was bound to some command, the hierarchy would look like
90
91       keymap-1: associates the integer XEMACS_MOD_CONTROL with keymap-2
92       keymap-2: associates "a" with the command
93
94    Similarly, if the key `C-H-a' was bound to some command, the hierarchy
95    would look like
96
97       keymap-1: associates the integer (XEMACS_MOD_CONTROL | XEMACS_MOD_HYPER)
98                 with keymap-2
99       keymap-2: associates "a" with the command
100
101    Note that a special exception is made for the meta modifier, in order
102    to deal with ESC/meta lossage.  Any key combination containing the
103    meta modifier is first indexed off of the main map into the meta
104    submap (with hash key XEMACS_MOD_META) and then indexed off of the
105    meta submap with the meta modifier removed from the key combination.
106    For example, when associating a command with C-M-H-a, we'd have
107
108       keymap-1: associates the integer XEMACS_MOD_META with keymap-2
109       keymap-2: associates the integer (XEMACS_MOD_CONTROL | XEMACS_MOD_HYPER)
110                 with keymap-3
111       keymap-3: associates "a" with the command
112
113    Note that keymap-2 might have normal bindings in it; these would be
114    for key combinations containing only the meta modifier, such as
115    M-y or meta-backspace.
116
117    If the command that "a" was bound to in keymap-3 was itself a keymap,
118    then that would make the key "C-M-H-a" be a prefix character.
119
120    Note that this new model of keymaps takes much of the magic away from
121    the Escape key: the value of the variable `esc-map' is no longer indexed
122    in the `global-map' under the ESC key.  It's indexed under the integer
123    XEMACS_MOD_META.  This is not user-visible, however; none of the "bucky"
124    maps are.
125
126    There is a hack in Flookup_key() that makes (lookup-key global-map "\^[")
127    and (define-key some-random-map "\^[" my-esc-map) work as before, for
128    compatibility.
129
130    Since keymaps are opaque, the only way to extract information from them
131    is with the functions lookup-key, key-binding, local-key-binding, and
132    global-key-binding, which work just as before, and the new function
133    map-keymap, which is roughly analogous to maphash.
134
135    Note that map-keymap perpetuates the illusion that the "bucky" submaps
136    don't exist: if you map over a keymap with bucky submaps, it will also
137    map over those submaps.  It does not, however, map over other random
138    submaps of the keymap, just the bucky ones.
139
140    One implication of this is that when you map over `global-map', you will
141    also map over `esc-map'.  It is merely for compatibility that the esc-map
142    is accessible at all; I think that's a bad thing, since it blurs the
143    distinction between ESC and "meta" even more.  "M-x" is no more a two-
144    key sequence than "C-x" is.
145
146  */
147
148 struct Lisp_Keymap
149 {
150   struct lcrecord_header header;
151   Lisp_Object parents;          /* Keymaps to be searched after this one.
152                                    An ordered list */
153   Lisp_Object prompt;           /* Qnil or a string to print in the minibuffer
154                                    when reading from this keymap */
155   Lisp_Object table;            /* The contents of this keymap */
156   Lisp_Object inverse_table;    /* The inverse mapping of the above */
157   Lisp_Object default_binding;  /* Use this if no other binding is found
158                                    (this overrides parent maps and the
159                                    normal global-map lookup). */
160   Lisp_Object sub_maps_cache;   /* Cache of directly inferior keymaps;
161                                    This holds an alist, of the key and the
162                                    maps, or the modifier bit and the map.
163                                    If this is the symbol t, then the cache
164                                    needs to be recomputed. */
165   Lisp_Object name;             /* Just for debugging convenience */
166 };
167
168 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier)
169 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0)
170
171 \f
172
173 /* Actually allocate storage for these variables */
174
175 Lisp_Object Vcurrent_global_map; /* Always a keymap */
176
177 static Lisp_Object Vmouse_grabbed_buffer;
178
179 /* Alist of minor mode variables and keymaps.  */
180 static Lisp_Object Qminor_mode_map_alist;
181
182 static Lisp_Object Voverriding_local_map;
183
184 static Lisp_Object Vkey_translation_map;
185
186 static Lisp_Object Vvertical_divider_map;
187
188 /* This is incremented whenever a change is made to a keymap.  This is
189    so that things which care (such as the menubar code) can recompute
190    privately-cached data when the user has changed keybindings.
191  */
192 Fixnum keymap_tick;
193
194 /* Prefixing a key with this character is the same as sending a meta bit. */
195 Lisp_Object Vmeta_prefix_char;
196
197 Lisp_Object Qkeymapp;
198 Lisp_Object Vsingle_space_string;
199 Lisp_Object Qsuppress_keymap;
200 Lisp_Object Qmodeline_map;
201 Lisp_Object Qtoolbar_map;
202
203 EXFUN (Fkeymap_fullness, 1);
204 EXFUN (Fset_keymap_name, 2);
205 EXFUN (Fsingle_key_description, 1);
206
207 static void describe_command (Lisp_Object definition, Lisp_Object buffer);
208 static void describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
209                           void (*elt_describer) (Lisp_Object, Lisp_Object),
210                           int partial,
211                           Lisp_Object shadow,
212                           int mice_only_p,
213                           Lisp_Object buffer);
214 static Lisp_Object keymap_submaps (Lisp_Object keymap);
215
216 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift;
217 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3;
218 Lisp_Object Qbutton4, Qbutton5, Qbutton6, Qbutton7;
219 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up;
220 Lisp_Object Qbutton4up, Qbutton5up, Qbutton6up, Qbutton7up;
221
222 Lisp_Object Qmenu_selection;
223 /* Emacs compatibility */
224 Lisp_Object Qdown_mouse_1, Qmouse_1;
225 Lisp_Object Qdown_mouse_2, Qmouse_2;
226 Lisp_Object Qdown_mouse_3, Qmouse_3;
227 Lisp_Object Qdown_mouse_4, Qmouse_4;
228 Lisp_Object Qdown_mouse_5, Qmouse_5;
229 Lisp_Object Qdown_mouse_6, Qmouse_6;
230 Lisp_Object Qdown_mouse_7, Qmouse_7;
231
232 /* Kludge kludge kludge */
233 Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS;
234
235 \f
236 /************************************************************************/
237 /*                     The keymap Lisp object                           */
238 /************************************************************************/
239
240 static Lisp_Object
241 mark_keymap (Lisp_Object obj)
242 {
243   Lisp_Keymap *keymap = XKEYMAP (obj);
244   mark_object (keymap->parents);
245   mark_object (keymap->prompt);
246   mark_object (keymap->inverse_table);
247   mark_object (keymap->sub_maps_cache);
248   mark_object (keymap->default_binding);
249   mark_object (keymap->name);
250   return keymap->table;
251 }
252
253 static void
254 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
255 {
256   /* This function can GC */
257   Lisp_Keymap *keymap = XKEYMAP (obj);
258   char buf[200];
259   if (print_readably)
260     error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid);
261   write_c_string ("#<keymap ", printcharfun);
262   if (!NILP (keymap->name))
263     {
264       print_internal (keymap->name, printcharfun, 1);
265       write_c_string (" ", printcharfun);
266     }
267   sprintf (buf, "size %ld 0x%x>",
268            (long) XINT (Fkeymap_fullness (obj)), keymap->header.uid);
269   write_c_string (buf, printcharfun);
270 }
271
272 static const struct lrecord_description keymap_description[] = {
273   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, parents) },
274   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, prompt) },
275   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, table) },
276   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, inverse_table) },
277   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, default_binding) },
278   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, sub_maps_cache) },
279   { XD_LISP_OBJECT, offsetof (Lisp_Keymap, name) },
280   { XD_END }
281 };
282
283 /* No need for keymap_equal #### Why not? */
284 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
285                                mark_keymap, print_keymap, 0, 0, 0,
286                                keymap_description,
287                                Lisp_Keymap);
288 \f
289 /************************************************************************/
290 /*                Traversing keymaps and their parents                  */
291 /************************************************************************/
292
293 static Lisp_Object
294 traverse_keymaps (Lisp_Object start_keymap, Lisp_Object start_parents,
295                   Lisp_Object (*mapper) (Lisp_Object keymap, void *mapper_arg),
296                   void *mapper_arg)
297 {
298   /* This function can GC */
299   Lisp_Object keymap;
300   Lisp_Object tail = start_parents;
301   Lisp_Object malloc_sucks[10];
302   Lisp_Object malloc_bites = Qnil;
303   int stack_depth = 0;
304   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
305   GCPRO4 (*malloc_sucks, malloc_bites, start_keymap, tail);
306   gcpro1.nvars = 0;
307
308   start_keymap = get_keymap (start_keymap, 1, 1);
309   keymap = start_keymap;
310   /* Hack special-case parents at top-level */
311   tail = !NILP (tail) ? tail : XKEYMAP (keymap)->parents;
312
313   for (;;)
314     {
315       Lisp_Object result;
316
317       QUIT;
318       result = mapper (keymap, mapper_arg);
319       if (!NILP (result))
320         {
321           while (CONSP (malloc_bites))
322             {
323               Lisp_Cons *victim = XCONS (malloc_bites);
324               malloc_bites = victim->cdr;
325               free_cons (victim);
326             }
327           UNGCPRO;
328           return result;
329         }
330       if (NILP (tail))
331         {
332           if (stack_depth == 0)
333             {
334               UNGCPRO;
335               return Qnil;          /* Nothing found */
336             }
337           stack_depth--;
338           if (CONSP (malloc_bites))
339             {
340               Lisp_Cons *victim = XCONS (malloc_bites);
341               tail = victim->car;
342               malloc_bites = victim->cdr;
343               free_cons (victim);
344             }
345           else
346             {
347               tail = malloc_sucks[stack_depth];
348               gcpro1.nvars = stack_depth;
349             }
350           keymap = XCAR (tail);
351           tail = XCDR (tail);
352         }
353       else
354         {
355           Lisp_Object parents;
356
357           keymap = XCAR (tail);
358           tail = XCDR (tail);
359           parents = XKEYMAP (keymap)->parents;
360           if (!CONSP (parents))
361             ;
362           else if (NILP (tail))
363             /* Tail-recurse */
364             tail = parents;
365           else
366             {
367               if (CONSP (malloc_bites))
368                 malloc_bites = noseeum_cons (tail, malloc_bites);
369               else if (stack_depth < countof (malloc_sucks))
370                 {
371                   malloc_sucks[stack_depth++] = tail;
372                   gcpro1.nvars = stack_depth;
373                 }
374               else
375                 {
376                   /* *&@##[*&^$ C. @#[$*&@# Unix.  Losers all. */
377                   int i;
378                   for (i = 0, malloc_bites = Qnil;
379                        i < countof (malloc_sucks);
380                        i++)
381                     malloc_bites = noseeum_cons (malloc_sucks[i],
382                                                  malloc_bites);
383                   gcpro1.nvars = 0;
384                 }
385               tail = parents;
386             }
387         }
388       keymap = get_keymap (keymap, 1, 1);
389       if (EQ (keymap, start_keymap))
390         {
391           signal_simple_error ("Cyclic keymap indirection",
392                                start_keymap);
393         }
394     }
395 }
396
397 \f
398 /************************************************************************/
399 /*                     Some low-level functions                         */
400 /************************************************************************/
401
402 static int
403 bucky_sym_to_bucky_bit (Lisp_Object sym)
404 {
405   if (EQ (sym, Qcontrol)) return XEMACS_MOD_CONTROL;
406   if (EQ (sym, Qmeta))    return XEMACS_MOD_META;
407   if (EQ (sym, Qsuper))   return XEMACS_MOD_SUPER;
408   if (EQ (sym, Qhyper))   return XEMACS_MOD_HYPER;
409   if (EQ (sym, Qalt))     return XEMACS_MOD_ALT;
410   if (EQ (sym, Qsymbol))  return XEMACS_MOD_ALT; /* #### - reverse compat */
411   if (EQ (sym, Qshift))   return XEMACS_MOD_SHIFT;
412
413   return 0;
414 }
415
416 static Lisp_Object
417 control_meta_superify (Lisp_Object frob, int modifiers)
418 {
419   if (modifiers == 0)
420     return frob;
421   frob = Fcons (frob, Qnil);
422   if (modifiers & XEMACS_MOD_SHIFT)   frob = Fcons (Qshift,   frob);
423   if (modifiers & XEMACS_MOD_ALT)     frob = Fcons (Qalt,     frob);
424   if (modifiers & XEMACS_MOD_HYPER)   frob = Fcons (Qhyper,   frob);
425   if (modifiers & XEMACS_MOD_SUPER)   frob = Fcons (Qsuper,   frob);
426   if (modifiers & XEMACS_MOD_CONTROL) frob = Fcons (Qcontrol, frob);
427   if (modifiers & XEMACS_MOD_META)    frob = Fcons (Qmeta,    frob);
428   return frob;
429 }
430
431 static Lisp_Object
432 make_key_description (const struct key_data *key, int prettify)
433 {
434   Lisp_Object keysym = key->keysym;
435   int modifiers = key->modifiers;
436
437   if (prettify && CHARP (keysym))
438     {
439       /* This is a little slow, but (control a) is prettier than (control 65).
440          It's now ok to do this for digit-chars too, since we've fixed the
441          bug where \9 read as the integer 9 instead of as the symbol with
442          "9" as its name.
443        */
444       /* !!#### I'm not sure how correct this is. */
445       Bufbyte str [1 + MAX_EMCHAR_LEN];
446       Bytecount count = set_charptr_emchar (str, XCHAR (keysym));
447       str[count] = 0;
448       keysym = intern ((char *) str);
449     }
450   return control_meta_superify (keysym, modifiers);
451 }
452
453 \f
454 /************************************************************************/
455 /*                   Low-level keymap-store functions                   */
456 /************************************************************************/
457
458 static Lisp_Object
459 raw_lookup_key (Lisp_Object keymap,
460                 const struct key_data *raw_keys, int raw_keys_count,
461                 int keys_so_far, int accept_default);
462
463 /* Relies on caller to gc-protect args */
464 static Lisp_Object
465 keymap_lookup_directly (Lisp_Object keymap,
466                         Lisp_Object keysym, int modifiers)
467 {
468   Lisp_Keymap *k;
469
470   modifiers &= ~(XEMACS_MOD_BUTTON1 | XEMACS_MOD_BUTTON2 | XEMACS_MOD_BUTTON3
471                  | XEMACS_MOD_BUTTON4 | XEMACS_MOD_BUTTON5);
472   if ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META | XEMACS_MOD_SUPER
473                      | XEMACS_MOD_HYPER | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT))
474       != 0)
475     abort ();
476
477   k = XKEYMAP (keymap);
478
479   /* If the keysym is a one-character symbol, use the char code instead. */
480   if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1)
481     {
482       Lisp_Object i_fart_on_gcc =
483         make_char (string_char (XSYMBOL (keysym)->name, 0));
484       keysym = i_fart_on_gcc;
485     }
486
487   if (modifiers & XEMACS_MOD_META)     /* Utterly hateful ESC lossage */
488     {
489       Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META),
490                                      k->table, Qnil);
491       if (NILP (submap))
492         return Qnil;
493       k = XKEYMAP (submap);
494       modifiers &= ~XEMACS_MOD_META;
495     }
496
497   if (modifiers != 0)
498     {
499       Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers),
500                                      k->table, Qnil);
501       if (NILP (submap))
502         return Qnil;
503       k = XKEYMAP (submap);
504     }
505   return Fgethash (keysym, k->table, Qnil);
506 }
507
508 static void
509 keymap_store_inverse_internal (Lisp_Object inverse_table,
510                                Lisp_Object keysym,
511                                Lisp_Object value)
512 {
513   Lisp_Object keys = Fgethash (value, inverse_table, Qunbound);
514
515   if (UNBOUNDP (keys))
516     {
517       keys = keysym;
518       /* Don't cons this unless necessary */
519       /* keys = Fcons (keysym, Qnil); */
520       Fputhash (value, keys, inverse_table);
521     }
522   else if (!CONSP (keys))
523     {
524       /* Now it's necessary to cons */
525       keys = Fcons (keys, keysym);
526       Fputhash (value, keys, inverse_table);
527     }
528   else
529     {
530       while (CONSP (XCDR (keys)))
531         keys = XCDR (keys);
532       XCDR (keys) = Fcons (XCDR (keys), keysym);
533       /* No need to call puthash because we've destructively
534          modified the list tail in place */
535     }
536 }
537
538
539 static void
540 keymap_delete_inverse_internal (Lisp_Object inverse_table,
541                                 Lisp_Object keysym,
542                                 Lisp_Object value)
543 {
544   Lisp_Object keys = Fgethash (value, inverse_table, Qunbound);
545   Lisp_Object new_keys = keys;
546   Lisp_Object tail;
547   Lisp_Object *prev;
548
549   if (UNBOUNDP (keys))
550     abort ();
551
552   for (prev = &new_keys, tail = new_keys;
553        ;
554        prev = &(XCDR (tail)), tail = XCDR (tail))
555     {
556       if (EQ (tail, keysym))
557         {
558           *prev = Qnil;
559           break;
560         }
561       else if (EQ (keysym, XCAR (tail)))
562         {
563           *prev = XCDR (tail);
564           break;
565         }
566     }
567
568   if (NILP (new_keys))
569     Fremhash (value, inverse_table);
570   else if (!EQ (keys, new_keys))
571     /* Removed the first elt */
572     Fputhash (value, new_keys, inverse_table);
573   /* else the list's tail has been modified, so we don't need to
574      touch the hash table again (the pointer in there is ok).
575    */
576 }
577
578 /* Prevent luser from shooting herself in the foot using something like
579    (define-key ctl-x-4-map "p" global-map) */
580 static void
581 check_keymap_definition_loop (Lisp_Object def, Lisp_Keymap *to_keymap)
582 {
583   def = get_keymap (def, 0, 0);
584
585   if (KEYMAPP (def))
586     {
587       Lisp_Object maps;
588
589       if (XKEYMAP (def) == to_keymap)
590         signal_simple_error ("Cyclic keymap definition", def);
591
592       for (maps = keymap_submaps (def);
593            CONSP (maps);
594            maps = XCDR (maps))
595         check_keymap_definition_loop (XCDR (XCAR (maps)), to_keymap);
596     }
597 }
598
599 static void
600 keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap,
601                        Lisp_Object def)
602 {
603   Lisp_Object prev_def = Fgethash (keysym, keymap->table, Qnil);
604
605   if (EQ (prev_def, def))
606       return;
607
608   check_keymap_definition_loop (def, keymap);
609
610   if (!NILP (prev_def))
611     keymap_delete_inverse_internal (keymap->inverse_table,
612                                     keysym, prev_def);
613   if (NILP (def))
614     {
615       Fremhash (keysym, keymap->table);
616     }
617   else
618     {
619       Fputhash (keysym, def, keymap->table);
620       keymap_store_inverse_internal (keymap->inverse_table,
621                                      keysym, def);
622     }
623   keymap_tick++;
624 }
625
626
627 static Lisp_Object
628 create_bucky_submap (Lisp_Keymap *k, int modifiers,
629                      Lisp_Object parent_for_debugging_info)
630 {
631   Lisp_Object submap = Fmake_sparse_keymap (Qnil);
632   /* User won't see this, but it is nice for debugging Emacs */
633   XKEYMAP (submap)->name
634     = control_meta_superify (parent_for_debugging_info, modifiers);
635   /* Invalidate cache */
636   k->sub_maps_cache = Qt;
637   keymap_store_internal (MAKE_MODIFIER_HASH_KEY (modifiers), k, submap);
638   return submap;
639 }
640
641
642 /* Relies on caller to gc-protect keymap, keysym, value */
643 static void
644 keymap_store (Lisp_Object keymap, const struct key_data *key,
645               Lisp_Object value)
646 {
647   Lisp_Object keysym = key->keysym;
648   int modifiers = key->modifiers;
649   Lisp_Keymap *k = XKEYMAP (keymap);
650
651   modifiers &= ~(XEMACS_MOD_BUTTON1 | XEMACS_MOD_BUTTON2 | XEMACS_MOD_BUTTON3
652                  | XEMACS_MOD_BUTTON4 | XEMACS_MOD_BUTTON5);
653   assert ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META
654                          | XEMACS_MOD_SUPER | XEMACS_MOD_HYPER
655                          | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT)) == 0);
656
657   /* If the keysym is a one-character symbol, use the char code instead. */
658   if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1)
659     keysym = make_char (string_char (XSYMBOL (keysym)->name, 0));
660
661   if (modifiers & XEMACS_MOD_META)     /* Utterly hateful ESC lossage */
662     {
663       Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META),
664                                      k->table, Qnil);
665       if (NILP (submap))
666         submap = create_bucky_submap (k, XEMACS_MOD_META, keymap);
667       k = XKEYMAP (submap);
668       modifiers &= ~XEMACS_MOD_META;
669     }
670
671   if (modifiers != 0)
672     {
673       Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers),
674                                      k->table, Qnil);
675       if (NILP (submap))
676         submap = create_bucky_submap (k, modifiers, keymap);
677       k = XKEYMAP (submap);
678     }
679   k->sub_maps_cache = Qt; /* Invalidate cache */
680   keymap_store_internal (keysym, k, value);
681 }
682
683 \f
684 /************************************************************************/
685 /*                   Listing the submaps of a keymap                    */
686 /************************************************************************/
687
688 struct keymap_submaps_closure
689 {
690   Lisp_Object *result_locative;
691 };
692
693 static int
694 keymap_submaps_mapper_0 (Lisp_Object key, Lisp_Object value,
695                          void *keymap_submaps_closure)
696 {
697   /* This function can GC */
698   /* Perform any autoloads, etc */
699   Fkeymapp (value);
700   return 0;
701 }
702
703 static int
704 keymap_submaps_mapper (Lisp_Object key, Lisp_Object value,
705                        void *keymap_submaps_closure)
706 {
707   /* This function can GC */
708   Lisp_Object *result_locative;
709   struct keymap_submaps_closure *cl =
710     (struct keymap_submaps_closure *) keymap_submaps_closure;
711   result_locative = cl->result_locative;
712
713   if (!NILP (Fkeymapp (value)))
714     *result_locative = Fcons (Fcons (key, value), *result_locative);
715   return 0;
716 }
717
718 static int map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
719                                       Lisp_Object pred);
720
721 static Lisp_Object
722 keymap_submaps (Lisp_Object keymap)
723 {
724   /* This function can GC */
725   Lisp_Keymap *k = XKEYMAP (keymap);
726
727   if (EQ (k->sub_maps_cache, Qt)) /* Unknown */
728     {
729       Lisp_Object result = Qnil;
730       struct gcpro gcpro1, gcpro2;
731       struct keymap_submaps_closure keymap_submaps_closure;
732
733       GCPRO2 (keymap, result);
734       keymap_submaps_closure.result_locative = &result;
735       /* Do this first pass to touch (and load) any autoloaded maps */
736       elisp_maphash (keymap_submaps_mapper_0, k->table,
737                      &keymap_submaps_closure);
738       result = Qnil;
739       elisp_maphash (keymap_submaps_mapper, k->table,
740                      &keymap_submaps_closure);
741       /* keep it sorted so that the result of accessible-keymaps is ordered */
742       k->sub_maps_cache = list_sort (result,
743                                      Qnil,
744                                      map_keymap_sort_predicate);
745       UNGCPRO;
746     }
747   return k->sub_maps_cache;
748 }
749
750 \f
751 /************************************************************************/
752 /*                    Basic operations on keymaps                       */
753 /************************************************************************/
754
755 static Lisp_Object
756 make_keymap (size_t size)
757 {
758   Lisp_Object result;
759   Lisp_Keymap *keymap = alloc_lcrecord_type (Lisp_Keymap, &lrecord_keymap);
760
761   XSETKEYMAP (result, keymap);
762
763   keymap->parents         = Qnil;
764   keymap->prompt          = Qnil;
765   keymap->table           = Qnil;
766   keymap->inverse_table   = Qnil;
767   keymap->default_binding = Qnil;
768   keymap->sub_maps_cache  = Qnil; /* No possible submaps */
769   keymap->name            = Qnil;
770
771   if (size != 0) /* hack for copy-keymap */
772     {
773       keymap->table =
774         make_lisp_hash_table (size, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
775       /* Inverse table is often less dense because of duplicate key-bindings.
776          If not, it will grow anyway. */
777       keymap->inverse_table =
778         make_lisp_hash_table (size * 3 / 4, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
779     }
780   return result;
781 }
782
783 DEFUN ("make-keymap", Fmake_keymap, 0, 1, 0, /*
784 Construct and return a new keymap object.
785 All entries in it are nil, meaning "command undefined".
786
787 Optional argument NAME specifies a name to assign to the keymap,
788 as in `set-keymap-name'.  This name is only a debugging convenience;
789 it is not used except when printing the keymap.
790 */
791        (name))
792 {
793   Lisp_Object keymap = make_keymap (60);
794   if (!NILP (name))
795     Fset_keymap_name (keymap, name);
796   return keymap;
797 }
798
799 DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, 0, 1, 0, /*
800 Construct and return a new keymap object.
801 All entries in it are nil, meaning "command undefined".  The only
802 difference between this function and `make-keymap' is that this function
803 returns a "smaller" keymap (one that is expected to contain fewer
804 entries).  As keymaps dynamically resize, this distinction is not great.
805
806 Optional argument NAME specifies a name to assign to the keymap,
807 as in `set-keymap-name'.  This name is only a debugging convenience;
808 it is not used except when printing the keymap.
809 */
810        (name))
811 {
812   Lisp_Object keymap = make_keymap (8);
813   if (!NILP (name))
814     Fset_keymap_name (keymap, name);
815   return keymap;
816 }
817
818 DEFUN ("keymap-parents", Fkeymap_parents, 1, 1, 0, /*
819 Return the `parent' keymaps of KEYMAP, or nil.
820 The parents of a keymap are searched for keybindings when a key sequence
821 isn't bound in this one.  `(current-global-map)' is the default parent
822 of all keymaps.
823 */
824        (keymap))
825 {
826   keymap = get_keymap (keymap, 1, 1);
827   return Fcopy_sequence (XKEYMAP (keymap)->parents);
828 }
829
830
831
832 static Lisp_Object
833 traverse_keymaps_noop (Lisp_Object keymap, void *arg)
834 {
835   return Qnil;
836 }
837
838 DEFUN ("set-keymap-parents", Fset_keymap_parents, 2, 2, 0, /*
839 Set the `parent' keymaps of KEYMAP to PARENTS.
840 The parents of a keymap are searched for keybindings when a key sequence
841 isn't bound in this one.  `(current-global-map)' is the default parent
842 of all keymaps.
843 */
844        (keymap, parents))
845 {
846   /* This function can GC */
847   Lisp_Object k;
848   struct gcpro gcpro1, gcpro2;
849
850   GCPRO2 (keymap, parents);
851   keymap = get_keymap (keymap, 1, 1);
852
853   if (KEYMAPP (parents))        /* backwards-compatibility */
854     parents = list1 (parents);
855   if (!NILP (parents))
856     {
857       Lisp_Object tail = parents;
858       while (!NILP (tail))
859         {
860           QUIT;
861           CHECK_CONS (tail);
862           k = XCAR (tail);
863           /* Require that it be an actual keymap object, rather than a symbol
864              with a (crockish) symbol-function which is a keymap */
865           CHECK_KEYMAP (k); /* get_keymap (k, 1, 1); */
866           tail = XCDR (tail);
867         }
868     }
869
870   /* Check for circularities */
871   traverse_keymaps (keymap, parents, traverse_keymaps_noop, 0);
872   keymap_tick++;
873   XKEYMAP (keymap)->parents = Fcopy_sequence (parents);
874   UNGCPRO;
875   return parents;
876 }
877
878 DEFUN ("set-keymap-name", Fset_keymap_name, 2, 2, 0, /*
879 Set the `name' of the KEYMAP to NEW-NAME.
880 The name is only a debugging convenience; it is not used except
881 when printing the keymap.
882 */
883        (keymap, new_name))
884 {
885   keymap = get_keymap (keymap, 1, 1);
886
887   XKEYMAP (keymap)->name = new_name;
888   return new_name;
889 }
890
891 DEFUN ("keymap-name", Fkeymap_name, 1, 1, 0, /*
892 Return the `name' of KEYMAP.
893 The name is only a debugging convenience; it is not used except
894 when printing the keymap.
895 */
896        (keymap))
897 {
898   keymap = get_keymap (keymap, 1, 1);
899
900   return XKEYMAP (keymap)->name;
901 }
902
903 DEFUN ("set-keymap-prompt", Fset_keymap_prompt, 2, 2, 0, /*
904 Set the `prompt' of KEYMAP to string NEW-PROMPT, or `nil'
905 if no prompt is desired.  The prompt is shown in the echo-area
906 when reading a key-sequence to be looked-up in this keymap.
907 */
908        (keymap, new_prompt))
909 {
910   keymap = get_keymap (keymap, 1, 1);
911
912   if (!NILP (new_prompt))
913     CHECK_STRING (new_prompt);
914
915   XKEYMAP (keymap)->prompt = new_prompt;
916   return new_prompt;
917 }
918
919 static Lisp_Object
920 keymap_prompt_mapper (Lisp_Object keymap, void *arg)
921 {
922   return XKEYMAP (keymap)->prompt;
923 }
924
925
926 DEFUN ("keymap-prompt", Fkeymap_prompt, 1, 2, 0, /*
927 Return the `prompt' of KEYMAP.
928 If non-nil, the prompt is shown in the echo-area
929 when reading a key-sequence to be looked-up in this keymap.
930 */
931        (keymap, use_inherited))
932 {
933   /* This function can GC */
934   Lisp_Object prompt;
935
936   keymap = get_keymap (keymap, 1, 1);
937   prompt = XKEYMAP (keymap)->prompt;
938   if (!NILP (prompt) || NILP (use_inherited))
939     return prompt;
940   else
941     return traverse_keymaps (keymap, Qnil, keymap_prompt_mapper, 0);
942 }
943
944 DEFUN ("set-keymap-default-binding", Fset_keymap_default_binding, 2, 2, 0, /*
945 Sets the default binding of KEYMAP to COMMAND, or `nil'
946 if no default is desired.  The default-binding is returned when
947 no other binding for a key-sequence is found in the keymap.
948 If a keymap has a non-nil default-binding, neither the keymap's
949 parents nor the current global map are searched for key bindings.
950 */
951        (keymap, command))
952 {
953   /* This function can GC */
954   keymap = get_keymap (keymap, 1, 1);
955
956   XKEYMAP (keymap)->default_binding = command;
957   return command;
958 }
959
960 DEFUN ("keymap-default-binding", Fkeymap_default_binding, 1, 1, 0, /*
961 Return the default binding of KEYMAP, or `nil' if it has none.
962 The default-binding is returned when no other binding for a key-sequence
963 is found in the keymap.
964 If a keymap has a non-nil default-binding, neither the keymap's
965 parents nor the current global map are searched for key bindings.
966 */
967        (keymap))
968 {
969   /* This function can GC */
970   keymap = get_keymap (keymap, 1, 1);
971   return XKEYMAP (keymap)->default_binding;
972 }
973
974 DEFUN ("keymapp", Fkeymapp, 1, 1, 0, /*
975 Return t if OBJECT is a keymap object.
976 The keymap may be autoloaded first if necessary.
977 */
978        (object))
979 {
980   /* This function can GC */
981   return KEYMAPP (get_keymap (object, 0, 0)) ? Qt : Qnil;
982 }
983
984 /* Check that OBJECT is a keymap (after dereferencing through any
985    symbols).  If it is, return it.
986
987    If AUTOLOAD is non-zero and OBJECT is a symbol whose function value
988    is an autoload form, do the autoload and try again.
989    If AUTOLOAD is nonzero, callers must assume GC is possible.
990
991    ERRORP controls how we respond if OBJECT isn't a keymap.
992    If ERRORP is non-zero, signal an error; otherwise, just return Qnil.
993
994    Note that most of the time, we don't want to pursue autoloads.
995    Functions like Faccessible_keymaps which scan entire keymap trees
996    shouldn't load every autoloaded keymap.  I'm not sure about this,
997    but it seems to me that only read_key_sequence, Flookup_key, and
998    Fdefine_key should cause keymaps to be autoloaded.  */
999
1000 Lisp_Object
1001 get_keymap (Lisp_Object object, int errorp, int autoload)
1002 {
1003   /* This function can GC */
1004   while (1)
1005     {
1006       Lisp_Object tem = indirect_function (object, 0);
1007
1008       if (KEYMAPP (tem))
1009         return tem;
1010       /* Should we do an autoload?  */
1011       else if (autoload
1012                /* (autoload "filename" doc nil keymap) */
1013                && SYMBOLP (object)
1014                && CONSP (tem)
1015                && EQ (XCAR (tem), Qautoload)
1016                && EQ (Fcar (Fcdr (Fcdr (Fcdr (Fcdr (tem))))), Qkeymap))
1017         {
1018           struct gcpro gcpro1, gcpro2;
1019           GCPRO2 (tem, object);
1020           do_autoload (tem, object);
1021           UNGCPRO;
1022         }
1023       else if (errorp)
1024         object = wrong_type_argument (Qkeymapp, object);
1025       else
1026         return Qnil;
1027     }
1028 }
1029
1030 /* Given OBJECT which was found in a slot in a keymap,
1031    trace indirect definitions to get the actual definition of that slot.
1032    An indirect definition is a list of the form
1033    (KEYMAP . INDEX), where KEYMAP is a keymap or a symbol defined as one
1034    and INDEX is an ASCII code, or a cons of (KEYSYM . MODIFIERS).
1035  */
1036 static Lisp_Object
1037 get_keyelt (Lisp_Object object, int accept_default)
1038 {
1039   /* This function can GC */
1040   Lisp_Object map;
1041
1042  tail_recurse:
1043   if (!CONSP (object))
1044     return object;
1045
1046   {
1047     struct gcpro gcpro1;
1048     GCPRO1 (object);
1049     map = XCAR (object);
1050     map = get_keymap (map, 0, 1);
1051     UNGCPRO;
1052   }
1053   /* If the contents are (KEYMAP . ELEMENT), go indirect.  */
1054   if (!NILP (map))
1055     {
1056       Lisp_Object idx = Fcdr (object);
1057       struct key_data indirection;
1058       if (CHARP (idx))
1059         {
1060           Lisp_Event event;
1061           event.event_type = empty_event;
1062           character_to_event (XCHAR (idx), &event,
1063                               XCONSOLE (Vselected_console), 0, 0);
1064           indirection = event.event.key;
1065         }
1066       else if (CONSP (idx))
1067         {
1068           if (!INTP (XCDR (idx)))
1069             return Qnil;
1070           indirection.keysym = XCAR (idx);
1071           indirection.modifiers = (unsigned char) XINT (XCDR (idx));
1072         }
1073       else if (SYMBOLP (idx))
1074         {
1075           indirection.keysym = idx;
1076           indirection.modifiers = 0;
1077         }
1078       else
1079         {
1080           /* Random junk */
1081           return Qnil;
1082         }
1083       return raw_lookup_key (map, &indirection, 1, 0, accept_default);
1084     }
1085   else if (STRINGP (XCAR (object)))
1086     {
1087       /* If the keymap contents looks like (STRING . DEFN),
1088          use DEFN.
1089          Keymap alist elements like (CHAR MENUSTRING . DEFN)
1090          will be used by HierarKey menus.  */
1091       object = XCDR (object);
1092       goto tail_recurse;
1093     }
1094   else
1095     {
1096       /* Anything else is really the value.  */
1097       return object;
1098     }
1099 }
1100
1101 static Lisp_Object
1102 keymap_lookup_1 (Lisp_Object keymap, const struct key_data *key,
1103                  int accept_default)
1104 {
1105   /* This function can GC */
1106   return get_keyelt (keymap_lookup_directly (keymap,
1107                                              key->keysym, key->modifiers),
1108                      accept_default);
1109 }
1110
1111 \f
1112 /************************************************************************/
1113 /*                          Copying keymaps                             */
1114 /************************************************************************/
1115
1116 struct copy_keymap_inverse_closure
1117 {
1118   Lisp_Object inverse_table;
1119 };
1120
1121 static int
1122 copy_keymap_inverse_mapper (Lisp_Object key, Lisp_Object value,
1123                             void *copy_keymap_inverse_closure)
1124 {
1125   struct copy_keymap_inverse_closure *closure =
1126     (struct copy_keymap_inverse_closure *) copy_keymap_inverse_closure;
1127
1128   /* copy-sequence deals with dotted lists. */
1129   if (CONSP (value))
1130     value = Fcopy_list (value);
1131   Fputhash (key, value, closure->inverse_table);
1132
1133   return 0;
1134 }
1135
1136
1137 static Lisp_Object
1138 copy_keymap_internal (Lisp_Keymap *keymap)
1139 {
1140   Lisp_Object nkm = make_keymap (0);
1141   Lisp_Keymap *new_keymap = XKEYMAP (nkm);
1142   struct copy_keymap_inverse_closure copy_keymap_inverse_closure;
1143   copy_keymap_inverse_closure.inverse_table = keymap->inverse_table;
1144
1145   new_keymap->parents        = Fcopy_sequence (keymap->parents);
1146   new_keymap->sub_maps_cache = Qnil; /* No submaps */
1147   new_keymap->table          = Fcopy_hash_table (keymap->table);
1148   new_keymap->inverse_table  = Fcopy_hash_table (keymap->inverse_table);
1149   new_keymap->default_binding = keymap->default_binding;
1150   /* After copying the inverse map, we need to copy the conses which
1151      are its values, lest they be shared by the copy, and mangled.
1152    */
1153   elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table,
1154                  &copy_keymap_inverse_closure);
1155   return nkm;
1156 }
1157
1158
1159 static Lisp_Object copy_keymap (Lisp_Object keymap);
1160
1161 struct copy_keymap_closure
1162 {
1163   Lisp_Keymap *self;
1164 };
1165
1166 static int
1167 copy_keymap_mapper (Lisp_Object key, Lisp_Object value,
1168                     void *copy_keymap_closure)
1169 {
1170   /* This function can GC */
1171   struct copy_keymap_closure *closure =
1172     (struct copy_keymap_closure *) copy_keymap_closure;
1173
1174   /* When we encounter a keymap which is indirected through a
1175      symbol, we need to copy the sub-map.  In v18, the form
1176        (lookup-key (copy-keymap global-map) "\C-x")
1177      returned a new keymap, not the symbol 'Control-X-prefix.
1178    */
1179   value = get_keymap (value, 0, 1); /* #### autoload GC-safe here? */
1180   if (KEYMAPP (value))
1181     keymap_store_internal (key, closure->self,
1182                            copy_keymap (value));
1183   return 0;
1184 }
1185
1186 static Lisp_Object
1187 copy_keymap (Lisp_Object keymap)
1188 {
1189   /* This function can GC */
1190   struct copy_keymap_closure copy_keymap_closure;
1191
1192   keymap = copy_keymap_internal (XKEYMAP (keymap));
1193   copy_keymap_closure.self = XKEYMAP (keymap);
1194   elisp_maphash (copy_keymap_mapper,
1195                  XKEYMAP (keymap)->table,
1196                  &copy_keymap_closure);
1197   return keymap;
1198 }
1199
1200 DEFUN ("copy-keymap", Fcopy_keymap, 1, 1, 0, /*
1201 Return a copy of the keymap KEYMAP.
1202 The copy starts out with the same definitions of KEYMAP,
1203 but changing either the copy or KEYMAP does not affect the other.
1204 Any key definitions that are subkeymaps are recursively copied.
1205 */
1206        (keymap))
1207 {
1208   /* This function can GC */
1209   keymap = get_keymap (keymap, 1, 1);
1210   return copy_keymap (keymap);
1211 }
1212
1213 \f
1214 static int
1215 keymap_fullness (Lisp_Object keymap)
1216 {
1217   /* This function can GC */
1218   int fullness;
1219   Lisp_Object sub_maps;
1220   struct gcpro gcpro1, gcpro2;
1221
1222   keymap = get_keymap (keymap, 1, 1);
1223   fullness = XINT (Fhash_table_count (XKEYMAP (keymap)->table));
1224   GCPRO2 (keymap, sub_maps);
1225   for (sub_maps = keymap_submaps (keymap);
1226        !NILP (sub_maps);
1227        sub_maps = XCDR (sub_maps))
1228     {
1229       if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0)
1230         {
1231           Lisp_Object bucky_map = XCDR (XCAR (sub_maps));
1232           fullness--; /* don't count bucky maps themselves. */
1233           fullness += keymap_fullness (bucky_map);
1234         }
1235     }
1236   UNGCPRO;
1237   return fullness;
1238 }
1239
1240 DEFUN ("keymap-fullness", Fkeymap_fullness, 1, 1, 0, /*
1241 Return the number of bindings in the keymap.
1242 */
1243        (keymap))
1244 {
1245   /* This function can GC */
1246   return make_int (keymap_fullness (get_keymap (keymap, 1, 1)));
1247 }
1248
1249 \f
1250 /************************************************************************/
1251 /*                        Defining keys in keymaps                      */
1252 /************************************************************************/
1253
1254 /* Given a keysym (should be a symbol, int, char), make sure it's valid
1255    and perform any necessary canonicalization. */
1256
1257 static void
1258 define_key_check_and_coerce_keysym (Lisp_Object spec,
1259                                     Lisp_Object *keysym,
1260                                     int modifiers)
1261 {
1262   /* Now, check and massage the trailing keysym specifier. */
1263   if (SYMBOLP (*keysym))
1264     {
1265       if (string_char_length (XSYMBOL (*keysym)->name) == 1)
1266         {
1267           Lisp_Object ream_gcc_up_the_ass =
1268             make_char (string_char (XSYMBOL (*keysym)->name, 0));
1269           *keysym = ream_gcc_up_the_ass;
1270           goto fixnum_keysym;
1271         }
1272     }
1273   else if (CHAR_OR_CHAR_INTP (*keysym))
1274     {
1275       CHECK_CHAR_COERCE_INT (*keysym);
1276     fixnum_keysym:
1277       if (XCHAR (*keysym) < ' '
1278           /* || (XCHAR (*keysym) >= 128 && XCHAR (*keysym) < 160) */)
1279         /* yuck!  Can't make the above restriction; too many compatibility
1280            problems ... */
1281         signal_simple_error ("keysym char must be printable", *keysym);
1282       /* #### This bites!  I want to be able to write (control shift a) */
1283       if (modifiers & XEMACS_MOD_SHIFT)
1284         signal_simple_error
1285           ("The `shift' modifier may not be applied to ASCII keysyms",
1286            spec);
1287     }
1288   else
1289     {
1290       signal_simple_error ("Unknown keysym specifier", *keysym);
1291     }
1292
1293   if (SYMBOLP (*keysym))
1294     {
1295       char *name = (char *) string_data (XSYMBOL (*keysym)->name);
1296
1297       /* FSFmacs uses symbols with the printed representation of keysyms in
1298          their names, like 'M-x, and we use the syntax '(meta x).  So, to avoid
1299          confusion, notice the M-x syntax and signal an error - because
1300          otherwise it would be interpreted as a regular keysym, and would even
1301          show up in the list-buffers output, causing confusion to the naive.
1302
1303          We can get away with this because none of the X keysym names contain
1304          a hyphen (some contain underscore, however).
1305
1306          It might be useful to reject keysyms which are not x-valid-keysym-
1307          name-p, but that would interfere with various tricks we do to
1308          sanitize the Sun keyboards, and would make it trickier to
1309          conditionalize a .emacs file for multiple X servers.
1310          */
1311       if (((int) strlen (name) >= 2 && name[1] == '-')
1312 #if 1
1313           ||
1314           /* Ok, this is a bit more dubious - prevent people from doing things
1315              like (global-set-key 'RET 'something) because that will have the
1316              same problem as above.  (Gag!)  Maybe we should just silently
1317              accept these as aliases for the "real" names?
1318              */
1319           (string_length (XSYMBOL (*keysym)->name) <= 3 &&
1320            (!strcmp (name, "LFD") ||
1321             !strcmp (name, "TAB") ||
1322             !strcmp (name, "RET") ||
1323             !strcmp (name, "ESC") ||
1324             !strcmp (name, "DEL") ||
1325             !strcmp (name, "SPC") ||
1326             !strcmp (name, "BS")))
1327 #endif /* unused */
1328           )
1329         signal_simple_error
1330           ("Invalid (FSF Emacs) key format (see doc of define-key)",
1331            *keysym);
1332
1333       /* #### Ok, this is a bit more dubious - make people not lose if they
1334          do things like (global-set-key 'RET 'something) because that would
1335          otherwise have the same problem as above.  (Gag!)  We silently
1336          accept these as aliases for the "real" names.
1337          */
1338       else if (!strncmp(name, "kp_", 3)) {
1339         /* Likewise, the obsolete keysym binding of kp_.* should not lose. */
1340         char temp[50];
1341
1342         strncpy(temp, name, sizeof (temp));
1343         temp[sizeof (temp) - 1] = '\0';
1344         temp[2] = '-';
1345         *keysym = Fintern_soft(make_string((Bufbyte *)temp,
1346                                            strlen(temp)),
1347                                Qnil);
1348       } else if (EQ (*keysym, QLFD))
1349         *keysym = QKlinefeed;
1350       else if (EQ (*keysym, QTAB))
1351         *keysym = QKtab;
1352       else if (EQ (*keysym, QRET))
1353         *keysym = QKreturn;
1354       else if (EQ (*keysym, QESC))
1355         *keysym = QKescape;
1356       else if (EQ (*keysym, QDEL))
1357         *keysym = QKdelete;
1358       else if (EQ (*keysym, QSPC))
1359         *keysym = QKspace;
1360       else if (EQ (*keysym, QBS))
1361         *keysym = QKbackspace;
1362       /* Emacs compatibility */
1363       else if (EQ(*keysym, Qdown_mouse_1))
1364         *keysym = Qbutton1;
1365       else if (EQ(*keysym, Qdown_mouse_2))
1366         *keysym = Qbutton2;
1367       else if (EQ(*keysym, Qdown_mouse_3))
1368         *keysym = Qbutton3;
1369       else if (EQ(*keysym, Qdown_mouse_4))
1370         *keysym = Qbutton4;
1371       else if (EQ(*keysym, Qdown_mouse_5))
1372         *keysym = Qbutton5;
1373       else if (EQ(*keysym, Qdown_mouse_6))
1374         *keysym = Qbutton6;
1375       else if (EQ(*keysym, Qdown_mouse_7))
1376         *keysym = Qbutton7;
1377       else if (EQ(*keysym, Qmouse_1))
1378         *keysym = Qbutton1up;
1379       else if (EQ(*keysym, Qmouse_2))
1380         *keysym = Qbutton2up;
1381       else if (EQ(*keysym, Qmouse_3))
1382         *keysym = Qbutton3up;
1383       else if (EQ(*keysym, Qmouse_4))
1384         *keysym = Qbutton4up;
1385       else if (EQ(*keysym, Qmouse_5))
1386         *keysym = Qbutton5up;
1387       else if (EQ(*keysym, Qmouse_6))
1388         *keysym = Qbutton6up;
1389       else if (EQ(*keysym, Qmouse_7))
1390         *keysym = Qbutton7up;
1391     }
1392 }
1393
1394
1395 /* Given any kind of key-specifier, return a keysym and modifier mask.
1396    Proper canonicalization is performed:
1397
1398    -- integers are converted into the equivalent characters.
1399    -- one-character strings are converted into the equivalent characters.
1400  */
1401
1402 static void
1403 define_key_parser (Lisp_Object spec, struct key_data *returned_value)
1404 {
1405   if (CHAR_OR_CHAR_INTP (spec))
1406     {
1407       Lisp_Event event;
1408       event.event_type = empty_event;
1409       character_to_event (XCHAR_OR_CHAR_INT (spec), &event,
1410                           XCONSOLE (Vselected_console), 0, 0);
1411       returned_value->keysym    = event.event.key.keysym;
1412       returned_value->modifiers = event.event.key.modifiers;
1413     }
1414   else if (EVENTP (spec))
1415     {
1416       switch (XEVENT (spec)->event_type)
1417         {
1418         case key_press_event:
1419           {
1420             returned_value->keysym    = XEVENT (spec)->event.key.keysym;
1421             returned_value->modifiers = XEVENT (spec)->event.key.modifiers;
1422             break;
1423           }
1424         case button_press_event:
1425         case button_release_event:
1426           {
1427             int down = (XEVENT (spec)->event_type == button_press_event);
1428             switch (XEVENT (spec)->event.button.button)
1429               {
1430               case 1:
1431                 returned_value->keysym = (down ? Qbutton1 : Qbutton1up); break;
1432               case 2:
1433                 returned_value->keysym = (down ? Qbutton2 : Qbutton2up); break;
1434               case 3:
1435                 returned_value->keysym = (down ? Qbutton3 : Qbutton3up); break;
1436               case 4:
1437                 returned_value->keysym = (down ? Qbutton4 : Qbutton4up); break;
1438               case 5:
1439                 returned_value->keysym = (down ? Qbutton5 : Qbutton5up); break;
1440               case 6:
1441                 returned_value->keysym = (down ? Qbutton6 : Qbutton6up); break;
1442               case 7:
1443                 returned_value->keysym = (down ? Qbutton7 : Qbutton7up); break;
1444               default:
1445                 returned_value->keysym = (down ? Qbutton0 : Qbutton0up); break;
1446               }
1447             returned_value->modifiers = XEVENT (spec)->event.button.modifiers;
1448             break;
1449           }
1450         default:
1451           signal_error (Qwrong_type_argument,
1452                         list2 (build_translated_string
1453                                ("unable to bind this type of event"),
1454                                spec));
1455         }
1456     }
1457   else if (SYMBOLP (spec))
1458     {
1459       /* Be nice, allow = to mean (=) */
1460       if (bucky_sym_to_bucky_bit (spec) != 0)
1461         signal_simple_error ("Key is a modifier name", spec);
1462       define_key_check_and_coerce_keysym (spec, &spec, 0);
1463       returned_value->keysym = spec;
1464       returned_value->modifiers = 0;
1465     }
1466   else if (CONSP (spec))
1467     {
1468       int modifiers = 0;
1469       Lisp_Object keysym = Qnil;
1470       Lisp_Object rest = spec;
1471
1472       /* First, parse out the leading modifier symbols. */
1473       while (CONSP (rest))
1474         {
1475           int modifier;
1476
1477           keysym = XCAR (rest);
1478           modifier = bucky_sym_to_bucky_bit (keysym);
1479           modifiers |= modifier;
1480           if (!NILP (XCDR (rest)))
1481             {
1482               if (! modifier)
1483                 signal_simple_error ("Unknown modifier", keysym);
1484             }
1485           else
1486             {
1487               if (modifier)
1488                 signal_simple_error ("Nothing but modifiers here",
1489                                      spec);
1490             }
1491           rest = XCDR (rest);
1492           QUIT;
1493         }
1494       if (!NILP (rest))
1495         signal_simple_error ("List must be nil-terminated", spec);
1496
1497       define_key_check_and_coerce_keysym (spec, &keysym, modifiers);
1498       returned_value->keysym = keysym;
1499       returned_value->modifiers = modifiers;
1500     }
1501   else
1502     {
1503       signal_simple_error ("Unknown key-sequence specifier",
1504                            spec);
1505     }
1506 }
1507
1508 /* Used by character-to-event */
1509 void
1510 key_desc_list_to_event (Lisp_Object list, Lisp_Object event,
1511                         int allow_menu_events)
1512 {
1513   struct key_data raw_key;
1514
1515   if (allow_menu_events &&
1516       CONSP (list) &&
1517       /* #### where the hell does this come from? */
1518       EQ (XCAR (list), Qmenu_selection))
1519     {
1520       Lisp_Object fn, arg;
1521       if (! NILP (Fcdr (Fcdr (list))))
1522         signal_simple_error ("Invalid menu event desc", list);
1523       arg = Fcar (Fcdr (list));
1524       if (SYMBOLP (arg))
1525         fn = Qcall_interactively;
1526       else
1527         fn = Qeval;
1528       XSETFRAME (XEVENT (event)->channel, selected_frame ());
1529       XEVENT (event)->event_type = misc_user_event;
1530       XEVENT (event)->event.eval.function = fn;
1531       XEVENT (event)->event.eval.object = arg;
1532       return;
1533     }
1534
1535   define_key_parser (list, &raw_key);
1536
1537   if (EQ (raw_key.keysym, Qbutton0) || EQ (raw_key.keysym, Qbutton0up) ||
1538       EQ (raw_key.keysym, Qbutton1) || EQ (raw_key.keysym, Qbutton1up) ||
1539       EQ (raw_key.keysym, Qbutton2) || EQ (raw_key.keysym, Qbutton2up) ||
1540       EQ (raw_key.keysym, Qbutton3) || EQ (raw_key.keysym, Qbutton3up) ||
1541       EQ (raw_key.keysym, Qbutton4) || EQ (raw_key.keysym, Qbutton4up) ||
1542       EQ (raw_key.keysym, Qbutton5) || EQ (raw_key.keysym, Qbutton5up) ||
1543       EQ (raw_key.keysym, Qbutton6) || EQ (raw_key.keysym, Qbutton6up) ||
1544       EQ (raw_key.keysym, Qbutton7) || EQ (raw_key.keysym, Qbutton7up))
1545     error ("Mouse-clicks can't appear in saved keyboard macros.");
1546
1547   XEVENT (event)->channel = Vselected_console;
1548   XEVENT (event)->event_type = key_press_event;
1549   XEVENT (event)->event.key.keysym = raw_key.keysym;
1550   XEVENT (event)->event.key.modifiers = raw_key.modifiers;
1551 }
1552
1553
1554 int
1555 event_matches_key_specifier_p (Lisp_Event *event, Lisp_Object key_specifier)
1556 {
1557   Lisp_Object event2 = Qnil;
1558   int retval;
1559   struct gcpro gcpro1;
1560
1561   if (event->event_type != key_press_event || NILP (key_specifier) ||
1562       (INTP (key_specifier) && !CHAR_INTP (key_specifier)))
1563     return 0;
1564
1565   /* if the specifier is an integer such as 27, then it should match
1566      both of the events 'escape' and 'control ['.  Calling
1567      Fcharacter_to_event() will only match 'escape'. */
1568   if (CHAR_OR_CHAR_INTP (key_specifier))
1569     return (XCHAR_OR_CHAR_INT (key_specifier)
1570             == event_to_character (event, 0, 0, 0));
1571
1572   /* Otherwise, we cannot call event_to_character() because we may
1573      be dealing with non-ASCII keystrokes.  In any case, if I ask
1574      for 'control [' then I should get exactly that, and not
1575      'escape'.
1576
1577      However, we have to behave differently on TTY's, where 'control ['
1578      is silently converted into 'escape' by the keyboard driver.
1579      In this case, ASCII is the only thing we know about, so we have
1580      to compare the ASCII values. */
1581
1582   GCPRO1 (event2);
1583   event2 = Fmake_event (Qnil, Qnil);
1584   Fcharacter_to_event (key_specifier, event2, Qnil, Qnil);
1585   if (XEVENT (event2)->event_type != key_press_event)
1586     retval = 0;
1587   else if (CONSOLE_TTY_P (XCONSOLE (EVENT_CHANNEL (event))))
1588     {
1589       int ch1, ch2;
1590
1591       ch1 = event_to_character (event, 0, 0, 0);
1592       ch2 = event_to_character (XEVENT (event2), 0, 0, 0);
1593       retval = (ch1 >= 0 && ch2 >= 0 && ch1 == ch2);
1594     }
1595   else if (EQ (event->event.key.keysym, XEVENT (event2)->event.key.keysym) &&
1596            event->event.key.modifiers == XEVENT (event2)->event.key.modifiers)
1597     retval = 1;
1598   else
1599     retval = 0;
1600   Fdeallocate_event (event2);
1601   UNGCPRO;
1602   return retval;
1603 }
1604
1605 static int
1606 meta_prefix_char_p (const struct key_data *key)
1607 {
1608   Lisp_Event event;
1609
1610   event.event_type = key_press_event;
1611   event.channel = Vselected_console;
1612   event.event.key.keysym = key->keysym;
1613   event.event.key.modifiers = key->modifiers;
1614   return event_matches_key_specifier_p (&event, Vmeta_prefix_char);
1615 }
1616
1617 DEFUN ("event-matches-key-specifier-p", Fevent_matches_key_specifier_p, 2, 2, 0, /*
1618 Return non-nil if EVENT matches KEY-SPECIFIER.
1619 This can be useful, e.g., to determine if the user pressed `help-char' or
1620 `quit-char'.
1621 */
1622        (event, key_specifier))
1623 {
1624   CHECK_LIVE_EVENT (event);
1625   return (event_matches_key_specifier_p (XEVENT (event), key_specifier)
1626           ? Qt : Qnil);
1627 }
1628
1629 #define MACROLET(k,m) do {              \
1630   returned_value->keysym = (k);         \
1631   returned_value->modifiers = (m);      \
1632   RETURN_SANS_WARNINGS;                 \
1633 } while (0)
1634
1635 /* ASCII grunge.
1636    Given a keysym, return another keysym/modifier pair which could be
1637    considered the same key in an ASCII world.  Backspace returns ^H, for
1638    example.
1639  */
1640 static void
1641 define_key_alternate_name (struct key_data *key,
1642                            struct key_data *returned_value)
1643 {
1644   Lisp_Object keysym = key->keysym;
1645   int modifiers = key->modifiers;
1646   int modifiers_sans_control = (modifiers & (~XEMACS_MOD_CONTROL));
1647   int modifiers_sans_meta = (modifiers & (~XEMACS_MOD_META));
1648   returned_value->keysym = Qnil; /* By default, no "alternate" key */
1649   returned_value->modifiers = 0;
1650   if (modifiers_sans_meta == XEMACS_MOD_CONTROL)
1651     {
1652       if EQ (keysym, QKspace)
1653         MACROLET (make_char ('@'), modifiers);
1654       else if (!CHARP (keysym))
1655         return;
1656       else switch (XCHAR (keysym))
1657         {
1658         case '@':               /* c-@ => c-space */
1659           MACROLET (QKspace, modifiers);
1660         case 'h':               /* c-h => backspace */
1661           MACROLET (QKbackspace, modifiers_sans_control);
1662         case 'i':               /* c-i => tab */
1663           MACROLET (QKtab, modifiers_sans_control);
1664         case 'j':               /* c-j => linefeed */
1665           MACROLET (QKlinefeed, modifiers_sans_control);
1666         case 'm':               /* c-m => return */
1667           MACROLET (QKreturn, modifiers_sans_control);
1668         case '[':               /* c-[ => escape */
1669           MACROLET (QKescape, modifiers_sans_control);
1670         default:
1671           return;
1672         }
1673     }
1674   else if (modifiers_sans_meta != 0)
1675     return;
1676   else if (EQ (keysym, QKbackspace)) /* backspace => c-h */
1677     MACROLET (make_char ('h'), (modifiers | XEMACS_MOD_CONTROL));
1678   else if (EQ (keysym, QKtab))       /* tab => c-i */
1679     MACROLET (make_char ('i'), (modifiers | XEMACS_MOD_CONTROL));
1680   else if (EQ (keysym, QKlinefeed))  /* linefeed => c-j */
1681     MACROLET (make_char ('j'), (modifiers | XEMACS_MOD_CONTROL));
1682   else if (EQ (keysym, QKreturn))    /* return => c-m */
1683     MACROLET (make_char ('m'), (modifiers | XEMACS_MOD_CONTROL));
1684   else if (EQ (keysym, QKescape))    /* escape => c-[ */
1685     MACROLET (make_char ('['), (modifiers | XEMACS_MOD_CONTROL));
1686   else
1687     return;
1688 #undef MACROLET
1689 }
1690
1691
1692 static void
1693 ensure_meta_prefix_char_keymapp (Lisp_Object keys, int indx,
1694                                  Lisp_Object keymap)
1695 {
1696   /* This function can GC */
1697   Lisp_Object new_keys;
1698   int i;
1699   Lisp_Object mpc_binding;
1700   struct key_data meta_key;
1701
1702   if (NILP (Vmeta_prefix_char) ||
1703       (INTP (Vmeta_prefix_char) && !CHAR_INTP (Vmeta_prefix_char)))
1704     return;
1705
1706   define_key_parser (Vmeta_prefix_char, &meta_key);
1707   mpc_binding = keymap_lookup_1 (keymap, &meta_key, 0);
1708   if (NILP (mpc_binding) || !NILP (Fkeymapp (mpc_binding)))
1709     return;
1710
1711   if (indx == 0)
1712     new_keys = keys;
1713   else if (STRINGP (keys))
1714     new_keys = Fsubstring (keys, Qzero, make_int (indx));
1715   else if (VECTORP (keys))
1716     {
1717       new_keys = make_vector (indx, Qnil);
1718       for (i = 0; i < indx; i++)
1719         XVECTOR_DATA (new_keys) [i] = XVECTOR_DATA (keys) [i];
1720     }
1721   else
1722     {
1723       new_keys = Qnil;
1724       abort ();
1725     }
1726
1727   if (EQ (keys, new_keys))
1728     error_with_frob (mpc_binding,
1729                      "can't bind %s: %s has a non-keymap binding",
1730                      (char *) XSTRING_DATA (Fkey_description (keys)),
1731                      (char *) XSTRING_DATA (Fsingle_key_description
1732                                             (Vmeta_prefix_char)));
1733   else
1734     error_with_frob (mpc_binding,
1735                      "can't bind %s: %s %s has a non-keymap binding",
1736                      (char *) XSTRING_DATA (Fkey_description (keys)),
1737                      (char *) XSTRING_DATA (Fkey_description (new_keys)),
1738                      (char *) XSTRING_DATA (Fsingle_key_description
1739                                             (Vmeta_prefix_char)));
1740 }
1741
1742 DEFUN ("define-key", Fdefine_key, 3, 3, 0, /*
1743 Define key sequence KEYS, in KEYMAP, as DEF.
1744 KEYMAP is a keymap object.
1745 KEYS is the sequence of keystrokes to bind, described below.
1746 DEF is anything that can be a key's definition:
1747  nil (means key is undefined in this keymap);
1748  a command (a Lisp function suitable for interactive calling);
1749  a string or key sequence vector (treated as a keyboard macro);
1750  a keymap (to define a prefix key);
1751  a symbol; when the key is looked up, the symbol will stand for its
1752     function definition, that should at that time be one of the above,
1753     or another symbol whose function definition is used, and so on.
1754  a cons (STRING . DEFN), meaning that DEFN is the definition
1755     (DEFN should be a valid definition in its own right);
1756  or a cons (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP.
1757
1758 Contrary to popular belief, the world is not ASCII.  When running under a
1759 window manager, XEmacs can tell the difference between, for example, the
1760 keystrokes control-h, control-shift-h, and backspace.  You can, in fact,
1761 bind different commands to each of these.
1762
1763 A `key sequence' is a set of keystrokes.  A `keystroke' is a keysym and some
1764 set of modifiers (such as control and meta).  A `keysym' is what is printed
1765 on the keys on your keyboard.
1766
1767 A keysym may be represented by a symbol, or (if and only if it is equivalent
1768 to an ASCII character in the range 32 - 255) by a character or its equivalent
1769 ASCII code.  The `A' key may be represented by the symbol `A', the character
1770 `?A', or by the number 65.  The `break' key may be represented only by the
1771 symbol `break'.
1772
1773 A keystroke may be represented by a list: the last element of the list
1774 is the key (a symbol, character, or number, as above) and the
1775 preceding elements are the symbolic names of modifier keys (control,
1776 meta, super, hyper, alt, and shift).  Thus, the sequence control-b is
1777 represented by the forms `(control b)', `(control ?b)', and `(control
1778 98)'.  A keystroke may also be represented by an event object, as
1779 returned by the `next-command-event' and `read-key-sequence'
1780 functions.
1781
1782 Note that in this context, the keystroke `control-b' is *not* represented
1783 by the number 2 (the ASCII code for ^B) or the character `?\^B'.  See below.
1784
1785 The `shift' modifier is somewhat of a special case.  You should not (and
1786 cannot) use `(meta shift a)' to mean `(meta A)', since for characters that
1787 have ASCII equivalents, the state of the shift key is implicit in the
1788 keysym (a vs. A).  You also cannot say `(shift =)' to mean `+', as that
1789 sort of thing varies from keyboard to keyboard.  The shift modifier is for
1790 use only with characters that do not have a second keysym on the same key,
1791 such as `backspace' and `tab'.
1792
1793 A key sequence is a vector of keystrokes.  As a degenerate case, elements
1794 of this vector may also be keysyms if they have no modifiers.  That is,
1795 the `A' keystroke is represented by all of these forms:
1796         A       ?A      65      (A)     (?A)    (65)
1797         [A]     [?A]    [65]    [(A)]   [(?A)]  [(65)]
1798
1799 the `control-a' keystroke is represented by these forms:
1800         (control A)     (control ?A)    (control 65)
1801         [(control A)]   [(control ?A)]  [(control 65)]
1802 the key sequence `control-c control-a' is represented by these forms:
1803         [(control c) (control a)]       [(control ?c) (control ?a)]
1804         [(control 99) (control 65)]     etc.
1805
1806 Mouse button clicks work just like keypresses: (control button1) means
1807 pressing the left mouse button while holding down the control key.
1808 \[(control c) (shift button3)] means control-c, hold shift, click right.
1809
1810 Commands may be bound to the mouse-button up-stroke rather than the down-
1811 stroke as well.  `button1' means the down-stroke, and `button1up' means the
1812 up-stroke.  Different commands may be bound to the up and down strokes,
1813 though that is probably not what you want, so be careful.
1814
1815 For backward compatibility, a key sequence may also be represented by a
1816 string.  In this case, it represents the key sequence(s) that would
1817 produce that sequence of ASCII characters in a purely ASCII world.  For
1818 example, a string containing the ASCII backspace character, "\\^H", would
1819 represent two key sequences: `(control h)' and `backspace'.  Binding a
1820 command to this will actually bind both of those key sequences.  Likewise
1821 for the following pairs:
1822
1823                 control h       backspace
1824                 control i       tab
1825                 control m       return
1826                 control j       linefeed
1827                 control [       escape
1828                 control @       control space
1829
1830 After binding a command to two key sequences with a form like
1831
1832         (define-key global-map "\\^X\\^I" \'command-1)
1833
1834 it is possible to redefine only one of those sequences like so:
1835
1836         (define-key global-map [(control x) (control i)] \'command-2)
1837         (define-key global-map [(control x) tab] \'command-3)
1838
1839 Of course, all of this applies only when running under a window system.  If
1840 you're talking to XEmacs through a TTY connection, you don't get any of
1841 these features.
1842 */
1843        (keymap, keys, def))
1844 {
1845   /* This function can GC */
1846   int idx;
1847   int metized = 0;
1848   int len;
1849   int ascii_hack;
1850   struct gcpro gcpro1, gcpro2, gcpro3;
1851
1852   if (VECTORP (keys))
1853     len = XVECTOR_LENGTH (keys);
1854   else if (STRINGP (keys))
1855     len = XSTRING_CHAR_LENGTH (keys);
1856   else if (CHAR_OR_CHAR_INTP (keys) || SYMBOLP (keys) || CONSP (keys))
1857     {
1858       if (!CONSP (keys)) keys = list1 (keys);
1859       len = 1;
1860       keys = make_vector (1, keys); /* this is kinda sleazy. */
1861     }
1862   else
1863     {
1864       keys = wrong_type_argument (Qsequencep, keys);
1865       len = XINT (Flength (keys));
1866     }
1867   if (len == 0)
1868     return Qnil;
1869
1870   GCPRO3 (keymap, keys, def);
1871
1872   /* ASCII grunge.
1873      When the user defines a key which, in a strictly ASCII world, would be
1874      produced by two different keys (^J and linefeed, or ^H and backspace,
1875      for example) then the binding will be made for both keysyms.
1876
1877      This is done if the user binds a command to a string, as in
1878      (define-key map "\^H" 'something), but not when using one of the new
1879      syntaxes, like (define-key map '(control h) 'something).
1880      */
1881   ascii_hack = (STRINGP (keys));
1882
1883   keymap = get_keymap (keymap, 1, 1);
1884
1885   idx = 0;
1886   while (1)
1887     {
1888       Lisp_Object c;
1889       struct key_data raw_key1;
1890       struct key_data raw_key2;
1891
1892       if (STRINGP (keys))
1893         c = make_char (string_char (XSTRING (keys), idx));
1894       else
1895         c = XVECTOR_DATA (keys) [idx];
1896
1897       define_key_parser (c, &raw_key1);
1898
1899       if (!metized && ascii_hack && meta_prefix_char_p (&raw_key1))
1900         {
1901           if (idx == (len - 1))
1902             {
1903               /* This is a hack to prevent a binding for the meta-prefix-char
1904                  from being made in a map which already has a non-empty "meta"
1905                  submap.  That is, we can't let both "escape" and "meta" have
1906                  a binding in the same keymap.  This implies that the idiom
1907                  (define-key my-map "\e" my-escape-map)
1908                  (define-key my-escape-map "a" 'my-command)
1909                  no longer works.  That's ok.  Instead the luser should do
1910                  (define-key my-map "\ea" 'my-command)
1911                  or, more correctly
1912                  (define-key my-map "\M-a" 'my-command)
1913                  and then perhaps
1914                  (defvar my-escape-map (lookup-key my-map "\e"))
1915                  if the luser really wants the map in a variable.
1916                  */
1917               Lisp_Object meta_map;
1918               struct gcpro ngcpro1;
1919
1920               NGCPRO1 (c);
1921               meta_map = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META),
1922                                    XKEYMAP (keymap)->table, Qnil);
1923               if (!NILP (meta_map)
1924                   && keymap_fullness (meta_map) != 0)
1925                 signal_simple_error_2
1926                   ("Map contains meta-bindings, can't bind",
1927                    Fsingle_key_description (Vmeta_prefix_char), keymap);
1928               NUNGCPRO;
1929             }
1930           else
1931             {
1932               metized = 1;
1933               idx++;
1934               continue;
1935             }
1936         }
1937
1938       if (ascii_hack)
1939         define_key_alternate_name (&raw_key1, &raw_key2);
1940       else
1941         {
1942           raw_key2.keysym = Qnil;
1943           raw_key2.modifiers = 0;
1944         }
1945
1946       if (metized)
1947         {
1948           raw_key1.modifiers |= XEMACS_MOD_META;
1949           raw_key2.modifiers |= XEMACS_MOD_META;
1950           metized = 0;
1951         }
1952
1953       /* This crap is to make sure that someone doesn't bind something like
1954          "C-x M-a" while "C-x ESC" has a non-keymap binding. */
1955       if (raw_key1.modifiers & XEMACS_MOD_META)
1956         ensure_meta_prefix_char_keymapp (keys, idx, keymap);
1957
1958       if (++idx == len)
1959         {
1960           keymap_store (keymap, &raw_key1, def);
1961           if (ascii_hack && !NILP (raw_key2.keysym))
1962             keymap_store (keymap, &raw_key2, def);
1963           UNGCPRO;
1964           return def;
1965         }
1966
1967       {
1968         Lisp_Object cmd;
1969         struct gcpro ngcpro1;
1970         NGCPRO1 (c);
1971
1972         cmd = keymap_lookup_1 (keymap, &raw_key1, 0);
1973         if (NILP (cmd))
1974           {
1975             cmd = Fmake_sparse_keymap (Qnil);
1976             XKEYMAP (cmd)->name /* for debugging */
1977               = list2 (make_key_description (&raw_key1, 1), keymap);
1978             keymap_store (keymap, &raw_key1, cmd);
1979           }
1980         if (NILP (Fkeymapp (cmd)))
1981           signal_simple_error_2 ("Invalid prefix keys in sequence",
1982                                  c, keys);
1983
1984         if (ascii_hack && !NILP (raw_key2.keysym) &&
1985             NILP (keymap_lookup_1 (keymap, &raw_key2, 0)))
1986           keymap_store (keymap, &raw_key2, cmd);
1987
1988         keymap = get_keymap (cmd, 1, 1);
1989         NUNGCPRO;
1990       }
1991     }
1992 }
1993
1994 \f
1995 /************************************************************************/
1996 /*                      Looking up keys in keymaps                      */
1997 /************************************************************************/
1998
1999 /* We need a very fast (i.e., non-consing) version of lookup-key in order
2000    to make where-is-internal really fly. */
2001
2002 struct raw_lookup_key_mapper_closure
2003 {
2004   int remaining;
2005   const struct key_data *raw_keys;
2006   int raw_keys_count;
2007   int keys_so_far;
2008   int accept_default;
2009 };
2010
2011 static Lisp_Object raw_lookup_key_mapper (Lisp_Object k, void *);
2012
2013 /* Caller should gc-protect args (keymaps may autoload) */
2014 static Lisp_Object
2015 raw_lookup_key (Lisp_Object keymap,
2016                 const struct key_data *raw_keys, int raw_keys_count,
2017                 int keys_so_far, int accept_default)
2018 {
2019   /* This function can GC */
2020   struct raw_lookup_key_mapper_closure c;
2021   c.remaining = raw_keys_count - 1;
2022   c.raw_keys = raw_keys;
2023   c.raw_keys_count = raw_keys_count;
2024   c.keys_so_far = keys_so_far;
2025   c.accept_default = accept_default;
2026
2027   return traverse_keymaps (keymap, Qnil, raw_lookup_key_mapper, &c);
2028 }
2029
2030 static Lisp_Object
2031 raw_lookup_key_mapper (Lisp_Object k, void *arg)
2032 {
2033   /* This function can GC */
2034   struct raw_lookup_key_mapper_closure *c =
2035     (struct raw_lookup_key_mapper_closure *) arg;
2036   int accept_default = c->accept_default;
2037   int remaining = c->remaining;
2038   int keys_so_far = c->keys_so_far;
2039   const struct key_data *raw_keys = c->raw_keys;
2040   Lisp_Object cmd;
2041
2042   if (! meta_prefix_char_p (&(raw_keys[0])))
2043     {
2044       /* Normal case: every case except the meta-hack (see below). */
2045       cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default);
2046
2047       if (remaining == 0)
2048         /* Return whatever we found if we're out of keys */
2049         ;
2050       else if (NILP (cmd))
2051         /* Found nothing (though perhaps parent map may have binding) */
2052         ;
2053       else if (NILP (Fkeymapp (cmd)))
2054         /* Didn't find a keymap, and we have more keys.
2055          * Return a fixnum to indicate that keys were too long.
2056          */
2057         cmd = make_int (keys_so_far + 1);
2058       else
2059         cmd = raw_lookup_key (cmd, raw_keys + 1, remaining,
2060                               keys_so_far + 1, accept_default);
2061     }
2062   else
2063     {
2064       /* This is a hack so that looking up a key-sequence whose last
2065        * element is the meta-prefix-char will return the keymap that
2066        * the "meta" keys are stored in, if there is no binding for
2067        * the meta-prefix-char (and if this map has a "meta" submap).
2068        * If this map doesn't have a "meta" submap, then the
2069        * meta-prefix-char is looked up just like any other key.
2070        */
2071       if (remaining == 0)
2072         {
2073           /* First look for the prefix-char directly */
2074           cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default);
2075           if (NILP (cmd))
2076             {
2077               /* Do kludgy return of the meta-map */
2078               cmd = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META),
2079                               XKEYMAP (k)->table, Qnil);
2080             }
2081         }
2082       else
2083         {
2084           /* Search for the prefix-char-prefixed sequence directly */
2085           cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default);
2086           cmd = get_keymap (cmd, 0, 1);
2087           if (!NILP (cmd))
2088             cmd = raw_lookup_key (cmd, raw_keys + 1, remaining,
2089                                   keys_so_far + 1, accept_default);
2090           else if ((raw_keys[1].modifiers & XEMACS_MOD_META) == 0)
2091             {
2092               struct key_data metified;
2093               metified.keysym = raw_keys[1].keysym;
2094               metified.modifiers = raw_keys[1].modifiers |
2095                 (unsigned char) XEMACS_MOD_META;
2096
2097               /* Search for meta-next-char sequence directly */
2098               cmd = keymap_lookup_1 (k, &metified, accept_default);
2099               if (remaining == 1)
2100                 ;
2101               else
2102                 {
2103                   cmd = get_keymap (cmd, 0, 1);
2104                   if (!NILP (cmd))
2105                     cmd = raw_lookup_key (cmd, raw_keys + 2, remaining - 1,
2106                                           keys_so_far + 2,
2107                                           accept_default);
2108                 }
2109             }
2110         }
2111     }
2112   if (accept_default && NILP (cmd))
2113     cmd = XKEYMAP (k)->default_binding;
2114   return cmd;
2115 }
2116
2117 /* Value is number if `keys' is too long; NIL if valid but has no definition.*/
2118 /* Caller should gc-protect arguments */
2119 static Lisp_Object
2120 lookup_keys (Lisp_Object keymap, int nkeys, Lisp_Object *keys,
2121              int accept_default)
2122 {
2123   /* This function can GC */
2124   struct key_data kkk[20];
2125   struct key_data *raw_keys;
2126   int i;
2127
2128   if (nkeys == 0)
2129     return Qnil;
2130
2131   if (nkeys < countof (kkk))
2132     raw_keys = kkk;
2133   else
2134     raw_keys = alloca_array (struct key_data, nkeys);
2135
2136   for (i = 0; i < nkeys; i++)
2137     {
2138       define_key_parser (keys[i], &(raw_keys[i]));
2139     }
2140   return raw_lookup_key (keymap, raw_keys, nkeys, 0, accept_default);
2141 }
2142
2143 static Lisp_Object
2144 lookup_events (Lisp_Object event_head, int nmaps, Lisp_Object keymaps[],
2145                int accept_default)
2146 {
2147   /* This function can GC */
2148   struct key_data kkk[20];
2149   Lisp_Object event;
2150
2151   int nkeys;
2152   struct key_data *raw_keys;
2153   Lisp_Object tem = Qnil;
2154   struct gcpro gcpro1, gcpro2;
2155   int iii;
2156
2157   CHECK_LIVE_EVENT (event_head);
2158
2159   nkeys = event_chain_count (event_head);
2160
2161   if (nkeys < countof (kkk))
2162     raw_keys = kkk;
2163   else
2164     raw_keys = alloca_array (struct key_data, nkeys);
2165
2166   nkeys = 0;
2167   EVENT_CHAIN_LOOP (event, event_head)
2168     define_key_parser (event, &(raw_keys[nkeys++]));
2169   GCPRO2 (keymaps[0], event_head);
2170   gcpro1.nvars = nmaps;
2171   /* ####raw_keys[].keysym slots aren't gc-protected.  We rely (but shouldn't)
2172    * on somebody else somewhere (obarray) having a pointer to all keysyms. */
2173   for (iii = 0; iii < nmaps; iii++)
2174     {
2175       tem = raw_lookup_key (keymaps[iii], raw_keys, nkeys, 0,
2176                             accept_default);
2177       if (INTP (tem))
2178         {
2179           /* Too long in some local map means don't look at global map */
2180           tem = Qnil;
2181           break;
2182         }
2183       else if (!NILP (tem))
2184         break;
2185     }
2186   UNGCPRO;
2187   return tem;
2188 }
2189
2190 DEFUN ("lookup-key", Flookup_key, 2, 3, 0, /*
2191 In keymap KEYMAP, look up key-sequence KEYS.  Return the definition.
2192 Nil is returned if KEYS is unbound.  See documentation of `define-key'
2193 for valid key definitions and key-sequence specifications.
2194 A number is returned if KEYS is "too long"; that is, the leading
2195 characters fail to be a valid sequence of prefix characters in KEYMAP.
2196 The number is how many key strokes at the front of KEYS it takes to
2197 reach a non-prefix command.
2198 */
2199        (keymap, keys, accept_default))
2200 {
2201   /* This function can GC */
2202   if (VECTORP (keys))
2203     return lookup_keys (keymap,
2204                         XVECTOR_LENGTH (keys),
2205                         XVECTOR_DATA (keys),
2206                         !NILP (accept_default));
2207   else if (SYMBOLP (keys) || CHAR_OR_CHAR_INTP (keys) || CONSP (keys))
2208     return lookup_keys (keymap, 1, &keys, !NILP (accept_default));
2209   else if (STRINGP (keys))
2210     {
2211       int length = XSTRING_CHAR_LENGTH (keys);
2212       int i;
2213       struct key_data *raw_keys = alloca_array (struct key_data, length);
2214       if (length == 0)
2215         return Qnil;
2216
2217       for (i = 0; i < length; i++)
2218         {
2219           Emchar n = string_char (XSTRING (keys), i);
2220           define_key_parser (make_char (n), &(raw_keys[i]));
2221         }
2222       return raw_lookup_key (keymap, raw_keys, length, 0,
2223                              !NILP (accept_default));
2224     }
2225   else
2226     {
2227       keys = wrong_type_argument (Qsequencep, keys);
2228       return Flookup_key (keymap, keys, accept_default);
2229     }
2230 }
2231
2232 /* Given a key sequence, returns a list of keymaps to search for bindings.
2233    Does all manner of semi-hairy heuristics, like looking in the current
2234    buffer's map before looking in the global map and looking in the local
2235    map of the buffer in which the mouse was clicked in event0 is a click.
2236
2237    It would be kind of nice if this were in Lisp so that this semi-hairy
2238    semi-heuristic command-lookup behavior could be readily understood and
2239    customised.  However, this needs to be pretty fast, or performance of
2240    keyboard macros goes to shit; putting this in lisp slows macros down
2241    2-3x.  And they're already slower than v18 by 5-6x.
2242  */
2243
2244 struct relevant_maps
2245   {
2246     int nmaps;
2247     unsigned int max_maps;
2248     Lisp_Object *maps;
2249     struct gcpro *gcpro;
2250   };
2251
2252 static void get_relevant_extent_keymaps (Lisp_Object pos,
2253                                          Lisp_Object buffer_or_string,
2254                                          Lisp_Object glyph,
2255                                          struct relevant_maps *closure);
2256 static void get_relevant_minor_maps (Lisp_Object buffer,
2257                                      struct relevant_maps *closure);
2258
2259 static void
2260 relevant_map_push (Lisp_Object map, struct relevant_maps *closure)
2261 {
2262   unsigned int nmaps = closure->nmaps;
2263
2264   if (!KEYMAPP (map))
2265     return;
2266   closure->nmaps = nmaps + 1;
2267   if (nmaps < closure->max_maps)
2268     {
2269       closure->maps[nmaps] = map;
2270       closure->gcpro->nvars = nmaps;
2271     }
2272 }
2273
2274 static int
2275 get_relevant_keymaps (Lisp_Object keys,
2276                       int max_maps, Lisp_Object maps[])
2277 {
2278   /* This function can GC */
2279   Lisp_Object terminal = Qnil;
2280   struct gcpro gcpro1;
2281   struct relevant_maps closure;
2282   struct console *con;
2283
2284   GCPRO1 (*maps);
2285   gcpro1.nvars = 0;
2286   closure.nmaps = 0;
2287   closure.max_maps = max_maps;
2288   closure.maps = maps;
2289   closure.gcpro = &gcpro1;
2290
2291   if (EVENTP (keys))
2292     terminal = event_chain_tail (keys);
2293   else if (VECTORP (keys))
2294     {
2295       int len = XVECTOR_LENGTH (keys);
2296       if (len > 0)
2297         terminal = XVECTOR_DATA (keys)[len - 1];
2298     }
2299
2300   if (EVENTP (terminal))
2301     {
2302       CHECK_LIVE_EVENT (terminal);
2303       con = event_console_or_selected (terminal);
2304     }
2305   else
2306     con = XCONSOLE (Vselected_console);
2307
2308   if (KEYMAPP (con->overriding_terminal_local_map)
2309       || KEYMAPP (Voverriding_local_map))
2310     {
2311       if (KEYMAPP (con->overriding_terminal_local_map))
2312         relevant_map_push (con->overriding_terminal_local_map, &closure);
2313       if (KEYMAPP (Voverriding_local_map))
2314         relevant_map_push (Voverriding_local_map, &closure);
2315     }
2316   else if (!EVENTP (terminal)
2317            || (XEVENT (terminal)->event_type != button_press_event
2318                && XEVENT (terminal)->event_type != button_release_event))
2319     {
2320       Lisp_Object tem;
2321       XSETBUFFER (tem, current_buffer);
2322       /* It's not a mouse event; order of keymaps searched is:
2323          o  keymap of any/all extents under the mouse
2324          o  minor-mode maps
2325          o  local-map of current-buffer
2326          o  global-map
2327          */
2328       /* The terminal element of the lookup may be nil or a keysym.
2329          In those cases we don't want to check for an extent
2330          keymap. */
2331       if (EVENTP (terminal))
2332         {
2333           get_relevant_extent_keymaps (make_int (BUF_PT (current_buffer)),
2334                                        tem, Qnil, &closure);
2335         }
2336       get_relevant_minor_maps (tem, &closure);
2337
2338       tem = current_buffer->keymap;
2339       if (!NILP (tem))
2340         relevant_map_push (tem, &closure);
2341     }
2342 #ifdef HAVE_WINDOW_SYSTEM
2343   else
2344     {
2345       /* It's a mouse event; order of keymaps searched is:
2346          o  vertical-divider-map, if event is over a divider
2347          o  local-map of mouse-grabbed-buffer
2348          o  keymap of any/all extents under the mouse
2349          if the mouse is over a modeline:
2350          o  modeline-map of buffer corresponding to that modeline
2351          o  else, local-map of buffer under the mouse
2352          o  minor-mode maps
2353          o  local-map of current-buffer
2354          o  global-map
2355          */
2356       Lisp_Object window = Fevent_window (terminal);
2357
2358       if (!NILP (Fevent_over_vertical_divider_p (terminal)))
2359         {
2360           if (KEYMAPP (Vvertical_divider_map))
2361             relevant_map_push (Vvertical_divider_map, &closure);
2362         }
2363
2364       if (BUFFERP (Vmouse_grabbed_buffer))
2365         {
2366           Lisp_Object map = XBUFFER (Vmouse_grabbed_buffer)->keymap;
2367
2368           get_relevant_minor_maps (Vmouse_grabbed_buffer, &closure);
2369           if (!NILP (map))
2370             relevant_map_push (map, &closure);
2371         }
2372
2373       if (!NILP (window))
2374         {
2375           Lisp_Object buffer = Fwindow_buffer (window);
2376
2377           if (!NILP (buffer))
2378             {
2379               if (!NILP (Fevent_over_modeline_p (terminal)))
2380                 {
2381                   Lisp_Object map = symbol_value_in_buffer (Qmodeline_map,
2382                                                             buffer);
2383
2384                   get_relevant_extent_keymaps
2385                     (Fevent_modeline_position (terminal),
2386                      XBUFFER (buffer)->generated_modeline_string,
2387                      Fevent_glyph_extent (terminal), &closure);
2388
2389                   if (!UNBOUNDP (map) && !NILP (map))
2390                     relevant_map_push (get_keymap (map, 1, 1), &closure);
2391                 }
2392               else
2393                 {
2394                   get_relevant_extent_keymaps (Fevent_point (terminal), buffer,
2395                                                Fevent_glyph_extent (terminal),
2396                                                &closure);
2397                 }
2398
2399               if (!EQ (buffer, Vmouse_grabbed_buffer)) /* already pushed */
2400                 {
2401                   Lisp_Object map = XBUFFER (buffer)->keymap;
2402
2403                   get_relevant_minor_maps (buffer, &closure);
2404                   if (!NILP(map))
2405                     relevant_map_push (map, &closure);
2406                 }
2407             }
2408         }
2409       else if (!NILP (Fevent_over_toolbar_p (terminal)))
2410         {
2411           Lisp_Object map = Fsymbol_value (Qtoolbar_map);
2412
2413           if (!UNBOUNDP (map) && !NILP (map))
2414             relevant_map_push (map, &closure);
2415         }
2416     }
2417 #endif /* HAVE_WINDOW_SYSTEM */
2418
2419   {
2420     int nmaps = closure.nmaps;
2421     /* Silently truncate at 100 keymaps to prevent infinite lossage */
2422     if (nmaps >= max_maps && max_maps > 0)
2423       maps[max_maps - 1] = Vcurrent_global_map;
2424     else
2425       maps[nmaps] = Vcurrent_global_map;
2426     UNGCPRO;
2427     return nmaps + 1;
2428   }
2429 }
2430
2431 /* Returns a set of keymaps extracted from the extents at POS in
2432    BUFFER_OR_STRING.  The GLYPH arg, if specified, is one more extent
2433    to look for a keymap in, and if it has one, its keymap will be the
2434    first element in the list returned.  This is so we can correctly
2435    search the keymaps associated with glyphs which may be physically
2436    disjoint from their extents: for example, if a glyph is out in the
2437    margin, we should still consult the keymap of that glyph's extent,
2438    which may not itself be under the mouse.
2439  */
2440
2441 static void
2442 get_relevant_extent_keymaps (Lisp_Object pos, Lisp_Object buffer_or_string,
2443                              Lisp_Object glyph,
2444                              struct relevant_maps *closure)
2445 {
2446   /* This function can GC */
2447   /* the glyph keymap, if any, comes first.
2448      (Processing it twice is no big deal: noop.) */
2449   if (!NILP (glyph))
2450     {
2451       Lisp_Object keymap = Fextent_property (glyph, Qkeymap, Qnil);
2452       if (!NILP (keymap))
2453         relevant_map_push (get_keymap (keymap, 1, 1), closure);
2454     }
2455
2456   /* Next check the extents at the text position, if any */
2457   if (!NILP (pos))
2458     {
2459       Lisp_Object extent;
2460       for (extent = Fextent_at (pos, buffer_or_string, Qkeymap, Qnil, Qnil);
2461            !NILP (extent);
2462            extent = Fextent_at (pos, buffer_or_string, Qkeymap, extent, Qnil))
2463         {
2464           Lisp_Object keymap = Fextent_property (extent, Qkeymap, Qnil);
2465           if (!NILP (keymap))
2466             relevant_map_push (get_keymap (keymap, 1, 1), closure);
2467           QUIT;
2468         }
2469     }
2470 }
2471
2472 static Lisp_Object
2473 minor_mode_keymap_predicate (Lisp_Object assoc, Lisp_Object buffer)
2474 {
2475   /* This function can GC */
2476   if (CONSP (assoc))
2477     {
2478       Lisp_Object sym = XCAR (assoc);
2479       if (SYMBOLP (sym))
2480         {
2481           Lisp_Object val = symbol_value_in_buffer (sym, buffer);
2482           if (!NILP (val) && !UNBOUNDP (val))
2483             {
2484               Lisp_Object map = get_keymap (XCDR (assoc), 0, 1);
2485               return map;
2486             }
2487         }
2488     }
2489   return Qnil;
2490 }
2491
2492 static void
2493 get_relevant_minor_maps (Lisp_Object buffer, struct relevant_maps *closure)
2494 {
2495   /* This function can GC */
2496   Lisp_Object alist;
2497
2498   /* Will you ever lose badly if you make this circular! */
2499   for (alist = symbol_value_in_buffer (Qminor_mode_map_alist, buffer);
2500        CONSP (alist);
2501        alist = XCDR (alist))
2502     {
2503       Lisp_Object m = minor_mode_keymap_predicate (XCAR (alist),
2504                                                    buffer);
2505       if (!NILP (m)) relevant_map_push (m, closure);
2506       QUIT;
2507     }
2508 }
2509
2510 /* #### Would map-current-keymaps be a better thing?? */
2511 DEFUN ("current-keymaps", Fcurrent_keymaps, 0, 1, 0, /*
2512 Return a list of the current keymaps that will be searched for bindings.
2513 This lists keymaps such as the current local map and the minor-mode maps,
2514  but does not list the parents of those keymaps.
2515 EVENT-OR-KEYS controls which keymaps will be listed.
2516 If EVENT-OR-KEYS is a mouse event (or a vector whose last element is a
2517  mouse event), the keymaps for that mouse event will be listed (see
2518  `key-binding').  Otherwise, the keymaps for key presses will be listed.
2519 */
2520        (event_or_keys))
2521 {
2522   /* This function can GC */
2523   struct gcpro gcpro1;
2524   Lisp_Object maps[100];
2525   Lisp_Object *gubbish = maps;
2526   int nmaps;
2527
2528   GCPRO1 (event_or_keys);
2529   nmaps = get_relevant_keymaps (event_or_keys, countof (maps),
2530                                 gubbish);
2531   if (nmaps > countof (maps))
2532     {
2533       gubbish = alloca_array (Lisp_Object, nmaps);
2534       nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish);
2535     }
2536   UNGCPRO;
2537   return Flist (nmaps, gubbish);
2538 }
2539
2540 DEFUN ("key-binding", Fkey_binding, 1, 2, 0, /*
2541 Return the binding for command KEYS in current keymaps.
2542 KEYS is a string, a vector of events, or a vector of key-description lists
2543 as described in the documentation for the `define-key' function.
2544 The binding is probably a symbol with a function definition; see
2545 the documentation for `lookup-key' for more information.
2546
2547 For key-presses, the order of keymaps searched is:
2548   - the `keymap' property of any extent(s) at point;
2549   - any applicable minor-mode maps;
2550   - the current local map of the current-buffer;
2551   - the current global map.
2552
2553 For mouse-clicks, the order of keymaps searched is:
2554   - the current-local-map of the `mouse-grabbed-buffer' if any;
2555   - vertical-divider-map, if the event happened over a vertical divider
2556   - the `keymap' property of any extent(s) at the position of the click
2557     (this includes modeline extents);
2558   - the modeline-map of the buffer corresponding to the modeline under
2559     the mouse (if the click happened over a modeline);
2560   - the value of `toolbar-map' in the current-buffer (if the click
2561     happened over a toolbar);
2562   - the current local map of the buffer under the mouse (does not
2563     apply to toolbar clicks);
2564   - any applicable minor-mode maps;
2565   - the current global map.
2566
2567 Note that if `overriding-local-map' or `overriding-terminal-local-map'
2568 is non-nil, *only* those two maps and the current global map are searched.
2569 */
2570        (keys, accept_default))
2571 {
2572   /* This function can GC */
2573   int i;
2574   Lisp_Object maps[100];
2575   int nmaps;
2576   struct gcpro gcpro1, gcpro2;
2577   GCPRO2 (keys, accept_default); /* get_relevant_keymaps may autoload */
2578
2579   nmaps = get_relevant_keymaps (keys, countof (maps), maps);
2580
2581   UNGCPRO;
2582
2583   if (EVENTP (keys))           /* unadvertised "feature" for the future */
2584     return lookup_events (keys, nmaps, maps, !NILP (accept_default));
2585
2586   for (i = 0; i < nmaps; i++)
2587     {
2588       Lisp_Object tem = Flookup_key (maps[i], keys,
2589                                      accept_default);
2590       if (INTP (tem))
2591         {
2592           /* Too long in some local map means don't look at global map */
2593           return Qnil;
2594         }
2595       else if (!NILP (tem))
2596         return tem;
2597     }
2598   return Qnil;
2599 }
2600
2601 static Lisp_Object
2602 process_event_binding_result (Lisp_Object result)
2603 {
2604   if (EQ (result, Qundefined))
2605     /* The suppress-keymap function binds keys to 'undefined - special-case
2606        that here, so that being bound to that has the same error-behavior as
2607        not being defined at all.
2608        */
2609     result = Qnil;
2610   if (!NILP (result))
2611     {
2612       Lisp_Object map;
2613       /* Snap out possible keymap indirections */
2614       map = get_keymap (result, 0, 1);
2615       if (!NILP (map))
2616         result = map;
2617     }
2618
2619   return result;
2620 }
2621
2622 /* Attempts to find a command corresponding to the event-sequence
2623    whose head is event0 (sequence is threaded though event_next).
2624
2625    The return value will be
2626
2627       -- nil (there is no binding; this will also be returned
2628               whenever the event chain is "too long", i.e. there
2629               is a non-nil, non-keymap binding for a prefix of
2630               the event chain)
2631       -- a keymap (part of a command has been specified)
2632       -- a command (anything that satisfies `commandp'; this includes
2633                     some symbols, lists, subrs, strings, vectors, and
2634                     compiled-function objects) */
2635 Lisp_Object
2636 event_binding (Lisp_Object event0, int accept_default)
2637 {
2638   /* This function can GC */
2639   Lisp_Object maps[100];
2640   int nmaps;
2641
2642   assert (EVENTP (event0));
2643
2644   nmaps = get_relevant_keymaps (event0, countof (maps), maps);
2645   if (nmaps > countof (maps))
2646     nmaps = countof (maps);
2647   return process_event_binding_result (lookup_events (event0, nmaps, maps,
2648                                                       accept_default));
2649 }
2650
2651 /* like event_binding, but specify a keymap to search */
2652
2653 Lisp_Object
2654 event_binding_in (Lisp_Object event0, Lisp_Object keymap, int accept_default)
2655 {
2656   /* This function can GC */
2657   if (!KEYMAPP (keymap))
2658     return Qnil;
2659
2660   return process_event_binding_result (lookup_events (event0, 1, &keymap,
2661                                                       accept_default));
2662 }
2663
2664 /* Attempts to find a function key mapping corresponding to the
2665    event-sequence whose head is event0 (sequence is threaded through
2666    event_next).  The return value will be the same as for event_binding(). */
2667 Lisp_Object
2668 munging_key_map_event_binding (Lisp_Object event0,
2669                                enum munge_me_out_the_door munge)
2670 {
2671   Lisp_Object keymap = (munge == MUNGE_ME_FUNCTION_KEY) ?
2672     CONSOLE_FUNCTION_KEY_MAP (event_console_or_selected (event0)) :
2673     Vkey_translation_map;
2674
2675   if (NILP (keymap))
2676     return Qnil;
2677
2678   return process_event_binding_result (lookup_events (event0, 1, &keymap, 1));
2679 }
2680
2681 \f
2682 /************************************************************************/
2683 /*               Setting/querying the global and local maps             */
2684 /************************************************************************/
2685
2686 DEFUN ("use-global-map", Fuse_global_map, 1, 1, 0, /*
2687 Select KEYMAP as the global keymap.
2688 */
2689        (keymap))
2690 {
2691   /* This function can GC */
2692   keymap = get_keymap (keymap, 1, 1);
2693   Vcurrent_global_map = keymap;
2694   return Qnil;
2695 }
2696
2697 DEFUN ("use-local-map", Fuse_local_map, 1, 2, 0, /*
2698 Select KEYMAP as the local keymap in BUFFER.
2699 If KEYMAP is nil, that means no local keymap.
2700 If BUFFER is nil, the current buffer is assumed.
2701 */
2702        (keymap, buffer))
2703 {
2704   /* This function can GC */
2705   struct buffer *b = decode_buffer (buffer, 0);
2706   if (!NILP (keymap))
2707     keymap = get_keymap (keymap, 1, 1);
2708
2709   b->keymap = keymap;
2710
2711   return Qnil;
2712 }
2713
2714 DEFUN ("current-local-map", Fcurrent_local_map, 0, 1, 0, /*
2715 Return BUFFER's local keymap, or nil if it has none.
2716 If BUFFER is nil, the current buffer is assumed.
2717 */
2718        (buffer))
2719 {
2720   struct buffer *b = decode_buffer (buffer, 0);
2721   return b->keymap;
2722 }
2723
2724 DEFUN ("current-global-map", Fcurrent_global_map, 0, 0, 0, /*
2725 Return the current global keymap.
2726 */
2727        ())
2728 {
2729   return Vcurrent_global_map;
2730 }
2731
2732 \f
2733 /************************************************************************/
2734 /*                    Mapping over keymap elements                      */
2735 /************************************************************************/
2736
2737 /* Since keymaps are arranged in a hierarchy, one keymap per bucky bit or
2738    prefix key, it's not entirely obvious what map-keymap should do, but
2739    what it does is: map over all keys in this map; then recursively map
2740    over all submaps of this map that are "bucky" submaps.  This means that,
2741    when mapping over a keymap, it appears that "x" and "C-x" are in the
2742    same map, although "C-x" is really in the "control" submap of this one.
2743    However, since we don't recursively descend the submaps that are bound
2744    to prefix keys (like C-x, C-h, etc) the caller will have to recurse on
2745    those explicitly, if that's what they want.
2746
2747    So the end result of this is that the bucky keymaps (the ones indexed
2748    under the large integers returned from MAKE_MODIFIER_HASH_KEY()) are
2749    invisible from elisp.  They're just an implementation detail that code
2750    outside of this file doesn't need to know about.
2751  */
2752
2753 struct map_keymap_unsorted_closure
2754 {
2755   void (*fn) (const struct key_data *, Lisp_Object binding, void *arg);
2756   void *arg;
2757   int modifiers;
2758 };
2759
2760 /* used by map_keymap() */
2761 static int
2762 map_keymap_unsorted_mapper (Lisp_Object keysym, Lisp_Object value,
2763                             void *map_keymap_unsorted_closure)
2764 {
2765   /* This function can GC */
2766   struct map_keymap_unsorted_closure *closure =
2767     (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure;
2768   int modifiers = closure->modifiers;
2769   int mod_bit;
2770   mod_bit = MODIFIER_HASH_KEY_BITS (keysym);
2771   if (mod_bit != 0)
2772     {
2773       int omod = modifiers;
2774       closure->modifiers = (modifiers | mod_bit);
2775       value = get_keymap (value, 1, 0);
2776       elisp_maphash (map_keymap_unsorted_mapper,
2777                      XKEYMAP (value)->table,
2778                      map_keymap_unsorted_closure);
2779       closure->modifiers = omod;
2780     }
2781   else
2782     {
2783       struct key_data key;
2784       key.keysym = keysym;
2785       key.modifiers = modifiers;
2786       ((*closure->fn) (&key, value, closure->arg));
2787     }
2788   return 0;
2789 }
2790
2791
2792 struct map_keymap_sorted_closure
2793 {
2794   Lisp_Object *result_locative;
2795 };
2796
2797 /* used by map_keymap_sorted() */
2798 static int
2799 map_keymap_sorted_mapper (Lisp_Object key, Lisp_Object value,
2800                           void *map_keymap_sorted_closure)
2801 {
2802   struct map_keymap_sorted_closure *cl =
2803     (struct map_keymap_sorted_closure *) map_keymap_sorted_closure;
2804   Lisp_Object *list = cl->result_locative;
2805   *list = Fcons (Fcons (key, value), *list);
2806   return 0;
2807 }
2808
2809
2810 /* used by map_keymap_sorted(), describe_map_sort_predicate(),
2811    and keymap_submaps().
2812  */
2813 static int
2814 map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
2815                            Lisp_Object pred)
2816 {
2817   /* obj1 and obj2 are conses with keysyms in their cars.  Cdrs are ignored.
2818    */
2819   int bit1, bit2;
2820   int sym1_p = 0;
2821   int sym2_p = 0;
2822   obj1 = XCAR (obj1);
2823   obj2 = XCAR (obj2);
2824
2825   if (EQ (obj1, obj2))
2826     return -1;
2827   bit1 = MODIFIER_HASH_KEY_BITS (obj1);
2828   bit2 = MODIFIER_HASH_KEY_BITS (obj2);
2829
2830   /* If either is a symbol with a character-set-property, then sort it by
2831      that code instead of alphabetically.
2832      */
2833   if (! bit1 && SYMBOLP (obj1))
2834     {
2835       Lisp_Object code = Fget (obj1, Vcharacter_set_property, Qnil);
2836       if (CHAR_OR_CHAR_INTP (code))
2837         {
2838           obj1 = code;
2839           CHECK_CHAR_COERCE_INT (obj1);
2840           sym1_p = 1;
2841         }
2842     }
2843   if (! bit2 && SYMBOLP (obj2))
2844     {
2845       Lisp_Object code = Fget (obj2, Vcharacter_set_property, Qnil);
2846       if (CHAR_OR_CHAR_INTP (code))
2847         {
2848           obj2 = code;
2849           CHECK_CHAR_COERCE_INT (obj2);
2850           sym2_p = 1;
2851         }
2852     }
2853
2854   /* all symbols (non-ASCIIs) come after characters (ASCIIs) */
2855   if (XTYPE (obj1) != XTYPE (obj2))
2856     return SYMBOLP (obj2) ? 1 : -1;
2857
2858   if (! bit1 && CHARP (obj1)) /* they're both ASCII */
2859     {
2860       int o1 = XCHAR (obj1);
2861       int o2 = XCHAR (obj2);
2862       if (o1 == o2 &&           /* If one started out as a symbol and the */
2863           sym1_p != sym2_p)     /* other didn't, the symbol comes last. */
2864         return sym2_p ? 1 : -1;
2865
2866       return o1 < o2 ? 1 : -1;  /* else just compare them */
2867     }
2868
2869   /* else they're both symbols.  If they're both buckys, then order them. */
2870   if (bit1 && bit2)
2871     return bit1 < bit2 ? 1 : -1;
2872
2873   /* if only one is a bucky, then it comes later */
2874   if (bit1 || bit2)
2875     return bit2 ? 1 : -1;
2876
2877   /* otherwise, string-sort them. */
2878   {
2879     char *s1 = (char *) string_data (XSYMBOL (obj1)->name);
2880     char *s2 = (char *) string_data (XSYMBOL (obj2)->name);
2881 #ifdef I18N2
2882     return 0 > strcoll (s1, s2) ? 1 : -1;
2883 #else
2884     return 0 > strcmp  (s1, s2) ? 1 : -1;
2885 #endif
2886   }
2887 }
2888
2889
2890 /* used by map_keymap() */
2891 static void
2892 map_keymap_sorted (Lisp_Object keymap_table,
2893                    int modifiers,
2894                    void (*function) (const struct key_data *key,
2895                                      Lisp_Object binding,
2896                                      void *map_keymap_sorted_closure),
2897                    void *map_keymap_sorted_closure)
2898 {
2899   /* This function can GC */
2900   struct gcpro gcpro1;
2901   Lisp_Object contents = Qnil;
2902
2903   if (XINT (Fhash_table_count (keymap_table)) == 0)
2904     return;
2905
2906   GCPRO1 (contents);
2907
2908   {
2909     struct map_keymap_sorted_closure c1;
2910     c1.result_locative = &contents;
2911     elisp_maphash (map_keymap_sorted_mapper, keymap_table, &c1);
2912   }
2913   contents = list_sort (contents, Qnil, map_keymap_sort_predicate);
2914   for (; !NILP (contents); contents = XCDR (contents))
2915     {
2916       Lisp_Object keysym = XCAR (XCAR (contents));
2917       Lisp_Object binding = XCDR (XCAR (contents));
2918       int sub_bits = MODIFIER_HASH_KEY_BITS (keysym);
2919       if (sub_bits != 0)
2920         map_keymap_sorted (XKEYMAP (get_keymap (binding,
2921                                                 1, 1))->table,
2922                            (modifiers | sub_bits),
2923                            function,
2924                            map_keymap_sorted_closure);
2925       else
2926         {
2927           struct key_data k;
2928           k.keysym = keysym;
2929           k.modifiers = modifiers;
2930           ((*function) (&k, binding, map_keymap_sorted_closure));
2931         }
2932     }
2933   UNGCPRO;
2934 }
2935
2936
2937 /* used by Fmap_keymap() */
2938 static void
2939 map_keymap_mapper (const struct key_data *key,
2940                    Lisp_Object binding,
2941                    void *function)
2942 {
2943   /* This function can GC */
2944   Lisp_Object fn;
2945   VOID_TO_LISP (fn, function);
2946   call2 (fn, make_key_description (key, 1), binding);
2947 }
2948
2949
2950 static void
2951 map_keymap (Lisp_Object keymap_table, int sort_first,
2952             void (*function) (const struct key_data *key,
2953                               Lisp_Object binding,
2954                               void *fn_arg),
2955             void *fn_arg)
2956 {
2957   /* This function can GC */
2958   if (sort_first)
2959     map_keymap_sorted (keymap_table, 0, function, fn_arg);
2960   else
2961     {
2962       struct map_keymap_unsorted_closure map_keymap_unsorted_closure;
2963       map_keymap_unsorted_closure.fn = function;
2964       map_keymap_unsorted_closure.arg = fn_arg;
2965       map_keymap_unsorted_closure.modifiers = 0;
2966       elisp_maphash (map_keymap_unsorted_mapper, keymap_table,
2967                      &map_keymap_unsorted_closure);
2968     }
2969 }
2970
2971 DEFUN ("map-keymap", Fmap_keymap, 2, 3, 0, /*
2972 Apply FUNCTION to each element of KEYMAP.
2973 FUNCTION will be called with two arguments: a key-description list, and
2974 the binding.  The order in which the elements of the keymap are passed to
2975 the function is unspecified.  If the function inserts new elements into
2976 the keymap, it may or may not be called with them later.  No element of
2977 the keymap will ever be passed to the function more than once.
2978
2979 The function will not be called on elements of this keymap's parents
2980 \(see the function `keymap-parents') or upon keymaps which are contained
2981 within this keymap (multi-character definitions).
2982 It will be called on "meta" characters since they are not really
2983 two-character sequences.
2984
2985 If the optional third argument SORT-FIRST is non-nil, then the elements of
2986 the keymap will be passed to the mapper function in a canonical order.
2987 Otherwise, they will be passed in hash (that is, random) order, which is
2988 faster.
2989 */
2990      (function, keymap, sort_first))
2991 {
2992   /* This function can GC */
2993   struct gcpro gcpro1, gcpro2;
2994
2995  /* tolerate obviously transposed args */
2996   if (!NILP (Fkeymapp (function)))
2997     {
2998       Lisp_Object tmp = function;
2999       function = keymap;
3000       keymap = tmp;
3001     }
3002   GCPRO2 (function, keymap);
3003   keymap = get_keymap (keymap, 1, 1);
3004   map_keymap (XKEYMAP (keymap)->table, !NILP (sort_first),
3005               map_keymap_mapper, LISP_TO_VOID (function));
3006   UNGCPRO;
3007   return Qnil;
3008 }
3009
3010
3011 \f
3012 /************************************************************************/
3013 /*                          Accessible keymaps                          */
3014 /************************************************************************/
3015
3016 struct accessible_keymaps_closure
3017   {
3018     Lisp_Object tail;
3019   };
3020
3021
3022 static void
3023 accessible_keymaps_mapper_1 (Lisp_Object keysym, Lisp_Object contents,
3024                              int modifiers,
3025                              struct accessible_keymaps_closure *closure)
3026 {
3027   /* This function can GC */
3028   int subbits = MODIFIER_HASH_KEY_BITS (keysym);
3029
3030   if (subbits != 0)
3031     {
3032       Lisp_Object submaps;
3033
3034       contents = get_keymap (contents, 1, 1);
3035       submaps = keymap_submaps (contents);
3036       for (; !NILP (submaps); submaps = XCDR (submaps))
3037         {
3038           accessible_keymaps_mapper_1 (XCAR (XCAR (submaps)),
3039                                        XCDR (XCAR (submaps)),
3040                                        (subbits | modifiers),
3041                                        closure);
3042         }
3043     }
3044   else
3045     {
3046       Lisp_Object thisseq = Fcar (Fcar (closure->tail));
3047       Lisp_Object cmd = get_keyelt (contents, 1);
3048       Lisp_Object vec;
3049       int j;
3050       int len;
3051       struct key_data key;
3052       key.keysym = keysym;
3053       key.modifiers = modifiers;
3054
3055       if (NILP (cmd))
3056         abort ();
3057       cmd = get_keymap (cmd, 0, 1);
3058       if (!KEYMAPP (cmd))
3059         abort ();
3060
3061       vec = make_vector (XVECTOR_LENGTH (thisseq) + 1, Qnil);
3062       len = XVECTOR_LENGTH (thisseq);
3063       for (j = 0; j < len; j++)
3064         XVECTOR_DATA (vec) [j] = XVECTOR_DATA (thisseq) [j];
3065       XVECTOR_DATA (vec) [j] = make_key_description (&key, 1);
3066
3067       nconc2 (closure->tail, list1 (Fcons (vec, cmd)));
3068     }
3069 }
3070
3071
3072 static Lisp_Object
3073 accessible_keymaps_keymap_mapper (Lisp_Object thismap, void *arg)
3074 {
3075   /* This function can GC */
3076   struct accessible_keymaps_closure *closure =
3077     (struct accessible_keymaps_closure *) arg;
3078   Lisp_Object submaps = keymap_submaps (thismap);
3079
3080   for (; !NILP (submaps); submaps = XCDR (submaps))
3081     {
3082       accessible_keymaps_mapper_1 (XCAR (XCAR (submaps)),
3083                                    XCDR (XCAR (submaps)),
3084                                    0,
3085                                    closure);
3086     }
3087   return Qnil;
3088 }
3089
3090
3091 DEFUN ("accessible-keymaps", Faccessible_keymaps, 1, 2, 0, /*
3092 Find all keymaps accessible via prefix characters from KEYMAP.
3093 Returns a list of elements of the form (KEYS . MAP), where the sequence
3094 KEYS starting from KEYMAP gets you to MAP.  These elements are ordered
3095 so that the KEYS increase in length.  The first element is ([] . KEYMAP).
3096 An optional argument PREFIX, if non-nil, should be a key sequence;
3097 then the value includes only maps for prefixes that start with PREFIX.
3098 */
3099        (keymap, prefix))
3100 {
3101   /* This function can GC */
3102   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3103   Lisp_Object accessible_keymaps = Qnil;
3104   struct accessible_keymaps_closure c;
3105   c.tail = Qnil;
3106   GCPRO4 (accessible_keymaps, c.tail, prefix, keymap);
3107
3108   keymap = get_keymap (keymap, 1, 1);
3109
3110  retry:
3111   if (NILP (prefix))
3112     {
3113       prefix = make_vector (0, Qnil);
3114     }
3115   else if (VECTORP (prefix) || STRINGP (prefix))
3116     {
3117       int len = XINT (Flength (prefix));
3118       Lisp_Object def;
3119       Lisp_Object p;
3120       int iii;
3121       struct gcpro ngcpro1;
3122
3123       if (len == 0)
3124         {
3125           prefix = Qnil;
3126           goto retry;
3127         }
3128
3129       def = Flookup_key (keymap, prefix, Qnil);
3130       def = get_keymap (def, 0, 1);
3131       if (!KEYMAPP (def))
3132         goto RETURN;
3133
3134       keymap = def;
3135       p = make_vector (len, Qnil);
3136       NGCPRO1 (p);
3137       for (iii = 0; iii < len; iii++)
3138         {
3139           struct key_data key;
3140           define_key_parser (Faref (prefix, make_int (iii)), &key);
3141           XVECTOR_DATA (p)[iii] = make_key_description (&key, 1);
3142         }
3143       NUNGCPRO;
3144       prefix = p;
3145     }
3146   else
3147     {
3148       prefix = wrong_type_argument (Qarrayp, prefix);
3149       goto retry;
3150     }
3151
3152   accessible_keymaps = list1 (Fcons (prefix, keymap));
3153
3154   /* For each map in the list maps, look at any other maps it points
3155      to and stick them at the end if they are not already in the list */
3156
3157   for (c.tail = accessible_keymaps;
3158        !NILP (c.tail);
3159        c.tail = XCDR (c.tail))
3160     {
3161       Lisp_Object thismap = Fcdr (Fcar (c.tail));
3162       CHECK_KEYMAP (thismap);
3163       traverse_keymaps (thismap, Qnil,
3164                         accessible_keymaps_keymap_mapper, &c);
3165     }
3166  RETURN:
3167   UNGCPRO;
3168   return accessible_keymaps;
3169 }
3170
3171
3172 \f
3173 /************************************************************************/
3174 /*              Pretty descriptions of key sequences                    */
3175 /************************************************************************/
3176
3177 DEFUN ("key-description", Fkey_description, 1, 1, 0, /*
3178 Return a pretty description of key-sequence KEYS.
3179 Control characters turn into "C-foo" sequences, meta into "M-foo",
3180 spaces are put between sequence elements, etc...
3181 */
3182        (keys))
3183 {
3184   if (CHAR_OR_CHAR_INTP (keys) || CONSP (keys) || SYMBOLP (keys)
3185       || EVENTP (keys))
3186     {
3187       return Fsingle_key_description (keys);
3188     }
3189   else if (VECTORP (keys) ||
3190            STRINGP (keys))
3191     {
3192       Lisp_Object string = Qnil;
3193       /* Lisp_Object sep = Qnil; */
3194       int size = XINT (Flength (keys));
3195       int i;
3196
3197       for (i = 0; i < size; i++)
3198         {
3199           Lisp_Object s2 = Fsingle_key_description
3200             (STRINGP (keys)
3201              ? make_char (string_char (XSTRING (keys), i))
3202              : XVECTOR_DATA (keys)[i]);
3203
3204           if (i == 0)
3205             string = s2;
3206           else
3207             {
3208               /* if (NILP (sep)) Lisp_Object sep = build_string (" ") */;
3209               string = concat2 (string, concat2 (Vsingle_space_string, s2));
3210             }
3211         }
3212       return string;
3213     }
3214   return Fkey_description (wrong_type_argument (Qsequencep, keys));
3215 }
3216
3217 DEFUN ("single-key-description", Fsingle_key_description, 1, 1, 0, /*
3218 Return a pretty description of command character KEY.
3219 Control characters turn into C-whatever, etc.
3220 This differs from `text-char-description' in that it returns a description
3221 of a key read from the user rather than a character from a buffer.
3222 */
3223        (key))
3224 {
3225   if (SYMBOLP (key))
3226     key = Fcons (key, Qnil); /* sleaze sleaze */
3227
3228   if (EVENTP (key) || CHAR_OR_CHAR_INTP (key))
3229     {
3230       char buf [255];
3231       if (!EVENTP (key))
3232         {
3233           Lisp_Event event;
3234           event.event_type = empty_event;
3235           CHECK_CHAR_COERCE_INT (key);
3236           character_to_event (XCHAR (key), &event,
3237                               XCONSOLE (Vselected_console), 0, 1);
3238           format_event_object (buf, &event, 1);
3239         }
3240       else
3241         format_event_object (buf, XEVENT (key), 1);
3242       return build_string (buf);
3243     }
3244
3245   if (CONSP (key))
3246     {
3247       char buf[255];
3248       char *bufp = buf;
3249       Lisp_Object rest;
3250       buf[0] = 0;
3251       LIST_LOOP (rest, key)
3252         {
3253           Lisp_Object keysym = XCAR (rest);
3254           if (EQ (keysym, Qcontrol))    strcpy (bufp, "C-"), bufp += 2;
3255           else if (EQ (keysym, Qctrl))  strcpy (bufp, "C-"), bufp += 2;
3256           else if (EQ (keysym, Qmeta))  strcpy (bufp, "M-"), bufp += 2;
3257           else if (EQ (keysym, Qsuper)) strcpy (bufp, "S-"), bufp += 2;
3258           else if (EQ (keysym, Qhyper)) strcpy (bufp, "H-"), bufp += 2;
3259           else if (EQ (keysym, Qalt))   strcpy (bufp, "A-"), bufp += 2;
3260           else if (EQ (keysym, Qshift)) strcpy (bufp, "Sh-"), bufp += 3;
3261           else if (CHAR_OR_CHAR_INTP (keysym))
3262             {
3263               bufp += set_charptr_emchar ((Bufbyte *) bufp,
3264                                           XCHAR_OR_CHAR_INT (keysym));
3265               *bufp = 0;
3266             }
3267           else
3268             {
3269               CHECK_SYMBOL (keysym);
3270 #if 0                           /* This is bogus */
3271               if (EQ (keysym, QKlinefeed))       strcpy (bufp, "LFD");
3272               else if (EQ (keysym, QKtab))       strcpy (bufp, "TAB");
3273               else if (EQ (keysym, QKreturn))    strcpy (bufp, "RET");
3274               else if (EQ (keysym, QKescape))    strcpy (bufp, "ESC");
3275               else if (EQ (keysym, QKdelete))    strcpy (bufp, "DEL");
3276               else if (EQ (keysym, QKspace))     strcpy (bufp, "SPC");
3277               else if (EQ (keysym, QKbackspace)) strcpy (bufp, "BS");
3278               else
3279 #endif
3280                 strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name));
3281               if (!NILP (XCDR (rest)))
3282                 signal_simple_error ("Invalid key description",
3283                                      key);
3284             }
3285         }
3286       return build_string (buf);
3287     }
3288   return Fsingle_key_description
3289     (wrong_type_argument (intern ("char-or-event-p"), key));
3290 }
3291
3292 DEFUN ("text-char-description", Ftext_char_description, 1, 1, 0, /*
3293 Return a pretty description of file-character CHR.
3294 Unprintable characters turn into "^char" or \\NNN, depending on the value
3295 of the `ctl-arrow' variable.
3296 This differs from `single-key-description' in that it returns a description
3297 of a character from a buffer rather than a key read from the user.
3298 */
3299        (chr))
3300 {
3301   Bufbyte buf[200];
3302   Bufbyte *p;
3303   Emchar c;
3304   Lisp_Object ctl_arrow = current_buffer->ctl_arrow;
3305   int ctl_p = !NILP (ctl_arrow);
3306   Emchar printable_min = (CHAR_OR_CHAR_INTP (ctl_arrow)
3307                           ? XCHAR_OR_CHAR_INT (ctl_arrow)
3308                           : ((EQ (ctl_arrow, Qt) || NILP (ctl_arrow))
3309                              ? 256 : 160));
3310
3311   if (EVENTP (chr))
3312     {
3313       Lisp_Object ch = Fevent_to_character (chr, Qnil, Qnil, Qt);
3314       if (NILP (ch))
3315         return
3316           signal_simple_continuable_error
3317             ("character has no ASCII equivalent", Fcopy_event (chr, Qnil));
3318       chr = ch;
3319     }
3320
3321   CHECK_CHAR_COERCE_INT (chr);
3322
3323   c = XCHAR (chr);
3324   p = buf;
3325
3326   if (c >= printable_min)
3327     {
3328       p += set_charptr_emchar (p, c);
3329     }
3330   else if (c < 040 && ctl_p)
3331     {
3332       *p++ = '^';
3333       *p++ = c + 64;            /* 'A' - 1 */
3334     }
3335   else if (c == 0177)
3336     {
3337       *p++ = '^';
3338       *p++ = '?';
3339     }
3340   else if (c >= 0200 || c < 040)
3341     {
3342       *p++ = '\\';
3343 #ifdef MULE
3344       /* !!#### This syntax is not readable.  It will
3345          be interpreted as a 3-digit octal number rather
3346          than a 7-digit octal number. */
3347       if (c >= 0400)
3348         {
3349           *p++ = '0' + ((c & 07000000) >> 18);
3350           *p++ = '0' + ((c & 0700000) >> 15);
3351           *p++ = '0' + ((c & 070000) >> 12);
3352           *p++ = '0' + ((c & 07000) >> 9);
3353         }
3354 #endif
3355       *p++ = '0' + ((c & 0700) >> 6);
3356       *p++ = '0' + ((c & 0070) >> 3);
3357       *p++ = '0' + ((c & 0007));
3358     }
3359   else
3360     {
3361       p += set_charptr_emchar (p, c);
3362     }
3363
3364   *p = 0;
3365   return build_string ((char *) buf);
3366 }
3367
3368 \f
3369 /************************************************************************/
3370 /*              where-is (mapping bindings to keys)                     */
3371 /************************************************************************/
3372
3373 static Lisp_Object
3374 where_is_internal (Lisp_Object definition, Lisp_Object *maps, int nmaps,
3375                    Lisp_Object firstonly, char *target_buffer);
3376
3377 DEFUN ("where-is-internal", Fwhere_is_internal, 1, 5, 0, /*
3378 Return list of keys that invoke DEFINITION in KEYMAPS.
3379 KEYMAPS can be either a keymap (meaning search in that keymap and the
3380 current global keymap) or a list of keymaps (meaning search in exactly
3381 those keymaps and no others).  If KEYMAPS is nil, search in the currently
3382 applicable maps for EVENT-OR-KEYS (this is equivalent to specifying
3383 `(current-keymaps EVENT-OR-KEYS)' as the argument to KEYMAPS).
3384
3385 If optional 3rd arg FIRSTONLY is non-nil, return a vector representing
3386  the first key sequence found, rather than a list of all possible key
3387  sequences.
3388
3389 If optional 4th arg NOINDIRECT is non-nil, don't follow indirections
3390  to other keymaps or slots.  This makes it possible to search for an
3391  indirect definition itself.
3392 */
3393        (definition, keymaps, firstonly, noindirect, event_or_keys))
3394 {
3395   /* This function can GC */
3396   Lisp_Object maps[100];
3397   Lisp_Object *gubbish = maps;
3398   int nmaps;
3399
3400   /* Get keymaps as an array */
3401   if (NILP (keymaps))
3402     {
3403       nmaps = get_relevant_keymaps (event_or_keys, countof (maps),
3404                                     gubbish);
3405       if (nmaps > countof (maps))
3406         {
3407           gubbish = alloca_array (Lisp_Object, nmaps);
3408           nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish);
3409         }
3410     }
3411   else if (CONSP (keymaps))
3412     {
3413       Lisp_Object rest;
3414       int i;
3415
3416       nmaps = XINT (Flength (keymaps));
3417       if (nmaps > countof (maps))
3418         {
3419           gubbish = alloca_array (Lisp_Object, nmaps);
3420         }
3421       for (rest = keymaps, i = 0; !NILP (rest);
3422            rest = XCDR (keymaps), i++)
3423         {
3424           gubbish[i] = get_keymap (XCAR (keymaps), 1, 1);
3425         }
3426     }
3427   else
3428     {
3429       nmaps = 1;
3430       gubbish[0] = get_keymap (keymaps, 1, 1);
3431       if (!EQ (gubbish[0], Vcurrent_global_map))
3432         {
3433           gubbish[1] = Vcurrent_global_map;
3434           nmaps++;
3435         }
3436     }
3437
3438   return where_is_internal (definition, gubbish, nmaps, firstonly, 0);
3439 }
3440
3441 /* This function is like
3442    (key-description (where-is-internal definition nil t))
3443    except that it writes its output into a (char *) buffer that you
3444    provide; it doesn't cons (or allocate memory) at all, so it's
3445    very fast.  This is used by menubar.c.
3446  */
3447 void
3448 where_is_to_char (Lisp_Object definition, char *buffer)
3449 {
3450   /* This function can GC */
3451   Lisp_Object maps[100];
3452   Lisp_Object *gubbish = maps;
3453   int nmaps;
3454
3455   /* Get keymaps as an array */
3456   nmaps = get_relevant_keymaps (Qnil, countof (maps), gubbish);
3457   if (nmaps > countof (maps))
3458     {
3459       gubbish = alloca_array (Lisp_Object, nmaps);
3460       nmaps = get_relevant_keymaps (Qnil, nmaps, gubbish);
3461     }
3462
3463   buffer[0] = 0;
3464   where_is_internal (definition, maps, nmaps, Qt, buffer);
3465 }
3466
3467
3468 static Lisp_Object
3469 raw_keys_to_keys (struct key_data *keys, int count)
3470 {
3471   Lisp_Object result = make_vector (count, Qnil);
3472   while (count--)
3473     XVECTOR_DATA (result) [count] = make_key_description (&(keys[count]), 1);
3474   return result;
3475 }
3476
3477
3478 static void
3479 format_raw_keys (struct key_data *keys, int count, char *buf)
3480 {
3481   int i;
3482   Lisp_Event event;
3483   event.event_type = key_press_event;
3484   event.channel = Vselected_console;
3485   for (i = 0; i < count; i++)
3486     {
3487       event.event.key.keysym    = keys[i].keysym;
3488       event.event.key.modifiers = keys[i].modifiers;
3489       format_event_object (buf, &event, 1);
3490       buf += strlen (buf);
3491       if (i < count-1)
3492         buf[0] = ' ', buf++;
3493     }
3494 }
3495
3496
3497 /* definition is the thing to look for.
3498    map is a keymap.
3499    shadow is an array of shadow_count keymaps; if there is a different
3500    binding in any of the keymaps of a key that we are considering
3501    returning, then we reconsider.
3502    firstonly means give up after finding the first match;
3503    keys_so_far and modifiers_so_far describe which map we're looking in;
3504    If we're in the "meta" submap of the map that "C-x 4" is bound to,
3505    then keys_so_far will be {(control x), \4}, and modifiers_so_far
3506    will be XEMACS_MOD_META.  That is, keys_so_far is the chain of keys that we
3507    have followed, and modifiers_so_far_so_far is the bits (partial keys)
3508    beyond that.
3509
3510    (keys_so_far is a global buffer and the keys_count arg says how much
3511    of it we're currently interested in.)
3512
3513    If target_buffer is provided, then we write a key-description into it,
3514    to avoid consing a string.  This only works with firstonly on.
3515    */
3516
3517 struct where_is_closure
3518   {
3519     Lisp_Object definition;
3520     Lisp_Object *shadow;
3521     int shadow_count;
3522     int firstonly;
3523     int keys_count;
3524     int modifiers_so_far;
3525     char *target_buffer;
3526     struct key_data *keys_so_far;
3527     int keys_so_far_total_size;
3528     int keys_so_far_malloced;
3529   };
3530
3531 static Lisp_Object where_is_recursive_mapper (Lisp_Object map, void *arg);
3532
3533 static Lisp_Object
3534 where_is_recursive_mapper (Lisp_Object map, void *arg)
3535 {
3536   /* This function can GC */
3537   struct where_is_closure *c = (struct where_is_closure *) arg;
3538   Lisp_Object definition = c->definition;
3539   const int firstonly = c->firstonly;
3540   const int keys_count = c->keys_count;
3541   const int modifiers_so_far = c->modifiers_so_far;
3542   char *target_buffer = c->target_buffer;
3543   Lisp_Object keys = Fgethash (definition,
3544                                XKEYMAP (map)->inverse_table,
3545                                Qnil);
3546   Lisp_Object submaps;
3547   Lisp_Object result = Qnil;
3548
3549   if (!NILP (keys))
3550     {
3551       /* One or more keys in this map match the definition we're looking for.
3552          Verify that these bindings aren't shadowed by other bindings
3553          in the shadow maps.  Either nil or number as value from
3554          raw_lookup_key() means undefined.  */
3555       struct key_data *so_far = c->keys_so_far;
3556
3557       for (;;) /* loop over all keys that match */
3558         {
3559           Lisp_Object k = CONSP (keys) ? XCAR (keys) : keys;
3560           int i;
3561
3562           so_far [keys_count].keysym = k;
3563           so_far [keys_count].modifiers = modifiers_so_far;
3564
3565           /* now loop over all shadow maps */
3566           for (i = 0; i < c->shadow_count; i++)
3567             {
3568               Lisp_Object shadowed = raw_lookup_key (c->shadow[i],
3569                                                      so_far,
3570                                                      keys_count + 1,
3571                                                      0, 1);
3572
3573               if (NILP (shadowed) || CHARP (shadowed) ||
3574                   EQ (shadowed, definition))
3575                 continue; /* we passed this test; it's not shadowed here. */
3576               else
3577                 /* ignore this key binding, since it actually has a
3578                    different binding in a shadowing map */
3579                 goto c_doesnt_have_proper_loop_exit_statements;
3580             }
3581
3582           /* OK, the key is for real */
3583           if (target_buffer)
3584             {
3585               if (!firstonly) abort ();
3586               format_raw_keys (so_far, keys_count + 1, target_buffer);
3587               return make_int (1);
3588             }
3589           else if (firstonly)
3590             return raw_keys_to_keys (so_far, keys_count + 1);
3591           else
3592             result = Fcons (raw_keys_to_keys (so_far, keys_count + 1),
3593                             result);
3594
3595         c_doesnt_have_proper_loop_exit_statements:
3596           /* now on to the next matching key ... */
3597           if (!CONSP (keys)) break;
3598           keys = XCDR (keys);
3599         }
3600     }
3601
3602   /* Now search the sub-keymaps of this map.
3603      If we're in "firstonly" mode and have already found one, this
3604      point is not reached.  If we get one from lower down, either
3605      return it immediately (in firstonly mode) or tack it onto the
3606      end of the ones we've gotten so far.
3607      */
3608   for (submaps = keymap_submaps (map);
3609        !NILP (submaps);
3610        submaps = XCDR (submaps))
3611     {
3612       Lisp_Object key    = XCAR (XCAR (submaps));
3613       Lisp_Object submap = XCDR (XCAR (submaps));
3614       int lower_modifiers;
3615       int lower_keys_count = keys_count;
3616       int bucky;
3617
3618       submap = get_keymap (submap, 0, 0);
3619
3620       if (EQ (submap, map))
3621         /* Arrgh!  Some loser has introduced a loop... */
3622         continue;
3623
3624       /* If this is not a keymap, then that's probably because someone
3625          did an `fset' of a symbol that used to point to a map such that
3626          it no longer does.  Sigh.  Ignore this, and invalidate the cache
3627          so that it doesn't happen to us next time too.
3628          */
3629       if (NILP (submap))
3630         {
3631           XKEYMAP (map)->sub_maps_cache = Qt;
3632           continue;
3633         }
3634
3635       /* If the map is a "bucky" map, then add a bit to the
3636          modifiers_so_far list.
3637          Otherwise, add a new raw_key onto the end of keys_so_far.
3638          */
3639       bucky = MODIFIER_HASH_KEY_BITS (key);
3640       if (bucky != 0)
3641         lower_modifiers = (modifiers_so_far | bucky);
3642       else
3643         {
3644           struct key_data *so_far = c->keys_so_far;
3645           lower_modifiers = 0;
3646           so_far [lower_keys_count].keysym = key;
3647           so_far [lower_keys_count].modifiers = modifiers_so_far;
3648           lower_keys_count++;
3649         }
3650
3651       if (lower_keys_count >= c->keys_so_far_total_size)
3652         {
3653           int size = lower_keys_count + 50;
3654           if (! c->keys_so_far_malloced)
3655             {
3656               struct key_data *new = xnew_array (struct key_data, size);
3657               memcpy ((void *)new, (const void *)c->keys_so_far,
3658                       c->keys_so_far_total_size * sizeof (struct key_data));
3659             }
3660           else
3661             XREALLOC_ARRAY (c->keys_so_far, struct key_data, size);
3662
3663           c->keys_so_far_total_size = size;
3664           c->keys_so_far_malloced = 1;
3665         }
3666
3667       {
3668         Lisp_Object lower;
3669
3670         c->keys_count = lower_keys_count;
3671         c->modifiers_so_far = lower_modifiers;
3672
3673         lower = traverse_keymaps (submap, Qnil, where_is_recursive_mapper, c);
3674
3675         c->keys_count = keys_count;
3676         c->modifiers_so_far = modifiers_so_far;
3677
3678         if (!firstonly)
3679           result = nconc2 (lower, result);
3680         else if (!NILP (lower))
3681           return lower;
3682       }
3683     }
3684   return result;
3685 }
3686
3687
3688 static Lisp_Object
3689 where_is_internal (Lisp_Object definition, Lisp_Object *maps, int nmaps,
3690                    Lisp_Object firstonly, char *target_buffer)
3691 {
3692   /* This function can GC */
3693   Lisp_Object result = Qnil;
3694   int i;
3695   struct key_data raw[20];
3696   struct where_is_closure c;
3697
3698   c.definition = definition;
3699   c.shadow = maps;
3700   c.firstonly = !NILP (firstonly);
3701   c.target_buffer = target_buffer;
3702   c.keys_so_far = raw;
3703   c.keys_so_far_total_size = countof (raw);
3704   c.keys_so_far_malloced = 0;
3705
3706   /* Loop over each of the maps, accumulating the keys found.
3707      For each map searched, all previous maps shadow this one
3708      so that bogus keys aren't listed. */
3709   for (i = 0; i < nmaps; i++)
3710     {
3711       Lisp_Object this_result;
3712       c.shadow_count = i;
3713       /* Reset the things set in each iteration */
3714       c.keys_count = 0;
3715       c.modifiers_so_far = 0;
3716
3717       this_result = traverse_keymaps (maps[i], Qnil, where_is_recursive_mapper,
3718                                       &c);
3719       if (!NILP (firstonly))
3720         {
3721           result = this_result;
3722           if (!NILP (result))
3723             break;
3724         }
3725       else
3726         result = nconc2 (this_result, result);
3727     }
3728
3729   if (NILP (firstonly))
3730     result = Fnreverse (result);
3731
3732   if (c.keys_so_far_malloced)
3733     xfree (c.keys_so_far);
3734   return result;
3735 }
3736
3737 \f
3738 /************************************************************************/
3739 /*                         Describing keymaps                           */
3740 /************************************************************************/
3741
3742 DEFUN ("describe-bindings-internal", Fdescribe_bindings_internal, 1, 5, 0, /*
3743 Insert a list of all defined keys and their definitions in MAP.
3744 Optional second argument ALL says whether to include even "uninteresting"
3745 definitions (ie symbols with a non-nil `suppress-keymap' property.
3746 Third argument SHADOW is a list of keymaps whose bindings shadow those
3747 of map; if a binding is present in any shadowing map, it is not printed.
3748 Fourth argument PREFIX, if non-nil, should be a key sequence;
3749 only bindings which start with that key sequence will be printed.
3750 Fifth argument MOUSE-ONLY-P says to only print bindings for mouse clicks.
3751 */
3752        (map, all, shadow, prefix, mouse_only_p))
3753 {
3754   /* This function can GC */
3755
3756   /* #### At some point, this function should be changed to accept a
3757      BUFFER argument.  Currently, the BUFFER argument to
3758      describe_map_tree is being used only internally.  */
3759   describe_map_tree (map, NILP (all), shadow, prefix,
3760                      !NILP (mouse_only_p), Fcurrent_buffer ());
3761   return Qnil;
3762 }
3763
3764
3765 /* Insert a description of the key bindings in STARTMAP,
3766     followed by those of all maps reachable through STARTMAP.
3767    If PARTIAL is nonzero, omit certain "uninteresting" commands
3768     (such as `undefined').
3769    If SHADOW is non-nil, it is a list of other maps;
3770     don't mention keys which would be shadowed by any of them
3771    If PREFIX is non-nil, only list bindings which start with those keys.
3772  */
3773
3774 void
3775 describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow,
3776                    Lisp_Object prefix, int mice_only_p, Lisp_Object buffer)
3777 {
3778   /* This function can GC */
3779   Lisp_Object maps = Qnil;
3780   struct gcpro gcpro1, gcpro2;  /* get_keymap may autoload */
3781   GCPRO2 (maps, shadow);
3782
3783   maps = Faccessible_keymaps (startmap, prefix);
3784
3785   for (; !NILP (maps); maps = Fcdr (maps))
3786     {
3787       Lisp_Object sub_shadow = Qnil;
3788       Lisp_Object elt = Fcar (maps);
3789       Lisp_Object tail;
3790       int no_prefix = (VECTORP (Fcar (elt))
3791                        && XINT (Flength (Fcar (elt))) == 0);
3792       struct gcpro ngcpro1, ngcpro2, ngcpro3;
3793       NGCPRO3 (sub_shadow, elt, tail);
3794
3795       for (tail = shadow; CONSP (tail); tail = XCDR (tail))
3796         {
3797           Lisp_Object shmap = XCAR (tail);
3798
3799           /* If the sequence by which we reach this keymap is zero-length,
3800              then the shadow maps for this keymap are just SHADOW.  */
3801           if (no_prefix)
3802             ;
3803           /* If the sequence by which we reach this keymap actually has
3804              some elements, then the sequence's definition in SHADOW is
3805              what we should use.  */
3806           else
3807             {
3808               shmap = Flookup_key (shmap, Fcar (elt), Qt);
3809               if (CHARP (shmap))
3810                 shmap = Qnil;
3811             }
3812
3813           if (!NILP (shmap))
3814             {
3815               Lisp_Object shm = get_keymap (shmap, 0, 1);
3816               /* If shmap is not nil and not a keymap, it completely
3817                  shadows this map, so don't describe this map at all.  */
3818               if (!KEYMAPP (shm))
3819                 goto SKIP;
3820               sub_shadow = Fcons (shm, sub_shadow);
3821             }
3822         }
3823
3824       {
3825         /* Describe the contents of map MAP, assuming that this map
3826            itself is reached by the sequence of prefix keys KEYS (a vector).
3827            PARTIAL and SHADOW are as in `describe_map_tree'.  */
3828         Lisp_Object keysdesc
3829           = ((!no_prefix)
3830              ? concat2 (Fkey_description (Fcar (elt)), Vsingle_space_string)
3831              : Qnil);
3832         describe_map (Fcdr (elt), keysdesc,
3833                       describe_command,
3834                       partial,
3835                       sub_shadow,
3836                       mice_only_p,
3837                       buffer);
3838       }
3839     SKIP:
3840       NUNGCPRO;
3841     }
3842   UNGCPRO;
3843 }
3844
3845
3846 static void
3847 describe_command (Lisp_Object definition, Lisp_Object buffer)
3848 {
3849   /* This function can GC */
3850   int keymapp = !NILP (Fkeymapp (definition));
3851   struct gcpro gcpro1;
3852   GCPRO1 (definition);
3853
3854   Findent_to (make_int (16), make_int (3), buffer);
3855   if (keymapp)
3856     buffer_insert_c_string (XBUFFER (buffer), "<< ");
3857
3858   if (SYMBOLP (definition))
3859     {
3860       buffer_insert1 (XBUFFER (buffer), Fsymbol_name (definition));
3861     }
3862   else if (STRINGP (definition) || VECTORP (definition))
3863     {
3864       buffer_insert_c_string (XBUFFER (buffer), "Kbd Macro: ");
3865       buffer_insert1 (XBUFFER (buffer), Fkey_description (definition));
3866     }
3867   else if (COMPILED_FUNCTIONP (definition))
3868     buffer_insert_c_string (XBUFFER (buffer), "Anonymous Compiled Function");
3869   else if (CONSP (definition) && EQ (XCAR (definition), Qlambda))
3870     buffer_insert_c_string (XBUFFER (buffer), "Anonymous Lambda");
3871   else if (KEYMAPP (definition))
3872     {
3873       Lisp_Object name = XKEYMAP (definition)->name;
3874       if (STRINGP (name) || (SYMBOLP (name) && !NILP (name)))
3875         {
3876           buffer_insert_c_string (XBUFFER (buffer), "Prefix command ");
3877           if (SYMBOLP (name)
3878               && EQ (find_symbol_value (name), definition))
3879             buffer_insert1 (XBUFFER (buffer), Fsymbol_name (name));
3880           else
3881             {
3882               buffer_insert1 (XBUFFER (buffer), Fprin1_to_string (name, Qnil));
3883             }
3884         }
3885       else
3886         buffer_insert_c_string (XBUFFER (buffer), "Prefix Command");
3887     }
3888   else
3889     buffer_insert_c_string (XBUFFER (buffer), "??");
3890
3891   if (keymapp)
3892     buffer_insert_c_string (XBUFFER (buffer), " >>");
3893   buffer_insert_c_string (XBUFFER (buffer), "\n");
3894   UNGCPRO;
3895 }
3896
3897 struct describe_map_closure
3898   {
3899     Lisp_Object *list;   /* pointer to the list to update */
3900     Lisp_Object partial; /* whether to ignore suppressed commands */
3901     Lisp_Object shadow;  /* list of maps shadowing this one */
3902     Lisp_Object self;    /* this map */
3903     Lisp_Object self_root; /* this map, or some map that has this map as
3904                               a parent.  this is the base of the tree */
3905     int mice_only_p;     /* whether we are to display only button bindings */
3906   };
3907
3908 struct describe_map_shadow_closure
3909   {
3910     const struct key_data *raw_key;
3911     Lisp_Object self;
3912   };
3913
3914 static Lisp_Object
3915 describe_map_mapper_shadow_search (Lisp_Object map, void *arg)
3916 {
3917   struct describe_map_shadow_closure *c =
3918     (struct describe_map_shadow_closure *) arg;
3919
3920   if (EQ (map, c->self))
3921     return Qzero;               /* Not shadowed; terminate search */
3922
3923   return !NILP (keymap_lookup_directly (map,
3924                                         c->raw_key->keysym,
3925                                         c->raw_key->modifiers))
3926     ? Qt : Qnil;
3927 }
3928
3929
3930 static Lisp_Object
3931 keymap_lookup_inherited_mapper (Lisp_Object km, void *arg)
3932 {
3933   struct key_data *k = (struct key_data *) arg;
3934   return keymap_lookup_directly (km, k->keysym, k->modifiers);
3935 }
3936
3937
3938 static void
3939 describe_map_mapper (const struct key_data *key,
3940                      Lisp_Object binding,
3941                      void *describe_map_closure)
3942 {
3943   /* This function can GC */
3944   struct describe_map_closure *closure =
3945     (struct describe_map_closure *) describe_map_closure;
3946   Lisp_Object keysym = key->keysym;
3947   int modifiers = key->modifiers;
3948
3949   /* Don't mention suppressed commands.  */
3950   if (SYMBOLP (binding)
3951       && !NILP (closure->partial)
3952       && !NILP (Fget (binding, closure->partial, Qnil)))
3953     return;
3954
3955   /* If we're only supposed to display mouse bindings and this isn't one,
3956      then bug out. */
3957   if (closure->mice_only_p &&
3958       (! (EQ (keysym, Qbutton0) ||
3959           EQ (keysym, Qbutton1) ||
3960           EQ (keysym, Qbutton2) ||
3961           EQ (keysym, Qbutton3) ||
3962           EQ (keysym, Qbutton4) ||
3963           EQ (keysym, Qbutton5) ||
3964           EQ (keysym, Qbutton6) ||
3965           EQ (keysym, Qbutton7) ||
3966           EQ (keysym, Qbutton0up) ||
3967           EQ (keysym, Qbutton1up) ||
3968           EQ (keysym, Qbutton2up) ||
3969           EQ (keysym, Qbutton3up) ||
3970           EQ (keysym, Qbutton4up) ||
3971           EQ (keysym, Qbutton5up) ||
3972           EQ (keysym, Qbutton6up) ||
3973           EQ (keysym, Qbutton7up))))
3974     return;
3975
3976   /* If this command in this map is shadowed by some other map, ignore it. */
3977   {
3978     Lisp_Object tail;
3979
3980     for (tail = closure->shadow; CONSP (tail); tail = XCDR (tail))
3981       {
3982         QUIT;
3983         if (!NILP (traverse_keymaps (XCAR (tail), Qnil,
3984                                      keymap_lookup_inherited_mapper,
3985                                      /* Cast to discard `const' */
3986                                      (void *)key)))
3987           return;
3988       }
3989   }
3990
3991   /* If this key is in some map of which this map is a parent, then ignore
3992      it (in that case, it has been shadowed).
3993      */
3994   {
3995     Lisp_Object sh;
3996     struct describe_map_shadow_closure c;
3997     c.raw_key = key;
3998     c.self = closure->self;
3999
4000     sh = traverse_keymaps (closure->self_root, Qnil,
4001                            describe_map_mapper_shadow_search, &c);
4002     if (!NILP (sh) && !ZEROP (sh))
4003       return;
4004   }
4005
4006   /* Otherwise add it to the list to be sorted. */
4007   *(closure->list) = Fcons (Fcons (Fcons (keysym, make_int (modifiers)),
4008                                    binding),
4009                             *(closure->list));
4010 }
4011
4012
4013 static int
4014 describe_map_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
4015                              Lisp_Object pred)
4016 {
4017   /* obj1 and obj2 are conses of the form
4018      ( ( <keysym> . <modifiers> ) . <binding> )
4019      keysym and modifiers are used, binding is ignored.
4020    */
4021   int bit1, bit2;
4022   obj1 = XCAR (obj1);
4023   obj2 = XCAR (obj2);
4024   bit1 = XINT (XCDR (obj1));
4025   bit2 = XINT (XCDR (obj2));
4026   if (bit1 != bit2)
4027     return bit1 < bit2 ? 1 : -1;
4028   else
4029     return map_keymap_sort_predicate (obj1, obj2, pred);
4030 }
4031
4032 /* Elide 2 or more consecutive numeric keysyms bound to the same thing,
4033    or 2 or more symbolic keysyms that are bound to the same thing and
4034    have consecutive character-set-properties.
4035  */
4036 static int
4037 elide_next_two_p (Lisp_Object list)
4038 {
4039   Lisp_Object s1, s2;
4040
4041   if (NILP (XCDR (list)))
4042     return 0;
4043
4044   /* next two bindings differ */
4045   if (!EQ (XCDR (XCAR (list)),
4046            XCDR (XCAR (XCDR (list)))))
4047     return 0;
4048
4049   /* next two modifier-sets differ */
4050   if (!EQ (XCDR (XCAR (XCAR (list))),
4051            XCDR (XCAR (XCAR (XCDR (list))))))
4052     return 0;
4053
4054   s1 = XCAR (XCAR (XCAR (list)));
4055   s2 = XCAR (XCAR (XCAR (XCDR (list))));
4056
4057   if (SYMBOLP (s1))
4058     {
4059       Lisp_Object code = Fget (s1, Vcharacter_set_property, Qnil);
4060       if (CHAR_OR_CHAR_INTP (code))
4061         {
4062           s1 = code;
4063           CHECK_CHAR_COERCE_INT (s1);
4064         }
4065       else return 0;
4066     }
4067   if (SYMBOLP (s2))
4068     {
4069       Lisp_Object code = Fget (s2, Vcharacter_set_property, Qnil);
4070       if (CHAR_OR_CHAR_INTP (code))
4071         {
4072           s2 = code;
4073           CHECK_CHAR_COERCE_INT (s2);
4074         }
4075       else return 0;
4076     }
4077
4078   return (XCHAR (s1)     == XCHAR (s2) ||
4079           XCHAR (s1) + 1 == XCHAR (s2));
4080 }
4081
4082
4083 static Lisp_Object
4084 describe_map_parent_mapper (Lisp_Object keymap, void *arg)
4085 {
4086   /* This function can GC */
4087   struct describe_map_closure *describe_map_closure =
4088     (struct describe_map_closure *) arg;
4089   describe_map_closure->self = keymap;
4090   map_keymap (XKEYMAP (keymap)->table,
4091               0, /* don't sort: we'll do it later */
4092               describe_map_mapper, describe_map_closure);
4093   return Qnil;
4094 }
4095
4096
4097 /* Describe the contents of map MAP, assuming that this map itself is
4098    reached by the sequence of prefix keys KEYS (a string or vector).
4099    PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above.  */
4100
4101 static void
4102 describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
4103               void (*elt_describer) (Lisp_Object, Lisp_Object),
4104               int partial,
4105               Lisp_Object shadow,
4106               int mice_only_p,
4107               Lisp_Object buffer)
4108 {
4109   /* This function can GC */
4110   struct describe_map_closure describe_map_closure;
4111   Lisp_Object list = Qnil;
4112   struct buffer *buf = XBUFFER (buffer);
4113   Emchar printable_min = (CHAR_OR_CHAR_INTP (buf->ctl_arrow)
4114                           ? XCHAR_OR_CHAR_INT (buf->ctl_arrow)
4115                           : ((EQ (buf->ctl_arrow, Qt)
4116                               || EQ (buf->ctl_arrow, Qnil))
4117                              ? 256 : 160));
4118   int elided = 0;
4119   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4120
4121   keymap = get_keymap (keymap, 1, 1);
4122   describe_map_closure.partial = (partial ? Qsuppress_keymap : Qnil);
4123   describe_map_closure.shadow = shadow;
4124   describe_map_closure.list = &list;
4125   describe_map_closure.self_root = keymap;
4126   describe_map_closure.mice_only_p = mice_only_p;
4127
4128   GCPRO4 (keymap, elt_prefix, shadow, list);
4129
4130   traverse_keymaps (keymap, Qnil,
4131                     describe_map_parent_mapper, &describe_map_closure);
4132
4133   if (!NILP (list))
4134     {
4135       list = list_sort (list, Qnil, describe_map_sort_predicate);
4136       buffer_insert_c_string (buf, "\n");
4137       while (!NILP (list))
4138         {
4139           Lisp_Object elt = XCAR (XCAR (list));
4140           Lisp_Object keysym = XCAR (elt);
4141           int modifiers = XINT (XCDR (elt));
4142
4143           if (!NILP (elt_prefix))
4144             buffer_insert_lisp_string (buf, elt_prefix);
4145
4146           if (modifiers & XEMACS_MOD_META)
4147             buffer_insert_c_string (buf, "M-");
4148           if (modifiers & XEMACS_MOD_CONTROL)
4149             buffer_insert_c_string (buf, "C-");
4150           if (modifiers & XEMACS_MOD_SUPER)
4151             buffer_insert_c_string (buf, "S-");
4152           if (modifiers & XEMACS_MOD_HYPER)
4153             buffer_insert_c_string (buf, "H-");
4154           if (modifiers & XEMACS_MOD_ALT)
4155             buffer_insert_c_string (buf, "Alt-");
4156           if (modifiers & XEMACS_MOD_SHIFT)
4157             buffer_insert_c_string (buf, "Sh-");
4158           if (SYMBOLP (keysym))
4159             {
4160               Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
4161               Emchar c = (CHAR_OR_CHAR_INTP (code)
4162                           ? XCHAR_OR_CHAR_INT (code) : (Emchar) -1);
4163               /* Calling Fsingle_key_description() would cons more */
4164 #if 0                           /* This is bogus */
4165               if (EQ (keysym, QKlinefeed))
4166                 buffer_insert_c_string (buf, "LFD");
4167               else if (EQ (keysym, QKtab))
4168                 buffer_insert_c_string (buf, "TAB");
4169               else if (EQ (keysym, QKreturn))
4170                 buffer_insert_c_string (buf, "RET");
4171               else if (EQ (keysym, QKescape))
4172                 buffer_insert_c_string (buf, "ESC");
4173               else if (EQ (keysym, QKdelete))
4174                 buffer_insert_c_string (buf, "DEL");
4175               else if (EQ (keysym, QKspace))
4176                 buffer_insert_c_string (buf, "SPC");
4177               else if (EQ (keysym, QKbackspace))
4178                 buffer_insert_c_string (buf, "BS");
4179               else
4180 #endif
4181                 if (c >= printable_min)
4182                   buffer_insert_emacs_char (buf, c);
4183                 else buffer_insert1 (buf, Fsymbol_name (keysym));
4184             }
4185           else if (CHARP (keysym))
4186             buffer_insert_emacs_char (buf, XCHAR (keysym));
4187           else
4188             buffer_insert_c_string (buf, "---bad keysym---");
4189
4190           if (elided)
4191             elided = 0;
4192           else
4193             {
4194               int k = 0;
4195
4196               while (elide_next_two_p (list))
4197                 {
4198                   k++;
4199                   list = XCDR (list);
4200                 }
4201               if (k != 0)
4202                 {
4203                   if (k == 1)
4204                     buffer_insert_c_string (buf, ", ");
4205                   else
4206                     buffer_insert_c_string (buf, " .. ");
4207                   elided = 1;
4208                   continue;
4209                 }
4210             }
4211
4212           /* Print a description of the definition of this character.  */
4213           (*elt_describer) (XCDR (XCAR (list)), buffer);
4214           list = XCDR (list);
4215         }
4216     }
4217   UNGCPRO;
4218 }
4219
4220 \f
4221 void
4222 syms_of_keymap (void)
4223 {
4224   INIT_LRECORD_IMPLEMENTATION (keymap);
4225
4226   defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist");
4227
4228   defsymbol (&Qkeymapp, "keymapp");
4229
4230   defsymbol (&Qsuppress_keymap, "suppress-keymap");
4231
4232   defsymbol (&Qmodeline_map, "modeline-map");
4233   defsymbol (&Qtoolbar_map, "toolbar-map");
4234
4235   DEFSUBR (Fkeymap_parents);
4236   DEFSUBR (Fset_keymap_parents);
4237   DEFSUBR (Fkeymap_name);
4238   DEFSUBR (Fset_keymap_name);
4239   DEFSUBR (Fkeymap_prompt);
4240   DEFSUBR (Fset_keymap_prompt);
4241   DEFSUBR (Fkeymap_default_binding);
4242   DEFSUBR (Fset_keymap_default_binding);
4243
4244   DEFSUBR (Fkeymapp);
4245   DEFSUBR (Fmake_keymap);
4246   DEFSUBR (Fmake_sparse_keymap);
4247
4248   DEFSUBR (Fcopy_keymap);
4249   DEFSUBR (Fkeymap_fullness);
4250   DEFSUBR (Fmap_keymap);
4251   DEFSUBR (Fevent_matches_key_specifier_p);
4252   DEFSUBR (Fdefine_key);
4253   DEFSUBR (Flookup_key);
4254   DEFSUBR (Fkey_binding);
4255   DEFSUBR (Fuse_global_map);
4256   DEFSUBR (Fuse_local_map);
4257   DEFSUBR (Fcurrent_local_map);
4258   DEFSUBR (Fcurrent_global_map);
4259   DEFSUBR (Fcurrent_keymaps);
4260   DEFSUBR (Faccessible_keymaps);
4261   DEFSUBR (Fkey_description);
4262   DEFSUBR (Fsingle_key_description);
4263   DEFSUBR (Fwhere_is_internal);
4264   DEFSUBR (Fdescribe_bindings_internal);
4265
4266   DEFSUBR (Ftext_char_description);
4267
4268   defsymbol (&Qcontrol, "control");
4269   defsymbol (&Qctrl, "ctrl");
4270   defsymbol (&Qmeta, "meta");
4271   defsymbol (&Qsuper, "super");
4272   defsymbol (&Qhyper, "hyper");
4273   defsymbol (&Qalt, "alt");
4274   defsymbol (&Qshift, "shift");
4275   defsymbol (&Qbutton0, "button0");
4276   defsymbol (&Qbutton1, "button1");
4277   defsymbol (&Qbutton2, "button2");
4278   defsymbol (&Qbutton3, "button3");
4279   defsymbol (&Qbutton4, "button4");
4280   defsymbol (&Qbutton5, "button5");
4281   defsymbol (&Qbutton6, "button6");
4282   defsymbol (&Qbutton7, "button7");
4283   defsymbol (&Qbutton0up, "button0up");
4284   defsymbol (&Qbutton1up, "button1up");
4285   defsymbol (&Qbutton2up, "button2up");
4286   defsymbol (&Qbutton3up, "button3up");
4287   defsymbol (&Qbutton4up, "button4up");
4288   defsymbol (&Qbutton5up, "button5up");
4289   defsymbol (&Qbutton6up, "button6up");
4290   defsymbol (&Qbutton7up, "button7up");
4291   defsymbol (&Qmouse_1, "mouse-1");
4292   defsymbol (&Qmouse_2, "mouse-2");
4293   defsymbol (&Qmouse_3, "mouse-3");
4294   defsymbol (&Qmouse_4, "mouse-4");
4295   defsymbol (&Qmouse_5, "mouse-5");
4296   defsymbol (&Qmouse_6, "mouse-6");
4297   defsymbol (&Qmouse_7, "mouse-7");
4298   defsymbol (&Qdown_mouse_1, "down-mouse-1");
4299   defsymbol (&Qdown_mouse_2, "down-mouse-2");
4300   defsymbol (&Qdown_mouse_3, "down-mouse-3");
4301   defsymbol (&Qdown_mouse_4, "down-mouse-4");
4302   defsymbol (&Qdown_mouse_5, "down-mouse-5");
4303   defsymbol (&Qdown_mouse_6, "down-mouse-6");
4304   defsymbol (&Qdown_mouse_7, "down-mouse-7");
4305   defsymbol (&Qmenu_selection, "menu-selection");
4306   defsymbol (&QLFD, "LFD");
4307   defsymbol (&QTAB, "TAB");
4308   defsymbol (&QRET, "RET");
4309   defsymbol (&QESC, "ESC");
4310   defsymbol (&QDEL, "DEL");
4311   defsymbol (&QSPC, "SPC");
4312   defsymbol (&QBS, "BS");
4313 }
4314
4315 void
4316 vars_of_keymap (void)
4317 {
4318   DEFVAR_LISP ("meta-prefix-char", &Vmeta_prefix_char /*
4319 Meta-prefix character.
4320 This character followed by some character `foo' turns into `Meta-foo'.
4321 This can be any form recognized as a single key specifier.
4322 To disable the meta-prefix-char, set it to a negative number.
4323 */ );
4324   Vmeta_prefix_char = make_char (033);
4325
4326   DEFVAR_LISP ("mouse-grabbed-buffer", &Vmouse_grabbed_buffer /*
4327 A buffer which should be consulted first for all mouse activity.
4328 When a mouse-click is processed, it will first be looked up in the
4329 local-map of this buffer, and then through the normal mechanism if there
4330 is no binding for that click.  This buffer's value of `mode-motion-hook'
4331 will be consulted instead of the `mode-motion-hook' of the buffer of the
4332 window under the mouse.  You should *bind* this, not set it.
4333 */ );
4334   Vmouse_grabbed_buffer = Qnil;
4335
4336   DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map /*
4337 Keymap that overrides all other local keymaps.
4338 If this variable is non-nil, it is used as a keymap instead of the
4339 buffer's local map, and the minor mode keymaps and extent-local keymaps.
4340 You should *bind* this, not set it.
4341 */ );
4342   Voverriding_local_map = Qnil;
4343
4344   Fset (Qminor_mode_map_alist, Qnil);
4345
4346   DEFVAR_LISP ("key-translation-map", &Vkey_translation_map /*
4347 Keymap of key translations that can override keymaps.
4348 This keymap works like `function-key-map', but comes after that,
4349 and applies even for keys that have ordinary bindings.
4350 */ );
4351   Vkey_translation_map = Qnil;
4352
4353   DEFVAR_LISP ("vertical-divider-map", &Vvertical_divider_map /*
4354 Keymap which handles mouse clicks over vertical dividers.
4355 */ );
4356   Vvertical_divider_map = Qnil;
4357
4358   DEFVAR_INT ("keymap-tick", &keymap_tick /*
4359 Incremented for each change to any keymap.
4360 */ );
4361   keymap_tick = 0;
4362
4363   staticpro (&Vcurrent_global_map);
4364
4365   Vsingle_space_string = make_string ((const Bufbyte *) " ", 1);
4366   staticpro (&Vsingle_space_string);
4367 }
4368
4369 void
4370 complex_vars_of_keymap (void)
4371 {
4372   /* This function can GC */
4373   Lisp_Object ESC_prefix = intern ("ESC-prefix");
4374   Lisp_Object meta_disgustitute;
4375
4376   Vcurrent_global_map = Fmake_keymap (Qnil);
4377
4378   meta_disgustitute = Fmake_keymap (Qnil);
4379   Ffset (ESC_prefix, meta_disgustitute);
4380   /* no need to protect meta_disgustitute, though */
4381   keymap_store_internal (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META),
4382                          XKEYMAP (Vcurrent_global_map),
4383                          meta_disgustitute);
4384   XKEYMAP (Vcurrent_global_map)->sub_maps_cache = Qt;
4385
4386   Vkey_translation_map = Fmake_sparse_keymap (intern ("key-translation-map"));
4387 }