comparison src/keymap.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents 6240c7796c7a
children 74fd4e045ea6
comparison
equal deleted inserted replaced
379:76b7d63099ad 380:8626e4521993
28 #include <config.h> 28 #include <config.h>
29 #include "lisp.h" 29 #include "lisp.h"
30 30
31 #include "buffer.h" 31 #include "buffer.h"
32 #include "bytecode.h" 32 #include "bytecode.h"
33 #include "commands.h"
34 #include "console.h" 33 #include "console.h"
35 #include "elhash.h" 34 #include "elhash.h"
36 #include "events.h" 35 #include "events.h"
37 #include "frame.h" 36 #include "frame.h"
38 #include "insdel.h" 37 #include "insdel.h"
155 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-
156 key sequence than "C-x" is. 155 key sequence than "C-x" is.
157 156
158 */ 157 */
159 158
160 struct keymap 159 typedef struct Lisp_Keymap
161 { 160 {
162 struct lcrecord_header header; 161 struct lcrecord_header header;
163 Lisp_Object parents; /* Keymaps to be searched after this one 162 Lisp_Object parents; /* Keymaps to be searched after this one
164 * An ordered list */ 163 * An ordered list */
165 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
181 */ 180 */
182 int fullness; /* How many entries there are in this table. 181 int fullness; /* How many entries there are in this table.
183 This should be the same as the fullness 182 This should be the same as the fullness
184 of the `table', but hash.c is broken. */ 183 of the `table', but hash.c is broken. */
185 Lisp_Object name; /* Just for debugging convenience */ 184 Lisp_Object name; /* Just for debugging convenience */
186 }; 185 } Lisp_Keymap;
187
188 #define XKEYMAP(x) XRECORD (x, keymap, struct keymap)
189 #define XSETKEYMAP(x, p) XSETRECORD (x, p, keymap)
190 #define KEYMAPP(x) RECORDP (x, keymap)
191 #define CHECK_KEYMAP(x) CHECK_RECORD (x, keymap)
192 186
193 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier) 187 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier)
194 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0) 188 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0)
195 189
196 190
258 /************************************************************************/ 252 /************************************************************************/
259 253
260 static Lisp_Object 254 static Lisp_Object
261 mark_keymap (Lisp_Object obj, void (*markobj) (Lisp_Object)) 255 mark_keymap (Lisp_Object obj, void (*markobj) (Lisp_Object))
262 { 256 {
263 struct keymap *keymap = XKEYMAP (obj); 257 Lisp_Keymap *keymap = XKEYMAP (obj);
264 ((markobj) (keymap->parents)); 258 markobj (keymap->parents);
265 ((markobj) (keymap->prompt)); 259 markobj (keymap->prompt);
266 ((markobj) (keymap->inverse_table)); 260 markobj (keymap->inverse_table);
267 ((markobj) (keymap->sub_maps_cache)); 261 markobj (keymap->sub_maps_cache);
268 ((markobj) (keymap->default_binding)); 262 markobj (keymap->default_binding);
269 ((markobj) (keymap->name)); 263 markobj (keymap->name);
270 return keymap->table; 264 return keymap->table;
271 } 265 }
272 266
273 static void 267 static void
274 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 268 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
275 { 269 {
276 /* This function can GC */ 270 /* This function can GC */
277 struct keymap *keymap = XKEYMAP (obj); 271 Lisp_Keymap *keymap = XKEYMAP (obj);
278 char buf[200]; 272 char buf[200];
279 int size = XINT (Fkeymap_fullness (obj)); 273 int size = XINT (Fkeymap_fullness (obj));
280 if (print_readably) 274 if (print_readably)
281 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid); 275 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid);
282 write_c_string ("#<keymap ", printcharfun); 276 write_c_string ("#<keymap ", printcharfun);
292 } 286 }
293 287
294 /* No need for keymap_equal #### Why not? */ 288 /* No need for keymap_equal #### Why not? */
295 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap, 289 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
296 mark_keymap, print_keymap, 0, 0, 0, 290 mark_keymap, print_keymap, 0, 0, 0,
297 struct keymap); 291 Lisp_Keymap);
298 292
299 /************************************************************************/ 293 /************************************************************************/
300 /* Traversing keymaps and their parents */ 294 /* Traversing keymaps and their parents */
301 /************************************************************************/ 295 /************************************************************************/
302 296
473 /* Relies on caller to gc-protect args */ 467 /* Relies on caller to gc-protect args */
474 static Lisp_Object 468 static Lisp_Object
475 keymap_lookup_directly (Lisp_Object keymap, 469 keymap_lookup_directly (Lisp_Object keymap,
476 Lisp_Object keysym, unsigned int modifiers) 470 Lisp_Object keysym, unsigned int modifiers)
477 { 471 {
478 struct keymap *k; 472 Lisp_Keymap *k;
479 473
480 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER 474 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
481 | MOD_ALT | MOD_SHIFT)) != 0) 475 | MOD_ALT | MOD_SHIFT)) != 0)
482 abort (); 476 abort ();
483 477
532 keys = Fcons (keys, keysym); 526 keys = Fcons (keys, keysym);
533 Fputhash (value, keys, inverse_table); 527 Fputhash (value, keys, inverse_table);
534 } 528 }
535 else 529 else
536 { 530 {
537 while (CONSP (Fcdr (keys))) 531 while (CONSP (XCDR (keys)))
538 keys = XCDR (keys); 532 keys = XCDR (keys);
539 XCDR (keys) = Fcons (XCDR (keys), keysym); 533 XCDR (keys) = Fcons (XCDR (keys), keysym);
540 /* No need to call puthash because we've destructively 534 /* No need to call puthash because we've destructively
541 modified the list tail in place */ 535 modified the list tail in place */
542 } 536 }
582 */ 576 */
583 } 577 }
584 578
585 579
586 static void 580 static void
587 keymap_store_internal (Lisp_Object keysym, struct keymap *keymap, 581 keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap,
588 Lisp_Object value) 582 Lisp_Object value)
589 { 583 {
590 Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil); 584 Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil);
591 585
592 if (EQ (prev_value, value)) 586 if (EQ (prev_value, value))
611 keymap_tick++; 605 keymap_tick++;
612 } 606 }
613 607
614 608
615 static Lisp_Object 609 static Lisp_Object
616 create_bucky_submap (struct keymap *k, unsigned int modifiers, 610 create_bucky_submap (Lisp_Keymap *k, unsigned int modifiers,
617 Lisp_Object parent_for_debugging_info) 611 Lisp_Object parent_for_debugging_info)
618 { 612 {
619 Lisp_Object submap = Fmake_sparse_keymap (Qnil); 613 Lisp_Object submap = Fmake_sparse_keymap (Qnil);
620 /* 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 */
621 XKEYMAP (submap)->name 615 XKEYMAP (submap)->name
632 keymap_store (Lisp_Object keymap, CONST struct key_data *key, 626 keymap_store (Lisp_Object keymap, CONST struct key_data *key,
633 Lisp_Object value) 627 Lisp_Object value)
634 { 628 {
635 Lisp_Object keysym = key->keysym; 629 Lisp_Object keysym = key->keysym;
636 unsigned int modifiers = key->modifiers; 630 unsigned int modifiers = key->modifiers;
637 struct keymap *k; 631 Lisp_Keymap *k;
638 632
639 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER 633 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
640 | MOD_ALT | MOD_SHIFT)) != 0) 634 | MOD_ALT | MOD_SHIFT)) != 0)
641 abort (); 635 abort ();
642 636
681 { 675 {
682 Lisp_Object *result_locative; 676 Lisp_Object *result_locative;
683 }; 677 };
684 678
685 static int 679 static int
686 keymap_submaps_mapper_0 (CONST void *hash_key, void *hash_contents, 680 keymap_submaps_mapper_0 (Lisp_Object key, Lisp_Object value,
687 void *keymap_submaps_closure) 681 void *keymap_submaps_closure)
688 { 682 {
689 /* This function can GC */ 683 /* This function can GC */
690 Lisp_Object contents;
691 VOID_TO_LISP (contents, hash_contents);
692 /* Perform any autoloads, etc */ 684 /* Perform any autoloads, etc */
693 Fkeymapp (contents); 685 Fkeymapp (value);
694 return 0; 686 return 0;
695 } 687 }
696 688
697 static int 689 static int
698 keymap_submaps_mapper (CONST void *hash_key, void *hash_contents, 690 keymap_submaps_mapper (Lisp_Object key, Lisp_Object value,
699 void *keymap_submaps_closure) 691 void *keymap_submaps_closure)
700 { 692 {
701 /* This function can GC */ 693 /* This function can GC */
702 Lisp_Object key, contents;
703 Lisp_Object *result_locative; 694 Lisp_Object *result_locative;
704 struct keymap_submaps_closure *cl = 695 struct keymap_submaps_closure *cl =
705 (struct keymap_submaps_closure *) keymap_submaps_closure; 696 (struct keymap_submaps_closure *) keymap_submaps_closure;
706 CVOID_TO_LISP (key, hash_key);
707 VOID_TO_LISP (contents, hash_contents);
708 result_locative = cl->result_locative; 697 result_locative = cl->result_locative;
709 698
710 if (!NILP (Fkeymapp (contents))) 699 if (!NILP (Fkeymapp (value)))
711 *result_locative = Fcons (Fcons (key, contents), *result_locative); 700 *result_locative = Fcons (Fcons (key, value), *result_locative);
712 return 0; 701 return 0;
713 } 702 }
714 703
715 static int map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, 704 static int map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
716 Lisp_Object pred); 705 Lisp_Object pred);
717 706
718 static Lisp_Object 707 static Lisp_Object
719 keymap_submaps (Lisp_Object keymap) 708 keymap_submaps (Lisp_Object keymap)
720 { 709 {
721 /* This function can GC */ 710 /* This function can GC */
722 struct keymap *k = XKEYMAP (keymap); 711 Lisp_Keymap *k = XKEYMAP (keymap);
723 712
724 if (EQ (k->sub_maps_cache, Qt)) /* Unknown */ 713 if (EQ (k->sub_maps_cache, Qt)) /* Unknown */
725 { 714 {
726 Lisp_Object result = Qnil; 715 Lisp_Object result = Qnil;
727 struct gcpro gcpro1, gcpro2; 716 struct gcpro gcpro1, gcpro2;
748 /************************************************************************/ 737 /************************************************************************/
749 /* Basic operations on keymaps */ 738 /* Basic operations on keymaps */
750 /************************************************************************/ 739 /************************************************************************/
751 740
752 static Lisp_Object 741 static Lisp_Object
753 make_keymap (int size) 742 make_keymap (size_t size)
754 { 743 {
755 Lisp_Object result; 744 Lisp_Object result;
756 struct keymap *keymap = alloc_lcrecord_type (struct keymap, lrecord_keymap); 745 Lisp_Keymap *keymap = alloc_lcrecord_type (Lisp_Keymap, lrecord_keymap);
757 746
758 XSETKEYMAP (result, keymap); 747 XSETKEYMAP (result, keymap);
759 748
760 keymap->parents = Qnil; 749 keymap->parents = Qnil;
761 keymap->table = Qnil; 750 keymap->prompt = Qnil;
762 keymap->prompt = Qnil; 751 keymap->table = Qnil;
752 keymap->inverse_table = Qnil;
763 keymap->default_binding = Qnil; 753 keymap->default_binding = Qnil;
764 keymap->inverse_table = Qnil; 754 keymap->sub_maps_cache = Qnil; /* No possible submaps */
765 keymap->sub_maps_cache = Qnil; /* No possible submaps */ 755 keymap->fullness = 0;
766 keymap->fullness = 0; 756 keymap->name = Qnil;
757
767 if (size != 0) /* hack for copy-keymap */ 758 if (size != 0) /* hack for copy-keymap */
768 { 759 {
769 keymap->table = Fmake_hashtable (make_int (size), Qnil); 760 keymap->table =
761 make_lisp_hash_table (size, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
770 /* Inverse table is often less dense because of duplicate key-bindings. 762 /* Inverse table is often less dense because of duplicate key-bindings.
771 If not, it will grow anyway. */ 763 If not, it will grow anyway. */
772 keymap->inverse_table = Fmake_hashtable (make_int (size * 3 / 4), Qnil); 764 keymap->inverse_table =
773 } 765 make_lisp_hash_table (size * 3 / 4, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
774 keymap->name = Qnil; 766 }
775 return result; 767 return result;
776 } 768 }
777 769
778 DEFUN ("make-keymap", Fmake_keymap, 0, 1, 0, /* 770 DEFUN ("make-keymap", Fmake_keymap, 0, 1, 0, /*
779 Construct and return a new keymap object. 771 Construct and return a new keymap object.
1112 { 1104 {
1113 Lisp_Object inverse_table; 1105 Lisp_Object inverse_table;
1114 }; 1106 };
1115 1107
1116 static int 1108 static int
1117 copy_keymap_inverse_mapper (CONST void *hash_key, void *hash_contents, 1109 copy_keymap_inverse_mapper (Lisp_Object key, Lisp_Object value,
1118 void *copy_keymap_inverse_closure) 1110 void *copy_keymap_inverse_closure)
1119 { 1111 {
1120 Lisp_Object key, inverse_table, inverse_contents;
1121 struct copy_keymap_inverse_closure *closure = 1112 struct copy_keymap_inverse_closure *closure =
1122 (struct copy_keymap_inverse_closure *) copy_keymap_inverse_closure; 1113 (struct copy_keymap_inverse_closure *) copy_keymap_inverse_closure;
1123 1114
1124 VOID_TO_LISP (inverse_table, closure);
1125 VOID_TO_LISP (inverse_contents, hash_contents);
1126 CVOID_TO_LISP (key, hash_key);
1127 /* copy-sequence deals with dotted lists. */ 1115 /* copy-sequence deals with dotted lists. */
1128 if (CONSP (inverse_contents)) 1116 if (CONSP (value))
1129 inverse_contents = Fcopy_sequence (inverse_contents); 1117 value = Fcopy_list (value);
1130 Fputhash (key, inverse_contents, closure->inverse_table); 1118 Fputhash (key, value, closure->inverse_table);
1131 1119
1132 return 0; 1120 return 0;
1133 } 1121 }
1134 1122
1135 1123
1136 static Lisp_Object 1124 static Lisp_Object
1137 copy_keymap_internal (struct keymap *keymap) 1125 copy_keymap_internal (Lisp_Keymap *keymap)
1138 { 1126 {
1139 Lisp_Object nkm = make_keymap (0); 1127 Lisp_Object nkm = make_keymap (0);
1140 struct keymap *new_keymap = XKEYMAP (nkm); 1128 Lisp_Keymap *new_keymap = XKEYMAP (nkm);
1141 struct copy_keymap_inverse_closure copy_keymap_inverse_closure; 1129 struct copy_keymap_inverse_closure copy_keymap_inverse_closure;
1142 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table; 1130 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table;
1143 1131
1144 new_keymap->parents = Fcopy_sequence (keymap->parents); 1132 new_keymap->parents = Fcopy_sequence (keymap->parents);
1145 new_keymap->fullness = keymap->fullness; 1133 new_keymap->fullness = keymap->fullness;
1146 new_keymap->sub_maps_cache = Qnil; /* No submaps */ 1134 new_keymap->sub_maps_cache = Qnil; /* No submaps */
1147 new_keymap->table = Fcopy_hashtable (keymap->table); 1135 new_keymap->table = Fcopy_hash_table (keymap->table);
1148 new_keymap->inverse_table = Fcopy_hashtable (keymap->inverse_table); 1136 new_keymap->inverse_table = Fcopy_hash_table (keymap->inverse_table);
1149 /* 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
1150 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.
1151 */ 1139 */
1152 elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table, 1140 elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table,
1153 &copy_keymap_inverse_closure); 1141 &copy_keymap_inverse_closure);
1157 1145
1158 static Lisp_Object copy_keymap (Lisp_Object keymap); 1146 static Lisp_Object copy_keymap (Lisp_Object keymap);
1159 1147
1160 struct copy_keymap_closure 1148 struct copy_keymap_closure
1161 { 1149 {
1162 struct keymap *self; 1150 Lisp_Keymap *self;
1163 }; 1151 };
1164 1152
1165 static int 1153 static int
1166 copy_keymap_mapper (CONST void *hash_key, void *hash_contents, 1154 copy_keymap_mapper (Lisp_Object key, Lisp_Object value,
1167 void *copy_keymap_closure) 1155 void *copy_keymap_closure)
1168 { 1156 {
1169 /* This function can GC */ 1157 /* This function can GC */
1170 Lisp_Object key, contents;
1171 struct copy_keymap_closure *closure = 1158 struct copy_keymap_closure *closure =
1172 (struct copy_keymap_closure *) copy_keymap_closure; 1159 (struct copy_keymap_closure *) copy_keymap_closure;
1173 1160
1174 CVOID_TO_LISP (key, hash_key);
1175 VOID_TO_LISP (contents, hash_contents);
1176 /* When we encounter a keymap which is indirected through a 1161 /* When we encounter a keymap which is indirected through a
1177 symbol, we need to copy the sub-map. In v18, the form 1162 symbol, we need to copy the sub-map. In v18, the form
1178 (lookup-key (copy-keymap global-map) "\C-x") 1163 (lookup-key (copy-keymap global-map) "\C-x")
1179 returned a new keymap, not the symbol 'Control-X-prefix. 1164 returned a new keymap, not the symbol 'Control-X-prefix.
1180 */ 1165 */
1181 contents = get_keymap (contents, 1166 value = get_keymap (value, 0, 1); /* #### autoload GC-safe here? */
1182 0, 1); /* #### autoload GC-safe here? */ 1167 if (KEYMAPP (value))
1183 if (KEYMAPP (contents))
1184 keymap_store_internal (key, closure->self, 1168 keymap_store_internal (key, closure->self,
1185 copy_keymap (contents)); 1169 copy_keymap (value));
1186 return 0; 1170 return 0;
1187 } 1171 }
1188 1172
1189 static Lisp_Object 1173 static Lisp_Object
1190 copy_keymap (Lisp_Object keymap) 1174 copy_keymap (Lisp_Object keymap)
1282 problems ... */ 1266 problems ... */
1283 signal_simple_error ("keysym char must be printable", *keysym); 1267 signal_simple_error ("keysym char must be printable", *keysym);
1284 /* #### 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) */
1285 if (modifiers & MOD_SHIFT) 1269 if (modifiers & MOD_SHIFT)
1286 signal_simple_error 1270 signal_simple_error
1287 ("the `shift' modifier may not be applied to ASCII keysyms", 1271 ("The `shift' modifier may not be applied to ASCII keysyms",
1288 spec); 1272 spec);
1289 } 1273 }
1290 else 1274 else
1291 { 1275 {
1292 signal_simple_error ("unknown keysym specifier", 1276 signal_simple_error ("Unknown keysym specifier",
1293 *keysym); 1277 *keysym);
1294 } 1278 }
1295 1279
1296 if (SYMBOLP (*keysym)) 1280 if (SYMBOLP (*keysym))
1297 { 1281 {
1472 modifier = bucky_sym_to_bucky_bit (keysym); 1456 modifier = bucky_sym_to_bucky_bit (keysym);
1473 modifiers |= modifier; 1457 modifiers |= modifier;
1474 if (!NILP (XCDR (rest))) 1458 if (!NILP (XCDR (rest)))
1475 { 1459 {
1476 if (! modifier) 1460 if (! modifier)
1477 signal_simple_error ("unknown modifier", keysym); 1461 signal_simple_error ("Unknown modifier", keysym);
1478 } 1462 }
1479 else 1463 else
1480 { 1464 {
1481 if (modifier) 1465 if (modifier)
1482 signal_simple_error ("nothing but modifiers here", 1466 signal_simple_error ("Nothing but modifiers here",
1483 spec); 1467 spec);
1484 } 1468 }
1485 rest = XCDR (rest); 1469 rest = XCDR (rest);
1486 QUIT; 1470 QUIT;
1487 } 1471 }
1488 if (!NILP (rest)) 1472 if (!NILP (rest))
1489 signal_simple_error ("dotted list", spec); 1473 signal_simple_error ("List must be nil-terminated", spec);
1490 1474
1491 define_key_check_and_coerce_keysym (spec, &keysym, modifiers); 1475 define_key_check_and_coerce_keysym (spec, &keysym, modifiers);
1492 returned_value->keysym = keysym; 1476 returned_value->keysym = keysym;
1493 returned_value->modifiers = modifiers; 1477 returned_value->modifiers = modifiers;
1494 } 1478 }
1495 else 1479 else
1496 { 1480 {
1497 signal_simple_error ("unknown key-sequence specifier", 1481 signal_simple_error ("Unknown key-sequence specifier",
1498 spec); 1482 spec);
1499 } 1483 }
1500 } 1484 }
1501 1485
1502 /* Used by character-to-event */ 1486 /* Used by character-to-event */
1511 /* #### where the hell does this come from? */ 1495 /* #### where the hell does this come from? */
1512 EQ (XCAR (list), Qmenu_selection)) 1496 EQ (XCAR (list), Qmenu_selection))
1513 { 1497 {
1514 Lisp_Object fn, arg; 1498 Lisp_Object fn, arg;
1515 if (! NILP (Fcdr (Fcdr (list)))) 1499 if (! NILP (Fcdr (Fcdr (list))))
1516 signal_simple_error ("invalid menu event desc", list); 1500 signal_simple_error ("Invalid menu event desc", list);
1517 arg = Fcar (Fcdr (list)); 1501 arg = Fcar (Fcdr (list));
1518 if (SYMBOLP (arg)) 1502 if (SYMBOLP (arg))
1519 fn = Qcall_interactively; 1503 fn = Qcall_interactively;
1520 else 1504 else
1521 fn = Qeval; 1505 fn = Qeval;
1619 CHECK_LIVE_EVENT (event); 1603 CHECK_LIVE_EVENT (event);
1620 return (event_matches_key_specifier_p (XEVENT (event), key_specifier) 1604 return (event_matches_key_specifier_p (XEVENT (event), key_specifier)
1621 ? Qt : Qnil); 1605 ? Qt : Qnil);
1622 } 1606 }
1623 1607
1608 #define MACROLET(k,m) do { \
1609 returned_value->keysym = (k); \
1610 returned_value->modifiers = (m); \
1611 RETURN_SANS_WARNINGS; \
1612 } while (0)
1613
1624 /* ASCII grunge. 1614 /* ASCII grunge.
1625 Given a keysym, return another keysym/modifier pair which could be 1615 Given a keysym, return another keysym/modifier pair which could be
1626 considered the same key in an ASCII world. Backspace returns ^H, for 1616 considered the same key in an ASCII world. Backspace returns ^H, for
1627 example. 1617 example.
1628 */ 1618 */
1634 unsigned int modifiers = key->modifiers; 1624 unsigned int modifiers = key->modifiers;
1635 unsigned int modifiers_sans_control = (modifiers & (~MOD_CONTROL)); 1625 unsigned int modifiers_sans_control = (modifiers & (~MOD_CONTROL));
1636 unsigned int modifiers_sans_meta = (modifiers & (~MOD_META)); 1626 unsigned int modifiers_sans_meta = (modifiers & (~MOD_META));
1637 returned_value->keysym = Qnil; /* By default, no "alternate" key */ 1627 returned_value->keysym = Qnil; /* By default, no "alternate" key */
1638 returned_value->modifiers = 0; 1628 returned_value->modifiers = 0;
1639 #define MACROLET(k,m) do { returned_value->keysym = (k); \
1640 returned_value->modifiers = (m); \
1641 RETURN__; } while (0)
1642 if (modifiers_sans_meta == MOD_CONTROL) 1629 if (modifiers_sans_meta == MOD_CONTROL)
1643 { 1630 {
1644 if EQ (keysym, QKspace) 1631 if EQ (keysym, QKspace)
1645 MACROLET (make_char ('@'), modifiers); 1632 MACROLET (make_char ('@'), modifiers);
1646 else if (!CHARP (keysym)) 1633 else if (!CHARP (keysym))
1968 XKEYMAP (cmd)->name /* for debugging */ 1955 XKEYMAP (cmd)->name /* for debugging */
1969 = list2 (make_key_description (&raw_key1, 1), keymap); 1956 = list2 (make_key_description (&raw_key1, 1), keymap);
1970 keymap_store (keymap, &raw_key1, cmd); 1957 keymap_store (keymap, &raw_key1, cmd);
1971 } 1958 }
1972 if (NILP (Fkeymapp (cmd))) 1959 if (NILP (Fkeymapp (cmd)))
1973 signal_simple_error_2 ("invalid prefix keys in sequence", 1960 signal_simple_error_2 ("Invalid prefix keys in sequence",
1974 c, keys); 1961 c, keys);
1975 1962
1976 if (ascii_hack && !NILP (raw_key2.keysym) && 1963 if (ascii_hack && !NILP (raw_key2.keysym) &&
1977 NILP (keymap_lookup_1 (keymap, &raw_key2, 0))) 1964 NILP (keymap_lookup_1 (keymap, &raw_key2, 0)))
1978 keymap_store (keymap, &raw_key2, cmd); 1965 keymap_store (keymap, &raw_key2, cmd);
2055 { 2042 {
2056 /* This is a hack so that looking up a key-sequence whose last 2043 /* This is a hack so that looking up a key-sequence whose last
2057 * element is the meta-prefix-char will return the keymap that 2044 * element is the meta-prefix-char will return the keymap that
2058 * the "meta" keys are stored in, if there is no binding for 2045 * the "meta" keys are stored in, if there is no binding for
2059 * the meta-prefix-char (and if this map has a "meta" submap). 2046 * the meta-prefix-char (and if this map has a "meta" submap).
2060 * If this map doesnt have a "meta" submap, then the 2047 * If this map doesn't have a "meta" submap, then the
2061 * meta-prefix-char is looked up just like any other key. 2048 * meta-prefix-char is looked up just like any other key.
2062 */ 2049 */
2063 if (remaining == 0) 2050 if (remaining == 0)
2064 { 2051 {
2065 /* First look for the prefix-char directly */ 2052 /* First look for the prefix-char directly */
2224 Does all manner of semi-hairy heuristics, like looking in the current 2211 Does all manner of semi-hairy heuristics, like looking in the current
2225 buffer's map before looking in the global map and looking in the local 2212 buffer's map before looking in the global map and looking in the local
2226 map of the buffer in which the mouse was clicked in event0 is a click. 2213 map of the buffer in which the mouse was clicked in event0 is a click.
2227 2214
2228 It would be kind of nice if this were in Lisp so that this semi-hairy 2215 It would be kind of nice if this were in Lisp so that this semi-hairy
2229 semi-heuristic command-lookup behaviour could be readily understood and 2216 semi-heuristic command-lookup behavior could be readily understood and
2230 customised. However, this needs to be pretty fast, or performance of 2217 customised. However, this needs to be pretty fast, or performance of
2231 keyboard macros goes to shit; putting this in lisp slows macros down 2218 keyboard macros goes to shit; putting this in lisp slows macros down
2232 2-3x. And they're already slower than v18 by 5-6x. 2219 2-3x. And they're already slower than v18 by 5-6x.
2233 */ 2220 */
2234 2221
2408 } 2395 }
2409 #endif /* HAVE_WINDOW_SYSTEM */ 2396 #endif /* HAVE_WINDOW_SYSTEM */
2410 2397
2411 { 2398 {
2412 int nmaps = closure.nmaps; 2399 int nmaps = closure.nmaps;
2413 /* Silently truncate at 100 keymaps to prevent infinite losssage */ 2400 /* Silently truncate at 100 keymaps to prevent infinite lossage */
2414 if (nmaps >= max_maps && max_maps > 0) 2401 if (nmaps >= max_maps && max_maps > 0)
2415 maps[max_maps - 1] = Vcurrent_global_map; 2402 maps[max_maps - 1] = Vcurrent_global_map;
2416 else 2403 else
2417 maps[nmaps] = Vcurrent_global_map; 2404 maps[nmaps] = Vcurrent_global_map;
2418 UNGCPRO; 2405 UNGCPRO;
2424 BUFFER_OR_STRING. The GLYPH arg, if specified, is one more extent 2411 BUFFER_OR_STRING. The GLYPH arg, if specified, is one more extent
2425 to look for a keymap in, and if it has one, its keymap will be the 2412 to look for a keymap in, and if it has one, its keymap will be the
2426 first element in the list returned. This is so we can correctly 2413 first element in the list returned. This is so we can correctly
2427 search the keymaps associated with glyphs which may be physically 2414 search the keymaps associated with glyphs which may be physically
2428 disjoint from their extents: for example, if a glyph is out in the 2415 disjoint from their extents: for example, if a glyph is out in the
2429 margin, we should still consult the kemyap of that glyph's extent, 2416 margin, we should still consult the keymap of that glyph's extent,
2430 which may not itself be under the mouse. 2417 which may not itself be under the mouse.
2431 */ 2418 */
2432 2419
2433 static void 2420 static void
2434 get_relevant_extent_keymaps (Lisp_Object pos, Lisp_Object buffer_or_string, 2421 get_relevant_extent_keymaps (Lisp_Object pos, Lisp_Object buffer_or_string,
2749 unsigned int modifiers; 2736 unsigned int modifiers;
2750 }; 2737 };
2751 2738
2752 /* used by map_keymap() */ 2739 /* used by map_keymap() */
2753 static int 2740 static int
2754 map_keymap_unsorted_mapper (CONST void *hash_key, void *hash_contents, 2741 map_keymap_unsorted_mapper (Lisp_Object keysym, Lisp_Object value,
2755 void *map_keymap_unsorted_closure) 2742 void *map_keymap_unsorted_closure)
2756 { 2743 {
2757 /* This function can GC */ 2744 /* This function can GC */
2758 Lisp_Object keysym;
2759 Lisp_Object contents;
2760 struct map_keymap_unsorted_closure *closure = 2745 struct map_keymap_unsorted_closure *closure =
2761 (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure; 2746 (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure;
2762 unsigned int modifiers = closure->modifiers; 2747 unsigned int modifiers = closure->modifiers;
2763 unsigned int mod_bit; 2748 unsigned int mod_bit;
2764 CVOID_TO_LISP (keysym, hash_key);
2765 VOID_TO_LISP (contents, hash_contents);
2766 mod_bit = MODIFIER_HASH_KEY_BITS (keysym); 2749 mod_bit = MODIFIER_HASH_KEY_BITS (keysym);
2767 if (mod_bit != 0) 2750 if (mod_bit != 0)
2768 { 2751 {
2769 int omod = modifiers; 2752 int omod = modifiers;
2770 closure->modifiers = (modifiers | mod_bit); 2753 closure->modifiers = (modifiers | mod_bit);
2771 contents = get_keymap (contents, 1, 0); 2754 value = get_keymap (value, 1, 0);
2772 elisp_maphash (map_keymap_unsorted_mapper, 2755 elisp_maphash (map_keymap_unsorted_mapper,
2773 XKEYMAP (contents)->table, 2756 XKEYMAP (value)->table,
2774 map_keymap_unsorted_closure); 2757 map_keymap_unsorted_closure);
2775 closure->modifiers = omod; 2758 closure->modifiers = omod;
2776 } 2759 }
2777 else 2760 else
2778 { 2761 {
2779 struct key_data key; 2762 struct key_data key;
2780 key.keysym = keysym; 2763 key.keysym = keysym;
2781 key.modifiers = modifiers; 2764 key.modifiers = modifiers;
2782 ((*closure->fn) (&key, contents, closure->arg)); 2765 ((*closure->fn) (&key, value, closure->arg));
2783 } 2766 }
2784 return 0; 2767 return 0;
2785 } 2768 }
2786 2769
2787 2770
2790 Lisp_Object *result_locative; 2773 Lisp_Object *result_locative;
2791 }; 2774 };
2792 2775
2793 /* used by map_keymap_sorted() */ 2776 /* used by map_keymap_sorted() */
2794 static int 2777 static int
2795 map_keymap_sorted_mapper (CONST void *hash_key, void *hash_contents, 2778 map_keymap_sorted_mapper (Lisp_Object key, Lisp_Object value,
2796 void *map_keymap_sorted_closure) 2779 void *map_keymap_sorted_closure)
2797 { 2780 {
2798 struct map_keymap_sorted_closure *cl = 2781 struct map_keymap_sorted_closure *cl =
2799 (struct map_keymap_sorted_closure *) map_keymap_sorted_closure; 2782 (struct map_keymap_sorted_closure *) map_keymap_sorted_closure;
2800 Lisp_Object key, contents;
2801 Lisp_Object *list = cl->result_locative; 2783 Lisp_Object *list = cl->result_locative;
2802 CVOID_TO_LISP (key, hash_key); 2784 *list = Fcons (Fcons (key, value), *list);
2803 VOID_TO_LISP (contents, hash_contents);
2804 *list = Fcons (Fcons (key, contents), *list);
2805 return 0; 2785 return 0;
2806 } 2786 }
2807 2787
2808 2788
2809 /* used by map_keymap_sorted(), describe_map_sort_predicate(), 2789 /* used by map_keymap_sorted(), describe_map_sort_predicate(),
2897 { 2877 {
2898 /* This function can GC */ 2878 /* This function can GC */
2899 struct gcpro gcpro1; 2879 struct gcpro gcpro1;
2900 Lisp_Object contents = Qnil; 2880 Lisp_Object contents = Qnil;
2901 2881
2902 if (XINT (Fhashtable_fullness (keymap_table)) == 0) 2882 if (XINT (Fhash_table_count (keymap_table)) == 0)
2903 return; 2883 return;
2904 2884
2905 GCPRO1 (contents); 2885 GCPRO1 (contents);
2906 2886
2907 { 2887 {
3267 else if (EQ (keysym, QKbackspace)) strcpy (bufp, "BS"); 3247 else if (EQ (keysym, QKbackspace)) strcpy (bufp, "BS");
3268 else 3248 else
3269 #endif 3249 #endif
3270 strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name)); 3250 strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name));
3271 if (!NILP (XCDR (rest))) 3251 if (!NILP (XCDR (rest)))
3272 signal_simple_error ("invalid key description", 3252 signal_simple_error ("Invalid key description",
3273 key); 3253 key);
3274 } 3254 }
3275 } 3255 }
3276 return build_string (buf); 3256 return build_string (buf);
3277 } 3257 }
3750 !NILP (mouse_only_p), Fcurrent_buffer ()); 3730 !NILP (mouse_only_p), Fcurrent_buffer ());
3751 return Qnil; 3731 return Qnil;
3752 } 3732 }
3753 3733
3754 3734
3755 /* Insert a desription of the key bindings in STARTMAP, 3735 /* Insert a description of the key bindings in STARTMAP,
3756 followed by those of all maps reachable through STARTMAP. 3736 followed by those of all maps reachable through STARTMAP.
3757 If PARTIAL is nonzero, omit certain "uninteresting" commands 3737 If PARTIAL is nonzero, omit certain "uninteresting" commands
3758 (such as `undefined'). 3738 (such as `undefined').
3759 If SHADOW is non-nil, it is a list of other maps; 3739 If SHADOW is non-nil, it is a list of other maps;
3760 don't mention keys which would be shadowed by any of them 3740 don't mention keys which would be shadowed by any of them
3934 struct describe_map_closure *closure = 3914 struct describe_map_closure *closure =
3935 (struct describe_map_closure *) describe_map_closure; 3915 (struct describe_map_closure *) describe_map_closure;
3936 Lisp_Object keysym = key->keysym; 3916 Lisp_Object keysym = key->keysym;
3937 unsigned int modifiers = key->modifiers; 3917 unsigned int modifiers = key->modifiers;
3938 3918
3939 /* Dont mention suppressed commands. */ 3919 /* Don't mention suppressed commands. */
3940 if (SYMBOLP (binding) 3920 if (SYMBOLP (binding)
3941 && !NILP (closure->partial) 3921 && !NILP (closure->partial)
3942 && !NILP (Fget (binding, closure->partial, Qnil))) 3922 && !NILP (Fget (binding, closure->partial, Qnil)))
3943 return; 3923 return;
3944 3924
4141 if (modifiers & MOD_SHIFT) buffer_insert_c_string (buf, "Sh-"); 4121 if (modifiers & MOD_SHIFT) buffer_insert_c_string (buf, "Sh-");
4142 if (SYMBOLP (keysym)) 4122 if (SYMBOLP (keysym))
4143 { 4123 {
4144 Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil); 4124 Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
4145 Emchar c = (CHAR_OR_CHAR_INTP (code) 4125 Emchar c = (CHAR_OR_CHAR_INTP (code)
4146 ? XCHAR_OR_CHAR_INT (code) : -1); 4126 ? XCHAR_OR_CHAR_INT (code) : (Emchar) -1);
4147 /* Calling Fsingle_key_description() would cons more */ 4127 /* Calling Fsingle_key_description() would cons more */
4148 #if 0 /* This is bogus */ 4128 #if 0 /* This is bogus */
4149 if (EQ (keysym, QKlinefeed)) 4129 if (EQ (keysym, QKlinefeed))
4150 buffer_insert_c_string (buf, "LFD"); 4130 buffer_insert_c_string (buf, "LFD");
4151 else if (EQ (keysym, QKtab)) 4131 else if (EQ (keysym, QKtab))