#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"
static EMACS_INT last_auto_save;
-/* This is like Vthis_command, except that commands never set it. */
-Lisp_Object real_this_command;
-
/* The value of point when the last command was started. */
static ptrdiff_t last_point_position;
Time last_event_timestamp;
static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
+static Lisp_Object Qhandle_select_window;
Lisp_Object QPRIMARY;
static Lisp_Object Qself_insert_command;
#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 (int) 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);
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);
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)
/* 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)
/* Do this after running Vpost_command_hook, for consistency. */
KVAR (current_kboard, Vlast_command) = Vthis_command;
- KVAR (current_kboard, Vreal_last_command) = real_this_command;
+ KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
if (!CONSP (last_command_event))
- KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+ KVAR (current_kboard, Vlast_repeatable_command) = Vreal_this_command;
while (1)
{
before_command_echo_length = echo_length ();
Vthis_command = Qnil;
- real_this_command = Qnil;
+ Vreal_this_command = Qnil;
Vthis_original_command = Qnil;
Vthis_command_keys_shift_translated = Qnil;
from that position. But also throw away beg_unchanged and
end_unchanged information in that case, so that redisplay will
update the whole window properly. */
- if (!NILP (XWINDOW (selected_window)->force_start))
+ if (XWINDOW (selected_window)->force_start)
{
struct buffer *b;
- XWINDOW (selected_window)->force_start = Qnil;
+ XWINDOW (selected_window)->force_start = 0;
b = XBUFFER (XWINDOW (selected_window)->buffer);
BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
}
/* Execute the command. */
Vthis_command = cmd;
- real_this_command = cmd;
+ Vreal_this_command = cmd;
safe_run_hooks (Qpre_command_hook);
already_adjusted = 0;
If the command didn't actually create a prefix arg,
but is merely a frame event that is transparent to prefix args,
then the above doesn't apply. */
- if (NILP (KVAR (current_kboard, Vprefix_arg)) || CONSP (last_command_event))
+ if (NILP (KVAR (current_kboard, Vprefix_arg))
+ || CONSP (last_command_event))
{
KVAR (current_kboard, Vlast_command) = Vthis_command;
- KVAR (current_kboard, Vreal_last_command) = real_this_command;
+ KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
if (!CONSP (last_command_event))
- KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+ KVAR (current_kboard, Vlast_repeatable_command)
+ = Vreal_this_command;
cancel_echoing ();
this_command_key_count = 0;
this_command_key_count_reset = 0;
? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
: (!NILP (Vselect_active_regions)
&& !NILP (Vtransient_mark_mode)))
- && !EQ (Vthis_command, Qhandle_switch_frame))
+ && NILP (Fmemq (Vthis_command,
+ Vselection_inhibit_update_commands)))
{
ptrdiff_t beg =
XINT (Fmarker_position (BVAR (current_buffer, mark)));
&& (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
? max (beg - 1, BEGV)
#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;
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;
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;
ptrdiff_t jmpcount;
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:
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 (;;)
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
static void
process_special_events (void)
{
- while (kbd_fetch_ptr != kbd_store_ptr)
- {
- struct input_event *event;
-
- event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
- ? kbd_fetch_ptr
- : kbd_buffer);
+ struct input_event *event;
- last_event_timestamp = event->timestamp;
+ for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event)
+ {
+ 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;
}
}
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]))
{
ptrdiff_t count = SPECPDL_INDEX ();
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;
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;
*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 (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;
}
}
menu_bar_items_vector =
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 (i + 4 > ASIZE (menu_bar_items_vector))
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
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;
/* 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
&& 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;
memset (keybuf, 0, sizeof keybuf);
GCPRO1 (keybuf[0]);
- gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
+ gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0]));
if (NILP (continue_echo))
{
cancel_hourglass ();
#endif
- i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
+ i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), 0);
\f
-DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
- 1, 1, "P",
- doc: /* Read function name, then read its arguments and call it.
-
-To pass a numeric argument to the command you are invoking with, specify
-the numeric argument to this command.
-
-Noninteractively, the argument PREFIXARG is the prefix argument to
-give to the command you invoke, if it asks for an argument. */)
- (Lisp_Object prefixarg)
-{
- Lisp_Object function;
- ptrdiff_t saved_last_point_position;
- Lisp_Object saved_keys, saved_last_point_position_buffer;
- Lisp_Object bindings, value;
- struct gcpro gcpro1, gcpro2, gcpro3;
-#ifdef HAVE_WINDOW_SYSTEM
- /* The call to Fcompleting_read will start and cancel the hourglass,
- but if the hourglass was already scheduled, this means that no
- hourglass will be shown for the actual M-x command itself.
- So we restart it if it is already scheduled. Note that checking
- hourglass_shown_p is not enough, normally the hourglass is not shown,
- just scheduled to be shown. */
- int hstarted = hourglass_started ();
-#endif
-
- saved_keys = Fvector (this_command_key_count,
- XVECTOR (this_command_keys)->contents);
- saved_last_point_position_buffer = last_point_position_buffer;
- saved_last_point_position = last_point_position;
- GCPRO3 (saved_keys, prefixarg, saved_last_point_position_buffer);
-
- function = call0 (intern ("read-extended-command"));
-
-#ifdef HAVE_WINDOW_SYSTEM
- if (hstarted) start_hourglass ();
-#endif
-
- if (STRINGP (function) && SCHARS (function) == 0)
- error ("No command name given");
-
- /* Set this_command_keys to the concatenation of saved_keys and
- function, followed by a RET. */
- {
- Lisp_Object *keys;
- int i;
-
- this_command_key_count = 0;
- this_command_key_count_reset = 0;
- this_single_command_key_start = 0;
-
- keys = XVECTOR (saved_keys)->contents;
- for (i = 0; i < ASIZE (saved_keys); i++)
- add_command_key (keys[i]);
-
- for (i = 0; i < SCHARS (function); i++)
- add_command_key (Faref (function, make_number (i)));
-
- add_command_key (make_number ('\015'));
- }
-
- last_point_position = saved_last_point_position;
- last_point_position_buffer = saved_last_point_position_buffer;
-
- UNGCPRO;
-
- function = Fintern (function, Qnil);
- KVAR (current_kboard, Vprefix_arg) = prefixarg;
- Vthis_command = function;
- real_this_command = function;
-
- /* If enabled, show which key runs this command. */
- if (!NILP (Vsuggest_key_bindings)
- && NILP (Vexecuting_kbd_macro)
- && SYMBOLP (function))
- bindings = Fwhere_is_internal (function, Voverriding_local_map,
- Qt, Qnil, Qnil);
- else
- bindings = Qnil;
-
- value = Qnil;
- GCPRO3 (bindings, value, function);
- value = Fcommand_execute (function, Qt, Qnil, Qnil);
-
- /* If the command has a key binding, print it now. */
- if (!NILP (bindings)
- && ! (VECTORP (bindings) && EQ (Faref (bindings, make_number (0)),
- Qmouse_movement)))
- {
- /* But first wait, and skip the message if there is input. */
- Lisp_Object waited;
-
- /* If this command displayed something in the echo area;
- wait a few seconds, then display our suggestion message. */
- if (NILP (echo_area_buffer[0]))
- waited = sit_for (make_number (0), 0, 2);
- else if (NUMBERP (Vsuggest_key_bindings))
- waited = sit_for (Vsuggest_key_bindings, 0, 2);
- else
- waited = sit_for (make_number (2), 0, 2);
-
- if (!NILP (waited) && ! CONSP (Vunread_command_events))
- {
- Lisp_Object binding;
- char *newmessage;
- int message_p = push_message ();
- ptrdiff_t count = SPECPDL_INDEX ();
- ptrdiff_t newmessage_len, newmessage_alloc;
- USE_SAFE_ALLOCA;
-
- record_unwind_protect (pop_message_unwind, Qnil);
- binding = Fkey_description (bindings, Qnil);
- newmessage_alloc =
- (sizeof "You can run the command `' with "
- + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
- SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
- newmessage_len =
- esprintf (newmessage, "You can run the command `%s' with %s",
- SDATA (SYMBOL_NAME (function)),
- SDATA (binding));
- message2 (newmessage,
- newmessage_len,
- STRING_MULTIBYTE (binding));
- if (NUMBERP (Vsuggest_key_bindings))
- waited = sit_for (Vsuggest_key_bindings, 0, 2);
- else
- waited = sit_for (make_number (2), 0, 2);
-
- if (!NILP (waited) && message_p)
- restore_message ();
-
- SAFE_FREE ();
- unbind_to (count, Qnil);
- }
- }
-
- RETURN_UNGCPRO (value);
-}
-
-\f
/* Return nonzero if input events are pending. */
int
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;
}
}
\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;
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,
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.
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;
`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
}
/* Mark the pointers in the kboard objects.
- Called by the Fgarbage_collector. */
+ Called by Fgarbage_collect. */
void
mark_kboards (void)
{