diff options
| author | Richard M. Stallman | 1993-12-23 00:52:50 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-12-23 00:52:50 +0000 |
| commit | e9bf89a0badd390433c44c2219bdf9e33de7983d (patch) | |
| tree | 2aaaad1a6a062dc127c9fa3cff7c24459cec653e /src | |
| parent | 58f6c8ab02edf5ef1cfeed57eda7aa73cb6c02de (diff) | |
| download | emacs-e9bf89a0badd390433c44c2219bdf9e33de7983d.tar.gz emacs-e9bf89a0badd390433c44c2219bdf9e33de7983d.zip | |
(make_lispy_event): Offset the event code here.
Special handling for "dead accent" keysyms.
(lispy_accent_codes, lispy_accent_keys): New variables.
(quit_throw_to_read_char): Don't switch frames if
internal_last_event_frame is not a frame.
(kbd_buffer_store_event, make_lispy_event)
(stuff_buffered_input): `code' of an event is now an int.
(make_lispy_movement): If we have a frame but pos is not
in a window, return an event with the frame.
(read_key_sequence): Don't return if in middle
of possible function-key-map sequence, if the bindings were all
found by case conversion.
(set_waiting_for_input): Code testing echo_flag deleted.
(echo_flag, echo_now): Vars deleted.
(read_key_sequence): Bind case_converted at top level.
Clear it at replay_sequence.
(follow_key): Never clear *CASE_CONVERTED.
(syms_of_keyboard): Define Lisp var track-mouse.
(follow_key): New arg case_converted.
(read_key_sequence): Pass the new arg.
If key has a binding via case-conversion, that does not prevent
use of function_key_map.
(read_char): Call prepare_menu_bars.
(tracking_off): Call prepare_menu_bars.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 130 |
1 files changed, 108 insertions, 22 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index f28c4dccfca..d18c984d12d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1422,6 +1422,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1422 | goto reread_first; | 1422 | goto reread_first; |
| 1423 | } | 1423 | } |
| 1424 | 1424 | ||
| 1425 | if (commandflag >= 0 && !input_pending && !detect_input_pending ()) | ||
| 1426 | prepare_menu_bars (); | ||
| 1427 | |||
| 1425 | /* Save outer setjmp data, in case called recursively. */ | 1428 | /* Save outer setjmp data, in case called recursively. */ |
| 1426 | save_getcjmp (save_jump); | 1429 | save_getcjmp (save_jump); |
| 1427 | 1430 | ||
| @@ -1534,6 +1537,8 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1534 | && consing_since_gc > gc_cons_threshold / 2) | 1537 | && consing_since_gc > gc_cons_threshold / 2) |
| 1535 | { | 1538 | { |
| 1536 | Fgarbage_collect (); | 1539 | Fgarbage_collect (); |
| 1540 | /* prepare_menu_bars isn't safe here, but it should | ||
| 1541 | also be unnecessary. */ | ||
| 1537 | redisplay (); | 1542 | redisplay (); |
| 1538 | } | 1543 | } |
| 1539 | } | 1544 | } |
| @@ -1658,6 +1663,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1658 | c = read_char (0, 0, 0, Qnil, 0); | 1663 | c = read_char (0, 0, 0, Qnil, 0); |
| 1659 | /* Remove the help from the frame */ | 1664 | /* Remove the help from the frame */ |
| 1660 | unbind_to (count, Qnil); | 1665 | unbind_to (count, Qnil); |
| 1666 | prepare_menu_bars (); | ||
| 1661 | redisplay (); | 1667 | redisplay (); |
| 1662 | if (EQ (c, make_number (040))) | 1668 | if (EQ (c, make_number (040))) |
| 1663 | { | 1669 | { |
| @@ -1712,6 +1718,7 @@ tracking_off (old_value) | |||
| 1712 | redisplay. */ | 1718 | redisplay. */ |
| 1713 | if (!readable_events ()) | 1719 | if (!readable_events ()) |
| 1714 | { | 1720 | { |
| 1721 | prepare_menu_bars (); | ||
| 1715 | redisplay_preserve_echo_area (); | 1722 | redisplay_preserve_echo_area (); |
| 1716 | get_input_pending (&input_pending); | 1723 | get_input_pending (&input_pending); |
| 1717 | } | 1724 | } |
| @@ -1766,7 +1773,7 @@ kbd_buffer_store_event (event) | |||
| 1766 | 1773 | ||
| 1767 | if (event->kind == ascii_keystroke) | 1774 | if (event->kind == ascii_keystroke) |
| 1768 | { | 1775 | { |
| 1769 | register int c = XFASTINT (event->code) & 0377; | 1776 | register int c = event->code & 0377; |
| 1770 | 1777 | ||
| 1771 | if (event->modifiers & ctrl_modifier) | 1778 | if (event->modifiers & ctrl_modifier) |
| 1772 | c = make_ctrl_char (c); | 1779 | c = make_ctrl_char (c); |
| @@ -2106,9 +2113,50 @@ swallow_events () | |||
| 2106 | } | 2113 | } |
| 2107 | 2114 | ||
| 2108 | /* Caches for modify_event_symbol. */ | 2115 | /* Caches for modify_event_symbol. */ |
| 2116 | static Lisp_Object accent_key_syms; | ||
| 2109 | static Lisp_Object func_key_syms; | 2117 | static Lisp_Object func_key_syms; |
| 2110 | static Lisp_Object mouse_syms; | 2118 | static Lisp_Object mouse_syms; |
| 2111 | 2119 | ||
| 2120 | /* This is a list of keysym codes for special "accent" characters. | ||
| 2121 | It parallels lispy_accent_keys. */ | ||
| 2122 | |||
| 2123 | static int lispy_accent_codes[] = | ||
| 2124 | { | ||
| 2125 | XK_dead_circumflex, | ||
| 2126 | XK_dead_grave, | ||
| 2127 | XK_dead_tilde, | ||
| 2128 | XK_dead_diaeresis, | ||
| 2129 | XK_dead_macron, | ||
| 2130 | XK_dead_degree, | ||
| 2131 | XK_dead_acute, | ||
| 2132 | XK_dead_cedilla, | ||
| 2133 | XK_dead_breve, | ||
| 2134 | XK_dead_ogonek, | ||
| 2135 | XK_dead_caron, | ||
| 2136 | XK_dead_doubleacute, | ||
| 2137 | XK_dead_abovedot, | ||
| 2138 | }; | ||
| 2139 | |||
| 2140 | /* This is a list of Lisp names for special "accent" characters. | ||
| 2141 | It parallels lispy_accent_codes. */ | ||
| 2142 | |||
| 2143 | static char *lispy_accent_keys[] = | ||
| 2144 | { | ||
| 2145 | "dead-circumflex", | ||
| 2146 | "dead-grave", | ||
| 2147 | "dead-tilde", | ||
| 2148 | "dead-diaeresis", | ||
| 2149 | "dead-macron", | ||
| 2150 | "dead-degree", | ||
| 2151 | "dead-acute", | ||
| 2152 | "dead-cedilla", | ||
| 2153 | "dead-breve", | ||
| 2154 | "dead-ogonek", | ||
| 2155 | "dead-caron", | ||
| 2156 | "dead-doubleacute", | ||
| 2157 | "dead-abovedot", | ||
| 2158 | }; | ||
| 2159 | |||
| 2112 | /* You'll notice that this table is arranged to be conveniently | 2160 | /* You'll notice that this table is arranged to be conveniently |
| 2113 | indexed by X Windows keysym values. */ | 2161 | indexed by X Windows keysym values. */ |
| 2114 | static char *lispy_function_keys[] = | 2162 | static char *lispy_function_keys[] = |
| @@ -2271,7 +2319,7 @@ make_lispy_event (event) | |||
| 2271 | /* A simple keystroke. */ | 2319 | /* A simple keystroke. */ |
| 2272 | case ascii_keystroke: | 2320 | case ascii_keystroke: |
| 2273 | { | 2321 | { |
| 2274 | int c = XFASTINT (event->code) & 0377; | 2322 | int c = event->code & 0377; |
| 2275 | /* Turn ASCII characters into control characters | 2323 | /* Turn ASCII characters into control characters |
| 2276 | when proper. */ | 2324 | when proper. */ |
| 2277 | if (event->modifiers & ctrl_modifier) | 2325 | if (event->modifiers & ctrl_modifier) |
| @@ -2291,7 +2339,18 @@ make_lispy_event (event) | |||
| 2291 | tacked onto it. */ | 2339 | tacked onto it. */ |
| 2292 | case non_ascii_keystroke: | 2340 | case non_ascii_keystroke: |
| 2293 | button_down_time = 0; | 2341 | button_down_time = 0; |
| 2294 | return modify_event_symbol (XFASTINT (event->code), event->modifiers, | 2342 | |
| 2343 | for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++) | ||
| 2344 | if (event->code == lispy_accent_codes[i]) | ||
| 2345 | return modify_event_symbol (i, | ||
| 2346 | event->modifiers, | ||
| 2347 | Qfunction_key, | ||
| 2348 | lispy_accent_keys, &accent_key_syms, | ||
| 2349 | (sizeof (lispy_accent_keys) | ||
| 2350 | / sizeof (lispy_accent_keys[0]))); | ||
| 2351 | |||
| 2352 | return modify_event_symbol (event->code - 0xff00, | ||
| 2353 | event->modifiers, | ||
| 2295 | Qfunction_key, | 2354 | Qfunction_key, |
| 2296 | lispy_function_keys, &func_key_syms, | 2355 | lispy_function_keys, &func_key_syms, |
| 2297 | (sizeof (lispy_function_keys) | 2356 | (sizeof (lispy_function_keys) |
| @@ -2303,7 +2362,7 @@ make_lispy_event (event) | |||
| 2303 | case mouse_click: | 2362 | case mouse_click: |
| 2304 | case scroll_bar_click: | 2363 | case scroll_bar_click: |
| 2305 | { | 2364 | { |
| 2306 | int button = XFASTINT (event->code); | 2365 | int button = event->code; |
| 2307 | int is_double; | 2366 | int is_double; |
| 2308 | Lisp_Object position; | 2367 | Lisp_Object position; |
| 2309 | Lisp_Object *start_pos_ptr; | 2368 | Lisp_Object *start_pos_ptr; |
| @@ -2552,6 +2611,11 @@ make_lispy_movement (frame, bar_window, part, x, y, time) | |||
| 2552 | buffer_posn_from_coords (XWINDOW (window), | 2611 | buffer_posn_from_coords (XWINDOW (window), |
| 2553 | XINT (x), XINT (y))); | 2612 | XINT (x), XINT (y))); |
| 2554 | } | 2613 | } |
| 2614 | else if (frame != 0) | ||
| 2615 | { | ||
| 2616 | XSET (window, Lisp_Frame, frame); | ||
| 2617 | posn = Qnil; | ||
| 2618 | } | ||
| 2555 | else | 2619 | else |
| 2556 | { | 2620 | { |
| 2557 | window = Qnil; | 2621 | window = Qnil; |
| @@ -3400,9 +3464,6 @@ menu_bar_item (key, item_string, def, result) | |||
| 3400 | return result; | 3464 | return result; |
| 3401 | } | 3465 | } |
| 3402 | 3466 | ||
| 3403 | static int echo_flag; | ||
| 3404 | static int echo_now; | ||
| 3405 | |||
| 3406 | /* Read a character using menus based on maps in the array MAPS. | 3467 | /* Read a character using menus based on maps in the array MAPS. |
| 3407 | NMAPS is the length of MAPS. Return nil if there are no menus in the maps. | 3468 | NMAPS is the length of MAPS. Return nil if there are no menus in the maps. |
| 3408 | Return t if we displayed a menu but the user rejected it. | 3469 | Return t if we displayed a menu but the user rejected it. |
| @@ -3621,6 +3682,8 @@ read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) | |||
| 3621 | When KEY is not defined in any of the keymaps, if it is an upper | 3682 | When KEY is not defined in any of the keymaps, if it is an upper |
| 3622 | case letter and there are bindings for the corresponding lower-case | 3683 | case letter and there are bindings for the corresponding lower-case |
| 3623 | letter, return the bindings for the lower-case letter. | 3684 | letter, return the bindings for the lower-case letter. |
| 3685 | We store 1 in *CASE_CONVERTED in this case. | ||
| 3686 | Otherwise, we don't change *CASE_CONVERTED. | ||
| 3624 | 3687 | ||
| 3625 | If KEY has no bindings in any of the CURRENT maps, NEXT is left | 3688 | If KEY has no bindings in any of the CURRENT maps, NEXT is left |
| 3626 | unmodified. | 3689 | unmodified. |
| @@ -3628,10 +3691,11 @@ read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) | |||
| 3628 | NEXT may == CURRENT. */ | 3691 | NEXT may == CURRENT. */ |
| 3629 | 3692 | ||
| 3630 | static int | 3693 | static int |
| 3631 | follow_key (key, nmaps, current, defs, next) | 3694 | follow_key (key, nmaps, current, defs, next, case_converted) |
| 3632 | Lisp_Object key; | 3695 | Lisp_Object key; |
| 3633 | Lisp_Object *current, *defs, *next; | 3696 | Lisp_Object *current, *defs, *next; |
| 3634 | int nmaps; | 3697 | int nmaps; |
| 3698 | int *case_converted; | ||
| 3635 | { | 3699 | { |
| 3636 | int i, first_binding; | 3700 | int i, first_binding; |
| 3637 | 3701 | ||
| @@ -3698,6 +3762,8 @@ follow_key (key, nmaps, current, defs, next) | |||
| 3698 | else | 3762 | else |
| 3699 | defs[i] = Qnil; | 3763 | defs[i] = Qnil; |
| 3700 | } | 3764 | } |
| 3765 | if (first_binding != nmaps) | ||
| 3766 | *case_converted = 1; | ||
| 3701 | } | 3767 | } |
| 3702 | 3768 | ||
| 3703 | /* Given the set of bindings we've found, produce the next set of maps. */ | 3769 | /* Given the set of bindings we've found, produce the next set of maps. */ |
| @@ -3817,6 +3883,14 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3817 | 3883 | ||
| 3818 | struct buffer *starting_buffer; | 3884 | struct buffer *starting_buffer; |
| 3819 | 3885 | ||
| 3886 | /* Nonzero if we found the binding for one of the chars | ||
| 3887 | in this key sequence by downcasing it. */ | ||
| 3888 | int case_converted = 0; | ||
| 3889 | |||
| 3890 | /* Nonzero if we seem to have got the beginning of a binding | ||
| 3891 | in function_key_map. */ | ||
| 3892 | int function_key_possible = 0; | ||
| 3893 | |||
| 3820 | int junk; | 3894 | int junk; |
| 3821 | 3895 | ||
| 3822 | last_nonmenu_event = Qnil; | 3896 | last_nonmenu_event = Qnil; |
| @@ -3866,6 +3940,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3866 | replay_sequence: | 3940 | replay_sequence: |
| 3867 | 3941 | ||
| 3868 | starting_buffer = current_buffer; | 3942 | starting_buffer = current_buffer; |
| 3943 | case_converted = 0; | ||
| 3944 | function_key_possible = 0; | ||
| 3869 | 3945 | ||
| 3870 | /* Build our list of keymaps. | 3946 | /* Build our list of keymaps. |
| 3871 | If we recognize a function key and replace its escape sequence in | 3947 | If we recognize a function key and replace its escape sequence in |
| @@ -3916,7 +3992,13 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 3916 | || (first_binding >= nmaps | 3992 | || (first_binding >= nmaps |
| 3917 | && keytran_start < t | 3993 | && keytran_start < t |
| 3918 | /* mock input is never part of a function key's sequence. */ | 3994 | /* mock input is never part of a function key's sequence. */ |
| 3919 | && mock_input <= keytran_start)) | 3995 | && mock_input <= keytran_start) |
| 3996 | /* Don't return in the middle of a possible function key sequence, | ||
| 3997 | if the only bindings we found were via case conversion. | ||
| 3998 | Thus, if ESC O a has a function-key-map translation | ||
| 3999 | and ESC o has a binding, don't return after ESC O, | ||
| 4000 | so that we can translate ESC O plus the next character. */ | ||
| 4001 | || (function_key_possible && case_converted)) | ||
| 3920 | { | 4002 | { |
| 3921 | Lisp_Object key; | 4003 | Lisp_Object key; |
| 3922 | int used_mouse_menu = 0; | 4004 | int used_mouse_menu = 0; |
| @@ -4131,7 +4213,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4131 | nmaps - first_binding, | 4213 | nmaps - first_binding, |
| 4132 | submaps + first_binding, | 4214 | submaps + first_binding, |
| 4133 | defs + first_binding, | 4215 | defs + first_binding, |
| 4134 | submaps + first_binding) | 4216 | submaps + first_binding, |
| 4217 | &case_converted) | ||
| 4135 | + first_binding); | 4218 | + first_binding); |
| 4136 | 4219 | ||
| 4137 | /* If KEY wasn't bound, we'll try some fallbacks. */ | 4220 | /* If KEY wasn't bound, we'll try some fallbacks. */ |
| @@ -4230,7 +4313,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4230 | nmaps - local_first_binding, | 4313 | nmaps - local_first_binding, |
| 4231 | submaps + local_first_binding, | 4314 | submaps + local_first_binding, |
| 4232 | defs + local_first_binding, | 4315 | defs + local_first_binding, |
| 4233 | submaps + local_first_binding) | 4316 | submaps + local_first_binding, |
| 4317 | &case_converted) | ||
| 4234 | + local_first_binding); | 4318 | + local_first_binding); |
| 4235 | 4319 | ||
| 4236 | /* If that click is bound, go for it. */ | 4320 | /* If that click is bound, go for it. */ |
| @@ -4257,12 +4341,14 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4257 | off the end of it. We only want to scan real keyboard input | 4341 | off the end of it. We only want to scan real keyboard input |
| 4258 | for function key sequences, so if mock_input says that we're | 4342 | for function key sequences, so if mock_input says that we're |
| 4259 | re-reading old events, don't examine it. */ | 4343 | re-reading old events, don't examine it. */ |
| 4260 | if (first_binding >= nmaps | 4344 | if ((first_binding >= nmaps || case_converted) |
| 4261 | && t >= mock_input) | 4345 | && t >= mock_input) |
| 4262 | { | 4346 | { |
| 4263 | Lisp_Object fkey_next; | 4347 | Lisp_Object fkey_next; |
| 4264 | 4348 | ||
| 4265 | /* Scan from fkey_end until we find a bound suffix. */ | 4349 | /* Continue scan from fkey_end until we find a bound suffix. |
| 4350 | If we fail, increment fkey_start | ||
| 4351 | and start fkey_end from there. */ | ||
| 4266 | while (fkey_end < t) | 4352 | while (fkey_end < t) |
| 4267 | { | 4353 | { |
| 4268 | Lisp_Object key; | 4354 | Lisp_Object key; |
| @@ -4306,6 +4392,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4306 | error ("Function in function-key-map returns invalid key sequence"); | 4392 | error ("Function in function-key-map returns invalid key sequence"); |
| 4307 | } | 4393 | } |
| 4308 | 4394 | ||
| 4395 | function_key_possible = ! NILP (fkey_next); | ||
| 4396 | |||
| 4309 | /* If keybuf[fkey_start..fkey_end] is bound in the | 4397 | /* If keybuf[fkey_start..fkey_end] is bound in the |
| 4310 | function key map and it's a suffix of the current | 4398 | function key map and it's a suffix of the current |
| 4311 | sequence (i.e. fkey_end == t), replace it with | 4399 | sequence (i.e. fkey_end == t), replace it with |
| @@ -4347,6 +4435,7 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 4347 | { | 4435 | { |
| 4348 | fkey_end = ++fkey_start; | 4436 | fkey_end = ++fkey_start; |
| 4349 | fkey_map = Vfunction_key_map; | 4437 | fkey_map = Vfunction_key_map; |
| 4438 | function_key_possible = 0; | ||
| 4350 | } | 4439 | } |
| 4351 | } | 4440 | } |
| 4352 | } | 4441 | } |
| @@ -4874,7 +4963,7 @@ stuff_buffered_input (stuffstring) | |||
| 4874 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) | 4963 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) |
| 4875 | kbd_fetch_ptr = kbd_buffer; | 4964 | kbd_fetch_ptr = kbd_buffer; |
| 4876 | if (kbd_fetch_ptr->kind == ascii_keystroke) | 4965 | if (kbd_fetch_ptr->kind == ascii_keystroke) |
| 4877 | stuff_char (XINT (kbd_fetch_ptr->code)); | 4966 | stuff_char (kbd_fetch_ptr->code); |
| 4878 | kbd_fetch_ptr->kind = no_event; | 4967 | kbd_fetch_ptr->kind = no_event; |
| 4879 | (XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_fetch_ptr | 4968 | (XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_fetch_ptr |
| 4880 | - kbd_buffer] | 4969 | - kbd_buffer] |
| @@ -4898,13 +4987,6 @@ set_waiting_for_input (time_to_clear) | |||
| 4898 | make it run again now, to avoid timing error. */ | 4987 | make it run again now, to avoid timing error. */ |
| 4899 | if (!NILP (Vquit_flag)) | 4988 | if (!NILP (Vquit_flag)) |
| 4900 | quit_throw_to_read_char (); | 4989 | quit_throw_to_read_char (); |
| 4901 | |||
| 4902 | /* If alarm has gone off already, echo now. */ | ||
| 4903 | if (echo_flag) | ||
| 4904 | { | ||
| 4905 | echo (); | ||
| 4906 | echo_flag = 0; | ||
| 4907 | } | ||
| 4908 | } | 4990 | } |
| 4909 | 4991 | ||
| 4910 | clear_waiting_for_input () | 4992 | clear_waiting_for_input () |
| @@ -5033,7 +5115,8 @@ quit_throw_to_read_char () | |||
| 5033 | abort (); | 5115 | abort (); |
| 5034 | #endif | 5116 | #endif |
| 5035 | #ifdef MULTI_FRAME | 5117 | #ifdef MULTI_FRAME |
| 5036 | if (XFRAME (internal_last_event_frame) != selected_frame) | 5118 | if (XTYPE (internal_last_event_frame) == Lisp_Frame |
| 5119 | && XFRAME (internal_last_event_frame) != selected_frame) | ||
| 5037 | Fhandle_switch_frame (make_lispy_switch_frame (internal_last_event_frame)); | 5120 | Fhandle_switch_frame (make_lispy_switch_frame (internal_last_event_frame)); |
| 5038 | #endif | 5121 | #endif |
| 5039 | 5122 | ||
| @@ -5512,6 +5595,9 @@ Buffer modification stores t in this variable."); | |||
| 5512 | "List of menu bar items to move to the end of the menu bar.\n\ | 5595 | "List of menu bar items to move to the end of the menu bar.\n\ |
| 5513 | The elements of the list are event types that may have menu bar bindings."); | 5596 | The elements of the list are event types that may have menu bar bindings."); |
| 5514 | Vmenu_bar_final_items = Qnil; | 5597 | Vmenu_bar_final_items = Qnil; |
| 5598 | |||
| 5599 | DEFVAR_BOOL ("track-mouse", &do_mouse_tracking, | ||
| 5600 | "*Non-nil means generate motion events for mouse motion."); | ||
| 5515 | } | 5601 | } |
| 5516 | 5602 | ||
| 5517 | keys_of_keyboard () | 5603 | keys_of_keyboard () |