aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJim Blandy1993-05-04 02:32:22 +0000
committerJim Blandy1993-05-04 02:32:22 +0000
commit806451194be01bc8712d9f43793b3f6ec8c5458e (patch)
treede0ada0d82e535bf71e05020d18b1a8a8e4e353b /src
parent9083124bb71c9db86e7ab2338b0aeb0dbbbb9a45 (diff)
downloademacs-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.c119
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
2473static Lisp_Object modifier_symbols; 2499static 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
4481DEFUN ("current-input-mode", Fcurrent_input_mode, Scurrent_input_mode, 0, 0, 0,
4482 "Return information about the way Emacs currently reads keyboard input.\n\
4483The 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\
4491The elements of this list correspond to the arguments of\n\
4492set-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
4461init_keyboard () 4506init_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\
4787These bits follow the convention for X windows,\n\ 4833The modifiers of the character stored here apply to each keyboard\n\
4788but the control and meta bits work even when you are not using X:\n\ 4834character 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."); 4836all input characters will have the control modifier applied to them.\n\
4837\n\
4838Note that the character ?\C-@, equivalent to the integer zero, does\n\
4839not count as a control character; rather, it counts as a character\n\
4840with no modifiers; thus, setting extra_keyboard_modifiers to zero\n\
4841cancels 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,