/* 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 "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;
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;
/* read_key_sequence stores here the command definition of the
key sequence that it reads. */
static Lisp_Object read_key_sequence_cmd;
+static Lisp_Object read_key_sequence_remapped;
static Lisp_Object Qinput_method_function;
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;
/* If we support a window system, turn on the code to poll periodically
to detect C-g. It isn't actually used when doing interrupt input. */
-#if defined(HAVE_WINDOW_SYSTEM) && !defined(USE_ASYNC_EVENTS)
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_ASYNC_EVENTS)
#define POLL_FOR_INPUT
#endif
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);
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 */
+ /* Remap command through active keymaps. */
Vthis_original_command = cmd;
- if (SYMBOLP (cmd))
- {
- Lisp_Object cmd1;
- if (cmd1 = Fcommand_remapping (cmd, Qnil, Qnil), !NILP (cmd1))
- cmd = cmd1;
- }
+ if (!NILP (read_key_sequence_remapped))
+ cmd = read_key_sequence_remapped;
/* Execute the command. */
}
else
{
- /* Here for a command that isn't executed directly */
+ /* Here for a command that isn't executed directly. */
#ifdef HAVE_WINDOW_SYSTEM
int scount = SPECPDL_INDEX ();
? 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)))
{
EMACS_INT 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)
{
Lisp_Object keys;
int key_count, key_count_reset;
- struct gcpro inner_gcpro1;
+ struct gcpro gcpro1;
int 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))
/* 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. */
kbd_fetch_ptr = event + 1;
}
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK)
else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
{
kbd_fetch_ptr = event + 1;
obj = make_lispy_event (event);
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK)
/* If this was a menu selection, then set the flag to inhibit
writing to last_nonmenu_event. Don't do this if the event
we're returning is (menu-bar), though; that indicates the
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;
EMACS_INT 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;
#endif /* HAVE_MOUSE */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK)
case MENU_BAR_EVENT:
if (EQ (event->arg, event->frame_or_window))
/* This is the prefix key. We translate this to
}
}
-#if defined(HAVE_MOUSE) || defined(HAVE_GPM)
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object
make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
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;
}
if (n_to_read > sizeof cbuf)
n_to_read = sizeof cbuf;
#else /* no FIONREAD */
-#if defined (USG) || defined(CYGWIN)
+#if defined (USG) || defined (CYGWIN)
/* Read some input if available, but don't wait. */
n_to_read = sizeof cbuf;
fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
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;
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
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));
return 0;
}
+static int
+test_undefined (Lisp_Object binding)
+{
+ return (EQ (binding, Qundefined)
+ || (!NILP (binding) && SYMBOLP (binding)
+ && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
+}
+
/* Read a sequence of keys that ends with a non prefix character,
storing it in KEYBUF, a buffer of size BUFSIZE.
Prompt with PROMPT.
/* 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))
{
}
}
- if (first_binding < nmaps && NILP (submaps[first_binding])
+ if (first_binding < nmaps
+ && NILP (submaps[first_binding])
+ && !test_undefined (defs[first_binding])
&& indec.start >= t)
/* There is a binding and it's not a prefix.
(and it doesn't have any input-decode-map translation pending).
/* If there's a binding (i.e.
first_binding >= nmaps) we don't want
to apply this function-key-mapping. */
- fkey.end + 1 == t && first_binding >= nmaps,
+ fkey.end + 1 == t
+ && (first_binding >= nmaps
+ || test_undefined (defs[first_binding])),
&diff, prompt);
UNGCPRO;
if (done)
read_key_sequence_cmd = (first_binding < nmaps
? defs[first_binding]
: Qnil);
+ read_key_sequence_remapped
+ /* Remap command through active keymaps.
+ Do the remapping here, before the unbind_to so it uses the keymaps
+ of the appropriate buffer. */
+ = SYMBOLP (read_key_sequence_cmd)
+ ? Fcommand_remapping (read_key_sequence_cmd, Qnil, Qnil)
+ : Qnil;
unread_switch_frame = delayed_switch_frame;
unbind_to (count, Qnil);
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)
|| !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
{
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
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
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");
read_key_sequence_cmd = Qnil;
staticpro (&read_key_sequence_cmd);
+ read_key_sequence_remapped = Qnil;
+ staticpro (&read_key_sequence_remapped);
menu_bar_one_keymap_changed_items = Qnil;
staticpro (&menu_bar_one_keymap_changed_items);
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
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.
+ 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 ("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. */