/* Keyboard and mouse input; editor command loop.
-Copyright (C) 1985-1989, 1993-1997, 1999-2013 Free Software Foundation,
-Inc.
+Copyright (C) 1985-1989, 1993-1997, 1999-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include "sysstdio.h"
+#include <sys/stat.h>
#include "lisp.h"
#include "termchar.h"
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
+#include <gc.h> /* for GC_collect_a_little */
+
/* Variables for blockinput.h: */
/* Positive if interrupt input is blocked right now. */
Lisp_Object Qundefined;
static Lisp_Object Qtimer_event_handler;
-/* read_key_sequence stores here the command definition of the
+/* `read_key_sequence' stores here the command definition of the
key sequence that it reads. */
static Lisp_Object read_key_sequence_cmd;
static Lisp_Object read_key_sequence_remapped;
/* Symbols to use for parts of windows. */
Lisp_Object Qmode_line;
Lisp_Object Qvertical_line;
+Lisp_Object Qright_divider, Qbottom_divider;
static Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
static void recursive_edit_unwind (Lisp_Object buffer);
static Lisp_Object command_loop (void);
static Lisp_Object Qcommand_execute;
-struct timespec timer_check (void);
static void echo_now (void);
static ptrdiff_t echo_length (void);
/* Nonzero while interrupts are temporarily deferred during redisplay. */
bool interrupts_deferred;
-/* If we support a window system, turn on the code to poll periodically
- to detect C-g. It isn't actually used when doing interrupt input. */
-#ifdef HAVE_WINDOW_SYSTEM
-#define POLL_FOR_INPUT
-#endif
-
/* The time when Emacs started being idle. */
static struct timespec timer_idleness_start_time;
static Lisp_Object make_lispy_focus_out (Lisp_Object);
#endif /* HAVE_WINDOW_SYSTEM */
static bool help_char_p (Lisp_Object);
-static void save_getcjmp (sys_jmp_buf);
-static void restore_getcjmp (sys_jmp_buf);
+static void save_getcjmp (sys_jmp_buf *);
+static void restore_getcjmp (sys_jmp_buf *);
static Lisp_Object apply_modifiers (int, Lisp_Object);
static void clear_event (struct input_event *);
static void restore_kboard_configuration (int);
Lisp_Object
recursive_edit_1 (void)
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
Lisp_Object val;
if (command_loop_level > 0)
if (STRINGP (val))
xsignal1 (Qerror, val);
- return unbind_to (count, Qnil);
+ dynwind_end ();
+ return Qnil;
}
/* When an auto-save happens, record the "time", and don't do again soon. */
\f
DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
doc: /* Invoke the editor command loop recursively.
-To get out of the recursive edit, a command can do `(throw 'exit nil)';
-that tells this function to return.
-Alternatively, `(throw 'exit t)' makes this function signal an error.
+To get out of the recursive edit, a command can throw to `exit' -- for
+instance `(throw 'exit nil)'.
+If you throw a value other than t, `recursive-edit' returns normally
+to the function that called it. Throwing a t value causes
+`recursive-edit' to quit, so that control returns to the command loop
+one level up.
+
This function is called by the editor initialization to begin editing. */)
(void)
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
Lisp_Object buffer;
/* If we enter while input is blocked, don't lock up here.
This may happen through the debugger during redisplay. */
- if (input_blocked_p ())
+ if (input_blocked_p ()) {
+ dynwind_end ();
return Qnil;
+ }
- command_loop_level++;
- update_mode_lines = 1;
-
- if (command_loop_level
+ if (command_loop_level >= 0
&& current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
buffer = Fcurrent_buffer ();
else
buffer = Qnil;
+ /* Don't do anything interesting between the increment and the
+ record_unwind_protect! Otherwise, we could get distracted and
+ never decrement the counter again. */
+ command_loop_level++;
+ update_mode_lines = 17;
+ record_unwind_protect (recursive_edit_unwind, buffer);
+
/* If we leave recursive_edit_1 below with a `throw' for instance,
like it is done in the splash screen display, we have to
make sure that we restore single_kboard as command_loop_1
would have done if it were left normally. */
if (command_loop_level > 0)
temporarily_switch_to_single_kboard (SELECTED_FRAME ());
- record_unwind_protect (recursive_edit_unwind, buffer);
recursive_edit_1 ();
- return unbind_to (count, Qnil);
+ dynwind_end ();
+ return Qnil;
}
void
Fset_buffer (buffer);
command_loop_level--;
- update_mode_lines = 1;
+ update_mode_lines = 18;
}
\f
void
cmd_error_internal (Lisp_Object data, const char *context)
{
- struct frame *sf = SELECTED_FRAME ();
-
/* The immediate context is not interesting for Quits,
since they are asynchronous. */
if (EQ (XCAR (data), Qquit))
call3 (Vcommand_error_function, data,
context ? build_string (context) : empty_unibyte_string,
Vsignaling_function);
+
+ Vsignaling_function = Qnil;
+}
+
+DEFUN ("command-error-default-function", Fcommand_error_default_function,
+ Scommand_error_default_function, 3, 3, 0,
+ doc: /* Produce default output for unhandled error message.
+Default value of `command-error-function'. */)
+ (Lisp_Object data, Lisp_Object context, Lisp_Object signal)
+{
+ struct frame *sf = SELECTED_FRAME ();
+
+ CHECK_STRING (context);
+
/* If the window system or terminal frame hasn't been initialized
yet, or we're not interactive, write the message to stderr and exit. */
- else if (!sf->glyphs_initialized_p
+ if (!sf->glyphs_initialized_p
/* The initial frame is a special non-displaying frame. It
will be current in daemon mode when there are no frames
to display, and in non-daemon mode before the real frame
|| noninteractive)
{
print_error_message (data, Qexternal_debugging_output,
- context, Vsignaling_function);
+ SSDATA (context), signal);
Fterpri (Qexternal_debugging_output);
Fkill_emacs (make_number (-1));
}
message_log_maybe_newline ();
bitch_at_user ();
- print_error_message (data, Qt, context, Vsignaling_function);
+ print_error_message (data, Qt, SSDATA (context), signal);
}
-
- Vsignaling_function = Qnil;
+ return Qnil;
}
static Lisp_Object command_loop_2 (Lisp_Object);
xsignal1 (Quser_error, build_string (msg));
}
-_Noreturn
+/* _Noreturn will be added to prototype by make-docfile. */
DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
doc: /* Exit from the innermost recursive edit or minibuffer. */)
(void)
user_error ("No recursive edit is in progress");
}
-_Noreturn
+/* _Noreturn will be added to prototype by make-docfile. */
DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
doc: /* Abort the command that requested this recursive edit or minibuffer input. */)
(void)
usage: (track-mouse BODY...) */)
(Lisp_Object args)
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
Lisp_Object val;
record_unwind_protect (tracking_off, do_mouse_tracking);
do_mouse_tracking = Qt;
val = Fprogn (args);
- return unbind_to (count, val);
+ dynwind_end ();
+ return val;
}
/* If mouse has moved on some frame, return one of those frames.
If ignore_mouse_drag_p is non-zero, ignore (implicit) mouse movement
after resizing the tool-bar window. */
-#if !defined HAVE_WINDOW_SYSTEM || defined USE_GTK || defined HAVE_NS
-static
-#endif
bool ignore_mouse_drag_p;
static struct frame *
static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
bool, bool, bool, bool);
-void safe_run_hooks (Lisp_Object);
static void adjust_point_for_property (ptrdiff_t, bool);
/* The last boundary auto-added to buffer-undo-list. */
{
/* Bind inhibit-quit to t so that C-g gets read in
rather than quitting back to the minibuffer. */
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
specbind (Qinhibit_quit, Qt);
sit_for (Vminibuffer_message_timeout, 0, 2);
message1 (0);
safe_run_hooks (Qecho_area_clear_hook);
- unbind_to (count, Qnil);
+ dynwind_end ();
/* If a C-g came in before, treat it as input now. */
if (!NILP (Vquit_flag))
Vthis_command_keys_shift_translated = Qnil;
/* Read next key sequence; i gets its length. */
- i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
+ i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
Qnil, 0, 1, 1, 0);
/* A filter may have run while we were reading the input. */
already_adjusted = 0;
if (NILP (Vthis_command))
- {
- /* nil means key is undefined. */
- Lisp_Object keys = Fvector (i, keybuf);
- keys = Fkey_description (keys, Qnil);
- bitch_at_user ();
- message_with_string ("%s is undefined", keys, 0);
- kset_defining_kbd_macro (current_kboard, Qnil);
- update_mode_lines = 1;
- /* If this is a down-mouse event, don't reset prefix-arg;
- pass it to the command run by the up event. */
- if (EVENT_HAS_PARAMETERS (last_command_event))
- {
- Lisp_Object breakdown
- = parse_modifiers (EVENT_HEAD (last_command_event));
- int modifiers = XINT (XCAR (XCDR (breakdown)));
- if (!(modifiers & down_modifier))
- kset_prefix_arg (current_kboard, Qnil);
- }
- else
- kset_prefix_arg (current_kboard, Qnil);
- }
+ /* nil means key is undefined. */
+ call0 (Qundefined);
else
{
/* Here for a command that isn't executed directly. */
#ifdef HAVE_WINDOW_SYSTEM
- ptrdiff_t scount = SPECPDL_INDEX ();
+ dynwind_begin ();
if (display_hourglass_p
&& NILP (Vexecuting_kbd_macro))
hourglass cursor anyway.
But don't cancel the hourglass within a macro
just because a command in the macro finishes. */
- if (NILP (Vexecuting_kbd_macro))
- unbind_to (scount, Qnil);
+ dynwind_end ();
#endif
}
kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg);
&& NILP (Fmemq (Vthis_command,
Vselection_inhibit_update_commands)))
{
- ptrdiff_t beg =
- XINT (Fmarker_position (BVAR (current_buffer, mark)));
- ptrdiff_t end = PT;
- if (beg < end)
- call2 (Qx_set_selection, QPRIMARY,
- make_buffer_string (beg, end, 0));
- else if (beg > end)
- call2 (Qx_set_selection, QPRIMARY,
- make_buffer_string (end, beg, 0));
- /* Don't set empty selections. */
+ Lisp_Object txt
+ = call1 (Fsymbol_value (Qregion_extract_function), Qnil);
+ if (XINT (Flength (txt)) > 0)
+ /* Don't set empty selections. */
+ call2 (Qx_set_selection, QPRIMARY, txt);
}
if (current_buffer != prev_buffer || MODIFF != prev_modiff)
cluster to prevent automatic composition. To recover
the automatic composition, we must update the
display. */
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 21;
if (!already_adjusted)
adjust_point_for_property (last_point_position,
MODIFF != prev_modiff);
menus. */
specbind (Qecho_keystrokes, make_number (0));
- i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
+ i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
Qnil, 0, 1, 1, 1);
unbind_to (count, Qnil);
than skip both boundaries. However, this code
also stops anywhere in a non-sticky text-property,
which breaks (e.g.) Org mode. */
- && (val = get_pos_property (make_number (end),
- Qinvisible, Qnil),
+ && (val = Fget_pos_property (make_number (end),
+ Qinvisible, Qnil),
TEXT_PROP_MEANS_INVISIBLE (val))
#endif
&& !NILP (val = get_char_property_and_overlay
}
while (beg > BEGV
#if 0
- && (val = get_pos_property (make_number (beg),
- Qinvisible, Qnil),
+ && (val = Fget_pos_property (make_number (beg),
+ Qinvisible, Qnil),
TEXT_PROP_MEANS_INVISIBLE (val))
#endif
&& !NILP (val = get_char_property_and_overlay
to the other end would mean moving backwards and thus
could lead to an infinite loop. */
;
- else if (val = get_pos_property (make_number (PT),
- Qinvisible, Qnil),
+ else if (val = Fget_pos_property (make_number (PT),
+ Qinvisible, Qnil),
TEXT_PROP_MEANS_INVISIBLE (val)
- && (val = get_pos_property
- (make_number (PT == beg ? end : beg),
- Qinvisible, Qnil),
+ && (val = (Fget_pos_property
+ (make_number (PT == beg ? end : beg),
+ Qinvisible, Qnil)),
!TEXT_PROP_MEANS_INVISIBLE (val)))
(check_composition = check_display = 1,
SET_PT (PT == beg ? end : beg));
/* FIXME: our `internal_condition_case' does not provide any way to pass data
to its body or to its handlers other than via globals such as
dynamically-bound variables ;-) */
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
specbind (Qinhibit_quit, hook);
run_hook_with_args (1, &hook, safe_run_hook_funcall);
- unbind_to (count, Qnil);
+ dynwind_end ();
}
\f
static struct atimer *poll_timer;
-/* Poll for input, so that we catch a C-g if it comes in. This
- function is called from x_make_frame_visible, see comment
- there. */
-
+/* Poll for input, so that we catch a C-g if it comes in. */
void
poll_for_input_1 (void)
{
been turned off in process.c. */
turn_on_atimers (1);
- /* If poll timer doesn't exist, are we need one with
+ /* If poll timer doesn't exist, or we need one with
a different interval, start a new one. */
if (poll_timer == NULL
|| poll_timer->interval.tv_sec != polling_period)
\f
/* Apply the control modifier to CHARACTER. */
-#ifndef WINDOWSNT
-static
-#endif
int
make_ctrl_char (int c)
{
/* Save the upper bits here. */
int upper = c & ~0177;
- if (! ASCII_BYTE_P (c))
+ if (! ASCII_CHAR_P (c))
return c |= ctrl_modifier;
c &= 0177;
\f
-/* Input of single characters from keyboard */
+/* Input of single characters from keyboard. */
static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
struct timespec *end_time);
static Lisp_Object
read_event_from_main_queue (struct timespec *end_time,
- sys_jmp_buf local_getcjmp,
+ sys_jmp_buf *local_getcjmp,
bool *used_mouse_menu)
{
Lisp_Object c = Qnil;
- sys_jmp_buf save_jump;
+ sys_jmp_buf *save_jump = xmalloc (sizeof *save_jump);
KBOARD *kb IF_LINT (= NULL);
start:
to tty input. */
static Lisp_Object
read_decoded_event_from_main_queue (struct timespec *end_time,
- sys_jmp_buf local_getcjmp,
+ sys_jmp_buf *local_getcjmp,
Lisp_Object prev_event,
bool *used_mouse_menu)
{
#define MAX_ENCODED_BYTES 16
+#ifndef WINDOWSNT
Lisp_Object events[MAX_ENCODED_BYTES];
int n = 0;
+#endif
while (true)
{
Lisp_Object nextevt
}
}
+static bool
+echo_keystrokes_p (void)
+{
+ return (FLOATP (Vecho_keystrokes) ? XFLOAT_DATA (Vecho_keystrokes) > 0.0
+ : INTEGERP (Vecho_keystrokes) ? XINT (Vecho_keystrokes) > 0 : false);
+}
+
/* Read a character from the keyboard; call the redisplay if needed. */
/* commandflag 0 means do not autosave, but do redisplay.
-1 means do not redisplay, but do autosave.
-2 means do neither.
1 means do both. */
-/* The arguments MAP is for menu prompting. MAP is a keymap.
+/* The argument MAP is a keymap for menu prompting.
PREV_EVENT is the previous input event, or nil if we are reading
the first event of a key sequence (or not reading a key sequence).
Value is t if we showed a menu and the user rejected it. */
+struct read_char_state
+{
+ int commandflag;
+ Lisp_Object map;
+ Lisp_Object prev_event;
+ bool *used_mouse_menu;
+ struct timespec *end_time;
+ Lisp_Object c;
+ ptrdiff_t jmpcount;
+ sys_jmp_buf *local_getcjmp;
+ sys_jmp_buf *save_jump;
+ Lisp_Object previous_echo_area_message;
+ Lisp_Object also_record;
+ bool reread;
+ bool polling_stopped_here;
+ struct kboard *orig_kboard;
+};
+
+static Lisp_Object read_char_1 (bool, volatile struct read_char_state *);
+
+/* {{coccinelle:skip_start}} */
Lisp_Object
read_char (int commandflag, Lisp_Object map,
Lisp_Object prev_event,
bool *used_mouse_menu, struct timespec *end_time)
{
- Lisp_Object c;
- ptrdiff_t jmpcount;
- sys_jmp_buf local_getcjmp;
- sys_jmp_buf save_jump;
- Lisp_Object tem, save;
- volatile Lisp_Object previous_echo_area_message;
- volatile Lisp_Object also_record;
- volatile bool reread;
- struct gcpro gcpro1, gcpro2;
- bool volatile polling_stopped_here = 0;
- struct kboard *orig_kboard = current_kboard;
+ volatile struct read_char_state *state = xmalloc (sizeof *state);
+
+ state->commandflag = commandflag;
+ state->map = map;
+ state->prev_event = prev_event;
+ state->used_mouse_menu = used_mouse_menu;
+ state->end_time = end_time;
+ state->c = Qnil;
+ state->local_getcjmp = xmalloc (sizeof (*state->local_getcjmp));
+ state->save_jump = xmalloc (sizeof (*state->save_jump));
+ state->previous_echo_area_message = Qnil;
+ state->also_record = Qnil;
+ state->reread = false;
+ state->polling_stopped_here = false;
+ state->orig_kboard = current_kboard;
- also_record = Qnil;
+ /* Make a longjmp point for quits to use, but don't alter getcjmp just yet.
+ We will do that below, temporarily for short sections of code,
+ when appropriate. local_getcjmp must be in effect
+ around any call to sit_for or kbd_buffer_get_event;
+ it *must not* be in effect when we call redisplay. */
-#if 0 /* This was commented out as part of fixing echo for C-u left. */
- before_command_key_count = this_command_key_count;
- before_command_echo_length = echo_length ();
-#endif
- c = Qnil;
- previous_echo_area_message = Qnil;
+ state->jmpcount = SPECPDL_INDEX ();
+ if (sys_setjmp (*state->local_getcjmp))
+ {
+ /* Handle quits while reading the keyboard. */
+ /* We must have saved the outer value of getcjmp here,
+ so restore it now. */
+ restore_getcjmp (state->save_jump);
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ unbind_to (state->jmpcount, Qnil);
+ XSETINT (state->c, quit_char);
+ internal_last_event_frame = selected_frame;
+ Vlast_event_frame = internal_last_event_frame;
+ /* If we report the quit char as an event,
+ don't do so more than once. */
+ if (!NILP (Vinhibit_quit))
+ Vquit_flag = Qnil;
+
+ {
+ KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
+ if (kb != current_kboard)
+ {
+ Lisp_Object last = KVAR (kb, kbd_queue);
+ /* We shouldn't get here if we were in single-kboard mode! */
+ if (single_kboard)
+ emacs_abort ();
+ if (CONSP (last))
+ {
+ while (CONSP (XCDR (last)))
+ last = XCDR (last);
+ if (!NILP (XCDR (last)))
+ emacs_abort ();
+ }
+ if (!CONSP (last))
+ kset_kbd_queue (kb, list1 (state->c));
+ else
+ XSETCDR (last, list1 (state->c));
+ kb->kbd_queue_has_data = 1;
+ current_kboard = kb;
+ /* This is going to exit from read_char
+ so we had better get rid of this frame's stuff. */
+ UNGCPRO;
+ return make_number (-2); /* wrong_kboard_jmpbuf */
+ }
+ }
+ return read_char_1 (true, state);
+ }
+
+ return read_char_1 (false, state);
+}
- GCPRO2 (c, previous_echo_area_message);
+static Lisp_Object
+read_char_1 (bool jump, volatile struct read_char_state *state)
+{
+#define commandflag state->commandflag
+#define map state->map
+#define prev_event state->prev_event
+#define used_mouse_menu state->used_mouse_menu
+#define end_time state->end_time
+#define c state->c
+#define jmpcount state->jmpcount
+#define local_getcjmp state->local_getcjmp
+#define save_jump state->save_jump
+#define previous_echo_area_message state->previous_echo_area_message
+#define also_record state->also_record
+#define reread state->reread
+#define polling_stopped_here state->polling_stopped_here
+#define orig_kboard state->orig_kboard
+ Lisp_Object tem, save;
+
+ if (jump)
+ goto non_reread;
retry:
- reread = 0;
if (CONSP (Vunread_post_input_method_events))
{
c = XCAR (Vunread_post_input_method_events);
&& NILP (XCDR (c)))
c = XCAR (c);
- reread = 1;
+ reread = true;
goto reread_first;
}
+ else
+ reread = false;
+
if (CONSP (Vunread_command_events))
{
c = XCAR (Vunread_command_events);
Vunread_command_events = XCDR (Vunread_command_events);
- reread = 1;
-
/* Undo what sit-for did when it unread additional keys
inside universal-argument. */
- if (CONSP (c)
- && EQ (XCAR (c), Qt))
- {
- reread = 0;
- c = XCDR (c);
- }
+ if (CONSP (c) && EQ (XCAR (c), Qt))
+ c = XCDR (c);
+ else
+ reread = true;
/* Undo what read_char_x_menu_prompt did when it unread
additional keys returned by Fx_popup_menu. */
&& (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c)))
&& NILP (XCDR (c)))
c = XCAR (c);
- reread = 1;
+ reread = true;
goto reread_for_input_method;
}
goto exit;
}
- /* Make a longjmp point for quits to use, but don't alter getcjmp just yet.
- We will do that below, temporarily for short sections of code,
- when appropriate. local_getcjmp must be in effect
- around any call to sit_for or kbd_buffer_get_event;
- it *must not* be in effect when we call redisplay. */
-
- jmpcount = SPECPDL_INDEX ();
- if (sys_setjmp (local_getcjmp))
- {
- /* Handle quits while reading the keyboard. */
- /* We must have saved the outer value of getcjmp here,
- so restore it now. */
- restore_getcjmp (save_jump);
- unbind_to (jmpcount, Qnil);
- XSETINT (c, quit_char);
- internal_last_event_frame = selected_frame;
- Vlast_event_frame = internal_last_event_frame;
- /* If we report the quit char as an event,
- don't do so more than once. */
- if (!NILP (Vinhibit_quit))
- Vquit_flag = Qnil;
-
- {
- KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
- if (kb != current_kboard)
- {
- Lisp_Object last = KVAR (kb, kbd_queue);
- /* We shouldn't get here if we were in single-kboard mode! */
- if (single_kboard)
- emacs_abort ();
- if (CONSP (last))
- {
- while (CONSP (XCDR (last)))
- last = XCDR (last);
- if (!NILP (XCDR (last)))
- emacs_abort ();
- }
- if (!CONSP (last))
- kset_kbd_queue (kb, list1 (c));
- else
- XSETCDR (last, list1 (c));
- kb->kbd_queue_has_data = 1;
- current_kboard = kb;
- /* This is going to exit from read_char
- so we had better get rid of this frame's stuff. */
- UNGCPRO;
- return make_number (-2); /* wrong_kboard_jmpbuf */
- }
- }
- goto non_reread;
- }
-
/* Start idle timers if no time limit is supplied. We don't do it
if a time limit is supplied to avoid an infinite recursion in the
situation where an idle timer calls `sit-for'. */
&& !current_kboard->immediate_echo
&& this_command_key_count > 0
&& ! noninteractive
- && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes))
+ && echo_keystrokes_p ()
&& (/* No message. */
NILP (echo_area_buffer[0])
/* Or empty message. */
/* If there is still no input available, ask for GC. */
if (!detect_input_pending_run_timers (0))
- maybe_gc ();
+ GC_collect_a_little ();
}
/* Notify the caller if an autosave hook, or a timer, sentinel or
{
c = XCAR (Vunread_command_events);
Vunread_command_events = XCDR (Vunread_command_events);
+
+ if (CONSP (c) && EQ (XCAR (c), Qt))
+ c = XCDR (c);
+ else
+ reread = true;
}
/* Read something from current KBOARD's side queue, if possible. */
{
c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
prev_event, used_mouse_menu);
- if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
- goto exit;
+ if (NILP (c) && end_time
+ && timespec_cmp (*end_time, current_timespec ()) <= 0)
+ {
+ goto exit;
+ }
+
if (EQ (c, make_number (-2)))
{
/* This is going to exit from read_char
ptrdiff_t key_count;
bool key_count_reset;
struct gcpro gcpro1;
- ptrdiff_t count = SPECPDL_INDEX ();
/* Save the echo status. */
bool saved_immediate_echo = current_kboard->immediate_echo;
Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
ptrdiff_t saved_echo_after_prompt = current_kboard->echo_after_prompt;
+ dynwind_begin ();
+
#if 0
if (before_command_restore_flag)
{
/* Call the input method. */
tem = call1 (Vinput_method_function, c);
- tem = unbind_to (count, tem);
+ dynwind_end ();
/* Restore the saved echoing state
and this_command_keys state. */
{
/* Don't echo mouse motion events. */
- if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes))
+ if (echo_keystrokes_p ()
&& ! (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
{
/* Process the help character specially if enabled. */
if (!NILP (Vhelp_form) && help_char_p (c))
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
help_form_saved_window_configs
= Fcons (Fcurrent_window_configuration (Qnil),
}
while (BUFFERP (c));
/* Remove the help from the frame. */
- unbind_to (count, Qnil);
+ dynwind_end ();
redisplay ();
if (EQ (c, make_number (040)))
exit:
RESUME_POLLING;
RETURN_UNGCPRO (c);
-}
-
-#ifdef HAVE_MENUS
+#undef commandflag
+#undef map
+#undef prev_event
+#undef used_mouse_menu
+#undef end_time
+#undef c
+#undef jmpcount
+#undef local_getcjmp
+#undef save_jump
+#undef previous_echo_area_message
+#undef also_record
+#undef reread
+#undef polling_stopped_here
+#undef orig_kboard
+}
+/* {{coccinelle:skip_end}} */
/* Record a key that came from a mouse menu.
Record it for echoing, for this-command-keys, and so on. */
#endif
/* Don't echo mouse motion events. */
- if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes)))
+ if (echo_keystrokes_p ())
{
echo_char (c);
/* Record this character as part of the current key. */
add_command_key (c);
- /* Re-reading in the middle of a command */
+ /* Re-reading in the middle of a command. */
last_input_event = c;
num_input_events++;
}
-#endif /* HAVE_MENUS */
-
/* Return true if should recognize C as "the help character". */
static bool
See read_process_output. */
static void
-save_getcjmp (sys_jmp_buf temp)
+save_getcjmp (sys_jmp_buf *temp)
{
- memcpy (temp, getcjmp, sizeof getcjmp);
+ memcpy (*temp, getcjmp, sizeof getcjmp);
}
static void
-restore_getcjmp (sys_jmp_buf temp)
+restore_getcjmp (sys_jmp_buf *temp)
{
- memcpy (getcjmp, temp, sizeof getcjmp);
+ memcpy (getcjmp, *temp, sizeof getcjmp);
}
\f
/* Low level keyboard/mouse input.
*kbd_store_ptr = *event;
++kbd_store_ptr;
#ifdef subprocesses
- if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE/2 && ! kbd_on_hold_p ())
+ if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2
+ && ! kbd_on_hold_p ())
{
/* Don't read keyboard input until we have processed kbd_buffer.
This happens when pasting text longer than KBD_BUFFER_SIZE/2. */
}
#endif /* subprocesses */
-#ifndef HAVE_DBUS /* We want to read D-Bus events in batch mode. */
+#if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY
if (noninteractive
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
*kbp = current_kboard;
return obj;
}
-#endif /* ! HAVE_DBUS */
+#endif /* !defined HAVE_DBUS && !defined USE_FILE_NOTIFY */
/* Wait until there is input available. */
for (;;)
if (! (VECTORP (timer) && ASIZE (timer) == 9))
return 0;
- vector = XVECTOR (timer)->u.contents;
+ vector = XVECTOR (timer)->contents;
if (! NILP (vector[0]))
return 0;
{
if (NILP (AREF (chosen_timer, 0)))
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
Lisp_Object old_deactivate_mark = Vdeactivate_mark;
/* Mark the timer as triggered to prevent problems if the lisp
call1 (Qtimer_event_handler, chosen_timer);
Vdeactivate_mark = old_deactivate_mark;
timers_run++;
- unbind_to (count, Qnil);
+ dynwind_end ();
/* Since we have handled the event,
we don't need to tell the caller to wake up and do it. */
/* It's a click in window WINDOW at frame coordinates (X,Y) */
struct window *w = XWINDOW (window);
Lisp_Object string_info = Qnil;
- ptrdiff_t textpos = -1;
+ ptrdiff_t textpos = 0;
int col = -1, row = -1;
int dx = -1, dy = -1;
int width = -1, height = -1;
&object, &dx, &dy, &width, &height);
if (STRINGP (string))
string_info = Fcons (string, make_number (charpos));
- textpos = (w == XWINDOW (selected_window)
- && current_buffer == XBUFFER (w->contents))
- ? PT : marker_position (w->pointm);
+ textpos = -1;
xret = wx;
yret = wy;
dy = yret = wy;
}
/* Nothing special for part == ON_SCROLL_BAR. */
+ else if (part == ON_RIGHT_DIVIDER)
+ {
+ posn = Qright_divider;
+ width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ dx = xret = wx;
+ dy = yret = wy;
+ }
+ else if (part == ON_BOTTOM_DIVIDER)
+ {
+ posn = Qbottom_divider;
+ width = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ dx = xret = wx;
+ dy = yret = wy;
+ }
/* For clicks in the text area, fringes, or margins, call
buffer_posn_from_coords to extract TEXTPOS, the buffer
position nearest to the click. */
- if (textpos < 0)
+ if (!textpos)
{
Lisp_Object string2, object2 = Qnil;
struct display_pos p;
}
#endif
- /* Object info */
+ /* Object info. */
extra_info
= list3 (object,
Fcons (make_number (dx), make_number (dy)),
Fcons (make_number (width), make_number (height)));
- /* String info */
+ /* String info. */
extra_info = Fcons (string_info,
- Fcons (make_number (textpos),
+ Fcons (textpos < 0 ? Qnil : make_number (textpos),
Fcons (Fcons (make_number (col),
make_number (row)),
extra_info)));
case NON_ASCII_KEYSTROKE_EVENT:
button_down_time = 0;
- for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++)
+ for (i = 0; i < ARRAYELTS (lispy_accent_codes); i++)
if (event->code == lispy_accent_codes[i])
return modify_event_symbol (i,
event->modifiers,
Qfunction_key, Qnil,
lispy_accent_keys, &accent_key_syms,
- (sizeof (lispy_accent_keys)
- / sizeof (lispy_accent_keys[0])));
+ ARRAYELTS (lispy_accent_keys));
#if 0
#ifdef XK_kana_A
event->modifiers & ~shift_modifier,
Qfunction_key, Qnil,
lispy_kana_keys, &func_key_syms,
- (sizeof (lispy_kana_keys)
- / sizeof (lispy_kana_keys[0])));
+ ARRAYELTS (lispy_kana_keys));
#endif /* XK_kana_A */
#endif /* 0 */
event->modifiers,
Qfunction_key, Qnil,
iso_lispy_function_keys, &func_key_syms,
- (sizeof (iso_lispy_function_keys)
- / sizeof (iso_lispy_function_keys[0])));
+ ARRAYELTS (iso_lispy_function_keys));
#endif
/* Handle system-specific or unknown keysyms. */
if (event->code & (1 << 28)
|| event->code - FUNCTION_KEY_OFFSET < 0
|| (event->code - FUNCTION_KEY_OFFSET
- >= sizeof lispy_function_keys / sizeof *lispy_function_keys)
+ >= ARRAYELTS (lispy_function_keys))
|| !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
{
/* We need to use an alist rather than a vector as the cache
event->modifiers,
Qfunction_key, Qnil,
lispy_function_keys, &func_key_syms,
- (sizeof (lispy_function_keys)
- / sizeof (lispy_function_keys[0])));
+ ARRAYELTS (lispy_function_keys));
#ifdef HAVE_NTGUI
case MULTIMEDIA_KEY_EVENT:
- if (event->code < (sizeof (lispy_multimedia_keys)
- / sizeof (lispy_multimedia_keys[0]))
+ if (event->code < ARRAYELTS (lispy_multimedia_keys)
&& event->code > 0 && lispy_multimedia_keys[event->code])
{
return modify_event_symbol (event->code, event->modifiers,
Qfunction_key, Qnil,
lispy_multimedia_keys, &func_key_syms,
- (sizeof (lispy_multimedia_keys)
- / sizeof (lispy_multimedia_keys[0])));
+ ARRAYELTS (lispy_multimedia_keys));
}
return Qnil;
#endif
/* A mouse click. Figure out where it is, decide whether it's
a press, click or drag, and build the appropriate structure. */
case MOUSE_CLICK_EVENT:
+#ifdef HAVE_GPM
+ case GPM_CLICK_EVENT:
+#endif
#ifndef USE_TOOLKIT_SCROLL_BARS
case SCROLL_BAR_CLICK_EVENT:
#endif
position = Qnil;
/* Build the position as appropriate for this mouse click. */
- if (event->kind == MOUSE_CLICK_EVENT)
+ if (event->kind == MOUSE_CLICK_EVENT
+#ifdef HAVE_GPM
+ || event->kind == GPM_CLICK_EVENT
+#endif
+ )
{
struct frame *f = XFRAME (event->frame_or_window);
int row, column;
case CONFIG_CHANGED_EVENT:
return list3 (Qconfig_changed_event,
event->arg, event->frame_or_window);
-#ifdef HAVE_GPM
- case GPM_CLICK_EVENT:
- {
- struct frame *f = XFRAME (event->frame_or_window);
- Lisp_Object head, position;
- Lisp_Object *start_pos_ptr;
- Lisp_Object start_pos;
- int button = event->code;
-
- if (button >= ASIZE (button_down_location))
- {
- ptrdiff_t incr = button - ASIZE (button_down_location) + 1;
- button_down_location = larger_vector (button_down_location,
- incr, -1);
- mouse_syms = larger_vector (mouse_syms, incr, -1);
- }
-
- start_pos_ptr = aref_addr (button_down_location, button);
- start_pos = *start_pos_ptr;
-
- position = make_lispy_position (f, event->x, event->y,
- event->timestamp);
-
- if (event->modifiers & down_modifier)
- *start_pos_ptr = Fcopy_alist (position);
- else if (event->modifiers & (up_modifier | drag_modifier))
- {
- if (!CONSP (start_pos))
- return Qnil;
- event->modifiers &= ~up_modifier;
- }
-
- head = modify_event_symbol (button,
- event->modifiers,
- Qmouse_click, Vlispy_mouse_stem,
- NULL,
- &mouse_syms,
- ASIZE (mouse_syms));
-
- if (event->modifiers & drag_modifier)
- return list3 (head, start_pos, position);
- else if (event->modifiers & double_modifier)
- return list3 (head, position, make_number (2));
- else if (event->modifiers & triple_modifier)
- return list3 (head, position, make_number (3));
- else
- return list2 (head, position);
- }
-#endif /* HAVE_GPM */
/* The 'kind' field of the event is something we don't recognize. */
default:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, "alt", "super", "hyper", "shift", "control", "meta"
};
-#define NUM_MOD_NAMES (sizeof (modifier_names) / sizeof (modifier_names[0]))
+#define NUM_MOD_NAMES ARRAYELTS (modifier_names)
static Lisp_Object modifier_symbols;
}
}
+ /* If there was no error, make sure the pointer
+ is visible for all frames on this terminal. */
+ if (nr >= 0)
+ {
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_TERMINAL (f) == t)
+ frame_make_pointer_visible (f);
+ }
+ }
+
if (hold_quit.kind != NO_EVENT)
kbd_buffer_store_event (&hold_quit);
}
if (err && !nread)
nread = -1;
- frame_make_pointer_visible ();
-
return nread;
}
/* End critical section.
If doing signal-driven input, and a signal came in when input was
- blocked, reinvoke the signal handler now to deal with it. */
+ blocked, reinvoke the signal handler now to deal with it.
+
+ It will also process queued input, if it was not read before.
+ When a longer code sequence does not use block/unblock input
+ at all, the whole input gathered up to the next call to
+ unblock_input will be processed inside that call. */
void
unblock_input (void)
}
\f
-static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*);
+static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void *);
static Lisp_Object menu_bar_one_keymap_changed_items;
/* These variables hold the vector under construction within
static int menu_bar_items_index;
-static const char* separator_names[] = {
+static const char *separator_names[] = {
"space",
"no-line",
"single-line",
{
int i = menu_bar_items_index;
if (i + 4 > ASIZE (menu_bar_items_vector))
- menu_bar_items_vector =
- larger_vector (menu_bar_items_vector, 4, -1);
+ menu_bar_items_vector
+ = larger_vector (menu_bar_items_vector, 4, -1);
/* Add this item. */
ASET (menu_bar_items_vector, i, Qnil); i++;
ASET (menu_bar_items_vector, i, Qnil); i++;
Lisp_Object
menu_item_eval_property (Lisp_Object sexpr)
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
Lisp_Object val;
specbind (Qinhibit_redisplay, Qt);
val = internal_condition_case_1 (eval_dyn, sexpr, Qerror,
menu_item_eval_property_1);
- return unbind_to (count, val);
+ dynwind_end ();
+ return val;
}
/* This function parses a menu item and leaves the result in the
/* Function prototypes. */
static void init_tool_bar_items (Lisp_Object);
-static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*);
+static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object,
+ void *);
static bool parse_tool_bar_item (Lisp_Object, Lisp_Object);
static void append_tool_bar_item (void);
discard any previously made item. */
for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)
{
- Lisp_Object *v = XVECTOR (tool_bar_items_vector)->u.contents + i;
+ Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;
if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
{
const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
ptrdiff_t max_lbl =
2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
- char *buf = xmalloc (max_lbl + 1);
+ char *buf = xmalloc_atomic (max_lbl + 1);
Lisp_Object new_lbl;
ptrdiff_t caption_len = strlen (capt);
/* Append entries from tool_bar_item_properties to the end of
tool_bar_items_vector. */
vcopy (tool_bar_items_vector, ntool_bar_items,
- XVECTOR (tool_bar_item_properties)->u.contents, TOOL_BAR_ITEM_NSLOTS);
+ XVECTOR (tool_bar_item_properties)->contents, TOOL_BAR_ITEM_NSLOTS);
ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
}
if (! menu_prompting)
return Qnil;
-#ifdef HAVE_MENUS
/* If we got to this point via a mouse click,
use a real menu for mouse selection. */
if (EVENT_HAS_PARAMETERS (prev_event)
*used_mouse_menu = 1;
return value;
}
-#endif /* HAVE_MENUS */
return Qnil ;
}
bool dont_downcase_last, bool can_return_switch_frame,
bool fix_current_buffer, bool prevent_redisplay)
{
- ptrdiff_t count = SPECPDL_INDEX ();
-
/* How many keys there are in the current key sequence. */
int t;
struct gcpro gcpro1;
+ dynwind_begin ();
+
GCPRO1 (fake_prefixed_keys);
raw_keybuf_count = 0;
echo_now ();
}
else if (cursor_in_echo_area
- && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes)))
+ && echo_keystrokes_p ())
/* This doesn't put in a dash if the echo buffer is empty, so
you don't always see a dash hanging out in the minibuffer. */
echo_dash ();
{
key = keybuf[t];
add_command_key (key);
- if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes))
+ if (echo_keystrokes_p ()
&& current_kboard->immediate_echo)
{
echo_add_key (key);
Just return -1. */
if (EQ (key, Qt))
{
- unbind_to (count, Qnil);
+ dynwind_end ();
UNGCPRO;
return -1;
}
first_unbound = min (t, first_unbound);
head = EVENT_HEAD (key);
- if (help_char_p (head) && t > 0)
- {
- read_key_sequence_cmd = Vprefix_help_command;
- keybuf[t++] = key;
- last_nonmenu_event = key;
- /* The Microsoft C compiler can't handle the goto that
- would go here. */
- dummyflag = 1;
- break;
- }
if (SYMBOLP (head))
{
goto replay_sequence;
}
+
+ if (NILP (current_binding)
+ && help_char_p (EVENT_HEAD (key)) && t > 1)
+ {
+ read_key_sequence_cmd = Vprefix_help_command;
+ /* The Microsoft C compiler can't handle the goto that
+ would go here. */
+ dummyflag = 1;
+ break;
+ }
+
/* If KEY is not defined in any of the keymaps,
and cannot be part of a function key or translation,
and is a shifted function key,
: Qnil;
unread_switch_frame = delayed_switch_frame;
- unbind_to (count, Qnil);
+ dynwind_end ();
/* Don't downcase the last character if the caller says don't.
Don't downcase it if the result is undefined, either. */
Better ideas? */
for (; t < mock_input; t++)
{
- if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
- && NILP (Fzerop (Vecho_keystrokes)))
+ if (echo_keystrokes_p ())
echo_char (keybuf[t]);
add_command_key (keybuf[t]);
}
Lisp_Object keybuf[30];
register int i;
struct gcpro gcpro1;
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
if (!NILP (prompt))
CHECK_STRING (prompt);
memset (keybuf, 0, sizeof keybuf);
GCPRO1 (keybuf[0]);
- gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0]));
+ gcpro1.nvars = ARRAYELTS (keybuf);
if (NILP (continue_echo))
{
cancel_hourglass ();
#endif
- i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
+ i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), 0, 0);
QUIT;
}
UNGCPRO;
- return unbind_to (count,
- ((allow_string ? make_event_array : Fvector)
- (i, keybuf)));
+ Lisp_Object tem0 = ((allow_string ? make_event_array : Fvector) (i, keybuf));
+ dynwind_end ();
+ return tem0;
}
DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0,
doc: /* Return vector of last 300 events, not counting those from keyboard macros. */)
(void)
{
- Lisp_Object *keys = XVECTOR (recent_keys)->u.contents;
+ Lisp_Object *keys = XVECTOR (recent_keys)->contents;
Lisp_Object val;
if (total_keys < NUM_RECENT_KEYS)
(void)
{
return make_event_array (this_command_key_count,
- XVECTOR (this_command_keys)->u.contents);
+ XVECTOR (this_command_keys)->contents);
}
DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0,
(void)
{
return Fvector (this_command_key_count,
- XVECTOR (this_command_keys)->u.contents);
+ XVECTOR (this_command_keys)->contents);
}
DEFUN ("this-single-command-keys", Fthis_single_command_keys,
{
return Fvector (this_command_key_count
- this_single_command_key_start,
- (XVECTOR (this_command_keys)->u.contents
+ (XVECTOR (this_command_keys)->contents
+ this_single_command_key_start));
}
The value is always a vector. */)
(void)
{
- return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->u.contents);
+ return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents);
}
DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
"FOpen dribble file: ",
doc: /* Start writing all keyboard characters to a dribble file called FILE.
If FILE is nil, close any open dribble file.
-The file will be closed when Emacs exits. */)
+The file will be closed when Emacs exits.
+
+Be aware that this records ALL characters you type!
+This may include sensitive information such as passwords. */)
(Lisp_Object file)
{
if (dribble)
}
if (!NILP (file))
{
+ int fd;
+ Lisp_Object encfile;
+
file = Fexpand_file_name (file, Qnil);
- dribble = emacs_fopen (SSDATA (file), "w");
+ encfile = ENCODE_FILE (file);
+ fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (fd < 0 && errno == EEXIST && unlink (SSDATA (encfile)) == 0)
+ fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600);
+ dribble = fd < 0 ? 0 : fdopen (fd, "w");
if (dribble == 0)
report_file_error ("Opening dribble", file);
}
On such systems, Emacs starts a subshell instead of suspending. */)
(Lisp_Object stuffstring)
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
int old_height, old_width;
int width, height;
struct gcpro gcpro1;
sys_subshell ();
else
sys_suspend ();
- unbind_to (count, Qnil);
+ dynwind_end ();
/* Check if terminal/window size has changed.
Note that this is not useful when we are running directly
with a window system; but suspend should be disabled in that case. */
get_tty_size (fileno (CURTTY ()->input), &width, &height);
if (width != old_width || height != old_height)
- change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
+ change_frame_size (SELECTED_FRAME (), width, height, 0, 0, 0, 0);
/* Run suspend-resume-hook. */
hook = intern ("suspend-resume-hook");
is used. Note that [Enter] is not echoed by dos. */
cursor_to (SELECTED_FRAME (), 0, 0);
#endif
- /* It doesn't work to autosave while GC is in progress;
- the code used for auto-saving doesn't cope with the mark bit. */
- if (!gc_in_progress)
- {
- printf ("Auto-save? (y or n) ");
- fflush (stdout);
- if (((c = getchar ()) & ~040) == 'Y')
- {
- Fdo_auto_save (Qt, Qnil);
+ printf ("Auto-save? (y or n) ");
+ fflush (stdout);
+ if (((c = getchar ()) & ~040) == 'Y')
+ {
+ Fdo_auto_save (Qt, Qnil);
#ifdef MSDOS
- printf ("\r\nAuto-save done");
+ printf ("\r\nAuto-save done");
#else /* not MSDOS */
- printf ("Auto-save done\n");
-#endif /* not MSDOS */
- }
- while (c != '\n') c = getchar ();
- }
- else
- {
- /* During GC, it must be safe to reenable quitting again. */
- Vinhibit_quit = Qnil;
-#ifdef MSDOS
- printf ("\r\n");
+ printf ("Auto-save done\n");
#endif /* not MSDOS */
- printf ("Garbage collection in progress; cannot auto-save now\r\n");
- printf ("but will instead do a real quit after garbage collection ends\r\n");
- fflush (stdout);
- }
+ }
+ while (c != '\n') c = getchar ();
#ifdef MSDOS
printf ("\r\nAbort? (y or n) ");
}
XSETFASTINT (val[3], quit_char);
- return Flist (sizeof (val) / sizeof (val[0]), val);
+ return Flist (ARRAYELTS (val), val);
}
DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0,
void
syms_of_keyboard (void)
{
+#include "keyboard.x"
+
pending_funcalls = Qnil;
staticpro (&pending_funcalls);
DEFSYM (Qvertical_line, "vertical-line");
DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
DEFSYM (Qmenu_bar, "menu-bar");
+ DEFSYM (Qright_divider, "right-divider");
+ DEFSYM (Qbottom_divider, "bottom-divider");
DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
{
int i;
- int len = sizeof (head_table) / sizeof (head_table[0]);
+ int len = ARRAYELTS (head_table);
for (i = 0; i < len; i++)
{
staticpro (&button_down_location);
mouse_syms = Fmake_vector (make_number (5), Qnil);
staticpro (&mouse_syms);
- wheel_syms = Fmake_vector (make_number (sizeof (lispy_wheel_names)
- / sizeof (lispy_wheel_names[0])),
+ wheel_syms = Fmake_vector (make_number (ARRAYELTS (lispy_wheel_names)),
Qnil);
staticpro (&wheel_syms);
{
int i;
- int len = sizeof (modifier_names) / sizeof (modifier_names[0]);
+ int len = ARRAYELTS (modifier_names);
modifier_symbols = Fmake_vector (make_number (len), Qnil);
for (i = 0; i < len; i++)
help_form_saved_window_configs = Qnil;
staticpro (&help_form_saved_window_configs);
- defsubr (&Scurrent_idle_time);
- defsubr (&Sevent_symbol_parse_modifiers);
- defsubr (&Sevent_convert_list);
- defsubr (&Sread_key_sequence);
- defsubr (&Sread_key_sequence_vector);
- defsubr (&Srecursive_edit);
- defsubr (&Strack_mouse);
- defsubr (&Sinput_pending_p);
- defsubr (&Srecent_keys);
- defsubr (&Sthis_command_keys);
- defsubr (&Sthis_command_keys_vector);
- defsubr (&Sthis_single_command_keys);
- defsubr (&Sthis_single_command_raw_keys);
- defsubr (&Sreset_this_command_lengths);
- defsubr (&Sclear_this_command_keys);
- defsubr (&Ssuspend_emacs);
- defsubr (&Sabort_recursive_edit);
- defsubr (&Sexit_recursive_edit);
- defsubr (&Srecursion_depth);
- defsubr (&Stop_level);
- defsubr (&Sdiscard_input);
- defsubr (&Sopen_dribble_file);
- defsubr (&Sset_input_interrupt_mode);
- defsubr (&Sset_output_flow_control);
- defsubr (&Sset_input_meta_mode);
- defsubr (&Sset_quit_char);
- defsubr (&Sset_input_mode);
- defsubr (&Scurrent_input_mode);
- defsubr (&Sposn_at_point);
- defsubr (&Sposn_at_x_y);
-
DEFVAR_LISP ("last-command-event", last_command_event,
doc: /* Last input event that was part of a command. */);
Buffer modification stores t in this variable. */);
Vdeactivate_mark = Qnil;
DEFSYM (Qdeactivate_mark, "deactivate-mark");
+ Fmake_variable_buffer_local (Qdeactivate_mark);
DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
doc: /* Normal hook run before each command is executed.
DEFVAR_KBOARD ("overriding-terminal-local-map",
Voverriding_terminal_local_map,
doc: /* Per-terminal keymap that takes precedence over all other keymaps.
-
This variable is intended to let commands such as `universal-argument'
set up a different keymap for reading the next command.
`overriding-terminal-local-map' has a separate binding for each
-terminal device.
-See Info node `(elisp)Multiple Terminals'. */);
+terminal device. See Info node `(elisp)Multiple Terminals'. */);
DEFVAR_LISP ("overriding-local-map", Voverriding_local_map,
- doc: /* Keymap that overrides almost all other local keymaps.
-If this variable is non-nil, it is used as a keymap--replacing the
-buffer's local map, the minor mode keymaps, and char property keymaps. */);
+ doc: /* Keymap that replaces (overrides) local keymaps.
+If this variable is non-nil, Emacs looks up key bindings in this
+keymap INSTEAD OF the keymap char property, minor mode maps, and the
+buffer's local map. Hence, the only active keymaps would be
+`overriding-terminal-local-map', this keymap, and `global-keymap', in
+order of precedence. */);
Voverriding_local_map = Qnil;
DEFVAR_LISP ("overriding-local-map-menu-flag", Voverriding_local_map_menu_flag,
Vthrow_on_input = Qnil;
DEFVAR_LISP ("command-error-function", Vcommand_error_function,
- doc: /* If non-nil, function to output error messages.
-The arguments are the error data, a list of the form
- (SIGNALED-CONDITIONS . SIGNAL-DATA)
-such as just as `condition-case' would bind its variable to,
-the context (a string which normally goes at the start of the message),
-and the Lisp function within which the error was signaled. */);
- Vcommand_error_function = Qnil;
+ doc: /* Function to output error messages.
+Called with three arguments:
+- the error data, a list of the form (SIGNALED-CONDITION . SIGNAL-DATA)
+ such as what `condition-case' would bind its variable to,
+- the context (a string which normally goes at the start of the message),
+- the Lisp function within which the error was signaled. */);
+ Vcommand_error_function = intern ("command-error-default-function");
DEFVAR_LISP ("enable-disabled-menus-and-buttons",
Venable_disabled_menus_and_buttons,
initial_define_lispy_key (Vspecial_event_map, "focus-out",
"handle-focus-out");
}
-
-/* Mark the pointers in the kboard objects.
- Called by Fgarbage_collect. */
-void
-mark_kboards (void)
-{
- KBOARD *kb;
- Lisp_Object *p;
- for (kb = all_kboards; kb; kb = kb->next_kboard)
- {
- if (kb->kbd_macro_buffer)
- for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++)
- mark_object (*p);
- mark_object (KVAR (kb, Voverriding_terminal_local_map));
- mark_object (KVAR (kb, Vlast_command));
- mark_object (KVAR (kb, Vreal_last_command));
- mark_object (KVAR (kb, Vkeyboard_translate_table));
- mark_object (KVAR (kb, Vlast_repeatable_command));
- mark_object (KVAR (kb, Vprefix_arg));
- mark_object (KVAR (kb, Vlast_prefix_arg));
- mark_object (KVAR (kb, kbd_queue));
- mark_object (KVAR (kb, defining_kbd_macro));
- mark_object (KVAR (kb, Vlast_kbd_macro));
- mark_object (KVAR (kb, Vsystem_key_alist));
- mark_object (KVAR (kb, system_key_syms));
- mark_object (KVAR (kb, Vwindow_system));
- mark_object (KVAR (kb, Vinput_decode_map));
- mark_object (KVAR (kb, Vlocal_function_key_map));
- mark_object (KVAR (kb, Vdefault_minibuffer_frame));
- mark_object (KVAR (kb, echo_string));
- }
- {
- struct input_event *event;
- for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++)
- {
- if (event == kbd_buffer + KBD_BUFFER_SIZE)
- event = kbd_buffer;
- /* These two special event types has no Lisp_Objects to mark. */
- if (event->kind != SELECTION_REQUEST_EVENT
- && event->kind != SELECTION_CLEAR_EVENT)
- {
- mark_object (event->x);
- mark_object (event->y);
- mark_object (event->frame_or_window);
- mark_object (event->arg);
- }
- }
- }
-}