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;