along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
-#include <signal.h>
+
+#define BLOCKINPUT_INLINE EXTERN_INLINE
+#define KEYBOARD_INLINE EXTERN_INLINE
+
#include <stdio.h>
-#include <setjmp.h>
+
#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
#include <sys/ioctl.h>
#endif /* not MSDOS */
+#if defined USABLE_FIONREAD && defined USG5_4
+# include <sys/filio.h>
+#endif
+
#include "syssignal.h"
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
-/* This is to get the definitions of the XK_ symbols. */
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
-
-#ifdef HAVE_NTGUI
-#include "w32term.h"
-#endif /* HAVE_NTGUI */
-
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
-/* Variables for blockinput.h: */
+/* Variables for blockinput.h: */
-/* Non-zero if interrupt input is blocked right now. */
+/* Positive if interrupt input is blocked right now. */
volatile int interrupt_input_blocked;
-/* Nonzero means an input interrupt has arrived
- during the current critical section. */
-int interrupt_input_pending;
-
-/* This var should be (interrupt_input_pending || pending_atimers).
- The QUIT macro checks this instead of interrupt_input_pending and
- pending_atimers separately, to reduce code size. So, any code that
- changes interrupt_input_pending or pending_atimers should update
- this too. */
-#ifdef SYNC_INPUT
-int pending_signals;
-#endif
+/* Nonzero means an input interrupt or alarm signal has arrived.
+ The QUIT macro checks this. */
+volatile int pending_signals;
#define KBD_BUFFER_SIZE 4096
/* For longjmp to where kbd input is being done. */
-static jmp_buf getcjmp;
+static sys_jmp_buf getcjmp;
/* True while doing kbd input. */
int waiting_for_input;
last event came from a macro. We use this to determine when to
generate switch-frame events. This may be cleared by functions
like Fselect_frame, to make sure that a switch-frame event is
- generated by the next character. */
+ generated by the next character.
+
+ FIXME: This is modified by a signal handler so it should be volatile.
+ It's exported to Lisp, though, so it can't simply be marked
+ 'volatile' here. */
Lisp_Object internal_last_event_frame;
/* The timestamp of the last input event we received from the X server.
/* Nonzero while interrupts are temporarily deferred during redisplay. */
int interrupts_deferred;
-/* Allow m- file to inhibit use of FIONREAD. */
-#ifdef BROKEN_FIONREAD
-#undef FIONREAD
-#endif
-
-/* We are unable to use interrupts if FIONREAD is not available,
- so flush SIGIO so we won't try. */
-#if !defined (FIONREAD)
-#ifdef SIGIO
-#undef SIGIO
-#endif
-#endif
-
/* 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. */
-#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_ASYNC_EVENTS)
+#ifdef HAVE_WINDOW_SYSTEM
#define POLL_FOR_INPUT
#endif
/* Function for init_keyboard to call with no args (if nonzero). */
static void (*keyboard_init_hook) (void);
-static int read_avail_input (int);
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 *, ptrdiff_t);
static Lisp_Object make_lispy_switch_frame (Lisp_Object);
static int help_char_p (Lisp_Object);
-static void save_getcjmp (jmp_buf);
-static void restore_getcjmp (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 Lisp_Object restore_kboard_configuration (Lisp_Object);
-static void interrupt_signal (int signalnum);
-#ifdef SIGIO
-static void input_available_signal (int signo);
+#ifdef USABLE_SIGIO
+static void deliver_input_available_signal (int signo);
#endif
-static Lisp_Object (Fcommand_execute) (Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object);
-static void handle_interrupt (void);
-static void quit_throw_to_read_char (int) NO_RETURN;
+static void handle_interrupt (bool);
+static _Noreturn void quit_throw_to_read_char (int);
static void process_special_events (void);
static void timer_start_idle (void);
static void timer_stop_idle (void);
static void timer_resume_idle (void);
-static void handle_user_signal (int);
+static void deliver_user_signal (int);
static char *find_user_signal_name (int);
-static int store_user_signal_events (void);
+static void store_user_signal_events (void);
+
+/* These setters are used only in this file, so they can be private. */
+static inline void
+kset_echo_string (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (echo_string) = val;
+}
+static inline void
+kset_kbd_queue (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (kbd_queue) = val;
+}
+static inline void
+kset_keyboard_translate_table (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (Vkeyboard_translate_table) = val;
+}
+static inline void
+kset_last_prefix_arg (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (Vlast_prefix_arg) = val;
+}
+static inline void
+kset_last_repeatable_command (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (Vlast_repeatable_command) = val;
+}
+static inline void
+kset_local_function_key_map (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (Vlocal_function_key_map) = val;
+}
+static inline void
+kset_overriding_terminal_local_map (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (Voverriding_terminal_local_map) = val;
+}
+static inline void
+kset_real_last_command (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (Vreal_last_command) = val;
+}
+static inline void
+kset_system_key_syms (struct kboard *kb, Lisp_Object val)
+{
+ kb->INTERNAL_FIELD (system_key_syms) = val;
+}
\f
/* Add C to the echo string, if echoing is going on.
if (current_kboard->immediate_echo)
{
int size = KEY_DESCRIPTION_SIZE + 100;
- char *buffer = (char *) alloca (size);
+ char *buffer = alloca (size);
char *ptr = buffer;
Lisp_Object echo_string;
{
int offset = ptr - buffer;
size = max (2 * size, size + nbytes);
- buffer = (char *) alloca (size);
+ buffer = alloca (size);
ptr = buffer + offset;
}
{
int offset = ptr - buffer;
size += len;
- buffer = (char *) alloca (size);
+ buffer = alloca (size);
ptr = buffer + offset;
}
else if (STRINGP (echo_string))
echo_string = concat2 (echo_string, build_string (" "));
- KVAR (current_kboard, echo_string)
- = concat2 (echo_string, make_string (buffer, ptr - buffer));
+ kset_echo_string
+ (current_kboard,
+ concat2 (echo_string, make_string (buffer, ptr - buffer)));
echo_now ();
}
/* Put a dash at the end of the buffer temporarily,
but make it go away when the next character is added. */
- KVAR (current_kboard, echo_string) = concat2 (KVAR (current_kboard, echo_string),
- build_string ("-"));
+ kset_echo_string
+ (current_kboard,
+ concat2 (KVAR (current_kboard, echo_string), build_string ("-")));
echo_now ();
}
{
current_kboard->immediate_echo = 0;
current_kboard->echo_after_prompt = -1;
- KVAR (current_kboard, echo_string) = Qnil;
+ kset_echo_string (current_kboard, Qnil);
ok_to_echo_at_next_pause = NULL;
echo_kboard = NULL;
echo_message_buffer = Qnil;
echo_truncate (ptrdiff_t nchars)
{
if (STRINGP (KVAR (current_kboard, echo_string)))
- KVAR (current_kboard, echo_string)
- = Fsubstring (KVAR (current_kboard, echo_string),
- make_number (0), make_number (nchars));
+ kset_echo_string (current_kboard,
+ Fsubstring (KVAR (current_kboard, echo_string),
+ make_number (0), make_number (nchars)));
truncate_echo_area (nchars);
}
/* 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 ())
return Qnil;
command_loop_level++;
void
push_kboard (struct kboard *k)
{
- struct kboard_stack *p
- = (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack));
+ struct kboard_stack *p = xmalloc (sizeof *p);
p->next = kboard_stack;
p->kboard = current_kboard;
pop_kboard ();
/* The pop should not change the kboard. */
if (single_kboard && current_kboard != prev)
- abort ();
+ emacs_abort ();
}
return Qnil;
}
Vstandard_input = Qt;
Vexecuting_kbd_macro = Qnil;
executing_kbd_macro = Qnil;
- KVAR (current_kboard, Vprefix_arg) = Qnil;
- KVAR (current_kboard, Vlast_prefix_arg) = Qnil;
+ kset_prefix_arg (current_kboard, Qnil);
+ kset_last_prefix_arg (current_kboard, Qnil);
cancel_echoing ();
/* Avoid unquittable loop if data contains a circular list. */
/* Unblock input if we enter with input blocked. This may happen if
redisplay traps e.g. during tool-bar update with input blocked. */
- while (INPUT_BLOCKED_P)
- UNBLOCK_INPUT;
+ totally_unblock_input ();
Fthrow (Qtop_level, Qnil);
}
-static void user_error (const char*) NO_RETURN;
-static void user_error (const char *msg)
+static _Noreturn void
+user_error (const char *msg)
{
xsignal1 (Quser_error, build_string (msg));
}
-static Lisp_Object Fexit_recursive_edit (void) NO_RETURN;
+_Noreturn
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");
}
-static Lisp_Object Fabort_recursive_edit (void) NO_RETURN;
+_Noreturn
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)
}
#endif
+/* The last boundary auto-added to buffer-undo-list. */
+Lisp_Object last_undo_boundary;
+
/* FIXME: This is wrong rather than test window-system, we should call
a new set-selection, which will then dispatch to x-set-selection, or
tty-set-selection, or w32-set-selection, ... */
-EXFUN (Fwindow_system, 1);
Lisp_Object
command_loop_1 (void)
#endif
int already_adjusted = 0;
- KVAR (current_kboard, Vprefix_arg) = Qnil;
- KVAR (current_kboard, Vlast_prefix_arg) = Qnil;
+ kset_prefix_arg (current_kboard, Qnil);
+ kset_last_prefix_arg (current_kboard, Qnil);
Vdeactivate_mark = Qnil;
waiting_for_input = 0;
cancel_echoing ();
}
/* Do this after running Vpost_command_hook, for consistency. */
- KVAR (current_kboard, Vlast_command) = Vthis_command;
- KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
+ kset_last_command (current_kboard, Vthis_command);
+ kset_real_last_command (current_kboard, Vreal_this_command);
if (!CONSP (last_command_event))
- KVAR (current_kboard, Vlast_repeatable_command) = Vreal_this_command;
+ kset_last_repeatable_command (current_kboard, Vreal_this_command);
while (1)
{
Fkill_emacs (Qnil);
/* Make sure the current window's buffer is selected. */
- if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
- set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
/* Display any malloc warning that just came out. Use while because
displaying one warning can cause another. */
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. */
}
}
-#if 0
- /* Select the frame that the last event came from. Usually,
- switch-frame events will take care of this, but if some lisp
- code swallows a switch-frame event, we'll fix things up here.
- Is this a good idea? */
- if (FRAMEP (internal_last_event_frame)
- && !EQ (internal_last_event_frame, selected_frame))
- Fselect_frame (internal_last_event_frame, Qnil);
-#endif
/* If it has changed current-menubar from previous value,
really recompute the menubar from the value. */
if (! NILP (Vlucid_menu_bar_dirty_flag)
/* A filter may have run while we were reading the input. */
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
- if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
- set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
++num_input_keys;
keys = Fkey_description (keys, Qnil);
bitch_at_user ();
message_with_string ("%s is undefined", keys, 0);
- KVAR (current_kboard, defining_kbd_macro) = Qnil;
+ 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. */
= parse_modifiers (EVENT_HEAD (last_command_event));
int modifiers = XINT (XCAR (XCDR (breakdown)));
if (!(modifiers & down_modifier))
- KVAR (current_kboard, Vprefix_arg) = Qnil;
+ kset_prefix_arg (current_kboard, Qnil);
}
else
- KVAR (current_kboard, Vprefix_arg) = Qnil;
+ kset_prefix_arg (current_kboard, Qnil);
}
else
{
#endif
if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why? --Stef */
- Fundo_boundary ();
+ {
+ Lisp_Object undo = BVAR (current_buffer, undo_list);
+ Fundo_boundary ();
+ last_undo_boundary
+ = (EQ (undo, BVAR (current_buffer, undo_list))
+ ? Qnil : BVAR (current_buffer, undo_list));
+ }
Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
#ifdef HAVE_WINDOW_SYSTEM
unbind_to (scount, Qnil);
#endif
}
- KVAR (current_kboard, Vlast_prefix_arg) = Vcurrent_prefix_arg;
+ kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg);
safe_run_hooks (Qpost_command_hook);
if (NILP (KVAR (current_kboard, Vprefix_arg))
|| CONSP (last_command_event))
{
- KVAR (current_kboard, Vlast_command) = Vthis_command;
- KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
+ kset_last_command (current_kboard, Vthis_command);
+ kset_real_last_command (current_kboard, Vreal_this_command);
if (!CONSP (last_command_event))
- KVAR (current_kboard, Vlast_repeatable_command)
- = Vreal_this_command;
+ kset_last_repeatable_command (current_kboard, Vreal_this_command);
cancel_echoing ();
this_command_key_count = 0;
this_command_key_count_reset = 0;
&& (beg < PT /* && end > PT <- It's always the case. */
|| (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
{
- xassert (end > PT);
+ eassert (end > PT);
SET_PT (PT < last_pt
? (STRINGP (val) && SCHARS (val) == 0
? max (beg - 1, BEGV)
#if 0 /* This assertion isn't correct, because SET_PT may end up setting
the point to something other than its argument, due to
point-motion hooks, intangibility, etc. */
- xassert (PT == beg || PT == end);
+ eassert (PT == beg || PT == end);
#endif
/* Pretend the area doesn't exist if the buffer is not
void
poll_for_input_1 (void)
{
-/* Tell ns_read_socket() it is being called asynchronously so it can avoid
- doing anything dangerous. */
-#ifdef HAVE_NS
- ++handling_signal;
-#endif
- if (interrupt_input_blocked == 0
+ if (! input_blocked_p ()
&& !waiting_for_input)
- read_avail_input (0);
-#ifdef HAVE_NS
- --handling_signal;
-#endif
+ gobble_input ();
}
/* Timer callback function for poll_timer. TIMER is equal to
poll_for_input (struct atimer *timer)
{
if (poll_suppress_count == 0)
- {
-#ifdef SYNC_INPUT
- interrupt_input_pending = 1;
- pending_signals = 1;
-#else
- poll_for_input_1 ();
-#endif
- }
+ pending_signals = 1;
}
#endif /* POLL_FOR_INPUT */
|| EMACS_SECS (poll_timer->interval) != polling_period)
{
time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
- EMACS_TIME interval;
+ EMACS_TIME interval = make_emacs_time (period, 0);
if (poll_timer)
cancel_atimer (poll_timer);
- EMACS_SET_SECS_USECS (interval, period, 0);
poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
poll_for_input, NULL);
}
if (!NILP (help) && !STRINGP (help))
{
if (FUNCTIONP (help))
- {
- Lisp_Object args[4];
- args[0] = help;
- args[1] = window;
- args[2] = object;
- args[3] = pos;
- help = safe_call (4, args);
- }
+ help = safe_call (4, help, window, object, pos);
else
help = safe_eval (help);
{
volatile Lisp_Object c;
ptrdiff_t jmpcount;
- jmp_buf local_getcjmp;
- jmp_buf save_jump;
+ sys_jmp_buf local_getcjmp;
+ sys_jmp_buf save_jump;
volatile int key_already_recorded = 0;
Lisp_Object tem, save;
volatile Lisp_Object previous_echo_area_message;
goto reread_first;
}
- if (unread_command_char != -1)
- {
- XSETINT (c, unread_command_char);
- unread_command_char = -1;
-
- reread = 1;
- goto reread_first;
- }
-
if (CONSP (Vunread_command_events))
{
int was_disabled = 0;
&& !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
/* Don't bring up a menu if we already have another event. */
&& NILP (Vunread_command_events)
- && unread_command_char < 0
&& !detect_input_pending_run_timers (0))
{
c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
it *must not* be in effect when we call redisplay. */
jmpcount = SPECPDL_INDEX ();
- if (_setjmp (local_getcjmp))
+ if (sys_setjmp (local_getcjmp))
{
/* Handle quits while reading the keyboard. */
/* We must have saved the outer value of getcjmp here,
Lisp_Object last = KVAR (kb, kbd_queue);
/* We shouldn't get here if we were in single-kboard mode! */
if (single_kboard)
- abort ();
+ emacs_abort ();
if (CONSP (last))
{
while (CONSP (XCDR (last)))
last = XCDR (last);
if (!NILP (XCDR (last)))
- abort ();
+ emacs_abort ();
}
if (!CONSP (last))
- KVAR (kb, kbd_queue) = Fcons (c, Qnil);
+ kset_kbd_queue (kb, Fcons (c, Qnil));
else
XSETCDR (last, Fcons (c, Qnil));
kb->kbd_queue_has_data = 1;
&& !EQ (XCAR (prev_event), Qmenu_bar)
&& !EQ (XCAR (prev_event), Qtool_bar)
/* Don't bring up a menu if we already have another event. */
- && NILP (Vunread_command_events)
- && unread_command_char < 0)
+ && NILP (Vunread_command_events))
{
c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
&& ! CONSP (Vunread_command_events))
{
Fdo_auto_save (Qnil, Qnil);
-
- /* If we have auto-saved and there is still no input
- available, garbage collect if there has been enough
- consing going on to make it worthwhile. */
- if (!detect_input_pending_run_timers (0)
- && consing_since_gc > gc_cons_threshold / 2)
- Fgarbage_collect ();
-
redisplay ();
}
}
+
+ /* If there is still no input available, ask for GC. */
+ if (!detect_input_pending_run_timers (0))
+ maybe_gc ();
}
/* Notify the caller if an autosave hook, or a timer, sentinel or
if (current_kboard->kbd_queue_has_data)
{
if (!CONSP (KVAR (current_kboard, kbd_queue)))
- abort ();
+ emacs_abort ();
c = XCAR (KVAR (current_kboard, kbd_queue));
- KVAR (current_kboard, kbd_queue)
- = XCDR (KVAR (current_kboard, kbd_queue));
+ kset_kbd_queue (current_kboard,
+ XCDR (KVAR (current_kboard, kbd_queue)));
if (NILP (KVAR (current_kboard, kbd_queue)))
current_kboard->kbd_queue_has_data = 0;
input_pending = readable_events (0);
{
KBOARD *kb IF_LINT (= NULL);
- if (end_time)
- {
- EMACS_TIME now;
- EMACS_GET_TIME (now);
- if (EMACS_TIME_GE (now, *end_time))
- goto exit;
- }
+ if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
+ goto exit;
/* Actually read a character, waiting if necessary. */
save_getcjmp (save_jump);
while (CONSP (XCDR (last)))
last = XCDR (last);
if (!NILP (XCDR (last)))
- abort ();
+ emacs_abort ();
}
if (!CONSP (last))
- KVAR (kb, kbd_queue) = Fcons (c, Qnil);
+ kset_kbd_queue (kb, Fcons (c, Qnil));
else
XSETCDR (last, Fcons (c, Qnil));
kb->kbd_queue_has_data = 1;
cancel_echoing ();
ok_to_echo_at_next_pause = saved_ok_to_echo;
- KVAR (current_kboard, echo_string) = saved_echo_string;
+ kset_echo_string (current_kboard, saved_echo_string);
current_kboard->echo_after_prompt = saved_echo_after_prompt;
if (saved_immediate_echo)
echo_now ();
If you, dear reader, have a better idea, you've got the source. :-) */
if (dribble)
{
- BLOCK_INPUT;
+ block_input ();
if (INTEGERP (c))
{
if (XUINT (c) < 0x100)
}
fflush (dribble);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
See read_process_output. */
static void
-save_getcjmp (jmp_buf temp)
+save_getcjmp (sys_jmp_buf temp)
{
memcpy (temp, getcjmp, sizeof getcjmp);
}
static void
-restore_getcjmp (jmp_buf temp)
+restore_getcjmp (sys_jmp_buf temp)
{
memcpy (getcjmp, temp, sizeof getcjmp);
}
Else, if EVENT is a quit event, store the quit event
in HOLD_QUIT, and return (thus ignoring further events).
- This is used in read_avail_input to postpone the processing
- of the quit event until all subsequent input events have been
- parsed (and discarded).
- */
+ This is used to postpone the processing of the quit event until all
+ subsequent input events have been parsed (and discarded). */
void
kbd_buffer_store_event_hold (register struct input_event *event,
struct input_event *hold_quit)
{
if (event->kind == NO_EVENT)
- abort ();
+ emacs_abort ();
if (hold_quit && hold_quit->kind != NO_EVENT)
return;
if (single_kboard && kb != current_kboard)
{
- KVAR (kb, kbd_queue)
- = Fcons (make_lispy_switch_frame (event->frame_or_window),
- Fcons (make_number (c), Qnil));
+ kset_kbd_queue
+ (kb, Fcons (make_lispy_switch_frame (event->frame_or_window),
+ Fcons (make_number (c), Qnil)));
kb->kbd_queue_has_data = 1;
for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
{
if (hold_quit)
{
- memcpy (hold_quit, event, sizeof (*event));
+ *hold_quit = *event;
return;
}
}
last_event_timestamp = event->timestamp;
- handle_interrupt ();
+
+ handle_interrupt (0);
return;
}
/* Don't read keyboard input until we have processed kbd_buffer.
This happens when pasting text longer than KBD_BUFFER_SIZE/2. */
hold_keyboard_input ();
-#ifdef SIGIO
if (!noninteractive)
- signal (SIGIO, SIG_IGN);
-#endif
+ ignore_sigio ();
stop_polling ();
}
#endif /* subprocesses */
if (immediate_quit && NILP (Vinhibit_quit))
{
immediate_quit = 0;
- sigfree ();
QUIT;
}
}
/* Start reading input again, we have processed enough so we can
accept new events again. */
unhold_keyboard_input ();
-#ifdef SIGIO
- if (!noninteractive)
- signal (SIGIO, input_available_signal);
-#endif /* SIGIO */
start_polling ();
}
#endif /* subprocesses */
/* One way or another, wait until input is available; then, if
interrupt handlers have not read it, read it now. */
-/* Note SIGIO has been undef'd if FIONREAD is missing. */
-#ifdef SIGIO
- gobble_input (0);
-#endif /* SIGIO */
+#ifdef USABLE_SIGIO
+ gobble_input ();
+#endif
if (kbd_fetch_ptr != kbd_store_ptr)
break;
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
#endif
if (end_time)
{
- EMACS_TIME duration;
- EMACS_GET_TIME (duration);
- if (EMACS_TIME_GE (duration, *end_time))
- return Qnil; /* finished waiting */
+ EMACS_TIME now = current_emacs_time ();
+ if (EMACS_TIME_LE (*end_time, now))
+ return Qnil; /* Finished waiting. */
else
{
- EMACS_SUB_TIME (duration, *end_time, duration);
+ EMACS_TIME duration = sub_emacs_time (*end_time, now);
wait_reading_process_output (min (EMACS_SECS (duration),
- INTMAX_MAX),
+ WAIT_READING_MAX),
EMACS_NSECS (duration),
-1, 1, Qnil, NULL, 0);
}
wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0);
if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
- /* Pass 1 for EXPECT since we just waited to have input. */
- read_avail_input (1);
+ gobble_input ();
}
if (CONSP (Vunread_command_events))
#else
/* We're getting selection request events, but we don't have
a window system. */
- abort ();
+ emacs_abort ();
#endif
}
#if defined (WINDOWSNT)
else if (event->kind == LANGUAGE_CHANGE_EVENT)
{
- /* Make an event (language-change (FRAME CHARSET LCID)). */
- obj = Fcons (event->frame_or_window, Qnil);
- obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
+ /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */
+ obj = Fcons (Qlanguage_change,
+ list3 (event->frame_or_window,
+ make_number (event->code),
+ make_number (event->modifiers)));
kbd_fetch_ptr = event + 1;
}
#endif
*used_mouse_menu = 1;
#endif
#ifdef HAVE_NS
- /* certain system events are non-key events */
+ /* Certain system events are non-key events. */
if (used_mouse_menu
&& event->kind == NS_NONKEY_EVENT)
*used_mouse_menu = 1;
so x remains nil. */
x = Qnil;
- /* XXX Can f or mouse_position_hook be NULL here? */
+ /* XXX Can f or mouse_position_hook be NULL here? */
if (f && FRAME_TERMINAL (f)->mouse_position_hook)
(*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
&part, &x, &y, &t);
else
/* We were promised by the above while loop that there was
something for us to read! */
- abort ();
+ emacs_abort ();
input_pending = readable_events (0);
#else
/* We're getting selection request events, but we don't have
a window system. */
- abort ();
+ emacs_abort ();
#endif
}
}
if (EMACS_TIME_VALID_P (timer_idleness_start_time))
return;
- EMACS_GET_TIME (timer_idleness_start_time);
-
+ timer_idleness_start_time = current_emacs_time ();
timer_last_idleness_start_time = timer_idleness_start_time;
/* Mark all idle-time timers as once again candidates for running. */
static void
timer_stop_idle (void)
{
- EMACS_SET_INVALID_TIME (timer_idleness_start_time);
+ timer_idleness_start_time = invalid_emacs_time ();
}
/* Resume idle timer from last idle start time. */
...). Each element has the form (FUN . ARGS). */
Lisp_Object pending_funcalls;
-/* If TIMER is a valid timer, return nonzero and place its value into
- *RESULT. Otherwise return zero. */
-static int
+/* Return true if TIMER is a valid timer, placing its value into *RESULT. */
+static bool
decode_timer (Lisp_Object timer, EMACS_TIME *result)
{
Lisp_Object *vector;
if (! NILP (vector[0]))
return 0;
- return decode_time_components (vector[1], vector[2], vector[3], vector[4],
+ return decode_time_components (vector[1], vector[2], vector[3], vector[8],
result, 0);
}
should be done. */
static EMACS_TIME
-timer_check_2 (void)
+timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
{
EMACS_TIME nexttime;
EMACS_TIME now;
EMACS_TIME idleness_now;
- Lisp_Object timers, idle_timers, chosen_timer;
- struct gcpro gcpro1, gcpro2, gcpro3;
+ Lisp_Object chosen_timer;
+ struct gcpro gcpro1;
- EMACS_SET_INVALID_TIME (nexttime);
+ nexttime = invalid_emacs_time ();
- /* Always consider the ordinary timers. */
- timers = Vtimer_list;
- /* Consider the idle timers only if Emacs is idle. */
- if (EMACS_TIME_VALID_P (timer_idleness_start_time))
- idle_timers = Vtimer_idle_list;
- else
- idle_timers = Qnil;
chosen_timer = Qnil;
- GCPRO3 (timers, idle_timers, chosen_timer);
+ GCPRO1 (chosen_timer);
/* First run the code that was delayed. */
while (CONSP (pending_funcalls))
if (CONSP (timers) || CONSP (idle_timers))
{
- EMACS_GET_TIME (now);
- if (EMACS_TIME_VALID_P (timer_idleness_start_time))
- EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
- else
- EMACS_SET_SECS_NSECS (idleness_now, 0, 0);
+ now = current_emacs_time ();
+ idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time)
+ ? sub_emacs_time (now, timer_idleness_start_time)
+ : make_emacs_time (0, 0));
}
while (CONSP (timers) || CONSP (idle_timers))
{
- Lisp_Object *vector;
Lisp_Object timer = Qnil, idle_timer = Qnil;
EMACS_TIME timer_time, idle_timer_time;
EMACS_TIME difference;
- EMACS_TIME timer_difference, idle_timer_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;
- EMACS_SET_INVALID_TIME (timer_difference);
- EMACS_SET_INVALID_TIME (idle_timer_difference);
-
/* Set TIMER and TIMER_DIFFERENCE
based on the next ordinary timer.
TIMER_DIFFERENCE is the distance in time from NOW to when
}
timer_ripe = EMACS_TIME_LE (timer_time, now);
- if (timer_ripe)
- EMACS_SUB_TIME (timer_difference, now, timer_time);
- else
- EMACS_SUB_TIME (timer_difference, timer_time, now);
+ timer_difference = (timer_ripe
+ ? sub_emacs_time (now, timer_time)
+ : sub_emacs_time (timer_time, now));
}
/* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
}
idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
- if (idle_timer_ripe)
- EMACS_SUB_TIME (idle_timer_difference,
- idleness_now, idle_timer_time);
- else
- EMACS_SUB_TIME (idle_timer_difference,
- idle_timer_time, idleness_now);
+ idle_timer_difference =
+ (idle_timer_ripe
+ ? sub_emacs_time (idleness_now, idle_timer_time)
+ : sub_emacs_time (idle_timer_time, idleness_now));
}
/* Decide which timer is the next timer,
/* If timer is ripe, run it if it hasn't been run. */
if (ripe)
{
- vector = XVECTOR (chosen_timer)->contents;
- if (NILP (vector[0]))
+ if (NILP (AREF (chosen_timer, 0)))
{
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object old_deactivate_mark = Vdeactivate_mark;
/* Mark the timer as triggered to prevent problems if the lisp
code fails to reschedule it right. */
- vector[0] = Qt;
+ ASET (chosen_timer, 0, Qt);
specbind (Qinhibit_quit, Qt);
return 0 to indicate that. */
}
- EMACS_SET_SECS (nexttime, 0);
- EMACS_SET_USECS (nexttime, 0);
+ nexttime = make_emacs_time (0, 0);
+ break;
}
else
/* When we encounter a timer that is still waiting,
timer_check (void)
{
EMACS_TIME nexttime;
+ Lisp_Object timers, idle_timers;
+ struct gcpro gcpro1, gcpro2;
+
+ Lisp_Object tem = Vinhibit_quit;
+ Vinhibit_quit = Qt;
+
+ /* We use copies of the timers' lists to allow a timer to add itself
+ again, without locking up Emacs if the newly added timer is
+ already ripe when added. */
+
+ /* Always consider the ordinary timers. */
+ timers = Fcopy_sequence (Vtimer_list);
+ /* Consider the idle timers only if Emacs is idle. */
+ if (EMACS_TIME_VALID_P (timer_idleness_start_time))
+ idle_timers = Fcopy_sequence (Vtimer_idle_list);
+ else
+ idle_timers = Qnil;
+
+ Vinhibit_quit = tem;
+
+ GCPRO2 (timers, idle_timers);
do
{
- nexttime = timer_check_2 ();
+ nexttime = timer_check_2 (timers, idle_timers);
}
while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0);
+ UNGCPRO;
return nexttime;
}
The value when Emacs is not idle is nil.
-NSEC is a multiple of the system clock resolution. */)
+PSEC is a multiple of the system clock resolution. */)
(void)
{
if (EMACS_TIME_VALID_P (timer_idleness_start_time))
- {
- EMACS_TIME now, idleness_now;
-
- EMACS_GET_TIME (now);
- EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
-
- return make_lisp_time (idleness_now);
- }
+ return make_lisp_time (sub_emacs_time (current_emacs_time (),
+ timer_idleness_start_time));
return Qnil;
}
{
int i;
- switch (SWITCH_ENUM_CAST (event->kind))
+ switch (event->kind)
{
/* A simple keystroke. */
case ASCII_KEYSTROKE_EVENT:
/* We need to use an alist rather than a vector as the cache
since we can't make a vector long enough. */
if (NILP (KVAR (current_kboard, system_key_syms)))
- KVAR (current_kboard, system_key_syms) = Fcons (Qnil, Qnil);
+ kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil));
return modify_event_symbol (event->code,
event->modifiers,
Qfunction_key,
mouse_syms = larger_vector (mouse_syms, incr, -1);
}
- start_pos_ptr = &AREF (button_down_location, button);
+ start_pos_ptr = aref_addr (button_down_location, button);
start_pos = *start_pos_ptr;
*start_pos_ptr = Qnil;
else if (FRAMEP (event->frame_or_window))
f = XFRAME (event->frame_or_window);
else
- abort ();
+ emacs_abort ();
if (FRAME_WINDOW_P (f))
fuzz = double_click_fuzz;
else
/* Every mouse event should either have the down_modifier or
the up_modifier set. */
- abort ();
+ emacs_abort ();
{
/* Get the symbol we should use for the mouse click. */
else if (FRAMEP (event->frame_or_window))
fr = XFRAME (event->frame_or_window);
else
- abort ();
+ emacs_abort ();
fuzz = FRAME_WINDOW_P (fr)
? double_click_fuzz : double_click_fuzz / 8;
else
/* Every wheel event should either have the down_modifier or
the up_modifier set. */
- abort ();
+ emacs_abort ();
if (event->kind == HORIZ_WHEEL_EVENT)
symbol_num += 2;
{
char *name = find_user_signal_name (event->code);
if (!name)
- abort ();
+ emacs_abort ();
return intern (name);
}
mouse_syms = larger_vector (mouse_syms, incr, -1);
}
- start_pos_ptr = &AREF (button_down_location, button);
+ start_pos_ptr = aref_addr (button_down_location, button);
start_pos = *start_pos_ptr;
position = make_lispy_position (f, event->x, event->y,
/* The 'kind' field of the event is something we don't recognize. */
default:
- abort ();
+ emacs_abort ();
}
}
#define MULTI_LETTER_MOD(BIT, NAME, LEN) \
if (i + LEN + 1 <= SBYTES (name) \
- && ! strncmp (SSDATA (name) + i, NAME, LEN)) \
+ && ! memcmp (SDATA (name) + i, NAME, LEN)) \
{ \
this_mod_end = i + LEN; \
this_mod = BIT; \
if (! (modifiers & (down_modifier | drag_modifier
| double_modifier | triple_modifier))
&& i + 7 == SBYTES (name)
- && strncmp (SSDATA (name) + i, "mouse-", 6) == 0
+ && memcmp (SDATA (name) + i, "mouse-", 6) == 0
&& ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
modifiers |= click_modifier;
if (! (modifiers & (double_modifier | triple_modifier))
&& i + 6 < SBYTES (name)
- && strncmp (SSDATA (name) + i, "wheel-", 6) == 0)
+ && memcmp (SDATA (name) + i, "wheel-", 6) == 0)
modifiers |= click_modifier;
if (modifier_end)
/* Since BASE could contain nulls, we can't use intern here; we have
to use Fintern, which expects a genuine Lisp_String, and keeps a
reference to it. */
- char *new_mods
- = (char *) alloca (sizeof ("A-C-H-M-S-s-down-drag-double-triple-"));
+ char new_mods[sizeof "A-C-H-M-S-s-down-drag-double-triple-"];
int mod_len;
{
/* Only the event queue may use the `up' modifier; it should always
be turned into a click or drag event before presented to lisp code. */
if (modifiers & up_modifier)
- abort ();
+ emacs_abort ();
if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; }
if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; }
Qnil);
if (modifiers & ~INTMASK)
- abort ();
+ emacs_abort ();
XSETFASTINT (mask, modifiers);
elements = Fcons (unmodified, Fcons (mask, Qnil));
ptrdiff_t len = (SBYTES (name_alist_or_stem)
+ sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
USE_SAFE_ALLOCA;
- SAFE_ALLOCA (buf, char *, len);
+ buf = SAFE_ALLOCA (len);
esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
XINT (symbol_int) + 1);
value = intern (buf);
#define MULTI_LETTER_MOD(BIT, NAME, LEN) \
if (LEN == SBYTES (name) \
- && ! strncmp (SSDATA (name), NAME, LEN)) \
+ && ! memcmp (SDATA (name), NAME, LEN)) \
return BIT;
case 'A':
return;
/* Try to read some input and see how much we get. */
- gobble_input (0);
+ gobble_input ();
*addr = (!NILP (Vquit_flag) || readable_events (flags));
}
-/* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary. */
-
-void
-gobble_input (int expected)
-{
-#ifdef SIGIO
- if (interrupt_input)
- {
- SIGMASKTYPE mask;
- mask = sigblock (sigmask (SIGIO));
- read_avail_input (expected);
- sigsetmask (mask);
- }
- else
-#ifdef POLL_FOR_INPUT
- /* XXX This condition was (read_socket_hook && !interrupt_input),
- but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
- if (!interrupt_input && poll_suppress_count == 0)
- {
- SIGMASKTYPE mask;
- mask = sigblock (sigmask (SIGALRM));
- read_avail_input (expected);
- sigsetmask (mask);
- }
- else
-#endif
-#endif
- read_avail_input (expected);
-}
-
/* Put a BUFFER_SWITCH_EVENT in the buffer
so that read_key_sequence will notice the new current buffer. */
return;
/* Make sure no interrupt happens while storing the event. */
-#ifdef SIGIO
+#ifdef USABLE_SIGIO
if (interrupt_input)
- {
- SIGMASKTYPE mask;
- mask = sigblock (sigmask (SIGIO));
- kbd_buffer_store_event (&event);
- sigsetmask (mask);
- }
+ kbd_buffer_store_event (&event);
else
#endif
{
/* Read any terminal input already buffered up by the system
into the kbd_buffer, but do not wait.
- EXPECTED should be nonzero if the caller knows there is some input.
-
- Returns the number of keyboard chars read, or -1 meaning
+ Return the number of keyboard chars read, or -1 meaning
this is a bad time to try to read input. */
-static int
-read_avail_input (int expected)
+int
+gobble_input (void)
{
int nread = 0;
int err = 0;
struct terminal *t;
/* Store pending user signal events, if any. */
- if (store_user_signal_events ())
- expected = 0;
+ store_user_signal_events ();
/* Loop through the available terminals, and call their input hooks. */
t = terminal_list;
int nr;
struct input_event hold_quit;
+ if (input_blocked_p ())
+ {
+ pending_signals = 1;
+ break;
+ }
+
EVENT_INIT (hold_quit);
hold_quit.kind = NO_EVENT;
/* No need for FIONREAD or fcntl; just say don't wait. */
- while (nr = (*t->read_socket_hook) (t, expected, &hold_quit), nr > 0)
- {
- nread += nr;
- expected = 0;
- }
+ while (0 < (nr = (*t->read_socket_hook) (t, &hold_quit)))
+ nread += nr;
if (nr == -1) /* Not OK to read input now. */
{
this process rather than to the whole process
group? Perhaps on systems with FIONREAD Emacs is
alone in its group. */
- kill (getpid (), SIGHUP);
+ terminate_due_to_signal (SIGHUP, 10);
/* XXX Is calling delete_terminal safe here? It calls delete_frame. */
{
int
tty_read_avail_input (struct terminal *terminal,
- int expected,
struct input_event *hold_quit)
{
/* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
if (terminal->type != output_termcap
&& terminal->type != output_msdos_raw)
- abort ();
+ emacs_abort ();
/* XXX I think the following code should be moved to separate hook
functions in system-dependent files. */
#endif /* HAVE_GPM */
/* Determine how many characters we should *try* to read. */
-#ifdef FIONREAD
+#ifdef USABLE_FIONREAD
/* Find out how much input is available. */
if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
{
return 0;
if (n_to_read > sizeof cbuf)
n_to_read = sizeof cbuf;
-#else /* no FIONREAD */
-#if defined (USG) || defined (CYGWIN)
+#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);
#else
- you lose;
-#endif
+# error "Cannot read without possibly delaying"
#endif
#ifdef subprocesses
#endif
);
-#ifndef FIONREAD
+#ifndef USABLE_FIONREAD
#if defined (USG) || defined (CYGWIN)
fcntl (fileno (tty->input), F_SETFL, 0);
#endif /* USG or CYGWIN */
return nread;
}
\f
-#if defined SYNC_INPUT || defined SIGIO
static void
handle_async_input (void)
{
- interrupt_input_pending = 0;
-#ifdef SYNC_INPUT
- pending_signals = pending_atimers;
-#endif
-/* Tell ns_read_socket() it is being called asynchronously so it can avoid
- doing anything dangerous. */
-#ifdef HAVE_NS
- ++handling_signal;
-#endif
+#ifdef USABLE_SIGIO
while (1)
{
- int nread;
- nread = read_avail_input (1);
+ int nread = gobble_input ();
/* -1 means it's not ok to read the input now.
UNBLOCK_INPUT will read it later; now, avoid infinite loop.
0 means there was no keyboard input available. */
if (nread <= 0)
break;
}
-#ifdef HAVE_NS
- --handling_signal;
#endif
}
-#endif /* SYNC_INPUT || SIGIO */
-#ifdef SYNC_INPUT
void
process_pending_signals (void)
{
- if (interrupt_input_pending)
- handle_async_input ();
+ pending_signals = 0;
+ handle_async_input ();
do_pending_atimers ();
}
-#endif
-#ifdef SIGIO /* for entire page */
-/* Note SIGIO has been undef'd if FIONREAD is missing. */
+/* Undo any number of BLOCK_INPUT calls down to level LEVEL,
+ and also (if the level is now 0) reinvoke any pending signal. */
-static void
-input_available_signal (int signo)
+void
+unblock_input_to (int level)
{
- /* Must preserve main program's value of errno. */
- int old_errno = errno;
- SIGNAL_THREAD_CHECK (signo);
+ interrupt_input_blocked = level;
+ if (level == 0)
+ {
+ if (pending_signals)
+ process_pending_signals ();
+ }
+ else if (level < 0)
+ emacs_abort ();
+}
-#ifdef SYNC_INPUT
- interrupt_input_pending = 1;
- pending_signals = 1;
-#endif
+/* End critical section.
- if (input_available_clear_time)
- EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+ If doing signal-driven input, and a signal came in when input was
+ blocked, reinvoke the signal handler now to deal with it. */
-#ifndef SYNC_INPUT
- handle_async_input ();
-#endif
+void
+unblock_input (void)
+{
+ unblock_input_to (interrupt_input_blocked - 1);
+}
+
+/* Undo any number of BLOCK_INPUT calls,
+ and also reinvoke any pending signal. */
- errno = old_errno;
+void
+totally_unblock_input (void)
+{
+ unblock_input_to (0);
}
-#endif /* SIGIO */
-/* Send ourselves a SIGIO.
+#ifdef USABLE_SIGIO
- This function exists so that the UNBLOCK_INPUT macro in
- blockinput.h can have some way to take care of input we put off
- dealing with, without assuming that every file which uses
- UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
void
-reinvoke_input_signal (void)
+handle_input_available_signal (int sig)
{
-#ifdef SIGIO
- handle_async_input ();
-#endif
+ pending_signals = 1;
+
+ if (input_available_clear_time)
+ *input_available_clear_time = make_emacs_time (0, 0);
}
+static void
+deliver_input_available_signal (int sig)
+{
+ deliver_process_signal (sig, handle_input_available_signal);
+}
+#endif /* USABLE_SIGIO */
\f
/* User signal events. */
void
add_user_signal (int sig, const char *name)
{
+ struct sigaction action;
struct user_signal_info *p;
for (p = user_signals; p; p = p->next)
/* Already added. */
return;
- p = xmalloc (sizeof (struct user_signal_info));
+ p = xmalloc (sizeof *p);
p->sig = sig;
p->name = xstrdup (name);
p->npending = 0;
p->next = user_signals;
user_signals = p;
- signal (sig, handle_user_signal);
+ emacs_sigaction_init (&action, deliver_user_signal);
+ sigaction (sig, &action, 0);
}
static void
handle_user_signal (int sig)
{
- int old_errno = errno;
struct user_signal_info *p;
const char *special_event_name = NULL;
- SIGNAL_THREAD_CHECK (sig);
-
if (SYMBOLP (Vdebug_on_event))
special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event));
for (p = user_signals; p; p = p->next)
if (p->sig == sig)
{
- if (special_event_name &&
- strcmp (special_event_name, p->name) == 0)
+ if (special_event_name
+ && strcmp (special_event_name, p->name) == 0)
{
/* Enter the debugger in many ways. */
debug_on_next_call = 1;
}
p->npending++;
-#ifdef SIGIO
+#ifdef USABLE_SIGIO
if (interrupt_input)
- kill (getpid (), SIGIO);
+ handle_input_available_signal (sig);
else
#endif
{
/* Tell wait_reading_process_output that it needs to wake
up and look around. */
if (input_available_clear_time)
- EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+ *input_available_clear_time = make_emacs_time (0, 0);
}
break;
}
+}
- errno = old_errno;
+static void
+deliver_user_signal (int sig)
+{
+ deliver_process_signal (sig, handle_user_signal);
}
static char *
return NULL;
}
-static int
+static void
store_user_signal_events (void)
{
struct user_signal_info *p;
struct input_event buf;
- int nstored = 0;
+ bool buf_initialized = 0;
for (p = user_signals; p; p = p->next)
if (p->npending > 0)
{
- SIGMASKTYPE mask;
-
- if (nstored == 0)
+ if (! buf_initialized)
{
memset (&buf, 0, sizeof buf);
buf.kind = USER_SIGNAL_EVENT;
buf.frame_or_window = selected_frame;
+ buf_initialized = 1;
}
- nstored += p->npending;
- mask = sigblock (sigmask (p->sig));
do
{
buf.code = p->sig;
p->npending--;
}
while (p->npending > 0);
- sigsetmask (mask);
}
-
- return nstored;
}
\f
if (!label)
return 0;
else if (strlen (label) > 3
- && strncmp (label, "--", 2) == 0
+ && memcmp (label, "--", 2) == 0
&& label[2] != '-')
{
int i;
if (!NILP (Voverriding_local_map_menu_flag))
{
/* Yes, use them (if non-nil) as well as the global map. */
- maps = (Lisp_Object *) alloca (3 * sizeof (maps[0]));
+ maps = alloca (3 * sizeof (maps[0]));
nmaps = 0;
if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
Lisp_Object tem;
ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
- maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
+ maps = alloca ((nminor + 3) * sizeof *maps);
nmaps = 0;
if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
maps[nmaps++] = tem;
tem2 = AREF (menu_bar_items_vector, i + 2);
tem3 = AREF (menu_bar_items_vector, i + 3);
if (end > i + 4)
- memmove (&AREF (menu_bar_items_vector, i),
- &AREF (menu_bar_items_vector, i + 4),
- (end - i - 4) * sizeof (Lisp_Object));
+ memmove (aref_addr (menu_bar_items_vector, i),
+ aref_addr (menu_bar_items_vector, i + 4),
+ (end - i - 4) * word_size);
ASET (menu_bar_items_vector, end - 4, tem0);
ASET (menu_bar_items_vector, end - 3, tem1);
ASET (menu_bar_items_vector, end - 2, tem2);
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++;
- ASET (menu_bar_items_vector, i, Qnil), i++;
- ASET (menu_bar_items_vector, i, Qnil), i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
+ ASET (menu_bar_items_vector, i, Qnil); i++;
menu_bar_items_index = i;
}
if (EQ (key, AREF (menu_bar_items_vector, i)))
{
if (menu_bar_items_index > i + 4)
- memmove (&AREF (menu_bar_items_vector, i),
- &AREF (menu_bar_items_vector, i + 4),
- (menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
+ memmove (aref_addr (menu_bar_items_vector, i),
+ aref_addr (menu_bar_items_vector, i + 4),
+ (menu_bar_items_index - i - 4) * word_size);
menu_bar_items_index -= 4;
}
}
if (i + 4 > ASIZE (menu_bar_items_vector))
menu_bar_items_vector = larger_vector (menu_bar_items_vector, 4, -1);
/* Add this item. */
- ASET (menu_bar_items_vector, i, key), i++;
+ ASET (menu_bar_items_vector, i, key); i++;
ASET (menu_bar_items_vector, i,
- AREF (item_properties, ITEM_PROPERTY_NAME)), i++;
- ASET (menu_bar_items_vector, i, Fcons (item, Qnil)), i++;
- ASET (menu_bar_items_vector, i, make_number (0)), i++;
+ AREF (item_properties, ITEM_PROPERTY_NAME)); i++;
+ ASET (menu_bar_items_vector, i, Fcons (item, Qnil)); i++;
+ ASET (menu_bar_items_vector, i, make_number (0)); i++;
menu_bar_items_index = i;
}
/* We did find an item for this KEY. Add ITEM to its list of maps. */
/* If the command is an alias for another
(such as lmenu.el set it up), check if the
original command matches the cached command. */
- && !(SYMBOLP (def) && EQ (tem, XSYMBOL (def)->function))))
+ && !(SYMBOLP (def)
+ && EQ (tem, XSYMBOL (def)->function))))
keys = Qnil;
}
if (!NILP (Voverriding_local_map_menu_flag))
{
/* Yes, use them (if non-nil) as well as the global map. */
- maps = (Lisp_Object *) alloca (3 * sizeof (maps[0]));
+ maps = alloca (3 * sizeof *maps);
nmaps = 0;
if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
Lisp_Object tem;
ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
- maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
+ maps = alloca ((nminor + 3) * sizeof *maps);
nmaps = 0;
if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
maps[nmaps++] = tem;
if (ntool_bar_items > i + TOOL_BAR_ITEM_NSLOTS)
memmove (v, v + TOOL_BAR_ITEM_NSLOTS,
((ntool_bar_items - i - TOOL_BAR_ITEM_NSLOTS)
- * sizeof (Lisp_Object)));
+ * word_size));
ntool_bar_items -= TOOL_BAR_ITEM_NSLOTS;
break;
}
UNGCPRO;
}
+/* Access slot with index IDX of vector tool_bar_item_properties. */
+#define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
+static inline void
+set_prop (ptrdiff_t idx, Lisp_Object val)
+{
+ ASET (tool_bar_item_properties, idx, val);
+}
+
/* 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
static int
parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
{
- /* Access slot with index IDX of vector tool_bar_item_properties. */
-#define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
-
Lisp_Object filter = Qnil;
Lisp_Object caption;
int i, have_label = 0;
if (VECTORP (tool_bar_item_properties))
{
for (i = 0; i < TOOL_BAR_ITEM_NSLOTS; ++i)
- PROP (i) = Qnil;
+ set_prop (i, Qnil);
}
else
tool_bar_item_properties
= Fmake_vector (make_number (TOOL_BAR_ITEM_NSLOTS), Qnil);
/* Set defaults. */
- PROP (TOOL_BAR_ITEM_KEY) = key;
- PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt;
+ set_prop (TOOL_BAR_ITEM_KEY, key);
+ set_prop (TOOL_BAR_ITEM_ENABLED_P, Qt);
/* Get the caption of the item. If the caption is not a string,
evaluate it to get a string. If we don't get a string, skip this
if (!STRINGP (caption))
return 0;
}
- PROP (TOOL_BAR_ITEM_CAPTION) = caption;
+ set_prop (TOOL_BAR_ITEM_CAPTION, caption);
/* If the rest following the caption is not a list, the menu item is
either a separator, or invalid. */
{
if (menu_separator_name_p (SSDATA (caption)))
{
- PROP (TOOL_BAR_ITEM_TYPE) = Qt;
+ set_prop (TOOL_BAR_ITEM_TYPE, Qt);
#if !defined (USE_GTK) && !defined (HAVE_NS)
/* If we use build_desired_tool_bar_string to render the
tool bar, the separator is rendered as an image. */
}
/* Store the binding. */
- PROP (TOOL_BAR_ITEM_BINDING) = XCAR (item);
+ set_prop (TOOL_BAR_ITEM_BINDING, XCAR (item));
item = XCDR (item);
/* Ignore cached key binding, if any. */
{
/* `:enable FORM'. */
if (!NILP (Venable_disabled_menus_and_buttons))
- PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt;
+ set_prop (TOOL_BAR_ITEM_ENABLED_P, Qt);
else
- PROP (TOOL_BAR_ITEM_ENABLED_P) = value;
+ set_prop (TOOL_BAR_ITEM_ENABLED_P, value);
}
else if (EQ (ikey, QCvisible))
{
}
else if (EQ (ikey, QChelp))
/* `:help HELP-STRING'. */
- PROP (TOOL_BAR_ITEM_HELP) = value;
+ set_prop (TOOL_BAR_ITEM_HELP, value);
else if (EQ (ikey, QCvert_only))
/* `:vert-only t/nil'. */
- PROP (TOOL_BAR_ITEM_VERT_ONLY) = value;
+ set_prop (TOOL_BAR_ITEM_VERT_ONLY, value);
else if (EQ (ikey, QClabel))
{
const char *bad_label = "!!?GARBLED ITEM?!!";
/* `:label LABEL-STRING'. */
- PROP (TOOL_BAR_ITEM_LABEL) = STRINGP (value)
- ? value
- : build_string (bad_label);
+ set_prop (TOOL_BAR_ITEM_LABEL,
+ STRINGP (value) ? value : build_string (bad_label));
have_label = 1;
}
else if (EQ (ikey, QCfilter))
selected = XCDR (value);
if (EQ (type, QCtoggle) || EQ (type, QCradio))
{
- PROP (TOOL_BAR_ITEM_SELECTED_P) = selected;
- PROP (TOOL_BAR_ITEM_TYPE) = type;
+ set_prop (TOOL_BAR_ITEM_SELECTED_P, selected);
+ set_prop (TOOL_BAR_ITEM_TYPE, type);
}
}
else if (EQ (ikey, QCimage)
|| (VECTORP (value) && ASIZE (value) == 4)))
/* Value is either a single image specification or a vector
of 4 such specifications for the different button states. */
- PROP (TOOL_BAR_ITEM_IMAGES) = value;
+ set_prop (TOOL_BAR_ITEM_IMAGES, value);
else if (EQ (ikey, QCrtl))
/* ':rtl STRING' */
- PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value;
+ set_prop (TOOL_BAR_ITEM_RTL_IMAGE, value);
}
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 = (char *) xmalloc (max_lbl + 1);
+ char *buf = xmalloc (max_lbl + 1);
Lisp_Object new_lbl;
ptrdiff_t caption_len = strlen (capt);
new_lbl = Fupcase_initials (build_string (label));
if (SCHARS (new_lbl) <= tool_bar_max_label_size)
- PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
+ set_prop (TOOL_BAR_ITEM_LABEL, new_lbl);
else
- PROP (TOOL_BAR_ITEM_LABEL) = make_string ("", 0);
+ set_prop (TOOL_BAR_ITEM_LABEL, empty_unibyte_string);
xfree (buf);
}
/* If got a filter apply it on binding. */
if (!NILP (filter))
- PROP (TOOL_BAR_ITEM_BINDING)
- = menu_item_eval_property (list2 (filter,
- list2 (Qquote,
- PROP (TOOL_BAR_ITEM_BINDING))));
+ set_prop (TOOL_BAR_ITEM_BINDING,
+ (menu_item_eval_property
+ (list2 (filter,
+ list2 (Qquote,
+ PROP (TOOL_BAR_ITEM_BINDING))))));
/* See if the binding is a keymap. Give up if it is. */
if (CONSP (get_keymap (PROP (TOOL_BAR_ITEM_BINDING), 0, 1)))
/* Enable or disable selection of item. */
if (!EQ (PROP (TOOL_BAR_ITEM_ENABLED_P), Qt))
- PROP (TOOL_BAR_ITEM_ENABLED_P)
- = menu_item_eval_property (PROP (TOOL_BAR_ITEM_ENABLED_P));
+ set_prop (TOOL_BAR_ITEM_ENABLED_P,
+ menu_item_eval_property (PROP (TOOL_BAR_ITEM_ENABLED_P)));
/* Handle radio buttons or toggle boxes. */
if (!NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)))
- PROP (TOOL_BAR_ITEM_SELECTED_P)
- = menu_item_eval_property (PROP (TOOL_BAR_ITEM_SELECTED_P));
+ set_prop (TOOL_BAR_ITEM_SELECTED_P,
+ menu_item_eval_property (PROP (TOOL_BAR_ITEM_SELECTED_P)));
return 1;
static void
append_tool_bar_item (void)
{
- Lisp_Object *to, *from;
ptrdiff_t incr =
(ntool_bar_items
- (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
/* Append entries from tool_bar_item_properties to the end of
tool_bar_items_vector. */
- to = XVECTOR (tool_bar_items_vector)->contents + ntool_bar_items;
- from = XVECTOR (tool_bar_item_properties)->contents;
- memcpy (to, from, TOOL_BAR_ITEM_NSLOTS * sizeof *to);
+ vcopy (tool_bar_items_vector, ntool_bar_items,
+ XVECTOR (tool_bar_item_properties)->contents, TOOL_BAR_ITEM_NSLOTS);
ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
}
read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
Lisp_Object prev_event, int *used_mouse_menu)
{
+#ifdef HAVE_MENUS
ptrdiff_t mapno;
+#endif
if (used_mouse_menu)
*used_mouse_menu = 0;
&& !EQ (XCAR (prev_event), Qtool_bar))
{
/* Display the menu and get the selection. */
- Lisp_Object *realmaps
- = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
+ Lisp_Object *realmaps = alloca (nmaps * sizeof *realmaps);
Lisp_Object value;
ptrdiff_t nmaps1 = 0;
if (width + 4 > read_char_minibuf_menu_width)
{
read_char_minibuf_menu_text
- = (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
+ = xrealloc (read_char_minibuf_menu_text, width + 4);
read_char_minibuf_menu_width = width + 4;
}
menu = read_char_minibuf_menu_text;
is not used on replay.
*/
orig_defn_macro = KVAR (current_kboard, defining_kbd_macro);
- KVAR (current_kboard, defining_kbd_macro) = Qnil;
+ kset_defining_kbd_macro (current_kboard, Qnil);
do
obj = read_char (commandflag, 0, 0, Qt, 0, NULL);
while (BUFFERP (obj));
- KVAR (current_kboard, defining_kbd_macro) = orig_defn_macro;
+ kset_defining_kbd_macro (current_kboard, orig_defn_macro);
if (!INTEGERP (obj))
return obj;
next = access_keymap (map, key, 1, 0, 1);
- /* Handle symbol with autoload definition. */
- if (SYMBOLP (next) && !NILP (Ffboundp (next))
- && CONSP (XSYMBOL (next)->function)
- && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
- do_autoload (XSYMBOL (next)->function, next);
-
/* Handle a symbol whose function definition is a keymap
or an array. */
if (SYMBOLP (next) && !NILP (Ffboundp (next))
&& (ARRAYP (XSYMBOL (next)->function)
|| KEYMAPP (XSYMBOL (next)->function)))
- next = XSYMBOL (next)->function;
+ next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil);
/* If the keymap gives a function, not an
array, then call the function with one arg and use
its value instead. */
- if (SYMBOLP (next) && !NILP (Ffboundp (next)) && do_funcall)
+ if (do_funcall && FUNCTIONP (next))
{
Lisp_Object tem;
tem = next;
/* Install the string STR as the beginning of the string of
echoing, so that it serves as a prompt for the next
character. */
- KVAR (current_kboard, echo_string) = prompt;
+ kset_echo_string (current_kboard, prompt);
current_kboard->echo_after_prompt = SCHARS (prompt);
echo_now ();
}
{
if (2 > nmaps_allocated)
{
- submaps = (Lisp_Object *) alloca (2 * sizeof (submaps[0]));
- defs = (Lisp_Object *) alloca (2 * sizeof (defs[0]));
+ submaps = alloca (2 * sizeof *submaps);
+ defs = alloca (2 * sizeof *defs);
nmaps_allocated = 2;
}
submaps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
{
if (2 > nmaps_allocated)
{
- submaps = (Lisp_Object *) alloca (2 * sizeof (submaps[0]));
- defs = (Lisp_Object *) alloca (2 * sizeof (defs[0]));
+ submaps = alloca (2 * sizeof *submaps);
+ defs = alloca (2 * sizeof *defs);
nmaps_allocated = 2;
}
submaps[nmaps++] = Voverriding_local_map;
if (total > nmaps_allocated)
{
- submaps = (Lisp_Object *) alloca (total * sizeof (submaps[0]));
- defs = (Lisp_Object *) alloca (total * sizeof (defs[0]));
+ submaps = alloca (total * sizeof *submaps);
+ defs = alloca (total * sizeof *defs);
nmaps_allocated = total;
}
if (!NILP (delayed_switch_frame))
{
- KVAR (interrupted_kboard, kbd_queue)
- = Fcons (delayed_switch_frame,
- KVAR (interrupted_kboard, kbd_queue));
+ kset_kbd_queue
+ (interrupted_kboard,
+ Fcons (delayed_switch_frame,
+ KVAR (interrupted_kboard, kbd_queue)));
delayed_switch_frame = Qnil;
}
while (t > 0)
- KVAR (interrupted_kboard, kbd_queue)
- = Fcons (keybuf[--t], KVAR (interrupted_kboard, kbd_queue));
+ kset_kbd_queue
+ (interrupted_kboard,
+ Fcons (keybuf[--t], KVAR (interrupted_kboard, kbd_queue)));
/* If the side queue is non-empty, ensure it begins with a
switch-frame, so we'll replay it in the right context. */
{
Lisp_Object frame;
XSETFRAME (frame, interrupted_frame);
- KVAR (interrupted_kboard, kbd_queue)
- = Fcons (make_lispy_switch_frame (frame),
- KVAR (interrupted_kboard, kbd_queue));
+ kset_kbd_queue
+ (interrupted_kboard,
+ Fcons (make_lispy_switch_frame (frame),
+ KVAR (interrupted_kboard, kbd_queue)));
}
mock_input = 0;
orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
&& current_buffer != starting_buffer)
{
GROW_RAW_KEYBUF;
- ASET (raw_keybuf, raw_keybuf_count, key), raw_keybuf_count++;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
keybuf[t++] = key;
mock_input = t;
Vquit_flag = Qnil;
&& BUFFERP (XWINDOW (window)->buffer)
&& XBUFFER (XWINDOW (window)->buffer) != current_buffer)
{
- ASET (raw_keybuf, raw_keybuf_count, key), raw_keybuf_count++;
+ ASET (raw_keybuf, raw_keybuf_count, key);
+ raw_keybuf_count++;
keybuf[t] = key;
mock_input = t + 1;
because we may get input from a subprocess which
wants to change the selected window and stuff (say,
emacsclient). */
- record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ record_unwind_current_buffer ();
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
{
prefixarg = KVAR (current_kboard, Vprefix_arg);
Vcurrent_prefix_arg = prefixarg;
- KVAR (current_kboard, Vprefix_arg) = Qnil;
+ kset_prefix_arg (current_kboard, Qnil);
}
else
prefixarg = Qnil;
struct gcpro gcpro1, gcpro2;
GCPRO2 (cmd, prefixarg);
- do_autoload (final, cmd);
+ Fautoload_do_load (final, cmd, Qnil);
UNGCPRO;
}
else
int
requeued_events_pending_p (void)
{
- return (!NILP (Vunread_command_events) || unread_command_char != -1);
+ return (!NILP (Vunread_command_events));
}
if there is a doubt, the value is t. */)
(void)
{
- if (!NILP (Vunread_command_events) || unread_command_char != -1
+ if (!NILP (Vunread_command_events)
|| !NILP (Vunread_post_input_method_events)
|| !NILP (Vunread_input_method_events))
return (Qt);
else
{
val = Fvector (NUM_RECENT_KEYS, keys);
- memcpy (XVECTOR (val)->contents, keys + recent_keys_index,
- (NUM_RECENT_KEYS - recent_keys_index) * sizeof (Lisp_Object));
- memcpy (XVECTOR (val)->contents + NUM_RECENT_KEYS - recent_keys_index,
- keys, recent_keys_index * sizeof (Lisp_Object));
+ vcopy (val, 0, keys + recent_keys_index,
+ NUM_RECENT_KEYS - recent_keys_index);
+ vcopy (val, NUM_RECENT_KEYS - recent_keys_index,
+ keys, recent_keys_index);
return val;
}
}
{
if (dribble)
{
- BLOCK_INPUT;
+ block_input ();
fclose (dribble);
- UNBLOCK_INPUT;
+ unblock_input ();
dribble = 0;
}
if (!NILP (file))
update_mode_lines++;
Vunread_command_events = Qnil;
- unread_command_char = -1;
discard_tty_input ();
Otherwise, tell QUIT to kill Emacs. */
static void
-interrupt_signal (int signalnum) /* If we don't have an argument, some */
- /* compilers complain in signal calls. */
+handle_interrupt_signal (int sig)
{
- /* Must preserve main program's value of errno. */
- int old_errno = errno;
- struct terminal *terminal;
-
- SIGNAL_THREAD_CHECK (signalnum);
-
/* See if we have an active terminal on our controlling tty. */
- terminal = get_named_tty ("/dev/tty");
+ struct terminal *terminal = get_named_tty ("/dev/tty");
if (!terminal)
{
/* If there are no frames there, let's pretend that we are a
from the controlling tty. */
internal_last_event_frame = terminal->display_info.tty->top_frame;
- handle_interrupt ();
+ handle_interrupt (1);
}
+}
- errno = old_errno;
+static void
+deliver_interrupt_signal (int sig)
+{
+ deliver_process_signal (sig, handle_interrupt_signal);
}
+
/* If Emacs is stuck because `inhibit-quit' is true, then keep track
of the number of times C-g has been requested. If C-g is pressed
enough times, then quit anyway. See bug#6585. */
-static int force_quit_count;
+static int volatile force_quit_count;
/* This routine is called at interrupt level in response to C-g.
non-nil, it stops the job right away. */
static void
-handle_interrupt (void)
+handle_interrupt (bool in_signal_handler)
{
char c;
/* XXX This code needs to be revised for multi-tty support. */
if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty"))
{
- /* If SIGINT isn't blocked, don't let us be interrupted by
- another SIGINT, it might be harmful due to non-reentrancy
- in I/O functions. */
- sigblock (sigmask (SIGINT));
+ if (! in_signal_handler)
+ {
+ /* If SIGINT isn't blocked, don't let us be interrupted by
+ a SIGINT. It might be harmful due to non-reentrancy
+ in I/O functions. */
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGINT);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ }
fflush (stdout);
reset_all_sys_modes ();
#endif /* not MSDOS */
fflush (stdout);
if (((c = getchar ()) & ~040) == 'Y')
- abort ();
+ emacs_abort ();
while (c != '\n') c = getchar ();
#ifdef MSDOS
printf ("\r\nContinuing...\r\n");
#endif /* not MSDOS */
fflush (stdout);
init_all_sys_modes ();
- sigfree ();
}
else
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
immediate_quit = 0;
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
saved = gl_state;
GCPRO4 (saved.object, saved.global_code,
saved.current_syntax_table, saved.old_prop);
Fsignal (Qquit, Qnil);
- /* FIXME: AFAIK, `quit' can never return, so this code is dead! */
gl_state = saved;
UNGCPRO;
}
else
{ /* Else request quit when it's safe. */
- if (NILP (Vquit_flag))
- force_quit_count = 0;
- if (++force_quit_count == 3)
+ int count = NILP (Vquit_flag) ? 1 : force_quit_count + 1;
+ force_quit_count = count;
+ if (count == 3)
{
immediate_quit = 1;
Vinhibit_quit = Qnil;
}
}
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+
/* TODO: The longjmp in this call throws the NS event loop integration off,
and it seems to do fine without this. Probably some attention
needs to be paid to the setting of waiting_for_input in
separate event loop thread like W32. */
#ifndef HAVE_NS
if (waiting_for_input && !echoing)
- quit_throw_to_read_char (1);
+ quit_throw_to_read_char (in_signal_handler);
#endif
}
if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
Fkill_emacs (Qnil);
- sigfree ();
/* Prevent another signal from doing this before we finish. */
clear_waiting_for_input ();
input_pending = 0;
Vunread_command_events = Qnil;
- unread_command_char = -1;
-#if 0 /* Currently, sit_for is called from read_char without turning
- off polling. And that can call set_waiting_for_input.
- It seems to be harmless. */
-#ifdef POLL_FOR_INPUT
- /* May be > 1 if in recursive minibuffer. */
- if (poll_suppress_count == 0)
- abort ();
-#endif
-#endif
if (FRAMEP (internal_last_event_frame)
&& !EQ (internal_last_event_frame, selected_frame))
do_switch_frame (make_lispy_switch_frame (internal_last_event_frame),
0, 0, Qnil);
- _longjmp (getcjmp, 1);
+ sys_longjmp (getcjmp, 1);
}
\f
DEFUN ("set-input-interrupt-mode", Fset_input_interrupt_mode,
(Lisp_Object interrupt)
{
int new_interrupt_input;
-#ifdef SIGIO
-/* Note SIGIO has been undef'd if FIONREAD is missing. */
+#ifdef USABLE_SIGIO
#ifdef HAVE_X_WINDOWS
if (x_display_list != NULL)
{
else
#endif /* HAVE_X_WINDOWS */
new_interrupt_input = !NILP (interrupt);
-#else /* not SIGIO */
+#else /* not USABLE_SIGIO */
new_interrupt_input = 0;
-#endif /* not SIGIO */
+#endif /* not USABLE_SIGIO */
if (new_interrupt_input != interrupt_input)
{
if (WINDOWP (frame_or_window))
{
- struct window *w;
+ struct window *w = decode_live_window (frame_or_window);
- CHECK_LIVE_WINDOW (frame_or_window);
-
- w = XWINDOW (frame_or_window);
XSETINT (x, (XINT (x)
+ WINDOW_LEFT_EDGE_X (w)
+ (NILP (whole)
void
init_kboard (KBOARD *kb)
{
- KVAR (kb, Voverriding_terminal_local_map) = Qnil;
- KVAR (kb, Vlast_command) = Qnil;
- KVAR (kb, Vreal_last_command) = Qnil;
- KVAR (kb, Vkeyboard_translate_table) = Qnil;
- KVAR (kb, Vlast_repeatable_command) = Qnil;
- KVAR (kb, Vprefix_arg) = Qnil;
- KVAR (kb, Vlast_prefix_arg) = Qnil;
- KVAR (kb, kbd_queue) = Qnil;
+ kset_overriding_terminal_local_map (kb, Qnil);
+ kset_last_command (kb, Qnil);
+ kset_real_last_command (kb, Qnil);
+ kset_keyboard_translate_table (kb, Qnil);
+ kset_last_repeatable_command (kb, Qnil);
+ kset_prefix_arg (kb, Qnil);
+ kset_last_prefix_arg (kb, Qnil);
+ kset_kbd_queue (kb, Qnil);
kb->kbd_queue_has_data = 0;
kb->immediate_echo = 0;
- KVAR (kb, echo_string) = Qnil;
+ kset_echo_string (kb, Qnil);
kb->echo_after_prompt = -1;
kb->kbd_macro_buffer = 0;
kb->kbd_macro_bufsize = 0;
- KVAR (kb, defining_kbd_macro) = Qnil;
- KVAR (kb, Vlast_kbd_macro) = Qnil;
+ kset_defining_kbd_macro (kb, Qnil);
+ kset_last_kbd_macro (kb, Qnil);
kb->reference_count = 0;
- KVAR (kb, Vsystem_key_alist) = Qnil;
- KVAR (kb, system_key_syms) = Qnil;
- KVAR (kb, Vwindow_system) = Qt; /* Unset. */
- KVAR (kb, Vinput_decode_map) = Fmake_sparse_keymap (Qnil);
- KVAR (kb, Vlocal_function_key_map) = Fmake_sparse_keymap (Qnil);
+ kset_system_key_alist (kb, Qnil);
+ kset_system_key_syms (kb, Qnil);
+ kset_window_system (kb, Qt); /* Unset. */
+ kset_input_decode_map (kb, Fmake_sparse_keymap (Qnil));
+ kset_local_function_key_map (kb, Fmake_sparse_keymap (Qnil));
Fset_keymap_parent (KVAR (kb, Vlocal_function_key_map), Vfunction_key_map);
- KVAR (kb, Vdefault_minibuffer_frame) = Qnil;
+ kset_default_minibuffer_frame (kb, Qnil);
}
/*
for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard)
if (*kbp == NULL)
- abort ();
+ emacs_abort ();
*kbp = kb->next_kboard;
/* Prevent a dangling reference to KB. */
current_kboard = FRAME_KBOARD (XFRAME (selected_frame));
single_kboard = 0;
if (current_kboard == kb)
- abort ();
+ emacs_abort ();
}
wipe_kboard (kb);
void
init_keyboard (void)
{
- /* This is correct before outermost invocation of the editor loop */
+ /* This is correct before outermost invocation of the editor loop. */
command_loop_level = -1;
immediate_quit = 0;
quit_char = Ctl ('g');
Vunread_command_events = Qnil;
- unread_command_char = -1;
- EMACS_SET_INVALID_TIME (timer_idleness_start_time);
+ timer_idleness_start_time = invalid_emacs_time ();
total_keys = 0;
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
#endif
input_pending = 0;
interrupt_input_blocked = 0;
- interrupt_input_pending = 0;
-#ifdef SYNC_INPUT
pending_signals = 0;
-#endif
/* This means that command_loop_1 won't try to select anything the first
time through. */
init_kboard (current_kboard);
/* A value of nil for Vwindow_system normally means a tty, but we also use
it for the initial terminal since there is no window system there. */
- KVAR (current_kboard, Vwindow_system) = Qnil;
+ kset_window_system (current_kboard, Qnil);
if (!noninteractive)
{
/* Before multi-tty support, these handlers used to be installed
only if the current session was a tty session. Now an Emacs
session may have multiple display types, so we always handle
- SIGINT. There is special code in interrupt_signal to exit
+ SIGINT. There is special code in handle_interrupt_signal to exit
Emacs on SIGINT when there are no termcap frames on the
controlling terminal. */
- signal (SIGINT, interrupt_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_interrupt_signal);
+ sigaction (SIGINT, &action, 0);
#ifndef DOS_NT
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
SIGQUIT and we can't tell which one it will give us. */
- signal (SIGQUIT, interrupt_signal);
+ sigaction (SIGQUIT, &action, 0);
#endif /* not DOS_NT */
}
-/* Note SIGIO has been undef'd if FIONREAD is missing. */
-#ifdef SIGIO
+#ifdef USABLE_SIGIO
if (!noninteractive)
- signal (SIGIO, input_available_signal);
-#endif /* SIGIO */
+ {
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_input_available_signal);
+ sigaction (SIGIO, &action, 0);
+ }
+#endif
/* Use interrupt input by default, if it works and noninterrupt input
has deficiencies. */
interrupt_input = 0;
#endif
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
dribble = 0;
if (keyboard_init_hook)
pending_funcalls = Qnil;
staticpro (&pending_funcalls);
- Vlispy_mouse_stem = make_pure_c_string ("mouse");
+ Vlispy_mouse_stem = build_pure_c_string ("mouse");
staticpro (&Vlispy_mouse_stem);
/* Tool-bars. */
An element of the form (t . EVENT) forces EVENT to be added to that list. */);
Vunread_command_events = Qnil;
- DEFVAR_INT ("unread-command-char", unread_command_char,
- doc: /* If not -1, an object to be read as next command input event. */);
-
DEFVAR_LISP ("unread-post-input-method-events", Vunread_post_input_method_events,
doc: /* List of events to be processed as input by input methods.
These events are processed before `unread-command-events'
Vdebug_on_event = intern_c_string ("sigusr2");
/* Create the initial keyboard. */
- initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ initial_kboard = xmalloc (sizeof *initial_kboard);
init_kboard (initial_kboard);
/* Vwindow_system is left at t for now. */
initial_kboard->next_kboard = all_kboards;
initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
"ignore");
+#if defined (WINDOWSNT)
+ initial_define_lispy_key (Vspecial_event_map, "language-change",
+ "ignore");
+#endif
}
/* Mark the pointers in the kboard objects.