emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/oclosure f75ee15efd: Merge branch 'main' into oclosure


From: Stefan Monnier
Subject: scratch/oclosure f75ee15efd: Merge branch 'main' into oclosure
Date: Sun, 6 Feb 2022 13:39:30 -0500 (EST)

branch: scratch/oclosure
commit f75ee15efd83d74640d12483bd7d345114d5f5e5
Merge: e07802ff10 1850121629
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    Merge branch 'main' into oclosure
---
 INSTALL                                            |   12 +-
 admin/grammars/Makefile.in                         |    3 +-
 configure.ac                                       |   21 +-
 doc/emacs/search.texi                              |   36 +-
 doc/emacs/trouble.texi                             |   10 +-
 doc/emacs/xresources.texi                          |   20 +
 doc/lispref/display.texi                           |   35 +-
 doc/lispref/frames.texi                            |   17 +
 doc/lispref/functions.texi                         |    5 +-
 doc/lispref/loading.texi                           |   24 +-
 doc/lispref/modes.texi                             |   22 +-
 doc/misc/efaq.texi                                 |   55 +-
 doc/misc/gnus-faq.texi                             |   37 +-
 doc/misc/tramp.texi                                |    6 +-
 etc/NEWS                                           |   73 +
 etc/NEWS.28                                        |  159 +-
 etc/publicsuffix.txt                               |   17 +-
 etc/themes/leuven-dark-theme.el                    | 1095 +++++
 leim/Makefile.in                                   |    1 +
 lisp/autorevert.el                                 |    2 +-
 lisp/bindings.el                                   |   12 +
 lisp/bookmark.el                                   |    5 +-
 lisp/cedet/semantic/wisent/comp.el                 |    2 +
 lisp/cus-edit.el                                   |   50 +-
 lisp/cus-face.el                                   |    2 +-
 lisp/emacs-lisp/byte-run.el                        |    2 +-
 lisp/emacs-lisp/bytecomp.el                        |   47 +-
 lisp/emacs-lisp/comp.el                            |    5 +-
 lisp/emacs-lisp/debug-early.el                     |   87 +
 lisp/emacs-lisp/eieio-core.el                      |    8 +-
 lisp/emacs-lisp/eieio.el                           |    2 +-
 lisp/emacs-lisp/elp.el                             |    7 +-
 lisp/emacs-lisp/ert-x.el                           |    8 +
 lisp/emacs-lisp/find-func.el                       |   43 +-
 lisp/emacs-lisp/package.el                         |    3 +-
 lisp/emacs-lisp/smie.el                            |   10 +-
 lisp/eshell/em-cmpl.el                             |    2 +-
 lisp/eshell/em-dirs.el                             |    4 +
 lisp/eshell/em-rebind.el                           |    2 +-
 lisp/eshell/em-term.el                             |    2 +-
 lisp/eshell/em-tramp.el                            |    4 +-
 lisp/eshell/esh-cmd.el                             |   72 +-
 lisp/eshell/esh-io.el                              |    2 +-
 lisp/eshell/esh-mode.el                            |   28 +-
 lisp/eshell/esh-proc.el                            |   11 +-
 lisp/eshell/esh-util.el                            |   14 +
 lisp/eshell/eshell.el                              |    6 +-
 lisp/files.el                                      |   12 +-
 lisp/finder.el                                     |    3 +-
 lisp/frame.el                                      |   64 +-
 lisp/frameset.el                                   |   12 +-
 lisp/gnus/gnus-art.el                              |    3 +-
 lisp/gnus/gnus-group.el                            |    6 +-
 lisp/gnus/gnus-icalendar.el                        |    7 +-
 lisp/gnus/gnus-registry.el                         |   20 +-
 lisp/gnus/gnus-start.el                            |   29 +-
 lisp/gnus/mm-view.el                               |   22 +-
 lisp/gnus/nnregistry.el                            |    4 +-
 lisp/gnus/nnselect.el                              |   39 +-
 lisp/help-fns.el                                   |   23 +-
 lisp/help.el                                       |    6 +
 lisp/image.el                                      |   22 +-
 lisp/international/latin1-disp.el                  | 4860 ++++++++++----------
 lisp/isearch.el                                    |   12 +-
 lisp/language/indian.el                            |    8 +-
 lisp/ldefs-boot.el                                 |  125 +-
 lisp/loadhist.el                                   |   54 +-
 lisp/loadup.el                                     |    1 +
 lisp/mail/ietf-drums.el                            |    6 +-
 lisp/menu-bar.el                                   |   19 +-
 lisp/net/soap-client.el                            |    9 +-
 lisp/net/tramp-archive.el                          |    6 +
 lisp/net/tramp-cache.el                            |    2 +-
 lisp/net/tramp-gvfs.el                             |   21 +-
 lisp/net/tramp.el                                  |   27 +-
 lisp/notifications.el                              |    2 +-
 lisp/nxml/nxml-mode.el                             |    3 +-
 lisp/{ => obsolete}/vt-control.el                  |    1 +
 lisp/{ => obsolete}/vt100-led.el                   |    1 +
 lisp/org/ob-tangle.el                              |    2 +-
 lisp/org/ol-bibtex.el                              |    2 +-
 lisp/org/org-agenda.el                             |    6 +-
 lisp/org/org-capture.el                            |    3 +-
 lisp/org/org-clock.el                              |    2 +-
 lisp/org/org-compat.el                             |    6 +-
 lisp/org/org-refile.el                             |    8 +-
 lisp/org/org-version.el                            |    2 +-
 lisp/paren.el                                      |  126 +-
 lisp/pcmpl-gnu.el                                  |    2 +-
 lisp/pixel-scroll.el                               |   25 +-
 lisp/progmodes/cc-mode.el                          |   75 +-
 lisp/progmodes/cperl-mode.el                       |    2 +-
 lisp/progmodes/octave.el                           |    3 +-
 lisp/progmodes/project.el                          |    7 +-
 lisp/progmodes/python.el                           |  323 +-
 lisp/progmodes/sh-script.el                        |    2 +-
 lisp/progmodes/xref.el                             |    5 +-
 lisp/replace.el                                    |   39 +-
 lisp/select.el                                     |   36 +-
 lisp/simple.el                                     |   20 +
 lisp/sort.el                                       |   43 +-
 lisp/startup.el                                    |   70 +-
 lisp/subr.el                                       |   49 +-
 lisp/tab-bar.el                                    |    6 +-
 lisp/tab-line.el                                   |   10 +-
 lisp/term/x-win.el                                 |   13 +
 lisp/textmodes/reftex-toc.el                       |    2 +-
 lisp/tooltip.el                                    |   13 +-
 lisp/vc/diff-mode.el                               |    3 +-
 lisp/vc/vc-annotate.el                             |    2 +-
 lisp/vc/vc-hooks.el                                |    7 +-
 lisp/vc/vc.el                                      |   30 +-
 lisp/version.el                                    |    9 +-
 lisp/woman.el                                      |    4 +-
 lisp/yank-media.el                                 |   44 +-
 lwlib/xlwmenu.c                                    |    2 +
 src/Makefile.in                                    |    7 +-
 src/alloc.c                                        |    4 +-
 src/comp.c                                         |   11 +-
 src/data.c                                         |   67 +-
 src/emacs.c                                        |    7 +-
 src/eval.c                                         |  156 +-
 src/filelock.c                                     |   74 +-
 src/frame.c                                        |   38 +
 src/frame.h                                        |    4 +
 src/ftcrfont.c                                     |   34 +-
 src/gtkutil.c                                      |   81 +-
 src/haiku_io.c                                     |   26 +-
 src/haiku_support.cc                               |  183 +-
 src/haiku_support.h                                |   29 +-
 src/haikufns.c                                     |   31 +-
 src/haikufont.c                                    |   30 +-
 src/haikumenu.c                                    |   47 +-
 src/haikuterm.c                                    |  199 +-
 src/haikuterm.h                                    |   26 +-
 src/image.c                                        |   11 +-
 src/indent.c                                       |   61 +-
 src/lread.c                                        |    9 +-
 src/macfont.m                                      |    5 +-
 src/menu.c                                         |   16 +-
 src/nsfns.m                                        |    3 +
 src/nsselect.m                                     |    2 +-
 src/nsterm.m                                       |   20 +-
 src/pgtkfns.c                                      |  108 +-
 src/pgtkmenu.c                                     |   34 +-
 src/pgtkselect.c                                   |    9 -
 src/pgtkterm.c                                     |  227 +-
 src/pgtkterm.h                                     |    9 +-
 src/search.c                                       |    8 +
 src/terminal.c                                     |    2 +
 src/w32fns.c                                       |    8 +
 src/window.c                                       |    4 +-
 src/xdisp.c                                        |   78 +-
 src/xfaces.c                                       |    6 +-
 src/xfns.c                                         |  295 +-
 src/xfont.c                                        |   26 +
 src/xftfont.c                                      |   39 +-
 src/xselect.c                                      |   39 +-
 src/xterm.c                                        |  707 ++-
 src/xterm.h                                        |   58 +-
 src/xwidget.c                                      |  138 +-
 test/lisp/cedet/semantic/bovine/gcc-tests.el       |   12 +-
 test/lisp/electric-tests.el                        |    2 +-
 test/lisp/emacs-lisp/ert-tests.el                  |    2 +-
 test/lisp/eshell/em-extpipe-tests.el               |   12 +-
 test/lisp/eshell/eshell-tests-helpers.el           |    4 +-
 test/lisp/eshell/eshell-tests.el                   |   39 +-
 test/lisp/help-tests.el                            |    4 +-
 test/lisp/international/textsec-tests.el           |    4 +-
 test/lisp/loadhist-resources/loadhist--bar.el      |   27 +
 test/lisp/loadhist-resources/loadhist--foo.el      |   29 +
 test/lisp/loadhist-tests.el                        |   47 +
 test/lisp/mail/ietf-drums-tests.el                 |  162 +
 test/lisp/net/tramp-tests.el                       |   76 +-
 .../cperl-mode-resources/proto-and-attrs.pl        |   50 +
 test/lisp/progmodes/cperl-mode-tests.el            |   49 +
 test/lisp/progmodes/flymake-tests.el               |    9 +-
 test/lisp/progmodes/python-tests.el                |   76 +-
 test/lisp/yank-media-tests.el                      |   38 +
 test/src/buffer-tests.el                           |    2 +-
 test/src/filelock-tests.el                         |  217 +-
 test/src/xdisp-tests.el                            |    9 +
 182 files changed, 7985 insertions(+), 4383 deletions(-)

diff --git a/INSTALL b/INSTALL
index 7cb7e0526a..b1e3c72c4b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,11 +4,13 @@ Inc.
 See the end of the file for license conditions.
 
 
-This file contains general information on building GNU Emacs.
-For more information specific to the MS-Windows, GNUstep/macOS, and
-MS-DOS ports, also read the files nt/INSTALL, nextstep/INSTALL, and
-msdos/INSTALL.  For information about building from a repository checkout
-(rather than a release), also read the file INSTALL.REPO.
+This file contains general information on building GNU Emacs.  For
+more information specific to the MS-Windows, GNUstep/macOS, and MS-DOS
+ports, also read the files nt/INSTALL, nextstep/INSTALL, and
+msdos/INSTALL.
+
+For information about building from a Git checkout (rather than an
+Emacs release), read the INSTALL.REPO file first.
 
 
 BASIC INSTALLATION
diff --git a/admin/grammars/Makefile.in b/admin/grammars/Makefile.in
index 6f69943089..4ca88982cd 100644
--- a/admin/grammars/Makefile.in
+++ b/admin/grammars/Makefile.in
@@ -34,7 +34,8 @@ top_builddir = @top_builddir@
 unexport EMACSDATA EMACSDOC EMACSLOADPATH EMACSPATH
 
 EMACS = ${top_builddir}/src/emacs
-emacs = "${EMACS}" -batch --no-site-file --no-site-lisp --eval '(setq 
load-prefer-newer t)'
+emacs = "${EMACS}" -batch --no-site-file --no-site-lisp \
+  --eval '(setq max-specpdl-size 5000)' --eval '(setq load-prefer-newer t)'
 
 make_bovine = ${emacs} -l semantic/bovine/grammar -f bovine-batch-make-parser
 make_wisent = ${emacs} -l semantic/wisent/grammar -f wisent-batch-make-parser
diff --git a/configure.ac b/configure.ac
index 9f4d5db43f..6f469cf0f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2620,10 +2620,11 @@ if test "${HAVE_X11}" = "yes"; then
        emacs_cv_xkb=yes, emacs_cv_xkb=no)])
   if test $emacs_cv_xkb = yes; then
     AC_DEFINE(HAVE_XKB, 1, [Define to 1 if you have the Xkb extension.])
+    AC_CHECK_FUNCS(XkbRefreshKeyboardMapping XkbFreeNames)
   fi
 
-  AC_CHECK_FUNCS(XrmSetDatabase XScreenResourceString \
-XScreenNumberOfScreen)
+  AC_CHECK_FUNCS(XrmSetDatabase XScreenResourceString XScreenNumberOfScreen)
+  AC_CHECK_FUNCS(XDisplayCells XDestroySubwindows)
 fi
 
 if test "${window_system}" = "x11"; then
@@ -4489,6 +4490,22 @@ fi
 AC_SUBST(XINPUT_CFLAGS)
 AC_SUBST(XINPUT_LIBS)
 
+XSYNC_LIBS=
+XSYNC_CFLAGS=
+HAVE_XSYNC=no
+if test "${HAVE_X11}" = "yes"; then
+   AC_CHECK_HEADER(X11/extensions/sync.h,
+     AC_CHECK_LIB(Xext, XSyncQueryExtension, HAVE_XSYNC=yes),
+     [], [#include <X11/Xlib.h>])
+
+  if test "${HAVE_XSYNC}" = "yes"; then
+    AC_DEFINE(HAVE_XSYNC, 1, [Define to 1 if the X Synchronization Extension 
is available.])
+    XSYNC_LIBS="-lXext"
+  fi
+fi
+AC_SUBST(XSYNC_LIBS)
+AC_SUBST(XSYNC_CFLAGS)
+
 ### Use Xdbe (-lXdbe) if available
 HAVE_XDBE=no
 if test "${HAVE_X11}" = "yes"; then
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index a57cfac8da..982c7f4a2c 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1874,12 +1874,12 @@ replacing regexp matches in file names.
 @node Other Repeating Search
 @section Other Search-and-Loop Commands
 
-  Here are some other commands that find matches for a regular
-expression.  They all ignore case in matching, if the pattern contains
+  Here are some other commands that find matches for regular
+expressions.  They all ignore case in matching, if the pattern contains
 no upper-case letters and @code{case-fold-search} is non-@code{nil}.
 Aside from @code{multi-occur} and @code{multi-occur-in-matching-buffers},
-which always search the whole buffer, all operate on the text from point
-to the end of the buffer, or on the region if it is active.
+which always search the whole buffer, all of the commands operate on the
+text from point to the end of the buffer, or on the region if it is active.
 
 @table @kbd
 @findex multi-isearch-buffers
@@ -1953,19 +1953,27 @@ is not considered a match.
 @kindex RET @r{(Occur mode)}
 @kindex o @r{(Occur mode)}
 @kindex C-o @r{(Occur mode)}
-In the @file{*Occur*} buffer, you can click on each entry, or move
-point there and type @key{RET}, to visit the corresponding position in
-the buffer that was searched.  @kbd{o} and @kbd{C-o} display the match
-in another window; @kbd{C-o} does not select it.  Alternatively, you
-can use the @kbd{M-g M-n} (@code{next-error}) command to visit the
-occurrences one by one (@pxref{Compilation Mode}).
+The @file{*Occur*} buffer uses the Occur mode as its major mode.  You
+can use the @kbd{n} and @kbd{p} keys to move to the next or previous
+match; with prefix numeric argument, these commands move that many
+matches.  Digit keys are bound to @code{digit-argument}, so @kbd{5 n}
+moves to the fifth next match (you don't have to type @kbd{C-u}).
+@key{SPC} and @key{DEL} scroll the @file{*Occur*} buffer up and down.
+Clicking on a match or moving point there and typing @key{RET} visits
+the corresponding position in the original buffer that was searched.
+@kbd{o} and @kbd{C-o} display the match in another window; @kbd{C-o}
+does not select that window.  Alternatively, you can use the @kbd{M-g
+M-n} (@code{next-error}) command to visit the occurrences one by one
+(@pxref{Compilation Mode}).  Finally, @kbd{q} quits the window showing
+the @file{*Occur*} buffer and buries the buffer.
 
 @cindex Occur Edit mode
 @cindex mode, Occur Edit
-Typing @kbd{e} in the @file{*Occur*} buffer switches to Occur Edit
-mode, in which edits made to the entries are also applied to the text
-in the originating buffer.  Type @kbd{C-c C-c} to return to Occur
-mode.
+Typing @kbd{e} in the @file{*Occur*} buffer makes the buffer writable
+and enters the Occur Edit mode, in which you can edit the matching
+lines and have those edits reflected in the text in the originating
+buffer.  Type @kbd{C-c C-c} to leave the Occur Edit mode and return to
+the Occur mode.
 
 @findex list-matching-lines
 The command @kbd{M-x list-matching-lines} is a synonym for @kbd{M-x
diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi
index e966565f00..93f9c779db 100644
--- a/doc/emacs/trouble.texi
+++ b/doc/emacs/trouble.texi
@@ -782,10 +782,12 @@ Emacs, so you will have to report the bug somewhere else.
 
 @item
 The type of machine you are using, and the operating system name and
-version number (again, automatically included by @kbd{M-x
-report-emacs-bug}).  @kbd{M-x emacs-version @key{RET}} provides this
-information too.  Copy its output from the @file{*Messages*} buffer,
-so that you get it all and get it accurately.
+version number (again, automatically included by @w{@kbd{M-x
+report-emacs-bug}}).  @w{@kbd{M-x emacs-version @key{RET}}} provides
+this information too.  Copy its output from the @file{*Messages*}
+buffer, so that you get it all and get it accurately, or use
+@w{@kbd{C-u M-x emacs-version @key{RET}}} to insert the version
+information into the current buffer.
 
 @item
 The operands given to the @code{configure} command when Emacs was
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi
index ccf7e35eee..c7c6c072ee 100644
--- a/doc/emacs/xresources.texi
+++ b/doc/emacs/xresources.texi
@@ -149,6 +149,15 @@ various X toolkits (GTK+, Lucid, etc.)---we indicate below 
when this
 is the case.
 
 @table @asis
+@item @code{alpha} (class @code{Alpha})
+Sets the @samp{alpha} frame parameter, determining frame transparency
+(@pxref{Frame Parameters,,, elisp, The Emacs Lisp Reference Manual}).
+
+@item @code{alphaBackground} (class @code{AlphaBackground})
+Sets the @samp{alpha-background} frame parameter, determining background
+transparency
+(@pxref{Frame Parameters,,, elisp, The Emacs Lisp Reference Manual}).
+
 @item @code{background} (class @code{Background})
 Background color (@pxref{Colors}).
 
@@ -364,6 +373,17 @@ Use some location on display specific to the input method 
for
 displaying the preview text.
 @end table
 
+@item @code{synchronizeResize} (class @code{SynchronizeResize})
+If @samp{off} or @samp{false}, Emacs will not try to tell the window
+manager when it has finished redrawing the display in response to a
+request to resize a frame.  Otherwise, the window manager will
+postpone drawing a frame that was just resized until its contents are
+updated, which prevents blank areas of a frame that have not yet been
+painted from being displayed.  If set to @samp{extended}, it will
+enable use of extended frame synchronization, which might be supported
+by some compositing window managers which don't support basic
+synchronization.
+
 @item @code{verticalScrollBars} (class @code{ScrollBars})
 Give frames scroll bars on the left if @samp{left}, on the right if
 @samp{right}; don't have scroll bars if @samp{off} (@pxref{Scroll Bars}).
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 3ce93200a5..b749d3d892 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -612,6 +612,16 @@ how to display a message and prevent it from being logged:
 @end example
 @end defopt
 
+@defvar messages-buffer-name
+This variable has the name of the buffer where messages should be
+logged to, and defaults to @file{*Messages*}.  Some packages may find
+it useful to temporarily redirect the output to a different buffer
+(perhaps to write the buffer out to a log file later), and they can
+bind this variable to a different buffer name.  (Note that this buffer
+(if it doesn't exist already), will be created and put into
+@code{messages-buffer-mode}.)
+@end defvar
+
   To make @file{*Messages*} more convenient for the user, the logging
 facility combines successive identical messages.  It also combines
 successive related messages for the sake of two cases: question
@@ -2644,9 +2654,10 @@ used automatically to handle certain shades of gray.
 
 @item :font
 The font used to display the face.  Its value should be a font object
-or a fontset.  @xref{Low-Level Font}, for information about font
-objects, font specs, and font entities.  @xref{Fontsets}, for
-information about fontsets.
+or a fontset.  If it is a font object, it specifies the font to be
+used by the face for displaying ASCII characters.  @xref{Low-Level
+Font}, for information about font objects, font specs, and font
+entities.  @xref{Fontsets}, for information about fontsets.
 
 @anchor{face-font-attribute}
 When specifying this attribute using @code{set-face-attribute} or
@@ -3090,13 +3101,19 @@ return value is always specified, use a value of 
@code{default} for
 @var{inherit}.
 
 @defun face-font face &optional frame character
-This function returns the name of the font of face @var{face}.
+This function returns the name of the font used by the specified
+@var{face}.
 
 If the optional argument @var{frame} is specified, it returns the name
-of the font of @var{face} for that frame.  If @var{frame} is omitted or
-@code{nil}, the selected frame is used.  In the latter case, if the
-optional third argument @var{character} is supplied, it returns the font
-name used for @var{character}.
+of the font of @var{face} for that frame; @var{frame} defaults to the
+selected frame if it is @code{nil} or omitted.  If @var{frame} is
+@code{t}, the function reports on the font defaults for @var{face} to
+be used for new frames.
+
+By default, the returned font is for displaying ASCII characters, but
+if @var{frame} is anything but @code{t}, and the optional third
+argument @var{character} is supplied, the function returns the font
+name used by @var{face} for that character.
 @end defun
 
 @defun face-foreground face &optional frame inherit
@@ -7300,7 +7317,7 @@ current buffer, and returns it.
 @end defun
 
 @defun insert-button label &rest properties
-This insert a button with the label @var{label} at point,
+This inserts a button with the label @var{label} at point,
 and returns it.
 @end defun
 
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 2eeb8b7ed7..f8188708e5 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2433,6 +2433,16 @@ opacity when it is not selected.
 
 Some window systems do not support the @code{alpha} parameter for child
 frames (@pxref{Child Frames}).
+
+@vindex alpha-background@r{, a frame parameter}
+@item alpha-background
+@cindex opacity, frame
+@cindex transparency, frame
+Sets the background transparency of the frame.  Unlike the @code{alpha}
+frame parameter, this only controls the transparency of the background
+while keeping foreground elements such as text fully opaque.  It
+should be an integer between 0 and 100, where 0 means
+completely transparent and 100 means completely opaque (default).
 @end table
 
 The following frame parameters are semi-obsolete in that they are
@@ -3744,6 +3754,13 @@ still use a menu keymap to implement it.  To make the 
contents vary, add
 a hook function to @code{menu-bar-update-hook} to update the contents of
 the menu keymap as necessary.
 
+@defvar x-pre-popup-menu-hook
+  A normal hook run immediately before a pop-up menu is displayed,
+either directly by calling @code{x-popup-menu}, or through a menu
+keymap.  It won't be called if @code{x-popup-menu} returns for some
+other reason without displaying a pop-up menu.
+@end defvar
+
 @node Dialog Boxes
 @section Dialog Boxes
 @cindex dialog boxes
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index d07d7b80f5..5f85e501c2 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -2153,8 +2153,8 @@ worry about how many times the body uses the arguments, 
as you do for
 macros.
 
   Alternatively, you can define a function by providing the code which
-will inline it as a compiler macro.  The following macros make this
-possible.
+will inline it as a compiler macro (@pxref{Declare Form}).  The
+following macros make this possible.
 
 @c FIXME: Can define-inline use the interactive spec?
 @defmac define-inline name args [doc] [declare] body@dots{}
@@ -2310,6 +2310,7 @@ which case the warning message gives no extra details).  
@var{when}
 should be a string indicating when the function or macro was first
 made obsolete.
 
+@cindex compiler macro
 @item (compiler-macro @var{expander})
 This can only be used for functions, and tells the compiler to use
 @var{expander} as an optimization function.  When encountering a call to the
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 5957b8ac38..68cd74c7d1 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -1067,13 +1067,8 @@ list elements have these forms:
 The symbol @var{var} was defined as a variable.
 @item (defun . @var{fun})
 The function @var{fun} was defined.
-@item (t . @var{fun})
-The function @var{fun} was previously an autoload before this library
-redefined it as a function.  The following element is always
 @code{(defun . @var{fun})}, which represents defining @var{fun} as a
 function.
-@item (autoload . @var{fun})
-The function @var{fun} was defined as an autoload.
 @item (defface . @var{face})
 The face @var{face} was defined.
 @item (require . @var{feature})
@@ -1096,6 +1091,23 @@ The value of @code{load-history} may have one element 
whose @sc{car} is
 by adding the symbols defined to the element for the file being visited,
 rather than replacing that element.  @xref{Eval}.
 
+@kindex function-history @r{(function symbol property)}
+In addition to @code{load-history}, every function keeps track of its
+own history in the symbol property @code{function-history}.
+The reason why functions are treated specially in this respect is that
+it is common for functions to be defined in two steps in two different
+files (typically, one of them is an autoload), so in order to be
+able to properly @emph{unload} a file, we need to know more precisely
+what that file did to the function definition.
+
+The symbol property @code{function-history} holds a list of the form
+@w{@code{(@var{file1} @var{def2} @var{file2} @var{def3} ...)}}, where
+@var{file1} is the last file that changed the definition and
+@var{def2} was the definition before @var{file1}, set by @var{file2},
+etc.  Logically this list should end with the name of the first file
+that defined this function, but to save space this last element
+is usually omitted.
+
 @node Unloading
 @section Unloading
 @cindex unloading packages
@@ -1110,7 +1122,7 @@ It undefines all functions, macros, and variables defined 
in that
 library with @code{defun}, @code{defalias}, @code{defsubst},
 @code{defmacro}, @code{defconst}, @code{defvar}, and @code{defcustom}.
 It then restores any autoloads formerly associated with those symbols.
-(Loading saves these in the @code{autoload} property of the symbol.)
+(Loading saves these in the @code{function-history} property of the symbol.)
 
 Before restoring the previous definitions, @code{unload-feature} runs
 @code{remove-hook} to remove functions defined by the library from certain
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index e2b39836e6..2ef7de066f 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -1964,8 +1964,26 @@ This function also forces an update of the menu bar and 
frame title.
 @end defun
 
   The selected window's mode line is usually displayed in a different
-color using the face @code{mode-line}.  Other windows' mode lines appear
-in the face @code{mode-line-inactive} instead.  @xref{Faces}.
+color using the face @code{mode-line-active}.  Other windows' mode
+lines appear in the face @code{mode-line-inactive} instead.
+@xref{Faces}.
+
+@defun mode-line-window-selected-p
+If you want to have more extensive differences between the mode lines
+in selected and non-selected windows, you can use this predicate in an
+@code{:eval} construct.  For instance, if you want to display the
+buffer name in bold in selected windows, but in italics in the other
+windows, you can say something like:
+
+@lisp
+(setq-default
+ mode-line-buffer-identification
+ '(:eval (propertize "%12b"
+                    'face (if (mode-line-window-selected-p)
+                              'bold
+                            'italic))))
+@end lisp
+@end defun
 
 @vindex mode-line-compact
   Some modes put a lot of data in the mode line, pushing elements at
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index ed8a919ac7..5d4d378d82 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -3376,56 +3376,13 @@ bottom of files by setting the variable 
@code{enable-local-eval}.
 @xref{File Variables,,, emacs, The GNU Emacs Manual}.
 
 @item
-Synthetic X events.  (Yes, a risk; use @samp{MIT-MAGIC-COOKIE-1} or
-better.)
-
-Emacs accepts synthetic X events generated by the @code{SendEvent}
-request as though they were regular events.  As a result, if you are
-using the trivial host-based authentication, other users who can open X
-connections to your X workstation can make your Emacs process do
-anything, including run other processes with your privileges.
-
-The only fix for this is to prevent other users from being able to open
-X connections.  The standard way to prevent this is to use a real
-authentication mechanism, such as @samp{MIT-MAGIC-COOKIE-1}.  If using
-the @code{xauth} program has any effect, then you are probably using
-@samp{MIT-MAGIC-COOKIE-1}.  Your site may be using a superior
-authentication method; ask your system administrator.
-
-If real authentication is not a possibility, you may be satisfied by
-just allowing hosts access for brief intervals while you start your X
-programs, then removing the access.  This reduces the risk somewhat by
-narrowing the time window when hostile users would have access, but
-@emph{does not eliminate the risk}.
-
-On most computers running Unix and X, you enable and disable
-access using the @code{xhost} command.  To allow all hosts access to
-your X server, use
+Browsing the web.
 
-@example
-xhost +
-@end example
-
-@noindent
-at the shell prompt, which (on an HP machine, at least) produces the
-following message:
-
-@example
-access control disabled, clients can connect from any host
-@end example
-
-To deny all hosts access to your X server (except those explicitly
-allowed by name), use
-
-@example
-xhost -
-@end example
-
-On the test HP computer, this command generated the following message:
-
-@example
-access control enabled, only authorized clients can connect
-@end example
+Emacs relies on C libraries to parse images, and historically, many of
+these have had exploitable weaknesses.  If you're browsing the web
+with the eww browser, it will usually download and display images
+using these libraries.  If an image library has a weakness, it may be
+used by an attacker to gain access.
 
 @end itemize
 
diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi
index b576f383ac..630aaa282f 100644
--- a/doc/misc/gnus-faq.texi
+++ b/doc/misc/gnus-faq.texi
@@ -100,10 +100,9 @@ misprints are the Gnus team's fault, sorry.
 * FAQ 1-1::    What is the latest version of Gnus?
 * FAQ 1-2::    What's new in 5.10?
 * FAQ 1-3::    Where and how to get Gnus?
-* FAQ 1-4::    What to do with the tarball now?
-* FAQ 1-5::    I sometimes read references to No Gnus and Oort Gnus,
+* FAQ 1-4::    I sometimes read references to No Gnus and Oort Gnus,
                what are those?
-* FAQ 1-6::    Which version of Emacs do I need?
+* FAQ 1-5::    Which version of Emacs do I need?
 @end menu
 
 @node FAQ 1-1
@@ -165,34 +164,6 @@ Gnus is bundled with Emacs.
 @node FAQ 1-4
 @subsubheading Question 1.4
 
-What to do with the tarball now?
-
-@subsubheading Answer
-
-Untar it via @samp{tar xvzf gnus.tar.gz} and do the common
-@samp{./configure; make; make install} circle.
-(under MS-Windows either get the Cygwin environment from
-@uref{https://www.cygwin.com}
-which allows you to do what's described above or unpack the
-tarball with some packer (e.g., Winace)
-and use the batch-file make.bat included in the tarball to install
-Gnus.) If you don't want to (or aren't allowed to) install Gnus
-system-wide, you can install it in your home directory and add the
-following lines to your ~/.emacs:
-
-@example
-(add-to-list 'load-path "/path/to/gnus/lisp")
-(add-to-list 'Info-default-directory-list "/path/to/gnus/texi/")
-@end example
-@noindent
-
-Make sure that you don't have any Gnus related stuff
-before this line, on MS Windows use something like
-"C:/path/to/lisp" (yes, "/").
-
-@node FAQ 1-5
-@subsubheading Question 1.5
-
 I sometimes read references to No Gnus and Oort Gnus,
 what are those?
 
@@ -205,8 +176,8 @@ once become Gnus 5.12 or Gnus 6. (If you're wondering why
 not 5.11, the odd version numbers are normally used for
 the Gnus versions bundled with Emacs)
 
-@node FAQ 1-6
-@subsubheading Question 1.6
+@node FAQ 1-5
+@subsubheading Question 1.5
 
 Which version of Emacs do I need?
 
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index ea544218ec..8ee4ab24cd 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -4164,8 +4164,10 @@ methods}.  Internally, file archives are mounted via the
 @acronym{GVFS} @option{archive} method.
 
 A file archive is a regular file of kind @file{/path/to/dir/file.EXT}.
-The extension @samp{.EXT} identifies the type of the file archive.  A
-file inside a file archive, called archive file name, has the name
+The extension @samp{.EXT} identifies the type of the file archive.  To
+examine the contents of an archive with Dired, open file name as if it
+were a directory (i.e., open @file{/path/to/dir/file.EXT/}).  A file
+inside a file archive, called archive file name, has the name
 @file{/path/to/dir/file.EXT/dir/file}.
 
 Most of the @ref{Magic File Names, , magic file name operations,
diff --git a/etc/NEWS b/etc/NEWS
index d1eaf08036..cd5bd8b71c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -119,9 +119,28 @@ This is to open up the 'C-x 8 .' map to bind further 
characters there.
 This is for compatibility with the shell versions of these commands,
 which don't handle options like '--help' in any special way.
 
+---
+** The 'delete-forward-char' command now deletes by grapheme clusters.
+This command is by default bound to the <Delete> function key
+(a.k.a. <deletechar>).  When invoked without a prefix argument or with
+a positive prefix numeric argument, the command will now delete
+complete grapheme clusters produced by character composition.  For
+example, if point is before an Emoji sequence, pressing <Delete> will
+delete the entire sequence, not just a single character at its
+beginning.
+
+** 'load-history' does not treat autoloads specially any more.
+An autoload definition appears just as a (defun . NAME) and the
+(t . NAME) entries are not generated any more.
 
 * Changes in Emacs 29.1
 
+---
+** New user option 'find-library-include-other-files'.
+If set to nil, commands like 'M-x find-library' will only include library
+files in the completion candidates.  The default is t, which preserves
+previous behavior, whereby non-library files could also be included.
+
 ** New command 'sqlite-mode-open-file' for examining an sqlite3 file.
 This uses the new 'sqlite-mode' which allows listing the tables in a
 DB file, and examining and modifying the columns and the contents of
@@ -164,6 +183,19 @@ and pop-up menus.
 This controls the style of the pre-edit and status areas of X input
 methods.
 
++++
+** On X11, Emacs now tries to synchronize window resize with the window 
manager.
+This leads to less flicker and empty areas of a frame being displayed
+when a frame is being resized.  Unfortunately, it does not work on
+some ancient buggy window managers, so if Emacs appears to freeze, but
+is still responive to input, you can turn it off by setting the X
+resource "synchronizeResize" to "off".
+
++++
+** New frame parameter 'alpha-background' and X resource "alphaBackground".
+This controls the opacity of the text background when running on a
+composited display.
+
 ---
 ** New user option 'x-gtk-use-native-input'.
 This controls whether or not GTK input methods are used by Emacs,
@@ -407,6 +439,11 @@ When non-nil, if the point is in a closing delimiter and 
the opening
 delimiter is offscreen, shows some context around the opening
 delimiter in the echo area.  Default nil.
 
+May also be set to the symbol 'child-frame' in which case the context
+is shown in a child frame at the top left of the current window on
+graphical frames.  On non-graphical frames, the context is shown in
+the echo area.
+
 ** Comint
 
 +++
@@ -899,6 +936,10 @@ Enabling this minor mode turns on hiding header material, 
like
 
 * New Modes and Packages in Emacs 29.1
 
+---
+** New theme 'leuven-dark'.
+This is a dark version of the 'leuven' theme.
+
 +++
 ** New mode 'erts-mode'.
 This mode is used to edit files geared towards testing actions in
@@ -1013,6 +1054,16 @@ functions.
 
 * Lisp Changes in Emacs 29.1
 
++++
+** New utility predicate 'mode-line-window-selected-p'.
+This is meant to be used from ':eval' mode line constructs to create
+different mode line looks for selected and unselected windows.
+
++++
+** New variable 'messages-buffer-name'.
+This variable (defaulting to "*Messages*") allows packages to override
+where messages are logged.
+
 +++
 ** New function 'readablep'.
 This function says whether an object can be written out and then
@@ -1075,6 +1126,11 @@ This event is sent when a user performs a pinch gesture 
on a touchpad,
 which is comprised of placing two fingers on the touchpad and moving
 them towards or away from each other.
 
++++
+** New hook 'x-pre-popup-menu-hook'.
+This hook is run before 'x-popup-menu' is about to display a
+deck-of-cards menu on screen.
+
 ** Text security and suspiciousness
 
 +++
@@ -1210,6 +1266,20 @@ inhibits 'isearch' matching the STRING parameter.
 ** New function 'replace-regexp-function'.
 It can be used to implement own regexp syntax for search/replace.
 
+---
+** New variables to customize defaults of FROM for query-replace commands.
+The new variable 'query-replace-read-from-default' can be set to a
+function that returns the default value of FROM when 'query-replace'
+prompts for a string to be replaced.  An example of such a function is
+'find-tag-default'.
+
+The new variable 'query-replace-read-from-regexp-default' can be set
+to a function (such as 'find-tag-default-as-regexp') that returns the
+default value of FROM when 'query-replace-regexp' prompts for a regexp
+whose matches are to be replaced.  If these variables are nil (which
+is the default), 'query-replace' and 'query-replace-regexp' take the
+default value from the previous FROM-TO pair.
+
 ---
 ** New user option 'pp-use-max-width'.
 If non-nil, 'pp' will attempt to limit the line length when formatting
@@ -1447,6 +1517,9 @@ The property ':position' now specifies the position of 
the underline
 when used as part of a property list specification for the
 ':underline' attribute.
 
+** 'defalias' records a more precise history of definitions.
+This is recorded in the `function-history` symbol property.
+
 
 * Changes in Emacs 29.1 on Non-Free Operating Systems
 
diff --git a/etc/NEWS.28 b/etc/NEWS.28
index 1e882883b5..58c7c44a2b 100644
--- a/etc/NEWS.28
+++ b/etc/NEWS.28
@@ -33,8 +33,8 @@ more details.
 
 If you build Emacs with native compilation, but without zlib, be sure
 to configure with the '--without-compress-install' option, so that the
-installed *.el files are not compressed; otherwise, you will not be
-able to use JIT native compilation of the installed *.el files.
+installed "*.el" files are not compressed; otherwise, you will not be
+able to use JIT native compilation of the installed "*.el" files.
 
 Note that JIT native compilation is done in a fresh session of Emacs
 that is run in a subprocess, so it can legitimately report some
@@ -650,12 +650,12 @@ functions.
 *** The 'help-for-help' ('C-h C-h') screen has been redesigned.
 
 +++
-*** New convenience commands with short keys in the Help buffer.
+*** New convenience commands with short keys in the "*Help*" buffer.
 New command 'help-view-source' ('s') will view the source file (if
 any) of the current help topic.  New command 'help-goto-info' ('i')
 will look up the current symbol (if any) in Info.  New command
 'help-customize' ('c') will customize the user option or the face
-(if any) whose doc string is being shown in the Help buffer.
+(if any) whose doc string is being shown in the "*Help*" buffer.
 
 ---
 *** New user option 'describe-bindings-outline'.
@@ -664,9 +664,9 @@ can provide a better overview in a long list of available 
bindings.
 
 +++
 *** New commands to describe buttons and widgets.
-'widget-describe' (on a widget) will pop up a help buffer and give a
-description of the properties.  Likewise 'button-describe' does the
-same for a button.
+'widget-describe' (on a widget) will pop up the "*Help*" buffer and
+give a description of the properties.  Likewise 'button-describe' does
+the same for a button.
 
 ---
 *** Improved "find definition" feature of "*Help*" buffers.
@@ -731,7 +731,7 @@ result of this command.
 
 +++
 *** New desktop integration for connecting to the server.
-If your operating system’s desktop environment is
+If your operating system's desktop environment is
 freedesktop.org-compatible (which is true of most GNU/Linux and other
 recent Unix-like desktops), you may use the new "Emacs (Client)"
 desktop menu entry to open files in an existing Emacs instance rather
@@ -987,7 +987,7 @@ This is to keep the same behavior as Eshell.
 
 ---
 ** In 'nroff-mode', 'center-line' is no longer bound to a key.
-The original key binding was 'M-s', which interfered with I-search,
+The original key binding was 'M-s', which interfered with Isearch,
 since the latter uses 'M-s' as a prefix key of the search prefix map.
 
 ---
@@ -1193,7 +1193,7 @@ When called interactively, 'goto-char' now offers the 
position at
 point as the default.
 
 ** Auto-saving via 'auto-save-visited-mode' can now be inhibited.
-Set the variable 'auto-save-visited-mode' buffer-locally to nil to
+Set the user option 'auto-save-visited-mode' buffer-locally to nil to
 achieve that.
 
 +++
@@ -1264,11 +1264,11 @@ end of the current match.
 *** New user option 'isearch-allow-motion'.
 When 'isearch-allow-motion' is set, the commands 'beginning-of-buffer',
 'end-of-buffer', 'scroll-up-command' and 'scroll-down-command', when
-invoked during I-search, move respectively to the first occurrence of
+invoked during Isearch, move respectively to the first occurrence of
 the current search string in the buffer, the last one, the first one
 after the current window, and the last one before the current window.
 Additionally, users can change the meaning of other motion commands
-during I-search by using their 'isearch-motion' property.  The user
+during Isearch by using their 'isearch-motion' property.  The user
 option 'isearch-motion-changes-direction' controls whether the
 direction of the search changes after a motion command.
 
@@ -1294,9 +1294,9 @@ directory to display.
 
 +++
 *** Behavior change on 'dired-do-chmod'.
-As a security precaution, Dired's M command no longer follows symbolic
-links.  Instead, it changes the symbolic link's own mode; this always
-fails on platforms where such modes are immutable.
+As a security precaution, Dired's 'M' command no longer follows
+symbolic links.  Instead, it changes the symbolic link's own mode;
+this always fails on platforms where such modes are immutable.
 
 ---
 *** Behavior change on 'dired-clean-confirm-killing-deleted-buffers'.
@@ -1471,7 +1471,7 @@ key             binding
 / v             package-menu-filter-by-version
 / m             package-menu-filter-marked
 / u             package-menu-filter-upgradable
-/ /             package-menu-filter-clear
+/ /             package-menu-clear-filter
 
 *** Option to automatically native-compile packages upon installation.
 Customize the user option 'package-native-compile' to enable automatic
@@ -1589,7 +1589,7 @@ time zones will use a form like "+0100" instead of "CET".
 If creating the imenu index takes longer than specified by this
 option (default 5 seconds), imenu indexing is stopped.
 
-** ido
+** Ido
 
 ---
 *** Switching on 'ido-mode' now also overrides 'ffap-file-finder'.
@@ -1662,7 +1662,7 @@ buffers.
 ** Shell
 
 ---
-*** New command in 'shell-mode': 'narrow-to-prompt'.
+*** New command in 'shell-mode': 'shell-narrow-to-prompt'.
 This is bound to 'C-x n d' in 'shell-mode' buffers, and narrows to the
 command line under point (and any following output).
 
@@ -1672,7 +1672,7 @@ If non-nil, 'shell-mode' handles implicit "cd" commands, 
changing the
 directory if the command is a directory.  Useful for shells like "zsh"
 that has this feature.
 
-** term-mode
+** Term mode
 
 ---
 *** New user option 'term-scroll-snap-to-bottom'.
@@ -1681,7 +1681,7 @@ that the prompt is on the final line in the window.  
Setting this new
 user option to nil inhibits this behavior.
 
 ---
-*** New user option 'term-set-terminal-size'
+*** New user option 'term-set-terminal-size'.
 If non-nil, the 'LINES' and 'COLUMNS' environment variables will be set
 based on the current window size.  In previous versions of Emacs, this
 was always done (and that could lead to odd displays when resizing the
@@ -1706,7 +1706,7 @@ emacs-version)'.  Other package names, like "tramp", 
could also be included.
 
 ---
 *** Eshell no longer re-initializes its keymap every call.
-This allows users to use (define-key eshell-mode-map ...) as usual.
+This allows users to use '(define-key eshell-mode-map ...)' as usual.
 Some modules have their own minor mode now to account for these
 changes.
 
@@ -1717,7 +1717,7 @@ will create a bookmark that opens the current directory 
in Eshell.
 ** Archive mode
 
 ---
-*** Archive Mode can now parse ".squashfs" files.
+*** Archive mode can now parse ".squashfs" files.
 
 *** Can now modify members of 'ar' archives.
 
@@ -1733,7 +1733,7 @@ and which are kept hidden.
 This command extracts the file at point and writes its data to a
 file.
 
-** browse-url
+** Browse URL
 
 *** Added support for custom URL handlers.
 There is a new variable 'browse-url-default-handlers' and a user
@@ -1769,7 +1769,7 @@ passed to the browser.
 *** Support for the Mosaic browser has been removed.
 This support has been obsolete since 25.1.
 
-** Completion List Mode
+** Completion list mode
 
 *** Improved navigation in the "*Completions*" buffer.
 New key bindings have been added to 'completion-list-mode': 'n' and
@@ -1777,7 +1777,7 @@ New key bindings have been added to 
'completion-list-mode': 'n' and
 minibuffer and back to the completion list buffer.
 
 +++
-** profiler.el
+** Profiler
 The results displayed by 'profiler-report' now have the usage figures
 at the left hand side followed by the function name.  This is intended
 to make better use of the horizontal space, in particular eliminating
@@ -1793,8 +1793,8 @@ prompt prefix.
 
 +++
 *** New minor modes 'icomplete-vertical-mode' and 'fido-vertical-mode'.
-These modes modify Icomplete ('M-x icomplete-mode') and Fido ('M-x
-fido-mode'), to display completion candidates vertically instead of
+These modes modify Icomplete ('icomplete-mode') and Fido
+('fido-mode'), to display completion candidates vertically instead of
 horizontally.  In Icomplete, completions are rotated and selection
 kept at the top.  In Fido, completions scroll like a typical dropdown
 widget.  Both these new minor modes will turn on their non-vertical
@@ -1834,7 +1834,7 @@ Also new mode 'windmove-mode' enables the customized 
keybindings.
 ** Occur mode
 
 ---
-*** New bindings in occur-mode.
+*** New bindings in 'occur-mode'.
 The command 'next-error-no-select' is now bound to 'n' and
 'previous-error-no-select' is bound to 'p'.
 
@@ -1856,8 +1856,8 @@ The method of highlighting is specified by the user 
options
 The value was previously always a marker set to the start of the first
 match on the line but can now also be a list of '(BEGIN . END)' pairs
 of markers delimiting each match on the line.
-This is a fully compatible change to the internal occur-mode
-implementation, and code creating their own occur-mode buffers will
+This is a fully compatible change to the internal 'occur-mode'
+implementation, and code creating their own 'occur-mode' buffers will
 work as before.
 
 ** Emacs Lisp mode
@@ -1871,7 +1871,7 @@ The presence of a space between an open paren and a 
symbol now is
 taken as a statement by the programmer that this should be indented
 as a data list rather than as a piece of code.
 
-** Lisp Mode
+** Lisp mode
 
 *** New minor mode 'cl-font-lock-built-in-mode' for 'lisp-mode'.
 The mode provides refined highlighting of built-in functions, types,
@@ -2159,8 +2159,8 @@ take the actual screenshot, and defaults to "ImageMagick 
import".
 +++
 *** New user option 'smtpmail-store-queue-variables'.
 If non-nil, SMTP variables will be stored together with the queued
-messages, and will then be used when sending with
-'M-x smtpmail-send-queued-mail'.
+messages, and will then be used when sending with command
+'smtpmail-send-queued-mail'.
 
 +++
 *** Allow direct selection of smtp authentication mechanism.
@@ -2263,7 +2263,7 @@ set user option 'tramp-allow-unsafe-temporary-files' to t.
 +++
 *** 'make-directory' of a remote directory honors the default file modes.
 
-** gdb-mi
+** GDB/MI
 
 *** New user option 'gdb-registers-enable-filter'.
 If non-nil, apply a register filter based on
@@ -2377,7 +2377,7 @@ prefix on the Subject line in various languages.
 If set non-nil, showing an unseen message will set the Rmail buffer's
 modified flag.  The default is nil, to preserve the old behavior.
 
-** CC Mode
+** CC mode
 
 +++
 *** Added support for Doxygen documentation style.
@@ -2527,7 +2527,7 @@ However, if "~/Downloads/" already exists, that will 
continue to be
 used.
 
 ---
-*** The command 'eww-follow-link' now supports custom mailto: handlers.
+*** The command 'eww-follow-link' now supports custom 'mailto:' handlers.
 The function that is invoked when clicking on or otherwise following a
 'mailto:' link in an EWW buffer can now be customized.  For more
 information, see the related entry about 'shr-browse-url' below.
@@ -2540,9 +2540,9 @@ will create a bookmark that opens the current URL in EWW.
 ** SHR
 
 ---
-*** The command 'shr-browse-url' now supports custom mailto handlers.
+*** The command 'shr-browse-url' now supports custom 'mailto:' handlers.
 Clicking on or otherwise following a 'mailto:' link in an HTML buffer
-rendered by SHR previously invoked the command 'browse-url-mailto'.
+rendered by SHR previously invoked the command 'browse-url-mail'.
 This is still the case by default, but if you customize
 'browse-url-mailto-function' or 'browse-url-handlers' to call some
 other function, it will now be called instead of the default.
@@ -2652,7 +2652,7 @@ behavior of Xref commands such as 'xref-find-references',
 display many matches that the user would like to
 visit.  'xref-auto-jump-to-first-xref' changes their behavior much in
 the same way as 'xref-auto-jump-to-first-definition' affects the
-"find-definitions" commands.
+'xref-find-definitions*' commands.
 
 ---
 *** New user options 'xref-search-program' and 'xref-search-program-alist'.
@@ -2730,7 +2730,7 @@ the function 'format-spec' documented under node "(elisp) 
Custom Format
 Strings".  The new syntax includes specifiers for padding and
 truncation, amongst other things.
 
-** bug-reference.el
+** Bug Reference
 
 ---
 *** Bug reference mode uses auto-setup.
@@ -2747,7 +2747,7 @@ variables 'bug-reference-setup-from-vc-alist',
 'bug-reference-setup-from-mail-alist', and
 'bug-reference-setup-from-irc-alist'.
 
-** HTML Mode
+** HTML mode
 
 ---
 *** A new skeleton for adding relative URLs has been added.
@@ -2781,7 +2781,7 @@ This face is used for error messages from 'diff'.
 *** New command 'diff-refresh-hunk'.
 This new command (bound to 'C-c C-l') regenerates the current hunk.
 
-** thing-at-point
+** Thing at point
 
 +++
 *** New 'thing-at-point' target: 'existing-filename'.
@@ -2797,7 +2797,7 @@ If point is inside a string, it returns that string.
 This allows mode-specific alterations to how 'thing-at-point' works.
 
 ---
-*** thing-at-point now respects fields.
+*** 'thing-at-point' now respects fields.
 'thing-at-point' (and all functions that use it, like
 'symbol-at-point') will narrow to the current field (if any) before
 trying to identify the thing at point.
@@ -2806,7 +2806,7 @@ trying to identify the thing at point.
 *** New function 'thing-at-mouse'.
 This is like 'thing-at-point', but uses the mouse event position instead.
 
-** Image-Dired
+** Image Dired
 
 +++
 *** New user option 'image-dired-thumb-visible-marks'.
@@ -2886,7 +2886,7 @@ The command previously extended the start of the region 
to the start
 of the line, but will now actually send the marked region, as
 documented.
 
-** Ruby Mode
+** Ruby mode
 
 ---
 *** 'ruby-use-smie' is declared obsolete.
@@ -2899,7 +2899,7 @@ This previously used to align subsequent lines with the 
last sibling,
 but it now aligns with the first sibling (which is the preferred style
 in Ruby).
 
-** CPerl Mode
+** CPerl mode
 
 ---
 *** New face 'perl-heredoc', used for heredoc elements.
@@ -2916,7 +2916,7 @@ of conditionals.
 *** New face 'perl-non-scalar-variable'.
 This is used to fontify non-scalar variables.
 
-** Octave Mode
+** Octave mode
 
 +++
 *** Line continuations in double-quoted strings now use a backslash.
@@ -2928,7 +2928,7 @@ everywhere else.
 +++
 ** EasyPG
 GPG key servers can now be queried for keys with the
-'M-x epa-search-keys' command.  Keys can then be added to your
+'epa-search-keys' command.  Keys can then be added to your
 personal key ring.
 
 ** Etags
@@ -2948,7 +2948,7 @@ invoked with the '--declarations' command-line option.
 
 +++
 *** Support for OSC escape sequences.
-Adding the new 'comint-osc-process-output' to
+Adding the new function 'comint-osc-process-output' to
 'comint-output-filter-functions' enables the interpretation of OSC
 ("Operating System Command") escape sequences in comint buffers.  By
 default, only OSC 8, for hyperlinks, and OSC 7, for directory
@@ -2960,7 +2960,7 @@ sequences.
 *** 'comint-delete-output' can now save deleted text in the kill-ring.
 Interactively, 'C-u C-c C-o' triggers this new optional behavior.
 
-** ansi-color.el
+** ANSI color
 
 ---
 *** Colors are now defined by faces.
@@ -2980,7 +2980,7 @@ non-nil.
 *** Starting with Emacs 28.1 and ERC 5.4, see the ERC-NEWS file for
 user-visible changes in ERC.
 
-** xwidget-webkit mode
+** Xwidget Webkit mode
 
 ---
 *** New xwidget commands.
@@ -3062,7 +3062,7 @@ Shift while typing 'C-a', i.e. 'C-S-a', will now 
highlight the text.
 
 ---
 *** New user option 'gravatar-service' for host to query for gravatars.
-Defaults to 'libravatar', with 'unicornify' and 'gravatar' as options.
+Defaults to 'gravatar', with 'unicornify' and 'libravatar' as options.
 
 ** MH-E mail handler for Emacs
 
@@ -3199,8 +3199,8 @@ user-defined sorting schemes.
 ---
 *** New user option 'reveal-auto-hide'.
 If non-nil (the default), revealed text is automatically hidden when
-point leaves the text.  If nil, the text is not hidden again.  Instead
-'M-x reveal-hide-revealed' can be used to hide all the revealed text.
+point leaves the text.  If nil, the text is not hidden again.  Instead the
+command 'reveal-hide-revealed' can be used to hide all the revealed text.
 
 ---
 *** New user option 'ffap-file-name-with-spaces'.
@@ -3241,7 +3241,7 @@ different timezone causing a difference in the date.
 
 ---
 *** Loading dunnet.el in batch mode doesn't start the game any more.
-Instead you need to do "emacs -f dun-batch" to start the game in
+Instead you need to do "emacs --batch -f dunnet" to start the game in
 batch mode.
 
 
@@ -3270,7 +3270,7 @@ window navigation direction with 'C-x o M-- o o' or to 
set a new step
 with 'C-x { C-5 { { {', which will set the window resizing step to 5
 columns.
 
-'M-x describe-repeat-maps' will display a buffer showing
+Command 'describe-repeat-maps' will display a buffer showing
 which commands are repeatable in 'repeat-mode'.
 
 ---
@@ -3713,7 +3713,7 @@ user option has been renamed to 
'find-library-source-path', and
 ---
 ** The macro 'vc-call' no longer evaluates its second argument twice.
 
-** Xref migrated from EIEIO to cl-defstruct for its core objects.
+** Xref migrated from EIEIO to 'cl-defstruct' for its core objects.
 This means that 'oref' and 'with-slots' no longer works on them, and
 'make-instance' can no longer be used to create those instances (which
 wasn't recommended anyway).  Packages should restrict themselves to
@@ -3738,8 +3738,8 @@ or if the mode is a minor mode, when the current buffer 
has that
 minor mode activated.  Note that using this form will create byte code
 that is not compatible with byte code in previous Emacs versions.
 Also note that by default these annotations have no effect, unless the
-new option 'read-extended-command-predicate' option is customized to call
-'command-completion-default-include-p' or a similar function.
+new user option 'read-extended-command-predicate' option is customized
+to call 'command-completion-default-include-p' or a similar function.
 
 +++
 ** New 'declare' forms to control completion of commands in 'M-x'.
@@ -3754,14 +3754,14 @@ MODE..., or, if it's a minor mode, when that minor mode 
is enabled in
 the current buffer.
 
 Note that these forms will only have their effect if the
-'read-extended-command-predicate' option is customized to call
+'read-extended-command-predicate' user option is customized to call
 'command-completion-default-include-p' or a similar function.  The
 default value of 'read-extended-command-predicate' is nil, which means
 no commands that match what you have typed are excluded from being
 completion candidates.
 
 +++
-** 'define-minor-mode'  now takes an ':interactive' argument.
+** 'define-minor-mode' now takes an ':interactive' argument.
 This can be used for specifying which modes this minor mode is meant
 for, or to make the new minor mode non-interactive.  The default value
 is t.
@@ -3841,7 +3841,7 @@ presented to users or passed on to other applications.
 This does the same as the old command 'update-directory-autoloads',
 but has different semantics: Instead of passing in the output file via
 the dynamically bound 'generated-autoload-file' variable, the output
-file is now a explicit parameter.
+file is now an explicit parameter.
 
 ---
 ** Dragging a file into Emacs pushes the file name onto 'file-name-history'.
@@ -3874,11 +3874,11 @@ summaries will include the failing condition.
 *** New byte-compiler check for missing dynamic variable declarations.
 It is meant as an (experimental) aid for converting Emacs Lisp code
 to lexical binding, where dynamic (special) variables bound in one
-file can affect code in another.  For details, see the manual section
+file can affect code in another.  For details, see the Info node
 "(elisp) Converting to Lexical Binding".
 
 +++
-*** 'byte-recompile-directory' can now compile symlinked ".el" files.
+*** 'byte-recompile-directory' can now compile symlinked "*.el" files.
 This is achieved by giving a non-nil FOLLOW-SYMLINKS parameter.
 
 ---
@@ -3932,7 +3932,7 @@ always coincide with the keys that were actually merged, 
which could
 be 'equal' instead.  The function argument is now called whenever keys
 are merged, for greater consistency with 'map-merge' and 'map-elt'.
 
-** pcase
+** Pcase
 
 +++
 *** The 'or' pattern now binds the union of the vars of its sub-patterns.
@@ -3963,8 +3963,8 @@ destructuring patterns in a 'setq' form.
 *** Edebug specification lists can use some new keywords:
 
 +++
-**** '&interpose SPEC FUN ARGS..' lets FUN control parsing after SPEC.
-More specifically, FUN is called with 'HEAD PF ARGS..' where
+**** '&interpose SPEC FUN ARGS...' lets FUN control parsing after SPEC.
+More specifically, FUN is called with 'HEAD PF ARGS...' where
 PF is a parsing function that expects a single argument (the specs to
 use) and HEAD is the code that matched SPEC.
 
@@ -3978,7 +3978,7 @@ use) and HEAD is the code that matched SPEC.
 
 +++
 *** Type aliases for module functions and finalizers.
-The module header 'emacs-module.h' now contains type aliases
+The module header "emacs-module.h" now contains type aliases
 'emacs_function' and 'emacs_finalizer' for module functions and
 finalizers, respectively.
 
@@ -4012,8 +4012,8 @@ symbolic form found in Lisp source that "abbreviates" a 
symbol's print
 name.  Among other applications, this feature can be used to avoid
 name clashes and namespace pollution by renaming an entire file's
 worth of symbols with proper and longer prefixes, without actually
-touching the Lisp source.  For details, see the manual section
-"(elisp) Shorthands".
+touching the Lisp source.  For details, see the Info node "(elisp)
+Shorthands".
 
 +++
 ** New function 'string-search'.
@@ -4286,7 +4286,7 @@ Signaling it has almost the same effect as 'quit' except 
that it
 doesn't cause keyboard macro termination.
 
 +++
-** New error 'remote-file-error', a subcategory of 'file-error'.
+** New error symbol 'remote-file-error', a subcategory of 'file-error'.
 It is signaled if a remote file operation fails due to internal
 reasons, and could block Emacs.  It does not replace 'file-error'
 signals for the usual cases.  Timers, process filters and process
@@ -4296,10 +4296,11 @@ against this error.
 If such an error occurs, please report this as bug via 'M-x report-emacs-bug'.
 Until it is solved you could ignore such errors by performing
 
-    (setq debug-ignored-errors (cons 'remote-file-error debug-ignored-errors))
+    (setq debug-ignored-errors
+          (cons 'remote-file-error debug-ignored-errors))
 
 +++
-** New macro 'named-let' added to subr-x.el.
+** New macro 'named-let'.
 It provides Scheme's "named let" looping construct.
 
 ---
@@ -4329,12 +4330,12 @@ and display the result.
 
 +++
 ** 'read-number' now has its own history variable.
-Additionally, the function now accepts a HIST argument which can be
-used to specify a custom history variable.
+Additionally, the function now accepts an optional HIST argument which
+can be used to specify a custom history variable.
 
 +++
 ** 'set-window-configuration' now takes two optional parameters,
-'dont-set-frame' and 'dont-set-miniwindow'.  The first of these, when
+DONT-SET-FRAME and DONT-SET-MINIWINDOW.  The first of these, when
 non-nil, instructs the function not to select the frame recorded in
 the configuration.  The second prevents the current minibuffer being
 replaced by the one stored in the configuration.
@@ -4445,7 +4446,7 @@ has been the case since Emacs 24.4 but was not announced 
or documented
 until now.  (Checkdoc has also been updated to accept this convention.)
 
 +++
-** The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol.
+** The UNIQUIFY argument in 'auto-save-file-name-transforms' can be a symbol.
 If this symbol is one of the members of 'secure-hash-algorithms',
 Emacs constructs the nondirectory part of the auto-save file name by
 applying that 'secure-hash' to the buffer file name.  This avoids any
@@ -4533,7 +4534,7 @@ locales.  They are also available as aliases 
'ebcdic-cp-*' (e.g.,
 support these coding-systems.
 
 +++
-** New 'Bindat type expression' description language.
+** New "Bindat type expression" description language.
 This new system is provided by the new macro 'bindat-type' and
 obsoletes the old data layout specifications.  It supports
 arbitrary-size integers, recursive types, and more.  See the Info node
@@ -4581,7 +4582,7 @@ to select previous/next frame are still bound to 's-~' 
and 's-`'.
 ---
 ** On macOS, Xwidget is now supported.
 If Emacs was built with xwidget support, you can access the embedded
-webkit browser with 'M-x xwidget-webkit-browse-url'.  Viewing two
+webkit browser with command 'xwidget-webkit-browse-url'.  Viewing two
 instances of xwidget webkit is not supported.
 
 ---
diff --git a/etc/publicsuffix.txt b/etc/publicsuffix.txt
index fb018d626a..c67235fae0 100644
--- a/etc/publicsuffix.txt
+++ b/etc/publicsuffix.txt
@@ -3765,11 +3765,10 @@ org.kw
 // ky : http://www.icta.ky/da_ky_reg_dom.php
 // Confirmed by registry <kysupport@perimeterusa.com> 2008-06-17
 ky
-edu.ky
-gov.ky
 com.ky
-org.ky
+edu.ky
 net.ky
+org.ky
 
 // kz : https://en.wikipedia.org/wiki/.kz
 // see also: http://www.nic.kz/rules/index.jsp
@@ -11106,6 +11105,10 @@ cloudns.us
 // Submitted by Angelo Gladding <angelo@lahacker.net>
 cnpy.gdn
 
+// Codeberg e. V. : https://codeberg.org
+// Submitted by Moritz Marquardt <git@momar.de>
+codeberg.page
+
 // CoDNS B.V.
 co.nl
 co.no
@@ -11965,6 +11968,10 @@ futuremailing.at
 // Submitted by David Illsley <david.illsley@digital.cabinet-office.gov.uk>
 service.gov.uk
 
+// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk
+// Submitted by Jamie Tanna <jamie.tanna@digital.cabinet-office.gov.uk>
+api.gov.uk
+
 // Gehirn Inc. : https://www.gehirn.co.jp/
 // Submitted by Kohei YOSHIDA <tech@gehirn.co.jp>
 gehirn.ne.jp
@@ -13480,6 +13487,10 @@ gdynia.pl
 med.pl
 sopot.pl
 
+// team.blue https://team.blue
+// Submitted by Cedric Dubois <cedric.dubois@team.blue>
+site.tb-hosting.com
+
 // Teckids e.V. : https://www.teckids.org
 // Submitted by Dominik George <dominik.george@teckids.org>
 edugit.io
diff --git a/etc/themes/leuven-dark-theme.el b/etc/themes/leuven-dark-theme.el
new file mode 100644
index 0000000000..0f4c7920eb
--- /dev/null
+++ b/etc/themes/leuven-dark-theme.el
@@ -0,0 +1,1095 @@
+;;; leuven-dark-theme.el --- Awesome Emacs color theme on dark background
+
+;; Copyright (C) 2003-2022 Free Software Foundation, Inc.
+
+;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")>
+;; Contributor: Thibault Polge <(concat "thibault" at-sign "thb.lt")>
+;; URL: https://github.com/fniessen/emacs-leuven-dark-theme
+;; Version: 20220202.1126
+;; Keywords: color theme
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This elegant Org-enhancing color theme "leuven-dark" ROCKS!
+;; ... and not just for Org mode.
+;;
+;; To use it, put the following in your Emacs configuration file:
+;;
+;;   (load-theme 'leuven-dark t)
+;;
+;; Requirements: Emacs 24+.
+;;
+;; NOTE -- Would you like implement a version of this for dark backgrounds,
+;; please do so!  I'm willing to integrate it...
+
+;;; Code:
+
+;;; Options.
+
+(defgroup leuven-dark nil
+  "Leuven theme options.
+The theme has to be reloaded after changing anything in this group."
+  :group 'faces)
+
+(defcustom leuven-dark-scale-org-document-title t
+  "Scale Org document title.
+This can be nil for unscaled, t for using the theme default, or a scaling
+number."
+  :type '(choice
+          (const :tag "Unscaled" nil)
+          (const :tag "Default provided by theme" t)
+          (number :tag "Set scaling")))
+
+(defcustom leuven-dark-scale-outline-headlines t
+  "Scale `outline' (and `org') level-1 headlines.
+This can be nil for unscaled, t for using the theme default, or a scaling
+number."
+  :type '(choice
+          (const :tag "Unscaled" nil)
+          (const :tag "Default provided by theme" t)
+          (number :tag "Set scaling")))
+
+(defcustom leuven-dark-scale-org-agenda-structure t
+  "Scale Org agenda structure lines, like dates.
+This can be nil for unscaled, t for using the theme default, or a scaling
+number."
+  :type '(choice
+          (const :tag "Unscaled" nil)
+          (const :tag "Default provided by theme" t)
+          (number :tag "Set scaling")))
+
+(defcustom leuven-dark-scale-volatile-highlight t
+  "Increase size in the `next-error' face.
+This can be nil for unscaled, t for using the theme default, or a scaling
+number."
+  :type '(choice
+          (const :tag "Unscaled" nil)
+          (const :tag "Default provided by theme" t)
+          (number :tag "Set scaling")))
+
+;;;###autoload
+(defun leuven-dark-scale-font (control default-height)
+  "Function for splicing optional font heights into face descriptions.
+CONTROL can be a number, nil, or t.  When t, use DEFAULT-HEIGHT."
+  (cond
+   ((numberp control) (list :height control))
+   ((eq t control) (list :height default-height))
+   (t nil)))
+
+;;; Theme Faces.
+
+(deftheme leuven-dark
+  "Face colors with a light background.
+Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff,
+Flyspell, Semantic, and Ansi-Color faces are included -- and much
+more...")
+
+(let ((class '((class color) (min-colors 89)))
+
+      ;; Leuven generic colors.
+      (cancel '(:slant italic :strike-through t :foreground "#5b5660"))
+      (clock-line '(:box (:line-width 1 :color "#cfa161") :foreground 
"#ffffff" :background "#1636ff"))
+      (code-block '(:foreground "#ffff7f" :background "#252046"))
+      (code-inline '(:foreground "#ff9bff" :background "#262031"))
+      (column '(:height 1.0 :weight normal :slant normal :underline nil 
:strike-through nil :foreground "#1e52b8" :background "#252c48"))
+      (completion-inline '(:weight normal :foreground "#443f49" :inherit 
hl-line)) ; Like Google.
+      (completion-other-candidates '(:weight bold :foreground "#ffffff" 
:background "#372a2a"))
+      (completion-selected-candidate '(:weight bold :foreground "#25202a" 
:background "#ffad65"))
+      (diff-added '(:background "#442049"))
+      (diff-changed '(:foreground "#ffff0b" :background "#443f2a"))
+      (diff-header '(:weight bold :foreground "#83ffff" :background "#252073"))
+      (diff-hunk-header '(:foreground "#6bff6f" :background "#252f2a"))
+      (diff-none '(:foreground "#7b777f"))
+      (diff-refine-added '(:background "#6d0d73"))
+      (diff-refine-removed '(:background "#06494f"))
+      (diff-removed '(:background "#25353e"))
+      (directory '(:weight bold :foreground "#ffff0b" :background "#252053"))
+      (file '(:foreground "#ffffff"))
+      (function-param '(:foreground "#de8d83"))
+      (grep-file-name '(:weight bold :foreground "#d8b76b")) ; Used for grep 
hits.
+      (grep-line-number '(:weight bold :foreground "#5fca5b"))
+      (highlight-blue '(:background "#3c312a"))
+      (highlight-blue2 '(:background "#3e2d2f"))
+      (highlight-gray '(:background "#3e3944"))
+      (highlight-green '(:background "#2f0e3a"))
+      (highlight-red '(:background "#063741"))
+      (highlight-yellow '(:background "#2d2058"))
+      (link '(:weight normal :underline t :foreground "#ff925a"))
+      (link-no-underline '(:weight normal :foreground "#ff925a"))
+      (mail-header-name '(:family "Sans Serif" :weight normal :foreground 
"#615c67"))
+      (mail-header-other '(:family "Sans Serif" :slant normal :foreground 
"#9d99a1"))
+      (mail-read '(:foreground "#77737b"))
+      (mail-read-high '(:foreground "#837f87"))
+      (mail-ticked '(:foreground "#06ccff"))
+      (mail-to '(:family "Sans Serif" :underline nil :foreground "#ff925a"))
+      (mail-unread '(:weight bold :foreground "#ffffff"))
+      (mail-unread-high '(:weight bold :foreground "#eea682"))
+      (marked-line '(:foreground "#5affff" :background "#06555f"))
+      (match '(:weight bold :background "#0601ff")) ; occur patterns + match 
in helm for files + match in Org files.
+      (ol1 `(,@(leuven-dark-scale-font leuven-dark-scale-outline-headlines 
1.3) :weight bold :overline "#5d5862" :foreground "#c7c3cb" :background 
"#322d37"))
+      (ol2 '(:height 1.0 :weight bold :overline "#efcab2" :foreground 
"#efcab2" :background "#3d2a2d"))
+      (ol3 '(:height 1.0 :weight bold :foreground "#ffaae3" :background 
"#332038"))
+      (ol4 '(:height 1.0 :weight bold :slant normal :foreground "#1a9cff"))
+      (ol5 '(:height 1.0 :weight bold :slant normal :foreground "#21da7a"))
+      (ol6 '(:height 1.0 :weight bold :slant italic :foreground "#ff883d"))
+      (ol7 '(:height 1.0 :weight bold :slant italic :foreground "#d451d9"))
+      (ol8 '(:height 1.0 :weight bold :slant italic :foreground "#077ffa"))
+      (paren-matched '(:background "#7B4B98")) ; XXX Edited by hqnd.
+      (paren-unmatched '(:weight bold :underline "#06ffff" :foreground 
"#ffffff" :background "#065a64"))
+      (region '(:background "#752c0b"))
+      (shadow '(:foreground "#848088"))
+      (string '(:foreground "#ff7fff")) ; or #34c8d8
+      (subject '(:family "Sans Serif" :weight bold :foreground "#ffffff"))
+      (symlink '(:foreground "#e37233"))
+      (tab '(:foreground "#3a353f" :background "#25202a"))
+      (trailing '(:foreground "#3a353f" :background "#252076"))
+      (volatile-highlight '(:underline nil :foreground "#25202a" :background 
"#66c96f"))
+      (volatile-highlight-supersize `(,@(leuven-dark-scale-font 
leuven-dark-scale-volatile-highlight 1.1) :underline nil :foreground "#25202a" 
:background "#66c96f")) ; flash-region
+      (vc-branch '(:box (:line-width 1 :color "#ff33d2") :foreground "#ffffff" 
:background "#5a015f"))
+      (xml-attribute '(:foreground "#119cd0"))
+      (xml-tag '(:foreground "#56e46f"))
+      (highlight-current-tag '(:background "#3a352a")) ; #342b32 or #0614df
+  )
+
+  (custom-theme-set-faces
+   'leuven-dark
+   `(default ((,class (:foreground "#cfccd2" :background "#25202a"))))
+   `(bold ((,class (:weight bold :foreground "#ffffff"))))
+   `(bold-italic ((,class (:weight bold :slant italic :foreground "#ffffff"))))
+   `(italic ((,class (:slant italic :foreground "#e8e5eb"))))
+   `(underline ((,class (:underline t))))
+   `(cursor ((,class (:background "#e1420b"))))
+
+   ;; Lucid toolkit emacs menus.
+   `(menu ((,class (:foreground "#25202a" :background "#cfccd2"))))
+
+   ;; Highlighting faces.
+   `(fringe ((,class (:foreground "#b76130" :background "#25202a"))))
+   `(highlight ((,class ,highlight-blue)))
+   `(region ((,class ,region)))
+   `(secondary-selection ((,class ,match))) ; Used by Org-mode for 
highlighting matched entries and keywords.
+   `(isearch ((,class (:underline "#ffffff" :foreground "#25202a" :background 
"#aa8b5e"))))
+   `(isearch-fail ((,class (:weight bold :foreground "#ffffff" :background 
"#06333d"))))
+   `(lazy-highlight ((,class (:foreground "#ffffff" :background "#0601ff")))) 
; Isearch others (see `match').
+   `(trailing-whitespace ((,class ,trailing)))
+   `(query-replace ((,class (:inherit isearch))))
+   `(whitespace-hspace ((,class (:foreground "#322d37")))) ; see also 
`nobreak-space'
+   `(whitespace-indentation ((,class ,tab)))
+   `(whitespace-line ((,class (:foreground "#38ffff" :background "#06017f"))))
+   `(whitespace-tab ((,class ,tab)))
+   `(whitespace-trailing ((,class ,trailing)))
+
+   ;; Mode line faces.
+   `(mode-line ((,class (:box (:line-width 1 :color "#e8d0b3") :foreground 
"#7e311e" :background "#cfa161"))))
+   `(mode-line-inactive ((,class (:box (:line-width 1 :color "#b5b1bb") 
:foreground "#322d38" :background "#696371"))))
+   `(mode-line-buffer-id ((,class (:weight bold :foreground "#25202a"))))
+   `(mode-line-emphasis ((,class (:weight bold :foreground "#25202a"))))
+   `(mode-line-highlight ((,class (:foreground "#0601ff"))))
+
+   ;; Escape and prompt faces.
+   `(minibuffer-prompt ((,class (:weight bold :foreground "#ffffff" 
:background "#0628ff"))))
+   `(minibuffer-noticeable-prompt ((,class (:weight bold :foreground "#ffffff" 
:background "#0628ff"))))
+   `(escape-glyph ((,class (:foreground "#ff7138"))))
+   `(error ((,class (:foreground "#06ffff"))))
+   `(warning ((,class (:weight bold :foreground "#065aff"))))
+   `(success ((,class (:foreground "#ff01ff"))))
+
+   ;; Font lock faces.
+   `(font-lock-builtin-face ((,class (:foreground "#ff9029"))))
+   `(font-lock-comment-delimiter-face ((,class (:foreground "#767283")))) ; 
#9a969e
+   `(font-lock-comment-face ((,class (:slant italic :foreground "#767283")))) 
; #9a969e
+   `(font-lock-constant-face ((,class (:foreground "#34c8d8"))))
+   `(font-lock-doc-face ((,class (:foreground "#fd95fa"))))
+   ;; `(font-lock-doc-string-face ((,class (:foreground "#ff7fff")))) ; XEmacs 
only, but is used for HTML exports from org2html (and not interactively)
+   `(font-lock-function-name-face ((,class (:weight normal :foreground 
"#ff996f"))))
+   `(font-lock-keyword-face ((,class (:bold nil :foreground "#ffff0b")))) ; 
#ccab2d
+   `(font-lock-preprocessor-face ((,class (:foreground "#837f87"))))
+   `(font-lock-regexp-grouping-backslash ((,class (:weight bold :inherit 
nil))))
+   `(font-lock-regexp-grouping-construct ((,class (:weight bold :inherit 
nil))))
+   `(font-lock-string-face ((,class ,string)))
+   `(font-lock-type-face ((,class (:weight normal :foreground "#9fcb66"))))
+   `(font-lock-variable-name-face ((,class (:weight normal :foreground 
"#4ac964")))) ; #83ff87
+   `(font-lock-warning-face ((,class (:weight bold :foreground "#06ffff"))))
+
+   ;; Button and link faces.
+   `(link ((,class ,link)))
+   `(link-visited ((,class (:underline t :foreground "#1f879a"))))
+   `(button ((,class (:underline t :foreground "#ff925a"))))
+   `(header-line ((,class (:box (:line-width 1 :color "#ffffff") :foreground 
"#ffffff" :background "#322d37"))))
+
+   ;; Gnus faces.
+   `(gnus-button ((,class (:weight normal))))
+   `(gnus-cite-attribution-face ((,class (:foreground "#b3af59"))))
+   `(gnus-cite-1 ((,class (:foreground "#b3af59" :background "#2d2832"))))
+   `(gnus-cite-2 ((,class (:foreground "#9dffa1" :background "#2d2832"))))
+   `(gnus-cite-3 ((,class (:foreground "#ff8890" :background "#2d2832"))))
+   `(gnus-cite-4 ((,class (:foreground "#6bffff" :background "#2d2832"))))
+   `(gnus-cite-5 ((,class (:foreground "#ffff6f" :background "#2d2832"))))
+   `(gnus-cite-6 ((,class (:foreground "#4999ff" :background "#2d2832"))))
+   `(gnus-cite-7 ((,class (:foreground "#b3af59" :background "#2d2832"))))
+   `(gnus-cite-8 ((,class (:foreground "#9dffa1" :background "#2d2832"))))
+   `(gnus-cite-9 ((,class (:foreground "#ff8890" :background "#2d2832"))))
+   `(gnus-cite-10 ((,class (:foreground "#6bffff" :background "#2d2832"))))
+   `(gnus-emphasis-bold ((,class (:weight bold))))
+   `(gnus-emphasis-highlight-words ((,class (:foreground "#0601ff" :background 
"#ffffff"))))
+   `(gnus-group-mail-1 ((,class (:weight bold :foreground "#06af59"))))
+   `(gnus-group-mail-1-empty ((,class (:foreground "#b3af59"))))
+   `(gnus-group-mail-2 ((,class (:weight bold :foreground "#06ffa1"))))
+   `(gnus-group-mail-2-empty ((,class (:foreground "#9dffa1"))))
+   `(gnus-group-mail-3 ((,class ,mail-unread)))
+   `(gnus-group-mail-3-empty ((,class ,mail-read)))
+   `(gnus-group-mail-low ((,class ,cancel)))
+   `(gnus-group-mail-low-empty ((,class ,cancel)))
+   `(gnus-group-news-1 ((,class (:weight bold :foreground "#06af59"))))
+   `(gnus-group-news-1-empty ((,class (:foreground "#b3af59"))))
+   `(gnus-group-news-2 ((,class (:weight bold :foreground "#06ffa1"))))
+   `(gnus-group-news-2-empty ((,class (:foreground "#9dffa1"))))
+   `(gnus-group-news-3 ((,class ,mail-unread)))
+   `(gnus-group-news-3-empty ((,class ,mail-read)))
+   `(gnus-group-news-4 ((,class (:weight bold :foreground "#06ffff"))))
+   `(gnus-group-news-4-empty ((,class (:foreground "#6bffff"))))
+   `(gnus-group-news-5 ((,class (:weight bold :foreground "#06ff6f"))))
+   `(gnus-group-news-5-empty ((,class (:foreground "#ffff6f"))))
+   `(gnus-group-news-6 ((,class (:weight bold :foreground "#848088"))))
+   `(gnus-group-news-6-empty ((,class (:foreground "#837f87"))))
+   `(gnus-header-content ((,class ,mail-header-other)))
+   `(gnus-header-from ((,class (:family "Sans Serif" :foreground "#ffffff"))))
+   `(gnus-header-name ((,class ,mail-header-name)))
+   `(gnus-header-newsgroups ((,class (:family "Sans Serif" :foreground 
"#cf663d"))))
+   `(gnus-header-subject ((,class ,subject)))
+   `(gnus-picon ((,class (:foreground "#0601ff" :background "#25202a"))))
+   `(gnus-picon-xbm ((,class (:foreground "#0601ff" :background "#25202a"))))
+   `(gnus-server-closed ((,class (:slant italic :foreground "#ffff0b" 
:background "#25202a"))))
+   `(gnus-server-denied ((,class (:weight bold :foreground "#06ffff" 
:background "#25202a"))))
+   `(gnus-server-opened ((,class (:family "Sans Serif" :foreground "#25202a" 
:foreground "#bd9432"))))
+   `(gnus-signature ((,class (:slant italic :foreground "#787279"))))
+   `(gnus-splash ((,class (:foreground "#0673ff"))))
+   `(gnus-summary-cancelled ((,class ,cancel)))
+   `(gnus-summary-high-ancient ((,class ,mail-unread-high)))
+   `(gnus-summary-high-read ((,class ,mail-read-high)))
+   `(gnus-summary-high-ticked ((,class ,mail-ticked)))
+   `(gnus-summary-high-unread ((,class ,mail-unread-high)))
+   `(gnus-summary-low-ancient ((,class (:slant italic :foreground "#ffffff"))))
+   `(gnus-summary-low-read ((,class (:slant italic :foreground "#6b666f" 
:background "#413c46"))))
+   `(gnus-summary-low-ticked ((,class ,mail-ticked)))
+   `(gnus-summary-low-unread ((,class (:slant italic :foreground "#ffffff"))))
+   `(gnus-summary-normal-ancient ((,class ,mail-read)))
+   `(gnus-summary-normal-read ((,class ,mail-read)))
+   `(gnus-summary-normal-ticked ((,class ,mail-ticked)))
+   `(gnus-summary-normal-unread ((,class ,mail-unread)))
+   `(gnus-summary-selected ((,class (:foreground "#25202a" :background 
"#ff7332"))))
+   `(gnus-x-face ((,class (:foreground "#ffffff" :background "#25202a"))))
+
+   ;; Message faces.
+   `(message-header-name ((,class ,mail-header-name)))
+   `(message-header-cc ((,class ,mail-to)))
+   `(message-header-other ((,class ,mail-header-other)))
+   `(message-header-subject ((,class ,subject)))
+   `(message-header-to ((,class ,mail-to)))
+   `(message-cited-text ((,class (:foreground "#b3af59" :background 
"#2d2832"))))
+   `(message-separator ((,class (:family "Sans Serif" :weight normal 
:foreground "#473d43"))))
+   `(message-header-newsgroups ((,class (:family "Sans Serif" :foreground 
"#cf663d"))))
+   `(message-header-xheader ((,class ,mail-header-other)))
+   `(message-mml ((,class (:foreground "#e074e3"))))
+
+   ;; Diff.
+   `(diff-added ((,class ,diff-added)))
+   `(diff-changed ((,class ,diff-changed)))
+   `(diff-context ((,class ,diff-none)))
+   `(diff-file-header ((,class ,diff-header)))
+   `(diff-file1-hunk-header ((,class (:foreground "#78ff7c" :background 
"#382c33"))))
+   `(diff-file2-hunk-header ((,class (:foreground "#d781db" :background 
"#382c33"))))
+   `(diff-function ((,class (:foreground "#38663d"))))
+   `(diff-header ((,class ,diff-header)))
+   `(diff-hunk-header ((,class ,diff-hunk-header)))
+   `(diff-index ((,class ,diff-header)))
+   `(diff-indicator-added ((,class (:foreground "#c966cc" :background 
"#53204e"))))
+   `(diff-indicator-changed ((,class (:background "#46302a"))))
+   `(diff-indicator-removed ((,class (:foreground "#38ccd2" :background 
"#254046"))))
+   `(diff-refine-added ((,class ,diff-refine-added)))
+   `(diff-refine-change ((,class (:background "#443f2a"))))
+   `(diff-refine-removed ((,class ,diff-refine-removed)))
+   `(diff-removed ((,class ,diff-removed)))
+
+   ;; SMerge.
+   `(smerge-mine ((,class ,diff-changed)))
+   `(smerge-other ((,class ,diff-added)))
+   `(smerge-base ((,class ,diff-removed)))
+   `(smerge-markers ((,class (:background "#253859"))))
+   `(smerge-refined-change ((,class (:background "#5a550b"))))
+
+   ;; Ediff.
+   `(ediff-current-diff-A ((,class (:background "#253f49"))))
+   `(ediff-current-diff-B ((,class (:background "#442049"))))
+   `(ediff-current-diff-C ((,class (:background "#ff010b"))))
+   `(ediff-even-diff-A ((,class (:background "#312c36"))))
+   `(ediff-even-diff-B ((,class (:background "#312c36"))))
+   `(ediff-fine-diff-A ((,class (:background "#06555f"))))
+   `(ediff-fine-diff-B ((,class (:background "#ae01b2"))))
+   `(ediff-odd-diff-A ((,class (:background "#312c36"))))
+   `(ediff-odd-diff-B ((,class (:background "#312c36"))))
+
+   ;; Flyspell.
+   (if (version< emacs-version "24.4")
+       `(flyspell-duplicate ((,class (:underline "#101487" :inherit nil))))
+     `(flyspell-duplicate ((,class (:underline (:style wave :color "#101487") 
:background "#292759" :inherit nil)))))
+   (if (version< emacs-version "24.4")
+       `(flyspell-incorrect ((,class (:underline "#0a5864" :inherit nil))))
+     `(flyspell-incorrect ((,class (:underline (:style wave :color "#0a5864") 
:background "#2f454c":inherit nil)))))
+
+   ;; ;; Semantic faces.
+   ;; `(semantic-decoration-on-includes ((,class (:underline ,cham-4))))
+   ;; `(semantic-decoration-on-private-members-face ((,class (:background 
,alum-2))))
+   ;; `(semantic-decoration-on-protected-members-face ((,class (:background 
,alum-2))))
+   `(semantic-decoration-on-unknown-includes ((,class (:background 
"#252630"))))
+   ;; `(semantic-decoration-on-unparsed-includes ((,class (:underline 
,orange-3))))
+   `(semantic-highlight-func-current-tag-face ((,class 
,highlight-current-tag)))
+   `(semantic-tag-boundary-face ((,class (:overline "#8c8890")))) ; Method 
separator.
+   ;; `(semantic-unmatched-syntax-face ((,class (:underline ,red-1))))
+
+   `(Info-title-1-face ((,class ,ol1)))
+   `(Info-title-2-face ((,class ,ol2)))
+   `(Info-title-3-face ((,class ,ol3)))
+   `(Info-title-4-face ((,class ,ol4)))
+   `(ace-jump-face-foreground ((,class (:weight bold :foreground "#ffffff" 
:background "#065aff"))))
+   `(ahs-face ((,class (:background "#3e392a"))))
+   `(ahs-definition-face ((,class (:background "#064943"))))
+   `(ahs-plugin-defalt-face ((,class (:background "#25392a")))) ; Current.
+   `(anzu-match-1 ((,class (:foreground "#ffffff" :background "#840135"))))
+   `(anzu-match-2 ((,class (:foreground "#ffffff" :background "springgreen"))))
+   `(anzu-match-3 ((,class (:foreground "#ffffff" :background "#06ffff"))))
+   `(anzu-mode-line ((,class (:foreground "#ffffff" :background "#830187"))))
+   `(anzu-mode-line-no-match ((,class (:foreground "#ffffff" :background 
"#067f87"))))
+   `(anzu-replace-highlight ((,class (:inherit query-replace))))
+   `(anzu-replace-to ((,class (:weight bold :foreground "#47cc0c" :background 
"#0742d2"))))
+   `(auto-dim-other-buffers-face ((,class (:background "#2c2731"))))
+   `(avy-background-face ((,class (:background "#5b5660"))))
+   `(avy-lead-face ((,class (:weight bold :foreground "#ffffff" :background 
"#065aff"))))
+   `(bbdb-company ((,class (:slant italic :foreground "#bd7d55"))))
+   `(bbdb-field-name ((,class (:weight bold :foreground "#bd7d55"))))
+   `(bbdb-field-value ((,class (:foreground "#bd7d55"))))
+   `(bbdb-name ((,class (:underline t :foreground "#0699d2"))))
+   `(bmkp-light-autonamed ((,class (:background "#322d37"))))
+   `(bmkp-light-fringe-autonamed ((,class (:foreground "#a9a5ad" :background 
"#302b35"))))
+   `(bmkp-light-fringe-non-autonamed ((,class (:foreground "#252059" 
:background "#fe010e")))) ; default
+   `(bmkp-light-non-autonamed ((,class (:background "#60202a"))))
+   `(bmkp-no-local ((,class (:background "#063f3e"))))
+   `(browse-kill-ring-separator-face ((,class (:foreground "#06ffff"))))
+   `(calendar-month-header ((,class (:weight bold :foreground "#b4b5ca" 
:background "#252059"))))
+   `(calendar-today ((,class (:weight bold :foreground "#b4b5ca" :background 
"#252059"))))
+   `(calendar-weekday-header ((,class (:weight bold :foreground "#ec9d5a"))))
+   `(calendar-weekend-header ((,class (:weight bold :foreground "#b5b1b9"))))
+   `(cfw:face-annotation ((,class (:foreground "#ff01ff" :background 
"#06ffff"))))
+   `(cfw:face-day-title ((,class (:foreground "#3b3640"))))
+   `(cfw:face-default-content ((,class (:foreground "#d9ad66"))))
+   `(cfw:face-default-day ((,class (:weight bold))))
+   `(cfw:face-disable ((,class (:foreground "#5b5660"))))
+   `(cfw:face-grid ((,class (:foreground "#27222c"))))
+   `(cfw:face-header ((,class (:foreground "#ec9d5a" :background "#25202a" 
:weight bold))))
+   `(cfw:face-holiday ((,class (:foreground "#8c8890" :background "#3e322a"))))
+   `(cfw:face-periods ((,class (:foreground "#25202a" :background "#9d7330" 
:slant italic))))
+   `(cfw:face-saturday ((,class (:foreground "#b5b1b9" :background "#25202a" 
:weight bold))))
+   `(cfw:face-select ((,class (:foreground "#b96a1e" :background "#352d2e"))))
+   `(cfw:face-sunday ((,class (:foreground "#b5b1b9" :background "#25202a" 
:weight bold))))
+   `(cfw:face-title ((,class (:height 2.0 :foreground "#9c98a0" :weight bold 
:inherit variable-pitch))))
+   `(cfw:face-today ((,class (:foreground "#b4b5ca" :background "#252059"))))
+   `(cfw:face-today-title ((,class (:foreground "#25202a" :background 
"#eb9958"))))
+   `(cfw:face-toolbar ((,class (:background "#25202a"))))
+   `(cfw:face-toolbar-button-off ((,class (:foreground "#35303a" :background 
"#25202a"))))
+   `(cfw:face-toolbar-button-on ((,class (:foreground "#a5a1a9" :background 
"#2d2832"))))
+   `(change-log-date ((,class (:foreground "#64df19"))))
+   `(change-log-file ((,class (:weight bold :foreground "#c27c45"))))
+   `(change-log-list ((,class (:foreground "#ffffff" :background "#8e1142"))))
+   `(change-log-name ((,class (:foreground "#ff7fff"))))
+   `(circe-highlight-all-nicks-face ((,class (:foreground "#ffff0b" 
:background "#322d37")))) ; other nick names
+   `(circe-highlight-nick-face ((,class (:foreground "#ff6cff" :background 
"#322d37")))) ; messages with my nick cited
+   `(circe-my-message-face ((,class (:foreground "#78747c" :background 
"#322d37"))))
+   `(circe-originator-face ((,class (:foreground "#ffff0b"))))
+   `(circe-prompt-face ((,class (:foreground "#06ffff"))))
+   `(circe-server-face ((,class (:foreground "#6b3524"))))
+   `(comint-highlight-input ((,class (:weight bold :foreground "#ffff0b" 
:inherit nil))))
+   ;; `(comint-highlight-prompt ((,class (:weight bold :foreground "#ffffff" 
:background "#0628ff"))))
+   `(comint-highlight-prompt ((,class (:weight bold :foreground "#ffff0b" 
:inherit nil))))
+
+   ;; `(ac-selection-face ((,class ,completion-selected-candidate)))
+   `(ac-selection-face ((,class (:weight bold :foreground "#25202a" 
:background "#065aff")))) ; TEMP For diff'ing AC from Comp.
+   `(ac-candidate-face ((,class ,completion-other-candidates)))
+   `(ac-completion-face ((,class ,completion-inline)))
+   `(ac-candidate-mouse-face ((,class (:inherit highlight))))
+   `(popup-scroll-bar-background-face ((,class (:background "#372a2a"))))
+   `(popup-scroll-bar-foreground-face ((,class (:background "#332525")))) ; 
Scrollbar (visible).
+
+   ;; Company.
+   `(company-tooltip-common-selection ((,class (:weight normal :foreground 
"#2a3159" :inherit company-tooltip-selection)))) ; Prefix + common part in 
tooltip (for selection).
+   `(company-tooltip-selection ((,class ,completion-selected-candidate))) ; 
Suffix in tooltip (for selection).
+   `(company-tooltip-annotation-selection ((,class (:weight normal :foreground 
"#2a3159")))) ; Annotation (for selection).
+
+   `(company-tooltip-common ((,class (:weight normal :foreground "#54ff59" 
:inherit company-tooltip)))) ; Prefix + common part in tooltip.
+   `(company-tooltip ((,class ,completion-other-candidates))) ; Suffix in 
tooltip.
+   `(company-tooltip-annotation ((,class (:weight normal :foreground 
"#deea0b")))) ; Annotation.
+   `(company-preview ((,class ,completion-inline)))
+   `(company-preview-common ((,class ,completion-inline)))
+   `(company-scrollbar-bg ((,class (:background "#372a2a"))))
+   `(company-scrollbar-fg ((,class (:background "#332525")))) ; Scrollbar 
(visible).
+
+   `(compare-windows ((,class (:background "#0601ff"))))
+   ;; `(completions-common-part ((,class (:foreground "#06ffff" :weight 
bold))))
+   ;; `(completions-first-difference ((,class (:foreground "#ff01ff" :weight 
bold))))
+   `(compilation-error ((,class (:weight bold :foreground "#06ffff")))) ; Used 
for grep error messages.
+   `(compilation-info ((,class ,grep-file-name)))
+   `(compilation-line-number ((,class ,grep-line-number)))
+   `(compilation-warning ((,class (:weight bold :foreground "#065aff"))))
+   `(compilation-mode-line-exit ((,class (:weight bold :foreground 
"#ff01ff")))) ; :exit[matched]
+   `(compilation-mode-line-fail ((,class (:weight bold :foreground 
"#167d1b")))) ; :exit[no match]
+   `(compilation-mode-line-run ((,class (:weight bold :foreground 
"#065aff")))) ; :run
+   `(css-property ((,class (:foreground "#ff55ff"))))
+   `(css-selector ((,class (:weight bold :foreground "#ffff0b"))))
+   `(custom-button ((,class (:box (:line-width 2 :style released-button) 
:foreground "#ffffff" :background "lightgrey"))))
+   `(custom-button-mouse ((,class (:box (:line-width 2 :style released-button) 
:foreground "#ffffff" :background "#3d3842"))))
+   `(custom-button-pressed ((,class (:box (:line-width 2 :style 
pressed-button) :foreground "#ffffff" :background "#312c36"))))
+   `(custom-button-pressed-unraised ((,class (:underline t :foreground 
"#78ff7c"))))
+   `(custom-button-unraised ((,class (:underline t))))
+   `(custom-changed ((,class (:foreground "#25202a" :background "#ffff0b"))))
+   `(custom-comment ((,class (:background "#2b2630"))))
+   `(custom-comment-tag ((,class (:foreground "#ffff7c"))))
+   `(custom-documentation ((,class (nil))))
+   `(custom-face-tag ((,class (:family "Sans Serif" :height 1.2 :weight 
bold))))
+   `(custom-group-tag ((,class (:height 1.2 :weight bold :foreground 
"#ffff0b"))))
+   `(custom-group-tag-1 ((,class (:family "Sans Serif" :height 1.2 :weight 
bold :foreground "#06ffff"))))
+   `(custom-invalid ((,class (:foreground "#0601ff" :background "#06ffff"))))
+   `(custom-link ((,class (:underline t :foreground "#ffff0b"))))
+   `(custom-modified ((,class (:foreground "#25202a" :background "#ffff0b"))))
+   `(custom-rogue ((,class (:foreground "#063f3e" :background "#ffffff"))))
+   `(custom-saved ((,class (:underline t))))
+   `(custom-set ((,class (:foreground "#ffff0b" :background "#25202a"))))
+   `(custom-state ((,class (:foreground "#ff74ff"))))
+   `(custom-themed ((,class (:foreground "#25202a" :background "#ffff0b"))))
+   `(custom-variable-button ((,class (:weight bold :underline t))))
+   `(custom-variable-tag ((,class (:family "Sans Serif" :height 1.2 :weight 
bold :foreground "#ffff0b"))))
+   `(custom-visibility ((,class ,link)))
+   `(diff-hl-change ((,class (:foreground "#ffff3c" :background "#46302a"))))
+   `(diff-hl-delete ((,class (:foreground "#37ffff" :background "#254046"))))
+   `(diff-hl-dired-change ((,class (:weight bold :foreground "#ffffff" 
:background "#065cd0"))))
+   `(diff-hl-dired-delete ((,class (:weight bold :foreground "#2dc6ef"))))
+   `(diff-hl-dired-ignored ((,class (:weight bold :foreground "#25202a" 
:background "#44445e"))))
+   `(diff-hl-dired-insert ((,class (:weight bold :foreground "#4b464f"))))
+   `(diff-hl-dired-unknown ((,class (:foreground "#25202a" :background 
"#c4c455"))))
+   `(diff-hl-insert ((,class (:foreground "#ff74ff" :background "#53204e"))))
+   `(diff-hl-unknown ((,class (:foreground "#25202a" :background "#c4c455"))))
+   `(diary-face ((,class (:foreground "#7c360d"))))
+   `(dircolors-face-asm ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-backup ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-compress ((,class (:foreground "#06ffff"))))
+   `(dircolors-face-dir ((,class ,directory)))
+   `(dircolors-face-doc ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-dos ((,class (:foreground "#e074e3"))))
+   `(dircolors-face-emacs ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-exec ((,class (:foreground "#e074e3"))))
+   `(dircolors-face-html ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-img ((,class (:foreground "#37ff3c"))))
+   `(dircolors-face-lang ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-lang-interface ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-make ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-objet ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-package ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-paddb ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-ps ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-sound ((,class (:foreground "#ff400b"))))
+   `(dircolors-face-tar ((,class (:foreground "#06ffff"))))
+   `(dircolors-face-text ((,class (:foreground "#ffffff"))))
+   `(dircolors-face-yacc ((,class (:foreground "#ffffff"))))
+   `(dired-directory ((,class ,directory)))
+   `(dired-header ((,class ,directory)))
+   `(dired-ignored ((,class (:strike-through t :foreground "#06ffff"))))
+   `(dired-mark ((,class ,marked-line)))
+   `(dired-marked ((,class ,marked-line)))
+   `(dired-symlink ((,class ,symlink)))
+   `(diredfl-compressed-file-suffix ((,class (:foreground "#ffffff" 
:background "#2526c0"))))
+   `(diredp-compressed-file-suffix ((,class (:foreground "#06ffff"))))
+   `(diredp-date-time ((,class (:foreground "#64df19"))))
+   `(diredp-dir-heading ((,class ,directory)))
+   `(diredp-dir-name ((,class ,directory)))
+   `(diredp-dir-priv ((,class ,directory)))
+   `(diredp-exec-priv ((,class (:background "#fd3fcb"))))
+   `(diredp-executable-tag ((,class (:foreground "#e074e3" :background 
"#25202a"))))
+   `(diredp-file-name ((,class ,file)))
+   `(diredp-file-suffix ((,class (:foreground "#443f49"))))
+   `(diredp-flag-mark-line ((,class ,marked-line)))
+   `(diredp-ignored-file-name ((,class ,shadow)))
+   `(diredp-read-priv ((,class (:background "#f7660b"))))
+   `(diredp-write-priv ((,class (:foreground "#25202a" :background 
"#06bfc7"))))
+   `(doom-modeline-panel ((,class (:foreground "#ffffff" :background 
"#2526c0"))))
+   `(eldoc-highlight-function-argument ((,class (:weight bold :foreground 
"#06ffff" :background "#25392a"))))
+   `(elfeed-search-filter-face ((,class (:foreground "#46414b"))))
+   ;; `(eww-form-checkbox ((,class ())))
+   ;; `(eww-form-select ((,class ())))
+   ;; `(eww-form-submit ((,class ())))
+   `(eww-form-text ((,class (:weight bold :foreground "#c3a798" :background 
"#5d3218"))))
+   ;; `(eww-form-textarea ((,class ())))
+   `(file-name-shadow ((,class ,shadow)))
+   `(flycheck-error ((,class (:underline (:color "#06dae7" :style wave) 
:weight bold :background "#253c46"))))
+   `(flycheck-error-list-line-number ((,class (:foreground "#5fca5b"))))
+   `(flycheck-fringe-error ((,class (:foreground "#06dae7"))))
+   `(flycheck-fringe-info ((,class (:foreground "#ed75ef"))))
+   `(flycheck-fringe-warning ((,class (:foreground "#1056cd"))))
+   `(flycheck-info ((,class (:underline (:color "#ed75ef" :style wave) :weight 
bold))))
+   `(flycheck-warning ((,class (:underline (:color "#1056cd" :style wave) 
:weight bold :background "#252066"))))
+   `(font-latex-bold-face ((,class (:weight bold :foreground "#ffffff"))))
+   `(fancy-narrow-blocked-face ((,class (:foreground "#6b6765"))))
+   `(flycheck-color-mode-line-error-face ((, class (:background "#35a4b1"))))
+   `(flycheck-color-mode-line-warning-face ((, class (:background "#1938ff"))))
+   `(flycheck-color-mode-line-info-face ((, class (:background "#0601ff"))))
+   `(font-latex-italic-face ((,class (:slant italic :foreground "#e8e5eb"))))
+   `(font-latex-math-face ((,class (:foreground "#ffff0b"))))
+   `(font-latex-sectioning-1-face ((,class (:family "Sans Serif" :height 2.7 
:weight bold :foreground "#9f6a1c"))))
+   `(font-latex-sectioning-2-face ((,class ,ol1)))
+   `(font-latex-sectioning-3-face ((,class ,ol2)))
+   `(font-latex-sectioning-4-face ((,class ,ol3)))
+   `(font-latex-sectioning-5-face ((,class ,ol4)))
+   `(font-latex-sedate-face ((,class (:foreground "#06aaff"))))
+   `(font-latex-string-face ((,class (:weight bold :foreground "#ff990b"))))
+   `(font-latex-verbatim-face ((,class (:foreground "#ffff7f" :background 
"#252046" :inherit nil))))
+   `(git-commit-summary-face ((,class (:foreground "#ffffff"))))
+   `(git-commit-comment-face ((,class (:slant italic :foreground "#9a969e"))))
+   `(git-timemachine-commit ((,class ,diff-removed)))
+   `(git-timemachine-minibuffer-author-face ((,class ,diff-added)))
+   `(git-timemachine-minibuffer-detail-face ((,class ,diff-header)))
+   `(google-translate-text-face ((,class (:foreground "#8c8890" :background 
"#2e2933"))))
+   `(google-translate-phonetic-face ((,class (:inherit shadow))))
+   `(google-translate-translation-face ((,class (:weight normal :foreground 
"#d2861c" :background "#3f3336"))))
+   `(google-translate-suggestion-label-face ((,class (:foreground "#06ffff"))))
+   `(google-translate-suggestion-face ((,class (:slant italic :underline t))))
+   `(google-translate-listen-button-face ((,class (:height 0.8))))
+   `(helm-action ((,class (:foreground "#ffffff"))))
+   `(helm-bookmark-file ((,class ,file)))
+   `(helm-bookmarks-su-face ((,class (:foreground "#06ffff"))))
+   `(helm-buffer-directory ((,class ,directory)))
+   ;; `(helm-non-file-buffer ((,class (:slant italic :foreground "#ffff0b"))))
+   ;; `(helm-buffer-file ((,class (:foreground "#cfccd2"))))
+   `(helm-buffer-modified ((,class (:slant italic :foreground "#4ac964"))))
+   `(helm-buffer-process ((,class (:foreground "#ff7dff"))))
+   `(helm-candidate-number ((,class (:foreground "#ffffff" :background 
"#0601a1"))))
+   `(helm-dir-heading ((,class (:foreground "#ffff0b" :background "#063f3e"))))
+   `(helm-dir-priv ((,class (:foreground "#78ffff" :background "#312c36"))))
+   `(helm-ff-directory ((,class ,directory)))
+   `(helm-ff-dotted-directory ((,class ,directory)))
+   `(helm-ff-executable ((,class (:foreground "#ff32ff" :background 
"#25202a"))))
+   `(helm-ff-file ((,class (:foreground "#ffffff"))))
+   `(helm-ff-invalid-symlink ((,class (:foreground "#0601ff" :background 
"#06ffff"))))
+   `(helm-ff-symlink ((,class ,symlink)))
+   `(helm-file-name ((,class (:foreground "#ffff0b"))))
+   `(helm-gentoo-match-face ((,class (:foreground "#06ffff"))))
+   `(helm-grep-file ((,class ,grep-file-name)))
+   `(helm-grep-lineno ((,class ,grep-line-number)))
+   `(helm-grep-match ((,class ,match)))
+   `(helm-grep-running ((,class (:weight bold :foreground "#25202a"))))
+   `(helm-isearch-match ((,class (:background "#38013d"))))
+   `(helm-lisp-show-completion ((,class ,volatile-highlight-supersize))) ; See 
`helm-dabbrev'.
+   ;; `(helm-ls-git-added-copied-face ((,class (:foreground ""))))
+   ;; `(helm-ls-git-added-modified-face ((,class (:foreground ""))))
+   ;; `(helm-ls-git-conflict-face ((,class (:foreground ""))))
+   ;; `(helm-ls-git-deleted-and-staged-face ((,class (:foreground ""))))
+   ;; `(helm-ls-git-deleted-not-staged-face ((,class (:foreground ""))))
+   ;; `(helm-ls-git-modified-and-staged-face ((,class (:foreground ""))))
+   `(helm-ls-git-modified-not-staged-face ((,class (:foreground "#4ac964"))))
+   ;; `(helm-ls-git-renamed-modified-face ((,class (:foreground ""))))
+   ;; `(helm-ls-git-untracked-face ((,class (:foreground ""))))
+   `(helm-match ((,class ,match)))
+   `(helm-moccur-buffer ((,class (:foreground "#ff993d"))))
+   `(helm-selection ((,class (:background "#cb8a33" :foreground "#25202a"))))
+   `(helm-selection-line ((,class ,highlight-gray))) ; ???
+   `(helm-separator ((,class (:foreground "#06ffff"))))
+   `(helm-source-header ((,class (:weight bold :box (:line-width 1 :color 
"#3d3842") :background "#433e48" :foreground "#ffffff"))))
+   `(helm-swoop-target-line-block-face ((,class (:background "#3833ff" 
:foreground "#e0dde3"))))
+   `(helm-swoop-target-line-face ((,class (:background "#38330b"))))
+   `(helm-swoop-target-word-face ((,class (:weight bold :foreground nil 
:background "#0742d2"))))
+   `(helm-visible-mark ((,class ,marked-line)))
+   `(helm-w3m-bookmarks-face ((,class (:underline t :foreground "#ff010b"))))
+   `(highlight-changes ((,class (:foreground nil)))) ;; blue "#d4f754"
+   `(highlight-changes-delete ((,class (:strike-through nil :foreground 
nil)))) ;; red "#4ff7d7"
+   `(highlight-symbol-face ((,class (:background "#252080"))))
+   `(hl-line ((,class ,highlight-yellow))) ; Highlight current line.
+   `(hl-tags-face ((,class ,highlight-current-tag))) ; ~ Pair highlighting 
(matching tags).
+   `(holiday-face ((,class (:foreground "#8c8890" :background "#3e322a"))))
+   `(html-helper-bold-face ((,class (:weight bold :foreground "#ffffff"))))
+   `(html-helper-italic-face ((,class (:slant italic :foreground "#ffffff"))))
+   `(html-helper-underline-face ((,class (:underline t :foreground 
"#ffffff"))))
+   `(html-tag-face ((,class (:foreground "#ffff0b"))))
+   `(ilog-non-change-face ((,class (:height 2.0 :foreground "#9fcb66"))))
+   `(ilog-change-face ((,class (:height 2.0 :foreground "#ff7dff"))))
+   `(ilog-echo-face ((,class (:height 2.0 :foreground "#ff9029"))))
+   `(ilog-load-face ((,class (:foreground "#4ac964"))))
+   `(ilog-message-face ((,class (:foreground "#837f87"))))
+   `(indent-guide-face ((,class (:foreground "#312c36"))))
+   `(info-file ((,class (:family "Sans Serif" :height 1.8 :weight bold :box 
(:line-width 1 :color "#ffff3d") :foreground "#9f6a1c" :background "#563c2a"))))
+   `(info-header-node ((,class (:underline t :foreground "#065aff")))) ; nodes 
in header
+   `(info-header-xref ((,class (:underline t :foreground "#e46f0b")))) ; cross 
references in header
+   `(info-index-match ((,class (:weight bold :foreground nil :background 
"#0742d2")))) ; when using `i'
+   `(info-menu-header ((,class ,ol2))) ; menu titles (headers) -- major topics
+   `(info-menu-star ((,class (:foreground "#ffffff")))) ; every 3rd menu item
+   `(info-node ((,class (:underline t :foreground "#ffff0b")))) ; node names
+   `(info-quoted-name ((,class ,code-inline)))
+   `(info-string ((,class ,string)))
+   `(info-title-1 ((,class ,ol1)))
+   `(info-xref ((,class (:underline t :foreground "#ff925a")))) ; unvisited 
cross-references
+   `(info-xref-visited ((,class (:underline t :foreground "#78ff7c")))) ; 
previously visited cross-references
+   ;; js2-highlight-vars-face (~ auto-highlight-symbol)
+   `(js2-error ((,class (:box (:line-width 1 :color "#06c8cf") :background 
"#063741")))) ; DONE.
+   `(js2-external-variable ((,class (:foreground "#06ffff" :background 
"#252630")))) ; DONE.
+   `(js2-function-param ((,class ,function-param)))
+   `(js2-instance-member ((,class (:foreground "#6bcd3d"))))
+   `(js2-jsdoc-html-tag-delimiter ((,class (:foreground "#34c8d8"))))
+   `(js2-jsdoc-html-tag-name ((,class (:foreground "#34c8d8"))))
+   `(js2-jsdoc-tag ((,class (:weight normal :foreground "#9fcb66"))))
+   `(js2-jsdoc-type ((,class (:foreground "#bd7d55"))))
+   `(js2-jsdoc-value ((,class (:weight normal :foreground "#4ac964")))) ; 
#83ff87
+   `(js2-magic-paren ((,class (:underline t))))
+   `(js2-private-function-call ((,class (:foreground "#2a5ae5"))))
+   `(js2-private-member ((,class (:foreground "#375073"))))
+   `(js2-warning ((,class (:underline "#065aff"))))
+
+   ;; Org non-standard faces.
+   `(leuven-dark-org-deadline-overdue ((,class (:foreground "#12d9ae"))))
+   `(leuven-dark-org-deadline-today ((,class (:weight bold :foreground 
"#b4b5ca" :background "#252059"))))
+   `(leuven-dark-org-deadline-tomorrow ((,class (:foreground "#c357f8"))))
+   `(leuven-dark-org-deadline-future ((,class (:foreground "#c357f8"))))
+   `(leuven-dark-gnus-unseen ((,class (:weight bold :foreground "#088dfd"))))
+   `(leuven-dark-gnus-date ((,class (:foreground "#067f4a"))))
+   `(leuven-dark-gnus-size ((,class (:foreground "#7440a7"))))
+   `(leuven-dark-todo-items-face ((,class (:weight bold :foreground "#06cee0" 
:background "#06017f"))))
+
+   `(light-symbol-face ((,class (:background "#252080"))))
+   `(linum ((,class (:foreground "#6a656f" :background "#35303a"))))
+   `(log-view-file ((,class (:foreground "#ffff3d" :background "#382c33"))))
+   `(log-view-message ((,class (:foreground "#ffffff" :background "#171593"))))
+   `(lsp-modeline-code-actions-preferred-face ((,class (:foreground "#ffffff" 
:background "#2526c0"))))
+   `(lsp-ui-doc-background ((,class (:background "#2d2058"))))
+   `(lsp-ui-sideline-code-action ((,class (:foreground "#ffffff" :background 
"#2526c0"))))
+   `(lui-button-face ((,class ,link)))
+   `(lui-highlight-face ((,class (:box '(:line-width 1 :color "#38ffff") 
:foreground "#38ffff" :background "#06017f")))) ; my nickname
+   `(lui-time-stamp-face ((,class (:foreground "#64df19"))))
+   `(magit-blame-header ((,class (:inherit magit-diff-file-header))))
+   `(magit-blame-heading ((,class (:overline "#5d5862" :foreground "#06ffff" 
:background "#3c3741"))))
+   `(magit-blame-hash ((,class (:overline "#5d5862" :foreground "#06ffff" 
:background "#3c3741"))))
+   `(magit-blame-name ((,class (:overline "#5d5862" :foreground "#fd95fa" 
:background "#3c3741"))))
+   `(magit-blame-date ((,class (:overline "#5d5862" :foreground "#ffff0b" 
:background "#3c3741"))))
+   `(magit-blame-summary ((,class (:overline "#5d5862" :weight bold 
:foreground "#938f97" :background "#3c3741"))))
+   `(magit-branch ((,class ,vc-branch)))
+   `(magit-diff-add ((,class ,diff-added)))
+   `(magit-diff-del ((,class ,diff-removed)))
+   `(magit-diff-file-header ((,class (:height 1.1 :weight bold :foreground 
"#c27c45"))))
+   `(magit-diff-hunk-header ((,class ,diff-hunk-header)))
+   `(magit-diff-none ((,class ,diff-none)))
+   `(magit-header ((,class (:foreground "#25202a" :background "#06bfc7"))))
+   `(magit-item-highlight ((,class (:background "#382c33"))))
+   `(magit-item-mark ((,class ,marked-line)))
+   `(magit-log-head-label ((,class (:box (:line-width 1 :color "#ffff0b" 
:style nil)))))
+   `(magit-log-tag-label ((,class (:box (:line-width 1 :color "#ff33ff" :style 
nil)))))
+   `(magit-section-highlight ((,class (:background  "#2d2058"))))
+   `(magit-section-title ((,class (:family "Sans Serif" :height 1.8 :weight 
bold :foreground "#9f6a1c" :inherit nil))))
+   `(makefile-space-face ((,class (:background "#069655"))))
+   `(makefile-targets ((,class (:weight bold :foreground "#ffff0b"))))
+   ;; `(markdown-blockquote-face ((,class ())))
+   `(markdown-bold-face ((,class (:inherit bold))))
+   ;; `(markdown-comment-face ((,class ())))
+   ;; `(markdown-footnote-face ((,class ())))
+   ;; `(markdown-header-delimiter-face ((,class ())))
+   ;; `(markdown-header-face ((,class ())))
+   `(markdown-header-face-1 ((,class ,ol1)))
+   `(markdown-header-face-2 ((,class ,ol2)))
+   `(markdown-header-face-3 ((,class ,ol3)))
+   `(markdown-header-face-4 ((,class ,ol4)))
+   `(markdown-header-face-5 ((,class ,ol5)))
+   `(markdown-header-face-6 ((,class ,ol6)))
+   ;; `(markdown-header-rule-face ((,class ())))
+   `(markdown-inline-code-face ((,class ,code-inline)))
+   `(markdown-italic-face ((,class (:inherit italic))))
+   `(markdown-language-keyword-face ((,class (:inherit org-block-begin-line))))
+   ;; `(markdown-line-break-face ((,class ())))
+   `(markdown-link-face ((,class ,link-no-underline)))
+   ;; `(markdown-link-title-face ((,class ())))
+   ;; `(markdown-list-face ((,class ())))
+   ;; `(markdown-math-face ((,class ())))
+   ;; `(markdown-metadata-key-face ((,class ())))
+   ;; `(markdown-metadata-value-face ((,class ())))
+   ;; `(markdown-missing-link-face ((,class ())))
+   `(markdown-pre-face ((,class (:inherit org-block-background))))
+   ;; `(markdown-reference-face ((,class ())))
+   ;; `(markdown-strike-through-face ((,class ())))
+   `(markdown-url-face ((,class ,link)))
+   `(match ((,class ,match)))           ; Used for grep matches.
+   `(mc/cursor-bar-face ((,class (:height 1.0 :foreground "#ec9b45" 
:background "#ec9b45"))))
+   `(mc/cursor-face ((,class (:inverse-video t))))
+   `(mc/region-face ((,class (:inherit region))))
+   `(mm-uu-extract ((,class ,code-block)))
+   `(moccur-current-line-face ((,class (:foreground "#ffffff" :background 
"#252059"))))
+   `(moccur-face ((,class (:foreground "#ffffff" :background "#06016f"))))
+   `(next-error ((,class ,volatile-highlight-supersize)))
+   `(nobreak-space ((,class (:background "#543532"))))
+   `(nxml-attribute-local-name-face ((,class ,xml-attribute)))
+   `(nxml-attribute-value-delimiter-face ((,class (:foreground "#ff74ff"))))
+   `(nxml-attribute-value-face ((,class (:foreground "#ff74ff"))))
+   `(nxml-comment-content-face ((,class (:slant italic :foreground 
"#06ffff"))))
+   `(nxml-comment-delimiter-face ((,class (:foreground "#06ffff"))))
+   `(nxml-element-local-name ((,class ,xml-tag)))
+   `(nxml-element-local-name-face ((,class (:foreground "#ffff0b"))))
+   `(nxml-processing-instruction-target-face ((,class (:foreground 
"#69cf0b"))))
+   `(nxml-tag-delimiter-face ((,class (:foreground "#ffff0b"))))
+   `(nxml-tag-slash-face ((,class (:foreground "#ffff0b"))))
+   `(org-agenda-block-count ((,class (:weight bold :foreground "#5f5a64"))))
+   `(org-agenda-calendar-event ((,class (:weight bold :foreground "#cc8b3d" 
:background "#3e322a"))))
+   `(org-agenda-calendar-sexp ((,class (:foreground "#d0853c" :background 
"#30272c"))))
+   `(org-agenda-clocking ((,class (:foreground "#ffffff" :background 
"#1636ff"))))
+   `(org-agenda-column-dateline ((,class ,column)))
+   `(org-agenda-current-time ((,class (:underline t :foreground "#ec9d5a"))))
+   `(org-agenda-date ((,class (,@(leuven-dark-scale-font 
leuven-dark-scale-org-agenda-structure 1.6) :weight bold :foreground 
"#ec9d5a"))))
+   `(org-agenda-date-today ((,class (,@(leuven-dark-scale-font 
leuven-dark-scale-org-agenda-structure 1.6) :weight bold :foreground "#b4b5ca" 
:background "#252059"))))
+   `(org-agenda-date-weekend ((,class (,@(leuven-dark-scale-font 
leuven-dark-scale-org-agenda-structure 1.6) :weight bold :foreground 
"#b5b1b9"))))
+   `(org-agenda-diary ((,class (:weight bold :foreground "#ff74ff" :background 
"#572723"))))
+   `(org-agenda-dimmed-todo-face ((,class (:foreground "#1636ff"))))
+   `(org-agenda-done ((,class (:foreground "#aeaab2"))))
+   `(org-agenda-filter-category ((,class (:weight bold :foreground 
"#065aff"))))
+   `(org-agenda-filter-effort ((,class (:weight bold :foreground "#065aff"))))
+   `(org-agenda-filter-regexp ((,class (:weight bold :foreground "#065aff"))))
+   `(org-agenda-filter-tags ((,class (:weight bold :foreground "#065aff"))))
+   `(org-agenda-restriction-lock ((,class (:background "#1d82a4"))))
+   `(org-agenda-structure ((,class (,@(leuven-dark-scale-font 
leuven-dark-scale-org-agenda-structure 1.6) :weight bold :foreground 
"#e37233"))))
+   `(org-archived ((,class (:foreground "#514c56"))))
+   `(org-beamer-tag ((,class (:box (:line-width 1 :color "#0a43ed") 
:foreground "#d6d3d9" :background "#252655"))))
+   `(org-block ((,class ,code-block)))
+   `(org-block-background ((,class (:background "#252046")))) ;; :inherit 
fixed-pitch))))
+   `(org-block-begin-line ((,class (:underline "#5d595f" :foreground "#aeaab2" 
:background "#221e34"))))
+   `(org-block-end-line ((,class (:overline "#5d595f" :foreground "#aeaab2" 
:background "#221e34"))))
+   `(org-checkbox ((,class (:weight bold :box (:line-width 1 :style 
pressed-button) :foreground "#efcab2" :background "#615c66"))))
+   `(org-clock-overlay ((,class (:foreground "#25202a" :background 
"#b98f7c"))))
+   `(org-code ((,class ,code-inline)))
+   `(org-column ((,class ,column)))
+   `(org-column-title ((,class ,column)))
+   `(org-date ((,class (:underline t :foreground "#ffba6b"))))
+   `(org-default ((,class (:foreground "#cfccd2" :background "#25202a"))))
+   `(org-dim ((,class (:foreground "#5a555f"))))
+   `(org-document-info ((,class (:foreground "#bbb7bf"))))
+   `(org-document-info-keyword ((,class (:foreground "#ff7138" :background 
"#38332a"))))
+   `(org-document-title ((,class (,@(leuven-dark-scale-font 
leuven-dark-scale-org-document-title 1.8)  :weight bold :foreground 
"#ffffff"))))
+   `(org-done ((,class (:weight bold :box (:line-width 1 :color "#49444e") 
:foreground "#49444e" :background "#322d37"))))
+   `(org-drawer ((,class (:weight bold :foreground "#ff44ff" :background 
"#38203d"))))
+   `(org-ellipsis ((,class (:underline nil :foreground "#6b666f")))) ; #0611a5
+   `(org-example ((,class (:foreground "#ffff0b" :background "#38203d"))))
+   `(org-footnote ((,class (:underline t :foreground "#ff7138"))))
+   `(org-formula ((,class (:foreground "#0680e1"))))
+   ;; org-habit colours are thanks to zenburn
+   `(org-habit-ready-face ((t :background "#7F9F7F"))) ; ,zenburn-green
+   `(org-habit-alert-face ((t :background "#E0CF9F" :foreground "#3F3F3F"))) ; 
,zenburn-yellow-1 fg ,zenburn-bg
+   `(org-habit-clear-face ((t :background "#5C888B")))                       ; 
,zenburn-blue-3
+   `(org-habit-overdue-face ((t :background "#9C6363")))                     ; 
,zenburn-red-3
+   `(org-habit-clear-future-face ((t :background "#4C7073")))                ; 
,zenburn-blue-4
+   `(org-habit-ready-future-face ((t :background "#5F7F5F")))                ; 
,zenburn-green-2
+   `(org-habit-alert-future-face ((t :background "#D0BF8F" :foreground 
"#3F3F3F"))) ; ,zenburn-yellow-2 fg ,zenburn-bg
+   `(org-habit-overdue-future-face ((t :background "#8C5353"))) ; 
,zenburn-red-4
+   `(org-headline-done ((,class (:height 1.0 :weight normal :foreground 
"#57525c"))))
+   `(org-hide ((,class (:foreground "#403b45"))))
+   `(org-inlinetask ((,class (:box (:line-width 1 :color "#37323c") 
:foreground "#8c8890" :background "#252050"))))
+   `(org-latex-and-related ((,class (:foreground "#cf996f" :background 
"#25202a"))))
+   `(org-level-1 ((,class ,ol1)))
+   `(org-level-2 ((,class ,ol2)))
+   `(org-level-3 ((,class ,ol3)))
+   `(org-level-4 ((,class ,ol4)))
+   `(org-level-5 ((,class ,ol5)))
+   `(org-level-6 ((,class ,ol6)))
+   `(org-level-7 ((,class ,ol7)))
+   `(org-level-8 ((,class ,ol8)))
+   `(org-link ((,class ,link)))
+   `(org-list-dt ((,class (:weight bold :foreground "#cfa161"))))
+   `(org-macro ((,class (:weight bold :foreground "#1747fd"))))
+   `(org-meta-line ((,class (:slant normal :foreground "#ff7138" :background 
"#38332a"))))
+   `(org-mode-line-clock ((,class (:box (:line-width 1 :color "#cfa161") 
:foreground "#ffffff" :background "#065cd0"))))
+   `(org-mode-line-clock-overrun ((,class (:weight bold :box (:line-width 1 
:color "#cfa161") :foreground "#25202a" :background "#06bfc7"))))
+   `(org-number-of-items ((,class (:weight bold :foreground "#25202a" 
:background "#8a458e"))))
+   `(org-property-value ((,class (:foreground "#ff5fff"))))
+   `(org-quote ((,class (:slant italic :foreground "#9a969e" :background 
"#252046"))))
+   `(org-scheduled ((,class (:foreground "#cfccd2"))))
+   `(org-scheduled-previously ((,class (:foreground "#ed9943"))))
+   `(org-scheduled-today ((,class (:weight bold :foreground "#b4b5ca" 
:background "#252059"))))
+   `(org-sexp-date ((,class (:foreground "#cc8b3d"))))
+   `(org-special-keyword ((,class (:weight bold :foreground "#ff44ff" 
:background "#38203d"))))
+   `(org-table ((,class (:foreground "#ff9bff" :background "#38203d")))) ;; 
:inherit fixed-pitch))))
+   `(org-tag ((,class (:weight normal :slant italic :foreground "#6a6065" 
:background "#25202a"))))
+   `(org-target ((,class (:foreground "#06925a"))))
+   `(org-time-grid ((,class (:foreground "#35303a"))))
+   `(org-todo ((,class (:weight bold :box (:line-width 1 :color "#2c5462") 
:foreground "#2c5462" :background "#253743"))))
+   `(org-upcoming-deadline ((,class (:foreground "#06aab2"))))
+   `(org-verbatim ((,class (:foreground "#ff993d" :background "#2c212a"))))
+   `(org-verse ((,class (:slant italic :foreground "#9a969e" :background 
"#342f39"))))
+   `(org-warning ((,class (:weight bold :foreground "#ffffff" :background 
"#54362a"))))
+   `(outline-1 ((,class ,ol1)))
+   `(outline-2 ((,class ,ol2)))
+   `(outline-3 ((,class ,ol3)))
+   `(outline-4 ((,class ,ol4)))
+   `(outline-5 ((,class ,ol5)))
+   `(outline-6 ((,class ,ol6)))
+   `(outline-7 ((,class ,ol7)))
+   `(outline-8 ((,class ,ol8)))
+   `(pabbrev-debug-display-label-face ((,class (:foreground "#25202a" 
:background "#5edeb3"))))
+   `(pabbrev-suggestions-face ((,class (:weight bold :foreground "#25202a" 
:background "#06ffff"))))
+   `(pabbrev-suggestions-label-face ((,class (:weight bold :foreground 
"#25202a" :background "#64df19"))))
+   `(paren-face-match ((,class ,paren-matched)))
+   `(paren-face-mismatch ((,class ,paren-unmatched)))
+   `(paren-face-no-match ((,class ,paren-unmatched)))
+   `(persp-selected-face ((,class (:weight bold :foreground "#34292a"))))
+   `(powerline-active1 ((,class (:foreground "#7e311e" :background "#cbc7ce" 
:inherit mode-line))))
+   `(powerline-active2 ((,class (:foreground "#7e311e" :background "#c38f53" 
:inherit mode-line))))
+   `(powerline-inactive1 ((,class (:foreground "#322d38" :background "#9b979f" 
:inherit mode-line-inactive))))
+   `(powerline-inactive2 ((,class (:foreground "#322d38" :background "#5b5660" 
:inherit mode-line-inactive))))
+   `(rainbow-delimiters-depth-1-face ((,class (:foreground "#938e84"))))
+   `(rainbow-delimiters-depth-2-face ((,class (:foreground "#907733"))))
+   `(rainbow-delimiters-depth-3-face ((,class (:foreground "#736e84"))))
+   `(rainbow-delimiters-depth-4-face ((,class (:foreground "#936797"))))
+   `(rainbow-delimiters-depth-5-face ((,class (:foreground "#738c94"))))
+   `(rainbow-delimiters-depth-6-face ((,class (:foreground "#a1894f"))))
+   `(rainbow-delimiters-depth-7-face ((,class (:foreground "#7e7a87"))))
+   `(rainbow-delimiters-depth-8-face ((,class (:foreground "#835787"))))
+   `(rainbow-delimiters-depth-9-face ((,class (:foreground "#7b8f97"))))
+   `(rainbow-delimiters-mismatched-face ((,class ,paren-unmatched)))
+   `(rainbow-delimiters-unmatched-face ((,class ,paren-unmatched)))
+   `(recover-this-file ((,class (:weight bold :background "#06c0c8"))))
+   `(rng-error ((,class (:weight bold :foreground "#06ffff" :background 
"#283a43"))))
+   `(sh-heredoc ((,class (:foreground "#ffff0b" :background "#34292a"))))
+   `(sh-quoted-exec ((,class (:foreground "#06eb74"))))
+   `(shadow ((,class ,shadow)))         ; Used for grep context lines.
+   `(shell-option-face ((,class (:foreground "#e074e3"))))
+   `(shell-output-2-face ((,class (:foreground "#ffff0b"))))
+   `(shell-output-3-face ((,class (:foreground "#64df19"))))
+   `(shell-output-face ((,class (:foreground "#ffffff"))))
+   ;; `(shell-prompt-face ((,class (:weight bold :foreground "#0601ff"))))
+   `(shm-current-face ((,class (:background "#343551"))))
+   `(shm-quarantine-face ((,class (:background "lemonchiffon"))))
+   `(show-paren-match ((,class ,paren-matched)))
+   `(show-paren-mismatch ((,class ,paren-unmatched)))
+   `(sml-modeline-end-face ((,class (:background "#985213")))) ; #cfa161
+   `(sml-modeline-vis-face ((,class (:background "#e9863f"))))
+   `(term ((,class (:foreground "#cfccd2" :background "#25202a"))))
+
+   ;; `(sp-pair-overlay-face ((,class ())))
+   ;; `(sp-show-pair-enclosing ((,class ())))
+   ;; `(sp-show-pair-match-face ((,class ()))) ; ~ Pair highlighting (matching 
tags).
+   ;; `(sp-show-pair-mismatch-face ((,class ())))
+   ;; `(sp-wrap-overlay-closing-pair ((,class ())))
+   ;; `(sp-wrap-overlay-face ((,class ())))
+   ;; `(sp-wrap-overlay-opening-pair ((,class ())))
+   ;; `(sp-wrap-tag-overlay-face ((,class ())))
+
+   `(speedbar-button-face ((,class (:foreground "#ff74ff"))))
+   `(speedbar-directory-face ((,class (:foreground "#ffff7c"))))
+   `(speedbar-file-face ((,class (:foreground "#ff747c"))))
+   `(speedbar-highlight-face ((,class ,volatile-highlight)))
+   `(speedbar-selected-face ((,class (:underline t :foreground "#06ffff"))))
+   `(speedbar-tag-face ((,class (:foreground "#5fd5db"))))
+   `(svn-status-directory-face ((,class ,directory)))
+   `(svn-status-filename-face ((,class (:weight bold :foreground "#c27c45"))))
+   `(svn-status-locked-face ((,class (:weight bold :foreground "#06ffff"))))
+   `(svn-status-marked-face ((,class ,marked-line)))
+   `(svn-status-marked-popup-face ((,class (:weight bold :foreground 
"#ff32ff"))))
+   `(svn-status-switched-face ((,class (:slant italic :foreground "#77737b"))))
+   `(svn-status-symlink-face ((,class ,symlink)))
+   `(svn-status-update-available-face ((,class (:foreground "#065aff"))))
+   `(tex-verbatim ((,class (:foreground "#ffff0b"))))
+   `(tool-bar ((,class (:box (:line-width 1 :style released-button) 
:foreground "#ffffff" :background "#45404a"))))
+   `(tooltip ((,class (:foreground "#ffffff" :background "#252046"))))
+   `(traverse-match-face ((,class (:weight bold :foreground "#79d427"))))
+   `(vc-annotate-face-3F3FFF ((,class (:foreground "#c4c00b" :background 
"#ffffff"))))
+   `(vc-annotate-face-3F6CFF ((,class (:foreground "#c4c00b" :background 
"#ffffff"))))
+   `(vc-annotate-face-3F99FF ((,class (:foreground "#c4660b" :background 
"#ffffff"))))
+   `(vc-annotate-face-3FC6FF ((,class (:foreground "#c4660b" :background 
"#ffffff"))))
+   `(vc-annotate-face-3FF3FF ((,class (:foreground "#c40c0b" :background 
"#ffffff"))))
+   `(vc-annotate-face-3FFF56 ((,class (:foreground "#b801bc" :background 
"#ffffff"))))
+   `(vc-annotate-face-3FFF83 ((,class (:foreground "#c40159" :background 
"#ffffff"))))
+   `(vc-annotate-face-3FFFB0 ((,class (:foreground "#c40159" :background 
"#ffffff"))))
+   `(vc-annotate-face-3FFFDD ((,class (:foreground "#c40c0b" :background 
"#ffffff"))))
+   `(vc-annotate-face-56FF3F ((,class (:foreground "#b801bc" :background 
"#ffffff"))))
+   `(vc-annotate-face-83FF3F ((,class (:foreground "#5401c8" :background 
"#ffffff"))))
+   `(vc-annotate-face-B0FF3F ((,class (:foreground "#5401c8" :background 
"#ffffff"))))
+   `(vc-annotate-face-DDFF3F ((,class (:foreground "#060cc8" :background 
"#ffffff"))))
+   `(vc-annotate-face-F6FFCC ((,class (:foreground "#ffffff" :background 
"#252064"))))
+   `(vc-annotate-face-FF3F3F ((,class (:foreground "#06c0c8" :background 
"#ffffff"))))
+   `(vc-annotate-face-FF6C3F ((,class (:foreground "#06c0c8" :background 
"#ffffff"))))
+   `(vc-annotate-face-FF993F ((,class (:foreground "#0666c8" :background 
"#ffffff"))))
+   `(vc-annotate-face-FFC63F ((,class (:foreground "#0666c8" :background 
"#ffffff"))))
+   `(vc-annotate-face-FFF33F ((,class (:foreground "#060cc8" :background 
"#ffffff"))))
+
+   ;; ;; vc
+   ;; (vc-up-to-date-state    ((,c :foreground ,(gc 'green-1))))
+   ;; (vc-edited-state        ((,c :foreground ,(gc 'yellow+1))))
+   ;; (vc-missing-state       ((,c :foreground ,(gc 'red))))
+   ;; (vc-conflict-state      ((,c :foreground ,(gc 'red+2) :weight bold)))
+   ;; (vc-locked-state        ((,c :foreground ,(gc 'cyan-1))))
+   ;; (vc-locally-added-state ((,c :foreground ,(gc 'blue))))
+   ;; (vc-needs-update-state  ((,c :foreground ,(gc 'magenta))))
+   ;; (vc-removed-state       ((,c :foreground ,(gc 'red-1))))
+
+   `(vhl/default-face ((,class ,volatile-highlight))) ; 
`volatile-highlights.el' (for undo, yank).
+   `(w3m-anchor ((,class ,link)))
+   `(w3m-arrived-anchor ((,class (:foreground "#69cf0b"))))
+   `(w3m-bitmap-image-face ((,class (:foreground "#f7f5f9" :background 
"#ff01ff"))))
+   `(w3m-bold ((,class (:weight bold :foreground "#ffffff"))))
+   `(w3m-current-anchor ((,class (:weight bold :underline t :foreground 
"#ffff0b"))))
+   `(w3m-form ((,class (:underline t :foreground "#065ab8"))))
+   `(w3m-form-button-face ((,class (:weight bold :underline t :foreground 
"#f7f5f9" :background "#312c36"))))
+   `(w3m-form-button-mouse-face ((,class (:underline t :foreground "#312c36" 
:background "#d781db"))))
+   `(w3m-form-button-pressed-face ((,class (:weight bold :underline t 
:foreground "#f7f5f9" :background "#312c36"))))
+   `(w3m-header-line-location-content-face ((,class (:foreground 
"#848088":background "#2c2731"))))
+   `(w3m-header-line-location-title-face ((,class (:foreground "#d6aa58" 
:background "#2c2731"))))
+   `(w3m-history-current-url-face ((,class (:foreground "#252458"))))
+   `(w3m-image-face ((,class (:weight bold :foreground "#501155"))))
+   `(w3m-link-numbering ((,class (:foreground "#50381e")))) ; mouseless 
browsing
+   `(w3m-strike-through-face ((,class (:strike-through t))))
+   `(w3m-underline-face ((,class (:underline t))))
+
+   ;; `(web-mode-block-attr-name-face ((,class ())))
+   ;; `(web-mode-block-attr-value-face ((,class ())))
+   ;; `(web-mode-block-comment-face ((,class ())))
+   ;; `(web-mode-block-control-face ((,class ())))
+   ;; `(web-mode-block-delimiter-face ((,class ())))
+   ;; `(web-mode-block-face ((,class ())))
+   ;; `(web-mode-block-string-face ((,class ())))
+   ;; `(web-mode-bold-face ((,class ())))
+   ;; `(web-mode-builtin-face ((,class ())))
+   ;; `(web-mode-comment-face ((,class ())))
+   ;; `(web-mode-comment-keyword-face ((,class ())))
+   ;; `(web-mode-constant-face ((,class ())))
+   ;; `(web-mode-css-at-rule-face ((,class ())))
+   ;; `(web-mode-css-color-face ((,class ())))
+   ;; `(web-mode-css-comment-face ((,class ())))
+   ;; `(web-mode-css-function-face ((,class ())))
+   ;; `(web-mode-css-priority-face ((,class ())))
+   ;; `(web-mode-css-property-name-face ((,class ())))
+   ;; `(web-mode-css-pseudo-class-face ((,class ())))
+   ;; `(web-mode-css-selector-face ((,class ())))
+   ;; `(web-mode-css-string-face ((,class ())))
+   ;; `(web-mode-css-variable-face ((,class ())))
+   ;; `(web-mode-current-column-highlight-face ((,class ())))
+   `(web-mode-current-element-highlight-face ((,class (:background 
"#6b330b")))) ; #061187
+   ;; `(web-mode-doctype-face ((,class ())))
+   ;; `(web-mode-error-face ((,class ())))
+   ;; `(web-mode-filter-face ((,class ())))
+   `(web-mode-folded-face ((,class (:box (:line-width 1 :color "#8c8890") 
:foreground "#6a659d" :background "#110cbe"))))
+   ;; `(web-mode-function-call-face ((,class ())))
+   ;; `(web-mode-function-name-face ((,class ())))
+   ;; `(web-mode-html-attr-custom-face ((,class ())))
+   ;; `(web-mode-html-attr-engine-face ((,class ())))
+   ;; `(web-mode-html-attr-equal-face ((,class ())))
+   `(web-mode-html-attr-name-face ((,class ,xml-attribute)))
+   ;; `(web-mode-html-attr-value-face ((,class ())))
+   ;; `(web-mode-html-entity-face ((,class ())))
+   `(web-mode-html-tag-bracket-face ((,class ,xml-tag)))
+   ;; `(web-mode-html-tag-custom-face ((,class ())))
+   `(web-mode-html-tag-face ((,class ,xml-tag)))
+   ;; `(web-mode-html-tag-namespaced-face ((,class ())))
+   ;; `(web-mode-inlay-face ((,class ())))
+   ;; `(web-mode-italic-face ((,class ())))
+   ;; `(web-mode-javascript-comment-face ((,class ())))
+   ;; `(web-mode-javascript-string-face ((,class ())))
+   ;; `(web-mode-json-comment-face ((,class ())))
+   ;; `(web-mode-json-context-face ((,class ())))
+   ;; `(web-mode-json-key-face ((,class ())))
+   ;; `(web-mode-json-string-face ((,class ())))
+   ;; `(web-mode-jsx-depth-1-face ((,class ())))
+   ;; `(web-mode-jsx-depth-2-face ((,class ())))
+   ;; `(web-mode-jsx-depth-3-face ((,class ())))
+   ;; `(web-mode-jsx-depth-4-face ((,class ())))
+   ;; `(web-mode-keyword-face ((,class ())))
+   ;; `(web-mode-param-name-face ((,class ())))
+   ;; `(web-mode-part-comment-face ((,class ())))
+   `(web-mode-part-face ((,class (:background "#252046"))))
+   ;; `(web-mode-part-string-face ((,class ())))
+   ;; `(web-mode-preprocessor-face ((,class ())))
+   `(web-mode-script-face ((,class (:background "#332d37"))))
+   ;; `(web-mode-sql-keyword-face ((,class ())))
+   ;; `(web-mode-string-face ((,class ())))
+   ;; `(web-mode-style-face ((,class ())))
+   ;; `(web-mode-symbol-face ((,class ())))
+   ;; `(web-mode-type-face ((,class ())))
+   ;; `(web-mode-underline-face ((,class ())))
+   ;; `(web-mode-variable-name-face ((,class ())))
+   ;; `(web-mode-warning-face ((,class ())))
+   ;; `(web-mode-whitespace-face ((,class ())))
+
+   `(which-func ((,class (:weight bold :slant italic :foreground "#25202a"))))
+   ;; `(which-key-command-description-face)
+   ;; `(which-key-group-description-face)
+   ;; `(which-key-highlighted-command-face)
+   ;; `(which-key-key-face)
+   `(which-key-local-map-description-face ((,class (:weight bold :background 
"#30272c" :inherit which-key-command-description-face))))
+   ;; `(which-key-note-face)
+   ;; `(which-key-separator-face)
+   ;; `(which-key-special-key-face)
+   `(widget-button ((,class ,link)))
+   `(widget-button-pressed ((,class (:foreground "#06ffff"))))
+   `(widget-documentation ((,class (:foreground "#ff74ff"))))
+   `(widget-field ((,class (:background "#2b2630"))))
+   `(widget-inactive ((,class (:foreground "#9a969e"))))
+   `(widget-single-line-field ((,class (:background "#2b2630"))))
+   `(woman-bold ((,class (:weight bold :foreground "#13c2ca"))))
+   `(woman-italic ((,class (:weight bold :slant italic :foreground 
"#bd41ea"))))
+   `(woman-symbol ((,class (:weight bold :foreground "#64df19"))))
+   `(yas-field-debug-face ((,class (:foreground "#25202a" :background 
"#5edeb3"))))
+   `(yas-field-highlight-face ((,class (:box (:line-width 1 :color "#807c84") 
:foreground "#ffffff" :background "#302331"))))
+
+   ;; `(ztreep-arrow-face ((,class ())))
+   ;; `(ztreep-diff-header-face ((,class ())))
+   ;; `(ztreep-diff-header-small-face ((,class ())))
+   `(ztreep-diff-model-add-face ((,class (:weight bold :foreground 
"#ff77ff"))))
+   `(ztreep-diff-model-diff-face ((,class (:weight bold :foreground 
"#ffbb2c"))))
+   `(ztreep-diff-model-ignored-face ((,class (:strike-through t :foreground 
"#66616b"))))
+   `(ztreep-diff-model-normal-face ((,class (:foreground "#ffffff"))))
+   ;; `(ztreep-expand-sign-face ((,class ())))
+   ;; `(ztreep-header-face ((,class ())))
+   ;; `(ztreep-leaf-face ((,class ())))
+   ;; `(ztreep-node-face ((,class ())))
+
+   ))
+
+(custom-theme-set-variables 'leuven-dark
+
+  ;; highlight-sexp-mode.
+  '(hl-sexp-background-color "#33323e")
+
+  '(ansi-color-faces-vector
+    [default default default italic underline success warning error])
+
+  ;; Colors used in Shell mode.
+  '(ansi-color-names-vector
+    ["#ffffff" "#37ffff" "#e074e3" "#3732ff" "#ffff0b" "#37ff3c" "#ff400b" 
"#848088"])
+ )
+
+;;;###autoload
+(when (and (boundp 'custom-theme-load-path)
+           load-file-name)
+  ;; Add theme folder to `custom-theme-load-path' when installing over MELPA.
+  (add-to-list 'custom-theme-load-path
+               (file-name-as-directory (file-name-directory load-file-name))))
+
+(provide-theme 'leuven-dark)
+
+;; This is for the sake of Emacs.
+;; Local Variables:
+;; time-stamp-end: "$"
+;; time-stamp-format: "%:y%02m%02d.%02H%02M"
+;; time-stamp-start: "Version: "
+;; End:
+
+;;; leuven-dark-theme.el ends here
diff --git a/leim/Makefile.in b/leim/Makefile.in
index 2a477d868b..6cf0abb40c 100644
--- a/leim/Makefile.in
+++ b/leim/Makefile.in
@@ -122,6 +122,7 @@ leim-list.el: ${leimdir}/leim-list.el
 ${leimdir}/leim-list.el: ${srcdir}/leim-ext.el ${TIT_MISC}
        $(AM_V_GEN)rm -f $@
        $(AM_V_at)${RUN_EMACS} -l international/quail \
+         --eval "(setq max-specpdl-size 5000)" \
          --eval "(update-leim-list-file (unmsys--file-name \"${leimdir}\"))"
        $(AM_V_at)sed -n -e '/^[^;]/p' -e 's/^;\(;*\)inc /;\1 /p' < $< >> $@
 
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 97a122b7bc..918c0c7f19 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -692,7 +692,7 @@ system.")
 
 (defun auto-revert-notify-handler (event)
   "Handle an EVENT returned from file notification."
-  (with-demoted-errors
+  (with-demoted-errors "Error while auto-reverting: %S"
     (let* ((descriptor (car event))
           (action (nth 1 event))
           (file (nth 2 event))
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 86c0ea1a90..26b17035ef 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -654,6 +654,18 @@ By default, this shows the information specified by 
`global-mode-string'.")
   (with-selected-window (posn-window (event-start event))
     (previous-buffer)))
 
+(defun mode-line-window-selected-p ()
+  "Return non-nil if we're updating the mode line for the selected window.
+This function is meant to be called in `:eval' mode line
+constructs to allow altering the look of the mode line depending
+on whether the mode line belongs to the currently selected window
+or not."
+  (let ((window (selected-window)))
+    (or (eq window (old-selected-window))
+       (and (minibuffer-window-active-p (minibuffer-window))
+            (with-selected-window (minibuffer-window)
+              (eq window (minibuffer-selected-window)))))))
+
 (defmacro bound-and-true-p (var)
   "Return the value of symbol VAR if it is bound, else nil.
 Note that if `lexical-binding' is in effect, this function isn't
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index 0279d5ea83..8753326881 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -1274,7 +1274,10 @@ then offer interactively to relocate 
BOOKMARK-NAME-OR-RECORD."
 (defun bookmark-default-handler (bmk-record)
   "Default handler to jump to a particular bookmark location.
 BMK-RECORD is a bookmark record, not a bookmark name (i.e., not a string).
-Changes current buffer and point and returns nil, or signals a `file-error'."
+Changes current buffer and point and returns nil, or signals a `file-error'.
+
+If BMK-RECORD has a property called `buffer', it should be a live
+buffer object, and this buffer will be selected."
   (let ((file          (bookmark-get-filename bmk-record))
        (buf           (bookmark-prop-get bmk-record 'buffer))
         (forward-str   (bookmark-get-front-context-string bmk-record))
diff --git a/lisp/cedet/semantic/wisent/comp.el 
b/lisp/cedet/semantic/wisent/comp.el
index f842b3c364..ba67d25060 100644
--- a/lisp/cedet/semantic/wisent/comp.el
+++ b/lisp/cedet/semantic/wisent/comp.el
@@ -65,6 +65,7 @@
 (defmacro wisent-defcontext (name &rest vars)
   "Define a context NAME that will bind variables VARS."
   (declare (indent 1))
+  (declare-function wisent-context-name nil (name))
   (let* ((context (wisent-context-name name))
          (declarations (mapcar (lambda (v) (list 'defvar v)) vars)))
     `(progn
@@ -75,6 +76,7 @@
 (defmacro wisent-with-context (name &rest body)
   "Bind variables in context NAME then eval BODY."
   (declare (indent 1))
+  (declare-function wisent-context-bindings nil (name))
   `(dlet ,(wisent-context-bindings name)
      ,@body))
 
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index caac8ce34f..0ea689e3d6 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -3976,6 +3976,18 @@ Optional EVENT is the location for the menu."
       (setq comment nil)
       ;; Make the comment invisible by hand if it's empty
       (custom-comment-hide comment-widget))
+    ;; When modifying the default face, we need to save the standard or themed
+    ;; attrs, in case the user asks to revert to them in the future.
+    ;; In GUIs, when resetting the attributes of the default face, the frame
+    ;; parameters associated with this face won't change, unless explicitly
+    ;; passed a value.  Storing this known attrs allows us to tell faces.el to
+    ;; set those attributes to specified values, making the relevant frame
+    ;; parameters stay in sync with the default face.
+    (when (and (eq symbol 'default)
+               (not (get symbol 'custom-face-default-attrs))
+               (memq (custom-face-state symbol) '(standard themed)))
+      (put symbol 'custom-face-default-attrs
+           (custom-face-get-current-spec symbol)))
     (custom-push-theme 'theme-face symbol 'user 'set value)
     (face-spec-set symbol value 'customized-face)
     (put symbol 'face-comment comment)
@@ -3994,6 +4006,12 @@ Optional EVENT is the location for the menu."
       (setq comment nil)
       ;; Make the comment invisible by hand if it's empty
       (custom-comment-hide comment-widget))
+    ;; See the comments in `custom-face-set'.
+    (when (and (eq symbol 'default)
+               (not (get symbol 'custom-face-default-attrs))
+               (memq (custom-face-state symbol) '(standard themed)))
+      (put symbol 'custom-face-default-attrs
+           (custom-face-get-current-spec symbol)))
     (custom-push-theme 'theme-face symbol 'user 'set value)
     (face-spec-set symbol value (if standard 'reset 'saved-face))
     (put symbol 'face-comment comment)
@@ -4007,7 +4025,14 @@ Optional EVENT is the location for the menu."
 
 (defun custom-face-save (widget)
   "Save the face edited by WIDGET."
-  (let ((form (widget-get widget :custom-form)))
+  (let ((form (widget-get widget :custom-form))
+        (symbol (widget-value widget)))
+    ;; See the comments in `custom-face-set'.
+    (when (and (eq symbol 'default)
+               (not (get symbol 'custom-face-default-attrs))
+               (memq (custom-face-state symbol) '(standard themed)))
+      (put symbol 'custom-face-default-attrs
+           (custom-face-get-current-spec symbol)))
     (if (memq form '(all lisp))
         (custom-face-mark-to-save widget)
       ;; The user is working on only a selected terminal type;
@@ -4035,10 +4060,20 @@ uncustomized (themed or standard) face."
         (saved-face (get face 'saved-face))
         (comment (get face 'saved-face-comment))
         (comment-widget (widget-get widget :comment-widget)))
+    ;; If resetting the default face and there isn't a saved value,
+    ;; push a fake user setting, so that reverting to the default
+    ;; attributes works.
     (custom-push-theme 'theme-face face 'user
-                      (if saved-face 'set 'reset)
-                      saved-face)
+                       (if (or saved-face (eq face 'default)) 'set 'reset)
+                       (or saved-face
+                           ;; If this is t, then MODE is 'reset,
+                           ;; and `custom-push-theme' ignores this argument.
+                           (not (eq face 'default))
+                           (get face 'custom-face-default-attrs)))
     (face-spec-set face saved-face 'saved-face)
+    (when (and (not saved-face) (eq face 'default))
+      ;; Remove the fake user setting.
+      (custom-push-theme 'theme-face face 'user 'reset))
     (put face 'face-comment comment)
     (put face 'customized-face-comment nil)
     (widget-value-set child saved-face)
@@ -4060,8 +4095,15 @@ redraw the widget immediately."
         (comment-widget (widget-get widget :comment-widget)))
     (unless value
       (user-error "No standard setting for this face"))
-    (custom-push-theme 'theme-face symbol 'user 'reset)
+    ;; If erasing customizations for the default face, push a fake user 
setting,
+    ;; so that reverting to the default attributes works.
+    (custom-push-theme 'theme-face symbol 'user
+                       (if (eq symbol 'default) 'set 'reset)
+                       (or (not (eq symbol 'default))
+                           (get symbol 'custom-face-default-attrs)))
     (face-spec-set symbol value 'reset)
+    ;; Remove the fake user setting.
+    (custom-push-theme 'theme-face symbol 'user 'reset)
     (put symbol 'face-comment nil)
     (put symbol 'customized-face-comment nil)
     (if (and custom-reset-standard-faces-list
diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index 12ad3910fc..80d0aaa0d5 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -133,7 +133,7 @@
             :help-echo "Control text underlining."
             (const :tag "Off" nil)
             (list :tag "On"
-                  :value (:color foreground-color :style line)
+                  :value (:color foreground-color :style line :position nil)
                   (const :format "" :value :color)
                   (choice :tag "Color"
                           (const :tag "Foreground Color" foreground-color)
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
index fedc10cea4..110f7e4abf 100644
--- a/lisp/emacs-lisp/byte-run.el
+++ b/lisp/emacs-lisp/byte-run.el
@@ -656,7 +656,7 @@ For the `mapcar' case, only the `mapcar' function can be 
used in
 the symbol list.  For `suspicious', only `set-buffer' can be used."
   ;; Note: during compilation, this definition is overridden by the one in
   ;; byte-compile-initial-macro-environment.
-  (declare (debug (sexp &optional body)) (indent 1))
+  (declare (debug (sexp body)) (indent 1))
   (if (not (and (featurep 'macroexp)
                 (boundp 'byte-compile--suppressed-warnings)))
       ;; If `macroexp' is not yet loaded, we're in the middle of
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index d89403ba5d..f94571b7f2 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1031,30 +1031,23 @@ Each function's symbol gets added to 
`byte-compile-noruntime-functions'."
        (hist-nil-orig current-load-list))
     (prog1 (eval form lexical-binding)
       (when (byte-compile-warning-enabled-p 'noruntime)
-       (let ((hist-new load-history)
-             (hist-nil-new current-load-list))
+       (let* ((hist-new
+               ;; Get new `current-load-list' for the locally defined funs.
+               (cons (butlast current-load-list
+                              (length hist-nil-orig))
+                     load-history)))
          ;; Go through load-history, look for newly loaded files
          ;; and mark all the functions defined therein.
          (while (and hist-new (not (eq hist-new hist-orig)))
-           (let ((xs (pop hist-new))
-                 old-autoloads)
+           (let ((xs (pop hist-new)))
              ;; Make sure the file was not already loaded before.
              (unless (assoc (car xs) hist-orig)
                (dolist (s xs)
-                 (cond
-                  ((and (consp s) (eq t (car s)))
-                   (push (cdr s) old-autoloads))
-                  ((and (consp s) (memq (car s) '(autoload defun)))
-                   (unless (memq (cdr s) old-autoloads)
-                      (push (cdr s) byte-compile-noruntime-functions))))))))
-         ;; Go through current-load-list for the locally defined funs.
-         (let (old-autoloads)
-           (while (and hist-nil-new (not (eq hist-nil-new hist-nil-orig)))
-             (let ((s (pop hist-nil-new)))
-               (when (and (symbolp s) (not (memq s old-autoloads)))
-                 (push s byte-compile-noruntime-functions))
-               (when (and (consp s) (eq t (car s)))
-                  (push (cdr s) old-autoloads))))))))))
+                 (pcase s
+                   (`(defun . ,f)
+                    (unless (seq-some #'autoloadp
+                                      (get (cdr s) 'function-history))
+                       (push f byte-compile-noruntime-functions)))))))))))))
 
 (defun byte-compile-eval-before-compile (form)
   "Evaluate FORM for `eval-and-compile'."
@@ -2205,20 +2198,20 @@ With argument ARG, insert value in current buffer after 
the form."
   (save-excursion
     (end-of-defun)
     (beginning-of-defun)
-    (let* ((print-symbols-bare t)
+    (let* ((print-symbols-bare t)       ; For the final `message'.
            (byte-compile-current-file (current-buffer))
           (byte-compile-current-buffer (current-buffer))
           (start-read-position (point))
           (byte-compile-last-warned-form 'nothing)
+           (symbols-with-pos-enabled t)
           (value (eval
-                  (let ((symbols-with-pos-enabled t))
-                    (displaying-byte-compile-warnings
-                     (byte-compile-sexp
-                       (let ((form (read-positioning-symbols 
(current-buffer))))
-                         (push form byte-compile-form-stack)
-                         (eval-sexp-add-defvars
-                          form
-                          start-read-position)))))
+                  (displaying-byte-compile-warnings
+                   (byte-compile-sexp
+                     (let ((form (read-positioning-symbols (current-buffer))))
+                       (push form byte-compile-form-stack)
+                       (eval-sexp-add-defvars
+                        form
+                        start-read-position))))
                    lexical-binding)))
       (cond (arg
             (message "Compiling from buffer... done.")
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index a23169aa0f..122638077c 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -1767,6 +1767,7 @@ This is responsible for generating the proper stack 
adjustment, when known,
 and the annotation emission."
   (declare (debug (body))
            (indent defun))
+  (declare-function comp-body-eff nil (body op-name sp-delta))
   `(pcase op
      ,@(cl-loop for (op . body) in cases
                for sp-delta = (gethash op comp-op-stack-info)
@@ -1831,7 +1832,9 @@ and the annotation emission."
       (byte-listp auto)
       (byte-eq auto)
       (byte-memq auto)
-      (byte-not null)
+      (byte-not
+       (comp-emit-set-call (comp-call 'eq (comp-slot-n (comp-sp))
+                                      (make-comp-mvar :constant nil))))
       (byte-car auto)
       (byte-cdr auto)
       (byte-cons auto)
diff --git a/lisp/emacs-lisp/debug-early.el b/lisp/emacs-lisp/debug-early.el
new file mode 100644
index 0000000000..e557643e46
--- /dev/null
+++ b/lisp/emacs-lisp/debug-early.el
@@ -0,0 +1,87 @@
+;;; debug-early.el --- Dump a Lisp backtrace without frills  -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Alan Mackenzie <acm@muc.de>
+;; Maintainer: emacs-devel@gnu.org
+;; Keywords: internal, backtrace, bootstrap.
+;; Package: emacs
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file dumps a backtrace on stderr when an error is thrown.  It
+;; has no dependencies on any Lisp libraries and is thus used for
+;; generating backtraces for bugs in the early parts of bootstrapping.
+;; It is also always used in batch model.  It was introduced in Emacs
+;; 29, before which there was no backtrace available during early
+;; bootstrap.
+
+(defalias 'debug-early-backtrace
+  #'(lambda ()
+  "Print a trace of Lisp function calls currently active.
+The output stream used is the value of `standard-output'.
+
+This is a simplified version of the standard `backtrace'
+function, intended for use in debugging the early parts
+of the build process."
+  (princ "\n")
+  (mapbacktrace
+   #'(lambda (evald func args _flags)
+       (let ((args args))
+        (if evald
+            (progn
+              (princ "  ")
+              (prin1 func)
+              (princ "(")
+              (while args
+                (prin1 (car args))
+                (setq args (cdr args))
+                (if args
+                    (princ " ")))
+              (princ ")\n"))
+          (while args
+            (princ "  ")
+            (prin1 (car args))
+            (princ "\n")
+            (setq args (cdr args)))))))))
+
+(defalias 'debug-early
+  #'(lambda (&rest args)
+  "Print an error message with a backtrace of active Lisp function calls.
+The output stream used is the value of `standard-output'.
+
+The Emacs core calls this function after an error has been
+signaled, and supplies two ARGS.  These are the symbol
+`error' (which is ignored) and a cons of the error symbol and the
+error data.
+
+`debug-early' is a simplified version of `debug', and is
+available during the early parts of the build process.  It is
+superseded by `debug' after enough Lisp has been loaded to
+support the latter, except in batch mode which always uses
+`debug-early'.
+
+(In versions of Emacs prior to Emacs 29, no backtrace was
+available before `debug' was usable.)"
+  (princ "\nError: ")
+  (prin1 (car (car (cdr args))))       ; The error symbol.
+  (princ " ")
+  (prin1 (cdr (car (cdr args))))       ; The error data.
+  (debug-early-backtrace)))
+
+;;; debug-early.el ends here.
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index 6cdd3ccb6d..041cec2178 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -212,7 +212,7 @@ It creates an autoload function for CNAME's constructor."
       (when eieio-backward-compatibility
         (set cname cname)
         (make-obsolete-variable cname (format "\
-use \\='%s or turn off `eieio-backward-compatibility' instead" cname)
+use '%s or turn off `eieio-backward-compatibility' instead" cname)
                                 "25.1"))
 
       (setf (cl--find-class cname) newc)
@@ -337,7 +337,7 @@ See `defclass' for more information."
     ;; turn this into a usable self-pointing symbol;  FIXME: Why?
     (when eieio-backward-compatibility
       (set cname cname)
-      (make-obsolete-variable cname (format "use \\='%s instead" cname)
+      (make-obsolete-variable cname (format "use '%s instead" cname)
                               "25.1"))
 
     ;; Create a handy list of the class test too
@@ -359,7 +359,7 @@ See `defclass' for more information."
                   (setq obj (cdr obj)))
                 ans))))
         (make-obsolete csym (format
-                             "use (cl-typep ... \\='(list-of %s)) instead"
+                             "use (cl-typep ... '(list-of %s)) instead"
                              cname)
                        "25.1")))
 
@@ -417,7 +417,7 @@ See `defclass' for more information."
                  (progn
                    (set initarg initarg)
                    (make-obsolete-variable
-                    initarg (format "use \\='%s instead" initarg) "25.1"))))
+                    initarg (format "use '%s instead" initarg) "25.1"))))
 
        ;; The customgroup should be a list of symbols.
        (cond ((and (null customg) custom)
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 74f8463148..738b5bdeae 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -260,7 +260,7 @@ This method is obsolete."
            (let ((f (intern (format "%s-child-p" name))))
              `((defalias ',f #',testsym2)
                (make-obsolete
-                ',f ,(format "use (cl-typep ... \\='%s) instead" name)
+                ',f ,(format "use (cl-typep ... '%s) instead" name)
                 "25.1"))))
 
        ;; When using typep, (typep OBJ 'myclass) returns t for objects which
diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el
index e5c94c09c2..385ddb3f41 100644
--- a/lisp/emacs-lisp/elp.el
+++ b/lisp/emacs-lisp/elp.el
@@ -287,7 +287,12 @@ type \"nil\" to use `elp-function-list'."
   "Instrument for profiling, all functions which start with PREFIX.
 For example, to instrument all ELP functions, do the following:
 
-    \\[elp-instrument-package] RET elp- RET"
+    \\[elp-instrument-package] RET elp- RET
+
+Note that only functions that are currently loaded will be
+instrumented.  If you run this function, and then later load
+further functions that start with PREFIX, they will not be
+instrumented automatically."
   (interactive
    (list (completing-read "Prefix of package to instrument: "
                           obarray 'elp-profilable-p)))
diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el
index 2818d4b6cc..0e412a8d34 100644
--- a/lisp/emacs-lisp/ert-x.el
+++ b/lisp/emacs-lisp/ert-x.el
@@ -475,6 +475,14 @@ The same keyword arguments are supported as in
      :directory t
      ,@body))
 
+(defun ert-gcc-is-clang-p ()
+  "Return non-nil if the `gcc' command actually runs the Clang compiler."
+  ;; Some macOS machines run llvm when you type gcc.  (!)
+  ;; We can't even check if it's a symlink; it's a binary placed in
+  ;; "/usr/bin/gcc".  So we need to check the output.
+  (string-match "Apple \\(LLVM\\|[Cc]lang\\)\\|Xcode\\.app"
+                (shell-command-to-string "gcc --version")))
+
 (provide 'ert-x)
 
 ;;; ert-x.el ends here
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index 6eac25c100..571087c963 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -183,6 +183,16 @@ See the functions `find-function' and `find-variable'."
   :group 'find-function
   :version "20.3")
 
+(defcustom find-library-include-other-files t
+  "If non-nil, `read-library-name' will also include non-library files.
+This affects commands like `read-library'.
+
+If nil, only library files (i.e., \".el\" files) will be offered
+for completion."
+  :type 'boolean
+  :version "29.1"
+  :group 'find-function)
+
 ;;; Functions:
 
 (defun find-library-suffixes ()
@@ -302,7 +312,10 @@ TYPE should be nil to find a function, or `defvar' to find 
a variable."
 Interactively, prompt for LIBRARY using the one at or near point.
 
 This function searches `find-library-source-path' if non-nil, and
-`load-path' otherwise."
+`load-path' otherwise.
+
+See the `find-library-include-other-files' user option for
+customizing the candidate completions."
   (interactive (list (read-library-name)))
   (prog1
       (switch-to-buffer (find-file-noselect (find-library-name library)))
@@ -317,8 +330,6 @@ in a directory under `load-path' (or 
`find-library-source-path',
 if non-nil)."
   (let* ((dirs (or find-library-source-path load-path))
          (suffixes (find-library-suffixes))
-         (table (apply-partially 'locate-file-completion-table
-                                 dirs suffixes))
          (def (if (eq (function-called-at-point) 'require)
                   ;; `function-called-at-point' may return 'require
                   ;; with `point' anywhere on this line.  So wrap the
@@ -332,10 +343,28 @@ if non-nil)."
                         (thing-at-point 'symbol))
                     (error nil))
                 (thing-at-point 'symbol))))
-    (when (and def (not (test-completion def table)))
-      (setq def nil))
-    (completing-read (format-prompt "Library name" def)
-                     table nil nil nil nil def)))
+    (if find-library-include-other-files
+        (let ((table (apply-partially #'locate-file-completion-table
+                                      dirs suffixes)))
+          (when (and def (not (test-completion def table)))
+            (setq def nil))
+          (completing-read (format-prompt "Library name" def)
+                           table nil nil nil nil def))
+      (let ((files (read-library-name--find-files dirs suffixes)))
+        (when (and def (not (member def files)))
+          (setq def nil))
+        (completing-read (format-prompt "Library name" def)
+                         files nil t nil nil def)))))
+
+(defun read-library-name--find-files (dirs suffixes)
+  "Return a list of all files in DIRS that match SUFFIXES."
+  (let ((files nil)
+        (regexp (concat (regexp-opt suffixes) "\\'")))
+    (dolist (dir dirs)
+      (dolist (file (ignore-errors (directory-files dir nil regexp t)))
+        (and (string-match regexp file)
+             (push (substring file 0 (match-beginning 0)) files))))
+    files))
 
 ;;;###autoload
 (defun find-library-other-window (library)
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index aa3e48155c..2e01449613 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -1005,7 +1005,8 @@ untar into a directory named DIR; otherwise, signal an 
error."
   "Make sure that the autoload file FILE exists and if not create it."
   (unless (file-exists-p file)
     (require 'autoload)
-    (write-region (autoload-rubric file "package" nil) nil file nil 'silent))
+    (let ((coding-system-for-write 'utf-8-emacs-unix))
+      (write-region (autoload-rubric file "package" nil) nil file nil 
'silent)))
   file)
 
 (defvar autoload-timestamps)
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index b2283e66e4..2bab131913 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -1301,9 +1301,9 @@ Only meaningful when called from within 
`smie-rules-function'."
   (let ((afterpos (save-excursion
                     (let ((tok (funcall smie-forward-token-function)))
                       (unless tok
-                        (with-demoted-errors
-                          (error "smie-rule-separator: Can't skip token %s"
-                                 smie--token))))
+                        (funcall (if debug-on-error #'error #'message)
+                                 "smie-rule-separator: Can't skip token %s"
+                                 smie--token)))
                     (skip-chars-forward " ")
                     (unless (eolp) (point)))))
     (or (and afterpos
@@ -1820,7 +1820,7 @@ to which that point should be aligned, if we were to 
reindent it.")
   "Indent current line using the SMIE indentation engine."
   (interactive)
   (let* ((savep (point))
-        (indent (or (with-demoted-errors
+        (indent (or (with-demoted-errors "SMIE Error: %S"
                        (save-excursion
                          (forward-line 0)
                          (skip-chars-forward " \t")
@@ -1846,7 +1846,7 @@ to which that point should be aligned, if we were to 
reindent it.")
                            (move-to-column fc)
                            (syntax-ppss))))
         (while
-            (and (with-demoted-errors
+            (and (with-demoted-errors "SMIE Error: %S"
                    (save-excursion
                      (let ((end (point))
                            (bsf nil)    ;Best-so-far.
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index c6a51b1793..b79475f6e0 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -314,7 +314,7 @@ to writing a completion function."
 (defun eshell-complete-parse-arguments ()
   "Parse the command line arguments for `pcomplete-argument'."
   (when (and eshell-no-completion-during-jobs
-            (eshell-interactive-process))
+            (eshell-interactive-process-p))
     (insert-and-inherit "\t")
     (throw 'pcompleted t))
   (let ((end (point-marker))
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el
index 893cad7b4f..3998026d7f 100644
--- a/lisp/eshell/em-dirs.el
+++ b/lisp/eshell/em-dirs.el
@@ -391,6 +391,10 @@ in the minibuffer:
        (unless (equal curdir newdir)
          (eshell-add-to-dir-ring curdir))
        (let ((result (cd newdir)))
+          ;; If we're in "/" and cd to ".." or the like, make things
+          ;; less confusing by changing "/.." to "/".
+          (when (equal (file-truename result) "/")
+            (setq result (cd "/")))
          (and eshell-cd-shows-directory
               (eshell-printn result)))
        (run-hooks 'eshell-directory-change-hook)
diff --git a/lisp/eshell/em-rebind.el b/lisp/eshell/em-rebind.el
index f24758d4e3..2b56c9e844 100644
--- a/lisp/eshell/em-rebind.el
+++ b/lisp/eshell/em-rebind.el
@@ -238,7 +238,7 @@ lock it at that."
 Sends an EOF only if point is at the end of the buffer and there is no
 input."
   (interactive "p")
-  (let ((proc (eshell-interactive-process)))
+  (let ((proc (eshell-head-process)))
     (if (eobp)
        (cond
         ((/= (point) eshell-last-output-end)
diff --git a/lisp/eshell/em-term.el b/lisp/eshell/em-term.el
index e34c5ae47c..d150c07b03 100644
--- a/lisp/eshell/em-term.el
+++ b/lisp/eshell/em-term.el
@@ -224,7 +224,7 @@ the buffer."
 
 ; (defun eshell-term-send-raw-string (chars)
 ;   (goto-char eshell-last-output-end)
-;   (process-send-string (eshell-interactive-process) chars))
+;   (process-send-string (eshell-head-process) chars))
 
 ; (defun eshell-term-send-raw ()
 ;   "Send the last character typed through the terminal-emulator
diff --git a/lisp/eshell/em-tramp.el b/lisp/eshell/em-tramp.el
index 2afd4fe066..aebbc36e71 100644
--- a/lisp/eshell/em-tramp.el
+++ b/lisp/eshell/em-tramp.el
@@ -71,7 +71,7 @@ Become another USER during a login session.")
    (throw 'eshell-replace-command
           (let ((user "root")
                 (host (or (file-remote-p default-directory 'host)
-                          "localhost"))
+                          tramp-default-host))
                 (dir (file-local-name (expand-file-name default-directory)))
                 (prefix (file-remote-p default-directory)))
             (dolist (arg args)
@@ -106,7 +106,7 @@ Execute a COMMAND as the superuser or another USER.")
    (throw 'eshell-external
           (let* ((user (or user "root"))
                  (host (or (file-remote-p default-directory 'host)
-                           "localhost"))
+                           tramp-default-host))
                  (dir (file-local-name (expand-file-name default-directory)))
                  (prefix (file-remote-p default-directory))
                  (default-directory
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 04d65df4f3..5819506cc0 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -279,14 +279,33 @@ otherwise t.")
 (defvar eshell-in-subcommand-p nil)
 (defvar eshell-last-arguments nil)
 (defvar eshell-last-command-name nil)
-(defvar eshell-last-async-proc nil
-  "When this foreground process completes, resume command evaluation.")
+(defvar eshell-last-async-procs nil
+  "The currently-running foreground process(es).
+When executing a pipeline, this is a cons cell whose CAR is the
+first process (usually reading from stdin) and whose CDR is the
+last process (usually writing to stdout).  Otherwise, the CAR and
+CDR are the same process.
+
+When the process in the CDR completes, resume command evaluation.")
 
 ;;; Functions:
 
-(defsubst eshell-interactive-process ()
-  "Return currently running command process, if non-Lisp."
-  eshell-last-async-proc)
+(defsubst eshell-interactive-process-p ()
+  "Return non-nil if there is a currently running command process."
+  eshell-last-async-procs)
+
+(defsubst eshell-head-process ()
+  "Return the currently running process at the head of any pipeline.
+This only returns external (non-Lisp) processes."
+  (car-safe eshell-last-async-procs))
+
+(defsubst eshell-tail-process ()
+  "Return the currently running process at the tail of any pipeline.
+This only returns external (non-Lisp) processes."
+  (cdr-safe eshell-last-async-procs))
+
+(define-obsolete-function-alias 'eshell-interactive-process
+  'eshell-tail-process "29.1")
 
 (defun eshell-cmd-initialize ()     ;Called from `eshell-mode' via intern-soft!
   "Initialize the Eshell command processing module."
@@ -295,7 +314,7 @@ otherwise t.")
   (setq-local eshell-command-arguments nil)
   (setq-local eshell-last-arguments nil)
   (setq-local eshell-last-command-name nil)
-  (setq-local eshell-last-async-proc nil)
+  (setq-local eshell-last-async-procs nil)
 
   (add-hook 'eshell-kill-hook #'eshell-resume-command nil t)
 
@@ -306,7 +325,7 @@ otherwise t.")
   (add-hook 'eshell-post-command-hook
             (lambda ()
               (setq eshell-current-command nil
-                    eshell-last-async-proc nil))
+                    eshell-last-async-procs nil))
             nil t)
 
   (add-hook 'eshell-parse-argument-hook
@@ -764,8 +783,7 @@ This macro calls itself recursively, with NOTFIRST non-nil."
               (eshell-set-output-handle ,eshell-output-handle
                                         'append nextproc)
               (eshell-set-output-handle ,eshell-error-handle
-                                        'append nextproc)
-              (setq tailproc (or tailproc nextproc))))
+                                        'append nextproc)))
        ,(let ((head (car pipeline)))
           (if (memq (car head) '(let progn))
               (setq head (car (last head))))
@@ -781,7 +799,10 @@ This macro calls itself recursively, with NOTFIRST 
non-nil."
               ,(cond ((not notfirst) (quote 'first))
                      ((cdr pipeline) t)
                      (t (quote 'last)))))
-         ,(car pipeline))))))
+          (let ((proc ,(car pipeline)))
+            (setq headproc (or proc headproc))
+            (setq tailproc (or tailproc proc))
+            proc))))))
 
 (defmacro eshell-do-pipelines-synchronously (pipeline)
   "Execute the commands in PIPELINE in sequence synchronously.
@@ -822,7 +843,7 @@ This is used on systems where async subprocesses are not 
supported."
 
 (defmacro eshell-execute-pipeline (pipeline)
   "Execute the commands in PIPELINE, connecting each to one another."
-  `(let ((eshell-in-pipeline-p t) tailproc)
+  `(let ((eshell-in-pipeline-p t) headproc tailproc)
      (progn
        ,(if (fboundp 'make-process)
            `(eshell-do-pipelines ,pipeline)
@@ -832,7 +853,7 @@ This is used on systems where async subprocesses are not 
supported."
                                (car (aref eshell-current-handles
                                           ,eshell-error-handle)) nil)))
             (eshell-do-pipelines-synchronously ,pipeline)))
-       (eshell-process-identity tailproc))))
+       (eshell-process-identity (cons headproc tailproc)))))
 
 (defmacro eshell-as-subcommand (command)
   "Execute COMMAND using a temp buffer.
@@ -992,24 +1013,24 @@ produced by `eshell-parse-command'."
     (unless (or (not (stringp status))
                (string= "stopped" status)
                (string-match eshell-reset-signals status))
-      (if (eq proc (eshell-interactive-process))
+      (if (eq proc (eshell-tail-process))
          (eshell-resume-eval)))))
 
 (defun eshell-resume-eval ()
   "Destructively evaluate a form which may need to be deferred."
   (eshell-condition-case err
       (progn
-       (setq eshell-last-async-proc nil)
+       (setq eshell-last-async-procs nil)
        (when eshell-current-command
          (let* (retval
-                (proc (catch 'eshell-defer
+                (procs (catch 'eshell-defer
                         (ignore
                          (setq retval
                                (eshell-do-eval
                                 eshell-current-command))))))
-           (if (eshell-processp proc)
-               (ignore (setq eshell-last-async-proc proc))
-             (cadr retval)))))
+           (if (eshell-process-pair-p procs)
+               (ignore (setq eshell-last-async-procs procs))
+             (cadr retval)))))
     (error
      (error (error-message-string err)))))
 
@@ -1172,17 +1193,16 @@ be finished later after the completion of an 
asynchronous subprocess."
                    (setcar form (car new-form))
                    (setcdr form (cdr new-form)))
                  (eshell-do-eval form synchronous-p))
-             (if (and (memq (car form) eshell-deferrable-commands)
-                      (not eshell-current-subjob-p)
-                      result
-                      (eshell-processp result))
-                 (if synchronous-p
-                     (eshell/wait result)
+              (if-let (((memq (car form) eshell-deferrable-commands))
+                       ((not eshell-current-subjob-p))
+                       (procs (eshell-make-process-pair result)))
+                  (if synchronous-p
+                     (eshell/wait (cdr procs))
                    (eshell-manipulate "inserting ignore form"
                      (setcar form 'ignore)
                      (setcdr form nil))
-                   (throw 'eshell-defer result))
-               (list 'quote result))))))))))))
+                   (throw 'eshell-defer procs))
+                (list 'quote result))))))))))))
 
 ;; command invocation
 
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index 2e0f312f4a..8e6463eac2 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -485,7 +485,7 @@ Returns what was actually sent, or nil if nothing was sent."
    ((eshell-processp target)
     (when (eq (process-status target) 'run)
       (unless (stringp object)
-       (setq object (eshell-stringify object)))
+       (setq object (eshell-stringify object)))
       (process-send-string target object)))
 
    ((consp target)
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index 8302eefe1e..59c8f8034f 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -423,13 +423,13 @@ and the hook `eshell-exit-hook'."
 (defun eshell-self-insert-command ()
   (interactive)
   (process-send-string
-   (eshell-interactive-process)
+   (eshell-head-process)
    (char-to-string (if (symbolp last-command-event)
                       (get last-command-event 'ascii-character)
                     last-command-event))))
 
 (defun eshell-intercept-commands ()
-  (when (and (eshell-interactive-process)
+  (when (and (eshell-interactive-process-p)
             (not (and (integerp last-input-event)
                       (memq last-input-event '(?\C-x ?\C-c)))))
     (let ((possible-events (where-is-internal this-command))
@@ -595,13 +595,13 @@ If NO-NEWLINE is non-nil, the input is sent without an 
implied final
 newline."
   (interactive "P")
   ;; Note that the input string does not include its terminal newline.
-  (let ((proc-running-p (and (eshell-interactive-process)
+  (let ((proc-running-p (and (eshell-head-process)
                             (not queue-p)))
        (inhibit-point-motion-hooks t)
        (inhibit-modification-hooks t))
     (unless (and proc-running-p
                 (not (eq (process-status
-                          (eshell-interactive-process))
+                          (eshell-head-process))
                           'run)))
       (if (or proc-running-p
              (>= (point) eshell-last-output-end))
@@ -627,8 +627,8 @@ newline."
            (if (or eshell-send-direct-to-subprocesses
                    (= eshell-last-input-start eshell-last-input-end))
                (unless no-newline
-                 (process-send-string (eshell-interactive-process) "\n"))
-             (process-send-region (eshell-interactive-process)
+                 (process-send-string (eshell-head-process) "\n"))
+             (process-send-region (eshell-head-process)
                                   eshell-last-input-start
                                   eshell-last-input-end)))
        (if (= eshell-last-output-end (point))
@@ -665,6 +665,16 @@ newline."
               (run-hooks 'eshell-post-command-hook)
               (insert-and-inherit input)))))))))
 
+(defun eshell-send-eof-to-process ()
+  "Send EOF to the currently-running \"head\" process."
+  (interactive)
+  (require 'esh-mode)
+  (declare-function eshell-send-input "esh-mode"
+                    (&optional use-region queue-p no-newline))
+  (eshell-send-input nil nil t)
+  (when (eshell-head-process)
+    (process-send-eof (eshell-head-process))))
+
 (defsubst eshell-kill-new ()
   "Add the last input text to the kill ring."
   (kill-ring-save eshell-last-input-start eshell-last-input-end))
@@ -924,9 +934,9 @@ Then send it to the process running in the current buffer."
   (interactive) ; Don't pass str as argument, to avoid snooping via C-x ESC ESC
   (let ((str (read-passwd
              (format "%s Password: "
-                     (process-name (eshell-interactive-process))))))
+                     (process-name (eshell-head-process))))))
     (if (stringp str)
-       (process-send-string (eshell-interactive-process)
+       (process-send-string (eshell-head-process)
                             (concat str "\n"))
       (message "Warning: text will be echoed"))))
 
@@ -937,7 +947,7 @@ buffer's process if STRING contains a password prompt 
defined by
 `eshell-password-prompt-regexp'.
 
 This function could be in the list `eshell-output-filter-functions'."
-  (when (eshell-interactive-process)
+  (when (eshell-interactive-process-p)
     (save-excursion
       (let ((case-fold-search t))
        (goto-char eshell-last-output-block-begin)
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 5ed692fb5a..bb2136c06c 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -101,6 +101,8 @@ information, for example."
 (defvar eshell-process-list nil
   "A list of the current status of subprocesses.")
 
+(declare-function eshell-send-eof-to-process "esh-mode")
+
 (defvar-keymap eshell-proc-mode-map
   "C-c M-i"  #'eshell-insert-process
   "C-c C-c"  #'eshell-interrupt-process
@@ -542,14 +544,5 @@ See the variable `eshell-kill-processes-on-exit'."
 ;    ;; `eshell-resume-eval'.
 ;    (eshell-kill-process-function nil "continue")))
 
-(defun eshell-send-eof-to-process ()
-  "Send EOF to process."
-  (interactive)
-  (require 'esh-mode)
-  (declare-function eshell-send-input "esh-mode"
-                    (&optional use-region queue-p no-newline))
-  (eshell-send-input nil nil t)
-  (eshell-process-interact 'process-send-eof))
-
 (provide 'esh-proc)
 ;;; esh-proc.el ends here
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 0e04dbc7c9..788404fc43 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -609,6 +609,20 @@ gid format.  Valid values are `string' and `integer', 
defaulting to
   "If the `processp' function does not exist, PROC is not a process."
   (and (fboundp 'processp) (processp proc)))
 
+(defun eshell-process-pair-p (procs)
+  "Return non-nil if PROCS is a pair of process objects."
+  (and (consp procs)
+       (eshell-processp (car procs))
+       (eshell-processp (cdr procs))))
+
+(defun eshell-make-process-pair (procs)
+  "Make a pair of process objects from PROCS if possible.
+This represents the head and tail of a pipeline of processes,
+where the head and tail may be the same process."
+  (pcase procs
+    ((pred eshell-processp) (cons procs procs))
+    ((pred eshell-process-pair-p) procs)))
+
 ;; (defun eshell-copy-file
 ;;   (file newname &optional ok-if-already-exists keep-date)
 ;;   "Copy FILE to NEWNAME.  See docs for `copy-file'."
diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el
index 5c356e8928..2c472a2afa 100644
--- a/lisp/eshell/eshell.el
+++ b/lisp/eshell/eshell.el
@@ -332,9 +332,9 @@ With prefix ARG, insert output into the current buffer at 
point."
        ;; make the output as attractive as possible, with no
        ;; extraneous newlines
        (when intr
-         (if (eshell-interactive-process)
-             (eshell-wait-for-process (eshell-interactive-process)))
-         (cl-assert (not (eshell-interactive-process)))
+         (if (eshell-interactive-process-p)
+             (eshell-wait-for-process (eshell-tail-process)))
+         (cl-assert (not (eshell-interactive-process-p)))
          (goto-char (point-max))
          (while (and (bolp) (not (bobp)))
            (delete-char -1)))
diff --git a/lisp/files.el b/lisp/files.el
index 11cb4d4dcc..a998608208 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4061,7 +4061,8 @@ It is safe if any of these conditions are met:
         (and (functionp safep)
              ;; If the function signals an error, that means it
              ;; can't assure us that the value is safe.
-             (with-demoted-errors (funcall safep val))))))
+             (with-demoted-errors "Local variable error: %S"
+               (funcall safep val))))))
 
 (defun risky-local-variable-p (sym &optional _ignored)
   "Non-nil if SYM could be dangerous as a file-local variable.
@@ -4937,7 +4938,7 @@ BACKUPNAME is the backup file name, which is the old file 
renamed."
        nil)))
   ;; If set-file-extended-attributes fails, fall back on set-file-modes.
   (unless (and extended-attributes
-              (with-demoted-errors
+              (with-demoted-errors "Error setting attributes: %S"
                 (set-file-extended-attributes to-name extended-attributes)))
     (and modes
         (set-file-modes to-name (logand modes #o1777) nofollow-flag)))))
@@ -5559,7 +5560,8 @@ Before and after saving the buffer, this function runs
                     (goto-char (point-max))
                     (insert ?\n))))
            ;; Don't let errors prevent saving the buffer.
-           (with-demoted-errors (run-hooks 'before-save-hook))
+           (with-demoted-errors "Before-save hook error: %S"
+             (run-hooks 'before-save-hook))
             ;; Give `write-contents-functions' a chance to
             ;; short-circuit the whole process.
            (unless (run-hook-with-args-until-success 'write-contents-functions)
@@ -5607,7 +5609,7 @@ Before and after saving the buffer, this function runs
                  (condition-case ()
                      (progn
                        (unless
-                           (with-demoted-errors
+                           (with-demoted-errors "Error setting file modes: %S"
                                (set-file-modes buffer-file-name (car 
setmodes)))
                          (set-file-extended-attributes buffer-file-name
                                                        (nth 1 setmodes))))
@@ -5722,7 +5724,7 @@ Before and after saving the buffer, this function runs
               ;; If set-file-extended-attributes fails, fall back on
               ;; set-file-modes.
               (unless
-                  (with-demoted-errors
+                  (with-demoted-errors "Error setting attributes: %s"
                     (set-file-extended-attributes buffer-file-name
                                                   (nth 1 setmodes)))
                 (set-file-modes buffer-file-name
diff --git a/lisp/finder.el b/lisp/finder.el
index 5a6fe45192..a40f8c64f2 100644
--- a/lisp/finder.el
+++ b/lisp/finder.el
@@ -454,7 +454,8 @@ Quit the window and kill all Finder-related buffers."
 
 (defun finder-unload-function ()
   "Unload the Finder library."
-  (with-demoted-errors (unload-feature 'finder-inf t))
+  (with-demoted-errors "Error unloading finder: %S"
+    (unload-feature 'finder-inf t))
   ;; continue standard unloading
   nil)
 
diff --git a/lisp/frame.el b/lisp/frame.el
index 13f82ea4c7..6bf4c6178b 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -799,7 +799,7 @@ also select the new frame."
                     (window-state-get (frame-root-window frame))))
          (default-frame-alist
           (seq-remove (lambda (elem)
-                        (memq (car elem) '(name parent-id)))
+                        (memq (car elem) frame-internal-parameters))
                       (frame-parameters frame)))
          (new-frame (make-frame)))
     (when windows
@@ -1590,6 +1590,11 @@ acquires focus to be automatically raised.
 Note that this minor mode controls Emacs's own auto-raise
 feature.  Window managers that switch focus on mouse movement
 often have their own auto-raise feature."
+  ;; This isn't really a global minor mode; rather, it's local to the
+  ;; selected frame, but declaring it as global prevents a misleading
+  ;; "Auto-Raise mode enabled in current buffer" message from being
+  ;; displayed when it is turned on.
+  :global t
   :variable (frame-parameter nil 'auto-raise)
   (if (frame-parameter nil 'auto-raise)
       (raise-frame)))
@@ -2530,31 +2535,29 @@ deleting them."
         (if iconify (iconify-frame this) (delete-frame this)))
       (setq this next))))
 
-(eval-when-compile (require 'frameset))
-
 (defvar undelete-frame--deleted-frames nil
-  "Internal variable used by `undelete-frame--handle-delete-frame'.")
+  "Internal variable used by `undelete-frame--save-deleted-frame'.")
 
-(defun undelete-frame--handle-delete-frame (frame)
+(defun undelete-frame--save-deleted-frame (frame)
   "Save the configuration of frames deleted with `delete-frame'.
 Only the 16 most recently deleted frames are saved."
-  (when (frame-live-p frame)
+  (when (and after-init-time (frame-live-p frame))
     (setq undelete-frame--deleted-frames
           (cons
-           (cons
+           (list
             (display-graphic-p)
-            (frameset-save
-             (list frame)
-             ;; When the daemon is started from a graphical
-             ;; environment, TTY frames have a 'display' parameter set
-             ;; to the value of $DISPLAY (see the note in
-             ;; `server--on-display-p').  Do not store that parameter
-             ;; in the frameset, otherwise `frameset-restore' attempts
-             ;; to restore a graphical frame.
-             :filters (if (display-graphic-p)
-                          frameset-filter-alist
-                        (cons '(display . :never)
-                              frameset-filter-alist))))
+            (seq-remove
+             (lambda (elem)
+               (or (memq (car elem) frame-internal-parameters)
+                   ;; When the daemon is started from a graphical
+                   ;; environment, TTY frames have a 'display' parameter set
+                   ;; to the value of $DISPLAY (see the note in
+                   ;; `server--on-display-p').  Do not store that parameter
+                   ;; in the frame data, otherwise `undelete-frame' attempts
+                   ;; to restore a graphical frame.
+                   (and (eq (car elem) 'display) (not (display-graphic-p)))))
+             (frame-parameters frame))
+            (window-state-get (frame-root-window frame)))
            undelete-frame--deleted-frames))
     (if (> (length undelete-frame--deleted-frames) 16)
         (setq undelete-frame--deleted-frames
@@ -2566,9 +2569,9 @@ Only the 16 most recently deleted frames are saved."
   :global t
   (if undelete-frame-mode
       (add-hook 'delete-frame-functions
-                #'undelete-frame--handle-delete-frame -75)
+                #'undelete-frame--save-deleted-frame -75)
     (remove-hook 'delete-frame-functions
-                 #'undelete-frame--handle-delete-frame)
+                 #'undelete-frame--save-deleted-frame)
     (setq undelete-frame--deleted-frames nil)))
 
 (defun undelete-frame (&optional arg)
@@ -2584,26 +2587,25 @@ When called from Lisp, returns the new frame."
     (if (consp arg)
         (user-error "Missing deleted frame number argument")
       (let* ((number (pcase arg ('nil 1) ('- -1) (_ arg)))
-             (frames (frame-list))
-             (frameset (nth (1- number) undelete-frame--deleted-frames))
+             (frame-data (nth (1- number) undelete-frame--deleted-frames))
              (graphic (display-graphic-p)))
         (if (not (<= 1 number 16))
             (user-error "%d is not a valid deleted frame number argument"
                         number)
-          (if (not frameset)
+          (if (not frame-data)
               (user-error "No deleted frame with number %d" number)
-            (if (not (eq graphic (car frameset)))
+            (if (not (eq graphic (nth 0 frame-data)))
                 (user-error
                  "Cannot undelete a %s display frame on a %s display"
                  (if graphic "non-graphic" "graphic")
                  (if graphic "graphic" "non-graphic"))
               (setq undelete-frame--deleted-frames
-                    (delq frameset undelete-frame--deleted-frames))
-              (frameset-restore (cdr frameset))
-              (let ((frame (car (seq-difference (frame-list) frames))))
-                (when frame
-                  (select-frame-set-input-focus frame)
-                  frame)))))))))
+                    (delq frame-data undelete-frame--deleted-frames))
+              (let* ((default-frame-alist (nth 1 frame-data))
+                     (frame (make-frame)))
+                (window-state-put (nth 2 frame-data) (frame-root-window frame) 
'safe)
+                (select-frame-set-input-focus frame)
+                frame))))))))
 
 ;;; Window dividers.
 (defgroup window-divider nil
diff --git a/lisp/frameset.el b/lisp/frameset.el
index 10714af1fa..05884eed3a 100644
--- a/lisp/frameset.el
+++ b/lisp/frameset.el
@@ -436,10 +436,11 @@ Properties can be set with
 
 ;;;###autoload
 (defvar frameset-session-filter-alist
-  '((name            . :never)
-    (left            . frameset-filter-iconified)
-    (minibuffer      . frameset-filter-minibuffer)
-    (top             . frameset-filter-iconified))
+  (append
+   '((left            . frameset-filter-iconified)
+     (minibuffer      . frameset-filter-minibuffer)
+     (top             . frameset-filter-iconified))
+   (mapcar (lambda (p) (cons p :never)) frame-internal-parameters))
   "Minimum set of parameters to filter for live (on-session) framesets.
 DO NOT MODIFY.  See `frameset-filter-alist' for a full description.")
 
@@ -468,14 +469,11 @@ DO NOT MODIFY.  See `frameset-filter-alist' for a full 
description.")
      (GUI:height                  . frameset-filter-unshelve-param)
      (GUI:width                   . frameset-filter-unshelve-param)
      (height                      . frameset-filter-shelve-param)
-     (outer-window-id             . :never)
      (parent-frame                . :never)
-     (parent-id                   . :never)
      (mouse-wheel-frame           . :never)
      (tty                         . frameset-filter-tty-to-GUI)
      (tty-type                    . frameset-filter-tty-to-GUI)
      (width                       . frameset-filter-shelve-param)
-     (window-id                   . :never)
      (window-system               . :never))
    frameset-session-filter-alist)
   "Parameters to filter for persistent framesets.
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 08e1a6f93e..59c3bbc76e 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -2659,7 +2659,8 @@ If PROMPT (the prefix), prompt for a coding system to 
use."
   (dolist (header (mail-header-parse-addresses addresses t))
     (when-let* ((address (car (ignore-errors
                                 (mail-header-parse-address header))))
-                (warning (textsec-suspicious-p address 'email-address)))
+                (warning (and (string-match "@" address)
+                              (textsec-suspicious-p address 'email-address))))
       (goto-char (point-min))
       (while (search-forward address nil t)
         (put-text-property (match-beginning 0) (match-end 0)
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index d3a94e9f4e..8937df2601 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -3135,9 +3135,9 @@ If SOLID (the prefix), create a solid group."
             (if (derived-mode-p 'gnus-summary-mode) 'summary 'group))))))
 
 (defvar nnrss-group-alist)
-(eval-when-compile
-  (defun nnrss-discover-feed (_arg))
-  (defun nnrss-save-server-data (_arg)))
+(declare-function nnrss-discover-feed "nnrss" (url))
+(declare-function nnrss-save-server-data "nnrss" (server))
+
 (defun gnus-group-make-rss-group (&optional url)
   "Given a URL, discover if there is an RSS feed.
 If there is, use Gnus to create an nnrss group"
diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el
index 754a1d91cb..1bffdf3513 100644
--- a/lisp/gnus/gnus-icalendar.el
+++ b/lisp/gnus/gnus-icalendar.el
@@ -830,11 +830,12 @@ These will be used to retrieve the RSVP information from 
ical events."
 (defmacro gnus-icalendar-with-decoded-handle (handle &rest body)
   "Execute BODY in buffer containing the decoded contents of HANDLE."
   (let ((charset (make-symbol "charset")))
-    `(let ((,charset (cdr (assoc 'charset (mm-handle-type ,handle)))))
+    `(let ((,charset (downcase
+                     (or (cdr (assoc 'charset (mm-handle-type ,handle)))
+                         "utf-8"))))
        (with-temp-buffer
          (mm-insert-part ,handle)
-         (when (and ,charset (string= (downcase ,charset) "utf-8"))
-           (decode-coding-region (point-min) (point-max) 'utf-8))
+         (decode-coding-region (point-min) (point-max) (intern ,charset))
          ,@body))))
 
 
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el
index ccdaabe3c6..8cefb09b66 100644
--- a/lisp/gnus/gnus-registry.el
+++ b/lisp/gnus/gnus-registry.el
@@ -163,7 +163,9 @@ nnmairix groups are specifically excluded because they are 
ephemeral."
   :type 'boolean
   :version "28.1")
 
-(defvar gnus-registry-enabled nil)
+(make-obsolete-variable
+ 'gnus-registry-enabled
+ "Check for non-nil value of `gnus-registry-db'" "29.1")
 
 (defvar gnus-summary-misc-menu) ;; Avoid byte compiler warning.
 
@@ -360,8 +362,7 @@ This is not required after changing 
`gnus-registry-cache-file'."
         (progn
           (gnus-registry-read file)
           (gnus-registry-install-hooks)
-          (gnus-registry-install-shortcuts)
-          (setq gnus-registry-enabled t))
+          (gnus-registry-install-shortcuts))
       (file-error
        ;; Fix previous mis-naming of the registry file.
        (let ((old-file-name
@@ -851,7 +852,7 @@ Overrides existing keywords with FORCE set non-nil."
 
 (defun gnus-registry-register-message-ids ()
   "Register the Message-ID of every article in the group."
-  (unless (or (null gnus-registry-enabled)
+  (unless (or (null gnus-registry-db)
               (null gnus-registry-register-all)
              (gnus-parameter-registry-ignore gnus-newsgroup-name))
     (dolist (article gnus-newsgroup-articles)
@@ -1010,7 +1011,7 @@ Uses `gnus-registry-marks' to find what shortcuts to 
install."
 ;; (defalias 'gnus-user-format-function-M 
#'gnus-registry-article-marks-to-chars)
 (defun gnus-registry-article-marks-to-chars (headers)
   "Show the marks for an article by the :char property."
-  (if gnus-registry-enabled
+  (if gnus-registry-db
       (let* ((id (mail-header-message-id headers))
              (marks (when id (gnus-registry-get-id-key id 'mark))))
        (concat (delq nil
@@ -1026,7 +1027,7 @@ Uses `gnus-registry-marks' to find what shortcuts to 
install."
 ;; (defalias 'gnus-user-format-function-M 
#'gnus-registry-article-marks-to-names)
 (defun gnus-registry-article-marks-to-names (headers)
   "Show the marks for an article by name."
-  (if gnus-registry-enabled
+  (if gnus-registry-db
       (let* ((id (mail-header-message-id headers))
              (marks (when id (gnus-registry-get-id-key id 'mark))))
        (mapconcat #'symbol-name marks ","))
@@ -1177,8 +1178,7 @@ non-nil."
 (defun gnus-registry-clear ()
   "Clear the registry."
   (gnus-registry-unload-hook)
-  (setq gnus-registry-db nil
-        gnus-registry-enabled nil))
+  (setq gnus-registry-db nil))
 
 (gnus-add-shutdown 'gnus-registry-clear 'gnus)
 
@@ -1220,7 +1220,7 @@ non-nil."
 If the registry is not already enabled, then if `gnus-registry-install'
 is `ask', ask the user; or if `gnus-registry-install' is non-nil, enable it."
   (interactive)
-  (unless gnus-registry-enabled
+  (unless gnus-registry-db
     (when (if (eq gnus-registry-install 'ask)
               (gnus-y-or-n-p
                (concat "Enable the Gnus registry?  "
@@ -1228,7 +1228,7 @@ is `ask', ask the user; or if `gnus-registry-install' is 
non-nil, enable it."
                        "to get rid of this query permanently. "))
             gnus-registry-install)
       (gnus-registry-initialize)))
-  gnus-registry-enabled)
+  (null (null gnus-registry-db)))
 
 ;; largely based on nnselect-warp-to-article
 (defun gnus-try-warping-via-registry ()
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 2cf11fb12f..dd9c277805 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -2867,12 +2867,6 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'."
       (princ "(setq gnus-newsrc-file-version ")
       (princ (gnus-prin1-to-string gnus-version))
       (princ ")\n"))
-    ;; Sort `gnus-newsrc-alist' according to order in
-    ;; `gnus-group-list'.
-    (setq gnus-newsrc-alist
-         (mapcar (lambda (g)
-                   (nth 1 (gethash g gnus-newsrc-hashtb)))
-                 (delete "dummy.group" gnus-group-list)))
     (let* ((print-quoted t)
            (print-escape-multibyte nil)
            (print-escape-nonascii t)
@@ -2891,17 +2885,20 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'."
                  ;; Remove the `gnus-killed-list' from the list of variables
                  ;; to be saved, if required.
                  (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))))
-          ;; Encode group names in `gnus-newsrc-alist' and
-          ;; `gnus-topic-alist' in order to keep newsrc.eld files
-          ;; compatible with older versions of Gnus.  At some point,
-          ;; if/when a new version of Gnus is released, stop doing
-          ;; this and move the corresponding decode in
-          ;; `gnus-read-newsrc-el-file' into a conversion routine.
+           ;; Sort `gnus-newsrc-alist' according to order in
+           ;; `gnus-group-list'.  Encode group names in
+           ;; `gnus-newsrc-alist' and `gnus-topic-alist' in order to
+           ;; keep newsrc.eld files compatible with older versions of
+           ;; Gnus.  At some point, if/when a new version of Gnus is
+           ;; released, stop doing this and move the corresponding
+           ;; decode in `gnus-read-newsrc-el-file' into a conversion
+           ;; routine.
           (gnus-newsrc-alist
-           (mapcar (lambda (info)
-                     (cons (encode-coding-string (car info) 'utf-8-emacs)
-                           (cdr info)))
-                   gnus-newsrc-alist))
+           (mapcar (lambda (group)
+                     (cons (encode-coding-string group 'utf-8-emacs)
+                           (cdadr (gethash group
+                           gnus-newsrc-hashtb))))
+                   (remove "dummy.group" gnus-group-list)))
           (gnus-topic-alist
            (when (memq 'gnus-topic-alist variables)
             (mapcar (lambda (elt)
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index c40c38a95f..57ce36a944 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -519,17 +519,17 @@ If MODE is not set, try to find mode automatically."
         ;; setting now, but it seems harmless and potentially still useful.
        (setq-local font-lock-mode-hook nil)
         (setq buffer-file-name (mm-handle-filename handle))
-       (with-demoted-errors
-           (if mode
-                (save-window-excursion
-                  ;; According to Katsumi Yamaoka <yamaoka@jpl.org>, org-mode
-                  ;; requires the buffer to be temporarily displayed here, but
-                  ;; I could not reproduce this problem.  Furthermore, if
-                  ;; there's such a problem, we should fix org-mode rather than
-                  ;; use switch-to-buffer which can have undesirable
-                  ;; side-effects!
-                  ;;(switch-to-buffer (current-buffer))
-                 (funcall mode))
+       (with-demoted-errors "Error setting mode: %S"
+         (if mode
+              (save-window-excursion
+                ;; According to Katsumi Yamaoka <yamaoka@jpl.org>, org-mode
+                ;; requires the buffer to be temporarily displayed here, but
+                ;; I could not reproduce this problem.  Furthermore, if
+                ;; there's such a problem, we should fix org-mode rather than
+                ;; use switch-to-buffer which can have undesirable
+                ;; side-effects!
+                ;;(switch-to-buffer (current-buffer))
+               (funcall mode))
            (let ((auto-mode-alist
                   (delq (rassq 'doc-view-mode-maybe auto-mode-alist)
                         (copy-sequence auto-mode-alist))))
diff --git a/lisp/gnus/nnregistry.el b/lisp/gnus/nnregistry.el
index d042981ca9..4a799acad9 100644
--- a/lisp/gnus/nnregistry.el
+++ b/lisp/gnus/nnregistry.el
@@ -36,7 +36,7 @@
 (nnoo-declare nnregistry)
 
 (deffoo nnregistry-server-opened (_server)
-  gnus-registry-enabled)
+  gnus-registry-db)
 
 (deffoo nnregistry-close-server (_server &optional _defs)
   t)
@@ -45,7 +45,7 @@
   nil)
 
 (deffoo nnregistry-open-server (_server &optional _defs)
-  gnus-registry-enabled)
+  gnus-registry-db)
 
 (defvar nnregistry-within-nnregistry nil)
 
diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el
index 205456a57d..85df0284ef 100644
--- a/lisp/gnus/nnselect.el
+++ b/lisp/gnus/nnselect.el
@@ -79,30 +79,33 @@
 ;;; Helper routines.
 (defun nnselect-compress-artlist (artlist)
   "Compress ARTLIST."
-  (let (selection)
-    (pcase-dolist (`(,artgroup . ,arts)
-                   (nnselect-categorize artlist #'nnselect-artitem-group))
-      (let (list)
-        (pcase-dolist (`(,rsv . ,articles)
-                       (nnselect-categorize
-                        arts #'nnselect-artitem-rsv #'nnselect-artitem-number))
-          (push (cons rsv (gnus-compress-sequence (sort articles #'<)))
-                list))
-        (push (cons artgroup list) selection)))
-    selection))
+  (if (consp artlist)
+      artlist
+    (let (selection)
+      (pcase-dolist (`(,artgroup . ,arts)
+                     (nnselect-categorize artlist #'nnselect-artitem-group))
+       (let (list)
+          (pcase-dolist (`(,rsv . ,articles)
+                        (nnselect-categorize
+                          arts #'nnselect-artitem-rsv 
#'nnselect-artitem-number))
+            (push (cons rsv (gnus-compress-sequence (sort articles #'<)))
+                  list))
+          (push (cons artgroup list) selection)))
+      selection)))
 
 (defun nnselect-uncompress-artlist (artlist)
   "Uncompress ARTLIST."
   (if (vectorp artlist)
       artlist
     (let (selection)
-      (pcase-dolist (`(,artgroup (,artrsv . ,artseq)) artlist)
-       (setq selection
-             (vconcat
-              (cl-map 'vector
-                       (lambda (art)
-                         (vector artgroup art artrsv))
-                   (gnus-uncompress-sequence artseq)) selection)))
+      (pcase-dolist (`(,artgroup . ,list) artlist)
+       (pcase-dolist (`(,artrsv . ,artseq) list)
+         (setq selection
+               (vconcat
+                (cl-map 'vector
+                        (lambda (art)
+                           (vector artgroup art artrsv))
+                        (gnus-uncompress-sequence artseq)) selection))))
       selection)))
 
 (make-obsolete 'nnselect-group-server 'gnus-group-server "28.1")
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 98a1b11e08..36c7966919 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -33,6 +33,7 @@
 ;;; Code:
 
 (require 'cl-lib)
+(require 'seq)
 (require 'help-mode)
 (require 'radix-tree)
 (eval-when-compile (require 'subr-x))   ;For when-let.
@@ -678,19 +679,9 @@ suitable file is found, return nil."
     (terpri)))
 
 ;; We could use `symbol-file' but this is a wee bit more efficient.
-(defun help-fns--autoloaded-p (function file)
-  "Return non-nil if FUNCTION has previously been autoloaded.
-FILE is the file where FUNCTION was probably defined."
-  (let* ((file (file-name-sans-extension (file-truename file)))
-        (load-hist load-history)
-        (target (cons t function))
-        found)
-    (while (and load-hist (not found))
-      (and (stringp (caar load-hist))
-          (equal (file-name-sans-extension (caar load-hist)) file)
-          (setq found (member target (cdar load-hist))))
-      (setq load-hist (cdr load-hist)))
-    found))
+(defun help-fns--autoloaded-p (function)
+  "Return non-nil if FUNCTION has previously been autoloaded."
+  (seq-some #'autoloadp (get function 'function-history)))
 
 (defun help-fns--interactive-only (function)
   "Insert some help blurb if FUNCTION should only be used interactively."
@@ -873,13 +864,13 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED 
REAL-DEF)."
   "Print a line describing FUNCTION to `standard-output'."
   (pcase-let* ((`(,_real-function ,def ,aliased ,real-def)
                 (help-fns--analyze-function function))
-               (file-name (find-lisp-object-file-name function (if aliased 
'defun
-                                                                 def)))
+               (file-name (find-lisp-object-file-name
+                           function (if aliased 'defun def)))
                (beg (if (and (or (byte-code-function-p def)
                                  (keymapp def)
                                  (memq (car-safe def) '(macro lambda closure)))
                              (stringp file-name)
-                             (help-fns--autoloaded-p function file-name))
+                             (help-fns--autoloaded-p function))
                         (concat
                          "an autoloaded " (if (commandp def)
                                               "interactive "))
diff --git a/lisp/help.el b/lisp/help.el
index c3aae4acdd..8d90ce744e 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -907,6 +907,12 @@ While reading KEY-LIST interactively, this command 
temporarily enables
 menu items or tool-bar buttons that are disabled to allow getting help
 on them.
 
+Interactively, this command can't describe prefix commands, but
+will always wait for the user to type the complete key sequence.
+For instance, entering \"C-x\" will wait until the command has
+been completed, but `M-: (describe-key (kbd \"C-x\")) RET' will
+tell you what this prefix command is bound to.
+
 BUFFER is the buffer in which to lookup those keys; it defaults to the
 current buffer."
   (declare (advertised-calling-convention (key-list &optional buffer) "27.1"))
diff --git a/lisp/image.el b/lisp/image.el
index 80815a8a66..ec4ee06eb1 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -171,18 +171,16 @@ or \"ffmpeg\") is installed."
 
 (define-error 'unknown-image-type "Unknown image type")
 
-;; Map put into text properties on images.
-(defvar image-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "-" 'image-decrease-size)
-    (define-key map "+" 'image-increase-size)
-    (define-key map [C-wheel-down] 'image-mouse-decrease-size)
-    (define-key map [C-mouse-5]    'image-mouse-decrease-size)
-    (define-key map [C-wheel-up]   'image-mouse-increase-size)
-    (define-key map [C-mouse-4]    'image-mouse-increase-size)
-    (define-key map "r" 'image-rotate)
-    (define-key map "o" 'image-save)
-    map))
+(defvar-keymap image-map
+  :doc "Map put into text properties on images."
+  "-" #'image-decrease-size
+  "+" #'image-increase-size
+  "r" #'image-rotate
+  "o" #'image-save
+  "C-<wheel-down>" #'image-mouse-decrease-size
+  "C-<mouse-5>"    #'image-mouse-decrease-size
+  "C-<wheel-up>"   #'image-mouse-increase-size
+  "C-<mouse-4>"    #'image-mouse-increase-size)
 
 (defun image-load-path-for-library (library image &optional path no-error)
   "Return a suitable search path for images used by LIBRARY.
diff --git a/lisp/international/latin1-disp.el 
b/lisp/international/latin1-disp.el
index c8ff93aeb2..7054077fb0 100644
--- a/lisp/international/latin1-disp.el
+++ b/lisp/international/latin1-disp.el
@@ -1,4 +1,4 @@
-;;; latin1-disp.el --- display tables for other ISO 8859 on Latin-1 terminals 
-*- lexical-binding: t; -*-
+;;; latin1-disp.el --- display tables for non-ASCII on Latin-1 terminals -*- 
lexical-binding: t; -*-
 
 ;; Copyright (C) 2000-2022 Free Software Foundation, Inc.
 
@@ -22,18 +22,23 @@
 
 ;;; Commentary:
 
-;; This package sets up display of ISO 8859-n for n>1 by substituting
-;; Latin-1 characters and sequences of them for characters which can't
-;; be displayed, either because we're on a tty or because we don't
-;; have the relevant window system fonts available.  For instance,
-;; Latin-9 is very similar to Latin-1, so we can display most Latin-9
-;; characters using the Latin-1 characters at the same code point and
-;; fall back on more-or-less mnemonic ASCII sequences for the rest.
+;; This package sets up display of many non-ASCII characters by
+;; substituting ASCII and Latin-1 characters and sequences of them for
+;; characters which can't be displayed, either because we're on a tty
+;; or because we don't have the relevant window system fonts
+;; available.  For instance, Latin-9 is very similar to Latin-1, so we
+;; can display most Latin-9 characters using the Latin-1 characters at
+;; the same code point and fall back on more-or-less mnemonic ASCII
+;; sequences for the rest.
 
 ;; For the Latin charsets the ASCII sequences are mostly consistent
 ;; with the Quail prefix input sequences.  Latin-4 uses the Quail
 ;; postfix sequences since a prefix method isn't defined for Latin-4.
 
+;; Non-Latin non-ASCII characters are generally displayed as ASCII
+;; strings remotely reminiscent of the original characters, as best as
+;; possible.  See `latin1-display-ucs-per-lynx'.
+
 ;; [A different approach is taken in the DOS display tables in
 ;; term/internal.el, and the relevant ASCII sequences from there are
 ;; available as an alternative; see `latin1-display-mnemonic'.  Only
@@ -759,2426 +764,2425 @@ turn it off and display Unicode characters literally. 
 The display
 isn't changed if the display can render Unicode characters."
   (interactive "p")
   (if (> arg 0)
-      (unless (char-displayable-p #x101) ; a with macron
-       ;; It doesn't look as though we have a Unicode font.
-       (let ((latin1-display-format "%s"))
-         (mapc
-          (lambda (l)
-            (apply 'latin1-display-char l))
-          ;; Table derived by running Lynx on a suitable list of
-          ;; characters in a utf-8 file, except for some added by
-          ;; hand at the end.
-          '((?\Ā "A")
-            (?\ā "a")
-            (?\Ă "A")
-            (?\ă "a")
-            (?\Ą "A")
-            (?\ą "a")
-            (?\Ć "C")
-            (?\ć "c")
-            (?\Ĉ "C")
-            (?\ĉ "c")
-            (?\Ċ "C")
-            (?\ċ "c")
-            (?\Č "C")
-            (?\č "c")
-            (?\Ď "D")
-            (?\ď "d")
-            (?\Đ "Ð")
-            (?\đ "d/")
-            (?\Ē "E")
-            (?\ē "e")
-            (?\Ĕ "E")
-            (?\ĕ "e")
-            (?\Ė "E")
-            (?\ė "e")
-            (?\Ę "E")
-            (?\ę "e")
-            (?\Ě "E")
-            (?\ě "e")
-            (?\Ĝ "G")
-            (?\ĝ "g")
-            (?\Ğ "G")
-            (?\ğ "g")
-            (?\Ġ "G")
-            (?\ġ "g")
-            (?\Ģ "G")
-            (?\ģ "g")
-            (?\Ĥ "H")
-            (?\ĥ "h")
-            (?\Ħ "H/")
-            (?\ħ "H")
-            (?\Ĩ "I")
-            (?\ĩ "i")
-            (?\Ī "I")
-            (?\ī "i")
-            (?\Ĭ "I")
-            (?\ĭ "i")
-            (?\Į "I")
-            (?\į "i")
-            (?\İ "I")
-            (?\ı "i")
-            (?\IJ "IJ")
-            (?\ij "ij")
-            (?\Ĵ "J")
-            (?\ĵ "j")
-            (?\Ķ "K")
-            (?\ķ "k")
-            (?\ĸ "kk")
-            (?\Ĺ "L")
-            (?\ĺ "l")
-            (?\Ļ "L")
-            (?\ļ "l")
-            (?\Ľ "L")
-            (?\ľ "l")
-            (?\Ŀ "L.")
-            (?\ŀ "l.")
-            (?\Ł "L/")
-            (?\ł "l/")
-            (?\Ń "N")
-            (?\ń "n")
-            (?\Ņ "N")
-            (?\ņ "n")
-            (?\Ň "N")
-            (?\ň "n")
-            (?\ʼn "'n")
-            (?\Ŋ "NG")
-            (?\ŋ "N")
-            (?\Ō "O")
-            (?\ō "o")
-            (?\Ŏ "O")
-            (?\ŏ "o")
-            (?\Ő "O\"")
-            (?\ő "o\"")
-            (?\Π"OE")
-            (?\œ "oe")
-            (?\Ŕ "R")
-            (?\ŕ "r")
-            (?\Ŗ "R")
-            (?\ŗ "r")
-            (?\Ř "R")
-            (?\ř "r")
-            (?\Ś "S")
-            (?\ś "s")
-            (?\Ŝ "S")
-            (?\ŝ "s")
-            (?\Ş "S")
-            (?\ş "s")
-            (?\Š "S")
-            (?\š "s")
-            (?\Ţ "T")
-            (?\ţ "t")
-            (?\Ť "T")
-            (?\ť "t")
-            (?\Ŧ "T/")
-            (?\ŧ "t/")
-            (?\Ũ "U")
-            (?\ũ "u")
-            (?\Ū "U")
-            (?\ū "u")
-            (?\Ŭ "U")
-            (?\ŭ "u")
-            (?\Ů "U")
-            (?\ů "u")
-            (?\Ű "U\"")
-            (?\ű "u\"")
-            (?\Ų "U")
-            (?\ų "u")
-            (?\Ŵ "W")
-            (?\ŵ "w")
-            (?\Ŷ "Y")
-            (?\ŷ "y")
-            (?\Ÿ "Y")
-            (?\Ź "Z")
-            (?\ź "z")
-            (?\Ż "Z")
-            (?\ż "z")
-            (?\Ž "Z")
-            (?\ž "z")
-            (?\ſ "s1")
-            (?\Ƈ "C2")
-            (?\ƈ "c2")
-            (?\Ƒ "F2")
-            (?\ƒ " f")
-            (?\Ƙ "K2")
-            (?\ƙ "k2")
-            (?\Ơ "O9")
-            (?\ơ "o9")
-            (?\Ƣ "OI")
-            (?\ƣ "oi")
-            (?\Ʀ "yr")
-            (?\Ư "U9")
-            (?\ư "u9")
-            (?\Ƶ "Z/")
-            (?\ƶ "z/")
-            (?\Ʒ "ED")
-            (?\Ǎ "A")
-            (?\ǎ "a")
-            (?\Ǐ "I")
-            (?\ǐ "i")
-            (?\Ǒ "O")
-            (?\ǒ "o")
-            (?\Ǔ "U")
-            (?\ǔ "u")
-            (?\Ǖ "U:-")
-            (?\ǖ "u:-")
-            (?\Ǘ "U:'")
-            (?\ǘ "u:'")
-            (?\Ǚ "U:<")
-            (?\ǚ "u:<")
-            (?\Ǜ "U:!")
-            (?\ǜ "u:!")
-            (?\Ǟ "A1")
-            (?\ǟ "a1")
-            (?\Ǡ "A7")
-            (?\ǡ "a7")
-            (?\Ǣ "A3")
-            (?\ǣ "a3")
-            (?\Ǥ "G/")
-            (?\ǥ "g/")
-            (?\Ǧ "G")
-            (?\ǧ "g")
-            (?\Ǩ "K")
-            (?\ǩ "k")
-            (?\Ǫ "O")
-            (?\ǫ "o")
-            (?\Ǭ "O1")
-            (?\ǭ "o1")
-            (?\Ǯ "EZ")
-            (?\ǯ "ez")
-            (?\ǰ "j")
-            (?\Ǵ "G")
-            (?\ǵ "g")
-            (?\Ǻ "AA'")
-            (?\ǻ "aa'")
-            (?\Ǽ "AE'")
-            (?\ǽ "ae'")
-            (?\Ǿ "O/'")
-            (?\ǿ "o/'")
-            (?\Ȁ "A!!")
-            (?\ȁ "a!!")
-            (?\Ȃ "A)")
-            (?\ȃ "a)")
-            (?\Ȅ "E!!")
-            (?\ȅ "e!!")
-            (?\Ȇ "E)")
-            (?\ȇ "e)")
-            (?\Ȉ "I!!")
-            (?\ȉ "i!!")
-            (?\Ȋ "I)")
-            (?\ȋ "i)")
-            (?\Ȍ "O!!")
-            (?\ȍ "o!!")
-            (?\Ȏ "O)")
-            (?\ȏ "o)")
-            (?\Ȑ "R!!")
-            (?\ȑ "r!!")
-            (?\Ȓ "R)")
-            (?\ȓ "r)")
-            (?\Ȕ "U!!")
-            (?\ȕ "u!!")
-            (?\Ȗ "U)")
-            (?\ȗ "u)")
-            (?\ȝ "Z")
-            (?\ɑ "A")
-            (?\ɒ "A.")
-            (?\ɓ "b`")
-            (?\ɔ "O")
-            (?\ɖ "d.")
-            (?\ɗ "d`")
-            (?\ɘ "@<umd>")
-            (?\ə "@")
-            (?\ɚ "R")
-            (?\ɛ "E")
-            (?\ɜ "V\"")
-            (?\ɝ "R<umd>")
-            (?\ɞ "O\"")
-            (?\ɟ "J")
-            (?\ɠ "g`")
-            (?\ɡ "g")
-            (?\ɢ "G")
-            (?\ɣ "Q")
-            (?\ɤ "o-")
-            (?\ɥ "j<rnd>")
-            (?\ɦ "h<?>")
-            (?\ɨ "i\"")
-            (?\ɩ "I")
-            (?\ɪ "I")
-            (?\ɫ "L")
-            (?\ɬ "L")
-            (?\ɭ "l.")
-            (?\ɮ "z<lat>")
-            (?\ɯ "u-")
-            (?\ɰ "j<vel>")
-            (?\ɱ "M")
-            (?\ɳ "n.")
-            (?\ɴ "n\"")
-            (?\ɵ "@.")
-            (?\ɶ "&.")
-            (?\ɷ "U")
-            (?\ɹ "r")
-            (?\ɺ "*<lat>")
-            (?\ɻ "r.")
-            (?\ɽ "*.")
-            (?\ɾ "*")
-            (?\ʀ "R")
-            (?\ʁ "g\"")
-            (?\ʂ "s.")
-            (?\ʃ "S")
-            (?\ʄ "J`")
-            (?\ʇ "t!")
-            (?\ʈ "t.")
-            (?\ʉ "u\"")
-            (?\ʊ "U")
-            (?\ʋ "r<lbd>")
-            (?\ʌ "V")
-            (?\ʍ "w<vls>")
-            (?\ʎ "l^")
-            (?\ʏ "I.")
-            (?\ʐ "z.")
-            (?\ʒ "Z")
-            (?\ʔ "?")
-            (?\ʕ "H<vcd>")
-            (?\ʖ "l!")
-            (?\ʗ "c!")
-            (?\ʘ "p!")
-            (?\ʙ "b<trl>")
-            (?\ʛ "G`")
-            (?\ʝ "j")
-            (?\ʞ "k!")
-            (?\ʟ "L")
-            (?\ʠ "q`")
-            (?\ʤ "d3")
-            (?\ʦ "ts")
-            (?\ʧ "tS")
-            (?\ʰ "<h>")
-            (?\ʱ "<?>")
-            (?\ʲ ";")
-            (?\ʳ "<r>")
-            (?\ʷ "<w>")
-            (?\ʻ ";S")
-            (?\ʼ "`")
-            (?\ˆ "^")
-            (?\ˇ "'<")
-            (?\ˈ "|")
-            (?\ˉ "1-")
-            (?\ˋ "1!")
-            (?\ː ":")
-            (?\ˑ ":\\")
-            (?\˖ "+")
-            (?\˗ "-")
-            (?\˘ "'(")
-            (?\˙ "'.")
-            (?\˚ "'0")
-            (?\˛ "';")
-            (?\˜ "~")
-            (?\˝ "'\"")
-            (?\˥ "_T")
-            (?\˦ "_H")
-            (?\˧ "_M")
-            (?\˨ "_L")
-            (?\˩ "_B")
-            (?\ˬ "_v")
-            (?\ˮ "''")
-            (?\̀ "`")
-            (?\́ "'")
-            (?\̂ "^")
-            (?\̃ "~")
-            (?\̄ "¯")
-            (?\̇ "·")
-            (?\̈ "¨")
-            (?\̊ "°")
-            (?\̋ "''")
-            (?\̍ "|")
-            (?\̎ "||")
-            (?\̏ "``")
-            (?\̡ ";")
-            (?\̢ ".")
-            (?\̣ ".")
-            (?\̤ "<?>")
-            (?\̥ "<o>")
-            (?\̦ ",")
-            (?\̧ "¸")
-            (?\̩ "-")
-            (?\̪ "[")
-            (?\̫ "<w>")
-            (?\̴ "~")
-            (?\̷ "/")
-            (?\̸ "/")
-            (?\̀ "`")
-            (?\́ "'")
-            (?\͂ "~")
-            (?\̈́ "'%")
-            (?\ͅ "j3")
-            (?\͇ "=")
-            (?\͠ "~~")
-            (?\ʹ "'")
-            (?\͵ ",")
-            (?\ͺ "j3")
-            (?\; "?%")
-            (?\΄ "'*")
-            (?\΅ "'%")
-            (?\Ά "A'")
-            (?\· "·")
-            (?\Έ "E'")
-            (?\Ή "Y%")
-            (?\Ί "I'")
-            (?\Ό "O'")
-            (?\Ύ "U%")
-            (?\Ώ "W%")
-            (?\ΐ "i3")
-            (?\Α "A")
-            (?\Β "B")
-            (?\Γ "G")
-            (?\Δ "D")
-            (?\Ε "E")
-            (?\Ζ "Z")
-            (?\Η "Y")
-            (?\Θ "TH")
-            (?\Ι "I")
-            (?\Κ "K")
-            (?\Λ "L")
-            (?\Μ "M")
-            (?\Ν "N")
-            (?\Ξ "C")
-            (?\Ο "O")
-            (?\Π "P")
-            (?\Ρ "R")
-            (?\Σ "S")
-            (?\Τ "T")
-            (?\Υ "U")
-            (?\Φ "F")
-            (?\Χ "X")
-            (?\Ψ "Q")
-            (?\Ω "W*")
-            (?\Ϊ "J")
-            (?\Ϋ "V*")
-            (?\ά "a'")
-            (?\έ "e'")
-            (?\ή "y%")
-            (?\ί "i'")
-            (?\ΰ "u3")
-            (?\α "a")
-            (?\β "b")
-            (?\γ "g")
-            (?\δ "d")
-            (?\ε "e")
-            (?\ζ "z")
-            (?\η "y")
-            (?\θ "th")
-            (?\ι "i")
-            (?\κ "k")
-            (?\λ "l")
-            (?\μ "µ")
-            (?\ν "n")
-            (?\ξ "c")
-            (?\ο "o")
-            (?\π "p")
-            (?\ρ "r")
-            (?\ς "*s")
-            (?\σ "s")
-            (?\τ "t")
-            (?\υ "u")
-            (?\φ "f")
-            (?\χ "x")
-            (?\ψ "q")
-            (?\ω "w")
-            (?\ϊ "j")
-            (?\ϋ "v*")
-            (?\ό "o'")
-            (?\ύ "u%")
-            (?\ώ "w%")
-            (?\ϐ "beta ")
-            (?\ϑ "theta ")
-            (?\ϒ "upsi ")
-            (?\ϕ "phi ")
-            (?\ϖ "pi ")
-            (?\ϗ "k.")
-            (?\Ϛ "T3")
-            (?\ϛ "t3")
-            (?\Ϝ "M3")
-            (?\ϝ "m3")
-            (?\Ϟ "K3")
-            (?\ϟ "k3")
-            (?\Ϡ "P3")
-            (?\ϡ "p3")
-            (?\ϰ "kappa ")
-            (?\ϱ "rho ")
-            (?\ϳ "J")
-            (?\ϴ "'%")
-            (?\ϵ "j3")
-            (?\Ё "IO")
-            (?\Ђ "D%")
-            (?\Ѓ "G%")
-            (?\Є "IE")
-            (?\Ѕ "DS")
-            (?\І "II")
-            (?\Ї "YI")
-            (?\Ј "J%")
-            (?\Љ "LJ")
-            (?\Њ "NJ")
-            (?\Ћ "Ts")
-            (?\Ќ "KJ")
-            (?\Ў "V%")
-            (?\Џ "DZ")
-            (?\А "A")
-            (?\Б "B")
-            (?\В "V")
-            (?\Г "G")
-            (?\Д "D")
-            (?\Е "E")
-            (?\Ж "ZH")
-            (?\З "Z")
-            (?\И "I")
-            (?\Й "J")
-            (?\К "K")
-            (?\Л "L")
-            (?\М "M")
-            (?\Н "N")
-            (?\О "O")
-            (?\П "P")
-            (?\Р "R")
-            (?\С "S")
-            (?\Т "T")
-            (?\У "U")
-            (?\Ф "F")
-            (?\Х "H")
-            (?\Ц "C")
-            (?\Ч "CH")
-            (?\Ш "SH")
-            (?\Щ "SCH")
-            (?\Ъ "\"")
-            (?\Ы "Y")
-            (?\Ь "'")
-            (?\Э "`E")
-            (?\Ю "YU")
-            (?\Я "YA")
-            (?\а "a")
-            (?\б "b")
-            (?\в "v")
-            (?\г "g")
-            (?\д "d")
-            (?\е "e")
-            (?\ж "zh")
-            (?\з "z")
-            (?\и "i")
-            (?\й "j")
-            (?\к "k")
-            (?\л "l")
-            (?\м "m")
-            (?\н "n")
-            (?\о "o")
-            (?\п "p")
-            (?\р "r")
-            (?\с "s")
-            (?\т "t")
-            (?\у "u")
-            (?\ф "f")
-            (?\х "h")
-            (?\ц "c")
-            (?\ч "ch")
-            (?\ш "sh")
-            (?\щ "sch")
-            (?\ъ "\"")
-            (?\ы "y")
-            (?\ь "'")
-            (?\э "`e")
-            (?\ю "yu")
-            (?\я "ya")
-            (?\ё "io")
-            (?\ђ "d%")
-            (?\ѓ "g%")
-            (?\є "ie")
-            (?\ѕ "ds")
-            (?\і "ii")
-            (?\ї "yi")
-            (?\ј "j%")
-            (?\љ "lj")
-            (?\њ "nj")
-            (?\ћ "ts")
-            (?\ќ "kj")
-            (?\ў "v%")
-            (?\џ "dz")
-            (?\Ѣ "Y3")
-            (?\ѣ "y3")
-            (?\Ѫ "O3")
-            (?\ѫ "o3")
-            (?\Ѳ "F3")
-            (?\ѳ "f3")
-            (?\Ѵ "V3")
-            (?\ѵ "v3")
-            (?\Ҁ "C3")
-            (?\ҁ "c3")
-            (?\Ґ "G3")
-            (?\ґ "g3")
-            (?\Ӕ "AE")
-            (?\ӕ "ae")
-            (?\ִ "i")
-            (?\ַ "a")
-            (?\ָ "o")
-            (?\ּ "u")
-            (?\ֿ "h")
-            (?\ׂ ":")
-            (?\א "#")
-            (?\ב "B+")
-            (?\ג "G+")
-            (?\ד "D+")
-            (?\ה "H+")
-            (?\ו "W+")
-            (?\ז "Z+")
-            (?\ח "X+")
-            (?\ט "Tj")
-            (?\י "J+")
-            (?\ך "K%")
-            (?\כ "K+")
-            (?\ל "L+")
-            (?\ם "M%")
-            (?\מ "M+")
-            (?\ן "N%")
-            (?\נ "N+")
-            (?\ס "S+")
-            (?\ע "E+")
-            (?\ף "P%")
-            (?\פ "P+")
-            (?\ץ "Zj")
-            (?\צ "ZJ")
-            (?\ק "Q+")
-            (?\ר "R+")
-            (?\ש "Sh")
-            (?\ת "T+")
-            (?\װ "v")
-            (?\ױ "oy")
-            (?\ײ "ey")
-            (?\، ",+")
-            (?\؛ ";+")
-            (?\؟ "?+")
-            (?\ء "H'")
-            (?\آ "aM")
-            (?\أ "aH")
-            (?\ؤ "wH")
-            (?\إ "ah")
-            (?\ئ "yH")
-            (?\ا "a+")
-            (?\ب "b+")
-            (?\ة "tm")
-            (?\ت "t+")
-            (?\ث "tk")
-            (?\ج "g+")
-            (?\ح "hk")
-            (?\خ "x+")
-            (?\د "d+")
-            (?\ذ "dk")
-            (?\ر "r+")
-            (?\ز "z+")
-            (?\س "s+")
-            (?\ش "sn")
-            (?\ص "c+")
-            (?\ض "dd")
-            (?\ط "tj")
-            (?\ظ "zH")
-            (?\ع "e+")
-            (?\غ "i+")
-            (?\ـ "++")
-            (?\ف "f+")
-            (?\ق "q+")
-            (?\ك "k+")
-            (?\ل "l+")
-            (?\م "m+")
-            (?\ن "n+")
-            (?\ه "h+")
-            (?\و "w+")
-            (?\ى "j+")
-            (?\ي "y+")
-            (?\ً ":+")
-            (?\ٌ "\"+")
-            (?\ٍ "=+")
-            (?\َ "/+")
-            (?\ُ "'+")
-            (?\ِ "1+")
-            (?\ّ "3+")
-            (?\ْ "0+")
-            (?\٠ "0a")
-            (?\١ "1a")
-            (?\٢ "2a")
-            (?\٣ "3a")
-            (?\٤ "4a")
-            (?\٥ "5a")
-            (?\٦ "6a")
-            (?\٧ "7a")
-            (?\٨ "8a")
-            (?\٩ "9a")
-            (?\ٰ "aS")
-            (?\پ "p+")
-            (?\ځ "hH")
-            (?\چ "tc")
-            (?\ژ "zj")
-            (?\ڤ "v+")
-            (?\گ "gf")
-            (?\۰ "0a")
-            (?\۱ "1a")
-            (?\۲ "2a")
-            (?\۳ "3a")
-            (?\۴ "4a")
-            (?\۵ "5a")
-            (?\۶ "6a")
-            (?\۷ "7a")
-            (?\۸ "8a")
-            (?\۹ "9a")
-            (?\ሀ "he")
-            (?\ሁ "hu")
-            (?\ሂ "hi")
-            (?\ሃ "ha")
-            (?\ሄ "hE")
-            (?\ህ "h")
-            (?\ሆ "ho")
-            (?\ለ "le")
-            (?\ሉ "lu")
-            (?\ሊ "li")
-            (?\ላ "la")
-            (?\ሌ "lE")
-            (?\ል "l")
-            (?\ሎ "lo")
-            (?\ሏ "lWa")
-            (?\ሐ "He")
-            (?\ሑ "Hu")
-            (?\ሒ "Hi")
-            (?\ሓ "Ha")
-            (?\ሔ "HE")
-            (?\ሕ "H")
-            (?\ሖ "Ho")
-            (?\ሗ "HWa")
-            (?\መ "me")
-            (?\ሙ "mu")
-            (?\ሚ "mi")
-            (?\ማ "ma")
-            (?\ሜ "mE")
-            (?\ም "m")
-            (?\ሞ "mo")
-            (?\ሟ "mWa")
-            (?\ሠ "`se")
-            (?\ሡ "`su")
-            (?\ሢ "`si")
-            (?\ሣ "`sa")
-            (?\ሤ "`sE")
-            (?\ሥ "`s")
-            (?\ሦ "`so")
-            (?\ሧ "`sWa")
-            (?\ረ "re")
-            (?\ሩ "ru")
-            (?\ሪ "ri")
-            (?\ራ "ra")
-            (?\ሬ "rE")
-            (?\ር "r")
-            (?\ሮ "ro")
-            (?\ሯ "rWa")
-            (?\ሰ "se")
-            (?\ሱ "su")
-            (?\ሲ "si")
-            (?\ሳ "sa")
-            (?\ሴ "sE")
-            (?\ስ "s")
-            (?\ሶ "so")
-            (?\ሷ "sWa")
-            (?\ሸ "xe")
-            (?\ሹ "xu")
-            (?\ሺ "xi")
-            (?\ሻ "xa")
-            (?\ሼ "xE")
-            (?\ሽ "xa")
-            (?\ሾ "xo")
-            (?\ሿ "xWa")
-            (?\ቀ "qe")
-            (?\ቁ "qu")
-            (?\ቂ "qi")
-            (?\ቃ "qa")
-            (?\ቄ "qE")
-            (?\ቅ "q")
-            (?\ቆ "qo")
-            (?\ቈ "qWe")
-            (?\ቊ "qWi")
-            (?\ቋ "qWa")
-            (?\ቌ "qWE")
-            (?\ቍ "qW")
-            (?\ቐ "Qe")
-            (?\ቑ "Qu")
-            (?\ቒ "Qi")
-            (?\ቓ "Qa")
-            (?\ቔ "QE")
-            (?\ቕ "Q")
-            (?\ቖ "Qo")
-            (?\ቘ "QWe")
-            (?\ቚ "QWi")
-            (?\ቛ "QWa")
-            (?\ቜ "QWE")
-            (?\ቝ "QW")
-            (?\በ "be")
-            (?\ቡ "bu")
-            (?\ቢ "bi")
-            (?\ባ "ba")
-            (?\ቤ "bE")
-            (?\ብ "b")
-            (?\ቦ "bo")
-            (?\ቧ "bWa")
-            (?\ቨ "ve")
-            (?\ቩ "vu")
-            (?\ቪ "vi")
-            (?\ቫ "va")
-            (?\ቬ "vE")
-            (?\ቭ "v")
-            (?\ቮ "vo")
-            (?\ቯ "vWa")
-            (?\ተ "te")
-            (?\ቱ "tu")
-            (?\ቲ "ti")
-            (?\ታ "ta")
-            (?\ቴ "tE")
-            (?\ት "t")
-            (?\ቶ "to")
-            (?\ቷ "tWa")
-            (?\ቸ "ce")
-            (?\ቹ "cu")
-            (?\ቺ "ci")
-            (?\ቻ "ca")
-            (?\ቼ "cE")
-            (?\ች "c")
-            (?\ቾ "co")
-            (?\ቿ "cWa")
-            (?\ኀ "`he")
-            (?\ኁ "`hu")
-            (?\ኂ "`hi")
-            (?\ኃ "`ha")
-            (?\ኄ "`hE")
-            (?\ኅ "`h")
-            (?\ኆ "`ho")
-            (?\ኈ "hWe")
-            (?\ኊ "hWi")
-            (?\ኋ "hWa")
-            (?\ኌ "hWE")
-            (?\ኍ "hW")
-            (?\ነ "na")
-            (?\ኑ "nu")
-            (?\ኒ "ni")
-            (?\ና "na")
-            (?\ኔ "nE")
-            (?\ን "n")
-            (?\ኖ "no")
-            (?\ኗ "nWa")
-            (?\ኘ "Ne")
-            (?\ኙ "Nu")
-            (?\ኚ "Ni")
-            (?\ኛ "Na")
-            (?\ኜ "NE")
-            (?\ኝ "N")
-            (?\ኞ "No")
-            (?\ኟ "NWa")
-            (?\አ "e")
-            (?\ኡ "u")
-            (?\ኢ "i")
-            (?\ኣ "a")
-            (?\ኤ "E")
-            (?\እ "I")
-            (?\ኦ "o")
-            (?\ኧ "e3")
-            (?\ከ "ke")
-            (?\ኩ "ku")
-            (?\ኪ "ki")
-            (?\ካ "ka")
-            (?\ኬ "kE")
-            (?\ክ "k")
-            (?\ኮ "ko")
-            (?\ኰ "kWe")
-            (?\ኲ "kWi")
-            (?\ኳ "kWa")
-            (?\ኴ "kWE")
-            (?\ኵ "kW")
-            (?\ኸ "Ke")
-            (?\ኹ "Ku")
-            (?\ኺ "Ki")
-            (?\ኻ "Ka")
-            (?\ኼ "KE")
-            (?\ኽ "K")
-            (?\ኾ "Ko")
-            (?\ዀ "KWe")
-            (?\ዂ "KWi")
-            (?\ዃ "KWa")
-            (?\ዄ "KWE")
-            (?\ዅ "KW")
-            (?\ወ "we")
-            (?\ዉ "wu")
-            (?\ዊ "wi")
-            (?\ዋ "wa")
-            (?\ዌ "wE")
-            (?\ው "w")
-            (?\ዎ "wo")
-            (?\ዐ "`e")
-            (?\ዑ "`u")
-            (?\ዒ "`i")
-            (?\ዓ "`a")
-            (?\ዔ "`E")
-            (?\ዕ "`I")
-            (?\ዖ "`o")
-            (?\ዘ "ze")
-            (?\ዙ "zu")
-            (?\ዚ "zi")
-            (?\ዛ "za")
-            (?\ዜ "zE")
-            (?\ዝ "z")
-            (?\ዞ "zo")
-            (?\ዟ "zWa")
-            (?\ዠ "Ze")
-            (?\ዡ "Zu")
-            (?\ዢ "Zi")
-            (?\ዣ "Za")
-            (?\ዤ "ZE")
-            (?\ዥ "Z")
-            (?\ዦ "Zo")
-            (?\ዧ "ZWa")
-            (?\የ "ye")
-            (?\ዩ "yu")
-            (?\ዪ "yi")
-            (?\ያ "ya")
-            (?\ዬ "yE")
-            (?\ይ "y")
-            (?\ዮ "yo")
-            (?\ዯ "yWa")
-            (?\ደ "de")
-            (?\ዱ "du")
-            (?\ዲ "di")
-            (?\ዳ "da")
-            (?\ዴ "dE")
-            (?\ድ "d")
-            (?\ዶ "do")
-            (?\ዷ "dWa")
-            (?\ዸ "De")
-            (?\ዹ "Du")
-            (?\ዺ "Di")
-            (?\ዻ "Da")
-            (?\ዼ "DE")
-            (?\ዽ "D")
-            (?\ዾ "Do")
-            (?\ዿ "DWa")
-            (?\ጀ "je")
-            (?\ጁ "ju")
-            (?\ጂ "ji")
-            (?\ጃ "ja")
-            (?\ጄ "jE")
-            (?\ጅ "j")
-            (?\ጆ "jo")
-            (?\ጇ "jWa")
-            (?\ገ "ga")
-            (?\ጉ "gu")
-            (?\ጊ "gi")
-            (?\ጋ "ga")
-            (?\ጌ "gE")
-            (?\ግ "g")
-            (?\ጎ "go")
-            (?\ጐ "gWu")
-            (?\ጒ "gWi")
-            (?\ጓ "gWa")
-            (?\ጔ "gWE")
-            (?\ጕ "gW")
-            (?\ጘ "Ge")
-            (?\ጙ "Gu")
-            (?\ጚ "Gi")
-            (?\ጛ "Ga")
-            (?\ጜ "GE")
-            (?\ጝ "G")
-            (?\ጞ "Go")
-            (?\ጟ "GWa")
-            (?\ጠ "Te")
-            (?\ጡ "Tu")
-            (?\ጢ "Ti")
-            (?\ጣ "Ta")
-            (?\ጤ "TE")
-            (?\ጥ "T")
-            (?\ጦ "To")
-            (?\ጧ "TWa")
-            (?\ጨ "Ce")
-            (?\ጩ "Ca")
-            (?\ጪ "Cu")
-            (?\ጫ "Ca")
-            (?\ጬ "CE")
-            (?\ጭ "C")
-            (?\ጮ "Co")
-            (?\ጯ "CWa")
-            (?\ጰ "Pe")
-            (?\ጱ "Pu")
-            (?\ጲ "Pi")
-            (?\ጳ "Pa")
-            (?\ጴ "PE")
-            (?\ጵ "P")
-            (?\ጶ "Po")
-            (?\ጷ "PWa")
-            (?\ጸ "SWe")
-            (?\ጹ "SWu")
-            (?\ጺ "SWi")
-            (?\ጻ "SWa")
-            (?\ጼ "SWE")
-            (?\ጽ "SW")
-            (?\ጾ "SWo")
-            (?\ጿ "SWa")
-            (?\ፀ "`Sa")
-            (?\ፁ "`Su")
-            (?\ፂ "`Si")
-            (?\ፃ "`Sa")
-            (?\ፄ "`SE")
-            (?\ፅ "`S")
-            (?\ፆ "`So")
-            (?\ፈ "fa")
-            (?\ፉ "fu")
-            (?\ፊ "fi")
-            (?\ፋ "fa")
-            (?\ፌ "fE")
-            (?\ፍ "o")
-            (?\ፎ "fo")
-            (?\ፏ "fWa")
-            (?\ፐ "pe")
-            (?\ፑ "pu")
-            (?\ፒ "pi")
-            (?\ፓ "pa")
-            (?\ፔ "pE")
-            (?\ፕ "p")
-            (?\ፖ "po")
-            (?\ፗ "pWa")
-            (?\ፘ "mYa")
-            (?\ፙ "rYa")
-            (?\ፚ "fYa")
-            (?\፠ " ")
-            (?\፡ ":")
-            (?\። "::")
-            (?\፣ ",")
-            (?\፤ ";")
-            (?\፥ "-:")
-            (?\፦ ":-")
-            (?\፧ "`?")
-            (?\፨ ":|:")
-            (?\፩ "`1")
-            (?\፪ "`2")
-            (?\፫ "`3")
-            (?\፬ "`4")
-            (?\፭ "`5")
-            (?\፮ "`6")
-            (?\፯ "`7")
-            (?\፰ "`8")
-            (?\፱ "`9")
-            (?\፲ "`10")
-            (?\፳ "`20")
-            (?\፴ "`30")
-            (?\፵ "`40")
-            (?\፶ "`50")
-            (?\፷ "`60")
-            (?\፸ "`70")
-            (?\፹ "`80")
-            (?\፺ "`90")
-            (?\፻ "`100")
-            (?\፼ "`10000")
-            (?\Ḁ "A-0")
-            (?\ḁ "a-0")
-            (?\Ḃ "B.")
-            (?\ḃ "b.")
-            (?\Ḅ "B-.")
-            (?\ḅ "b-.")
-            (?\Ḇ "B_")
-            (?\ḇ "b_")
-            (?\Ḉ "C,'")
-            (?\ḉ "c,'")
-            (?\Ḋ "D.")
-            (?\ḋ "d.")
-            (?\Ḍ "D-.")
-            (?\ḍ "d-.")
-            (?\Ḏ "D_")
-            (?\ḏ "d_")
-            (?\Ḑ "D,")
-            (?\ḑ "d,")
-            (?\Ḓ "D->")
-            (?\ḓ "d->")
-            (?\Ḕ "E-!")
-            (?\ḕ "e-!")
-            (?\Ḗ "E-'")
-            (?\ḗ "e-'")
-            (?\Ḙ "E->")
-            (?\ḙ "e->")
-            (?\Ḛ "E-?")
-            (?\ḛ "e-?")
-            (?\Ḝ "E,(")
-            (?\ḝ "e,(")
-            (?\Ḟ "F.")
-            (?\ḟ "f.")
-            (?\Ḡ "G-")
-            (?\ḡ "g-")
-            (?\Ḣ "H.")
-            (?\ḣ "h.")
-            (?\Ḥ "H-.")
-            (?\ḥ "h-.")
-            (?\Ḧ "H:")
-            (?\ḧ "h:")
-            (?\Ḩ "H,")
-            (?\ḩ "h,")
-            (?\Ḫ "H-(")
-            (?\ḫ "h-(")
-            (?\Ḭ "I-?")
-            (?\ḭ "i-?")
-            (?\Ḯ "I:'")
-            (?\ḯ "i:'")
-            (?\Ḱ "K'")
-            (?\ḱ "k'")
-            (?\Ḳ "K-.")
-            (?\ḳ "k-.")
-            (?\Ḵ "K_")
-            (?\ḵ "k_")
-            (?\Ḷ "L-.")
-            (?\ḷ "l-.")
-            (?\Ḹ "L--.")
-            (?\ḹ "l--.")
-            (?\Ḻ "L_")
-            (?\ḻ "l_")
-            (?\Ḽ "L->")
-            (?\ḽ "l->")
-            (?\Ḿ "M'")
-            (?\ḿ "m'")
-            (?\Ṁ "M.")
-            (?\ṁ "m.")
-            (?\Ṃ "M-.")
-            (?\ṃ "m-.")
-            (?\Ṅ "N.")
-            (?\ṅ "n.")
-            (?\Ṇ "N-.")
-            (?\ṇ "n-.")
-            (?\Ṉ "N_")
-            (?\ṉ "n_")
-            (?\Ṋ "N->")
-            (?\ṋ "n->")
-            (?\Ṍ "O?'")
-            (?\ṍ "o?'")
-            (?\Ṏ "O?:")
-            (?\ṏ "o?:")
-            (?\Ṑ "O-!")
-            (?\ṑ "o-!")
-            (?\Ṓ "O-'")
-            (?\ṓ "o-'")
-            (?\Ṕ "P'")
-            (?\ṕ "p'")
-            (?\Ṗ "P.")
-            (?\ṗ "p.")
-            (?\Ṙ "R.")
-            (?\ṙ "r.")
-            (?\Ṛ "R-.")
-            (?\ṛ "r-.")
-            (?\Ṝ "R--.")
-            (?\ṝ "r--.")
-            (?\Ṟ "R_")
-            (?\ṟ "r_")
-            (?\Ṡ "S.")
-            (?\ṡ "s.")
-            (?\Ṣ "S-.")
-            (?\ṣ "s-.")
-            (?\Ṥ "S'.")
-            (?\ṥ "s'.")
-            (?\Ṧ "S<.")
-            (?\ṧ "s<.")
-            (?\Ṩ "S.-.")
-            (?\ṩ "s.-.")
-            (?\Ṫ "T.")
-            (?\ṫ "t.")
-            (?\Ṭ "T-.")
-            (?\ṭ "t-.")
-            (?\Ṯ "T_")
-            (?\ṯ "t_")
-            (?\Ṱ "T->")
-            (?\ṱ "t->")
-            (?\Ṳ "U--:")
-            (?\ṳ "u--:")
-            (?\Ṵ "U-?")
-            (?\ṵ "u-?")
-            (?\Ṷ "U->")
-            (?\ṷ "u->")
-            (?\Ṹ "U?'")
-            (?\ṹ "u?'")
-            (?\Ṻ "U-:")
-            (?\ṻ "u-:")
-            (?\Ṽ "V?")
-            (?\ṽ "v?")
-            (?\Ṿ "V-.")
-            (?\ṿ "v-.")
-            (?\Ẁ "W!")
-            (?\ẁ "w!")
-            (?\Ẃ "W'")
-            (?\ẃ "w'")
-            (?\Ẅ "W:")
-            (?\ẅ "w:")
-            (?\Ẇ "W.")
-            (?\ẇ "w.")
-            (?\Ẉ "W-.")
-            (?\ẉ "w-.")
-            (?\Ẋ "X.")
-            (?\ẋ "x.")
-            (?\Ẍ "X:")
-            (?\ẍ "x:")
-            (?\Ẏ "Y.")
-            (?\ẏ "y.")
-            (?\Ẑ "Z>")
-            (?\ẑ "z>")
-            (?\Ẓ "Z-.")
-            (?\ẓ "z-.")
-            (?\Ẕ "Z_")
-            (?\ẕ "z_")
-            (?\ẖ "h_")
-            (?\ẗ "t:")
-            (?\ẘ "w0")
-            (?\ẙ "y0")
-            (?\Ạ "A-.")
-            (?\ạ "a-.")
-            (?\Ả "A2")
-            (?\ả "a2")
-            (?\Ấ "A>'")
-            (?\ấ "a>'")
-            (?\Ầ "A>!")
-            (?\ầ "a>!")
-            (?\Ẩ "A>2")
-            (?\ẩ "a>2")
-            (?\Ẫ "A>?")
-            (?\ẫ "a>?")
-            (?\Ậ "A>-.")
-            (?\ậ "a>-.")
-            (?\Ắ "A('")
-            (?\ắ "a('")
-            (?\Ằ "A(!")
-            (?\ằ "a(!")
-            (?\Ẳ "A(2")
-            (?\ẳ "a(2")
-            (?\Ẵ "A(?")
-            (?\ẵ "a(?")
-            (?\Ặ "A(-.")
-            (?\ặ "a(-.")
-            (?\Ẹ "E-.")
-            (?\ẹ "e-.")
-            (?\Ẻ "E2")
-            (?\ẻ "e2")
-            (?\Ẽ "E?")
-            (?\ẽ "e?")
-            (?\Ế "E>'")
-            (?\ế "e>'")
-            (?\Ề "E>!")
-            (?\ề "e>!")
-            (?\Ể "E>2")
-            (?\ể "e>2")
-            (?\Ễ "E>?")
-            (?\ễ "e>?")
-            (?\Ệ "E>-.")
-            (?\ệ "e>-.")
-            (?\Ỉ "I2")
-            (?\ỉ "i2")
-            (?\Ị "I-.")
-            (?\ị "i-.")
-            (?\Ọ "O-.")
-            (?\ọ "o-.")
-            (?\Ỏ "O2")
-            (?\ỏ "o2")
-            (?\Ố "O>'")
-            (?\ố "o>'")
-            (?\Ồ "O>!")
-            (?\ồ "o>!")
-            (?\Ổ "O>2")
-            (?\ổ "o>2")
-            (?\Ỗ "O>?")
-            (?\ỗ "o>?")
-            (?\Ộ "O>-.")
-            (?\ộ "o>-.")
-            (?\Ớ "O9'")
-            (?\ớ "o9'")
-            (?\Ờ "O9!")
-            (?\ờ "o9!")
-            (?\Ở "O92")
-            (?\ở "o92")
-            (?\Ỡ "O9?")
-            (?\ỡ "o9?")
-            (?\Ợ "O9-.")
-            (?\ợ "o9-.")
-            (?\Ụ "U-.")
-            (?\ụ "u-.")
-            (?\Ủ "U2")
-            (?\ủ "u2")
-            (?\Ứ "U9'")
-            (?\ứ "u9'")
-            (?\Ừ "U9!")
-            (?\ừ "u9!")
-            (?\Ử "U92")
-            (?\ử "u92")
-            (?\Ữ "U9?")
-            (?\ữ "u9?")
-            (?\Ự "U9-.")
-            (?\ự "u9-.")
-            (?\Ỳ "Y!")
-            (?\ỳ "y!")
-            (?\Ỵ "Y-.")
-            (?\ỵ "y-.")
-            (?\Ỷ "Y2")
-            (?\ỷ "y2")
-            (?\Ỹ "Y?")
-            (?\ỹ "y?")
-            (?\ἀ "a")
-            (?\ἁ "ha")
-            (?\ἂ "`a")
-            (?\ἃ "h`a")
-            (?\ἄ "a'")
-            (?\ἅ "ha'")
-            (?\ἆ "a~")
-            (?\ἇ "ha~")
-            (?\Ἀ "A")
-            (?\Ἁ "hA")
-            (?\Ἂ "`A")
-            (?\Ἃ "h`A")
-            (?\Ἄ "A'")
-            (?\Ἅ "hA'")
-            (?\Ἆ "A~")
-            (?\Ἇ "hA~")
-            (?\ἑ "he")
-            (?\Ἑ "hE")
-            (?\ἱ "hi")
-            (?\Ἱ "hI")
-            (?\ὁ "ho")
-            (?\Ὁ "hO")
-            (?\ὑ "hu")
-            (?\Ὑ "hU")
-            (?\᾿ ",,")
-            (?\῀ "?*")
-            (?\῁ "?:")
-            (?\῍ ",!")
-            (?\῎ ",'")
-            (?\῏ "?,")
-            (?\῝ ";!")
-            (?\῞ ";'")
-            (?\῟ "?;")
-            (?\ῥ "rh")
-            (?\Ῥ "Rh")
-            (?\῭ "!:")
-            (?\` "!*")
-            (?\῾ ";;")
-            (?\  " ")
-            (?\  "  ")
-            (?\  " ")
-            (?\  "  ")
-            (?\  " ")
-            (?\  " ")
-            (?\  " ")
-            (?\  " ")
-            (?\  " ")
-            (?\  " ")
-            (?\‐ "-")
-            (?\‑ "-")
-            (?\– "-")
-            (?\— "--")
-            (?\― "-")
-            (?\‖ "||")
-            (?\‗ "=2")
-            (?\‘ "`")
-            (?\’ "'")
-            (?\‚ "'")
-            (?\‛ "'")
-            (?\“ "\"")
-            (?\” "\"")
-            (?\„ "\"")
-            (?\‟ "\"")
-            (?\† "/-")
-            (?\‡ "/=")
-            (?\• " o ")
-            (?\․ ".")
-            (?\‥ "..")
-            (?\… "...")
-            (?\‧ "·")
-            (?\‰ " 0/00")
-            (?\′ "'")
-            (?\″ "''")
-            (?\‴ "'''")
-            (?\‵ "`")
-            (?\‶ "``")
-            (?\‷ "```")
-            (?\‸ "Ca")
-            (?\‹ "<")
-            (?\› ">")
-            (?\※ ":X")
-            (?\‼ "!!")
-            (?\‾ "'-")
-            (?\⁃ "-")
-            (?\⁄ "/")
-            (?\⁈ "?!")
-            (?\⁉ "!?")
-            (?\⁰ "^0")
-            (?\⁴ "^4")
-            (?\⁵ "^5")
-            (?\⁶ "^6")
-            (?\⁷ "^7")
-            (?\⁸ "^8")
-            (?\⁹ "^9")
-            (?\⁺ "^+")
-            (?\⁻ "^-")
-            (?\⁼ "^=")
-            (?\⁽ "^(")
-            (?\⁾ "^)")
-            (?\ⁿ "^n")
-            (?\₀ "_0")
-            (?\₁ "_1")
-            (?\₂ "_2")
-            (?\₃ "_3")
-            (?\₄ "_4")
-            (?\₅ "_5")
-            (?\₆ "_6")
-            (?\₇ "_7")
-            (?\₈ "_8")
-            (?\₉ "_9")
-            (?\₊ "_+")
-            (?\₋ "_-")
-            (?\₌ "_=")
-            (?\₍ "(")
-            (?\₎ ")")
-            (?\₣ "Ff")
-            (?\₤ "Li")
-            (?\₧ "Pt")
-            (?\₩ "W=")
-            (?\€ "EUR")
-            (?\℀ "a/c")
-            (?\℁ "a/s")
-            (?\℃ "oC")
-            (?\℅ "c/o")
-            (?\℆ "c/u")
-            (?\℉ "oF")
-            (?\ℊ "g")
-            (?\ℎ "h")
-            (?\ℏ "\\hbar")
-            (?\ℑ "Im")
-            (?\ℓ "l")
-            (?\№ "No.")
-            (?\℗ "PO")
-            (?\℘ "P")
-            (?\ℜ "Re")
-            (?\℞ "Rx")
-            (?\℠ "(SM)")
-            (?\℡ "TEL")
-            (?\™ "(TM)")
-            (?\Ω "Ohm")
-            (?\K "K")
-            (?\Å "Ang.")
-            (?\℮ "est.")
-            (?\ℴ "o")
-            (?\ℵ "Aleph ")
-            (?\ℶ "Bet ")
-            (?\ℷ "Gimel ")
-            (?\ℸ "Dalet ")
-            (?\⅓ " 1/3")
-            (?\⅔ " 2/3")
-            (?\⅕ " 1/5")
-            (?\⅖ " 2/5")
-            (?\⅗ " 3/5")
-            (?\⅘ " 4/5")
-            (?\⅙ " 1/6")
-            (?\⅚ " 5/6")
-            (?\⅛ " 1/8")
-            (?\⅜ " 3/8")
-            (?\⅝ " 5/8")
-            (?\⅞ " 7/8")
-            (?\⅟ " 1/")
-            (?\Ⅰ "I")
-            (?\Ⅱ "II")
-            (?\Ⅲ "III")
-            (?\Ⅳ "IV")
-            (?\Ⅴ "V")
-            (?\Ⅵ "VI")
-            (?\Ⅶ "VII")
-            (?\Ⅷ "VIII")
-            (?\Ⅸ "IX")
-            (?\Ⅹ "X")
-            (?\Ⅺ "XI")
-            (?\Ⅻ "XII")
-            (?\Ⅼ "L")
-            (?\Ⅽ "C")
-            (?\Ⅾ "D")
-            (?\Ⅿ "M")
-            (?\ⅰ "i")
-            (?\ⅱ "ii")
-            (?\ⅲ "iii")
-            (?\ⅳ "iv")
-            (?\ⅴ "v")
-            (?\ⅵ "vi")
-            (?\ⅶ "vii")
-            (?\ⅷ "viii")
-            (?\ⅸ "ix")
-            (?\ⅹ "x")
-            (?\ⅺ "xi")
-            (?\ⅻ "xii")
-            (?\ⅼ "l")
-            (?\ⅽ "c")
-            (?\ⅾ "d")
-            (?\ⅿ "m")
-            (?\ↀ "1000RCD")
-            (?\ↁ "5000R")
-            (?\ↂ "10000R")
-            (?\← "<-")
-            (?\↑ "-^")
-            (?\→ "->")
-            (?\↓ "-v")
-            (?\↔ "<->")
-            (?\↕ "UD")
-            (?\↖ "<!!")
-            (?\↗ "//>")
-            (?\↘ "!!>")
-            (?\↙ "<//")
-            (?\↨ "UD-")
-            (?\↵ "RET")
-            (?\⇀ ">V")
-            (?\⇐ "<=")
-            (?\⇑ "^^")
-            (?\⇒ "=>")
-            (?\⇓ "vv")
-            (?\⇔ "<=>")
-            (?\∀ "FA")
-            (?\∂ "\\partial")
-            (?\∃ "TE")
-            (?\∅ "{}")
-            (?\∆ "Delta")
-            (?\∇ "Nabla")
-            (?\∈ "(-")
-            (?\∉ "!(-")
-            (?\∊ "(-")
-            (?\∋ "-)")
-            (?\∌ "!-)")
-            (?\∍ "-)")
-            (?\∎ " qed")
-            (?\∏ "\\prod")
-            (?\∑ "\\sum")
-            (?\− " -")
-            (?\∓ "-/+")
-            (?\∔ ".+")
-            (?\∕ "/")
-            (?\∖ " - ")
-            (?\∗ "*")
-            (?\∘ " ° ")
-            (?\∙ "sb")
-            (?\√ " SQRT ")
-            (?\∛ " ROOT³ ")
-            (?\∜ " ROOT4 ")
-            (?\∝ "0(")
-            (?\∞ "infty")
-            (?\∟ "-L")
-            (?\∠ "-V")
-            (?\∥ "PP")
-            (?\∦ " !PP ")
-            (?\∧ "AND")
-            (?\∨ "OR")
-            (?\∩ "(U")
-            (?\∪ ")U")
-            (?\∫ "\\int ")
-            (?\∬ "DI")
-            (?\∮ "Io")
-            (?\∴ ".:")
-            (?\∵ ":.")
-            (?\∶ ":R")
-            (?\∷ "::")
-            (?\∼ "?1")
-            (?\∾ "CG")
-            (?\≃ "?-")
-            (?\≅ "?=")
-            (?\≈ "~=")
-            (?\≉ " !~= ")
-            (?\≌ "=?")
-            (?\≓ "HI")
-            (?\≔ ":=")
-            (?\≕ "=:")
-            (?\≠ "!=")
-            (?\≡ "=3")
-            (?\≢ " !=3 ")
-            (?\≤ "=<")
-            (?\≥ ">=")
-            (?\≦ ".LE.")
-            (?\≧ ".GE.")
-            (?\≨ ".LT.NOT.EQ.")
-            (?\≩ ".GT.NOT.EQ.")
-            (?\≪ "<<")
-            (?\≫ ">>")
-            (?\≮ "!<")
-            (?\≯ "!>")
-            (?\≶ " <> ")
-            (?\≷ " >< ")
-            (?\⊂ "(C")
-            (?\⊃ ")C")
-            (?\⊄ " !(C ")
-            (?\⊅ " !)C ")
-            (?\⊆ "(_")
-            (?\⊇ ")_")
-            (?\⊕ "(+)")
-            (?\⊖ "(-)")
-            (?\⊗ "(×)")
-            (?\⊘ "(/)")
-            (?\⊙ "(·)")
-            (?\⊚ "(°)")
-            (?\⊛ "(*)")
-            (?\⊜ "(=)")
-            (?\⊝ "(-)")
-            (?\⊞ "[+]")
-            (?\⊟ "[-]")
-            (?\⊠ "[×]")
-            (?\⊡ "[·]")
-            (?\⊥ "-T")
-            (?\⊧ " MODELS ")
-            (?\⊨ " TRUE ")
-            (?\⊩ " FORCES ")
-            (?\⊬ " !PROVES ")
-            (?\⊭ " NOT TRUE ")
-            (?\⊮ " !FORCES ")
-            (?\⊲ " NORMAL SUBGROUP OF ")
-            (?\⊳ " CONTAINS AS NORMAL SUBGROUP ")
-            (?\⊴ " NORMAL SUBGROUP OF OR EQUAL TO ")
-            (?\⊵ " CONTAINS AS NORMAL SUBGROUP OR EQUAL TO ")
-            (?\⊸ " MULTIMAP ")
-            (?\⊺ " INTERCALATE ")
-            (?\⊻ " XOR ")
-            (?\⊼ " NAND ")
-            (?\⋅ " · ")
-            (?\⋖ "<.")
-            (?\⋗ ">.")
-            (?\⋘ "<<<")
-            (?\⋙ ">>>")
-            (?\⋮ ":3")
-            (?\⋯ ".3")
-            (?\⌂ "Eh")
-            (?\⌇ "~~")
-            (?\⌈ "<7")
-            (?\⌉ ">7")
-            (?\⌊ "7<")
-            (?\⌋ "7>")
-            (?\⌐ "NI")
-            (?\⌒ "(A")
-            (?\⌕ "TR")
-            (?\⌘ "88")
-            (?\⌠ "Iu")
-            (?\⌡ "Il")
-            (?\⌢ ":(")
-            (?\⌣ ":)")
-            (?\⌤ "|^|")
-            (?\⌧ "[X]")
-            (?\〈 "</")
-            (?\〉 "/>")
-            (?\␣ "Vs")
-            (?\⑀ "1h")
-            (?\⑁ "3h")
-            (?\⑂ "2h")
-            (?\⑃ "4h")
-            (?\⑆ "1j")
-            (?\⑇ "2j")
-            (?\⑈ "3j")
-            (?\⑉ "4j")
-            (?\① "1-o")
-            (?\② "2-o")
-            (?\③ "3-o")
-            (?\④ "4-o")
-            (?\⑤ "5-o")
-            (?\⑥ "6-o")
-            (?\⑦ "7-o")
-            (?\⑧ "8-o")
-            (?\⑨ "9-o")
-            (?\⑩ "10-o")
-            (?\⑪ "11-o")
-            (?\⑫ "12-o")
-            (?\⑬ "13-o")
-            (?\⑭ "14-o")
-            (?\⑮ "15-o")
-            (?\⑯ "16-o")
-            (?\⑰ "17-o")
-            (?\⑱ "18-o")
-            (?\⑲ "19-o")
-            (?\⑳ "20-o")
-            (?\⑴ "(1)")
-            (?\⑵ "(2)")
-            (?\⑶ "(3)")
-            (?\⑷ "(4)")
-            (?\⑸ "(5)")
-            (?\⑹ "(6)")
-            (?\⑺ "(7)")
-            (?\⑻ "(8)")
-            (?\⑼ "(9)")
-            (?\⑽ "(10)")
-            (?\⑾ "(11)")
-            (?\⑿ "(12)")
-            (?\⒀ "(13)")
-            (?\⒁ "(14)")
-            (?\⒂ "(15)")
-            (?\⒃ "(16)")
-            (?\⒄ "(17)")
-            (?\⒅ "(18)")
-            (?\⒆ "(19)")
-            (?\⒇ "(20)")
-            (?\⒈ "1.")
-            (?\⒉ "2.")
-            (?\⒊ "3.")
-            (?\⒋ "4.")
-            (?\⒌ "5.")
-            (?\⒍ "6.")
-            (?\⒎ "7.")
-            (?\⒏ "8.")
-            (?\⒐ "9.")
-            (?\⒑ "10.")
-            (?\⒒ "11.")
-            (?\⒓ "12.")
-            (?\⒔ "13.")
-            (?\⒕ "14.")
-            (?\⒖ "15.")
-            (?\⒗ "16.")
-            (?\⒘ "17.")
-            (?\⒙ "18.")
-            (?\⒚ "19.")
-            (?\⒛ "20.")
-            (?\⒜ "(a)")
-            (?\⒝ "(b)")
-            (?\⒞ "(c)")
-            (?\⒟ "(d)")
-            (?\⒠ "(e)")
-            (?\⒡ "(f)")
-            (?\⒢ "(g)")
-            (?\⒣ "(h)")
-            (?\⒤ "(i)")
-            (?\⒥ "(j)")
-            (?\⒦ "(k)")
-            (?\⒧ "(l)")
-            (?\⒨ "(m)")
-            (?\⒩ "(n)")
-            (?\⒪ "(o)")
-            (?\⒫ "(p)")
-            (?\⒬ "(q)")
-            (?\⒭ "(r)")
-            (?\⒮ "(s)")
-            (?\⒯ "(t)")
-            (?\⒰ "(u)")
-            (?\⒱ "(v)")
-            (?\⒲ "(w)")
-            (?\⒳ "(x)")
-            (?\⒴ "(y)")
-            (?\⒵ "(z)")
-            (?\Ⓐ "A-o")
-            (?\Ⓑ "B-o")
-            (?\Ⓒ "C-o")
-            (?\Ⓓ "D-o")
-            (?\Ⓔ "E-o")
-            (?\Ⓕ "F-o")
-            (?\Ⓖ "G-o")
-            (?\Ⓗ "H-o")
-            (?\Ⓘ "I-o")
-            (?\Ⓙ "J-o")
-            (?\Ⓚ "K-o")
-            (?\Ⓛ "L-o")
-            (?\Ⓜ "M-o")
-            (?\Ⓝ "N-o")
-            (?\Ⓞ "O-o")
-            (?\Ⓟ "P-o")
-            (?\Ⓠ "Q-o")
-            (?\Ⓡ "R-o")
-            (?\Ⓢ "S-o")
-            (?\Ⓣ "T-o")
-            (?\Ⓤ "U-o")
-            (?\Ⓥ "V-o")
-            (?\Ⓦ "W-o")
-            (?\Ⓧ "X-o")
-            (?\Ⓨ "Y-o")
-            (?\Ⓩ "Z-o")
-            (?\ⓐ "a-o")
-            (?\ⓑ "b-o")
-            (?\ⓒ "c-o")
-            (?\ⓓ "d-o")
-            (?\ⓔ "e-o")
-            (?\ⓕ "f-o")
-            (?\ⓖ "g-o")
-            (?\ⓗ "h-o")
-            (?\ⓘ "i-o")
-            (?\ⓙ "j-o")
-            (?\ⓚ "k-o")
-            (?\ⓛ "l-o")
-            (?\ⓜ "m-o")
-            (?\ⓝ "n-o")
-            (?\ⓞ "o-o")
-            (?\ⓟ "p-o")
-            (?\ⓠ "q-o")
-            (?\ⓡ "r-o")
-            (?\ⓢ "s-o")
-            (?\ⓣ "t-o")
-            (?\ⓤ "u-o")
-            (?\ⓥ "v-o")
-            (?\ⓦ "w-o")
-            (?\ⓧ "x-o")
-            (?\ⓨ "y-o")
-            (?\ⓩ "z-o")
-            (?\⓪ "0-o")
-            (?\─ "-")
-            (?\━ "=")
-            (?\│ "|")
-            (?\┃ "|")
-            (?\┄ "-")
-            (?\┅ "=")
-            (?\┆ "|")
-            (?\┇ "|")
-            (?\┈ "-")
-            (?\┉ "=")
-            (?\┊ "|")
-            (?\┋ "|")
-            (?\┌ "+")
-            (?\┍ "+")
-            (?\┎ "+")
-            (?\┏ "+")
-            (?\┐ "+")
-            (?\┑ "+")
-            (?\┒ "+")
-            (?\┓ "+")
-            (?\└ "+")
-            (?\┕ "+")
-            (?\┖ "+")
-            (?\┗ "+")
-            (?\┘ "+")
-            (?\┙ "+")
-            (?\┚ "+")
-            (?\┛ "+")
-            (?\├ "+")
-            (?\┝ "+")
-            (?\┞ "+")
-            (?\┟ "+")
-            (?\┠ "+")
-            (?\┡ "+")
-            (?\┢ "+")
-            (?\┣ "+")
-            (?\┤ "+")
-            (?\┥ "+")
-            (?\┦ "+")
-            (?\┧ "+")
-            (?\┨ "+")
-            (?\┩ "+")
-            (?\┪ "+")
-            (?\┫ "+")
-            (?\┬ "+")
-            (?\┭ "+")
-            (?\┮ "+")
-            (?\┯ "+")
-            (?\┰ "+")
-            (?\┱ "+")
-            (?\┲ "+")
-            (?\┳ "+")
-            (?\┴ "+")
-            (?\┵ "+")
-            (?\┶ "+")
-            (?\┷ "+")
-            (?\┸ "+")
-            (?\┹ "+")
-            (?\┺ "+")
-            (?\┻ "+")
-            (?\┼ "+")
-            (?\┽ "+")
-            (?\┾ "+")
-            (?\┿ "+")
-            (?\╀ "+")
-            (?\╁ "+")
-            (?\╂ "+")
-            (?\╃ "+")
-            (?\╄ "+")
-            (?\╅ "+")
-            (?\╆ "+")
-            (?\╇ "+")
-            (?\╈ "+")
-            (?\╉ "+")
-            (?\╊ "+")
-            (?\╋ "+")
-            (?\╌ "+")
-            (?\╍ "+")
-            (?\╎ "+")
-            (?\╏ "+")
-            (?\═ "+")
-            (?\║ "+")
-            (?\╒ "+")
-            (?\╓ "+")
-            (?\╔ "+")
-            (?\╕ "+")
-            (?\╖ "+")
-            (?\╗ "+")
-            (?\╘ "+")
-            (?\╙ "+")
-            (?\╚ "+")
-            (?\╛ "+")
-            (?\╜ "+")
-            (?\╝ "+")
-            (?\╞ "+")
-            (?\╟ "+")
-            (?\╠ "+")
-            (?\╡ "+")
-            (?\╢ "+")
-            (?\╣ "+")
-            (?\╤ "+")
-            (?\╥ "+")
-            (?\╦ "+")
-            (?\╧ "+")
-            (?\╨ "+")
-            (?\╩ "+")
-            (?\╪ "+")
-            (?\╫ "+")
-            (?\╬ "+")
-            (?\╱ "/")
-            (?\╲ "\\")
-            (?\▀ "TB")
-            (?\▄ "LB")
-            (?\█ "FB")
-            (?\▌ "lB")
-            (?\▐ "RB")
-            (?\░ ".S")
-            (?\▒ ":S")
-            (?\▓ "?S")
-            (?\■ "fS")
-            (?\□ "OS")
-            (?\▢ "RO")
-            (?\▣ "Rr")
-            (?\▤ "RF")
-            (?\▥ "RY")
-            (?\▦ "RH")
-            (?\▧ "RZ")
-            (?\▨ "RK")
-            (?\▩ "RX")
-            (?\▪ "sB")
-            (?\▬ "SR")
-            (?\▭ "Or")
-            (?\▲ "^")
-            (?\△ "uT")
-            (?\▶ "|>")
-            (?\▷ "Tr")
-            (?\► "|>")
-            (?\▼ "v")
-            (?\▽ "dT")
-            (?\◀ "<|")
-            (?\◁ "Tl")
-            (?\◄ "<|")
-            (?\◆ "Db")
-            (?\◇ "Dw")
-            (?\◊ "LZ")
-            (?\○ "0m")
-            (?\◎ "0o")
-            (?\● "0M")
-            (?\◐ "0L")
-            (?\◑ "0R")
-            (?\◘ "Sn")
-            (?\◙ "Ic")
-            (?\◢ "Fd")
-            (?\◣ "Bd")
-            (?\◯ "Ci")
-            (?\★ "*2")
-            (?\☆ "*1")
-            (?\☎ "TEL")
-            (?\☏ "tel")
-            (?\☜ "<--")
-            (?\☞ "-->")
-            (?\☡ "CAUTION ")
-            (?\☧ "XP")
-            (?\☹ ":-(")
-            (?\☺ ":-)")
-            (?\☻ "(-:")
-            (?\☼ "SU")
-            (?\♀ "f.")
-            (?\♂ "m.")
-            (?\♠ "cS")
-            (?\♡ "cH")
-            (?\♢ "cD")
-            (?\♣ "cC")
-            (?\♤ "cS-")
-            (?\♥ "cH-")
-            (?\♦ "cD-")
-            (?\♧ "cC-")
-            (?\♩ "Md")
-            (?\♪ "M8")
-            (?\♫ "M2")
-            (?\♬ "M16")
-            (?\♭ "b")
-            (?\♮ "Mx")
-            (?\♯ "#")
-            (?\✓ "X")
-            (?\✗ "X")
-            (?\✠ "-X")
-            (?\  " ")
-            (?\、 ",_")
-            (?\。 "._")
-            (?\〃 "+\"")
-            (?\〄 "JIS")
-            (?\々 "*_")
-            (?\〆 ";_")
-            (?\〇 "0_")
-            (?\《 "<+")
-            (?\》 ">+")
-            (?\「 "<'")
-            (?\」 ">'")
-            (?\『 "<\"")
-            (?\』 ">\"")
-            (?\【 "(\"")
-            (?\】 ")\"")
-            (?\〒 "=T")
-            (?\〓 "=_")
-            (?\〔 "('")
-            (?\〕 ")'")
-            (?\〖 "(I")
-            (?\〗 ")I")
-            (?\〚 "[[")
-            (?\〛 "]]")
-            (?\〜 "-?")
-            (?\〠 "=T:)")
-            (?\〿 " ")
-            (?\ぁ "A5")
-            (?\あ "a5")
-            (?\ぃ "I5")
-            (?\い "i5")
-            (?\ぅ "U5")
-            (?\う "u5")
-            (?\ぇ "E5")
-            (?\え "e5")
-            (?\ぉ "O5")
-            (?\お "o5")
-            (?\か "ka")
-            (?\が "ga")
-            (?\き "ki")
-            (?\ぎ "gi")
-            (?\く "ku")
-            (?\ぐ "gu")
-            (?\け "ke")
-            (?\げ "ge")
-            (?\こ "ko")
-            (?\ご "go")
-            (?\さ "sa")
-            (?\ざ "za")
-            (?\し "si")
-            (?\じ "zi")
-            (?\す "su")
-            (?\ず "zu")
-            (?\せ "se")
-            (?\ぜ "ze")
-            (?\そ "so")
-            (?\ぞ "zo")
-            (?\た "ta")
-            (?\だ "da")
-            (?\ち "ti")
-            (?\ぢ "di")
-            (?\っ "tU")
-            (?\つ "tu")
-            (?\づ "du")
-            (?\て "te")
-            (?\で "de")
-            (?\と "to")
-            (?\ど "do")
-            (?\な "na")
-            (?\に "ni")
-            (?\ぬ "nu")
-            (?\ね "ne")
-            (?\の "no")
-            (?\は "ha")
-            (?\ば "ba")
-            (?\ぱ "pa")
-            (?\ひ "hi")
-            (?\び "bi")
-            (?\ぴ "pi")
-            (?\ふ "hu")
-            (?\ぶ "bu")
-            (?\ぷ "pu")
-            (?\へ "he")
-            (?\べ "be")
-            (?\ぺ "pe")
-            (?\ほ "ho")
-            (?\ぼ "bo")
-            (?\ぽ "po")
-            (?\ま "ma")
-            (?\み "mi")
-            (?\む "mu")
-            (?\め "me")
-            (?\も "mo")
-            (?\ゃ "yA")
-            (?\や "ya")
-            (?\ゅ "yU")
-            (?\ゆ "yu")
-            (?\ょ "yO")
-            (?\よ "yo")
-            (?\ら "ra")
-            (?\り "ri")
-            (?\る "ru")
-            (?\れ "re")
-            (?\ろ "ro")
-            (?\ゎ "wA")
-            (?\わ "wa")
-            (?\ゐ "wi")
-            (?\ゑ "we")
-            (?\を "wo")
-            (?\ん "n5")
-            (?\ゔ "vu")
-            (?\゛ "\"5")
-            (?\゜ "05")
-            (?\ゝ "*5")
-            (?\ゞ "+5")
-            (?\ァ "a6")
-            (?\ア "A6")
-            (?\ィ "i6")
-            (?\イ "I6")
-            (?\ゥ "u6")
-            (?\ウ "U6")
-            (?\ェ "e6")
-            (?\エ "E6")
-            (?\ォ "o6")
-            (?\オ "O6")
-            (?\カ "Ka")
-            (?\ガ "Ga")
-            (?\キ "Ki")
-            (?\ギ "Gi")
-            (?\ク "Ku")
-            (?\グ "Gu")
-            (?\ケ "Ke")
-            (?\ゲ "Ge")
-            (?\コ "Ko")
-            (?\ゴ "Go")
-            (?\サ "Sa")
-            (?\ザ "Za")
-            (?\シ "Si")
-            (?\ジ "Zi")
-            (?\ス "Su")
-            (?\ズ "Zu")
-            (?\セ "Se")
-            (?\ゼ "Ze")
-            (?\ソ "So")
-            (?\ゾ "Zo")
-            (?\タ "Ta")
-            (?\ダ "Da")
-            (?\チ "Ti")
-            (?\ヂ "Di")
-            (?\ッ "TU")
-            (?\ツ "Tu")
-            (?\ヅ "Du")
-            (?\テ "Te")
-            (?\デ "De")
-            (?\ト "To")
-            (?\ド "Do")
-            (?\ナ "Na")
-            (?\ニ "Ni")
-            (?\ヌ "Nu")
-            (?\ネ "Ne")
-            (?\ノ "No")
-            (?\ハ "Ha")
-            (?\バ "Ba")
-            (?\パ "Pa")
-            (?\ヒ "Hi")
-            (?\ビ "Bi")
-            (?\ピ "Pi")
-            (?\フ "Hu")
-            (?\ブ "Bu")
-            (?\プ "Pu")
-            (?\ヘ "He")
-            (?\ベ "Be")
-            (?\ペ "Pe")
-            (?\ホ "Ho")
-            (?\ボ "Bo")
-            (?\ポ "Po")
-            (?\マ "Ma")
-            (?\ミ "Mi")
-            (?\ム "Mu")
-            (?\メ "Me")
-            (?\モ "Mo")
-            (?\ャ "YA")
-            (?\ヤ "Ya")
-            (?\ュ "YU")
-            (?\ユ "Yu")
-            (?\ョ "YO")
-            (?\ヨ "Yo")
-            (?\ラ "Ra")
-            (?\リ "Ri")
-            (?\ル "Ru")
-            (?\レ "Re")
-            (?\ロ "Ro")
-            (?\ヮ "WA")
-            (?\ワ "Wa")
-            (?\ヰ "Wi")
-            (?\ヱ "We")
-            (?\ヲ "Wo")
-            (?\ン "N6")
-            (?\ヴ "Vu")
-            (?\ヵ "KA")
-            (?\ヶ "KE")
-            (?\ヷ "Va")
-            (?\ヸ "Vi")
-            (?\ヹ "Ve")
-            (?\ヺ "Vo")
-            (?\・ ".6")
-            (?\ー "-6")
-            (?\ヽ "*6")
-            (?\ヾ "+6")
-            (?\ㄅ "b4")
-            (?\ㄆ "p4")
-            (?\ㄇ "m4")
-            (?\ㄈ "f4")
-            (?\ㄉ "d4")
-            (?\ㄊ "t4")
-            (?\ㄋ "n4")
-            (?\ㄌ "l4")
-            (?\ㄍ "g4")
-            (?\ㄎ "k4")
-            (?\ㄏ "h4")
-            (?\ㄐ "j4")
-            (?\ㄑ "q4")
-            (?\ㄒ "x4")
-            (?\ㄓ "zh")
-            (?\ㄔ "ch")
-            (?\ㄕ "sh")
-            (?\ㄖ "r4")
-            (?\ㄗ "z4")
-            (?\ㄘ "c4")
-            (?\ㄙ "s4")
-            (?\ㄚ "a4")
-            (?\ㄛ "o4")
-            (?\ㄜ "e4")
-            (?\ㄝ "eh4")
-            (?\ㄞ "ai")
-            (?\ㄟ "ei")
-            (?\ㄠ "au")
-            (?\ㄡ "ou")
-            (?\ㄢ "an")
-            (?\ㄣ "en")
-            (?\ㄤ "aN")
-            (?\ㄥ "eN")
-            (?\ㄦ "er")
-            (?\ㄧ "i4")
-            (?\ㄨ "u4")
-            (?\ㄩ "iu")
-            (?\ㄪ "v4")
-            (?\ㄫ "nG")
-            (?\ㄬ "gn")
-            (?\㈜ "(JU)")
-            (?\㈠ "1c")
-            (?\㈡ "2c")
-            (?\㈢ "3c")
-            (?\㈣ "4c")
-            (?\㈤ "5c")
-            (?\㈥ "6c")
-            (?\㈦ "7c")
-            (?\㈧ "8c")
-            (?\㈨ "9c")
-            (?\㈩ "10c")
-            (?\㉿ "KSC")
-            (?\㏂ "am")
-            (?\㏘ "pm")
-            (?\ff "ff")
-            (?\fi "fi")
-            (?\fl "fl")
-            (?\ffi "ffi")
-            (?\ffl "ffl")
-            (?\ſt "St")
-            (?\st "st")
-            (?\ﹽ "3+;")
-            (?\ﺂ "aM.")
-            (?\ﺄ "aH.")
-            (?\ﺈ "ah.")
-            (?\ﺍ "a+-")
-            (?\ﺎ "a+.")
-            (?\ﺏ "b+-")
-            (?\ﺐ "b+.")
-            (?\ﺑ "b+,")
-            (?\ﺒ "b+;")
-            (?\ﺓ "tm-")
-            (?\ﺔ "tm.")
-            (?\ﺕ "t+-")
-            (?\ﺖ "t+.")
-            (?\ﺗ "t+,")
-            (?\ﺘ "t+;")
-            (?\ﺙ "tk-")
-            (?\ﺚ "tk.")
-            (?\ﺛ "tk,")
-            (?\ﺜ "tk;")
-            (?\ﺝ "g+-")
-            (?\ﺞ "g+.")
-            (?\ﺟ "g+,")
-            (?\ﺠ "g+;")
-            (?\ﺡ "hk-")
-            (?\ﺢ "hk.")
-            (?\ﺣ "hk,")
-            (?\ﺤ "hk;")
-            (?\ﺥ "x+-")
-            (?\ﺦ "x+.")
-            (?\ﺧ "x+,")
-            (?\ﺨ "x+;")
-            (?\ﺩ "d+-")
-            (?\ﺪ "d+.")
-            (?\ﺫ "dk-")
-            (?\ﺬ "dk.")
-            (?\ﺭ "r+-")
-            (?\ﺮ "r+.")
-            (?\ﺯ "z+-")
-            (?\ﺰ "z+.")
-            (?\ﺱ "s+-")
-            (?\ﺲ "s+.")
-            (?\ﺳ "s+,")
-            (?\ﺴ "s+;")
-            (?\ﺵ "sn-")
-            (?\ﺶ "sn.")
-            (?\ﺷ "sn,")
-            (?\ﺸ "sn;")
-            (?\ﺹ "c+-")
-            (?\ﺺ "c+.")
-            (?\ﺻ "c+,")
-            (?\ﺼ "c+;")
-            (?\ﺽ "dd-")
-            (?\ﺾ "dd.")
-            (?\ﺿ "dd,")
-            (?\ﻀ "dd;")
-            (?\ﻁ "tj-")
-            (?\ﻂ "tj.")
-            (?\ﻃ "tj,")
-            (?\ﻄ "tj;")
-            (?\ﻅ "zH-")
-            (?\ﻆ "zH.")
-            (?\ﻇ "zH,")
-            (?\ﻈ "zH;")
-            (?\ﻉ "e+-")
-            (?\ﻊ "e+.")
-            (?\ﻋ "e+,")
-            (?\ﻌ "e+;")
-            (?\ﻍ "i+-")
-            (?\ﻎ "i+.")
-            (?\ﻏ "i+,")
-            (?\ﻐ "i+;")
-            (?\ﻑ "f+-")
-            (?\ﻒ "f+.")
-            (?\ﻓ "f+,")
-            (?\ﻔ "f+;")
-            (?\ﻕ "q+-")
-            (?\ﻖ "q+.")
-            (?\ﻗ "q+,")
-            (?\ﻘ "q+;")
-            (?\ﻙ "k+-")
-            (?\ﻚ "k+.")
-            (?\ﻛ "k+,")
-            (?\ﻜ "k+;")
-            (?\ﻝ "l+-")
-            (?\ﻞ "l+.")
-            (?\ﻟ "l+,")
-            (?\ﻠ "l+;")
-            (?\ﻡ "m+-")
-            (?\ﻢ "m+.")
-            (?\ﻣ "m+,")
-            (?\ﻤ "m+;")
-            (?\ﻥ "n+-")
-            (?\ﻦ "n+.")
-            (?\ﻧ "n+,")
-            (?\ﻨ "n+;")
-            (?\ﻩ "h+-")
-            (?\ﻪ "h+.")
-            (?\ﻫ "h+,")
-            (?\ﻬ "h+;")
-            (?\ﻭ "w+-")
-            (?\ﻮ "w+.")
-            (?\ﻯ "j+-")
-            (?\ﻰ "j+.")
-            (?\ﻱ "y+-")
-            (?\ﻲ "y+.")
-            (?\ﻳ "y+,")
-            (?\ﻴ "y+;")
-            (?\ﻵ "lM-")
-            (?\ﻶ "lM.")
-            (?\ﻷ "lH-")
-            (?\ﻸ "lH.")
-            (?\ﻹ "lh-")
-            (?\ﻺ "lh.")
-            (?\ﻻ "la-")
-            (?\ﻼ "la.")
-            (?\! "!")
-            (?\" "\"")
-            (?\# "#")
-            (?\$ "$")
-            (?\% "%")
-            (?\& "&")
-            (?\' "'")
-            (?\( "(")
-            (?\) ")")
-            (?\* "*")
-            (?\+ "+")
-            (?\, ",")
-            (?\- "-")
-            (?\. ".")
-            (?\/ "/")
-            (?\0 "0")
-            (?\1 "1")
-            (?\2 "2")
-            (?\3 "3")
-            (?\4 "4")
-            (?\5 "5")
-            (?\6 "6")
-            (?\7 "7")
-            (?\8 "8")
-            (?\9 "9")
-            (?\: ":")
-            (?\; ";")
-            (?\< "<")
-            (?\= "=")
-            (?\> ">")
-            (?\? "?")
-            (?\@ "@")
-            (?\A "A")
-            (?\B "B")
-            (?\C "C")
-            (?\D "D")
-            (?\E "E")
-            (?\F "F")
-            (?\G "G")
-            (?\H "H")
-            (?\I "I")
-            (?\J "J")
-            (?\K "K")
-            (?\L "L")
-            (?\M "M")
-            (?\N "N")
-            (?\O "O")
-            (?\P "P")
-            (?\Q "Q")
-            (?\R "R")
-            (?\S "S")
-            (?\T "T")
-            (?\U "U")
-            (?\V "V")
-            (?\W "W")
-            (?\X "X")
-            (?\Y "Y")
-            (?\Z "Z")
-            (?\[ "[")
-            (?\\ "\\")
-            (?\] "]")
-            (?\^ "^")
-            (?\_ "_")
-            (?\` "`")
-            (?\a "a")
-            (?\b "b")
-            (?\c "c")
-            (?\d "d")
-            (?\e "e")
-            (?\f "f")
-            (?\g "g")
-            (?\h "h")
-            (?\i "i")
-            (?\j "j")
-            (?\k "k")
-            (?\l "l")
-            (?\m "m")
-            (?\n "n")
-            (?\o "o")
-            (?\p "p")
-            (?\q "q")
-            (?\r "r")
-            (?\s "s")
-            (?\t "t")
-            (?\u "u")
-            (?\v "v")
-            (?\w "w")
-            (?\x "x")
-            (?\y "y")
-            (?\z "z")
-            (?\{ "{")
-            (?\| "|")
-            (?\} "}")
-            (?\~ "~")
-            (?\。 ".")
-            (?\「 "\"")
-            (?\」 "\"")
-            (?\、 ",")
-            ;; Not from Lynx
-            (? "")
-            (?� "?")))))
+      (let ((latin1-display-format "%s"))
+       (mapc
+        (lambda (l)
+           (or (char-displayable-p (car l))
+              (apply 'latin1-display-char l)))
+        ;; Table derived by running Lynx on a suitable list of
+        ;; characters in a utf-8 file, except for some added by
+        ;; hand at the end.
+        '((?\Ā "A")
+          (?\ā "a")
+          (?\Ă "A")
+          (?\ă "a")
+          (?\Ą "A")
+          (?\ą "a")
+          (?\Ć "C")
+          (?\ć "c")
+          (?\Ĉ "C")
+          (?\ĉ "c")
+          (?\Ċ "C")
+          (?\ċ "c")
+          (?\Č "C")
+          (?\č "c")
+          (?\Ď "D")
+          (?\ď "d")
+          (?\Đ "Ð")
+          (?\đ "d/")
+          (?\Ē "E")
+          (?\ē "e")
+          (?\Ĕ "E")
+          (?\ĕ "e")
+          (?\Ė "E")
+          (?\ė "e")
+          (?\Ę "E")
+          (?\ę "e")
+          (?\Ě "E")
+          (?\ě "e")
+          (?\Ĝ "G")
+          (?\ĝ "g")
+          (?\Ğ "G")
+          (?\ğ "g")
+          (?\Ġ "G")
+          (?\ġ "g")
+          (?\Ģ "G")
+          (?\ģ "g")
+          (?\Ĥ "H")
+          (?\ĥ "h")
+          (?\Ħ "H/")
+          (?\ħ "H")
+          (?\Ĩ "I")
+          (?\ĩ "i")
+          (?\Ī "I")
+          (?\ī "i")
+          (?\Ĭ "I")
+          (?\ĭ "i")
+          (?\Į "I")
+          (?\į "i")
+          (?\İ "I")
+          (?\ı "i")
+          (?\IJ "IJ")
+          (?\ij "ij")
+          (?\Ĵ "J")
+          (?\ĵ "j")
+          (?\Ķ "K")
+          (?\ķ "k")
+          (?\ĸ "kk")
+          (?\Ĺ "L")
+          (?\ĺ "l")
+          (?\Ļ "L")
+          (?\ļ "l")
+          (?\Ľ "L")
+          (?\ľ "l")
+          (?\Ŀ "L.")
+          (?\ŀ "l.")
+          (?\Ł "L/")
+          (?\ł "l/")
+          (?\Ń "N")
+          (?\ń "n")
+          (?\Ņ "N")
+          (?\ņ "n")
+          (?\Ň "N")
+          (?\ň "n")
+          (?\ʼn "'n")
+          (?\Ŋ "NG")
+          (?\ŋ "N")
+          (?\Ō "O")
+          (?\ō "o")
+          (?\Ŏ "O")
+          (?\ŏ "o")
+          (?\Ő "O\"")
+          (?\ő "o\"")
+          (?\Π"OE")
+          (?\œ "oe")
+          (?\Ŕ "R")
+          (?\ŕ "r")
+          (?\Ŗ "R")
+          (?\ŗ "r")
+          (?\Ř "R")
+          (?\ř "r")
+          (?\Ś "S")
+          (?\ś "s")
+          (?\Ŝ "S")
+          (?\ŝ "s")
+          (?\Ş "S")
+          (?\ş "s")
+          (?\Š "S")
+          (?\š "s")
+          (?\Ţ "T")
+          (?\ţ "t")
+          (?\Ť "T")
+          (?\ť "t")
+          (?\Ŧ "T/")
+          (?\ŧ "t/")
+          (?\Ũ "U")
+          (?\ũ "u")
+          (?\Ū "U")
+          (?\ū "u")
+          (?\Ŭ "U")
+          (?\ŭ "u")
+          (?\Ů "U")
+          (?\ů "u")
+          (?\Ű "U\"")
+          (?\ű "u\"")
+          (?\Ų "U")
+          (?\ų "u")
+          (?\Ŵ "W")
+          (?\ŵ "w")
+          (?\Ŷ "Y")
+          (?\ŷ "y")
+          (?\Ÿ "Y")
+          (?\Ź "Z")
+          (?\ź "z")
+          (?\Ż "Z")
+          (?\ż "z")
+          (?\Ž "Z")
+          (?\ž "z")
+          (?\ſ "s1")
+          (?\Ƈ "C2")
+          (?\ƈ "c2")
+          (?\Ƒ "F2")
+          (?\ƒ " f")
+          (?\Ƙ "K2")
+          (?\ƙ "k2")
+          (?\Ơ "O9")
+          (?\ơ "o9")
+          (?\Ƣ "OI")
+          (?\ƣ "oi")
+          (?\Ʀ "yr")
+          (?\Ư "U9")
+          (?\ư "u9")
+          (?\Ƶ "Z/")
+          (?\ƶ "z/")
+          (?\Ʒ "ED")
+          (?\Ǎ "A")
+          (?\ǎ "a")
+          (?\Ǐ "I")
+          (?\ǐ "i")
+          (?\Ǒ "O")
+          (?\ǒ "o")
+          (?\Ǔ "U")
+          (?\ǔ "u")
+          (?\Ǖ "U:-")
+          (?\ǖ "u:-")
+          (?\Ǘ "U:'")
+          (?\ǘ "u:'")
+          (?\Ǚ "U:<")
+          (?\ǚ "u:<")
+          (?\Ǜ "U:!")
+          (?\ǜ "u:!")
+          (?\Ǟ "A1")
+          (?\ǟ "a1")
+          (?\Ǡ "A7")
+          (?\ǡ "a7")
+          (?\Ǣ "A3")
+          (?\ǣ "a3")
+          (?\Ǥ "G/")
+          (?\ǥ "g/")
+          (?\Ǧ "G")
+          (?\ǧ "g")
+          (?\Ǩ "K")
+          (?\ǩ "k")
+          (?\Ǫ "O")
+          (?\ǫ "o")
+          (?\Ǭ "O1")
+          (?\ǭ "o1")
+          (?\Ǯ "EZ")
+          (?\ǯ "ez")
+          (?\ǰ "j")
+          (?\Ǵ "G")
+          (?\ǵ "g")
+          (?\Ǻ "AA'")
+          (?\ǻ "aa'")
+          (?\Ǽ "AE'")
+          (?\ǽ "ae'")
+          (?\Ǿ "O/'")
+          (?\ǿ "o/'")
+          (?\Ȁ "A!!")
+          (?\ȁ "a!!")
+          (?\Ȃ "A)")
+          (?\ȃ "a)")
+          (?\Ȅ "E!!")
+          (?\ȅ "e!!")
+          (?\Ȇ "E)")
+          (?\ȇ "e)")
+          (?\Ȉ "I!!")
+          (?\ȉ "i!!")
+          (?\Ȋ "I)")
+          (?\ȋ "i)")
+          (?\Ȍ "O!!")
+          (?\ȍ "o!!")
+          (?\Ȏ "O)")
+          (?\ȏ "o)")
+          (?\Ȑ "R!!")
+          (?\ȑ "r!!")
+          (?\Ȓ "R)")
+          (?\ȓ "r)")
+          (?\Ȕ "U!!")
+          (?\ȕ "u!!")
+          (?\Ȗ "U)")
+          (?\ȗ "u)")
+          (?\ȝ "Z")
+          (?\ɑ "A")
+          (?\ɒ "A.")
+          (?\ɓ "b`")
+          (?\ɔ "O")
+          (?\ɖ "d.")
+          (?\ɗ "d`")
+          (?\ɘ "@<umd>")
+          (?\ə "@")
+          (?\ɚ "R")
+          (?\ɛ "E")
+          (?\ɜ "V\"")
+          (?\ɝ "R<umd>")
+          (?\ɞ "O\"")
+          (?\ɟ "J")
+          (?\ɠ "g`")
+          (?\ɡ "g")
+          (?\ɢ "G")
+          (?\ɣ "Q")
+          (?\ɤ "o-")
+          (?\ɥ "j<rnd>")
+          (?\ɦ "h<?>")
+          (?\ɨ "i\"")
+          (?\ɩ "I")
+          (?\ɪ "I")
+          (?\ɫ "L")
+          (?\ɬ "L")
+          (?\ɭ "l.")
+          (?\ɮ "z<lat>")
+          (?\ɯ "u-")
+          (?\ɰ "j<vel>")
+          (?\ɱ "M")
+          (?\ɳ "n.")
+          (?\ɴ "n\"")
+          (?\ɵ "@.")
+          (?\ɶ "&.")
+          (?\ɷ "U")
+          (?\ɹ "r")
+          (?\ɺ "*<lat>")
+          (?\ɻ "r.")
+          (?\ɽ "*.")
+          (?\ɾ "*")
+          (?\ʀ "R")
+          (?\ʁ "g\"")
+          (?\ʂ "s.")
+          (?\ʃ "S")
+          (?\ʄ "J`")
+          (?\ʇ "t!")
+          (?\ʈ "t.")
+          (?\ʉ "u\"")
+          (?\ʊ "U")
+          (?\ʋ "r<lbd>")
+          (?\ʌ "V")
+          (?\ʍ "w<vls>")
+          (?\ʎ "l^")
+          (?\ʏ "I.")
+          (?\ʐ "z.")
+          (?\ʒ "Z")
+          (?\ʔ "?")
+          (?\ʕ "H<vcd>")
+          (?\ʖ "l!")
+          (?\ʗ "c!")
+          (?\ʘ "p!")
+          (?\ʙ "b<trl>")
+          (?\ʛ "G`")
+          (?\ʝ "j")
+          (?\ʞ "k!")
+          (?\ʟ "L")
+          (?\ʠ "q`")
+          (?\ʤ "d3")
+          (?\ʦ "ts")
+          (?\ʧ "tS")
+          (?\ʰ "<h>")
+          (?\ʱ "<?>")
+          (?\ʲ ";")
+          (?\ʳ "<r>")
+          (?\ʷ "<w>")
+          (?\ʻ ";S")
+          (?\ʼ "`")
+          (?\ˆ "^")
+          (?\ˇ "'<")
+          (?\ˈ "|")
+          (?\ˉ "1-")
+          (?\ˋ "1!")
+          (?\ː ":")
+          (?\ˑ ":\\")
+          (?\˖ "+")
+          (?\˗ "-")
+          (?\˘ "'(")
+          (?\˙ "'.")
+          (?\˚ "'0")
+          (?\˛ "';")
+          (?\˜ "~")
+          (?\˝ "'\"")
+          (?\˥ "_T")
+          (?\˦ "_H")
+          (?\˧ "_M")
+          (?\˨ "_L")
+          (?\˩ "_B")
+          (?\ˬ "_v")
+          (?\ˮ "''")
+          (?\̀ "`")
+          (?\́ "'")
+          (?\̂ "^")
+          (?\̃ "~")
+          (?\̄ "¯")
+          (?\̇ "·")
+          (?\̈ "¨")
+          (?\̊ "°")
+          (?\̋ "''")
+          (?\̍ "|")
+          (?\̎ "||")
+          (?\̏ "``")
+          (?\̡ ";")
+          (?\̢ ".")
+          (?\̣ ".")
+          (?\̤ "<?>")
+          (?\̥ "<o>")
+          (?\̦ ",")
+          (?\̧ "¸")
+          (?\̩ "-")
+          (?\̪ "[")
+          (?\̫ "<w>")
+          (?\̴ "~")
+          (?\̷ "/")
+          (?\̸ "/")
+          (?\̀ "`")
+          (?\́ "'")
+          (?\͂ "~")
+          (?\̈́ "'%")
+          (?\ͅ "j3")
+          (?\͇ "=")
+          (?\͠ "~~")
+          (?\ʹ "'")
+          (?\͵ ",")
+          (?\ͺ "j3")
+          (?\; "?%")
+          (?\΄ "'*")
+          (?\΅ "'%")
+          (?\Ά "A'")
+          (?\· "·")
+          (?\Έ "E'")
+          (?\Ή "Y%")
+          (?\Ί "I'")
+          (?\Ό "O'")
+          (?\Ύ "U%")
+          (?\Ώ "W%")
+          (?\ΐ "i3")
+          (?\Α "A")
+          (?\Β "B")
+          (?\Γ "G")
+          (?\Δ "D")
+          (?\Ε "E")
+          (?\Ζ "Z")
+          (?\Η "Y")
+          (?\Θ "TH")
+          (?\Ι "I")
+          (?\Κ "K")
+          (?\Λ "L")
+          (?\Μ "M")
+          (?\Ν "N")
+          (?\Ξ "C")
+          (?\Ο "O")
+          (?\Π "P")
+          (?\Ρ "R")
+          (?\Σ "S")
+          (?\Τ "T")
+          (?\Υ "U")
+          (?\Φ "F")
+          (?\Χ "X")
+          (?\Ψ "Q")
+          (?\Ω "W*")
+          (?\Ϊ "J")
+          (?\Ϋ "V*")
+          (?\ά "a'")
+          (?\έ "e'")
+          (?\ή "y%")
+          (?\ί "i'")
+          (?\ΰ "u3")
+          (?\α "a")
+          (?\β "b")
+          (?\γ "g")
+          (?\δ "d")
+          (?\ε "e")
+          (?\ζ "z")
+          (?\η "y")
+          (?\θ "th")
+          (?\ι "i")
+          (?\κ "k")
+          (?\λ "l")
+          (?\μ "µ")
+          (?\ν "n")
+          (?\ξ "c")
+          (?\ο "o")
+          (?\π "p")
+          (?\ρ "r")
+          (?\ς "*s")
+          (?\σ "s")
+          (?\τ "t")
+          (?\υ "u")
+          (?\φ "f")
+          (?\χ "x")
+          (?\ψ "q")
+          (?\ω "w")
+          (?\ϊ "j")
+          (?\ϋ "v*")
+          (?\ό "o'")
+          (?\ύ "u%")
+          (?\ώ "w%")
+          (?\ϐ "beta ")
+          (?\ϑ "theta ")
+          (?\ϒ "upsi ")
+          (?\ϕ "phi ")
+          (?\ϖ "pi ")
+          (?\ϗ "k.")
+          (?\Ϛ "T3")
+          (?\ϛ "t3")
+          (?\Ϝ "M3")
+          (?\ϝ "m3")
+          (?\Ϟ "K3")
+          (?\ϟ "k3")
+          (?\Ϡ "P3")
+          (?\ϡ "p3")
+          (?\ϰ "kappa ")
+          (?\ϱ "rho ")
+          (?\ϳ "J")
+          (?\ϴ "'%")
+          (?\ϵ "j3")
+          (?\Ё "IO")
+          (?\Ђ "D%")
+          (?\Ѓ "G%")
+          (?\Є "IE")
+          (?\Ѕ "DS")
+          (?\І "II")
+          (?\Ї "YI")
+          (?\Ј "J%")
+          (?\Љ "LJ")
+          (?\Њ "NJ")
+          (?\Ћ "Ts")
+          (?\Ќ "KJ")
+          (?\Ў "V%")
+          (?\Џ "DZ")
+          (?\А "A")
+          (?\Б "B")
+          (?\В "V")
+          (?\Г "G")
+          (?\Д "D")
+          (?\Е "E")
+          (?\Ж "ZH")
+          (?\З "Z")
+          (?\И "I")
+          (?\Й "J")
+          (?\К "K")
+          (?\Л "L")
+          (?\М "M")
+          (?\Н "N")
+          (?\О "O")
+          (?\П "P")
+          (?\Р "R")
+          (?\С "S")
+          (?\Т "T")
+          (?\У "U")
+          (?\Ф "F")
+          (?\Х "H")
+          (?\Ц "C")
+          (?\Ч "CH")
+          (?\Ш "SH")
+          (?\Щ "SCH")
+          (?\Ъ "\"")
+          (?\Ы "Y")
+          (?\Ь "'")
+          (?\Э "`E")
+          (?\Ю "YU")
+          (?\Я "YA")
+          (?\а "a")
+          (?\б "b")
+          (?\в "v")
+          (?\г "g")
+          (?\д "d")
+          (?\е "e")
+          (?\ж "zh")
+          (?\з "z")
+          (?\и "i")
+          (?\й "j")
+          (?\к "k")
+          (?\л "l")
+          (?\м "m")
+          (?\н "n")
+          (?\о "o")
+          (?\п "p")
+          (?\р "r")
+          (?\с "s")
+          (?\т "t")
+          (?\у "u")
+          (?\ф "f")
+          (?\х "h")
+          (?\ц "c")
+          (?\ч "ch")
+          (?\ш "sh")
+          (?\щ "sch")
+          (?\ъ "\"")
+          (?\ы "y")
+          (?\ь "'")
+          (?\э "`e")
+          (?\ю "yu")
+          (?\я "ya")
+          (?\ё "io")
+          (?\ђ "d%")
+          (?\ѓ "g%")
+          (?\є "ie")
+          (?\ѕ "ds")
+          (?\і "ii")
+          (?\ї "yi")
+          (?\ј "j%")
+          (?\љ "lj")
+          (?\њ "nj")
+          (?\ћ "ts")
+          (?\ќ "kj")
+          (?\ў "v%")
+          (?\џ "dz")
+          (?\Ѣ "Y3")
+          (?\ѣ "y3")
+          (?\Ѫ "O3")
+          (?\ѫ "o3")
+          (?\Ѳ "F3")
+          (?\ѳ "f3")
+          (?\Ѵ "V3")
+          (?\ѵ "v3")
+          (?\Ҁ "C3")
+          (?\ҁ "c3")
+          (?\Ґ "G3")
+          (?\ґ "g3")
+          (?\Ӕ "AE")
+          (?\ӕ "ae")
+          (?\ִ "i")
+          (?\ַ "a")
+          (?\ָ "o")
+          (?\ּ "u")
+          (?\ֿ "h")
+          (?\ׂ ":")
+          (?\א "#")
+          (?\ב "B+")
+          (?\ג "G+")
+          (?\ד "D+")
+          (?\ה "H+")
+          (?\ו "W+")
+          (?\ז "Z+")
+          (?\ח "X+")
+          (?\ט "Tj")
+          (?\י "J+")
+          (?\ך "K%")
+          (?\כ "K+")
+          (?\ל "L+")
+          (?\ם "M%")
+          (?\מ "M+")
+          (?\ן "N%")
+          (?\נ "N+")
+          (?\ס "S+")
+          (?\ע "E+")
+          (?\ף "P%")
+          (?\פ "P+")
+          (?\ץ "Zj")
+          (?\צ "ZJ")
+          (?\ק "Q+")
+          (?\ר "R+")
+          (?\ש "Sh")
+          (?\ת "T+")
+          (?\װ "v")
+          (?\ױ "oy")
+          (?\ײ "ey")
+          (?\، ",+")
+          (?\؛ ";+")
+          (?\؟ "?+")
+          (?\ء "H'")
+          (?\آ "aM")
+          (?\أ "aH")
+          (?\ؤ "wH")
+          (?\إ "ah")
+          (?\ئ "yH")
+          (?\ا "a+")
+          (?\ب "b+")
+          (?\ة "tm")
+          (?\ت "t+")
+          (?\ث "tk")
+          (?\ج "g+")
+          (?\ح "hk")
+          (?\خ "x+")
+          (?\د "d+")
+          (?\ذ "dk")
+          (?\ر "r+")
+          (?\ز "z+")
+          (?\س "s+")
+          (?\ش "sn")
+          (?\ص "c+")
+          (?\ض "dd")
+          (?\ط "tj")
+          (?\ظ "zH")
+          (?\ع "e+")
+          (?\غ "i+")
+          (?\ـ "++")
+          (?\ف "f+")
+          (?\ق "q+")
+          (?\ك "k+")
+          (?\ل "l+")
+          (?\م "m+")
+          (?\ن "n+")
+          (?\ه "h+")
+          (?\و "w+")
+          (?\ى "j+")
+          (?\ي "y+")
+          (?\ً ":+")
+          (?\ٌ "\"+")
+          (?\ٍ "=+")
+          (?\َ "/+")
+          (?\ُ "'+")
+          (?\ِ "1+")
+          (?\ّ "3+")
+          (?\ْ "0+")
+          (?\٠ "0a")
+          (?\١ "1a")
+          (?\٢ "2a")
+          (?\٣ "3a")
+          (?\٤ "4a")
+          (?\٥ "5a")
+          (?\٦ "6a")
+          (?\٧ "7a")
+          (?\٨ "8a")
+          (?\٩ "9a")
+          (?\ٰ "aS")
+          (?\پ "p+")
+          (?\ځ "hH")
+          (?\چ "tc")
+          (?\ژ "zj")
+          (?\ڤ "v+")
+          (?\گ "gf")
+          (?\۰ "0a")
+          (?\۱ "1a")
+          (?\۲ "2a")
+          (?\۳ "3a")
+          (?\۴ "4a")
+          (?\۵ "5a")
+          (?\۶ "6a")
+          (?\۷ "7a")
+          (?\۸ "8a")
+          (?\۹ "9a")
+          (?\ሀ "he")
+          (?\ሁ "hu")
+          (?\ሂ "hi")
+          (?\ሃ "ha")
+          (?\ሄ "hE")
+          (?\ህ "h")
+          (?\ሆ "ho")
+          (?\ለ "le")
+          (?\ሉ "lu")
+          (?\ሊ "li")
+          (?\ላ "la")
+          (?\ሌ "lE")
+          (?\ል "l")
+          (?\ሎ "lo")
+          (?\ሏ "lWa")
+          (?\ሐ "He")
+          (?\ሑ "Hu")
+          (?\ሒ "Hi")
+          (?\ሓ "Ha")
+          (?\ሔ "HE")
+          (?\ሕ "H")
+          (?\ሖ "Ho")
+          (?\ሗ "HWa")
+          (?\መ "me")
+          (?\ሙ "mu")
+          (?\ሚ "mi")
+          (?\ማ "ma")
+          (?\ሜ "mE")
+          (?\ም "m")
+          (?\ሞ "mo")
+          (?\ሟ "mWa")
+          (?\ሠ "`se")
+          (?\ሡ "`su")
+          (?\ሢ "`si")
+          (?\ሣ "`sa")
+          (?\ሤ "`sE")
+          (?\ሥ "`s")
+          (?\ሦ "`so")
+          (?\ሧ "`sWa")
+          (?\ረ "re")
+          (?\ሩ "ru")
+          (?\ሪ "ri")
+          (?\ራ "ra")
+          (?\ሬ "rE")
+          (?\ር "r")
+          (?\ሮ "ro")
+          (?\ሯ "rWa")
+          (?\ሰ "se")
+          (?\ሱ "su")
+          (?\ሲ "si")
+          (?\ሳ "sa")
+          (?\ሴ "sE")
+          (?\ስ "s")
+          (?\ሶ "so")
+          (?\ሷ "sWa")
+          (?\ሸ "xe")
+          (?\ሹ "xu")
+          (?\ሺ "xi")
+          (?\ሻ "xa")
+          (?\ሼ "xE")
+          (?\ሽ "xa")
+          (?\ሾ "xo")
+          (?\ሿ "xWa")
+          (?\ቀ "qe")
+          (?\ቁ "qu")
+          (?\ቂ "qi")
+          (?\ቃ "qa")
+          (?\ቄ "qE")
+          (?\ቅ "q")
+          (?\ቆ "qo")
+          (?\ቈ "qWe")
+          (?\ቊ "qWi")
+          (?\ቋ "qWa")
+          (?\ቌ "qWE")
+          (?\ቍ "qW")
+          (?\ቐ "Qe")
+          (?\ቑ "Qu")
+          (?\ቒ "Qi")
+          (?\ቓ "Qa")
+          (?\ቔ "QE")
+          (?\ቕ "Q")
+          (?\ቖ "Qo")
+          (?\ቘ "QWe")
+          (?\ቚ "QWi")
+          (?\ቛ "QWa")
+          (?\ቜ "QWE")
+          (?\ቝ "QW")
+          (?\በ "be")
+          (?\ቡ "bu")
+          (?\ቢ "bi")
+          (?\ባ "ba")
+          (?\ቤ "bE")
+          (?\ብ "b")
+          (?\ቦ "bo")
+          (?\ቧ "bWa")
+          (?\ቨ "ve")
+          (?\ቩ "vu")
+          (?\ቪ "vi")
+          (?\ቫ "va")
+          (?\ቬ "vE")
+          (?\ቭ "v")
+          (?\ቮ "vo")
+          (?\ቯ "vWa")
+          (?\ተ "te")
+          (?\ቱ "tu")
+          (?\ቲ "ti")
+          (?\ታ "ta")
+          (?\ቴ "tE")
+          (?\ት "t")
+          (?\ቶ "to")
+          (?\ቷ "tWa")
+          (?\ቸ "ce")
+          (?\ቹ "cu")
+          (?\ቺ "ci")
+          (?\ቻ "ca")
+          (?\ቼ "cE")
+          (?\ች "c")
+          (?\ቾ "co")
+          (?\ቿ "cWa")
+          (?\ኀ "`he")
+          (?\ኁ "`hu")
+          (?\ኂ "`hi")
+          (?\ኃ "`ha")
+          (?\ኄ "`hE")
+          (?\ኅ "`h")
+          (?\ኆ "`ho")
+          (?\ኈ "hWe")
+          (?\ኊ "hWi")
+          (?\ኋ "hWa")
+          (?\ኌ "hWE")
+          (?\ኍ "hW")
+          (?\ነ "na")
+          (?\ኑ "nu")
+          (?\ኒ "ni")
+          (?\ና "na")
+          (?\ኔ "nE")
+          (?\ን "n")
+          (?\ኖ "no")
+          (?\ኗ "nWa")
+          (?\ኘ "Ne")
+          (?\ኙ "Nu")
+          (?\ኚ "Ni")
+          (?\ኛ "Na")
+          (?\ኜ "NE")
+          (?\ኝ "N")
+          (?\ኞ "No")
+          (?\ኟ "NWa")
+          (?\አ "e")
+          (?\ኡ "u")
+          (?\ኢ "i")
+          (?\ኣ "a")
+          (?\ኤ "E")
+          (?\እ "I")
+          (?\ኦ "o")
+          (?\ኧ "e3")
+          (?\ከ "ke")
+          (?\ኩ "ku")
+          (?\ኪ "ki")
+          (?\ካ "ka")
+          (?\ኬ "kE")
+          (?\ክ "k")
+          (?\ኮ "ko")
+          (?\ኰ "kWe")
+          (?\ኲ "kWi")
+          (?\ኳ "kWa")
+          (?\ኴ "kWE")
+          (?\ኵ "kW")
+          (?\ኸ "Ke")
+          (?\ኹ "Ku")
+          (?\ኺ "Ki")
+          (?\ኻ "Ka")
+          (?\ኼ "KE")
+          (?\ኽ "K")
+          (?\ኾ "Ko")
+          (?\ዀ "KWe")
+          (?\ዂ "KWi")
+          (?\ዃ "KWa")
+          (?\ዄ "KWE")
+          (?\ዅ "KW")
+          (?\ወ "we")
+          (?\ዉ "wu")
+          (?\ዊ "wi")
+          (?\ዋ "wa")
+          (?\ዌ "wE")
+          (?\ው "w")
+          (?\ዎ "wo")
+          (?\ዐ "`e")
+          (?\ዑ "`u")
+          (?\ዒ "`i")
+          (?\ዓ "`a")
+          (?\ዔ "`E")
+          (?\ዕ "`I")
+          (?\ዖ "`o")
+          (?\ዘ "ze")
+          (?\ዙ "zu")
+          (?\ዚ "zi")
+          (?\ዛ "za")
+          (?\ዜ "zE")
+          (?\ዝ "z")
+          (?\ዞ "zo")
+          (?\ዟ "zWa")
+          (?\ዠ "Ze")
+          (?\ዡ "Zu")
+          (?\ዢ "Zi")
+          (?\ዣ "Za")
+          (?\ዤ "ZE")
+          (?\ዥ "Z")
+          (?\ዦ "Zo")
+          (?\ዧ "ZWa")
+          (?\የ "ye")
+          (?\ዩ "yu")
+          (?\ዪ "yi")
+          (?\ያ "ya")
+          (?\ዬ "yE")
+          (?\ይ "y")
+          (?\ዮ "yo")
+          (?\ዯ "yWa")
+          (?\ደ "de")
+          (?\ዱ "du")
+          (?\ዲ "di")
+          (?\ዳ "da")
+          (?\ዴ "dE")
+          (?\ድ "d")
+          (?\ዶ "do")
+          (?\ዷ "dWa")
+          (?\ዸ "De")
+          (?\ዹ "Du")
+          (?\ዺ "Di")
+          (?\ዻ "Da")
+          (?\ዼ "DE")
+          (?\ዽ "D")
+          (?\ዾ "Do")
+          (?\ዿ "DWa")
+          (?\ጀ "je")
+          (?\ጁ "ju")
+          (?\ጂ "ji")
+          (?\ጃ "ja")
+          (?\ጄ "jE")
+          (?\ጅ "j")
+          (?\ጆ "jo")
+          (?\ጇ "jWa")
+          (?\ገ "ga")
+          (?\ጉ "gu")
+          (?\ጊ "gi")
+          (?\ጋ "ga")
+          (?\ጌ "gE")
+          (?\ግ "g")
+          (?\ጎ "go")
+          (?\ጐ "gWu")
+          (?\ጒ "gWi")
+          (?\ጓ "gWa")
+          (?\ጔ "gWE")
+          (?\ጕ "gW")
+          (?\ጘ "Ge")
+          (?\ጙ "Gu")
+          (?\ጚ "Gi")
+          (?\ጛ "Ga")
+          (?\ጜ "GE")
+          (?\ጝ "G")
+          (?\ጞ "Go")
+          (?\ጟ "GWa")
+          (?\ጠ "Te")
+          (?\ጡ "Tu")
+          (?\ጢ "Ti")
+          (?\ጣ "Ta")
+          (?\ጤ "TE")
+          (?\ጥ "T")
+          (?\ጦ "To")
+          (?\ጧ "TWa")
+          (?\ጨ "Ce")
+          (?\ጩ "Ca")
+          (?\ጪ "Cu")
+          (?\ጫ "Ca")
+          (?\ጬ "CE")
+          (?\ጭ "C")
+          (?\ጮ "Co")
+          (?\ጯ "CWa")
+          (?\ጰ "Pe")
+          (?\ጱ "Pu")
+          (?\ጲ "Pi")
+          (?\ጳ "Pa")
+          (?\ጴ "PE")
+          (?\ጵ "P")
+          (?\ጶ "Po")
+          (?\ጷ "PWa")
+          (?\ጸ "SWe")
+          (?\ጹ "SWu")
+          (?\ጺ "SWi")
+          (?\ጻ "SWa")
+          (?\ጼ "SWE")
+          (?\ጽ "SW")
+          (?\ጾ "SWo")
+          (?\ጿ "SWa")
+          (?\ፀ "`Sa")
+          (?\ፁ "`Su")
+          (?\ፂ "`Si")
+          (?\ፃ "`Sa")
+          (?\ፄ "`SE")
+          (?\ፅ "`S")
+          (?\ፆ "`So")
+          (?\ፈ "fa")
+          (?\ፉ "fu")
+          (?\ፊ "fi")
+          (?\ፋ "fa")
+          (?\ፌ "fE")
+          (?\ፍ "o")
+          (?\ፎ "fo")
+          (?\ፏ "fWa")
+          (?\ፐ "pe")
+          (?\ፑ "pu")
+          (?\ፒ "pi")
+          (?\ፓ "pa")
+          (?\ፔ "pE")
+          (?\ፕ "p")
+          (?\ፖ "po")
+          (?\ፗ "pWa")
+          (?\ፘ "mYa")
+          (?\ፙ "rYa")
+          (?\ፚ "fYa")
+          (?\፠ " ")
+          (?\፡ ":")
+          (?\። "::")
+          (?\፣ ",")
+          (?\፤ ";")
+          (?\፥ "-:")
+          (?\፦ ":-")
+          (?\፧ "`?")
+          (?\፨ ":|:")
+          (?\፩ "`1")
+          (?\፪ "`2")
+          (?\፫ "`3")
+          (?\፬ "`4")
+          (?\፭ "`5")
+          (?\፮ "`6")
+          (?\፯ "`7")
+          (?\፰ "`8")
+          (?\፱ "`9")
+          (?\፲ "`10")
+          (?\፳ "`20")
+          (?\፴ "`30")
+          (?\፵ "`40")
+          (?\፶ "`50")
+          (?\፷ "`60")
+          (?\፸ "`70")
+          (?\፹ "`80")
+          (?\፺ "`90")
+          (?\፻ "`100")
+          (?\፼ "`10000")
+          (?\Ḁ "A-0")
+          (?\ḁ "a-0")
+          (?\Ḃ "B.")
+          (?\ḃ "b.")
+          (?\Ḅ "B-.")
+          (?\ḅ "b-.")
+          (?\Ḇ "B_")
+          (?\ḇ "b_")
+          (?\Ḉ "C,'")
+          (?\ḉ "c,'")
+          (?\Ḋ "D.")
+          (?\ḋ "d.")
+          (?\Ḍ "D-.")
+          (?\ḍ "d-.")
+          (?\Ḏ "D_")
+          (?\ḏ "d_")
+          (?\Ḑ "D,")
+          (?\ḑ "d,")
+          (?\Ḓ "D->")
+          (?\ḓ "d->")
+          (?\Ḕ "E-!")
+          (?\ḕ "e-!")
+          (?\Ḗ "E-'")
+          (?\ḗ "e-'")
+          (?\Ḙ "E->")
+          (?\ḙ "e->")
+          (?\Ḛ "E-?")
+          (?\ḛ "e-?")
+          (?\Ḝ "E,(")
+          (?\ḝ "e,(")
+          (?\Ḟ "F.")
+          (?\ḟ "f.")
+          (?\Ḡ "G-")
+          (?\ḡ "g-")
+          (?\Ḣ "H.")
+          (?\ḣ "h.")
+          (?\Ḥ "H-.")
+          (?\ḥ "h-.")
+          (?\Ḧ "H:")
+          (?\ḧ "h:")
+          (?\Ḩ "H,")
+          (?\ḩ "h,")
+          (?\Ḫ "H-(")
+          (?\ḫ "h-(")
+          (?\Ḭ "I-?")
+          (?\ḭ "i-?")
+          (?\Ḯ "I:'")
+          (?\ḯ "i:'")
+          (?\Ḱ "K'")
+          (?\ḱ "k'")
+          (?\Ḳ "K-.")
+          (?\ḳ "k-.")
+          (?\Ḵ "K_")
+          (?\ḵ "k_")
+          (?\Ḷ "L-.")
+          (?\ḷ "l-.")
+          (?\Ḹ "L--.")
+          (?\ḹ "l--.")
+          (?\Ḻ "L_")
+          (?\ḻ "l_")
+          (?\Ḽ "L->")
+          (?\ḽ "l->")
+          (?\Ḿ "M'")
+          (?\ḿ "m'")
+          (?\Ṁ "M.")
+          (?\ṁ "m.")
+          (?\Ṃ "M-.")
+          (?\ṃ "m-.")
+          (?\Ṅ "N.")
+          (?\ṅ "n.")
+          (?\Ṇ "N-.")
+          (?\ṇ "n-.")
+          (?\Ṉ "N_")
+          (?\ṉ "n_")
+          (?\Ṋ "N->")
+          (?\ṋ "n->")
+          (?\Ṍ "O?'")
+          (?\ṍ "o?'")
+          (?\Ṏ "O?:")
+          (?\ṏ "o?:")
+          (?\Ṑ "O-!")
+          (?\ṑ "o-!")
+          (?\Ṓ "O-'")
+          (?\ṓ "o-'")
+          (?\Ṕ "P'")
+          (?\ṕ "p'")
+          (?\Ṗ "P.")
+          (?\ṗ "p.")
+          (?\Ṙ "R.")
+          (?\ṙ "r.")
+          (?\Ṛ "R-.")
+          (?\ṛ "r-.")
+          (?\Ṝ "R--.")
+          (?\ṝ "r--.")
+          (?\Ṟ "R_")
+          (?\ṟ "r_")
+          (?\Ṡ "S.")
+          (?\ṡ "s.")
+          (?\Ṣ "S-.")
+          (?\ṣ "s-.")
+          (?\Ṥ "S'.")
+          (?\ṥ "s'.")
+          (?\Ṧ "S<.")
+          (?\ṧ "s<.")
+          (?\Ṩ "S.-.")
+          (?\ṩ "s.-.")
+          (?\Ṫ "T.")
+          (?\ṫ "t.")
+          (?\Ṭ "T-.")
+          (?\ṭ "t-.")
+          (?\Ṯ "T_")
+          (?\ṯ "t_")
+          (?\Ṱ "T->")
+          (?\ṱ "t->")
+          (?\Ṳ "U--:")
+          (?\ṳ "u--:")
+          (?\Ṵ "U-?")
+          (?\ṵ "u-?")
+          (?\Ṷ "U->")
+          (?\ṷ "u->")
+          (?\Ṹ "U?'")
+          (?\ṹ "u?'")
+          (?\Ṻ "U-:")
+          (?\ṻ "u-:")
+          (?\Ṽ "V?")
+          (?\ṽ "v?")
+          (?\Ṿ "V-.")
+          (?\ṿ "v-.")
+          (?\Ẁ "W!")
+          (?\ẁ "w!")
+          (?\Ẃ "W'")
+          (?\ẃ "w'")
+          (?\Ẅ "W:")
+          (?\ẅ "w:")
+          (?\Ẇ "W.")
+          (?\ẇ "w.")
+          (?\Ẉ "W-.")
+          (?\ẉ "w-.")
+          (?\Ẋ "X.")
+          (?\ẋ "x.")
+          (?\Ẍ "X:")
+          (?\ẍ "x:")
+          (?\Ẏ "Y.")
+          (?\ẏ "y.")
+          (?\Ẑ "Z>")
+          (?\ẑ "z>")
+          (?\Ẓ "Z-.")
+          (?\ẓ "z-.")
+          (?\Ẕ "Z_")
+          (?\ẕ "z_")
+          (?\ẖ "h_")
+          (?\ẗ "t:")
+          (?\ẘ "w0")
+          (?\ẙ "y0")
+          (?\Ạ "A-.")
+          (?\ạ "a-.")
+          (?\Ả "A2")
+          (?\ả "a2")
+          (?\Ấ "A>'")
+          (?\ấ "a>'")
+          (?\Ầ "A>!")
+          (?\ầ "a>!")
+          (?\Ẩ "A>2")
+          (?\ẩ "a>2")
+          (?\Ẫ "A>?")
+          (?\ẫ "a>?")
+          (?\Ậ "A>-.")
+          (?\ậ "a>-.")
+          (?\Ắ "A('")
+          (?\ắ "a('")
+          (?\Ằ "A(!")
+          (?\ằ "a(!")
+          (?\Ẳ "A(2")
+          (?\ẳ "a(2")
+          (?\Ẵ "A(?")
+          (?\ẵ "a(?")
+          (?\Ặ "A(-.")
+          (?\ặ "a(-.")
+          (?\Ẹ "E-.")
+          (?\ẹ "e-.")
+          (?\Ẻ "E2")
+          (?\ẻ "e2")
+          (?\Ẽ "E?")
+          (?\ẽ "e?")
+          (?\Ế "E>'")
+          (?\ế "e>'")
+          (?\Ề "E>!")
+          (?\ề "e>!")
+          (?\Ể "E>2")
+          (?\ể "e>2")
+          (?\Ễ "E>?")
+          (?\ễ "e>?")
+          (?\Ệ "E>-.")
+          (?\ệ "e>-.")
+          (?\Ỉ "I2")
+          (?\ỉ "i2")
+          (?\Ị "I-.")
+          (?\ị "i-.")
+          (?\Ọ "O-.")
+          (?\ọ "o-.")
+          (?\Ỏ "O2")
+          (?\ỏ "o2")
+          (?\Ố "O>'")
+          (?\ố "o>'")
+          (?\Ồ "O>!")
+          (?\ồ "o>!")
+          (?\Ổ "O>2")
+          (?\ổ "o>2")
+          (?\Ỗ "O>?")
+          (?\ỗ "o>?")
+          (?\Ộ "O>-.")
+          (?\ộ "o>-.")
+          (?\Ớ "O9'")
+          (?\ớ "o9'")
+          (?\Ờ "O9!")
+          (?\ờ "o9!")
+          (?\Ở "O92")
+          (?\ở "o92")
+          (?\Ỡ "O9?")
+          (?\ỡ "o9?")
+          (?\Ợ "O9-.")
+          (?\ợ "o9-.")
+          (?\Ụ "U-.")
+          (?\ụ "u-.")
+          (?\Ủ "U2")
+          (?\ủ "u2")
+          (?\Ứ "U9'")
+          (?\ứ "u9'")
+          (?\Ừ "U9!")
+          (?\ừ "u9!")
+          (?\Ử "U92")
+          (?\ử "u92")
+          (?\Ữ "U9?")
+          (?\ữ "u9?")
+          (?\Ự "U9-.")
+          (?\ự "u9-.")
+          (?\Ỳ "Y!")
+          (?\ỳ "y!")
+          (?\Ỵ "Y-.")
+          (?\ỵ "y-.")
+          (?\Ỷ "Y2")
+          (?\ỷ "y2")
+          (?\Ỹ "Y?")
+          (?\ỹ "y?")
+          (?\ἀ "a")
+          (?\ἁ "ha")
+          (?\ἂ "`a")
+          (?\ἃ "h`a")
+          (?\ἄ "a'")
+          (?\ἅ "ha'")
+          (?\ἆ "a~")
+          (?\ἇ "ha~")
+          (?\Ἀ "A")
+          (?\Ἁ "hA")
+          (?\Ἂ "`A")
+          (?\Ἃ "h`A")
+          (?\Ἄ "A'")
+          (?\Ἅ "hA'")
+          (?\Ἆ "A~")
+          (?\Ἇ "hA~")
+          (?\ἑ "he")
+          (?\Ἑ "hE")
+          (?\ἱ "hi")
+          (?\Ἱ "hI")
+          (?\ὁ "ho")
+          (?\Ὁ "hO")
+          (?\ὑ "hu")
+          (?\Ὑ "hU")
+          (?\᾿ ",,")
+          (?\῀ "?*")
+          (?\῁ "?:")
+          (?\῍ ",!")
+          (?\῎ ",'")
+          (?\῏ "?,")
+          (?\῝ ";!")
+          (?\῞ ";'")
+          (?\῟ "?;")
+          (?\ῥ "rh")
+          (?\Ῥ "Rh")
+          (?\῭ "!:")
+          (?\` "!*")
+          (?\῾ ";;")
+          (?\  " ")
+          (?\  "  ")
+          (?\  " ")
+          (?\  "  ")
+          (?\  " ")
+          (?\  " ")
+          (?\  " ")
+          (?\  " ")
+          (?\  " ")
+          (?\  " ")
+          (?\‐ "-")
+          (?\‑ "-")
+          (?\– "-")
+          (?\— "--")
+          (?\― "-")
+          (?\‖ "||")
+          (?\‗ "=2")
+          (?\‘ "`")
+          (?\’ "'")
+          (?\‚ "'")
+          (?\‛ "'")
+          (?\“ "\"")
+          (?\” "\"")
+          (?\„ "\"")
+          (?\‟ "\"")
+          (?\† "/-")
+          (?\‡ "/=")
+          (?\• " o ")
+          (?\․ ".")
+          (?\‥ "..")
+          (?\… "...")
+          (?\‧ "·")
+          (?\‰ " 0/00")
+          (?\′ "'")
+          (?\″ "''")
+          (?\‴ "'''")
+          (?\‵ "`")
+          (?\‶ "``")
+          (?\‷ "```")
+          (?\‸ "Ca")
+          (?\‹ "<")
+          (?\› ">")
+          (?\※ ":X")
+          (?\‼ "!!")
+          (?\‾ "'-")
+          (?\⁃ "-")
+          (?\⁄ "/")
+          (?\⁈ "?!")
+          (?\⁉ "!?")
+          (?\⁰ "^0")
+          (?\⁴ "^4")
+          (?\⁵ "^5")
+          (?\⁶ "^6")
+          (?\⁷ "^7")
+          (?\⁸ "^8")
+          (?\⁹ "^9")
+          (?\⁺ "^+")
+          (?\⁻ "^-")
+          (?\⁼ "^=")
+          (?\⁽ "^(")
+          (?\⁾ "^)")
+          (?\ⁿ "^n")
+          (?\₀ "_0")
+          (?\₁ "_1")
+          (?\₂ "_2")
+          (?\₃ "_3")
+          (?\₄ "_4")
+          (?\₅ "_5")
+          (?\₆ "_6")
+          (?\₇ "_7")
+          (?\₈ "_8")
+          (?\₉ "_9")
+          (?\₊ "_+")
+          (?\₋ "_-")
+          (?\₌ "_=")
+          (?\₍ "(")
+          (?\₎ ")")
+          (?\₣ "Ff")
+          (?\₤ "Li")
+          (?\₧ "Pt")
+          (?\₩ "W=")
+          (?\€ "EUR")
+          (?\℀ "a/c")
+          (?\℁ "a/s")
+          (?\℃ "oC")
+          (?\℅ "c/o")
+          (?\℆ "c/u")
+          (?\℉ "oF")
+          (?\ℊ "g")
+          (?\ℎ "h")
+          (?\ℏ "\\hbar")
+          (?\ℑ "Im")
+          (?\ℓ "l")
+          (?\№ "No.")
+          (?\℗ "PO")
+          (?\℘ "P")
+          (?\ℜ "Re")
+          (?\℞ "Rx")
+          (?\℠ "(SM)")
+          (?\℡ "TEL")
+          (?\™ "(TM)")
+          (?\Ω "Ohm")
+          (?\K "K")
+          (?\Å "Ang.")
+          (?\℮ "est.")
+          (?\ℴ "o")
+          (?\ℵ "Aleph ")
+          (?\ℶ "Bet ")
+          (?\ℷ "Gimel ")
+          (?\ℸ "Dalet ")
+          (?\⅓ " 1/3")
+          (?\⅔ " 2/3")
+          (?\⅕ " 1/5")
+          (?\⅖ " 2/5")
+          (?\⅗ " 3/5")
+          (?\⅘ " 4/5")
+          (?\⅙ " 1/6")
+          (?\⅚ " 5/6")
+          (?\⅛ " 1/8")
+          (?\⅜ " 3/8")
+          (?\⅝ " 5/8")
+          (?\⅞ " 7/8")
+          (?\⅟ " 1/")
+          (?\Ⅰ "I")
+          (?\Ⅱ "II")
+          (?\Ⅲ "III")
+          (?\Ⅳ "IV")
+          (?\Ⅴ "V")
+          (?\Ⅵ "VI")
+          (?\Ⅶ "VII")
+          (?\Ⅷ "VIII")
+          (?\Ⅸ "IX")
+          (?\Ⅹ "X")
+          (?\Ⅺ "XI")
+          (?\Ⅻ "XII")
+          (?\Ⅼ "L")
+          (?\Ⅽ "C")
+          (?\Ⅾ "D")
+          (?\Ⅿ "M")
+          (?\ⅰ "i")
+          (?\ⅱ "ii")
+          (?\ⅲ "iii")
+          (?\ⅳ "iv")
+          (?\ⅴ "v")
+          (?\ⅵ "vi")
+          (?\ⅶ "vii")
+          (?\ⅷ "viii")
+          (?\ⅸ "ix")
+          (?\ⅹ "x")
+          (?\ⅺ "xi")
+          (?\ⅻ "xii")
+          (?\ⅼ "l")
+          (?\ⅽ "c")
+          (?\ⅾ "d")
+          (?\ⅿ "m")
+          (?\ↀ "1000RCD")
+          (?\ↁ "5000R")
+          (?\ↂ "10000R")
+          (?\← "<-")
+          (?\↑ "-^")
+          (?\→ "->")
+          (?\↓ "-v")
+          (?\↔ "<->")
+          (?\↕ "UD")
+          (?\↖ "<!!")
+          (?\↗ "//>")
+          (?\↘ "!!>")
+          (?\↙ "<//")
+          (?\↨ "UD-")
+          (?\↵ "RET")
+          (?\⇀ ">V")
+          (?\⇐ "<=")
+          (?\⇑ "^^")
+          (?\⇒ "=>")
+          (?\⇓ "vv")
+          (?\⇔ "<=>")
+          (?\∀ "FA")
+          (?\∂ "\\partial")
+          (?\∃ "TE")
+          (?\∅ "{}")
+          (?\∆ "Delta")
+          (?\∇ "Nabla")
+          (?\∈ "(-")
+          (?\∉ "!(-")
+          (?\∊ "(-")
+          (?\∋ "-)")
+          (?\∌ "!-)")
+          (?\∍ "-)")
+          (?\∎ " qed")
+          (?\∏ "\\prod")
+          (?\∑ "\\sum")
+          (?\− " -")
+          (?\∓ "-/+")
+          (?\∔ ".+")
+          (?\∕ "/")
+          (?\∖ " - ")
+          (?\∗ "*")
+          (?\∘ " ° ")
+          (?\∙ "sb")
+          (?\√ " SQRT ")
+          (?\∛ " ROOT³ ")
+          (?\∜ " ROOT4 ")
+          (?\∝ "0(")
+          (?\∞ "infty")
+          (?\∟ "-L")
+          (?\∠ "-V")
+          (?\∥ "PP")
+          (?\∦ " !PP ")
+          (?\∧ "AND")
+          (?\∨ "OR")
+          (?\∩ "(U")
+          (?\∪ ")U")
+          (?\∫ "\\int ")
+          (?\∬ "DI")
+          (?\∮ "Io")
+          (?\∴ ".:")
+          (?\∵ ":.")
+          (?\∶ ":R")
+          (?\∷ "::")
+          (?\∼ "?1")
+          (?\∾ "CG")
+          (?\≃ "?-")
+          (?\≅ "?=")
+          (?\≈ "~=")
+          (?\≉ " !~= ")
+          (?\≌ "=?")
+          (?\≓ "HI")
+          (?\≔ ":=")
+          (?\≕ "=:")
+          (?\≠ "!=")
+          (?\≡ "=3")
+          (?\≢ " !=3 ")
+          (?\≤ "=<")
+          (?\≥ ">=")
+          (?\≦ ".LE.")
+          (?\≧ ".GE.")
+          (?\≨ ".LT.NOT.EQ.")
+          (?\≩ ".GT.NOT.EQ.")
+          (?\≪ "<<")
+          (?\≫ ">>")
+          (?\≮ "!<")
+          (?\≯ "!>")
+          (?\≶ " <> ")
+          (?\≷ " >< ")
+          (?\⊂ "(C")
+          (?\⊃ ")C")
+          (?\⊄ " !(C ")
+          (?\⊅ " !)C ")
+          (?\⊆ "(_")
+          (?\⊇ ")_")
+          (?\⊕ "(+)")
+          (?\⊖ "(-)")
+          (?\⊗ "(×)")
+          (?\⊘ "(/)")
+          (?\⊙ "(·)")
+          (?\⊚ "(°)")
+          (?\⊛ "(*)")
+          (?\⊜ "(=)")
+          (?\⊝ "(-)")
+          (?\⊞ "[+]")
+          (?\⊟ "[-]")
+          (?\⊠ "[×]")
+          (?\⊡ "[·]")
+          (?\⊥ "-T")
+          (?\⊧ " MODELS ")
+          (?\⊨ " TRUE ")
+          (?\⊩ " FORCES ")
+          (?\⊬ " !PROVES ")
+          (?\⊭ " NOT TRUE ")
+          (?\⊮ " !FORCES ")
+          (?\⊲ " NORMAL SUBGROUP OF ")
+          (?\⊳ " CONTAINS AS NORMAL SUBGROUP ")
+          (?\⊴ " NORMAL SUBGROUP OF OR EQUAL TO ")
+          (?\⊵ " CONTAINS AS NORMAL SUBGROUP OR EQUAL TO ")
+          (?\⊸ " MULTIMAP ")
+          (?\⊺ " INTERCALATE ")
+          (?\⊻ " XOR ")
+          (?\⊼ " NAND ")
+          (?\⋅ " · ")
+          (?\⋖ "<.")
+          (?\⋗ ">.")
+          (?\⋘ "<<<")
+          (?\⋙ ">>>")
+          (?\⋮ ":3")
+          (?\⋯ ".3")
+          (?\⌂ "Eh")
+          (?\⌇ "~~")
+          (?\⌈ "<7")
+          (?\⌉ ">7")
+          (?\⌊ "7<")
+          (?\⌋ "7>")
+          (?\⌐ "NI")
+          (?\⌒ "(A")
+          (?\⌕ "TR")
+          (?\⌘ "88")
+          (?\⌠ "Iu")
+          (?\⌡ "Il")
+          (?\⌢ ":(")
+          (?\⌣ ":)")
+          (?\⌤ "|^|")
+          (?\⌧ "[X]")
+          (?\〈 "</")
+          (?\〉 "/>")
+          (?\␣ "Vs")
+          (?\⑀ "1h")
+          (?\⑁ "3h")
+          (?\⑂ "2h")
+          (?\⑃ "4h")
+          (?\⑆ "1j")
+          (?\⑇ "2j")
+          (?\⑈ "3j")
+          (?\⑉ "4j")
+          (?\① "1-o")
+          (?\② "2-o")
+          (?\③ "3-o")
+          (?\④ "4-o")
+          (?\⑤ "5-o")
+          (?\⑥ "6-o")
+          (?\⑦ "7-o")
+          (?\⑧ "8-o")
+          (?\⑨ "9-o")
+          (?\⑩ "10-o")
+          (?\⑪ "11-o")
+          (?\⑫ "12-o")
+          (?\⑬ "13-o")
+          (?\⑭ "14-o")
+          (?\⑮ "15-o")
+          (?\⑯ "16-o")
+          (?\⑰ "17-o")
+          (?\⑱ "18-o")
+          (?\⑲ "19-o")
+          (?\⑳ "20-o")
+          (?\⑴ "(1)")
+          (?\⑵ "(2)")
+          (?\⑶ "(3)")
+          (?\⑷ "(4)")
+          (?\⑸ "(5)")
+          (?\⑹ "(6)")
+          (?\⑺ "(7)")
+          (?\⑻ "(8)")
+          (?\⑼ "(9)")
+          (?\⑽ "(10)")
+          (?\⑾ "(11)")
+          (?\⑿ "(12)")
+          (?\⒀ "(13)")
+          (?\⒁ "(14)")
+          (?\⒂ "(15)")
+          (?\⒃ "(16)")
+          (?\⒄ "(17)")
+          (?\⒅ "(18)")
+          (?\⒆ "(19)")
+          (?\⒇ "(20)")
+          (?\⒈ "1.")
+          (?\⒉ "2.")
+          (?\⒊ "3.")
+          (?\⒋ "4.")
+          (?\⒌ "5.")
+          (?\⒍ "6.")
+          (?\⒎ "7.")
+          (?\⒏ "8.")
+          (?\⒐ "9.")
+          (?\⒑ "10.")
+          (?\⒒ "11.")
+          (?\⒓ "12.")
+          (?\⒔ "13.")
+          (?\⒕ "14.")
+          (?\⒖ "15.")
+          (?\⒗ "16.")
+          (?\⒘ "17.")
+          (?\⒙ "18.")
+          (?\⒚ "19.")
+          (?\⒛ "20.")
+          (?\⒜ "(a)")
+          (?\⒝ "(b)")
+          (?\⒞ "(c)")
+          (?\⒟ "(d)")
+          (?\⒠ "(e)")
+          (?\⒡ "(f)")
+          (?\⒢ "(g)")
+          (?\⒣ "(h)")
+          (?\⒤ "(i)")
+          (?\⒥ "(j)")
+          (?\⒦ "(k)")
+          (?\⒧ "(l)")
+          (?\⒨ "(m)")
+          (?\⒩ "(n)")
+          (?\⒪ "(o)")
+          (?\⒫ "(p)")
+          (?\⒬ "(q)")
+          (?\⒭ "(r)")
+          (?\⒮ "(s)")
+          (?\⒯ "(t)")
+          (?\⒰ "(u)")
+          (?\⒱ "(v)")
+          (?\⒲ "(w)")
+          (?\⒳ "(x)")
+          (?\⒴ "(y)")
+          (?\⒵ "(z)")
+          (?\Ⓐ "A-o")
+          (?\Ⓑ "B-o")
+          (?\Ⓒ "C-o")
+          (?\Ⓓ "D-o")
+          (?\Ⓔ "E-o")
+          (?\Ⓕ "F-o")
+          (?\Ⓖ "G-o")
+          (?\Ⓗ "H-o")
+          (?\Ⓘ "I-o")
+          (?\Ⓙ "J-o")
+          (?\Ⓚ "K-o")
+          (?\Ⓛ "L-o")
+          (?\Ⓜ "M-o")
+          (?\Ⓝ "N-o")
+          (?\Ⓞ "O-o")
+          (?\Ⓟ "P-o")
+          (?\Ⓠ "Q-o")
+          (?\Ⓡ "R-o")
+          (?\Ⓢ "S-o")
+          (?\Ⓣ "T-o")
+          (?\Ⓤ "U-o")
+          (?\Ⓥ "V-o")
+          (?\Ⓦ "W-o")
+          (?\Ⓧ "X-o")
+          (?\Ⓨ "Y-o")
+          (?\Ⓩ "Z-o")
+          (?\ⓐ "a-o")
+          (?\ⓑ "b-o")
+          (?\ⓒ "c-o")
+          (?\ⓓ "d-o")
+          (?\ⓔ "e-o")
+          (?\ⓕ "f-o")
+          (?\ⓖ "g-o")
+          (?\ⓗ "h-o")
+          (?\ⓘ "i-o")
+          (?\ⓙ "j-o")
+          (?\ⓚ "k-o")
+          (?\ⓛ "l-o")
+          (?\ⓜ "m-o")
+          (?\ⓝ "n-o")
+          (?\ⓞ "o-o")
+          (?\ⓟ "p-o")
+          (?\ⓠ "q-o")
+          (?\ⓡ "r-o")
+          (?\ⓢ "s-o")
+          (?\ⓣ "t-o")
+          (?\ⓤ "u-o")
+          (?\ⓥ "v-o")
+          (?\ⓦ "w-o")
+          (?\ⓧ "x-o")
+          (?\ⓨ "y-o")
+          (?\ⓩ "z-o")
+          (?\⓪ "0-o")
+          (?\─ "-")
+          (?\━ "=")
+          (?\│ "|")
+          (?\┃ "|")
+          (?\┄ "-")
+          (?\┅ "=")
+          (?\┆ "|")
+          (?\┇ "|")
+          (?\┈ "-")
+          (?\┉ "=")
+          (?\┊ "|")
+          (?\┋ "|")
+          (?\┌ "+")
+          (?\┍ "+")
+          (?\┎ "+")
+          (?\┏ "+")
+          (?\┐ "+")
+          (?\┑ "+")
+          (?\┒ "+")
+          (?\┓ "+")
+          (?\└ "+")
+          (?\┕ "+")
+          (?\┖ "+")
+          (?\┗ "+")
+          (?\┘ "+")
+          (?\┙ "+")
+          (?\┚ "+")
+          (?\┛ "+")
+          (?\├ "+")
+          (?\┝ "+")
+          (?\┞ "+")
+          (?\┟ "+")
+          (?\┠ "+")
+          (?\┡ "+")
+          (?\┢ "+")
+          (?\┣ "+")
+          (?\┤ "+")
+          (?\┥ "+")
+          (?\┦ "+")
+          (?\┧ "+")
+          (?\┨ "+")
+          (?\┩ "+")
+          (?\┪ "+")
+          (?\┫ "+")
+          (?\┬ "+")
+          (?\┭ "+")
+          (?\┮ "+")
+          (?\┯ "+")
+          (?\┰ "+")
+          (?\┱ "+")
+          (?\┲ "+")
+          (?\┳ "+")
+          (?\┴ "+")
+          (?\┵ "+")
+          (?\┶ "+")
+          (?\┷ "+")
+          (?\┸ "+")
+          (?\┹ "+")
+          (?\┺ "+")
+          (?\┻ "+")
+          (?\┼ "+")
+          (?\┽ "+")
+          (?\┾ "+")
+          (?\┿ "+")
+          (?\╀ "+")
+          (?\╁ "+")
+          (?\╂ "+")
+          (?\╃ "+")
+          (?\╄ "+")
+          (?\╅ "+")
+          (?\╆ "+")
+          (?\╇ "+")
+          (?\╈ "+")
+          (?\╉ "+")
+          (?\╊ "+")
+          (?\╋ "+")
+          (?\╌ "+")
+          (?\╍ "+")
+          (?\╎ "+")
+          (?\╏ "+")
+          (?\═ "+")
+          (?\║ "+")
+          (?\╒ "+")
+          (?\╓ "+")
+          (?\╔ "+")
+          (?\╕ "+")
+          (?\╖ "+")
+          (?\╗ "+")
+          (?\╘ "+")
+          (?\╙ "+")
+          (?\╚ "+")
+          (?\╛ "+")
+          (?\╜ "+")
+          (?\╝ "+")
+          (?\╞ "+")
+          (?\╟ "+")
+          (?\╠ "+")
+          (?\╡ "+")
+          (?\╢ "+")
+          (?\╣ "+")
+          (?\╤ "+")
+          (?\╥ "+")
+          (?\╦ "+")
+          (?\╧ "+")
+          (?\╨ "+")
+          (?\╩ "+")
+          (?\╪ "+")
+          (?\╫ "+")
+          (?\╬ "+")
+          (?\╱ "/")
+          (?\╲ "\\")
+          (?\▀ "TB")
+          (?\▄ "LB")
+          (?\█ "FB")
+          (?\▌ "lB")
+          (?\▐ "RB")
+          (?\░ ".S")
+          (?\▒ ":S")
+          (?\▓ "?S")
+          (?\■ "fS")
+          (?\□ "OS")
+          (?\▢ "RO")
+          (?\▣ "Rr")
+          (?\▤ "RF")
+          (?\▥ "RY")
+          (?\▦ "RH")
+          (?\▧ "RZ")
+          (?\▨ "RK")
+          (?\▩ "RX")
+          (?\▪ "sB")
+          (?\▬ "SR")
+          (?\▭ "Or")
+          (?\▲ "^")
+          (?\△ "uT")
+          (?\▶ "|>")
+          (?\▷ "Tr")
+          (?\► "|>")
+          (?\▼ "v")
+          (?\▽ "dT")
+          (?\◀ "<|")
+          (?\◁ "Tl")
+          (?\◄ "<|")
+          (?\◆ "Db")
+          (?\◇ "Dw")
+          (?\◊ "LZ")
+          (?\○ "0m")
+          (?\◎ "0o")
+          (?\● "0M")
+          (?\◐ "0L")
+          (?\◑ "0R")
+          (?\◘ "Sn")
+          (?\◙ "Ic")
+          (?\◢ "Fd")
+          (?\◣ "Bd")
+          (?\◯ "Ci")
+          (?\★ "*2")
+          (?\☆ "*1")
+          (?\☎ "TEL")
+          (?\☏ "tel")
+          (?\☜ "<--")
+          (?\☞ "-->")
+          (?\☡ "CAUTION ")
+          (?\☧ "XP")
+          (?\☹ ":-(")
+          (?\☺ ":-)")
+          (?\☻ "(-:")
+          (?\☼ "SU")
+          (?\♀ "f.")
+          (?\♂ "m.")
+          (?\♠ "cS")
+          (?\♡ "cH")
+          (?\♢ "cD")
+          (?\♣ "cC")
+          (?\♤ "cS-")
+          (?\♥ "cH-")
+          (?\♦ "cD-")
+          (?\♧ "cC-")
+          (?\♩ "Md")
+          (?\♪ "M8")
+          (?\♫ "M2")
+          (?\♬ "M16")
+          (?\♭ "b")
+          (?\♮ "Mx")
+          (?\♯ "#")
+          (?\✓ "X")
+          (?\✗ "X")
+          (?\✠ "-X")
+          (?\  " ")
+          (?\、 ",_")
+          (?\。 "._")
+          (?\〃 "+\"")
+          (?\〄 "JIS")
+          (?\々 "*_")
+          (?\〆 ";_")
+          (?\〇 "0_")
+          (?\《 "<+")
+          (?\》 ">+")
+          (?\「 "<'")
+          (?\」 ">'")
+          (?\『 "<\"")
+          (?\』 ">\"")
+          (?\【 "(\"")
+          (?\】 ")\"")
+          (?\〒 "=T")
+          (?\〓 "=_")
+          (?\〔 "('")
+          (?\〕 ")'")
+          (?\〖 "(I")
+          (?\〗 ")I")
+          (?\〚 "[[")
+          (?\〛 "]]")
+          (?\〜 "-?")
+          (?\〠 "=T:)")
+          (?\〿 " ")
+          (?\ぁ "A5")
+          (?\あ "a5")
+          (?\ぃ "I5")
+          (?\い "i5")
+          (?\ぅ "U5")
+          (?\う "u5")
+          (?\ぇ "E5")
+          (?\え "e5")
+          (?\ぉ "O5")
+          (?\お "o5")
+          (?\か "ka")
+          (?\が "ga")
+          (?\き "ki")
+          (?\ぎ "gi")
+          (?\く "ku")
+          (?\ぐ "gu")
+          (?\け "ke")
+          (?\げ "ge")
+          (?\こ "ko")
+          (?\ご "go")
+          (?\さ "sa")
+          (?\ざ "za")
+          (?\し "si")
+          (?\じ "zi")
+          (?\す "su")
+          (?\ず "zu")
+          (?\せ "se")
+          (?\ぜ "ze")
+          (?\そ "so")
+          (?\ぞ "zo")
+          (?\た "ta")
+          (?\だ "da")
+          (?\ち "ti")
+          (?\ぢ "di")
+          (?\っ "tU")
+          (?\つ "tu")
+          (?\づ "du")
+          (?\て "te")
+          (?\で "de")
+          (?\と "to")
+          (?\ど "do")
+          (?\な "na")
+          (?\に "ni")
+          (?\ぬ "nu")
+          (?\ね "ne")
+          (?\の "no")
+          (?\は "ha")
+          (?\ば "ba")
+          (?\ぱ "pa")
+          (?\ひ "hi")
+          (?\び "bi")
+          (?\ぴ "pi")
+          (?\ふ "hu")
+          (?\ぶ "bu")
+          (?\ぷ "pu")
+          (?\へ "he")
+          (?\べ "be")
+          (?\ぺ "pe")
+          (?\ほ "ho")
+          (?\ぼ "bo")
+          (?\ぽ "po")
+          (?\ま "ma")
+          (?\み "mi")
+          (?\む "mu")
+          (?\め "me")
+          (?\も "mo")
+          (?\ゃ "yA")
+          (?\や "ya")
+          (?\ゅ "yU")
+          (?\ゆ "yu")
+          (?\ょ "yO")
+          (?\よ "yo")
+          (?\ら "ra")
+          (?\り "ri")
+          (?\る "ru")
+          (?\れ "re")
+          (?\ろ "ro")
+          (?\ゎ "wA")
+          (?\わ "wa")
+          (?\ゐ "wi")
+          (?\ゑ "we")
+          (?\を "wo")
+          (?\ん "n5")
+          (?\ゔ "vu")
+          (?\゛ "\"5")
+          (?\゜ "05")
+          (?\ゝ "*5")
+          (?\ゞ "+5")
+          (?\ァ "a6")
+          (?\ア "A6")
+          (?\ィ "i6")
+          (?\イ "I6")
+          (?\ゥ "u6")
+          (?\ウ "U6")
+          (?\ェ "e6")
+          (?\エ "E6")
+          (?\ォ "o6")
+          (?\オ "O6")
+          (?\カ "Ka")
+          (?\ガ "Ga")
+          (?\キ "Ki")
+          (?\ギ "Gi")
+          (?\ク "Ku")
+          (?\グ "Gu")
+          (?\ケ "Ke")
+          (?\ゲ "Ge")
+          (?\コ "Ko")
+          (?\ゴ "Go")
+          (?\サ "Sa")
+          (?\ザ "Za")
+          (?\シ "Si")
+          (?\ジ "Zi")
+          (?\ス "Su")
+          (?\ズ "Zu")
+          (?\セ "Se")
+          (?\ゼ "Ze")
+          (?\ソ "So")
+          (?\ゾ "Zo")
+          (?\タ "Ta")
+          (?\ダ "Da")
+          (?\チ "Ti")
+          (?\ヂ "Di")
+          (?\ッ "TU")
+          (?\ツ "Tu")
+          (?\ヅ "Du")
+          (?\テ "Te")
+          (?\デ "De")
+          (?\ト "To")
+          (?\ド "Do")
+          (?\ナ "Na")
+          (?\ニ "Ni")
+          (?\ヌ "Nu")
+          (?\ネ "Ne")
+          (?\ノ "No")
+          (?\ハ "Ha")
+          (?\バ "Ba")
+          (?\パ "Pa")
+          (?\ヒ "Hi")
+          (?\ビ "Bi")
+          (?\ピ "Pi")
+          (?\フ "Hu")
+          (?\ブ "Bu")
+          (?\プ "Pu")
+          (?\ヘ "He")
+          (?\ベ "Be")
+          (?\ペ "Pe")
+          (?\ホ "Ho")
+          (?\ボ "Bo")
+          (?\ポ "Po")
+          (?\マ "Ma")
+          (?\ミ "Mi")
+          (?\ム "Mu")
+          (?\メ "Me")
+          (?\モ "Mo")
+          (?\ャ "YA")
+          (?\ヤ "Ya")
+          (?\ュ "YU")
+          (?\ユ "Yu")
+          (?\ョ "YO")
+          (?\ヨ "Yo")
+          (?\ラ "Ra")
+          (?\リ "Ri")
+          (?\ル "Ru")
+          (?\レ "Re")
+          (?\ロ "Ro")
+          (?\ヮ "WA")
+          (?\ワ "Wa")
+          (?\ヰ "Wi")
+          (?\ヱ "We")
+          (?\ヲ "Wo")
+          (?\ン "N6")
+          (?\ヴ "Vu")
+          (?\ヵ "KA")
+          (?\ヶ "KE")
+          (?\ヷ "Va")
+          (?\ヸ "Vi")
+          (?\ヹ "Ve")
+          (?\ヺ "Vo")
+          (?\・ ".6")
+          (?\ー "-6")
+          (?\ヽ "*6")
+          (?\ヾ "+6")
+          (?\ㄅ "b4")
+          (?\ㄆ "p4")
+          (?\ㄇ "m4")
+          (?\ㄈ "f4")
+          (?\ㄉ "d4")
+          (?\ㄊ "t4")
+          (?\ㄋ "n4")
+          (?\ㄌ "l4")
+          (?\ㄍ "g4")
+          (?\ㄎ "k4")
+          (?\ㄏ "h4")
+          (?\ㄐ "j4")
+          (?\ㄑ "q4")
+          (?\ㄒ "x4")
+          (?\ㄓ "zh")
+          (?\ㄔ "ch")
+          (?\ㄕ "sh")
+          (?\ㄖ "r4")
+          (?\ㄗ "z4")
+          (?\ㄘ "c4")
+          (?\ㄙ "s4")
+          (?\ㄚ "a4")
+          (?\ㄛ "o4")
+          (?\ㄜ "e4")
+          (?\ㄝ "eh4")
+          (?\ㄞ "ai")
+          (?\ㄟ "ei")
+          (?\ㄠ "au")
+          (?\ㄡ "ou")
+          (?\ㄢ "an")
+          (?\ㄣ "en")
+          (?\ㄤ "aN")
+          (?\ㄥ "eN")
+          (?\ㄦ "er")
+          (?\ㄧ "i4")
+          (?\ㄨ "u4")
+          (?\ㄩ "iu")
+          (?\ㄪ "v4")
+          (?\ㄫ "nG")
+          (?\ㄬ "gn")
+          (?\㈜ "(JU)")
+          (?\㈠ "1c")
+          (?\㈡ "2c")
+          (?\㈢ "3c")
+          (?\㈣ "4c")
+          (?\㈤ "5c")
+          (?\㈥ "6c")
+          (?\㈦ "7c")
+          (?\㈧ "8c")
+          (?\㈨ "9c")
+          (?\㈩ "10c")
+          (?\㉿ "KSC")
+          (?\㏂ "am")
+          (?\㏘ "pm")
+          (?\ff "ff")
+          (?\fi "fi")
+          (?\fl "fl")
+          (?\ffi "ffi")
+          (?\ffl "ffl")
+          (?\ſt "St")
+          (?\st "st")
+          (?\ﹽ "3+;")
+          (?\ﺂ "aM.")
+          (?\ﺄ "aH.")
+          (?\ﺈ "ah.")
+          (?\ﺍ "a+-")
+          (?\ﺎ "a+.")
+          (?\ﺏ "b+-")
+          (?\ﺐ "b+.")
+          (?\ﺑ "b+,")
+          (?\ﺒ "b+;")
+          (?\ﺓ "tm-")
+          (?\ﺔ "tm.")
+          (?\ﺕ "t+-")
+          (?\ﺖ "t+.")
+          (?\ﺗ "t+,")
+          (?\ﺘ "t+;")
+          (?\ﺙ "tk-")
+          (?\ﺚ "tk.")
+          (?\ﺛ "tk,")
+          (?\ﺜ "tk;")
+          (?\ﺝ "g+-")
+          (?\ﺞ "g+.")
+          (?\ﺟ "g+,")
+          (?\ﺠ "g+;")
+          (?\ﺡ "hk-")
+          (?\ﺢ "hk.")
+          (?\ﺣ "hk,")
+          (?\ﺤ "hk;")
+          (?\ﺥ "x+-")
+          (?\ﺦ "x+.")
+          (?\ﺧ "x+,")
+          (?\ﺨ "x+;")
+          (?\ﺩ "d+-")
+          (?\ﺪ "d+.")
+          (?\ﺫ "dk-")
+          (?\ﺬ "dk.")
+          (?\ﺭ "r+-")
+          (?\ﺮ "r+.")
+          (?\ﺯ "z+-")
+          (?\ﺰ "z+.")
+          (?\ﺱ "s+-")
+          (?\ﺲ "s+.")
+          (?\ﺳ "s+,")
+          (?\ﺴ "s+;")
+          (?\ﺵ "sn-")
+          (?\ﺶ "sn.")
+          (?\ﺷ "sn,")
+          (?\ﺸ "sn;")
+          (?\ﺹ "c+-")
+          (?\ﺺ "c+.")
+          (?\ﺻ "c+,")
+          (?\ﺼ "c+;")
+          (?\ﺽ "dd-")
+          (?\ﺾ "dd.")
+          (?\ﺿ "dd,")
+          (?\ﻀ "dd;")
+          (?\ﻁ "tj-")
+          (?\ﻂ "tj.")
+          (?\ﻃ "tj,")
+          (?\ﻄ "tj;")
+          (?\ﻅ "zH-")
+          (?\ﻆ "zH.")
+          (?\ﻇ "zH,")
+          (?\ﻈ "zH;")
+          (?\ﻉ "e+-")
+          (?\ﻊ "e+.")
+          (?\ﻋ "e+,")
+          (?\ﻌ "e+;")
+          (?\ﻍ "i+-")
+          (?\ﻎ "i+.")
+          (?\ﻏ "i+,")
+          (?\ﻐ "i+;")
+          (?\ﻑ "f+-")
+          (?\ﻒ "f+.")
+          (?\ﻓ "f+,")
+          (?\ﻔ "f+;")
+          (?\ﻕ "q+-")
+          (?\ﻖ "q+.")
+          (?\ﻗ "q+,")
+          (?\ﻘ "q+;")
+          (?\ﻙ "k+-")
+          (?\ﻚ "k+.")
+          (?\ﻛ "k+,")
+          (?\ﻜ "k+;")
+          (?\ﻝ "l+-")
+          (?\ﻞ "l+.")
+          (?\ﻟ "l+,")
+          (?\ﻠ "l+;")
+          (?\ﻡ "m+-")
+          (?\ﻢ "m+.")
+          (?\ﻣ "m+,")
+          (?\ﻤ "m+;")
+          (?\ﻥ "n+-")
+          (?\ﻦ "n+.")
+          (?\ﻧ "n+,")
+          (?\ﻨ "n+;")
+          (?\ﻩ "h+-")
+          (?\ﻪ "h+.")
+          (?\ﻫ "h+,")
+          (?\ﻬ "h+;")
+          (?\ﻭ "w+-")
+          (?\ﻮ "w+.")
+          (?\ﻯ "j+-")
+          (?\ﻰ "j+.")
+          (?\ﻱ "y+-")
+          (?\ﻲ "y+.")
+          (?\ﻳ "y+,")
+          (?\ﻴ "y+;")
+          (?\ﻵ "lM-")
+          (?\ﻶ "lM.")
+          (?\ﻷ "lH-")
+          (?\ﻸ "lH.")
+          (?\ﻹ "lh-")
+          (?\ﻺ "lh.")
+          (?\ﻻ "la-")
+          (?\ﻼ "la.")
+          (?\! "!")
+          (?\" "\"")
+          (?\# "#")
+          (?\$ "$")
+          (?\% "%")
+          (?\& "&")
+          (?\' "'")
+          (?\( "(")
+          (?\) ")")
+          (?\* "*")
+          (?\+ "+")
+          (?\, ",")
+          (?\- "-")
+          (?\. ".")
+          (?\/ "/")
+          (?\0 "0")
+          (?\1 "1")
+          (?\2 "2")
+          (?\3 "3")
+          (?\4 "4")
+          (?\5 "5")
+          (?\6 "6")
+          (?\7 "7")
+          (?\8 "8")
+          (?\9 "9")
+          (?\: ":")
+          (?\; ";")
+          (?\< "<")
+          (?\= "=")
+          (?\> ">")
+          (?\? "?")
+          (?\@ "@")
+          (?\A "A")
+          (?\B "B")
+          (?\C "C")
+          (?\D "D")
+          (?\E "E")
+          (?\F "F")
+          (?\G "G")
+          (?\H "H")
+          (?\I "I")
+          (?\J "J")
+          (?\K "K")
+          (?\L "L")
+          (?\M "M")
+          (?\N "N")
+          (?\O "O")
+          (?\P "P")
+          (?\Q "Q")
+          (?\R "R")
+          (?\S "S")
+          (?\T "T")
+          (?\U "U")
+          (?\V "V")
+          (?\W "W")
+          (?\X "X")
+          (?\Y "Y")
+          (?\Z "Z")
+          (?\[ "[")
+          (?\\ "\\")
+          (?\] "]")
+          (?\^ "^")
+          (?\_ "_")
+          (?\` "`")
+          (?\a "a")
+          (?\b "b")
+          (?\c "c")
+          (?\d "d")
+          (?\e "e")
+          (?\f "f")
+          (?\g "g")
+          (?\h "h")
+          (?\i "i")
+          (?\j "j")
+          (?\k "k")
+          (?\l "l")
+          (?\m "m")
+          (?\n "n")
+          (?\o "o")
+          (?\p "p")
+          (?\q "q")
+          (?\r "r")
+          (?\s "s")
+          (?\t "t")
+          (?\u "u")
+          (?\v "v")
+          (?\w "w")
+          (?\x "x")
+          (?\y "y")
+          (?\z "z")
+          (?\{ "{")
+          (?\| "|")
+          (?\} "}")
+          (?\~ "~")
+          (?\。 ".")
+          (?\「 "\"")
+          (?\」 "\"")
+          (?\、 ",")
+          ;; Not from Lynx
+          (? "")
+          (?� "?"))))
     (aset standard-display-table
          (make-char 'mule-unicode-0100-24ff) nil)
     (aset standard-display-table
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 833d031c56..8970216398 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -430,13 +430,13 @@ and doesn't remove full-buffer highlighting after a 
search."
 
 (defface lazy-highlight
   '((((class color) (min-colors 88) (background light))
-     (:background "paleturquoise"))
+     (:background "paleturquoise" :distant-foreground "black"))
     (((class color) (min-colors 88) (background dark))
-     (:background "paleturquoise4"))
+     (:background "paleturquoise4" :distant-foreground "white"))
     (((class color) (min-colors 16))
-     (:background "turquoise3"))
+     (:background "turquoise3" :distant-foreground "white"))
     (((class color) (min-colors 8))
-     (:background "turquoise3"))
+     (:background "turquoise3" :distant-foreground "white"))
     (t (:underline t)))
   "Face for lazy highlighting of matches other than the current one."
   :group 'lazy-highlight
@@ -2934,6 +2934,7 @@ to the barrier."
 (put 'scroll-other-window-down 'isearch-scroll t)
 (put 'beginning-of-buffer-other-window 'isearch-scroll t)
 (put 'end-of-buffer-other-window 'isearch-scroll t)
+(put 'recenter-other-window 'isearch-scroll t)
 
 ;; Commands which change the window layout
 (put 'delete-other-windows 'isearch-scroll t)
@@ -2948,6 +2949,9 @@ to the barrier."
 (put 'mouse-drag-mode-line 'isearch-scroll t)
 (put 'mouse-drag-vertical-line 'isearch-scroll t)
 
+;; For context menu with isearch submenu
+(put 'context-menu-open 'isearch-scroll t)
+
 ;; Aliases for split-window-*
 (put 'split-window-vertically 'isearch-scroll t)
 (put 'split-window-horizontally 'isearch-scroll t)
diff --git a/lisp/language/indian.el b/lisp/language/indian.el
index 614d0767e7..e0adb0de6c 100644
--- a/lisp/language/indian.el
+++ b/lisp/language/indian.el
@@ -354,14 +354,14 @@ South Indian language Malayalam is supported in this 
language environment."))
           ("X" . "[\u0D00-\u0D7F]"))))           ; all coverage
     (indian-compose-regexp
      (concat
+      ;; any sequence of 2 or more Malayalam characters, or
+      "XX+\\|"
       ;; consonant-based syllables, or
       "C\\(?:J?HJ?C\\)*\\(?:H[NJ]?\\|v?A?\\)\\|"
       ;; syllables with an independent vowel, or
       "V\\(?:J?HY\\)?v*?A?\\|"
-      ;; special consonant form, or
-      "JHY\\|"
-      ;; any other singleton characters
-      "X")
+      ;; special consonant form
+      "JHY")
      table))
   "Regexp matching a composable sequence of Malayalam characters.")
 
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index 6ddce2eba3..9f5169605b 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -8580,8 +8580,8 @@ Locate SOA record and increment the serial field." t nil)
 
 (autoload 'doc-view-mode-p "doc-view" "\
 Return non-nil if document type TYPE is available for `doc-view'.
-Document types are symbols like `dvi', `ps', `pdf', or `odf' (any
-OpenDocument format).
+Document types are symbols like `dvi', `ps', `pdf', `epub',
+`cbz', `fb2', `xps', `oxps', or`odf' (any OpenDocument format).
 
 \(fn TYPE)" nil nil)
 
@@ -10409,6 +10409,14 @@ displayed." t nil)
 
 ;;;***
 
+;;;### (autoloads nil "em-extpipe" "eshell/em-extpipe.el" (0 0 0
+;;;;;;  0))
+;;; Generated autoloads from eshell/em-extpipe.el
+
+(register-definition-prefixes "em-extpipe" '("eshell-"))
+
+;;;***
+
 ;;;### (autoloads nil "emacs-lock" "emacs-lock.el" (0 0 0 0))
 ;;; Generated autoloads from emacs-lock.el
 
@@ -13923,11 +13931,11 @@ and choose the directory as the fortune-file.
 ;;;### (autoloads nil "frameset" "frameset.el" (0 0 0 0))
 ;;; Generated autoloads from frameset.el
 
-(defvar frameset-session-filter-alist '((name . :never) (left . 
frameset-filter-iconified) (minibuffer . frameset-filter-minibuffer) (top . 
frameset-filter-iconified)) "\
+(defvar frameset-session-filter-alist (append '((left . 
frameset-filter-iconified) (minibuffer . frameset-filter-minibuffer) (top . 
frameset-filter-iconified)) (mapcar (lambda (p) (cons p :never)) 
frame-internal-parameters)) "\
 Minimum set of parameters to filter for live (on-session) framesets.
 DO NOT MODIFY.  See `frameset-filter-alist' for a full description.")
 
-(defvar frameset-persistent-filter-alist (append '((background-color . 
frameset-filter-sanitize-color) (buffer-list . :never) (buffer-predicate . 
:never) (buried-buffer-list . :never) (client . :never) (delete-before . 
:never) (font . frameset-filter-font-param) (font-backend . :never) 
(foreground-color . frameset-filter-sanitize-color) 
(frameset--text-pixel-height . :save) (frameset--text-pixel-width . :save) 
(fullscreen . frameset-filter-shelve-param) (GUI:font . frameset-filter-unshel 
[...]
+(defvar frameset-persistent-filter-alist (append '((background-color . 
frameset-filter-sanitize-color) (buffer-list . :never) (buffer-predicate . 
:never) (buried-buffer-list . :never) (client . :never) (delete-before . 
:never) (font . frameset-filter-font-param) (font-backend . :never) 
(foreground-color . frameset-filter-sanitize-color) 
(frameset--text-pixel-height . :save) (frameset--text-pixel-width . :save) 
(fullscreen . frameset-filter-shelve-param) (GUI:font . frameset-filter-unshel 
[...]
 Parameters to filter for persistent framesets.
 DO NOT MODIFY.  See `frameset-filter-alist' for a full description.")
 
@@ -40107,23 +40115,24 @@ Zone out, completely." t nil)
 
 ;;;### (autoloads nil nil ("abbrev.el" "bindings.el" "buff-menu.el"
 ;;;;;;  "button.el" "calc/calc-aent.el" "calc/calc-embed.el" 
"calc/calc-misc.el"
-;;;;;;  "calc/calc-yank.el" "case-table.el" "cedet/ede/cpp-root.el"
-;;;;;;  "cedet/ede/custom.el" "cedet/ede/dired.el" "cedet/ede/emacs.el"
-;;;;;;  "cedet/ede/files.el" "cedet/ede/generic.el" "cedet/ede/linux.el"
-;;;;;;  "cedet/ede/locate.el" "cedet/ede/make.el" "cedet/ede/speedbar.el"
-;;;;;;  "cedet/ede/system.el" "cedet/ede/util.el" "cedet/semantic/analyze.el"
-;;;;;;  "cedet/semantic/analyze/complete.el" "cedet/semantic/analyze/refs.el"
-;;;;;;  "cedet/semantic/bovine.el" "cedet/semantic/bovine/c-by.el"
-;;;;;;  "cedet/semantic/bovine/c.el" "cedet/semantic/bovine/el.el"
-;;;;;;  "cedet/semantic/bovine/gcc.el" "cedet/semantic/bovine/make-by.el"
-;;;;;;  "cedet/semantic/bovine/make.el" "cedet/semantic/bovine/scm-by.el"
-;;;;;;  "cedet/semantic/bovine/scm.el" "cedet/semantic/complete.el"
-;;;;;;  "cedet/semantic/ctxt.el" "cedet/semantic/db-file.el" 
"cedet/semantic/db-find.el"
-;;;;;;  "cedet/semantic/db-global.el" "cedet/semantic/db-mode.el"
-;;;;;;  "cedet/semantic/db-typecache.el" "cedet/semantic/db.el" 
"cedet/semantic/debug.el"
-;;;;;;  "cedet/semantic/decorate/include.el" "cedet/semantic/decorate/mode.el"
-;;;;;;  "cedet/semantic/dep.el" "cedet/semantic/doc.el" 
"cedet/semantic/edit.el"
-;;;;;;  "cedet/semantic/find.el" "cedet/semantic/format.el" 
"cedet/semantic/grammar-wy.el"
+;;;;;;  "calc/calc-yank.el" "case-table.el" "cedet/ede/base.el" 
"cedet/ede/config.el"
+;;;;;;  "cedet/ede/cpp-root.el" "cedet/ede/custom.el" "cedet/ede/dired.el"
+;;;;;;  "cedet/ede/emacs.el" "cedet/ede/files.el" "cedet/ede/generic.el"
+;;;;;;  "cedet/ede/linux.el" "cedet/ede/locate.el" "cedet/ede/make.el"
+;;;;;;  "cedet/ede/shell.el" "cedet/ede/speedbar.el" "cedet/ede/system.el"
+;;;;;;  "cedet/ede/util.el" "cedet/semantic/analyze.el" 
"cedet/semantic/analyze/complete.el"
+;;;;;;  "cedet/semantic/analyze/refs.el" "cedet/semantic/bovine.el"
+;;;;;;  "cedet/semantic/bovine/c-by.el" "cedet/semantic/bovine/c.el"
+;;;;;;  "cedet/semantic/bovine/el.el" "cedet/semantic/bovine/gcc.el"
+;;;;;;  "cedet/semantic/bovine/make-by.el" "cedet/semantic/bovine/make.el"
+;;;;;;  "cedet/semantic/bovine/scm-by.el" "cedet/semantic/bovine/scm.el"
+;;;;;;  "cedet/semantic/complete.el" "cedet/semantic/ctxt.el" 
"cedet/semantic/db-file.el"
+;;;;;;  "cedet/semantic/db-find.el" "cedet/semantic/db-global.el"
+;;;;;;  "cedet/semantic/db-mode.el" "cedet/semantic/db-typecache.el"
+;;;;;;  "cedet/semantic/db.el" "cedet/semantic/debug.el" 
"cedet/semantic/decorate/include.el"
+;;;;;;  "cedet/semantic/decorate/mode.el" "cedet/semantic/dep.el"
+;;;;;;  "cedet/semantic/doc.el" "cedet/semantic/edit.el" 
"cedet/semantic/find.el"
+;;;;;;  "cedet/semantic/format.el" "cedet/semantic/grammar-wy.el"
 ;;;;;;  "cedet/semantic/grm-wy-boot.el" "cedet/semantic/html.el"
 ;;;;;;  "cedet/semantic/ia-sb.el" "cedet/semantic/ia.el" 
"cedet/semantic/idle.el"
 ;;;;;;  "cedet/semantic/imenu.el" "cedet/semantic/lex-spp.el" 
"cedet/semantic/lex.el"
@@ -40142,8 +40151,8 @@ Zone out, completely." t nil)
 ;;;;;;  "cedet/srecode/insert.el" "cedet/srecode/java.el" 
"cedet/srecode/map.el"
 ;;;;;;  "cedet/srecode/mode.el" "cedet/srecode/srt-wy.el" 
"cedet/srecode/srt.el"
 ;;;;;;  "cedet/srecode/template.el" "cedet/srecode/texi.el" "composite.el"
-;;;;;;  "cus-face.el" "cus-load.el" "cus-start.el" "custom.el" "dired-aux.el"
-;;;;;;  "dired-x.el" "electric.el" "emacs-lisp/backquote.el" 
"emacs-lisp/byte-run.el"
+;;;;;;  "cus-face.el" "cus-start.el" "custom.el" "dired-aux.el" "dired-x.el"
+;;;;;;  "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el"
 ;;;;;;  "emacs-lisp/cl-extra.el" "emacs-lisp/cl-macs.el" 
"emacs-lisp/cl-preloaded.el"
 ;;;;;;  "emacs-lisp/cl-seq.el" "emacs-lisp/easymenu.el" 
"emacs-lisp/eieio-custom.el"
 ;;;;;;  "emacs-lisp/eieio-opt.el" "emacs-lisp/float-sup.el" 
"emacs-lisp/lisp-mode.el"
@@ -40165,47 +40174,35 @@ Zone out, completely." t nil)
 ;;;;;;  "eshell/em-pred.el" "eshell/em-prompt.el" "eshell/em-rebind.el"
 ;;;;;;  "eshell/em-script.el" "eshell/em-smart.el" "eshell/em-term.el"
 ;;;;;;  "eshell/em-tramp.el" "eshell/em-unix.el" "eshell/em-xtra.el"
-;;;;;;  "eshell/esh-groups.el" "faces.el" "files.el" "finder-inf.el"
-;;;;;;  "font-core.el" "font-lock.el" "format.el" "frame.el" "help.el"
-;;;;;;  "hfy-cmap.el" "ibuf-ext.el" "indent.el" "international/characters.el"
-;;;;;;  "international/charprop.el" "international/charscript.el"
-;;;;;;  "international/cp51932.el" "international/emoji-labels.el"
-;;;;;;  "international/emoji-zwj.el" "international/eucjp-ms.el"
-;;;;;;  "international/idna-mapping.el" "international/iso-transl.el"
-;;;;;;  "international/mule-cmds.el" "international/mule-conf.el"
-;;;;;;  "international/mule.el" "international/uni-bidi.el" 
"international/uni-brackets.el"
-;;;;;;  "international/uni-category.el" "international/uni-combining.el"
-;;;;;;  "international/uni-comment.el" "international/uni-confusable.el"
-;;;;;;  "international/uni-decimal.el" "international/uni-decomposition.el"
-;;;;;;  "international/uni-digit.el" "international/uni-lowercase.el"
-;;;;;;  "international/uni-mirrored.el" "international/uni-name.el"
-;;;;;;  "international/uni-numeric.el" "international/uni-old-name.el"
-;;;;;;  "international/uni-scripts.el" "international/uni-special-lowercase.el"
-;;;;;;  "international/uni-special-titlecase.el" 
"international/uni-special-uppercase.el"
-;;;;;;  "international/uni-titlecase.el" "international/uni-uppercase.el"
-;;;;;;  "isearch.el" "jit-lock.el" "jka-cmpr-hook.el" "keymap.el"
-;;;;;;  "language/burmese.el" "language/cham.el" "language/chinese.el"
-;;;;;;  "language/cyrillic.el" "language/czech.el" "language/english.el"
-;;;;;;  "language/ethiopic.el" "language/european.el" "language/georgian.el"
-;;;;;;  "language/greek.el" "language/hebrew.el" "language/indian.el"
-;;;;;;  "language/japanese.el" "language/khmer.el" "language/korean.el"
-;;;;;;  "language/lao.el" "language/misc-lang.el" "language/romanian.el"
-;;;;;;  "language/sinhala.el" "language/slovak.el" "language/tai-viet.el"
-;;;;;;  "language/thai.el" "language/tibetan.el" "language/utf-8-lang.el"
-;;;;;;  "language/vietnamese.el" "ldefs-boot.el" "leim/ja-dic/ja-dic.el"
-;;;;;;  "leim/leim-list.el" "leim/quail/4Corner.el" "leim/quail/ARRAY30.el"
-;;;;;;  "leim/quail/CCDOSPY.el" "leim/quail/CTLau-b5.el" "leim/quail/CTLau.el"
-;;;;;;  "leim/quail/ECDICT.el" "leim/quail/ETZY.el" "leim/quail/PY-b5.el"
-;;;;;;  "leim/quail/PY.el" "leim/quail/Punct-b5.el" "leim/quail/Punct.el"
-;;;;;;  "leim/quail/QJ-b5.el" "leim/quail/QJ.el" "leim/quail/SW.el"
-;;;;;;  "leim/quail/TONEPY.el" "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el"
-;;;;;;  "leim/quail/arabic.el" "leim/quail/cham.el" "leim/quail/compose.el"
-;;;;;;  "leim/quail/croatian.el" "leim/quail/cyril-jis.el" 
"leim/quail/cyrillic.el"
-;;;;;;  "leim/quail/czech.el" "leim/quail/emoji.el" "leim/quail/georgian.el"
-;;;;;;  "leim/quail/greek.el" "leim/quail/hanja-jis.el" "leim/quail/hanja.el"
-;;;;;;  "leim/quail/hanja3.el" "leim/quail/hebrew.el" "leim/quail/ipa-praat.el"
-;;;;;;  "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el" 
"leim/quail/latin-post.el"
-;;;;;;  "leim/quail/latin-pre.el" "leim/quail/persian.el" 
"leim/quail/programmer-dvorak.el"
+;;;;;;  "faces.el" "files.el" "font-core.el" "font-lock.el" "format.el"
+;;;;;;  "frame.el" "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el"
+;;;;;;  "international/characters.el" "international/charscript.el"
+;;;;;;  "international/cp51932.el" "international/emoji-zwj.el" 
"international/eucjp-ms.el"
+;;;;;;  "international/iso-transl.el" "international/mule-cmds.el"
+;;;;;;  "international/mule-conf.el" "international/mule.el" "isearch.el"
+;;;;;;  "jit-lock.el" "jka-cmpr-hook.el" "keymap.el" "language/burmese.el"
+;;;;;;  "language/cham.el" "language/chinese.el" "language/cyrillic.el"
+;;;;;;  "language/czech.el" "language/english.el" "language/ethiopic.el"
+;;;;;;  "language/european.el" "language/georgian.el" "language/greek.el"
+;;;;;;  "language/hebrew.el" "language/indian.el" "language/japanese.el"
+;;;;;;  "language/khmer.el" "language/korean.el" "language/lao.el"
+;;;;;;  "language/misc-lang.el" "language/romanian.el" "language/sinhala.el"
+;;;;;;  "language/slovak.el" "language/tai-viet.el" "language/thai.el"
+;;;;;;  "language/tibetan.el" "language/utf-8-lang.el" "language/vietnamese.el"
+;;;;;;  "ldefs-boot.el" "leim/ja-dic/ja-dic.el" "leim/leim-list.el"
+;;;;;;  "leim/quail/4Corner.el" "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el"
+;;;;;;  "leim/quail/CTLau-b5.el" "leim/quail/CTLau.el" "leim/quail/ECDICT.el"
+;;;;;;  "leim/quail/ETZY.el" "leim/quail/PY-b5.el" "leim/quail/PY.el"
+;;;;;;  "leim/quail/Punct-b5.el" "leim/quail/Punct.el" "leim/quail/QJ-b5.el"
+;;;;;;  "leim/quail/QJ.el" "leim/quail/SW.el" "leim/quail/TONEPY.el"
+;;;;;;  "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el" "leim/quail/arabic.el"
+;;;;;;  "leim/quail/cham.el" "leim/quail/compose.el" "leim/quail/croatian.el"
+;;;;;;  "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" 
"leim/quail/czech.el"
+;;;;;;  "leim/quail/emoji.el" "leim/quail/georgian.el" "leim/quail/greek.el"
+;;;;;;  "leim/quail/hanja-jis.el" "leim/quail/hanja.el" "leim/quail/hanja3.el"
+;;;;;;  "leim/quail/hebrew.el" "leim/quail/ipa-praat.el" 
"leim/quail/latin-alt.el"
+;;;;;;  "leim/quail/latin-ltx.el" "leim/quail/latin-post.el" 
"leim/quail/latin-pre.el"
+;;;;;;  "leim/quail/persian.el" "leim/quail/programmer-dvorak.el"
 ;;;;;;  "leim/quail/py-punct.el" "leim/quail/pypunct-b5.el" 
"leim/quail/quick-b5.el"
 ;;;;;;  "leim/quail/quick-cns.el" "leim/quail/rfc1345.el" "leim/quail/sami.el"
 ;;;;;;  "leim/quail/sgml-input.el" "leim/quail/slovak.el" 
"leim/quail/symbol-ksc.el"
diff --git a/lisp/loadhist.el b/lisp/loadhist.el
index 48058f4053..39481ab068 100644
--- a/lisp/loadhist.el
+++ b/lisp/loadhist.el
@@ -157,38 +157,35 @@ documentation of `unload-feature' for details.")
           ;; mode, or proposed is not nil and not major-mode, and so we use it.
           (funcall (or proposed 'fundamental-mode)))))))
 
+(defvar loadhist-unload-filename nil)
+
 (cl-defgeneric loadhist-unload-element (x)
-  "Unload an element from the `load-history'."
+  "Unload an element from the `load-history'.
+The variable `loadhist-unload-filename' holds the name of the file we're
+unloading."
   (message "Unexpected element %S in load-history" x))
 
-;; In `load-history', the definition of a previously autoloaded
-;; function is represented by 2 entries: (t . SYMBOL) comes before
-;; (defun . SYMBOL) and says we should restore SYMBOL's autoload when
-;; we undefine it.
-;; So we use this auxiliary variable to keep track of the last (t . SYMBOL)
-;; that occurred.
-(defvar loadhist--restore-autoload nil
-  "If non-nil, is a symbol for which to try to restore a previous autoload.")
-
-(cl-defmethod loadhist-unload-element ((x (head t)))
-  (setq loadhist--restore-autoload (cdr x)))
-
-(defun loadhist--unload-function (x)
-  (let ((fun (cdr x)))
-    (when (fboundp fun)
-      (when (fboundp 'ad-unadvise)
-       (ad-unadvise fun))
-      (let ((aload (get fun 'autoload)))
-       (defalias fun
-          (if (and aload (eq fun loadhist--restore-autoload))
-             (cons 'autoload aload)
-            nil)))))
-  (setq loadhist--restore-autoload nil))
-
 (cl-defmethod loadhist-unload-element ((x (head defun)))
-  (loadhist--unload-function x))
-(cl-defmethod loadhist-unload-element ((x (head autoload)))
-  (loadhist--unload-function x))
+  (let* ((fun (cdr x))
+         (hist (get fun 'function-history)))
+    (cond
+     ((null hist)
+      (defalias fun nil)
+      ;; Override the change that `defalias' just recorded.
+      (put fun 'function-history nil))
+     ((equal (car hist) loadhist-unload-filename)
+      (defalias fun (cadr hist))
+      ;; Set the history afterwards, to override the change that
+      ;; `defalias' records otherwise.
+      (put fun 'function-history (cddr hist)))
+     (t
+      ;; Unloading a file whose definition is "inactive" (i.e. has been
+      ;; overridden by another file): just remove it from the history,
+      ;; so future unloading of that other file has a chance to DTRT.
+      (let* ((tmp (plist-member hist loadhist-unload-filename))
+             (pos (- (length hist) (length tmp))))
+        (cl-assert (> pos 1))
+        (setcdr (nthcdr (- pos 2) hist) (cdr tmp)))))))
 
 (cl-defmethod loadhist-unload-element ((_ (head require))) nil)
 (cl-defmethod loadhist-unload-element ((_ (head defface))) nil)
@@ -257,6 +254,7 @@ something strange, such as redefining an Emacs function."
               (prin1-to-string dependents) file))))
   (let* ((unload-function-defs-list (feature-symbols feature))
          (file (pop unload-function-defs-list))
+         (loadhist-unload-filename file)
         (name (symbol-name feature))
          (unload-hook (intern-soft (concat name "-unload-hook")))
         (unload-func (intern-soft (concat name "-unload-function"))))
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 3c59d639a0..a988980b62 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -128,6 +128,7 @@
 (set-buffer "*scratch*")
 (setq buffer-undo-list t)
 
+(load "emacs-lisp/debug-early")
 (load "emacs-lisp/byte-run")
 (load "emacs-lisp/backquote")
 (load "subr")
diff --git a/lisp/mail/ietf-drums.el b/lisp/mail/ietf-drums.el
index 4a07959189..473f95ca50 100644
--- a/lisp/mail/ietf-drums.el
+++ b/lisp/mail/ietf-drums.el
@@ -150,7 +150,7 @@ backslash and doublequote.")
       (buffer-string))))
 
 (defun ietf-drums-get-comment (string)
-  "Return the first comment in STRING."
+  "Return the last comment in STRING."
   (with-temp-buffer
     (ietf-drums-init string)
     (let (result c)
@@ -191,6 +191,8 @@ the Content-Transfer-Encoding header of a mail."
   "Parse STRING and return a MAILBOX / DISPLAY-NAME pair.
 If DECODE, the DISPLAY-NAME will have RFC2047 decoding performed
 (that's the \"=?utf...q...=?\") stuff."
+  (when decode
+    (require 'rfc2047))
   (with-temp-buffer
     (let (display-name mailbox c display-string)
       (ietf-drums-init string)
@@ -240,7 +242,7 @@ If DECODE, the DISPLAY-NAME will have RFC2047 decoding 
performed
            (cons
             (mapconcat #'identity (nreverse display-name) "")
             (ietf-drums-get-comment string)))
-       (cons mailbox (if decode
+       (cons mailbox (if (and decode display-string)
                           (rfc2047-decode-string display-string)
                         display-string))))))
 
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 817c2d485e..7678b1ece6 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -2342,9 +2342,13 @@ It must accept a buffer as its only required argument.")
   (and (lookup-key (current-global-map) [menu-bar buffer])
        (or force (frame-or-buffer-changed-p))
        (let ((buffers (buffer-list))
-            (frames (frame-list))
-            buffers-menu)
-
+            frames buffers-menu)
+         ;; Ignore the initial frame if present.  It can happen if
+         ;; Emacs was started as a daemon.  (bug#53740)
+         (dolist (frame (frame-list))
+           (unless (equal (terminal-name (frame-terminal frame))
+                          "initial_terminal")
+             (push frame frames)))
         ;; Make the menu of buffers proper.
         (setq buffers-menu
                (let ((i 0)
@@ -2537,7 +2541,7 @@ Use \\[menu-bar-mode] to make the menu bar appear."))))
 (put 'menu-bar-mode 'standard-value '(t))
 
 (defun toggle-menu-bar-mode-from-frame (&optional arg)
-  "Toggle display of the menu bar of the current frame.
+  "Toggle display of the menu bar.
 See `menu-bar-mode' for more information."
   (interactive (list (or current-prefix-arg 'toggle)))
   (if (eq arg 'toggle)
@@ -2629,8 +2633,11 @@ FROM-MENU-BAR, if non-nil, means we are dropping one of 
menu-bar's menus."
       ;; `setup-specified-language-environment', for instance,
       ;; expects this to be set from a menu keymap.
       (setq last-command-event (car (last event)))
-      ;; mouse-major-mode-menu was using `command-execute' instead.
-      (call-interactively cmd))))
+      (setq from--tty-menu-p nil)
+      ;; Signal use-dialog-box-p this command was invoked from a menu.
+      (let ((from--tty-menu-p t))
+        ;; mouse-major-mode-menu was using `command-execute' instead.
+        (call-interactively cmd)))))
 
 (defun popup-menu-normalize-position (position)
   "Convert the POSITION to the form which `popup-menu' expects internally.
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index d2092633d8..5e7bdbe6c6 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -5,12 +5,11 @@
 ;; Author: Alexandru Harsanyi <AlexHarsanyi@gmail.com>
 ;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
 ;; Created: December, 2009
-;; Version: 3.2.0
+;; Version: 3.2.1
 ;; Keywords: soap, web-services, comm, hypermedia
 ;; Package: soap-client
 ;; URL: https://github.com/alex-hhh/emacs-soap-client
-;; Package-Requires: ((cl-lib "0.6.1"))
-;;FIXME: Put in `Package-Requires:' the Emacs version we expect.
+;; Package-Requires: ((emacs "24.1") (cl-lib "0.6.1"))
 
 ;; This file is part of GNU Emacs.
 
@@ -659,7 +658,7 @@ representing leap seconds."
             (if second
                 (if second-fraction
                     (let* ((second-fraction-significand
-                            (string-replace "." "" second-fraction))
+                            (replace-regexp-in-string "\\." "" 
second-fraction))
                            (hertz
                             (expt 10 (length second-fraction-significand)))
                            (ticks (+ (* hertz (string-to-number second))
@@ -1937,7 +1936,7 @@ This is a specialization of `soap-decode-type' for
                   (e-name (soap-xs-element-name element))
                   ;; Heuristic: guess if we need to decode using local
                   ;; namespaces.
-                  (use-fq-names (string-search ":" (symbol-name (car node))))
+                  (use-fq-names (string-match ":" (symbol-name (car node))))
                   (children (if e-name
                                 (if use-fq-names
                                     ;; Find relevant children
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index d3f427932f..c6523003b8 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -190,6 +190,8 @@ It must be supported by libarchive(3).")
     "\\)" ;; \1
     "\\(" "/" ".*" "\\)" "\\'"))) ;; \2
 
+(put #'tramp-archive-autoload-file-name-regexp 'tramp-autoload t)
+
 ;; In older Emacsen (prior 27.1), `tramp-archive-autoload-file-name-regexp'
 ;; is not autoloaded.  So we cannot expect it to be known in
 ;; tramp-loaddefs.el.  But it exists, when tramp-archive.el is loaded.
@@ -366,6 +368,8 @@ arguments to pass to the OPERATION."
           (tramp-archive-autoload t))
       (apply #'tramp-autoload-file-name-handler operation args)))))
 
+(put #'tramp-archive-autoload-file-name-handler 'tramp-autoload t)
+
 ;;;###autoload
 (progn (defun tramp-register-archive-file-name-handler ()
   "Add archive file name handler to `file-name-handler-alist'."
@@ -375,6 +379,8 @@ arguments to pass to the OPERATION."
                       #'tramp-archive-autoload-file-name-handler))
     (put #'tramp-archive-autoload-file-name-handler 'safe-magic t))))
 
+(put #'tramp-register-archive-file-name-handler 'tramp-autoload t)
+
 ;;;###autoload
 (progn
   (add-hook 'after-init-hook #'tramp-register-archive-file-name-handler)
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index 1ab8f4d335..dc1e3d28b5 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -122,7 +122,7 @@ If KEY is `tramp-cache-undefined', don't create anything, 
and return nil."
               (puthash key (make-hash-table :test #'equal) tramp-cache-data)))
          (when (tramp-file-name-p key)
            (dolist (elt tramp-connection-properties)
-             (when (tramp-compat-string-search
+             (when (string-match-p
                     (or (nth 0 elt) "")
                     (tramp-make-tramp-file-name key 'noloc))
                (tramp-set-connection-property key (nth 1 elt) (nth 2 elt)))))
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 221ee547a2..d3af9f4769 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -916,8 +916,6 @@ or `dbus-call-method-asynchronously'."
      ;; when loading.
      (dbus-ignore-errors (tramp-dbus-function ,vec func args))))
 
-(font-lock-add-keywords 'emacs-lisp-mode 
'("\\<with-tramp-dbus-call-method\\>"))
-
 (defmacro with-tramp-dbus-get-all-properties
   (vec bus service path interface)
   "Return all properties of INTERFACE.
@@ -932,8 +930,6 @@ The call will be traced by Tramp with trace level 6."
      (tramp-dbus-function
       ,vec #'dbus-get-all-properties (list ,bus ,service ,path ,interface))))
 
-(font-lock-add-keywords 'emacs-lisp-mode 
'("\\<with-tramp-dbus-get-all-properties\\>"))
-
 (defvar tramp-gvfs-dbus-event-vector nil
   "Current Tramp file name to be used, as vector.
 It is needed when D-Bus signals or errors arrive, because there
@@ -2246,13 +2242,7 @@ connection if a previous connection has died for some 
reason."
 COMMAND is a command from the gvfs-* utilities.  It is replaced
 by the corresponding gio tool call if available.  `call-process'
 is applied, and it returns t if the return code is zero."
-  (let* ((locale (tramp-get-local-locale vec))
-        (process-environment
-         (append
-          `(,(format "LANG=%s" locale)
-            ,(format "LANGUAGE=%s" locale)
-            ,(format "LC_ALL=%s" locale))
-          process-environment)))
+  (let ((locale (tramp-get-local-locale vec)))
     (when (tramp-gvfs-gio-tool-p vec)
       ;; Use gio tool.
       (setq args (cons (cdr (assoc command tramp-gvfs-gio-mapping))
@@ -2262,7 +2252,14 @@ is applied, and it returns t if the return code is zero."
     (with-current-buffer (tramp-get-connection-buffer vec)
       (tramp-gvfs-maybe-open-connection vec)
       (erase-buffer)
-      (or (zerop (apply #'tramp-call-process vec command nil t nil args))
+      (or (zerop
+          (apply
+           #'tramp-call-process vec "env" nil t nil
+           (append `(,(format "LANG=%s" locale)
+                     ,(format "LANGUAGE=%s" locale)
+                     ,(format "LC_ALL=%s" locale)
+                     ,command)
+                   args)))
          ;; Remove information about mounted connection.
          (and (tramp-flush-file-properties vec "/") nil)))))
 
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index c6e55ff688..6d8f267ddf 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2302,8 +2302,6 @@ If VAR is nil, then we bind `v' to the structure and 
`method', `user',
        (ignore ,@(mapcar #'car bindings))
        ,@body)))
 
-(font-lock-add-keywords 'emacs-lisp-mode 
'("\\<with-parsed-tramp-file-name\\>"))
-
 (defun tramp-progress-reporter-update (reporter &optional value suffix)
   "Report progress of an operation for Tramp."
   (let* ((parameters (cdr reporter))
@@ -2340,9 +2338,6 @@ without a visible progress reporter."
          (if tm (cancel-timer tm))
          (tramp-message ,vec ,level "%s...%s" ,message cookie)))))
 
-(font-lock-add-keywords
- 'emacs-lisp-mode '("\\<with-tramp-progress-reporter\\>"))
-
 (defmacro with-tramp-file-property (vec file property &rest body)
   "Check in Tramp cache for PROPERTY, otherwise execute BODY and set cache.
 FILE must be a local file name on a connection identified via VEC."
@@ -2359,8 +2354,6 @@ FILE must be a local file name on a connection identified 
via VEC."
         value)
      ,@body))
 
-(font-lock-add-keywords 'emacs-lisp-mode '("\\<with-tramp-file-property\\>"))
-
 (defmacro with-tramp-connection-property (key property &rest body)
   "Check in Tramp for property PROPERTY, otherwise execute BODY and set."
   (declare (indent 2) (debug t))
@@ -2374,9 +2367,6 @@ FILE must be a local file name on a connection identified 
via VEC."
        (tramp-set-connection-property ,key ,property value))
      value))
 
-(font-lock-add-keywords
- 'emacs-lisp-mode '("\\<with-tramp-connection-property\\>"))
-
 (defun tramp-drop-volume-letter (name)
   "Cut off unnecessary drive letter from file NAME.
 The functions `tramp-*-handle-expand-file-name' call `expand-file-name'
@@ -2742,6 +2732,8 @@ Falls back to normal file name handler if no Tramp file 
name handler exists."
       (load "tramp" 'noerror 'nomessage)))
   (apply operation args)))
 
+(put #'tramp-autoload-file-name-handler 'tramp-autoload t)
+
 ;; `tramp-autoload-file-name-handler' must be registered before
 ;; evaluation of site-start and init files, because there might exist
 ;; remote files already, f.e. files kept via recentf-mode.
@@ -2753,6 +2745,7 @@ Falls back to normal file name handler if no Tramp file 
name handler exists."
                     #'tramp-autoload-file-name-handler))
   (put #'tramp-autoload-file-name-handler 'safe-magic t)))
 
+(put #'tramp-register-autoload-file-name-handlers 'tramp-autoload t)
 ;;;###autoload (tramp-register-autoload-file-name-handlers)
 
 (defun tramp-use-absolute-autoload-file-names ()
@@ -2866,6 +2859,7 @@ whether HANDLER is to be called.  Add operations defined 
in
               (string-prefix-p "tramp-" (symbol-name (cdr fnh))))
       (setq file-name-handler-alist (delq fnh file-name-handler-alist))))))
 
+(put #'tramp-unload-file-name-handlers 'tramp-autoload t)
 (add-hook 'tramp-unload-hook #'tramp-unload-file-name-handlers)
 
 ;;; File name handler functions for completion mode:
@@ -4008,6 +4002,14 @@ Do not set it manually, it is used buffer-local in 
`tramp-get-lock-pid'.")
   ;; was visited.
   (catch 'dont-lock
     (unless (eq (file-locked-p file) t) ;; Locked by me.
+      (when (and buffer-file-truename
+                (not (verify-visited-file-modtime))
+                (file-exists-p file))
+       ;; In filelock.c, `userlock--ask-user-about-supersession-threat'
+       ;; is called, which also checks file contents.  This is unwise
+       ;; for remote files.
+       (ask-user-about-supersession-threat file))
+
       (when-let ((info (tramp-get-lock-file file))
                 (match (string-match tramp-lock-file-info-regexp info)))
        (unless (ask-user-about-lock
@@ -5015,9 +5017,6 @@ Mostly useful to protect BODY from being interrupted by 
timers."
           ,@body)
        (tramp-flush-connection-property ,proc "locked"))))
 
-(font-lock-add-keywords
- 'emacs-lisp-mode '("\\<with-tramp-locked-connection\\>"))
-
 (defun tramp-accept-process-output (proc &optional timeout)
   "Like `accept-process-output' for Tramp processes.
 This is needed in order to hide `last-coding-system-used', which is set
@@ -5957,6 +5956,8 @@ BODY is the backend specific code."
   ;; Maybe it's not loaded yet.
   (ignore-errors (unload-feature 'tramp 'force))))
 
+(put #'tramp-unload-tramp 'tramp-autoload t)
+
 (provide 'tramp)
 
 (run-hooks 'tramp--startup-hook)
diff --git a/lisp/notifications.el b/lisp/notifications.el
index 5ad64ff73b..b58a1a0211 100644
--- a/lisp/notifications.el
+++ b/lisp/notifications.el
@@ -202,7 +202,7 @@ This function returns a notification id, an integer, which 
can be
 used to manipulate the notification item with
 `notifications-close-notification' or the `:replaces-id' argument
 of another `notifications-notify' call."
-  (with-demoted-errors
+  (with-demoted-errors "Notification error: %S"
     (let ((bus (or (plist-get params :bus) :session))
          (title (plist-get params :title))
          (body (plist-get params :body))
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index b8f6cb5ad3..171b7088c1 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -566,7 +566,8 @@ Many aspects this mode can be customized using
           (font-lock-syntactic-face-function
            . sgml-font-lock-syntactic-face)))
 
-  (with-demoted-errors (rng-nxml-mode-init)))
+  (with-demoted-errors "RNG NXML error: %S"
+    (rng-nxml-mode-init)))
 
 (defun nxml--buffer-substring-filter (string)
   ;; The `rng-state' property is huge, so don't copy it to the kill ring.
diff --git a/lisp/vt-control.el b/lisp/obsolete/vt-control.el
similarity index 99%
rename from lisp/vt-control.el
rename to lisp/obsolete/vt-control.el
index b80d3505b3..190ccbaa83 100644
--- a/lisp/vt-control.el
+++ b/lisp/obsolete/vt-control.el
@@ -4,6 +4,7 @@
 
 ;; Author: Rob Riepel <riepel@networking.stanford.edu>
 ;; Keywords: terminals
+;; Obsolete-since: 29.1
 
 ;; This file is part of GNU Emacs.
 
diff --git a/lisp/vt100-led.el b/lisp/obsolete/vt100-led.el
similarity index 98%
rename from lisp/vt100-led.el
rename to lisp/obsolete/vt100-led.el
index a6a256a6a7..d741a112aa 100644
--- a/lisp/vt100-led.el
+++ b/lisp/obsolete/vt100-led.el
@@ -5,6 +5,7 @@
 ;; Author: Howard Gayle
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: hardware
+;; Obsolete-since: 29.1
 
 ;; This file is part of GNU Emacs.
 
diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el
index cf307aa0cb..566258eba4 100644
--- a/lisp/org/ob-tangle.el
+++ b/lisp/org/ob-tangle.el
@@ -43,7 +43,7 @@
 (declare-function org-in-commented-heading-p "org" (&optional no-inheritance))
 (declare-function org-in-archived-heading-p "org" (&optional no-inheritance))
 (declare-function outline-previous-heading "outline" ())
-(defvar org-id-link-to-org-use-id nil) ; Dynamically scoped
+(defvar org-id-link-to-org-use-id) ; Dynamically scoped
 
 (defcustom org-babel-tangle-lang-exts
   '(("emacs-lisp" . "el")
diff --git a/lisp/org/ol-bibtex.el b/lisp/org/ol-bibtex.el
index 41443d7959..218f8f17ed 100644
--- a/lisp/org/ol-bibtex.el
+++ b/lisp/org/ol-bibtex.el
@@ -115,7 +115,7 @@
 
 (defvar org-agenda-overriding-header)
 (defvar org-agenda-search-view-always-boolean)
-(defvar org-bibtex-description nil) ; dynamically scoped from org.el
+(defvar org-bibtex-description nil)
 (defvar org-id-locations)
 (defvar org-property-end-re)
 (defvar org-special-properties)
diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el
index 94aea1b0a3..ae0058e037 100644
--- a/lisp/org/org-agenda.el
+++ b/lisp/org/org-agenda.el
@@ -99,8 +99,8 @@
 
 ;; Defined somewhere in this file, but used before definition.
 (defvar org-agenda-buffer-name "*Org Agenda*")
-(defvar org-agenda-overriding-header nil)
 (defvar org-agenda-title-append nil)
+(defvar org-agenda-overriding-header)
 ;; (with-no-warnings (defvar entry)) ;; unprefixed, from calendar.el
 ;; (with-no-warnings (defvar date))  ;; unprefixed, from calendar.el
 (defvar original-date) ; dynamically scoped, calendar.el does scope this
@@ -2158,7 +2158,7 @@ string that it returns."
 (org-remap org-agenda-mode-map 'move-end-of-line 'org-agenda-end-of-line)
 
 (defvar org-agenda-menu) ; defined later in this file.
-(defvar org-agenda-restrict nil) ; defined later in this file.
+(defvar org-agenda-restrict nil)
 (defvar org-agenda-follow-mode nil)
 (defvar org-agenda-entry-text-mode nil)
 (defvar org-agenda-clockreport-mode nil)
@@ -7288,7 +7288,7 @@ When TYPE is \"scheduled\", \"deadline\", \"timestamp\" or
 \"timestamp_ia\", compare within each of these type.  When TYPE
 is the empty string, compare all timestamps without respect of
 their type."
-  (let* ((def (and (not org-agenda-sort-notime-is-late) -1))
+  (let* ((def (if org-agenda-sort-notime-is-late 99999999 -1))
         (ta (or (and (string-match type (or (get-text-property 1 'type a) ""))
                      (get-text-property 1 'ts-date a))
                 def))
diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el
index d3c5094b46..2fd9a9c74d 100644
--- a/lisp/org/org-capture.el
+++ b/lisp/org/org-capture.el
@@ -1453,7 +1453,8 @@ Of course, if exact position has been required, just put 
it there."
       (org-with-point-at pos
        (when org-capture-bookmark
          (let ((bookmark (plist-get org-bookmark-names-plist :last-capture)))
-           (when bookmark (with-demoted-errors (bookmark-set bookmark)))))
+           (when bookmark (with-demoted-errors "Bookmark set error: %S"
+                            (bookmark-set bookmark)))))
        (move-marker org-capture-last-stored-marker (point))))))
 
 (defun org-capture-narrow (beg end)
diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el
index ddae182791..dce5d9d4c0 100644
--- a/lisp/org/org-clock.el
+++ b/lisp/org/org-clock.el
@@ -2505,7 +2505,7 @@ the currently selected interval size."
       (when step
        ;; Write many tables, in steps
        (unless (or block (and ts te))
-         (user-error "Clocktable `:step' can only be used with `:block' or 
`:tstart, :end'"))
+         (user-error "Clocktable `:step' can only be used with `:block' or 
`:tstart', `:tend'"))
        (org-clocktable-steps params)
        (throw 'exit nil))
 
diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
index cfccc2c052..819ce74d93 100644
--- a/lisp/org/org-compat.el
+++ b/lisp/org/org-compat.el
@@ -1048,9 +1048,9 @@ ELEMENT is the element at point."
     (cl-case (org-element-type object)
       ;; Prevent checks in links due to keybinding conflict with
       ;; Flyspell.
-      ((code entity export-snippet inline-babel-call
-            inline-src-block line-break latex-fragment link macro
-            statistics-cookie target timestamp verbatim)
+      ((citation citation-reference code entity export-snippet 
inline-babel-call
+                inline-src-block line-break latex-fragment link macro
+                statistics-cookie target timestamp verbatim)
        nil)
       (footnote-reference
        ;; Only in inline footnotes, within the definition.
diff --git a/lisp/org/org-refile.el b/lisp/org/org-refile.el
index 8e1ab7439e..f76ebefe7b 100644
--- a/lisp/org/org-refile.el
+++ b/lisp/org/org-refile.el
@@ -566,16 +566,16 @@ prefix argument (`C-u C-u C-u C-c C-w')."
               (let ((bookmark-name (plist-get org-bookmark-names-plist
                                               :last-refile)))
                 (when bookmark-name
-                  (with-demoted-errors
-                      (bookmark-set bookmark-name))))
+                  (with-demoted-errors "Bookmark set error: %S"
+                    (bookmark-set bookmark-name))))
               ;; If we are refiling for capture, make sure that the
               ;; last-capture pointers point here
               (when (bound-and-true-p org-capture-is-refiling)
                 (let ((bookmark-name (plist-get org-bookmark-names-plist
                                                 :last-capture-marker)))
                   (when bookmark-name
-                    (with-demoted-errors
-                        (bookmark-set bookmark-name))))
+                    (with-demoted-errors "Bookmark set error: %S"
+                      (bookmark-set bookmark-name))))
                 (move-marker org-capture-last-stored-marker (point)))
               (when (fboundp 'deactivate-mark) (deactivate-mark))
               (run-hooks 'org-after-refile-insert-hook)))
diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el
index 5337d9df74..572203711c 100644
--- a/lisp/org/org-version.el
+++ b/lisp/org/org-version.el
@@ -11,7 +11,7 @@ Inserted by installing Org mode or when a release is made."
 (defun org-git-version ()
   "The Git version of Org mode.
 Inserted by installing Org or when a release is made."
-   (let ((org-git-version "release_9.5.2-9-g7ba24c"))
+   (let ((org-git-version "release_9.5.2-13-gdd6486"))
      org-git-version))
 
 (provide 'org-version)
diff --git a/lisp/paren.el b/lisp/paren.el
index 0065bba72e..b0a2eb8dc5 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -89,11 +89,21 @@ its position."
   :type 'boolean)
 
 (defcustom show-paren-context-when-offscreen nil
-  "If non-nil, show context in the echo area when the openparen is offscreen.
+  "If non-nil, show context around the opening paren if it is offscreen.
 The context is usually the line that contains the openparen,
 except if the openparen is on its own line, in which case the
-context includes the previous nonblank line."
-  :type 'boolean
+context includes the previous nonblank line.
+
+By default, the context is shown in the echo area.
+
+If set to the symbol `child-frame', the context is shown in a
+child frame at the top left of the window.  You might want to
+customize the `child-frame-border' face (especially the
+background color) to give the child frame a distinguished border.
+On non-graphical frames, the context is shown in the echo area."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "In echo area" t)
+                 (const :tag "Child frame" child-frame))
   :version "29.1")
 
 (defvar show-paren--idle-timer nil)
@@ -260,6 +270,103 @@ It is the default value of `show-paren-data-function'."
                  (if (= dir 1) pos (1+ pos))
                  mismatch)))))))
 
+(defvar show-paren--context-child-frame nil)
+
+(defun show-paren--context-child-frame-redirect-focus ()
+  "Redirect focus from child frame."
+  (redirect-frame-focus
+   show-paren--context-child-frame
+   (frame-parent corfu--frame)))
+
+(defun show-paren--context-child-frame-buffer (text)
+  (with-current-buffer
+      (get-buffer-create " *show-paren context*")
+    ;; Redirect focus to parent.
+    (add-hook 'pre-command-hook
+              #'show-paren--delete-context-child-frame
+              nil t)
+    ;; Use an empty keymap.
+    (use-local-map (make-keymap))
+    (dolist (var '((mode-line-format . nil)
+                   (header-line-format . nil)
+                   (tab-line-format . nil)
+                   (tab-bar-format . nil) ;; Emacs 28 tab-bar-format
+                   (frame-title-format . "")
+                   (truncate-lines . t)
+                   (cursor-in-non-selected-windows . nil)
+                   (cursor-type . nil)
+                   (show-trailing-whitespace . nil)
+                   (display-line-numbers . nil)
+                   (left-fringe-width . nil)
+                   (right-fringe-width . nil)
+                   (left-margin-width . 0)
+                   (right-margin-width . 0)
+                   (fringes-outside-margins . 0)
+                   (buffer-read-only . t)))
+      (set (make-local-variable (car var)) (cdr var)))
+    (let ((inhibit-modification-hooks t)
+          (inhibit-read-only t))
+      (erase-buffer)
+      (insert text)
+      (goto-char (point-min)))
+    (current-buffer)))
+
+(defvar show-paren--context-child-frame-parameters
+  `((visibility . nil)
+    (width . 0) (height . 0)
+    (min-width . t) (min-height . t)
+    (no-accept-focus . t)
+    (no-focus-on-map . t)
+    (border-width . 0)
+    (child-frame-border-width . 1)
+    (left-fringe . 0)
+    (right-fringe . 0)
+    (vertical-scroll-bars . nil)
+    (horizontal-scroll-bars . nil)
+    (menu-bar-lines . 0)
+    (tool-bar-lines . 0)
+    (tab-bar-lines . 0)
+    (no-other-frame . t)
+    (no-other-window . t)
+    (no-delete-other-windows . t)
+    (unsplittable . t)
+    (undecorated . t)
+    (cursor-type . nil)
+    (no-special-glyphs . t)
+    (desktop-dont-save . t)))
+
+(defun show-paren--delete-context-child-frame ()
+  (when show-paren--context-child-frame
+    (delete-frame show-paren--context-child-frame))
+  (remove-hook 'post-command-hook
+               #'show-paren--delete-context-child-frame))
+
+(defun show-paren--show-context-in-child-frame (text)
+  "Show TEXT in a child-frame at the top-left of the current window."
+  (let ((minibuffer (minibuffer-window (window-frame)))
+        (buffer (show-paren--context-child-frame-buffer text))
+        (x (window-pixel-left))
+        (y (window-pixel-top))
+        (window-min-height 1)
+        (window-min-width 1)
+        after-make-frame-functions)
+    (show-paren--delete-context-child-frame)
+    (setq show-paren--context-child-frame
+          (make-frame
+           `((parent-frame . ,(window-frame))
+             (minibuffer . ,minibuffer)
+             ,@show-paren--context-child-frame-parameters)))
+    (let ((win (frame-root-window show-paren--context-child-frame)))
+      (set-window-buffer win buffer)
+      (set-window-dedicated-p win t)
+      (set-frame-size show-paren--context-child-frame
+                      (string-width text)
+                      (length (string-lines text)))
+      (set-frame-position show-paren--context-child-frame x y)
+      (make-frame-visible show-paren--context-child-frame)
+      (add-hook 'post-command-hook
+                #'show-paren--delete-context-child-frame))))
+
 (defun show-paren-function ()
   "Highlight the parentheses until the next input arrives."
   (let ((data (and show-paren-mode (funcall show-paren-data-function))))
@@ -299,8 +406,8 @@ It is the default value of `show-paren-data-function'."
         ;; Otherwise, turn off any such highlighting.
         (if (or (not here-beg)
                 (and (not show-paren-highlight-openparen)
-                    (> here-end (point))
-                    (<= here-beg (point))
+                     (> here-end (point))
+                     (<= here-beg (point))
                      (integerp there-beg)))
             (delete-overlay show-paren--overlay-1)
           (move-overlay show-paren--overlay-1
@@ -315,7 +422,7 @@ It is the default value of `show-paren-data-function'."
             (delete-overlay show-paren--overlay)
           (if highlight-expression
               (move-overlay show-paren--overlay
-                           (if (< there-beg here-beg) here-end here-beg)
+                            (if (< there-beg here-beg) here-end here-beg)
                             (if (< there-beg here-beg) there-beg there-end)
                             (current-buffer))
             (move-overlay show-paren--overlay
@@ -330,7 +437,12 @@ It is the default value of `show-paren-data-function'."
                 (let ((open-paren-line-string
                        (blink-paren-open-paren-line-string openparen))
                       (message-log-max nil))
-                  (minibuffer-message "Matches %s" open-paren-line-string))))
+                  (if (and (eq show-paren-context-when-offscreen
+                               'child-frame)
+                           (display-graphic-p))
+                      (show-paren--show-context-in-child-frame
+                       open-paren-line-string)
+                    (minibuffer-message "Matches %s" 
open-paren-line-string)))))
           ;; Always set the overlay face, since it varies.
           (overlay-put show-paren--overlay 'priority show-paren-priority)
           (overlay-put show-paren--overlay 'face face))))))
diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el
index d0ae9390e3..3c9bf1ec9d 100644
--- a/lisp/pcmpl-gnu.el
+++ b/lisp/pcmpl-gnu.el
@@ -134,7 +134,7 @@ Return the new list."
   "Add to TARGETS the list of target names in MAKEFILE and files it includes.
 Return the new list."
   (with-temp-buffer
-    (with-demoted-errors                       ;Could be a directory or 
something.
+    (with-demoted-errors "Error inserting makefile: %S"
         (insert-file-contents makefile))
 
     (let ((filenames (when pcmpl-gnu-makefile-includes 
(pcmpl-gnu-make-includes))))
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index e8b637ba1a..54724ca328 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -32,8 +32,10 @@
 
 ;;; Commentary:
 
-;; This package offers a global minor mode which makes mouse-wheel
-;; scroll a line smoothly.
+;; This file contains two somewhat related features.
+
+;; The first is a global minor mode which makes Emacs try to scroll
+;; each line smoothly.
 ;;
 ;; Scrolling a line up by `set-window-vscroll' and that by `scroll-up'
 ;; give similar display as shown below.
@@ -58,6 +60,25 @@
 ;;    (set-window-vscroll nil vs t) (sit-for 0))
 ;;  (scroll-up 1)
 
+;; The second is another global minor mode that redefines `wheel-up'
+;; and `wheel-down' to a command that tries to scroll the display
+;; according to the precise movement of a trackpad or mouse.
+
+;; But it operates in a much more intelligent manner than simply
+;; setting the vscroll.  It will set window start to the position
+;; closest to the position at the top-left corner of the window if
+;; vscroll were set accordingly, in a smart and fast manner, and only
+;; set vscroll the rest of the way.  There is no visible difference,
+;; but it is much faster, and doesn't move the display by a huge
+;; portion if vscroll is reset for some reason.
+
+;; It also tries to move point out of the way, so redisplay will not
+;; recenter the display as it scrolls.  This works well almost all of
+;; the time, but is impossible to get right with images larger than
+;; the window they're displayed in.  A feature that will allow
+;; redisplay to skip recentering is in the works, and will completely
+;; resolve this problem.
+
 ;;; Todo:
 ;;
 ;; Allowing pixel-level scrolling in Emacs requires a thorough review
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 3a3413dc36..957a0b8a7c 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -798,43 +798,44 @@ MODE is the symbol for the mode to initialize, like 
`c-mode'.  See
 `c-basic-common-init' for details.  It's only optional to be
 compatible with old code; callers should always specify it."
 
-  (unless mode
-    ;; Called from an old third party package.  The fallback is to
-    ;; initialize for C.
-    (c-init-language-vars-for 'c-mode))
-
-  (c-basic-common-init mode c-default-style)
-  (when mode
-    ;; Only initialize font locking if we aren't called from an old package.
-    (c-font-lock-init))
-
-  ;; Starting a mode is a sort of "change".  So call the change functions...
-  (save-restriction
-    (widen)
-    (setq c-new-BEG (point-min))
-    (setq c-new-END (point-max))
-    (save-excursion
-      (let (before-change-functions after-change-functions)
-       (mapc (lambda (fn)
-               (funcall fn (point-min) (point-max)))
-             c-get-state-before-change-functions)
-       (mapc (lambda (fn)
-               (funcall fn (point-min) (point-max)
-                        (- (point-max) (point-min))))
-             c-before-font-lock-functions))))
-
-  (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
-  (set (make-local-variable 'outline-level) 'c-outline-level)
-  (set (make-local-variable 'add-log-current-defun-function)
-       (lambda ()
-        (or (c-cpp-define-name) (car (c-defun-name-and-limits nil)))))
-  (let ((rfn (assq mode c-require-final-newline)))
-    (when rfn
-      (if (boundp 'mode-require-final-newline)
-          (and (cdr rfn)
-               (set (make-local-variable 'require-final-newline)
-                    mode-require-final-newline))
-        (set (make-local-variable 'require-final-newline) (cdr rfn))))))
+  (let (case-fold-search)
+    (unless mode
+      ;; Called from an old third party package.  The fallback is to
+      ;; initialize for C.
+      (c-init-language-vars-for 'c-mode))
+
+    (c-basic-common-init mode c-default-style)
+    (when mode
+      ;; Only initialize font locking if we aren't called from an old package.
+      (c-font-lock-init))
+
+    ;; Starting a mode is a sort of "change".  So call the change functions...
+    (save-restriction
+      (widen)
+      (setq c-new-BEG (point-min))
+      (setq c-new-END (point-max))
+      (save-excursion
+       (let (before-change-functions after-change-functions)
+         (mapc (lambda (fn)
+                 (funcall fn (point-min) (point-max)))
+               c-get-state-before-change-functions)
+         (mapc (lambda (fn)
+                 (funcall fn (point-min) (point-max)
+                          (- (point-max) (point-min))))
+               c-before-font-lock-functions))))
+
+    (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
+    (set (make-local-variable 'outline-level) 'c-outline-level)
+    (set (make-local-variable 'add-log-current-defun-function)
+        (lambda ()
+          (or (c-cpp-define-name) (car (c-defun-name-and-limits nil)))))
+    (let ((rfn (assq mode c-require-final-newline)))
+      (when rfn
+       (if (boundp 'mode-require-final-newline)
+            (and (cdr rfn)
+                (set (make-local-variable 'require-final-newline)
+                      mode-require-final-newline))
+          (set (make-local-variable 'require-final-newline) (cdr rfn)))))))
 
 (defun c-count-cfss (lv-alist)
   ;; LV-ALIST is an alist like `file-local-variables-alist'.  Count how many
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 8f33b3e3b7..94ecc45b15 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3834,7 +3834,7 @@ recursive calls in starting lines of here-documents."
                "\\<" cperl-sub-regexp "\\>" ;  sub with proto/attr
                "\\("
                   cperl-white-and-comment-rex
-                   (rx (group (eval cperl--normal-identifier-rx)))
+                   (rx (opt (group (eval cperl--normal-identifier-rx))))
                 "\\)"
                "\\("
                   cperl-maybe-white-and-comment-rex
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index ecc9386cae..7b7c675873 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -879,7 +879,8 @@ startup file, `~/.emacs-octave'."
     (set-process-filter proc 'comint-output-filter)
     ;; Just in case, to be sure a cd in the startup file won't have
     ;; detrimental effects.
-    (with-demoted-errors (inferior-octave-resync-dirs))
+    (with-demoted-errors "Octave resync error: %S"
+      (inferior-octave-resync-dirs))
     ;; Generate a proper prompt, which is critical to
     ;; `comint-history-isearch-backward-regexp'.  Bug#14433.
     (comint-send-string proc "\n")))
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index c812f28c1b..f606a25575 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1072,9 +1072,10 @@ Stops when a match is found and prompts for whether to 
replace it.
 If you exit the `query-replace', you can later continue the
 `query-replace' loop using the command \\[fileloop-continue]."
   (interactive
-   (pcase-let ((`(,from ,to)
-                (query-replace-read-args "Query replace (regexp)" t t)))
-     (list from to)))
+   (let ((query-replace-read-from-regexp-default 'find-tag-default-as-regexp))
+     (pcase-let ((`(,from ,to)
+                  (query-replace-read-args "Query replace (regexp)" t t)))
+       (list from to))))
   (fileloop-initialize-replace
    from to (project-files (project-current t)) 'default)
   (fileloop-continue))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 5889f2ab67..d83290fe45 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -92,7 +92,7 @@
 ;; Operating Systems' pipe buffering (e.g. CPython 3.3.4 in Windows 7.
 ;; See URL `https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17304').  To
 ;; avoid this, the `python-shell-unbuffered' defaults to non-nil and
-;; controls whether `python-shell-calculate-process-environment'
+;; controls whether `python-shell--calculate-process-environment'
 ;; should set the "PYTHONUNBUFFERED" environment variable on startup:
 ;; See URL `https://docs.python.org/3/using/cmdline.html#cmdoption-u'.
 
@@ -149,7 +149,7 @@
 ;; (setq python-shell-process-environment
 ;;       (list
 ;;        (format "PATH=%s" (mapconcat
-;;                           'identity
+;;                           #'identity
 ;;                           (reverse
 ;;                            (cons (getenv "PATH")
 ;;                                  '("/path/to/env/bin/")))
@@ -245,7 +245,7 @@
 (require 'ansi-color)
 (require 'cl-lib)
 (require 'comint)
-(require 'tramp-sh)
+(eval-when-compile (require 'subr-x))   ;For `string-empty-p'.
 
 ;; Avoid compiler warnings
 (defvar view-return-to-alist)
@@ -273,39 +273,39 @@
 (defvar python-mode-map
   (let ((map (make-sparse-keymap)))
     ;; Movement
-    (define-key map [remap backward-sentence] 'python-nav-backward-block)
-    (define-key map [remap forward-sentence] 'python-nav-forward-block)
-    (define-key map [remap backward-up-list] 'python-nav-backward-up-list)
-    (define-key map [remap mark-defun] 'python-mark-defun)
-    (define-key map "\C-c\C-j" 'imenu)
+    (define-key map [remap backward-sentence] #'python-nav-backward-block)
+    (define-key map [remap forward-sentence] #'python-nav-forward-block)
+    (define-key map [remap backward-up-list] #'python-nav-backward-up-list)
+    (define-key map [remap mark-defun] #'python-mark-defun)
+    (define-key map "\C-c\C-j" #'imenu)
     ;; Indent specific
-    (define-key map "\177" 'python-indent-dedent-line-backspace)
-    (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
-    (define-key map "\C-c<" 'python-indent-shift-left)
-    (define-key map "\C-c>" 'python-indent-shift-right)
+    (define-key map "\177" #'python-indent-dedent-line-backspace)
+    (define-key map (kbd "<backtab>") #'python-indent-dedent-line)
+    (define-key map "\C-c<" #'python-indent-shift-left)
+    (define-key map "\C-c>" #'python-indent-shift-right)
     ;; Skeletons
-    (define-key map "\C-c\C-tc" 'python-skeleton-class)
-    (define-key map "\C-c\C-td" 'python-skeleton-def)
-    (define-key map "\C-c\C-tf" 'python-skeleton-for)
-    (define-key map "\C-c\C-ti" 'python-skeleton-if)
-    (define-key map "\C-c\C-tm" 'python-skeleton-import)
-    (define-key map "\C-c\C-tt" 'python-skeleton-try)
-    (define-key map "\C-c\C-tw" 'python-skeleton-while)
+    (define-key map "\C-c\C-tc" #'python-skeleton-class)
+    (define-key map "\C-c\C-td" #'python-skeleton-def)
+    (define-key map "\C-c\C-tf" #'python-skeleton-for)
+    (define-key map "\C-c\C-ti" #'python-skeleton-if)
+    (define-key map "\C-c\C-tm" #'python-skeleton-import)
+    (define-key map "\C-c\C-tt" #'python-skeleton-try)
+    (define-key map "\C-c\C-tw" #'python-skeleton-while)
     ;; Shell interaction
-    (define-key map "\C-c\C-p" 'run-python)
-    (define-key map "\C-c\C-s" 'python-shell-send-string)
-    (define-key map "\C-c\C-e" 'python-shell-send-statement)
-    (define-key map "\C-c\C-r" 'python-shell-send-region)
-    (define-key map "\C-\M-x" 'python-shell-send-defun)
-    (define-key map "\C-c\C-c" 'python-shell-send-buffer)
-    (define-key map "\C-c\C-l" 'python-shell-send-file)
-    (define-key map "\C-c\C-z" 'python-shell-switch-to-shell)
+    (define-key map "\C-c\C-p" #'run-python)
+    (define-key map "\C-c\C-s" #'python-shell-send-string)
+    (define-key map "\C-c\C-e" #'python-shell-send-statement)
+    (define-key map "\C-c\C-r" #'python-shell-send-region)
+    (define-key map "\C-\M-x"  #'python-shell-send-defun)
+    (define-key map "\C-c\C-c" #'python-shell-send-buffer)
+    (define-key map "\C-c\C-l" #'python-shell-send-file)
+    (define-key map "\C-c\C-z" #'python-shell-switch-to-shell)
     ;; Some util commands
-    (define-key map "\C-c\C-v" 'python-check)
-    (define-key map "\C-c\C-f" 'python-eldoc-at-point)
-    (define-key map "\C-c\C-d" 'python-describe-at-point)
+    (define-key map "\C-c\C-v" #'python-check)
+    (define-key map "\C-c\C-f" #'python-eldoc-at-point)
+    (define-key map "\C-c\C-d" #'python-describe-at-point)
     ;; Utilities
-    (substitute-key-definition 'complete-symbol 'completion-at-point
+    (substitute-key-definition #'complete-symbol #'completion-at-point
                                map global-map)
     (easy-menu-define python-menu map "Python Mode menu"
       '("Python"
@@ -825,7 +825,6 @@ It makes underscores and dots word constituent chars.")
 
 (defcustom python-indent-offset 4
   "Default indentation offset for Python."
-  :group 'python
   :type 'integer
   :safe 'integerp)
 
@@ -835,21 +834,18 @@ It makes underscores and dots word constituent chars.")
 (defcustom python-indent-guess-indent-offset t
   "Non-nil tells Python mode to guess `python-indent-offset' value."
   :type 'boolean
-  :group 'python
   :safe 'booleanp)
 
 (defcustom python-indent-guess-indent-offset-verbose t
   "Non-nil means to emit a warning when indentation guessing fails."
   :version "25.1"
   :type 'boolean
-  :group 'python
   :safe' booleanp)
 
 (defcustom python-indent-trigger-commands
   '(indent-for-tab-command yas-expand yas/expand)
   "Commands that might trigger a `python-indent-line' call."
-  :type '(repeat symbol)
-  :group 'python)
+  :type '(repeat symbol))
 
 (defcustom python-indent-def-block-scale 2
   "Multiplier applied to indentation inside multi-line def blocks."
@@ -2031,7 +2027,6 @@ position, else returns nil."
 (defcustom python-shell-buffer-name "Python"
   "Default buffer name for Python interpreter."
   :type 'string
-  :group 'python
   :safe 'stringp)
 
 (defcustom python-shell-interpreter
@@ -2045,19 +2040,16 @@ Some Python interpreters also require changes to
 `python-shell-interpreter' to \"ipython3\" requires setting
 `python-shell-interpreter-args' to \"--simple-prompt\"."
   :version "28.1"
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (defcustom python-shell-internal-buffer-name "Python Internal"
   "Default buffer name for the Internal Python interpreter."
   :type 'string
-  :group 'python
   :safe 'stringp)
 
 (defcustom python-shell-interpreter-args "-i"
   "Default arguments for the Python interpreter."
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (defcustom python-shell-interpreter-interactive-arg "-i"
   "Interpreter argument to force it to run interactively."
@@ -2122,7 +2114,6 @@ It should not contain a caret (^) at the beginning."
   "Should syntax highlighting be enabled in the Python shell buffer?
 Restart the Python shell after changing this variable for it to take effect."
   :type 'boolean
-  :group 'python
   :safe 'booleanp)
 
 (defcustom python-shell-unbuffered t
@@ -2130,7 +2121,6 @@ Restart the Python shell after changing this variable for 
it to take effect."
 When non-nil, this may prevent delayed and missing output in the
 Python shell.  See commentary for details."
   :type 'boolean
-  :group 'python
   :safe 'booleanp)
 
 (defcustom python-shell-process-environment nil
@@ -2140,8 +2130,7 @@ When this variable is non-nil, values are exported into 
the
 process environment before starting it.  Any variables already
 present in the current environment are superseded by variables
 set here."
-  :type '(repeat string)
-  :group 'python)
+  :type '(repeat string))
 
 (defcustom python-shell-extra-pythonpaths nil
   "List of extra pythonpaths for Python shell.
@@ -2150,8 +2139,7 @@ the PYTHONPATH before starting processes.  Any values 
present
 here that already exists in PYTHONPATH are moved to the beginning
 of the list so that they are prioritized when looking for
 modules."
-  :type '(repeat string)
-  :group 'python)
+  :type '(repeat string))
 
 (defcustom python-shell-exec-path nil
   "List of paths for searching executables.
@@ -2159,8 +2147,7 @@ When this variable is non-nil, values added at the 
beginning of
 the PATH before starting processes.  Any values present here that
 already exists in PATH are moved to the beginning of the list so
 that they are prioritized when looking for executables."
-  :type '(repeat string)
-  :group 'python)
+  :type '(repeat string))
 
 (defcustom python-shell-remote-exec-path nil
   "List of paths to be ensured remotely for searching executables.
@@ -2171,8 +2158,7 @@ here.  Normally you won't use this variable directly 
unless you
 plan to ensure a particular set of paths to all Python shell
 executed through tramp connections."
   :version "25.1"
-  :type '(repeat string)
-  :group 'python)
+  :type '(repeat string))
 
 (define-obsolete-variable-alias
   'python-shell-virtualenv-path 'python-shell-virtualenv-root "25.1")
@@ -2182,13 +2168,11 @@ executed through tramp connections."
 This variable, when set to a string, makes the environment to be
 modified such that shells are started within the specified
 virtualenv."
-  :type '(choice (const nil) directory)
-  :group 'python)
+  :type '(choice (const nil) directory))
 
 (defcustom python-shell-setup-codes nil
   "List of code run by `python-shell-send-setup-code'."
-  :type '(repeat symbol)
-  :group 'python)
+  :type '(repeat symbol))
 
 (defcustom python-shell-compilation-regexp-alist
   `((,(rx line-start (1+ (any " \t")) "File \""
@@ -2202,8 +2186,7 @@ virtualenv."
           "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
      1 2))
   "`compilation-error-regexp-alist' for inferior Python."
-  :type '(alist regexp)
-  :group 'python)
+  :type '(alist regexp))
 
 (defvar python-shell-output-filter-in-progress nil)
 (defvar python-shell-output-filter-buffer nil)
@@ -2221,33 +2204,34 @@ virtualenv."
           (or (getenv "PYTHONPATH") "") path-separator 'omit)))
     (python-shell--add-to-path-with-priority
      pythonpath python-shell-extra-pythonpaths)
-    (mapconcat 'identity pythonpath path-separator)))
+    (mapconcat #'identity pythonpath path-separator)))
 
 (defun python-shell-calculate-process-environment ()
-  "Calculate `process-environment' or `tramp-remote-process-environment'.
+  (declare (obsolete python-shell--calculate-process-environment "29.1"))
+  (defvar tramp-remote-process-environment)
+  (let* ((remote-p (file-remote-p default-directory)))
+    (append (python-shell--calculate-process-environment)
+            (if remote-p
+                tramp-remote-process-environment
+              process-environment))))
+
+(defun python-shell--calculate-process-environment ()
+  "Return a list of entries to add to the `process-environment'.
 Prepends `python-shell-process-environment', sets extra
 pythonpaths from `python-shell-extra-pythonpaths' and sets a few
-virtualenv related vars.  If `default-directory' points to a
-remote host, the returned value is intended for
-`tramp-remote-process-environment'."
-  (let* ((remote-p (file-remote-p default-directory))
-         (process-environment (if remote-p
-                                  tramp-remote-process-environment
-                                process-environment))
-         (virtualenv (when python-shell-virtualenv-root
-                       (directory-file-name python-shell-virtualenv-root))))
-    (dolist (env python-shell-process-environment)
-      (pcase-let ((`(,key ,value) (split-string env "=")))
-        (setenv key value)))
+virtualenv related vars."
+  (let* ((virtualenv (when python-shell-virtualenv-root
+                       (directory-file-name python-shell-virtualenv-root)))
+         (res python-shell-process-environment))
     (when python-shell-unbuffered
-      (setenv "PYTHONUNBUFFERED" "1"))
+      (push "PYTHONUNBUFFERED=1" res))
     (when python-shell-extra-pythonpaths
-      (setenv "PYTHONPATH" (python-shell-calculate-pythonpath)))
+      (push (concat "PYTHONPATH=" (python-shell-calculate-pythonpath)) res))
     (if (not virtualenv)
-        process-environment
-      (setenv "PYTHONHOME" nil)
-      (setenv "VIRTUAL_ENV" virtualenv))
-    process-environment))
+        nil
+      (push "PYTHONHOME" res)
+      (push (concat "VIRTUAL_ENV=" virtualenv) res))
+    res))
 
 (defun python-shell-calculate-exec-path ()
   "Calculate `exec-path'.
@@ -2275,14 +2259,26 @@ of `exec-path'."
 
 (defun python-shell-tramp-refresh-remote-path (vec paths)
   "Update VEC's remote-path giving PATHS priority."
+  (cl-assert (featurep 'tramp))
+  (declare-function tramp-set-remote-path "tramp-sh")
+  (declare-function tramp-set-connection-property "tramp-cache")
+  (declare-function tramp-get-connection-property "tramp-cache")
   (let ((remote-path (tramp-get-connection-property vec "remote-path" nil)))
     (when remote-path
+      ;; FIXME: This part of the Tramp code still knows about Python!
       (python-shell--add-to-path-with-priority remote-path paths)
       (tramp-set-connection-property vec "remote-path" remote-path)
       (tramp-set-remote-path vec))))
 
+
 (defun python-shell-tramp-refresh-process-environment (vec env)
   "Update VEC's process environment with ENV."
+  (cl-assert (featurep 'tramp))
+  (defvar tramp-end-of-heredoc)
+  (defvar tramp-end-of-output)
+  ;; Do we even know that `tramp-sh' is loaded at this point?
+  ;; What about files accessed via FTP, sudo, ...?
+  (declare-function tramp-send-command "tramp-sh")
   ;; Stolen from `tramp-open-connection-setup-interactive-shell'.
   (let ((env (append (when (fboundp 'tramp-get-remote-locale)
                        ;; Emacs<24.4 compat.
@@ -2295,7 +2291,7 @@ of `exec-path'."
        unset vars item)
     (while env
       (setq item (split-string (car env) "=" 'omit))
-      (setcdr item (mapconcat 'identity (cdr item) "="))
+      (setcdr item (mapconcat #'identity (cdr item) "="))
       (if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
          (push (format "%s %s" (car item) (cdr item)) vars)
        (push (car item) unset))
@@ -2305,12 +2301,12 @@ of `exec-path'."
        vec
        (format "while read var val; do export $var=$val; done <<'%s'\n%s\n%s"
               tramp-end-of-heredoc
-              (mapconcat 'identity vars "\n")
+              (mapconcat #'identity vars "\n")
               tramp-end-of-heredoc)
        t))
     (when unset
       (tramp-send-command
-       vec (format "unset %s" (mapconcat 'identity unset " ")) t))))
+       vec (format "unset %s" (mapconcat #'identity unset " ")) t))))
 
 (defmacro python-shell-with-environment (&rest body)
   "Modify shell environment during execution of BODY.
@@ -2319,41 +2315,49 @@ execution of body.  If `default-directory' points to a 
remote
 machine then modifies `tramp-remote-process-environment' and
 `python-shell-remote-exec-path' instead."
   (declare (indent 0) (debug (body)))
-  (let ((vec (make-symbol "vec")))
-    `(progn
-       (let* ((,vec
-               (when (file-remote-p default-directory)
-                 (ignore-errors
-                   (tramp-dissect-file-name default-directory 'noexpand))))
-              (process-environment
-               (if ,vec
-                   process-environment
-                 (python-shell-calculate-process-environment)))
-              (exec-path
-               (if ,vec
-                   exec-path
-                 (python-shell-calculate-exec-path)))
-              (tramp-remote-process-environment
-               (if ,vec
-                   (python-shell-calculate-process-environment)
-                 tramp-remote-process-environment)))
-         (when (tramp-get-connection-process ,vec)
-           ;; For already existing connections, the new exec path must
-           ;; be re-set, otherwise it won't take effect.  One example
-           ;; of such case is when remote dir-locals are read and
-           ;; *then* subprocesses are triggered within the same
-           ;; connection.
-           (python-shell-tramp-refresh-remote-path
-            ,vec (python-shell-calculate-exec-path))
-           ;; The `tramp-remote-process-environment' variable is only
-           ;; effective when the started process is an interactive
-           ;; shell, otherwise (like in the case of processes started
-           ;; with `process-file') the environment is not changed.
-           ;; This makes environment modifications effective
-           ;; unconditionally.
-           (python-shell-tramp-refresh-process-environment
-            ,vec tramp-remote-process-environment))
-         ,(macroexp-progn body)))))
+  `(python-shell--with-environment
+    (python-shell--calculate-process-environment)
+    (lambda () ,@body)))
+
+(defun python-shell--with-environment (extraenv bodyfun)
+  ;; FIXME: This is where the generic code delegates to Tramp.
+  (let* ((vec
+          (and (file-remote-p default-directory)
+               (fboundp 'tramp-dissect-file-name)
+               (ignore-errors
+                 (tramp-dissect-file-name default-directory 'noexpand)))))
+    (if vec
+        (python-shell--tramp-with-environment vec extraenv bodyfun)
+      (let ((process-environment
+             (append extraenv process-environment))
+            (exec-path
+             ;; FIXME: This is still Python-specific.
+             (python-shell-calculate-exec-path)))
+        (funcall bodyfun)))))
+
+(defun python-shell--tramp-with-environment (vec extraenv bodyfun)
+  (defvar tramp-remote-process-environment)
+  (declare-function tramp-get-connection-process "tramp" (vec))
+  (let* ((tramp-remote-process-environment
+          (append extraenv tramp-remote-process-environment)))
+    (when (tramp-get-connection-process vec)
+      ;; For already existing connections, the new exec path must
+      ;; be re-set, otherwise it won't take effect.  One example
+      ;; of such case is when remote dir-locals are read and
+      ;; *then* subprocesses are triggered within the same
+      ;; connection.
+      (python-shell-tramp-refresh-remote-path
+       ;; FIXME: This is still Python-specific.
+       vec (python-shell-calculate-exec-path))
+      ;; The `tramp-remote-process-environment' variable is only
+      ;; effective when the started process is an interactive
+      ;; shell, otherwise (like in the case of processes started
+      ;; with `process-file') the environment is not changed.
+      ;; This makes environment modifications effective
+      ;; unconditionally.
+      (python-shell-tramp-refresh-process-environment
+       vec tramp-remote-process-environment))
+    (funcall bodyfun)))
 
 (defvar python-shell--prompt-calculated-input-regexp nil
   "Calculated input prompt regexp for inferior python shell.
@@ -2636,7 +2640,7 @@ banner and the initial prompt are received separately."
 
 (define-obsolete-function-alias
   'python-comint-output-filter-function
-  'ansi-color-filter-apply
+  #'ansi-color-filter-apply
   "25.1")
 
 (defun python-comint-postoutput-scroll-to-bottom (output)
@@ -2821,8 +2825,7 @@ current process to not hang while waiting.  This is 
useful to
 safely attach setup code for long-running processes that
 eventually provide a shell."
   :version "25.1"
-  :type 'hook
-  :group 'python)
+  :type 'hook)
 
 (defconst python-shell-eval-setup-code
   "\
@@ -2956,7 +2959,7 @@ variable.
   (add-hook 'completion-at-point-functions
             #'python-shell-completion-at-point nil 'local)
   (define-key inferior-python-mode-map "\t"
-    'python-shell-completion-complete-or-indent)
+    #'python-shell-completion-complete-or-indent)
   (make-local-variable 'python-shell-internal-last-output)
   (when python-shell-font-lock-enable
     (python-shell-font-lock-turn-on))
@@ -2982,7 +2985,8 @@ killed."
           (let* ((cmdlist (split-string-and-unquote cmd))
                  (interpreter (car cmdlist))
                  (args (cdr cmdlist))
-                 (buffer (apply #'make-comint-in-buffer proc-name 
proc-buffer-name
+                 (buffer (apply #'make-comint-in-buffer proc-name
+                                proc-buffer-name
                                 interpreter nil args))
                  (python-shell--parent-buffer (current-buffer))
                  (process (get-buffer-process buffer))
@@ -3131,7 +3135,7 @@ there for compatibility with CEDET.")
       (run-python-internal))))
 
 (define-obsolete-function-alias
-  'python-proc 'python-shell-internal-get-or-create-process "24.3")
+  'python-proc #'python-shell-internal-get-or-create-process "24.3")
 
 (defun python-shell--save-temp-file (string)
   (let* ((temporary-file-directory
@@ -3250,10 +3254,10 @@ Returns the output.  See 
`python-shell-send-string-no-output'."
          (python-shell-internal-get-or-create-process))))
 
 (define-obsolete-function-alias
-  'python-send-receive 'python-shell-internal-send-string "24.3")
+  'python-send-receive #'python-shell-internal-send-string "24.3")
 
 (define-obsolete-function-alias
-  'python-send-string 'python-shell-internal-send-string "24.3")
+  'python-send-string #'python-shell-internal-send-string "24.3")
 
 (defun python-shell-buffer-substring (start end &optional nomain no-cookie)
   "Send buffer substring from START to END formatted for shell.
@@ -3549,8 +3553,7 @@ def __PYTHON_EL_get_completions(text):
             completer.print_mode = True
     return completions"
   "Code used to setup completion in inferior Python processes."
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (define-obsolete-variable-alias
   'python-shell-completion-module-string-code
@@ -3823,7 +3826,8 @@ With argument MSG show activation/deactivation message."
               ;; in use based on its args and uses `apply-partially'
               ;; to make it up for the 3 args case.
               (if (= (length
-                      (help-function-arglist 'comint-redirect-filter)) 3)
+                      (help-function-arglist 'comint-redirect-filter))
+                     3)
                   (set-process-filter
                    process (apply-partially
                             #'comint-redirect-filter original-filter-fn))
@@ -3932,7 +3936,7 @@ using that one instead of current buffer's process."
 
 (define-obsolete-function-alias
   'python-shell-completion-complete-at-point
-  'python-shell-completion-at-point
+  #'python-shell-completion-at-point
   "25.1")
 
 (defun python-shell-completion-complete-or-indent ()
@@ -3961,7 +3965,6 @@ considered over.  The overlay arrow will be removed from 
the currently tracked
 buffer.  Additionally, if `python-pdbtrack-kill-buffers' is non-nil, all
 files opened by pdbtracking will be killed."
   :type 'boolean
-  :group 'python
   :safe 'booleanp)
 
 (defcustom python-pdbtrack-stacktrace-info-regexp
@@ -4170,7 +4173,7 @@ inferior Python process is updated properly."
 
 (define-obsolete-function-alias
   'python-completion-complete-at-point
-  'python-completion-at-point
+  #'python-completion-at-point
   "25.1")
 
 
@@ -4180,29 +4183,25 @@ inferior Python process is updated properly."
   "Function to fill comments.
 This is the function used by `python-fill-paragraph' to
 fill comments."
-  :type 'symbol
-  :group 'python)
+  :type 'symbol)
 
 (defcustom python-fill-string-function 'python-fill-string
   "Function to fill strings.
 This is the function used by `python-fill-paragraph' to
 fill strings."
-  :type 'symbol
-  :group 'python)
+  :type 'symbol)
 
 (defcustom python-fill-decorator-function 'python-fill-decorator
   "Function to fill decorators.
 This is the function used by `python-fill-paragraph' to
 fill decorators."
-  :type 'symbol
-  :group 'python)
+  :type 'symbol)
 
 (defcustom python-fill-paren-function 'python-fill-paren
   "Function to fill parens.
 This is the function used by `python-fill-paragraph' to
 fill parens."
-  :type 'symbol
-  :group 'python)
+  :type 'symbol)
 
 (defcustom python-fill-docstring-style 'pep-257
   "Style used to fill docstrings.
@@ -4272,7 +4271,6 @@ value may result in one of the following docstring styles:
           (const :tag "PEP-257 with 2 newlines at end of string." pep-257)
           (const :tag "PEP-257 with 1 newline at end of string." pep-257-nn)
           (const :tag "Symmetric style." symmetric))
-  :group 'python
   :safe (lambda (val)
           (memq val '(django onetwo pep-257 pep-257-nn symmetric nil))))
 
@@ -4431,7 +4429,6 @@ JUSTIFY should be used (if applicable) as in 
`fill-paragraph'."
 This happens when pressing \"if<SPACE>\", for example, to prompt for
 the if condition."
   :type 'boolean
-  :group 'python
   :safe 'booleanp)
 
 (defvar python-skeleton-available '()
@@ -4556,7 +4553,7 @@ The skeleton will be bound to python-skeleton-NAME."
 
 (defun python-skeleton-add-menu-items ()
   "Add menu items to Python->Skeletons menu."
-  (let ((skeletons (sort python-skeleton-available 'string<)))
+  (let ((skeletons (sort python-skeleton-available #'string<)))
     (dolist (skeleton skeletons)
       (easy-menu-add-item
        nil '("Python" "Skeletons")
@@ -4586,8 +4583,7 @@ def __FFAP_get_module_path(objstr):
     except:
         return ''"
   "Python code to get a module path."
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (defun python-ffap-module-path (module)
   "Function for `ffap-alist' to return path for MODULE."
@@ -4615,14 +4611,12 @@ def __FFAP_get_module_path(objstr):
       (executable-find "epylint")
       "install pyflakes, pylint or something else")
   "Command used to check a Python file."
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (defcustom python-check-buffer-name
   "*Python check: %s*"
   "Buffer name used for check commands."
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (defvar python-check-custom-command nil
   "Internal use.")
@@ -4689,8 +4683,7 @@ See `python-check-command' for the default."
         doc = ''
     return doc"
   "Python code to setup documentation retrieval."
-  :type 'string
-  :group 'python)
+  :type 'string)
 
 (defun python-eldoc--get-symbol-at-point ()
   "Get the current symbol for eldoc.
@@ -4737,14 +4730,13 @@ Set to nil by `python-eldoc-function' if
 
 (defcustom python-eldoc-function-timeout 1
   "Timeout for `python-eldoc-function' in seconds."
-  :group 'python
   :type 'integer
   :version "25.1")
 
 (defcustom python-eldoc-function-timeout-permanent t
-  "Non-nil means that when `python-eldoc-function' times out
-`python-eldoc-get-doc' will be set to nil."
-  :group 'python
+  "If non-nil, a timeout in Python-Eldoc will disable it permanently.
+Python-Eldoc can be re-enabled manually by setting `python-eldoc-get-doc'
+back to t in the affected buffer."
   :type 'boolean
   :version "25.1")
 
@@ -4936,7 +4928,7 @@ To this:
      (\"decorator.wrapped_f\" . 393))"
   ;; Inspired by imenu--flatten-index-alist removed in revno 21853.
   (apply
-   'nconc
+   #'nconc
    (mapcar
     (lambda (item)
       (let ((name (if prefix
@@ -5019,7 +5011,7 @@ since it returns nil if point is not inside a defun."
             (and (= (current-indentation) 0) (throw 'exit t))))
         (and names
              (concat (and type (format "%s " type))
-                     (mapconcat 'identity names ".")))))))
+                     (mapconcat #'identity names ".")))))))
 
 (defun python-info-current-symbol (&optional replace-self)
   "Return current symbol using dotty syntax.
@@ -5040,9 +5032,10 @@ parent defun name."
             (replace-regexp-in-string
              (python-rx line-start word-start "self" word-end ?.)
              (concat
-              (mapconcat 'identity
+              (mapconcat #'identity
                          (butlast (split-string current-defun "\\."))
-                         ".") ".")
+                         ".")
+              ".")
              name)))))))
 
 (defun python-info-statement-starts-block-p ()
@@ -5084,7 +5077,7 @@ parent defun name."
 
 (define-obsolete-function-alias
   'python-info-closing-block
-  'python-info-dedenter-opening-block-position "24.4")
+  #'python-info-dedenter-opening-block-position "24.4")
 
 (defun python-info-dedenter-opening-block-position ()
   "Return the point of the closest block the current line closes.
@@ -5129,7 +5122,8 @@ likely an invalid python file."
               (let ((indentation (current-indentation)))
                 (when (and (not (memq indentation collected-indentations))
                            (or (not collected-indentations)
-                               (< indentation (apply #'min 
collected-indentations)))
+                               (< indentation
+                                  (apply #'min collected-indentations)))
                            ;; There must be no line with indentation
                            ;; smaller than `indentation' (except for
                            ;; blank lines) between the found opening
@@ -5157,7 +5151,7 @@ likely an invalid python file."
 
 (define-obsolete-function-alias
   'python-info-closing-block-message
-  'python-info-dedenter-opening-block-message "24.4")
+  #'python-info-dedenter-opening-block-message "24.4")
 
 (defun python-info-dedenter-opening-block-message  ()
   "Message the first line of the block the current statement closes."
@@ -5459,10 +5453,12 @@ allowed files."
   (let ((dir-name (file-name-as-directory dir)))
     (apply #'nconc
            (mapcar (lambda (file-name)
-                     (let ((full-file-name (expand-file-name file-name 
dir-name)))
+                     (let ((full-file-name
+                            (expand-file-name file-name dir-name)))
                        (when (and
                               (not (member file-name '("." "..")))
-                              (funcall (or predicate #'identity) 
full-file-name))
+                              (funcall (or predicate #'identity)
+                                       full-file-name))
                          (list full-file-name))))
                    (directory-files dir-name)))))
 
@@ -5530,7 +5526,6 @@ required arguments.  Once launched it will receive the 
Python source to be
 checked as its standard input.
 To use `flake8' you would set this to (\"flake8\" \"-\")."
   :version "26.1"
-  :group 'python-flymake
   :type '(repeat string))
 
 ;; The default regexp accommodates for older pyflakes, which did not
@@ -5552,7 +5547,6 @@ If COLUMN or TYPE are nil or that index didn't match, that
 information is not present on the matched line and a default will
 be used."
   :version "26.1"
-  :group 'python-flymake
   :type '(list regexp
                (integer :tag "Line's index")
                (choice
@@ -5577,7 +5571,6 @@ configuration could be:
 
 By default messages are considered errors."
   :version "26.1"
-  :group 'python-flymake
   :type '(alist :key-type (regexp)
                 :value-type (symbol)))
 
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 3ad0f0182f..0a2ec348c1 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1973,7 +1973,7 @@ May return nil if the line should not be treated as 
continued."
          (cons 'column (smie-indent-keyword ";"))
        (smie-rule-separator kind)))
     (`(:after . ,(or ";;" ";&" ";;&"))
-     (with-demoted-errors
+     (with-demoted-errors "SMIE rule error: %S"
        (smie-backward-sexp token)
        (cons 'column
              (if (or (smie-rule-bolp)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 37e2159782..4efa652084 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1481,8 +1481,9 @@ is nil, prompt only if there's no usable symbol at point."
 (defun xref-find-references-and-replace (from to)
   "Replace all references to identifier FROM with TO."
   (interactive
-   (let ((common
-          (query-replace-read-args "Query replace identifier" nil)))
+   (let* ((query-replace-read-from-default 'find-tag-default)
+          (common
+           (query-replace-read-args "Query replace identifier" nil)))
      (list (nth 0 common) (nth 1 common))))
   (require 'xref)
   (with-current-buffer
diff --git a/lisp/replace.el b/lisp/replace.el
index 299e42b20e..4d7b3ccb5b 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -186,6 +186,12 @@ See `replace-regexp' and `query-replace-regexp-eval'.")
                         length)
              length)))))
 
+(defvar query-replace-read-from-default nil
+  "Function to get default non-regexp value for `query-replace-read-from'.")
+
+(defvar query-replace-read-from-regexp-default nil
+  "Function to get default regexp value for `query-replace-read-from'.")
+
 (defun query-replace-read-from-suggestions ()
   "Return a list of standard suggestions for `query-replace-read-from'.
 By default, the list includes the active region, the identifier
@@ -233,8 +239,12 @@ wants to replace FROM with TO."
                       query-replace-defaults))
             (symbol-value query-replace-from-history-variable)))
           (minibuffer-allow-text-properties t) ; separator uses text-properties
+          (default (when (and query-replace-read-from-default (not 
regexp-flag))
+                     (funcall query-replace-read-from-default)))
           (prompt
-           (cond ((and query-replace-defaults separator)
+            (cond ((and query-replace-read-from-regexp-default regexp-flag) 
prompt)
+                  (default (format-prompt prompt default))
+                  ((and query-replace-defaults separator)
                    (format-prompt prompt (car minibuffer-history)))
                   (query-replace-defaults
                    (format-prompt
@@ -255,16 +265,26 @@ wants to replace FROM with TO."
                                 (append '((separator . t) (face . t))
                                         text-property-default-nonsticky)))
                 (if regexp-flag
-                    (read-regexp prompt nil 'minibuffer-history)
+                    (read-regexp
+                     (if query-replace-read-from-regexp-default
+                         (string-remove-suffix ": " prompt)
+                       prompt)
+                     query-replace-read-from-regexp-default
+                     'minibuffer-history)
                   (read-from-minibuffer
                    prompt nil nil nil nil
-                   (query-replace-read-from-suggestions) t)))))
+                   (if default
+                       (delete-dups
+                        (cons default (query-replace-read-from-suggestions)))
+                     (query-replace-read-from-suggestions))
+                   t)))))
            (to))
-      (if (and (zerop (length from)) query-replace-defaults)
+      (if (and (zerop (length from)) query-replace-defaults (not default))
          (cons (caar query-replace-defaults)
                (query-replace-compile-replacement
                 (cdar query-replace-defaults) regexp-flag))
-        (setq from (query-replace--split-string from))
+        (setq from (or (and (zerop (length from)) default)
+                       (query-replace--split-string from)))
         (when (consp from) (setq to (cdr from) from (car from)))
         (add-to-history query-replace-from-history-variable from nil t)
         ;; Warn if user types \n or \t, but don't reject the input.
@@ -1413,10 +1433,15 @@ To return to ordinary Occur mode, use 
\\[occur-cease-edit]."
                             (length s1)))))
                      (prefix-len (funcall common-prefix buf-str text))
                      (suffix-len (funcall common-prefix
-                                          (reverse buf-str) (reverse text))))
+                                          (reverse (substring
+                                                    buf-str prefix-len))
+                                          (reverse (substring
+                                                    text prefix-len)))))
                 (setq beg-pos (+ beg-pos prefix-len))
                 (setq end-pos (- end-pos suffix-len))
-                (setq text (substring text prefix-len (- suffix-len)))
+                (setq text (substring text prefix-len
+                                      (and (not (zerop suffix-len))
+                                           (- suffix-len))))
                 (delete-region beg-pos end-pos)
                 (goto-char beg-pos)
                 (insert text)))
diff --git a/lisp/select.el b/lisp/select.el
index 7f29f02dab..ca9061c0b0 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -168,20 +168,28 @@ text/plain\\;charset=utf-8)."
 Call `gui-get-selection' with an appropriate DATA-TYPE argument
 decided by `x-select-request-type'.  The return value is already
 decoded.  If `gui-get-selection' signals an error, return nil."
-  (let ((request-type (if (memq window-system '(x pgtk))
-                          (or x-select-request-type
-                              '(UTF8_STRING COMPOUND_TEXT STRING 
text/plain\;charset=utf-8))
-                        'STRING))
-       text)
-    (with-demoted-errors "gui-get-selection: %S"
-      (if (consp request-type)
-          (while (and request-type (not text))
-            (setq text (gui-get-selection type (car request-type)))
-            (setq request-type (cdr request-type)))
-        (setq text (gui-get-selection type request-type))))
-    (if text
-       (remove-text-properties 0 (length text) '(foreign-selection nil) text))
-    text))
+  ;; The doc string of `interprogram-paste-function' says to return
+  ;; nil if no other program has provided text to paste.
+  (unless (and
+           ;; `gui-backend-selection-owner-p' might be unreliable on
+           ;; some other window systems.
+           (memq window-system '(x haiku))
+           (eq type 'CLIPBOARD)
+           (gui-backend-selection-owner-p type))
+    (let ((request-type (if (memq window-system '(x pgtk))
+                            (or x-select-request-type
+                                '(UTF8_STRING COMPOUND_TEXT STRING 
text/plain\;charset=utf-8))
+                          'STRING))
+         text)
+      (with-demoted-errors "gui-get-selection: %S"
+        (if (consp request-type)
+            (while (and request-type (not text))
+              (setq text (gui-get-selection type (car request-type)))
+              (setq request-type (cdr request-type)))
+          (setq text (gui-get-selection type request-type))))
+      (if text
+         (remove-text-properties 0 (length text) '(foreign-selection nil) 
text))
+      text)))
 
 (defun gui-selection-value ()
   (let ((clip-text
diff --git a/lisp/simple.el b/lisp/simple.el
index ac1d89b670..ebf2285352 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1295,6 +1295,11 @@ If Transient Mark mode is enabled, the mark is active, 
and N is 1,
 delete the text in the region and deactivate the mark instead.
 To disable this, set variable `delete-active-region' to nil.
 
+If N is positive, characters composed into a single grapheme cluster
+count as a single character and are deleted together.  Thus,
+\"\\[universal-argument] 2 \\[delete-forward-char]\" when two grapheme 
clusters follow point will
+delete the characters composed into both of the grapheme clusters.
+
 Optional second arg KILLFLAG non-nil means to kill (save in kill
 ring) instead of delete.  If called interactively, a numeric
 prefix argument specifies N, and KILLFLAG is also set if a prefix
@@ -1315,6 +1320,21 @@ the actual saved text might be different from what was 
killed."
             (kill-region (region-beginning) (region-end) 'region)
           (funcall region-extract-function 'delete-only)))
 
+       ;; For forward deletion, treat composed characters as a single
+       ;; character to delete.
+        ((>= n 1)
+         (let ((pos (point))
+               start cmp)
+           (setq start pos)
+           (while (> n 0)
+             ;; 'find-composition' will return (FROM TO ....) or nil.
+             (setq cmp (find-composition pos))
+             (if cmp
+                 (setq pos (cadr cmp))
+               (setq pos (1+ pos)))
+             (setq n (1- n)))
+           (delete-char (- pos start) killflag)))
+
        ;; Otherwise, do simple deletion.
        (t (delete-char n killflag))))
 
diff --git a/lisp/sort.el b/lisp/sort.el
index eb8e2787d1..90eee01caf 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -286,25 +286,30 @@ FIELD, BEG and END.  BEG and END specify region to sort."
   (interactive "p\nr")
   (let ;; To make `end-of-line' and etc. to ignore fields.
       ((inhibit-field-text-motion t))
-    (sort-fields-1 field beg end
-                  (lambda ()
-                    (sort-skip-fields field)
-                    (let* ((case-fold-search t)
-                           (base
-                            (if (looking-at "\\(0x\\)[0-9a-f]\\|\\(0\\)[0-7]")
-                                (cond ((match-beginning 1)
-                                       (goto-char (match-end 1))
-                                       16)
-                                      ((match-beginning 2)
-                                       (goto-char (match-end 2))
-                                       8)
-                                      (t nil)))))
-                      (string-to-number (buffer-substring (point)
-                                                          (save-excursion
-                                                            (forward-sexp 1)
-                                                            (point)))
-                                        (or base sort-numeric-base))))
-                  nil)))
+    (sort-fields-1
+     field beg end
+     (lambda ()
+       ;; Don't try to parse blank lines (they'll be
+       ;; sorted at the start).
+       (if (looking-at "[\t ]*$")
+           0
+        (sort-skip-fields field)
+        (let* ((case-fold-search t)
+               (base
+                (if (looking-at "\\(0x\\)[0-9a-f]\\|\\(0\\)[0-7]")
+                    (cond ((match-beginning 1)
+                           (goto-char (match-end 1))
+                           16)
+                          ((match-beginning 2)
+                           (goto-char (match-end 2))
+                           8)
+                          (t nil)))))
+          (string-to-number (buffer-substring (point)
+                                              (save-excursion
+                                                (forward-sexp 1)
+                                                (point)))
+                            (or base sort-numeric-base)))))
+     nil)))
 
 ;;;;;###autoload
 ;;(defun sort-float-fields (field beg end)
diff --git a/lisp/startup.el b/lisp/startup.el
index 66dd726ae9..d838dd6827 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -519,14 +519,14 @@ DIRS are relative."
       xdg-dir)
      (t emacs-d-dir))))
 
-(defvar comp--loadable)
+(defvar comp--compilable)
 (defvar comp--delayed-sources)
 (defun startup--require-comp-safely ()
   "Require the native compiler avoiding circular dependencies."
-  (unless (featurep 'comp)
-    ;; Require comp with `comp--loadable' set to nil to break
+  (when (featurep 'native-compile)
+    ;; Require comp with `comp--compilable' set to nil to break
     ;; circularity.
-    (let ((comp--loadable nil))
+    (let ((comp--compilable nil))
       (require 'comp))
     (native--compile-async comp--delayed-sources nil 'late)
     (setq comp--delayed-sources nil)))
@@ -538,7 +538,7 @@ DIRS are relative."
   (when (and (native-comp-available-p)
              comp--delayed-sources)
     (startup--require-comp-safely))
-  (setq comp--loadable t))
+  (setq comp--compilable t))
 
 (defvar native-comp-eln-load-path)
 (defun normal-top-level ()
@@ -558,6 +558,27 @@ It is the default value of the variable `top-level'."
     (setq user-emacs-directory
          (startup--xdg-or-homedot startup--xdg-config-home-emacs nil))
 
+    (when (featurep 'native-compile)
+      ;; Form `native-comp-eln-load-path'.
+      (let ((path-env (getenv "EMACSNATIVELOADPATH")))
+        (when path-env
+          (dolist (path (split-string path-env path-separator))
+            (unless (string= "" path)
+              (push path native-comp-eln-load-path)))))
+      (push (expand-file-name "eln-cache/" user-emacs-directory)
+            native-comp-eln-load-path)
+      ;; When $HOME is set to '/nonexistent' means we are running the
+      ;; testsuite, add a temporary folder in front to produce there
+      ;; new compilations.
+      (when (and (equal (getenv "HOME") "/nonexistent")
+                 ;; We may be running in a chroot environment where we
+                 ;; can't write anything.
+                 (file-writable-p (expand-file-name
+                                   (or temporary-file-directory ""))))
+        (let ((tmp-dir (make-temp-file "emacs-testsuite-" t)))
+          (add-hook 'kill-emacs-hook (lambda () (delete-directory tmp-dir t)))
+          (push tmp-dir native-comp-eln-load-path))))
+
     ;; Look in each dir in load-path for a subdirs.el file.  If we
     ;; find one, load it, which will add the appropriate subdirs of
     ;; that dir into load-path.  This needs to be done before setting
@@ -644,6 +665,16 @@ It is the default value of the variable `top-level'."
                (set pathsym (mapcar (lambda (dir)
                                       (decode-coding-string dir coding t))
                                     path)))))
+        (when (featurep 'native-compile)
+          (let ((npath (symbol-value 'native-comp-eln-load-path)))
+            (set 'native-comp-eln-load-path
+                 (mapcar (lambda (dir)
+                           ;; Call expand-file-name to remove all the
+                           ;; pesky ".." from the directyory names in
+                           ;; native-comp-eln-load-path.
+                           (expand-file-name
+                            (decode-coding-string dir coding t)))
+                         npath))))
        (dolist (filesym '(data-directory doc-directory exec-directory
                                          installation-directory
                                          invocation-directory invocation-name
@@ -801,6 +832,35 @@ It is the default value of the variable `top-level'."
        (unless inhibit-startup-hooks
          (run-hooks 'window-setup-hook))))
 
+    ;; Amend `native-comp-eln-load-path' after `command-line', since
+    ;; the latter may have altered `user-emacs-directory'.
+    (when (featurep 'native-compile)
+      (let ((tmp-dir (and (equal (getenv "HOME") "/nonexistent")
+                          (file-writable-p (expand-file-name
+                                            (or temporary-file-directory "")))
+                          (car native-comp-eln-load-path)))
+            (coding (if (eq system-type 'windows-nt)
+                       'utf-8
+                     locale-coding-system)))
+        (if tmp-dir
+            (setq native-comp-eln-load-path
+                  (cdr native-comp-eln-load-path)))
+        ;; Remove the original eln-cache.
+        (setq native-comp-eln-load-path
+              (cdr native-comp-eln-load-path))
+        ;; Add the new eln-cache.
+        (push (expand-file-name "eln-cache/"
+                                (if coding
+                                    (decode-coding-string user-emacs-directory
+                                                          coding t)
+                                  user-emacs-directory))
+              native-comp-eln-load-path)
+        (when tmp-dir
+          ;; Recompute tmp-dir, in case user-emacs-directory affects it.
+          (setq tmp-dir (make-temp-file "emacs-testsuite-" t))
+          (add-hook 'kill-emacs-hook (lambda () (delete-directory tmp-dir t)))
+          (push tmp-dir native-comp-eln-load-path))))
+
     ;; Subprocesses of Emacs do not have direct access to the terminal, so
     ;; unless told otherwise they should only assume a dumb terminal.
     ;; We are careful to do it late (after term-setup-hook), although the
diff --git a/lisp/subr.el b/lisp/subr.el
index 2749c4c5c8..19ab20c5b5 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1149,8 +1149,17 @@ Subkeymaps may be modified but are not canonicalized."
       (setq map (map-keymap ;; -internal
                  (lambda (key item)
                    (if (consp key)
-                       ;; Treat char-ranges specially.
-                       (push (cons key item) ranges)
+                       (if (= (car key) (1- (cdr key)))
+                           ;; If we have a two-character range, then
+                           ;; treat it as two separate characters
+                           ;; (because this makes `describe-bindings'
+                           ;; look better and shouldn't affect
+                           ;; anything else).
+                           (progn
+                             (push (cons (car key) item) bindings)
+                             (push (cons (cdr key) item) bindings))
+                         ;; Treat char-ranges specially.
+                         (push (cons key item) ranges))
                      (push (cons key item) bindings)))
                  map)))
     ;; Create the new map.
@@ -3250,11 +3259,13 @@ switch back again to the minibuffer before entering the
 character.  This is not possible when using `read-key', but using
 `read-key' may be less confusing to some users.")
 
+(defvar from--tty-menu-p nil
+  "Non-nil means the current command was invoked from a TTY menu.")
 (defun use-dialog-box-p ()
-  "Say whether the user should be prompted with a dialog popup box."
-  (and (display-popup-menus-p)
-       last-input-event                 ; not during startup
-       (listp last-nonmenu-event)
+  "Say whether the current command should prompt the user via a dialog box."
+  (and last-input-event                 ; not during startup
+       (or (listp last-nonmenu-event)   ; invoked by a mouse event
+           from--tty-menu-p)            ; invoked via TTY menu
        use-dialog-box))
 
 (defun y-or-n-p (prompt)
@@ -4521,19 +4532,21 @@ It should contain a single %-sequence; e.g., \"Error: 
%S\".
 
 If `debug-on-error' is non-nil, run BODY without catching its errors.
 This is to be used around code that is not expected to signal an error
-but that should be robust in the unexpected case that an error is signaled.
-
-For backward compatibility, if FORMAT is not a constant string, it
-is assumed to be part of BODY, in which case the message format
-used is \"Error: %S\"."
+but that should be robust in the unexpected case that an error is signaled."
   (declare (debug t) (indent 1))
-  (let ((err (make-symbol "err"))
-        (format (if (and (stringp format) body) format
-                  (prog1 "Error: %S"
-                    (if format (push format body))))))
-    `(condition-case-unless-debug ,err
-         ,(macroexp-progn body)
-       (error (message ,format ,err) nil))))
+  (let* ((err (make-symbol "err"))
+         (orig-body body)
+         (format (if (and (stringp format) body) format
+                   (prog1 "Error: %S"
+                     (if format (push format body)))))
+         (exp
+          `(condition-case-unless-debug ,err
+               ,(macroexp-progn body)
+             (error (message ,format ,err) nil))))
+    (if (eq orig-body body) exp
+      ;; The use without `format' is obsolete, let's warn when we bump
+      ;; into any such remaining uses.
+      (macroexp-warn-and-return format "Missing format argument" exp))))
 
 (defmacro combine-after-change-calls (&rest body)
   "Execute BODY, but don't call the after-change functions till the end.
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index d49fc2efea..06ad8f60af 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -751,9 +751,13 @@ Used by `tab-bar-format-menu-bar'."
                 (menu-bar-keymap))
     (popup-menu menu event)))
 
+(defvar tab-bar-menu-bar-button
+  (propertize "Menu" 'face 'tab-bar-tab-inactive)
+  "Button for the menu bar.")
+
 (defun tab-bar-format-menu-bar ()
   "Produce the Menu button for the tab bar that shows the menu bar."
-  `((menu-bar menu-item (propertize "Menu" 'face 'tab-bar-tab-inactive)
+  `((menu-bar menu-item ,tab-bar-menu-bar-button
      tab-bar-menu-bar :help "Menu Bar")))
 
 (defun tab-bar-format-history ()
diff --git a/lisp/tab-line.el b/lisp/tab-line.el
index 1c1217cdf6..24033945f0 100644
--- a/lisp/tab-line.el
+++ b/lisp/tab-line.el
@@ -558,8 +558,9 @@ inherit from `tab-line-tab-inactive-alternate'.  For use in
 When TAB is a non-file-visiting buffer, make FACE inherit from
 `tab-line-tab-special'.  For use in
 `tab-line-tab-face-functions'."
-  (when (and buffer-p (not (buffer-file-name tab)))
-    (setf face `(:inherit (tab-line-tab-special ,face))))
+  (let ((buffer (if buffer-p tab (cdr (assq 'buffer tab)))))
+    (when (and buffer (not (buffer-file-name buffer)))
+      (setf face `(:inherit (tab-line-tab-special ,face)))))
   face)
 
 (defun tab-line-tab-face-modified (tab _tabs face buffer-p _selected-p)
@@ -567,8 +568,9 @@ When TAB is a non-file-visiting buffer, make FACE inherit 
from
 When TAB is a modified, file-backed buffer, make FACE inherit
 from `tab-line-tab-modified'.  For use in
 `tab-line-tab-face-functions'."
-  (when (and buffer-p (buffer-file-name tab) (buffer-modified-p tab))
-    (setf face `(:inherit (tab-line-tab-modified ,face))))
+  (let ((buffer (if buffer-p tab (cdr (assq 'buffer tab)))))
+    (when (and buffer (buffer-file-name buffer) (buffer-modified-p buffer))
+      (setf face `(:inherit (tab-line-tab-modified ,face)))))
   face)
 
 (defun tab-line-tab-face-group (tab _tabs face _buffer-p _selected-p)
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index 019a01e22c..298c23566e 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -1563,6 +1563,19 @@ EVENT is a preedit-text event."
 
 (defvaralias 'x-gtk-use-system-tooltips 'use-system-tooltips)
 
+(declare-function x-internal-focus-input-context (focus frame) "xfns.c")
+
+(defun x-gtk-use-native-input-watcher (_symbol newval &rest _ignored)
+  "Variable watcher for `x-gtk-use-native-input'.
+If NEWVAL is non-nil and the selected frame is displayed through X,
+focus the GTK input context."
+  (when (and (featurep 'gtk)
+             (eq (framep (selected-frame)) 'x))
+    (x-internal-focus-input-context newval (selected-frame))))
+
+(add-variable-watcher 'x-gtk-use-native-input
+                      #'x-gtk-use-native-input-watcher)
+
 (provide 'x-win)
 (provide 'term/x-win)
 
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index 4ba3c2193e..f6f72cec4f 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -381,7 +381,7 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels 
[f]ollow [x]r [?]Help
                 (- (or reftex-last-window-height (window-height))
                    (window-height)))))
     (when (> count 0)
-      (with-demoted-errors           ;E.g. the window might be the root window!
+      (with-demoted-errors "Enlarge window error: %S"
         (enlarge-window count reftex-toc-split-windows-horizontally)))))
 
 (defun reftex-toc-dframe-p (&optional frame error)
diff --git a/lisp/tooltip.el b/lisp/tooltip.el
index 2aa487d045..0ee3c38e26 100644
--- a/lisp/tooltip.el
+++ b/lisp/tooltip.el
@@ -58,9 +58,11 @@ echo area, instead of making a pop-up window."
   (if (and tooltip-mode (fboundp 'x-show-tip))
       (progn
        (add-hook 'pre-command-hook 'tooltip-hide)
-       (add-hook 'tooltip-functions 'tooltip-help-tips))
+       (add-hook 'tooltip-functions 'tooltip-help-tips)
+        (add-hook 'x-pre-popup-menu-hook 'tooltip-hide))
     (unless (and (boundp 'gud-tooltip-mode) gud-tooltip-mode)
-      (remove-hook 'pre-command-hook 'tooltip-hide))
+      (remove-hook 'pre-command-hook 'tooltip-hide)
+      (remove-hook 'x-pre-popup-menu-hook 'tooltip-hide))
     (remove-hook 'tooltip-functions 'tooltip-help-tips))
   (setq show-help-function
        (if tooltip-mode 'tooltip-show-help 'tooltip-show-help-non-mode)))
@@ -375,12 +377,7 @@ It is also called if Tooltip mode is on, for text-only 
displays."
 (defun tooltip-show-help (msg)
   "Function installed as `show-help-function'.
 MSG is either a help string to display, or nil to cancel the display."
-  (if (and (display-graphic-p)
-           ;; On Haiku, system tooltips can't be displayed above
-           ;; menus.
-           (or (not (and (eq window-system 'haiku)
-                         haiku-use-system-tooltips))
-               (not (menu-or-popup-active-p))))
+  (if (and (display-graphic-p))
       (let ((previous-help tooltip-help-message))
        (setq tooltip-help-message msg)
        (cond ((null msg)
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 731d1e8256..0bf7899246 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2678,7 +2678,8 @@ When OLD is non-nil, highlight the hunk from the old 
source."
          ;; Trim a trailing newline to find hunk in diff-syntax-fontify-props
          ;; in diffs that have no newline at end of diff file.
          (text (string-trim-right
-                (or (with-demoted-errors (diff-hunk-text hunk (not old) nil))
+                (or (with-demoted-errors "Error getting hunk text: %S"
+                      (diff-hunk-text hunk (not old) nil))
                     "")))
         (line (if (looking-at "\\(?:\\*\\{15\\}.*\n\\)?[-@* 
]*\\([0-9,]+\\)\\([ acd+]+\\([0-9,]+\\)\\)?")
                   (if old (match-string 1)
diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el
index bd4ff3e015..4a511f1f68 100644
--- a/lisp/vc/vc-annotate.el
+++ b/lisp/vc/vc-annotate.el
@@ -57,7 +57,7 @@ is applied to the background."
   :set (lambda (symbol value)
         (set-default symbol value)
         (when (boundp 'vc-annotate-color-map)
-          (with-demoted-errors
+          (with-demoted-errors "VC color map error: %S"
             ;; Update the value of the dependent variable.
             (custom-reevaluate-setting 'vc-annotate-color-map))))
   :version "25.1"
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 9c49e94781..bd2ea337b1 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -799,9 +799,10 @@ In the latter case, VC mode is deactivated for this 
buffer."
     (add-hook 'vc-mode-line-hook #'vc-mode-line nil t)
     (let (backend)
       (cond
-        ((setq backend (with-demoted-errors (vc-backend buffer-file-name)))
-         ;; Let the backend setup any buffer-local things he needs.
-         (vc-call-backend backend 'find-file-hook)
+       ((setq backend (with-demoted-errors "VC refresh error: %S"
+                        (vc-backend buffer-file-name)))
+        ;; Let the backend setup any buffer-local things he needs.
+        (vc-call-backend backend 'find-file-hook)
        ;; Compute the state and put it in the mode line.
        (vc-mode-line buffer-file-name backend)
        (unless vc-make-backup-files
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 54457a2143..a6124acadd 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1742,7 +1742,20 @@ BUFFER defaults to the current buffer."
   "Functions run at the end of the diff command.
 Each function runs in the diff output buffer without args.")
 
-(defun vc-diff-finish (buffer messages)
+(defun vc-diff-restore-buffer (original new)
+  "Restore point in buffer NEW to where it was in ORIGINAL.
+
+This function works by updating buffer ORIGINAL with the contents
+of NEW (without destroying existing markers), swapping their text
+objects, and finally killing buffer ORIGINAL."
+  (with-current-buffer original
+    (let ((inhibit-read-only t))
+      (replace-buffer-contents new)))
+  (with-current-buffer new
+    (buffer-swap-text original))
+  (kill-buffer original))
+
+(defun vc-diff-finish (buffer messages &optional oldbuf)
   ;; The empty sync output case has already been handled, so the only
   ;; possibility of an empty output is for an async process.
   (when (buffer-live-p buffer)
@@ -1754,7 +1767,11 @@ Each function runs in the diff output buffer without 
args.")
               (message "%s" (cdr messages))))
        (diff-setup-whitespace)
        (diff-setup-buffer-type)
-       (goto-char (point-min))
+        ;; `oldbuf' is the buffer that used to show this diff.  Make
+        ;; sure that we restore point in it if it's given.
+       (if oldbuf
+            (vc-diff-restore-buffer oldbuf buffer)
+          (goto-char (point-min)))
        (run-hooks 'vc-diff-finish-functions))
       (when (and messages (not emptyp))
        (message "%sdone" (car messages))))))
@@ -1779,7 +1796,11 @@ Return t if the buffer had changes, nil otherwise."
         ;; but the only way to set it for each file included would
         ;; be to call the back end separately for each file.
         (coding-system-for-read
-         (if files (vc-coding-system-for-diff (car files)) 'undecided)))
+         (if files (vc-coding-system-for-diff (car files)) 'undecided))
+         (orig-diff-buffer-clone
+          (if revert-buffer-in-progress-p
+              (clone-buffer
+               (generate-new-buffer-name " *vc-diff-clone*") nil))))
     ;; On MS-Windows and MS-DOS, Diff is likely to produce DOS-style
     ;; EOLs, which will look ugly if (car files) happens to have Unix
     ;; EOLs.
@@ -1840,7 +1861,8 @@ Return t if the buffer had changes, nil otherwise."
       ;; after `pop-to-buffer'; the former assumes the diff buffer is
       ;; shown in some window.
       (let ((buf (current-buffer)))
-        (vc-run-delayed (vc-diff-finish buf (when verbose messages))))
+        (vc-run-delayed (vc-diff-finish buf (when verbose messages)
+                                        orig-diff-buffer-clone)))
       ;; In the async case, we return t even if there are no differences
       ;; because we don't know that yet.
       t)))
diff --git a/lisp/version.el b/lisp/version.el
index 45f72b4329..7e360209d8 100644
--- a/lisp/version.el
+++ b/lisp/version.el
@@ -56,8 +56,13 @@ developing Emacs.")
 (declare-function haiku-get-version-string "haikufns.c")
 
 (defun emacs-version (&optional here)
-  "Return string describing the version of Emacs that is running.
-If optional argument HERE is non-nil, insert string at point.
+  "Display the version of Emacs that is running in this session.
+With a prefix argument, insert the Emacs version string at point
+instead of displaying it.
+If called from Lisp, by default return the version string; but
+if the optional argument HERE is non-nil, insert the string at
+point instead.
+
 Don't use this function in programs to choose actions according
 to the system configuration; look at `system-configuration' instead."
   (interactive "P")
diff --git a/lisp/woman.el b/lisp/woman.el
index 2e0d9a9090..e16785329a 100644
--- a/lisp/woman.el
+++ b/lisp/woman.el
@@ -2280,9 +2280,9 @@ Currently set only from \\='\\\" t in the first line of 
the source file.")
       (replace-match woman-unpadded-space-string t t))
 
     ;; Discard optional hyphen \%; concealed newlines \<newline>;
-    ;; point-size change function \sN,\s+N, \s-N:
+    ;; kerning \/, \,; point-size change function \sN,\s+N, \s-N:
     (goto-char from)
-    (while (re-search-forward "\\\\\\([%\n]\\|s[-+]?[0-9]+\\)" nil t)
+    (while (re-search-forward "\\\\\\([%\n/,]\\|s[-+]?[0-9]+\\)" nil t)
       (woman-delete-match 0))
 
     ;; BEWARE: THIS SHOULD PROBABLY ALL BE DONE MUCH LATER!!!!!
diff --git a/lisp/yank-media.el b/lisp/yank-media.el
index 9836082fb2..5cd75eb318 100644
--- a/lisp/yank-media.el
+++ b/lisp/yank-media.el
@@ -155,30 +155,7 @@ non-supported selection data types."
     (format "%s" data))
    ((string-match-p "\\`text/" (symbol-name data-type))
     ;; We may have utf-16, which Emacs won't detect automatically.
-    (let ((coding-system
-           (and (zerop (mod (length data) 2))
-                (let ((stats (vector 0 0)))
-                  (dotimes (i (length data))
-                    (when (zerop (elt data i))
-                      (setf (aref stats (mod i 2))
-                            (1+ (aref stats (mod i 2))))))
-                  ;; If we have more than 90% every-other nul, then it's
-                  ;; pretty likely to be utf-16.
-                  (cond
-                   ((> (if (zerop (elt stats 1))
-                           1
-                         (/ (float (elt stats 0))
-                            (float (elt stats 1))))
-                       0.9)
-                    ;; Big endian.
-                    'utf-16-be)
-                   ((> (if (zerop (elt stats 0))
-                           1
-                         (/ (float (elt stats 1))
-                            (float (elt stats 0))))
-                       0.9)
-                    ;; Little endian.
-                    'utf-16-le))))))
+    (let ((coding-system (yank-media--utf-16-p data)))
       (if coding-system
           (decode-coding-string data coding-system)
         ;; Some programs add a nul character at the end of text/*
@@ -189,6 +166,25 @@ non-supported selection data types."
    (t
     data)))
 
+(defun yank-media--utf-16-p (data)
+  (and (zerop (mod (length data) 2))
+       (let ((stats (vector 0 0)))
+         (dotimes (i (length data))
+           (when (zerop (elt data i))
+             (setf (aref stats (mod i 2))
+                   (1+ (aref stats (mod i 2))))))
+         ;; If we have more than 90% every-other nul, then it's
+         ;; pretty likely to be utf-16.
+         (cond
+          ((> (/ (float (elt stats 0)) (/ (length data) 2))
+              0.9)
+           ;; Big endian.
+           'utf-16-be)
+          ((> (/ (float (elt stats 1)) (/ (length data) 2))
+              0.9)
+           ;; Little endian.
+           'utf-16-le)))))
+
 (provide 'yank-media)
 
 ;;; yank-media.el ends here
diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c
index 369162c7fe..8c5794c043 100644
--- a/lwlib/xlwmenu.c
+++ b/lwlib/xlwmenu.c
@@ -2742,4 +2742,6 @@ pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent *event)
 
   ((XMotionEvent*)event)->is_hint = 0;
   handle_motion_event (mw, (XMotionEvent*)event);
+
+  XlwMenuRedisplay ((XlwMenuWidget) mw, NULL, None);
 }
diff --git a/src/Makefile.in b/src/Makefile.in
index 706beb453b..186e06735c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -264,6 +264,9 @@ XFIXES_CFLAGS = @XFIXES_CFLAGS@
 XINPUT_LIBS = @XINPUT_LIBS@
 XINPUT_CFLAGS = @XINPUT_CFLAGS@
 
+XSYNC_LIBS = @XSYNC_LIBS@
+XSYNC_CFLAGS = @XSYNC_CFLAGS@
+
 XDBE_LIBS = @XDBE_LIBS@
 XDBE_CFLAGS = @XDBE_CFLAGS@
 
@@ -396,7 +399,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
   $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
   $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
   $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
-  $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \
+  $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) \
   $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
   $(WERROR_CFLAGS) $(HAIKU_CFLAGS)
 ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
@@ -548,7 +551,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) 
$(LIBX_BASE) $(LIBIMAGE
    $(WEBKIT_LIBS) \
    $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
    $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \
-   $(XDBE_LIBS) \
+   $(XDBE_LIBS) $(XSYNC_LIBS) \
    $(LIBXML2_LIBS) $(LIBGPM) $(LIBS_SYSTEM) $(CAIRO_LIBS) \
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) 
$(M17N_FLT_LIBS) \
diff --git a/src/alloc.c b/src/alloc.c
index e01ea36e64..5d7b484f6e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4925,8 +4925,8 @@ mark_maybe_pointer (void *p, bool symbol_only)
    miss objects if __alignof__ were used.  */
 #define GC_POINTER_ALIGNMENT alignof (void *)
 
-/* Mark Lisp objects referenced from the address range START+OFFSET..END
-   or END+OFFSET..START.  */
+/* Mark Lisp objects referenced from the address range START..END
+   or END..START.  */
 
 static void ATTRIBUTE_NO_SANITIZE_ADDRESS
 mark_memory (void const *start, void const *end)
diff --git a/src/comp.c b/src/comp.c
index 9342712a38..251613dc3d 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -5127,13 +5127,14 @@ maybe_defer_native_compilation (Lisp_Object 
function_name,
        return;
     }
 
+  Fputhash (function_name, definition, Vcomp_deferred_pending_h);
+
   /* This is so deferred compilation is able to compile comp
      dependencies breaking circularity.  */
-  if (comp__loadable)
+  if (comp__compilable)
     {
       /* Startup is done, comp is usable.  */
       CALL0I (startup--require-comp-safely);
-      Fputhash (function_name, definition, Vcomp_deferred_pending_h);
       CALLN (Ffuncall, intern_c_string ("native--compile-async"),
             src, Qnil, Qlate);
     }
@@ -5600,9 +5601,9 @@ syms_of_comp (void)
   DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources,
               doc: /* List of sources to be native-compiled when startup is 
finished.
 For internal use.  */);
-  DEFVAR_BOOL ("comp--loadable",
-              comp__loadable,
-              doc: /* Non-nil when comp.el can be loaded.
+  DEFVAR_BOOL ("comp--compilable",
+              comp__compilable,
+              doc: /* Non-nil when comp.el can be native compiled.
 For internal use. */);
   /* Compiler control customizes.  */
   DEFVAR_BOOL ("native-comp-deferred-compilation",
diff --git a/src/data.c b/src/data.c
index 00704cc992..0d83a1ffa4 100644
--- a/src/data.c
+++ b/src/data.c
@@ -836,7 +836,6 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
        doc: /* Set SYMBOL's function definition to DEFINITION, and return 
DEFINITION.  */)
   (register Lisp_Object symbol, Lisp_Object definition)
 {
-  register Lisp_Object function;
   CHECK_SYMBOL (symbol);
   /* Perhaps not quite the right error signal, but seems good enough.  */
   if (NILP (symbol) && !NILP (definition))
@@ -844,14 +843,11 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
        think this one little sanity check is worth its cost, but anyway.  */
     xsignal1 (Qsetting_constant, symbol);
 
-  function = XSYMBOL (symbol)->u.s.function;
-
-  if (AUTOLOADP (function))
-    Fput (symbol, Qautoload, XCDR (function));
-
   eassert (valid_lisp_object_p (definition));
 
 #ifdef HAVE_NATIVE_COMP
+  register Lisp_Object function = XSYMBOL (symbol)->u.s.function;
+
   if (comp_enable_subr_trampolines
       && SUBRP (function)
       && !SUBR_NATIVE_COMPILEDP (function))
@@ -863,6 +859,43 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
   return definition;
 }
 
+static void
+add_to_function_history (Lisp_Object symbol, Lisp_Object olddef)
+{
+  eassert (!NILP (olddef));
+
+  Lisp_Object past = Fget (symbol, Qfunction_history);
+  Lisp_Object file = Qnil;
+  /* FIXME: Sadly, `Vload_file_name` gives less precise information
+     (it's sometimes non-nil when it shoujld be nil).  */
+  Lisp_Object tail = Vcurrent_load_list;
+  FOR_EACH_TAIL_SAFE (tail)
+    if (NILP (XCDR (tail)) && STRINGP (XCAR (tail)))
+      file = XCAR (tail);
+
+  Lisp_Object tem = Fplist_member (past, file);
+  if (!NILP (tem))
+    { /* New def from a file used before.
+         Overwrite the previous record associated with this file.  */
+      if (EQ (tem, past))
+        /* The new def is from the same file as the last change, so
+           there's nothing to do: unloading the file should revert to
+           the status before the last change rather than before this load.  */
+        return;
+      Lisp_Object pastlen = Flength (past);
+      Lisp_Object temlen = Flength (tem);
+      EMACS_INT tempos = XFIXNUM (pastlen) - XFIXNUM (temlen);
+      eassert (tempos > 1);
+      Lisp_Object prev = Fnthcdr (make_fixnum (tempos - 2), past);
+      /* Remove the previous info for this file.
+         E.g. change `hist` from (... OTHERFILE DEF3 THISFILE DEF2 ...)
+         to (... OTHERFILE DEF2). */
+      XSETCDR (prev, XCDR (tem));
+    }
+  /* Push new def from new file.  */
+  Fput (symbol, Qfunction_history, Fcons (file, Fcons (olddef, past)));
+}
+
 void
 defalias (Lisp_Object symbol, Lisp_Object definition)
 {
@@ -870,16 +903,19 @@ defalias (Lisp_Object symbol, Lisp_Object definition)
     bool autoload = AUTOLOADP (definition);
     if (!will_dump_p () || !autoload)
       { /* Only add autoload entries after dumping, because the ones before are
-          not useful and else we get loads of them from the loaddefs.el.  */
-        Lisp_Object function = XSYMBOL (symbol)->u.s.function;
-
-       if (AUTOLOADP (function))
-         /* Remember that the function was already an autoload.  */
-         LOADHIST_ATTACH (Fcons (Qt, symbol));
-       LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
+          not useful and else we get loads of them from the loaddefs.el.
+          That saves us about 110KB in the pdmp file (Jan 2022).  */
+       LOADHIST_ATTACH (Fcons (Qdefun, symbol));
+      }
+  }
 
-        if (!NILP (Vautoload_queue) && !NILP (function))
-          Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
+  {
+    Lisp_Object olddef = XSYMBOL (symbol)->u.s.function;
+    if (!NILP (olddef))
+      {
+        if (!NILP (Vautoload_queue))
+          Vautoload_queue = Fcons (symbol, Vautoload_queue);
+        add_to_function_history (symbol, olddef);
       }
   }
 
@@ -4122,6 +4158,7 @@ syms_of_data (void)
 
   DEFSYM (Qinteractive_form, "interactive-form");
   DEFSYM (Qdefalias_fset_function, "defalias-fset-function");
+  DEFSYM (Qfunction_history, "function-history");
 
   DEFSYM (Qbyte_code_function_p, "byte-code-function-p");
 
diff --git a/src/emacs.c b/src/emacs.c
index 2014e97fbf..31cc2078bd 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -190,8 +190,11 @@ static uintmax_t heap_bss_diff;
 
    We mark being in the exec'd process by a daemon name argument of
    form "--daemon=\nFD0,FD1\nNAME" where FD are the pipe file descriptors,
-   NAME is the original daemon name, if any. */
-#if defined NS_IMPL_COCOA || defined CYGWIN
+   NAME is the original daemon name, if any.
+
+   On Haiku, the table of semaphores used for looper locks doesn't
+   persist across forked processes.  */
+#if defined NS_IMPL_COCOA || defined CYGWIN || defined HAVE_HAIKU
 # define DAEMON_MUST_EXEC
 #endif
 
diff --git a/src/eval.c b/src/eval.c
index 5d1da325ec..d3f27c0623 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1877,18 +1877,19 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object 
data, bool keyboard_quit)
     }
 
   /* If we're in batch mode, print a backtrace unconditionally to help
-     with debugging.  Make sure to use `debug' unconditionally to not
-     interfere with ERT or other packages that install custom
-     debuggers.  Don't try to call the debugger while dumping or
-     bootstrapping, it wouldn't work anyway.  */
+     with debugging.  Make sure to use `debug-early' unconditionally
+     to not interfere with ERT or other packages that install custom
+     debuggers.  */
   if (!debugger_called && !NILP (error_symbol)
       && (NILP (clause) || EQ (h->tag_or_ch, Qerror))
       && noninteractive && backtrace_on_error_noninteractive
-      && !will_dump_p () && !will_bootstrap_p ()
-      && NILP (Vinhibit_debugger))
+      && NILP (Vinhibit_debugger)
+      && !NILP (Ffboundp (Qdebug_early)))
     {
+      max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
+      max_ensure_room (&max_specpdl_size, SPECPDL_INDEX (), 200);
       ptrdiff_t count = SPECPDL_INDEX ();
-      specbind (Vdebugger, Qdebug);
+      specbind (Qdebugger, Qdebug_early);
       call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
       unbind_to (count, Qnil);
     }
@@ -2284,21 +2285,17 @@ this does nothing and returns nil.  */)
 static void
 un_autoload (Lisp_Object oldqueue)
 {
-  Lisp_Object queue, first, second;
-
   /* Queue to unwind is current value of Vautoload_queue.
      oldqueue is the shadowed value to leave in Vautoload_queue.  */
-  queue = Vautoload_queue;
+  Lisp_Object queue = Vautoload_queue;
   Vautoload_queue = oldqueue;
   while (CONSP (queue))
     {
-      first = XCAR (queue);
-      second = Fcdr (first);
-      first = Fcar (first);
-      if (EQ (first, make_fixnum (0)))
-       Vfeatures = second;
+      Lisp_Object first = XCAR (queue);
+      if (CONSP (first) && EQ (XCAR (first), make_fixnum (0)))
+       Vfeatures = XCDR (first);
       else
-       Ffset (first, second);
+       Ffset (first, Fcar (Fcdr (Fget (first, Qfunction_history))));
       queue = XCDR (queue);
     }
 }
@@ -3142,80 +3139,65 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
 Lisp_Object
 funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
 {
-  if (numargs < subr->min_args
-      || (subr->max_args >= 0 && subr->max_args < numargs))
+  eassume (numargs >= 0);
+  if (numargs >= subr->min_args)
     {
-      Lisp_Object fun;
-      XSETSUBR (fun, subr);
-      xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (numargs));
-    }
+      /* Conforming call to finite-arity subr.  */
+      if (numargs <= subr->max_args)
+       {
+         Lisp_Object argbuf[8];
+         Lisp_Object *a;
+         if (numargs < subr->max_args)
+           {
+             eassume (subr->max_args <= ARRAYELTS (argbuf));
+             a = argbuf;
+             memcpy (a, args, numargs * word_size);
+             memclear (a + numargs, (subr->max_args - numargs) * word_size);
+           }
+         else
+           a = args;
+         switch (subr->max_args)
+           {
+           case 0:
+             return subr->function.a0 ();
+           case 1:
+             return subr->function.a1 (a[0]);
+           case 2:
+             return subr->function.a2 (a[0], a[1]);
+           case 3:
+             return subr->function.a3 (a[0], a[1], a[2]);
+           case 4:
+             return subr->function.a4 (a[0], a[1], a[2], a[3]);
+           case 5:
+             return subr->function.a5 (a[0], a[1], a[2], a[3], a[4]);
+           case 6:
+             return subr->function.a6 (a[0], a[1], a[2], a[3], a[4], a[5]);
+           case 7:
+             return subr->function.a7 (a[0], a[1], a[2], a[3], a[4], a[5],
+                                       a[6]);
+           case 8:
+             return subr->function.a8 (a[0], a[1], a[2], a[3], a[4], a[5],
+                                       a[6], a[7]);
+           default:
+             /* If a subr takes more than 8 arguments without using MANY
+                or UNEVALLED, we need to extend this function to support it.
+                Until this is done, there is no way to call the function.  */
+             emacs_abort ();
+           }
+       }
 
-  else if (subr->max_args == UNEVALLED)
-    {
-      Lisp_Object fun;
-      XSETSUBR (fun, subr);
-      xsignal1 (Qinvalid_function, fun);
+      /* Call to n-adic subr.  */
+      if (subr->max_args == MANY)
+       return subr->function.aMANY (numargs, args);
     }
 
-  else if (subr->max_args == MANY)
-    return (subr->function.aMANY) (numargs, args);
+  /* Anything else is an error.  */
+  Lisp_Object fun;
+  XSETSUBR (fun, subr);
+  if (subr->max_args == UNEVALLED)
+    xsignal1 (Qinvalid_function, fun);
   else
-    {
-      Lisp_Object internal_argbuf[8];
-      Lisp_Object *internal_args;
-      if (subr->max_args > numargs)
-        {
-          eassert (subr->max_args <= ARRAYELTS (internal_argbuf));
-          internal_args = internal_argbuf;
-          memcpy (internal_args, args, numargs * word_size);
-          memclear (internal_args + numargs,
-                    (subr->max_args - numargs) * word_size);
-        }
-      else
-        internal_args = args;
-      switch (subr->max_args)
-        {
-        case 0:
-          return (subr->function.a0 ());
-        case 1:
-          return (subr->function.a1 (internal_args[0]));
-        case 2:
-          return (subr->function.a2
-                  (internal_args[0], internal_args[1]));
-        case 3:
-          return (subr->function.a3
-                  (internal_args[0], internal_args[1], internal_args[2]));
-        case 4:
-          return (subr->function.a4
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3]));
-        case 5:
-          return (subr->function.a5
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4]));
-        case 6:
-          return (subr->function.a6
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4], internal_args[5]));
-        case 7:
-          return (subr->function.a7
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4], internal_args[5],
-                   internal_args[6]));
-        case 8:
-          return (subr->function.a8
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4], internal_args[5],
-                   internal_args[6], internal_args[7]));
-
-        default:
-
-          /* If a subr takes more than 8 arguments without using MANY
-             or UNEVALLED, we need to extend this function to support it.
-             Until this is done, there is no way to call the function.  */
-          emacs_abort ();
-        }
-    }
+    xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (numargs));
 }
 
 /* Call the compiled Lisp function FUN.  If we have not yet read FUN's
@@ -4452,6 +4434,7 @@ before making `inhibit-quit' nil.  */);
   DEFSYM (Qclosure, "closure");
   DEFSYM (QCdocumentation, ":documentation");
   DEFSYM (Qdebug, "debug");
+  DEFSYM (Qdebug_early, "debug-early");
 
   DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger,
               doc: /* Non-nil means never enter the debugger.
@@ -4498,6 +4481,7 @@ might not be safe to continue.  */);
               doc: /* Non-nil means display call stack frames as lists. */);
   debugger_stack_frame_as_list = 0;
 
+  DEFSYM (Qdebugger, "debugger");
   DEFVAR_LISP ("debugger", Vdebugger,
               doc: /* Function to call to invoke debugger.
 If due to frame exit, args are `exit' and the value being returned;
@@ -4505,7 +4489,7 @@ If due to frame exit, args are `exit' and the value being 
returned;
 If due to error, args are `error' and a list of the args to `signal'.
 If due to `apply' or `funcall' entry, one arg, `lambda'.
 If due to `eval' entry, one arg, t.  */);
-  Vdebugger = Qnil;
+  Vdebugger = Qdebug_early;
 
   DEFVAR_LISP ("signal-hook-function", Vsignal_hook_function,
               doc: /* If non-nil, this is a function for `signal' to call.
diff --git a/src/filelock.c b/src/filelock.c
index eb8d9ab5e0..cb548ac79b 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -658,6 +658,7 @@ make_lock_file_name (Lisp_Object fn)
 static Lisp_Object
 lock_file (Lisp_Object fn)
 {
+  char *lfname = NULL;
   lock_info_type lock_info;
 
   /* Don't do locking while dumping Emacs.
@@ -666,47 +667,46 @@ lock_file (Lisp_Object fn)
   if (will_dump_p ())
     return Qnil;
 
-  /* If the file name has special constructs in it,
-     call the corresponding file name handler.  */
-  Lisp_Object handler;
-  handler = Ffind_file_name_handler (fn, Qlock_file);
-  if (!NILP (handler))
+  if (create_lockfiles)
     {
-      return call2 (handler, Qlock_file, fn);
+      /* Create the name of the lock-file for file fn */
+      Lisp_Object lock_filename = make_lock_file_name (fn);
+      if (NILP (lock_filename))
+       return Qnil;
+      lfname = SSDATA (ENCODE_FILE (lock_filename));
     }
 
-  Lisp_Object lock_filename = make_lock_file_name (fn);
-  if (NILP (lock_filename))
-    return Qnil;
-  char *lfname = SSDATA (ENCODE_FILE (lock_filename));
-
   /* See if this file is visited and has changed on disk since it was
      visited.  */
   Lisp_Object subject_buf = get_truename_buffer (fn);
   if (!NILP (subject_buf)
       && NILP (Fverify_visited_file_modtime (subject_buf))
       && !NILP (Ffile_exists_p (fn))
-      && current_lock_owner (NULL, lfname) != I_OWN_IT)
+      && !(lfname && (current_lock_owner (NULL, lfname) == I_OWN_IT)))
     call1 (intern ("userlock--ask-user-about-supersession-threat"), fn);
 
-  /* Try to lock the lock.  FIXME: This ignores errors when
-     lock_if_free returns an errno value.  */
-  if (lock_if_free (&lock_info, lfname) == ANOTHER_OWNS_IT)
+  /* Don't do locking if the user has opted out.  */
+  if (lfname)
     {
-      /* Someone else has the lock.  Consider breaking it.  */
-      Lisp_Object attack;
-      char *dot = lock_info.dot;
-      ptrdiff_t pidlen = lock_info.colon - (dot + 1);
-      static char const replacement[] = " (pid ";
-      int replacementlen = sizeof replacement - 1;
-      memmove (dot + replacementlen, dot + 1, pidlen);
-      strcpy (dot + replacementlen + pidlen, ")");
-      memcpy (dot, replacement, replacementlen);
-      attack = call2 (intern ("ask-user-about-lock"), fn,
-                     build_string (lock_info.user));
-      /* Take the lock if the user said so.  */
-      if (!NILP (attack))
-       lock_file_1 (lfname, 1);
+      /* Try to lock the lock.  FIXME: This ignores errors when
+        lock_if_free returns a positive errno value.  */
+      if (lock_if_free (&lock_info, lfname) == ANOTHER_OWNS_IT)
+       {
+         /* Someone else has the lock.  Consider breaking it.  */
+         Lisp_Object attack;
+         char *dot = lock_info.dot;
+         ptrdiff_t pidlen = lock_info.colon - (dot + 1);
+         static char const replacement[] = " (pid ";
+         int replacementlen = sizeof replacement - 1;
+         memmove (dot + replacementlen, dot + 1, pidlen);
+         strcpy (dot + replacementlen + pidlen, ")");
+         memcpy (dot, replacement, replacementlen);
+         attack = call2 (intern ("ask-user-about-lock"), fn,
+                         build_string (lock_info.user));
+         /* Take the lock if the user said so.  */
+         if (!NILP (attack))
+           lock_file_1 (lfname, 1);
+       }
     }
   return Qnil;
 }
@@ -760,12 +760,16 @@ If the option `create-lockfiles' is nil, this does 
nothing.  */)
   (Lisp_Object file)
 {
 #ifndef MSDOS
-  /* Don't do locking if the user has opted out.  */
-  if (create_lockfiles)
-    {
-      CHECK_STRING (file);
-      lock_file (file);
-    }
+  CHECK_STRING (file);
+
+  /* If the file name has special constructs in it,
+     call the corresponding file name handler.  */
+  Lisp_Object handler;
+  handler = Ffind_file_name_handler (file, Qlock_file);
+  if (!NILP (handler))
+    return call2 (handler, Qlock_file, file);
+
+  lock_file (file);
 #endif /* MSDOS */
   return Qnil;
 }
diff --git a/src/frame.c b/src/frame.c
index 8aaff949ba..8750fe4889 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3907,6 +3907,7 @@ static const struct frame_parm_table frame_parms[] =
   {"z-group",                  SYMBOL_INDEX (Qz_group)},
   {"override-redirect",                SYMBOL_INDEX (Qoverride_redirect)},
   {"no-special-glyphs",                SYMBOL_INDEX (Qno_special_glyphs)},
+  {"alpha-background",          SYMBOL_INDEX (Qalpha_background)},
 #ifdef NS_IMPL_COCOA
   {"ns-appearance",            SYMBOL_INDEX (Qns_appearance)},
   {"ns-transparent-titlebar",  SYMBOL_INDEX (Qns_transparent_titlebar)},
@@ -5024,6 +5025,34 @@ gui_set_alpha (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
     }
 }
 
+void
+gui_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  double alpha = 1.0;
+
+  if (NILP (arg))
+    alpha = 1.0;
+  else if (FLOATP (arg))
+    {
+      alpha = XFLOAT_DATA (arg);
+      if (! (0 <= alpha && alpha <= 1.0))
+       args_out_of_range (make_float (0.0), make_float (1.0));
+    }
+  else if (FIXNUMP (arg))
+    {
+      EMACS_INT ialpha = XFIXNUM (arg);
+      if (! (0 <= ialpha && ialpha <= 100))
+       args_out_of_range (make_fixnum (0), make_fixnum (100));
+      alpha = ialpha / 100.0;
+    }
+  else
+    wrong_type_argument (Qnumberp, arg);
+
+  f->alpha_background = alpha;
+
+  recompute_basic_faces (f);
+  SET_FRAME_GARBAGED (f);
+}
 
 /**
  * gui_set_no_special_glyphs:
@@ -6100,6 +6129,7 @@ syms_of_frame (void)
 #endif
 
   DEFSYM (Qalpha, "alpha");
+  DEFSYM (Qalpha_background, "alpha-background");
   DEFSYM (Qauto_lower, "auto-lower");
   DEFSYM (Qauto_raise, "auto-raise");
   DEFSYM (Qborder_color, "border-color");
@@ -6495,6 +6525,14 @@ making the child frame unresponsive to user actions, the 
default is to
 iconify the top level frame instead.  */);
   iconify_child_frame = Qiconify_top_level;
 
+  DEFVAR_LISP ("frame-internal-parameters", frame_internal_parameters,
+              doc: /* Frame parameters specific to every frame.  */);
+#ifdef HAVE_X_WINDOWS
+  frame_internal_parameters = list4 (Qname, Qparent_id, Qwindow_id, 
Qouter_window_id);
+#else
+  frame_internal_parameters = list3 (Qname, Qparent_id, Qwindow_id);
+#endif
+
   defsubr (&Sframep);
   defsubr (&Sframe_live_p);
   defsubr (&Swindow_system);
diff --git a/src/frame.h b/src/frame.h
index cb2f58e261..5d5f2122fb 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -637,6 +637,9 @@ struct frame
      Negative values mean not to change alpha.  */
   double alpha[2];
 
+  /* Background opacity */
+  double alpha_background;
+
   /* Exponent for gamma correction of colors.  1/(VIEWING_GAMMA *
      SCREEN_GAMMA) where viewing_gamma is 0.4545 and SCREEN_GAMMA is a
      frame parameter.  0 means don't do gamma correction.  */
@@ -1669,6 +1672,7 @@ extern void gui_set_scroll_bar_height (struct frame *, 
Lisp_Object, Lisp_Object)
 extern long gui_figure_window_size (struct frame *, Lisp_Object, bool, bool);
 
 extern void gui_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
+extern void gui_set_alpha_background (struct frame *, Lisp_Object, 
Lisp_Object);
 extern void gui_set_no_special_glyphs (struct frame *, Lisp_Object, 
Lisp_Object);
 
 extern void validate_x_resource_name (void);
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 558e44d5b9..a0a3490c49 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -522,12 +522,23 @@ ftcrfont_draw (struct glyph_string *s,
                int from, int to, int x, int y, bool with_background)
 {
   struct frame *f = s->f;
-  struct face *face = s->face;
   struct font_info *ftcrfont_info = (struct font_info *) s->font;
   cairo_t *cr;
   cairo_glyph_t *glyphs;
   int len = to - from;
   int i;
+#ifdef USE_BE_CAIRO
+  unsigned long be_foreground, be_background;
+
+  if (s->hl != DRAW_CURSOR)
+    {
+      be_foreground = s->face->foreground;
+      be_background = s->face->background;
+    }
+  else
+    haiku_merge_cursor_foreground (s, &be_foreground,
+                                  &be_background);
+#endif
 
   block_input ();
 
@@ -538,12 +549,12 @@ ftcrfont_draw (struct glyph_string *s,
   cr = pgtk_begin_cr_clip (f);
 #endif
 #else
-  BView_draw_lock (FRAME_HAIKU_VIEW (f));
+  /* Presumably the draw lock is already held by
+     haiku_draw_glyph_string.  */
   EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f));
   cr = haiku_begin_cr_clip (f, s);
   if (!cr)
     {
-      BView_draw_unlock (FRAME_HAIKU_VIEW (f));
       EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
       unblock_input ();
       return 0;
@@ -557,21 +568,18 @@ ftcrfont_draw (struct glyph_string *s,
 #ifdef HAVE_X_WINDOWS
       x_set_cr_source_with_gc_background (f, s->gc);
 #else
-      pgtk_set_cr_source_with_color (f, s->xgcv.background);
+      pgtk_set_cr_source_with_color (f, s->xgcv.background, true);
 #endif
 #else
-      struct face *face = s->face;
-
-      uint32_t col = s->hl == DRAW_CURSOR ?
-       FRAME_CURSOR_COLOR (s->f).pixel : face->background;
+      uint32_t col = be_background;
 
       cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
                            GREEN_FROM_ULONG (col) / 255.0,
                            BLUE_FROM_ULONG (col) / 255.0);
 #endif
       s->background_filled_p = 1;
-      cairo_rectangle (cr, x, y - FONT_BASE (face->font),
-                      s->width, FONT_HEIGHT (face->font));
+      cairo_rectangle (cr, x, y - FONT_BASE (s->font),
+                      s->width, FONT_HEIGHT (s->font));
       cairo_fill (cr);
     }
 
@@ -589,11 +597,10 @@ ftcrfont_draw (struct glyph_string *s,
 #ifdef HAVE_X_WINDOWS
   x_set_cr_source_with_gc_foreground (f, s->gc);
 #else
-  pgtk_set_cr_source_with_color (f, s->xgcv.foreground);
+  pgtk_set_cr_source_with_color (f, s->xgcv.foreground, false);
 #endif
 #else
-  uint32_t col = s->hl == DRAW_CURSOR ?
-    FRAME_OUTPUT_DATA (s->f)->cursor_fg : face->foreground;
+  uint32_t col = be_foreground;
 
   cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
                        GREEN_FROM_ULONG (col) / 255.0,
@@ -610,7 +617,6 @@ ftcrfont_draw (struct glyph_string *s,
 #else
   haiku_end_cr_clip (cr);
   EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
-  BView_draw_unlock (FRAME_HAIKU_VIEW (f));
 #endif
   unblock_input ();
 
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 98907bf022..6912ea1e96 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -83,6 +83,10 @@ static void xg_im_context_preedit_end (GtkIMContext *, 
gpointer);
 static bool xg_widget_key_press_event_cb (GtkWidget *, GdkEvent *, gpointer);
 #endif
 
+#if GTK_CHECK_VERSION (3, 10, 0)
+static void xg_widget_style_updated (GtkWidget *, gpointer);
+#endif
+
 #ifndef HAVE_GTK3
 
 #ifdef HAVE_FREETYPE
@@ -1469,6 +1473,12 @@ xg_create_frame_widgets (struct frame *f)
   gtk_widget_add_events (wtop, GDK_ALL_EVENTS_MASK);
 #endif
 
+  gtk_widget_set_app_paintable (wtop, f->alpha_background != 1.0);
+#if GTK_CHECK_VERSION (3, 10, 0)
+  g_signal_connect (G_OBJECT (wtop), "style-updated",
+                   G_CALLBACK (xg_widget_style_updated), f);
+#endif
+
   /* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu
      has backported it to Gtk+ 2.0 and they add the resize grip for
      Gtk+ 2.0 applications also.  But it has a bug that makes Emacs loop
@@ -1587,6 +1597,21 @@ xg_create_frame_widgets (struct frame *f)
 #endif
                          | GDK_VISIBILITY_NOTIFY_MASK);
 
+  GdkScreen *screen = gtk_widget_get_screen (wtop);
+
+#if !defined HAVE_PGTK
+  GdkVisual *visual = gdk_x11_screen_lookup_visual (screen,
+                                                   XVisualIDFromVisual 
(FRAME_X_VISUAL (f)));
+
+  if (!visual)
+    emacs_abort ();
+#else
+  GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
+#endif
+
+  gtk_widget_set_visual (wtop, visual);
+  gtk_widget_set_visual (wfixed, visual);
+
 #ifndef HAVE_PGTK
   /* Must realize the windows so the X window gets created.  It is used
      by callers of this function.  */
@@ -1651,7 +1676,6 @@ xg_create_frame_widgets (struct frame *f)
 #endif
 
   {
-    GdkScreen *screen = gtk_widget_get_screen (wtop);
     GtkSettings *gs = gtk_settings_get_for_screen (screen);
     /* Only connect this signal once per screen.  */
     if (! g_signal_handler_find (G_OBJECT (gs),
@@ -4030,6 +4054,18 @@ xg_update_frame_menubar (struct frame *f)
   gtk_widget_show_all (x->menubar_widget);
   gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req);
   req.height *= xg_get_scale (f);
+
+#if !defined HAVE_PGTK && defined HAVE_GTK3
+  if (FRAME_DISPLAY_INFO (f)->n_planes == 32)
+    {
+      GdkScreen *screen = gtk_widget_get_screen (x->menubar_widget);
+      GdkVisual *visual = gdk_screen_get_system_visual (screen);
+
+      gtk_widget_realize (x->menubar_widget);
+      gtk_widget_set_visual (x->menubar_widget, visual);
+    }
+#endif
+
   if (FRAME_MENUBAR_HEIGHT (f) != (req.height * scale))
     {
       FRAME_MENUBAR_HEIGHT (f) = req.height * scale;
@@ -4820,9 +4856,8 @@ xg_event_is_for_scrollbar (struct frame *f, const EVENT 
*event)
             && event->type == GenericEvent
             && (event->xgeneric.extension
                 == FRAME_DISPLAY_INFO (f)->xi2_opcode)
-            && ((event->xgeneric.evtype == XI_ButtonPress
-                 && xev->detail < 4)
-                || (event->xgeneric.evtype == XI_Motion)))
+            && (event->xgeneric.evtype == XI_ButtonPress
+                && xev->detail < 4))
            || (event->type == ButtonPress
                && event->xbutton.button < 4)))
 #else
@@ -4854,19 +4889,7 @@ xg_event_is_for_scrollbar (struct frame *f, const EVENT 
*event)
 #else
       gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL);
 #endif
-#ifndef HAVE_XINPUT2
       retval = gwin != gtk_widget_get_window (f->output_data.xp->edit_widget);
-#else
-      retval = (gwin
-               && (gwin
-                   != gtk_widget_get_window (f->output_data.xp->edit_widget)));
-#endif
-#ifdef HAVE_XINPUT2
-      GtkWidget *grab = gtk_grab_get_current ();
-      if (event->type == GenericEvent
-         && event->xgeneric.evtype == XI_Motion)
-       retval = retval || (grab && GTK_IS_SCROLLBAR (grab));
-#endif
     }
 #ifdef HAVE_XINPUT2
   else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
@@ -6364,8 +6387,10 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
                                           NULL, NULL, &consumed);
       xg_add_virtual_mods (dpyinfo, &xg_event->key);
       xg_event->key.state &= ~consumed;
+#if GTK_CHECK_VERSION (3, 6, 0)
       xg_event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap,
                                                                  
xg_event->key.hardware_keycode);
+#endif
     }
 #endif
 
@@ -6377,4 +6402,28 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
   return result;
 }
 #endif
+
+#if GTK_CHECK_VERSION (3, 10, 0)
+static void
+xg_widget_style_updated (GtkWidget *widget, gpointer user_data)
+{
+  struct frame *f = user_data;
+
+  if (f->alpha_background < 1.0)
+    {
+#ifndef HAVE_PGTK
+      XChangeProperty (FRAME_X_DISPLAY (f),
+                      FRAME_X_WINDOW (f),
+                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
+                      XA_CARDINAL, 32, PropModeReplace,
+                      NULL, 0);
+#else
+      if (FRAME_GTK_OUTER_WIDGET (f)
+         && gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f)))
+       gdk_window_set_opaque_region (gtk_widget_get_window 
(FRAME_GTK_OUTER_WIDGET (f)),
+                                     NULL);
+#endif
+    }
+}
+#endif
 #endif /* USE_GTK */
diff --git a/src/haiku_io.c b/src/haiku_io.c
index cb7750634c..185bd5e9ff 100644
--- a/src/haiku_io.c
+++ b/src/haiku_io.c
@@ -36,6 +36,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
    Emacs.  */
 port_id port_application_to_emacs;
 
+/* The port used to send popup menu messages from the application
+   thread to Emacs.  */
+port_id port_popup_menu_to_emacs;
+
 void
 haiku_io_init (void)
 {
@@ -90,6 +94,8 @@ haiku_len (enum haiku_event_type type)
       return sizeof (struct haiku_refs_event);
     case APP_QUIT_REQUESTED_EVENT:
       return sizeof (struct haiku_app_quit_requested_event);
+    case DUMMY_EVENT:
+      return sizeof (struct haiku_dummy_event);
     }
 
   emacs_abort ();
@@ -98,9 +104,11 @@ haiku_len (enum haiku_event_type type)
 /* Read the size of the next message into len, returning -1 if the
    query fails or there is no next message.  */
 void
-haiku_read_size (ssize_t *len)
+haiku_read_size (ssize_t *len, bool popup_menu_p)
 {
-  port_id from = port_application_to_emacs;
+  port_id from = (popup_menu_p
+                 ? port_popup_menu_to_emacs
+                 : port_application_to_emacs);
   ssize_t size;
 
   size = port_buffer_size_etc (from, B_TIMEOUT, 0);
@@ -129,13 +137,16 @@ haiku_read (enum haiku_event_type *type, void *buf, 
ssize_t len)
 }
 
 /* The same as haiku_read, but time out after TIMEOUT microseconds.
+   POPUP_MENU_P means to read from the popup menu port instead.
    Input is blocked when an attempt to read is in progress.  */
 int
 haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len,
-                        time_t timeout)
+                        time_t timeout, bool popup_menu_p)
 {
   int32 typ;
-  port_id from = port_application_to_emacs;
+  port_id from = (popup_menu_p
+                 ? port_popup_menu_to_emacs
+                 : port_application_to_emacs);
 
   block_input ();
   if (read_port_etc (from, &typ, buf, len,
@@ -165,9 +176,12 @@ haiku_write (enum haiku_event_type type, void *buf)
 }
 
 int
-haiku_write_without_signal (enum haiku_event_type type, void *buf)
+haiku_write_without_signal (enum haiku_event_type type, void *buf,
+                           bool popup_menu_p)
 {
-  port_id to = port_application_to_emacs;
+  port_id to = (popup_menu_p
+               ? port_popup_menu_to_emacs
+               : port_application_to_emacs);
 
   if (write_port (to, (int32_t) type, buf, haiku_len (type)) < B_OK)
     return -1;
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 41e5b71182..fad2b46654 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -114,6 +114,8 @@ static BLocker child_frame_lock;
 
 static BLocker movement_locker;
 
+static BMessage volatile *popup_track_message;
+
 /* This could be a private API, but it's used by (at least) the Qt
    port, so it's probably here to stay.  */
 extern status_t get_subpixel_antialiasing (bool *);
@@ -137,6 +139,32 @@ gui_abort (const char *msg)
   emacs_abort ();
 }
 
+struct be_popup_menu_data
+{
+  int x, y;
+  BPopUpMenu *menu;
+};
+
+static int32
+be_popup_menu_thread_entry (void *thread_data)
+{
+  struct be_popup_menu_data *data;
+  struct haiku_dummy_event dummy;
+  BMenuItem *it;
+
+  data = (struct be_popup_menu_data *) thread_data;
+
+  it = data->menu->Go (BPoint (data->x, data->y));
+
+  if (it)
+    popup_track_message = it->Message ();
+  else
+    popup_track_message = NULL;
+
+  haiku_write (DUMMY_EVENT, &dummy);
+  return 0;
+}
+
 /* Convert a raw character RAW produced by the keycode KEY into a key
    symbol and place it in KEYSYM.
 
@@ -656,8 +684,10 @@ public:
     else if (msg->GetPointer ("menuptr"))
       {
        struct haiku_menu_bar_select_event rq;
+
        rq.window = this;
        rq.ptr = (void *) msg->GetPointer ("menuptr");
+
        haiku_write (MENU_BAR_SELECT_EVENT, &rq);
       }
     else if (msg->what == 'FPSE'
@@ -1154,6 +1184,7 @@ public:
 
 #ifdef USE_BE_CAIRO
   cairo_surface_t *cr_surface = NULL;
+  cairo_t *cr_context = NULL;
   BLocker cr_surface_lock;
 #endif
 
@@ -1185,8 +1216,10 @@ public:
       gui_abort ("Could not lock cr surface during detachment");
     if (!cr_surface)
       gui_abort ("Trying to detach window cr surface when none exists");
+    cairo_destroy (cr_context);
     cairo_surface_destroy (cr_surface);
     cr_surface = NULL;
+    cr_context = NULL;
     cr_surface_lock.Unlock ();
   }
 
@@ -1206,6 +1239,10 @@ public:
        offscreen_draw_bitmap_1->BytesPerRow ());
     if (!cr_surface)
       gui_abort ("Cr surface allocation failed for double-buffered view");
+
+    cr_context = cairo_create (cr_surface);
+    if (!cr_context)
+      gui_abort ("cairo_t allocation failed for double-buffered view");
     cr_surface_lock.Unlock ();
   }
 #endif
@@ -1607,6 +1644,7 @@ class EmacsMenuItem : public BMenuItem
 {
 public:
   int menu_bar_id = -1;
+  void *menu_ptr = NULL;
   void *wind_ptr = NULL;
   char *key = NULL;
   char *help = NULL;
@@ -1648,11 +1686,17 @@ public:
 
     if (key)
       {
-       BRect r = menu->Frame ();
-       int w = menu->StringWidth (key);
+       BRect r = Frame ();
+       int w;
+
+       menu->PushState ();
+       menu->ClipToRect (r);
+       menu->SetFont (be_plain_font);
+       w = menu->StringWidth (key);
        menu->MovePenTo (BPoint (BE_RECT_WIDTH (r) - w - 4,
                                 menu->PenLocation ().y));
        menu->DrawString (key);
+       menu->PopState ();
       }
   }
 
@@ -1668,6 +1712,7 @@ public:
   Highlight (bool highlight_p)
   {
     struct haiku_menu_bar_help_event rq;
+    struct haiku_dummy_event dummy;
     BMenu *menu = Menu ();
     BRect r;
     BPoint pt;
@@ -1675,16 +1720,26 @@ public:
 
     if (help)
       menu->SetToolTip (highlight_p ? help : NULL);
-    else if (menu_bar_id >= 0)
+    else
       {
        rq.window = wind_ptr;
        rq.mb_idx = highlight_p ? menu_bar_id : -1;
+       rq.highlight_p = highlight_p;
+       rq.data = menu_ptr;
 
        r = Frame ();
        menu->GetMouse (&pt, &buttons);
 
        if (!highlight_p || r.Contains (pt))
-         haiku_write (MENU_BAR_HELP_EVENT, &rq);
+         {
+           if (menu_bar_id > 0)
+             haiku_write (MENU_BAR_HELP_EVENT, &rq);
+           else
+             {
+               haiku_write_without_signal (MENU_BAR_HELP_EVENT, &rq, true);
+               haiku_write (DUMMY_EVENT, &dummy);
+             }
+         }
       }
 
     BMenuItem::Highlight (highlight_p);
@@ -1980,7 +2035,8 @@ BCursor_create_grab (void)
 void
 BCursor_delete (void *cursor)
 {
-  delete (BCursor *) cursor;
+  if (cursor)
+    delete (BCursor *) cursor;
 }
 
 void
@@ -2353,6 +2409,7 @@ BMenu_add_item (void *menu, const char *label, void *ptr, 
bool enabled_p,
       it->menu_bar_id = (intptr_t) ptr;
       it->wind_ptr = mbw_ptr;
     }
+  it->menu_ptr = ptr;
   if (ptr)
     msg->AddPointer ("menuptr", ptr);
   m->AddItem (it);
@@ -2397,20 +2454,106 @@ BMenu_new_menu_bar_submenu (void *menu, const char 
*label)
    data of the selected item (if one exists), or NULL.  X, Y should
    be in the screen coordinate system.  */
 void *
-BMenu_run (void *menu, int x, int y)
+BMenu_run (void *menu, int x, int y,
+          void (*run_help_callback) (void *, void *),
+          void (*block_input_function) (void),
+          void (*unblock_input_function) (void),
+          void (*process_pending_signals_function) (void),
+          void *run_help_callback_data)
 {
   BPopUpMenu *mn = (BPopUpMenu *) menu;
+  enum haiku_event_type type;
+  void *buf;
+  void *ptr = NULL;
+  struct be_popup_menu_data data;
+  struct object_wait_info infos[2];
+  struct haiku_menu_bar_help_event *event;
+  BMessage *msg;
+  ssize_t stat;
+
+  block_input_function ();
+  port_popup_menu_to_emacs = create_port (1800, "popup menu port");
+  data.x = x;
+  data.y = y;
+  data.menu = mn;
+  unblock_input_function ();
+
+  if (port_popup_menu_to_emacs < B_OK)
+    return NULL;
+
+  block_input_function ();
   mn->SetRadioMode (0);
-  BMenuItem *it = mn->Go (BPoint (x, y));
-  if (it)
+  buf = alloca (200);
+
+  infos[0].object = port_popup_menu_to_emacs;
+  infos[0].type = B_OBJECT_TYPE_PORT;
+  infos[0].events = B_EVENT_READ;
+
+  infos[1].object = spawn_thread (be_popup_menu_thread_entry,
+                                 "Menu tracker", B_DEFAULT_MEDIA_PRIORITY,
+                                 (void *) &data);
+  infos[1].type = B_OBJECT_TYPE_THREAD;
+  infos[1].events = B_EVENT_INVALID;
+  unblock_input_function ();
+
+  if (infos[1].object < B_OK)
     {
-      BMessage *mg = it->Message ();
-      if (mg)
-       return (void *) mg->GetPointer ("menuptr");
-      else
-       return NULL;
+      block_input_function ();
+      delete_port (port_popup_menu_to_emacs);
+      unblock_input_function ();
+      return NULL;
+    }
+
+  block_input_function ();
+  resume_thread (infos[1].object);
+  unblock_input_function ();
+
+  while (true)
+    {
+      process_pending_signals_function ();
+
+      if ((stat = wait_for_objects_etc ((object_wait_info *) &infos, 2,
+                                       B_RELATIVE_TIMEOUT, 10000)) < B_OK)
+       {
+         if (stat == B_INTERRUPTED || stat == B_TIMED_OUT)
+           continue;
+         else
+           gui_abort ("Failed to wait for popup");
+       }
+
+      if (infos[0].events & B_EVENT_READ)
+       {
+         if (!haiku_read_with_timeout (&type, buf, 200, 1000000, true))
+           {
+             switch (type)
+               {
+               case MENU_BAR_HELP_EVENT:
+                 event = (struct haiku_menu_bar_help_event *) buf;
+                 run_help_callback (event->highlight_p
+                                    ? event->data
+                                    : NULL, run_help_callback_data);
+                 break;
+               default:
+                 gui_abort ("Unknown popup menu event");
+               }
+           }
+       }
+
+      if (infos[1].events & B_EVENT_INVALID)
+       {
+         block_input_function ();
+         msg = (BMessage *) popup_track_message;
+         if (popup_track_message)
+           ptr = (void *) msg->GetPointer ("menuptr");
+
+         delete_port (port_popup_menu_to_emacs);
+         unblock_input_function ();
+         return ptr;
+       }
+
+      infos[0].events = B_EVENT_READ;
+      infos[1].events = B_EVENT_INVALID;
     }
-  return NULL;
 }
 
 /* Delete the entire menu hierarchy of MENU, and then delete MENU
@@ -2864,7 +3007,7 @@ be_popup_file_dialog (int open_p, const char 
*default_dir, int must_match_p, int
       enum haiku_event_type type;
       char *ptr = NULL;
 
-      if (!haiku_read_with_timeout (&type, buf, 200, 1000000))
+      if (!haiku_read_with_timeout (&type, buf, 200, 1000000, false))
        {
          block_input_function ();
          if (type != FILE_PANEL_EVENT)
@@ -2878,7 +3021,7 @@ be_popup_file_dialog (int open_p, const char 
*default_dir, int must_match_p, int
 
       ssize_t b_s;
       block_input_function ();
-      haiku_read_size (&b_s);
+      haiku_read_size (&b_s, false);
       if (!b_s || ptr || panel->Window ()->IsHidden ())
        {
          c_unbind_to_nil_from_cxx (idx);
@@ -3042,12 +3185,12 @@ BView_show_tooltip (void *view)
 
 
 #ifdef USE_BE_CAIRO
-/* Return VIEW's cairo surface.  */
-cairo_surface_t *
-EmacsView_cairo_surface (void *view)
+/* Return VIEW's cairo context.  */
+cairo_t *
+EmacsView_cairo_context (void *view)
 {
   EmacsView *vw = (EmacsView *) view;
-  return vw->cr_surface;
+  return vw->cr_context;
 }
 
 /* Transfer each clip rectangle in VIEW to the cairo context
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 8d4dddd90f..ea34ccb435 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -86,7 +86,8 @@ enum haiku_event_type
     MENU_BAR_HELP_EVENT,
     ZOOM_EVENT,
     REFS_EVENT,
-    APP_QUIT_REQUESTED_EVENT
+    APP_QUIT_REQUESTED_EVENT,
+    DUMMY_EVENT
   };
 
 struct haiku_quit_requested_event
@@ -123,6 +124,11 @@ struct haiku_app_quit_requested_event
   char dummy;
 };
 
+struct haiku_dummy_event
+{
+  char dummy;
+};
+
 #define HAIKU_MODIFIER_ALT (1)
 #define HAIKU_MODIFIER_CTRL (1 << 1)
 #define HAIKU_MODIFIER_SHIFT (1 << 2)
@@ -200,6 +206,8 @@ struct haiku_menu_bar_help_event
 {
   void *window;
   int mb_idx;
+  void *data;
+  bool highlight_p;
 };
 
 struct haiku_zoom_event
@@ -358,25 +366,27 @@ extern "C"
 #endif
 
   extern port_id port_application_to_emacs;
+  extern port_id port_popup_menu_to_emacs;
 
   extern void haiku_io_init (void);
   extern void haiku_io_init_in_app_thread (void);
 
   extern void
-  haiku_read_size (ssize_t *len);
+  haiku_read_size (ssize_t *len, bool popup_menu_p);
 
   extern int
   haiku_read (enum haiku_event_type *type, void *buf, ssize_t len);
 
   extern int
   haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len,
-                          time_t timeout);
+                          time_t timeout, bool popup_menu_p);
 
   extern int
   haiku_write (enum haiku_event_type type, void *buf);
 
   extern int
-  haiku_write_without_signal (enum haiku_event_type type, void *buf);
+  haiku_write_without_signal (enum haiku_event_type type, void *buf,
+                             bool popup_menu_p);
 
   extern void
   rgb_color_hsl (uint32_t rgb, double *h, double *s, double *l);
@@ -679,7 +689,12 @@ extern "C"
   BMenu_item_at (void *menu, int idx);
 
   extern void *
-  BMenu_run (void *menu, int x, int y);
+  BMenu_run (void *menu, int x, int y,
+            void (*run_help_callback) (void *, void *),
+            void (*block_input_function) (void),
+            void (*unblock_input_function) (void),
+            void (*process_pending_signals_function) (void),
+            void *run_help_callback_data);
 
   extern void
   BPopUpMenu_delete (void *menu);
@@ -812,8 +827,8 @@ extern "C"
   BView_show_tooltip (void *view);
 
 #ifdef USE_BE_CAIRO
-  extern cairo_surface_t *
-  EmacsView_cairo_surface (void *view);
+  extern cairo_t *
+  EmacsView_cairo_context (void *view);
 
   extern void
   BView_cr_dump_clipping (void *view, cairo_t *ctx);
diff --git a/src/haikufns.c b/src/haikufns.c
index 58a2e1d464..eb736f1153 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -418,13 +418,20 @@ haiku_set_parent_frame (struct frame *f,
     }
 
   if (!NILP (old_value))
-    EmacsWindow_unparent (FRAME_HAIKU_WINDOW (f));
+    {
+      EmacsWindow_unparent (FRAME_HAIKU_WINDOW (f));
+      FRAME_OUTPUT_DATA (f)->parent_desc = NULL;
+    }
   if (!NILP (new_value))
     {
       EmacsWindow_parent_to (FRAME_HAIKU_WINDOW (f),
                             FRAME_HAIKU_WINDOW (p));
       BWindow_set_offset (FRAME_HAIKU_WINDOW (f),
                          f->left_pos, f->top_pos);
+
+      /* This isn't actually used for anything, but makes the
+        `parent-id' parameter correct.  */
+      FRAME_OUTPUT_DATA (f)->parent_desc = FRAME_HAIKU_WINDOW (p);
     }
   fset_parent_frame (f, new_value);
   unblock_input ();
@@ -592,8 +599,6 @@ haiku_create_frame (Lisp_Object parms)
   if (STRINGP (name))
     Vx_resource_name = name;
 
-  block_input ();
-
   /* make_frame_without_minibuffer can run Lisp code and garbage collect.  */
   /* No need to protect DISPLAY because that's not used after passing
      it to make_frame_without_minibuffer.  */
@@ -668,8 +673,6 @@ haiku_create_frame (Lisp_Object parms)
 
   FRAME_RIF (f)->default_font_parameter (f, parms);
 
-  unblock_input ();
-
   gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
                          "borderwidth", "BorderWidth", RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2),
@@ -749,6 +752,7 @@ haiku_create_frame (Lisp_Object parms)
                              RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem));
 
+  block_input ();
 #define ASSIGN_CURSOR(cursor, be_cursor) \
   (FRAME_OUTPUT_DATA (f)->cursor = be_cursor)
 
@@ -786,11 +790,15 @@ haiku_create_frame (Lisp_Object parms)
   f->terminal->reference_count++;
 
   FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
+  unblock_input ();
+
   if (!FRAME_OUTPUT_DATA (f)->window)
     xsignal1 (Qerror, build_unibyte_string ("Could not create window"));
 
+  block_input ();
   if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
     initialize_frame_menubar (f);
+  unblock_input ();
 
   FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window;
 
@@ -830,6 +838,8 @@ haiku_create_frame (Lisp_Object parms)
                         RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                         "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qfullscreen, Qnil,
                         "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
@@ -869,10 +879,12 @@ haiku_create_frame (Lisp_Object parms)
     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
       fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
 
+  block_input ();
   if (window_prompting & (USPosition | PPosition))
     haiku_set_offset (f, f->left_pos, f->top_pos, 1);
   else
     BWindow_center_on_screen (FRAME_HAIKU_WINDOW (f));
+  unblock_input ();
 
   /* Make sure windows on this frame appear in calls to next-window
      and similar functions.  */
@@ -1043,6 +1055,8 @@ haiku_create_tip_frame (Lisp_Object parms)
                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   initial_setup_back_buffer (f);
 
@@ -1898,10 +1912,8 @@ DEFUN ("x-display-visual-class", Fx_display_visual_class,
 
   if (planes == 8)
     return intern ("static-color");
-  else if (planes == 16 || planes == 15)
-    return intern ("pseudo-color");
 
-  return intern ("direct-color");
+  return intern ("true-color");
 }
 
 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
@@ -2609,7 +2621,8 @@ frame_parm_handler haiku_frame_parm_handlers[] =
     haiku_set_no_accept_focus,
     NULL, /* set z group */
     haiku_set_override_redirect,
-    gui_set_no_special_glyphs
+    gui_set_no_special_glyphs,
+    gui_set_alpha_background,
   };
 
 void
diff --git a/src/haikufont.c b/src/haikufont.c
index e08792be4b..6cc984f316 100644
--- a/src/haikufont.c
+++ b/src/haikufont.c
@@ -951,11 +951,21 @@ haikufont_draw (struct glyph_string *s, int from, int to,
   struct font_info *info = (struct font_info *) s->font;
   unsigned char mb[MAX_MULTIBYTE_LENGTH];
   void *view = FRAME_HAIKU_VIEW (f);
+  unsigned long foreground, background;
 
   block_input ();
   prepare_face_for_display (s->f, face);
 
-  BView_draw_lock (view);
+  if (s->hl != DRAW_CURSOR)
+    {
+      foreground = s->face->foreground;
+      background = s->face->background;
+    }
+  else
+    haiku_merge_cursor_foreground (s, &foreground, &background);
+
+  /* Presumably the draw lock is already held by
+     haiku_draw_glyph_string; */
   if (with_background)
     {
       int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
@@ -976,18 +986,12 @@ haikufont_draw (struct glyph_string *s, int from, int to,
          s->first_glyph->slice.glyphless.lower_yoff
          - s->first_glyph->slice.glyphless.upper_yoff;
 
-      BView_SetHighColor (view, s->hl == DRAW_CURSOR ?
-                         FRAME_CURSOR_COLOR (s->f).pixel : face->background);
-
+      BView_SetHighColor (view, background);
       BView_FillRectangle (view, x, y - ascent, s->width, height);
       s->background_filled_p = 1;
     }
 
-  if (s->hl == DRAW_CURSOR)
-    BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
-  else
-    BView_SetHighColor (view, face->foreground);
-
+  BView_SetHighColor (view, foreground);
   BView_MovePenTo (view, x, y);
   BView_SetFont (view, ((struct haikufont_info *) info)->be_font);
 
@@ -999,12 +1003,13 @@ haikufont_draw (struct glyph_string *s, int from, int to,
   else
     {
       ptrdiff_t b_len = 0;
-      char *b = xmalloc (b_len);
+      char *b = alloca ((to - from + 1) * MAX_MULTIBYTE_LENGTH);
 
       for (int idx = from; idx < to; ++idx)
        {
          int len = CHAR_STRING (s->char2b[idx], mb);
-         b = xrealloc (b, b_len = (b_len + len));
+         b_len += len;
+
          if (len == 1)
            b[b_len - len] = mb[0];
          else
@@ -1012,9 +1017,8 @@ haikufont_draw (struct glyph_string *s, int from, int to,
        }
 
       BView_DrawString (view, b, b_len);
-      xfree (b);
     }
-  BView_draw_unlock (view);
+
   unblock_input ();
   return 1;
 }
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 875f1afb6a..26eb3dbfe1 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -150,11 +150,20 @@ digest_menu_items (void *first_menu, int start, int 
menu_items_used,
          else if (NILP (def) && menu_separator_name_p (SSDATA (item_name)))
            BMenu_add_separator (menu);
          else if (!mbar_p)
-           BMenu_add_item (menu, SSDATA (item_name),
-                           !NILP (def) ? aref_addr (menu_items, i) : NULL,
-                           !NILP (enable), !NILP (selected), 0, window,
-                           !NILP (descrip) ? SSDATA (descrip) : NULL,
-                           STRINGP (help) ? SSDATA (help) : NULL);
+           {
+             if (!use_system_tooltips || NILP (Fsymbol_value (Qtooltip_mode)))
+               BMenu_add_item (menu, SSDATA (item_name),
+                               !NILP (def) ? aref_addr (menu_items, i) : NULL,
+                               !NILP (enable), !NILP (selected), 0, window,
+                               !NILP (descrip) ? SSDATA (descrip) : NULL,
+                               NULL);
+             else
+               BMenu_add_item (menu, SSDATA (item_name),
+                               !NILP (def) ? aref_addr (menu_items, i) : NULL,
+                               !NILP (enable), !NILP (selected), 0, window,
+                               !NILP (descrip) ? SSDATA (descrip) : NULL,
+                               STRINGP (help) ? SSDATA (help) : NULL);
+           }
          else if (!use_system_tooltips || NILP (Fsymbol_value (Qtooltip_mode)))
            BMenu_add_item (menu, SSDATA (item_name),
                            !NILP (def) ? (void *) (intptr_t) i : NULL,
@@ -294,6 +303,27 @@ haiku_popup_dialog (struct frame *f, Lisp_Object header, 
Lisp_Object contents)
   return selection;
 }
 
+static void
+haiku_menu_show_help (void *help, void *data)
+{
+  Lisp_Object *id = (Lisp_Object *) help;
+
+  if (help)
+    show_help_echo (id[MENU_ITEMS_ITEM_HELP],
+                   Qnil, Qnil, Qnil);
+  else
+    show_help_echo (Qnil, Qnil, Qnil, Qnil);
+}
+
+static void
+haiku_process_pending_signals_for_menu (void)
+{
+  process_pending_signals ();
+
+  input_pending = false;
+  detect_input_pending_run_timers (true);
+}
+
 Lisp_Object
 haiku_menu_show (struct frame *f, int x, int y, int menuflags,
                 Lisp_Object title, const char **error_name)
@@ -327,9 +357,14 @@ haiku_menu_show (struct frame *f, int x, int y, int 
menuflags,
     }
   digest_menu_items (menu, 0, menu_items_used, 0);
   BView_convert_to_screen (view, &x, &y);
-  menu_item_selection = BMenu_run (menu, x, y);
   unblock_input ();
 
+  popup_activated_p++;
+  menu_item_selection = BMenu_run (menu, x, y,  haiku_menu_show_help,
+                                  block_input, unblock_input,
+                                  haiku_process_pending_signals_for_menu, 
NULL);
+  popup_activated_p--;
+
   FRAME_DISPLAY_INFO (f)->grabbed = 0;
 
   if (menu_item_selection)
diff --git a/src/haikuterm.c b/src/haikuterm.c
index b9eb1d2fc5..0c7e08585e 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -461,9 +461,8 @@ haiku_draw_box_rect (struct glyph_string *s,
 }
 
 static void
-haiku_calculate_relief_colors (struct glyph_string *s,
-                              uint32_t *rgbout_w, uint32_t *rgbout_b,
-                              uint32_t *rgbout_c)
+haiku_calculate_relief_colors (struct glyph_string *s, uint32_t *rgbout_w,
+                              uint32_t *rgbout_b)
 {
   struct face *face = s->face;
 
@@ -480,7 +479,6 @@ haiku_calculate_relief_colors (struct glyph_string *s,
 
   hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 0.6), rgbout_b);
   hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 1.2), rgbout_w);
-  hsl_color_rgb (h, cs, fmin (1.0, fmax (0.2, l) * 1.8), rgbout_c);
 }
 
 static void
@@ -492,16 +490,18 @@ haiku_draw_relief_rect (struct glyph_string *s,
 {
   uint32_t color_white;
   uint32_t color_black;
-  uint32_t color_corner;
 
-  haiku_calculate_relief_colors (s, &color_white, &color_black,
-                                &color_corner);
+  haiku_calculate_relief_colors (s, &color_white, &color_black);
 
   void *view = FRAME_HAIKU_VIEW (s->f);
   BView_SetHighColor (view, raised_p ? color_white : color_black);
   if (clip_rect)
-    BView_ClipToRect (view, clip_rect->x, clip_rect->y, clip_rect->width,
-                     clip_rect->height);
+    {
+      BView_StartClip (view);
+      haiku_clip_to_string (s);
+      BView_ClipToRect (view, clip_rect->x, clip_rect->y, clip_rect->width,
+                       clip_rect->height);
+    }
   if (top_p)
     BView_FillRectangle (view, left_x, top_y, right_x - left_x + 1, hwidth);
   if (left_p)
@@ -546,7 +546,7 @@ haiku_draw_relief_rect (struct glyph_string *s,
   if (vwidth > 1 && right_p)
     BView_StrokeLine (view, right_x, top_y, right_x, bottom_y);
 
-  BView_SetHighColor (view, color_corner);
+  BView_SetHighColor (view, s->face->background);
 
   /* Omit corner pixels.  */
   if (hwidth > 1 || vwidth > 1)
@@ -560,6 +560,9 @@ haiku_draw_relief_rect (struct glyph_string *s,
       if (right_p && bot_p)
        BView_FillRectangle (view, right_x, bottom_y, 1, 1);
     }
+
+  if (clip_rect)
+    BView_EndClip (view);
 }
 
 static void
@@ -601,22 +604,26 @@ haiku_draw_underwave (struct glyph_string *s, int width, 
int x)
 
 static void
 haiku_draw_text_decoration (struct glyph_string *s, struct face *face,
-                           uint8_t dcol, int width, int x)
+                           int width, int x)
 {
+  unsigned long cursor_color;
+
   if (s->for_overlaps)
     return;
 
+  if (s->hl == DRAW_CURSOR)
+    haiku_merge_cursor_foreground (s, &cursor_color, NULL);
+
   void *view = FRAME_HAIKU_VIEW (s->f);
-  BView_draw_lock (view);
 
   if (face->underline)
     {
       if (s->hl == DRAW_CURSOR)
-       BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+       BView_SetHighColor (view, cursor_color);
       else if (!face->underline_defaulted_p)
        BView_SetHighColor (view, face->underline_color);
       else
-       BView_SetHighColor (view, dcol);
+       BView_SetHighColor (view, face->foreground);
 
       if (face->underline == FACE_UNDER_WAVE)
        haiku_draw_underwave (s, width, x);
@@ -709,11 +716,11 @@ haiku_draw_text_decoration (struct glyph_string *s, 
struct face *face,
     {
       unsigned long dy = 0, h = 1;
       if (s->hl == DRAW_CURSOR)
-       BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+       BView_SetHighColor (view, cursor_color);
       else if (!face->overline_color_defaulted_p)
        BView_SetHighColor (view, face->overline_color);
       else
-       BView_SetHighColor (view, dcol);
+       BView_SetHighColor (view, face->foreground);
 
       BView_FillRectangle (view, s->x, s->y + dy, s->width, h);
     }
@@ -733,26 +740,22 @@ haiku_draw_text_decoration (struct glyph_string *s, 
struct face *face,
       unsigned long dy = (glyph_height - h) / 2;
 
       if (s->hl == DRAW_CURSOR)
-       BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg);
+       BView_SetHighColor (view, cursor_color);
       else if (!face->strike_through_color_defaulted_p)
        BView_SetHighColor (view, face->strike_through_color);
       else
-       BView_SetHighColor (view, dcol);
+       BView_SetHighColor (view, face->foreground);
 
       BView_FillRectangle (view, s->x, glyph_y + dy, s->width, h);
     }
-
-  BView_draw_unlock (view);
 }
 
 static void
-haiku_draw_string_box (struct glyph_string *s, int clip_p)
+haiku_draw_string_box (struct glyph_string *s)
 {
   int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
   bool raised_p, left_p, right_p;
   struct glyph *last_glyph;
-  struct haiku_rect clip_rect;
-
   struct face *face = s->face;
 
   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
@@ -800,30 +803,13 @@ haiku_draw_string_box (struct glyph_string *s, int clip_p)
                 && (s->next == NULL
                     || s->next->hl != s->hl)));
 
-  get_glyph_string_clip_rect (s, &clip_rect);
-
   if (face->box == FACE_SIMPLE_BOX)
     haiku_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
-                        vwidth, left_p, right_p, &clip_rect);
+                        vwidth, left_p, right_p, NULL);
   else
     haiku_draw_relief_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
                            vwidth, raised_p, true, true, left_p, right_p,
-                           &clip_rect, 1);
-
-  if (clip_p)
-    {
-      void *view = FRAME_HAIKU_VIEW (s->f);
-
-      haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x);
-      BView_ClipToInverseRect (view, left_x, top_y, right_x - left_x + 1, 
hwidth);
-      if (left_p)
-       BView_ClipToInverseRect (view, left_x, top_y, vwidth, bottom_y - top_y 
+ 1);
-      BView_ClipToInverseRect (view, left_x, bottom_y - hwidth + 1,
-                              right_x - left_x + 1, hwidth);
-      if (right_p)
-       BView_ClipToInverseRect (view, right_x - vwidth + 1,
-                                top_y, vwidth, bottom_y - top_y + 1);
-    }
+                           NULL, 1);
 }
 
 static void
@@ -831,8 +817,12 @@ haiku_draw_plain_background (struct glyph_string *s, 
struct face *face,
                             int box_line_hwidth, int box_line_vwidth)
 {
   void *view = FRAME_HAIKU_VIEW (s->f);
+  unsigned long cursor_color;
   if (s->hl == DRAW_CURSOR)
-    BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
+    {
+      haiku_merge_cursor_foreground (s, NULL, &cursor_color);
+      BView_SetHighColor (view, cursor_color);
+    }
   else
     BView_SetHighColor (view, face->background_defaulted_p ?
                        FRAME_BACKGROUND_PIXEL (s->f) :
@@ -1064,7 +1054,10 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s)
        x -= width;
 
       void *view = FRAME_HAIKU_VIEW (s->f);
-      BView_SetHighColor (view, FRAME_CURSOR_COLOR (s->f).pixel);
+      unsigned long cursor_color;
+
+      haiku_merge_cursor_foreground (s, NULL, &cursor_color);
+      BView_SetHighColor (view, cursor_color);
       BView_FillRectangle (view, x, s->y, width, s->height);
 
       if (width < background_width)
@@ -1107,9 +1100,9 @@ haiku_draw_stretch_glyph_string (struct glyph_string *s)
       if (background_width > 0)
        {
          void *view = FRAME_HAIKU_VIEW (s->f);
-         uint32_t bkg;
+         unsigned long bkg;
          if (s->hl == DRAW_CURSOR)
-           bkg = FRAME_CURSOR_COLOR (s->f).pixel;
+           haiku_merge_cursor_foreground (s, NULL, &bkg);
          else
            bkg = s->face->background;
 
@@ -1124,7 +1117,6 @@ static void
 haiku_start_clip (struct glyph_string *s)
 {
   void *view = FRAME_HAIKU_VIEW (s->f);
-  BView_draw_lock (view);
   BView_StartClip (view);
 }
 
@@ -1133,7 +1125,6 @@ haiku_end_clip (struct glyph_string *s)
 {
   void *view = FRAME_HAIKU_VIEW (s->f);
   BView_EndClip (view);
-  BView_draw_unlock (view);
 }
 
 static void
@@ -1467,7 +1458,11 @@ haiku_draw_image_glyph_string (struct glyph_string *s)
 static void
 haiku_draw_glyph_string (struct glyph_string *s)
 {
+  void *view;
+
   block_input ();
+  view = FRAME_HAIKU_VIEW (s->f);
+  BView_draw_lock (view);
   prepare_face_for_display (s->f, s->face);
 
   struct face *face = s->face;
@@ -1506,7 +1501,7 @@ haiku_draw_glyph_string (struct glyph_string *s)
       haiku_clip_to_string (s);
       haiku_maybe_draw_background (s, 1);
       box_filled_p = 1;
-      haiku_draw_string_box (s, 0);
+      haiku_draw_string_box (s);
     }
   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
           && !s->clip_tail
@@ -1559,10 +1554,9 @@ haiku_draw_glyph_string (struct glyph_string *s)
   if (!s->for_overlaps)
     {
       if (!box_filled_p && face->box != FACE_NO_BOX)
-       haiku_draw_string_box (s, 1);
+       haiku_draw_string_box (s);
       else
-       haiku_draw_text_decoration (s, face, face->foreground,
-                                   s->width, s->x);
+       haiku_draw_text_decoration (s, face, s->width, s->x);
 
       if (s->prev)
        {
@@ -1617,6 +1611,7 @@ haiku_draw_glyph_string (struct glyph_string *s)
        }
     }
   haiku_end_clip (s);
+  BView_draw_unlock (view);
   unblock_input ();
 }
 
@@ -1692,7 +1687,7 @@ haiku_draw_window_cursor (struct window *w,
                          int cursor_width, bool on_p, bool active_p)
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-
+  struct face *face;
   struct glyph *phys_cursor_glyph;
   struct glyph *cursor_glyph;
 
@@ -1746,7 +1741,26 @@ haiku_draw_window_cursor (struct window *w,
 
   BView_draw_lock (view);
   BView_StartClip (view);
-  BView_SetHighColor (view, FRAME_CURSOR_COLOR (f).pixel);
+
+  if (cursor_type == BAR_CURSOR)
+    {
+      cursor_glyph = get_phys_cursor_glyph (w);
+      face = FACE_FROM_ID (f, cursor_glyph->face_id);
+    }
+
+  /* If the glyph's background equals the color we normally draw the
+     bar cursor in, our cursor in its normal color is invisible.  Use
+     the glyph's foreground color instead in this case, on the
+     assumption that the glyph's colors are chosen so that the glyph
+     is legible.  */
+
+  /* xterm.c only does this for bar cursors, and nobody has
+     complained, so it would be best to do that here as well.  */
+  if (cursor_type == BAR_CURSOR
+      && face->background == FRAME_CURSOR_COLOR (f).pixel)
+    BView_SetHighColor (view, face->foreground);
+  else
+    BView_SetHighColor (view, FRAME_CURSOR_COLOR (f).pixel);
   haiku_clip_to_row (w, glyph_row, TEXT_AREA);
 
   switch (cursor_type)
@@ -1759,7 +1773,6 @@ haiku_draw_window_cursor (struct window *w,
       BView_FillRectangle (view, fx, fy, w->phys_cursor_width, h);
       break;
     case BAR_CURSOR:
-      cursor_glyph = get_phys_cursor_glyph (w);
       if (cursor_glyph->resolved_level & 1)
        BView_FillRectangle (view, fx + cursor_glyph->pixel_width - 
w->phys_cursor_width,
                             fy, w->phys_cursor_width, h);
@@ -1916,11 +1929,11 @@ haiku_draw_window_divider (struct window *w, int x0, 
int x1, int y0, int y1)
        last pixels differently.  */
     {
       BView_SetHighColor (view, color_first);
-      BView_StrokeLine (f, x0, y0, x1 - 1, y0);
+      BView_StrokeLine (view, x0, y0, x1 - 1, y0);
       BView_SetHighColor (view, color);
       BView_FillRectangle (view, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
       BView_SetHighColor (view, color_last);
-      BView_StrokeLine (view, x0, y1, x1 - 1, y1);
+      BView_FillRectangle (view, x0, y1 - 1, x1 - x0, 1);
     }
   else
     {
@@ -2559,7 +2572,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
 
   if (!buf)
     buf = xmalloc (200);
-  haiku_read_size (&b_size);
+  haiku_read_size (&b_size, false);
   while (b_size >= 0)
     {
       enum haiku_event_type type;
@@ -2816,9 +2829,10 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
                    if (WINDOWP (window)
                        && !EQ (window, last_mouse_window)
                        && !EQ (window, selected_window)
+                       && !popup_activated_p
+                       && !MINI_WINDOW_P (XWINDOW (selected_window))
                        && (!NILP (focus_follows_mouse)
-                               || (EQ (XWINDOW (window)->frame,
-                                       XWINDOW (selected_window)->frame))))
+                           || f == SELECTED_FRAME ()))
                      {
                        inev.kind = SELECT_WINDOW_EVENT;
                        inev.frame_or_window = window;
@@ -2827,10 +2841,18 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
                    last_mouse_window = window;
                  }
 
+               if (f->auto_raise)
+                 {
+                   if (!BWindow_is_active (FRAME_HAIKU_WINDOW (f)))
+                     haiku_frame_raise_lower (f, 1);
+                 }
+
                if (!NILP (help_echo_string)
                    || !NILP (previous_help_echo_string))
                  do_help = 1;
              }
+
+           need_flush = FRAME_DIRTY_P (f);
            break;
          }
        case BUTTON_UP:
@@ -2840,8 +2862,9 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
            struct frame *f = haiku_window_to_frame (b->window);
            Lisp_Object tab_bar_arg = Qnil;
            int tab_bar_p = 0, tool_bar_p = 0;
+           bool up_okay_p = false;
 
-           if (!f)
+           if (popup_activated_p || !f)
              continue;
 
            struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
@@ -2892,10 +2915,12 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
            if (type == BUTTON_UP)
              {
                inev.modifiers |= up_modifier;
+               up_okay_p = (dpyinfo->grabbed & (1 << b->btn_no));
                dpyinfo->grabbed &= ~(1 << b->btn_no);
              }
            else
              {
+               up_okay_p = true;
                inev.modifiers |= down_modifier;
                dpyinfo->last_mouse_frame = f;
                dpyinfo->grabbed |= (1 << b->btn_no);
@@ -2905,7 +2930,9 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
                  f->last_tool_bar_item = -1;
              }
 
-           if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
+           if (up_okay_p
+               && !(tab_bar_p && NILP (tab_bar_arg))
+               && !tool_bar_p)
              inev.kind = MOUSE_CLICK_EVENT;
            inev.arg = tab_bar_arg;
            inev.code = b->btn_no;
@@ -3256,11 +3283,12 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
          }
        case APP_QUIT_REQUESTED_EVENT:
        case KEY_UP:
+       case DUMMY_EVENT:
        default:
          break;
        }
 
-      haiku_read_size (&b_size);
+      haiku_read_size (&b_size, false);
 
       if (inev.kind != NO_EVENT)
        {
@@ -3285,7 +3313,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
 
   for (struct unhandled_event *ev = unhandled_events; ev;)
     {
-      haiku_write_without_signal (ev->type, &ev->buffer);
+      haiku_write_without_signal (ev->type, &ev->buffer, false);
       struct unhandled_event *old = ev;
       ev = old->next;
       xfree (old);
@@ -3317,6 +3345,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
     flush_dirty_back_buffers ();
 
   unblock_input ();
+
   return message_count;
 }
 
@@ -3625,21 +3654,53 @@ haiku_set_offset (struct frame *frame, int x, int y,
 cairo_t *
 haiku_begin_cr_clip (struct frame *f, struct glyph_string *s)
 {
-  cairo_surface_t *surface = FRAME_CR_SURFACE (f);
-  if (!surface)
+  cairo_t *cr = FRAME_CR_CONTEXT (f);
+
+  if (!cr)
     return NULL;
 
-  cairo_t *context = cairo_create (surface);
-  return context;
+  cairo_save (cr);
+  return cr;
 }
 
 void
 haiku_end_cr_clip (cairo_t *cr)
 {
-  cairo_destroy (cr);
+  if (!cr)
+    return;
+
+  cairo_restore (cr);
 }
 #endif
 
+void
+haiku_merge_cursor_foreground (struct glyph_string *s,
+                              unsigned long *foreground_out,
+                              unsigned long *background_out)
+{
+  unsigned long background = FRAME_CURSOR_COLOR (s->f).pixel;
+  unsigned long foreground = s->face->background;
+
+  if (background == foreground)
+    foreground = s->face->background;
+  if (background == foreground)
+    foreground = FRAME_OUTPUT_DATA (s->f)->cursor_fg;
+  if (background == foreground)
+    foreground = s->face->foreground;
+
+  if (background == s->face->background
+      || foreground == s->face->foreground)
+    {
+      background = s->face->foreground;
+      foreground = s->face->background;
+    }
+
+  if (foreground_out)
+    *foreground_out = foreground;
+  if (background_out)
+    *background_out = background;
+}
+
 void
 syms_of_haikuterm (void)
 {
diff --git a/src/haikuterm.h b/src/haikuterm.h
index de302883e4..a2520858f5 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -32,10 +32,6 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "font.h"
 #include "systime.h"
 
-#define C_FRAME struct frame *
-#define C_FONT struct font *
-#define C_TERMINAL struct terminal *
-
 #define HAVE_CHAR_CACHE_MAX 65535
 
 extern int popup_activated_p;
@@ -64,7 +60,7 @@ struct haiku_display_info
 {
   /* Chain of all haiku_display_info structures. */
   struct haiku_display_info *next;
-  C_TERMINAL terminal;
+  struct terminal *terminal;
 
   Lisp_Object name_list_element;
   Lisp_Object color_map;
@@ -86,7 +82,6 @@ struct haiku_display_info
   int n_planes;
   int color_p;
 
-  Window root_window;
   Lisp_Object rdb;
 
   Emacs_Cursor vertical_scroll_bar_cursor;
@@ -94,9 +89,9 @@ struct haiku_display_info
 
   Mouse_HLInfo mouse_highlight;
 
-  C_FRAME highlight_frame;
-  C_FRAME last_mouse_frame;
-  C_FRAME last_mouse_motion_frame;
+  struct frame *highlight_frame;
+  struct frame *last_mouse_frame;
+  struct frame *last_mouse_motion_frame;
 
   int last_mouse_motion_x;
   int last_mouse_motion_y;
@@ -110,6 +105,8 @@ struct haiku_display_info
   double resx, resy;
 
   Time last_mouse_movement_time;
+
+  Window root_window;
 };
 
 struct haiku_output
@@ -160,7 +157,7 @@ struct haiku_output
 
   int menu_bar_open_p;
 
-  C_FONT font;
+  struct font *font;
 
   int hourglass_p;
   uint32_t cursor_fg;
@@ -234,8 +231,10 @@ struct scroll_bar
 #define FRAME_CURSOR_COLOR(f) (FRAME_OUTPUT_DATA (f)->cursor_color)
 
 #ifdef USE_BE_CAIRO
-#define FRAME_CR_SURFACE(f) \
-  (FRAME_HAIKU_VIEW (f) ? EmacsView_cairo_surface (FRAME_HAIKU_VIEW (f)) : 0);
+#define FRAME_CR_CONTEXT(f)                                    \
+  (FRAME_HAIKU_VIEW (f)                                                \
+   ? EmacsView_cairo_context (FRAME_HAIKU_VIEW (f))            \
+   : NULL)
 #endif
 
 extern void syms_of_haikuterm (void);
@@ -295,4 +294,7 @@ haiku_begin_cr_clip (struct frame *f, struct glyph_string 
*s);
 extern void
 haiku_end_cr_clip (cairo_t *cr);
 #endif
+
+extern void haiku_merge_cursor_foreground (struct glyph_string *, unsigned 
long *,
+                                          unsigned long *);
 #endif /* _HAIKU_TERM_H_ */
diff --git a/src/image.c b/src/image.c
index 32e03ab6f7..7f2bd77781 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2848,13 +2848,12 @@ x_create_x_image_and_pixmap (struct frame *f, int 
width, int height, int depth,
 {
   Display *display = FRAME_X_DISPLAY (f);
   Drawable drawable = FRAME_X_DRAWABLE (f);
-  Screen *screen = FRAME_X_SCREEN (f);
 
   eassert (input_blocked_p ());
 
   if (depth <= 0)
-    depth = DefaultDepthOfScreen (screen);
-  *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
+    depth = FRAME_DISPLAY_INFO (f)->n_planes;
+  *ximg = XCreateImage (display, FRAME_X_VISUAL (f),
                        depth, ZPixmap, 0, NULL, width, height,
                        depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
   if (*ximg == NULL)
@@ -2910,7 +2909,7 @@ x_create_xrender_picture (struct frame *f, Emacs_Pixmap 
pixmap, int depth)
   if (FRAME_DISPLAY_INFO (f)->xrender_supported_p)
     {
       if (depth <= 0)
-       depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
+       depth = FRAME_DISPLAY_INFO (f)->n_planes;
       if (depth == 32 || depth == 24 || depth == 8 || depth == 4 || depth == 1)
         {
           /* FIXME: Do we need to handle all possible bit depths?
@@ -4632,8 +4631,10 @@ xpm_load (struct frame *f, struct image *img)
 #ifndef HAVE_NTGUI
   attrs.visual = FRAME_X_VISUAL (f);
   attrs.colormap = FRAME_X_COLORMAP (f);
+  attrs.depth = FRAME_DISPLAY_INFO (f)->n_planes;
   attrs.valuemask |= XpmVisual;
   attrs.valuemask |= XpmColormap;
+  attrs.valuemask |= XpmDepth;
 #endif /* HAVE_NTGUI */
 
 #ifdef ALLOC_XPM_COLORS
@@ -11024,7 +11025,7 @@ gs_load (struct frame *f, struct image *img)
       block_input ();
       img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
                                   img->width, img->height,
-                                  DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
+                                  FRAME_DISPLAY_INFO (f)->n_planes);
       unblock_input ();
     }
 
diff --git a/src/indent.c b/src/indent.c
index 5c21cd8f99..efeb9e74f4 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -468,31 +468,40 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, 
ptrdiff_t *endpos)
 {
   Lisp_Object val, overlay;
 
-  if (CONSP (val = get_char_property_and_overlay
-            (make_fixnum (pos), Qdisplay, Qnil, &overlay))
-      && EQ (Qspace, XCAR (val)))
-    { /* FIXME: Use calc_pixel_width_or_height.  */
-      Lisp_Object plist = XCDR (val), prop;
+  if (!NILP (val = get_char_property_and_overlay (make_fixnum (pos), Qdisplay,
+                                                 Qnil, &overlay)))
+    {
       int width = -1;
-      EMACS_INT align_to_max =
-       (col < MOST_POSITIVE_FIXNUM - INT_MAX
-        ? (EMACS_INT) INT_MAX + col
-        : MOST_POSITIVE_FIXNUM);
-
-      if ((prop = Fplist_get (plist, QCwidth),
-          RANGED_FIXNUMP (0, prop, INT_MAX))
-         || (prop = Fplist_get (plist, QCrelative_width),
-             RANGED_FIXNUMP (0, prop, INT_MAX)))
-       width = XFIXNUM (prop);
-      else if (FLOATP (prop) && 0 <= XFLOAT_DATA (prop)
-              && XFLOAT_DATA (prop) <= INT_MAX)
-       width = (int)(XFLOAT_DATA (prop) + 0.5);
-      else if ((prop = Fplist_get (plist, QCalign_to),
-               RANGED_FIXNUMP (col, prop, align_to_max)))
-       width = XFIXNUM (prop) - col;
-      else if (FLOATP (prop) && col <= XFLOAT_DATA (prop)
-              && (XFLOAT_DATA (prop) <= align_to_max))
-       width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
+      Lisp_Object plist = Qnil;
+
+      /* Handle '(space ...)' display specs.  */
+      if (CONSP (val) && EQ (Qspace, XCAR (val)))
+       { /* FIXME: Use calc_pixel_width_or_height.  */
+         Lisp_Object prop;
+         EMACS_INT align_to_max =
+           (col < MOST_POSITIVE_FIXNUM - INT_MAX
+            ? (EMACS_INT) INT_MAX + col
+            : MOST_POSITIVE_FIXNUM);
+
+         plist = XCDR (val);
+         if ((prop = Fplist_get (plist, QCwidth),
+              RANGED_FIXNUMP (0, prop, INT_MAX))
+             || (prop = Fplist_get (plist, QCrelative_width),
+                 RANGED_FIXNUMP (0, prop, INT_MAX)))
+           width = XFIXNUM (prop);
+         else if (FLOATP (prop) && 0 <= XFLOAT_DATA (prop)
+                  && XFLOAT_DATA (prop) <= INT_MAX)
+           width = (int)(XFLOAT_DATA (prop) + 0.5);
+         else if ((prop = Fplist_get (plist, QCalign_to),
+                   RANGED_FIXNUMP (col, prop, align_to_max)))
+           width = XFIXNUM (prop) - col;
+         else if (FLOATP (prop) && col <= XFLOAT_DATA (prop)
+                  && (XFLOAT_DATA (prop) <= align_to_max))
+           width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
+       }
+      /* Handle 'display' strings.   */
+      else if (STRINGP (val))
+       width = XFIXNUM (Fstring_width (val, Qnil, Qnil));
 
       if (width >= 0)
        {
@@ -504,7 +513,8 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, 
ptrdiff_t *endpos)
 
          /* For :relative-width, we need to multiply by the column
             width of the character at POS, if it is greater than 1.  */
-         if (!NILP (Fplist_get (plist, QCrelative_width))
+         if (!NILP (plist)
+             && !NILP (Fplist_get (plist, QCrelative_width))
              && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
            {
              int b, wd;
@@ -516,6 +526,7 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, 
ptrdiff_t *endpos)
          return width;
        }
     }
+
   return -1;
 }
 
diff --git a/src/lread.c b/src/lread.c
index 9910db27de..713c03243c 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -5240,12 +5240,9 @@ for symbols and features not associated with any file.
 The remaining ENTRIES in the alist element describe the functions and
 variables defined in that file, the features provided, and the
 features required.  Each entry has the form `(provide . FEATURE)',
-`(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)',
-`(defface . SYMBOL)', `(define-type . SYMBOL)',
-`(cl-defmethod METHOD SPECIALIZERS)', or `(t . SYMBOL)'.
-Entries like `(t . SYMBOL)' may precede a `(defun . FUNCTION)' entry,
-and mean that SYMBOL was an autoload before this file redefined it
-as a function.  In addition, entries may also be single symbols,
+`(require . FEATURE)', `(defun . FUNCTION)', `(defface . SYMBOL)',
+ `(define-type . SYMBOL)', or `(cl-defmethod METHOD SPECIALIZERS)'.
+In addition, entries may also be single symbols,
 which means that symbol was defined by `defvar' or `defconst'.
 
 During preloading, the file name recorded is relative to the main Lisp
diff --git a/src/macfont.m b/src/macfont.m
index f623c3ca2f..34e48afb98 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -3570,7 +3570,10 @@ mac_font_create_preferred_family_for_attributes 
(CFDictionaryRef attributes)
 
       if (languages && CFArrayGetCount (languages) > 0)
         {
-          if (CTGetCoreTextVersion () >= kCTVersionNumber10_9)
+          if ([[NSProcessInfo processInfo]
+                isOperatingSystemAtLeastVersion:
+                  ((NSOperatingSystemVersion){
+                    .majorVersion = 10, .minorVersion = 9})])
             values[num_values++] = CFArrayGetValueAtIndex (languages, 0);
           else
             {
diff --git a/src/menu.c b/src/menu.c
index 18ecaf0b0b..449f0b44ae 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1395,6 +1395,8 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
   record_unwind_protect_void (discard_menu_items);
 #endif
 
+  run_hook (Qx_pre_popup_menu_hook);
+
   /* Display them in a menu, but not if F is the initial frame that
      doesn't have its hooks set (e.g., in a batch session), because
      such a frame cannot display menus.  */
@@ -1408,7 +1410,11 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
   discard_menu_items ();
 #endif
 
-#ifdef HAVE_NTGUI     /* FIXME: Is it really w32-specific?  --Stef  */
+#ifdef HAVE_NTGUI     /* W32 specific because other terminals clear
+                        the grab inside their `menu_show_hook's if
+                        it's actually required (i.e. there isn't a
+                        way to query the buttons currently held down
+                        after XMenuActivate). */
   if (FRAME_W32_P (f))
     FRAME_DISPLAY_INFO (f)->grabbed = 0;
 #endif
@@ -1602,6 +1608,14 @@ syms_of_menu (void)
   staticpro (&menu_items);
 
   DEFSYM (Qhide, "hide");
+  DEFSYM (Qx_pre_popup_menu_hook, "x-pre-popup-menu-hook");
+
+  DEFVAR_LISP ("x-pre-popup-menu-hook", Vx_pre_popup_menu_hook,
+              doc: /* Hook run before `x-popup-menu' displays a popup menu.
+It is only run before the menu is really going to be displayed.  It
+won't be run if `x-popup-menu' fails or returns for some other reason
+(such as the keymap is invalid).  */);
+  Vx_pre_popup_menu_hook = Qnil;
 
   defsubr (&Sx_popup_menu);
   defsubr (&Sx_popup_dialog);
diff --git a/src/nsfns.m b/src/nsfns.m
index 11132a294a..467e56ece4 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1004,6 +1004,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
   ns_set_z_group,
   0, /* x_set_override_redirect */
   gui_set_no_special_glyphs,
+  gui_set_alpha_background,
 #ifdef NS_IMPL_COCOA
   ns_set_appearance,
   ns_set_transparent_titlebar,
@@ -1436,6 +1437,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
                          RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qfullscreen, Qnil,
                          "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
diff --git a/src/nsselect.m b/src/nsselect.m
index 13ca9b9c44..a7ef9df0e0 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -250,7 +250,7 @@ ns_get_foreign_selection (Lisp_Object symbol, Lisp_Object 
target)
 
       NSString *type;
       NSEnumerator *e = [[pb types] objectEnumerator];
-      while (type = [e nextObject])
+      while ((type = [e nextObject]))
         {
           NSString *val = [typeLookup valueForKey:type];
           if (val && ! [types containsObject:val])
diff --git a/src/nsterm.m b/src/nsterm.m
index a3c7b55218..1d7788e3e5 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6798,6 +6798,7 @@ not_in_argv (NSString *arg)
       if (WINDOWP (window)
           && !EQ (window, last_mouse_window)
           && !EQ (window, selected_window)
+         && !MINI_WINDOW_P (XWINDOW (selected_window))
           && (!NILP (focus_follows_mouse)
               || (EQ (XWINDOW (window)->frame,
                       XWINDOW (selected_window)->frame))))
@@ -7933,25 +7934,6 @@ not_in_argv (NSString *arg)
 
   NSRect dstRect = NSMakeRect (dest.x, dest.y, NSWidth (srcRect),
                                NSHeight (srcRect));
-  NSRect frame = [self frame];
-
-  /* TODO: This check is an attempt to debug a rare graphical glitch
-     on macOS and should be removed before the Emacs 28 release.  */
-  if (!NSContainsRect (frame, srcRect)
-      || !NSContainsRect (frame, dstRect))
-    {
-      NSLog (@"[EmacsView copyRect:to:] Attempting to copy to or "
-             "from an area outside the graphics buffer.");
-      NSLog (@"  Frame: (%f, %f) %f×%f",
-             NSMinX (frame), NSMinY (frame),
-             NSWidth (frame), NSHeight (frame));
-      NSLog (@"  Source: (%f, %f) %f×%f",
-             NSMinX (srcRect), NSMinY (srcRect),
-             NSWidth (srcRect), NSHeight (srcRect));
-      NSLog (@"  Destination: (%f, %f) %f×%f",
-             NSMinX (dstRect), NSMinY (dstRect),
-             NSWidth (dstRect), NSHeight (dstRect));
-    }
 
 #ifdef NS_IMPL_COCOA
   if ([self wantsLayer])
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 9c37c04810..15e14f75e4 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -234,6 +234,24 @@ x_set_background_color (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
   unblock_input ();
 }
 
+static void
+pgtk_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object 
oldval)
+{
+  gui_set_alpha_background (f, arg, oldval);
+
+  /* This prevents GTK from painting the window's background, which
+     interferes with transparent background in some environments */
+
+  gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f),
+                               f->alpha_background != 1.0);
+
+  if (FRAME_GTK_OUTER_WIDGET (f)
+      && gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f))
+      && f->alpha_background != 1.0)
+    gdk_window_set_opaque_region (gtk_widget_get_window 
(FRAME_GTK_OUTER_WIDGET (f)),
+                                 NULL);
+}
+
 static void
 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
@@ -664,40 +682,6 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
 {
 }
 
-
-static void
-x_icon (struct frame *f, Lisp_Object parms)
-/* --------------------------------------------------------------------------
-   Strangely-named function to set icon position parameters in frame.
-   This is irrelevant under macOS, but might be needed under GNUstep,
-   depending on the window manager used.  Note, this is not a standard
-   frame parameter-setter; it is called directly from x-create-frame.
-   -------------------------------------------------------------------------- 
*/
-{
-#if 0
-  Lisp_Object icon_x, icon_y;
-  struct pgtk_display_info *dpyinfo = check_pgtk_display_info (Qnil);
-
-  FRAME_X_OUTPUT (f)->icon_top = -1;
-  FRAME_X_OUTPUT (f)->icon_left = -1;
-
-  /* Set the position of the icon.  */
-  icon_x =
-    gui_display_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
-  icon_y =
-    gui_display_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
-  if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
-    {
-      CHECK_NUMBER (icon_x);
-      CHECK_NUMBER (icon_y);
-      FRAME_X_OUTPUT (f)->icon_top = XFIXNUM (icon_y);
-      FRAME_X_OUTPUT (f)->icon_left = XFIXNUM (icon_x);
-    }
-  else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
-    error ("Both left and top icon corners of icon must be specified");
-#endif
-}
-
 /**
  * x_set_undecorated:
  *
@@ -874,13 +858,10 @@ pgtk_set_scroll_bar_foreground (struct frame *f, 
Lisp_Object new_value,
       if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
        error ("Unknown color.");
 
-      /* On pgtk, this frame parameter should be ignored, and honor gtk theme. 
*/
-#if 0
       char css[64];
       sprintf (css, "scrollbar slider { background-color: #%06x; }",
               (unsigned int) rgb.pixel & 0xffffff);
       gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
-#endif
       update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
 
     }
@@ -907,13 +888,13 @@ pgtk_set_scroll_bar_background (struct frame *f, 
Lisp_Object new_value,
       if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
        error ("Unknown color.");
 
-      /* On pgtk, this frame parameter should be ignored, and honor gtk theme. 
*/
-#if 0
+      /* On pgtk, this frame parameter should be ignored, and honor
+        gtk theme.  (It honors the GTK theme if not explictly set, so
+        I see no harm in letting users tinker a bit more.)  */
       char css[64];
       sprintf (css, "scrollbar trough { background-color: #%06x; }",
               (unsigned int) rgb.pixel & 0xffffff);
       gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
-#endif
       update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
 
     }
@@ -1043,6 +1024,7 @@ frame_parm_handler pgtk_frame_parm_handlers[] = {
   x_set_z_group,
   x_set_override_redirect,
   gui_set_no_special_glyphs,
+  pgtk_set_alpha_background,
 };
 
 
@@ -1359,9 +1341,6 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
 
   f->output_method = output_pgtk;
   FRAME_X_OUTPUT (f) = xzalloc (sizeof *FRAME_X_OUTPUT (f));
-#if 0
-  FRAME_X_OUTPUT (f)->icon_bitmap = -1;
-#endif
   FRAME_FONTSET (f) = -1;
   FRAME_X_OUTPUT (f)->white_relief.pixel = -1;
   FRAME_X_OUTPUT (f)->black_relief.pixel = -1;
@@ -1459,12 +1438,8 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
       error ("Invalid frame font");
     }
 
-  /* Frame contents get displaced if an embedded X window has a border.  */
-#if 0
-  if (!FRAME_X_EMBEDDED_P (f))
-#endif
-    gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
-                          "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
+                        "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
 
   if (NILP (Fassq (Qinternal_border_width, parms)))
     {
@@ -1608,10 +1583,6 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
                         RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
-#if 0
-  x_icon_verify (f, parms);
-#endif
-
   /* Create the X widget or window.  */
   /* x_window (f); */
   xg_create_frame_widgets (f);
@@ -1639,11 +1610,6 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
 
 #undef INSTALL_CURSOR
 
-  x_icon (f, parms);
-#if 0
-  x_make_gc (f);
-#endif
-
   /* Now consider the frame official.  */
   f->terminal->reference_count++;
   FRAME_DISPLAY_INFO (f)->reference_count++;
@@ -1667,6 +1633,8 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
                         RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                         "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   if (!NILP (parent_frame))
     {
@@ -1798,21 +1766,6 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
   return unbind_to (count, frame);
 }
 
-
-#if 0
-static int
-pgtk_window_is_ancestor (PGTKWindow * win, PGTKWindow * candidate)
-/* Test whether CANDIDATE is an ancestor window of WIN. */
-{
-  if (candidate == NULL)
-    return 0;
-  else if (win == candidate)
-    return 1;
-  else
-    return pgtk_window_is_ancestor (win,[candidate parentWindow]);
-}
-#endif
-
 /**
  * x_frame_restack:
  *
@@ -2796,9 +2749,6 @@ x_create_tip_frame (struct pgtk_display_info *dpyinfo, 
Lisp_Object parms, struct
      counts etc.  */
   f->output_method = output_pgtk;
   f->output_data.pgtk = xzalloc (sizeof *f->output_data.pgtk);
-#if 0
-  f->output_data.pgtk->icon_bitmap = -1;
-#endif
   FRAME_FONTSET (f) = -1;
   f->output_data.pgtk->white_relief.pixel = -1;
   f->output_data.pgtk->black_relief.pixel = -1;
@@ -2924,10 +2874,6 @@ x_create_tip_frame (struct pgtk_display_info *dpyinfo, 
Lisp_Object parms, struct
   gtk_window_set_type_hint (GTK_WINDOW (tip_window), 
GDK_WINDOW_TYPE_HINT_TOOLTIP);
   f->output_data.pgtk->current_cursor = f->output_data.pgtk->text_cursor;
 
-#if 0
-  x_make_gc (f);
-#endif
-
   gui_default_parameter (f, parms, Qauto_raise, Qnil,
                          "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
   gui_default_parameter (f, parms, Qauto_lower, Qnil,
@@ -2936,6 +2882,8 @@ x_create_tip_frame (struct pgtk_display_info *dpyinfo, 
Lisp_Object parms, struct
                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   /* Add `tooltip' frame parameter's default value. */
   if (NILP (Fframe_parameter (frame, Qtooltip)))
diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c
index d1b1bfffb3..18aaf57302 100644
--- a/src/pgtkmenu.c
+++ b/src/pgtkmenu.c
@@ -141,31 +141,15 @@ popup_deactivate_callback (GtkWidget *widget, gpointer 
client_data)
 static void
 show_help_event (struct frame *f, GtkWidget *widget, Lisp_Object help)
 {
-  /* Don't show this tooltip.
-   * Tooltips are always tied to main widget, so stacking order
-   * on Wayland is:
-   *   (above)
-   *   - menu
-   *   - tooltip
-   *   - main widget
-   *   (below)
-   * This is applicable to tooltips for menu, and menu tooltips
-   * are shown below menus.
-   * As a workaround, I entrust Gtk with menu tooltips, and
-   * let emacs not to show menu tooltips.
-   */
-
-#if 0
-  Lisp_Object frame;
-
-  if (f)
-    {
-      XSETFRAME (frame, f);
-      kbd_buffer_store_help_event (frame, help);
-    }
-  else
-    show_help_echo (help, Qnil, Qnil, Qnil);
-#endif
+  /* Don't show help echo on PGTK, as tooltips are always transient
+     for the main widget, so on Wayland the menu will display above
+     and obscure the tooltip.  FIXME: this is some low hanging fruit
+     for fixing.  After you fix Fx_show_tip in pgtkterm.c so that it
+     can display tooltips above menus, copy the definition of this
+     function from xmenu.c.
+
+     As a workaround, GTK is used to display menu tooltips, outside
+     the Emacs help echo machinery.  */
 }
 
 /* Callback called when menu items are highlighted/unhighlighted
diff --git a/src/pgtkselect.c b/src/pgtkselect.c
index 23a79895d5..24fed19cd2 100644
--- a/src/pgtkselect.c
+++ b/src/pgtkselect.c
@@ -36,10 +36,6 @@ GNUstep port and post-20 update by Adrian Robert 
(arobert@cogsci.ucsd.edu)
 #include "pgtkselect.h"
 #include <gdk/gdk.h>
 
-#if 0
-static Lisp_Object Vselection_alist;
-#endif
-
 static GQuark quark_primary_data = 0;
 static GQuark quark_primary_size = 0;
 static GQuark quark_secondary_data = 0;
@@ -606,11 +602,6 @@ syms_of_pgtkselect (void)
   defsubr (&Spgtk_selection_exists_p);
   defsubr (&Spgtk_selection_owner_p);
 
-#if 0
-  Vselection_alist = Qnil;
-  staticpro (&Vselection_alist);
-#endif
-
   DEFVAR_LISP ("pgtk-sent-selection-hooks", Vpgtk_sent_selection_hooks,
               "A list of functions to be called when Emacs answers a selection 
request.\n\
 The functions are called with four arguments:\n\
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index efbeaafaf1..169d3f8a03 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -101,7 +101,8 @@ static void pgtk_delete_display (struct pgtk_display_info 
*dpyinfo);
 static void pgtk_clear_frame_area (struct frame *f, int x, int y, int width,
                                   int height);
 static void pgtk_fill_rectangle (struct frame *f, unsigned long color, int x,
-                                int y, int width, int height);
+                                int y, int width, int height,
+                                bool respect_alpha_background);
 static void pgtk_clip_to_row (struct window *w, struct glyph_row *row,
                              enum glyph_row_area area, cairo_t * cr);
 static struct frame *pgtk_any_window_to_frame (GdkWindow * window);
@@ -581,10 +582,6 @@ pgtk_iconify_frame (struct frame *f)
 
   block_input ();
 
-#if 0
-  x_set_bitmap_icon (f);
-#endif
-
   if (FRAME_GTK_OUTER_WIDGET (f))
     {
       if (!FRAME_VISIBLE_P (f))
@@ -599,21 +596,9 @@ pgtk_iconify_frame (struct frame *f)
 
   /* Make sure the X server knows where the window should be positioned,
      in case the user deiconifies with the window manager.  */
-  if (!FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f)
-#if 0
-      && !FRAME_X_EMBEDDED_P (f)
-#endif
-    )
+  if (!FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
     x_set_offset (f, f->left_pos, f->top_pos, 0);
 
-#if 0
-  if (!FRAME_VISIBLE_P (f))
-    {
-      /* If the frame was withdrawn, before, we must map it.  */
-      XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-    }
-#endif
-
   SET_FRAME_ICONIFIED (f, true);
   SET_FRAME_VISIBLE (f, 0);
 
@@ -1243,7 +1228,7 @@ pgtk_compute_glyph_string_overhangs (struct glyph_string 
*s)
 static void
 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
 {
-  pgtk_fill_rectangle (s->f, s->xgcv.background, x, y, w, h);
+  pgtk_fill_rectangle (s->f, s->xgcv.background, x, y, w, h, true);
 }
 
 
@@ -1328,12 +1313,12 @@ x_draw_glyph_string_background (struct glyph_string *s, 
bool force_p)
 
 static void
 pgtk_draw_rectangle (struct frame *f, unsigned long color, int x, int y,
-                    int width, int height)
+                    int width, int height, bool respect_alpha_background)
 {
   cairo_t *cr;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, respect_alpha_background);
   cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
   cairo_set_line_width (cr, 1);
   cairo_stroke (cr);
@@ -1363,7 +1348,8 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
          struct glyph *g = s->first_glyph + i;
          pgtk_draw_rectangle (s->f,
                               s->face->foreground, x, s->y,
-                              g->pixel_width - 1, s->height - 1);
+                              g->pixel_width - 1, s->height - 1,
+                              false);
          x += g->pixel_width;
        }
     }
@@ -1413,7 +1399,7 @@ x_draw_composite_glyph_string_foreground (struct 
glyph_string *s)
     {
       if (s->cmp_from == 0)
        pgtk_draw_rectangle (s->f, s->face->foreground, x, s->y,
-                            s->width - 1, s->height - 1);
+                            s->width - 1, s->height - 1, false);
     }
   else if (!s->first_glyph->u.cmp.automatic)
     {
@@ -1555,7 +1541,8 @@ x_draw_glyphless_glyph_string_foreground (struct 
glyph_string *s)
        pgtk_draw_rectangle (s->f, s->face->foreground,
                             x, s->ybase - glyph->ascent,
                             glyph->pixel_width - 1,
-                            glyph->ascent + glyph->descent - 1);
+                            glyph->ascent + glyph->descent - 1,
+                            false);
       x += glyph->pixel_width;
     }
 }
@@ -1658,7 +1645,7 @@ x_fill_trapezoid_for_relief (struct frame *f, unsigned 
long color, int x,
   cairo_t *cr;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, false);
   cairo_move_to (cr, top_p ? x : x + height, y);
   cairo_line_to (cr, x, y + height);
   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
@@ -1685,7 +1672,7 @@ x_erase_corners_for_relief (struct frame *f, unsigned 
long color, int x,
   int i;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, false);
   for (i = 0; i < CORNER_LAST; i++)
     if (corners & (1 << i))
       {
@@ -1818,7 +1805,7 @@ x_draw_relief_rect (struct frame *f,
   if (left_p)
     {
       pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
-                          vwidth, bottom_y + 1 - top_y);
+                          vwidth, bottom_y + 1 - top_y, false);
       if (top_p)
        corners |= 1 << CORNER_TOP_LEFT;
       if (bot_p)
@@ -1827,7 +1814,7 @@ x_draw_relief_rect (struct frame *f,
   if (right_p)
     {
       pgtk_fill_rectangle (f, bottom_right_color, right_x + 1 - vwidth, top_y,
-                          vwidth, bottom_y + 1 - top_y);
+                          vwidth, bottom_y + 1 - top_y, false);
       if (top_p)
        corners |= 1 << CORNER_TOP_RIGHT;
       if (bot_p)
@@ -1837,7 +1824,7 @@ x_draw_relief_rect (struct frame *f,
     {
       if (!right_p)
        pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
-                            right_x + 1 - left_x, hwidth);
+                            right_x + 1 - left_x, hwidth, false);
       else
        x_fill_trapezoid_for_relief (f, top_left_color, left_x, top_y,
                                     right_x + 1 - left_x, hwidth, 1);
@@ -1847,7 +1834,7 @@ x_draw_relief_rect (struct frame *f,
       if (!left_p)
        pgtk_fill_rectangle (f, bottom_right_color, left_x,
                             bottom_y + 1 - hwidth, right_x + 1 - left_x,
-                            hwidth);
+                            hwidth, false);
       else
        x_fill_trapezoid_for_relief (f, bottom_right_color,
                                     left_x, bottom_y + 1 - hwidth,
@@ -1855,10 +1842,10 @@ x_draw_relief_rect (struct frame *f,
     }
   if (left_p && vwidth > 1)
     pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
-                        1, bottom_y + 1 - top_y);
+                        1, bottom_y + 1 - top_y, false);
   if (top_p && hwidth > 1)
     pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
-                        right_x + 1 - left_x, 1);
+                        right_x + 1 - left_x, 1, false);
   if (corners)
     {
       x_erase_corners_for_relief (f, FRAME_BACKGROUND_PIXEL (f), left_x,
@@ -1893,23 +1880,25 @@ x_draw_box_rect (struct glyph_string *s,
 
   /* Top.  */
   pgtk_fill_rectangle (s->f, s->xgcv.foreground,
-                      left_x, top_y, right_x - left_x + 1, hwidth);
+                      left_x, top_y, right_x - left_x + 1, hwidth,
+                      false);
 
   /* Left.  */
   if (left_p)
     pgtk_fill_rectangle (s->f, s->xgcv.foreground,
-                        left_x, top_y, vwidth, bottom_y - top_y + 1);
+                        left_x, top_y, vwidth, bottom_y - top_y + 1,
+                        false);
 
   /* Bottom.  */
   pgtk_fill_rectangle (s->f, s->xgcv.foreground,
                       left_x, bottom_y - hwidth + 1, right_x - left_x + 1,
-                      hwidth);
+                      hwidth, false);
 
   /* Right.  */
   if (right_p)
     pgtk_fill_rectangle (s->f, s->xgcv.foreground,
                         right_x - vwidth + 1, top_y, vwidth,
-                        bottom_y - top_y + 1);
+                        bottom_y - top_y + 1, false);
 
   s->xgcv.foreground = foreground_backup;
 
@@ -1979,7 +1968,7 @@ x_draw_horizontal_wave (struct frame *f, unsigned long 
color, int x, int y,
   int xoffset, n;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, false);
   cairo_rectangle (cr, x, y, width, height);
   cairo_clip (cr);
 
@@ -2155,7 +2144,7 @@ x_cr_draw_image (struct frame *f, Emacs_GC *gc, 
cairo_pattern_t *image,
     cairo_rectangle (cr, dest_x, dest_y, width, height);
   else
     {
-      pgtk_set_cr_source_with_gc_background (f, gc);
+      pgtk_set_cr_source_with_gc_background (f, gc, false);
       cairo_rectangle (cr, dest_x, dest_y, width, height);
       cairo_fill_preserve (cr);
     }
@@ -2172,7 +2161,7 @@ x_cr_draw_image (struct frame *f, Emacs_GC *gc, 
cairo_pattern_t *image,
     }
   else
     {
-      pgtk_set_cr_source_with_gc_foreground (f, gc);
+      pgtk_set_cr_source_with_gc_foreground (f, gc, false);
       cairo_clip (cr);
       cairo_mask (cr, image);
     }
@@ -2222,7 +2211,7 @@ x_draw_image_foreground (struct glyph_string *s)
              int relief = eabs (s->img->relief);
              pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief, y - 
relief,
                                   s->slice.width + relief*2 - 1,
-                                  s->slice.height + relief*2 - 1);
+                                  s->slice.height + relief*2 - 1, false);
            }
        }
       pgtk_end_cr_clip (s->f);
@@ -2230,7 +2219,7 @@ x_draw_image_foreground (struct glyph_string *s)
   else
     /* Draw a rectangle if image could not be loaded.  */
     pgtk_draw_rectangle (s->f, s->xgcv.foreground, x, y,
-                        s->slice.width - 1, s->slice.height - 1);
+                        s->slice.width - 1, s->slice.height - 1, false);
 }
 
 /* Draw image glyph string S.
@@ -2375,7 +2364,8 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
            }
          else
            {
-             pgtk_fill_rectangle (s->f, color, x, y, w, h);
+             pgtk_fill_rectangle (s->f, color, x, y, w, h,
+                                  true);
            }
 
          pgtk_end_cr_clip (s->f);
@@ -2601,11 +2591,13 @@ pgtk_draw_glyph_string (struct glyph_string *s)
              y = s->ybase + position;
              if (s->face->underline_defaulted_p)
                pgtk_fill_rectangle (s->f, s->xgcv.foreground,
-                                    s->x, y, s->width, thickness);
+                                    s->x, y, s->width, thickness,
+                                    false);
              else
                {
                  pgtk_fill_rectangle (s->f, s->face->underline_color,
-                                      s->x, y, s->width, thickness);
+                                      s->x, y, s->width, thickness,
+                                      false);
                }
            }
        }
@@ -2616,11 +2608,11 @@ pgtk_draw_glyph_string (struct glyph_string *s)
 
          if (s->face->overline_color_defaulted_p)
            pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, s->y + dy,
-                                s->width, h);
+                                s->width, h, false);
          else
            {
              pgtk_fill_rectangle (s->f, s->face->overline_color, s->x,
-                                  s->y + dy, s->width, h);
+                                  s->y + dy, s->width, h, false);
            }
        }
 
@@ -2641,11 +2633,11 @@ pgtk_draw_glyph_string (struct glyph_string *s)
 
          if (s->face->strike_through_color_defaulted_p)
            pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, glyph_y + dy,
-                                s->width, h);
+                                s->width, h, false);
          else
            {
              pgtk_fill_rectangle (s->f, s->face->strike_through_color, s->x,
-                                  glyph_y + dy, s->width, h);
+                                  glyph_y + dy, s->width, h, false);
            }
        }
 
@@ -2778,7 +2770,7 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row 
*row)
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
   cairo_t *cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->cursor_color);
+  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->cursor_color, false);
 
   /* When on R2L character, show cursor at the right edge of the
      glyph, unless the cursor box is as wide as the glyph or wider
@@ -2792,7 +2784,7 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row 
*row)
     }
   /* Set clipping, draw the rectangle, and reset clipping again.  */
   pgtk_clip_to_row (w, row, TEXT_AREA, cr);
-  pgtk_draw_rectangle (f, FRAME_X_OUTPUT (f)->cursor_color, x, y, wd, h - 1);
+  pgtk_draw_rectangle (f, FRAME_X_OUTPUT (f)->cursor_color, x, y, wd, h - 1, 
false);
   pgtk_end_cr_clip (f);
 }
 
@@ -2866,7 +2858,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row 
*row, int width,
 
          pgtk_fill_rectangle (f, color, x,
                               WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                              width, row->height);
+                              width, row->height, false);
        }
       else                     /* HBAR_CURSOR */
        {
@@ -2887,7 +2879,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row 
*row, int width,
          pgtk_fill_rectangle (f, color, x,
                               WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
                                                        row->height - width),
-                              w->phys_cursor_width - 1, width);
+                              w->phys_cursor_width - 1, width, false);
        }
 
       pgtk_end_cr_clip (f);
@@ -2958,17 +2950,20 @@ pgtk_draw_window_cursor (struct window *w, struct 
glyph_row *glyph_row, int x,
 }
 
 static void
-pgtk_copy_bits (struct frame *f, cairo_rectangle_t * src_rect,
-               cairo_rectangle_t * dst_rect)
+pgtk_copy_bits (struct frame *f, cairo_rectangle_t *src_rect,
+               cairo_rectangle_t *dst_rect)
 {
   cairo_t *cr;
+  GdkWindow *window;
   cairo_surface_t *surface;    /* temporary surface */
 
+  window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
+
   surface =
-    cairo_surface_create_similar (FRAME_CR_SURFACE (f),
-                                 CAIRO_CONTENT_COLOR_ALPHA,
-                                 (int) src_rect->width,
-                                 (int) src_rect->height);
+    gdk_window_create_similar_surface (window, CAIRO_CONTENT_COLOR_ALPHA,
+                                      FRAME_CR_SURFACE_DESIRED_WIDTH (f),
+                                      FRAME_CR_SURFACE_DESIRED_HEIGHT
+                                      (f));
 
   cr = cairo_create (surface);
   cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), -src_rect->x,
@@ -2980,6 +2975,7 @@ pgtk_copy_bits (struct frame *f, cairo_rectangle_t * 
src_rect,
 
   cr = pgtk_begin_cr_clip (f);
   cairo_set_source_surface (cr, surface, dst_rect->x, dst_rect->y);
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
   cairo_rectangle (cr, dst_rect->x, dst_rect->y, dst_rect->width,
                   dst_rect->height);
   cairo_clip (cr);
@@ -3241,7 +3237,7 @@ pgtk_draw_vertical_window_border (struct window *w, int 
x, int y0, int y1)
 
   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
   if (face)
-    pgtk_set_cr_source_with_color (f, face->foreground);
+    pgtk_set_cr_source_with_color (f, face->foreground, false);
 
   cairo_rectangle (cr, x, y0, 1, y1 - y0);
   cairo_fill (cr);
@@ -3272,32 +3268,32 @@ pgtk_draw_window_divider (struct window *w, int x0, int 
x1, int y0, int y1)
   if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
     /* Vertical.  */
     {
-      pgtk_set_cr_source_with_color (f, color_first);
+      pgtk_set_cr_source_with_color (f, color_first, false);
       cairo_rectangle (cr, x0, y0, 1, y1 - y0);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color);
+      pgtk_set_cr_source_with_color (f, color, false);
       cairo_rectangle (cr, x0 + 1, y0, x1 - x0 - 2, y1 - y0);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color_last);
+      pgtk_set_cr_source_with_color (f, color_last, false);
       cairo_rectangle (cr, x1 - 1, y0, 1, y1 - y0);
       cairo_fill (cr);
     }
   else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
     /* Horizontal.  */
     {
-      pgtk_set_cr_source_with_color (f, color_first);
+      pgtk_set_cr_source_with_color (f, color_first, false);
       cairo_rectangle (cr, x0, y0, x1 - x0, 1);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color);
+      pgtk_set_cr_source_with_color (f, color, false);
       cairo_rectangle (cr, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color_last);
+      pgtk_set_cr_source_with_color (f, color_last, false);
       cairo_rectangle (cr, x0, y1 - 1, x1 - x0, 1);
       cairo_fill (cr);
     }
   else
     {
-      pgtk_set_cr_source_with_color (f, color);
+      pgtk_set_cr_source_with_color (f, color, false);
       cairo_rectangle (cr, x0, y0, x1 - x0, y1 - y0);
       cairo_fill (cr);
     }
@@ -3520,7 +3516,7 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC * gc, 
cairo_pattern_t * image,
     cairo_rectangle (cr, dest_x, dest_y, width, height);
   else
     {
-      pgtk_set_cr_source_with_gc_background (f, gc);
+      pgtk_set_cr_source_with_gc_background (f, gc, false);
       cairo_rectangle (cr, dest_x, dest_y, width, height);
       cairo_fill_preserve (cr);
     }
@@ -3536,7 +3532,7 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC * gc, 
cairo_pattern_t * image,
     }
   else
     {
-      pgtk_set_cr_source_with_gc_foreground (f, gc);
+      pgtk_set_cr_source_with_gc_foreground (f, gc, false);
       cairo_clip (cr);
       cairo_mask (cr, image);
     }
@@ -3568,7 +3564,7 @@ pgtk_draw_fringe_bitmap (struct window *w, struct 
glyph_row *row,
        }
       else
        {
-         pgtk_set_cr_source_with_color (f, face->background);
+         pgtk_set_cr_source_with_color (f, face->background, true);
          cairo_rectangle (cr, p->bx, p->by, p->nx, p->ny);
          cairo_fill (cr);
        }
@@ -4588,22 +4584,6 @@ x_set_frame_alpha (struct frame *f)
   else if (alpha < alpha_min && alpha_min <= 1.0)
     alpha = alpha_min;
 
-#if 0
-  /* If there is a parent from the window manager, put the property there
-     also, to work around broken window managers that fail to do that.
-     Do this unconditionally as this function is called on reparent when
-     alpha has not changed on the frame.  */
-
-  if (!FRAME_PARENT_FRAME (f))
-    {
-      Window parent = x_find_topmost_parent (f);
-      if (parent != None)
-       XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
-                        XA_CARDINAL, 32, PropModeReplace,
-                        (unsigned char *) &opac, 1);
-    }
-#endif
-
   set_opacity_recursively (FRAME_WIDGET (f), &alpha);
   /* without this, blending mode is strange on wayland. */
   gtk_widget_queue_resize_no_redraw (FRAME_WIDGET (f));
@@ -4970,11 +4950,11 @@ pgtk_handle_event (GtkWidget *widget, GdkEvent *event, 
gpointer *data)
 
 static void
 pgtk_fill_rectangle (struct frame *f, unsigned long color, int x, int y,
-                    int width, int height)
+                    int width, int height, bool respect_alpha_background)
 {
   cairo_t *cr;
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, respect_alpha_background);
   cairo_rectangle (cr, x, y, width, height);
   cairo_fill (cr);
   pgtk_end_cr_clip (f);
@@ -5682,6 +5662,32 @@ window_state_event (GtkWidget *widget,
        }
     }
 
+  if (event->window_state.new_window_state
+      & GDK_WINDOW_STATE_FULLSCREEN)
+    store_frame_param (f, Qfullscreen, Qfullboth);
+  else if (event->window_state.new_window_state
+          & GDK_WINDOW_STATE_MAXIMIZED)
+    store_frame_param (f, Qfullscreen, Qmaximized);
+  else
+    store_frame_param (f, Qfullscreen, Qnil);
+
+  if (event->window_state.new_window_state
+      & GDK_WINDOW_STATE_ICONIFIED)
+    SET_FRAME_ICONIFIED (f, true);
+  else
+    {
+      FRAME_X_OUTPUT (f)->has_been_visible = true;
+      inev.ie.kind = DEICONIFY_EVENT;
+      XSETFRAME (inev.ie.frame_or_window, f);
+      SET_FRAME_ICONIFIED (f, false);
+    }
+
+  if (event->window_state.new_window_state
+      & GDK_WINDOW_STATE_STICKY)
+    store_frame_param (f, Qsticky, Qt);
+  else
+    store_frame_param (f, Qsticky, Qnil);
+
   if (inev.ie.kind != NO_EVENT)
     evq_enqueue (&inev);
   return FALSE;
@@ -6114,9 +6120,6 @@ button_event (GtkWidget * widget, GdkEvent * event, 
gpointer * user_data)
   dpyinfo = FRAME_DISPLAY_INFO (frame);
 
   dpyinfo->last_mouse_glyph_frame = NULL;
-#if 0
-  x_display_set_last_user_time (dpyinfo, event->button.time);
-#endif
 
   if (gui_mouse_grabbed (dpyinfo))
     f = dpyinfo->last_mouse_frame;
@@ -6145,14 +6148,6 @@ button_event (GtkWidget * widget, GdkEvent * event, 
gpointer * user_data)
        }
     }
 
-  /* xg_event_is_for_scrollbar() doesn't work correctly on sway, and
-   * we shouldn't need it.
-   */
-#if 0
-  if (f && xg_event_is_for_scrollbar (f, event))
-    f = 0;
-#endif
-
   if (f)
     {
       /* Is this in the tab-bar?  */
@@ -6194,11 +6189,6 @@ button_event (GtkWidget * widget, GdkEvent * event, 
gpointer * user_data)
          if (!NILP (tab_bar_arg))
            inev.ie.arg = tab_bar_arg;
        }
-#if 0
-      if (FRAME_X_EMBEDDED_P (f))
-       xembed_send_message (f, event->button.time,
-                            XEMBED_REQUEST_FOCUS, 0, 0, 0);
-#endif
     }
 
   if (event->type == GDK_BUTTON_PRESS)
@@ -6913,7 +6903,8 @@ pgtk_clear_area (struct frame *f, int x, int y, int 
width, int height)
   eassert (width > 0 && height > 0);
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->background_color);
+  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->background_color,
+                                true);
   cairo_rectangle (cr, x, y, width, height);
   cairo_fill (cr);
   pgtk_end_cr_clip (f);
@@ -7095,25 +7086,39 @@ pgtk_end_cr_clip (struct frame *f)
 }
 
 void
-pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC * gc)
+pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC *gc,
+                                      bool respects_alpha_background)
 {
-  pgtk_set_cr_source_with_color (f, gc->foreground);
+  pgtk_set_cr_source_with_color (f, gc->foreground,
+                                respects_alpha_background);
 }
 
 void
-pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC * gc)
+pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC *gc,
+                                      bool respects_alpha_background)
 {
-  pgtk_set_cr_source_with_color (f, gc->background);
+  pgtk_set_cr_source_with_color (f, gc->background,
+                                respects_alpha_background);
 }
 
 void
-pgtk_set_cr_source_with_color (struct frame *f, unsigned long color)
+pgtk_set_cr_source_with_color (struct frame *f, unsigned long color,
+                              bool respects_alpha_background)
 {
   Emacs_Color col;
   col.pixel = color;
   pgtk_query_color (f, &col);
-  cairo_set_source_rgb (FRAME_CR_CONTEXT (f), col.red / 65535.0,
-                       col.green / 65535.0, col.blue / 65535.0);
+
+  if (!respects_alpha_background)
+    cairo_set_source_rgb (FRAME_CR_CONTEXT (f), col.red / 65535.0,
+                         col.green / 65535.0, col.blue / 65535.0);
+  else
+    {
+      cairo_set_source_rgba (FRAME_CR_CONTEXT (f), col.red / 65535.0,
+                            col.green / 65535.0, col.blue / 65535.0,
+                            f->alpha_background);
+      cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
+    }
 }
 
 void
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index 42b03e315e..4d2285cdb0 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -591,12 +591,9 @@ extern void x_set_z_group (struct frame *f, Lisp_Object 
new_value,
 extern void pgtk_cr_update_surface_desired_size (struct frame *, int, int, 
bool);
 extern cairo_t *pgtk_begin_cr_clip (struct frame *f);
 extern void pgtk_end_cr_clip (struct frame *f);
-extern void pgtk_set_cr_source_with_gc_foreground (struct frame *f,
-                                                  Emacs_GC * gc);
-extern void pgtk_set_cr_source_with_gc_background (struct frame *f,
-                                                  Emacs_GC * gc);
-extern void pgtk_set_cr_source_with_color (struct frame *f,
-                                          unsigned long color);
+extern void pgtk_set_cr_source_with_gc_foreground (struct frame *, Emacs_GC *, 
bool);
+extern void pgtk_set_cr_source_with_gc_background (struct frame *, Emacs_GC *, 
bool);
+extern void pgtk_set_cr_source_with_color (struct frame *, unsigned long, 
bool);
 extern void pgtk_cr_draw_frame (cairo_t * cr, struct frame *f);
 extern void pgtk_cr_destroy_frame_context (struct frame *f);
 extern Lisp_Object pgtk_cr_export_frames (Lisp_Object frames, 
cairo_surface_type_t surface_type);
diff --git a/src/search.c b/src/search.c
index a1adfa2d8c..80541921de 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2827,6 +2827,14 @@ All the elements are markers or nil (nil if the Nth pair 
didn't match)
 if the last match was on a buffer; integers or nil if a string was matched.
 Use `set-match-data' to reinstate the data in this list.
 
+Note that non-matching optional groups at the end of the regexp are
+elided instead of being represented with two `nil's each.  For instance:
+
+  (progn
+    (string-match "^\\(a\\)?\\(b\\)\\(c\\)?$" "b")
+    (match-data))
+  => (0 1 nil nil 0 1)
+
 If INTEGERS (the optional first argument) is non-nil, always use
 integers (rather than markers) to represent buffer positions.  In
 this case, and if the last match was in a buffer, the buffer will get
diff --git a/src/terminal.c b/src/terminal.c
index 3db80f4b1f..80f3aed700 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -622,6 +622,8 @@ init_initial_terminal (void)
     emacs_abort ();
 
   initial_terminal = create_terminal (output_initial, NULL);
+  /* Note: menu-bar.el:menu-bar-update-buffers knows about this
+     special name of the initial terminal.  */
   initial_terminal->name = xstrdup ("initial_terminal");
   initial_terminal->kboard = initial_kboard;
   initial_terminal->delete_terminal_hook = &delete_initial_terminal;
diff --git a/src/w32fns.c b/src/w32fns.c
index 1ea685d194..009855602e 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6018,6 +6018,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
                          NULL, NULL, RES_TYPE_BOOLEAN);
   gui_default_parameter (f, parameters, Qno_special_glyphs, Qnil,
                          NULL, NULL, RES_TYPE_BOOLEAN);
+  gui_default_parameter (f, parameters, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   /* Process alpha here (Bug#16619).  On XP this fails with child
      frames.  For `no-focus-on-map' frames delay processing of alpha
@@ -6155,6 +6157,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   gui_default_parameter (f, parameters, Qz_group, Qnil,
                          NULL, NULL, RES_TYPE_SYMBOL);
 
+  gui_default_parameter (f, parameters, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
+
   /* Make the window appear on the frame and enable display, unless
      the caller says not to.  However, with explicit parent, Emacs
      cannot control visibility, so don't try.  */
@@ -7089,6 +7094,8 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, 
Lisp_Object parms)
   /* Process alpha here (Bug#17344).  */
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   /* Add `tooltip' frame parameter's default value. */
   if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -10436,6 +10443,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
   w32_set_z_group,
   0, /* x_set_override_redirect */
   gui_set_no_special_glyphs,
+  gui_set_alpha_background,
 };
 
 void
diff --git a/src/window.c b/src/window.c
index 2a5e4042a4..449f2b0cc5 100644
--- a/src/window.c
+++ b/src/window.c
@@ -481,7 +481,9 @@ Return WINDOW.  */)
 DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
        doc: /* Return the selected window.
 The selected window is the window in which the standard cursor for
-selected windows appears and to which many commands apply.  */)
+selected windows appears and to which many commands apply.
+
+Also see `old-selected-window' and `minibuffer-selected-window'.  */)
   (void)
 {
   return selected_window;
diff --git a/src/xdisp.c b/src/xdisp.c
index 26bd45a861..cafc50e755 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -741,10 +741,6 @@ int update_mode_lines;
 
 static bool line_number_displayed;
 
-/* The name of the *Messages* buffer, a string.  */
-
-static Lisp_Object Vmessages_buffer_name;
-
 /* Current, index 0, and last displayed echo area message.  Either
    buffers from echo_buffers, or nil to indicate no message.  */
 
@@ -11378,6 +11374,10 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool 
nlflag, bool multibyte)
       old_deactivate_mark = Vdeactivate_mark;
       oldbuf = current_buffer;
 
+      /* Sanity check, in case the variable has been set to something
+        invalid.  */
+      if (! STRINGP (Vmessages_buffer_name))
+       Vmessages_buffer_name = build_string ("*Messages*");
       /* Ensure the Messages buffer exists, and switch to it.
          If we created it, set the major-mode.  */
       bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
@@ -18739,6 +18739,33 @@ set_horizontal_scroll_bar (struct window *w)
       (w, portion, whole, start);
 }
 
+/* Subroutine of redisplay_window, to determine whether a window-start
+   point STARTP of WINDOW should be rejected.  */
+static bool
+window_start_acceptable_p (Lisp_Object window, ptrdiff_t startp)
+{
+  if (!make_window_start_visible)
+    return true;
+
+  struct window *w = XWINDOW (window);
+  struct frame *f = XFRAME (w->frame);
+  Lisp_Object startpos = make_fixnum (startp);
+  Lisp_Object invprop, disp_spec;
+  struct text_pos ignored;
+
+  /* Is STARTP in invisible text?  */
+  if ((invprop = Fget_char_property (startpos, Qinvisible, window)),
+      TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
+    return false;
+
+  /* Is STARTP covered by a replacing 'display' property?  */
+  if (!NILP (disp_spec = Fget_char_property (startpos, Qdisplay, window))
+      && handle_display_spec (NULL, disp_spec, Qnil, Qnil, &ignored, startp,
+                             FRAME_WINDOW_P (f)) > 0)
+    return false;
+
+  return true;
+}
 
 /* Redisplay leaf window WINDOW.  JUST_THIS_ONE_P means only
    selected_window is redisplayed.
@@ -19070,6 +19097,11 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
       else if (CHARPOS (startp) > ZV)
        SET_TEXT_POS (startp, ZV, ZV_BYTE);
 
+      /* Reject the specified start location if it is invisible, and
+        the buffer wants it always visible.  */
+      if (!window_start_acceptable_p (window, CHARPOS (startp)))
+       goto ignore_start;
+
       /* Redisplay, then check if cursor has been set during the
         redisplay.  Give up if new fonts were loaded.  */
       /* We used to issue a CHECK_MARGINS argument to try_window here,
@@ -19227,6 +19259,8 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
       goto done;
     }
 
+ ignore_start:
+
   /* Handle case where text has not changed, only point, and it has
      not moved off the frame, and we are not retrying after hscroll.
      (current_matrix_up_to_date_p is true when retrying.)  */
@@ -19248,10 +19282,14 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
        }
     }
   /* If current starting point was originally the beginning of a line
-     but no longer is, find a new starting point.  */
+     but no longer is, or if the starting point is invisible but the
+     buffer wants it always visible, find a new starting point.  */
   else if (w->start_at_line_beg
-          && !(CHARPOS (startp) <= BEGV
-               || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
+          && ((CHARPOS (startp) > BEGV
+               && FETCH_BYTE (BYTEPOS (startp) - 1) != '\n')
+              || (CHARPOS (startp) >= BEGV
+                  && CHARPOS (startp) <= ZV
+                  && !window_start_acceptable_p (window, CHARPOS (startp)))))
     {
 #ifdef GLYPH_DEBUG
       debug_method_add (w, "recenter 1");
@@ -19327,6 +19365,17 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
          goto force_start;
        }
 
+      /* Don't use the same window-start if it is invisible or covered
+        by a replacing 'display' property and the buffer requested
+        the window-start to be always visible.  */
+      if (!window_start_acceptable_p (window, CHARPOS (startp)))
+       {
+#ifdef GLYPH_DEBUG
+         debug_method_add (w, "recenter 2");
+#endif
+         goto recenter;
+       }
+
 #ifdef GLYPH_DEBUG
       debug_method_add (w, "same window start");
 #endif
@@ -35626,8 +35675,13 @@ be let-bound around code that needs to disable 
messages temporarily. */);
   staticpro (&echo_area_buffer[0]);
   staticpro (&echo_area_buffer[1]);
 
-  Vmessages_buffer_name = build_pure_c_string ("*Messages*");
-  staticpro (&Vmessages_buffer_name);
+  DEFVAR_LISP ("messages-buffer-name", Vmessages_buffer_name,
+    doc: /* The name of the buffer where messages are logged.
+This is normally \"\*Messages*\", but can be rebound by packages that
+wish to redirect messages to a different buffer.  (If the buffer
+doesn't exist, it will be created and put into
+`messages-buffer-mode'.)  */);
+  Vmessages_buffer_name = build_string ("*Messages*");
 
   mode_line_proptrans_alist = Qnil;
   staticpro (&mode_line_proptrans_alist);
@@ -35968,6 +36022,12 @@ window, nil if it's okay to leave the cursor 
partially-visible.  */);
   Vmake_cursor_line_fully_visible = Qt;
   DEFSYM (Qmake_cursor_line_fully_visible, "make-cursor-line-fully-visible");
 
+  DEFVAR_BOOL ("make-window-start-visible", make_window_start_visible,
+    doc: /* Whether to ensure `window-start' position is never invisible.  */);
+  make_window_start_visible = false;
+  DEFSYM (Qmake_window_start_visible, "make-window-start-visible");
+  Fmake_variable_buffer_local (Qmake_window_start_visible);
+
   DEFSYM (Qclose_tab, "close-tab");
   DEFVAR_LISP ("tab-bar-border", Vtab_bar_border,
     doc: /* Border below tab-bar in pixels.
diff --git a/src/xfaces.c b/src/xfaces.c
index 6a279f8719..76ce693202 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4151,9 +4151,9 @@ If the optional argument FRAME is given, report on face 
FACE in that frame.
 If FRAME is t, report on the defaults for face FACE (for new frames).
   The font default for a face is either nil, or a list
   of the form (bold), (italic) or (bold italic).
-If FRAME is omitted or nil, use the selected frame.  And, in this case,
-if the optional third argument CHARACTER is given,
-return the font name used for CHARACTER.  */)
+If FRAME is omitted or nil, use the selected frame.
+If FRAME is anything but t, and the optional third argument CHARACTER
+is given, return the font name used by FACE for CHARACTER on FRAME.  */)
   (Lisp_Object face, Lisp_Object frame, Lisp_Object character)
 {
   if (EQ (frame, Qt))
diff --git a/src/xfns.c b/src/xfns.c
index faab1b1158..7878ee62f5 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -727,6 +727,30 @@ x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, 
Lisp_Object old_value
   f->output_data.x->wait_for_wm = !NILP (new_value);
 }
 
+static void
+x_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  gui_set_alpha_background (f, arg, oldval);
+
+#ifdef USE_GTK
+  /* This prevents GTK from painting the window's background, which
+     interferes with transparent background in some environments */
+
+  if (!FRAME_TOOLTIP_P (f))
+    gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f),
+                                 f->alpha_background != 1.0);
+#endif
+
+  if (f->alpha_background != 1.0)
+    {
+      XChangeProperty (FRAME_X_DISPLAY (f),
+                      FRAME_X_WINDOW (f),
+                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
+                      XA_CARDINAL, 32, PropModeReplace,
+                      NULL, 0);
+    }
+}
+
 static void
 x_set_tool_bar_position (struct frame *f,
                          Lisp_Object new_value,
@@ -1925,7 +1949,7 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object 
value, Lisp_Object old
 
 
 /* Encode Lisp string STRING as a text in a format appropriate for
-   XICCC (X Inter Client Communication Conventions).
+   the ICCCM (Inter Client Communication Conventions Manual).
 
    If STRING contains only ASCII characters, do no conversion and
    return the string data of STRING.  Otherwise, encode the text by
@@ -2331,6 +2355,67 @@ hack_wm_protocols (struct frame *f, Widget widget)
 }
 #endif
 
+static void
+append_wm_protocols (struct x_display_info *dpyinfo,
+                    struct frame *f)
+{
+  unsigned char *existing = NULL;
+  int format = 0;
+  unsigned long nitems = 0;
+  Atom type;
+  Atom *existing_protocols;
+  Atom protos[10];
+  int num_protos = 0;
+  bool found_wm_ping = false;
+#if !defined HAVE_GTK3 && defined HAVE_XSYNC
+  bool found_wm_sync_request = false;
+#endif
+  unsigned long bytes_after;
+
+  block_input ();
+  if ((XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
+                          dpyinfo->Xatom_wm_protocols,
+                          0, 100, False, XA_ATOM, &type, &format, &nitems,
+                          &bytes_after, &existing) == Success)
+      && format == 32 && type == XA_ATOM)
+    {
+      existing_protocols = (Atom *) existing;
+
+      while (nitems)
+       {
+         nitems--;
+
+         if (existing_protocols[nitems]
+             == dpyinfo->Xatom_net_wm_ping)
+           found_wm_ping = true;
+#if !defined HAVE_GTK3 && defined HAVE_XSYNC
+         else if (existing_protocols[nitems]
+                  == dpyinfo->Xatom_net_wm_sync_request)
+           found_wm_sync_request = true;
+#endif
+       }
+    }
+
+  if (existing)
+    XFree (existing);
+
+  if (!found_wm_ping)
+    protos[num_protos++] = dpyinfo->Xatom_net_wm_ping;
+#if !defined HAVE_GTK3 && defined HAVE_XSYNC
+  if (!found_wm_sync_request && dpyinfo->xsync_supported_p)
+    protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request;
+#endif
+
+  if (num_protos)
+    XChangeProperty (dpyinfo->display,
+                    FRAME_OUTER_WINDOW (f),
+                    dpyinfo->Xatom_wm_protocols,
+                    XA_ATOM, 32, PropModeAppend,
+                    (unsigned char *) protos,
+                    num_protos);
+  unblock_input ();
+}
+
 
 
 /* Support routines for XIC (X Input Context).  */
@@ -2848,6 +2933,9 @@ xic_set_preeditarea (struct window *w, int x, int y)
       XFree (attr);
     }
 #ifdef USE_GTK
+  if (f->tooltip)
+    return;
+
   GdkRectangle rect;
   int scale = xg_get_scale (f);
 
@@ -3603,6 +3691,7 @@ x_window (struct frame *f, long window_prompting)
               &f->output_data.x->wm_hints);
 
   hack_wm_protocols (f, shell_widget);
+  append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
 
 #ifdef X_TOOLKIT_EDITRES
   XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
@@ -3723,6 +3812,8 @@ x_window (struct frame *f)
   }
 #endif
 
+  append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
+
 #ifdef HAVE_XINPUT2
   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
     setup_xi_event_mask (f);
@@ -3758,7 +3849,7 @@ x_window (struct frame *f)
                     f->top_pos,
                     FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
                     f->border_width,
-                    CopyFromParent, /* depth */
+                    FRAME_DISPLAY_INFO (f)->n_planes, /* depth */
                     InputOutput, /* class */
                     FRAME_X_VISUAL (f),
                      attribute_mask, &attributes);
@@ -3811,6 +3902,8 @@ x_window (struct frame *f)
     XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
   }
 
+  append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
+
   /* x_set_name normally ignores requests to set the name if the
      requested name is the same as the current name.  This is the one
      place where that assumption isn't correct; f->name is set, but
@@ -4598,6 +4691,8 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
                          RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   if (!NILP (parent_frame))
     {
@@ -4713,6 +4808,46 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
                       (unsigned char *) &dpyinfo->client_leader_window, 1);
     }
 
+#ifdef HAVE_XSYNC
+  if (dpyinfo->xsync_supported_p)
+    {
+#ifndef HAVE_GTK3
+      XSyncValue initial_value;
+      XSyncCounter counters[2];
+
+      AUTO_STRING (synchronizeResize, "synchronizeResize");
+      AUTO_STRING (SynchronizeResize, "SynchronizeResize");
+
+      Lisp_Object value = gui_display_get_resource (dpyinfo,
+                                                   synchronizeResize,
+                                                   SynchronizeResize,
+                                                   Qnil, Qnil);
+
+      XSyncIntToValue (&initial_value, 0);
+      counters[0]
+       = FRAME_X_BASIC_COUNTER (f)
+       = XSyncCreateCounter (FRAME_X_DISPLAY (f),
+                             initial_value);
+
+      if (STRINGP (value) && !strcmp (SSDATA (value), "extended"))
+       counters[1]
+         = FRAME_X_EXTENDED_COUNTER (f)
+         = XSyncCreateCounter (FRAME_X_DISPLAY (f),
+                               initial_value);
+
+      FRAME_X_OUTPUT (f)->current_extended_counter_value
+       = initial_value;
+
+      XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+                      dpyinfo->Xatom_net_wm_sync_request_counter,
+                      XA_CARDINAL, 32, PropModeReplace,
+                      (unsigned char *) &counters,
+                      ((STRINGP (value)
+                        && !strcmp (SSDATA (value), "extended")) ? 2 : 1));
+#endif
+    }
+#endif
+
   unblock_input ();
 
   /* Works iff frame has been already mapped.  */
@@ -6371,10 +6506,32 @@ select_visual (struct x_display_info *dpyinfo)
       int n_visuals;
       XVisualInfo *vinfo, vinfo_template;
 
-      dpyinfo->visual = DefaultVisualOfScreen (screen);
+      vinfo_template.screen = XScreenNumberOfScreen (screen);
 
+#if !defined USE_X_TOOLKIT && !(defined USE_GTK && !defined HAVE_GTK3)
+      /* First attempt to use 32-bit visual if available */
+
+      vinfo_template.depth = 32;
+      vinfo_template.class = TrueColor;
+
+      vinfo = XGetVisualInfo (dpy, (VisualScreenMask
+                                   | VisualDepthMask
+                                   | VisualClassMask),
+                             &vinfo_template, &n_visuals);
+
+      if (n_visuals > 0 && vinfo)
+       {
+         dpyinfo->n_planes = vinfo->depth;
+         dpyinfo->visual = vinfo->visual;
+         XFree (vinfo);
+         return;
+       }
+
+#endif /* !USE_X_TOOLKIT */
+
+      /* 32-bit visual not available, fallback to default visual */
+      dpyinfo->visual = DefaultVisualOfScreen (screen);
       vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
-      vinfo_template.screen = XScreenNumberOfScreen (screen);
       vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
                              &vinfo_template, &n_visuals);
       if (n_visuals <= 0)
@@ -7148,7 +7305,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
     Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
 
     block_input ();
-    mask = CWBackPixel | CWOverrideRedirect | CWEventMask | CWCursor;
+    mask = (CWBackPixel | CWOverrideRedirect | CWEventMask
+           | CWCursor | CWColormap | CWBorderPixel);
     if (DoesSaveUnders (dpyinfo->screen))
       mask |= CWSaveUnder;
 
@@ -7158,9 +7316,11 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
     attrs.override_redirect = True;
     attrs.save_under = True;
     attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
+    attrs.colormap = FRAME_X_COLORMAP (f);
     attrs.cursor =
       f->output_data.x->current_cursor
       = f->output_data.x->text_cursor;
+    attrs.border_pixel = f->output_data.x->border_pixel;
     /* Arrange for getting MapNotify and UnmapNotify events.  */
     attrs.event_mask = StructureNotifyMask;
     tip_window
@@ -7171,7 +7331,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
                       0, 0, 1, 1,
                       /* Border.  */
                       f->border_width,
-                      CopyFromParent, InputOutput, CopyFromParent,
+                      dpyinfo->n_planes, InputOutput,
+                      FRAME_X_VISUAL (f),
                        mask, &attrs);
     initial_set_up_x_back_buffer (f);
     XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
@@ -7180,17 +7341,21 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
                      (unsigned char *)&type, 1);
     unblock_input ();
 #else
-    uint32_t value_list[4];
+    uint32_t value_list[6];
     xcb_atom_t net_wm_window_type_tooltip
       = (xcb_atom_t) dpyinfo->Xatom_net_window_type_tooltip;
+    xcb_visualid_t visual_id
+      = (xcb_visualid_t) XVisualIDFromVisual (FRAME_X_VISUAL (f));
 
     f->output_data.x->current_cursor = f->output_data.x->text_cursor;
     /* Values are set in the order of their enumeration in `enum
        xcb_cw_t'.  */
     value_list[0] = FRAME_BACKGROUND_PIXEL (f);
-    value_list[1] = true;
-    value_list[2] = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
-    value_list[3] = (xcb_cursor_t) f->output_data.x->text_cursor;
+    value_list[1] = f->output_data.x->border_pixel;
+    value_list[2] = true;
+    value_list[3] = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+    value_list[4] = (xcb_colormap_t) FRAME_X_COLORMAP (f);
+    value_list[5] = (xcb_cursor_t) f->output_data.x->text_cursor;
 
     block_input ();
     tip_window
@@ -7198,15 +7363,17 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
       = (Window) xcb_generate_id (dpyinfo->xcb_connection);
 
     xcb_create_window (dpyinfo->xcb_connection,
-                      XCB_COPY_FROM_PARENT,
+                      dpyinfo->n_planes,
                       (xcb_window_t) tip_window,
                       (xcb_window_t) dpyinfo->root_window,
                       0, 0, 1, 1, f->border_width,
                       XCB_WINDOW_CLASS_INPUT_OUTPUT,
-                      XCB_COPY_FROM_PARENT,
+                      visual_id,
                       (XCB_CW_BACK_PIXEL
+                       | XCB_CW_BORDER_PIXEL
                        | XCB_CW_OVERRIDE_REDIRECT
                        | XCB_CW_EVENT_MASK
+                       | XCB_CW_COLORMAP
                        | XCB_CW_CURSOR),
                       &value_list);
 
@@ -7232,6 +7399,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
+                         "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   /* Add `tooltip' frame parameter's default value. */
   if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -7618,6 +7787,8 @@ Text larger than the specified size is clipped.  */)
   ptrdiff_t count = SPECPDL_INDEX ();
   ptrdiff_t count_1;
   Lisp_Object window, size, tip_buf;
+  Window child;
+  int dest_x_return, dest_y_return;
   AUTO_STRING (tip, " *tip*");
 
   specbind (Qinhibit_redisplay, Qt);
@@ -7842,6 +8013,27 @@ Text larger than the specified size is clipped.  */)
 
   /* Show tooltip frame.  */
   block_input ();
+  /* If the display is composited, then WM_TRANSIENT_FOR must be set
+     as well, or else the compositing manager won't display
+     decorations correctly, even though the tooltip window is override
+     redirect. See
+     https://specifications.freedesktop.org/wm-spec/1.4/ar01s08.html
+
+     Perhaps WM_TRANSIENT_FOR should be used in place of
+     override-redirect anyway.  The ICCCM only recommends
+     override-redirect if the pointer will be grabbed.  */
+
+  if (XTranslateCoordinates (FRAME_X_DISPLAY (f),
+                            FRAME_DISPLAY_INFO (f)->root_window,
+                            FRAME_DISPLAY_INFO (f)->root_window,
+                            root_x, root_y, &dest_x_return,
+                            &dest_y_return, &child))
+    XSetTransientForHint (FRAME_X_DISPLAY (tip_f),
+                         FRAME_X_WINDOW (tip_f), child);
+  else
+    XSetTransientForHint (FRAME_X_DISPLAY (tip_f),
+                         FRAME_X_WINDOW (tip_f), None);
+
 #ifndef USE_XCB
   XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
                     root_x, root_y, width, height);
@@ -8502,6 +8694,34 @@ DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 
0,
 #endif /* GTK_CHECK_VERSION (3, 14, 0) */
 #endif /* HAVE_GTK3 */
 #endif /* USE_GTK */
+
+DEFUN ("x-internal-focus-input-context", Fx_internal_focus_input_context,
+       Sx_internal_focus_input_context, 2, 2, 0,
+       doc: /* Focus and set the client window of FRAME's GTK input context.
+If FOCUS is nil, focus out and remove the client window instead.
+This should be called from a variable watcher for `x-gtk-use-native-input'.  
*/)
+  (Lisp_Object focus, Lisp_Object frame)
+{
+#ifdef USE_GTK
+  struct frame *f = decode_window_system_frame (frame);
+  GtkWidget *widget = FRAME_GTK_OUTER_WIDGET (f);
+
+  if (!NILP (focus))
+    {
+      gtk_im_context_focus_in (FRAME_X_OUTPUT (f)->im_context);
+      gtk_im_context_set_client_window (FRAME_X_OUTPUT (f)->im_context,
+                                       gtk_widget_get_window (widget));
+    }
+  else
+    {
+      gtk_im_context_focus_out (FRAME_X_OUTPUT (f)->im_context);
+      gtk_im_context_set_client_window (FRAME_X_OUTPUT (f)->im_context,
+                                       NULL);
+    }
+#endif
+
+  return Qnil;
+}
 
 /***********************************************************************
                            Initialization
@@ -8560,8 +8780,57 @@ frame_parm_handler x_frame_parm_handlers[] =
   x_set_z_group,
   x_set_override_redirect,
   gui_set_no_special_glyphs,
+  x_set_alpha_background,
 };
 
+/* Some versions of libX11 don't have symbols for a few functions we
+   need, so define replacements here.  */
+
+#ifdef HAVE_XKB
+#ifndef HAVE_XKBREFRESHKEYBOARDMAPPING
+Status
+XkbRefreshKeyboardMapping (XkbMapNotifyEvent *event)
+{
+  return Success;
+}
+#endif
+
+#ifndef HAVE_XKBFREENAMES
+void
+XkbFreeNames (XkbDescPtr xkb, unsigned int which, Bool free_map)
+{
+  return;
+}
+#endif
+#endif
+
+#ifndef HAVE_XDISPLAYCELLS
+int
+XDisplayCells (Display *dpy, int screen_number)
+{
+  return 1677216;
+}
+#endif
+
+#ifndef HAVE_XDESTROYSUBWINDOWS
+int
+XDestroySubwindows (Display *dpy, Window w)
+{
+  Window root, parent, *children;
+  unsigned int nchildren, i;
+
+  if (XQueryTree (dpy, w, &root, &parent, &children,
+                 &nchildren))
+    {
+      for (i = 0; i < nchildren; ++i)
+       XDestroyWindow (dpy, children[i]);
+      XFree (children);
+    }
+
+  return 0;
+}
+#endif
+
 void
 syms_of_xfns (void)
 {
@@ -8878,6 +9147,8 @@ eliminated in future versions of Emacs.  */);
   defsubr (&Sx_select_font);
 #endif
 
+  defsubr (&Sx_internal_focus_input_context);
+
 #ifdef USE_CAIRO
   defsubr (&Sx_export_frames);
 #ifdef USE_GTK
diff --git a/src/xfont.c b/src/xfont.c
index b5765cfa7b..684c28ab21 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -1003,6 +1003,32 @@ xfont_draw (struct glyph_string *s, int from, int to, 
int x, int y,
       unblock_input ();
     }
 
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+  if (with_background
+      && FRAME_DISPLAY_INFO (s->f)->alpha_bits
+      && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
+    {
+      x_xr_ensure_picture (s->f);
+
+      if (FRAME_X_PICTURE (s->f) != None)
+       {
+         XRenderColor xc;
+         int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
+
+         x_xr_apply_ext_clip (s->f, gc);
+         x_xrender_color_from_gc_background (s->f, gc, &xc,
+                                             s->hl != DRAW_CURSOR);
+         XRenderFillRectangle (FRAME_X_DISPLAY (s->f),
+                               PictOpSrc, FRAME_X_PICTURE (s->f),
+                               &xc, x, y - ascent, s->width, height);
+         x_xr_reset_ext_clip (s->f);
+         x_mark_frame_dirty (s->f);
+
+         with_background = false;
+       }
+    }
+#endif
+
   if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
     {
       USE_SAFE_ALLOCA;
diff --git a/src/xftfont.c b/src/xftfont.c
index c2175d9614..6a2b2086df 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -33,6 +33,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "ftfont.h"
 #include "pdumper.h"
 
+#ifdef HAVE_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+
 #ifndef FC_LCD_FILTER
 /* Older fontconfig versions don't have FC_LCD_FILTER.  */
 # define FC_LCD_FILTER "lcdfilter"
@@ -496,7 +500,40 @@ xftfont_draw (struct glyph_string *s, int from, int to, 
int x, int y,
        height = ascent =
          s->first_glyph->slice.glyphless.lower_yoff
          - s->first_glyph->slice.glyphless.upper_yoff;
-      XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
+
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+      if (with_background
+         && FRAME_DISPLAY_INFO (s->f)->alpha_bits
+         && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
+       {
+         x_xr_ensure_picture (s->f);
+
+         if (FRAME_X_PICTURE (s->f) != None)
+           {
+             XRenderColor xc;
+             int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
+
+             if (s->num_clips > 0)
+               XRenderSetPictureClipRectangles (FRAME_X_DISPLAY (s->f),
+                                                FRAME_X_PICTURE (s->f),
+                                                0, 0, s->clip, s->num_clips);
+             else
+               x_xr_reset_ext_clip (f);
+             x_xrender_color_from_gc_background (s->f, s->gc, &xc, s->hl != 
DRAW_CURSOR);
+             XRenderFillRectangle (FRAME_X_DISPLAY (s->f),
+                                   PictOpSrc, FRAME_X_PICTURE (s->f),
+                                   &xc, x, y - ascent, s->width, height);
+             x_xr_reset_ext_clip (f);
+             x_mark_frame_dirty (s->f);
+
+             with_background = false;
+           }
+         else
+           XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
+       }
+      else
+#endif
+       XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
     }
   code = alloca (sizeof (FT_UInt) * len);
   for (i = 0; i < len; i++)
diff --git a/src/xselect.c b/src/xselect.c
index cfe028a169..f2a64dd953 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -52,7 +52,7 @@ static void unexpect_property_change (struct prop_location *);
 static void wait_for_property_change (struct prop_location *);
 static Lisp_Object x_get_window_property_as_lisp_data (struct x_display_info *,
                                                        Window, Atom,
-                                                       Lisp_Object, Atom);
+                                                       Lisp_Object, Atom, 
bool);
 static Lisp_Object selection_data_to_lisp_data (struct x_display_info *,
                                                const unsigned char *,
                                                ptrdiff_t, Atom, int);
@@ -795,11 +795,12 @@ x_handle_selection_request (struct selection_input_event 
*event)
       Window requestor = SELECTION_EVENT_REQUESTOR (event);
       Lisp_Object multprop;
       ptrdiff_t j, nselections;
+      struct selection_data cs;
 
       if (property == None) goto DONE;
       multprop
        = x_get_window_property_as_lisp_data (dpyinfo, requestor, property,
-                                             QMULTIPLE, selection);
+                                             QMULTIPLE, selection, true);
 
       if (!VECTORP (multprop) || ASIZE (multprop) % 2)
        goto DONE;
@@ -811,11 +812,19 @@ x_handle_selection_request (struct selection_input_event 
*event)
          Lisp_Object subtarget = AREF (multprop, 2*j);
          Atom subproperty = symbol_to_x_atom (dpyinfo,
                                               AREF (multprop, 2*j+1));
+         bool subsuccess = false;
 
          if (subproperty != None)
-           x_convert_selection (selection_symbol, subtarget,
-                                subproperty, true, dpyinfo);
+           subsuccess = x_convert_selection (selection_symbol, subtarget,
+                                             subproperty, true, dpyinfo);
+         if (!subsuccess)
+           ASET (multprop, 2*j+1, Qnil);
        }
+      /* Save conversion results */
+      lisp_data_to_selection_data (dpyinfo, multprop, &cs);
+      XChangeProperty (dpyinfo->display, requestor, property,
+                      cs.type, cs.format, PropModeReplace,
+                      cs.data, cs.size);
       success = true;
     }
   else
@@ -1210,7 +1219,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, 
Lisp_Object target_type,
   return
     x_get_window_property_as_lisp_data (dpyinfo, requestor_window,
                                        target_property, target_type,
-                                       selection_atom);
+                                       selection_atom, false);
 }
 
 /* Subroutines of x_get_window_property_as_lisp_data */
@@ -1461,7 +1470,8 @@ static Lisp_Object
 x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo,
                                    Window window, Atom property,
                                    Lisp_Object target_type,
-                                   Atom selection_atom)
+                                   Atom selection_atom,
+                                   bool for_multiple)
 {
   Atom actual_type;
   int actual_format;
@@ -1477,6 +1487,8 @@ x_get_window_property_as_lisp_data (struct x_display_info 
*dpyinfo,
                         &actual_type, &actual_format, &actual_size);
   if (! data)
     {
+      if (for_multiple)
+       return Qnil;
       block_input ();
       bool there_is_a_selection_owner
        = XGetSelectionOwner (display, selection_atom) != 0;
@@ -1499,7 +1511,7 @@ x_get_window_property_as_lisp_data (struct x_display_info 
*dpyinfo,
        }
     }
 
-  if (actual_type == dpyinfo->Xatom_INCR)
+  if (!for_multiple && actual_type == dpyinfo->Xatom_INCR)
     {
       /* That wasn't really the data, just the beginning.  */
 
@@ -1515,11 +1527,14 @@ x_get_window_property_as_lisp_data (struct 
x_display_info *dpyinfo,
                                     &actual_size);
     }
 
-  block_input ();
-  TRACE1 ("  Delete property %s", XGetAtomName (display, property));
-  XDeleteProperty (display, window, property);
-  XFlush (display);
-  unblock_input ();
+  if (!for_multiple)
+    {
+      block_input ();
+      TRACE1 ("  Delete property %s", XGetAtomName (display, property));
+      XDeleteProperty (display, window, property);
+      XFlush (display);
+      unblock_input ();
+    }
 
   /* It's been read.  Now convert it to a lisp object in some semi-rational
      manner.  */
diff --git a/src/xterm.c b/src/xterm.c
index 3f277c5b87..167e3a44d2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -122,6 +122,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <X11/extensions/Xrandr.h>
 #endif
 
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
 /* Load sys/types.h if not already loaded.
    In some systems loading it twice is suicidal.  */
 #ifndef makedev
@@ -341,6 +345,7 @@ static void x_wm_set_icon_pixmap (struct frame *, 
ptrdiff_t);
 static void x_initialize (void);
 
 static bool x_get_current_wm_state (struct frame *, Window, int *, bool *);
+static void x_update_opaque_region (struct frame *);
 
 /* Flush display of frame F.  */
 
@@ -361,6 +366,7 @@ x_flush (struct frame *f)
 static void
 x_drop_xrender_surfaces (struct frame *f)
 {
+  x_update_opaque_region (f);
   font_drop_xrender_surfaces (f);
 
 #ifdef HAVE_XRENDER
@@ -375,18 +381,18 @@ x_drop_xrender_surfaces (struct frame *f)
 }
 
 #ifdef HAVE_XRENDER
-MAYBE_UNUSED static void
+void
 x_xr_ensure_picture (struct frame *f)
 {
   if (FRAME_X_PICTURE (f) == None && FRAME_X_PICTURE_FORMAT (f))
     {
       XRenderPictureAttributes attrs;
       attrs.clip_mask = None;
+      XRenderPictFormat *fmt = FRAME_X_PICTURE_FORMAT (f);
 
       FRAME_X_PICTURE (f) = XRenderCreatePicture (FRAME_X_DISPLAY (f),
                                                  FRAME_X_RAW_DRAWABLE (f),
-                                                 FRAME_X_PICTURE_FORMAT (f),
-                                                 CPClipMask, &attrs);
+                                                 fmt, CPClipMask, &attrs);
     }
 }
 #endif
@@ -433,6 +439,18 @@ record_event (char *locus, int type)
 
 #endif
 
+static void
+x_update_opaque_region (struct frame *f)
+{
+  if (f->alpha_background < 1.0)
+    XChangeProperty (FRAME_X_DISPLAY (f),
+                    FRAME_X_WINDOW (f),
+                    FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
+                    XA_CARDINAL, 32, PropModeReplace,
+                    NULL, 0);
+}
+
+
 #if defined USE_CAIRO || defined HAVE_XRENDER
 static struct x_gc_ext_data *
 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
@@ -874,12 +892,27 @@ x_set_cr_source_with_gc_background (struct frame *f, GC 
gc)
 {
   XGCValues xgcv;
   XColor color;
+  unsigned int depth;
 
   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
   color.pixel = xgcv.background;
+
   x_query_colors (f, &color, 1);
-  cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
-                       color.green / 65535.0, color.blue / 65535.0);
+
+  depth = FRAME_DISPLAY_INFO (f)->n_planes;
+
+  if (f->alpha_background < 1.0 && depth == 32)
+    {
+      cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
+                            color.green / 65535.0, color.blue / 65535.0,
+                            f->alpha_background);
+
+      cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
+    }
+  else
+    cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
+                          color.green / 65535.0, color.blue / 65535.0);
+
 }
 
 static const cairo_user_data_key_t xlib_surface_key, saved_drawable_key;
@@ -1218,8 +1251,8 @@ x_cr_export_frames (Lisp_Object frames, 
cairo_surface_type_t surface_type)
 
 #endif /* USE_CAIRO */
 
-#if defined HAVE_XRENDER && !defined USE_CAIRO
-MAYBE_UNUSED static void
+#if defined HAVE_XRENDER
+void
 x_xr_apply_ext_clip (struct frame *f, GC gc)
 {
   eassert (FRAME_X_PICTURE (f) != None);
@@ -1233,7 +1266,7 @@ x_xr_apply_ext_clip (struct frame *f, GC gc)
                                     data->n_clip_rects);
 }
 
-MAYBE_UNUSED static void
+void
 x_xr_reset_ext_clip (struct frame *f)
 {
   XRenderPictureAttributes attrs = { .clip_mask = None };
@@ -1275,7 +1308,8 @@ x_reset_clip_rectangles (struct frame *f, GC gc)
 }
 
 static void
-x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
+x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
+                 bool respect_alpha_background)
 {
 #ifdef USE_CAIRO
   Display *dpy = FRAME_X_DISPLAY (f);
@@ -1313,11 +1347,82 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, 
int width, int height)
     }
   x_end_cr_clip (f);
 #else
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+  if (respect_alpha_background
+      && FRAME_DISPLAY_INFO (f)->alpha_bits
+      && FRAME_CHECK_XR_VERSION (f, 0, 2))
+    {
+      x_xr_ensure_picture (f);
+
+      if (FRAME_X_PICTURE (f) != None)
+       {
+         XRenderColor xc;
+
+         x_xr_apply_ext_clip (f, gc);
+         x_xrender_color_from_gc_foreground (f, gc, &xc, true);
+         XRenderFillRectangle (FRAME_X_DISPLAY (f),
+                               PictOpSrc, FRAME_X_PICTURE (f),
+                               &xc, x, y, width, height);
+         x_xr_reset_ext_clip (f);
+         x_mark_frame_dirty (f);
+
+         return;
+       }
+    }
+#endif
   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
                  gc, x, y, width, height);
 #endif
 }
 
+
+static void
+x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
+                  bool respect_alpha_background)
+{
+#ifdef USE_CAIRO
+  cairo_t *cr;
+
+  cr = x_begin_cr_clip (f, gc);
+  x_set_cr_source_with_gc_background (f, gc);
+  cairo_rectangle (cr, x, y, width, height);
+  cairo_fill (cr);
+  x_end_cr_clip (f);
+#else
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+  if (respect_alpha_background
+      && FRAME_DISPLAY_INFO (f)->alpha_bits
+      && FRAME_CHECK_XR_VERSION (f, 0, 2))
+    {
+      x_xr_ensure_picture (f);
+
+      if (FRAME_X_PICTURE (f) != None)
+       {
+         XRenderColor xc;
+
+         x_xr_apply_ext_clip (f, gc);
+         x_xrender_color_from_gc_background (f, gc, &xc, true);
+         XRenderFillRectangle (FRAME_X_DISPLAY (f),
+                               PictOpSrc, FRAME_X_PICTURE (f),
+                               &xc, x, y, width, height);
+         x_xr_reset_ext_clip (f);
+         x_mark_frame_dirty (f);
+
+         return;
+       }
+    }
+#endif
+
+  XGCValues xgcv;
+  Display *dpy = FRAME_X_DISPLAY (f);
+  XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
+  XSetForeground (dpy, gc, xgcv.background);
+  XFillRectangle (dpy, FRAME_X_DRAWABLE (f),
+                 gc, x, y, width, height);
+  XSetForeground (dpy, gc, xgcv.foreground);
+#endif
+}
+
 static void
 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
 {
@@ -1348,7 +1453,7 @@ x_clear_window (struct frame *f)
   x_end_cr_clip (f);
 #else
 #ifndef USE_GTK
-  if (FRAME_X_DOUBLE_BUFFERED_P (f))
+  if (FRAME_X_DOUBLE_BUFFERED_P (f) || (f->alpha_background != 1.0))
 #endif
     x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 #ifndef USE_GTK
@@ -1606,7 +1711,7 @@ x_draw_vertical_window_border (struct window *w, int x, 
int y0, int y1)
                    face->foreground);
 
 #ifdef USE_CAIRO
-  x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
+  x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0, false);
 #else
   XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
             f->output_data.x->normal_gc, x, y0, x, y1);
@@ -1639,13 +1744,13 @@ x_draw_window_divider (struct window *w, int x0, int 
x1, int y0, int y1)
     {
       XSetForeground (display, f->output_data.x->normal_gc, color_first);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x0, y0, 1, y1 - y0);
+                       x0, y0, 1, y1 - y0, false);
       XSetForeground (display, f->output_data.x->normal_gc, color);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+                       x0 + 1, y0, x1 - x0 - 2, y1 - y0, false);
       XSetForeground (display, f->output_data.x->normal_gc, color_last);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x1 - 1, y0, 1, y1 - y0);
+                       x1 - 1, y0, 1, y1 - y0, false);
     }
   else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
     /* A horizontal divider, at least three pixels high: Draw first and
@@ -1653,13 +1758,13 @@ x_draw_window_divider (struct window *w, int x0, int 
x1, int y0, int y1)
     {
       XSetForeground (display, f->output_data.x->normal_gc, color_first);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x0, y0, x1 - x0, 1);
+                       x0, y0, x1 - x0, 1, false);
       XSetForeground (display, f->output_data.x->normal_gc, color);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+                       x0, y0 + 1, x1 - x0, y1 - y0 - 2, false);
       XSetForeground (display, f->output_data.x->normal_gc, color_last);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x0, y1 - 1, x1 - x0, 1);
+                       x0, y1 - 1, x1 - x0, 1, false);
     }
   else
     {
@@ -1667,7 +1772,7 @@ x_draw_window_divider (struct window *w, int x0, int x1, 
int y0, int y1)
        differently.  */
       XSetForeground (display, f->output_data.x->normal_gc, color);
       x_fill_rectangle (f, f->output_data.x->normal_gc,
-                       x0, y0, x1 - x0, y1 - y0);
+                       x0, y0, x1 - x0, y1 - y0, false);
     }
 }
 
@@ -1748,6 +1853,37 @@ XTframe_up_to_date (struct frame *f)
   FRAME_MOUSE_UPDATE (f);
   if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
     show_back_buffer (f);
+
+#ifdef HAVE_XSYNC
+  if (FRAME_X_OUTPUT (f)->sync_end_pending_p
+      && FRAME_X_BASIC_COUNTER (f) != None)
+    {
+      XSyncSetCounter (FRAME_X_DISPLAY (f),
+                      FRAME_X_BASIC_COUNTER (f),
+                      FRAME_X_OUTPUT (f)->pending_basic_counter_value);
+      FRAME_X_OUTPUT (f)->sync_end_pending_p = false;
+    }
+
+  if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p
+      && FRAME_X_EXTENDED_COUNTER (f) != None)
+    {
+      XSyncValue add;
+      Bool overflow_p;
+
+      XSyncIntToValue (&add, 1);
+      XSyncValueAdd (&FRAME_X_OUTPUT (f)->current_extended_counter_value,
+                    add, add, &overflow_p);
+
+      if (overflow_p)
+       emacs_abort ();
+
+      XSyncSetCounter (FRAME_X_DISPLAY (f),
+                      FRAME_X_EXTENDED_COUNTER (f),
+                      FRAME_X_OUTPUT (f)->current_extended_counter_value);
+
+      FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false;
+    }
+#endif
   unblock_input ();
 }
 
@@ -1792,10 +1928,10 @@ x_clear_under_internal_border (struct frame *f)
          GC gc = f->output_data.x->normal_gc;
 
          XSetForeground (display, gc, color);
-         x_fill_rectangle (f, gc, 0, margin, width, border);
-         x_fill_rectangle (f, gc, 0, 0, border, height);
-         x_fill_rectangle (f, gc, width - border, 0, border, height);
-         x_fill_rectangle (f, gc, 0, height - border, width, border);
+         x_fill_rectangle (f, gc, 0, margin, width, border, false);
+         x_fill_rectangle (f, gc, 0, 0, border, height, false);
+         x_fill_rectangle (f, gc, width - border, 0, border, height, false);
+         x_fill_rectangle (f, gc, 0, height - border, width, border, false);
          XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
        }
       else
@@ -1862,9 +1998,9 @@ x_after_update_window_line (struct window *w, struct 
glyph_row *desired_row)
            GC gc = f->output_data.x->normal_gc;
 
            XSetForeground (display, gc, color);
-           x_fill_rectangle (f, gc, 0, y, width, height);
+           x_fill_rectangle (f, gc, 0, y, width, height, true);
            x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
-                             width, height);
+                             width, height, true);
            XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
          }
        else
@@ -1898,9 +2034,10 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row 
*row, struct draw_fring
       if (face->stipple)
        XSetFillStyle (display, face->gc, FillOpaqueStippled);
       else
-       XSetForeground (display, face->gc, face->background);
+       XSetBackground (display, face->gc, face->background);
 
-      x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
+      x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
+                        true);
 
       if (!face->stipple)
        XSetForeground (display, face->gc, face->foreground);
@@ -1927,15 +2064,30 @@ x_draw_fringe_bitmap (struct window *w, struct 
glyph_row *row, struct draw_fring
     {
       Drawable drawable = FRAME_X_DRAWABLE (f);
       char *bits;
-      Pixmap pixmap, clipmask = (Pixmap) 0;
-      int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
+      Pixmap pixmap, clipmask = None;
+      int depth = FRAME_DISPLAY_INFO (f)->n_planes;
       XGCValues gcv;
+      unsigned long background = face->background;
+#ifdef HAVE_XRENDER
+      Picture picture = None;
+      XRenderPictureAttributes attrs;
+
+      memset (&attrs, 0, sizeof attrs);
+#endif
 
       if (p->wd > 8)
        bits = (char *) (p->bits + p->dh);
       else
        bits = (char *) p->bits + p->dh;
 
+      if (FRAME_DISPLAY_INFO (f)->alpha_bits)
+       {
+         background = (background & ~FRAME_DISPLAY_INFO (f)->alpha_mask);
+         background |= (((unsigned long) (f->alpha_background * 0xffff)
+                         >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
+                        << FRAME_DISPLAY_INFO (f)->alpha_offset);
+       }
+
       /* Draw the bitmap.  I believe these small pixmaps can be cached
         by the server.  */
       pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, 
p->h,
@@ -1943,7 +2095,15 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row 
*row, struct draw_fring
                                             ? (p->overlay_p ? face->background
                                                : 
f->output_data.x->cursor_pixel)
                                             : face->foreground),
-                                           face->background, depth);
+                                           background, depth);
+
+#ifdef HAVE_XRENDER
+      if (FRAME_X_PICTURE_FORMAT (f)
+         && (x_xr_ensure_picture (f), FRAME_X_PICTURE (f)))
+       picture = XRenderCreatePicture (display, pixmap,
+                                       FRAME_X_PICTURE_FORMAT (f),
+                                       0, &attrs);
+#endif
 
       if (p->overlay_p)
        {
@@ -1951,14 +2111,43 @@ x_draw_fringe_bitmap (struct window *w, struct 
glyph_row *row, struct draw_fring
                                                  FRAME_DISPLAY_INFO 
(f)->root_window,
                                                  bits, p->wd, p->h,
                                                  1, 0, 1);
-         gcv.clip_mask = clipmask;
-         gcv.clip_x_origin = p->x;
-         gcv.clip_y_origin = p->y;
-         XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, 
&gcv);
+
+#ifdef HAVE_XRENDER
+         if (picture != None)
+           {
+             attrs.clip_mask = clipmask;
+             attrs.clip_x_origin = p->x;
+             attrs.clip_y_origin = p->y;
+
+             XRenderChangePicture (display, FRAME_X_PICTURE (f),
+                                   CPClipMask | CPClipXOrigin | CPClipYOrigin,
+                                   &attrs);
+           }
+         else
+#endif
+           {
+             gcv.clip_mask = clipmask;
+             gcv.clip_x_origin = p->x;
+             gcv.clip_y_origin = p->y;
+             XChangeGC (display, gc, GCClipMask | GCClipXOrigin | 
GCClipYOrigin, &gcv);
+           }
        }
 
-      XCopyArea (display, pixmap, drawable, gc, 0, 0,
-                p->wd, p->h, p->x, p->y);
+#ifdef HAVE_XRENDER
+      if (picture != None)
+       {
+         x_xr_apply_ext_clip (f, gc);
+         XRenderComposite (display, PictOpSrc, picture,
+                           None, FRAME_X_PICTURE (f),
+                           0, 0, 0, 0, p->x, p->y, p->wd, p->h);
+         x_xr_reset_ext_clip (f);
+
+         XRenderFreePicture (display, picture);
+       }
+      else
+#endif
+       XCopyArea (display, pixmap, drawable, gc, 0, 0,
+                  p->wd, p->h, p->x, p->y);
       XFreePixmap (display, pixmap);
 
       if (p->overlay_p)
@@ -2201,12 +2390,9 @@ x_compute_glyph_string_overhangs (struct glyph_string *s)
 static void
 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
 {
-  Display *display = FRAME_X_DISPLAY (s->f);
-  XGCValues xgcv;
-  XGetGCValues (display, s->gc, GCForeground | GCBackground, &xgcv);
-  XSetForeground (display, s->gc, xgcv.background);
-  x_fill_rectangle (s->f, s->gc, x, y, w, h);
-  XSetForeground (display, s->gc, xgcv.foreground);
+  x_clear_rectangle (s->f, s->gc, x, y, w, h,
+                    (s->first_glyph->type != STRETCH_GLYPH
+                     || s->hl != DRAW_CURSOR));
 }
 
 
@@ -2232,9 +2418,10 @@ x_draw_glyph_string_background (struct glyph_string *s, 
bool force_p)
          /* Fill background with a stipple pattern.  */
          XSetFillStyle (display, s->gc, FillOpaqueStippled);
          x_fill_rectangle (s->f, s->gc, s->x,
-                         s->y + box_line_width,
-                         s->background_width,
-                         s->height - 2 * box_line_width);
+                           s->y + box_line_width,
+                           s->background_width,
+                           s->height - 2 * box_line_width,
+                           false);
          XSetFillStyle (display, s->gc, FillSolid);
          s->background_filled_p = true;
        }
@@ -2329,7 +2516,8 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
                  x_fill_rectangle (s->f, s->gc, s->x,
                                    s->y + box_line_width,
                                    s->background_width,
-                                   s->height - 2 * box_line_width);
+                                   s->height - 2 * box_line_width,
+                                   false);
                  XSetFillStyle (display, s->gc, FillSolid);
                }
              else
@@ -2779,12 +2967,12 @@ void
 x_query_colors (struct frame *f, XColor *colors, int ncolors)
 {
   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+  int i;
 
   if (dpyinfo->red_bits > 0)
     {
       /* For TrueColor displays, we can decompose the RGB value
         directly.  */
-      int i;
       unsigned int rmult, gmult, bmult;
       unsigned int rmask, gmask, bmask;
 
@@ -2840,12 +3028,23 @@ x_query_colors (struct frame *f, XColor *colors, int 
ncolors)
   XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
 }
 
-/* Store F's background color into *BGCOLOR.  */
+/* Store F's real background color into *BGCOLOR.  */
 
 static void
 x_query_frame_background_color (struct frame *f, XColor *bgcolor)
 {
-  bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
+  unsigned long background = FRAME_BACKGROUND_PIXEL (f);
+
+  if (FRAME_DISPLAY_INFO (f)->alpha_bits)
+    {
+      background = (background & ~FRAME_DISPLAY_INFO (f)->alpha_mask);
+      background |= (((unsigned long) (f->alpha_background * 0xffff)
+                     >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
+                    << FRAME_DISPLAY_INFO (f)->alpha_offset);
+    }
+
+  bgcolor->pixel = background;
+
   x_query_colors (f, bgcolor, 1);
 }
 
@@ -2919,34 +3118,55 @@ x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, 
XColor *color)
   if (rc == 0)
     {
       /* If we got to this point, the colormap is full, so we're going
-        to try to get the next closest color.  The algorithm used is
+        to try and get the next closest color.  The algorithm used is
         a least-squares matching, which is what X uses for closest
         color matching with StaticColor visuals.  */
-      int nearest, i;
-      int max_color_delta = 255;
-      int max_delta = 3 * max_color_delta;
-      int nearest_delta = max_delta + 1;
-      int ncells;
-      const XColor *cells = x_color_cells (dpy, &ncells);
-
-      for (nearest = i = 0; i < ncells; ++i)
-       {
-         int dred   = (color->red   >> 8) - (cells[i].red   >> 8);
-         int dgreen = (color->green >> 8) - (cells[i].green >> 8);
-         int dblue  = (color->blue  >> 8) - (cells[i].blue  >> 8);
-         int delta = dred * dred + dgreen * dgreen + dblue * dblue;
 
-         if (delta < nearest_delta)
+      const XColor *cells;
+      int no_cells;
+      int nearest;
+      long nearest_delta, trial_delta;
+      int x;
+      Status status;
+
+      cells = x_color_cells (dpy, &no_cells);
+
+      nearest = 0;
+      /* I'm assuming CSE so I'm not going to condense this. */
+      nearest_delta = ((((color->red >> 8) - (cells[0].red >> 8))
+                       * ((color->red >> 8) - (cells[0].red >> 8)))
+                      + (((color->green >> 8) - (cells[0].green >> 8))
+                         * ((color->green >> 8) - (cells[0].green >> 8)))
+                      + (((color->blue >> 8) - (cells[0].blue >> 8))
+                         * ((color->blue >> 8) - (cells[0].blue >> 8))));
+      for (x = 1; x < no_cells; x++)
+       {
+         trial_delta = ((((color->red >> 8) - (cells[x].red >> 8))
+                         * ((color->red >> 8) - (cells[x].red >> 8)))
+                        + (((color->green >> 8) - (cells[x].green >> 8))
+                           * ((color->green >> 8) - (cells[x].green >> 8)))
+                        + (((color->blue >> 8) - (cells[x].blue >> 8))
+                           * ((color->blue >> 8) - (cells[x].blue >> 8))));
+         if (trial_delta < nearest_delta)
            {
-             nearest = i;
-             nearest_delta = delta;
+             XColor temp;
+             temp.red = cells[x].red;
+             temp.green = cells[x].green;
+             temp.blue = cells[x].blue;
+             status = XAllocColor (dpy, cmap, &temp);
+             if (status)
+               {
+                 nearest = x;
+                 nearest_delta = trial_delta;
+               }
            }
        }
-
-      color->red   = cells[nearest].red;
+      color->red = cells[nearest].red;
       color->green = cells[nearest].green;
-      color->blue  = cells[nearest].blue;
-      rc = XAllocColor (dpy, cmap, color) != 0;
+      color->blue = cells[nearest].blue;
+      status = XAllocColor (dpy, cmap, color);
+
+      rc = status != 0;
     }
   else
     {
@@ -2991,7 +3211,9 @@ x_alloc_nearest_color (struct frame *f, Colormap cmap, 
XColor *color)
 
   gamma_correct (f, color);
 
-  if (dpyinfo->red_bits > 0)
+  if (dpyinfo->red_bits > 0
+      && (dpyinfo->n_planes != 32
+         || dpyinfo->alpha_bits > 0))
     {
       color->pixel = x_make_truecolor_pixel (dpyinfo,
                                             color->red,
@@ -3245,7 +3467,7 @@ x_draw_relief_rect (struct frame *f,
   if (left_p)
     {
       x_fill_rectangle (f, top_left_gc, left_x, top_y,
-                       vwidth, bottom_y + 1 - top_y);
+                       vwidth, bottom_y + 1 - top_y, false);
       if (top_p)
        corners |= 1 << CORNER_TOP_LEFT;
       if (bot_p)
@@ -3254,7 +3476,7 @@ x_draw_relief_rect (struct frame *f,
   if (right_p)
     {
       x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
-                       vwidth, bottom_y + 1 - top_y);
+                       vwidth, bottom_y + 1 - top_y, false);
       if (top_p)
        corners |= 1 << CORNER_TOP_RIGHT;
       if (bot_p)
@@ -3264,7 +3486,7 @@ x_draw_relief_rect (struct frame *f,
     {
       if (!right_p)
        x_fill_rectangle (f, top_left_gc, left_x, top_y,
-                         right_x + 1 - left_x, hwidth);
+                         right_x + 1 - left_x, hwidth, false);
       else
        x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
                                     right_x + 1 - left_x, hwidth, 1);
@@ -3273,7 +3495,7 @@ x_draw_relief_rect (struct frame *f,
     {
       if (!left_p)
        x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
-                         right_x + 1 - left_x, hwidth);
+                         right_x + 1 - left_x, hwidth, false);
       else
        x_fill_trapezoid_for_relief (f, bottom_right_gc,
                                     left_x, bottom_y + 1 - hwidth,
@@ -3281,10 +3503,10 @@ x_draw_relief_rect (struct frame *f,
     }
   if (left_p && vwidth > 1)
     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
-                     1, bottom_y + 1 - top_y);
+                     1, bottom_y + 1 - top_y, false);
   if (top_p && hwidth > 1)
     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
-                     right_x + 1 - left_x, 1);
+                     right_x + 1 - left_x, 1, false);
   if (corners)
     {
       XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
@@ -3406,21 +3628,25 @@ x_draw_box_rect (struct glyph_string *s,
 
   /* Top.  */
   x_fill_rectangle (s->f, s->gc,
-                 left_x, top_y, right_x - left_x + 1, hwidth);
+                   left_x, top_y, right_x - left_x + 1, hwidth,
+                   false);
 
   /* Left.  */
   if (left_p)
     x_fill_rectangle (s->f, s->gc,
-                   left_x, top_y, vwidth, bottom_y - top_y + 1);
+                     left_x, top_y, vwidth, bottom_y - top_y + 1,
+                     false);
 
   /* Bottom.  */
   x_fill_rectangle (s->f, s->gc,
-                 left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
+                   left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth,
+                   false);
 
   /* Right.  */
   if (right_p)
     x_fill_rectangle (s->f, s->gc,
-                   right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
+                     right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1,
+                     false);
 
   XSetForeground (display, s->gc, xgcv.foreground);
   x_reset_clip_rectangles (s->f, s->gc);
@@ -3835,7 +4061,7 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int 
x, int y, int w, int h)
 
       /* Fill background with a stipple pattern.  */
       XSetFillStyle (display, s->gc, FillOpaqueStippled);
-      x_fill_rectangle (s->f, s->gc, x, y, w, h);
+      x_fill_rectangle (s->f, s->gc, x, y, w, h, false);
       XSetFillStyle (display, s->gc, FillSolid);
     }
   else
@@ -3891,8 +4117,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
          /* Create a pixmap as large as the glyph string.  Fill it
             with the background color.  Copy the image to it, using
             its mask.  Copy the temporary pixmap to the display.  */
-         Screen *screen = FRAME_X_SCREEN (s->f);
-         int depth = DefaultDepthOfScreen (screen);
+         int depth = FRAME_DISPLAY_INFO (s->f)->n_planes;
 
          /* Create a pixmap as large as the glyph string.  */
           pixmap = XCreatePixmap (display, FRAME_X_DRAWABLE (s->f),
@@ -3917,12 +4142,34 @@ x_draw_image_glyph_string (struct glyph_string *s)
          else
            {
              XGCValues xgcv;
-             XGetGCValues (display, s->gc, GCForeground | GCBackground,
-                           &xgcv);
-             XSetForeground (display, s->gc, xgcv.background);
-             XFillRectangle (display, pixmap, s->gc,
-                             0, 0, s->background_width, s->height);
-             XSetForeground (display, s->gc, xgcv.foreground);
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+             if (FRAME_DISPLAY_INFO (s->f)->alpha_bits
+                 && FRAME_CHECK_XR_VERSION (s->f, 0, 2)
+                 && FRAME_X_PICTURE_FORMAT (s->f))
+               {
+                 XRenderColor xc;
+                 XRenderPictureAttributes attrs;
+                 Picture pict;
+                 memset (&attrs, 0, sizeof attrs);
+
+                 pict = XRenderCreatePicture (display, pixmap,
+                                              FRAME_X_PICTURE_FORMAT (s->f),
+                                              0, &attrs);
+                 x_xrender_color_from_gc_background (s->f, s->gc, &xc, true);
+                 XRenderFillRectangle (FRAME_X_DISPLAY (s->f), PictOpSrc, pict,
+                                       &xc, 0, 0, s->background_width, 
s->height);
+                 XRenderFreePicture (display, pict);
+               }
+             else
+#endif
+               {
+                 XGetGCValues (display, s->gc, GCForeground | GCBackground,
+                               &xgcv);
+                 XSetForeground (display, s->gc, xgcv.background);
+                 XFillRectangle (display, pixmap, s->gc,
+                                 0, 0, s->background_width, s->height);
+                 XSetForeground (display, s->gc, xgcv.foreground);
+               }
            }
        }
       else
@@ -4041,7 +4288,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
            {
              /* Fill background with a stipple pattern.  */
              XSetFillStyle (display, gc, FillOpaqueStippled);
-             x_fill_rectangle (s->f, gc, x, y, w, h);
+             x_fill_rectangle (s->f, gc, x, y, w, h, true);
              XSetFillStyle (display, gc, FillSolid);
            }
          else
@@ -4049,7 +4296,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
              XGCValues xgcv;
              XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv);
              XSetForeground (display, gc, xgcv.background);
-             x_fill_rectangle (s->f, gc, x, y, w, h);
+             x_fill_rectangle (s->f, gc, x, y, w, h, true);
              XSetForeground (display, gc, xgcv.foreground);
            }
 
@@ -4399,7 +4646,8 @@ x_draw_glyph_string (struct glyph_string *s)
               y = s->ybase + position;
               if (s->face->underline_defaulted_p)
                 x_fill_rectangle (s->f, s->gc,
-                                 s->x, y, decoration_width, thickness);
+                                 s->x, y, decoration_width, thickness,
+                                 false);
               else
                 {
                   Display *display = FRAME_X_DISPLAY (s->f);
@@ -4407,7 +4655,8 @@ x_draw_glyph_string (struct glyph_string *s)
                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
                   XSetForeground (display, s->gc, s->face->underline_color);
                   x_fill_rectangle (s->f, s->gc,
-                                   s->x, y, decoration_width, thickness);
+                                   s->x, y, decoration_width, thickness,
+                                   false);
                   XSetForeground (display, s->gc, xgcv.foreground);
                 }
             }
@@ -4419,7 +4668,7 @@ x_draw_glyph_string (struct glyph_string *s)
 
          if (s->face->overline_color_defaulted_p)
            x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                             decoration_width, h);
+                             decoration_width, h, false);
          else
            {
               Display *display = FRAME_X_DISPLAY (s->f);
@@ -4427,7 +4676,7 @@ x_draw_glyph_string (struct glyph_string *s)
              XGetGCValues (display, s->gc, GCForeground, &xgcv);
              XSetForeground (display, s->gc, s->face->overline_color);
              x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
-                               decoration_width, h);
+                               decoration_width, h, false);
              XSetForeground (display, s->gc, xgcv.foreground);
            }
        }
@@ -4449,7 +4698,7 @@ x_draw_glyph_string (struct glyph_string *s)
 
          if (s->face->strike_through_color_defaulted_p)
            x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
-                           s->width, h);
+                             s->width, h, false);
          else
            {
               Display *display = FRAME_X_DISPLAY (s->f);
@@ -4457,7 +4706,7 @@ x_draw_glyph_string (struct glyph_string *s)
              XGetGCValues (display, s->gc, GCForeground, &xgcv);
              XSetForeground (display, s->gc, s->face->strike_through_color);
              x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
-                               decoration_width, h);
+                               decoration_width, h, false);
              XSetForeground (display, s->gc, xgcv.foreground);
            }
        }
@@ -4569,20 +4818,22 @@ x_clear_area (struct frame *f, int x, int y, int width, 
int height)
   x_end_cr_clip (f);
 #else
 #ifndef USE_GTK
-  if (FRAME_X_DOUBLE_BUFFERED_P (f))
+  if (FRAME_X_DOUBLE_BUFFERED_P (f)
+      || f->alpha_background != 1.0)
 #endif
     {
 #if defined HAVE_XRENDER && \
   (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
       x_xr_ensure_picture (f);
-      if (FRAME_X_PICTURE (f) != None
+      if (FRAME_DISPLAY_INFO (f)->alpha_bits
+         && FRAME_X_PICTURE (f) != None
          && FRAME_CHECK_XR_VERSION (f, 0, 2))
        {
          XRenderColor xc;
-         GC gc = f->output_data.x->reverse_gc;
+         GC gc = f->output_data.x->normal_gc;
 
          x_xr_apply_ext_clip (f, gc);
-         x_xrender_color_from_gc_foreground (f, gc, &xc);
+         x_xrender_color_from_gc_background (f, gc, &xc, true);
          XRenderFillRectangle (FRAME_X_DISPLAY (f),
                                PictOpSrc, FRAME_X_PICTURE (f),
                                &xc, x, y, width, height);
@@ -5175,10 +5426,13 @@ x_focus_changed (int type, int state, struct 
x_display_info *dpyinfo, struct fra
 #ifdef USE_GTK
       GtkWidget *widget;
 
-      gtk_im_context_focus_in (FRAME_X_OUTPUT (frame)->im_context);
-      widget = FRAME_GTK_OUTER_WIDGET (frame);
-      gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context,
-                                       gtk_widget_get_window (widget));
+      if (x_gtk_use_native_input)
+       {
+         gtk_im_context_focus_in (FRAME_X_OUTPUT (frame)->im_context);
+         widget = FRAME_GTK_OUTER_WIDGET (frame);
+         gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context,
+                                           gtk_widget_get_window (widget));
+       }
 #endif
 #endif
     }
@@ -5199,8 +5453,11 @@ x_focus_changed (int type, int state, struct 
x_display_info *dpyinfo, struct fra
       if (FRAME_XIC (frame))
         XUnsetICFocus (FRAME_XIC (frame));
 #ifdef USE_GTK
-      gtk_im_context_focus_out (FRAME_X_OUTPUT (frame)->im_context);
-      gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context, 
NULL);
+      if (x_gtk_use_native_input)
+       {
+         gtk_im_context_focus_out (FRAME_X_OUTPUT (frame)->im_context);
+         gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context, 
NULL);
+       }
 #endif
 #endif
       if (frame->pointer_invisible)
@@ -5567,7 +5824,8 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
   dpyinfo->hyper_mod_mask = 0;
 
 #ifdef HAVE_XKB
-  if (dpyinfo->xkb_desc)
+  if (dpyinfo->xkb_desc
+      && dpyinfo->xkb_desc->server)
     {
       for (i = 0; i < XkbNumVirtualMods; i++)
        {
@@ -5609,6 +5867,14 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
   syms = XGetKeyboardMapping (dpyinfo->display,
                              min_code, max_code - min_code + 1,
                              &syms_per_code);
+
+  if (!syms)
+    {
+      dpyinfo->meta_mod_mask = Mod1Mask;
+      dpyinfo->super_mod_mask = Mod2Mask;
+      return;
+    }
+
   mods = XGetModifierMapping (dpyinfo->display);
 
   /* Scan the modifier table to see which modifier bits the Meta and
@@ -8840,6 +9106,47 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                goto done;
               }
 
+
+           if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_ping
+               && event->xclient.format == 32)
+             {
+               XEvent send_event = *event;
+
+               send_event.xclient.window = dpyinfo->root_window;
+               XSendEvent (dpyinfo->display, dpyinfo->root_window, False,
+                           SubstructureRedirectMask | SubstructureNotifyMask,
+                           &send_event);
+
+               *finish = X_EVENT_DROP;
+               goto done;
+             }
+
+#if defined HAVE_XSYNC && !defined HAVE_GTK3
+           if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request
+               && event->xclient.format == 32
+               && dpyinfo->xsync_supported_p)
+             {
+               struct frame *f
+                 = x_top_window_to_frame (dpyinfo,
+                                          event->xclient.window);
+
+               if (f)
+                 {
+                   if (event->xclient.data.l[4] == 0)
+                     {
+                       XSyncIntsToValue (&FRAME_X_OUTPUT 
(f)->pending_basic_counter_value,
+                                         event->xclient.data.l[2], 
event->xclient.data.l[3]);
+                       FRAME_X_OUTPUT (f)->sync_end_pending_p = true;
+                     }
+                   else if (event->xclient.data.l[4] == 1)
+                     FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = true;
+
+                   *finish = X_EVENT_DROP;
+                   goto done;
+                 }
+             }
+#endif
+
            goto done;
           }
 
@@ -9294,6 +9601,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              f->output_data.x->has_been_visible = true;
            }
 
+         x_update_opaque_region (f);
+
           if (not_hidden && iconified)
             {
               inev.ie.kind = DEICONIFY_EVENT;
@@ -12036,8 +12345,8 @@ x_draw_bar_cursor (struct window *w, struct glyph_row 
*row, int width, enum text
            x += cursor_glyph->pixel_width - width;
 
          x_fill_rectangle (f, gc, x,
-                         WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                         width, row->height);
+                           WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+                           width, row->height, false);
        }
       else /* HBAR_CURSOR */
        {
@@ -12058,7 +12367,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row 
*row, int width, enum text
          x_fill_rectangle (f, gc, x,
                            WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
                                                      row->height - width),
-                            w->phys_cursor_width - 1, width);
+                            w->phys_cursor_width - 1, width, false);
        }
 
       x_reset_clip_rectangles (f, gc);
@@ -14497,9 +14806,19 @@ x_free_frame_resources (struct frame *f)
 
       tear_down_x_back_buffer (f);
       if (FRAME_X_WINDOW (f))
-          XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 #endif /* !USE_X_TOOLKIT */
 
+#ifdef HAVE_XSYNC
+      if (FRAME_X_BASIC_COUNTER (f) != None)
+       XSyncDestroyCounter (FRAME_X_DISPLAY (f),
+                            FRAME_X_BASIC_COUNTER (f));
+
+      if (FRAME_X_EXTENDED_COUNTER (f) != None)
+       XSyncDestroyCounter (FRAME_X_DISPLAY (f),
+                            FRAME_X_EXTENDED_COUNTER (f));
+#endif
+
       unload_color (f, FRAME_FOREGROUND_PIXEL (f));
       unload_color (f, FRAME_BACKGROUND_PIXEL (f));
       unload_color (f, f->output_data.x->cursor_pixel);
@@ -15364,17 +15683,49 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
 
   reset_mouse_highlight (&dpyinfo->mouse_highlight);
 
-  /* See if we can construct pixel values from RGB values.  */
-  if (dpyinfo->visual->class == TrueColor)
+#ifdef HAVE_XRENDER
+  int event_base, error_base;
+  dpyinfo->xrender_supported_p
+    = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
+
+  if (dpyinfo->xrender_supported_p)
     {
-      get_bits_and_offset (dpyinfo->visual->red_mask,
-                           &dpyinfo->red_bits, &dpyinfo->red_offset);
-      get_bits_and_offset (dpyinfo->visual->blue_mask,
-                           &dpyinfo->blue_bits, &dpyinfo->blue_offset);
-      get_bits_and_offset (dpyinfo->visual->green_mask,
-                           &dpyinfo->green_bits, &dpyinfo->green_offset);
+      if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
+                               &dpyinfo->xrender_minor))
+       dpyinfo->xrender_supported_p = false;
+      else
+       dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
+                                                       dpyinfo->visual);
     }
+#endif
+
+#ifdef HAVE_XSYNC
+  int xsync_event_base, xsync_error_base;
+  dpyinfo->xsync_supported_p
+    = XSyncQueryExtension (dpyinfo->display,
+                          &xsync_event_base,
+                          &xsync_error_base);
+
+  if (dpyinfo->xsync_supported_p)
+    dpyinfo->xsync_supported_p = XSyncInitialize (dpyinfo->display,
+                                                 &dpyinfo->xsync_major,
+                                                 &dpyinfo->xsync_minor);
+
+  {
+    AUTO_STRING (synchronizeResize, "synchronizeResize");
+    AUTO_STRING (SynchronizeResize, "SynchronizeResize");
 
+    Lisp_Object value = gui_display_get_resource (dpyinfo,
+                                                 synchronizeResize,
+                                                 SynchronizeResize,
+                                                 Qnil, Qnil);
+
+    if (STRINGP (value) &&
+       (!strcmp (SSDATA (value), "false")
+        || !strcmp (SSDATA (value), "off")))
+      dpyinfo->xsync_supported_p = false;
+  }
+#endif
   /* See if a private colormap is requested.  */
   if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
     {
@@ -15395,6 +15746,52 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
     dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
                                      dpyinfo->visual, AllocNone);
 
+  /* See if we can construct pixel values from RGB values.  */
+  if (dpyinfo->visual->class == TrueColor)
+    {
+      get_bits_and_offset (dpyinfo->visual->red_mask,
+                           &dpyinfo->red_bits, &dpyinfo->red_offset);
+      get_bits_and_offset (dpyinfo->visual->blue_mask,
+                           &dpyinfo->blue_bits, &dpyinfo->blue_offset);
+      get_bits_and_offset (dpyinfo->visual->green_mask,
+                           &dpyinfo->green_bits, &dpyinfo->green_offset);
+
+#ifdef HAVE_XRENDER
+      if (dpyinfo->pict_format)
+       {
+         unsigned long channel_mask
+           = ((unsigned long) dpyinfo->pict_format->direct.alphaMask
+              << dpyinfo->pict_format->direct.alpha);
+
+         if (channel_mask)
+           get_bits_and_offset (channel_mask, &dpyinfo->alpha_bits,
+                                &dpyinfo->alpha_offset);
+         dpyinfo->alpha_mask = channel_mask;
+       }
+      else
+#endif
+       {
+         XColor xc;
+         unsigned long alpha_mask;
+         xc.red = 65535;
+         xc.green = 65535;
+         xc.blue = 65535;
+
+         if (XAllocColor (dpyinfo->display,
+                          dpyinfo->cmap, &xc) != 0)
+           {
+             alpha_mask = xc.pixel & ~(dpyinfo->visual->red_mask
+                                       | dpyinfo->visual->blue_mask
+                                       | dpyinfo->visual->green_mask);
+
+             if (alpha_mask)
+               get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits,
+                                    &dpyinfo->alpha_offset);
+             dpyinfo->alpha_mask = alpha_mask;
+           }
+       }
+    }
+
 #ifdef HAVE_XDBE
   dpyinfo->supports_xdbe = false;
   int xdbe_major;
@@ -15507,22 +15904,6 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
     }
 #endif
 
-#ifdef HAVE_XRENDER
-  int event_base, error_base;
-  dpyinfo->xrender_supported_p
-    = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
-
-  if (dpyinfo->xrender_supported_p)
-    {
-      if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
-                               &dpyinfo->xrender_minor))
-       dpyinfo->xrender_supported_p = false;
-      else
-       dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
-                                                       dpyinfo->visual);
-    }
-#endif
-
 #ifdef HAVE_XFIXES
   int xfixes_event_base, xfixes_error_base;
   dpyinfo->xfixes_supported_p
@@ -15604,6 +15985,7 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
       ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
       ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
       ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
+      ATOM_REFS_INIT ("XATOM_COUNTER", Xatom_XEMBED_INFO)
       ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
       /* For properties of font.  */
       ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
@@ -15638,6 +16020,9 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
       ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
       ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
       ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
+      ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
+      ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", 
Xatom_net_wm_sync_request_counter)
+      ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn)
       /* Session management */
       ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
       ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
@@ -15645,6 +16030,8 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
       ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", 
Xatom_net_wm_state_skip_taskbar)
       ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
       ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
+      ATOM_REFS_INIT ("_NET_WM_OPAQUE_REGION", Xatom_net_wm_opaque_region)
+      ATOM_REFS_INIT ("_NET_WM_PING", Xatom_net_wm_ping)
 #ifdef HAVE_XKB
       ATOM_REFS_INIT ("Meta", Xatom_Meta)
       ATOM_REFS_INIT ("Super", Xatom_Super)
@@ -16181,7 +16568,8 @@ init_xterm (void)
 
 #ifdef HAVE_XRENDER
 void
-x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor 
*color)
+x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor 
*color,
+                                   bool apply_alpha_background)
 {
   XGCValues xgcv;
   XColor xc;
@@ -16190,26 +16578,51 @@ x_xrender_color_from_gc_foreground (struct frame *f, 
GC gc, XRenderColor *color)
   xc.pixel = xgcv.foreground;
   x_query_colors (f, &xc, 1);
 
-  color->alpha = 65535;
-  color->red = xc.red;
-  color->blue = xc.blue;
-  color->green = xc.green;
+  color->alpha = (apply_alpha_background
+                 ? 65535 * f->alpha_background
+                 : 65535);
+
+  if (color->alpha == 65535)
+    {
+      color->red = xc.red;
+      color->blue = xc.blue;
+      color->green = xc.green;
+    }
+  else
+    {
+      color->red = (xc.red * color->alpha) / 65535;
+      color->blue = (xc.blue * color->alpha) / 65535;
+      color->green = (xc.green * color->alpha) / 65535;
+    }
 }
 
 void
-x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor 
*color)
+x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor 
*color,
+                                   bool apply_alpha_background)
 {
   XGCValues xgcv;
   XColor xc;
 
   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
-  xc.pixel = xgcv.foreground;
+  xc.pixel = xgcv.background;
   x_query_colors (f, &xc, 1);
 
-  color->alpha = 65535;
-  color->red = xc.red;
-  color->blue = xc.blue;
-  color->green = xc.green;
+  color->alpha = (apply_alpha_background
+                 ? 65535 * f->alpha_background
+                 : 65535);
+
+  if (color->alpha == 65535)
+    {
+      color->red = xc.red;
+      color->blue = xc.blue;
+      color->green = xc.green;
+    }
+  else
+    {
+      color->red = (xc.red * color->alpha) / 65535;
+      color->blue = (xc.blue * color->alpha) / 65535;
+      color->green = (xc.green * color->alpha) / 65535;
+    }
 }
 #endif
 
diff --git a/src/xterm.h b/src/xterm.h
index 33887be52b..d3678054a8 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -99,6 +99,10 @@ typedef GtkWidget *xt_or_gtk_widget;
 #include <X11/XKBlib.h>
 #endif
 
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
 #include "dispextern.h"
 #include "termhooks.h"
 
@@ -366,9 +370,9 @@ struct x_display_info
 
   /* More atoms, which are selection types.  */
   Atom Xatom_CLIPBOARD, Xatom_TIMESTAMP, Xatom_TEXT, Xatom_DELETE,
-  Xatom_COMPOUND_TEXT, Xatom_UTF8_STRING,
-  Xatom_MULTIPLE, Xatom_INCR, Xatom_EMACS_TMP, Xatom_TARGETS, Xatom_NULL,
-  Xatom_ATOM, Xatom_ATOM_PAIR, Xatom_CLIPBOARD_MANAGER;
+    Xatom_COMPOUND_TEXT, Xatom_UTF8_STRING,
+    Xatom_MULTIPLE, Xatom_INCR, Xatom_EMACS_TMP, Xatom_TARGETS, Xatom_NULL,
+    Xatom_ATOM, Xatom_ATOM_PAIR, Xatom_CLIPBOARD_MANAGER, Xatom_COUNTER;
 
   /* More atoms for font properties.  The last three are private
      properties, see the comments in src/fontset.h.  */
@@ -460,8 +464,9 @@ struct x_display_info
   int ncolor_cells;
 
   /* Bits and shifts to use to compose pixel values on TrueColor visuals.  */
-  int red_bits, blue_bits, green_bits;
-  int red_offset, blue_offset, green_offset;
+  int red_bits, blue_bits, green_bits, alpha_bits;
+  int red_offset, blue_offset, green_offset, alpha_offset;
+  unsigned long alpha_mask;
 
   /* The type of window manager we have.  If we move FRAME_OUTER_WINDOW
      to x/y 0/0, some window managers (type A) puts the window manager
@@ -496,7 +501,9 @@ struct x_display_info
     Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert,
     Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, 
Xatom_net_wm_state_below,
     Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar,
-    Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea;
+    Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea,
+    Xatom_net_wm_opaque_region, Xatom_net_wm_ping, Xatom_net_wm_sync_request,
+    Xatom_net_wm_sync_request_counter, Xatom_net_wm_frame_drawn;
 
   /* XSettings atoms and windows.  */
   Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
@@ -563,6 +570,12 @@ struct x_display_info
   int xfixes_major;
   int xfixes_minor;
 #endif
+
+#ifdef HAVE_XSYNC
+  bool xsync_supported_p;
+  int xsync_major;
+  int xsync_minor;
+#endif
 };
 
 #ifdef HAVE_X_I18N
@@ -799,6 +812,16 @@ struct x_output
   XFontSet xic_xfs;
 #endif
 
+#ifdef HAVE_XSYNC
+  XSyncCounter basic_frame_counter;
+  XSyncCounter extended_frame_counter;
+  XSyncValue pending_basic_counter_value;
+  XSyncValue current_extended_counter_value;
+
+  bool_bf sync_end_pending_p : 1;
+  bool_bf ext_sync_end_pending_p : 1;
+#endif
+
   /* Relief GCs, colors etc.  */
   struct relief
   {
@@ -961,6 +984,10 @@ extern void x_mark_frame_dirty (struct frame *f);
        || (FRAME_DISPLAY_INFO (f)->xrender_major > (major))))
 #endif
 
+#ifdef HAVE_XSYNC
+#define FRAME_X_BASIC_COUNTER(f) FRAME_X_OUTPUT (f)->basic_frame_counter
+#define FRAME_X_EXTENDED_COUNTER(f) FRAME_X_OUTPUT (f)->extended_frame_counter
+#endif
 
 /* This is the Colormap which frame F uses.  */
 #define FRAME_X_COLORMAP(f) FRAME_DISPLAY_INFO (f)->cmap
@@ -1242,8 +1269,13 @@ extern Lisp_Object x_cr_export_frames (Lisp_Object, 
cairo_surface_type_t);
 #endif
 
 #ifdef HAVE_XRENDER
-extern void x_xrender_color_from_gc_foreground (struct frame *, GC, 
XRenderColor *);
-extern void x_xrender_color_from_gc_background (struct frame *, GC, 
XRenderColor *);
+extern void x_xrender_color_from_gc_foreground (struct frame *, GC,
+                                               XRenderColor *, bool);
+extern void x_xrender_color_from_gc_background (struct frame *, GC,
+                                               XRenderColor *, bool);
+extern void x_xr_ensure_picture (struct frame *f);
+extern void x_xr_apply_ext_clip (struct frame *f, GC gc);
+extern void x_xr_reset_ext_clip (struct frame *f);
 #endif
 
 INLINE int
@@ -1270,7 +1302,7 @@ x_display_set_last_user_time (struct x_display_info 
*dpyinfo, Time t)
 INLINE unsigned long
 x_make_truecolor_pixel (struct x_display_info *dpyinfo, int r, int g, int b)
 {
-  unsigned long pr, pg, pb;
+  unsigned long pr, pg, pb, pa = 0;
 
   /* Scale down RGB values to the visual's bits per RGB, and shift
      them to the right position in the pixel color.  Note that the
@@ -1279,8 +1311,14 @@ x_make_truecolor_pixel (struct x_display_info *dpyinfo, 
int r, int g, int b)
   pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
   pb = (b >> (16 - dpyinfo->blue_bits))  << dpyinfo->blue_offset;
 
+  if (dpyinfo->alpha_bits)
+    pa = (((unsigned long) 0xffff >> (16 - dpyinfo->alpha_bits))
+         << dpyinfo->alpha_offset);
+  else
+    pa = 0;
+
   /* Assemble the pixel color.  */
-  return pr | pg | pb;
+  return pr | pg | pb | pa;
 }
 
 /* If display has an immutable color map, freeing colors is not
diff --git a/src/xwidget.c b/src/xwidget.c
index 85535a35b1..fc6ba2c633 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -265,10 +265,12 @@ xw_translate_x_modifiers (struct x_display_info *dpyinfo,
 
 static bool xw_maybe_synthesize_crossing (struct xwidget_view *,
                                          GdkWindow *, int, int, int,
-                                         Time, unsigned int);
+                                         Time, unsigned int,
+                                         GdkCrossingMode, GdkCrossingMode);
 static void xw_notify_virtual_upwards_until (struct xwidget_view *, GdkWindow 
*,
                                             GdkWindow *, GdkWindow *, unsigned 
int,
-                                            int, int, Time, GdkEventType, 
bool);
+                                            int, int, Time, GdkEventType, bool,
+                                            GdkCrossingMode);
 static void window_coords_from_toplevel (GdkWindow *, GdkWindow *, int,
                                         int, int *, int *);
 #endif
@@ -1178,6 +1180,25 @@ xwidget_button_1 (struct xwidget_view *view,
   if (!target)
     target = model->widget_osr;
 
+  xg_event = gdk_event_new (down_p ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
+
+  xg_event->any.window = gtk_widget_get_window (target);
+  g_object_ref (xg_event->any.window); /* The window will be unrefed
+                                         later by gdk_event_free.  */
+
+  xg_event->button.x = x;
+  xg_event->button.x_root = x;
+  xg_event->button.y = y;
+  xg_event->button.y_root = y;
+  xg_event->button.button = button;
+  xg_event->button.state = modifier_state;
+  xg_event->button.time = time;
+  xg_event->button.device = find_suitable_pointer (view->frame);
+
+  gtk_main_do_event (xg_event);
+  gdk_event_free (xg_event);
+
+
   if (down_p && !view->passive_grab)
     {
       view->passive_grab = target;
@@ -1200,7 +1221,8 @@ xwidget_button_1 (struct xwidget_view *view,
        {
          xw_maybe_synthesize_crossing (view, gtk_widget_get_window 
(ungrab_target),
                                        view_x, view_y, XW_CROSSING_NONE,
-                                       time, modifier_state);
+                                       time, modifier_state, 
GDK_CROSSING_UNGRAB,
+                                       GDK_CROSSING_UNGRAB);
        }
       else
        {
@@ -1224,7 +1246,8 @@ xwidget_button_1 (struct xwidget_view *view,
 
          xw_notify_virtual_upwards_until (view, target_window, toplevel, 
toplevel,
                                           modifier_state, view_x, view_y, time,
-                                          GDK_LEAVE_NOTIFY, false);
+                                          GDK_LEAVE_NOTIFY, false,
+                                          GDK_CROSSING_UNGRAB);
 
          if (target_window != toplevel)
            {
@@ -1254,24 +1277,6 @@ xwidget_button_1 (struct xwidget_view *view,
          view->passive_grab = NULL;
        }
     }
-
-  xg_event = gdk_event_new (down_p ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
-
-  xg_event->any.window = gtk_widget_get_window (target);
-  g_object_ref (xg_event->any.window); /* The window will be unrefed
-                                         later by gdk_event_free.  */
-
-  xg_event->button.x = x;
-  xg_event->button.x_root = x;
-  xg_event->button.y = y;
-  xg_event->button.y_root = y;
-  xg_event->button.button = button;
-  xg_event->button.state = modifier_state;
-  xg_event->button.time = time;
-  xg_event->button.device = find_suitable_pointer (view->frame);
-
-  gtk_main_do_event (xg_event);
-  gdk_event_free (xg_event);
 }
 
 void
@@ -1286,12 +1291,7 @@ xwidget_button (struct xwidget_view *view,
 
   if (button < 4 || button > 8)
     xwidget_button_1 (view, down_p, x, y, button, modifier_state, time);
-#ifndef HAVE_XINPUT2
   else
-#else
-  else if (!FRAME_DISPLAY_INFO (view->frame)->supports_xi2
-          || FRAME_DISPLAY_INFO (view->frame)->xi2_version < 1)
-#endif
     {
       if (!down_p)
        {
@@ -1369,7 +1369,11 @@ xwidget_motion_notify (struct xwidget_view *view,
     }
   else if (xw_maybe_synthesize_crossing (view, gtk_widget_get_window (target),
                                         x + view->clip_left, y + 
view->clip_top,
-                                        XW_CROSSING_NONE, time, state))
+                                        XW_CROSSING_NONE, time, state,
+                                        (view->passive_grab
+                                         ? GDK_CROSSING_GRAB
+                                         : GDK_CROSSING_NORMAL),
+                                        GDK_CROSSING_NORMAL))
     return;
 
   xg_event = gdk_event_new (GDK_MOTION_NOTIFY);
@@ -1604,7 +1608,8 @@ xw_notify_virtual_upwards_until (struct xwidget_view *xv,
                                 unsigned int state,
                                 int x, int y, Time time,
                                 GdkEventType type,
-                                bool nonlinear_p)
+                                bool nonlinear_p,
+                                GdkCrossingMode crossing)
 {
   GdkEvent *xg_event;
   GdkWindow *tem;
@@ -1625,7 +1630,7 @@ xw_notify_virtual_upwards_until (struct xwidget_view *xv,
       xg_event->crossing.detail = (nonlinear_p
                                   ? GDK_NOTIFY_NONLINEAR_VIRTUAL
                                   : GDK_NOTIFY_VIRTUAL);
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = crossing;
       xg_event->crossing.window = g_object_ref (tem);
 
       gtk_main_do_event (xg_event);
@@ -1641,7 +1646,8 @@ xw_notify_virtual_downwards_until (struct xwidget_view 
*xv,
                                   unsigned int state,
                                   int x, int y, Time time,
                                   GdkEventType type,
-                                  bool nonlinear_p)
+                                  bool nonlinear_p,
+                                  GdkCrossingMode crossing)
 {
   GdkEvent *xg_event;
   GdkWindow *tem;
@@ -1670,7 +1676,7 @@ xw_notify_virtual_downwards_until (struct xwidget_view 
*xv,
       xg_event->crossing.detail = (nonlinear_p
                                   ? GDK_NOTIFY_NONLINEAR_VIRTUAL
                                   : GDK_NOTIFY_VIRTUAL);
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = crossing;
       xg_event->crossing.window = g_object_ref (tem);
 
       gtk_main_do_event (xg_event);
@@ -1715,14 +1721,18 @@ static bool
 xw_maybe_synthesize_crossing (struct xwidget_view *view,
                              GdkWindow *current_window,
                              int x, int y, int crossing,
-                             Time time, unsigned int state)
+                             Time time, unsigned int state,
+                             GdkCrossingMode entry_crossing,
+                             GdkCrossingMode exit_crossing)
 {
   GdkWindow *last_crossing, *toplevel, *ancestor;
   GdkEvent *xg_event;
   int cx, cy;
   bool nonlinear_p;
+  bool retention_flag;
 
   toplevel = gtk_widget_get_window (XXWIDGET (view->model)->widgetwindow_osr);
+  retention_flag = false;
 
   if (crossing == XW_CROSSING_LEFT
       && (view->last_crossing_window
@@ -1731,13 +1741,40 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
       xw_notify_virtual_upwards_until (view, view->last_crossing_window,
                                       toplevel, toplevel,
                                       state, x, y, time,
-                                      GDK_LEAVE_NOTIFY, false);
+                                      GDK_LEAVE_NOTIFY, false,
+                                      exit_crossing);
     }
 
   if (view->last_crossing_window
       && (gdk_window_is_destroyed (view->last_crossing_window)
          || crossing == XW_CROSSING_LEFT))
     {
+      if (!gdk_window_is_destroyed (view->last_crossing_window)
+         && view->last_crossing_window != toplevel)
+       {
+         xg_event = gdk_event_new (GDK_LEAVE_NOTIFY);
+         window_coords_from_toplevel (view->last_crossing_window,
+                                      toplevel, x, y, &cx, &cy);
+
+         xg_event->crossing.x = cx;
+         xg_event->crossing.y = cy;
+         xg_event->crossing.time = time;
+         xg_event->crossing.focus = FALSE;
+         xg_event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+         xg_event->crossing.mode = exit_crossing;
+         xg_event->crossing.window = g_object_ref (view->last_crossing_window);
+         gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
+
+         gtk_main_do_event (xg_event);
+         gdk_event_free (xg_event);
+
+         xw_notify_virtual_upwards_until (view, view->last_crossing_window,
+                                          gdk_window_get_parent (toplevel),
+                                          toplevel, state, x, y, time,
+                                          GDK_LEAVE_NOTIFY, false, 
exit_crossing);
+         retention_flag = true;
+       }
+
       g_signal_handler_disconnect (view->last_crossing_window,
                                   view->last_crossing_cursor_signal);
       g_clear_pointer (&view->last_crossing_window,
@@ -1759,9 +1796,9 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                             toplevel, toplevel,
                                             state, x, y, time,
                                             GDK_ENTER_NOTIFY,
-                                            false);
+                                            false, entry_crossing);
        }
-      return false;
+      return retention_flag;
     }
 
   if (last_crossing != current_window)
@@ -1786,7 +1823,8 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                         ancestor, toplevel,
                                         state, x, y, time,
                                         GDK_LEAVE_NOTIFY,
-                                        nonlinear_p);
+                                        nonlinear_p,
+                                        exit_crossing);
 
       xg_event = gdk_event_new (GDK_LEAVE_NOTIFY);
       gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
@@ -1797,13 +1835,12 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
       xg_event->crossing.time = time;
       xg_event->crossing.focus = FALSE;
       xg_event->crossing.state = state;
-      /* TODO: actually calculate the event mode.  */
       xg_event->crossing.detail = (nonlinear_p
                                   ? GDK_NOTIFY_NONLINEAR
                                   : (last_crossing == ancestor
                                      ? GDK_NOTIFY_INFERIOR
                                      : GDK_NOTIFY_ANCESTOR));
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = exit_crossing;
       xg_event->crossing.window = g_object_ref (last_crossing);
 
       gtk_main_do_event (xg_event);
@@ -1814,7 +1851,8 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                           ancestor, toplevel,
                                           state, x, y, time,
                                           GDK_ENTER_NOTIFY,
-                                          nonlinear_p);
+                                          nonlinear_p,
+                                          entry_crossing);
 
       xg_event = gdk_event_new (GDK_ENTER_NOTIFY);
       gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
@@ -1830,7 +1868,7 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                   : (current_window == ancestor
                                      ? GDK_NOTIFY_INFERIOR
                                      : GDK_NOTIFY_ANCESTOR));
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = entry_crossing;
       xg_event->crossing.window = g_object_ref (current_window);
 
       gtk_main_do_event (xg_event);
@@ -1908,7 +1946,11 @@ xwidget_motion_or_crossing (struct xwidget_view *view, 
const XEvent *event)
       if (!xw_maybe_synthesize_crossing (view, xg_event->any.window,
                                         toplevel_x, toplevel_y,
                                         XW_CROSSING_NONE, event->xmotion.time,
-                                        event->xmotion.state))
+                                        event->xmotion.state,
+                                        (view->passive_grab
+                                         ? GDK_CROSSING_GRAB
+                                         : GDK_CROSSING_NORMAL),
+                                        GDK_CROSSING_NORMAL))
        {
          xg_event->motion.x = x;
          xg_event->motion.y = y;
@@ -1953,7 +1995,11 @@ xwidget_motion_or_crossing (struct xwidget_view *view, 
const XEvent *event)
                                           (xev->type == XI_Enter
                                            ? XW_CROSSING_ENTERED
                                            : XW_CROSSING_LEFT),
-                                          xev->time, xg_event->crossing.state))
+                                          xev->time, xg_event->crossing.state,
+                                          (view->passive_grab
+                                           ? GDK_CROSSING_GRAB
+                                           : GDK_CROSSING_NORMAL),
+                                          GDK_CROSSING_NORMAL))
        {
          gdk_event_free (xg_event);
          return;
@@ -1971,7 +2017,11 @@ xwidget_motion_or_crossing (struct xwidget_view *view, 
const XEvent *event)
                                            ? XW_CROSSING_ENTERED
                                            : XW_CROSSING_LEFT),
                                           event->xcrossing.time,
-                                          event->xcrossing.state))
+                                          event->xcrossing.state,
+                                          (view->passive_grab
+                                           ? GDK_CROSSING_GRAB
+                                           : GDK_CROSSING_NORMAL),
+                                          GDK_CROSSING_NORMAL))
        {
          gdk_event_free (xg_event);
          return;
diff --git a/test/lisp/cedet/semantic/bovine/gcc-tests.el 
b/test/lisp/cedet/semantic/bovine/gcc-tests.el
index 2e61f91e58..041773a0c8 100644
--- a/test/lisp/cedet/semantic/bovine/gcc-tests.el
+++ b/test/lisp/cedet/semantic/bovine/gcc-tests.el
@@ -26,6 +26,7 @@
 ;;; Code:
 
 (require 'ert)
+(require 'ert-x)
 (require 'semantic/bovine/gcc)
 
 ;;; From bovine-gcc:
@@ -122,14 +123,9 @@ gcc version 2.95.2 19991024 (release)"
 
 (ert-deftest semantic-gcc-test-output-parser-this-machine ()
   "Test the output parser against the machine currently running Emacs."
-  (skip-unless (executable-find "gcc"))
+  (skip-unless (and (executable-find "gcc")
+                    (not (ert-gcc-is-clang-p))))
   (let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v"))))
-    ;; Some macOS machines run llvm when you type gcc.  (!)
-    ;; We can't even check if it's a symlink; it's a binary placed in
-    ;; "/usr/bin/gcc".  So check the output and just skip this test if
-    ;; it looks like that's the case.
-    (unless (string-match "Apple \\(LLVM\\|clang\\)\\|Xcode\\.app"
-                          (car semantic-gcc-test-strings))
-        (semantic-gcc-test-output-parser))))
+    (semantic-gcc-test-output-parser)))
 
 ;;; gcc-tests.el ends here
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index e10ed04f9d..5d7e905cfa 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -79,7 +79,7 @@
     (should (equal (point)
                    expected-point))))
 
-(eval-when-compile
+(eval-and-compile
   (defun electric-pair-define-test-form (name fixture
                                               char
                                               pos
diff --git a/test/lisp/emacs-lisp/ert-tests.el 
b/test/lisp/emacs-lisp/ert-tests.el
index 270cca1c2e..dd12e3764c 100644
--- a/test/lisp/emacs-lisp/ert-tests.el
+++ b/test/lisp/emacs-lisp/ert-tests.el
@@ -865,7 +865,7 @@ This macro is used to test if macroexpansion in `should' 
works."
 (ert-deftest ert-test-with-demoted-errors ()
   "Check that ERT correctly handles `with-demoted-errors'."
   :expected-result :failed  ;; FIXME!  Bug#11218
-  (should-not (with-demoted-errors (error "Foo"))))
+  (should-not (with-demoted-errors "FOO: %S" (error "Foo"))))
 
 (ert-deftest ert-test-fail-inside-should ()
   "Check that `ert-fail' inside `should' works correctly."
diff --git a/test/lisp/eshell/em-extpipe-tests.el 
b/test/lisp/eshell/em-extpipe-tests.el
index 0879ad5b0c..a1d15fe73a 100644
--- a/test/lisp/eshell/em-extpipe-tests.el
+++ b/test/lisp/eshell/em-extpipe-tests.el
@@ -28,14 +28,10 @@
 (require 'ert)
 (require 'ert-x)
 (require 'em-extpipe)
-(eval-and-compile
-  (load (expand-file-name "eshell-tests-helpers"
-                          (file-name-directory (or load-file-name
-                                                   default-directory)))))
-
-(defvar eshell-history-file-name)
-(defvar eshell-test--max-subprocess-time)
-(declare-function eshell-command-result-p "eshell-tests-helpers")
+(require 'eshell-tests-helpers
+         (expand-file-name "eshell-tests-helpers"
+                           (file-name-directory (or load-file-name
+                                                    default-directory))))
 
 (defmacro em-extpipe-tests--deftest (name input &rest body)
   (declare (indent 2))
diff --git a/test/lisp/eshell/eshell-tests-helpers.el 
b/test/lisp/eshell/eshell-tests-helpers.el
index 77f5313d57..33cdd60113 100644
--- a/test/lisp/eshell/eshell-tests-helpers.el
+++ b/test/lisp/eshell/eshell-tests-helpers.el
@@ -30,6 +30,8 @@
 (require 'esh-mode)
 (require 'eshell)
 
+(defvar eshell-history-file-name nil)
+
 (defvar eshell-test--max-subprocess-time 5
   "The maximum amount of time to wait for a subprocess to finish, in seconds.
 See `eshell-wait-for-subprocess'.")
@@ -53,7 +55,7 @@ See `eshell-wait-for-subprocess'.")
 If this takes longer than `eshell-test--max-subprocess-time',
 raise an error."
   (let ((start (current-time)))
-    (while (eshell-interactive-process)
+    (while (eshell-interactive-process-p)
       (when (> (float-time (time-since start))
                eshell-test--max-subprocess-time)
         (error "timed out waiting for subprocess"))
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 542815df80..d6ee1bdb17 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -29,16 +29,10 @@
 (require 'ert-x)
 (require 'esh-mode)
 (require 'eshell)
-(eval-and-compile
-  (load (expand-file-name "eshell-tests-helpers"
-                          (file-name-directory (or load-file-name
-                                                   default-directory)))))
-
-(defvar eshell-history-file-name)
-(defvar eshell-test--max-subprocess-time)
-(declare-function eshell-insert-command "eshell-tests-helpers")
-(declare-function eshell-match-result "eshell-tests-helpers")
-(declare-function eshell-command-result-p "eshell-tests-helpers")
+(require 'eshell-tests-helpers
+         (expand-file-name "eshell-tests-helpers"
+                           (file-name-directory (or load-file-name
+                                                    default-directory))))
 
 ;;; Tests:
 
@@ -129,6 +123,31 @@ e.g. \"{(+ 1 2)} 3\" => 3"
    (eshell-command-result-p "echo ${echo hi}-${*echo there}"
                             "hi-there\n")))
 
+(ert-deftest eshell-test/pipe-headproc ()
+  "Check that piping a non-process to a process command waits for the process"
+  (skip-unless (executable-find "cat"))
+  (with-temp-eshell
+   (eshell-command-result-p "echo hi | *cat"
+                            "hi")))
+
+(ert-deftest eshell-test/pipe-tailproc ()
+  "Check that piping a process to a non-process command waits for the process"
+  (skip-unless (executable-find "echo"))
+  (with-temp-eshell
+   (eshell-command-result-p "*echo hi | echo bye"
+                            "bye\nhi\n")))
+
+(ert-deftest eshell-test/pipe-headproc-stdin ()
+  "Check that standard input is sent to the head process in a pipeline"
+  (skip-unless (and (executable-find "tr")
+                    (executable-find "rev")))
+  (with-temp-eshell
+   (eshell-insert-command "tr a-z A-Z | rev")
+   (eshell-insert-command "hello")
+   (eshell-send-eof-to-process)
+   (eshell-wait-for-subprocess)
+   (eshell-match-result "OLLEH\n")))
+
 (ert-deftest eshell-test/window-height ()
   "$LINES should equal (window-height)"
   (should (eshell-test-command-result "= $LINES (window-height)")))
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index d27e3d7cd4..9c9dddcd19 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -286,11 +286,11 @@ M-g M-c           switch-to-completions
            "
 Key             Binding
 -+
-( .. )         short-range
 1 .. 4         foo-range
 a .. c         foo-other-range
 
 C-e            foo-something
+( .. )         short-range
 x              foo-original
 <F1>           foo-function-key1
 "))))
@@ -304,12 +304,12 @@ x         foo-original
            "
 Key             Binding
 -+
-( .. )         short-range
 1 .. 4         foo-range
 a .. c         foo-other-range
 
 C-e            foo-something
   (this binding is currently shadowed)
+( .. )         short-range
 x              foo-original
   (this binding is currently shadowed)
 <F1>           foo-function-key1
diff --git a/test/lisp/international/textsec-tests.el 
b/test/lisp/international/textsec-tests.el
index ee0af66d99..5bf9a3dcfb 100644
--- a/test/lisp/international/textsec-tests.el
+++ b/test/lisp/international/textsec-tests.el
@@ -169,8 +169,8 @@
    (textsec-email-address-header-suspicious-p
     "Lars Ingebrigtsen <larsi@\N{RIGHT-TO-LEFT OVERRIDE}gnus.org>"))
 
-  (should (textsec-email-address-header-suspicious-p
-           "דגבא <foo@bar.com>"))
+  (should-not (textsec-email-address-header-suspicious-p
+               "דגבא <foo@bar.com>"))
 
   (should (textsec-email-address-suspicious-p
            "Bob_Norbolwits@GCSsafetyACE.com​")))
diff --git a/test/lisp/loadhist-resources/loadhist--bar.el 
b/test/lisp/loadhist-resources/loadhist--bar.el
new file mode 100644
index 0000000000..5c8914ed57
--- /dev/null
+++ b/test/lisp/loadhist-resources/loadhist--bar.el
@@ -0,0 +1,27 @@
+;;; loadhist--bar.el --- Dummy package for loadhist-tests  -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2022  Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(autoload 'loadhist--foo-inc "loadhist--foo")
+
+(defun loadhist--bar-dec (x) (1- x))
+
+(provide 'loadhist--bar)
+;;; loadhist--bar.el ends here
diff --git a/test/lisp/loadhist-resources/loadhist--foo.el 
b/test/lisp/loadhist-resources/loadhist--foo.el
new file mode 100644
index 0000000000..3574c22013
--- /dev/null
+++ b/test/lisp/loadhist-resources/loadhist--foo.el
@@ -0,0 +1,29 @@
+;;; loadhist--foo.el --- Dummy package for loadhist-tests  -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2022  Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(autoload 'loadhist--bar-dec "loadhist--bar")
+
+(defun loadhist--foo-inc (x) (1+ x))
+
+(provide 'loadhist--foo)
+;;; loadhist--foo.el ends here
diff --git a/test/lisp/loadhist-tests.el b/test/lisp/loadhist-tests.el
index a941ac0632..ef5fc164d3 100644
--- a/test/lisp/loadhist-tests.el
+++ b/test/lisp/loadhist-tests.el
@@ -54,4 +54,51 @@
   (should-error (unload-feature 'dired))
   (unload-feature 'dired-x))
 
+(defvar loadhist--tests-dir (file-name-directory (macroexp-file-name)))
+
+(ert-deftest loadhist-tests-unload-feature-nested ()
+  (add-to-list 'load-path (expand-file-name
+                           "loadhist-resources/"
+                           loadhist--tests-dir))
+  (declare-function loadhist--foo-inc "loadhist--foo")
+  (declare-function loadhist--bar-dec "loadhist--dec")
+  (load "loadhist--foo" nil t)
+  (should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
+  (should (autoloadp (symbol-function 'loadhist--bar-dec)))
+  (load "loadhist--bar" nil t)
+  (should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
+  (should (not (autoloadp (symbol-function 'loadhist--bar-dec))))
+  (should (not (autoloadp (symbol-function 'loadhist--foo-inc))))
+  (should (equal (list 40 42)
+                 (list (loadhist--bar-dec 41) (loadhist--foo-inc 41))))
+  (unload-feature 'loadhist--bar)
+  (should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
+  (should (autoloadp (symbol-function 'loadhist--bar-dec)))
+  (should (not (autoloadp (symbol-function 'loadhist--foo-inc))))
+  (unload-feature 'loadhist--foo)
+  (should (null (symbol-function 'loadhist--bar-dec)))
+  (should (null (symbol-function 'loadhist--foo-inc)))
+  (should (null (get 'loadhist--bar-dec 'function-history)))
+  (should (null (get 'loadhist--foo-inc 'function-history))))
+
+(ert-deftest loadhist-tests-unload-feature-notnested ()
+  (add-to-list 'load-path (expand-file-name
+                           "loadhist-resources/"
+                           loadhist--tests-dir))
+  (load "loadhist--foo" nil t)
+  (load "loadhist--bar" nil t)
+  (should (equal (list 40 42)
+                 (list (loadhist--bar-dec 41) (loadhist--foo-inc 41))))
+  (unload-feature 'loadhist--foo)
+  (should (functionp 'loadhist--bar-dec))
+  (should (not (autoloadp (symbol-function 'loadhist--bar-dec))))
+  (should  (let ((f (symbol-function 'loadhist--foo-inc)))
+             ;; Both choices seem acceptable.
+             (or (null f) (autoloadp f))))
+  (unload-feature 'loadhist--bar)
+  (should (null (symbol-function 'loadhist--bar-dec)))
+  (should (null (symbol-function 'loadhist--foo-inc)))
+  (should (null (get 'loadhist--bar-dec 'function-history)))
+  (should (null (get 'loadhist--foo-inc 'function-history))))
+
 ;;; loadhist-tests.el ends here
diff --git a/test/lisp/mail/ietf-drums-tests.el 
b/test/lisp/mail/ietf-drums-tests.el
new file mode 100644
index 0000000000..4cc38b8763
--- /dev/null
+++ b/test/lisp/mail/ietf-drums-tests.el
@@ -0,0 +1,162 @@
+;;; ietf-drums-tests.el --- Test suite for ietf-drums.el  -*- 
lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Bob Rogers <rogers@rgrjr.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'ietf-drums)
+
+(ert-deftest ietf-drums-tests ()
+  "Test ietf-drums functionality."
+
+  ;; ietf-drums-remove-comments
+  (should (equal (ietf-drums-remove-comments "random string") "random string"))
+  (should (equal (ietf-drums-remove-comments "random \"non comment\" string")
+                 "random \"non comment\" string"))
+  (should (equal (ietf-drums-remove-comments "random (comment) string")
+                 "random  string"))
+  (should (equal (ietf-drums-remove-comments "random (comment) (string)")
+                 "random  "))
+  (should (equal (ietf-drums-remove-comments
+                  "random (first) (second (and)) (third) not fourth")
+                 "random    not fourth"))
+
+  ;; ietf-drums-remove-whitespace
+  (should (equal (ietf-drums-remove-whitespace "random string")
+                 "randomstring"))
+  (should (equal (ietf-drums-remove-whitespace "random (comment) string")
+                 "random(comment)string"))
+  (should (equal (ietf-drums-remove-whitespace "random \"non comment\" string")
+                 "random\"non comment\"string"))
+  (should (equal (ietf-drums-remove-whitespace "random (comment)\r\n(string)")
+                 "random(comment)(string)"))
+  (should (equal (ietf-drums-remove-whitespace
+                  "random (first) (second (and)) (third) not fourth")
+                 "random(first)(second (and))(third)notfourth"))
+
+  ;; ietf-drums-strip
+  (should (equal (ietf-drums-strip "random string") "randomstring"))
+  (should (equal (ietf-drums-strip "random \"non comment\" string")
+                 "random\"non comment\"string"))
+  (should (equal (ietf-drums-strip "random (comment) string")
+                 "randomstring"))
+  (should (equal (ietf-drums-strip "random (comment) (string)")
+                 "random"))
+  (should (equal (ietf-drums-strip
+                  "random (first) (second (and)) (third) not fourth")
+                 "randomnotfourth"))
+
+  ;; ietf-drums-strip-cte
+  (should (equal (ietf-drums-strip-cte "random \"non comment\" string")
+                 ;; [the " " is still in there because it was quoted
+                 ;; through the "strip".  -- rgr, 5-Feb-22.]
+                 "randomnon commentstring"))
+  (should (equal (ietf-drums-strip-cte "ran(d)do<m@>[s;t:r],,in=g")
+                 "randomstring"))
+
+  ;; ietf-drums-quote-string
+  (should (equal (ietf-drums-quote-string "Bob") "Bob"))
+  (should (equal (ietf-drums-quote-string "Foo Bar") "\"Foo Bar\""))
+
+  ;; ietf-drums-get-comment
+  (should (equal (ietf-drums-get-comment "random string") nil))
+  (should (equal (ietf-drums-get-comment "random (comment) string") "comment"))
+  (should (equal (ietf-drums-get-comment "random \"non comment\" string") nil))
+  (should (equal (ietf-drums-get-comment "\"still (non) comment\" string")
+                 nil))
+  (should (equal (ietf-drums-get-comment "random (comment)\r\nstring")
+                 "comment"))
+  (should (equal (ietf-drums-get-comment "random (comment) (string)") 
"string"))
+  (should (equal (ietf-drums-get-comment
+                  "random (first) (second (and)) (third) not fourth")
+                 "third"))
+
+  ;; ietf-drums-make-address
+  (should (equal (ietf-drums-make-address "Bob Rogers" "rogers@rgrjr.com")
+                 "\"Bob Rogers\" <rogers@rgrjr.com>"))
+  (should (equal (ietf-drums-make-address nil "rogers@rgrjr.com")
+                 "rogers@rgrjr.com"))
+
+  ;; ietf-drums-parse-address
+  (should (equal (ietf-drums-parse-address "foo@example.com")
+                 '("foo@example.com")))
+  (should (equal (ietf-drums-parse-address "<foo@example.com>")
+                 '("foo@example.com")))
+  (should (equal (ietf-drums-parse-address "'foo' <foo@example.com>")
+                 '("foo@example.com" . "'foo'")))
+  (should (equal (ietf-drums-parse-address "foo <foo@example.com>")
+                 '("foo@example.com" . "foo")))
+  (should (equal (ietf-drums-parse-address "foo <foo@example.com> bar")
+                 ;; [contrary to RFC2822, which wants the display-name
+                 ;; before the address.  -- rgr, 5-Feb-22.]
+                 '("foo@example.com" . "foo bar")))
+  (should (equal (ietf-drums-parse-address " <foo@example.com> foo ")
+                 ;; [ditto.  -- rgr, 5-Feb-22.]
+                 '("foo@example.com" . "foo")))
+  (should (equal (ietf-drums-parse-address "foo@example.com (foo)")
+                 '("foo@example.com" . "foo")))
+  (should (equal (ietf-drums-parse-address "Bar Baz <barbaz@example.com>")
+                 '("barbaz@example.com" . "Bar Baz")))
+  (should (equal (ietf-drums-parse-address "barbaz@example.com (Bar Baz)")
+                 '("barbaz@example.com" . "Bar Baz")))
+  (should (equal (ietf-drums-parse-address
+                  "Bar Baz (ignored) <barbaz@example.com>")
+                 '("barbaz@example.com" . "Bar Baz")))
+  (should (equal (ietf-drums-parse-address "<barbaz@example.com> Bar Baz")
+                 '("barbaz@example.com" . "Bar Baz")))
+  (should (equal (ietf-drums-parse-address
+                  "(Bar Baz not ignored) barbaz@example.com")
+                 ;; [not strictly RFC2822, which expects the name
+                 ;; comment after the address.  -- rgr, 5-Feb-22.]
+                 '("barbaz@example.com" . "Bar Baz not ignored")))
+  (should (equal (ietf-drums-parse-address
+                  "(ignored) <barbaz@example.com> (Bar Baz not ignored)")
+                 '("barbaz@example.com" . "Bar Baz not ignored")))
+  (should (equal (ietf-drums-parse-address
+                  "(ignored) barbaz@example.com (Bar Baz not ignored)")
+                 '("barbaz@example.com" . "Bar Baz not ignored")))
+  ;; Test for RFC2047 token decoding.
+  (should (equal (ietf-drums-parse-address
+                  "=?utf-8?B?0JfQtNGA0LDMgdCy0YHRgtCy0YPQudGC0LUh?= 
<foo@goo.ru>"
+                  t)
+                 '("foo@goo.ru" . "Здра́вствуйте!")))
+
+  ;; ietf-drums-parse-addresses
+  ;; Note that it's not worth getting too elaborate here, as the heavy
+  ;; lifting is all done by ietf-drums-parse-address.
+  (should (equal (ietf-drums-parse-addresses "foo@example.com")
+                 '(("foo@example.com"))))
+  (should (equal (ietf-drums-parse-addresses
+                  "foo@example.com, bar@example.com")
+                 '(("foo@example.com") ("bar@example.com"))))
+  (should (equal (ietf-drums-parse-addresses
+                  "foo@example.com, quux, bar@example.com")
+                 '(("foo@example.com") ("bar@example.com"))))
+  (should (equal (ietf-drums-parse-addresses
+                  "foo@example.com, Quux Dude <quux@noop.org>, 
bar@example.com")
+                 '(("foo@example.com") ("quux@noop.org" . "Quux Dude")
+                   ("bar@example.com")))))
+
+(provide 'ietf-drums-tests)
+
+;;; ietf-drums-tests.el ends here
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 01fe7355f4..a4f2fe9e0e 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -6018,6 +6018,78 @@ Use direct async.")
        (ignore-errors (delete-file tmp-name1))
        (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
 
+;; The functions were introduced in Emacs 28.1.
+(ert-deftest tramp-test39-detect-external-change ()
+  "Check that an external file modification is reported."
+  (skip-unless (tramp--test-enabled))
+  (skip-unless (not (tramp--test-ange-ftp-p)))
+  ;; Since Emacs 28.1.
+  (skip-unless (and (fboundp 'lock-file) (fboundp 'file-locked-p)))
+
+  (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
+    (dolist (create-lockfiles '(nil t))
+      (let ((tmp-name (tramp--test-make-temp-name nil quoted))
+           (remote-file-name-inhibit-cache t)
+           (remote-file-name-inhibit-locks nil)
+           tramp-allow-unsafe-temporary-files
+            (inhibit-message t)
+           ;; tramp-rclone.el and tramp-sshfs.el cache the mounted files.
+           (tramp-fuse-unmount-on-cleanup t)
+            auto-save-default
+           (backup-inhibited t)
+           noninteractive)
+        (with-temp-buffer
+          (unwind-protect
+             (progn
+               (setq buffer-file-name tmp-name
+                     buffer-file-truename tmp-name)
+               (insert "foo")
+               ;; Bug#53207: with `create-lockfiles' nil, saving the
+               ;; buffer results in a prompt.
+               (cl-letf (((symbol-function 'yes-or-no-p)
+                          (lambda (_) (ert-fail "Test failed unexpectedly"))))
+                 (save-buffer))
+               (should-not (file-locked-p tmp-name))
+
+               ;; For local files, just changing the file
+               ;; modification on disk doesn't hurt, because file
+               ;; contents in buffer and on disk are equal.  For
+               ;; remote files, file contents is not compared.  We
+               ;; mock an older modification time in buffer, because
+               ;; Tramp regards modification times equal if they
+               ;; differ for less than 2 seconds.
+               (set-visited-file-modtime (time-add (current-time) -60))
+               ;; Some Tramp methods cannot check the file
+               ;; modification time properly, for them it doesn't
+               ;; make sense to test.
+               (when (not (verify-visited-file-modtime))
+                 (cl-letf (((symbol-function 'read-char-choice)
+                            (lambda (prompt &rest _) (message "%s" prompt) 
?y)))
+                   (ert-with-message-capture captured-messages
+                     (insert "bar")
+                     (when create-lockfiles
+                       (should (string-match-p
+                                (format
+                                 "^%s changed on disk; really edit the 
buffer\\?"
+                                 (if (tramp--test-crypt-p)
+                                     ".+" (file-name-nondirectory tmp-name)))
+                                captured-messages))
+                       (should (file-locked-p tmp-name)))))
+
+                 ;; `save-buffer' removes the file lock.
+                 (cl-letf (((symbol-function 'yes-or-no-p) 
#'tramp--test-always)
+                           ((symbol-function 'read-char-choice)
+                            (lambda (&rest _) ?y)))
+                   (save-buffer))
+                 (should-not (file-locked-p tmp-name))))
+
+           ;; Cleanup.
+           (set-buffer-modified-p nil)
+           (ignore-errors (delete-file tmp-name))
+           (tramp-cleanup-connection
+            tramp-test-vec 'keep-debug 'keep-password)))))))
+
+;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-test40-make-nearby-temp-file ()
   "Check `make-nearby-temp-file' and `temporary-file-directory'."
   (skip-unless (tramp--test-enabled))
@@ -7133,12 +7205,14 @@ Since it unloads Tramp, it shall be the last test to 
run."
   (mapatoms
    (lambda (x)
      (and (or (and (boundp x) (null (local-variable-if-set-p x)))
-             (and (functionp x) (null (autoloadp (symbol-function x)))))
+             (and (functionp x) (null (autoloadp (symbol-function x))))
+             (macrop x))
          (string-match-p "^tramp" (symbol-name x))
          ;; `tramp-completion-mode' is autoloaded in Emacs < 28.1.
          (not (eq 'tramp-completion-mode x))
          (not (string-match-p "^tramp\\(-archive\\)?--?test" (symbol-name x)))
          (not (string-match-p "unload-hook$" (symbol-name x)))
+         (not (get x 'tramp-autoload))
          (ert-fail (format "`%s' still bound" x)))))
   ;; The defstruct `tramp-file-name' and all its internal functions
   ;; shall be purged.
diff --git a/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl 
b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
new file mode 100644
index 0000000000..7138bf631d
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
@@ -0,0 +1,50 @@
+# The next two lines are required as of 2022, but obsolescent
+# as soon as signatures leave their "experimental" state
+use feature 'signatures';
+no warnings 'experimental::signatures';
+
+# Tests for subroutine prototypes, signatures and the like
+
+# Prototypes have syntactical properties different from "normal" Perl:
+# Perl has a variable $), so ($)) is not an unbalanced parenthesis.
+# On the other hand, in a prototype ($) is _not_ an open paren
+# followed by the variable $), so the parens are balanced.  Prototypes
+# are somewhat frowned upon most of the times, but they are required
+# for some Perl magic
+
+# FIXME: 2022-02-02 CPerl mode does not handle subroutine signatures.
+# In simple cases it mistakes them as prototypes, when attributes are
+# present, it doesn't handle them at all.  Variables in signatures
+# SHOULD be fontified like variable declarations.
+
+# Part 1: Named subroutines
+# A prototype and a trivial subroutine attribute
+{
+    no feature 'signatures'; # that's a prototype, not a signature
+    sub sub_1 ($) :lvalue { local $); }
+}
+
+# A prototype as an attribute (how it should be written these days)
+sub sub_2 :prototype($) { ...; }
+
+# A signature (these will soon-ish leave the experimental state)
+sub sub_3 ($foo,$bar) { ...; }
+
+# Attribute plus signature FIXME: Not yet supported
+sub bad_sub_4 :prototype($$$) ($foo,$bar,$baz) { ...; }
+
+# Part 2: Same constructs for anonymous subs
+# A prototype and a trivial subroutine attribute
+{
+    no feature 'signatures'; # that's a prototype, not a signature
+    my $subref_1 = sub ($) :lvalue { local $); };
+}
+
+# A prototype as an attribute (how it should be written these days)
+my $subref_2 = sub :prototype($) { ...; };
+
+# A signature (these will soon-ish leave the experimental state)
+my $subref_3 = sub ($foo,$bar) { ...; };
+
+# Attribute plus signature
+my $subref_4 = sub :prototype($$$) ($foo,$bar,$baz) { ...; };
diff --git a/test/lisp/progmodes/cperl-mode-tests.el 
b/test/lisp/progmodes/cperl-mode-tests.el
index 0124dad6f1..b8a3bd97d8 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -154,6 +154,55 @@ point in the distant past, and is still broken in 
perl-mode. "
     (should (equal (get-text-property (match-beginning 0) 'face)
                    'font-lock-keyword-face))))
 
+(ert-deftest cperl-test-fontify-attrs-and-signatures ()
+  "Test fontification of the various combinations of subroutine
+attributes, prototypes and signatures."
+  (skip-unless (eq cperl-test-mode #'cperl-mode))
+  (let ((file (ert-resource-file "proto-and-attrs.pl")))
+    (with-temp-buffer
+      (insert-file-contents file)
+      (goto-char (point-min))
+      (funcall cperl-test-mode)
+      (font-lock-ensure)
+
+      ;; Named subroutines
+      (while (search-forward-regexp "\\_<sub_[[:digit:]]+" nil t)
+        (should (equal (get-text-property (match-beginning 0) 'face)
+                       'font-lock-function-name-face))
+        (let ((start-of-sub (match-beginning 0))
+              (end-of-sub (save-excursion (search-forward "}") (point))))
+
+          ;; Prototypes are shown as strings
+          (when (search-forward-regexp " ([$%@*]*) " end-of-sub t)
+            (should (equal (get-text-property (1+ (match-beginning 0)) 'face)
+                           'font-lock-string-face)))
+          (goto-char start-of-sub)
+          (when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub 
t)
+            (should (equal (get-text-property (match-beginning 1) 'face)
+                           'font-lock-constant-face))
+            (when (match-beginning 2)
+              (should (equal (get-text-property (match-beginning 2) 'face)
+                             'font-lock-string-face))))
+          (goto-char end-of-sub)))
+
+      ;; Anonymous subroutines
+      (while (search-forward-regexp "= sub" nil t)
+        (let ((start-of-sub (match-beginning 0))
+              (end-of-sub (save-excursion (search-forward "}") (point))))
+
+          ;; Prototypes are shown as strings
+          (when (search-forward-regexp " ([$%@*]*) " end-of-sub t)
+            (should (equal (get-text-property (1+ (match-beginning 0)) 'face)
+                           'font-lock-string-face)))
+          (goto-char start-of-sub)
+          (when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub 
t)
+            (should (equal (get-text-property (match-beginning 1) 'face)
+                           'font-lock-constant-face))
+            (when (match-beginning 2)
+              (should (equal (get-text-property (match-beginning 2) 'face)
+                             'font-lock-string-face))))
+          (goto-char end-of-sub))))))
+
 (ert-deftest cperl-test-fontify-special-variables ()
   "Test fontification of variables like $^T or ${^ENCODING}.
 These can occur as \"local\" aliases."
diff --git a/test/lisp/progmodes/flymake-tests.el 
b/test/lisp/progmodes/flymake-tests.el
index ced7b5aace..71b03b21e5 100644
--- a/test/lisp/progmodes/flymake-tests.el
+++ b/test/lisp/progmodes/flymake-tests.el
@@ -140,15 +140,10 @@ SEVERITY-PREDICATE is used to setup
         (flymake-goto-next-error)
         (should (eq 'flymake-error (face-at-point)))))))
 
-(defun flymake-tests--gcc-is-clang ()
-  "Whether the `gcc' command actually runs the Clang compiler."
-  (string-match "[Cc]lang version "
-                (shell-command-to-string "gcc --version")))
-
 (ert-deftest different-diagnostic-types ()
   "Test GCC warning via function predicate."
   (skip-unless (and (executable-find "gcc")
-                    (not (flymake-tests--gcc-is-clang))
+                    (not (ert-gcc-is-clang-p))
                     (version<=
                      "5" (string-trim
                           (shell-command-to-string "gcc -dumpversion")))
@@ -173,7 +168,7 @@ SEVERITY-PREDICATE is used to setup
 (ert-deftest included-c-header-files ()
   "Test inclusion of .h header files."
   (skip-unless (and (executable-find "gcc")
-                    (not (flymake-tests--gcc-is-clang))
+                    (not (ert-gcc-is-clang-p))
                     (executable-find "make")))
   (let ((flymake-wrap-around nil))
     (flymake-tests--with-flymake
diff --git a/test/lisp/progmodes/python-tests.el 
b/test/lisp/progmodes/python-tests.el
index 0eb1c087f4..1a6a7dc176 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -2634,58 +2634,59 @@ if x:
   "Test `python-shell-process-environment' modification."
   (let* ((python-shell-process-environment
           '("TESTVAR1=value1" "TESTVAR2=value2"))
-         (process-environment (python-shell-calculate-process-environment)))
-    (should (equal (getenv "TESTVAR1") "value1"))
-    (should (equal (getenv "TESTVAR2") "value2"))))
+         (env (python-shell--calculate-process-environment)))
+    (should (equal (getenv-internal "TESTVAR1" env) "value1"))
+    (should (equal (getenv-internal "TESTVAR2" env) "value2"))))
 
 (ert-deftest python-shell-calculate-process-environment-2 ()
   "Test `python-shell-extra-pythonpaths' modification."
   (let* ((process-environment process-environment)
          (_original-pythonpath (setenv "PYTHONPATH" "/path0"))
          (python-shell-extra-pythonpaths '("/path1" "/path2"))
-         (process-environment (python-shell-calculate-process-environment)))
-    (should (equal (getenv "PYTHONPATH")
+         (env (python-shell--calculate-process-environment)))
+    (should (equal (getenv-internal "PYTHONPATH" env)
                    (concat "/path1" path-separator
                            "/path2" path-separator "/path0")))))
 
 (ert-deftest python-shell-calculate-process-environment-3 ()
   "Test `python-shell-virtualenv-root' modification."
   (let* ((python-shell-virtualenv-root "/env")
-         (process-environment
+         (env
           (let ((process-environment process-environment))
             (setenv "PYTHONHOME" "/home")
             (setenv "VIRTUAL_ENV")
-            (python-shell-calculate-process-environment))))
-    (should (not (getenv "PYTHONHOME")))
-    (should (string= (getenv "VIRTUAL_ENV") "/env"))))
+            (python-shell--calculate-process-environment))))
+    (should (member "PYTHONHOME" env))
+    (should (string= (getenv-internal "VIRTUAL_ENV" env) "/env"))))
 
 (ert-deftest python-shell-calculate-process-environment-4 ()
   "Test PYTHONUNBUFFERED when `python-shell-unbuffered' is non-nil."
   (let* ((python-shell-unbuffered t)
-         (process-environment
+         (env
           (let ((process-environment process-environment))
             (setenv "PYTHONUNBUFFERED")
-            (python-shell-calculate-process-environment))))
-    (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
+            (python-shell--calculate-process-environment))))
+    (should (string= (getenv-internal "PYTHONUNBUFFERED" env) "1"))))
 
 (ert-deftest python-shell-calculate-process-environment-5 ()
   "Test PYTHONUNBUFFERED when `python-shell-unbuffered' is nil."
   (let* ((python-shell-unbuffered nil)
-         (process-environment
+         (env
           (let ((process-environment process-environment))
             (setenv "PYTHONUNBUFFERED")
-            (python-shell-calculate-process-environment))))
-    (should (not (getenv "PYTHONUNBUFFERED")))))
+            (python-shell--calculate-process-environment))))
+    (should (not (getenv-internal "PYTHONUNBUFFERED" env)))))
 
 (ert-deftest python-shell-calculate-process-environment-6 ()
   "Test PYTHONUNBUFFERED=1 when `python-shell-unbuffered' is nil."
   (let* ((python-shell-unbuffered nil)
-         (process-environment
+         (env
           (let ((process-environment process-environment))
             (setenv "PYTHONUNBUFFERED" "1")
-            (python-shell-calculate-process-environment))))
+            (append (python-shell--calculate-process-environment)
+                    process-environment))))
     ;; User default settings must remain untouched:
-    (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
+    (should (string= (getenv-internal "PYTHONUNBUFFERED" env) "1"))))
 
 (ert-deftest python-shell-calculate-process-environment-7 ()
   "Test no side-effects on `process-environment'."
@@ -2695,7 +2696,7 @@ if x:
          (python-shell-unbuffered t)
          (python-shell-extra-pythonpaths'("/path1" "/path2"))
          (original-process-environment (copy-sequence process-environment)))
-    (python-shell-calculate-process-environment)
+    (python-shell--calculate-process-environment)
     (should (equal process-environment original-process-environment))))
 
 (ert-deftest python-shell-calculate-process-environment-8 ()
@@ -2708,7 +2709,7 @@ if x:
          (python-shell-extra-pythonpaths'("/path1" "/path2"))
          (original-process-environment
           (copy-sequence tramp-remote-process-environment)))
-    (python-shell-calculate-process-environment)
+    (python-shell--calculate-process-environment)
     (should (equal tramp-remote-process-environment 
original-process-environment))))
 
 (ert-deftest python-shell-calculate-exec-path-1 ()
@@ -2780,23 +2781,43 @@ if x:
       (should (string= (getenv "VIRTUAL_ENV") "/env")))
     (should (equal exec-path original-exec-path))))
 
+(defun python--tests-process-env-canonical (pe)
+  ;; `process-environment' can contain various entries for the same
+  ;; var, and the first in the list hides the others.
+  (let ((process-environment '()))
+    (dolist (x (reverse pe))
+      (if (string-match "=" x)
+          (setenv (substring x 0 (match-beginning 0))
+                  (substring x (match-end 0)))
+        (setenv x nil)))
+    process-environment))
+
+(defun python--tests-process-env-eql (pe1 pe2)
+  (equal (python--tests-process-env-canonical pe1)
+         (python--tests-process-env-canonical pe2)))
+
 (ert-deftest python-shell-with-environment-2 ()
   "Test environment with remote `default-directory'."
   (let* ((default-directory "/ssh::/example/dir/")
          (python-shell-remote-exec-path '("/remote1" "/remote2"))
          (python-shell-exec-path '("/path1" "/path2"))
          (tramp-remote-process-environment '("EMACS=t"))
-         (original-process-environment (copy-sequence 
tramp-remote-process-environment))
+         (original-process-environment
+          (copy-sequence tramp-remote-process-environment))
          (python-shell-virtualenv-root "/env"))
     (python-shell-with-environment
       (should (equal (python-shell-calculate-exec-path)
                      (list (python-virt-bin)
                            "/path1" "/path2" "/remote1" "/remote2")))
-      (let ((process-environment (python-shell-calculate-process-environment)))
+      (let ((process-environment
+             (append (python-shell--calculate-process-environment)
+                     tramp-remote-process-environment)))
         (should (not (getenv "PYTHONHOME")))
         (should (string= (getenv "VIRTUAL_ENV") "/env"))
-        (should (equal tramp-remote-process-environment process-environment))))
-    (should (equal tramp-remote-process-environment 
original-process-environment))))
+        (should (python--tests-process-env-eql
+                 tramp-remote-process-environment process-environment))))
+    (should (equal tramp-remote-process-environment
+                   original-process-environment))))
 
 (ert-deftest python-shell-with-environment-3 ()
   "Test `python-shell-with-environment' is idempotent."
@@ -2805,11 +2826,14 @@ if x:
          (python-shell-virtualenv-root "/home/user/env")
          (single-call
           (python-shell-with-environment
-            (list exec-path process-environment)))
+            (list exec-path
+                  (python--tests-process-env-canonical process-environment))))
          (nested-call
           (python-shell-with-environment
             (python-shell-with-environment
-              (list exec-path process-environment)))))
+              (list exec-path
+                    (python--tests-process-env-canonical
+                     process-environment))))))
     (should (equal single-call nested-call))))
 
 (ert-deftest python-shell-make-comint-1 ()
diff --git a/test/lisp/yank-media-tests.el b/test/lisp/yank-media-tests.el
new file mode 100644
index 0000000000..4487ae150d
--- /dev/null
+++ b/test/lisp/yank-media-tests.el
@@ -0,0 +1,38 @@
+;;; yank-media-tests.el --- Tests for yank-media.el  -*- lexical-binding: t; 
-*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'yank-media)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-utf-16 ()
+  (should-not (yank-media--utf-16-p "f"))
+  (should-not (yank-media--utf-16-p "fo"))
+  (should-not (yank-media--utf-16-p "\000ofo"))
+  (should (eq (yank-media--utf-16-p "\000o\000o") 'utf-16-be))
+  (should (eq (yank-media--utf-16-p "o\000o\000") 'utf-16-le))
+  (should-not (yank-media--utf-16-p "o\000\000o")))
+
+;;; yank-media-tests.el ends here
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 31a4b1ac71..c1e5d0ebed 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -101,7 +101,7 @@ with parameters from the *Messages* buffer modification."
 ;; | Overlay test setup
 ;; +==========================================================================+
 
-(eval-when-compile
+(eval-and-compile
   (defun buffer-tests--make-test-name (fn x y)
     (intern (format "buffer-tests--%s-%s-%s" fn x y))))
 
diff --git a/test/src/filelock-tests.el b/test/src/filelock-tests.el
index 21478a1a0f..97642669a0 100644
--- a/test/src/filelock-tests.el
+++ b/test/src/filelock-tests.el
@@ -31,26 +31,26 @@
 (require 'ert-x)
 (require 'seq)
 
-(defun filelock-tests--fixture (test-function)
-  "Call TEST-FUNCTION under a test fixture.
+(defmacro filelock-tests--fixture (&rest body)
+  "Call BODY under a test fixture.
 Create a test directory and a buffer whose `buffer-file-name' and
-`buffer-file-truename' are a file within it, then call
-TEST-FUNCTION.  Finally, delete the buffer and the test
-directory."
-  (ert-with-temp-directory temp-dir
-    (let ((name (concat (file-name-as-directory temp-dir)
-                        "userfile"))
-          (create-lockfiles t))
-      (with-temp-buffer
-        (setq buffer-file-name name
-              buffer-file-truename name)
-        (unwind-protect
-            (save-current-buffer
-              (funcall test-function))
-          ;; Set `buffer-file-truename' nil to prevent unlocking,
-          ;; which might prompt the user and/or signal errors.
-          (setq buffer-file-name nil
-                buffer-file-truename nil))))))
+`buffer-file-truename' are a file within it, then call BODY.
+Finally, delete the buffer and the test directory."
+  (declare (debug (body)))
+  `(ert-with-temp-directory temp-dir
+     (let ((name (concat (file-name-as-directory temp-dir)
+                         "userfile"))
+           (create-lockfiles t))
+       (with-temp-buffer
+         (setq buffer-file-name name
+               buffer-file-truename name)
+         (unwind-protect
+             (save-current-buffer
+               ,@body)
+           ;; Set `buffer-file-truename' nil to prevent unlocking,
+           ;; which might prompt the user and/or signal errors.
+           (setq buffer-file-name nil
+                 buffer-file-truename nil))))))
 
 (defun filelock-tests--make-lock-name (file-name)
   "Return the lock file name for FILE-NAME.
@@ -86,105 +86,132 @@ the case)."
 (ert-deftest filelock-tests-lock-unlock-no-errors ()
   "Check that locking and unlocking works without error."
   (filelock-tests--fixture
-   (lambda ()
-     (should-not (file-locked-p (buffer-file-name)))
+   (should-not (file-locked-p (buffer-file-name)))
 
-     ;; inserting text should lock the buffer's file.
-     (insert "this locks the buffer's file")
-     (filelock-tests--should-be-locked)
-     (unlock-buffer)
-     (set-buffer-modified-p nil)
-     (should-not (file-locked-p (buffer-file-name)))
+   ;; Inserting text should lock the buffer's file.
+   (insert "this locks the buffer's file")
+   (filelock-tests--should-be-locked)
+   (unlock-buffer)
+   (set-buffer-modified-p nil)
+   (should-not (file-locked-p (buffer-file-name)))
 
-     ;; `set-buffer-modified-p' should lock the buffer's file.
-     (set-buffer-modified-p t)
-     (filelock-tests--should-be-locked)
-     (unlock-buffer)
-     (should-not (file-locked-p (buffer-file-name)))
+   ;; `set-buffer-modified-p' should lock the buffer's file.
+   (set-buffer-modified-p t)
+   (filelock-tests--should-be-locked)
+   (unlock-buffer)
+   (should-not (file-locked-p (buffer-file-name)))
 
-     (should-not (file-locked-p (buffer-file-name))))))
+   (should-not (file-locked-p (buffer-file-name)))))
 
 (ert-deftest filelock-tests-lock-spoiled ()
-  "Check `lock-buffer' ."
+  "Check `lock-buffer'."
   (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
   (filelock-tests--fixture
-   (lambda ()
-     (filelock-tests--spoil-lock-file buffer-file-truename)
-     ;; FIXME: errors when locking a file are ignored; should they be?
-     (set-buffer-modified-p t)
-     (filelock-tests--unspoil-lock-file buffer-file-truename)
-     (should-not (file-locked-p buffer-file-truename)))))
+   (filelock-tests--spoil-lock-file buffer-file-truename)
+   ;; FIXME: errors when locking a file are ignored; should they be?
+   (set-buffer-modified-p t)
+   (filelock-tests--unspoil-lock-file buffer-file-truename)
+   (should-not (file-locked-p buffer-file-truename))))
 
 (ert-deftest filelock-tests-file-locked-p-spoiled ()
   "Check that `file-locked-p' fails if the lockfile is \"spoiled\"."
   (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
   (filelock-tests--fixture
-   (lambda ()
-     (filelock-tests--spoil-lock-file buffer-file-truename)
-     (let ((err (should-error (file-locked-p (buffer-file-name)))))
-       (should (equal (seq-subseq err 0 2)
-                      (if (eq system-type 'windows-nt)
-                          '(permission-denied "Testing file lock")
-                        '(file-error "Testing file lock"))))))))
+   (filelock-tests--spoil-lock-file buffer-file-truename)
+   (let ((err (should-error (file-locked-p (buffer-file-name)))))
+     (should (equal (seq-subseq err 0 2)
+                    (if (eq system-type 'windows-nt)
+                        '(permission-denied "Testing file lock")
+                      '(file-error "Testing file lock")))))))
 
 (ert-deftest filelock-tests-unlock-spoiled ()
   "Check that `unlock-buffer' fails if the lockfile is \"spoiled\"."
   (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
   (filelock-tests--fixture
-   (lambda ()
-     ;; Set the buffer modified with file locking temporarily
-     ;; disabled.
-     (let ((create-lockfiles nil))
-       (set-buffer-modified-p t))
-     (should-not (file-locked-p buffer-file-truename))
-     (filelock-tests--spoil-lock-file buffer-file-truename)
-
-     ;; Errors from `unlock-buffer' should call
-     ;; `userlock--handle-unlock-error' (bug#46397).
-     (let (errors)
-       (cl-letf (((symbol-function 'userlock--handle-unlock-error)
-                  (lambda (err) (push err errors))))
-         (unlock-buffer))
-       (should (consp errors))
-       (should (equal
-                (if (eq system-type 'windows-nt)
-                    '(permission-denied "Unlocking file")
-                  '(file-error "Unlocking file"))
-                (seq-subseq (car errors) 0 2)))
-       (should (equal (length errors) 1))))))
+   ;; Set the buffer modified with file locking temporarily disabled.
+   (let ((create-lockfiles nil))
+     (set-buffer-modified-p t))
+   (should-not (file-locked-p buffer-file-truename))
+   (filelock-tests--spoil-lock-file buffer-file-truename)
+
+   ;; Errors from `unlock-buffer' should call
+   ;; `userlock--handle-unlock-error' (bug#46397).
+   (cl-letf (((symbol-function 'userlock--handle-unlock-error)
+              (lambda (err) (signal (car err) (cdr err)))))
+     (should (equal
+              (if (eq system-type 'windows-nt)
+                  '(permission-denied "Unlocking file")
+                '(file-error "Unlocking file"))
+              (seq-subseq (should-error (unlock-buffer)) 0 2))))))
 
 (ert-deftest filelock-tests-kill-buffer-spoiled ()
   "Check that `kill-buffer' fails if a lockfile is \"spoiled\"."
   (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
   (filelock-tests--fixture
-   (lambda ()
-     ;; Set the buffer modified with file locking temporarily
-     ;; disabled.
-     (let ((create-lockfiles nil))
-       (set-buffer-modified-p t))
-     (should-not (file-locked-p buffer-file-truename))
-     (filelock-tests--spoil-lock-file buffer-file-truename)
-
-     ;; Kill the current buffer.  Because the buffer is modified Emacs
-     ;; will attempt to unlock it.  Temporarily bind `yes-or-no-p' to
-     ;; a function that fakes a "yes" answer for the "Buffer modified;
-     ;; kill anyway?" prompt.
-     ;;
-     ;; File errors from unlocking files should call
-     ;; `userlock--handle-unlock-error' (bug#46397).
-     (let (errors)
+   ;; Set the buffer modified with file locking temporarily disabled.
+   (let ((create-lockfiles nil))
+     (set-buffer-modified-p t))
+   (should-not (file-locked-p buffer-file-truename))
+   (filelock-tests--spoil-lock-file buffer-file-truename)
+
+   ;; Kill the current buffer.  Because the buffer is modified Emacs
+   ;; will attempt to unlock it.  Temporarily bind `yes-or-no-p' to a
+   ;; function that fakes a "yes" answer for the "Buffer modified;
+   ;; kill anyway?" prompt.
+   ;;
+   ;; File errors from unlocking files should call
+   ;; `userlock--handle-unlock-error' (bug#46397).
+   (cl-letf (((symbol-function 'yes-or-no-p) #'always)
+             ((symbol-function 'userlock--handle-unlock-error)
+              (lambda (err) (signal (car err) (cdr err)))))
+     (should (equal
+              (if (eq system-type 'windows-nt)
+                  '(permission-denied "Unlocking file")
+                '(file-error "Unlocking file"))
+              (seq-subseq (should-error (kill-buffer)) 0 2))))))
+
+(ert-deftest filelock-tests-detect-external-change ()
+  "Check that an external file modification is reported."
+  (skip-unless (not (eq system-type 'ms-dos))) ; no filelock support
+  (skip-unless (executable-find "touch"))
+  (skip-unless (executable-find "echo"))
+  (dolist (cl '(t nil))
+    (filelock-tests--fixture
+     (let ((create-lockfiles cl))
+       (write-region "foo" nil (buffer-file-name))
+       (revert-buffer nil 'noconfirm)
+       (should-not (file-locked-p (buffer-file-name)))
+
+       ;; Just changing the file modification on disk doesn't hurt,
+       ;; because file contents in buffer and on disk look equal.
+       (shell-command (format "touch %s" (buffer-file-name)))
+       (insert "bar")
+       (when cl (filelock-tests--should-be-locked))
+
+       ;; Bug#53207: with `create-lockfiles' nil, saving the buffer
+       ;; results in a prompt.
        (cl-letf (((symbol-function 'yes-or-no-p)
-                  (lambda (&rest _) t))
-                 ((symbol-function 'userlock--handle-unlock-error)
-                  (lambda (err) (push err errors))))
-         (kill-buffer))
-       (should (consp errors))
-       (should (equal
-                (if (eq system-type 'windows-nt)
-                    '(permission-denied "Unlocking file")
-                  '(file-error "Unlocking file"))
-                (seq-subseq (car errors) 0 2)))
-       (should (equal (length errors) 1))))))
+                  (lambda (_) (ert-fail "Test failed unexpectedly"))))
+         (save-buffer))
+       (should-not (file-locked-p (buffer-file-name)))
+
+       ;; Changing the file contents on disk hurts when buffer is
+       ;; modified.  There shall be a query, which we answer.
+       ;; *Messages* buffer is checked for prompt.
+       (shell-command (format "echo bar >>%s" (buffer-file-name)))
+       (cl-letf (((symbol-function 'read-char-choice)
+                  (lambda (prompt &rest _) (message "%s" prompt) ?y)))
+         (ert-with-message-capture captured-messages
+           ;; `ask-user-about-supersession-threat' does not work in
+           ;; batch mode, let's simulate interactiveness.
+           (let (noninteractive)
+             (insert "baz"))
+           (should (string-match-p
+                   (format
+                     "^%s changed on disk; really edit the buffer\\?"
+                     (file-name-nondirectory (buffer-file-name)))
+                    captured-messages))))
+       (when cl (filelock-tests--should-be-locked))))))
 
 (provide 'filelock-tests)
 ;;; filelock-tests.el ends here
diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el
index 0870dc9de4..6ff64d0431 100644
--- a/test/src/xdisp-tests.el
+++ b/test/src/xdisp-tests.el
@@ -170,4 +170,13 @@ int main () {
     (should (equal (get-display-property 2 'height) 2.0))
     (should (equal (get-display-property 2 'space-width) 20))))
 
+(ert-deftest test-messages-buffer-name ()
+  (should
+   (equal
+    (let ((messages-buffer-name "test-message"))
+      (message "foo")
+      (with-current-buffer messages-buffer-name
+        (buffer-string)))
+    "foo\n")))
+
 ;;; xdisp-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]