/* Last input character read for any purpose. */
Lisp_Object last_input_char;
-/* If not Qnil, an object to be read as the next command input. */
-Lisp_Object unread_command_event;
+/* If not Qnil, a list of objects to be read as subsequent command input. */
+Lisp_Object unread_command_events;
/* If not Qnil, this is a switch-frame event which we decided to put
off until the end of a key sequence. This should be read as the
- next command input, after any unread_command_event.
+ next command input, after any unread_command_events.
read_key_sequence uses this to delay switch-frame events until the
end of the key sequence; Fread_char uses it to put off switch-frame
if (!NILP (Vquit_flag))
{
Vquit_flag = Qnil;
- unread_command_event = make_number (quit_char);
+ unread_command_events = Fcons (make_number (quit_char), Qnil);
}
}
int count;
jmp_buf save_jump;
- if (!NILP (unread_command_event))
+ if (CONSP (unread_command_events))
{
- c = unread_command_event;
- unread_command_event = Qnil;
+ c = XCONS (unread_command_events)->car;
+ unread_command_events = XCONS (unread_command_events)->cdr;
if (this_command_key_count == 0)
goto reread_first;
/* After a mouse event, start echoing right away.
This is because we are probably about to display a menu,
and we don't want to delay before doing so. */
- if (XTYPE (prev_event) == Lisp_Cons)
+ if (EVENT_HAS_PARAMETERS (prev_event))
echo ();
else
{
{
int button = XFASTINT (event->code);
Lisp_Object position;
- Lisp_Object *start_pos;
+ Lisp_Object *start_pos_ptr;
+ Lisp_Object start_pos;
if (button < 0 || button >= NUM_MOUSE_BUTTONS)
abort ();
posn = Qnil;
else
{
+ XSETINT (event->x,
+ (XINT (event->x) - XINT (XWINDOW (window)->left)));
+ XSETINT (event->y,
+ (XINT (event->y) - XINT (XWINDOW (window)->top)));
+
if (part == 1)
posn = Qmode_line;
else if (part == 2)
posn = Qvertical_line;
else
- {
- XSETINT (event->x, (XINT (event->x)
- - XINT (XWINDOW (window)->left)));
- XSETINT (event->y, (XINT (event->y)
- - XINT (XWINDOW (window)->top)));
- XSET (posn, Lisp_Int,
- buffer_posn_from_coords (XWINDOW (window),
- XINT (event->x),
- XINT (event->y)));
- }
+ XSET (posn, Lisp_Int,
+ buffer_posn_from_coords (XWINDOW (window),
+ XINT (event->x),
+ XINT (event->y)));
}
position =
Qnil)))));
}
- start_pos = &XVECTOR (button_down_location)->contents[button];
+ start_pos_ptr = &XVECTOR (button_down_location)->contents[button];
+
+ start_pos = *start_pos_ptr;
+ *start_pos_ptr = Qnil;
/* If this is a button press, squirrel away the location, so
we can decide later whether it was a click or a drag. */
if (event->modifiers & down_modifier)
- *start_pos = Fcopy_alist (position);
+ *start_pos_ptr = Fcopy_alist (position);
/* Now we're releasing a button - check the co-ordinates to
see if this was a click or a drag. */
else if (event->modifiers & up_modifier)
{
- Lisp_Object down = Fnth (make_number (2), *start_pos);
-
- /* The third element of every position should be the (x,y)
- pair. */
- if (! CONSP (down))
- abort ();
-
+ /* Is there a start position stored at all for this
+ button?
+
+ It would be nice if we could assume that if we're
+ getting a button release, we must therefore have gotten
+ a button press. Unfortunately, the X menu code thwarts
+ this assumption, so we'll have to be more robust. We
+ treat a button release with no stored start position as
+ a click. */
event->modifiers &= ~up_modifier;
- event->modifiers |= ((EQ (event->x, XCONS (down)->car)
- && EQ (event->y, XCONS (down)->cdr))
- ? click_modifier
- : drag_modifier);
+ if (XTYPE (start_pos) != Lisp_Cons)
+ event->modifiers |= click_modifier;
+ else
+ {
+ /* The third element of every position should be the (x,y)
+ pair. */
+ Lisp_Object down = Fnth (make_number (2), start_pos);
+
+ event->modifiers |= ((EQ (event->x, XCONS (down)->car)
+ && EQ (event->y, XCONS (down)->cdr))
+ ? click_modifier
+ : drag_modifier);
+ }
}
else
/* Every mouse event should either have the down_modifier or
/ sizeof (lispy_mouse_names[0])));
if (event->modifiers & drag_modifier)
- {
- Lisp_Object lispy_event =
- Fcons (head,
- Fcons (*start_pos,
- Fcons (position,
- Qnil)));
-
- /* Allow this to be GC'd. */
- *start_pos = Qnil;
-
- return lispy_event;
- }
+ return Fcons (head,
+ Fcons (start_pos,
+ Fcons (position,
+ Qnil)));
else
return Fcons (head,
Fcons (position,
}
\f
-DEFUN ("mouse-click-p", Fmouse_click_p, Smouse_click_p, 1, 1, 0,
- "Return non-nil iff OBJECT is a representation of a mouse event.\n\
-A mouse event is a list of five elements whose car is a symbol of the\n\
-form <MODIFIERS>mouse-<DIGIT>. I hope this is a temporary hack.")
- (object)
- Lisp_Object object;
-{
- if (EVENT_HAS_PARAMETERS (object)
- && EQ (EVENT_HEAD_KIND (EVENT_HEAD (object)),
- Qmouse_click))
- return Qt;
- else
- return Qnil;
-}
-\f
/* Store into *addr a value nonzero if terminal input chars are available.
Serves the purpose of ioctl (0, FIONREAD, addr)
but works even if FIONREAD does not exist.
static int echo_now;
/* Read a character like read_char but optionally prompt based on maps
- in the array MAPS. NMAPS is the length of MAPS.
+ in the array MAPS. NMAPS is the length of MAPS. Return nil if we
+ decided not to read a character, because there are no menu items in
+ MAPS.
PREV_EVENT is the previous input event, or nil if we are reading
the first event of a key sequence.
}
/* If we don't have any menus, just read a character normally. */
- if (NILP (name))
+ if (mapno >= nmaps)
return Qnil;
-#ifdef HAVE_X_WINDOW
-#ifndef NO_X_MENU
+#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_X_MENU
/* If we got to this point via a mouse click,
use a real menu for mouse selection. */
- if (XTYPE (prev_event) == Lisp_Cons)
+ if (EVENT_HAS_PARAMETERS (prev_event))
{
/* Display the menu and get the selection. */
Lisp_Object *realmaps
*used_mouse_menu = 1;
return value;
}
-#endif /* not NO_X_MENU */
-#endif /* HAVE_X_WINDOW */
+#endif /* HAVE_X_MENU */
+#endif /* HAVE_X_WINDOWS */
/* Prompt string always starts with map's prompt, and a space. */
strcpy (menu, XSTRING (name)->data);
Actually, the value is nil only if we can be sure that no input is available.")
()
{
- if (!NILP (unread_command_event))
+ if (!NILP (unread_command_events))
return (Qt);
return detect_input_pending () ? Qt : Qnil;
defining_kbd_macro = 0;
update_mode_lines++;
- unread_command_event = Qnil;
+ unread_command_events = Qnil;
discard_tty_input ();
clear_waiting_for_input ();
input_pending = 0;
- unread_command_event = Qnil;
+ unread_command_events = Qnil;
_longjmp (getcjmp, 1);
}
command_loop_level = -1;
immediate_quit = 0;
quit_char = Ctl ('g');
- unread_command_event = Qnil;
+ unread_command_events = Qnil;
total_keys = 0;
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
defsubr (&Sread_key_sequence);
defsubr (&Srecursive_edit);
defsubr (&Strack_mouse);
- defsubr (&Smouse_click_p);
defsubr (&Sinput_pending_p);
defsubr (&Scommand_execute);
defsubr (&Srecent_keys);
DEFVAR_LISP ("last-input-char", &last_input_char,
"Last terminal input key.");
- DEFVAR_LISP ("unread-command-event", &unread_command_event,
- "Object to be read as next input from input stream, or nil if none.");
+ DEFVAR_LISP ("unread-command-events", &unread_command_events,
+ "Lisp of object to be read as next input from input stream, or nil if none.");
DEFVAR_LISP ("meta-prefix-char", &meta_prefix_char,
"Meta-prefix character code. Meta-foo as command input\n\