X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/4c36be58ca2b4777a5e7bf0d3e692cfd9fa1aea3..6cd7a13902729007a4d1e14a299bad47c9808353:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index 5d1784ad0b..00e6f4cbbe 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,6 +1,6 @@ /* Keyboard and mouse input; editor command loop. -Copyright (C) 1985-1989, 1993-1997, 1999-2011 Free Software Foundation, Inc. +Copyright (C) 1985-1989, 1993-1997, 1999-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -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,9 @@ 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 (void) NO_RETURN; +static _Noreturn void quit_throw_to_read_char (int); +static void process_special_events (void); static void timer_start_idle (void); static void timer_stop_idle (void); static void timer_resume_idle (void); @@ -483,7 +480,7 @@ echo_char (Lisp_Object c) if (current_kboard->immediate_echo) { int size = KEY_DESCRIPTION_SIZE + 100; - char *buffer = (char *) alloca (size); + char *buffer = alloca (size); char *ptr = buffer; Lisp_Object echo_string; @@ -505,7 +502,7 @@ echo_char (Lisp_Object c) { int offset = ptr - buffer; size = max (2 * size, size + nbytes); - buffer = (char *) alloca (size); + buffer = alloca (size); ptr = buffer + offset; } @@ -523,7 +520,7 @@ echo_char (Lisp_Object c) { int offset = ptr - buffer; size += len; - buffer = (char *) alloca (size); + buffer = alloca (size); ptr = buffer + offset; } @@ -613,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++) @@ -626,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); @@ -653,7 +650,7 @@ echo_now (void) echo_kboard = current_kboard; if (waiting_for_input && !NILP (Vquit_flag)) - quit_throw_to_read_char (); + quit_throw_to_read_char (0); } /* Turn off echoing, for the start of a new command. */ @@ -671,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)) @@ -684,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) @@ -713,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; @@ -725,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) @@ -793,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. @@ -889,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 *p); p->next = kboard_stack; p->kboard = current_kboard; @@ -1198,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) @@ -1206,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) @@ -1217,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) @@ -1254,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); @@ -1305,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. */ @@ -1318,10 +1318,12 @@ cancel_hourglass_unwind (Lisp_Object arg) } #endif +/* The last boundary auto-added to buffer-undo-list. */ +Lisp_Object last_undo_boundary; + /* 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) @@ -1329,7 +1331,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; @@ -1370,9 +1372,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) { @@ -1401,7 +1403,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); @@ -1439,7 +1441,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; @@ -1478,10 +1480,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; } @@ -1523,7 +1525,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; @@ -1555,7 +1557,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)) @@ -1566,7 +1568,13 @@ command_loop_1 (void) #endif if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why? --Stef */ - Fundo_boundary (); + { + Lisp_Object undo = BVAR (current_buffer, undo_list); + Fundo_boundary (); + last_undo_boundary + = (EQ (undo, BVAR (current_buffer, undo_list)) + ? Qnil : BVAR (current_buffer, undo_list)); + } Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil); #ifdef HAVE_WINDOW_SYSTEM @@ -1607,12 +1615,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; @@ -1646,11 +1656,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)); @@ -1710,16 +1721,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. */ @@ -1746,9 +1757,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; } @@ -1826,7 +1839,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 @@ -1876,7 +1889,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; @@ -1932,7 +1945,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); @@ -2012,12 +2025,12 @@ start_polling (void) if (poll_timer == NULL || EMACS_SECS (poll_timer->interval) != polling_period) { - EMACS_TIME interval; + time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); + EMACS_TIME interval = make_emacs_time (period, 0); if (poll_timer) cancel_atimer (poll_timer); - EMACS_SET_SECS_USECS (interval, polling_period, 0); poll_timer = start_atimer (ATIMER_CONTINUOUS, interval, poll_for_input, NULL); } @@ -2085,7 +2098,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; @@ -2172,14 +2185,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, if (!NILP (help) && !STRINGP (help)) { if (FUNCTIONP (help)) - { - Lisp_Object args[4]; - args[0] = help; - args[1] = window; - args[2] = object; - args[3] = pos; - help = safe_call (4, args); - } + help = safe_call (4, help, window, object, pos); else help = safe_eval (help); @@ -2215,7 +2221,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; @@ -2238,8 +2244,8 @@ do { if (polling_stopped_here) start_polling (); \ polling_stopped_here = 0; } while (0) /* read a character from the keyboard; call the redisplay if needed */ -/* commandflag 0 means do not do auto-saving, but do do redisplay. - -1 means do not do redisplay, but do do autosaving. +/* commandflag 0 means do not autosave, but do redisplay. + -1 means do not redisplay, but do autosave. 1 means do both. */ /* The arguments MAPS and NMAPS are for menu prompting. @@ -2267,10 +2273,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; @@ -2659,7 +2665,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. */ @@ -2680,8 +2686,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); @@ -2691,17 +2698,13 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, && ! CONSP (Vunread_command_events)) { Fdo_auto_save (Qnil, Qnil); - - /* If we have auto-saved and there is still no input - available, garbage collect if there has been enough - consing going on to make it worthwhile. */ - if (!detect_input_pending_run_timers (0) - && consing_since_gc > gc_cons_threshold / 2) - Fgarbage_collect (); - redisplay (); } } + + /* If there is still no input available, ask for GC. */ + if (!detect_input_pending_run_timers (0)) + maybe_gc (); } /* Notify the caller if an autosave hook, or a timer, sentinel or @@ -2780,13 +2783,8 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, { KBOARD *kb IF_LINT (= NULL); - if (end_time) - { - EMACS_TIME now; - EMACS_GET_TIME (now); - if (EMACS_TIME_GE (now, *end_time)) - goto exit; - } + if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) + goto exit; /* Actually read a character, waiting if necessary. */ save_getcjmp (save_jump); @@ -2875,7 +2873,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 @@ -2979,11 +2977,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: @@ -2997,9 +3000,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; - struct gcpro inner_gcpro1; - int count = SPECPDL_INDEX (); + ptrdiff_t key_count; + int key_count_reset; + struct gcpro gcpro1; + ptrdiff_t count = SPECPDL_INDEX (); /* Save the echo status. */ int saved_immediate_echo = current_kboard->immediate_echo; @@ -3026,7 +3030,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, keys = Fcopy_sequence (this_command_keys); else keys = Qnil; - GCPRO1_VAR (keys, inner_gcpro); + GCPRO1 (keys); /* Clear out this_command_keys. */ this_command_key_count = 0; @@ -3064,7 +3068,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, if (saved_immediate_echo) echo_now (); - UNGCPRO_VAR (inner_gcpro); + UNGCPRO; /* The input method can return no events. */ if (! CONSP (tem)) @@ -3136,7 +3140,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), @@ -3296,7 +3300,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; @@ -3665,7 +3669,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; @@ -3768,9 +3772,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 @@ -3787,16 +3790,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 (;;) @@ -3817,7 +3822,7 @@ kbd_buffer_get_event (KBOARD **kbp, /* If the quit flag is set, then read_char will return quit_char, so that counts as "available input." */ if (!NILP (Vquit_flag)) - quit_throw_to_read_char (); + quit_throw_to_read_char (0); /* One way or another, wait until input is available; then, if interrupt handlers have not read it, read it now. */ @@ -3834,15 +3839,15 @@ kbd_buffer_get_event (KBOARD **kbp, #endif if (end_time) { - EMACS_TIME duration; - EMACS_GET_TIME (duration); - if (EMACS_TIME_GE (duration, *end_time)) - return Qnil; /* finished waiting */ + EMACS_TIME now = current_emacs_time (); + if (EMACS_TIME_LE (*end_time, now)) + return Qnil; /* Finished waiting. */ else { - EMACS_SUB_TIME (duration, *end_time, duration); - wait_reading_process_output (EMACS_SECS (duration), - EMACS_USECS (duration), + EMACS_TIME duration = sub_emacs_time (*end_time, now); + wait_reading_process_output (min (EMACS_SECS (duration), + WAIT_READING_MAX), + EMACS_NSECS (duration), -1, 1, Qnil, NULL, 0); } } @@ -3964,9 +3969,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 @@ -4145,37 +4152,61 @@ kbd_buffer_get_event (KBOARD **kbp, return (obj); } -/* Process any events that are not user-visible, - then return, without reading any user-visible events. */ +/* Process any non-user-visible events (currently X selection events), + without reading any user-visible events. */ -void -swallow_events (int do_display) +static void +process_special_events (void) { - int old_timers_run; + struct input_event *event; - while (kbd_fetch_ptr != kbd_store_ptr) + for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event) { - struct input_event *event; - - event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) - ? kbd_fetch_ptr - : kbd_buffer); - - last_event_timestamp = event->timestamp; + if (event == kbd_buffer + KBD_BUFFER_SIZE) + { + event = kbd_buffer; + if (event == kbd_store_ptr) + break; + } - /* These two kinds of events get special handling - and don't actually appear to the command loop. */ + /* If we find a stored X selection request, handle it now. */ if (event->kind == SELECTION_REQUEST_EVENT || event->kind == SELECTION_CLEAR_EVENT) { #ifdef HAVE_X11 - struct input_event copy; - /* Remove it from the buffer before processing it, - since otherwise swallow_events called recursively could see it - and process it again. */ - copy = *event; - kbd_fetch_ptr = event + 1; + /* Remove the event from the fifo buffer before processing; + otherwise swallow_events called recursively could see it + and process it again. To do this, we move the events + between kbd_fetch_ptr and EVENT one slot to the right, + cyclically. */ + + struct input_event copy = *event; + struct input_event *beg + = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) + ? kbd_buffer : kbd_fetch_ptr; + + if (event > beg) + memmove (beg + 1, beg, (event - beg) * sizeof (struct input_event)); + else if (event < beg) + { + if (event > kbd_buffer) + memmove (kbd_buffer + 1, kbd_buffer, + (event - kbd_buffer) * sizeof (struct input_event)); + *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1); + if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1) + memmove (beg + 1, beg, + (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) + * sizeof (struct input_event)); + } + + if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) + kbd_fetch_ptr = kbd_buffer + 1; + else + kbd_fetch_ptr++; + + /* X wants last_event_timestamp for selection ownership. */ + last_event_timestamp = copy.timestamp; input_pending = readable_events (0); x_handle_selection_event (©); #else @@ -4184,9 +4215,18 @@ swallow_events (int do_display) abort (); #endif } - else - break; } +} + +/* Process any events that are not user-visible, run timer events that + are ripe, and return, without reading any user-visible events. */ + +void +swallow_events (int do_display) +{ + int old_timers_run; + + process_special_events (); old_timers_run = timers_run; get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW); @@ -4204,11 +4244,10 @@ 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); - + timer_idleness_start_time = current_emacs_time (); timer_last_idleness_start_time = timer_idleness_start_time; /* Mark all idle-time timers as once again candidates for running. */ @@ -4218,9 +4257,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); } } @@ -4229,7 +4268,7 @@ timer_start_idle (void) static void timer_stop_idle (void) { - EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1); + timer_idleness_start_time = invalid_emacs_time (); } /* Resume idle timer from last idle start time. */ @@ -4237,7 +4276,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; @@ -4251,6 +4290,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. @@ -4268,17 +4325,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); + nexttime = invalid_emacs_time (); /* 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; @@ -4295,9 +4351,10 @@ timer_check_2 (void) if (CONSP (timers) || CONSP (idle_timers)) { - EMACS_GET_TIME (now); - if (! EMACS_TIME_NEG_P (timer_idleness_start_time)) - EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time); + now = current_emacs_time (); + idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time) + ? sub_emacs_time (now, timer_idleness_start_time) + : make_emacs_time (0, 0)); } while (CONSP (timers) || CONSP (idle_timers)) @@ -4306,116 +4363,82 @@ 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 = invalid_emacs_time (); + EMACS_TIME idle_timer_difference = invalid_emacs_time (); + int ripe, timer_ripe = 0, idle_timer_ripe = 0; - /* 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); + timer_difference = (timer_ripe + ? sub_emacs_time (now, timer_time) + : sub_emacs_time (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_timer = XCAR (idle_timers); + if (! decode_timer (idle_timer, &idle_timer_time)) { idle_timers = XCDR (idle_timers); continue; } - vector = XVECTOR (timer)->contents; - if (!INTEGERP (vector[1]) || !INTEGERP (vector[2]) - || !INTEGERP (vector[3]) - || ! NILP (vector[0])) - { - 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); + idle_timer_difference = + (idle_timer_ripe + ? sub_emacs_time (idleness_now, idle_timer_time) + : sub_emacs_time (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 @@ -4435,8 +4458,7 @@ timer_check_2 (void) return 0 to indicate that. */ } - EMACS_SET_SECS (nexttime, 0); - EMACS_SET_USECS (nexttime, 0); + nexttime = make_emacs_time (0, 0); } else /* When we encounter a timer that is still waiting, @@ -4459,7 +4481,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. */ @@ -4472,34 +4494,24 @@ 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)) - { - 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))); - } + if (EMACS_TIME_VALID_P (timer_idleness_start_time)) + return make_lisp_time (sub_emacs_time (current_emacs_time (), + timer_idleness_start_time)); return Qnil; } @@ -4813,7 +4825,7 @@ const char *const lispy_function_keys[] = "ico-00", /* VK_ICO_00 0xE4 */ 0, /* VK_PROCESSKEY 0xE5 - used by IME */ "ico-clear", /* VK_ICO_CLEAR 0xE6 */ - 0, /* VK_PACKET 0xE7 - used to pass unicode chars */ + 0, /* VK_PACKET 0xE7 - used to pass Unicode chars */ 0, /* 0xE8 */ "reset", /* VK_OEM_RESET 0xE9 */ "jump", /* VK_OEM_JUMP 0xEA */ @@ -5123,10 +5135,10 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, if (WINDOWP (window)) { - /* It's a click in window window at frame coordinates (x,y) */ + /* It's a click in window WINDOW at frame coordinates (X,Y) */ struct window *w = XWINDOW (window); Lisp_Object string_info = Qnil; - EMACS_INT textpos = -1; + ptrdiff_t textpos = -1; int col = -1, row = -1; int dx = -1, dy = -1; int width = -1, height = -1; @@ -5150,7 +5162,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 @@ -5173,7 +5185,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; @@ -5401,7 +5413,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, @@ -5533,9 +5545,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); @@ -5835,7 +5848,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, @@ -5938,9 +5953,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); @@ -6042,10 +6058,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); @@ -6053,9 +6069,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. @@ -6095,7 +6111,7 @@ parse_modifiers_uncached (Lisp_Object symbol, EMACS_INT *modifier_end) #define MULTI_LETTER_MOD(BIT, NAME, LEN) \ if (i + LEN + 1 <= SBYTES (name) \ - && ! strncmp (SSDATA (name) + i, NAME, LEN)) \ + && ! memcmp (SDATA (name) + i, NAME, LEN)) \ { \ this_mod_end = i + LEN; \ this_mod = BIT; \ @@ -6133,13 +6149,13 @@ parse_modifiers_uncached (Lisp_Object symbol, EMACS_INT *modifier_end) if (! (modifiers & (down_modifier | drag_modifier | double_modifier | triple_modifier)) && i + 7 == SBYTES (name) - && strncmp (SSDATA (name) + i, "mouse-", 6) == 0 + && memcmp (SDATA (name) + i, "mouse-", 6) == 0 && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9')) modifiers |= click_modifier; if (! (modifiers & (double_modifier | triple_modifier)) && i + 6 < SBYTES (name) - && strncmp (SSDATA (name) + i, "wheel-", 6) == 0) + && memcmp (SDATA (name) + i, "wheel-", 6) == 0) modifiers |= click_modifier; if (modifier_end) @@ -6157,8 +6173,7 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_ /* Since BASE could contain nulls, we can't use intern here; we have to use Fintern, which expects a genuine Lisp_String, and keeps a reference to it. */ - char *new_mods - = (char *) alloca (sizeof ("A-C-H-M-S-s-down-drag-double-triple-")); + char new_mods[sizeof "A-C-H-M-S-s-down-drag-double-triple-"]; int mod_len; { @@ -6219,7 +6234,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; @@ -6252,7 +6267,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; @@ -6418,9 +6433,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; @@ -6450,7 +6465,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? */ @@ -6486,14 +6501,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 @@ -6592,7 +6607,7 @@ parse_solitary_modifier (Lisp_Object symbol) #define MULTI_LETTER_MOD(BIT, NAME, LEN) \ if (LEN == SBYTES (name) \ - && ! strncmp (SSDATA (name), NAME, LEN)) \ + && ! memcmp (SDATA (name), NAME, LEN)) \ return BIT; case 'A': @@ -7131,6 +7146,7 @@ tty_read_avail_input (struct terminal *terminal, return nread; } +#if defined SYNC_INPUT || defined SIGIO static void handle_async_input (void) { @@ -7157,7 +7173,9 @@ handle_async_input (void) --handling_signal; #endif } +#endif /* SYNC_INPUT || SIGIO */ +#ifdef SYNC_INPUT void process_pending_signals (void) { @@ -7165,6 +7183,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. */ @@ -7182,7 +7201,7 @@ input_available_signal (int signo) #endif if (input_available_clear_time) - EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); + *input_available_clear_time = make_emacs_time (0, 0); #ifndef SYNC_INPUT handle_async_input (); @@ -7237,7 +7256,7 @@ add_user_signal (int sig, const char *name) /* Already added. */ return; - p = xmalloc (sizeof (struct user_signal_info)); + p = xmalloc (sizeof *p); p->sig = sig; p->name = xstrdup (name); p->npending = 0; @@ -7262,8 +7281,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; @@ -7285,7 +7304,7 @@ handle_user_signal (int sig) /* Tell wait_reading_process_output that it needs to wake up and look around. */ if (input_available_clear_time) - EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); + *input_available_clear_time = make_emacs_time (0, 0); } break; } @@ -7376,7 +7395,7 @@ menu_separator_name_p (const char *label) if (!label) return 0; else if (strlen (label) > 3 - && strncmp (label, "--", 2) == 0 + && memcmp (label, "--", 2) == 0 && label[2] != '-') { int i; @@ -7463,7 +7482,7 @@ menu_bar_items (Lisp_Object old) Lisp_Object tem; ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); - maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); + maps = alloca ((nminor + 3) * sizeof *maps); nmaps = 0; if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem)) maps[nmaps++] = tem; @@ -7496,23 +7515,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; } } @@ -7522,12 +7541,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; } @@ -7553,11 +7572,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; } @@ -7581,11 +7600,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. */ @@ -7593,24 +7612,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); } } @@ -7637,7 +7656,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, @@ -7990,7 +8009,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems) if (!NILP (Voverriding_local_map_menu_flag)) { /* Yes, use them (if non-nil) as well as the global map. */ - maps = (Lisp_Object *) alloca (3 * sizeof (maps[0])); + maps = alloca (3 * sizeof *maps); nmaps = 0; if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map); @@ -8007,7 +8026,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems) Lisp_Object tem; ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); - maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); + maps = alloca ((nminor + 3) * sizeof *maps); nmaps = 0; if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem)) maps[nmaps++] = tem; @@ -8127,7 +8146,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; @@ -8279,7 +8298,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); @@ -8310,7 +8329,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) if (SCHARS (new_lbl) <= tool_bar_max_label_size) PROP (TOOL_BAR_ITEM_LABEL) = new_lbl; else - PROP (TOOL_BAR_ITEM_LABEL) = make_string ("", 0); + PROP (TOOL_BAR_ITEM_LABEL) = empty_unibyte_string; xfree (buf); } @@ -8362,13 +8381,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. */ @@ -8431,8 +8451,7 @@ read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, && !EQ (XCAR (prev_event), Qtool_bar)) { /* Display the menu and get the selection. */ - Lisp_Object *realmaps - = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); + Lisp_Object *realmaps = alloca (nmaps * sizeof *realmaps); Lisp_Object value; ptrdiff_t nmaps1 = 0; @@ -8526,7 +8545,7 @@ read_char_minibuf_menu_prompt (int commandflag, if (width + 4 > read_char_minibuf_menu_width) { read_char_minibuf_menu_text - = (char *) xrealloc (read_char_minibuf_menu_text, width + 4); + = xrealloc (read_char_minibuf_menu_text, width + 4); read_char_minibuf_menu_width = width + 4; } menu = read_char_minibuf_menu_text; @@ -8571,7 +8590,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); @@ -8606,7 +8625,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); @@ -8624,12 +8643,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 @@ -8801,18 +8820,12 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt, next = access_keymap (map, key, 1, 0, 1); - /* Handle symbol with autoload definition. */ - if (SYMBOLP (next) && !NILP (Ffboundp (next)) - && CONSP (XSYMBOL (next)->function) - && EQ (XCAR (XSYMBOL (next)->function), Qautoload)) - do_autoload (XSYMBOL (next)->function, next); - /* Handle a symbol whose function definition is a keymap or an array. */ if (SYMBOLP (next) && !NILP (Ffboundp (next)) && (ARRAYP (XSYMBOL (next)->function) || KEYMAPP (XSYMBOL (next)->function))) - next = XSYMBOL (next)->function; + next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil); /* If the keymap gives a function, not an array, then call the function with one arg and use @@ -8953,15 +8966,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. */ @@ -9053,9 +9066,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, int junk; #endif - struct gcpro outer_gcpro1; + struct gcpro gcpro1; - GCPRO1_VAR (fake_prefixed_keys, outer_gcpro); + GCPRO1 (fake_prefixed_keys); raw_keybuf_count = 0; last_nonmenu_event = Qnil; @@ -9133,8 +9146,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { if (2 > nmaps_allocated) { - submaps = (Lisp_Object *) alloca (2 * sizeof (submaps[0])); - defs = (Lisp_Object *) alloca (2 * sizeof (defs[0])); + submaps = alloca (2 * sizeof *submaps); + defs = alloca (2 * sizeof *defs); nmaps_allocated = 2; } submaps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map); @@ -9143,8 +9156,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { if (2 > nmaps_allocated) { - submaps = (Lisp_Object *) alloca (2 * sizeof (submaps[0])); - defs = (Lisp_Object *) alloca (2 * sizeof (defs[0])); + submaps = alloca (2 * sizeof *submaps); + defs = alloca (2 * sizeof *defs); nmaps_allocated = 2; } submaps[nmaps++] = Voverriding_local_map; @@ -9160,8 +9173,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, if (total > nmaps_allocated) { - submaps = (Lisp_Object *) alloca (total * sizeof (submaps[0])); - defs = (Lisp_Object *) alloca (total * sizeof (defs[0])); + submaps = alloca (total * sizeof *submaps); + defs = alloca (total * sizeof *defs); nmaps_allocated = total; } @@ -9217,7 +9230,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; @@ -9351,7 +9364,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, if (EQ (key, Qt)) { unbind_to (count, Qnil); - UNGCPRO_VAR (outer_gcpro); + UNGCPRO; return -1; } @@ -9399,7 +9412,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; @@ -9477,7 +9491,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; @@ -10049,7 +10064,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, add_command_key (keybuf[t]); } - UNGCPRO_VAR (outer_gcpro); + UNGCPRO; return t; } @@ -10105,7 +10120,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); @@ -10137,7 +10152,7 @@ will read just one key sequence. */) ! NILP (can_return_switch_frame), 0); #if 0 /* The following is fine for code reading a key sequence and - then proceeding with a lenghty computation, but it's not good + then proceeding with a lengthy computation, but it's not good for code reading keys in a loop, like an input method. */ #ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) @@ -10162,7 +10177,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); @@ -10175,7 +10190,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)) { @@ -10189,7 +10204,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); @@ -10254,7 +10269,7 @@ a special event, so ignore the prefix argument and don't clear it. */) struct gcpro gcpro1, gcpro2; GCPRO2 (cmd, prefixarg); - do_autoload (final, cmd); + Fautoload_do_load (final, cmd, Qnil); UNGCPRO; } else @@ -10296,146 +10311,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 @@ -10522,6 +10397,9 @@ if there is a doubt, the value is t. */) || !NILP (Vunread_input_method_events)) return (Qt); + /* Process non-user-visible events (Bug#10195). */ + process_special_events (); + get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW | READABLE_EVENTS_FILTER_EVENTS); @@ -10645,7 +10523,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; } @@ -10727,7 +10605,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; @@ -10783,7 +10661,7 @@ stuff_buffered_input (Lisp_Object stuffstring) if (STRINGP (stuffstring)) { - register EMACS_INT count; + register ptrdiff_t count; p = SDATA (stuffstring); count = SBYTES (stuffstring); @@ -10814,7 +10692,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; @@ -10824,7 +10702,7 @@ set_waiting_for_input (struct timeval *time_to_clear) /* If handle_interrupt was called before and buffered a C-g, make it run again now, to avoid timing error. */ if (!NILP (Vquit_flag)) - quit_throw_to_read_char (); + quit_throw_to_read_char (0); } void @@ -10839,7 +10717,7 @@ clear_waiting_for_input (void) If we have a frame on the controlling tty, we assume that the SIGINT was generated by C-g, so we call handle_interrupt. - Otherwise, the handler kills Emacs. */ + Otherwise, tell QUIT to kill Emacs. */ static void interrupt_signal (int signalnum) /* If we don't have an argument, some */ @@ -10856,12 +10734,10 @@ interrupt_signal (int signalnum) /* If we don't have an argument, some */ if (!terminal) { /* If there are no frames there, let's pretend that we are a - well-behaving UN*X program and quit. We cannot do that while - GC is in progress, though. */ - if (!gc_in_progress) - Fkill_emacs (Qnil); - else - Vquit_flag = Qt; + well-behaving UN*X program and quit. We must not call Lisp + in a signal handler, so tell QUIT to exit when it is + safe. */ + Vquit_flag = Qkill_emacs; } else { @@ -10879,6 +10755,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. @@ -10997,8 +10878,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, @@ -11010,15 +10899,20 @@ handle_interrupt (void) separate event loop thread like W32. */ #ifndef HAVE_NS if (waiting_for_input && !echoing) - quit_throw_to_read_char (); + quit_throw_to_read_char (1); #endif } /* Handle a C-g by making read_char return C-g. */ static void -quit_throw_to_read_char (void) +quit_throw_to_read_char (int from_signal) { + /* When not called from a signal handler it is safe to call + Lisp. */ + if (!from_signal && EQ (Vquit_flag, Qkill_emacs)) + Fkill_emacs (Qnil); + sigfree (); /* Prevent another signal from doing this before we finish. */ clear_waiting_for_input (); @@ -11421,7 +11315,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); + timer_idleness_start_time = invalid_emacs_time (); total_keys = 0; recent_keys_index = 0; kbd_fetch_ptr = kbd_buffer; @@ -11518,7 +11412,7 @@ syms_of_keyboard (void) pending_funcalls = Qnil; staticpro (&pending_funcalls); - Vlispy_mouse_stem = make_pure_c_string ("mouse"); + Vlispy_mouse_stem = build_pure_c_string ("mouse"); staticpro (&Vlispy_mouse_stem); /* Tool-bars. */ @@ -11534,9 +11428,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"); @@ -11607,6 +11498,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"); @@ -11650,7 +11542,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); } @@ -11726,7 +11618,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); @@ -11790,12 +11681,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. @@ -11803,6 +11696,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. @@ -11819,38 +11716,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 @@ -11861,7 +11759,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, @@ -12036,7 +11934,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. @@ -12100,7 +11998,7 @@ This variable is keyboard-local. */); Function key definitions that apply to all terminal devices should go here. If a mapping is defined in both the current `local-function-key-map' binding and this variable, then the local -definition will take precendence. */); +definition will take precedence. */); Vfunction_key_map = Fmake_sparse_keymap (Qnil); DEFVAR_LISP ("key-translation-map", Vkey_translation_map, @@ -12122,19 +12020,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; @@ -12190,7 +12082,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 @@ -12198,7 +12090,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); @@ -12242,10 +12134,20 @@ 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 -receives the special event specifed by this variable, it will try to +receives the special event specified by this variable, it will try to break into the debugger as soon as possible instead of processing the event normally through `special-event-map'. @@ -12254,7 +12156,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 *initial_kboard); init_kboard (initial_kboard); /* Vwindow_system is left at t for now. */ initial_kboard->next_kboard = all_kboards; @@ -12317,10 +12219,14 @@ keys_of_keyboard (void) initial_define_lispy_key (Vspecial_event_map, "config-changed-event", "ignore"); +#if defined (WINDOWSNT) + initial_define_lispy_key (Vspecial_event_map, "language-change", + "ignore"); +#endif } /* Mark the pointers in the kboard objects. - Called by the Fgarbage_collector. */ + Called by Fgarbage_collect. */ void mark_kboards (void) {