summaryrefslogtreecommitdiff
path: root/src/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c314
1 files changed, 171 insertions, 143 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 63e7573fbe9..d307250b868 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -201,8 +201,8 @@ Lisp_Object unread_switch_frame;
/* Last size recorded for a current buffer which is not a minibuffer. */
static EMACS_INT last_non_minibuf_size;
-/* Total number of times read_char has returned. */
-int num_input_events;
+/* Total number of times read_char has returned, modulo SIZE_MAX + 1. */
+size_t num_input_events;
/* Value of num_nonmacro_input_events as of last auto save. */
@@ -254,7 +254,6 @@ Lisp_Object Qecho_area_clear_hook;
/* Hooks to run before and after each command. */
Lisp_Object Qpre_command_hook;
Lisp_Object Qpost_command_hook;
-Lisp_Object Qcommand_hook_internal;
Lisp_Object Qdeferred_action_function;
@@ -351,7 +350,7 @@ Lisp_Object Qmenu_bar;
Lisp_Object recursive_edit_unwind (Lisp_Object buffer), command_loop (void);
Lisp_Object Fthis_command_keys (void);
Lisp_Object Qextended_command_history;
-EMACS_TIME timer_check (int do_it_now);
+EMACS_TIME timer_check (void);
static void record_menu_key (Lisp_Object c);
static int echo_length (void);
@@ -434,15 +433,15 @@ static void restore_getcjmp (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 SIGTYPE interrupt_signal (int signalnum);
+static void interrupt_signal (int signalnum);
#ifdef SIGIO
-static SIGTYPE input_available_signal (int signo);
+static void input_available_signal (int signo);
#endif
static void handle_interrupt (void);
static void timer_start_idle (void);
static void timer_stop_idle (void);
static void timer_resume_idle (void);
-static SIGTYPE handle_user_signal (int);
+static void handle_user_signal (int);
static char *find_user_signal_name (int);
static int store_user_signal_events (void);
@@ -1270,7 +1269,7 @@ some_mouse_moved (void)
/* This is the actual command reading loop,
sans error-handling encapsulation. */
-static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
+static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object,
int, int, int);
void safe_run_hooks (Lisp_Object);
static void adjust_point_for_property (EMACS_INT, int);
@@ -1492,10 +1491,7 @@ command_loop_1 (void)
Vthis_command = cmd;
real_this_command = cmd;
- /* Note that the value cell will never directly contain nil
- if the symbol is a local variable. */
- if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks))
- safe_run_hooks (Qpre_command_hook);
+ safe_run_hooks (Qpre_command_hook);
already_adjusted = 0;
@@ -1541,18 +1537,14 @@ command_loop_1 (void)
}
KVAR (current_kboard, Vlast_prefix_arg) = Vcurrent_prefix_arg;
- /* Note that the value cell will never directly contain nil
- if the symbol is a local variable. */
- if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
- safe_run_hooks (Qpost_command_hook);
+ safe_run_hooks (Qpost_command_hook);
/* If displaying a message, resize the echo area window to fit
that message's size exactly. */
if (!NILP (echo_area_buffer[0]))
resize_echo_area_exactly ();
- if (!NILP (Vdeferred_action_list))
- safe_run_hooks (Qdeferred_action_function);
+ safe_run_hooks (Qdeferred_action_function);
/* If there is a prefix argument,
1) We don't want Vlast_command to be ``universal-argument''
@@ -1621,7 +1613,10 @@ command_loop_1 (void)
}
if (current_buffer != prev_buffer || MODIFF != prev_modiff)
- call1 (Vrun_hooks, intern ("activate-mark-hook"));
+ {
+ Lisp_Object hook = intern ("activate-mark-hook");
+ Frun_hooks (1, &hook);
+ }
}
Vsaved_region_selection = Qnil;
@@ -1819,22 +1814,63 @@ adjust_point_for_property (EMACS_INT last_pt, int modified)
static Lisp_Object
safe_run_hooks_1 (void)
{
- if (NILP (Vrun_hooks))
- return Qnil;
- return call1 (Vrun_hooks, Vinhibit_quit);
+ eassert (CONSP (Vinhibit_quit));
+ return call0 (XCDR (Vinhibit_quit));
}
-/* Subroutine for safe_run_hooks: handle an error by clearing out the hook. */
+/* Subroutine for safe_run_hooks: handle an error by clearing out the function
+ from the hook. */
+
+static Lisp_Object
+safe_run_hooks_error (Lisp_Object error_data)
+{
+ Lisp_Object hook
+ = CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit;
+ Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil;
+ Lisp_Object args[4];
+ args[0] = build_string ("Error in %s (%s): %s");
+ args[1] = hook;
+ args[2] = fun;
+ args[3] = error_data;
+ Fmessage (4, args);
+ if (SYMBOLP (hook))
+ {
+ Lisp_Object val;
+ int found = 0;
+ Lisp_Object newval = Qnil;
+ for (val = find_symbol_value (hook); CONSP (val); val = XCDR (val))
+ if (EQ (fun, XCAR (val)))
+ found = 1;
+ else
+ newval = Fcons (XCAR (val), newval);
+ if (found)
+ return Fset (hook, Fnreverse (newval));
+ /* Not found in the local part of the hook. Let's look at the global
+ part. */
+ newval = Qnil;
+ for (val = (NILP (Fdefault_boundp (hook)) ? Qnil
+ : Fdefault_value (hook));
+ CONSP (val); val = XCDR (val))
+ if (EQ (fun, XCAR (val)))
+ found = 1;
+ else
+ newval = Fcons (XCAR (val), newval);
+ if (found)
+ return Fset_default (hook, Fnreverse (newval));
+ }
+ return Qnil;
+}
static Lisp_Object
-safe_run_hooks_error (Lisp_Object data)
+safe_run_hook_funcall (size_t nargs, Lisp_Object *args)
{
- Lisp_Object args[3];
- args[0] = build_string ("Error in %s: %s");
- args[1] = Vinhibit_quit;
- args[2] = data;
- Fmessage (3, args);
- return Fset (Vinhibit_quit, Qnil);
+ eassert (nargs == 1);
+ if (CONSP (Vinhibit_quit))
+ XSETCDR (Vinhibit_quit, args[0]);
+ else
+ Vinhibit_quit = Fcons (Vinhibit_quit, args[0]);
+
+ return internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);
}
/* If we get an error while running the hook, cause the hook variable
@@ -1844,10 +1880,13 @@ safe_run_hooks_error (Lisp_Object data)
void
safe_run_hooks (Lisp_Object hook)
{
+ /* FIXME: our `internal_condition_case' does not provide any way to pass data
+ to its body or to its handlers other than via globals such as
+ dynamically-bound variables ;-) */
int count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, hook);
- internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);
+ run_hook_with_args (1, &hook, safe_run_hook_funcall);
unbind_to (count, Qnil);
}
@@ -2074,16 +2113,12 @@ make_ctrl_char (int c)
the `display' property). POS is the position in that string under
the mouse.
- OK_TO_OVERWRITE_KEYSTROKE_ECHO non-zero means it's okay if the help
- echo overwrites a keystroke echo currently displayed in the echo
- area.
-
Note: this function may only be called with HELP nil or a string
from X code running asynchronously. */
void
show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
- Lisp_Object pos, int ok_to_overwrite_keystroke_echo)
+ Lisp_Object pos)
{
if (!NILP (help) && !STRINGP (help))
{
@@ -3013,7 +3048,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
htem = Fcdr (htem);
position = Fcar (htem);
- show_help_echo (help, window, object, position, 0);
+ show_help_echo (help, window, object, position);
/* We stopped being idle for this event; undo that. */
if (!end_time)
@@ -3315,7 +3350,7 @@ static int
readable_events (int flags)
{
if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
- timer_check (1);
+ timer_check ();
/* If the buffer contains only FOCUS_IN_EVENT events, and
READABLE_EVENTS_FILTER_EVENTS is set, report it as empty. */
@@ -4389,14 +4424,10 @@ timer_check_2 (void)
Returns the time to wait until the next timer fires.
If no timer is active, return -1.
- As long as any timer is ripe, we run it.
-
- DO_IT_NOW is now ignored. It used to mean that we should
- run the timer directly instead of queueing a timer-event.
- Now we always run timers directly. */
+ As long as any timer is ripe, we run it. */
EMACS_TIME
-timer_check (int do_it_now)
+timer_check (void)
{
EMACS_TIME nexttime;
@@ -5405,7 +5436,6 @@ make_lispy_event (struct input_event *event)
&& (event->modifiers & down_modifier))
{
Lisp_Object items, item;
- int hpos;
int i;
/* Find the menu bar item under `column'. */
@@ -5974,10 +6004,10 @@ make_lispy_switch_frame (Lisp_Object frame)
This doesn't use any caches. */
static int
-parse_modifiers_uncached (Lisp_Object symbol, int *modifier_end)
+parse_modifiers_uncached (Lisp_Object symbol, EMACS_INT *modifier_end)
{
Lisp_Object name;
- int i;
+ EMACS_INT i;
int modifiers;
CHECK_SYMBOL (symbol);
@@ -5987,7 +6017,7 @@ parse_modifiers_uncached (Lisp_Object symbol, int *modifier_end)
for (i = 0; i+2 <= SBYTES (name); )
{
- int this_mod_end = 0;
+ EMACS_INT this_mod_end = 0;
int this_mod = 0;
/* See if the name continues with a modifier word.
@@ -6184,7 +6214,7 @@ parse_modifiers (Lisp_Object symbol)
return elements;
else
{
- int end;
+ EMACS_INT end;
int modifiers = parse_modifiers_uncached (symbol, &end);
Lisp_Object unmodified;
Lisp_Object mask;
@@ -7097,7 +7127,7 @@ process_pending_signals (void)
#ifdef SIGIO /* for entire page */
/* Note SIGIO has been undef'd if FIONREAD is missing. */
-static SIGTYPE
+static void
input_available_signal (int signo)
{
/* Must preserve main program's value of errno. */
@@ -7175,7 +7205,7 @@ add_user_signal (int sig, const char *name)
signal (sig, handle_user_signal);
}
-static SIGTYPE
+static void
handle_user_signal (int sig)
{
int old_errno = errno;
@@ -8769,7 +8799,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
The return value is non-zero if the remapping actually took place. */
static int
-keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
+keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
int input, int doit, int *diff, Lisp_Object prompt)
{
Lisp_Object next, key;
@@ -8862,7 +8892,7 @@ keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
from the selected window's buffer. */
static int
-read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
+read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
int dont_downcase_last, int can_return_switch_frame,
int fix_current_buffer)
{
@@ -9380,80 +9410,84 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
last_real_key_start = t - 1;
}
- /* Key sequences beginning with mouse clicks are
- read using the keymaps in the buffer clicked on,
- not the current buffer. If we're at the
- beginning of a key sequence, switch buffers. */
- if (last_real_key_start == 0
- && WINDOWP (window)
- && BUFFERP (XWINDOW (window)->buffer)
- && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+ if (last_real_key_start == 0)
{
- XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
- keybuf[t] = key;
- mock_input = t + 1;
-
- /* Arrange to go back to the original buffer once we're
- done reading the key sequence. Note that we can't
- use save_excursion_{save,restore} here, because they
- save point as well as the current buffer; we don't
- want to save point, because redisplay may change it,
- to accommodate a Fset_window_start or something. We
- don't want to do this at the top of the function,
- because we may get input from a subprocess which
- wants to change the selected window and stuff (say,
- emacsclient). */
- record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
-
- if (! FRAME_LIVE_P (XFRAME (selected_frame)))
- Fkill_emacs (Qnil);
- set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
- orig_local_map = get_local_map (PT, current_buffer,
- Qlocal_map);
- orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
- goto replay_sequence;
- }
+ /* Key sequences beginning with mouse clicks are
+ read using the keymaps in the buffer clicked on,
+ not the current buffer. If we're at the
+ beginning of a key sequence, switch buffers. */
+ if (WINDOWP (window)
+ && BUFFERP (XWINDOW (window)->buffer)
+ && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+ {
+ XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+ keybuf[t] = key;
+ mock_input = t + 1;
+
+ /* Arrange to go back to the original buffer once we're
+ done reading the key sequence. Note that we can't
+ use save_excursion_{save,restore} here, because they
+ save point as well as the current buffer; we don't
+ want to save point, because redisplay may change it,
+ to accommodate a Fset_window_start or something. We
+ don't want to do this at the top of the function,
+ because we may get input from a subprocess which
+ wants to change the selected window and stuff (say,
+ emacsclient). */
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+
+ if (! FRAME_LIVE_P (XFRAME (selected_frame)))
+ Fkill_emacs (Qnil);
+ set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+ orig_local_map = get_local_map (PT, current_buffer,
+ Qlocal_map);
+ orig_keymap = get_local_map (PT, current_buffer,
+ Qkeymap);
+ goto replay_sequence;
+ }
- /* For a mouse click, get the local text-property keymap
- of the place clicked on, rather than point. */
- if (last_real_key_start == 0
- && CONSP (XCDR (key))
- && ! localized_local_map)
- {
- Lisp_Object map_here, start, pos;
+ /* For a mouse click, get the local text-property keymap
+ of the place clicked on, rather than point. */
+ if (CONSP (XCDR (key))
+ && ! localized_local_map)
+ {
+ Lisp_Object map_here, start, pos;
- localized_local_map = 1;
- start = EVENT_START (key);
+ localized_local_map = 1;
+ start = EVENT_START (key);
- if (CONSP (start) && POSN_INBUFFER_P (start))
- {
- pos = POSN_BUFFER_POSN (start);
- if (INTEGERP (pos)
- && XINT (pos) >= BEGV
- && XINT (pos) <= ZV)
+ if (CONSP (start) && POSN_INBUFFER_P (start))
{
- map_here = get_local_map (XINT (pos),
- current_buffer, Qlocal_map);
- if (!EQ (map_here, orig_local_map))
+ pos = POSN_BUFFER_POSN (start);
+ if (INTEGERP (pos)
+ && XINT (pos) >= BEGV
+ && XINT (pos) <= ZV)
{
- orig_local_map = map_here;
- ++localized_local_map;
- }
+ map_here = get_local_map (XINT (pos),
+ current_buffer,
+ Qlocal_map);
+ if (!EQ (map_here, orig_local_map))
+ {
+ orig_local_map = map_here;
+ ++localized_local_map;
+ }
- map_here = get_local_map (XINT (pos),
- current_buffer, Qkeymap);
- if (!EQ (map_here, orig_keymap))
- {
- orig_keymap = map_here;
- ++localized_local_map;
- }
+ map_here = get_local_map (XINT (pos),
+ current_buffer,
+ Qkeymap);
+ if (!EQ (map_here, orig_keymap))
+ {
+ orig_keymap = map_here;
+ ++localized_local_map;
+ }
- if (localized_local_map > 1)
- {
- keybuf[t] = key;
- mock_input = t + 1;
+ if (localized_local_map > 1)
+ {
+ keybuf[t] = key;
+ mock_input = t + 1;
- goto replay_sequence;
+ goto replay_sequence;
+ }
}
}
}
@@ -10135,11 +10169,11 @@ a special event, so ignore the prefix argument and don't clear it. */)
if (SYMBOLP (cmd))
{
tem = Fget (cmd, Qdisabled);
- if (!NILP (tem) && !NILP (Vrun_hooks))
+ if (!NILP (tem))
{
tem = Fsymbol_value (Qdisabled_command_function);
if (!NILP (tem))
- return call1 (Vrun_hooks, Qdisabled_command_function);
+ return Frun_hooks (1, &Qdisabled_command_function);
}
}
@@ -10312,9 +10346,9 @@ give to the command you invoke, if it asks for an argument. */)
sprintf (newmessage, "You can run the command `%s' with %s",
SDATA (SYMBOL_NAME (function)),
SDATA (binding));
- message2_nolog (newmessage,
- strlen (newmessage),
- STRING_MULTIBYTE (binding));
+ message2 (newmessage,
+ strlen (newmessage),
+ STRING_MULTIBYTE (binding));
if (NUMBERP (Vsuggest_key_bindings))
waited = sit_for (Vsuggest_key_bindings, 0, 2);
else
@@ -10623,6 +10657,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
int old_height, old_width;
int width, height;
struct gcpro gcpro1;
+ Lisp_Object hook;
if (tty_list && tty_list->next)
error ("There are other tty frames open; close them before suspending Emacs");
@@ -10631,8 +10666,8 @@ On such systems, Emacs starts a subshell instead of suspending. */)
CHECK_STRING (stuffstring);
/* Run the functions in suspend-hook. */
- if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, intern ("suspend-hook"));
+ hook = intern ("suspend-hook");
+ Frun_hooks (1, &hook);
GCPRO1 (stuffstring);
get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
@@ -10656,8 +10691,8 @@ On such systems, Emacs starts a subshell instead of suspending. */)
change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
/* Run suspend-resume-hook. */
- if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, intern ("suspend-resume-hook"));
+ hook = intern ("suspend-resume-hook");
+ Frun_hooks (1, &hook);
UNGCPRO;
return Qnil;
@@ -10732,7 +10767,7 @@ clear_waiting_for_input (void)
SIGINT was generated by C-g, so we call handle_interrupt.
Otherwise, the handler kills Emacs. */
-static SIGTYPE
+static void
interrupt_signal (int signalnum) /* If we don't have an argument, some */
/* compilers complain in signal calls. */
{
@@ -11458,9 +11493,6 @@ syms_of_keyboard (void)
Qdeferred_action_function = intern_c_string ("deferred-action-function");
staticpro (&Qdeferred_action_function);
- Qcommand_hook_internal = intern_c_string ("command-hook-internal");
- staticpro (&Qcommand_hook_internal);
-
Qfunction_key = intern_c_string ("function-key");
staticpro (&Qfunction_key);
Qmouse_click = intern_c_string ("mouse-click");
@@ -11580,12 +11612,12 @@ syms_of_keyboard (void)
last_point_position_window = Qnil;
{
- const struct event_head *p;
+ int i;
+ int len = sizeof (head_table) / sizeof (head_table[0]);
- for (p = head_table;
- p < head_table + (sizeof (head_table) / sizeof (head_table[0]));
- p++)
+ for (i = 0; i < len; i++)
{
+ const struct event_head *p = &head_table[i];
*p->var = intern_c_string (p->name);
staticpro (p->var);
Fput (*p->var, Qevent_kind, *p->kind);
@@ -11928,22 +11960,18 @@ Buffer modification stores t in this variable. */);
Qdeactivate_mark = intern_c_string ("deactivate-mark");
staticpro (&Qdeactivate_mark);
- DEFVAR_LISP ("command-hook-internal", Vcommand_hook_internal,
- doc: /* Temporary storage of `pre-command-hook' or `post-command-hook'. */);
- Vcommand_hook_internal = Qnil;
-
DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
doc: /* Normal hook run before each command is executed.
If an unhandled error happens in running this hook,
-the hook value is set to nil, since otherwise the error
-might happen repeatedly and make Emacs nonfunctional. */);
+the function in which the error occurred is unconditionally removed, since
+otherwise the error might happen repeatedly and make Emacs nonfunctional. */);
Vpre_command_hook = Qnil;
DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
doc: /* Normal hook run after each command is executed.
If an unhandled error happens in running this hook,
-the hook value is set to nil, since otherwise the error
-might happen repeatedly and make Emacs nonfunctional. */);
+the function in which the error occurred is unconditionally removed, since
+otherwise the error might happen repeatedly and make Emacs nonfunctional. */);
Vpost_command_hook = Qnil;
#if 0