/* Keyboard and mouse input; editor command loop.
-Copyright (C) 1985-1989, 1993-1997, 1999-2012 Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993-1997, 1999-2013 Free Software Foundation,
+Inc.
This file is part of GNU Emacs.
KBOARD *current_kboard;
KBOARD *all_kboards;
-/* Nonzero in the single-kboard state, 0 in the any-kboard state. */
-static int single_kboard;
+/* True in the single-kboard state, false in the any-kboard state. */
+static bool single_kboard;
/* Non-nil disable property on a command means
do not execute it; call disabled-command-function's value instead. */
Lisp_Object this_command_keys;
ptrdiff_t this_command_key_count;
-/* 1 after calling Freset_this_command_lengths.
- Usually it is 0. */
-static int this_command_key_count_reset;
+/* True after calling Freset_this_command_lengths.
+ Usually it is false. */
+static bool this_command_key_count_reset;
/* This vector is used as a buffer to record the events that were actually read
by read_key_sequence. */
static sys_jmp_buf getcjmp;
/* True while doing kbd input. */
-int waiting_for_input;
+bool waiting_for_input;
/* True while displaying for echoing. Delays C-g throwing. */
-static int echoing;
+static bool echoing;
/* Non-null means we can start echoing at the next input pause even
though there is something in the echo area. */
Lisp_Object echo_message_buffer;
-/* Nonzero means C-g should cause immediate error-signal. */
-int immediate_quit;
+/* True means C-g should cause immediate error-signal. */
+bool immediate_quit;
/* Character that causes a quit. Normally C-g.
static FILE *dribble;
/* Nonzero if input is available. */
-int input_pending;
+bool input_pending;
/* Circular buffer for pre-read keyboard input. */
static Lisp_Object Qselect_window;
Lisp_Object Qhelp_echo;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object Qmouse_fixup_help_message;
-#endif
/* Symbols to denote kinds of events. */
static Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
-#if defined (WINDOWSNT)
-Lisp_Object Qlanguage_change, Qfile_notify;
+#ifdef HAVE_NTGUI
+Lisp_Object Qlanguage_change;
+#ifdef WINDOWSNT
+Lisp_Object Qfile_w32notify;
+#endif
#endif
static Lisp_Object Qdrag_n_drop;
static Lisp_Object Qsave_session;
#ifdef HAVE_DBUS
static Lisp_Object Qdbus_event;
#endif
+#ifdef HAVE_INOTIFY
+static Lisp_Object Qfile_inotify;
+#endif /* HAVE_INOTIFY */
static Lisp_Object Qconfig_changed_event;
/* Lisp_Object Qmouse_movement; - also an event header */
static Lisp_Object recursive_edit_unwind (Lisp_Object buffer);
static Lisp_Object command_loop (void);
-static Lisp_Object Qextended_command_history;
+static Lisp_Object Qcommand_execute;
EMACS_TIME timer_check (void);
-static void record_menu_key (Lisp_Object c);
static void echo_now (void);
static ptrdiff_t echo_length (void);
static Lisp_Object Qpolling_period;
/* Incremented whenever a timer is run. */
-int timers_run;
+unsigned timers_run;
/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
happens. */
EMACS_TIME *input_available_clear_time;
-/* Nonzero means use SIGIO interrupts; zero means use CBREAK mode.
- Default is 1 if INTERRUPT_INPUT is defined. */
-int interrupt_input;
+/* True means use SIGIO interrupts; false means use CBREAK mode.
+ Default is true if INTERRUPT_INPUT is defined. */
+bool interrupt_input;
/* Nonzero while interrupts are temporarily deferred during redisplay. */
-int interrupts_deferred;
+bool interrupts_deferred;
/* If we support a window system, turn on the code to poll periodically
to detect C-g. It isn't actually used when doing interrupt input. */
/* Function for init_keyboard to call with no args (if nonzero). */
static void (*keyboard_init_hook) (void);
-static void get_input_pending (int *, int);
-static int readable_events (int);
-static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
- Lisp_Object, int *);
-static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
- Lisp_Object *);
+static bool get_input_pending (int);
+static bool readable_events (int);
+static Lisp_Object read_char_x_menu_prompt (Lisp_Object,
+ Lisp_Object, bool *);
+static Lisp_Object read_char_minibuf_menu_prompt (int, Lisp_Object);
static Lisp_Object make_lispy_event (struct input_event *);
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
enum scroll_bar_part,
Lisp_Object, Lisp_Object,
Time);
-#endif
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 int help_char_p (Lisp_Object);
+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 deliver_input_available_signal (int signo);
#endif
static void handle_interrupt (bool);
-static _Noreturn void quit_throw_to_read_char (int);
+static _Noreturn void quit_throw_to_read_char (bool);
static void process_special_events (void);
static void timer_start_idle (void);
static void timer_stop_idle (void);
}
\f
-/* Add C to the echo string, if echoing is going on.
- C can be a character, which is printed prettily ("M-C-x" and all that
- jazz), or a symbol, whose name is printed. */
+/* Add C to the echo string, without echoing it immediately. C can be
+ a character, which is pretty-printed, or a symbol, whose name is
+ printed. */
static void
-echo_char (Lisp_Object c)
+echo_add_key (Lisp_Object c)
{
- if (current_kboard->immediate_echo)
- {
- int size = KEY_DESCRIPTION_SIZE + 100;
- char *buffer = alloca (size);
- char *ptr = buffer;
- Lisp_Object echo_string;
+ int size = KEY_DESCRIPTION_SIZE + 100;
+ char *buffer = alloca (size);
+ char *ptr = buffer;
+ Lisp_Object echo_string;
- echo_string = KVAR (current_kboard, echo_string);
+ echo_string = KVAR (current_kboard, echo_string);
- /* If someone has passed us a composite event, use its head symbol. */
- c = EVENT_HEAD (c);
+ /* If someone has passed us a composite event, use its head symbol. */
+ c = EVENT_HEAD (c);
- if (INTEGERP (c))
+ if (INTEGERP (c))
+ ptr = push_key_description (XINT (c), ptr);
+ else if (SYMBOLP (c))
+ {
+ Lisp_Object name = SYMBOL_NAME (c);
+ int nbytes = SBYTES (name);
+
+ if (size - (ptr - buffer) < nbytes)
{
- ptr = push_key_description (XINT (c), ptr, 1);
+ int offset = ptr - buffer;
+ size = max (2 * size, size + nbytes);
+ buffer = alloca (size);
+ ptr = buffer + offset;
}
- else if (SYMBOLP (c))
- {
- Lisp_Object name = SYMBOL_NAME (c);
- int nbytes = SBYTES (name);
- if (size - (ptr - buffer) < nbytes)
- {
- int offset = ptr - buffer;
- size = max (2 * size, size + nbytes);
- buffer = alloca (size);
- ptr = buffer + offset;
- }
+ ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes,
+ STRING_MULTIBYTE (name), 1);
+ }
- ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes,
- STRING_MULTIBYTE (name), 1);
- }
+ if ((NILP (echo_string) || SCHARS (echo_string) == 0)
+ && help_char_p (c))
+ {
+ const char *text = " (Type ? for further options)";
+ int len = strlen (text);
- if ((NILP (echo_string) || SCHARS (echo_string) == 0)
- && help_char_p (c))
+ if (size - (ptr - buffer) < len)
{
- const char *text = " (Type ? for further options)";
- int len = strlen (text);
-
- if (size - (ptr - buffer) < len)
- {
- int offset = ptr - buffer;
- size += len;
- buffer = alloca (size);
- ptr = buffer + offset;
- }
-
- memcpy (ptr, text, len);
- ptr += len;
+ int offset = ptr - buffer;
+ size += len;
+ buffer = alloca (size);
+ ptr = buffer + offset;
}
- /* Replace a dash from echo_dash with a space, otherwise
- add a space at the end as a separator between keys. */
- if (STRINGP (echo_string)
- && SCHARS (echo_string) > 1)
- {
- Lisp_Object last_char, prev_char, idx;
+ memcpy (ptr, text, len);
+ ptr += len;
+ }
- idx = make_number (SCHARS (echo_string) - 2);
- prev_char = Faref (echo_string, idx);
+ /* Replace a dash from echo_dash with a space, otherwise add a space
+ at the end as a separator between keys. */
+ if (STRINGP (echo_string) && SCHARS (echo_string) > 1)
+ {
+ Lisp_Object last_char, prev_char, idx;
- idx = make_number (SCHARS (echo_string) - 1);
- last_char = Faref (echo_string, idx);
+ idx = make_number (SCHARS (echo_string) - 2);
+ prev_char = Faref (echo_string, idx);
- /* We test PREV_CHAR to make sure this isn't the echoing
- of a minus-sign. */
- if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
- Faset (echo_string, idx, make_number (' '));
- else
- echo_string = concat2 (echo_string, build_string (" "));
- }
- else if (STRINGP (echo_string))
+ idx = make_number (SCHARS (echo_string) - 1);
+ last_char = Faref (echo_string, idx);
+
+ /* We test PREV_CHAR to make sure this isn't the echoing of a
+ minus-sign. */
+ if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
+ Faset (echo_string, idx, make_number (' '));
+ else
echo_string = concat2 (echo_string, build_string (" "));
+ }
+ else if (STRINGP (echo_string) && SCHARS (echo_string) > 0)
+ echo_string = concat2 (echo_string, build_string (" "));
- kset_echo_string
- (current_kboard,
- concat2 (echo_string, make_string (buffer, ptr - buffer)));
+ kset_echo_string
+ (current_kboard,
+ concat2 (echo_string, make_string (buffer, ptr - buffer)));
+}
+
+/* Add C to the echo string, if echoing is going on. C can be a
+ character or a symbol. */
+static void
+echo_char (Lisp_Object c)
+{
+ if (current_kboard->immediate_echo)
+ {
+ echo_add_key (c);
echo_now ();
}
}
/* Temporarily add a dash to the end of the echo string if it's not
- empty, so that it serves as a mini-prompt for the very next character. */
+ empty, so that it serves as a mini-prompt for the very next
+ character. */
static void
echo_dash (void)
}
echoing = 1;
- message3_nolog (KVAR (current_kboard, echo_string),
- SBYTES (KVAR (current_kboard, echo_string)),
- STRING_MULTIBYTE (KVAR (current_kboard, echo_string)));
+ /* FIXME: Use call (Qmessage) so it can be advised (e.g. emacspeak). */
+ message3_nolog (KVAR (current_kboard, echo_string));
echoing = 0;
/* Record in what buffer we echoed, and from which kboard. */
{
struct terminal *t;
struct kboard_stack *p = kboard_stack;
- int found = 0;
+ bool found = 0;
for (t = terminal_list; t; t = t->next_terminal)
{
if (t->kboard == p->kboard)
void
temporarily_switch_to_single_kboard (struct frame *f)
{
- int was_locked = single_kboard;
+ bool was_locked = single_kboard;
if (was_locked)
{
if (f != NULL && FRAME_KBOARD (f) != current_kboard)
Vprint_length = old_length;
Vquit_flag = Qnil;
-
Vinhibit_quit = Qnil;
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
- if (command_loop_level == 0 && minibuf_level == 0)
- any_kboard_state ();
-#endif
return make_number (0);
}
Vsignaling_function = Qnil;
}
-\f
-Lisp_Object command_loop_1 (void);
+
static Lisp_Object command_loop_2 (Lisp_Object);
static Lisp_Object top_level_1 (Lisp_Object);
while (1)
{
internal_catch (Qtop_level, top_level_1, Qnil);
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
- /* Reset single_kboard in case top-level set it while
- evaluating an -f option, or we are stuck there for some
- other reason. */
- any_kboard_state ();
-#endif
internal_catch (Qtop_level, command_loop_2, Qnil);
executing_kbd_macro = Qnil;
value to us. A value of nil means that command_loop_1 itself
returned due to end of file (or end of kbd macro). */
-Lisp_Object
+static Lisp_Object
command_loop_2 (Lisp_Object ignore)
{
register Lisp_Object val;
return Feval (Vtop_level, Qnil);
}
-Lisp_Object
+static Lisp_Object
top_level_1 (Lisp_Object ignore)
{
- /* On entry to the outer level, run the startup file */
+ /* On entry to the outer level, run the startup file. */
if (!NILP (Vtop_level))
internal_condition_case (top_level_2, Qerror, cmd_error);
else if (!NILP (Vpurify_flag))
- message ("Bare impure Emacs (standard Lisp code not loaded)");
+ message1 ("Bare impure Emacs (standard Lisp code not loaded)");
else
- message ("Bare Emacs (standard Lisp code not loaded)");
+ message1 ("Bare Emacs (standard Lisp code not loaded)");
return Qnil;
}
user_error ("No recursive edit is in progress");
}
\f
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
-
/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
of this function. */
if (!readable_events (READABLE_EVENTS_DO_TIMERS_NOW))
{
redisplay_preserve_echo_area (6);
- get_input_pending (&input_pending,
- READABLE_EVENTS_DO_TIMERS_NOW);
+ get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
}
}
return Qnil;
#if !defined HAVE_WINDOW_SYSTEM || defined USE_GTK || defined HAVE_NS
static
#endif
-int ignore_mouse_drag_p;
+bool ignore_mouse_drag_p;
static FRAME_PTR
some_mouse_moved (void)
return 0;
}
-#endif /* HAVE_MOUSE || HAVE_GPM */
\f
/* This is the actual command reading loop,
sans error-handling encapsulation. */
static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
- int, int, int);
+ bool, bool, bool);
void safe_run_hooks (Lisp_Object);
-static void adjust_point_for_property (ptrdiff_t, int);
+static void adjust_point_for_property (ptrdiff_t, bool);
/* Cancel hourglass from protect_unwind.
ARG is not used. */
int i;
EMACS_INT prev_modiff = 0;
struct buffer *prev_buffer = NULL;
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
- int was_locked = single_kboard;
-#endif
- int already_adjusted = 0;
+ bool already_adjusted = 0;
kset_prefix_arg (current_kboard, Qnil);
kset_last_prefix_arg (current_kboard, Qnil);
Vdeactivate_mark = Qnil;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
-
/* Don't ignore mouse movements for more than a single command
loop. (This flag is set in xdisp.c whenever the tool bar is
resized, because the resize moves text up or down, and would
generate false mouse drag events if we don't ignore them.) */
ignore_mouse_drag_p = 0;
-#endif
/* If minibuffer on and echo area in use,
wait a short time and redraw minibuffer. */
sit_for (Vminibuffer_message_timeout, 0, 2);
/* Clear the echo area. */
- message2 (0, 0, 0);
+ message1 (0);
safe_run_hooks (Qecho_area_clear_hook);
unbind_to (count, Qnil);
= (EQ (undo, BVAR (current_buffer, undo_list))
? Qnil : BVAR (current_buffer, undo_list));
}
- Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
+ call1 (Qcommand_execute, Vthis_command);
#ifdef HAVE_WINDOW_SYSTEM
/* Do not check display_hourglass_p here, because
- Fcommand_execute could change it, but we should cancel
+ `command-execute' could change it, but we should cancel
hourglass cursor anyway.
But don't cancel the hourglass within a macro
just because a command in the macro finishes. */
if (!NILP (KVAR (current_kboard, defining_kbd_macro))
&& NILP (KVAR (current_kboard, Vprefix_arg)))
finalize_kbd_macro_chars ();
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
- if (!was_locked)
- any_kboard_state ();
-#endif
}
}
LAST_PT is the last position of point. */
static void
-adjust_point_for_property (ptrdiff_t last_pt, int modified)
+adjust_point_for_property (ptrdiff_t last_pt, bool modified)
{
ptrdiff_t beg, end;
Lisp_Object val, overlay, tmp;
suppress the point adjustment for automatic composition so that a
user can keep inserting another character at point or keep
deleting characters around point. */
- int check_composition = ! modified, check_display = 1, check_invisible = 1;
+ bool check_composition = ! modified, check_display = 1, check_invisible = 1;
ptrdiff_t orig_pt = PT;
/* FIXME: cycling is probably not necessary because these properties
check_display = 0;
if (check_invisible && PT > BEGV && PT < ZV)
{
- int inv, ellipsis = 0;
+ int inv;
+ bool ellipsis = 0;
beg = end = PT;
/* Find boundaries `beg' and `end' of the invisible area, if any. */
if (SYMBOLP (hook))
{
Lisp_Object val;
- int found = 0;
+ bool found = 0;
Lisp_Object newval = Qnil;
for (val = find_symbol_value (hook); CONSP (val); val = XCDR (val))
if (EQ (fun, XCAR (val)))
int poll_suppress_count;
-/* Asynchronous timer for polling. */
-static struct atimer *poll_timer;
+#ifdef POLL_FOR_INPUT
+/* Asynchronous timer for polling. */
-#ifdef POLL_FOR_INPUT
+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
#endif
}
-/* Nonzero if we are using polling to handle input asynchronously. */
+/* True if we are using polling to handle input asynchronously. */
-int
+bool
input_polling_used (void)
{
#ifdef POLL_FOR_INPUT
return;
}
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!noninteractive && STRINGP (help))
{
/* The mouse-fixup-help-message Lisp function can call
if (f)
f->mouse_moved = 1;
}
-#endif
if (STRINGP (help) || NILP (help))
{
\f
/* Input of single characters from keyboard */
-static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
+static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
EMACS_TIME *end_time);
static void record_char (Lisp_Object c);
do { if (polling_stopped_here) start_polling (); \
polling_stopped_here = 0; } while (0)
-/* read a character from the keyboard; call the redisplay if needed */
+/* 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.
1 means do both. */
-/* The arguments MAPS and NMAPS are for menu prompting.
- MAPS is an array of keymaps; NMAPS is the length of MAPS.
+/* The arguments MAP is for menu prompting. MAP is a keymap.
PREV_EVENT is the previous input event, or nil if we are reading
the first event of a key sequence (or not reading a key sequence).
not to run input methods, but in other respects to act as if
not reading a key sequence.
- If USED_MOUSE_MENU is non-null, then we set *USED_MOUSE_MENU to 1
- if we used a mouse menu to read the input, or zero otherwise. If
- USED_MOUSE_MENU is null, we don't dereference it.
+ If USED_MOUSE_MENU is non-null, then set *USED_MOUSE_MENU to true
+ if we used a mouse menu to read the input, or false otherwise. If
+ USED_MOUSE_MENU is null, don't dereference it.
Value is -2 when we find input on another keyboard. A second call
to read_char will read it.
Value is t if we showed a menu and the user rejected it. */
Lisp_Object
-read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
+read_char (int commandflag, Lisp_Object map,
Lisp_Object prev_event,
- int *used_mouse_menu, EMACS_TIME *end_time)
+ bool *used_mouse_menu, EMACS_TIME *end_time)
{
Lisp_Object c;
ptrdiff_t jmpcount;
Lisp_Object tem, save;
volatile Lisp_Object previous_echo_area_message;
volatile Lisp_Object also_record;
- volatile int reread;
+ volatile bool reread;
struct gcpro gcpro1, gcpro2;
- int volatile polling_stopped_here = 0;
+ bool volatile polling_stopped_here = 0;
struct kboard *orig_kboard = current_kboard;
also_record = Qnil;
if (CONSP (Vunread_command_events))
{
- int was_disabled = 0;
+ bool was_disabled = 0;
c = XCAR (Vunread_command_events);
Vunread_command_events = XCDR (Vunread_command_events);
goto reread_first;
}
- /* if redisplay was requested */
+ /* If redisplay was requested. */
if (commandflag >= 0)
{
- int echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
+ bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
/* If there is pending input, process any events which are not
user-visible, such as X selection_request events. */
if (input_pending
|| detect_input_pending_run_timers (0))
- swallow_events (0); /* may clear input_pending */
+ swallow_events (0); /* May clear input_pending. */
/* Redisplay if no pending input. */
while (!input_pending)
menu prompting. If EVENT_HAS_PARAMETERS then we are reading
after a mouse event so don't try a minibuf menu. */
c = Qnil;
- if (nmaps > 0 && INTERACTIVE
+ if (KEYMAPP (map) && INTERACTIVE
&& !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
/* Don't bring up a menu if we already have another event. */
&& NILP (Vunread_command_events)
&& !detect_input_pending_run_timers (0))
{
- c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
+ c = read_char_minibuf_menu_prompt (commandflag, map);
if (INTEGERP (c) && XINT (c) == -2)
return c; /* wrong_kboard_jmpbuf */
because the recursive call of read_char in read_char_minibuf_menu_prompt
does not pass on any keymaps. */
- if (nmaps > 0 && INTERACTIVE
+ if (KEYMAPP (map) && INTERACTIVE
&& !NILP (prev_event)
&& EVENT_HAS_PARAMETERS (prev_event)
&& !EQ (XCAR (prev_event), Qmenu_bar)
/* Don't bring up a menu if we already have another event. */
&& NILP (Vunread_command_events))
{
- c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
+ c = read_char_x_menu_prompt (map, prev_event, used_mouse_menu);
/* Now that we have read an event, Emacs is not idle. */
if (!end_time)
&& XINT (Vauto_save_timeout) > 0)
{
Lisp_Object tem0;
- EMACS_INT timeout = (delay_level
- * min (XFASTINT (Vauto_save_timeout) / 4,
- MOST_POSITIVE_FIXNUM / delay_level));
+ EMACS_INT timeout = XFASTINT (Vauto_save_timeout);
+
+ timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
+ timeout = delay_level * timeout / 4;
save_getcjmp (save_jump);
restore_getcjmp (local_getcjmp);
tem0 = sit_for (make_number (timeout), 1, 1);
if (!NILP (tem))
{
struct buffer *prev_buffer = current_buffer;
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
- int was_locked = single_kboard;
- ptrdiff_t count = SPECPDL_INDEX ();
- record_single_kboard_state ();
-#endif
-
last_input_event = c;
- Fcommand_execute (tem, Qnil, Fvector (1, &last_input_event), Qt);
+ call4 (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
if (CONSP (c) && EQ (XCAR (c), Qselect_window) && !end_time)
/* We stopped being idle for this event; undo that. This
example banishing the mouse under mouse-avoidance-mode. */
timer_resume_idle ();
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
- /* Resume allowing input from any kboard, if that was true before. */
- if (!was_locked)
- any_kboard_state ();
- unbind_to (count, Qnil);
-#endif
-
if (current_buffer != prev_buffer)
{
/* The command may have changed the keymaps. Pretend there
{
Lisp_Object keys;
ptrdiff_t key_count;
- int key_count_reset;
+ bool key_count_reset;
struct gcpro gcpro1;
ptrdiff_t count = SPECPDL_INDEX ();
/* Save the echo status. */
- int saved_immediate_echo = current_kboard->immediate_echo;
+ bool saved_immediate_echo = current_kboard->immediate_echo;
struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
- int saved_echo_after_prompt = current_kboard->echo_after_prompt;
+ ptrdiff_t saved_echo_after_prompt = current_kboard->echo_after_prompt;
#if 0
if (before_command_restore_flag)
/* If we are not reading a key sequence,
never use the echo area. */
- if (maps == 0)
+ if (!KEYMAPP (map))
{
specbind (Qinput_method_use_echo_area, Qt);
}
last_input_event = c;
num_input_events++;
- /* Process the help character specially if enabled */
+ /* Process the help character specially if enabled. */
if (!NILP (Vhelp_form) && help_char_p (c))
{
ptrdiff_t count = SPECPDL_INDEX ();
cancel_echoing ();
do
{
- c = read_char (0, 0, 0, Qnil, 0, NULL);
+ c = read_char (0, Qnil, Qnil, 0, NULL);
if (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click))
XSETCAR (help_form_saved_window_configs, Qnil);
}
while (BUFFERP (c));
- /* Remove the help from the frame */
+ /* Remove the help from the frame. */
unbind_to (count, Qnil);
redisplay ();
{
cancel_echoing ();
do
- c = read_char (0, 0, 0, Qnil, 0, NULL);
+ c = read_char (0, Qnil, Qnil, 0, NULL);
while (BUFFERP (c));
}
}
num_input_events++;
}
-/* Return 1 if should recognize C as "the help character". */
+/* Return true if should recognize C as "the help character". */
-static int
+static bool
help_char_p (Lisp_Object c)
{
Lisp_Object tail;
/* Return true if there are any events in the queue that read-char
would return. If this returns false, a read-char would block. */
-static int
+static bool
readable_events (int flags)
{
if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
return 1;
}
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
&& !NILP (do_mouse_tracking) && some_mouse_moved ())
return 1;
-#endif
if (single_kboard)
{
if (current_kboard->kbd_queue_has_data)
static KBOARD *
event_to_kboard (struct input_event *event)
{
- Lisp_Object frame;
- frame = event->frame_or_window;
- if (CONSP (frame))
- frame = XCAR (frame);
- else if (WINDOWP (frame))
- frame = WINDOW_FRAME (XWINDOW (frame));
-
- /* There are still some events that don't set this field.
- For now, just ignore the problem.
- Also ignore dead frames here. */
- if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
- return 0;
+ /* Not applicable for these special events. */
+ if (event->kind == SELECTION_REQUEST_EVENT
+ || event->kind == SELECTION_CLEAR_EVENT)
+ return NULL;
else
- return FRAME_KBOARD (XFRAME (frame));
+ {
+ Lisp_Object obj = event->frame_or_window;
+ /* There are some events that set this field to nil or string. */
+ if (WINDOWP (obj))
+ obj = WINDOW_FRAME (XWINDOW (obj));
+ /* Also ignore dead frames here. */
+ return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
+ ? FRAME_KBOARD (XFRAME (obj)) : NULL);
+ }
}
#ifdef subprocesses
}
-/* Return non-zero if there are any real events waiting in the event
+/* Return true if there are any real events waiting in the event
buffer, not counting `NO_EVENT's.
- If DISCARD is non-zero, discard NO_EVENT events at the front of
- the input queue, possibly leaving the input queue empty if there
- are no real input events. */
+ Discard NO_EVENT events at the front of the input queue, possibly
+ leaving the input queue empty if there are no real input events. */
-int
-kbd_buffer_events_waiting (int discard)
+bool
+kbd_buffer_events_waiting (void)
{
struct input_event *sp;
sp = kbd_buffer;
}
- if (discard)
- kbd_fetch_ptr = sp;
-
+ kbd_fetch_ptr = sp;
return sp != kbd_store_ptr && sp->kind != NO_EVENT;
}
static Lisp_Object
kbd_buffer_get_event (KBOARD **kbp,
- int *used_mouse_menu,
+ bool *used_mouse_menu,
EMACS_TIME *end_time)
{
Lisp_Object obj;
#ifdef subprocesses
if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4)
{
- /* Start reading input again, we have processed enough so we can
- accept new events again. */
+ /* Start reading input again because we have processed enough to
+ be able to accept new events again. */
unhold_keyboard_input ();
start_polling ();
}
if (kbd_fetch_ptr != kbd_store_ptr)
break;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!NILP (do_mouse_tracking) && some_mouse_moved ())
break;
-#endif
/* If the quit flag is set, then read_char will return
quit_char, so that counts as "available input." */
#endif
if (kbd_fetch_ptr != kbd_store_ptr)
break;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!NILP (do_mouse_tracking) && some_mouse_moved ())
break;
-#endif
if (end_time)
{
EMACS_TIME now = current_emacs_time ();
x_activate_menubar (XFRAME (event->frame_or_window));
}
#endif
-#if defined (WINDOWSNT)
+#ifdef HAVE_NTGUI
else if (event->kind == LANGUAGE_CHANGE_EVENT)
{
/* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */
make_number (event->modifiers)));
kbd_fetch_ptr = event + 1;
}
+#endif
+#ifdef WINDOWSNT
else if (event->kind == FILE_NOTIFY_EVENT)
{
/* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
- obj = Fcons (Qfile_notify,
- list2 (list3 (event->code,
+ obj = Fcons (Qfile_w32notify,
+ list2 (list3 (make_number (event->code),
XCAR (event->arg),
- CAR_SAFE (XCDR (event->arg))),
+ XCDR (event->arg)),
event->frame_or_window));
kbd_fetch_ptr = event + 1;
}
obj = make_lispy_event (event);
kbd_fetch_ptr = event + 1;
}
+#endif
+#ifdef HAVE_INOTIFY
+ else if (event->kind == FILE_NOTIFY_EVENT)
+ {
+ obj = make_lispy_event (event);
+ kbd_fetch_ptr = event + 1;
+ }
#endif
else if (event->kind == CONFIG_CHANGED_EVENT)
{
}
}
}
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* Try generating a mouse motion event. */
else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
{
if (!NILP (x) && NILP (obj))
obj = make_lispy_movement (f, bar_window, part, x, y, t);
}
-#endif /* HAVE_MOUSE || HAVE GPM */
else
/* We were promised by the above while loop that there was
something for us to read! */
are ripe, and return, without reading any user-visible events. */
void
-swallow_events (int do_display)
+swallow_events (bool do_display)
{
- int old_timers_run;
+ unsigned old_timers_run;
process_special_events ();
old_timers_run = timers_run;
- get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
+ get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
if (timers_run != old_timers_run && do_display)
redisplay_preserve_echo_area (7);
EMACS_TIME difference;
EMACS_TIME timer_difference = invalid_emacs_time ();
EMACS_TIME idle_timer_difference = invalid_emacs_time ();
- int ripe, timer_ripe = 0, idle_timer_ripe = 0;
+ bool ripe, timer_ripe = 0, idle_timer_ripe = 0;
/* Set TIMER and TIMER_DIFFERENCE
based on the next ordinary timer.
string_info = Fcons (string, make_number (charpos));
textpos = (w == XWINDOW (selected_window)
&& current_buffer == XBUFFER (w->buffer))
- ? PT : XMARKER (w->pointm)->charpos;
+ ? PT : marker_position (w->pointm);
xret = wx;
yret = wy;
(sizeof (lispy_function_keys)
/ sizeof (lispy_function_keys[0])));
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
case MULTIMEDIA_KEY_EVENT:
if (event->code < (sizeof (lispy_multimedia_keys)
/ sizeof (lispy_multimedia_keys[0]))
return Qnil;
#endif
-#ifdef HAVE_MOUSE
/* 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:
#endif
{
int button = event->code;
- int is_double;
+ bool is_double;
Lisp_Object position;
Lisp_Object *start_pos_ptr;
Lisp_Object start_pos;
struct frame *fr;
int fuzz;
int symbol_num;
- int is_double;
+ bool is_double;
if (WINDOWP (event->frame_or_window))
fr = XFRAME (XWINDOW (event->frame_or_window)->frame);
Fcons (files,
Qnil)));
}
-#endif /* HAVE_MOUSE */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
}
#endif /* HAVE_DBUS */
+#ifdef HAVE_INOTIFY
+ case FILE_NOTIFY_EVENT:
+ {
+ return Fcons (Qfile_inotify, event->arg);
+ }
+#endif /* HAVE_INOTIFY */
+
case CONFIG_CHANGED_EVENT:
return Fcons (Qconfig_changed_event,
Fcons (event->arg,
}
}
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
-
static Lisp_Object
make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
Lisp_Object x, Lisp_Object y, Time t)
}
}
-#endif /* HAVE_MOUSE || HAVE GPM */
-
/* Construct a switch frame event. */
static Lisp_Object
make_lispy_switch_frame (Lisp_Object frame)
return 0;
}
-/* Return 1 if EVENT is a list whose elements are all integers or symbols.
+/* Return true if EVENT is a list whose elements are all integers or symbols.
Such a list is not valid as an event,
but it can be a Lucid-style event type list. */
-int
+bool
lucid_event_type_list_p (Lisp_Object object)
{
Lisp_Object tail;
return NILP (tail);
}
\f
-/* Store into *addr a value nonzero if terminal input chars are available.
- Serves the purpose of ioctl (0, FIONREAD, addr)
+/* Return true if terminal input chars are available.
+ Also, store the return value into INPUT_PENDING.
+
+ Serves the purpose of ioctl (0, FIONREAD, ...)
but works even if FIONREAD does not exist.
(In fact, this may actually read some input.)
If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
movements and toolkit scroll bar thumb drags. */
-static void
-get_input_pending (int *addr, int flags)
+static bool
+get_input_pending (int flags)
{
/* First of all, have we already counted some input? */
- *addr = (!NILP (Vquit_flag) || readable_events (flags));
+ input_pending = (!NILP (Vquit_flag) || readable_events (flags));
/* If input is being read as it arrives, and we have none, there is none. */
- if (*addr > 0 || (interrupt_input && ! interrupts_deferred))
- return;
+ if (!input_pending && (!interrupt_input || interrupts_deferred))
+ {
+ /* Try to read some input and see how much we get. */
+ gobble_input ();
+ input_pending = (!NILP (Vquit_flag) || readable_events (flags));
+ }
- /* Try to read some input and see how much we get. */
- gobble_input ();
- *addr = (!NILP (Vquit_flag) || readable_events (flags));
+ return input_pending;
}
/* Put a BUFFER_SWITCH_EVENT in the buffer
void
record_asynch_buffer_change (void)
{
- struct input_event event;
- Lisp_Object tem;
- EVENT_INIT (event);
-
- event.kind = BUFFER_SWITCH_EVENT;
- event.frame_or_window = Qnil;
- event.arg = Qnil;
-
/* We don't need a buffer-switch event unless Emacs is waiting for input.
The purpose of the event is to make read_key_sequence look up the
keymaps again. If we aren't in read_key_sequence, we don't need one,
and the event could cause trouble by messing up (input-pending-p).
Note: Fwaiting_for_user_input_p always returns nil when async
subprocesses aren't supported. */
- tem = Fwaiting_for_user_input_p ();
- if (NILP (tem))
- return;
+ if (!NILP (Fwaiting_for_user_input_p ()))
+ {
+ struct input_event event;
- /* Make sure no interrupt happens while storing the event. */
+ EVENT_INIT (event);
+ event.kind = BUFFER_SWITCH_EVENT;
+ event.frame_or_window = Qnil;
+ event.arg = Qnil;
+
+ /* Make sure no interrupt happens while storing the event. */
#ifdef USABLE_SIGIO
- if (interrupt_input)
- kbd_buffer_store_event (&event);
- else
+ if (interrupt_input)
+ kbd_buffer_store_event (&event);
+ else
#endif
- {
- stop_polling ();
- kbd_buffer_store_event (&event);
- start_polling ();
+ {
+ stop_polling ();
+ kbd_buffer_store_event (&event);
+ start_polling ();
+ }
}
}
-\f
+
/* Read any terminal input already buffered up by the system
into the kbd_buffer, but do not wait.
gobble_input (void)
{
int nread = 0;
- int err = 0;
+ bool err = 0;
struct terminal *t;
/* Store pending user signal events, if any. */
#elif defined USG || defined CYGWIN
/* Read some input if available, but don't wait. */
n_to_read = sizeof cbuf;
- fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
+ fcntl (fileno (tty->input), F_SETFL, O_NONBLOCK);
#else
# error "Cannot read without possibly delaying"
#endif
}
while (
/* We used to retry the read if it was interrupted.
- But this does the wrong thing when O_NDELAY causes
+ But this does the wrong thing when O_NONBLOCK causes
an EAGAIN error. Does anybody know of a situation
where a retry is actually needed? */
#if 0
- nread < 0 && (errno == EAGAIN
-#ifdef EFAULT
- || errno == EFAULT
-#endif
+ nread < 0 && (errno == EAGAIN || errno == EFAULT
#ifdef EBADSLT
|| errno == EBADSLT
#endif
0,
};
-/* Return non-zero if LABEL specifies a separator. */
+/* Return true if LABEL specifies a separator. */
-int
+bool
menu_separator_name_p (const char *label)
{
if (!label)
{
struct gcpro gcpro1;
int i;
+ bool parsed;
Lisp_Object tem;
if (EQ (item, Qundefined))
parse_menu_item, so that if it turns out it wasn't a menu item,
it still correctly hides any further menu item. */
GCPRO1 (key);
- i = parse_menu_item (item, 1);
+ parsed = parse_menu_item (item, 1);
UNGCPRO;
- if (!i)
+ if (!parsed)
return;
item = AREF (item_properties, ITEM_PROPERTY_DEF);
parse_menu_item returns true if the item is a menu item and false
otherwise. */
-int
+bool
parse_menu_item (Lisp_Object item, int inmenubar)
{
Lisp_Object def, tem, item_string, start;
static void init_tool_bar_items (Lisp_Object);
static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*);
-static int parse_tool_bar_item (Lisp_Object, Lisp_Object);
+static bool parse_tool_bar_item (Lisp_Object, Lisp_Object);
static void append_tool_bar_item (void);
/* Parse a tool bar item specification ITEM for key KEY and return the
- result in tool_bar_item_properties. Value is zero if ITEM is
+ result in tool_bar_item_properties. Value is false if ITEM is
invalid.
ITEM is a list `(menu-item CAPTION BINDING PROPS...)'.
A text label to show with the tool bar button if labels are enabled. */
-static int
+static bool
parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
{
Lisp_Object filter = Qnil;
Lisp_Object caption;
- int i, have_label = 0;
+ int i;
+ bool have_label = 0;
/* Definition looks like `(menu-item CAPTION BINDING PROPS...)'.
Rule out items that aren't lists, don't start with
static void
append_tool_bar_item (void)
{
- ptrdiff_t incr =
- (ntool_bar_items
- - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
+ ptrdiff_t incr
+ = (ntool_bar_items
+ - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
/* Enlarge tool_bar_items_vector if necessary. */
if (0 < incr)
\f
-/* Read a character using menus based on maps in the array MAPS.
- NMAPS is the length of MAPS. Return nil if there are no menus in the maps.
+/* Read a character using menus based on the keymap MAP.
+ Return nil if there are no menus in the maps.
Return t if we displayed a menu but the user rejected it.
PREV_EVENT is the previous input event, or nil if we are reading
the first event of a key sequence.
- If USED_MOUSE_MENU is non-null, then we set *USED_MOUSE_MENU to 1
- if we used a mouse menu to read the input, or zero otherwise. If
- USED_MOUSE_MENU is null, we don't dereference it.
+ If USED_MOUSE_MENU is non-null, set *USED_MOUSE_MENU to true
+ if we used a mouse menu to read the input, or false otherwise. If
+ USED_MOUSE_MENU is null, don't dereference it.
The prompting is done based on the prompt-string of the map
and the strings associated with various map elements.
and do auto-saving in the inner call of read_char. */
static Lisp_Object
-read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
- Lisp_Object prev_event, int *used_mouse_menu)
+read_char_x_menu_prompt (Lisp_Object map,
+ Lisp_Object prev_event, bool *used_mouse_menu)
{
-#ifdef HAVE_MENUS
- ptrdiff_t mapno;
-#endif
-
if (used_mouse_menu)
*used_mouse_menu = 0;
- /* Use local over global Menu maps */
+ /* Use local over global Menu maps. */
if (! menu_prompting)
return Qnil;
- /* Optionally disregard all but the global map. */
- if (inhibit_local_menu_bar_menus)
- {
- maps += (nmaps - 1);
- nmaps = 1;
- }
-
#ifdef HAVE_MENUS
/* If we got to this point via a mouse click,
use a real menu for mouse selection. */
&& !EQ (XCAR (prev_event), Qtool_bar))
{
/* Display the menu and get the selection. */
- Lisp_Object *realmaps = alloca (nmaps * sizeof *realmaps);
Lisp_Object value;
- ptrdiff_t nmaps1 = 0;
-
- /* Use the maps that are not nil. */
- for (mapno = 0; mapno < nmaps; mapno++)
- if (!NILP (maps[mapno]))
- realmaps[nmaps1++] = maps[mapno];
- value = Fx_popup_menu (prev_event, Flist (nmaps1, realmaps));
+ value = Fx_popup_menu (prev_event, get_keymap (map, 0, 1));
if (CONSP (value))
{
Lisp_Object tem;
return Qnil ;
}
-/* Buffer in use so far for the minibuf prompts for menu keymaps.
- We make this bigger when necessary, and never free it. */
-static char *read_char_minibuf_menu_text;
-/* Size of that buffer. */
-static ptrdiff_t read_char_minibuf_menu_width;
-
static Lisp_Object
read_char_minibuf_menu_prompt (int commandflag,
- ptrdiff_t nmaps, Lisp_Object *maps)
+ Lisp_Object map)
{
- ptrdiff_t mapno;
register Lisp_Object name;
ptrdiff_t nlength;
/* FIXME: Use the minibuffer's frame width. */
ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
ptrdiff_t idx = -1;
- int nobindings = 1;
+ bool nobindings = 1;
Lisp_Object rest, vector;
- char *menu;
+ Lisp_Object prompt_strings = Qnil;
vector = Qnil;
- name = Qnil;
if (! menu_prompting)
return Qnil;
- /* Get the menu name from the first map that has one (a prompt string). */
- for (mapno = 0; mapno < nmaps; mapno++)
- {
- name = Fkeymap_prompt (maps[mapno]);
- if (!NILP (name))
- break;
- }
+ map = get_keymap (map, 0, 1);
+ name = Fkeymap_prompt (map);
/* If we don't have any menus, just read a character normally. */
if (!STRINGP (name))
return Qnil;
- /* Make sure we have a big enough buffer for the menu text. */
- width = max (width, SBYTES (name));
- if (STRING_BYTES_BOUND - 4 < width)
- memory_full (SIZE_MAX);
- if (width + 4 > read_char_minibuf_menu_width)
- {
- read_char_minibuf_menu_text
- = xrealloc (read_char_minibuf_menu_text, width + 4);
- read_char_minibuf_menu_width = width + 4;
- }
- menu = read_char_minibuf_menu_text;
+#define PUSH_C_STR(str, listvar) \
+ listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar)
/* Prompt string always starts with map's prompt, and a space. */
- strcpy (menu, SSDATA (name));
- nlength = SBYTES (name);
- menu[nlength++] = ':';
- menu[nlength++] = ' ';
- menu[nlength] = 0;
+ prompt_strings = Fcons (name, prompt_strings);
+ PUSH_C_STR (": ", prompt_strings);
+ nlength = SCHARS (name) + 2;
- /* Start prompting at start of first map. */
- mapno = 0;
- rest = maps[mapno];
+ rest = map;
/* Present the documented bindings, a line at a time. */
while (1)
{
- int notfirst = 0;
+ bool notfirst = 0;
+ Lisp_Object menu_strings = prompt_strings;
ptrdiff_t i = nlength;
Lisp_Object obj;
Lisp_Object orig_defn_macro;
{
Lisp_Object elt;
- /* If reached end of map, start at beginning of next map. */
+ /* FIXME: Use map_keymap to handle new keymap formats. */
+
+ /* At end of map, wrap around if just starting,
+ or end this line if already have something on it. */
if (NILP (rest))
{
- mapno++;
- /* At end of last map, wrap around to first map if just starting,
- or end this line if already have something on it. */
- if (mapno == nmaps)
- {
- mapno = 0;
- if (notfirst || nobindings) break;
- }
- rest = maps[mapno];
+ if (notfirst || nobindings)
+ break;
+ else
+ rest = map;
}
/* Look at the next element of the map. */
/* Ignore the element if it has no prompt string. */
if (INTEGERP (event) && parse_menu_item (elt, -1))
{
- /* 1 if the char to type matches the string. */
- int char_matches;
+ /* True if the char to type matches the string. */
+ bool char_matches;
Lisp_Object upcased_event, downcased_event;
Lisp_Object desc = Qnil;
Lisp_Object s
/* Punctuate between strings. */
if (notfirst)
{
- strcpy (menu + i, ", ");
+ PUSH_C_STR (", ", menu_strings);
i += 2;
}
notfirst = 1;
- nobindings = 0 ;
+ nobindings = 0;
/* If the char to type doesn't match the string's
first char, explicitly show what char to type. */
{
/* Add as much of string as fits. */
thiswidth = min (SCHARS (desc), width - i);
- memcpy (menu + i, SDATA (desc), thiswidth);
+ menu_strings
+ = Fcons (Fsubstring (desc, make_number (0),
+ make_number (thiswidth)),
+ menu_strings);
i += thiswidth;
- strcpy (menu + i, " = ");
+ PUSH_C_STR (" = ", menu_strings);
i += 3;
}
/* Add as much of string as fits. */
thiswidth = min (SCHARS (s), width - i);
- memcpy (menu + i, SDATA (s), thiswidth);
+ menu_strings
+ = Fcons (Fsubstring (s, make_number (0),
+ make_number (thiswidth)),
+ menu_strings);
i += thiswidth;
- menu[i] = 0;
}
else
{
/* If this element does not fit, end the line now,
and save the element for the next line. */
- strcpy (menu + i, "...");
+ PUSH_C_STR ("...", menu_strings);
break;
}
}
}
/* Prompt with that and read response. */
- message2_nolog (menu, strlen (menu),
- ! NILP (BVAR (current_buffer, enable_multibyte_characters)));
+ message3_nolog (apply1 (intern ("concat"), Fnreverse (menu_strings)));
- /* Make believe its not a keyboard macro in case the help char
+ /* Make believe it's not a keyboard macro in case the help char
is pressed. Help characters are not recorded because menu prompting
- is not used on replay.
- */
+ is not used on replay. */
orig_defn_macro = KVAR (current_kboard, defining_kbd_macro);
kset_defining_kbd_macro (current_kboard, Qnil);
do
- obj = read_char (commandflag, 0, 0, Qt, 0, NULL);
+ obj = read_char (commandflag, Qnil, Qt, 0, NULL);
while (BUFFERP (obj));
kset_defining_kbd_macro (current_kboard, orig_defn_macro);
- if (!INTEGERP (obj))
- return obj;
- else if (XINT (obj) == -2)
+ if (!INTEGERP (obj) || XINT (obj) == -2)
return obj;
if (! EQ (obj, menu_prompt_more_char)
store_kbd_macro_char (obj);
return obj;
}
- /* Help char - go round again */
+ /* Help char - go round again. */
}
}
\f
/* Reading key sequences. */
-/* Follow KEY in the maps in CURRENT[0..NMAPS-1], placing its bindings
- in DEFS[0..NMAPS-1]. Set NEXT[i] to DEFS[i] if DEFS[i] is a
- keymap, or nil otherwise. Return the index of the first keymap in
- which KEY has any binding, or NMAPS if no map has a binding.
-
- If KEY is a meta ASCII character, treat it like meta-prefix-char
- followed by the corresponding non-meta character. Keymaps in
- CURRENT with non-prefix bindings for meta-prefix-char become nil in
- NEXT.
-
- If KEY has no bindings in any of the CURRENT maps, NEXT is left
- unmodified.
-
- NEXT may be the same array as CURRENT. */
-
-static int
-follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current,
- Lisp_Object *defs, Lisp_Object *next)
+static Lisp_Object
+follow_key (Lisp_Object keymap, Lisp_Object key)
{
- ptrdiff_t i, first_binding;
-
- first_binding = nmaps;
- for (i = nmaps - 1; i >= 0; i--)
- {
- if (! NILP (current[i]))
- {
- defs[i] = access_keymap (current[i], key, 1, 0, 1);
- if (! NILP (defs[i]))
- first_binding = i;
- }
- else
- defs[i] = Qnil;
- }
-
- /* Given the set of bindings we've found, produce the next set of maps. */
- if (first_binding < nmaps)
- for (i = 0; i < nmaps; i++)
- next[i] = NILP (defs[i]) ? Qnil : get_keymap (defs[i], 0, 1);
+ return access_keymap (get_keymap (keymap, 0, 1),
+ key, 1, 0, 1);
+}
- return first_binding;
+static Lisp_Object
+active_maps (Lisp_Object first_event)
+{
+ Lisp_Object position
+ = CONSP (first_event) ? CAR_SAFE (XCDR (first_event)) : Qnil;
+ return Fcons (Qkeymap, Fcurrent_active_maps (Qt, position));
}
/* Structure used to keep track of partial application of key remapping
/* Lookup KEY in MAP.
MAP is a keymap mapping keys to key vectors or functions.
- If the mapping is a function and DO_FUNCTION is non-zero, then
+ If the mapping is a function and DO_FUNCALL is true,
the function is called with PROMPT as parameter and its return
value is used as the return value of this function (after checking
that it is indeed a vector). */
static Lisp_Object
access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
- int do_funcall)
+ bool do_funcall)
{
Lisp_Object next;
BUFSIZE is its maximum size.
FKEY is a pointer to the keyremap structure to use.
INPUT is the index of the last element in KEYBUF.
- DOIT if non-zero says that the remapping can actually take place.
+ DOIT if true says that the remapping can actually take place.
DIFF is used to return the number of keys added/removed by the remapping.
PARENT is the root of the keymap.
PROMPT is the prompt to use if the remapping happens through a function.
- The return value is non-zero if the remapping actually took place. */
+ Return true if the remapping actually took place. */
-static int
+static bool
keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
- int input, int doit, int *diff, Lisp_Object prompt)
+ int input, bool doit, int *diff, Lisp_Object prompt)
{
Lisp_Object next, key;
return 0;
}
-static int
+static bool
test_undefined (Lisp_Object binding)
{
- return (EQ (binding, Qundefined)
- || (!NILP (binding) && SYMBOLP (binding)
+ return (NILP (binding)
+ || EQ (binding, Qundefined)
+ || (SYMBOLP (binding)
&& EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
}
off the switch-frame event until later; the next call to
read_char will return it.
- If FIX_CURRENT_BUFFER is nonzero, we restore current_buffer
+ If FIX_CURRENT_BUFFER, we restore current_buffer
from the selected window's buffer. */
static int
read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
- int dont_downcase_last, int can_return_switch_frame,
- int fix_current_buffer)
+ bool dont_downcase_last, bool can_return_switch_frame,
+ bool fix_current_buffer)
{
- Lisp_Object from_string;
ptrdiff_t count = SPECPDL_INDEX ();
/* How many keys there are in the current key sequence. */
ptrdiff_t echo_start IF_LINT (= 0);
ptrdiff_t keys_start;
- /* The number of keymaps we're scanning right now, and the number of
- keymaps we have allocated space for. */
- ptrdiff_t nmaps;
- ptrdiff_t nmaps_allocated = 0;
+ Lisp_Object current_binding = Qnil;
+ Lisp_Object first_event = Qnil;
- /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
- the current keymaps. */
- Lisp_Object *defs = NULL;
-
- /* submaps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
- in the current keymaps, or nil where it is not a prefix. */
- Lisp_Object *submaps = NULL;
-
- /* The local map to start out with at start of key sequence. */
- Lisp_Object orig_local_map;
-
- /* The map from the `keymap' property to start out with at start of
- key sequence. */
- Lisp_Object orig_keymap;
-
- /* 1 if we have already considered switching to the local-map property
- of the place where a mouse click occurred. */
- int localized_local_map = 0;
-
- /* The index in submaps[] of the first keymap that has a binding for
- this key sequence. In other words, the lowest i such that
- submaps[i] is non-nil. */
- ptrdiff_t first_binding;
/* Index of the first key that has no binding.
It is useless to try fkey.start larger than that. */
int first_unbound;
/* Likewise, for key_translation_map and input-decode-map. */
keyremap keytran, indec;
- /* Non-zero if we are trying to map a key by changing an upper-case
+ /* True if we are trying to map a key by changing an upper-case
letter to lower case, or a shifted function key to an unshifted
one. */
- int shift_translated = 0;
+ bool shift_translated = 0;
/* If we receive a `switch-frame' or `select-window' event in the middle of
a key sequence, we put it off for later.
While we're reading, we keep the event here. */
Lisp_Object delayed_switch_frame;
- /* See the comment below... */
-#if defined (GOBBLE_FIRST_EVENT)
- Lisp_Object first_event;
-#endif
-
Lisp_Object original_uppercase IF_LINT (= Qnil);
int original_uppercase_position = -1;
/* Gets around Microsoft compiler limitations. */
- int dummyflag = 0;
+ bool dummyflag = 0;
struct buffer *starting_buffer;
/* List of events for which a fake prefix key has been generated. */
Lisp_Object fake_prefixed_keys = Qnil;
-#if defined (GOBBLE_FIRST_EVENT)
- int junk;
-#endif
-
struct gcpro gcpro1;
GCPRO1 (fake_prefixed_keys);
keys_start = this_command_key_count;
this_single_command_key_start = keys_start;
-#if defined (GOBBLE_FIRST_EVENT)
- /* This doesn't quite work, because some of the things that read_char
- does cannot safely be bypassed. It seems too risky to try to make
- this work right. */
-
- /* Read the first char of the sequence specially, before setting
- up any keymaps, in case a filter runs and switches buffers on us. */
- first_event = read_char (NILP (prompt), 0, submaps, last_nonmenu_event,
- &junk, NULL);
-#endif /* GOBBLE_FIRST_EVENT */
-
- orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
- orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
- from_string = Qnil;
-
/* We jump here when we need to reinitialize fkey and keytran; this
happens if we switch keyboards between rescans. */
replay_entire_sequence:
keybuf with its symbol, or if the sequence starts with a mouse
click and we need to switch buffers, we jump back here to rebuild
the initial keymaps from the current buffer. */
- nmaps = 0;
-
- if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
- {
- if (2 > nmaps_allocated)
- {
- submaps = alloca (2 * sizeof *submaps);
- defs = alloca (2 * sizeof *defs);
- nmaps_allocated = 2;
- }
- submaps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
- }
- else if (!NILP (Voverriding_local_map))
- {
- if (2 > nmaps_allocated)
- {
- submaps = alloca (2 * sizeof *submaps);
- defs = alloca (2 * sizeof *defs);
- nmaps_allocated = 2;
- }
- submaps[nmaps++] = Voverriding_local_map;
- }
- else
- {
- ptrdiff_t nminor;
- ptrdiff_t total;
- Lisp_Object *maps;
-
- nminor = current_minor_maps (0, &maps);
- total = nminor + (!NILP (orig_keymap) ? 3 : 2);
-
- if (total > nmaps_allocated)
- {
- submaps = alloca (total * sizeof *submaps);
- defs = alloca (total * sizeof *defs);
- nmaps_allocated = total;
- }
-
- if (!NILP (orig_keymap))
- submaps[nmaps++] = orig_keymap;
-
- memcpy (submaps + nmaps, maps, nminor * sizeof (submaps[0]));
-
- nmaps += nminor;
-
- submaps[nmaps++] = orig_local_map;
- }
- submaps[nmaps++] = current_global_map;
-
- /* Find an accurate initial value for first_binding. */
- for (first_binding = 0; first_binding < nmaps; first_binding++)
- if (! NILP (submaps[first_binding]))
- break;
+ current_binding = active_maps (first_event);
/* Start from the beginning in keybuf. */
t = 0;
/* If the best binding for the current key sequence is a keymap, or
we may be looking at a function key's escape sequence, keep on
reading. */
- while (first_binding < nmaps
+ while (!NILP (current_binding)
/* Keep reading as long as there's a prefix binding. */
- ? !NILP (submaps[first_binding])
+ ? KEYMAPP (current_binding)
/* Don't return in the middle of a possible function key sequence,
if the only bindings we found were via case conversion.
Thus, if ESC O a has a function-key-map translation
: (/* indec.start < t || fkey.start < t || */ keytran.start < t))
{
Lisp_Object key;
- int used_mouse_menu = 0;
+ bool used_mouse_menu = 0;
/* Where the last real key started. If we need to throw away a
key that has expanded into more than one element of keybuf
just one key. */
ptrdiff_t echo_local_start IF_LINT (= 0);
int keys_local_start;
- ptrdiff_t local_first_binding;
+ Lisp_Object new_binding;
eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
eassert (indec.start <= indec.end);
if (INTERACTIVE)
echo_local_start = echo_length ();
keys_local_start = this_command_key_count;
- local_first_binding = first_binding;
replay_key:
/* These are no-ops, unless we throw away a keystroke below and
if (INTERACTIVE && t < mock_input)
echo_truncate (echo_local_start);
this_command_key_count = keys_local_start;
- first_binding = local_first_binding;
/* By default, assume each event is "real". */
last_real_key_start = t;
key = keybuf[t];
add_command_key (key);
if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes)))
- echo_char (key);
+ && NILP (Fzerop (Vecho_keystrokes))
+ && current_kboard->immediate_echo)
+ {
+ echo_add_key (key);
+ echo_dash ();
+ }
}
/* If not, we should actually read a character. */
{
KBOARD *interrupted_kboard = current_kboard;
struct frame *interrupted_frame = SELECTED_FRAME ();
- key = read_char (NILP (prompt), nmaps,
- (Lisp_Object *) submaps, last_nonmenu_event,
+ key = read_char (NILP (prompt),
+ current_binding, last_nonmenu_event,
&used_mouse_menu, NULL);
if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
/* When switching to a new tty (with a new keyboard),
return. Any better way to fix this? -- cyd */
|| (interrupted_kboard != current_kboard))
{
- int found = 0;
+ bool found = 0;
struct kboard *k;
for (k = all_kboards; k; k = k->next_kboard)
KVAR (interrupted_kboard, kbd_queue)));
}
mock_input = 0;
- orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
- orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
goto replay_entire_sequence;
}
}
{
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
- if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
+ if (XBUFFER (XWINDOW (selected_window)->buffer)
+ != current_buffer)
Fset_buffer (XWINDOW (selected_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;
}
keybuf[t++] = key;
mock_input = t;
Vquit_flag = Qnil;
- orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
- orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
goto replay_sequence;
}
}
}
+ if (NILP (first_event))
+ {
+ first_event = key;
+ /* Even if first_event does not specify a particular
+ window/position, it's important to recompute the maps here
+ since a long time might have passed since we entered
+ read_key_sequence, and a timer (or process-filter or
+ special-event-map, ...) might have switched the current buffer
+ or the selected window from under us in the mean time. */
+ if (fix_current_buffer
+ && (XBUFFER (XWINDOW (selected_window)->buffer)
+ != current_buffer))
+ Fset_buffer (XWINDOW (selected_window)->buffer);
+ current_binding = active_maps (first_event);
+ }
+
GROW_RAW_KEYBUF;
ASET (raw_keybuf, raw_keybuf_count, key);
raw_keybuf_count++;
or when user programs play with this-command-keys. */
if (EVENT_HAS_PARAMETERS (key))
{
- Lisp_Object kind;
- Lisp_Object string;
-
- kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
+ Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
if (EQ (kind, Qmouse_click))
{
- Lisp_Object window, posn;
-
- window = POSN_WINDOW (EVENT_START (key));
- posn = POSN_POSN (EVENT_START (key));
+ Lisp_Object window = POSN_WINDOW (EVENT_START (key));
+ Lisp_Object posn = POSN_POSN (EVENT_START (key));
if (CONSP (posn)
|| (!NILP (fake_prefixed_keys)
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 (CONSP (XCDR (key))
- && ! localized_local_map)
- {
- Lisp_Object map_here, start, pos;
-
- 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)
- {
- 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;
- }
-
- if (localized_local_map > 1)
- {
- keybuf[t] = key;
- mock_input = t + 1;
-
- goto replay_sequence;
- }
- }
- }
- }
}
/* Expand mode-line and scroll-bar events into two events:
prevent proper action when the event is pushed
back into unread-command-events. */
fake_prefixed_keys = Fcons (key, fake_prefixed_keys);
-
- /* If on a mode line string with a local keymap,
- reconsider the key sequence with that keymap. */
- if (string = POSN_STRING (EVENT_START (key)),
- (CONSP (string) && STRINGP (XCAR (string))))
- {
- Lisp_Object pos, map, map2;
-
- pos = XCDR (string);
- string = XCAR (string);
- if (XINT (pos) >= 0
- && XINT (pos) < SCHARS (string))
- {
- map = Fget_text_property (pos, Qlocal_map, string);
- if (!NILP (map))
- orig_local_map = map;
- map2 = Fget_text_property (pos, Qkeymap, string);
- if (!NILP (map2))
- orig_keymap = map2;
- if (!NILP (map) || !NILP (map2))
- goto replay_sequence;
- }
- }
-
goto replay_key;
}
- else if (NILP (from_string)
- && (string = POSN_STRING (EVENT_START (key)),
- (CONSP (string) && STRINGP (XCAR (string)))))
- {
- /* For a click on a string, i.e. overlay string or a
- string displayed via the `display' property,
- consider `local-map' and `keymap' properties of
- that string. */
- Lisp_Object pos, map, map2;
-
- pos = XCDR (string);
- string = XCAR (string);
- if (XINT (pos) >= 0
- && XINT (pos) < SCHARS (string))
- {
- map = Fget_text_property (pos, Qlocal_map, string);
- if (!NILP (map))
- orig_local_map = map;
- map2 = Fget_text_property (pos, Qkeymap, string);
- if (!NILP (map2))
- orig_keymap = map2;
-
- if (!NILP (map) || !NILP (map2))
- {
- from_string = string;
- keybuf[t++] = key;
- mock_input = t;
- goto replay_sequence;
- }
- }
- }
}
else if (CONSP (XCDR (key))
&& CONSP (EVENT_START (key))
if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
- keybuf[t+1] = key;
+ keybuf[t + 1] = key;
/* Zap the position in key, so we know that we've
expanded it, and don't try to do so again. */
/* We have finally decided that KEY is something we might want
to look up. */
- first_binding = (follow_key (key,
- nmaps - first_binding,
- submaps + first_binding,
- defs + first_binding,
- submaps + first_binding)
- + first_binding);
+ new_binding = follow_key (current_binding, key);
/* If KEY wasn't bound, we'll try some fallbacks. */
- if (first_binding < nmaps)
+ if (!NILP (new_binding))
/* This is needed for the following scenario:
event 0: a down-event that gets dropped by calling replay_key.
event 1: some normal prefix like C-h.
new_click
= Fcons (new_head, Fcons (EVENT_START (key), Qnil));
- /* Look for a binding for this new key. follow_key
- promises that it didn't munge submaps the
- last time we called it, since key was unbound. */
- first_binding
- = (follow_key (new_click,
- nmaps - local_first_binding,
- submaps + local_first_binding,
- defs + local_first_binding,
- submaps + local_first_binding)
- + local_first_binding);
+ /* Look for a binding for this new key. */
+ new_binding = follow_key (current_binding, new_click);
/* If that click is bound, go for it. */
- if (first_binding < nmaps)
+ if (!NILP (new_binding))
{
+ current_binding = new_binding;
key = new_click;
break;
}
}
}
}
+ current_binding = new_binding;
keybuf[t++] = key;
/* Normally, last_nonmenu_event gets the previous key we read.
while (indec.end < t)
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- int done, diff;
+ bool done;
+ int diff;
GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame);
done = keyremap_step (keybuf, bufsize, &indec, max (t, mock_input),
}
}
- if (first_binding < nmaps
- && NILP (submaps[first_binding])
- && !test_undefined (defs[first_binding])
+ if (!KEYMAPP (current_binding)
+ && !test_undefined (current_binding)
&& indec.start >= t)
/* There is a binding and it's not a prefix.
(and it doesn't have any input-decode-map translation pending).
while (fkey.end < indec.start)
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- int done, diff;
+ bool done;
+ int diff;
GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame);
done = keyremap_step (keybuf, bufsize, &fkey,
first_binding >= nmaps) we don't want
to apply this function-key-mapping. */
fkey.end + 1 == t
- && (first_binding >= nmaps
- || test_undefined (defs[first_binding])),
+ && (test_undefined (current_binding)),
&diff, prompt);
UNGCPRO;
if (done)
while (keytran.end < fkey.start)
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- int done, diff;
+ bool done;
+ int diff;
GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame);
done = keyremap_step (keybuf, bufsize, &keytran, max (t, mock_input),
and cannot be part of a function key or translation,
and is an upper case letter
use the corresponding lower-case letter instead. */
- if (first_binding >= nmaps
+ if (NILP (current_binding)
&& /* indec.start >= t && fkey.start >= t && */ keytran.start >= t
&& INTEGERP (key)
&& ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK))
and cannot be part of a function key or translation,
and is a shifted function key,
use the corresponding unshifted function key instead. */
- if (first_binding >= nmaps
+ if (NILP (current_binding)
&& /* indec.start >= t && fkey.start >= t && */ keytran.start >= t)
{
Lisp_Object breakdown = parse_modifiers (key);
}
}
if (!dummyflag)
- read_key_sequence_cmd = (first_binding < nmaps
- ? defs[first_binding]
- : Qnil);
+ read_key_sequence_cmd = current_binding;
read_key_sequence_remapped
/* Remap command through active keymaps.
Do the remapping here, before the unbind_to so it uses the keymaps
/* Don't downcase the last character if the caller says don't.
Don't downcase it if the result is undefined, either. */
- if ((dont_downcase_last || first_binding >= nmaps)
+ if ((dont_downcase_last || NILP (current_binding))
&& t > 0
&& t - 1 == original_uppercase_position)
{
memset (keybuf, 0, sizeof keybuf);
GCPRO1 (keybuf[0]);
- gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
+ gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0]));
if (NILP (continue_echo))
{
cancel_hourglass ();
#endif
- i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
+ i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), 0);
return unbind_to (count, Fvector (i, keybuf));
}
\f
-DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0,
- doc: /* Execute CMD as an editor command.
-CMD must be a symbol that satisfies the `commandp' predicate.
-Optional second arg RECORD-FLAG non-nil
-means unconditionally put this command in `command-history'.
-Otherwise, that is done only if an arg is read using the minibuffer.
-The argument KEYS specifies the value to use instead of (this-command-keys)
-when reading the arguments; if it is nil, (this-command-keys) is used.
-The argument SPECIAL, if non-nil, means that this command is executing
-a special event, so ignore the prefix argument and don't clear it. */)
- (Lisp_Object cmd, Lisp_Object record_flag, Lisp_Object keys, Lisp_Object special)
-{
- register Lisp_Object final;
- register Lisp_Object tem;
- Lisp_Object prefixarg;
-
- debug_on_next_call = 0;
-
- if (NILP (special))
- {
- prefixarg = KVAR (current_kboard, Vprefix_arg);
- Vcurrent_prefix_arg = prefixarg;
- kset_prefix_arg (current_kboard, Qnil);
- }
- else
- prefixarg = Qnil;
-
- if (SYMBOLP (cmd))
- {
- tem = Fget (cmd, Qdisabled);
- if (!NILP (tem))
- {
- tem = Fsymbol_value (Qdisabled_command_function);
- if (!NILP (tem))
- return Frun_hooks (1, &Qdisabled_command_function);
- }
- }
-
- while (1)
- {
- final = Findirect_function (cmd, Qnil);
-
- if (CONSP (final) && (tem = Fcar (final), EQ (tem, Qautoload)))
- {
- struct gcpro gcpro1, gcpro2;
-
- GCPRO2 (cmd, prefixarg);
- Fautoload_do_load (final, cmd, Qnil);
- UNGCPRO;
- }
- else
- break;
- }
-
- if (STRINGP (final) || VECTORP (final))
- {
- /* If requested, place the macro in the command history. For
- other sorts of commands, call-interactively takes care of
- this. */
- if (!NILP (record_flag))
- {
- Vcommand_history
- = Fcons (Fcons (Qexecute_kbd_macro,
- Fcons (final, Fcons (prefixarg, Qnil))),
- Vcommand_history);
-
- /* Don't keep command history around forever. */
- if (NUMBERP (Vhistory_length) && XINT (Vhistory_length) > 0)
- {
- tem = Fnthcdr (Vhistory_length, Vcommand_history);
- if (CONSP (tem))
- XSETCDR (tem, Qnil);
- }
- }
-
- return Fexecute_kbd_macro (final, prefixarg, Qnil);
- }
-
- if (CONSP (final) || SUBRP (final) || COMPILEDP (final))
- /* Don't call Fcall_interactively directly because we want to make
- sure the backtrace has an entry for `call-interactively'.
- For the same reason, pass `cmd' rather than `final'. */
- return call3 (Qcall_interactively, cmd, record_flag, keys);
-
- return Qnil;
-}
-
-
-\f
-/* Return nonzero if input events are pending. */
+/* Return true if input events are pending. */
-int
+bool
detect_input_pending (void)
{
- if (!input_pending)
- get_input_pending (&input_pending, 0);
-
- return input_pending;
+ return input_pending || get_input_pending (0);
}
-/* Return nonzero if input events other than mouse movements are
+/* Return true if input events other than mouse movements are
pending. */
-int
+bool
detect_input_pending_ignore_squeezables (void)
{
- if (!input_pending)
- get_input_pending (&input_pending, READABLE_EVENTS_IGNORE_SQUEEZABLES);
-
- return input_pending;
+ return input_pending || get_input_pending (READABLE_EVENTS_IGNORE_SQUEEZABLES);
}
-/* Return nonzero if input events are pending, and run any pending timers. */
+/* Return true if input events are pending, and run any pending timers. */
-int
-detect_input_pending_run_timers (int do_display)
+bool
+detect_input_pending_run_timers (bool do_display)
{
- int old_timers_run = timers_run;
+ unsigned old_timers_run = timers_run;
if (!input_pending)
- get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
+ get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
if (old_timers_run != timers_run && do_display)
{
input_pending = 0;
}
-/* Return nonzero if there are pending requeued events.
+/* Return true if there are pending requeued events.
This isn't used yet. The hope is to make wait_reading_process_output
call it, and return if it runs Lisp code that unreads something.
The problem is, kbd_buffer_get_event needs to be fixed to know what
to do in that case. It isn't trivial. */
-int
+bool
requeued_events_pending_p (void)
{
return (!NILP (Vunread_command_events));
/* Process non-user-visible events (Bug#10195). */
process_special_events ();
- get_input_pending (&input_pending,
- READABLE_EVENTS_DO_TIMERS_NOW
- | READABLE_EVENTS_FILTER_EVENTS);
- return input_pending > 0 ? Qt : Qnil;
+ return (get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW
+ | READABLE_EVENTS_FILTER_EVENTS)
+ ? Qt : Qnil);
}
DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0,
fflush (stdout);
reset_all_sys_modes ();
-#ifdef SIGTSTP /* Support possible in later USG versions */
+#ifdef SIGTSTP
/*
* On systems which can suspend the current process and return to the original
* shell, this command causes the user to end up back at the shell.
/* Handle a C-g by making read_char return C-g. */
static void
-quit_throw_to_read_char (int from_signal)
+quit_throw_to_read_char (bool from_signal)
{
/* When not called from a signal handler it is safe to call
Lisp. */
See also `current-input-mode'. */)
(Lisp_Object interrupt)
{
- int new_interrupt_input;
+ bool new_interrupt_input;
#ifdef USABLE_SIGIO
#ifdef HAVE_X_WINDOWS
if (x_display_list != NULL)
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
kbd_store_ptr = kbd_buffer;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
do_mouse_tracking = Qnil;
-#endif
input_pending = 0;
interrupt_input_blocked = 0;
pending_signals = 0;
DEFSYM (Qconfig_changed_event, "config-changed-event");
DEFSYM (Qmenu_enable, "menu-enable");
-#if defined (WINDOWSNT)
+#ifdef HAVE_NTGUI
DEFSYM (Qlanguage_change, "language-change");
- DEFSYM (Qfile_notify, "file-notify");
+#endif
+
+#ifdef WINDOWSNT
+ DEFSYM (Qfile_w32notify, "file-w32notify");
#endif
#ifdef HAVE_DBUS
DEFSYM (Qdbus_event, "dbus-event");
#endif
+#ifdef HAVE_INOTIFY
+ DEFSYM (Qfile_inotify, "file-inotify");
+#endif /* HAVE_INOTIFY */
+
DEFSYM (QCenable, ":enable");
DEFSYM (QCvisible, ":visible");
DEFSYM (QChelp, ":help");
DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
DEFSYM (Qmenu_bar, "menu-bar");
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
-#endif
DEFSYM (Qabove_handle, "above-handle");
DEFSYM (Qhandle, "handle");
raw_keybuf = Fmake_vector (make_number (30), Qnil);
staticpro (&raw_keybuf);
- DEFSYM (Qextended_command_history, "extended-command-history");
- Fset (Qextended_command_history, Qnil);
+ DEFSYM (Qcommand_execute, "command-execute");
accent_key_syms = Qnil;
staticpro (&accent_key_syms);
defsubr (&Sread_key_sequence);
defsubr (&Sread_key_sequence_vector);
defsubr (&Srecursive_edit);
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
defsubr (&Strack_mouse);
-#endif
defsubr (&Sinput_pending_p);
- defsubr (&Scommand_execute);
defsubr (&Srecent_keys);
defsubr (&Sthis_command_keys);
defsubr (&Sthis_command_keys_vector);
to count as a drag. */);
double_click_fuzz = 3;
- DEFVAR_BOOL ("inhibit-local-menu-bar-menus", inhibit_local_menu_bar_menus,
- doc: /* Non-nil means inhibit local map menu bar menus. */);
- inhibit_local_menu_bar_menus = 0;
-
DEFVAR_INT ("num-input-keys", num_input_keys,
doc: /* Number of complete key sequences read as input so far.
This includes key sequences read from keyboard macros.
and its return value (a key sequence) is used.
The events that come from bindings in `input-decode-map' are not
-themselves looked up in `input-decode-map'.
-
-This variable is keyboard-local. */);
+themselves looked up in `input-decode-map'. */);
DEFVAR_LISP ("function-key-map", Vfunction_key_map,
doc: /* The parent keymap of all `local-function-key-map' instances.
DEFVAR_LISP ("key-translation-map", Vkey_translation_map,
doc: /* Keymap of key translations that can override keymaps.
-This keymap works like `function-key-map', but comes after that,
-and its non-prefix bindings override ordinary bindings.
-Another difference is that it is global rather than keyboard-local. */);
+This keymap works like `input-decode-map', but comes after `function-key-map'.
+Another difference is that it is global rather than terminal-local. */);
Vkey_translation_map = Fmake_sparse_keymap (Qnil);
DEFVAR_LISP ("deferred-action-list", Vdeferred_action_list,
Vsaved_region_selection,
doc: /* Contents of active region prior to buffer modification.
If `select-active-regions' is non-nil, Emacs sets this to the
-text in the region before modifying the buffer. The next
-`deactivate-mark' call uses this to set the window selection. */);
+text in the region before modifying the buffer. The next call to
+the function `deactivate-mark' uses this to set the window selection. */);
Vsaved_region_selection = Qnil;
DEFVAR_LISP ("selection-inhibit-update-commands",
"dbus-handle-event");
#endif
+#ifdef HAVE_INOTIFY
+ /* Define a special event which is raised for inotify callback
+ functions. */
+ initial_define_lispy_key (Vspecial_event_map, "file-inotify",
+ "inotify-handle-event");
+#endif /* HAVE_INOTIFY */
+
initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
"ignore");
#if defined (WINDOWSNT)
initial_define_lispy_key (Vspecial_event_map, "language-change",
"ignore");
- initial_define_lispy_key (Vspecial_event_map, "file-notify",
- "w32notify-handlde-event");
+ initial_define_lispy_key (Vspecial_event_map, "file-w32notify",
+ "w32notify-handle-event");
#endif
}
{
if (event == kbd_buffer + KBD_BUFFER_SIZE)
event = kbd_buffer;
+ /* These two special event types has no Lisp_Objects to mark. */
if (event->kind != SELECTION_REQUEST_EVENT
&& event->kind != SELECTION_CLEAR_EVENT)
{
mark_object (event->x);
mark_object (event->y);
+ mark_object (event->frame_or_window);
+ mark_object (event->arg);
}
- mark_object (event->frame_or_window);
- mark_object (event->arg);
}
}
}