XEmacs 21.2.47 (Zephir).
[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, gcpro3;
2994   Lisp_Object table = Qnil;
2995
2996  /* tolerate obviously transposed args */
2997   if (!NILP (Fkeymapp (function)))
2998     {
2999       Lisp_Object tmp = function;
3000       function = keymap;
3001       keymap = tmp;
3002     }
3003
3004   GCPRO3 (function, keymap, table);
3005   keymap = get_keymap (keymap, 1, 1);
3006
3007   /* elisp_maphash does not allow mapping functions to modify the hash
3008      table being mapped over.  Since map-keymap explicitly allows a
3009      mapping function to modify KEYMAP, we map over a copy of the hash
3010      table instead.  */
3011   table = Fcopy_hash_table (XKEYMAP (keymap)->table);
3012
3013   map_keymap (table, !NILP (sort_first),
3014               map_keymap_mapper, LISP_TO_VOID (function));
3015   UNGCPRO;
3016   return Qnil;
3017 }
3018
3019
3020 \f
3021 /************************************************************************/
3022 /*                          Accessible keymaps                          */
3023 /************************************************************************/
3024
3025 struct accessible_keymaps_closure
3026   {
3027     Lisp_Object tail;
3028   };
3029
3030
3031 static void
3032 accessible_keymaps_mapper_1 (Lisp_Object keysym, Lisp_Object contents,
3033                              int modifiers,
3034                              struct accessible_keymaps_closure *closure)
3035 {
3036   /* This function can GC */
3037   int subbits = MODIFIER_HASH_KEY_BITS (keysym);
3038
3039   if (subbits != 0)
3040     {
3041       Lisp_Object submaps;
3042
3043       contents = get_keymap (contents, 1, 1);
3044       submaps = keymap_submaps (contents);
3045       for (; !NILP (submaps); submaps = XCDR (submaps))
3046         {
3047           accessible_keymaps_mapper_1 (XCAR (XCAR (submaps)),
3048                                        XCDR (XCAR (submaps)),
3049                                        (subbits | modifiers),
3050                                        closure);
3051         }
3052     }
3053   else
3054     {
3055       Lisp_Object thisseq = Fcar (Fcar (closure->tail));
3056       Lisp_Object cmd = get_keyelt (contents, 1);
3057       Lisp_Object vec;
3058       int j;
3059       int len;
3060       struct key_data key;
3061       key.keysym = keysym;
3062       key.modifiers = modifiers;
3063
3064       if (NILP (cmd))
3065         abort ();
3066       cmd = get_keymap (cmd, 0, 1);
3067       if (!KEYMAPP (cmd))
3068         abort ();
3069
3070       vec = make_vector (XVECTOR_LENGTH (thisseq) + 1, Qnil);
3071       len = XVECTOR_LENGTH (thisseq);
3072       for (j = 0; j < len; j++)
3073         XVECTOR_DATA (vec) [j] = XVECTOR_DATA (thisseq) [j];
3074       XVECTOR_DATA (vec) [j] = make_key_description (&key, 1);
3075
3076       nconc2 (closure->tail, list1 (Fcons (vec, cmd)));
3077     }
3078 }
3079
3080
3081 static Lisp_Object
3082 accessible_keymaps_keymap_mapper (Lisp_Object thismap, void *arg)
3083 {
3084   /* This function can GC */
3085   struct accessible_keymaps_closure *closure =
3086     (struct accessible_keymaps_closure *) arg;
3087   Lisp_Object submaps = keymap_submaps (thismap);
3088
3089   for (; !NILP (submaps); submaps = XCDR (submaps))
3090     {
3091       accessible_keymaps_mapper_1 (XCAR (XCAR (submaps)),
3092                                    XCDR (XCAR (submaps)),
3093                                    0,
3094                                    closure);
3095     }
3096   return Qnil;
3097 }
3098
3099
3100 DEFUN ("accessible-keymaps", Faccessible_keymaps, 1, 2, 0, /*
3101 Find all keymaps accessible via prefix characters from KEYMAP.
3102 Returns a list of elements of the form (KEYS . MAP), where the sequence
3103 KEYS starting from KEYMAP gets you to MAP.  These elements are ordered
3104 so that the KEYS increase in length.  The first element is ([] . KEYMAP).
3105 An optional argument PREFIX, if non-nil, should be a key sequence;
3106 then the value includes only maps for prefixes that start with PREFIX.
3107 */
3108        (keymap, prefix))
3109 {
3110   /* This function can GC */
3111   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3112   Lisp_Object accessible_keymaps = Qnil;
3113   struct accessible_keymaps_closure c;
3114   c.tail = Qnil;
3115   GCPRO4 (accessible_keymaps, c.tail, prefix, keymap);
3116
3117   keymap = get_keymap (keymap, 1, 1);
3118
3119  retry:
3120   if (NILP (prefix))
3121     {
3122       prefix = make_vector (0, Qnil);
3123     }
3124   else if (VECTORP (prefix) || STRINGP (prefix))
3125     {
3126       int len = XINT (Flength (prefix));
3127       Lisp_Object def;
3128       Lisp_Object p;
3129       int iii;
3130       struct gcpro ngcpro1;
3131
3132       if (len == 0)
3133         {
3134           prefix = Qnil;
3135           goto retry;
3136         }
3137
3138       def = Flookup_key (keymap, prefix, Qnil);
3139       def = get_keymap (def, 0, 1);
3140       if (!KEYMAPP (def))
3141         goto RETURN;
3142
3143       keymap = def;
3144       p = make_vector (len, Qnil);
3145       NGCPRO1 (p);
3146       for (iii = 0; iii < len; iii++)
3147         {
3148           struct key_data key;
3149           define_key_parser (Faref (prefix, make_int (iii)), &key);
3150           XVECTOR_DATA (p)[iii] = make_key_description (&key, 1);
3151         }
3152       NUNGCPRO;
3153       prefix = p;
3154     }
3155   else
3156     {
3157       prefix = wrong_type_argument (Qarrayp, prefix);
3158       goto retry;
3159     }
3160
3161   accessible_keymaps = list1 (Fcons (prefix, keymap));
3162
3163   /* For each map in the list maps, look at any other maps it points
3164      to and stick them at the end if they are not already in the list */
3165
3166   for (c.tail = accessible_keymaps;
3167        !NILP (c.tail);
3168        c.tail = XCDR (c.tail))
3169     {
3170       Lisp_Object thismap = Fcdr (Fcar (c.tail));
3171       CHECK_KEYMAP (thismap);
3172       traverse_keymaps (thismap, Qnil,
3173                         accessible_keymaps_keymap_mapper, &c);
3174     }
3175  RETURN:
3176   UNGCPRO;
3177   return accessible_keymaps;
3178 }
3179
3180
3181 \f
3182 /************************************************************************/
3183 /*              Pretty descriptions of key sequences                    */
3184 /************************************************************************/
3185
3186 DEFUN ("key-description", Fkey_description, 1, 1, 0, /*
3187 Return a pretty description of key-sequence KEYS.
3188 Control characters turn into "C-foo" sequences, meta into "M-foo",
3189 spaces are put between sequence elements, etc...
3190 */
3191        (keys))
3192 {
3193   if (CHAR_OR_CHAR_INTP (keys) || CONSP (keys) || SYMBOLP (keys)
3194       || EVENTP (keys))
3195     {
3196       return Fsingle_key_description (keys);
3197     }
3198   else if (VECTORP (keys) ||
3199            STRINGP (keys))
3200     {
3201       Lisp_Object string = Qnil;
3202       /* Lisp_Object sep = Qnil; */
3203       int size = XINT (Flength (keys));
3204       int i;
3205
3206       for (i = 0; i < size; i++)
3207         {
3208           Lisp_Object s2 = Fsingle_key_description
3209             (STRINGP (keys)
3210              ? make_char (string_char (XSTRING (keys), i))
3211              : XVECTOR_DATA (keys)[i]);
3212
3213           if (i == 0)
3214             string = s2;
3215           else
3216             {
3217               /* if (NILP (sep)) Lisp_Object sep = build_string (" ") */;
3218               string = concat2 (string, concat2 (Vsingle_space_string, s2));
3219             }
3220         }
3221       return string;
3222     }
3223   return Fkey_description (wrong_type_argument (Qsequencep, keys));
3224 }
3225
3226 DEFUN ("single-key-description", Fsingle_key_description, 1, 1, 0, /*
3227 Return a pretty description of command character KEY.
3228 Control characters turn into C-whatever, etc.
3229 This differs from `text-char-description' in that it returns a description
3230 of a key read from the user rather than a character from a buffer.
3231 */
3232        (key))
3233 {
3234   if (SYMBOLP (key))
3235     key = Fcons (key, Qnil); /* sleaze sleaze */
3236
3237   if (EVENTP (key) || CHAR_OR_CHAR_INTP (key))
3238     {
3239       char buf [255];
3240       if (!EVENTP (key))
3241         {
3242           Lisp_Event event;
3243           event.event_type = empty_event;
3244           CHECK_CHAR_COERCE_INT (key);
3245           character_to_event (XCHAR (key), &event,
3246                               XCONSOLE (Vselected_console), 0, 1);
3247           format_event_object (buf, &event, 1);
3248         }
3249       else
3250         format_event_object (buf, XEVENT (key), 1);
3251       return build_string (buf);
3252     }
3253
3254   if (CONSP (key))
3255     {
3256       char buf[255];
3257       char *bufp = buf;
3258       Lisp_Object rest;
3259       buf[0] = 0;
3260       LIST_LOOP (rest, key)
3261         {
3262           Lisp_Object keysym = XCAR (rest);
3263           if (EQ (keysym, Qcontrol))    strcpy (bufp, "C-"), bufp += 2;
3264           else if (EQ (keysym, Qctrl))  strcpy (bufp, "C-"), bufp += 2;
3265           else if (EQ (keysym, Qmeta))  strcpy (bufp, "M-"), bufp += 2;
3266           else if (EQ (keysym, Qsuper)) strcpy (bufp, "S-"), bufp += 2;
3267           else if (EQ (keysym, Qhyper)) strcpy (bufp, "H-"), bufp += 2;
3268           else if (EQ (keysym, Qalt))   strcpy (bufp, "A-"), bufp += 2;
3269           else if (EQ (keysym, Qshift)) strcpy (bufp, "Sh-"), bufp += 3;
3270           else if (CHAR_OR_CHAR_INTP (keysym))
3271             {
3272               bufp += set_charptr_emchar ((Bufbyte *) bufp,
3273                                           XCHAR_OR_CHAR_INT (keysym));
3274               *bufp = 0;
3275             }
3276           else
3277             {
3278               CHECK_SYMBOL (keysym);
3279 #if 0                           /* This is bogus */
3280               if (EQ (keysym, QKlinefeed))       strcpy (bufp, "LFD");
3281               else if (EQ (keysym, QKtab))       strcpy (bufp, "TAB");
3282               else if (EQ (keysym, QKreturn))    strcpy (bufp, "RET");
3283               else if (EQ (keysym, QKescape))    strcpy (bufp, "ESC");
3284               else if (EQ (keysym, QKdelete))    strcpy (bufp, "DEL");
3285               else if (EQ (keysym, QKspace))     strcpy (bufp, "SPC");
3286               else if (EQ (keysym, QKbackspace)) strcpy (bufp, "BS");
3287               else
3288 #endif
3289                 strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name));
3290               if (!NILP (XCDR (rest)))
3291                 signal_simple_error ("Invalid key description",
3292                                      key);
3293             }
3294         }
3295       return build_string (buf);
3296     }
3297   return Fsingle_key_description
3298     (wrong_type_argument (intern ("char-or-event-p"), key));
3299 }
3300
3301 DEFUN ("text-char-description", Ftext_char_description, 1, 1, 0, /*
3302 Return a pretty description of file-character CHR.
3303 Unprintable characters turn into "^char" or \\NNN, depending on the value
3304 of the `ctl-arrow' variable.
3305 This differs from `single-key-description' in that it returns a description
3306 of a character from a buffer rather than a key read from the user.
3307 */
3308        (chr))
3309 {
3310   Bufbyte buf[200];
3311   Bufbyte *p;
3312   Emchar c;
3313   Lisp_Object ctl_arrow = current_buffer->ctl_arrow;
3314   int ctl_p = !NILP (ctl_arrow);
3315   Emchar printable_min = (CHAR_OR_CHAR_INTP (ctl_arrow)
3316                           ? XCHAR_OR_CHAR_INT (ctl_arrow)
3317                           : ((EQ (ctl_arrow, Qt) || NILP (ctl_arrow))
3318                              ? 256 : 160));
3319
3320   if (EVENTP (chr))
3321     {
3322       Lisp_Object ch = Fevent_to_character (chr, Qnil, Qnil, Qt);
3323       if (NILP (ch))
3324         return
3325           signal_simple_continuable_error
3326             ("character has no ASCII equivalent", Fcopy_event (chr, Qnil));
3327       chr = ch;
3328     }
3329
3330   CHECK_CHAR_COERCE_INT (chr);
3331
3332   c = XCHAR (chr);
3333   p = buf;
3334
3335   if (c >= printable_min)
3336     {
3337       p += set_charptr_emchar (p, c);
3338     }
3339   else if (c < 040 && ctl_p)
3340     {
3341       *p++ = '^';
3342       *p++ = c + 64;            /* 'A' - 1 */
3343     }
3344   else if (c == 0177)
3345     {
3346       *p++ = '^';
3347       *p++ = '?';
3348     }
3349   else if (c >= 0200 || c < 040)
3350     {
3351       *p++ = '\\';
3352 #ifdef MULE
3353       /* !!#### This syntax is not readable.  It will
3354          be interpreted as a 3-digit octal number rather
3355          than a 7-digit octal number. */
3356       if (c >= 0400)
3357         {
3358           *p++ = '0' + ((c & 07000000) >> 18);
3359           *p++ = '0' + ((c & 0700000) >> 15);
3360           *p++ = '0' + ((c & 070000) >> 12);
3361           *p++ = '0' + ((c & 07000) >> 9);
3362         }
3363 #endif
3364       *p++ = '0' + ((c & 0700) >> 6);
3365       *p++ = '0' + ((c & 0070) >> 3);
3366       *p++ = '0' + ((c & 0007));
3367     }
3368   else
3369     {
3370       p += set_charptr_emchar (p, c);
3371     }
3372
3373   *p = 0;
3374   return build_string ((char *) buf);
3375 }
3376
3377 \f
3378 /************************************************************************/
3379 /*              where-is (mapping bindings to keys)                     */
3380 /************************************************************************/
3381
3382 static Lisp_Object
3383 where_is_internal (Lisp_Object definition, Lisp_Object *maps, int nmaps,
3384                    Lisp_Object firstonly, char *target_buffer);
3385
3386 DEFUN ("where-is-internal", Fwhere_is_internal, 1, 5, 0, /*
3387 Return list of keys that invoke DEFINITION in KEYMAPS.
3388 KEYMAPS can be either a keymap (meaning search in that keymap and the
3389 current global keymap) or a list of keymaps (meaning search in exactly
3390 those keymaps and no others).  If KEYMAPS is nil, search in the currently
3391 applicable maps for EVENT-OR-KEYS (this is equivalent to specifying
3392 `(current-keymaps EVENT-OR-KEYS)' as the argument to KEYMAPS).
3393
3394 If optional 3rd arg FIRSTONLY is non-nil, return a vector representing
3395  the first key sequence found, rather than a list of all possible key
3396  sequences.
3397
3398 If optional 4th arg NOINDIRECT is non-nil, don't follow indirections
3399  to other keymaps or slots.  This makes it possible to search for an
3400  indirect definition itself.
3401 */
3402        (definition, keymaps, firstonly, noindirect, event_or_keys))
3403 {
3404   /* This function can GC */
3405   Lisp_Object maps[100];
3406   Lisp_Object *gubbish = maps;
3407   int nmaps;
3408
3409   /* Get keymaps as an array */
3410   if (NILP (keymaps))
3411     {
3412       nmaps = get_relevant_keymaps (event_or_keys, countof (maps),
3413                                     gubbish);
3414       if (nmaps > countof (maps))
3415         {
3416           gubbish = alloca_array (Lisp_Object, nmaps);
3417           nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish);
3418         }
3419     }
3420   else if (CONSP (keymaps))
3421     {
3422       Lisp_Object rest;
3423       int i;
3424
3425       nmaps = XINT (Flength (keymaps));
3426       if (nmaps > countof (maps))
3427         {
3428           gubbish = alloca_array (Lisp_Object, nmaps);
3429         }
3430       for (rest = keymaps, i = 0; !NILP (rest);
3431            rest = XCDR (keymaps), i++)
3432         {
3433           gubbish[i] = get_keymap (XCAR (keymaps), 1, 1);
3434         }
3435     }
3436   else
3437     {
3438       nmaps = 1;
3439       gubbish[0] = get_keymap (keymaps, 1, 1);
3440       if (!EQ (gubbish[0], Vcurrent_global_map))
3441         {
3442           gubbish[1] = Vcurrent_global_map;
3443           nmaps++;
3444         }
3445     }
3446
3447   return where_is_internal (definition, gubbish, nmaps, firstonly, 0);
3448 }
3449
3450 /* This function is like
3451    (key-description (where-is-internal definition nil t))
3452    except that it writes its output into a (char *) buffer that you
3453    provide; it doesn't cons (or allocate memory) at all, so it's
3454    very fast.  This is used by menubar.c.
3455  */
3456 void
3457 where_is_to_char (Lisp_Object definition, char *buffer)
3458 {
3459   /* This function can GC */
3460   Lisp_Object maps[100];
3461   Lisp_Object *gubbish = maps;
3462   int nmaps;
3463
3464   /* Get keymaps as an array */
3465   nmaps = get_relevant_keymaps (Qnil, countof (maps), gubbish);
3466   if (nmaps > countof (maps))
3467     {
3468       gubbish = alloca_array (Lisp_Object, nmaps);
3469       nmaps = get_relevant_keymaps (Qnil, nmaps, gubbish);
3470     }
3471
3472   buffer[0] = 0;
3473   where_is_internal (definition, maps, nmaps, Qt, buffer);
3474 }
3475
3476
3477 static Lisp_Object
3478 raw_keys_to_keys (struct key_data *keys, int count)
3479 {
3480   Lisp_Object result = make_vector (count, Qnil);
3481   while (count--)
3482     XVECTOR_DATA (result) [count] = make_key_description (&(keys[count]), 1);
3483   return result;
3484 }
3485
3486
3487 static void
3488 format_raw_keys (struct key_data *keys, int count, char *buf)
3489 {
3490   int i;
3491   Lisp_Event event;
3492   event.event_type = key_press_event;
3493   event.channel = Vselected_console;
3494   for (i = 0; i < count; i++)
3495     {
3496       event.event.key.keysym    = keys[i].keysym;
3497       event.event.key.modifiers = keys[i].modifiers;
3498       format_event_object (buf, &event, 1);
3499       buf += strlen (buf);
3500       if (i < count-1)
3501         buf[0] = ' ', buf++;
3502     }
3503 }
3504
3505
3506 /* definition is the thing to look for.
3507    map is a keymap.
3508    shadow is an array of shadow_count keymaps; if there is a different
3509    binding in any of the keymaps of a key that we are considering
3510    returning, then we reconsider.
3511    firstonly means give up after finding the first match;
3512    keys_so_far and modifiers_so_far describe which map we're looking in;
3513    If we're in the "meta" submap of the map that "C-x 4" is bound to,
3514    then keys_so_far will be {(control x), \4}, and modifiers_so_far
3515    will be XEMACS_MOD_META.  That is, keys_so_far is the chain of keys that we
3516    have followed, and modifiers_so_far_so_far is the bits (partial keys)
3517    beyond that.
3518
3519    (keys_so_far is a global buffer and the keys_count arg says how much
3520    of it we're currently interested in.)
3521
3522    If target_buffer is provided, then we write a key-description into it,
3523    to avoid consing a string.  This only works with firstonly on.
3524    */
3525
3526 struct where_is_closure
3527   {
3528     Lisp_Object definition;
3529     Lisp_Object *shadow;
3530     int shadow_count;
3531     int firstonly;
3532     int keys_count;
3533     int modifiers_so_far;
3534     char *target_buffer;
3535     struct key_data *keys_so_far;
3536     int keys_so_far_total_size;
3537     int keys_so_far_malloced;
3538   };
3539
3540 static Lisp_Object where_is_recursive_mapper (Lisp_Object map, void *arg);
3541
3542 static Lisp_Object
3543 where_is_recursive_mapper (Lisp_Object map, void *arg)
3544 {
3545   /* This function can GC */
3546   struct where_is_closure *c = (struct where_is_closure *) arg;
3547   Lisp_Object definition = c->definition;
3548   const int firstonly = c->firstonly;
3549   const int keys_count = c->keys_count;
3550   const int modifiers_so_far = c->modifiers_so_far;
3551   char *target_buffer = c->target_buffer;
3552   Lisp_Object keys = Fgethash (definition,
3553                                XKEYMAP (map)->inverse_table,
3554                                Qnil);
3555   Lisp_Object submaps;
3556   Lisp_Object result = Qnil;
3557
3558   if (!NILP (keys))
3559     {
3560       /* One or more keys in this map match the definition we're looking for.
3561          Verify that these bindings aren't shadowed by other bindings
3562          in the shadow maps.  Either nil or number as value from
3563          raw_lookup_key() means undefined.  */
3564       struct key_data *so_far = c->keys_so_far;
3565
3566       for (;;) /* loop over all keys that match */
3567         {
3568           Lisp_Object k = CONSP (keys) ? XCAR (keys) : keys;
3569           int i;
3570
3571           so_far [keys_count].keysym = k;
3572           so_far [keys_count].modifiers = modifiers_so_far;
3573
3574           /* now loop over all shadow maps */
3575           for (i = 0; i < c->shadow_count; i++)
3576             {
3577               Lisp_Object shadowed = raw_lookup_key (c->shadow[i],
3578                                                      so_far,
3579                                                      keys_count + 1,
3580                                                      0, 1);
3581
3582               if (NILP (shadowed) || CHARP (shadowed) ||
3583                   EQ (shadowed, definition))
3584                 continue; /* we passed this test; it's not shadowed here. */
3585               else
3586                 /* ignore this key binding, since it actually has a
3587                    different binding in a shadowing map */
3588                 goto c_doesnt_have_proper_loop_exit_statements;
3589             }
3590
3591           /* OK, the key is for real */
3592           if (target_buffer)
3593             {
3594               if (!firstonly) abort ();
3595               format_raw_keys (so_far, keys_count + 1, target_buffer);
3596               return make_int (1);
3597             }
3598           else if (firstonly)
3599             return raw_keys_to_keys (so_far, keys_count + 1);
3600           else
3601             result = Fcons (raw_keys_to_keys (so_far, keys_count + 1),
3602                             result);
3603
3604         c_doesnt_have_proper_loop_exit_statements:
3605           /* now on to the next matching key ... */
3606           if (!CONSP (keys)) break;
3607           keys = XCDR (keys);
3608         }
3609     }
3610
3611   /* Now search the sub-keymaps of this map.
3612      If we're in "firstonly" mode and have already found one, this
3613      point is not reached.  If we get one from lower down, either
3614      return it immediately (in firstonly mode) or tack it onto the
3615      end of the ones we've gotten so far.
3616      */
3617   for (submaps = keymap_submaps (map);
3618        !NILP (submaps);
3619        submaps = XCDR (submaps))
3620     {
3621       Lisp_Object key    = XCAR (XCAR (submaps));
3622       Lisp_Object submap = XCDR (XCAR (submaps));
3623       int lower_modifiers;
3624       int lower_keys_count = keys_count;
3625       int bucky;
3626
3627       submap = get_keymap (submap, 0, 0);
3628
3629       if (EQ (submap, map))
3630         /* Arrgh!  Some loser has introduced a loop... */
3631         continue;
3632
3633       /* If this is not a keymap, then that's probably because someone
3634          did an `fset' of a symbol that used to point to a map such that
3635          it no longer does.  Sigh.  Ignore this, and invalidate the cache
3636          so that it doesn't happen to us next time too.
3637          */
3638       if (NILP (submap))
3639         {
3640           XKEYMAP (map)->sub_maps_cache = Qt;
3641           continue;
3642         }
3643
3644       /* If the map is a "bucky" map, then add a bit to the
3645          modifiers_so_far list.
3646          Otherwise, add a new raw_key onto the end of keys_so_far.
3647          */
3648       bucky = MODIFIER_HASH_KEY_BITS (key);
3649       if (bucky != 0)
3650         lower_modifiers = (modifiers_so_far | bucky);
3651       else
3652         {
3653           struct key_data *so_far = c->keys_so_far;
3654           lower_modifiers = 0;
3655           so_far [lower_keys_count].keysym = key;
3656           so_far [lower_keys_count].modifiers = modifiers_so_far;
3657           lower_keys_count++;
3658         }
3659
3660       if (lower_keys_count >= c->keys_so_far_total_size)
3661         {
3662           int size = lower_keys_count + 50;
3663           if (! c->keys_so_far_malloced)
3664             {
3665               struct key_data *new = xnew_array (struct key_data, size);
3666               memcpy ((void *)new, (const void *)c->keys_so_far,
3667                       c->keys_so_far_total_size * sizeof (struct key_data));
3668             }
3669           else
3670             XREALLOC_ARRAY (c->keys_so_far, struct key_data, size);
3671
3672           c->keys_so_far_total_size = size;
3673           c->keys_so_far_malloced = 1;
3674         }
3675
3676       {
3677         Lisp_Object lower;
3678
3679         c->keys_count = lower_keys_count;
3680         c->modifiers_so_far = lower_modifiers;
3681
3682         lower = traverse_keymaps (submap, Qnil, where_is_recursive_mapper, c);
3683
3684         c->keys_count = keys_count;
3685         c->modifiers_so_far = modifiers_so_far;
3686
3687         if (!firstonly)
3688           result = nconc2 (lower, result);
3689         else if (!NILP (lower))
3690           return lower;
3691       }
3692     }
3693   return result;
3694 }
3695
3696
3697 static Lisp_Object
3698 where_is_internal (Lisp_Object definition, Lisp_Object *maps, int nmaps,
3699                    Lisp_Object firstonly, char *target_buffer)
3700 {
3701   /* This function can GC */
3702   Lisp_Object result = Qnil;
3703   int i;
3704   struct key_data raw[20];
3705   struct where_is_closure c;
3706
3707   c.definition = definition;
3708   c.shadow = maps;
3709   c.firstonly = !NILP (firstonly);
3710   c.target_buffer = target_buffer;
3711   c.keys_so_far = raw;
3712   c.keys_so_far_total_size = countof (raw);
3713   c.keys_so_far_malloced = 0;
3714
3715   /* Loop over each of the maps, accumulating the keys found.
3716      For each map searched, all previous maps shadow this one
3717      so that bogus keys aren't listed. */
3718   for (i = 0; i < nmaps; i++)
3719     {
3720       Lisp_Object this_result;
3721       c.shadow_count = i;
3722       /* Reset the things set in each iteration */
3723       c.keys_count = 0;
3724       c.modifiers_so_far = 0;
3725
3726       this_result = traverse_keymaps (maps[i], Qnil, where_is_recursive_mapper,
3727                                       &c);
3728       if (!NILP (firstonly))
3729         {
3730           result = this_result;
3731           if (!NILP (result))
3732             break;
3733         }
3734       else
3735         result = nconc2 (this_result, result);
3736     }
3737
3738   if (NILP (firstonly))
3739     result = Fnreverse (result);
3740
3741   if (c.keys_so_far_malloced)
3742     xfree (c.keys_so_far);
3743   return result;
3744 }
3745
3746 \f
3747 /************************************************************************/
3748 /*                         Describing keymaps                           */
3749 /************************************************************************/
3750
3751 DEFUN ("describe-bindings-internal", Fdescribe_bindings_internal, 1, 5, 0, /*
3752 Insert a list of all defined keys and their definitions in MAP.
3753 Optional second argument ALL says whether to include even "uninteresting"
3754 definitions (ie symbols with a non-nil `suppress-keymap' property.
3755 Third argument SHADOW is a list of keymaps whose bindings shadow those
3756 of map; if a binding is present in any shadowing map, it is not printed.
3757 Fourth argument PREFIX, if non-nil, should be a key sequence;
3758 only bindings which start with that key sequence will be printed.
3759 Fifth argument MOUSE-ONLY-P says to only print bindings for mouse clicks.
3760 */
3761        (map, all, shadow, prefix, mouse_only_p))
3762 {
3763   /* This function can GC */
3764
3765   /* #### At some point, this function should be changed to accept a
3766      BUFFER argument.  Currently, the BUFFER argument to
3767      describe_map_tree is being used only internally.  */
3768   describe_map_tree (map, NILP (all), shadow, prefix,
3769                      !NILP (mouse_only_p), Fcurrent_buffer ());
3770   return Qnil;
3771 }
3772
3773
3774 /* Insert a description of the key bindings in STARTMAP,
3775     followed by those of all maps reachable through STARTMAP.
3776    If PARTIAL is nonzero, omit certain "uninteresting" commands
3777     (such as `undefined').
3778    If SHADOW is non-nil, it is a list of other maps;
3779     don't mention keys which would be shadowed by any of them
3780    If PREFIX is non-nil, only list bindings which start with those keys.
3781  */
3782
3783 void
3784 describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow,
3785                    Lisp_Object prefix, int mice_only_p, Lisp_Object buffer)
3786 {
3787   /* This function can GC */
3788   Lisp_Object maps = Qnil;
3789   struct gcpro gcpro1, gcpro2;  /* get_keymap may autoload */
3790   GCPRO2 (maps, shadow);
3791
3792   maps = Faccessible_keymaps (startmap, prefix);
3793
3794   for (; !NILP (maps); maps = Fcdr (maps))
3795     {
3796       Lisp_Object sub_shadow = Qnil;
3797       Lisp_Object elt = Fcar (maps);
3798       Lisp_Object tail;
3799       int no_prefix = (VECTORP (Fcar (elt))
3800                        && XINT (Flength (Fcar (elt))) == 0);
3801       struct gcpro ngcpro1, ngcpro2, ngcpro3;
3802       NGCPRO3 (sub_shadow, elt, tail);
3803
3804       for (tail = shadow; CONSP (tail); tail = XCDR (tail))
3805         {
3806           Lisp_Object shmap = XCAR (tail);
3807
3808           /* If the sequence by which we reach this keymap is zero-length,
3809              then the shadow maps for this keymap are just SHADOW.  */
3810           if (no_prefix)
3811             ;
3812           /* If the sequence by which we reach this keymap actually has
3813              some elements, then the sequence's definition in SHADOW is
3814              what we should use.  */
3815           else
3816             {
3817               shmap = Flookup_key (shmap, Fcar (elt), Qt);
3818               if (CHARP (shmap))
3819                 shmap = Qnil;
3820             }
3821
3822           if (!NILP (shmap))
3823             {
3824               Lisp_Object shm = get_keymap (shmap, 0, 1);
3825               /* If shmap is not nil and not a keymap, it completely
3826                  shadows this map, so don't describe this map at all.  */
3827               if (!KEYMAPP (shm))
3828                 goto SKIP;
3829               sub_shadow = Fcons (shm, sub_shadow);
3830             }
3831         }
3832
3833       {
3834         /* Describe the contents of map MAP, assuming that this map
3835            itself is reached by the sequence of prefix keys KEYS (a vector).
3836            PARTIAL and SHADOW are as in `describe_map_tree'.  */
3837         Lisp_Object keysdesc
3838           = ((!no_prefix)
3839              ? concat2 (Fkey_description (Fcar (elt)), Vsingle_space_string)
3840              : Qnil);
3841         describe_map (Fcdr (elt), keysdesc,
3842                       describe_command,
3843                       partial,
3844                       sub_shadow,
3845                       mice_only_p,
3846                       buffer);
3847       }
3848     SKIP:
3849       NUNGCPRO;
3850     }
3851   UNGCPRO;
3852 }
3853
3854
3855 static void
3856 describe_command (Lisp_Object definition, Lisp_Object buffer)
3857 {
3858   /* This function can GC */
3859   int keymapp = !NILP (Fkeymapp (definition));
3860   struct gcpro gcpro1;
3861   GCPRO1 (definition);
3862
3863   Findent_to (make_int (16), make_int (3), buffer);
3864   if (keymapp)
3865     buffer_insert_c_string (XBUFFER (buffer), "<< ");
3866
3867   if (SYMBOLP (definition))
3868     {
3869       buffer_insert1 (XBUFFER (buffer), Fsymbol_name (definition));
3870     }
3871   else if (STRINGP (definition) || VECTORP (definition))
3872     {
3873       buffer_insert_c_string (XBUFFER (buffer), "Kbd Macro: ");
3874       buffer_insert1 (XBUFFER (buffer), Fkey_description (definition));
3875     }
3876   else if (COMPILED_FUNCTIONP (definition))
3877     buffer_insert_c_string (XBUFFER (buffer), "Anonymous Compiled Function");
3878   else if (CONSP (definition) && EQ (XCAR (definition), Qlambda))
3879     buffer_insert_c_string (XBUFFER (buffer), "Anonymous Lambda");
3880   else if (KEYMAPP (definition))
3881     {
3882       Lisp_Object name = XKEYMAP (definition)->name;
3883       if (STRINGP (name) || (SYMBOLP (name) && !NILP (name)))
3884         {
3885           buffer_insert_c_string (XBUFFER (buffer), "Prefix command ");
3886           if (SYMBOLP (name)
3887               && EQ (find_symbol_value (name), definition))
3888             buffer_insert1 (XBUFFER (buffer), Fsymbol_name (name));
3889           else
3890             {
3891               buffer_insert1 (XBUFFER (buffer), Fprin1_to_string (name, Qnil));
3892             }
3893         }
3894       else
3895         buffer_insert_c_string (XBUFFER (buffer), "Prefix Command");
3896     }
3897   else
3898     buffer_insert_c_string (XBUFFER (buffer), "??");
3899
3900   if (keymapp)
3901     buffer_insert_c_string (XBUFFER (buffer), " >>");
3902   buffer_insert_c_string (XBUFFER (buffer), "\n");
3903   UNGCPRO;
3904 }
3905
3906 struct describe_map_closure
3907   {
3908     Lisp_Object *list;   /* pointer to the list to update */
3909     Lisp_Object partial; /* whether to ignore suppressed commands */
3910     Lisp_Object shadow;  /* list of maps shadowing this one */
3911     Lisp_Object self;    /* this map */
3912     Lisp_Object self_root; /* this map, or some map that has this map as
3913                               a parent.  this is the base of the tree */
3914     int mice_only_p;     /* whether we are to display only button bindings */
3915   };
3916
3917 struct describe_map_shadow_closure
3918   {
3919     const struct key_data *raw_key;
3920     Lisp_Object self;
3921   };
3922
3923 static Lisp_Object
3924 describe_map_mapper_shadow_search (Lisp_Object map, void *arg)
3925 {
3926   struct describe_map_shadow_closure *c =
3927     (struct describe_map_shadow_closure *) arg;
3928
3929   if (EQ (map, c->self))
3930     return Qzero;               /* Not shadowed; terminate search */
3931
3932   return !NILP (keymap_lookup_directly (map,
3933                                         c->raw_key->keysym,
3934                                         c->raw_key->modifiers))
3935     ? Qt : Qnil;
3936 }
3937
3938
3939 static Lisp_Object
3940 keymap_lookup_inherited_mapper (Lisp_Object km, void *arg)
3941 {
3942   struct key_data *k = (struct key_data *) arg;
3943   return keymap_lookup_directly (km, k->keysym, k->modifiers);
3944 }
3945
3946
3947 static void
3948 describe_map_mapper (const struct key_data *key,
3949                      Lisp_Object binding,
3950                      void *describe_map_closure)
3951 {
3952   /* This function can GC */
3953   struct describe_map_closure *closure =
3954     (struct describe_map_closure *) describe_map_closure;
3955   Lisp_Object keysym = key->keysym;
3956   int modifiers = key->modifiers;
3957
3958   /* Don't mention suppressed commands.  */
3959   if (SYMBOLP (binding)
3960       && !NILP (closure->partial)
3961       && !NILP (Fget (binding, closure->partial, Qnil)))
3962     return;
3963
3964   /* If we're only supposed to display mouse bindings and this isn't one,
3965      then bug out. */
3966   if (closure->mice_only_p &&
3967       (! (EQ (keysym, Qbutton0) ||
3968           EQ (keysym, Qbutton1) ||
3969           EQ (keysym, Qbutton2) ||
3970           EQ (keysym, Qbutton3) ||
3971           EQ (keysym, Qbutton4) ||
3972           EQ (keysym, Qbutton5) ||
3973           EQ (keysym, Qbutton6) ||
3974           EQ (keysym, Qbutton7) ||
3975           EQ (keysym, Qbutton0up) ||
3976           EQ (keysym, Qbutton1up) ||
3977           EQ (keysym, Qbutton2up) ||
3978           EQ (keysym, Qbutton3up) ||
3979           EQ (keysym, Qbutton4up) ||
3980           EQ (keysym, Qbutton5up) ||
3981           EQ (keysym, Qbutton6up) ||
3982           EQ (keysym, Qbutton7up))))
3983     return;
3984
3985   /* If this command in this map is shadowed by some other map, ignore it. */
3986   {
3987     Lisp_Object tail;
3988
3989     for (tail = closure->shadow; CONSP (tail); tail = XCDR (tail))
3990       {
3991         QUIT;
3992         if (!NILP (traverse_keymaps (XCAR (tail), Qnil,
3993                                      keymap_lookup_inherited_mapper,
3994                                      /* Cast to discard `const' */
3995                                      (void *)key)))
3996           return;
3997       }
3998   }
3999
4000   /* If this key is in some map of which this map is a parent, then ignore
4001      it (in that case, it has been shadowed).
4002      */
4003   {
4004     Lisp_Object sh;
4005     struct describe_map_shadow_closure c;
4006     c.raw_key = key;
4007     c.self = closure->self;
4008
4009     sh = traverse_keymaps (closure->self_root, Qnil,
4010                            describe_map_mapper_shadow_search, &c);
4011     if (!NILP (sh) && !ZEROP (sh))
4012       return;
4013   }
4014
4015   /* Otherwise add it to the list to be sorted. */
4016   *(closure->list) = Fcons (Fcons (Fcons (keysym, make_int (modifiers)),
4017                                    binding),
4018                             *(closure->list));
4019 }
4020
4021
4022 static int
4023 describe_map_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
4024                              Lisp_Object pred)
4025 {
4026   /* obj1 and obj2 are conses of the form
4027      ( ( <keysym> . <modifiers> ) . <binding> )
4028      keysym and modifiers are used, binding is ignored.
4029    */
4030   int bit1, bit2;
4031   obj1 = XCAR (obj1);
4032   obj2 = XCAR (obj2);
4033   bit1 = XINT (XCDR (obj1));
4034   bit2 = XINT (XCDR (obj2));
4035   if (bit1 != bit2)
4036     return bit1 < bit2 ? 1 : -1;
4037   else
4038     return map_keymap_sort_predicate (obj1, obj2, pred);
4039 }
4040
4041 /* Elide 2 or more consecutive numeric keysyms bound to the same thing,
4042    or 2 or more symbolic keysyms that are bound to the same thing and
4043    have consecutive character-set-properties.
4044  */
4045 static int
4046 elide_next_two_p (Lisp_Object list)
4047 {
4048   Lisp_Object s1, s2;
4049
4050   if (NILP (XCDR (list)))
4051     return 0;
4052
4053   /* next two bindings differ */
4054   if (!EQ (XCDR (XCAR (list)),
4055            XCDR (XCAR (XCDR (list)))))
4056     return 0;
4057
4058   /* next two modifier-sets differ */
4059   if (!EQ (XCDR (XCAR (XCAR (list))),
4060            XCDR (XCAR (XCAR (XCDR (list))))))
4061     return 0;
4062
4063   s1 = XCAR (XCAR (XCAR (list)));
4064   s2 = XCAR (XCAR (XCAR (XCDR (list))));
4065
4066   if (SYMBOLP (s1))
4067     {
4068       Lisp_Object code = Fget (s1, Vcharacter_set_property, Qnil);
4069       if (CHAR_OR_CHAR_INTP (code))
4070         {
4071           s1 = code;
4072           CHECK_CHAR_COERCE_INT (s1);
4073         }
4074       else return 0;
4075     }
4076   if (SYMBOLP (s2))
4077     {
4078       Lisp_Object code = Fget (s2, Vcharacter_set_property, Qnil);
4079       if (CHAR_OR_CHAR_INTP (code))
4080         {
4081           s2 = code;
4082           CHECK_CHAR_COERCE_INT (s2);
4083         }
4084       else return 0;
4085     }
4086
4087   return (XCHAR (s1)     == XCHAR (s2) ||
4088           XCHAR (s1) + 1 == XCHAR (s2));
4089 }
4090
4091
4092 static Lisp_Object
4093 describe_map_parent_mapper (Lisp_Object keymap, void *arg)
4094 {
4095   /* This function can GC */
4096   struct describe_map_closure *describe_map_closure =
4097     (struct describe_map_closure *) arg;
4098   describe_map_closure->self = keymap;
4099   map_keymap (XKEYMAP (keymap)->table,
4100               0, /* don't sort: we'll do it later */
4101               describe_map_mapper, describe_map_closure);
4102   return Qnil;
4103 }
4104
4105
4106 /* Describe the contents of map MAP, assuming that this map itself is
4107    reached by the sequence of prefix keys KEYS (a string or vector).
4108    PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above.  */
4109
4110 static void
4111 describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
4112               void (*elt_describer) (Lisp_Object, Lisp_Object),
4113               int partial,
4114               Lisp_Object shadow,
4115               int mice_only_p,
4116               Lisp_Object buffer)
4117 {
4118   /* This function can GC */
4119   struct describe_map_closure describe_map_closure;
4120   Lisp_Object list = Qnil;
4121   struct buffer *buf = XBUFFER (buffer);
4122   Emchar printable_min = (CHAR_OR_CHAR_INTP (buf->ctl_arrow)
4123                           ? XCHAR_OR_CHAR_INT (buf->ctl_arrow)
4124                           : ((EQ (buf->ctl_arrow, Qt)
4125                               || EQ (buf->ctl_arrow, Qnil))
4126                              ? 256 : 160));
4127   int elided = 0;
4128   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4129
4130   keymap = get_keymap (keymap, 1, 1);
4131   describe_map_closure.partial = (partial ? Qsuppress_keymap : Qnil);
4132   describe_map_closure.shadow = shadow;
4133   describe_map_closure.list = &list;
4134   describe_map_closure.self_root = keymap;
4135   describe_map_closure.mice_only_p = mice_only_p;
4136
4137   GCPRO4 (keymap, elt_prefix, shadow, list);
4138
4139   traverse_keymaps (keymap, Qnil,
4140                     describe_map_parent_mapper, &describe_map_closure);
4141
4142   if (!NILP (list))
4143     {
4144       list = list_sort (list, Qnil, describe_map_sort_predicate);
4145       buffer_insert_c_string (buf, "\n");
4146       while (!NILP (list))
4147         {
4148           Lisp_Object elt = XCAR (XCAR (list));
4149           Lisp_Object keysym = XCAR (elt);
4150           int modifiers = XINT (XCDR (elt));
4151
4152           if (!NILP (elt_prefix))
4153             buffer_insert_lisp_string (buf, elt_prefix);
4154
4155           if (modifiers & XEMACS_MOD_META)
4156             buffer_insert_c_string (buf, "M-");
4157           if (modifiers & XEMACS_MOD_CONTROL)
4158             buffer_insert_c_string (buf, "C-");
4159           if (modifiers & XEMACS_MOD_SUPER)
4160             buffer_insert_c_string (buf, "S-");
4161           if (modifiers & XEMACS_MOD_HYPER)
4162             buffer_insert_c_string (buf, "H-");
4163           if (modifiers & XEMACS_MOD_ALT)
4164             buffer_insert_c_string (buf, "Alt-");
4165           if (modifiers & XEMACS_MOD_SHIFT)
4166             buffer_insert_c_string (buf, "Sh-");
4167           if (SYMBOLP (keysym))
4168             {
4169               Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
4170               Emchar c = (CHAR_OR_CHAR_INTP (code)
4171                           ? XCHAR_OR_CHAR_INT (code) : (Emchar) -1);
4172               /* Calling Fsingle_key_description() would cons more */
4173 #if 0                           /* This is bogus */
4174               if (EQ (keysym, QKlinefeed))
4175                 buffer_insert_c_string (buf, "LFD");
4176               else if (EQ (keysym, QKtab))
4177                 buffer_insert_c_string (buf, "TAB");
4178               else if (EQ (keysym, QKreturn))
4179                 buffer_insert_c_string (buf, "RET");
4180               else if (EQ (keysym, QKescape))
4181                 buffer_insert_c_string (buf, "ESC");
4182               else if (EQ (keysym, QKdelete))
4183                 buffer_insert_c_string (buf, "DEL");
4184               else if (EQ (keysym, QKspace))
4185                 buffer_insert_c_string (buf, "SPC");
4186               else if (EQ (keysym, QKbackspace))
4187                 buffer_insert_c_string (buf, "BS");
4188               else
4189 #endif
4190                 if (c >= printable_min)
4191                   buffer_insert_emacs_char (buf, c);
4192                 else buffer_insert1 (buf, Fsymbol_name (keysym));
4193             }
4194           else if (CHARP (keysym))
4195             buffer_insert_emacs_char (buf, XCHAR (keysym));
4196           else
4197             buffer_insert_c_string (buf, "---bad keysym---");
4198
4199           if (elided)
4200             elided = 0;
4201           else
4202             {
4203               int k = 0;
4204
4205               while (elide_next_two_p (list))
4206                 {
4207                   k++;
4208                   list = XCDR (list);
4209                 }
4210               if (k != 0)
4211                 {
4212                   if (k == 1)
4213                     buffer_insert_c_string (buf, ", ");
4214                   else
4215                     buffer_insert_c_string (buf, " .. ");
4216                   elided = 1;
4217                   continue;
4218                 }
4219             }
4220
4221           /* Print a description of the definition of this character.  */
4222           (*elt_describer) (XCDR (XCAR (list)), buffer);
4223           list = XCDR (list);
4224         }
4225     }
4226   UNGCPRO;
4227 }
4228
4229 \f
4230 void
4231 syms_of_keymap (void)
4232 {
4233   INIT_LRECORD_IMPLEMENTATION (keymap);
4234
4235   defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist");
4236
4237   defsymbol (&Qkeymapp, "keymapp");
4238
4239   defsymbol (&Qsuppress_keymap, "suppress-keymap");
4240
4241   defsymbol (&Qmodeline_map, "modeline-map");
4242   defsymbol (&Qtoolbar_map, "toolbar-map");
4243
4244   DEFSUBR (Fkeymap_parents);
4245   DEFSUBR (Fset_keymap_parents);
4246   DEFSUBR (Fkeymap_name);
4247   DEFSUBR (Fset_keymap_name);
4248   DEFSUBR (Fkeymap_prompt);
4249   DEFSUBR (Fset_keymap_prompt);
4250   DEFSUBR (Fkeymap_default_binding);
4251   DEFSUBR (Fset_keymap_default_binding);
4252
4253   DEFSUBR (Fkeymapp);
4254   DEFSUBR (Fmake_keymap);
4255   DEFSUBR (Fmake_sparse_keymap);
4256
4257   DEFSUBR (Fcopy_keymap);
4258   DEFSUBR (Fkeymap_fullness);
4259   DEFSUBR (Fmap_keymap);
4260   DEFSUBR (Fevent_matches_key_specifier_p);
4261   DEFSUBR (Fdefine_key);
4262   DEFSUBR (Flookup_key);
4263   DEFSUBR (Fkey_binding);
4264   DEFSUBR (Fuse_global_map);
4265   DEFSUBR (Fuse_local_map);
4266   DEFSUBR (Fcurrent_local_map);
4267   DEFSUBR (Fcurrent_global_map);
4268   DEFSUBR (Fcurrent_keymaps);
4269   DEFSUBR (Faccessible_keymaps);
4270   DEFSUBR (Fkey_description);
4271   DEFSUBR (Fsingle_key_description);
4272   DEFSUBR (Fwhere_is_internal);
4273   DEFSUBR (Fdescribe_bindings_internal);
4274
4275   DEFSUBR (Ftext_char_description);
4276
4277   defsymbol (&Qcontrol, "control");
4278   defsymbol (&Qctrl, "ctrl");
4279   defsymbol (&Qmeta, "meta");
4280   defsymbol (&Qsuper, "super");
4281   defsymbol (&Qhyper, "hyper");
4282   defsymbol (&Qalt, "alt");
4283   defsymbol (&Qshift, "shift");
4284   defsymbol (&Qbutton0, "button0");
4285   defsymbol (&Qbutton1, "button1");
4286   defsymbol (&Qbutton2, "button2");
4287   defsymbol (&Qbutton3, "button3");
4288   defsymbol (&Qbutton4, "button4");
4289   defsymbol (&Qbutton5, "button5");
4290   defsymbol (&Qbutton6, "button6");
4291   defsymbol (&Qbutton7, "button7");
4292   defsymbol (&Qbutton0up, "button0up");
4293   defsymbol (&Qbutton1up, "button1up");
4294   defsymbol (&Qbutton2up, "button2up");
4295   defsymbol (&Qbutton3up, "button3up");
4296   defsymbol (&Qbutton4up, "button4up");
4297   defsymbol (&Qbutton5up, "button5up");
4298   defsymbol (&Qbutton6up, "button6up");
4299   defsymbol (&Qbutton7up, "button7up");
4300   defsymbol (&Qmouse_1, "mouse-1");
4301   defsymbol (&Qmouse_2, "mouse-2");
4302   defsymbol (&Qmouse_3, "mouse-3");
4303   defsymbol (&Qmouse_4, "mouse-4");
4304   defsymbol (&Qmouse_5, "mouse-5");
4305   defsymbol (&Qmouse_6, "mouse-6");
4306   defsymbol (&Qmouse_7, "mouse-7");
4307   defsymbol (&Qdown_mouse_1, "down-mouse-1");
4308   defsymbol (&Qdown_mouse_2, "down-mouse-2");
4309   defsymbol (&Qdown_mouse_3, "down-mouse-3");
4310   defsymbol (&Qdown_mouse_4, "down-mouse-4");
4311   defsymbol (&Qdown_mouse_5, "down-mouse-5");
4312   defsymbol (&Qdown_mouse_6, "down-mouse-6");
4313   defsymbol (&Qdown_mouse_7, "down-mouse-7");
4314   defsymbol (&Qmenu_selection, "menu-selection");
4315   defsymbol (&QLFD, "LFD");
4316   defsymbol (&QTAB, "TAB");
4317   defsymbol (&QRET, "RET");
4318   defsymbol (&QESC, "ESC");
4319   defsymbol (&QDEL, "DEL");
4320   defsymbol (&QSPC, "SPC");
4321   defsymbol (&QBS, "BS");
4322 }
4323
4324 void
4325 vars_of_keymap (void)
4326 {
4327   DEFVAR_LISP ("meta-prefix-char", &Vmeta_prefix_char /*
4328 Meta-prefix character.
4329 This character followed by some character `foo' turns into `Meta-foo'.
4330 This can be any form recognized as a single key specifier.
4331 To disable the meta-prefix-char, set it to a negative number.
4332 */ );
4333   Vmeta_prefix_char = make_char (033);
4334
4335   DEFVAR_LISP ("mouse-grabbed-buffer", &Vmouse_grabbed_buffer /*
4336 A buffer which should be consulted first for all mouse activity.
4337 When a mouse-click is processed, it will first be looked up in the
4338 local-map of this buffer, and then through the normal mechanism if there
4339 is no binding for that click.  This buffer's value of `mode-motion-hook'
4340 will be consulted instead of the `mode-motion-hook' of the buffer of the
4341 window under the mouse.  You should *bind* this, not set it.
4342 */ );
4343   Vmouse_grabbed_buffer = Qnil;
4344
4345   DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map /*
4346 Keymap that overrides all other local keymaps.
4347 If this variable is non-nil, it is used as a keymap instead of the
4348 buffer's local map, and the minor mode keymaps and extent-local keymaps.
4349 You should *bind* this, not set it.
4350 */ );
4351   Voverriding_local_map = Qnil;
4352
4353   Fset (Qminor_mode_map_alist, Qnil);
4354
4355   DEFVAR_LISP ("key-translation-map", &Vkey_translation_map /*
4356 Keymap of key translations that can override keymaps.
4357 This keymap works like `function-key-map', but comes after that,
4358 and applies even for keys that have ordinary bindings.
4359 */ );
4360   Vkey_translation_map = Qnil;
4361
4362   DEFVAR_LISP ("vertical-divider-map", &Vvertical_divider_map /*
4363 Keymap which handles mouse clicks over vertical dividers.
4364 */ );
4365   Vvertical_divider_map = Qnil;
4366
4367   DEFVAR_INT ("keymap-tick", &keymap_tick /*
4368 Incremented for each change to any keymap.
4369 */ );
4370   keymap_tick = 0;
4371
4372   staticpro (&Vcurrent_global_map);
4373
4374   Vsingle_space_string = make_string ((const Bufbyte *) " ", 1);
4375   staticpro (&Vsingle_space_string);
4376 }
4377
4378 void
4379 complex_vars_of_keymap (void)
4380 {
4381   /* This function can GC */
4382   Lisp_Object ESC_prefix = intern ("ESC-prefix");
4383   Lisp_Object meta_disgustitute;
4384
4385   Vcurrent_global_map = Fmake_keymap (Qnil);
4386
4387   meta_disgustitute = Fmake_keymap (Qnil);
4388   Ffset (ESC_prefix, meta_disgustitute);
4389   /* no need to protect meta_disgustitute, though */
4390   keymap_store_internal (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META),
4391                          XKEYMAP (Vcurrent_global_map),
4392                          meta_disgustitute);
4393   XKEYMAP (Vcurrent_global_map)->sub_maps_cache = Qt;
4394
4395   Vkey_translation_map = Fmake_sparse_keymap (intern ("key-translation-map"));
4396 }