Remove HAVE_MOUSE; see https://lists.gnu.org/archive/html/emacs-devel/2012-10/msg0040...
[bpt/emacs.git] / src / keyboard.c
index 098d353..0ad6d18 100644 (file)
@@ -19,6 +19,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#define BLOCKINPUT_INLINE EXTERN_INLINE
 #define KEYBOARD_INLINE EXTERN_INLINE
 
 #include <stdio.h>
@@ -72,19 +73,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* 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;
+/* True means an input interrupt or alarm signal has arrived.
+   The QUIT macro checks this.  */
+volatile bool pending_signals;
 
 #define KBD_BUFFER_SIZE 4096
 
@@ -92,8 +86,8 @@ KBOARD *initial_kboard;
 KBOARD *current_kboard;
 KBOARD *all_kboards;
 
-/* Nonzero in the single-kboard state, 0 in the any-kboard state.  */
-static int single_kboard;
+/* True in the single-kboard state, false in the any-kboard state.  */
+static bool single_kboard;
 
 /* Non-nil disable property on a command means
    do not execute it; call disabled-command-function's value instead.  */
@@ -119,9 +113,9 @@ static Lisp_Object recent_keys;
 Lisp_Object this_command_keys;
 ptrdiff_t this_command_key_count;
 
-/* 1 after calling Freset_this_command_lengths.
-   Usually it is 0.  */
-static int this_command_key_count_reset;
+/* True after calling Freset_this_command_lengths.
+   Usually it is false.  */
+static bool this_command_key_count_reset;
 
 /* This vector is used as a buffer to record the events that were actually read
    by read_key_sequence.  */
@@ -146,11 +140,11 @@ static ptrdiff_t before_command_echo_length;
 static sys_jmp_buf getcjmp;
 
 /* True while doing kbd input.  */
-int waiting_for_input;
+bool waiting_for_input;
 
 /* True while displaying for echoing.   Delays C-g throwing.  */
 
-static int echoing;
+static bool echoing;
 
 /* Non-null means we can start echoing at the next input pause even
    though there is something in the echo area.  */
@@ -169,8 +163,8 @@ struct kboard *echo_kboard;
 
 Lisp_Object echo_message_buffer;
 
-/* Nonzero means C-g should cause immediate error-signal.  */
-int immediate_quit;
+/* True means C-g should cause immediate error-signal.  */
+bool immediate_quit;
 
 /* Character that causes a quit.  Normally C-g.
 
@@ -225,7 +219,11 @@ static Lisp_Object last_point_position_window;
    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.
@@ -272,7 +270,7 @@ static Lisp_Object Qhelp_form_show;
 static FILE *dribble;
 
 /* Nonzero if input is available.  */
-int input_pending;
+bool input_pending;
 
 /* Circular buffer for pre-read keyboard input.  */
 
@@ -308,14 +306,12 @@ static Lisp_Object Qmake_frame_visible;
 static Lisp_Object Qselect_window;
 Lisp_Object Qhelp_echo;
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 static Lisp_Object Qmouse_fixup_help_message;
-#endif
 
 /* Symbols to denote kinds of events.  */
 static Lisp_Object Qfunction_key;
 Lisp_Object Qmouse_click;
-#if defined (WINDOWSNT)
+#ifdef HAVE_NTGUI
 Lisp_Object Qlanguage_change;
 #endif
 static Lisp_Object Qdrag_n_drop;
@@ -367,29 +363,28 @@ static Lisp_Object command_loop (void);
 static Lisp_Object Qextended_command_history;
 EMACS_TIME timer_check (void);
 
-static void record_menu_key (Lisp_Object c);
 static void echo_now (void);
 static ptrdiff_t echo_length (void);
 
 static Lisp_Object Qpolling_period;
 
 /* Incremented whenever a timer is run.  */
-int timers_run;
+unsigned timers_run;
 
 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
    happens.  */
 EMACS_TIME *input_available_clear_time;
 
-/* Nonzero means use SIGIO interrupts; zero means use CBREAK mode.
-   Default is 1 if INTERRUPT_INPUT is defined.  */
-int interrupt_input;
+/* True means use SIGIO interrupts; false means use CBREAK mode.
+   Default is true if INTERRUPT_INPUT is defined.  */
+bool interrupt_input;
 
 /* Nonzero while interrupts are temporarily deferred during redisplay.  */
-int interrupts_deferred;
+bool interrupts_deferred;
 
 /* If we support a window system, turn on the code to poll periodically
    to detect C-g.  It isn't actually used when doing interrupt input.  */
-#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_ASYNC_EVENTS)
+#ifdef HAVE_WINDOW_SYSTEM
 #define POLL_FOR_INPUT
 #endif
 
@@ -413,25 +408,22 @@ static EMACS_TIME timer_last_idleness_start_time;
 /* 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 bool get_input_pending (int);
+static bool readable_events (int);
 static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
-                                            Lisp_Object, int *);
+                                            Lisp_Object, bool *);
 static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
                                                   Lisp_Object *);
 static Lisp_Object make_lispy_event (struct input_event *);
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
                                         enum scroll_bar_part,
                                         Lisp_Object, Lisp_Object,
                                        Time);
-#endif
 static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object,
                                         Lisp_Object, const char *const *,
                                         Lisp_Object *, ptrdiff_t);
 static Lisp_Object make_lispy_switch_frame (Lisp_Object);
-static int help_char_p (Lisp_Object);
+static bool help_char_p (Lisp_Object);
 static void save_getcjmp (sys_jmp_buf);
 static void restore_getcjmp (sys_jmp_buf);
 static Lisp_Object apply_modifiers (int, Lisp_Object);
@@ -440,8 +432,8 @@ static Lisp_Object restore_kboard_configuration (Lisp_Object);
 #ifdef USABLE_SIGIO
 static void deliver_input_available_signal (int signo);
 #endif
-static void handle_interrupt (void);
-static _Noreturn void quit_throw_to_read_char (int);
+static void handle_interrupt (bool);
+static _Noreturn void quit_throw_to_read_char (bool);
 static void process_special_events (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
@@ -451,47 +443,47 @@ static char *find_user_signal_name (int);
 static void store_user_signal_events (void);
 
 /* These setters are used only in this file, so they can be private.  */
-static inline void
+static void
 kset_echo_string (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (echo_string) = val;
 }
-static inline void
+static void
 kset_kbd_queue (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (kbd_queue) = val;
 }
-static inline void
+static void
 kset_keyboard_translate_table (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (Vkeyboard_translate_table) = val;
 }
-static inline void
+static void
 kset_last_prefix_arg (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (Vlast_prefix_arg) = val;
 }
-static inline void
+static void
 kset_last_repeatable_command (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (Vlast_repeatable_command) = val;
 }
