X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/bd358779861f265a7acff31ead40172735af693e..3b8d5131a316ad2fdc206744cec489a11f0bf1d3:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index 7cb4c4b91e..8ccbf77871 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -20,10 +20,7 @@ along with GNU Emacs. If not, see . */ #include -#define BLOCKINPUT_INLINE EXTERN_INLINE -#define KEYBOARD_INLINE EXTERN_INLINE - -#include +#include "sysstdio.h" #include "lisp.h" #include "termchar.h" @@ -85,7 +82,7 @@ volatile bool pending_signals; KBOARD *initial_kboard; KBOARD *current_kboard; -KBOARD *all_kboards; +static KBOARD *all_kboards; /* True in the single-kboard state, false in the any-kboard state. */ static bool single_kboard; @@ -221,10 +218,6 @@ static ptrdiff_t last_point_position; 'volatile' here. */ Lisp_Object internal_last_event_frame; -/* The timestamp of the last input event we received from the X server. - X Windows wants this for selection ownership. */ -Time last_event_timestamp; - static Lisp_Object Qx_set_selection, Qhandle_switch_frame; static Lisp_Object Qhandle_select_window; Lisp_Object QPRIMARY; @@ -295,6 +288,7 @@ static struct input_event * volatile kbd_store_ptr; static Lisp_Object Qmouse_movement; static Lisp_Object Qscroll_bar_movement; Lisp_Object Qswitch_frame; +static Lisp_Object Qfocus_in, Qfocus_out; static Lisp_Object Qdelete_frame; static Lisp_Object Qiconify_frame; static Lisp_Object Qmake_frame_visible; @@ -353,13 +347,16 @@ static Lisp_Object Qmodifier_cache; /* Symbols to use for parts of windows. */ Lisp_Object Qmode_line; Lisp_Object Qvertical_line; +Lisp_Object Qright_divider, Qbottom_divider; static Lisp_Object Qvertical_scroll_bar; Lisp_Object Qmenu_bar; -static Lisp_Object recursive_edit_unwind (Lisp_Object buffer); +static Lisp_Object Qecho_keystrokes; + +static void recursive_edit_unwind (Lisp_Object buffer); static Lisp_Object command_loop (void); static Lisp_Object Qcommand_execute; -EMACS_TIME timer_check (void); +struct timespec timer_check (void); static void echo_now (void); static ptrdiff_t echo_length (void); @@ -369,9 +366,9 @@ static Lisp_Object Qpolling_period; /* Incremented whenever a timer is run. */ unsigned timers_run; -/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt +/* Address (if not 0) of struct timespec to zero out if a SIGIO interrupt happens. */ -EMACS_TIME *input_available_clear_time; +struct timespec *input_available_clear_time; /* True means use SIGIO interrupts; false means use CBREAK mode. Default is true if INTERRUPT_INPUT is defined. */ @@ -388,12 +385,12 @@ bool interrupts_deferred; /* The time when Emacs started being idle. */ -static EMACS_TIME timer_idleness_start_time; +static struct timespec timer_idleness_start_time; /* After Emacs stops being idle, this saves the last value of timer_idleness_start_time from when it was idle. */ -static EMACS_TIME timer_last_idleness_start_time; +static struct timespec timer_last_idleness_start_time; /* Global variable declarations. */ @@ -420,12 +417,16 @@ static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object, Lisp_Object, const char *const *, Lisp_Object *, ptrdiff_t); static Lisp_Object make_lispy_switch_frame (Lisp_Object); +static Lisp_Object make_lispy_focus_in (Lisp_Object); +#ifdef HAVE_WINDOW_SYSTEM +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 Lisp_Object apply_modifiers (int, Lisp_Object); static void clear_event (struct input_event *); -static Lisp_Object restore_kboard_configuration (Lisp_Object); +static void restore_kboard_configuration (int); #ifdef USABLE_SIGIO static void deliver_input_available_signal (int signo); #endif @@ -821,7 +822,7 @@ This function is called by the editor initialization to begin editing. */) return Qnil; command_loop_level++; - update_mode_lines = 1; + update_mode_lines = 17; if (command_loop_level && current_buffer != XBUFFER (XWINDOW (selected_window)->contents)) @@ -841,15 +842,14 @@ This function is called by the editor initialization to begin editing. */) return unbind_to (count, Qnil); } -Lisp_Object +void recursive_edit_unwind (Lisp_Object buffer) { if (BUFFERP (buffer)) Fset_buffer (buffer); command_loop_level--; - update_mode_lines = 1; - return Qnil; + update_mode_lines = 18; } @@ -946,7 +946,7 @@ pop_kboard (void) from which further input is accepted. If F is non-nil, set its KBOARD as the current keyboard. - This function uses record_unwind_protect to return to the previous + This function uses record_unwind_protect_int to return to the previous state later. If Emacs is already in single_kboard mode, and F's keyboard is @@ -977,8 +977,7 @@ temporarily_switch_to_single_kboard (struct frame *f) else if (f != NULL) current_kboard = FRAME_KBOARD (f); single_kboard = 1; - record_unwind_protect (restore_kboard_configuration, - (was_locked ? Qt : Qnil)); + record_unwind_protect_int (restore_kboard_configuration, was_locked); } #if 0 /* This function is not needed anymore. */ @@ -987,26 +986,22 @@ record_single_kboard_state () { if (single_kboard) push_kboard (current_kboard); - record_unwind_protect (restore_kboard_configuration, - (single_kboard ? Qt : Qnil)); + record_unwind_protect_int (restore_kboard_configuration, single_kboard); } #endif -static Lisp_Object -restore_kboard_configuration (Lisp_Object was_locked) +static void +restore_kboard_configuration (int was_locked) { - if (NILP (was_locked)) - single_kboard = 0; - else + single_kboard = was_locked; + if (was_locked) { struct kboard *prev = current_kboard; - single_kboard = 1; pop_kboard (); /* The pop should not change the kboard. */ if (single_kboard && current_kboard != prev) emacs_abort (); } - return Qnil; } @@ -1070,8 +1065,6 @@ cmd_error (Lisp_Object data) void cmd_error_internal (Lisp_Object data, const char *context) { - struct frame *sf = SELECTED_FRAME (); - /* The immediate context is not interesting for Quits, since they are asynchronous. */ if (EQ (XCAR (data), Qquit)) @@ -1085,9 +1078,23 @@ cmd_error_internal (Lisp_Object data, const char *context) call3 (Vcommand_error_function, data, context ? build_string (context) : empty_unibyte_string, Vsignaling_function); + + Vsignaling_function = Qnil; +} + +DEFUN ("command-error-default-function", Fcommand_error_default_function, + Scommand_error_default_function, 3, 3, 0, + doc: /* Produce default output for unhandled error message. +Default value of `command-error-function'. */) + (Lisp_Object data, Lisp_Object context, Lisp_Object signal) +{ + struct frame *sf = SELECTED_FRAME (); + + CHECK_STRING (context); + /* If the window system or terminal frame hasn't been initialized yet, or we're not interactive, write the message to stderr and exit. */ - else if (!sf->glyphs_initialized_p + if (!sf->glyphs_initialized_p /* The initial frame is a special non-displaying frame. It will be current in daemon mode when there are no frames to display, and in non-daemon mode before the real frame @@ -1102,7 +1109,7 @@ cmd_error_internal (Lisp_Object data, const char *context) || noninteractive) { print_error_message (data, Qexternal_debugging_output, - context, Vsignaling_function); + SSDATA (context), signal); Fterpri (Qexternal_debugging_output); Fkill_emacs (make_number (-1)); } @@ -1113,10 +1120,9 @@ cmd_error_internal (Lisp_Object data, const char *context) message_log_maybe_newline (); bitch_at_user (); - print_error_message (data, Qt, context, Vsignaling_function); + print_error_message (data, Qt, SSDATA (context), signal); } - - Vsignaling_function = Qnil; + return Qnil; } static Lisp_Object command_loop_2 (Lisp_Object); @@ -1234,7 +1240,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, /* Restore mouse tracking enablement. See Ftrack_mouse for the only use of this function. */ -static Lisp_Object +static void tracking_off (Lisp_Object old_value) { do_mouse_tracking = old_value; @@ -1251,7 +1257,6 @@ tracking_off (Lisp_Object old_value) get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW); } } - return Qnil; } DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, @@ -1285,7 +1290,7 @@ static #endif bool ignore_mouse_drag_p; -static FRAME_PTR +static struct frame * some_mouse_moved (void) { Lisp_Object tail, frame; @@ -1310,24 +1315,15 @@ some_mouse_moved (void) sans error-handling encapsulation. */ static int read_key_sequence (Lisp_Object *, int, Lisp_Object, - bool, bool, bool); + bool, bool, bool, bool); void safe_run_hooks (Lisp_Object); static void adjust_point_for_property (ptrdiff_t, bool); -/* Cancel hourglass from protect_unwind. - ARG is not used. */ -#ifdef HAVE_WINDOW_SYSTEM -static Lisp_Object -cancel_hourglass_unwind (Lisp_Object arg) -{ - cancel_hourglass (); - return Qnil; -} -#endif - /* 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, ... */ @@ -1427,7 +1423,7 @@ command_loop_1 (void) if (!NILP (Vquit_flag)) { Vquit_flag = Qnil; - Vunread_command_events = Fcons (make_number (quit_char), Qnil); + Vunread_command_events = list1 (make_number (quit_char)); } } @@ -1447,7 +1443,7 @@ command_loop_1 (void) /* Read next key sequence; i gets its length. */ i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], - Qnil, 0, 1, 1); + Qnil, 0, 1, 1, 0); /* A filter may have run while we were reading the input. */ if (! FRAME_LIVE_P (XFRAME (selected_frame))) @@ -1528,27 +1524,8 @@ command_loop_1 (void) already_adjusted = 0; if (NILP (Vthis_command)) - { - /* nil means key is undefined. */ - Lisp_Object keys = Fvector (i, keybuf); - keys = Fkey_description (keys, Qnil); - bitch_at_user (); - message_with_string ("%s is undefined", keys, 0); - kset_defining_kbd_macro (current_kboard, Qnil); - update_mode_lines = 1; - /* If this is a down-mouse event, don't reset prefix-arg; - pass it to the command run by the up event. */ - if (EVENT_HAS_PARAMETERS (last_command_event)) - { - Lisp_Object breakdown - = parse_modifiers (EVENT_HEAD (last_command_event)); - int modifiers = XINT (XCAR (XCDR (breakdown))); - if (!(modifiers & down_modifier)) - kset_prefix_arg (current_kboard, Qnil); - } - else - kset_prefix_arg (current_kboard, Qnil); - } + /* nil means key is undefined. */ + call0 (Qundefined); else { /* Here for a command that isn't executed directly. */ @@ -1559,7 +1536,7 @@ command_loop_1 (void) if (display_hourglass_p && NILP (Vexecuting_kbd_macro)) { - record_unwind_protect (cancel_hourglass_unwind, Qnil); + record_unwind_protect_void (cancel_hourglass); start_hourglass (); } #endif @@ -1655,16 +1632,11 @@ command_loop_1 (void) && NILP (Fmemq (Vthis_command, Vselection_inhibit_update_commands))) { - ptrdiff_t beg = - XINT (Fmarker_position (BVAR (current_buffer, mark))); - ptrdiff_t end = PT; - if (beg < end) - call2 (Qx_set_selection, QPRIMARY, - make_buffer_string (beg, end, 0)); - else if (beg > end) - call2 (Qx_set_selection, QPRIMARY, - make_buffer_string (end, beg, 0)); - /* Don't set empty selections. */ + Lisp_Object txt + = call1 (Fsymbol_value (Qregion_extract_function), Qnil); + if (XINT (Flength (txt)) > 0) + /* Don't set empty selections. */ + call2 (Qx_set_selection, QPRIMARY, txt); } if (current_buffer != prev_buffer || MODIFF != prev_modiff) @@ -1693,7 +1665,7 @@ command_loop_1 (void) cluster to prevent automatic composition. To recover the automatic composition, we must update the display. */ - windows_or_buffers_changed++; + windows_or_buffers_changed = 21; if (!already_adjusted) adjust_point_for_property (last_point_position, MODIFF != prev_modiff); @@ -1707,6 +1679,30 @@ command_loop_1 (void) } } +Lisp_Object +read_menu_command (void) +{ + Lisp_Object keybuf[30]; + ptrdiff_t count = SPECPDL_INDEX (); + int i; + + /* We don't want to echo the keystrokes while navigating the + menus. */ + specbind (Qecho_keystrokes, make_number (0)); + + i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], + Qnil, 0, 1, 1, 1); + + unbind_to (count, Qnil); + + if (! FRAME_LIVE_P (XFRAME (selected_frame))) + Fkill_emacs (Qnil); + if (i == 0 || i == -1) + return Qt; + + return read_key_sequence_cmd; +} + /* Adjust point to a boundary of a region that has such a property that should be treated intangible. For the moment, we check `composition', `display' and `invisible' properties. @@ -1776,8 +1772,8 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) than skip both boundaries. However, this code also stops anywhere in a non-sticky text-property, which breaks (e.g.) Org mode. */ - && (val = get_pos_property (make_number (end), - Qinvisible, Qnil), + && (val = Fget_pos_property (make_number (end), + Qinvisible, Qnil), TEXT_PROP_MEANS_INVISIBLE (val)) #endif && !NILP (val = get_char_property_and_overlay @@ -1794,8 +1790,8 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) } while (beg > BEGV #if 0 - && (val = get_pos_property (make_number (beg), - Qinvisible, Qnil), + && (val = Fget_pos_property (make_number (beg), + Qinvisible, Qnil), TEXT_PROP_MEANS_INVISIBLE (val)) #endif && !NILP (val = get_char_property_and_overlay @@ -1848,12 +1844,12 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) to the other end would mean moving backwards and thus could lead to an infinite loop. */ ; - else if (val = get_pos_property (make_number (PT), - Qinvisible, Qnil), + else if (val = Fget_pos_property (make_number (PT), + Qinvisible, Qnil), TEXT_PROP_MEANS_INVISIBLE (val) - && (val = get_pos_property - (make_number (PT == beg ? end : beg), - Qinvisible, Qnil), + && (val = (Fget_pos_property + (make_number (PT == beg ? end : beg), + Qinvisible, Qnil)), !TEXT_PROP_MEANS_INVISIBLE (val))) (check_composition = check_display = 1, SET_PT (PT == beg ? end : beg)); @@ -1958,10 +1954,7 @@ int poll_suppress_count; static struct atimer *poll_timer; -/* Poll for input, so that we catch a C-g if it comes in. This - function is called from x_make_frame_visible, see comment - there. */ - +/* Poll for input, so that we catch a C-g if it comes in. */ void poll_for_input_1 (void) { @@ -2001,10 +1994,10 @@ start_polling (void) /* If poll timer doesn't exist, are we need one with a different interval, start a new one. */ if (poll_timer == NULL - || EMACS_SECS (poll_timer->interval) != polling_period) + || poll_timer->interval.tv_sec != polling_period) { time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); - EMACS_TIME interval = make_emacs_time (period, 0); + struct timespec interval = make_timespec (period, 0); if (poll_timer) cancel_atimer (poll_timer); @@ -2091,6 +2084,9 @@ bind_polling_period (int n) /* Apply the control modifier to CHARACTER. */ +#ifndef HAVE_NTGUI +static +#endif int make_ctrl_char (int c) { @@ -2178,7 +2174,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, This causes trouble if we are trying to read a mouse motion event (i.e., if we are inside a `track-mouse' form), so we restore the mouse_moved flag. */ - FRAME_PTR f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved (); + struct frame *f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved (); help = call1 (Qmouse_fixup_help_message, help); if (f) f->mouse_moved = 1; @@ -2197,18 +2193,17 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, /* Input of single characters from keyboard */ static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, - EMACS_TIME *end_time); + struct timespec *end_time); static void record_char (Lisp_Object c); static Lisp_Object help_form_saved_window_configs; -static Lisp_Object -read_char_help_form_unwind (Lisp_Object arg) +static void +read_char_help_form_unwind (void) { Lisp_Object window_config = XCAR (help_form_saved_window_configs); help_form_saved_window_configs = XCDR (help_form_saved_window_configs); if (!NILP (window_config)) Fset_window_configuration (window_config); - return Qnil; } #define STOP_POLLING \ @@ -2220,7 +2215,7 @@ do { if (polling_stopped_here) start_polling (); \ polling_stopped_here = 0; } while (0) static Lisp_Object -read_event_from_main_queue (EMACS_TIME *end_time, +read_event_from_main_queue (struct timespec *end_time, sys_jmp_buf local_getcjmp, bool *used_mouse_menu) { @@ -2233,7 +2228,7 @@ read_event_from_main_queue (EMACS_TIME *end_time, /* Read from the main queue, and if that gives us something we can't use yet, we put it on the appropriate side queue and try again. */ - if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) + if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0) return c; /* Actually read a character, waiting if necessary. */ @@ -2255,9 +2250,9 @@ read_event_from_main_queue (EMACS_TIME *end_time, emacs_abort (); } if (!CONSP (last)) - kset_kbd_queue (kb, Fcons (c, Qnil)); + kset_kbd_queue (kb, list1 (c)); else - XSETCDR (last, Fcons (c, Qnil)); + XSETCDR (last, list1 (c)); kb->kbd_queue_has_data = 1; c = Qnil; if (single_kboard) @@ -2286,7 +2281,6 @@ read_event_from_main_queue (EMACS_TIME *end_time, XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL)); } - /* FIXME: Decode tty keyboard input here. */ return c; } @@ -2295,7 +2289,7 @@ read_event_from_main_queue (EMACS_TIME *end_time, /* Like `read_event_from_main_queue' but applies keyboard-coding-system to tty input. */ static Lisp_Object -read_decoded_event_from_main_queue (EMACS_TIME *end_time, +read_decoded_event_from_main_queue (struct timespec *end_time, sys_jmp_buf local_getcjmp, Lisp_Object prev_event, bool *used_mouse_menu) @@ -2376,6 +2370,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time, /* 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. @@ -2393,7 +2388,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time, Value is -2 when we find input on another keyboard. A second call to read_char will read it. - If END_TIME is non-null, it is a pointer to an EMACS_TIME + If END_TIME is non-null, it is a pointer to a struct timespec specifying the maximum time to wait until. If no input arrives by that time, stop waiting and return nil. @@ -2402,7 +2397,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time, Lisp_Object read_char (int commandflag, Lisp_Object map, Lisp_Object prev_event, - bool *used_mouse_menu, EMACS_TIME *end_time) + bool *used_mouse_menu, struct timespec *end_time) { Lisp_Object c; ptrdiff_t jmpcount; @@ -2611,10 +2606,8 @@ read_char (int commandflag, Lisp_Object map, if (/* There currently is something in the echo area. */ !NILP (echo_area_buffer[0]) - && (/* And it's either not from echoing. */ - !EQ (echo_area_buffer[0], echo_message_buffer) - /* Or it's an echo from a different kboard. */ - || echo_kboard != current_kboard + && (/* It's an echo from a different kboard. */ + echo_kboard != current_kboard /* Or we explicitly allow overwriting whatever there is. */ || ok_to_echo_at_next_pause == NULL)) cancel_echoing (); @@ -2680,9 +2673,9 @@ read_char (int commandflag, Lisp_Object map, emacs_abort (); } if (!CONSP (last)) - kset_kbd_queue (kb, Fcons (c, Qnil)); + kset_kbd_queue (kb, list1 (c)); else - XSETCDR (last, Fcons (c, Qnil)); + XSETCDR (last, list1 (c)); kb->kbd_queue_has_data = 1; current_kboard = kb; /* This is going to exit from read_char @@ -2742,7 +2735,7 @@ read_char (int commandflag, Lisp_Object map, /* Maybe auto save due to number of keystrokes. */ - if (commandflag != 0 + if (commandflag != 0 && commandflag != -2 && auto_save_interval > 0 && num_nonmacro_input_events - last_auto_save > max (auto_save_interval, 20) && !detect_input_pending_run_timers (0)) @@ -2794,7 +2787,7 @@ read_char (int commandflag, Lisp_Object map, 9 at 200k, 11 at 300k, and 12 at 500k. It is 15 at 1 meg. */ /* Auto save if enough time goes by without input. */ - if (commandflag != 0 + if (commandflag != 0 && commandflag != -2 && num_nonmacro_input_events > last_auto_save && INTEGERP (Vauto_save_timeout) && XINT (Vauto_save_timeout) > 0) @@ -2894,7 +2887,7 @@ read_char (int commandflag, Lisp_Object map, { c = read_decoded_event_from_main_queue (end_time, local_getcjmp, prev_event, used_mouse_menu); - if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) + if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0) goto exit; if (EQ (c, make_number (-2))) { @@ -3000,7 +2993,7 @@ read_char (int commandflag, Lisp_Object map, if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) { /* Change menu-bar to (menu-bar) as the event "position". */ - POSN_SET_POSN (EVENT_START (c), Fcons (posn, Qnil)); + POSN_SET_POSN (EVENT_START (c), list1 (posn)); also_record = c; Vunread_command_events = Fcons (c, Vunread_command_events); @@ -3197,7 +3190,7 @@ read_char (int commandflag, Lisp_Object map, help_form_saved_window_configs = Fcons (Fcurrent_window_configuration (Qnil), help_form_saved_window_configs); - record_unwind_protect (read_char_help_form_unwind, Qnil); + record_unwind_protect_void (read_char_help_form_unwind); call0 (Qhelp_form_show); cancel_echoing (); @@ -3257,7 +3250,7 @@ record_menu_key (Lisp_Object c) /* Record this character as part of the current key. */ add_command_key (c); - /* Re-reading in the middle of a command */ + /* Re-reading in the middle of a command. */ last_input_event = c; num_input_events++; } @@ -3583,8 +3576,8 @@ kbd_buffer_store_event_hold (register struct input_event *event, if (single_kboard && kb != current_kboard) { kset_kbd_queue - (kb, Fcons (make_lispy_switch_frame (event->frame_or_window), - Fcons (make_number (c), Qnil))); + (kb, list2 (make_lispy_switch_frame (event->frame_or_window), + make_number (c))); kb->kbd_queue_has_data = 1; for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) { @@ -3621,8 +3614,6 @@ kbd_buffer_store_event_hold (register struct input_event *event, Vlast_event_frame = focus; } - last_event_timestamp = event->timestamp; - handle_interrupt (0); return; } @@ -3815,7 +3806,7 @@ clear_event (struct input_event *event) static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, - EMACS_TIME *end_time) + struct timespec *end_time) { Lisp_Object obj; @@ -3873,20 +3864,35 @@ kbd_buffer_get_event (KBOARD **kbp, break; if (end_time) { - EMACS_TIME now = current_emacs_time (); - if (EMACS_TIME_LE (*end_time, now)) + struct timespec now = current_timespec (); + if (timespec_cmp (*end_time, now) <= 0) return Qnil; /* Finished waiting. */ else { - EMACS_TIME duration = sub_emacs_time (*end_time, now); - wait_reading_process_output (min (EMACS_SECS (duration), + struct timespec duration = timespec_sub (*end_time, now); + wait_reading_process_output (min (duration.tv_sec, WAIT_READING_MAX), - EMACS_NSECS (duration), + duration.tv_nsec, -1, 1, Qnil, NULL, 0); } } else - wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0); + { + bool do_display = true; + + if (FRAME_TERMCAP_P (SELECTED_FRAME ())) + { + struct tty_display_info *tty = CURTTY (); + + /* When this TTY is displaying a menu, we must prevent + any redisplay, because we modify the frame's glyph + matrix behind the back of the display engine. */ + if (tty->showing_menu) + do_display = false; + } + + wait_reading_process_output (0, 0, -1, do_display, Qnil, NULL, 0); + } if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr) gobble_input (); @@ -3912,8 +3918,6 @@ kbd_buffer_get_event (KBOARD **kbp, ? kbd_fetch_ptr : kbd_buffer); - last_event_timestamp = event->timestamp; - *kbp = event_to_kboard (event); if (*kbp == 0) *kbp = current_kboard; /* Better than returning null ptr? */ @@ -3947,9 +3951,9 @@ kbd_buffer_get_event (KBOARD **kbp, else if (event->kind == NS_TEXT_EVENT) { if (event->code == KEY_NS_PUT_WORKING_TEXT) - obj = Fcons (intern ("ns-put-working-text"), Qnil); + obj = list1 (intern ("ns-put-working-text")); else - obj = Fcons (intern ("ns-unput-working-text"), Qnil); + obj = list1 (intern ("ns-unput-working-text")); kbd_fetch_ptr = event + 1; if (used_mouse_menu) *used_mouse_menu = 1; @@ -3961,8 +3965,7 @@ kbd_buffer_get_event (KBOARD **kbp, else if (event->kind == DELETE_WINDOW_EVENT) { /* Make an event (delete-frame (FRAME)). */ - obj = Fcons (event->frame_or_window, Qnil); - obj = Fcons (Qdelete_frame, Fcons (obj, Qnil)); + obj = list2 (Qdelete_frame, list1 (event->frame_or_window)); kbd_fetch_ptr = event + 1; } #endif @@ -3971,15 +3974,13 @@ kbd_buffer_get_event (KBOARD **kbp, else if (event->kind == ICONIFY_EVENT) { /* Make an event (iconify-frame (FRAME)). */ - obj = Fcons (event->frame_or_window, Qnil); - obj = Fcons (Qiconify_frame, Fcons (obj, Qnil)); + obj = list2 (Qiconify_frame, list1 (event->frame_or_window)); kbd_fetch_ptr = event + 1; } else if (event->kind == DEICONIFY_EVENT) { /* Make an event (make-frame-visible (FRAME)). */ - obj = Fcons (event->frame_or_window, Qnil); - obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil)); + obj = list2 (Qmake_frame_visible, list1 (event->frame_or_window)); kbd_fetch_ptr = event + 1; } #endif @@ -4002,11 +4003,11 @@ kbd_buffer_get_event (KBOARD **kbp, #ifdef HAVE_NTGUI else if (event->kind == LANGUAGE_CHANGE_EVENT) { - /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */ - obj = Fcons (Qlanguage_change, - list3 (event->frame_or_window, - make_number (event->code), - make_number (event->modifiers))); + /* 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)); kbd_fetch_ptr = event + 1; } #endif @@ -4015,11 +4016,11 @@ kbd_buffer_get_event (KBOARD **kbp, { #ifdef HAVE_W32NOTIFY /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */ - obj = Fcons (Qfile_notify, - list2 (list3 (make_number (event->code), - XCAR (event->arg), - XCDR (event->arg)), - event->frame_or_window)); + obj = list3 (Qfile_notify, + list3 (make_number (event->code), + XCAR (event->arg), + XCDR (event->arg)), + event->frame_or_window); #else obj = make_lispy_event (event); #endif @@ -4028,7 +4029,7 @@ kbd_buffer_get_event (KBOARD **kbp, #endif /* USE_FILE_NOTIFY */ else if (event->kind == SAVE_SESSION_EVENT) { - obj = Fcons (Qsave_session, Fcons (event->arg, Qnil)); + obj = list2 (Qsave_session, event->arg); kbd_fetch_ptr = event + 1; } /* Just discard these, by returning nil. @@ -4065,17 +4066,43 @@ kbd_buffer_get_event (KBOARD **kbp, switch-frame event if necessary. */ Lisp_Object frame, focus; - frame = event->frame_or_window; - focus = FRAME_FOCUS_FRAME (XFRAME (frame)); - if (FRAMEP (focus)) - frame = focus; + frame = event->frame_or_window; + focus = FRAME_FOCUS_FRAME (XFRAME (frame)); + if (FRAMEP (focus)) + frame = focus; - if (!EQ (frame, internal_last_event_frame) - && !EQ (frame, selected_frame)) - obj = make_lispy_switch_frame (frame); - internal_last_event_frame = frame; - kbd_fetch_ptr = event + 1; - } + if ( +#ifdef HAVE_X11 + ! NILP (event->arg) + && +#endif + !EQ (frame, internal_last_event_frame) + && !EQ (frame, selected_frame)) + obj = make_lispy_switch_frame (frame); + else + obj = make_lispy_focus_in (frame); + + internal_last_event_frame = frame; + kbd_fetch_ptr = event + 1; + } + else if (event->kind == FOCUS_OUT_EVENT) + { +#ifdef HAVE_WINDOW_SYSTEM + + Display_Info *di; + Lisp_Object frame = event->frame_or_window; + bool focused = false; + + for (di = x_display_list; di && ! focused; di = di->next) + focused = di->x_highlight_frame != 0; + + if (!focused) + obj = make_lispy_focus_out (frame); + +#endif /* HAVE_WINDOW_SYSTEM */ + + kbd_fetch_ptr = event + 1; + } #ifdef HAVE_DBUS else if (event->kind == DBUS_EVENT) { @@ -4146,7 +4173,7 @@ kbd_buffer_get_event (KBOARD **kbp, /* Try generating a mouse motion event. */ else if (!NILP (do_mouse_tracking) && some_mouse_moved ()) { - FRAME_PTR f = some_mouse_moved (); + struct frame *f = some_mouse_moved (); Lisp_Object bar_window; enum scroll_bar_part part; Lisp_Object x, y; @@ -4252,8 +4279,6 @@ process_special_events (void) else kbd_fetch_ptr++; - /* X wants last_event_timestamp for selection ownership. */ - last_event_timestamp = copy.timestamp; input_pending = readable_events (0); x_handle_selection_event (©); #else @@ -4289,10 +4314,10 @@ static void timer_start_idle (void) { /* If we are already in the idle state, do nothing. */ - if (EMACS_TIME_VALID_P (timer_idleness_start_time)) + if (timespec_valid_p (timer_idleness_start_time)) return; - timer_idleness_start_time = current_emacs_time (); + timer_idleness_start_time = current_timespec (); timer_last_idleness_start_time = timer_idleness_start_time; /* Mark all idle-time timers as once again candidates for running. */ @@ -4304,7 +4329,7 @@ timer_start_idle (void) static void timer_stop_idle (void) { - timer_idleness_start_time = invalid_emacs_time (); + timer_idleness_start_time = invalid_timespec (); } /* Resume idle timer from last idle start time. */ @@ -4312,7 +4337,7 @@ timer_stop_idle (void) static void timer_resume_idle (void) { - if (EMACS_TIME_VALID_P (timer_idleness_start_time)) + if (timespec_valid_p (timer_idleness_start_time)) return; timer_idleness_start_time = timer_last_idleness_start_time; @@ -4328,7 +4353,7 @@ Lisp_Object pending_funcalls; /* Return true if TIMER is a valid timer, placing its value into *RESULT. */ static bool -decode_timer (Lisp_Object timer, EMACS_TIME *result) +decode_timer (Lisp_Object timer, struct timespec *result) { Lisp_Object *vector; @@ -4355,16 +4380,16 @@ decode_timer (Lisp_Object timer, EMACS_TIME *result) In that case we return 0 to indicate that a new timer_check_2 call should be done. */ -static EMACS_TIME +static struct timespec timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) { - EMACS_TIME nexttime; - EMACS_TIME now; - EMACS_TIME idleness_now; + struct timespec nexttime; + struct timespec now; + struct timespec idleness_now; Lisp_Object chosen_timer; struct gcpro gcpro1; - nexttime = invalid_emacs_time (); + nexttime = invalid_timespec (); chosen_timer = Qnil; GCPRO1 (chosen_timer); @@ -4379,19 +4404,19 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) if (CONSP (timers) || CONSP (idle_timers)) { - now = current_emacs_time (); - idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time) - ? sub_emacs_time (now, timer_idleness_start_time) - : make_emacs_time (0, 0)); + now = current_timespec (); + idleness_now = (timespec_valid_p (timer_idleness_start_time) + ? timespec_sub (now, timer_idleness_start_time) + : make_timespec (0, 0)); } while (CONSP (timers) || CONSP (idle_timers)) { Lisp_Object timer = Qnil, idle_timer = Qnil; - EMACS_TIME timer_time, idle_timer_time; - EMACS_TIME difference; - EMACS_TIME timer_difference = invalid_emacs_time (); - EMACS_TIME idle_timer_difference = invalid_emacs_time (); + struct timespec timer_time, idle_timer_time; + struct timespec difference; + struct timespec timer_difference = invalid_timespec (); + struct timespec idle_timer_difference = invalid_timespec (); bool ripe, timer_ripe = 0, idle_timer_ripe = 0; /* Set TIMER and TIMER_DIFFERENCE @@ -4408,10 +4433,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) continue; } - timer_ripe = EMACS_TIME_LE (timer_time, now); + timer_ripe = timespec_cmp (timer_time, now) <= 0; timer_difference = (timer_ripe - ? sub_emacs_time (now, timer_time) - : sub_emacs_time (timer_time, now)); + ? timespec_sub (now, timer_time) + : timespec_sub (timer_time, now)); } /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE @@ -4425,26 +4450,27 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) continue; } - idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now); + idle_timer_ripe = timespec_cmp (idle_timer_time, idleness_now) <= 0; idle_timer_difference = (idle_timer_ripe - ? sub_emacs_time (idleness_now, idle_timer_time) - : sub_emacs_time (idle_timer_time, idleness_now)); + ? timespec_sub (idleness_now, idle_timer_time) + : timespec_sub (idle_timer_time, idleness_now)); } /* Decide which timer is the next timer, and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly. Also step down the list where we found that timer. */ - if (EMACS_TIME_VALID_P (timer_difference) - && (! EMACS_TIME_VALID_P (idle_timer_difference) + if (timespec_valid_p (timer_difference) + && (! timespec_valid_p (idle_timer_difference) || idle_timer_ripe < timer_ripe || (idle_timer_ripe == timer_ripe - && (timer_ripe - ? EMACS_TIME_LT (idle_timer_difference, + && ((timer_ripe + ? timespec_cmp (idle_timer_difference, timer_difference) - : EMACS_TIME_LT (timer_difference, - idle_timer_difference))))) + : timespec_cmp (timer_difference, + idle_timer_difference)) + < 0)))) { chosen_timer = timer; timers = XCDR (timers); @@ -4484,7 +4510,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) return 0 to indicate that. */ } - nexttime = make_emacs_time (0, 0); + nexttime = make_timespec (0, 0); break; } else @@ -4512,10 +4538,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) As long as any timer is ripe, we run it. */ -EMACS_TIME +struct timespec timer_check (void) { - EMACS_TIME nexttime; + struct timespec nexttime; Lisp_Object timers, idle_timers; struct gcpro gcpro1, gcpro2; @@ -4529,7 +4555,7 @@ timer_check (void) /* Always consider the ordinary timers. */ timers = Fcopy_sequence (Vtimer_list); /* Consider the idle timers only if Emacs is idle. */ - if (EMACS_TIME_VALID_P (timer_idleness_start_time)) + if (timespec_valid_p (timer_idleness_start_time)) idle_timers = Fcopy_sequence (Vtimer_idle_list); else idle_timers = Qnil; @@ -4542,7 +4568,7 @@ timer_check (void) { nexttime = timer_check_2 (timers, idle_timers); } - while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0); + while (nexttime.tv_sec == 0 && nexttime.tv_nsec == 0); UNGCPRO; return nexttime; @@ -4558,9 +4584,9 @@ The value when Emacs is not idle is nil. PSEC is a multiple of the system clock resolution. */) (void) { - if (EMACS_TIME_VALID_P (timer_idleness_start_time)) - return make_lisp_time (sub_emacs_time (current_emacs_time (), - timer_idleness_start_time)); + if (timespec_valid_p (timer_idleness_start_time)) + return make_lisp_time (timespec_sub (current_timespec (), + timer_idleness_start_time)); return Qnil; } @@ -5274,6 +5300,20 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, dy = yret = wy; } /* Nothing special for part == ON_SCROLL_BAR. */ + else if (part == ON_RIGHT_DIVIDER) + { + posn = Qright_divider; + width = WINDOW_RIGHT_DIVIDER_WIDTH (w); + dx = xret = wx; + dy = yret = wy; + } + else if (part == ON_BOTTOM_DIVIDER) + { + posn = Qbottom_divider; + width = WINDOW_BOTTOM_DIVIDER_WIDTH (w); + dx = xret = wx; + dy = yret = wy; + } /* For clicks in the text area, fringes, or margins, call buffer_posn_from_coords to extract TEXTPOS, the buffer @@ -5355,6 +5395,20 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, extra_info)))); } +/* Return non-zero if F is a GUI frame that uses some toolkit-managed + menu bar. This really means that Emacs draws and manages the menu + bar as part of its normal display, and therefore can compute its + geometry. */ +static bool +toolkit_menubar_in_use (struct frame *f) +{ +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI) + return !(!FRAME_WINDOW_P (f)); +#else + return false; +#endif +} + /* Given a struct input_event, build the lisp event which represents it. If EVENT is 0, build a mouse movement event from the mouse movement buffer, which should have a movement event in it. @@ -5490,6 +5544,9 @@ make_lispy_event (struct input_event *event) /* A mouse click. Figure out where it is, decide whether it's a press, click or drag, and build the appropriate structure. */ case MOUSE_CLICK_EVENT: +#ifdef HAVE_GPM + case GPM_CLICK_EVENT: +#endif #ifndef USE_TOOLKIT_SCROLL_BARS case SCROLL_BAR_CLICK_EVENT: #endif @@ -5503,69 +5560,71 @@ make_lispy_event (struct input_event *event) position = Qnil; /* Build the position as appropriate for this mouse click. */ - if (event->kind == MOUSE_CLICK_EVENT) + if (event->kind == MOUSE_CLICK_EVENT +#ifdef HAVE_GPM + || event->kind == GPM_CLICK_EVENT +#endif + ) { struct frame *f = XFRAME (event->frame_or_window); -#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) && ! defined (HAVE_NS) int row, column; -#endif /* Ignore mouse events that were made on frame that have been deleted. */ if (! FRAME_LIVE_P (f)) return Qnil; -#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) && ! defined (HAVE_NS) /* EVENT->x and EVENT->y are frame-relative pixel coordinates at this place. Under old redisplay, COLUMN and ROW are set to frame relative glyph coordinates which are then used to determine whether this click is in a menu (non-toolkit version). */ - pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), - &column, &row, NULL, 1); - - /* In the non-toolkit version, clicks on the menu bar - are ordinary button events in the event buffer. - Distinguish them, and invoke the menu. - - (In the toolkit version, the toolkit handles the menu bar - and Emacs doesn't know about it until after the user - makes a selection.) */ - if (row >= 0 && row < FRAME_MENU_BAR_LINES (f) - && (event->modifiers & down_modifier)) + if (!toolkit_menubar_in_use (f)) { - Lisp_Object items, item; - - /* Find the menu bar item under `column'. */ - item = Qnil; - items = FRAME_MENU_BAR_ITEMS (f); - for (i = 0; i < ASIZE (items); i += 4) + pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), + &column, &row, NULL, 1); + + /* In the non-toolkit version, clicks on the menu bar + are ordinary button events in the event buffer. + Distinguish them, and invoke the menu. + + (In the toolkit version, the toolkit handles the + menu bar and Emacs doesn't know about it until + after the user makes a selection.) */ + if (row >= 0 && row < FRAME_MENU_BAR_LINES (f) + && (event->modifiers & down_modifier)) { - Lisp_Object pos, string; - string = AREF (items, i + 1); - pos = AREF (items, i + 3); - if (NILP (string)) - break; - if (column >= XINT (pos) - && column < XINT (pos) + SCHARS (string)) + Lisp_Object items, item; + + /* Find the menu bar item under `column'. */ + item = Qnil; + items = FRAME_MENU_BAR_ITEMS (f); + for (i = 0; i < ASIZE (items); i += 4) { - item = AREF (items, i); - break; + Lisp_Object pos, string; + string = AREF (items, i + 1); + pos = AREF (items, i + 3); + if (NILP (string)) + break; + if (column >= XINT (pos) + && column < XINT (pos) + SCHARS (string)) + { + item = AREF (items, i); + break; + } } - } - /* ELisp manual 2.4b says (x y) are window relative but - code says they are frame-relative. */ - position - = Fcons (event->frame_or_window, - Fcons (Qmenu_bar, - Fcons (Fcons (event->x, event->y), - Fcons (make_number (event->timestamp), - Qnil)))); + /* ELisp manual 2.4b says (x y) are window + relative but code says they are + frame-relative. */ + position = list4 (event->frame_or_window, + Qmenu_bar, + Fcons (event->x, event->y), + make_number (event->timestamp)); - return Fcons (item, Fcons (position, Qnil)); + return list2 (item, position); + } } -#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */ position = make_lispy_position (f, event->x, event->y, event->timestamp); @@ -5582,12 +5641,9 @@ make_lispy_event (struct input_event *event) portion_whole = Fcons (event->x, event->y); part = *scroll_bar_parts[(int) event->part]; - position - = Fcons (window, - Fcons (Qvertical_scroll_bar, - Fcons (portion_whole, - Fcons (make_number (event->timestamp), - Fcons (part, Qnil))))); + position = list5 (window, Qvertical_scroll_bar, + portion_whole, make_number (event->timestamp), + part); } #endif /* not USE_TOOLKIT_SCROLL_BARS */ @@ -5735,19 +5791,11 @@ make_lispy_event (struct input_event *event) &mouse_syms, ASIZE (mouse_syms)); if (event->modifiers & drag_modifier) - return Fcons (head, - Fcons (start_pos, - Fcons (position, - Qnil))); + return list3 (head, start_pos, position); else if (event->modifiers & (double_modifier | triple_modifier)) - return Fcons (head, - Fcons (position, - Fcons (make_number (double_click_count), - Qnil))); + return list3 (head, position, make_number (double_click_count)); else - return Fcons (head, - Fcons (position, - Qnil)); + return list2 (head, position); } } @@ -5846,14 +5894,9 @@ make_lispy_event (struct input_event *event) } if (event->modifiers & (double_modifier | triple_modifier)) - return Fcons (head, - Fcons (position, - Fcons (make_number (double_click_count), - Qnil))); + return list3 (head, position, make_number (double_click_count)); else - return Fcons (head, - Fcons (position, - Qnil)); + return list2 (head, position); } @@ -5884,12 +5927,8 @@ make_lispy_event (struct input_event *event) portion_whole = Fcons (event->x, event->y); part = *scroll_bar_parts[(int) event->part]; - position - = Fcons (window, - Fcons (Qvertical_scroll_bar, - Fcons (portion_whole, - Fcons (make_number (event->timestamp), - Fcons (part, Qnil))))); + position = list5 (window, Qvertical_scroll_bar, portion_whole, + make_number (event->timestamp), part); /* Always treat scroll bar events as clicks. */ event->modifiers |= click_modifier; @@ -5907,14 +5946,14 @@ make_lispy_event (struct input_event *event) Vlispy_mouse_stem, NULL, &mouse_syms, ASIZE (mouse_syms)); - return Fcons (head, Fcons (position, Qnil)); + return list2 (head, position); } #endif /* USE_TOOLKIT_SCROLL_BARS */ case DRAG_N_DROP_EVENT: { - FRAME_PTR f; + struct frame *f; Lisp_Object head, position; Lisp_Object files; @@ -5933,10 +5972,7 @@ make_lispy_event (struct input_event *event) Qdrag_n_drop, Qnil, lispy_drag_n_drop_names, &drag_n_drop_syms, 1); - return Fcons (head, - Fcons (position, - Fcons (files, - Qnil))); + return list3 (head, position, files); } #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ @@ -5946,22 +5982,20 @@ make_lispy_event (struct input_event *event) /* This is the prefix key. We translate this to `(menu_bar)' because the code in keyboard.c for menu events, which we use, relies on this. */ - return Fcons (Qmenu_bar, Qnil); + return list1 (Qmenu_bar); return event->arg; #endif case SELECT_WINDOW_EVENT: /* Make an event (select-window (WINDOW)). */ - return Fcons (Qselect_window, - Fcons (Fcons (event->frame_or_window, Qnil), - Qnil)); + return list2 (Qselect_window, list1 (event->frame_or_window)); case TOOL_BAR_EVENT: if (EQ (event->arg, event->frame_or_window)) /* This is the prefix key. We translate this to `(tool_bar)' because the code in keyboard.c for tool bar events, which we use, relies on this. */ - return Fcons (Qtool_bar, Qnil); + return list1 (Qtool_bar); else if (SYMBOLP (event->arg)) return apply_modifiers (event->modifiers, event->arg); return event->arg; @@ -5993,69 +6027,8 @@ make_lispy_event (struct input_event *event) #endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */ case CONFIG_CHANGED_EVENT: - return Fcons (Qconfig_changed_event, - Fcons (event->arg, - Fcons (event->frame_or_window, Qnil))); -#ifdef HAVE_GPM - case GPM_CLICK_EVENT: - { - FRAME_PTR f = XFRAME (event->frame_or_window); - Lisp_Object head, position; - Lisp_Object *start_pos_ptr; - Lisp_Object start_pos; - int button = event->code; - - if (button >= ASIZE (button_down_location)) - { - ptrdiff_t incr = button - ASIZE (button_down_location) + 1; - button_down_location = larger_vector (button_down_location, - incr, -1); - mouse_syms = larger_vector (mouse_syms, incr, -1); - } - - start_pos_ptr = aref_addr (button_down_location, button); - start_pos = *start_pos_ptr; - - position = make_lispy_position (f, event->x, event->y, - event->timestamp); - - if (event->modifiers & down_modifier) - *start_pos_ptr = Fcopy_alist (position); - else if (event->modifiers & (up_modifier | drag_modifier)) - { - if (!CONSP (start_pos)) - return Qnil; - event->modifiers &= ~up_modifier; - } - - head = modify_event_symbol (button, - event->modifiers, - Qmouse_click, Vlispy_mouse_stem, - NULL, - &mouse_syms, - ASIZE (mouse_syms)); - - if (event->modifiers & drag_modifier) - return Fcons (head, - Fcons (start_pos, - Fcons (position, - Qnil))); - else if (event->modifiers & double_modifier) - return Fcons (head, - Fcons (position, - Fcons (make_number (2), - Qnil))); - else if (event->modifiers & triple_modifier) - return Fcons (head, - Fcons (position, - Fcons (make_number (3), - Qnil))); - else - return Fcons (head, - Fcons (position, - Qnil)); - } -#endif /* HAVE_GPM */ + return list3 (Qconfig_changed_event, + event->arg, event->frame_or_window); /* The 'kind' field of the event is something we don't recognize. */ default: @@ -6064,7 +6037,7 @@ make_lispy_event (struct input_event *event) } static Lisp_Object -make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part, +make_lispy_movement (struct frame *frame, Lisp_Object bar_window, enum scroll_bar_part part, Lisp_Object x, Lisp_Object y, Time t) { /* Is it a scroll bar movement? */ @@ -6073,13 +6046,12 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa Lisp_Object part_sym; part_sym = *scroll_bar_parts[(int) part]; - return Fcons (Qscroll_bar_movement, - Fcons (list5 (bar_window, - Qvertical_scroll_bar, - Fcons (x, y), - make_number (t), - part_sym), - Qnil)); + return list2 (Qscroll_bar_movement, + list5 (bar_window, + Qvertical_scroll_bar, + Fcons (x, y), + make_number (t), + part_sym)); } /* Or is it an ordinary mouse movement? */ else @@ -6094,9 +6066,25 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa static Lisp_Object make_lispy_switch_frame (Lisp_Object frame) { - return Fcons (Qswitch_frame, Fcons (frame, Qnil)); + return list2 (Qswitch_frame, frame); } - + +static Lisp_Object +make_lispy_focus_in (Lisp_Object frame) +{ + return list2 (Qfocus_in, frame); +} + +#ifdef HAVE_WINDOW_SYSTEM + +static Lisp_Object +make_lispy_focus_out (Lisp_Object frame) +{ + return list2 (Qfocus_out, frame); +} + +#endif /* HAVE_WINDOW_SYSTEM */ + /* Manipulating modifiers. */ /* Parse the name of SYMBOL, and return the set of modifiers it contains. @@ -6327,7 +6315,7 @@ parse_modifiers (Lisp_Object symbol) if (modifiers & ~INTMASK) emacs_abort (); XSETFASTINT (mask, modifiers); - elements = Fcons (unmodified, Fcons (mask, Qnil)); + elements = list2 (unmodified, mask); /* Cache the parsing results on SYMBOL. */ Fput (symbol, Qevent_symbol_element_mask, @@ -6400,7 +6388,7 @@ apply_modifiers (int modifiers, Lisp_Object base) the caches: XSETFASTINT (idx, modifiers); Fput (new_symbol, Qevent_symbol_element_mask, - Fcons (base, Fcons (idx, Qnil))); + list2 (base, idx)); Fput (new_symbol, Qevent_symbol_elements, Fcons (base, lispy_modifier_list (modifiers))); Sadly, this is only correct if `base' is indeed a base event, @@ -7009,7 +6997,7 @@ tty_read_avail_input (struct terminal *terminal, { nread = emacs_read (fileno (tty->input), (char *) cbuf, n_to_read); /* POSIX infers that processes which are not in the session leader's - process group won't get SIGHUP's at logout time. BSDI adheres to + process group won't get SIGHUPs at logout time. BSDI adheres to this part standard and returns -1 from read (0) with errno==EIO when the control tty is taken away. Jeffrey Honig says this is generally safe. */ @@ -7106,7 +7094,8 @@ process_pending_signals (void) } /* Undo any number of BLOCK_INPUT calls down to level LEVEL, - and also (if the level is now 0) reinvoke any pending signal. */ + and reinvoke any pending signal if the level is now 0 and + a fatal error is not already in progress. */ void unblock_input_to (int level) @@ -7114,7 +7103,7 @@ unblock_input_to (int level) interrupt_input_blocked = level; if (level == 0) { - if (pending_signals) + if (pending_signals && !fatal_error_in_progress) process_pending_signals (); } else if (level < 0) @@ -7149,7 +7138,7 @@ handle_input_available_signal (int sig) pending_signals = 1; if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); + *input_available_clear_time = make_timespec (0, 0); } static void @@ -7236,7 +7225,7 @@ handle_user_signal (int sig) /* Tell wait_reading_process_output that it needs to wake up and look around. */ if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); + *input_available_clear_time = make_timespec (0, 0); } break; } @@ -7552,7 +7541,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm ASET (menu_bar_items_vector, i, key); i++; ASET (menu_bar_items_vector, i, AREF (item_properties, ITEM_PROPERTY_NAME)); i++; - ASET (menu_bar_items_vector, i, Fcons (item, Qnil)); i++; + ASET (menu_bar_items_vector, i, list1 (item)); i++; ASET (menu_bar_items_vector, i, make_number (0)); i++; menu_bar_items_index = i; } @@ -8107,7 +8096,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) /* As an exception, allow old-style menu separators. */ if (STRINGP (XCAR (item))) - item = Fcons (XCAR (item), Qnil); + item = list1 (XCAR (item)); else if (!EQ (XCAR (item), Qmenu_item) || (item = XCDR (item), !CONSP (item))) return 0; @@ -8378,7 +8367,6 @@ read_char_x_menu_prompt (Lisp_Object map, if (! menu_prompting) return Qnil; -#ifdef HAVE_MENUS /* If we got to this point via a mouse click, use a real menu for mouse selection. */ if (EVENT_HAS_PARAMETERS (prev_event) @@ -8424,7 +8412,6 @@ read_char_x_menu_prompt (Lisp_Object map, *used_mouse_menu = 1; return value; } -#endif /* HAVE_MENUS */ return Qnil ; } @@ -8454,7 +8441,7 @@ read_char_minibuf_menu_prompt (int commandflag, return Qnil; #define PUSH_C_STR(str, listvar) \ - listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar) + listvar = Fcons (build_unibyte_string (str), listvar) /* Prompt string always starts with map's prompt, and a space. */ prompt_strings = Fcons (name, prompt_strings); @@ -8807,6 +8794,9 @@ test_undefined (Lisp_Object binding) Echo starting immediately unless `prompt' is 0. + If PREVENT_REDISPLAY is non-zero, avoid redisplay by calling + read_char with a suitable COMMANDFLAG argument. + Where a key sequence ends depends on the currently active keymaps. These include any minor mode keymaps active in the current buffer, the current buffer's local map, and the global map. @@ -8839,7 +8829,7 @@ test_undefined (Lisp_Object binding) static int 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 fix_current_buffer, bool prevent_redisplay) { ptrdiff_t count = SPECPDL_INDEX (); @@ -8920,8 +8910,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { if (!NILP (prompt)) { - /* Install the string STR as the beginning of the string of - echoing, so that it serves as a prompt for the next + /* 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); @@ -9076,7 +9066,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { KBOARD *interrupted_kboard = current_kboard; struct frame *interrupted_frame = SELECTED_FRAME (); - key = read_char (NILP (prompt), + /* Calling read_char with COMMANDFLAG = -2 avoids + redisplay in read_char and its subroutines. */ + key = read_char (prevent_redisplay ? -2 : NILP (prompt), current_binding, last_nonmenu_event, &used_mouse_menu, NULL); if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ @@ -9339,8 +9331,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, /* Zap the position in key, so we know that we've expanded it, and don't try to do so again. */ - POSN_SET_POSN (EVENT_START (key), - Fcons (posn, Qnil)); + POSN_SET_POSN (EVENT_START (key), list1 (posn)); mock_input = t + 2; goto replay_sequence; @@ -9495,8 +9486,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, new_head = apply_modifiers (modifiers, XCAR (breakdown)); - new_click - = Fcons (new_head, Fcons (EVENT_START (key), Qnil)); + new_click = list2 (new_head, EVENT_START (key)); /* Look for a binding for this new key. */ new_binding = follow_key (current_binding, new_click); @@ -9736,54 +9726,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, return t; } -DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, - doc: /* Read a sequence of keystrokes and return as a string or vector. -The sequence is sufficient to specify a non-prefix command in the -current local and global maps. - -First arg PROMPT is a prompt string. If nil, do not prompt specially. -Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos -as a continuation of the previous key. - -The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not -convert the last event to lower case. (Normally any upper case event -is converted to lower case if the original event is undefined and the lower -case equivalent is defined.) A non-nil value is appropriate for reading -a key sequence to be defined. - -A C-g typed while in this function is treated like any other character, -and `quit-flag' is not set. - -If the key sequence starts with a mouse click, then the sequence is read -using the keymaps of the buffer of the window clicked in, not the buffer -of the selected window as normal. - -`read-key-sequence' drops unbound button-down events, since you normally -only care about the click or drag events which follow them. If a drag -or multi-click event is unbound, but the corresponding click event would -be bound, `read-key-sequence' turns the event into a click event at the -drag's starting position. This means that you don't have to distinguish -between click and drag, double, or triple events unless you want to. - -`read-key-sequence' prefixes mouse events on mode lines, the vertical -lines separating windows, and scroll bars with imaginary keys -`mode-line', `vertical-line', and `vertical-scroll-bar'. - -Optional fourth argument CAN-RETURN-SWITCH-FRAME non-nil means that this -function will process a switch-frame event if the user switches frames -before typing anything. If the user switches frames in the middle of a -key sequence, or at the start of the sequence but CAN-RETURN-SWITCH-FRAME -is nil, then the event will be put off until after the current key sequence. - -`read-key-sequence' checks `function-key-map' for function key -sequences, where they wouldn't conflict with ordinary bindings. See -`function-key-map' for more details. - -The optional fifth argument CMD-LOOP, if non-nil, means -that this key sequence is being read by something that will -read commands one after another. It should be nil if the caller -will read just one key sequence. */) - (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop) +static Lisp_Object +read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, + Lisp_Object dont_downcase_last, + Lisp_Object can_return_switch_frame, + Lisp_Object cmd_loop, bool allow_string) { Lisp_Object keybuf[30]; register int i; @@ -9817,7 +9764,7 @@ will read just one key sequence. */) i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), prompt, ! NILP (dont_downcase_last), - ! NILP (can_return_switch_frame), 0); + ! NILP (can_return_switch_frame), 0, 0); #if 0 /* The following is fine for code reading a key sequence and then proceeding with a lengthy computation, but it's not good @@ -9834,60 +9781,71 @@ will read just one key sequence. */) QUIT; } UNGCPRO; - return unbind_to (count, make_event_array (i, keybuf)); + return unbind_to (count, + ((allow_string ? make_event_array : Fvector) + (i, keybuf))); } -DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, - Sread_key_sequence_vector, 1, 5, 0, - doc: /* Like `read-key-sequence' but always return a vector. */) - (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop) -{ - Lisp_Object keybuf[30]; - register int i; - struct gcpro gcpro1; - ptrdiff_t count = SPECPDL_INDEX (); +DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, + doc: /* Read a sequence of keystrokes and return as a string or vector. +The sequence is sufficient to specify a non-prefix command in the +current local and global maps. - if (!NILP (prompt)) - CHECK_STRING (prompt); - QUIT; +First arg PROMPT is a prompt string. If nil, do not prompt specially. +Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos +as a continuation of the previous key. - specbind (Qinput_method_exit_on_first_char, - (NILP (cmd_loop) ? Qt : Qnil)); - specbind (Qinput_method_use_echo_area, - (NILP (cmd_loop) ? Qt : Qnil)); +The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not +convert the last event to lower case. (Normally any upper case event +is converted to lower case if the original event is undefined and the lower +case equivalent is defined.) A non-nil value is appropriate for reading +a key sequence to be defined. - memset (keybuf, 0, sizeof keybuf); - GCPRO1 (keybuf[0]); - gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0])); +A C-g typed while in this function is treated like any other character, +and `quit-flag' is not set. - if (NILP (continue_echo)) - { - this_command_key_count = 0; - this_command_key_count_reset = 0; - this_single_command_key_start = 0; - } +If the key sequence starts with a mouse click, then the sequence is read +using the keymaps of the buffer of the window clicked in, not the buffer +of the selected window as normal. -#ifdef HAVE_WINDOW_SYSTEM - if (display_hourglass_p) - cancel_hourglass (); -#endif +`read-key-sequence' drops unbound button-down events, since you normally +only care about the click or drag events which follow them. If a drag +or multi-click event is unbound, but the corresponding click event would +be bound, `read-key-sequence' turns the event into a click event at the +drag's starting position. This means that you don't have to distinguish +between click and drag, double, or triple events unless you want to. - i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), - prompt, ! NILP (dont_downcase_last), - ! NILP (can_return_switch_frame), 0); +`read-key-sequence' prefixes mouse events on mode lines, the vertical +lines separating windows, and scroll bars with imaginary keys +`mode-line', `vertical-line', and `vertical-scroll-bar'. -#ifdef HAVE_WINDOW_SYSTEM - if (display_hourglass_p) - start_hourglass (); -#endif +Optional fourth argument CAN-RETURN-SWITCH-FRAME non-nil means that this +function will process a switch-frame event if the user switches frames +before typing anything. If the user switches frames in the middle of a +key sequence, or at the start of the sequence but CAN-RETURN-SWITCH-FRAME +is nil, then the event will be put off until after the current key sequence. - if (i == -1) - { - Vquit_flag = Qt; - QUIT; - } - UNGCPRO; - return unbind_to (count, Fvector (i, keybuf)); +`read-key-sequence' checks `function-key-map' for function key +sequences, where they wouldn't conflict with ordinary bindings. See +`function-key-map' for more details. + +The optional fifth argument CMD-LOOP, if non-nil, means +that this key sequence is being read by something that will +read commands one after another. It should be nil if the caller +will read just one key sequence. */) + (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop) +{ + return read_key_sequence_vs (prompt, continue_echo, dont_downcase_last, + can_return_switch_frame, cmd_loop, true); +} + +DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, + Sread_key_sequence_vector, 1, 5, 0, + doc: /* Like `read-key-sequence' but always return a vector. */) + (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop) +{ + return read_key_sequence_vs (prompt, continue_echo, dont_downcase_last, + can_return_switch_frame, cmd_loop, false); } /* Return true if input events are pending. */ @@ -9918,20 +9876,7 @@ detect_input_pending_run_timers (bool do_display) get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW); if (old_timers_run != timers_run && do_display) - { - redisplay_preserve_echo_area (8); - /* The following fixes a bug when using lazy-lock with - lazy-lock-defer-on-the-fly set to t, i.e. when fontifying - from an idle timer function. The symptom of the bug is that - the cursor sometimes doesn't become visible until the next X - event is processed. --gerd. */ - { - Lisp_Object tail, frame; - FOR_EACH_FRAME (tail, frame) - if (FRAME_RIF (XFRAME (frame))) - FRAME_RIF (XFRAME (frame))->flush_display (XFRAME (frame)); - } - } + redisplay_preserve_echo_area (8); return input_pending; } @@ -9958,12 +9903,13 @@ requeued_events_pending_p (void) return (!NILP (Vunread_command_events)); } - -DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 0, +DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 1, 0, doc: /* Return t if command input is currently available with no wait. Actually, the value is nil only if we can be sure that no input is available; -if there is a doubt, the value is t. */) - (void) +if there is a doubt, the value is t. + +If CHECK-TIMERS is non-nil, timers that are ready to run will do so. */) + (Lisp_Object check_timers) { if (!NILP (Vunread_command_events) || !NILP (Vunread_post_input_method_events) @@ -9973,7 +9919,8 @@ if there is a doubt, the value is t. */) /* Process non-user-visible events (Bug#10195). */ process_special_events (); - return (get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW + return (get_input_pending ((NILP (check_timers) + ? 0 : READABLE_EVENTS_DO_TIMERS_NOW) | READABLE_EVENTS_FILTER_EVENTS) ? Qt : Qnil); } @@ -10049,8 +9996,7 @@ shows the events before all translations (except for input methods). The value is always a vector. */) (void) { - return Fvector (raw_keybuf_count, - (XVECTOR (raw_keybuf)->contents)); + return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents); } DEFUN ("reset-this-command-lengths", Freset_this_command_lengths, @@ -10130,9 +10076,9 @@ The file will be closed when Emacs exits. */) if (!NILP (file)) { file = Fexpand_file_name (file, Qnil); - dribble = fopen (SSDATA (file), "w"); + dribble = emacs_fopen (SSDATA (file), "w"); if (dribble == 0) - report_file_error ("Opening dribble", Fcons (file, Qnil)); + report_file_error ("Opening dribble", file); } return Qnil; } @@ -10149,8 +10095,6 @@ Also end any kbd macro being defined. */) end_kbd_macro (); } - update_mode_lines++; - Vunread_command_events = Qnil; discard_tty_input (); @@ -10197,8 +10141,7 @@ On such systems, Emacs starts a subshell instead of suspending. */) reset_all_sys_modes (); /* sys_suspend can get an error if it tries to fork a subshell and the system resources aren't available for that. */ - record_unwind_protect ((Lisp_Object (*) (Lisp_Object)) init_all_sys_modes, - Qnil); + record_unwind_protect_void (init_all_sys_modes); stuff_buffered_input (stuffstring); if (cannot_suspend) sys_subshell (); @@ -10211,7 +10154,7 @@ On such systems, Emacs starts a subshell instead of suspending. */) with a window system; but suspend should be disabled in that case. */ get_tty_size (fileno (CURTTY ()->input), &width, &height); if (width != old_width || height != old_height) - change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0); + change_frame_size (SELECTED_FRAME (), width, height, 0, 0, 0, 0); /* Run suspend-resume-hook. */ hook = intern ("suspend-resume-hook"); @@ -10263,7 +10206,7 @@ stuff_buffered_input (Lisp_Object stuffstring) } void -set_waiting_for_input (EMACS_TIME *time_to_clear) +set_waiting_for_input (struct timespec *time_to_clear) { input_available_clear_time = time_to_clear; @@ -10795,12 +10738,11 @@ The `posn-' functions access elements of such lists. */) return tem; } - -/* - * Set up a new kboard object with reasonable initial values. - */ -void -init_kboard (KBOARD *kb) +/* Set up a new kboard object with reasonable initial values. + TYPE is a window system for which this keyboard is used. */ + +static void +init_kboard (KBOARD *kb, Lisp_Object type) { kset_overriding_terminal_local_map (kb, Qnil); kset_last_command (kb, Qnil); @@ -10821,13 +10763,27 @@ init_kboard (KBOARD *kb) kb->reference_count = 0; kset_system_key_alist (kb, Qnil); kset_system_key_syms (kb, Qnil); - kset_window_system (kb, Qt); /* Unset. */ + kset_window_system (kb, type); kset_input_decode_map (kb, Fmake_sparse_keymap (Qnil)); kset_local_function_key_map (kb, Fmake_sparse_keymap (Qnil)); Fset_keymap_parent (KVAR (kb, Vlocal_function_key_map), Vfunction_key_map); kset_default_minibuffer_frame (kb, Qnil); } +/* Allocate and basically initialize keyboard + object to use with window system TYPE. */ + +KBOARD * +allocate_kboard (Lisp_Object type) +{ + KBOARD *kb = xmalloc (sizeof *kb); + + init_kboard (kb, type); + kb->next_kboard = all_kboards; + all_kboards = kb; + return kb; +} + /* * Destroy the contents of a kboard object, but not the object itself. * We use this just before deleting it, or if we're going to initialize @@ -10874,7 +10830,7 @@ init_keyboard (void) immediate_quit = 0; quit_char = Ctl ('g'); Vunread_command_events = Qnil; - timer_idleness_start_time = invalid_emacs_time (); + timer_idleness_start_time = invalid_timespec (); total_keys = 0; recent_keys_index = 0; kbd_fetch_ptr = kbd_buffer; @@ -10892,10 +10848,9 @@ init_keyboard (void) current_kboard = initial_kboard; /* Re-initialize the keyboard again. */ wipe_kboard (current_kboard); - init_kboard (current_kboard); /* A value of nil for Vwindow_system normally means a tty, but we also use it for the initial terminal since there is no window system there. */ - kset_window_system (current_kboard, Qnil); + init_kboard (current_kboard, Qnil); if (!noninteractive) { @@ -10957,6 +10912,8 @@ static const struct event_head head_table[] = { {&Qmouse_movement, "mouse-movement", &Qmouse_movement}, {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement}, {&Qswitch_frame, "switch-frame", &Qswitch_frame}, + {&Qfocus_in, "focus-in", &Qfocus_in}, + {&Qfocus_out, "focus-out", &Qfocus_out}, {&Qdelete_frame, "delete-frame", &Qdelete_frame}, {&Qiconify_frame, "iconify-frame", &Qiconify_frame}, {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible}, @@ -11033,6 +10990,8 @@ syms_of_keyboard (void) DEFSYM (Qvertical_line, "vertical-line"); DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar"); DEFSYM (Qmenu_bar, "menu-bar"); + DEFSYM (Qright_divider, "right-divider"); + DEFSYM (Qbottom_divider, "bottom-divider"); DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message"); @@ -11067,6 +11026,8 @@ syms_of_keyboard (void) DEFSYM (Qhelp_form_show, "help-form-show"); + DEFSYM (Qecho_keystrokes, "echo-keystrokes"); + Fset (Qinput_method_exit_on_first_char, Qnil); Fset (Qinput_method_use_echo_area, Qnil); @@ -11080,7 +11041,7 @@ syms_of_keyboard (void) *p->var = intern_c_string (p->name); staticpro (p->var); Fput (*p->var, Qevent_kind, *p->kind); - Fput (*p->var, Qevent_symbol_elements, Fcons (*p->var, Qnil)); + Fput (*p->var, Qevent_symbol_elements, list1 (*p->var)); } } @@ -11163,6 +11124,7 @@ syms_of_keyboard (void) 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); @@ -11453,18 +11415,19 @@ tool-bar separators natively. Otherwise it is unused (e.g. on GTK). */); DEFVAR_KBOARD ("overriding-terminal-local-map", Voverriding_terminal_local_map, doc: /* Per-terminal keymap that takes precedence over all other keymaps. - This variable is intended to let commands such as `universal-argument' set up a different keymap for reading the next command. `overriding-terminal-local-map' has a separate binding for each -terminal device. -See Info node `(elisp)Multiple Terminals'. */); +terminal device. See Info node `(elisp)Multiple Terminals'. */); DEFVAR_LISP ("overriding-local-map", Voverriding_local_map, - doc: /* Keymap that overrides almost all other local keymaps. -If this variable is non-nil, it is used as a keymap--replacing the -buffer's local map, the minor mode keymaps, and char property keymaps. */); + doc: /* Keymap that replaces (overrides) local keymaps. +If this variable is non-nil, Emacs looks up key bindings in this +keymap INSTEAD OF the keymap char property, minor mode maps, and the +buffer's local map. Hence, the only active keymaps would be +`overriding-terminal-local-map', this keymap, and `global-keymap', in +order of precedence. */); Voverriding_local_map = Qnil; DEFVAR_LISP ("overriding-local-map-menu-flag", Voverriding_local_map_menu_flag, @@ -11475,7 +11438,7 @@ and the minor mode maps regardless of `overriding-local-map'. */); DEFVAR_LISP ("special-event-map", Vspecial_event_map, doc: /* Keymap defining bindings for special events to execute at low level. */); - Vspecial_event_map = Fcons (intern_c_string ("keymap"), Qnil); + Vspecial_event_map = list1 (intern_c_string ("keymap")); DEFVAR_LISP ("track-mouse", do_mouse_tracking, doc: /* Non-nil means generate motion events for mouse motion. */); @@ -11642,13 +11605,13 @@ peculiar kind of quitting. */); Vthrow_on_input = Qnil; DEFVAR_LISP ("command-error-function", Vcommand_error_function, - doc: /* If non-nil, function to output error messages. -The arguments are the error data, a list of the form - (SIGNALED-CONDITIONS . SIGNAL-DATA) -such as just as `condition-case' would bind its variable to, -the context (a string which normally goes at the start of the message), -and the Lisp function within which the error was signaled. */); - Vcommand_error_function = Qnil; + doc: /* Function to output error messages. +Called with three arguments: +- the error data, a list of the form (SIGNALED-CONDITION . SIGNAL-DATA) + such as what `condition-case' would bind its variable to, +- the context (a string which normally goes at the start of the message), +- the Lisp function within which the error was signaled. */); + Vcommand_error_function = intern ("command-error-default-function"); DEFVAR_LISP ("enable-disabled-menus-and-buttons", Venable_disabled_menus_and_buttons, @@ -11696,12 +11659,8 @@ Currently, the only supported values for this variable are `sigusr1' and `sigusr2'. */); Vdebug_on_event = intern_c_string ("sigusr2"); - /* Create the initial keyboard. */ - initial_kboard = xmalloc (sizeof *initial_kboard); - init_kboard (initial_kboard); - /* Vwindow_system is left at t for now. */ - initial_kboard->next_kboard = all_kboards; - all_kboards = initial_kboard; + /* Create the initial keyboard. Qt means 'unset'. */ + initial_kboard = allocate_kboard (Qt); } void @@ -11771,6 +11730,10 @@ keys_of_keyboard (void) initial_define_lispy_key (Vspecial_event_map, "language-change", "ignore"); #endif + initial_define_lispy_key (Vspecial_event_map, "focus-in", + "handle-focus-in"); + initial_define_lispy_key (Vspecial_event_map, "focus-out", + "handle-focus-out"); } /* Mark the pointers in the kboard objects.