* nt/inc/ms-w32.h (emacs_raise): New macro.
* src/alloc.c (die):
* src/sysdep.c (emacs_abort) [HAVE_NTGUI]:
Avoid recursive loop if there's a fatal error in the function itself.
* src/atimer.c (pending_atimers):
* src/blockinput.h: Don't include "atimer.h"; no longer needed.
(interrupt_input_pending): Remove. All uses removed.
pending_signals now counts both atimers and ordinary interrupts.
This is less racy than having three separate pending-signal flags.
(block_input, unblock_input, totally_unblock_input, unblock_input_to)
(input_blocked_p):
Rename from their upper-case counterparts BLOCK_INPUT,
UNBLOCK_INPUT, TOTALLY_UNBLOCK_INPUT, UNBLOCK_INPUT_TO,
INPUT_BLOCKED_P, and turn into functions. All uses changed.
This makes it easier to access volatile variables more accurately.
(BLOCK_INPUT_RESIGNAL): Remove. All uses replaced by unblock_input ().
(input_blocked_p): Prefer this to 'interrupt_input_blocked', as
that's more reliable if the code is buggy and sets
interrupt_input_blocked to a negative value. All uses changed.
* src/atimer.c (deliver_alarm_signal):
Remove. No need to deliver this to the parent; any thread can
handle this signal now. All uses replaced by underlying handler.
* src/atimer.c (turn_on_atimers):
* src/dispnew.c (handle_window_change_signal):
* src/emacs.c (handle_danger_signal):
* src/keyboard.c (kbd_buffer_get_event):
Don't reestablish signal handler; not needed with sigaction.
* src/blockinput.h (UNBLOCK_INPUT_TO, TOTALLY_UNBLOCK_INPUT)
(UNBLOCK_INPUT_TO):
Rework to avoid unnecessary accesses to volatile variables.
(UNBLOCK_INPUT_TO): Now a function.
(totally_unblock_input, unblock_input): New decls.
* src/data.c (handle_arith_signal, deliver_arith_signal): Move to sysdep.c
(init_data): Remove. Necessary stuff now done in init_signal.
* src/emacs.c, src/xdisp.c: Include "atimer.h", since we invoke atimer functions.
* src/emacs.c (handle_fatal_signal, deliver_fatal_signal): Move to sysdep.c.
(fatal_error_code): Remove; no longer needed.
(terminate_due_to_signal): Rename from fatal_error_backtrace, since
it doesn't always backtrace. All uses changed. No need to reset
signal to default, since sigaction and/or die does that for us now.
Use emacs_raise (FOO), not kill (getpid (), FOO).
(main): Check more-accurately whether we're dumping.
Move fatal-error setup to sysdep.c
* src/floatfns.c: Do not include "syssignal.h"; no longer needed.
* src/gtkutil.c (xg_get_file_name, xg_get_font):
Remove no-longer-needed signal-mask manipulation.
* src/keyboard.c, src/process.c (POLL_FOR_INPUT):
Don't depend on USE_ASYNC_EVENTS, a symbol that is never defined.
* src/keyboard.c (read_avail_input): Remove.
All uses replaced by gobble_input.
(Ftop_level): Use TOTALLY_UNBLOCK_INPUT rather than open code.
(kbd_buffer_store_event_hold, gobble_input):
(record_asynch_buffer_change) [USABLE_SIGIO]:
(store_user_signal_events):
No need to mess with signal mask.
(gobble_input): If blocking input and there are terminals, simply
set pending_signals to 1 and return. All hooks changed to not
worry about whether input is blocked.
(process_pending_signals): Clear pending_signals before processing
them, in case a signal comes in while we're processing.
By convention callers now test pending_signals before calling us.
(UNBLOCK_INPUT_TO, unblock_input, totally_unblock_input):
New functions, to support changes to blockinput.h.
(handle_input_available_signal): Now extern.
(reinvoke_input_signal): Remove. All uses replaced by
handle_async_input.
(quit_count): Now volatile, since a signal handler uses it.
(handle_interrupt): Now takes bool IN_SIGNAL_HANDLER as arg. All
callers changed. Block SIGINT only if not already blocked.
Clear sigmask reliably, even if Fsignal returns, which it can.
Omit unnecessary accesses to volatile var.
(quit_throw_to_read_char): No need to restore sigmask.
* src/keyboard.c (gobble_input, handle_user_signal):
* src/process.c (wait_reading_process_output):
Call signal-handling code rather than killing ourselves.
* src/lisp.h: Include <float.h>, for...
(IEEE_FLOATING_POINT): New macro, moved here to avoid duplication.
(pending_signals): Now volatile.
(syms_of_data): Now const if IEEE floating point.
(handle_input_available_signal) [USABLE_SIGIO]:
(terminate_due_to_signal, record_child_status_change): New decls.
* src/process.c (create_process): Avoid disaster if memory is exhausted
while we're processing a vfork, by tightening the critical section
around the vfork.
(send_process_frame, process_sent_to, handle_pipe_signal)
(deliver_pipe_signal): Remove. No longer needed, as Emacs now
ignores SIGPIPE.
(send_process): No need for setjmp/longjmp any more, since the
SIGPIPE stuff is now gone. Instead, report an error if errno
is EPIPE.
(record_child_status_change): Now extern. PID and W are now args.
Return void, not bool. All callers changed.
* src/sysdep.c (wait_debugging) [(BSD_SYSTEM || HPUX) && !defined (__GNU__)]:
Remove. All uses removed. This bug should be fixed now in a
different way.
(wait_for_termination_1): Use waitpid rather than sigsuspend,
and record the child status change directly. This avoids the
need to futz with the signal mask.
(process_fatal_action): Move here from emacs.c.
(emacs_sigaction_flags): New function, containing
much of what used to be in emacs_sigaction_init.
(emacs_sigaction_init): Use it. Block nonfatal system signals that are
caught by emacs, to make races less likely.
(deliver_process_signal): Rename from handle_on_main_thread.
All uses changed.
(BACKTRACE_LIMIT_MAX): Now at top level.
(thread_backtrace_buffer, threadback_backtrace_pointers):
New static vars.
(deliver_thread_signal, deliver_fatal_thread_signal):
New functions, for more-accurate delivery of thread-specific signals.
(handle_fatal_signal, deliver_fatal_signal): Move here from emacs.c.
(deliver_arith_signal): Handle in this thread, not
in the main thread, since it's triggered by this thread.
(maybe_fatal_sig): New function.
(init_signals): New arg DUMPING so that we can be more accurate
about whether we're dumping. Caller changed.
Treat thread-specific signals differently from process-general signals.
Block all signals while handling fatal error; that's safer.
xsignal from SIGFPE only on non-IEEE hosts, treating it as fatal
on IEEE hosts.
When batch, ignore SIGHUP, SIGINT, SIGTERM if they were already ignored.
Ignore SIGPIPE unless batch.
(emacs_backtrace): Output backtrace for the appropriate thread,
which is not necessarily the main thread.
* src/syssignal.h: Include <stdbool.h>.
(emacs_raise): New macro.
* src/xterm.c (x_connection_signal): Remove; no longer needed
now that we use sigaction.
(x_connection_closed): No need to mess with sigmask now.
(x_initialize): No need to reset SIGPIPE handler here, since
init_signals does this for us now.
Fixes: debbugs:12471
+2012-09-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify and avoid signal-handling races (Bug#12471).
+ * inc/ms-w32.h (emacs_raise): New macro.
+
2012-09-18 Eli Zaretskii <eliz@gnu.org>
* configure.bat: Include stddef.h before gif_lib.h, to have size_t
#define kill sys_kill
#define signal sys_signal
+/* Internal signals. */
+#define emacs_raise(sig) kill (getpid (), sig)
+
/* termcap.c calls that are emulated. */
#define tputs sys_tputs
#define tgetstr sys_tgetstr
+2012-09-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Simplify and avoid signal-handling races (Bug#12471).
+ * alloc.c (die):
+ * sysdep.c (emacs_abort) [HAVE_NTGUI]:
+ Avoid recursive loop if there's a fatal error in the function itself.
+ * atimer.c (pending_atimers):
+ * blockinput.h: Don't include "atimer.h"; no longer needed.
+ (interrupt_input_pending): Remove. All uses removed.
+ pending_signals now counts both atimers and ordinary interrupts.
+ This is less racy than having three separate pending-signal flags.
+ (block_input, unblock_input, totally_unblock_input, unblock_input_to)
+ (input_blocked_p):
+ Rename from their upper-case counterparts BLOCK_INPUT,
+ UNBLOCK_INPUT, TOTALLY_UNBLOCK_INPUT, UNBLOCK_INPUT_TO,
+ INPUT_BLOCKED_P, and turn into functions. All uses changed.
+ This makes it easier to access volatile variables more accurately.
+ (BLOCK_INPUT_RESIGNAL): Remove. All uses replaced by unblock_input ().
+ (input_blocked_p): Prefer this to 'interrupt_input_blocked', as
+ that's more reliable if the code is buggy and sets
+ interrupt_input_blocked to a negative value. All uses changed.
+ * atimer.c (deliver_alarm_signal):
+ Remove. No need to deliver this to the parent; any thread can
+ handle this signal now. All uses replaced by underlying handler.
+ * atimer.c (turn_on_atimers):
+ * dispnew.c (handle_window_change_signal):
+ * emacs.c (handle_danger_signal):
+ * keyboard.c (kbd_buffer_get_event):
+ Don't reestablish signal handler; not needed with sigaction.
+ * blockinput.h (UNBLOCK_INPUT_TO, TOTALLY_UNBLOCK_INPUT)
+ (UNBLOCK_INPUT_TO):
+ Rework to avoid unnecessary accesses to volatile variables.
+ (UNBLOCK_INPUT_TO): Now a function.
+ (totally_unblock_input, unblock_input): New decls.
+ * data.c (handle_arith_signal, deliver_arith_signal): Move to sysdep.c
+ (init_data): Remove. Necessary stuff now done in init_signal.
+ * emacs.c, xdisp.c: Include "atimer.h", since we invoke atimer functions.
+ * emacs.c (handle_fatal_signal, deliver_fatal_signal): Move to sysdep.c.
+ (fatal_error_code): Remove; no longer needed.
+ (terminate_due_to_signal): Rename from fatal_error_backtrace, since
+ it doesn't always backtrace. All uses changed. No need to reset
+ signal to default, since sigaction and/or die does that for us now.
+ Use emacs_raise (FOO), not kill (getpid (), FOO).
+ (main): Check more-accurately whether we're dumping.
+ Move fatal-error setup to sysdep.c
+ * floatfns.c: Do not include "syssignal.h"; no longer needed.
+ * gtkutil.c (xg_get_file_name, xg_get_font):
+ Remove no-longer-needed signal-mask manipulation.
+ * keyboard.c, process.c (POLL_FOR_INPUT):
+ Don't depend on USE_ASYNC_EVENTS, a symbol that is never defined.
+ * keyboard.c (read_avail_input): Remove.
+ All uses replaced by gobble_input.
+ (Ftop_level): Use TOTALLY_UNBLOCK_INPUT rather than open code.
+ (kbd_buffer_store_event_hold, gobble_input):
+ (record_asynch_buffer_change) [USABLE_SIGIO]:
+ (store_user_signal_events):
+ No need to mess with signal mask.
+ (gobble_input): If blocking input and there are terminals, simply
+ set pending_signals to 1 and return. All hooks changed to not
+ worry about whether input is blocked.
+ (process_pending_signals): Clear pending_signals before processing
+ them, in case a signal comes in while we're processing.
+ By convention callers now test pending_signals before calling us.
+ (UNBLOCK_INPUT_TO, unblock_input, totally_unblock_input):
+ New functions, to support changes to blockinput.h.
+ (handle_input_available_signal): Now extern.
+ (reinvoke_input_signal): Remove. All uses replaced by
+ handle_async_input.
+ (quit_count): Now volatile, since a signal handler uses it.
+ (handle_interrupt): Now takes bool IN_SIGNAL_HANDLER as arg. All
+ callers changed. Block SIGINT only if not already blocked.
+ Clear sigmask reliably, even if Fsignal returns, which it can.
+ Omit unnecessary accesses to volatile var.
+ (quit_throw_to_read_char): No need to restore sigmask.
+ * keyboard.c (gobble_input, handle_user_signal):
+ * process.c (wait_reading_process_output):
+ Call signal-handling code rather than killing ourselves.
+ * lisp.h: Include <float.h>, for...
+ (IEEE_FLOATING_POINT): New macro, moved here to avoid duplication.
+ (pending_signals): Now volatile.
+ (syms_of_data): Now const if IEEE floating point.
+ (handle_input_available_signal) [USABLE_SIGIO]:
+ (terminate_due_to_signal, record_child_status_change): New decls.
+ * process.c (create_process): Avoid disaster if memory is exhausted
+ while we're processing a vfork, by tightening the critical section
+ around the vfork.
+ (send_process_frame, process_sent_to, handle_pipe_signal)
+ (deliver_pipe_signal): Remove. No longer needed, as Emacs now
+ ignores SIGPIPE.
+ (send_process): No need for setjmp/longjmp any more, since the
+ SIGPIPE stuff is now gone. Instead, report an error if errno
+ is EPIPE.
+ (record_child_status_change): Now extern. PID and W are now args.
+ Return void, not bool. All callers changed.
+ * sysdep.c (wait_debugging) [(BSD_SYSTEM || HPUX) && !defined (__GNU__)]:
+ Remove. All uses removed. This bug should be fixed now in a
+ different way.
+ (wait_for_termination_1): Use waitpid rather than sigsuspend,
+ and record the child status change directly. This avoids the
+ need to futz with the signal mask.
+ (process_fatal_action): Move here from emacs.c.
+ (emacs_sigaction_flags): New function, containing
+ much of what used to be in emacs_sigaction_init.
+ (emacs_sigaction_init): Use it. Block nonfatal system signals that are
+ caught by emacs, to make races less likely.
+ (deliver_process_signal): Rename from handle_on_main_thread.
+ All uses changed.
+ (BACKTRACE_LIMIT_MAX): Now at top level.
+ (thread_backtrace_buffer, threadback_backtrace_pointers):
+ New static vars.
+ (deliver_thread_signal, deliver_fatal_thread_signal):
+ New functions, for more-accurate delivery of thread-specific signals.
+ (handle_fatal_signal, deliver_fatal_signal): Move here from emacs.c.
+ (deliver_arith_signal): Handle in this thread, not
+ in the main thread, since it's triggered by this thread.
+ (maybe_fatal_sig): New function.
+ (init_signals): New arg DUMPING so that we can be more accurate
+ about whether we're dumping. Caller changed.
+ Treat thread-specific signals differently from process-general signals.
+ Block all signals while handling fatal error; that's safer.
+ xsignal from SIGFPE only on non-IEEE hosts, treating it as fatal
+ on IEEE hosts.
+ When batch, ignore SIGHUP, SIGINT, SIGTERM if they were already ignored.
+ Ignore SIGPIPE unless batch.
+ (emacs_backtrace): Output backtrace for the appropriate thread,
+ which is not necessarily the main thread.
+ * syssignal.h: Include <stdbool.h>.
+ (emacs_raise): New macro.
+ * xterm.c (x_connection_signal): Remove; no longer needed
+ now that we use sigaction.
+ (x_connection_closed): No need to mess with sigmask now.
+ (x_initialize): No need to reset SIGPIPE handler here, since
+ init_signals does this for us now.
+
2012-09-23 Jan Djärv <jan.h.d@swipnet.se>
* nsterm.m (ns_dumpglyphs_image): dr is a new rect to draw image into,
malloc_block_input (void)
{
if (block_input_in_memory_allocators)
- BLOCK_INPUT;
+ block_input ();
}
static void
malloc_unblock_input (void)
{
if (block_input_in_memory_allocators)
- UNBLOCK_INPUT;
+ unblock_input ();
}
# define MALLOC_BLOCK_INPUT malloc_block_input ()
# define MALLOC_UNBLOCK_INPUT malloc_unblock_input ()
if (garbage_collection_messages)
message1_nolog ("Garbage collecting...");
- BLOCK_INPUT;
+ block_input ();
shrink_regexp_cache ();
dump_zombies ();
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
check_cons_list ();
void
die (const char *msg, const char *file, int line)
{
+ signal (SIGABRT, SIG_DFL);
fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n",
file, line, msg);
- fatal_error_backtrace (SIGABRT, INT_MAX);
+ terminate_due_to_signal (SIGABRT, INT_MAX);
}
#endif
\f
static struct atimer *atimers;
-/* Non-zero means alarm signal handler has found ripe timers but
- interrupt_input_blocked was non-zero. In this case, timer
- functions are not called until the next UNBLOCK_INPUT because timer
- functions are expected to call X, and X cannot be assumed to be
- reentrant. */
-
-int pending_atimers;
-
/* Block/unblock SIGALRM. */
static void
static void
run_timers (void)
{
- EMACS_TIME now;
+ EMACS_TIME now = current_emacs_time ();
- while (atimers
- && (pending_atimers = interrupt_input_blocked) == 0
- && (now = current_emacs_time (),
- EMACS_TIME_LE (atimers->expiration, now)))
+ while (atimers && EMACS_TIME_LE (atimers->expiration, now))
{
- struct atimer *t;
-
- t = atimers;
+ struct atimer *t = atimers;
atimers = atimers->next;
t->fn (t);
}
}
- if (! atimers)
- pending_atimers = 0;
-
- if (pending_atimers)
- pending_signals = 1;
- else
- {
- pending_signals = interrupt_input_pending;
- set_alarm ();
- }
+ set_alarm ();
}
static void
handle_alarm_signal (int sig)
{
- pending_atimers = 1;
pending_signals = 1;
}
-static void
-deliver_alarm_signal (int sig)
-{
- handle_on_main_thread (sig, handle_alarm_signal);
-}
-
-/* Call alarm signal handler for pending timers. */
+/* Do pending timers. */
void
do_pending_atimers (void)
{
- if (pending_atimers)
+ if (atimers)
{
block_atimers ();
run_timers ();
turn_on_atimers (bool on)
{
if (on)
- {
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_alarm_signal);
- sigaction (SIGALRM, &action, 0);
- set_alarm ();
- }
+ set_alarm ();
else
alarm (0);
}
{
struct sigaction action;
free_atimers = stopped_atimers = atimers = NULL;
- pending_atimers = 0;
/* pending_signals is initialized in init_keyboard.*/
- emacs_sigaction_init (&action, deliver_alarm_signal);
+ emacs_sigaction_init (&action, handle_alarm_signal);
sigaction (SIGALRM, &action, 0);
}
#ifndef EMACS_BLOCKINPUT_H
#define EMACS_BLOCKINPUT_H
-#include "atimer.h"
+INLINE_HEADER_BEGIN
+#ifndef BLOCKINPUT_INLINE
+# define BLOCKINPUT_INLINE INLINE
+#endif
-/* When Emacs is using signal-driven input, the processing of those
- input signals can get pretty hairy. For example, when Emacs is
- running under X windows, handling an input signal can entail
- retrieving events from the X event queue, or making other X calls.
-
- If an input signal occurs while Emacs is in the midst of some
- non-reentrant code, and the signal processing invokes that same
- code, we lose. For example, malloc and the Xlib functions aren't
- usually re-entrant, and both are used by the X input signal handler
- - if we try to process an input signal in the midst of executing
- any of these functions, we'll lose.
+/* Emacs should avoid doing anything hairy in a signal handler, because
+ so many system functions are non-reentrant. For example, malloc
+ and the Xlib functions aren't usually re-entrant, so if they were
+ used by the SIGIO handler, we'd lose.
To avoid this, we make the following requirements:
- * Everyone must evaluate BLOCK_INPUT before entering these functions,
- and then call UNBLOCK_INPUT after performing them. Calls
- BLOCK_INPUT and UNBLOCK_INPUT may be nested.
+ * Everyone must evaluate BLOCK_INPUT before performing actions that
+ might conflict with a signal handler, and then call UNBLOCK_INPUT
+ after performing them. Calls BLOCK_INPUT and UNBLOCK_INPUT may be
+ nested.
* Any complicated interrupt handling code should test
- interrupt_input_blocked, and put off its work until later.
+ INPUT_BLOCKED_P, and put off its work until later.
* If the interrupt handling code wishes, it may set
- interrupt_input_pending to a non-zero value. If that flag is set
- when input becomes unblocked, UNBLOCK_INPUT will send a new SIGIO. */
-
-extern volatile int interrupt_input_blocked;
-
-/* Nonzero means an input interrupt has arrived
- during the current critical section. */
-extern int interrupt_input_pending;
+ pending_signals to a non-zero value. If that flag is set
+ when input becomes unblocked, UNBLOCK_INPUT will then read
+ input and process timers.
+ Historically, Emacs signal handlers did much more than they do now,
+ and this caused many BLOCK_INPUT calls to be sprinkled around the code.
+ FIXME: Remove calls that aren't needed now. */
-/* Non-zero means asynchronous timers should be run when input is
- unblocked. */
+extern volatile int interrupt_input_blocked;
-extern int pending_atimers;
+/* Begin critical section. */
+BLOCKINPUT_INLINE void
+block_input (void)
+{
+ interrupt_input_blocked++;
+}
-/* Begin critical section. */
-#define BLOCK_INPUT (interrupt_input_blocked++)
-
-/* 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.
-
- Always test interrupt_input_pending; that's not too expensive, and
- it'll never get set if we don't need to resignal. This is simpler
- than dealing here with every configuration option that might affect
- whether interrupt_input_pending can be nonzero. */
-
-#define UNBLOCK_INPUT \
- do \
- { \
- --interrupt_input_blocked; \
- if (interrupt_input_blocked == 0) \
- { \
- if (interrupt_input_pending) \
- reinvoke_input_signal (); \
- if (pending_atimers) \
- do_pending_atimers (); \
- } \
- else if (interrupt_input_blocked < 0) \
- emacs_abort (); \
- } \
- while (0)
-
-/* Undo any number of BLOCK_INPUT calls,
- and also reinvoke any pending signal. */
-
-#define TOTALLY_UNBLOCK_INPUT \
- do if (interrupt_input_blocked != 0) \
- { \
- interrupt_input_blocked = 1; \
- UNBLOCK_INPUT; \
- } \
- while (0)
-
-/* Undo any number of BLOCK_INPUT calls down to level LEVEL,
- and also (if the level is now 0) reinvoke any pending signal. */
-
-#define UNBLOCK_INPUT_TO(LEVEL) \
- do \
- { \
- interrupt_input_blocked = (LEVEL) + 1; \
- UNBLOCK_INPUT; \
- } \
- while (0)
-
-#define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT
+extern void unblock_input (void);
+extern void totally_unblock_input (void);
+extern void unblock_input_to (int);
/* In critical section ? */
-#define INPUT_BLOCKED_P (interrupt_input_blocked > 0)
-/* Defined in keyboard.c */
-extern void reinvoke_input_signal (void);
+BLOCKINPUT_INLINE bool
+input_blocked_p (void)
+{
+ return 0 < interrupt_input_blocked;
+}
+
+INLINE_HEADER_END
#endif /* EMACS_BLOCKINPUT_H */
b->indirections = 0;
BUF_GAP_SIZE (b) = 20;
- BLOCK_INPUT;
+ block_input ();
/* We allocate extra 1-byte at the tail and keep it always '\0' for
anchoring a search. */
alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
- UNBLOCK_INPUT;
+ unblock_input ();
if (! BUF_BEG_ADDR (b))
buffer_memory_full (BUF_GAP_SIZE (b) + 1);
bset_name (b, Qnil);
- BLOCK_INPUT;
+ block_input ();
if (b->base_buffer)
{
/* Notify our base buffer that we don't share the text anymore. */
b->width_run_cache = 0;
}
bset_width_table (b, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
bset_undo_list (b, Qnil);
/* Run buffer-list-update-hook. */
{
void *p;
- BLOCK_INPUT;
+ block_input ();
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_alloc ((void **) &b->text->beg, nbytes);
#elif defined REL_ALLOC
if (p == NULL)
{
- UNBLOCK_INPUT;
+ unblock_input ();
memory_full (nbytes);
}
b->text->beg = (unsigned char *) p;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Enlarge buffer B's text buffer by DELTA bytes. DELTA < 0 means
void *p;
ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
+ delta);
- BLOCK_INPUT;
+ block_input ();
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_realloc ((void **) &b->text->beg, nbytes);
#elif defined REL_ALLOC
if (p == NULL)
{
- UNBLOCK_INPUT;
+ unblock_input ();
memory_full (nbytes);
}
BUF_BEG_ADDR (b) = (unsigned char *) p;
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
free_buffer_text (struct buffer *b)
{
- BLOCK_INPUT;
+ block_input ();
#if defined USE_MMAP_FOR_BUFFERS
mmap_free ((void **) &b->text->beg);
#endif
BUF_BEG_ADDR (b) = NULL;
- UNBLOCK_INPUT;
+ unblock_input ();
}
0, current_dir);
#else /* not WINDOWSNT */
- BLOCK_INPUT;
+ block_input ();
/* vfork, and prevent local vars from being clobbered by the vfork. */
{
setpgrp (pid, pid);
#endif /* USG */
- /* GConf causes us to ignore SIGPIPE, make sure it is restored
- in the child. */
+ /* Emacs ignores SIGPIPE, but the child should not. */
signal (SIGPIPE, SIG_DFL);
child_setup (filefd, fd1, fd_error, (char **) new_argv,
0, current_dir);
}
- UNBLOCK_INPUT;
+ unblock_input ();
#endif /* not WINDOWSNT */
{
int fd;
- BLOCK_INPUT;
+ block_input ();
fd = mkstemp (tempfile);
- UNBLOCK_INPUT;
+ unblock_input ();
if (fd == -1)
report_file_error ("Failed to open temporary file",
Fcons (build_string (tempfile), Qnil));
#include "font.h"
#include "keymap.h"
-#include <float.h>
-#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
- && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
-#define IEEE_FLOATING_POINT 1
-#else
-#define IEEE_FLOATING_POINT 0
-#endif
-
Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
static Lisp_Object Qsubr;
Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
Vmost_negative_fixnum = make_number (MOST_NEGATIVE_FIXNUM);
XSYMBOL (intern_c_string ("most-negative-fixnum"))->constant = 1;
}
-
-static _Noreturn void
-handle_arith_signal (int sig)
-{
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
- xsignal0 (Qarith_error);
-}
-
-static void
-deliver_arith_signal (int sig)
-{
- handle_on_main_thread (sig, handle_arith_signal);
-}
-
-void
-init_data (void)
-{
- struct sigaction action;
- /* Don't do this if just dumping out.
- We don't want to call `signal' in this case
- so that we don't have trouble with dumping
- signal-delivering routines in an inconsistent state. */
-#ifndef CANNOT_DUMP
- if (!initialized)
- return;
-#endif /* CANNOT_DUMP */
- emacs_sigaction_init (&action, deliver_arith_signal);
- sigaction (SIGFPE, &action, 0);
-}
directory_files_internal_unwind (Lisp_Object dh)
{
DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
- BLOCK_INPUT;
+ block_input ();
closedir (d);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
/* Now *bufp is the compiled form of MATCH; don't call anything
which might compile a new regexp until we're done with the loop! */
- BLOCK_INPUT;
+ block_input ();
d = opendir (SSDATA (dirfilename));
- UNBLOCK_INPUT;
+ unblock_input ();
if (d == NULL)
report_file_error ("Opening directory", Fcons (directory, Qnil));
}
}
- BLOCK_INPUT;
+ block_input ();
closedir (d);
- UNBLOCK_INPUT;
+ unblock_input ();
#ifdef WINDOWSNT
if (attrs)
Vw32_get_true_file_attributes = w32_save;
encoded_dir = ENCODE_FILE (dirname);
- BLOCK_INPUT;
+ block_input ();
d = opendir (SSDATA (Fdirectory_file_name (encoded_dir)));
- UNBLOCK_INPUT;
+ unblock_input ();
if (!d)
report_file_error ("Opening directory", Fcons (dirname, Qnil));
if (!(NILP (id_format) || EQ (id_format, Qinteger)))
{
- BLOCK_INPUT;
+ block_input ();
uname = stat_uname (&s);
gname = stat_gname (&s);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (uname)
values[2] = DECODE_SYSTEM (build_string (uname));
{
/* Block input so that expose events and other events that access
glyph matrices are not processed while we are changing them. */
- BLOCK_INPUT;
+ block_input ();
if (f)
adjust_frame_glyphs (f);
adjust_frame_glyphs (XFRAME (lisp_frame));
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
/* Block interrupt input so that we don't get surprised by an X
event while we're in an inconsistent state. */
- BLOCK_INPUT;
+ block_input ();
f->glyphs_initialized_p = 0;
/* Release window sub-matrices. */
f->desired_pool = f->current_pool = NULL;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
int width, height;
struct tty_display_info *tty;
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_window_change_signal);
- sigaction (SIGWINCH, &action, 0);
-
/* The frame size change obviously applies to a single
termcap-controlled terminal, but we can't decide which.
Therefore, we resize the frames corresponding to each tty.
static void
deliver_window_change_signal (int sig)
{
- handle_on_main_thread (sig, handle_window_change_signal);
+ deliver_process_signal (sig, handle_window_change_signal);
}
#endif /* SIGWINCH */
&& new_frame_total_cols == FRAME_TOTAL_COLS (f))
return;
- BLOCK_INPUT;
+ block_input ();
#ifdef MSDOS
/* We only can set screen dimensions to certain values supported
SET_FRAME_GARBAGED (f);
f->resized_p = 1;
- UNBLOCK_INPUT;
+ unblock_input ();
record_unwind_current_buffer ();
if (tty->termscript != 0)
{
- BLOCK_INPUT;
+ block_input ();
fclose (tty->termscript);
- UNBLOCK_INPUT;
+ unblock_input ();
}
tty->termscript = 0;
/* ??? Perhaps we should do something special for multibyte strings here. */
CHECK_STRING (string);
- BLOCK_INPUT;
+ block_input ();
if (!t)
error ("Unknown terminal device");
}
fwrite (SDATA (string), 1, SBYTES (string), out);
fflush (out);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
if (FRAME_MSDOS_P (f))
{
- BLOCK_INPUT;
+ block_input ();
w95_set_virtual_machine_title (SDATA (name));
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
#endif /* !HAVE_X_WINDOWS */
return Vuser_login_name;
CONS_TO_INTEGER (uid, uid_t, id);
- BLOCK_INPUT;
+ block_input ();
pw = getpwuid (id);
- UNBLOCK_INPUT;
+ unblock_input ();
return (pw ? build_string (pw->pw_name) : Qnil);
}
{
uid_t u;
CONS_TO_INTEGER (uid, uid_t, u);
- BLOCK_INPUT;
+ block_input ();
pw = getpwuid (u);
- UNBLOCK_INPUT;
+ unblock_input ();
}
else if (STRINGP (uid))
{
- BLOCK_INPUT;
+ block_input ();
pw = getpwnam (SSDATA (uid));
- UNBLOCK_INPUT;
+ unblock_input ();
}
else
error ("Invalid UID specification");
while (1)
{
time_t *taddr = emacs_secs_addr (&t);
- BLOCK_INPUT;
+ block_input ();
synchronize_system_time_locale ();
tm = ut ? gmtime (taddr) : localtime (taddr);
if (! tm)
{
- UNBLOCK_INPUT;
+ unblock_input ();
time_overflow ();
}
*tmp = *tm;
/* Buffer was too small, so make it bigger and try again. */
len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tm, ut, ns);
- UNBLOCK_INPUT;
+ unblock_input ();
if (STRING_BYTES_BOUND <= len)
string_overflow ();
size = len + 1;
buf = SAFE_ALLOCA (size);
}
- UNBLOCK_INPUT;
+ unblock_input ();
bufstring = make_unibyte_string (buf, len);
SAFE_FREE ();
return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0);
struct tm *decoded_time;
Lisp_Object list_args[9];
- BLOCK_INPUT;
+ block_input ();
decoded_time = localtime (&time_spec);
if (decoded_time)
save_tm = *decoded_time;
- UNBLOCK_INPUT;
+ unblock_input ();
if (! (decoded_time
&& MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= save_tm.tm_year
&& save_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
XSETFASTINT (list_args[6], save_tm.tm_wday);
list_args[7] = save_tm.tm_isdst ? Qt : Qnil;
- BLOCK_INPUT;
+ block_input ();
decoded_time = gmtime (&time_spec);
if (decoded_time == 0)
list_args[8] = Qnil;
else
XSETINT (list_args[8], tm_diff (&save_tm, decoded_time));
- UNBLOCK_INPUT;
+ unblock_input ();
return Flist (9, list_args);
}
zone = XCAR (zone);
if (NILP (zone))
{
- BLOCK_INPUT;
+ block_input ();
value = mktime (&tm);
- UNBLOCK_INPUT;
+ unblock_input ();
}
else
{
else
error ("Invalid time zone specification");
- BLOCK_INPUT;
+ block_input ();
/* Set TZ before calling mktime; merely adjusting mktime's returned
value doesn't suffice, since that would mishandle leap seconds. */
#ifdef LOCALTIME_CACHE
tzset ();
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
xfree (newenv);
}
newline, and without the 4-digit year limit. Don't use asctime
or ctime, as they might dump core if the year is outside the
range -999 .. 9999. */
- BLOCK_INPUT;
+ block_input ();
tm = localtime (&value);
if (tm)
{
tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_year + year_base);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (! tm)
time_overflow ();
zone_offset = Qnil;
value = make_emacs_time (lisp_seconds_argument (specified_time), 0);
zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm);
- BLOCK_INPUT;
+ block_input ();
t = gmtime (emacs_secs_addr (&value));
if (t)
offset = tm_diff (&localtm, t);
- UNBLOCK_INPUT;
+ unblock_input ();
if (t)
{
if (! (NILP (tz) || EQ (tz, Qt)))
CHECK_STRING (tz);
- BLOCK_INPUT;
+ block_input ();
/* When called for the first time, save the original TZ. */
old_environbuf = environbuf;
set_time_zone_rule (tzstring);
environbuf = environ;
- UNBLOCK_INPUT;
+ unblock_input ();
xfree (old_environbuf);
return Qnil;
#include "window.h"
#include "systty.h"
+#include "atimer.h"
#include "blockinput.h"
#include "syssignal.h"
#include "process.h"
section of the Emacs manual or the file BUGS.\n"
\f
-/* Signal code for the fatal signal that was received. */
-static int fatal_error_code;
-
/* True if handling a fatal error already. */
bool fatal_error_in_progress;
-/* Handle bus errors, invalid instruction, etc. */
-static void
-handle_fatal_signal (int sig)
-{
- fatal_error_backtrace (sig, 10);
-}
-
-static void
-deliver_fatal_signal (int sig)
-{
- handle_on_main_thread (sig, handle_fatal_signal);
-}
-
/* Report a fatal error due to signal SIG, output a backtrace of at
most BACKTRACE_LIMIT lines, and exit. */
_Noreturn void
-fatal_error_backtrace (int sig, int backtrace_limit)
+terminate_due_to_signal (int sig, int backtrace_limit)
{
- fatal_error_code = sig;
- signal (sig, SIG_DFL);
-
- TOTALLY_UNBLOCK_INPUT;
+ totally_unblock_input ();
/* If fatal error occurs in code below, avoid infinite recursion. */
if (! fatal_error_in_progress)
}
/* Signal the same code; this time it will really be fatal.
- Remember that since we're in a signal handler, the signal we're
- going to send is probably blocked, so we have to unblock it if we
- want to really receive it. */
+ Since we're in a signal handler, the signal is blocked, so we
+ have to unblock it if we want to really receive it. */
#ifndef MSDOS
{
sigset_t unblocked;
sigemptyset (&unblocked);
- sigaddset (&unblocked, fatal_error_code);
+ sigaddset (&unblocked, sig);
pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
}
#endif
- kill (getpid (), fatal_error_code);
+ emacs_raise (sig);
/* This shouldn't be executed, but it prevents a warning. */
exit (1);
#ifdef SIGDANGER
/* Handler for SIGDANGER. */
-static void deliver_danger_signal (int);
-
static void
handle_danger_signal (int sig)
{
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_danger_signal);
- sigaction (sig, &action, 0);
-
malloc_warning ("Operating system warns that virtual memory is running low.\n");
/* It might be unsafe to call do_auto_save now. */
static void
deliver_danger_signal (int sig)
{
- handle_on_main_thread (sig, handle_danger_signal);
+ deliver_process_signal (sig, handle_danger_signal);
}
#endif
\f
#endif
char stack_bottom_variable;
bool do_initial_setlocale;
+ bool dumping;
int skip_args = 0;
#ifdef HAVE_SETRLIMIT
struct rlimit rlim;
char dname_arg2[80];
#endif
char *ch_to_dir;
- struct sigaction fatal_error_action;
#if GC_MARK_STACK
stack_base = &dummy;
exit (1);
}
+ dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
+ || strcmp (argv[argc - 1], "bootstrap") == 0);
#ifdef HAVE_PERSONALITY_LINUX32
- if (!initialized
- && (strcmp (argv[argc-1], "dump") == 0
- || strcmp (argv[argc-1], "bootstrap") == 0)
- && ! getenv ("EMACS_HEAP_EXEC"))
+ if (dumping && ! getenv ("EMACS_HEAP_EXEC"))
{
static char heapexec[] = "EMACS_HEAP_EXEC=true";
/* Set this so we only do this once. */
#endif
}
- init_signals ();
- emacs_sigaction_init (&fatal_error_action, deliver_fatal_signal);
-
- /* Don't catch SIGHUP if dumping. */
- if (1
-#ifndef CANNOT_DUMP
- && initialized
-#endif
- )
- {
- /* In --batch mode, don't catch SIGHUP if already ignored.
- That makes nohup work. */
- bool catch_SIGHUP = !noninteractive;
- if (!catch_SIGHUP)
- {
- struct sigaction old_action;
- sigaction (SIGHUP, 0, &old_action);
- catch_SIGHUP = old_action.sa_handler != SIG_IGN;
- }
- if (catch_SIGHUP)
- sigaction (SIGHUP, &fatal_error_action, 0);
- }
-
- if (
-#ifndef CANNOT_DUMP
- ! noninteractive || initialized
-#else
- 1
-#endif
- )
- {
- /* Don't catch these signals in batch mode if dumping.
- On some machines, this sets static data that would make
- signal fail to work right when the dumped Emacs is run. */
- sigaction (SIGQUIT, &fatal_error_action, 0);
- sigaction (SIGILL, &fatal_error_action, 0);
- sigaction (SIGTRAP, &fatal_error_action, 0);
-#ifdef SIGUSR1
- add_user_signal (SIGUSR1, "sigusr1");
-#endif
-#ifdef SIGUSR2
- add_user_signal (SIGUSR2, "sigusr2");
-#endif
-#ifdef SIGABRT
- sigaction (SIGABRT, &fatal_error_action, 0);
-#endif
-#ifdef SIGHWE
- sigaction (SIGHWE, &fatal_error_action, 0);
-#endif
-#ifdef SIGPRE
- sigaction (SIGPRE, &fatal_error_action, 0);
-#endif
-#ifdef SIGORE
- sigaction (SIGORE, &fatal_error_action, 0);
-#endif
-#ifdef SIGUME
- sigaction (SIGUME, &fatal_error_action, 0);
-#endif
-#ifdef SIGDLK
- sigaction (SIGDLK, &fatal_error_action, 0);
-#endif
-#ifdef SIGCPULIM
- sigaction (SIGCPULIM, &fatal_error_action, 0);
-#endif
-#ifdef SIGIOT
- /* This is missing on some systems - OS/2, for example. */
- sigaction (SIGIOT, &fatal_error_action, 0);
-#endif
-#ifdef SIGEMT
- sigaction (SIGEMT, &fatal_error_action, 0);
-#endif
- sigaction (SIGFPE, &fatal_error_action, 0);
-#ifdef SIGBUS
- sigaction (SIGBUS, &fatal_error_action, 0);
-#endif
- sigaction (SIGSEGV, &fatal_error_action, 0);
-#ifdef SIGSYS
- sigaction (SIGSYS, &fatal_error_action, 0);
-#endif
- /* May need special treatment on MS-Windows. See
- http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
- Please update the doc of kill-emacs, kill-emacs-hook, and
- NEWS if you change this.
- */
- if (noninteractive)
- sigaction (SIGINT, &fatal_error_action, 0);
- sigaction (SIGTERM, &fatal_error_action, 0);
-#ifdef SIGXCPU
- sigaction (SIGXCPU, &fatal_error_action, 0);
-#endif
-#ifdef SIGXFSZ
- sigaction (SIGXFSZ, &fatal_error_action, 0);
-#endif /* SIGXFSZ */
-
-#ifdef SIGDANGER
- /* This just means available memory is getting low. */
- {
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_danger_signal);
- sigaction (SIGDANGER, &action, 0);
- }
-#endif
-
-#ifdef AIX
-/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
- sigaction (SIGXCPU, &fatal_error_action, 0);
- sigaction (SIGIOINT, &fatal_error_action, 0);
- sigaction (SIGGRANT, &fatal_error_action, 0);
- sigaction (SIGRETRACT, &fatal_error_action, 0);
- sigaction (SIGSOUND, &fatal_error_action, 0);
- sigaction (SIGMSG, &fatal_error_action, 0);
-#endif /* AIX */
- }
+ init_signals (dumping);
noninteractive1 = noninteractive;
}
init_eval ();
- init_data ();
init_atimer ();
running_asynch_code = 0;
init_random ();
/* egetenv is a pretty low-level facility, which may get called in
many circumstances; it seems flimsy to put off initializing it
until calling init_callproc. Do not do it when dumping. */
- if (initialized || ((strcmp (argv[argc-1], "dump") != 0
- && strcmp (argv[argc-1], "bootstrap") != 0)))
+ if (! dumping)
set_initial_environment ();
/* AIX crashes are reported in system versions 3.2.3 and 3.2.4
/* Unwind the specbind, catch, and handler stacks back to CATCH, and
jump to that CATCH, returning VALUE as the value of that catch.
- This is the guts Fthrow and Fsignal; they differ only in the way
+ This is the guts of Fthrow and Fsignal; they differ only in the way
they choose the catch tag to throw to. A catch tag for a
condition-case form has a TAG of Qnil.
the handler stack as we go, so that the proper handlers are in
effect for each unwind-protect clause we run. At the end, restore
some static info saved in CATCH, and longjmp to the location
- specified in the
+ specified there.
This is used for correct unwinding in Fthrow and Fsignal. */
/* Restore certain special C variables. */
set_poll_suppress_count (catch->poll_suppress_count);
- UNBLOCK_INPUT_TO (catch->interrupt_input_blocked);
+ unblock_input_to (catch->interrupt_input_blocked);
immediate_quit = 0;
do
}
while (! last_time);
-#if HAVE_X_WINDOWS
- /* If x_catch_errors was done, turn it off now.
- (First we give unbind_to a chance to do that.) */
-#if 0 /* This would disable x_catch_errors after x_connection_closed.
- The catch must remain in effect during that delicate
- state. --lorentey */
- x_fully_uncatch_errors ();
-#endif
-#endif
-
byte_stack_list = catch->byte_stack;
gcprolist = catch->gcpro;
#ifdef DEBUG_GCPRO
if (
/* Don't try to run the debugger with interrupts blocked.
The editing loop would return anyway. */
- ! INPUT_BLOCKED_P
+ ! input_blocked_p ()
&& NILP (Vinhibit_debugger)
/* Does user want to enter debugger for this kind of error? */
&& (EQ (sig, Qquit)
memcpy (o, nm, p - nm);
o [p - nm] = 0;
- BLOCK_INPUT;
+ block_input ();
pw = (struct passwd *) getpwnam (o + 1);
- UNBLOCK_INPUT;
+ unblock_input ();
if (pw)
{
newdir = pw->pw_dir;
o[len] = 0;
/* Look up the user name. */
- BLOCK_INPUT;
+ block_input ();
pw = (struct passwd *) getpwnam (o + 1);
- UNBLOCK_INPUT;
+ unblock_input ();
if (!pw)
error ("\"%s\" isn't a registered user", o + 1);
/* If we have ~user and `user' exists, discard
everything up to ~. But if `user' does not exist, leave
~user alone, it might be a literal file name. */
- BLOCK_INPUT;
+ block_input ();
pw = getpwnam (o + 1);
- UNBLOCK_INPUT;
+ unblock_input ();
if (pw)
return p;
}
mode_t realmask;
Lisp_Object value;
- BLOCK_INPUT;
+ block_input ();
realmask = umask (0);
umask (realmask);
- UNBLOCK_INPUT;
+ unblock_input ();
XSETINT (value, (~ realmask) & 0777);
return value;
auto_saving = 0;
if (stream != NULL)
{
- BLOCK_INPUT;
+ block_input ();
fclose (stream);
- UNBLOCK_INPUT;
+ unblock_input ();
}
return Qnil;
}
if (STRINGP (BVAR (b, auto_save_file_name))
&& stream != NULL && do_handled_files == 0)
{
- BLOCK_INPUT;
+ block_input ();
if (!NILP (BVAR (b, filename)))
{
fwrite (SDATA (BVAR (b, filename)), 1,
fwrite (SDATA (BVAR (b, auto_save_file_name)), 1,
SBYTES (BVAR (b, auto_save_file_name)), stream);
putc ('\n', stream);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!NILP (current_only)
#include <config.h>
#include "lisp.h"
-#include "syssignal.h"
-
-#include <float.h>
-#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
- && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
-#define IEEE_FLOATING_POINT 1
-#else
-#define IEEE_FLOATING_POINT 0
-#endif
#include <math.h>
halftail = XCDR (halftail);
if (EQ (tail, halftail))
break;
-
-#if 0 /* Unsafe version. */
- /* This function can be called asynchronously
- (setup_coding_system). Don't QUIT in that case. */
- if (!interrupt_input_blocked)
- QUIT;
-#endif
}
return Qnil;
doesn't remove FACE from a cache. Until we find a solution, we
suppress this code, and simply use Fclear_face_cache even though
that is not efficient. */
- BLOCK_INPUT;
+ block_input ();
for (id = 0; id < ASIZE (Vfontset_table); id++)
{
Lisp_Object this = AREF (Vfontset_table, id);
}
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
#else /* not 0 */
/* But, we don't have to call Fclear_face_cache if no fontset has
been realized from BASE. */
f->alpha[i] = newval[i];
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
- BLOCK_INPUT;
+ block_input ();
x_set_frame_alpha (f);
- UNBLOCK_INPUT;
+ unblock_input ();
#endif
return;
void
draw_row_fringe_bitmaps (struct window *w, struct glyph_row *row)
{
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
/* If row is completely invisible, because of vscrolling, we
don't have to draw anything. */
new->colors[0].pixel = background;
new->colors[1].pixel = foreground;
- BLOCK_INPUT;
+ block_input ();
XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), new->colors, 2);
for (i = 1; i < 7; i++)
{
new->gcs[i - 1] = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCForeground, &xgcv);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (i < 7)
{
- BLOCK_INPUT;
+ block_input ();
for (i--; i >= 0; i--)
XFreeGC (FRAME_X_DISPLAY (f), new->gcs[i]);
- UNBLOCK_INPUT;
+ unblock_input ();
if (prev)
prev->next = new->next;
else if (data)
n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0;
- BLOCK_INPUT;
+ block_input ();
if (with_background)
ftxfont_draw_background (f, font, s->gc, x, y, s->width);
code = alloca (sizeof (unsigned) * len);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return len;
}
{
struct ftxfont_frame_data *data = font_get_frame_data (f, &ftxfont_driver);
- BLOCK_INPUT;
+ block_input ();
while (data)
{
struct ftxfont_frame_data *next = data->next;
free (data);
data = next;
}
- UNBLOCK_INPUT;
+ unblock_input ();
font_put_frame_data (f, &ftxfont_driver, NULL);
return 0;
}
if (! FRAME_GTK_WIDGET (f) || ! (get_bg || get_fg))
return success_p;
- BLOCK_INPUT;
+ block_input ();
{
#ifdef HAVE_GTK3
GtkStyleContext *gsty
#endif
}
- UNBLOCK_INPUT;
+ unblock_input ();
return success_p;
}
if (!x->ttip_lbl) return 0;
- BLOCK_INPUT;
+ block_input ();
encoded_string = ENCODE_UTF_8 (string);
widget = GTK_WIDGET (x->ttip_lbl);
gwin = gtk_widget_get_window (GTK_WIDGET (x->ttip_window));
if (width) *width = req.width;
if (height) *height = req.height;
- UNBLOCK_INPUT;
+ unblock_input ();
return 1;
#endif /* USE_GTK_TOOLTIP */
struct x_output *x = f->output_data.x;
if (x->ttip_window)
{
- BLOCK_INPUT;
+ block_input ();
gtk_window_move (x->ttip_window, root_x, root_y);
gtk_widget_show_all (GTK_WIDGET (x->ttip_window));
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif
}
if (f->output_data.x->ttip_window)
{
GtkWindow *win = f->output_data.x->ttip_window;
- BLOCK_INPUT;
+ block_input ();
gtk_widget_hide (GTK_WIDGET (win));
if (g_object_get_data (G_OBJECT (win), "restore-tt"))
GtkSettings *settings = gtk_settings_get_for_screen (screen);
g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL);
}
- UNBLOCK_INPUT;
+ unblock_input ();
ret = 1;
}
gpointer gdkwin;
GtkWidget *gwdesc = 0;
- BLOCK_INPUT;
+ block_input ();
gdkwin = gdk_x11_window_lookup_for_display (gdk_x11_lookup_xdisplay (dpy),
wdesc);
gwdesc = gtk_get_event_widget (&event);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return gwdesc;
}
#endif
char *title = 0;
- BLOCK_INPUT;
+ block_input ();
if (FRAME_X_EMBEDDED_P (f))
{
if (whbox) gtk_widget_destroy (whbox);
if (wfixed) gtk_widget_destroy (wfixed);
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return 1;
}
&f->output_data.x->size_hints,
sizeof (size_hints)) != 0)
{
- BLOCK_INPUT;
+ block_input ();
gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
NULL, &size_hints, hint_flags);
f->output_data.x->size_hints = size_hints;
f->output_data.x->hint_flags = hint_flags;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
{
if (FRAME_GTK_WIDGET (f))
{
- BLOCK_INPUT;
+ block_input ();
xg_set_widget_bg (f, FRAME_GTK_WIDGET (f), FRAME_BACKGROUND_PIXEL (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
struct xg_dialog_data *dd = (struct xg_dialog_data *) p->pointer;
- BLOCK_INPUT;
+ block_input ();
if (dd->w) gtk_widget_destroy (dd->w);
if (dd->timerid != 0) g_source_remove (dd->timerid);
g_main_loop_quit (dd->loop);
g_main_loop_unref (dd->loop);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
int filesel_done = 0;
xg_get_file_func func;
-#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- /* I really don't know why this is needed, but without this the GLIBC add on
- library linuxthreads hangs when the Gnome file chooser backend creates
- threads. */
- sigset_t blocked;
- sigemptyset (&blocked);
- sigaddset (&blocked, __SIGRTMIN);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
-#endif /* HAVE_PTHREAD */
-
#ifdef HAVE_GTK_FILE_SELECTION_NEW
if (xg_uses_old_file_dialog ())
gtk_widget_set_name (w, "emacs-filedialog");
filesel_done = xg_dialog_run (f, w);
-
-#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
-#endif
-
if (filesel_done == GTK_RESPONSE_OK)
fn = (*func) (w);
int done = 0;
Lisp_Object font = Qnil;
-#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- sigset_t blocked;
- sigemptyset (&blocked);
- sigaddset (&blocked, __SIGRTMIN);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
-#endif /* HAVE_PTHREAD */
-
w = gtk_font_chooser_dialog_new
("Pick a font", GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
gtk_widget_set_name (w, "emacs-fontdialog");
done = xg_dialog_run (f, w);
-
-#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
-#endif
-
if (done == GTK_RESPONSE_OK)
{
#if USE_NEW_GTK_FONT_CHOOSER
if (x->menubar_widget && gtk_widget_get_parent (x->menubar_widget))
return 0; /* Already done this, happens for frames created invisible. */
- BLOCK_INPUT;
+ block_input ();
gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->menubar_widget,
FALSE, FALSE, 0);
FRAME_MENUBAR_HEIGHT (f) = req.height;
xg_height_or_width_changed (f);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return 1;
}
if (x->menubar_widget)
{
- BLOCK_INPUT;
+ block_input ();
gtk_container_remove (GTK_CONTAINER (x->vbox_widget), x->menubar_widget);
/* The menubar and its children shall be deleted when removed from
x->menubar_widget = 0;
FRAME_MENUBAR_HEIGHT (f) = 0;
xg_height_or_width_changed (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
if (changed || int_gtk_range_get_value (GTK_RANGE (wscroll)) != value)
{
- BLOCK_INPUT;
+ block_input ();
/* gtk_range_set_value invokes the callback. Set
ignore_gtk_scrollbar to make the callback do nothing */
xg_ignore_gtk_scrollbar = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
if (! FRAME_GTK_WIDGET (f))
return;
- BLOCK_INPUT;
+ block_input ();
if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX))
{
&& ! NILP (Fequal (tbinfo->style, style))
&& ! NILP (Fequal (tbinfo->last_tool_bar, f->tool_bar_items)))
{
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
xg_height_or_width_changed (f);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Deallocate all resources for the tool bar on frame F.
{
struct xg_frame_tb_info *tbinfo;
int is_packed = x->handlebox_widget != 0;
- BLOCK_INPUT;
+ block_input ();
/* We may have created the toolbar_widget in xg_create_tool_bar, but
not the x->handlebox_widget which is created in xg_pack_tool_bar. */
if (is_packed)
xg_height_or_width_changed (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
if (! x->toolbar_widget || ! x->handlebox_widget)
return 1;
- BLOCK_INPUT;
+ block_input ();
g_object_ref (x->handlebox_widget);
if (x->toolbar_in_hbox)
gtk_container_remove (GTK_CONTAINER (x->hbox_widget),
if (xg_update_tool_bar_sizes (f))
xg_height_or_width_changed (f);
- UNBLOCK_INPUT;
+ unblock_input ();
return 1;
}
if (--bm->refcount == 0)
{
- BLOCK_INPUT;
+ block_input ();
free_bitmap_record (dpyinfo, bm);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
width = x_bitmap_width (f, id);
height = x_bitmap_height (f, id);
- BLOCK_INPUT;
+ block_input ();
ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
~0, ZPixmap);
if (!ximg)
{
- UNBLOCK_INPUT;
+ unblock_input ();
return -1;
}
result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
- UNBLOCK_INPUT;
+ unblock_input ();
if (!result)
{
XDestroyImage (ximg);
}
}
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
width, height);
Lisp_Object target_type = *type->type;
int type_valid = 1;
- BLOCK_INPUT;
+ block_input ();
for (p = image_types; p; p = p->next)
if (EQ (*p->type, target_type))
}
done:
- UNBLOCK_INPUT;
+ unblock_input ();
return p;
}
static void
x_clear_image (struct frame *f, struct image *img)
{
- BLOCK_INPUT;
+ block_input ();
x_clear_image_1 (f, img, 1, 1, 1);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Block input so that we won't be interrupted by a SIGIO
while being in an inconsistent state. */
- BLOCK_INPUT;
+ block_input ();
if (!NILP (filter))
{
++windows_or_buffers_changed;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
/* If not found, create a new image and cache it. */
if (img == NULL)
{
- BLOCK_INPUT;
+ block_input ();
img = make_image (spec, hash);
cache_image (f, img);
img->load_failed_p = img->type->load (f, img) == 0;
postprocess_image (f, img);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* We're using IMG, so set its timestamp to `now'. */
Window window = FRAME_X_WINDOW (f);
Screen *screen = FRAME_X_SCREEN (f);
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
if (depth <= 0)
depth = DefaultDepthOfScreen (screen);
static void
x_destroy_x_image (XImagePtr ximg)
{
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
if (ximg)
{
#ifdef HAVE_X_WINDOWS
#ifdef HAVE_X_WINDOWS
GC gc;
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
XFreeGC (FRAME_X_DISPLAY (f), gc);
x_query_color (f, &color);
rc = x_alloc_nearest_color (f, cmap, &color);
#else
- BLOCK_INPUT;
+ block_input ();
cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
color.pixel = pixel;
XQueryColor (NULL, cmap, &color);
rc = x_alloc_nearest_color (f, cmap, &color);
- UNBLOCK_INPUT;
+ unblock_input ();
#endif /* HAVE_X_WINDOWS */
if (rc)
if (x_check_image_size (0, img->width, img->height))
{
/* Only W32 version did BLOCK_INPUT here. ++kfs */
- BLOCK_INPUT;
+ block_input ();
img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
img->width, img->height,
DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!img->pixmap)
{
XImagePtr ximg;
- BLOCK_INPUT;
+ block_input ();
/* Try to get an XImage for img->pixmep. */
ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
image_error ("Cannot get X image of `%s'; colors will not be freed",
img->spec, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_X_WINDOWS */
/* Now that we have the pixmap, compute mask and transform the
image if requested. */
- BLOCK_INPUT;
+ block_input ();
postprocess_image (f, img);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_GHOSTSCRIPT */
#include <config.h>
+#define BLOCKINPUT_INLINE EXTERN_INLINE
#define KEYBOARD_INLINE EXTERN_INLINE
#include <stdio.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. */
-int pending_signals;
+/* Nonzero means an input interrupt or alarm signal has arrived.
+ The QUIT macro checks this. */
+volatile int pending_signals;
#define KBD_BUFFER_SIZE 4096
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.
/* 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 (void);
static void get_input_pending (int *, int);
static int readable_events (int);
static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
#ifdef USABLE_SIGIO
static void deliver_input_available_signal (int signo);
#endif
-static void handle_interrupt (void);
+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);
/* 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++;
/* 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);
}
}
}
-#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)
void
poll_for_input_1 (void)
{
- if (interrupt_input_blocked == 0
+ if (! input_blocked_p ()
&& !waiting_for_input)
- read_avail_input ();
+ gobble_input ();
}
/* Timer callback function for poll_timer. TIMER is equal to
poll_for_input (struct atimer *timer)
{
if (poll_suppress_count == 0)
- {
- interrupt_input_pending = 1;
- pending_signals = 1;
- }
+ pending_signals = 1;
}
#endif /* POLL_FOR_INPUT */
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 ();
}
}
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,
}
last_event_timestamp = event->timestamp;
- handle_interrupt ();
+
+ handle_interrupt (0);
return;
}
if (immediate_quit && NILP (Vinhibit_quit))
{
immediate_quit = 0;
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
QUIT;
}
}
/* Start reading input again, we have processed enough so we can
accept new events again. */
unhold_keyboard_input ();
-#ifdef USABLE_SIGIO
- if (!noninteractive)
- {
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_input_available_signal);
- sigaction (SIGIO, &action, 0);
- }
-#endif
start_polling ();
}
#endif /* subprocesses */
wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0);
if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
- read_avail_input ();
+ gobble_input ();
}
if (CONSP (Vunread_command_events))
*addr = (!NILP (Vquit_flag) || readable_events (flags));
}
-/* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary. */
-
-void
-gobble_input (void)
-{
-#ifdef USABLE_SIGIO
- if (interrupt_input)
- {
- sigset_t blocked, procmask;
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGIO);
- pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
- read_avail_input ();
- pthread_sigmask (SIG_SETMASK, &procmask, 0);
- }
- 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)
- {
- sigset_t blocked, procmask;
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGALRM);
- pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
- read_avail_input ();
- pthread_sigmask (SIG_SETMASK, &procmask, 0);
- }
- else
-#endif
-#endif
- read_avail_input ();
-}
-
/* Put a BUFFER_SWITCH_EVENT in the buffer
so that read_key_sequence will notice the new current buffer. */
/* Make sure no interrupt happens while storing the event. */
#ifdef USABLE_SIGIO
if (interrupt_input)
- {
- sigset_t blocked, procmask;
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGIO);
- pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
- kbd_buffer_store_event (&event);
- pthread_sigmask (SIG_SETMASK, &procmask, 0);
- }
+ 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 (void)
+int
+gobble_input (void)
{
int nread = 0;
int err = 0;
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 (0 < (nr = (*t->read_socket_hook) (t, &hold_quit)))
+ 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. */
{
static void
handle_async_input (void)
{
- interrupt_input_pending = 0;
- pending_signals = pending_atimers;
-
+#ifdef USABLE_SIGIO
while (1)
{
- int nread = read_avail_input ();
+ 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;
}
+#endif
}
void
process_pending_signals (void)
{
- if (interrupt_input_pending)
- handle_async_input ();
+ pending_signals = 0;
+ handle_async_input ();
do_pending_atimers ();
}
+/* Undo any number of BLOCK_INPUT calls down to level LEVEL,
+ and also (if the level is now 0) reinvoke any pending signal. */
+
+void
+unblock_input_to (int level)
+{
+ interrupt_input_blocked = level;
+ if (level == 0)
+ {
+ if (pending_signals)
+ process_pending_signals ();
+ }
+ else if (level < 0)
+ emacs_abort ();
+}
+
+/* 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. */
+
+void
+unblock_input (void)
+{
+ unblock_input_to (interrupt_input_blocked - 1);
+}
+
+/* Undo any number of BLOCK_INPUT calls,
+ and also reinvoke any pending signal. */
+
+void
+totally_unblock_input (void)
+{
+ unblock_input_to (0);
+}
+
#ifdef USABLE_SIGIO
-static void
+void
handle_input_available_signal (int sig)
{
- interrupt_input_pending = 1;
pending_signals = 1;
if (input_available_clear_time)
static void
deliver_input_available_signal (int sig)
{
- handle_on_main_thread (sig, handle_input_available_signal);
+ deliver_process_signal (sig, handle_input_available_signal);
}
#endif /* USABLE_SIGIO */
-/* Send ourselves a 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)
-{
-#ifdef USABLE_SIGIO
- handle_async_input ();
-#endif
-}
-
-
\f
/* User signal events. */
p->npending++;
#ifdef USABLE_SIGIO
if (interrupt_input)
- kill (getpid (), SIGIO);
+ handle_input_available_signal (sig);
else
#endif
{
static void
deliver_user_signal (int sig)
{
- handle_on_main_thread (sig, handle_user_signal);
+ deliver_process_signal (sig, handle_user_signal);
}
static char *
for (p = user_signals; p; p = p->next)
if (p->npending > 0)
{
- sigset_t blocked, procmask;
-
if (! buf_initialized)
{
memset (&buf, 0, sizeof buf);
buf_initialized = 1;
}
- sigemptyset (&blocked);
- sigaddset (&blocked, p->sig);
- pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
-
do
{
buf.code = p->sig;
p->npending--;
}
while (p->npending > 0);
-
- pthread_sigmask (SIG_SETMASK, &procmask, 0);
}
}
{
if (dribble)
{
- BLOCK_INPUT;
+ block_input ();
fclose (dribble);
- UNBLOCK_INPUT;
+ unblock_input ();
dribble = 0;
}
if (!NILP (file))
from the controlling tty. */
internal_last_event_frame = terminal->display_info.tty->top_frame;
- handle_interrupt ();
+ handle_interrupt (1);
}
}
static void
deliver_interrupt_signal (int sig)
{
- handle_on_main_thread (sig, handle_interrupt_signal);
+ 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. */
- sigset_t blocked;
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGINT);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ 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);
init_all_sys_modes ();
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
}
else
{
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);
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
/* Prevent another signal from doing this before we finish. */
clear_waiting_for_input ();
input_pending = 0;
Vunread_command_events = Qnil;
-#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)
- emacs_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),
#endif
input_pending = 0;
interrupt_input_blocked = 0;
- interrupt_input_pending = 0;
pending_signals = 0;
/* This means that command_loop_1 won't try to select anything the first
/* 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. */
struct sigaction action;
extern void start_polling (void);
extern void stop_polling (void);
extern void set_poll_suppress_count (int);
-extern void gobble_input (void);
+extern int gobble_input (void);
extern int input_polling_used (void);
extern void clear_input_pending (void);
extern int requeued_events_pending_p (void);
/* Use malloc here. See the comment above this function.
Avoid realloc here; it causes spurious traps on GNU/Linux [KFS] */
- BLOCK_INPUT;
+ block_input ();
newmodes = malloc (allocsize);
if (newmodes)
{
}
cmm_maps = newmaps;
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (newmodes == NULL || newmaps == NULL)
break;
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
+#include <float.h>
#include <inttypes.h>
#include <limits.h>
#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data)
#define XFLOAT_INIT(f, n) (XFLOAT (f)->u.data = (n))
+/* Most hosts nowadays use IEEE floating point, so they use IEC 60559
+ representations, have infinities and NaNs, and do not trap on
+ exceptions. Define IEEE_FLOATING_POINT if this host is one of the
+ typical ones. The C11 macro __STDC_IEC_559__ is close to what is
+ wanted here, but is not quite right because Emacs does not require
+ all the features of C11 Annex F (and does not require C11 at all,
+ for that matter). */
+#define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
+ && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
+
/* A character, declared with the following typedef, is a member
of some character set associated with the current buffer. */
#ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */
a request to exit Emacs when it is safe to do. */
extern void process_pending_signals (void);
-extern int pending_signals;
+extern int volatile pending_signals;
extern void process_quit_flag (void);
#define QUIT \
extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *);
extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, bool);
extern void syms_of_data (void);
-extern void init_data (void);
extern void swap_in_global_binding (struct Lisp_Symbol *);
/* Defined in cmds.c */
extern Lisp_Object menu_bar_items (Lisp_Object);
extern Lisp_Object tool_bar_items (Lisp_Object, int *);
extern void discard_mouse_events (void);
+#ifdef USABLE_SIGIO
+void handle_input_available_signal (int);
+#endif
extern Lisp_Object pending_funcalls;
extern int detect_input_pending (void);
extern int detect_input_pending_ignore_squeezables (void);
extern Lisp_Object decode_env_path (const char *, const char *);
extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
extern Lisp_Object Qfile_name_handler_alist;
-extern _Noreturn void fatal_error_backtrace (int, int);
+extern _Noreturn void terminate_due_to_signal (int, int);
extern Lisp_Object Qkill_emacs;
#if HAVE_SETLOCALE
void fixup_locale (void);
#endif
extern void add_keyboard_wait_descriptor (int);
extern void delete_keyboard_wait_descriptor (int);
+extern void record_child_status_change (pid_t, int);
#ifdef HAVE_GPM
extern void add_gpm_wait_descriptor (int);
extern void delete_gpm_wait_descriptor (int);
{
if (load_each_byte)
{
- BLOCK_INPUT;
+ block_input ();
ungetc (c, instream);
- UNBLOCK_INPUT;
+ unblock_input ();
}
else
unread_char = c;
{
if (c >= 0)
{
- BLOCK_INPUT;
+ block_input ();
ungetc (c, instream);
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
- BLOCK_INPUT;
+ block_input ();
c = getc (instream);
#ifdef EINTR
/* Interrupted reads have been observed while reading over the network. */
while (c == EOF && ferror (instream) && errno == EINTR)
{
- UNBLOCK_INPUT;
+ unblock_input ();
QUIT;
- BLOCK_INPUT;
+ block_input ();
clearerr (instream);
c = getc (instream);
}
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
return (c == EOF ? -1 : c);
}
(void)
{
register Lisp_Object val;
- BLOCK_INPUT;
+ block_input ();
XSETINT (val, getc (instream));
- UNBLOCK_INPUT;
+ unblock_input ();
return val;
}
FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
if (stream != NULL)
{
- BLOCK_INPUT;
+ block_input ();
fclose (stream);
- UNBLOCK_INPUT;
+ unblock_input ();
}
return Qnil;
}
{
widget_value *value;
- BLOCK_INPUT;
+ block_input ();
value = malloc_widget_value ();
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
free_menubar_widget_value_tree (wv->next);
wv->next = (widget_value *) 0xDEADBEEF;
}
- BLOCK_INPUT;
+ block_input ();
free_widget_value (wv);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Create a tree of widget_value objects
#endif
/* Display them in a menu. */
- BLOCK_INPUT;
+ block_input ();
/* FIXME: Use a terminal hook! */
#if defined HAVE_NTGUI
last_event_timestamp);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
#ifdef HAVE_NS
unbind_to (specpdl_count, Qnil);
if (display_info->termscript)
fprintf (display_info->termscript, "\n\n<UPDATE_BEGIN");
- BLOCK_INPUT;
+ block_input ();
if (f && f == mouse_face_frame)
{
hlinfo->mouse_face_mouse_frame = NULL;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
if (hlinfo->mouse_face_deferred_gc
|| (f && f == hlinfo->mouse_face_mouse_frame))
{
- BLOCK_INPUT;
+ block_input ();
if (hlinfo->mouse_face_mouse_frame)
note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
hlinfo->mouse_face_mouse_x,
hlinfo->mouse_face_mouse_y);
hlinfo->mouse_face_deferred_gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Set the cursor type to whatever they wanted. In a minibuffer
if (f->explicit_name || ! NILP (f->title) || ns_in_resize)
return;
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
filename = BVAR (XBUFFER (buf), filename);
name = BVAR (XBUFFER (buf), name);
if (title && (! strcmp (title, SSDATA (encoded_name))))
{
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
}
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
NSAutoreleasePool *pool;
if (!MINI_WINDOW_P (XWINDOW (f->selected_window)))
{
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
[[view window] setDocumentEdited: !NILP (arg)];
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
NSTRACE (ns_implicitly_set_icon_type);
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
if (f->output_data.ns->miniimage
&& [[NSString stringWithUTF8String: SSDATA (f->name)]
isEqualToString: [(NSImage *)f->output_data.ns->miniimage name]])
{
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
if (CONSP (tem) && ! NILP (XCDR (tem)))
{
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
f->output_data.ns->miniimage = image;
[view setMiniwindowImage: setMini];
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
f->resx = dpyinfo->resx;
f->resy = dpyinfo->resy;
- BLOCK_INPUT;
+ block_input ();
register_font_driver (&nsfont_driver, f);
x_default_parameter (f, parms, Qfont_backend, Qnil,
"fontBackend", "FontBackend", RES_TYPE_STRING);
build_string ([[font fontName] UTF8String]),
"font", "Font", RES_TYPE_STRING);
}
- UNBLOCK_INPUT;
+ unblock_input ();
x_default_parameter (f, parms, Qborder_width, make_number (0),
"borderwidth", "BorderWidth", RES_TYPE_NUMBER);
if (dpyinfo->x_focus_frame != f)
{
EmacsView *view = FRAME_NS_VIEW (f);
- BLOCK_INPUT;
+ block_input ();
[NSApp activateIgnoringOtherApps: YES];
[[view window] makeKeyAndOrderFront: view];
- UNBLOCK_INPUT;
+ unblock_input ();
}
return Qnil;
[panel setDelegate: fileDelegate];
panelOK = 0;
- BLOCK_INPUT;
+ block_input ();
if (NILP (mustmatch))
{
ret = [panel runModalForDirectory: dirS file: initS];
fname = build_string ([[panel filename] UTF8String]);
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
- UNBLOCK_INPUT;
+ unblock_input ();
return ret ? fname : Qnil;
}
error ("non-Nextstep frame used in `ns-list-colors'");
}
- BLOCK_INPUT;
+ block_input ();
colorlists = [[NSColorList availableColorLists] objectEnumerator];
while ((clist = [colorlists nextObject]))
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return list;
}
CHECK_STRING (script);
check_ns ();
- BLOCK_INPUT;
+ block_input ();
as_script = script;
as_result = &result;
as_status = 0;
as_script = Qnil;
as_result = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
if (status == 0)
return result;
else if (!STRINGP (result))
else
CHECK_NUMBER (dy);
- BLOCK_INPUT;
+ block_input ();
if (ns_tooltip == nil)
ns_tooltip = [[EmacsTooltip alloc] init];
else
&root_x, &root_y);
[ns_tooltip showAtX: root_x Y: root_y for: XINT (timeout)];
- UNBLOCK_INPUT;
+ unblock_input ();
UNGCPRO;
return unbind_to (count, Qnil);
font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics);
- BLOCK_INPUT;
+ block_input ();
/* for metrics */
sfont = [nsfont screenFont];
font->props[FONT_FULLNAME_INDEX] =
make_unibyte_string (font_info->name, strlen (font_info->name));
}
- UNBLOCK_INPUT;
+ unblock_input ();
return font_object;
}
fprintf (stderr, "%p\tFinding glyphs for glyphs in block %d\n",
font_info, block);
- BLOCK_INPUT;
+ block_input ();
#ifdef NS_IMPL_COCOA
if (firstTime)
#endif
}
- UNBLOCK_INPUT;
+ unblock_input ();
xfree (unichars);
}
numGlyphs = 0x10000;
#endif
- BLOCK_INPUT;
+ block_input ();
sfont = [font_info->nsfont screenFont];
font_info->metrics[block] = xzalloc (0x100 * sizeof (struct font_metrics));
metrics->ascent = r.size.height - metrics->descent;
/*-lrint (hshrink* [sfont descender] - expand * hd/2); */
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
XSETFRAME (Vmenu_updating_frame, f);
/*fprintf (stderr, "ns_update_menubar: frame: %p\tdeep: %d\tsub: %p\n", f, deep_p, submenu); */
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
/* Menu may have been created automatically; if so, discard it. */
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
}
{
free_menubar_widget_value_tree (first_wv);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
{
free_menubar_widget_value_tree (first_wv);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
}
[NSApp setMainMenu: menu];
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
Under NS we just hide the toolbar until it might be needed again.
-------------------------------------------------------------------------- */
{
- BLOCK_INPUT;
+ block_input ();
[[FRAME_NS_VIEW (f) toolbar] setVisible: NO];
FRAME_TOOLBAR_HEIGHT (f) = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
NSWindow *window = [view window];
EmacsToolbar *toolbar = [view toolbar];
- BLOCK_INPUT;
+ block_input ();
[toolbar clearActive];
/* update EmacsToolbar as in GtkUtils, build items list */
FRAME_TOOLBAR_HEIGHT (f) =
NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
- FRAME_NS_TITLEBAR_HEIGHT (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
struct Popdown_data *unwind_data = (struct Popdown_data *) p->pointer;
- BLOCK_INPUT;
+ block_input ();
if (popup_activated_flag)
{
EmacsDialogPanel *panel = unwind_data->dialog;
}
xfree (unwind_data);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
the dialog. */
contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
dialog = [[EmacsDialogPanel alloc] initFromContents: contents
isQuestion: isQ];
unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */
}
- UNBLOCK_INPUT;
+ unblock_input ();
return tem;
}
#endif
#ifdef NS_IMPL_COCOA
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
- BLOCK_INPUT;
+ block_input ();
NSTRACE (ns_update_auto_hide_menu_bar);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
#endif
#endif
}
updated_window = w;
set_output_cursor (&w->cursor);
- BLOCK_INPUT;
+ block_input ();
if (f == hlinfo->mouse_face_mouse_frame)
{
/* (further code for mouse faces ifdef'd out in other terms elided) */
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* note: this fn is nearly identical in all terms */
if (!w->pseudo_window_p)
{
- BLOCK_INPUT;
+ block_input ();
if (cursor_on_p)
display_and_set_cursor (w, 1,
if (draw_window_fringes (w, 1))
x_draw_vertical_border (w);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If a row with mouse-face was overwritten, arrange for
/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
MOUSE_HL_INFO (f)->mouse_face_defer = 0;
- BLOCK_INPUT;
+ block_input ();
#ifdef NS_IMPL_GNUSTEP
/* trigger flush only in the rectangle we tracked as being drawn */
[view unlockFocus];
[[view window] flushWindow];
- UNBLOCK_INPUT;
+ unblock_input ();
ns_updating_frame = NULL;
NSTRACE (ns_update_end);
}
struct frame *frame = SELECTED_FRAME ();
NSView *view;
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
view = FRAME_NS_VIEW (frame);
ns_unfocus (frame);
}
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
else
{
{
NSView *view = FRAME_NS_VIEW (f);
check_ns ();
- BLOCK_INPUT;
+ block_input ();
FRAME_SAMPLE_VISIBILITY (f);
if (FRAME_VISIBLE_P (f))
{
[[view window] makeKeyAndOrderFront: NSApp];
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
NSView *view = FRAME_NS_VIEW (f);
check_ns ();
- BLOCK_INPUT;
+ block_input ();
[[view window] orderBack: NSApp];
- UNBLOCK_INPUT;
+ unblock_input ();
}
[(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */
- BLOCK_INPUT;
+ block_input ();
free_frame_menubar (f);
xfree (f->output_data.ns);
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
NSTRACE (x_set_offset);
- BLOCK_INPUT;
+ block_input ();
f->left_pos = xoff;
f->top_pos = yoff;
f->size_hint_flags &= ~(XNegative|YNegative);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/*fprintf (stderr, "\tsetWindowSize: %d x %d, font size %d x %d\n", cols, rows, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f)); */
- BLOCK_INPUT;
+ block_input ();
check_frame_size (f, &rows, &cols);
mark_window_cursors_off (XWINDOW (f->root_window));
cancel_mouse_face (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
NSString *nsname = [NSString stringWithUTF8String: name];
/*fprintf (stderr, "ns_get_color: '%s'\n", name); */
- BLOCK_INPUT;
+ block_input ();
if ([nsname isEqualToString: @"ns_selection_color"])
{
if (r >= 0.0)
{
*col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0];
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
if (new)
*col = [new colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
- UNBLOCK_INPUT;
+ unblock_input ();
return new ? 0 : 1;
}
const char *str;
NSTRACE (ns_color_to_lisp);
- BLOCK_INPUT;
+ block_input ();
if ([[col colorSpaceName] isEqualToString: NSNamedColorSpace])
if ((str =[[col colorNameComponent] UTF8String]))
{
- UNBLOCK_INPUT;
+ unblock_input ();
return build_string ((char *)str);
}
getWhite: &gray alpha: &alpha];
snprintf (buf, sizeof (buf), "#%2.2lx%2.2lx%2.2lx",
lrint (gray * 0xff), lrint (gray * 0xff), lrint (gray * 0xff));
- UNBLOCK_INPUT;
+ unblock_input ();
return build_string (buf);
}
snprintf (buf, sizeof (buf), "#%2.2lx%2.2lx%2.2lx",
lrint (red*0xff), lrint (green*0xff), lrint (blue*0xff));
- UNBLOCK_INPUT;
+ unblock_input ();
return build_string (buf);
}
NSColor *col;
NSTRACE (ns_defined_color);
- BLOCK_INPUT;
+ block_input ();
if (ns_get_color (name, &col) != 0) /* Color not found */
{
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
if (makeIndex && alloc)
color_def->pixel = ns_index_color (col, f);
ns_query_color (col, color_def, !makeIndex);
- UNBLOCK_INPUT;
+ unblock_input ();
return 1;
}
dpyinfo = FRAME_NS_DISPLAY_INFO (*fp);
- BLOCK_INPUT;
+ block_input ();
if (last_mouse_scroll_bar != nil && insist == 0)
{
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
if ((hlinfo->mouse_face_deferred_gc || f ==hlinfo->mouse_face_mouse_frame)
/*&& hlinfo->mouse_face_mouse_frame*/)
{
- BLOCK_INPUT;
+ block_input ();
ns_update_begin(f);
if (hlinfo->mouse_face_mouse_frame)
note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
hlinfo->mouse_face_mouse_y);
hlinfo->mouse_face_deferred_gc = 0;
ns_update_end(f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
r = [view bounds];
- BLOCK_INPUT;
+ block_input ();
ns_focus (f, &r, 1);
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (FRAME_DEFAULT_FACE (f)), f) set];
NSRectFill (r);
/* as of 2006/11 or so this is now needed */
ns_redraw_scroll_bars (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (height == 0)
return;
- BLOCK_INPUT;
+ block_input ();
updated_window = w;
x_clear_cursor (w);
ns_unfocus (f);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- BLOCK_INPUT;
+ block_input ();
ns_clear_frame_area (f, 0, y, width, height);
ns_clear_frame_area (f,
FRAME_PIXEL_WIDTH (f) - width,
y, width, height);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
if (hourglass_shown_p)
return;
- BLOCK_INPUT;
+ block_input ();
/* TODO: add NSProgressIndicator to selected frame (see macfns.c) */
hourglass_shown_p = 1;
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!hourglass_shown_p)
return;
- BLOCK_INPUT;
+ block_input ();
/* TODO: remove NSProgressIndicator from all frames */
hourglass_shown_p = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
if ([NSApp modalWindow] != nil)
return -1;
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- pending_signals = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- pending_signals = pending_atimers;
-
- BLOCK_INPUT;
+ block_input ();
n_emacs_events_pending = 0;
EVENT_INIT (ev);
emacs_event = &ev;
nevents = n_emacs_events_pending;
n_emacs_events_pending = 0;
emacs_event = q_event_ptr = NULL;
- UNBLOCK_INPUT;
+ unblock_input ();
return nevents;
}
}
EVENT_INIT (event);
- BLOCK_INPUT;
+ block_input ();
emacs_event = &event;
if (++apploopnr != 1)
{
c = 's';
write (selfds[1], &c, 1);
}
- UNBLOCK_INPUT;
+ unblock_input ();
ev = last_appdefined_event;
|| WINDOW_RIGHT_MARGIN_COLS (window) == 0));
XSETWINDOW (win, window);
- BLOCK_INPUT;
+ block_input ();
/* we want at least 5 lines to display a scrollbar */
if (WINDOW_TOTAL_LINES (window) < 5)
wset_vertical_scroll_bar (window, Qnil);
}
ns_clear_frame_area (f, sb_left, top, width, height);
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
}
[bar setPosition: position portion: portion whole: whole];
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!terminal->name)
return;
- BLOCK_INPUT;
+ block_input ();
x_destroy_all_bitmaps (dpyinfo);
ns_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* count object allocs (About, click icon); on OS X use ObjectAlloc tool */
/*GSDebugAllocationActive (YES); */
- BLOCK_INPUT;
+ block_input ();
baud_rate = 38400;
Fset_input_interrupt_mode (Qnil);
terminal->name = xstrdup (SSDATA (display_name));
- UNBLOCK_INPUT;
+ unblock_input ();
if (!inhibit_x_resources)
{
- (void)setFrame: (NSRect)newRect
{
NSTRACE (EmacsScroller_setFrame);
-/* BLOCK_INPUT; */
+/* block_input (); */
pixel_height = NSHeight (newRect);
if (pixel_height == 0) pixel_height = 1;
min_portion = 20 / pixel_height;
[super setFrame: newRect];
[self display];
-/* UNBLOCK_INPUT; */
+/* unblock_input (); */
}
if (condemned)
{
EmacsView *view;
- BLOCK_INPUT;
+ block_input ();
/* ensure other scrollbar updates after deletion */
view = (EmacsView *)FRAME_NS_VIEW (frame);
if (view != nil)
view->scrollbarsNeedingUpdate++;
[self removeFromSuperview];
[self release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
return self;
}
{
if (initial_stderr_stream != NULL)
{
- BLOCK_INPUT;
+ block_input ();
fclose (stderr);
- UNBLOCK_INPUT;
+ unblock_input ();
}
stderr = initial_stderr_stream;
initial_stderr_stream = NULL;
static void deactivate_process (Lisp_Object);
static void status_notify (struct Lisp_Process *);
static int read_process_output (Lisp_Object, int);
+static void handle_child_signal (int);
static void create_pty (Lisp_Object);
/* 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
int wait_child_setup[2];
#endif
#ifdef SIGCHLD
- sigset_t blocked, procmask;
+ sigset_t blocked;
#endif
/* Use volatile to protect variables from being clobbered by vfork. */
volatile int forkin, forkout;
volatile int pty_flag = 0;
+ volatile Lisp_Object lisp_pty_name = Qnil;
+ volatile Lisp_Object encoded_current_dir;
+#if HAVE_WORKING_VFORK
+ char **volatile save_environ;
+#endif
inchannel = outchannel = -1;
forkin = forkout = -1;
#endif /* not USG, or USG_SUBTTY_WORKS */
pty_flag = 1;
+ lisp_pty_name = build_string (pty_name);
}
else
#endif /* HAVE_PTYS */
XPROCESS (process)->pty_flag = pty_flag;
pset_status (XPROCESS (process), Qrun);
-#ifdef SIGCHLD
- /* Delay interrupts until we have a chance to store
- the new fork's pid in its process structure */
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGCHLD);
- pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
-#endif
-
FD_SET (inchannel, &input_wait_mask);
FD_SET (inchannel, &non_keyboard_wait_mask);
if (inchannel > max_process_desc)
error. */
setup_process_coding_systems (process);
- BLOCK_INPUT;
+ encoded_current_dir = ENCODE_FILE (current_dir);
- {
- /* child_setup must clobber environ on systems with true vfork.
- Protect it from permanent change. */
- char **save_environ = environ;
- volatile Lisp_Object encoded_current_dir = ENCODE_FILE (current_dir);
+ block_input ();
+
+#ifdef SIGCHLD
+ /* Block SIGCHLD until we have a chance to store the new fork's
+ pid in its process structure. */
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGCHLD);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
+#endif
+
+#if HAVE_WORKING_VFORK
+ /* child_setup must clobber environ on systems with true vfork.
+ Protect it from permanent change. */
+ save_environ = environ;
+#endif
#ifndef WINDOWSNT
- pid = vfork ();
- if (pid == 0)
+ pid = vfork ();
+ if (pid == 0)
#endif /* not WINDOWSNT */
- {
- int xforkin = forkin;
- int xforkout = forkout;
+ {
+ int xforkin = forkin;
+ int xforkout = forkout;
- /* Make the pty be the controlling terminal of the process. */
+ /* Make the pty be the controlling terminal of the process. */
#ifdef HAVE_PTYS
- /* First, disconnect its current controlling terminal. */
+ /* First, disconnect its current controlling terminal. */
#ifdef HAVE_SETSID
- /* We tried doing setsid only if pty_flag, but it caused
- process_set_signal to fail on SGI when using a pipe. */
- setsid ();
- /* Make the pty's terminal the controlling terminal. */
- if (pty_flag && xforkin >= 0)
- {
+ /* We tried doing setsid only if pty_flag, but it caused
+ process_set_signal to fail on SGI when using a pipe. */
+ setsid ();
+ /* Make the pty's terminal the controlling terminal. */
+ if (pty_flag && xforkin >= 0)
+ {
#ifdef TIOCSCTTY
- /* We ignore the return value
- because faith@cs.unc.edu says that is necessary on Linux. */
- ioctl (xforkin, TIOCSCTTY, 0);
+ /* We ignore the return value
+ because faith@cs.unc.edu says that is necessary on Linux. */
+ ioctl (xforkin, TIOCSCTTY, 0);
#endif
- }
+ }
#else /* not HAVE_SETSID */
#ifdef USG
- /* It's very important to call setpgrp here and no time
- afterwards. Otherwise, we lose our controlling tty which
- is set when we open the pty. */
- setpgrp ();
+ /* It's very important to call setpgrp here and no time
+ afterwards. Otherwise, we lose our controlling tty which
+ is set when we open the pty. */
+ setpgrp ();
#endif /* USG */
#endif /* not HAVE_SETSID */
#if defined (LDISC1)
- if (pty_flag && xforkin >= 0)
- {
- struct termios t;
- tcgetattr (xforkin, &t);
- t.c_lflag = LDISC1;
- if (tcsetattr (xforkin, TCSANOW, &t) < 0)
- emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39);
- }
+ if (pty_flag && xforkin >= 0)
+ {
+ struct termios t;
+ tcgetattr (xforkin, &t);
+ t.c_lflag = LDISC1;
+ if (tcsetattr (xforkin, TCSANOW, &t) < 0)
+ emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39);
+ }
#else
#if defined (NTTYDISC) && defined (TIOCSETD)
- if (pty_flag && xforkin >= 0)
- {
- /* Use new line discipline. */
- int ldisc = NTTYDISC;
- ioctl (xforkin, TIOCSETD, &ldisc);
- }
+ if (pty_flag && xforkin >= 0)
+ {
+ /* Use new line discipline. */
+ int ldisc = NTTYDISC;
+ ioctl (xforkin, TIOCSETD, &ldisc);
+ }
#endif
#endif
#ifdef TIOCNOTTY
- /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you
- can do TIOCSPGRP only to the process's controlling tty. */
- if (pty_flag)
- {
- /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here?
- I can't test it since I don't have 4.3. */
- int j = emacs_open ("/dev/tty", O_RDWR, 0);
- if (j >= 0)
- {
- ioctl (j, TIOCNOTTY, 0);
- emacs_close (j);
- }
+ /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you
+ can do TIOCSPGRP only to the process's controlling tty. */
+ if (pty_flag)
+ {
+ /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here?
+ I can't test it since I don't have 4.3. */
+ int j = emacs_open ("/dev/tty", O_RDWR, 0);
+ if (j >= 0)
+ {
+ ioctl (j, TIOCNOTTY, 0);
+ emacs_close (j);
+ }
#ifndef USG
- /* In order to get a controlling terminal on some versions
- of BSD, it is necessary to put the process in pgrp 0
- before it opens the terminal. */
+ /* In order to get a controlling terminal on some versions
+ of BSD, it is necessary to put the process in pgrp 0
+ before it opens the terminal. */
#ifdef HAVE_SETPGID
- setpgid (0, 0);
+ setpgid (0, 0);
#else
- setpgrp (0, 0);
+ setpgrp (0, 0);
#endif
#endif
- }
+ }
#endif /* TIOCNOTTY */
#if !defined (DONT_REOPEN_PTY)
both HAVE_SETSID and TIOCSCTTY are defined. */
/* Now close the pty (if we had it open) and reopen it.
This makes the pty the controlling terminal of the subprocess. */
- if (pty_flag)
- {
+ if (pty_flag)
+ {
- /* I wonder if emacs_close (emacs_open (pty_name, ...))
- would work? */
- if (xforkin >= 0)
- emacs_close (xforkin);
- xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0);
+ /* I wonder if emacs_close (emacs_open (pty_name, ...))
+ would work? */
+ if (xforkin >= 0)
+ emacs_close (xforkin);
+ xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0);
- if (xforkin < 0)
- {
- emacs_write (1, "Couldn't open the pty terminal ", 31);
- emacs_write (1, pty_name, strlen (pty_name));
- emacs_write (1, "\n", 1);
- _exit (1);
- }
+ if (xforkin < 0)
+ {
+ emacs_write (1, "Couldn't open the pty terminal ", 31);
+ emacs_write (1, pty_name, strlen (pty_name));
+ emacs_write (1, "\n", 1);
+ _exit (1);
+ }
- }
+ }
#endif /* not DONT_REOPEN_PTY */
#ifdef SETUP_SLAVE_PTY
- if (pty_flag)
- {
- SETUP_SLAVE_PTY;
- }
+ if (pty_flag)
+ {
+ SETUP_SLAVE_PTY;
+ }
#endif /* SETUP_SLAVE_PTY */
#ifdef AIX
- /* On AIX, we've disabled SIGHUP above once we start a child on a pty.
- Now reenable it in the child, so it will die when we want it to. */
- if (pty_flag)
- signal (SIGHUP, SIG_DFL);
+ /* On AIX, we've disabled SIGHUP above once we start a child on a pty.
+ Now reenable it in the child, so it will die when we want it to. */
+ if (pty_flag)
+ signal (SIGHUP, SIG_DFL);
#endif
#endif /* HAVE_PTYS */
- signal (SIGINT, SIG_DFL);
- signal (SIGQUIT, SIG_DFL);
- /* GConf causes us to ignore SIGPIPE, make sure it is restored
- in the child. */
- signal (SIGPIPE, SIG_DFL);
+ signal (SIGINT, SIG_DFL);
+ signal (SIGQUIT, SIG_DFL);
+
+ /* Emacs ignores SIGPIPE, but the child should not. */
+ signal (SIGPIPE, SIG_DFL);
#ifdef SIGCHLD
/* Stop blocking signals in the child. */
- pthread_sigmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
#endif
- if (pty_flag)
- child_setup_tty (xforkout);
+ if (pty_flag)
+ child_setup_tty (xforkout);
#ifdef WINDOWSNT
- pid = child_setup (xforkin, xforkout, xforkout,
- new_argv, 1, encoded_current_dir);
+ pid = child_setup (xforkin, xforkout, xforkout,
+ new_argv, 1, encoded_current_dir);
#else /* not WINDOWSNT */
#ifdef FD_CLOEXEC
- emacs_close (wait_child_setup[0]);
+ emacs_close (wait_child_setup[0]);
#endif
- child_setup (xforkin, xforkout, xforkout,
- new_argv, 1, encoded_current_dir);
+ child_setup (xforkin, xforkout, xforkout,
+ new_argv, 1, encoded_current_dir);
#endif /* not WINDOWSNT */
- }
- environ = save_environ;
- }
+ }
+
+ /* Back in the parent process. */
+
+#if HAVE_WORKING_VFORK
+ environ = save_environ;
+#endif
+
+ XPROCESS (process)->pid = pid;
- UNBLOCK_INPUT;
+ /* Stop blocking signals in the parent. */
+#ifdef SIGCHLD
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+#endif
+ unblock_input ();
- /* This runs in the Emacs process. */
if (pid < 0)
{
if (forkin >= 0)
else
{
/* vfork succeeded. */
- XPROCESS (process)->pid = pid;
#ifdef WINDOWSNT
register_child (pid, inchannel);
if (forkin != forkout && forkout >= 0)
emacs_close (forkout);
-#ifdef HAVE_PTYS
- if (pty_flag)
- pset_tty_name (XPROCESS (process), build_string (pty_name));
- else
-#endif
- pset_tty_name (XPROCESS (process), Qnil);
+ pset_tty_name (XPROCESS (process), lisp_pty_name);
#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
/* Wait for child_setup to complete in case that vfork is
#endif
}
-#ifdef SIGCHLD
- /* Stop blocking signals in the parent. */
- pthread_sigmask (SIG_SETMASK, &procmask, 0);
-#endif
-
/* Now generate the error if vfork failed. */
if (pid < 0)
report_file_error ("Doing vfork", Qnil);
#ifdef HAVE_GETADDRINFO
if (res != &ai)
{
- BLOCK_INPUT;
+ block_input ();
freeaddrinfo (res);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif
Otherwise, do pending quit if requested. */
if (read_kbd >= 0)
QUIT;
- else
+ else if (pending_signals)
process_pending_signals ();
/* Exit now if the cell we're waiting for became non-nil. */
check_write = 0;
}
-#if 0 /* When polling is used, interrupt_input is 0,
- so get_input_pending should read the input.
- So this should not be needed. */
- /* If we are using polling for input,
- and we see input available, make it get read now.
- Otherwise it might not actually get read for a second.
- And on hpux, since we turn off polling in wait_reading_process_output,
- it might never get read at all if we don't spend much time
- outside of wait_reading_process_output. */
- if (read_kbd && interrupt_input
- && keyboard_bit_set (&Available)
- && input_polling_used ())
- kill (getpid (), SIGALRM);
-#endif
-
/* Check for keyboard input */
/* If there is any, return immediately
to give it higher priority than subprocesses */
if (read_kbd && interrupt_input
&& keyboard_bit_set (&Available) && ! noninteractive)
- kill (getpid (), SIGIO);
+ handle_input_available_signal (SIGIO);
#endif
if (! wait_proc)
pset_status (p, Qfailed);
}
else
- kill (getpid (), SIGCHLD);
+ handle_child_signal (SIGCHLD);
}
#endif /* HAVE_PTYS */
/* If we can detect process termination, don't consider the
\f
/* Sending data to subprocess */
-static sys_jmp_buf send_process_frame;
-static Lisp_Object process_sent_to;
-
-static _Noreturn void
-handle_pipe_signal (int sig)
-{
- sigset_t unblocked;
- sigemptyset (&unblocked);
- sigaddset (&unblocked, SIGPIPE);
- pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
- sys_longjmp (send_process_frame, 1);
-}
-
-static void
-deliver_pipe_signal (int sig)
-{
- handle_on_main_thread (sig, handle_pipe_signal);
-}
-
/* In send_process, when a write fails temporarily,
wait_reading_process_output is called. It may execute user code,
e.g. timers, that attempts to write new data to the same process.
This function can evaluate Lisp code and can garbage collect. */
static void
-send_process (volatile Lisp_Object proc, const char *volatile buf,
- volatile ptrdiff_t len, volatile Lisp_Object object)
+send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
+ Lisp_Object object)
{
- /* Use volatile to protect variables from being clobbered by longjmp. */
struct Lisp_Process *p = XPROCESS (proc);
ssize_t rv;
struct coding_system *coding;
- struct sigaction old_sigpipe_action;
if (p->raw_status_new)
update_status (p);
pty_max_bytes--;
}
- /* 2000-09-21: Emacs 20.7, sparc-sun-solaris-2.6, GCC 2.95.2,
- CFLAGS="-g -O": The value of the parameter `proc' is clobbered
- when returning with longjmp despite being declared volatile. */
- if (!sys_setjmp (send_process_frame))
- {
- p = XPROCESS (proc); /* Repair any setjmp clobbering. */
- process_sent_to = proc;
+ /* If there is already data in the write_queue, put the new data
+ in the back of queue. Otherwise, ignore it. */
+ if (!NILP (p->write_queue))
+ write_queue_push (p, object, buf, len, 0);
- /* If there is already data in the write_queue, put the new data
- in the back of queue. Otherwise, ignore it. */
- if (!NILP (p->write_queue))
- write_queue_push (p, object, buf, len, 0);
+ do /* while !NILP (p->write_queue) */
+ {
+ ptrdiff_t cur_len = -1;
+ const char *cur_buf;
+ Lisp_Object cur_object;
- do /* while !NILP (p->write_queue) */
+ /* If write_queue is empty, ignore it. */
+ if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len))
{
- ptrdiff_t cur_len = -1;
- const char *cur_buf;
- Lisp_Object cur_object;
+ cur_len = len;
+ cur_buf = buf;
+ cur_object = object;
+ }
- /* If write_queue is empty, ignore it. */
- if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len))
+ while (cur_len > 0)
+ {
+ /* Send this batch, using one or more write calls. */
+ ptrdiff_t written = 0;
+ int outfd = p->outfd;
+#ifdef DATAGRAM_SOCKETS
+ if (DATAGRAM_CHAN_P (outfd))
{
- cur_len = len;
- cur_buf = buf;
- cur_object = object;
+ rv = sendto (outfd, cur_buf, cur_len,
+ 0, datagram_address[outfd].sa,
+ datagram_address[outfd].len);
+ if (0 <= rv)
+ written = rv;
+ else if (errno == EMSGSIZE)
+ report_file_error ("sending datagram", Fcons (proc, Qnil));
}
-
- while (cur_len > 0)
- {
- /* Send this batch, using one or more write calls. */
- ptrdiff_t written = 0;
- int outfd = p->outfd;
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_pipe_signal);
- sigaction (SIGPIPE, &action, &old_sigpipe_action);
-#ifdef DATAGRAM_SOCKETS
- if (DATAGRAM_CHAN_P (outfd))
- {
- rv = sendto (outfd, cur_buf, cur_len,
- 0, datagram_address[outfd].sa,
- datagram_address[outfd].len);
- if (0 <= rv)
- written = rv;
- else if (errno == EMSGSIZE)
- {
- sigaction (SIGPIPE, &old_sigpipe_action, 0);
- report_file_error ("sending datagram",
- Fcons (proc, Qnil));
- }
- }
- else
+ else
#endif
- {
+ {
#ifdef HAVE_GNUTLS
- if (p->gnutls_p)
- written = emacs_gnutls_write (p, cur_buf, cur_len);
- else
+ if (p->gnutls_p)
+ written = emacs_gnutls_write (p, cur_buf, cur_len);
+ else
#endif
- written = emacs_write (outfd, cur_buf, cur_len);
- rv = (written ? 0 : -1);
+ written = emacs_write (outfd, cur_buf, cur_len);
+ rv = (written ? 0 : -1);
#ifdef ADAPTIVE_READ_BUFFERING
- if (p->read_output_delay > 0
- && p->adaptive_read_buffering == 1)
- {
- p->read_output_delay = 0;
- process_output_delay_count--;
- p->read_output_skip = 0;
- }
-#endif
+ if (p->read_output_delay > 0
+ && p->adaptive_read_buffering == 1)
+ {
+ p->read_output_delay = 0;
+ process_output_delay_count--;
+ p->read_output_skip = 0;
}
- sigaction (SIGPIPE, &old_sigpipe_action, 0);
+#endif
+ }
- if (rv < 0)
- {
- if (0
+ if (rv < 0)
+ {
+ if (0
#ifdef EWOULDBLOCK
- || errno == EWOULDBLOCK
+ || errno == EWOULDBLOCK
#endif
#ifdef EAGAIN
- || errno == EAGAIN
+ || errno == EAGAIN
#endif
- )
- /* Buffer is full. Wait, accepting input;
- that may allow the program
- to finish doing output and read more. */
- {
+ )
+ /* Buffer is full. Wait, accepting input;
+ that may allow the program
+ to finish doing output and read more. */
+ {
#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
- /* A gross hack to work around a bug in FreeBSD.
- In the following sequence, read(2) returns
- bogus data:
-
- write(2) 1022 bytes
- write(2) 954 bytes, get EAGAIN
- read(2) 1024 bytes in process_read_output
- read(2) 11 bytes in process_read_output
-
- That is, read(2) returns more bytes than have
- ever been written successfully. The 1033 bytes
- read are the 1022 bytes written successfully
- after processing (for example with CRs added if
- the terminal is set up that way which it is
- here). The same bytes will be seen again in a
- later read(2), without the CRs. */
-
- if (errno == EAGAIN)
- {
- int flags = FWRITE;
- ioctl (p->outfd, TIOCFLUSH, &flags);
- }
+ /* A gross hack to work around a bug in FreeBSD.
+ In the following sequence, read(2) returns
+ bogus data:
+
+ write(2) 1022 bytes
+ write(2) 954 bytes, get EAGAIN
+ read(2) 1024 bytes in process_read_output
+ read(2) 11 bytes in process_read_output
+
+ That is, read(2) returns more bytes than have
+ ever been written successfully. The 1033 bytes
+ read are the 1022 bytes written successfully
+ after processing (for example with CRs added if
+ the terminal is set up that way which it is
+ here). The same bytes will be seen again in a
+ later read(2), without the CRs. */
+
+ if (errno == EAGAIN)
+ {
+ int flags = FWRITE;
+ ioctl (p->outfd, TIOCFLUSH, &flags);
+ }
#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
- /* Put what we should have written in wait_queue. */
- write_queue_push (p, cur_object, cur_buf, cur_len, 1);
- wait_reading_process_output (0, 20 * 1000 * 1000,
- 0, 0, Qnil, NULL, 0);
- /* Reread queue, to see what is left. */
- break;
- }
- else
- /* This is a real error. */
- report_file_error ("writing to process", Fcons (proc, Qnil));
+ /* Put what we should have written in wait_queue. */
+ write_queue_push (p, cur_object, cur_buf, cur_len, 1);
+ wait_reading_process_output (0, 20 * 1000 * 1000,
+ 0, 0, Qnil, NULL, 0);
+ /* Reread queue, to see what is left. */
+ break;
}
- cur_buf += written;
- cur_len -= written;
+ else if (errno == EPIPE)
+ {
+ p->raw_status_new = 0;
+ pset_status (p, list2 (Qexit, make_number (256)));
+ p->tick = ++process_tick;
+ deactivate_process (proc);
+ error ("process %s no longer connected to pipe; closed it",
+ SDATA (p->name));
+ }
+ else
+ /* This is a real error. */
+ report_file_error ("writing to process", Fcons (proc, Qnil));
}
+ cur_buf += written;
+ cur_len -= written;
}
- while (!NILP (p->write_queue));
- }
- else
- {
- sigaction (SIGPIPE, &old_sigpipe_action, 0);
- proc = process_sent_to;
- p = XPROCESS (proc);
- p->raw_status_new = 0;
- pset_status (p, Fcons (Qexit, Fcons (make_number (256), Qnil)));
- p->tick = ++process_tick;
- deactivate_process (proc);
- error ("SIGPIPE raised on process %s; closed it", SDATA (p->name));
}
+ while (!NILP (p->write_queue));
}
DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,
#ifdef SIGUSR2
parse_signal ("usr2", SIGUSR2);
#endif
-#ifdef SIGTERM
parse_signal ("term", SIGTERM);
-#endif
#ifdef SIGHUP
parse_signal ("hup", SIGHUP);
#endif
-#ifdef SIGINT
parse_signal ("int", SIGINT);
-#endif
#ifdef SIGQUIT
parse_signal ("quit", SIGQUIT);
#endif
-#ifdef SIGILL
parse_signal ("ill", SIGILL);
-#endif
-#ifdef SIGABRT
parse_signal ("abrt", SIGABRT);
-#endif
#ifdef SIGEMT
parse_signal ("emt", SIGEMT);
#endif
#ifdef SIGKILL
parse_signal ("kill", SIGKILL);
#endif
-#ifdef SIGFPE
parse_signal ("fpe", SIGFPE);
-#endif
#ifdef SIGBUS
parse_signal ("bus", SIGBUS);
#endif
-#ifdef SIGSEGV
parse_signal ("segv", SIGSEGV);
-#endif
#ifdef SIGSYS
parse_signal ("sys", SIGSYS);
#endif
** Malloc WARNING: This should never call malloc either directly or
indirectly; if it does, that is a bug */
-#ifdef SIGCHLD
-
-/* Record one child's changed status. Return true if a child was found. */
-static bool
-record_child_status_change (void)
+/* Record the changed status of the child process PID with wait status W. */
+void
+record_child_status_change (pid_t pid, int w)
{
+#ifdef SIGCHLD
Lisp_Object proc;
struct Lisp_Process *p;
- pid_t pid;
- int w;
Lisp_Object tail;
- do
- pid = waitpid (-1, &w, WNOHANG | WUNTRACED);
- while (pid < 0 && errno == EINTR);
-
- /* PID == 0 means no processes found, PID == -1 means a real failure.
- Either way, we have done all our job. */
- if (pid <= 0)
- return false;
-
/* Find the process that signaled us, and record its status. */
/* The process can have been deleted by Fdelete_process. */
|| (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
{
XSETCAR (tail, Qnil);
- return true;
+ return;
}
}
if (input_available_clear_time)
*input_available_clear_time = make_emacs_time (0, 0);
}
-
- return true;
+#endif
}
+#ifdef SIGCHLD
+
/* On some systems, the SIGCHLD handler must return right away. If
any more processes want to signal us, we will get another signal.
Otherwise, loop around to use up all the processes that have
static void
handle_child_signal (int sig)
{
- while (record_child_status_change () && CAN_HANDLE_MULTIPLE_CHILDREN)
- continue;
+ do
+ {
+ pid_t pid;
+ int status;
+
+ do
+ pid = waitpid (-1, &status, WNOHANG | WUNTRACED);
+ while (pid < 0 && errno == EINTR);
+
+ /* PID == 0 means no processes found, PID == -1 means a real failure.
+ Either way, we have done all our job. */
+ if (pid <= 0)
+ break;
+
+ record_child_status_change (pid, status);
+ }
+ while (CAN_HANDLE_MULTIPLE_CHILDREN);
}
static void
deliver_child_signal (int sig)
{
- handle_on_main_thread (sig, handle_child_signal);
+ deliver_process_signal (sig, handle_child_signal);
}
#endif /* SIGCHLD */
#endif
#ifdef DOUG_LEA_MALLOC
- BLOCK_INPUT;
+ block_input ();
mallopt (M_TOP_PAD, 64 * 4096);
- UNBLOCK_INPUT;
+ unblock_input ();
#else
#ifndef SYSTEM_MALLOC
/* Give GNU malloc's morecore some hysteresis so that we move all
re_set_whitespace_regexp (NULL);
re_set_syntax (old);
- /* UNBLOCK_INPUT; */
+ /* unblock_input (); */
if (val)
xsignal1 (Qinvalid_regexp, build_string (val));
\f
-/* Set nonzero to make following function work under dbx
- (at least for bsd). */
-int wait_debugging EXTERNALLY_VISIBLE;
-
#ifndef MSDOS
static void
{
while (1)
{
-#if (defined (BSD_SYSTEM) || defined (HPUX)) && !defined (__GNU__)
- /* Note that kill returns -1 even if the process is just a zombie now.
- But inevitably a SIGCHLD interrupt should be generated
- and child_sig will do waitpid and make the process go away. */
- /* There is some indication that there is a bug involved with
- termination of subprocesses, perhaps involving a kernel bug too,
- but no idea what it is. Just as a hunch we signal SIGCHLD to see
- if that causes the problem to go away or get worse. */
- sigset_t sigchild_mask;
- sigemptyset (&sigchild_mask);
- sigaddset (&sigchild_mask, SIGCHLD);
- pthread_sigmask (SIG_SETMASK, &sigchild_mask, 0);
-
- if (0 > kill (pid, 0))
- {
- pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
- kill (getpid (), SIGCHLD);
- break;
- }
- if (wait_debugging)
- sleep (1);
- else
- sigsuspend (&empty_mask);
-#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
#ifdef WINDOWSNT
wait (0);
break;
#else /* not WINDOWSNT */
- sigset_t blocked;
- sigemptyset (&blocked);
- sigaddset (&blocked, SIGCHLD);
- pthread_sigmask (SIG_BLOCK, &blocked, 0);
- errno = 0;
- if (kill (pid, 0) == -1 && errno == ESRCH)
+ int status;
+ int wait_result = waitpid (pid, &status, 0);
+ if (wait_result < 0)
{
- pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
+ if (errno != EINTR)
+ break;
+ }
+ else
+ {
+ record_child_status_change (wait_result, status);
break;
}
- sigsuspend (&empty_mask);
#endif /* not WINDOWSNT */
-#endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
if (interruptible)
QUIT;
}
\f
sigset_t empty_mask;
-/* Store into *ACTION a signal action suitable for Emacs, with handler
- HANDLER. */
-void
-emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
+static struct sigaction process_fatal_action;
+
+static int
+emacs_sigaction_flags (void)
{
- sigemptyset (&action->sa_mask);
- action->sa_handler = handler;
- action->sa_flags = 0;
-#if defined (SA_RESTART)
+#ifdef SA_RESTART
/* SA_RESTART causes interruptible functions with timeouts (e.g.,
'select') to reset their timeout on some platforms (e.g.,
HP-UX 11), which is not what we want. Also, when Emacs is
interactive, we don't want SA_RESTART because we need to poll
for pending input so we need long-running syscalls to be interrupted
- after a signal that sets the interrupt_input_pending flag. */
- /* Non-interactive keyboard input goes through stdio, where we always
- want restartable system calls. */
+ after a signal that sets pending_signals.
+
+ Non-interactive keyboard input goes through stdio, where we
+ always want restartable system calls. */
if (noninteractive)
- action->sa_flags = SA_RESTART;
+ return SA_RESTART;
#endif
+ return 0;
+}
+
+/* Store into *ACTION a signal action suitable for Emacs, with handler
+ HANDLER. */
+void
+emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
+{
+ sigemptyset (&action->sa_mask);
+
+ /* When handling a signal, block nonfatal system signals that are caught
+ by Emacs. This makes race conditions less likely. */
+ sigaddset (&action->sa_mask, SIGALRM);
+#ifdef SIGCHLD
+ sigaddset (&action->sa_mask, SIGCHLD);
+#endif
+#ifdef SIGDANGER
+ sigaddset (&action->sa_mask, SIGDANGER);
+#endif
+#ifdef SIGWINCH
+ sigaddset (&action->sa_mask, SIGWINCH);
+#endif
+ if (! noninteractive)
+ {
+ sigaddset (&action->sa_mask, SIGINT);
+ sigaddset (&action->sa_mask, SIGQUIT);
+#ifdef USABLE_SIGIO
+ sigaddset (&action->sa_mask, SIGIO);
+#endif
+ }
+
+ if (! IEEE_FLOATING_POINT)
+ sigaddset (&action->sa_mask, SIGFPE);
+
+ action->sa_handler = handler;
+ action->sa_flags = emacs_sigaction_flags ();
}
#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
static pthread_t main_thread;
#endif
-/* If we are on the main thread, handle the signal SIG with HANDLER.
+/* SIG has arrived at the current process. Deliver it to the main
+ thread, which should handle it with HANDLER.
+
+ If we are on the main thread, handle the signal SIG with HANDLER.
Otherwise, redirect the signal to the main thread, blocking it from
this thread. POSIX says any thread can receive a signal that is
associated with a process, process group, or asynchronous event.
On GNU/Linux that is not true, but for other systems (FreeBSD at
least) it is. */
void
-handle_on_main_thread (int sig, signal_handler_t handler)
+deliver_process_signal (int sig, signal_handler_t handler)
{
/* Preserve errno, to avoid race conditions with signal handlers that
might change errno. Races can occur even in single-threaded hosts. */
errno = old_errno;
}
+
+/* Static location to save a fatal backtrace in a thread.
+ FIXME: If two subsidiary threads fail simultaneously, the resulting
+ backtrace may be garbage. */
+enum { BACKTRACE_LIMIT_MAX = 500 };
+static void *thread_backtrace_buffer[BACKTRACE_LIMIT_MAX + 1];
+static int thread_backtrace_npointers;
+
+/* SIG has arrived at the current thread.
+ If we are on the main thread, handle the signal SIG with HANDLER.
+ Otherwise, this is a fatal error in the handling thread. */
+static void
+deliver_thread_signal (int sig, signal_handler_t handler)
+{
+ int old_errno = errno;
+
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
+ if (! pthread_equal (pthread_self (), main_thread))
+ {
+ thread_backtrace_npointers
+ = backtrace (thread_backtrace_buffer, BACKTRACE_LIMIT_MAX);
+ sigaction (sig, &process_fatal_action, 0);
+ pthread_kill (main_thread, sig);
+
+ /* Avoid further damage while the main thread is exiting. */
+ while (1)
+ sigsuspend (&empty_mask);
+ }
+#endif
+
+ handler (sig);
+ errno = old_errno;
+}
\f
#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
static char *my_sys_siglist[NSIG];
# define sys_siglist my_sys_siglist
#endif
+/* Handle bus errors, invalid instruction, etc. */
+static void
+handle_fatal_signal (int sig)
+{
+ terminate_due_to_signal (sig, 10);
+}
+
+static void
+deliver_fatal_signal (int sig)
+{
+ deliver_process_signal (sig, handle_fatal_signal);
+}
+
+static void
+deliver_fatal_thread_signal (int sig)
+{
+ deliver_thread_signal (sig, handle_fatal_signal);
+}
+
+static _Noreturn void
+handle_arith_signal (int sig)
+{
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+ xsignal0 (Qarith_error);
+}
+
+static void
+deliver_arith_signal (int sig)
+{
+ deliver_thread_signal (sig, handle_arith_signal);
+}
+
+/* Treat SIG as a terminating signal, unless it is already ignored and
+ we are in --batch mode. Among other things, this makes nohup work. */
+static void
+maybe_fatal_sig (int sig)
+{
+ bool catch_sig = !noninteractive;
+ if (!catch_sig)
+ {
+ struct sigaction old_action;
+ sigaction (sig, 0, &old_action);
+ catch_sig = old_action.sa_handler != SIG_IGN;
+ }
+ if (catch_sig)
+ sigaction (sig, &process_fatal_action, 0);
+}
+
void
-init_signals (void)
+init_signals (bool dumping)
{
+ struct sigaction thread_fatal_action;
+ struct sigaction action;
+
sigemptyset (&empty_mask);
#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
if (! initialized)
{
-# ifdef SIGABRT
sys_siglist[SIGABRT] = "Aborted";
-# endif
# ifdef SIGAIO
sys_siglist[SIGAIO] = "LAN I/O interrupt";
# endif
# ifdef SIGEMT
sys_siglist[SIGEMT] = "Emulation trap";
# endif
-# ifdef SIGFPE
sys_siglist[SIGFPE] = "Arithmetic exception";
-# endif
# ifdef SIGFREEZE
sys_siglist[SIGFREEZE] = "SIGFREEZE";
# endif
# ifdef SIGHUP
sys_siglist[SIGHUP] = "Hangup";
# endif
-# ifdef SIGILL
sys_siglist[SIGILL] = "Illegal instruction";
-# endif
-# ifdef SIGINT
sys_siglist[SIGINT] = "Interrupt";
-# endif
# ifdef SIGIO
sys_siglist[SIGIO] = "I/O possible";
# endif
# ifdef SIGSAK
sys_siglist[SIGSAK] = "Secure attention";
# endif
-# ifdef SIGSEGV
sys_siglist[SIGSEGV] = "Segmentation violation";
-# endif
# ifdef SIGSOUND
sys_siglist[SIGSOUND] = "Sound completed";
# endif
# ifdef SIGSYS
sys_siglist[SIGSYS] = "Bad argument to system call";
# endif
-# ifdef SIGTERM
sys_siglist[SIGTERM] = "Terminated";
-# endif
# ifdef SIGTHAW
sys_siglist[SIGTHAW] = "SIGTHAW";
# endif
# endif
}
#endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
+
+ /* Don't alter signal handlers if dumping. On some machines,
+ changing signal handlers sets static data that would make signals
+ fail to work right when the dumped Emacs is run. */
+ if (dumping)
+ return;
+
+ sigfillset (&process_fatal_action.sa_mask);
+ process_fatal_action.sa_handler = deliver_fatal_signal;
+ process_fatal_action.sa_flags = emacs_sigaction_flags () | SA_NODEFER;
+
+ sigfillset (&thread_fatal_action.sa_mask);
+ thread_fatal_action.sa_handler = deliver_fatal_thread_signal;
+ thread_fatal_action.sa_flags = process_fatal_action.sa_flags;
+
+ /* SIGINT may need special treatment on MS-Windows. See
+ http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
+ Please update the doc of kill-emacs, kill-emacs-hook, and
+ NEWS if you change this. */
+
+ maybe_fatal_sig (SIGHUP);
+ maybe_fatal_sig (SIGINT);
+ maybe_fatal_sig (SIGTERM);
+
+ /* Emacs checks for write errors, so it can safely ignore SIGPIPE.
+ However, in batch mode leave SIGPIPE alone, as that causes Emacs
+ to behave more like typical batch applications do. */
+ if (! noninteractive)
+ signal (SIGPIPE, SIG_IGN);
+
+ sigaction (SIGQUIT, &process_fatal_action, 0);
+ sigaction (SIGILL, &thread_fatal_action, 0);
+ sigaction (SIGTRAP, &thread_fatal_action, 0);
+
+ /* Typically SIGFPE is thread-specific and is fatal, like SIGILL.
+ But on a non-IEEE host SIGFPE can come from a trap in the Lisp
+ interpreter's floating point operations, so treat SIGFPE as an
+ arith-error if it arises in the main thread. */
+ if (IEEE_FLOATING_POINT)
+ sigaction (SIGFPE, &thread_fatal_action, 0);
+ else
+ {
+ emacs_sigaction_init (&action, deliver_arith_signal);
+ sigaction (SIGFPE, &action, 0);
+ }
+
+#ifdef SIGUSR1
+ add_user_signal (SIGUSR1, "sigusr1");
+#endif
+#ifdef SIGUSR2
+ add_user_signal (SIGUSR2, "sigusr2");
+#endif
+ sigaction (SIGABRT, &thread_fatal_action, 0);
+#ifdef SIGPRE
+ sigaction (SIGPRE, &thread_fatal_action, 0);
+#endif
+#ifdef SIGORE
+ sigaction (SIGORE, &thread_fatal_action, 0);
+#endif
+#ifdef SIGUME
+ sigaction (SIGUME, &thread_fatal_action, 0);
+#endif
+#ifdef SIGDLK
+ sigaction (SIGDLK, &process_fatal_action, 0);
+#endif
+#ifdef SIGCPULIM
+ sigaction (SIGCPULIM, &process_fatal_action, 0);
+#endif
+#ifdef SIGIOT
+ sigaction (SIGIOT, &thread_fatal_action, 0);
+#endif
+#ifdef SIGEMT
+ sigaction (SIGEMT, &thread_fatal_action, 0);
+#endif
+#ifdef SIGBUS
+ sigaction (SIGBUS, &thread_fatal_action, 0);
+#endif
+ sigaction (SIGSEGV, &thread_fatal_action, 0);
+#ifdef SIGSYS
+ sigaction (SIGSYS, &thread_fatal_action, 0);
+#endif
+ sigaction (SIGTERM, &process_fatal_action, 0);
+#ifdef SIGPROF
+ sigaction (SIGPROF, &process_fatal_action, 0);
+#endif
+#ifdef SIGVTALRM
+ sigaction (SIGVTALRM, &process_fatal_action, 0);
+#endif
+#ifdef SIGXCPU
+ sigaction (SIGXCPU, &process_fatal_action, 0);
+#endif
+#ifdef SIGXFSZ
+ sigaction (SIGXFSZ, &process_fatal_action, 0);
+#endif
+
+#ifdef SIGDANGER
+ /* This just means available memory is getting low. */
+ emacs_sigaction_init (&action, deliver_danger_signal);
+ sigaction (SIGDANGER, &action, 0);
+#endif
+
+ /* AIX-specific signals. */
+#ifdef SIGGRANT
+ sigaction (SIGGRANT, &process_fatal_action, 0);
+#endif
+#ifdef SIGMIGRATE
+ sigaction (SIGMIGRATE, &process_fatal_action, 0);
+#endif
+#ifdef SIGMSG
+ sigaction (SIGMSG, &process_fatal_action, 0);
+#endif
+#ifdef SIGRETRACT
+ sigaction (SIGRETRACT, &process_fatal_action, 0);
+#endif
+#ifdef SIGSAK
+ sigaction (SIGSAK, &process_fatal_action, 0);
+#endif
+#ifdef SIGSOUND
+ sigaction (SIGSOUND, &process_fatal_action, 0);
+#endif
+#ifdef SIGTALRM
+ sigaction (SIGTALRM, &thread_fatal_action, 0);
+#endif
}
\f
#ifndef HAVE_RANDOM
void
emacs_backtrace (int backtrace_limit)
{
- enum { BACKTRACE_LIMIT_MAX = 500 };
- void *buffer[BACKTRACE_LIMIT_MAX + 1];
+ void *main_backtrace_buffer[BACKTRACE_LIMIT_MAX + 1];
int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX);
- int npointers = backtrace (buffer, bounded_limit + 1);
+ void *buffer;
+ int npointers;
+
+ if (thread_backtrace_npointers)
+ {
+ buffer = thread_backtrace_buffer;
+ npointers = thread_backtrace_npointers;
+ }
+ else
+ {
+ buffer = main_backtrace_buffer;
+ npointers = backtrace (buffer, bounded_limit + 1);
+ }
+
if (npointers)
- ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
- backtrace_symbols_fd (buffer, bounded_limit, STDERR_FILENO);
- if (bounded_limit < npointers)
- ignore_value (write (STDERR_FILENO, "...\n", 4));
+ {
+ ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
+ backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
+ if (bounded_limit < npointers)
+ ignore_value (write (STDERR_FILENO, "...\n", 4));
+ }
}
\f
#ifndef HAVE_NTGUI
-/* Using emacs_abort lets GDB return from a breakpoint here. */
void
emacs_abort (void)
{
- fatal_error_backtrace (SIGABRT, 10);
+ signal (SIGABRT, SIG_DFL);
+ terminate_due_to_signal (SIGABRT, 10);
}
#endif
{
/* I originally used `QUIT' but that might causes files to
be truncated if you hit C-g in the middle of it. --Stef */
- process_pending_signals ();
+ if (pending_signals)
+ process_pending_signals ();
continue;
}
else
char *npath, *spath;
extern char *getcwd (char *, size_t);
- BLOCK_INPUT; /* getcwd uses malloc */
+ block_input (); /* getcwd uses malloc */
spath = npath = getcwd ((char *) 0, MAXPATHLEN);
if (spath == 0)
{
- UNBLOCK_INPUT;
+ unblock_input ();
return spath;
}
/* On Altos 3068, getcwd can return @hostname/dir, so discard
npath++;
strcpy (pathname, npath);
free (spath); /* getcwd uses malloc */
- UNBLOCK_INPUT;
+ unblock_input ();
return pathname;
}
FILE *fup;
EMACS_TIME up = make_emacs_time (0, 0);
- BLOCK_INPUT;
+ block_input ();
fup = fopen ("/proc/uptime", "r");
if (fup)
}
fclose (fup);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return up;
}
FILE *fdev = NULL;
char name[PATH_MAX];
- BLOCK_INPUT;
+ block_input ();
fdev = fopen ("/proc/tty/drivers", "r");
if (fdev)
}
fclose (fdev);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return build_string (name);
}
FILE *fmem = NULL;
unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
- BLOCK_INPUT;
+ block_input ();
fmem = fopen ("/proc/meminfo", "r");
if (fmem)
}
fclose (fmem);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return retval;
}
/* euid egid */
uid = st.st_uid;
attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
- BLOCK_INPUT;
+ block_input ();
pw = getpwuid (uid);
- UNBLOCK_INPUT;
+ unblock_input ();
if (pw)
attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
gid = st.st_gid;
attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
- BLOCK_INPUT;
+ block_input ();
gr = getgrgid (gid);
- UNBLOCK_INPUT;
+ unblock_input ();
if (gr)
attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
/* euid egid */
uid = st.st_uid;
attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
- BLOCK_INPUT;
+ block_input ();
pw = getpwuid (uid);
- UNBLOCK_INPUT;
+ unblock_input ();
if (pw)
attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
gid = st.st_gid;
attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
- BLOCK_INPUT;
+ block_input ();
gr = getgrgid (gid);
- UNBLOCK_INPUT;
+ unblock_input ();
if (gr)
attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (proc.ki_uid)), attrs);
- BLOCK_INPUT;
+ block_input ();
pw = getpwuid (proc.ki_uid);
- UNBLOCK_INPUT;
+ unblock_input ();
if (pw)
attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (proc.ki_svgid)), attrs);
- BLOCK_INPUT;
+ block_input ();
gr = getgrgid (proc.ki_svgid);
- UNBLOCK_INPUT;
+ unblock_input ();
if (gr)
attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (proc.ki_pgid)), attrs);
attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (proc.ki_sid)), attrs);
- BLOCK_INPUT;
+ block_input ();
ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR);
- UNBLOCK_INPUT;
+ unblock_input ();
if (ttyname)
attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs);
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <signal.h>
+#include <stdbool.h>
-extern void init_signals (void);
+extern void init_signals (bool);
#ifdef HAVE_PTHREAD
#include <pthread.h>
# define NSIG NSIG_MINIMUM
#endif
+#ifndef emacs_raise
+# define emacs_raise(sig) raise (sig)
+#endif
+
/* On bsd, [man says] kill does not accept a negative number to kill a pgrp.
Must do that using the killpg call. */
#ifdef BSD_SYSTEM
char *strsignal (int);
#endif
-void handle_on_main_thread (int, signal_handler_t);
+void deliver_process_signal (int, signal_handler_t);
conversion_buffer = encode_terminal_code (string, n, coding);
if (coding->produced > 0)
{
- BLOCK_INPUT;
+ block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
- UNBLOCK_INPUT;
+ unblock_input ();
}
string += n;
conversion_buffer = encode_terminal_code (string, len, coding);
if (coding->produced > 0)
{
- BLOCK_INPUT;
+ block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Turn appearance modes off. */
if (coding->produced > 0)
{
- BLOCK_INPUT;
+ block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
- UNBLOCK_INPUT;
+ unblock_input ();
}
OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
/* Called to read input events.
TERMINAL indicates which terminal device to read from. Input
- events should be read into BUF, the size of which is given in
- SIZE.
+ events should be read into HOLD_QUIT.
A positive return value indicates that that many input events
were read into BUF.
if ( !FRAME_MSDOS_P (XFRAME (frame)))
goto done;
- BLOCK_INPUT;
+ block_input ();
if (!open_clipboard ())
goto error;
unblock:
xfree (dst);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Notify user if the text is too large to fit into DOS memory.
(This will happen somewhere after 600K bytes (470K in DJGPP v1.x),
if ( !FRAME_MSDOS_P (XFRAME (frame)))
goto done;
- BLOCK_INPUT;
+ block_input ();
if (!open_clipboard ())
goto unblock;
close_clipboard ();
unblock:
- UNBLOCK_INPUT;
+ unblock_input ();
done:
XSETINT (rgb, RGB (XUINT (red), XUINT (green), XUINT (blue)));
- BLOCK_INPUT;
+ block_input ();
/* replace existing entry in w32-color-map or add new entry. */
entry = Fassoc (name, Vw32_color_map);
Fsetcdr (entry, rgb);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return (oldrgb);
}
colormap_t *pc = w32_color_map;
Lisp_Object cmap;
- BLOCK_INPUT;
+ block_input ();
cmap = Qnil;
make_number (pc->colorref)),
cmap);
- UNBLOCK_INPUT;
+ unblock_input ();
return (cmap);
}
{
Lisp_Object tail, ret = Qnil;
- BLOCK_INPUT;
+ block_input ();
for (tail = Vw32_color_map; CONSP (tail); tail = XCDR (tail))
{
QUIT;
}
- UNBLOCK_INPUT;
+ unblock_input ();
return ret;
}
HKEY colors_key;
/* Other registry operations are done with input blocked. */
- BLOCK_INPUT;
+ block_input ();
/* Look for "Control Panel/Colors" under User and Machine registry
settings. */
RegCloseKey (colors_key);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
register Lisp_Object ret = Qnil;
- BLOCK_INPUT;
+ block_input ();
if (colorname[0] == '#')
{
pos += 0x8;
if (i == 2)
{
- UNBLOCK_INPUT;
+ unblock_input ();
XSETINT (ret, colorval);
return ret;
}
{
if (*end != '\0')
break;
- UNBLOCK_INPUT;
+ unblock_input ();
XSETINT (ret, colorval);
return ret;
}
{
if (*end != '\0')
break;
- UNBLOCK_INPUT;
+ unblock_input ();
XSETINT (ret, colorval);
return ret;
}
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return ret;
}
f->output_data.w32->mouse_pixel = FRAME_FOREGROUND_PIXEL (f);
#if 0 /* TODO : Mouse cursor customization. */
- BLOCK_INPUT;
+ block_input ();
/* It's not okay to crash if the user selects a screwy cursor. */
count = x_catch_errors (FRAME_W32_DISPLAY (f));
f->output_data.w32->hand_cursor = hand_cursor;
XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
update_face_from_frame_parameter (f, Qmouse_color, arg);
#endif /* TODO */
if (FRAME_W32_WINDOW (f) != 0)
{
- BLOCK_INPUT;
+ block_input ();
/* Update frame's cursor_gc. */
f->output_data.w32->cursor_gc->foreground = fore_pixel;
f->output_data.w32->cursor_gc->background = pixel;
- UNBLOCK_INPUT;
+ unblock_input ();
if (FRAME_VISIBLE_P (f))
{
if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
return;
- BLOCK_INPUT;
+ block_input ();
result = x_bitmap_icon (f, arg);
if (result)
{
- UNBLOCK_INPUT;
+ unblock_input ();
error ("No icon window available");
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
if (f->output_data.w32->icon_bitmap != 0)
return;
- BLOCK_INPUT;
+ block_input ();
result = x_text_icon (f,
SSDATA ((!NILP (f->icon_name)
if (result)
{
- UNBLOCK_INPUT;
+ unblock_input ();
error ("No icon window available");
}
}
XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
#endif
}
int width = FRAME_PIXEL_WIDTH (f);
int y = nlines * FRAME_LINE_HEIGHT (f);
- BLOCK_INPUT;
+ block_input ();
{
HDC hdc = get_frame_dc (f);
w32_clear_area (f, hdc, 0, y, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (WINDOWP (f->tool_bar_window))
clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
if (STRING_MULTIBYTE (name))
name = ENCODE_SYSTEM (name);
- BLOCK_INPUT;
+ block_input ();
SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
if (STRING_MULTIBYTE (name))
name = ENCODE_SYSTEM (name);
- BLOCK_INPUT;
+ block_input ();
SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
static void
w32_window (struct frame *f, long window_prompting, int minibuffer_only)
{
- BLOCK_INPUT;
+ block_input ();
/* Use the resource name as the top-level window name
for looking up resources. Make a non-Lisp copy
x_set_name (f, name, explicit);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
initialize_frame_menubar (f);
else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
error ("Both left and top icon corners of icon must be specified");
- BLOCK_INPUT;
+ block_input ();
if (! EQ (icon_x, Qunbound))
x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
: f->name)));
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
XGCValues gc_values;
- BLOCK_INPUT;
+ block_input ();
/* Create the GC's of this frame.
Note that many default values are used. */
f->output_data.w32->white_relief.gc = 0;
f->output_data.w32->black_relief.gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
bar so that its size can be taken into account. */
- BLOCK_INPUT;
+ block_input ();
x_wm_set_size_hint (f, window_prompting, 0);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Make the window appear on the frame and enable display, unless
the caller says not to. However, with explicit parent, Emacs
if (dpyinfo->reference_count > 0)
error ("Display still has frames on it");
- BLOCK_INPUT;
+ block_input ();
x_destroy_all_bitmaps (dpyinfo);
x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
CHECK_STRING (prop);
CHECK_STRING (value);
- BLOCK_INPUT;
+ block_input ();
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
prop_atom, XA_STRING, 8, PropModeReplace,
/* Make sure the property is set when we return. */
XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
Atom prop_atom;
CHECK_STRING (prop);
- BLOCK_INPUT;
+ block_input ();
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
/* Make sure the property is removed when we return. */
XFlush (FRAME_W32_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
return prop;
}
unsigned long actual_size, bytes_remaining;
CHECK_STRING (prop);
- BLOCK_INPUT;
+ block_input ();
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
prop_atom, 0, 0, False, XA_STRING,
XFree (tmp_data);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return prop_value;
f->left_fringe_width = 0;
f->right_fringe_width = 0;
- BLOCK_INPUT;
+ block_input ();
my_create_tip_window (f);
- UNBLOCK_INPUT;
+ unblock_input ();
x_make_gc (f);
max_x = x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f));
max_y = x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f));
- BLOCK_INPUT;
+ block_input ();
GetCursorPos (&pt);
*root_x = pt.x;
*root_y = pt.y;
- UNBLOCK_INPUT;
+ unblock_input ();
/* If multiple monitor support is available, constrain the tip onto
the current monitor. This improves the above by allowing negative
call1 (Qcancel_timer, timer);
}
- BLOCK_INPUT;
+ block_input ();
compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
goto start_timer;
}
}
/* Block input until the tip has been fully drawn, to avoid crashes
when drawing tips in menus. */
- BLOCK_INPUT;
+ block_input ();
/* Create a frame for the tooltip, and record it in the global
variable tip_frame. */
w->must_be_updated_p = 1;
update_single_window (w, 1);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Restore original current buffer. */
set_buffer_internal_1 (old_buffer);
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
- BLOCK_INPUT;
+ block_input ();
memset (&new_file_details, 0, sizeof (new_file_details));
/* Apparently NT4 crashes if you give it an unexpected size.
file_opened = GetOpenFileName (file_details);
- UNBLOCK_INPUT;
+ unblock_input ();
if (file_opened)
{
Lisp_Object *y,
Time *time)
{
- BLOCK_INPUT;
+ block_input ();
insist = insist;
XSETINT (*y, movement_pos.Y);
*time = movement_time;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Remember mouse motion and notify emacs. */
int nev, add;
int isdead;
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- BLOCK_INPUT;
+ block_input ();
for (;;)
{
if (!w32_use_full_screen_buffer)
maybe_generate_resize_event ();
- UNBLOCK_INPUT;
+ unblock_input ();
return nev;
}
list_of_panes (Fcons (contents, Qnil));
/* Display them in a dialog box. */
- BLOCK_INPUT;
+ block_input ();
selection = w32_dialog_show (f, 0, title, header, &error_name);
- UNBLOCK_INPUT;
+ unblock_input ();
discard_menu_items ();
FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
/* Create or update the menu bar widget. */
- BLOCK_INPUT;
+ block_input ();
if (menubar_widget)
{
x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Called from Fx_create_frame to create the initial menubar of a frame
void
free_frame_menubar (FRAME_PTR f)
{
- BLOCK_INPUT;
+ block_input ();
{
HMENU old = GetMenu (FRAME_W32_WINDOW (f));
DestroyMenu (old);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
trykey:
- BLOCK_INPUT;
+ block_input ();
/* Check both the current user and the local machine to see if we have
any resources */
RegCloseKey (hrootkey);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (!ok)
{
extern int waiting_for_input; /* from keyboard.c */
int owfi;
- BLOCK_INPUT;
+ block_input ();
/* Fsignal calls emacs_abort () if it sees that waiting_for_input is
set. */
waiting_for_input = owfi;
- UNBLOCK_INPUT;
+ unblock_input ();
}
static Lisp_Object
current_num_nls = 0;
current_requires_encoding = 0;
- BLOCK_INPUT;
+ block_input ();
/* Check for non-ASCII characters. While we are at it, count the
number of LFs, so we know how many CRs we will have to add later
current_coding_system = Qnil;
done:
- UNBLOCK_INPUT;
+ unblock_input ();
return (ok ? string : Qnil);
}
setup_config ();
actual_clipboard_type = cfg_clipboard_type;
- BLOCK_INPUT;
+ block_input ();
if (!OpenClipboard (clipboard_owner))
goto done;
CloseClipboard ();
done:
- UNBLOCK_INPUT;
+ unblock_input ();
return (ret);
}
updated_window = w;
set_output_cursor (&w->cursor);
- BLOCK_INPUT;
+ block_input ();
if (f == hlinfo->mouse_face_mouse_frame)
{
#endif /* 0 */
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Draw a vertical window border from (x,y0) to (x,y1) */
if (!w->pseudo_window_p)
{
- BLOCK_INPUT;
+ block_input ();
if (cursor_on_p)
display_and_set_cursor (w, 1, output_cursor.hpos,
if (draw_window_fringes (w, 1))
x_draw_vertical_border (w);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If a row with mouse-face was overwritten, arrange for
if (hlinfo->mouse_face_deferred_gc
|| f == hlinfo->mouse_face_mouse_frame)
{
- BLOCK_INPUT;
+ block_input ();
if (hlinfo->mouse_face_mouse_frame)
note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
hlinfo->mouse_face_mouse_x,
hlinfo->mouse_face_mouse_y);
hlinfo->mouse_face_deferred_gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- BLOCK_INPUT;
+ block_input ();
{
HDC hdc = get_frame_dc (f);
w32_clear_area (f, hdc, 0, y, width, height);
y, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
/* We don't set the output cursor here because there will always
follow an explicit cursor_to. */
- BLOCK_INPUT;
+ block_input ();
w32_clear_window (f);
colors or something like that, then they should be notified. */
x_scroll_bar_clear (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
static void
w32_ring_bell (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
if (FRAME_W32_P (f) && visible_bell)
{
else
w32_sys_ring_bell (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
expect_dirty = CreateRectRgn (x, y, x + width, to_y);
}
- BLOCK_INPUT;
+ block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
updated_window = w;
DeleteObject (combined);
}
- UNBLOCK_INPUT;
+ unblock_input ();
DeleteObject (expect_dirty);
}
/* Make static so we can always return it */
static char value[100];
- BLOCK_INPUT;
+ block_input ();
GetKeyNameText (keysym, value, 100);
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
{
FRAME_PTR f1;
- BLOCK_INPUT;
+ block_input ();
if (! NILP (last_mouse_scroll_bar) && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
if (draggingp)
{
int near_bottom_p;
- BLOCK_INPUT;
+ block_input ();
si.cbSize = sizeof (si);
si.fMask = SIF_POS | SIF_PAGE;
GetScrollInfo (w, SB_CTL, &si);
near_bottom_p = si.nPos + si.nPage >= range;
- UNBLOCK_INPUT;
+ unblock_input ();
if (!near_bottom_p)
return;
}
sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
- BLOCK_INPUT;
+ block_input ();
si.cbSize = sizeof (si);
si.fMask = SIF_PAGE | SIF_POS;
SetScrollInfo (w, SB_CTL, &si, TRUE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
= XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
Lisp_Object barobj;
- BLOCK_INPUT;
+ block_input ();
XSETWINDOW (bar->window, w);
XSETINT (bar->top, top);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
- UNBLOCK_INPUT;
+ unblock_input ();
return bar;
}
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- BLOCK_INPUT;
+ block_input ();
/* Destroy the window. */
my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
/* Dissociate this scroll bar from its window. */
wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Set the handle of the vertical scroll bar for WINDOW to indicate
if (NILP (w->vertical_scroll_bar))
{
HDC hdc;
- BLOCK_INPUT;
+ block_input ();
if (width > 0 && height > 0)
{
hdc = get_frame_dc (f);
w32_clear_area (f, hdc, left, top, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
}
HDC hdc;
SCROLLINFO si;
- BLOCK_INPUT;
+ block_input ();
if (width && height)
{
hdc = get_frame_dc (f);
XSETINT (bar->width, sb_width);
XSETINT (bar->height, height);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
SCROLLINFO si;
- BLOCK_INPUT;
+ block_input ();
*fp = f;
*bar_window = bar->window;
*time = last_mouse_movement_time;
- UNBLOCK_INPUT;
+ unblock_input ();
}
struct w32_display_info *dpyinfo = &one_w32_display_info;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- pending_signals = 1;
- return -1;
- }
-
interrupt_input_pending = 0;
- BLOCK_INPUT;
+ block_input ();
/* So people can tell when we have read the available input. */
input_signal_count++;
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return count;
}
}
x_calc_absolute_position (f);
- BLOCK_INPUT;
+ block_input ();
x_wm_set_size_hint (f, (long) 0, 0);
modified_left = f->left_pos;
modified_left, modified_top,
0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
int pixelwidth, pixelheight;
- BLOCK_INPUT;
+ block_input ();
check_frame_size (f, &rows, &cols);
f->scroll_bar_actual_width
cancel_mouse_face (f);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
/* Mouse warping. */
RECT rect;
POINT pt;
- BLOCK_INPUT;
+ block_input ();
GetClientRect (FRAME_W32_WINDOW (f), &rect);
pt.x = rect.left + pix_x;
SetCursorPos (pt.x, pt.y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
struct w32_display_info *dpyinfo = &one_w32_display_info;
/* Give input focus to frame. */
- BLOCK_INPUT;
+ block_input ();
#if 0
/* Try not to change its Z-order if possible. */
if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
else
#endif
my_set_foreground_window (FRAME_W32_WINDOW (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
void
x_raise_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
/* Strictly speaking, raise-frame should only change the frame's Z
order, leaving input focus unchanged. This is reasonable behavior
my_bring_window_to_top (FRAME_W32_WINDOW (f));
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Lower frame F. */
void
x_lower_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
my_set_window_pos (FRAME_W32_WINDOW (f),
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
{
Lisp_Object type;
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
int count;
/* This must come after we set COUNT. */
- UNBLOCK_INPUT;
+ unblock_input ();
XSETFRAME (frame, f);
if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
- BLOCK_INPUT;
+ block_input ();
my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
f->async_visible = 0;
f->async_iconified = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Change window state from mapped to iconified. */
if (f->async_iconified)
return;
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
/* Simulate the user minimizing the frame. */
SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- BLOCK_INPUT;
+ block_input ();
/* We must free faces before destroying windows because some
font-driver (e.g. xft) access a window while finishing a
hlinfo->mouse_face_mouse_frame = 0;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!terminal->name)
return;
- BLOCK_INPUT;
+ block_input ();
x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
}
struct w32_display_info *
struct terminal *terminal;
HDC hdc;
- BLOCK_INPUT;
+ block_input ();
if (!w32_initialized)
{
init_sigio (connection);
#endif /* ! defined (SIGIO) */
- UNBLOCK_INPUT;
+ unblock_input ();
return dpyinfo;
}
if (! s) emacs_abort ();
if (! s->output_data.x) emacs_abort ();
- BLOCK_INPUT;
+ block_input ();
x_free_gcs (s);
if (s->output_data.x->white_relief.gc)
XFreeGC (XtDisplay (widget), s->output_data.x->white_relief.gc);
if (s->output_data.x->black_relief.gc)
XFreeGC (XtDisplay (widget), s->output_data.x->black_relief.gc);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
}
}
- BLOCK_INPUT;
+ block_input ();
if (!FRAME_INITIAL_P (f))
{
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
}
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
run_window_configuration_change_hook (f);
(horflag ? r->total_cols : r->total_lines)))
return Qnil;
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, horflag);
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
run_window_configuration_change_hook (f);
wset_new_total (n, total_size);
wset_new_normal (n, normal_size);
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (p, horflag);
adjust_glyphs (f);
/* Set buffer of NEW to buffer of reference window. Don't run
any hooks. */
set_window_buffer (new, r->buffer, 0, 1);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Maybe we should run the scroll functions in Elisp (which already
runs the configuration change hook). */
{
/* Block input. */
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (p, horflag);
/* If this window is referred to by the dpyinfo's mouse
else
fset_selected_window (f, new_selected_window);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Now look whether `get-mru-window' gets us something. */
mru_window = call1 (Qget_mru_window, frame);
fset_selected_window (f, new_selected_window);
}
else
- UNBLOCK_INPUT;
+ unblock_input ();
/* Must be run by the caller:
run_window_configuration_change_hook (f); */
root, make_number (- delta));
if (INTEGERP (value) && window_resize_check (r, 0))
{
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, 0);
/* Grow the mini-window. */
w->last_overlay_modified = 0;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
root, make_number (size - 1));
if (INTEGERP (value) && window_resize_check (r, 0))
{
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, 0);
/* Shrink the mini-window. */
w->last_overlay_modified = 0;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If the above failed for whatever strange reason we must make a
one window frame here. The same routine will be needed when
&& XINT (w->new_total) > 0
&& height == XINT (r->new_total) + XINT (w->new_total))
{
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, 0);
wset_total_lines (w, w->new_total);
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
run_window_configuration_change_hook (f);
return Qt;
/* The mouse highlighting code could get screwed up
if it runs during this. */
- BLOCK_INPUT;
+ block_input ();
if (data->frame_lines != previous_frame_lines
|| data->frame_cols != previous_frame_cols)
}
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Scan dead buffer windows. */
for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
#include <limits.h>
#include "lisp.h"
+#include "atimer.h"
#include "keyboard.h"
#include "frame.h"
#include "window.h"
This will also set the cursor position of W. */
if (updated_window == NULL)
{
- BLOCK_INPUT;
+ block_input ();
display_and_set_cursor (w, 1, hpos, vpos, x, y);
if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
/* Redisplay that happens asynchronously due to an expose event
may access f->tool_bar_items. Make sure we update both
variables within BLOCK_INPUT so no such event interrupts. */
- BLOCK_INPUT;
+ block_input ();
fset_tool_bar_items (f, new_tool_bar);
f->n_tool_bar_items = new_n_tool_bar;
w->update_mode_line = 1;
- UNBLOCK_INPUT;
+ unblock_input ();
}
UNGCPRO;
|| w->pseudo_window_p)))
{
update_begin (f);
- BLOCK_INPUT;
+ block_input ();
if (draw_window_fringes (w, 1))
x_draw_vertical_border (w);
- UNBLOCK_INPUT;
+ unblock_input ();
update_end (f);
}
#endif /* HAVE_WINDOW_SYSTEM */
if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
chpos = updated_row->used[TEXT_AREA] - 1;
- BLOCK_INPUT;
+ block_input ();
/* Write glyphs. */
&& chpos < hpos + len)
updated_window->phys_cursor_on_p = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
/* Advance the output cursor. */
output_cursor.hpos += len;
ptrdiff_t hpos;
eassert (updated_window && updated_row);
- BLOCK_INPUT;
+ block_input ();
w = updated_window;
f = XFRAME (WINDOW_FRAME (w));
/* Advance the output cursor. */
output_cursor.hpos += len;
output_cursor.x += shift_by_width;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Prevent inadvertently clearing to end of the X window. */
if (to_x > from_x && to_y > from_y)
{
- BLOCK_INPUT;
+ block_input ();
FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
to_x - from_x, to_y - from_y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
{
int i, x;
- BLOCK_INPUT;
+ block_input ();
x = 0;
for (i = 0; i < row->used[area];)
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
|| (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
/* Set new_cursor_type to the cursor we want to be displayed. */
new_cursor_type = get_window_cursor_type (w, glyph,
if (row->reversed_p && hpos >= row->used[TEXT_AREA])
hpos = row->used[TEXT_AREA] - 1;
- BLOCK_INPUT;
+ block_input ();
display_and_set_cursor (w, on, hpos, vpos,
w->phys_cursor.x, w->phys_cursor.y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
if (row->reversed_p && hpos >= row->used[TEXT_AREA])
hpos = row->used[TEXT_AREA] - 1;
- BLOCK_INPUT;
+ block_input ();
display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
w->phys_cursor.x, w->phys_cursor.y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_WINDOW_SYSTEM */
}
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
Lisp_Object window;
- BLOCK_INPUT;
+ block_input ();
XSETWINDOW (window, w);
if (EQ (window, hlinfo->mouse_face_window))
clear_mouse_face (hlinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
}
x_create_gc (struct frame *f, long unsigned int mask, XGCValues *xgcv)
{
GC gc;
- BLOCK_INPUT;
+ block_input ();
gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
- UNBLOCK_INPUT;
+ unblock_input ();
IF_DEBUG (++ngcs);
return gc;
}
static inline void
x_free_gc (struct frame *f, GC gc)
{
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
IF_DEBUG (eassert (--ngcs >= 0));
XFreeGC (FRAME_X_DISPLAY (f), gc);
}
x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
{
GC gc;
- BLOCK_INPUT;
+ block_input ();
gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
- UNBLOCK_INPUT;
+ unblock_input ();
IF_DEBUG (++ngcs);
return gc;
}
CHECK_TYPE (!NILP (Fbitmap_spec_p (name)), Qbitmap_spec_p, name);
- BLOCK_INPUT;
+ block_input ();
if (CONSP (name))
{
/* Decode a bitmap spec into a bitmap. */
/* It must be a string -- a file name. */
bitmap_id = x_create_bitmap_from_file (f, name);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (bitmap_id < 0)
{
#ifdef HAVE_X_WINDOWS
if (pixel != -1)
{
- BLOCK_INPUT;
+ block_input ();
x_free_colors (f, &pixel, 1);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif
}
if (face->colors_copied_bitwise_p)
return;
- BLOCK_INPUT;
+ block_input ();
if (!face->foreground_defaulted_p)
{
IF_DEBUG (--ncolors_allocated);
}
- UNBLOCK_INPUT;
+ unblock_input ();
#endif /* HAVE_X_WINDOWS */
}
CHECK_STRING (resource);
CHECK_STRING (class);
CHECK_LIVE_FRAME (frame);
- BLOCK_INPUT;
+ block_input ();
value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
resource, class, Qnil, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
free_face_fontset (f, face);
if (face->gc)
{
- BLOCK_INPUT;
+ block_input ();
if (face->font)
font_done_for_face (f, face);
x_free_gc (f, face->gc);
face->gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
free_face_colors (f, face);
xgcv.graphics_exposures = False;
#endif
- BLOCK_INPUT;
+ block_input ();
#ifdef HAVE_X_WINDOWS
if (face->stipple)
{
face->gc = x_create_gc (f, mask, &xgcv);
if (face->font)
font_prepare_for_face (f, face);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_WINDOW_SYSTEM */
}
struct face *face = c->faces_by_id[i];
if (face && face->gc)
{
- BLOCK_INPUT;
+ block_input ();
if (face->font)
font_done_for_face (c->f, face);
x_free_gc (c->f, face->gc);
face->gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
#endif /* HAVE_WINDOW_SYSTEM */
/* We must block input here because we can't process X events
safely while only some faces are freed, or when the frame's
current matrix still references freed faces. */
- BLOCK_INPUT;
+ block_input ();
for (i = 0; i < c->used; ++i)
{
++windows_or_buffers_changed;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
/* Block input here so that we won't be surprised by an X expose
event, for instance, without having the faces set up. */
- BLOCK_INPUT;
+ block_input ();
specbind (Qscalable_fonts_allowed, Qt);
if (realize_default_face (f))
}
unbind_to (count, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
return success_p;
}
int red, green, blue;
int num;
- BLOCK_INPUT;
+ block_input ();
while (fgets (buf, sizeof (buf), fp) != NULL) {
if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
}
fclose (fp);
- UNBLOCK_INPUT;
+ unblock_input ();
}
return cmap;
unsigned char *tmp_data = NULL;
Atom target_type = XA_CARDINAL;
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (dpy);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
if (had_errors) return;
Display *dpy = FRAME_X_DISPLAY (f);
Colormap cmap = FRAME_X_COLORMAP (f);
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_GTK
success_p = xg_check_special_colors (f, color_name, color);
#endif
success_p = XParseColor (dpy, cmap, color_name, color);
if (success_p && alloc_p)
success_p = x_alloc_nearest_color (f, cmap, color);
- UNBLOCK_INPUT;
+ unblock_input ();
return success_p;
}
GdkPixbuf *pixbuf;
GError *err = NULL;
char *filename = SSDATA (found);
- BLOCK_INPUT;
+ block_input ();
pixbuf = gdk_pixbuf_new_from_file (filename, &err);
else
g_error_free (err);
- UNBLOCK_INPUT;
+ unblock_input ();
}
return result;
{
Display *dpy = FRAME_X_DISPLAY (f);
- BLOCK_INPUT;
+ block_input ();
XSetForeground (dpy, x->normal_gc, fg);
XSetBackground (dpy, x->reverse_gc, fg);
XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
}
- UNBLOCK_INPUT;
+ unblock_input ();
update_face_from_frame_parameter (f, Qforeground_color, arg);
{
Display *dpy = FRAME_X_DISPLAY (f);
- BLOCK_INPUT;
+ block_input ();
XSetBackground (dpy, x->normal_gc, bg);
XSetForeground (dpy, x->reverse_gc, bg);
XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
}
#endif /* USE_TOOLKIT_SCROLL_BARS */
- UNBLOCK_INPUT;
+ unblock_input ();
update_face_from_frame_parameter (f, Qbackground_color, arg);
if (FRAME_VISIBLE_P (f))
unload_color (f, x->mouse_pixel);
x->mouse_pixel = pixel;
- BLOCK_INPUT;
+ block_input ();
/* It's not okay to crash if the user selects a screwy cursor. */
x_catch_errors (dpy);
x->horizontal_drag_cursor = horizontal_drag_cursor;
XFlush (dpy);
- UNBLOCK_INPUT;
+ unblock_input ();
update_face_from_frame_parameter (f, Qmouse_color, arg);
}
if (FRAME_X_WINDOW (f) != 0)
{
- BLOCK_INPUT;
+ block_input ();
XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
- UNBLOCK_INPUT;
+ unblock_input ();
if (FRAME_VISIBLE_P (f))
{
if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
{
- BLOCK_INPUT;
+ block_input ();
XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
- UNBLOCK_INPUT;
+ unblock_input ();
if (FRAME_VISIBLE_P (f))
redraw_frame (f);
else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
return;
- BLOCK_INPUT;
+ block_input ();
if (NILP (arg))
result = x_text_icon (f,
SSDATA ((!NILP (f->icon_name)
if (result)
{
- UNBLOCK_INPUT;
+ unblock_input ();
error ("No icon window available");
}
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
if (f->output_data.x->icon_bitmap != 0)
return;
- BLOCK_INPUT;
+ block_input ();
result = x_text_icon (f,
SSDATA ((!NILP (f->icon_name)
if (result)
{
- UNBLOCK_INPUT;
+ unblock_input ();
error ("No icon window available");
}
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
{
y = FRAME_TOP_MARGIN_HEIGHT (f);
- BLOCK_INPUT;
+ block_input ();
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
0, y, width, height, False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (nlines > 1 && nlines > olines)
y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
height = nlines * FRAME_LINE_HEIGHT (f) - y;
- BLOCK_INPUT;
+ block_input ();
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
0, y, width, height, False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (nlines == 0 && WINDOWP (f->menu_bar_window))
/* height can be zero here. */
if (height > 0 && width > 0)
{
- BLOCK_INPUT;
+ block_input ();
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
0, y, width, height, False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (WINDOWP (f->tool_bar_window))
{
if (FRAME_X_WINDOW (f))
{
- BLOCK_INPUT;
+ block_input ();
{
XTextProperty text, icon;
ptrdiff_t bytes;
if (do_free_text_value)
xfree (text.value);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
int need_focus = 1;
int need_save = 1;
- BLOCK_INPUT;
+ block_input ();
{
Atom type;
unsigned char *catoms;
XA_ATOM, 32, PropModeAppend,
(unsigned char *) props, count);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif
Arg al [25];
int ac;
- BLOCK_INPUT;
+ block_input ();
/* Use the resource name as the top-level widget name
for looking up resources. Make a non-Lisp copy
f->output_data.x->current_cursor
= f->output_data.x->text_cursor);
- UNBLOCK_INPUT;
+ unblock_input ();
/* This is a no-op, except under Motif. Make sure main areas are
set to something reasonable, in case we get an error later. */
FRAME_XIC (f) = NULL;
if (use_xim)
{
- BLOCK_INPUT;
+ block_input ();
create_frame_xic (f);
if (FRAME_XIC (f))
{
attribute_mask, &attributes);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif
}
attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
| CWColormap);
- BLOCK_INPUT;
+ block_input ();
FRAME_X_WINDOW (f)
= XCreateWindow (FRAME_X_DISPLAY (f),
f->output_data.x->parent_desc,
f->output_data.x->current_cursor
= f->output_data.x->text_cursor);
- UNBLOCK_INPUT;
+ unblock_input ();
if (FRAME_X_WINDOW (f) == 0)
error ("Unable to create window");
else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
error ("Both left and top icon corners of icon must be specified");
- BLOCK_INPUT;
+ block_input ();
if (! EQ (icon_x, Qunbound))
x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
? f->icon_name
: f->name)));
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Make the GCs needed for this window, setting the
{
XGCValues gc_values;
- BLOCK_INPUT;
+ block_input ();
/* Create the GCs of this frame.
Note that many default values are used. */
FRAME_BACKGROUND_PIXEL (f),
DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
Display *dpy = FRAME_X_DISPLAY (f);
- BLOCK_INPUT;
+ block_input ();
if (f->output_data.x->normal_gc)
{
f->output_data.x->border_tile = 0;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (NILP (frame))
frame = selected_frame;
f = XFRAME (frame);
- BLOCK_INPUT;
+ block_input ();
if (FRAME_X_P (f))
x_wm_set_size_hint (f, 0, 0);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
bar so that its size can be taken into account. */
- BLOCK_INPUT;
+ block_input ();
x_wm_set_size_hint (f, window_prompting, 0);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Make the window appear on the frame and enable display, unless
the caller says not to. However, with explicit parent, Emacs
}
}
- BLOCK_INPUT;
+ block_input ();
/* Set machine name and pid for the purpose of window managers. */
set_machine_and_pid_properties (f);
(unsigned char *) &dpyinfo->client_leader_window, 1);
}
- UNBLOCK_INPUT;
+ unblock_input ();
/* Initialize `default-minibuffer-frame' in case this is the first
frame on this terminal. */
struct frame *f = check_x_frame (frame);
Display *dpy = FRAME_X_DISPLAY (f);
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (dpy);
if (FRAME_X_EMBEDDED_P (f))
}
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
void
x_sync (FRAME_PTR f)
{
- BLOCK_INPUT;
+ block_input ();
XSync (FRAME_X_DISPLAY (f), False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
nelements = SBYTES (value);
}
- BLOCK_INPUT;
+ block_input ();
prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
if (! NILP (type))
{
/* Make sure the property is set when we return. */
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
Atom prop_atom;
CHECK_STRING (prop);
- BLOCK_INPUT;
+ block_input ();
prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), prop_atom);
/* Make sure the property is removed when we return. */
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
return prop;
}
target_window = FRAME_X_DISPLAY_INFO (f)->root_window;
}
- BLOCK_INPUT;
+ block_input ();
if (STRINGP (type))
{
if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
if (tmp_data) XFree (tmp_data);
}
- UNBLOCK_INPUT;
+ unblock_input ();
UNGCPRO;
return prop_value;
}
{
Lisp_Object rest, frame;
- BLOCK_INPUT;
+ block_input ();
FOR_EACH_FRAME (rest, frame)
{
}
hourglass_shown_p = 1;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
{
Lisp_Object rest, frame;
- BLOCK_INPUT;
+ block_input ();
FOR_EACH_FRAME (rest, frame)
{
struct frame *f = XFRAME (frame);
}
hourglass_shown_p = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
unsigned long mask;
Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
- BLOCK_INPUT;
+ block_input ();
mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
if (DoesSaveUnders (dpyinfo->screen))
mask |= CWSaveUnder;
FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type,
XA_ATOM, 32, PropModeReplace,
(unsigned char *)&type, 1);
- UNBLOCK_INPUT;
+ unblock_input ();
}
x_make_gc (f);
show it. */
if (!INTEGERP (left) || !INTEGERP (top))
{
- BLOCK_INPUT;
+ block_input ();
XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
&root, &child, root_x, root_y, &win_x, &win_y, &pmask);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (INTEGERP (top))
/* Hide a previous tip, if any. */
Fx_hide_tip ();
- BLOCK_INPUT;
+ block_input ();
if ((ok = xg_prepare_tooltip (f, string, &width, &height)) != 0)
{
compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
/* This is used in Fx_hide_tip. */
XSETFRAME (tip_frame, f);
}
- UNBLOCK_INPUT;
+ unblock_input ();
if (ok) goto start_timer;
}
#endif /* USE_GTK */
call1 (Qcancel_timer, timer);
}
- BLOCK_INPUT;
+ block_input ();
compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
root_x, root_y);
- UNBLOCK_INPUT;
+ unblock_input ();
goto start_timer;
}
}
show it. */
compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
- BLOCK_INPUT;
+ block_input ();
XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
root_x, root_y, width, height);
XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
- UNBLOCK_INPUT;
+ unblock_input ();
/* Draw into the window. */
w->must_be_updated_p = 1;
if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
&& w != NULL)
{
- BLOCK_INPUT;
+ block_input ();
xlwmenu_redisplay (w);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
#endif /* USE_LUCID */
Widget dialog = (Widget) p->pointer;
/* Clean up. */
- BLOCK_INPUT;
+ block_input ();
XtUnmanageChild (dialog);
XtDestroyWidget (dialog);
x_menu_set_in_use (0);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
- BLOCK_INPUT;
+ block_input ();
/* Create the dialog with PROMPT as title, using DIR as initial
directory and using "*" as pattern. */
else
file = Qnil;
- UNBLOCK_INPUT;
+ unblock_input ();
UNGCPRO;
/* Make "Cancel" equivalent to C-g. */
specbind (Qinhibit_redisplay, Qt);
record_unwind_protect (clean_up_dialog, Qnil);
- BLOCK_INPUT;
+ block_input ();
if (STRINGP (default_filename))
cdef_file = SSDATA (default_filename);
xfree (fn);
}
- UNBLOCK_INPUT;
+ unblock_input ();
UNGCPRO;
/* Make "Cancel" equivalent to C-g. */
specbind (Qinhibit_redisplay, Qt);
record_unwind_protect (clean_up_dialog, Qnil);
- BLOCK_INPUT;
+ block_input ();
GCPRO2 (font_param, font);
font = xg_get_font (f, default_name);
xfree (default_name);
- UNBLOCK_INPUT;
+ unblock_input ();
if (NILP (font))
Fsignal (Qquit, Qnil);
Lisp_Object have_keys;
int major, minor, op, event, error_code;
- BLOCK_INPUT;
+ block_input ();
/* Check library version in case we're dynamically linked. */
major = XkbMajorVersion;
minor = XkbMinorVersion;
if (!XkbLibraryVersion (&major, &minor))
{
- UNBLOCK_INPUT;
+ unblock_input ();
return Qlambda;
}
minor = XkbMinorVersion;
if (!XkbQueryExtension (dpy, &op, &event, &error_code, &major, &minor))
{
- UNBLOCK_INPUT;
+ unblock_input ();
return Qlambda;
}
&& XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
have_keys = Qt;
}
- UNBLOCK_INPUT;
+ unblock_input ();
return have_keys;
#else /* not HAVE_XKBGETKEYBOARD */
return Qlambda;
}
}
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (display);
for (limit = 512; ; limit *= 2)
}
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
return list;
if (xfont_encode_coding_xlfd (name) < 0)
return Qnil;
- BLOCK_INPUT;
+ block_input ();
entity = Qnil;
xfont = XLoadQueryFont (display, name);
if (xfont)
}
XFreeFont (display, xfont);
}
- UNBLOCK_INPUT;
+ unblock_input ();
FONT_ADD_LOG ("xfont-match", spec, entity);
return entity;
char *last_family IF_LINT (= 0);
int last_len;
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (dpyinfo->display);
names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
0x8000, &num_fonts);
XFreeFontNames (names);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return list;
}
return Qnil;
}
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (display);
xfont = XLoadQueryFont (display, name);
if (x_had_errors_p (display))
XFree (p0);
}
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
if (! xfont)
{
}
}
- BLOCK_INPUT;
+ block_input ();
font->underline_thickness
= (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
? (long) value : 0);
font->default_ascent
= (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
? (long) value : 0);
- UNBLOCK_INPUT;
+ unblock_input ();
if (NILP (fullname))
fullname = AREF (font_object, FONT_NAME_INDEX);
static void
xfont_close (FRAME_PTR f, struct font *font)
{
- BLOCK_INPUT;
+ block_input ();
XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static int
xfont_prepare_face (FRAME_PTR f, struct face *face)
{
- BLOCK_INPUT;
+ block_input ();
XSetFont (FRAME_X_DISPLAY (f), face->gc,
((struct xfont_info *) face->font)->xfont->fid);
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
if (s->gc != s->face->gc)
{
- BLOCK_INPUT;
+ block_input ();
XSetFont (s->display, gc, xfont->fid);
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
char *str = SAFE_ALLOCA (len);
for (i = 0; i < len ; i++)
str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
- BLOCK_INPUT;
+ block_input ();
if (with_background)
{
if (s->padding_p)
XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
gc, x, y, str, len);
}
- UNBLOCK_INPUT;
+ unblock_input ();
SAFE_FREE ();
return s->nchars;
}
- BLOCK_INPUT;
+ block_input ();
if (with_background)
{
if (s->padding_p)
XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
gc, x, y, s->char2b + from, len);
}
- UNBLOCK_INPUT;
+ unblock_input ();
return len;
}
XGCValues xgcv;
bool fg_done = 0, bg_done = 0;
- BLOCK_INPUT;
+ block_input ();
XGetGCValues (FRAME_X_DISPLAY (f), gc,
GCForeground | GCBackground, &xgcv);
if (xftface_info)
bg->color.blue = colors[1].blue;
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
FcPatternAddInteger (pat, FC_INDEX, XINT (idx));
- BLOCK_INPUT;
+ block_input ();
/* Make sure that the Xrender extension is added before the Xft one.
Otherwise, the close-display hook set by Xft is called after the
one for Xrender, and the former tries to re-add the latter. This
xftfont = XftFontOpenPattern (display, match);
if (!xftfont)
{
- UNBLOCK_INPUT;
+ unblock_input ();
XftPatternDestroy (match);
return Qnil;
}
ft_face = XftLockFace (xftfont);
- UNBLOCK_INPUT;
+ unblock_input ();
/* We should not destroy PAT here because it is kept in XFTFONT and
destroyed automatically when XFTFONT is closed. */
for (ch = 0; ch < 95; ch++)
ascii_printable[ch] = ' ' + ch;
}
- BLOCK_INPUT;
+ block_input ();
/* Unfortunately Xft doesn't provide a way to get minimum char
width. So, we set min_width to space_width. */
XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
font->average_width = (font->space_width + extents.xOff) / 95;
}
- UNBLOCK_INPUT;
+ unblock_input ();
font->ascent = xftfont->ascent;
font->descent = xftfont->descent;
if (xftfont_info->otf)
OTF_close (xftfont_info->otf);
#endif
- BLOCK_INPUT;
+ block_input ();
XftUnlockFace (xftfont_info->xftfont);
XftFontClose (xftfont_info->display, xftfont_info->xftfont);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static int
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
- BLOCK_INPUT;
+ block_input ();
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
- UNBLOCK_INPUT;
+ unblock_input ();
if (metrics)
{
metrics->lbearing = - extents.x;
if (! xft_draw)
{
- BLOCK_INPUT;
+ block_input ();
xft_draw= XftDrawCreate (FRAME_X_DISPLAY (f),
FRAME_X_WINDOW (f),
FRAME_X_VISUAL (f),
FRAME_X_COLORMAP (f));
- UNBLOCK_INPUT;
+ unblock_input ();
eassert (xft_draw != NULL);
font_put_frame_data (f, &xftfont_driver, xft_draw);
}
xftface_info = (struct xftface_info *) face->extra;
xftfont_get_colors (f, face, s->gc, xftface_info,
&fg, with_background ? &bg : NULL);
- BLOCK_INPUT;
+ block_input ();
if (s->num_clips > 0)
XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips);
else
else
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x, y, code, len);
- UNBLOCK_INPUT;
+ unblock_input ();
return len;
}
if (xft_draw)
{
- BLOCK_INPUT;
+ block_input ();
XftDrawDestroy (xft_draw);
- UNBLOCK_INPUT;
+ unblock_input ();
font_put_frame_data (f, &xftfont_driver, NULL);
}
return 0;
if (! FRAME_X_P (f))
emacs_abort ();
- BLOCK_INPUT;
+ block_input ();
XQueryPointer (FRAME_X_DISPLAY (f),
DefaultRootWindow (FRAME_X_DISPLAY (f)),
we don't care. */
(unsigned int *) &dummy);
- UNBLOCK_INPUT;
+ unblock_input ();
/* xmenu_show expects window coordinates, not root window
coordinates. Translate. */
list_of_panes (Fcons (contents, Qnil));
/* Display them in a dialog box. */
- BLOCK_INPUT;
+ block_input ();
selection = xdialog_show (f, 0, title, header, &error_name);
- UNBLOCK_INPUT;
+ unblock_input ();
unbind_to (specpdl_count, Qnil);
discard_menu_items ();
XEvent ev;
FRAME_PTR f = check_x_frame (frame);
Widget menubar;
- BLOCK_INPUT;
+ block_input ();
if (FRAME_EXTERNAL_MENU_BAR (f))
set_frame_menubar (f, 0, 1);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
FRAME_PTR f;
/* gcc 2.95 doesn't accept the FRAME_PTR declaration after
- BLOCK_INPUT. */
+ block_input (). */
- BLOCK_INPUT;
+ block_input ();
f = check_x_frame (frame);
if (FRAME_EXTERNAL_MENU_BAR (f))
g_list_free (children);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
#endif
set_frame_menubar (f, 0, 1);
- BLOCK_INPUT;
+ block_input ();
popup_activated_flag = 1;
#ifdef USE_GTK
XPutBackEvent (f->output_data.x->display_info->display,
#else
XtDispatchEvent (f->output_data.x->saved_menu_event);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
/* Ignore this if we get it a second time. */
f->output_data.x->saved_menu_event->type = 0;
sit-for will exit at once if the focus event follows the menu selection
event. */
- BLOCK_INPUT;
+ block_input ();
while (gtk_events_pending ())
gtk_main_iteration ();
- UNBLOCK_INPUT;
+ unblock_input ();
find_and_call_menu_selection (cb_data->cl_data->f,
cb_data->cl_data->menu_bar_items_used,
if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
return 0;
- BLOCK_INPUT;
+ block_input ();
/* Save the size of the frame because the pane widget doesn't accept
to resize itself. So force it. */
columns = FRAME_COLS (f);
/* Force the pane widget to resize itself with the right values. */
EmacsFrameSetCharSize (x->edit_widget, columns, rows);
- UNBLOCK_INPUT;
+ unblock_input ();
#endif
return 1;
}
/* Create or update the menu bar widget. */
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_GTK
xg_crazy_callback_abort = 1;
xg_crazy_callback_abort = 0;
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Called from Fx_create_frame to create the initial menubar of a frame
Position x0, y0, x1, y1;
#endif
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_MOTIF
if (f->output_data.x->widget)
#endif
x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
#endif /* not USE_GTK */
struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
popup_activated_flag = 0;
- BLOCK_INPUT;
+ block_input ();
gtk_widget_destroy (GTK_WIDGET (p->pointer));
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
| XINT (XCDR (arg)));
- BLOCK_INPUT;
+ block_input ();
lw_destroy_all_widgets (id);
- UNBLOCK_INPUT;
+ unblock_input ();
popup_activated_flag = 0;
return Qnil;
if ((intptr_t) client_data != -1)
menu_item_selection = (Lisp_Object *) client_data;
- BLOCK_INPUT;
+ block_input ();
lw_destroy_all_widgets (id);
- UNBLOCK_INPUT;
+ unblock_input ();
popup_activated_flag = 0;
}
FRAME_PTR f = p1->pointer;
XMenu *menu = p2->pointer;
- BLOCK_INPUT;
+ block_input ();
#ifndef MSDOS
XUngrabPointer (FRAME_X_DISPLAY (f), CurrentTime);
XUngrabKeyboard (FRAME_X_DISPLAY (f), CurrentTime);
#endif /* HAVE_X_WINDOWS */
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
if (!SYMBOLP (sym)) emacs_abort ();
TRACE1 (" XInternAtom %s", SSDATA (SYMBOL_NAME (sym)));
- BLOCK_INPUT;
+ block_input ();
val = XInternAtom (dpyinfo->display, SSDATA (SYMBOL_NAME (sym)), False);
- UNBLOCK_INPUT;
+ unblock_input ();
return val;
}
if (atom == dpyinfo->Xatom_NULL)
return QNULL;
- BLOCK_INPUT;
+ block_input ();
str = XGetAtomName (dpy, atom);
- UNBLOCK_INPUT;
+ unblock_input ();
TRACE1 ("XGetAtomName --> %s", str);
if (! str) return Qnil;
val = intern (str);
- BLOCK_INPUT;
+ block_input ();
/* This was allocated by Xlib, so use XFree. */
XFree (str);
- UNBLOCK_INPUT;
+ unblock_input ();
return val;
}
\f
Time timestamp = last_event_timestamp;
Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_name);
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (display);
XSetSelectionOwner (display, selection_atom, selecting_window, timestamp);
x_check_errors (display, "Can't set selection: %s");
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
/* Now update the local cache */
{
/* The reason for the error may be that the receiver has
died in the meantime. Handle that case. */
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (reply->display);
XSendEvent (reply->display, reply->requestor, False, 0L, &reply_base);
XFlush (reply->display);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* This is the selection request currently being processed.
static Lisp_Object
x_catch_errors_unwind (Lisp_Object dummy)
{
- BLOCK_INPUT;
+ block_input ();
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
\f
if (reply->property == None)
reply->property = reply->target;
- BLOCK_INPUT;
+ block_input ();
/* The protected block contains wait_for_property_change, which can
run random lisp code (process handlers) or signal. Therefore, we
put the x_uncatch_errors call in an unwind. */
{
int format_bytes = cs->format / 8;
int had_errors = x_had_errors_p (display);
- UNBLOCK_INPUT;
+ unblock_input ();
bytes_remaining = cs->size;
bytes_remaining *= format_bytes;
int i = ((bytes_remaining < max_bytes)
? bytes_remaining
: max_bytes) / format_bytes;
- BLOCK_INPUT;
+ block_input ();
cs->wait_object
= expect_property_change (display, window, cs->property,
: format_bytes);
XFlush (display);
had_errors = x_had_errors_p (display);
- UNBLOCK_INPUT;
+ unblock_input ();
if (had_errors) break;
/* Now write a zero-length chunk to the property to tell the
requestor that we're done. */
- BLOCK_INPUT;
+ block_input ();
if (! waiting_for_other_props_on_window (display, window))
XSelectInput (display, window, 0L);
/* 2004-09-10: XSync and UNBLOCK so that possible protocol errors are
delivered before uncatch errors. */
XSync (display, False);
- UNBLOCK_INPUT;
+ unblock_input ();
/* GTK queues events in addition to the queue in Xlib. So we
UNBLOCK to enter the event loop and get possible errors delivered,
and then BLOCK again because x_uncatch_errors requires it. */
- BLOCK_INPUT;
+ block_input ();
/* This calls x_uncatch_errors. */
unbind_to (count, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
/* Handle a SelectionRequest event EVENT.
if (! NILP (time_stamp))
CONS_TO_INTEGER (time_stamp, Time, requestor_time);
- BLOCK_INPUT;
+ block_input ();
TRACE2 ("Get selection %s, type %s",
XGetAtomName (display, type_atom),
XGetAtomName (display, target_property));
record_unwind_protect (queue_selection_requests_unwind, Qnil);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
/* This allows quits. Also, don't wait forever. */
timeout = max (0, x_selection_timeout);
? min (PTRDIFF_MAX, SIZE_MAX) - 1
: LONG_MAX * x_long_size);
- BLOCK_INPUT;
+ block_input ();
/* First probe the thing to find out how big it is. */
result = XGetWindowProperty (display, window, property,
data[offset] = '\0';
done:
- UNBLOCK_INPUT;
+ unblock_input ();
*data_ret = data;
*bytes_ret = offset;
return;
size_overflow:
free (data);
- UNBLOCK_INPUT;
+ unblock_input ();
memory_full (SIZE_MAX);
memory_exhausted:
free (data);
- UNBLOCK_INPUT;
+ unblock_input ();
memory_full (total_size + 1);
}
\f
that property, then reading the property, then deleting it to ack.
We are done when the sender places a property of length 0.
*/
- BLOCK_INPUT;
+ block_input ();
XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
TRACE1 (" Delete property %s",
SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
wait_object = expect_property_change (display, window, property,
PropertyNewValue);
XFlush (display);
- UNBLOCK_INPUT;
+ unblock_input ();
while (1)
{
break;
}
- BLOCK_INPUT;
+ block_input ();
TRACE1 (" ACK by deleting property %s",
XGetAtomName (display, property));
XDeleteProperty (display, window, property);
wait_object = expect_property_change (display, window, property,
PropertyNewValue);
XFlush (display);
- UNBLOCK_INPUT;
+ unblock_input ();
if (*size_bytes_ret - offset < tmp_size_bytes)
*data_ret = xpalloc (*data_ret, size_bytes_ret,
if (! data)
{
int there_is_a_selection_owner;
- BLOCK_INPUT;
+ block_input ();
there_is_a_selection_owner
= XGetSelectionOwner (display, selection_atom);
- UNBLOCK_INPUT;
+ unblock_input ();
if (there_is_a_selection_owner)
signal_error ("Selection owner couldn't convert",
actual_type
/* That wasn't really the data, just the beginning. */
unsigned int min_size_bytes = * ((unsigned int *) data);
- BLOCK_INPUT;
+ block_input ();
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
xfree (data);
- UNBLOCK_INPUT;
+ unblock_input ();
receive_incremental_selection (display, window, property, target_type,
min_size_bytes, &data, &bytes,
&actual_type, &actual_format,
&actual_size);
}
- BLOCK_INPUT;
+ block_input ();
TRACE1 (" Delete property %s", XGetAtomName (display, property));
XDeleteProperty (display, window, property);
XFlush (display);
- UNBLOCK_INPUT;
+ unblock_input ();
/* It's been read. Now convert it to a lisp object in some semi-rational
manner. */
selection_atom = symbol_to_x_atom (dpyinfo, selection);
- BLOCK_INPUT;
+ block_input ();
if (NILP (time_object))
timestamp = last_event_timestamp;
else
CONS_TO_INTEGER (time_object, Time, timestamp);
XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp);
- UNBLOCK_INPUT;
+ unblock_input ();
/* It doesn't seem to be guaranteed that a SelectionClear event will be
generated for a window which owns the selection when that window sets
atom = symbol_to_x_atom (dpyinfo, selection);
if (atom == 0) return Qnil;
- BLOCK_INPUT;
+ block_input ();
owner = XGetSelectionOwner (dpyinfo->display, atom);
- UNBLOCK_INPUT;
+ unblock_input ();
return (owner ? Qt : Qnil);
}
val = cons_to_signed (o, LONG_MIN, LONG_MAX);
else if (STRINGP (o))
{
- BLOCK_INPUT;
+ block_input ();
val = (long) XInternAtom (dpy, SSDATA (o), False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
else
error ("Wrong type, must be string, number or cons");
Window root, dummy_window;
int dummy;
- BLOCK_INPUT;
+ block_input ();
XQueryPointer (FRAME_X_DISPLAY (f),
DefaultRootWindow (FRAME_X_DISPLAY (f)),
*x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
*y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
DEFUN ("x-get-atom-name", Fx_get_atom_name,
CONS_TO_INTEGER (value, Atom, atom);
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (dpy);
name = atom ? XGetAtomName (dpy, atom) : empty;
had_errors = x_had_errors_p (dpy);
if (atom && name) XFree (name);
if (NILP (ret)) ret = empty_unibyte_string;
- UNBLOCK_INPUT;
+ unblock_input ();
return ret;
}
x_atom = symbol_to_x_atom (dpyinfo, atom);
else if (STRINGP (atom))
{
- BLOCK_INPUT;
+ block_input ();
x_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (atom), False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
else
error ("ATOM must be a symbol or a string");
if (wdest == 0) wdest = dpyinfo->root_window;
to_root = wdest == dpyinfo->root_window;
- BLOCK_INPUT;
+ block_input ();
event.xclient.message_type = message_type;
event.xclient.display = dpyinfo->display;
XFlush (dpyinfo->display);
}
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
{
Display *dpy = dpyinfo->display;
- BLOCK_INPUT;
+ block_input ();
/* Select events so we can detect client messages sent when selection
owner changes. */
if (dpyinfo->xsettings_window != None)
read_and_apply_settings (dpyinfo, False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
if (!NILP (Vinhibit_redisplay))
return;
- BLOCK_INPUT;
+ block_input ();
if (f == NULL)
{
Lisp_Object rest, frame;
}
else if (FRAME_X_P (f))
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
updated_window = w;
set_output_cursor (&w->cursor);
- BLOCK_INPUT;
+ block_input ();
if (f == hlinfo->mouse_face_mouse_frame)
{
hlinfo->mouse_face_window = Qnil;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!w->pseudo_window_p)
{
- BLOCK_INPUT;
+ block_input ();
if (cursor_on_p)
display_and_set_cursor (w, 1, output_cursor.hpos,
if (draw_window_fringes (w, 1))
x_draw_vertical_border (w);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If a row with mouse-face was overwritten, arrange for
MOUSE_HL_INFO (f)->mouse_face_defer = 0;
#ifndef XFlush
- BLOCK_INPUT;
+ block_input ();
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
#endif
}
if (hlinfo->mouse_face_deferred_gc
|| f == hlinfo->mouse_face_mouse_frame)
{
- BLOCK_INPUT;
+ block_input ();
if (hlinfo->mouse_face_mouse_frame)
note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
hlinfo->mouse_face_mouse_x,
hlinfo->mouse_face_mouse_y);
hlinfo->mouse_face_deferred_gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- BLOCK_INPUT;
+ block_input ();
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
0, y, width, height, False);
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
FRAME_PIXEL_WIDTH (f) - width,
y, width, height, False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
XColor color;
color.pixel = pixel;
- BLOCK_INPUT;
+ block_input ();
x_query_color (f, &color);
XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
- UNBLOCK_INPUT;
+ unblock_input ();
#ifdef DEBUG_X_COLORS
register_color (pixel);
#endif
/* We don't set the output cursor here because there will always
follow an explicit cursor_to. */
- BLOCK_INPUT;
+ block_input ();
XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
XTflash (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
{
#ifdef USE_GTK
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
XTtoggle_invisible_pointer (FRAME_PTR f, int invisible)
{
- BLOCK_INPUT;
+ block_input ();
if (invisible)
{
if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor != 0)
XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
f->output_data.x->current_cursor);
f->pointer_invisible = invisible;
- UNBLOCK_INPUT;
+ unblock_input ();
}
XTflash (f);
else
{
- BLOCK_INPUT;
+ block_input ();
XBell (FRAME_X_DISPLAY (f), 0);
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
height = run->height;
}
- BLOCK_INPUT;
+ block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
updated_window = w;
width, height,
x, to_y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
the ICCCM (section 4.1.6) says that the window's border pixmap
and border pixel are window attributes which are "private to the
client", so we can always change it to whatever we want. */
- BLOCK_INPUT;
+ block_input ();
/* I recently started to get errors in this XSetWindowBorder, depending on
the window-manager in use, tho something more is at play since I've been
using that same window-manager binary for ever. Let's not crash just
XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
f->output_data.x->border_pixel);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
x_update_cursor (f, 1);
x_set_frame_alpha (f);
}
the ICCCM (section 4.1.6) says that the window's border pixmap
and border pixel are window attributes which are "private to the
client", so we can always change it to whatever we want. */
- BLOCK_INPUT;
+ block_input ();
/* Same as above for XSetWindowBorder (bug#9310). */
x_catch_errors (FRAME_X_DISPLAY (f));
XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
f->output_data.x->border_tile);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
x_update_cursor (f, 1);
x_set_frame_alpha (f);
}
{
char *value;
- BLOCK_INPUT;
+ block_input ();
value = XKeysymToString (keysym);
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
{
FRAME_PTR f1;
- BLOCK_INPUT;
+ block_input ();
if (! NILP (last_mouse_scroll_bar) && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
struct frame *f = XFRAME (w->frame);
ptrdiff_t i;
- BLOCK_INPUT;
+ block_input ();
/* Construct a ClientMessage event to send to the frame. */
ev->type = ClientMessage;
be sent to the client that created the window, and if that
window no longer exists, no event will be sent. */
XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False, 0, &event);
- UNBLOCK_INPUT;
+ unblock_input ();
}
int slider_size;
/* Get the slider size. */
- BLOCK_INPUT;
+ block_input ();
XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
- UNBLOCK_INPUT;
+ unblock_input ();
whole = XM_SB_MAX - slider_size;
portion = min (cs->value, whole);
int part;
/* Get the size of the thumb, a value between 0 and 1. */
- BLOCK_INPUT;
+ block_input ();
XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
- UNBLOCK_INPUT;
+ unblock_input ();
whole = 10000000;
portion = shown < 1 ? top * whole : 0;
int part;
/* Get the height of the scroll bar. */
- BLOCK_INPUT;
+ block_input ();
XtVaGetValues (widget, XtNheight, &height, NULL);
- UNBLOCK_INPUT;
+ unblock_input ();
if (eabs (position) >= height)
part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
{
const char *scroll_bar_name = SCROLL_BAR_NAME;
- BLOCK_INPUT;
+ block_input ();
xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
G_CALLBACK (xg_end_scroll_callback),
scroll_bar_name);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#else /* not USE_GTK */
const char *scroll_bar_name = SCROLL_BAR_NAME;
unsigned long pixel;
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_MOTIF
/* Set resources. Create the widget. */
xwindow = XtWindow (widget);
bar->x_window = xwindow;
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* not USE_GTK */
Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
float top, shown;
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_MOTIF
}
#endif /* !USE_MOTIF */
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* not USE_GTK */
= ALLOCATE_PSEUDOVECTOR (struct scroll_bar, x_window, PVEC_OTHER);
Lisp_Object barobj;
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_TOOLKIT_SCROLL_BARS
x_create_toolkit_scroll_bar (f, bar);
XMapRaised (FRAME_X_DISPLAY (f), bar->x_window);
#endif /* not USE_TOOLKIT_SCROLL_BARS */
- UNBLOCK_INPUT;
+ unblock_input ();
return bar;
}
&& end == bar->end)
return;
- BLOCK_INPUT;
+ block_input ();
{
int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* !USE_TOOLKIT_SCROLL_BARS */
x_scroll_bar_remove (struct scroll_bar *bar)
{
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_TOOLKIT_SCROLL_BARS
#ifdef USE_GTK
/* Dissociate this scroll bar from its window. */
wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
if (width > 0 && height > 0)
{
- BLOCK_INPUT;
+ block_input ();
#ifdef USE_TOOLKIT_SCROLL_BARS
if (fringe_extended_p)
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
#endif
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
left, top, width, height, False);
- UNBLOCK_INPUT;
+ unblock_input ();
}
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
bar = XSCROLL_BAR (w->vertical_scroll_bar);
- BLOCK_INPUT;
+ block_input ();
if (sb_left != bar->left)
mask |= CWX;
bar->width = sb_width;
bar->height = height;
- UNBLOCK_INPUT;
+ unblock_input ();
}
#ifdef USE_TOOLKIT_SCROLL_BARS
GC gc = f->output_data.x->normal_gc;
int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
- BLOCK_INPUT;
+ block_input ();
x_scroll_bar_set_handle (bar, bar->start, bar->end, 1);
XSetForeground (FRAME_X_DISPLAY (f), gc,
FRAME_FOREGROUND_PIXEL (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* not USE_TOOLKIT_SCROLL_BARS */
int dummy_coord;
unsigned int dummy_mask;
- BLOCK_INPUT;
+ block_input ();
/* Get the mouse's position relative to the scroll bar window, and
report that. */
*timestamp = last_mouse_movement_time;
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
XEvent *xev = (XEvent *) gxev;
- BLOCK_INPUT;
+ block_input ();
if (current_count >= 0)
{
struct x_display_info *dpyinfo;
&& dpyinfo
&& x_filter_event (dpyinfo, xev))
{
- UNBLOCK_INPUT;
+ unblock_input ();
return GDK_FILTER_REMOVE;
}
#endif
else
current_finish = x_dispatch_event (xev, xev->xany.display);
- UNBLOCK_INPUT;
+ unblock_input ();
if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
return GDK_FILTER_REMOVE;
default:
OTHER:
#ifdef USE_X_TOOLKIT
- BLOCK_INPUT;
+ block_input ();
if (*finish != X_EVENT_DROP)
XtDispatchEvent (&event);
- UNBLOCK_INPUT;
+ unblock_input ();
#endif /* USE_X_TOOLKIT */
break;
}
int count = 0;
int event_found = 0;
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- pending_signals = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- pending_signals = pending_atimers;
- BLOCK_INPUT;
+ block_input ();
/* So people can tell when we have read the available input. */
input_signal_count++;
pending_autoraise_frame = 0;
}
- UNBLOCK_INPUT;
+ unblock_input ();
return count;
}
{
struct x_error_message_stack *tmp;
- BLOCK_INPUT;
+ block_input ();
/* The display may have been closed before this function is called.
Check if it is still open before calling XSync. */
tmp = x_error_message;
x_error_message = x_error_message->prev;
xfree (tmp);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If any X protocol errors have arrived since the last call to
}
#endif /* ! 0 */
-\f
-/* Handle SIGPIPE, which can happen when the connection to a server
- simply goes away. SIGPIPE is handled by x_connection_signal.
- Don't need to do anything, because the write which caused the
- SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
- which will do the appropriate cleanup for us. */
-
-static void
-x_connection_signal (int signalnum) /* If we don't have an argument, */
- /* some compilers complain in signal calls. */
-{
-#ifdef USG
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- struct sigaction action;
- emacs_sigaction_init (&action, x_connection_signal);
- sigaction (signalnum, &action, 0);
-#endif /* USG */
-}
-
\f
/************************************************************************
Handling X errors
/* NOTREACHED */
}
- /* Ordinary stack unwind doesn't deal with these. */
- {
- sigset_t unblocked;
- sigemptyset (&unblocked);
-#ifdef USABLE_SIGIO
- sigaddset (&unblocked, SIGIO);
-#endif
- sigaddset (&unblocked, SIGALRM);
- pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
- }
- TOTALLY_UNBLOCK_INPUT;
+ totally_unblock_input ();
unbind_to (idx, Qnil);
clear_waiting_for_input ();
if (FRAME_XIC (f)
&& (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
{
- BLOCK_INPUT;
+ block_input ();
xic_set_xfontset (f, SSDATA (fontset_ascii (fontset)));
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif
struct x_display_info *dpyinfo = (struct x_display_info *) client_data;
Lisp_Object frame, tail;
- BLOCK_INPUT;
+ block_input ();
/* No need to call XDestroyIC.. */
FOR_EACH_FRAME (tail, frame)
/* No need to call XCloseIM. */
dpyinfo->xim = NULL;
XFree (dpyinfo->xim_styles);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_X11R6 */
{
Lisp_Object tail, frame;
- BLOCK_INPUT;
+ block_input ();
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
x_calc_absolute_position (f);
- BLOCK_INPUT;
+ block_input ();
x_wm_set_size_hint (f, (long) 0, 0);
modified_left = f->left_pos;
&& FRAME_X_OUTPUT (f)->move_offset_top == 0))))
x_check_expected_move (f, modified_left, modified_top);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Return non-zero if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
unsigned char *tmp_data = NULL;
Atom target_type = XA_WINDOW;
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (dpy);
rc = XGetWindowProperty (dpy, target_window,
{
if (tmp_data) XFree (tmp_data);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
if (x_had_errors_p (dpy))
{
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
{
if (tmp_data) XFree (tmp_data);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
rc = dpyinfo->net_supported_atoms[i] == want_atom;
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return rc;
}
*sticky = 0;
*size_state = FULLSCREEN_NONE;
- BLOCK_INPUT;
+ block_input ();
x_catch_errors (dpy);
rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state,
0, max_len, False, target_type,
{
if (tmp_data) XFree (tmp_data);
x_uncatch_errors ();
- UNBLOCK_INPUT;
+ unblock_input ();
return ! f->iconified;
}
}
if (tmp_data) XFree (tmp_data);
- UNBLOCK_INPUT;
+ unblock_input ();
return ! is_hidden;
}
{
if (f->async_visible)
{
- BLOCK_INPUT;
+ block_input ();
x_check_fullscreen (f);
x_sync (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
while (pending_event_wait.eventtype)
{
- interrupt_input_pending = 1;
- TOTALLY_UNBLOCK_INPUT;
+ pending_signals = 1;
+ totally_unblock_input ();
/* XTread_socket is called after unblock. */
- BLOCK_INPUT;
+ block_input ();
interrupt_input_blocked = level;
FD_ZERO (&fds);
void
x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
{
- BLOCK_INPUT;
+ block_input ();
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
{
so don't try--just let the highlighting be done afresh with new size. */
cancel_mouse_face (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
/* Mouse warping. */
if (pix_y < 0) pix_y = 0;
if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f);
- BLOCK_INPUT;
+ block_input ();
XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
0, 0, 0, 0, pix_x, pix_y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
void
x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
{
- BLOCK_INPUT;
+ block_input ();
XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
0, 0, 0, 0, pix_x, pix_y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
/* Raise frame F. */
void
x_raise_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
if (f->async_visible)
XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Lower frame F. */
{
if (f->async_visible)
{
- BLOCK_INPUT;
+ block_input ();
XLowerWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
retry:
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
original_top = f->top_pos;
/* This must come after we set COUNT. */
- UNBLOCK_INPUT;
+ unblock_input ();
/* We unblock here so that arriving X events are processed. */
int x, y;
unsigned int width, height, border, depth;
- BLOCK_INPUT;
+ block_input ();
/* On some window managers (such as FVWM) moving an existing
window, even to the same place, causes the window manager
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
original_left, original_top);
- UNBLOCK_INPUT;
+ unblock_input ();
}
XSETFRAME (frame, f);
if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f)
FRAME_X_DISPLAY_INFO (f)->x_highlight_frame = 0;
- BLOCK_INPUT;
+ block_input ();
/* Before unmapping the window, update the WM_SIZE_HINTS property to claim
that the current position of the window is user-specified, rather than
if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
DefaultScreen (FRAME_X_DISPLAY (f))))
{
- UNBLOCK_INPUT_RESIGNAL;
+ unblock_input ();
error ("Can't notify window manager of window withdrawal");
}
}
x_sync (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Change window state from mapped to iconified. */
if (f->async_iconified)
return;
- BLOCK_INPUT;
+ block_input ();
FRAME_SAMPLE_VISIBILITY (f);
f->visible = 1;
f->async_iconified = 1;
f->async_visible = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
#endif
f->visible = 1;
f->async_iconified = 1;
f->async_visible = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
result = XIconifyWindow (FRAME_X_DISPLAY (f),
XtWindow (f->output_data.x->widget),
DefaultScreen (FRAME_X_DISPLAY (f)));
- UNBLOCK_INPUT;
+ unblock_input ();
if (!result)
error ("Can't notify window manager of iconification");
f->async_visible = 0;
- BLOCK_INPUT;
+ block_input ();
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
#else /* not USE_X_TOOLKIT */
/* Make sure the X server knows where the window should be positioned,
SubstructureRedirectMask | SubstructureNotifyMask,
&msg))
{
- UNBLOCK_INPUT_RESIGNAL;
+ unblock_input ();
error ("Can't notify window manager of iconification");
}
}
f->async_visible = 0;
XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
+ unblock_input ();
#endif /* not USE_X_TOOLKIT */
}
struct scroll_bar *b;
#endif
- BLOCK_INPUT;
+ block_input ();
/* If a display connection is dead, don't try sending more
commands to the X server. */
hlinfo->mouse_face_mouse_frame = 0;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
Mouse_HLInfo *hlinfo;
ptrdiff_t lim;
- BLOCK_INPUT;
+ block_input ();
if (!x_initialized)
{
/* Detect failure. */
if (dpy == 0)
{
- UNBLOCK_INPUT;
+ unblock_input ();
return 0;
}
/* Temporarily hide the partially initialized terminal. */
terminal_list = terminal->next_terminal;
- UNBLOCK_INPUT;
+ unblock_input ();
kset_system_key_alist
(terminal->kboard,
call1 (Qvendor_specific_keysyms,
vendor ? build_string (vendor) : empty_unibyte_string));
- BLOCK_INPUT;
+ block_input ();
terminal->next_terminal = terminal_list;
terminal_list = terminal;
UNGCPRO;
x_session_initialize (dpyinfo);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
return dpyinfo;
}
static void
x_process_timeouts (struct atimer *timer)
{
- BLOCK_INPUT;
+ block_input ();
x_timeout_atimer_activated_flag = 0;
if (toolkit_scroll_bar_interaction || popup_activated ())
{
/* Reactivate the atimer for next time. */
x_activate_timeout_atimer ();
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Install an asynchronous timer that processes Xt timeout events
void
x_activate_timeout_atimer (void)
{
- BLOCK_INPUT;
+ block_input ();
if (!x_timeout_atimer_activated_flag)
{
EMACS_TIME interval = make_emacs_time (0, 100 * 1000 * 1000);
start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
x_timeout_atimer_activated_flag = 1;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* USE_X_TOOLKIT */
if (!terminal->name)
return;
- BLOCK_INPUT;
+ block_input ();
#ifdef HAVE_X_I18N
/* We must close our connection to the XIM server before closing the
X display. */
/* Mark as dead. */
dpyinfo->display = NULL;
x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Create a struct terminal, initialize it with the X11 specific
void
x_initialize (void)
{
- struct sigaction action;
-
baud_rate = 19200;
x_noop_count = 0;
original error handler. */
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_quitter);
-
- emacs_sigaction_init (&action, x_connection_signal);
- sigaction (SIGPIPE, &action, 0);
}