-static inline void
+static void
 kset_local_function_key_map (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (Vlocal_function_key_map) = val;
 }
-static inline void
+static void
 kset_overriding_terminal_local_map (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (Voverriding_terminal_local_map) = val;
 }
-static inline void
+static void
 kset_real_last_command (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (Vreal_last_command) = val;
 }
-static inline void
+static void
 kset_system_key_syms (struct kboard *kb, Lisp_Object val)
 {
   kb->INTERNAL_FIELD (system_key_syms) = val;
@@ -519,7 +511,7 @@ echo_char (Lisp_Object c)
 
       if (INTEGERP (c))
        {
-         ptr = push_key_description (XINT (c), ptr, 1);
+         ptr = push_key_description (XINT (c), ptr);
        }
       else if (SYMBOLP (c))
        {
@@ -823,7 +815,7 @@ This function is called by the editor initialization to begin editing.  */)
 
   /* 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++;
@@ -928,7 +920,7 @@ pop_kboard (void)
 {
   struct terminal *t;
   struct kboard_stack *p = kboard_stack;
-  int found = 0;
+  bool found = 0;
   for (t = terminal_list; t; t = t->next_terminal)
     {
       if (t->kboard == p->kboard)
@@ -961,7 +953,7 @@ pop_kboard (void)
 void
 temporarily_switch_to_single_kboard (struct frame *f)
 {
-  int was_locked = single_kboard;
+  bool was_locked = single_kboard;
   if (was_locked)
     {
       if (f != NULL && FRAME_KBOARD (f) != current_kboard)
@@ -1060,12 +1052,7 @@ cmd_error (Lisp_Object data)
   Vprint_length = old_length;
 
   Vquit_flag = Qnil;
-
   Vinhibit_quit = Qnil;
-#if 0 /* This shouldn't be necessary anymore.  --lorentey  */
-  if (command_loop_level == 0 && minibuf_level == 0)
-    any_kboard_state ();
-#endif
 
   return make_number (0);
 }
@@ -1152,12 +1139,6 @@ command_loop (void)
     while (1)
       {
        internal_catch (Qtop_level, top_level_1, Qnil);
-#if 0 /* This shouldn't be necessary anymore.  --lorentey  */
-        /* Reset single_kboard in case top-level set it while
-           evaluating an -f option, or we are stuck there for some
-           other reason.  */
-        any_kboard_state ();
-#endif
        internal_catch (Qtop_level, command_loop_2, Qnil);
        executing_kbd_macro = Qnil;
 
@@ -1216,8 +1197,7 @@ This also exits all active minibuffers.  */)
 
   /* 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);
 }
@@ -1250,8 +1230,6 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
   user_error ("No recursive edit is in progress");
 }
 \f
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
-
 /* Restore mouse tracking enablement.  See Ftrack_mouse for the only use
    of this function.  */
 
@@ -1269,8 +1247,7 @@ tracking_off (Lisp_Object old_value)
       if (!readable_events (READABLE_EVENTS_DO_TIMERS_NOW))
        {
          redisplay_preserve_echo_area (6);
-         get_input_pending (&input_pending,
-                            READABLE_EVENTS_DO_TIMERS_NOW);
+         get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
        }
     }
   return Qnil;
@@ -1305,7 +1282,7 @@ usage: (track-mouse BODY...)  */)
 #if !defined HAVE_WINDOW_SYSTEM || defined USE_GTK || defined HAVE_NS
 static
 #endif
-int ignore_mouse_drag_p;
+bool ignore_mouse_drag_p;
 
 static FRAME_PTR
 some_mouse_moved (void)
@@ -1327,15 +1304,14 @@ some_mouse_moved (void)
   return 0;
 }
 
-#endif /* HAVE_MOUSE || HAVE_GPM */
 \f
 /* This is the actual command reading loop,
    sans error-handling encapsulation.  */
 
 static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
-                              int, int, int);
+                              bool, bool, bool);
 void safe_run_hooks (Lisp_Object);
-static void adjust_point_for_property (ptrdiff_t, int);
+static void adjust_point_for_property (ptrdiff_t, bool);
 
 /* Cancel hourglass from protect_unwind.
    ARG is not used.  */
@@ -1363,10 +1339,7 @@ command_loop_1 (void)
   int i;
   EMACS_INT prev_modiff = 0;
   struct buffer *prev_buffer = NULL;
-#if 0 /* This shouldn't be necessary anymore.  --lorentey  */
-  int was_locked = single_kboard;
-#endif
-  int already_adjusted = 0;
+  bool already_adjusted = 0;
 
   kset_prefix_arg (current_kboard, Qnil);
   kset_last_prefix_arg (current_kboard, Qnil);
@@ -1422,14 +1395,11 @@ command_loop_1 (void)
 
       Vdeactivate_mark = Qnil;
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
-
       /* Don't ignore mouse movements for more than a single command
         loop.  (This flag is set in xdisp.c whenever the tool bar is
         resized, because the resize moves text up or down, and would
         generate false mouse drag events if we don't ignore them.)  */
       ignore_mouse_drag_p = 0;
-#endif
 
       /* If minibuffer on and echo area in use,
         wait a short time and redraw minibuffer.  */
@@ -1460,15 +1430,6 @@ command_loop_1 (void)
            }
        }
 
-#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)
@@ -1744,10 +1705,6 @@ command_loop_1 (void)
       if (!NILP (KVAR (current_kboard, defining_kbd_macro))
          && NILP (KVAR (current_kboard, Vprefix_arg)))
        finalize_kbd_macro_chars ();
-#if 0 /* This shouldn't be necessary anymore.  --lorentey  */
-      if (!was_locked)
-        any_kboard_state ();
-#endif
     }
 }
 
@@ -1757,7 +1714,7 @@ command_loop_1 (void)
    LAST_PT is the last position of point.  */
 
 static void
