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