]> code.delx.au - gnu-emacs/blobdiff - src/keyboard.c
Implement tool-bar separators for non-GTK tool-bars.
[gnu-emacs] / src / keyboard.c
index 001ae9f7cef5ce975ebd00c678814c866d30fa50..27c311d72e20f0a422078640be688a25390cb490 100644 (file)
@@ -42,7 +42,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "puresize.h"
 #include "systime.h"
 #include "atimer.h"
-#include <setjmp.h>
+#include "process.h"
 #include <errno.h>
 
 #ifdef HAVE_GTK_AND_PTHREAD
@@ -62,9 +62,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <unistd.h>
 #endif
 
-#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
-#endif
 
 /* This is to get the definitions of the XK_ symbols.  */
 #ifdef HAVE_X_WINDOWS
@@ -146,10 +144,6 @@ int this_single_command_key_start;
 static int before_command_key_count;
 static int before_command_echo_length;
 
-extern int minbuf_level;
-
-extern int message_enable_multibyte;
-
 /* If non-nil, the function that implements the display of help.
    It's called with one argument, the help string to display.  */
 
@@ -218,6 +212,12 @@ Lisp_Object Vprefix_help_command;
 /* List of items that should move to the end of the menu bar.  */
 Lisp_Object Vmenu_bar_final_items;
 
+/* Expression to evaluate for the tool bar separator image.
+   This is used for build_desired_tool_bar_string only.  For GTK, we
+   use GTK tool bar seperators.  */
+
+Lisp_Object Vtool_bar_separator_image_expression;
+
 /* Non-nil means show the equivalent key-binding for
    any M-x command that has one.
    The value can be a length of time to show the message for.
@@ -246,9 +246,6 @@ Lisp_Object Vminibuffer_message_timeout;
    ASCII character.  */
 int quit_char;
 
-extern Lisp_Object current_global_map;
-extern int minibuf_level;
-
 /* If non-nil, this is a map that overrides all other local maps.  */
 Lisp_Object Voverriding_local_map;
 
@@ -307,7 +304,7 @@ EMACS_INT extra_keyboard_modifiers;
 Lisp_Object meta_prefix_char;
 
 /* Last size recorded for a current buffer which is not a minibuffer.  */
-static int last_non_minibuf_size;
+static EMACS_INT last_non_minibuf_size;
 
 /* Number of idle seconds before an auto-save and garbage collection.  */
 static Lisp_Object Vauto_save_timeout;
@@ -340,7 +337,7 @@ Lisp_Object real_this_command;
 Lisp_Object Vthis_original_command;
 
 /* The value of point when the last command was started.  */
-int last_point_position;
+EMACS_INT last_point_position;
 
 /* The buffer that was current when the last command was started.  */
 Lisp_Object last_point_position_buffer;
@@ -364,6 +361,15 @@ Lisp_Object Vlast_event_frame;
    X Windows wants this for selection ownership.  */
 unsigned long last_event_timestamp;
 
+/* If non-nil, active regions automatically become the window selection.  */
+Lisp_Object Vselect_active_regions;
+
+/* The text in the active region prior to modifying the buffer.
+   Used by the `select-active-regions' feature.  */
+Lisp_Object Vsaved_region_selection;
+
+Lisp_Object Qx_set_selection, QPRIMARY, Qhandle_switch_frame;
+
 Lisp_Object Qself_insert_command;
 Lisp_Object Qforward_char;
 Lisp_Object Qbackward_char;
@@ -427,8 +433,6 @@ FILE *dribble;
 /* Nonzero if input is available.  */
 int input_pending;
 
-extern char *pending_malloc_warning;
-
 /* Circular buffer for pre-read keyboard input.  */
 
 static struct input_event kbd_buffer[KBD_BUFFER_SIZE];
@@ -468,8 +472,6 @@ Lisp_Object Qmake_frame_visible;
 Lisp_Object Qselect_window;
 Lisp_Object Qhelp_echo;
 
-extern Lisp_Object Qremap;
-
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
 Lisp_Object Qmouse_fixup_help_message;
 #endif
@@ -493,11 +495,10 @@ Lisp_Object Qconfig_changed_event;
 Lisp_Object Qevent_kind;
 Lisp_Object Qevent_symbol_elements;
 
-/* menu item parts */
+/* menu and tool bar item parts */
 Lisp_Object Qmenu_enable;
 Lisp_Object QCenable, QCvisible, QChelp, QCfilter, QCkeys, QCkey_sequence;
-Lisp_Object QCbutton, QCtoggle, QCradio, QClabel;
-extern Lisp_Object Qmenu_item;
+Lisp_Object QCbutton, QCtoggle, QCradio, QClabel, QCvert_only;
 
 /* An event header symbol HEAD may have a property named
    Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS);
@@ -517,17 +518,12 @@ Lisp_Object Qmode_line;
 Lisp_Object Qvertical_line;
 Lisp_Object Qvertical_scroll_bar;
 Lisp_Object Qmenu_bar;
-extern Lisp_Object Qleft_margin, Qright_margin;
-extern Lisp_Object Qleft_fringe, Qright_fringe;
-extern Lisp_Object QCmap;
 
 Lisp_Object recursive_edit_unwind (Lisp_Object buffer), command_loop (void);
 Lisp_Object Fthis_command_keys (void);
 Lisp_Object Qextended_command_history;
 EMACS_TIME timer_check (int do_it_now);
 
-extern Lisp_Object Vhistory_length, Vtranslation_table_for_input;
-
 static void record_menu_key (Lisp_Object c);
 static int echo_length (void);
 
@@ -542,8 +538,6 @@ Lisp_Object Vtimer_idle_list;
 /* Incremented whenever a timer is run.  */
 int timers_run;
 
-extern Lisp_Object Vprint_level, Vprint_length;
-
 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
    happens.  */
 EMACS_TIME *input_available_clear_time;
@@ -625,8 +619,8 @@ static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
                                         Lisp_Object, Lisp_Object,
                                         unsigned long);
 #endif
-static Lisp_Object modify_event_symbol (int, unsigned, Lisp_Object,
-                                        Lisp_Object, char **,
+static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object,
+                                        Lisp_Object, const char *const *,
                                         Lisp_Object *, unsigned);
 static Lisp_Object make_lispy_switch_frame (Lisp_Object);
 static void save_getcjmp (jmp_buf);
@@ -635,6 +629,9 @@ static Lisp_Object apply_modifiers (int, Lisp_Object);
 static void clear_event (struct input_event *);
 static Lisp_Object restore_kboard_configuration (Lisp_Object);
 static SIGTYPE interrupt_signal (int signalnum);
+#ifdef SIGIO
+static SIGTYPE input_available_signal (int signo);
+#endif
 static void handle_interrupt (void);
 static void timer_start_idle (void);
 static void timer_stop_idle (void);
@@ -647,20 +644,7 @@ static int store_user_signal_events (void);
    to support it.  */
 static int cannot_suspend;
 
-extern Lisp_Object Qidentity, Qonly;
 \f
-/* Install the string STR as the beginning of the string of echoing,
-   so that it serves as a prompt for the next character.
-   Also start echoing.  */
-
-void
-echo_prompt (Lisp_Object str)
-{
-  current_kboard->echo_string = str;
-  current_kboard->echo_after_prompt = SCHARS (str);
-  echo_now ();
-}
-
 /* Add C to the echo string, if echoing is going on.
    C can be a character, which is printed prettily ("M-C-x" and all that
    jazz), or a symbol, whose name is printed.  */
@@ -715,7 +699,7 @@ echo_char (Lisp_Object c)
              ptr = buffer + offset;
            }
 
-         bcopy (text, ptr, len);
+         memcpy (ptr, text, len);
          ptr += len;
        }
 
@@ -759,6 +743,9 @@ echo_dash (void)
   if (NILP (current_kboard->echo_string))
     return;
 
+  if (this_command_key_count == 0)
+    return;
+
   if (!current_kboard->immediate_echo
       && SCHARS (current_kboard->echo_string) == 0)
     return;
@@ -869,7 +856,7 @@ echo_length (void)
    switches frames while entering a key sequence.  */
 
 static void
-echo_truncate (int nchars)
+echo_truncate (EMACS_INT nchars)
 {
   if (STRINGP (current_kboard->echo_string))
     current_kboard->echo_string
@@ -974,7 +961,7 @@ To get out of the recursive edit, a command can do `(throw 'exit nil)';
 that tells this function to return.
 Alternatively, `(throw 'exit t)' makes this function signal an error.
 This function is called by the editor initialization to begin editing.  */)
-     ()
+  (void)
 {
   int count = SPECPDL_INDEX ();
   Lisp_Object buffer;
@@ -1237,7 +1224,7 @@ cmd_error (Lisp_Object data)
    string.  */
 
 void
-cmd_error_internal (Lisp_Object data, char *context)
+cmd_error_internal (Lisp_Object data, const char *context)
 {
   struct frame *sf = SELECTED_FRAME ();
 
@@ -1365,7 +1352,7 @@ top_level_1 (Lisp_Object ignore)
 DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "",
        doc: /* Exit all recursive editing levels.
 This also exits all active minibuffers.  */)
-     ()
+  (void)
 {
 #ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
@@ -1377,29 +1364,27 @@ This also exits all active minibuffers.  */)
   while (INPUT_BLOCKED_P)
     UNBLOCK_INPUT;
 
-  return Fthrow (Qtop_level, Qnil);
+  Fthrow (Qtop_level, Qnil);
 }
 
 DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
        doc: /* Exit from the innermost recursive edit or minibuffer.  */)
-     ()
+  (void)
 {
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qnil);
 
   error ("No recursive edit is in progress");
-  return Qnil;
 }
 
 DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
        doc: /* Abort the command that requested this recursive edit or minibuffer input.  */)
