/* 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.
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;
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. */
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)
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;
? 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;
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.
{
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. */
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 */
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;
|| !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,
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. */
/* 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;
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 (EQ (key, Qt))
{
unbind_to (count, Qnil);
- UNGCPRO_VAR (outer_gcpro);
+ UNGCPRO;
return -1;
}
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);
/* If handle_interrupt was called before and buffered a C-g,
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 */
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
{
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 ();
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");
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'.