]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
Auto-commit of generated files.
[gnu-emacs] / src / keyboard.c
index 9faa3770cf3f8a9eb63a751fdcd5f5029d9ba160..0ff4cda034ac6e0a1e52f76df24f0b95e05e71ea 100644 (file)
@@ -20,9 +20,6 @@ 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 "sysstdio.h"
 
 #include "lisp.h"
@@ -85,7 +82,7 @@ volatile bool pending_signals;
 
 KBOARD *initial_kboard;
 KBOARD *current_kboard;
-KBOARD *all_kboards;
+static KBOARD *all_kboards;
 
 /* True in the single-kboard state, false in the any-kboard state.  */
 static bool single_kboard;
@@ -221,10 +218,6 @@ static ptrdiff_t last_point_position;
    'volatile' here.  */
 Lisp_Object internal_last_event_frame;
 
-/* The timestamp of the last input event we received from the X server.
-   X Windows wants this for selection ownership.  */
-Time last_event_timestamp;
-
 static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
 static Lisp_Object Qhandle_select_window;
 Lisp_Object QPRIMARY;
@@ -292,7 +285,7 @@ static struct input_event * volatile kbd_store_ptr;
    at inopportune times.  */
 
 /* Symbols to head events.  */
-Lisp_Object Qmouse_movement;
+static Lisp_Object Qmouse_movement;
 static Lisp_Object Qscroll_bar_movement;
 Lisp_Object Qswitch_frame;
 static Lisp_Object Qfocus_in, Qfocus_out;
@@ -1699,7 +1692,6 @@ command_loop_1 (void)
 Lisp_Object
 read_menu_command (void)
 {
-  Lisp_Object cmd;
   Lisp_Object keybuf[30];
   ptrdiff_t count = SPECPDL_INDEX ();
   int i;
@@ -2105,6 +2097,9 @@ bind_polling_period (int n)
 \f
 /* Apply the control modifier to CHARACTER.  */
 
+#ifndef WINDOWSNT
+static
+#endif
 int
 make_ctrl_char (int c)
 {
@@ -2624,10 +2619,8 @@ read_char (int commandflag, Lisp_Object map,
 
   if (/* There currently is something in the echo area.  */
       !NILP (echo_area_buffer[0])
-      && (/* And it's either not from echoing.  */
-         !EQ (echo_area_buffer[0], echo_message_buffer)
-         /* Or it's an echo from a different kboard.  */
-         || echo_kboard != current_kboard
+      && (/* It's an echo from a different kboard.  */
+         echo_kboard != current_kboard
          /* Or we explicitly allow overwriting whatever there is.  */
          || ok_to_echo_at_next_pause == NULL))
     cancel_echoing ();
@@ -3638,8 +3631,6 @@ kbd_buffer_store_event_hold (register struct input_event *event,
            Vlast_event_frame = focus;
          }
 
-         last_event_timestamp = event->timestamp;
-
          handle_interrupt (0);
          return;
        }
@@ -3905,13 +3896,17 @@ kbd_buffer_get_event (KBOARD **kbp,
       else
        {
          bool do_display = true;
-         struct tty_display_info *tty = CURTTY ();
 
-         /* When this TTY is displaying a menu, we must prevent any
-            redisplay, because we modify the frame's glyph matrix
-            behind the back of the display engine.  */
-         if (tty->showing_menu)
-           do_display = false;
+         if (FRAME_TERMCAP_P (SELECTED_FRAME ()))
+           {
+             struct tty_display_info *tty = CURTTY ();
+
+             /* When this TTY is displaying a menu, we must prevent
+                any redisplay, because we modify the frame's glyph
+                matrix behind the back of the display engine.  */
+             if (tty->showing_menu)
+               do_display = false;
+           }
 
          wait_reading_process_output (0, 0, -1, do_display, Qnil, NULL, 0);
        }
@@ -3940,8 +3935,6 @@ kbd_buffer_get_event (KBOARD **kbp,
               ? kbd_fetch_ptr
               : kbd_buffer);
 
-      last_event_timestamp = event->timestamp;
-
       *kbp = event_to_kboard (event);
       if (*kbp == 0)
        *kbp = current_kboard;  /* Better than returning null ptr?  */
@@ -4303,8 +4296,6 @@ process_special_events (void)
          else
            kbd_fetch_ptr++;
 
-         /* X wants last_event_timestamp for selection ownership.  */
-         last_event_timestamp = copy.timestamp;
          input_pending = readable_events (0);
          x_handle_selection_event (&copy);
 #else
@@ -4385,7 +4376,7 @@ decode_timer (Lisp_Object timer, struct timespec *result)
 
   if (! (VECTORP (timer) && ASIZE (timer) == 9))
     return 0;
-  vector = XVECTOR (timer)->contents;
+  vector = XVECTOR (timer)->u.contents;
   if (! NILP (vector[0]))
     return 0;
 
@@ -5407,6 +5398,20 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
                                     extra_info))));
 }
 
