X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/6e9ddbb313cf7db66550f93a74cbba12e39e93c0..6dd5a677dbf794eedaa8325c46d57ac041373361:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index c304439f27..0d686e299c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -30,8 +30,8 @@ along with GNU Emacs. If not, see . */ #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" @@ -122,7 +122,7 @@ static Lisp_Object recent_keys; 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. */ @@ -135,16 +135,16 @@ static int raw_keybuf_count; #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. */ @@ -208,20 +208,17 @@ EMACS_INT command_loop_level; 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; @@ -241,6 +238,7 @@ Lisp_Object internal_last_event_frame; 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; @@ -376,7 +374,7 @@ EMACS_TIME timer_check (void); 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; @@ -447,9 +445,9 @@ static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, 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); @@ -461,10 +459,8 @@ static void interrupt_signal (int signalnum); #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); @@ -614,7 +610,7 @@ echo_now (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++) @@ -627,7 +623,7 @@ echo_now (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); @@ -672,7 +668,7 @@ cancel_echoing (void) /* Return the length of the current echo string. */ -static int +static ptrdiff_t echo_length (void) { return (STRINGP (KVAR (current_kboard, echo_string)) @@ -685,7 +681,7 @@ echo_length (void) 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) @@ -714,9 +710,7 @@ add_command_key (Lisp_Object key) #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; @@ -726,7 +720,7 @@ add_command_key (Lisp_Object key) Lisp_Object recursive_edit_1 (void) { - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object val; if (command_loop_level > 0) @@ -794,7 +788,7 @@ Alternatively, `(throw 'exit t)' makes this function signal an error. 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. @@ -890,8 +884,7 @@ static struct kboard_stack *kboard_stack; void push_kboard (struct kboard *k) { - struct kboard_stack *p - = (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack)); + struct kboard_stack *p = xmalloc (sizeof (struct kboard_stack)); p->next = kboard_stack; p->kboard = current_kboard; @@ -1199,7 +1192,13 @@ This also exits all active minibuffers. */) 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) @@ -1207,10 +1206,10 @@ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, 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) @@ -1218,7 +1217,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 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"); } #if defined (HAVE_MOUSE) || defined (HAVE_GPM) @@ -1255,7 +1254,7 @@ Normally, mouse motion is ignored. 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); @@ -1306,7 +1305,7 @@ some_mouse_moved (void) 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. */ @@ -1322,7 +1321,6 @@ cancel_hourglass_unwind (Lisp_Object arg) /* 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) @@ -1330,7 +1328,7 @@ 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; @@ -1371,9 +1369,9 @@ 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) { @@ -1402,7 +1400,7 @@ command_loop_1 (void) { /* 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); @@ -1440,7 +1438,7 @@ command_loop_1 (void) 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; @@ -1479,10 +1477,10 @@ command_loop_1 (void) 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; } @@ -1524,7 +1522,7 @@ command_loop_1 (void) /* Execute the command. */ Vthis_command = cmd; - real_this_command = cmd; + Vreal_this_command = cmd; safe_run_hooks (Qpre_command_hook); already_adjusted = 0; @@ -1556,7 +1554,7 @@ command_loop_1 (void) /* 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)) @@ -1608,12 +1606,14 @@ command_loop_1 (void) 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; @@ -1647,11 +1647,12 @@ command_loop_1 (void) ? 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)); @@ -1711,16 +1712,16 @@ command_loop_1 (void) 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. */ @@ -1747,9 +1748,11 @@ adjust_point_for_property (EMACS_INT last_pt, int modified) && (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; } @@ -1827,7 +1830,7 @@ adjust_point_for_property (EMACS_INT last_pt, int modified) #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 @@ -1877,7 +1880,7 @@ safe_run_hooks_error (Lisp_Object error_data) = 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; @@ -1933,7 +1936,7 @@ safe_run_hooks (Lisp_Object hook) /* 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); @@ -2013,12 +2016,13 @@ start_polling (void) 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); } @@ -2086,7 +2090,7 @@ void bind_polling_period (int n) { #ifdef POLL_FOR_INPUT - int new = polling_period; + EMACS_INT new = polling_period; if (n > new) new = n; @@ -2216,7 +2220,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, /* 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; @@ -2268,10 +2272,10 @@ do { if (polling_stopped_here) start_polling (); \ 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; @@ -2660,7 +2664,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, 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. */ @@ -2681,8 +2685,9 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, && 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); @@ -2876,7 +2881,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, 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 @@ -2980,11 +2985,16 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, 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: @@ -2998,9 +3008,10 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, && ' ' <= XINT (c) && XINT (c) < 256 && XINT (c) != 127) { Lisp_Object keys; - int key_count, key_count_reset; + ptrdiff_t key_count; + int key_count_reset; struct gcpro gcpro1; - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); /* Save the echo status. */ int saved_immediate_echo = current_kboard->immediate_echo; @@ -3137,7 +3148,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, /* 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), @@ -3297,7 +3308,7 @@ record_char (Lisp_Object c) 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; @@ -3666,7 +3677,7 @@ kbd_buffer_unget_event (register struct input_event *event) 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; @@ -3769,9 +3780,8 @@ clear_event (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 @@ -3788,16 +3798,18 @@ kbd_buffer_get_event (KBOARD **kbp, } #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 (;;) @@ -3838,12 +3850,13 @@ kbd_buffer_get_event (KBOARD **kbp, 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); } } @@ -3965,9 +3978,11 @@ kbd_buffer_get_event (KBOARD **kbp, #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 @@ -4152,29 +4167,55 @@ kbd_buffer_get_event (KBOARD **kbp, 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 @@ -4183,8 +4224,6 @@ process_special_events (void) abort (); #endif } - else - break; } } @@ -4214,7 +4253,7 @@ timer_start_idle (void) 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); @@ -4228,9 +4267,9 @@ timer_start_idle (void) 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); } } @@ -4239,7 +4278,7 @@ timer_start_idle (void) 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. */ @@ -4247,7 +4286,7 @@ timer_stop_idle (void) 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; @@ -4261,6 +4300,24 @@ struct input_event last_timer_event EXTERNALLY_VISIBLE; ...). 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. @@ -4278,17 +4335,16 @@ timer_check_2 (void) { 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; @@ -4306,8 +4362,10 @@ timer_check_2 (void) 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)) @@ -4316,116 +4374,87 @@ timer_check_2 (void) 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; - /* Skip past invalid timers and timers already handled. */ + EMACS_SET_INVALID_TIME (timer_difference); + EMACS_SET_INVALID_TIME (idle_timer_difference); + + /* 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 @@ -4469,7 +4498,7 @@ timer_check_2 (void) 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. */ @@ -4482,33 +4511,29 @@ timer_check (void) { 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; @@ -5136,7 +5161,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object 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; @@ -5160,7 +5185,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, 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 @@ -5183,7 +5208,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, 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; @@ -5411,7 +5436,7 @@ make_lispy_event (struct input_event *event) 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, @@ -5543,9 +5568,10 @@ make_lispy_event (struct input_event *event) 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); @@ -5845,7 +5871,9 @@ make_lispy_event (struct input_event *event) 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, @@ -5948,9 +5976,10 @@ make_lispy_event (struct input_event *event) 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); @@ -6052,10 +6081,10 @@ make_lispy_switch_frame (Lisp_Object frame) 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); @@ -6063,9 +6092,9 @@ parse_modifiers_uncached (Lisp_Object symbol, EMACS_INT *modifier_end) 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. @@ -6229,7 +6258,7 @@ lispy_modifier_list (int modifiers) modifier_list = Qnil; for (i = 0; (1<contents[i], + modifier_list = Fcons (AREF (modifier_symbols, i), modifier_list); return modifier_list; @@ -6262,7 +6291,7 @@ parse_modifiers (Lisp_Object symbol) return elements; else { - EMACS_INT end; + ptrdiff_t end; int modifiers = parse_modifiers_uncached (symbol, &end); Lisp_Object unmodified; Lisp_Object mask; @@ -6428,9 +6457,9 @@ reorder_modifiers (Lisp_Object symbol) 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; @@ -6460,7 +6489,7 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s *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? */ @@ -6496,14 +6525,14 @@ modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object s 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 @@ -7141,6 +7170,7 @@ tty_read_avail_input (struct terminal *terminal, return nread; } +#if defined SYNC_INPUT || defined SIGIO static void handle_async_input (void) { @@ -7167,7 +7197,9 @@ handle_async_input (void) --handling_signal; #endif } +#endif /* SYNC_INPUT || SIGIO */ +#ifdef SYNC_INPUT void process_pending_signals (void) { @@ -7175,6 +7207,7 @@ 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. */ @@ -7272,8 +7305,8 @@ handle_user_signal (int sig) 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; @@ -7506,23 +7539,23 @@ menu_bar_items (Lisp_Object old) 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; } } @@ -7532,12 +7565,12 @@ menu_bar_items (Lisp_Object old) 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; } @@ -7563,11 +7596,11 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm 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; } @@ -7591,11 +7624,11 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm 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. */ @@ -7603,24 +7636,24 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm { /* 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); } } @@ -7647,7 +7680,7 @@ eval_dyn (Lisp_Object form) 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, @@ -8137,7 +8170,7 @@ static int 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; @@ -8289,7 +8322,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; ptrdiff_t max_lbl = 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)); - char *buf = (char *) xmalloc (max_lbl + 1); + char *buf = xmalloc (max_lbl + 1); Lisp_Object new_lbl; ptrdiff_t caption_len = strlen (capt); @@ -8372,13 +8405,14 @@ static void 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. */ @@ -8581,7 +8615,7 @@ read_char_minibuf_menu_prompt (int commandflag, /* 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); @@ -8616,7 +8650,7 @@ read_char_minibuf_menu_prompt (int commandflag, 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); @@ -8634,12 +8668,12 @@ read_char_minibuf_menu_prompt (int commandflag, 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 @@ -8963,15 +8997,15 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, 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. */ @@ -9227,7 +9261,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, 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; @@ -9409,7 +9443,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, && 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; @@ -9487,7 +9522,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, && 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; @@ -10115,7 +10151,7 @@ will read just one key sequence. */) 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); @@ -10172,7 +10208,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, 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); @@ -10185,7 +10221,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, 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)) { @@ -10199,7 +10235,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, 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); @@ -10306,146 +10342,6 @@ a special event, so ignore the prefix argument and don't clear it. */) -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); -} - - /* Return nonzero if input events are pending. */ int @@ -10658,7 +10554,7 @@ KEEP-RECORD is non-nil. */) 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; } @@ -10740,7 +10636,7 @@ Some operating systems cannot stop the Emacs process and resume it later. 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; @@ -10796,7 +10692,7 @@ stuff_buffered_input (Lisp_Object stuffstring) if (STRINGP (stuffstring)) { - register EMACS_INT count; + register ptrdiff_t count; p = SDATA (stuffstring); count = SBYTES (stuffstring); @@ -10827,7 +10723,7 @@ stuff_buffered_input (Lisp_Object stuffstring) } 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; @@ -10890,6 +10786,11 @@ interrupt_signal (int signalnum) /* If we don't have an argument, some */ 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. @@ -11008,8 +10909,16 @@ handle_interrupt (void) 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, @@ -11437,7 +11346,7 @@ init_keyboard (void) 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; @@ -11550,9 +11459,6 @@ syms_of_keyboard (void) 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"); @@ -11623,6 +11529,7 @@ syms_of_keyboard (void) 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"); @@ -11666,7 +11573,7 @@ syms_of_keyboard (void) 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); } @@ -11742,7 +11649,6 @@ syms_of_keyboard (void) 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); @@ -11806,12 +11712,14 @@ was a kill command. 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. @@ -11819,6 +11727,10 @@ The command can set this variable; whatever is put here 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. @@ -11835,38 +11747,39 @@ result of looking up the original command in the active keymaps. */); 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 @@ -11877,7 +11790,7 @@ to count as a drag. */); 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, @@ -12052,7 +11965,7 @@ and the minor mode maps regardless of `overriding-local-map'. */); 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. @@ -12138,19 +12051,13 @@ whenever `deferred-action-list' is non-nil. */); 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; @@ -12206,7 +12113,7 @@ just after executing the command. */); 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 @@ -12214,7 +12121,7 @@ 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); @@ -12258,6 +12165,16 @@ text in the region before modifying the buffer. The next `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 @@ -12270,7 +12187,7 @@ variable are `sigusr1' and `sigusr2'. */); Vdebug_on_event = intern_c_string ("sigusr2"); /* Create the initial keyboard. */ - initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); + initial_kboard = xmalloc (sizeof (KBOARD)); init_kboard (initial_kboard); /* Vwindow_system is left at t for now. */ initial_kboard->next_kboard = all_kboards; @@ -12336,7 +12253,7 @@ keys_of_keyboard (void) } /* Mark the pointers in the kboard objects. - Called by the Fgarbage_collector. */ + Called by Fgarbage_collect. */ void mark_kboards (void) {