-adjust_point_for_property (ptrdiff_t last_pt, int modified)
+adjust_point_for_property (ptrdiff_t last_pt, bool modified)
 {
   ptrdiff_t beg, end;
   Lisp_Object val, overlay, tmp;
@@ -1765,7 +1722,7 @@ adjust_point_for_property (ptrdiff_t last_pt, int modified)
      suppress the point adjustment for automatic composition so that a
      user can keep inserting another character at point or keep
      deleting characters around point.  */
-  int check_composition = ! modified, check_display = 1, check_invisible = 1;
+  bool check_composition = ! modified, check_display = 1, check_invisible = 1;
   ptrdiff_t orig_pt = PT;
 
   /* FIXME: cycling is probably not necessary because these properties
@@ -1804,7 +1761,8 @@ adjust_point_for_property (ptrdiff_t last_pt, int modified)
       check_display = 0;
       if (check_invisible && PT > BEGV && PT < ZV)
        {
-         int inv, ellipsis = 0;
+         int inv;
+         bool ellipsis = 0;
          beg = end = PT;
 
          /* Find boundaries `beg' and `end' of the invisible area, if any.  */
@@ -1933,7 +1891,7 @@ safe_run_hooks_error (Lisp_Object error_data)
   if (SYMBOLP (hook))
     {
       Lisp_Object val;
-      int found = 0;
+      bool found = 0;
       Lisp_Object newval = Qnil;
       for (val = find_symbol_value (hook); CONSP (val); val = XCDR (val))
        if (EQ (fun, XCAR (val)))
@@ -1994,12 +1952,12 @@ safe_run_hooks (Lisp_Object hook)
 
 int poll_suppress_count;
 
-/* Asynchronous timer for polling.  */
 
-static struct atimer *poll_timer;
+#ifdef POLL_FOR_INPUT
 
+/* Asynchronous timer for polling.  */
 
-#ifdef POLL_FOR_INPUT
+static struct atimer *poll_timer;
 
 /* Poll for input, so that we catch a C-g if it comes in.  This
    function is called from x_make_frame_visible, see comment
@@ -2008,9 +1966,9 @@ static struct atimer *poll_timer;
 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
@@ -2020,10 +1978,7 @@ static void
 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 */
@@ -2066,9 +2021,9 @@ start_polling (void)
 #endif
 }
 
-/* Nonzero if we are using polling to handle input asynchronously.  */
+/* True if we are using polling to handle input asynchronously.  */
 
-int
+bool
 input_polling_used (void)
 {
 #ifdef POLL_FOR_INPUT
@@ -2217,7 +2172,6 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
        return;
     }
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   if (!noninteractive && STRINGP (help))
     {
       /* The mouse-fixup-help-message Lisp function can call
@@ -2230,7 +2184,6 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
       if (f)
        f->mouse_moved = 1;
     }
-#endif
 
   if (STRINGP (help) || NILP (help))
     {
@@ -2244,7 +2197,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
 \f
 /* Input of single characters from keyboard */
 
-static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
+static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
                                         EMACS_TIME *end_time);
 static void record_char (Lisp_Object c);
 
@@ -2281,9 +2234,9 @@ do { if (polling_stopped_here) start_polling ();  \
    not to run input methods, but in other respects to act as if
    not reading a key sequence.
 
-   If USED_MOUSE_MENU is non-null, then we set *USED_MOUSE_MENU to 1
-   if we used a mouse menu to read the input, or zero otherwise.  If
-   USED_MOUSE_MENU is null, we don't dereference it.
+   If USED_MOUSE_MENU is non-null, then set *USED_MOUSE_MENU to true
+   if we used a mouse menu to read the input, or false otherwise.  If
+   USED_MOUSE_MENU is null, don't dereference it.
 
    Value is -2 when we find input on another keyboard.  A second call
    to read_char will read it.
@@ -2297,19 +2250,18 @@ do { if (polling_stopped_here) start_polling ();        \
 Lisp_Object
 read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
           Lisp_Object prev_event,
-          int *used_mouse_menu, EMACS_TIME *end_time)
+          bool *used_mouse_menu, EMACS_TIME *end_time)
 {
-  volatile Lisp_Object c;
+  Lisp_Object c;
   ptrdiff_t jmpcount;
   sys_jmp_buf local_getcjmp;
   sys_jmp_buf save_jump;
-  volatile int key_already_recorded = 0;
   Lisp_Object tem, save;
   volatile Lisp_Object previous_echo_area_message;
   volatile Lisp_Object also_record;
-  volatile int reread;
+  volatile bool reread;
   struct gcpro gcpro1, gcpro2;
-  int volatile polling_stopped_here = 0;
+  bool volatile polling_stopped_here = 0;
   struct kboard *orig_kboard = current_kboard;
 
   also_record = Qnil;
@@ -2345,7 +2297,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
 
   if (CONSP (Vunread_command_events))
     {
-      int was_disabled = 0;
+      bool was_disabled = 0;
 
       c = XCAR (Vunread_command_events);
       Vunread_command_events = XCDR (Vunread_command_events);
@@ -2447,7 +2399,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
   /* if redisplay was requested */
   if (commandflag >= 0)
     {
-      int echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
+      bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
 
        /* If there is pending input, process any events which are not
           user-visible, such as X selection_request events.  */
@@ -2535,10 +2487,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
         return c;               /* wrong_kboard_jmpbuf */
 
       if (! NILP (c))
-       {
-         key_already_recorded = 1;
-         goto non_reread_1;
-       }
+       goto exit;
     }
 
   /* Make a longjmp point for quits to use, but don't alter getcjmp just yet.
@@ -2866,12 +2815,10 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
       goto wrong_kboard;
     }
 
- non_reread_1:
-
   /* Buffer switch events are only for internal wakeups
      so don't show them to the user.
      Also, don't record a key if we already did.  */
-  if (BUFFERP (c) || key_already_recorded)
+  if (BUFFERP (c))
     goto exit;
 
   /* Process special events within read_char
@@ -2884,12 +2831,6 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
   if (!NILP (tem))
     {
       struct buffer *prev_buffer = current_buffer;
-#if 0 /* This shouldn't be necessary anymore. --lorentey  */
-      int was_locked = single_kboard;
-      ptrdiff_t count = SPECPDL_INDEX ();
-      record_single_kboard_state ();
-#endif
-
       last_input_event = c;
       Fcommand_execute (tem, Qnil, Fvector (1, &last_input_event), Qt);
 
@@ -2900,13 +2841,6 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
           example banishing the mouse under mouse-avoidance-mode.  */
        timer_resume_idle ();
 
-#if 0 /* This shouldn't be necessary anymore. --lorentey  */
-      /* Resume allowing input from any kboard, if that was true before.  */
-      if (!was_locked)
-       any_kboard_state ();
-      unbind_to (count, Qnil);
-#endif
-
       if (current_buffer != prev_buffer)
        {
          /* The command may have changed the keymaps.  Pretend there
@@ -3014,15 +2948,15 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
     {
       Lisp_Object keys;
       ptrdiff_t key_count;
-      int key_count_reset;
+      bool key_count_reset;
       struct gcpro gcpro1;
       ptrdiff_t count = SPECPDL_INDEX ();
 
       /* Save the echo status.  */
-      int saved_immediate_echo = current_kboard->immediate_echo;
+      bool saved_immediate_echo = current_kboard->immediate_echo;
       struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
       Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
-      int saved_echo_after_prompt = current_kboard->echo_after_prompt;
+      ptrdiff_t saved_echo_after_prompt = current_kboard->echo_after_prompt;
 
 #if 0
       if (before_command_restore_flag)
@@ -3223,9 +3157,9 @@ record_menu_key (Lisp_Object c)
   num_input_events++;
 }
 
-/* Return 1 if should recognize C as "the help character".  */
+/* Return true if should recognize C as "the help character".  */
 
-static int
+static bool
 help_char_p (Lisp_Object c)
 {
   Lisp_Object tail;
@@ -3344,7 +3278,7 @@ record_char (Lisp_Object c)
      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)
@@ -3370,7 +3304,7 @@ record_char (Lisp_Object c)
        }
 
       fflush (dribble);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 }
 
@@ -3397,7 +3331,7 @@ restore_getcjmp (sys_jmp_buf temp)
 
 /* Return true if there are any events in the queue that read-char
    would return.  If this returns false, a read-char would block.  */
-static int
+static bool
 readable_events (int flags)
 {
   if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
@@ -3444,11 +3378,9 @@ readable_events (int flags)
        return 1;
     }
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
       && !NILP (do_mouse_tracking) && some_mouse_moved ())
     return 1;
