Mercurial > hg > xemacs-beta
comparison src/keymap.c @ 440:8de8e3f6228a r21-2-28
Import from CVS: tag r21-2-28
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:33:38 +0200 |
parents | 84b14dcb0985 |
children | abe6d1db359e |
comparison
equal
deleted
inserted
replaced
439:357dd071b03c | 440:8de8e3f6228a |
---|---|
139 compatibility. | 139 compatibility. |
140 | 140 |
141 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 |
142 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 |
143 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 |
144 map-keymap, which is roughly analagous to maphash. | 144 map-keymap, which is roughly analogous to maphash. |
145 | 145 |
146 Note that map-keymap perpetuates the illusion that the "bucky" submaps | 146 Note that map-keymap perpetuates the illusion that the "bucky" submaps |
147 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 |
148 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 |
149 submaps of the keymap, just the bucky ones. | 149 submaps of the keymap, just the bucky ones. |
154 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- |
155 key sequence than "C-x" is. | 155 key sequence than "C-x" is. |
156 | 156 |
157 */ | 157 */ |
158 | 158 |
159 typedef struct Lisp_Keymap | 159 struct Lisp_Keymap |
160 { | 160 { |
161 struct lcrecord_header header; | 161 struct lcrecord_header header; |
162 Lisp_Object parents; /* Keymaps to be searched after this one | 162 Lisp_Object parents; /* Keymaps to be searched after this one. |
163 * An ordered list */ | 163 An ordered list */ |
164 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 |
165 * when reading from this keymap */ | 165 when reading from this keymap */ |
166 | |
167 Lisp_Object table; /* The contents of this keymap */ | 166 Lisp_Object table; /* The contents of this keymap */ |
168 Lisp_Object inverse_table; /* The inverse mapping of the above */ | 167 Lisp_Object inverse_table; /* The inverse mapping of the above */ |
169 | |
170 Lisp_Object default_binding; /* Use this if no other binding is found | 168 Lisp_Object default_binding; /* Use this if no other binding is found |
171 * (this overrides parent maps and the | 169 (this overrides parent maps and the |
172 * normal global-map lookup). */ | 170 normal global-map lookup). */ |
173 | |
174 | |
175 Lisp_Object sub_maps_cache; /* Cache of directly inferior keymaps; | 171 Lisp_Object sub_maps_cache; /* Cache of directly inferior keymaps; |
176 This holds an alist, of the key and the | 172 This holds an alist, of the key and the |
177 maps, or the modifier bit and the map. | 173 maps, or the modifier bit and the map. |
178 If this is the symbol t, then the cache | 174 If this is the symbol t, then the cache |
179 needs to be recomputed. | 175 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. */ | |
184 Lisp_Object name; /* Just for debugging convenience */ | 176 Lisp_Object name; /* Just for debugging convenience */ |
185 } Lisp_Keymap; | 177 }; |
186 | 178 |
187 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier) | 179 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier) |
188 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0) | 180 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0) |
189 | 181 |
190 | 182 |
191 | 183 |
192 /* Actually allocate storage for these variables */ | 184 /* Actually allocate storage for these variables */ |
193 | 185 |
194 static Lisp_Object Vcurrent_global_map; /* Always a keymap */ | 186 Lisp_Object Vcurrent_global_map; /* Always a keymap */ |
195 | 187 |
196 static Lisp_Object Vmouse_grabbed_buffer; | 188 static Lisp_Object Vmouse_grabbed_buffer; |
197 | 189 |
198 /* Alist of minor mode variables and keymaps. */ | 190 /* Alist of minor mode variables and keymaps. */ |
199 static Lisp_Object Qminor_mode_map_alist; | 191 static Lisp_Object Qminor_mode_map_alist; |
228 void (*elt_describer) (Lisp_Object, Lisp_Object), | 220 void (*elt_describer) (Lisp_Object, Lisp_Object), |
229 int partial, | 221 int partial, |
230 Lisp_Object shadow, | 222 Lisp_Object shadow, |
231 int mice_only_p, | 223 int mice_only_p, |
232 Lisp_Object buffer); | 224 Lisp_Object buffer); |
225 static Lisp_Object keymap_submaps (Lisp_Object keymap); | |
233 | 226 |
234 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift; | 227 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift; |
235 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3; | 228 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3; |
236 Lisp_Object Qbutton4, Qbutton5, Qbutton6, Qbutton7; | 229 Lisp_Object Qbutton4, Qbutton5, Qbutton6, Qbutton7; |
237 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up; | 230 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up; |
268 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 261 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
269 { | 262 { |
270 /* This function can GC */ | 263 /* This function can GC */ |
271 Lisp_Keymap *keymap = XKEYMAP (obj); | 264 Lisp_Keymap *keymap = XKEYMAP (obj); |
272 char buf[200]; | 265 char buf[200]; |
273 int size = XINT (Fkeymap_fullness (obj)); | |
274 if (print_readably) | 266 if (print_readably) |
275 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid); | 267 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid); |
276 write_c_string ("#<keymap ", printcharfun); | 268 write_c_string ("#<keymap ", printcharfun); |
277 if (!NILP (keymap->name)) | 269 if (!NILP (keymap->name)) |
278 print_internal (keymap->name, printcharfun, 1); | 270 { |
279 /* #### Yuck! This is no way to form plural! --hniksic */ | 271 print_internal (keymap->name, printcharfun, 1); |
280 sprintf (buf, "%s%d entr%s 0x%x>", | 272 write_c_string (" ", printcharfun); |
281 (NILP (keymap->name) ? "" : " "), | 273 } |
282 size, | 274 sprintf (buf, "size %ld 0x%x>", |
283 ((size == 1) ? "y" : "ies"), | 275 (long) XINT (Fkeymap_fullness (obj)), keymap->header.uid); |
284 keymap->header.uid); | |
285 write_c_string (buf, printcharfun); | 276 write_c_string (buf, printcharfun); |
286 } | 277 } |
287 | 278 |
288 static const struct lrecord_description keymap_description[] = { | 279 static const struct lrecord_description keymap_description[] = { |
289 { XD_LISP_OBJECT, offsetof(Lisp_Keymap, parents), 6 }, | 280 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, parents) }, |
290 { XD_LISP_OBJECT, offsetof(Lisp_Keymap, name), 1 }, | 281 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, prompt) }, |
282 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, table) }, | |
283 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, inverse_table) }, | |
284 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, default_binding) }, | |
285 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, sub_maps_cache) }, | |
286 { XD_LISP_OBJECT, offsetof (Lisp_Keymap, name) }, | |
291 { XD_END } | 287 { XD_END } |
292 }; | 288 }; |
293 | 289 |
294 /* No need for keymap_equal #### Why not? */ | 290 /* No need for keymap_equal #### Why not? */ |
295 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap, | 291 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap, |
317 gcpro1.nvars = 0; | 313 gcpro1.nvars = 0; |
318 | 314 |
319 start_keymap = get_keymap (start_keymap, 1, 1); | 315 start_keymap = get_keymap (start_keymap, 1, 1); |
320 keymap = start_keymap; | 316 keymap = start_keymap; |
321 /* Hack special-case parents at top-level */ | 317 /* Hack special-case parents at top-level */ |
322 tail = ((!NILP (tail)) ? tail : XKEYMAP (keymap)->parents); | 318 tail = !NILP (tail) ? tail : XKEYMAP (keymap)->parents; |
323 | 319 |
324 for (;;) | 320 for (;;) |
325 { | 321 { |
326 Lisp_Object result; | 322 Lisp_Object result; |
327 | 323 |
328 QUIT; | 324 QUIT; |
329 result = ((mapper) (keymap, mapper_arg)); | 325 result = mapper (keymap, mapper_arg); |
330 if (!NILP (result)) | 326 if (!NILP (result)) |
331 { | 327 { |
332 while (CONSP (malloc_bites)) | 328 while (CONSP (malloc_bites)) |
333 { | 329 { |
334 struct Lisp_Cons *victim = XCONS (malloc_bites); | 330 Lisp_Cons *victim = XCONS (malloc_bites); |
335 malloc_bites = victim->cdr; | 331 malloc_bites = victim->cdr; |
336 free_cons (victim); | 332 free_cons (victim); |
337 } | 333 } |
338 UNGCPRO; | 334 UNGCPRO; |
339 return result; | 335 return result; |
346 return Qnil; /* Nothing found */ | 342 return Qnil; /* Nothing found */ |
347 } | 343 } |
348 stack_depth--; | 344 stack_depth--; |
349 if (CONSP (malloc_bites)) | 345 if (CONSP (malloc_bites)) |
350 { | 346 { |
351 struct Lisp_Cons *victim = XCONS (malloc_bites); | 347 Lisp_Cons *victim = XCONS (malloc_bites); |
352 tail = victim->car; | 348 tail = victim->car; |
353 malloc_bites = victim->cdr; | 349 malloc_bites = victim->cdr; |
354 free_cons (victim); | 350 free_cons (victim); |
355 } | 351 } |
356 else | 352 else |
581 /* else the list's tail has been modified, so we don't need to | 577 /* else the list's tail has been modified, so we don't need to |
582 touch the hash table again (the pointer in there is ok). | 578 touch the hash table again (the pointer in there is ok). |
583 */ | 579 */ |
584 } | 580 } |
585 | 581 |
582 /* Prevent luser from shooting herself in the foot using something like | |
583 (define-key ctl-x-4-map "p" global-map) */ | |
584 static void | |
585 check_keymap_definition_loop (Lisp_Object def, Lisp_Keymap *to_keymap) | |
586 { | |
587 def = get_keymap (def, 0, 0); | |
588 | |
589 if (KEYMAPP (def)) | |
590 { | |
591 Lisp_Object maps; | |
592 | |
593 if (XKEYMAP (def) == to_keymap) | |
594 signal_simple_error ("Cyclic keymap definition", def); | |
595 | |
596 for (maps = keymap_submaps (def); | |
597 CONSP (maps); | |
598 maps = XCDR (maps)) | |
599 check_keymap_definition_loop (XCDR (XCAR (maps)), to_keymap); | |
600 } | |
601 } | |
586 | 602 |
587 static void | 603 static void |
588 keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap, | 604 keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap, |
589 Lisp_Object value) | 605 Lisp_Object def) |
590 { | 606 { |
591 Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil); | 607 Lisp_Object prev_def = Fgethash (keysym, keymap->table, Qnil); |
592 | 608 |
593 if (EQ (prev_value, value)) | 609 if (EQ (prev_def, def)) |
594 return; | 610 return; |
595 if (!NILP (prev_value)) | 611 |
612 check_keymap_definition_loop (def, keymap); | |
613 | |
614 if (!NILP (prev_def)) | |
596 keymap_delete_inverse_internal (keymap->inverse_table, | 615 keymap_delete_inverse_internal (keymap->inverse_table, |
597 keysym, prev_value); | 616 keysym, prev_def); |
598 if (NILP (value)) | 617 if (NILP (def)) |
599 { | 618 { |
600 keymap->fullness--; | |
601 if (keymap->fullness < 0) abort (); | |
602 Fremhash (keysym, keymap->table); | 619 Fremhash (keysym, keymap->table); |
603 } | 620 } |
604 else | 621 else |
605 { | 622 { |
606 if (NILP (prev_value)) | 623 Fputhash (keysym, def, keymap->table); |
607 keymap->fullness++; | |
608 Fputhash (keysym, value, keymap->table); | |
609 keymap_store_inverse_internal (keymap->inverse_table, | 624 keymap_store_inverse_internal (keymap->inverse_table, |
610 keysym, value); | 625 keysym, def); |
611 } | 626 } |
612 keymap_tick++; | 627 keymap_tick++; |
613 } | 628 } |
614 | 629 |
615 | 630 |
633 keymap_store (Lisp_Object keymap, CONST struct key_data *key, | 648 keymap_store (Lisp_Object keymap, CONST struct key_data *key, |
634 Lisp_Object value) | 649 Lisp_Object value) |
635 { | 650 { |
636 Lisp_Object keysym = key->keysym; | 651 Lisp_Object keysym = key->keysym; |
637 unsigned int modifiers = key->modifiers; | 652 unsigned int modifiers = key->modifiers; |
638 Lisp_Keymap *k; | 653 Lisp_Keymap *k = XKEYMAP (keymap); |
639 | 654 |
640 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER | 655 assert ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER |
641 | MOD_ALT | MOD_SHIFT)) != 0) | 656 | MOD_ALT | MOD_SHIFT)) == 0); |
642 abort (); | |
643 | |
644 k = XKEYMAP (keymap); | |
645 | 657 |
646 /* If the keysym is a one-character symbol, use the char code instead. */ | 658 /* If the keysym is a one-character symbol, use the char code instead. */ |
647 if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1) | 659 if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1) |
648 { | 660 keysym = make_char (string_char (XSYMBOL (keysym)->name, 0)); |
649 Lisp_Object run_the_gcc_developers_over_with_a_steamroller = | |
650 make_char (string_char (XSYMBOL (keysym)->name, 0)); | |
651 keysym = run_the_gcc_developers_over_with_a_steamroller; | |
652 } | |
653 | 661 |
654 if (modifiers & MOD_META) /* Utterly hateful ESC lossage */ | 662 if (modifiers & MOD_META) /* Utterly hateful ESC lossage */ |
655 { | 663 { |
656 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), | 664 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), |
657 k->table, Qnil); | 665 k->table, Qnil); |
757 keymap->prompt = Qnil; | 765 keymap->prompt = Qnil; |
758 keymap->table = Qnil; | 766 keymap->table = Qnil; |
759 keymap->inverse_table = Qnil; | 767 keymap->inverse_table = Qnil; |
760 keymap->default_binding = Qnil; | 768 keymap->default_binding = Qnil; |
761 keymap->sub_maps_cache = Qnil; /* No possible submaps */ | 769 keymap->sub_maps_cache = Qnil; /* No possible submaps */ |
762 keymap->fullness = 0; | |
763 keymap->name = Qnil; | 770 keymap->name = Qnil; |
764 | 771 |
765 if (size != 0) /* hack for copy-keymap */ | 772 if (size != 0) /* hack for copy-keymap */ |
766 { | 773 { |
767 keymap->table = | 774 keymap->table = |
1049 { | 1056 { |
1050 Lisp_Object idx = Fcdr (object); | 1057 Lisp_Object idx = Fcdr (object); |
1051 struct key_data indirection; | 1058 struct key_data indirection; |
1052 if (CHARP (idx)) | 1059 if (CHARP (idx)) |
1053 { | 1060 { |
1054 struct Lisp_Event event; | 1061 Lisp_Event event; |
1055 event.event_type = empty_event; | 1062 event.event_type = empty_event; |
1056 character_to_event (XCHAR (idx), &event, | 1063 character_to_event (XCHAR (idx), &event, |
1057 XCONSOLE (Vselected_console), 0, 0); | 1064 XCONSOLE (Vselected_console), 0, 0); |
1058 indirection = event.event.key; | 1065 indirection = event.event.key; |
1059 } | 1066 } |
1135 Lisp_Keymap *new_keymap = XKEYMAP (nkm); | 1142 Lisp_Keymap *new_keymap = XKEYMAP (nkm); |
1136 struct copy_keymap_inverse_closure copy_keymap_inverse_closure; | 1143 struct copy_keymap_inverse_closure copy_keymap_inverse_closure; |
1137 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table; | 1144 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table; |
1138 | 1145 |
1139 new_keymap->parents = Fcopy_sequence (keymap->parents); | 1146 new_keymap->parents = Fcopy_sequence (keymap->parents); |
1140 new_keymap->fullness = keymap->fullness; | |
1141 new_keymap->sub_maps_cache = Qnil; /* No submaps */ | 1147 new_keymap->sub_maps_cache = Qnil; /* No submaps */ |
1142 new_keymap->table = Fcopy_hash_table (keymap->table); | 1148 new_keymap->table = Fcopy_hash_table (keymap->table); |
1143 new_keymap->inverse_table = Fcopy_hash_table (keymap->inverse_table); | 1149 new_keymap->inverse_table = Fcopy_hash_table (keymap->inverse_table); |
1144 new_keymap->default_binding = keymap->default_binding; | 1150 new_keymap->default_binding = keymap->default_binding; |
1145 /* After copying the inverse map, we need to copy the conses which | 1151 /* After copying the inverse map, we need to copy the conses which |
1213 int fullness; | 1219 int fullness; |
1214 Lisp_Object sub_maps; | 1220 Lisp_Object sub_maps; |
1215 struct gcpro gcpro1, gcpro2; | 1221 struct gcpro gcpro1, gcpro2; |
1216 | 1222 |
1217 keymap = get_keymap (keymap, 1, 1); | 1223 keymap = get_keymap (keymap, 1, 1); |
1218 fullness = XKEYMAP (keymap)->fullness; | 1224 fullness = XINT (Fhash_table_count (XKEYMAP (keymap)->table)); |
1219 sub_maps = keymap_submaps (keymap); | |
1220 GCPRO2 (keymap, sub_maps); | 1225 GCPRO2 (keymap, sub_maps); |
1221 for (; !NILP (sub_maps); sub_maps = XCDR (sub_maps)) | 1226 for (sub_maps = keymap_submaps (keymap); |
1227 !NILP (sub_maps); | |
1228 sub_maps = XCDR (sub_maps)) | |
1222 { | 1229 { |
1223 if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0) | 1230 if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0) |
1224 { | 1231 { |
1225 Lisp_Object sub_map = XCDR (XCAR (sub_maps)); | 1232 Lisp_Object bucky_map = XCDR (XCAR (sub_maps)); |
1226 fullness--; /* don't count bucky maps */ | 1233 fullness--; /* don't count bucky maps themselves. */ |
1227 fullness += keymap_fullness (sub_map); | 1234 fullness += keymap_fullness (bucky_map); |
1228 } | 1235 } |
1229 } | 1236 } |
1230 UNGCPRO; | 1237 UNGCPRO; |
1231 return fullness; | 1238 return fullness; |
1232 } | 1239 } |
1279 ("The `shift' modifier may not be applied to ASCII keysyms", | 1286 ("The `shift' modifier may not be applied to ASCII keysyms", |
1280 spec); | 1287 spec); |
1281 } | 1288 } |
1282 else | 1289 else |
1283 { | 1290 { |
1284 signal_simple_error ("Unknown keysym specifier", | 1291 signal_simple_error ("Unknown keysym specifier", *keysym); |
1285 *keysym); | |
1286 } | 1292 } |
1287 | 1293 |
1288 if (SYMBOLP (*keysym)) | 1294 if (SYMBOLP (*keysym)) |
1289 { | 1295 { |
1290 char *name = (char *) | 1296 char *name = (char *) string_data (XSYMBOL (*keysym)->name); |
1291 string_data (XSYMBOL (*keysym)->name); | |
1292 | 1297 |
1293 /* FSFmacs uses symbols with the printed representation of keysyms in | 1298 /* FSFmacs uses symbols with the printed representation of keysyms in |
1294 their names, like 'M-x, and we use the syntax '(meta x). So, to avoid | 1299 their names, like 'M-x, and we use the syntax '(meta x). So, to avoid |
1295 confusion, notice the M-x syntax and signal an error - because | 1300 confusion, notice the M-x syntax and signal an error - because |
1296 otherwise it would be interpreted as a regular keysym, and would even | 1301 otherwise it would be interpreted as a regular keysym, and would even |
1390 static void | 1395 static void |
1391 define_key_parser (Lisp_Object spec, struct key_data *returned_value) | 1396 define_key_parser (Lisp_Object spec, struct key_data *returned_value) |
1392 { | 1397 { |
1393 if (CHAR_OR_CHAR_INTP (spec)) | 1398 if (CHAR_OR_CHAR_INTP (spec)) |
1394 { | 1399 { |
1395 struct Lisp_Event event; | 1400 Lisp_Event event; |
1396 event.event_type = empty_event; | 1401 event.event_type = empty_event; |
1397 character_to_event (XCHAR_OR_CHAR_INT (spec), &event, | 1402 character_to_event (XCHAR_OR_CHAR_INT (spec), &event, |
1398 XCONSOLE (Vselected_console), 0, 0); | 1403 XCONSOLE (Vselected_console), 0, 0); |
1399 returned_value->keysym = event.event.key.keysym; | 1404 returned_value->keysym = event.event.key.keysym; |
1400 returned_value->modifiers = event.event.key.modifiers; | 1405 returned_value->modifiers = event.event.key.modifiers; |
1538 XEVENT (event)->event.key.modifiers = raw_key.modifiers; | 1543 XEVENT (event)->event.key.modifiers = raw_key.modifiers; |
1539 } | 1544 } |
1540 | 1545 |
1541 | 1546 |
1542 int | 1547 int |
1543 event_matches_key_specifier_p (struct Lisp_Event *event, | 1548 event_matches_key_specifier_p (Lisp_Event *event, Lisp_Object key_specifier) |
1544 Lisp_Object key_specifier) | |
1545 { | 1549 { |
1546 Lisp_Object event2; | 1550 Lisp_Object event2; |
1547 int retval; | 1551 int retval; |
1548 struct gcpro gcpro1; | 1552 struct gcpro gcpro1; |
1549 | 1553 |
1592 } | 1596 } |
1593 | 1597 |
1594 static int | 1598 static int |
1595 meta_prefix_char_p (CONST struct key_data *key) | 1599 meta_prefix_char_p (CONST struct key_data *key) |
1596 { | 1600 { |
1597 struct Lisp_Event event; | 1601 Lisp_Event event; |
1598 | 1602 |
1599 event.event_type = key_press_event; | 1603 event.event_type = key_press_event; |
1600 event.channel = Vselected_console; | 1604 event.channel = Vselected_console; |
1601 event.event.key.keysym = key->keysym; | 1605 event.event.key.keysym = key->keysym; |
1602 event.event.key.modifiers = key->modifiers; | 1606 event.event.key.modifiers = key->modifiers; |
1898 (define-key my-map "\M-a" 'my-command) | 1902 (define-key my-map "\M-a" 'my-command) |
1899 and then perhaps | 1903 and then perhaps |
1900 (defvar my-escape-map (lookup-key my-map "\e")) | 1904 (defvar my-escape-map (lookup-key my-map "\e")) |
1901 if the luser really wants the map in a variable. | 1905 if the luser really wants the map in a variable. |
1902 */ | 1906 */ |
1903 Lisp_Object mmap; | 1907 Lisp_Object meta_map; |
1904 struct gcpro ngcpro1; | 1908 struct gcpro ngcpro1; |
1905 | 1909 |
1906 NGCPRO1 (c); | 1910 NGCPRO1 (c); |
1907 mmap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), | 1911 meta_map = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), |
1908 XKEYMAP (keymap)->table, Qnil); | 1912 XKEYMAP (keymap)->table, Qnil); |
1909 if (!NILP (mmap) | 1913 if (!NILP (meta_map) |
1910 && keymap_fullness (mmap) != 0) | 1914 && keymap_fullness (meta_map) != 0) |
1911 { | 1915 signal_simple_error_2 |
1912 Lisp_Object desc | 1916 ("Map contains meta-bindings, can't bind", |
1913 = Fsingle_key_description (Vmeta_prefix_char); | 1917 Fsingle_key_description (Vmeta_prefix_char), keymap); |
1914 signal_simple_error_2 | |
1915 ("Map contains meta-bindings, can't bind", desc, keymap); | |
1916 } | |
1917 NUNGCPRO; | 1918 NUNGCPRO; |
1918 } | 1919 } |
1919 else | 1920 else |
1920 { | 1921 { |
1921 metized = 1; | 1922 metized = 1; |
1932 raw_key2.modifiers = 0; | 1933 raw_key2.modifiers = 0; |
1933 } | 1934 } |
1934 | 1935 |
1935 if (metized) | 1936 if (metized) |
1936 { | 1937 { |
1937 raw_key1.modifiers |= MOD_META; | 1938 raw_key1.modifiers |= MOD_META; |
1938 raw_key2.modifiers |= MOD_META; | 1939 raw_key2.modifiers |= MOD_META; |
1939 metized = 0; | 1940 metized = 0; |
1940 } | 1941 } |
1941 | 1942 |
1942 /* This crap is to make sure that someone doesn't bind something like | 1943 /* This crap is to make sure that someone doesn't bind something like |
3091 Lisp_Object accessible_keymaps = Qnil; | 3092 Lisp_Object accessible_keymaps = Qnil; |
3092 struct accessible_keymaps_closure c; | 3093 struct accessible_keymaps_closure c; |
3093 c.tail = Qnil; | 3094 c.tail = Qnil; |
3094 GCPRO4 (accessible_keymaps, c.tail, prefix, keymap); | 3095 GCPRO4 (accessible_keymaps, c.tail, prefix, keymap); |
3095 | 3096 |
3097 keymap = get_keymap (keymap, 1, 1); | |
3098 | |
3096 retry: | 3099 retry: |
3097 keymap = get_keymap (keymap, 1, 1); | |
3098 if (NILP (prefix)) | 3100 if (NILP (prefix)) |
3099 prefix = make_vector (0, Qnil); | 3101 { |
3100 else if (!VECTORP (prefix) || STRINGP (prefix)) | 3102 prefix = make_vector (0, Qnil); |
3101 { | 3103 } |
3102 prefix = wrong_type_argument (Qarrayp, prefix); | 3104 else if (VECTORP (prefix) || STRINGP (prefix)) |
3103 goto retry; | |
3104 } | |
3105 else | |
3106 { | 3105 { |
3107 int len = XINT (Flength (prefix)); | 3106 int len = XINT (Flength (prefix)); |
3108 Lisp_Object def = Flookup_key (keymap, prefix, Qnil); | 3107 Lisp_Object def; |
3109 Lisp_Object p; | 3108 Lisp_Object p; |
3110 int iii; | 3109 int iii; |
3111 struct gcpro ngcpro1; | 3110 struct gcpro ngcpro1; |
3112 | 3111 |
3112 if (len == 0) | |
3113 { | |
3114 prefix = Qnil; | |
3115 goto retry; | |
3116 } | |
3117 | |
3118 def = Flookup_key (keymap, prefix, Qnil); | |
3113 def = get_keymap (def, 0, 1); | 3119 def = get_keymap (def, 0, 1); |
3114 if (!KEYMAPP (def)) | 3120 if (!KEYMAPP (def)) |
3115 goto RETURN; | 3121 goto RETURN; |
3116 | 3122 |
3117 keymap = def; | 3123 keymap = def; |
3124 XVECTOR_DATA (p)[iii] = make_key_description (&key, 1); | 3130 XVECTOR_DATA (p)[iii] = make_key_description (&key, 1); |
3125 } | 3131 } |
3126 NUNGCPRO; | 3132 NUNGCPRO; |
3127 prefix = p; | 3133 prefix = p; |
3128 } | 3134 } |
3135 else | |
3136 { | |
3137 prefix = wrong_type_argument (Qarrayp, prefix); | |
3138 goto retry; | |
3139 } | |
3129 | 3140 |
3130 accessible_keymaps = list1 (Fcons (prefix, keymap)); | 3141 accessible_keymaps = list1 (Fcons (prefix, keymap)); |
3131 | 3142 |
3132 /* For each map in the list maps, | 3143 /* For each map in the list maps, look at any other maps it points |
3133 look at any other maps it points to | 3144 to and stick them at the end if they are not already in the list */ |
3134 and stick them at the end if they are not already in the list */ | |
3135 | 3145 |
3136 for (c.tail = accessible_keymaps; | 3146 for (c.tail = accessible_keymaps; |
3137 !NILP (c.tail); | 3147 !NILP (c.tail); |
3138 c.tail = XCDR (c.tail)) | 3148 c.tail = XCDR (c.tail)) |
3139 { | 3149 { |
3207 if (EVENTP (key) || CHAR_OR_CHAR_INTP (key)) | 3217 if (EVENTP (key) || CHAR_OR_CHAR_INTP (key)) |
3208 { | 3218 { |
3209 char buf [255]; | 3219 char buf [255]; |
3210 if (!EVENTP (key)) | 3220 if (!EVENTP (key)) |
3211 { | 3221 { |
3212 struct Lisp_Event event; | 3222 Lisp_Event event; |
3213 event.event_type = empty_event; | 3223 event.event_type = empty_event; |
3214 CHECK_CHAR_COERCE_INT (key); | 3224 CHECK_CHAR_COERCE_INT (key); |
3215 character_to_event (XCHAR (key), &event, | 3225 character_to_event (XCHAR (key), &event, |
3216 XCONSOLE (Vselected_console), 0, 1); | 3226 XCONSOLE (Vselected_console), 0, 1); |
3217 format_event_object (buf, &event, 1); | 3227 format_event_object (buf, &event, 1); |
3456 | 3466 |
3457 static void | 3467 static void |
3458 format_raw_keys (struct key_data *keys, int count, char *buf) | 3468 format_raw_keys (struct key_data *keys, int count, char *buf) |
3459 { | 3469 { |
3460 int i; | 3470 int i; |
3461 struct Lisp_Event event; | 3471 Lisp_Event event; |
3462 event.event_type = key_press_event; | 3472 event.event_type = key_press_event; |
3463 event.channel = Vselected_console; | 3473 event.channel = Vselected_console; |
3464 for (i = 0; i < count; i++) | 3474 for (i = 0; i < count; i++) |
3465 { | 3475 { |
3466 event.event.key.keysym = keys[i].keysym; | 3476 event.event.key.keysym = keys[i].keysym; |