diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 76 | ||||
| -rw-r--r-- | src/keyboard.h | 1 | ||||
| -rw-r--r-- | src/menu.c | 96 | ||||
| -rw-r--r-- | src/menu.h | 1 |
4 files changed, 85 insertions, 89 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index b18dc1abbe7..375aa4f6067 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -43,6 +43,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 43 | #include "systime.h" | 43 | #include "systime.h" |
| 44 | #include "atimer.h" | 44 | #include "atimer.h" |
| 45 | #include "process.h" | 45 | #include "process.h" |
| 46 | #include "menu.h" | ||
| 46 | #include <errno.h> | 47 | #include <errno.h> |
| 47 | 48 | ||
| 48 | #ifdef HAVE_PTHREAD | 49 | #ifdef HAVE_PTHREAD |
| @@ -121,17 +122,12 @@ ptrdiff_t this_command_key_count; | |||
| 121 | 122 | ||
| 122 | /* This vector is used as a buffer to record the events that were actually read | 123 | /* This vector is used as a buffer to record the events that were actually read |
| 123 | by read_key_sequence. */ | 124 | by read_key_sequence. */ |
| 124 | static Lisp_Object raw_keybuf_buffer; | 125 | static Lisp_Object raw_keybuf; |
| 125 | static int raw_keybuf_count_buffer; | 126 | static int raw_keybuf_count; |
| 126 | static Lisp_Object *raw_keybuf = &raw_keybuf_buffer; | 127 | |
| 127 | static int *raw_keybuf_count = &raw_keybuf_count_buffer; | 128 | #define GROW_RAW_KEYBUF \ |
| 128 | 129 | if (raw_keybuf_count == ASIZE (raw_keybuf)) \ | |
| 129 | #define GROW_RAW_KEYBUF(inc) \ | 130 | raw_keybuf = larger_vector (raw_keybuf, 1, -1) |
| 130 | if (*raw_keybuf_count > ASIZE (*raw_keybuf) - (inc)) \ | ||
| 131 | *raw_keybuf = \ | ||
| 132 | larger_vector (*raw_keybuf, \ | ||
| 133 | (inc) + *raw_keybuf_count - ASIZE (*raw_keybuf), \ | ||
| 134 | -1) | ||
| 135 | 131 | ||
| 136 | /* Number of elements of this_command_keys | 132 | /* Number of elements of this_command_keys |
| 137 | that precede this key sequence. */ | 133 | that precede this key sequence. */ |
| @@ -1370,8 +1366,7 @@ command_loop_1 (void) | |||
| 1370 | Vthis_command_keys_shift_translated = Qnil; | 1366 | Vthis_command_keys_shift_translated = Qnil; |
| 1371 | 1367 | ||
| 1372 | /* Read next key sequence; i gets its length. */ | 1368 | /* Read next key sequence; i gets its length. */ |
| 1373 | raw_keybuf_count = &raw_keybuf_count_buffer; /* For safety */ | 1369 | raw_keybuf_count = 0; |
| 1374 | raw_keybuf = &raw_keybuf_buffer; /* Ditto */ | ||
| 1375 | i = read_key_sequence (keybuf, ARRAYELTS (keybuf), | 1370 | i = read_key_sequence (keybuf, ARRAYELTS (keybuf), |
| 1376 | Qnil, 0, 1, 1, 0); | 1371 | Qnil, 0, 1, 1, 0); |
| 1377 | 1372 | ||
| @@ -8460,7 +8455,7 @@ read_char_x_menu_prompt (Lisp_Object map, | |||
| 8460 | /* Display the menu and get the selection. */ | 8455 | /* Display the menu and get the selection. */ |
| 8461 | Lisp_Object value; | 8456 | Lisp_Object value; |
| 8462 | 8457 | ||
| 8463 | value = Fx_popup_menu (prev_event, get_keymap (map, 0, 1)); | 8458 | value = x_popup_menu_1 (prev_event, get_keymap (map, 0, 1)); |
| 8464 | if (CONSP (value)) | 8459 | if (CONSP (value)) |
| 8465 | { | 8460 | { |
| 8466 | Lisp_Object tem; | 8461 | Lisp_Object tem; |
| @@ -8870,6 +8865,11 @@ test_undefined (Lisp_Object binding) | |||
| 8870 | && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); | 8865 | && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); |
| 8871 | } | 8866 | } |
| 8872 | 8867 | ||
| 8868 | void init_raw_keybuf_count (void) | ||
| 8869 | { | ||
| 8870 | raw_keybuf_count = 0; | ||
| 8871 | } | ||
| 8872 | |||
| 8873 | /* Read a sequence of keys that ends with a non prefix character, | 8873 | /* Read a sequence of keys that ends with a non prefix character, |
| 8874 | storing it in KEYBUF, a buffer of size BUFSIZE. | 8874 | storing it in KEYBUF, a buffer of size BUFSIZE. |
| 8875 | Prompt with PROMPT. | 8875 | Prompt with PROMPT. |
| @@ -8920,11 +8920,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8920 | /* How many keys there are in the current key sequence. */ | 8920 | /* How many keys there are in the current key sequence. */ |
| 8921 | int t; | 8921 | int t; |
| 8922 | 8922 | ||
| 8923 | int *outer_raw_keybuf_count; | ||
| 8924 | Lisp_Object *outer_raw_keybuf; | ||
| 8925 | int inner_raw_keybuf_count_buffer; | ||
| 8926 | Lisp_Object inner_raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil); | ||
| 8927 | |||
| 8928 | /* The length of the echo buffer when we started reading, and | 8923 | /* The length of the echo buffer when we started reading, and |
| 8929 | the length of this_command_keys when we started reading. */ | 8924 | the length of this_command_keys when we started reading. */ |
| 8930 | ptrdiff_t echo_start UNINIT; | 8925 | ptrdiff_t echo_start UNINIT; |
| @@ -8985,7 +8980,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8985 | /* List of events for which a fake prefix key has been generated. */ | 8980 | /* List of events for which a fake prefix key has been generated. */ |
| 8986 | Lisp_Object fake_prefixed_keys = Qnil; | 8981 | Lisp_Object fake_prefixed_keys = Qnil; |
| 8987 | 8982 | ||
| 8988 | *raw_keybuf_count = 0; | 8983 | /* raw_keybuf_count is now initialized in (most of) the callers of |
| 8984 | read_key_sequence. This is so that in a recursive call (for | ||
| 8985 | mouse menus) a spurious initialization doesn't erase the contents | ||
| 8986 | of raw_keybuf created by the outer call. */ | ||
| 8987 | /* raw_keybuf_count = 0; */ | ||
| 8989 | 8988 | ||
| 8990 | last_nonmenu_event = Qnil; | 8989 | last_nonmenu_event = Qnil; |
| 8991 | 8990 | ||
| @@ -9157,23 +9156,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9157 | { | 9156 | { |
| 9158 | KBOARD *interrupted_kboard = current_kboard; | 9157 | KBOARD *interrupted_kboard = current_kboard; |
| 9159 | struct frame *interrupted_frame = SELECTED_FRAME (); | 9158 | struct frame *interrupted_frame = SELECTED_FRAME (); |
| 9160 | int i; | ||
| 9161 | outer_raw_keybuf_count = raw_keybuf_count; | ||
| 9162 | outer_raw_keybuf = raw_keybuf; | ||
| 9163 | inner_raw_keybuf_count_buffer = 0; | ||
| 9164 | raw_keybuf_count = &inner_raw_keybuf_count_buffer; | ||
| 9165 | raw_keybuf = &inner_raw_keybuf_buffer; | ||
| 9166 | /* Calling read_char with COMMANDFLAG = -2 avoids | 9159 | /* Calling read_char with COMMANDFLAG = -2 avoids |
| 9167 | redisplay in read_char and its subroutines. */ | 9160 | redisplay in read_char and its subroutines. */ |
| 9168 | key = read_char (prevent_redisplay ? -2 : NILP (prompt), | 9161 | key = read_char (prevent_redisplay ? -2 : NILP (prompt), |
| 9169 | current_binding, last_nonmenu_event, | 9162 | current_binding, last_nonmenu_event, |
| 9170 | &used_mouse_menu, NULL); | 9163 | &used_mouse_menu, NULL); |
| 9171 | raw_keybuf_count = outer_raw_keybuf_count; | ||
| 9172 | raw_keybuf = outer_raw_keybuf; | ||
| 9173 | GROW_RAW_KEYBUF (inner_raw_keybuf_count_buffer); | ||
| 9174 | for (i = 0; i < inner_raw_keybuf_count_buffer; i++) | ||
| 9175 | ASET (*raw_keybuf, (*raw_keybuf_count)++, | ||
| 9176 | AREF (inner_raw_keybuf_buffer, i)); | ||
| 9177 | if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ | 9164 | if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ |
| 9178 | /* When switching to a new tty (with a new keyboard), | 9165 | /* When switching to a new tty (with a new keyboard), |
| 9179 | read_char returns the new buffer, rather than -2 | 9166 | read_char returns the new buffer, rather than -2 |
| @@ -9281,9 +9268,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9281 | && XINT (key) == quit_char | 9268 | && XINT (key) == quit_char |
| 9282 | && current_buffer != starting_buffer) | 9269 | && current_buffer != starting_buffer) |
| 9283 | { | 9270 | { |
| 9284 | GROW_RAW_KEYBUF (1); | 9271 | GROW_RAW_KEYBUF; |
| 9285 | ASET (*raw_keybuf, *raw_keybuf_count, key); | 9272 | ASET (raw_keybuf, raw_keybuf_count, key); |
| 9286 | (*raw_keybuf_count)++; | 9273 | raw_keybuf_count++; |
| 9287 | keybuf[t++] = key; | 9274 | keybuf[t++] = key; |
| 9288 | mock_input = t; | 9275 | mock_input = t; |
| 9289 | Vquit_flag = Qnil; | 9276 | Vquit_flag = Qnil; |
| @@ -9322,9 +9309,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9322 | current_binding = active_maps (first_event); | 9309 | current_binding = active_maps (first_event); |
| 9323 | } | 9310 | } |
| 9324 | 9311 | ||
| 9325 | GROW_RAW_KEYBUF (1); | 9312 | GROW_RAW_KEYBUF; |
| 9326 | ASET (*raw_keybuf, *raw_keybuf_count, key); | 9313 | ASET (raw_keybuf, raw_keybuf_count, key); |
| 9327 | (*raw_keybuf_count)++; | 9314 | raw_keybuf_count++; |
| 9328 | } | 9315 | } |
| 9329 | 9316 | ||
| 9330 | /* Clicks in non-text areas get prefixed by the symbol | 9317 | /* Clicks in non-text areas get prefixed by the symbol |
| @@ -9370,9 +9357,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9370 | && BUFFERP (XWINDOW (window)->contents) | 9357 | && BUFFERP (XWINDOW (window)->contents) |
| 9371 | && XBUFFER (XWINDOW (window)->contents) != current_buffer) | 9358 | && XBUFFER (XWINDOW (window)->contents) != current_buffer) |
| 9372 | { | 9359 | { |
| 9373 | GROW_RAW_KEYBUF (1); | 9360 | GROW_RAW_KEYBUF; |
| 9374 | ASET (*raw_keybuf, *raw_keybuf_count, key); | 9361 | ASET (raw_keybuf, raw_keybuf_count, key); |
| 9375 | (*raw_keybuf_count)++; | 9362 | raw_keybuf_count++; |
| 9376 | keybuf[t] = key; | 9363 | keybuf[t] = key; |
| 9377 | mock_input = t + 1; | 9364 | mock_input = t + 1; |
| 9378 | 9365 | ||
| @@ -9865,6 +9852,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, | |||
| 9865 | cancel_hourglass (); | 9852 | cancel_hourglass (); |
| 9866 | #endif | 9853 | #endif |
| 9867 | 9854 | ||
| 9855 | raw_keybuf_count = 0; | ||
| 9868 | i = read_key_sequence (keybuf, ARRAYELTS (keybuf), | 9856 | i = read_key_sequence (keybuf, ARRAYELTS (keybuf), |
| 9869 | prompt, ! NILP (dont_downcase_last), | 9857 | prompt, ! NILP (dont_downcase_last), |
| 9870 | ! NILP (can_return_switch_frame), 0, 0); | 9858 | ! NILP (can_return_switch_frame), 0, 0); |
| @@ -10145,7 +10133,7 @@ shows the events before all translations (except for input methods). | |||
| 10145 | The value is always a vector. */) | 10133 | The value is always a vector. */) |
| 10146 | (void) | 10134 | (void) |
| 10147 | { | 10135 | { |
| 10148 | return Fvector (*raw_keybuf_count, XVECTOR (*raw_keybuf)->contents); | 10136 | return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents); |
| 10149 | } | 10137 | } |
| 10150 | 10138 | ||
| 10151 | DEFUN ("clear-this-command-keys", Fclear_this_command_keys, | 10139 | DEFUN ("clear-this-command-keys", Fclear_this_command_keys, |
| @@ -11290,8 +11278,8 @@ syms_of_keyboard (void) | |||
| 11290 | this_command_keys = Fmake_vector (make_number (40), Qnil); | 11278 | this_command_keys = Fmake_vector (make_number (40), Qnil); |
| 11291 | staticpro (&this_command_keys); | 11279 | staticpro (&this_command_keys); |
| 11292 | 11280 | ||
| 11293 | raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil); | 11281 | raw_keybuf = Fmake_vector (make_number (30), Qnil); |
| 11294 | staticpro (raw_keybuf); | 11282 | staticpro (&raw_keybuf); |
| 11295 | 11283 | ||
| 11296 | DEFSYM (Qcommand_execute, "command-execute"); | 11284 | DEFSYM (Qcommand_execute, "command-execute"); |
| 11297 | DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix"); | 11285 | DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix"); |
diff --git a/src/keyboard.h b/src/keyboard.h index 662d8e4a4f6..c232e778e21 100644 --- a/src/keyboard.h +++ b/src/keyboard.h | |||
| @@ -438,6 +438,7 @@ extern unsigned int timers_run; | |||
| 438 | extern bool menu_separator_name_p (const char *); | 438 | extern bool menu_separator_name_p (const char *); |
| 439 | extern bool parse_menu_item (Lisp_Object, int); | 439 | extern bool parse_menu_item (Lisp_Object, int); |
| 440 | 440 | ||
| 441 | extern void init_raw_keybuf_count (void); | ||
| 441 | extern KBOARD *allocate_kboard (Lisp_Object); | 442 | extern KBOARD *allocate_kboard (Lisp_Object); |
| 442 | extern void delete_kboard (KBOARD *); | 443 | extern void delete_kboard (KBOARD *); |
| 443 | extern void not_single_kboard_state (KBOARD *); | 444 | extern void not_single_kboard_state (KBOARD *); |
diff --git a/src/menu.c b/src/menu.c index d569b4b29b5..b40c2c04ce7 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -1112,51 +1112,8 @@ into menu items. */) | |||
| 1112 | return Qnil; | 1112 | return Qnil; |
| 1113 | } | 1113 | } |
| 1114 | 1114 | ||
| 1115 | 1115 | Lisp_Object | |
| 1116 | DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0, | 1116 | x_popup_menu_1 (Lisp_Object position, Lisp_Object menu) |
| 1117 | doc: /* Pop up a deck-of-cards menu and return user's selection. | ||
| 1118 | POSITION is a position specification. This is either a mouse button event | ||
| 1119 | or a list ((XOFFSET YOFFSET) WINDOW) | ||
| 1120 | where XOFFSET and YOFFSET are positions in pixels from the top left | ||
| 1121 | corner of WINDOW. (WINDOW may be a window or a frame object.) | ||
| 1122 | This controls the position of the top left of the menu as a whole. | ||
| 1123 | If POSITION is t, it means to use the current mouse position. | ||
| 1124 | |||
| 1125 | MENU is a specifier for a menu. For the simplest case, MENU is a keymap. | ||
| 1126 | The menu items come from key bindings that have a menu string as well as | ||
| 1127 | a definition; actually, the "definition" in such a key binding looks like | ||
| 1128 | \(STRING . REAL-DEFINITION). To give the menu a title, put a string into | ||
| 1129 | the keymap as a top-level element. | ||
| 1130 | |||
| 1131 | If REAL-DEFINITION is nil, that puts a nonselectable string in the menu. | ||
| 1132 | Otherwise, REAL-DEFINITION should be a valid key binding definition. | ||
| 1133 | |||
| 1134 | You can also use a list of keymaps as MENU. | ||
| 1135 | Then each keymap makes a separate pane. | ||
| 1136 | |||
| 1137 | When MENU is a keymap or a list of keymaps, the return value is the | ||
| 1138 | list of events corresponding to the user's choice. Note that | ||
| 1139 | `x-popup-menu' does not actually execute the command bound to that | ||
| 1140 | sequence of events. | ||
| 1141 | |||
| 1142 | Alternatively, you can specify a menu of multiple panes | ||
| 1143 | with a list of the form (TITLE PANE1 PANE2...), | ||
| 1144 | where each pane is a list of form (TITLE ITEM1 ITEM2...). | ||
| 1145 | Each ITEM is normally a cons cell (STRING . VALUE); | ||
| 1146 | but a string can appear as an item--that makes a nonselectable line | ||
| 1147 | in the menu. | ||
| 1148 | With this form of menu, the return value is VALUE from the chosen item. | ||
| 1149 | |||
| 1150 | If POSITION is nil, don't display the menu at all, just precalculate the | ||
| 1151 | cached information about equivalent key sequences. | ||
| 1152 | |||
| 1153 | If the user gets rid of the menu without making a valid choice, for | ||
| 1154 | instance by clicking the mouse away from a valid choice or by typing | ||
| 1155 | keyboard input, then this normally results in a quit and | ||
| 1156 | `x-popup-menu' does not return. But if POSITION is a mouse button | ||
| 1157 | event (indicating that the user invoked the menu with the mouse) then | ||
| 1158 | no quit occurs and `x-popup-menu' returns nil. */) | ||
| 1159 | (Lisp_Object position, Lisp_Object menu) | ||
| 1160 | { | 1117 | { |
| 1161 | Lisp_Object keymap, tem, tem2; | 1118 | Lisp_Object keymap, tem, tem2; |
| 1162 | int xpos = 0, ypos = 0; | 1119 | int xpos = 0, ypos = 0; |
| @@ -1443,6 +1400,55 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 1443 | return selection; | 1400 | return selection; |
| 1444 | } | 1401 | } |
| 1445 | 1402 | ||
| 1403 | DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0, | ||
| 1404 | doc: /* Pop up a deck-of-cards menu and return user's selection. | ||
| 1405 | POSITION is a position specification. This is either a mouse button event | ||
| 1406 | or a list ((XOFFSET YOFFSET) WINDOW) | ||
| 1407 | where XOFFSET and YOFFSET are positions in pixels from the top left | ||
| 1408 | corner of WINDOW. (WINDOW may be a window or a frame object.) | ||
| 1409 | This controls the position of the top left of the menu as a whole. | ||
| 1410 | If POSITION is t, it means to use the current mouse position. | ||
| 1411 | |||
| 1412 | MENU is a specifier for a menu. For the simplest case, MENU is a keymap. | ||
| 1413 | The menu items come from key bindings that have a menu string as well as | ||
| 1414 | a definition; actually, the "definition" in such a key binding looks like | ||
| 1415 | \(STRING . REAL-DEFINITION). To give the menu a title, put a string into | ||
| 1416 | the keymap as a top-level element. | ||
| 1417 | |||
| 1418 | If REAL-DEFINITION is nil, that puts a nonselectable string in the menu. | ||
| 1419 | Otherwise, REAL-DEFINITION should be a valid key binding definition. | ||
| 1420 | |||
| 1421 | You can also use a list of keymaps as MENU. | ||
| 1422 | Then each keymap makes a separate pane. | ||
| 1423 | |||
| 1424 | When MENU is a keymap or a list of keymaps, the return value is the | ||
| 1425 | list of events corresponding to the user's choice. Note that | ||
| 1426 | `x-popup-menu' does not actually execute the command bound to that | ||
| 1427 | sequence of events. | ||
| 1428 | |||
| 1429 | Alternatively, you can specify a menu of multiple panes | ||
| 1430 | with a list of the form (TITLE PANE1 PANE2...), | ||
| 1431 | where each pane is a list of form (TITLE ITEM1 ITEM2...). | ||
| 1432 | Each ITEM is normally a cons cell (STRING . VALUE); | ||
| 1433 | but a string can appear as an item--that makes a nonselectable line | ||
| 1434 | in the menu. | ||
| 1435 | With this form of menu, the return value is VALUE from the chosen item. | ||
| 1436 | |||
| 1437 | If POSITION is nil, don't display the menu at all, just precalculate the | ||
| 1438 | cached information about equivalent key sequences. | ||
| 1439 | |||
| 1440 | If the user gets rid of the menu without making a valid choice, for | ||
| 1441 | instance by clicking the mouse away from a valid choice or by typing | ||
| 1442 | keyboard input, then this normally results in a quit and | ||
| 1443 | `x-popup-menu' does not return. But if POSITION is a mouse button | ||
| 1444 | event (indicating that the user invoked the menu with the mouse) then | ||
| 1445 | no quit occurs and `x-popup-menu' returns nil. */) | ||
| 1446 | (Lisp_Object position, Lisp_Object menu) | ||
| 1447 | { | ||
| 1448 | init_raw_keybuf_count (); | ||
| 1449 | return x_popup_menu_1 (position, menu); | ||
| 1450 | } | ||
| 1451 | |||
| 1446 | /* If F's terminal is not capable of displaying a popup dialog, | 1452 | /* If F's terminal is not capable of displaying a popup dialog, |
| 1447 | emulate it with a menu. */ | 1453 | emulate it with a menu. */ |
| 1448 | 1454 | ||
diff --git a/src/menu.h b/src/menu.h index 1469cc87d99..3335616338d 100644 --- a/src/menu.h +++ b/src/menu.h | |||
| @@ -60,4 +60,5 @@ extern Lisp_Object ns_menu_show (struct frame *, int, int, int, | |||
| 60 | extern Lisp_Object tty_menu_show (struct frame *, int, int, int, | 60 | extern Lisp_Object tty_menu_show (struct frame *, int, int, int, |
| 61 | Lisp_Object, const char **); | 61 | Lisp_Object, const char **); |
| 62 | extern ptrdiff_t menu_item_width (const unsigned char *); | 62 | extern ptrdiff_t menu_item_width (const unsigned char *); |
| 63 | extern Lisp_Object x_popup_menu_1 (Lisp_Object position, Lisp_Object menu); | ||
| 63 | #endif /* MENU_H */ | 64 | #endif /* MENU_H */ |