-#endif
   if (single_kboard)
     {
       if (current_kboard->kbd_queue_has_data)
@@ -3470,20 +3402,20 @@ int stop_character EXTERNALLY_VISIBLE;
 static KBOARD *
 event_to_kboard (struct input_event *event)
 {
-  Lisp_Object frame;
-  frame = event->frame_or_window;
-  if (CONSP (frame))
-    frame = XCAR (frame);
-  else if (WINDOWP (frame))
-    frame = WINDOW_FRAME (XWINDOW (frame));
-
-  /* There are still some events that don't set this field.
-     For now, just ignore the problem.
-     Also ignore dead frames here.  */
-  if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
-    return 0;
+  /* Not applicable for these special events.  */
+  if (event->kind == SELECTION_REQUEST_EVENT
+      || event->kind == SELECTION_CLEAR_EVENT)
+    return NULL;
   else
-    return FRAME_KBOARD (XFRAME (frame));
+    {
+      Lisp_Object obj = event->frame_or_window;
+      /* There are some events that set this field to nil or string.  */
+      if (WINDOWP (obj))
+       obj = WINDOW_FRAME (XWINDOW (obj));
+      /* Also ignore dead frames here.  */
+      return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
+             ? FRAME_KBOARD (XFRAME (obj)) : NULL);
+    }
 }
 
 #ifdef subprocesses
@@ -3514,10 +3446,8 @@ kbd_buffer_store_event (register struct input_event *event)
    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,
@@ -3587,7 +3517,8 @@ kbd_buffer_store_event_hold (register struct input_event *event,
          }
 
          last_event_timestamp = event->timestamp;
-         handle_interrupt ();
+
+         handle_interrupt (0);
          return;
        }
 
@@ -3643,7 +3574,6 @@ kbd_buffer_store_event_hold (register struct input_event *event,
       if (immediate_quit && NILP (Vinhibit_quit))
        {
          immediate_quit = 0;
-         pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
          QUIT;
        }
     }
@@ -3738,15 +3668,14 @@ discard_mouse_events (void)
 }
 
 
-/* Return non-zero if there are any real events waiting in the event
+/* Return true if there are any real events waiting in the event
    buffer, not counting `NO_EVENT's.
 
-   If DISCARD is non-zero, discard NO_EVENT events at the front of
-   the input queue, possibly leaving the input queue empty if there
-   are no real input events.  */
+   Discard NO_EVENT events at the front of the input queue, possibly
+   leaving the input queue empty if there are no real input events.  */
 
-int
-kbd_buffer_events_waiting (int discard)
+bool
+kbd_buffer_events_waiting (void)
 {
   struct input_event *sp;
 
@@ -3758,16 +3687,14 @@ kbd_buffer_events_waiting (int discard)
        sp = kbd_buffer;
     }
 
-  if (discard)
-    kbd_fetch_ptr = sp;
-
+  kbd_fetch_ptr = sp;
   return sp != kbd_store_ptr && sp->kind != NO_EVENT;
 }
 
 \f
 /* Clear input event EVENT.  */
 
