diff options
| author | Richard M. Stallman | 1993-07-23 23:23:57 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-07-23 23:23:57 +0000 |
| commit | a612e298a4e036b32b12092315d9028e2ea298a0 (patch) | |
| tree | b3e0234f36d6b475c5a5c6da2782d03498443792 /src | |
| parent | ab8fb1933c6e229e92ddbdaaaa1b55c862481485 (diff) | |
| download | emacs-a612e298a4e036b32b12092315d9028e2ea298a0.tar.gz emacs-a612e298a4e036b32b12092315d9028e2ea298a0.zip | |
(command_loop_1): Run post-command-hook first thing.
(Fread_key_sequence): Doc fix.
(read_key_sequence): Handle Vkey_translation_map.
(kbd_buffer_get_event): Discard an event whose kind is no_event.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 188 |
1 files changed, 148 insertions, 40 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index c0758af6ea2..359a480aac2 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -260,6 +260,9 @@ Lisp_Object Vkeyboard_translate_table; | |||
| 260 | /* Keymap mapping ASCII function key sequences onto their preferred forms. */ | 260 | /* Keymap mapping ASCII function key sequences onto their preferred forms. */ |
| 261 | extern Lisp_Object Vfunction_key_map; | 261 | extern Lisp_Object Vfunction_key_map; |
| 262 | 262 | ||
| 263 | /* Keymap mapping ASCII function key sequences onto their preferred forms. */ | ||
| 264 | Lisp_Object Vkey_translation_map; | ||
| 265 | |||
| 263 | /* Non-nil means deactivate the mark at end of this command. */ | 266 | /* Non-nil means deactivate the mark at end of this command. */ |
| 264 | Lisp_Object Vdeactivate_mark; | 267 | Lisp_Object Vdeactivate_mark; |
| 265 | 268 | ||
| @@ -443,6 +446,10 @@ void (*keyboard_init_hook) (); | |||
| 443 | static int read_avail_input (); | 446 | static int read_avail_input (); |
| 444 | static void get_input_pending (); | 447 | static void get_input_pending (); |
| 445 | static Lisp_Object read_char_menu_prompt (); | 448 | static Lisp_Object read_char_menu_prompt (); |
| 449 | static Lisp_Object make_lispy_event (); | ||
| 450 | static Lisp_Object make_lispy_movement (); | ||
| 451 | static Lisp_Object modify_event_symbol (); | ||
| 452 | static Lisp_Object make_lispy_switch_frame (); | ||
| 446 | 453 | ||
| 447 | /* > 0 if we are to echo keystrokes. */ | 454 | /* > 0 if we are to echo keystrokes. */ |
| 448 | static int echo_keystrokes; | 455 | static int echo_keystrokes; |
| @@ -888,6 +895,11 @@ command_loop_1 () | |||
| 888 | no_redisplay = 0; | 895 | no_redisplay = 0; |
| 889 | this_command_key_count = 0; | 896 | this_command_key_count = 0; |
| 890 | 897 | ||
| 898 | /* Make sure this hook runs after commands that get errors and | ||
| 899 | throw to top level. */ | ||
| 900 | if (!NILP (Vpost_command_hook)) | ||
| 901 | call1 (Vrun_hooks, Qpost_command_hook); | ||
| 902 | |||
| 891 | while (1) | 903 | while (1) |
| 892 | { | 904 | { |
| 893 | /* Install chars successfully executed in kbd macro. */ | 905 | /* Install chars successfully executed in kbd macro. */ |
| @@ -1660,26 +1672,6 @@ restore_getcjmp (temp) | |||
| 1660 | } | 1672 | } |
| 1661 | 1673 | ||
| 1662 | 1674 | ||
| 1663 | /* Low level keyboard/mouse input. | ||
| 1664 | kbd_buffer_store_event places events in kbd_buffer, and | ||
| 1665 | kbd_buffer_get_event retrieves them. | ||
| 1666 | mouse_moved indicates when the mouse has moved again, and | ||
| 1667 | *mouse_position_hook provides the mouse position. */ | ||
| 1668 | |||
| 1669 | /* Set this for debugging, to have a way to get out */ | ||
| 1670 | int stop_character; | ||
| 1671 | |||
| 1672 | extern int frame_garbaged; | ||
| 1673 | |||
| 1674 | /* Return true iff there are any events in the queue that read-char | ||
| 1675 | would return. If this returns false, a read-char would block. */ | ||
| 1676 | static int | ||
| 1677 | readable_events () | ||
| 1678 | { | ||
| 1679 | return ! EVENT_QUEUES_EMPTY; | ||
| 1680 | } | ||
| 1681 | |||
| 1682 | |||
| 1683 | /* Restore mouse tracking enablement. See Ftrack_mouse for the only use | 1675 | /* Restore mouse tracking enablement. See Ftrack_mouse for the only use |
| 1684 | of this function. */ | 1676 | of this function. */ |
| 1685 | static Lisp_Object | 1677 | static Lisp_Object |
| @@ -1722,6 +1714,23 @@ Normally, mouse motion is ignored.") | |||
| 1722 | val = Fprogn (args); | 1714 | val = Fprogn (args); |
| 1723 | return unbind_to (count, val); | 1715 | return unbind_to (count, val); |
| 1724 | } | 1716 | } |
| 1717 | |||
| 1718 | /* Low level keyboard/mouse input. | ||
| 1719 | kbd_buffer_store_event places events in kbd_buffer, and | ||
| 1720 | kbd_buffer_get_event retrieves them. | ||
| 1721 | mouse_moved indicates when the mouse has moved again, and | ||
| 1722 | *mouse_position_hook provides the mouse position. */ | ||
| 1723 | |||
| 1724 | /* Return true iff there are any events in the queue that read-char | ||
| 1725 | would return. If this returns false, a read-char would block. */ | ||
| 1726 | static int | ||
| 1727 | readable_events () | ||
| 1728 | { | ||
| 1729 | return ! EVENT_QUEUES_EMPTY; | ||
| 1730 | } | ||
| 1731 | |||
| 1732 | /* Set this for debugging, to have a way to get out */ | ||
| 1733 | int stop_character; | ||
| 1725 | 1734 | ||
| 1726 | /* Store an event obtained at interrupt level into kbd_buffer, fifo */ | 1735 | /* Store an event obtained at interrupt level into kbd_buffer, fifo */ |
| 1727 | 1736 | ||
| @@ -1798,11 +1807,12 @@ kbd_buffer_store_event (event) | |||
| 1798 | kbd_store_ptr++; | 1807 | kbd_store_ptr++; |
| 1799 | } | 1808 | } |
| 1800 | } | 1809 | } |
| 1801 | 1810 | ||
| 1802 | static Lisp_Object make_lispy_event (); | 1811 | /* Read one event from the event buffer, waiting if necessary. |
| 1803 | static Lisp_Object make_lispy_movement (); | 1812 | The value is a Lisp object representing the event. |
| 1804 | static Lisp_Object modify_event_symbol (); | 1813 | The value is nil for an event that should be ignored, |
| 1805 | static Lisp_Object make_lispy_switch_frame (); | 1814 | or that was handled here. |
| 1815 | We always read and discard one event. */ | ||
| 1806 | 1816 | ||
| 1807 | static Lisp_Object | 1817 | static Lisp_Object |
| 1808 | kbd_buffer_get_event () | 1818 | kbd_buffer_get_event () |
| @@ -1817,7 +1827,6 @@ kbd_buffer_get_event () | |||
| 1817 | return obj; | 1827 | return obj; |
| 1818 | } | 1828 | } |
| 1819 | 1829 | ||
| 1820 | retry: | ||
| 1821 | /* Wait until there is input available. */ | 1830 | /* Wait until there is input available. */ |
| 1822 | for (;;) | 1831 | for (;;) |
| 1823 | { | 1832 | { |
| @@ -1870,7 +1879,8 @@ kbd_buffer_get_event () | |||
| 1870 | obj = Qnil; | 1879 | obj = Qnil; |
| 1871 | 1880 | ||
| 1872 | /* These two kinds of events get special handling | 1881 | /* These two kinds of events get special handling |
| 1873 | and don't actually appear to the command loop. */ | 1882 | and don't actually appear to the command loop. |
| 1883 | We return nil for them. */ | ||
| 1874 | if (event->kind == selection_request_event) | 1884 | if (event->kind == selection_request_event) |
| 1875 | { | 1885 | { |
| 1876 | #ifdef HAVE_X11 | 1886 | #ifdef HAVE_X11 |
| @@ -1894,6 +1904,11 @@ kbd_buffer_get_event () | |||
| 1894 | abort (); | 1904 | abort (); |
| 1895 | #endif | 1905 | #endif |
| 1896 | } | 1906 | } |
| 1907 | /* Just discard these, by returning nil. | ||
| 1908 | (They shouldn't be found in the buffer, | ||
| 1909 | but on some machines it appears they do show up.) */ | ||
| 1910 | else if (event->kind == no_event) | ||
| 1911 | kbd_fetch_ptr = event + 1; | ||
| 1897 | 1912 | ||
| 1898 | /* If this event is on a different frame, return a switch-frame this | 1913 | /* If this event is on a different frame, return a switch-frame this |
| 1899 | time, and leave the event in the queue for next time. */ | 1914 | time, and leave the event in the queue for next time. */ |
| @@ -1932,6 +1947,7 @@ kbd_buffer_get_event () | |||
| 1932 | } | 1947 | } |
| 1933 | } | 1948 | } |
| 1934 | } | 1949 | } |
| 1950 | /* Try generating a mouse motion event. */ | ||
| 1935 | else if (do_mouse_tracking && mouse_moved) | 1951 | else if (do_mouse_tracking && mouse_moved) |
| 1936 | { | 1952 | { |
| 1937 | FRAME_PTR f = 0; | 1953 | FRAME_PTR f = 0; |
| @@ -1972,13 +1988,6 @@ kbd_buffer_get_event () | |||
| 1972 | something for us to read! */ | 1988 | something for us to read! */ |
| 1973 | abort (); | 1989 | abort (); |
| 1974 | 1990 | ||
| 1975 | #if 0 | ||
| 1976 | /* If something gave back nil as the Lispy event, | ||
| 1977 | it means the event was discarded, so try again. */ | ||
| 1978 | if (NILP (obj)) | ||
| 1979 | goto retry; | ||
| 1980 | #endif | ||
| 1981 | |||
| 1982 | input_pending = readable_events (); | 1991 | input_pending = readable_events (); |
| 1983 | 1992 | ||
| 1984 | #ifdef MULTI_FRAME | 1993 | #ifdef MULTI_FRAME |
| @@ -1987,8 +1996,9 @@ kbd_buffer_get_event () | |||
| 1987 | 1996 | ||
| 1988 | return (obj); | 1997 | return (obj); |
| 1989 | } | 1998 | } |
| 1990 | 1999 | ||
| 1991 | /* Process any events that are not user-visible. */ | 2000 | /* Process any events that are not user-visible, |
| 2001 | then return, without reading any user-visible events. */ | ||
| 1992 | 2002 | ||
| 1993 | void | 2003 | void |
| 1994 | swallow_events () | 2004 | swallow_events () |
| @@ -2034,7 +2044,7 @@ swallow_events () | |||
| 2034 | 2044 | ||
| 2035 | get_input_pending (&input_pending); | 2045 | get_input_pending (&input_pending); |
| 2036 | } | 2046 | } |
| 2037 | 2047 | ||
| 2038 | /* Caches for modify_event_symbol. */ | 2048 | /* Caches for modify_event_symbol. */ |
| 2039 | static Lisp_Object func_key_syms; | 2049 | static Lisp_Object func_key_syms; |
| 2040 | static Lisp_Object mouse_syms; | 2050 | static Lisp_Object mouse_syms; |
| @@ -3718,6 +3728,10 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3718 | int fkey_start = 0, fkey_end = 0; | 3728 | int fkey_start = 0, fkey_end = 0; |
| 3719 | Lisp_Object fkey_map; | 3729 | Lisp_Object fkey_map; |
| 3720 | 3730 | ||
| 3731 | /* Likewise, for key_translation_map. */ | ||
| 3732 | int keytran_start = 0, keytran_end = 0; | ||
| 3733 | Lisp_Object keytran_map; | ||
| 3734 | |||
| 3721 | /* If we receive a ``switch-frame'' event in the middle of a key sequence, | 3735 | /* If we receive a ``switch-frame'' event in the middle of a key sequence, |
| 3722 | we put it off for later. While we're reading, we keep the event here. */ | 3736 | we put it off for later. While we're reading, we keep the event here. */ |
| 3723 | Lisp_Object delayed_switch_frame; | 3737 | Lisp_Object delayed_switch_frame; |
| @@ -3730,11 +3744,16 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3730 | 3744 | ||
| 3731 | delayed_switch_frame = Qnil; | 3745 | delayed_switch_frame = Qnil; |
| 3732 | fkey_map = Vfunction_key_map; | 3746 | fkey_map = Vfunction_key_map; |
| 3747 | keytran_map = Vkey_translation_map; | ||
| 3733 | 3748 | ||
| 3734 | /* If there is no function key map, turn off function key scanning. */ | 3749 | /* If there is no function-key-map, turn off function key scanning. */ |
| 3735 | if (NILP (Fkeymapp (Vfunction_key_map))) | 3750 | if (NILP (Fkeymapp (Vfunction_key_map))) |
| 3736 | fkey_start = fkey_end = bufsize + 1; | 3751 | fkey_start = fkey_end = bufsize + 1; |
| 3737 | 3752 | ||
| 3753 | /* If there is no key-translation-map, turn off scanning. */ | ||
| 3754 | if (NILP (Fkeymapp (Vkey_translation_map))) | ||
| 3755 | keytran_start = keytran_end = bufsize + 1; | ||
| 3756 | |||
| 3738 | if (INTERACTIVE) | 3757 | if (INTERACTIVE) |
| 3739 | { | 3758 | { |
| 3740 | if (prompt) | 3759 | if (prompt) |
| @@ -3812,7 +3831,11 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3812 | || (first_binding >= nmaps | 3831 | || (first_binding >= nmaps |
| 3813 | && fkey_start < t | 3832 | && fkey_start < t |
| 3814 | /* mock input is never part of a function key's sequence. */ | 3833 | /* mock input is never part of a function key's sequence. */ |
| 3815 | && mock_input <= fkey_start)) | 3834 | && mock_input <= fkey_start) |
| 3835 | || (first_binding >= nmaps | ||
| 3836 | && keytran_start < t | ||
| 3837 | /* mock input is never part of a function key's sequence. */ | ||
| 3838 | && mock_input <= keytran_start)) | ||
| 3816 | { | 3839 | { |
| 3817 | Lisp_Object key; | 3840 | Lisp_Object key; |
| 3818 | int used_mouse_menu = 0; | 3841 | int used_mouse_menu = 0; |
| @@ -4208,6 +4231,78 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4208 | } | 4231 | } |
| 4209 | } | 4232 | } |
| 4210 | } | 4233 | } |
| 4234 | |||
| 4235 | /* Look for this sequence in key-translation-map. */ | ||
| 4236 | { | ||
| 4237 | Lisp_Object keytran_next; | ||
| 4238 | |||
| 4239 | /* Scan from keytran_end until we find a bound suffix. */ | ||
| 4240 | while (keytran_end < t) | ||
| 4241 | { | ||
| 4242 | Lisp_Object key; | ||
| 4243 | |||
| 4244 | key = keybuf[keytran_end++]; | ||
| 4245 | /* Look up meta-characters by prefixing them | ||
| 4246 | with meta_prefix_char. I hate this. */ | ||
| 4247 | if (XTYPE (key) == Lisp_Int && XINT (key) & meta_modifier) | ||
| 4248 | { | ||
| 4249 | keytran_next | ||
| 4250 | = get_keymap_1 | ||
| 4251 | (get_keyelt | ||
| 4252 | (access_keymap (keytran_map, meta_prefix_char, 1, 0)), | ||
| 4253 | 0, 1); | ||
| 4254 | XFASTINT (key) = XFASTINT (key) & ~meta_modifier; | ||
| 4255 | } | ||
| 4256 | else | ||
| 4257 | keytran_next = keytran_map; | ||
| 4258 | |||
| 4259 | keytran_next | ||
| 4260 | = get_keyelt (access_keymap (keytran_next, key, 1, 0)); | ||
| 4261 | |||
| 4262 | /* If keybuf[keytran_start..keytran_end] is bound in the | ||
| 4263 | function key map and it's a suffix of the current | ||
| 4264 | sequence (i.e. keytran_end == t), replace it with | ||
| 4265 | the binding and restart with keytran_start at the end. */ | ||
| 4266 | if ((VECTORP (keytran_next) || STRINGP (keytran_next)) | ||
| 4267 | && keytran_end == t) | ||
| 4268 | { | ||
| 4269 | int len = Flength (keytran_next); | ||
| 4270 | |||
| 4271 | t = keytran_start + len; | ||
| 4272 | if (t >= bufsize) | ||
| 4273 | error ("key sequence too long"); | ||
| 4274 | |||
| 4275 | if (VECTORP (keytran_next)) | ||
| 4276 | bcopy (XVECTOR (keytran_next)->contents, | ||
| 4277 | keybuf + keytran_start, | ||
| 4278 | (t - keytran_start) * sizeof (keybuf[0])); | ||
| 4279 | else if (STRINGP (keytran_next)) | ||
| 4280 | { | ||
| 4281 | int i; | ||
| 4282 | |||
| 4283 | for (i = 0; i < len; i++) | ||
| 4284 | XFASTINT (keybuf[keytran_start + i]) | ||
| 4285 | = XSTRING (keytran_next)->data[i]; | ||
| 4286 | } | ||
| 4287 | |||
| 4288 | mock_input = t; | ||
| 4289 | keytran_start = keytran_end = t; | ||
| 4290 | keytran_map = Vkey_translation_map; | ||
| 4291 | |||
| 4292 | goto replay_sequence; | ||
| 4293 | } | ||
| 4294 | |||
| 4295 | keytran_map = get_keymap_1 (keytran_next, 0, 1); | ||
| 4296 | |||
| 4297 | /* If we no longer have a bound suffix, try a new positions for | ||
| 4298 | keytran_start. */ | ||
| 4299 | if (NILP (keytran_map)) | ||
| 4300 | { | ||
| 4301 | keytran_end = ++keytran_start; | ||
| 4302 | keytran_map = Vkey_translation_map; | ||
| 4303 | } | ||
| 4304 | } | ||
| 4305 | } | ||
| 4211 | } | 4306 | } |
| 4212 | 4307 | ||
| 4213 | read_key_sequence_cmd = (first_binding < nmaps | 4308 | read_key_sequence_cmd = (first_binding < nmaps |
| @@ -4236,6 +4331,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4236 | return t; | 4331 | return t; |
| 4237 | } | 4332 | } |
| 4238 | 4333 | ||
| 4334 | #if 0 /* This doc string is too long for some compilers. | ||
| 4335 | This commented-out definition serves for DOC. */ | ||
| 4239 | DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 2, 0, | 4336 | DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 2, 0, |
| 4240 | "Read a sequence of keystrokes and return as a string or vector.\n\ | 4337 | "Read a sequence of keystrokes and return as a string or vector.\n\ |
| 4241 | The sequence is sufficient to specify a non-prefix command in the\n\ | 4338 | The sequence is sufficient to specify a non-prefix command in the\n\ |
| @@ -4270,6 +4367,11 @@ frame-switch event is put off until after the current key sequence.\n\ | |||
| 4270 | sequences, where they wouldn't conflict with ordinary bindings. See\n\ | 4367 | sequences, where they wouldn't conflict with ordinary bindings. See\n\ |
| 4271 | `function-key-map' for more details.") | 4368 | `function-key-map' for more details.") |
| 4272 | (prompt, continue_echo) | 4369 | (prompt, continue_echo) |
| 4370 | #endif | ||
| 4371 | |||
| 4372 | DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 2, 0, | ||
| 4373 | 0) | ||
| 4374 | (prompt, continue_echo) | ||
| 4273 | Lisp_Object prompt, continue_echo; | 4375 | Lisp_Object prompt, continue_echo; |
| 4274 | { | 4376 | { |
| 4275 | Lisp_Object keybuf[30]; | 4377 | Lisp_Object keybuf[30]; |
| @@ -5194,6 +5296,12 @@ Each character is looked up in this string and the contents used instead.\n\ | |||
| 5194 | If string is of length N, character codes N and up are untranslated."); | 5296 | If string is of length N, character codes N and up are untranslated."); |
| 5195 | Vkeyboard_translate_table = Qnil; | 5297 | Vkeyboard_translate_table = Qnil; |
| 5196 | 5298 | ||
| 5299 | DEFVAR_LISP ("key-translation-map", &Vkey_translation_map, | ||
| 5300 | "Keymap of key translations that can override keymaps.\n\ | ||
| 5301 | This keymap works like `function-key-map', but comes after that,\n\ | ||
| 5302 | and applies even for keys that have ordinary bindings."); | ||
| 5303 | Vkey_translation_map = Qnil; | ||
| 5304 | |||
| 5197 | DEFVAR_BOOL ("menu-prompting", &menu_prompting, | 5305 | DEFVAR_BOOL ("menu-prompting", &menu_prompting, |
| 5198 | "Non-nil means prompt with menus when appropriate.\n\ | 5306 | "Non-nil means prompt with menus when appropriate.\n\ |
| 5199 | This is done when reading from a keymap that has a prompt string,\n\ | 5307 | This is done when reading from a keymap that has a prompt string,\n\ |
| @@ -5243,7 +5351,7 @@ Buffer modification stores t in this variable."); | |||
| 5243 | 5351 | ||
| 5244 | DEFVAR_LISP ("menu-bar-final-items", &Vmenu_bar_final_items, | 5352 | DEFVAR_LISP ("menu-bar-final-items", &Vmenu_bar_final_items, |
| 5245 | "List of menu bar items to move to the end of the menu bar.\n\ | 5353 | "List of menu bar items to move to the end of the menu bar.\n\ |
| 5246 | The elements of the listare event types that may have menu bar bindings."); | 5354 | The elements of the list are event types that may have menu bar bindings."); |
| 5247 | Vmenu_bar_final_items = Qnil; | 5355 | Vmenu_bar_final_items = Qnil; |
| 5248 | } | 5356 | } |
| 5249 | 5357 | ||