Support menus on text-mode terminals.
authorEli Zaretskii <eliz@gnu.org>
Tue, 8 Oct 2013 17:49:20 +0000 (20:49 +0300)
committerEli Zaretskii <eliz@gnu.org>
Tue, 8 Oct 2013 17:49:20 +0000 (20:49 +0300)
 src/xterm.h (xw_popup_dialog): Add prototype.
 src/xmenu.c (Fx_popup_dialog): Function moved to menu.c.
 (xmenu_show): Block input here, instead in Fx_popup_menu.
 (xw_popup_dialog): New function, with X-specific bits of popup
 dialogs.
 src/xdisp.c (deep_copy_glyph_row, display_tty_menu_item): New
 functions.
 src/window.c (Fset_window_configuration): Use run-time tests of the
 frame type instead of compile-time conditionals, when menu-bar
 lines are considered.
 src/w32term.h (w32con_hide_cursor, w32con_show_cursor)
 (w32_popup_dialog): New prototypes.
 src/w32menu.c (Fx_popup_dialog): Function deleted.
 (w32_popup_dialog): New function, with w32 specific bits of popup
 dialogs.  Block input here.
 src/w32inevt.c (w32_console_read_socket): Minor change to add
 debugging TTY events.
 src/w32fns.c (show_hourglass): If returning early because the frame
 is not a GUI frame, unblock input.
 src/w32console.c (w32con_hide_cursor, w32con_show_cursor, cursorX)
 (cursorY): New functions.
 src/termhooks.h (cursorX, cursorY): Prototypes of functions on
 WINDOWSNT, macros that call curX and curY elsewhere.
 src/termchar.h (struct tty_display_info) <showing_menu>: New flag.
 src/term.c (tty_hide_cursor, tty_show_cursor) [WINDOWSNT]: Call w32
 specific function to hide and show cursor on a text-mode terminal.
 (tty_menu_struct, struct tty_menu_state): New structures.
 (tty_menu_create, tty_menu_make_room, tty_menu_search_pane)
 (tty_menu_calc_size, mouse_get_xy, tty_menu_display)
 (have_menus_p, tty_menu_add_pane, tty_menu_add_selection)
 (tty_menu_locate, save_and_enable_current_matrix)
 (restore_desired_matrix, screen_update, read_menu_input)
 (tty_menu_activate, tty_menu_destroy, tty_menu_help_callback)
 (tty_pop_down_menu, tty_menu_last_menubar_item)
 (tty_menu_new_item_coords, tty_menu_show): New functions.
 (syms_of_term): New DEFSYMs for tty-menu-* symbols.
 src/nsterm.h (ns_popup_dialog): Adjust prototype.
 src/nsmenu.m (ns_menu_show): Block and unblock input here, instead
 of in x-popup-menu.
 (ns_popup_dialog): Adapt order of arguments to the other
 *_menu_show implementations.
 (Fx_popup_dialog): Function deleted.
 src/msdos.c (x_set_menu_bar_lines): Delete unused function.
 src/menu.h (tty_menu_show, menu_item_width): provide prototypes.
 src/menu.c (have_boxes): New function.
 (single_keymap_panes): Use it instead of a compile-time
 conditional.
 (single_menu_item): Use run-time tests of the frame type instead
 of compile-time conditionals.
 (encode_menu_string): New function.
 (list_of_items, list_of_panes): Use it instead of ENCODE_STRING
 the macro, since different types of frame need different encoding
 of menu items.
 (digest_single_submenu): Use run-time tests of frame type instead
 of, or in addition to, compile-time conditionals.
 (menu_item_width, Fmenu_bar_menu_at_x_y): New functions.
 (Fx_popup_menu): Detect when the function is called from keyboard
 on a TTY.  Don't barf when invoked on a text-mode frame.  Check
 frame type at run time, instead of compile-time conditionals for
 invoking terminal-specific menu-show functions.  Call
 tty_menu_show on text-mode frames.
 (Fx_popup_dialog): Moved here from xmenu.c.  Test frame types at
 run time to determine which alternative to invoke; support dialogs
 on TTYs.
 src/keyboard.h <Qmouse_movement>: Declare.
 src/keyboard.c <Qmouse_movement>: Now extern.
 <Qecho_keystrokes>: New static variable.
 (read_key_sequence): Accept an additional argument, a flag to
 prevent redisplay during reading of the key sequence.  All callers
 changed.
 (read_menu_command): New function.
 (read_char): When COMMANDFLAG is -2, do not redisplay and do not
 autosave.
 (toolkit_menubar_in_use): New function.
 (make_lispy_event): Use it instead of a compile-time test.
 src/fns.c (Fyes_or_no_p) [HAVE_MENUS]: Don't condition on
 window-system being available.
 src/editfns.c (Fmessage_box) [HAVE_MENUS]: Don't condition the call
 to x-popup-dialog on the frame type, they all now support popup
 dialogs.
 src/dispnew.c (save_current_matrix): Save the margin areas.
 (restore_current_matrix): Restore margin areas.
 (update_frame_with_menu): New function.
 src/dispextern.h (display_tty_menu_item, update_frame_with_menu):
 Add prototypes.
 src/alloc.c (make_save_ptr): Now compiled unconditionally.

 lisp/tmm.el (tmm-menubar): Adapt doc string to TTY menus
 functionality.
 lisp/tooltip.el (tooltip-mode): Don't error out on TTYs.
 lisp/menu-bar.el (popup-menu, popup-menu-normalize-position): Moved
 here from mouse.el.
 (popup-menu): Support menu-bar navigation on TTYs using C-f/C-b
 and arrow keys.
 (tty-menu-navigation-map): New map for TTY menu navigation.
 lisp/loadup.el ("tooltip"): Load even if x-show-tip is not available.
 lisp/frame.el (display-mouse-p): Report text-mode mouse as available
 on w32.
 (display-popup-menus-p): Report availability if mouse is
 available; don't condition on window-system.
 lisp/faces.el (tty-menu-enabled-face, tty-menu-disabled-face)
 (tty-menu-selected-face): New faces.

 configure.ac (HAVE_MENUS): Define unconditionally.

 doc/emacs/screen.texi (Menu Bar): Adapt to TTY menus.
 doc/emacs/frames.texi (Frames): Mention menu support on text terminals.
 doc/emacs/files.texi (Visiting): Mention the "File" menu-bar menu.
 doc/emacs/display.texi (Standard Faces): Mention TTY faces for menus.

 doc/lispref/keymaps.texi (Defining Menus, Mouse Menus, Menu Bar): Modify
 wording to the effect that menus are supported on TTYs.
 doc/lisprefframes.texi (Pop-Up Menus, Dialog Boxes)
 (Display Feature Testing): Update for menu support on TTYs.

  etc/NEWS: Mention the new features.

17 files changed:
1  2 
ChangeLog
doc/emacs/ChangeLog
doc/lispref/ChangeLog
etc/NEWS
lisp/ChangeLog
lisp/faces.el
src/ChangeLog
src/alloc.c
src/dispextern.h
src/dispnew.c
src/editfns.c
src/frame.h
src/keyboard.c
src/nsterm.h
src/term.c
src/window.c
src/xdisp.c

