comparison src/keymap.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents b8cc9ab3f761
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
35 #include "events.h" 35 #include "events.h"
36 #include "frame.h" 36 #include "frame.h"
37 #include "insdel.h" 37 #include "insdel.h"
38 #include "keymap.h" 38 #include "keymap.h"
39 #include "window.h" 39 #include "window.h"
40
41 #ifdef WINDOWSNT
42 /* Hmm, under unix we want X modifiers, under NT we want X modifiers if
43 we are running X and Windows modifiers otherwise.
44 gak. This is a kludge until we support multiple native GUIs!
45 */
46 #undef MOD_ALT
47 #undef MOD_CONTROL
48 #undef MOD_SHIFT
49 #endif
50
40 #include "events-mod.h" 51 #include "events-mod.h"
41 52
42 53
43 /* A keymap contains six slots: 54 /* A keymap contains six slots:
44 55
86 off of the main map. The hash key for a modifier combination is 97 off of the main map. The hash key for a modifier combination is
87 an integer, computed by MAKE_MODIFIER_HASH_KEY(). 98 an integer, computed by MAKE_MODIFIER_HASH_KEY().
88 99
89 If the key `C-a' was bound to some command, the hierarchy would look like 100 If the key `C-a' was bound to some command, the hierarchy would look like
90 101
91 keymap-1: associates the integer XEMACS_MOD_CONTROL with keymap-2 102 keymap-1: associates the integer MOD_CONTROL with keymap-2
92 keymap-2: associates "a" with the command 103 keymap-2: associates "a" with the command
93 104
94 Similarly, if the key `C-H-a' was bound to some command, the hierarchy 105 Similarly, if the key `C-H-a' was bound to some command, the hierarchy
95 would look like 106 would look like
96 107
97 keymap-1: associates the integer (XEMACS_MOD_CONTROL | XEMACS_MOD_HYPER) 108 keymap-1: associates the integer (MOD_CONTROL | MOD_HYPER)
98 with keymap-2 109 with keymap-2
99 keymap-2: associates "a" with the command 110 keymap-2: associates "a" with the command
100 111
101 Note that a special exception is made for the meta modifier, in order 112 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 113 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 114 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 115 submap (with hash key MOD_META) and then indexed off of the
105 meta submap with the meta modifier removed from the key combination. 116 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 117 For example, when associating a command with C-M-H-a, we'd have
107 118
108 keymap-1: associates the integer XEMACS_MOD_META with keymap-2 119 keymap-1: associates the integer MOD_META with keymap-2
109 keymap-2: associates the integer (XEMACS_MOD_CONTROL | XEMACS_MOD_HYPER) 120 keymap-2: associates the integer (MOD_CONTROL | MOD_HYPER)
110 with keymap-3 121 with keymap-3
111 keymap-3: associates "a" with the command 122 keymap-3: associates "a" with the command
112 123
113 Note that keymap-2 might have normal bindings in it; these would be 124 Note that keymap-2 might have normal bindings in it; these would be
114 for key combinations containing only the meta modifier, such as 125 for key combinations containing only the meta modifier, such as
118 then that would make the key "C-M-H-a" be a prefix character. 129 then that would make the key "C-M-H-a" be a prefix character.
119 130
120 Note that this new model of keymaps takes much of the magic away from 131 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 132 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 133 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" 134 MOD_META. This is not user-visible, however; none of the "bucky"
124 maps are. 135 maps are.
125 136
126 There is a hack in Flookup_key() that makes (lookup-key global-map "\^[") 137 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 138 and (define-key some-random-map "\^[" my-esc-map) work as before, for
128 compatibility. 139 compatibility.
129 140
130 Since keymaps are opaque, the only way to extract information from them 141 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 142 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 143 global-key-binding, which work just as before, and the new function
133 map-keymap, which is roughly analogous to maphash. 144 map-keymap, which is roughly analagous to maphash.
134 145
135 Note that map-keymap perpetuates the illusion that the "bucky" submaps 146 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 147 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 148 map over those submaps. It does not, however, map over other random
138 submaps of the keymap, just the bucky ones. 149 submaps of the keymap, just the bucky ones.
143 distinction between ESC and "meta" even more. "M-x" is no more a two- 154 distinction between ESC and "meta" even more. "M-x" is no more a two-
144 key sequence than "C-x" is. 155 key sequence than "C-x" is.
145 156
146 */ 157 */
147 158
148 struct Lisp_Keymap 159 typedef struct Lisp_Keymap
149 { 160 {
150 struct lcrecord_header header; 161 struct lcrecord_header header;
151 Lisp_Object parents; /* Keymaps to be searched after this one. 162 Lisp_Object parents; /* Keymaps to be searched after this one
152 An ordered list */ 163 * An ordered list */
153 Lisp_Object prompt; /* Qnil or a string to print in the minibuffer 164 Lisp_Object prompt; /* Qnil or a string to print in the minibuffer
154 when reading from this keymap */ 165 * when reading from this keymap */
166
155 Lisp_Object table; /* The contents of this keymap */ 167 Lisp_Object table; /* The contents of this keymap */
156 Lisp_Object inverse_table; /* The inverse mapping of the above */ 168 Lisp_Object inverse_table; /* The inverse mapping of the above */
169
157 Lisp_Object default_binding; /* Use this if no other binding is found 170 Lisp_Object default_binding; /* Use this if no other binding is found
158 (this overrides parent maps and the 171 * (this overrides parent maps and the
159 normal global-map lookup). */ 172 * normal global-map lookup). */
173
174
160 Lisp_Object sub_maps_cache; /* Cache of directly inferior keymaps; 175 Lisp_Object sub_maps_cache; /* Cache of directly inferior keymaps;
161 This holds an alist, of the key and the 176 This holds an alist, of the key and the
162 maps, or the modifier bit and the map. 177 maps, or the modifier bit and the map.
163 If this is the symbol t, then the cache 178 If this is the symbol t, then the cache
164 needs to be recomputed. */ 179 needs to be recomputed.
180 */
181 int fullness; /* How many entries there are in this table.
182 This should be the same as the fullness
183 of the `table', but hash.c is broken. */
165 Lisp_Object name; /* Just for debugging convenience */ 184 Lisp_Object name; /* Just for debugging convenience */
166 }; 185 } Lisp_Keymap;
167 186
168 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier) 187 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier)
169 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0) 188 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0)
170 189
171 190
172 191
173 /* Actually allocate storage for these variables */ 192 /* Actually allocate storage for these variables */
174 193
175 Lisp_Object Vcurrent_global_map; /* Always a keymap */ 194 static Lisp_Object Vcurrent_global_map; /* Always a keymap */
176 195
177 static Lisp_Object Vmouse_grabbed_buffer; 196 static Lisp_Object Vmouse_grabbed_buffer;
178 197
179 /* Alist of minor mode variables and keymaps. */ 198 /* Alist of minor mode variables and keymaps. */
180 static Lisp_Object Qminor_mode_map_alist; 199 static Lisp_Object Qminor_mode_map_alist;
209 void (*elt_describer) (Lisp_Object, Lisp_Object), 228 void (*elt_describer) (Lisp_Object, Lisp_Object),
210 int partial, 229 int partial,
211 Lisp_Object shadow, 230 Lisp_Object shadow,
212 int mice_only_p, 231 int mice_only_p,
213 Lisp_Object buffer); 232 Lisp_Object buffer);
214 static Lisp_Object keymap_submaps (Lisp_Object keymap);
215 233
216 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift; 234 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift;
217 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3; 235 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3;
218 Lisp_Object Qbutton4, Qbutton5, Qbutton6, Qbutton7; 236 Lisp_Object Qbutton4, Qbutton5, Qbutton6, Qbutton7;
219 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up; 237 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up;
232 /************************************************************************/ 250 /************************************************************************/
233 /* The keymap Lisp object */ 251 /* The keymap Lisp object */
234 /************************************************************************/ 252 /************************************************************************/
235 253
236 static Lisp_Object 254 static Lisp_Object
237 mark_keymap (Lisp_Object obj) 255 mark_keymap (Lisp_Object obj, void (*markobj) (Lisp_Object))
238 { 256 {
239 Lisp_Keymap *keymap = XKEYMAP (obj); 257 Lisp_Keymap *keymap = XKEYMAP (obj);
240 mark_object (keymap->parents); 258 markobj (keymap->parents);
241 mark_object (keymap->prompt); 259 markobj (keymap->prompt);
242 mark_object (keymap->inverse_table); 260 markobj (keymap->inverse_table);
243 mark_object (keymap->sub_maps_cache); 261 markobj (keymap->sub_maps_cache);
244 mark_object (keymap->default_binding); 262 markobj (keymap->default_binding);
245 mark_object (keymap->name); 263 markobj (keymap->name);
246 return keymap->table; 264 return keymap->table;
247 } 265 }
248 266
249 static void 267 static void
250 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 268 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
251 { 269 {
252 /* This function can GC */ 270 /* This function can GC */
253 Lisp_Keymap *keymap = XKEYMAP (obj); 271 Lisp_Keymap *keymap = XKEYMAP (obj);
254 char buf[200]; 272 char buf[200];
273 int size = XINT (Fkeymap_fullness (obj));
255 if (print_readably) 274 if (print_readably)
256 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid); 275 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid);
257 write_c_string ("#<keymap ", printcharfun); 276 write_c_string ("#<keymap ", printcharfun);
258 if (!NILP (keymap->name)) 277 if (!NILP (keymap->name))
259 { 278 print_internal (keymap->name, printcharfun, 1);
260 print_internal (keymap->name, printcharfun, 1); 279 /* #### Yuck! This is no way to form plural! --hniksic */
261 write_c_string (" ", printcharfun); 280 sprintf (buf, "%s%d entr%s 0x%x>",
262 } 281 ((NILP (keymap->name)) ? "" : " "),
263 sprintf (buf, "size %ld 0x%x>", 282 size,
264 (long) XINT (Fkeymap_fullness (obj)), keymap->header.uid); 283 ((size == 1) ? "y" : "ies"),
284 keymap->header.uid);
265 write_c_string (buf, printcharfun); 285 write_c_string (buf, printcharfun);
266 } 286 }
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 287
279 /* No need for keymap_equal #### Why not? */ 288 /* No need for keymap_equal #### Why not? */
280 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap, 289 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
281 mark_keymap, print_keymap, 0, 0, 0, 290 mark_keymap, print_keymap, 0, 0, 0,
282 keymap_description,
283 Lisp_Keymap); 291 Lisp_Keymap);
284 292
285 /************************************************************************/ 293 /************************************************************************/
286 /* Traversing keymaps and their parents */ 294 /* Traversing keymaps and their parents */
287 /************************************************************************/ 295 /************************************************************************/
302 gcpro1.nvars = 0; 310 gcpro1.nvars = 0;
303 311
304 start_keymap = get_keymap (start_keymap, 1, 1); 312 start_keymap = get_keymap (start_keymap, 1, 1);
305 keymap = start_keymap; 313 keymap = start_keymap;
306 /* Hack special-case parents at top-level */ 314 /* Hack special-case parents at top-level */
307 tail = !NILP (tail) ? tail : XKEYMAP (keymap)->parents; 315 tail = ((!NILP (tail)) ? tail : XKEYMAP (keymap)->parents);
308 316
309 for (;;) 317 for (;;)
310 { 318 {
311 Lisp_Object result; 319 Lisp_Object result;
312 320
313 QUIT; 321 QUIT;
314 result = mapper (keymap, mapper_arg); 322 result = ((mapper) (keymap, mapper_arg));
315 if (!NILP (result)) 323 if (!NILP (result))
316 { 324 {
317 while (CONSP (malloc_bites)) 325 while (CONSP (malloc_bites))
318 { 326 {
319 Lisp_Cons *victim = XCONS (malloc_bites); 327 struct Lisp_Cons *victim = XCONS (malloc_bites);
320 malloc_bites = victim->cdr; 328 malloc_bites = victim->cdr;
321 free_cons (victim); 329 free_cons (victim);
322 } 330 }
323 UNGCPRO; 331 UNGCPRO;
324 return result; 332 return result;
331 return Qnil; /* Nothing found */ 339 return Qnil; /* Nothing found */
332 } 340 }
333 stack_depth--; 341 stack_depth--;
334 if (CONSP (malloc_bites)) 342 if (CONSP (malloc_bites))
335 { 343 {
336 Lisp_Cons *victim = XCONS (malloc_bites); 344 struct Lisp_Cons *victim = XCONS (malloc_bites);
337 tail = victim->car; 345 tail = victim->car;
338 malloc_bites = victim->cdr; 346 malloc_bites = victim->cdr;
339 free_cons (victim); 347 free_cons (victim);
340 } 348 }
341 else 349 else
393 401
394 /************************************************************************/ 402 /************************************************************************/
395 /* Some low-level functions */ 403 /* Some low-level functions */
396 /************************************************************************/ 404 /************************************************************************/
397 405
398 static int 406 static unsigned int
399 bucky_sym_to_bucky_bit (Lisp_Object sym) 407 bucky_sym_to_bucky_bit (Lisp_Object sym)
400 { 408 {
401 if (EQ (sym, Qcontrol)) return XEMACS_MOD_CONTROL; 409 if (EQ (sym, Qcontrol)) return MOD_CONTROL;
402 if (EQ (sym, Qmeta)) return XEMACS_MOD_META; 410 if (EQ (sym, Qmeta)) return MOD_META;
403 if (EQ (sym, Qsuper)) return XEMACS_MOD_SUPER; 411 if (EQ (sym, Qsuper)) return MOD_SUPER;
404 if (EQ (sym, Qhyper)) return XEMACS_MOD_HYPER; 412 if (EQ (sym, Qhyper)) return MOD_HYPER;
405 if (EQ (sym, Qalt)) return XEMACS_MOD_ALT; 413 if (EQ (sym, Qalt)) return MOD_ALT;
406 if (EQ (sym, Qsymbol)) return XEMACS_MOD_ALT; /* #### - reverse compat */ 414 if (EQ (sym, Qsymbol)) return MOD_ALT; /* #### - reverse compat */
407 if (EQ (sym, Qshift)) return XEMACS_MOD_SHIFT; 415 if (EQ (sym, Qshift)) return MOD_SHIFT;
408 416
409 return 0; 417 return 0;
410 } 418 }
411 419
412 static Lisp_Object 420 static Lisp_Object
413 control_meta_superify (Lisp_Object frob, int modifiers) 421 control_meta_superify (Lisp_Object frob, unsigned int modifiers)
414 { 422 {
415 if (modifiers == 0) 423 if (modifiers == 0)
416 return frob; 424 return frob;
417 frob = Fcons (frob, Qnil); 425 frob = Fcons (frob, Qnil);
418 if (modifiers & XEMACS_MOD_SHIFT) frob = Fcons (Qshift, frob); 426 if (modifiers & MOD_SHIFT) frob = Fcons (Qshift, frob);
419 if (modifiers & XEMACS_MOD_ALT) frob = Fcons (Qalt, frob); 427 if (modifiers & MOD_ALT) frob = Fcons (Qalt, frob);
420 if (modifiers & XEMACS_MOD_HYPER) frob = Fcons (Qhyper, frob); 428 if (modifiers & MOD_HYPER) frob = Fcons (Qhyper, frob);
421 if (modifiers & XEMACS_MOD_SUPER) frob = Fcons (Qsuper, frob); 429 if (modifiers & MOD_SUPER) frob = Fcons (Qsuper, frob);
422 if (modifiers & XEMACS_MOD_CONTROL) frob = Fcons (Qcontrol, frob); 430 if (modifiers & MOD_CONTROL) frob = Fcons (Qcontrol, frob);
423 if (modifiers & XEMACS_MOD_META) frob = Fcons (Qmeta, frob); 431 if (modifiers & MOD_META) frob = Fcons (Qmeta, frob);
424 return frob; 432 return frob;
425 } 433 }
426 434
427 static Lisp_Object 435 static Lisp_Object
428 make_key_description (const struct key_data *key, int prettify) 436 make_key_description (CONST struct key_data *key, int prettify)
429 { 437 {
430 Lisp_Object keysym = key->keysym; 438 Lisp_Object keysym = key->keysym;
431 int modifiers = key->modifiers; 439 unsigned int modifiers = key->modifiers;
432 440
433 if (prettify && CHARP (keysym)) 441 if (prettify && CHARP (keysym))
434 { 442 {
435 /* This is a little slow, but (control a) is prettier than (control 65). 443 /* 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 444 It's now ok to do this for digit-chars too, since we've fixed the
451 /* Low-level keymap-store functions */ 459 /* Low-level keymap-store functions */
452 /************************************************************************/ 460 /************************************************************************/
453 461
454 static Lisp_Object 462 static Lisp_Object
455 raw_lookup_key (Lisp_Object keymap, 463 raw_lookup_key (Lisp_Object keymap,
456 const struct key_data *raw_keys, int raw_keys_count, 464 CONST struct key_data *raw_keys, int raw_keys_count,
457 int keys_so_far, int accept_default); 465 int keys_so_far, int accept_default);
458 466
459 /* Relies on caller to gc-protect args */ 467 /* Relies on caller to gc-protect args */
460 static Lisp_Object 468 static Lisp_Object
461 keymap_lookup_directly (Lisp_Object keymap, 469 keymap_lookup_directly (Lisp_Object keymap,
462 Lisp_Object keysym, int modifiers) 470 Lisp_Object keysym, unsigned int modifiers)
463 { 471 {
464 Lisp_Keymap *k; 472 Lisp_Keymap *k;
465 473
466 if ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META | XEMACS_MOD_SUPER | XEMACS_MOD_HYPER 474 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
467 | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT)) != 0) 475 | MOD_ALT | MOD_SHIFT)) != 0)
468 abort (); 476 abort ();
469 477
470 k = XKEYMAP (keymap); 478 k = XKEYMAP (keymap);
471 479
472 /* If the keysym is a one-character symbol, use the char code instead. */ 480 /* If the keysym is a one-character symbol, use the char code instead. */
475 Lisp_Object i_fart_on_gcc = 483 Lisp_Object i_fart_on_gcc =
476 make_char (string_char (XSYMBOL (keysym)->name, 0)); 484 make_char (string_char (XSYMBOL (keysym)->name, 0));
477 keysym = i_fart_on_gcc; 485 keysym = i_fart_on_gcc;
478 } 486 }
479 487
480 if (modifiers & XEMACS_MOD_META) /* Utterly hateful ESC lossage */ 488 if (modifiers & MOD_META) /* Utterly hateful ESC lossage */
481 { 489 {
482 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META), 490 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META),
483 k->table, Qnil); 491 k->table, Qnil);
484 if (NILP (submap)) 492 if (NILP (submap))
485 return Qnil; 493 return Qnil;
486 k = XKEYMAP (submap); 494 k = XKEYMAP (submap);
487 modifiers &= ~XEMACS_MOD_META; 495 modifiers &= ~MOD_META;
488 } 496 }
489 497
490 if (modifiers != 0) 498 if (modifiers != 0)
491 { 499 {
492 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers), 500 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers),
566 /* else the list's tail has been modified, so we don't need to 574 /* 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). 575 touch the hash table again (the pointer in there is ok).
568 */ 576 */
569 } 577 }
570 578
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 579
592 static void 580 static void
593 keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap, 581 keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap,
594 Lisp_Object def) 582 Lisp_Object value)
595 { 583 {
596 Lisp_Object prev_def = Fgethash (keysym, keymap->table, Qnil); 584 Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil);
597 585
598 if (EQ (prev_def, def)) 586 if (EQ (prev_value, value))
599 return; 587 return;
600 588 if (!NILP (prev_value))
601 check_keymap_definition_loop (def, keymap);
602
603 if (!NILP (prev_def))
604 keymap_delete_inverse_internal (keymap->inverse_table, 589 keymap_delete_inverse_internal (keymap->inverse_table,
605 keysym, prev_def); 590 keysym, prev_value);
606 if (NILP (def)) 591 if (NILP (value))
607 { 592 {
593 keymap->fullness--;
594 if (keymap->fullness < 0) abort ();
608 Fremhash (keysym, keymap->table); 595 Fremhash (keysym, keymap->table);
609 } 596 }
610 else 597 else
611 { 598 {
612 Fputhash (keysym, def, keymap->table); 599 if (NILP (prev_value))
600 keymap->fullness++;
601 Fputhash (keysym, value, keymap->table);
613 keymap_store_inverse_internal (keymap->inverse_table, 602 keymap_store_inverse_internal (keymap->inverse_table,
614 keysym, def); 603 keysym, value);
615 } 604 }
616 keymap_tick++; 605 keymap_tick++;
617 } 606 }
618 607
619 608
620 static Lisp_Object 609 static Lisp_Object
621 create_bucky_submap (Lisp_Keymap *k, int modifiers, 610 create_bucky_submap (Lisp_Keymap *k, unsigned int modifiers,
622 Lisp_Object parent_for_debugging_info) 611 Lisp_Object parent_for_debugging_info)
623 { 612 {
624 Lisp_Object submap = Fmake_sparse_keymap (Qnil); 613 Lisp_Object submap = Fmake_sparse_keymap (Qnil);
625 /* User won't see this, but it is nice for debugging Emacs */ 614 /* User won't see this, but it is nice for debugging Emacs */
626 XKEYMAP (submap)->name 615 XKEYMAP (submap)->name
632 } 621 }
633 622
634 623
635 /* Relies on caller to gc-protect keymap, keysym, value */ 624 /* Relies on caller to gc-protect keymap, keysym, value */
636 static void 625 static void
637 keymap_store (Lisp_Object keymap, const struct key_data *key, 626 keymap_store (Lisp_Object keymap, CONST struct key_data *key,
638 Lisp_Object value) 627 Lisp_Object value)
639 { 628 {
640 Lisp_Object keysym = key->keysym; 629 Lisp_Object keysym = key->keysym;
641 int modifiers = key->modifiers; 630 unsigned int modifiers = key->modifiers;
642 Lisp_Keymap *k = XKEYMAP (keymap); 631 Lisp_Keymap *k;
643 632
644 assert ((modifiers & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_META 633 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
645 | XEMACS_MOD_SUPER | XEMACS_MOD_HYPER 634 | MOD_ALT | MOD_SHIFT)) != 0)
646 | XEMACS_MOD_ALT | XEMACS_MOD_SHIFT)) == 0); 635 abort ();
636
637 k = XKEYMAP (keymap);
647 638
648 /* If the keysym is a one-character symbol, use the char code instead. */ 639 /* If the keysym is a one-character symbol, use the char code instead. */
649 if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1) 640 if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1)
650 keysym = make_char (string_char (XSYMBOL (keysym)->name, 0)); 641 {
651 642 Lisp_Object run_the_gcc_developers_over_with_a_steamroller =
652 if (modifiers & XEMACS_MOD_META) /* Utterly hateful ESC lossage */ 643 make_char (string_char (XSYMBOL (keysym)->name, 0));
653 { 644 keysym = run_the_gcc_developers_over_with_a_steamroller;
654 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META), 645 }
646
647 if (modifiers & MOD_META) /* Utterly hateful ESC lossage */
648 {
649 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META),
655 k->table, Qnil); 650 k->table, Qnil);
656 if (NILP (submap)) 651 if (NILP (submap))
657 submap = create_bucky_submap (k, XEMACS_MOD_META, keymap); 652 submap = create_bucky_submap (k, MOD_META, keymap);
658 k = XKEYMAP (submap); 653 k = XKEYMAP (submap);
659 modifiers &= ~XEMACS_MOD_META; 654 modifiers &= ~MOD_META;
660 } 655 }
661 656
662 if (modifiers != 0) 657 if (modifiers != 0)
663 { 658 {
664 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers), 659 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers),
755 keymap->prompt = Qnil; 750 keymap->prompt = Qnil;
756 keymap->table = Qnil; 751 keymap->table = Qnil;
757 keymap->inverse_table = Qnil; 752 keymap->inverse_table = Qnil;
758 keymap->default_binding = Qnil; 753 keymap->default_binding = Qnil;
759 keymap->sub_maps_cache = Qnil; /* No possible submaps */ 754 keymap->sub_maps_cache = Qnil; /* No possible submaps */
755 keymap->fullness = 0;
760 keymap->name = Qnil; 756 keymap->name = Qnil;
761 757
762 if (size != 0) /* hack for copy-keymap */ 758 if (size != 0) /* hack for copy-keymap */
763 { 759 {
764 keymap->table = 760 keymap->table =
1046 { 1042 {
1047 Lisp_Object idx = Fcdr (object); 1043 Lisp_Object idx = Fcdr (object);
1048 struct key_data indirection; 1044 struct key_data indirection;
1049 if (CHARP (idx)) 1045 if (CHARP (idx))
1050 { 1046 {
1051 Lisp_Event event; 1047 struct Lisp_Event event;
1052 event.event_type = empty_event; 1048 event.event_type = empty_event;
1053 character_to_event (XCHAR (idx), &event, 1049 character_to_event (XCHAR (idx), &event,
1054 XCONSOLE (Vselected_console), 0, 0); 1050 XCONSOLE (Vselected_console), 0, 0);
1055 indirection = event.event.key; 1051 indirection = event.event.key;
1056 } 1052 }
1057 else if (CONSP (idx)) 1053 else if (CONSP (idx))
1058 { 1054 {
1059 if (!INTP (XCDR (idx))) 1055 if (!INTP (XCDR (idx)))
1060 return Qnil; 1056 return Qnil;
1061 indirection.keysym = XCAR (idx); 1057 indirection.keysym = XCAR (idx);
1062 indirection.modifiers = (unsigned char) XINT (XCDR (idx)); 1058 indirection.modifiers = XINT (XCDR (idx));
1063 } 1059 }
1064 else if (SYMBOLP (idx)) 1060 else if (SYMBOLP (idx))
1065 { 1061 {
1066 indirection.keysym = idx; 1062 indirection.keysym = idx;
1067 indirection.modifiers = 0; 1063 indirection.modifiers = 0;
1088 return object; 1084 return object;
1089 } 1085 }
1090 } 1086 }
1091 1087
1092 static Lisp_Object 1088 static Lisp_Object
1093 keymap_lookup_1 (Lisp_Object keymap, const struct key_data *key, 1089 keymap_lookup_1 (Lisp_Object keymap, CONST struct key_data *key,
1094 int accept_default) 1090 int accept_default)
1095 { 1091 {
1096 /* This function can GC */ 1092 /* This function can GC */
1097 return get_keyelt (keymap_lookup_directly (keymap, 1093 return get_keyelt (keymap_lookup_directly (keymap,
1098 key->keysym, key->modifiers), 1094 key->keysym, key->modifiers),
1132 Lisp_Keymap *new_keymap = XKEYMAP (nkm); 1128 Lisp_Keymap *new_keymap = XKEYMAP (nkm);
1133 struct copy_keymap_inverse_closure copy_keymap_inverse_closure; 1129 struct copy_keymap_inverse_closure copy_keymap_inverse_closure;
1134 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table; 1130 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table;
1135 1131
1136 new_keymap->parents = Fcopy_sequence (keymap->parents); 1132 new_keymap->parents = Fcopy_sequence (keymap->parents);
1133 new_keymap->fullness = keymap->fullness;
1137 new_keymap->sub_maps_cache = Qnil; /* No submaps */ 1134 new_keymap->sub_maps_cache = Qnil; /* No submaps */
1138 new_keymap->table = Fcopy_hash_table (keymap->table); 1135 new_keymap->table = Fcopy_hash_table (keymap->table);
1139 new_keymap->inverse_table = Fcopy_hash_table (keymap->inverse_table); 1136 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 1137 /* 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. 1138 are its values, lest they be shared by the copy, and mangled.
1143 */ 1139 */
1144 elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table, 1140 elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table,
1145 &copy_keymap_inverse_closure); 1141 &copy_keymap_inverse_closure);
1209 int fullness; 1205 int fullness;
1210 Lisp_Object sub_maps; 1206 Lisp_Object sub_maps;
1211 struct gcpro gcpro1, gcpro2; 1207 struct gcpro gcpro1, gcpro2;
1212 1208
1213 keymap = get_keymap (keymap, 1, 1); 1209 keymap = get_keymap (keymap, 1, 1);
1214 fullness = XINT (Fhash_table_count (XKEYMAP (keymap)->table)); 1210 fullness = XKEYMAP (keymap)->fullness;
1211 sub_maps = keymap_submaps (keymap);
1215 GCPRO2 (keymap, sub_maps); 1212 GCPRO2 (keymap, sub_maps);
1216 for (sub_maps = keymap_submaps (keymap); 1213 for (; !NILP (sub_maps); sub_maps = XCDR (sub_maps))
1217 !NILP (sub_maps);
1218 sub_maps = XCDR (sub_maps))
1219 { 1214 {
1220 if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0) 1215 if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0)
1221 { 1216 {
1222 Lisp_Object bucky_map = XCDR (XCAR (sub_maps)); 1217 Lisp_Object sub_map = XCDR (XCAR (sub_maps));
1223 fullness--; /* don't count bucky maps themselves. */ 1218 fullness--; /* don't count bucky maps */
1224 fullness += keymap_fullness (bucky_map); 1219 fullness += keymap_fullness (sub_map);
1225 } 1220 }
1226 } 1221 }
1227 UNGCPRO; 1222 UNGCPRO;
1228 return fullness; 1223 return fullness;
1229 } 1224 }
1246 and perform any necessary canonicalization. */ 1241 and perform any necessary canonicalization. */
1247 1242
1248 static void 1243 static void
1249 define_key_check_and_coerce_keysym (Lisp_Object spec, 1244 define_key_check_and_coerce_keysym (Lisp_Object spec,
1250 Lisp_Object *keysym, 1245 Lisp_Object *keysym,
1251 int modifiers) 1246 unsigned int modifiers)
1252 { 1247 {
1253 /* Now, check and massage the trailing keysym specifier. */ 1248 /* Now, check and massage the trailing keysym specifier. */
1254 if (SYMBOLP (*keysym)) 1249 if (SYMBOLP (*keysym))
1255 { 1250 {
1256 if (string_char_length (XSYMBOL (*keysym)->name) == 1) 1251 if (string_char_length (XSYMBOL (*keysym)->name) == 1)
1269 /* || (XCHAR (*keysym) >= 128 && XCHAR (*keysym) < 160) */) 1264 /* || (XCHAR (*keysym) >= 128 && XCHAR (*keysym) < 160) */)
1270 /* yuck! Can't make the above restriction; too many compatibility 1265 /* yuck! Can't make the above restriction; too many compatibility
1271 problems ... */ 1266 problems ... */
1272 signal_simple_error ("keysym char must be printable", *keysym); 1267 signal_simple_error ("keysym char must be printable", *keysym);
1273 /* #### This bites! I want to be able to write (control shift a) */ 1268 /* #### This bites! I want to be able to write (control shift a) */
1274 if (modifiers & XEMACS_MOD_SHIFT) 1269 if (modifiers & MOD_SHIFT)
1275 signal_simple_error 1270 signal_simple_error
1276 ("The `shift' modifier may not be applied to ASCII keysyms", 1271 ("The `shift' modifier may not be applied to ASCII keysyms",
1277 spec); 1272 spec);
1278 } 1273 }
1279 else 1274 else
1280 { 1275 {
1281 signal_simple_error ("Unknown keysym specifier", *keysym); 1276 signal_simple_error ("Unknown keysym specifier",
1277 *keysym);
1282 } 1278 }
1283 1279
1284 if (SYMBOLP (*keysym)) 1280 if (SYMBOLP (*keysym))
1285 { 1281 {
1286 char *name = (char *) string_data (XSYMBOL (*keysym)->name); 1282 char *name = (char *)
1283 string_data (XSYMBOL (*keysym)->name);
1287 1284
1288 /* FSFmacs uses symbols with the printed representation of keysyms in 1285 /* 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 1286 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 1287 confusion, notice the M-x syntax and signal an error - because
1291 otherwise it would be interpreted as a regular keysym, and would even 1288 otherwise it would be interpreted as a regular keysym, and would even
1344 *keysym = QKreturn; 1341 *keysym = QKreturn;
1345 else if (EQ (*keysym, QESC)) 1342 else if (EQ (*keysym, QESC))
1346 *keysym = QKescape; 1343 *keysym = QKescape;
1347 else if (EQ (*keysym, QDEL)) 1344 else if (EQ (*keysym, QDEL))
1348 *keysym = QKdelete; 1345 *keysym = QKdelete;
1349 else if (EQ (*keysym, QSPC))
1350 *keysym = QKspace;
1351 else if (EQ (*keysym, QBS)) 1346 else if (EQ (*keysym, QBS))
1352 *keysym = QKbackspace; 1347 *keysym = QKbackspace;
1353 /* Emacs compatibility */ 1348 /* Emacs compatibility */
1354 else if (EQ(*keysym, Qdown_mouse_1)) 1349 else if (EQ(*keysym, Qdown_mouse_1))
1355 *keysym = Qbutton1; 1350 *keysym = Qbutton1;
1385 static void 1380 static void
1386 define_key_parser (Lisp_Object spec, struct key_data *returned_value) 1381 define_key_parser (Lisp_Object spec, struct key_data *returned_value)
1387 { 1382 {
1388 if (CHAR_OR_CHAR_INTP (spec)) 1383 if (CHAR_OR_CHAR_INTP (spec))
1389 { 1384 {
1390 Lisp_Event event; 1385 struct Lisp_Event event;
1391 event.event_type = empty_event; 1386 event.event_type = empty_event;
1392 character_to_event (XCHAR_OR_CHAR_INT (spec), &event, 1387 character_to_event (XCHAR_OR_CHAR_INT (spec), &event,
1393 XCONSOLE (Vselected_console), 0, 0); 1388 XCONSOLE (Vselected_console), 0, 0);
1394 returned_value->keysym = event.event.key.keysym; 1389 returned_value->keysym = event.event.key.keysym;
1395 returned_value->modifiers = event.event.key.modifiers; 1390 returned_value->modifiers = event.event.key.modifiers;
1446 returned_value->keysym = spec; 1441 returned_value->keysym = spec;
1447 returned_value->modifiers = 0; 1442 returned_value->modifiers = 0;
1448 } 1443 }
1449 else if (CONSP (spec)) 1444 else if (CONSP (spec))
1450 { 1445 {
1451 int modifiers = 0; 1446 unsigned int modifiers = 0;
1452 Lisp_Object keysym = Qnil; 1447 Lisp_Object keysym = Qnil;
1453 Lisp_Object rest = spec; 1448 Lisp_Object rest = spec;
1454 1449
1455 /* First, parse out the leading modifier symbols. */ 1450 /* First, parse out the leading modifier symbols. */
1456 while (CONSP (rest)) 1451 while (CONSP (rest))
1457 { 1452 {
1458 int modifier; 1453 unsigned int modifier;
1459 1454
1460 keysym = XCAR (rest); 1455 keysym = XCAR (rest);
1461 modifier = bucky_sym_to_bucky_bit (keysym); 1456 modifier = bucky_sym_to_bucky_bit (keysym);
1462 modifiers |= modifier; 1457 modifiers |= modifier;
1463 if (!NILP (XCDR (rest))) 1458 if (!NILP (XCDR (rest)))
1533 XEVENT (event)->event.key.modifiers = raw_key.modifiers; 1528 XEVENT (event)->event.key.modifiers = raw_key.modifiers;
1534 } 1529 }
1535 1530
1536 1531
1537 int 1532 int
1538 event_matches_key_specifier_p (Lisp_Event *event, Lisp_Object key_specifier) 1533 event_matches_key_specifier_p (struct Lisp_Event *event,
1534 Lisp_Object key_specifier)
1539 { 1535 {
1540 Lisp_Object event2; 1536 Lisp_Object event2;
1541 int retval; 1537 int retval;
1542 struct gcpro gcpro1; 1538 struct gcpro gcpro1;
1543 1539
1584 UNGCPRO; 1580 UNGCPRO;
1585 return retval; 1581 return retval;
1586 } 1582 }
1587 1583
1588 static int 1584 static int
1589 meta_prefix_char_p (const struct key_data *key) 1585 meta_prefix_char_p (CONST struct key_data *key)
1590 { 1586 {
1591 Lisp_Event event; 1587 struct Lisp_Event event;
1592 1588
1593 event.event_type = key_press_event; 1589 event.event_type = key_press_event;
1594 event.channel = Vselected_console; 1590 event.channel = Vselected_console;
1595 event.event.key.keysym = key->keysym; 1591 event.event.key.keysym = key->keysym;
1596 event.event.key.modifiers = key->modifiers; 1592 event.event.key.modifiers = key->modifiers;
1623 static void 1619 static void
1624 define_key_alternate_name (struct key_data *key, 1620 define_key_alternate_name (struct key_data *key,
1625 struct key_data *returned_value) 1621 struct key_data *returned_value)
1626 { 1622 {
1627 Lisp_Object keysym = key->keysym; 1623 Lisp_Object keysym = key->keysym;
1628 int modifiers = key->modifiers; 1624 unsigned int modifiers = key->modifiers;
1629 int modifiers_sans_control = (modifiers & (~XEMACS_MOD_CONTROL)); 1625 unsigned int modifiers_sans_control = (modifiers & (~MOD_CONTROL));
1630 int modifiers_sans_meta = (modifiers & (~XEMACS_MOD_META)); 1626 unsigned int modifiers_sans_meta = (modifiers & (~MOD_META));
1631 returned_value->keysym = Qnil; /* By default, no "alternate" key */ 1627 returned_value->keysym = Qnil; /* By default, no "alternate" key */
1632 returned_value->modifiers = 0; 1628 returned_value->modifiers = 0;
1633 if (modifiers_sans_meta == XEMACS_MOD_CONTROL) 1629 if (modifiers_sans_meta == MOD_CONTROL)
1634 { 1630 {
1635 if EQ (keysym, QKspace) 1631 if EQ (keysym, QKspace)
1636 MACROLET (make_char ('@'), modifiers); 1632 MACROLET (make_char ('@'), modifiers);
1637 else if (!CHARP (keysym)) 1633 else if (!CHARP (keysym))
1638 return; 1634 return;
1655 } 1651 }
1656 } 1652 }
1657 else if (modifiers_sans_meta != 0) 1653 else if (modifiers_sans_meta != 0)
1658 return; 1654 return;
1659 else if (EQ (keysym, QKbackspace)) /* backspace => c-h */ 1655 else if (EQ (keysym, QKbackspace)) /* backspace => c-h */
1660 MACROLET (make_char ('h'), (modifiers | XEMACS_MOD_CONTROL)); 1656 MACROLET (make_char ('h'), (modifiers | MOD_CONTROL));
1661 else if (EQ (keysym, QKtab)) /* tab => c-i */ 1657 else if (EQ (keysym, QKtab)) /* tab => c-i */
1662 MACROLET (make_char ('i'), (modifiers | XEMACS_MOD_CONTROL)); 1658 MACROLET (make_char ('i'), (modifiers | MOD_CONTROL));
1663 else if (EQ (keysym, QKlinefeed)) /* linefeed => c-j */ 1659 else if (EQ (keysym, QKlinefeed)) /* linefeed => c-j */
1664 MACROLET (make_char ('j'), (modifiers | XEMACS_MOD_CONTROL)); 1660 MACROLET (make_char ('j'), (modifiers | MOD_CONTROL));
1665 else if (EQ (keysym, QKreturn)) /* return => c-m */ 1661 else if (EQ (keysym, QKreturn)) /* return => c-m */
1666 MACROLET (make_char ('m'), (modifiers | XEMACS_MOD_CONTROL)); 1662 MACROLET (make_char ('m'), (modifiers | MOD_CONTROL));
1667 else if (EQ (keysym, QKescape)) /* escape => c-[ */ 1663 else if (EQ (keysym, QKescape)) /* escape => c-[ */
1668 MACROLET (make_char ('['), (modifiers | XEMACS_MOD_CONTROL)); 1664 MACROLET (make_char ('['), (modifiers | MOD_CONTROL));
1669 else 1665 else
1670 return; 1666 return;
1671 #undef MACROLET 1667 #undef MACROLET
1672 } 1668 }
1673 1669
1892 (define-key my-map "\M-a" 'my-command) 1888 (define-key my-map "\M-a" 'my-command)
1893 and then perhaps 1889 and then perhaps
1894 (defvar my-escape-map (lookup-key my-map "\e")) 1890 (defvar my-escape-map (lookup-key my-map "\e"))
1895 if the luser really wants the map in a variable. 1891 if the luser really wants the map in a variable.
1896 */ 1892 */
1897 Lisp_Object meta_map; 1893 Lisp_Object mmap;
1898 struct gcpro ngcpro1; 1894 struct gcpro ngcpro1;
1899 1895
1900 NGCPRO1 (c); 1896 NGCPRO1 (c);
1901 meta_map = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META), 1897 mmap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META),
1902 XKEYMAP (keymap)->table, Qnil); 1898 XKEYMAP (keymap)->table, Qnil);
1903 if (!NILP (meta_map) 1899 if (!NILP (mmap)
1904 && keymap_fullness (meta_map) != 0) 1900 && keymap_fullness (mmap) != 0)
1905 signal_simple_error_2 1901 {
1906 ("Map contains meta-bindings, can't bind", 1902 Lisp_Object desc
1907 Fsingle_key_description (Vmeta_prefix_char), keymap); 1903 = Fsingle_key_description (Vmeta_prefix_char);
1904 signal_simple_error_2
1905 ("Map contains meta-bindings, can't bind", desc, keymap);
1906 }
1908 NUNGCPRO; 1907 NUNGCPRO;
1909 } 1908 }
1910 else 1909 else
1911 { 1910 {
1912 metized = 1; 1911 metized = 1;
1923 raw_key2.modifiers = 0; 1922 raw_key2.modifiers = 0;
1924 } 1923 }
1925 1924
1926 if (metized) 1925 if (metized)
1927 { 1926 {
1928 raw_key1.modifiers |= XEMACS_MOD_META; 1927 raw_key1.modifiers |= MOD_META;
1929 raw_key2.modifiers |= XEMACS_MOD_META; 1928 raw_key2.modifiers |= MOD_META;
1930 metized = 0; 1929 metized = 0;
1931 } 1930 }
1932 1931
1933 /* This crap is to make sure that someone doesn't bind something like 1932 /* 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. */ 1933 "C-x M-a" while "C-x ESC" has a non-keymap binding. */
1935 if (raw_key1.modifiers & XEMACS_MOD_META) 1934 if (raw_key1.modifiers & MOD_META)
1936 ensure_meta_prefix_char_keymapp (keys, idx, keymap); 1935 ensure_meta_prefix_char_keymapp (keys, idx, keymap);
1937 1936
1938 if (++idx == len) 1937 if (++idx == len)
1939 { 1938 {
1940 keymap_store (keymap, &raw_key1, def); 1939 keymap_store (keymap, &raw_key1, def);
1980 to make where-is-internal really fly. */ 1979 to make where-is-internal really fly. */
1981 1980
1982 struct raw_lookup_key_mapper_closure 1981 struct raw_lookup_key_mapper_closure
1983 { 1982 {
1984 int remaining; 1983 int remaining;
1985 const struct key_data *raw_keys; 1984 CONST struct key_data *raw_keys;
1986 int raw_keys_count; 1985 int raw_keys_count;
1987 int keys_so_far; 1986 int keys_so_far;
1988 int accept_default; 1987 int accept_default;
1989 }; 1988 };
1990 1989
1991 static Lisp_Object raw_lookup_key_mapper (Lisp_Object k, void *); 1990 static Lisp_Object raw_lookup_key_mapper (Lisp_Object k, void *);
1992 1991
1993 /* Caller should gc-protect args (keymaps may autoload) */ 1992 /* Caller should gc-protect args (keymaps may autoload) */
1994 static Lisp_Object 1993 static Lisp_Object
1995 raw_lookup_key (Lisp_Object keymap, 1994 raw_lookup_key (Lisp_Object keymap,
1996 const struct key_data *raw_keys, int raw_keys_count, 1995 CONST struct key_data *raw_keys, int raw_keys_count,
1997 int keys_so_far, int accept_default) 1996 int keys_so_far, int accept_default)
1998 { 1997 {
1999 /* This function can GC */ 1998 /* This function can GC */
2000 struct raw_lookup_key_mapper_closure c; 1999 struct raw_lookup_key_mapper_closure c;
2001 c.remaining = raw_keys_count - 1; 2000 c.remaining = raw_keys_count - 1;
2014 struct raw_lookup_key_mapper_closure *c = 2013 struct raw_lookup_key_mapper_closure *c =
2015 (struct raw_lookup_key_mapper_closure *) arg; 2014 (struct raw_lookup_key_mapper_closure *) arg;
2016 int accept_default = c->accept_default; 2015 int accept_default = c->accept_default;
2017 int remaining = c->remaining; 2016 int remaining = c->remaining;
2018 int keys_so_far = c->keys_so_far; 2017 int keys_so_far = c->keys_so_far;
2019 const struct key_data *raw_keys = c->raw_keys; 2018 CONST struct key_data *raw_keys = c->raw_keys;
2020 Lisp_Object cmd; 2019 Lisp_Object cmd;
2021 2020
2022 if (! meta_prefix_char_p (&(raw_keys[0]))) 2021 if (! meta_prefix_char_p (&(raw_keys[0])))
2023 { 2022 {
2024 /* Normal case: every case except the meta-hack (see below). */ 2023 /* Normal case: every case except the meta-hack (see below). */
2053 /* First look for the prefix-char directly */ 2052 /* First look for the prefix-char directly */
2054 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default); 2053 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default);
2055 if (NILP (cmd)) 2054 if (NILP (cmd))
2056 { 2055 {
2057 /* Do kludgy return of the meta-map */ 2056 /* Do kludgy return of the meta-map */
2058 cmd = Fgethash (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META), 2057 cmd = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META),
2059 XKEYMAP (k)->table, Qnil); 2058 XKEYMAP (k)->table, Qnil);
2060 } 2059 }
2061 } 2060 }
2062 else 2061 else
2063 { 2062 {
2065 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default); 2064 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default);
2066 cmd = get_keymap (cmd, 0, 1); 2065 cmd = get_keymap (cmd, 0, 1);
2067 if (!NILP (cmd)) 2066 if (!NILP (cmd))
2068 cmd = raw_lookup_key (cmd, raw_keys + 1, remaining, 2067 cmd = raw_lookup_key (cmd, raw_keys + 1, remaining,
2069 keys_so_far + 1, accept_default); 2068 keys_so_far + 1, accept_default);
2070 else if ((raw_keys[1].modifiers & XEMACS_MOD_META) == 0) 2069 else if ((raw_keys[1].modifiers & MOD_META) == 0)
2071 { 2070 {
2072 struct key_data metified; 2071 struct key_data metified;
2073 metified.keysym = raw_keys[1].keysym; 2072 metified.keysym = raw_keys[1].keysym;
2074 metified.modifiers = raw_keys[1].modifiers | 2073 metified.modifiers = raw_keys[1].modifiers | MOD_META;
2075 (unsigned char) XEMACS_MOD_META;
2076 2074
2077 /* Search for meta-next-char sequence directly */ 2075 /* Search for meta-next-char sequence directly */
2078 cmd = keymap_lookup_1 (k, &metified, accept_default); 2076 cmd = keymap_lookup_1 (k, &metified, accept_default);
2079 if (remaining == 1) 2077 if (remaining == 1)
2080 ; 2078 ;
2106 int i; 2104 int i;
2107 2105
2108 if (nkeys == 0) 2106 if (nkeys == 0)
2109 return Qnil; 2107 return Qnil;
2110 2108
2111 if (nkeys < countof (kkk)) 2109 if (nkeys < (countof (kkk)))
2112 raw_keys = kkk; 2110 raw_keys = kkk;
2113 else 2111 else
2114 raw_keys = alloca_array (struct key_data, nkeys); 2112 raw_keys = alloca_array (struct key_data, nkeys);
2115 2113
2116 for (i = 0; i < nkeys; i++) 2114 for (i = 0; i < nkeys; i++)
2136 2134
2137 CHECK_LIVE_EVENT (event_head); 2135 CHECK_LIVE_EVENT (event_head);
2138 2136
2139 nkeys = event_chain_count (event_head); 2137 nkeys = event_chain_count (event_head);
2140 2138
2141 if (nkeys < countof (kkk)) 2139 if (nkeys < (countof (kkk)))
2142 raw_keys = kkk; 2140 raw_keys = kkk;
2143 else 2141 else
2144 raw_keys = alloca_array (struct key_data, nkeys); 2142 raw_keys = alloca_array (struct key_data, nkeys);
2145 2143
2146 nkeys = 0; 2144 nkeys = 0;
2362 buffer); 2360 buffer);
2363 2361
2364 get_relevant_extent_keymaps 2362 get_relevant_extent_keymaps
2365 (Fevent_modeline_position (terminal), 2363 (Fevent_modeline_position (terminal),
2366 XBUFFER (buffer)->generated_modeline_string, 2364 XBUFFER (buffer)->generated_modeline_string,
2367 Fevent_glyph_extent (terminal), &closure); 2365 /* #### third arg should maybe be a glyph. */
2366 Qnil, &closure);
2368 2367
2369 if (!UNBOUNDP (map) && !NILP (map)) 2368 if (!UNBOUNDP (map) && !NILP (map))
2370 relevant_map_push (get_keymap (map, 1, 1), &closure); 2369 relevant_map_push (get_keymap (map, 1, 1), &closure);
2371 } 2370 }
2372 else 2371 else
2730 outside of this file doesn't need to know about. 2729 outside of this file doesn't need to know about.
2731 */ 2730 */
2732 2731
2733 struct map_keymap_unsorted_closure 2732 struct map_keymap_unsorted_closure
2734 { 2733 {
2735 void (*fn) (const struct key_data *, Lisp_Object binding, void *arg); 2734 void (*fn) (CONST struct key_data *, Lisp_Object binding, void *arg);
2736 void *arg; 2735 void *arg;
2737 int modifiers; 2736 unsigned int modifiers;
2738 }; 2737 };
2739 2738
2740 /* used by map_keymap() */ 2739 /* used by map_keymap() */
2741 static int 2740 static int
2742 map_keymap_unsorted_mapper (Lisp_Object keysym, Lisp_Object value, 2741 map_keymap_unsorted_mapper (Lisp_Object keysym, Lisp_Object value,
2743 void *map_keymap_unsorted_closure) 2742 void *map_keymap_unsorted_closure)
2744 { 2743 {
2745 /* This function can GC */ 2744 /* This function can GC */
2746 struct map_keymap_unsorted_closure *closure = 2745 struct map_keymap_unsorted_closure *closure =
2747 (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure; 2746 (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure;
2748 int modifiers = closure->modifiers; 2747 unsigned int modifiers = closure->modifiers;
2749 int mod_bit; 2748 unsigned int mod_bit;
2750 mod_bit = MODIFIER_HASH_KEY_BITS (keysym); 2749 mod_bit = MODIFIER_HASH_KEY_BITS (keysym);
2751 if (mod_bit != 0) 2750 if (mod_bit != 0)
2752 { 2751 {
2753 int omod = modifiers; 2752 int omod = modifiers;
2754 closure->modifiers = (modifiers | mod_bit); 2753 closure->modifiers = (modifiers | mod_bit);
2794 map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, 2793 map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
2795 Lisp_Object pred) 2794 Lisp_Object pred)
2796 { 2795 {
2797 /* obj1 and obj2 are conses with keysyms in their cars. Cdrs are ignored. 2796 /* obj1 and obj2 are conses with keysyms in their cars. Cdrs are ignored.
2798 */ 2797 */
2799 int bit1, bit2; 2798 unsigned int bit1, bit2;
2800 int sym1_p = 0; 2799 int sym1_p = 0;
2801 int sym2_p = 0; 2800 int sym2_p = 0;
2802 obj1 = XCAR (obj1); 2801 obj1 = XCAR (obj1);
2803 obj2 = XCAR (obj2); 2802 obj2 = XCAR (obj2);
2804 2803
2868 2867
2869 2868
2870 /* used by map_keymap() */ 2869 /* used by map_keymap() */
2871 static void 2870 static void
2872 map_keymap_sorted (Lisp_Object keymap_table, 2871 map_keymap_sorted (Lisp_Object keymap_table,
2873 int modifiers, 2872 unsigned int modifiers,
2874 void (*function) (const struct key_data *key, 2873 void (*function) (CONST struct key_data *key,
2875 Lisp_Object binding, 2874 Lisp_Object binding,
2876 void *map_keymap_sorted_closure), 2875 void *map_keymap_sorted_closure),
2877 void *map_keymap_sorted_closure) 2876 void *map_keymap_sorted_closure)
2878 { 2877 {
2879 /* This function can GC */ 2878 /* This function can GC */
2893 contents = list_sort (contents, Qnil, map_keymap_sort_predicate); 2892 contents = list_sort (contents, Qnil, map_keymap_sort_predicate);
2894 for (; !NILP (contents); contents = XCDR (contents)) 2893 for (; !NILP (contents); contents = XCDR (contents))
2895 { 2894 {
2896 Lisp_Object keysym = XCAR (XCAR (contents)); 2895 Lisp_Object keysym = XCAR (XCAR (contents));
2897 Lisp_Object binding = XCDR (XCAR (contents)); 2896 Lisp_Object binding = XCDR (XCAR (contents));
2898 int sub_bits = MODIFIER_HASH_KEY_BITS (keysym); 2897 unsigned int sub_bits = MODIFIER_HASH_KEY_BITS (keysym);
2899 if (sub_bits != 0) 2898 if (sub_bits != 0)
2900 map_keymap_sorted (XKEYMAP (get_keymap (binding, 2899 map_keymap_sorted (XKEYMAP (get_keymap (binding,
2901 1, 1))->table, 2900 1, 1))->table,
2902 (modifiers | sub_bits), 2901 (modifiers | sub_bits),
2903 function, 2902 function,
2914 } 2913 }
2915 2914
2916 2915
2917 /* used by Fmap_keymap() */ 2916 /* used by Fmap_keymap() */
2918 static void 2917 static void
2919 map_keymap_mapper (const struct key_data *key, 2918 map_keymap_mapper (CONST struct key_data *key,
2920 Lisp_Object binding, 2919 Lisp_Object binding,
2921 void *function) 2920 void *function)
2922 { 2921 {
2923 /* This function can GC */ 2922 /* This function can GC */
2924 Lisp_Object fn; 2923 Lisp_Object fn;
2927 } 2926 }
2928 2927
2929 2928
2930 static void 2929 static void
2931 map_keymap (Lisp_Object keymap_table, int sort_first, 2930 map_keymap (Lisp_Object keymap_table, int sort_first,
2932 void (*function) (const struct key_data *key, 2931 void (*function) (CONST struct key_data *key,
2933 Lisp_Object binding, 2932 Lisp_Object binding,
2934 void *fn_arg), 2933 void *fn_arg),
2935 void *fn_arg) 2934 void *fn_arg)
2936 { 2935 {
2937 /* This function can GC */ 2936 /* This function can GC */
2999 }; 2998 };
3000 2999
3001 3000
3002 static void 3001 static void
3003 accessible_keymaps_mapper_1 (Lisp_Object keysym, Lisp_Object contents, 3002 accessible_keymaps_mapper_1 (Lisp_Object keysym, Lisp_Object contents,
3004 int modifiers, 3003 unsigned int modifiers,
3005 struct accessible_keymaps_closure *closure) 3004 struct accessible_keymaps_closure *closure)
3006 { 3005 {
3007 /* This function can GC */ 3006 /* This function can GC */
3008 int subbits = MODIFIER_HASH_KEY_BITS (keysym); 3007 unsigned int subbits = MODIFIER_HASH_KEY_BITS (keysym);
3009 3008
3010 if (subbits != 0) 3009 if (subbits != 0)
3011 { 3010 {
3012 Lisp_Object submaps; 3011 Lisp_Object submaps;
3013 3012
3083 Lisp_Object accessible_keymaps = Qnil; 3082 Lisp_Object accessible_keymaps = Qnil;
3084 struct accessible_keymaps_closure c; 3083 struct accessible_keymaps_closure c;
3085 c.tail = Qnil; 3084 c.tail = Qnil;
3086 GCPRO4 (accessible_keymaps, c.tail, prefix, keymap); 3085 GCPRO4 (accessible_keymaps, c.tail, prefix, keymap);
3087 3086
3087 retry:
3088 keymap = get_keymap (keymap, 1, 1); 3088 keymap = get_keymap (keymap, 1, 1);
3089
3090 retry:
3091 if (NILP (prefix)) 3089 if (NILP (prefix))
3092 { 3090 prefix = make_vector (0, Qnil);
3093 prefix = make_vector (0, Qnil); 3091 else if (!VECTORP (prefix) || STRINGP (prefix))
3094 } 3092 {
3095 else if (VECTORP (prefix) || STRINGP (prefix)) 3093 prefix = wrong_type_argument (Qarrayp, prefix);
3094 goto retry;
3095 }
3096 else
3096 { 3097 {
3097 int len = XINT (Flength (prefix)); 3098 int len = XINT (Flength (prefix));
3098 Lisp_Object def; 3099 Lisp_Object def = Flookup_key (keymap, prefix, Qnil);
3099 Lisp_Object p; 3100 Lisp_Object p;
3100 int iii; 3101 int iii;
3101 struct gcpro ngcpro1; 3102 struct gcpro ngcpro1;
3102 3103
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); 3104 def = get_keymap (def, 0, 1);
3111 if (!KEYMAPP (def)) 3105 if (!KEYMAPP (def))
3112 goto RETURN; 3106 goto RETURN;
3113 3107
3114 keymap = def; 3108 keymap = def;
3121 XVECTOR_DATA (p)[iii] = make_key_description (&key, 1); 3115 XVECTOR_DATA (p)[iii] = make_key_description (&key, 1);
3122 } 3116 }
3123 NUNGCPRO; 3117 NUNGCPRO;
3124 prefix = p; 3118 prefix = p;
3125 } 3119 }
3126 else
3127 {
3128 prefix = wrong_type_argument (Qarrayp, prefix);
3129 goto retry;
3130 }
3131 3120
3132 accessible_keymaps = list1 (Fcons (prefix, keymap)); 3121 accessible_keymaps = list1 (Fcons (prefix, keymap));
3133 3122
3134 /* For each map in the list maps, look at any other maps it points 3123 /* For each map in the list maps,
3135 to and stick them at the end if they are not already in the list */ 3124 look at any other maps it points to
3125 and stick them at the end if they are not already in the list */
3136 3126
3137 for (c.tail = accessible_keymaps; 3127 for (c.tail = accessible_keymaps;
3138 !NILP (c.tail); 3128 !NILP (c.tail);
3139 c.tail = XCDR (c.tail)) 3129 c.tail = XCDR (c.tail))
3140 { 3130 {
3175 int i; 3165 int i;
3176 3166
3177 for (i = 0; i < size; i++) 3167 for (i = 0; i < size; i++)
3178 { 3168 {
3179 Lisp_Object s2 = Fsingle_key_description 3169 Lisp_Object s2 = Fsingle_key_description
3180 (STRINGP (keys) 3170 (((STRINGP (keys))
3181 ? make_char (string_char (XSTRING (keys), i)) 3171 ? make_char (string_char (XSTRING (keys), i))
3182 : XVECTOR_DATA (keys)[i]); 3172 : XVECTOR_DATA (keys)[i]));
3183 3173
3184 if (i == 0) 3174 if (i == 0)
3185 string = s2; 3175 string = s2;
3186 else 3176 else
3187 { 3177 {
3208 if (EVENTP (key) || CHAR_OR_CHAR_INTP (key)) 3198 if (EVENTP (key) || CHAR_OR_CHAR_INTP (key))
3209 { 3199 {
3210 char buf [255]; 3200 char buf [255];
3211 if (!EVENTP (key)) 3201 if (!EVENTP (key))
3212 { 3202 {
3213 Lisp_Event event; 3203 struct Lisp_Event event;
3214 event.event_type = empty_event; 3204 event.event_type = empty_event;
3215 CHECK_CHAR_COERCE_INT (key); 3205 CHECK_CHAR_COERCE_INT (key);
3216 character_to_event (XCHAR (key), &event, 3206 character_to_event (XCHAR (key), &event,
3217 XCONSOLE (Vselected_console), 0, 1); 3207 XCONSOLE (Vselected_console), 0, 1);
3218 format_event_object (buf, &event, 1); 3208 format_event_object (buf, &event, 1);
3457 3447
3458 static void 3448 static void
3459 format_raw_keys (struct key_data *keys, int count, char *buf) 3449 format_raw_keys (struct key_data *keys, int count, char *buf)
3460 { 3450 {
3461 int i; 3451 int i;
3462 Lisp_Event event; 3452 struct Lisp_Event event;
3463 event.event_type = key_press_event; 3453 event.event_type = key_press_event;
3464 event.channel = Vselected_console; 3454 event.channel = Vselected_console;
3465 for (i = 0; i < count; i++) 3455 for (i = 0; i < count; i++)
3466 { 3456 {
3467 event.event.key.keysym = keys[i].keysym; 3457 event.event.key.keysym = keys[i].keysym;
3481 returning, then we reconsider. 3471 returning, then we reconsider.
3482 firstonly means give up after finding the first match; 3472 firstonly means give up after finding the first match;
3483 keys_so_far and modifiers_so_far describe which map we're looking in; 3473 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, 3474 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 3475 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 3476 will be 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) 3477 have followed, and modifiers_so_far_so_far is the bits (partial keys)
3488 beyond that. 3478 beyond that.
3489 3479
3490 (keys_so_far is a global buffer and the keys_count arg says how much 3480 (keys_so_far is a global buffer and the keys_count arg says how much
3491 of it we're currently interested in.) 3481 of it we're currently interested in.)
3499 Lisp_Object definition; 3489 Lisp_Object definition;
3500 Lisp_Object *shadow; 3490 Lisp_Object *shadow;
3501 int shadow_count; 3491 int shadow_count;
3502 int firstonly; 3492 int firstonly;
3503 int keys_count; 3493 int keys_count;
3504 int modifiers_so_far; 3494 unsigned int modifiers_so_far;
3505 char *target_buffer; 3495 char *target_buffer;
3506 struct key_data *keys_so_far; 3496 struct key_data *keys_so_far;
3507 int keys_so_far_total_size; 3497 int keys_so_far_total_size;
3508 int keys_so_far_malloced; 3498 int keys_so_far_malloced;
3509 }; 3499 };
3514 where_is_recursive_mapper (Lisp_Object map, void *arg) 3504 where_is_recursive_mapper (Lisp_Object map, void *arg)
3515 { 3505 {
3516 /* This function can GC */ 3506 /* This function can GC */
3517 struct where_is_closure *c = (struct where_is_closure *) arg; 3507 struct where_is_closure *c = (struct where_is_closure *) arg;
3518 Lisp_Object definition = c->definition; 3508 Lisp_Object definition = c->definition;
3519 const int firstonly = c->firstonly; 3509 CONST int firstonly = c->firstonly;
3520 const int keys_count = c->keys_count; 3510 CONST unsigned int keys_count = c->keys_count;
3521 const int modifiers_so_far = c->modifiers_so_far; 3511 CONST unsigned int modifiers_so_far = c->modifiers_so_far;
3522 char *target_buffer = c->target_buffer; 3512 char *target_buffer = c->target_buffer;
3523 Lisp_Object keys = Fgethash (definition, 3513 Lisp_Object keys = Fgethash (definition,
3524 XKEYMAP (map)->inverse_table, 3514 XKEYMAP (map)->inverse_table,
3525 Qnil); 3515 Qnil);
3526 Lisp_Object submaps; 3516 Lisp_Object submaps;
3534 raw_lookup_key() means undefined. */ 3524 raw_lookup_key() means undefined. */
3535 struct key_data *so_far = c->keys_so_far; 3525 struct key_data *so_far = c->keys_so_far;
3536 3526
3537 for (;;) /* loop over all keys that match */ 3527 for (;;) /* loop over all keys that match */
3538 { 3528 {
3539 Lisp_Object k = CONSP (keys) ? XCAR (keys) : keys; 3529 Lisp_Object k = ((CONSP (keys)) ? XCAR (keys) : keys);
3540 int i; 3530 int i;
3541 3531
3542 so_far [keys_count].keysym = k; 3532 so_far [keys_count].keysym = k;
3543 so_far [keys_count].modifiers = modifiers_so_far; 3533 so_far [keys_count].modifiers = modifiers_so_far;
3544 3534
3589 !NILP (submaps); 3579 !NILP (submaps);
3590 submaps = XCDR (submaps)) 3580 submaps = XCDR (submaps))
3591 { 3581 {
3592 Lisp_Object key = XCAR (XCAR (submaps)); 3582 Lisp_Object key = XCAR (XCAR (submaps));
3593 Lisp_Object submap = XCDR (XCAR (submaps)); 3583 Lisp_Object submap = XCDR (XCAR (submaps));
3594 int lower_modifiers; 3584 unsigned int lower_modifiers;
3595 int lower_keys_count = keys_count; 3585 int lower_keys_count = keys_count;
3596 int bucky; 3586 unsigned int bucky;
3597 3587
3598 submap = get_keymap (submap, 0, 0); 3588 submap = get_keymap (submap, 0, 0);
3599 3589
3600 if (EQ (submap, map)) 3590 if (EQ (submap, map))
3601 /* Arrgh! Some loser has introduced a loop... */ 3591 /* Arrgh! Some loser has introduced a loop... */
3632 { 3622 {
3633 int size = lower_keys_count + 50; 3623 int size = lower_keys_count + 50;
3634 if (! c->keys_so_far_malloced) 3624 if (! c->keys_so_far_malloced)
3635 { 3625 {
3636 struct key_data *new = xnew_array (struct key_data, size); 3626 struct key_data *new = xnew_array (struct key_data, size);
3637 memcpy ((void *)new, (const void *)c->keys_so_far, 3627 memcpy ((void *)new, (CONST void *)c->keys_so_far,
3638 c->keys_so_far_total_size * sizeof (struct key_data)); 3628 c->keys_so_far_total_size * sizeof (struct key_data));
3639 } 3629 }
3640 else 3630 else
3641 XREALLOC_ARRAY (c->keys_so_far, struct key_data, size); 3631 XREALLOC_ARRAY (c->keys_so_far, struct key_data, size);
3642 3632
3885 int mice_only_p; /* whether we are to display only button bindings */ 3875 int mice_only_p; /* whether we are to display only button bindings */
3886 }; 3876 };
3887 3877
3888 struct describe_map_shadow_closure 3878 struct describe_map_shadow_closure
3889 { 3879 {
3890 const struct key_data *raw_key; 3880 CONST struct key_data *raw_key;
3891 Lisp_Object self; 3881 Lisp_Object self;
3892 }; 3882 };
3893 3883
3894 static Lisp_Object 3884 static Lisp_Object
3895 describe_map_mapper_shadow_search (Lisp_Object map, void *arg) 3885 describe_map_mapper_shadow_search (Lisp_Object map, void *arg)
3914 return keymap_lookup_directly (km, k->keysym, k->modifiers); 3904 return keymap_lookup_directly (km, k->keysym, k->modifiers);
3915 } 3905 }
3916 3906
3917 3907
3918 static void 3908 static void
3919 describe_map_mapper (const struct key_data *key, 3909 describe_map_mapper (CONST struct key_data *key,
3920 Lisp_Object binding, 3910 Lisp_Object binding,
3921 void *describe_map_closure) 3911 void *describe_map_closure)
3922 { 3912 {
3923 /* This function can GC */ 3913 /* This function can GC */
3924 struct describe_map_closure *closure = 3914 struct describe_map_closure *closure =
3925 (struct describe_map_closure *) describe_map_closure; 3915 (struct describe_map_closure *) describe_map_closure;
3926 Lisp_Object keysym = key->keysym; 3916 Lisp_Object keysym = key->keysym;
3927 int modifiers = key->modifiers; 3917 unsigned int modifiers = key->modifiers;
3928 3918
3929 /* Don't mention suppressed commands. */ 3919 /* Don't mention suppressed commands. */
3930 if (SYMBOLP (binding) 3920 if (SYMBOLP (binding)
3931 && !NILP (closure->partial) 3921 && !NILP (closure->partial)
3932 && !NILP (Fget (binding, closure->partial, Qnil))) 3922 && !NILP (Fget (binding, closure->partial, Qnil)))
3996 { 3986 {
3997 /* obj1 and obj2 are conses of the form 3987 /* obj1 and obj2 are conses of the form
3998 ( ( <keysym> . <modifiers> ) . <binding> ) 3988 ( ( <keysym> . <modifiers> ) . <binding> )
3999 keysym and modifiers are used, binding is ignored. 3989 keysym and modifiers are used, binding is ignored.
4000 */ 3990 */
4001 int bit1, bit2; 3991 unsigned int bit1, bit2;
4002 obj1 = XCAR (obj1); 3992 obj1 = XCAR (obj1);
4003 obj2 = XCAR (obj2); 3993 obj2 = XCAR (obj2);
4004 bit1 = XINT (XCDR (obj1)); 3994 bit1 = XINT (XCDR (obj1));
4005 bit2 = XINT (XCDR (obj2)); 3995 bit2 = XINT (XCDR (obj2));
4006 if (bit1 != bit2) 3996 if (bit1 != bit2)
4116 buffer_insert_c_string (buf, "\n"); 4106 buffer_insert_c_string (buf, "\n");
4117 while (!NILP (list)) 4107 while (!NILP (list))
4118 { 4108 {
4119 Lisp_Object elt = XCAR (XCAR (list)); 4109 Lisp_Object elt = XCAR (XCAR (list));
4120 Lisp_Object keysym = XCAR (elt); 4110 Lisp_Object keysym = XCAR (elt);
4121 int modifiers = XINT (XCDR (elt)); 4111 unsigned int modifiers = XINT (XCDR (elt));
4122 4112
4123 if (!NILP (elt_prefix)) 4113 if (!NILP (elt_prefix))
4124 buffer_insert_lisp_string (buf, elt_prefix); 4114 buffer_insert_lisp_string (buf, elt_prefix);
4125 4115
4126 if (modifiers & XEMACS_MOD_META) buffer_insert_c_string (buf, "M-"); 4116 if (modifiers & MOD_META) buffer_insert_c_string (buf, "M-");
4127 if (modifiers & XEMACS_MOD_CONTROL) buffer_insert_c_string (buf, "C-"); 4117 if (modifiers & MOD_CONTROL) buffer_insert_c_string (buf, "C-");
4128 if (modifiers & XEMACS_MOD_SUPER) buffer_insert_c_string (buf, "S-"); 4118 if (modifiers & MOD_SUPER) buffer_insert_c_string (buf, "S-");
4129 if (modifiers & XEMACS_MOD_HYPER) buffer_insert_c_string (buf, "H-"); 4119 if (modifiers & MOD_HYPER) buffer_insert_c_string (buf, "H-");
4130 if (modifiers & XEMACS_MOD_ALT) buffer_insert_c_string (buf, "Alt-"); 4120 if (modifiers & MOD_ALT) buffer_insert_c_string (buf, "Alt-");
4131 if (modifiers & XEMACS_MOD_SHIFT) buffer_insert_c_string (buf, "Sh-"); 4121 if (modifiers & MOD_SHIFT) buffer_insert_c_string (buf, "Sh-");
4132 if (SYMBOLP (keysym)) 4122 if (SYMBOLP (keysym))
4133 { 4123 {
4134 Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil); 4124 Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
4135 Emchar c = (CHAR_OR_CHAR_INTP (code) 4125 Emchar c = (CHAR_OR_CHAR_INTP (code)
4136 ? XCHAR_OR_CHAR_INT (code) : (Emchar) -1); 4126 ? XCHAR_OR_CHAR_INT (code) : (Emchar) -1);
4193 4183
4194 4184
4195 void 4185 void
4196 syms_of_keymap (void) 4186 syms_of_keymap (void)
4197 { 4187 {
4198 INIT_LRECORD_IMPLEMENTATION (keymap);
4199
4200 defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist"); 4188 defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist");
4201 4189
4202 defsymbol (&Qkeymapp, "keymapp"); 4190 defsymbol (&Qkeymapp, "keymapp");
4203 4191
4204 defsymbol (&Qsuppress_keymap, "suppress-keymap"); 4192 defsymbol (&Qsuppress_keymap, "suppress-keymap");
4276 defsymbol (&QLFD, "LFD"); 4264 defsymbol (&QLFD, "LFD");
4277 defsymbol (&QTAB, "TAB"); 4265 defsymbol (&QTAB, "TAB");
4278 defsymbol (&QRET, "RET"); 4266 defsymbol (&QRET, "RET");
4279 defsymbol (&QESC, "ESC"); 4267 defsymbol (&QESC, "ESC");
4280 defsymbol (&QDEL, "DEL"); 4268 defsymbol (&QDEL, "DEL");
4281 defsymbol (&QSPC, "SPC");
4282 defsymbol (&QBS, "BS"); 4269 defsymbol (&QBS, "BS");
4283 } 4270 }
4284 4271
4285 void 4272 void
4286 vars_of_keymap (void) 4273 vars_of_keymap (void)
4330 */ ); 4317 */ );
4331 keymap_tick = 0; 4318 keymap_tick = 0;
4332 4319
4333 staticpro (&Vcurrent_global_map); 4320 staticpro (&Vcurrent_global_map);
4334 4321
4335 Vsingle_space_string = make_string ((const Bufbyte *) " ", 1); 4322 Vsingle_space_string = make_string_nocopy ((CONST Bufbyte *) " ", 1);
4336 staticpro (&Vsingle_space_string); 4323 staticpro (&Vsingle_space_string);
4337 } 4324 }
4338 4325
4339 void 4326 void
4340 complex_vars_of_keymap (void) 4327 complex_vars_of_keymap (void)
4346 Vcurrent_global_map = Fmake_keymap (Qnil); 4333 Vcurrent_global_map = Fmake_keymap (Qnil);
4347 4334
4348 meta_disgustitute = Fmake_keymap (Qnil); 4335 meta_disgustitute = Fmake_keymap (Qnil);
4349 Ffset (ESC_prefix, meta_disgustitute); 4336 Ffset (ESC_prefix, meta_disgustitute);
4350 /* no need to protect meta_disgustitute, though */ 4337 /* no need to protect meta_disgustitute, though */
4351 keymap_store_internal (MAKE_MODIFIER_HASH_KEY (XEMACS_MOD_META), 4338 keymap_store_internal (MAKE_MODIFIER_HASH_KEY (MOD_META),
4352 XKEYMAP (Vcurrent_global_map), 4339 XKEYMAP (Vcurrent_global_map),
4353 meta_disgustitute); 4340 meta_disgustitute);
4354 XKEYMAP (Vcurrent_global_map)->sub_maps_cache = Qt; 4341 XKEYMAP (Vcurrent_global_map)->sub_maps_cache = Qt;
4355 4342
4356 Vkey_translation_map = Fmake_sparse_keymap (intern ("key-translation-map")); 4343 Vkey_translation_map = Fmake_sparse_keymap (intern ("key-translation-map"));