X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index 439a40f876..20498d074f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,7 +1,6 @@ /* Keyboard and mouse input; editor command loop. -Copyright (C) 1985-1989, 1993-1997, 1999-2014 Free Software Foundation, -Inc. +Copyright (C) 1985-1989, 1993-1997, 1999-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -21,6 +20,7 @@ along with GNU Emacs. If not, see . */ #include #include "sysstdio.h" +#include #include "lisp.h" #include "termchar.h" @@ -69,6 +69,8 @@ along with GNU Emacs. If not, see . */ #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ +#include /* for GC_collect_a_little */ + /* Variables for blockinput.h: */ /* Positive if interrupt input is blocked right now. */ @@ -228,7 +230,7 @@ static Lisp_Object Qbackward_char; Lisp_Object Qundefined; static Lisp_Object Qtimer_event_handler; -/* read_key_sequence stores here the command definition of the +/* `read_key_sequence' stores here the command definition of the key sequence that it reads. */ static Lisp_Object read_key_sequence_cmd; static Lisp_Object read_key_sequence_remapped; @@ -356,7 +358,6 @@ static Lisp_Object Qecho_keystrokes; static void recursive_edit_unwind (Lisp_Object buffer); static Lisp_Object command_loop (void); static Lisp_Object Qcommand_execute; -struct timespec timer_check (void); static void echo_now (void); static ptrdiff_t echo_length (void); @@ -377,12 +378,6 @@ bool interrupt_input; /* Nonzero while interrupts are temporarily deferred during redisplay. */ bool interrupts_deferred; -/* If we support a window system, turn on the code to poll periodically - to detect C-g. It isn't actually used when doing interrupt input. */ -#ifdef HAVE_WINDOW_SYSTEM -#define POLL_FOR_INPUT -#endif - /* The time when Emacs started being idle. */ static struct timespec timer_idleness_start_time; @@ -422,8 +417,8 @@ static Lisp_Object make_lispy_focus_in (Lisp_Object); static Lisp_Object make_lispy_focus_out (Lisp_Object); #endif /* HAVE_WINDOW_SYSTEM */ static bool help_char_p (Lisp_Object); -static void save_getcjmp (sys_jmp_buf); -static void restore_getcjmp (sys_jmp_buf); +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); @@ -745,7 +740,7 @@ add_command_key (Lisp_Object key) Lisp_Object recursive_edit_1 (void) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); Lisp_Object val; if (command_loop_level > 0) @@ -782,7 +777,8 @@ recursive_edit_1 (void) if (STRINGP (val)) xsignal1 (Qerror, val); - return unbind_to (count, Qnil); + dynwind_end (); + return Qnil; } /* When an auto-save happens, record the "time", and don't do again soon. */ @@ -817,33 +813,39 @@ one level up. This function is called by the editor initialization to begin editing. */) (void) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); Lisp_Object buffer; /* If we enter while input is blocked, don't lock up here. This may happen through the debugger during redisplay. */ - if (input_blocked_p ()) + if (input_blocked_p ()) { + dynwind_end (); return Qnil; + } - command_loop_level++; - update_mode_lines = 17; - - if (command_loop_level + if (command_loop_level >= 0 && current_buffer != XBUFFER (XWINDOW (selected_window)->contents)) buffer = Fcurrent_buffer (); else buffer = Qnil; + /* Don't do anything interesting between the increment and the + record_unwind_protect! Otherwise, we could get distracted and + never decrement the counter again. */ + command_loop_level++; + update_mode_lines = 17; + record_unwind_protect (recursive_edit_unwind, buffer); + /* If we leave recursive_edit_1 below with a `throw' for instance, like it is done in the splash screen display, we have to make sure that we restore single_kboard as command_loop_1 would have done if it were left normally. */ if (command_loop_level > 0) temporarily_switch_to_single_kboard (SELECTED_FRAME ()); - record_unwind_protect (recursive_edit_unwind, buffer); recursive_edit_1 (); - return unbind_to (count, Qnil); + dynwind_end (); + return Qnil; } void @@ -1219,7 +1221,7 @@ user_error (const char *msg) xsignal1 (Quser_error, build_string (msg)); } -_Noreturn +/* _Noreturn will be added to prototype by make-docfile. */ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "", doc: /* Exit from the innermost recursive edit or minibuffer. */) (void) @@ -1230,7 +1232,7 @@ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, user_error ("No recursive edit is in progress"); } -_Noreturn +/* _Noreturn will be added to prototype by make-docfile. */ 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) @@ -1271,7 +1273,7 @@ Normally, mouse motion is ignored. usage: (track-mouse BODY...) */) (Lisp_Object args) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); Lisp_Object val; record_unwind_protect (tracking_off, do_mouse_tracking); @@ -1279,7 +1281,8 @@ usage: (track-mouse BODY...) */) do_mouse_tracking = Qt; val = Fprogn (args); - return unbind_to (count, val); + dynwind_end (); + return val; } /* If mouse has moved on some frame, return one of those frames. @@ -1289,9 +1292,6 @@ usage: (track-mouse BODY...) */) If ignore_mouse_drag_p is non-zero, ignore (implicit) mouse movement after resizing the tool-bar window. */ -#if !defined HAVE_WINDOW_SYSTEM || defined USE_GTK || defined HAVE_NS -static -#endif bool ignore_mouse_drag_p; static struct frame * @@ -1320,14 +1320,11 @@ some_mouse_moved (void) static int read_key_sequence (Lisp_Object *, int, Lisp_Object, bool, bool, bool, bool); -void safe_run_hooks (Lisp_Object); static void adjust_point_for_property (ptrdiff_t, bool); /* The last boundary auto-added to buffer-undo-list. */ Lisp_Object last_undo_boundary; -extern Lisp_Object Qregion_extract_function; - /* 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, ... */ @@ -1412,7 +1409,7 @@ command_loop_1 (void) { /* Bind inhibit-quit to t so that C-g gets read in rather than quitting back to the minibuffer. */ - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); specbind (Qinhibit_quit, Qt); sit_for (Vminibuffer_message_timeout, 0, 2); @@ -1421,7 +1418,7 @@ command_loop_1 (void) message1 (0); safe_run_hooks (Qecho_area_clear_hook); - unbind_to (count, Qnil); + dynwind_end (); /* If a C-g came in before, treat it as input now. */ if (!NILP (Vquit_flag)) @@ -1446,7 +1443,7 @@ command_loop_1 (void) Vthis_command_keys_shift_translated = Qnil; /* Read next key sequence; i gets its length. */ - i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], + i = read_key_sequence (keybuf, ARRAYELTS (keybuf), Qnil, 0, 1, 1, 0); /* A filter may have run while we were reading the input. */ @@ -1535,7 +1532,7 @@ command_loop_1 (void) /* Here for a command that isn't executed directly. */ #ifdef HAVE_WINDOW_SYSTEM - ptrdiff_t scount = SPECPDL_INDEX (); + dynwind_begin (); if (display_hourglass_p && NILP (Vexecuting_kbd_macro)) @@ -1561,8 +1558,7 @@ command_loop_1 (void) hourglass cursor anyway. But don't cancel the hourglass within a macro just because a command in the macro finishes. */ - if (NILP (Vexecuting_kbd_macro)) - unbind_to (scount, Qnil); + dynwind_end (); #endif } kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg); @@ -1694,7 +1690,7 @@ read_menu_command (void) menus. */ specbind (Qecho_keystrokes, make_number (0)); - i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], + i = read_key_sequence (keybuf, ARRAYELTS (keybuf), Qnil, 0, 1, 1, 1); unbind_to (count, Qnil); @@ -1938,12 +1934,12 @@ 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 ;-) */ - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); specbind (Qinhibit_quit, hook); run_hook_with_args (1, &hook, safe_run_hook_funcall); - unbind_to (count, Qnil); + dynwind_end (); } @@ -2088,16 +2084,13 @@ bind_polling_period (int n) /* Apply the control modifier to CHARACTER. */ -#ifndef HAVE_NTGUI -static -#endif int make_ctrl_char (int c) { /* Save the upper bits here. */ int upper = c & ~0177; - if (! ASCII_BYTE_P (c)) + if (! ASCII_CHAR_P (c)) return c |= ctrl_modifier; c &= 0177; @@ -2194,7 +2187,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, -/* Input of single characters from keyboard */ +/* Input of single characters from keyboard. */ static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, struct timespec *end_time); @@ -2220,11 +2213,11 @@ do { if (polling_stopped_here) start_polling (); \ static Lisp_Object read_event_from_main_queue (struct timespec *end_time, - sys_jmp_buf local_getcjmp, + sys_jmp_buf *local_getcjmp, bool *used_mouse_menu) { Lisp_Object c = Qnil; - sys_jmp_buf save_jump; + sys_jmp_buf *save_jump = xmalloc (sizeof *save_jump); KBOARD *kb IF_LINT (= NULL); start: @@ -2294,7 +2287,7 @@ read_event_from_main_queue (struct timespec *end_time, to tty input. */ static Lisp_Object read_decoded_event_from_main_queue (struct timespec *end_time, - sys_jmp_buf local_getcjmp, + sys_jmp_buf *local_getcjmp, Lisp_Object prev_event, bool *used_mouse_menu) { @@ -2373,13 +2366,20 @@ read_decoded_event_from_main_queue (struct timespec *end_time, } } +static bool +echo_keystrokes_p (void) +{ + return (FLOATP (Vecho_keystrokes) ? XFLOAT_DATA (Vecho_keystrokes) > 0.0 + : INTEGERP (Vecho_keystrokes) ? XINT (Vecho_keystrokes) > 0 : false); +} + /* Read a character from the keyboard; call the redisplay if needed. */ /* commandflag 0 means do not autosave, but do redisplay. -1 means do not redisplay, but do autosave. -2 means do neither. 1 means do both. */ -/* The arguments MAP is for menu prompting. MAP is a keymap. +/* The argument MAP is a keymap for menu prompting. PREV_EVENT is the previous input event, or nil if we are reading the first event of a key sequence (or not reading a key sequence). @@ -2400,37 +2400,128 @@ read_decoded_event_from_main_queue (struct timespec *end_time, Value is t if we showed a menu and the user rejected it. */ +struct read_char_state +{ + int commandflag; + Lisp_Object map; + Lisp_Object prev_event; + bool *used_mouse_menu; + struct timespec *end_time; + Lisp_Object c; + ptrdiff_t jmpcount; + sys_jmp_buf *local_getcjmp; + sys_jmp_buf *save_jump; + Lisp_Object previous_echo_area_message; + Lisp_Object also_record; + bool reread; + bool polling_stopped_here; + struct kboard *orig_kboard; +}; + +static Lisp_Object read_char_1 (bool, volatile struct read_char_state *); + +/* {{coccinelle:skip_start}} */ Lisp_Object read_char (int commandflag, Lisp_Object map, Lisp_Object prev_event, bool *used_mouse_menu, struct timespec *end_time) { - Lisp_Object c; - ptrdiff_t jmpcount; - sys_jmp_buf local_getcjmp; - sys_jmp_buf save_jump; - 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; - struct kboard *orig_kboard = current_kboard; + volatile struct read_char_state *state = xmalloc (sizeof *state); + + state->commandflag = commandflag; + state->map = map; + state->prev_event = prev_event; + state->used_mouse_menu = used_mouse_menu; + state->end_time = end_time; + state->c = Qnil; + state->local_getcjmp = xmalloc (sizeof (*state->local_getcjmp)); + state->save_jump = xmalloc (sizeof (*state->save_jump)); + state->previous_echo_area_message = Qnil; + state->also_record = Qnil; + state->reread = false; + state->polling_stopped_here = false; + state->orig_kboard = current_kboard; - also_record = Qnil; + /* Make a longjmp point for quits to use, but don't alter getcjmp just yet. + We will do that below, temporarily for short sections of code, + when appropriate. local_getcjmp must be in effect + around any call to sit_for or kbd_buffer_get_event; + it *must not* be in effect when we call redisplay. */ -#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; + state->jmpcount = SPECPDL_INDEX (); + if (sys_setjmp (*state->local_getcjmp)) + { + /* Handle quits while reading the keyboard. */ + /* We must have saved the outer value of getcjmp here, + so restore it now. */ + restore_getcjmp (state->save_jump); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + unbind_to (state->jmpcount, Qnil); + XSETINT (state->c, quit_char); + internal_last_event_frame = selected_frame; + Vlast_event_frame = internal_last_event_frame; + /* If we report the quit char as an event, + don't do so more than once. */ + if (!NILP (Vinhibit_quit)) + Vquit_flag = Qnil; + + { + KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame)); + if (kb != current_kboard) + { + Lisp_Object last = KVAR (kb, kbd_queue); + /* We shouldn't get here if we were in single-kboard mode! */ + if (single_kboard) + emacs_abort (); + if (CONSP (last)) + { + while (CONSP (XCDR (last))) + last = XCDR (last); + if (!NILP (XCDR (last))) + emacs_abort (); + } + if (!CONSP (last)) + kset_kbd_queue (kb, list1 (state->c)); + else + XSETCDR (last, list1 (state->c)); + kb->kbd_queue_has_data = 1; + 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 */ + } + } + return read_char_1 (true, state); + } - GCPRO2 (c, previous_echo_area_message); + return read_char_1 (false, state); +} + +static Lisp_Object +read_char_1 (bool jump, volatile struct read_char_state *state) +{ +#define commandflag state->commandflag +#define map state->map +#define prev_event state->prev_event +#define used_mouse_menu state->used_mouse_menu +#define end_time state->end_time +#define c state->c +#define jmpcount state->jmpcount +#define local_getcjmp state->local_getcjmp +#define save_jump state->save_jump +#define previous_echo_area_message state->previous_echo_area_message +#define also_record state->also_record +#define reread state->reread +#define polling_stopped_here state->polling_stopped_here +#define orig_kboard state->orig_kboard + Lisp_Object tem, save; + + if (jump) + goto non_reread; retry: - reread = 0; if (CONSP (Vunread_post_input_method_events)) { c = XCAR (Vunread_post_input_method_events); @@ -2444,9 +2535,12 @@ read_char (int commandflag, Lisp_Object map, && NILP (XCDR (c))) c = XCAR (c); - reread = 1; + reread = true; goto reread_first; } + else + reread = false; + if (CONSP (Vunread_command_events)) { @@ -2455,17 +2549,13 @@ read_char (int commandflag, Lisp_Object map, c = XCAR (Vunread_command_events); Vunread_command_events = XCDR (Vunread_command_events); - reread = 1; - /* Undo what sit-for did when it unread additional keys inside universal-argument. */ - if (CONSP (c) - && EQ (XCAR (c), Qt)) - { - reread = 0; - c = XCDR (c); - } + if (CONSP (c) && EQ (XCAR (c), Qt)) + c = XCDR (c); + else + reread = true; /* Undo what read_char_x_menu_prompt did when it unread additional keys returned by Fx_popup_menu. */ @@ -2499,7 +2589,7 @@ read_char (int commandflag, Lisp_Object map, && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c))) && NILP (XCDR (c))) c = XCAR (c); - reread = 1; + reread = true; goto reread_for_input_method; } @@ -2641,58 +2731,6 @@ read_char (int commandflag, Lisp_Object map, goto exit; } - /* Make a longjmp point for quits to use, but don't alter getcjmp just yet. - We will do that below, temporarily for short sections of code, - when appropriate. local_getcjmp must be in effect - around any call to sit_for or kbd_buffer_get_event; - it *must not* be in effect when we call redisplay. */ - - jmpcount = SPECPDL_INDEX (); - if (sys_setjmp (local_getcjmp)) - { - /* Handle quits while reading the keyboard. */ - /* We must have saved the outer value of getcjmp here, - so restore it now. */ - restore_getcjmp (save_jump); - unbind_to (jmpcount, Qnil); - XSETINT (c, quit_char); - internal_last_event_frame = selected_frame; - Vlast_event_frame = internal_last_event_frame; - /* If we report the quit char as an event, - don't do so more than once. */ - if (!NILP (Vinhibit_quit)) - Vquit_flag = Qnil; - - { - KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame)); - if (kb != current_kboard) - { - Lisp_Object last = KVAR (kb, kbd_queue); - /* We shouldn't get here if we were in single-kboard mode! */ - if (single_kboard) - emacs_abort (); - if (CONSP (last)) - { - while (CONSP (XCDR (last))) - last = XCDR (last); - if (!NILP (XCDR (last))) - emacs_abort (); - } - if (!CONSP (last)) - kset_kbd_queue (kb, list1 (c)); - else - XSETCDR (last, list1 (c)); - kb->kbd_queue_has_data = 1; - 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 */ - } - } - goto non_reread; - } - /* Start idle timers if no time limit is supplied. We don't do it if a time limit is supplied to avoid an infinite recursion in the situation where an idle timer calls `sit-for'. */ @@ -2708,8 +2746,7 @@ read_char (int commandflag, Lisp_Object map, && !current_kboard->immediate_echo && this_command_key_count > 0 && ! noninteractive - && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) - && NILP (Fzerop (Vecho_keystrokes)) + && echo_keystrokes_p () && (/* No message. */ NILP (echo_area_buffer[0]) /* Or empty message. */ @@ -2818,7 +2855,7 @@ read_char (int commandflag, Lisp_Object map, /* If there is still no input available, ask for GC. */ if (!detect_input_pending_run_timers (0)) - maybe_gc (); + GC_collect_a_little (); } /* Notify the caller if an autosave hook, or a timer, sentinel or @@ -2840,6 +2877,11 @@ read_char (int commandflag, Lisp_Object map, { c = XCAR (Vunread_command_events); Vunread_command_events = XCDR (Vunread_command_events); + + if (CONSP (c) && EQ (XCAR (c), Qt)) + c = XCDR (c); + else + reread = true; } /* Read something from current KBOARD's side queue, if possible. */ @@ -2893,8 +2935,8 @@ read_char (int commandflag, Lisp_Object map, { c = read_decoded_event_from_main_queue (end_time, local_getcjmp, prev_event, used_mouse_menu); - if (NILP(c) && end_time && - timespec_cmp (*end_time, current_timespec ()) <= 0) + if (NILP (c) && end_time + && timespec_cmp (*end_time, current_timespec ()) <= 0) { goto exit; } @@ -3058,7 +3100,6 @@ read_char (int commandflag, Lisp_Object map, ptrdiff_t key_count; bool key_count_reset; struct gcpro gcpro1; - ptrdiff_t count = SPECPDL_INDEX (); /* Save the echo status. */ bool saved_immediate_echo = current_kboard->immediate_echo; @@ -3066,6 +3107,8 @@ read_char (int commandflag, Lisp_Object map, Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string); ptrdiff_t saved_echo_after_prompt = current_kboard->echo_after_prompt; + dynwind_begin (); + #if 0 if (before_command_restore_flag) { @@ -3107,7 +3150,7 @@ read_char (int commandflag, Lisp_Object map, /* Call the input method. */ tem = call1 (Vinput_method_function, c); - tem = unbind_to (count, tem); + dynwind_end (); /* Restore the saved echoing state and this_command_keys state. */ @@ -3170,8 +3213,7 @@ read_char (int commandflag, Lisp_Object map, { /* Don't echo mouse motion events. */ - if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) - && NILP (Fzerop (Vecho_keystrokes)) + if (echo_keystrokes_p () && ! (EVENT_HAS_PARAMETERS (c) && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) { @@ -3195,7 +3237,7 @@ read_char (int commandflag, Lisp_Object map, /* Process the help character specially if enabled. */ if (!NILP (Vhelp_form) && help_char_p (c)) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); help_form_saved_window_configs = Fcons (Fcurrent_window_configuration (Qnil), @@ -3213,7 +3255,7 @@ read_char (int commandflag, Lisp_Object map, } while (BUFFERP (c)); /* Remove the help from the frame. */ - unbind_to (count, Qnil); + dynwind_end (); redisplay (); if (EQ (c, make_number (040))) @@ -3228,7 +3270,22 @@ read_char (int commandflag, Lisp_Object map, exit: RESUME_POLLING; RETURN_UNGCPRO (c); -} +#undef commandflag +#undef map +#undef prev_event +#undef used_mouse_menu +#undef end_time +#undef c +#undef jmpcount +#undef local_getcjmp +#undef save_jump +#undef previous_echo_area_message +#undef also_record +#undef reread +#undef polling_stopped_here +#undef orig_kboard +} +/* {{coccinelle:skip_end}} */ /* Record a key that came from a mouse menu. Record it for echoing, for this-command-keys, and so on. */ @@ -3247,8 +3304,7 @@ record_menu_key (Lisp_Object c) #endif /* Don't echo mouse motion events. */ - if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) - && NILP (Fzerop (Vecho_keystrokes))) + if (echo_keystrokes_p ()) { echo_char (c); @@ -3422,15 +3478,15 @@ record_char (Lisp_Object c) See read_process_output. */ static void -save_getcjmp (sys_jmp_buf temp) +save_getcjmp (sys_jmp_buf *temp) { - memcpy (temp, getcjmp, sizeof getcjmp); + memcpy (*temp, getcjmp, sizeof getcjmp); } static void -restore_getcjmp (sys_jmp_buf temp) +restore_getcjmp (sys_jmp_buf *temp) { - memcpy (getcjmp, temp, sizeof getcjmp); + memcpy (getcjmp, *temp, sizeof getcjmp); } /* Low level keyboard/mouse input. @@ -3655,7 +3711,8 @@ kbd_buffer_store_event_hold (register struct input_event *event, *kbd_store_ptr = *event; ++kbd_store_ptr; #ifdef subprocesses - if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE/2 && ! kbd_on_hold_p ()) + if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2 + && ! kbd_on_hold_p ()) { /* Don't read keyboard input until we have processed kbd_buffer. This happens when pasting text longer than KBD_BUFFER_SIZE/2. */ @@ -4500,7 +4557,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) { if (NILP (AREF (chosen_timer, 0))) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); Lisp_Object old_deactivate_mark = Vdeactivate_mark; /* Mark the timer as triggered to prevent problems if the lisp @@ -4512,7 +4569,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) call1 (Qtimer_event_handler, chosen_timer); Vdeactivate_mark = old_deactivate_mark; timers_run++; - unbind_to (count, Qnil); + dynwind_end (); /* Since we have handled the event, we don't need to tell the caller to wake up and do it. */ @@ -5223,7 +5280,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, /* It's a click in window WINDOW at frame coordinates (X,Y) */ struct window *w = XWINDOW (window); Lisp_Object string_info = Qnil; - ptrdiff_t textpos = -1; + ptrdiff_t textpos = 0; int col = -1, row = -1; int dx = -1, dy = -1; int width = -1, height = -1; @@ -5258,9 +5315,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, &object, &dx, &dy, &width, &height); if (STRINGP (string)) string_info = Fcons (string, make_number (charpos)); - textpos = (w == XWINDOW (selected_window) - && current_buffer == XBUFFER (w->contents)) - ? PT : marker_position (w->pointm); + textpos = -1; xret = wx; yret = wy; @@ -5328,7 +5383,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, /* For clicks in the text area, fringes, or margins, call buffer_posn_from_coords to extract TEXTPOS, the buffer position nearest to the click. */ - if (textpos < 0) + if (!textpos) { Lisp_Object string2, object2 = Qnil; struct display_pos p; @@ -5379,15 +5434,15 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, } #endif - /* Object info */ + /* Object info. */ extra_info = list3 (object, Fcons (make_number (dx), make_number (dy)), Fcons (make_number (width), make_number (height))); - /* String info */ + /* String info. */ extra_info = Fcons (string_info, - Fcons (make_number (textpos), + Fcons (textpos < 0 ? Qnil : make_number (textpos), Fcons (Fcons (make_number (col), make_number (row)), extra_info))); @@ -5478,14 +5533,13 @@ make_lispy_event (struct input_event *event) case NON_ASCII_KEYSTROKE_EVENT: button_down_time = 0; - for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++) + for (i = 0; i < ARRAYELTS (lispy_accent_codes); i++) if (event->code == lispy_accent_codes[i]) return modify_event_symbol (i, event->modifiers, Qfunction_key, Qnil, lispy_accent_keys, &accent_key_syms, - (sizeof (lispy_accent_keys) - / sizeof (lispy_accent_keys[0]))); + ARRAYELTS (lispy_accent_keys)); #if 0 #ifdef XK_kana_A @@ -5494,8 +5548,7 @@ make_lispy_event (struct input_event *event) event->modifiers & ~shift_modifier, Qfunction_key, Qnil, lispy_kana_keys, &func_key_syms, - (sizeof (lispy_kana_keys) - / sizeof (lispy_kana_keys[0]))); + ARRAYELTS (lispy_kana_keys)); #endif /* XK_kana_A */ #endif /* 0 */ @@ -5506,15 +5559,14 @@ make_lispy_event (struct input_event *event) event->modifiers, Qfunction_key, Qnil, iso_lispy_function_keys, &func_key_syms, - (sizeof (iso_lispy_function_keys) - / sizeof (iso_lispy_function_keys[0]))); + ARRAYELTS (iso_lispy_function_keys)); #endif /* Handle system-specific or unknown keysyms. */ if (event->code & (1 << 28) || event->code - FUNCTION_KEY_OFFSET < 0 || (event->code - FUNCTION_KEY_OFFSET - >= sizeof lispy_function_keys / sizeof *lispy_function_keys) + >= ARRAYELTS (lispy_function_keys)) || !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET]) { /* We need to use an alist rather than a vector as the cache @@ -5533,20 +5585,17 @@ make_lispy_event (struct input_event *event) event->modifiers, Qfunction_key, Qnil, lispy_function_keys, &func_key_syms, - (sizeof (lispy_function_keys) - / sizeof (lispy_function_keys[0]))); + ARRAYELTS (lispy_function_keys)); #ifdef HAVE_NTGUI case MULTIMEDIA_KEY_EVENT: - if (event->code < (sizeof (lispy_multimedia_keys) - / sizeof (lispy_multimedia_keys[0])) + if (event->code < ARRAYELTS (lispy_multimedia_keys) && event->code > 0 && lispy_multimedia_keys[event->code]) { return modify_event_symbol (event->code, event->modifiers, Qfunction_key, Qnil, lispy_multimedia_keys, &func_key_syms, - (sizeof (lispy_multimedia_keys) - / sizeof (lispy_multimedia_keys[0]))); + ARRAYELTS (lispy_multimedia_keys)); } return Qnil; #endif @@ -6268,7 +6317,7 @@ static const char *const modifier_names[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "alt", "super", "hyper", "shift", "control", "meta" }; -#define NUM_MOD_NAMES (sizeof (modifier_names) / sizeof (modifier_names[0])) +#define NUM_MOD_NAMES ARRAYELTS (modifier_names) static Lisp_Object modifier_symbols; @@ -6876,6 +6925,20 @@ gobble_input (void) } } + /* If there was no error, make sure the pointer + is visible for all frames on this terminal. */ + if (nr >= 0) + { + Lisp_Object tail, frame; + + FOR_EACH_FRAME (tail, frame) + { + struct frame *f = XFRAME (frame); + if (FRAME_TERMINAL (f) == t) + frame_make_pointer_visible (f); + } + } + if (hold_quit.kind != NO_EVENT) kbd_buffer_store_event (&hold_quit); } @@ -6886,8 +6949,6 @@ gobble_input (void) if (err && !nread) nread = -1; - frame_make_pointer_visible (); - return nread; } @@ -7123,7 +7184,12 @@ unblock_input_to (int level) /* End critical section. If doing signal-driven input, and a signal came in when input was - blocked, reinvoke the signal handler now to deal with it. */ + blocked, reinvoke the signal handler now to deal with it. + + It will also process queued input, if it was not read before. + When a longer code sequence does not use block/unblock input + at all, the whole input gathered up to the next call to + unblock_input will be processed inside that call. */ void unblock_input (void) @@ -7288,7 +7354,7 @@ store_user_signal_events (void) } -static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*); +static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void *); static Lisp_Object menu_bar_one_keymap_changed_items; /* These variables hold the vector under construction within @@ -7298,7 +7364,7 @@ static Lisp_Object menu_bar_items_vector; static int menu_bar_items_index; -static const char* separator_names[] = { +static const char *separator_names[] = { "space", "no-line", "single-line", @@ -7473,8 +7539,8 @@ 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, 4, -1); + menu_bar_items_vector + = larger_vector (menu_bar_items_vector, 4, -1); /* Add this item. */ ASET (menu_bar_items_vector, i, Qnil); i++; ASET (menu_bar_items_vector, i, Qnil); i++; @@ -7590,12 +7656,13 @@ eval_dyn (Lisp_Object form) Lisp_Object menu_item_eval_property (Lisp_Object sexpr) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); Lisp_Object val; specbind (Qinhibit_redisplay, Qt); val = internal_condition_case_1 (eval_dyn, sexpr, Qerror, menu_item_eval_property_1); - return unbind_to (count, val); + dynwind_end (); + return val; } /* This function parses a menu item and leaves the result in the @@ -7906,7 +7973,8 @@ static Lisp_Object QCrtl; /* Function prototypes. */ static void init_tool_bar_items (Lisp_Object); -static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*); +static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, + void *); static bool parse_tool_bar_item (Lisp_Object, Lisp_Object); static void append_tool_bar_item (void); @@ -8243,7 +8311,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 = xmalloc (max_lbl + 1); + char *buf = xmalloc_atomic (max_lbl + 1); Lisp_Object new_lbl; ptrdiff_t caption_len = strlen (capt); @@ -8841,8 +8909,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, bool dont_downcase_last, bool can_return_switch_frame, bool fix_current_buffer, bool prevent_redisplay) { - ptrdiff_t count = SPECPDL_INDEX (); - /* How many keys there are in the current key sequence. */ int t; @@ -8909,6 +8975,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, struct gcpro gcpro1; + dynwind_begin (); + GCPRO1 (fake_prefixed_keys); raw_keybuf_count = 0; @@ -8928,8 +8996,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, echo_now (); } else if (cursor_in_echo_area - && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) - && NILP (Fzerop (Vecho_keystrokes))) + && echo_keystrokes_p ()) /* This doesn't put in a dash if the echo buffer is empty, so you don't always see a dash hanging out in the minibuffer. */ echo_dash (); @@ -9061,8 +9128,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { key = keybuf[t]; add_command_key (key); - if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) - && NILP (Fzerop (Vecho_keystrokes)) + if (echo_keystrokes_p () && current_kboard->immediate_echo) { echo_add_key (key); @@ -9142,7 +9208,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Just return -1. */ if (EQ (key, Qt)) { - unbind_to (count, Qnil); + dynwind_end (); UNGCPRO; return -1; } @@ -9378,16 +9444,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, first_unbound = min (t, first_unbound); head = EVENT_HEAD (key); - if (help_char_p (head) && t > 0) - { - read_key_sequence_cmd = Vprefix_help_command; - keybuf[t++] = key; - last_nonmenu_event = key; - /* The Microsoft C compiler can't handle the goto that - would go here. */ - dummyflag = 1; - break; - } if (SYMBOLP (head)) { @@ -9645,6 +9701,17 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, goto replay_sequence; } + + if (NILP (current_binding) + && help_char_p (EVENT_HEAD (key)) && t > 1) + { + read_key_sequence_cmd = Vprefix_help_command; + /* The Microsoft C compiler can't handle the goto that + would go here. */ + dummyflag = 1; + break; + } + /* If KEY is not defined in any of the keymaps, and cannot be part of a function key or translation, and is a shifted function key, @@ -9700,7 +9767,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, : Qnil; unread_switch_frame = delayed_switch_frame; - unbind_to (count, Qnil); + dynwind_end (); /* Don't downcase the last character if the caller says don't. Don't downcase it if the result is undefined, either. */ @@ -9726,8 +9793,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Better ideas? */ for (; t < mock_input; t++) { - if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) - && NILP (Fzerop (Vecho_keystrokes))) + if (echo_keystrokes_p ()) echo_char (keybuf[t]); add_command_key (keybuf[t]); } @@ -9745,7 +9811,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object keybuf[30]; register int i; struct gcpro gcpro1; - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); if (!NILP (prompt)) CHECK_STRING (prompt); @@ -9758,7 +9824,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, memset (keybuf, 0, sizeof keybuf); GCPRO1 (keybuf[0]); - gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0])); + gcpro1.nvars = ARRAYELTS (keybuf); if (NILP (continue_echo)) { @@ -9772,7 +9838,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, cancel_hourglass (); #endif - i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), + i = read_key_sequence (keybuf, ARRAYELTS (keybuf), prompt, ! NILP (dont_downcase_last), ! NILP (can_return_switch_frame), 0, 0); @@ -9791,9 +9857,9 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, QUIT; } UNGCPRO; - return unbind_to (count, - ((allow_string ? make_event_array : Fvector) - (i, keybuf))); + Lisp_Object tem0 = ((allow_string ? make_event_array : Fvector) (i, keybuf)); + dynwind_end (); + return tem0; } DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, @@ -10073,7 +10139,10 @@ DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, "FOpen dribble file: ", doc: /* Start writing all keyboard characters to a dribble file called FILE. If FILE is nil, close any open dribble file. -The file will be closed when Emacs exits. */) +The file will be closed when Emacs exits. + +Be aware that this records ALL characters you type! +This may include sensitive information such as passwords. */) (Lisp_Object file) { if (dribble) @@ -10085,8 +10154,15 @@ The file will be closed when Emacs exits. */) } if (!NILP (file)) { + int fd; + Lisp_Object encfile; + file = Fexpand_file_name (file, Qnil); - dribble = emacs_fopen (SSDATA (file), "w"); + encfile = ENCODE_FILE (file); + fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600); + if (fd < 0 && errno == EEXIST && unlink (SSDATA (encfile)) == 0) + fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600); + dribble = fd < 0 ? 0 : fdopen (fd, "w"); if (dribble == 0) report_file_error ("Opening dribble", file); } @@ -10130,7 +10206,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) { - ptrdiff_t count = SPECPDL_INDEX (); + dynwind_begin (); int old_height, old_width; int width, height; struct gcpro gcpro1; @@ -10157,7 +10233,7 @@ On such systems, Emacs starts a subshell instead of suspending. */) sys_subshell (); else sys_suspend (); - unbind_to (count, Qnil); + dynwind_end (); /* Check if terminal/window size has changed. Note that this is not useful when we are running directly @@ -10297,9 +10373,6 @@ static void handle_interrupt (bool in_signal_handler) { char c; - sigset_t blocked; - sigemptyset (&blocked); - sigaddset (&blocked, SIGINT); cancel_echoing (); @@ -10311,6 +10384,9 @@ handle_interrupt (bool in_signal_handler) /* If SIGINT isn't blocked, don't let us be interrupted by a SIGINT. It might be harmful due to non-reentrancy in I/O functions. */ + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGINT); pthread_sigmask (SIG_BLOCK, &blocked, 0); } @@ -10338,34 +10414,18 @@ handle_interrupt (bool in_signal_handler) is used. Note that [Enter] is not echoed by dos. */ cursor_to (SELECTED_FRAME (), 0, 0); #endif - /* It doesn't work to autosave while GC is in progress; - the code used for auto-saving doesn't cope with the mark bit. */ - if (!gc_in_progress) - { - printf ("Auto-save? (y or n) "); - fflush (stdout); - if (((c = getchar ()) & ~040) == 'Y') - { - Fdo_auto_save (Qt, Qnil); + printf ("Auto-save? (y or n) "); + fflush (stdout); + if (((c = getchar ()) & ~040) == 'Y') + { + Fdo_auto_save (Qt, Qnil); #ifdef MSDOS - printf ("\r\nAuto-save done"); + printf ("\r\nAuto-save done"); #else /* not MSDOS */ - printf ("Auto-save done\n"); + printf ("Auto-save done\n"); #endif /* not MSDOS */ - } - while (c != '\n') c = getchar (); - } - else - { - /* During GC, it must be safe to reenable quitting again. */ - Vinhibit_quit = Qnil; -#ifdef MSDOS - printf ("\r\n"); -#endif /* not MSDOS */ - printf ("Garbage collection in progress; cannot auto-save now\r\n"); - printf ("but will instead do a real quit after garbage collection ends\r\n"); - fflush (stdout); - } + } + while (c != '\n') c = getchar (); #ifdef MSDOS printf ("\r\nAbort? (y or n) "); @@ -10395,7 +10455,7 @@ handle_interrupt (bool in_signal_handler) struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; immediate_quit = 0; - pthread_sigmask (SIG_UNBLOCK, &blocked, 0); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); saved = gl_state; GCPRO4 (saved.object, saved.global_code, saved.current_syntax_table, saved.old_prop); @@ -10416,7 +10476,7 @@ handle_interrupt (bool in_signal_handler) } } - pthread_sigmask (SIG_UNBLOCK, &blocked, 0); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); /* TODO: The longjmp in this call throws the NS event loop integration off, and it seems to do fine without this. Probably some attention @@ -10675,7 +10735,7 @@ The elements of this list correspond to the arguments of } XSETFASTINT (val[3], quit_char); - return Flist (sizeof (val) / sizeof (val[0]), val); + return Flist (ARRAYELTS (val), val); } DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0, @@ -10935,6 +10995,8 @@ static const struct event_head head_table[] = { void syms_of_keyboard (void) { +#include "keyboard.x" + pending_funcalls = Qnil; staticpro (&pending_funcalls); @@ -11043,7 +11105,7 @@ syms_of_keyboard (void) { int i; - int len = sizeof (head_table) / sizeof (head_table[0]); + int len = ARRAYELTS (head_table); for (i = 0; i < len; i++) { @@ -11059,14 +11121,13 @@ syms_of_keyboard (void) staticpro (&button_down_location); mouse_syms = Fmake_vector (make_number (5), Qnil); staticpro (&mouse_syms); - wheel_syms = Fmake_vector (make_number (sizeof (lispy_wheel_names) - / sizeof (lispy_wheel_names[0])), + wheel_syms = Fmake_vector (make_number (ARRAYELTS (lispy_wheel_names)), Qnil); staticpro (&wheel_syms); { int i; - int len = sizeof (modifier_names) / sizeof (modifier_names[0]); + int len = ARRAYELTS (modifier_names); modifier_symbols = Fmake_vector (make_number (len), Qnil); for (i = 0; i < len; i++) @@ -11115,38 +11176,6 @@ syms_of_keyboard (void) help_form_saved_window_configs = Qnil; staticpro (&help_form_saved_window_configs); - defsubr (&Scurrent_idle_time); - defsubr (&Sevent_symbol_parse_modifiers); - defsubr (&Sevent_convert_list); - defsubr (&Sread_key_sequence); - defsubr (&Sread_key_sequence_vector); - defsubr (&Srecursive_edit); - defsubr (&Strack_mouse); - defsubr (&Sinput_pending_p); - defsubr (&Srecent_keys); - defsubr (&Sthis_command_keys); - 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); - defsubr (&Sexit_recursive_edit); - defsubr (&Srecursion_depth); - defsubr (&Scommand_error_default_function); - defsubr (&Stop_level); - defsubr (&Sdiscard_input); - defsubr (&Sopen_dribble_file); - defsubr (&Sset_input_interrupt_mode); - defsubr (&Sset_output_flow_control); - defsubr (&Sset_input_meta_mode); - defsubr (&Sset_quit_char); - defsubr (&Sset_input_mode); - defsubr (&Scurrent_input_mode); - defsubr (&Sposn_at_point); - defsubr (&Sposn_at_x_y); - DEFVAR_LISP ("last-command-event", last_command_event, doc: /* Last input event that was part of a command. */); @@ -11385,6 +11414,7 @@ and tests the value when the command returns. Buffer modification stores t in this variable. */); Vdeactivate_mark = Qnil; DEFSYM (Qdeactivate_mark, "deactivate-mark"); + Fmake_variable_buffer_local (Qdeactivate_mark); DEFVAR_LISP ("pre-command-hook", Vpre_command_hook, doc: /* Normal hook run before each command is executed. @@ -11745,52 +11775,3 @@ keys_of_keyboard (void) initial_define_lispy_key (Vspecial_event_map, "focus-out", "handle-focus-out"); } - -/* Mark the pointers in the kboard objects. - Called by Fgarbage_collect. */ -void -mark_kboards (void) -{ - KBOARD *kb; - Lisp_Object *p; - for (kb = all_kboards; kb; kb = kb->next_kboard) - { - if (kb->kbd_macro_buffer) - for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++) - mark_object (*p); - mark_object (KVAR (kb, Voverriding_terminal_local_map)); - mark_object (KVAR (kb, Vlast_command)); - mark_object (KVAR (kb, Vreal_last_command)); - mark_object (KVAR (kb, Vkeyboard_translate_table)); - mark_object (KVAR (kb, Vlast_repeatable_command)); - mark_object (KVAR (kb, Vprefix_arg)); - mark_object (KVAR (kb, Vlast_prefix_arg)); - mark_object (KVAR (kb, kbd_queue)); - mark_object (KVAR (kb, defining_kbd_macro)); - mark_object (KVAR (kb, Vlast_kbd_macro)); - mark_object (KVAR (kb, Vsystem_key_alist)); - mark_object (KVAR (kb, system_key_syms)); - mark_object (KVAR (kb, Vwindow_system)); - mark_object (KVAR (kb, Vinput_decode_map)); - mark_object (KVAR (kb, Vlocal_function_key_map)); - mark_object (KVAR (kb, Vdefault_minibuffer_frame)); - mark_object (KVAR (kb, echo_string)); - } - { - struct input_event *event; - for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++) - { - if (event == kbd_buffer + KBD_BUFFER_SIZE) - event = kbd_buffer; - /* These two special event types has no Lisp_Objects to mark. */ - 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); - } - } - } -}