-static inline void
+static void
 clear_event (struct input_event *event)
 {
   event->kind = NO_EVENT;
@@ -3782,7 +3709,7 @@ clear_event (struct input_event *event)
 
 static Lisp_Object
 kbd_buffer_get_event (KBOARD **kbp,
-                      int *used_mouse_menu,
+                      bool *used_mouse_menu,
                       EMACS_TIME *end_time)
 {
   Lisp_Object obj;
@@ -3790,17 +3717,9 @@ kbd_buffer_get_event (KBOARD **kbp,
 #ifdef subprocesses
   if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4)
     {
-      /* Start reading input again, we have processed enough so we can
-         accept new events again.  */
+      /* Start reading input again because we have processed enough to
+         be able to accept new events again.  */
       unhold_keyboard_input ();
-#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 */
@@ -3829,10 +3748,8 @@ kbd_buffer_get_event (KBOARD **kbp,
 
       if (kbd_fetch_ptr != kbd_store_ptr)
        break;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
       if (!NILP (do_mouse_tracking) && some_mouse_moved ())
        break;
-#endif
 
       /* If the quit flag is set, then read_char will return
         quit_char, so that counts as "available input."  */
@@ -3847,10 +3764,8 @@ kbd_buffer_get_event (KBOARD **kbp,
 #endif
       if (kbd_fetch_ptr != kbd_store_ptr)
        break;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
       if (!NILP (do_mouse_tracking) && some_mouse_moved ())
        break;
-#endif
       if (end_time)
        {
          EMACS_TIME now = current_emacs_time ();
@@ -3869,7 +3784,7 @@ kbd_buffer_get_event (KBOARD **kbp,
        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))
@@ -3979,7 +3894,7 @@ kbd_buffer_get_event (KBOARD **kbp,
            x_activate_menubar (XFRAME (event->frame_or_window));
        }
 #endif
-#if defined (WINDOWSNT)
+#ifdef HAVE_NTGUI
       else if (event->kind == LANGUAGE_CHANGE_EVENT)
        {
          /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)).  */
@@ -4107,7 +4022,6 @@ kbd_buffer_get_event (KBOARD **kbp,
            }
        }
     }
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   /* Try generating a mouse motion event.  */
   else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
     {
@@ -4152,7 +4066,6 @@ kbd_buffer_get_event (KBOARD **kbp,
       if (!NILP (x) && NILP (obj))
        obj = make_lispy_movement (f, bar_window, part, x, y, t);
     }
-#endif /* HAVE_MOUSE || HAVE GPM */
   else
     /* We were promised by the above while loop that there was
        something for us to read!  */
@@ -4235,14 +4148,14 @@ process_special_events (void)
    are ripe, and return, without reading any user-visible events.  */
 
 void
-swallow_events (int do_display)
+swallow_events (bool do_display)
 {
-  int old_timers_run;
+  unsigned old_timers_run;
 
   process_special_events ();
 
   old_timers_run = timers_run;
-  get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
+  get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
 
   if (timers_run != old_timers_run && do_display)
     redisplay_preserve_echo_area (7);
@@ -4333,25 +4246,18 @@ decode_timer (Lisp_Object timer, EMACS_TIME *result)
    should be done.  */
 
 static EMACS_TIME
-timer_check_2 (void)
+timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
 {
   EMACS_TIME nexttime;
   EMACS_TIME now;
   EMACS_TIME idleness_now;
-  Lisp_Object timers, idle_timers, chosen_timer;
-  struct gcpro gcpro1, gcpro2, gcpro3;
+  Lisp_Object chosen_timer;
+  struct gcpro gcpro1;
 
   nexttime = invalid_emacs_time ();
 
-  /* Always consider the ordinary timers.  */
-  timers = Vtimer_list;
-  /* Consider the idle timers only if Emacs is idle.  */
-  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
-    idle_timers = Vtimer_idle_list;
-  else
-    idle_timers = Qnil;
   chosen_timer = Qnil;
-  GCPRO3 (timers, idle_timers, chosen_timer);
+  GCPRO1 (chosen_timer);
 
   /* First run the code that was delayed.  */
   while (CONSP (pending_funcalls))
@@ -4376,7 +4282,7 @@ timer_check_2 (void)
       EMACS_TIME difference;
       EMACS_TIME timer_difference = invalid_emacs_time ();
       EMACS_TIME idle_timer_difference = invalid_emacs_time ();
-      int ripe, timer_ripe = 0, idle_timer_ripe = 0;
+      bool ripe, timer_ripe = 0, idle_timer_ripe = 0;
 
       /* Set TIMER and TIMER_DIFFERENCE
         based on the next ordinary timer.
@@ -4500,13 +4406,35 @@ EMACS_TIME
 timer_check (void)
 {
   EMACS_TIME nexttime;
+  Lisp_Object timers, idle_timers;
+  struct gcpro gcpro1, gcpro2;
+
+  Lisp_Object tem = Vinhibit_quit;
+  Vinhibit_quit = Qt;
+
+  /* We use copies of the timers' lists to allow a timer to add itself
+     again, without locking up Emacs if the newly added timer is
+     already ripe when added.  */
+
+  /* Always consider the ordinary timers.  */
+  timers = Fcopy_sequence (Vtimer_list);
+  /* Consider the idle timers only if Emacs is idle.  */
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
+    idle_timers = Fcopy_sequence (Vtimer_idle_list);
+  else
+    idle_timers = Qnil;
+
+  Vinhibit_quit = tem;
+
+  GCPRO2 (timers, idle_timers);
 
   do
     {
-      nexttime = timer_check_2 ();
+      nexttime = timer_check_2 (timers, idle_timers);
     }
   while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0);
 
+  UNGCPRO;
   return nexttime;
 }
 
@@ -5434,7 +5362,7 @@ make_lispy_event (struct input_event *event)
                                  (sizeof (lispy_function_keys)
                                   / sizeof (lispy_function_keys[0])));
 
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
     case MULTIMEDIA_KEY_EVENT:
       if (event->code < (sizeof (lispy_multimedia_keys)
                          / sizeof (lispy_multimedia_keys[0]))
@@ -5449,7 +5377,6 @@ make_lispy_event (struct input_event *event)
       return Qnil;
 #endif
 
-#ifdef HAVE_MOUSE
       /* A mouse click.  Figure out where it is, decide whether it's
          a press, click or drag, and build the appropriate structure.  */
     case MOUSE_CLICK_EVENT:
@@ -5458,7 +5385,7 @@ make_lispy_event (struct input_event *event)
 #endif
       {
        int button = event->code;
-       int is_double;
+       bool is_double;
        Lisp_Object position;
        Lisp_Object *start_pos_ptr;
        Lisp_Object start_pos;
@@ -5739,7 +5666,7 @@ make_lispy_event (struct input_event *event)
          struct frame *fr;
          int fuzz;
          int symbol_num;
-         int is_double;
+         bool is_double;
 
          if (WINDOWP (event->frame_or_window))
            fr = XFRAME (XWINDOW (event->frame_or_window)->frame);
@@ -5901,7 +5828,6 @@ make_lispy_event (struct input_event *event)
                             Fcons (files,
                                    Qnil)));
       }
-#endif /* HAVE_MOUSE */
 
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
     || defined (HAVE_NS) || defined (USE_GTK)
@@ -6020,8 +5946,6 @@ make_lispy_event (struct input_event *event)
     }
 }
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
-
 static Lisp_Object
 make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
                     Lisp_Object x, Lisp_Object y, Time t)
@@ -6049,8 +5973,6 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
     }
 }
 
-#endif /* HAVE_MOUSE || HAVE GPM */
-
 /* Construct a switch frame event.  */
 static Lisp_Object
 make_lispy_switch_frame (Lisp_Object frame)
@@ -6681,11 +6603,11 @@ parse_solitary_modifier (Lisp_Object symbol)
   return 0;
 }
 
-/* Return 1 if EVENT is a list whose elements are all integers or symbols.
+/* Return true if EVENT is a list whose elements are all integers or symbols.
    Such a list is not valid as an event,
    but it can be a Lucid-style event type list.  */
 
-int
+bool
 lucid_event_type_list_p (Lisp_Object object)
 {
   Lisp_Object tail;
@@ -6710,8 +6632,10 @@ lucid_event_type_list_p (Lisp_Object object)
   return NILP (tail);
 }
 \f
-/* Store into *addr a value nonzero if terminal input chars are available.
-   Serves the purpose of ioctl (0, FIONREAD, addr)
+/* Return true if terminal input chars are available.
+   Also, store the return value into INPUT_PENDING.
+
+   Serves the purpose of ioctl (0, FIONREAD, ...)
    but works even if FIONREAD does not exist.
    (In fact, this may actually read some input.)
 
@@ -6722,54 +6646,21 @@ lucid_event_type_list_p (Lisp_Object object)
    If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
    movements and toolkit scroll bar thumb drags.  */
 