-     ()
+  (void)
 {
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qt);
 
   error ("No recursive edit is in progress");
-  return Qnil;
 }
 \f
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
@@ -1434,8 +1419,7 @@ Within a `track-mouse' form, mouse motion generates input events that
 you can read with `read-event'.
 Normally, mouse motion is ignored.
 usage: (track-mouse BODY...)  */)
-     (args)
-     Lisp_Object args;
+  (Lisp_Object args)
 {
   int count = SPECPDL_INDEX ();
   Lisp_Object val;
@@ -1485,7 +1469,7 @@ some_mouse_moved (void)
 static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
                               int, int, int);
 void safe_run_hooks (Lisp_Object);
-static void adjust_point_for_property (int, int);
+static void adjust_point_for_property (EMACS_INT, int);
 
 /* Cancel hourglass from protect_unwind.
    ARG is not used.  */
@@ -1498,6 +1482,11 @@ cancel_hourglass_unwind (Lisp_Object arg)
 }
 #endif
 
+/* FIXME: This is wrong rather than test window-system, we should call
+   a new set-selection, which will then dispatch to x-set-selection, or
+   tty-set-selection, or w32-set-selection, ...  */
+EXFUN (Fwindow_system, 1);
+
 Lisp_Object
 command_loop_1 (void)
 {
@@ -1786,7 +1775,8 @@ command_loop_1 (void)
          this_single_command_key_start = 0;
        }
 
-      if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
+      if (!NILP (current_buffer->mark_active)
+         && !NILP (Vrun_hooks))
        {
          /* In Emacs 22, setting transient-mark-mode to `only' was a
             way of turning it on for just one command.  This usage is
@@ -1797,9 +1787,40 @@ command_loop_1 (void)
            Vtransient_mark_mode = Qidentity;
 
          if (!NILP (Vdeactivate_mark))
+           /* If `select-active-regions' is non-nil, this call to
+              `deactivate-mark' also sets the PRIMARY selection.  */
            call0 (Qdeactivate_mark);
-         else if (current_buffer != prev_buffer || MODIFF != prev_modiff)
-           call1 (Vrun_hooks, intern ("activate-mark-hook"));
+         else
+           {
+             /* Even if not deactivating the mark, set PRIMARY if
+                `select-active-regions' is non-nil.  */
+             if (!NILP (Fwindow_system (Qnil))
+                 /* Even if mark_active is non-nil, the actual buffer
+                    marker may not have been set yet (Bug#7044).  */
+                 && XMARKER (current_buffer->mark)->buffer
+                 && (EQ (Vselect_active_regions, Qonly)
+                     ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
+                     : (!NILP (Vselect_active_regions)
+                        && !NILP (Vtransient_mark_mode)))
+                 && !EQ (Vthis_command, Qhandle_switch_frame))
+               {
+                 EMACS_INT beg =
+                   XINT (Fmarker_position (current_buffer->mark));
+                 EMACS_INT end = PT;
+                 if (beg < end)
+                   call2 (Qx_set_selection, QPRIMARY,
+                          make_buffer_string (beg, end, 0));
+                 else if (beg > end)
+                   call2 (Qx_set_selection, QPRIMARY,
+                          make_buffer_string (end, beg, 0));
+                 /* Don't set empty selections.  */
+               }
+
+             if (current_buffer != prev_buffer || MODIFF != prev_modiff)
+               call1 (Vrun_hooks, intern ("activate-mark-hook"));
+           }
+
+         Vsaved_region_selection = Qnil;
        }
 
     finalize:
@@ -1836,18 +1857,13 @@ command_loop_1 (void)
     }
 }
 
-extern Lisp_Object Qcomposition, Qdisplay;
-
 /* Adjust point to a boundary of a region that has such a property
    that should be treated intangible.  For the moment, we check
    `composition', `display' and `invisible' properties.
    LAST_PT is the last position of point.  */
 
-extern Lisp_Object Qafter_string, Qbefore_string;
-extern Lisp_Object get_pos_property (Lisp_Object, Lisp_Object, Lisp_Object);
-
 static void
-adjust_point_for_property (int last_pt, int modified)
+adjust_point_for_property (EMACS_INT last_pt, int modified)
 {
   EMACS_INT beg, end;
   Lisp_Object val, overlay, tmp;
@@ -1856,7 +1872,7 @@ adjust_point_for_property (int last_pt, int modified)
      user can keep inserting another character at point or keep
      deleting characters around point.  */
   int check_composition = ! modified, check_display = 1, check_invisible = 1;
-  int orig_pt = PT;
+  EMACS_INT orig_pt = PT;
 
   /* FIXME: cycling is probably not necessary because these properties
      can't be usefully combined anyway.  */
@@ -2759,7 +2775,8 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
 
   if (INTERACTIVE && NILP (c))
     {
-      int delay_level, buffer_size;
+      int delay_level;
+      EMACS_INT buffer_size;
 
       /* Slow down auto saves logarithmically in size of current buffer,
         and garbage collect while we're at it.  */
@@ -3480,13 +3497,13 @@ print_help (Lisp_Object object)
 static void
 save_getcjmp (jmp_buf temp)
 {
-  bcopy (getcjmp, temp, sizeof getcjmp);
+  memcpy (temp, getcjmp, sizeof getcjmp);
 }
 
 static void
 restore_getcjmp (jmp_buf temp)
 {
-  bcopy (temp, getcjmp, sizeof getcjmp);
+  memcpy (getcjmp, temp, sizeof getcjmp);
 }
 \f
 /* Low level keyboard/mouse input.
@@ -3498,12 +3515,6 @@ restore_getcjmp (jmp_buf temp)
 static int
 readable_events (int flags)
 {
-#ifdef HAVE_DBUS
-  /* Check whether a D-Bus message has arrived.  */
-  if (xd_pending_messages () > 0)
-    return 1;
-#endif /* HAVE_DBUS */
-
   if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
     timer_check (1);
 
@@ -3590,6 +3601,20 @@ event_to_kboard (struct input_event *event)
     return FRAME_KBOARD (XFRAME (frame));
 }
 
+#ifdef subprocesses
+/* Return the number of slots occupied in kbd_buffer.  */
+
+static int
+kbd_buffer_nr_stored (void)
+{
+  return kbd_fetch_ptr == kbd_store_ptr
+    ? 0
+    : (kbd_fetch_ptr < kbd_store_ptr
+       ? kbd_store_ptr - kbd_fetch_ptr
+       : ((kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr
+          + (kbd_store_ptr - kbd_buffer)));
+}
+#endif /* subprocesses */
 
 Lisp_Object Vthrow_on_input;
 
@@ -3662,7 +3687,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
 
          if (hold_quit)
            {
-             bcopy (event, (char *) hold_quit, sizeof (*event));
+             memcpy (hold_quit, event, sizeof (*event));
              return;
            }
 
@@ -3711,6 +3736,19 @@ kbd_buffer_store_event_hold (register struct input_event *event,
     {
       *kbd_store_ptr = *event;
       ++kbd_store_ptr;
+#ifdef subprocesses
+      if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE/2 && ! kbd_on_hold_p ())
+        {
+          /* Don't read keyboard input until we have processed kbd_buffer.
+             This happens when pasting text longer than KBD_BUFFER_SIZE/2.  */
+          hold_keyboard_input ();
+#ifdef SIGIO
+          if (!noninteractive)
+            signal (SIGIO, SIG_IGN);
+#endif
+          stop_polling ();
+        }
+#endif /* subprocesses */
     }
 
   /* If we're inside while-no-input, and this event qualifies
@@ -3750,22 +3788,20 @@ kbd_buffer_unget_event (register struct input_event *event)
 }
 
 
-/* Generate HELP_EVENT input_events in BUFP which has room for
-   SIZE events.  If there's not enough room in BUFP, ignore this
-   event.
+/* Generate a HELP_EVENT input_event and store it in the keyboard
+   buffer.
 
    HELP is the help form.
 
-   FRAME is the frame on which the help is generated.  OBJECT is the
-   Lisp object where the help was found (a buffer, a string, an
-   overlay, or nil if neither from a string nor from a buffer.  POS is
-   the position within OBJECT where the help was found.
-
-   Value is the number of input_events generated.  */
+   FRAME and WINDOW are the frame and window where the help is
+   generated.  OBJECT is the Lisp object where the help was found (a
+   buffer, a string, an overlay, or nil if neither from a string nor
+   from a buffer).  POS is the position within OBJECT where the help
+   was found.  */
 
 void
 gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
-               Lisp_Object object, int pos)
+               Lisp_Object object, EMACS_INT pos)
 {
   struct input_event event;
 
@@ -3866,11 +3902,27 @@ clear_event (struct input_event *event)
    We always read and discard one event.  */
 
 static Lisp_Object
-kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu, struct timeval *end_time)
+kbd_buffer_get_event (KBOARD **kbp,
+                      int *used_mouse_menu,
+                      struct timeval *end_time)
 {
   register int c;
   Lisp_Object obj;
 
+#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.  */
+      unhold_keyboard_input ();
+#ifdef SIGIO
+      if (!noninteractive)
+        signal (SIGIO, input_available_signal);
+#endif /* SIGIO */
+      start_polling ();
+    }
+#endif /* subprocesses */
+
   if (noninteractive
       /* In case we are running as a daemon, only do this before
         detaching from the terminal.  */
@@ -4056,7 +4108,7 @@ kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu, struct timeval *end_ti
 #endif
       else if (event->kind == SAVE_SESSION_EVENT)
         {
-          obj = Fcons (Qsave_session, Qnil);
+          obj = Fcons (Qsave_session, Fcons (event->arg, Qnil));
          kbd_fetch_ptr = event + 1;
         }
       /* Just discard these, by returning nil.
@@ -4335,8 +4387,6 @@ struct input_event last_timer_event;
    ...).  Each element has the form (FUN . ARGS).  */
 Lisp_Object pending_funcalls;
 
-extern Lisp_Object Qapply;
-
 /* Check whether a timer has fired.  To prevent larger problems we simply
    disregard elements that are not proper timers.  Do not make a circular
    timer list for the time being.
@@ -4574,7 +4624,7 @@ The value when Emacs is not idle is nil.
 
 The microsecond count is zero on systems that do not provide
 resolution finer than a second.  */)
