/* 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"
actually mean something.
It's easier to staticpro a single Lisp_Object than an array. */
Lisp_Object this_command_keys;
-int this_command_key_count;
+ptrdiff_t this_command_key_count;
/* 1 after calling Freset_this_command_lengths.
Usually it is 0. */
#define GROW_RAW_KEYBUF \
if (raw_keybuf_count == ASIZE (raw_keybuf)) \
- raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil) \
+ raw_keybuf = larger_vector (raw_keybuf, 1, -1)
/* Number of elements of this_command_keys
that precede this key sequence. */
-static int this_single_command_key_start;
+static ptrdiff_t this_single_command_key_start;
/* Record values of this_command_key_count and echo_length ()
before this command was read. */
-static int before_command_key_count;
-static int before_command_echo_length;
+static ptrdiff_t before_command_key_count;
+static ptrdiff_t before_command_echo_length;
/* For longjmp to where kbd input is being done. */
Lisp_Object unread_switch_frame;
/* Last size recorded for a current buffer which is not a minibuffer. */
-static EMACS_INT last_non_minibuf_size;
+static ptrdiff_t last_non_minibuf_size;
/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */
uintmax_t num_input_events;
/* Value of num_nonmacro_input_events as of last auto save. */
-static int last_auto_save;
-
-/* This is like Vthis_command, except that commands never set it. */
-Lisp_Object real_this_command;
+static EMACS_INT last_auto_save;
/* The value of point when the last command was started. */
-static EMACS_INT last_point_position;
+static ptrdiff_t last_point_position;
/* The buffer that was current when the last command was started. */
static Lisp_Object last_point_position_buffer;
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 void record_menu_key (Lisp_Object c);
static void echo_now (void);
-static int echo_length (void);
+static ptrdiff_t echo_length (void);
static Lisp_Object Qpolling_period;
Lisp_Object, Lisp_Object,
Time);
#endif
-static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object,
+static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object,
Lisp_Object, const char *const *,
- Lisp_Object *, EMACS_INT);
+ Lisp_Object *, ptrdiff_t);
static Lisp_Object make_lispy_switch_frame (Lisp_Object);
static int help_char_p (Lisp_Object);
static void save_getcjmp (jmp_buf);
#ifdef SIGIO
static void input_available_signal (int signo);
#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 _Noreturn void quit_throw_to_read_char (int);
+static void process_special_events (void);
static void timer_start_idle (void);
static void timer_stop_idle (void);
static void timer_resume_idle (void);
{
if (!current_kboard->immediate_echo)
{
- int i;
+ ptrdiff_t i;
current_kboard->immediate_echo = 1;
for (i = 0; i < this_command_key_count; i++)
if (i == this_single_command_key_start)
before_command_echo_length = echo_length ();
- c = XVECTOR (this_command_keys)->contents[i];
+ c = AREF (this_command_keys, i);
if (! (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
echo_char (c);
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. */
/* Return the length of the current echo string. */
-static int
+static ptrdiff_t
echo_length (void)
{
return (STRINGP (KVAR (current_kboard, echo_string))
switches frames while entering a key sequence. */
static void
-echo_truncate (EMACS_INT nchars)
+echo_truncate (ptrdiff_t nchars)
{
if (STRINGP (KVAR (current_kboard, echo_string)))
KVAR (current_kboard, echo_string)
#endif
if (this_command_key_count >= ASIZE (this_command_keys))
- this_command_keys = larger_vector (this_command_keys,
- 2 * ASIZE (this_command_keys),
- Qnil);
+ this_command_keys = larger_vector (this_command_keys, 1, -1);
ASET (this_command_keys, this_command_key_count, key);
++this_command_key_count;
Lisp_Object
recursive_edit_1 (void)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
if (command_loop_level > 0)
This function is called by the editor initialization to begin editing. */)
(void)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object buffer;
/* If we enter while input is blocked, don't lock up here.
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;
Fthrow (Qtop_level, Qnil);
}
-static Lisp_Object Fexit_recursive_edit (void) NO_RETURN;
+static _Noreturn void
+user_error (const char *msg)
+{
+ xsignal1 (Quser_error, build_string (msg));
+}
+
+_Noreturn
DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
doc: /* Exit from the innermost recursive edit or minibuffer. */)
(void)
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;
+_Noreturn
DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
doc: /* Abort the command that requested this recursive edit or minibuffer input. */)
(void)
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)
usage: (track-mouse BODY...) */)
(Lisp_Object args)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
record_unwind_protect (tracking_off, do_mouse_tracking);
static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
int, int, int);
void safe_run_hooks (Lisp_Object);
-static void adjust_point_for_property (EMACS_INT, int);
+static void adjust_point_for_property (ptrdiff_t, int);
/* Cancel hourglass from protect_unwind.
ARG is not used. */
/* FIXME: This is wrong rather than test window-system, we should call
a new set-selection, which will then dispatch to x-set-selection, or
tty-set-selection, or w32-set-selection, ... */
-EXFUN (Fwindow_system, 1);
Lisp_Object
command_loop_1 (void)
Lisp_Object cmd;
Lisp_Object keybuf[30];
int i;
- int prev_modiff = 0;
+ EMACS_INT prev_modiff = 0;
struct buffer *prev_buffer = NULL;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
int was_locked = single_kboard;
/* 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)
{
{
/* Bind inhibit-quit to t so that C-g gets read in
rather than quitting back to the minibuffer. */
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, Qt);
sit_for (Vminibuffer_message_timeout, 0, 2);
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;
}
/* Execute the command. */
Vthis_command = cmd;
- real_this_command = cmd;
+ Vreal_this_command = cmd;
safe_run_hooks (Qpre_command_hook);
already_adjusted = 0;
/* Here for a command that isn't executed directly. */
#ifdef HAVE_WINDOW_SYSTEM
- int scount = SPECPDL_INDEX ();
+ ptrdiff_t scount = SPECPDL_INDEX ();
if (display_hourglass_p
&& NILP (Vexecuting_kbd_macro))
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)))
{
- EMACS_INT beg =
+ ptrdiff_t beg =
XINT (Fmarker_position (BVAR (current_buffer, mark)));
- EMACS_INT end = PT;
+ ptrdiff_t end = PT;
if (beg < end)
call2 (Qx_set_selection, QPRIMARY,
make_buffer_string (beg, end, 0));
LAST_PT is the last position of point. */
static void
-adjust_point_for_property (EMACS_INT last_pt, int modified)
+adjust_point_for_property (ptrdiff_t last_pt, int modified)
{
- EMACS_INT beg, end;
+ ptrdiff_t beg, end;
Lisp_Object val, overlay, tmp;
/* When called after buffer modification, we should temporarily
suppress the point adjustment for automatic composition so that a
user can keep inserting another character at point or keep
deleting characters around point. */
int check_composition = ! modified, check_display = 1, check_invisible = 1;
- EMACS_INT orig_pt = PT;
+ ptrdiff_t orig_pt = PT;
/* FIXME: cycling is probably not necessary because these properties
can't be usefully combined anyway. */
&& (beg < PT /* && end > PT <- It's always the case. */
|| (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
{
- xassert (end > PT);
+ eassert (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;
}
#if 0 /* This assertion isn't correct, because SET_PT may end up setting
the point to something other than its argument, due to
point-motion hooks, intangibility, etc. */
- xassert (PT == beg || PT == end);
+ eassert (PT == beg || PT == end);
#endif
/* Pretend the area doesn't exist if the buffer is not
= 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;
/* FIXME: our `internal_condition_case' does not provide any way to pass data
to its body or to its handlers other than via globals such as
dynamically-bound variables ;-) */
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, hook);
run_hook_with_args (1, &hook, safe_run_hook_funcall);
if (poll_timer == NULL
|| EMACS_SECS (poll_timer->interval) != polling_period)
{
+ time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
EMACS_TIME interval;
if (poll_timer)
cancel_atimer (poll_timer);
- EMACS_SET_SECS_USECS (interval, polling_period, 0);
+ EMACS_SET_SECS_USECS (interval, period, 0);
poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
poll_for_input, NULL);
}
bind_polling_period (int n)
{
#ifdef POLL_FOR_INPUT
- int new = polling_period;
+ EMACS_INT new = polling_period;
if (n > new)
new = n;
/* Input of single characters from keyboard */
static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
- struct timeval *end_time);
+ EMACS_TIME *end_time);
static void record_char (Lisp_Object c);
static Lisp_Object help_form_saved_window_configs;
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
read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
Lisp_Object prev_event,
- int *used_mouse_menu, struct timeval *end_time)
+ int *used_mouse_menu, EMACS_TIME *end_time)
{
volatile Lisp_Object c;
- int jmpcount;
+ ptrdiff_t jmpcount;
jmp_buf local_getcjmp;
jmp_buf save_jump;
volatile int key_already_recorded = 0;
if (INTERACTIVE && NILP (c))
{
int delay_level;
- EMACS_INT buffer_size;
+ ptrdiff_t buffer_size;
/* Slow down auto saves logarithmically in size of current buffer,
and garbage collect while we're at it. */
&& XINT (Vauto_save_timeout) > 0)
{
Lisp_Object tem0;
- int timeout = delay_level * XFASTINT (Vauto_save_timeout) / 4;
-
+ EMACS_INT timeout = (delay_level
+ * min (XFASTINT (Vauto_save_timeout) / 4,
+ MOST_POSITIVE_FIXNUM / delay_level));
save_getcjmp (save_jump);
restore_getcjmp (local_getcjmp);
tem0 = sit_for (make_number (timeout), 1, 1);
struct buffer *prev_buffer = current_buffer;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
int was_locked = single_kboard;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
record_single_kboard_state ();
#endif
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:
&& ' ' <= XINT (c) && XINT (c) < 256 && XINT (c) != 127)
{
Lisp_Object keys;
- int key_count, key_count_reset;
- struct gcpro inner_gcpro1;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t key_count;
+ int key_count_reset;
+ struct gcpro gcpro1;
+ ptrdiff_t count = SPECPDL_INDEX ();
/* Save the echo status. */
int saved_immediate_echo = current_kboard->immediate_echo;
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))
/* Process the help character specially if enabled */
if (!NILP (Vhelp_form) && help_char_p (c))
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
help_form_saved_window_configs
= Fcons (Fcurrent_window_configuration (Qnil),
if (!recorded)
{
- total_keys++;
+ total_keys += total_keys < NUM_RECENT_KEYS;
ASET (recent_keys, recent_keys_index, c);
if (++recent_keys_index >= NUM_RECENT_KEYS)
recent_keys_index = 0;
void
gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
- Lisp_Object object, EMACS_INT pos)
+ Lisp_Object object, ptrdiff_t pos)
{
struct input_event event;
static Lisp_Object
kbd_buffer_get_event (KBOARD **kbp,
int *used_mouse_menu,
- struct timeval *end_time)
+ EMACS_TIME *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. */
EMACS_TIME duration;
EMACS_GET_TIME (duration);
if (EMACS_TIME_GE (duration, *end_time))
- return Qnil; /* finished waiting */
+ return Qnil; /* Finished waiting. */
else
{
EMACS_SUB_TIME (duration, *end_time, duration);
- wait_reading_process_output (EMACS_SECS (duration),
- EMACS_USECS (duration),
+ wait_reading_process_output (min (EMACS_SECS (duration),
+ WAIT_READING_MAX),
+ EMACS_NSECS (duration),
-1, 1, Qnil, NULL, 0);
}
}
#if defined (WINDOWSNT)
else if (event->kind == LANGUAGE_CHANGE_EVENT)
{
- /* Make an event (language-change (FRAME CHARSET LCID)). */
- obj = Fcons (event->frame_or_window, Qnil);
- obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
+ /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */
+ obj = Fcons (Qlanguage_change,
+ list3 (event->frame_or_window,
+ make_number (event->code),
+ make_number (event->modifiers)));
kbd_fetch_ptr = event + 1;
}
#endif
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);
Lisp_Object timers;
/* If we are already in the idle state, do nothing. */
- if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+ if (EMACS_TIME_VALID_P (timer_idleness_start_time))
return;
EMACS_GET_TIME (timer_idleness_start_time);
timer = XCAR (timers);
- if (!VECTORP (timer) || ASIZE (timer) != 8)
+ if (!VECTORP (timer) || ASIZE (timer) != 9)
continue;
- XVECTOR (timer)->contents[0] = Qnil;
+ ASET (timer, 0, Qnil);
}
}
static void
timer_stop_idle (void)
{
- EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
+ EMACS_SET_INVALID_TIME (timer_idleness_start_time);
}
/* Resume idle timer from last idle start time. */
static void
timer_resume_idle (void)
{
- if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+ if (EMACS_TIME_VALID_P (timer_idleness_start_time))
return;
timer_idleness_start_time = timer_last_idleness_start_time;
...). Each element has the form (FUN . ARGS). */
Lisp_Object pending_funcalls;
+/* If TIMER is a valid timer, return nonzero and place its value into
+ *RESULT. Otherwise return zero. */
+static int
+decode_timer (Lisp_Object timer, EMACS_TIME *result)
+{
+ Lisp_Object *vector;
+
+ if (! (VECTORP (timer) && ASIZE (timer) == 9))
+ return 0;
+ vector = XVECTOR (timer)->contents;
+ if (! NILP (vector[0]))
+ return 0;
+
+ return decode_time_components (vector[1], vector[2], vector[3], vector[4],
+ result, 0);
+}
+
+
/* Check whether a timer has fired. To prevent larger problems we simply
disregard elements that are not proper timers. Do not make a circular
timer list for the time being.
{
EMACS_TIME nexttime;
EMACS_TIME now;
- EMACS_TIME idleness_now IF_LINT (= {0});
+ EMACS_TIME idleness_now;
Lisp_Object timers, idle_timers, chosen_timer;
struct gcpro gcpro1, gcpro2, gcpro3;
- EMACS_SET_SECS (nexttime, -1);
- EMACS_SET_USECS (nexttime, -1);
+ EMACS_SET_INVALID_TIME (nexttime);
/* Always consider the ordinary timers. */
timers = Vtimer_list;
/* Consider the idle timers only if Emacs is idle. */
- if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+ if (EMACS_TIME_VALID_P (timer_idleness_start_time))
idle_timers = Vtimer_idle_list;
else
idle_timers = Qnil;
if (CONSP (timers) || CONSP (idle_timers))
{
EMACS_GET_TIME (now);
- if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+ if (EMACS_TIME_VALID_P (timer_idleness_start_time))
EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
+ else
+ EMACS_SET_SECS_NSECS (idleness_now, 0, 0);
}
while (CONSP (timers) || CONSP (idle_timers))
Lisp_Object timer = Qnil, idle_timer = Qnil;
EMACS_TIME timer_time, idle_timer_time;
EMACS_TIME difference;
- EMACS_TIME timer_difference IF_LINT (= {0});
- EMACS_TIME idle_timer_difference IF_LINT (= {0});
+ EMACS_TIME timer_difference, idle_timer_difference;
+ int ripe, timer_ripe = 0, idle_timer_ripe = 0;
+
+ EMACS_SET_INVALID_TIME (timer_difference);
+ EMACS_SET_INVALID_TIME (idle_timer_difference);
- /* Skip past invalid timers and timers already handled. */
+ /* Set TIMER and TIMER_DIFFERENCE
+ based on the next ordinary timer.
+ TIMER_DIFFERENCE is the distance in time from NOW to when
+ this timer becomes ripe (negative if it's already ripe).
+ Skip past invalid timers and timers already handled. */
if (CONSP (timers))
{
timer = XCAR (timers);
- if (!VECTORP (timer) || ASIZE (timer) != 8)
+ if (! decode_timer (timer, &timer_time))
{
timers = XCDR (timers);
continue;
}
- vector = XVECTOR (timer)->contents;
- if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
- || !INTEGERP (vector[3])
- || ! NILP (vector[0]))
- {
- timers = XCDR (timers);
- continue;
- }
+ timer_ripe = EMACS_TIME_LE (timer_time, now);
+ if (timer_ripe)
+ EMACS_SUB_TIME (timer_difference, now, timer_time);
+ else
+ EMACS_SUB_TIME (timer_difference, timer_time, now);
}
+
+ /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
+ based on the next idle timer. */
if (CONSP (idle_timers))
{
- timer = XCAR (idle_timers);
- if (!VECTORP (timer) || ASIZE (timer) != 8)
- {
- idle_timers = XCDR (idle_timers);
- continue;
- }
- vector = XVECTOR (timer)->contents;
-
- if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
- || !INTEGERP (vector[3])
- || ! NILP (vector[0]))
+ idle_timer = XCAR (idle_timers);
+ if (! decode_timer (idle_timer, &idle_timer_time))
{
idle_timers = XCDR (idle_timers);
continue;
}
- }
- /* Set TIMER, TIMER_TIME and TIMER_DIFFERENCE
- based on the next ordinary timer.
- TIMER_DIFFERENCE is the distance in time from NOW to when
- this timer becomes ripe (negative if it's already ripe). */
- if (CONSP (timers))
- {
- timer = XCAR (timers);
- vector = XVECTOR (timer)->contents;
- EMACS_SET_SECS (timer_time,
- (XINT (vector[1]) << 16) | (XINT (vector[2])));
- EMACS_SET_USECS (timer_time, XINT (vector[3]));
- EMACS_SUB_TIME (timer_difference, timer_time, now);
- }
-
- /* Set IDLE_TIMER, IDLE_TIMER_TIME and IDLE_TIMER_DIFFERENCE
- based on the next idle timer. */
- if (CONSP (idle_timers))
- {
- idle_timer = XCAR (idle_timers);
- vector = XVECTOR (idle_timer)->contents;
- EMACS_SET_SECS (idle_timer_time,
- (XINT (vector[1]) << 16) | (XINT (vector[2])));
- EMACS_SET_USECS (idle_timer_time, XINT (vector[3]));
- EMACS_SUB_TIME (idle_timer_difference, idle_timer_time, idleness_now);
+ idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
+ if (idle_timer_ripe)
+ EMACS_SUB_TIME (idle_timer_difference,
+ idleness_now, idle_timer_time);
+ else
+ EMACS_SUB_TIME (idle_timer_difference,
+ idle_timer_time, idleness_now);
}
/* Decide which timer is the next timer,
- and set CHOSEN_TIMER, VECTOR and DIFFERENCE accordingly.
+ and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly.
Also step down the list where we found that timer. */
- if (CONSP (timers) && CONSP (idle_timers))
- {
- EMACS_TIME temp;
- EMACS_SUB_TIME (temp, timer_difference, idle_timer_difference);
- if (EMACS_TIME_NEG_P (temp))
- {
- chosen_timer = timer;
- timers = XCDR (timers);
- difference = timer_difference;
- }
- else
- {
- chosen_timer = idle_timer;
- idle_timers = XCDR (idle_timers);
- difference = idle_timer_difference;
- }
- }
- else if (CONSP (timers))
+ if (EMACS_TIME_VALID_P (timer_difference)
+ && (! EMACS_TIME_VALID_P (idle_timer_difference)
+ || idle_timer_ripe < timer_ripe
+ || (idle_timer_ripe == timer_ripe
+ && (timer_ripe
+ ? EMACS_TIME_LT (idle_timer_difference,
+ timer_difference)
+ : EMACS_TIME_LT (timer_difference,
+ idle_timer_difference)))))
{
chosen_timer = timer;
timers = XCDR (timers);
difference = timer_difference;
+ ripe = timer_ripe;
}
else
{
chosen_timer = idle_timer;
idle_timers = XCDR (idle_timers);
difference = idle_timer_difference;
+ ripe = idle_timer_ripe;
}
- vector = XVECTOR (chosen_timer)->contents;
/* If timer is ripe, run it if it hasn't been run. */
- if (EMACS_TIME_NEG_P (difference)
- || (EMACS_SECS (difference) == 0
- && EMACS_USECS (difference) == 0))
+ if (ripe)
{
+ vector = XVECTOR (chosen_timer)->contents;
if (NILP (vector[0]))
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object old_deactivate_mark = Vdeactivate_mark;
/* Mark the timer as triggered to prevent problems if the lisp
timer list for the time being.
Returns the time to wait until the next timer fires.
- If no timer is active, return -1.
+ If no timer is active, return an invalid value.
As long as any timer is ripe, we run it. */
{
nexttime = timer_check_2 ();
}
- while (EMACS_SECS (nexttime) == 0 && EMACS_USECS (nexttime) == 0);
+ while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0);
return nexttime;
}
DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
doc: /* Return the current length of Emacs idleness, or nil.
-The value when Emacs is idle is a list of three integers. The first has
-the most significant 16 bits of the seconds, while the second has the least
-significant 16 bits. The third integer gives the microsecond count.
+The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC)
+in the same style as (current-time).
The value when Emacs is not idle is nil.
-The microsecond count is zero on systems that do not provide
-resolution finer than a second. */)
+NSEC is a multiple of the system clock resolution. */)
(void)
{
- if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+ if (EMACS_TIME_VALID_P (timer_idleness_start_time))
{
EMACS_TIME now, idleness_now;
EMACS_GET_TIME (now);
EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
- return list3 (make_number ((EMACS_SECS (idleness_now) >> 16) & 0xffff),
- make_number ((EMACS_SECS (idleness_now) >> 0) & 0xffff),
- make_number (EMACS_USECS (idleness_now)));
+ return make_lisp_time (idleness_now);
}
return Qnil;
"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;
+ ptrdiff_t textpos = -1;
int col = -1, row = -1;
int dx = -1, dy = -1;
int width = -1, height = -1;
else if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
{
Lisp_Object string;
- EMACS_INT charpos;
+ ptrdiff_t charpos;
posn = (part == ON_MODE_LINE) ? Qmode_line : Qheader_line;
/* Note that mode_line_string takes COL, ROW as pixels and
else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
{
Lisp_Object string;
- EMACS_INT charpos;
+ ptrdiff_t charpos;
posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
col = wx;
|| !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,
Qfunction_key,
KVAR (current_kboard, Vsystem_key_alist),
0, &KVAR (current_kboard, system_key_syms),
- TYPE_MAXIMUM (EMACS_INT));
+ PTRDIFF_MAX);
}
return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
if (button >= ASIZE (button_down_location))
{
+ ptrdiff_t incr = button - ASIZE (button_down_location) + 1;
button_down_location = larger_vector (button_down_location,
- button + 1, Qnil);
- mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
+ incr, -1);
+ mouse_syms = larger_vector (mouse_syms, incr, -1);
}
start_pos_ptr = &AREF (button_down_location, button);
event->modifiers &= ~up_modifier;
if (event->code >= ASIZE (mouse_syms))
- mouse_syms = larger_vector (mouse_syms, event->code + 1, Qnil);
+ mouse_syms = larger_vector (mouse_syms,
+ event->code - ASIZE (mouse_syms) + 1,
+ -1);
/* Get the symbol we should use for the mouse click. */
head = modify_event_symbol (event->code,
if (button >= ASIZE (button_down_location))
{
+ ptrdiff_t incr = button - ASIZE (button_down_location) + 1;
button_down_location = larger_vector (button_down_location,
- button + 1, Qnil);
- mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
+ incr, -1);
+ mouse_syms = larger_vector (mouse_syms, incr, -1);
}
start_pos_ptr = &AREF (button_down_location, button);
This doesn't use any caches. */
static int
-parse_modifiers_uncached (Lisp_Object symbol, EMACS_INT *modifier_end)
+parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
{
Lisp_Object name;
- EMACS_INT i;
+ ptrdiff_t i;
int modifiers;
CHECK_SYMBOL (symbol);
modifiers = 0;
name = SYMBOL_NAME (symbol);
- for (i = 0; i+2 <= SBYTES (name); )
+ for (i = 0; i < SBYTES (name) - 1; )
{
- EMACS_INT this_mod_end = 0;
+ ptrdiff_t this_mod_end = 0;
int this_mod = 0;
/* See if the name continues with a modifier word.
modifier_list = Qnil;
for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
if (modifiers & (1<<i))
- modifier_list = Fcons (XVECTOR (modifier_symbols)->contents[i],
+ modifier_list = Fcons (AREF (modifier_symbols, i),
modifier_list);
return modifier_list;
return elements;
else
{
- EMACS_INT end;
+ ptrdiff_t end;
int modifiers = parse_modifiers_uncached (symbol, &end);
Lisp_Object unmodified;
Lisp_Object mask;
in the symbol's name. */
static Lisp_Object
-modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object symbol_kind,
+modify_event_symbol (ptrdiff_t symbol_num, int modifiers, Lisp_Object symbol_kind,
Lisp_Object name_alist_or_stem, const char *const *name_table,
- Lisp_Object *symbol_table, EMACS_INT table_size)
+ Lisp_Object *symbol_table, ptrdiff_t table_size)
{
Lisp_Object value;
Lisp_Object symbol_int;
*symbol_table = Fmake_vector (size, Qnil);
}
- value = XVECTOR (*symbol_table)->contents[symbol_num];
+ value = AREF (*symbol_table, symbol_num);
}
/* Have we already used this symbol before? */
if (NILP (value))
{
char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
- sprintf (buf, "key-%"pI"d", symbol_num);
+ sprintf (buf, "key-%"pD"d", symbol_num);
value = intern (buf);
}
if (CONSP (*symbol_table))
*symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
else
- XVECTOR (*symbol_table)->contents[symbol_num] = value;
+ ASET (*symbol_table, symbol_num, value);
/* Fill in the cache entries for this symbol; this also
builds the Qevent_symbol_elements property, which the user
return nread;
}
\f
+#if defined SYNC_INPUT || defined SIGIO
static void
handle_async_input (void)
{
--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. */
for (p = user_signals; p; p = p->next)
if (p->sig == sig)
{
- if (special_event_name &&
- strcmp (special_event_name, p->name) == 0)
+ if (special_event_name
+ && strcmp (special_event_name, p->name) == 0)
{
/* Enter the debugger in many ways. */
debug_on_next_call = 1;
int end = menu_bar_items_index;
for (i = 0; i < end; i += 4)
- if (EQ (XCAR (tail), XVECTOR (menu_bar_items_vector)->contents[i]))
+ if (EQ (XCAR (tail), AREF (menu_bar_items_vector, i)))
{
Lisp_Object tem0, tem1, tem2, tem3;
/* Move the item at index I to the end,
shifting all the others forward. */
- tem0 = XVECTOR (menu_bar_items_vector)->contents[i + 0];
- tem1 = XVECTOR (menu_bar_items_vector)->contents[i + 1];
- tem2 = XVECTOR (menu_bar_items_vector)->contents[i + 2];
- tem3 = XVECTOR (menu_bar_items_vector)->contents[i + 3];
+ tem0 = AREF (menu_bar_items_vector, i + 0);
+ tem1 = AREF (menu_bar_items_vector, i + 1);
+ tem2 = AREF (menu_bar_items_vector, i + 2);
+ tem3 = AREF (menu_bar_items_vector, i + 3);
if (end > i + 4)
- memmove (&XVECTOR (menu_bar_items_vector)->contents[i],
- &XVECTOR (menu_bar_items_vector)->contents[i + 4],
+ memmove (&AREF (menu_bar_items_vector, i),
+ &AREF (menu_bar_items_vector, i + 4),
(end - i - 4) * sizeof (Lisp_Object));
- XVECTOR (menu_bar_items_vector)->contents[end - 4] = tem0;
- XVECTOR (menu_bar_items_vector)->contents[end - 3] = tem1;
- XVECTOR (menu_bar_items_vector)->contents[end - 2] = tem2;
- XVECTOR (menu_bar_items_vector)->contents[end - 1] = tem3;
+ ASET (menu_bar_items_vector, end - 4, tem0);
+ ASET (menu_bar_items_vector, end - 3, tem1);
+ ASET (menu_bar_items_vector, end - 2, tem2);
+ ASET (menu_bar_items_vector, end - 1, tem3);
break;
}
}
int i = menu_bar_items_index;
if (i + 4 > ASIZE (menu_bar_items_vector))
menu_bar_items_vector =
- larger_vector (menu_bar_items_vector, 2 * i, Qnil);
+ larger_vector (menu_bar_items_vector, 4, -1);
/* Add this item. */
- XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
- XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
- XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
- XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
menu_bar_items_index = i;
}
discard any previously made menu bar item. */
for (i = 0; i < menu_bar_items_index; i += 4)
- if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
+ if (EQ (key, AREF (menu_bar_items_vector, i)))
{
if (menu_bar_items_index > i + 4)
- memmove (&XVECTOR (menu_bar_items_vector)->contents[i],
- &XVECTOR (menu_bar_items_vector)->contents[i + 4],
+ memmove (&AREF (menu_bar_items_vector, i),
+ &AREF (menu_bar_items_vector, i + 4),
(menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
menu_bar_items_index -= 4;
}
if (!i)
return;
- item = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
+ item = AREF (item_properties, ITEM_PROPERTY_DEF);
/* Find any existing item for this KEY. */
for (i = 0; i < menu_bar_items_index; i += 4)
- if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
+ if (EQ (key, AREF (menu_bar_items_vector, i)))
break;
/* If we did not find this KEY, add it at the end. */
{
/* If vector is too small, get a bigger one. */
if (i + 4 > ASIZE (menu_bar_items_vector))
- menu_bar_items_vector = larger_vector (menu_bar_items_vector, 2 * i, Qnil);
+ menu_bar_items_vector = larger_vector (menu_bar_items_vector, 4, -1);
/* Add this item. */
- XVECTOR (menu_bar_items_vector)->contents[i++] = key;
- XVECTOR (menu_bar_items_vector)->contents[i++]
- = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
- XVECTOR (menu_bar_items_vector)->contents[i++] = Fcons (item, Qnil);
- XVECTOR (menu_bar_items_vector)->contents[i++] = make_number (0);
+ ASET (menu_bar_items_vector, i, key); i++;
+ ASET (menu_bar_items_vector, i,
+ AREF (item_properties, ITEM_PROPERTY_NAME)); i++;
+ ASET (menu_bar_items_vector, i, Fcons (item, Qnil)); i++;
+ ASET (menu_bar_items_vector, i, make_number (0)); i++;
menu_bar_items_index = i;
}
/* We did find an item for this KEY. Add ITEM to its list of maps. */
else
{
Lisp_Object old;
- old = XVECTOR (menu_bar_items_vector)->contents[i + 2];
+ old = AREF (menu_bar_items_vector, i + 2);
/* If the new and the old items are not both keymaps,
the lookup will only find `item'. */
item = Fcons (item, KEYMAPP (item) && KEYMAPP (XCAR (old)) ? old : Qnil);
- XVECTOR (menu_bar_items_vector)->contents[i + 2] = item;
+ ASET (menu_bar_items_vector, i + 2, item);
}
}
\f
Lisp_Object
menu_item_eval_property (Lisp_Object sexpr)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
specbind (Qinhibit_redisplay, Qt);
val = internal_condition_case_1 (eval_dyn, sexpr, Qerror,
parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
{
/* Access slot with index IDX of vector tool_bar_item_properties. */
-#define PROP(IDX) XVECTOR (tool_bar_item_properties)->contents[IDX]
+#define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
Lisp_Object filter = Qnil;
Lisp_Object caption;
append_tool_bar_item (void)
{
Lisp_Object *to, *from;
+ ptrdiff_t incr =
+ (ntool_bar_items
+ - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
/* Enlarge tool_bar_items_vector if necessary. */
- if (ntool_bar_items + TOOL_BAR_ITEM_NSLOTS
- >= ASIZE (tool_bar_items_vector))
+ if (0 < incr)
tool_bar_items_vector
- = larger_vector (tool_bar_items_vector,
- 2 * ASIZE (tool_bar_items_vector), Qnil);
+ = larger_vector (tool_bar_items_vector, incr, -1);
/* Append entries from tool_bar_item_properties to the end of
tool_bar_items_vector. */
/* Look at the next element of the map. */
if (idx >= 0)
- elt = XVECTOR (vector)->contents[idx];
+ elt = AREF (vector, idx);
else
elt = Fcar_safe (rest);
Lisp_Object upcased_event, downcased_event;
Lisp_Object desc = Qnil;
Lisp_Object s
- = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
+ = AREF (item_properties, ITEM_PROPERTY_NAME);
upcased_event = Fupcase (event);
downcased_event = Fdowncase (event);
s = concat2 (s, tem);
#endif
tem
- = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
+ = AREF (item_properties, ITEM_PROPERTY_TYPE);
if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
{
/* Insert button prefix. */
Lisp_Object selected
- = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
+ = AREF (item_properties, ITEM_PROPERTY_SELECTED);
if (EQ (tem, QCradio))
tem = build_string (NILP (selected) ? "(*) " : "( ) ");
else
int fix_current_buffer)
{
Lisp_Object from_string;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
/* How many keys there are in the current key sequence. */
int t;
/* The length of the echo buffer when we started reading, and
the length of this_command_keys when we started reading. */
- int echo_start IF_LINT (= 0);
- int keys_start;
+ ptrdiff_t echo_start IF_LINT (= 0);
+ ptrdiff_t keys_start;
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
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;
while those allow us to restart the entire key sequence,
echo_local_start and keys_local_start allow us to throw away
just one key. */
- int echo_local_start IF_LINT (= 0);
+ ptrdiff_t echo_local_start IF_LINT (= 0);
int keys_local_start;
ptrdiff_t local_first_binding;
if (EQ (key, Qt))
{
unbind_to (count, Qnil);
- UNGCPRO_VAR (outer_gcpro);
+ UNGCPRO;
return -1;
}
&& current_buffer != starting_buffer)
{
GROW_RAW_KEYBUF;
- XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
keybuf[t++] = key;
mock_input = t;
Vquit_flag = Qnil;
&& BUFFERP (XWINDOW (window)->buffer)
&& XBUFFER (XWINDOW (window)->buffer) != current_buffer)
{
- XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
keybuf[t] = key;
mock_input = t + 1;
add_command_key (keybuf[t]);
}
- UNGCPRO_VAR (outer_gcpro);
+ UNGCPRO;
return t;
}
Lisp_Object keybuf[30];
register int i;
struct gcpro gcpro1;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
if (!NILP (prompt))
CHECK_STRING (prompt);
! 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)
Lisp_Object keybuf[30];
register int i;
struct gcpro gcpro1;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
if (!NILP (prompt))
CHECK_STRING (prompt);
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;
- EMACS_INT 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 ();
- int 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);
if (NILP (keep_record))
{
for (i = 0; i < ASIZE (recent_keys); ++i)
- XVECTOR (recent_keys)->contents[i] = Qnil;
+ ASET (recent_keys, i, Qnil);
total_keys = 0;
recent_keys_index = 0;
}
On such systems, Emacs starts a subshell instead of suspending. */)
(Lisp_Object stuffstring)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
int old_height, old_width;
int width, height;
struct gcpro gcpro1;
if (STRINGP (stuffstring))
{
- register EMACS_INT count;
+ register ptrdiff_t count;
p = SDATA (stuffstring);
count = SBYTES (stuffstring);
}
\f
void
-set_waiting_for_input (struct timeval *time_to_clear)
+set_waiting_for_input (EMACS_TIME *time_to_clear)
{
input_available_clear_time = time_to_clear;
/* 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. We cannot do that while
- GC is in progress, though. */
- if (!gc_in_progress)
- Fkill_emacs (Qnil);
- else
- Vquit_flag = Qt;
+ 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.
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,
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 ();
quit_char = Ctl ('g');
Vunread_command_events = Qnil;
unread_command_char = -1;
- EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
+ EMACS_SET_INVALID_TIME (timer_idleness_start_time);
total_keys = 0;
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
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");
modifier_symbols = Fmake_vector (make_number (len), Qnil);
for (i = 0; i < len; i++)
if (modifier_names[i])
- XVECTOR (modifier_symbols)->contents[i] = intern_c_string (modifier_names[i]);
+ ASET (modifier_symbols, i, intern_c_string (modifier_names[i]));
staticpro (&modifier_symbols);
}
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'.
}
/* Mark the pointers in the kboard objects.
- Called by the Fgarbage_collector. */
+ Called by Fgarbage_collect. */
void
mark_kboards (void)
{