diff options
| author | Jim Blandy | 1993-05-04 02:32:22 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-05-04 02:32:22 +0000 |
| commit | 806451194be01bc8712d9f43793b3f6ec8c5458e (patch) | |
| tree | de0ada0d82e535bf71e05020d18b1a8a8e4e353b /src | |
| parent | 9083124bb71c9db86e7ab2338b0aeb0dbbbb9a45 (diff) | |
| download | emacs-806451194be01bc8712d9f43793b3f6ec8c5458e.tar.gz emacs-806451194be01bc8712d9f43793b3f6ec8c5458e.zip | |
Implement extra_keyboard_modifiers properly.
* keyboard.c (syms_of_keyboard): Doc fix for
extra-keyboard-modifiers; use the same modifier bits as we do for
characters.
(read_char): Apply all the modifiers in extra_keyboard_modifiers
to the input characters, so you can get hyper, super, and the rest
of the gang.
* xterm.c (x_emacs_to_x_modifiers): New function.
(x_convert_modifiers): Renamed to x_x_to_emacs_modifiers, for
consistency. Callers changed.
(XTread_socket): Apply x_emacs_to_x_modifiers to
extra_keyboard_modifiers before setting the state member of the
event; this will get all the modifiers on ASCII characters.
* keyboard.c (kbd_buffer_get_event): Don't generate switch-frame
events if they'd only switch to the frame already selected. This
avoids lots of extra switch-frame events when using a separate
minibuffer.
* keyboard.c (Fcurrent_input_mode): New function.
* keyboard.c (read_key_sequence): Let the `modifiers' variable in
the code which deals with KEY being unbound be an int, not a
Lisp_Object.
Make the modifier manipulation functions more robust. The old way
caused a bug once, and probably would again.
* termhooks.h (alt_modifier, super_modifier, hyper_modifier,
shift_modifier, ctrl_modifier, meta_modifier): Shift these all
down one bit in value, to avoid sign extension problems.
* lisp.h (CHAR_META, CHAR_CTL, CHAR_SHIFT): Fix these definitions too.
* keyboard.c (lispy_modifier_list): Ignore modifier bits beyond
what our table of modifier names can handle.
(apply_modifiers): Don't abort if you see extra modifier bits,
just remove them.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 119 |
1 files changed, 85 insertions, 34 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index d5e15152526..2b51d6abb90 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1448,11 +1448,38 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1448 | if (noninteractive && XTYPE (c) == Lisp_Int && XINT (c) < 0) | 1448 | if (noninteractive && XTYPE (c) == Lisp_Int && XINT (c) < 0) |
| 1449 | Fkill_emacs (make_number (1)); | 1449 | Fkill_emacs (make_number (1)); |
| 1450 | 1450 | ||
| 1451 | /* Test for ControlMask and Mod1Mask. */ | 1451 | if (XTYPE (c) == Lisp_Int) |
| 1452 | if (extra_keyboard_modifiers & 4) | 1452 | { |
| 1453 | c &= ~0140; | 1453 | /* Add in any extra modifiers, where appropriate. */ |
| 1454 | if (extra_keyboard_modifiers & 8) | 1454 | if ((extra_keyboard_modifiers & CHAR_CTL) |
| 1455 | c |= 0200; | 1455 | || ((extra_keyboard_modifiers & 0177) < ' ' |
| 1456 | && (extra_keyboard_modifiers & 0177) != 0)) | ||
| 1457 | { | ||
| 1458 | /* If it's already a control character, don't mess with it. */ | ||
| 1459 | if ((c & 0177) == 0) | ||
| 1460 | ; | ||
| 1461 | |||
| 1462 | /* Making ? a control character should result in DEL. */ | ||
| 1463 | else if ((c & 0177) == '?') | ||
| 1464 | c |= 0177; | ||
| 1465 | |||
| 1466 | /* ASCII control chars are made from letters (both cases), | ||
| 1467 | as well as the non-letters within 0100...0137. */ | ||
| 1468 | else if ((c & 0137) >= 0101 && (c & 0137) <= 0132) | ||
| 1469 | c = (c & (037 | ~0177)); | ||
| 1470 | else if ((c & 0177) >= 0100 && (c & 0177) <= 0137) | ||
| 1471 | c = (c & (037 | ~0177)); | ||
| 1472 | |||
| 1473 | /* Anything else must get its high control bit set. */ | ||
| 1474 | else | ||
| 1475 | c = c | ctrl_modifier; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | /* Transfer any other modifier bits directly from | ||
| 1479 | extra_keyboard_modifiers to c. Ignore the actual character code | ||
| 1480 | in the low 16 bits of extra_keyboard_modifiers. */ | ||
| 1481 | c |= (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL); | ||
| 1482 | } | ||
| 1456 | 1483 | ||
| 1457 | non_reread: | 1484 | non_reread: |
| 1458 | 1485 | ||
| @@ -1829,11 +1856,10 @@ kbd_buffer_get_event () | |||
| 1829 | if (! NILP (focus)) | 1856 | if (! NILP (focus)) |
| 1830 | frame = focus; | 1857 | frame = focus; |
| 1831 | 1858 | ||
| 1832 | if (! EQ (frame, internal_last_event_frame)) | 1859 | if (! EQ (frame, internal_last_event_frame) |
| 1833 | { | 1860 | && XFRAME (frame) != selected_frame) |
| 1834 | internal_last_event_frame = frame; | 1861 | obj = make_lispy_switch_frame (frame); |
| 1835 | obj = make_lispy_switch_frame (frame); | 1862 | internal_last_event_frame = frame; |
| 1836 | } | ||
| 1837 | } | 1863 | } |
| 1838 | #endif | 1864 | #endif |
| 1839 | 1865 | ||
| @@ -1874,11 +1900,10 @@ kbd_buffer_get_event () | |||
| 1874 | if (NILP (frame)) | 1900 | if (NILP (frame)) |
| 1875 | XSET (frame, Lisp_Frame, f); | 1901 | XSET (frame, Lisp_Frame, f); |
| 1876 | 1902 | ||
| 1877 | if (! EQ (frame, internal_last_event_frame)) | 1903 | if (! EQ (frame, internal_last_event_frame) |
| 1878 | { | 1904 | && XFRAME (frame) != selected_frame) |
| 1879 | XSET (internal_last_event_frame, Lisp_Frame, frame); | 1905 | obj = make_lispy_switch_frame (internal_last_event_frame); |
| 1880 | obj = make_lispy_switch_frame (internal_last_event_frame); | 1906 | internal_last_event_frame = frame; |
| 1881 | } | ||
| 1882 | } | 1907 | } |
| 1883 | #endif | 1908 | #endif |
| 1884 | 1909 | ||
| @@ -2469,6 +2494,7 @@ static char *modifier_names[] = | |||
| 2469 | "drag", "click", 0, 0, 0, 0, 0, 0, | 2494 | "drag", "click", 0, 0, 0, 0, 0, 0, |
| 2470 | 0, 0, "alt", "super", "hyper", "shift", "control", "meta" | 2495 | 0, 0, "alt", "super", "hyper", "shift", "control", "meta" |
| 2471 | }; | 2496 | }; |
| 2497 | #define NUM_MOD_NAMES (sizeof (modifier_names) / sizeof (modifier_names[0])) | ||
| 2472 | 2498 | ||
| 2473 | static Lisp_Object modifier_symbols; | 2499 | static Lisp_Object modifier_symbols; |
| 2474 | 2500 | ||
| @@ -2481,14 +2507,10 @@ lispy_modifier_list (modifiers) | |||
| 2481 | int i; | 2507 | int i; |
| 2482 | 2508 | ||
| 2483 | modifier_list = Qnil; | 2509 | modifier_list = Qnil; |
| 2484 | for (i = 0; (1<<i) <= modifiers; i++) | 2510 | for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++) |
| 2485 | if (modifiers & (1<<i)) | 2511 | if (modifiers & (1<<i)) |
| 2486 | { | 2512 | modifier_list = Fcons (XVECTOR (modifier_symbols)->contents[i], |
| 2487 | if (i >= XVECTOR (modifier_symbols)->size) | 2513 | modifier_list); |
| 2488 | abort (); | ||
| 2489 | modifier_list = Fcons (XVECTOR (modifier_symbols)->contents[i], | ||
| 2490 | modifier_list); | ||
| 2491 | } | ||
| 2492 | 2514 | ||
| 2493 | return modifier_list; | 2515 | return modifier_list; |
| 2494 | } | 2516 | } |
| @@ -2554,10 +2576,11 @@ apply_modifiers (modifiers, base) | |||
| 2554 | { | 2576 | { |
| 2555 | Lisp_Object cache, index, entry, new_symbol; | 2577 | Lisp_Object cache, index, entry, new_symbol; |
| 2556 | 2578 | ||
| 2579 | /* Mask out upper bits. We don't know where this value's been. */ | ||
| 2580 | modifiers &= (1<<VALBITS) - 1; | ||
| 2581 | |||
| 2557 | /* The click modifier never figures into cache indices. */ | 2582 | /* The click modifier never figures into cache indices. */ |
| 2558 | cache = Fget (base, Qmodifier_cache); | 2583 | cache = Fget (base, Qmodifier_cache); |
| 2559 | if (modifiers & ~((1<<VALBITS) - 1)) | ||
| 2560 | abort (); | ||
| 2561 | XFASTINT (index) = (modifiers & ~click_modifier); | 2584 | XFASTINT (index) = (modifiers & ~click_modifier); |
| 2562 | entry = Fassq (index, cache); | 2585 | entry = Fassq (index, cache); |
| 2563 | 2586 | ||
| @@ -2575,8 +2598,6 @@ apply_modifiers (modifiers, base) | |||
| 2575 | Fput (base, Qmodifier_cache, Fcons (entry, cache)); | 2598 | Fput (base, Qmodifier_cache, Fcons (entry, cache)); |
| 2576 | 2599 | ||
| 2577 | /* We have the parsing info now for free, so add it to the caches. */ | 2600 | /* We have the parsing info now for free, so add it to the caches. */ |
| 2578 | if (modifiers & ~((1<<VALBITS) - 1)) | ||
| 2579 | abort (); | ||
| 2580 | XFASTINT (index) = modifiers; | 2601 | XFASTINT (index) = modifiers; |
| 2581 | Fput (new_symbol, Qevent_symbol_element_mask, | 2602 | Fput (new_symbol, Qevent_symbol_element_mask, |
| 2582 | Fcons (base, Fcons (index, Qnil))); | 2603 | Fcons (base, Fcons (index, Qnil))); |
| @@ -2589,8 +2610,8 @@ apply_modifiers (modifiers, base) | |||
| 2589 | You'd think we could just set this once and for all when we | 2610 | You'd think we could just set this once and for all when we |
| 2590 | intern the symbol above, but reorder_modifiers may call us when | 2611 | intern the symbol above, but reorder_modifiers may call us when |
| 2591 | BASE's property isn't set right; we can't assume that just | 2612 | BASE's property isn't set right; we can't assume that just |
| 2592 | because we found something in the cache it must have its kind set | 2613 | because it has a Qmodifier_cache property it must have its |
| 2593 | right. */ | 2614 | Qevent_kind set right as well. */ |
| 2594 | if (NILP (Fget (new_symbol, Qevent_kind))) | 2615 | if (NILP (Fget (new_symbol, Qevent_kind))) |
| 2595 | { | 2616 | { |
| 2596 | Lisp_Object kind = Fget (base, Qevent_kind); | 2617 | Lisp_Object kind = Fget (base, Qevent_kind); |
| @@ -3701,8 +3722,7 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3701 | if (XTYPE (head) == Lisp_Symbol) | 3722 | if (XTYPE (head) == Lisp_Symbol) |
| 3702 | { | 3723 | { |
| 3703 | Lisp_Object breakdown = parse_modifiers (head); | 3724 | Lisp_Object breakdown = parse_modifiers (head); |
| 3704 | Lisp_Object modifiers = | 3725 | int modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car); |
| 3705 | XINT (XCONS (XCONS (breakdown)->cdr)->car); | ||
| 3706 | 3726 | ||
| 3707 | /* We drop unbound `down-' events altogether. */ | 3727 | /* We drop unbound `down-' events altogether. */ |
| 3708 | if (modifiers & down_modifier) | 3728 | if (modifiers & down_modifier) |
| @@ -4457,6 +4477,31 @@ Optional fourth arg QUIT if non-nil specifies character to use for quitting.") | |||
| 4457 | init_sys_modes (); | 4477 | init_sys_modes (); |
| 4458 | return Qnil; | 4478 | return Qnil; |
| 4459 | } | 4479 | } |
| 4480 | |||
| 4481 | DEFUN ("current-input-mode", Fcurrent_input_mode, Scurrent_input_mode, 0, 0, 0, | ||
| 4482 | "Return information about the way Emacs currently reads keyboard input.\n\ | ||
| 4483 | The value is a list of the form (INTERRUPT FLOW META QUIT), where\n\ | ||
| 4484 | INTERRUPT is non-nil if Emacs is using interrupt-driven input; if\n\ | ||
| 4485 | nil, Emacs is using CBREAK mode.\n\ | ||
| 4486 | FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the\n\ | ||
| 4487 | terminal; this does not apply if Emacs uses interrupt-driven input.\n\ | ||
| 4488 | META is non-nil if Emacs is accepting 8-bit input; otherwise, Emacs\n\ | ||
| 4489 | clears the eighth bit of every input character.\n\ | ||
| 4490 | QUIT is the character Emacs currently uses to quit.\n\ | ||
| 4491 | The elements of this list correspond to the arguments of\n\ | ||
| 4492 | set-input-mode.") | ||
| 4493 | () | ||
| 4494 | { | ||
| 4495 | Lisp_Object val[4]; | ||
| 4496 | |||
| 4497 | val[0] = interrupt_input ? Qt : Qnil; | ||
| 4498 | val[1] = flow_control ? Qt : Qnil; | ||
| 4499 | val[2] = meta_key ? Qt : Qnil; | ||
| 4500 | XSETINT (val[3], quit_char); | ||
| 4501 | |||
| 4502 | return Flist (val, sizeof (val) / sizeof (val[0])); | ||
| 4503 | } | ||
| 4504 | |||
| 4460 | 4505 | ||
| 4461 | init_keyboard () | 4506 | init_keyboard () |
| 4462 | { | 4507 | { |
| @@ -4663,6 +4708,7 @@ syms_of_keyboard () | |||
| 4663 | defsubr (&Sdiscard_input); | 4708 | defsubr (&Sdiscard_input); |
| 4664 | defsubr (&Sopen_dribble_file); | 4709 | defsubr (&Sopen_dribble_file); |
| 4665 | defsubr (&Sset_input_mode); | 4710 | defsubr (&Sset_input_mode); |
| 4711 | defsubr (&Scurrent_input_mode); | ||
| 4666 | defsubr (&Sexecute_extended_command); | 4712 | defsubr (&Sexecute_extended_command); |
| 4667 | 4713 | ||
| 4668 | DEFVAR_LISP ("disabled-command-hook", &Vdisabled_command_hook, | 4714 | DEFVAR_LISP ("disabled-command-hook", &Vdisabled_command_hook, |
| @@ -4784,10 +4830,15 @@ Type this character while in a menu prompt to rotate around the lines of it."); | |||
| 4784 | 4830 | ||
| 4785 | DEFVAR_INT ("extra-keyboard-modifiers", &extra_keyboard_modifiers, | 4831 | DEFVAR_INT ("extra-keyboard-modifiers", &extra_keyboard_modifiers, |
| 4786 | "A mask of additional modifier keys to use with every keyboard character.\n\ | 4832 | "A mask of additional modifier keys to use with every keyboard character.\n\ |
| 4787 | These bits follow the convention for X windows,\n\ | 4833 | The modifiers of the character stored here apply to each keyboard\n\ |
| 4788 | but the control and meta bits work even when you are not using X:\n\ | 4834 | character we read. For example, after evaluating the expression\n\ |
| 4789 | 1 -- shift bit 2 -- lock bit\n\ | 4835 | (setq extra-keyboard-modifiers ?\C-x)\n\ |
| 4790 | 4 -- control bit 8 -- meta bit."); | 4836 | all input characters will have the control modifier applied to them.\n\ |
| 4837 | \n\ | ||
| 4838 | Note that the character ?\C-@, equivalent to the integer zero, does\n\ | ||
| 4839 | not count as a control character; rather, it counts as a character\n\ | ||
| 4840 | with no modifiers; thus, setting extra_keyboard_modifiers to zero\n\ | ||
| 4841 | cancels any modification."); | ||
| 4791 | extra_keyboard_modifiers = 0; | 4842 | extra_keyboard_modifiers = 0; |
| 4792 | 4843 | ||
| 4793 | DEFVAR_LISP ("deactivate-mark", &Vdeactivate_mark, | 4844 | DEFVAR_LISP ("deactivate-mark", &Vdeactivate_mark, |