+/* Return non-zero if F is a GUI frame that uses some toolkit-managed
+   menu bar.  This really means that Emacs draws and manages the menu
+   bar as part of its normal display, and therefore can compute its
+   geometry.  */
+static bool
+toolkit_menubar_in_use (struct frame *f)
+{
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
+  return !(!FRAME_WINDOW_P (f));
+#else
+  return false;
+#endif
+}
+
 /* Given a struct input_event, build the lisp event which represents
    it.  If EVENT is 0, build a mouse movement event from the mouse
    movement buffer, which should have a movement event in it.
@@ -5542,6 +5547,9 @@ make_lispy_event (struct input_event *event)
       /* A mouse click.  Figure out where it is, decide whether it's
          a press, click or drag, and build the appropriate structure.  */
     case MOUSE_CLICK_EVENT:
+#ifdef HAVE_GPM
+    case GPM_CLICK_EVENT:
+#endif
 #ifndef USE_TOOLKIT_SCROLL_BARS
     case SCROLL_BAR_CLICK_EVENT:
 #endif
@@ -5555,67 +5563,71 @@ make_lispy_event (struct input_event *event)
        position = Qnil;
 
        /* Build the position as appropriate for this mouse click.  */
-       if (event->kind == MOUSE_CLICK_EVENT)
+       if (event->kind == MOUSE_CLICK_EVENT
+#ifdef HAVE_GPM
+           || event->kind == GPM_CLICK_EVENT
+#endif
+           )
          {
            struct frame *f = XFRAME (event->frame_or_window);
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) && ! defined (HAVE_NS)
            int row, column;
-#endif
 
            /* Ignore mouse events that were made on frame that
               have been deleted.  */
            if (! FRAME_LIVE_P (f))
              return Qnil;
 
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) && ! defined (HAVE_NS)
            /* EVENT->x and EVENT->y are frame-relative pixel
               coordinates at this place.  Under old redisplay, COLUMN
               and ROW are set to frame relative glyph coordinates
               which are then used to determine whether this click is
               in a menu (non-toolkit version).  */