-static void
-get_input_pending (int *addr, int flags)
+static bool
+get_input_pending (int flags)
 {
   /* First of all, have we already counted some input?  */
-  *addr = (!NILP (Vquit_flag) || readable_events (flags));
+  input_pending = (!NILP (Vquit_flag) || readable_events (flags));
 
   /* If input is being read as it arrives, and we have none, there is none.  */
-  if (*addr > 0 || (interrupt_input && ! interrupts_deferred))
-    return;
-
-  /* Try to read some input and see how much we get.  */
-  gobble_input ();
-  *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)
+  if (!input_pending && (!interrupt_input || interrupts_deferred))
     {
-      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);
+      /* Try to read some input and see how much we get.  */
+      gobble_input ();
+      input_pending = (!NILP (Vquit_flag) || readable_events (flags));
     }
-  else
-#endif
-#endif
-    read_avail_input ();
+
+  return input_pending;
 }
 
 /* Put a BUFFER_SWITCH_EVENT in the buffer
@@ -6799,14 +6690,7 @@ record_asynch_buffer_change (void)
   /* 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
     {
@@ -6819,16 +6703,14 @@ record_asynch_buffer_change (void)
 /* 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;
+  bool err = 0;
   struct terminal *t;
 
   /* Store pending user signal events, if any.  */
@@ -6845,11 +6727,17 @@ read_avail_input (void)
           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.  */