diff --cc ChangeLog
+++ b/ChangeLog
@@@ -1,28 -1,3 +1,32 @@@
++2013-10-08  Eli Zaretskii  <eliz@gnu.org>
++
++      * configure.ac (HAVE_MENUS): Define unconditionally.
++
 +2013-10-07  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      Improve support for popcount and counting trailing zeros (Bug#15550).
 +      Do this by using the Gnulib modules for this.
 +      This should generate faster code on non-GCC, non-MSC platforms,
 +      and make the code a bit more portable, at least in theory.
 +      * lib/count-one-bits.c, lib/count-one-bits.h:
 +      * lib/count-trailing-zeros.c, lib/count-trailing-zeros.h:
 +      * m4/count-one-bits.m4, m4/count-trailing-zeros.m4:
 +      New files, copied from gnulib.
 +      * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
 +
 +2013-10-04  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      Use hardware support for byteswapping on glibc x86 etc.
 +      * lib/byteswap.in.h, m4/byteswap.m4: New files, copied from Gnulib.
 +      * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
 +
 +2013-10-03  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      Merge from gnulib, incorporating:
 +      2013-10-02 verify: new macro 'assume'
 +      2013-09-26 dup2, dup3: work around another cygwin crasher
 +      2013-09-26 getdtablesize: work around cygwin issue
 +
  2013-09-25  Paul Eggert  <eggert@cs.ucla.edu>
  
        Merge from gnulib, incorporating:
@@@ -1,11 -1,13 +1,22 @@@
 -2013-10-02  Eli Zaretskii  <eliz@gnu.org>
++2013-10-08  Eli Zaretskii  <eliz@gnu.org>
++      Support menus on text-mode terminals.
+       * screen.texi (Menu Bar): Adapt to TTY menus.
+       * frames.texi (Frames): Mention menu support on text terminals.
+       * files.texi (Visiting): Mention the "File" menu-bar menu.
+       * display.texi (Standard Faces): Mention TTY faces for menus.
 +2013-10-06  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * cal-xtra.texi (Calendar Customizing, Diary Display): Remove @refill.
 +
 +2013-09-29  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * fortran-xtra.texi (Fortran Abbrev): Remove @refill.
 +
  2013-09-26  Xue Fuqiao  <xfq.free@gmail.com>
  
        * dired.texi (Flagging Many Files): Use @emph instead of @strong.
@@@ -1,25 -1,11 +1,34 @@@
 -2013-10-03  Eli Zaretskii  <eliz@gnu.org>
++2013-10-08  Eli Zaretskii  <eliz@gnu.org>
++      Support menus on text-mode terminals.
+       * keymaps.texi (Defining Menus, Mouse Menus, Menu Bar): Modify
+       wording to the effect that menus are supported on TTYs.
+       * frames.texi (Pop-Up Menus, Dialog Boxes)
+       (Display Feature Testing): Update for menu support on TTYs.
 +2013-10-07  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * tips.texi (Comment Tips): Discourage use of triple semi-colons for
 +      non-headings.
 +
 +2013-10-05  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * syntax.texi (Categories): Add an index for category sets.
 +
 +2013-10-03  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * syntax.texi (Syntax Flags):
 +      (Syntax Table Functions): Add indexes.
 +
 +2013-10-02  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * syntax.texi (Syntax Class Table): Add an index for syntax class table.
 +
 +2013-09-29  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * searching.texi (Regexp Search): Refine.
 +
  2013-09-22  Xue Fuqiao  <xfq.free@gmail.com>
  
        * nonascii.texi (Default Coding Systems): Typo fix.
diff --cc etc/NEWS
Simple merge
diff --cc lisp/ChangeLog
++2013-10-08  Eli Zaretskii  <eliz@gnu.org>
++
++      Support menus on text-mode terminals.
++      * tmm.el (tmm-menubar): Adapt doc string to TTY menus
++      functionality.
++
++      * tooltip.el (tooltip-mode): Don't error out on TTYs.
++
++      * menu-bar.el (popup-menu, popup-menu-normalize-position): Moved
++      here from mouse.el.
++      (popup-menu): Support menu-bar navigation on TTYs using C-f/C-b
++      and arrow keys.
++      (tty-menu-navigation-map): New map for TTY menu navigation.
++
++      * loadup.el ("tooltip"): Load even if x-show-tip is not available.
++
++      * frame.el (display-mouse-p): Report text-mode mouse as available
++      on w32.
++      (display-popup-menus-p): Report availability if mouse is
++      available; don't condition on window-system.
++
++      * faces.el (tty-menu-enabled-face, tty-menu-disabled-face)
++      (tty-menu-selected-face): New faces.
++
 +2013-10-08  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * emacs-lisp/lisp-mode.el: Font-lock cl-lib constructs.
 +      (lisp-el-font-lock-keywords, lisp-el-font-lock-keywords-1)
 +      (lisp-el-font-lock-keywords-2, lisp-cl-font-lock-keywords)
 +      (lisp-cl-font-lock-keywords-1, lisp-cl-font-lock-keywords-2):
 +      New constants.
 +      (lisp-mode-variables): New `elisp' argument.
 +      (emacs-lisp-mode): Use it.
 +      * font-lock.el (lisp-font-lock-keywords, lisp-font-lock-keywords-1)
 +      (lisp-font-lock-keywords-2): Move to lisp-mode.el.
 +
 +      * indent.el: Use lexical-binding.
 +      (indent-region): Add progress reporter.
 +      (tab-stop-list): Make it implicitly extend to infinity by repeating the
 +      last step.
 +      (indent--next-tab-stop): New function to implement this behavior.
 +      (tab-to-tab-stop, move-to-tab-stop): Use it.
 +
 +2013-10-08  Teemu Likonen  <tlikonen@iki.fi>
 +
 +      * indent.el (indent-rigidly--current-indentation): New function.
 +      (indent-rigidly-map): New var.
 +      (indent-rigidly): Use it to provide interactive mode (bug#8196).
 +
 +2013-10-08  Bastien Guerry  <bzg@gnu.org>
 +
 +      * register.el (insert-register): Fix 2013-10-07T01:28:34Z!sdl.web@gmail.com.
 +
 +2013-10-08  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * progmodes/perl-mode.el: Use lexical-binding.
 +      Remove redundant :group args.
 +      (perl-nochange): Change default to be closer to other major modes's
 +      standard behavior.
 +      (perl-indent-line): Don't consider text on current line as a
 +      valid beginning of function from which to indent.
 +
 +      * emacs-lisp/backquote.el (backquote-process): Catch uses of , and ,@
 +      with more than one argument (bug#15538).
 +
 +      * mpc.el (mpc-songs-jump-to): Adjust to different playlist format.
 +
 +      * vc/pcvs.el: Use lexical-binding.
 +      (cvs-temp-buffer, cvs-make-cvs-buffer): Pass some vars in the lexical
 +      environment of `eval'.
 +      (cvs-mode-run, cvs-mode-do): Change `postproc' to be a function rather
 +      than a list of expressions.  Adjust callers.
 +      * vc/pcvs-defs.el (cvs-postprocess): Remove, unused.
 +
 +2013-10-07  Dmitry Gutov  <dgutov@yandex.ru>
 +
 +      * progmodes/ruby-mode.el (ruby-smie--implicit-semi-p): Handle the
 +      case of the dot in a chained method call being on the following line.
 +
 +2013-10-07  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * electric.el (electric-indent-inhibit): New var.
 +      (electric-indent-post-self-insert-function): Use it.
 +      * progmodes/python.el (python-mode): Set it.
 +
 +      * progmodes/ruby-mode.el (ruby-smie-rules): Tweak handling of
 +      open braces.
 +
 +      * emacs-lisp/smie.el (smie-next-sexp): Refine last fix.
 +
 +      * textmodes/css-mode.el (css-smie-rules): Fix indentation (bug#15467).
 +      (css-mode): Use electric-indent-chars.
 +
 +      * nxml/nxml-mode.el: Use lexical-binding and syntax-propertize.
 +      (font-lock-beg, font-lock-end): Move before first use.
 +      (nxml-mode): Use syntax-propertize-function.
 +      (nxml-after-change, nxml-after-change1): Adjust accordingly.
 +      (nxml-extend-after-change-region): Remove.
 +      * nxml/xmltok.el: Use lexical-binding.
 +      (xmltok-save): Use `declare'.
 +      (xmltok-unclosed-reparse-p, xmltok-semi-closed-reparse-p): Remove.
 +      * nxml/nxml-util.el: Use lexical-binding.
 +      (nxml-with-degradation-on-error, nxml-with-invisible-motion):
 +      Use `declare'.
 +      * nxml/nxml-ns.el: Use lexical-binding.
 +      (nxml-ns-save): Use `declare'.
 +      (nxml-ns-prefixes-for): Avoid add-to-list.
 +      * nxml/rng-match.el: Use lexical-binding.
 +      (rng--ipattern): Use cl-defstruct.
 +      (rng-compute-start-tag-open-deriv, rng-compute-start-attribute-deriv)
 +      (rng-cons-group-after, rng-subst-group-after)
 +      (rng-subst-interleave-after, rng-apply-after, rng-compute-data-deriv):
 +      Use closures instead of `(lambda...).
 +
 +2013-10-07  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * net/tramp.el (tramp-handle-insert-file-contents): Improve handling
 +      of BEG and END.
 +
 +      * net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
 +      Use `tramp-handle-insert-file-contents'.
 +      (tramp-gvfs-handle-insert-file-contents): Remove function.
 +
 +      * net/tramp-sh.el (tramp-sh-handle-insert-directory):
 +      Use `save-restriction' in order to keep markers.
 +
 +      * net/trampver.el: Update release number.
 +
 +2013-10-07  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * progmodes/compile.el (compilation-parse-errors):
 +      Use compilation--put-prop.
 +      (compilation--ensure-parse): Check compilation-multiline.
 +
 +      * emacs-lisp/easymenu.el (easy-menu-create-menu): Use closures.
 +
 +      * emacs-lisp/lisp-mode.el (eval-defun-2): Simplify, using
 +      lexical-binding.
 +
 +      * emacs-lisp/tq.el (tq-create): Use a closure instead of `(lambda...).
 +
 +      * progmodes/ruby-mode.el: Fix recently added tests.
 +      (ruby-smie-grammar): Add - and +.
 +      (ruby-smie--redundant-do-p, ruby-smie--forward-id)
 +      (ruby-smie--backward-id): New functions.
 +      (ruby-smie--forward-token, ruby-smie--backward-token): Use them.
 +      (ruby-smie-rules): Handle hanging do.  Get rid of hack, not needed
 +      any more.
 +
 +2013-10-07  Leo Liu  <sdl.web@gmail.com>
 +
 +      * register.el (register-preview-delay)
 +      (register-preview-functions): New variables.
 +      (register-read-with-preview, register-preview)
 +      (register-describe-oneline): New functions.
 +      (point-to-register, window-configuration-to-register)
 +      (frame-configuration-to-register, jump-to-register)
 +      (number-to-register, view-register, insert-register)
 +      (copy-to-register, append-to-register, prepend-to-register)
 +      (copy-rectangle-to-register): Use register-read-with-preview to
 +      read register.  (Bug#15525)
 +
 +2013-10-06  Dato Simó  <dato@net.com.org.es>  (tiny change)
 +
 +      * net/network-stream.el (network-stream-open-starttls): Don't add
 +      --insecure if it's already present, because that gnutls-cli
 +      rejects getting that parameter twice.
 +
 +2013-10-06  Dmitry Gutov  <dgutov@yandex.ru>
 +
 +      * progmodes/ruby-mode.el (ruby-smie-rules): Dedent `ensure'
 +      keyword, too.
 +
 +2013-10-05  Dmitry Gutov  <dgutov@yandex.ru>
 +
 +      * newcomment.el (comment-use-global-state): Change default value
 +      to t, mark obsolete (Bug#15251).
 +      (comment-beginning): In addition to `comment-to-syntax', check the
 +      value of `comment-use-global-state'.
 +
 +2013-10-05  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * progmodes/ruby-mode.el (ruby-use-smie): Change default.
 +      (ruby-comment-column): Follow the global default, by default.
 +      (ruby-smie-grammar): Add assignment syntax.
 +      (ruby-smie--implicit-semi-p): No implicit semi-colon after an
 +      open-paren, a comma, or a \.
 +      (ruby-smie--forward-token, ruby-smie--backward-token): Handle heredocs,
 +      and line continuations.
 +      (ruby-smie-rules): Adjust handling of open-paren, now that it's never
 +      followed by implicit semi-colons.  Add rule for string concatenation
 +      and for indentation at BOB.
 +      (ruby-forward-sexp, ruby-backward-sexp): Adjust for when smie is in use.
 +
 +      * emacs-lisp/smie.el (smie-next-sexp): Don't go back to pos before
 +      calling next-sexp, since next-token may have skipped chars which
 +      next-sexp doesn't know should be skipped!
 +
 +2013-10-05  Leo Liu  <sdl.web@gmail.com>
 +
 +      * progmodes/octave.el (octave-send-region):
 +      Call compilation-forget-errors.
 +
 +2013-10-04  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * vc/vc-svn.el (vc-svn-find-admin-dir):
 +      * vc/vc-rcs.el (vc-rcs-find-admin-dir):
 +      * vc/vc-mtn.el (vc-mtn-find-admin-dir):
 +      * vc/vc-cvs.el (vc-cvs-find-admin-dir):
 +      * vc/vc-arch.el (vc-arch-find-admin-dir): New functions.
 +
 +2013-10-04  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * textmodes/css-mode.el (css-smie-rules): Toplevel's a list (bug#15467).
 +
 +2013-10-04  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * subr.el (read-passwd): Hide chars even when called within a context
 +      where after-change-functions is disabled (bug#15501).
 +      (set-temporary-overlay-map): Don't remove oneself from pre-command-hook
 +      until we removed ourself from overriding-terminal-local-map.
 +
 +2013-10-04  Leo Liu  <sdl.web@gmail.com>
 +
 +      * progmodes/octave.el (inferior-octave-mode):
 +      Call compilation-forget-errors.
 +
 +2013-10-04  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * emacs-lisp/syntax.el (syntax-ppss): Doc fix.
 +
 +2013-10-04  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      * net/secrets.el (secrets-create-collection): Add optional
 +      argument ALIAS.  Use proper Label keyword.  Append ALIAS as
 +      dbus-call-method argument.  (Bug#15516)
 +
 +2013-10-04  Leo Liu  <sdl.web@gmail.com>
 +
 +      * progmodes/octave.el (inferior-octave-error-regexp-alist)
 +      (inferior-octave-compilation-font-lock-keywords): New variables.
 +      (compilation-error-regexp-alist)
 +      (compilation-mode-font-lock-keywords): Defvar to pacify compiler.
 +      (inferior-octave-mode): Use compilation-shell-minor-mode.
 +
 +2013-10-04  Jorgen Schaefer  <forcer@forcix.cx>
 +
 +      * minibuffer.el (completion--replace): Be careful that `end' might be
 +      a marker.
 +
 +2013-10-03  Daiki Ueno  <ueno@gnu.org>
 +
 +      Add support for package signature checking.
 +      * emacs-lisp/package.el (url-http-file-exists-p)
 +      (epg-make-context, epg-context-set-home-directory)
 +      (epg-verify-string, epg-context-result-for)
 +      (epg-signature-status, epg-signature-to-string)
 +      (epg-check-configuration, epg-configuration)
 +      (epg-import-keys-from-file): Declare.
 +      (package-check-signature): New user option.
 +      (package-unsigned-archives): New user option.
 +      (package-desc): Add `signed' field.
 +      (package-load-descriptor): Set `signed' field if .signed file exists.
 +      (package--archive-file-exists-p): New function.
 +      (package--check-signature): New function.
 +      (package-install-from-archive): Check package signature.
 +      (package--download-one-archive): Check archive signature.
 +      (package-delete): Remove .signed file.
 +      (package-import-keyring): New command.
 +      (package-refresh-contents): Import default keyring.
 +      (package-desc-status): Add "unsigned" status.
 +      (describe-package-1, package-menu--print-info)
 +      (package-menu-mark-delete, package-menu--find-upgrades)
 +      (package-menu--status-predicate): Support "unsigned" status.
 +
 +2013-10-03  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * emacs-lisp/cconv.el (cconv-convert, cconv-analyse-form): Adjust for
 +      the new compilation scheme using the new byte-codes.
 +
 +      * emacs-lisp/bytecomp.el (byte-pushcatch, byte-pushconditioncase)
 +      (byte-pophandler): New byte codes.
 +      (byte-goto-ops): Adjust accordingly.
 +      (byte-compile--use-old-handlers): New var.
 +      (byte-compile-catch): Use new byte codes depending on
 +      byte-compile--use-old-handlers.
 +      (byte-compile-condition-case--old): Rename from
 +      byte-compile-condition-case.
 +      (byte-compile-condition-case--new): New function.
 +      (byte-compile-condition-case): New function that dispatches depending
 +      on byte-compile--use-old-handlers.
 +      (byte-compile-unwind-protect): Pass a function to byte-unwind-protect
 +      when we can.
 +
 +      * emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
 +      Optimize under `condition-case' and `catch' if
 +      byte-compile--use-old-handlers is nil.
 +      (disassemble-offset): Handle new bytecodes.
 +
 +2013-10-03  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * subr.el (error): Use `declare'.
 +      (decode-char, encode-char): Use advertised-calling-convention instead
 +      of the docstring to discourage use of the `restriction' arg.
 +
 +2013-10-03  Daiki Ueno  <ueno@gnu.org>
 +
 +      * epg.el (epg-verify-file): Add a comment saying that it does not
 +      notify verification error as a return value nor a signal.
 +      (epg-verify-string): Ditto.
 +
 +2013-10-02  Kevin Rodgers  <kevin.d.rodgers@gmail.com>
 +
 +      * progmodes/compile.el (compilation-start): Try globbing the arg to
 +      `cd' (bug#15417).
 +
 +2013-10-02  Michael Albinus  <michael.albinus@gmx.de>
 +
 +      Sync with Tramp 2.2.8.
 +
 +      * net/tramp-cmds.el (tramp-bug, tramp-append-tramp-buffers):
 +      * net/tramp-cache.el (tramp-cache-print): Use `tramp-compat-funcall'.
 +      * net/trampver.el: Update release number.
 +
 +2013-10-01  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * term/ns-win.el (ns-initialize-window-system): Set locale-coding-system
 +      and default-process-coding-system for darwin only.
 +
 +2013-10-01  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * emacs-lisp/package.el (package-desc): Simplify (bug#15495).
 +
 +2013-10-01  Mitchel Humpherys  <mitch.special@gmail.com>  (tiny change)
 +
 +      * vc/vc-git.el (vc-git-grep): Disable pager.
 +
 +2013-10-01  Dmitry Gutov  <dgutov@yandex.ru>
 +
 +      * emacs-lisp/package.el (package-buffer-info, describe-package-1):
 +      Use :url instead of :homepage, as per
 +      http://lists.gnu.org/archive/html/emacs-devel/2013-09/msg00622.html
 +
 +      * newcomment.el (comment-beginning): When `comment-use-syntax' is
 +      non-nil, use `syntax-ppss' (Bug#15251).
 +
 +2013-09-30  Rüdiger Sonderfeld  <ruediger@c-plusplus.de>
 +
 +      * progmodes/octave.el (inferior-octave-startup-file):
 +      Prefer ~/.emacs.d/init_octave.m.
 +
 +2013-09-29  Dmitry Gutov  <dgutov@yandex.ru>
 +
 +      * emacs-lisp/package.el (package-desc-from-define):
 +      Accept additional arguments as plist, convert them to an alist and store
 +      them in the `extras' slot.
 +      (package-generate-description-file): Convert extras alist back to
 +      plist and append to the `define-package' form arguments.
 +      (package--alist-to-plist): New function.
 +      (package--ac-desc): Add `extras' slot.
 +      (package--add-to-archive-contents): Check if the archive-contents
 +      vector is long enough, and if it is, pass its `extras' slot value
 +      to `package-desc-create'.
 +      (package-buffer-info): Call `lm-homepage', pass the returned value
 +      to `package-desc-from-define'.
 +      (describe-package-1): Render the homepage button (Bug#13291).
 +
 +      * emacs-lisp/package-x.el (package-upload-buffer-internal):
 +      Pass `extras' slot from `package-desc' to `package-make-ac-desc'.
 +
 +2013-09-29  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * term/ns-win.el (ns-initialize-window-system): Set locale-coding-system
 +      and default-process-coding-system to utf-8-unix (Bug#15402).
 +
 +2013-09-29  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * subr.el (looking-back): Do not recommend using looking-back.
 +
 +2013-09-28  Alan Mackenzie  <acm@muc.de>
 +
 +      Fix indentation/fontification of Java enum with "implements".
 +
 +      * progmodes/cc-langs.el (c-postfix-decl-spec-key): New variable, a
 +      regexp which matches "implements", etc., in Java.
 +      * progmodes/cc-engine.el (c-inside-bracelist-p): Check for extra
 +      specifier clauses coming after "enum".
 +      * progmodes/cc-fonts.el (c-font-lock-declarations)
 +      (c-font-lock-enum-tail): Check for extra specifier clauses coming
 +      after "enum".
 +
 +2013-09-28  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * faces.el (region): Change ns_selection_color to
 +      ns_selection_fg_color, add ns_selection_bg_color.
 +
  2013-09-28  Leo Liu  <sdl.web@gmail.com>
  
        * progmodes/octave.el (inferior-octave-completion-table)
diff --cc lisp/faces.el
Simple merge
diff --cc src/ChangeLog
++2013-10-08  Eli Zaretskii  <eliz@gnu.org>
++
++      Support menus on text-mode terminals.
++      * xterm.h (xw_popup_dialog): Add prototype.
++
++      * xmenu.c (Fx_popup_dialog): Function moved to menu.c.
++      (xmenu_show): Block input here, instead in Fx_popup_menu.
++      (xw_popup_dialog): New function, with X-specific bits of popup
++      dialogs.
++
++      * xdisp.c (deep_copy_glyph_row, display_tty_menu_item): New
++      functions.
++
++      * window.c (Fset_window_configuration): Use run-time tests of the
++      frame type instead of compile-time conditionals, when menu-bar
++      lines are considered.
++
++      * w32term.h (w32con_hide_cursor, w32con_show_cursor)
++      (w32_popup_dialog): New prototypes.
++
++      * w32menu.c (Fx_popup_dialog): Function deleted.
++      (w32_popup_dialog): New function, with w32 specific bits of popup
++      dialogs.  Block input here.
++
++      * w32inevt.c (w32_console_read_socket): Minor change to add
++      debugging TTY events.
++
++      * w32fns.c (show_hourglass): If returning early because the frame
++      is not a GUI frame, unblock input.
++
++      * w32console.c (w32con_hide_cursor, w32con_show_cursor, cursorX)
++      (cursorY): New functions.
++
++      * termhooks.h (cursorX, cursorY): Prototypes of functions on
++      WINDOWSNT, macros that call curX and curY elsewhere.
++
++      * termchar.h (struct tty_display_info) <showing_menu>: New flag.
++
++      * term.c (tty_hide_cursor, tty_show_cursor) [WINDOWSNT]: Call w32
++      specific function to hide and show cursor on a text-mode terminal.
++      (tty_menu_struct, struct tty_menu_state): New structures.
++      (tty_menu_create, tty_menu_make_room, tty_menu_search_pane)
++      (tty_menu_calc_size, mouse_get_xy, tty_menu_display)
++      (have_menus_p, tty_menu_add_pane, tty_menu_add_selection)
++      (tty_menu_locate, save_and_enable_current_matrix)
++      (restore_desired_matrix, screen_update, read_menu_input)
++      (tty_menu_activate, tty_menu_destroy, tty_menu_help_callback)
++      (tty_pop_down_menu, tty_menu_last_menubar_item)
++      (tty_menu_new_item_coords, tty_menu_show): New functions.
++      (syms_of_term): New DEFSYMs for tty-menu-* symbols.
++
++      * nsterm.h (ns_popup_dialog): Adjust prototype.
++
++      * nsmenu.m (ns_menu_show): Block and unblock input here, instead
++      of in x-popup-menu.
++      (ns_popup_dialog): Adapt order of arguments to the other
++      *_menu_show implementations.
++      (Fx_popup_dialog): Function deleted.
++
++      * msdos.c (x_set_menu_bar_lines): Delete unused function.
++
++      * menu.h (tty_menu_show, menu_item_width): provide prototypes.
++
++      * menu.c (have_boxes): New function.
++      (single_keymap_panes): Use it instead of a compile-time
++      conditional.
++      (single_menu_item): Use run-time tests of the frame type instead
++      of compile-time conditionals.
++      (encode_menu_string): New function.
++      (list_of_items, list_of_panes): Use it instead of ENCODE_STRING
++      the macro, since different types of frame need different encoding
++      of menu items.
++      (digest_single_submenu): Use run-time tests of frame type instead
++      of, or in addition to, compile-time conditionals.
++      (menu_item_width, Fmenu_bar_menu_at_x_y): New functions.
++      (Fx_popup_menu): Detect when the function is called from keyboard
++      on a TTY.  Don't barf when invoked on a text-mode frame.  Check
++      frame type at run time, instead of compile-time conditionals for
++      invoking terminal-specific menu-show functions.  Call
++      tty_menu_show on text-mode frames.
++      (Fx_popup_dialog): Moved here from xmenu.c.  Test frame types at
++      run time to determine which alternative to invoke; support dialogs
++      on TTYs.
++
++      * keyboard.h <Qmouse_movement>: Declare.
++
++      * keyboard.c <Qmouse_movement>: Now extern.
++      <Qecho_keystrokes>: New static variable.
++      (read_key_sequence): Accept an additional argument, a flag to
++      prevent redisplay during reading of the key sequence.  All callers
++      changed.
++      (read_menu_command): New function.
++      (read_char): When COMMANDFLAG is -2, do not redisplay and do not
++      autosave.
++      (toolkit_menubar_in_use): New function.
++      (make_lispy_event): Use it instead of a compile-time test.
++
++      * fns.c (Fyes_or_no_p) [HAVE_MENUS]: Don't condition on
++      window-system being available.
++
++      * editfns.c (Fmessage_box) [HAVE_MENUS]: Don't condition the call
++      to x-popup-dialog on the frame type, they all now support popup
++      dialogs.
++
++      * dispnew.c (save_current_matrix): Save the margin areas.
++      (restore_current_matrix): Restore margin areas.
++      (update_frame_with_menu): New function.
++
++      * dispextern.h (display_tty_menu_item, update_frame_with_menu):
++      Add prototypes.
++
++      * alloc.c (make_save_ptr): Now compiled unconditionally.
++
 +2013-10-08  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * dispnew.c (set_window_update_flags): Add buffer arg.  Adjust comment.
 +      (redraw_frame, update_frame): Adjust users.
 +      * dispextern.h (set_window_update_flags): Adjust prototype.
 +      * xdisp.c (redisplay_internal): When updating all frames with zero
 +      windows_or_buffers_changed, assume that only the windows that shows
 +      current buffer should be really updated.
 +
 +2013-10-08  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      Do not allocate huge temporary memory areas and objects while encoding
 +      for file I/O, thus reducing an enormous memory usage for large buffers.
 +      See http://lists.gnu.org/archive/html/emacs-devel/2013-10/msg00180.html.
 +      * coding.h (struct coding_system): New member raw_destination.
 +      * coding.c (setup_coding_system): Initialize it to zero.
 +      (encode_coding_object): If raw_destination is set, do not create
 +      dst_object.  Add comment.
 +      * fileio.c (toplevel): New constant E_WRITE_MAX.
 +      (e_write): Do not encode more than E_WRITE_MAX characters per one loop
 +      iteration.  Use raw_destination if E_WRITE_MAX characters is encoded.
 +
 +2013-10-08  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (windowDidExitFullScreen:):
 +      (toggleFullScreen:): Change NS_IMPL_COCOA to HAVE_NATIVE_FS.
 +
 +2013-10-08  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      Fix race where emacs aborts when sent SIGTERM (Bug#15534).
 +      * keyboard.c (unblock_input_to): Don't process pending signals
 +      if a fatal error is in progress.
 +
 +      * lisp.h (bits_word, BITS_WORD_MAX): New type and macro.
 +      All uses of 'size_t' and 'SIZE_MAX' changed to use them, when
 +      they're talking about words in Lisp bool vectors.
 +      (BITS_PER_BITS_WORD): Rename from BITS_PER_SIZE_T.  All uses changed.
 +      * data.c (popcount_bits_word): Rename from popcount_size_t.
 +      (bits_word_to_host_endian): Rename from size_t_to_host_endian.
 +      All uses changed.
 +
 +2013-10-07  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      Improve support for popcount and counting trailing zeros (Bug#15550).
 +      * data.c: Include <count-one-bits.h>, <count-trailing-zeros.h>.
 +      (USE_MSC_POPCOUNT, POPCOUNT_STATIC_INLINE)
 +      (NEED_GENERIC_POPCOUNT, popcount_size_t_generic)
 +      (popcount_size_t_msc, popcount_size_t_gcc):
 +      Remove; now done by Gnulib.
 +      (popcount_size_t): Now a macro that defers to Gnulib.
 +      (count_trailing_zero_bits): Return int, for consistency with
 +      Gnulib and because Emacs prefers signed to unsigned int.
 +      Don't assume that size_t is either unsigned int or unsigned long
 +      or unsigned long long.
 +      (size_t_to_host_endian): Do not assume that size_t is either
 +      exactly 32 or exactly 64 bits wide.
 +      * lisp.h (BITS_PER_SIZE_T): Define consistently with BITS_PER_LONG
 +      etc., so that it's now an enum constant, not a macro.
 +      No need to assume that it's either 32 or 64.
 +
 +2013-10-07  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (windowDidEnterFullScreen:): setPresentationOptions only
 +      on >= 10.7.
 +
 +2013-10-07  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * insdel.c (insert_from_gap): Prefer ptrdiff_t to int where needed.
 +      * xdisp.c (handle_fontified_prop): Likewise.  Use bool for boolean.
 +
 +2013-10-07  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      emacs_read and emacs_write now use void *, not char *.
 +      * alloc.c (valid_pointer_p) [!WINDOWSNT]: Remove now-unnecessary cast.
 +      * sysdep.c (emacs_read, emacs_write, emacs_write_sig):
 +      Buffer arg is now void *, not char *.  This matches plain
 +      'read' and 'write' better, and avoids a constraint violation
 +      on Solaris 9 with Oracle Studio.
 +
 +2013-10-07  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * alloc.c (Fmake_string): For ASCII char initializer, prefer
 +      memset to explicit loop.  Otherwise copy largest possible chunk
 +      from initialized to uninitialized part, thus allowing the longer
 +      memcpy runs and reducing the number of loop iterations.
 +
 +2013-10-06  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (ns_update_begin): If native fullscreen and no toolbar,
 +      hide toolbar (Bug#15388).
 +      (windowDidEnterFullScreen:): If presentation options are zero,
 +      set them here (Bug#15388).
 +      (ns_update_auto_hide_menu_bar): Remove runtime check.
 +      Don't auto hide dock unless menubar is also auto hidden.
 +
 +2013-10-05  Xue Fuqiao  <xfq.free@gmail.com>
 +
 +      * editfns.c (message): Mention batch mode in doc string.
 +
 +2013-10-05  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (check_native_fs): Remove erroneous comment.
 +
 +2013-10-04  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * xdisp.c (redisplay_internal): Simplify because scan_for_column now
 +      uses find_newline instead of scan_newline and so doesn't move point.
 +
 +2013-10-04  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      Use hardware support for byteswapping on glibc x86 etc.
 +      On Fedora 19 x86-64, the new bswap_64 needs 1 instruction,
 +      whereas the old swap64 needed 30.
 +      * fringe.c (init_fringe_bitmap) [WORDS_BIGENDIAN]:
 +      * sound.c (le2hl, le2hs, be2hl) [!WINDOWSNT]:
 +      Use byteswap.h's macros to swap bytes.
 +      * lisp.h (swap16, swap32, swap64): Remove.
 +      All uses replaced by bswap_16, bswap_32, bswap_64.
 +
 +      * bytecode.c (exec_byte_code): Use some more volatile variables
 +      to work around local variables getting clobbered by longjmp.
 +      Port to pre-C99, which doesn't allow decls after stmts.
 +
 +2013-10-03  Paul Eggert  <eggert@cs.ucla.edu>
 +
 +      * lisp.h (eassert): Assume that COND is true when optimizing.
 +      In other words, take on the behavior of eassert_and_assume.
 +      This makes Emacs 0.2% smaller on my platform (Fedora 19, x86-64).
 +      (eassert_and_assume): Remove.  All uses replaced by eassert.
 +
 +      * xdisp.c (Qglyphless_char): Now static.
 +
 +      Adjust to merge from gnulib.
 +      * conf_post.h (__has_builtin, assume): Remove; gnulib now does these.
 +      * lisp.h: Include <verify.h>, for 'assume'.
 +
 +      * eval.c (clobbered_eassert): New macro.
 +      (internal_catch, internal_condition_case)
 +      (internal_condition_case_1, internal_condition_case_2)
 +      (internal_condition_case_n): Use it instead of eassert
 +      when the argument contains locals clobbered by longjmp.
 +      Don't use clobbered locals outside of clobbered_eassert.
 +      (internal_lisp_condition_case): Use a volatile variable
 +      to work around a local variable's getting clobbered.
 +
 +2013-10-03  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * lisp.h (struct handler): Merge struct handler and struct catchtag.
 +      (PUSH_HANDLER): New macro.
 +      (catchlist): Remove.
 +      (handlerlist): Always declare.
 +
 +      * eval.c (catchlist): Remove (merge with handlerlist).
 +      (handlerlist, lisp_eval_depth): Not static any more.
 +      (internal_catch, internal_condition_case, internal_condition_case_1)
 +      (internal_condition_case_2, internal_condition_case_n):
 +      Use PUSH_HANDLER.
 +      (unwind_to_catch, Fthrow, Fsignal): Adjust to merged
 +      handlerlist/catchlist.
 +      (internal_lisp_condition_case): Use PUSH_HANDLER.  Adjust to new
 +      handlerlist which can only handle a single condition-case handler at
 +      a time.
 +      (find_handler_clause): Simplify since we only a single branch here
 +      any more.
 +
 +      * bytecode.c (BYTE_CODES): Add Bpushcatch, Bpushconditioncase
 +      and Bpophandler.
 +      (bcall0): New function.
 +      (exec_byte_code): Add corresponding cases.  Improve error message when
 +      encountering an invalid byte-code.  Let Bunwind_protect accept
 +      a function (rather than a list of expressions) as argument.
 +
 +      * alloc.c (Fgarbage_collect): Merge scans of handlerlist and catchlist,
 +      and make them unconditional now that they're heap-allocated.
 +
 +2013-10-03  Stefan Monnier  <monnier@iro.umontreal.ca>
 +
 +      * charset.c (Fdecode_char, Fencode_char): Remove description of
 +      `restriction' arg. now that it's hidden by advertised-calling-convention.
 +
 +2013-10-02  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * macfont.m (mac_ctfont_create_preferred_family_for_attributes):
 +      Remove unused variable (from mac-port).
 +      (macfont_draw): Use s->ybase for correct y position.
 +
 +2013-10-02  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * frame.h (struct frame): Drop has_minibuffer member because...
 +      (FRAME_HAS_MINIBUF_P): ...this macro can be implemented without it.
 +      * frame.c (make_frame, make_minibuffer_frame): Adjust users.
 +
 +2013-10-02  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * window.h (struct window): Prefer enum text_cursor_kinds to int
 +      for phys_cursor_type member.  Move the latter, phys_cursor_width,
 +      phys_cursor_ascent and phys_cursor_height under HAVE_WINDOW_SYSTEM.
 +      * window.c (replace_window, make_window): Adjust users.
 +
 +2013-10-02  Dmitry Antipov  <dmantipov@yandex.ru>
 +
 +      * fringe.c (toplevel): Do not use HAVE_WINDOW_SYSTEM because
 +      this module is never compiled otherwise.
 +
 +2013-10-01  Alp Aker  <alp.tekin.aker@gmail.com>
 +
 +      * macfont.m (macfont_draw): Use CGRectMake rather than NSMakeRect
 +      (Bug#15500).
 +
 +2013-09-29  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * xdisp.c (get_next_display_element): Don't call face_for_font in
 +      a build configured --without-x.  (Bug#15484)
 +
 +2013-09-29  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * window.c (calc_absolute_offset): #elif should be #elif defined.
 +
 +      * frame.c (delete_frame): Block/unblock input to overcome race
 +      condition (Bug#15475).
 +
 +2013-09-29  Andreas Politz  <politza@hochschule-trier.de>  (tiny change)
 +
 +      * frame.c (delete_frame): Record selected frame only after
 +      calling Qdelete_frame_functions (Bug#15477).
 +
 +2013-09-28  Jan Djärv  <jan.h.d@swipnet.se>
 +
 +      * nsterm.m (ns_selection_color): Remove.
 +      (ns_get_color): Check for ns_selection_(fg|bg)_color using
 +      NSColor selectedText(Background)Color.  Only for COCOA.
 +      (ns_term_init): Remove assignment of ns_selection_color, logic
 +      moved to ns_get_color.
 +
 +      * nsterm.h (NS_SELECTION_BG_COLOR_DEFAULT): Rename from
 +      NS_SELECTION_COLOR_DEFAULT.
 +      (NS_SELECTION_FG_COLOR_DEFAULT): New.
 +
 +2013-09-28  Eli Zaretskii  <eliz@gnu.org>
 +
 +      * xdisp.c (Fdump_tool_bar_row): Ifdef away the body if 'struct
 +      frame' does not have the tool_bar_window member.
 +
  2013-09-26  Barry O'Reilly  <gundaetiapo@gmail.com>
  
        Signal error when reading an empty byte-code object (Bug#15405)
diff --cc src/alloc.c
Simple merge
Simple merge
diff --cc src/dispnew.c
@@@ -3047,6 -3087,47 +3087,47 @@@ update_frame (struct frame *f, bool for
    return paused_p;
  }
  
 -  set_window_update_flags (root_window, 0);
+ /* Update a TTY frame F that has a menu dropped down over some of its
+    glyphs.  This is like the second part of update_frame, but it
+    doesn't call build_frame_matrix, because we already have the
+    desired matrix prepared, and don't want it to be overwritten by the
+    text of the normal display.  */
+ void
+ update_frame_with_menu (struct frame *f)
+ {
+   struct window *root_window = XWINDOW (f->root_window);
+   bool paused_p;
+   eassert (FRAME_TERMCAP_P (f));
+   /* We are working on frame matrix basis.  Set the frame on whose
+      frame matrix we operate.  */
+   set_frame_matrix_frame (f);
+   /* Update the display  */
+   update_begin (f);
+   /* Force update_frame_1 not to stop due to pending input, and not
+      try scrolling.  */
+   paused_p = update_frame_1 (f, 1, 1);
+   update_end (f);
+   if (FRAME_TTY (f)->termscript)
+     fflush (FRAME_TTY (f)->termscript);
+   fflush (FRAME_TTY (f)->output);
+   /* Check window matrices for lost pointers.  */
+ #if GLYPH_DEBUG
+ #if 0
+       /* We cannot possibly survive the matrix pointers check, since
+        we have overwritten parts of the frame glyph matrix without
+        making any updates to the window matrices.  */
+   check_window_matrix_pointers (root_window);
+ #endif
+   add_frame_display_history (f, paused_p);
+ #endif
+   /* Reset flags indicating that a window should be updated.  */
++  set_window_update_flags (root_window, NULL, 0);
+ }
  
  \f
  /************************************************************************
diff --cc src/editfns.c
Simple merge
diff --cc src/frame.h
Simple merge
diff --cc src/keyboard.c
Simple merge
diff --cc src/nsterm.h
Simple merge
diff --cc src/term.c
@@@ -2755,6 -2765,1107 +2765,1107 @@@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_sto
  #endif /* HAVE_GPM */
  
  \f
 -struct glyph_matrix *
+ /***********************************************************************
+                              Menus
+  ***********************************************************************/
+ #if defined (HAVE_MENUS) && !defined (MSDOS)
+ /* TTY menu implementation and main ideas are borrowed from msdos.c.
+    However, unlike on MSDOS, where the menu text is drawn directly to
+    the display video memory, on a TTY we use display_string (see
+    display_tty_menu_item in xdisp.c) to put the glyphs produced from
+    the menu items directly into the frame's 'desired_matrix' glyph
+    matrix, and then call update_frame_with_menu to deliver the results
+    to the glass.  The previous contents of the screen, in the form of
+    the current_matrix, is stashed away, and used to restore screen
+    contents when the menu selection changes or when the final
+    selection is made and the menu should be popped down.
+    The idea of this implementation was suggested by Gerd Moellmann.  */
+ #define TTYM_FAILURE -1
+ #define TTYM_SUCCESS 1
+ #define TTYM_NO_SELECT 2
+ #define TTYM_IA_SELECT 3
+ #define TTYM_NEXT 4
+ #define TTYM_PREV 5
+ /* These hold text of the current and the previous menu help messages.  */
+ static const char *menu_help_message, *prev_menu_help_message;
+ /* Pane number and item number of the menu item which generated the
+    last menu help message.  */
+ static int menu_help_paneno, menu_help_itemno;
+ static Lisp_Object Qtty_menu_navigation_map, Qtty_menu_exit;
+ static Lisp_Object Qtty_menu_prev_item, Qtty_menu_next_item;
+ static Lisp_Object Qtty_menu_next_menu, Qtty_menu_prev_menu;
+ static Lisp_Object Qtty_menu_select, Qtty_menu_ignore;
+ static Lisp_Object Qtty_menu_mouse_movement;
+ typedef struct tty_menu_struct
+ {
+   int count;
+   char **text;
+   struct tty_menu_struct **submenu;
+   int *panenumber; /* Also used as enabled flag.  */
+   int allocated;
+   int panecount;
+   int width;
+   const char **help_text;
+ } tty_menu;
+ /* Create a brand new menu structure.  */
+ static tty_menu *
+ tty_menu_create (void)
+ {
+   tty_menu *menu;
+   menu = (tty_menu *) xmalloc (sizeof (tty_menu));
+   menu->allocated = menu->count = menu->panecount = menu->width = 0;
+   return menu;
+ }
+ /* Allocate some (more) memory for MENU ensuring that there is room for one
+    for item.  */
+ static void
+ tty_menu_make_room (tty_menu *menu)
+ {
+   if (menu->allocated == 0)
+     {
+       int count = menu->allocated = 10;
+       menu->text = (char **) xmalloc (count * sizeof (char *));
+       menu->submenu = (tty_menu **) xmalloc (count * sizeof (tty_menu *));
+       menu->panenumber = (int *) xmalloc (count * sizeof (int));
+       menu->help_text = (const char **) xmalloc (count * sizeof (char *));
+     }
+   else if (menu->allocated == menu->count)
+     {
+       int count = menu->allocated = menu->allocated + 10;
+       menu->text
+       = (char **) xrealloc (menu->text, count * sizeof (char *));
+       menu->submenu
+       = (tty_menu **) xrealloc (menu->submenu, count * sizeof (tty_menu *));
+       menu->panenumber
+       = (int *) xrealloc (menu->panenumber, count * sizeof (int));
+       menu->help_text
+       = (const char **) xrealloc (menu->help_text, count * sizeof (char *));
+     }
+ }
+ /* Search the given menu structure for a given pane number.  */
+ static tty_menu *
+ tty_menu_search_pane (tty_menu *menu, int pane)
+ {
+   int i;
+   tty_menu *try;
+   for (i = 0; i < menu->count; i++)
+     if (menu->submenu[i])
+       {
+       if (pane == menu->panenumber[i])
+         return menu->submenu[i];
+       if ((try = tty_menu_search_pane (menu->submenu[i], pane)))
+         return try;
+       }
+   return (tty_menu *) 0;
+ }
+ /* Determine how much screen space a given menu needs.  */
+ static void
+ tty_menu_calc_size (tty_menu *menu, int *width, int *height)
+ {
+   int i, h2, w2, maxsubwidth, maxheight;
+   maxsubwidth = menu->width;
+   maxheight = menu->count;
+   for (i = 0; i < menu->count; i++)
+     {
+       if (menu->submenu[i])
+       {
+         tty_menu_calc_size (menu->submenu[i], &w2, &h2);
+         if (w2 > maxsubwidth) maxsubwidth = w2;
+         if (i + h2 > maxheight) maxheight = i + h2;
+       }
+     }
+   *width = maxsubwidth;
+   *height = maxheight;
+ }
+ static void
+ mouse_get_xy (int *x, int *y)
+ {
+   struct frame *sf = SELECTED_FRAME ();
+   Lisp_Object lmx = Qnil, lmy = Qnil, lisp_dummy;
+   enum scroll_bar_part part_dummy;
+   Time time_dummy;
+   if (FRAME_TERMINAL (sf)->mouse_position_hook)
+     (*FRAME_TERMINAL (sf)->mouse_position_hook) (&sf, -1,
+                                                  &lisp_dummy, &part_dummy,
+                                                &lmx, &lmy,
+                                                &time_dummy);
+   if (!NILP (lmx))
+     {
+       *x = XINT (lmx);
+       *y = XINT (lmy);
+     }
+ }
+ /* Display MENU at (X,Y) using FACES.  */
+ static void
+ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces,
+                 int mx, int my, int disp_help)
+ {
+   int i, face, width, enabled, mousehere, row, col;
+   struct frame *sf = SELECTED_FRAME ();
+   struct tty_display_info *tty = FRAME_TTY (sf);
+   menu_help_message = NULL;
+   width = menu->width;
+   col = cursorX (tty);
+   row = cursorY (tty);
+   for (i = 0; i < menu->count; i++)
+     {
+       int max_width = width + 2; /* +2 for padding blanks on each side */
+       cursor_to (sf, y + i, x);
+       if (menu->submenu[i])
+       max_width += 2; /* for displaying " >" after the item */
+       enabled
+       = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
+       mousehere = (y + i == my && x <= mx && mx < x + max_width);
+       face = faces[enabled + mousehere * 2];
+       /* Display the menu help string for the i-th menu item even if
+        the menu item is currently disabled.  That's what the GUI
+        code does.  */
+       if (disp_help && enabled + mousehere * 2 >= 2)
+       {
+         menu_help_message = menu->help_text[i];
+         menu_help_paneno = pn - 1;
+         menu_help_itemno = i;
+       }
+       display_tty_menu_item (menu->text[i], max_width, face, x, y + i,
+                            menu->submenu[i] != NULL);
+     }
+   update_frame_with_menu (sf);
+   cursor_to (sf, row, col);
+ }
+ /* --------------------------- X Menu emulation ---------------------- */
+ /* Report availability of menus.  */
+ int
+ have_menus_p (void) {  return 1; }
+ /* Create a new pane and place it on the outer-most level.  */
+ static int
+ tty_menu_add_pane (tty_menu *menu, const char *txt)
+ {
+   int len;
+   const char *p;
+   tty_menu_make_room (menu);
+   menu->submenu[menu->count] = tty_menu_create ();
+   menu->text[menu->count] = (char *)txt;
+   menu->panenumber[menu->count] = ++menu->panecount;
+   menu->help_text[menu->count] = NULL;
+   menu->count++;
+   /* Update the menu width, if necessary.  */
+   for (len = 0, p = txt; *p; )
+     {
+       int ch_len;
+       int ch = STRING_CHAR_AND_LENGTH (p, ch_len);
+       len += CHAR_WIDTH (ch);
+       p += ch_len;
+     }
+   if (len > menu->width)
+     menu->width = len;
+   return menu->panecount;
+ }
+ /* Create a new item in a menu pane.  */
+ int
+ tty_menu_add_selection (tty_menu *menu, int pane,
+                       char *txt, int enable, char const *help_text)
+ {
+   int len;
+   char *p;
+   if (pane)
+     if (!(menu = tty_menu_search_pane (menu, pane)))
+       return TTYM_FAILURE;
+   tty_menu_make_room (menu);
+   menu->submenu[menu->count] = (tty_menu *) 0;
+   menu->text[menu->count] = txt;
+   menu->panenumber[menu->count] = enable;
+   menu->help_text[menu->count] = help_text;
+   menu->count++;
+   /* Update the menu width, if necessary.  */
+   for (len = 0, p = txt; *p; )
+     {
+       int ch_len;
+       int ch = STRING_CHAR_AND_LENGTH (p, ch_len);
+       len += CHAR_WIDTH (ch);
+       p += ch_len;
+     }
+   if (len > menu->width)
+     menu->width = len;
+   return TTYM_SUCCESS;
+ }
+ /* Decide where the menu would be placed if requested at (X,Y).  */
+ void
+ tty_menu_locate (tty_menu *menu, int x, int y,
+                int *ulx, int *uly, int *width, int *height)
+ {
+   tty_menu_calc_size (menu, width, height);
+   *ulx = x + 1;
+   *uly = y;
+   *width += 2;
+ }
+ struct tty_menu_state
+ {
+   struct glyph_matrix *screen_behind;
+   tty_menu *menu;
+   int pane;
+   int x, y;
+ };
+ /* Save away the contents of frame F's current frame matrix, and
+    enable all its rows.  Value is a glyph matrix holding the contents
+    of F's current frame matrix with all its glyph rows enabled.  */
++static struct glyph_matrix *
+ save_and_enable_current_matrix (struct frame *f)
+ {
+   int i;
+   struct glyph_matrix *saved = xzalloc (sizeof *saved);
+   saved->nrows = f->current_matrix->nrows;
+   saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
+   for (i = 0; i < saved->nrows; ++i)
+     {
+       struct glyph_row *from = f->current_matrix->rows + i;
+       struct glyph_row *to = saved->rows + i;
+       ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+       to->glyphs[TEXT_AREA] = xmalloc (nbytes);
+       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
+       to->used[TEXT_AREA] = from->used[TEXT_AREA];
+       /* Make sure every row is enabled, or else update_frame will not
+        redraw them.  (Rows that are identical to what is already on
+        screen will not be redrawn anyway.)  */
+       to->enabled_p = 1;
+       to->hash = from->hash;
+       if (from->used[LEFT_MARGIN_AREA])
+       {
+         nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+         to->glyphs[LEFT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+         memcpy (to->glyphs[LEFT_MARGIN_AREA],
+                 from->glyphs[LEFT_MARGIN_AREA], nbytes);
+         to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+       }
+       if (from->used[RIGHT_MARGIN_AREA])
+       {
+         nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+         to->glyphs[RIGHT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+         memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+                 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+         to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+       }
+     }
+   return saved;
+ }
+ /* Restore the contents of frame F's desired frame matrix from SAVED,
+    and free memory associated with SAVED.  */
+ static void
+ restore_desired_matrix (struct frame *f, struct glyph_matrix *saved)
+ {
+   int i;
+   for (i = 0; i < saved->nrows; ++i)
+     {
+       struct glyph_row *from = saved->rows + i;
+       struct glyph_row *to = f->desired_matrix->rows + i;
+       ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+       eassert (to->glyphs[TEXT_AREA] != from->glyphs[TEXT_AREA]);
+       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
+       to->used[TEXT_AREA] = from->used[TEXT_AREA];
+       to->enabled_p = from->enabled_p;
+       to->hash = from->hash;
+       nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+       if (nbytes)
+       {
+         eassert (to->glyphs[LEFT_MARGIN_AREA] != from->glyphs[LEFT_MARGIN_AREA]);
+         memcpy (to->glyphs[LEFT_MARGIN_AREA],
+                 from->glyphs[LEFT_MARGIN_AREA], nbytes);
+         to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+       }
+       else
+       to->used[LEFT_MARGIN_AREA] = 0;
+       nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+       if (nbytes)
+       {
+         eassert (to->glyphs[RIGHT_MARGIN_AREA] != from->glyphs[RIGHT_MARGIN_AREA]);
+         memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+                 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+         to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+       }
+       else
+       to->used[RIGHT_MARGIN_AREA] = 0;
+     }
+ }
+ static void
+ free_saved_screen (struct glyph_matrix *saved)
+ {
+   int i;
+   if (!saved)
+     return;   /* already freed */
+   for (i = 0; i < saved->nrows; ++i)
+     {
+       struct glyph_row *from = saved->rows + i;
+       xfree (from->glyphs[TEXT_AREA]);
+       if (from->used[LEFT_MARGIN_AREA])
+       xfree (from->glyphs[LEFT_MARGIN_AREA]);
+       if (from->used[RIGHT_MARGIN_AREA])
+       xfree (from->glyphs[RIGHT_MARGIN_AREA]);
+     }
+   xfree (saved->rows);
+   xfree (saved);
+ }
+ /* Update the display of frame F from its saved contents.  */
+ static void
+ screen_update (struct frame *f, struct glyph_matrix *mtx)
+ {
+   restore_desired_matrix (f, mtx);
+   update_frame_with_menu (f);
+ }
+ /* Read user input and return X and Y coordinates where that input
+    puts us.  We only consider mouse movement and click events and
+    keyboard movement commands; the rest are ignored.
+    Value is -1 if C-g was pressed, 1 if an item was selected, 2 or 3
+    if we need to move to the next or previous menu-bar menu, zero
+    otherwise.  */
+ static int
+ read_menu_input (struct frame *sf, int *x, int *y, int min_y, int max_y,
+                bool *first_time)
+ {
+   if (*first_time)
+     {
+       *first_time = false;
+       sf->mouse_moved = 1;
+     }
+   else
+     {
+       extern Lisp_Object read_menu_command (void);
+       Lisp_Object cmd;
+       int usable_input = 1;
+       int st = 0;
+       struct tty_display_info *tty = FRAME_TTY (sf);
+       Lisp_Object saved_mouse_tracking = do_mouse_tracking;
+       /* Signal the keyboard reading routines we are displaying a menu
+        on this terminal.  */
+       tty->showing_menu = 1;
+       /* We want mouse movements be reported by read_menu_command.  */
+       do_mouse_tracking = Qt;
+       do {
+       cmd = read_menu_command ();
+       } while (NILP (cmd));
+       tty->showing_menu = 0;
+       do_mouse_tracking = saved_mouse_tracking;
+       if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit))
+       return -1;
+       if (EQ (cmd, Qtty_menu_mouse_movement))
+       {
+         int mx, my;
+         mouse_get_xy (&mx, &my);
+         *x = mx;
+         *y = my;
+       }
+       else if (EQ (cmd, Qtty_menu_next_menu))
+       {
+         usable_input = 0;
+         st = 2;
+       }
+       else if (EQ (cmd, Qtty_menu_prev_menu))
+       {
+         usable_input = 0;
+         st = 3;
+       }
+       else if (EQ (cmd, Qtty_menu_next_item))
+       {
+         if (*y < max_y)
+           *y += 1;
+       }
+       else if (EQ (cmd, Qtty_menu_prev_item))
+       {
+         if (*y > min_y)
+           *y -= 1;
+       }
+       else if (EQ (cmd, Qtty_menu_select))
+       st = 1;
+       else if (!EQ (cmd, Qtty_menu_ignore))
+       usable_input = 0;
+       if (usable_input)
+       sf->mouse_moved = 1;
+       return st;
+     }
+   return 0;
+ }
+ /* Display menu, wait for user's response, and return that response.  */
+ static int
+ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
+                  int x0, int y0, char **txt,
+                  void (*help_callback)(char const *, int, int),
+                  int kbd_navigation)
+ {
+   struct tty_menu_state *state;
+   int statecount, x, y, i, b, leave, result, onepane;
+   int title_faces[4];         /* face to display the menu title */
+   int faces[4], buffers_num_deleted = 0;
+   struct frame *sf = SELECTED_FRAME ();
+   struct tty_display_info *tty = FRAME_TTY (sf);
+   bool first_time;
+   Lisp_Object saved_echo_area_message, selectface;
+   /* Don't allow non-positive x0 and y0, lest the menu will wrap
+      around the display.  */
+   if (x0 <= 0)
+     x0 = 1;
+   if (y0 <= 0)
+     y0 = 1;
+   state = alloca (menu->panecount * sizeof (struct tty_menu_state));
+   memset (state, 0, sizeof (*state));
+   faces[0]
+     = lookup_derived_face (sf, intern ("tty-menu-disabled-face"),
+                          DEFAULT_FACE_ID, 1);
+   faces[1]
+     = lookup_derived_face (sf, intern ("tty-menu-enabled-face"),
+                          DEFAULT_FACE_ID, 1);
+   selectface = intern ("tty-menu-selected-face");
+   faces[2] = lookup_derived_face (sf, selectface,
+                                 faces[0], 1);
+   faces[3] = lookup_derived_face (sf, selectface,
+                                 faces[1], 1);
+   /* Make sure the menu title is always displayed with
+      `tty-menu-selected-face', no matter where the mouse pointer is.  */
+   for (i = 0; i < 4; i++)
+     title_faces[i] = faces[3];
+   statecount = 1;
+   /* Don't let the title for the "Buffers" popup menu include a
+      digit (which is ugly).
+      This is a terrible kludge, but I think the "Buffers" case is
+      the only one where the title includes a number, so it doesn't
+      seem to be necessary to make this more general.  */
+   if (strncmp (menu->text[0], "Buffers 1", 9) == 0)
+     {
+       menu->text[0][7] = '\0';
+       buffers_num_deleted = 1;
+     }
+   /* Force update of the current frame, so that the desired and the
+      current matrices are identical.  */
+   update_frame_with_menu (sf);
+   state[0].menu = menu;
+   state[0].screen_behind = save_and_enable_current_matrix (sf);
+   /* Display the menu title.  We subtract 1 from x0 and y0 because we
+      want to interpret them as zero-based column and row coordinates,
+      and also because we want the first item of the menu, not its
+      title, to appear at x0,y0.  */
+   tty_menu_display (menu, x0 - 1, y0 - 1, 1, title_faces, x0 - 1, y0 - 1, 0);
+   /* Turn off the cursor.  Otherwise it shows through the menu
+      panes, which is ugly.  */
+   tty_hide_cursor (tty);
+   if (buffers_num_deleted)
+     menu->text[0][7] = ' ';
+   if ((onepane = menu->count == 1 && menu->submenu[0]))
+     {
+       menu->width = menu->submenu[0]->width;
+       state[0].menu = menu->submenu[0];
+     }
+   else
+     {
+       state[0].menu = menu;
+     }
+   state[0].x = x0 - 1;
+   state[0].y = y0;
+   state[0].pane = onepane;
+   x = state[0].x;
+   y = state[0].y;
+   first_time = true;
+   leave = 0;
+   while (!leave)
+     {
+       int input_status;
+       int min_y = state[0].y, max_y = min_y + state[0].menu->count - 1;
+       input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time);
+       if (input_status)
+       {
+         leave = 1;
+         if (input_status == -1)
+           {
+             /* Remove the last help-echo, so that it doesn't
+                re-appear after "Quit".  */
+             show_help_echo (Qnil, Qnil, Qnil, Qnil);
+             result = TTYM_NO_SELECT;
+           }
+         else if (input_status == 2)
+           {
+             if (kbd_navigation)
+               result = TTYM_NEXT;
+             else
+               leave = 0;
+           }
+         else if (input_status == 3)
+           {
+             if (kbd_navigation)
+               result = TTYM_PREV;
+             else
+               leave = 0;
+           }
+       }
+       if (sf->mouse_moved && input_status != -1)
+       {
+         sf->mouse_moved = 0;
+         result = TTYM_IA_SELECT;
+         for (i = 0; i < statecount; i++)
+           if (state[i].x <= x && x < state[i].x + state[i].menu->width + 2)
+             {
+               int dy = y - state[i].y;
+               if (0 <= dy && dy < state[i].menu->count)
+                 {
+                   if (!state[i].menu->submenu[dy])
+                     {
+                       if (state[i].menu->panenumber[dy])
+                         result = TTYM_SUCCESS;
+                       else
+                         result = TTYM_IA_SELECT;
+                     }
+                   *pane = state[i].pane - 1;
+                   *selidx = dy;
+                   /* We hit some part of a menu, so drop extra menus that
+                      have been opened.  That does not include an open and
+                      active submenu.  */
+                   if (i != statecount - 2
+                       || state[i].menu->submenu[dy] != state[i+1].menu)
+                     while (i != statecount - 1)
+                       {
+                         statecount--;
+                         screen_update (sf, state[statecount].screen_behind);
+                         state[statecount].screen_behind = NULL;
+                       }
+                   if (i == statecount - 1 && state[i].menu->submenu[dy])
+                     {
+                       tty_menu_display (state[i].menu,
+                                         state[i].x,
+                                         state[i].y,
+                                         state[i].pane,
+                                         faces, x, y, 1);
+                       state[statecount].menu = state[i].menu->submenu[dy];
+                       state[statecount].pane = state[i].menu->panenumber[dy];
+                       state[statecount].screen_behind
+                         = save_and_enable_current_matrix (sf);
+                       state[statecount].x
+                         = state[i].x + state[i].menu->width + 2;
+                       state[statecount].y = y;
+                       statecount++;
+                     }
+                 }
+             }
+         tty_menu_display (state[statecount - 1].menu,
+                           state[statecount - 1].x,
+                           state[statecount - 1].y,
+                           state[statecount - 1].pane,
+                           faces, x, y, 1);
+         tty_hide_cursor (tty);
+         fflush (tty->output);
+       }
+       /* Display the help-echo message for the currently-selected menu
+        item.  */
+       if ((menu_help_message || prev_menu_help_message)
+         && menu_help_message != prev_menu_help_message)
+       {
+         help_callback (menu_help_message,
+                        menu_help_paneno, menu_help_itemno);
+         tty_hide_cursor (tty);
+         fflush (tty->output);
+         prev_menu_help_message = menu_help_message;
+       }
+     }
+   sf->mouse_moved = 0;
+   screen_update (sf, state[0].screen_behind);
+   while (statecount--)
+     free_saved_screen (state[statecount].screen_behind);
+   tty_show_cursor (tty);      /* turn cursor back on */
+ /* Clean up any mouse events that are waiting inside Emacs event queue.
+      These events are likely to be generated before the menu was even
+      displayed, probably because the user pressed and released the button
+      (which invoked the menu) too quickly.  If we don't remove these events,
+      Emacs will process them after we return and surprise the user.  */
+   discard_mouse_events ();
+   if (!kbd_buffer_events_waiting ())
+     clear_input_pending ();
+   SET_FRAME_GARBAGED (sf);
+   return result;
+ }
+ /* Dispose of a menu.  */
+ void
+ tty_menu_destroy (tty_menu *menu)
+ {
+   int i;
+   if (menu->allocated)
+     {
+       for (i = 0; i < menu->count; i++)
+       if (menu->submenu[i])
+         tty_menu_destroy (menu->submenu[i]);
+       xfree (menu->text);
+       xfree (menu->submenu);
+       xfree (menu->panenumber);
+       xfree (menu->help_text);
+     }
+   xfree (menu);
+   menu_help_message = prev_menu_help_message = NULL;
+ }
+ /* Show help HELP_STRING, or clear help if HELP_STRING is null.
+    PANE is the pane number, and ITEM is the menu item number in
+    the menu (currently not used).  */
+ static void
+ tty_menu_help_callback (char const *help_string, int pane, int item)
+ {
+   Lisp_Object *first_item;
+   Lisp_Object pane_name;
+   Lisp_Object menu_object;
+   first_item = XVECTOR (menu_items)->u.contents;
+   if (EQ (first_item[0], Qt))
+     pane_name = first_item[MENU_ITEMS_PANE_NAME];
+   else if (EQ (first_item[0], Qquote))
+     /* This shouldn't happen, see xmenu_show.  */
+     pane_name = empty_unibyte_string;
+   else
+     pane_name = first_item[MENU_ITEMS_ITEM_NAME];
+   /* (menu-item MENU-NAME PANE-NUMBER)  */
+   menu_object = list3 (Qmenu_item, pane_name, make_number (pane));
+   show_help_echo (help_string ? build_string (help_string) : Qnil,
+                 Qnil, menu_object, make_number (item));
+ }
+ static void
+ tty_pop_down_menu (Lisp_Object arg)
+ {
+   tty_menu *menu = XSAVE_POINTER (arg, 0);
+   block_input ();
+   tty_menu_destroy (menu);
+   unblock_input ();
+ }
+ /* Return the zero-based index of the last menu-bar item on frame F.  */
+ static int
+ tty_menu_last_menubar_item (struct frame *f)
+ {
+   int i = 0;
+   eassert (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f));
+   if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f))
+     {
+       Lisp_Object items = FRAME_MENU_BAR_ITEMS (f);
+       while (i < ASIZE (items))
+       {
+         Lisp_Object str;
+         str = AREF (items, i + 1);
+         if (NILP (str))
+           break;
+         i += 4;
+       }
+       i -= 4; /* went one too far */
+     }
+   return i;
+ }
+ /* Find in frame F's menu bar the menu item that is next or previous
+    to the item at X/Y, and return that item's position in X/Y.  WHICH
+    says which one--next or previous--item to look for.  X and Y are
+    measured in character cells.  This should only be called on TTY
+    frames.  */
+ static void
+ tty_menu_new_item_coords (struct frame *f, int which, int *x, int *y)
+ {
+   eassert (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f));
+   if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f))
+     {
+       Lisp_Object items = FRAME_MENU_BAR_ITEMS (f);
+       int last_i = tty_menu_last_menubar_item (f);
+       int i, prev_x;
+       /* This loop assumes a single menu-bar line, and will fail to
+        find an item if it is not in the first line.  Note that
+        make_lispy_event in keyboard.c makes the same assumption.  */
+       for (i = 0, prev_x = -1; i < ASIZE (items); i += 4)
+       {
+         Lisp_Object pos, str;
+         int ix;
+         str = AREF (items, i + 1);
+         pos = AREF (items, i + 3);
+         if (NILP (str))
+           return;
+         ix = XINT (pos);
+         if (ix <= *x
+             /* We use <= so the blank between 2 items on a TTY is
+                considered part of the previous item.  */
+             && *x <= ix + menu_item_width (SSDATA (str)))
+           {
+             /* Found current item.  Now compute the X coordinate of
+                the previous or next item.  */
+             if (which == TTYM_NEXT)
+               {
+                 if (i < last_i)
+                   *x = XINT (AREF (items, i + 4 + 3));
+                 else
+                   *x = 0;     /* wrap around to the first item */
+               }
+             else if (prev_x < 0)
+               {
+                 /* Wrap around to the last item.  */
+                 *x = XINT (AREF (items, last_i + 3));
+               }
+             else
+               *x = prev_x;
+             return;
+           }
+         prev_x = ix;
+       }
+     }
+ }
+ Lisp_Object
+ tty_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
+              Lisp_Object title, int kbd_navigation, const char **error_name)
+ {
+   tty_menu *menu;
+   int pane, selidx, lpane, status;
+   Lisp_Object entry, pane_prefix;
+   char *datap;
+   int ulx, uly, width, height;
+   int item_x, item_y;
+   int dispwidth, dispheight;
+   int i, j, lines, maxlines;
+   int maxwidth;
+   int dummy_int;
+   unsigned int dummy_uint;
+   ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+   if (! FRAME_TERMCAP_P (f))
+     emacs_abort ();
+   *error_name = 0;
+   if (menu_items_n_panes == 0)
+     return Qnil;
+   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
+     {
+       *error_name = "Empty menu";
+       return Qnil;
+     }
+   /* Make the menu on that window.  */
+   menu = tty_menu_create ();
+   if (menu == NULL)
+     {
+       *error_name = "Can't create menu";
+       return Qnil;
+     }
+   /* Don't GC while we prepare and show the menu, because we give the
+      menu functions pointers to the contents of strings.  */
+   inhibit_garbage_collection ();
+   /* Adjust coordinates to be root-window-relative.  */
+   item_x = x += f->left_pos;
+   item_y = y += f->top_pos;
+   /* Create all the necessary panes and their items.  */
+   maxwidth = maxlines = lines = i = 0;
+   lpane = TTYM_FAILURE;
+   while (i < menu_items_used)
+     {
+       if (EQ (AREF (menu_items, i), Qt))
+       {
+         /* Create a new pane.  */
+         Lisp_Object pane_name, prefix;
+         const char *pane_string;
+           maxlines = max (maxlines, lines);
+           lines = 0;
+         pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
+         prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+         pane_string = (NILP (pane_name)
+                        ? "" : SSDATA (pane_name));
+         if (keymaps && !NILP (prefix))
+           pane_string++;
+         lpane = tty_menu_add_pane (menu, pane_string);
+         if (lpane == TTYM_FAILURE)
+           {
+             tty_menu_destroy (menu);
+             *error_name = "Can't create pane";
+             return Qnil;
+           }
+         i += MENU_ITEMS_PANE_LENGTH;
+         /* Find the width of the widest item in this pane.  */
+         j = i;
+         while (j < menu_items_used)
+           {
+             Lisp_Object item;
+             item = AREF (menu_items, j);
+             if (EQ (item, Qt))
+               break;
+             if (NILP (item))
+               {
+                 j++;
+                 continue;
+               }
+             width = SBYTES (item);
+             if (width > maxwidth)
+               maxwidth = width;
+             j += MENU_ITEMS_ITEM_LENGTH;
+           }
+       }
+       /* Ignore a nil in the item list.
+        It's meaningful only for dialog boxes.  */
+       else if (EQ (AREF (menu_items, i), Qquote))
+       i += 1;
+       else
+       {
+         /* Create a new item within current pane.  */
+         Lisp_Object item_name, enable, descrip, help;
+         char *item_data;
+         char const *help_string;
+         item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
+         enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
+         descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
+         help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
+         help_string = STRINGP (help) ? SSDATA (help) : NULL;
+         if (!NILP (descrip))
+           {
+             /* if alloca is fast, use that to make the space,
+                to reduce gc needs.  */
+             item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1);
+             memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
+             for (j = SCHARS (item_name); j < maxwidth; j++)
+               item_data[j] = ' ';
+             memcpy (item_data + j, SSDATA (descrip), SBYTES (descrip));
+             item_data[j + SBYTES (descrip)] = 0;
+           }
+         else
+           item_data = SSDATA (item_name);
+         if (lpane == TTYM_FAILURE
+             || (tty_menu_add_selection (menu, lpane, item_data,
+                                         !NILP (enable), help_string)
+                 == TTYM_FAILURE))
+           {
+             tty_menu_destroy (menu);
+             *error_name = "Can't add selection to menu";
+             return Qnil;
+           }
+         i += MENU_ITEMS_ITEM_LENGTH;
+           lines++;
+       }
+     }
+   maxlines = max (maxlines, lines);
+   /* All set and ready to fly.  */
+   dispwidth = f->text_cols;
+   dispheight = f->text_lines;
+   x = min (x, dispwidth);
+   y = min (y, dispheight);
+   x = max (x, 1);
+   y = max (y, 1);
+   tty_menu_locate (menu, x, y, &ulx, &uly, &width, &height);
+   if (ulx+width > dispwidth)
+     {
+       x -= (ulx + width) - dispwidth;
+       ulx = dispwidth - width;
+     }
+   if (uly+height > dispheight)
+     {
+       y -= (uly + height) - dispheight;
+       uly = dispheight - height;
+     }
+   if (FRAME_HAS_MINIBUF_P (f) && uly+height > dispheight - 2)
+     {
+       /* Move the menu away of the echo area, to avoid overwriting the
+        menu with help echo messages or vice versa.  */
+       if (BUFFERP (echo_area_buffer[0]) && WINDOWP (echo_area_window))
+       {
+         y -= WINDOW_TOTAL_LINES (XWINDOW (echo_area_window)) + 1;
+         uly -= WINDOW_TOTAL_LINES (XWINDOW (echo_area_window)) + 1;
+       }
+       else
+       {
+         y -= 2;
+         uly -= 2;
+       }
+     }
+   if (ulx < 0) x -= ulx;
+   if (uly < 0) y -= uly;
+ #if 0
+   /* This code doesn't make sense on a TTY, since it can easily annul
+      the adjustments above that carefully avoid truncation of the menu
+      items.  I think it was written to fix some problem that only
+      happens on X11.  */
+   if (! for_click)
+     {
+       /* If position was not given by a mouse click, adjust so upper left
+          corner of the menu as a whole ends up at given coordinates.  This
+          is what x-popup-menu says in its documentation.  */
+       x += width/2;
+       y += 1.5*height/(maxlines+2);
+     }
+ #endif
+   pane = selidx = 0;
+   record_unwind_protect (tty_pop_down_menu, make_save_ptr (menu));
+   specbind (Qoverriding_terminal_local_map,
+           Fsymbol_value (Qtty_menu_navigation_map));
+   status = tty_menu_activate (menu, &pane, &selidx, x, y, &datap,
+                             tty_menu_help_callback, kbd_navigation);
+   entry = pane_prefix = Qnil;
+   switch (status)
+     {
+     case TTYM_SUCCESS:
+       /* Find the item number SELIDX in pane number PANE.  */
+       i = 0;
+       while (i < menu_items_used)
+       {
+         if (EQ (AREF (menu_items, i), Qt))
+           {
+             if (pane == 0)
+               pane_prefix
+                 = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
+             pane--;
+             i += MENU_ITEMS_PANE_LENGTH;
+           }
+         else
+           {
+             if (pane == -1)
+               {
+                 if (selidx == 0)
+                   {
+                     entry
+                       = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+                     if (keymaps != 0)
+                       {
+                         entry = Fcons (entry, Qnil);
+                         if (!NILP (pane_prefix))
+                           entry = Fcons (pane_prefix, entry);
+                       }
+                     break;
+                   }
+                 selidx--;
+               }
+             i += MENU_ITEMS_ITEM_LENGTH;
+           }
+       }
+       break;
+     case TTYM_NEXT:
+     case TTYM_PREV:
+       tty_menu_new_item_coords (f, status, &item_x, &item_y);
+       entry = Fcons (make_number (item_x), make_number (item_y));
+       break;
+     case TTYM_FAILURE:
+       *error_name = "Can't activate menu";
+     case TTYM_IA_SELECT:
+       break;
+     case TTYM_NO_SELECT:
+       /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
+        the menu was invoked with a mouse event as POSITION).  */
+       if (! for_click)
+         Fsignal (Qquit, Qnil);
+       break;
+     }
+   unbind_to (specpdl_count, Qnil);
+   return entry;
+ }
+ #endif        /* HAVE_MENUS && !MSDOS */
\f
  #ifndef MSDOS
  /***********************************************************************
                            Initialization
diff --cc src/window.c
Simple merge
diff --cc src/xdisp.c
Simple merge