-           pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
-                                  &column, &row, NULL, 1);
-
-           /* In the non-toolkit version, clicks on the menu bar
-              are ordinary button events in the event buffer.
-              Distinguish them, and invoke the menu.
-
-              (In the toolkit version, the toolkit handles the menu bar
-              and Emacs doesn't know about it until after the user
-              makes a selection.)  */
-           if (row >= 0 && row < FRAME_MENU_BAR_LINES (f)
-               && (event->modifiers & down_modifier))
+           if (!toolkit_menubar_in_use (f))
              {
-               Lisp_Object items, item;
-
-               /* Find the menu bar item under `column'.  */
-               item = Qnil;
-               items = FRAME_MENU_BAR_ITEMS (f);
-               for (i = 0; i < ASIZE (items); i += 4)
+               pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
+                                      &column, &row, NULL, 1);
+
+               /* In the non-toolkit version, clicks on the menu bar
+                  are ordinary button events in the event buffer.
+                  Distinguish them, and invoke the menu.
+
+                  (In the toolkit version, the toolkit handles the
+                  menu bar and Emacs doesn't know about it until
+                  after the user makes a selection.)  */
+               if (row >= 0 && row < FRAME_MENU_BAR_LINES (f)
+                 && (event->modifiers & down_modifier))
                  {
-                   Lisp_Object pos, string;
-                   string = AREF (items, i + 1);
-                   pos = AREF (items, i + 3);
-                   if (NILP (string))
-                     break;
-                   if (column >= XINT (pos)
-                       && column < XINT (pos) + SCHARS (string))
+                   Lisp_Object items, item;
+
+                   /* Find the menu bar item under `column'.  */
+                   item = Qnil;
+                   items = FRAME_MENU_BAR_ITEMS (f);
+                   for (i = 0; i < ASIZE (items); i += 4)
                      {
-                       item = AREF (items, i);
-                       break;
+                       Lisp_Object pos, string;
+                       string = AREF (items, i + 1);
+                       pos = AREF (items, i + 3);
+                       if (NILP (string))
+                         break;
+                       if (column >= XINT (pos)
+                           && column < XINT (pos) + SCHARS (string))
+                         {
+                           item = AREF (items, i);
+                           break;
+                         }
                      }
-                 }
 
-               /* ELisp manual 2.4b says (x y) are window relative but
-                  code says they are frame-relative.  */
-               position = list4 (event->frame_or_window,
-                                 Qmenu_bar,
-                                 Fcons (event->x, event->y),
-                                 make_number (event->timestamp));
+                   /* ELisp manual 2.4b says (x y) are window
+                      relative but code says they are
+                      frame-relative.  */
+                   position = list4 (event->frame_or_window,
+                                     Qmenu_bar,
+                                     Fcons (event->x, event->y),
+                                     make_number (event->timestamp));
 
-               return list2 (item, position);
+                   return list2 (item, position);
+                 }
              }
-#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */
 
            position = make_lispy_position (f, event->x, event->y,
                                            event->timestamp);
@@ -6020,55 +6032,6 @@ make_lispy_event (struct input_event *event)
     case CONFIG_CHANGED_EVENT:
        return list3 (Qconfig_changed_event,
                      event->arg, event->frame_or_window);
-#ifdef HAVE_GPM
-    case GPM_CLICK_EVENT:
-      {
-       struct frame *f = XFRAME (event->frame_or_window);
-       Lisp_Object head, position;
-       Lisp_Object *start_pos_ptr;
-       Lisp_Object start_pos;
-       int button = event->code;
-
-       if (button >= ASIZE (button_down_location))
-         {
-           ptrdiff_t incr = button - ASIZE (button_down_location) + 1;
-           button_down_location = larger_vector (button_down_location,
-                                                 incr, -1);
-           mouse_syms = larger_vector (mouse_syms, incr, -1);
-         }
-
-       start_pos_ptr = aref_addr (button_down_location, button);
-       start_pos = *start_pos_ptr;
-
-       position = make_lispy_position (f, event->x, event->y,
-                                       event->timestamp);
-
-       if (event->modifiers & down_modifier)
-         *start_pos_ptr = Fcopy_alist (position);
-       else if (event->modifiers & (up_modifier | drag_modifier))
-         {
-           if (!CONSP (start_pos))
-             return Qnil;
-           event->modifiers &= ~up_modifier;
-         }
-
-       head = modify_event_symbol (button,
-                                   event->modifiers,
-                                   Qmouse_click, Vlispy_mouse_stem,
-                                   NULL,
-                                   &mouse_syms,
-                                   ASIZE (mouse_syms));
-
-       if (event->modifiers & drag_modifier)
-         return list3 (head, start_pos, position);
-       else if (event->modifiers & double_modifier)
-         return list3 (head, position, make_number (2));
-       else if (event->modifiers & triple_modifier)
-         return list3 (head, position, make_number (3));
-       else
-         return list2 (head, position);
-       }
-#endif /* HAVE_GPM */
 
       /* The 'kind' field of the event is something we don't recognize.  */
     default:
@@ -7134,7 +7097,8 @@ process_pending_signals (void)
 }
 
 /* Undo any number of BLOCK_INPUT calls down to level LEVEL,
-   and also (if the level is now 0) reinvoke any pending signal.  */
+   and reinvoke any pending signal if the level is now 0 and
+   a fatal error is not already in progress.  */
 
 void
 unblock_input_to (int level)
@@ -7142,7 +7106,7 @@ unblock_input_to (int level)
   interrupt_input_blocked = level;
   if (level == 0)
     {
-      if (pending_signals)
+      if (pending_signals && !fatal_error_in_progress)
        process_pending_signals ();
     }
   else if (level < 0)
@@ -8042,7 +8006,7 @@ process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void
         discard any previously made item.  */
       for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)
        {
-         Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;
+         Lisp_Object *v = XVECTOR (tool_bar_items_vector)->u.contents + i;
 
          if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
            {
@@ -8366,7 +8330,7 @@ append_tool_bar_item (void)
   /* Append entries from tool_bar_item_properties to the end of
      tool_bar_items_vector.  */
   vcopy (tool_bar_items_vector, ntool_bar_items,
-        XVECTOR (tool_bar_item_properties)->contents, TOOL_BAR_ITEM_NSLOTS);
+        XVECTOR (tool_bar_item_properties)->u.contents, TOOL_BAR_ITEM_NSLOTS);
   ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
 }
 
@@ -9917,20 +9881,7 @@ detect_input_pending_run_timers (bool do_display)
     get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
 
   if (old_timers_run != timers_run && do_display)
-    {
-      redisplay_preserve_echo_area (8);
-      /* The following fixes a bug when using lazy-lock with
-        lazy-lock-defer-on-the-fly set to t, i.e.  when fontifying
-        from an idle timer function.  The symptom of the bug is that
-        the cursor sometimes doesn't become visible until the next X
-        event is processed.  --gerd.  */
-      {
-        Lisp_Object tail, frame;
-        FOR_EACH_FRAME (tail, frame)
-          if (FRAME_RIF (XFRAME (frame)))
-            FRAME_RIF (XFRAME (frame))->flush_display (XFRAME (frame));
-      }
-    }
+    redisplay_preserve_echo_area (8);
 
   return input_pending;
 }
@@ -9957,12 +9908,13 @@ requeued_events_pending_p (void)
   return (!NILP (Vunread_command_events));
 }
 
-
-DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 0,
+DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 1, 0,
        doc: /* Return t if command input is currently available with no wait.
 Actually, the value is nil only if we can be sure that no input is available;
-if there is a doubt, the value is t.  */)
-  (void)
+if there is a doubt, the value is t.
+
+If CHECK-TIMERS is non-nil, timers that are ready to run will do so.  */)
+  (Lisp_Object check_timers)
 {
   if (!NILP (Vunread_command_events)
       || !NILP (Vunread_post_input_method_events)
@@ -9972,7 +9924,8 @@ if there is a doubt, the value is t.  */)
   /* Process non-user-visible events (Bug#10195).  */
   process_special_events ();
 
-  return (get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW
+  return (get_input_pending ((NILP (check_timers)
+                              ? 0 : READABLE_EVENTS_DO_TIMERS_NOW)
                             | READABLE_EVENTS_FILTER_EVENTS)
          ? Qt : Qnil);
 }
@@ -9981,7 +9934,7 @@ DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0,
        doc: /* Return vector of last 300 events, not counting those from keyboard macros.  */)
   (void)
 {
-  Lisp_Object *keys = XVECTOR (recent_keys)->contents;
+  Lisp_Object *keys = XVECTOR (recent_keys)->u.contents;
   Lisp_Object val;
 
   if (total_keys < NUM_RECENT_KEYS)
@@ -10007,7 +9960,7 @@ See also `this-command-keys-vector'.  */)
   (void)
 {
   return make_event_array (this_command_key_count,
-                          XVECTOR (this_command_keys)->contents);
+                          XVECTOR (this_command_keys)->u.contents);
 }
 
 DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0,
@@ -10019,7 +9972,7 @@ See also `this-command-keys'.  */)
   (void)
 {
   return Fvector (this_command_key_count,
-                 XVECTOR (this_command_keys)->contents);
+                 XVECTOR (this_command_keys)->u.contents);
 }
 
 DEFUN ("this-single-command-keys", Fthis_single_command_keys,
@@ -10034,7 +9987,7 @@ The value is always a vector.  */)
 {
   return Fvector (this_command_key_count
                  - this_single_command_key_start,
-                 (XVECTOR (this_command_keys)->contents
+                 (XVECTOR (this_command_keys)->u.contents
                   + this_single_command_key_start));
 }
 
@@ -10048,8 +10001,7 @@ shows the events before all translations (except for input methods).
 The value is always a vector.  */)
   (void)
 {
-  return Fvector (raw_keybuf_count,
-                 (XVECTOR (raw_keybuf)->contents));
+  return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->u.contents);
 }
 
 DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
