X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8121e4813da7e5898eb216a5de3c17f4875cac61..0fa30f3361e5876a7d0734e891f7386675775c8e:/src/keyboard.c
diff --git a/src/keyboard.c b/src/keyboard.c
index 3afdce42ca..915ce9dcf2 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -20,9 +20,6 @@ along with GNU Emacs. If not, see . */
#include
-#define BLOCKINPUT_INLINE EXTERN_INLINE
-#define KEYBOARD_INLINE EXTERN_INLINE
-
#include "sysstdio.h"
#include "lisp.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;
@@ -354,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 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);
@@ -370,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. */
@@ -389,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. */
@@ -422,7 +418,9 @@ static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object,
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);
@@ -824,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))
@@ -851,7 +849,7 @@ recursive_edit_unwind (Lisp_Object buffer)
Fset_buffer (buffer);
command_loop_level--;
- update_mode_lines = 1;
+ update_mode_lines = 18;
}
@@ -1067,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))
@@ -1082,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
@@ -1099,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));
}
@@ -1110,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);
@@ -1306,13 +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);
/* 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, ... */
@@ -1432,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)))
@@ -1513,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. */
@@ -1640,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)
@@ -1678,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);
@@ -1692,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.
@@ -1761,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
@@ -1779,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
@@ -1833,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));
@@ -1943,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)
{
@@ -1986,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);
@@ -2076,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)
{
@@ -2182,7 +2193,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
/* Input of single characters from keyboard */
static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, 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;
@@ -2204,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)
{
@@ -2217,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. */
@@ -2278,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)
@@ -2359,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.
@@ -2376,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.
@@ -2385,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;
@@ -2594,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 ();
@@ -2725,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))
@@ -2777,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)
@@ -2877,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)))
{
@@ -3240,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++;
}
@@ -3604,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;
}
@@ -3798,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;
@@ -3856,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 ();
@@ -3895,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? */
@@ -4258,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
@@ -4295,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. */
@@ -4310,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. */
@@ -4318,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;
@@ -4334,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;
@@ -4361,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);
@@ -4385,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
@@ -4414,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
@@ -4431,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);
@@ -4490,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
@@ -4518,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;
@@ -4535,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;
@@ -4548,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;
@@ -4564,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;
}
@@ -5280,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
@@ -5361,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.
@@ -5496,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
@@ -5509,67 +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 = list4 (event->frame_or_window,
- Qmenu_bar,
- Fcons (event->x, event->y),
- make_number (event->timestamp));
+ /* 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 list2 (item, position);
+ 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);
@@ -5974,55 +6029,6 @@ make_lispy_event (struct input_event *event)
case CONFIG_CHANGED_EVENT:
return list3 (Qconfig_changed_event,
event->arg, event->frame_or_window);
-#ifdef HAVE_GPM
- case GPM_CLICK_EVENT:
- {
- struct frame *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 list3 (head, start_pos, position);
- else if (event->modifiers & double_modifier)
- return list3 (head, position, make_number (2));
- else if (event->modifiers & triple_modifier)
- return list3 (head, position, make_number (3));
- else
- return list2 (head, position);
- }
-#endif /* HAVE_GPM */
/* The 'kind' field of the event is something we don't recognize. */
default:
@@ -6068,12 +6074,17 @@ 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.
@@ -7083,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)
@@ -7091,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)
@@ -7126,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
@@ -7213,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;
}
@@ -8355,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)
@@ -8401,7 +8412,6 @@ read_char_x_menu_prompt (Lisp_Object map,
*used_mouse_menu = 1;
return value;
}
-#endif /* HAVE_MENUS */
return Qnil ;
}
@@ -8784,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.
@@ -8816,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 ();
@@ -8897,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);
@@ -9053,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 */
@@ -9711,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;
@@ -9792,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
@@ -9809,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. */
@@ -9893,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;
}
@@ -9933,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)
@@ -9948,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);
}
@@ -10024,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,
@@ -10124,8 +10095,6 @@ Also end any kbd macro being defined. */)
end_kbd_macro ();
}
- update_mode_lines++;
-
Vunread_command_events = Qnil;
discard_tty_input ();
@@ -10185,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");
@@ -10237,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;
@@ -10769,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);
@@ -10795,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
@@ -10848,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;
@@ -10866,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)
{
@@ -11009,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");
@@ -11043,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);
@@ -11139,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);
@@ -11618,13 +11604,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,
@@ -11672,12 +11658,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