X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/0dfe7002a6b6f330b981e2d40f372bf71eeac1df..e573d08ef15f0431ad8289b4242c49826f20efb6:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index bf65df1584..966af69c97 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -107,10 +107,6 @@ static Lisp_Object recent_keys; Lisp_Object this_command_keys; ptrdiff_t this_command_key_count; -/* True after calling Freset_this_command_lengths. - Usually it is false. */ -static bool this_command_key_count_reset; - /* This vector is used as a buffer to record the events that were actually read by read_key_sequence. */ static Lisp_Object raw_keybuf; @@ -124,11 +120,6 @@ static int raw_keybuf_count; that precede this key sequence. */ static ptrdiff_t this_single_command_key_start; -/* Record values of this_command_key_count and echo_length () - before this command was read. */ -static ptrdiff_t before_command_key_count; -static ptrdiff_t before_command_echo_length; - #ifdef HAVE_STACK_OVERFLOW_HANDLING /* For longjmp to recover from C stack overflow. */ @@ -288,18 +279,18 @@ static bool input_was_pending; /* Circular buffer for pre-read keyboard input. */ -static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; +static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE]; /* Pointer to next available character in kbd_buffer. If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next available char is in kbd_buffer[0]. */ -static struct input_event *kbd_fetch_ptr; +static union buffered_input_event *kbd_fetch_ptr; /* Pointer to next place to store character in kbd_buffer. This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next character should go in kbd_buffer[0]. */ -static struct input_event * volatile kbd_store_ptr; +static union buffered_input_event *volatile kbd_store_ptr; /* The above pair of variables forms a "queue empty" flag. When we enqueue a non-hook event, we increment kbd_store_ptr. When we @@ -372,14 +363,9 @@ static bool help_char_p (Lisp_Object); static void save_getcjmp (sys_jmp_buf); static void restore_getcjmp (sys_jmp_buf); static Lisp_Object apply_modifiers (int, Lisp_Object); -static void clear_event (struct input_event *); static void restore_kboard_configuration (int); -#ifdef USABLE_SIGIO -static void deliver_input_available_signal (int signo); -#endif static void handle_interrupt (bool); static _Noreturn void quit_throw_to_read_char (bool); -static void process_special_events (void); static void timer_start_idle (void); static void timer_stop_idle (void); static void timer_resume_idle (void); @@ -391,47 +377,52 @@ static void store_user_signal_events (void); static void kset_echo_string (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (echo_string) = val; + kb->echo_string_ = val; +} +static void +kset_echo_prompt (struct kboard *kb, Lisp_Object val) +{ + kb->echo_prompt_ = val; } static void kset_kbd_queue (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (kbd_queue) = val; + kb->kbd_queue_ = val; } static void kset_keyboard_translate_table (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (Vkeyboard_translate_table) = val; + kb->Vkeyboard_translate_table_ = val; } static void kset_last_prefix_arg (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (Vlast_prefix_arg) = val; + kb->Vlast_prefix_arg_ = val; } static void kset_last_repeatable_command (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (Vlast_repeatable_command) = val; + kb->Vlast_repeatable_command_ = val; } static void kset_local_function_key_map (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (Vlocal_function_key_map) = val; + kb->Vlocal_function_key_map_ = val; } static void kset_overriding_terminal_local_map (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (Voverriding_terminal_local_map) = val; + kb->Voverriding_terminal_local_map_ = val; } static void kset_real_last_command (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (Vreal_last_command) = val; + kb->Vreal_last_command_ = val; } static void kset_system_key_syms (struct kboard *kb, Lisp_Object val) { - kb->INTERNAL_FIELD (system_key_syms) = val; + kb->system_key_syms_ = val; } @@ -446,10 +437,12 @@ echo_add_key (Lisp_Object c) ptrdiff_t size = sizeof initbuf; char *buffer = initbuf; char *ptr = buffer; - Lisp_Object echo_string; + Lisp_Object echo_string = KVAR (current_kboard, echo_string); USE_SAFE_ALLOCA; - echo_string = KVAR (current_kboard, echo_string); + if (STRINGP (echo_string) && SCHARS (echo_string) > 0) + /* Add a space at the end as a separator between keys. */ + ptr++[0] = ' '; /* If someone has passed us a composite event, use its head symbol. */ c = EVENT_HEAD (c); @@ -491,48 +484,12 @@ echo_add_key (Lisp_Object c) ptr += len; } - /* Replace a dash from echo_dash with a space, otherwise add a space - at the end as a separator between keys. */ - AUTO_STRING (space, " "); - if (STRINGP (echo_string) && SCHARS (echo_string) > 1) - { - Lisp_Object last_char, prev_char, idx; - - idx = make_number (SCHARS (echo_string) - 2); - prev_char = Faref (echo_string, idx); - - idx = make_number (SCHARS (echo_string) - 1); - last_char = Faref (echo_string, idx); - - /* We test PREV_CHAR to make sure this isn't the echoing of a - minus-sign. */ - if (XINT (last_char) == '-' && XINT (prev_char) != ' ') - Faset (echo_string, idx, make_number (' ')); - else - echo_string = concat2 (echo_string, space); - } - else if (STRINGP (echo_string) && SCHARS (echo_string) > 0) - echo_string = concat2 (echo_string, space); - kset_echo_string (current_kboard, concat2 (echo_string, make_string (buffer, ptr - buffer))); SAFE_FREE (); } -/* Add C to the echo string, if echoing is going on. C can be a - character or a symbol. */ - -static void -echo_char (Lisp_Object c) -{ - if (current_kboard->immediate_echo) - { - echo_add_key (c); - echo_now (); - } -} - /* Temporarily add a dash to the end of the echo string if it's not empty, so that it serves as a mini-prompt for the very next character. */ @@ -544,16 +501,14 @@ echo_dash (void) if (NILP (KVAR (current_kboard, echo_string))) return; - if (this_command_key_count == 0) - return; - if (!current_kboard->immediate_echo && SCHARS (KVAR (current_kboard, echo_string)) == 0) return; /* Do nothing if we just printed a prompt. */ - if (current_kboard->echo_after_prompt - == SCHARS (KVAR (current_kboard, echo_string))) + if (STRINGP (KVAR (current_kboard, echo_prompt)) + && (SCHARS (KVAR (current_kboard, echo_prompt)) + == SCHARS (KVAR (current_kboard, echo_string)))) return; /* Do nothing if we have already put a dash at the end. */ @@ -579,47 +534,51 @@ echo_dash (void) echo_now (); } -/* Display the current echo string, and begin echoing if not already - doing so. */ - static void -echo_now (void) +echo_update (void) { - if (!current_kboard->immediate_echo) + if (current_kboard->immediate_echo) { ptrdiff_t i; - current_kboard->immediate_echo = 1; + Lisp_Object prompt = KVAR (current_kboard, echo_prompt); + Lisp_Object prefix = call0 (Qinternal_echo_keystrokes_prefix); + kset_echo_string (current_kboard, + NILP (prompt) ? prefix + : NILP (prefix) ? prompt + : concat2 (prompt, prefix)); for (i = 0; i < this_command_key_count; i++) { Lisp_Object c; - /* Set before_command_echo_length to the value that would - have been saved before the start of this subcommand in - command_loop_1, if we had already been echoing then. */ - if (i == this_single_command_key_start) - before_command_echo_length = echo_length (); - c = AREF (this_command_keys, i); if (! (EVENT_HAS_PARAMETERS (c) && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) - echo_char (c); + echo_add_key (c); } - /* Set before_command_echo_length to the value that would - have been saved before the start of this subcommand in - command_loop_1, if we had already been echoing then. */ - if (this_command_key_count == this_single_command_key_start) - before_command_echo_length = echo_length (); + echo_now (); + } +} +/* Display the current echo string, and begin echoing if not already + doing so. */ + +static void +echo_now (void) +{ + if (!current_kboard->immediate_echo) + { + current_kboard->immediate_echo = true; + echo_update (); /* Put a dash at the end to invite the user to type more. */ echo_dash (); } - echoing = 1; + echoing = true; /* FIXME: Use call (Qmessage) so it can be advised (e.g. emacspeak). */ message3_nolog (KVAR (current_kboard, echo_string)); - echoing = 0; + echoing = false; /* Record in what buffer we echoed, and from which kboard. */ echo_message_buffer = echo_area_buffer[0]; @@ -634,8 +593,8 @@ echo_now (void) void cancel_echoing (void) { - current_kboard->immediate_echo = 0; - current_kboard->echo_after_prompt = -1; + current_kboard->immediate_echo = false; + kset_echo_prompt (current_kboard, Qnil); kset_echo_string (current_kboard, Qnil); ok_to_echo_at_next_pause = NULL; echo_kboard = NULL; @@ -671,20 +630,6 @@ echo_truncate (ptrdiff_t nchars) static void add_command_key (Lisp_Object key) { -#if 0 /* Not needed after we made Freset_this_command_lengths - do the job immediately. */ - /* If reset-this-command-length was called recently, obey it now. - See the doc string of that function for an explanation of why. */ - if (before_command_restore_flag) - { - this_command_key_count = before_command_key_count_1; - if (this_command_key_count < this_single_command_key_start) - this_single_command_key_start = this_command_key_count; - echo_truncate (before_command_echo_length_1); - before_command_restore_flag = 0; - } -#endif - if (this_command_key_count >= ASIZE (this_command_keys)) this_command_keys = larger_vector (this_command_keys, 1, -1); @@ -759,7 +704,7 @@ force_auto_save_soon (void) DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "", doc: /* Invoke the editor command loop recursively. To get out of the recursive edit, a command can throw to `exit' -- for -instance `(throw 'exit nil)'. +instance (throw \\='exit nil). If you throw a value other than t, `recursive-edit' returns normally to the function that called it. Throwing a t value causes `recursive-edit' to quit, so that control returns to the command loop @@ -824,11 +769,11 @@ any_kboard_state () { current_kboard->kbd_queue = nconc2 (Vunread_command_events, current_kboard->kbd_queue); - current_kboard->kbd_queue_has_data = 1; + current_kboard->kbd_queue_has_data = true; } Vunread_command_events = Qnil; #endif - single_kboard = 0; + single_kboard = false; } /* Switch to the single-kboard state, making current_kboard @@ -837,7 +782,7 @@ any_kboard_state () void single_kboard_state () { - single_kboard = 1; + single_kboard = true; } #endif @@ -848,7 +793,7 @@ void not_single_kboard_state (KBOARD *kboard) { if (kboard == current_kboard) - single_kboard = 0; + single_kboard = false; } /* Maintain a stack of kboards, so other parts of Emacs @@ -880,13 +825,13 @@ pop_kboard (void) { struct terminal *t; struct kboard_stack *p = kboard_stack; - bool found = 0; + bool found = false; for (t = terminal_list; t; t = t->next_terminal) { if (t->kboard == p->kboard) { current_kboard = p->kboard; - found = 1; + found = true; break; } } @@ -894,7 +839,7 @@ pop_kboard (void) { /* The terminal we remembered has been deleted. */ current_kboard = FRAME_KBOARD (SELECTED_FRAME ()); - single_kboard = 0; + single_kboard = false; } kboard_stack = p->next; xfree (p); @@ -934,7 +879,7 @@ temporarily_switch_to_single_kboard (struct frame *f) } else if (f != NULL) current_kboard = FRAME_KBOARD (f); - single_kboard = 1; + single_kboard = true; record_unwind_protect_int (restore_kboard_configuration, was_locked); } @@ -1097,7 +1042,11 @@ command_loop (void) /* At least on GNU/Linux, saving signal mask is important here. */ if (sigsetjmp (return_to_command_loop, 1) != 0) { - /* Comes here from handle_sigsegv, see sysdep.c. */ + /* Comes here from handle_sigsegv (see sysdep.c) and + stack_overflow_handler (see w32fns.c). */ +#ifdef WINDOWSNT + w32_reset_stack_overflow_guard (); +#endif init_eval (); Vinternal__top_level_message = recover_top_level_message; } @@ -1286,10 +1235,6 @@ static void adjust_point_for_property (ptrdiff_t, bool); /* 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, ... */ - Lisp_Object command_loop_1 (void) { @@ -1303,11 +1248,10 @@ command_loop_1 (void) kset_prefix_arg (current_kboard, Qnil); kset_last_prefix_arg (current_kboard, Qnil); Vdeactivate_mark = Qnil; - waiting_for_input = 0; + waiting_for_input = false; cancel_echoing (); this_command_key_count = 0; - this_command_key_count_reset = 0; this_single_command_key_start = 0; if (NILP (Vmemory_full)) @@ -1395,9 +1339,6 @@ command_loop_1 (void) && !NILP (Ffboundp (Qrecompute_lucid_menubar))) call0 (Qrecompute_lucid_menubar); - before_command_key_count = this_command_key_count; - before_command_echo_length = echo_length (); - Vthis_command = Qnil; Vreal_this_command = Qnil; Vthis_original_command = Qnil; @@ -1425,7 +1366,6 @@ command_loop_1 (void) { cancel_echoing (); this_command_key_count = 0; - this_command_key_count_reset = 0; this_single_command_key_start = 0; goto finalize; } @@ -1510,14 +1450,13 @@ command_loop_1 (void) } #endif - if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why? --Stef */ - { - 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)); - } + { + 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)); + } call1 (Qcommand_execute, Vthis_command); #ifdef HAVE_WINDOW_SYSTEM @@ -1545,31 +1484,23 @@ command_loop_1 (void) safe_run_hooks (Qdeferred_action_function); - /* If there is a prefix argument, - 1) We don't want Vlast_command to be ``universal-argument'' - (that would be dumb), so don't set Vlast_command, - 2) we want to leave echoing on so that the prefix will be - echoed as part of this key sequence, so don't call - cancel_echoing, and - 3) we want to leave this_command_key_count non-zero, so that - read_char will realize that it is re-reading a character, and - not echo it a second time. - - 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)) + kset_last_command (current_kboard, Vthis_command); + kset_real_last_command (current_kboard, Vreal_this_command); + if (!CONSP (last_command_event)) + kset_last_repeatable_command (current_kboard, Vreal_this_command); + + this_command_key_count = 0; + this_single_command_key_start = 0; + + if (current_kboard->immediate_echo + && !NILP (call0 (Qinternal_echo_keystrokes_prefix))) { - kset_last_command (current_kboard, Vthis_command); - kset_real_last_command (current_kboard, Vreal_this_command); - if (!CONSP (last_command_event)) - kset_last_repeatable_command (current_kboard, Vreal_this_command); - cancel_echoing (); - this_command_key_count = 0; - this_command_key_count_reset = 0; - this_single_command_key_start = 0; + current_kboard->immediate_echo = false; + /* Refresh the echo message. */ + echo_now (); } + else + cancel_echoing (); if (!NILP (BVAR (current_buffer, mark_active)) && !NILP (Vrun_hooks)) @@ -1618,6 +1549,7 @@ command_loop_1 (void) finalize: if (current_buffer == prev_buffer + && XBUFFER (XWINDOW (selected_window)->contents) == current_buffer && last_point_position != PT && NILP (Vdisable_point_adjustment) && NILP (Vglobal_disable_point_adjustment)) @@ -1683,9 +1615,12 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) suppress the point adjustment for automatic composition so that a user can keep inserting another character at point or keep deleting characters around point. */ - bool check_composition = ! modified, check_display = 1, check_invisible = 1; + bool check_composition = ! modified; + bool check_display = true, check_invisible = true; ptrdiff_t orig_pt = PT; + eassert (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer); + /* FIXME: cycling is probably not necessary because these properties can't be usefully combined anyway. */ while (check_composition || check_display || check_invisible) @@ -1696,13 +1631,14 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) && (beg = composition_adjust_point (last_pt, PT)) != PT) { SET_PT (beg); - check_display = check_invisible = 1; + check_display = check_invisible = true; } - check_composition = 0; + check_composition = false; if (check_display && PT > BEGV && PT < ZV && !NILP (val = get_char_property_and_overlay - (make_number (PT), Qdisplay, Qnil, &overlay)) + (make_number (PT), Qdisplay, selected_window, + &overlay)) && display_prop_intangible_p (val, overlay, PT, PT_BYTE) && (!OVERLAYP (overlay) ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil) @@ -1717,13 +1653,13 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) ? max (beg - 1, BEGV) : beg) : end); - check_composition = check_invisible = 1; + check_composition = check_invisible = true; } - check_display = 0; + check_display = false; if (check_invisible && PT > BEGV && PT < ZV) { int inv; - bool ellipsis = 0; + bool ellipsis = false; beg = end = PT; /* Find boundaries `beg' and `end' of the invisible area, if any. */ @@ -1789,7 +1725,7 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) was already in the range: we don't get to choose which end of the range we have to go to. */ : (PT < last_pt ? beg : end)); - check_composition = check_display = 1; + check_composition = check_display = true; } #if 0 /* This assertion isn't correct, because SET_PT may end up setting the point to something other than its argument, due to @@ -1802,9 +1738,9 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) if (!modified && !ellipsis && beg < end) { if (last_pt == beg && PT == end && end < ZV) - (check_composition = check_display = 1, SET_PT (end + 1)); + (check_composition = check_display = true, SET_PT (end + 1)); else if (last_pt == end && PT == beg && beg > BEGV) - (check_composition = check_display = 1, SET_PT (beg - 1)); + (check_composition = check_display = true, SET_PT (beg - 1)); else if (PT == ((PT < last_pt) ? beg : end)) /* We've already moved as far as we can. Trying to go to the other end would mean moving backwards and thus @@ -1817,11 +1753,11 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) (make_number (PT == beg ? end : beg), Qinvisible, Qnil)), !TEXT_PROP_MEANS_INVISIBLE (val))) - (check_composition = check_display = 1, + (check_composition = check_display = true, SET_PT (PT == beg ? end : beg)); } } - check_invisible = 0; + check_invisible = false; } } @@ -1849,11 +1785,11 @@ safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) if (SYMBOLP (hook)) { Lisp_Object val; - bool found = 0; + bool found = false; Lisp_Object newval = Qnil; for (val = find_symbol_value (hook); CONSP (val); val = XCDR (val)) if (EQ (fun, XCAR (val))) - found = 1; + found = true; else newval = Fcons (XCAR (val), newval); if (found) @@ -1865,7 +1801,7 @@ safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) : Fdefault_value (hook)); CONSP (val); val = XCDR (val)) if (EQ (fun, XCAR (val))) - found = 1; + found = true; else newval = Fcons (XCAR (val), newval); if (found) @@ -1892,14 +1828,11 @@ safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args) void safe_run_hooks (Lisp_Object hook) { - struct gcpro gcpro1; ptrdiff_t count = SPECPDL_INDEX (); - GCPRO1 (hook); specbind (Qinhibit_quit, Qt); run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), safe_run_hook_funcall); unbind_to (count, Qnil); - UNGCPRO; } @@ -1930,7 +1863,7 @@ static void poll_for_input (struct atimer *timer) { if (poll_suppress_count == 0) - pending_signals = 1; + pending_signals = true; } #endif /* POLL_FOR_INPUT */ @@ -2134,13 +2067,13 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, struct frame *f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved (); help = call1 (Qmouse_fixup_help_message, help); if (f) - f->mouse_moved = 1; + f->mouse_moved = true; } if (STRINGP (help) || NILP (help)) { if (!NILP (Vshow_help_function)) - call1 (Vshow_help_function, help); + call1 (Vshow_help_function, Fsubstitute_command_keys (help)); help_echo_showing_p = STRINGP (help); } } @@ -2165,11 +2098,11 @@ read_char_help_form_unwind (void) #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ - polling_stopped_here = 1; } while (0) + polling_stopped_here = true; } while (0) #define RESUME_POLLING \ do { if (polling_stopped_here) start_polling (); \ - polling_stopped_here = 0; } while (0) + polling_stopped_here = false; } while (0) static Lisp_Object read_event_from_main_queue (struct timespec *end_time, @@ -2192,7 +2125,7 @@ read_event_from_main_queue (struct timespec *end_time, save_getcjmp (save_jump); restore_getcjmp (local_getcjmp); if (!end_time) - timer_start_idle (); + timer_start_idle (); c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time); restore_getcjmp (save_jump); @@ -2210,13 +2143,11 @@ read_event_from_main_queue (struct timespec *end_time, kset_kbd_queue (kb, list1 (c)); else XSETCDR (last, list1 (c)); - kb->kbd_queue_has_data = 1; + kb->kbd_queue_has_data = true; c = Qnil; if (single_kboard) goto start; current_kboard = kb; - /* This is going to exit from read_char - so we had better get rid of this frame's stuff. */ return make_number (-2); } @@ -2384,24 +2315,19 @@ read_char (int commandflag, Lisp_Object map, Lisp_Object tem, save; volatile Lisp_Object previous_echo_area_message; volatile Lisp_Object also_record; - volatile bool reread; - struct gcpro gcpro1, gcpro2; - bool volatile polling_stopped_here = 0; + volatile bool reread, recorded; + bool volatile polling_stopped_here = false; struct kboard *orig_kboard = current_kboard; also_record = Qnil; -#if 0 /* This was commented out as part of fixing echo for C-u left. */ - before_command_key_count = this_command_key_count; - before_command_echo_length = echo_length (); -#endif c = Qnil; previous_echo_area_message = Qnil; - GCPRO2 (c, previous_echo_area_message); - retry: + recorded = false; + if (CONSP (Vunread_post_input_method_events)) { c = XCAR (Vunread_post_input_method_events); @@ -2424,7 +2350,7 @@ read_char (int commandflag, Lisp_Object map, if (CONSP (Vunread_command_events)) { - bool was_disabled = 0; + bool was_disabled = false; c = XCAR (Vunread_command_events); Vunread_command_events = XCDR (Vunread_command_events); @@ -2443,7 +2369,7 @@ read_char (int commandflag, Lisp_Object map, && EQ (XCDR (c), Qdisabled) && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c)))) { - was_disabled = 1; + was_disabled = true; c = XCAR (c); } @@ -2453,7 +2379,7 @@ read_char (int commandflag, Lisp_Object map, /* Also check was_disabled so last-nonmenu-event won't return a bad value when submenus are involved. (Bug#447) */ && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar) || was_disabled)) - *used_mouse_menu = 1; + *used_mouse_menu = true; goto reread_for_input_method; } @@ -2473,8 +2399,6 @@ read_char (int commandflag, Lisp_Object map, goto reread_for_input_method; } - this_command_key_count_reset = 0; - if (!NILP (Vexecuting_kbd_macro)) { /* We set this to Qmacro; since that's not a frame, nobody will @@ -2572,7 +2496,7 @@ read_char (int commandflag, Lisp_Object map, (3) There's only one place in 20.x where ok_to_echo_at_next_pause is set to a non-null value. This is done in read_char and it is - set to echo_area_glyphs after a call to echo_char. That means + set to echo_area_glyphs. That means ok_to_echo_at_next_pause is either null or current_kboard->echobuf with the appropriate current_kboard at that time. @@ -2655,11 +2579,8 @@ read_char (int commandflag, Lisp_Object map, kset_kbd_queue (kb, list1 (c)); else XSETCDR (last, list1 (c)); - kb->kbd_queue_has_data = 1; + kb->kbd_queue_has_data = true; current_kboard = kb; - /* This is going to exit from read_char - so we had better get rid of this frame's stuff. */ - UNGCPRO; return make_number (-2); /* wrong_kboard_jmpbuf */ } } @@ -2679,7 +2600,8 @@ read_char (int commandflag, Lisp_Object map, if (minibuf_level == 0 && !end_time && !current_kboard->immediate_echo - && this_command_key_count > 0 + && (this_command_key_count > 0 + || !NILP (call0 (Qinternal_echo_keystrokes_prefix))) && ! noninteractive && echo_keystrokes_p () && (/* No message. */ @@ -2801,10 +2723,7 @@ read_char (int commandflag, Lisp_Object map, interpret the next key sequence using the wrong translation tables and function keymaps. */ if (NILP (c) && current_kboard != orig_kboard) - { - UNGCPRO; - return make_number (-2); /* wrong_kboard_jmpbuf */ - } + return make_number (-2); /* wrong_kboard_jmpbuf */ /* If this has become non-nil here, it has been set by a timer or sentinel or filter. */ @@ -2831,7 +2750,7 @@ read_char (int commandflag, Lisp_Object map, kset_kbd_queue (current_kboard, XCDR (KVAR (current_kboard, kbd_queue))); if (NILP (KVAR (current_kboard, kbd_queue))) - current_kboard->kbd_queue_has_data = 0; + current_kboard->kbd_queue_has_data = false; input_pending = readable_events (0); if (EVENT_HAS_PARAMETERS (c) && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame)) @@ -2855,9 +2774,6 @@ read_char (int commandflag, Lisp_Object map, if (kb->kbd_queue_has_data) { current_kboard = kb; - /* This is going to exit from read_char - so we had better get rid of this frame's stuff. */ - UNGCPRO; return make_number (-2); /* wrong_kboard_jmpbuf */ } } @@ -2877,12 +2793,7 @@ read_char (int commandflag, Lisp_Object map, } if (EQ (c, make_number (-2))) - { - /* This is going to exit from read_char - so we had better get rid of this frame's stuff. */ - UNGCPRO; - return c; - } + return c; } non_reread: @@ -2991,6 +2902,7 @@ read_char (int commandflag, Lisp_Object map, /* Store these characters into recent_keys, the dribble file if any, and the keyboard macro being defined, if any. */ record_char (c); + recorded = true; if (! NILP (also_record)) record_char (also_record); @@ -3033,42 +2945,26 @@ read_char (int commandflag, Lisp_Object map, { Lisp_Object keys; ptrdiff_t key_count; - bool key_count_reset; ptrdiff_t command_key_start; - struct gcpro gcpro1; ptrdiff_t count = SPECPDL_INDEX (); /* Save the echo status. */ bool saved_immediate_echo = current_kboard->immediate_echo; struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause; Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string); - ptrdiff_t saved_echo_after_prompt = current_kboard->echo_after_prompt; - -#if 0 - if (before_command_restore_flag) - { - this_command_key_count = before_command_key_count_1; - if (this_command_key_count < this_single_command_key_start) - this_single_command_key_start = this_command_key_count; - echo_truncate (before_command_echo_length_1); - before_command_restore_flag = 0; - } -#endif + Lisp_Object saved_echo_prompt = KVAR (current_kboard, echo_prompt); /* Save the this_command_keys status. */ key_count = this_command_key_count; - key_count_reset = this_command_key_count_reset; command_key_start = this_single_command_key_start; if (key_count > 0) keys = Fcopy_sequence (this_command_keys); else keys = Qnil; - GCPRO1 (keys); /* Clear out this_command_keys. */ this_command_key_count = 0; - this_command_key_count_reset = 0; this_single_command_key_start = 0; /* Now wipe the echo area. */ @@ -3092,27 +2988,17 @@ read_char (int commandflag, Lisp_Object map, /* Restore the saved echoing state and this_command_keys state. */ this_command_key_count = key_count; - this_command_key_count_reset = key_count_reset; this_single_command_key_start = command_key_start; if (key_count > 0) this_command_keys = keys; cancel_echoing (); ok_to_echo_at_next_pause = saved_ok_to_echo; - /* Do not restore the echo area string when the user is - introducing a prefix argument. Otherwise we end with - repetitions of the partially introduced prefix - argument. (bug#19875) */ - if (NILP (intern ("prefix-arg"))) - { - kset_echo_string (current_kboard, saved_echo_string); - } - current_kboard->echo_after_prompt = saved_echo_after_prompt; + kset_echo_string (current_kboard, saved_echo_string); + kset_echo_prompt (current_kboard, saved_echo_prompt); if (saved_immediate_echo) echo_now (); - UNGCPRO; - /* The input method can return no events. */ if (! CONSP (tem)) { @@ -3126,6 +3012,14 @@ read_char (int commandflag, Lisp_Object map, Vunread_post_input_method_events = nconc2 (XCDR (tem), Vunread_post_input_method_events); } + /* When we consume events from the various unread-*-events lists, we + bypass the code that records input, so record these events now if + they were not recorded already. */ + if (!recorded) + { + record_char (c); + recorded = true; + } reread_first: @@ -3152,28 +3046,23 @@ read_char (int commandflag, Lisp_Object map, goto retry; } - if ((! reread || this_command_key_count == 0 - || this_command_key_count_reset) + if ((! reread || this_command_key_count == 0) && !end_time) { /* Don't echo mouse motion events. */ - if (echo_keystrokes_p () - && ! (EVENT_HAS_PARAMETERS (c) - && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) - { - echo_char (c); - if (! NILP (also_record)) - echo_char (also_record); - /* Once we reread a character, echoing can happen - the next time we pause to read a new one. */ - ok_to_echo_at_next_pause = current_kboard; - } + if (! (EVENT_HAS_PARAMETERS (c) + && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) + /* Once we reread a character, echoing can happen + the next time we pause to read a new one. */ + ok_to_echo_at_next_pause = current_kboard; /* Record this character as part of the current key. */ add_command_key (c); if (! NILP (also_record)) add_command_key (also_record); + + echo_update (); } last_input_event = c; @@ -3215,7 +3104,7 @@ read_char (int commandflag, Lisp_Object map, exit: RESUME_POLLING; input_was_pending = input_pending; - RETURN_UNGCPRO (c); + return c; } /* Record a key that came from a mouse menu. @@ -3229,23 +3118,13 @@ record_menu_key (Lisp_Object c) record_char (c); -#if 0 - before_command_key_count = this_command_key_count; - before_command_echo_length = echo_length (); -#endif - - /* Don't echo mouse motion events. */ - if (echo_keystrokes_p ()) - { - echo_char (c); - - /* Once we reread a character, echoing can happen - the next time we pause to read a new one. */ - ok_to_echo_at_next_pause = 0; - } + /* Once we reread a character, echoing can happen + the next time we pause to read a new one. */ + ok_to_echo_at_next_pause = NULL; /* Record this character as part of the current key. */ add_command_key (c); + echo_update (); /* Re-reading in the middle of a command. */ last_input_event = c; @@ -3442,7 +3321,7 @@ readable_events (int flags) #endif )) { - struct input_event *event; + union buffered_input_event *event; event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) ? kbd_fetch_ptr @@ -3459,8 +3338,8 @@ readable_events (int flags) && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && (event->kind == SCROLL_BAR_CLICK_EVENT || event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT) - && event->part == scroll_bar_handle - && event->modifiers == 0) + && event->ie.part == scroll_bar_handle + && event->ie.modifiers == 0) #endif && !((flags & READABLE_EVENTS_FILTER_EVENTS) && event->kind == BUFFER_SWITCH_EVENT)) @@ -3547,8 +3426,8 @@ kbd_buffer_store_event (register struct input_event *event) subsequent input events have been parsed (and discarded). */ void -kbd_buffer_store_event_hold (register struct input_event *event, - struct input_event *hold_quit) +kbd_buffer_store_buffered_event (union buffered_input_event *event, + struct input_event *hold_quit) { if (event->kind == NO_EVENT) emacs_abort (); @@ -3558,36 +3437,36 @@ kbd_buffer_store_event_hold (register struct input_event *event, if (event->kind == ASCII_KEYSTROKE_EVENT) { - register int c = event->code & 0377; + int c = event->ie.code & 0377; - if (event->modifiers & ctrl_modifier) + if (event->ie.modifiers & ctrl_modifier) c = make_ctrl_char (c); - c |= (event->modifiers + c |= (event->ie.modifiers & (meta_modifier | alt_modifier | hyper_modifier | super_modifier)); if (c == quit_char) { - KBOARD *kb = FRAME_KBOARD (XFRAME (event->frame_or_window)); - struct input_event *sp; + KBOARD *kb = FRAME_KBOARD (XFRAME (event->ie.frame_or_window)); if (single_kboard && kb != current_kboard) { kset_kbd_queue - (kb, list2 (make_lispy_switch_frame (event->frame_or_window), + (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window), make_number (c))); - kb->kbd_queue_has_data = 1; + kb->kbd_queue_has_data = true; + union buffered_input_event *sp; for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) { if (sp == kbd_buffer + KBD_BUFFER_SIZE) sp = kbd_buffer; - if (event_to_kboard (sp) == kb) + if (event_to_kboard (&sp->ie) == kb) { - sp->kind = NO_EVENT; - sp->frame_or_window = Qnil; - sp->arg = Qnil; + sp->ie.kind = NO_EVENT; + sp->ie.frame_or_window = Qnil; + sp->ie.arg = Qnil; } } return; @@ -3595,7 +3474,7 @@ kbd_buffer_store_event_hold (register struct input_event *event, if (hold_quit) { - *hold_quit = *event; + *hold_quit = event->ie; return; } @@ -3606,9 +3485,9 @@ kbd_buffer_store_event_hold (register struct input_event *event, { Lisp_Object focus; - focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window)); + focus = FRAME_FOCUS_FRAME (XFRAME (event->ie.frame_or_window)); if (NILP (focus)) - focus = event->frame_or_window; + focus = event->ie.frame_or_window; internal_last_event_frame = focus; Vlast_event_frame = focus; } @@ -3650,8 +3529,7 @@ kbd_buffer_store_event_hold (register struct input_event *event, /* Don't read keyboard input until we have processed kbd_buffer. This happens when pasting text longer than KBD_BUFFER_SIZE/2. */ hold_keyboard_input (); - if (!noninteractive) - ignore_sigio (); + unrequest_sigio (); stop_polling (); } #endif /* subprocesses */ @@ -3671,29 +3549,34 @@ kbd_buffer_store_event_hold (register struct input_event *event, do it now. */ if (immediate_quit && NILP (Vinhibit_quit)) { - immediate_quit = 0; + immediate_quit = false; QUIT; } } } -/* Put an input event back in the head of the event queue. */ +#ifdef HAVE_X11 + +/* Put a selection input event back in the head of the event queue. */ void -kbd_buffer_unget_event (register struct input_event *event) +kbd_buffer_unget_event (struct selection_input_event *event) { if (kbd_fetch_ptr == kbd_buffer) kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE; /* Don't let the very last slot in the buffer become full, */ - if (kbd_fetch_ptr - 1 != kbd_store_ptr) + union buffered_input_event *kp = kbd_fetch_ptr - 1; + if (kp != kbd_store_ptr) { - --kbd_fetch_ptr; - *kbd_fetch_ptr = *event; + kp->sie = *event; + kbd_fetch_ptr = kp; } } +#endif + /* Limit help event positions to this range, to avoid overflow problems. */ #define INPUT_EVENT_POS_MAX \ ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \ @@ -3772,7 +3655,7 @@ kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help) void discard_mouse_events (void) { - struct input_event *sp; + union buffered_input_event *sp; for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) { if (sp == kbd_buffer + KBD_BUFFER_SIZE) @@ -3802,7 +3685,7 @@ discard_mouse_events (void) bool kbd_buffer_events_waiting (void) { - struct input_event *sp; + union buffered_input_event *sp; for (sp = kbd_fetch_ptr; sp != kbd_store_ptr && sp->kind == NO_EVENT; @@ -3820,7 +3703,7 @@ kbd_buffer_events_waiting (void) /* Clear input event EVENT. */ static void -clear_event (struct input_event *event) +clear_event (union buffered_input_event *event) { event->kind = NO_EVENT; } @@ -3845,6 +3728,7 @@ kbd_buffer_get_event (KBOARD **kbp, /* Start reading input again because we have processed enough to be able to accept new events again. */ unhold_keyboard_input (); + request_sigio (); start_polling (); } #endif /* subprocesses */ @@ -3941,13 +3825,13 @@ kbd_buffer_get_event (KBOARD **kbp, mouse movement enabled and available. */ if (kbd_fetch_ptr != kbd_store_ptr) { - struct input_event *event; + union buffered_input_event *event; event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) ? kbd_fetch_ptr : kbd_buffer); - *kbp = event_to_kboard (event); + *kbp = event_to_kboard (&event->ie); if (*kbp == 0) *kbp = current_kboard; /* Better than returning null ptr? */ @@ -3960,12 +3844,10 @@ kbd_buffer_get_event (KBOARD **kbp, || event->kind == SELECTION_CLEAR_EVENT) { #ifdef HAVE_X11 - struct input_event copy; - /* Remove it from the buffer before processing it, since otherwise swallow_events will see it and process it again. */ - copy = *event; + struct selection_input_event copy = event->sie; kbd_fetch_ptr = event + 1; input_pending = readable_events (0); x_handle_selection_event (©); @@ -3979,13 +3861,13 @@ kbd_buffer_get_event (KBOARD **kbp, #if defined (HAVE_NS) else if (event->kind == NS_TEXT_EVENT) { - if (event->code == KEY_NS_PUT_WORKING_TEXT) + if (event->ie.code == KEY_NS_PUT_WORKING_TEXT) obj = list1 (intern ("ns-put-working-text")); else obj = list1 (intern ("ns-unput-working-text")); kbd_fetch_ptr = event + 1; if (used_mouse_menu) - *used_mouse_menu = 1; + *used_mouse_menu = true; } #endif @@ -3994,7 +3876,7 @@ kbd_buffer_get_event (KBOARD **kbp, else if (event->kind == DELETE_WINDOW_EVENT) { /* Make an event (delete-frame (FRAME)). */ - obj = list2 (Qdelete_frame, list1 (event->frame_or_window)); + obj = list2 (Qdelete_frame, list1 (event->ie.frame_or_window)); kbd_fetch_ptr = event + 1; } #endif @@ -4003,13 +3885,13 @@ kbd_buffer_get_event (KBOARD **kbp, else if (event->kind == ICONIFY_EVENT) { /* Make an event (iconify-frame (FRAME)). */ - obj = list2 (Qiconify_frame, list1 (event->frame_or_window)); + obj = list2 (Qiconify_frame, list1 (event->ie.frame_or_window)); kbd_fetch_ptr = event + 1; } else if (event->kind == DEICONIFY_EVENT) { /* Make an event (make-frame-visible (FRAME)). */ - obj = list2 (Qmake_frame_visible, list1 (event->frame_or_window)); + obj = list2 (Qmake_frame_visible, list1 (event->ie.frame_or_window)); kbd_fetch_ptr = event + 1; } #endif @@ -4025,8 +3907,8 @@ kbd_buffer_get_event (KBOARD **kbp, { kbd_fetch_ptr = event + 1; input_pending = readable_events (0); - if (FRAME_LIVE_P (XFRAME (event->frame_or_window))) - x_activate_menubar (XFRAME (event->frame_or_window)); + if (FRAME_LIVE_P (XFRAME (event->ie.frame_or_window))) + x_activate_menubar (XFRAME (event->ie.frame_or_window)); } #endif #ifdef HAVE_NTGUI @@ -4034,9 +3916,9 @@ kbd_buffer_get_event (KBOARD **kbp, { /* Make an event (language-change FRAME CODEPAGE LANGUAGE-ID). */ obj = list4 (Qlanguage_change, - event->frame_or_window, - make_number (event->code), - make_number (event->modifiers)); + event->ie.frame_or_window, + make_number (event->ie.code), + make_number (event->ie.modifiers)); kbd_fetch_ptr = event + 1; } #endif @@ -4045,16 +3927,16 @@ kbd_buffer_get_event (KBOARD **kbp, { #ifdef HAVE_W32NOTIFY /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */ - obj = list3 (Qfile_notify, event->arg, event->frame_or_window); + obj = list3 (Qfile_notify, event->ie.arg, event->ie.frame_or_window); #else - obj = make_lispy_event (event); + obj = make_lispy_event (&event->ie); #endif kbd_fetch_ptr = event + 1; } #endif /* USE_FILE_NOTIFY */ else if (event->kind == SAVE_SESSION_EVENT) { - obj = list2 (Qsave_session, event->arg); + obj = list2 (Qsave_session, event->ie.arg); kbd_fetch_ptr = event + 1; } /* Just discard these, by returning nil. @@ -4071,11 +3953,11 @@ kbd_buffer_get_event (KBOARD **kbp, { Lisp_Object object, position, help, frame, window; - frame = event->frame_or_window; - object = event->arg; - position = make_number (Time_to_position (event->timestamp)); - window = event->x; - help = event->y; + frame = event->ie.frame_or_window; + object = event->ie.arg; + position = make_number (Time_to_position (event->ie.timestamp)); + window = event->ie.x; + help = event->ie.y; clear_event (event); kbd_fetch_ptr = event + 1; @@ -4091,14 +3973,14 @@ kbd_buffer_get_event (KBOARD **kbp, switch-frame event if necessary. */ Lisp_Object frame, focus; - frame = event->frame_or_window; + frame = event->ie.frame_or_window; focus = FRAME_FOCUS_FRAME (XFRAME (frame)); if (FRAMEP (focus)) frame = focus; if ( #ifdef HAVE_X11 - ! NILP (event->arg) + ! NILP (event->ie.arg) && #endif !EQ (frame, internal_last_event_frame) @@ -4115,7 +3997,7 @@ kbd_buffer_get_event (KBOARD **kbp, #ifdef HAVE_WINDOW_SYSTEM Display_Info *di; - Lisp_Object frame = event->frame_or_window; + Lisp_Object frame = event->ie.frame_or_window; bool focused = false; for (di = x_display_list; di && ! focused; di = di->next) @@ -4131,13 +4013,13 @@ kbd_buffer_get_event (KBOARD **kbp, #ifdef HAVE_DBUS else if (event->kind == DBUS_EVENT) { - obj = make_lispy_event (event); + obj = make_lispy_event (&event->ie); kbd_fetch_ptr = event + 1; } #endif else if (event->kind == CONFIG_CHANGED_EVENT) { - obj = make_lispy_event (event); + obj = make_lispy_event (&event->ie); kbd_fetch_ptr = event + 1; } else @@ -4147,7 +4029,7 @@ kbd_buffer_get_event (KBOARD **kbp, Lisp_Object frame; Lisp_Object focus; - frame = event->frame_or_window; + frame = event->ie.frame_or_window; if (CONSP (frame)) frame = XCAR (frame); else if (WINDOWP (frame)) @@ -4167,7 +4049,7 @@ kbd_buffer_get_event (KBOARD **kbp, if (NILP (obj)) { - obj = make_lispy_event (event); + obj = make_lispy_event (&event->ie); #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ || defined (HAVE_NS) || defined (USE_GTK) @@ -4177,16 +4059,16 @@ kbd_buffer_get_event (KBOARD **kbp, beginning of the menu sequence, and we might as well leave that as the `event with parameters' for this selection. */ if (used_mouse_menu - && !EQ (event->frame_or_window, event->arg) + && !EQ (event->ie.frame_or_window, event->ie.arg) && (event->kind == MENU_BAR_EVENT || event->kind == TOOL_BAR_EVENT)) - *used_mouse_menu = 1; + *used_mouse_menu = true; #endif #ifdef HAVE_NS /* Certain system events are non-key events. */ if (used_mouse_menu && event->kind == NS_NONKEY_EVENT) - *used_mouse_menu = 1; + *used_mouse_menu = true; #endif /* Wipe out this event, to catch bugs. */ @@ -4257,7 +4139,7 @@ kbd_buffer_get_event (KBOARD **kbp, static void process_special_events (void) { - struct input_event *event; + union buffered_input_event *event; for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event) { @@ -4280,23 +4162,22 @@ process_special_events (void) between kbd_fetch_ptr and EVENT one slot to the right, cyclically. */ - struct input_event copy = *event; - struct input_event *beg + struct selection_input_event copy = event->sie; + union buffered_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)); + memmove (beg + 1, beg, (event - beg) * sizeof *beg); else if (event < beg) { if (event > kbd_buffer) memmove (kbd_buffer + 1, kbd_buffer, - (event - kbd_buffer) * sizeof (struct input_event)); + (event - kbd_buffer) * sizeof *kbd_buffer); *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)); + (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) * sizeof *beg); } if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) @@ -4368,9 +4249,6 @@ timer_resume_idle (void) timer_idleness_start_time = timer_last_idleness_start_time; } -/* This is only for debugging. */ -struct input_event last_timer_event EXTERNALLY_VISIBLE; - /* List of elisp functions to call, delayed because they were generated in a context where Elisp could not be safely run (e.g. redisplay, signal, ...). Each element has the form (FUN . ARGS). */ @@ -4417,12 +4295,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) struct timespec now; struct timespec idleness_now; Lisp_Object chosen_timer; - struct gcpro gcpro1; nexttime = invalid_timespec (); chosen_timer = Qnil; - GCPRO1 (chosen_timer); /* First run the code that was delayed. */ while (CONSP (pending_funcalls)) @@ -4547,14 +4423,12 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) /* When we encounter a timer that is still waiting, return the amount of time to wait before it is ripe. */ { - UNGCPRO; return difference; } } /* No timers are pending in the future. */ /* Return 0 if we generated an event, and -1 if not. */ - UNGCPRO; return nexttime; } @@ -4573,7 +4447,6 @@ timer_check (void) { struct timespec nexttime; Lisp_Object timers, idle_timers; - struct gcpro gcpro1, gcpro2; Lisp_Object tem = Vinhibit_quit; Vinhibit_quit = Qt; @@ -4592,15 +4465,12 @@ timer_check (void) Vinhibit_quit = tem; - GCPRO2 (timers, idle_timers); - do { nexttime = timer_check_2 (timers, idle_timers); } while (nexttime.tv_sec == 0 && nexttime.tv_nsec == 0); - UNGCPRO; return nexttime; } @@ -6228,6 +6098,10 @@ parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end) case 't': MULTI_LETTER_MOD (triple_modifier, "triple", 6); break; + + case 'u': + MULTI_LETTER_MOD (up_modifier, "up", 2); + break; #undef MULTI_LETTER_MOD } @@ -6275,16 +6149,19 @@ 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[sizeof "A-C-H-M-S-s-down-drag-double-triple-"]; + char new_mods[sizeof "A-C-H-M-S-s-up-down-drag-double-triple-"]; int mod_len; { char *p = new_mods; - /* Only the event queue may use the `up' modifier; it should always - be turned into a click or drag event before presented to lisp code. */ - if (modifiers & up_modifier) - emacs_abort (); + /* Mouse events should not exhibit the `up' modifier once they + leave the event queue only accessible to C code; `up' will + always be turned into a click or drag event before being + presented to lisp code. But since lisp events can be + synthesized bypassing the event queue and pushed into + `unread-command-events' or its companions, it's better to just + deal with unexpected modifier combinations. */ if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; } if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } @@ -6294,6 +6171,7 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_ if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; } if (modifiers & double_modifier) p = stpcpy (p, "double-"); if (modifiers & triple_modifier) p = stpcpy (p, "triple-"); + if (modifiers & up_modifier) p = stpcpy (p, "up-"); if (modifiers & down_modifier) p = stpcpy (p, "down-"); if (modifiers & drag_modifier) p = stpcpy (p, "drag-"); /* The click modifier is denoted by the absence of other modifiers. */ @@ -6413,8 +6291,7 @@ DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers, BASE must be unmodified. This is like apply_modifiers_uncached, but uses BASE's - Qmodifier_cache property, if present. It also builds - Qevent_symbol_elements properties, since it has that info anyway. + Qmodifier_cache property, if present. apply_modifiers copies the value of BASE's Qevent_kind property to the modified symbol. */ @@ -6760,6 +6637,10 @@ parse_solitary_modifier (Lisp_Object symbol) MULTI_LETTER_MOD (triple_modifier, "triple", 6); break; + case 'u': + MULTI_LETTER_MOD (up_modifier, "up", 2); + break; + #undef SINGLE_LETTER_MOD #undef MULTI_LETTER_MOD } @@ -6872,7 +6753,7 @@ int gobble_input (void) { int nread = 0; - bool err = 0; + bool err = false; struct terminal *t; /* Store pending user signal events, if any. */ @@ -6891,7 +6772,7 @@ gobble_input (void) if (input_blocked_p ()) { - pending_signals = 1; + pending_signals = true; break; } @@ -6904,7 +6785,7 @@ gobble_input (void) if (nr == -1) /* Not OK to read input now. */ { - err = 1; + err = true; } else if (nr == -2) /* Non-transient error. */ { @@ -7164,7 +7045,7 @@ handle_async_input (void) void process_pending_signals (void) { - pending_signals = 0; + pending_signals = false; handle_async_input (); do_pending_atimers (); } @@ -7216,7 +7097,7 @@ totally_unblock_input (void) void handle_input_available_signal (int sig) { - pending_signals = 1; + pending_signals = true; if (input_available_clear_time) *input_available_clear_time = make_timespec (0, 0); @@ -7287,8 +7168,8 @@ handle_user_signal (int sig) && strcmp (special_event_name, p->name) == 0) { /* Enter the debugger in many ways. */ - debug_on_next_call = 1; - debug_on_quit = 1; + debug_on_next_call = true; + debug_on_quit = true; Vquit_flag = Qt; Vinhibit_quit = Qnil; @@ -7335,7 +7216,7 @@ store_user_signal_events (void) { struct user_signal_info *p; struct input_event buf; - bool buf_initialized = 0; + bool buf_initialized = false; for (p = user_signals; p; p = p->next) if (p->npending > 0) @@ -7345,7 +7226,7 @@ store_user_signal_events (void) memset (&buf, 0, sizeof buf); buf.kind = USER_SIGNAL_EVENT; buf.frame_or_window = selected_frame; - buf_initialized = 1; + buf_initialized = true; } do @@ -7483,18 +7364,19 @@ menu_bar_items (Lisp_Object old) properties may not work reliable, as they are only recognized when the menu-bar (or mode-line) is updated, which does not normally happen after every command. */ - Lisp_Object tem; - ptrdiff_t nminor; - nminor = current_minor_maps (NULL, &tmaps); + ptrdiff_t nminor = current_minor_maps (NULL, &tmaps); SAFE_NALLOCA (maps, 1, nminor + 4); nmaps = 0; - tem = KVAR (current_kboard, Voverriding_terminal_local_map); + Lisp_Object tem = KVAR (current_kboard, Voverriding_terminal_local_map); if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag)) maps[nmaps++] = tem; if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem)) maps[nmaps++] = tem; - memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0])); - nmaps += nminor; + if (nminor != 0) + { + memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0])); + nmaps += nminor; + } maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map); } maps[nmaps++] = current_global_map; @@ -7570,7 +7452,6 @@ Lisp_Object item_properties; static void menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dummy2) { - struct gcpro gcpro1; int i; bool parsed; Lisp_Object tem; @@ -7603,9 +7484,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm /* We add to menu_bar_one_keymap_changed_items before doing the parse_menu_item, so that if it turns out it wasn't a menu item, it still correctly hides any further menu item. */ - GCPRO1 (key); parsed = parse_menu_item (item, 1); - UNGCPRO; if (!parsed) return; @@ -7721,7 +7600,8 @@ parse_menu_item (Lisp_Object item, int inmenubar) /* Maybe help string. */ if (CONSP (item) && STRINGP (XCAR (item))) { - ASET (item_properties, ITEM_PROPERTY_HELP, XCAR (item)); + ASET (item_properties, ITEM_PROPERTY_HELP, + Fsubstitute_command_keys (XCAR (item))); start = item; item = XCDR (item); } @@ -7782,7 +7662,12 @@ parse_menu_item (Lisp_Object item, int inmenubar) return 0; } else if (EQ (tem, QChelp)) - ASET (item_properties, ITEM_PROPERTY_HELP, XCAR (item)); + { + Lisp_Object help = XCAR (item); + if (STRINGP (help)) + help = Fsubstitute_command_keys (help); + ASET (item_properties, ITEM_PROPERTY_HELP, help); + } else if (EQ (tem, QCfilter)) filter = item; else if (EQ (tem, QCkey_sequence)) @@ -8032,18 +7917,19 @@ tool_bar_items (Lisp_Object reuse, int *nitems) properties may not work reliable, as they are only recognized when the tool-bar (or mode-line) is updated, which does not normally happen after every command. */ - Lisp_Object tem; - ptrdiff_t nminor; - nminor = current_minor_maps (NULL, &tmaps); + ptrdiff_t nminor = current_minor_maps (NULL, &tmaps); SAFE_NALLOCA (maps, 1, nminor + 4); nmaps = 0; - tem = KVAR (current_kboard, Voverriding_terminal_local_map); + Lisp_Object tem = KVAR (current_kboard, Voverriding_terminal_local_map); if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag)) maps[nmaps++] = tem; if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem)) maps[nmaps++] = tem; - memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0])); - nmaps += nminor; + if (nminor != 0) + { + memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0])); + nmaps += nminor; + } maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map); } @@ -8075,11 +7961,6 @@ static void process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void *args) { int i; - struct gcpro gcpro1, gcpro2; - - /* Protect KEY and DEF from GC because parse_tool_bar_item may call - eval. */ - GCPRO2 (key, def); if (EQ (def, Qundefined)) { @@ -8104,8 +7985,6 @@ process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void /* Append a new tool bar item to tool_bar_items_vector. Accept more than one definition for the same key. */ append_tool_bar_item (); - - UNGCPRO; } /* Access slot with index IDX of vector tool_bar_item_properties. */ @@ -8169,7 +8048,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) Lisp_Object filter = Qnil; Lisp_Object caption; int i; - bool have_label = 0; + bool have_label = false; /* Definition looks like `(menu-item CAPTION BINDING PROPS...)'. Rule out items that aren't lists, don't start with @@ -8278,7 +8157,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) /* `:label LABEL-STRING'. */ set_prop (TOOL_BAR_ITEM_LABEL, STRINGP (value) ? value : build_string (bad_label)); - have_label = 1; + have_label = true; } else if (EQ (ikey, QCfilter)) /* ':filter FORM'. */ @@ -8444,7 +8323,7 @@ read_char_x_menu_prompt (Lisp_Object map, Lisp_Object prev_event, bool *used_mouse_menu) { if (used_mouse_menu) - *used_mouse_menu = 0; + *used_mouse_menu = false; /* Use local over global Menu maps. */ @@ -8493,7 +8372,7 @@ read_char_x_menu_prompt (Lisp_Object map, else if (NILP (value)) value = Qt; if (used_mouse_menu) - *used_mouse_menu = 1; + *used_mouse_menu = true; return value; } return Qnil ; @@ -8508,7 +8387,7 @@ read_char_minibuf_menu_prompt (int commandflag, /* FIXME: Use the minibuffer's frame width. */ ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4; ptrdiff_t idx = -1; - bool nobindings = 1; + bool nobindings = true; Lisp_Object rest, vector; Lisp_Object prompt_strings = Qnil; @@ -8537,7 +8416,7 @@ read_char_minibuf_menu_prompt (int commandflag, /* Present the documented bindings, a line at a time. */ while (1) { - bool notfirst = 0; + bool notfirst = false; Lisp_Object menu_strings = prompt_strings; ptrdiff_t i = nlength; Lisp_Object obj; @@ -8648,8 +8527,8 @@ read_char_minibuf_menu_prompt (int commandflag, PUSH_C_STR (", ", menu_strings); i += 2; } - notfirst = 1; - nobindings = 0; + notfirst = true; + nobindings = false; /* If the char to type doesn't match the string's first char, explicitly show what char to type. */ @@ -8707,12 +8586,10 @@ read_char_minibuf_menu_prompt (int commandflag, while (BUFFERP (obj)); kset_defining_kbd_macro (current_kboard, orig_defn_macro); - if (!INTEGERP (obj) || XINT (obj) == -2) - return obj; - - if (! EQ (obj, menu_prompt_more_char) - && (!INTEGERP (menu_prompt_more_char) - || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char)))))) + if (!INTEGERP (obj) || XINT (obj) == -2 + || (! EQ (obj, menu_prompt_more_char) + && (!INTEGERP (menu_prompt_more_char) + || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char))))))) { if (!NILP (KVAR (current_kboard, defining_kbd_macro))) store_kbd_macro_char (obj); @@ -8787,9 +8664,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt, next = call1 (next, prompt); /* If the function returned something invalid, - barf--don't ignore it. - (To ignore it safely, we would need to gcpro a bunch of - other variables.) */ + barf--don't ignore it. */ if (! (NILP (next) || VECTORP (next) || STRINGP (next))) error ("Function %s returns invalid key sequence", SSDATA (SYMBOL_NAME (tem))); @@ -8967,7 +8842,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, /* True if we are trying to map a key by changing an upper-case letter to lower case, or a shifted function key to an unshifted one. */ - bool shift_translated = 0; + bool shift_translated = false; /* If we receive a `switch-frame' or `select-window' event in the middle of a key sequence, we put it off for later. @@ -8978,16 +8853,13 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, int original_uppercase_position = -1; /* Gets around Microsoft compiler limitations. */ - bool dummyflag = 0; + bool dummyflag = false; struct buffer *starting_buffer; /* List of events for which a fake prefix key has been generated. */ Lisp_Object fake_prefixed_keys = Qnil; - struct gcpro gcpro1; - - GCPRO1 (fake_prefixed_keys); raw_keybuf_count = 0; last_nonmenu_event = Qnil; @@ -9001,8 +8873,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, /* Install the string PROMPT as the beginning of the string of echoing, so that it serves as a prompt for the next character. */ - kset_echo_string (current_kboard, prompt); - current_kboard->echo_after_prompt = SCHARS (prompt); + kset_echo_prompt (current_kboard, prompt); + current_kboard->immediate_echo = false; echo_now (); } else if (cursor_in_echo_area @@ -9068,7 +8940,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, : (/* indec.start < t || fkey.start < t || */ keytran.start < t)) { Lisp_Object key; - bool used_mouse_menu = 0; + bool used_mouse_menu = false; /* Where the last real key started. If we need to throw away a key that has expanded into more than one element of keybuf @@ -9138,11 +9010,12 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { key = keybuf[t]; add_command_key (key); - if (echo_keystrokes_p () - && current_kboard->immediate_echo) + if (current_kboard->immediate_echo) { - echo_add_key (key); - echo_dash (); + /* Set immediate_echo to false so as to force echo_now to + redisplay (it will set immediate_echo right back to true). */ + current_kboard->immediate_echo = false; + echo_now (); } } @@ -9165,12 +9038,12 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, return. Any better way to fix this? -- cyd */ || (interrupted_kboard != current_kboard)) { - bool found = 0; + bool found = false; struct kboard *k; for (k = all_kboards; k; k = k->next_kboard) if (k == interrupted_kboard) - found = 1; + found = true; if (!found) { @@ -9219,7 +9092,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, if (EQ (key, Qt)) { unbind_to (count, Qnil); - UNGCPRO; return -1; } @@ -9231,7 +9103,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, t = 0; /* The Microsoft C compiler can't handle the goto that would go here. */ - dummyflag = 1; + dummyflag = true; break; } @@ -9467,14 +9339,16 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Drags reduce to clicks. Double-clicks reduce to clicks. Triple-clicks reduce to double-clicks, then to clicks. - Down-clicks are eliminated. + Up/Down-clicks are eliminated. Double-downs reduce to downs, then are eliminated. Triple-downs reduce to double-downs, then to downs, then are eliminated. */ - if (modifiers & (down_modifier | drag_modifier + if (modifiers & (up_modifier | down_modifier + | drag_modifier | double_modifier | triple_modifier)) { - while (modifiers & (down_modifier | drag_modifier + while (modifiers & (up_modifier | down_modifier + | drag_modifier | double_modifier | triple_modifier)) { Lisp_Object new_head, new_click; @@ -9486,7 +9360,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, modifiers &= ~drag_modifier; else { - /* Dispose of this `down' event by simply jumping + /* Dispose of this `up/down' event by simply jumping back to replay_key, to get another event. Note that if this event came from mock input, @@ -9591,19 +9465,28 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, /* Record what part of this_command_keys is the current key sequence. */ this_single_command_key_start = this_command_key_count - t; + /* When 'input-method-function' called above causes events to be + put on 'unread-post-input-method-events', and as result + 'reread' is set to 'true', the value of 't' can become larger + than 'this_command_key_count', because 'add_command_key' is + not called to update 'this_command_key_count'. If this + happens, 'this_single_command_key_start' will become negative + above, and any call to 'this-single-command-keys' will return + a garbled vector. See bug #20223 for one such situation. + Here we force 'this_single_command_key_start' to never become + negative, to avoid that. */ + if (this_single_command_key_start < 0) + this_single_command_key_start = 0; /* Look for this sequence in input-decode-map. Scan from indec.end until we find a bound suffix. */ while (indec.end < t) { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; bool done; int diff; - GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame); done = keyremap_step (keybuf, bufsize, &indec, max (t, mock_input), 1, &diff, prompt); - UNGCPRO; if (done) { mock_input = diff + max (t, mock_input); @@ -9630,11 +9513,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, /* Continue scan from fkey.end until we find a bound suffix. */ while (fkey.end < indec.start) { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; bool done; int diff; - GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame); done = keyremap_step (keybuf, bufsize, &fkey, max (t, mock_input), /* If there's a binding (i.e. @@ -9643,7 +9524,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, fkey.end + 1 == t && (test_undefined (current_binding)), &diff, prompt); - UNGCPRO; if (done) { mock_input = diff + max (t, mock_input); @@ -9659,14 +9539,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Scan from keytran.end until we find a bound suffix. */ while (keytran.end < fkey.start) { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; bool done; int diff; - GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame); done = keyremap_step (keybuf, bufsize, &keytran, max (t, mock_input), 1, &diff, prompt); - UNGCPRO; if (done) { mock_input = diff + max (t, mock_input); @@ -9707,7 +9584,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, might get translated through function-key-map. */ keybuf[t - 1] = new_key; mock_input = max (t, mock_input); - shift_translated = 1; + shift_translated = true; goto replay_sequence; } @@ -9718,7 +9595,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, read_key_sequence_cmd = Vprefix_help_command; /* The Microsoft C compiler can't handle the goto that would go here. */ - dummyflag = 1; + dummyflag = true; break; } @@ -9760,7 +9637,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, input-decode-map doesn't need to go through it again. */ fkey.start = fkey.end = 0; keytran.start = keytran.end = 0; - shift_translated = 1; + shift_translated = true; goto replay_sequence; } @@ -9786,7 +9663,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, && t - 1 == original_uppercase_position) { keybuf[t - 1] = original_uppercase; - shift_translated = 0; + shift_translated = false; } if (shift_translated) @@ -9802,13 +9679,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Better ideas? */ for (; t < mock_input; t++) - { - if (echo_keystrokes_p ()) - echo_char (keybuf[t]); - add_command_key (keybuf[t]); - } + add_command_key (keybuf[t]); + echo_update (); - UNGCPRO; return t; } @@ -9819,8 +9692,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object cmd_loop, bool allow_string) { Lisp_Object keybuf[30]; - register int i; - struct gcpro gcpro1; + int i; ptrdiff_t count = SPECPDL_INDEX (); if (!NILP (prompt)) @@ -9832,14 +9704,9 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, specbind (Qinput_method_use_echo_area, (NILP (cmd_loop) ? Qt : Qnil)); - memset (keybuf, 0, sizeof keybuf); - GCPRO1 (keybuf[0]); - gcpro1.nvars = ARRAYELTS (keybuf); - if (NILP (continue_echo)) { this_command_key_count = 0; - this_command_key_count_reset = 0; this_single_command_key_start = 0; } @@ -9866,7 +9733,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, Vquit_flag = Qt; QUIT; } - UNGCPRO; + return unbind_to (count, ((allow_string ? make_event_array : Fvector) (i, keybuf))); @@ -9974,7 +9841,7 @@ detect_input_pending_run_timers (bool do_display) void clear_input_pending (void) { - input_pending = 0; + input_pending = false; } /* Return true if there are pending requeued events. @@ -10096,33 +9963,6 @@ The value is always a vector. */) return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents); } -DEFUN ("reset-this-command-lengths", Freset_this_command_lengths, - Sreset_this_command_lengths, 0, 0, 0, - doc: /* Make the unread events replace the last command and echo. -Used in `universal-argument-other-key'. - -`universal-argument-other-key' rereads the event just typed. -It then gets translated through `function-key-map'. -The translated event has to replace the real events, -both in the value of (this-command-keys) and in echoing. -To achieve this, `universal-argument-other-key' calls -`reset-this-command-lengths', which discards the record of reading -these events the first time. */) - (void) -{ - this_command_key_count = before_command_key_count; - if (this_command_key_count < this_single_command_key_start) - this_single_command_key_start = this_command_key_count; - - echo_truncate (before_command_echo_length); - - /* Cause whatever we put into unread-command-events - to echo as if it were being freshly read from the keyboard. */ - this_command_key_count_reset = 1; - - return Qnil; -} - DEFUN ("clear-this-command-keys", Fclear_this_command_keys, Sclear_this_command_keys, 0, 1, 0, doc: /* Clear out the vector that `this-command-keys' returns. @@ -10133,7 +9973,6 @@ KEEP-RECORD is non-nil. */) int i; this_command_key_count = 0; - this_command_key_count_reset = 0; if (NILP (keep_record)) { @@ -10207,7 +10046,7 @@ Also end any kbd macro being defined. */) discard_tty_input (); kbd_fetch_ptr = kbd_store_ptr; - input_pending = 0; + input_pending = false; return Qnil; } @@ -10230,7 +10069,6 @@ On such systems, Emacs starts a subshell instead of suspending. */) ptrdiff_t count = SPECPDL_INDEX (); int old_height, old_width; int width, height; - struct gcpro gcpro1; if (tty_list && tty_list->next) error ("There are other tty frames open; close them before suspending Emacs"); @@ -10240,7 +10078,6 @@ On such systems, Emacs starts a subshell instead of suspending. */) run_hook (intern ("suspend-hook")); - GCPRO1 (stuffstring); get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height); reset_all_sys_modes (); /* sys_suspend can get an error if it tries to fork a subshell @@ -10264,7 +10101,6 @@ On such systems, Emacs starts a subshell instead of suspending. */) run_hook (intern ("suspend-resume-hook")); - UNGCPRO; return Qnil; } @@ -10300,12 +10136,12 @@ stuff_buffered_input (Lisp_Object stuffstring) if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) kbd_fetch_ptr = kbd_buffer; if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT) - stuff_char (kbd_fetch_ptr->code); + stuff_char (kbd_fetch_ptr->ie.code); clear_event (kbd_fetch_ptr); } - input_pending = 0; + input_pending = false; #endif /* SIGTSTP */ } @@ -10315,7 +10151,7 @@ set_waiting_for_input (struct timespec *time_to_clear) input_available_clear_time = time_to_clear; /* Tell handle_interrupt to throw back to read_char, */ - waiting_for_input = 1; + waiting_for_input = true; /* If handle_interrupt was called before and buffered a C-g, make it run again now, to avoid timing error. */ @@ -10327,7 +10163,7 @@ void clear_waiting_for_input (void) { /* Tell handle_interrupt not to throw back to read_char, */ - waiting_for_input = 0; + waiting_for_input = false; input_available_clear_time = 0; } @@ -10486,16 +10322,12 @@ handle_interrupt (bool in_signal_handler) if (immediate_quit && NILP (Vinhibit_quit)) { struct gl_state_s saved; - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; - immediate_quit = 0; + immediate_quit = false; pthread_sigmask (SIG_SETMASK, &empty_mask, 0); saved = gl_state; - GCPRO4 (saved.object, saved.global_code, - saved.current_syntax_table, saved.old_prop); Fsignal (Qquit, Qnil); gl_state = saved; - UNGCPRO; } else { /* Else request quit when it's safe. */ @@ -10503,7 +10335,7 @@ handle_interrupt (bool in_signal_handler) force_quit_count = count; if (count == 3) { - immediate_quit = 1; + immediate_quit = true; Vinhibit_quit = Qnil; } Vquit_flag = Qt; @@ -10537,7 +10369,7 @@ quit_throw_to_read_char (bool from_signal) /* Prevent another signal from doing this before we finish. */ clear_waiting_for_input (); - input_pending = 0; + input_pending = false; Vunread_command_events = Qnil; @@ -10565,13 +10397,13 @@ See also `current-input-mode'. */) { /* When using X, don't give the user a real choice, because we haven't implemented the mechanisms to support it. */ - new_interrupt_input = 1; + new_interrupt_input = true; } else #endif /* HAVE_X_WINDOWS */ new_interrupt_input = !NILP (interrupt); #else /* not USABLE_SIGIO */ - new_interrupt_input = 0; + new_interrupt_input = false; #endif /* not USABLE_SIGIO */ if (new_interrupt_input != interrupt_input) @@ -10787,7 +10619,11 @@ The return value is similar to a mouse click position: The `posn-' functions access elements of such lists. */) (Lisp_Object x, Lisp_Object y, Lisp_Object frame_or_window, Lisp_Object whole) { - CHECK_NATNUM (x); + CHECK_NUMBER (x); + /* We allow X of -1, for the newline in a R2L line that overflowed + into the left fringe. */ + if (XINT (x) != -1) + CHECK_NATNUM (x); CHECK_NATNUM (y); if (NILP (frame_or_window)) @@ -10835,8 +10671,9 @@ The `posn-' functions access elements of such lists. */) Lisp_Object x = XCAR (tem); Lisp_Object y = XCAR (XCDR (tem)); - /* Point invisible due to hscrolling? */ - if (XINT (x) < 0) + /* Point invisible due to hscrolling? X can be -1 when a + newline in a R2L line overflows into the left fringe. */ + if (XINT (x) < -1) return Qnil; tem = Fposn_at_x_y (x, y, window, Qnil); } @@ -10858,10 +10695,10 @@ init_kboard (KBOARD *kb, Lisp_Object type) kset_prefix_arg (kb, Qnil); kset_last_prefix_arg (kb, Qnil); kset_kbd_queue (kb, Qnil); - kb->kbd_queue_has_data = 0; - kb->immediate_echo = 0; + kb->kbd_queue_has_data = false; + kb->immediate_echo = false; kset_echo_string (kb, Qnil); - kb->echo_after_prompt = -1; + kset_echo_prompt (kb, Qnil); kb->kbd_macro_buffer = 0; kb->kbd_macro_bufsize = 0; kset_defining_kbd_macro (kb, Qnil); @@ -10919,7 +10756,7 @@ delete_kboard (KBOARD *kb) && FRAME_LIVE_P (XFRAME (selected_frame))) { current_kboard = FRAME_KBOARD (XFRAME (selected_frame)); - single_kboard = 0; + single_kboard = false; if (current_kboard == kb) emacs_abort (); } @@ -10933,7 +10770,7 @@ init_keyboard (void) { /* This is correct before outermost invocation of the editor loop. */ command_loop_level = -1; - immediate_quit = 0; + immediate_quit = false; quit_char = Ctl ('g'); Vunread_command_events = Qnil; timer_idleness_start_time = invalid_timespec (); @@ -10942,9 +10779,9 @@ init_keyboard (void) kbd_fetch_ptr = kbd_buffer; kbd_store_ptr = kbd_buffer; do_mouse_tracking = Qnil; - input_pending = 0; + input_pending = false; interrupt_input_blocked = 0; - pending_signals = 0; + pending_signals = false; /* This means that command_loop_1 won't try to select anything the first time through. */ @@ -11063,10 +10900,6 @@ syms_of_keyboard (void) tool_bar_items_vector = Qnil; DEFSYM (Qtimer_event_handler, "timer-event-handler"); - DEFSYM (Qdisabled_command_function, "disabled-command-function"); - DEFSYM (Qself_insert_command, "self-insert-command"); - DEFSYM (Qforward_char, "forward-char"); - DEFSYM (Qbackward_char, "backward-char"); /* Non-nil disable property on a command means do not execute it; call disabled-command-function's value instead. */ @@ -11174,7 +11007,6 @@ syms_of_keyboard (void) 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"); DEFSYM (Qinput_method_use_echo_area, "input-method-use-echo-area"); @@ -11237,6 +11069,7 @@ syms_of_keyboard (void) staticpro (&raw_keybuf); DEFSYM (Qcommand_execute, "command-execute"); + DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix"); accent_key_syms = Qnil; staticpro (&accent_key_syms); @@ -11280,7 +11113,6 @@ syms_of_keyboard (void) defsubr (&Sthis_command_keys_vector); defsubr (&Sthis_single_command_keys); defsubr (&Sthis_single_command_raw_keys); - defsubr (&Sreset_this_command_lengths); defsubr (&Sclear_this_command_keys); defsubr (&Ssuspend_emacs); defsubr (&Sabort_recursive_edit); @@ -11480,6 +11312,7 @@ for that character after that prefix key. */); doc: /* Form to evaluate when Emacs starts up. Useful to set before you dump a modified Emacs. */); Vtop_level = Qnil; + XSYMBOL (Qtop_level)->declared_special = false; DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, doc: /* Translate table for local keyboard input, or nil. @@ -11499,8 +11332,8 @@ See Info node `(elisp)Multiple Terminals'. */); DEFVAR_BOOL ("cannot-suspend", cannot_suspend, doc: /* Non-nil means to always spawn a subshell instead of suspending. -\(Even if the operating system has support for stopping a process.\) */); - cannot_suspend = 0; +(Even if the operating system has support for stopping a process.) */); + cannot_suspend = false; DEFVAR_BOOL ("menu-prompting", menu_prompting, doc: /* Non-nil means prompt with menus when appropriate. @@ -11510,7 +11343,7 @@ The menu is displayed on the screen if X menus were enabled at configuration time and the previous event was a mouse click prefix key. Otherwise, menu prompting uses the echo area. */); - menu_prompting = 1; + menu_prompting = true; DEFVAR_LISP ("menu-prompt-more-char", menu_prompt_more_char, doc: /* Character to see next line of menu prompt. @@ -11705,7 +11538,7 @@ immediately after running `post-command-hook'. */); DEFVAR_LISP ("input-method-function", Vinput_method_function, doc: /* If non-nil, the function that implements the current input method. It's called with one argument, a printing character that was just read. -\(That means a character with code 040...0176.) +(That means a character with code 040...0176.) Typically this function uses `read-event' to read additional events. When it does so, it should first bind `input-method-function' to nil so it will not be called recursively. @@ -11928,9 +11761,10 @@ mark_kboards (void) mark_object (KVAR (kb, Vlocal_function_key_map)); mark_object (KVAR (kb, Vdefault_minibuffer_frame)); mark_object (KVAR (kb, echo_string)); + mark_object (KVAR (kb, echo_prompt)); } { - struct input_event *event; + union buffered_input_event *event; for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++) { if (event == kbd_buffer + KBD_BUFFER_SIZE) @@ -11939,10 +11773,10 @@ mark_kboards (void) if (event->kind != SELECTION_REQUEST_EVENT && event->kind != SELECTION_CLEAR_EVENT) { - mark_object (event->x); - mark_object (event->y); - mark_object (event->frame_or_window); - mark_object (event->arg); + mark_object (event->ie.x); + mark_object (event->ie.y); + mark_object (event->ie.frame_or_window); + mark_object (event->ie.arg); } } }