/* Keyboard and mouse input; editor command loop.
-Copyright (C) 1985-1989, 1993-1997, 1999-2011 Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993-1997, 1999-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "keyboard.h"
#include "window.h"
#include "commands.h"
-#include "buffer.h"
#include "character.h"
+#include "buffer.h"
#include "disptab.h"
#include "dispextern.h"
#include "syntax.h"
#include "nsterm.h"
#endif
-/* Variables for blockinput.h: */
+/* Variables for blockinput.h: */
/* Non-zero if interrupt input is blocked right now. */
volatile int interrupt_input_blocked;
static EMACS_INT last_auto_save;
-/* This is like Vthis_command, except that commands never set it. */
-Lisp_Object real_this_command;
-
/* The value of point when the last command was started. */
static ptrdiff_t last_point_position;
Time last_event_timestamp;
static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
+static Lisp_Object Qhandle_select_window;
Lisp_Object QPRIMARY;
static Lisp_Object Qself_insert_command;
Lisp_Object Qevent_kind;
static Lisp_Object Qevent_symbol_elements;
-/* menu and tool bar item parts */
+/* Menu and tool bar item parts. */
static Lisp_Object Qmenu_enable;
static Lisp_Object QCenable, QCvisible, QChelp, QCkeys, QCkey_sequence;
Lisp_Object QCfilter;
static Lisp_Object (Fcommand_execute) (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
static void handle_interrupt (void);
-static void quit_throw_to_read_char (void) NO_RETURN;
+static void quit_throw_to_read_char (int) NO_RETURN;
+static void process_special_events (void);
static void timer_start_idle (void);
static void timer_stop_idle (void);
static void timer_resume_idle (void);
echo_kboard = current_kboard;
if (waiting_for_input && !NILP (Vquit_flag))
- quit_throw_to_read_char ();
+ quit_throw_to_read_char (0);
}
/* Turn off echoing, for the start of a new command. */
\f
#if 0 /* These two functions are now replaced with
- temporarily_switch_to_single_kboard. */
+ temporarily_switch_to_single_kboard. */
static void
any_kboard_state ()
{
state later.
If Emacs is already in single_kboard mode, and F's keyboard is
- locked, then this function will throw an errow. */
+ locked, then this function will throw an error. */
void
temporarily_switch_to_single_kboard (struct frame *f)
Vquit_flag = Qnil;
Vinhibit_quit = Qnil;
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
if (command_loop_level == 0 && minibuf_level == 0)
any_kboard_state ();
#endif
struct frame *sf = SELECTED_FRAME ();
/* The immediate context is not interesting for Quits,
- since they are asyncronous. */
+ since they are asynchronous. */
if (EQ (XCAR (data), Qquit))
Vsignaling_function = Qnil;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
/* Reset single_kboard in case top-level set it while
evaluating an -f option, or we are stuck there for some
- other reason. */
+ other reason. */
any_kboard_state ();
#endif
internal_catch (Qtop_level, command_loop_2, Qnil);
Fthrow (Qtop_level, Qnil);
}
+static void user_error (const char*) NO_RETURN;
+static void user_error (const char *msg)
+{
+ xsignal1 (Quser_error, build_string (msg));
+}
+
static Lisp_Object Fexit_recursive_edit (void) NO_RETURN;
DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
doc: /* Exit from the innermost recursive edit or minibuffer. */)
if (command_loop_level > 0 || minibuf_level > 0)
Fthrow (Qexit, Qnil);
- error ("No recursive edit is in progress");
+ user_error ("No recursive edit is in progress");
}
static Lisp_Object Fabort_recursive_edit (void) NO_RETURN;
if (command_loop_level > 0 || minibuf_level > 0)
Fthrow (Qexit, Qt);
- error ("No recursive edit is in progress");
+ user_error ("No recursive edit is in progress");
}
\f
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* Do this after running Vpost_command_hook, for consistency. */
KVAR (current_kboard, Vlast_command) = Vthis_command;
- KVAR (current_kboard, Vreal_last_command) = real_this_command;
+ KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
if (!CONSP (last_command_event))
- KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+ KVAR (current_kboard, Vlast_repeatable_command) = Vreal_this_command;
while (1)
{
before_command_echo_length = echo_length ();
Vthis_command = Qnil;
- real_this_command = Qnil;
+ Vreal_this_command = Qnil;
Vthis_original_command = Qnil;
Vthis_command_keys_shift_translated = Qnil;
from that position. But also throw away beg_unchanged and
end_unchanged information in that case, so that redisplay will
update the whole window properly. */
- if (!NILP (XWINDOW (selected_window)->force_start))
+ if (XWINDOW (selected_window)->force_start)
{
struct buffer *b;
- XWINDOW (selected_window)->force_start = Qnil;
+ XWINDOW (selected_window)->force_start = 0;
b = XBUFFER (XWINDOW (selected_window)->buffer);
BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
}
if (!NILP (Vquit_flag))
{
Vexecuting_kbd_macro = Qt;
- QUIT; /* Make some noise. */
- /* Will return since macro now empty. */
+ QUIT; /* Make some noise. */
+ /* Will return since macro now empty. */
}
}
Vdisable_point_adjustment = Qnil;
/* Process filters and timers may have messed with deactivate-mark.
- reset it before we execute the command. */
+ reset it before we execute the command. */
Vdeactivate_mark = Qnil;
/* Remap command through active keymaps. */
/* Execute the command. */
Vthis_command = cmd;
- real_this_command = cmd;
+ Vreal_this_command = cmd;
safe_run_hooks (Qpre_command_hook);
already_adjusted = 0;
}
else
{
- /* Here for a command that isn't executed directly */
+ /* Here for a command that isn't executed directly. */
#ifdef HAVE_WINDOW_SYSTEM
ptrdiff_t scount = SPECPDL_INDEX ();
If the command didn't actually create a prefix arg,
but is merely a frame event that is transparent to prefix args,
then the above doesn't apply. */
- if (NILP (KVAR (current_kboard, Vprefix_arg)) || CONSP (last_command_event))
+ if (NILP (KVAR (current_kboard, Vprefix_arg))
+ || CONSP (last_command_event))
{
KVAR (current_kboard, Vlast_command) = Vthis_command;
- KVAR (current_kboard, Vreal_last_command) = real_this_command;
+ KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
if (!CONSP (last_command_event))
- KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+ KVAR (current_kboard, Vlast_repeatable_command)
+ = Vreal_this_command;
cancel_echoing ();
this_command_key_count = 0;
this_command_key_count_reset = 0;
? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
: (!NILP (Vselect_active_regions)
&& !NILP (Vtransient_mark_mode)))
- && !EQ (Vthis_command, Qhandle_switch_frame))
+ && NILP (Fmemq (Vthis_command,
+ Vselection_inhibit_update_commands)))
{
ptrdiff_t beg =
XINT (Fmarker_position (BVAR (current_buffer, mark)));
{
xassert (end > PT);
SET_PT (PT < last_pt
- ? (STRINGP (val) && SCHARS (val) == 0 ? beg - 1 : beg)
+ ? (STRINGP (val) && SCHARS (val) == 0
+ ? max (beg - 1, BEGV)
+ : beg)
: end);
check_composition = check_invisible = 1;
}
= CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit;
Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil;
Lisp_Object args[4];
- args[0] = build_string ("Error in %s (%s): %s");
+ args[0] = build_string ("Error in %s (%s): %S");
args[1] = hook;
args[2] = fun;
args[3] = error_data;
poll_for_input_1 (void)
{
/* Tell ns_read_socket() it is being called asynchronously so it can avoid
- doing anything dangerous. */
+ doing anything dangerous. */
#ifdef HAVE_NS
++handling_signal;
#endif
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
if (!interrupt_input)
{
/* Turn alarm handling on unconditionally. It might have
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
return !interrupt_input;
#else
return 0;
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
if (!interrupt_input)
++poll_suppress_count;
#endif
polling_stopped_here = 0; } while (0)
/* read a character from the keyboard; call the redisplay if needed */
-/* commandflag 0 means do not do auto-saving, but do do redisplay.
- -1 means do not do redisplay, but do do autosaving.
+/* commandflag 0 means do not autosave, but do redisplay.
+ -1 means do not redisplay, but do autosave.
1 means do both. */
/* The arguments MAPS and NMAPS are for menu prompting.
real event came from. Normally, a switch-frame event selects
internal_last_event_frame after each command is read, but
events read from a macro should never cause a new frame to be
- selected. */
+ selected. */
Vlast_event_frame = internal_last_event_frame = Qmacro;
/* Exit the macro if we are at the end.
Try this before the sit-for, because the sit-for
would do the wrong thing if we are supposed to do
menu prompting. If EVENT_HAS_PARAMETERS then we are reading
- after a mouse event so don't try a minibuf menu. */
+ after a mouse event so don't try a minibuf menu. */
c = Qnil;
if (nmaps > 0 && INTERACTIVE
&& !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
own stuff with the echo area. */
if (!CONSP (c)
|| (!(EQ (Qhelp_echo, XCAR (c)))
- && !(EQ (Qswitch_frame, XCAR (c)))))
+ && !(EQ (Qswitch_frame, XCAR (c)))
+ /* Don't wipe echo area for select window events: These might
+ get delayed via `mouse-autoselect-window' (Bug#11304). */
+ && !(EQ (Qselect_window, XCAR (c)))))
{
if (!NILP (echo_area_buffer[0]))
- safe_run_hooks (Qecho_area_clear_hook);
- clear_message (1, 0);
+ {
+ safe_run_hooks (Qecho_area_clear_hook);
+ clear_message (1, 0);
+ }
}
reread_for_input_method:
Lisp_Object keys;
ptrdiff_t key_count;
int key_count_reset;
- struct gcpro inner_gcpro1;
+ struct gcpro gcpro1;
ptrdiff_t count = SPECPDL_INDEX ();
/* Save the echo status. */
keys = Fcopy_sequence (this_command_keys);
else
keys = Qnil;
- GCPRO1_VAR (keys, inner_gcpro);
+ GCPRO1 (keys);
/* Clear out this_command_keys. */
this_command_key_count = 0;
if (saved_immediate_echo)
echo_now ();
- UNGCPRO_VAR (inner_gcpro);
+ UNGCPRO;
/* The input method can return no events. */
if (! CONSP (tem))
int *used_mouse_menu,
struct timeval *end_time)
{
- register int c;
Lisp_Object obj;
#ifdef subprocesses
}
#endif /* subprocesses */
+#ifndef HAVE_DBUS /* We want to read D-Bus events in batch mode. */
if (noninteractive
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
|| (IS_DAEMON && daemon_pipe[1] >= 0))
{
- c = getchar ();
+ int c = getchar ();
XSETINT (obj, c);
*kbp = current_kboard;
return obj;
}
+#endif /* ! HAVE_DBUS */
/* Wait until there is input available. */
for (;;)
/* If the quit flag is set, then read_char will return
quit_char, so that counts as "available input." */
if (!NILP (Vquit_flag))
- quit_throw_to_read_char ();
+ quit_throw_to_read_char (0);
/* One way or another, wait until input is available; then, if
interrupt handlers have not read it, read it now. */
return (obj);
}
\f
-/* Process any events that are not user-visible,
- then return, without reading any user-visible events. */
+/* Process any non-user-visible events (currently X selection events),
+ without reading any user-visible events. */
-void
-swallow_events (int do_display)
+static void
+process_special_events (void)
{
- int old_timers_run;
+ struct input_event *event;
- while (kbd_fetch_ptr != kbd_store_ptr)
+ for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event)
{
- struct input_event *event;
-
- event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
- ? kbd_fetch_ptr
- : kbd_buffer);
-
- last_event_timestamp = event->timestamp;
+ if (event == kbd_buffer + KBD_BUFFER_SIZE)
+ {
+ event = kbd_buffer;
+ if (event == kbd_store_ptr)
+ break;
+ }
- /* These two kinds of events get special handling
- and don't actually appear to the command loop. */
+ /* If we find a stored X selection request, handle it now. */
if (event->kind == SELECTION_REQUEST_EVENT
|| event->kind == SELECTION_CLEAR_EVENT)
{
#ifdef HAVE_X11
- struct input_event copy;
- /* Remove it from the buffer before processing it,
- since otherwise swallow_events called recursively could see it
- and process it again. */
- copy = *event;
- kbd_fetch_ptr = event + 1;
+ /* Remove the event from the fifo buffer before processing;
+ otherwise swallow_events called recursively could see it
+ and process it again. To do this, we move the events
+ between kbd_fetch_ptr and EVENT one slot to the right,
+ cyclically. */
+
+ struct input_event copy = *event;
+ struct input_event *beg
+ = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
+ ? kbd_buffer : kbd_fetch_ptr;
+
+ if (event > beg)
+ memmove (beg + 1, beg, (event - beg) * sizeof (struct input_event));
+ else if (event < beg)
+ {
+ if (event > kbd_buffer)
+ memmove (kbd_buffer + 1, kbd_buffer,
+ (event - kbd_buffer) * sizeof (struct input_event));
+ *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1);
+ if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1)
+ memmove (beg + 1, beg,
+ (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg)
+ * sizeof (struct input_event));
+ }
+
+ if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
+ kbd_fetch_ptr = kbd_buffer + 1;
+ else
+ kbd_fetch_ptr++;
+
+ /* X wants last_event_timestamp for selection ownership. */
+ last_event_timestamp = copy.timestamp;
input_pending = readable_events (0);
x_handle_selection_event (©);
#else
abort ();
#endif
}
- else
- break;
}
+}
+
+/* Process any events that are not user-visible, run timer events that
+ are ripe, and return, without reading any user-visible events. */
+
+void
+swallow_events (int do_display)
+{
+ int old_timers_run;
+
+ process_special_events ();
old_timers_run = timers_run;
get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
"ico-00", /* VK_ICO_00 0xE4 */
0, /* VK_PROCESSKEY 0xE5 - used by IME */
"ico-clear", /* VK_ICO_CLEAR 0xE6 */
- 0, /* VK_PACKET 0xE7 - used to pass unicode chars */
+ 0, /* VK_PACKET 0xE7 - used to pass Unicode chars */
0, /* 0xE8 */
"reset", /* VK_OEM_RESET 0xE9 */
"jump", /* VK_OEM_JUMP 0xEA */
"break", /* 0xff6b */
0, 0, 0, 0,
- 0, 0, 0, 0, "backtab", 0, 0, 0, /* 0xff70... */
- 0, 0, 0, 0, 0, 0, 0, "kp-numlock", /* 0xff78... */
+ 0, 0, 0, 0, "backtab", 0, 0, 0, /* 0xff70... */
+ 0, 0, 0, 0, 0, 0, 0, "kp-numlock", /* 0xff78... */
"kp-space", /* 0xff80 */ /* IsKeypadKey */
0, 0, 0, 0, 0, 0, 0, 0,
"kp-tab", /* 0xff89 */
static Lisp_Object button_down_location;
/* Information about the most recent up-going button event: Which
- button, what location, and what time. */
+ button, what location, and what time. */
static int last_mouse_button;
static int last_mouse_x;
static int last_mouse_y;
static Time button_down_time;
-/* The number of clicks in this multiple-click. */
+/* The number of clicks in this multiple-click. */
static int double_click_count;
if (WINDOWP (window))
{
- /* It's a click in window window at frame coordinates (x,y) */
+ /* It's a click in window WINDOW at frame coordinates (X,Y) */
struct window *w = XWINDOW (window);
Lisp_Object string_info = Qnil;
ptrdiff_t textpos = -1;
#ifdef HAVE_NS
/* NS_NONKEY_EVENTs are just like NON_ASCII_KEYSTROKE_EVENTs,
- except that they are non-key events (last-nonmenu-event is nil). */
+ except that they are non-key events (last-nonmenu-event is nil). */
case NS_NONKEY_EVENT:
#endif
|| !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
{
/* We need to use an alist rather than a vector as the cache
- since we can't make a vector long enuf. */
+ since we can't make a vector long enough. */
if (NILP (KVAR (current_kboard, system_key_syms)))
KVAR (current_kboard, system_key_syms) = Fcons (Qnil, Qnil);
return modify_event_symbol (event->code,
Fcons (make_number (event->timestamp),
Fcons (part, Qnil)))));
- /* Always treat scroll bar events as clicks. */
+ /* Always treat scroll bar events as clicks. */
event->modifiers |= click_modifier;
event->modifiers &= ~up_modifier;
If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
events (FOCUS_IN_EVENT).
If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
- movements and toolkit scroll bar thumb drags. */
+ movements and toolkit scroll bar thumb drags. */
static void
get_input_pending (int *addr, int flags)
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
if (!interrupt_input && poll_suppress_count == 0)
{
SIGMASKTYPE mask;
if (store_user_signal_events ())
expected = 0;
- /* Loop through the available terminals, and call their input hooks. */
+ /* Loop through the available terminals, and call their input hooks. */
t = terminal_list;
while (t)
{
expected = 0;
}
- if (nr == -1) /* Not OK to read input now. */
+ if (nr == -1) /* Not OK to read input now. */
{
err = 1;
}
- else if (nr == -2) /* Non-transient error. */
+ else if (nr == -2) /* Non-transient error. */
{
- /* The terminal device terminated; it should be closed. */
+ /* The terminal device terminated; it should be closed. */
- /* Kill Emacs if this was our last terminal. */
+ /* Kill Emacs if this was our last terminal. */
if (!terminal_list->next_terminal)
/* Formerly simply reported no input, but that
sometimes led to a failure of Emacs to terminate.
alone in its group. */
kill (getpid (), SIGHUP);
- /* XXX Is calling delete_terminal safe here? It calls delete_frame. */
+ /* XXX Is calling delete_terminal safe here? It calls delete_frame. */
{
Lisp_Object tmp;
XSETTERMINAL (tmp, t);
return 0;
#endif /* subprocesses */
- if (!terminal->name) /* Don't read from a dead terminal. */
+ if (!terminal->name) /* Don't read from a dead terminal. */
return 0;
if (terminal->type != output_termcap
abort ();
/* XXX I think the following code should be moved to separate hook
- functions in system-dependent files. */
+ functions in system-dependent files. */
#ifdef WINDOWSNT
return 0;
#else /* not WINDOWSNT */
- if (! tty->term_initted) /* In case we get called during bootstrap. */
+ if (! tty->term_initted) /* In case we get called during bootstrap. */
return 0;
if (! tty->input)
- return 0; /* The terminal is suspended. */
+ return 0; /* The terminal is suspended. */
#ifdef MSDOS
n_to_read = dos_keysns ();
Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
we save it in `fd' so close_gpm can remove it from the
select masks.
- gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
+ gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
while (gpm = Gpm_GetEvent (&event), gpm == 1) {
nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
}
if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
{
if (! noninteractive)
- return -2; /* Close this terminal. */
+ return -2; /* Close this terminal. */
else
n_to_read = 0;
}
process group won't get SIGHUP's at logout time. BSDI adheres to
this part standard and returns -1 from read (0) with errno==EIO
when the control tty is taken away.
- Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
+ Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
if (nread == -1 && errno == EIO)
- return -2; /* Close this terminal. */
+ return -2; /* Close this terminal. */
#if defined (AIX) && defined (_BSD)
/* The kernel sometimes fails to deliver SIGHUP for ptys.
This looks incorrect, but it isn't, because _BSD causes
O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
and that causes a value other than 0 when there is no input. */
if (nread == 0)
- return -2; /* Close this terminal. */
+ return -2; /* Close this terminal. */
#endif
}
while (
buf.code = cbuf[i];
/* Set the frame corresponding to the active tty. Note that the
value of selected_frame is not reliable here, redisplay tends
- to temporarily change it. */
+ to temporarily change it. */
buf.frame_or_window = tty->top_frame;
buf.arg = Qnil;
return nread;
}
\f
+#if defined SYNC_INPUT || defined SIGIO
static void
handle_async_input (void)
{
pending_signals = pending_atimers;
#endif
/* Tell ns_read_socket() it is being called asynchronously so it can avoid
- doing anything dangerous. */
+ doing anything dangerous. */
#ifdef HAVE_NS
++handling_signal;
#endif
--handling_signal;
#endif
}
+#endif /* SYNC_INPUT || SIGIO */
+#ifdef SYNC_INPUT
void
process_pending_signals (void)
{
handle_async_input ();
do_pending_atimers ();
}
+#endif
#ifdef SIGIO /* for entire page */
/* Note SIGIO has been undef'd if FIONREAD is missing. */
This function exists so that the UNBLOCK_INPUT macro in
blockinput.h can have some way to take care of input we put off
dealing with, without assuming that every file which uses
- UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
+ UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
void
reinvoke_input_signal (void)
{
struct user_signal_info *next;
};
-/* List of user signals. */
+/* List of user signals. */
static struct user_signal_info *user_signals = NULL;
void
{
tem = XCAR (item);
if (SYMBOLP (tem) || STRINGP (tem) || VECTORP (tem))
- /* Be GC protected. Set keyhint to item instead of tem. */
+ /* Be GC protected. Set keyhint to item instead of tem. */
keyhint = item;
}
else if (EQ (tem, QCkeys))
if (inmenubar > 0)
return 1;
- { /* This is a command. See if there is an equivalent key binding. */
+ { /* This is a command. See if there is an equivalent key binding. */
Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
/* The previous code preferred :key-sequence to :keys, so we
Lisp_Object caption;
int i, have_label = 0;
- /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'.
+ /* Definition looks like `(menu-item CAPTION BINDING PROPS...)'.
Rule out items that aren't lists, don't start with
`menu-item' or whose rest following `tool-bar-item' is not a
list. */
These are done in different ways, depending on how the input will be read.
Menus using X are done after auto-saving in read-char, getting the input
event from Fx_popup_menu; menus using the minibuf use read_char recursively
- and do auto-saving in the inner call of read_char. */
+ and do auto-saving in the inner call of read_char. */
static Lisp_Object
read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
tem
= XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
if (!NILP (tem))
- /* Insert equivalent keybinding. */
+ /* Insert equivalent keybinding. */
s = concat2 (s, tem);
#endif
tem
= XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
{
- /* Insert button prefix. */
+ /* Insert button prefix. */
Lisp_Object selected
= XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
if (EQ (tem, QCradio))
/* Positions [START, END) in the key sequence buffer
are the key that we have scanned so far.
Those events are the ones that we will replace
- if PAREHT maps them into a key sequence. */
+ if PARENT maps them into a key sequence. */
int start, end;
} keyremap;
/* If keybuf[fkey->start..fkey->end] is bound in the
map and we're in a position to do the key remapping, replace it with
- the binding and restart with fkey->start at the end. */
+ the binding and restart with fkey->start at the end. */
if ((VECTORP (next) || STRINGP (next)) && doit)
{
int len = XFASTINT (Flength (next));
/* Non-zero if we are trying to map a key by changing an upper-case
letter to lower case, or a shifted function key to an unshifted
- one. */
+ one. */
int shift_translated = 0;
/* If we receive a `switch-frame' or `select-window' event in the middle of
While we're reading, we keep the event here. */
Lisp_Object delayed_switch_frame;
- /* See the comment below... */
+ /* See the comment below... */
#if defined (GOBBLE_FIRST_EVENT)
Lisp_Object first_event;
#endif
int junk;
#endif
- struct gcpro outer_gcpro1;
+ struct gcpro gcpro1;
- GCPRO1_VAR (fake_prefixed_keys, outer_gcpro);
+ GCPRO1 (fake_prefixed_keys);
raw_keybuf_count = 0;
last_nonmenu_event = Qnil;
if (!found)
{
/* Don't touch interrupted_kboard when it's been
- deleted. */
+ deleted. */
delayed_switch_frame = Qnil;
goto replay_entire_sequence;
}
if (EQ (key, Qt))
{
unbind_to (count, Qnil);
- UNGCPRO_VAR (outer_gcpro);
+ UNGCPRO;
return -1;
}
{
/* If we're at the beginning of a key sequence, and the caller
says it's okay, go ahead and return this event. If we're
- in the midst of a key sequence, delay it until the end. */
+ in the midst of a key sequence, delay it until the end. */
if (t > 0 || !can_return_switch_frame)
{
delayed_switch_frame = key;
Down-clicks are eliminated.
Double-downs reduce to downs, then are eliminated.
Triple-downs reduce to double-downs, then to downs,
- then are eliminated. */
+ then are eliminated. */
if (modifiers & (down_modifier | drag_modifier
| double_modifier | triple_modifier))
{
add_command_key (keybuf[t]);
}
- UNGCPRO_VAR (outer_gcpro);
+ UNGCPRO;
return t;
}
! NILP (can_return_switch_frame), 0);
#if 0 /* The following is fine for code reading a key sequence and
- then proceeding with a lenghty computation, but it's not good
+ then proceeding with a lengthy computation, but it's not good
for code reading keys in a loop, like an input method. */
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
memset (keybuf, 0, sizeof keybuf);
GCPRO1 (keybuf[0]);
- gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
+ gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0]));
if (NILP (continue_echo))
{
cancel_hourglass ();
#endif
- i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
+ i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), 0);
\f
-DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
- 1, 1, "P",
- doc: /* Read function name, then read its arguments and call it.
-
-To pass a numeric argument to the command you are invoking with, specify
-the numeric argument to this command.
-
-Noninteractively, the argument PREFIXARG is the prefix argument to
-give to the command you invoke, if it asks for an argument. */)
- (Lisp_Object prefixarg)
-{
- Lisp_Object function;
- ptrdiff_t saved_last_point_position;
- Lisp_Object saved_keys, saved_last_point_position_buffer;
- Lisp_Object bindings, value;
- struct gcpro gcpro1, gcpro2, gcpro3;
-#ifdef HAVE_WINDOW_SYSTEM
- /* The call to Fcompleting_read will start and cancel the hourglass,
- but if the hourglass was already scheduled, this means that no
- hourglass will be shown for the actual M-x command itself.
- So we restart it if it is already scheduled. Note that checking
- hourglass_shown_p is not enough, normally the hourglass is not shown,
- just scheduled to be shown. */
- int hstarted = hourglass_started ();
-#endif
-
- saved_keys = Fvector (this_command_key_count,
- XVECTOR (this_command_keys)->contents);
- saved_last_point_position_buffer = last_point_position_buffer;
- saved_last_point_position = last_point_position;
- GCPRO3 (saved_keys, prefixarg, saved_last_point_position_buffer);
-
- function = call0 (intern ("read-extended-command"));
-
-#ifdef HAVE_WINDOW_SYSTEM
- if (hstarted) start_hourglass ();
-#endif
-
- if (STRINGP (function) && SCHARS (function) == 0)
- error ("No command name given");
-
- /* Set this_command_keys to the concatenation of saved_keys and
- function, followed by a RET. */
- {
- Lisp_Object *keys;
- int i;
-
- this_command_key_count = 0;
- this_command_key_count_reset = 0;
- this_single_command_key_start = 0;
-
- keys = XVECTOR (saved_keys)->contents;
- for (i = 0; i < ASIZE (saved_keys); i++)
- add_command_key (keys[i]);
-
- for (i = 0; i < SCHARS (function); i++)
- add_command_key (Faref (function, make_number (i)));
-
- add_command_key (make_number ('\015'));
- }
-
- last_point_position = saved_last_point_position;
- last_point_position_buffer = saved_last_point_position_buffer;
-
- UNGCPRO;
-
- function = Fintern (function, Qnil);
- KVAR (current_kboard, Vprefix_arg) = prefixarg;
- Vthis_command = function;
- real_this_command = function;
-
- /* If enabled, show which key runs this command. */
- if (!NILP (Vsuggest_key_bindings)
- && NILP (Vexecuting_kbd_macro)
- && SYMBOLP (function))
- bindings = Fwhere_is_internal (function, Voverriding_local_map,
- Qt, Qnil, Qnil);
- else
- bindings = Qnil;
-
- value = Qnil;
- GCPRO3 (bindings, value, function);
- value = Fcommand_execute (function, Qt, Qnil, Qnil);
-
- /* If the command has a key binding, print it now. */
- if (!NILP (bindings)
- && ! (VECTORP (bindings) && EQ (Faref (bindings, make_number (0)),
- Qmouse_movement)))
- {
- /* But first wait, and skip the message if there is input. */
- Lisp_Object waited;
-
- /* If this command displayed something in the echo area;
- wait a few seconds, then display our suggestion message. */
- if (NILP (echo_area_buffer[0]))
- waited = sit_for (make_number (0), 0, 2);
- else if (NUMBERP (Vsuggest_key_bindings))
- waited = sit_for (Vsuggest_key_bindings, 0, 2);
- else
- waited = sit_for (make_number (2), 0, 2);
-
- if (!NILP (waited) && ! CONSP (Vunread_command_events))
- {
- Lisp_Object binding;
- char *newmessage;
- int message_p = push_message ();
- ptrdiff_t count = SPECPDL_INDEX ();
- ptrdiff_t newmessage_len, newmessage_alloc;
- USE_SAFE_ALLOCA;
-
- record_unwind_protect (pop_message_unwind, Qnil);
- binding = Fkey_description (bindings, Qnil);
- newmessage_alloc =
- (sizeof "You can run the command `' with "
- + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
- SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
- newmessage_len =
- esprintf (newmessage, "You can run the command `%s' with %s",
- SDATA (SYMBOL_NAME (function)),
- SDATA (binding));
- message2 (newmessage,
- newmessage_len,
- STRING_MULTIBYTE (binding));
- if (NUMBERP (Vsuggest_key_bindings))
- waited = sit_for (Vsuggest_key_bindings, 0, 2);
- else
- waited = sit_for (make_number (2), 0, 2);
-
- if (!NILP (waited) && message_p)
- restore_message ();
-
- SAFE_FREE ();
- unbind_to (count, Qnil);
- }
- }
-
- RETURN_UNGCPRO (value);
-}
-
-\f
/* Return nonzero if input events are pending. */
int
|| !NILP (Vunread_input_method_events))
return (Qt);
+ /* Process non-user-visible events (Bug#10195). */
+ process_special_events ();
+
get_input_pending (&input_pending,
READABLE_EVENTS_DO_TIMERS_NOW
| READABLE_EVENTS_FILTER_EVENTS);
waiting_for_input = 1;
/* If handle_interrupt was called before and buffered a C-g,
- make it run again now, to avoid timing error. */
+ make it run again now, to avoid timing error. */
if (!NILP (Vquit_flag))
- quit_throw_to_read_char ();
+ quit_throw_to_read_char (0);
}
void
If we have a frame on the controlling tty, we assume that the
SIGINT was generated by C-g, so we call handle_interrupt.
- Otherwise, the handler kills Emacs. */
+ Otherwise, tell QUIT to kill Emacs. */
static void
interrupt_signal (int signalnum) /* If we don't have an argument, some */
- /* compilers complain in signal calls. */
+ /* compilers complain in signal calls. */
{
/* Must preserve main program's value of errno. */
int old_errno = errno;
SIGNAL_THREAD_CHECK (signalnum);
- /* See if we have an active terminal on our controlling tty. */
+ /* See if we have an active terminal on our controlling tty. */
terminal = get_named_tty ("/dev/tty");
if (!terminal)
{
/* If there are no frames there, let's pretend that we are a
- well-behaving UN*X program and quit. */
- Fkill_emacs (Qnil);
+ well-behaving UN*X program and quit. We must not call Lisp
+ in a signal handler, so tell QUIT to exit when it is
+ safe. */
+ Vquit_flag = Qkill_emacs;
}
else
{
errno = old_errno;
}
+/* If Emacs is stuck because `inhibit-quit' is true, then keep track
+ of the number of times C-g has been requested. If C-g is pressed
+ enough times, then quit anyway. See bug#6585. */
+static int force_quit_count;
+
/* This routine is called at interrupt level in response to C-g.
It is called from the SIGINT handler or kbd_buffer_store_event.
Otherwise it sets the Lisp variable quit-flag not-nil. This causes
eval to throw, when it gets a chance. If quit-flag is already
- non-nil, it stops the job right away. */
+ non-nil, it stops the job right away. */
static void
handle_interrupt (void)
cancel_echoing ();
- /* XXX This code needs to be revised for multi-tty support. */
+ /* XXX This code needs to be revised for multi-tty support. */
if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty"))
{
/* If SIGINT isn't blocked, don't let us be interrupted by
UNGCPRO;
}
else
- /* Else request quit when it's safe */
- Vquit_flag = Qt;
+ { /* Else request quit when it's safe. */
+ if (NILP (Vquit_flag))
+ force_quit_count = 0;
+ if (++force_quit_count == 3)
+ {
+ immediate_quit = 1;
+ Vinhibit_quit = Qnil;
+ }
+ Vquit_flag = Qt;
+ }
}
/* TODO: The longjmp in this call throws the NS event loop integration off,
wait_reading_process_output() under HAVE_NS because of the call
to ns_select there (needed because otherwise events aren't picked up
outside of polling since we don't get SIGIO like X and we don't have a
- separate event loop thread like W32. */
+ separate event loop thread like W32. */
#ifndef HAVE_NS
if (waiting_for_input && !echoing)
- quit_throw_to_read_char ();
+ quit_throw_to_read_char (1);
#endif
}
/* Handle a C-g by making read_char return C-g. */
static void
-quit_throw_to_read_char (void)
+quit_throw_to_read_char (int from_signal)
{
+ /* When not called from a signal handler it is safe to call
+ Lisp. */
+ if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
+ Fkill_emacs (Qnil);
+
sigfree ();
/* Prevent another signal from doing this before we finish. */
clear_waiting_for_input ();
session may have multiple display types, so we always handle
SIGINT. There is special code in interrupt_signal to exit
Emacs on SIGINT when there are no termcap frames on the
- controlling terminal. */
+ controlling terminal. */
signal (SIGINT, interrupt_signal);
#ifndef DOS_NT
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
staticpro (&tool_bar_items_vector);
tool_bar_items_vector = Qnil;
- staticpro (&real_this_command);
- real_this_command = Qnil;
-
DEFSYM (Qtimer_event_handler, "timer-event-handler");
DEFSYM (Qdisabled_command_function, "disabled-command-function");
DEFSYM (Qself_insert_command, "self-insert-command");
DEFSYM (Qx_set_selection, "x-set-selection");
DEFSYM (QPRIMARY, "PRIMARY");
DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
+ DEFSYM (Qhandle_select_window, "handle-select-window");
DEFSYM (Qinput_method_function, "input-method-function");
DEFSYM (Qinput_method_exit_on_first_char, "input-method-exit-on-first-char");
defsubr (&Sset_quit_char);
defsubr (&Sset_input_mode);
defsubr (&Scurrent_input_mode);
- defsubr (&Sexecute_extended_command);
defsubr (&Sposn_at_point);
defsubr (&Sposn_at_x_y);
See Info node `(elisp)Multiple Terminals'. */);
DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
- doc: /* Same as `last-command', but never altered by Lisp code. */);
+ doc: /* Same as `last-command', but never altered by Lisp code.
+Taken from the previous value of `real-this-command'. */);
DEFVAR_KBOARD ("last-repeatable-command", Vlast_repeatable_command,
doc: /* Last command that may be repeated.
The last command executed that was not bound to an input event.
-This is the command `repeat' will try to repeat. */);
+This is the command `repeat' will try to repeat.
+Taken from a previous value of `real-this-command'. */);
DEFVAR_LISP ("this-command", Vthis_command,
doc: /* The command now being executed.
will be in `last-command' during the following command. */);
Vthis_command = Qnil;
+ DEFVAR_LISP ("real-this-command", Vreal_this_command,
+ doc: /* This is like `this-command', except that commands should never modify it. */);
+ Vreal_this_command = Qnil;
+
DEFVAR_LISP ("this-command-keys-shift-translated",
Vthis_command_keys_shift_translated,
doc: /* Non-nil if the key sequence activating this command was shift-translated.
Vthis_original_command = Qnil;
DEFVAR_INT ("auto-save-interval", auto_save_interval,
- doc: /* *Number of input events between auto-saves.
+ doc: /* Number of input events between auto-saves.
Zero means disable autosaving due to number of characters typed. */);
auto_save_interval = 300;
DEFVAR_LISP ("auto-save-timeout", Vauto_save_timeout,
- doc: /* *Number of seconds idle time before auto-save.
+ doc: /* Number of seconds idle time before auto-save.
Zero or nil means disable auto-saving due to idleness.
After auto-saving due to this many seconds of idle time,
Emacs also does a garbage collection if that seems to be warranted. */);
XSETFASTINT (Vauto_save_timeout, 30);
DEFVAR_LISP ("echo-keystrokes", Vecho_keystrokes,
- doc: /* *Nonzero means echo unfinished commands after this many seconds of pause.
-The value may be integer or floating point. */);
+ doc: /* Nonzero means echo unfinished commands after this many seconds of pause.
+The value may be integer or floating point.
+If the value is zero, don't echo at all. */);
Vecho_keystrokes = make_number (1);
DEFVAR_INT ("polling-period", polling_period,
- doc: /* *Interval between polling for input during Lisp execution.
+ doc: /* Interval between polling for input during Lisp execution.
The reason for polling is to make C-g work to stop a running program.
Polling is needed only when using X windows and SIGIO does not work.
Polling is automatically disabled in all other cases. */);
polling_period = 2;
DEFVAR_LISP ("double-click-time", Vdouble_click_time,
- doc: /* *Maximum time between mouse clicks to make a double-click.
+ doc: /* Maximum time between mouse clicks to make a double-click.
Measured in milliseconds. The value nil means disable double-click
recognition; t means double-clicks have no time limit and are detected
by position only. */);
Vdouble_click_time = make_number (500);
DEFVAR_INT ("double-click-fuzz", double_click_fuzz,
- doc: /* *Maximum mouse movement between clicks to make a double-click.
+ doc: /* Maximum mouse movement between clicks to make a double-click.
On window-system frames, value is the number of pixels the mouse may have
moved horizontally or vertically between two clicks to make a double-click.
On non window-system frames, value is interpreted in units of 1/8 characters
double_click_fuzz = 3;
DEFVAR_BOOL ("inhibit-local-menu-bar-menus", inhibit_local_menu_bar_menus,
- doc: /* *Non-nil means inhibit local map menu bar menus. */);
+ doc: /* Non-nil means inhibit local map menu bar menus. */);
inhibit_local_menu_bar_menus = 0;
DEFVAR_INT ("num-input-keys", num_input_keys,
Vspecial_event_map = Fcons (intern_c_string ("keymap"), Qnil);
DEFVAR_LISP ("track-mouse", do_mouse_tracking,
- doc: /* *Non-nil means generate motion events for mouse motion. */);
+ doc: /* Non-nil means generate motion events for mouse motion. */);
DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist,
doc: /* Alist of system-specific X windows key symbols.
Function key definitions that apply to all terminal devices should go
here. If a mapping is defined in both the current
`local-function-key-map' binding and this variable, then the local
-definition will take precendence. */);
+definition will take precedence. */);
Vfunction_key_map = Fmake_sparse_keymap (Qnil);
DEFVAR_LISP ("key-translation-map", Vkey_translation_map,
Vdeferred_action_function = Qnil;
DEFVAR_LISP ("delayed-warnings-list", Vdelayed_warnings_list,
- doc: /* List of warnings to be displayed as soon as possible.
+ doc: /* List of warnings to be displayed after this command.
Each element must be a list (TYPE MESSAGE [LEVEL [BUFFER-NAME]]),
as per the args of `display-warning' (which see).
If this variable is non-nil, `delayed-warnings-hook' will be run
immediately after running `post-command-hook'. */);
Vdelayed_warnings_list = Qnil;
- DEFVAR_LISP ("suggest-key-bindings", Vsuggest_key_bindings,
- doc: /* *Non-nil means show the equivalent key-binding when M-x command has one.
-The value can be a length of time to show the message for.
-If the value is non-nil and not a number, we wait 2 seconds. */);
- Vsuggest_key_bindings = Qt;
-
DEFVAR_LISP ("timer-list", Vtimer_list,
doc: /* List of active absolute time timers in order of increasing time. */);
Vtimer_list = Qnil;
DEFVAR_LISP ("global-disable-point-adjustment",
Vglobal_disable_point_adjustment,
- doc: /* *If non-nil, always suppress point adjustment.
+ doc: /* If non-nil, always suppress point adjustment.
The default value is nil, in which case, point adjustment are
suppressed only after special commands that set
Vglobal_disable_point_adjustment = Qnil;
DEFVAR_LISP ("minibuffer-message-timeout", Vminibuffer_message_timeout,
- doc: /* *How long to display an echo-area message when the minibuffer is active.
+ doc: /* How long to display an echo-area message when the minibuffer is active.
If the value is not a number, such messages don't time out. */);
Vminibuffer_message_timeout = make_number (2);
`deactivate-mark' call uses this to set the window selection. */);
Vsaved_region_selection = Qnil;
+ DEFVAR_LISP ("selection-inhibit-update-commands",
+ Vselection_inhibit_update_commands,
+ doc: /* List of commands which should not update the selection.
+Normally, if `select-active-regions' is non-nil and the mark remains
+active after a command (i.e. the mark was not deactivated), the Emacs
+command loop sets the selection to the text in the region. However,
+if the command is in this list, the selection is not updated. */);
+ Vselection_inhibit_update_commands
+ = list2 (Qhandle_switch_frame, Qhandle_select_window);
+
DEFVAR_LISP ("debug-on-event",
Vdebug_on_event,
doc: /* Enter debugger on this event. When Emacs
-receives the special event specifed by this variable, it will try to
+receives the special event specified by this variable, it will try to
break into the debugger as soon as possible instead of processing the
event normally through `special-event-map'.
variable are `sigusr1' and `sigusr2'. */);
Vdebug_on_event = intern_c_string ("sigusr2");
- /* Create the initial keyboard. */
+ /* Create the initial keyboard. */
initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (initial_kboard);
/* Vwindow_system is left at t for now. */
}
/* Mark the pointers in the kboard objects.
- Called by the Fgarbage_collector. */
+ Called by Fgarbage_collect. */
void
mark_kboards (void)
{