#include "systime.h"
#include "atimer.h"
#include "process.h"
+#include "menu.h"
#include <errno.h>
#ifdef HAVE_PTHREAD
/* This vector is used as a buffer to record the events that were actually read
by read_key_sequence. */
-static Lisp_Object raw_keybuf_buffer;
-static int raw_keybuf_count_buffer;
-static Lisp_Object *raw_keybuf = &raw_keybuf_buffer;
-static int *raw_keybuf_count = &raw_keybuf_count_buffer;
-
-#define GROW_RAW_KEYBUF(inc) \
- if (*raw_keybuf_count > ASIZE (*raw_keybuf) - (inc)) \
- *raw_keybuf = \
- larger_vector (*raw_keybuf, \
- (inc) + *raw_keybuf_count - ASIZE (*raw_keybuf), \
- -1)
+static Lisp_Object raw_keybuf;
+static int raw_keybuf_count;
+
+#define GROW_RAW_KEYBUF \
+ if (raw_keybuf_count == ASIZE (raw_keybuf)) \
+ raw_keybuf = larger_vector (raw_keybuf, 1, -1)
/* Number of elements of this_command_keys
that precede this key sequence. */
Vthis_command_keys_shift_translated = Qnil;
/* Read next key sequence; i gets its length. */
- raw_keybuf_count = &raw_keybuf_count_buffer; /* For safety */
- raw_keybuf = &raw_keybuf_buffer; /* Ditto */
+ raw_keybuf_count = 0;
i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
Qnil, 0, 1, 1, 0);
/* Display the menu and get the selection. */
Lisp_Object value;
- value = Fx_popup_menu (prev_event, get_keymap (map, 0, 1));
+ value = x_popup_menu_1 (prev_event, get_keymap (map, 0, 1));
if (CONSP (value))
{
Lisp_Object tem;
&& EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
}
+void init_raw_keybuf_count (void)
+{
+ raw_keybuf_count = 0;
+}
+
/* Read a sequence of keys that ends with a non prefix character,
storing it in KEYBUF, a buffer of size BUFSIZE.
Prompt with PROMPT.
/* How many keys there are in the current key sequence. */
int t;
- int *outer_raw_keybuf_count;
- Lisp_Object *outer_raw_keybuf;
- int inner_raw_keybuf_count_buffer;
- Lisp_Object inner_raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil);
-
/* The length of the echo buffer when we started reading, and
the length of this_command_keys when we started reading. */
ptrdiff_t echo_start UNINIT;
/* List of events for which a fake prefix key has been generated. */
Lisp_Object fake_prefixed_keys = Qnil;
- *raw_keybuf_count = 0;
+ /* raw_keybuf_count is now initialized in (most of) the callers of
+ read_key_sequence. This is so that in a recursive call (for
+ mouse menus) a spurious initialization doesn't erase the contents
+ of raw_keybuf created by the outer call. */
+ /* raw_keybuf_count = 0; */
last_nonmenu_event = Qnil;
{
KBOARD *interrupted_kboard = current_kboard;
struct frame *interrupted_frame = SELECTED_FRAME ();
- int i;
- outer_raw_keybuf_count = raw_keybuf_count;
- outer_raw_keybuf = raw_keybuf;
- inner_raw_keybuf_count_buffer = 0;
- raw_keybuf_count = &inner_raw_keybuf_count_buffer;
- raw_keybuf = &inner_raw_keybuf_buffer;
/* Calling read_char with COMMANDFLAG = -2 avoids
redisplay in read_char and its subroutines. */
key = read_char (prevent_redisplay ? -2 : NILP (prompt),
current_binding, last_nonmenu_event,
&used_mouse_menu, NULL);
- raw_keybuf_count = outer_raw_keybuf_count;
- raw_keybuf = outer_raw_keybuf;
- GROW_RAW_KEYBUF (inner_raw_keybuf_count_buffer);
- for (i = 0; i < inner_raw_keybuf_count_buffer; i++)
- ASET (*raw_keybuf, (*raw_keybuf_count)++,
- AREF (inner_raw_keybuf_buffer, i));
if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
/* When switching to a new tty (with a new keyboard),
read_char returns the new buffer, rather than -2
&& XINT (key) == quit_char
&& current_buffer != starting_buffer)
{
- GROW_RAW_KEYBUF (1);
- ASET (*raw_keybuf, *raw_keybuf_count, key);
- (*raw_keybuf_count)++;
+ GROW_RAW_KEYBUF;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
keybuf[t++] = key;
mock_input = t;
Vquit_flag = Qnil;
current_binding = active_maps (first_event);
}
- GROW_RAW_KEYBUF (1);
- ASET (*raw_keybuf, *raw_keybuf_count, key);
- (*raw_keybuf_count)++;
+ GROW_RAW_KEYBUF;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
}
/* Clicks in non-text areas get prefixed by the symbol
&& BUFFERP (XWINDOW (window)->contents)
&& XBUFFER (XWINDOW (window)->contents) != current_buffer)
{
- GROW_RAW_KEYBUF (1);
- ASET (*raw_keybuf, *raw_keybuf_count, key);
- (*raw_keybuf_count)++;
+ GROW_RAW_KEYBUF;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
keybuf[t] = key;
mock_input = t + 1;
cancel_hourglass ();
#endif
+ raw_keybuf_count = 0;
i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), 0, 0);
The value is always a vector. */)
(void)
{
- return Fvector (*raw_keybuf_count, XVECTOR (*raw_keybuf)->contents);
+ return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents);
}
DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
this_command_keys = Fmake_vector (make_number (40), Qnil);
staticpro (&this_command_keys);
- raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil);
- staticpro (raw_keybuf);
+ raw_keybuf = Fmake_vector (make_number (30), Qnil);
+ staticpro (&raw_keybuf);
DEFSYM (Qcommand_execute, "command-execute");
DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix");
return Qnil;
}
-
-DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
- doc: /* Pop up a deck-of-cards menu and return user's selection.
-POSITION is a position specification. This is either a mouse button event
-or a list ((XOFFSET YOFFSET) WINDOW)
-where XOFFSET and YOFFSET are positions in pixels from the top left
-corner of WINDOW. (WINDOW may be a window or a frame object.)
-This controls the position of the top left of the menu as a whole.
-If POSITION is t, it means to use the current mouse position.
-
-MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
-The menu items come from key bindings that have a menu string as well as
-a definition; actually, the "definition" in such a key binding looks like
-\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
-the keymap as a top-level element.
-
-If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
-Otherwise, REAL-DEFINITION should be a valid key binding definition.
-
-You can also use a list of keymaps as MENU.
- Then each keymap makes a separate pane.
-
-When MENU is a keymap or a list of keymaps, the return value is the
-list of events corresponding to the user's choice. Note that
-`x-popup-menu' does not actually execute the command bound to that
-sequence of events.
-
-Alternatively, you can specify a menu of multiple panes
- with a list of the form (TITLE PANE1 PANE2...),
-where each pane is a list of form (TITLE ITEM1 ITEM2...).
-Each ITEM is normally a cons cell (STRING . VALUE);
-but a string can appear as an item--that makes a nonselectable line
-in the menu.
-With this form of menu, the return value is VALUE from the chosen item.
-
-If POSITION is nil, don't display the menu at all, just precalculate the
-cached information about equivalent key sequences.
-
-If the user gets rid of the menu without making a valid choice, for
-instance by clicking the mouse away from a valid choice or by typing
-keyboard input, then this normally results in a quit and
-`x-popup-menu' does not return. But if POSITION is a mouse button
-event (indicating that the user invoked the menu with the mouse) then
-no quit occurs and `x-popup-menu' returns nil. */)
- (Lisp_Object position, Lisp_Object menu)
+Lisp_Object
+x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
{
Lisp_Object keymap, tem, tem2;
int xpos = 0, ypos = 0;
return selection;
}
+DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
+ doc: /* Pop up a deck-of-cards menu and return user's selection.
+POSITION is a position specification. This is either a mouse button event
+or a list ((XOFFSET YOFFSET) WINDOW)
+where XOFFSET and YOFFSET are positions in pixels from the top left
+corner of WINDOW. (WINDOW may be a window or a frame object.)
+This controls the position of the top left of the menu as a whole.
+If POSITION is t, it means to use the current mouse position.
+
+MENU is a specifier for a menu. For the simplest case, MENU is a keymap.
+The menu items come from key bindings that have a menu string as well as
+a definition; actually, the "definition" in such a key binding looks like
+\(STRING . REAL-DEFINITION). To give the menu a title, put a string into
+the keymap as a top-level element.
+
+If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
+Otherwise, REAL-DEFINITION should be a valid key binding definition.
+
+You can also use a list of keymaps as MENU.
+ Then each keymap makes a separate pane.
+
+When MENU is a keymap or a list of keymaps, the return value is the
+list of events corresponding to the user's choice. Note that
+`x-popup-menu' does not actually execute the command bound to that
+sequence of events.
+
+Alternatively, you can specify a menu of multiple panes
+ with a list of the form (TITLE PANE1 PANE2...),
+where each pane is a list of form (TITLE ITEM1 ITEM2...).
+Each ITEM is normally a cons cell (STRING . VALUE);
+but a string can appear as an item--that makes a nonselectable line
+in the menu.
+With this form of menu, the return value is VALUE from the chosen item.
+
+If POSITION is nil, don't display the menu at all, just precalculate the
+cached information about equivalent key sequences.
+
+If the user gets rid of the menu without making a valid choice, for
+instance by clicking the mouse away from a valid choice or by typing
+keyboard input, then this normally results in a quit and
+`x-popup-menu' does not return. But if POSITION is a mouse button
+event (indicating that the user invoked the menu with the mouse) then
+no quit occurs and `x-popup-menu' returns nil. */)
+ (Lisp_Object position, Lisp_Object menu)
+{
+ init_raw_keybuf_count ();
+ return x_popup_menu_1 (position, menu);
+}
+
/* If F's terminal is not capable of displaying a popup dialog,
emulate it with a menu. */