Mercurial > hg > xemacs-beta
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 ©_keymap_inverse_closure); | 1141 ©_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)) |