aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c76
-rw-r--r--src/keyboard.h1
-rw-r--r--src/menu.c96
-rw-r--r--src/menu.h1
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. */
124static Lisp_Object raw_keybuf_buffer; 125static Lisp_Object raw_keybuf;
125static int raw_keybuf_count_buffer; 126static int raw_keybuf_count;
126static Lisp_Object *raw_keybuf = &raw_keybuf_buffer; 127
127static 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
8868void 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).
10145The value is always a vector. */) 10133The 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
10151DEFUN ("clear-this-command-keys", Fclear_this_command_keys, 10139DEFUN ("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;
438extern bool menu_separator_name_p (const char *); 438extern bool menu_separator_name_p (const char *);
439extern bool parse_menu_item (Lisp_Object, int); 439extern bool parse_menu_item (Lisp_Object, int);
440 440
441extern void init_raw_keybuf_count (void);
441extern KBOARD *allocate_kboard (Lisp_Object); 442extern KBOARD *allocate_kboard (Lisp_Object);
442extern void delete_kboard (KBOARD *); 443extern void delete_kboard (KBOARD *);
443extern void not_single_kboard_state (KBOARD *); 444extern 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 1115Lisp_Object
1116DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0, 1116x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
1117 doc: /* Pop up a deck-of-cards menu and return user's selection.
1118POSITION is a position specification. This is either a mouse button event
1119or a list ((XOFFSET YOFFSET) WINDOW)
1120where XOFFSET and YOFFSET are positions in pixels from the top left
1121corner of WINDOW. (WINDOW may be a window or a frame object.)
1122This controls the position of the top left of the menu as a whole.
1123If POSITION is t, it means to use the current mouse position.
1124
1125MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
1126The menu items come from key bindings that have a menu string as well as
1127a 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
1129the keymap as a top-level element.
1130
1131If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
1132Otherwise, REAL-DEFINITION should be a valid key binding definition.
1133
1134You can also use a list of keymaps as MENU.
1135 Then each keymap makes a separate pane.
1136
1137When MENU is a keymap or a list of keymaps, the return value is the
1138list of events corresponding to the user's choice. Note that
1139`x-popup-menu' does not actually execute the command bound to that
1140sequence of events.
1141
1142Alternatively, you can specify a menu of multiple panes
1143 with a list of the form (TITLE PANE1 PANE2...),
1144where each pane is a list of form (TITLE ITEM1 ITEM2...).
1145Each ITEM is normally a cons cell (STRING . VALUE);
1146but a string can appear as an item--that makes a nonselectable line
1147in the menu.
1148With this form of menu, the return value is VALUE from the chosen item.
1149
1150If POSITION is nil, don't display the menu at all, just precalculate the
1151cached information about equivalent key sequences.
1152
1153If the user gets rid of the menu without making a valid choice, for
1154instance by clicking the mouse away from a valid choice or by typing
1155keyboard input, then this normally results in a quit and
1156`x-popup-menu' does not return. But if POSITION is a mouse button
1157event (indicating that the user invoked the menu with the mouse) then
1158no 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
1403DEFUN ("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.
1405POSITION is a position specification. This is either a mouse button event
1406or a list ((XOFFSET YOFFSET) WINDOW)
1407where XOFFSET and YOFFSET are positions in pixels from the top left
1408corner of WINDOW. (WINDOW may be a window or a frame object.)
1409This controls the position of the top left of the menu as a whole.
1410If POSITION is t, it means to use the current mouse position.
1411
1412MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
1413The menu items come from key bindings that have a menu string as well as
1414a 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
1416the keymap as a top-level element.
1417
1418If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
1419Otherwise, REAL-DEFINITION should be a valid key binding definition.
1420
1421You can also use a list of keymaps as MENU.
1422 Then each keymap makes a separate pane.
1423
1424When MENU is a keymap or a list of keymaps, the return value is the
1425list of events corresponding to the user's choice. Note that
1426`x-popup-menu' does not actually execute the command bound to that
1427sequence of events.
1428
1429Alternatively, you can specify a menu of multiple panes
1430 with a list of the form (TITLE PANE1 PANE2...),
1431where each pane is a list of form (TITLE ITEM1 ITEM2...).
1432Each ITEM is normally a cons cell (STRING . VALUE);
1433but a string can appear as an item--that makes a nonselectable line
1434in the menu.
1435With this form of menu, the return value is VALUE from the chosen item.
1436
1437If POSITION is nil, don't display the menu at all, just precalculate the
1438cached information about equivalent key sequences.
1439
1440If the user gets rid of the menu without making a valid choice, for
1441instance by clicking the mouse away from a valid choice or by typing
1442keyboard input, then this normally results in a quit and
1443`x-popup-menu' does not return. But if POSITION is a mouse button
1444event (indicating that the user invoked the menu with the mouse) then
1445no 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,
60extern Lisp_Object tty_menu_show (struct frame *, int, int, int, 60extern Lisp_Object tty_menu_show (struct frame *, int, int, int,
61 Lisp_Object, const char **); 61 Lisp_Object, const char **);
62extern ptrdiff_t menu_item_width (const unsigned char *); 62extern ptrdiff_t menu_item_width (const unsigned char *);
63extern Lisp_Object x_popup_menu_1 (Lisp_Object position, Lisp_Object menu);
63#endif /* MENU_H */ 64#endif /* MENU_H */