-  ()
+  (void)
 {
   if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
     {
@@ -4708,7 +4758,7 @@ static const int lispy_accent_codes[] =
 /* This is a list of Lisp names for special "accent" characters.
    It parallels lispy_accent_codes.  */
 
-static char *lispy_accent_keys[] =
+static const char *const lispy_accent_keys[] =
 {
   "dead-circumflex",
   "dead-grave",
@@ -4735,7 +4785,7 @@ static char *lispy_accent_keys[] =
 #ifdef HAVE_NTGUI
 #define FUNCTION_KEY_OFFSET 0x0
 
-char *lispy_function_keys[] =
+const char *const lispy_function_keys[] =
   {
     0,                /* 0                      */
 
@@ -4898,9 +4948,9 @@ char *lispy_function_keys[] =
     0,               /* VK_OEM_102        0xE2 */
     "ico-help",      /* VK_ICO_HELP       0xE3 */
     "ico-00",        /* VK_ICO_00         0xE4 */
-    0,               /* VK_PROCESSKEY     0xE5 */
+    0,               /* VK_PROCESSKEY     0xE5 - used by IME */
     "ico-clear",     /* VK_ICO_CLEAR      0xE6 */
-    "packet",        /* VK_PACKET         0xE7 */
+    0,               /* VK_PACKET         0xE7  - used to pass unicode chars */
     0,               /*                   0xE8 */
     "reset",         /* VK_OEM_RESET      0xE9 */
     "jump",          /* VK_OEM_JUMP       0xEA */
@@ -4929,7 +4979,7 @@ char *lispy_function_keys[] =
 
 /* Some of these duplicate the "Media keys" on newer keyboards,
    but they are delivered to the application in a different way.  */
-static char *lispy_multimedia_keys[] =
+static const char *const lispy_multimedia_keys[] =
   {
     0,
     "browser-back",
@@ -4993,7 +5043,7 @@ static char *lispy_multimedia_keys[] =
    the XK_kana_A case below.  */
 #if 0
 #ifdef XK_kana_A
-static char *lispy_kana_keys[] =
+static const char *const lispy_kana_keys[] =
   {
     /* X Keysym value */
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,   /* 0x400 .. 0x40f */
@@ -5032,7 +5082,7 @@ static char *lispy_kana_keys[] =
 
 /* You'll notice that this table is arranged to be conveniently
    indexed by X Windows keysym values.  */
-static char *lispy_function_keys[] =
+static const char *const lispy_function_keys[] =
   {
     /* X Keysym value */
 
@@ -5118,7 +5168,7 @@ static char *lispy_function_keys[] =
 /* ISO 9995 Function and Modifier Keys; the first byte is 0xFE.  */
 #define ISO_FUNCTION_KEY_OFFSET 0xfe00
 
-static char *iso_lispy_function_keys[] =
+static const char *const iso_lispy_function_keys[] =
   {
     0, 0, 0, 0, 0, 0, 0, 0,    /* 0xfe00 */
     0, 0, 0, 0, 0, 0, 0, 0,    /* 0xfe08 */
@@ -5141,14 +5191,14 @@ static char *iso_lispy_function_keys[] =
 
 Lisp_Object Vlispy_mouse_stem;
 
-static char *lispy_wheel_names[] =
+static const char *const lispy_wheel_names[] =
 {
   "wheel-up", "wheel-down", "wheel-left", "wheel-right"
 };
 
 /* drag-n-drop events are generated when a set of selected files are
    dragged from another application and dropped onto an Emacs window.  */
-static char *lispy_drag_n_drop_names[] =
+static const char *const lispy_drag_n_drop_names[] =
 {
   "drag-n-drop"
 };
@@ -5159,7 +5209,7 @@ Lisp_Object Qup, Qdown, Qbottom, Qend_scroll;
 Lisp_Object Qtop, Qratio;
 
 /* An array of scroll bar parts, indexed by an enum scroll_bar_part value.  */
-Lisp_Object *scroll_bar_parts[] = {
+static Lisp_Object *const scroll_bar_parts[] = {
   &Qabove_handle, &Qhandle, &Qbelow_handle,
   &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio
 };
@@ -5199,126 +5249,137 @@ EMACS_INT double_click_fuzz;
 
 int double_click_count;
 
-/* Return position of a mouse click or wheel event */
+/* X and Y are frame-relative coordinates for a click or wheel event.
+   Return a Lisp-style event list.  */
 
 static Lisp_Object
-make_lispy_position (struct frame *f, Lisp_Object *x, Lisp_Object *y,
+make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
                     unsigned long time)
 {
-  Lisp_Object window;
   enum window_part part;
   Lisp_Object posn = Qnil;
   Lisp_Object extra_info = Qnil;
-  int wx, wy;
-
-  /* Set `window' to the window under frame pixel coordinates (x,y)  */
-  if (f)
-    window = window_from_coordinates (f, XINT (*x), XINT (*y),
-                                     &part, &wx, &wy, 0);
-  else
-    window = Qnil;
+  /* Coordinate pixel positions to return.  */
+  int xret = 0, yret = 0;
+  /* The window under frame pixel coordinates (x,y)  */
+  Lisp_Object window = f
+    ? window_from_coordinates (f, XINT (x), XINT (y), &part, 0)
+    : Qnil;
 
   if (WINDOWP (window))
     {
       /* It's a click in window window at frame coordinates (x,y)  */
       struct window *w = XWINDOW (window);
       Lisp_Object string_info = Qnil;
-      int textpos = -1, rx = -1, ry = -1;
-      int dx = -1, dy = -1;
+      EMACS_INT textpos = -1;
+      int col = -1, row = -1;
+      int dx  = -1, dy  = -1;
       int width = -1, height = -1;
       Lisp_Object object = Qnil;
 
-      /* Set event coordinates to window-relative coordinates
-        for constructing the Lisp event below.  */
-      XSETINT (*x, wx);
-      XSETINT (*y, wy);
+      /* Pixel coordinates relative to the window corner.  */
+      int wx = XINT (x) - WINDOW_LEFT_EDGE_X (w);
+      int wy = XINT (y) - WINDOW_TOP_EDGE_Y (w);
 
+      /* For text area clicks, return X, Y relative to the corner of
+        this text area.  Note that dX, dY etc are set below, by
+        buffer_posn_from_coords.  */
       if (part == ON_TEXT)
        {
-         wx += WINDOW_LEFT_MARGIN_WIDTH (w);
+         xret = XINT (x) - window_box_left (w, TEXT_AREA);
+         yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
        }
+      /* For mode line and header line clicks, return X, Y relative to
+        the left window edge.  Use mode_line_string to look for a
+        string on the click position.  */
       else if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
        {
-         /* Mode line or header line.  Look for a string under
-            the mouse that may have a `local-map' property.  */
          Lisp_Object string;
-         int charpos;
-
-         posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
-         rx = wx, ry = wy;
-         string = mode_line_string (w, part, &rx, &ry, &charpos,
+         EMACS_INT charpos;
+
+         posn = (part == ON_MODE_LINE) ? Qmode_line : Qheader_line;
+         /* Note that mode_line_string takes COL, ROW as pixels and
+            converts them to characters.  */
+         col = wx;
+         row = wy;
+         string = mode_line_string (w, part, &col, &row, &charpos,
                                     &object, &dx, &dy, &width, &height);
          if (STRINGP (string))
            string_info = Fcons (string, make_number (charpos));
-         if (w == XWINDOW (selected_window)
-             && current_buffer == XBUFFER (w->buffer))
-           textpos = PT;
-         else
-           textpos = XMARKER (w->pointm)->charpos;
-       }
-      else if (part == ON_VERTICAL_BORDER)
-       {
-         posn = Qvertical_line;
-         wx = -1;
-         dx = 0;
-         width = 1;
+         textpos = (w == XWINDOW (selected_window)
+                    && current_buffer == XBUFFER (w->buffer))
+           ? PT : XMARKER (w->pointm)->charpos;
+
+         xret = wx;
+         yret = wy;
        }
+      /* For fringes and margins, Y is relative to the area's (and the
+        window's) top edge, while X is meaningless.  */
       else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
        {
          Lisp_Object string;
-         int charpos;
+         EMACS_INT charpos;
 
          posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
-         rx = wx, ry = wy;
-         string = marginal_area_string (w, part, &rx, &ry, &charpos,
+         col = wx;
+         row = wy;
+         string = marginal_area_string (w, part, &col, &row, &charpos,
                                         &object, &dx, &dy, &width, &height);
          if (STRINGP (string))
            string_info = Fcons (string, make_number (charpos));
-         if (part == ON_LEFT_MARGIN)
-           wx = 0;
-         else
-           wx = window_box_right_offset (w, TEXT_AREA) - 1;
+         yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
        }
       else if (part == ON_LEFT_FRINGE)
        {
          posn = Qleft_fringe;
-         rx = 0;
-         dx = wx;
-         wx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
-               ? 0
-               : window_box_width (w, LEFT_MARGIN_AREA));
-         dx -= wx;
+         col = 0;
+         dx = wx
+           - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+              ? 0 : window_box_width (w, LEFT_MARGIN_AREA));
+         dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
        }
       else if (part == ON_RIGHT_FRINGE)
        {
          posn = Qright_fringe;
-         rx = 0;
-         dx = wx;
-         wx = (window_box_width (w, LEFT_MARGIN_AREA)
-               + window_box_width (w, TEXT_AREA)
-               + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
-                  ? window_box_width (w, RIGHT_MARGIN_AREA)
-                  : 0));
-         dx -= wx;
+         col = 0;
+         dx = wx
+           - window_box_width (w, LEFT_MARGIN_AREA)
+           - window_box_width (w, TEXT_AREA)
+           - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+              ? window_box_width (w, RIGHT_MARGIN_AREA)
+              : 0);
+         dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
        }
-      else
+      else if (part == ON_VERTICAL_BORDER)
        {
-         /* Note: We have no special posn for part == ON_SCROLL_BAR.  */
-         wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx);
+         posn = Qvertical_line;
+         width = 1;
+         dx = 0;
+         dy = yret = wy;
        }
+      /* Nothing special for part == ON_SCROLL_BAR.  */
 
+      /* For clicks in the text area, fringes, or margins, call
+        buffer_posn_from_coords to extract TEXTPOS, the buffer
+        position nearest to the click.  */
       if (textpos < 0)
        {
          Lisp_Object string2, object2 = Qnil;
          struct display_pos p;
          int dx2, dy2;
          int width2, height2;
-         string2 = buffer_posn_from_coords (w, &wx, &wy, &p,
+         /* The pixel X coordinate passed to buffer_posn_from_coords
+            is the X coordinate relative to the text area for
+            text-area clicks, zero otherwise.  */
+         int x2 = (part == ON_TEXT) ? xret : 0;
+         int y2 = wy;
+
+         string2 = buffer_posn_from_coords (w, &x2, &y2, &p,
                                             &object2, &dx2, &dy2,
                                             &width2, &height2);
          textpos = CHARPOS (p.pos);
-         if (rx < 0) rx = wx;
-         if (ry < 0) ry = wy;
+         if (col < 0) col = x2;
+         if (row < 0) row = y2;
          if (dx < 0) dx = dx2;
          if (dy < 0) dy = dy2;
          if (width < 0) width = width2;
@@ -5349,34 +5410,27 @@ make_lispy_position (struct frame *f, Lisp_Object *x, Lisp_Object *y,
 #endif
 
       /* Object info */
-      extra_info = Fcons (object,
-                         Fcons (Fcons (make_number (dx),
-                                       make_number (dy)),
-                                Fcons (Fcons (make_number (width),
-                                              make_number (height)),
-                                       Qnil)));
+      extra_info
+       = list3 (object,
+                Fcons (make_number (dx), make_number (dy)),
+                Fcons (make_number (width), make_number (height)));
 
       /* String info */
       extra_info = Fcons (string_info,
                          Fcons (make_number (textpos),
-                                Fcons (Fcons (make_number (rx),
-                                              make_number (ry)),
+                                Fcons (Fcons (make_number (col),
+                                              make_number (row)),
                                        extra_info)));
     }
   else if (f != 0)
-    {
-      XSETFRAME (window, f);
-    }
+    XSETFRAME (window, f);
   else
-    {
-      window = Qnil;
-      XSETFASTINT (*x, 0);
-      XSETFASTINT (*y, 0);
-    }
+    window = Qnil;
 
   return Fcons (window,
                Fcons (posn,
-                      Fcons (Fcons (*x, *y),
+                      Fcons (Fcons (make_number (xret),
+                                    make_number (yret)),
                              Fcons (make_number (time),
                                     extra_info))));
 }
@@ -5401,7 +5455,7 @@ make_lispy_event (struct input_event *event)
     case MULTIBYTE_CHAR_KEYSTROKE_EVENT:
       {
        Lisp_Object lispy_c;
-       int c = event->code;
+       EMACS_INT c = event->code;
        if (event->kind == ASCII_KEYSTROKE_EVENT)
          {
            c &= 0377;
@@ -5565,14 +5619,6 @@ make_lispy_event (struct input_event *event)
                int hpos;
                int i;
 
-#if 0
-               /* Activate the menu bar on the down event.  If the
-                  up event comes in before the menu code can deal with it,
-                  just ignore it.  */
-               if (! (event->modifiers & down_modifier))
-                 return Qnil;
-#endif
-
                /* Find the menu bar item under `column'.  */
                item = Qnil;
                items = FRAME_MENU_BAR_ITEMS (f);
@@ -5604,7 +5650,7 @@ make_lispy_event (struct input_event *event)
              }
 #endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */
 
-           position = make_lispy_position (f, &event->x, &event->y,
+           position = make_lispy_position (f, event->x, event->y,
                                            event->timestamp);
          }
 #ifndef USE_TOOLKIT_SCROLL_BARS
@@ -5704,23 +5750,21 @@ make_lispy_event (struct input_event *event)
              return Qnil;
 
            event->modifiers &= ~up_modifier;
-#if 0 /* Formerly we treated an up with no down as a click event.  */
-           if (!CONSP (start_pos))
-             event->modifiers |= click_modifier;
-           else
-#endif
+
              {
-               Lisp_Object down;
+               Lisp_Object new_down, down;
                EMACS_INT xdiff = double_click_fuzz, ydiff = double_click_fuzz;
 
                /* The third element of every position
                   should be the (x,y) pair.  */
                down = Fcar (Fcdr (Fcdr (start_pos)));
+               new_down = Fcar (Fcdr (Fcdr (position)));
+
                if (CONSP (down)
                    && INTEGERP (XCAR (down)) && INTEGERP (XCDR (down)))
                  {
-                   xdiff = XINT (event->x) - XINT (XCAR (down));
-                   ydiff = XINT (event->y) - XINT (XCDR (down));
+                   xdiff = XINT (XCAR (new_down)) - XINT (XCAR (down));
+                   ydiff = XINT (XCDR (new_down)) - XINT (XCDR (down));
                  }
 
                if (ignore_mouse_drag_p)
@@ -5803,7 +5847,7 @@ make_lispy_event (struct input_event *event)
        if (! FRAME_LIVE_P (f))
          return Qnil;
 
-       position = make_lispy_position (f, &event->x, &event->y,
+       position = make_lispy_position (f, event->x, event->y,
                                        event->timestamp);
 
        /* Set double or triple modifiers to indicate the wheel speed.  */
@@ -5823,10 +5867,8 @@ make_lispy_event (struct input_event *event)
          else
            abort ();
 
-         if (FRAME_WINDOW_P (f))
-           fuzz = double_click_fuzz;
-         else
-           fuzz = double_click_fuzz / 8;
+         fuzz = FRAME_WINDOW_P (f)
+           ? double_click_fuzz : double_click_fuzz / 8;
 
          if (event->modifiers & up_modifier)
            {
@@ -5964,7 +6006,7 @@ make_lispy_event (struct input_event *event)
        if (! FRAME_LIVE_P (f))
          return Qnil;
 
-       position = make_lispy_position (f, &event->x, &event->y,
+       position = make_lispy_position (f, event->x, event->y,
                                        event->timestamp);
 
        head = modify_event_symbol (0, event->modifiers,
@@ -6047,8 +6089,8 @@ make_lispy_event (struct input_event *event)
        start_pos_ptr = &AREF (button_down_location, button);
        start_pos = *start_pos_ptr;
 
-       position = make_lispy_position (f, &event->x, &event->y,
-                                           event->timestamp);
+       position = make_lispy_position (f, event->x, event->y,
+                                       event->timestamp);
 
        if (event->modifiers & down_modifier)
          *start_pos_ptr = Fcopy_alist (position);
@@ -6107,25 +6149,19 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
 
       part_sym = *scroll_bar_parts[(int) part];
       return Fcons (Qscroll_bar_movement,
-                   (Fcons (Fcons (bar_window,
-                                  Fcons (Qvertical_scroll_bar,
-                                         Fcons (Fcons (x, y),
-                                                Fcons (make_number (time),
-                                                       Fcons (part_sym,
-                                                              Qnil))))),
-                           Qnil)));
+                   Fcons (list5 (bar_window,
+                                 Qvertical_scroll_bar,
+                                 Fcons (x, y),
+                                 make_number (time),
+                                 part_sym),
+                          Qnil));
     }
-
   /* Or is it an ordinary mouse movement?  */
   else
     {
       Lisp_Object position;
-
-      position = make_lispy_position (frame, &x, &y, time);
-
-      return Fcons (Qmouse_movement,
-                   Fcons (position,
-                          Qnil));
+      position = make_lispy_position (frame, x, y, time);
+      return list2 (Qmouse_movement, position);
     }
 }
 
@@ -6298,15 +6334,15 @@ apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_
 
     new_name = make_uninit_multibyte_string (mod_len + base_len,
                                             mod_len + base_len_byte);
-    bcopy (new_mods, SDATA (new_name),        mod_len);
-    bcopy (base,     SDATA (new_name) + mod_len, base_len_byte);
+    memcpy (SDATA (new_name), new_mods, mod_len);
+    memcpy (SDATA (new_name) + mod_len, base, base_len_byte);
 
     return Fintern (new_name, Qnil);
   }
 }
 
 
-static const char *modifier_names[] =
+static const char *const modifier_names[] =
 {
   "up", "down", "drag", "click", "double", "triple", 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -6391,8 +6427,7 @@ parse_modifiers (Lisp_Object symbol)
 DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers,
        Sevent_symbol_parse_modifiers, 1, 1, 0,
        doc: /* Parse the event symbol.  For internal use.  */)
-     (symbol)
-     Lisp_Object symbol;
+  (Lisp_Object symbol)
 {
   /* Fill the cache if needed.  */
   parse_modifiers (symbol);
@@ -6526,8 +6561,8 @@ reorder_modifiers (Lisp_Object symbol)
    in the symbol's name.  */
 
 static Lisp_Object
-modify_event_symbol (int symbol_num, unsigned int modifiers, Lisp_Object symbol_kind,
-                    Lisp_Object name_alist_or_stem, char **name_table,
+modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object symbol_kind,
+                    Lisp_Object name_alist_or_stem, const char *const *name_table,
                     Lisp_Object *symbol_table, unsigned int table_size)
 {
   Lisp_Object value;
@@ -6581,7 +6616,6 @@ modify_event_symbol (int symbol_num, unsigned int modifiers, Lisp_Object symbol_
 #ifdef HAVE_WINDOW_SYSTEM
       if (NILP (value))
        {
-         extern char *x_get_keysym_name (KeySym keysym);
          char *name = x_get_keysym_name (symbol_num);
          if (name)
            value = intern (name);
@@ -6591,7 +6625,7 @@ modify_event_symbol (int symbol_num, unsigned int modifiers, Lisp_Object symbol_
       if (NILP (value))
        {
          char buf[20];
-         sprintf (buf, "key-%d", symbol_num);
+         sprintf (buf, "key-%ld", (long)symbol_num);
          value = intern (buf);
        }
 
@@ -6622,8 +6656,7 @@ and zero or more modifier names (control, meta, hyper, super, shift, alt,
 drag, down, double or triple).  The base must be last.
 The return value is an event type (a character or symbol) which
 has the same base event type and all the specified modifiers.  */)
-     (event_desc)
-     Lisp_Object event_desc;
+  (Lisp_Object event_desc)
 {
   Lisp_Object base;
   int modifiers = 0;
@@ -6822,11 +6855,6 @@ get_input_pending (int *addr, int flags)
 void
 gobble_input (int expected)
 {
-#ifdef HAVE_DBUS
-  /* Read D-Bus messages.  */
-  xd_read_queued_messages ();
-#endif /* HAVE_DBUS */
-
 #ifdef SIGIO
   if (interrupt_input)
     {
@@ -6867,18 +6895,15 @@ record_asynch_buffer_change (void)
   event.frame_or_window = Qnil;
   event.arg = Qnil;
 
-#ifdef subprocesses
   /* We don't need a buffer-switch event unless Emacs is waiting for input.
      The purpose of the event is to make read_key_sequence look up the
      keymaps again.  If we aren't in read_key_sequence, we don't need one,
-     and the event could cause trouble by messing up (input-pending-p).  */
+     and the event could cause trouble by messing up (input-pending-p).
+     Note: Fwaiting_for_user_input_p always returns nil when async
+     subprocesses aren't supported.  */
   tem = Fwaiting_for_user_input_p ();
   if (NILP (tem))
     return;
-#else
-  /* We never need these events if we have no asynchronous subprocesses.  */
-  return;
-#endif
 
   /* Make sure no interrupt happens while storing the event.  */
 #ifdef SIGIO
@@ -7040,6 +7065,12 @@ tty_read_avail_input (struct terminal *terminal,
   int n_to_read, i;
   struct tty_display_info *tty = terminal->display_info.tty;
   int nread = 0;
+#ifdef subprocesses
+  int buffer_free = KBD_BUFFER_SIZE - kbd_buffer_nr_stored () - 1;
+
+  if (kbd_on_hold_p () || buffer_free <= 0)
+    return 0;
+#endif /* subprocesses */
 
   if (!terminal->name)         /* Don't read from a dead terminal. */
     return 0;
@@ -7121,6 +7152,12 @@ tty_read_avail_input (struct terminal *terminal,
 #endif
 #endif
 
+#ifdef subprocesses
+  /* Don't read more than we can store.  */
+  if (n_to_read > buffer_free)
+    n_to_read = buffer_free;
+#endif /* subprocesses */
+
   /* Now read; for one reason or another, this will not block.
      NREAD is set to the number of chars read.  */
   do
@@ -7403,7 +7440,7 @@ store_user_signal_events (void)
 
        if (nstored == 0)
          {
-           bzero (&buf, sizeof buf);
+           memset (&buf, 0, sizeof buf);
            buf.kind = USER_SIGNAL_EVENT;
            buf.frame_or_window = selected_frame;
          }
@@ -7433,6 +7470,54 @@ static Lisp_Object menu_bar_one_keymap_changed_items;
 static Lisp_Object menu_bar_items_vector;
 static int menu_bar_items_index;
 
+
+static const char* separator_names[] = {
+  "space",
+  "no-line",
+  "single-line",
+  "double-line",
+  "single-dashed-line",
+  "double-dashed-line",
+  "shadow-etched-in",
+  "shadow-etched-out",
+  "shadow-etched-in-dash",
+  "shadow-etched-out-dash",
+  "shadow-double-etched-in",
+  "shadow-double-etched-out",
+  "shadow-double-etched-in-dash",
+  "shadow-double-etched-out-dash",
+  0,
+};
+
+/* Return non-zero if LABEL specifies a separator.  */
+
+int
+menu_separator_name_p (const char *label)
+{
+  if (!label)
+    return 0;
+  else if (strlen (label) > 3
+          && strncmp (label, "--", 2) == 0
+          && label[2] != '-')
+    {
+      int i;
+      label += 2;
+      for (i = 0; separator_names[i]; ++i)
+       if (strcmp (label, separator_names[i]) == 0)
+          return 1;
+    }
+  else
+    {
+      /* It's a separator if it contains only dashes.  */
+      while (*label == '-')
+       ++label;
+      return (*label == 0);
+    }
+
+  return 0;
+}
+
+
 /* Return a vector of menu items for a menu bar, appropriate
    to the current buffer.  Each item has three elements in the vector:
    KEY STRING MAPLIST.
@@ -7507,7 +7592,7 @@ menu_bar_items (Lisp_Object old)
        nmaps = 0;
        if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
          maps[nmaps++] = tem;
-       bcopy (tmaps, (void *) (maps + nmaps), nminor * sizeof (maps[0]));
+       memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
        nmaps += nminor;
        maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
       }
@@ -7548,9 +7633,9 @@ menu_bar_items (Lisp_Object old)
            tem2 = XVECTOR (menu_bar_items_vector)->contents[i + 2];
            tem3 = XVECTOR (menu_bar_items_vector)->contents[i + 3];
            if (end > i + 4)
-             bcopy (&XVECTOR (menu_bar_items_vector)->contents[i + 4],
-                    &XVECTOR (menu_bar_items_vector)->contents[i],
-                    (end - i - 4) * sizeof (Lisp_Object));
+             memmove (&XVECTOR (menu_bar_items_vector)->contents[i],
+                      &XVECTOR (menu_bar_items_vector)->contents[i + 4],
+                      (end - i - 4) * sizeof (Lisp_Object));
            XVECTOR (menu_bar_items_vector)->contents[end - 4] = tem0;
            XVECTOR (menu_bar_items_vector)->contents[end - 3] = tem1;
            XVECTOR (menu_bar_items_vector)->contents[end - 2] = tem2;
@@ -7595,9 +7680,9 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
        if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
          {
            if (menu_bar_items_index > i + 4)
-             bcopy (&XVECTOR (menu_bar_items_vector)->contents[i + 4],
-                    &XVECTOR (menu_bar_items_vector)->contents[i],
-                    (menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
+             memmove (&XVECTOR (menu_bar_items_vector)->contents[i],
+                      &XVECTOR (menu_bar_items_vector)->contents[i + 4],
+                      (menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
            menu_bar_items_index -= 4;
          }
     }
@@ -7977,9 +8062,8 @@ static Lisp_Object tool_bar_item_properties;
 
 static int ntool_bar_items;
 
-/* The symbols `tool-bar', `:image' and `:rtl'.  */
+/* The symbols `:image' and `:rtl'.  */
 
-extern Lisp_Object Qtool_bar;
 Lisp_Object QCimage;
 Lisp_Object Qrtl;
 
@@ -8045,7 +8129,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
       nmaps = 0;
       if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
        maps[nmaps++] = tem;
-      bcopy (tmaps, (void *) (maps + nmaps), nminor * sizeof (maps[0]));
+      memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
       nmaps += nminor;
       maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
     }
@@ -8077,7 +8161,6 @@ static void
 process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void *args)
 {
   int i;
-  extern Lisp_Object Qundefined;
   struct gcpro gcpro1, gcpro2;
 
   /* Protect KEY and DEF from GC because parse_tool_bar_item may call
@@ -8095,9 +8178,9 @@ process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void
          if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
            {
              if (ntool_bar_items > i + TOOL_BAR_ITEM_NSLOTS)
-               bcopy (v + TOOL_BAR_ITEM_NSLOTS, v,
-                      ((ntool_bar_items - i - TOOL_BAR_ITEM_NSLOTS)
-                       * sizeof (Lisp_Object)));
+               memmove (v, v + TOOL_BAR_ITEM_NSLOTS,
+                        ((ntool_bar_items - i - TOOL_BAR_ITEM_NSLOTS)
+                         * sizeof (Lisp_Object)));
              ntool_bar_items -= TOOL_BAR_ITEM_NSLOTS;
              break;
            }
@@ -8172,10 +8255,14 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
      Rule out items that aren't lists, don't start with
      `menu-item' or whose rest following `tool-bar-item' is not a
      list.  */
-  if (!CONSP (item)
-      || !EQ (XCAR (item), Qmenu_item)
-      || (item = XCDR (item),
-         !CONSP (item)))
+  if (!CONSP (item))
+    return 0;
+
+  /* As an exception, allow old-style menu separators.  */
+  if (STRINGP (XCAR (item)))
+    item = Fcons (XCAR (item), Qnil);
+  else if (!EQ (XCAR (item), Qmenu_item)
+          || (item = XCDR (item), !CONSP (item)))
     return 0;
 
   /* Create tool_bar_item_properties vector if necessary.  Reset it to
@@ -8205,10 +8292,27 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
     }
   PROP (TOOL_BAR_ITEM_CAPTION) = caption;
 
-  /* Give up if rest following the caption is not a list.  */
+  /* If the rest following the caption is not a list, the menu item is
+     either a separator, or invalid.  */
   item = XCDR (item);
   if (!CONSP (item))
-    return 0;
+    {
+      if (menu_separator_name_p (SDATA (caption)))
+       {
+         PROP (TOOL_BAR_ITEM_TYPE) = Qt;
+#if !defined (USE_GTK) && !defined (HAVE_NS)
+         /* If we use build_desired_tool_bar_string to render the
+            tool bar, the separator is rendered as an image.  */
+         PROP (TOOL_BAR_ITEM_IMAGES)
+           = menu_item_eval_property (Vtool_bar_separator_image_expression);
+         PROP (TOOL_BAR_ITEM_ENABLED_P) = Qnil;
+         PROP (TOOL_BAR_ITEM_SELECTED_P) = Qnil;
+         PROP (TOOL_BAR_ITEM_CAPTION) = Qnil;
+#endif
+         return 1;
+       }
+      return 0;
+    }
 
   /* Store the binding.  */
   PROP (TOOL_BAR_ITEM_BINDING) = XCAR (item);
@@ -8242,12 +8346,18 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
            return 0;
        }
       else if (EQ (key, QChelp))
-       /* `:help HELP-STRING'.  */
-       PROP (TOOL_BAR_ITEM_HELP) = value;
+        /* `:help HELP-STRING'.  */
+        PROP (TOOL_BAR_ITEM_HELP) = value;
+      else if (EQ (key, QCvert_only))
+        /* `:vert-only t/nil'.  */
+        PROP (TOOL_BAR_ITEM_VERT_ONLY) = value;
       else if (EQ (key, QClabel))
         {
+          const char *bad_label = "!!?GARBLED ITEM?!!";
           /* `:label LABEL-STRING'.  */
-          PROP (TOOL_BAR_ITEM_LABEL) = value;
+          PROP (TOOL_BAR_ITEM_LABEL) = STRINGP (value)
+            ? value
+            : make_string (bad_label, strlen (bad_label));
           have_label = 1;
         }
       else if (EQ (key, QCfilter))
@@ -8283,41 +8393,43 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
       /* Try to make one from caption and key.  */
       Lisp_Object key = PROP (TOOL_BAR_ITEM_KEY);
       Lisp_Object capt = PROP (TOOL_BAR_ITEM_CAPTION);
-      char *label = SYMBOLP (key) ? (char *) SDATA (SYMBOL_NAME (key)) : "";
-      char *caption = STRINGP (capt) ? (char *) SDATA (capt) : "";
-      char buf[64];
-      EMACS_INT max_lbl = 2*tool_bar_max_label_size;
+      const char *label = SYMBOLP (key) ? (char *) SDATA (SYMBOL_NAME (key)) : "";
+      const char *caption = STRINGP (capt) ? (char *) SDATA (capt) : "";
+      EMACS_INT max_lbl = 2 * tool_bar_max_label_size;
+      char *buf = (char *) xmalloc (max_lbl + 1);
       Lisp_Object new_lbl;
+      size_t caption_len = strlen (caption);
 
-      if (strlen (caption) < max_lbl && caption[0] != '\0')
+      if (caption_len <= max_lbl && caption[0] != '\0')
         {
           strcpy (buf, caption);
-          while (buf[0] != '\0' &&  buf[strlen (buf) -1] == '.')
-            buf[strlen (buf)-1] = '\0';
-          if (strlen (buf) <= max_lbl)
-            caption = buf;
+          while (caption_len > 0 && buf[caption_len - 1] == '.')
+            caption_len--;
+         buf[caption_len] = '\0';
+         label = caption = buf;
         }
 
-      if (strlen (caption) <= max_lbl)
-        label = caption;
-
       if (strlen (label) <= max_lbl && label[0] != '\0')
         {
           int i;
-          if (label != buf) strcpy (buf, label);
+          if (label != buf)
+           strcpy (buf, label);
 
-          for (i = 0; i < strlen (buf); ++i)
-            {
-              if (buf[i] == '-') buf[i] = ' ';
-            }
+          for (i = 0; buf[i] != '\0'; ++i)
+           if (buf[i] == '-')
+             buf[i] = ' ';
           label = buf;
 
         }
-      else label = "";
+      else
+       label = "";
 
       new_lbl = Fupcase_initials (make_string (label, strlen (label)));
       if (SCHARS (new_lbl) <= tool_bar_max_label_size)
         PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
+      else
+        PROP (TOOL_BAR_ITEM_LABEL) = make_string ("", 0);
+      free (buf);
     }
 
   /* If got a filter apply it on binding.  */
@@ -8380,7 +8492,7 @@ append_tool_bar_item (void)
      tool_bar_items_vector.  */
   to = XVECTOR (tool_bar_items_vector)->contents + ntool_bar_items;
   from = XVECTOR (tool_bar_item_properties)->contents;
-  bcopy (from, to, TOOL_BAR_ITEM_NSLOTS * sizeof *to);
+  memcpy (to, from, TOOL_BAR_ITEM_NSLOTS * sizeof *to);
   ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
 }
 
@@ -8673,7 +8785,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
                          thiswidth = SCHARS (desc);
                          if (thiswidth + i > width)
                            thiswidth = width - i;
-                         bcopy (SDATA (desc), menu + i, thiswidth);
+                         memcpy (menu + i, SDATA (desc), thiswidth);
                          i += thiswidth;
                          strcpy (menu + i, " = ");
                          i += 3;
@@ -8683,7 +8795,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
                      thiswidth = SCHARS (s);
                      if (thiswidth + i > width)
                        thiswidth = width - i;
-                     bcopy (SDATA (s), menu + i, thiswidth);
+                     memcpy (menu + i, SDATA (s), thiswidth);
                      i += thiswidth;
                      menu[i] = 0;
                    }
@@ -8958,48 +9070,48 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
                   int dont_downcase_last, int can_return_switch_frame,
                   int fix_current_buffer)
 {
-  volatile Lisp_Object from_string;
-  volatile int count = SPECPDL_INDEX ();
+  Lisp_Object from_string;
+  int count = SPECPDL_INDEX ();
 
   /* How many keys there are in the current key sequence.  */
-  volatile int t;
+  int t;
 
   /* The length of the echo buffer when we started reading, and
      the length of this_command_keys when we started reading.  */
-  volatile int echo_start;
-  volatile int keys_start;
+  int echo_start;
+  int keys_start;
 
   /* The number of keymaps we're scanning right now, and the number of
      keymaps we have allocated space for.  */
-  volatile int nmaps;
-  volatile int nmaps_allocated = 0;
+  int nmaps;
+  int nmaps_allocated = 0;
 
   /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
      the current keymaps.  */
-  Lisp_Object *volatile defs = NULL;
+  Lisp_Object *defs = NULL;
 
   /* submaps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
      in the current keymaps, or nil where it is not a prefix.  */
-  Lisp_Object *volatile submaps = NULL;
+  Lisp_Object *submaps = NULL;
 
   /* The local map to start out with at start of key sequence.  */
-  volatile Lisp_Object orig_local_map;
+  Lisp_Object orig_local_map;
 
   /* The map from the `keymap' property to start out with at start of
      key sequence.  */
-  volatile Lisp_Object orig_keymap;
+  Lisp_Object orig_keymap;
 
   /* 1 if we have already considered switching to the local-map property
      of the place where a mouse click occurred.  */
-  volatile int localized_local_map = 0;
+  int localized_local_map = 0;
 
   /* The index in submaps[] of the first keymap that has a binding for
      this key sequence.  In other words, the lowest i such that
      submaps[i] is non-nil.  */
-  volatile int first_binding;
+  int first_binding;
   /* Index of the first key that has no binding.
      It is useless to try fkey.start larger than that.  */
-  volatile int first_unbound;
+  int first_unbound;
 
   /* If t < mock_input, then KEYBUF[t] should be read as the next
      input key.
@@ -9014,7 +9126,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
      restart_sequence; the loop will read keys from keybuf up until
      mock_input, thus rebuilding the state; and then it will resume
      reading characters from the keyboard.  */
-  volatile int mock_input = 0;
+  int mock_input = 0;
 
   /* If the sequence is unbound in submaps[], then
      keybuf[fkey.start..fkey.end-1] is a prefix in Vfunction_key_map,
@@ -9024,28 +9136,28 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
      should hold off until t reaches them.  We do this when we've just
      recognized a function key, to avoid searching for the function
      key's again in Vfunction_key_map.  */
-  volatile keyremap fkey;
+  keyremap fkey;
 
   /* Likewise, for key_translation_map and input-decode-map.  */
-  volatile keyremap keytran, indec;
+  keyremap keytran, indec;
 
   /* Non-zero 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. */
-  volatile int shift_translated = 0;
+  int 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.
      While we're reading, we keep the event here.  */
-  volatile Lisp_Object delayed_switch_frame;
+  Lisp_Object delayed_switch_frame;
 
   /* See the comment below... */
 #if defined (GOBBLE_FIRST_EVENT)
   Lisp_Object first_event;
 #endif
 
-  volatile Lisp_Object original_uppercase;
-  volatile int original_uppercase_position = -1;
+  Lisp_Object original_uppercase;
+  int original_uppercase_position = -1;
 
   /* Gets around Microsoft compiler limitations.  */
   int dummyflag = 0;
@@ -9053,7 +9165,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
   struct buffer *starting_buffer;
 
   /* List of events for which a fake prefix key has been generated.  */
-  volatile Lisp_Object fake_prefixed_keys = Qnil;
+  Lisp_Object fake_prefixed_keys = Qnil;
 
 #if defined (GOBBLE_FIRST_EVENT)
   int junk;
@@ -9071,7 +9183,14 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
   if (INTERACTIVE)
     {
       if (!NILP (prompt))
-       echo_prompt (prompt);
+       {
+         /* Install the string STR as the beginning of the string of
+            echoing, so that it serves as a prompt for the next
+            character.  */
+         current_kboard->echo_string = prompt;
+         current_kboard->echo_after_prompt = SCHARS (prompt);
+         echo_now ();
+       }
       else if (cursor_in_echo_area
               && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
               && NILP (Fzerop (Vecho_keystrokes)))
@@ -9167,8 +9286,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
       if (!NILP (orig_keymap))
        submaps[nmaps++] = orig_keymap;
 
-      bcopy (maps, (void *) (submaps + nmaps),
-            nminor * sizeof (submaps[0]));
+      memcpy (submaps + nmaps, maps, nminor * sizeof (submaps[0]));
 
       nmaps += nminor;
 
@@ -9211,13 +9329,13 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
          (say, a mouse click on the mode line which is being treated
          as [mode-line (mouse-...)], then we backtrack to this point
          of keybuf.  */
-      volatile int last_real_key_start;
+      int last_real_key_start;
 
       /* These variables are analogous to echo_start and keys_start;
         while those allow us to restart the entire key sequence,
         echo_local_start and keys_local_start allow us to throw away
         just one key.  */
-      volatile int echo_local_start, keys_local_start, local_first_binding;
+      int echo_local_start, keys_local_start, local_first_binding;
 
       eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
       eassert (indec.start <= indec.end);
@@ -10083,10 +10201,7 @@ The optional fifth argument COMMAND-LOOP, if non-nil, means
 that this key sequence is being read by something that will
 read commands one after another.  It should be nil if the caller
 will read just one key sequence.  */)
-  (prompt, continue_echo, dont_downcase_last, can_return_switch_frame,
-   command_loop)
-     Lisp_Object prompt, continue_echo, dont_downcase_last;
-     Lisp_Object can_return_switch_frame, command_loop;
+  (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object command_loop)
 {
   Lisp_Object keybuf[30];
   register int i;
@@ -10102,7 +10217,7 @@ will read just one key sequence.  */)
   specbind (Qinput_method_use_echo_area,
            (NILP (command_loop) ? Qt : Qnil));
 
-  bzero (keybuf, sizeof keybuf);
+  memset (keybuf, 0, sizeof keybuf);
   GCPRO1 (keybuf[0]);
   gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
 
@@ -10143,10 +10258,7 @@ will read just one key sequence.  */)
 DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
        Sread_key_sequence_vector, 1, 5, 0,
        doc: /* Like `read-key-sequence' but always return a vector.  */)
-     (prompt, continue_echo, dont_downcase_last, can_return_switch_frame,
-      command_loop)
-     Lisp_Object prompt, continue_echo, dont_downcase_last;
-     Lisp_Object can_return_switch_frame, command_loop;
+  (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object command_loop)
 {
   Lisp_Object keybuf[30];
   register int i;
@@ -10162,7 +10274,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
   specbind (Qinput_method_use_echo_area,
            (NILP (command_loop) ? Qt : Qnil));
 
-  bzero (keybuf, sizeof keybuf);
+  memset (keybuf, 0, sizeof keybuf);
   GCPRO1 (keybuf[0]);
   gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
 
@@ -10206,13 +10318,11 @@ The argument KEYS specifies the value to use instead of (this-command-keys)
 when reading the arguments; if it is nil, (this-command-keys) is used.
 The argument SPECIAL, if non-nil, means that this command is executing
 a special event, so ignore the prefix argument and don't clear it.  */)
-     (cmd, record_flag, keys, special)
-     Lisp_Object cmd, record_flag, keys, special;
+  (Lisp_Object cmd, Lisp_Object record_flag, Lisp_Object keys, Lisp_Object special)
 {
   register Lisp_Object final;
   register Lisp_Object tem;
   Lisp_Object prefixarg;
-  extern int debug_on_next_call;
 
   debug_on_next_call = 0;
 
@@ -10296,17 +10406,15 @@ the numeric argument to this command.
 
 Noninteractively, the argument PREFIXARG is the prefix argument to
 give to the command you invoke, if it asks for an argument.  */)
-     (prefixarg)
-     Lisp_Object prefixarg;
+  (Lisp_Object prefixarg)
 {
   Lisp_Object function;
-  char buf[40];
-  int saved_last_point_position;
+  EMACS_INT saved_last_point_position;
   Lisp_Object saved_keys, saved_last_point_position_buffer;
   Lisp_Object bindings, value;
   struct gcpro gcpro1, gcpro2, gcpro3;
 #ifdef HAVE_WINDOW_SYSTEM
-  /* The call to Fcompleting_read wil start and cancel the hourglass,
+  /* The call to Fcompleting_read will start and cancel the hourglass,
      but if the hourglass was already scheduled, this means that no
      hourglass will be shown for the actual M-x command itself.
      So we restart it if it is already scheduled.  Note that checking
@@ -10319,31 +10427,9 @@ give to the command you invoke, if it asks for an argument.  */)
                        XVECTOR (this_command_keys)->contents);
   saved_last_point_position_buffer = last_point_position_buffer;
   saved_last_point_position = last_point_position;
-  buf[0] = 0;
   GCPRO3 (saved_keys, prefixarg, saved_last_point_position_buffer);
 
-  if (EQ (prefixarg, Qminus))
-    strcpy (buf, "- ");
-  else if (CONSP (prefixarg) && XINT (XCAR (prefixarg)) == 4)
-    strcpy (buf, "C-u ");
-  else if (CONSP (prefixarg) && INTEGERP (XCAR (prefixarg)))
-    sprintf (buf, "%ld ", (long) XINT (XCAR (prefixarg)));
-  else if (INTEGERP (prefixarg))
-    sprintf (buf, "%ld ", (long) XINT (prefixarg));
-
-  /* This isn't strictly correct if execute-extended-command
-     is bound to anything else.  Perhaps it should use
-     this_command_keys?  */
-  strcat (buf, "M-x ");
-
-  /* Prompt with buf, and then read a string, completing from and
-     restricting to the set of all defined commands.  Don't provide
-     any initial input.  Save the command read on the extended-command
-     history list. */
-  function = Fcompleting_read (build_string (buf),
-                              Vobarray, Qcommandp,
-                              Qt, Qnil, Qextended_command_history, Qnil,
-                              Qnil);
+  function = call0 (intern ("read-extended-command"));
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (hstarted) start_hourglass ();
@@ -10527,7 +10613,7 @@ DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 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 (!NILP (Vunread_command_events) || unread_command_char != -1
       || !NILP (Vunread_post_input_method_events)
@@ -10542,7 +10628,7 @@ if there is a doubt, the value is t.  */)
 
 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 val;
@@ -10552,12 +10638,10 @@ DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0,
   else
     {
       val = Fvector (NUM_RECENT_KEYS, keys);
-      bcopy (keys + recent_keys_index,
-            XVECTOR (val)->contents,
-            (NUM_RECENT_KEYS - recent_keys_index) * sizeof (Lisp_Object));
-      bcopy (keys,
-            XVECTOR (val)->contents + NUM_RECENT_KEYS - recent_keys_index,
-            recent_keys_index * sizeof (Lisp_Object));
+      memcpy (XVECTOR (val)->contents, keys + recent_keys_index,
+             (NUM_RECENT_KEYS - recent_keys_index) * sizeof (Lisp_Object));
+      memcpy (XVECTOR (val)->contents + NUM_RECENT_KEYS - recent_keys_index,
+             keys, recent_keys_index * sizeof (Lisp_Object));
       return val;
     }
 }
@@ -10569,7 +10653,7 @@ the last key sequence that has been read.
 The value is a string or a vector.
 
 See also `this-command-keys-vector'.  */)
-     ()
+  (void)
 {
   return make_event_array (this_command_key_count,
                           XVECTOR (this_command_keys)->contents);
@@ -10581,7 +10665,7 @@ However, if the command has called `read-key-sequence', it returns
 the last key sequence that has been read.
 
 See also `this-command-keys'.  */)
-     ()
+  (void)
 {
   return Fvector (this_command_key_count,
                  XVECTOR (this_command_keys)->contents);
@@ -10595,7 +10679,7 @@ the command loop or by `read-key-sequence'.
 Unlike `this-command-keys', this function's value
 does not include prefix arguments.
 The value is always a vector.  */)
-     ()
+  (void)
 {
   return Fvector (this_command_key_count
                  - this_single_command_key_start,
@@ -10611,7 +10695,7 @@ the command loop or by `read-key-sequence'.
 Unlike `this-single-command-keys', this function's value
 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));
@@ -10629,7 +10713,7 @@ both in the value of (this-command-keys) and in echoing.
 To achieve this, `universal-argument-other-key' calls
 `reset-this-command-lengths', which discards the record of reading
 these events the first time.  */)
-     ()
+  (void)
 {
   this_command_key_count = before_command_key_count;
   if (this_command_key_count < this_single_command_key_start)
@@ -10649,8 +10733,7 @@ DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
        doc: /* Clear out the vector that `this-command-keys' returns.
 Also clear the record of the last 100 events, unless optional arg
 KEEP-RECORD is non-nil.  */)
-     (keep_record)
-     Lisp_Object keep_record;
+  (Lisp_Object keep_record)
 {
   int i;
 
@@ -10669,7 +10752,7 @@ KEEP-RECORD is non-nil.  */)
 
 DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
        doc: /* Return the current depth in recursive edits.  */)
-     ()
+  (void)
 {
   Lisp_Object temp;
   XSETFASTINT (temp, command_loop_level + minibuf_level);
@@ -10680,8 +10763,7 @@ DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
        "FOpen dribble file: ",
        doc: /* Start writing all keyboard characters to a dribble file called FILE.
 If FILE is nil, close any open dribble file.  */)
-     (file)
-     Lisp_Object file;
+  (Lisp_Object file)
 {
   if (dribble)
     {
@@ -10703,7 +10785,7 @@ If FILE is nil, close any open dribble file.  */)
 DEFUN ("discard-input", Fdiscard_input, Sdiscard_input, 0, 0, 0,
        doc: /* Discard the contents of the terminal input buffer.
 Also end any kbd macro being defined.  */)
-     ()
+  (void)
 {
   if (!NILP (current_kboard->defining_kbd_macro))
     {
@@ -10738,8 +10820,7 @@ After resumption run the normal hook `suspend-resume-hook'.
 
 Some operating systems cannot stop the Emacs process and resume it later.
 On such systems, Emacs starts a subshell instead of suspending.  */)
-     (stuffstring)
-     Lisp_Object stuffstring;
+  (Lisp_Object stuffstring)
 {
   int count = SPECPDL_INDEX ();
   int old_height, old_width;
@@ -10796,7 +10877,7 @@ stuff_buffered_input (Lisp_Object stuffstring)
 
   if (STRINGP (stuffstring))
     {
-      register int count;
+      register EMACS_INT count;
 
       p = SDATA (stuffstring);
       count = SBYTES (stuffstring);
@@ -11059,8 +11140,7 @@ If INTERRUPT is non-nil, Emacs will use input interrupts;
 otherwise Emacs uses CBREAK mode.
 
 See also `current-input-mode'.  */)
-     (interrupt)
-     Lisp_Object interrupt;
+  (Lisp_Object interrupt)
 {
   int new_interrupt_input;
 #ifdef SIGIO
@@ -11087,10 +11167,10 @@ See also `current-input-mode'.  */)
 #ifndef DOS_NT
       /* this causes startup screen to be restored and messes with the mouse */
       reset_all_sys_modes ();
-#endif
       interrupt_input = new_interrupt_input;
-#ifndef DOS_NT
       init_all_sys_modes ();
+#else
+      interrupt_input = new_interrupt_input;
 #endif
 
 #ifdef POLL_FOR_INPUT
@@ -11110,8 +11190,7 @@ This setting only has an effect on tty terminals and only when
 Emacs reads input in CBREAK mode; see `set-input-interrupt-mode'.
 
 See also `current-input-mode'.  */)
-       (flow, terminal)
-       Lisp_Object flow, terminal;
+  (Lisp_Object flow, Lisp_Object terminal)
 {
   struct terminal *t = get_terminal (terminal, 1);
   struct tty_display_info *tty;
@@ -11153,8 +11232,7 @@ It may be a terminal object, a frame, or nil for the terminal used by
 the currently selected frame.
 
 See also `current-input-mode'.  */)
-       (meta, terminal)
-       Lisp_Object meta, terminal;
+  (Lisp_Object meta, Lisp_Object terminal)
 {
   struct terminal *t = get_terminal (terminal, 1);
   struct tty_display_info *tty;
@@ -11195,8 +11273,7 @@ This function only has an effect on the controlling tty of the Emacs
 process.
 
 See also `current-input-mode'.  */)
-       (quit)
-       Lisp_Object quit;
+  (Lisp_Object quit)
 {
   struct terminal *t = get_named_tty ("/dev/tty");
   struct tty_display_info *tty;
@@ -11233,8 +11310,7 @@ Third arg META t means accept 8-bit input (for a Meta key).
  Otherwise, accept 8-bit input and don't use the top bit for Meta.
 Optional fourth arg QUIT if non-nil specifies character to use for quitting.
 See also `current-input-mode'.  */)
-     (interrupt, flow, meta, quit)
-     Lisp_Object interrupt, flow, meta, quit;
+  (Lisp_Object interrupt, Lisp_Object flow, Lisp_Object meta, Lisp_Object quit)
 {
   Fset_input_interrupt_mode (interrupt);
   Fset_output_flow_control (flow, Qnil);
@@ -11258,7 +11334,7 @@ The value is a list of the form (INTERRUPT FLOW META QUIT), where
   QUIT is the character Emacs currently uses to quit.
 The elements of this list correspond to the arguments of
 `set-input-mode'.  */)
-     ()
+  (void)
 {
   Lisp_Object val[4];
   struct frame *sf = XFRAME (selected_frame);
@@ -11292,8 +11368,7 @@ The return value is similar to a mouse click position:
    (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
     IMAGE (DX . DY) (WIDTH . HEIGHT))
 The `posn-' functions access elements of such lists.  */)
-  (x, y, frame_or_window, whole)
-     Lisp_Object x, y, frame_or_window, whole;
+  (Lisp_Object x, Lisp_Object y, Lisp_Object frame_or_window, Lisp_Object whole)
 {
   CHECK_NATNUM (x);
   CHECK_NATNUM (y);
@@ -11319,7 +11394,7 @@ The `posn-' functions access elements of such lists.  */)
 
   CHECK_LIVE_FRAME (frame_or_window);
 
-  return make_lispy_position (XFRAME (frame_or_window), &x, &y, 0);
+  return make_lispy_position (XFRAME (frame_or_window), x, y, 0);
 }
 
 DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0,
@@ -11333,8 +11408,7 @@ to the given buffer position:
    (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
     IMAGE (DX . DY) (WIDTH . HEIGHT))
 The `posn-' functions access elements of such lists.  */)
-  (pos, window)
-     Lisp_Object pos, window;
+  (Lisp_Object pos, Lisp_Object window)
 {
   Lisp_Object tem;
 
@@ -11473,11 +11547,11 @@ init_keyboard (void)
          Emacs on SIGINT when there are no termcap frames on the
          controlling terminal. */
       signal (SIGINT, interrupt_signal);
-#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
+#ifndef DOS_NT
       /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
         SIGQUIT and we can't tell which one it will give us.  */
       signal (SIGQUIT, interrupt_signal);
-#endif /* HAVE_TERMIO */
+#endif /* not DOS_NT */
     }
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
 #ifdef SIGIO
@@ -11511,11 +11585,11 @@ init_keyboard (void)
    event header symbols and put properties on them.  */
 struct event_head {
   Lisp_Object *var;
-  char *name;
+  const char *name;
   Lisp_Object *kind;
 };
 
-struct event_head head_table[] = {
+static const struct event_head head_table[] = {
   {&Qmouse_movement,      "mouse-movement",      &Qmouse_movement},
   {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement},
   {&Qswitch_frame,        "switch-frame",        &Qswitch_frame},
@@ -11634,6 +11708,8 @@ syms_of_keyboard (void)
   staticpro (&QCradio);
   QClabel = intern_c_string (":label");
   staticpro (&QClabel);
+  QCvert_only = intern_c_string (":vert-only");
+  staticpro (&QCvert_only);
 
   Qmode_line = intern_c_string ("mode-line");
   staticpro (&Qmode_line);
@@ -11688,6 +11764,13 @@ syms_of_keyboard (void)
   Qinput_method_function = intern_c_string ("input-method-function");
   staticpro (&Qinput_method_function);
 
+  Qx_set_selection = intern_c_string ("x-set-selection");
+  staticpro (&Qx_set_selection);
+  QPRIMARY = intern_c_string ("PRIMARY");
+  staticpro (&QPRIMARY);
+  Qhandle_switch_frame = intern_c_string ("handle-switch-frame");
+  staticpro (&Qhandle_switch_frame);
+
   Qinput_method_exit_on_first_char = intern_c_string ("input-method-exit-on-first-char");
   staticpro (&Qinput_method_exit_on_first_char);
   Qinput_method_use_echo_area = intern_c_string ("input-method-use-echo-area");
@@ -11700,7 +11783,7 @@ syms_of_keyboard (void)
   last_point_position_window = Qnil;
 
   {
-    struct event_head *p;
+    const struct event_head *p;
 
     for (p = head_table;
         p < head_table + (sizeof (head_table) / sizeof (head_table[0]));
@@ -12083,6 +12166,12 @@ might happen repeatedly and make Emacs nonfunctional.  */);
 The elements of the list are event types that may have menu bar bindings.  */);
   Vmenu_bar_final_items = Qnil;
 
+  DEFVAR_LISP ("tool-bar-separator-image-expression", &Vtool_bar_separator_image_expression,
+    doc: /* Expression evaluating to the image spec for a tool-bar separator.
+This is used internally by graphical displays that do not render
+tool-bar separators natively.  Otherwise it is unused (e.g. on GTK).  */);
+  Vtool_bar_separator_image_expression = Qnil;
+
   DEFVAR_KBOARD ("overriding-terminal-local-map",
                 Voverriding_terminal_local_map,
                 doc: /* Per-terminal keymap that overrides all other local keymaps.
@@ -12295,6 +12384,23 @@ Help functions bind this to allow help on disabled menu items
 and tool-bar buttons.  */);
   Venable_disabled_menus_and_buttons = Qnil;
 
+  DEFVAR_LISP ("select-active-regions",
+              &Vselect_active_regions,
+              doc: /* If non-nil, an active region automatically becomes the window selection.
+If the value is `only', only temporarily active regions (usually made
+by mouse-dragging or shift-selection) set the window selection.
+
+This takes effect only when Transient Mark mode is enabled.  */);
+  Vselect_active_regions = Qt;
+
+  DEFVAR_LISP ("saved-region-selection",
+              &Vsaved_region_selection,
+              doc: /* Contents of active region prior to buffer modification.
+If `select-active-regions' is non-nil, Emacs sets this to the
+text in the region before modifying the buffer.  The next
+`deactivate-mark' call uses this to set the window selection.  */);
+  Vsaved_region_selection = Qnil;
+
   /* Create the initial keyboard. */
   initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
   init_kboard (initial_kboard);
@@ -12409,5 +12515,3 @@ mark_kboards (void)
   }
 }
 
-/* arch-tag: 774e34d7-6d31-42f3-8397-e079a4e4c9ca
-   (do not change this comment) */