@@ -10791,12 +10743,11 @@ The `posn-' functions access elements of such lists.  */)
   return tem;
 }
 
-\f
-/*
- * Set up a new kboard object with reasonable initial values.
- */
-void
-init_kboard (KBOARD *kb)
+/* Set up a new kboard object with reasonable initial values.
+   TYPE is a window system for which this keyboard is used.  */
+
+static void
+init_kboard (KBOARD *kb, Lisp_Object type)
 {
   kset_overriding_terminal_local_map (kb, Qnil);
   kset_last_command (kb, Qnil);
@@ -10817,13 +10768,27 @@ init_kboard (KBOARD *kb)
   kb->reference_count = 0;
   kset_system_key_alist (kb, Qnil);
   kset_system_key_syms (kb, Qnil);
-  kset_window_system (kb, Qt); /* Unset.  */
+  kset_window_system (kb, type);
   kset_input_decode_map (kb, Fmake_sparse_keymap (Qnil));
   kset_local_function_key_map (kb, Fmake_sparse_keymap (Qnil));
   Fset_keymap_parent (KVAR (kb, Vlocal_function_key_map), Vfunction_key_map);
   kset_default_minibuffer_frame (kb, Qnil);
 }
 
+/* Allocate and basically initialize keyboard
+   object to use with window system TYPE.  */
+
+KBOARD *
+allocate_kboard (Lisp_Object type)
+{
+  KBOARD *kb = xmalloc (sizeof *kb);
+
+  init_kboard (kb, type);
+  kb->next_kboard = all_kboards;
+  all_kboards = kb;
+  return kb;
+}
+
 /*
  * Destroy the contents of a kboard object, but not the object itself.
  * We use this just before deleting it, or if we're going to initialize
@@ -10888,10 +10853,9 @@ init_keyboard (void)
   current_kboard = initial_kboard;
   /* Re-initialize the keyboard again.  */
   wipe_kboard (current_kboard);
-  init_kboard (current_kboard);
   /* A value of nil for Vwindow_system normally means a tty, but we also use
      it for the initial terminal since there is no window system there.  */
-  kset_window_system (current_kboard, Qnil);
+  init_kboard (current_kboard, Qnil);
 
   if (!noninteractive)
     {
@@ -11696,12 +11660,8 @@ Currently, the only supported values for this
 variable are `sigusr1' and `sigusr2'.  */);
   Vdebug_on_event = intern_c_string ("sigusr2");
 
-  /* Create the initial keyboard.  */
-  initial_kboard = xmalloc (sizeof *initial_kboard);
-  init_kboard (initial_kboard);
-  /* Vwindow_system is left at t for now.  */
-  initial_kboard->next_kboard = all_kboards;
-  all_kboards = initial_kboard;
+  /* Create the initial keyboard.  Qt means 'unset'.  */
+  initial_kboard = allocate_kboard (Qt);
 }
 
 void