@@ -6870,7 +6758,7 @@ read_avail_input (void)
                    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.  */
              {
@@ -7034,7 +6922,7 @@ tty_read_avail_input (struct terminal *terminal,
 #elif defined USG || defined CYGWIN
   /* Read some input if available, but don't wait.  */
   n_to_read = sizeof cbuf;
-  fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
+  fcntl (fileno (tty->input), F_SETFL, O_NONBLOCK);
 #else
 # error "Cannot read without possibly delaying"
 #endif
@@ -7068,7 +6956,7 @@ tty_read_avail_input (struct terminal *terminal,
     }
   while (
          /* We used to retry the read if it was interrupted.
-            But this does the wrong thing when O_NDELAY causes
+            But this does the wrong thing when O_NONBLOCK causes
             an EAGAIN error.  Does anybody know of a situation
             where a retry is actually needed?  */
 #if 0
@@ -7159,34 +7047,68 @@ tty_read_avail_input (struct terminal *terminal,
 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)
@@ -7196,25 +7118,10 @@ handle_input_available_signal (int sig)
 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.  */
 
@@ -7285,7 +7192,7 @@ handle_user_signal (int sig)
        p->npending++;
 #ifdef USABLE_SIGIO
        if (interrupt_input)
-         kill (getpid (), SIGIO);
+         handle_input_available_signal (sig);
        else
 #endif
          {
@@ -7301,7 +7208,7 @@ handle_user_signal (int sig)
 static void
 deliver_user_signal (int sig)
 {
-  handle_on_main_thread (sig, handle_user_signal);
+  deliver_process_signal (sig, handle_user_signal);
 }
 
 static char *
@@ -7326,8 +7233,6 @@ store_user_signal_events (void)
   for (p = user_signals; p; p = p->next)
     if (p->npending > 0)
       {
-       sigset_t blocked, procmask;
-
        if (! buf_initialized)
          {
            memset (&buf, 0, sizeof buf);
@@ -7336,10 +7241,6 @@ store_user_signal_events (void)
            buf_initialized = 1;
          }
 
-       sigemptyset (&blocked);
-       sigaddset (&blocked, p->sig);
-       pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
-
        do
          {
            buf.code = p->sig;
@@ -7347,8 +7248,6 @@ store_user_signal_events (void)
            p->npending--;
          }
        while (p->npending > 0);
-
-       pthread_sigmask (SIG_SETMASK, &procmask, 0);
       }
 }
 
@@ -7381,9 +7280,9 @@ static const char* separator_names[] = {
   0,
 };
 
-/* Return non-zero if LABEL specifies a separator.  */
+/* Return true if LABEL specifies a separator.  */
 
-int
+bool
 menu_separator_name_p (const char *label)
 {
   if (!label)
@@ -7558,6 +7457,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
 {
   struct gcpro gcpro1;
   int i;
+  bool parsed;
   Lisp_Object tem;
 
   if (EQ (item, Qundefined))
@@ -7589,9 +7489,9 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
      parse_menu_item, so that if it turns out it wasn't a menu item,
      it still correctly hides any further menu item.  */
   GCPRO1 (key);
-  i = parse_menu_item (item, 1);
+  parsed = parse_menu_item (item, 1);
   UNGCPRO;
-  if (!i)
+  if (!parsed)
     return;
 
   item = AREF (item_properties, ITEM_PROPERTY_DEF);
@@ -7667,7 +7567,7 @@ menu_item_eval_property (Lisp_Object sexpr)
    parse_menu_item returns true if the item is a menu item and false
    otherwise.  */
 
-int
+bool
 parse_menu_item (Lisp_Object item, int inmenubar)
 {
   Lisp_Object def, tem, item_string, start;
@@ -7967,7 +7867,7 @@ static Lisp_Object QCrtl;
 
 static void init_tool_bar_items (Lisp_Object);
 static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*);
-static int parse_tool_bar_item (Lisp_Object, Lisp_Object);
+static bool parse_tool_bar_item (Lisp_Object, Lisp_Object);
 static void append_tool_bar_item (void);
 
 
@@ -8092,7 +7992,7 @@ process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void
 
 /* Access slot with index IDX of vector tool_bar_item_properties.  */
 #define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
-static inline void
+static void
 set_prop (ptrdiff_t idx, Lisp_Object val)
 {
   ASET (tool_bar_item_properties, idx, val);
@@ -8100,7 +8000,7 @@ set_prop (ptrdiff_t idx, Lisp_Object val)
 
 
 /* Parse a tool bar item specification ITEM for key KEY and return the
-   result in tool_bar_item_properties.  Value is zero if ITEM is
+   result in tool_bar_item_properties.  Value is false if ITEM is
    invalid.
 
    ITEM is a list `(menu-item CAPTION BINDING PROPS...)'.
@@ -8145,12 +8045,13 @@ set_prop (ptrdiff_t idx, Lisp_Object val)
 
    A text label to show with the tool bar button if labels are enabled.  */
 
-static int
+static bool
 parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
 {
   Lisp_Object filter = Qnil;
   Lisp_Object caption;
-  int i, have_label = 0;
+  int i;
+  bool have_label = 0;
 
   /* Definition looks like `(menu-item CAPTION BINDING PROPS...)'.
      Rule out items that aren't lists, don't start with
@@ -8407,9 +8308,9 @@ append_tool_bar_item (void)
    PREV_EVENT is the previous input event, or nil if we are reading
    the first event of a key sequence.
 
-   If USED_MOUSE_MENU is non-null, then we set *USED_MOUSE_MENU to 1
-   if we used a mouse menu to read the input, or zero otherwise.  If
-   USED_MOUSE_MENU is null, we don't dereference it.
+   If USED_MOUSE_MENU is non-null, set *USED_MOUSE_MENU to true
+   if we used a mouse menu to read the input, or false otherwise.  If
+   USED_MOUSE_MENU is null, don't dereference it.
 
    The prompting is done based on the prompt-string of the map
    and the strings associated with various map elements.
@@ -8422,7 +8323,7 @@ append_tool_bar_item (void)
 
 static Lisp_Object
 read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
-                        Lisp_Object prev_event, int *used_mouse_menu)
+                        Lisp_Object prev_event, bool *used_mouse_menu)
 {
 #ifdef HAVE_MENUS
   ptrdiff_t mapno;
@@ -8516,7 +8417,7 @@ read_char_minibuf_menu_prompt (int commandflag,
   /* FIXME: Use the minibuffer's frame width.  */
   ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
   ptrdiff_t idx = -1;
-  int nobindings = 1;
+  bool nobindings = 1;
   Lisp_Object rest, vector;
   char *menu;
 
@@ -8564,7 +8465,7 @@ read_char_minibuf_menu_prompt (int commandflag,
   /* Present the documented bindings, a line at a time.  */
   while (1)
     {
-      int notfirst = 0;
+      bool notfirst = 0;
       ptrdiff_t i = nlength;
       Lisp_Object obj;
       Lisp_Object orig_defn_macro;
@@ -8620,8 +8521,8 @@ read_char_minibuf_menu_prompt (int commandflag,
              /* Ignore the element if it has no prompt string.  */
              if (INTEGERP (event) && parse_menu_item (elt, -1))
                {
-                 /* 1 if the char to type matches the string.  */
-                 int char_matches;
+                 /* True if the char to type matches the string.  */
+                 bool char_matches;
                  Lisp_Object upcased_event, downcased_event;
                  Lisp_Object desc = Qnil;
                  Lisp_Object s
@@ -8673,7 +8574,7 @@ read_char_minibuf_menu_prompt (int commandflag,
                          i += 2;
                        }
                      notfirst = 1;
-                     nobindings = 0 ;
+                     nobindings = 0;
 
                      /* If the char to type doesn't match the string's
                         first char, explicitly show what char to type.  */
@@ -8807,14 +8708,14 @@ typedef struct keyremap
 
 /* Lookup KEY in MAP.
    MAP is a keymap mapping keys to key vectors or functions.
-   If the mapping is a function and DO_FUNCTION is non-zero, then
+   If the mapping is a function and DO_FUNCALL is true,
    the function is called with PROMPT as parameter and its return
    value is used as the return value of this function (after checking
    that it is indeed a vector).  */
 
 static Lisp_Object
 access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
-                       int do_funcall)
+                       bool do_funcall)
 {
   Lisp_Object next;
 
@@ -8853,15 +8754,15 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
    BUFSIZE is its maximum size.
    FKEY is a pointer to the keyremap structure to use.
    INPUT is the index of the last element in KEYBUF.
-   DOIT if non-zero says that the remapping can actually take place.
+   DOIT if true says that the remapping can actually take place.
    DIFF is used to return the number of keys added/removed by the remapping.
    PARENT is the root of the keymap.
    PROMPT is the prompt to use if the remapping happens through a function.
-   The return value is non-zero if the remapping actually took place.  */
+   Return true if the remapping actually took place.  */
 
-static int
+static bool
 keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
-              int input, int doit, int *diff, Lisp_Object prompt)
+              int input, bool doit, int *diff, Lisp_Object prompt)
 {
   Lisp_Object next, key;
 
@@ -8915,7 +8816,7 @@ keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
   return 0;
 }
 
-static int
+static bool
 test_undefined (Lisp_Object binding)
 {
   return (EQ (binding, Qundefined)
@@ -8957,13 +8858,13 @@ test_undefined (Lisp_Object binding)
    off the switch-frame event until later; the next call to
    read_char will return it.
 
-   If FIX_CURRENT_BUFFER is nonzero, we restore current_buffer
+   If FIX_CURRENT_BUFFER, we restore current_buffer
    from the selected window's buffer.  */
 
 static int
 read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
-                  int dont_downcase_last, int can_return_switch_frame,
-                  int fix_current_buffer)
+                  bool dont_downcase_last, bool can_return_switch_frame,
+                  bool fix_current_buffer)
 {
   Lisp_Object from_string;
   ptrdiff_t count = SPECPDL_INDEX ();
@@ -8996,7 +8897,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
      key sequence.  */
   Lisp_Object orig_keymap;
 
-  /* 1 if we have already considered switching to the local-map property
+  /* Positive if we have already considered switching to the local-map property
      of the place where a mouse click occurred.  */
   int localized_local_map = 0;
 
@@ -9036,10 +8937,10 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
   /* Likewise, for key_translation_map and input-decode-map.  */
   keyremap keytran, indec;
 
-  /* Non-zero if we are trying to map a key by changing an upper-case
+  /* True if we are trying to map a key by changing an upper-case
      letter to lower case, or a shifted function key to an unshifted
      one.  */
-  int shift_translated = 0;
+  bool shift_translated = 0;
 
   /* If we receive a `switch-frame' or `select-window' event in the middle of
      a key sequence, we put it off for later.
@@ -9055,7 +8956,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
   int original_uppercase_position = -1;
 
   /* Gets around Microsoft compiler limitations.  */
-  int dummyflag = 0;
+  bool dummyflag = 0;
 
   struct buffer *starting_buffer;
 
@@ -9217,7 +9118,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
         : (/* indec.start < t || fkey.start < t || */ keytran.start < t))
     {
       Lisp_Object key;
-      int used_mouse_menu = 0;
+      bool used_mouse_menu = 0;
 
       /* Where the last real key started.  If we need to throw away a
          key that has expanded into more than one element of keybuf
@@ -9311,7 +9212,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                   return.  Any better way to fix this? -- cyd  */
                || (interrupted_kboard != current_kboard))
              {
-               int found = 0;
+               bool found = 0;
                struct kboard *k;
 
                for (k = all_kboards; k; k = k->next_kboard)
@@ -9865,7 +9766,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
       while (indec.end < t)
        {
          struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-         int done, diff;
+         bool done;
+         int diff;
 
          GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame);
          done = keyremap_step (keybuf, bufsize, &indec, max (t, mock_input),
@@ -9899,7 +9801,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
        while (fkey.end < indec.start)
          {
            struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-           int done, diff;
+           bool done;
+           int diff;
 
            GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame);
            done = keyremap_step (keybuf, bufsize, &fkey,
@@ -9928,7 +9831,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
       while (keytran.end < fkey.start)
        {
          struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-         int done, diff;
+         bool done;
+         int diff;
 
          GCPRO4 (indec.map, fkey.map, keytran.map, delayed_switch_frame);
          done = keyremap_step (keybuf, bufsize, &keytran, max (t, mock_input),
@@ -10314,38 +10218,32 @@ a special event, so ignore the prefix argument and don't clear it.  */)
 
 
 \f
-/* Return nonzero if input events are pending.  */
+/* Return true if input events are pending.  */
 
-int
+bool
 detect_input_pending (void)
 {
-  if (!input_pending)
-    get_input_pending (&input_pending, 0);
-
-  return input_pending;
+  return input_pending || get_input_pending (0);
 }
 
-/* Return nonzero if input events other than mouse movements are
+/* Return true if input events other than mouse movements are
    pending.  */
 
-int
+bool
 detect_input_pending_ignore_squeezables (void)
 {
-  if (!input_pending)
-    get_input_pending (&input_pending, READABLE_EVENTS_IGNORE_SQUEEZABLES);
-
-  return input_pending;
+  return input_pending || get_input_pending (READABLE_EVENTS_IGNORE_SQUEEZABLES);
 }
 
-/* Return nonzero if input events are pending, and run any pending timers.  */
+/* Return true if input events are pending, and run any pending timers.  */
 
-int
-detect_input_pending_run_timers (int do_display)
+bool
+detect_input_pending_run_timers (bool do_display)
 {
-  int old_timers_run = timers_run;
+  unsigned old_timers_run = timers_run;
 
   if (!input_pending)
-    get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
+    get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
 
   if (old_timers_run != timers_run && do_display)
     {
@@ -10376,13 +10274,13 @@ clear_input_pending (void)
   input_pending = 0;
 }
 
-/* Return nonzero if there are pending requeued events.
+/* Return true if there are pending requeued events.
    This isn't used yet.  The hope is to make wait_reading_process_output
    call it, and return if it runs Lisp code that unreads something.
    The problem is, kbd_buffer_get_event needs to be fixed to know what
    to do in that case.  It isn't trivial.  */
 
-int
+bool
 requeued_events_pending_p (void)
 {
   return (!NILP (Vunread_command_events));
@@ -10403,10 +10301,9 @@ if there is a doubt, the value is t.  */)
   /* Process non-user-visible events (Bug#10195).  */
   process_special_events ();
 
-  get_input_pending (&input_pending,
-                    READABLE_EVENTS_DO_TIMERS_NOW
-                    | READABLE_EVENTS_FILTER_EVENTS);
-  return input_pending > 0 ? Qt : Qnil;
+  return (get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW
+                            | READABLE_EVENTS_FILTER_EVENTS)
+         ? Qt : Qnil);
 }
 
 DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0,
@@ -10553,9 +10450,9 @@ The file will be closed when Emacs exits.  */)
 {
   if (dribble)
     {
-      BLOCK_INPUT;
+      block_input ();
       fclose (dribble);
-      UNBLOCK_INPUT;
+      unblock_input ();
       dribble = 0;
     }
   if (!NILP (file))
@@ -10744,21 +10641,21 @@ handle_interrupt_signal (int sig)
          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.
 
@@ -10772,7 +10669,7 @@ static int force_quit_count;
    non-nil, it stops the job right away.  */
 
 static void
-handle_interrupt (void)
+handle_interrupt (bool in_signal_handler)
 {
   char c;
 
@@ -10781,13 +10678,16 @@ handle_interrupt (void)
   /* 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 ();
@@ -10858,7 +10758,6 @@ handle_interrupt (void)
 #endif /* not MSDOS */
       fflush (stdout);
       init_all_sys_modes ();
-      pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
     }
   else
     {
@@ -10876,15 +10775,14 @@ handle_interrupt (void)
          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;
@@ -10893,6 +10791,8 @@ handle_interrupt (void)
         }
     }
 
+  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
@@ -10902,36 +10802,26 @@ handle_interrupt (void)
          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
 }
 
 /* Handle a C-g by making read_char return C-g.  */
 
 static void
-quit_throw_to_read_char (int from_signal)
+quit_throw_to_read_char (bool from_signal)
 {
   /* When not called from a signal handler it is safe to call
      Lisp.  */
   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),
@@ -10949,7 +10839,7 @@ otherwise Emacs uses CBREAK mode.
 See also `current-input-mode'.  */)
   (Lisp_Object interrupt)
 {
-  int new_interrupt_input;
+  bool new_interrupt_input;
 #ifdef USABLE_SIGIO
 #ifdef HAVE_X_WINDOWS
   if (x_display_list != NULL)
@@ -11317,12 +11207,9 @@ init_keyboard (void)
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;
   kbd_store_ptr = kbd_buffer;
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   do_mouse_tracking = Qnil;
-#endif
   input_pending = 0;
   interrupt_input_blocked = 0;
-  interrupt_input_pending = 0;
   pending_signals = 0;
 
   /* This means that command_loop_1 won't try to select anything the first
@@ -11343,7 +11230,7 @@ init_keyboard (void)
       /* 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;
@@ -11446,7 +11333,7 @@ syms_of_keyboard (void)
   DEFSYM (Qconfig_changed_event, "config-changed-event");
   DEFSYM (Qmenu_enable, "menu-enable");
 
-#if defined (WINDOWSNT)
+#ifdef HAVE_NTGUI
   DEFSYM (Qlanguage_change, "language-change");
 #endif
 
@@ -11471,9 +11358,7 @@ syms_of_keyboard (void)
   DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
   DEFSYM (Qmenu_bar, "menu-bar");
 
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
-#endif
 
   DEFSYM (Qabove_handle, "above-handle");
   DEFSYM (Qhandle, "handle");
@@ -11593,9 +11478,7 @@ syms_of_keyboard (void)
   defsubr (&Sread_key_sequence);
   defsubr (&Sread_key_sequence_vector);
   defsubr (&Srecursive_edit);
-#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
   defsubr (&Strack_mouse);
-#endif
   defsubr (&Sinput_pending_p);
   defsubr (&Scommand_execute);
   defsubr (&Srecent_keys);
@@ -12258,14 +12141,15 @@ mark_kboards (void)
       {
        if (event == kbd_buffer + KBD_BUFFER_SIZE)
          event = kbd_buffer;
+       /* These two special event types has no Lisp_Objects to mark.  */
        if (event->kind != SELECTION_REQUEST_EVENT
            && event->kind != SELECTION_CLEAR_EVENT)
          {
            mark_object (event->x);
            mark_object (event->y);
+           mark_object (event->frame_or_window);
+           mark_object (event->arg);
          }
-       mark_object (event->frame_or_window);
-       mark_object (event->arg);
       }
   }
 }