emacs-diffs
[Top][All Lists]
Advanced

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

scratch/pkg fe600979521 4/5: Merge remote-tracking branch 'origin/master


From: Gerd Moellmann
Subject: scratch/pkg fe600979521 4/5: Merge remote-tracking branch 'origin/master' into scratch/pkg
Date: Tue, 22 Aug 2023 10:29:50 -0400 (EDT)

branch: scratch/pkg
commit fe6009795211844ae2deda602c197cb57265eb64
Merge: ba213150c59 18c85306ac2
Author: Gerd Möllmann <gerd@gnu.org>
Commit: Gerd Möllmann <gerd@gnu.org>

    Merge remote-tracking branch 'origin/master' into scratch/pkg
---
 .gitattributes                                     |   28 +-
 .gitignore                                         |    2 +
 .mailmap                                           |    5 +-
 ChangeLog.1                                        |   14 +-
 ChangeLog.android                                  | 4865 +++++++++-----------
 INSTALL                                            |   17 +-
 Makefile.in                                        |    2 +-
 admin/MAINTAINERS                                  |    6 +
 admin/emake                                        |   47 +-
 admin/git-bisect-start                             |   21 +-
 admin/merge-gnulib                                 |    9 +-
 admin/notes/copyright                              |    2 +-
 admin/notes/unicode                                |   24 +-
 autogen.sh                                         |    7 +
 build-aux/config.guess                             |   33 +-
 build-aux/config.sub                               |   37 +-
 build-aux/git-hooks/pre-commit                     |    8 +
 build-aux/git-hooks/prepare-commit-msg             |    4 +
 build-aux/make-info-dir                            |    2 +-
 configure.ac                                       |   78 +-
 cross/Makefile.in                                  |   16 +-
 doc/emacs/ChangeLog.1                              |   36 +-
 doc/emacs/ack.texi                                 |    2 +-
 doc/emacs/android.texi                             |    8 +-
 doc/emacs/dired.texi                               |   17 +-
 doc/emacs/input.texi                               |    4 +-
 doc/emacs/mini.texi                                |    4 +-
 doc/lispref/ChangeLog.1                            |    8 +-
 doc/lispref/commands.texi                          |   19 +-
 doc/lispref/files.texi                             |   11 +-
 doc/lispref/os.texi                                |   85 +-
 doc/misc/calc.texi                                 |    4 +-
 doc/misc/eglot.texi                                |    7 +-
 doc/misc/eshell.texi                               |   55 +-
 doc/misc/eww.texi                                  |   13 +-
 doc/misc/gnus.texi                                 |    4 +-
 doc/misc/texinfo.tex                               |  257 +-
 doc/misc/tramp.texi                                |    5 +-
 etc/ChangeLog.1                                    |   30 +-
 etc/DEBUG                                          |  189 +-
 etc/MACHINES                                       |    8 +
 etc/NEWS                                           |   92 +-
 etc/NEWS.28                                        |    2 +-
 etc/NEWS.29                                        |  742 +--
 etc/PROBLEMS                                       |  139 +-
 etc/TODO                                           |   13 +
 etc/themes/leuven-dark-theme.el                    |    2 +-
 exec/configure.ac                                  |    4 +-
 exec/exec.c                                        |   79 +-
 exec/mipsel-user.h                                 |    1 -
 java/AndroidManifest.xml.in                        |    7 +-
 java/INSTALL                                       |   59 +-
 java/org/gnu/emacs/EmacsDesktopNotification.java   |  175 +
 java/org/gnu/emacs/EmacsDialog.java                |    1 +
 java/org/gnu/emacs/EmacsSafThread.java             |   88 +-
 java/org/gnu/emacs/EmacsService.java               |   83 +-
 java/org/gnu/emacs/EmacsWindow.java                |    2 +-
 java/res/drawable/emacs_background.xml             |   42 +
 java/res/drawable/emacs_foreground.xml             |   53 +
 java/res/layout/sdk8_notifications_view.xml        |   33 +
 .../res/mipmap-v26/emacs_icon.xml                  |   36 +-
 java/res/mipmap/emacs_icon.png                     |  Bin 0 -> 13462 bytes
 java/res/values/strings.xml                        |    2 +-
 lib-src/ChangeLog.1                                |    4 +-
 lib/boot-time-aux.h                                |  317 ++
 lib/boot-time.c                                    |  287 ++
 lib/boot-time.h                                    |   44 +
 lib/diffseq.h                                      |   24 +-
 lib/gnulib.mk.in                                   |   29 +-
 lib/nproc.c                                        |    4 +-
 lib/readutmp.h                                     |  334 ++
 lib/stpncpy.c                                      |   92 -
 lib/time.in.h                                      |   81 +
 lisp/ChangeLog.13                                  |   40 +-
 lisp/ChangeLog.14                                  |   36 +-
 lisp/ChangeLog.15                                  |    2 +-
 lisp/ChangeLog.17                                  |   22 +-
 lisp/ChangeLog.3                                   |  150 +-
 lisp/ChangeLog.4                                   |    8 +-
 lisp/ChangeLog.5                                   |    2 +-
 lisp/ChangeLog.6                                   |    2 +-
 lisp/ChangeLog.7                                   |    4 +-
 lisp/Makefile.in                                   |    4 -
 lisp/auth-source.el                                |  106 +-
 lisp/calendar/cal-move.el                          |    6 +-
 lisp/calendar/calendar.el                          |   20 +-
 lisp/calendar/holidays.el                          |    4 +-
 lisp/calendar/lunar.el                             |    2 +-
 lisp/comint.el                                     |    4 +-
 lisp/cus-edit.el                                   |    2 +-
 lisp/dired-aux.el                                  |  172 +-
 lisp/dired.el                                      |   30 +-
 lisp/doc-view.el                                   |    2 +-
 lisp/emacs-lisp/byte-opt.el                        |   47 +-
 lisp/emacs-lisp/bytecomp.el                        |   89 +-
 lisp/emacs-lisp/cl-generic.el                      |    8 +-
 lisp/emacs-lisp/cl-indent.el                       |    2 +-
 lisp/emacs-lisp/cl-macs.el                         |   23 +-
 lisp/emacs-lisp/comp.el                            |   31 +-
 lisp/emacs-lisp/ert.el                             |    4 +-
 lisp/emacs-lisp/find-func.el                       |    2 +-
 lisp/emacs-lisp/lisp-mnt.el                        |   10 +-
 lisp/emacs-lisp/macroexp.el                        |   69 +-
 lisp/emacs-lisp/package.el                         |  118 +-
 lisp/emacs-lisp/pp.el                              |    6 +-
 lisp/emacs-lisp/rx.el                              |  576 ++-
 lisp/erc/erc-button.el                             |   13 +-
 lisp/erc/erc-fill.el                               |   77 +-
 lisp/erc/erc-goodies.el                            |    4 +-
 lisp/eshell/em-unix.el                             |  106 +-
 lisp/eshell/esh-arg.el                             |    2 +-
 lisp/eshell/esh-cmd.el                             |  190 +-
 lisp/faces.el                                      |    7 +-
 lisp/ffap.el                                       |    8 +-
 lisp/files.el                                      |   39 +-
 lisp/finder.el                                     |    2 +-
 lisp/gnus/nnspool.el                               |    6 +-
 lisp/help-fns.el                                   |   19 +-
 lisp/help.el                                       |    2 +-
 lisp/ielm.el                                       |    5 +-
 lisp/image/image-dired.el                          |   20 +
 lisp/indent-aux.el                                 |   76 +
 lisp/info.el                                       |    2 +-
 lisp/international/iso-transl.el                   |    4 +
 lisp/isearch.el                                    |   13 +-
 lisp/kmacro.el                                     |   17 +-
 lisp/language/tibetan.el                           |   32 +-
 lisp/ldefs-boot.el                                 |  191 +-
 lisp/loadhist.el                                   |    2 +-
 lisp/loadup.el                                     |   11 +-
 lisp/mail/emacsbug.el                              |   10 +-
 lisp/mail/supercite.el                             |    3 -
 lisp/net/dictionary.el                             |   96 +-
 lisp/net/eww.el                                    |   47 +-
 lisp/net/newst-plainview.el                        |    4 +-
 lisp/net/tramp-adb.el                              |    2 +
 lisp/net/tramp-message.el                          |   88 +-
 lisp/net/tramp-sh.el                               |  152 +-
 lisp/net/tramp-smb.el                              |    2 +
 lisp/net/tramp-sshfs.el                            |    4 +-
 lisp/net/tramp.el                                  |   48 +-
 lisp/org/ob-tangle.el                              |    2 +-
 lisp/org/ol-bibtex.el                              |    5 +-
 lisp/org/org-clock.el                              |   15 +
 lisp/org/org-colview.el                            |    1 +
 lisp/org/org-element.el                            |    7 +-
 lisp/org/org-num.el                                |    1 +
 lisp/org/org-table.el                              |    2 +
 lisp/org/org-version.el                            |    2 +-
 lisp/org/org.el                                    |    7 +
 lisp/org/ox-publish.el                             |    3 +-
 lisp/org/ox.el                                     |    7 +-
 lisp/pcmpl-unix.el                                 |    2 +-
 lisp/pcomplete.el                                  |   13 +-
 lisp/pixel-scroll.el                               |  111 +-
 lisp/play/cookie1.el                               |    2 +-
 lisp/progmodes/asm-mode.el                         |    4 +-
 lisp/progmodes/compile.el                          |   13 +-
 lisp/progmodes/csharp-mode.el                      |   11 +-
 lisp/progmodes/eglot.el                            |    6 +-
 lisp/progmodes/elisp-mode.el                       |   23 +-
 lisp/progmodes/gud.el                              |    2 +-
 lisp/progmodes/idlwave.el                          |   10 +-
 lisp/progmodes/js.el                               |    2 +-
 lisp/progmodes/make-mode.el                        |    2 +-
 lisp/progmodes/project.el                          |   32 +-
 lisp/progmodes/python.el                           |    4 +
 lisp/progmodes/sql.el                              |    6 +-
 lisp/progmodes/xref.el                             |    3 +-
 lisp/server.el                                     |   23 +-
 lisp/shell.el                                      |    2 +
 lisp/simple.el                                     |    2 -
 lisp/startup.el                                    |   13 +-
 lisp/subr.el                                       |  138 +-
 lisp/term.el                                       |   12 +-
 lisp/term/AT386.el                                 |    2 +-
 lisp/textmodes/reftex-index.el                     |    6 +-
 lisp/textmodes/reftex-ref.el                       |    2 +-
 lisp/textmodes/reftex-toc.el                       |   31 +-
 lisp/textmodes/reftex.el                           |   38 +-
 lisp/tooltip.el                                    |    2 +-
 lisp/touch-screen.el                               |   37 +-
 lisp/type-break.el                                 |   25 +-
 lisp/use-package/use-package-core.el               |   24 +-
 lisp/vc/vc-git.el                                  |    6 +-
 lisp/vc/vc-hooks.el                                |    3 +-
 lisp/version.el                                    |   16 +-
 lisp/wid-edit.el                                   |   53 +-
 m4/clock_time.m4                                   |   32 +-
 m4/gnulib-comp.m4                                  |   17 +-
 m4/mktime.m4                                       |    3 +-
 m4/nanosleep.m4                                    |    6 +-
 m4/ndk-build.m4                                    |    3 +-
 m4/readutmp.m4                                     |  121 +
 m4/stdalign.m4                                     |   10 +-
 m4/stdint.m4                                       |    7 +-
 m4/stpncpy.m4                                      |  108 -
 m4/time_h.m4                                       |   35 +-
 m4/time_r.m4                                       |    4 +-
 m4/timegm.m4                                       |    3 +-
 msdos/sed1v2.inp                                   |    1 +
 msdos/sedlibmk.inp                                 |    1 +
 nt/inc/ms-w32.h                                    |   12 -
 src/ChangeLog.3                                    |   36 +-
 src/Makefile.in                                    |    4 +-
 src/android-emacs.c                                |   25 +-
 src/android.c                                      |  108 +-
 src/android.h                                      |    2 +
 src/androidfns.c                                   |    9 +-
 src/androidselect.c                                |  297 ++
 src/androidterm.c                                  |   12 +-
 src/androidvfs.c                                   |  290 +-
 src/callproc.c                                     |    9 +-
 src/data.c                                         |   19 +-
 src/editfns.c                                      |   16 +-
 src/emacs.c                                        |   24 +-
 src/eval.c                                         |    4 +
 src/fileio.c                                       |  297 +-
 src/filelock.c                                     |  180 +-
 src/fns.c                                          |    3 +
 src/haiku_io.c                                     |    2 +
 src/haiku_select.cc                                |  146 +-
 src/haiku_support.cc                               |   54 +-
 src/haiku_support.h                                |    7 +
 src/haikuselect.c                                  |  125 +
 src/haikuselect.h                                  |   25 +-
 src/haikuterm.c                                    |   13 +
 src/image.c                                        |   92 +-
 src/lread.c                                        |    9 +-
 src/nsfns.m                                        |   29 +-
 src/nsimage.m                                      |    4 +
 src/pdumper.c                                      |    2 +-
 src/pgtkterm.c                                     |   19 +-
 src/process.c                                      |   27 +-
 src/sfnt.c                                         |  522 ++-
 src/sfnt.h                                         |   24 +-
 src/sfntfont-android.c                             |    3 +-
 src/sfntfont.c                                     |   58 +-
 src/sfntfont.h                                     |    3 +-
 src/sysdep.c                                       |   13 +-
 src/termhooks.h                                    |    6 +
 src/textconv.c                                     |  169 +-
 src/xdisp.c                                        |   38 +-
 src/xmenu.c                                        |   17 +-
 src/xterm.c                                        |  190 +-
 test/Makefile.in                                   |    3 +
 test/lisp/auth-source-tests.el                     |   20 +
 test/lisp/calc/calc-tests.el                       |    4 +-
 test/lisp/calculator-tests.el                      |    6 +
 test/lisp/cus-edit-tests.el                        |   43 +
 test/lisp/dired-tests.el                           |    4 +-
 .../warn-make-process-missing-keyword-arg.el       |    3 +
 .../warn-make-process-missing-keyword-value.el     |    3 +
 .../warn-make-process-repeated-keyword-arg.el      |    3 +
 .../warn-make-process-unknown-keyword-arg.el       |    4 +
 test/lisp/emacs-lisp/bytecomp-tests.el             |   37 +-
 test/lisp/emacs-lisp/cl-macs-tests.el              |   17 +
 test/lisp/emacs-lisp/rx-tests.el                   |   94 +-
 test/lisp/erc/erc-scenarios-base-renick.el         |    4 +-
 .../erc/resources/base/netid/bouncer/barnet.eld    |   12 +-
 .../erc/resources/base/netid/bouncer/foonet.eld    |   12 +-
 test/lisp/erc/resources/base/reconnect/options.eld |   10 +-
 .../base/renick/queries/bouncer-barnet.eld         |   14 +-
 .../base/renick/queries/bouncer-foonet.eld         |   12 +-
 test/lisp/erc/resources/erc-scenarios-common.el    |    2 +-
 .../erc/resources/services/auth-source/libera.eld  |   10 +-
 test/lisp/eshell/em-extpipe-tests.el               |   25 +-
 test/lisp/eshell/em-unix-tests.el                  |   68 +
 test/lisp/eshell/eshell-tests.el                   |    9 +-
 test/lisp/files-tests.el                           |   16 +-
 test/lisp/minibuffer-tests.el                      |    2 +-
 test/lisp/net/tramp-archive-tests.el               |   15 +-
 test/lisp/net/tramp-tests.el                       |   30 +-
 test/lisp/progmodes/python-tests.el                |   12 +-
 test/lisp/server-tests.el                          |   12 +-
 test/lisp/wid-edit-tests.el                        |   31 +
 test/src/comp-tests.el                             |    7 +-
 test/src/data-tests.el                             |   25 +
 test/src/keyboard-tests.el                         |    5 +
 test/src/syntax-tests.el                           |    3 +-
 280 files changed, 9588 insertions(+), 6788 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index d9288b27d0f..b56f0ec617d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -17,13 +17,11 @@
 # You should have received a copy of the GNU General Public License
 # along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
 
-# A few files use CRLF endings, even on non-Microsoft platforms.
+# A few UTF-8-compatible text files use CRLF endings,
+# even on non-Microsoft platforms.
 # Do not warn about trailing whitespace with these files.
 *.bat whitespace=cr-at-eol
 admin/charsets/mapfiles/PTCP154 whitespace=cr-at-eol
-leim/MISC-DIC/cangjie-table.b5 whitespace=cr-at-eol
-leim/MISC-DIC/cangjie-table.cns whitespace=cr-at-eol
-leim/MISC-DIC/pinyin.map whitespace=cr-at-eol
 test/manual/etags/c-src/dostorture.c whitespace=cr-at-eol
 test/manual/etags/cp-src/c.C whitespace=cr-at-eol
 test/manual/etags/html-src/algrthms.html whitespace=cr-at-eol
@@ -31,19 +29,41 @@ test/manual/etags/html-src/algrthms.html 
whitespace=cr-at-eol
 # The todo-mode file format includes trailing whitespace.
 *.tod[aorty] -whitespace=blank-at-eol
 
+# The following text files use encodings incompatible with UTF-8.
+# They should not be treated as text when diffing, as that could
+# cause the output to mix encodings.
+*.tit -diff
+admin/charsets/mapfiles/cns2ucsdkw.txt -diff
+leim/MISC-DIC/CTLau* -diff
+leim/MISC-DIC/cangjie-table.* -diff
+leim/MISC-DIC/pinyin.map -diff
+leim/MISC-DIC/ziranma.cin -diff
+leim/SKK-DIC/SKK-JISYO.L -diff
+src/msdos.c -diff
+test/lisp/gnus/mm-decode-resources/win1252-multipart.bin -diff
+
 # Some files should not be treated as text when diffing or merging.
+*.bmp binary
 *.cur binary
+*.gif binary
 *.gpg binary
 *.gz binary
 *.icns binary
 *.ico binary
+*.jpg binary
+*.kbx binary
+*.key binary
 *.pbm binary
 *.pdf binary
 *.pif binary
 *.png binary
 *.sig binary
 *.tiff binary
+*.webp binary
+*.zip binary
 etc/e/eterm-color binary
+etc/e/eterm-direct binary
+java/emacs.keystore binary
 
 # Git's builtin diff hunk header styles.
 *.ad[abs] diff=ada
diff --git a/.gitignore b/.gitignore
index 4717611ab8c..ca89bc47f79 100644
--- a/.gitignore
+++ b/.gitignore
@@ -375,11 +375,13 @@ _gdb_history
 *.desktop
 
 # Files ignored in exec/.
+exec/aclocal.m4
 exec/config.status
 exec/loader
 exec/test
 exec/exec1
 exec/deps/*
+exec/aclocal.m4
 exec/autom4te.cache
 exec/config.h
 exec/config.h.in
diff --git a/.mailmap b/.mailmap
index 8454eb9154c..f14f086b2e5 100644
--- a/.mailmap
+++ b/.mailmap
@@ -51,8 +51,7 @@ David M. Koppelman <koppel@ece.lsu.edu>
 Deniz Dogan <deniz@dogan.se> <deniz.a.m.dogan@gmail.com>
 Dick R. Chiang <dick.r.chiang@gmail.com>
 Dick R. Chiang <dick.r.chiang@gmail.com> dickmao <none>
-Earl Hyatt <ej32u@protonmail.com>
-Earl Hyatt <ej32u@protonmail.com> <okamsn@protonmail.com>
+Earl Hyatt <okamsn@protonmail.com> <ej32u@protonmail.com>
 Edward M. Reingold <reingold@emr.cs.iit.edu>
 Eli Zaretskii <eliz@gnu.org> <eliz@is.elta.co.il>
 Emilio C. Lopes <eclig@gmx.net>
@@ -61,7 +60,7 @@ Era Eriksson <era+emacs@iki.fi> <era+emacsbugs@iki.fi>
 Eric Ludlam <zappo@gnu.org>
 Eric Ludlam <zappo@gnu.org> <eric@siege-engine.com>
 Eric Ludlam <zappo@gnu.org> <ericludlam@gmail.com>
-Eric S. Raymond <esr@thyrsus.com> <esr@snark.thyrsus.com>
+Eric S. Raymond <esr@thyrsus.com>
 Etienne Prud’homme <e.e.f.prudhomme@gmail.com>
 Fabián Ezequiel Gallina <fgallina@gnu.org> <fgallina@cuca>
 Fabián Ezequiel Gallina <fgallina@gnu.org> <galli.87@gmail.com>
diff --git a/ChangeLog.1 b/ChangeLog.1
index fcfae7c3883..654cb43d4dc 100644
--- a/ChangeLog.1
+++ b/ChangeLog.1
@@ -7582,7 +7582,7 @@
 
        * INSTALL.CVS: Clarify why `make bootstrap' sometimes fails.
 
-2008-06-08  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-06-08  Eric S. Raymond  <esr@thyrsus.com>
 
        * INSTALL.CVS: Indicate when "cvs update -d" may be needed.
 
@@ -9672,7 +9672,7 @@
        * configure.in: New entry for HP/UX-11.
 
        * Makefile.in (SOURCES): Replace GETTING.GNU.SOFTWARE with FTP.
-       From Eric S. Raymond <esr@golux.thyrsus.com>.
+       From Eric S. Raymond <esr@thyrsus.com>.
 
 2001-10-28  Eli Zaretskii  <eliz@is.elta.co.il>
 
@@ -13896,7 +13896,7 @@
        places.  Implement them by setting C_SWITCH_X_SITE and
        LD_SWITCH_X_SITE in src/config.h.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * make-dist: Don't distribute etc/Old files.
 
@@ -13907,7 +13907,7 @@
 
        * make-dist: Fix typo.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * make-dist: Corrected typo, fixed it to discard = and TAGS files
        in some cases where it should but didn't seen to.
@@ -13924,11 +13924,11 @@
        * configure: Recognize rs6000-ibm-aix32 and rs6000-ibm-aix, and
        make rs6000-ibm-aix default to -aix32.
 
-1993-03-17  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * Makefile.in: Added `Developer's configuration' section.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * Makefile.in: Add commented-out variable settings for developer's
        configuration.
@@ -14299,7 +14299,7 @@
        return handler, make a copy of it, not a symbolic link to it; that
        way, it will work on systems that don't have symbolic links.
 
-1992-08-14  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-08-14  Eric S. Raymond  (esr@thyrsus.com)
 
        * make-dist: Taught it about vcdiff and rcs2log, added --newer
        option for generating incremental distributions.  Stopped it from
diff --git a/ChangeLog.android b/ChangeLog.android
index 3cb88b6f10c..f56c0469408 100644
--- a/ChangeLog.android
+++ b/ChangeLog.android
@@ -39,29 +39,25 @@
 
 2023-08-04  Po Lu  <luangruo@yahoo.com>
 
-       Optimize creation of multibyte menu items on Android
        * src/androidvfs.c (android_verify_jni_string): Move to
        android.c.
+
        * src/android.c (android_verify_jni_string): New function.
        (android_build_string): Forgo encoding menu text if TEXT is a
        multibyte string that's also a valid JNI string.
+
        * src/android.h: Update prototypes.
 
-       Avoid encoding commonplace characters in tree names
        * java/org/gnu/emacs/EmacsService.java (getDocumentTrees): Don't
        encode some characters that need not be escaped within file
        names.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-08-03  Po Lu  <luangruo@yahoo.com>
 
        * src/fileio.c (check_vfs_filename): Revert earlier change.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Isolate fchmodat within the Android VFS layer
        * src/android.h: Update prototypes.
+
        * src/androidvfs.c (unix_vfs_ops, android_unix_chmod, afs_vfs_ops)
        (android_afs_chmod, content_vfs_ops, android_content_chmod)
        (authority_vfs_ops, android_authority_chmod, saf_root_vfs_ops)
@@ -70,61 +66,56 @@
        (root_vfs_ops): Add `chmod' to the list of functions implemented
        by each vnode.
        (android_fchmodat): New function.
+
        * src/fileio.c (Fset_file_modes): Use `emacs_fchmodat'.
+
        * src/lisp.h:
        * src/sysdep.c (emacs_fchmodat): Delegate to android_fchmodat on
        Android.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsSafThread.java (CacheToplevel):
-       (EmacsSafThread):
-       (DocIdEntry):
-       (getCache):
-       (pruneCache):
-       (cacheDirectoryFromCursor):
-       (run):
-       (documentIdFromName1):
-       (statDocument1):
-       (openDocumentDirectory1):
-       (openDocument1): Introduce a file status cache and populate
-       it with files within directories as they are opened.
-       * java/org/gnu/emacs/EmacsService.java (createDocument):
-       (createDirectory):
-       (moveDocument): Invalidate the file status cache wherever
-       needed.
+       * java/org/gnu/emacs/EmacsSafThread.java (CacheToplevel)
+       (EmacsSafThread, DocIdEntry, getCache, pruneCache)
+       (cacheDirectoryFromCursor, run, documentIdFromName1)
+       (statDocument1, openDocumentDirectory1, openDocument1): Introduce
+       a file status cache and populate it with files within directories
+       as they are opened.
+
+       * java/org/gnu/emacs/EmacsService.java (createDocument)
+       (createDirectory, moveDocument): Invalidate the file status cache
+       wherever needed.
+
        * src/fileio.c (check_vfs_filename):
        (Fset_file_modes): Permit `set-file-modes' to silently fail
        on asset and content files.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-08-02  Po Lu  <luangruo@yahoo.com>
 
-       Fix reporting of key events containing SYM and META
-       * doc/emacs/android.texi (Android)::(What is Android?):
-       (Android Startup, Android File System, Android Environment)
-       (Android Windowing, Android Fonts, Android Troubleshooting):
-       Improve section titles.
+       * doc/emacs/android.texi (Android, What is Android?, Android
+       Startup, Android File System, Android Environment,Android
+       Windowing, Android Fonts, Android Troubleshooting): Improve
+       section titles.
        (Android Windowing): Describe the relation between keyboard
        modifiers reported by Android and those in key events.
+
        * java/org/gnu/emacs/EmacsWindow.java (onKeyDown, onKeyUp):
        Clear META_SYM_ON and META_META_MASK when retrieving ASCII
        characters.
+
        * src/androidgui.h: Add ANDROID_META_MASK.
+
        * src/androidterm.c (android_android_to_emacs_modifiers)
        (android_emacs_to_android_modifiers): Transform META to Alt, and
        vice versa.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-08-01  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/android.texi (Android File System): Describe how to
        access real files named /assets or /contents if so required.
+
        * java/org/gnu/emacs/EmacsService.java (validAuthority):
        * src/android.c (android_init_emacs_service):
        * src/android.h: New function.
+
        * src/androidvfs.c (android_saf_valid_authority_p): New
        function.  Wrap the Java function.
        (android_saf_root_stat, android_saf_root_access): Don't return
@@ -132,51 +123,45 @@
        (android_saf_tree_from_name): Check validity of string data
        before giving it to JNI.
 
-       Micro-optimize PUSHW/PUSHB
        * src/sfnt.c (CHECK_STACK_AVAILABLE): New macro.
-       (PUSH):
-       (PUSH_UNCHECKED): Always define to unchecked versions,
+       (PUSH, PUSH_UNCHECKED): Always define to unchecked versions,
        even if TEST.
        (PUSH2_UNCHECKED): New macro.
-       (NPUSHB):
-       (NPUSHW):
-       (PUSHB):
-       (PUSHW): Check the number of remaining stack elements
-       once.
+       (NPUSHB, NPUSHW, PUSHB, PUSHW): Check the number of remaining
+       stack elements once.
        (stack_overflow_test_args): Expect zero stack arguments.
 
        * src/android.c (ANDROID_THROW): Remove unused macro.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-31  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * src/sfnt.c (ISECT): Micro-optimize this instruction.
-       * src/sfntfont.c (sfnt_parse_style): Avoid GC safety problem.
 
-       Update Android port
-       * src/sfntfont.c (sfnt_parse_style): Fix misworded commentary.
+       * src/sfntfont.c (sfnt_parse_style): Avoid GC safety problem.
+       (sfnt_parse_style): Fix misworded commentary.
 
-       Initialize Android API level earlier
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative):
        * java/org/gnu/emacs/EmacsNoninteractive.java (main):
        * java/org/gnu/emacs/EmacsService.java (run):
        * java/org/gnu/emacs/EmacsThread.java (run):
        * src/android.c (initEmacs, setEmacsParams): Set
        `android_api_level' within setEmacsParams, not in initEmacs.
+
        * src/androidvfs.c: Pacify compiler warnings.
 
-       Implement cross-directory SAF rename operations
        * java/org/gnu/emacs/EmacsService.java (renameDocument): Don't
        catch UnsupportedOperationException; handle ENOSYS in
        android_saf_rename_document instead.
        (moveDocument): New function.
+
        * lisp/subr.el (y-or-n-p): Always change the text conversion
        style.
+
        * src/android.c (android_init_emacs_service)
        (android_exception_check_4): New function.
+
        * src/android.h: Update Java function table.
+
        * src/androidvfs.c (android_saf_rename_document): Handle ENOSYS
        here by setting errno to EXDEV.
        (android_saf_move_document): New function.
@@ -184,40 +169,36 @@
        (android_saf_tree_rename): Use delete-move-rename to implement
        cross-directory renames.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-30  Po Lu  <luangruo@yahoo.com>
 
-       Partially implement rename operations on SAF files
        * java/org/gnu/emacs/EmacsSafThread.java
        (postInvalidateCacheDir):
        * java/org/gnu/emacs/EmacsService.java (renameDocument): New
        functions.
+
        * src/android.c (android_init_emacs_service):
        * src/android.h (struct android_emacs_service): Link to new JNI
        function.
+
        * src/androidvfs.c (android_saf_rename_document): New function.
        (android_saf_tree_rename): Implement in terms of that function
        if possible.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-29  Po Lu  <luangruo@yahoo.com>
 
-       Correct directory permissions reported for VFS files
        * java/org/gnu/emacs/EmacsSafThread.java (statDocument1):
+
        * src/androidvfs.c (android_afs_stat, android_content_stat)
        (android_saf_root_stat): Report search permissions for files.
 
-       Update Android port
        * src/androidvfs.c: Improve commentary.
 
 2023-07-29  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsSafThread.java (postInvalidateCache):
        New argument cacheName.  Remove that file from the cache.
        (accessDocument1): Consult the storage cache as well.
+
        * java/org/gnu/emacs/EmacsService.java (deleteDocument): New
        argument NAME.
 
@@ -228,62 +209,57 @@
 
 2023-07-29  Po Lu  <luangruo@yahoo.com>
 
-       ; Update Android port
        * src/androidvfs.c (android_saf_exception_check): Describe
        exceptions earlier.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsSafThread.java (DocIdEntry):
-       (getCacheEntry):
-       (CacheEntry):
-       (documentIdFromName1): Fix earlier change.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/org/gnu/emacs/EmacsSafThread.java (DocIdEntry)
+       (getCacheEntry, CacheEntry, documentIdFromName1): Fix earlier
+       change.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsSafThread.java (DocIdEntry)
        (getCacheEntry, CacheEntry): Use `uptimeMillis' as the basis for
        cache expiration.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsSafThread.java (EmacsSafThread, getCache)
        (pruneCache1, pruneCache, cacheChild, cacheDirectoryFromCursor)
        (documentIdFromName1, openDocumentDirectory1): Implement the
        cache referred to by the commentary.
+
        * java/org/gnu/emacs/EmacsService.java (deleteDocument):
        Invalidate the cache upon document removal.
+
        * src/androidvfs.c (android_saf_exception_check)
        (android_document_id_from_name): Correctly preserve or set errno
        in error cases.
 
 2023-07-28  Po Lu  <luangruo@yahoo.com>
 
-       Fix SAF query
        * java/org/gnu/emacs/EmacsSafThread.java (documentIdFromName1):
        Fix query argument placeholder string.
 
-       Update Android port
        * src/androidvfs.c (android_document_id_from_name): Don't return
        0 if an SAF exception occurs.
 
-       Avoid crashes when the primary clip is empty
        * src/androidselect.c (Fandroid_get_clipboard): Don't return
        data if clipboard is empty.  Reported by Johan Widén
        <j.e.widen@gmail.com>.
 
 2023-07-28  Po Lu  <luangruo@yahoo.com>
 
-       Allow quitting from Android content provider operations
        * doc/emacs/android.texi (Android Document Providers): Say that
        quitting is now possible.
+
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
        functions `safSyncAndReadInput', `safync' and `safPostRequest'.
+
        * java/org/gnu/emacs/EmacsSafThread.java: New file.  Move
        cancel-able SAF operations here.
+
        * java/org/gnu/emacs/EmacsService.java (EmacsService): Allow
        quitting from most SAF operations.
-       * src/androidvfs.c (android_saf_exception_check): Return EINTR
-       if OperationCanceledException is received.
+
+       * src/androidvfs.c (android_saf_exception_check): Return EINTR if
+       OperationCanceledException is received.
        (android_saf_stat, android_saf_access)
        (android_document_id_from_name, android_saf_tree_opendir_1)
        (android_saf_file_open): Don't allow reentrant calls from async
@@ -292,20 +268,24 @@
        (android_vfs_init): Initialize new class.
 
        * src/dired.c (open_directory): Handle EINTR from opendir.
+
        * src/sysdep.c: Describe which operations may return EINTR on
        Android.
 
 2023-07-28  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsDirectoryEntry.java
        (EmacsDirectoryEntry): Make class final.
+
        * java/org/gnu/emacs/EmacsService.java (accessDocument)
        (openDocumentDirectory, openDocument, createDocument): Throw
        access and IO error exceptions instead of catching them.
        (createDirectory, deleteDocument): New functions.
+
        * src/android.c (android_init_emacs_service): Add new functions.
+
        * src/android.h (struct android_emacs_service): Likewise.
+
        * src/androidvfs.c (android_saf_exception_check): New function.
        Translate between Java exceptions and errno values.
        (android_saf_stat, android_saf_access, android_saf_delete_document)
@@ -319,13 +299,11 @@
        (android_vfs_init): Initialize exception classes.
        (android_mkdir, android_fstat): Remove trailing whitespace.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-27  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/android.texi (Android Document Providers): Improve
        wording of paragraph clarifying limits on subprocesses.
+
        * java/org/gnu/emacs/EmacsService.java (getDocumentTrees): Use
        Java standard US-ASCII coding standard instead of the
        undocumented ``ASCII'' alias.
@@ -333,78 +311,88 @@
        (documentIdFromName):
        * src/android.c (android_init_emacs_service): Take a String for
        NAME instead of a byte array.
+
        * src/androidvfs.c (android_verify_jni_string): New function.
        (android_document_id_from_name): Verify that STRING is a valid
        Modified UTF-8 string.
 
-       Update Android port
-       * src/androidvfs.c (android_afs_initial):
-       (android_content_get_directory_name):
-       (android_saf_tree_name):
-       (android_saf_tree_from_name):
-       (android_vfs_init): Silence compiler warnings.
+       * src/androidvfs.c (android_afs_initial)
+       (android_content_get_directory_name, android_saf_tree_name)
+       (android_saf_tree_from_name, android_vfs_init): Silence compiler
+       warnings.
 
-       Update Android port
        * src/android.c (android_run_in_emacs_thread): Behave more
        robustly if SIGIO arrives too late Emacs for Emacs to check for
        signals, but too early to preempt a long running syscall.
 
-       Avoid crashes in some edge cases
        * java/org/gnu/emacs/EmacsActivity.java (onActivityResult):
-       Avoid crashes in some edge cases.
 
-       Avoid dereference of a freed vnode's operations table
-       * src/androidvfs.c (android_renameat_noreplace):
-       (android_rename): Free vdst using vdst->ops, not vp->ops.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/androidvfs.c (android_renameat_noreplace, android_rename):
+       Free vdst using vdst->ops, not vp->ops.
 
 2023-07-27  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * configure.ac (ANDROID_STUBIFY): Add androidvfs.o when building
        libemacs.so.
-       * doc/emacs/android.texi (Android): Add `Android Document Providers'.
+
+       * doc/emacs/android.texi (Android): Add `Android Document
+       Providers'.
        (Android Startup): Update the location of the content identifier
        directory.
        (Android File System): Describe access to document provider
        directories.
        (Android Document Providers): New node.
+
        * doc/emacs/emacs.texi (Top): Update the menu for the Android
        appendix.
-       * java/Makefile.in (filename, install_temp/assets/build_info): Make
-       directory-tree depend on build_info.
+
+       * java/Makefile.in (filename, install_temp/assets/build_info):
+       Make directory-tree depend on build_info.
+
        * java/org/gnu/emacs/EmacsActivity.java (onActivityResult): New
        function.  When a document tree is accepted, persist access to it.
-       * java/org/gnu/emacs/EmacsDirectoryEntry.java (EmacsDirectoryEntry):
-       New struct.
-       * java/org/gnu/emacs/EmacsOpenActivity.java (checkReadableOrCopy): Use
-       EmacsService.buildContentName.
-       * java/org/gnu/emacs/EmacsService.java (getEmacsView, openContentUri)
+
+       * java/org/gnu/emacs/EmacsDirectoryEntry.java
+       (EmacsDirectoryEntry): New struct.
+
+       * java/org/gnu/emacs/EmacsOpenActivity.java (checkReadableOrCopy):
+       Use EmacsService.buildContentName.
+
+       * java/org/gnu/emacs/EmacsService.java (getEmacsView)
+       (openContentUri)
        (checkContentUri): Remove excessive debug logging.
        (buildContentName, getDocumentAuthorities, requestDirectoryAccess)
        (getDocumentTrees, decodeFileName, documentIdFromName, getTreeUri)
-       (statDocument, accessDocument, openDocumentDirectory, 
readDirectoryEntry)
+       (statDocument, accessDocument, openDocumentDirectory)
+       (readDirectoryEntry)
        (openDocument, createDocument): New functions.
 
-       * lib-src/asset-directory-tool.c: Improve commentary by illustrating
-       the difference between directory and ordinary files.
+       * lib-src/asset-directory-tool.c: Improve commentary by
+       illustrating the difference between directory and ordinary files.
 
        * src/android.c (ANDROID_THROW, enum android_fd_table_entry_flags)
        (struct android_emacs_service, android_extract_long)
        (android_scan_directory_tree, android_is_directory)
-       (android_get_asset_name, android_url_encode, android_content_name_p)
-       (android_get_content_name, android_check_content_access, android_fstat)
-       (android_fstatat, android_file_access_p, android_hack_asset_fd_fallback)
-       (android_detect_ashmem, android_hack_asset_fd, android_close_on_exec)
-       (android_open, android_close, android_fclose, android_create_lib_link)
-       (android_faccessat, struct android_dir, android_opendir, android_dirfd)
-       (android_readdir, android_closedir, android_lookup_asset_directory_fd)
+       (android_get_asset_name, android_url_encode)
+       (android_content_name_p)
+       (android_get_content_name, android_check_content_access)
+       (android_fstat)
+       (android_fstatat, android_file_access_p)
+       (android_hack_asset_fd_fallback)
+       (android_detect_ashmem, android_hack_asset_fd)
+       (android_close_on_exec)
+       (android_open, android_close, android_fclose)
+       (android_create_lib_link)
+       (android_faccessat, struct android_dir, android_opendir)
+       (android_dirfd)
+       (android_readdir, android_closedir)
+       (android_lookup_asset_directory_fd)
        (android_exception_check_3, android_get_current_api_level)
        (android_open_asset, android_close_asset, android_asset_read_quit)
-       (android_asset_read, android_asset_lseek, android_asset_fstat): Move
-       content and asset related functions to androidvfs.c.
-       (android_init_emacs_service): Obtain handles for new JNI functions.
+       (android_asset_read, android_asset_lseek, android_asset_fstat):
+       Move content and asset related functions to androidvfs.c.
+       (android_init_emacs_service): Obtain handles for new JNI
+       functions.
        (initEmacsParams): Initialize the VFS layer.
        (android_request_directory_access): New function.
        (android_display_toast): Remove unused function.
@@ -425,7 +413,8 @@
        (struct android_parcel_file_descriptor_class)
        (android_init_cursor_class, android_init_entry_class)
        (android_init_fd_class, android_vfs_canonicalize_name)
-       (struct android_unix_vnode, struct android_unix_vdir, unix_vfs_ops)
+       (struct android_unix_vnode, struct android_unix_vdir)
+       (unix_vfs_ops)
        (android_unix_name, android_unix_vnode, android_unix_open)
        (android_unix_close, android_unix_unlink, android_unix_symlink)
        (android_unix_rmdir, android_unix_rename, android_unix_stat)
@@ -453,7 +442,8 @@
        (android_content_opendir, android_content_get_directory_name)
        (android_content_initial, android_get_content_name)
        (android_check_content_access, struct android_authority_vnode)
-       (authority_vfs_ops, android_authority_name, android_authority_open)
+       (authority_vfs_ops, android_authority_name)
+       (android_authority_open)
        (android_authority_close, android_authority_unlink)
        (android_authority_symlink, android_authority_rmdir)
        (android_authority_rename, android_authority_stat)
@@ -464,7 +454,7 @@
        (android_saf_root_close, android_saf_root_unlink)
        (android_saf_root_symlink, android_saf_root_rmdir)
        (android_saf_root_rename, android_saf_root_stat)
-       (android_saf_root_access, android_saf_root_mkdir)
+       (androqid_saf_root_access, android_saf_root_mkdir)
        (android_saf_root_readdir, android_saf_root_closedir)
        (android_saf_root_dirfd, android_saf_root_opendir)
        (android_saf_root_initial, android_saf_root_get_directory)
@@ -483,7 +473,8 @@
        (saf_file_vfs_ops, android_saf_file_name, android_saf_file_open)
        (android_saf_file_unlink, android_saf_file_rmdir)
        (android_saf_file_opendir, android_close_parcel_fd)
-       (android_saf_new_vnode, android_saf_new_name, android_saf_new_open)
+       (android_saf_new_vnode, android_saf_new_name)
+       (android_saf_new_open)
        (android_saf_new_unlink, android_saf_new_symlink)
        (android_saf_new_rmdir, android_saf_new_rename)
        (android_saf_new_stat, android_saf_new_access)
@@ -491,7 +482,8 @@
        (special_vnodes, android_root_name, android_name_file)
        (android_vfs_init, android_open, android_unlink, android_symlink)
        (android_rmdir, android_mkdir, android_renameat_noreplace)
-       (android_rename, android_fstat, android_fstatat_1, android_fstatat)
+       (android_rename, android_fstat, android_fstatat_1)
+       (android_fstatat)
        (android_faccessat, android_fdopen, android_close, android_fclose)
        (android_open_asset, android_close_asset, android_asset_read_quit)
        (android_asset_read, android_asset_lseek, android_asset_fstat)
@@ -508,7 +500,8 @@
        * src/fileio.c (check_mutable_filename, Fcopy_file)
        (Fmake_directory_internal, Fdelete_directory_internal)
        (Fdelete_file, Frename_file, Fadd_name_to_file)
-       (Fmake_symbolic_link, file_accessible_directory_p, Fset_file_modes)
+       (Fmake_symbolic_link, file_accessible_directory_p)
+       (Fset_file_modes)
        (Fset_file_times, write_region):
        * src/filelock.c (get_boot_time, rename_lock_file)
        (create_lock_file, current_lock_owner, unlock_file):
@@ -524,40 +517,27 @@
        for fopen, fdopen, unlink, symlink, rmdir, mkdir,
        renameat_norepalce and rename.
 
-2023-07-26  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-07-24  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-23  Po Lu  <luangruo@yahoo.com>
 
-       Facilitate locating the app library directory
-       * doc/emacs/android.texi (Android File System): Document where
-       the app library directory can probably be found.
-       * src/android.c (android_create_lib_link): New function.  Try to
-       symlink `lib' in the directory holding the files directory to
-       the app library directory.
-       (setEmacsParams): Call that function if Emacs is being
-       initialized from an application context.
+       * doc/emacs/android.texi (Android File System): Document where the
+       app library directory can probably be found.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_create_lib_link): New function.  Try to
+       symlink `lib' in the directory holding the files directory to the
+       app library directory.
+       (setEmacsParams): Call that function if Emacs is being initialized
+       from an application context.
 
 2023-07-22  Po Lu  <luangruo@yahoo.com>
 
-       Try harder to keep the initial word selected
        * lisp/touch-screen.el (touch-screen-drag): If
        touch-screen-word-select, also keep the initial word within the
        region while scrolling.
 
-       Fix window box computation for menu bar windows
        * src/window.h (WINDOW_MENU_BAR_P): Check for external menu bars
        using HAVE_WINDOW_SYSTEM && HAVE_EXT_MENU_BAR instead of hard
        coding X without Xt or GTK.
 
-       Update Android port
        * doc/lispref/commands.texi (Key Sequence Input): Describe which
        events receive imaginary prefix keys.
        * lisp/touch-screen.el (touch-screen-translate-touch): Consider
@@ -566,104 +546,95 @@
 
        * etc/NEWS: Announce `current-key-remap-sequence'.
 
-       Fix default value of scroll bar frame parameters on Android
        * src/androidfns.c (Fx_create_frame): Default
        Qvertical_scroll_bars to Qnil, but set scroll-bar-width and
        scroll-bar-height.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-21  Po Lu  <luangruo@yahoo.com>
 
-       Improve touch screen and text conversion behavior of many commands
        * doc/lispref/commands.texi (Key Sequence Input): Document new
        argument to `read-key-sequence' etc.
+
        * lisp/help-macro.el (make-help-screen):
-       * lisp/subr.el (read-key, read-char-choice-with-read-key):
-       Disable text conversion and display the OSK before reading a key
-       sequence.
+       * lisp/subr.el (read-key, read-char-choice-with-read-key): Disable
+       text conversion and display the OSK before reading a key sequence.
+
        * lisp/touch-screen.el (touch-screen-window-selection-changed):
        Only cancel the minibuffer OSK timer.
        (touch-screen-handle-point-up): Update comment accordingly.
+
        * src/keyboard.c (command_loop_1, read_menu_command)
        (read_key_sequence, read_key_sequence_vs, Fread_key_sequence)
        (Fread_key_sequence_vector): New arg DISABLE_TEXT_CONVERSION.
        All callers changed.
 
-       Correctly translate touchscreen-up events outside a frame
-       * lisp/touch-screen.el (touch-screen-translate-touch): Check if
-       a prefix is specified separately from prefix being non-nil.
-       Accept `nil' as an imaginary prefix key.
-       (function-key-map): Register translation functions on the tab
-       bar, tab lines and internal border.
+       * lisp/touch-screen.el (touch-screen-translate-touch): Check if a
+       prefix is specified separately from prefix being non-nil.  Accept
+       `nil' as an imaginary prefix key.
+       (function-key-map): Register translation functions on the tab bar,
+       tab lines and internal border.
 
-       Improve touch screen scrolling support
        * lisp/touch-screen.el (touch-screen-preview-select): Avoid
        unnecessary redisplays.
        (touch-screen-drag): Scroll at window margins using window
        scrolling functions instead of relying on redisplay to recenter
        the window around point.
 
-       Update Android port
        * doc/emacs/input.texi (Touchscreens): Document
        `touch-screen-preview-select'.
-       * doc/lispref/commands.texi (Touchscreen Events): Fix typo in
-       the descriptions of two touch screen events.
-       * lisp/dired.el (dired-insert-set-properties): Adjust for
-       changes to file end computation.
+
+       * doc/lispref/commands.texi (Touchscreen Events): Fix typo in the
+       descriptions of two touch screen events.
+
+       * lisp/dired.el (dired-insert-set-properties): Adjust for changes
+       to file end computation.
+
        * lisp/minibuffer.el (clear-minibuffer-message): Don't clear
        minibuffer message if dragging.
+
        * lisp/touch-screen.el (touch-screen-current-tool): Fix doc
        string.
        (touch-screen-preview-select): New function.
        (touch-screen-drag): Call it if point changes.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-20  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * exec/trace.c (handle_readlinkat): Adjust commentary to match
        behavior.
+
        * src/android.c (android_get_keysym_name): NULL terminate
-       *name_return.
+       *NAME_RETURN.
 
-       Update some menu definitions for Android
        * lisp/international/mule-cmds.el (set-coding-system-map): Don't
        display `set-terminal-coding-system' on Android.
 
        * lisp/cus-edit.el (custom-display): Add `android' display type.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/android.c (struct android_event_queue): Don't make
        unnecessarily volatile.
 
-       Update Android port
-       * lisp/touch-screen.el (touch-screen-handle-touch): Don't
-       restart dragging if point is at ZV and the tap falls on a
-       different row.
+       * lisp/touch-screen.el (touch-screen-handle-touch): Don't restart
+       dragging if point is at ZV and the tap falls on a different row.
 
-       Use context menu header titles on Android
-       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
-       New field `title'.
+       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu): New
+       field `title'.
        (addSubmenu): New arg TITLE.  Set that field.
        (expandTo): Set MENU's header title if it's a context menu.
+
        * src/androidmenu.c (android_init_emacs_context_menu): Adjust
        signature of `createContextMenu'.
        (android_menu_show): Use TITLE instead of pane titles if there's
        only one pane.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Introduce a `dired-click-select' mode
        * doc/emacs/dired.texi (Marks vs Flags): Document command bound
        to `touchscreen-hold'.
+
        * doc/lispref/commands.texi (Touchscreen Events): Describe
        `touch-screen-inhibit-drag'.
+
        * etc/NEWS: Improve description of changes to touch screen
        support.
+
        * lisp/dired-aux.el (dired-do-chxxx, dired-do-chmod)
        (dired-do-print, dired-do-shell-command, dired-do-compress-to)
        (dired-do-create-files, dired-do-rename, dired-do-isearch)
@@ -671,6 +642,7 @@
        (dired-do-query-replace-regexp, dired-do-find-regexp)
        (dired-vc-next-action): Disable ``click to select'' after
        running this command.
+
        * lisp/dired.el (dired-insert-set-properties): Attach
        click-to-select keymap to file names if necessary.
        (dired-mode-map): Bind `touchscreen-hold' to click to select
@@ -680,6 +652,7 @@
        (dired-mark-for-click, dired-enable-click-to-select-mode): New
        functions.
        (dired-click-to-select-mode): New minor mode.
+
        * lisp/touch-screen.el (touch-screen-current-tool): Fix doc
        string.
        (touch-screen-inhibit-drag): New function.
@@ -688,19 +661,20 @@
 
        * src/sfnt.c (sfnt_infer_deltas): Improve commentary.
 
-       Improve behavior of `restart-drag'
-       * lisp/touch-screen.el (touch-screen-handle-point-up): If what
-       is `restart-drag' (meaning that a drag has been restarted but
-       the touchpoint has not moved), translate the release into a
-       regular mouse click to deactivate the region.
+       * lisp/touch-screen.el (touch-screen-handle-point-up): If what is
+       `restart-drag' (meaning that a drag has been restarted but the
+       touchpoint has not moved), translate the release into a regular
+       mouse click to deactivate the region.
 
-       Update Android port
        * build-aux/makecounter.sh (curcount): Rename `counter' to
        `emacs_shortlisp_counter'.
+
        * doc/emacs/input.texi (Touchscreens): Document
        `touch-screen-extend-selection'.
+
        * doc/lispref/commands.texi (Touchscreen Events): Document
        `touchscreen-restart-drag'.
+
        * lisp/touch-screen.el (touch-screen-extend-selection): New user
        option.
        (touch-screen-restart-drag): New function.
@@ -710,15 +684,15 @@
        extending a previous drag gesture are met, and generate such
        events if so.
        (touch-screen-translate-touch): Update doc string.
+
        * src/Makefile.in (otherobj): Remove BUILD_COUNTER_OBJ.
        ($(lispsource)/international/charprop.el):
-       (%.elc): Don't depend on bootstrap-emacs if cross configuring
-       for Android.
-       (libemacs.so): Directly depend on and link with
-       BUILD_COUNTER_OBJ.
+       (%.elc): Don't depend on bootstrap-emacs if cross configuring for
+       Android.
+       (libemacs.so): Directly depend on and link with BUILD_COUNTER_OBJ.
 
-       Make sure Android builds are redumped upon changes to shortlisp
        * build-aux/makecounter.sh: New script.
+
        * src/Makefile.in (abs_top_builddir): New variable.
        (BUILD_COUNTER_OBJ): Define to build-counter.o
        if compiling for Android.
@@ -728,106 +702,94 @@
        (emacs$(EXEEXT)): Adjust acordingly.
        (mostlyclean): Remove build-counter.c.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-18  Po Lu  <luangruo@yahoo.com>
 
-       Fix typos in touch-screen.el
        * lisp/touch-screen.el (touch-screen-handle-point-update)
        (touch-screen-handle-point-up): Fix typos.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * lisp/touch-screen.el (touch-screen-handle-point-update): Fix
+       typo.
 
-       * lisp/touch-screen.el (touch-screen-handle-point-update): Fix typo.
-
-       Avoid splurious menu-bar nil events
        * src/keyboard.c (make_lispy_event): Return nil if no menu item
        is found.
 
-       Update Android port
        * lisp/touch-screen.el (touch-screen-hold)
        (touch-screen-handle-point-up): Don't select inactive minibuffer
        windows.
        (touch-screen-handle-point-update): Improve detection of left
        and right edges.
 
-       Update Android port
-       * lisp/touch-screen.el (touch-screen-handle-touch): Fix
-       treatment of stray update events.
+       * lisp/touch-screen.el (touch-screen-handle-touch): Fix treatment
+       of stray update events.
 
-       Don't enable scroll-bar-mode by default on Android
        * src/frame.c (syms_of_frame): Default to nil if HAVE_ANDROID.
 
        * src/keyboard.c (make_lispy_event): Fix botched merge.
 
-       Update Android port
        * doc/lispref/commands.texi (Touchscreen Events): Describe
        treatment of canceled touch sequences during touch event
        translation.
+
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Update JNI
        prototypes.
+
        * java/org/gnu/emacs/EmacsWindow.java (motionEvent): Set
        cancelation flag in events sent where appropriate.
+
        * lisp/touch-screen.el (touch-screen-handle-point-update):
        Improve treatment of horizontal scrolling near window edges.
        (touch-screen-handle-touch): Don't handle point up if the touch
        sequence has been canceled.
+
        * src/android.c (sendTouchDown, sendTouchUp, sendTouchMove): New
        argument `flags'.
+
        * src/androidgui.h (enum android_touch_event_flags): New enum.
        (struct android_touch_event): New field `flags'.
+
        * src/androidterm.c (handle_one_android_event): Report
        cancelation in TOUCHSCREEN_END_EVENTs.
-       * src/keyboard.c (make_lispy_event): Fix botched merge.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/keyboard.c (make_lispy_event): Fix botched merge.
 
 2023-07-17  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * doc/lispref/commands.texi (Touchscreen Events): Document meaning
+       of `mouse-1-menu-command'.
 
-       Update Android port
-       * doc/lispref/commands.texi (Touchscreen Events): Document
-       meaning of `mouse-1-menu-command'.
        * lisp/mouse.el (minor-mode-menu-from-indicator): New arg EVENT.
        Give it to popup-menu.
        (mouse-minor-mode-menu): Use posn specified within EVENT.
+
        * lisp/touch-screen.el (touch-screen-handle-touch): Fix
        interactive translation.  Treat commands labeled
        `mouse-1-menu-command' like ordinary keymaps.
 
-       Update Android port
        * doc/lispref/commands.texi (Touchscreen Events): Document
        changes to simple translation.
+
        * lisp/touch-screen.el (touch-screen-handle-point-up): Generate
        `down-mouse-1' if the current gesture is `mouse-1-menu'.
-       (touch-screen-handle-touch): If binding is a keymap, set state
-       to `mouse-1-menu' and wait for point to be released before
-       generating down-mouse-1.
+       (touch-screen-handle-touch): If binding is a keymap, set state to
+       `mouse-1-menu' and wait for point to be released before generating
+       down-mouse-1.
 
-       Improve word selection behavior
        * lisp/tab-bar.el (tab-bar-map): Don't bind touch-screen-drag.
+
        * lisp/touch-screen.el (touch-screen-drag): Extend the region
        based on the position of the mark, not the position of point
        relative to EVENT.
        (touch-screen-translate-touch): Don't generate virtual function
        keys for non-mouse events.
        (function-key-map): Remove redundant definitions.
-       * src/keyboard.c (read_key_sequence): Don't generate *-bar
-       prefix keys for mock input (such as input from function key
-       translation.)
 
-       Improve touch screen support
+       * src/keyboard.c (read_key_sequence): Don't generate *-bar prefix
+       keys for mock input (such as input from function key translation.)
+
        * doc/emacs/input.texi (Touchscreens): Document the new feature
        for people who have trouble dragging to word boundaries.
-       * lisp/touch-screen.el (touch-screen-word-select): New
-       defcustom.
+
+       * lisp/touch-screen.el (touch-screen-word-select): New defcustom.
        (touch-screen-word-select-bounds)
        (touch-screen-word-select-initial-word): New variable
        definitions.
@@ -840,25 +802,24 @@
        (touch-screen-translate-touch): Fix doc strings and fill
        comments.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-16  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsService.java (displayToast):
        * src/android.c (android_init_emacs_service): Remove unused
        function.
+
        * lisp/touch-screen.el (touch-screen-handle-point-up): Correctly
        compute posn point.
        (touch-screen-translate-touch): Update doc string.
        (function-key-map): Define touch screen translation functions
        within the internal border.
 
-       Update Android port
        * doc/lispref/commands.texi (Touchscreen Events): Improve
        documentation.
+
        * lisp/tab-bar.el (tab-bar-map): Bind `[tab-bar
        touchscreen-hold]'.
+
        * lisp/touch-screen.el (touch-screen-hold, touch-screen-drag):
        New functions.
        (touch-screen-handle-timeout): Generate a `touchscreen-hold'
@@ -867,33 +828,37 @@
        `touchscreen-drag' event upon dragging.
        (touch-screen-translate-touch): Cancel touch screen timer upon
        exit.
+
        * src/keyboard.c (access_keymap_keyremap): Take unsigned int
        start and end instead.
 
-       Improve touch-screen support
        * doc/emacs/emacs.texi (Top):
        * doc/emacs/input.texi (Other Input Devices): Correctly
        capitalize subsection name.
        (Touchscreens): Document additional translation.
+
        * doc/lispref/commands.texi (Touchscreen Events): Document that
        `touchscreen-end' events now have prefix keys.  Also, describe
        mouse emulation and `touchscreen-scroll' events.
+
        * doc/lispref/keymaps.texi (Translation Keymaps): Document
        `current-key-remap-sequence'.
+
        * lisp/touch-screen.el (touch-screen-translate-prompt): New
        function.
-       (touch-screen-scroll): New command.  Bind to
-       `touchscreen-scroll'.
+       (touch-screen-scroll): New command.  Bind to `touchscreen-scroll'.
        (touch-screen-handle-point-update, touch-screen-handle-point-up)
-       (touch-screen-handle-touch): Refactor to actually translate
-       touch screen event sequences, as opposed to looking up commands
-       and executing them.
+       (touch-screen-handle-touch): Refactor to actually translate touch
+       screen event sequences, as opposed to looking up commands and
+       executing them.
        (touch-screen-translate-touch): New function.  Bind in
        function-key-map to all touch screen events.
        (touch-screen-drag-mode-line-1, touch-screen-drag-mode-line)
        (touch-screen-tap-header-line): Remove special commands for
        dragging the mode line and clicking on the header line.
+
        * lisp/wid-edit.el (widget-button-click): Adjust accordingly.
+
        * src/keyboard.c (access_keymap_keyremap): Bind
        `current-key-remap-sequence' to the key sequence being remapped.
        (keyremap_step): Give fkey->start and fkey->end to
@@ -902,240 +867,223 @@
        well.
        (syms_of_keyboard): New variable Vcurrent_key_remap_sequence.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/android.texi (Android): Add new node to menu.
        (Android Environment): Add footnote pointing to new node.
        (Android Software): New node.
+
        * doc/emacs/emacs.texi (Top): Add new node to menu.
+
        * java/AndroidManifest.xml.in (manifest): Fix location of
        sharedUserId property.
+
        * java/INSTALL: Improve documentation of shared user ID
        support.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-14  Po Lu  <luangruo@yahoo.com>
 
-       Make --with-shared-user-id work
        * configure.ac (ANDROID_SHARED_USER_NAME): New variable.
        Substitute it.
+
        * java/AndroidManifest.xml.in: Set `sharedUserLabel' if a shared
        user ID is enabled.
+
        * java/res/values/strings.xml (shared_user_name): New string
        resource.
 
-       Update Android port
        * src/android.c (android_blit_copy): Don't check for overflow
        where not required.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Clean up Android debug code
        * java/org/gnu/emacs/EmacsInputConnection.java
-       (getSurroundingText): Don't print debug information if DEBUG_IC
-       is off.
+       (getSurroundingText): Don't print debug information if DEBUG_IC is
+       off.
 
        * lisp/calc/calc.el (calc): Fix typo.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-13  Po Lu  <luangruo@yahoo.com>
 
-       Add a Doc View tool bar
        * etc/NEWS: Announce the new tool bar.
+
        * etc/images/last-page.xpm:
        * etc/images/last-page.pbm: New images.  Mirrored from
        next-page.xpm.
+
        * lisp/doc-view.el (doc-view-menu): Use `doc-view-new-search'
        instead of an anonymous function.
        (doc-view-tool-bar-map): New keymap.
-       (doc-view-search): Update the tool bar after initiating a
-       search.
+       (doc-view-search): Update the tool bar after initiating a search.
        (doc-view-new-search): New command.
        (doc-view-mode): Set the tool bar map appropriately.
 
-       Improve workaround for partial texture updates on Android
+       Restore hardware acceleration, as a small degree of tearing is
+       preferable towards large slowdowns on some specific devices.  The
+       slight tearing remains, but a workaround for the GPU texture
+       remaining partially updated has been introduced.
+
        * java/AndroidManifest.xml.in:
        * java/org/gnu/emacs/EmacsDialog.java (toAlertDialog): Don't
        change hardware acceleration state.
+
        * java/org/gnu/emacs/EmacsNative.java (notifyPixelsChanged): New
        function.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
        New field `bitmapChanged'.
        (copyToFrontBuffer): Signal that the bitmap has changed.
-       (onDraw): If the bitmap has changed, increment the generation
-       ID.
+       (onDraw): If the bitmap has changed, increment the generation ID.
+
        * src/android.c (JNICALL): Implement new function.
 
 2023-07-13  Po Lu  <luangruo@yahoo.com>
 
-       Disable hardware acceleration on Android
-       It serves no purpose and causes tearing.  Uploading the bitmap
-       to the GPU takes about as long as it does to incrementally
-       update the surface in software.
+       Disable hardware acceleration on Android.  It serves no purpose
+       and causes tearing.  Uploading the bitmap to the GPU takes about
+       as long as it does to incrementally update the surface in
+       software.
 
        * java/AndroidManifest.xml.in: Disable hardware acceleration.
+
        * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): Make
        lastClosedMenu static.
+
        * java/org/gnu/emacs/EmacsDialog.java (toAlertDialog): Enable
        hardware acceleration within alert dialogs.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (onDraw): Describe
        why hardware acceleration is disabled.
+
        * java/org/gnu/emacs/EmacsWindow.java (run): Remove redundant
        call.
 
-2023-07-13  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-12  Po Lu  <luangruo@yahoo.com>
 
        * src/android.c (android_run_select_thread): Fix typo.
 
-       Update Android port
-       * src/android.c (android_run_select_thread): Correctly return
-       the set of ready read and write descriptors on __ANDROID_API__ <
-       16 systems.
+       * src/android.c (android_run_select_thread): Correctly return the
+       set of ready read and write descriptors on __ANDROID_API__ < 16
+       systems.
        (android_select): Clear the set of ready file descriptors if
        events from the event queue are present despite pselect failing.
 
-       Fix keyboard state translation on Android
        * src/androidterm.c (android_android_to_emacs_modifiers)
        (android_emacs_to_android_modifiers): Fix statement precedence
        bugs.
 
        * src/doc.c (doc_close): Remove unused macro.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsWindow.java (whatButtonWasIt): Handle
        back and forward buttons along with styluses.
+
        * src/doc.c (close_file_unwind_android_fd): New function.
        (get_doc_string, Fsnarf_documentation): Don't create a temporary
        fd if it can be avoided.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-11  Po Lu  <luangruo@yahoo.com>
 
-       Fix doc file generation on Android
        * .gitignore: Ignore cross/etc/DOC.
+
        * configure.ac: Make the directory `cross/etc'.
+
        * cross/Makefile.in (CLEAN_SUBDIRS): Clean files inside `etc' as
        well.
+
        * java/Makefile.in (install_temp): Copy cross/etc/DOC to the
        package if it is available.
+
        * src/Makefile.in (SOME_MACHINE_OBJECTS): Add androidselect.c,
        sfntfont-android.c and sfntfont.c.
        (libemacs.so): Depend on $(etc)/DOC.
 
-       Update Android port
        * src/sfnt.c (sfnt_fill_span): Correctly clip span to raster
        width, ensuring that the last pixel is filled.
        (main): Adjust test sizes.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsView.java (onGenericMotionEvent): Call
        onGenericMotionEvent.
+
        * java/org/gnu/emacs/EmacsWindow.java (Coordinate): New fields
        `button' and `id'.
        (<init>): Add new arguments to the construtor.
        (whatButtonWasIt): Return 0 if the button state has not changed.
        (buttonForEvent): New function.
-       (figureChange): Return the Coordinate object associated to
-       EVENT.  Determine whether or not EVENT was accompanied by a
-       change to the button state, and ascertain which button that was.
+       (figureChange): Return the Coordinate object associated to EVENT.
+       Determine whether or not EVENT was accompanied by a change to the
+       button state, and ascertain which button that was.
        (motionEvent): New function.
        (onGenericMotionEvent, onTouchEvent): Factor out touch and mouse
        event delivery to motionEvent.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-10  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsService.java (browseUrl): New argument
        SEND.  Choose from a list of applications that want to share the
        URL if true.
+
        * lisp/net/browse-url.el (browse-url-android-share): New user
        option.
        (browse-url-default-android-browser): Respect said user option.
-       * src/android.c (android_init_emacs_service)
-       (android_browse_url): Expose new option.
+
+       * src/android.c (android_init_emacs_service, android_browse_url):
+       Expose new option.
+
        * src/android.h: Update prototypes.
-       * src/androidselect.c (Fandroid_browse_url): Likewise.
 
-       ; Update from Gnulib
-       * lib/vasnprintf.c (VASNPRINTF):
-       * m4/printf.m4 (gl_SWPRINTF_WORKS):
-       (gl_SWPRINTF_DIRECTIVE_LA):
-       * m4/vasnprintf.m4 (gl_PREREQ_PRINTF_PARSE):
+       * src/androidselect.c (Fandroid_browse_url): Likewise.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * lib/vasnprintf.c:
+       * m4/printf.m4:
+       * m4/vasnprintf.m4: Update from Gnulib.
 
 2023-07-09  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsWindow.java (eventModifiers)
        (motionEventModifiers): New functions.
        (onKeyDown, onKeyUp, onFocusChanged, onSomeKindOfMotionEvent):
        Don't record the previous modifier mask; instead, always use the
        modifier state specified in the event.
+
        * src/androidterm.c (handle_one_android_event): Don't dispatch
        button release events when a popup is active.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsService.java (onStartCommand): Fix
-       typo in notification message.
-       * java/org/gnu/emacs/EmacsWindow.java (onFocusChanged): Reset
-       the recorded modifier state upon a change to the window focus.
+       * java/org/gnu/emacs/EmacsService.java (onStartCommand): Fix typo
+       in notification message.
+       * java/org/gnu/emacs/EmacsWindow.java (onFocusChanged): Reset the
+       recorded modifier state upon a change to the window focus.
 
        * java/org/gnu/emacs/EmacsService.java (onCreate): Fix typo.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsDrawPoint.java (perform): Don't fill
-       an extra pixel.
+       * java/org/gnu/emacs/EmacsDrawPoint.java (perform): Don't fill an
+       extra pixel.
        * java/org/gnu/emacs/EmacsService.java (onCreate): Make sure
        scaledDensity is always at least 160 dpi.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-08  Po Lu  <luangruo@yahoo.com>
 
-       Fix EmacsDrawLine again
        * java/org/gnu/emacs/EmacsDrawLine.java (perform): Symmetrically
        adjust coordinates to cover the last pixel.  Then, fill the left
        most pixel of the line.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsService.java (DEBUG_IC)
        (DEBUG_THREADS): Improve commentary.
-       * src/androidterm.c (handle_one_android_event): Signal
-       completion of IME events that have lost their frames.
+
+       * src/androidterm.c (handle_one_android_event): Signal completion
+       of IME events that have lost their frames.
        (requestCursorUpdates): Don't set an edit counter as this event
        won't be passed to the text conversion machinery.
 
-       ; Fix whitespace
-       * src/android.c (android_blit_xor):
-       (android_check_query_urgent):
-       (android_run_in_emacs_thread):
-       (android_update_extracted_text): Fix whitespace.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_blit_xor, android_check_query_urgent)
+       (android_run_in_emacs_thread, android_update_extracted_text): Fix
+       whitespace.
 
 2023-07-07  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsSurfaceView.java (copyToFrontBuffer):
-       Use fallback bit blit function on Android 7.0 as well, as
-       crashes have been observed in drawBitmap.
+       Use fallback bit blit function on Android 7.0 as well, as crashes
+       have been observed in drawBitmap.
 
 2023-07-07  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * lisp/tool-bar.el (modifier-bar-modifier-list): New variable.
        (modifier-bar-button): New function.
        (tool-bar-event-apply-alt-modifier)
@@ -1150,42 +1098,44 @@
        (modifier-bar-mode): Disable tool bar items corresponding to
        modifier keys that've already been pressed.
 
-       * etc/images/shift.pbm: Regenerate from correct font.
-
-2023-07-07  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * etc/images/shift.pbm: Regenerate using the same font as the
+       other modifier button bitmaps.
 
 2023-07-06  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsNative.java (scaledDensity): Announce
        new argument `scaledDensity'.
-       * java/org/gnu/emacs/EmacsNoninteractive.java (main): Specify
-       new argument.
+
+       * java/org/gnu/emacs/EmacsNoninteractive.java (main): Specify new
+       argument.
+
        * java/org/gnu/emacs/EmacsService.java (onCreate): Compute an
-       adjusted DPI for the font size based on the ratio between
-       density and scaledDensity.
+       adjusted DPI for the font size based on the ratio between density
+       and scaledDensity.
        (run): Specify that adjusted density.
+
        * src/android.c (setEmacsParams): Set
        `android_scaled_pixel_density'.
-       * src/android.h: (android_scaled_pixel_density: New variable.
+
+       * src/android.h (android_scaled_pixel_density) New variable.
+
        * src/androidterm.c (android_term_init): Set `font_resolution'.
+
        * src/androidterm.h (struct android_display_info): New field.
+
        * src/font.c (font_pixel_size, font_find_for_lface)
        (font_open_for_lface, Ffont_face_attributes, Fopen_font): Use
        FRAME_RES instead of FRAME_RES_Y.
-       * src/frame.h (FRAME_RES): New macro.  Use this to convert
-       between font point and pixel sizes as opposed to FRAME_RES_Y.
+
+       * src/frame.h (FRAME_RES): New macro.  Use this to convert between
+       font point and pixel sizes as opposed to FRAME_RES_Y.
+
        * src/w32font.c (fill_in_logfont):
        * src/xfaces.c (Fx_family_fonts, set_lface_from_font): Use
        FRAME_RES instead of FRAME_RES_Y.  (bug#64444)
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-07-05  Po Lu  <luangruo@yahoo.com>
 
-       Fix bug#64445
        * doc/emacs/android.texi (Android Environment): Document that
        Emacs also receives READ_EXTERNAL_STORAGE by default on old
        versions of Android.
@@ -1194,17 +1144,15 @@
 
        * doc/emacs/emacs.texi (Emacs and Android): Fix menu.
 
-       ; Update Android port
-       * doc/emacs/android.texi (Android): Fix discrepancies between
-       menu and sectioning.
+       * doc/emacs/android.texi (Android): Fix discrepancies between menu
+       and sectioning.
 
-       Fix crash between Android 4.0 and Android 5.1
        * java/org/gnu/emacs/EmacsService.java (detectMouse): Don't use
        function that is not present on Android 4.0.
 
-       Update Android port
        * doc/lispref/commands.texi (Misc Events): Correctly index
        `set-text-conversion-style'.
+
        * lisp/tool-bar.el (tool-bar-event-apply-alt-modifier)
        (tool-bar-event-apply-super-modifier)
        (tool-bar-event-apply-hyper-modifier)
@@ -1212,35 +1160,40 @@
        (tool-bar-event-apply-control-modifier)
        (tool-bar-event-apply-meta-modifier): Pass t when restoring text
        conversion style.
+
        * src/keyboard.c (restore_reading_key_sequence): New function.
        (read_key_sequence): Set `reading_key_sequence' where necessary.
+
        * src/keyboard.h: Declare variable.
+
        * src/textconv.c (check_postponed_buffers): New function.
        (Fset_text_conversion_style): New argument.  If set, and a key
        sequence is being read, postpone resetting the IME until the key
        sequence is read.
        (syms_of_textconv): Clear new variable and add staticpro.
-       * src/textconv.h: Update prototypes.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/textconv.h: Update prototypes.
 
 2023-07-04  Po Lu  <luangruo@yahoo.com>
 
-       Implement a tool bar containing modifier keys
        * doc/emacs/frames.texi (Tool Bars): Describe modifier bars.
+
        * doc/lispref/keymaps.texi (Extended Menu Items, Tool Bar):
-       Document changes to tool bar menu item handling and secondary
-       tool bars.
+       Document changes to tool bar menu item handling and secondary tool
+       bars.
+
        * etc/NEWS: Announce changes.
-       * lisp/simple.el (event-apply-modifier): Correctly apply Ctrl
-       and Shift modifiers to lower case ASCII key events that already
-       have other modifiers applied.
+
+       * lisp/simple.el (event-apply-modifier): Correctly apply Ctrl and
+       Shift modifiers to lower case ASCII key events that already have
+       other modifiers applied.
+
        * lisp/tool-bar.el (tool-bar--cache-key)
        (tool-bar--secondary-cache-key): New defsubsts.
        (tool-bar--flush-cache): Flush secondary tool bar cache.
        (tool-bar-make-keymap): Include secondary tool bar if necessary.
-       (tool-bar-make-keymap-1): New arg MAP.  Generate a keymap for
-       that map if specified, else default to tool-bar-map.
+       (tool-bar-make-keymap-1): New arg MAP.  Generate a keymap for that
+       map if specified, else default to tool-bar-map.
        (set-text-conversion-style, tool-bar-apply-modifiers)
        (overriding-text-conversion-style)
        (tool-bar-event-apply-alt-modifier)
@@ -1250,83 +1203,58 @@
        (tool-bar-event-apply-control-modifier)
        (tool-bar-event-apply-meta-modifier, modifier-bar-mode): New
        functions.
+
        * src/dispextern.h (enum tool_bar_item_idx): Add
        TOOL_BAR_ITEM_WRAP.
+
        * src/frame.c (make_frame): Clear new field `tool_bar_wraps_p'.
+
        * src/frame.h (struct frame): New field `tool_bar_wraps_p'.
+
        * src/keyboard.c (parse_tool_bar_item): Handle QCwrap properties
        in tool bar menu items.
        (syms_of_keyboard): New defsym QCwrap.
+
        * src/xdisp.c (build_desired_tool_bar_string): Clear
        f->tool_bar_wraps_p and set it appropriately.  Insert new line
        characters in the tool bar string upon encountering a wrap
        character.
-       (display_tool_bar_line): Stop at EOB, not line end.  Reseat on
-       the next line upon encountering EOL characters.
+       (display_tool_bar_line): Stop at EOB, not line end.  Reseat on the
+       next line upon encountering EOL characters.
        (redisplay_tool_bar): Allow rows to be different heights if
        explicit new lines are present upon the tool bar string.
 
        * src/sfnt.c (sfnt_decompose_compound_glyph): Pacify warning.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-07-03  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-07-02  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-07-01  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-30  Po Lu  <luangruo@yahoo.com>
 
        * src/android.c (android_query_tree): Correctly return children.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-06-29  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-06-28  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-27  Po Lu  <luangruo@yahoo.com>
 
        * doc/emacs/android.texi (Android Environment): Improve wording.
 
        * doc/emacs/android.texi (Android Environment): Fix typos.
 
-       Update Android port
        * src/android.c (android_exception_check)
        (android_exception_check_1)
        (android_exception_check_2)
        (android_exception_check_nonnull)
        (android_exception_check_nonnull_1): Tell the compiler to expect
-       that the object is non-NULL, or that no exception has been
-       thrown.
+       that the object is non-NULL, or that no exception has been thrown.
 
        * exec/loader-mips64el.s (rest_of_exec): Fix typo in comment.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-26  Po Lu  <luangruo@yahoo.com>
 
        * doc/lispref/commands.texi (Touchscreen Events): Fix typo.
 
 2023-06-26  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * lisp/calc/calc.el (calc-mode, calc): Make sure the on-screen
        keyboard is not hidden when a Calc buffer is created or a Calc
        Trail window is being created for the first time.
+
        * lisp/touch-screen.el (touch-screen-window-selection-changed):
        Take touch-screen-display-keyboard in to account.
 
@@ -1336,114 +1264,71 @@
        (sfnt_lerp_half): Avoid undefined shift of negative value.
        (sfnt_compute_tuple_scale): Pacify compiler warning.
 
-2023-06-26  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-06-25  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-06-24  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-23  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsDrawRectangle.java (perform):
        * java/org/gnu/emacs/EmacsSdk7FontDriver.java (Sdk7FontEntity):
        (hasChar): Clean up dead stores.
 
        * src/android.c (android_wc_lookup_string): Fix typo.
-
-       Correctly check result of string lookup
-       * src/android.c (android_wc_lookup_string): Check that
-       GetStringChars returns non-NULL, not if it throws an exception.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-06-22  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       (android_wc_lookup_string): Check that GetStringChars returns
+       non-NULL, not if it throws an exception.
 
 2023-06-21  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * src/androidfns.c (android_set_tool_bar_position):
+       * src/androidfns.c (android_set_tool_bar_position)
        (frame_geometry):
-       * src/androidterm.c (android_flash):
+       * src/androidterm.c (android_flash)
        (android_clear_under_internal_border): Synchronize with X.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-20  Po Lu  <luangruo@yahoo.com>
 
        * src/androidfns.c (android_frame_parm_handlers): Fix typo.
-
-       Synchronize tool bar position code with X
-       * src/androidfns.c (android_set_tool_bar_position): New
-       function.
+       (android_set_tool_bar_position): New function.
        (android_frame_parm_handlers): Add new frame param handler.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-19  Po Lu  <luangruo@yahoo.com>
 
        * lib-src/Makefile.in (seccomp-filter$(EXEEXT)): Link with Gnulib.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsView.java (EmacsView, dimensionsLock):
        New field.
        (<init>): Create new lock object.
        (handleDirtyBitmap, onLayout, onAttachedToWindow): Make sure
-       measuredWidth and measuredHeight are extracted and set
-       atomically.  Send Expose upon layout changes if the view has
-       grown.
+       measuredWidth and measuredHeight are extracted and set atomically.
+       Send Expose upon layout changes if the view has grown.
 
        * exec/Makefile.in (clean): Add `exec1'.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-18  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * src/window.h (GCALIGNED_STRUCT): Improve documentation of
+       * src/window.h (struct window): Improve documentation of
        `last_mark'.
+
        * src/xdisp.c (mark_window_display_accurate_1): Don't set
        `last_mark' to -1 if the mark is inactive.
 
-       Enable text conversion in conf-modes
        * lisp/textmodes/conf-mode.el (conf-mode-initialize): Set
        text-conversion-style.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-17  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Initialize signal mask earlier
        * java/org/gnu/emacs/EmacsService.java (onCreate, run): Don't
        initialize signal mask here.
+
        * java/org/gnu/emacs/EmacsApplication.java (onCreate): Do it
        here instead.
+
        * src/android.c (JNICALL): Restore previous signal masks.
 
        * java/README: More documentation.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-16  Po Lu  <luangruo@yahoo.com>
 
-       Fix quitting after changes to signal delivery
        * src/android.c (android_write_event, JNICALL)
        (android_run_in_emacs_thread): Don't rely on raise to call
        deliver_process_signal.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity):
        * java/org/gnu/emacs/EmacsApplication.java (findDumpFile):
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu)
@@ -1463,201 +1348,184 @@
        (EmacsWindowAttachmentManager): Remove various unused arguments
        and variables, dead stores, and make minor cleanups and
        performance improvements.
+
        * src/androidmenu.c (FIND_METHOD_STATIC, android_menu_show):
        Adjust accordingly.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsInputConnection.java
-       (EmacsInputConnection, beginBatchEdit, reset, endBatchEdit):
-       Keep track of the number of batch edits and return an
-       appropriate value.
+       (EmacsInputConnection, beginBatchEdit, reset, endBatchEdit): Keep
+       track of the number of batch edits and return an appropriate
+       value.
        (takeSnapshot): Implement function.
+
        * java/org/gnu/emacs/EmacsNative.java (takeSnapshot): New
        function.
+
        * java/org/gnu/emacs/EmacsService.java (resetIC): Improve
        debugging output.
+
        * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
        Call `reset' to clear the UI side batch edit count.
-       * src/androidterm.c (struct
-       android_get_surrounding_text_context): New fields
-       `conversion_start' and `conversion_end'.
+
+       * src/androidterm.c (struct android_get_surrounding_text_context):
+       New fields `conversion_start' and `conversion_end'.
        (android_get_surrounding_text): Return the conversion region.
        (android_get_surrounding_text_internal, NATIVE_NAME): Factor out
        `getSurroundingText'.
        (takeSnapshot): New function.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-14  Po Lu  <luangruo@yahoo.com>
 
-       Improve IM synchronization on Android
        * java/org/gnu/emacs/EmacsInputConnection.java
        (EmacsInputConnection): Reimplement as an InputConnection, not
        BaseInputConnection.
+
        * src/androidterm.c (performEditorAction): Sync prior to sending
        keyboard events.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-13  Po Lu  <luangruo@yahoo.com>
 
-       Improve behavior of Gnus on Android
        * etc/NEWS: Fix typo.
+
        * lisp/gnus/gnus-score.el (gnus-read-char): New function.
        (gnus-summary-increase-score): Use it to display a dialog box on
        Android, where input methods have trouble with plain old
        read-char.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-12  Po Lu  <luangruo@yahoo.com>
 
-       Improve appearance of custom dialog buttons on Android
        * java/org/gnu/emacs/EmacsDialog.java (toAlertDialog): Resolve
        dialog button style and use it instead.
 
-       Fix deadlocks
        * java/org/gnu/emacs/EmacsView.java (EmacsView)
        (showOnScreenKeyboard, hideOnScreenKeyboard): Don't synchronize.
+
        * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
-       (toggleOnScreenKeyboard): Revert to calling IMM functions from
-       the main thread.
+       (toggleOnScreenKeyboard): Revert to calling IMM functions from the
+       main thread.
+
        * src/android.c (struct android_event_container)
        (android_pselect_nfds, android_pselect_readfds)
        (android_pselect_writefds, android_pselect_exceptfds)
        (android_pselect_timeout): Don't make volatile.
        (android_wait_event): Run queries if necessary.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-11  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * lisp/net/tramp.el (tramp-encoding-shell):
        * lisp/obsolete/terminal.el (terminal-emulator):
        * lisp/term.el (term-exec-1):
        * lisp/textmodes/artist.el (artist-figlet-get-font-list):
-       * src/android.c (JNICALL): Where /bin/sh was previously used,
-       use /system/bin/sh on Android.
+       * src/android.c (JNICALL): Where /bin/sh was previously used, use
+       /system/bin/sh on Android.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
        Document member variables.
        (onDraw): Use separate Paint object on the UI thread.
+
        * src/textconv.c (really_commit_text, really_set_composing_text)
        (really_delete_surrounding_text): Run modification hooks when
        deleting text.
 
-       Avoid extraneous calls to the UI thread
        * java/org/gnu/emacs/EmacsView.java (EmacsView)
        (showOnScreenKeyboard, hideOnScreenKeyboard)
        (onCheckIsTextEditor): Make synchronized.
+
        * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
        (toggleOnScreenKeyboard): Don't post to the main thread.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-10  Po Lu  <luangruo@yahoo.com>
 
-       ; Update Android port
        * src/keyboard.c (handle_input_available_signal): Don't generate
        instructions not available in arm mode.
 
-       Update Android port
        * src/android.c (android_select, android_check_query)
        (android_check_query_urgent, android_answer_query)
-       (android_answer_query_spin, android_begin_query, android_end_query)
+       (android_answer_query_spin, android_begin_query)
+       (android_end_query)
        (android_run_in_emacs_thread): Use finer grained memory
        synchronization semantics.
+
        * src/androidterm.c (android_get_selection): Use the current
        selection, not its value at the time of the last redisplay.
+
        * src/keyboard.c (handle_input_available_signal): Place memory
        barrier.
 
-       Inherit surrounding text properties when inserting conversion text
        * src/textconv.c (really_commit_text)
        (really_set_composing_text): Improve behavior of certain
        fontification mechanisms by inheriting text properties from
        surrounding text.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Prevent hangs from IM requests with the main thread busy
        * src/android.c (android_select): Clear `android_urgent_query'.
-       (android_check_query): Make static.  Clear
-       `android_urgent_query'.
+       (android_check_query): Make static.  Clear `android_urgent_query'.
        (android_check_query_urgent): New function; work like
        `android_check_query', but only answer urgent queries.
        (android_answer_query, android_end_query): Clear urgent query
        flag.
-       (android_run_in_emacs_thread): Initially wait two seconds for
-       the query to run from the keyboard loop; upon a timeout, set
+       (android_run_in_emacs_thread): Initially wait two seconds for the
+       query to run from the keyboard loop; upon a timeout, set
        `android_urgent_query' to true and wait for it to run while
        reading async input.
+
        * src/android.h: Update prototypes.
+
        * src/keyboard.c (handle_async_input): Call
        `android_check_query_urgent'.
 
 2023-06-09  Po Lu  <luangruo@yahoo.com>
 
-       ; Fix typos
-       * src/textconv.c (really_commit_text):
+       * src/textconv.c (really_commit_text)
        (handle_pending_conversion_events): Fix minor typos.
 
-       Avoid responding to input method queries asynchronously
        * src/androidterm.c (handle_one_android_event): Don't answer
-       queries here; just rely on the event interrupting
-       android_select.  This avoids exposing buffer contents to input
-       methods while a command is being executed.
+       queries here; just rely on the event interrupting android_select.
+       This avoids exposing buffer contents to input methods while a
+       command is being executed.
+
        * src/textconv.c (TEXTCONV_DEBUG, really_commit_text)
        (really_finish_composing_text, really_set_composing_text)
        (really_set_composing_region, really_delete_surrounding_text)
        (really_set_point_and_mark, get_extracted_text): Add debugging
        printouts.
 
-       Initialize text conversion hooks for each C Mode buffer
        * lisp/progmodes/cc-mode.el (c-initialize-cc-mode): Always add
        text conversion hooks.
 
        * src/android.c (android_get_gc_values): Remove redundancy.
 
-       Block profiling signals in the Android UI thread
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
        function `setupSystemThread'.
+
        * java/org/gnu/emacs/EmacsService.java (onCreate): Block all
        signals except for SIGBUS and SIGSEGV in the UI thread.
+
        * src/android.c (setupSystemThread): New function.
 
-       Fix crash starting Emacs to open file
        * java/org/gnu/emacs/EmacsThread.java (run): Correct check
        against extraStartupArgument when an initial file is specified.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-08  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Correctly display popup dialogs from Emacsclient
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
        Make subclasses final.
+
        * java/org/gnu/emacs/EmacsDialog.java (display1): Check if an
        instance of EmacsOpenActivity is open; if it is, try using it to
        display the pop up dialog.
+
        * java/org/gnu/emacs/EmacsDialogButtonLayout.java
        (EmacsDialogButtonLayout): Make final.
-       * java/org/gnu/emacs/EmacsHolder.java (EmacsHolder<T>):
-       Likewise.
+
+       * java/org/gnu/emacs/EmacsHolder.java (EmacsHolder<T>): Likewise.
+
        * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity):
        New field `currentActivity'.
        (onCreate, onDestroy, onWindowFocusChanged, onPause): Set that
        field as appropriate.
 
-       Update Android port
        * src/android.c (android_is_special_directory): New function.
        (android_get_asset_name, android_content_name_p)
        (android_get_content_name):
@@ -1668,64 +1536,59 @@
        * src/inotify.c (IN_ONLYDIR, Finotify_add_watch): Factor out
        checks against asset and content directories to that function.
 
-       ; Update from Gnulib
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-07  Po Lu  <luangruo@yahoo.com>
 
-       ; Update Android port
-       * doc/emacs/android.texi (Android Startup): Fix reference to
-       non existent node.
+       * doc/emacs/android.texi (Android Startup): Fix reference to non
+       existent node.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsInputConnection.java (beginBatchEdit)
-       (endBatchEdit, commitCompletion, commitText, deleteSurroundingText)
+       (endBatchEdit, commitCompletion, commitText)
+       (deleteSurroundingText)
        (finishComposingText, getSelectedText, getTextAfterCursor)
        (getTextBeforeCursor, setComposingText, setComposingRegion)
        (performEditorAction, performContextMenuAction, getExtractedText)
        (setSelection, sendKeyEvent, deleteSurroundingTextInCodePoints)
-       (requestCursorUpdates): Ensure that the input connection is up
-       to date.
+       (requestCursorUpdates): Ensure that the input connection is up to
+       date.
        (getSurroundingText): New function.
-       * java/org/gnu/emacs/EmacsNative.java (getSurroundingText):
-       Export new C function.
+
+       * java/org/gnu/emacs/EmacsNative.java (getSurroundingText): Export
+       new C function.
+
        * java/org/gnu/emacs/EmacsService.java (resetIC): Invalidate
        previously created input connections.
+
        * java/org/gnu/emacs/EmacsView.java (EmacsView)
        (onCreateInputConnection): Signify that input connections are
        now up to date.
-       * src/androidterm.c (struct
-       android_get_surrounding_text_context): New structure.
+
+       * src/androidterm.c (struct android_get_surrounding_text_context):
+       New structure.
        (android_get_surrounding_text, NATIVE_NAME):
        * src/textconv.c (get_surrounding_text):
        * src/textconv.h: New functions.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-06  Po Lu  <luangruo@yahoo.com>
 
        * lisp/simple.el (analyze-text-conversion): Remove old workaround.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-06  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsContextMenu.java (display): Use
        `EmacsHolder' instead of `Holder'.
+
        * java/org/gnu/emacs/EmacsDialog.java (toAlertDialog): Use
        `EmacsDialogButtonLayout' to ensure that buttons are wrapped
        properly.
        (display): Adjust for new holder class.
+
        * java/org/gnu/emacs/EmacsDialogButtonLayout.java
        (EmacsDialogButtonLayout, onMeasure, onLayout): New functions.
 
        * java/org/gnu/emacs/EmacsDrawLine.java:
        * java/org/gnu/emacs/EmacsFillPolygon.java: Remove redundant
        imports.
+
        * java/org/gnu/emacs/EmacsHolder.java (EmacsHolder<T>):
        * java/org/gnu/emacs/EmacsService.java (class Holder<T>)
        (getEmacsView, EmacsService): Rename `Holder' to `EmacsHolder'
@@ -1733,71 +1596,64 @@
 
 2023-06-06  Po Lu  <luangruo@yahoo.com>
 
-       Improve undo behavior on Android
        * lisp/simple.el (undo-auto-amalgamate): Update doc string to
        describe new amalgamating commands.
        (analyze-text-conversion): Make this an amalgamating command by
        default, unless a new line has been inserted.  Also, shorten the
        undo boundary timer.
+
        * src/textconv.c (really_commit_text)
-       (really_set_composing_text): Correctly report ephemeral
-       deletions.
+       (really_set_composing_text): Correctly report ephemeral deletions.
        (syms_of_textconv): Fix doc strings.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-05  Po Lu  <luangruo@yahoo.com>
 
-       Clear batch edit state once a new input connection is established
        * src/androidterm.c (android_handle_ime_event): Clear batch edit
        state, in case the previous input method forgot to do so.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
        function clearInputFlags.
+
        * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
        Stop reporting changes after a new input method connection is
        established.
+
        * src/androidterm.c (android_handle_ime_event): Implement that
        change.
        (JNICALL): New function.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-04  Po Lu  <luangruo@yahoo.com>
 
        * src/keyboard.c: Fix build without window system
 
        * configure.ac: Tune pty detection for Android.
 
-       Fix input method synchronization problems
        * java/debug.sh (gdbserver_cmd, is_root): Prefer TCP again.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function `queryAndSpin'.
+
+       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New function
+       `queryAndSpin'.
+
        * java/org/gnu/emacs/EmacsService.java (EmacsService)
        (icBeginSynchronous, icEndSynchronous, viewGetSelection): New
        synchronization functions.
        (resetIC, updateCursorAnchorInfo): Call those instead.
+
        * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
        Call viewGetSelection.
+
        * src/android.c (JNICALL, android_answer_query_spin): New
        functions.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-03  Po Lu  <luangruo@yahoo.com>
 
-       Fix typos in Android port
        * lisp/bindings.el (global-map): Bind cut, copy and paste.
+
        * src/androidterm.c (JNICALL): Use key.
 
-       Behave correctly when IMEs commit or compose text with active mark
        * src/textconv.c (really_commit_text)
-       (really_set_composing_text): Delete text between mark and point
-       if the mark is active.  Don't record changes if the text is
-       empty.
+       (really_set_composing_text): Delete text between mark and point if
+       the mark is active.  Don't record changes if the text is empty.
 
-       Update Android port
        * src/androidterm.c (struct android_get_extracted_text_context):
        New field `mark_active'.
        (android_get_extracted_text): Set that field.
@@ -1805,39 +1661,41 @@
        (android_build_extracted_text): New argument `mark_active'.  Set
        flags appropriately.
        (NATIVE_NAME, android_update_selection): Likewise.
+
        * src/textconv.c (get_extracted_text): New argument
        `mark_active'.  Set it if the mark is active.
-       * src/textconv.h: Update prototypes.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/textconv.h: Update prototypes.
 
        * etc/MACHINES: Fix reference to obsolete file.
 
 2023-06-02  Po Lu  <luangruo@yahoo.com>
 
-       Improve Eldoc text conversion support
-       * lisp/emacs-lisp/eldoc.el: ("back-to-indentation"): Register
-       touch screen and text conversion commands.
+       * lisp/emacs-lisp/eldoc.el ("back-to-indentation"): Register touch
+       screen and text conversion commands.
 
-       Improve CC Mode support for text conversion
        * lisp/progmodes/cc-cmds.el (c-post-text-conversion): New
        function.
-       * lisp/progmodes/cc-mode.el (c-initialize-cc-mode): Add it as
-       the `post-texxt-conversion-hook'.
+
+       * lisp/progmodes/cc-mode.el (c-initialize-cc-mode): Add it as the
+       `post-texxt-conversion-hook'.
+
        * lisp/simple.el (post-text-conversion-hook): New hook.
-       (analyze-text-conversion): Run it until success before trying
-       post insert functions.
+       (analyze-text-conversion): Run it until success before trying post
+       insert functions.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsInputConnection.java
-       (EmacsInputConnection): Apply workarounds on Vivo devices as
-       well.
+       (EmacsInputConnection): Apply workarounds on Vivo devices as well.
+
        * src/android.c (sendKeyPress, sendKeyRelease): Clear counter.
+
        * src/androidgui.h (struct android_key_event): New field
        `counter'.
-       * src/androidterm.c (handle_one_android_event): Generate
-       barriers as appropriate.
+
+       * src/androidterm.c (handle_one_android_event): Generate barriers
+       as appropriate.
        (JNICALL): Set `counter'.
+
        * src/frame.h (enum text_conversion_operation):
        * src/textconv.c (detect_conversion_events)
        (really_set_composing_text, handle_pending_conversion_events_1)
@@ -1845,52 +1703,51 @@
        * src/textconv.h: Implement text conversion barriers and fix
        various typos.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-06-01  Po Lu  <luangruo@yahoo.com>
 
-       Correctly export file:// URIs on Android
        * java/org/gnu/emacs/EmacsService.java (browseUrl): If uri's
        scheme is `file', rewrite it into a content URI.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsInputConnection.java
        (EmacsInputConnection, performContextMenuAction): New function.
+
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative)
        (performContextMenuAction): New function.
+
        * src/android.c (android_get_gc_values): Implement more
        efficiently.
+
        * src/androidterm.c (android_handle_ime_event): Pass through
        `update' argument to `finish_composing_text'.  Fix thinko.
+
        * src/textconv.c (really_finish_composing_text)
        (really_set_composing_text, really_set_composing_region)
        (handle_pending_conversion_events_1, finish_composing_text): New
        argument `update'.  Notify IME of conversion region changes if
        set.
+
        * src/textconv.h: Update structs and prototypes.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsInputConnection.java
-       (EmacsInputConnection): Add compatibility adjustments for
-       Samsung devices.
+       (EmacsInputConnection): Add compatibility adjustments for Samsung
+       devices.
 
-       Correctly report start and end in extracted text
        * src/androidterm.c (struct android_get_extracted_text_context):
        New field `start_offset' and `end_offset'.  Delete `offset'.
        (android_get_extracted_text, android_build_extracted_text):
        Replace `offset' with new args `start_offset' and `end_offset'.
        (NATIVE_NAME): Set `start_offset' and `end_offset'.
        (android_update_selection): Likewise.
+
        * src/textconv.c (get_extracted_text): Likewise.
-       * src/textconv.h: Update prototypes.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/textconv.h: Update prototypes.
 
 2023-05-31  Po Lu  <luangruo@yahoo.com>
 
-       Fix build with Lisp_Object type checking
-       * configure.ac: Pass through `--enable-check-lisp-object-type'
-       on Android.
+       * configure.ac: Pass through `--enable-check-lisp-object-type' on
+       Android.
+
        * src/alloc.c (android_make_lisp_symbol):
        * src/android.c:
        * src/androidfns.c (android_set_no_focus_on_map)
@@ -1900,88 +1757,72 @@
        (Fandroid_get_clipboard_targets):
        * src/keyboard.c (make_lispy_event, syms_of_keyboard):
        * src/sfntfont.c (sfnt_enum_font_1, sfntfont_list_1):
-       * src/textconv.c (really_set_point_and_mark): Fix Lisp_Object
-       and integer screw-ups.
+       * src/textconv.c (really_set_point_and_mark): Fix Lisp_Object and
+       integer screw-ups.
 
-       Update Android port
        * doc/emacs/input.texi (Other Input Devices, Touchscreens)
        (On-Screen Keyboards):
        * doc/lispref/commands.texi (Misc Events):
        * src/android.c (android_faccessat): Improve word choices and
        commentary.
+
        * lisp/touch-screen.el (touch-screen-handle-scroll): Make
        precision scrolling work better with horizontal movement.
 
        * src/android.c (android_copy_area): Pacify compiler warning.
 
-       Update Android port
-       * exec/exec.c (insert_args): New argument `arg3'.  Replace
-       argv[1] with that argument.
+       * exec/exec.c (insert_args): New argument `arg3'.  Replace argv[1]
+       with that argument.
        (exec_0): Pass file name of script to `insert_args'.
 
-       Update android.texi
-       * doc/emacs/android.texi (What is Android?):
-       (Android Startup):
-       (Android File System):
-       (Android Environment):
-       (Android Windowing):
+       * doc/emacs/android.texi (What is Android?, Android Startup)
+       (Android File System, Android Environment, Android Windowing)
        (Android Troubleshooting): Improve wording and various other
        issues.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * java/debug.sh (is_root): Go back to using unix sockets; allow
        adb to forward them correctly.
+
        * java/org/gnu/emacs/EmacsInputConnection.java
        (getExtractedText): Don't print text if NULL.
+
        * java/org/gnu/emacs/EmacsService.java (EmacsService): New field
        `imSyncInProgress'.
        (updateIC): If an IM sync might be in progress, avoid deadlocks.
+
        * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
        Set `imSyncInProgress' across synchronization point.
+
        * src/android.c (android_check_query): Use __atomic_store_n.
        (android_answer_query): New function.
-       (android_begin_query): Set `android_servicing_query' to 2.
-       Check once, and don't spin waiting for query to complete.
+       (android_begin_query): Set `android_servicing_query' to 2.  Check
+       once, and don't spin waiting for query to complete.
        (android_end_query): Use __atomic_store_n.
        (android_run_in_emacs_thread): Compare-and-exchange flag.  If
        originally 1, fail.
+
        * src/textconv.c (really_set_composing_text): Clear conversion
        region if text is empty.
 
-2023-05-30  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-29  Po Lu  <luangruo@yahoo.com>
 
-       * src/android.c: Fix typos.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_blit_copy, android_blit_xor): Fix typos.
 
-       Update Android port
-       * src/android.c (android_blit_copy):
-       (android_blit_xor): Fix typos.
+       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New function
+       `blitRect'.
 
-       * src/android.c (android_blit_copy): Fix typos.
+       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView): Use
+       it on Android 8.x.
 
-       Work around more problems with Bitmaps
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function `blitRect'.
-       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
-       Use it on Android 8.x.
        * src/android.c (blitRect): Implement new function.
-
-       Update Android port
-       * src/android.c (android_neon_mask_line): Fix iteration
-       over remainder.
+       (android_neon_mask_line): Fix iteration over remainder.
        (android_blit_copy): Be more paranoid.
 
-       Implement android_copy_area in C
        * java/org/gnu/emacs/EmacsCopyArea.java: Remove file.
-       * java/org/gnu/emacs/EmacsService.java (EmacsService, copyArea):
-       Delete function.
+
+       * java/org/gnu/emacs/EmacsService.java (copyArea): Delete
+       function.
+
        * src/android.c (struct android_emacs_service)
        (android_init_emacs_service): Remove `copy_area'.
        (android_create_gc, android_change_gc, android_get_gc_values):
@@ -1990,68 +1831,66 @@
        (android_blit_copy, android_blit_xor): New functions.
        (android_copy_area): Implement in C.
        (android_lock_bitmap): Accept drawables instead of windows.
+
        * src/android.h: Adjust prototype for `android_lock_bitmap'.
+
        * src/androidgui.h (struct android_gc): Record last known GC
        values.
 
 2023-05-27  Po Lu  <luangruo@yahoo.com>
 
-       Add extra thread-related checking
        * java/org/gnu/emacs/EmacsService.java (EmacsService)
        (checkEmacsThread): New function.
        (fillPolygon, drawRectangle, drawLine, drawPoint, copyArea)
        (clearArea):
        * java/org/gnu/emacs/EmacsThread.java (EmacsThread):
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, swapBuffers):
-       Call where appropriate.
+       * java/org/gnu/emacs/EmacsView.java (EmacsView, swapBuffers): Call
+       where appropriate.
 
-       Remove synchronization around `damageRegion'
        * java/org/gnu/emacs/EmacsView.java (EmacsView, swapBuffers):
-       Remove unnecessary documentation.  `damageRegion' is only
-       changed from the Emacs thread.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       Remove unnecessary documentation.  `damageRegion' is only changed
+       from the Emacs thread.
 
 2023-05-26  Po Lu  <luangruo@yahoo.com>
 
-       Allow starting Emacs --debug-init on Android
        * doc/emacs/android.texi (Android Troubleshooting): Document
        `debug-init' option.
+
        * java/AndroidManifest.xml.in
        (EmacsLauncherPreferencesActivity): New activity.  Export on
        systems older than Android 7.0.
+
        * java/org/gnu/emacs/EmacsActivity.java (onCreate): Adjust for
        string startup argument.
+
        * java/org/gnu/emacs/EmacsLauncherPreferencesActivity.java: New
        file.
+
        * java/org/gnu/emacs/EmacsPreferencesActivity.java
        (EmacsPreferencesActivity): Don't make final.
        (startEmacsQ): Give start-up argument as an argument, not as a
        boolean.
        (startEmacsDebugInit): New function.
        (onCreate): Register new listener; make final.
+
        * java/org/gnu/emacs/EmacsService.java (onCreate): Pass
        extraStartupArgument.
+
        * java/org/gnu/emacs/EmacsThread.java (EmacsThread): Rename
        startDashQ to extraStartupArgument.
        (run): Adjust accordingly.
+
        * java/res/values-v24/bool.xml:
        * java/res/values/bool.xml:
        * java/res/values/strings.xml: New files.
+
        * java/res/xml/preferences.xml: Add new option.  Move string
        resources around.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-25  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-24  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * src/sfnt.c (sfnt_decompose_compound_glyph): Allow decomposing
-       up to 16 nested components.
+       * src/sfnt.c (sfnt_decompose_compound_glyph): Allow decomposing up
+       to 16 nested components.
        (CALL, LOOPCALL): Correctly error if no fdef storage exists.
        (sfnt_interpret_run): New label `next_instruction', for CALL.
        (sfnt_interpret_compound_glyph_1): Allow decomposing up to 16
@@ -2060,58 +1899,39 @@
        (sfnt_read_cvar_table): Prevent assigning uninitialized values.
        (sfnt_vary_simple_glyph): Update commentary.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-23  Po Lu  <luangruo@yahoo.com>
 
        * exec/exec.c (exec_0): Use strcpy.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-22  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-21  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-20  Po Lu  <luangruo@yahoo.com>
 
-       Remove arbitrary process count limit
-       * exec/trace.c (handle_clone_prepare):
-       (handle_clone): When !REENTRANT, use malloc to allocate
-       tracees after running out of static ones.
+       * exec/trace.c (handle_clone_prepare, handle_clone): When
+       !REENTRANT, use malloc to allocate tracees after running out of
+       static ones.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsView.java (swapBuffers): Restore
-       missing damage rect code.
+       * java/org/gnu/emacs/EmacsView.java (swapBuffers): Restore missing
+       damage rect code.
        (onDetachedFromWindow): Remove redundant synchronization.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-19  Po Lu  <luangruo@yahoo.com>
 
-       Make tapping on header lines behave reasonably
        * lisp/touch-screen.el (touch-screen-tap-header-line): New
        function.
        ([header-line touchscreen-begin]): Define to
        `touch-screen-tap-header-line'.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-18  Po Lu  <luangruo@yahoo.com>
 
        * make-dist (possibly_non_vc_files): Add Android-specific files.
 
-       Allow interacting with the tab line from a touch screen
        * doc/emacs/frames.texi (Tab Bars): Explain how to interact with
        the tab bar from a touch screen.
+
        * doc/emacs/input.texi (Touchscreens): Document exactly what a
        ``long press'' is.
+
        * doc/emacs/windows.texi (Tab Line): Likewise.
+
        * lisp/tab-line.el (tab-line-tab-map, tab-line-add-map)
        (tab-line-tab-close-map, tab-line-left-map, tab-line-right-map):
        Bind `touchscreen-begin' to each command.
@@ -2119,322 +1939,272 @@
        (tab-line-hscroll-right, tab-line-hscroll-left, tab-line-new-tab)
        (tab-line-select-tab, tab-line-close-tab): Use them.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-17  Po Lu  <luangruo@yahoo.com>
-
-       ; Update from Gnulib
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-16  Po Lu  <luangruo@yahoo.com>
 
-       Add touchscreen support to the tab bar
        * lisp/menu-bar.el (popup-menu-normalize-position): Normalize
        `touchscreen-begin' events correctly.
-       * lisp/tab-bar.el (tab-bar-mouse-context-menu): New argument
-       POSN.  Use it if specified.
+
+       * lisp/tab-bar.el (tab-bar-mouse-context-menu): New argument POSN.
+       Use it if specified.
        (touch-screen-track-tap, tab-bar-handle-timeout)
        (tab-bar-touchscreen-begin): New functions.
        (tab-bar-map): Bind [tab-bar touchscreen-begin].
+
        * lisp/touch-screen.el (touch-screen-track-drag): Fix doc
        string.
+
        * src/dispextern.h: Export `get_tab_bar_item_kbd'.
+
        * src/keyboard.c (coords_in_tab_bar_window): New function.
        (make_lispy_event): Adjust touchscreen begin event mouse
        position list for tab bar.
+
        * src/xdisp.c (tab_bar_item_info): Allow CLOSE_P to be NULL.
        (get_tab_bar_item): Adjust doc string.
        (get_tab_bar_item_kbd): New function.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-15  Po Lu  <luangruo@yahoo.com>
 
-       Fix year 2038 code for Android 4.4 and earlier
        * configure.ac: Also disable enable_year2038.
 
-       Fix the MS-DOS build
        * msdos/sed1v2.inp: Fix removal of ANDROID_BUILD_CFLAGS.
-       * msdos/sedlibmk.inp: Clear DIR_HAS_FD_MEMBER and
-       LOCALE_FR_UTF8.
-
-       ; Update from Gnulib
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * msdos/sedlibmk.inp: Clear DIR_HAS_FD_MEMBER and LOCALE_FR_UTF8.
 
 2023-05-14  Po Lu  <luangruo@yahoo.com>
 
-       Implement document moving on Android
        * java/org/gnu/emacs/EmacsDocumentsProvider.java
        (notifyChangeByName): New function.
        (queryDocument1): Set FLAG_SUPPORTS_MOVE where necessary.
        (moveDocument): Implement new function.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-13  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-12  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-11  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-10  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-05-09  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-08  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/Makefile.in (install_temp/assets/version): Fix generation
        in out of tree builds.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-07  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsInputConnection.java
        (requestCursorUpdates):
        * java/org/gnu/emacs/EmacsNative.java (requestCursorUpdates):
        * java/org/gnu/emacs/EmacsService.java (updateCursorAnchorInfo):
        New functions.
+
        * src/android.c (struct android_emacs_service)
        (android_init_emacs_service): Add new method.
        (android_update_cursor_anchor_info): New function.
+
        * src/androidfns.c (android_set_preeditarea): New function.
+
        * src/androidgui.h (enum android_ime_operation): New operation
        `REQUEST_CURSOR_UPDATES'.
        (struct android_ime_event): Document new meaning of `length'.
+
        * src/androidterm.c (android_request_cursor_updates): New
        function.
        (android_handle_ime_event): Handle new operations.
        (handle_one_android_event, android_draw_window_cursor): Update
        the preedit area if needed, like on X.
        (requestCursorUpdates): New function.
+
        * src/androidterm.h (struct android_output): New field
        `need_cursor_updates'.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-06  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * configure.ac (LIBGMP_CFLAGS): Avoid non portable test
        expression.
 
-       Update Android port
-       * cross/verbose.mk.android: Get rid of badly aligned ANDROID_CC
-       messages.
+       * cross/verbose.mk.android (AM_V_CC): Get rid of badly aligned
+       ANDROID_CC messages.
+
        * java/org/gnu/emacs/EmacsInputConnection.java (syncAfterCommit)
        (extractAbsoluteOffsets): Add workarounds for several kinds of
        machines.
        (commitText, getExtractedText): Likewise.
+
        * src/textconv.c (really_commit_text): Improve definition of
        POSITION.
-       (get_extracted_text): Default to providing at least 4
-       characters.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       (get_extracted_text): Default to providing at least 4 characters.
 
 2023-05-05  Po Lu  <luangruo@yahoo.com>
 
-       Fix execution of /proc/self/exe within child processes
-       * exec/exec.h (struct exec_tracee): New field `new_child'.
-       Also, make `waiting_for_syscall' a bitfield.
+       * exec/exec.h (struct exec_tracee): New field `new_child'.  Also
+       make `waiting_for_syscall' a bitfield.
+
        * exec/trace.c (PTRACE_GETEVENTMSG): New declaration.
        (MAX_TRACEES): Bump to 4096.
        (handle_clone_prepare): New function.
-       (handle_clone): If required, set `new_child' and wait for a
-       ptrace event describing the parent to arrive.
+       (handle_clone): If required, set `new_child' and wait for a ptrace
+       event describing the parent to arrive.
        (after_fork): Clear new field.
-       (exec_waitpid): Upon a ptrace event describing a clone, create
-       the child's tracee if it doesn't already exist.  Otherwise, copy
-       over the parent's cmdline and start running it.
+       (exec_waitpid): Upon a ptrace event describing a clone, create the
+       child's tracee if it doesn't already exist.  Otherwise, copy over
+       the parent's cmdline and start running it.
 
-       Update Android port
        * doc/emacs/android.texi (Android Environment): Document lossage
        with SIGSTOP.
+
        * exec/exec.c (exec_0): Check X_OK on file being opened.  Also
        handle /proc/self/exe.
 
-       Update Android port
        * exec/trace.c (SYS_SECCOMP): Define when not present.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-04  Po Lu  <luangruo@yahoo.com>
 
-       Document another misfeature of Android
        * doc/emacs/android.texi (Android Environment): Describe how to
        turn off process killing.
 
-       Update Android port
        * exec/trace.c (check_signal): New function.
        (handle_exec, process_system_call): Handle signal-delivery-stop
        while waiting synchronously for syscall completion.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-03  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * exec/config.h.in: Autoheader.
+       * exec/config.h.in: Update from new automatically generated
+       headers.
+
        * exec/configure.ac: Check for siginfo_t.si_syscall.
-       * exec/trace.c (exec_waitpid): If SIGSYS is received, and caused by
-       seccomp, drop it should the call number be the invalid system call
-       used by Emacs.
 
-       Update Android port
-       * exec/config.h.in: Autoheader.
+       * exec/trace.c (exec_waitpid): If SIGSYS is received, and caused
+       by seccomp, drop it should the call number be the invalid system
+       call used by Emacs.
+
        * exec/configure.ac: Use system extensions.
        (HAVE_PROCESS_VM): Define if process_vm_readv and
        process_vm_writev are available.
+
        * exec/trace.c (read_memory, user_copy): Implement in terms of
        process_vm if possible.
 
-       Remove extra debugging code
        * exec/loader-mipsel.s (__start): Remove extraneous debugging
        code.
 
-       Update Android port
        * exec/Makefile.in: (.PHONY): Add `bootstrap-clean' and
        `extraclean'.
        (bootstrap-clean): New rule.
 
-       Update Android port
        * java/Makefile.in (FIND_DELETE): New substitution.
        (clean): Use FIND_DELETE.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-05-02  Po Lu  <luangruo@yahoo.com>
 
        * doc/emacs/android.texi (Android Environment): Improve doc.
 
-       Update Android port
        * exec/config.h.in (__bool_true_false_are_defined):
-       * exec/configure.ac (REENTRANT): New definition.
+       * exec/configure.ac (REENTRANT): New definitions.
        (READLINKAT_SYSCALL, READLINK_SYSCALL): New defines.  Set on all
        hosts.
-       * exec/exec.c (MIN, MAX): Remove redundant declarations.  Move
-       to config.h.
+
+       * exec/exec.c (MIN, MAX): Remove redundant declarations.  Move to
+       config.h.
        (exec_0): Copy name of executable into NAME when !REENTRANT.
+
        * exec/exec.h (struct exec_tracee): New struct `exec_file'.
+
        * exec/trace.c (remove_tracee, handle_exec, handle_readlinkat)
-       (process_system_call, after_fork): Handle readlinkat system
-       calls.
+       (process_system_call, after_fork): Handle readlinkat system calls.
 
-       Fix ps name in Android subprocesses
        * exec/Makefile.in (.SUFFIXES): Include ., then `srcdir'.
+
        * exec/loader-aarch64.s (_start):
        * exec/loader-armeabi.s (_start):
        * exec/loader-mips64el.s (__start):
        * exec/loader-mipsel.s (__start):
        * exec/loader-x86.s (_start):
-       * exec/loader-x86_64.s (_start): Get basename of opened exec
-       file and make it the command name.  Fix envp skipping on x86
-       and various leaks.
+       * exec/loader-x86_64.s (_start): Get basename of opened exec file
+       and make it the command name.  Fix envp skipping on x86 and
+       various leaks.
 
-       Port Android port to older Android systems
-       * exec/config.h.in: Autoheader.
-       * exec/configure.ac: Check for declarations of stpcpy and
-       stpncpy.
-       * exec/exec.c (stpcpy, stpncpy): Use replacements if
-       declarations are not present; this happens when a new Android
-       NDK is building for an old version of Android.
+       * exec/configure.ac: Check for declarations of stpcpy and stpncpy.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * exec/exec.c (stpcpy, stpncpy): Use replacements if declarations
+       are not present; this happens when a new Android NDK is building
+       for an old version of Android.
 
 2023-05-01  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * exec/config.h.in: Update config.h.in.
+
        * exec/configure.ac: Check for stpcpy and stpncpy.
-       * exec/exec.c (rpl_stpcpy, rpl_stpncpy): Define replacements
-       when they are not present on the system.
+
+       * exec/exec.c (rpl_stpcpy, rpl_stpncpy): Define replacements when
+       they are not present on the system.
        (process_program_header): Fill comment.
 
        * src/term.c (syms_of_term): Pretend Android uses TERMINFO.
 
-       Fix cwd relative process execution on Android
        * exec/exec.c (format_pid): New function.
-       (exec_0): Make cwd relative file names relative to
-       /proc/pid/cwd.
+       (exec_0): Make cwd relative file names relative to /proc/pid/cwd.
+
        * exec/trace.c (handle_exec): Handle EINTR.
+
        (process_system_call): Report failure without clobbering x0.
 
        * README: Describe `exec' directory.
 
-       Fix use dialog box regression on Android
        * lisp/subr.el (use-dialog-box-p): Always prefer dialog boxes.
 
-       Make it easier to quit on Android
-       * src/android.c (android_write_event):
-       (JNICALL): Raise SIGIO on key press and window action events.
+       * src/android.c (android_write_event, JNICALL): Raise SIGIO on key
+       press and window action events.
 
-       Fix syscall error reporting on aarch64
-       * exec/trace.c (process_system_call): Save and restore x0, x1
-       and x2 regs after replacing them with an invalid file
-       descriptor.
+       * exec/trace.c (process_system_call): Save and restore x0, x1 and
+       x2 regs after replacing them with an invalid file descriptor.
 
-       Update Android port
        * Makefile.in (extraclean): Clean in exec as well.
+
        * configure.ac: Fix detection of absolute srcdir.  Also, pass
        CFLAGS.
-       * exec/Makefile.in: (.c.o): Add -I. so config.h can be
-       found.:(.s.o): Don't create m4 temporary in srcdir.
-       * exec/config-mips.m4.in (DADDI2, DADDI3): New macros.  Define
-       to substitute if as cannot assemble daddi.
+
+       * exec/Makefile.in: (.c.o): Add -I. so config.h can be found.
+       (.s.o): Don't create m4 temporary in srcdir.
+
+       * exec/config-mips.m4.in (DADDI2, DADDI3): New macros.  Define to
+       substitute if as cannot assemble daddi.
+
        * exec/configure.ac (user_h): Look for user.h in asm/ as well.
        Use new user.h.  Also look in ptrace.h on arm systems.  Check if
        as supports daddi on mips64.
+
        * exec/exec.c (check_interpreter): Fix char signedness bug.
-       * exec/loader-mips64el.s (__start): Use DADDI2 and DADDI3 for
-       two- and 3-operand daddi.
+
+       * exec/loader-mips64el.s (__start): Use DADDI2 and DADDI3 for two-
+       and 3-operand daddi.
+
        * exec/mipsel-user.h: Don't include sgidefs.h.
+
        * java/INSTALL: Document that m4 is now required.
-       * src/android.c (android_rewrite_spawn_argv): Add missing NULL.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_rewrite_spawn_argv): Add missing NULL.
 
-       Work around system restrictions regarding exec
        * doc/emacs/android.texi (Android Environment): Document
        `android-use-exec-loader'.
+
        * exec/exec1.c (main): Set program group of child process.
+
        * src/android.c (android_rewrite_spawn_argv): New function.
+
        * src/android.h: Update prototypes.
+
        * src/androidfns.c (syms_of_androidfns): New variable
        `android_use_exec_loader'.
-       * src/callproc.c (emacs_spawn): Rewrite the argument vector to
-       use exec1 if necessary.
 
-       Remove exec/configure
-       * exec/configure: Remove file.
+       * src/callproc.c (emacs_spawn): Rewrite the argument vector to use
+       exec1 if necessary.
+
        * .gitignore: Add exec/configure.
 
 2023-04-30  Po Lu  <luangruo@yahoo.com>
 
-       Add helper binary `exec1'
        * .gitignore: New files.
+
        * Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
        exists.
+
        * autogen.sh (do_git): Autoreconf in exec as well.
+
        * configure.ac: Configure libexec on Android.
+
        * exec/Makefile.in:
        * exec/README:
        * exec/config-mips.m4.in:
@@ -2470,182 +2240,94 @@
        (user_alloca, user_copy, remove_tracee, handle_clone)
        (syscall_trap_p, handle_exec, process_system_call, tracing_execve)
        (after_fork, find_tracee, exec_waitpid, exec_init): New files.
-       * java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
-       loader.
+       * java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and loader.
        ($(CROSS_EXEC_BINS) &): New target.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-04-29  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * build-aux/ndk-build-helper.mk (TARGET_ARCH): Define variable.
+
        * configure.ac (ENABLE_CHECKING, CHECK_STRUCTS)
        (GC_CHECK_STRING_OVERRUN, GC_CHECK_STRING_FREE_LIST, GLYPH_DEBUG)
        (GC_CHECK_STRING_BYTES): Enable checking correctly on Android.
+
        * java/README: Fix typos.
+
        * m4/ndk-build.m4 (ndk_run_test): Pass target arch.
+
        * src/android.c (android_get_content_name, android_close)
        (android_fclose, android_check_string): Fix various typos caught
        by checking.
+
        * src/charset.c (load_charset_map_from_file): Call emacs_fclose,
        not fclose.
-       * src/image.c (image_set_transform): Fix thinko.
-       (png_load_body, jpeg_load_body, gif_load): Call emacs_fclose,
-       not fclose.  Use open instead of fdopen.
-       * src/xfaces.c (Fx_load_color_file): Likewise.
 
-2023-04-28  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/image.c (image_set_transform): Fix thinko.
+       (png_load_body, jpeg_load_body, gif_load): Call emacs_fclose, not
+       fclose.  Use open instead of fdopen.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/xfaces.c (Fx_load_color_file): Likewise.
 
 2023-04-27  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * src/image.c (image_create_bitmap_from_data): Fix typo in
        preprocessor conditionals.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * doc/emacs/android.texi (Android File System, Android Windowing):
+       Make Emacs manual more portable.
 
-       Update Android port
-       * doc/emacs/android.texi (Android File System):
-       (Android Windowing): Make Emacs manual more portable.
-
-       Update Android port
        * doc/lispref/commands.texi (Misc Events):
-       * doc/lispref/frames.texi (Accessing Selections):
-       (X Selections): Fix pieces of the Info manual.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * doc/lispref/frames.texi (Accessing Selections, X Selections):
+       Fix pieces of the Info manual.
 
 2023-04-26  Po Lu  <luangruo@yahoo.com>
 
-       Make two well known amusements work on Android
-       * lisp/play/doctor.el (text-conversion-style):
-       (doctor-mode):
-       * lisp/play/dunnet.el (text-conversion-style):
-       (dun-mode): Set `text-conversion-style' to `action'.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-25  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-24  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-23  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-22  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-21  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-20  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-19  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-18  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-17  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-16  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-15  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-14  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * lisp/play/doctor.el (text-conversion-style, doctor-mode):
+       * lisp/play/dunnet.el (text-conversion-style, dun-mode): Set
+       `text-conversion-style' to `action'.
 
 2023-04-13  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/android.texi (Android Fonts): Update documentation.
+
        * doc/lispref/frames.texi (Accessing Selections, X Selections):
        Fix typos.
+
        * src/sfntfont-android.c (system_font_directories)
        (init_sfntfont_android): Add `/product/fonts'.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-12  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-11  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-10  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-09  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-04-08  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Document selections on Android more thoroughly
        * doc/lispref/elisp.texi (Top):
        * doc/lispref/frames.texi (Frames): Add ``Accessing Selections''
        to menu.
-       (Accessing Selections, X Selections, Other Selections): New
-       nodes.
-
-2023-04-07  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       (Accessing Selections, X Selections, Other Selections): New nodes.
 
 2023-04-06  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-06  Po Lu  <luangruo@yahoo.com>
-
-       Implement `yank-media' on Android
        * doc/emacs/android.texi (Android Windowing): Update selection
        restrictions.
+
        * java/org/gnu/emacs/EmacsClipboard.java (EmacsClipboard): New
        functions `getClipboardTargets' and `getClipboardData'.
+
        * java/org/gnu/emacs/EmacsSdk11Clipboard.java
        (EmacsSdk11Clipboard, getClipboardTargets, getClipboardData):
-       Implement.
+       Implement these virtual functions defined in EmacsClipboard.
+
        * java/org/gnu/emacs/EmacsSdk8Clipboard.java: Stub out new
        functions.
 
        * lisp/term/android-win.el (android-get-clipboard-1): Implement
        MIME type targets.
+
        * src/android.c (android_exception_check)
        (android_exception_check_1, android_exception_check_2): Fix
        punctuation in warning message.
        (android_exception_check_nonnull_1): New function.
+
        * src/android.h: Update prototypes.
+
        * src/androidselect.c (struct android_emacs_clipboard): New
        methods.
        (android_init_emacs_clipboard): Initialize new methods.
@@ -2653,58 +2335,24 @@
        (Fandroid_get_clipboard_data): New functions.
        (syms_of_androidselect): Define new subrs.
 
-2023-04-05  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-04-04  Po Lu  <luangruo@yahoo.com>
 
-       * lisp/subr.el (read-char-from-minibuffer): Fix typo.
-
-       Update Android port
        * lisp/subr.el (read-char-from-minibuffer): Don't use undefined
        variable.  Reported by Robert Pluim.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-04-03  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       ; * src/androidselect.c (Fandroid_clipboard_exists_p): Add check.
-
-       Update Android port
        * src/sfnt.c (sfnt_normalize_vector): Don't rely on undefined
        sign extension semantics.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-02  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-04-01  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-03-31  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-30  Po Lu  <luangruo@yahoo.com>
 
-       Tweak outline cache stuff
        * src/sfntfont.c: Adjust font cache size constants.
 
        * src/sfnt.c (GETINFO): Fix typo.
 
        * src/sfnt.h: Fix typo.
 
-       Update Android port
        * src/sfnt.c (sfnt_make_interpreter): New argument `fvar'.  Set
        axis count.
        (SCANCTRL): Implement selector bit 8.
@@ -2717,72 +2365,50 @@
        (sfnt_vary_interpreter): Set naxis and norm_coords.
        (sfnt_make_test_interpreter, pushb_test_args, pushw_test_args)
        (sfnt_name_instruction, main): Adjust accordingly.
-       * src/sfnt.h (struct sfnt_interpreter, PROTOTYPE):
-       * src/sfntfont.c (sfntfont_setup_interpreter, sfntfont_open):
-       Set up distortion information.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/sfnt.h (struct sfnt_interpreter):
+       * src/sfntfont.c (sfntfont_setup_interpreter, sfntfont_open): Set
+       up distortion information.
 
 2023-03-29  Po Lu  <luangruo@yahoo.com>
 
-       Improve rules for enumerating user fonts
        * doc/emacs/android.texi (Android Fonts): Document distortable
        font replacement rules.
+
        * src/sfntfont.c (sfnt_replace_fonts_p): New function.
        (sfnt_enum_font_1): Call it.
 
-       Fix optimized move functions
-       * src/sfnt.c (sfnt_move_x):
-       (sfnt_move_y):
-       (sfnt_move): Set N flags and don't forget to
-       set N points too.
-
-       * src/sfnt.c (sfnt_read_avar_table): Fix sequencing problem.
+       * src/sfnt.c (sfnt_move_x, sfnt_move_y, sfnt_move): Set N flags
+       and don't forget to set N points too.
+       (sfnt_read_avar_table): Fix sequencing problem.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/sfntfont.c (sfntfont_setup_interpreter): Don't create
        interpreter for blatently broken fonts.
+       (sfntfont_open): Avoid specifying redundant blends.
 
-       Update Android port
-       * src/sfntfont.c (sfntfont_open): Avoid specifying redundant
-       blends.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/sfnt.c (sfnt_validate_gs): Fix validation of projection
        vector.
 
 2023-03-28  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * src/sfnt.c (sfnt_vary_compound_glyph):
        * src/sfntfont.c (sfntfont_get_glyph)
        (sfntfont_get_glyph_outline): Avoid clobbering offset size flag
        when varying compound glyph.
 
-       Update Android port
        * src/sfnt.c (sfnt_vary_simple_glyph, sfnt_vary_compound_glyph):
        Fix application of intermediate tuples.
        * src/sfntfont.c (sfntfont_open): Set xlfd name after applying
        distortion.
 
-       Correctly round lbearing values
        * src/sfnt.h (SFNT_ROUND_FIXED):
        * src/sfntfont.c (sfntfont_probe_widths):
        (sfntfont_measure_pcm): Round lbearing properly.
+       (sfnt_open_tables): Fix typos in non-HarfBuzz code.
 
-       Update Android port
-       * src/sfntfont.c (sfnt_open_tables): Fix typos in non-HarfBuzz
-       code.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/androidterm.c (android_draw_image_glyph_string): Restore
        potentially clobbered GC clipping.
+
        * src/sfnt.c (sfnt_large_integer_add, sfnt_multiply_divide_round)
        (sfnt_mul_fixed_round): New functions.
        (sfnt_build_glyph_outline): Take unscaled glyph metrics.
@@ -2790,24 +2416,24 @@
        (sfnt_vary_compound_glyph, sfnt_vary_interpreter): Use rounding
        multiplication to scale deltas.
        (main): Adjust tests.
+
        * src/sfntfont.c (sfntfont_get_glyph_outline)
        (sfntfont_probe_widths, sfntfont_open, sfntfont_measure_pcm)
        (sfntfont_draw): More minor fixes to variable fonts.
 
 2023-03-27  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * src/sfnt.c (sfnt_normalize_blend): Don't crash when axis
        variations are not present.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * configure.ac (HAVE_OTF_GET_VARIATION_GLYPHS): Check for
        `hb_font_set_var_named_instance'.
+
        * src/sfnt.c (main): Update tests.
+
        * src/sfntfont-android.c (Fandroid_enumerate_fonts): Blacklist
        bad font.
+
        * src/sfntfont.c (struct sfnt_font_tables, struct sfnt_font_desc)
        (sfnt_decode_instance_name, sfnt_weight_descriptions)
        (sfnt_enum_font_1, sfntfont_list_1, sfntfont_desc_to_entity)
@@ -2818,24 +2444,22 @@
        (sfntfont_draw, sfntfont_begin_hb_font, syms_of_sfntfont)
        (mark_sfntfont): Handle variable fonts correctly.
 
-       Refactor sfntfont.c
        * src/sfnt.c (sfnt_build_glyph_outline): Take scale, not head
        and pixel size.
        (sfnt_scale_metrics_to_pixel_size): Delete function.
        (sfnt_get_scale): New function.
        (main): Update tests.
-       * src/sfnt.h (PROTOTYPE): Update prototypes.
+
+       * src/sfnt.h: Update prototypes.
+
        * src/sfntfont.c (struct sfnt_outline_cache)
        (sfntfont_get_glyph_outline, struct sfnt_font_info)
        (sfntfont_open): Save scale in font information and use it.
        (sfntfont_measure_instructed_pcm): Delete function.
        (sfntfont_measure_pcm): Make this the only ``measure pcm''
        function.
-       (sfntfont_draw): Rely on sfntfont_get_glyph_outline for the
-       scale.
-
-       Refactor sfntfont.c
-       * src/sfntfont.c (struct sfnt_font_tables): New structure.
+       (sfntfont_draw): Rely on sfntfont_get_glyph_outline for the scale.
+       (struct sfnt_font_tables): New structure.
        (struct sfnt_font_desc): New field `tables'.
        (struct sfnt_font_info): New field `desc'.
        (sfntfont_setup_interpreter): Drop fd arguments and don't try to
@@ -2848,11 +2472,6 @@
 
 2023-03-26  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-03-26  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * src/sfnt.c (sfnt_table_names): Add avar.
        (sfnt_read_glyph): Clear distortion fields.
        (sfnt_build_glyph_outline): Calculate the outline origin point.
@@ -2877,40 +2496,25 @@
        (struct sfnt_test_dcontext, sfnt_test_get_glyph, main): Test
        distortable font handling.
 
-       * src/sfnt.h (SFNT_ENABLE_HINTING):
-       (enum sfnt_table):
-       (struct sfnt_glyph):
-       (struct sfnt_glyph_outline):
-       (struct sfnt_raster):
-       (struct sfnt_default_uvs_table):
-       (struct sfnt_unicode_value_range):
-       (struct sfnt_nondefault_uvs_table):
-       (struct sfnt_uvs_mapping):
-       (struct sfnt_mapped_variation_selector_record):
-       (struct sfnt_table_offset_rec):
-       (struct sfnt_uvs_context):
-       (struct sfnt_mapped_table):
-       (struct sfnt_variation_axis):
-       (struct sfnt_instance):
-       (struct sfnt_fvar_table):
-       (struct sfnt_short_frac_correspondence):
-       (struct sfnt_short_frac_segment):
-       (struct sfnt_avar_table):
-       (struct sfnt_tuple_variation):
-       (struct sfnt_cvar_table):
-       (struct sfnt_gvar_table):
-       (struct sfnt_blend):
-       (struct sfnt_metrics_distortion):
-       (PROTOTYPE): Update prototypes.
-
-       * src/sfntfont.c (sfntfont_get_glyph_outline):
+       * src/sfnt.h (SFNT_ENABLE_HINTING, enum sfnt_table)
+       (struct sfnt_glyph, struct sfnt_glyph_outline, struct sfnt_raster)
+       (struct sfnt_default_uvs_table, struct sfnt_unicode_value_range)
+       (struct sfnt_nondefault_uvs_table, struct sfnt_uvs_mapping)
+       (struct sfnt_mapped_variation_selector_record)
+       (struct sfnt_table_offset_rec, struct sfnt_uvs_context)
+       (struct sfnt_mapped_table, struct sfnt_variation_axis)
+       (struct sfnt_instance, struct sfnt_fvar_table)
+       (struct sfnt_short_frac_correspondence)
+       (struct sfnt_short_frac_segment, struct sfnt_avar_table)
+       (struct sfnt_tuple_variation, struct sfnt_cvar_table)
+       (struct sfnt_gvar_table, struct sfnt_blend)
+       (struct sfnt_metrics_distortion): Update prototypes.
+
+       * src/sfntfont.c (sfntfont_get_glyph_outline)
        (sfntfont_measure_pcm): Adjust calls.
 
 2023-03-24  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/sfnt.c (sfnt_table_names): Add fvar, gvar, cvar.
        (sfnt_read_maxp_table): Call xmalloc, not malloc.
        (sfnt_read_simple_glyph): Avoid use-after-free if simple is
@@ -2927,6 +2531,7 @@
        (sfnt_read_packed_points, sfnt_read_packed_deltas)
        (sfnt_compute_tuple_scale, sfnt_infer_deltas_1, sfnt_infer_deltas)
        (sfnt_vary_glyph): Add WIP variation glyph implementation.
+
        * src/sfnt.h (enum sfnt_table, struct sfnt_simple_glyph):
        Likewise.
 
@@ -2934,14 +2539,14 @@
 
        * java/INSTALL: Fix typo.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * configure.ac: Add support for HarfBuzz on Android.
+
        * java/INSTALL: Document where to get Emacs with HarfBuzz.
+
        * lisp/subr.el (overriding-text-conversion-style, y-or-n-p):
        Correctly set text conversion style if y-or-n-p is called inside
        the minibuffer.
+
        * src/sfnt.c (sfnt_read_cmap_format_8)
        (sfnt_read_cmap_format_12): Fix typos.
        (sfnt_read_24, sfnt_read_cmap_format_14): New function.
@@ -2953,6 +2558,7 @@
        (sfnt_variation_glyph_for_char, sfnt_map_table, sfnt_unmap_table)
        (sfnt_read_table, sfnt_test_uvs): New functions.
        (main): Add UVS tests.
+
        * src/sfnt.h (struct sfnt_cmap_format_14)
        (struct sfnt_variation_selector_record)
        (struct sfnt_default_uvs_table, struct sfnt_unicode_value_range)
@@ -2960,8 +2566,10 @@
        (struct sfnt_mapped_variation_selector_record)
        (struct sfnt_table_offset_rec, struct sfnt_uvs_context)
        (struct sfnt_mapped_table): New structures.  Update prototypes.
+
        * src/sfntfont-android.c (android_sfntfont_driver): Register
        HarfBuzz callbacks where required.
+
        * src/sfntfont.c (sfntfont_select_cmap): Look for a format 14
        table.  Save it in new arg FORMAT14.
        (sfntfont_read_cmap): Adjust accordingly.
@@ -2975,87 +2583,75 @@
        (sfntfont_get_variation_glyphs): New function.
        (sfntfont_unmap_blob, sfntfont_get_font_table)
        (sfntfont_begin_hb_font): New functions.
-       * src/sfntfont.h: Update prototypes.
-       * src/textconv.c (Fset_text_conversion_style): Fix doc string.
 
-2023-03-19  Po Lu  <luangruo@yahoo.com>
+       * src/sfntfont.h: Update prototypes.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/textconv.c (Fset_text_conversion_style): Fix doc string.
 
 2023-03-18  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * java/org/gnu/emacs/EmacsView.java (onAttachedToWindow): Send
        measured width and height in exposures again.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Remove extraneous debugging code
        * src/androidterm.c (handle_one_android_event): Don't log expose
        events.
 
-       Work around pselect lossage on Android
        * src/android.c (android_run_select_thread): New flag.  Use it
        rather than the rc of pselect and errno to determine whether or
        not it has been interrupted.
        (android_handle_sigusr1): Set said flag.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsView.java (EmacsView)
-       (prepareForLayout): New function.  Call this prior to mapping
-       the view.
+       * java/org/gnu/emacs/EmacsView.java (prepareForLayout): New
+       function.  Call this prior to mapping the view.
        (onGlobalLayout): New function.  Register as global layout
        listener.
+
        * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
        (notifyContentRectPosition): New function.  Use specified
-       xPosition and yPosition when reporting the offsets of children
-       of the root window.
+       xPosition and yPosition when reporting the offsets of children of
+       the root window.
+
        * java/org/gnu/emacs/EmacsWindowAttachmentManager.java
        (registerWindow): Specify activity launch bounds if necessary.
+
        * src/androidterm.c (handle_one_android_event): Send
        MOVE_FRAME_EVENT where necessary.
 
 2023-03-17  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Include more information in Android bug reports
        * src/androidfns.c (Fx_server_vendor, Fx_server_version): New
        functions.
        (syms_of_androidfns): Define new functions.
+
        * src/androidterm.c (android_set_build_fingerprint)
        (syms_of_androidterm): Set new variable
        Vandroid_build_manufacturer.
+
        * src/xfns.c (Fx_server_vendor, Fx_server_version): Update doc
        strings.
 
-       Fix WINDOWSNT build of fileio.c and image.c
        * src/fileio.c (emacs_fd_to_int): Don't define on WINDOWSNT.
+
        * src/image.c (image_create_bitmap_from_data): Don't abort if
        !defined HAVE_ANDROID.
 
-       Update Android port
        * configure.ac:
-       * m4/ndk-build.m4 (ndk_INIT):
-       (ndk_LATE): Avoid AC_REQUIRE magic.
+       * m4/ndk-build.m4 (ndk_INIT, ndk_LATE): Avoid AC_REQUIRE magic.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Improve radio button appearance in Android menus
-       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
-       New field `lastGroupId'.
+       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu): New
+       field `lastGroupId'.
        (Item): New field `isRadio'.
        (addItem): New arg `isRadio'.
-       (inflateMenuItems): Apply an empty radio button group if
-       required.
+       (inflateMenuItems): Apply an empty radio button group if required.
+
        * src/androidmenu.c (android_init_emacs_context_menu): Adjust
        accordingly.
        (android_menu_show): Likewise.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsView.java (cancelPopupMenu): Dismiss
        context menu correctly.
        (isOpaque): New function.
+
        * java/org/gnu/emacs/EmacsWindowAttachmentManager.java: Make
        consumer list public.
 
@@ -3063,16 +2659,12 @@
 
 2023-03-16  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * lisp/frame.el (android-detect-mouse):
-       * lisp/term/android-win.el (android-get-connection): Add
-       function declarations.
+       * lisp/term/android-win.el (android-get-connection): Add function
+       declarations.
 
        * configure.ac: Remove unnecessary escape.
 
-       Make ANDROID_CC and SDK_BUILD_TOOLS precious variables
        * configure.ac (AUTO_DEPEND, ANDROID_STUBIFY, ANDROID_LDFLAGS):
        * lib/Makefile.in (ANDROID_CFLAGS, ANDROID_BUILD_CFLAGS)
        (ALL_CFLAGS):
@@ -3083,194 +2675,169 @@
        variables precious.  Rename ANDROID_CFLAGS substitution to
        ANDROID_BUILD_CFLAGS.
 
-       Update Android port
-       * nt/mingw-cfg.site: Suppress build of gnulib printf.
+       * nt/mingw-cfg.site: Suppress build of Gnulib printf.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsDocumentsProvider.java (queryRoots): Add
        icon to document root.
 
-       Update Android port
-       * lisp/loadup.el (current-load-list): Set to empty load list
-       after startup.
-       * src/lread.c (build_load_history): Revert earlier changes.
+       * lisp/loadup.el (current-load-list): Set to empty load list after
+       startup.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/lread.c (build_load_history): Revert earlier changes.
 
 2023-03-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * configure.ac: Improve portability.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-15  Robert Pluim  <rpluim@gmail.com>
 
-       Fix typos in Android port
        * src/fileio.c (Finsert_file_contents):
        * src/window.c (replace_buffer_in_windows): Call Fboundp, not
        boundp.
 
 2023-03-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * cross/Makefile.in (lib/gnulib.mk): Edit out
-       build-aux stuff.
+       * cross/Makefile.in (lib/gnulib.mk): Edit out build-aux stuff.
        * m4/ndk-build.m4: Also look for cross ranlib.
 
        * src/sfntfont.c (sfntfont_close): Fix warning w/o mmap.
 
-       Port to systems without endian.h
-       * lib-src/asset-directory-tool.c (main_2): Port to systems
-       without htole32.
+       * lib-src/asset-directory-tool.c (main_2): Port to systems without
+       htole32.
 
 2023-03-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * configure.ac (XCONFIGURE): Disable NS.
-       * cross/Makefile.in (lib-src/config.h):
 
-       (lib/libgnu.a):
+       * cross/Makefile.in (lib-src/config.h, lib/libgnu.a)
        (src/android-emacs): Port sed invocation to Mac OS without GNU
        sed.
 
 2023-03-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/lispref/commands.texi (Misc Events): Document variable
        `disable-inhibit-text-conversion'.
-       * java/org/gnu/emacs/EmacsDialog.java (display1): Try an
-       activity that is certain to be focused first.
+
+       * java/org/gnu/emacs/EmacsDialog.java (display1): Try an activity
+       that is certain to be focused first.
+
        * lisp/touch-screen.el (touch-screen-track-tap)
-       (touch-screen-track-drag): Bind
-       `disable-inhibit-text-conversion'.
-       * src/keyboard.c (read_key_sequence): Only disable text
-       conversion if an actual function or numeric key is found in the
-       key sequence.
+       (touch-screen-track-drag): Bind `disable-inhibit-text-conversion'.
+
+       * src/keyboard.c (read_key_sequence): Only disable text conversion
+       if an actual function or numeric key is found in the key sequence.
        (syms_of_keyboard): New variable
        `disable-inhibit-text-conversion'.
+
        * src/lread.c (read_filtered_event): Check new variable.
+
        * src/textconv.c (textconv_query): Remove unused label.
 
-       Omit gnulib modules added by Android port on MinGW
        * nt/gnulib-cfg.mk: Omit new gnulib modules.
 
 2023-03-14  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * lisp/minibuffer.el (minibuffer-setup-on-screen-keyboard):
-       Handle cases where last-event-frame is a kbd macro.
+       * lisp/minibuffer.el (minibuffer-setup-on-screen-keyboard): Handle
+       cases where last-event-frame is a kbd macro.
        * src/keyboard.c (lispy_function_keys): Remove duplicates.
 
-       Fix the MS-DOS build
        * msdos/sed1v2.inp:
        * msdos/sed3v2.inp:
        * msdos/sedlibcf.inp:
        * msdos/sedlibmk.inp: Update for Android port and new Gnulib
        modules.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsWindow.java (figureChange): Detect
-       mice on up events as well.
+       * java/org/gnu/emacs/EmacsWindow.java (figureChange): Detect mice
+       on up events as well.
        (onSomeKindOfMotionEvent): Work past framework bug.
+
        * src/androidterm.c (android_perform_conversion_query):
        * src/textconv.c (textconv_query):
        * src/textconv.h (TEXTCONV_SKIP_ACTIVE_REGION): Remove unused
        code.
 
-       Update Android port
        * doc/emacs/android.texi (Android Windowing): Document how to
        display dialogs when Emacs is in the background.
+
        * java/org/gnu/emacs/EmacsDialog.java (display1): Use system
        dialogs if possible.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-13  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * etc/NEWS: Announce new option.
+
        * lisp/menu-bar.el (menu-bar-close-window): New option.
-       (kill-this-buffer):
-       (kill-this-buffer-enabled-p): Adjust accordingly.
-       * src/keyboard.c (lispy_function_keys): Add more silly
-       keys.
+       (kill-this-buffer, kill-this-buffer-enabled-p): Adjust
+       accordingly.
+
+       * src/keyboard.c (lispy_function_keys): Add more silly keys.
 
-       Update Android port
        * src/android.c (android_check_string, android_build_string):
        Reduce consing when building menu bar strings.
 
        * etc/MACHINES (Android): Update with more recent information.
 
-       Update Android port
        * doc/emacs/android.texi (Android Startup): Document changes to
        emacsclient wrapper.
+
        * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity)
        (startEmacsClient): Open EmacsActivity if the service is not
        running.
+
        * java/org/gnu/emacs/EmacsService.java (onCreate):
-       * java/org/gnu/emacs/EmacsThread.java (EmacsThread, run): Pass
-       any file to open to Emacs.
+       * java/org/gnu/emacs/EmacsThread.java (run): Pass any file to open
+       to Emacs.
+
        * lisp/term/android-win.el (handle-args-function): Implement.
 
-       Update Android port
        * src/image.c (image_create_bitmap_from_file, image_find_image_fd)
        (close_android_fd, slurp_file): Return and use `struct
        android_fd_or_asset' on Android.
        (xbm_load, xpm_load, pbm_load, png_load_body, jpeg_load_body)
        (webp_load, svg_load): Adjust accordingly.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-12  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * src/android.c (android_get_screen_width):
-       (android_get_screen_height):
-       (android_get_mm_width):
-       (android_get_mm_height):
-       (android_detect_mouse): Correctly handle Java exceptions.
+       * src/android.c (android_get_screen_width)
+       (android_get_screen_height, android_get_mm_width)
+       (android_get_mm_height, android_detect_mouse): Correctly handle
+       Java exceptions.
+
+       * src/android.c (android_check_if_event): New function.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/androidgui.h: Update prototypes.
 
-       Update Android port
-       * src/android.c (android_check_if_event):
-       * src/androidgui.h: New function.
        * src/androidterm.c (android_event_is_for_frame): New function.
        (android_reset_conversion): Free and unqueue all text conversion
        events for the given frame.
 
-       Update Android port
        * src/androidterm.c (NATIVE_NAME, JNICALL)
        (android_build_extracted_text, android_update_selection): Use
        0-based indices for Android buffer positions.  Also, report
        surrounding text relative to the region, not to the cursor.
-       * src/textconv.c (textconv_query): Accept new values of
-       position.
-       (really_set_composing_text): Use ephemeral last point.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/textconv.c (textconv_query): Accept new values of position.
+       (really_set_composing_text): Use ephemeral last point.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity)
-       (onCancel): New function.
+       * java/org/gnu/emacs/EmacsOpenActivity.java (onCancel): New
+       function.
        (displayFailureDialog): Handle dialog cancellation.
+
        * src/sfntfont.c (sfnt_parse_languages): Look for SLNG tag if
        DLNG is not present.
 
-       Add Super modifier support to Android port
        * src/androidgui.h (enum android_modifier_mask): New modifier
        ANDROID_SUPER_MASK.
+
        * src/androidterm.c (android_android_to_emacs_modifiers)
        (android_emacs_to_android_modifiers): Add new modifier.
 
-       Fix crash during androidterm init
        * src/androidterm.c (syms_of_androidterm): Initialize
        Vandroid_build_fingerprint in case GC happens.
 
-       * src/emacs-module.c (module_reset_handlerlist): Fix macro conflict.
+       * src/emacs-module.c (module_reset_handlerlist): Fix macro
+       conflict.
 
-       Clean up emacs-module.c
        * src/emacs-module.c (MODULE_HANDLE_NONLOCAL_EXIT)
        (module_make_global_ref, module_free_global_ref)
        (module_make_function, module_get_function_finalizer)
@@ -3287,60 +2854,47 @@
        (module_open_channel, module_reset_handlerlist): Adjust as
        recommended by Paul Eggert <eggert@cs.ucla.edu>.
 
-       Update Android port
-       * configure.ac: Take option `--with-shared-user-id' and give it
-       to AndroidManifest.xml.in.
+       * configure.ac: Take option `--with-shared-user-id' and give it to
+       AndroidManifest.xml.in.
+
        * java/AndroidManifest.xml.in: Substitute that into the
        application info.
+
        * java/INSTALL (BUILDING WITH A SHARED USER ID): New section.
 
 2023-03-11  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Improve default value of `with_mailutils' on Android
-       * configure.ac: Default to off on Android.
+       * configure.ac (with_mailutils): Default to off on Android.
+       (HAVE_MAILUTILS, with_mailutils, ANDROID_SDK_8_OR_EARLIER)
+       (XCONFIGURE): Fix POP and mailutils configuration on Android.
 
-       * configure.ac: Fix typo.
-
-       Update Android port
-       * configure.ac (HAVE_MAILUTILS, with_mailutils)
-       (ANDROID_SDK_8_OR_EARLIER, XCONFIGURE): Fix POP and mailutils
-       configuration on Android.
        * java/Makefile.in:
-       * src/callproc.c (syms_of_callproc): Avoid using built-in
-       movemail when --with-mailutils.
+       * src/callproc.c (syms_of_callproc): Avoid using built-in movemail
+       when --with-mailutils.
 
-       Update Android port
        * src/android.c (android_resolve_handle)
-       (android_resolve_handle2): Don't perform checking done by
-       CheckJNI by default.
+       (android_resolve_handle2): Don't perform checking done by CheckJNI
+       by default.
        (android_copy_area): Check for errors here because CopyArea can
        perform a lot of consing.
        (android_define_cursor): Remove redundant code.
 
-       Fix problems with the menu bar on large screen Android devices
        * java/org/gnu/emacs/EmacsActivity.java (onContextMenuClosed):
        Process submenu closing normally if it happens more than 300 ms
        after a submenu item was selected.
+
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu)
        (onMenuItemClick, display1): Give `wasSubmenuSelected' different
        values depending on how the submenu was selected.
 
        * lib/gnulib.mk.in: Update from gnulib.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-03-11  Po Lu  <luangruo@yahoo.com>
-
-       Don't use GCC extensions in src/emacs-module.c
        * configure.ac: Default modules to on.  Remove check for
        __attribute__((cleanup)).  However, keep the new `ifavailable'
        value for systems without dlopen.
 
-       * src/emacs-module.c (MODULE_HANDLE_NONLOCAL_EXIT): Don't rely
-       on cleanup attribute and correctly reset handlerlist upon
-       longjmp.
+       * src/emacs-module.c (MODULE_HANDLE_NONLOCAL_EXIT): Don't rely on
+       cleanup attribute and correctly reset handlerlist upon longjmp.
        (MODULE_INTERNAL_CLEANUP): New macro.
        (module_make_global_ref, module_free_global_ref)
        (module_make_function, module_get_function_finalizer)
@@ -3357,222 +2911,219 @@
        (module_open_channel): Call MODULE_INTERNAL_CLEANUP prior to
        returning.
 
-2023-03-11  Po Lu  <luangruo@yahoo.com>
-
-       Implement hourglass cursor on Android
        * lisp/term/android-win.el (x-pointer-arrow, x-pointer-left-ptr)
        (x-pointer-left-side, x-pointer-sb-h-double-arrow)
        (x-pointer-sb-v-double-arrow, x-pointer-watch, x-pointer-xterm)
        (x-pointer-invisible): New constants.
+
        * src/androidterm.c (android_show_hourglass)
        (android_hide_hourglass): New functions.
        (android_toggle_visible_pointer, android_define_frame_cursor):
        Define or don't define hourglass cursor if x->hourglass.
        (android_redisplay_interface): Add new functions.
+
        * src/androidterm.h (struct android_output): New field
        `hourglass'.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-10  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * doc/emacs/android.texi (Android Windowing): Document how to
-       pass multimedia keys to the system.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function.
+       * doc/emacs/android.texi (Android Windowing): Document how to pass
+       multimedia keys to the system.
+
+       * java/org/gnu/emacs/EmacsNative.java
+       (shouldForwardMultimediaButtons): New function.
+
        * java/org/gnu/emacs/EmacsView.java (onKeyDown, onKeyMultiple)
        (onKeyUp): Check that function.
-       * java/org/gnu/emacs/EmacsWindow.java (defineCursor): Handle
-       cases where cursor is NULL.
+
+       * java/org/gnu/emacs/EmacsWindow.java (defineCursor): Handle cases
+       where cursor is NULL.
+
        * src/android.c (NATIVE_NAME): New function.
+
        * src/androidfns.c (syms_of_androidfns): New variable.
+
        * src/keyboard.c (lispy_function_keys): Add volume keys.
 
        * java/org/gnu/emacs/EmacsCursor.java: New file.
 
-       Implement mouse cursors on Android 7.0 and later
        * java/org/gnu/emacs/EmacsWindow.java (defineCursor): New
        function.
+
        * src/android.c (struct android_emacs_cursor): New struct.
        (android_init_emacs_cursor): New function.
-       (JNICALL): Call it.
+       (initEmacs): Call it.
        (android_create_font_cursor, android_define_cursor)
        (android_free_cursor): New functions.
+
        * src/android.h (enum android_handle_type): Add cursor handle
        type.
+
        * src/androidfns.c (Fx_create_frame, android_create_tip_frame)
        (enum mouse_cursor, struct mouse_cursor_types, mouse_cursor_types)
        (struct mouse_cursor_data, android_set_mouse_color)
        (syms_of_androidfns):
+
        * src/androidgui.h (enum android_cursor_shape):
+
        * src/androidterm.c (make_invisible_cursor)
        (android_toggle_invisible_pointer, android_free_frame_resources)
        (android_define_frame_cursor):
+
        * src/androidterm.h (struct android_display_info)
        (struct android_output): Port mouse cursor code over from X.
 
        * java/org/gnu/emacs/EmacsNative.java: Add missing dependency.
 
-       Avoid using Linux sysfs APIs to access battery state on Android
-       * lisp/battery.el (battery-status-function): Don't look for /sys,
-       /proc* on Android.  Explain why.
+       * lisp/battery.el (battery-status-function): Don't look for /sys
+       or /proc* on Android.  Explain why.
 
-       Port Android battery status to Android 4.4 and earlier
-       * java/org/gnu/emacs/EmacsService.java (EmacsService)
-       (queryBattery19): New function.
+       * java/org/gnu/emacs/EmacsService.java (queryBattery19): New
+       function.
        (queryBattery): Call it on old systems.  Also, return AC line
        status and temperature.
+
        * lisp/battery.el (battery-android): Implement more format
        directives.
-       * src/android.c (android_query_battery): Handle new status
-       fields.
-       * src/android.h (struct android_battery_state): Add `plugged'
-       and `temperature'.
-       * src/androidfns.c (Fandroid_query_battery): Return new fields.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_query_battery): Handle new status fields.
 
-2023-03-09  Po Lu  <luangruo@yahoo.com>
+       * src/android.h (struct android_battery_state): Add `plugged' and
+       `temperature'.
+
+       * src/androidfns.c (Fandroid_query_battery): Return new fields.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+2023-03-09  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * src/android.c (android_destroy_handle): Handle OOM errors in
        android_destroy_handle.
 
        * textconv.c: Remove out-of-date comment.
 
-2023-03-09  Po Lu  <luangruo@yahoo.com>
-
-       Fix menu and popup race conditions on Android
        * java/org/gnu/emacs/EmacsActivity.java (onContextMenuClosed):
+
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu)
        (onMenuItemClick, run):
-       * java/org/gnu/emacs/EmacsDialog.java (EmacsDialog, onClick)
-       (createDialog, onDismiss): Take menu event serial, and pass it
-       along in context menu events.
+
+       * java/org/gnu/emacs/EmacsDialog.java (onClick, createDialog)
+       (onDismiss): Take menu event serial, and pass it along in context
+       menu events.
+
        * java/org/gnu/emacs/EmacsNative.java (sendContextMenu): New
        argument.
+
        * src/android.c (sendContextMenu): Pass serial number in event.
 
        * src/androidgui.h (struct android_menu_event): New field
        `menu_event_serial'.
-       * src/androidmenu.c (FIND_METHOD_STATIC)
-       (android_init_emacs_context_menu): Adjust method declarations.
+
+       * src/androidmenu.c (android_init_emacs_dialog): Adjust method
+       declarations.
        (android_menu_show, android_dialog_show):
+
        * src/androidterm.c (handle_one_android_event): Expect serial in
        context menu events.
-       * src/androidterm.h: Update prototypes.
 
-2023-03-09  Po Lu  <luangruo@yahoo.com>
+       * src/androidterm.h: Update prototypes.
 
-       Fix webp test for Android
        * configure.ac (HAVE_WEBP): Disable WebPGetInfo check when
        REALLY_ANDROID.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
-       * java/debug.sh (is_root): Port to android versions which don't
+       * java/debug.sh (is_root): Port to Android versions which don't
        support `chmod +x'.
-       * src/android.c (android_content_name_p): Disable before API
-       level 19.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu)
-       (addItem): New argument `tooltip'.
+       * src/android.c (android_content_name_p): Disable before API level
+       19.
+
+       * java/org/gnu/emacs/EmacsContextMenu.java (addItem): New argument
+       `tooltip'.
 
-       Update Android port
        * src/android.c (android_build_string): Convert the text to
        UTF-16, and create the Java string using that.
        (android_build_jstring): Update comment.
-       * src/androidmenu.c (android_init_emacs_context_menu): Add
-       String argument to `addItem'.
+
+       * src/androidmenu.c (android_init_emacs_context_menu): Add String
+       argument to `addItem'.
+
        (android_menu_show): Correctly pass help strings in regular menu
        items.
+
        * src/sfnt.c (_sfnt_swap16, _sfnt_swap32): Avoid reserved names.
 
-       Fix crash upon restoring desktop
        * src/android.c (android_set_input_focus): Don't call method on
        window using service class.
 
        * src/sfnt.c (ODD): Use PUSH_UNCHECKED.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-08  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * src/fileio.c (Fcopy_file): On Android, ignore ENOSYS and
-       ENOTSUP when restoring file times, as the system call used is
-       supported by many kernels.
+       * src/fileio.c (Fcopy_file): On Android, ignore ENOSYS and ENOTSUP
+       when restoring file times, as many old kernel versions encountered
+       on Android devices omit support for the relevant system calls.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Fix occasional crash
-       * src/androidterm.c (android_build_extracted_text): Return NULL
-       if text class not initialized.
+       * src/androidterm.c (android_build_extracted_text): Return NULL if
+       text class not initialized.
        (android_update_selection): Check that EXTRACTED is not NULL.
 
-       Update Android port
        * doc/emacs/android.texi (Android File System): Document what
        `temp~unlinked' means in the temporary files directory.
-       * java/org/gnu/emacs/EmacsService.java (updateExtractedText):
-       New function.
-       * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
-       Ask the input method nicely to not display the extracted text
-       UI.
+
+       * java/org/gnu/emacs/EmacsService.java (updateExtractedText): New
+       function.
+
+       * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection): Ask
+       the input method nicely to not display the extracted text UI.
+
        * src/android.c (struct android_emacs_service): New method
        `updateExtractedText'.
-       (android_hack_asset_fd_fallback): Improve naming convention.
-       Fix typo.
+       (android_hack_asset_fd_fallback): Improve naming convention.  Fix
+       typo.
        (android_init_emacs_service): Add new method.
        (android_update_extracted_text): New function.
        (android_open_asset): Fix typo.
+
        * src/androidgui.h: Update prototypes.
+
        * src/androidterm.c (struct android_get_extracted_text_context):
        New field `flags'.
        (android_get_extracted_text): Set flags on the frame's output
        data.
        (android_build_extracted_text): New function.
        (getExtractedText): Move out class structures.
-       (android_update_selection): Send updates to extracted text if
-       the input method asked for them.
+       (android_update_selection): Send updates to extracted text if the
+       input method asked for them.
        (android_reset_conversion): Clear extracted text flags.
+
        * src/androidterm.h (struct android_output): New fields for
        storing extracted text data.
 
-       Fix double free upon encountering invalid font
-       * src/sfnt.c (sfnt_read_cmap_table): Don't allocate too big
-       data.  Also, free elements of (*data), not offsets into data
-       itself.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/sfnt.c (sfnt_read_cmap_table): Don't allocate too big data.
+       Also, free elements of (*data), not offsets into data itself.
 
 2023-03-07  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/Makefile.in (install_temp/assets/build_info): New rule.
+       (emacs.apk-in): Depend on that file.
 
-       Save build timestamps in Android builds
-       * java/Makefile.in (install_temp/assets/build_info): New
-       rule.:(emacs.apk-in): Depend on that file.
        * lisp/version.el (android-read-build-system)
        (android-read-build-time): New functions.
        (emacs-build-system, emacs-build-time): Use those functions on
        Android, as dumping is done after installation on Android.
+
        * src/fileio.c (Finsert_file_contents):
+
        * src/window.c (replace_buffer_in_windows): Don't call functions
        if they are not defined, which can happen during loadup.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsWindow.java (onSomeKindOfMotionEvent):
        Dismiss splurious LeaveNotify events from button presses.
+
        * src/android.c (android_change_window_attributes)
        (android_change_gc, android_set_clip_rectangles)
-       (android_reparent_window, android_clear_window, android_map_window)
-       (android_unmap_window, android_resize_window, android_move_window)
-       (android_swap_buffers, android_fill_rectangle, android_copy_area)
+       (android_reparent_window, android_clear_window)
+       (android_map_window, android_unmap_window, android_resize_window)
+       (android_move_window, android_swap_buffers)
+       (android_fill_rectangle, android_copy_area)
        (android_fill_polygon, android_draw_rectangle, android_draw_point)
        (android_draw_line, android_clear_area, android_bell)
        (android_set_input_focus, android_raise_window)
@@ -3583,75 +3134,77 @@
        (android_set_fullscreen): Optimize by specifying the class
        explicitly when calling a method.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/lread.c (lread_fd, file_tell, infile, skip_dyn_bytes)
        (skip_dyn_eof, readbyte_from_stdio, safe_to_load_version)
-       (close_infile_unwind, close_file_unwind_android_fd): New
-       function.
-       (Fload, Flocate_file_internal, openp): New argument PLATFORM.
-       All callers changed.
+       (close_infile_unwind, close_file_unwind_android_fd): New function.
+       (Fload, Flocate_file_internal, openp): New argument PLATFORM.  All
+       callers changed.
        (skip_lazy_string): Add optimized versions of various functions
        for accessing Android assets.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-06  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New function
+       requestSelectionUpdate.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function requestSelectionUpdate.
        * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
-       Call it instead of losing if getting the current selection
-       fails.
+       Call it instead of losing if getting the current selection fails.
+
        * src/android-asset.h (AAsset_seek): Define stub.
-       * src/android.c (android_open): Take mode_t.
+
+       * src/android.c (android_open): Take mode_t MODE instead of int.
        (android_open_asset, android_close_asset, android_asset_read_quit)
        (android_asset_read, android_asset_lseek, android_asset_fstat):
        New functions.
+
        * src/android.h (struct android_fd_or_asset): Update prototypes.
-       * src/androidgui.h (enum android_ime_operation): Add new
-       operation to update the selection position.
+
+       * src/androidgui.h (enum android_ime_operation): Add new operation
+       to update the selection position.
+
        * src/androidterm.c (android_handle_ime_event): Handle new
        operation.
        (requestSelectionUpdate): New function.
+
        * src/fileio.c (close_file_unwind_emacs_fd): New function.
        (Fcopy_file, union read_non_regular, read_non_regular)
-       (Finsert_file_contents): Use optimized codepath to insert
-       Android asset files.
+       (Finsert_file_contents): Use optimized codepath to insert Android
+       asset files.
+
        * src/frame.h (enum text_conversion_operation): New operation.
+
        * src/textconv.c (really_request_point_update)
        (handle_pending_conversion_events_1, request_point_update): New
        functions.
+
        * src/textconv.h: Update prototypes.
 
        * src/conf_post.h: Avoid macro redeclaration.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsService.java (sync): Delete function.
+
        * java/org/gnu/emacs/EmacsView.java (handleDirtyBitmap): Erase
        with window background.
        (onDetachedFromWindow): Only recycle bitmap if non-NULL.
+
        * java/org/gnu/emacs/EmacsWindow.java (background): New field.
        (changeWindowBackground): Set it.
+
        * src/android.c (struct android_emacs_service): Remove `sync'.
        (android_init_emacs_service): Likewise.
        (android_sync): Delete function.
+
        * src/androidfns.c (android_create_tip_frame): Set frame
        background color correctly.
        (Fx_show_tip): Make the tip frame visible.
+
        * src/androidgui.h: Update prototypes.
+
        * src/androidterm.c (handle_one_android_event): Handle tooltip
        movement correctly.
 
 2023-03-05  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * java/org/gnu/emacs/EmacsActivity.java (onCreate):
        * java/org/gnu/emacs/EmacsContextMenu.java:
        * java/org/gnu/emacs/EmacsDocumentsProvider.java (getMimeType):
@@ -3661,49 +3214,48 @@
        * java/org/gnu/emacs/EmacsFontDriver.java:
        * java/org/gnu/emacs/EmacsHandleObject.java:
        * java/org/gnu/emacs/EmacsInputConnection.java:
-       * java/org/gnu/emacs/EmacsMultitaskActivity.java
-       (EmacsMultitaskActivity):
+       * java/org/gnu/emacs/EmacsMultitaskActivity.java:
        * java/org/gnu/emacs/EmacsNative.java:
-       * java/org/gnu/emacs/EmacsNoninteractive.java
-       (EmacsNoninteractive, main):
-       * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity)
-       (startEmacsClient):
+       * java/org/gnu/emacs/EmacsNoninteractive.java (main):
+       * java/org/gnu/emacs/EmacsOpenActivity.java (startEmacsClient):
        * java/org/gnu/emacs/EmacsSdk7FontDriver.java:
        * java/org/gnu/emacs/EmacsSdk8Clipboard.java:
-       * java/org/gnu/emacs/EmacsService.java (EmacsService, onCreate):
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, onLayout):
+       * java/org/gnu/emacs/EmacsService.java (onCreate):
+       * java/org/gnu/emacs/EmacsView.java (onLayout):
        * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow):
-       * java/org/gnu/emacs/EmacsWindowAttachmentManager.java
-       (EmacsWindowAttachmentManager): Remove redundant includes.
-       Reorganize some functions around, remove duplicate `getLibDir'
-       functions, and remove unused local variables.
+       * java/org/gnu/emacs/EmacsWindowAttachmentManager.java: Remove
+       redundant includes.  Reorganize some functions, remove duplicate
+       `getLibDir' functions, and remove unused local variables.
+
+       * java/org/gnu/emacs/EmacsOpenActivity.java (onCreate): Don't set
+       the style here.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsOpenActivity.java (onCreate): Don't
-       set the style here.
        * java/res/values-v11/style.xml:
        * java/res/values-v14/style.xml:
        * java/res/values-v29/style.xml:
        * java/res/values/style.xml: Define styles for the emacsclient
        wrapper.
+
        * src/keyboard.c (read_key_sequence): Don't disable text
-       conversion if use_mouse_menu or if a menu bar prefix key is
-       being displayed.
+       conversion if use_mouse_menu or if a menu bar prefix key is being
+       displayed.
 
-       Update Android port
        * etc/PROBLEMS: Document problem with default monospace font.
-       * src/fileio.c (check_mutable_filename): Check /content as well.
+
+       * src/fileio.c (check_mutable_filename): Check if the file is a
+       constituent of /content as well.
        (Fcopy_file, Fdelete_directory_internal, Fdelete_file)
        (Frename_file, Fadd_name_to_file, Fmake_symbolic_link)
        (Fset_file_modes, Fset_file_times, Ffile_newer_than_file_p)
        (write_region): Adjust accordingly.
        (Fset_visited_file_modtime): Remove unnecessary restriction.
+
        * src/filelock.c (make_lock_file_name): Don't interlock files
        under /assets and /content.
+
        * src/inotify.c (Finotify_add_watch): Fix typo.
 
-       Fix cross compilation of cross/lib in some cases
-       * cross/Makefile.in: (config.status): Depend on
+       * cross/Makefile.in (config.status): Depend on
        top_builddir/config.status instead.
 
        * configure.ac: Fix another typo.
@@ -3712,189 +3264,168 @@
 
        * cross/README: Update.
 
-       Remove redundant gnulib files
        * cross/lib: Delete.  Make configure generate it instead.
 
-       Remove redundant second copy of gnulib
        * .gitignore: Simplify cross/lib rule.
+
        * admin/merge-gnulib (avoided_flags): Stop copying to cross/lib.
-       * configure.ac: Link gnulib source and header files to
-       cross/lib.
+
+       * configure.ac: Link gnulib source and header files to cross/lib.
+
        * cross/Makefile.in (LIB_SRCDIR): Make relative to builddir.
        (maintainer-clean): Merge with distclean.  Remove links created
        by configure.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-04  Po Lu  <luangruo@yahoo.com>
 
-       Fix x86_64 builds of libjpeg on Android
        * cross/ndk-build/ndk-build-shared-library.mk:
        * cross/ndk-build/ndk-build-static-library.mk: Specify right ELF
        format for 64 bit executables.
 
-       Fix calls to nasm in cross/ndk-build
        * cross/ndk-build/ndk-build-shared-library.mk:
        * cross/ndk-build/ndk-build-static-library.mk: Ensure nasm
        generates ELF objects.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/sfnt.c (sfnt_fill_span): Specifically handle spans that span
+       a single pixel by computing the coverage in the center.
 
-       Fix out of bound write after poly of single pixel span
-       * src/sfnt.c (sfnt_fill_span): Specifically handle spans that
-       span a single pixel by computing the coverage in the center.
+       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New field
+       `lastClosedMenu'.
+       (onContextMenuClosed): Don't send event if a menu is closed twice
+       in a row.  Also, clear wasSubmenuSelected immediately.
 
-       Improve context menus on old versions of Android
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New
-       field `lastClosedMenu'.
-       (onContextMenuClosed): Don't send event if a menu is closed
-       twice in a row.  Also, clear wasSubmenuSelected immediately.
        * java/org/gnu/emacs/EmacsContextMenu.java: Display submenus
        manually in Android 6.0 and earlier.
+
        * java/org/gnu/emacs/EmacsView.java (onCreateContextMenu)
        (popupMenu): Adjust accordingly.
 
-       Port to broken Android NDK version
-       * configure.ac: Check for __ctype_get_mb_cur_max.
-       Then see if MB_CUR_MAX is defined to it, and define
-       REPLACEMENT_MB_CUR_MAX if so and it does not link.
+       * configure.ac: Check for __ctype_get_mb_cur_max.  Then see if
+       MB_CUR_MAX is defined to it, and define REPLACEMENT_MB_CUR_MAX if
+       so and it does not link.
+
        * java/INSTALL: Update documentation.
+
        * src/conf_post.h (MB_CUR_MAX): Define replacement if
        necessary.
 
        * m4/ndk-build.m4 (ndk_INIT): Fix typo.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Improve support for building Android C++ dependencies
        * configure.ac: Call ndk_LATE after gl_EARLY.
+
        * cross/ndk-build/Makefile.in (NDK_BUILD_CXX): New variable.
+
        * cross/ndk-build/ndk-build-shared-library.mk:
        * cross/ndk-build/ndk-build-static-library.mk: Use it.
+
        * java/INSTALL: Describe how to build C++ dependencies.
+
        * m4/ndk-build.m4 (ndk_LATE): New macro.
        (ndk_INIT): Try to find a suitable C++ compiler.
        (ndk_CHECK_MODULES): Make sure the C++ compiler works before
        allowing C++ dependencies.
 
-       Fix cross-compilation of C++ code with old NDK versions
-       * cross/ndk-build/Makefile.in (NDK_BUILD_CFLAGS_CXX): New variable.
+       * cross/ndk-build/Makefile.in (NDK_BUILD_CFLAGS_CXX): New
+       variable.
+
        * cross/ndk-build/ndk-build-shared-library.mk
        ($(call objname,$(LOCAL_MODULE),$(basename $(1)))):
        * cross/ndk-build/ndk-build-static-library.mk
-       ($(call objname,$(LOCAL_MODULE),$(basename $(1)))): Use it to build
-       C++ code.
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1)))): Use it to
+       build C++ code.
 
 2023-03-03  Po Lu  <luangruo@yahoo.com>
 
-       Minor fixes to configury
        * configure.ac (ANDROID_SDK_8_OR_EARLIER): Pass through
        `--with-ndk-cxx-shared'.
-       * m4/ndk-build.m4: Fix quoting of $CC.
 
-       Fix out-of-tree builds with native dependencies
+       * m4/ndk-build.m4 (ndk_INIT): Fix quoting of $CC.
+
        * cross/ndk-build/ndk-build-shared-library.mk:
        * cross/ndk-build/ndk-build-static-library.mk: Include
        ndk-resolve.mk in srcdir.
 
        * cross/ndk-build/README: Update accordingly.
 
-       Improve ndk-build implementation
        * build-aux/ndk-build-helper.mk: Define in terms of BUILD_AUXDIR.
+
        * m4/ndk-build.m4 (ndk_INIT): Find right build-aux directory.
        Remove uses of unportable shell constructs.
 
-       Fix visiting and saving writable content provider files
-       * java/org/gnu/emacs/EmacsService.java (checkContentUri):
-       Improve debug output.
+       * java/org/gnu/emacs/EmacsService.java (checkContentUri): Improve
+       debug output.
+
        * lisp/files.el (basic-save-buffer): Check whether or not file
        itself exists before checking for the existence of the directory
        containing it.
+
        * src/android.c (android_open): Don't forget to set errno after
        open_content_uri fails.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-03-03  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity)
-       (onCreate): Add view tree observer.
+       * java/org/gnu/emacs/EmacsActivity.java (onCreate): Add view tree
+       observer.
        (onGlobalLayout): Sync fullscreen state.
        (syncFullscreenWith): Improve visibility flag setting.
 
        * src/textconv.c (select_window): New function.
-       (textconv_query):
-       (restore_selected_window):
-       (really_commit_text):
-       (really_set_composing_text):
-       (really_set_composing_region):
-       (really_delete_surrounding_text):
-       (really_set_point_and_mark):
-       (get_extracted_text): Call it instead of Fselect_window
-       to avoid selecting the mini window if it is no longer active.
-
-2023-03-03  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       (textconv_query, restore_selected_window, really_commit_text)
+       (really_set_composing_text, really_set_composing_region)
+       (really_delete_surrounding_text, really_set_point_and_mark)
+       (get_extracted_text): Call it instead of Fselect_window to avoid
+       selecting the mini window if it is no longer active.
 
 2023-03-02  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
        * doc/emacs/input.texi (On-Screen Keyboards): Fix indexing.
 
-       Summary: Update Android port
        * INSTALL: Document where to find Android installation
        instructions.
+
        * configure.ac (CHECK_LISP_OBJECT_TYPE): Pacify
        -Wsuggest-attribute=noreturn only on Android.
+
        * cross/ndk-build/README: New file.
+
        * doc/emacs/android.texi (Android):
        * doc/emacs/emacs.texi (Top):
        * doc/emacs/input.texi (Other Input Devices): Untabify menus.
+
        * etc/NEWS: Move INSTALL.android to java/INSTALL.
+
        * java/INSTALL: New file.
+
        * java/README:
+
        * src/coding.c (from_unicode_buffer): Make Android specific code
        only build on Android.
 
        * INSTALL.android: Remove file.
 
-       Fix Makefile race conditions
        * configure.ac: Make cross/* and related directories.
+
        * cross/Makefile.in (src/verbose.mk, lib/libgnu.a)
        (src/config.h): Stop making directories here.
        (lib-src/config.h): New config.h rule.
        ($(LIBSRC_BINARIES)): Add it.
        (clean): Don't remove CLEAN_SUBDIRS, but clean inside.
 
-       Fix Android handle wraparound
        * src/android.c (android_alloc_id): Return correct values upon
        wraparound.
 
-2023-03-02  Po Lu  <luangruo@yahoo.com>
-
-       Improve criteria for restoring fullscreen state on Android
-       * java/Makefile.in ($(CLASS_FILES) &): Touch all class files,
-       even those javac chose not to rebuild.
+       * java/Makefile.in ($(CLASS_FILES) &): Touch all class files, even
+       those the Java compiler elected not to rebuild.
 
        * java/org/gnu/emacs/EmacsActivity.java (onWindowFocusChanged):
        Restore fullscreen state here.
        (onResume): And not here.
 
-2023-03-02  Po Lu  <luangruo@yahoo.com>
-
-       Fix sectioning of android texi files
        * doc/emacs/android.texi (Android):
        * doc/emacs/emacs.texi (Top, GNU Free Documentation License):
        Rearrange menu and sectioning.
 
-       Update Android port
        * doc/emacs/android.texi (Android Windowing): Reword
        documentation.
+
        * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity):
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
        * java/org/gnu/emacs/EmacsFontDriver.java (EmacsFontDriver):
@@ -3902,31 +3433,36 @@
        (EmacsSdk7FontDriver):
        * java/org/gnu/emacs/EmacsService.java (queryBattery):
        * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): Make
-       functions final and classes static where necessary.
+       functions final and classes static where possible.  This
+       subsequently brings a small speed-up as the JVM can optimize
+       vtable dispatch away at run-time.
+
        * src/android.c (struct android_emacs_service): New method
        `display_toast'.
        (android_init_emacs_service): Load new method.
        (android_display_toast): New function.
-       * src/android.h: Export.
+
+       * src/android.h (android_display_toast): Export that new function.
+
        * src/androidfns.c (Fandroid_detect_mouse):
        * src/androidselect.c (Fandroid_clipboard_owner_p)
        (Fandroid_set_clipboard, Fandroid_get_clipboard)
        (Fandroid_browse_url): Prevent crashes when called from
-       libandroid-emacs.so.
+       libandroid-emacs.so, where the Emacs service object is not
+       present.
+
        * src/androidterm.c (handle_one_android_event): Fix out of date
        commentary.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-03-01  Po Lu  <luangruo@yahoo.com>
 
-       Fix out-of-tree Android builds
-       * configure.ac (JAVA_PUSH_LINT): Push to WARN_JAVAFLAGS instead
-       of JAVAFLAGS.
+       * configure.ac (JAVA_PUSH_LINT): Push to WARN_JAVAFLAGS instead of
+       JAVAFLAGS.
        (cross/lib): Always AS_MKDIR_P.
+
        * cross/Makefile.in (srcdir): New variable.
-       (LIB_SRCDIR): Take realpath relative to srcdir, not
-       .:(src/verbose.mk): Depend on verbose.mk.android in srcdir.
+       (LIB_SRCDIR): Take realpath relative to srcdir, not.
+       (src/verbose.mk): Depend on verbose.mk.android in srcdir.
        (lib/Makefile): Edit srcdir and VPATH to LIB_SRCDIR.
        (src/Makefile): Edit -I$$(top_srcdir) to -I../$(srcdir)/lib,
        instead of ommitting it.
@@ -3940,47 +3476,46 @@
        (install_temp, emacs.apk-in)
        (../config.status): Depend relative to top_srcdir.
        (AndroidManifest.xml, $(APK_NAME)): Likewise.
-       (RESOURCE_FILE, CLASS_FILES, classes.dex): Output class files
-       to $(srcdir); these are arch independents, so this is okay.
+       (RESOURCE_FILE, CLASS_FILES, classes.dex): Output class files to
+       $(srcdir); these are arch independents, so this is okay.
 
 2023-03-01  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Fix mostlyclean rules
        * cross/Makefile.in: Remove outdated comment.
-       * src/Makefile.in: (.PHONY): Clean android-emacs and
-       libemacs.so, not emacs.so and aemacs.
 
-       Update Android port
+       * src/Makefile.in (.PHONY): Clean android-emacs and libemacs.so,
+       not emacs.so and aemacs.
+
        * doc/emacs/android.texi (Android File System): Document new
        behavior of starting a subprocess from /assets.
+
        * java/org/gnu/emacs/EmacsWindow.java (onSomeKindOfMotionEvent):
        Don't use isFromSource where not present.
-       * src/androidterm.c (android_scroll_run): Avoid undefined
-       behavior writing to bitfields.
+
+       * src/androidterm.c (android_scroll_run): Avoid undefined behavior
+       writing to bitfields.
+
        * src/callproc.c (get_current_directory): When trying to run a
-       subprocess inside /assets, run it from the home directory
-       instead.
+       subprocess inside /assets, run it from the home directory instead.
 
-       Update Android port
        * java/AndroidManifest.xml.in: Specify @style/EmacsStyle.
+
        * java/org/gnu/emacs/EmacsActivity.java (onCreate): Stop setting
        the theme here.
+
        * java/res/values-v11/style.xml:
        * java/res/values-v14/style.xml:
        * java/res/values-v29/style.xml:
        * java/res/values/style.xml: Extract style resources into
        res/values.
 
-       Update Android port
        * java/Makefile.in (ETAGS, clean): New rules to generate tags.
+
        * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity):
        * java/org/gnu/emacs/EmacsApplication.java (EmacsApplication):
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
        * java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea):
-       * java/org/gnu/emacs/EmacsDialog.java (EmacsDialog)::(dialog.
-       Then):
+       * java/org/gnu/emacs/EmacsDialog.java (EmacsDialog):
        * java/org/gnu/emacs/EmacsDocumentsProvider.java
        (EmacsDocumentsProvider):
        * java/org/gnu/emacs/EmacsDrawLine.java (EmacsDrawLine):
@@ -4007,36 +3542,33 @@
        * java/org/gnu/emacs/EmacsSdk8Clipboard.java
        (EmacsSdk8Clipboard):
        * java/org/gnu/emacs/EmacsService.java (EmacsService):
-       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView)
-       (buffers):
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, ViewGroup):
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, drawables):
+       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
+       * java/org/gnu/emacs/EmacsView.java (EmacsView):
+       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow):
        * java/org/gnu/emacs/EmacsWindowAttachmentManager.java
        (EmacsWindowAttachmentManager): Make classes final where
-       appropriate.
+       appropriate.  The Java virtual machine is capable of removing
+       vtable dispatch when a virtual function call is being performed on
+       an instance of a final class.
 
-       More fixes to JNI error checking
        * src/android.c (android_query_tree, android_get_geometry)
-       (android_translate_coordinates, android_query_battery):
-       Correctly handle result of GetTArrayElements.
+       (android_translate_coordinates, android_query_battery): Correctly
+       verify the results of calls to JNI Get<Type>ArrayElements
+       functions.
        (android_exception_check_nonnull): New function.
-       * src/android.h:
-       * src/androidselect.c (Fandroid_get_clipboard): Likewise.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/androidselect.c (Fandroid_get_clipboard): Also check the
+       return values of calls to JNI array extraction functions.
 
 2023-02-28  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/sfnt.c (main):
+
        * src/sfntfont.c (sfntfont_get_glyph_outline): Remove outdated
-       comment.
+       commentary.
 
 2023-02-26  Po Lu  <luangruo@yahoo.com>
 
-       Get rid of android_lookup_method
        * src/android.c (struct android_emacs_window): New methods.
        (android_init_emacs_window): Add new methods.
        (android_lookup_method): Delete now-unused function.
@@ -4046,61 +3578,60 @@
        (android_raise_window, android_lower_window, android_get_geometry)
        (android_translate_coordinates, android_set_dont_focus_on_map)
        (android_set_dont_accept_focus): Don't look up the class and
-       method each time when calling a function; that's just waste.
+       method each time when calling a function; that's just wasteful.
 
-       Update from gnulib
        * cross/lib/unistd.in.h:
-       * lib/gnulib.mk.in (INT64_MAX_EQ_LONG_MAX):
-       * m4/gnulib-comp.m4 (gl_EARLY): Update from gnulib.
+       * lib/gnulib.mk.in:
+       * m4/gnulib-comp.m4: Update from gnulib.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * doc/lispref/commands.texi (Misc Events): Update documentation.
-       * java/org/gnu/emacs/EmacsService.java (EmacsService)
-       (onStartCommand): Improve notification message.
+
+       * java/org/gnu/emacs/EmacsService.java (onStartCommand): Improve
+       notification message.
+
        * src/android.c (android_hack_asset_fd): Detect if ashmem is
        available dynamically.
        (android_detect_ashmem): New function.
+
        * src/textconv.c (record_buffer_change): Use markers to
        represent BEG and END instead.
        (syms_of_textconv): Update doc string.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-02-25  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * java/debug.sh (is_root): Fix tee detection again for old
-       systems which don't return exit codes from adb shell.
-       * src/android.c (android_run_select_thread, NATIVE_NAME,
-       JNICALL):
-       * src/android.h (NATIVE_NAME):
-       * src/androidterm.c (JNICALL, NATIVE_NAME): Apply stack
-       alignment to all JNICALL functions.
+       * java/debug.sh (is_root): Fix tee detection again for old systems
+       which don't return exit codes from adb shell.
+
+       * src/android.c (android_run_select_thread, initEmacs):
+       * src/android.h:
+       * src/androidterm.c: Apply stack alignment to all JNICALL
+       functions.
 
        * src/android.c (android_open): Clean up unused variables.
 
-       Update Android port
        * java/org/gnu/emacs/EmacsNoninteractive.java (main): Port to
        Android 2.2.
+
        * src/android-asset.h (AAsset_openFileDescriptor): Delete stub
        function.
-       * src/android.c (android_check_compressed_file): Delete
-       function.
-       (android_open): Stop trying to find compressed files or to use
-       the system provided file descriptor.  Explain why.
 
-       Update Android port
+       * src/android.c (android_check_compressed_file): Delete function.
+       (android_open): Stop trying to find compressed files or to use the
+       system provided file descriptor.  Explain why.
+
        * doc/emacs/android.texi (Android Startup, Android File System)
-       (Android Environment, Android Windowing, Android
-       Troubleshooting): Improve documentation; fix typos.
+       (Android Environment, Android Windowing, Android Troubleshooting):
+       Improve documentation; fix typos.
+
        * doc/lispref/commands.texi (Misc Events): Likewise.
+
        * java/org/gnu/emacs/EmacsService.java (queryBattery): New
        function.
+
        * lisp/battery.el (battery-status-function): Set appropriately
        for Android.
        (battery-android): New function.
+
        * src/android.c (struct android_emacs_service): New method
        `query_battery'.
        (android_check_content_access): Improve exception checking.
@@ -4119,9 +3650,12 @@
        (android_browse_url): Improve exception handling.  Always use
        android_exception_check and don't leak local refs.
        (android_query_battery): New function.
+
        * src/android.h (struct android_battery_state): New struct.
+
        * src/androidfns.c (Fandroid_query_battery, syms_of_androidfns):
-       New function.
+       New functions.
+
        * src/androidfont.c (androidfont_from_lisp, DO_SYMBOL_FIELD)
        (DO_CARDINAL_FIELD, androidfont_list, androidfont_match)
        (androidfont_draw, androidfont_open_font)
@@ -4130,196 +3664,142 @@
        (Fandroid_get_clipboard):
        * src/sfnt.c (sfnt_map_glyf_table):
        * src/sfntfont.c (sfntfont_free_outline_cache)
-       (sfntfont_free_raster_cache, sfntfont_close): Allow font close
-       functions to be called twice.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       (sfntfont_free_raster_cache, sfntfont_close): Allow calling font
+       close functions twice.
 
 2023-02-24  Po Lu  <luangruo@yahoo.com>
 
-       Improve Android configury
        * configure.ac (JAVA_PUSH_LINT): New macro.
        (JAVAFLAGS): New variable.  Check for various lint flags and
        macros and enable them.
+
        * java/Makefile.in (ANDROID_ABI):
+
        * java/org/gnu/emacs/EmacsSdk7FontDriver.java: Remove compiler
        warning.
 
-       Enable normal-erase-is-backspace on Android
        * lisp/frame.el (display-symbol-keys-p):
        * lisp/simple.el (normal-erase-is-backspace-setup-frame): Return
        appropriate values on Android.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Fix auto-revert-mode on Android
-       * src/inotify.c (Finotify_add_watch): Handle asset files.
+       * src/inotify.c (Finotify_add_watch): Handle asset files by
+       returning nil.
 
        * src/keyboard.c (lispy_function_keys): Add missing delete key.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-02-23  Po Lu  <luangruo@yahoo.com>
 
-       Make sure scroll-bar.el is loaded on Android
        * lisp/loadup.el: Update commentary.
+
        * src/androidterm.c (syms_of_androidterm): Define
        Vx_toolkit_scroll_bars.
-       * src/xterm.c (syms_of_xterm): Update doc string.xf64
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/xterm.c (syms_of_xterm): Update doc string.
 
-       Fix ImageMagick build on Android
-       * INSTALL.android (-linux_arm_sources):
+       * INSTALL.android:
        * build-aux/ndk-build-helper-1.mk:
-       (NDK_$(LOCAL_MODULE)_STATIC_LIBRARIES)::(NDK_CXX_FLAG_$(LOCAL_MODULE)):
+       (NDK_$(LOCAL_MODULE)_STATIC_LIBRARIES)
+       (NDK_CXX_FLAG_$(LOCAL_MODULE)):
        * build-aux/ndk-build-helper-2.mk:
-       (NDK_$(LOCAL_MODULE)_STATIC_LIBRARIES)::(NDK_CXX_FLAG_$(LOCAL_MODULE)):
-       * cross/ndk-build/ndk-build-shared-library.mk (objname)::($(call
-       objname,$(LOCAL_MODULE),$(basename
-       $(1))))::(ALL_OBJECT_FILES$(LOCAL_MODULE)):
-       * cross/ndk-build/ndk-build-static-library.mk (objname)::($(call
-       objname,$(LOCAL_MODULE),$(basename
-       $(1))))::(ALL_OBJECT_FILES$(LOCAL_MODULE)):
-       (ALL_SOURCE_FILES): Update ImageMagick build instructions and
-       C++ module detection.
+       (NDK_$(LOCAL_MODULE)_STATIC_LIBRARIES)
+       (NDK_CXX_FLAG_$(LOCAL_MODULE)):
+       * cross/ndk-build/ndk-build-shared-library.mk (objname)
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1))))
+       (ALL_OBJECT_FILES$(LOCAL_MODULE)):
+       * cross/ndk-build/ndk-build-static-library.mk (objname)
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1))))
+       (ALL_OBJECT_FILES$(LOCAL_MODULE)):
+       (ALL_SOURCE_FILES): Update ImageMagick build instructions and C++
+       module detection.
 
        * src/android.c (android_run_select_thread): Fix typos.
-
-       Make android_select more robust
-       * src/android.c (android_run_select_thread): Lock select_mutex
-       before signalling condition variable.
+       (android_run_select_thread): Lock select_mutex before signalling
+       condition variable.
        (android_select): Unlock event queue mutex prior to waiting for
        it.
 
 2023-02-22  Po Lu  <luangruo@yahoo.com>
 
-       ; Fix typo
        * cross/ndk-build/ndk-build-shared-library.mk: Fix typo.
 
        * src/image.c (imagemagick_load_image): Check HAVE_DECL_xxx.
 
-2023-02-22  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
-       ImageMagick now builds but does not link yet some of the time.
-
        * INSTALL.android: Document ImageMagick and caveats.
+
        * build-aux/ndk-build-helper-1.mk (NDK_SO_NAMES):
        * build-aux/ndk-build-helper-2.mk (NDK_A_NAMES):
-       * build-aux/ndk-build-helper.mk (TARGET_ARCH_ABI): Define architecture
-       and don't respect explicitly specified library names.
+       * build-aux/ndk-build-helper.mk (TARGET_ARCH_ABI): Define
+       architecture and don't respect explicitly specified library names.
        * configure.ac: Enable ImageMagick and lcms2 on Android.
-       * cross/ndk-build/ndk-build-shared-library.mk (objname)::($(call
-       objname,$(LOCAL_MODULE),$(basename
-       $(1))))::(ALL_OBJECT_FILES$(LOCAL_MODULE)):
-       * cross/ndk-build/ndk-build-static-library.mk (objname)::($(call
-       objname,$(LOCAL_MODULE),$(basename $(1)))):
-       (NDK_CFLAGS, ALL_SOURCE_FILES): Handle sources files which start with
-       $(LOCAL_PATH).
-       * cross/ndk-build/ndk-clear-vars.mk: Don't undefine; clear variables
-       instead.
-       * m4/ndk-build.m4 (ndk_SEARCH_MODULE): Redirect make stderr to
-       config.log.xf64
+       * cross/ndk-build/ndk-build-shared-library.mk (objname)
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1))))
+       (ALL_OBJECT_FILES$(LOCAL_MODULE)):
+       * cross/ndk-build/ndk-build-static-library.mk (objname)
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1))))
+       (NDK_CFLAGS, ALL_SOURCE_FILES): Handle source files whose names
+       begin with $(LOCAL_PATH).
 
-2023-02-22  Po Lu  <luangruo@yahoo.com>
+       * cross/ndk-build/ndk-clear-vars.mk: Don't undefine; clear
+       variables instead.
+
+       * m4/ndk-build.m4 (ndk_SEARCH_MODULE): Redirect make stderr to
+       config.log.
 
        * src/androidmenu.c (android_menu_show): Fix typo.
 
-       Update Android port
-       * doc/emacs/input.texi (On-Screen Keyboards): Document changes
-       to text conversion.
-       * java/org/gnu/emacs/EmacsInputConnection.java (getExtractedText)
-       (EmacsInputConnection):
+       * doc/emacs/input.texi (On-Screen Keyboards): Document changes to
+       text conversion.
+
+       * java/org/gnu/emacs/EmacsInputConnection.java (getExtractedText):
        * src/keyboard.c (read_key_sequence): Disable text conversion
        after reading prefix key.
+
        * src/textconv.c (get_extracted_text): Fix returned value when
        request length is zero.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Add cross-compilation test for cleanup attribute
        * configure.ac: Per title.
 
-       Update Android port
        * INSTALL.android: Port to MIPS.
-       * configure.ac (modules): Default to ifavailable.
-       Write actual test for __attribute__((cleanup)).
+
+       * configure.ac (modules): Default to ifavailable.  Write actual
+       test for __attribute__((cleanup)).
+
        * m4/ndk-build.m4: Recognize mips and mips64.
+
        * src/emacs-module.c: Remove broken HAS_ATTRIBUTE test.
 
 2023-02-21  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/org/gnu/emacs/EmacsContextMenu.java (addSubmenu)
+       (inflateMenuItems): Handle tooltips correctly.
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu)
-       (addSubmenu, inflateMenuItems): Handle tooltips correctly.
        * src/android.c (android_scan_directory_tree): Fix limit
        generation for root directory.
+
        * src/androidmenu.c (android_init_emacs_context_menu)
-       (android_menu_show): Implement menu item help text on Android
-       8.0 and later.
-
-       Update from gnulib
-       * admin/merge-gnulib (GNULIB_MODULES):
-       * cross/lib/getopt-pfx-core.h (optind):
-       * cross/lib/limits.in.h (BOOL_WIDTH):
-       * cross/lib/math.in.h:
-       * cross/lib/stpncpy.c (__stpncpy):
-       * cross/lib/string.in.h:
-       * lib/getopt-pfx-core.h (optind):
-       * lib/gnulib.mk.in (ANDROID_MIN_SDK):
-       (GL_COND_OBJ_STDIO_READ_CONDITION):
-       (LIBS):
-       (NDK_BUILD_AR):
-       (REPLACE__EXIT):
-       (libgnu_a_SOURCES):
-       * lib/limits.in.h (BOOL_WIDTH):
-       * lib/math.in.h:
-       * lib/stpncpy.c (__stpncpy):
-       * lib/string.in.h:
-       * m4/assert_h.m4 (gl_ASSERT_H):
-       * m4/fdopendir.m4 (gl_FUNC_FDOPENDIR):
-       * m4/getdelim.m4 (gl_FUNC_GETDELIM):
-       * m4/getline.m4 (gl_FUNC_GETLINE):
-       * m4/gnulib-common.m4 (gl_COMMON_BODY):
-       (gl_CONDITIONAL_HEADER):
-       (gl_CHECK_FUNCS_ANDROID):
-       * m4/gnulib-comp.m4 (gl_EARLY):
-       (gl_INIT):
-       (gl_FILE_LIST):
-       * m4/limits-h.m4:
-       * m4/lstat.m4 (gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK):
-       * m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
-       * m4/printf.m4 (gl_PRINTF_SIZES_C99):
-       (gl_PRINTF_INFINITE):
-       (gl_PRINTF_INFINITE_LONG_DOUBLE):
-       (gl_PRINTF_DIRECTIVE_A):
-       (gl_PRINTF_DIRECTIVE_F):
-       (gl_PRINTF_FLAG_ZERO):
-       (gl_SNPRINTF_PRESENCE):
-       (gl_SNPRINTF_DIRECTIVE_N):
-       (gl_VSNPRINTF_ZEROSIZE_C99):
-       * m4/pselect.m4 (gl_FUNC_PSELECT):
-       * m4/readlink.m4 (gl_FUNC_READLINK):
-       * m4/realloc.m4 (_AC_FUNC_REALLOC_IF):
-       * m4/signbit.m4 (gl_SIGNBIT):
-       * m4/stpncpy.m4 (gl_FUNC_STPNCPY):
-       * m4/symlink.m4 (gl_FUNC_SYMLINK): Add gnulib module stpncpy.
+       (android_menu_show): Implement menu item help text on Android 8.0
+       and later.
+
+       * admin/merge-gnulib (GNULIB_MODULES): Add gnulib module stpncpy.
+
+       * m4, lib: Update from Gnulib.
+
        * src/android.c: Include string.h.
 
-       Update Android port
        * doc/emacs/android.texi (Android Startup): Document `content'
        special directory.
+
        * java/debug.sh (is_root): Improve /bin/tee detection.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function `dup'.
-       * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity)
-       (checkReadableOrCopy, onCreate): Create content directory names
-       when the file is not readable.
-       * java/org/gnu/emacs/EmacsService.java (EmacsService)
-       (openContentUri, checkContentUri): New functions.
+
+       * java/org/gnu/emacs/EmacsNative.java (dup): New function.
+
+       * java/org/gnu/emacs/EmacsOpenActivity.java (checkReadableOrCopy)
+       (onCreate): Create content directory names when the file is not
+       readable.
+
+       * java/org/gnu/emacs/EmacsService.java (openContentUri)
+       (checkContentUri): New functions.
+
        * src/android.c (struct android_emacs_service): New methods.
        (android_content_name_p, android_get_content_name)
        (android_check_content_access): New function.
@@ -4328,37 +3808,29 @@
        (android_init_emacs_service): Initialize new methods.
        (android_faccessat): Implement content file names.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-02-20  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-02-20  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * INSTALL.android: Explain where to get tree-sitter.
 
        * configure.ac: Add support for dynamic modules and tree-sitter.
 
        * doc/emacs/android.texi (Android Windowing):
+
        * java/org/gnu/emacs/EmacsSdk11Clipboard.java
-       (EmacsSdk11Clipboard, ownsClipboard): Improve clipboard handling
-       and documentation.
+       (ownsClipboard): Enhance the treatment of the clipboard and the
+       documentation addressing that subject.
 
 2023-02-20  Po Lu  <luangruo@yahoo.com>
 
-       Fix crash inside font-list-family
        * src/androidfont.c (androidfont_list_family): Don't
        unconditionally initialize the Android font driver.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Improve SFNT driver lookup efficiency
        * src/fontset.c (fontset_find_font): Add compatibility test to
        registry strangeness case.
+
        * src/sfnt.c (sfnt_read_cmap_table): Don't read subtable data if
        DATA is NULL.
+
        * src/sfntfont.c (struct sfnt_font_desc): New field `registry'.
        (sfnt_registry_for_subtable): New function.
        (sfntfont_identify_cmap): Move above sfnt_grok_registry.
@@ -4369,266 +3841,276 @@
        (sfntfont_registry_for_desc): New function.
        (mark_sfntfont): Mark desc->registry.
 
-       Improve reliability of Java code rebuilds
-       * java/Makefile.in ($(CLASS_FILES)): Depend on the Java
-       compiler's internal dependency tracking.
+       * java/Makefile.in ($(CLASS_FILES)): Depend on the Java compiler's
+       internal dependency tracking.
 
-2023-02-19  Po Lu  <luangruo@yahoo.com>
-
-       Match font registry after font is opened
        * src/fontset.c (fontset_find_font): Work around TrueType
        performance problem.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
        * cross/Makefile.in (src/libemacs.so): Depend on libgnu.a.
 
-       More fixes to parallel Make
        * cross/ndk-build/ndk-build.mk.in (NDK_BUILD_MODULES)
        (NDK_BUILD_SHARED, NDK_BUILD_STATIC): Define group rule to build
        all files so that they are built within one make process.
+
        * java/Makefile.in: Reorganize cross compilation and make sure
-       there is only one make subprocess for each subdirectory of
-       cross.
-
-       More parallel build fixes
-       * cross/Makefile.in: (.PHONY):
-       * java/Makefile.in: (.PHONY):
-       * src/Makefile.in: (libemacs.so): Avoid calling ndk-build from
-       two places at once.  Build android-emacs separately from
-       libemacs.so.
+       there is only one make subprocess for each subdirectory of cross.
+
+       * cross/Makefile.in (.PHONY):
+       * java/Makefile.in (.PHONY):
+       * src/Makefile.in (libemacs.so): Avoid calling ndk-build from two
+       places at once.  Build android-emacs separately from libemacs.so.
 
-       Fix parallel compilation of Android port
        * cross/Makefile.in ($(top_builddir)/lib/libgnu.a):
-       * java/Makefile.in (CROSS_LIBS): Explicitly depend on gnulib
-       to prevent it from being built at the same time from different
-       jobs.
+       * java/Makefile.in (CROSS_LIBS): Explicitly depend on Gnulib to
+       prevent it from being built at the same time from different jobs.
 
-       Fix sfntfont.c build without mmap
        * src/sfntfont.c (sfntfont_close): Don't unlink font if mmap is
        not available.
 
-       Improve Android documentation
        * INSTALL.android: Say where building Emacs is supported.
+
        * doc/emacs/android.texi (Android Startup): Describe how to
        connect via ADB.
 
-       Report both sides of the region to the input method upon setup
-       * java/org/gnu/emacs/EmacsNative.java (getSelection): Return
-       array of ints.
+       * java/org/gnu/emacs/EmacsNative.java (getSelection): Return array
+       of ints.
+
        * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
        Adjust accordingly.
+
        * src/androidterm.c (struct android_get_selection_context): New
        field `mark'.
        (android_get_selection): Set the mark field as appropriate.
        (getSelection): Adjust accordingly.
 
-       Fix gamegrid.el with high resolution displays
-       * lisp/play/gamegrid.el (gamegrid-setup-default-font): Clamp
-       font size at eight.
+       * lisp/play/gamegrid.el (gamegrid-setup-default-font): Clamp font
+       size at eight.
 
-       Allow opening more files in emacsclient on Android
-       * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity)
-       (checkReadableOrCopy): New function.
-       (onCreate): If the file specified is not readable from C, read
-       it into a temporary file and ask Emacs to open that.
+       * java/org/gnu/emacs/EmacsOpenActivity.java (checkReadableOrCopy):
+       New function.
+       (onCreate): If the file specified is not readable from C, read it
+       into a temporary file and ask Emacs to open that.
 
-       Implement `fullscreen' on Android 4.0 and later
        * doc/emacs/android.texi (Android Windowing): Document what new
        frame parameters are now supported.
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New
-       field `isFullscreen'.
+
+       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New field
+       `isFullscreen'.
        (detachWindow, attachWindow): Sync fullscreen state.
        (onWindowFocusChanged): Add more logging.
        (onResume): Restore previous fullscreen state.
        (syncFullscreen): New function.
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
-       (setFullscreen): New function.
+
+       * java/org/gnu/emacs/EmacsWindow.java (setFullscreen): New
+       function.
+
        * src/android.c (struct android_emacs_window): Add new method.
        (android_init_emacs_window): Look up new method.
        (android_set_fullscreen): New function.
+
        * src/androidgui.h:
        * src/androidterm.c (android_fullscreen_hook): Implement
        accordingly.
 
-       Fix crashes in desktop-save-mode
        * lisp/subr.el (overriding-text-conversion-style, y-or-n-p):
        Disable text conversion when reading from minibuffer.
+
        * src/androidfns.c (android_make_monitor_attribute_list): New
        function.
        (Fandroid_display_monitor_attributes_list): Call it to set
        monitor_frames, which avoids a NULL pointer dereference.
        Reported by Angelo Graziosi <angelo.g0@libero.it>.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-02-18  Po Lu  <luangruo@yahoo.com>
 
        * lisp/loadup.el: Fix merge typos.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * doc/emacs/input.texi (On-Screen Keyboards): Document
        `touch-screen-always-display'.
+
        * doc/lispref/commands.texi (Misc Events): Improve documentation
        of text conversion events.
+
        * java/org/gnu/emacs/EmacsDialog.java (toAlertDialog, display1):
        Reorder buttons to make more sense.
+
        * lisp/elec-pair.el (electric-pair-analyze-conversion): New
        function.
+
        * lisp/simple.el (analyze-text-conversion): Improve integration
        with electric pair modes.
-       * lisp/term.el (term-mode): Always display the onscreen
-       keyboard.
+
+       * lisp/term.el (term-mode): Always display the onscreen keyboard.
+
        * lisp/touch-screen.el (touch-screen-display-keyboard)
        (touch-screen-handle-point-up): Respect new options.
+
        * src/textconv.c (really_set_composing_text): Stop widenining
        unnecessarily.
-       (really_delete_surrounding_text): Really delete surrounding
-       text.  Give text conversion analyzers the buffer text.
+       (really_delete_surrounding_text): Really delete surrounding text.
+       Give text conversion analyzers the buffer text.
        (syms_of_textconv): Update doc string.
 
-       Notify input methods when editing fails
        * INSTALL.android: Clarify build instructions.
+
        * src/textconv.c (struct complete_edit_check_context): New
        structure.
        (complete_edit_check): New function.
-       (handle_pending_conversion_events_1): If the window is known,
-       then ensure that any editing failures are reported to the input
-       method.
+       (handle_pending_conversion_events_1): If the window is known, then
+       ensure that any editing failures are reported to the input method.
 
-       * configure.ac: Fix typo.
+       * configure.ac: Fix typo.  Check for madvise.
 
-       Update Android port
-       * configure.ac: Check for madvise.
        * lisp/international/fontset.el (script-representative-chars):
        Improve detection of CJK fonts.
+
        * src/pdumper.c (dump_discard_mem): Use madvise if possible.
+
        * src/sfnt.c (sfnt_map_glyf_table, sfnt_unmap_glyf_table): New
        functions.
+
        * src/sfnt.h (struct sfnt_glyf_table): New field.
+
        * src/sfntfont.c (struct sfnt_font_info, sfntfont_open)
-       (sfntfont_close, sfntfont_detect_sigbus): Allow mmapping fonts
-       if possible.
+       (sfntfont_close, sfntfont_detect_sigbus): Map fonts into memory if
+       possible.
+
        * src/sfntfont.h: Update prototypes.
+
        * src/sysdep.c (handle_sigbus, init_sigbus, init_signals):
        Initialize SIGBUS correctly.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-02-17  Po Lu  <luangruo@yahoo.com>
 
-       Work around race condition bug in Android 13's input manager
        * src/androidterm.c (android_get_selection): Use ephemeral last
        point.
+
        * src/textconv.c (report_selected_window_change): Set
        w->ephemeral_last_point to the window's point now.
 
-       Update emacsbug and version.el for the Android port
        * java/Makefile.in (install_temp/assets/version): New generated
        file.
-       * lisp/loadup.el: Set emacs versions appropriately prior to
+
+       * lisp/loadup.el: Set Emacs versions appropriately prior to
        dumping on Android.
-       * lisp/mail/emacsbug.el (emacs-build-description): Insert
-       Android build fingerprint.
+
+       * lisp/mail/emacsbug.el (emacs-build-description): Insert Android
+       build fingerprint.
+
        * lisp/version.el (emacs-repository-version-android)
        (emacs-repository-get-version, emacs-repository-get-branch):
        Implement for Android.
-       * src/androidterm.c (android_set_build_fingerprint): New
-       function.
+
+       * src/androidterm.c (android_set_build_fingerprint): New function.
        (syms_of_androidterm): New variable `android-build-fingerprint'.
 
        * src/android.c (android_exception_check): Fix typo.
+       (android_exception_check): Print more detailed information.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Improve logging of Java exceptions
-       * src/android.c (android_exception_check): Print more detailed
-       information.
-
-       Fix crash on old versions of Android
        * java/org/gnu/emacs/EmacsService.java (nameKeysym): Implement
        stub on Android 3.0 and earlier.
 
-       Fix build and running on Android 2.2
-       * INSTALL.android: Document that Android 2.2 is now supported,
-       with caveats.
+       * INSTALL.android: Document that Android 2.2 is now supported)
+       (with caveats.
+
        * configure.ac (ANDROID_MIN_SDK, ANDROID_SDK_18_OR_EARLIER)
        (SYSTEM_TYPE, ANDROID_STUBIFY, SIZEOF_LONG): Correctly detect
        things missing on Android 2.2.
+
        * java/Makefile.in (ANDROID_JAR, JARSIGNER_FLAGS):
        * java/debug.sh (jdb, gdbserver, line):
        * java/org/gnu/emacs/EmacsApplication.java (findDumpFile):
        * java/org/gnu/emacs/EmacsService.java (onCreate):
-       * java/org/gnu/emacs/EmacsThread.java (EmacsThread, run): Run
-       parameter initialization on main thread.
+       * java/org/gnu/emacs/EmacsThread.java (run): Run parameter
+       initialization on main thread.
+
        * src/android-asset.h (struct android_asset_manager)
        (struct android_asset, AAssetManager_fromJava, AAssetManager_open)
        (AAsset_close, android_asset_create_stream)
        (android_asset_read_internal, AAsset_openFileDescriptor)
        (AAsset_getLength, AAsset_getBuffer, AAsset_read): New file.
-       * src/android.c (android_user_full_name, android_hack_asset_fd)
+       Write substitutes for functions that aren't present within the NDK
+       on Android 2.2.
+
+       * src/android.c: Arrange to include android-asset.h if the minimum
+       supported Android version is 2.2.
+       (android_user_full_name, android_hack_asset_fd)
        (android_check_compressed_file): Implement for Android 2.2.
+
        * src/process.c (Fprocess_send_eof): Don't call tcdrain if
        unavailable.
+
        * src/sfntfont-android.c (system_font_directories): Fix compiler
        warning.
+
        * src/sfntfont.c (sfntfont_read_cmap): Correctly test rc of
        emacs_open.
-       * src/textconv.c (handle_pending_conversion_events_1): Mark
-       buffer UNINIT.
 
-2023-02-16  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/textconv.c (handle_pending_conversion_events_1): Mark buffer
+       UNINIT.
 
 2023-02-16  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/android.texi (Android Fonts):
        * doc/emacs/input.texi (On-Screen Keyboards):
        * doc/lispref/commands.texi (Misc Events): Update documentation.
-       * java/org/gnu/emacs/EmacsInputConnection.java (setSelection):
-       New function.
-       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView)
-       (reconfigureFrontBuffer): Make bitmap references weak
-       references.
+
+       * java/org/gnu/emacs/EmacsInputConnection.java (setSelection): New
+       function.
+       * java/org/gnu/emacs/EmacsSurfaceView.java
+       (reconfigureFrontBuffer): Make bitmap references weak references.
+
        * java/org/gnu/emacs/EmacsView.java (handleDirtyBitmap): Don't
        clear surfaceView bitmap.
-       * lisp/comint.el (comint-mode):
+
+       * lisp/comint.el (comint-mode): Set text-conversion-style to
+       `action' so on screen keyboards' Return buttons send an actual key
+       press event.
+
        * lisp/international/fontset.el (script-representative-chars)
        (setup-default-fontset): Improve detection of CJK fonts.
+
        * lisp/isearch.el (set-text-conversion-style): New variable.
-       (isearch-mode, isearch-done): Save and restore the text
-       conversion style.
+       (isearch-mode, isearch-done): Save and restore the text conversion
+       style.
+
        * lisp/minibuffer.el (minibuffer-mode): Set an appropriate text
        conversion style.
+
        * lisp/simple.el (analyze-text-conversion): Run
        post-self-insert-hook properly.
+
        * lisp/subr.el (read-char-from-minibuffer): Disable text
        conversion when reading character.
-       * src/androidterm.c (show_back_buffer): Don't check that F is
-       not garbaged.
+
+       * src/androidterm.c (show_back_buffer): Don't check that F is not
+       garbaged.
        (android_update_selection, android_reset_conversion): Use the
        ephemeral last point and handle text conversion being disabled.
+
        * src/buffer.c (syms_of_buffer): Convert old style DEFVAR.
+
        * src/keyboard.c (kbd_buffer_get_event): Handle text conversion
        first.
+
        * src/lisp.h: Update prototypes.
+
        * src/lread.c (read_filtered_event): Temporarily disable text
        conversion.
-       * src/sfnt.c (sfnt_decompose_glyph_1, sfnt_decompose_glyph_2):
-       New functions.
+
+       * src/sfnt.c (sfnt_decompose_glyph_1, sfnt_decompose_glyph_2): New
+       functions.
        (sfnt_decompose_glyph, sfnt_decompose_instructed_outline):
        Refactor contour decomposition to those two functions.
        (main): Update tests.
+
        * src/sfntfont-android.c (system_font_directories): Add empty
        field.
-       (Fandroid_enumerate_fonts, init_sfntfont_android): Enumerate
-       fonts in a user fonts directory.
-       * src/sfntfont.c (struct sfnt_font_desc): New field
-       `num_glyphs'.
+       (Fandroid_enumerate_fonts, init_sfntfont_android): Enumerate fonts
+       in a user fonts directory.
+
+       * src/sfntfont.c (struct sfnt_font_desc): New field `num_glyphs'.
        (sfnt_enum_font_1): Set num_glyphs and avoid duplicate fonts.
        (sfntfont_glyph_valid): New function.
        (sfntfont_lookup_char, sfntfont_list_1): Make sure glyphs found
@@ -4640,34 +4122,42 @@
        (handle_pending_conversion_events_1)
        (handle_pending_conversion_events, conversion_disabled_p)
        (disable_text_conversion, resume_text_conversion)
-       (Fset_text_conversion_style, syms_of_textconv): Update to
-       respect new options.
-       * src/textconv.h:
+       (Fset_text_conversion_style, syms_of_textconv): Update to respect
+       new options.
+
        * src/window.h (GCALIGNED_STRUCT): New field
        `ephemeral_last_point'.
+
        * src/xdisp.c (mark_window_display_accurate_1): Set it.
 
 2023-02-15  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/input.texi (On-Screen Keyboards):
        * doc/lispref/commands.texi (Misc Events): Improve documentation
        of text conversion stuff.
+
        * java/org/gnu/emacs/EmacsInputConnection.java (beginBatchEdit)
-       (endBatchEdit, commitCompletion, commitText, deleteSurroundingText)
+       (endBatchEdit, commitCompletion, commitText)
+       (deleteSurroundingText)
        (finishComposingText, getSelectedText, getTextAfterCursor)
        (EmacsInputConnection, setComposingRegion, performEditorAction)
        (getExtractedText): Condition debug code on DEBUG_IC.
+
        * java/org/gnu/emacs/EmacsService.java (EmacsService, updateIC):
        Likewise.
+
        * lisp/bindings.el (global-map):
        * lisp/electric.el (global-map): Make `text-conversion'
        `analyze-text-conversion'.
-       * lisp/progmodes/prog-mode.el (prog-mode): Enable text
-       conversion in input methods.
+
+       * lisp/progmodes/prog-mode.el (prog-mode): Enable text conversion
+       in input methods.
+
        * lisp/simple.el (analyze-text-conversion): New function.
+
        * lisp/textmodes/text-mode.el (text-conversion-style)
        (text-mode): Likewise.
+
        * src/androidterm.c (android_handle_ime_event): Handle
        set_point_and_mark.
        (android_sync_edit): Give Emacs 100 ms instead.
@@ -4676,14 +4166,19 @@
        (getSelectedText): Implement properly.
        (android_update_selection): Expose mark to input methods.
        (android_reset_conversion): Handle `text-conversion-style'.
+
        * src/buffer.c (init_buffer_once, syms_of_buffer): Add buffer
        local variable `text-conversion-style'.
+
        * src/buffer.h (struct buffer, bset_text_conversion_style): New
        fields.
+
        * src/emacs.c (android_emacs_init): Call syms_of_textconv.
+
        * src/frame.h (enum text_conversion_operation): Rename
        TEXTCONV_SET_POINT.
-       * src/lisp.h: Export syms_of_textconv.
+
+       * src/lisp.h (syms_of_textconv): Export syms_of_textconv.
 
        * src/marker.c (set_marker_internal): Force redisplay when the
        mark is set and the buffer is visible on builds that use text
@@ -4704,41 +4199,42 @@
 
        * src/textconv.h (struct textconv_interface): Update
        documentation.
+
        * src/window.h (GCALIGNED_STRUCT): New field `prev_mark'.
-       * src/xdisp.c (mark_window_display_accurate_1): Handle
-       prev_mark.
 
-2023-02-15  Po Lu  <luangruo@yahoo.com>
+       * src/xdisp.c (mark_window_display_accurate_1): Handle prev_mark.
 
-       Make debug.sh detect adb running as root
        * java/debug.sh: Run gdbserver directly if possible.
 
-       Fix small bugs
        * src/androidterm.c (android_handle_ime_event): Pacify compiler
        warnings.
+
        * src/textconv.c (really_set_composing_text)
        (handle_pending_conversion_events, get_extracted_text): Fix
        reentrancy problems and uses of uninitialized values.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-02-15  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * configure.ac (HAVE_TEXT_CONVERSION): Define on Android.
+
        * doc/emacs/input.texi (On-Screen Keyboards): Document ``text
        conversion'' slightly.
+
        * doc/lispref/commands.texi (Misc Events): Document new
        `text-conversion' event.
+
        * java/org/gnu/emacs/EmacsContextMenu.java (display): Use
        `syncRunnable'.
+
        * java/org/gnu/emacs/EmacsDialog.java (display): Likewise.
+
        * java/org/gnu/emacs/EmacsEditable.java: Delete file.
+
        * java/org/gnu/emacs/EmacsInputConnection.java
        (EmacsInputConnection): Reimplement from scratch.
+
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Add new
        functions.
-       * java/org/gnu/emacs/EmacsService.java (EmacsService, getEmacsView)
+
+       * java/org/gnu/emacs/EmacsService.java (getEmacsView)
        (getLocationOnScreen, sync, getClipboardManager, restartEmacs):
        Use syncRunnable.
        (syncRunnable): New function.
@@ -4750,7 +4246,9 @@
        (setICMode, getICMode): New functions.
 
        * lisp/bindings.el (global-map): Ignore text conversion events.
+
        * src/alloc.c (mark_frame): Mark text conversion data.
+
        * src/android.c (struct android_emacs_service): New fields
        `update_ic' and `reset_ic'.
        (event_serial): Export.
@@ -4762,18 +4260,19 @@
        methods.
        (android_check_query, android_begin_query, android_end_query)
        (android_run_in_emacs_thread):
-       (android_update_ic, android_reset_ic): New functions for
-       managing synchronous queries from one thread to another.
+       (android_update_ic, android_reset_ic): New functions for managing
+       synchronous queries from one thread to another.
 
        * src/android.h: Export new functions.
+
        * src/androidgui.h (enum android_event_type): Add input method
        events.
        (enum android_ime_operation, struct android_ime_event)
        (union android_event, enum android_ic_mode): New structs and
        enums.
 
-       * src/androidterm.c (android_window_to_frame): Allow DPYINFO to
-       be NULL.
+       * src/androidterm.c (android_window_to_frame): Allow DPYINFO to be
+       NULL.
        (android_decode_utf16, android_handle_ime_event)
        (handle_one_android_event, android_sync_edit)
        (android_copy_java_string, beginBatchEdit, endBatchEdit)
@@ -4781,32 +4280,29 @@
        (getSelectedtext, getTextAfterCursor, getTextBeforeCursor)
        (setComposingText, setComposingRegion, setSelection, getSelection)
        (performEditorAction, getExtractedText): New functions.
-       (struct android_conversion_query_context):
-       (android_perform_conversion_query):
-       (android_text_to_string):
-       (struct android_get_selection_context):
-       (android_get_selection):
-       (struct android_get_extracted_text_context):
-       (android_get_extracted_text):
-       (struct android_extracted_text_request_class):
-       (struct android_extracted_text_class):
-       (android_update_selection):
-       (android_reset_conversion):
-       (android_set_point):
-       (android_compose_region_changed):
-       (android_notify_conversion):
+       (struct android_conversion_query_context)
+       (android_perform_conversion_query, android_text_to_string)
+       (android_get_selection_context, android_get_selection)
+       (android_get_extracted_text_context, android_get_extracted_text)
+       (android_extracted_text_request_class)
+       (android_extracted_text_class, android_update_selection)
+       (android_reset_conversion, android_set_point)
+       (android_compose_region_changed, android_notify_conversion)
        (text_conversion_interface): New functions and structures.
        (android_term_init): Initialize text conversion.
 
        * src/coding.c (syms_of_coding): Define Qutf_16le on Android.
+
        * src/frame.c (make_frame): Clear conversion data.
        (delete_frame): Reset conversion state.
 
        * src/frame.h (enum text_conversion_operation)
        (struct text_conversion_action, struct text_conversion_state)
        (GCALIGNED_STRUCT): Update structures.
+
        * src/keyboard.c (read_char, readable_events, kbd_buffer_get_event)
        (syms_of_keyboard): Handle text conversion events.
+
        * src/lisp.h:
        * src/process.c: Fix includes.
 
@@ -4826,78 +4322,81 @@
 
        * src/textconv.h (struct textconv_interface)
        (TEXTCONV_SKIP_CONVERSION_REGION): Update prototype.
+
        * src/xdisp.c (mark_window_display_accurate_1):
        * src/xfns.c (xic_string_conversion_callback):
        * src/xterm.c (init_xterm): Adjust accordingly.
 
 2023-02-12  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * doc/emacs/android.texi (Android Environment): Mention that Emacs
+       also requests the notifications permission.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/org/gnu/emacs/EmacsEditable.java:
+       * java/org/gnu/emacs/EmacsInputConnection.java: New files.
+
+       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Load library
+       dependencies in a less verbose fashion.
 
-       Update Android port
-       * doc/emacs/android.texi (Android Environment): Document
-       notifications permission.
-       * java/org/gnu/emacs/EmacsEditable.java (EmacsEditable):
-       * java/org/gnu/emacs/EmacsInputConnection.java
-       (EmacsInputConnection): New files.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Load
-       library dependencies in a less verbose fashion.
        * java/org/gnu/emacs/EmacsView.java (EmacsView): Make imManager
        public.
        (onCreateInputConnection): Set InputType to TYPE_NULL for now.
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, onKeyDown)
-       (onKeyUp, getEventUnicodeChar): Correctly handle key events with
-       strings.
+
+       * java/org/gnu/emacs/EmacsWindow.java (onKeyDown, onKeyUp)
+       (getEventUnicodeChar): Correctly handle key events with strings.
+
        * lisp/term/android-win.el (android-clear-preedit-text)
        (android-preedit-text): New special event handlers.
+
        * src/android.c (struct android_emacs_window): Add function
        lookup_string.
        (android_init_emacs_window): Adjust accordingly.
        (android_wc_lookup_string): New function.
-       * src/androidgui.h (struct android_key_event): Improve
-       commentary.
+
+       * src/androidgui.h (struct android_key_event): Improve commentary.
        (enum android_lookup_status): New enum.
+
        * src/androidterm.c (handle_one_android_event): Synchronize IM
        lookup code with X.
+
        * src/coding.c (from_unicode_buffer): Implement on Android.
+
        * src/coding.h:
        * src/sfnt.c: Fix commentary.
 
 2023-02-11  Po Lu  <luangruo@yahoo.com>
 
-       Fix displaying popup menus from a menu entry on Android
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity, onDestroy)
+       * java/org/gnu/emacs/EmacsActivity.java (onDestroy)
        (onWindowFocusChanged): Keep track of the last focused activity.
-       * java/org/gnu/emacs/EmacsDialog.java (display1): Use it if
-       there is no current focus.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/org/gnu/emacs/EmacsDialog.java (display1): Use it if there
+       is no current focus.
 
 2023-02-10  Po Lu  <luangruo@yahoo.com>
 
-       Improve appearance of the Android preferences screen
        * .gitignore: Add org/gnu/emacs/R.java.
+
        * cross/Makefile.in (top_builddir): Include verbose.mk.  Rewrite
        rules to print nice looking statements.
+
        * doc/emacs/android.texi (Android, Android Startup)
        (Android Environment, Android Windowing, Android Fonts):
        * doc/emacs/emacs.texi (Top): Add an extra ``Android
        Troubleshooting'' node and move troubleshooting details there.
+
        * java/Makefile.in: Generate R.java; improve appearance by using
        verbose.mk.
 
-       * java/org/gnu/emacs/EmacsPreferencesActivity.java: Reimplement
-       in terms of PreferencesActivity.
+       * java/org/gnu/emacs/EmacsPreferencesActivity.java: Reimplement in
+       terms of PreferencesActivity.
+
        * java/org/gnu/emacs/EmacsView.java (handleDirtyBitmap): Avoid
        flicker.
+
        * java/res/xml/preferences.xml: New file.
-       * src/verbose.mk.in (AM_V_AAPT, AM_V_SILENT): New variables.
 
-2023-02-10  Po Lu  <luangruo@yahoo.com>
+       * src/verbose.mk.in (AM_V_AAPT, AM_V_SILENT): New variables.
 
-       Implement more features for the Emacs ``documents provider''
        * java/org/gnu/emacs/EmacsDocumentsProvider.java (queryRoots):
        Implement isChild.
        (getNotificationUri, notifyChange): New functions.
@@ -4909,64 +4408,52 @@
 
        * java/org/gnu/emacs/EmacsCopyArea.java (perform): Fix typo.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Fix buffer swapping on Android 7.1 and earlier
        * java/org/gnu/emacs/EmacsSurfaceView.java
        (reconfigureFrontBuffer): Don't use function only present on
        Android 8.0 and later.
 
-       Update Android port
        * doc/emacs/android.texi (Android Windowing): Remove yet another
        limitation.
+
        * java/debug.sh: Make this work on systems which prohibit
        attaching to app processes from adbd.
-       * java/org/gnu/emacs/EmacsCopyArea.java (perform): Avoid
-       creating copies whenever possible.
+
+       * java/org/gnu/emacs/EmacsCopyArea.java (perform): Avoid creating
+       copies whenever possible.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
        Remove SurfaceView based implementation and use manual double
        buffering with invalidate instead.
+
        * java/org/gnu/emacs/EmacsView.java (EmacsView, handleDirtyBitmap)
        (raise, lower, onDetachedFromWindow): Adjust accordingly.
+
        * java/org/gnu/emacs/EmacsWindow.java (windowUpdated): Remove
        function.
-       * src/sfntfont.c (sfntfont_open): Set font->max_width correctly.
-
-2023-02-10  Po Lu  <luangruo@yahoo.com>
 
-       Fix IUP for contours which start past end
-       Found with Droid Sans Mono hinted with ttfautohint 1.8.4.
+       * src/sfntfont.c (sfntfont_open): Set font->max_width correctly.
 
        * src/sfnt.c (IUP_SINGLE_PAIR): If i is initially more than end,
        make it start.
        (sfnt_verbose): Handle cases where interpreter->glyph_zone is
        NULL.
        (main): Update tests.
-
-2023-02-10  Po Lu  <luangruo@yahoo.com>
-
-       Fix typo
-       * src/sfnt.c (sfnt_read_cmap_table): Fix typo.
+       (sfnt_read_cmap_table): Fix typo.
        (main): Update tests.
 
 2023-02-09  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * java/AndroidManifest.xml.in: Declare the new documents provider.
 
-       Allow other text editors to edit files in Emacs' home directory
-       * java/AndroidManifest.xml.in: Declare the new documents
-       provider.
        * java/README: Describe the meaning of files in res/values.
-       * java/org/gnu/emacs/EmacsDocumentsProvider.java
-       (EmacsDocumentsProvider): New file.
+
+       * java/org/gnu/emacs/EmacsDocumentsProvider.java: New file.
+
        * java/res/values-v19/bool.xml:
        * java/res/values/bool.xml: New files.
 
        * src/sfnt.c (main): Update tests.
 
-2023-02-09  Po Lu  <luangruo@yahoo.com>
-
-       Implement instructing compound glyphs
        * src/sfnt.c (sfnt_read_simple_glyph, sfnt_read_compound_glyph)
        (sfnt_read_glyph): Take size_t offsets.
        (struct sfnt_compound_glyph_context)
@@ -4993,76 +4480,64 @@
 
 2023-02-08  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * src/sfnt.c (SCFS): Fix order of arguments.
        (sfnt_normalize_vector): Make sure vx and vy are within a
        reasonable range.
        (sfnt_move): Don't move when vectors are orthogonal.
        (main): Update.
 
-       Update Android port
        * doc/emacs/android.texi (Android Startup): Fix typos.
+
        * src/sfnt.c (sfnt_interpret_msirp): Fix order in which operands
        to MSIRP are popped.
        (main): Reduce ppem values.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-02-08  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * doc/lispref/frames.texi (On-Screen Keyboards): Describe return
        value of `frame-toggle-on-screen-keyboard'.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (surfaceChanged)
-       (surfaceCreated, EmacsSurfaceView): Remove unuseful
-       synchronization code.  The framework doesn't seem to look at
-       this at all.
+       (surfaceCreated): Remove purposeless synchronization code.  The
+       framework doesn't seem to consult this at all.
 
-       * java/org/gnu/emacs/EmacsView.java (EmacsView):
-       (onLayout): Lay out the window after children.
+       * java/org/gnu/emacs/EmacsView.java (onLayout): Lay out the window
+       after children.
        (swapBuffers): Properly implement `force'.
        (windowUpdated): Delete function.
 
-       * lisp/frame.el (frame-toggle-on-screen-keyboard): Return
-       whether or not the on screen keyboard might've been displayed.
+       * lisp/frame.el (frame-toggle-on-screen-keyboard): Return whether
+       or not the on screen keyboard might've been displayed.
 
-       * lisp/minibuffer.el (minibuffer-on-screen-keyboard-timer):
-       (minibuffer-on-screen-keyboard-displayed):
-       (minibuffer-setup-on-screen-keyboard):
+       * lisp/minibuffer.el (minibuffer-on-screen-keyboard-timer)
+       (minibuffer-on-screen-keyboard-displayed)
+       (minibuffer-setup-on-screen-keyboard)
        (minibuffer-exit-on-screen-keyboard): Improve OSK dismissal when
        there are consecutive minibuffers.
 
        * lisp/touch-screen.el (touch-screen-window-selection-changed):
        New function.
-       (touch-screen-handle-point-up): Register it as a window
-       selection changed function.
+       (touch-screen-handle-point-up): Register it as a window selection
+       changed function.
 
        * src/android.c (struct android_emacs_window)
-       (android_init_emacs_window): Remove references to
-       `windowUpdated'.
+       (android_init_emacs_window): Remove references to `windowUpdated'.
        (android_window_updated): Delete function.
+
        * src/android.h (struct android_output): Remove
        `last_configure_serial'.
+
        * src/androidterm.c (handle_one_android_event)
        (android_frame_up_to_date):
+
        * src/androidterm.h (struct android_output): Remove frame
        synchronization, as that does not work on Android.
 
-2023-02-08  Po Lu  <luangruo@yahoo.com>
-
-       Fix graphics state when instructing glyphs
        * src/sfntfont.c (sfntfont_get_glyph_outline): Take new argument
        STATE and restore it prior to instructing the glyph.
        (sfntfont_measure_instructed_pcm, sfntfont_measure_pcm)
        (sfntfont_draw): Adjust accordingly.
-
-       Correctly round bearing values while computing pcm
-       * src/sfntfont.c (sfntfont_measure_instructed_pcm)
+       (sfntfont_measure_instructed_pcm)
        (sfntfont_measure_pcm): Ceil rbearing value.
 
-2023-02-08  Po Lu  <luangruo@yahoo.com>
-
-       Improve text display on Android port
        * src/sfnt.c (sfnt_build_glyph_outline): Clear
        build_outline_context.
        (sfnt_poly_coverage): Extend coverage map.
@@ -5070,39 +4545,32 @@
        increase in coverage makes this hack unnecessary.
        (sfnt_build_outline_edges): Likewise.
        (sfnt_compare_edges): Remove function.
-       (sfnt_edge_sort): New function.  Since edges are already
-       partially sorted, and there are not many, insertion sort
-       suffices.
+       (sfnt_edge_sort): New function.  Since edges are already partially
+       sorted, and there are not many, insertion sort suffices.
        (sfnt_poly_edges): Use sfnt_edge_sort.
        (sfnt_fill_span): Stop rounding x0 and x1 to the grid, and make
        coverage computation static.
-       (sfnt_lookup_glyph_metrics): Fix return code for unscaled
-       metrics.
+       (sfnt_lookup_glyph_metrics): Fix return code for unscaled metrics.
        (sfnt_scale_metrics): New function.
        (SFNT_ENABLE_HINTING): Remove define.
        (struct sfnt_cvt_table, struct sfnt_fpgm_table)
        (struct sfnt_prep_table): Move to sfnt.h.
-       (sfnt_read_cvt_table):
-       (sfnt_read_fpgm_table, sfnt_read_prep_table): Make TEST_STATIC.
+       (sfnt_read_cvt_table, sfnt_read_fpgm_table, sfnt_read_prep_table):
+       Make TEST_STATIC.
        (struct sfnt_unit_vector, struct sfnt_interpreter_definition)
        (struct sfnt_interpreter_zone, struct sfnt_graphics_state):
        (struct sfnt_interpreter): Move to sfnt.h.
        (sfnt_make_interpreter): Make TEST_STATIC.
        (POP, PUSH, DELTAP1, DELTAP2, DELTAP3): When TEST, define to
        regular push and pop.
-       (sfnt_deltac):
-       (sfnt_deltap): Fix order of arguments.
+       (sfnt_deltac, sfnt_deltap): Fix order of arguments.
        (IUP_SINGLE_PAIR): Fix interpolation loop wraparound.
-       (sfnt_interpret_font_program):
+       (sfnt_interpret_font_program)
        (sfnt_interpret_control_value_program): Make TEST_STATIC.
        (struct sfnt_instructed_outline): Move to sfnt.h.
        (sfnt_build_instructed_outline): Make TEST_STATIC.
-       (sfnt_interpret_simple_glyph):
-       (sfnt_x_raster):
-       (sfnt_test_raster):
-       (all_tests):
-       (sfnt_verbose):
-       (main): Improve test code.
+       (sfnt_interpret_simple_glyph, sfnt_x_raster, sfnt_test_raster)
+       (all_tests, sfnt_verbose, main): Improve test code.
 
        * src/sfnt.h (SFNT_ENABLE_HINTING, struct sfnt_cvt_table)
        (struct sfnt_fpgm_table, struct sfnt_prep_table)
@@ -5110,8 +4578,10 @@
        (struct sfnt_interpreter_zone, struct sfnt_graphics_state)
        (struct sfnt_interpreter, struct sfnt_instructed_outline)
        (PROTOTYPE): New definitions.
+
        * src/sfntfont-android.c (sfntfont_android_put_glyphs): Make
        coordinate generation more straightforward.
+
        * src/sfntfont.c (sfntfont_get_glyph_outline): New arguments
        INTERPRETER and METRICS.
        (struct sfnt_font_info): New tables.
@@ -5125,20 +4595,13 @@
 
 2023-02-07  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Remove junk from instruction table
-       * src/sfnt.c (sfnt_name_instruction): Do so.
-
-       Remove bresenham stuff
-       * src/sfnt.c (sfnt_step_edge, sfnt_step_edge_n)
+       * src/sfnt.c (sfnt_name_instruction): Remove junk from instruction
+       table.
+       (sfnt_step_edge, sfnt_step_edge_n)
        (sfnt_build_outline_edges, sfnt_test_edge, main):
        * src/sfnt.h (struct sfnt_edge): Stop using error corrected line
        drawing, as it's actually slower.
 
-2023-02-07  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * INSTALL.android: Describe patches for BoringSSL on ARM.
 
        * src/sfnt.c (sfnt_build_glyph_outline): Remove redundant
@@ -5155,21 +4618,19 @@
        (sfnt_large_integer_add): New function.
        (sfnt_mul_f26dot6_fixed): Round product.
        (sfnt_make_interpreter): Remove redundant multiplication.
-
-       (CHECK_STACK_ELEMENTS, POP_UNCHECKED, PUSH_UNCHECKED): New
-       macros.
+       (CHECK_STACK_ELEMENTS, POP_UNCHECKED, PUSH_UNCHECKED): New macros.
        (MOVE, POP, SWAP, CINDEX, RS, RCVT, LT, LTEQ, GT, GTEQ, EQ, NEQ)
        (EVEN, AND, OR, NOT, ADD, SUB, DIV, MUL, ABS, NEG, FLOOR, CEILING)
-       (GETINFO, ROLL, _MAX, _MIN, ROUND, NROUND, GC, MD): Don't check
-       SP redundantly, especially when pushing an element right after
+       (GETINFO, ROLL, _MAX, _MIN, ROUND, NROUND, GC, MD): Don't check SP
+       redundantly, especially when pushing an element right after
        popping one.
        (sfnt_move_glyph_zone): Don't touch points by passing NULL as
        flags.
-       (sfnt_direct_move_zp2): Touch P in the directions of the
-       movement.
+       (sfnt_direct_move_zp2): Touch P in the directions of the movement.
        (sfnt_interpret_scfs): Fix coding style.
        (sfnt_interpret_simple_glyph): Don't round Y coordinates.
-       (sfnt_test_span, sfnt_test_edges, sfnt_debug_edges, sfnt_test_edge)
+       (sfnt_test_span, sfnt_test_edges, sfnt_debug_edges)
+       (sfnt_test_edge)
        (sfnt_x_raster, sfnt_test_raster, rcvt_test_args)
        (deltac1_test_args, deltac2_test_args, deltac3_test_args)
        (roll_1_test_args, sfnt_run_hook, sfnt_identify_instruction)
@@ -5179,19 +4640,16 @@
 
 2023-02-06  Po Lu  <luangruo@yahoo.com>
 
-       Port emacsclient wrapper to Android 7.1 and earlier
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Load every
-       native library on which Emacs depends prior to loading libemacs
-       itself.
+       * java/org/gnu/emacs/EmacsNative.java
+       (EmacsNative) <static constructor>: Load every native library on
+       which Emacs depends prior to loading libemacs itself.
 
        * java/org/gnu/emacs/EmacsOpenActivity.java (readEmacsClientLog)
-       (EmacsOpenActivity, startEmacsClient): Don't use redirectError
-       on Android 7.1 and earlier.
-
-2023-02-06  Po Lu  <luangruo@yahoo.com>
+       (startEmacsClient): Don't use redirectError on Android 7.1 and
+       earlier.
 
-       Adjust ndk-build implementation for old NDK versions
        * configure.ac: Pass ANDROID_CFLAGS to ndk_INIT.
+
        * cross/ndk-build/Makefile.in (NDK_BUILD_CFLAGS):
        * cross/ndk-build/ndk-build-shared-library.mk
        ($(call objname,$(LOCAL_MODULE),$(basename $(1)))):
@@ -5199,14 +4657,10 @@
        * cross/ndk-build/ndk-build-static-library.mk
        ($(call objname,$(LOCAL_MODULE),$(basename $(1)))):
        ($$(error Unsupported suffix): Use NDK_BUILD_CFLAGS.
+
        * m4/ndk-build.m4 (ndk_INIT): Accept cflags.
        (ndk_CONFIG_FILES): Export NDK_BUILD_CFLAGS.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-02-06  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * java/AndroidManifest.xml.in: Prevent the Emacs activity from
        being overlayed by the emacsclient wrapper.
        * java/org/gnu/emacs/EmacsOpenActivity.java (run): Likewise.
@@ -5215,13 +4669,9 @@
        * java/org/gnu/emacs/EmacsWindow.java (onTouchEvent): Handle
        ACTION_CANCEL correctly.
 
-2023-02-06  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * src/sfnt.c (struct sfnt_build_glyph_outline_context)
        (sfnt_build_glyph_outline, sfnt_fill_span): Improve glyph
        appearance by rounding coordinate values.
-
        (struct sfnt_interpreter): New fields `twilight_original_x',
        `twilight_original_y'.
        (sfnt_make_interpreter): Set new fields.
@@ -5231,13 +4681,15 @@
        callers changed.
        (sfnt_address_zp2, sfnt_address_zp1, sfnt_address_zp0): Obtain
        original positions in the twilight zone as well.
-       (sfnt_check_zp1, sfnt_interpret_fliprgoff, sfnt_interpret_fliprgon)
+       (sfnt_check_zp1, sfnt_interpret_fliprgoff)
+       (sfnt_interpret_fliprgon)
        (sfnt_interpret_flippt, sfnt_interpret_scfs, sfnt_interpret_miap)
        (sfnt_interpret_alignrp, sfnt_line_to_vector, P)
        (sfnt_interpret_msirp, sfnt_interpret_ip, sfnt_interpret_call)
        (load_point, sfnt_interpret_iup_1, sfnt_interpret_iup)
        (sfnt_interpret_run, struct sfnt_scaled_outline)
-       (struct sfnt_instructed_outline, sfnt_decompose_instructed_outline)
+       (struct sfnt_instructed_outline)
+       (sfnt_decompose_instructed_outline)
        (sfnt_build_instructed_outline, sfnt_compute_phantom_points)
        (sfnt_interpret_simple_glyph, all_tests, sfnt_setup_debugger)
        (sfnt_name_instruction, sfnt_draw_debugger, sfnt_run_hook)
@@ -5247,16 +4699,20 @@
 
 2023-02-05  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * INSTALL.android: Explain how to build selinux.
+
        * configure.ac: Enable selinux on Android.
-       * cross/ndk-build/ndk-build-shared-library.mk: ($(call
-       objname,$(LOCAL_MODULE),$(basename $(1))))::($$(error
-       Unsupported suffix)::(NDK_CFLAGS_$(LOCAL_MODULE)):
-       * cross/ndk-build/ndk-build-static-library.mk: ($(call
-       objname,$(LOCAL_MODULE),$(basename $(1))))::($$(error
-       Unsupported suffix)::(NDK_CFLAGS_$(LOCAL_MODULE)): Correctly
-       handle files with a .cc suffix, and clang-specific asflags.
+
+       * cross/ndk-build/ndk-build-shared-library.mk
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1))))
+       ($$(error Unsupported suffix))
+       (NDK_CFLAGS_$(LOCAL_MODULE)):
+       * cross/ndk-build/ndk-build-static-library.mk
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1))))
+       ($$(error Unsupported suffix))
+       (NDK_CFLAGS_$(LOCAL_MODULE)): Correctly handle files with a .cc
+       suffix, and clang-specific asflags.
+
        * cross/ndk-build/ndk-clear-vars.mk: Handle AOSP extensions
        LOCAL_ADDITIONAL_DEPENDENCIES,
        LOCAL_CLANG_ASFLAGS_$(NDK_BUILD_ARCH) and LOCAL_IS_HOST_MODULE.
@@ -5266,12 +4722,12 @@
 
        * java/org/gnu/emacs/EmacsView.java (EmacsView): New flag
        `isCurrentlyTextEditor'.
-       (showOnScreenKeyboard, hideOnScreenKeyboard): Set as
-       appropriate.
+       (showOnScreenKeyboard, hideOnScreenKeyboard): Set as appropriate.
        (onCheckIsTextEditor): Return its value.
 
        * lisp/touch-screen.el (touch-screen-handle-scroll): Don't ding
        at buffer limits.
+
        * m4/ndk-build.m4: Improve doc.
 
        * src/Makefile.in (LIBSELINUX_CFLAGS): New variable.
@@ -5279,173 +4735,97 @@
 
 2023-02-05  Po Lu  <luangruo@yahoo.com>
 
-       Update from gnulib
-       * admin/merge-gnulib (avoided_flags):
-       * cross/lib/cdefs.h (__bos):
-       (__glibc_unsigned_or_positive):
-       (__glibc_unsafe_len):
-       (__glibc_fortify):
-       (__glibc_fortify_n):
-       * cross/lib/isnan.c:
-       * cross/lib/libc-config.h:
-       * cross/lib/openat-proc.c (openat_proc_name):
-       * cross/lib/vasnprintf.c (VASNPRINTF):
-       * cross/lib/verify.h (_Static_assert):
-       (_GL_SA3):
-       * lib/gnulib.mk.in (HAVE_GRANTPT):
-       (HAVE_SPAWN_H):
-       (NEXT_AS_FIRST_DIRECTIVE_LIMITS_H):
-       (NEXT_LIMITS_H):
-       (REPLACE_GETSUBOPT):
-       (REPLACE_ILOGB):
-       (SYSTEM_TYPE):
-       (BUILT_SOURCES):
-       * lib/isnan.c:
-       * lib/vasnprintf.c (VASNPRINTF):
-       * lib/verify.h (_GL_SA3):
-       * m4/gnulib-common.m4 (gl_COMMON_BODY):
-       * m4/gnulib-comp.m4 (gl_INIT): Update from gnulib.
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
-       * src/sfnt.c (struct sfnt_graphics_state):
-       (LOOPCALL):
-       (DELTAC3):
-       (PROJECT):
-       (SHPIX):
-       (sfnt_save_projection_vector):
-       (sfnt_check_zp0):
-       (sfnt_dual_project_vector):
-       (sfnt_interpret_scfs):
-       (sfnt_round_symmetric):
-       (sfnt_interpret_miap):
-       (sfnt_interpret_alignrp_1):
-       (sfnt_interpret_alignrp):
-       (sfnt_measure_distance):
-       (sfnt_interpret_msirp):
-       (sfnt_interpret_ip):
-       (sfnt_interpret_mdap):
-       (sfnt_deltap):
-       (sfnt_dual_project_onto_any_vector):
-       (sfnt_validate_gs):
-       (sfnt_set_projection_vector):
-       (sfnt_interpret_shp):
-       (sfnt_interpret_run):
-       (sfnt_check_sloop):
-       (main): Check in more WIP font code.
+       * m4, lib: Update from Gnulib.
+
+       * src/sfnt.c (struct sfnt_graphics_state, LOOPCALL, DELTAC3)
+       (PROJECT, SHPIX, sfnt_save_projection_vector, sfnt_check_zp0)
+       (sfnt_dual_project_vector, sfnt_interpret_scfs)
+       (sfnt_round_symmetric, sfnt_interpret_miap)
+       (sfnt_interpret_alignrp_1, sfnt_interpret_alignrp)
+       (sfnt_measure_distance, sfnt_interpret_msirp, sfnt_interpret_ip)
+       (sfnt_interpret_mdap, sfnt_deltap)
+       (sfnt_dual_project_onto_any_vector, sfnt_validate_gs)
+       (sfnt_set_projection_vector, sfnt_interpret_shp)
+       (sfnt_interpret_run, sfnt_check_sloop, main): Check in more WIP
+       font code.
 
 2023-02-04  Po Lu  <luangruo@yahoo.com>
 
-       Add emacsclient desktop file equivalent on Android
        * doc/emacs/android.texi (Android File System):
+
        * java/AndroidManifest.xml.in: Update with new activity.  Remove
        Android 10 restrictions through a special flag.
 
        * java/org/gnu/emacs/EmacsNative.java (getProcName): New
        function.
-       * java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity):
-       New file.
+
+       * java/org/gnu/emacs/EmacsOpenActivity.java: New file.
+
        * java/org/gnu/emacs/EmacsService.java (getLibraryDirection):
        Remove unused annotation.
+
        * lib-src/emacsclient.c (decode_options): Set alt_display on
        Android.
-       * src/android.c (android_proc_name): New function.
-       (NATIVE_NAME): Export via JNI.
 
-2023-02-04  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_proc_name): New function.
+       (getProcName): Export via JNI.
 
-       Add additional permissions to Android port
        * doc/emacs/android.texi (Android Environment):
+
        * java/AndroidManifest.xml.in: Add network state permissions.
 
-       Update Android port
-       * src/sfnt.c (sfnt_multiply_divide_signed):
-       (struct sfnt_interpreter_zone):
-       (struct sfnt_graphics_state):
-       (struct sfnt_interpreter):
-       (sfnt_mul_f2dot14):
-       (sfnt_interpret_trap):
-       (WCVTF):
-       (ALIGNPTS):
-       (sfnt_scale_by_freedom_vector):
-       (sfnt_interpret_utp):
-       (sfnt_address_zp2):
-       (sfnt_address_zp1):
-       (sfnt_address_zp0):
-       (sfnt_check_zp2):
-       (sfnt_move_zp0):
-       (sfnt_move_zp1):
-       (sfnt_move_glyph_zone):
-       (sfnt_move_twilight_zone):
-       (sfnt_direct_move_zp2):
-       (sfnt_interpret_alignpts):
-       (sfnt_interpret_isect):
-       (sfnt_line_to_vector):
-       (sfnt_deltac):
-       (sfnt_interpret_mdap):
-       (sfnt_interpret_call):
-       (sfnt_dot_fix_14):
-       (sfnt_move_x):
-       (sfnt_move_y):
-       (sfnt_move):
-       (sfnt_validate_gs):
-       (sfnt_interpret_shz):
-       (sfnt_interpret_shc):
-       (sfnt_interpret_shp):
-       (sfnt_interpret_iup_1):
-       (sfnt_interpret_iup):
-       (sfnt_interpret_run):
-       (sfnt_interpret_font_program):
-       (sfnt_interpret_control_value_program):
-       (sfnt_interpret_simple_glyph):
-       (jrot_test_args):
-       (jrof_test_args):
-       (all_tests):
-       (main): Check in more WIP code.
+       * src/sfnt.c (sfnt_multiply_divide_signed)
+       (struct sfnt_interpreter_zone, struct sfnt_graphics_state)
+       (struct sfnt_interpreter, sfnt_mul_f2dot14)
+       (sfnt_interpret_trap, WCVTF)
+       (ALIGNPTS, sfnt_scale_by_freedom_vector, sfnt_interpret_utp)
+       (sfnt_address_zp2, sfnt_address_zp1, sfnt_address_zp0)
+       (sfnt_check_zp2, sfnt_move_zp0, sfnt_move_zp1)
+       (sfnt_move_glyph_zone, sfnt_move_twilight_zone)
+       (sfnt_direct_move_zp2, sfnt_interpret_alignpts)
+       (sfnt_interpret_isect, sfnt_line_to_vector, sfnt_deltac)
+       (sfnt_interpret_mdap, sfnt_interpret_call, sfnt_dot_fix_14)
+       (sfnt_move_x, sfnt_move_y, sfnt_move, sfnt_validate_gs)
+       (sfnt_interpret_shz, sfnt_interpret_shc, sfnt_interpret_shp)
+       (sfnt_interpret_iup_1, sfnt_interpret_iup, sfnt_interpret_run)
+       (sfnt_interpret_font_program)
+       (sfnt_interpret_control_value_program)
+       (sfnt_interpret_simple_glyph, jrot_test_args, jrof_test_args)
+       (all_tests, main): Check in more WIP code.
 
 2023-02-02  Po Lu  <luangruo@yahoo.com>
 
-       Add Emacs icon for Android package
        * java/AndroidManifest.xml.in: Add new icon.
+
        * java/Makefile.in (srcdir): New variable.
        (JAVA_FILES, RESOURCE_FILES): Update variables.
        (emacs.apk-in): Apply resources.
+
        * java/README: Describe directory tree.
 
-       Add Emacs icon for Android
        * java/res/drawable/emacs.png: New file.
 
-       Update Android port
        * src/android.c (android_get_current_api_level): New function.
-       * src/android.h: Export it.
-       * src/sfntfont-android.c (init_sfntfont_android): Make device
-       API level detection always work.
 
-       Clean up compiler warnings
-       * src/sfnt.c (sfnt_multiply_divide_signed): Add MAYBE_UNUSED.
+       * src/android.h: Export it.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/sfntfont-android.c (init_sfntfont_android): Make device API
+       level detection always work.
 
-2023-02-02  Po Lu  <luangruo@yahoo.com>
+       * src/sfnt.c (sfnt_multiply_divide_signed): Add MAYBE_UNUSED.
 
-       Update Android port
-       * src/sfnt.c (xmalloc, xrealloc): Improve behavior upon
-       allocation failures during test.
+       * src/sfnt.c (xmalloc, xrealloc): Improve behavior upon allocation
+       failures during test.
        (sfnt_table_names): Add prep.
        (sfnt_transform_coordinates): Allow applying offsets during
        coordinate transform.
        (sfnt_decompose_compound_glyph): Defer offset computation until
        any component compound glyph is loaded, then apply it during the
        transform process.
-
        (sfnt_multiply_divide): Make available everywhere.  Implement on
        64 bit systems.
        (sfnt_multiply_divide_signed): New function.
        (sfnt_mul_fixed): Fix division overflow.
-
        (sfnt_curve_to_and_build_1, sfnt_build_glyph_outline): Remove
        outdated comment.
        (sfnt_build_outline_edges): Fix coding style.
@@ -5463,128 +4843,52 @@
        `move', `vector_dot_product'.  Rename to `sfnt_graphics_state'.
        (struct sfnt_interpreter, sfnt_mul_f26dot6): Stop doing rounding
        division.
-       (sfnt_init_graphics_state):
-       (sfnt_make_interpreter):
-       (MOVE):
-       (SSW):
-       (RAW):
-       (SDS):
-       (ADD):
-       (SUB):
-       (ABS):
-       (NEG):
-       (WCVTF):
-       (_MIN):
-       (S45ROUND):
-       (SVTCAx):
-       (sfnt_set_srounding_state):
-       (sfnt_skip_code):
-       (sfnt_interpret_unimplemented):
-       (sfnt_interpret_fdef):
-       (sfnt_interpret_idef):
-       (sfnt_interpret_if):
-       (sfnt_interpret_else):
-       (sfnt_round_none):
-       (sfnt_round_to_grid):
-       (sfnt_round_to_double_grid):
-       (sfnt_round_down_to_grid):
-       (sfnt_round_up_to_grid):
-       (sfnt_round_to_half_grid):
-       (sfnt_round_super):
-       (sfnt_validate_gs):
-       (sfnt_interpret_run):
-       (sfnt_interpret_font_program):
-       (struct sfnt_test_dcontext):
-       (sfnt_test_move_to):
-       (sfnt_test_line_to):
-       (sfnt_test_curve_to):
-       (sfnt_test_get_glyph):
-       (sfnt_test_free_glyph):
-       (sfnt_test_span):
-       (sfnt_test_edge_ignore):
-       (sfnt_test_edge):
-       (sfnt_test_raster):
-       (test_interpreter_profile):
-       (test_cvt_values):
-       (test_interpreter_cvt):
-       (test_interpreter_head):
-       (sfnt_make_test_interpreter):
-       (struct sfnt_interpreter_test):
-       (sfnt_run_interpreter_test):
-       (struct sfnt_generic_test_args):
-       (sfnt_generic_check):
-       (sfnt_check_srp0):
-       (sfnt_check_szp0):
-       (sfnt_check_sloop):
-       (struct sfnt_rounding_test_args):
-       (sfnt_check_rounding):
-       (sfnt_check_smd):
-       (sfnt_check_scvtci):
-       (sfnt_check_sswci):
-       (sfnt_check_ssw):
-       (sfnt_check_flipon):
-       (sfnt_check_flipoff):
-       (npushb_test_args):
-       (npushw_test_args):
-       (pushb_test_args):
-       (pushw_test_args):
-       (stack_overflow_test_args):
-       (stack_underflow_test_args):
-       (rtg_test_args):
-       (rtg_symmetric_test_args):
-       (rtg_1_test_args):
-       (rtg_1_symmetric_test_args):
-       (rthg_test_args):
-       (rthg_1_test_args):
-       (rtdg_test_args):
-       (rtdg_1_test_args):
-       (rtdg_2_test_args):
-       (rtdg_3_test_args):
-       (else_test_args):
-       (jmpr_test_args):
-       (dup_test_args):
-       (pop_test_args):
-       (clear_test_args):
-       (swap_test_args):
-       (depth_test_args):
-       (cindex_test_args):
-       (mindex_test_args):
-       (raw_test_args):
-       (loopcall_test_args):
-       (call_test_args):
-       (fdef_test_args):
-       (fdef_1_test_args):
-       (endf_test_args):
-       (ws_test_args):
-       (rs_test_args):
-       (wcvtp_test_args):
-       (rcvt_test_args):
-       (mppem_test_args):
-       (mps_test_args):
-       (debug_test_args):
-       (lt_test_args):
-       (all_tests):
-       (main): Implement more instructions.
-
-       * src/sfnt.h (enum sfnt_table, struct sfnt_glyph_metrics): Add
-       new tables.  Add comment.
-
-2023-01-30  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Merge remote-tracking branch 'origin/master' into feature/android
+       (sfnt_init_graphics_state, sfnt_make_interpreter, MOVE, SSW, RAW)
+       (SDS, ADD, SUB, ABS, NEG, WCVTF, _MIN, S45ROUND, SVTCAx)
+       (sfnt_set_srounding_state, sfnt_skip_code)
+       (sfnt_interpret_unimplemented, sfnt_interpret_fdef)
+       (sfnt_interpret_idef, sfnt_interpret_if, sfnt_interpret_else)
+       (sfnt_round_none, sfnt_round_to_grid, sfnt_round_to_double_grid)
+       (sfnt_round_down_to_grid, sfnt_round_up_to_grid)
+       (sfnt_round_to_half_grid, sfnt_round_super, sfnt_validate_gs)
+       (sfnt_interpret_run, sfnt_interpret_font_program)
+       (struct sfnt_test_dcontext, sfnt_test_move_to, sfnt_test_line_to)
+       (sfnt_test_curve_to, sfnt_test_get_glyph, sfnt_test_free_glyph)
+       (sfnt_test_span, sfnt_test_edge_ignore, sfnt_test_edge)
+       (sfnt_test_raster, test_interpreter_profile, test_cvt_values)
+       (test_interpreter_cvt, test_interpreter_head)
+       (sfnt_make_test_interpreter, struct sfnt_interpreter_test)
+       (sfnt_run_interpreter_test, struct sfnt_generic_test_args)
+       (sfnt_generic_check, sfnt_check_srp0, sfnt_check_szp0)
+       (sfnt_check_sloop, struct sfnt_rounding_test_args)
+       (sfnt_check_rounding, sfnt_check_smd, sfnt_check_scvtci)
+       (sfnt_check_sswci, sfnt_check_ssw, sfnt_check_flipon)
+       (sfnt_check_flipoff, npushb_test_args, npushw_test_args)
+       (pushb_test_args, pushw_test_args, stack_overflow_test_args)
+       (stack_underflow_test_args, rtg_test_args)
+       (rtg_symmetric_test_args, rtg_1_test_args)
+       (rtg_1_symmetric_test_args, rthg_test_args, rthg_1_test_args)
+       (rtdg_test_args, rtdg_1_test_args, rtdg_2_test_args)
+       (rtdg_3_test_args, else_test_args, jmpr_test_args, dup_test_args)
+       (pop_test_args, clear_test_args, swap_test_args, depth_test_args)
+       (cindex_test_args, mindex_test_args, raw_test_args)
+       (loopcall_test_args, call_test_args, fdef_test_args)
+       (fdef_1_test_args, endf_test_args, ws_test_args, rs_test_args)
+       (wcvtp_test_args, rcvt_test_args, mppem_test_args, mps_test_args)
+       (debug_test_args, lt_test_args, all_tests, main): Implement more
+       instructions.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/sfnt.h (enum sfnt_table, struct sfnt_glyph_metrics): Add new
+       tables.  Add comment.
 
 2023-01-30  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * cross/ndk-build/ndk-build-shared-library.mk: ($(call
-       objname,$(LOCAL_MODULE),$(basename $(1)))):
-       * cross/ndk-build/ndk-build-static-library.mk: ($(call
-       objname,$(LOCAL_MODULE),$(basename $(1)))): Revert broken typo
-       fixes.
+       * cross/ndk-build/ndk-build-shared-library.mk
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1)))):
+       * cross/ndk-build/ndk-build-static-library.mk
+       ($(call objname,$(LOCAL_MODULE),$(basename $(1)))): Revert broken
+       typo fixes.
+
        * src/sfnt.c (TEST_STATIC): Define ARRAYELTS.
        (sfnt_table_names): New CVT and FPGM tables.
        (sfnt_decompose_compound_glyph, sfnt_decompose_glyph)
@@ -5637,43 +4941,43 @@
 
 2023-01-29  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Check in missing files
-       * .gitignore:
-       * cross/lib/_Noreturn.h (_Noreturn): Add missing gnulib files.
+       * .gitignore: Add missing Gnulib files.
 
-       Update Android port
        * INSTALL.android (module_target): Clarify documentation.
+
        * cross/ndk-build/ndk-build-shared-library.mk:
-       * cross/ndk-build/ndk-build-static-library.mk: Fix building Neon 
objects.
+       * cross/ndk-build/ndk-build-static-library.mk: Fix building Neon
+       objects.
+
        * java/AndroidManifest.xml.in: Add a version code.
 
 2023-01-28  Po Lu  <luangruo@yahoo.com>
 
-       Implement `restart-emacs' on Android
        * java/org/gnu/emacs/EmacsService.java (restartEmacs): New
        function.
+
        * src/android.c (struct android_emacs_service)
        (android_init_emacs_service): Add new method.
        (android_restart_emacs): New function.
+
        * src/android.h: Update prototypes.
+
        * src/emacs.c (Fkill_emacs): Call android_restart_emacs whenever
        appropriate.
 
-2023-01-28  Po Lu  <luangruo@yahoo.com>
-
-       Add libtiff support to Android port
        * INSTALL.android: Document how to build with libtiff.
 
        * build-aux/ndk-build-helper-1.mk (NDK_SO_NAME):
        * build-aux/ndk-build-helper-2.mk (NDK_A_NAME):
        * build-aux/ndk-build-helper-4.mk: Decrease number of duplicate
        dependencies found.
+
        * configure.ac (ANDROID_SDK_18_OR_EARLIER, XCONFIGURE, PNG_CFLAGS)
        (HAVE_TIFF): Allow using libtiff on Android.
+
        * cross/ndk-build/ndk-clear-vars.mk: Undefine additional
        variables.
+
        * cross/ndk-build/ndk-resolve.mk: Split CFLAGS resolution from
        a-name resolution, and do not recursively add archive or shared
        object names for dependencies of shared libraries.
@@ -5685,154 +4989,135 @@
 
        * src/image.c (syms_of_image): Fix typo.
 
-2023-01-28  Po Lu  <luangruo@yahoo.com>
+       * doc/emacs/android.texi (Android File System): Describe an easier
+       way to disable scoped storage.
 
-       Update Android port
-       * doc/emacs/android.texi (Android File System): Describe an
-       easier way to disable scoped storage.
        * java/AndroidManifest.xml.in: Add new permission to allow that.
+
        * java/README: Add more text describing Java.
+
        * java/org/gnu/emacs/EmacsContextMenu.java (Item): New fields
        `isCheckable' and `isChecked'.
        (EmacsContextMenu, addItem): New arguments.
        (inflateMenuItems): Set checked status as appropriate.
 
        * java/org/gnu/emacs/EmacsCopyArea.java (perform): Disallow
-       operations where width and height are less than or equal to
-       zero.
+       operations where width and height are less than or equal to zero.
+
        * lisp/menu-bar.el (menu-bar-edit-menu): Make
        execute-extended-command available as a menu item.
+
        * src/androidmenu.c (android_init_emacs_context_menu)
-       (android_menu_show):
-       * src/menu.c (have_boxes): Implement menu check boxes.
+       (android_menu_show): Implement menu check boxes.
+
+       * src/menu.c (have_boxes): Treat Android builds as providing menu
+       checkboxes.
 
 2023-01-28  Po Lu  <luangruo@yahoo.com>
 
-       Set up fontset stuff on Android
-       * lisp/term/android-win.el (window-system-initialization):
-       Create default fontset.
-
-       Fix file descriptor leaks
-       * src/sfntfont.c (sfntfont_read_cmap):
-       (sfntfont_open): Fix leaks of file descriptors.
-
-       Update from gnulib
-       * cross/lib/stdalign.in.h (_GL_STDALIGN_H):
-       (_):
-       (__alignof_is_defined):
-       * cross/lib/vasnprintf.c:
-       * lib/gnulib.mk.in (ANDROID_MIN_SDK):
-       (HAVE_SPAWN_H):
-       (LIBGCCJIT_LIBS):
-       (NATIVE_COMPILATION_AOT):
-       (NEXT_AS_FIRST_DIRECTIVE_LIMITS_H):
-       (NEXT_LIMITS_H):
-       (SIZEOF_LONG):
-       (stdalign.h):
-       * ../../../../dev/null:
-       * lib/stdalign.in.h (_GL_STDALIGN_H):
-       (_):
-       (__alignof_is_defined):
-       * lib/vasnprintf.c:
-       * m4/gnulib-common.m4 (gl_COMMON_BODY):
-       * m4/stdalign.m4 (gl_ALIGNASOF):
-       * m4/stddef_h.m4: Update from gnulib.
+       * lisp/term/android-win.el (window-system-initialization): Create
+       default fontset.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/sfntfont.c (sfntfont_read_cmap, sfntfont_open): Fix leaks of
+       file descriptors.
 
-2023-01-28  Po Lu  <luangruo@yahoo.com>
+       * m4, lib: Update from Gnulib.
 
-       Update Android port
        * INSTALL.android: Document support for gnutls and libgmp.
+
        * build-aux/ndk-build-helper-1.mk (NDK_SO_NAMES, NDK_INCLUDES)
        (SYSTEM_LIBRARIES):
        * build-aux/ndk-build-helper-2.mk: Recursively resolve and add
        shared library dependencies; even those of static libraries.
+
        * build-aux/ndk-module-extract.awk: Fix makefile_imports code.
+
        * configure.ac (ANDROID_SDK_18_OR_EARLIER, XCONFIGURE)
        (LIBGMP_CFLAGS): Enable GMP and gnutls on Android.
 
        * cross/ndk-build/Makefile.in (LOCAL_EXPORT_C_INCLUDES):
-       * cross/ndk-build/ndk-build-shared-library.mk: ($(call
-       objname,$(LOCAL_MODULE),$(basename $(1))))::($$(error
-       Unsupported suffix)::($(LOCAL_MODULE_FILENAME)):
-       * cross/ndk-build/ndk-build-static-library.mk: ($(call
-       objname,$(LOCAL_MODULE),$(basename $(1))))::($$(error
-       Unsupported suffix):
+       * cross/ndk-build/ndk-build-shared-library.mk:
        * cross/ndk-build/ndk-clear-vars.mk:
        * cross/ndk-build/ndk-resolve.mk (NDK_SYSTEM_LIBRARIES):
        (NDK_LOCAL_EXPORT_C_INCLUDES_$(LOCAL_MODULE)):
-       (NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)):
-       Implement ``LOCAL_ASM_RULE'' and ``LOCAL_C_ADDITIONAL_FLAGS''
-       extensions for libgmp.
+       (NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)): Implement ``LOCAL_ASM_RULE''
+       and ``LOCAL_C_ADDITIONAL_FLAGS'' extensions for libgmp.
 
        * doc/emacs/input.texi (Touchscreens): Document how to
        horizontally scroll.
+
        * java/org/gnu/emacs/EmacsActivity.java (attachWindow): Give the
        view focus again if necessary.
        (onPause): Call right super function.
+
        * java/org/gnu/emacs/EmacsPreferencesActivity.java (onClick):
-       Clear dumpFileName lest Emacs try to load a nonexistent dump
-       file.
+       Clear dumpFileName lest Emacs try to load a nonexistent dump file.
+
        * java/org/gnu/emacs/EmacsView.java (onDetachedFromWindow)
        (onAttachedToWindow): Call super functions.
-       (onCreateInputConnection): Make sure the IME never obscures
-       Emacs.
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, onKeyDown)
-       (onKeyUp): Improve tracking of quit keys.
+       (onCreateInputConnection): Make sure the IME never obscures Emacs.
+
+       * java/org/gnu/emacs/EmacsWindow.java (onKeyDown, onKeyUp):
+       Improve tracking of quit keys.
+
+       * lisp/isearch.el (isearch-mode): Bring up the onscreen keyboard.
 
-       * lisp/isearch.el (isearch-mode): Bring up the onscreen
-       keyboard.
        * lisp/touch-screen.el (touch-screen-current-tool): Add three
        fields.
        (touch-screen-handle-scroll): Allow hscrolling as well.
        (touch-screen-handle-touch): Add additional fields to
        `touch-screen-current-tool'.
-       * src/Makefile.in (LIBGMP_CFLAGS, EMACS_CFLAGS): Add new
-       variable.
-       * src/android.c (android_run_select_thread):
-       (android_write_event): Use pthread_cond_broadcast because
-       pthread_cond_signal does nothing on some Android
-       versions/devices?
 
-2023-01-26  Po Lu  <luangruo@yahoo.com>
+       * src/Makefile.in (LIBGMP_CFLAGS, EMACS_CFLAGS): Add new variable.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/android.c (android_run_select_thread, android_write_event):
+       Use pthread_cond_broadcast because pthread_cond_signal does
+       nothing on some Android versions/devices?
+
+2023-01-26  Po Lu  <luangruo@yahoo.com>
 
        * doc/emacs/input.texi (On-Screen Keyboards): Fix typo.
 
-       Update Android port
-       * INSTALL.android: Describe that apksigner is also required.
-       * configure.ac: Correctly add cross/Makefile to
-       SUBDIR_MAKEFILES.
-       * cross/Makefile.in: (config.status): Depend on
+       * INSTALL.android: Mention that apksigner is also required.
+
+       * configure.ac: Correctly add cross/Makefile to SUBDIR_MAKEFILES.
+
+       * cross/Makefile.in (config.status): Depend on
        $(top_srcdir)/config.status.
-       * doc/emacs/input.texi (On-Screen Keyboards): Document how to
-       quit without a physical keyboard.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function `quit'.
+
+       * doc/emacs/input.texi (On-Screen Keyboards): Document how to quit
+       without a physical keyboard.
+
+       * java/org/gnu/emacs/EmacsNative.java (quit): New function `quit'.
+
        * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): New field
        `lastVolumeButtonPress'.
        (onKeyDown): Quit if necessary.
-       * m4/ndk-build.m4 (ndk_where_cc): Fix search if CC is not a
-       single word.
+
+       * m4/ndk-build.m4 (ndk_where_cc): Fix search if CC is not a single
+       word.
+
        * src/android.c (android_open): Remove unused variable.
        (quit): New function.
+
        * src/androidmenu.c (android_process_events_for_menu): Allow
        quitting the menu.
+
        * src/xterm.c (handle_one_xevent, x_term_init, syms_of_xterm):
-       Implement features described above, so they work on free
+       Implement features illustrated above, so they work on free
        operating systems.
+
        * src/xterm.h (struct x_display_info): New fields `quit_keysym',
        `quit_keysym_time'.
 
 2023-01-26  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * INSTALL.android: Document how to install sqlite3.
+
        * build-aux/ndk-build-helper-1.mk (SYSTEM_LIBRARIES):
        * build-aux/ndk-build-helper-2.mk (SYSTEM_LIBRARIES): Add liblog
        and libandroid.
+
        * configure.ac (SQLITE3_LIBS, HAVE_SQLITE3)
        (HAVE_SQLITE3_LOAD_EXTENSION): Support on Android.
        (APKSIGNER): Look for this new required binary.
@@ -5843,38 +5128,43 @@
 
        * cross/ndk-build/ndk-build.mk.in (NDK_BUILD_SHARED): Fix
        definition.
-       * cross/ndk-build/ndk-resolve.mk:
-       (NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)): Handle new system
-       libraries.
+
+       * cross/ndk-build/ndk-resolve.mk
+       (NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)): Handle new system libraries.
 
        * doc/emacs/android.texi (Android File System): Document Android
        10 system restriction.
 
-       * java/AndroidManifest.xml.in: Target Android 33, not 28.
+       * java/AndroidManifest.xml.in: Target Android API 33, not 28.
+
        * java/Makefile.in (SIGN_EMACS_V2, APKSIGNER): New variables.
-       ($(APK_NAME)): Make sure to apply a ``version 2 signature'' to
-       the package as well.
+       ($(APK_NAME)): Make sure to apply a ``version 2 signature'' to the
+       package as well.
 
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
        argument apiLevel.
+
        * java/org/gnu/emacs/EmacsNoninteractive.java (main):
        * java/org/gnu/emacs/EmacsThread.java (run): Pass API level.
+
        * m4/ndk-build.m4 (ndk_package_mape): Add package mapping for
        sqlite3.
+
        * src/Makefile.in (SQLITE3_CFLAGS): New substition.
        (EMACS_CFLAGS): Add that variable.
 
        * src/android.c (android_api_level): New variable.
        (initEmacs): Set it.
        (android_file_access_p): Make static.
-       (android_hack_asset_fd): Adjust for restrictions in Android 29
-       and later.
+       (android_hack_asset_fd): Adjust for restrictions in Android 29 and
+       later.
        (android_close_on_exec): New function.
        (android_open): Adjust to not duplicate file descriptor even if
        CLOEXEC.
        (android_faccessat): Use fstatat at-func emulation.
 
        * src/android.h: Update prototypes.
+
        * src/dired.c (file_name_completion_dirp):
        * src/fileio.c (file_access_p, Faccess_file): Now that
        sys_faccessat takes care of everything, stop calling
@@ -5882,9 +5172,10 @@
 
 2023-01-26  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * .gitignore: Ignore lib/math.h.
+
        * INSTALL.android: Update accordingly.
+
        * build-aux/ndk-build-helper-1.mk:
        * build-aux/ndk-build-helper-2.mk:
        * build-aux/ndk-build-helper.mk:
@@ -5902,11 +5193,13 @@
        version for actual popup menus.
        * lib/math.h: Delete file.
 
-       * m4/ndk-build.m4 (ndk_SEARCH_MODULE, ndk_CHECK_MODULES): Look
-       for nasm and C++ libraries.
+       * m4/ndk-build.m4 (ndk_SEARCH_MODULE, ndk_CHECK_MODULES): Look for
+       nasm and C++ libraries.
 
        * src/android.c (faccessat): Rename to `android_faccessat'.
+
        * src/android.h: Update prototypes.
+
        * src/dired.c (file_name_completion_dirp):
        * src/fileio.c (file_access_p, Faccess_file, file_directory_p):
        * src/lisp.h:
@@ -5916,26 +5209,26 @@
 
 2023-01-26  Po Lu  <luangruo@yahoo.com>
 
-       Remove unused file
        * cross/ndk-build/ndk-build.in: Delete unused file.
 
 2023-01-25  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * java/org/gnu/emacs/EmacsDrawLine.java: Fix this again.  Gosh,
-       how does Android do this.
+       * java/org/gnu/emacs/EmacsDrawLine.java: Fix this again.
+
        * java/org/gnu/emacs/EmacsNoninteractive.java (main): Port to
        Android 2.3.3.
 
-       * java/org/gnu/emacs/EmacsSdk11Clipboard.java
-       (EmacsSdk11Clipboard): Port to Android 4.0.3.
-       * java/org/gnu/emacs/EmacsService.java (getClipboardManager):
-       New function.
+       * java/org/gnu/emacs/EmacsSdk11Clipboard.java: Port to Android
+       4.0.3.
+
+       * java/org/gnu/emacs/EmacsService.java (getClipboardManager): New
+       function.
 
        * src/alloc.c (find_string_data_in_pure): Fix Android alignment
        issue.
 
        * src/android-emacs.c (main): Port to Android 4.4.
+
        * src/android.c (initEmacs): Align stack to 32 bytes, so it ends
        up aligned to 16 even though gcc thinks the stack is already
        aligned to 16 bytes.
@@ -5943,23 +5236,15 @@
        * src/callproc.c (init_callproc): Use /system/bin/sh instead of
        /bin/sh by default.
 
-2023-01-25  Po Lu  <luangruo@yahoo.com>
-
-       Remove extra header
        * cross/lib/math.h: Delete header.
 
-       Minor fixes to Android port
-       * java/Makefile.in: (emacs.apk-in): Don't call cp with empty
-       args.
+       * java/Makefile.in (emacs.apk-in): Don't call cp with empty args.
+
        * java/org/gnu/emacs/EmacsDrawLine.java (perform): Fix for
        PostScript filling semantics.
-       * src/Makefile.in (android-emacs): Build android-emacs directly.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-01-25  Po Lu  <luangruo@yahoo.com>
+       * src/Makefile.in (android-emacs): Build android-emacs directly.
 
-       Update Android port
        * doc/emacs/android.texi (Android Startup, Android Environment):
        Document that restrictions on starting Emacs have been lifted.
 
@@ -5972,48 +5257,57 @@
 
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Update
        function declarations.
-       * java/org/gnu/emacs/EmacsNoninteractive.java
-       (EmacsNoninteractive): New class.
 
-       * java/org/gnu/emacs/EmacsService.java (EmacsService, getApkFile)
+       * java/org/gnu/emacs/EmacsNoninteractive.java: New class.
+
+       * java/org/gnu/emacs/EmacsService.java (getApkFile)
        (onCreate): Pass classpath to setEmacsParams.
-       * java/org/gnu/emacs/EmacsThread.java (EmacsThread): Make run an
-       override.
+
+       * java/org/gnu/emacs/EmacsThread.java (run): Label as an
+       @Override.
+
        * lisp/loadup.el: Don't dump on Android when noninteractive.
+
        * lisp/shell.el (shell--command-completion-data): Handle
        inaccessible directories.
-       * src/Makefile.in (android-emacs): Link with gnulib.
-       * src/android-emacs.c (main): Implement to launch app-process
-       and then EmacsNoninteractive.
+
+       * src/Makefile.in (android-emacs): Link with Gnulib.
+
+       * src/android-emacs.c (main): Implement to launch app-process and
+       then EmacsNoninteractive.
+
        * src/android.c (setEmacsParams): New argument `class_path'.
        Don't set stuff up when running noninteractive.
+
        * src/android.h (initEmacs): Likewise.
+
        * src/androidfont.c (init_androidfont):
-       * src/androidselect.c (init_androidselect): Don't initialize
-       when running noninteractive.
+       * src/androidselect.c (init_androidselect): Don't initialize when
+       running noninteractive.
+
        * src/emacs.c (load_pdump): New argument `dump_file'.
        (android_emacs_init): Give new argument `dump_file' to
        `load_pdump'.
-       * src/sfntfont-android.c (init_sfntfont_android): Don't
-       initialize when running noninteractive.
-
-2023-01-25  Po Lu  <luangruo@yahoo.com>
 
-       Import gnulib modules printf-posix and vasprintf-posix
-       These are neccessary because Android's printf is missing basic format
-       modifiers such as t.
+       * src/sfntfont-android.c (init_sfntfont_android): Don't initialize
+       when running noninteractive.
 
        * admin/merge-gnulib (GNULIB_MODULES): Add printf-posix and
-       vasprintf-posix.  Update from gnulib.
+       vasprintf-posix.
+
+       * m4, lib: Update from Gnulib.
+
        * configure.ac (CFLAGS): Add -DHAVE_CONFIG_H.
 
 2023-01-24  Po Lu  <luangruo@yahoo.com>
 
-       Make binaries distributed with Emacs work on Android
        * doc/lispref/processes.texi (Subprocess Creation): Document
        variables containing program names.
+
        * etc/NEWS: Document new variables.
+
        * java/Makefile.in (CROSS_BINS): Add missing etags binary.
+
        * lisp/cedet/semantic/db-ebrowse.el
        (semanticdb-create-ebrowse-database):
        * lisp/gnus/mail-source.el (mail-source-movemail-program):
@@ -6027,24 +5321,26 @@
        * lisp/speedbar.el (speedbar-fetch-etags-command):
        * lisp/textmodes/reftex-global.el (reftex-create-tags-file): Use
        new variables.
-       * src/callproc.c (syms_of_callproc): New variables naming
-       binaries redistributed with Emacs.
 
-2023-01-24  Po Lu  <luangruo@yahoo.com>
+       * src/callproc.c (syms_of_callproc): Introduce new variables
+       naming binaries redistributed with Emacs.
 
-       Enable libjpeg on Android
        * INSTALL.android: Update documentation.
+
        * build-aux/ndk-build-helper-1.mk: When building shared
        libraries, do not link libemacs.so with dependent archive files.
-       * build-aux/ndk-build-helper-2.mk: Add whole archive
-       dependencies as well.
+
+       * build-aux/ndk-build-helper-2.mk: Add whole archive dependencies
+       as well.
 
        * configure.ac (HAVE_JPEG): Enable on Android.
 
        * cross/ndk-build/ndk-build-shared-library.mk: Link the shared
        object with archive file dependencies.
+
        * cross/ndk-build/ndk-build-static-library.mk: Build all code
        position-independently.
+
        * cross/ndk-build/ndk-resolve.mk: Separately resolve a names of
        archive and whole archive dependencies.
 
@@ -6053,10 +5349,12 @@
 
 2023-01-24  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * INSTALL.android: Update.
+
        * build-aux/ndk-build-helper-1.mk: Fix typo.
+
        * configure.ac: Enable --with-json on Android.
+
        * cross/ndk-build/ndk-build-shared-library.mk:
        (NDK_CFLAGS_$(LOCAL_MODULE)):
        (LOCAL_MODULE_FILENAME):
@@ -6065,29 +5363,36 @@
        (LOCAL_MODULE_FILENAME): Recursively resolve dependencies.
        * cross/ndk-build/ndk-resolve.mk: New function.
 
-       * doc/emacs/android.texi (Android Startup): Document how Emacs
-       is dumped during initial startup.
+       * doc/emacs/android.texi (Android Startup): Document how Emacs is
+       dumped during initial startup.
 
        * java/Makefile.in (filename): Fix build with multiple shared
        libraries.
+
        * java/README: Improve commentary.
+
        * java/org/gnu/emacs/EmacsApplication.java (onCreate): Look and
        set dump file.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
+
+       * java/org/gnu/emacs/EmacsNative.java (getFingerprint): New
        function getFingerprint.
+
        * java/org/gnu/emacs/EmacsPreferencesActivity.java (onCreate):
        Add option to erase the dump file.
-       * java/org/gnu/emacs/EmacsService.java (browseUrl): New
-       function.
-       * java/org/gnu/emacs/EmacsThread.java (run): Specify dump file
-       if found.
+
+       * java/org/gnu/emacs/EmacsService.java (browseUrl): New function.
+
+       * java/org/gnu/emacs/EmacsThread.java (run): Specify dump file if
+       found.
+
        * lisp/loadup.el: Always dump during loadup on Android.
 
-       * lisp/net/browse-url.el (browse-url--browser-defcustom-type):
-       (browse-url-default-browser):
-       (browse-url-default-android-browser): New browse url type.
+       * lisp/net/browse-url.el (browse-url--browser-defcustom-type)
+       (browse-url-default-browser, browse-url-default-android-browser):
+       New browse url type.
 
        * m4/ndk-build.m4 (ndk_package_map): Map jansson to libjansson.
+
        * src/android.c (struct android_emacs_service): New method
        `browse_url'.
        (getFingerprint): New function.
@@ -6099,37 +5404,29 @@
        * src/androidselect.c (Fandroid_browse_url): New function.
        (syms_of_androidselect): Define it.
 
-       * src/emacs.c (load_pdump): Don't look in fancy places on
-       Android.
+       * src/emacs.c (load_pdump): Eschew excessively elaborate dump file
+       location code on on Android.
+
        * src/pdumper.c (Fdump_emacs_portable): Allow dumping while
        interactive on Android.
        (syms_of_pdumper): New variable `pdumper-fingerprint'.
 
-       * src/sfntfont-android.c (sfntfont_android_composite_bitmap):
-       Fix unused variables.
+       * src/sfntfont-android.c (sfntfont_android_composite_bitmap): Fix
+       unused variables.
 
 2023-01-24  Po Lu  <luangruo@yahoo.com>
 
-       Update from gnulib
-       Update from gnulib.  In addition,
-
        * admin/merge-gnulib: Fix paths for rename.
 
-2023-01-24  Po Lu  <luangruo@yahoo.com>
-
-       Improve lib-src/Makefile.in
-       * lib-src/Makefile.in (DONT_INSTALL):
-       (clean): Correctly define asset-directory-tool.
+       * lib-src/Makefile.in (DONT_INSTALL, clean): Correctly define
+       asset-directory-tool.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Fix distclean target
        * cross/Makefile.in (distclean bootstrap-clean): Remove Makefile.
 
 2023-01-24  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * .gitignore: Update with new files.  Do not ignore std*.in.h.
+
        * INSTALL.android: Explain how to build Emacs with external
        dependencies.
 
@@ -6138,49 +5435,55 @@
 
        * README: Document new directories.
 
-       * build-aux/ndk-build-helper-1.mk (build_kind, NDK_SO_NAMES):
-       * build-aux/ndk-build-helper-2.mk (build_kind, NDK_SO_NAMES):
-       * build-aux/ndk-build-helper-3.mk (build_kind):
+       * build-aux/ndk-build-helper-1.mk:
+       * build-aux/ndk-build-helper-2.mk:
+       * build-aux/ndk-build-helper-3.mk:
        * build-aux/ndk-build-helper-4.mk:
        * build-aux/ndk-build-helper.mk (NDK_BUILD_DIR, my-dir):
        * build-aux/ndk-module-extract.awk: New files.
-       * configure.ac: Set up libgif, libwebp, and libpng for
-       ndk-build.
-       * cross/ndk-build/Makefile.in (srcdir, NDK_BUILD_ANDROID_MK):
+       * configure.ac: Set up libgif, libwebp, and libpng for ndk-build.
+
+       * cross/ndk-build/Makefile.in:
        * cross/ndk-build/ndk-build-executable.mk:
-       * cross/ndk-build/ndk-build-shared-library.mk (eq, objname):
-       * cross/ndk-build/ndk-build-static-library.mk (eq, objname):
-       * cross/ndk-build/ndk-build.in (NDK_BUILD_MODULES):
-       * cross/ndk-build/ndk-build.mk.in (NDK_BUILD_MODULES)
-       (NDK_BUILD_SHARED):
+       * cross/ndk-build/ndk-build-shared-library.mk:
+       * cross/ndk-build/ndk-build-static-library.mk:
+       * cross/ndk-build/ndk-build.in:
+       * cross/ndk-build/ndk-build.mk.in:
        * cross/ndk-build/ndk-clear-vars.mk:
        * cross/ndk-build/ndk-prebuilt-shared-library.mk:
        * cross/ndk-build/ndk-prebuilt-static-library.mk: New files.
-       * doc/emacs/android.texi (Android, Android Environment):
-       Document clipboard support on Android.
+
+       * doc/emacs/android.texi (Android, Android Environment): Document
+       clipboard support on Android.
+
        * doc/emacs/emacs.texi (Top): Update menus.
+
        * etc/MACHINES: Document Android.
-       * java/AndroidManifest.xml.in: Respect new
-       `--with-android-debug' option.
+
+       * java/AndroidManifest.xml.in: Respect new `--with-android-debug'
+       option.
+
        * java/Makefile.in (CROSS_BINS, CROSS_LIBS): Adjust for rename.
-       Include ndk-build.mk.:(emacs.apk-in): Depend on shared
-       libraries.  Then, package shared libraries.
-       * java/org/gnu/emacs/EmacsClipboard.java (EmacsClipboard): New
-       class.
+       Include ndk-build.mk.
+       (emacs.apk-in): Depend on shared libraries.  Then, package shared
+       libraries.
+
+       * java/org/gnu/emacs/EmacsClipboard.java: New file.
+
        * java/org/gnu/emacs/EmacsFontDriver.java: Update comment to say
        this is unused.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       function `sendExpose'.
-       * java/org/gnu/emacs/EmacsSdk11Clipboard.java
-       (EmacsSdk11Clipboard):
-       * java/org/gnu/emacs/EmacsSdk8Clipboard.java
-       (EmacsSdk8Clipboard): New classes.
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, handleDirtyBitmap)
+
+       * java/org/gnu/emacs/EmacsNative.java (sendExpose): New function
+       `sendExpose'.
+
+       * java/org/gnu/emacs/EmacsSdk11Clipboard.java:
+       * java/org/gnu/emacs/EmacsSdk8Clipboard.java: New files.
+
+       * java/org/gnu/emacs/EmacsView.java (handleDirtyBitmap)
        (onDetachedFromWindow): When window is reattached, expose the
        frame.
 
-       * lib/Makefile.in (VPATH):
-       (ALL_CFLAGS): Adjust for rename.
+       * lib/Makefile.in (VPATH, ALL_CFLAGS): Adjust for rename.
 
        * lisp/term/android-win.el (android-clipboard-exists-p)
        (android-get-clipboard, android-set-clipboard)
@@ -6192,11 +5495,10 @@
        functions.
 
        * m4/ndk-build.m4: New file.
+
        * src/Makefile.in (GIF_CFLAGS, ANDROID_LDFLAGS): New variables.
-       (EMACS_CFLAGS): Add GIF_CFLAGS.  Include
-       ndk-build.mk.
-       (libemacs.so): Depend on and link with required
-       libraries.
+       (EMACS_CFLAGS): Add GIF_CFLAGS.  Include ndk-build.mk.
+       (libemacs.so): Depend on and link with required libraries.
 
        * src/android.c (android_check_compressed_file): New function.
        (android_open): Work around Android platform bug.
@@ -6207,32 +5509,23 @@
        (struct android_expose_event, union android_event): Add expose
        events.
 
-       * src/androidselect.c (struct android_emacs_clipboard)
-       (android_init_emacs_clipboard, Fandroid_clipboard_owner_p)
-       (Fandroid_set_clipboard, Fandroid_get_clipboard)
-       (Fandroid_clipboard_exists_p, init_androidselect)
-       (syms_of_androidselect): New file.
+       * src/androidselect.c: New file.
 
-       * src/androidterm.c (handle_one_android_event): Handle
-       exposures.
-       * src/androidterm.h: Update prototypes.
-       * src/emacs.c (android_emacs_init): Initialize androidselect.
+       * src/androidterm.c (handle_one_android_event) <ANDROID_EXPOSE>:
+       Handle exposures.
 
-2023-01-24  Po Lu  <luangruo@yahoo.com>
+       * src/androidterm.h: Update prototypes.
 
-       Update android port
-       * xcompile: Move to cross.
-       * cross: New directory.
+       * src/emacs.c (android_emacs_init): Initialize androidselect.
 
-       Update android port
        * xcompile: Move to cross.
        * cross: New directory.
 
 2023-01-21  Po Lu  <luangruo@yahoo.com>
 
-       Improve touch-screen support
        * doc/lispref/commands.texi (Touchscreen Events): Document
        changes.
+
        * lisp/touch-screen.el (touch-screen-current-tool): Update doc
        string.
        (touch-screen-precision-scroll): New user option.
@@ -6248,18 +5541,19 @@
 
        * src/fileio.c (Fverify_visited_file_modtime): Fix fs check.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-01-21  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * doc/emacs/android.texi (Android File System): Document that
        ls-lisp is now used by default.
+
        * java/org/gnu/emacs/EmacsThread.java (EmacsThread): Name the
        thread something meaningful.
+
        * lisp/loadup.el (featurep): Load ls-lisp on Android.
-       * lisp/ls-lisp.el (ls-lisp-use-insert-directory-program):
-       Default to off on Android.
+
+       * lisp/ls-lisp.el (ls-lisp-use-insert-directory-program): Default
+       to off on Android.
+
        * src/android.c (android_is_directory): New fucntion.
        (android_fstatat): Handle directories created by
        `android_opendir'.
@@ -6271,6 +5565,7 @@
        (android_lookup_asset_directory_fd): New function.
 
        * src/android.h: Update prototypes.
+
        * src/androidfont.c (androidfont_check_init): New function.
        (androidfont_list, androidfont_match, androidfont_draw)
        (androidfont_open_font, androidfont_close_font)
@@ -6294,75 +5589,81 @@
        * src/sfntfont-android.c (GET_SCANLINE_BUFFER)
        (sfntfont_android_u255to256, sfntfont_android_over_8888_1)
        (sfntfont_android_over_8888, sfntfont_android_composite_bitmap):
-       Optimize on 64-bit ARM devices.
-       (sfntfont_android_put_glyphs): Optimize away memset if
-       background need not be filled.
+       Optimize for 64-bit ARM devices.
+       (sfntfont_android_put_glyphs): Optimize away memset if background
+       need not be filled.
 
 2023-01-20  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Update Android port
        * src/android.c (android_run_select_thread, android_select)
        (android_ftruncate):
-       * src/android.h (ftruncate): Fix compilation on Android 16 and
-       up.
+       * src/android.h (ftruncate): Fix compilation on Android 16 and up.
 
-       Update Android port
        * src/android.c (android_run_select_thread, android_init_events)
        (android_select): Add alternative android_select implementation
        for API 16 and lower.
+
        * src/androidterm.c (handle_one_android_event): Fix
        use-after-frees.
 
-       Remove unused file
        * xcompile/lib/gnulib.mk.in: Delete.
 
 2023-01-20  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
        * .gitignore: Don't ignore verbose.mk.android.
+
        * doc/emacs/Makefile.in (EMACSSOURCES): Add android.texi and
        input.texi.
+
        * doc/emacs/android.texi (Android): Document support for the
        on-screen keyboard.
-       (Android Startup): Document how to start Emacs with -Q on
-       Android.
-       (Android Environment): Document how Emacs works around the
-       system ``task killer''.  Document changes to frame deletion
-       behavior.
+       (Android Startup): Document how to start Emacs with -Q on Android.
+       (Android Environment): Document how Emacs circumvents the system
+       ``task killer''.  Document changes to frame deletion behavior.
+
        * doc/emacs/emacs.texi (Top):
-       * doc/emacs/input.texi (Other Input Devices, On-Screen
-       Keyboards): Document how to use Emacs with virtual keyboards.
-       * doc/lispref/commands.texi (Touchscreen Events): Document
-       changes to `touch-screen-track-drag'.
-       * doc/lispref/frames.texi (Frames, On-Screen Keyboards): New
-       node.
+       * doc/emacs/input.texi (Other Input Devices)
+       (On-Screen Keyboards): Document how to use Emacs with virtual
+       keyboards.
+
+       * doc/lispref/commands.texi (Touchscreen Events): Document changes
+       to `touch-screen-track-drag'.
+
+       * doc/lispref/frames.texi (Frames, On-Screen Keyboards): New node.
+
        * java/AndroidManifest.xml.in: Add settings activity and
        appropriate OSK adjustment mode.
-       * java/org/gnu/emacs/EmacsActivity.java (onCreate): Allow
-       creating Emacs with -Q.
+
+       * java/org/gnu/emacs/EmacsActivity.java (onCreate): Allow creating
+       Emacs with -Q.
        (onDestroy): Don't remove if killed by the system.
-       * java/org/gnu/emacs/EmacsContextMenu.java (inflateMenuItems):
-       Fix context menus again.
+
+       * java/org/gnu/emacs/EmacsContextMenu.java (inflateMenuItems): Fix
+       context menus again.
+
        * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Make all
        event sending functions return long.
-       * java/org/gnu/emacs/EmacsPreferencesActivity.java
-       (EmacsPreferencesActivity): New class.
+
+       * java/org/gnu/emacs/EmacsPreferencesActivity.java: New fle.
+
        * java/org/gnu/emacs/EmacsService.java (EmacsService)
        (onStartCommand, onCreate, startEmacsService): Start as a
        foreground service if necessary to bypass system restrictions.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
-       * java/org/gnu/emacs/EmacsThread.java (EmacsThread, run):
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, onLayout)
+       * java/org/gnu/emacs/EmacsThread.java (run):
+       * java/org/gnu/emacs/EmacsView.java (onLayout)
        (onDetachedFromWindow):
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, viewLayout):
-       Implement frame resize synchronization..
+       * java/org/gnu/emacs/EmacsWindow.java (viewLayout):
+       Implement frame resize synchronization.
+
        * java/org/gnu/emacs/EmacsWindowAttachmentManager.java
-       (EmacsWindowAttachmentManager, removeWindowConsumer): Adjust
-       accordingly for changes to frame deletion behavior.
+       (removeWindowConsumer): Adjust accordingly for changes to frame
+       deletion behavior.
+
        * lisp/frame.el (android-toggle-on-screen-keyboard)
-       (frame-toggle-on-screen-keyboard): New function.
+       (frame-toggle-on-screen-keyboard): New functions.
+
        * lisp/minibuffer.el (minibuffer-setup-on-screen-keyboard)
        (minibuffer-exit-on-screen-keyboard): New functions.
        (minibuffer-setup-hook, minibuffer-exit-hook): Add new functions
@@ -6376,13 +5677,16 @@
        (touch-screen-drag-mode-line-1, touch-screen-drag-mode-line):
        Refactor to use `no-drag'.
 
-       * src/android.c (struct android_emacs_window): New methods.
-       Make all event sending functions return the event serial.
+       * src/android.c (struct android_emacs_window): New methods.  Make
+       all event sending functions return the event serial.
        (android_toggle_on_screen_keyboard, android_window_updated): New
        functions.
+
        * src/android.h: Update prototypes.
+
        * src/androidfns.c (Fandroid_toggle_on_screen_keyboard)
-       (syms_of_androidfns): New function.
+       (syms_of_androidfns): New functions.
+
        * src/androidgui.h (struct android_any_event)
        (struct android_key_event, struct android_configure_event)
        (struct android_focus_event, struct android_window_action_event)
@@ -6393,27 +5697,24 @@
 
        * src/androidterm.c (handle_one_android_event)
        (android_frame_up_to_date):
+
        * src/androidterm.h (struct android_output): Implement frame
        resize synchronization.
 
-2023-01-20  Po Lu  <luangruo@yahoo.com>
-
-       Check in missing file
        * xcompile/verbose.mk.android: New file.
 
 2023-01-19  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * .gitignore: Add new files.
 
-2023-01-19  Po Lu  <luangruo@yahoo.com>
+       * INSTALL.android: Explain how to build Emacs for ancient versions
+       of Android.
 
-       Update Android port
-       * .gitignore: Add new files.
-       * INSTALL.android: Explain how to build Emacs for ancient
-       versions of Android.
        * admin/merge-gnulib (GNULIB_MODULES): Add getdelim.
+
        * build-aux/config.guess (timestamp, version):
        * build-aux/config.sub (timestamp, version): Autoupdate.
+
        * configure.ac (BUILD_DETAILS, ANDROID_MIN_SDK):
        (ANDROID_STUBIFY): Allow specifying CFLAGS via ANDROID_CFLAGS.
        Add new configure tests for Android API version when not
@@ -6423,14 +5724,21 @@
        Input Devices''.
        (Android File System): Remove restrictions on directory-files on
        the assets directory.
+
        * doc/emacs/emacs.texi (Top): Add Other Input Devices to menu.
+
        * doc/emacs/input.texi (Other Input Devices): New node.
+
        * doc/lispref/commands.texi (Touchscreen Events): Document
        changes to touchscreen input events.
+
        * doc/lispref/frames.texi (Pop-Up Menus): Likewise.
+
        * etc/NEWS: Announce changes.
+
        * java/Makefile.in: Use lib-src/asset-directory-tool to generate
        an `directory-tree' file placed in /assets.
+
        * java/debug.sh: Large adjustments to support Android 2.2 and
        later.
 
@@ -6442,11 +5750,11 @@
        * java/org/gnu/emacs/EmacsDrawable.java (EmacsDrawable):
        * java/org/gnu/emacs/EmacsFillPolygon.java (perform):
        * java/org/gnu/emacs/EmacsFillRectangle.java (perform):
-       * java/org/gnu/emacs/EmacsGC.java (EmacsGC):
-       * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap):
-       (destroyHandle):
+       * java/org/gnu/emacs/EmacsGC.java:
+       * java/org/gnu/emacs/EmacsPixmap.java (destroyHandle):
        * java/org/gnu/emacs/EmacsSdk7FontDriver.java (draw): Avoid
        redundant canvas saves and restores.
+
        * java/org/gnu/emacs/EmacsService.java (run):
        * java/org/gnu/emacs/EmacsView.java (EmacsView):
        (handleDirtyBitmap):
@@ -6454,33 +5762,32 @@
        (EmacsWindow): Make compatible with Android 2.2 and later.
 
        * lib-src/Makefile.in (DONT_INSTALL): Add asset-directory-tool
-       on Android.:(asset-directory-tool{EXEEXT}): New target.
+       on Android.
+       (asset-directory-tool${EXEEXT}): New target.
+
        * lib-src/asset-directory-tool.c (struct directory_tree, xmalloc)
        (main_1, main_2, main): New file.
 
        * lib, m4: Merge from gnulib.  This will be reverted before
        merging to master.
 
-       * lisp/button.el (button-map):
-       (push-button):
+       * lisp/button.el (button-map, push-button):
        * lisp/frame.el (display-popup-menus-p): Improve touchscreen
        support.
-       * lisp/subr.el (event-start):
-       (event-end): Handle touchscreen events.
-       * lisp/touch-screen.el (touch-screen-handle-timeout):
-       (touch-screen-handle-point-update):
-       (touch-screen-handle-point-up):
-       (touch-screen-track-tap):
-       (touch-screen-track-drag):
-       (touch-screen-drag-mode-line-1):
-       (touch-screen-drag-mode-line): New functions.
-       ([mode-line touchscreen-begin]):
+
+       * lisp/subr.el (event-start, event-end): Handle touchscreen
+       events.
+
+       * lisp/touch-screen.el (touch-screen-handle-timeout)
+       (touch-screen-handle-point-update, touch-screen-handle-point-up)
+       (touch-screen-track-tap, touch-screen-track-drag)
+       (touch-screen-drag-mode-line-1, touch-screen-drag-mode-line): New
+       function
+       ([mode-line touchscreen-begin])
        ([bottom-divider touchscreen-begin]): Bind new events.
 
-       * lisp/wid-edit.el (widget-event-point):
-       (widget-keymap):
-       (widget-event-start):
-       (widget-button--check-and-call-button):
+       * lisp/wid-edit.el (widget-event-point, widget-keymap)
+       (widget-event-start, widget-button--check-and-call-button)
        (widget-button-click): Improve touchscreen support.
 
        * src/alloc.c (make_lisp_symbol): Avoid ICE on Android NDK GCC.
@@ -6502,18 +5809,25 @@
        (android_opendir, android_readdir, android_closedir): Likewise.
        (android_four_corners_bilinear): Fix coding style.
        (android_ftruncate): New function.
+
        * src/android.h: Update prototypes.  Replace ftruncate with
        android_ftruncate when necessary.
 
        * src/androidterm.c (handle_one_android_event): Pacify GCC.  Fix
        touch screen tool bar bug.
+
        * src/emacs.c (using_utf8): Fix compilation error.
+
        * src/fileio.c (Ffile_system_info): Return Qnil when fsusage.o
        is not built.
+
        * src/filelock.c (BOOT_TIME_FILE): Fix definition for Android.
+
        * src/frame.c (Fx_parse_geometry): Fix uninitialized variable
        uses.
+
        * src/keyboard.c (lispy_function_keys): Fix `back'.
+
        * src/menu.c (x_popup_menu_1): Handle touch screen events.
        (Fx_popup_menu): Document changes.
 
@@ -6523,8 +5837,9 @@
        minor problem.
        (init_sfntfont_android): Check for
        HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL.
-       * src/sfntfont.c (struct sfnt_font_desc): New fields `adstyle'
-       and `languages'.
+
+       * src/sfntfont.c (struct sfnt_font_desc): New fields `adstyle' and
+       `languages'.
        (sfnt_parse_style): Append tokens to adstyle.
        (sfnt_parse_languages): New function.
        (sfnt_enum_font_1): Parse supported languages and adstyle.
@@ -6534,28 +5849,31 @@
 
 2023-01-17  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-01-17  Po Lu  <luangruo@yahoo.com>
+       * doc/emacs/android.texi (Android Fonts): Document that TTC format
+       fonts are now supported.
 
-       Update Android port
-       * doc/emacs/android.texi (Android Fonts): Document that TTC
-       format fonts are now supported.
        * doc/emacs/emacs.texi (Top): Fix menus.
+
        * doc/lispref/commands.texi (Touchscreen Events)
        (Key Sequence Input): Document changes to touchscreen events.
+
        * etc/DEBUG: Describe how to debug 64 bit binaries on Android.
 
        * java/org/gnu/emacs/EmacsCopyArea.java (perform): Explicitly
        recycle copy bitmap.
+
        * java/org/gnu/emacs/EmacsDialog.java (EmacsDialog): New class.
+
        * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Use 5
-       point PolyLine like X, because Android behaves like Postscript
-       on some devices and X elsewhere.
-       * java/org/gnu/emacs/EmacsFillRectangle.java (perform):
-       Explicitly recycle copy bitmap.
-       * java/org/gnu/emacs/EmacsPixmap.java (destroyHandle):
-       Explicitly recycle bitmap and GC if it is big.
+       point PolyLine like X, because Android behaves like Postscript on
+       some devices and X elsewhere.
+
+       * java/org/gnu/emacs/EmacsFillRectangle.java (perform): Explicitly
+       recycle copy bitmap.
+
+       * java/org/gnu/emacs/EmacsPixmap.java (destroyHandle): Explicitly
+       recycle bitmap and GC if it is big.
+
        * java/org/gnu/emacs/EmacsView.java (EmacsView): Make
        `bitmapDirty' a boolean.
        (handleDirtyBitmap): Reimplement in terms of that boolean.
@@ -6569,11 +5887,13 @@
        * src/android.c (android_run_select_thread, android_select):
        Really fix android_select.
        (android_build_jstring): New function.
+
        * src/android.h: Update prototypes.
+
        * src/androidmenu.c (android_process_events_for_menu): Totally
        unblock input before process_pending_signals.
-       (android_menu_show): Remove redundant unblock_input and
-       debugging code.
+       (android_menu_show): Remove redundant unblock_input and debugging
+       code.
        (struct android_emacs_dialog, android_init_emacs_dialog)
        (android_dialog_show, android_popup_dialog, init_androidmenu):
        Implement popup dialogs on Android.
@@ -6583,70 +5903,75 @@
        tapping tool bar items.
        (android_create_terminal): Add dialog hook.
        (android_wait_for_event): Adjust call to android_select.
+
        * src/androidterm.h (struct android_touch_point): New field
        `tool_bar_p'.
+
        * src/keyboard.c (read_key_sequence, head_table)
        (syms_of_keyboard): Prefix touchscreen events with posn.
+
        * src/keyboard.h (EVENT_HEAD): Handle touchscreen events.
+
        * src/process.c (wait_reading_process_output): Adjust call to
        android_select.
-       * src/sfnt.c (sfnt_read_table_directory): If the first long
-       turns out to be ttcf, return -1.
+
+       * src/sfnt.c (sfnt_read_table_directory): If the first long turns
+       out to be ttcf, return -1.
        (sfnt_read_ttc_header): New function.
        (main): Test TTC support.
 
        * src/sfnt.h (struct sfnt_ttc_header): New structure.
        (enum sfnt_ttc_tag): New enum.
 
-       * src/sfntfont-android.c (struct
-       sfntfont_android_scanline_buffer): New structure.
+       * src/sfntfont-android.c
+       (struct sfntfont_android_scanline_buffer): New structure.
        (GET_SCANLINE_BUFFER): New macro.  Try to avoid so much malloc
        upon accessing the scanline buffer.
-       (sfntfont_android_put_glyphs): Do not use SAFE_ALLOCA to
-       allocate the scaline buffer.
+       (sfntfont_android_put_glyphs): Do not use SAFE_ALLOCA to allocate
+       the scaline buffer.
        (Fandroid_enumerate_fonts): Enumerate ttc fonts too.
 
        * src/sfntfont.c (struct sfnt_font_desc): New field `offset'.
        (sfnt_enum_font_1): Split out enumeration code from
        sfnt_enum_font.
-       (sfnt_enum_font): Read TTC tables and enumerate each font
-       therein.
+       (sfnt_enum_font): Read TTC tables and enumerate each font therein.
        (sfntfont_open): Seek to the offset specified.
 
        * xcompile/Makefile.in (maintainer-clean): Fix depends here.
 
 2023-01-16  Po Lu  <luangruo@yahoo.com>
 
-       Fix display of glyphs with word-sized component offsets on Android
-       * src/sfnt.c (sfnt_decompose_compound_glyph): Handle correctly
+       * src/sfnt.c (sfnt_decompose_compound_glyph): Correct treatment of
        the Y offset in components with ARG_1_AND_2_ARE_WORDS.
        (main): Update debugging code.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-01-16  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * doc/emacs/android.texi (Android, Android Environment): Improve
        documentation.
-       * doc/lispref/commands.texi (Touchscreen Events): Document
-       changes to touchscreen support.
+
+       * doc/lispref/commands.texi (Touchscreen Events): Document changes
+       to touchscreen support.
+
        * doc/lispref/display.texi (Defining Faces, Window Systems):
-       * doc/lispref/frames.texi (Frame Layout, Font and Color
-       Parameters):
+       * doc/lispref/frames.texi (Frame Layout)
+       (Font and Color Parameters):
        * doc/lispref/os.texi (System Environment): Document Android in
        various places.
 
        * java/org/gnu/emacs/EmacsWindow.java (figureChange): Fix crash.
-       * lisp/loadup.el: ("touch-screen"): Load touch-screen.el.
+
+       * lisp/loadup.el ("touch-screen"): Load touch-screen.el.
+
        * lisp/pixel-scroll.el: Autoload two functions.
+
        * lisp/term/android-win.el: Add require 'touch-screen.
+
        * lisp/touch-screen.el (touch-screen-current-tool)
        (touch-screen-current-timer, touch-screen-delay)
        (touch-screen-relative-xy, touch-screen-handle-scroll)
        (touch-screen-handle-timeout, touch-screen-handle-point-update)
        (touch-screen-handle-point-up, touch-screen-handle-touch)
        (global-map, touch-screen): New file.
+
        * src/android.c (android_run_debug_thread): Fix build on 64 bit
        systems.
        (JNICALL, android_put_pixel): Likewise.
@@ -6654,12 +5979,16 @@
        (android_fetch_pixel_bilinear, android_project_image_bilinear)
        (android_fetch_pixel_nearest_24, android_fetch_pixel_nearest_1)
        (android_project_image_nearest): New functions.
+
        * src/androidgui.h (struct android_transform): New structure.
-       * src/androidterm.c (android_note_mouse_movement): Remove
-       obsolete TODO.
+
+       * src/androidterm.c (android_note_mouse_movement): Remove obsolete
+       TODO.
        (android_get_scale_factor): New function.
        (android_draw_underwave): Scale underwave correctly.
+
        * src/dispextern.h: Support native image transforms on Android.
+
        * src/image.c (matrix_identity, matrix_rotate)
        (matrix_mirror_horizontal, matrix_translate): New functions.
        (image_set_transform): Implement native image transforms on
@@ -6667,64 +5996,77 @@
        (Fimage_transforms_p): Implement on Android.
 
        * src/keyboard.c (make_lispy_event, syms_of_keyboard): Handle
-       touch screen- menu bar events.
+       touch screen menu bar events.
+
        * src/sfnt.c: Fix typo in comment.
+
        * src/sfntfont-android.c (sfntfont_android_blend, U255TO256)
-       (sfntfont_android_put_glyphs): Avoid redundant swizzling.
+       (sfntfont_android_put_glyphs): Prevent redundant swizzling.
+
        * src/sfntfont.c (sfntfont_lookup_char): Fix build on 64 bit
        systems.
 
 2023-01-15  Po Lu  <luangruo@yahoo.com>
 
-       Implement submenus on Android
        * java/org/gnu/emacs/EmacsActivity.java (onCreate): Set the
        default theme to Theme.DeviceDefault.NoActionBar if possible.
        (onContextMenuClosed): Add hack for Android bug.
+
        * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu)
        (onMenuItemClick): Set flag upon submenu selection.
        (inflateMenuItems): Set onClickListener for submenus as well.
        (display1): Clear new flag.
+
        * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Fix
        rectangle bounds.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative):
+
+       * java/org/gnu/emacs/EmacsNative.java (setEmacsParams): New
+       argument for the cache directory.
+
        * java/org/gnu/emacs/EmacsService.java (onCreate): Pass cache
        directory.
        (sync): New function.
-       * src/android.c (struct android_emacs_service): New method
-       `sync'.
+
+       * src/android.c (struct android_emacs_service): New method `sync'.
        (setEmacsParams, initEmacs): Handle cache directory.
        (android_init_emacs_service): Initialize new method `sync'.
        (android_sync): New function.
+
        * src/androidfns.c (Fx_show_tip): Call both functions.
+
        * src/androidgui.h: Update prototypes.
+
        * src/androidmenu.c (struct android_menu_subprefix)
        (android_free_subprefixes, android_menu_show): Handle submenu
        prefixes correctly.
+
        * src/androidterm.c (handle_one_android_event): Clear help echo
        on MotionNotify like on X.
-       * src/menu.c (single_menu_item): Enable submenus on Android.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
+       * src/menu.c (single_menu_item): Enable submenus on Android.
 
 2023-01-15  Po Lu  <luangruo@yahoo.com>
 
-       Implement toolkit menus on Android
        * java/org/gnu/emacs/EmacsActivity.java (onContextMenuClosed):
        New function.
-       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
-       New field `itemAlreadySelected'.
+
+       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu): New
+       field `itemAlreadySelected'.
        (onMenuItemClick): New function.
        (inflateMenuItems): Attach onClickListener as appropriate.
        (display1): Clear itemAlreadySelected.
        (display): Fix runnable synchronization.
+
        * java/org/gnu/emacs/EmacsNative.java (sendContextMenu): New
        function.
+
        * java/org/gnu/emacs/EmacsView.java (popupMenu):
        (cancelPopupMenu): Set popupactive correctly.
 
        * src/android.c (android_run_select_thread): Fix android_select
        again.
        (android_wait_event): New function.
+
        * src/android.h: Update prototypes.
        * src/androidgui.h (enum android_event_type): New
        `ANDROID_CONTEXT_MENU' event.
@@ -6743,54 +6085,55 @@
 
        * src/androidterm.c (handle_one_android_event): Handle context
        menu events.
+
        * src/androidterm.h (struct android_display_info): New field for
        menu item ID.
+
        * src/emacs.c (android_emacs_init): Call syms_of_androidmenu.
-       * src/xdisp.c (note_mouse_highlight): Return if popup_activated
-       on Android as well.
+
+       * src/xdisp.c (note_mouse_highlight): Return if popup_activated on
+       Android as well.
 
 2023-01-14  Po Lu  <luangruo@yahoo.com>
 
-       Fix android_select
        * src/android.c (android_run_select_thread, android_select):
        Handle EINTR in sem_wait and fix sigsets.
 
-       Add temporary gnulib patch
        * xcompile/lib/fpending.c (__fpending): Fix gnulib problem.
 
-       Drop unneeded changes to gnulib
        * xcompile/lib/fpending.c (__fpending):
        * xcompile/lib/open.c:
        * xcompile/lib/unistd.c (_GL_UNISTD_INLINE): Remove Android
        patches.
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-01-14  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       * java/Makefile.in (clean): Fix distclean and bootstrap-clean rules.
-       * java/debug.sh (jdb_port):
-       (attach_existing):
-       (num_pids):
-       (line): Add new options to upload a gdbserver binary to the device.
+       * java/Makefile.in (clean): Fix distclean and bootstrap-clean
+       rules.
+       * java/debug.sh (jdb_port, attach_existing, num_pids, line): Add
+       new options to upload a gdbserver binary to the device.
 
        * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): Make
        focusedActivities public.
-       * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
-       New class.
+
+       * java/org/gnu/emacs/EmacsContextMenu.java: New file.
+
        * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Fix
        bounds computation.
-       * java/org/gnu/emacs/EmacsGC.java (markDirty): Set stroke width
-       explicitly.
-       * java/org/gnu/emacs/EmacsService.java (EmacsService)
-       (getLocationOnScreen, nameKeysym): New functions.
-       * java/org/gnu/emacs/EmacsView.java (EmacsView): Disable focus
+
+       * java/org/gnu/emacs/EmacsGC.java (markDirty): Expressly provide
+       stroke width.
+
+       * java/org/gnu/emacs/EmacsService.java (getLocationOnScreen)
+       (nameKeysym): New functions.
+
+       * java/org/gnu/emacs/EmacsView.java (<init>): Disable focus
        highlight.
-       (onCreateContextMenu, popupMenu, cancelPopupMenu): New
-       functions.
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): Implement a
-       kind of ``override redirect'' window for tooltips.
+       (onCreateContextMenu, popupMenu, cancelPopupMenu): New functions.
+
+       * java/org/gnu/emacs/EmacsWindow.java: Implement a kind of
+       ``override redirect'' window for tooltips.
+
        * src/android.c (struct android_emacs_service): New method
        `name_keysym'.
        (android_run_select_thread, android_init_events):
@@ -6801,6 +6144,7 @@
        (android_move_resize_window, android_map_raised)
        (android_translate_coordinates, android_get_keysym_name)
        (android_build_string, android_exception_check): New functions.
+
        * src/android.h: Update prototypes.
 
        * src/androidfns.c (android_set_parent_frame, Fx_create_frame)
@@ -6834,42 +6178,46 @@
 
 2023-01-14  Po Lu  <luangruo@yahoo.com>
 
-       Improve reliability of Android build system
        * .gitignore: Add new files.
+
        * INSTALL.android: New file.
+
        * Makefile.in (clean_dirs): Clean xcompile as well.
-       * admin/merge-gnulib (avoided_flags): Import gnulib into Android
+
+       * admin/merge-gnulib (avoided_flags): Import Gnulib into Android
        directory as well.
+
        * doc/emacs/android.texi (Android):
        * doc/emacs/emacs.texi (Top): New node `Android'.
-       * java/org/gnu/emacs/EmacsThread.java (run): Use right
-       executable name.
+
+       * java/org/gnu/emacs/EmacsThread.java (run): Use right executable
+       name.
+
        * lib/Makefile.in (ANDROID_CFLAGS): Use better way to refer to
        /src.
        (vpath): Delete ugly block of vpath statements.
        (mostlyclean): Remove Makefile.android.
+
        * lib/fpending.c (__fpending):
        * lib/open.c:
        * lib/unistd.c (_GL_UNISTD_INLINE): Revert changes to gnulib in
        lib/.
+
        * src/android.h:
        * src/androidterm.c: Fix build.
-       * xcompile/Makefile.in (LIB_SRCDIR):
-       (LIBSRC_BINARIES, src/verbose.mk):
-       (PRE_BUILD_DEPS, PHONY): Use gnulib in xcompile/lib/ as opposed
-       to lib/.
+       * xcompile/Makefile.in (LIB_SRCDIR, LIBSRC_BINARIES)
+       (src/verbose.mk, PRE_BUILD_DEPS, PHONY): Use gnulib in
+       xcompile/lib/ as opposed to lib/.
+
        * xcompile/README: Adjust README.
 
-       Check in gnulib with Android patches
-       * xcompile/lib: Check-in gnulib with patches for Android.
+       * xcompile/lib: Check-in Gnulib with patches for Android.
 
 2023-01-13  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-       Fix crashes in Android port
        * java/org/gnu/emacs/EmacsService.java (queryTree): Fix NULL
        pointer dereference.
+
        * src/android.c (android_query_tree): Set *nchildren_return.
 
        * .gitignore: Add AndroidManifest.xml.
@@ -6878,9 +6226,6 @@
 
        * src/frame.c (make_monitor_attribute_list): Allow source to be NULL.
 
-2023-01-13  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * configure.ac (ANDROID_MIN_SDK): New variable.
        (DX): Remove and replace with D8.
        (XCONFIGURE): Check for the minimum version of Android the cross
@@ -6893,34 +6238,36 @@
        * java/Makefile.in (top_srcdir, version): New variables.
        (DX, D8): Replace with D8.
        (ANDROID_MIN_SDK, APK_NAME): New variables.
-       (.PHONY):
-       (.PRECIOUS):
-       (classes.dex):
-       (emacs.apk): Generate $(APK_NAME) instead of `emacs.apk'.
+       (.PHONY, .PRECIOUS, classes.dex, emacs.apk): Generate $(APK_NAME)
+       rather than `emacs.apk'.
 
        * java/debug.sh: New option --attach-existing.  Attach to an
        existing Emacs instance when specified.
 
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New
-       field `isPaused'.
+       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New field
+       `isPaused'.
        (invalidateFocus1): Fix infinite recursion.
        (detachWindow): Deiconify window.
        (attachWindow): Iconify the window if the activity is paused.
        (onCreate): Use the ``no title bar'' theme.
        (onPause, onResume): New functions.
+
        * java/org/gnu/emacs/EmacsNative.java (sendTouchUp, sendTouchDown)
        (sendTouchMove, sendWheel, sendIconified, sendDeiconified): New
        functions.
+
        * java/org/gnu/emacs/EmacsSdk7FontDriver.java (Sdk7Typeface):
        (list): Remove logging for code that is mostly going to be unused.
+
        * java/org/gnu/emacs/EmacsService.java (ringBell, queryTree)
        (getScreenWidth, getScreenHeight, detectMouse): New functions.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView)
        (surfaceChanged, surfaceCreated, surfaceDestroyed): Add extra
        debug logging.  Avoid deadlock in surfaceCreated.
 
-       * java/org/gnu/emacs/EmacsView.java (EmacsView): Try very hard
-       to make the SurfaceView respect Z order.  It didn't work.
+       * java/org/gnu/emacs/EmacsView.java (EmacsView): Try very hard to
+       make the SurfaceView respect Z order.  It didn't work.
        (handleDirtyBitmap): Copy over the contents from the old bitmap.
        (explicitlyDirtyBitmap): New function.
        (onLayout): Don't dirty bitmap if unnecessary.
@@ -6942,6 +6289,7 @@
        (reparentTo, makeInputFocus, raise, lower, getWindowGeometry)
        (noticeIconified, noticeDeiconified, setDontAcceptFocus)
        (setDontFocusOnMap, getDontFocusOnMap): New functions.
+
        * java/org/gnu/emacs/EmacsWindowAttachmentManager.java
        (registerWindow, detachWindow): Synchronize.
        (noticeIconified, noticeDeiconified): New functions.
@@ -6952,10 +6300,9 @@
        (frame-list-z-order, frame-restack, display-mouse-p)
        (display-monitor-attributes-list): Implement on Android.
 
-       * lisp/mwheel.el (mouse-wheel-down-event):
-       (mouse-wheel-up-event):
-       (mouse-wheel-left-event):
-       (mouse-wheel-right-event): Define on Android.
+       * lisp/mwheel.el (mouse-wheel-down-event, mouse-wheel-up-event)
+       (mouse-wheel-left-event, mouse-wheel-right-event): Define on
+       Android.
 
        * src/android.c (struct android_emacs_service): New methods
        `ringBell', `queryTree', `getScreenWidth', `getScreenHeight',
@@ -6970,7 +6317,8 @@
        (android_bell, android_set_input_focus, android_raise_window)
        (android_lower_window, android_query_tree, android_get_geometry)
        (android_get_screen_width, android_get_screen_height)
-       (android_get_mm_width, android_get_mm_height, android_detect_mouse)
+       (android_get_mm_width, android_get_mm_height)
+       (android_detect_mouse)
        (android_set_dont_focus_on_map, android_set_dont_accept_focus):
        New functions.
        (struct android_dir): New structure.
@@ -7011,8 +6359,8 @@
        handlers.
        (syms_of_androidfns): Update appropriately.
 
-       * src/androidfont.c (androidfont_draw): Use
-       FRAME_ANDROID_DRAWABLE instead of FRAME_ANDROID_WINDOW.
+       * src/androidfont.c (androidfont_draw): Use FRAME_ANDROID_DRAWABLE
+       instead of FRAME_ANDROID_WINDOW.
 
        * src/androidgui.h (enum android_event_type): New events.
        (struct android_touch_event, struct android_wheel_event)
@@ -7022,10 +6370,10 @@
        * src/androidterm.c (android_clear_frame): Use
        FRAME_ANDROID_DRAWABLE instead of FRAME_ANDROID_WINDOW.
        (android_flash, android_ring_bell): Implement bell ringing.
-       (android_toggle_invisible_pointer): Don't TODO function that
-       can't be implemented.
-       (show_back_buffer, android_flush_dirty_back_buffer_on): Check if
-       a buffer flip is required before doing the flip.
+       (android_toggle_invisible_pointer): Don't TODO function that can't
+       be implemented.
+       (show_back_buffer, android_flush_dirty_back_buffer_on): Check if a
+       buffer flip is required before doing the flip.
        (android_lower_frame, android_raise_frame): Implement functions.
        (android_update_tools, android_find_tool): New functions.
        (handle_one_android_event): Handle new iconification, wheel and
@@ -7052,8 +6400,8 @@
        (android_draw_glyph_string, android_clear_frame_area)
        (android_clear_under_internal_border, android_draw_hollow_cursor)
        (android_draw_bar_cursor, android_draw_vertical_window_border)
-       (android_draw_window_divider): Use FRAME_ANDROID_DRAWABLE
-       instead of FRAME_ANDROID_WINDOW for drawing operations.
+       (android_draw_window_divider): Use FRAME_ANDROID_DRAWABLE instead
+       of FRAME_ANDROID_WINDOW for drawing operations.
 
        * src/androidterm.h (struct android_touch_point): New structure.
        (struct android_output): New fields.
@@ -7061,9 +6409,8 @@
 
        * src/dired.c (emacs_readdir, open_directory)
        (directory_files_internal_unwind, read_dirent)
-       (directory_files_internal, file_name_completion): Add
-       indirection over readdir and opendir.  Use android variants on
-       Android.
+       (directory_files_internal, file_name_completion): Add indirection
+       over readdir and opendir.  Use android variants on Android.
 
        * src/dispnew.c (Fopen_termscript):
        * src/fileio.c (fclose_unwind): Use emacs_fclose.
@@ -7071,8 +6418,9 @@
        (file_accessible_directory_p): Append right suffix to Android
        assets directory.
        (do_auto_save_unwind): Use emacs_fclose.
-       * src/keyboard.c (lispy_function_keys): Use right function key
-       for page up and page down.
+
+       * src/keyboard.c (lispy_function_keys): Use right function key for
+       page up and page down.
        (Fopen_dribble_file): Use emacs_fclose.
 
        * src/lisp.h: New prototype emacs_fclose.
@@ -7082,34 +6430,29 @@
        * src/sfnt.c (sfnt_curve_is_flat): Fix area-squared computation.
        (sfnt_prepare_raster): Compute raster width and height
        consistently with outline building.
-       (sfnt_build_outline_edges): Use the same offsets used to set
-       offy and offx.
+       (sfnt_build_outline_edges): Use the same offsets used to set offy
+       and offx.
        (main): Adjust debug code.
 
        * src/sfntfont-android.c (sfntfont_android_saturate32): Delete
        function.
        (sfntfont_android_blend, sfntfont_android_blendrgb): Remove
        unnecessary debug code.
-       (sfntfont_android_composite_bitmap): Prevent out of bounds
-       write.
+       (sfntfont_android_composite_bitmap): Prevent out of bounds write.
        (sfntfont_android_put_glyphs): Use FRAME_ANDROID_DRAWABLE.
        (init_sfntfont_android): Initialize Monospace Serif font to
        something sensible.
+
        * src/sfntfont.c (sfntfont_text_extents): Clear glyph metrics
        before summing up pcm.
        (sfntfont_draw): Use s->font instead of s->face->font.
 
        * src/sysdep.c (emacs_fclose): Wrap around android_fclose on
-       android.
+       Android.
 
-       * src/term.c (Fsuspend_tty):
-       (delete_tty): Use emacs_fclose.
+       * src/term.c (Fsuspend_tty, delete_tty): Use emacs_fclose.
        * src/verbose.mk.in (AM_V_DX): Replace with D8 version.
 
-2023-01-11  Po Lu  <luangruo@yahoo.com>
-
-       Merge remote-tracking branch 'origin/master' into feature/android
-
 2023-01-11  Po Lu  <luangruo@yahoo.com>
 
        Bring up the sfnt-android font driver
@@ -7244,11 +6587,8 @@
 
 2023-01-08  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
        * configure.ac (ANDROID_OBJS): Add sfntfont files.
 
-       Check in new files
        * src/sfnt.h:
        * src/sfntfont-android.c:
        * src/sfntfont.c:
@@ -7256,152 +6596,106 @@
 
 2023-01-08  Po Lu  <luangruo@yahoo.com>
 
-       Update Android port
-       Note that the port currently does not work as of this check-in.
-
        * src/android.c (android_change_gc): Fix situations where clip
        rects are cleared.
        (android_create_pixmap_from_bitmap_data): Fix bitmap data
        iteration.
+
        * src/androidfns.c (Fx_show_tip, Fx_hide_tip): Remove annoying
        errors.
 
-       * src/androidgui.h (enum android_event_type):
-       (struct android_crossing_event):
-       (struct android_motion_event):
-       (struct android_button_event):
-       (union android_event): New crossing, motion and button events.
+       * src/androidgui.h (enum android_event_type)
+       (struct android_crossing_event)
+       (struct android_motion_event)
+       (struct android_button_event, union android_event): New crossing,
+       motion and button events.
 
        * src/androidterm.c (android_note_mouse_movement)
        (mouse_or_wdesc_frame, android_construct_mouse_click)
        (handle_one_android_event, android_mouse_position)
        (android_wait_for_event, android_set_window_size_1)
        (android_bitmap_icon, android_free_frame_resources)
-       (syms_of_androidterm): New functions.  Handle crossing, motion
-       and button events.
+       (syms_of_androidterm): New functions.  Handle crossing, motion and
+       button events.
 
        * src/androidterm.h (struct android_display_info): New field
        `last_mouse_movement_time'.
        (struct android_output): Remove unused `need_buffer_flip' field.
 
        * src/emacs.c (android_emacs_init): Initialize sfntfont.
+
        * src/frame.c (syms_of_frame): Set frame_inhibit_implied_resize
        to some reasonable value.
-       * src/frame.h (GCALIGNED_STRUCT): Set wait_event_type on
-       Android.
 
-       * src/sfnt.c (eassert):
-       (TEST_STATIC):
-       (available):
-       (enum sfnt_table):
-       (sfnt_table_names):
-       (SFNT_ENDOF):
-       (struct sfnt_table_directory):
-       (enum sfnt_scaler_type):
-       (sfnt_coerce_fixed):
-       (struct sfnt_hhea_table):
-       (struct sfnt_cmap_table):
-       (enum sfnt_platform_id):
-       (enum sfnt_unicode_platform_specific_id):
-       (enum sfnt_macintosh_platform_specific_id):
-       (enum sfnt_microsoft_platform_specific_id):
-       (struct sfnt_cmap_encoding_subtable):
-       (struct sfnt_cmap_encoding_subtable_data):
-       (struct sfnt_cmap_format_0):
-       (struct sfnt_cmap_format_2_subheader):
-       (struct sfnt_cmap_format_2):
-       (struct sfnt_cmap_format_4):
-       (struct sfnt_cmap_format_6):
-       (struct sfnt_cmap_format_8_or_12_group):
-       (struct sfnt_cmap_format_8):
-       (struct sfnt_cmap_format_12):
-       (struct sfnt_maxp_table):
-       (struct sfnt_loca_table_short):
-       (struct sfnt_loca_table_long):
-       (struct sfnt_glyf_table):
-       (struct sfnt_simple_glyph):
-       (struct sfnt_compound_glyph_component):
-       (struct sfnt_compound_glyph):
-       (struct sfnt_glyph):
-       (sfnt_read_table_directory):
-       (file):
-       (sfnt_read_cmap_table):
-       (sfnt_read_head_table):
-       (success):
-       (sfnt_read_hhea_table):
-       (sfnt_read_loca_table_short):
-       (sfnt_read_loca_table_long):
-       (sfnt_read_maxp_table):
-       (sfnt_read_glyf_table):
-       (sfnt_read_compound_glyph):
-       (sfnt_read_glyph):
-       (struct sfnt_point):
-       (sfnt_expand_compound_glyph_context):
-       (sfnt_decompose_compound_glyph):
-       (struct sfnt_glyph_outline):
-       (enum sfnt_glyph_outline_flags):
-       (struct sfnt_build_glyph_outline_context):
-       (sfnt_build_append):
-       (sfnt_build_glyph_outline):
-       (struct sfnt_raster):
-       (struct sfnt_edge):
-       (sfnt_prepare_raster):
-       (sfnt_build_outline_edges):
-       (sfnt_raster_glyph_outline): Move structures to sfnt.h.
+       * src/frame.h (GCALIGNED_STRUCT): Set wait_event_type on Android.
 
-       (struct sfnt_long_hor_metric):
-       (struct sfnt_hmtx_table):
-       (struct sfnt_glyph_metrics):
-       (sfnt_read_hmtx_table):
-       (sfnt_lookup_glyph_metrics):
-       (sfnt_read_name_table):
-       (sfnt_find_name):
-       (sfnt_read_meta_table):
-       (sfnt_find_metadata):
-       (sfnt_test_edge_ignore): New functions.
+       * src/sfnt.c (eassert, TEST_STATIC, available, enum sfnt_table)
+       (sfnt_table_names, SFNT_ENDOF, struct sfnt_table_directory)
+       (sfnt_scaler_type, sfnt_coerce_fixed, struct sfnt_hhea_table)
+       (struct sfnt_cmap_table, enum sfnt_platform_id)
+       (enum sfnt_unicode_platform_specific_id)
+       (enum sfnt_macintosh_platform_specific_id)
+       (enum sfnt_microsoft_platform_specific_id)
+       (struct sfnt_cmap_encoding_subtable)
+       (struct sfnt_cmap_encoding_subtable_data)
+       (struct sfnt_cmap_format_0)
+       (struct sfnt_cmap_format_2_subheader, struct sfnt_cmap_format_2)
+       (struct sfnt_cmap_format_4, struct sfnt_cmap_format_6)
+       (struct sfnt_cmap_format_8_or_12_group, struct sfnt_cmap_format_8)
+       (struct sfnt_cmap_format_12, struct sfnt_maxp_table)
+       (struct sfnt_loca_table_short, struct sfnt_loca_table_long)
+       (struct sfnt_glyf_table, struct sfnt_simple_glyph)
+       (struct sfnt_compound_glyph_component, struct sfnt_compound_glyph)
+       (struct sfnt_glyph, sfnt_read_table_directory, file)
+       (sfnt_read_cmap_table)
+       (sfnt_read_head_table, success, sfnt_read_hhea_table)
+       (sfnt_read_loca_table_short, sfnt_read_loca_table_long)
+       (sfnt_read_maxp_table, sfnt_read_glyf_table)
+       (sfnt_read_compound_glyph, sfnt_read_glyph, struct sfnt_point)
+       (sfnt_expand_compound_glyph_context)
+       (sfnt_decompose_compound_glyph, struct sfnt_glyph_outline)
+       (enum sfnt_glyph_outline_flags)
+       (struct sfnt_build_glyph_outline_context)
+       (sfnt_build_append, sfnt_build_glyph_outline, struct sfnt_raster)
+       (struct sfnt_edge, sfnt_prepare_raster, sfnt_build_outline_edges)
+       (sfnt_raster_glyph_outline): Move structures to sfnt.h.
+       (struct sfnt_long_hor_metric, sfnt_read_hmtx_table)
+       (sfnt_lookup_glyph_metrics, sfnt_read_name_table, sfnt_find_name)
+       (sfnt_read_meta_table, sfnt_find_metadata, sfnt_test_edge_ignore):
+       New functions.
        (main): Add new tests.
-       * src/xdisp.c (redisplay_tool_bar):
 
 2023-01-08  Po Lu  <luangruo@yahoo.com>
 
-       Delete unused files
        * java/org/gnu/emacs/EmacsPaintQueue.java
        * java/org/gnu/emacs/EmacsPaintReq.java: Remove files.
 
-       Update Java part of Android port
-       * java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea, perform)
-       (paintTo):
-       * java/org/gnu/emacs/EmacsDrawLine.java (EmacsDrawLine):
-       * java/org/gnu/emacs/EmacsDrawPoint.java (EmacsDrawPoint):
-       * java/org/gnu/emacs/EmacsDrawRectangle.java (EmacsDrawRectangle)
-       (paintTo):
-       * java/org/gnu/emacs/EmacsDrawable.java (EmacsDrawable):
-       * java/org/gnu/emacs/EmacsFillPolygon.java (EmacsFillPolygon):
-       * java/org/gnu/emacs/EmacsFillRectangle.java
-       (EmacsFillRectangle):
-       * java/org/gnu/emacs/EmacsFontDriver.java (EmacsFontDriver):
-       * java/org/gnu/emacs/EmacsGC.java (EmacsGC):
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative):
-       * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap):
-       * java/org/gnu/emacs/EmacsSdk23FontDriver.java
-       (EmacsSdk23FontDriver):
-       * java/org/gnu/emacs/EmacsSdk7FontDriver.java
-       (EmacsSdk7FontDriver, textExtents1, textExtents, draw):
-       * java/org/gnu/emacs/EmacsService.java (EmacsService, copyArea):
-       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, onLayout)
-       (onFocusChanged):
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, run)
-       (resizeWindow, lockCanvas, getBitmap, onKeyDown, onKeyUp)
+       * java/org/gnu/emacs/EmacsCopyArea.java (perform, paintTo):
+       * java/org/gnu/emacs/EmacsDrawLine.java:
+       * java/org/gnu/emacs/EmacsDrawPoint.java:
+       * java/org/gnu/emacs/EmacsDrawRectangle.java (paintTo):
+       * java/org/gnu/emacs/EmacsDrawable.java:
+       * java/org/gnu/emacs/EmacsFillPolygon.java:
+       * java/org/gnu/emacs/EmacsFillRectangle.java:
+       * java/org/gnu/emacs/EmacsFontDriver.java:
+       * java/org/gnu/emacs/EmacsGC.java:
+       * java/org/gnu/emacs/EmacsNative.java:
+       * java/org/gnu/emacs/EmacsPixmap.java:
+       * java/org/gnu/emacs/EmacsSdk23FontDriver.java:
+       * java/org/gnu/emacs/EmacsSdk7FontDriver.java (textExtents1)
+       (textExtents, draw):
+       * java/org/gnu/emacs/EmacsService.java (copyArea):
+       * java/org/gnu/emacs/EmacsSurfaceView.java:
+       * java/org/gnu/emacs/EmacsView.java (onLayout, onFocusChanged):
+       * java/org/gnu/emacs/EmacsWindow.java (run, resizeWindow)
+       (lockCanvas, getBitmap, onKeyDown, onKeyUp)
        (onActivityDetached): Move rendering to main thread.  Make
        drawing operations completely static.
 
-       Check in new file androidmenu.c
        * src/androidmenu.c: New file.
 
 2023-01-07  Po Lu  <luangruo@yahoo.com>
 
-       Check in new file sfnt.c
        * src/sfnt.c (xmalloc, xrealloc, xfree, eassert, MIN)
        (sfnt_table_names, SFNT_ENDOF, struct sfnt_table_directory)
        (enum sfnt_scaler_type, sfnt_coerce_fixed, struct sfnt_hhea_table)
@@ -7423,7 +6717,8 @@
        (sfnt_read_cmap_format_0, sfnt_read_cmap_format_2)
        (sfnt_read_cmap_format_4, sfnt_read_cmap_format_6)
        (sfnt_read_cmap_format_8, sfnt_read_cmap_format_12)
-       (sfnt_read_cmap_table_1, sfnt_read_cmap_table, sfnt_lookup_glyph_0)
+       (sfnt_read_cmap_table_1, sfnt_read_cmap_table)
+       (sfnt_lookup_glyph_0)
        (sfnt_lookup_glyph_2, sfnt_bsearch_above, sfnt_compare_uint16)
        (sfnt_lookup_glyph_4, sfnt_lookup_glyph_6, sfnt_lookup_glyph_8)
        (sfnt_lookup_glyph_12, sfnt_lookup_glyph, sfnt_read_head_table)
@@ -7452,68 +6747,77 @@
        (sfnt_lookup_glyph_metrics, struct sfnt_test_dcontext)
        (sfnt_test_move_to, sfnt_test_line_to, sfnt_test_curve_to)
        (sfnt_test_get_glyph, sfnt_test_free_glyph, sfnt_test_span)
-       (sfnt_test_edge, sfnt_test_raster, main): Check in
-       5000-line-long file written by me for reading TrueType and
-       OpenType fonts with TrueType outlines.
+       (sfnt_test_edge, sfnt_test_raster, main): New file, meant to read
+       TrueType fonts and OpenType fonts using TrueType outlines.
 
 2023-01-02  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2023-01-02  Po Lu  <luangruo@yahoo.com>
-
-       Update Android port
        * Makefile.in (java): Depend on info.
-       (MAKEFILE_NAME):
-       (config.status): Remove unneeded changes.
+       (MAKEFILE_NAME, config.status): Remove unneeded changes.
+
        * configure.ac (BUILD_DETAILS, ANDROID_STUBIFY): Don't require a
        C++ compiler on Android.
-       * java/AndroidManifest.xml: <EmacsActivity>: Set launchMode
-       appropriately.  <EmacsMultitaskActivity>: New activity.
-       * java/Makefile.in (CROSS_BINS): Add EmacsClient.
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity)
-       (onCreate): Use the window attachment manager.
-       * java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea)
-       (paintTo): Implement clip masks correctly.
+
+       * java/AndroidManifest.xml <EmacsActivity>: Set launchMode
+       appropriately.
+       <EmacsMultitaskActivity>: New activity.
+
+       * java/Makefile.in (CROSS_BINS): Add Emacsclient to the list of
+       binaries that will be copied into the app package.
+
+       * java/org/gnu/emacs/EmacsActivity.java (onCreate): Use the window
+       attachment manager.
+
+       * java/org/gnu/emacs/EmacsCopyArea.java (paintTo): Implement clip
+       masks correctly.
+
        * java/org/gnu/emacs/EmacsDrawRectangle.java (getRect, paintTo):
        Fix damage tracking rectangles.
-       * java/org/gnu/emacs/EmacsFontDriver.java (FontSpec, toString):
-       New function.
-       (FontMetrics, EmacsFontDriver): Fix signature of textExtents.
-       * java/org/gnu/emacs/EmacsMultitaskActivity.java
-       (EmacsMultitaskActivity): New file.
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
-       functions sendFocusIn, sendFocusOut, sendWindowAction.
-       * java/org/gnu/emacs/EmacsPaintQueue.java (run): Fix clipping
-       handling.
-       * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): Add
-       constructor for mutable pixmaps.
-       * java/org/gnu/emacs/EmacsSdk23FontDriver.java
-       (EmacsSdk23FontDriver): New file.
-       * java/org/gnu/emacs/EmacsSdk7FontDriver.java
-       (EmacsSdk7FontDriver, Sdk7Typeface, Sdk7FontEntity, Sdk7FontObject)
-       (checkMatch, hasChar, encodeChar): Implement text display and
-       fix font metrics semantics.
+
+       * java/org/gnu/emacs/EmacsFontDriver.java (toString): New
+       function.
+       (FontMetrics): Fix signature of textExtents.
+
+       * java/org/gnu/emacs/EmacsMultitaskActivity.java: New file.
+
+       * java/org/gnu/emacs/EmacsNative.java (sendFocusIn, sendFocusOut)
+       (sendWindowAction): New functions.
+
+       * java/org/gnu/emacs/EmacsPaintQueue.java (run): Correct treatment
+       of the clip rectangle list.
+
+       * java/org/gnu/emacs/EmacsPixmap.java: Add constructor for mutable
+       pixmaps.
+
+       * java/org/gnu/emacs/EmacsSdk23FontDriver.java: New file.
+
+       * java/org/gnu/emacs/EmacsSdk7FontDriver.java (Sdk7Typeface)
+       (Sdk7FontEntity, Sdk7FontObject, checkMatch, hasChar, encodeChar):
+       Implement text display and fix font metrics semantics.
 
        * java/org/gnu/emacs/EmacsService.java (EmacsService): Remove
        availableChildren.
        (getLibraryDirectory, onCreate): Pass pixel density to Emacs.
-       (clearArea): Fix arguments.  Switch to using the window
-       attachment manager.
+       (clearArea): Fix arguments.  Switch to using the window attachment
+       manager.
+
        * java/org/gnu/emacs/EmacsSurfaceView.java (surfaceChanged)
        (surfaceCreated): Flip buffers on surface attachment.
-       * java/org/gnu/emacs/EmacsView.java (EmacsView, swapBuffers):
-       New argument FORCE.  Always swap if it is true.
+
+       * java/org/gnu/emacs/EmacsView.java (swapBuffers): New argument
+       FORCE.  Always swap if it is true.
        (onKeyMultiple, onFocusChanged): New functions.
 
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, destroyHandle)
-       (run): Switch to using the window attachment manager.
-       * java/org/gnu/emacs/EmacsWindowAttachmentManager.java
-       (EmacsWindowAttachmentManager): New file.
+       * java/org/gnu/emacs/EmacsWindow.java (destroyHandle, run): Switch
+       to using the window attachment manager.
+
+       * java/org/gnu/emacs/EmacsWindowAttachmentManager.java: New file.
 
        * lisp/cus-edit.el (custom-button, custom-button-mouse)
        (custom-button-pressed):
+
        * lisp/faces.el (tool-bar): Define faces correctly on Android.
+
        * src/android.c (struct android_emacs_pixmap): Add mutable
        constructor.
        (struct android_emacs_drawable): New structure.
@@ -7522,40 +6826,38 @@
        (android_select): Set errno to EINTR if pselect fails.
        (android_close): Remove unused debugging code.
        (android_get_home_directory): New function.
-       (Java_org_gnu_emacs_EmacsNative_setEmacsParams): Set pixel
-       density and compute game path.
+       (Java_org_gnu_emacs_EmacsNative_setEmacsParams): Set pixel density
+       and compute game path.
        (android_init_emacs_drawable): New function.
        (Java_org_gnu_emacs_EmacsNative_sendKeyPress): New argument
        `unicode_char'.  Pass it in events.
        (Java_org_gnu_emacs_EmacsNative_sendKeyRelease): Likewise.
        (Java_org_gnu_emacs_EmacsNative_sendFocusIn)
        (Java_org_gnu_emacs_EmacsNative_sendFocusOut)
-       (Java_org_gnu_emacs_EmacsNative_sendWindowAction): New
-       functions.
+       (Java_org_gnu_emacs_EmacsNative_sendWindowAction): New functions.
        (android_resolve_handle): Export function.
        (android_change_gc): Clear clip rects under the right
        circumstances.  Set right clip mask field.
        (android_create_pixmap_from_bitmap_data): Use correct alpha
        channels.
-       (android_create_pixmap): Create mutable pixmap and avoid
-       redundant color array allocation.
+       (android_create_pixmap): Create mutable pixmap and avoid redundant
+       color array allocation.
        (android_create_bitmap_from_data, android_create_image)
        (android_destroy_image, android_put_pixel, android_get_pixel)
-       (android_get_image, android_put_image, faccessat): New
-       functions.
+       (android_get_image, android_put_image, faccessat): New functions.
 
        * src/android.h: Update prototypes.
 
        * src/androidfns.c (android_default_font_parameter): Prefer
        monospace to Droid Sans Mono.
-       * src/androidfont.c (struct android_emacs_font_driver): New
-       method `draw'.
+
+       * src/androidfont.c (struct android_emacs_font_driver): New method
+       `draw'.
        (struct android_emacs_font_spec): New field `dpi'.
        (struct androidfont_info): Add font metrics cache.
        (android_init_font_driver, android_init_font_spec): Adjust
        accordingly.
-       (androidfont_from_lisp, androidfont_from_java): Handle new
-       fields.
+       (androidfont_from_lisp, androidfont_from_java): Handle new fields.
        (androidfont_draw): Implement function.
        (androidfont_open_font): Set pixel size correctly.
        (androidfont_close_font): Free metrics cache.
@@ -7565,13 +6867,13 @@
        future use.
        (androidfont_list_family): Implement function.
 
-       * src/androidgui.h (enum android_event_type): New focus and
-       window action events.
+       * src/androidgui.h (enum android_event_type): New focus and window
+       action events.
        (enum android_modifier_mask): New masks.
        (struct android_key_event): New field `unicode_char'.
        (ANDROID_IS_MODIFIER_KEY): Newmacro.
-       (struct android_focus_event, struct
-       android_window_action_event): New structs.
+       (struct android_focus_event, struct android_window_action_event):
+       New structs.
        (union android_event): Add new fields.
        (enum android_image_format, struct android_image): New enums and
        structs.
@@ -7585,26 +6887,27 @@
        handling.
        (android_frame_rehighlight): New function.
        (android_frame_raise_lower): Implement accordingly.
-       (android_make_frame_invisible): Clear highlight_frame if
-       required.
+       (android_make_frame_invisible): Clear highlight_frame if required.
        (android_free_frame_resources): Clear x_focus_event_frame if
        required.
        (android_draw_fringe_bitmap, android_draw_image_foreground)
        (android_draw_image_foreground_1)
        (android_draw_image_glyph_string): Remove unnecessary code.
-       (android_create_terminal, android_term_init): Set the baud rate
-       to something sensible.
-       * src/androidterm.h (struct android_bitmap_record): Make
-       structure the same as on X.
+       (android_create_terminal, android_term_init): Set the baud rate to
+       something sensible.
+
+       * src/androidterm.h (struct android_bitmap_record): Make structure
+       the same as on X.
        (struct android_display_info): New focus tracking fields.
        (struct android_output): Likewise.
+
        * src/dispextern.h (struct image): Add ximg and mask_img on
        Android.
 
        * src/emacs.c (android_emacs_init): Fix argc sorting iteration.
 
-       * src/fileio.c (user_homedir):
-       (get_homedir): Implement correctly on Android.
+       * src/fileio.c (user_homedir, get_homedir): Implement correctly on
+       Android.
 
        * src/font.h (PT_PER_INCH): Define correctly on Android.
 
@@ -7621,25 +6924,24 @@
        (image_destroy_x_image, gui_put_x_image, image_put_x_image)
        (image_get_x_image, image_unget_x_image)
        (Create_Pixmap_From_Bitmap_Data, image_pixmap_draw_cross)
-       (MaskForeground, image_types, syms_of_image): Implement all of
-       the above on Android in terms of an API very similar to X.
+       (MaskForeground, image_types, syms_of_image): Implement all of the
+       above on Android in terms of an API very similar to X.
 
        * src/keyboard.c (FUNCTION_KEY_OFFSET, lispy_function_keys):
-       Define on Android to something sensible.
+       Define to something sensible under Android.
 
        * src/lread.c (build_load_history): Fix problem.
 
 2022-12-31  Po Lu  <luangruo@yahoo.com>
 
-       Merge remote-tracking branch 'origin/master' into feature/android
-
-2022-12-31  Po Lu  <luangruo@yahoo.com>
-
-       Bring up the Android operating system and its window system
        * .dir-locals.el (c-mode): Add ANDROID_EXPORT noise macro.
+
        * .gitignore: Add new files to ignore.
+
        * Makefile.in: Adjust for Android.
+
        * admin/merge-gnulib: Add new warning.
+
        * configure.ac: Detect Android.  Run cross-configuration for
        Android when appropriate.
 
@@ -7649,69 +6951,67 @@
        * java/Makefile.in:
        * java/README:
        * java/debug.sh:
-       * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity):
-       * java/org/gnu/emacs/EmacsApplication.java (EmacsApplication):
-       * java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea):
-       * java/org/gnu/emacs/EmacsDrawLine.java (EmacsDrawLine):
-       * java/org/gnu/emacs/EmacsDrawPoint.java (EmacsDrawPoint):
-       * java/org/gnu/emacs/EmacsDrawRectangle.java
-       (EmacsDrawRectangle):
-       * java/org/gnu/emacs/EmacsDrawable.java (EmacsDrawable):
-       * java/org/gnu/emacs/EmacsFillPolygon.java (EmacsFillPolygon):
-       * java/org/gnu/emacs/EmacsFillRectangle.java
-       (EmacsFillRectangle):
-       * java/org/gnu/emacs/EmacsFontDriver.java (EmacsFontDriver):
-       * java/org/gnu/emacs/EmacsGC.java (EmacsGC):
-       * java/org/gnu/emacs/EmacsHandleObject.java (EmacsHandleObject):
-       * java/org/gnu/emacs/EmacsNative.java (EmacsNative):
-       * java/org/gnu/emacs/EmacsPaintQueue.java (EmacsPaintQueue):
-       * java/org/gnu/emacs/EmacsPaintReq.java (EmacsPaintReq):
-       * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap):
-       * java/org/gnu/emacs/EmacsSdk7FontDriver.java
-       (EmacsSdk7FontDriver):
-       * java/org/gnu/emacs/EmacsService.java (class Holder<T>)
-       (EmacsService):
-       * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
-       * java/org/gnu/emacs/EmacsThread.java (EmacsThread):
-       * java/org/gnu/emacs/EmacsView.java (EmacsView):
-       * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): New files
-       and classes.
+       * java/org/gnu/emacs/EmacsActivity.java:
+       * java/org/gnu/emacs/EmacsApplication.java:
+       * java/org/gnu/emacs/EmacsCopyArea.java:
+       * java/org/gnu/emacs/EmacsDrawLine.java:
+       * java/org/gnu/emacs/EmacsDrawPoint.java:
+       * java/org/gnu/emacs/EmacsDrawRectangle.java:
+       * java/org/gnu/emacs/EmacsDrawable.java:
+       * java/org/gnu/emacs/EmacsFillPolygon.java:
+       * java/org/gnu/emacs/EmacsFillRectangle.java:
+       * java/org/gnu/emacs/EmacsFontDriver.java:
+       * java/org/gnu/emacs/EmacsGC.java:
+       * java/org/gnu/emacs/EmacsHandleObject.java:
+       * java/org/gnu/emacs/EmacsNative.java:
+       * java/org/gnu/emacs/EmacsPaintQueue.java:
+       * java/org/gnu/emacs/EmacsPaintReq.java:
+       * java/org/gnu/emacs/EmacsPixmap.java:
+       * java/org/gnu/emacs/EmacsSdk7FontDriver.java:
+       * java/org/gnu/emacs/EmacsService.java:
+       * java/org/gnu/emacs/EmacsSurfaceView.java:
+       * java/org/gnu/emacs/EmacsThread.java:
+       * java/org/gnu/emacs/EmacsView.java:
+       * java/org/gnu/emacs/EmacsWindow.java: New files and classes.
 
        * lib-src/Makefile.in (srcdir):
-       * lib/Makefile.in (VPATH):
-       (HAVE_NATIVE_COMP):
-       (libgnu_a_SOURCES):
+
+       * lib/Makefile.in (VPATH, HAVE_NATIVE_COMP, libgnu_a_SOURCES):
        (DEPFLAGS): Configure correctly for cross-compiling.
 
        * lib/faccessat.c:
+
        * lib/fpending.c (__fpending):
+
        * lib/open.c:
+
        * lib/unistd.c (_GL_UNISTD_INLINE): Temporary adjustments to
-       gnulib.
-
-       * lisp/frame.el (display-graphic-p):
-       (display-screens):
-       (display-pixel-height):
-       (display-pixel-width):
-       (display-mm-height):
-       (display-mm-width):
-       (display-backing-store):
-       (display-save-under):
-       (display-planes):
-       (display-color-cells):
-       (display-visual-class): Adjust for new window system `android'.
+       Gnulib.
+
+       * lisp/frame.el (display-graphic-p, display-screens)
+       (display-pixel-height, display-pixel-width, display-mm-height)
+       (display-mm-width, display-backing-store, display-save-under)
+       (display-planes, display-color-cells, display-visual-class):
+       Adjust for new window system `android'.
 
        * lisp/image/wallpaper.el (x-open-connection): Add declaration.
-       * lisp/loadup.el (featurep): Load up files for Android.
+
+       * lisp/loadup.el (featurep): Load files for Android.
+
        * lisp/net/eww.el (eww-form-submit, eww-form-file)
        (eww-form-checkbox, eww-form-select): Adjust faces for android.
+
        * lisp/term/android-win.el: New file.
+
        * src/Makefile.in: Add new targets emacs.so and android-emacs,
        then adjust for cross compilation.
+
        * src/alloc.c (cleanup_vector): Clean up Android font entities
        as well.
        (garbage_collect): Mark androidterm.
+
        * src/android-emacs.c (main):
+
        * src/android.c (ANDROID_THROW, enum android_fd_table_entry_flags)
        (struct android_emacs_service, struct android_emacs_pixmap)
        (struct android_graphics_point, struct android_event_container)
@@ -7736,10 +7036,14 @@
        (android_get_gc_values, android_set_foreground)
        (android_fill_rectangle, android_create_pixmap_from_bitmap_data)
        (android_set_clip_mask, android_set_fill_style, android_copy_area)
-       (android_free_pixmap, android_set_background, android_fill_polygon)
+       (android_free_pixmap, android_set_background)
+       (android_fill_polygon)
        (android_draw_rectangle, android_draw_point, android_draw_line)
-       (android_create_pixmap, android_set_ts_origin, android_clear_area):
+       (android_create_pixmap, android_set_ts_origin)
+       (android_clear_area):
+
        * src/android.h (ANDROID_EXPORT):
+
        * src/androidfns.c (android_display_info_for_name)
        (check_android_display_info, check_x_display_info, gamma_correct)
        (android_defined_color, android_decode_color)
@@ -7769,8 +7073,10 @@
        (android_set_internal_border_width, android_set_menu_bar_lines)
        (android_set_mouse_color, android_set_title, android_set_alpha)
        (android_frame_parm_handlers, syms_of_androidfns):
+
        * src/androidfont.c (struct android_emacs_font_driver)
-       (struct android_emacs_font_spec, struct android_emacs_font_metrics)
+       (struct android_emacs_font_spec)
+       (struct android_emacs_font_metrics)
        (struct android_emacs_font_object, struct android_integer)
        (struct androidfont_info, struct androidfont_entity)
        (android_init_font_driver, android_init_font_spec)
@@ -7783,6 +7089,7 @@
        (androidfont_list_family, androidfont_driver)
        (syms_of_androidfont_for_pdumper, syms_of_androidfont)
        (init_androidfont, android_finalize_font_entity):
+
        * src/androidgui.h (_ANDROID_GUI_H_, struct android_rectangle)
        (struct android_point, enum android_gc_function)
        (enum android_gc_value_mask, enum android_fill_style)
@@ -7793,6 +7100,7 @@
        (NativeRectangle, struct android_any_event)
        (struct android_key_event, struct android_configure_event)
        (union android_event):
+
        * src/androidterm.c (android_window_to_frame, android_clear_frame)
        (android_ring_bell, android_toggle_invisible_pointer)
        (android_update_begin, android_update_end, show_back_buffer)
@@ -7840,64 +7148,73 @@
        (frame_set_mouse_pixel_position, get_keysym_name)
        (android_create_terminal, android_term_init, syms_of_androidterm)
        (mark_androidterm):
-       * src/androidterm.h (_ANDROID_TERM_H_, struct android_display_info)
+
+       * src/androidterm.h (_ANDROID_TERM_H_)
+       (struct android_display_info)
        (struct android_output, FRAME_ANDROID_OUTPUT, XSCROLL_BAR): New
        files.
+
        * src/dired.c (file_attributes): Do not use openat on Android.
+
        * src/dispextern.h (No_Cursor): Define appropriately on Android.
        (struct glyph_string, struct face): Make gc field of type struct
        android_gc on Android.
+
        * src/dispnew.c (clear_current_matrices, clear_desired_matrices)
        (adjust_frame_glyphs_for_window_redisplay, free_glyphs)
        (update_frame, scrolling, char_ins_del_cost, update_frame_line)
        (init_display_interactive): Disable text terminal support
        completely on Android.  Fix non-toolkit menus for non-X systems.
+
        * src/editfns.c (Fuser_full_name): Call android_user_full_name.
+
        * src/emacs.c (android_emacs_init): Make main this on Android.
        Prohibit argv sorting from exceeding end of argv.
+
        * src/epaths.in: Add path definitions for Android.
 
        * src/fileio.c (file_access_p): Call android_file_access_p.
        (file_name_directory): Avoid using openat on Android.
        (Fcopy_file): Adjust to call sys_fstat instead.
-       (file_directory_p):
-       (Finsert_file_contents):
-       (write_region): Likewise.
+       (file_directory_p, Finsert_file_contents, write_region): Likewise.
+
        * src/filelock.c:
+
        * src/fns.c (Flocale_info): Pacify warning on Android.
+
        * src/font.c (font_make_entity_android): New function.
+
        * src/font.h:
-       * src/frame.c (Fframep):
-       (Fwindow_system): Handle new window system `android'.  Update doc 
strings.
+
+       * src/frame.c (Fframep, Fwindow_system): Handle new window system
+       `android'.  Update doc strings.
        (Fmake_terminal_frame): Disable on Android.
-       (gui_display_get_resource): Disable get_string_resource_hook on Android.
+       (gui_display_get_resource): Disable get_string_resource_hook on
+       Android.
        (syms_of_frame): New defsym `android'.
 
-       * src/frame.h (GCALIGNED_STRUCT): Add new output data for
-       Android.
+       * src/frame.h (GCALIGNED_STRUCT): Add new output data for Android.
        (ENUM_BF): Expand enumerator size.
-       (FRAME_ANDROID_P, FRAME_WINDOW_P, MOUSE_HL_INFO): Add
-       definitions for Android.
-
-       * src/image.c (GET_PIXEL):
-       (image_create_bitmap_from_file):
-       (image_create_x_image_and_pixmap_1):
-       (image_get_x_image):
-       (slurp_file):
-       (lookup_rgb_color):
-       (image_to_emacs_colors):
-       (image_from_emacs_colors):
-       (image_pixmap_draw_cross):
-       (image_disable_image):
-       (MaskForeground):
+       (FRAME_ANDROID_P, FRAME_WINDOW_P, MOUSE_HL_INFO): Add definitions
+       for Android.
+
+       * src/image.c (GET_PIXEL, image_create_bitmap_from_file)
+       (image_create_x_image_and_pixmap_1, image_get_x_image, slurp_file)
+       (lookup_rgb_color, image_to_emacs_colors, image_from_emacs_colors)
+       (image_pixmap_draw_cross, image_disable_image, MaskForeground)
        (gif_load): Add stubs for Android.
 
        * src/lisp.h:
+
        * src/lread.c (safe_to_load_version, maybe_swap_for_eln1, openp):
+
        * src/pdumper.c (pdumper_load): Call sys_fstat instead of fstat.
-       * src/process.c (wait_reading_process_output): Use
-       android_select instead of pselect.
+
+       * src/process.c (wait_reading_process_output): Use android_select
+       instead of pselect.
+
        * src/scroll.c: Disable on Android.
+
        * src/sysdep.c (widen_foreground_group, reset_sys_modes)
        (init_signals, emacs_fstatat, sys_fstat): New function.
        (emacs_open, emacs_open_noquit, emacs_close): Implement
@@ -7911,29 +7228,29 @@
        (maybe_fatal, syms_of_term): Disable text terminal support on
        Android.
 
-       * src/termhooks.h (enum output_method): Add android output
-       method.
+       * src/termhooks.h (enum output_method): Add android output method.
        (GCALIGNED_STRUCT, TERMINAL_FONT_CACHE): Define for Android.
 
        * src/terminal.c (Fterminal_live_p): Implement for Android.
 
        * src/verbose.mk.in (AM_V_GLOBALS): Add JAVAC and DX.
-       * src/xdisp.c (redisplay_internal): Disable text terminals on Android.
-       (display_menu_bar):
-       (display_tty_menu_item):
-       (draw_row_with_mouse_face):
-       (expose_frame): Make the non toolkit menu bar work on Android.
-
-       * src/xfaces.c (GCGraphicsExposures):
-       (x_create_gc):
-       (x_free_gc):
+       * src/xdisp.c (redisplay_internal): Disable text terminals on
+       Android.
+       (display_menu_bar, display_tty_menu_item)
+       (draw_row_with_mouse_face, expose_frame): Make the non toolkit
+       menu bar work on Android.
+
+       * src/xfaces.c (GCGraphicsExposures, x_create_gc, x_free_gc)
        (Fx_load_color_file): Define for Android.
 
-       * xcompile/Makefile.in (top_srcdir):
-       (top_builddir):
+       * xcompile/Makefile.in:
        * xcompile/README:
        * xcompile/langinfo.h (nl_langinfo): New files.
 
+2022-12-29  Po Lu  <luangruo@yahoo.com>
+
+       Development of the Android port starts...
+
 This ChangeLog only chronicles changes constituting the initial
 development of the Android port.  Refer to other ChangeLog files for a
 narrative of unrelated modifications made to Emacs during that time,
diff --git a/INSTALL b/INSTALL
index 605be366e92..d09216739f6 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,13 +4,16 @@ 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, MS-DOS,
-and Android ports, also read the files nt/INSTALL, nextstep/INSTALL,
-msdos/INSTALL, and java/INSTALL.
-
-For information about building from a Git checkout (rather than an
-Emacs release), read the INSTALL.REPO file first.
+This file contains general information on building GNU Emacs.  If you
+are building an Emacs release tarball on a Unix or a GNU system, the
+instructions in this file should be sufficient.  For other
+configurations, we have additional specialized files:
+
+  . INSTALL.REPO if you build from a Git checkout
+  . nt/INSTALL if you build for MS-Windows
+  . nextstep/INSTALL if you build for GNUstep/macOS
+  . java/INSTALL if you build for Android
+  . msdos/INSTALL if you build for MS-DOS
 
 
 BASIC INSTALLATION
diff --git a/Makefile.in b/Makefile.in
index b47e88f6970..fdd9353e254 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1116,7 +1116,7 @@ TAGS tags: lib lib-src # src
        $(MAKE) -C doc/lispref tags
        $(MAKE) -C doc/misc tags
 
-CHECK_TARGETS = check check-maybe check-expensive check-all
+CHECK_TARGETS = check check-maybe check-expensive check-all check-byte-compile
 .PHONY: $(CHECK_TARGETS)
 $(CHECK_TARGETS): all
        $(MAKE) -C test $@
diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS
index 1273e9a976b..cea1aa56cde 100644
--- a/admin/MAINTAINERS
+++ b/admin/MAINTAINERS
@@ -160,6 +160,12 @@ Po Lu
 
        Haiku battery support in lisp/battery.el
 
+Jim Porter
+       Eshell
+           lisp/eshell/*
+           test/lisp/eshell/*
+           doc/misc/eshell.texi
+
 ==============================================================================
 2. Areas that someone is willing to maintain, although he would not
 necessarily mind if someone else was the official maintainer.
diff --git a/admin/emake b/admin/emake
index 0aa1178768d..c9e59d34067 100755
--- a/admin/emake
+++ b/admin/emake
@@ -19,13 +19,20 @@
 
 # This script is meant to be used as ./admin/emake, and will compile
 # the Emacs tree with virtually all of the informational messages
-# removed, and with errors/warnings highlighted in red.  It'll give a
-# quick overview to confirm that nothing has broken, for instance
+# removed, and with errors/warnings highlighted in red.  It will also
+# run the test files belonging to files that have changed.  It'll give
+# a quick overview to confirm that nothing has broken, for instance
 # after doing a "git pull".  It's not meant to be used during actual
 # development, because it removes so much information that commands
 # like `next-error' won't be able to jump to the source code where
 # errors are.
 
+# It has a few options:
+# with --no-color errors/warnings are not highlighted
+# with --no-check test files are not run
+# with --no-fast the FAST=true make variable is not set (see Makefile.in)
+# with --quieter only errors/warnings remain visible
+
 cores=1
 
 # Determine the number of cores.
@@ -96,6 +103,7 @@ GEN.*loaddefs|\
 ^.Read INSTALL.REPO for more|\
 ^Your system has the required tools.|\
 ^Building aclocal.m4|\
+^Building 'aclocal.m4'|\
 ^ Running 'autoreconf|\
 ^You can now run './configure'|\
 ^./configure|\
@@ -129,15 +137,21 @@ The GNU allocators don't work|\
 " | \
 while read
 do
-  C=""
-  (($NOCOLOR == 0)) && [[ "X${REPLY:0:1}" != "X " ]] && C="\033[1;31m"
-  (($NOCOLOR == 0)) && [[ "X${REPLY:0:3}" == "X   " ]] && C="\033[1;31m"
-  if (($QUIETER == 0))
-  then
-      [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" 
"$REPLY"
-  else
-      [[ "X$C" == "X" ]] && printf "%-80s\r" "$REPLY" || printf 
"$C%-80s\033[0m\n" "$REPLY"
-  fi
+    C=""
+    E=0
+    [ ! -v L ] && L=80
+    [[ "X${REPLY:0:1}" != "X " ]] && E=1
+    [[ "X${REPLY:0:3}" == "X   " ]] && E=1
+    (($NOCOLOR == 0)) && (($E == 1)) && C="\033[1;31m"
+    (($NOCOLOR == 0)) && (($E == 1)) && C="\033[1;31m"
+    if (($QUIETER == 0))
+    then
+       (($E == 0)) && printf "%s\n" "$REPLY" || printf "${C}%s\033[0m\n" 
"$REPLY"
+    else
+       (($E == 0)) && printf "%-${L}s\r" "$REPLY" || printf 
"${C}%-${L}s\033[0m\n" "$REPLY"
+    fi
+    L=${#REPLY}
+    (($L < 80)) && L=80
 done
 
 # If make failed, exit now with its error code.
@@ -149,4 +163,13 @@ done
 # changed since last time.
 make -j$cores check-maybe 2>&1 | \
     sed -n '/contained unexpected results/,$p' | \
-    grep -E --line-buffered -v "^make"
+    grep -E --line-buffered -v "^make" | \
+while read
+do
+    if (($NOCOLOR == 0))
+    then
+       printf "\033[1;31m%s\033[0m\n" "$REPLY"
+    else
+       printf "%s\n" "$REPLY"
+    fi
+done
diff --git a/admin/git-bisect-start b/admin/git-bisect-start
index 9de4d547323..8eb5328a1a1 100755
--- a/admin/git-bisect-start
+++ b/admin/git-bisect-start
@@ -82,7 +82,7 @@ done
 # SKIP-BRANCH 58cc931e92ece70c3e64131ee12a799d65409100
 
 ## The list below is the exhaustive list of all commits between Dec 1
-## 2016 and Jul 8 2023 on which building Emacs with the default
+## 2016 and Aug 10 2023 on which building Emacs with the default
 ## options, on a GNU/Linux computer and with GCC, fails.  It is
 ## possible (though unlikely) that building Emacs with non-default
 ## options, with other compilers, or on other platforms, would succeed
@@ -1757,3 +1757,22 @@ $REAL_GIT bisect skip $(cat $0 | grep '^# SKIP-SINGLE ' 
| sed 's/^# SKIP-SINGLE
 # SKIP-SINGLE 0a35c991c19a6dd0a707f2baa868f8989242c3ab
 # SKIP-SINGLE e2ee646b162b87e832c8032b9d90577bd21f21f8
 # SKIP-SINGLE 35d2fe176cb438d55552cacbdf25c3692c054d51
+# SKIP-SINGLE de3d8ae71b43f80244c4d813ff1503b8551f0026
+# SKIP-SINGLE a496509cedb17109d0e6297a74e2ff8ed526333c
+# SKIP-SINGLE a6a586ffc1bd302e30d80cb88b06e1e7e1573f63
+# SKIP-SINGLE f5d142f66370b29af58360faeea90d1112756bc5
+# SKIP-SINGLE 46e8ab23eaeb5e453042f430fc016cf9ffc2ac37
+# SKIP-SINGLE eb72569dbef91862a765cd4d9f380220244b4549
+# SKIP-SINGLE c4b77b82decb757af0aff1b7420203fa0805b483
+# SKIP-SINGLE 0ee01457a84e031d490553949a2deacd4865a5bb
+# SKIP-SINGLE 6c68d9bd3a18c74384fc764179fd92a024d6c35d
+# SKIP-SINGLE a46e231a5f27c46933cc53865cee452ad1a0c0d3
+# SKIP-SINGLE c045d5322c2c1658f215bf59d431fcc8f96ffc12
+# SKIP-SINGLE dabb713eb05aff62deb6872a3498327934f18c8d
+# SKIP-SINGLE b8c05636ca4b28a7adc62e82a5fed528b402396d
+# SKIP-SINGLE e72afa9dbf92f45d00c87c90ead364d52f73024f
+# SKIP-SINGLE 9d3aacedf0c217af207d39e390f376914160396b
+# SKIP-SINGLE 6bdbb4cbfc2deb7d3a02e1428768e101f3dbd265
+# SKIP-SINGLE 2752573dfb76873dbe783e89a1fbf01d157c54e3
+# SKIP-SINGLE 62e990db7a2fad16756e019b331c28ad5a5a89fe
+# SKIP-SINGLE 6253e7e74249c7cdfa86723f0b91a1d207cb143e
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index b533f69cceb..fe88d1106ae 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -26,7 +26,7 @@
 GNULIB_URL=https://git.savannah.gnu.org/git/gnulib.git
 
 GNULIB_MODULES='
-  alignasof alloca-opt binary-io byteswap c-ctype c-strcase
+  alignasof alloca-opt binary-io boot-time byteswap c-ctype c-strcase
   canonicalize-lgpl
   careadlinkat close-stream copy-file-range
   count-leading-zeros count-one-bits count-trailing-zeros
@@ -45,19 +45,20 @@ GNULIB_MODULES='
   pathmax pipe2 pselect pthread_sigmask
   qcopy-acl readlink readlinkat regex
   sig2str sigdescr_np socklen stat-time std-gnu11 stdbool stdckdint stddef 
stdio
-  stpcpy stpncpy strnlen strnlen strtoimax symlink sys_stat sys_time
+  stpcpy strnlen strnlen strtoimax symlink sys_stat sys_time
   tempname time-h time_r time_rz timegm timer-time timespec-add timespec-sub
   update-copyright unlocked-io utimensat
   vla warnings year2038
 '
 
 AVOIDED_MODULES='
-  btowc chmod close crypto/af_alg dup fchdir fstat langinfo lock
+  btowc chmod close crypto/af_alg dup fchdir fstat
+  iswblank iswctype iswdigit iswxdigit langinfo lock
   mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
   openat-die opendir pthread-h raise
   save-cwd select setenv sigprocmask stat stdarg
   threadlib tzset unsetenv utime utime-h
-  wchar wcrtomb wctype-h
+  wchar wcrtomb wctype wctype-h
 '
 
 GNULIB_TOOL_FLAGS='
diff --git a/admin/notes/copyright b/admin/notes/copyright
index ae09707bac8..a06d92a2c5f 100644
--- a/admin/notes/copyright
+++ b/admin/notes/copyright
@@ -381,7 +381,7 @@ conclude it was written by me."
 
 lisp/term/README
   - had no copyright notice till Feb 2007. ChangeLog.3 suggests it was
-  written by Eric Raymond. When asked by rms on 14 Feb 2007 he said:
+  written by Eric S. Raymond. When asked by rms on 14 Feb 2007 he said:
 
     I don't remember writing it, but it reads like my prose and I believe
     I wrote the feature(s) it's describing.  So I would have been the
diff --git a/admin/notes/unicode b/admin/notes/unicode
index b4f23f68def..da4736c43c6 100644
--- a/admin/notes/unicode
+++ b/admin/notes/unicode
@@ -305,6 +305,12 @@ nontrivial changes to the build process.
 
        src/msdos.c
 
+ * iso-latin-1
+
+     This file is used to test Emacs encoding.
+
+        test/lisp/gnus/mm-decode-resources/win1252-multipart.bin
+
  * iso-2022-cn-ext
 
      This file is externally generated from leim/MISC-DIC/cangjie-table.b5
@@ -355,19 +361,27 @@ nontrivial changes to the build process.
      Some of the entries in this list are patterns, and stand for any
      files with the listed extension.
 
+       *.bmp
+       *.cur
+       *.gif
+       *.gpg
        *.gz
        *.icns
        *.ico
+       *.jpg
+       *.kbx
+       *.key
        *.pbm
        *.pdf
+       *.pif
        *.png
        *.sig
+       *.tiff
+       *.webp
+       *.zip
        etc/e/eterm-color
-       etc/package-keyring.gpg
-       msdos/emacs.pif
-       nextstep/GNUstep/Emacs.base/Resources/emacs.tiff
-       nt/icons/hand.cur
-
+       etc/e/eterm-direct
+       java/emacs.keystore
 
 This file is part of GNU Emacs.
 
diff --git a/autogen.sh b/autogen.sh
index 3cb77afedb3..0d89b7cfc9a 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -257,6 +257,13 @@ Please report any problems with this script to 
bug-gnu-emacs@gnu.org .'
   ## Use autoreconf's -f option in case autoreconf itself has changed.
   autoreconf -fi -I m4 || exit
 
+  echo "Building 'aclocal.m4' in exec ..."
+
+  # Create a placeholder aclocal.m4 in exec, preventing autoreconf
+  # from running aclocal.
+
+  echo "" > exec/aclocal.m4
+
   echo "Running 'autoreconf -fi' in exec ..."
 
   # Now, run autoreconf inside the exec directory to generate its
diff --git a/build-aux/config.guess b/build-aux/config.guess
index 354a8ccde42..b187213930f 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -4,7 +4,7 @@
 
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 
-timestamp='2023-06-23'
+timestamp='2023-07-20'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -976,7 +976,27 @@ EOF
        GUESS=$UNAME_MACHINE-unknown-minix
        ;;
     aarch64:Linux:*:*)
-       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       set_cc_for_build
+       CPU=$UNAME_MACHINE
+       LIBCABI=$LIBC
+       if test "$CC_FOR_BUILD" != no_compiler_found; then
+           ABI=64
+           sed 's/^        //' << EOF > "$dummy.c"
+           #ifdef __ARM_EABI__
+           #ifdef __ARM_PCS_VFP
+           ABI=eabihf
+           #else
+           ABI=eabi
+           #endif
+           #endif
+EOF
+           cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | 
sed 's, ,,g'`
+           eval "$cc_set_abi"
+           case $ABI in
+               eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
+           esac
+       fi
+       GUESS=$CPU-unknown-linux-$LIBCABI
        ;;
     aarch64_be:Linux:*:*)
        UNAME_MACHINE=aarch64_be
@@ -1042,6 +1062,15 @@ EOF
     k1om:Linux:*:*)
        GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
        ;;
+    kvx:Linux:*:*)
+       GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+       ;;
+    kvx:cos:*:*)
+       GUESS=$UNAME_MACHINE-unknown-cos
+       ;;
+    kvx:mbr:*:*)
+       GUESS=$UNAME_MACHINE-unknown-mbr
+       ;;
     loongarch32:Linux:*:* | loongarch64:Linux:*:*)
        GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
        ;;
diff --git a/build-aux/config.sub b/build-aux/config.sub
index 9865d6ea4d1..6ae25027537 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -4,7 +4,7 @@
 
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 
-timestamp='2023-06-26'
+timestamp='2023-07-31'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -1206,6 +1206,7 @@ case $cpu-$vendor in
                        | i370 | i*86 | i860 | i960 | ia16 | ia64 \
                        | ip2k | iq2000 \
                        | k1om \
+                       | kvx \
                        | le32 | le64 \
                        | lm32 \
                        | loongarch32 | loongarch64 \
@@ -1214,31 +1215,7 @@ case $cpu-$vendor in
                        | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
                        | m88110 | m88k | maxq | mb | mcore | mep | metag \
                        | microblaze | microblazeel \
-                       | mips | mipsbe | mipseb | mipsel | mipsle \
-                       | mips16 \
-                       | mips64 | mips64eb | mips64el \
-                       | mips64octeon | mips64octeonel \
-                       | mips64orion | mips64orionel \
-                       | mips64r5900 | mips64r5900el \
-                       | mips64vr | mips64vrel \
-                       | mips64vr4100 | mips64vr4100el \
-                       | mips64vr4300 | mips64vr4300el \
-                       | mips64vr5000 | mips64vr5000el \
-                       | mips64vr5900 | mips64vr5900el \
-                       | mipsisa32 | mipsisa32el \
-                       | mipsisa32r2 | mipsisa32r2el \
-                       | mipsisa32r3 | mipsisa32r3el \
-                       | mipsisa32r5 | mipsisa32r5el \
-                       | mipsisa32r6 | mipsisa32r6el \
-                       | mipsisa64 | mipsisa64el \
-                       | mipsisa64r2 | mipsisa64r2el \
-                       | mipsisa64r3 | mipsisa64r3el \
-                       | mipsisa64r5 | mipsisa64r5el \
-                       | mipsisa64r6 | mipsisa64r6el \
-                       | mipsisa64sb1 | mipsisa64sb1el \
-                       | mipsisa64sr71k | mipsisa64sr71kel \
-                       | mipsr5900 | mipsr5900el \
-                       | mipstx39 | mipstx39el \
+                       | mips* \
                        | mmix \
                        | mn10200 | mn10300 \
                        | moxie \
@@ -1733,7 +1710,7 @@ case $os in
             | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
             | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \
             | hiux* | abug | nacl* | netware* | windows* \
-            | os9* | macos* | osx* | ios* \
+            | os9* | macos* | osx* | ios* | tvos* | watchos* \
             | mpw* | magic* | mmixware* | mon960* | lnews* \
             | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
             | aos* | aros* | cloudabi* | sortix* | twizzler* \
@@ -1759,7 +1736,7 @@ case $os in
             | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
             | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
             | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
-            | fiwix* | mlibc* )
+            | fiwix* | mlibc* | cos* | mbr* )
                ;;
        # This one is extra strict with allowed versions
        sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1816,6 +1793,10 @@ case $kernel-$os in
                ;;
        *-eabi* | *-gnueabi*)
                ;;
+       none-coff* | none-elf*)
+               # None (no kernel, i.e. freestanding / bare metal),
+               # can be paired with an output format "OS"
+               ;;
        -*)
                # Blank kernel with real OS is always fine.
                ;;
diff --git a/build-aux/git-hooks/pre-commit b/build-aux/git-hooks/pre-commit
index f89d9ca8f8c..12b08d2c25f 100755
--- a/build-aux/git-hooks/pre-commit
+++ b/build-aux/git-hooks/pre-commit
@@ -21,6 +21,14 @@
 LC_ALL=C
 export LC_ALL
 
+# If this is a system where /bin/sh isn't sufficient to
+# run git-sh-setup, use a working shell as a recourse.
+if test -x "/usr/xpg4/bin/sh" && test -z "$POSIX_SHELL"; then
+    POSIX_SHELL=1
+    export POSIX_SHELL
+    exec "/usr/xpg4/bin/sh" `dirname $0`/pre-commit
+fi
+
 exec >&2
 
 . git-sh-setup
diff --git a/build-aux/git-hooks/prepare-commit-msg 
b/build-aux/git-hooks/prepare-commit-msg
index 7802dffda43..1520ef3f5f8 100755
--- a/build-aux/git-hooks/prepare-commit-msg
+++ b/build-aux/git-hooks/prepare-commit-msg
@@ -25,6 +25,10 @@ SHA1=$3
 # Prefer gawk if available, as it handles NUL bytes properly.
 if type gawk >/dev/null 2>&1; then
   awk="gawk"
+# Next use /usr/xpg4/bin/awk if available, since the script
+# doesn't support Unix awk.
+elif test -x /usr/xpg4/bin/awk; then
+  awk="/usr/xpg4/bin/awk"
 else
   awk="awk"
 fi
diff --git a/build-aux/make-info-dir b/build-aux/make-info-dir
index 3490b7a31f9..64cf2d43f16 100755
--- a/build-aux/make-info-dir
+++ b/build-aux/make-info-dir
@@ -38,7 +38,7 @@ shift
 
 exec "${AWK-awk}" '
   function detexinfo() {
-    gsub(/@value{emacsname}/, "Emacs")
+    gsub(/@value\{emacsname\}/, "Emacs")
     gsub(/@[^{]*\{/, "")
     gsub(/}/, "")
   }
diff --git a/configure.ac b/configure.ac
index e01465c2af0..f92339225b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -305,7 +305,8 @@ AC_DEFUN([OPTION_DEFAULT_OFF], [dnl
 ])dnl
 
 dnl OPTION_DEFAULT_IFAVAILABLE(NAME, HELP-STRING)
-dnl Create a new --with option that defaults to 'ifavailable'.
+dnl Create a new --with option that defaults to 'ifavailable',
+dnl unless it is overriden by $with_features being equal to 'no'.
 dnl NAME is the base name of the option.  The shell variable with_NAME
 dnl   will be set to either the user's value (if the option is
 dnl   specified; 'yes' for a plain --with-NAME) or to 'ifavailable' (if the
@@ -315,10 +316,12 @@ dnl   characters with "_".
 dnl HELP-STRING is the help text for the option.
 AC_DEFUN([OPTION_DEFAULT_IFAVAILABLE], [dnl
   AC_ARG_WITH([$1],[AS_HELP_STRING([--with-$1],[$2])],[],[dnl
-    m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=ifavailable])dnl
+    AS_IF([test "$with_features" != no],
+      [m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=ifavailable],
+      [m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=no])dnl
+  ])dnl
 ])dnl
 
-
 dnl OPTION_DEFAULT_ON(NAME, HELP-STRING)
 dnl Create a new --with option that defaults to $with_features.
 dnl NAME is the base name of the option.  The shell variable with_NAME
@@ -342,22 +345,13 @@ AC_ARG_WITH([mailutils],
       options are irrelevant; this is the default if GNU Mailutils is
       installed])],
   [],
-  [with_mailutils=$with_features
-   AS_IF([test "$with_mailutils" = yes],
-     [AS_IF([test "x$XCONFIGURE" != "xandroid" \
-             && test "$with_android" = "no"],
-       [(movemail --version) >/dev/null 2>&1 || with_mailutils=no],
-       [dnl Don't check for movemail if cross-compiling.
-        dnl instead, default to false.
-        with_mailutils=no])])])
-AS_IF([test "$with_mailutils" = no],
-  [with_mailutils=])
-
-AS_IF([test x"$with_mailutils" = xyes],
-  [AC_DEFINE([HAVE_MAILUTILS], [1],
-     [Define to 1 if Emacs was configured with mailutils])])
-
-AC_SUBST([with_mailutils])
+  [AS_IF([test "$with_features" != "no"],
+   [with_mailutils=yes-unless-android
+    AS_IF([test "x$XCONFIGURE" != "xandroid"],
+     [(movemail --version) >/dev/null 2>&1 || with_mailutils=no],
+     [dnl Don't check for movemail if cross-compiling.
+      dnl instead, default to false.
+      with_mailutils=no])])])
 
 AC_ARG_WITH([pop],
   [AS_HELP_STRING([--with-pop],
@@ -594,6 +588,25 @@ OPTION_DEFAULT_OFF([small-ja-dic],[generate a smaller-size 
Japanese dictionary])
 OPTION_DEFAULT_OFF([android],[cross-compile Android application package])
 OPTION_DEFAULT_ON([android-debug],[don't build Emacs as a debug package on 
Android])
 
+# Find out of Android support is enabled and mailutils has defaulted
+# to `yes-unless-android'.  Disable it if so.
+
+AS_IF([test "x$with_mailutils" = "xyes-unless-android"],
+  [AS_IF([test "x$with_android" != "xno"],
+     [with_mailutils=no],
+     [with_mailutils=yes])])
+
+# Clear with_mailutils if it's set to no.
+
+AS_IF([test "$with_mailutils" = no],
+  [with_mailutils=])
+
+AS_IF([test x"$with_mailutils" = xyes],
+  [AC_DEFINE([HAVE_MAILUTILS], [1],
+     [Define to 1 if Emacs was configured with mailutils])])
+
+AC_SUBST([with_mailutils])
+
 AC_ARG_WITH([shared-user-id],
   [AS_HELP_STRING([--with-shared-user-id=ID],
     [use the given shared user ID in Android builds])])
@@ -2526,7 +2539,7 @@ AC_CHECK_HEADERS_ONCE(
   sys/sysinfo.h
   coff.h pty.h
   sys/resource.h
-  sys/utsname.h pwd.h utmp.h util.h
+  sys/utsname.h pwd.h util.h
   sanitizer/lsan_interface.h
   sanitizer/asan_interface.h
   sanitizer/common_interface_defs.h])
@@ -2698,7 +2711,7 @@ for Android, but all API calls need to be stubbed out])
     # Check for some functions not always present in the NDK.
     AC_CHECK_DECLS([android_get_device_api_level])
 
-    # Say this build is really for Android.
+    # Mention this build is really for Android.
     REALLY_ANDROID=yes])])
 
 AC_SUBST([ANDROID])
@@ -2759,16 +2772,16 @@ if test x"${x_includes}" = x; then
   bitmapdir=/usr/include/X11/bitmaps
 else
   # accumulate include directories that have X11 bitmap subdirectories
-  bmd_acc=
+  AS_UNSET([bmd_acc])
   for bmd in `AS_ECHO(["$x_includes"]) | sed -e 's/:/ /g'`; do
     if test -d "${bmd}/X11/bitmaps"; then
-      bmd_acc="${bmd_acc}:${bmd}/X11/bitmaps"
+      bmd_acc="${bmd_acc+$bmd_acc:}${bmd}/X11/bitmaps"
     fi
     if test -d "${bmd}/bitmaps"; then
-      bmd_acc="${bmd_acc}:${bmd}/bitmaps"
+      bmd_acc="${bmd_acc+$bmd_acc:}${bmd}/bitmaps"
     fi
   done
-  bitmapdir=${bmd_acc#:}
+  bitmapdir=$bmd_acc
 fi
 
 NATIVE_IMAGE_API=no
@@ -4020,6 +4033,7 @@ if test "${with_tree_sitter}" != "no"; then
     [HAVE_TREE_SITTER=yes], [HAVE_TREE_SITTER=no])
   if test "${HAVE_TREE_SITTER}" = yes; then
     AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.])
+    NEED_DYNLIB=yes
   else
     EMACS_CHECK_MODULES([TREE_SITTER], [tree-sitter >= 0.6.3],
       [HAVE_TREE_SITTER=yes], [HAVE_TREE_SITTER=no])
@@ -5832,11 +5846,14 @@ getrlimit setrlimit shutdown \
 pthread_sigmask strsignal setitimer \
 sendto recvfrom getsockname getifaddrs freeifaddrs \
 gai_strerror sync \
-getpwent endpwent getgrent endgrent \
+endpwent getgrent endgrent \
 renameat2 \
 cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np \
 pthread_set_name_np])
 
+# getpwent is not present in older versions of Android.  (bug#65319)
+gl_CHECK_FUNCS_ANDROID([getpwent], [[#include <pwd.h>]])
+
 if test "$ac_cv_func_cfmakeraw" != "yes"; then
   # On some systems (Android), cfmakeraw is inline, so AC_CHECK_FUNCS
   # cannot find it.  Check if some code including termios.h and using
@@ -5975,7 +5992,7 @@ AC_DEFUN([tputs_link_source], [
 # than to expect to find it in ncurses.
 # Also we need tputs and friends to be able to build at all.
 AC_CACHE_CHECK([for library containing tputs], [emacs_cv_tputs_lib],
-[if test "${opsys}" = "mingw32" || test "$opsys" = "android"; then
+[if test "${opsys}" = "mingw32" || test x"$REALLY_ANDROID" = "xyes"; then
   emacs_cv_tputs_lib='none required'
 else
   # curses precedes termcap because of AIX (Bug#9736#35) and OpenIndiana.
@@ -6013,7 +6030,7 @@ TERMINFO=yes
 ## LIBS_TERMCAP="-lncurses", this overrides LIBS_TERMCAP = -ltinfo,
 ## if that was found above to have tputs.
 ## Should we use the gnu* logic everywhere?
-case "$opsys" in
+case "$opsys$REALLY_ANDROID" in
   ## darwin: Prevents crashes when running Emacs in Terminal.app under 10.2.
   ##  The ncurses library has been moved out of the System framework in
   ##  Mac OS X 10.2.  So if configure detects it, set the command-line
@@ -6042,7 +6059,10 @@ fail;
     fi
     ;;
 
-  mingw32 | android)
+  # The case condition is a concatenation of both $opsys and
+  # $REALLY_ANDROID.  Only disable termcap if building a GUI program.
+  # (bug#65340)
+  mingw32 | androidyes)
     TERMINFO=no
     LIBS_TERMCAP=
     ;;
diff --git a/cross/Makefile.in b/cross/Makefile.in
index a7b5700440e..b66025283aa 100644
--- a/cross/Makefile.in
+++ b/cross/Makefile.in
@@ -22,6 +22,8 @@ srcdir = @srcdir@
 top_builddir = @top_builddir@
 builddir = @builddir@
 
+FIND_DELETE = @FIND_DELETE@
+
 -include $(top_builddir)/src/verbose.mk
 
 # Cross-compiling Emacs for Android.
@@ -51,7 +53,7 @@ LIB_SRC_TOP_SRCDIR = $(realpath $(top_src))
 LIBSRC_BINARIES = lib-src/etags lib-src/ctags lib-src/emacsclient \
                  lib-src/ebrowse lib-src/hexl lib-src/movemail
 
-CLEAN_SUBDIRS = src lib-src lib etc
+CLEAN_SUBDIRS = $(wildcard src lib-src lib etc)
 
 .PHONY: all
 all: lib/libgnu.a src/libemacs.so src/android-emacs $(LIBSRC_BINARIES)
@@ -174,17 +176,19 @@ $(LIBSRC_BINARIES) &: src/verbose.mk $(top_builddir)/$@ 
lib/libgnu.a \
 
 .PHONY: clean maintainer-clean distclean
 clean:
-       for dir in $(CLEAN_SUBDIRS); do \
-         find $$dir -type f -delete;   \
+       for dir in $(CLEAN_SUBDIRS); do         \
+         find $$dir -type f $(FIND_DELETE);    \
        done
        rm -rf lib/config.h lib-src/config.h
 # ndk-build won't have been generated in a non-Android build.
-       -make -C ndk-build clean
+       if test -f ndk-build/Makefile; then     \
+          $(MAKE) -C ndk-build clean;          \
+       fi
 
 maintainer-clean distclean bootstrap-clean: clean
 # Remove links created by configure.
-       for dir in $(CLEAN_SUBDIRS); do \
-         find $$dir -type l -delete;   \
+       for dir in $(CLEAN_SUBDIRS); do         \
+         find $$dir -type l $(FIND_DELETE);    \
        done
        rm -rf lib/Makefile lib/gnulib.mk ndk-build/Makefile
        rm -rf ndk-build/ndk-build.mk Makefile
diff --git a/doc/emacs/ChangeLog.1 b/doc/emacs/ChangeLog.1
index 16afa073169..1cf26aeff06 100644
--- a/doc/emacs/ChangeLog.1
+++ b/doc/emacs/ChangeLog.1
@@ -81,7 +81,7 @@
        * misc.texi (Network Security): Mention the new protocol-level
        `high' NSM checks.
 
-2014-12-08  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-08  Eric S. Raymond  <esr@thyrsus.com>
 
        * maintaining.texi: Support for Arch has been moved to obsolete,
        remove references that imply otherwise.
@@ -128,7 +128,7 @@
 
        * maintaining.texi (Version Control Systems): Fix a typo.
 
-2014-11-20  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-11-20  Eric S. Raymond  <esr@thyrsus.com>
 
        * maintaining.texi: Document SRC support.
 
@@ -5616,11 +5616,11 @@
        * custom.texi (Variables): Add Directory Variables to menu.
        (Directory Variables): New node.
 
-2008-05-16  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-16  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc2-xtra.texi: Modify an example so it reflects what vc.el now does.
 
-2008-05-15  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-15  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc2-xtra.texi, emacs.texi, files.texi: Snapshots node renamed to
        Revision Tags and rewritten.  Section now uses modern terminology,
@@ -5632,7 +5632,7 @@
        * msdog.texi (Windows Files): Update documentation of
        w32-get-true-file-attributes.
 
-2008-05-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi, vc-xtra.texi, vc1-xtra.texi: Document the new VC
        directory mode.
@@ -5642,11 +5642,11 @@
        * killing.texi (Appending Kills): Remove a strangely off-topic index
        entry "television".
 
-2008-05-07  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-07  Eric S. Raymond  <esr@thyrsus.com>
 
        * ack.texi, files.texi, vc2-xtra.texi: Meta-CVS is no longer supported.
 
-2008-05-02  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-02  Eric S. Raymond  <esr@thyrsus.com>
 
        * buffers.texi, files.texi (Version-control):
        vc-toggle-read-only is no longer a good idea...
@@ -5923,7 +5923,7 @@
        * mini.texi (Minibuffer History): Add text about a list of minibuffer
        default values.
 
-2007-10-20  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-20  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi: Disambiguate two slightly different uses of the term
        'filesets'.
@@ -5963,7 +5963,7 @@
 
        * calendar.texi (Diary): Clarify text about diary file example.
 
-2007-10-13  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-13  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi: Capitalize node names according to convention.
 
@@ -5971,13 +5971,13 @@
 
        * misc.texi (Interactive Shell): Correct INSIDE_EMACS reference.
 
-2007-10-11  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-11  Eric S. Raymond  <esr@thyrsus.com>
 
        * emacs.texi:
        * files.texi (Version Systems): Minor fixes to version-control material
        suggested by RMS and Robert J. Chassell.
 
-2007-10-10  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-10  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi (Version Systems):
        * vc-xtra.texi:
@@ -5987,7 +5987,7 @@
        Revise text for adequate description of VCSes with monotonic IDs.
        * emacs.texi: Change of terminology from `version' to `revision'.
 
-2007-10-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi (Version Systems): Describe newer VCses.
        Reorder the descriptions to be chronological.
@@ -6015,7 +6015,7 @@
        * basic.texi (Arguments): Replace fill-paragraph with
        fill-paragraph-or-region.
 
-2007-10-06  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-06  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi: Update the section on version control for 2007
        conditions.  None of these changes are new-VC-specific; that
@@ -6128,7 +6128,7 @@
 
        * files.texi (Why Version Control?): Improve previous change.
 
-2007-07-18  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-07-18  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.texi (Why Version Control?): New node.
 
@@ -10860,7 +10860,7 @@
        * emacs.texi: Add a sentence to the top menu mentioning the
        specific version of Emacs this manual applies to.
 
-1993-04-25  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-25  Eric S. Raymond  (esr@thyrsus.com)
 
        * basic.texi: Document next-line-add-lines variable used to
        implement down-arrow.
@@ -10871,17 +10871,17 @@
 
        * text.texi: Update unix TeX ordering information.
 
-1993-03-26  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * news.texi: Mention fill-rectangle in keybinding list.
 
        * killing.texi: Document fill-rectangle.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.texi: Bring the docs up to date with VC 5.2.
 
-1992-01-10  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-01-10  Eric S. Raymond  (esr@thyrsus.com)
 
        * emacs.tex: Mention blackbox and gomoku under Amusements.
        Assembler mode is now mentioned and appropriately indexed
diff --git a/doc/emacs/ack.texi b/doc/emacs/ack.texi
index d61809fa58f..4a8a2a24377 100644
--- a/doc/emacs/ack.texi
+++ b/doc/emacs/ack.texi
@@ -899,7 +899,7 @@ Takahashi Naoto co-wrote @file{quail.el} (q.v.), and wrote
 @file{robin.el}, another input method.
 
 @item
-Thomas Neumann and Eric Raymond wrote @file{make-mode.el},
+Thomas Neumann and Eric S. Raymond wrote @file{make-mode.el},
 a mode for editing makefiles.
 
 @item
diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi
index 9d352f3a484..a85589f864c 100644
--- a/doc/emacs/android.texi
+++ b/doc/emacs/android.texi
@@ -399,7 +399,7 @@ Startup}) connect the Android system to another computer, 
and run:
 $ adb shell "settings put global settings_enable_monitor_phantom_procs false"
 @end example
 
-@section Running Emacs in the Background
+@cindex running emacs in the background, android
 @cindex emacs killed, android
 @cindex emacs in the background, android
 
@@ -429,7 +429,7 @@ the background in their proprietary versions of Android.  
There is a
 list of such troublesome manufacturers and sometimes workarounds at
 @url{https://dontkillmyapp.com/}.
 
-@section Android Permissions
+@cindex permissions under android
 @cindex external storage, android
 
   Android also defines a permissions system that determines what
@@ -491,6 +491,8 @@ permissions it has requested upon being installed:
 @code{android.permission.RECORD_AUDIO}
 @item
 @code{android.permission.CAMERA}
+@item
+@code{android.permission.POST_NOTIFICATIONS}
 @end itemize
 
 While most of these permissions are left unused by Emacs itself, they
@@ -516,8 +518,6 @@ permissions upon installation:
 @code{android.permission.TRANSMIT_IR}
 @item
 @code{android.permission.WAKE_LOCK}
-@item
-@code{android.permission.POST_NOTIFICATIONS}
 @end itemize
 
 Other permissions must be granted by the user through the system
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 244dd7eb525..87124e962ca 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1739,12 +1739,17 @@ rotation is lossless, and uses an external utility 
called
 @section Other Dired Features
 
 @vindex dired-free-space
-  By default, Dired will display the available space on the disk in
-the first line.  This is the @code{first} value of the
-@code{dired-free-space} variable.  If you set this to
-@code{separate} instead, Dired will display this on a separate line
-(including the space the files in the current directory takes).  If
-you set this to @code{nil}, the free space isn't displayed at all.
+  By default, Dired displays the available space on the directory's
+disk on the first line of that directory's listing, following the
+directory name.  You can control this display by customizing the
+variable @code{dired-free-space}.  Its default value is @code{first},
+which produces the available space after the directory name.  If you
+customize it to the value @code{separate} instead, Dired will display
+the disk space information on a separate line, following the line with
+the directory name, and will include in that line the space used by
+the files in the current directory as well as the available disk
+space.  If you set this to @code{nil}, the available disk space
+information will not be displayed at all.
 
 @kindex + @r{(Dired)}
 @findex dired-create-directory
diff --git a/doc/emacs/input.texi b/doc/emacs/input.texi
index 671901fea88..4f49ca3cece 100644
--- a/doc/emacs/input.texi
+++ b/doc/emacs/input.texi
@@ -20,7 +20,7 @@ which is detailed here.
 @end menu
 
 @node Touchscreens
-@section Using Emacs on touchscreens
+@section Using Emacs on Touchscreens
 @cindex touchscreen input
 
   Touchscreen input works by pressing and moving tools (which include
@@ -97,7 +97,7 @@ this can be changed by customizing the variable
 @code{touch-screen-delay}.
 
 @node On-Screen Keyboards
-@section Using Emacs with virtual keyboards
+@section Using Emacs with Virtual Keyboards
 @cindex virtual keyboards
 @cindex on-screen keyboards
 
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 21e2d38e96f..a104cd2bfa1 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -411,8 +411,8 @@ the minibuffer.
 @itemx @key{prior}
 Typing @kbd{M-v}, while in the minibuffer, selects the window showing
 the completion list (@code{switch-to-completions}).  This paves the
-way for also using the commands below.  @key{PageUp}, @key{prior} and
-@kbd{M-g M-c} does the same.  You can also select the window in other
+way for using the commands below.  @key{PageUp}, @key{prior} and
+@kbd{M-g M-c} do the same.  You can also select the window in other
 ways (@pxref{Windows}).
 
 @findex choose-completion
diff --git a/doc/lispref/ChangeLog.1 b/doc/lispref/ChangeLog.1
index dd6a220398f..c96ba40dbe5 100644
--- a/doc/lispref/ChangeLog.1
+++ b/doc/lispref/ChangeLog.1
@@ -7394,7 +7394,7 @@
        * tips.texi (Coding Conventions): Do not encourage the use of "-flag"
        variable names.
 
-2008-05-03  Eric S. Raymond  <esr@golux>
+2008-05-03  Eric S. Raymond  <esr@thyrsus.com>
 
        * keymaps.texi: Clarify that (current-local-map) and
        (current-global-map) return references, not copies.
@@ -13889,17 +13889,17 @@
 
        * Makefile (dist): Change to use Gzip instead of compress.
 
-1993-04-23  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * loading.texi (Unloading): define-function changed back to
        defalias.  It may not stay this way, but at least it's
        consistent with the known-good version of the code patch.
 
-1993-03-26  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * modes.texi (Hooks): Document new optional arg of add-hook.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * variables.texi: Document nil initial value of buffer-local variables.
 
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 2991799e668..741d98655d0 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -1255,12 +1255,19 @@ A device used by the XTEST extension to report input.
 @cindex @code{display} property, and point display
 @cindex @code{composition} property, and point display
 
-  Emacs cannot display the cursor when point is in the middle of a
-sequence of text that has the @code{display} or @code{composition}
-property, or is invisible.  Therefore, after a command finishes and
-returns to the command loop, if point is within such a sequence, the
-command loop normally moves point to the edge of the sequence, making this
-sequence effectively intangible.
+  When a sequence of text has the @code{display} or @code{composition}
+property, or is invisible, there can be several buffer positions that
+result in the cursor being displayed at same place on the screen.
+Therefore, after a command finishes and returns to the command loop,
+if point is in such a sequence, the command loop normally moves point
+to try and make this sequence effectively intangible.
+
+This @emph{point adjustment} follows the following general rules: first, the
+adjustment should not change the overall direction of the command;
+second if the command moved point, the adjustment tries to ensure the
+cursor is also moved; third, Emacs prefers the edges of an intangible
+sequence and among those edges it prefers the non sticky ones, such
+that newly inserted text is visible.
 
   A command can inhibit this feature by setting the variable
 @code{disable-point-adjustment}:
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index aaab4e455a0..afedf776c86 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -582,11 +582,12 @@ contents and inserting the whole file, because (1) it 
preserves some
 marker positions and (2) it puts less data in the undo list.
 
 It is possible to read a special file (such as a FIFO or an I/O
-device) with @code{insert-file-contents}, as long as @var{replace},
-and @var{visit} and @var{beg} are @code{nil}.  However, you should
-normally use an @var{end} argument for these files to avoid inserting
-(potentially) unlimited data into the buffer (for instance, when
-inserting data from @file{/dev/urandom}).
+device) with @code{insert-file-contents}, as long as @var{replace} is
+@code{nil} or @code{if-regular}, and @var{visit} and @var{beg} are
+@code{nil}.  However, you should normally use an @var{end} argument
+for these files to avoid inserting (potentially) unlimited data into
+the buffer (for instance, when inserting data from
+@file{/dev/urandom}).
 @end defun
 
 @defun insert-file-contents-literally filename &optional visit beg end replace
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index be8624e0fde..3c704970cda 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -2850,7 +2850,9 @@ Emacs is restarted by the session manager.
 @cindex notifications, on desktop
 
 Emacs is able to send @dfn{notifications} on systems that support the
-freedesktop.org Desktop Notifications Specification and on MS-Windows.
+freedesktop.org Desktop Notifications Specification, MS-Windows,
+Haiku, and Android.
+
 In order to use this functionality on POSIX hosts, Emacs must have
 been compiled with D-Bus support, and the @code{notifications} library
 must be loaded.  @xref{Top, , D-Bus,dbus,D-Bus integration in Emacs}.
@@ -3167,6 +3169,87 @@ This function removes the tray notification given by its 
unique
 @var{id}.
 @end defun
 
+@cindex desktop notifications, Haiku
+When Emacs runs under Haiku as a GUI program, it is also provides a
+restricted pastiche of the D-Bus desktop notifications interface
+previously addressed.  The principle capabilities absent from the
+function detailed below are call-back functions such as
+@code{:actions}, @code{:on-action} and @code{:on-close}.
+
+@defun haiku-notifications-notify &rest params
+This function sends a notification to the desktop notification server,
+incorporating a number of parameters that are akin to some of those
+accepted by @code{notifications-notify}.  The parameters are:
+
+@table @code
+@item :title @var{title}
+@item :body @var{body}
+@item :replaces-id @var{replaces-id}
+@item :urgency @var{urgency}
+These have the same meaning as they do when used in calls to
+@code{notifications-notify}.
+
+@item :app-icon @var{app-icon}
+This should be the file name designating an image file to use as the
+icon for the notification displayed.  If @code{nil}, the icon
+presented will instead be Emacs's app icon.
+@end table
+
+Its return value is a number identifying the notification, which can
+be exploited as the @code{:replaces-id} parameter to a subsequent call
+to this function.
+@end defun
+
+@cindex desktop notifications, Android
+When Emacs is built as an Android application package, displaying
+notifications is facilitated by the function
+@code{android-notifications-notify}.  This function does not feature
+call-backs, and has several idiosyncrasies, when compared to
+@code{notifications-notify}.
+
+@defun android-notifications-notify &rest params
+This function displays a desktop notification.  @var{params} is a list
+of parameters analogous to its namesake in
+@code{notifications-notify}.  The parameters are:
+
+@table @code
+@item :title @var{title}
+@item :body @var{body}
+@item :replaces-id @var{replaces-id}
+These have the same meaning as they do when used in calls to
+@code{notifications-notify}.
+
+@item :urgency @var{urgency}
+@item :group @var{group}
+These two parameters are ignored under Android 7.1 and earlier
+versions of the system.  The set of values for @var{urgency} is the
+same as with @code{notifications-notify}, but the urgency applies to
+all notifications displayed with the defined @var{group}.
+
+If @var{group} is nil or not present within @var{params}, it is
+replaced by the string @samp{"Desktop Notifications"}.
+
+@item :icon @var{icon}
+This parameter controls the symbolic icon the notification will be
+displayed with.  Its value is a string designating an icon within the
+@code{android.R.drawable} system package.  See
+@uref{https://developer.android.com/reference/android/R.drawable,R.drawable
+| Android Developers} for a list of such icons.
+
+If it is not provided within @var{params} or @var{icon} does not
+exist, it defaults to @samp{"ic_dialog_alert"}.
+@end table
+
+It returns a number identifying the notification, which may be
+supplied as the @code{:replaces-id} parameter to a later call to this
+function.
+
+If Emacs is not afforded the permission to display notifications
+(@pxref{Android Environment,,, emacs, The GNU Emacs Manual}) under
+Android 13 and later, any notifications sent will be silently
+disregarded.
+@end defun
+
 @node File Notifications
 @section Notifications on File Changes
 @cindex file notifications
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 00c0fa6001a..5064f76e7b8 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -28476,12 +28476,12 @@ B and
 the octave numbered 0 was chosen to correspond to the lowest
 audible frequency.  Using this system, middle C (about 261.625 Hz)
 corresponds to the note @slanted{C} in octave 4 and is denoted
-@slanted{C@sub{4}}.  Any frequency can be described by giving a note plus an
+@slanted{C4}.  Any frequency can be described by giving a note plus an
 offset in cents (where a cent is a ratio of frequencies so that a
 semitone consists of 100 cents).
 
 The midi note number system assigns numbers to notes so that
-@slanted{C@sub{-1}} corresponds to the midi note number 0 and 
@slanted{G@sub{9}}
+@slanted{C-1} corresponds to the midi note number 0 and @slanted{G9}
 corresponds to the midi note number 127.   A midi controller can have
 up to 128 keys and each midi note number from  0 to 127 corresponds to
 a possible key.
diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi
index 962e6c914ce..6eb212ca841 100644
--- a/doc/misc/eglot.texi
+++ b/doc/misc/eglot.texi
@@ -406,9 +406,10 @@ provides:
 At-point documentation: when point is at or near a symbol or an
 identifier, the information about the symbol/identifier, such as the
 signature of a function or class method and server-generated
-diagnostics, is made available via the ElDoc package (@pxref{Lisp
-Doc,,, emacs, GNU Emacs Manual}).  This allows major modes to provide
-extensive help and documentation about the program identifiers.
+diagnostics, is made available via the ElDoc package
+(@pxref{Programming Language Doc,,, emacs, GNU Emacs Manual}).  This
+allows major modes to provide extensive help and documentation about
+the program identifiers.
 
 @item
 On-the-fly diagnostic annotations with server-suggested fixes, via the
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index 7c7f304d55d..6890728a81d 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -409,8 +409,18 @@ implementing common command-line utilities, but enhanced 
for Eshell.
 (These built-in commands are just ordinary Lisp functions whose names
 begin with @code{eshell/}.)  In order to call the external variant of
 a built-in command @code{foo}, you could call @code{*foo}.  Usually,
-this should not be necessary.  You can check what will be applied by
-the @code{which} command:
+this should not be necessary; if the Eshell version of a command
+doesn't support a particular option, it will automatically invoke the
+external command for you.
+
+Some built-in Eshell commands provide enhanced versions of regular
+Emacs Lisp functions.  If you want to call the regular Emacs Lisp
+version, you can write your command in Lisp form (@pxref{Invocation}).
+To call the regular version in command form, you can use
+@code{funcall} or @code{apply}, e.g.@: @samp{funcall #'compile "make all"}
+(@pxref{Calling Functions,,, elisp, GNU Emacs Lisp Reference Manual}).
+
+You can check what will be applied by the @code{which} command:
 
 @example
 ~ $ which ls
@@ -420,14 +430,19 @@ eshell/ls is a compiled Lisp function in `em-ls.el'
 @end example
 
 If you want to discard a given built-in command, you could declare an
-alias (@pxref{Aliases}).  Example:
+alias (@pxref{Aliases}).  For example:
 
 @example
-~ $ which sudo
-eshell/sudo is a compiled Lisp function in `em-tramp.el'.
-~ $ alias sudo '*sudo $@@*'
-~ $ which sudo
-sudo is an alias, defined as "*sudo $@@*"
+@group
+~ $ alias ls '*ls $@@*'
+~ $ which ls
+ls is an alias, defined as "*ls $@@*"
+@end group
+@group
+~ $ alias compile 'apply #''compile $*'
+~ $ which compile
+ls is an alias, defined as "apply #'compile $*"
+@end group
 @end example
 
 Some of the built-in commands have different behavior from their
@@ -523,6 +538,17 @@ Clear the scrollback contents of the Eshell window.  
Unlike the
 command @command{clear}, this command deletes content in the Eshell
 buffer.
 
+@item compile
+@cmindex compile
+Run an external command, sending its output to a compilation buffer if
+the command would output to the screen and is not part of a pipeline
+or subcommand.  This is particularly useful when defining aliases, so
+that interactively, the output shows up in a compilation buffer, but
+you can still pipe the output elsewhere if desired.  For example, if
+you have a grep-like command on your system, you might define an alias
+for it like so: @samp{alias mygrep 'compile --mode=grep-mode -- mygrep
+$*'}.
+
 @item cp
 @cmindex cp
 Copy a file to a new location or copy multiple files to the same
@@ -2308,11 +2334,6 @@ This happens because the @code{grep} Lisp function 
returns immediately,
 and then the asynchronous @command{grep} process expects to examine the
 temporary file, which has since been deleted.
 
-@item Problem with C-r repeating text
-
-If the text @emph{before point} reads "./run", and you type @kbd{C-r r u
-n}, it will repeat the line for every character typed.
-
 @item Backspace doesn't scroll back after continuing (in smart mode)
 
 Hitting space during a process invocation, such as @command{make}, will
@@ -2365,8 +2386,6 @@ be Eshell's job?
 This would be so that if a Lisp function calls @code{print}, everything
 will happen as it should (albeit slowly).
 
-@item When an extension module fails to load, @samp{cd /} gives a Lisp error
-
 @item If a globbing pattern returns one match, should it be a list?
 
 @item Make sure syntax table is correct in Eshell mode
@@ -2670,12 +2689,6 @@ Everywhere in Emacs where @code{shell-mode} is specially 
noticed, add
 
 @item Permit the umask to be selectively set on a @command{cp} target
 
-@item Problem using @kbd{M-x eshell} after using @code{eshell-command}
-
-If the first thing that I do after entering Emacs is to run
-@code{eshell-command} and invoke @command{ls}, and then use @kbd{M-x
-eshell}, it doesn't display anything.
-
 @item @kbd{M-@key{RET}} during a long command (using smart display) doesn't 
work
 
 Since it keeps the cursor up where the command was invoked.
diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi
index b67624af9f8..abd498824c5 100644
--- a/doc/misc/eww.texi
+++ b/doc/misc/eww.texi
@@ -132,12 +132,13 @@ visible in its rendered content.
 
 @findex eww-open-in-new-buffer
 @kindex M-RET
-  The @kbd{M-@key{RET}} command (@code{eww-open-in-new-buffer}) opens the
-URL at point in a new EWW buffer, akin to opening a link in a new
-``tab'' in other browsers.  When @code{global-tab-line-mode} is
-enabled, this buffer is displayed in the tab on the window tab line.
-When @code{tab-bar-mode} is enabled, a new tab is created on the frame
-tab bar.
+  The @kbd{M-@key{RET}} command (@code{eww-open-in-new-buffer}) opens
+the URL at point in a new EWW buffer, akin to opening a link in a new
+``tab'' in other browsers.  If invoked with prefix argument, the
+command will not make the new buffer the current one.  When
+@code{global-tab-line-mode} is enabled, this buffer is displayed in
+the tab on the window tab line.  When @code{tab-bar-mode} is enabled,
+a new tab is created on the frame tab bar.
 
 @findex eww-readable
 @kindex R
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 8d25e868c8a..f017b011d71 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -25476,7 +25476,7 @@ There is no specific spam or ham processor for regular 
expressions.
 
 @defvar spam-use-bogofilter
 
-Set this variable if you want @code{spam-split} to use Eric Raymond's
+Set this variable if you want @code{spam-split} to use Eric S. Raymond's
 speedy Bogofilter.
 
 With a minimum of care for associating the @samp{$} mark for spam
@@ -25508,7 +25508,7 @@ Get the Bogofilter spamicity score 
(@code{spam-bogofilter-score}).
 
 @defvar spam-use-bogofilter-headers
 
-Set this variable if you want @code{spam-split} to use Eric Raymond's
+Set this variable if you want @code{spam-split} to use Eric S. Raymond's
 speedy Bogofilter, looking only at the message headers.  It works
 similarly to @code{spam-use-bogofilter}, but the @code{X-Bogosity} header
 must be in the message already.  Normally you would do this with a
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index b1d2999e5d7..6e521944b22 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,7 +3,7 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2023-07-02.10}
+\def\texinfoversion{2023-07-27.21}
 %
 % Copyright 1985, 1986, 1988, 1990-2023 Free Software Foundation, Inc.
 %
@@ -426,42 +426,21 @@
 }
 
 % First remove any @comment, then any @c comment.  Pass the result on to
-% \argcheckspaces.
+% \argremovespace.
 \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
-\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
-
-% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
-%
-% \argremovec might leave us with trailing space, e.g.,
+\def\argremovec#1\c#2\ArgTerm{\argremovespace#1$ $\ArgTerm}
+% \argremovec might leave us with trailing space, though; e.g.,
 %    @end itemize  @c foo
-% This space token undergoes the same procedure and is eventually removed
-% by \finishparsearg.
-%
-\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
-\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
-\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
-  \def\temp{#3}%
-  \ifx\temp\empty
-    % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
-    \let\temp\finishparsearg
-  \else
-    \let\temp\argcheckspaces
-  \fi
-  % Put the space token in:
-  \temp#1 #3\ArgTerm
-}
+% Note that the argument cannot contain the TeX $, as its catcode is
+% changed to \other when Texinfo source is read.
+\def\argremovespace#1 $#2\ArgTerm{\finishparsearg#1$\ArgTerm}
 
 % If a _delimited_ argument is enclosed in braces, they get stripped; so
 % to get _exactly_ the rest of the line, we had to prevent such situation.
-% We prepended an \empty token at the very beginning and we expand it now,
-% just before passing the control to \argtorun.
-% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
-% either the null string, or it ends with \^^M---thus there is no danger
-% that a pair of braces would be stripped.
-%
-% But first, we have to remove the trailing space token.
-%
-\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+% We prepended an \empty token at the very beginning and we expand it
+% just before passing the control to \next.
+% (But first, we have to remove the remaining $ or two.)
+\def\finishparsearg#1$#2\ArgTerm{\expandafter\argtorun\expandafter{#1}}
 
 
 % \parseargdef - define a command taking an argument on the line
@@ -5575,6 +5554,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
 \newdimen\entryrightmargin
 \entryrightmargin=0pt
 
+% amount to indent subsequent lines in an entry when it spans more than
+% one line.
+\newdimen\entrycontskip
+\entrycontskip=1em
+
 % for PDF output, whether to make the text of the entry a link to the page
 % number.  set for @contents and @shortcontents where there is only one
 % page number.
@@ -5684,25 +5668,30 @@ might help (with 'rm \jobname.?? \jobname.??s')%
       \advance\dimen@ii by 1\dimen@i
       \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line
       \ifdim\dimen@ > 0.8\dimen@ii   % due to long index text
+        % Undo changes above
+        \advance \parfillskip by 0pt minus -1\dimen@i
+        \advance\dimen@ii by -1\dimen@i
+        %
         % Try to split the text roughly evenly.  \dimen@ will be the length of
         % the first line.
         \dimen@ = 0.7\dimen@
         \dimen@ii = \hsize
         \ifnum\dimen@>\dimen@ii
           % If the entry is too long (for example, if it needs more than
-          % two lines), use all the space in the first line.
+          % two lines), use the same line length for all lines.
           \dimen@ = \dimen@ii
+        \else
+          \advance \dimen@ by 1\rightskip
         \fi
         \advance\leftskip by 0pt plus 1fill % ragged right
-        \advance \dimen@ by 1\rightskip
         \parshape = 2 0pt \dimen@ 0em \dimen@ii
         % Ideally we'd add a finite glue at the end of the first line only,
         % instead of using \parshape with explicit line lengths, but TeX
         % doesn't seem to provide a way to do such a thing.
         %
         % Indent all lines but the first one.
-        \advance\leftskip by 1em
-        \advance\parindent by -1em
+        \advance\leftskip by \entrycontskip
+        \advance\parindent by -\entrycontskip
       \fi\fi
       \indent % start paragraph
       \unhbox\boxA
@@ -6721,6 +6710,82 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   \input \tocreadfilename
 }
 
+% process toc file to find the maximum width of the section numbers for
+% each chapter
+\def\findsecnowidths{%
+  \begingroup
+  \setupdatafile
+  \activecatcodes
+  \secentryfonts
+  % Redefinitions
+  \def\numchapentry##1##2##3##4{%
+    \def\curchapname{secnowidth-##2}%
+    \curchapmax=0pt
+  }%
+  \let\appentry\numchapentry
+  %
+  \def\numsecentry##1##2##3##4{%
+    \def\cursecname{secnowidth-##2}%
+    \cursecmax=0pt
+    %
+    \setbox0=\hbox{##2}%
+    \ifdim\wd0>\curchapmax
+      \curchapmax=\wd0
+      \expandafter\xdef\csname\curchapname\endcsname{\the\wd0}%
+    \fi
+  }%
+  \let\appsecentry\numsecentry
+  %
+  \def\numsubsecentry##1##2##3##4{%
+    \def\curssecname{secnowidth-##2}%
+    \curssecmax=0pt
+    %
+    \setbox0=\hbox{##2}%
+    \ifdim\wd0>\cursecmax
+      \cursecmax=\wd0
+      \expandafter\xdef\csname\cursecname\endcsname{\the\wd0}%
+    \fi
+  }%
+  \let\appsubsecentry\numsubsecentry
+  %
+  \def\numsubsubsecentry##1##2##3##4{%
+    \setbox0=\hbox{##2}%
+    \ifdim\wd0>\curssecmax
+      \curssecmax=\wd0
+      \expandafter\xdef\csname\curssecname\endcsname{\the\wd0}%
+    \fi
+  }%
+  \let\appsubsubsecentry\numsubsubsecentry
+  %
+  % Discard any output by outputting to dummy vbox, in case the toc file
+  % contains macros that we have not redefined above.
+  \setbox\dummybox\vbox\bgroup
+    \input \tocreadfilename\relax
+  \egroup
+  \endgroup
+}
+\newdimen\curchapmax
+\newdimen\cursecmax
+\newdimen\curssecmax
+
+
+% set #1 to the maximum section width for #2
+\def\retrievesecnowidth#1#2{%
+  \expandafter\let\expandafter\savedsecnowidth \csname secnowidth-#2\endcsname
+  \ifx\savedsecnowidth\relax
+    #1=0pt
+  \else
+    #1=\savedsecnowidth
+  \fi
+}
+\newdimen\secnowidthchap
+\secnowidthchap=0pt
+\newdimen\secnowidthsec
+\secnowidthsec=0pt
+\newdimen\secnowidthssec
+\secnowidthssec=0pt
+
+
 \newskip\contentsrightmargin \contentsrightmargin=1in
 \newcount\savepageno
 \newcount\lastnegativepageno \lastnegativepageno = -1
@@ -6766,6 +6831,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   \startcontents{\putwordTOC}%
     \openin 1 \tocreadfilename\space
     \ifeof 1 \else
+      \findsecnowidths
       \readtocfile
     \fi
     \vfill \eject
@@ -6793,6 +6859,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
     \rm
     \hyphenpenalty = 10000
     \advance\baselineskip by 1pt % Open it up a little.
+    \extrasecnoskip=0.4pt
     \def\numsecentry##1##2##3##4{}
     \let\appsecentry = \numsecentry
     \let\unnsecentry = \numsecentry
@@ -6828,8 +6895,6 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   % This space should be enough, since a single number is .5em, and the
   % widest letter (M) is 1em, at least in the Computer Modern fonts.
   % But use \hss just in case.
-  % (This space doesn't include the extra space that gets added after
-  % the label; that gets put in by \shortchapentry above.)
   %
   % We'd like to right-justify chapter numbers, but that looks strange
   % with appendix letters.  And right-justifying numbers and
@@ -6839,10 +6904,15 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   \hbox to 1em{#1\hss}%
 }
 
-% These macros generate individual entries in the table of contents.
-% The first argument is the chapter or section name.
-% The last argument is the page number.
-% The arguments in between are the chapter number, section number, ...
+% These macros generate individual entries in the table of contents,
+% and are read in from the *.toc file.
+%
+% The arguments are like:
+% \def\numchapentry#1#2#3#4
+%   #1 - the chapter or section name.
+%   #2 - section number
+%   #3 - level of section (e.g "chap", "sec")
+%   #4 - page number
 
 % Parts, in the main contents.  Replace the part number, which doesn't
 % exist, with an empty box.  Let's hope all the numbers have the same width.
@@ -6855,7 +6925,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   \vskip 0pt plus 5\baselineskip
   \penalty-300
   \vskip 0pt plus -5\baselineskip
-  \dochapentry{\numeralbox\labelspace#1}{}%
+  \dochapentry{#1}{\numeralbox}{}%
 }
 %
 % Parts, in the short toc.
@@ -6866,12 +6936,14 @@ might help (with 'rm \jobname.?? \jobname.??s')%
 }
 
 % Chapters, in the main contents.
-\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+\def\numchapentry#1#2#3#4{%
+  \retrievesecnowidth\secnowidthchap{#2}%
+  \dochapentry{#1}{#2}{#4}%
+}
 
 % Chapters, in the short toc.
-% See comments in \dochapentry re vbox and related settings.
 \def\shortchapentry#1#2#3#4{%
-  \tocentry{\shortchaplabel{#2}\labelspace #1}{#4}%
+  \tocentry{#1}{\shortchaplabel{#2}}{#4}%
 }
 
 % Appendices, in the main contents.
@@ -6882,67 +6954,111 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   \setbox0 = \hbox{\putwordAppendix{} M}%
   \hbox to \wd0{\putwordAppendix{} #1\hss}}
 %
-\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}}
+\def\appentry#1#2#3#4{%
+  \retrievesecnowidth\secnowidthchap{#2}%
+  \dochapentry{\appendixbox{#2}\hskip.7em#1}{}{#4}%
+}
 
 % Unnumbered chapters.
-\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
-\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{#4}}
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{}{#4}}
 
 % Sections.
-\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\def\numsecentry#1#2#3#4{\dosecentry{#1}{#2}{#4}}
+
+\def\numsecentry#1#2#3#4{%
+  \retrievesecnowidth\secnowidthsec{#2}%
+  \dosecentry{#1}{#2}{#4}%
+}
 \let\appsecentry=\numsecentry
-\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+\def\unnsecentry#1#2#3#4{%
+  \retrievesecnowidth\secnowidthsec{#2}%
+  \dosecentry{#1}{}{#4}%
+}
 
 % Subsections.
-\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\def\numsubsecentry#1#2#3#4{%
+  \retrievesecnowidth\secnowidthssec{#2}%
+  \dosubsecentry{#1}{#2}{#4}%
+}
 \let\appsubsecentry=\numsubsecentry
-\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+\def\unnsubsecentry#1#2#3#4{%
+  \retrievesecnowidth\secnowidthssec{#2}%
+  \dosubsecentry{#1}{}{#4}%
+}
 
 % And subsubsections.
-\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#2}{#4}}
 \let\appsubsubsecentry=\numsubsubsecentry
-\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{}{#4}}
 
 % This parameter controls the indentation of the various levels.
 % Same as \defaultparindent.
 \newdimen\tocindent \tocindent = 15pt
 
-% Now for the actual typesetting. In all these, #1 is the text and #2 is the
-% page number.
+% Now for the actual typesetting. In all these, #1 is the text, #2 is
+% a section number if present, and #3 is the page number.
 %
 % If the toc has to be broken over pages, we want it to be at chapters
 % if at all possible; hence the \penalty.
-\def\dochapentry#1#2{%
+\def\dochapentry#1#2#3{%
    \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
    \begingroup
      % Move the page numbers slightly to the right
      \advance\entryrightmargin by -0.05em
      \chapentryfonts
-     \tocentry{#1}{#2}%
+     \extrasecnoskip=0.4em % separate chapter number more
+     \tocentry{#1}{#2}{#3}%
    \endgroup
    \nobreak\vskip .25\baselineskip plus.1\baselineskip
 }
 
-\def\dosecentry#1#2{\begingroup
+\def\dosecentry#1#2#3{\begingroup
+  \secnowidth=\secnowidthchap
   \secentryfonts \leftskip=\tocindent
-  \tocentry{#1}{#2}%
+  \tocentry{#1}{#2}{#3}%
 \endgroup}
 
-\def\dosubsecentry#1#2{\begingroup
+\def\dosubsecentry#1#2#3{\begingroup
+  \secnowidth=\secnowidthsec
   \subsecentryfonts \leftskip=2\tocindent
-  \tocentry{#1}{#2}%
+  \tocentry{#1}{#2}{#3}%
 \endgroup}
 
-\def\dosubsubsecentry#1#2{\begingroup
+\def\dosubsubsecentry#1#2#3{\begingroup
+  \secnowidth=\secnowidthssec
   \subsubsecentryfonts \leftskip=3\tocindent
-  \tocentry{#1}{#2}%
+  \tocentry{#1}{#2}{#3}%
 \endgroup}
 
-% We use the same \entry macro as for the index entries.
-\let\tocentry = \entry
+% Used for the maximum width of a section number so we can align
+% section titles.
+\newdimen\secnowidth
+\secnowidth=0pt
+\newdimen\extrasecnoskip
+\extrasecnoskip=0pt
 
-% Space between chapter (or whatever) number and the title.
-\def\labelspace{\hskip1em \relax}
+% \tocentry{TITLE}{SEC NO}{PAGE}
+%
+\def\tocentry#1#2#3{%
+  \def\secno{#2}%
+  \ifx\empty\secno
+    \entry{#1}{#3}%
+  \else
+    \ifdim 0pt=\secnowidth
+      \setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}%
+    \else
+      \advance\secnowidth by \labelspace
+      \advance\secnowidth by \extrasecnoskip
+      \setbox0=\hbox to \secnowidth{%
+        #2\hskip\labelspace\hskip\extrasecnoskip\hfill}%
+    \fi
+    \entrycontskip=\wd0
+    \entry{\box0 #1}{#3}%
+  \fi
+}
+\newdimen\labelspace
+\labelspace=0.6em
 
 \def\chapentryfonts{\secfonts \rm}
 \def\secentryfonts{\textfonts}
@@ -7787,6 +7903,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   \tolerance=10000 \hbadness=10000
   \exdentamount=\defbodyindent
   {%
+    \def\^^M{}% for line continuation
+    %
     % defun fonts. We use typewriter by default (used to be bold) because:
     % . we're printing identifiers, they should be in tt in principle.
     % . in languages with many accents, such as Czech or French, it's
@@ -7819,6 +7937,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
 % Print arguments.  Use slanted for @def*, typewriter for @deftype*.
 \def\defunargs#1{%
   \bgroup
+    \def\^^M{}% for line continuation
     \df \ifdoingtypefn \tt \else \sl \fi
     \ifflagclear{txicodevaristt}{}%
        {\def\var##1{{\setregularquotes \ttsl ##1}}}%
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 291d6600af5..6189ef2d41d 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -6125,9 +6125,8 @@ performance of @value{tramp} actions.
 If @code{tramp-verbose} is greater than or equal to 11, @value{tramp}
 function call traces are written to the buffer @file{*trace tramp/foo*}.
 
-When @code{tramp-debug-command-messages} is non-@code{nil} and
-@code{tramp-verbose} is greater than or equal to 6, the debug buffer
-contains all messages with verbosity level 6 (sent and received
+When @code{tramp-debug-command-messages} is non-@code{nil}, the debug
+buffer contains all messages with verbosity level 6 (sent and received
 strings), and the entry and exit messages for the function
 @code{tramp-file-name-handler}.  This is intended for @value{tramp}
 maintainers, analyzing the remote commands for performance analysis.
diff --git a/etc/ChangeLog.1 b/etc/ChangeLog.1
index de6abff2881..68c15fc6e69 100644
--- a/etc/ChangeLog.1
+++ b/etc/ChangeLog.1
@@ -2624,7 +2624,7 @@
        * images/custom/right.xpm:
        * images/custom/right-pushed.xpm: New files.
 
-2008-05-07  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-07  Eric S. Raymond  <esr@thyrsus.com>
 
        * NEWS: Support for Meta-CVS removed.
 
@@ -3015,7 +3015,7 @@
 
        * NEWS: Mention desktop locking.
 
-2007-10-10  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-10  Eric S. Raymond  <esr@thyrsus.com>
 
        * NEWS: Explain the VC fileset changes a bit better.
 
@@ -6019,7 +6019,7 @@
        * Rename termcap to termcap.src, the historical name for an
        uninstalled termcap file.
 
-1995-06-28  Eric S. Raymond  <esr@spiff.gnu.ai.mit.edu>
+1995-06-28  Eric S. Raymond  <esr@thyrsus.com>
 
        * termcap.dat, termcap.ucb: Deleted and replaced.
 
@@ -6147,11 +6147,11 @@
 
        * MACHINES: Add section for NeXT, from Thorsten Ohl.
 
-1993-04-28  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-28  Eric S. Raymond  (esr@thyrsus.com)
 
        * NEWS: Documented picture-mode improvements.
 
-1993-04-25  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-25  Eric S. Raymond  (esr@thyrsus.com)
 
        * NEWS: Described the new properties of arrow keys and
        next-line-add-newlines.  Fixed up the GUD description, it was
@@ -6160,23 +6160,23 @@
 
        * news.texi: invocation-name now exists.
 
-1993-03-27  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * MORE.STUFF: Added.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * NEWS: Preserved jimb's last change (documenting kill on
        read-only buffers).
 
        Added documentation on new info features.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * spook.lines: Alpha-sorted this, and added some new hot buttons
        for the 1990s.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * MACHINES: Deleted some VMS caveats.  If the src and lisp
        ChangeLogs are correct, dired and mail and process control are now
@@ -6188,13 +6188,13 @@
 
        * NEWS: Changed.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * sex.6: Added 900-line support.
 
        * NEWS: Added news about the package finder.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * MACHINES: `Last updated 10 Feb 1992.' was obviously wrong, so
        I nuked it.  Let the file mod date serve.  Merged in APOLLO and
@@ -6205,7 +6205,7 @@
 
        * Makefile (relock, unlock): New productions.
 
-1993-03-18  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-18  Eric S. Raymond  (esr@thyrsus.com)
 
        Augean-stable cleaning time.  Partly to save space, but mostly to
        reduce the dizzying amount of *stuff* confronting someone exploring
@@ -6245,7 +6245,7 @@
        names as per convention.  Originals of all files merged still
        exist with =-names.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * XENIX: Nuked (moved to =XENIX).  The hackery it describes is
        no longer necessary in the presence of 19's function-key-map
@@ -6254,7 +6254,7 @@
 1993-03-10  Jim Blandy  (jimb@totoro.cs.oberlin.edu)
 
        * MACHINES: Update description of SYSVr3 and r4 support, due to
-       Eric Raymond's changes.
+       Eric S. Raymond's changes.
 
 1993-03-09  Jim Blandy  (jimb@totoro.cs.oberlin.edu)
 
@@ -6272,7 +6272,7 @@
 
        * NEWS: Document included tags tables.
 
-1992-07-22  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * Corrected the news about VC to reflect reality.
 
diff --git a/etc/DEBUG b/etc/DEBUG
index 1cc575598bf..7c54b488cad 100644
--- a/etc/DEBUG
+++ b/etc/DEBUG
@@ -1063,7 +1063,7 @@ recovering the contents of Emacs buffers from a core dump 
file.  You
 might also find those commands useful for displaying the list of
 buffers in human-readable format from within the debugger.
 
-*** Debugging Emacs with LLDB
+** Debugging Emacs with LLDB
 
 On systems where GDB is not available, like macOS with M1 chip, you
 can also use LLDB for Emacs debugging.
@@ -1101,36 +1101,183 @@ from GDB commands to corresponding LLDB commands there.
 
 ** Debugging Emacs on Android.
 
-Attaching GDB to Emacs running inside the Android application setup
-requires a special script found in the java/ directory, and a suitable
-GDB server binary to be present on the Android device, which is
-present on the free versions of Android.  Connecting to the device
-also requires the `adb' (Android Debug Bridge) utility, and telling
-the Android system to resume the Emacs process after startup requires
-the Java debugger (jdb).
+A script located in the java/ directory automates the procedures
+necessary run Emacs under a Gdb session on an Android device connected
+to a computer using USB.
+
+Its requirements are the `adb' (Android Debug Bridge) utility and the
+Java debugger (jdb), utilized to cue the Android system to resume the
+Emacs process after the debugger attaches.
 
 If all three of those tools are present, simply run (from the Emacs
 source directory):
 
   ../java/debug.sh -- [any extra arguments you wish to pass to gdb]
 
-After which, upon waiting a while, the GDB prompt will show up.
-
-If Emacs crashes and "JNI ERROR" shows up in the Android system log,
-then placing a breakpoint on:
-
-  break art::JavaVMExt::JniAbort
-
-will let you find the source of the crash.
+Several lines of debug information will be printed, after which the
+Gdb prompt should be displayed.
 
-If there is no `gdbserver' binary present on the device, then you can
-specify one to upload, like so:
+If there is no Gdbserver binary present on the device, then specify
+one to upload, like so:
 
   ../java/debug.sh --gdbserver /path/to/gdbserver
 
-In addition, when Emacs runs as a 64-bit process on a system
-supporting both 64 and 32-bit binaries, you must specify the path to a
-64-bit gdbserver binary.
+This Gdbserver should be statically linked or compiled using the
+Android NDK, and must target the same architecture as the debugee
+Emacs binary.  Older versions of the Android NDK (such as r24)
+distribute suitable Gdbserver binaries, usually located within
+
+  prebuilt/android-<arch>/gdbserver/gdbserver
+
+relative to the root of the NDK distribution.
+
+To attach Emacs to an existing process on a target device, use the
+`--attach-existing' argument to debug.sh:
+
+  ../java/debug.sh --attach-existing [other arguments]
+
+If multiple Emacs processes are running, debug.sh will display the
+names and PIDs of each running process, and prompt for the process
+that it should attach to.
+
+After Emacs starts, type:
+
+  (gdb) handle SIGUSR1 noprint pass
+
+to ignore the SIGUSR1 signal that is sent by the Android port's
+`select' emulation.  If this is overlooked, Emacs will stop each time
+a windowing event is received, which is probably unwanted.
+
+On top of the debugging procedure described above, Android also
+maintains a "logcat" buffer, where it prints backtraces during or
+after each crash.  Its contents are of interest when performing
+post-mortem debugging after a crash, and can also be retrieved through
+the `adb' tool, like so:
+
+  $ adb logcat
+
+There are three forms of crash messages printed by Android.  The first
+form is printed when a crash arises within Java code, and should
+resemble the following when printed in the logcat buffer:
+
+E AndroidRuntime: FATAL EXCEPTION: main
+E AndroidRuntime: Process: org.gnu.emacs, PID: 18057
+E AndroidRuntime: java.lang.RuntimeException: sample crash
+E AndroidRuntime:      at 
org.gnu.emacs.EmacsService.onCreate(EmacsService.java:308)
+E AndroidRuntime:      at 
android.app.ActivityThread.handleCreateService(ActivityThread.java:4485)
+E AndroidRuntime:      ... 9 more
+
+The second form is printed when a fatal signal (such as an abort, or
+segmentation fault) is raised within C code.  Here is an example of
+such a crash:
+
+F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x3 in 
tid 32644
+ (Emacs main thre), pid 32619 (org.gnu.emacs)
+F DEBUG   : Cmdline: org.gnu.emacs
+F DEBUG   : pid: 32619, tid: 32644, name: Emacs main thre  >>> org.gnu.emacs 
<<<
+F DEBUG   :       #00 pc 002b27b0  /.../lib/arm64/libemacs.so 
(sfnt_read_cmap_table+32)
+F DEBUG   :       #01 pc 002c4ee8  /.../lib/arm64/libemacs.so 
(sfntfont_read_cmap+84)
+F DEBUG   :       #02 pc 002c4dc4  /.../lib/arm64/libemacs.so 
(sfntfont_lookup_char+396)
+F DEBUG   :       #03 pc 002c23d8  /.../lib/arm64/libemacs.so 
(sfntfont_list+1688)
+F DEBUG   :       #04 pc 0021112c  /.../lib/arm64/libemacs.so 
(font_list_entities+864)
+F DEBUG   :       #05 pc 002138d8  /.../lib/arm64/libemacs.so 
(font_find_for_lface+1532)
+F DEBUG   :       #06 pc 00280c50  /.../lib/arm64/libemacs.so 
(fontset_find_font+2760)
+F DEBUG   :       #07 pc 0027cadc  /.../lib/arm64/libemacs.so 
(fontset_font+792)
+F DEBUG   :       #08 pc 0027c710  /.../lib/arm64/libemacs.so 
(face_for_char+412)
+F DEBUG   :       #09 pc 00217314  /.../lib/arm64/libemacs.so 
(Finternal_char_font+324)
+F DEBUG   :       #10 pc 00240d78  /.../lib/arm64/libemacs.so 
(exec_byte_code+3112)
+F DEBUG   :       #11 pc 001f5ff8  /.../lib/arm64/libemacs.so (Ffuncall+392)
+F DEBUG   :       #12 pc 001f3cf0  /.../lib/arm64/libemacs.so (eval_sub+2260)
+F DEBUG   :       #13 pc 001f853c  /.../lib/arm64/libemacs.so (Feval+80)
+F DEBUG   :       #14 pc 00240d78  /.../lib/arm64/libemacs.so 
(exec_byte_code+3112)
+F DEBUG   :       #15 pc 00240130  /.../lib/arm64/libemacs.so (Fbyte_code+120)
+F DEBUG   :       #16 pc 001f3d84  /.../lib/arm64/libemacs.so (eval_sub+2408)
+F DEBUG   :       #17 pc 00221d7c  /.../lib/arm64/libemacs.so 
(readevalloop+1748)
+F DEBUG   :       #18 pc 002201a0  /.../lib/arm64/libemacs.so (Fload+2544)
+F DEBUG   :       #19 pc 00221f3c  /.../lib/arm64/libemacs.so 
(save_match_data_load+88)
+F DEBUG   :       #20 pc 001f8414  /.../lib/arm64/libemacs.so 
(load_with_autoload_queue+252)
+F DEBUG   :       #21 pc 001f6550  /.../lib/arm64/libemacs.so 
(Fautoload_do_load+608)
+F DEBUG   :       #22 pc 00240d78  /.../lib/arm64/libemacs.so 
(exec_byte_code+3112)
+F DEBUG   :       #23 pc 001f5ff8  /.../lib/arm64/libemacs.so (Ffuncall+392)
+F DEBUG   :       #24 pc 001f1120  /.../lib/arm64/libemacs.so 
(Ffuncall_interactively+64)
+F DEBUG   :       #25 pc 001f5ff8  /.../lib/arm64/libemacs.so (Ffuncall+392)
+F DEBUG   :       #26 pc 001f8b8c  /.../lib/arm64/libemacs.so (Fapply+916)
+F DEBUG   :       #27 pc 001f137c  /.../lib/arm64/libemacs.so 
(Fcall_interactively+576)
+F DEBUG   :       #28 pc 00240d78  /.../lib/arm64/libemacs.so 
(exec_byte_code+3112)
+F DEBUG   :       #29 pc 001f5ff8  /.../lib/arm64/libemacs.so (Ffuncall+392)
+F DEBUG   :       #30 pc 0016d054  /.../lib/arm64/libemacs.so 
(command_loop_1+1344)
+F DEBUG   :       #31 pc 001f6d90  /.../lib/arm64/libemacs.so 
(internal_condition_case+92)
+F DEBUG   :       #32 pc 0016cafc  /.../lib/arm64/libemacs.so 
(command_loop_2+48)
+F DEBUG   :       #33 pc 001f6660  /.../lib/arm64/libemacs.so 
(internal_catch+84)
+F DEBUG   :       #34 pc 0016c288  /.../lib/arm64/libemacs.so 
(command_loop+264)
+F DEBUG   :       #35 pc 0016c0d8  /.../lib/arm64/libemacs.so 
(recursive_edit_1+144)
+F DEBUG   :       #36 pc 0016c4fc  /.../lib/arm64/libemacs.so 
(Frecursive_edit+348)
+F DEBUG   :       #37 pc 0016af9c  /.../lib/arm64/libemacs.so 
(android_emacs_init+7132)
+F DEBUG   :       #38 pc 002ab8d4  /.../lib/arm64/libemacs.so 
(Java_org_gnu_emacs_...+3816)
+
+Where the first line (the one containing "libc") mentions the number
+of the fatal signal, the address of any VM fault, and the name and ID
+of the thread which crashed.  Subsequent lines then contain a
+backtrace, recounting each function in the call stack culminating in
+the crash.
+
+The third form is printed when Emacs misuses the JVM in some fashion
+that is detected by the Android CheckJNI facility.  It looks like:
+
+A/art﹕ art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: ...
+A/art﹕ art/runtime/check_jni.cc:65]     in call to CallVoidMethodV
+A/art﹕ art/runtime/check_jni.cc:65]     from void 
android.os.MessageQueue.nativePollOnce(long, int)
+A/art﹕ art/runtime/check_jni.cc:65] "main" prio=5 tid=1 Runnable
+A/art﹕ art/runtime/check_jni.cc:65]   | group="main" sCount=0 dsCount=0 
obj=0x87d30ef0 self=0xb4f07800
+A/art﹕ art/runtime/check_jni.cc:65]   | sysTid=18828 nice=-11 cgrp=apps 
sched=0/0 handle=0xb6fdeec8
+A/art﹕ art/runtime/check_jni.cc:65]   | state=R schedstat=( 2249126546 
506089308 3210 ) utm=183 stm=41 core=3 HZ=100
+A/art﹕ art/runtime/check_jni.cc:65]   | stack=0xbe0c8000-0xbe0ca000 
stackSize=8MB
+A/art﹕ art/runtime/check_jni.cc:65]   | held mutexes= "mutator lock"(shared 
held)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #00 pc 00004640  
/system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, 
ucontext*)+23)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #01 pc 00002e8d  
/system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, 
ucontext*)+8)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #02 pc 00248381  
/system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, 
std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+68)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #03 pc 0022cd0b  
/system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, 
std::__1::char_traits<char> >&) const+146)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #04 pc 000b189b  
/system/lib/libart.so (art::JniAbort(char const*, char const*)+582)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #05 pc 000b1fd5  
/system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+60)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #06 pc 000b50e5  
/system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char 
const*)+1284)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #07 pc 000bc59f  
/system/lib/libart.so (art::CheckJNI::CallVoidMethodV(_JNIEnv*, _jobject*, 
_jmethodID*, std::__va_list)+30)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #08 pc 00063803  
/system/lib/libandroid_runtime.so (???)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #09 pc 000776bd  
/system/lib/libandroid_runtime.so 
(android::NativeDisplayEventReceiver::dispatchVsync(long long, int, unsigned 
int)+40)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #10 pc 00077885  
/system/lib/libandroid_runtime.so 
(android::NativeDisplayEventReceiver::handleEvent(int, int, void*)+80)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #11 pc 00010f6f  
/system/lib/libutils.so (android::Looper::pollInner(int)+482)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #12 pc 00011019  
/system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+92)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #13 pc 000830c1  
/system/lib/libandroid_runtime.so 
(android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+22)
+A/art﹕ art/runtime/check_jni.cc:65]   native: #14 pc 000b22d7  
/system/framework/arm/boot.oat 
(Java_android_os_MessageQueue_nativePollOnce__JI+102)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
android.os.MessageQueue.nativePollOnce(Native method)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
android.os.MessageQueue.next(MessageQueue.java:143)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
android.os.Looper.loop(Looper.java:130)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
android.app.ActivityThread.main(ActivityThread.java:5832)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
java.lang.reflect.Method.invoke!(Native method)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
java.lang.reflect.Method.invoke(Method.java:372)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
+A/art﹕ art/runtime/check_jni.cc:65]   at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
+A/art﹕ art/runtime/check_jni.cc:65]
+
+In such situations, the first line explains what infraction Emacs
+committed, while the ensuing ones print backtraces for each running
+Java thread at the time of the error.
+
+If Emacs is executing on Android 5.0 and later, placing a breakpoint
+on
+
+  (gdb) break art::JavaVMExt::JniAbort
+
+will set a breakpoint that is hit each time such an error is detected.
+
+Since the logcat output is always rapidly being amended, it is worth
+piping it to a file or shell command buffer, and then searching for
+keywords such as "AndroidRuntime", "Fatal signal", or "JNI DETECTED
+ERROR IN APPLICATION".
+
+Once in a blue moon, it proves necessary to debug Java rather than C
+code.  To this end, the `--jdb' option will attach the Java debugger
+instead of gdbserver.  Lametably, it seems impossible to debug both C
+and Java code in concert.
 
 
 This file is part of GNU Emacs.
diff --git a/etc/MACHINES b/etc/MACHINES
index 751d59932c5..c9f6ec265d8 100644
--- a/etc/MACHINES
+++ b/etc/MACHINES
@@ -143,6 +143,14 @@ the list at the end of this file.
 
   See the file java/INSTALL for detailed installation instructions.
 
+  It is also possible to build Emacs for Android systems without using
+  GUI capabilities provided by the Android port.  We do not know
+  exactly which configurations this works on, but the installation
+  instructions for such a build should be the same as for any Unix
+  system.  (This does in turn imply that such a build must be carried
+  out on an Android device itself utilizing development tools provided
+  by third party package repositories.)
+
 
 * Obsolete platforms
 
diff --git a/etc/NEWS b/etc/NEWS
index 16dd7d5f791..c97df11042d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -70,9 +70,9 @@ example, as part of preview for iconified frames.
 
 ---
 ** New user option 'menu-bar-close-window'.
-When non-nil, selecting Close from the File menu or clicking Close in
-the tool bar will result in the current window being closed, if
-possible.
+When non-nil, selecting "Close" from the "File" menu or clicking
+"Close" in the tool bar will result in the current window being
+closed, if possible.
 
 +++
 ** 'write-region-inhibit-fsync' now defaults to t in interactive mode,
@@ -134,8 +134,12 @@ transform function 'project-uniquify-dirname-transform'.
 The code that allowed "..." to be expanded in the "*Backtrace*" buffer
 should now work anywhere the data is generated by 'cl-print'.
 
+*** The 'backtrace-ellipsis' button is replaced by 'cl-print-ellipsis'.
+
 *** hash-tables' contents can be expanded via the ellipsis.
 
+*** Modes can control the expansion via 'cl-print-expand-ellipsis-function'.
+
 ** Modeline elements can now be right-aligned.
 Anything following the symbol 'mode-line-format-right-align' in
 'mode-line-format' will be right-aligned.  Exactly where it is
@@ -145,6 +149,29 @@ right-aligned to is controlled by the new user option
 
 * Editing Changes in Emacs 30.1
 
+---
+** New global minor mode 'kill-ring-deindent-mode'.
+When enabled, text being saved to the kill ring will be de-indented by
+the column number at its start.  For example, saving the entire
+function call within:
+
+foo ()
+{
+  long_function_with_several_arguments (argument_1_compute (),
+                                       argument_2_compute (),
+                                       argument_3_compute ());
+}
+
+will save:
+
+long_function_with_several_arguments (argument_1_compute (),
+                                     argument_2_compute (),
+                                     argument_3_compute ())
+
+to the kill ring, omitting the two columns of extra indentation that
+would otherwise be present in the second and third lines of the
+function call.
+
 +++
 ** Emacs now has better support for touchscreen devices.
 Many touch screen gestures are now implemented and translated into
@@ -268,6 +295,15 @@ using this new option.  (Or set 'display-buffer-alist' 
directly.)
 
 ** Eshell
 
++++
+*** New builtin Eshell command 'compile'.
+This command runs another command, sending its output to a compilation
+buffer when the command would output interactively.  This can be useful
+when defining aliases so that they produce a compilation buffer when
+appropriate, but still allow piping the output elsewhere if desired.
+For more information, see the "(eshell) Built-ins" node in the Eshell
+manual.
+
 +++
 *** New splice operator for Eshell dollar expansions.
 Dollar expansions in Eshell now let you splice the elements of the
@@ -321,6 +357,14 @@ to load the edited aliases.
 Running 'rgrep' in Eshell now uses the Emacs grep facility instead of
 calling external rgrep.
 
+** Pcomplete
+
+---
+*** New user option 'pcomplete-remote-file-ignore'.
+When this option is non-nil, remote file names are not completed by
+Pcomplete.  Packages, like 'shell-mode', could set this in order to
+suppress remote file name completion at all.
+
 ** Shell Mode
 
 +++
@@ -416,6 +460,13 @@ the kill ring.  Alternate links are optional metadata that 
HTML pages
 use for linking to their alternative representations, such as
 translated versions or associated RSS feeds.
 
++++
+*** 'eww-open-in-new-buffer' supports the prefix argument.
+When invoked with the prefix argument ('C-u'),
+'eww-open-in-new-buffer' will not make the new buffer the current one.
+This is useful for continuing reading the URL in the current buffer
+when the new URL is fetched.
+
 ** go-ts-mode
 
 +++
@@ -478,6 +529,15 @@ project, that you can quickly select using 
'project-switch-project'
 When non-nil, package specifications with side-effects for building
 software will be used when building a package.
 
+---
+*** New command to start an inferior Emacs loading only specific packages.
+The new command 'package-isolate' will start a new Emacs process, as
+a sub-process of Emacs where you invoke the command, in a way that
+causes the new process to load only some of the installed packages.
+The command prompts for the packages to activate in this
+sub-process, and is intended for testing Emacs and/or the packages
+in a clean environment.
+
 ** Flymake
 
 +++
@@ -619,12 +679,12 @@ of the accessibility of remote files can now time out if
 ** Notifications
 
 +++
-*** Allow to use Icon Naming Specification for app-icon
+*** Allow to use Icon Naming Specification for ':app-icon'.
 You can use a symbol as the value for ':app-icon' to provide icon name
 without specifying a file, like this:
 
-  (notifications-notify
-    :title "I am playing music" :app-icon 'multimedia-player)
+    (notifications-notify
+      :title "I am playing music" :app-icon 'multimedia-player)
 
 ** Image Dired
 
@@ -737,20 +797,32 @@ The compatibility aliases 'x-defined-colors', 
'x-color-defined-p',
 'x-color-values', and 'x-display-color-p' are now obsolete.
 
 +++
-** 'easy-mmode-define-{minor-mode,global-mode}' aliases are now obsolete.
+** 'easy-mmode-define-{minor,global}-mode' aliases are now obsolete.
 Use 'define-minor-mode' and 'define-globalized-minor-mode' instead.
 
 
 * Lisp Changes in Emacs 30.1
 
 ** 'defadvice' is marked as obsolete.
-See (info "(elisp)Porting Old Advice") for help converting them
-to use `advice-add` or `define-advice instead.
+See the "(elisp) Porting Old Advice" node for help converting them
+to use 'advice-add' or 'define-advice' instead.
+
++++
+** Desktop notifications are now supported on the Haiku operating system.
+The new function 'haiku-notifications-notify' provides a subset of the
+capabilities of the 'notifications-notify' function in a manner
+analogous to 'w32-notification-notify'.
+
++++
+** New value 'if-regular' for the REPLACE argument to 'insert-file-contents'.
+It results in 'insert-file-contents' erasing the buffer instead of
+preserving markers if the file being inserted is not a regular file,
+rather than signaling an error.
 
 +++
 ** New variable 'current-key-remap-sequence'.
 It is bound to the key sequence that caused a call to a function bound
-within `function-key-map' or `input-decode-map' around those calls.
+within 'function-key-map' or 'input-decode-map' around those calls.
 
 +++
 ** New variables describing the names of built in programs.
diff --git a/etc/NEWS.28 b/etc/NEWS.28
index 6ffe39b9493..89ef25bb32d 100644
--- a/etc/NEWS.28
+++ b/etc/NEWS.28
@@ -3150,7 +3150,7 @@ declared obsolete.
 This was a compatibility kludge which is no longer needed.
 
 ** Some libraries obsolete since Emacs 23 have been removed:
-ledit.el, lmenu.el, lucid.el and old-whitespace.el.
+ledit.el, levents.el, lmenu.el, lucid.el and old-whitespace.el.
 
 ** Some functions and variables obsolete since Emacs 23 have been removed:
 'GOLD-map', 'advertised-xscheme-send-previous-expression',
diff --git a/etc/NEWS.29 b/etc/NEWS.29
index 9e6f0c16bcd..e74cbee4a53 100644
--- a/etc/NEWS.29
+++ b/etc/NEWS.29
@@ -22,9 +22,42 @@ When you add a new item, use the appropriate mark if you are 
sure it
 applies, and please also update docstrings as needed.
 
 
+* Installation Changes in Emacs 29.2
+
+
+* Startup Changes in Emacs 29.2
+
+
+* Changes in Emacs 29.2
+
+
+* Editing Changes in Emacs 29.2
+
+
+* Changes in Specialized Modes and Packages in Emacs 29.2
+
+** Tramp
+
++++
+*** New user option 'tramp-show-ad-hoc-proxies'.
+When non-nil, ad-hoc definitions are kept in remote file names instead
+of showing the shortcuts.
+
+
+* New Modes and Packages in Emacs 29.2
+
+
+* Incompatible Lisp Changes in Emacs 29.2
+
+
+* Lisp Changes in Emacs 29.2
+
+
+* Changes in Emacs 29.2 on Non-Free Operating Systems
+
+
 * Installation Changes in Emacs 29.1
 
----
 ** Ahead-of-time native compilation can now be requested via configure.
 Use '--with-native-compilation=aot' to request that all the Lisp files
 in the Emacs tree should be natively compiled ahead of time.  (This is
@@ -32,7 +65,6 @@ slow on most machines.)
 
 This feature existed in Emacs 28.1, but was less easy to request.
 
-+++
 ** Emacs can be built with the tree-sitter parsing library.
 This library, together with separate grammar libraries for each
 language, provides incremental parsing capabilities for several
@@ -85,26 +117,22 @@ available from their sites, as these libraries are in 
constant
 development and occasionally add features and fix important bugs to
 follow the advances in the programming languages they support.
 
-+++
 ** Emacs can be built with built-in support for accessing SQLite databases.
 This uses the popular sqlite3 library, and can be disabled by using
 the '--without-sqlite3' option to the 'configure' script.
 
-+++
 ** Support for the WebP image format.
 This support is built by default when the libwebp library is
 available, and includes support for animated WebP images.  To disable
 WebP support, use the '--without-webp' configure flag.  Image
 specifiers can now use ':type webp'.
 
----
 ** Emacs now installs the ".pdmp" file using a unique fingerprint in the name.
 The file is typically installed using a file name akin to
 "...dir/libexec/emacs/29.1/x86_64-pc-linux-gnu/emacs-<fingerprint>.pdmp".
 If a constant file name is required, the file can be renamed to
 "emacs.pdmp", and Emacs will find it during startup anyway.
 
----
 ** Emacs on X now uses XInput 2 for input events.
 If your X server has support and you have the XInput 2 development
 headers installed, Emacs will use the X Input Extension for handling
@@ -114,7 +142,6 @@ option '--without-xinput2' to disable this support.
 '(featurep 'xinput2)' can be used to test for the presence of XInput 2
 support from Lisp programs.
 
----
 ** Emacs can now be optionally built with the Cairo XCB backend.
 Configure Emacs with the '--with-cairo-xcb' option to use the Cairo
 XCB backend; the default is not to use it.  This backend makes Emacs
@@ -124,7 +151,6 @@ a display connection to the same terminal; this could 
happen, for
 example, if you repeatedly visit files via emacsclient in a single
 client frame, each time deleting the frame with 'C-x C-c'.
 
-+++
 ** Emacs now supports being built with pure GTK.
 To use this option, make sure the GTK 3 (version 3.22.23 or later) and
 Cairo development files are installed, and configure Emacs with the
@@ -142,7 +168,6 @@ automatically switch to text-mode interface (thus emulating 
'-nw') if
 it cannot determine the default display; it will instead complain and
 ask you to invoke it with the explicit '-nw' option.
 
-+++
 ** Emacs has been ported to the Haiku operating system.
 The configuration process should automatically detect and build for
 Haiku.  There is also an optional window-system port to Haiku, which
@@ -160,7 +185,6 @@ Unlike X, there is no compile-time option to enable or 
disable
 double-buffering; it is always enabled.  To disable it, change the
 frame parameter 'inhibit-double-buffering' instead.
 
----
 ** Emacs no longer reduces the size of the Japanese dictionary.
 Building Emacs includes generation of a Japanese dictionary, which is
 used by Japanese input methods.  Previously, the build included a step
@@ -175,7 +199,6 @@ by saying
 
 after deleting "lisp/leim/ja-dic/ja-dic.el".
 
----
 ** The docstrings of preloaded files are not in "etc/DOC" any more.
 Instead, they're fetched as needed from the corresponding ".elc"
 files, as was already the case for all the non-preloaded files.
@@ -183,7 +206,6 @@ files, as was already the case for all the non-preloaded 
files.
 
 * Startup Changes in Emacs 29.1
 
-+++
 ** '--batch' and '--script' now adjust the garbage collection levels.
 These switches now set 'gc-cons-percentage' to 1.0 (up from the
 default of 0.1).  This means that batch processes will typically use
@@ -191,7 +213,6 @@ more memory than before, but use less time doing garbage 
collection.
 Batch jobs that are supposed to run for a long time should adjust the
 limit back down again.
 
-+++
 ** Emacs can now be used more easily in an executable script.
 If you start an executable script with
 
@@ -202,16 +223,13 @@ and then execute the rest of the script file as Emacs 
Lisp.  When it
 reaches the end of the script, Emacs will exit with an exit code from
 the value of the final form.
 
-+++
 ** Emacs now supports setting 'user-emacs-directory' via '--init-directory'.
 Use the '--init-directory' command-line option to set
 'user-emacs-directory'.
 
-+++
 ** Emacs now has a '--fingerprint' option.
 This will output a string identifying the current Emacs build, and exit.
 
-+++
 ** New hook 'after-pdump-load-hook'.
 This is run at the end of the Emacs startup process, and is meant to
 be used to reinitialize data structures that would normally be done at
@@ -219,14 +237,12 @@ load time.
 
 ** Native Compilation
 
-+++
 *** New command 'native-compile-prune-cache'.
 This command deletes old subdirectories of the eln cache (but not the
 ones for the current Emacs version).  Note that subdirectories of the
 system directory where the "*.eln" files are installed (usually, the
 last entry in 'native-comp-eln-load-path') are not deleted.
 
-+++
 *** New function 'startup-redirect-eln-cache'.
 This function can be called in your init files to change the
 user-specific directory where Emacs stores the "*.eln" files produced
@@ -237,7 +253,6 @@ of 'user-emacs-directory'.
 
 * Incompatible changes in Emacs 29.1
 
-+++
 ** The image commands have changed key bindings.
 In previous Emacs versions, the '+', '-' and 'r' keys were bound when
 point was over an image.  In Emacs 29.1, additional commands have been
@@ -247,7 +262,6 @@ moved to the 'i' prefix keymap, so '+' is now 'i +', '-' is 
now 'i -',
 and 'r' is now 'i r'.  In addition, these commands are now repeating,
 so you can rotate an image twice by saying 'i r r', for instance.
 
-+++
 ** Emacs now picks the correct coding-system for X input methods.
 Previously, Emacs would use 'locale-coding-system' for input
 methods, which could in some circumstances be incorrect, especially
@@ -260,7 +274,6 @@ changed the coding system used to decode X keyboard input 
must adjust
 their customizations to 'locale-coding-system' to the variable
 'x-input-coding-system' instead.
 
-+++
 ** Bookmarks no longer include context for encrypted files.
 If you're visiting an encrypted file, setting a bookmark no longer
 includes excerpts from that buffer in the bookmarks file.  This is
@@ -268,7 +281,6 @@ implemented by the new hook 
'bookmark-inhibit-context-functions',
 where packages can register a function which returns non-nil for file
 names to be excluded from adding such excerpts.
 
----
 ** 'show-paren-mode' is now disabled in 'special-mode' buffers.
 In Emacs versions previous to Emacs 28.1, 'show-paren-mode' defaulted
 off.  In Emacs 28.1, the mode was switched on in all buffers.  In
@@ -279,7 +291,6 @@ init file:
 
     (setopt show-paren-predicate t)
 
-+++
 ** Explicitly-set read-only state is preserved when reverting a buffer.
 If you use the 'C-x C-q' command to change the read-only state of the
 buffer and then revert it, Emacs would previously use the file
@@ -287,14 +298,12 @@ permission bits to determine whether the buffer should be 
read-only
 after reverting the buffer.  Emacs now remembers the decision made in
 'C-x C-q'.
 
----
 ** The Gtk selection face is no longer used for the region.
 The combination of a Gtk-controlled background and a foreground color
 controlled by the internal Emacs machinery led to low-contrast faces
 in common default setups.  Emacs now uses the same 'region' face on
 Gtk and non-Gtk setups.
 
----
 ** 'C-h f' and 'C-h x' may now require confirmation when you press 'RET'.
 If the text in the minibuffer cannot be completed to a single function
 or command, typing 'RET' will not automatically complete to the shortest
@@ -306,12 +315,10 @@ second 'RET'.
 
 ** Dired
 
----
 *** 'w' ('dired-copy-filename-as-kill') has changed behavior.
 If there are several files marked, file names containing space and
 quote characters will be quoted "like this".
 
----
 *** The 'd' command now more consistently skips dot files.
 In previous Emacs versions, commands like 'C-u 10 d' would put the "D"
 mark on the next ten files, no matter whether they were dot files
@@ -319,10 +326,8 @@ mark on the next ten files, no matter whether they were 
dot files
 mouse (in 'transient-mark-mode') and then hitting 'd' would skip dot
 files.  These now work equivalently.
 
-+++
 ** Warning about "eager macro-expansion failure" is now an error.
 
----
 ** Previously, the X "reverseVideo" value at startup was heeded for all frames.
 This meant that if you had a "reverseVideo" resource on the initial
 display, and then opened up a new frame on a display without any
@@ -330,26 +335,21 @@ explicit "reverseVideo" setting, it would get heeded 
there, too.  (This
 included terminal frames.)  In Emacs 29, the "reverseVideo" X resource
 is handled like all the other X resources, and set on a per-frame basis.
 
-+++
 ** 'E' in 'query-replace' now edits the replacement with exact case.
 Previously, this command did the same as 'e'.
 
----
 ** '/ a' in "*Packages*" buffer now limits by archive name(s) instead of 
regexp.
 
-+++
 ** Setting the goal columns now also affects '<prior>' and '<next>'.
 Previously, 'C-x C-n' only affected 'next-line' and 'previous-line',
 but it now also affects 'scroll-up-command' and 'scroll-down-command'.
 
----
 ** Isearch in "*Help*" and "*info*" now char-folds quote characters by default.
 This means that you can say 'C-s `foo' (GRAVE ACCENT) if the buffer
 contains "‘foo" (LEFT SINGLE QUOTATION MARK) and the like.  These
 quotation characters look somewhat similar in some fonts.  To switch
 this off, disable the new 'isearch-fold-quotes-mode' minor mode.
 
----
 ** Sorting commands no longer necessarily change modification status.
 In earlier Emacs versions, commands like 'sort-lines' would always
 change buffer modification status to "modified", whether they changed
@@ -357,19 +357,16 @@ something in the buffer or not.  This has been changed: 
the buffer is
 marked as modified only if the sorting ended up actually changing the
 contents of the buffer.
 
----
 ** 'string-lines' handles trailing newlines differently.
 It no longer returns an empty final string if the string ends with a
 newline.
 
----
 ** 'TAB' and '<backtab>' are now bound in 'button-map'.
 This means that if point is on a button, 'TAB' will take you to the
 next button, even if the mode has bound it to something else.  This
 also means that 'TAB' on a button in an 'outline-minor-mode' heading
 will move point instead of collapsing the outline.
 
----
 ** 'outline-minor-mode-cycle-map' is now parent of 'outline-minor-mode'.
 Instead of adding text property 'keymap' with 'outline-minor-mode-cycle'
 on outline headings in 'outline-minor-mode', the keymap
@@ -378,12 +375,10 @@ But keybindings in 'outline-minor-mode-cycle' still take 
effect
 only on outline headings because they are bound with the help of
 'outline-minor-mode-cycle--bind' that checks if point is on a heading.
 
----
 ** 'Info-default-directory-list' is no longer populated at Emacs startup.
 If you have code in your init file that removes directories from
 'Info-default-directory-list', this will no longer work.
 
----
 ** 'C-k' no longer deletes files in 'ido-mode'.
 To get the previous action back, put something like the following in
 your Init file:
@@ -391,14 +386,12 @@ your Init file:
     (require 'ido)
     (keymap-set ido-file-completion-map "C-k" #'ido-delete-file-at-head)
 
----
 ** New user option 'term-clear-full-screen-programs'.
 By default, term.el will now work like most terminals when displaying
 full-screen programs: When they exit, the output is cleared, leaving
 what was displayed in the window before the programs started.  Set
 this user option to nil to revert back to the old behavior.
 
----
 ** Support for old EIEIO functions is not autoloaded any more.
 You need an explicit '(require 'eieio-compat)' to use 'defmethod'
 and 'defgeneric' (which were made obsolete in Emacs 25.1 by
@@ -406,11 +399,9 @@ and 'defgeneric' (which were made obsolete in Emacs 25.1 by
 Similarly you might need to '(require 'eieio-compat)' before loading
 files that were compiled with an old EIEIO (Emacs<25).
 
----
 ** 'C-x 8 .' has been moved to 'C-x 8 . .'.
 This is to open up the 'C-x 8 .' map to bind further characters there.
 
----
 ** 'C-x 8 =' has been moved to 'C-x 8 = ='.
 You can now use 'C-x 8 =' to insert several characters with macron;
 for example, 'C-x 8 = a' will insert U+0101 LATIN SMALL LETTER A WITH
@@ -424,12 +415,10 @@ For consistency with remote connections, Eshell now uses 
'exec-path'
 to determine the execution path on the local or remote system, instead
 of using the PATH environment variable directly.
 
----
 *** 'source' and '.' no longer accept the '--help' option.
 This is for compatibility with the shell versions of these commands,
 which don't handle options like '--help' in any special way.
 
-+++
 *** String delimiters in argument predicates/modifiers are more restricted.
 Previously, some argument predicates/modifiers allowed arbitrary
 characters as string delimiters.  To provide more unified behavior
@@ -438,11 +427,9 @@ been restricted to "...", '...', /.../, |...|, (...), 
[...], <...>,
 and {...}.  See the "(eshell) Argument Predication and Modification"
 node in the Eshell manual for more details.
 
-+++
 *** Eshell pipelines now only pipe stdout by default.
 To pipe both stdout and stderr, use the '|&' operator instead of '|'.
 
----
 ** 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
@@ -452,12 +439,10 @@ 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.
 
----
 ** The Tamil input methods no longer insert Tamil digits.
 The input methods 'tamil-itrans' and 'tamil-inscript' no longer insert
 the Tamil digits, as those digit characters are not used nowadays by
@@ -465,7 +450,6 @@ speakers of the Tamil language.  To get back the previous 
behavior,
 use the new 'tamil-itrans-digits' and 'tamil-inscript-digits' input
 methods instead.
 
-+++
 ** New variable 'current-time-list' governing default timestamp form.
 Functions like 'current-time' now yield '(TICKS . HZ)' timestamps if
 this new variable is nil.  The variable defaults to t, which means
@@ -476,7 +460,6 @@ Developers are encouraged to test timestamp-related code 
with this
 variable set to nil, as it will default to nil in a future Emacs
 version and will be removed some time after that.
 
-+++
 ** Functions that recreate the "*scratch*" buffer now also initialize it.
 When functions like 'other-buffer' and 'server-execute' recreate
 "*scratch*", they now also insert 'initial-scratch-message' and set
@@ -484,7 +467,6 @@ the major mode according to 'initial-major-mode', like at 
Emacs
 startup.  Previously, these functions ignored
 'initial-scratch-message' and left "*scratch*" in 'fundamental-mode'.
 
----
 ** Naming of Image-Dired thumbnail files has changed.
 Names of thumbnail files generated when 'image-dired-thumbnail-storage'
 is 'image-dired' now always end in ".jpg".  This fixes various issues
@@ -493,25 +475,21 @@ will not be used in Emacs 29, and vice-versa.  If disk 
space is an
 issue, consider deleting the 'image-dired-dir' directory (usually
 "~/.emacs.d/image-dired/") after upgrading to Emacs 29.
 
----
 ** The 'rlogin' method in the URL library is now obsolete.
 Emacs will now display a warning if you request a URL like
 "rlogin://foo@example.org".
 
----
 ** Setting 'url-gateway-method' to 'rlogin' is now obsolete.
 Emacs will now display a warning when setting it to that value.
 The user options 'url-gateway-rlogin-host',
 'url-gateway-rlogin-parameters', and 'url-gateway-rlogin-user-name'
 are also obsolete.
 
----
 ** The user function 'url-irc-function' now takes a SCHEME argument.
 The user option 'url-irc-function' is now called with a sixth argument
 corresponding to the scheme portion of the target URL.  For example,
 this would be "ircs" for a URL like "ircs://irc.libera.chat".
 
----
 ** The linum.el library is now obsolete.
 We recommend using either the built-in 'display-line-numbers-mode', or
 the 'nlinum' package from GNU ELPA instead.  The former has better
@@ -536,40 +514,31 @@ performance, but the latter is closer to a drop-in 
replacement.
 
     (require 'linum)
 
----
 ** The thumbs.el library is now obsolete.
 We recommend using the 'image-dired' command instead.
 
----
 ** The autoarg.el library is now marked obsolete.
 This library provides the 'autoarg-mode' and 'autoarg-kp-mode' minor
 modes to emulate the behavior of the historical editor Twenex Emacs.
 We believe it is no longer useful.
 
----
 ** The quickurl.el library is now obsolete.
 Use 'abbrev', 'skeleton' or 'tempo' instead.
 
----
 ** The rlogin.el library, and the 'rsh' command are now obsolete.
 Use something like 'M-x shell RET ssh <host> RET' instead.
 
----
 ** The url-about.el library is now obsolete.
 
----
 ** The autoload.el library is now obsolete.
 It is superseded by the new loaddefs-gen.el library.
 
----
 ** The netrc.el library is now obsolete.
 Use the 'auth-source-netrc-parse-all' function in auth-source.el
 instead.
 
----
 ** The url-dired.el library is now obsolete.
 
----
 ** The fast-lock.el and lazy-lock.el libraries have been removed.
 They have been obsolete since Emacs 22.1.
 
@@ -577,7 +546,6 @@ The variable 'font-lock-support-mode' is occasionally 
useful for
 debugging purposes.  It is now a regular variable (instead of a user
 option) and can be set to nil to disable Just-in-time Lock mode.
 
-+++
 ** The 'utf-8-auto' coding-system now produces BOM on encoding.
 This is actually a bugfix, since this is how 'utf-8-auto' was
 documented from day one; it just didn't behave according to
@@ -594,7 +562,6 @@ encoding, only for decoding.
 
 * Changes in Emacs 29.1
 
-+++
 ** New user option 'major-mode-remap-alist' to specify favorite major modes.
 This user option lets you remap the default modes (e.g. 'perl-mode' or
 'latex-mode') to your favorite ones (e.g. 'cperl-mode' or
@@ -603,15 +570,12 @@ undesirable side effects.
 This applies to all modes specified via 'auto-mode-alist', file-local
 variables, etc.
 
----
 ** Emacs now supports Unicode Standard version 15.0.
 
----
 ** New user option 'electric-quote-replace-consecutive'.
 This allows you to disable the default behavior of consecutive single
 quotes being replaced with a double quote.
 
----
 ** Emacs is now capable of editing files with very long lines.
 The display of long lines has been optimized, and Emacs should no
 longer choke when a buffer on display contains long lines.  The
@@ -648,7 +612,6 @@ access portions of the buffer outside of the narrowed 
region.
 The new function 'long-line-optimizations-p' returns non-nil when
 these optimizations are in effect in the current buffer.
 
-+++
 ** New command to change the font size globally.
 To increase the font size, type 'C-x C-M-+' or 'C-x C-M-='; to
 decrease it, type 'C-x C-M--'; to restore the font size, type 'C-x
@@ -660,7 +623,6 @@ increase and decrease the font size globally.  
Additionally, the
 user option 'global-text-scale-adjust-resizes-frames' controls whether
 the frames are resized when the font size is changed.
 
----
 ** New config variable 'syntax-wholeline-max' to reduce the cost of long lines.
 This variable is used by some operations (mostly syntax-propertization
 and font-locking) to treat lines longer than this variable as if they
@@ -672,13 +634,11 @@ can recover the previous behavior with:
 
     (setq syntax-wholeline-max most-positive-fixnum)
 
----
 ** New bindings in 'find-function-setup-keys' for 'find-library'.
 When 'find-function-setup-keys' is enabled, 'C-x L' is now bound to
 'find-library', 'C-x 4 L' is now bound to 'find-library-other-window'
 and 'C-x 5 L' is now bound to 'find-library-other-frame'.
 
-+++
 ** New key binding after 'M-x' or 'M-X': 'M-X'.
 Emacs allows different completion predicates to be used with 'M-x'
 (i.e., 'execute-extended-command') via the
@@ -688,10 +648,8 @@ especially relevant to the current buffer.  Emacs now 
allows toggling
 between these modes while the user is inputting a command by hitting
 'M-X' while in the minibuffer.
 
----
 ** Interactively, 'kill-buffer' will now offer to save the buffer if unsaved.
 
----
 ** New commands 'duplicate-line' and 'duplicate-dwim'.
 'duplicate-line' duplicates the current line the specified number of times.
 'duplicate-dwim' duplicates the region if it is active.  If not, it
@@ -700,10 +658,8 @@ duplicated on its right-hand side.  The new user option
 'duplicate-line-final-position' specifies where to move point
 after duplicating a line.
 
----
 ** Files with the ".eld" extension are now visited in 'lisp-data-mode'.
 
-+++
 ** 'network-lookup-address-info' can now check numeric IP address validity.
 Specifying 'numeric' as the new optional HINTS argument makes it
 check if the passed address is a valid IPv4/IPv6 address (without DNS
@@ -712,23 +668,19 @@ traffic).
     (network-lookup-address-info "127.1" 'ipv4 'numeric)
     => ([127 0 0 1 0])
 
-+++
 ** New command 'find-sibling-file'.
 This command jumps to a file considered a "sibling file", which is
 determined according to the new user option 'find-sibling-rules'.
 
-+++
 ** New user option 'delete-selection-temporary-region'.
 When non-nil, 'delete-selection-mode' will only delete the temporary
 regions (usually set by mouse-dragging or shift-selection).
 
-+++
 ** New user option 'switch-to-prev-buffer-skip-regexp'.
 This should be a regexp or a list of regexps; buffers whose names
 match those regexps will be ignored by 'switch-to-prev-buffer' and
 'switch-to-next-buffer'.
 
-+++
 ** New command 'rename-visited-file'.
 This command renames the file visited by the current buffer by moving
 it to a new name or location, and also makes the buffer visit this new
@@ -736,19 +688,16 @@ file.
 
 ** Menus
 
----
 *** The entries following the buffers in the "Buffers" menu can now be altered.
 Change the 'menu-bar-buffers-menu-command-entries' variable to alter
 the entries that follow the buffer list.
 
----
 ** 'delete-process' is now a command.
 When called interactively, it will kill the process running in the
 current buffer (if any).  This can be useful if you have runaway
 output in the current buffer (from a process or a network connection),
 and want to stop it.
 
-+++
 ** New command 'restart-emacs'.
 This is like 'save-buffers-kill-emacs', but instead of just killing
 the current Emacs process at the end, it starts a new Emacs process
@@ -759,66 +708,54 @@ process.
 
 ** Drag and Drop
 
-+++
 *** New user option 'mouse-drag-mode-line-buffer'.
 If non-nil, dragging on the buffer name part of the mode-line will
 drag the buffer's associated file to other programs.  This option is
 currently only available on X, Haiku and Nextstep (GNUstep or macOS).
 
-+++
 *** New user option 'mouse-drag-and-drop-region-cross-program'.
 If non-nil, this option allows dragging text in the region from Emacs
 to another program.
 
----
 *** New user option 'mouse-drag-and-drop-region-scroll-margin'.
 If non-nil, this option allows scrolling a window while dragging text
 around without a scroll wheel.
 
-+++
 *** The value of 'mouse-drag-copy-region' can now be the symbol 'non-empty'.
 This prevents mouse drag gestures from putting empty strings onto the
 kill ring.
 
-+++
 *** New user options 'dnd-indicate-insertion-point' and 'dnd-scroll-margin'.
 These options allow adjusting point and scrolling a window when
 dragging items from another program.
 
-+++
 *** The X Direct Save (XDS) protocol is now supported.
 This means dropping an image or file link from programs such as
 Firefox will no longer create a temporary file in a random directory,
 instead asking you where to save the file first.
 
-+++
 ** New user option 'record-all-keys'.
 If non-nil, this option will force recording of all input keys,
 including those typed in response to passwords prompt (this was the
 previous behavior).  The default is nil, which inhibits recording of
 passwords.
 
-+++
 ** New function 'command-query'.
 This function makes its argument command prompt the user for
 confirmation before executing.
 
-+++
 ** The 'disabled' property of a command's symbol can now be a list.
 The first element of the list should be the symbol 'query', which will
 cause the command disabled this way prompt the user with a y/n or a
 yes/no question before executing.  The new function 'command-query' is
 a convenient method of making commands disabled in this way.
 
----
 ** 'count-words' will now report buffer totals if given a prefix.
 Without a prefix, it will only report the word count for the narrowed
 part of the buffer.
 
-+++
 ** 'count-words' will now report sentence count when used interactively.
 
-+++
 ** New user option 'set-message-functions'.
 It allows more flexible control of how echo-area messages are displayed
 by adding functions to this list.  The default value is a list of one
@@ -829,29 +766,24 @@ specifying, via 'inhibit-message-regexps', the list of 
messages whose
 display should be inhibited; and 'set-multi-message' that accumulates
 recent messages and displays them stacked together.
 
----
 ** New user option 'find-library-include-other-files'.
 If set to nil, commands like '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
 those tables.
 
----
 ** 'write-file' will now copy some file mode bits.
 If the current buffer is visiting a file that is executable, the
 'C-x C-w' command will now make the new file executable, too.
 
-+++
 ** New user option 'process-error-pause-time'.
 This determines how long to pause Emacs after a process
 filter/sentinel error has been handled.
 
-+++
 ** New faces for font-lock.
 These faces are primarily meant for use with tree-sitter.  They are:
 'font-lock-bracket-face', 'font-lock-delimiter-face',
@@ -861,40 +793,33 @@ These faces are primarily meant for use with tree-sitter. 
 They are:
 'font-lock-property-use-face', 'font-lock-punctuation-face',
 'font-lock-regexp-face', and 'font-lock-variable-use-face'.
 
-+++
 ** New face 'variable-pitch-text'.
 This face is like 'variable-pitch' (from which it inherits), but is
 slightly larger, which should help with the visual size differences
 between the default, non-proportional font and proportional fonts when
 mixed.
 
-+++
 ** New face 'mode-line-active'.
 This inherits from the 'mode-line' face, but is the face actually used
 on the mode lines (along with 'mode-line-inactive').
 
-+++
 ** New face attribute pseudo-value 'reset'.
 This value stands for the value of the corresponding attribute of the
 'default' face.  It can be used to reset attribute values produced by
 inheriting from other faces.
 
-+++
 ** New X resource "borderThickness".
 This controls the thickness of the external borders of the menu bars
 and pop-up menus.
 
-+++
 ** New X resource "inputStyle".
 This controls the style of the pre-edit and status areas of X input
 methods.
 
-+++
 ** New X resources "highlightForeground" and "highlightBackground".
 Only in the Lucid build, this controls colors used for highlighted
 menu item widgets.
 
-+++
 ** On X, 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
@@ -902,7 +827,6 @@ some ancient buggy window managers, so if Emacs appears to 
freeze, but
 is still responsive to input, you can turn it off by setting the X
 resource "synchronizeResize" to "off".
 
-+++
 ** On X, Emacs can optionally synchronize display with the graphics hardware.
 When this is enabled by setting the X resource "synchronizeResize" to
 "extended", frame content "tearing" is drastically reduced.  This is
@@ -914,22 +838,18 @@ https://fishsoup.net/misc/wm-spec-synchronization.html).
 This behavior can be toggled on and off via the frame parameter
 'use-frame-synchronization'.
 
-+++
 ** New frame parameter 'alpha-background' and X resource "alphaBackground".
 This controls the opacity of the text background when running on a
 composited display.
 
-+++
 ** New frame parameter 'shaded'.
 With window managers which support this, it controls whether or not a
 frame's contents will be hidden, leaving only the title bar on display.
 
----
 ** New user option 'x-gtk-use-native-input'.
 This controls whether or not GTK input methods are used by Emacs,
 instead of XIM input methods.  Defaults to nil.
 
-+++
 ** New user option 'use-system-tooltips'.
 This controls whether to use the toolkit tooltips, or Emacs's own
 native implementation of tooltips as small frames.  This option is
@@ -938,13 +858,11 @@ support, and defaults to t, which makes Emacs use the 
toolkit
 tooltips.  The existing GTK-specific option
 'x-gtk-use-system-tooltips' is now an alias of this new option.
 
-+++
 ** Non-native tooltips are now supported on Nextstep.
 This means Emacs built with GNUstep or built on macOS is now able to
 display different faces and images inside tooltips when the
 'use-system-tooltips' user option is nil.
 
----
 ** New minor mode 'pixel-scroll-precision-mode'.
 When enabled, and if your mouse supports it, you can scroll the
 display up or down at pixel resolution, according to what your mouse
@@ -954,20 +872,17 @@ scrolls.
 
 ** Terminal Emacs
 
----
 *** Emacs will now use 24-bit colors on terminals that support "Tc" capability.
 This is in addition to previously-supported ways of discovering 24-bit
 color support: either via the "RGB" or "setf24" capabilities, or if
 the 'COLORTERM' environment variable is set to the value "truecolor".
 
----
 *** Select active regions with xterm selection support.
 On terminals with xterm "setSelection" support, the active region may be
 saved to the X primary selection, following the
 'select-active-regions' variable.  This support is enabled when
 'tty-select-active-regions' is non-nil.
 
----
 *** New command to set up display of unsupported characters.
 The new command 'standard-display-by-replacement-char' produces Lisp
 code that sets up the 'standard-display-table' to use a replacement
@@ -977,7 +892,6 @@ This feature is most useful with the Linux console and 
similar
 terminals, where Emacs has a reliable way of determining which
 characters have glyphs in the font loaded into the terminal's memory.
 
----
 *** New functions to set terminal output buffer size.
 The new functions 'tty--set-output-buffer-size' and
 'tty--output-buffer-size' allow setting and retrieving the output
@@ -989,89 +903,72 @@ at the end of display update.
 
 ** ERT
 
-+++
 *** New ERT variables 'ert-batch-print-length' and 'ert-batch-print-level'.
 These variables will override 'print-length' and 'print-level' when
 printing Lisp values in ERT batch test results.
 
----
 *** Redefining an ERT test in batch mode now signals an error.
 Executing 'ert-deftest' with the same name as an existing test causes
 the previous definition to be discarded, which was probably not
 intended when this occurs in batch mode.  To remedy the error, rename
 tests so that they all have unique names.
 
-+++
 *** ERT can generate JUnit test reports.
 When environment variable 'EMACS_TEST_JUNIT_REPORT' is set, ERT
 generates a JUnit test report under this file name.  This is useful
 for Emacs integration into CI/CD test environments.
 
----
 *** Unbound test symbols now signal an 'ert-test-unbound' error.
 This affects the 'ert-select-tests' function and its callers.
 
 ** Emoji
 
-+++
 *** Emacs now has several new methods for inserting Emoji.
 The Emoji commands are under the new 'C-x 8 e' prefix.
 
-+++
 *** New command 'emoji-insert' (bound to 'C-x 8 e e' and 'C-x 8 e i').
 This command guides you through various Emoji categories and
 combinations in a graphical menu system.
 
-+++
 *** New command 'emoji-search' (bound to 'C-x 8 e s').
 This command lets you search for and insert an Emoji based on names.
 
-+++
 *** New command 'emoji-list' (bound to 'C-x 8 e l').
 This command lists all Emoji (categorized by themes) in a special
 buffer and lets you choose one of them to insert.
 
----
 *** New command 'emoji-recent' (bound to 'C-x 8 e r').
 This command lets you choose among the Emoji you have recently
 inserted and insert it.
 
-+++
 *** New command 'emoji-describe' (bound to 'C-x 8 e d').
 This command will tell you the name of the Emoji at point.  (It also
 works for non-Emoji characters.)
 
----
 *** New commands 'emoji-zoom-increase' and 'emoji-zoom-decrease'.
 These are bound to 'C-x 8 e +' and 'C-x 8 e -', respectively.  They
 can be used on any character, but are mainly useful for Emoji.
 
----
 *** New command 'emoji-zoom-reset'.
 This is bound to 'C-x 8 e 0', and undoes any size changes performed by
 'emoji-zoom-increase' and 'emoji-zoom-decrease'.
 
----
 *** New input method 'emoji'.
 This allows you to enter Emoji using short strings, eg ':face_palm:'
 or ':scream:'.
 
 ** Help
 
----
 *** Variable values displayed by 'C-h v' in "*Help*" are now fontified.
 
-+++
 *** New user option 'help-clean-buttons'.
 If non-nil, link buttons in "*Help*" buffers will have any surrounding
 quotes removed.
 
----
 *** 'M-x apropos-variable' output now includes values of variables.
 Such an apropos buffer is more easily viewed with outlining after
 enabling 'outline-minor-mode' in 'apropos-mode'.
 
-+++
 *** New docstring syntax to indicate that symbols shouldn't be links.
 When displaying docstrings in "*Help*" buffers, strings that are
 "`like-this'" are made into links (if they point to a bound
@@ -1080,12 +977,10 @@ about values that are symbols that happen to have the 
same names as
 functions/variables.  To inhibit this buttonification, use the new
 "\\+`like-this'" syntax.
 
-+++
 *** New user option 'help-window-keep-selected'.
 If non-nil, commands to show the info manual and the source will reuse
 the same window in which the "*Help*" buffer is shown.
 
----
 *** Commands like 'C-h f' have changed how they describe menu bindings.
 For instance, previously a command might be described as having the
 following bindings:
@@ -1097,56 +992,45 @@ This has been changed to:
     It is bound to <open> and C-x C-f.
     It can also be invoked from the menu: File → Visit New File...
 
-+++
 *** The 'C-h .' command now accepts a prefix argument.
 'C-u C-h .' would previously inhibit displaying a warning message if
 there was no local help at point.  This has been changed to call
 'button-describe'/'widget-describe' and display button/widget help
 instead.
 
----
 *** New user option 'help-enable-variable-value-editing'.
 If enabled, 'e' on a value in "*Help*" will pop you to a new buffer
 where you can edit the value.  This is not enabled by default, because
 it is easy to make an edit that yields an invalid result.
 
----
 *** 'C-h b' uses outlining by default.
 Set 'describe-bindings-outline' to nil to get back the old behavior.
 
----
 *** Jumping to function/variable source now saves mark before moving point.
 Jumping to source from a "*Help*" buffer moves point when the source
 buffer is already open.  Now, the old point is pushed onto mark ring.
 
-+++
 *** New key bindings in "*Help*" buffers: 'n' and 'p'.
 These will take you (respectively) to the next and previous "page".
 
----
 *** 'describe-char' now also outputs the name of Emoji sequences.
 
-+++
 *** New key binding in "*Help*" buffer: 'I'.
 This will take you to the Emacs Lisp manual entry for the item
 displayed, if any.
 
----
 *** The 'C-h m' ('describe-mode') "*Help*" buffer has been reformatted.
 It now only includes local minor modes at the start, and the global
 minor modes are listed after the major mode.
 
-+++
 *** The user option 'help-window-select' now affects apropos commands.
 The apropos commands will now select the apropos window if
 'help-window-select' is non-nil.
 
----
 *** 'describe-keymap' now considers the symbol at point.
 If the symbol at point is a keymap, 'describe-keymap' suggests it as
 the default candidate.
 
----
 *** New command 'help-quick' displays an overview of common commands.
 The command pops up a buffer at the bottom of the screen with a few
 helpful commands for various tasks.  You can toggle the display using
@@ -1157,7 +1041,6 @@ See the file "etc/ORG-NEWS" for user-visible changes in 
Org.
 
 ** Outline Mode
 
-+++
 *** Support for customizing the default visibility state of headings.
 Customize the user option 'outline-default-state' to define what
 headings will be visible initially, after Outline mode is turned on.
@@ -1169,7 +1052,6 @@ subtree has long lines or is itself too long.
 
 ** Outline Minor Mode
 
-+++
 *** New user option 'outline-minor-mode-use-buttons'.
 If non-nil, Outline Minor Mode will use buttons to hide/show outlines
 in addition to the ellipsis.  The default is nil, but in 'help-mode'
@@ -1178,7 +1060,6 @@ buffer, and you can use 'RET' to cycle outline 
visibility.  When
 the value is 'in-margins', Outline Minor Mode uses the window margins
 for buttons that hide/show outlines.
 
-+++
 *** Buttons and headings now have their own keymaps.
 'outline-button-icon-map', 'outline-overlay-button-map', and
 'outline-inserted-button-map' are now available as defined keymaps
@@ -1186,19 +1067,16 @@ instead of being anonymous keymaps.
 
 ** Windows
 
-+++
 *** New commands 'split-root-window-below' and 'split-root-window-right'.
 These commands split the root window in two, and are bound to 'C-x w 2'
 and 'C-x w 3', respectively.  A number of other useful window-related
 commands are now available with key sequences that start with the
 'C-x w' prefix.
 
-+++
 *** New display action 'display-buffer-full-frame'.
 This action removes other windows from the frame when displaying a
 buffer on that frame.
 
-+++
 *** 'display-buffer' now can set up the body size of the chosen window.
 For example, a 'display-buffer-alist' entry of
 
@@ -1207,35 +1085,29 @@ For example, a 'display-buffer-alist' entry of
 will make the body of the chosen window 40 columns wide.  For the
 height use 'window-height' and 'body-lines', respectively.
 
-+++
 *** 'display-buffer' provides more options for using an existing window.
 The display buffer action functions 'display-buffer-use-some-window' and
 'display-buffer-use-least-recent-window' now honor the action alist
 entry 'window-min-height' as well as the entries listed below to make
 the display of several buffers in a row more amenable.
 
-+++
 *** New buffer display action alist entry 'lru-frames'.
 This allows specifying which frames 'display-buffer' should consider
 when using a window that shows another buffer.  It is interpreted as
 per the ALL-FRAMES argument of 'get-lru-window'.
 
-+++
 *** New buffer display action alist entry 'lru-time'.
 'display-buffer' will ignore windows with a use time higher than this
 when using a window that shows another buffer.
 
-+++
 *** New buffer display action alist entry 'bump-use-time'.
 This has 'display-buffer' bump the use time of any window it returns,
 making it a less likely candidate for displaying another buffer.
 
-+++
 *** New buffer display action alist entry 'window-min-width'.
 This allows specifying a preferred minimum width of the window used to
 display a buffer.
 
----
 *** You can specify on which window 'scroll-other-window' operates.
 This is controlled by the new 'other-window-scroll-default' variable,
 which should be set to a function that returns a window.  When this
@@ -1243,7 +1115,6 @@ variable is nil, 'next-window' is used.
 
 ** Frames
 
-+++
 *** Deleted frames can now be undeleted.
 The 16 most recently deleted frames can be undeleted with 'C-x 5 u' when
 'undelete-frame-mode' is enabled.  Without a prefix argument, undelete
@@ -1251,7 +1122,6 @@ the most recently deleted frame.  With a numerical prefix 
argument
 between 1 and 16, where 1 is the most recently deleted frame, undelete
 the corresponding deleted frame.
 
-+++
 *** The variable 'icon-title-format' can now have the value t.
 That value means to use 'frame-title-format' for iconified frames.
 This is useful with some window managers and desktop environments
@@ -1261,24 +1131,20 @@ same no matter if the frame is iconified or not.
 
 ** Tab Bars and Tab Lines
 
----
 *** New user option 'tab-bar-auto-width' to automatically determine tab width.
 This option is non-nil by default, which resizes tab-bar tabs so that
 their width is evenly distributed across the tab bar.  A companion
 option 'tab-bar-auto-width-max' controls the maximum width of a tab
 before its name on display is truncated.
 
----
 *** 'C-x t RET' creates a new tab when the provided tab name doesn't exist.
 It prompts for the name of a tab and switches to it, creating a new
 tab if no tab exists by that name.
 
----
 *** New keymap 'tab-bar-history-mode-map'.
 By default, it contains 'C-c <left>' and 'C-c <right>' to browse
 the history of tab window configurations back and forward.
 
----
 ** Better detection of text suspiciously reordered on display.
 The function 'bidi-find-overridden-directionality' has been extended
 to detect reordering effects produced by embeddings and isolates
@@ -1289,17 +1155,14 @@ suspicious and could be malicious.
 
 ** Emacs Server and Client
 
-+++
 *** New command-line option '-r'/'--reuse-frame' for emacsclient.
 With this command-line option, Emacs reuses an existing graphical client
 frame if one exists; otherwise it creates a new frame.
 
-+++
 *** New command-line option '-w N'/'--timeout=N' for emacsclient.
 With this command-line option, emacsclient will exit if Emacs does not
 respond within N seconds.  The default is to wait forever.
 
-+++
 *** 'server-stop-automatically' can be used to automatically stop the server.
 The Emacs server will be automatically stopped when certain conditions
 are met.  The conditions are determined by the argument to
@@ -1308,17 +1171,14 @@ are met.  The conditions are determined by the argument 
to
 
 ** Rcirc
 
-+++
 *** New command 'rcirc-when'.
 This shows the reception time of the message at point (if available).
 
-+++
 *** New user option 'rcirc-cycle-completion-flag'.
 Rcirc now uses the default 'completion-at-point' mechanism.  The
 conventional IRC behavior of completing by cycling through the
 available options can be restored by enabling this option.
 
-+++
 *** New user option 'rcirc-bridge-bot-alist'.
 If you are in a channel where a bot is responsible for bridging
 between networks, you can use this variable to make these messages
@@ -1334,7 +1194,6 @@ to be reformatted into
 
     09:47 <john> I am not on IRC
 
----
 *** New formatting commands.
 Most IRC clients (including rcirc) support basic formatting using
 control codes.  Under the 'C-c C-f' prefix a few commands have been
@@ -1344,15 +1203,12 @@ to be highlighted in bold.
 
 ** Imenu
 
-+++
 *** 'imenu' is now bound to 'M-g i' globally.
 
----
 *** New function 'imenu-flush-cache'.
 Use it if you want Imenu to forget the buffer's index alist and
 recreate it anew next time 'imenu' is invoked.
 
----
 ** Emacs is now capable of abandoning a window's redisplay that takes too long.
 This is controlled by the new variable 'max-redisplay-ticks'.  If that
 variable is set to a non-zero value, display of a window will be
@@ -1366,19 +1222,16 @@ lines.)
 
 * Editing Changes in Emacs 29.1
 
-+++
 ** 'M-SPC' is now bound to 'cycle-spacing'.
 Formerly it invoked 'just-one-space'.  The actions performed by
 'cycle-spacing' and their order can now be customized via the user
 option 'cycle-spacing-actions'.
 
----
 ** 'zap-to-char' and 'zap-up-to-char' are case-sensitive for upper-case chars.
 These commands now behave as case-sensitive for interactive calls when
 they are invoked with an uppercase character, regardless of the value
 of 'case-fold-search'.
 
----
 ** 'scroll-other-window' and 'scroll-other-window-down' now respect remapping.
 These commands (bound to 'C-M-v' and 'C-M-V') used to scroll the other
 windows without looking at customizations in that other window.  These
@@ -1387,7 +1240,6 @@ in that other window, and then call the remapped function 
instead.  In
 addition, these commands now also respect the
 'scroll-error-top-bottom' user option.
 
----
 ** Indentation of 'cl-flet' and 'cl-labels' has changed.
 These forms now indent like this:
 
@@ -1398,32 +1250,26 @@ These forms now indent like this:
 This change also affects 'cl-macrolet', 'cl-flet*' and
 'cl-symbol-macrolet'.
 
-+++
 ** New user option 'translate-upper-case-key-bindings'.
 Set this option to nil to inhibit the default translation of upper
 case keys to their lower case variants.
 
-+++
 ** New command 'ensure-empty-lines'.
 This command increases (or decreases) the number of empty lines before
 point.
 
----
 ** Improved mouse behavior with auto-scrolling modes.
 When clicking inside the 'scroll-margin' or 'hscroll-margin' region,
 point is now moved only when releasing the mouse button.  This no
 longer results in a bogus selection, unless the mouse has also been
 dragged.
 
-+++
 ** 'kill-ring-max' now defaults to 120.
 
----
 ** New user option 'yank-menu-max-items'.
 Customize this option to limit the number of entries in the menu
 "Edit → Paste from Kill Menu".  The default is 60.
 
----
 ** New user option 'copy-region-blink-predicate'.
 By default, when copying a region with 'kill-ring-save', Emacs only
 blinks point and mark when the region is not denoted visually, that
@@ -1435,12 +1281,10 @@ this user option to 'always'.  To disable blinking 
unconditionally,
 either set this option to 'ignore', or set 'copy-region-blink-delay'
 to 0.
 
-+++
 ** Performing a pinch gesture on a touchpad now increases the text scale.
 
 ** Show Paren Mode
 
-+++
 *** New user option 'show-paren-context-when-offscreen'.
 When non-nil, if the point is in a closing delimiter and the opening
 delimiter is offscreen, shows some context around the opening
@@ -1454,19 +1298,16 @@ echo area.
 
 ** Comint
 
-+++
 *** 'comint-term-environment' is now aware of connection-local variables.
 The user option 'comint-terminfo-terminal' and the variable
 'system-uses-terminfo' can now be set as connection-local variables to
 change the terminal used on a remote host.
 
----
 *** New user option 'comint-delete-old-input'.
 When nil, this prevents comint from deleting the current input when
 inserting previous input using '<mouse-2>'.  The default is t, to
 preserve previous behavior.
 
----
 *** New minor mode 'comint-fontify-input-mode'.
 This minor mode is enabled by default in "*shell*" and "*ielm*"
 buffers.  It fontifies input text according to 'shell-mode' or
@@ -1476,7 +1317,6 @@ you don't want to enable input fontification by default.
 
 ** Mwheel
 
----
 *** New user options for alternate wheel events.
 The user options 'mouse-wheel-down-alternate-event' and
 'mouse-wheel-up-alternate-event' as well as the variables
@@ -1486,19 +1326,16 @@ systems where two kinds of wheel events can be received.
 
 ** Internationalization
 
----
 *** The '<Delete>' function key now allows deleting the entire composed 
sequence.
 For the details, see the item about the 'delete-forward-char' command
 above.
 
----
 *** New user option 'composition-break-at-point'.
 Setting it to a non-nil value temporarily disables automatic
 composition of character sequences at point, and thus makes it easier
 to edit such sequences by allowing point to "enter" the composed
 sequence.
 
----
 *** Support for many old scripts and writing systems.
 Emacs now supports, and has language-environments and input methods,
 for several dozens of old scripts that were used in the past for
@@ -1573,48 +1410,39 @@ environments are:
 
  Mongolian-cyrillic language environment
 
----
 *** The "Oriya" language environment was renamed to "Odia".
 This is to follow the change in the official name of the script.  The
 'oriya' input method was also renamed to 'odia'.  However, the old
 name of the language environment and the input method are still
 supported.
 
----
 *** New Greek translation of the Emacs tutorial.
 Type 'C-u C-h t' to select it in case your language setup does not do
 so automatically.
 
----
 *** New Ukrainian translation of the Emacs tutorial.
 
----
 *** New Farsi/Persian translation of the Emacs tutorial.
 
----
 *** New default phonetic input method for the Tamil language environment.
 The default input method for the Tamil language environment is now
 "tamil-phonetic" which is a customizable phonetic input method.  To
 change the input method's translation rules, customize the user option
 'tamil-translation-rules'.
 
----
 *** New 'tamil99' input method for the Tamil language.
 This supports the keyboard layout specifically designed for the Tamil
 language.
 
----
 *** New input method 'slovak-qwerty'.
 This is a variant of the 'slovak' input method, which corresponds to
 the QWERTY Slovak keyboards.
 
----
 *** New input method 'cyrillic-chuvash'.
 This input method is based on the russian-computer input method, and
 is intended for typing in the Chuvash language written in the Cyrillic
 script.
 
----
 *** New input method 'cyrillic-mongolian'.
 This input method is for typing in the Mongolian language using the
 Cyrillic script.  It is the default input method for the new
@@ -1625,23 +1453,19 @@ Mongolian-cyrillic language environment, see above.
 
 ** Ecomplete
 
----
 *** New commands 'ecomplete-edit' and 'ecomplete-remove'.
 These allow you to (respectively) edit and bulk-remove entries from
 the ecomplete database.
 
----
 *** New user option 'ecomplete-auto-select'.
 If non-nil and there's only one matching option, auto-select that.
 
----
 *** New user option 'ecomplete-filter-regexp'.
 If non-nil, this user option describes what entries not to add to the
 database stored on disk.
 
 ** Auth Source
 
-+++
 *** New user option 'auth-source-pass-extra-query-keywords'.
 Whether to recognize additional keyword params, like ':max' and
 ':require', as well as accept lists of query terms paired with
@@ -1650,13 +1474,11 @@ unique to auth-source-pass, such as wildcard subdomain 
matching.
 
 ** Dired
 
-+++
 *** 'dired-guess-shell-command' moved from dired-x to dired.
 This means that 'dired-do-shell-command' will now provide smarter
 defaults without first having to require 'dired-x'.  See the node
 "(emacs) Shell Command Guessing" in the Emacs manual for more details.
 
----
 *** 'dired-clean-up-buffers-too' moved from dired-x to dired.
 This means that Dired now offers to kill buffers visiting files and
 dirs when they are deleted in Dired.  Before, you had to require
@@ -1665,20 +1487,16 @@ customize the user option 'dired-clean-up-buffers-too' 
to nil.  The
 related user option 'dired-clean-confirm-killing-deleted-buffers'
 (which see) has also been moved to 'dired'.
 
-+++
 *** 'dired-do-relsymlink' moved from dired-x to dired.
 The corresponding key 'Y' is now bound by default in Dired.
 
-+++
 *** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
 The corresponding key sequence '% Y' is now bound by default in Dired.
 
----
 *** 'M-G' is now bound to 'dired-goto-subdir'.
 Before, that binding was only available if the dired-x package was
 loaded.
 
-+++
 *** 'dired-info' and 'dired-man' moved from dired-x to dired.
 The 'dired-info' and 'dired-man' commands have been moved from the
 dired-x package to dired.  They have also been renamed to
@@ -1696,29 +1514,24 @@ the following to your Init file:
       (keymap-set dired-mode-map "N" nil)
       (keymap-set dired-mode-map "I" nil))
 
----
 *** New command 'dired-do-eww'.
 This command visits the file on the current line with EWW.
 
----
 *** 'browse-url-of-dired-file' can now call the secondary browser.
 When invoked with a prefix arg, this will now call
 'browse-url-secondary-browser-function' instead of the default
 browser.  'browse-url-of-dired-file' is bound to 'W' by default in
 dired mode.
 
----
 *** New user option 'dired-omit-lines'.
 This is used by 'dired-omit-mode', and now allows you to hide based on
 other things than just the file names.
 
-+++
 *** New user option 'dired-mouse-drag-files'.
 If non-nil, dragging file names with the mouse in a Dired buffer will
 initiate a drag-and-drop session allowing them to be opened in other
 programs.
 
-+++
 *** New user option 'dired-free-space'.
 Dired will now, by default, include the free space in the first line
 instead of having it on a separate line.  To get the previous behavior
@@ -1726,13 +1539,11 @@ back, say:
 
     (setopt dired-free-space 'separate)
 
----
 *** New user option 'dired-make-directory-clickable'.
 If non-nil (which is the default), hitting 'RET' or 'mouse-1' on
 the directory components at the directory displayed at the start of
 the buffer will take you to that directory.
 
----
 *** Search and replace in Dired/Wdired supports more regexps.
 For example, the regexp ".*" will match only characters that are part
 of the file name.  Also "^.*$" can be used to match at the beginning
@@ -1743,31 +1554,26 @@ default).
 
 ** Elisp
 
----
 *** New command 'elisp-eval-region-or-buffer' (bound to 'C-c C-e').
 This command evals the forms in the active region or in the whole buffer.
 
----
 *** New commands 'elisp-byte-compile-file' and 'elisp-byte-compile-buffer'.
 These commands (bound to 'C-c C-f' and 'C-c C-b', respectively)
 byte-compile the visited file and the current buffer, respectively.
 
 ** Games
 
----
 *** New user option 'tetris-allow-repetitions'.
 This controls how randomness is implemented (whether to use pure
 randomness as before, or to use a bag).
 
 ** Battery
 
-+++
 *** New user option 'battery-update-functions'.
 This can be used to trigger actions based on the battery status.
 
 ** DocView
 
----
 *** doc-view can now generate SVG images when viewing PDF files.
 If Emacs is built with SVG support, doc-view can generate SVG files
 when using MuPDF as the converter for PDF files, which generally leads
@@ -1781,14 +1587,12 @@ or can take a long time to render.
 
 ** Enriched Mode
 
-+++
 *** New command 'enriched-toggle-markup'.
 This allows you to see the markup in 'enriched-mode' buffers (e.g.,
 the "HELLO" file).  Bound to 'M-o m' by default.
 
 ** Shell Script Mode
 
----
 *** New user option 'sh-indent-statement-after-and'.
 This controls how statements like the following are indented:
 
@@ -1801,10 +1605,8 @@ command is installed.
 
 ** CC Mode
 
----
 *** C++ Mode now supports most of the new features in the C++20 Standard.
 
----
 *** In Objective-C Mode, no extra types are recognized by default.
 The default value of 'objc-font-lock-extra-types' has been changed to
 nil, since too many identifiers were getting misfontified as types.
@@ -1814,19 +1616,16 @@ doc string.
 
 ** Cperl Mode
 
----
 *** New user option 'cperl-file-style'.
 This option determines the indentation style to be used.  It can also
 be used as a file-local variable.
 
 ** Gud
 
----
 *** 'gud-go' is now bound to 'C-c C-v'.
 If given a prefix, it will prompt for an argument to use for the
 run/continue command.
 
----
 *** 'perldb' now recognizes '-E'.
 As of Perl 5.10, 'perl -E 0' behaves like 'perl -e 0' but also activates
 all optional features of the Perl version in use.  'perldb' now uses
@@ -1834,27 +1633,23 @@ this invocation as its default.
 
 ** Customize
 
----
 *** New command 'custom-toggle-hide-all-widgets'.
 This is bound to 'H' and toggles whether to hide or show the widget
 contents.
 
 ** Diff Mode
 
----
 *** New user option 'diff-whitespace-style'.
 Sets the value of the buffer-local variable 'whitespace-style' in
 'diff-mode' buffers.  By default, this variable is '(face trailing)',
 which preserves behavior of previous Emacs versions.
 
-+++
 *** New user option 'diff-add-log-use-relative-names'.
 If non-nil insert file names in ChangeLog skeletons relative to the
 VC root directory.
 
 ** Ispell
 
----
 *** 'ispell-region' and 'ispell-buffer' now push the mark.
 These commands push onto the mark ring the location of the last
 misspelled word where corrections were offered, so that you can then
@@ -1862,73 +1657,60 @@ skip back to that location with 'C-x C-x'.
 
 ** Dabbrev
 
----
 *** New function 'dabbrev-capf' for use on 'completion-at-point-functions'.
 
-+++
 *** New user option 'dabbrev-ignored-buffer-modes'.
 Buffers with major modes in this list will be ignored.  By default,
 this includes "binary" buffers like 'archive-mode' and 'image-mode'.
 
 ** Package
 
-+++
 *** New command 'package-upgrade'.
 This command allows you to upgrade packages without using 'list-packages'.
 A package that comes with the Emacs distribution can only be upgraded
 after you install, once, a newer version from ELPA via the
 package-menu displayed by 'list-packages'.
 
-+++
 *** New command 'package-upgrade-all'.
 This command allows upgrading all packages without any queries.
 A package that comes with the Emacs distribution will only be upgraded
 by this command after you install, once, a newer version of that
 package from ELPA via the package-menu displayed by 'list-packages'.
 
-+++
 *** New commands 'package-recompile' and 'package-recompile-all'.
 These commands can be useful if the ".elc" files are out of date
 (invalid byte code and macros).
 
-+++
 *** New DWIM action on 'x' in "*Packages*" buffer.
 If no packages are marked, 'x' will install the package under point if
 it isn't already, and remove it if it is installed.  Customize the new
 option 'package-menu-use-current-if-no-marks' to the nil value to get
 back the old behavior of signaling an error in that case.
 
-+++
 *** New command 'package-vc-install'.
 Packages can now be installed directly from source by cloning from
 their repository.
 
-+++
 *** New command 'package-vc-install-from-checkout'.
 An existing checkout can now be loaded via package.el, by creating a
 symbolic link from the usual package directory to the checkout.
 
-+++
 *** New command 'package-vc-checkout'.
 Used to fetch the source of a package by cloning a repository without
 activating the package.
 
-+++
 *** New command 'package-vc-prepare-patch'.
 This command allows you to send patches to package maintainers, for
 packages checked out using 'package-vc-install'.
 
-+++
 *** New command 'package-report-bug'.
 This command helps you compose an email for sending bug reports to
 package maintainers, and is bound to 'b' in the "*Packages*" buffer.
 
-+++
 *** New user option 'package-vc-selected-packages'.
 By customizing this user option you can specify specific packages to
 install.
 
----
 *** New user option 'package-install-upgrade-built-in'.
 When enabled, 'package-install' will include in the list of
 upgradeable packages those built-in packages (like Eglot and
@@ -1950,7 +1732,6 @@ setting in your early-init file.
 
 ** Emacs Sessions (Desktop)
 
-+++
 *** New user option to load a locked desktop if locking Emacs is not running.
 The option 'desktop-load-locked-desktop' can now be set to the value
 'check-pid', which means to allow loading a locked ".emacs.desktop"
@@ -1962,7 +1743,6 @@ Emacs Sessions" node in the Emacs manual for more details.
 
 ** Miscellaneous
 
-+++
 *** New command 'scratch-buffer'.
 This command switches to the "*scratch*" buffer.  If "*scratch*" doesn't
 exist, the command creates it first.  You can use this command if you
@@ -1970,31 +1750,26 @@ inadvertently delete the "*scratch*" buffer.
 
 ** Debugging
 
----
 *** 'q' in a "*Backtrace*" buffer no longer clears the buffer.
 Instead it just buries the buffer and switches the mode from
 'debugger-mode' to 'backtrace-mode', since commands like 'e' are no
 longer available after exiting the recursive edit.
 
-+++
 *** New user option 'debug-allow-recursive-debug'.
 This user option controls whether the 'e' (in a "*Backtrace*"
 buffer or while edebugging) and 'C-x C-e' (while edebugging) commands
 lead to a (further) backtrace.  By default, this variable is nil,
 which is a change in behavior from previous Emacs versions.
 
-+++
 *** 'e' in edebug can now take a prefix arg to pretty-print the results.
 When invoked with a prefix argument, as in 'C-u e', this command will
 pop up a new buffer and show the full pretty-printed value there.
 
-+++
 *** 'C-x C-e' now interprets a non-zero prefix arg to pretty-print the results.
 When invoked with a non-zero prefix argument, as in 'C-u C-x C-e',
 this command will pop up a new buffer and show the full pretty-printed
 value there.
 
-+++
 *** You can now generate a backtrace from Lisp errors in redisplay.
 To do this, set the new variable 'backtrace-on-redisplay-error' to a
 non-nil value.  The backtrace will be written to a special buffer
@@ -2003,18 +1778,15 @@ displayed in a window.
 
 ** Compile
 
-+++
 *** New user option 'compilation-hidden-output'.
 This regular expression can be used to make specific parts of
 compilation output invisible.
 
-+++
 *** The 'compilation-auto-jump-to-first-error' user option has been extended.
 It can now have the additional values 'if-location-known' (which will
 only jump if the location of the first error is known), and
 'first-known' (which will jump to the first known error location).
 
-+++
 *** New user option 'compilation-max-output-line-length'.
 Lines longer than the value of this option will have their ends
 hidden, with a button to reveal the hidden text.  This speeds up
@@ -2023,15 +1795,12 @@ value is 400; set to nil to disable hiding.
 
 ** Flymake
 
-+++
 *** New user option 'flymake-mode-line-lighter'.
 
-+++
 ** New minor mode 'word-wrap-whitespace-mode' for extending 'word-wrap'.
 This mode switches 'word-wrap' on, and breaks on all the whitespace
 characters instead of just 'SPC' and 'TAB'.
 
----
 ** New mode, 'emacs-news-mode', for editing the NEWS file.
 This mode adds some highlighting, makes the 'M-q' command aware of the
 format of NEWS entries, and has special commands for doing maintenance
@@ -2040,13 +1809,11 @@ of the Emacs NEWS files.  In addition, this mode turns 
on
 'icon-preference') in the margins.  To disable these icons, set
 'outline-minor-mode-use-buttons' to a nil value.
 
----
 ** Kmacro
 Kmacros are now OClosures and have a new constructor 'kmacro' which
 uses the 'key-parse' syntax.  It replaces the old 'kmacro-lambda-form'
 (which is now declared obsolete).
 
----
 ** savehist.el can now truncate variables that are too long.
 An element of user option 'savehist-additional-variables' can now be
 of the form '(VARIABLE . MAX-ELTS)', which means to truncate the
@@ -2055,7 +1822,6 @@ before saving the value.
 
 ** Minibuffer and Completions
 
-+++
 *** New commands for navigating completions from the minibuffer.
 When the minibuffer is the current buffer, typing 'M-<up>' or
 'M-<down>' selects a previous/next completion candidate from the
@@ -2070,13 +1836,11 @@ exit the minibuffer.  These keys are also available for 
in-buffer
 completion, but they don't insert candidates automatically, you need
 to type 'M-RET' to insert the selected candidate to the buffer.
 
-+++
 *** Choosing a completion with a prefix argument doesn't exit the minibuffer.
 This means that typing 'C-u RET' on a completion candidate in the
 "*Completions*" buffer inserts the completion into the minibuffer,
 but doesn't exit the minibuffer.
 
-+++
 *** The "*Completions*" buffer can now be automatically selected.
 To enable this behavior, customize the user option
 'completion-auto-select' to t, then pressing 'TAB' will switch to the
@@ -2084,13 +1848,11 @@ To enable this behavior, customize the user option
 'second-tab', then the first 'TAB' will display "*Completions*", and
 the second one will switch to the "*Completions*" buffer.
 
----
 *** New user option 'completion-auto-wrap'.
 When non-nil, the commands 'next-completion' and 'previous-completion'
 automatically wrap around on reaching the beginning or the end of
 the "*Completions*" buffer.
 
-+++
 *** New values for the 'completion-auto-help' user option.
 There are two new values to control the way the "*Completions*" buffer
 behaves after pressing a 'TAB' if completion is not unique.  The value
@@ -2099,61 +1861,51 @@ to complete.  The value 'visual' is like 'always', but 
only updates
 the completions if they are already visible.  The default value t
 always hides the completion buffer after some completion is made.
 
----
 *** New commands to complete the minibuffer history.
 'minibuffer-complete-history' ('C-x <up>') is like 'minibuffer-complete'
 but completes on the history items instead of the default completion
 table.  'minibuffer-complete-defaults' ('C-x <down>') completes
 on the list of default items.
 
-+++
 *** User option 'minibuffer-eldef-shorten-default' is now obsolete.
 Customize the user option 'minibuffer-default-prompt-format' instead.
 
-+++
 *** New user option 'completions-sort'.
 This option controls the sorting of the completion candidates in
 the "*Completions*" buffer.  Available styles are no sorting,
 alphabetical (the default), or a custom sort function.
 
-+++
 *** New user option 'completions-max-height'.
 This option limits the height of the "*Completions*" buffer.
 
-+++
 *** New user option 'completions-header-format'.
 This is a string to control the header line to show in the
 "*Completions*" buffer before the list of completions.
 If it contains "%s", that is replaced with the number of completions.
 If nil, the header line is not shown.
 
-+++
 *** New user option 'completions-highlight-face'.
 When this user option names a face, the current
 candidate in the "*Completions*" buffer is highlighted with that face.
 The nil value disables this highlighting.  The default is to highlight
 using the 'completions-highlight' face.
 
-+++
 *** You can now define abbrevs for the minibuffer modes.
 'minibuffer-mode-abbrev-table' and
 'minibuffer-inactive-mode-abbrev-table' are now defined.
 
 ** Isearch and Replace
 
-+++
 *** Changes in how Isearch responds to 'mouse-yank-at-point'.
 If a user does 'C-s' and then uses '<mouse-2>' ('mouse-yank-primary')
 outside the echo area, Emacs will, by default, end the Isearch and
 yank the text at mouse cursor.  But if 'mouse-yank-at-point' is
 non-nil, the text will now be added to the Isearch instead.
 
-+++
 *** Changes for values 'no' and 'no-ding' of 'isearch-wrap-pause'.
 Now with these values the search will wrap around not only on repeating
 with 'C-s C-s', but also after typing a character.
 
-+++
 *** New user option 'char-fold-override'.
 Non-nil means that the default definitions of equivalent characters
 are overridden.
@@ -2161,7 +1913,6 @@ are overridden.
 *** New command 'describe-char-fold-equivalences'.
 It displays character equivalences used by 'char-fold-to-regexp'.
 
-+++
 *** New command 'isearch-emoji-by-name'.
 It is bound to 'C-x 8 e RET' during an incremental search.  The
 command accepts the Unicode name of an Emoji (for example, "smiling
@@ -2170,7 +1921,6 @@ completion, and adds the Emoji into the search string.
 
 ** GDB/MI
 
----
 *** New user option 'gdb-debuginfod-enable-setting'.
 On capable platforms, GDB 10.1 and later can download missing source
 and debug info files from special-purpose servers, called "debuginfod
@@ -2182,18 +1932,15 @@ that session.
 
 ** Glyphless Characters
 
-+++
 *** New minor mode 'glyphless-display-mode'.
 This allows an easy way to toggle seeing all glyphless characters in
 the current buffer.
 
----
 *** The extra slot of 'glyphless-char-display' can now have cons values.
 The extra slot of the 'glyphless-char-display' char-table can now have
 values that are cons cells, specifying separate values for text-mode
 and GUI terminals.
 
-+++
 *** "Replacement character" feature for undisplayable characters on TTYs.
 The 'acronym' method of displaying glyphless characters on text-mode
 frames treats single-character acronyms specially: they are displayed
@@ -2202,7 +1949,6 @@ without the surrounding '[..]' "box", thus in effect 
treating such
 
 ** Registers
 
-+++
 *** Buffer names can now be stored in registers.
 For instance, to enable jumping to the "*Messages*" buffer with
 'C-x r j m':
@@ -2211,53 +1957,43 @@ For instance, to enable jumping to the "*Messages*" 
buffer with
 
 ** Pixel Fill
 
-+++
 *** This is a new package that deals with filling variable-pitch text.
 
-+++
 *** New function 'pixel-fill-region'.
 This fills the region to be no wider than a specified pixel width.
 
 ** Info
 
-+++
 *** Command 'info-apropos' now takes a prefix argument to search for regexps.
 
----
 *** New command 'Info-goto-node-web' and key binding 'G'.
 This will take you to the "gnu.org" web server's version of the current
 info node.  This command only works for the Emacs and Emacs Lisp manuals.
 
 ** Shortdoc
 
----
 *** New command 'shortdoc-copy-function-as-kill' bound to 'w'.
 It copies the name of the function near point into the kill ring.
 
----
 *** 'N' and 'P' are now bound to 'shortdoc-{next,previous}-section'.
 This is in addition to the old keybindings 'C-c C-n' and 'C-c C-p'.
 
 ** VC
 
----
 *** New command 'vc-pull-and-push'.
 This commands first does a "pull" command, and if that is successful,
 does a "push" command afterwards.  Currently supported in Git and Bzr.
 
-+++
 *** 'C-x v b' prefix key is used now for branch commands.
 'vc-print-branch-log' is bound to 'C-x v b l', and new commands are
 'vc-create-branch' ('C-x v b c') and 'vc-switch-branch' ('C-x v b s').
 The VC Directory buffer now uses the prefix 'b' for these branch-related
 commands.
 
-+++
 *** New command 'vc-dir-mark-by-regexp' bound to '% m' and '* %'.
 This command marks files based on a regexp.  If given a prefix
 argument, unmark instead.
 
-+++
 *** New command 'C-x v !' ('vc-edit-next-command').
 This prefix command requests editing of the next VC shell command
 before execution.  For example, in a Git repository, you can produce a
@@ -2268,7 +2004,6 @@ The intention is that this command can be used to access 
a wide
 variety of version control system-specific functionality from VC
 without complexifying either the VC command set or the backend API.
 
----
 *** 'C-x v v' in a diffs buffer allows to commit only some of the changes.
 This command is intended to allow you to commit only some of the
 changes you have in your working tree.  Begin by creating a buffer
@@ -2277,7 +2012,6 @@ with the changes against the last commit, e.g. with 'C-x 
v D'
 want to commit.  Finally, type 'C-x v v' in that diff buffer to commit
 only part of your changes, those whose hunks were left in the buffer.
 
----
 *** 'C-x v v' on an unregistered file will now use the most specific backend.
 Previously, if you had an SVN-covered "~/" directory, and a Git-covered
 directory in "~/foo/bar", using 'C-x v v' on a new, unregistered file
@@ -2285,28 +2019,23 @@ directory in "~/foo/bar", using 'C-x v v' on a new, 
unregistered file
 in the Git repository in "~/foo/bar".  This makes this command
 consistent with 'vc-responsible-backend'.
 
----
 *** Log Edit now fontifies long Git commit summary lines.
 Writing shorter summary lines avoids truncation in contexts in which
 Git commands display summary lines.  See the two new user options
 'vc-git-log-edit-summary-target-len' and 'vc-git-log-edit-summary-max-len'.
 
----
 *** New 'log-edit-headers-separator' face.
 It is used to style the line that separates the 'log-edit' headers
 from the 'log-edit' summary.
 
----
 *** The function 'vc-read-revision' accepts a new MULTIPLE argument.
 If non-nil, multiple revisions can be queried.  This is done using
 'completing-read-multiple'.
 
----
 *** New function 'vc-read-multiple-revisions'.
 This function invokes 'vc-read-revision' with a non-nil value for
 MULTIPLE.
 
-+++
 *** New command 'vc-prepare-patch'.
 Patches for any version control system can be prepared using VC.  The
 command will query what commits to send and will compose messages for
@@ -2316,32 +2045,26 @@ modified by the user options 
'vc-prepare-patches-separately' and
 
 ** Message
 
----
 *** New user option 'mml-attach-file-at-the-end'.
 If non-nil, 'C-c C-a' will put attached files at the end of the message.
 
----
 *** Message Mode now supports image yanking.
 
-+++
 *** New user option 'message-server-alist'.
 This controls automatic insertion of the "X-Message-SMTP-Method"
 header before sending a message.
 
 ** HTML Mode
 
----
 *** HTML Mode now supports "text/html" and "image/*" yanking.
 
 ** Texinfo Mode
 
----
 *** 'texinfo-mode' now has a specialized 'narrow-to-defun' definition.
 It narrows to the current node.
 
 ** EUDC
 
-+++
 *** Deprecations planned for next release.
 After Emacs 29.1, some aspects of EUDC will be deprecated.  The goal
 of these deprecations is to simplify EUDC server configuration by
@@ -2361,20 +2084,17 @@ possible servers, instead of requiring a call to 
'eudc-set-server'
 like it does in this release.  The default value of
 'eudc-ignore-options-file' will be changed from nil to t.
 
-+++
 *** New user option 'eudc-ignore-options-file' that defaults to nil.
 The 'eudc-ignore-options-file' user option can be configured to ignore
 the 'eudc-options-file' (typically "~/.emacs.d/eudc-options").  Most
 users should configure this to t and put EUDC configuration in the
 main Emacs initialization file ("~/.emacs" or "~/.emacs.d/init.el").
 
-+++
 *** 'eudc-expansion-overwrites-query' to 'eudc-expansion-save-query-as-kill'.
 The user option 'eudc-expansion-overwrites-query' is renamed to
 'eudc-expansion-save-query-as-kill' to reflect the actual behavior of
 the user option.  The former is kept as alias.
 
-+++
 *** New command 'eudc-expand-try-all'.
 This command can be used in place of 'eudc-expand-inline'.  It takes a
 prefix argument that causes 'eudc-expand-try-all' to return matches
@@ -2382,7 +2102,6 @@ from all servers instead of just the matches from the 
first server to
 return any.  This is useful for example, if one wants to search LDAP
 for a name that happens to match a contact in one's BBDB.
 
-+++
 *** New behavior and default for user option 'eudc-inline-expansion-format'.
 EUDC inline expansion result formatting defaulted to
 
@@ -2402,25 +2121,21 @@ is called, and the returned values are used to populate 
the phrase and
 comment parts (see RFC 5322 for definitions).  In both cases, the
 phrase part will be automatically quoted if necessary.
 
-+++
 *** New function 'eudc-capf-complete' with 'message-mode' integration.
 EUDC can now contribute email addresses to 'completion-at-point' by
 adding the new function 'eudc-capf-complete' to
 'completion-at-point-functions' in 'message-mode'.
 
-+++
 *** Additional attributes of query and results in eudcb-macos-contacts.el.
 The EUDC back-end for the macOS Contacts app now provides a wider set
 of attributes to use for queries, and delivers more attributes in
 query results.
 
-+++
 *** New back-end for ecomplete.
 A new back-end for ecomplete allows information from that database to
 be queried by EUDC, too.  The attributes present in the EUDC query are
 used to select the entry type in the ecomplete database.
 
-+++
 *** New back-end for mailabbrev.
 A new back-end for mailabbrev allows information from that database to
 be queried by EUDC, too.  Only the attributes 'email', 'name', and
@@ -2428,7 +2143,6 @@ be queried by EUDC, too.  Only the attributes 'email', 
'name', and
 
 ** EWW/SHR
 
-+++
 *** New user option to automatically rename EWW buffers.
 The 'eww-auto-rename-buffer' user option can be configured to rename
 rendered web pages by using their title, URL, or a user-defined
@@ -2437,26 +2151,22 @@ of the resulting name is controlled by the user option
 'eww-buffer-name-length'.  By default, no automatic renaming is
 performed.
 
-+++
 *** New user option 'shr-allowed-images'.
 This complements 'shr-blocked-images', but allows specifying just the
 allowed images.
 
-+++
 *** New user option 'shr-use-xwidgets-for-media'.
 If non-nil (and Emacs has been built with support for xwidgets),
 display <video> elements with an xwidget.  Note that this is
 experimental; it is known to crash Emacs on some systems, and just
 doesn't work on other systems.  Also see etc/PROBLEMS.
 
-+++
 *** New user option 'eww-url-transformers'.
 These are used to alter an URL before using it.  By default it removes
 the common "utm_" trackers from URLs.
 
 ** Find Dired
 
----
 *** New command 'find-dired-with-command'.
 This enables users to run 'find-dired' with an arbitrary command,
 enabling running commands previously unsupported and also enabling new
@@ -2464,7 +2174,6 @@ commands to be built on top.
 
 ** Gnus
 
-+++
 *** Tool bar changes in Gnus/Message.
 There were previously two styles of tool bars available in Gnus and
 Message, referred to as 'gnus-summary-tool-bar-retro',
@@ -2474,42 +2183,34 @@ Message, referred to as 'gnus-summary-tool-bar-retro',
 well as the icons used), and the "gnome" tool bars are now the only
 pre-defined toolbars.
 
----
 *** 'gnus-summary-up-thread' and 'gnus-summary-down-thread' bindings removed.
 The 'gnus-summary-down-thread' binding to 'M-C-d' was shadowed by
 'gnus-summary-read-document', and these commands are also available on
 'T u' and 'T d' respectively.
 
----
 *** Gnus now uses a variable-pitch font in the headers by default.
 To get the monospace font back, you can put something like the
 following in your ".gnus" file:
 
     (set-face-attribute 'gnus-header nil :inherit 'unspecified)
 
----
 *** The default value of 'gnus-treat-fold-headers' is now 'head'.
 
----
 *** New face 'gnus-header'.
 All other 'gnus-header-*' faces inherit from this face now.
 
-+++
 *** New user option 'gnus-treat-emojize-symbols'.
 If non-nil, symbols that have an Emoji representation will be
 displayed as emojis.  The default is nil.
 
-+++
 *** New command 'gnus-article-emojize-symbols'.
 This is bound to 'W D e' and will display symbols that have Emoji
 representation as Emoji.
 
-+++
 *** New mu backend for gnus-search.
 Configuration is very similar to the notmuch and namazu backends.  It
 supports the unified search syntax.
 
----
 *** 'gnus-html-image-cache-ttl' is now a seconds count.
 Formerly it was a pair of numbers '(A B)' that represented 65536*A + B,
 to cater to older Emacs implementations that lacked bignums.
@@ -2517,7 +2218,6 @@ The older form still works but is undocumented.
 
 ** Rmail
 
----
 *** Rmail partial summaries can now be applied one on top of the other.
 You can now narrow the set of messages selected by Rmail summary's
 criteria (recipients, topic, senders, etc.) by making a summary of the
@@ -2529,19 +2229,16 @@ to your selection.  The new user option
 the filters is in effect; customize it to a non-nil value to enable
 this feature.
 
----
 *** New Rmail summary: by thread.
 The new command 'rmail-summary-by-thread' produces a summary of
 messages that belong to a single thread of discussion.
 
 ** EIEIO
 
-+++
 *** 'slot-value' can now be used to access slots of 'cl-defstruct' objects.
 
 ** Align
 
----
 *** Alignment in 'text-mode' has changed.
 Previously, 'M-x align' didn't do anything, and you had to say 'C-u
 M-x align' for it to work.  This has now been changed.  The default
@@ -2550,12 +2247,10 @@ for inexperienced users to use.
 
 ** Help
 
----
 *** New mode, 'emacs-news-view-mode', for viewing the NEWS file.
 This mode is used by the 'C-h N' command, and adds buttons to manual
 entries and symbol references.
 
----
 *** New user option 'help-link-key-to-documentation'.
 When this option is non-nil (which is the default), key bindings
 displayed in the "*Help*" buffer will be linked to the documentation
@@ -2564,7 +2259,6 @@ key bindings and functions (such as 'C-h b').
 
 ** Info Look
 
----
 *** info-look specs can now be expanded at run time instead of a load time.
 The new ':doc-spec-function' element can be used to compute the
 ':doc-spec' element when the user asks for info on that particular
@@ -2572,19 +2266,16 @@ mode (instead of at load time).
 
 ** Ansi Color
 
----
 *** Support for ANSI 256-color and 24-bit colors.
 256-color and 24-bit color codes are now handled by ANSI color
 filters and displayed with the specified color.
 
 ** Term Mode
 
----
 *** New user option 'term-bind-function-keys'.
 If non-nil, 'term-mode' will pass the function keys on to the
 underlying shell instead of using the normal Emacs bindings.
 
----
 *** Support for ANSI 256-color and 24-bit colors, italic and other fonts.
 'term-mode' can now display 256-color and 24-bit color codes.  It can
 also handle ANSI codes for faint, italic and blinking text, displaying
@@ -2592,17 +2283,14 @@ it with new 'term-{faint,italic,slow-blink,fast-blink}' 
faces.
 
 ** Project
 
-+++
 *** 'project-find-file' and 'project-or-external-find-file' can include all.
 The commands 'project-find-file' and 'project-or-external-find-file'
 now accept a prefix argument, which is interpreted to mean "include
 all files".
 
-+++
 *** New command 'project-list-buffers' bound to 'C-x p C-b'.
 This command displays a list of buffers from the current project.
 
-+++
 *** 'project-kill-buffers' can display the list of buffers to kill.
 Customize the user option 'project-kill-buffers-display-buffer-list'
 to enable the display of the buffer list.
@@ -2614,19 +2302,16 @@ or projects outside of VCS repositories.
 As a consequence, the 'VC project backend' is formally renamed to
 'VC-aware project backend'.
 
-+++
 *** New user option 'project-vc-include-untracked'.
 If non-nil, files untracked by a VCS are considered to be part of
 the project by a VC project based on that VCS.
 
 ** Xref
 
-+++
 *** New command 'xref-go-forward'.
 It is bound to 'C-M-,' and jumps to the location where you previously
 invoked 'xref-go-back' ('M-,', also known as 'xref-pop-marker-stack').
 
-+++
 *** The depth of the Xref marker stack is now infinite.
 The implementation of the Xref marker stack was changed in a way that
 allows as many places to be saved on the stack as needed, limited only
@@ -2634,19 +2319,15 @@ by the available memory.  Therefore, the variables
 'find-tag-marker-ring-length' and 'xref-marker-ring-length' are now
 obsolete and unused; setting them has no effect.
 
-+++
 *** 'xref-query-replace-in-results' prompting change.
 This command no longer prompts for FROM when called without prefix
 argument.  This makes the most common case faster: replacing entire
 matches.
 
-+++
 *** New command 'xref-find-references-and-replace' to rename one identifier.
 
----
 *** New variable 'xref-current-item' (renamed from a private version).
 
----
 *** New function 'xref-show-xrefs'.
 
 *** 'outline-minor-mode' is supported in Xref buffers.
@@ -2655,12 +2336,10 @@ You can enable outlining by adding 'outline-minor-mode' 
to
 
 ** File Notifications
 
-+++
 *** The new command 'file-notify-rm-all-watches' removes all file 
notifications.
 
 ** Sql
 
----
 *** Sql now supports sending of passwords in-process.
 To improve security, if an sql product has ':password-in-comint' set
 to t, a password supplied via the minibuffer will be sent in-process,
@@ -2668,54 +2347,44 @@ as opposed to via the command-line.
 
 ** Image Mode
 
-+++
 *** New command 'image-transform-fit-to-window'.
 This command fits the image to the current window by scaling down or
 up as necessary.  Unlike 'image-transform-fit-both', this can scale
 the image up as well as down.  It is bound to 's w' in Image Mode by
 default.
 
----
 *** New command 'image-mode-wallpaper-set'.
 This command sets the desktop background to the current image.  It is
 bound to 'W' in Image Mode by default.
 
-+++
 *** 'image-transform-fit-to-{height,width}' are now obsolete.
 Use the new command 'image-transform-fit-to-window' instead.
 The keybinding for 'image-transform-fit-to-width' is now 's i'.
 
----
 *** User option 'image-auto-resize' can now be set to 'fit-window'.
 This works like 'image-transform-fit-to-window'.
 
----
 *** New user option 'image-auto-resize-max-scale-percent'.
 The new 'fit-window' option will never scale an image more than this
 much (in percent).  It is nil by default, which means no limit.
 
----
 *** New user option 'image-text-based-formats'.
 This controls whether or not to show a message, when opening certain
 image formats, explaining how to edit it as text.  The default is to
 show this message for SVG and XPM.
 
-+++
 *** New command 'image-transform-set-percent'.
 It allows resizing the image to a percentage of its original size, and
 is bound to 's p' in Image mode.
 
-+++
 *** 'image-transform-original' renamed to 'image-transform-reset-to-original'.
 The old name was confusing, and is now an obsolete function alias.
 
-+++
 *** 'image-transform-reset' renamed to 'image-transform-reset-to-initial'.
 The old name was confusing, and is now an obsolete function alias.
 
 ** Images
 
-+++
 *** New commands 'image-crop' and 'image-cut'.
 These commands allow interactively cropping/cutting the image at
 point.  The commands are bound to keys 'i c' and 'i x' (respectively)
@@ -2723,25 +2392,21 @@ in the local keymap over images.  They rely on external 
programs, by
 default "convert" from ImageMagick, to do the actual cropping/eliding
 of the image file.
 
-+++
 *** New commands 'image-flip-horizontally' and 'image-flip-vertically'.
 These commands horizontally and vertically flip the image under point,
 and are bound to 'i h' and 'i v', respectively.
 
-+++
 *** Users can now add special image conversion functions.
 This is done via 'image-converter-add-handler'.
 
 ** Image Dired
 
-+++
 *** 'image-dired-image-mode' is now based on 'image-mode'.
 This avoids converting images in the background, and makes Image-Dired
 noticeably faster.  New keybindings from 'image-mode' are now
 available in the "*image-dired-display-image*" buffer; press '?' or
 'h' in that buffer to see the full list.
 
----
 *** Navigation and marking commands now work in image display buffer.
 The following new bindings have been added:
 - 'n', 'SPC' => 'image-dired-display-next'
@@ -2750,52 +2415,43 @@ The following new bindings have been added:
 - 'd'        => 'image-dired-flag-thumb-original-file'
 - 'u'        => 'image-dired-unmark-thumb-original-file'
 
----
 *** New command 'image-dired-unmark-all-marks'.
 It removes all marks from all files in the thumbnail and the
 associated Dired buffer, and is bound to 'U' in the thumbnail and
 display buffer.
 
----
 *** New command 'image-dired-do-flagged-delete'.
 It deletes all flagged files, and is bound to 'x' in the thumbnail
 buffer.  It replaces the command 'image-dired-delete-marked', which is
 now an obsolete alias.
 
----
 *** New command 'image-dired-copy-filename-as-kill'.
 It copies the name of the marked or current image to the kill ring,
 and is bound to 'w' in the thumbnail buffer.
 
----
 *** New command 'image-dired-wallpaper-set'.
 This command sets the desktop background to the image at point in the
 thumbnail buffer.  It is bound to 'W' by default.
 
----
 *** 'image-dired-slideshow-start' is now bound to 'S'.
 It is bound in both the thumbnail and display buffer, and no longer
 prompts for a timeout; use a numerical prefix (e.g. 'C-u 8 S') to set
 the timeout.
 
----
 *** New user option 'image-dired-marking-shows-next'.
 If this option is non-nil (the default), marking, unmarking or
 flagging an image in either the thumbnail or display buffer shows the
 next image.
 
----
 *** New face 'image-dired-thumb-flagged'.
 If 'image-dired-thumb-mark' is non-nil (the default), this face is
 used for images that are flagged for deletion in the Dired buffer
 associated with Image-Dired.
 
----
 *** Image information is now shown in the header line of the thumbnail buffer.
 This replaces the message that most navigation commands in the
 thumbnail buffer used to show at the bottom of the screen.
 
----
 *** New specifiers for 'image-dired-display-properties-format'.
 This is used to format the new header line.  The new specifiers are:
 "%d" for the name of the directory that the file is in, "%n" for
@@ -2806,7 +2462,6 @@ old format, add this to your Init file:
 
     (setopt image-dired-display-properties-format "%b: %f (%t): %c")
 
----
 *** New faces for the header line of the thumbnail buffer.
 These faces correspond to different parts of the header line, as
 specified in 'image-dired-display-properties-format':
@@ -2815,37 +2470,31 @@ specified in 'image-dired-display-properties-format':
 - 'image-dired-thumb-header-file-size'
 - 'image-dired-thumb-header-image-count'
 
----
 *** PDF support.
 Image-Dired now displays thumbnails for PDF files.  Type 'RET' on a
 PDF file in the thumbnail buffer to visit the corresponding PDF.
 
----
 *** Support GraphicsMagick command line tools.
 Support for the GraphicsMagick command line tool ("gm") has been
 added, and is used when it is available instead of ImageMagick.
 
----
 *** Support Thumbnail Managing Standard v0.9.0 (Dec 2020).
 This standard allows sharing generated thumbnails across different
 programs.  Version 0.9.0 adds two larger thumbnail sizes: 512x512 and
 1024x1024 pixels.  See the user option 'image-dired-thumbnail-storage'
 to use it; it is not enabled by default.
 
----
 *** Reduce dependency on external "exiftool" program.
 The 'image-dired-copy-with-exif-file-name' command no longer requires
 an external "exiftool" program to be available.  The user options
 'image-dired-cmd-read-exif-data-program' and
 'image-dired-cmd-read-exif-data-options' are now obsolete.
 
----
 *** Support for bookmark.el.
 The command 'bookmark-set' (bound to 'C-x r m') is now supported in
 the thumbnail view, and will create a bookmark that opens the current
 directory in Image-Dired.
 
----
 *** The 'image-dired-slideshow-start' command no longer prompts.
 It no longer inconveniently prompts for a number of images and a
 delay: it runs indefinitely, but stops automatically on any command.
@@ -2853,7 +2502,6 @@ You can set the delay with a prefix argument, or a 
negative prefix
 argument to prompt for a delay.  Customize the user option
 'image-dired-slideshow-delay' to change the default from 5 seconds.
 
-+++
 *** 'image-dired-show-all-from-dir-max-files' increased to 1000.
 This user option controls asking for confirmation when starting
 Image-Dired in a directory with many files.  Since Image-Dired creates
@@ -2861,17 +2509,13 @@ thumbnails in the background in recent versions, this 
is not as
 important as it used to be.  You can now also customize this option to
 nil to disable this confirmation completely.
 
----
 *** 'image-dired-thumb-size' increased to 128.
 
-+++
 *** 'image-dired-db-file' renamed to 'image-dired-tags-db-file'.
 
----
 *** 'image-dired-display-image-mode' renamed to 'image-dired-image-mode'.
 The corresponding keymap is now named 'image-dired-image-mode-map'.
 
-+++
 *** Some commands have been renamed to be shorter.
 - 'image-dired-display-thumbnail-original-image' has been renamed to
   'image-dired-display-this'.
@@ -2881,25 +2525,21 @@ The corresponding keymap is now named 
'image-dired-image-mode-map'.
   to 'image-dired-display-previous'.
 The old names are now obsolete aliases.
 
----
 *** 'image-dired-thumb-{height,width}' are now obsolete.
 Customize 'image-dired-thumb-size' instead, which will set both the
 height and width.
 
----
 *** HTML image gallery generation is now obsolete.
 The 'image-dired-gallery-generate' command and these user options are
 now obsolete: 'image-dired-gallery-thumb-image-root-url',
 'image-dired-gallery-hidden-tags', 'image-dired-gallery-dir',
 'image-dired-gallery-image-root-url'.
 
----
 *** 'image-dired-rotate-thumbnail-{left,right}' are now obsolete.
 Instead, use commands 'image-dired-refresh-thumb' to generate a new
 thumbnail, or 'image-rotate' to rotate the thumbnail without updating
 the thumbnail file.
 
-+++
 *** Some commands and user options are now obsolete.
 Since 'image-dired-display-image-mode' is now based on 'image-mode',
 some commands and user options are no longer needed and are now obsolete:
@@ -2913,66 +2553,54 @@ some commands and user options are no longer needed and 
are now obsolete:
 
 ** Exif
 
----
 *** New function 'exif-field'.
 This is a convenience function to extract the field data from
 'exif-parse-file' and 'exif-parse-buffer'.
 
 ** Bookmarks
 
----
 *** 'list-bookmarks' now includes a type column.
 Types are registered via a 'bookmark-handler-type' symbol property on
 the jumping function.
 
-+++
 *** 'bookmark-sort-flag' can now be set to 'last-modified'.
 This will display bookmark list from most recently set to least
 recently set.
 
----
 *** When editing a bookmark annotation, 'C-c C-k' will now cancel.
 It is bound to the new command 'bookmark-edit-annotation-cancel'.
 
----
 *** New user option 'bookmark-fringe-mark'.
 This option controls the bitmap used to indicate bookmarks in the
 fringe (or nil to disable showing this marker).
 
 ** Xwidget
 
----
 *** New user option 'xwidget-webkit-buffer-name-format'.
 This option controls how xwidget-webkit buffers are named.
 
----
 *** New user option 'xwidget-webkit-cookie-file'.
 This option controls whether the xwidget-webkit buffers save cookies
 set by web pages, and if so, in which file to save them.
 
-+++
 *** New minor mode 'xwidget-webkit-edit-mode'.
 When this mode is enabled, self-inserting characters and other common
 web browser shortcut keys are redefined to send themselves to the
 WebKit widget.
 
-+++
 *** New minor mode 'xwidget-webkit-isearch-mode'.
 This mode acts similarly to incremental search, and allows searching
 the contents of a WebKit widget.  In xwidget-webkit mode, it is bound
 to 'C-s' and 'C-r'.
 
-+++
 *** New command 'xwidget-webkit-browse-history'.
 This command displays a buffer containing the page load history of
 the current WebKit widget, and allows you to navigate it.
 
----
 *** On X, the WebKit inspector is now available inside xwidgets.
 To access the inspector, right click on the widget and select "Inspect
 Element".
 
----
 *** "Open in New Window" in a WebKit widget's context menu now works.
 The newly created buffer will be displayed via 'display-buffer', which
 can be customized through the usual mechanism of 'display-buffer-alist'
@@ -2980,31 +2608,26 @@ and friends.
 
 ** Tramp
 
-+++
 *** New connection methods "docker", "podman" and "kubernetes".
 They allow accessing containers provided by Docker and similar
 programs.
 
----
 *** Tramp supports abbreviating remote home directories now.
 When calling 'abbreviate-file-name' on a Tramp file name, the result
 will abbreviate the user's home directory, for example by abbreviating
 "/ssh:user@host:/home/user" to "/ssh:user@host:~".
 
-+++
 *** New user option 'tramp-use-scp-direct-remote-copying'.
 When set to non-nil, Tramp does not copy files between two remote
 hosts via a local copy in its temporary directory, but lets the 'scp'
 command do this job.
 
-+++
 *** Proper password prompts for methods "doas", "sudo" and "sudoedit".
 The password prompts for these methods reflect now the credentials of
 the user requesting such a connection, and not of the user who is the
 target.  This has always been needed, just the password prompt and the
 related 'auth-sources' entry were wrong.
 
-+++
 *** New user option 'tramp-completion-use-cache'.
 During user and host name completion in the minibuffer, results from
 Tramp's connection cache are taken into account.  This can be disabled
@@ -3012,41 +2635,34 @@ by setting the user option 'tramp-completion-use-cache' 
to nil.
 
 ** Browse URL
 
----
 *** New user option 'browse-url-default-scheme'.
 This user option decides which URL scheme that 'browse-url' and
 related functions will use by default.  For example, you could
 customize this to "https" to always prefer HTTPS URLs.
 
----
 *** New user option 'browse-url-irc-function'.
 This option specifies a function for opening "irc://" links.  It
 defaults to the new function 'browse-url-irc'.
 
----
 *** New function 'browse-url-irc'.
 This multipurpose autoloaded function can be used for opening "irc://"
 and "ircs://" URLS by any caller that passes a URL string as an initial
 arg.
 
----
 *** Support for the Netscape web browser has been removed.
 This support has been obsolete since Emacs 25.1.  The final version of
 the Netscape web browser was released in February, 2008.
 
----
 *** Support for the Galeon web browser has been removed.
 This support has been obsolete since Emacs 25.1.  The final version of
 the Galeon web browser was released in September, 2008.
 
----
 *** Support for the Mozilla web browser is now obsolete.
 Note that this historical web browser is different from Mozilla
 Firefox; it is its predecessor.
 
 ** Python Mode
 
-+++
 *** Project shells and a new user option 'python-shell-dedicated'.
 When called with a prefix argument, 'run-python' now offers the choice
 of creating a shell dedicated to the current project.  This shell runs
@@ -3058,13 +2674,10 @@ project-dedicated or global) is specified by the new
 
 ** Ruby Mode
 
----
 *** New user option 'ruby-toggle-block-space-before-parameters'.
 
----
 *** Support for endless methods.
 
----
 *** New user options that determine indentation logic.
 'ruby-method-params-indent', 'ruby-block-indent',
 'ruby-after-operator-indent', 'ruby-method-call-indent',
@@ -3073,7 +2686,6 @@ explanations and examples.
 
 ** Eshell
 
-+++
 *** New feature to easily bypass Eshell's own pipelining.
 Prefixing '|', '<' or '>' with an asterisk, i.e. '*|', '*<' or '*>',
 will cause the whole command to be passed to the operating system
@@ -3082,7 +2694,6 @@ support for pipelines which will move a lot of data.  See 
section
 "Running Shell Pipelines Natively" in the Eshell manual, node
 "(eshell) Pipelines".
 
-+++
 *** New module to help supplying absolute file names to remote commands.
 After enabling the new 'eshell-elecslash' module, typing a forward
 slash as the first character of a command line argument will
@@ -3093,40 +2704,34 @@ commands are Lisp function or external when supplying 
absolute file
 name arguments.  See the "(eshell) Electric forward slash" node in the
 Eshell manual for details.
 
-+++
 *** Improved support for redirection operators in Eshell.
 Eshell now supports a wider variety of redirection operators.  For
 example, you can now redirect both stdout and stderr via '&>' or
 duplicate one output handle to another via 'NEW-FD>&OLD-FD'.  For more
 information, see the "(eshell) Redirection" node in the Eshell manual.
 
-+++
 *** New eshell built-in command 'doas'.
 The privilege-escalation program 'doas' has been added to the existing
 'su' and 'sudo' commands from the 'eshell-tramp' module.  The external
 command may still be accessed by using '*doas'.
 
-+++
 *** Double-quoting an Eshell expansion now treats the result as a single 
string.
 If an Eshell expansion like '$FOO' is surrounded by double quotes, the
 result will always be a single string, no matter the type that would
 otherwise be returned.
 
-+++
 *** Concatenating Eshell expansions now works more similarly to other shells.
 When concatenating an Eshell expansion that returns a list, "adjacent"
 elements of each operand are now concatenated together,
 e.g. '$(list "a" "b")c' returns '("a" "bc")'.  See the "(eshell)
 Expansion" node in the Eshell manual for more details.
 
-+++
 *** Eshell subcommands with multiline numeric output return lists of numbers.
 If every line of the output of an Eshell subcommand like '${COMMAND}'
 is numeric, the result will be a list of numbers (or a single number
 if only one line of output).  Previously, this only converted numbers
 when there was a single line of output.
 
----
 *** Built-in Eshell commands now follow Posix/GNU argument syntax conventions.
 Built-in commands in Eshell now accept command-line options with
 values passed as a single token, such as '-oVALUE' or
@@ -3134,13 +2739,11 @@ values passed as a single token, such as '-oVALUE' or
 'eshell-eval-using-options' macro.  See "Defining new built-in
 commands" in the "(eshell) Built-ins" node of the Eshell manual.
 
----
 *** Eshell globs ending with "/" now match only directories.
 Additionally, globs ending with "**/" or "***/" no longer raise an
 error, and now expand to all directories recursively (following
 symlinks in the latter case).
 
-+++
 *** Lisp forms in Eshell now treat a nil result as a failed exit status.
 When executing a command that looks like '(lisp form)' and returns
 nil, Eshell will set the exit status (available in the '$?'
@@ -3150,12 +2753,10 @@ conditionals.  To change this behavior, customize the 
new
 
 ** Shell
 
----
 *** New user option 'shell-kill-buffer-on-exit'.
 Enabling this will automatically kill a "*shell*" buffer as soon as
 the shell session terminates.
 
----
 *** New minor mode 'shell-highlight-undef-mode'.
 Customize 'shell-highlight-undef-enable' to t if you want to enable
 this minor mode in "*shell*" buffers.  It will highlight undefined
@@ -3163,13 +2764,11 @@ commands with a warning face as you type.
 
 ** Calc
 
-+++
 *** New user option 'calc-kill-line-numbering'.
 Set it to nil to exclude line numbering from kills and copies.
 
 ** Hierarchy
 
-+++
 *** Tree Display can delay computation of children.
 'hierarchy-add-tree' and 'hierarchy-add-trees' have an optional
 argument which allows tree-widget display to be activated and computed
@@ -3177,7 +2776,6 @@ only when the user expands the node.
 
 ** Proced
 
----
 *** proced.el shows system processes of remote hosts.
 When 'default-directory' is remote, and 'proced' is invoked with a
 negative argument like 'C-u - proced', the system processes of that
@@ -3185,7 +2783,6 @@ remote host are shown.  Alternatively, the user option
 'proced-show-remote-processes' can be set to non-nil.
 'proced-signal-function' has been marked obsolete.
 
----
 *** Proced can now optionally show process details in color.
 New user option 'proced-enable-color-flag' enables coloring of Proced
 buffers.  This option is disabled by default; customize it to a
@@ -3193,36 +2790,30 @@ non-nil value to enable colors.
 
 ** Miscellaneous
 
----
 *** New user option 'webjump-use-internal-browser'.
 When non-nil, WebJump will use an internal browser to open web pages,
 instead of the default external browser.
 
-+++
 *** New user option 'font-lock-ignore'.
 This option provides a mechanism to selectively disable font-lock
 keyword-driven fontifications.
 
----
 *** New user option 'auto-save-visited-predicate'.
 This user option is a predicate function which is called by
 'auto-save-visited-mode' to decide whether or not to save a buffer.
 You can use it to automatically save only specific buffers, for
 example buffers using a particular mode or in some directory.
 
----
 *** New user option 'remote-file-name-inhibit-auto-save-visited'.
 If this user option is non-nil, 'auto-save-visited-mode' will not
 auto-save remote buffers.  The default is nil.
 
-+++
 *** New package vtable.el for formatting tabular data.
 This package allows formatting data using variable-pitch fonts.
 The resulting tables can display text in variable pitch fonts, text
 using fonts of different sizes, and images.  See the "(vtable) Top"
 manual for more details.
 
----
 *** New minor mode 'elide-head-mode'.
 Enabling this minor mode turns on hiding header material, like
 'elide-head' does; disabling it shows the header.  The commands
@@ -3241,27 +2832,22 @@ filtered out.
 The list of handlers (already covering OSC 7 and 8) has been extended
 with a handler for OSC 2, the command to set a window title.
 
----
 *** 'recentf-mode' now uses abbreviated file names by default.
 This means that e.g. "/home/foo/bar" is now displayed as "~/bar".
 Customize the user option 'recentf-filename-handlers' to nil to get
 back the old behavior.
 
----
 *** New command 'recentf-open'.
 This command prompts for a recently opened file in the minibuffer, and
 visits it.
 
----
 *** 'ffap-machine-at-point' no longer pings hosts by default.
 It will now simply look at a hostname to determine if it is valid,
 instead of also trying to ping it.  Customize the user option
 'ffap-machine-p-known' to 'ping' to get the old behavior back.
 
----
 *** The 'run-dig' command is now obsolete; use 'dig' instead.
 
----
 *** Some 'bib-mode' commands and variables have been renamed.
 To respect Emacs naming conventions, the variable 'unread-bib-file'
 has been renamed to 'bib-unread-file'.  The following commands have
@@ -3271,36 +2857,29 @@ also been renamed:
     'mark-bib'         to  'bib-mark'
     'unread-bib'       to  'bib-unread'
 
----
 *** 'outlineify-sticky' command is renamed to 'allout-outlinify-sticky'.
 The old name is still available as an obsolete function alias.
 
----
 *** The url-irc library now understands "ircs://" links.
 
----
 *** New command 'world-clock-copy-time-as-kill' for 'world-clock-mode'.
 It copies the current line into the kill ring.
 
----
 *** 'edit-abbrevs' now uses font-locking.
 The new face 'abbrev-table-name' is used to display the abbrev table
 name.
 
----
 *** New key binding 'O' in "*Buffer List*".
 This key is now bound to 'Buffer-menu-view-other-window', which will
 view this line's buffer in View mode in another window.
 
 ** Scheme Mode
 
----
 *** Auto-detection of Scheme library files.
 Emacs now automatically enables the Scheme mode when opening R6RS
 Scheme Library Source (".sls") files and R7RS Scheme Library
 Definition (".sld") files.
 
----
 *** Imenu members for R6RS and R7RS library members.
 Imenu now lists the members directly nested in R6RS Scheme libraries
 ('library') and R7RS libraries ('define-library').
@@ -3308,7 +2887,6 @@ Imenu now lists the members directly nested in R6RS 
Scheme libraries
 
 * New Modes and Packages in Emacs 29.1
 
-+++
 ** Eglot: Emacs Client for the Language Server Protocol.
 Emacs now comes with the Eglot package, which enhances various Emacs
 features, such as completion, documentation, error detection, etc.,
@@ -3320,7 +2898,6 @@ If you want to be able to use 'package-install' to 
upgrade Eglot to
 newer versions released on GNU ELPA, customize the new option
 'package-install-upgrade-built-in' to a non-nil value.
 
-+++
 ** use-package: Declarative package configuration.
 use-package is now shipped with Emacs.  It provides the 'use-package'
 macro, which allows you to isolate package configuration in your init
@@ -3331,7 +2908,6 @@ If you want to be able to use 'package-install' to 
upgrade use-package
 to newer versions released on GNU ELPA, customize the new option
 'package-install-upgrade-built-in' to a non-nil value.
 
----
 ** New package 'wallpaper'.
 This package provides the command 'wallpaper-set', which sets the
 desktop background image.  Depending on the system and the desktop,
@@ -3341,7 +2917,6 @@ detected automatically in most cases.  It can also be 
customized
 manually if needed, using the new user options 'wallpaper-command' and
 'wallpaper-command-args'.
 
-+++
 ** New package 'oclosure'.
 This allows the creation of OClosures, which are "functions with
 slots" or "function objects" that expose additional information about
@@ -3349,33 +2924,27 @@ themselves.  Use the new macros 'oclosure-define' and
 'oclosure-lambda' to create OClosures.  See the "(elisp) OClosures"
 node for more information.
 
-+++
 *** New generic function 'oclosure-interactive-form'.
 Used by 'interactive-form' when called on an OClosure.
 This allows specific OClosure types to compute their interactive specs
 on demand rather than precompute them when created.
 
----
 ** 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
 Emacs buffers, like indentation and the like.  The new ert function
 'ert-test-erts-file' is used to parse these files.
 
----
 ** New major mode 'js-json-mode'.
 This is a lightweight variant of 'js-mode' that is used by default
 when visiting JSON files.
 
-+++
 ** New major mode 'csharp-mode'.
 A major mode based on CC Mode for editing programs in the C# language.
 This mode is auto-enabled for files with the ".cs" extension.
 
-+++
 ** New major modes based on the tree-sitter library.
 These new major modes are available if Emacs was built with the
 tree-sitter library.  They provide support for font-locking,
@@ -3417,96 +2986,77 @@ If a language grammar library required by a mode is not 
found in any
 of the above places, the mode will display a warning when you try to
 turn it on.
 
-+++
 *** New major mode 'typescript-ts-mode'.
 A major mode based on the tree-sitter library for editing programs
 in the TypeScript language.
 
-+++
 *** New major mode 'tsx-ts-mode'.
 A major mode based on the tree-sitter library for editing programs
 in the TypeScript language, with support for TSX.
 
-+++
 *** New major mode 'c-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the C language.
 
-+++
 *** New major mode 'c++-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the C++ language.
 
-+++
 *** New command 'c-or-c++-ts-mode'.
 A command that automatically guesses the language of a header file,
 and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly.
 
-+++
 *** New major mode 'java-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the Java language.
 
-+++
 *** New major mode 'python-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the Python language.
 
-+++
 *** New major mode 'css-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 CSS (Cascading Style Sheets).
 
-+++
 *** New major mode 'json-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the JSON language.
 
-+++
 *** New major mode 'csharp-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the C# language.
 
-+++
 *** New major mode 'bash-ts-mode'.
 Am optional major mode based on the tree-sitter library for editing
 Bash shell scripts.
 
-+++
 *** New major mode 'dockerfile-ts-mode'.
 A major mode based on the tree-sitter library for editing
 Dockerfiles.
 
-+++
 *** New major mode 'cmake-ts-mode'.
 A major mode based on the tree-sitter library for editing CMake files.
 
-+++
 *** New major mode 'toml-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 files written in TOML, a format for writing configuration files.
 
-+++
 *** New major mode 'go-ts-mode'.
 A major mode based on the tree-sitter library for editing programs in
 the Go language.
 
-+++
 *** New major mode 'go-mod-ts-mode'.
 A major mode based on the tree-sitter library for editing "go.mod"
 files.
 
-+++
 *** New major mode 'yaml-ts-mode'.
 A major mode based on the tree-sitter library for editing files
 written in YAML.
 
-+++
 *** New major mode 'rust-ts-mode'.
 A major mode based on the tree-sitter library for editing programs in
 the Rust language.
 
----
 *** New major mode 'ruby-ts-mode'.
 An optional major mode based on the tree-sitter library for editing
 programs in the Ruby language.
@@ -3514,7 +3064,6 @@ programs in the Ruby language.
 
 * Incompatible Lisp Changes in Emacs 29.1
 
-+++
 ** The implementation of overlays has changed.
 Emacs now uses an implementation of overlays that is much more
 efficient than the original one, and should speed up all the
@@ -3528,7 +3077,6 @@ or user level, with the exception of better performance 
and the order
 of overlays returned by functions that don't promise any particular
 order.
 
----
 *** The function 'overlay-recenter' is now a no-op.
 This function does nothing, and in particular has no effect on the
 value returned by 'overlay-lists'.  The purpose of 'overlay-recenter'
@@ -3538,30 +3086,25 @@ is efficient regardless of their position, and there's 
no longer any
 need to "optimize" the lookup, nor any notion of a "center" of the
 overlays.
 
----
 *** The function 'overlay-lists' returns one unified list of overlays.
 This function used to return a cons of two lists, one with overlays
 before the "center" position, the other after that "center".  It now
 returns a list whose 'car' is the list of all the buffer overlays, and
 whose 'cdr' is always nil.
 
-+++
 ** 'format-prompt' now uses 'substitute-command-keys'.
 This means that both the prompt and 'minibuffer-default-prompt-format'
 will have key definitions and single quotes handled specially.
 
-+++
 ** New function 'substitute-quotes'.
 This function works like 'substitute-command-keys' but only
 substitutes quote characters.
 
----
 ** 'find-image' now uses 'create-image'.
 This means that images found through 'find-image' also have
 auto-scaling applied.  (This only makes a difference on HiDPI
 displays.)
 
-+++
 ** Changes in how "raw" in-memory XBM images are specified.
 Some years back Emacs gained the ability to scale images, and you
 could then specify ':width' and ':height' when using 'create-image' on all
@@ -3573,7 +3116,6 @@ has been changed, and ':width'/':height' now works as 
with all other image
 formats, and the way to specify the width/height of the "raw"
 in-memory format is now by using ':data-width' and ':data-height'.
 
-+++
 ** "loaddefs.el" generation has been reimplemented.
 The various "loaddefs.el" files in the Emacs tree (which contain
 information about autoloads, built-in packages and package prefixes)
@@ -3589,19 +3131,16 @@ Previously, ';;;###' specs inside a top-level form 
(i.e., something
 like '(when ... ;;;### ...)' would be ignored.  They are now parsed as
 usual.
 
----
 ** Themes have special autoload cookies.
 All built-in themes are scraped for ';;;###theme-autoload' cookies
 that are loaded along with the regular auto-loaded code.
 
-+++
 ** 'buffer-modified-p' has been extended.
 This function was previously documented to return only nil or t.  This
 has been changed to nil/'autosaved'/non-nil.  The new 'autosaved'
 value means that the buffer is modified, but that it hasn't been
 modified since the time of last auto-save.
 
----
 ** 'with-silent-modifications' also restores buffer autosave status.
 'with-silent-modifications' is a macro meant to be used by the font
 locking machinery to allow applying text properties without changing
@@ -3610,7 +3149,6 @@ buffer autosave status, so applying font locking to a 
modified buffer
 that had already been auto-saved would trigger another auto-saving.
 This is no longer the case.
 
----
 ** 'prin1' doesn't always escape "." and "?" in symbols any more.
 Previously, symbols like 'foo.bar' would be printed by 'prin1' as
 "foo\.bar".  This now prints as "foo.bar" instead.  The Emacs Lisp
@@ -3626,19 +3164,16 @@ If the "." and "?" characters are the first character 
in the symbol,
 they will still be escaped, so the '.foo' symbol is still printed as
 "\.foo" and the '?bar' symbol is still printed as "\?bar".
 
-+++
 ** Remapping 'mode-line' face no longer works as expected.
 'mode-line' is now the parent face of the new 'mode-line-active' face,
 and remapping parent of basic faces does not work reliably.
 Instead of remapping 'mode-line', you have to remap 'mode-line-active'.
 
-+++
 ** 'make-process' has been extended to support ptys when ':stderr' is set.
 Previously, setting ':stderr' to a non-nil value would force the
 process's connection to use pipes.  Now, Emacs will use a pty for
 stdin and stdout if requested no matter the value of ':stderr'.
 
----
 ** User option 'mail-source-ignore-errors' is now obsolete.
 The whole mechanism for prompting users to continue in case of
 mail-source errors has been removed, so this option is no longer
@@ -3646,7 +3181,6 @@ needed.
 
 ** Fonts
 
----
 *** Emacs now supports 'medium' fonts.
 Emacs previously didn't distinguish between the 'regular'/'normal'
 weight and the 'medium' weight, but it now also supports the (heavier)
@@ -3655,7 +3189,6 @@ weight and the 'medium' weight, but it now also supports 
the (heavier)
 font spec.  In these cases, replacing ":weight 'normal" with ":weight
 'medium" should fix the issue.
 
----
 ** Keymap descriptions by Help commands have changed.
 'help--describe-command', 'C-h b' and associated functions that output
 keymap descriptions have changed.  In particular, prefix commands are
@@ -3664,7 +3197,6 @@ functions output "[closure]"/"[lambda]".  You can get 
back the old
 behavior of including prefix commands by customizing the new option
 'describe-bindings-show-prefix-commands' to a non-nil value.
 
----
 ** 'downcase' details have changed slightly.
 In certain locales, changing the case of an ASCII-range character may
 turn it into a multibyte character, most notably with "I" in Turkish
@@ -3676,13 +3208,11 @@ get proper locale-dependent downcasing, the string has 
to be converted
 to multibyte first.  (This goes for the other case-changing functions,
 too.)
 
----
 ** Functions in 'tramp-foreign-file-name-handler-alist' have changed.
 Functions to determine which Tramp file name handler to use are now
 passed a file name in dissected form (via 'tramp-dissect-file-name')
 instead of in string form.
 
----
 ** 'def' indentation changes.
 In 'emacs-lisp-mode', forms with a symbol with a name that start with
 "def" have been automatically indented as if they were 'defun'-like
@@ -3702,33 +3232,26 @@ like:
 
     (put 'defzot 'lisp-indent-function 'defun)
 
----
 ** The 'inhibit-changing-match-data' variable is now obsolete.
 Instead, functions like 'string-match' and 'looking-at' now take an
 optional INHIBIT-MODIFY argument.
 
----
 ** 'gnus-define-keys' is now obsolete.
 Use 'define-keymap' instead.
 
----
 ** MozRepl has been removed from js.el.
 MozRepl was removed from Firefox in 2017, so this code doesn't work
 with recent versions of Firefox.
 
----
 ** The function 'image-dired-get-exif-data' is now obsolete.
 Use 'exif-parse-file' and 'exif-field' instead.
 
----
 ** 'insert-directory' alternatives should not change the free disk space line.
 This change is now applied in 'dired-insert-directory'.
 
----
 ** 'compilation-last-buffer' is (finally) declared obsolete.
 It has been obsolete since Emacs 22.1, actually.
 
----
 ** Calling 'lsh' now elicits a byte-compiler warning.
 'lsh' behaves in somewhat surprising and platform-dependent ways for
 negative arguments, and is generally slower than 'ash', which should be
@@ -3736,7 +3259,6 @@ used instead.  This warning can be suppressed by 
surrounding calls to
 'lsh' with the construct '(with-suppressed-warnings ((suspicious lsh)) ...)',
 but switching to 'ash' is generally much preferable.
 
----
 ** Some functions and variables obsolete since Emacs 24 have been removed:
 'Buffer-menu-buffer+size-width', 'Electric-buffer-menu-mode',
 'Info-edit-map', 'allout-abbreviate-flattened-numbering',
@@ -3834,7 +3356,6 @@ but switching to 'ash' is generally much preferable.
 'which-func-mode' (function), 'window-system-version',
 'winner-mode-leave-hook', 'x-cut-buffer-or-selection-value'.
 
----
 ** Some functions and variables obsolete since Emacs 23 have been removed:
 'find-emacs-lisp-shadows', 'newsticker-cache-filename',
 'process-filter-multibyte-p', 'redisplay-end-trigger-functions',
@@ -3842,17 +3363,14 @@ but switching to 'ash' is generally much preferable.
 'unify-8859-on-decoding-mode', 'unify-8859-on-encoding-mode',
 'vc-arch-command', 'window-redisplay-end-trigger', 'x-selection'.
 
----
 ** Some functions and variables obsolete since Emacs 21 or 22 have been 
removed:
 'c-toggle-auto-state', 'find-file-not-found-hooks',
 'ls-lisp-dired-ignore-case', 'query-replace-regexp-eval'.
 
-+++
 ** New generic function 'function-documentation'.
 It can dynamically generate a raw docstring depending on the type of a
 function.  Used mainly for docstrings of OClosures.
 
-+++
 ** Base64 encoding no longer tolerates latin-1 input.
 The functions 'base64-encode-string', 'base64url-encode-string',
 'base64-encode-region' and 'base64url-encode-region' no longer accept
@@ -3860,24 +3378,20 @@ characters in the range U+0080..U+00FF as substitutes 
for single bytes
 in the range 128..255, but signal an error for all multibyte characters.
 The input must be unibyte encoded text.
 
-+++
 ** The 'clone-indirect-buffer-hook' is now run by 'make-indirect-buffer'.
 It was previously only run by 'clone-indirect-buffer' and
 'clone-indirect-buffer-other-window'.  Since 'make-indirect-buffer' is
 called by both of these, the hook is now run by all 3 of these
 functions.
 
----
 ** '?\' at the end of a line now signals an error.
 Previously, it produced a nonsense value, -1, that was never intended.
 
----
 ** Some libraries obsolete since Emacs 24.1 and 24.3 have been removed:
 abbrevlist.el, assoc.el, complete.el, cust-print.el,
 erc-hecomplete.el, mailpost.el, mouse-sel.el, old-emacs-lock.el,
 patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el.
 
-+++
 ** Many seldom-used generalized variables have been made obsolete.
 Emacs has a number of rather obscure generalized variables defined,
 that, for instance, allowed you to say things like:
@@ -3903,7 +3417,6 @@ The following generalized variables have been made 
obsolete:
 'standard-case-table', 'syntax-table', 'visited-file-modtime',
 'window-height', 'window-width', and 'x-get-secondary-selection'.
 
----
 ** The 'dotimes' loop variable can no longer be manipulated in the loop body.
 Previously, the 'dotimes' loop counter could be modified inside the
 loop body, but only in code using dynamic binding.  Now the behavior
@@ -3919,7 +3432,6 @@ now always prints the numbers 0 .. 9.
 
 * Lisp Changes in Emacs 29.1
 
-+++
 ** Interpreted closures are "safe for space".
 As was already the case for byte-compiled closures, instead of capturing
 the whole current lexical environment, interpreted closures now only
@@ -3928,55 +3440,45 @@ The previous behavior could occasionally lead to memory 
leaks or
 to problems where a printed closure would not be 'read'able because
 of an un'read'able value in an unrelated lexical variable.
 
-+++
 ** New accessor function 'file-attribute-file-identifier'.
 It returns the list of the inode number and device identifier
 retrieved by 'file-attributes'.  This value can be used to identify a
 file uniquely.  The device identifier can be a single number or (for
 remote files) a cons of 2 numbers.
 
-+++
 ** New macro 'while-let'.
 This is like 'when-let', but repeats until a binding form is nil.
 
-+++
 ** New function 'make-obsolete-generalized-variable'.
 This can be used to mark setters used by 'setf' as obsolete, and the
 byte-compiler will then warn about using them.
 
-+++
 ** New functions 'pos-eol' and 'pos-bol'.
 These are like 'line-end-position' and 'line-beginning-position'
 (respectively), but ignore fields (and are more efficient).
 
-+++
 ** New function 'compiled-function-p'.
 This returns non-nil if its argument is either a built-in, or a
 byte-compiled, or a natively-compiled function object, or a function
 loaded from a dynamic module.
 
----
 ** 'deactivate-mark' can have new value 'dont-save'.
 This value means that Emacs should deactivate the mark as usual, but
 without setting the primary selection, if 'select-active-regions' is
 enabled.
 
-+++
 ** New 'declare' form 'interactive-args'.
 This can be used to specify what forms to put into 'command-history'
 when executing commands interactively.
 
-+++
 ** The FORM argument of 'time-convert' is mandatory.
 'time-convert' can still be called without it, as before, but the
 compiler now emits a warning about this deprecated usage.
 
-+++
 ** Emacs now supports user-customizable and themable icons.
 These can be used for buttons in buffers and the like.  See the
 "(elisp) Icons" and "(emacs) Icons" nodes in the manuals for details.
 
-+++
 ** New arguments MESSAGE and TIMEOUT of 'set-transient-map'.
 MESSAGE specifies a message to display after activating the transient
 map, including a special formatting spec to list available keys.
@@ -3984,7 +3486,6 @@ TIMEOUT is the idle time after which to deactivate the 
transient map.
 The default timeout value can be defined by the new variable
 'set-transient-map-timeout'.
 
-+++
 ** New forms 'with-restriction' and 'without-restriction'.
 These forms can be used as enhanced alternatives to the
 'save-restriction' form combined with, respectively,
@@ -3994,88 +3495,70 @@ See the "(elisp) Narrowing" node for details.
 
 ** Connection Local Variables
 
-+++
 *** Some connection-local variables are now user options.
 The variables 'connection-local-profile-alist' and
 'connection-local-criteria-alist' are now user options, in order to
 make it more convenient to inspect and modify them.
 
-+++
 *** New function 'connection-local-update-profile-variables'.
 This function allows to modify the settings of an existing
 connection-local profile.
 
-+++
 *** New macro 'with-connection-local-application-variables'.
 This macro works like 'with-connection-local-variables', but it allows
 using another application instead of 'tramp'.  This is useful when
 running code in a buffer where Tramp has already set some
 connection-local variables.
 
-+++
 *** New macro 'setq-connection-local'.
 This allows dynamically setting variable values for a particular
 connection within the body of 'with-connection-local-{application-}variables'.
 See the "(elisp) Connection Local Variables" node in the Lisp
 Reference manual for more information.
 
-+++
 ** 'plist-get', 'plist-put' and 'plist-member' are no longer limited to 'eq'.
 These function now take an optional comparison PREDICATE argument.
 
-+++
 ** 'read-multiple-choice' can now use long-form answers.
 
-+++
 ** 'M-s c' in 'read-regexp' now toggles case folding.
 
-+++
 ** 'completing-read' now allows a function as its REQUIRE-MATCH argument.
 This function is called to see whether what the user has typed is a
 match.  This is also available from functions that call
 'completing-read', like 'read-file-name'.
 
-+++
 ** 'posn-col-row' can now give position data based on windows.
 Previously, it reported data only based on the frame.
 
-+++
 ** 'file-expand-wildcards' can now also take a regexp as PATTERN argument.
 
----
 ** vc-mtn (the VC backend for Monotone) has been made obsolete.
 
-+++
 ** 'gui-set-selection' can specify different values for different data types.
 If DATA is a string, then its text properties are searched for values
 for each specific data type while the selection is being converted.
 
----
 ** New eldoc function 'elisp-eldoc-var-docstring-with-value'.
 This function includes the current value of the variable in eldoc display
 and can be used as a more detailed alternative to 'elisp-eldoc-var-docstring'.
 
-+++
 ** 'save-some-buffers' can now be extended to save other things.
 Traditionally, 'save-some-buffers' saved buffers, and also saved
 abbrevs.  This has been generalized via the
 'save-some-buffers-functions' variable, and packages can now register
 things to be saved.
 
-+++
 ** New function 'string-equal-ignore-case'.
 This compares strings ignoring case differences.
 
-+++
 ** 'symbol-file' can now report natively-compiled ".eln" files.
 If Emacs was built with native-compilation enabled, Lisp programs can
 now call 'symbol-file' with the new optional 3rd argument non-nil to
 request the name of the ".eln" file which defined a given symbol.
 
-+++
 ** New macro 'with-memoization' provides a very primitive form of memoization.
 
-+++
 ** 'max-char' can now report the maximum codepoint according to Unicode.
 When called with a new optional argument UNICODE non-nil, 'max-char'
 will now report the maximum valid codepoint defined by the Unicode
@@ -4083,46 +3566,37 @@ Standard.
 
 ** Seq
 
-+++
 *** New function 'seq-split'.
 This returns a list of sub-sequences of the specified sequence.
 
-+++
 *** New function 'seq-remove-at-position'.
 This function returns a copy of the specified sequence with the
 element at a given (zero-based) index removed.
 
-+++
 *** New function 'seq-positions'.
 This returns a list of the (zero-based) indices of elements matching a
 given predicate in the specified sequence.
 
-+++
 *** New function 'seq-keep'.
 This is like 'seq-map', but removes all nil results from the returned
 list.
 
 ** Themes
 
----
 *** New hooks 'enable-theme-functions' and 'disable-theme-functions'.
 These are run after enabling and disabling a theme, respectively.
 
----
 *** Themes can now be made obsolete.
 Using 'make-obsolete' on a theme is now supported.  This will make
 'load-theme' issue a warning when loading the theme.
 
-+++
 ** New hook 'display-monitors-changed-functions'.
 It is called whenever the configuration of different monitors on a
 display changes.
 
-+++
 ** 'prin1' and 'prin1-to-string' now take an optional OVERRIDES argument.
 This argument can be used to override values of print-related settings.
 
-+++
 ** New minor mode 'header-line-indent-mode'.
 This is meant to be used by Lisp programs that show a header line
 which should be kept aligned with the buffer contents when the user
@@ -4130,12 +3604,10 @@ switches 'display-line-numbers-mode' on or off, and 
when the width of
 line-number display changes.  See the "(elisp) Header Lines" node in
 the Emacs Lisp Reference manual for more information.
 
-+++
 ** New global minor mode 'lost-selection-mode'.
 This global minor mode makes Emacs deactivate the mark in all buffers
 when the primary selection is obtained by another program.
 
----
 ** On X, Emacs will try to preserve selection ownership when a frame is 
deleted.
 This means that if you make Emacs the owner of a selection, such as by
 selecting some text into the clipboard or primary selection, and then
@@ -4144,13 +3616,11 @@ contents of that selection into other programs as long 
as another
 frame is open on the same display.  This behavior can be disabled by
 setting the user option 'x-auto-preserve-selections' to nil.
 
-+++
 ** New predicate 'char-uppercase-p'.
 This returns non-nil if its argument its an uppercase character.
 
 ** Byte Compilation
 
----
 *** Byte compilation will now warn about some quoting mistakes in docstrings.
 When writing code snippets that contains the "'" character (APOSTROPHE),
 that quote character has to be escaped to avoid Emacs displaying it as
@@ -4164,7 +3634,6 @@ QUOTATION MARK directly.  In both these cases, if these 
characters
 should really be present in the docstring, they should be quoted with
 "\=".
 
----
 *** Byte compilation will now warn about some malformed 'defcustom' types.
 It is very common to write 'defcustom' types on the form:
 
@@ -4174,137 +3643,111 @@ I.e., double-quoting the 'bar', which is almost never 
the correct
 value.  The byte compiler will now issue a warning if it encounters
 these forms.
 
-+++
 ** 'restore-buffer-modified-p' can now alter buffer auto-save state.
 With a FLAG value of 'autosaved', it will mark the buffer as having
 been auto-saved since the time of last modification.
 
----
 ** New minor mode 'isearch-fold-quotes-mode'.
 This sets up 'search-default-mode' so that quote characters are
 char-folded into each other.  It is used, by default, in "*Help*" and
 "*info*" buffers.
 
-+++
 ** New macro 'buffer-local-set-state'.
 This is a helper macro to be used by minor modes that wish to restore
 buffer-local variables back to their original states when the mode is
 switched off.
 
----
 ** New macro 'with-buffer-unmodified-if-unchanged'.
 If the buffer is marked as unmodified, and code does modifications
 that, in total, means that the buffer is identical to the buffer
 before, mark the buffer as unmodified again.
 
----
 ** New function 'malloc-trim'.
 This function allows returning unused memory back to the operating
 system, and is mainly meant as a debugging tool.  It is currently
 available only when Emacs was built with glibc as the C library.
 
----
 ** 'x-show-tip' no longer hard-codes a timeout default.
 The new variable 'x-show-tooltip-timeout' allows the user to alter
 this for packages that don't use 'tooltip-show', but instead call the
 lower level function directly.
 
----
 ** New function 'current-cpu-time'.
 It gives access to the CPU time used by the Emacs process, for
 example for benchmarking purposes.
 
----
 ** New function 'string-edit'.
 This is meant to be used when the user has to edit a (potentially)
 long string.  It pops up a new buffer where you can edit the string,
 and the provided callback is called when the user types 'C-c C-c'.
 
-+++
 ** New function 'read-string-from-buffer'.
 This is a modal version of 'string-edit', and can be used as an
 alternative to 'read-string'.
 
-+++
 ** The return value of 'clear-message-function' is not ignored anymore.
 If the function returns 'dont-clear-message', then the message is not
 cleared, with the assumption that the function cleared it itself.
 
-+++
 ** The local variables section now supports defining fallback modes.
 This was previously only available when using a property line (i.e.,
 putting the modes on the first line of a file).
 
-+++
 ** New function 'flush-standard-output'.
 This enables display of lines that don't end in a newline from
 batch-based Emacs scripts.
 
-+++
 ** New convenience function 'buttonize-region'.
 This works like 'buttonize', but for a region instead of a string.
 
-+++
 ** 'macroexp-let2*' can omit TEST argument and use single-var bindings.
 
-+++
 ** New macro-writing macros, 'cl-with-gensyms' and 'cl-once-only'.
 See the "(cl) Macro-Writing Macros" manual section for descriptions.
 
-+++
 ** New variable 'last-event-device' and new function 'device-class'.
 On X Windows, 'last-event-device' specifies the input extension device
 from which the last input event originated, and 'device-class' can be
 used to determine the type of an input device.
 
-+++
 ** Variable 'track-mouse' can have a new value 'drag-source'.
 This means the same as 'dropping', but modifies the mouse position
 list in reported motion events if there is no frame underneath the
 mouse pointer.
 
-+++
 ** New functions for dragging items from Emacs to other programs.
 The new functions 'x-begin-drag', 'dnd-begin-file-drag',
 'dnd-begin-drag-files', and 'dnd-direct-save' allow dragging contents
 (such as files and text) from Emacs to other programs.
 
----
 ** New function 'ietf-drums-parse-date-string'.
 This function parses RFC5322 (and RFC822) date strings, and should be
 used instead of 'parse-time-string' when parsing data that's standards
 compliant.
 
-+++
 ** New macro 'setopt'.
 This is like 'setq', but is meant to be used for user options instead
 of plain variables, and uses 'custom-set'/'set-default' to set them.
 
-+++
 ** 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
 read back by the Emacs Lisp reader.
 
-+++
 ** New variable 'print-unreadable-function'.
 This variable allows changing how Emacs prints unreadable objects.
 
----
 ** The user option 'polling-period' now accepts floating point values.
 This means Emacs can now poll for input during Lisp execution more
 frequently than once in a second.
 
----
 ** New function 'bidi-string-strip-control-characters'.
 This utility function is meant for displaying strings when it is
 essential that there's no bidirectional context.  It removes all the
@@ -4312,67 +3755,54 @@ bidirectional formatting control characters (such as 
RLM, LRO, PDF,
 etc.) from its argument string.  The characters it removes are listed
 in the value of 'bidi-control-characters'.
 
----
 ** The Gnus range functions have been moved to a new library, range.el.
 All the old names have been made obsolete.
 
-+++
 ** New function 'function-alias-p'.
 This predicate says whether an object is a function alias, and if it
 is, the alias chain is returned.
 
-+++
 ** New variable 'lisp-directory' holds the directory of Emacs's own Lisp files.
 
-+++
 ** New facility for handling session state: 'multisession-value'.
 This can be used as a convenient way to store (simple) application
 state, and the command 'list-multisession-values' allows users to list
 (and edit) this data.
 
-+++
 ** New function 'get-display-property'.
 This is like 'get-text-property', but works on the 'display' text
 property.
 
-+++
 ** New function 'add-display-text-property'.
 This is like 'put-text-property', but works on the 'display' text
 property.
 
-+++
 ** New 'min-width' 'display' property.
 This allows setting a minimum display width for a region of text.
 
-+++
 ** New 'cursor-face' text property.
 This uses 'cursor-face' instead of the default face when cursor is on or
 near the character and 'cursor-face-highlight-mode' is enabled.  The
 user option 'cursor-face-highlight-nonselected-window' is similar to
 'highlight-nonselected-windows', but for this property.
 
-+++
 ** New event type 'touch-end'.
 This event is sent whenever the user's finger moves off the mouse
 wheel on some mice, or when the user's finger moves off the touchpad.
 
-+++
 ** New event type 'pinch'.
 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.
 
----
 ** New hook 'post-select-region-hook'.
 This hook is run immediately after 'select-active-regions'.  It causes
 the region to be set as the primary selection.
 
-+++
 ** New function 'buffer-match-p'.
 Check if a buffer satisfies some condition.  Some examples for
 conditions can be regular expressions that match a buffer name, a
@@ -4380,19 +3810,16 @@ cons-cell like '(major-mode . shell-mode)' that matches 
any buffer
 where 'major-mode' is 'shell-mode' or a combination with a condition
 like '(and "\\`\\*.+\\*\\'" (major-mode . special-mode))'.
 
-+++
 ** New function 'match-buffers'.
 It uses 'buffer-match-p' to gather a list of buffers that match a
 condition.
 
----
 ** New optional arguments TEXT-FACE and DEFAULT-FACE for 'tooltip-show'.
 They allow changing the faces used for the tooltip text and frame
 colors of the resulting tooltip frame from the default 'tooltip' face.
 
 ** Text Security and Suspiciousness
 
-+++
 *** New library textsec.el.
 This library contains a number of checks for whether a string is
 "suspicious".  This usually means that the string contains characters
@@ -4400,7 +3827,6 @@ that have glyphs that can be confused with other, more 
commonly used
 glyphs, or contains bidirectional (or other) formatting characters
 that may be used to confuse a user.
 
-+++
 *** New user option 'textsec-check'.
 If non-nil (which is the default), Emacs packages that are vulnerable
 to attackers trying to confuse the users will use the textsec library
@@ -4410,7 +3836,6 @@ Message mode will query the user if the user is sending 
mail to a
 suspicious address.  If this variable is nil, these checks are
 disabled.
 
-+++
 *** New function 'textsec-suspicious-p'.
 This is the main function Emacs applications should be using to check
 whether a string is suspicious.  It heeds the 'textsec-check' user
@@ -4418,13 +3843,11 @@ option.
 
 ** Keymaps and Key Definitions
 
-+++
 *** 'where-is-internal' can now filter events marked as non key events.
 If a command maps to a key binding like '[some-event]', and 'some-event'
 has a symbol plist containing a non-nil 'non-key-event' property, then
 that binding is ignored by 'where-is-internal'.
 
-+++
 *** New functions for defining and manipulating keystrokes.
 These all take the syntax defined by 'key-valid-p', which is basically
 the same syntax as the one accepted by the 'kbd' macro.  None of the
@@ -4432,68 +3855,51 @@ older functions have been deprecated or altered, but 
they are now
 de-emphasized in the documentation, and we encourage Lisp programs to
 switch to these new functions.
 
-+++
 *** Use 'keymap-set' instead of 'define-key'.
 
-+++
 *** Use 'keymap-global-set' instead of 'global-set-key'.
 
-+++
 *** Use 'keymap-local-set' instead of 'local-set-key'.
 
-+++
 *** Use 'keymap-global-unset' instead of 'global-unset-key'.
 
-+++
 *** Use 'keymap-local-unset' instead of 'local-unset-key'.
 
-+++
 *** Use 'keymap-substitute' instead of 'substitute-key-definition'.
 
-+++
 *** Use 'keymap-set-after' instead of 'define-key-after'.
 
-+++
 *** Use 'keymap-lookup' instead of 'lookup-key' and 'key-binding'.
 
-+++
 *** Use 'keymap-local-lookup' instead of 'local-key-binding'.
 
-+++
 *** Use 'keymap-global-lookup' instead of 'global-key-binding'.
 
-+++
 *** 'define-key' now takes an optional REMOVE argument.
 If non-nil, remove the definition from the keymap.  This is subtly
 different from setting a definition to nil: when the keymap has a
 parent such a definition will shadow the parent's definition.
 
-+++
 *** 'read-multiple-choice' now takes an optional SHOW-HELP argument.
 If non-nil, show the help buffer immediately, before any user input.
 
-+++
 *** New function 'key-valid-p'.
 The 'kbd' function is quite permissive, and will try to return
 something usable even if the syntax of the argument isn't completely
 correct.  The 'key-valid-p' predicate does a stricter check of the
 syntax.
 
----
 *** New function 'key-parse'.
 This is like 'kbd', but only returns vectors instead of a mix of
 vectors and strings.
 
-+++
 *** New ':type' for 'defcustom' for keys.
 The new 'key' type can be used for options that should be a valid key
 according to 'key-valid-p'.  The type 'key-sequence' is now obsolete.
 
-+++
 ** New function 'define-keymap'.
 This function allows defining a number of keystrokes with one form.
 
-+++
 ** New macro 'defvar-keymap'.
 This macro allows defining keymap variables more conveniently.
 
@@ -4503,11 +3909,9 @@ advanced usage:
 
     :repeat (:enter (commands ...) :exit (commands ...))
 
----
 ** 'kbd' can now be used in built-in, preloaded libraries.
 It no longer depends on edmacro.el and cl-lib.el.
 
-+++
 ** New substitution in docstrings and 'substitute-command-keys'.
 Use \\`KEYSEQ' to insert a literal key sequence "KEYSEQ" (for example
 \\`C-k') in a docstring or when calling 'substitute-command-keys',
@@ -4516,7 +3920,6 @@ be used only when a key sequence has no corresponding 
command, for
 example when it is read directly with 'read-key-sequence'.  It must be
 a valid key sequence according to 'key-valid-p'.
 
----
 ** 'lookup-key' is more permissive when searching for extended menu items.
 In Emacs 28.1, the behavior of 'lookup-key' was changed: when looking
 for a menu item '[menu-bar Foo-Bar]', first try to find an exact
@@ -4528,61 +3931,49 @@ an exact match, then the lowercased '[menu-bar foo\ 
bar]' and finally
 '[menu-bar foo-bar]'.  This further improves backwards-compatibility
 when converting menus to use 'easy-menu-define'.
 
-+++
 ** New function 'file-name-split'.
 This returns a list of all the components of a file name.
 
-+++
 ** New function 'file-name-parent-directory'.
 This returns the parent directory of a file name.
 
-+++
 ** New macro 'with-undo-amalgamate'.
 It records a particular sequence of operations as a single undo step.
 
-+++
 ** New command 'yank-media'.
 This command supports yanking non-plain-text media like images and
 HTML from other applications into Emacs.  It is only supported in
 modes that have registered support for it, and only on capable
 platforms.
 
-+++
 ** New command 'yank-media-types'.
 This command lets you examine all data in the current selection and
 the clipboard, and insert it into the buffer.
 
-+++
 ** New variable 'yank-transform-functions'.
 This variable allows the user to alter the string to be inserted.
 
----
 ** New command 'yank-in-context'.
 This command tries to preserve string/comment syntax when yanking.
 
----
 ** New function 'minibuffer-lazy-highlight-setup'.
 This function allows setting up the minibuffer so that lazy
 highlighting of its content is applied in the original window.
 
-+++
 ** New text property 'inhibit-isearch'.
 If set, 'isearch' will skip these areas, which can be useful (for
 instance) when covering huge amounts of data (that has no meaningful
 searchable data, like image data) with a 'display' text property.
 
-+++
 ** 'insert-image' now takes an INHIBIT-ISEARCH optional argument.
 It marks the image with the 'inhibit-isearch' text property, which
 inhibits 'isearch' matching the STRING argument.
 
----
 ** New variable 'replace-regexp-function'.
 Function to call to convert the entered FROM string to an Emacs
 regexp in 'query-replace' and similar commands.  It can be used to
 implement a different 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'
@@ -4598,59 +3989,49 @@ default value from the previous FROM-TO pair.
 
 ** Lisp pretty-printer ('pp')
 
----
 *** New function 'pp-emacs-lisp-code'.
 'pp' formats general Lisp sexps.  This function does much the same,
 but applies formatting rules appropriate for Emacs Lisp code.  Note
 that this could currently be quite slow, and is thus appropriate only
 for relatively small code fragments.
 
----
 *** New user option 'pp-use-max-width'.
 If non-nil, 'pp' and all 'pp-*' commands that format the results, will
 attempt to limit the line length when formatting long lists and
 vectors.  This uses 'pp-emacs-lisp-code', and thus could be slow for
 large lists.
 
-+++
 ** New function 'file-has-changed-p'.
 This convenience function is useful when writing code that parses
 files at run-time, and allows Lisp programs to re-parse files only
 when they have changed.
 
-+++
 ** 'abbreviate-file-name' now respects magic file name handlers.
 
----
 ** New function 'font-has-char-p'.
 This can be used to check whether a specific font has a glyph for a
 character.
 
-+++
 ** 'window-text-pixel-size' now accepts a new argument IGNORE-LINE-AT-END.
 This controls whether or not the last screen line of the text being
 measured will be counted for the purpose of calculating the text
 dimensions.
 
-+++
 ** 'window-text-pixel-size' understands a new meaning of FROM.
 Specifying a cons as the FROM argument allows to start measuring text
 from a specified amount of pixels above or below a position.
 
-+++
 ** 'window-body-width' and 'window-body-height' can use remapped faces.
 Specifying 'remap' as the PIXELWISE argument now checks if the default
 face was remapped, and if so, uses the remapped face to determine the
 character width/height.
 
-+++
 ** 'set-window-vscroll' now accepts a new argument PRESERVE-VSCROLL-P.
 This means the vscroll will not be reset when set on a window that is
 "frozen" due to a mini-window being resized.
 
 ** XDG Support
 
----
 *** New function 'xdg-state-home'.
 It returns the new 'XDG_STATE_HOME' environment variable.  It should
 point to a file name that "contains state data that should persist
@@ -4659,7 +4040,6 @@ enough to the user that it should be stored in 
$XDG_DATA_HOME".
 (This variable was introduced in the XDG Base Directory Specification
 version 0.8 released on May 8, 2021.)
 
----
 *** New function 'xdg-current-desktop'.
 It returns a list of strings, corresponding to the colon-separated
 list of names in the 'XDG_CURRENT_DESKTOP' environment variable, which
@@ -4667,83 +4047,68 @@ identify the current desktop environment.
 (This variable was introduced in XDG Desktop Entry Specification
 version 1.2.)
 
----
 *** New function 'xdg-session-type'.
 It returns the 'XDG_SESSION_TYPE' environment variable.  (This is not
 part of any official standard; see the man page pam_systemd(8) for
 more information.)
 
-+++
 ** New macro 'with-delayed-message'.
 This macro is like 'progn', but will output the specified message if
 the body takes longer to execute than the specified timeout.
 
----
 ** New function 'funcall-with-delayed-message'.
 This function is like 'funcall', but will output the specified message
 if the function takes longer to execute than the specified timeout.
 
 ** Locale
 
----
 *** New variable 'current-locale-environment'.
 This holds the value of the previous call to 'set-locale-environment'.
 
----
 *** New macro 'with-locale-environment'.
 This macro can be used to change the locale temporarily while
 executing code.
 
 ** Table
 
----
 *** New user option 'table-latex-environment'.
 This allows switching between "table" and "tabular".
 
 ** Tabulated List Mode
 
-+++
 *** A column can now be set to an image descriptor.
 The 'tabulated-list-entries' variable now supports using an image
 descriptor, which means to insert an image in that column instead of
 text.  See the documentation string of that variable for details.
 
-+++
 ** ':keys' in 'menu-item' can now be a function.
 If so, it is called whenever the menu is computed, and can be used to
 calculate the keys dynamically.
 
-+++
 ** New major mode 'clean-mode'.
 This is a new major mode meant for debugging.  It kills absolutely all
 local variables and removes overlays and text properties.
 
-+++
 ** 'kill-all-local-variables' can now kill all local variables.
 If given the new optional KILL-PERMANENT argument, it also kills
 permanent local variables.
 
-+++
 ** Third 'mapconcat' argument SEPARATOR is now optional.
 An explicit nil always meant the empty string, now it can be left out.
 
-+++
 ** New function 'image-at-point-p'.
 This function returns t if point is on a valid image, and nil
 otherwise.
 
-+++
 ** New function 'buffer-text-pixel-size'.
 This is similar to 'window-text-pixel-size', but can be used when the
 buffer isn't displayed.
 
-+++
 ** New function 'string-pixel-width'.
 This returns the width of a string in pixels.  This can be useful when
 dealing with variable pitch fonts and glyphs that have widths that
 aren't integer multiples of the default font.
 
-+++
 ** New function 'string-glyph-split'.
 This function splits a string into a list of strings representing
 separate glyphs.  This takes into account combining characters and
@@ -4752,13 +4117,11 @@ display as a single unit.
 
 ** Xwidget
 
-+++
 *** The function 'make-xwidget' now accepts an optional RELATED argument.
 This argument is used as another widget for the newly created WebKit
 widget to share settings and subprocesses with.  It must be another
 WebKit widget.
 
-+++
 *** New function 'xwidget-perform-lispy-event'.
 This function allows you to send events to xwidgets.  Usually, some
 equivalent of the event will be sent, but there is no guarantee of
@@ -4766,33 +4129,27 @@ what the widget will actually receive.
 
 On GTK+, only key and function key events are implemented.
 
-+++
 *** New function 'xwidget-webkit-load-html'.
 This function is used to load HTML text into WebKit xwidgets
 directly, in contrast to creating a temporary file to hold the
 markup, and passing the URI of the file as an argument to
 'xwidget-webkit-goto-uri'.
 
-+++
 *** New functions for performing searches on WebKit xwidgets.
 Some new functions, such as 'xwidget-webkit-search', have been added
 for performing searches on WebKit xwidgets.
 
-+++
 *** New function 'xwidget-webkit-back-forward-list'.
 This function returns the history of page-loads in a WebKit xwidget.
 
-+++
 *** New function 'xwidget-webkit-estimated-load-progress'.
 This function returns the estimated progress of page loading in a
 WebKit xwidget.
 
-+++
 *** New function 'xwidget-webkit-stop-loading'.
 This function terminates all data transfer during page loads in a
 WebKit xwidget.
 
-+++
 *** 'load-changed' xwidget events are now more detailed.
 In particular, they can now have different arguments based on the
 state of the WebKit widget.  'load-finished' is sent when a load has
@@ -4800,84 +4157,68 @@ completed, 'load-started' when a load first starts, 
'load-redirected'
 after a redirect, and 'load-committed' when the WebKit widget first
 commits to the load.
 
-+++
 *** New event type 'xwidget-display-event'.
 These events are sent whenever an xwidget requests that Emacs displays
 another xwidget.  The only arguments to this event are the xwidget
 that should be displayed, and the xwidget that asked to display it.
 
-+++
 *** New function 'xwidget-webkit-set-cookie-storage-file'.
 This function is used to control where and if an xwidget stores
 cookies set by web pages on disk.
 
----
 ** New variable 'help-buffer-under-preparation'.
 This variable is bound to t during the preparation of a "*Help*" buffer.
 
-+++
 ** Timestamps like '(1 . 1000)' now work without warnings being generated.
 For example, '(time-add nil '(1 . 1000))' no longer warns that the
 '(1 . 1000)' acts like '(1000 . 1000000)'.  This warning, which was a
 temporary transition aid for Emacs 27, has served its purpose.
 
-+++
 ** 'encode-time' now also accepts a 6-element list with just time and date.
 '(encode-time (list SECOND MINUTE HOUR DAY MONTH YEAR))' is now short for
 '(encode-time (list SECOND MINUTE HOUR DAY MONTH YEAR nil -1 nil))'.
 
-+++
 ** 'date-to-time' now accepts arguments that lack month, day, or time.
 The function now assumes the earliest possible values if its argument
 lacks month, day, or time.  For example, (date-to-time "2021-12-04")
 now assumes a time of "00:00" instead of signaling an error.
 
-+++
 ** 'format-seconds' now allows suppressing zero-value trailing elements.
 The new "%x" non-printing control character will suppress zero-value
 elements that appear after "%x".
 
-+++
 ** New events for taking advantage of touchscreen devices.
 The events 'touchscreen-begin', 'touchscreen-update', and
 'touchscreen-end' have been added to take better advantage of
 touch-capable display panels.
 
-+++
 ** New error symbol 'permission-denied'.
 This is a subcategory of 'file-error', and is signaled when some file
 operation fails because the OS doesn't allow Emacs to access a file or
 a directory.
 
-+++
 ** The ':underline' face attribute now accepts a new property.
 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.
 
----
 ** New hook 'save-place-after-find-file-hook'.
 This is called at the end of 'save-place-find-file-hook'.
 
----
 ** 'indian-tml-base-table' no longer translates digits.
 Use 'indian-tml-base-digits-table' if you want digits translation.
 
----
 ** 'indian-tml-itrans-v5-hash' no longer translates digits.
 Use 'indian-tml-itrans-digits-v5-hash' if you want digits
 translation.
 
-+++
 ** 'shell-quote-argument' has a new optional argument POSIX.
 This is useful when quoting shell arguments for a remote shell
 invocation.  Such shells are POSIX conformant by default.
 
-+++
 ** 'make-process' can set connection type independently for input and output.
 When calling 'make-process', communication via pty can be enabled
 selectively for just input or output by passing a cons cell for
@@ -4886,14 +4227,12 @@ later, you can determine whether a particular stream 
for a process
 uses a pty by passing one of 'stdin', 'stdout', or 'stderr' as the
 second argument to 'process-tty-name'.
 
-+++
 ** 'signal-process' now consults the list 'signal-process-functions'.
 This is to determine which function has to be called in order to
 deliver the signal.  This allows Tramp to send the signal to remote
 asynchronous processes.  The hitherto existing implementation has been
 moved to 'internal-default-signal-process'.
 
-+++
 ** Some system information functions honor remote systems now.
 'list-system-processes' returns remote process IDs.
 'memory-info' returns memory information of remote systems.
@@ -4905,21 +4244,17 @@ remote.  In order to preserve the old behavior, bind
     (let ((default-directory temporary-file-directory))
       (list-system-processes))
 
-+++
 ** New functions 'take' and 'ntake'.
 '(take N LIST)' returns the first N elements of LIST; 'ntake' does
 the same but works by modifying LIST destructively.
 
----
 ** 'string-split' is now an alias for 'split-string'.
 
-+++
 ** 'format-spec' now accepts functions in the replacement.
 The function is called only when used in the format string.  This is
 useful to avoid side-effects such as prompting, when the value is not
 actually being used for anything.
 
-+++
 ** The variable 'max-specpdl-size' has been made obsolete.
 Now 'max-lisp-eval-depth' alone is used for limiting Lisp recursion
 and stack usage.  'max-specpdl-size' is still present as a plain
@@ -4933,11 +4268,9 @@ set is too big to transfer to Emacs every time a 
completion is
 needed.  The table uses new 'external' completion style exclusively
 and cannot work with regular styles such as 'basic' or 'flex'.
 
-+++
 ** Magic file name handlers for 'make-directory-internal' are no longer needed.
 Instead, Emacs uses the already-existing 'make-directory' handlers.
 
-+++
 ** '(make-directory DIR t)' returns non-nil if DIR already exists.
 This can let a caller know whether it created DIR.  Formerly,
 'make-directory's return value was unspecified.
@@ -4947,7 +4280,6 @@ This can let a caller know whether it created DIR.  
Formerly,
 
 ** MS-Windows
 
----
 *** Emacs now supports double-buffering on MS-Windows to reduce display 
flicker.
 (This was supported on Free systems since Emacs 26.1.)
 
@@ -4962,14 +4294,12 @@ selected frame by evaluating
 
     (modify-frame-parameters nil '((inhibit-double-buffering . t)))
 
-+++
 *** Emacs now supports system dark mode.
 On Windows 10 (version 1809 and higher) and Windows 11, Emacs will now
 follow the system's dark mode: GUI frames use the appropriate light or
 dark title bar and scroll bars, based on the user's Windows-wide color
 settings.
 
----
 *** Emacs now uses native image APIs to display some image formats.
 On Windows 2000 and later, Emacs now defaults to using the native
 image APIs for displaying the BMP, GIF, JPEG, PNG, and TIFF images.
@@ -4982,12 +4312,10 @@ The use of native image APIs is controlled by the 
variable
 'w32-use-native-image-API', whose value now defaults to t on systems
 where those APIs are available.
 
-+++
 *** Emacs now supports display of BMP images using native image APIs.
 When 'w32-use-native-image-API' is non-nil, Emacs on MS-Windows now
 has built-in support for displaying BMP images.
 
----
 *** GUI Yes/No dialogs now include a "Cancel" button.
 The "Cancel" button is in addition to "Yes" and "No", and is intended
 to allow users to quit the dialog, as an equivalent of 'C-g' when Emacs
@@ -4998,12 +4326,10 @@ two buttons: "Yes" and "No".
 
 ** Cygwin
 
----
 *** 'process-attributes' is now implemented.
 
 ** macOS
 
-+++
 *** The 'ns-popup-font-panel' command has been removed.
 Use the general command 'M-x menu-set-font' instead.
 
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 6dc56dd9e81..265e28e5ddc 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -516,7 +516,7 @@ directory copy is ineffective.
 This is due to an arbitrary limit in certain versions of awk.
 The solution is to use gawk (GNU awk).
 
-*** Saving, via EasyPG, a file encrypted with GnuPG hangs
+*** Saving a file encrypted with GnuPG via EasyPG hangs.
 
 This is known to happen with GnuPG v2.4.1.  The only known workaround
 is to downgrade to a version of GnuPG older than 2.4.1 (or, in the
@@ -575,6 +575,20 @@ This can happen with CVS versions 1.12.8 and 1.12.9.  
Upgrade to CVS
 
 ** Miscellaneous problems
 
+*** 'set-mouse-color' and the '-ms' command line argument do not work.
+
+Systems where the default cursors are not simple 1 bit-per-pixel
+bitmaps usually forbid recoloring the cursor, since it is unclear
+which colors should replace those already present within each cursor
+image.  For example, 'set-mouse-color' and '-ms' have no function on X
+systems with GNOME, KDE, and other recent desktop environments
+employing cursor images containing colors and partial transparency.
+
+Changing the cursor color is also impossible on MS-Windows and PGTK
+systems.  In the former case, it is because the prerequisite code has
+yet to be written.  In the latter, it is because GTK does not provide
+for changing the color of cursor images.
+
 *** Display artifacts on GUI frames on X-based systems.
 
 This is known to be caused by using double-buffering (which is enabled
@@ -1163,43 +1177,6 @@ do anything about it.
 
 ** International characters aren't displayed under X.
 
-*** Missing X fonts
-
-XFree86 4 contains many fonts in iso10646-1 encoding which have
-minimal character repertoires (whereas the encoding part of the font
-name is meant to be a reasonable indication of the repertoire
-according to the XLFD spec).  Emacs may choose one of these to display
-characters from the mule-unicode charsets and then typically won't be
-able to find the glyphs to display many characters.  (Check with C-u
-C-x = .)  To avoid this, you may need to use a fontset which sets the
-font for the mule-unicode sets explicitly.  E.g. to use GNU unifont,
-include in the fontset spec:
-
-mule-unicode-2500-33ff:-gnu-unifont-*-iso10646-1,\
-mule-unicode-e000-ffff:-gnu-unifont-*-iso10646-1,\
-mule-unicode-0100-24ff:-gnu-unifont-*-iso10646-1
-
-** The UTF-8/16/7 coding systems don't encode CJK (Far Eastern) characters.
-
-Emacs directly supports the Unicode BMP whose code points are in the
-ranges 0000-33ff and e000-ffff, and indirectly supports the parts of
-CJK characters belonging to these legacy charsets:
-
-    GB2312, Big5, JISX0208, JISX0212, JISX0213-1, JISX0213-2, KSC5601
-
-The latter support is done in Utf-Translate-Cjk mode (turned on by
-default).   Which Unicode CJK characters are decoded into which Emacs
-charset is decided by the current language environment.  For instance,
-in Chinese-GB, most of them are decoded into chinese-gb2312.
-
-If you read UTF-8 data with code points outside these ranges, the
-characters appear in the buffer as raw bytes of the original UTF-8
-(composed into a single quasi-character) and they will be written back
-correctly as UTF-8, assuming you don't break the composed sequences.
-If you read such characters from UTF-16 or UTF-7 data, they are
-substituted with the Unicode 'replacement character', and you lose
-information.
-
 ** Accented ISO-8859-1 characters are displayed as | or _.
 
 Try other font set sizes (S-mouse-1).  If the problem persists with
@@ -1237,6 +1214,16 @@ In your ~/.Xresources file, then run
 
 And restart Emacs.
 
+** Emacs hangs when using XIM
+
+This is due to an old bug in the implementation of the X protocol's
+XIM transport: when an input method crashes for some reason, Xlib
+cannot recover.  Emacs cannot do anything about this except wait for
+the I-Bux developers to fix their crashes.  You can work around these
+problems by disabling XIM in your X resources:
+
+  Emacs.useXIM: false
+
 ** On Haiku, BeCJK doesn't work properly with Emacs
 
 Some popular Haiku input methods such BeCJK are known to behave badly
@@ -3366,7 +3353,7 @@ this and many other problems do not exist on the regular 
X builds.
 ** Text displayed in the default monospace font looks horrible.
 
 Droid Sans Mono (the default Monospace font which comes with Android)
-comes with instruction code designed for Microsoft's proprietary
+incorporates instruction code designed for Microsoft's proprietary
 TrueType font scaler.  When this code is executed by Emacs to instruct
 a glyph containing more than one component, it tries to address
 "reference points" which are set to the values of two extra "phantom
@@ -3411,6 +3398,80 @@ you are not seeing problems with character display, as 
the
 automatically generated instructions result in superior display
 results that are easier to read.
 
+We have been told that the default Sans font under Android 2.3.7,
+named "Droid Sans", also exhibits this problem.  The procedure for
+repairing the font is identical to the procedure outlined above,
+albeit with "DroidSansMono" replaced by simply "DroidSans".
+
+** The "Anonymous Pro" font displays incorrectly.
+
+Glyph instruction code within the Anonymous Pro font relies on
+undocumented features of the Microsoft TrueType font scaler, namely
+that the scaler always resets the "projection" and "freedom" vector
+interpreter control registers after the execution of the font
+pre-program, which sets them to a value that is perpendicular to the
+horizontal plane of movement.
+
+Since Emacs does not provide this "feature", various points inside
+glyphs are moved vertically rather than horizontally when a glyph
+program later executes an instruction such as "MIRP" (Move Indirect
+Relative Point) that moves and measures points along the axis
+specified by those registers.
+
+This can be remedied in two ways; the first (and the easiest) is to
+replace its instruction code with that supplied by "ttfautohint", as
+depicted above.  The second is to patch the instruction code inside
+the font itself, using the "ttx" utility:
+
+  https://fonttools.readthedocs.io/en/latest/ttx.html
+
+First, convert the font to its XML representation:
+
+  $ ttx Anonymous_Pro.ttf
+
+then, find the end of the section labeled 'prep':
+
+  <prep>
+    <assembly>
+      [...]
+      ROUND[01]        /* Round */
+      RTG[ ]   /* RoundToGrid */
+      WCVTP[ ] /* WriteCVTInPixels */
+    </assembly>
+  </prep>
+
+and insert the following instruction immediately before the closing
+'/assembly' tag, so as to reset the interpreter control registers back
+to their default values prior to the completion of the pre-program:
+
+     SVTCA[1]  /* Set Vector registers to Control Axis X */
+
+Then, reassemble the font from the modified XML:
+
+  $ ttx Anonymous_Pro.ttx
+
+which should produce a modified font by the name of
+Anonymous_Pro#1.ttf.
+
+** CJK text does not display in Emacs, but does in other programs.
+
+When inserting CJK text into a buffer or visiting a file containing
+CJK text, Emacs often fails to locate a suitable font.  This problem
+manifests itself as hollow squares with numbers and letters within
+being displayed in lieu of the text itself.
+
+The reason for this is Emacs's absence of support for OpenType fonts
+utilizing CFF (Compact Font Format) outlines, which the CJK fonts
+bundled with Android have been distributed as since Android 7.0.
+
+The solution is to install a TrueType CJK font to the user fonts
+directory detailed in the "Android Fonts" node of the Emacs manual.
+
+Introducing support for the byzantine CFF font format into the Android
+port is a large undertaking that we are looking for volunteers to
+perform.  If you are interested in taking responsibility for this
+task, please contact <emacs-devel@gnu.org>.
+
 * Build-time problems
 
 ** Configuration
diff --git a/etc/TODO b/etc/TODO
index f097e76b917..a918f496863 100644
--- a/etc/TODO
+++ b/etc/TODO
@@ -1748,6 +1748,19 @@ The former is based on the GVFS archive backend, which 
makes it
 available on GNU/Linux only.  That implementation has further
 drawbacks like it doesn't support to write into archives.
 
+** Provide support for CFF outlines in the Android port.
+
+The file src/sfnt.c supplies the font backend for the Android port.
+It is presently a self contained TrueType scaler, implementing both a
+grayscale outline generator and an instruction code interpreter.
+
+Support for CFF (Compact Font Format) outlines will facilitate
+utilizing fonts distributed as ".otf" files, a category that currently
+encompasses all CJK and some Middle Eastern and Indic fonts
+distributed with Android, obviating the present requirement for users
+of such scripts to actively install TrueType versions of fonts
+otherwise bundled with the system.
+
 * Other known bugs
 
 ** 'make-frame' forgets unhandled parameters, at least for X11 frames
diff --git a/etc/themes/leuven-dark-theme.el b/etc/themes/leuven-dark-theme.el
index bfe5256ab97..33a15945e71 100644
--- a/etc/themes/leuven-dark-theme.el
+++ b/etc/themes/leuven-dark-theme.el
@@ -95,7 +95,7 @@ CONTROL can be a number, nil, or t.  When t, use 
DEFAULT-HEIGHT."
 
 ;;;###theme-autoload
 (deftheme leuven-dark
-  "Face colors with a light background.
+  "Face colors with a dark background.
 Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff,
 Flyspell, Semantic, and Ansi-Color faces are included -- and much
 more..."
diff --git a/exec/configure.ac b/exec/configure.ac
index e78d8ebea90..180c200d13d 100644
--- a/exec/configure.ac
+++ b/exec/configure.ac
@@ -62,8 +62,8 @@ AC_TYPE_SSIZE_T
 AC_TYPE_PID_T
 
 AC_HEADER_STDBOOL
-AC_CHECK_FUNCS([getpagesize stpcpy stpncpy])
-AC_CHECK_DECLS([stpcpy, stpncpy])
+AC_CHECK_FUNCS([getpagesize stpcpy])
+AC_CHECK_DECLS([stpcpy])
 AC_CHECK_FUNC([process_vm_readv],
   [AC_CHECK_FUNC([process_vm_writev],
     [AC_CHECK_DECL([process_vm_readv],
diff --git a/exec/exec.c b/exec/exec.c
index 0d9187cabfa..dae05755675 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -66,74 +66,6 @@ rpl_stpcpy (char *dest, const char *src)
 #define stpcpy rpl_stpcpy
 #endif /* !defined HAVE_STPCPY || !defined HAVE_DECL_STPCPY */
 
-#if !defined HAVE_STPNCPY || !defined HAVE_DECL_STPNCPY
-
-/* Copy no more than N bytes of SRC to DST, returning a pointer past
-   the last non-NUL byte written into DST.  */
-
-static char *
-rpl_stpncpy (char *dest, const char *src, size_t n)
-{
-  char c, *s;
-  size_t n4;
-
-  s = dest;
-
-  if (n >= 4)
-    {
-      n4 = n >> 2;
-
-      for (;;)
-       {
-         c = *src++;
-         *dest++ = c;
-         if (c == '\0')
-           break;
-         c = *src++;
-         *dest++ = c;
-         if (c == '\0')
-           break;
-         c = *src++;
-         *dest++ = c;
-         if (c == '\0')
-           break;
-         c = *src++;
-         *dest++ = c;
-         if (c == '\0')
-           break;
-         if (--n4 == 0)
-           goto last_chars;
-       }
-      n -= dest - s;
-      goto zero_fill;
-    }
-
- last_chars:
-  n &= 3;
-  if (n == 0)
-    return dest;
-
-  for (;;)
-    {
-      c = *src++;
-      --n;
-      *dest++ = c;
-      if (c == '\0')
-       break;
-      if (n == 0)
-       return dest;
-    }
-
- zero_fill:
-  while (n-- > 0)
-    dest[n] = '\0';
-
-  return dest - 1;
-}
-
-#define stpncpy rpl_stpncpy
-#endif /* !defined HAVE_STPNCPY || !defined HAVE_DECL_STPNCPY */
-
 
 
 /* Executable reading functions.
@@ -1005,13 +937,14 @@ exec_0 (char *name, struct exec_tracee *tracee,
   else
     {
       /* If name is not absolute, then make it relative to TRACEE's
-        cwd.  Use stpcpy, as sprintf is not reentrant.  */
+        cwd.  Do not use sprintf at it is not reentrant and it
+        mishandles results longer than INT_MAX.  */
 
       if (name[0] && name[0] != '/')
        {
-         /* Clear `buffer'.  */
+         /* Clear both buffers.  */
          memset (buffer, 0, sizeof buffer);
-         memset (buffer1, 0, sizeof buffer);
+         memset (buffer1, 0, sizeof buffer1);
 
          /* Copy over /proc, the PID, and /cwd/.  */
          rewrite = stpcpy (buffer, "/proc/");
@@ -1036,13 +969,13 @@ exec_0 (char *name, struct exec_tracee *tracee,
            }
 
          /* Add a directory separator if necessary.  */
-      
+
          if (!link_size || buffer1[link_size - 1] != '/')
            buffer1[link_size] = '/', link_size++;
 
          rewrite = buffer1 + link_size;
          remaining = buffer1 + sizeof buffer1 - rewrite - 1;
-         rewrite = stpncpy (rewrite, name, remaining);
+         memcpy (rewrite, name, strnlen (name, remaining));
 
          /* Replace name with buffer1.  */
 #ifndef REENTRANT
diff --git a/exec/mipsel-user.h b/exec/mipsel-user.h
index dc3f98eb4e7..9c5a445c9aa 100644
--- a/exec/mipsel-user.h
+++ b/exec/mipsel-user.h
@@ -40,4 +40,3 @@ struct mipsel_regs
 };
 
 #endif /* _MIPSEL_USER_H_ */
-
diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in
index 895e7f88c57..2cbcdbc3e5b 100644
--- a/java/AndroidManifest.xml.in
+++ b/java/AndroidManifest.xml.in
@@ -66,12 +66,17 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>. -->
 
   <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
 
+  <!-- And under Android 13 or later to post desktop
+       notifications.  -->
+
+  <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
+
   <uses-sdk android:minSdkVersion="@ANDROID_MIN_SDK@"
            android:targetSdkVersion="33"/>
 
   <application android:name="org.gnu.emacs.EmacsApplication"
               android:label="Emacs"
-              android:icon="@drawable/emacs"
+              android:icon="@mipmap/emacs_icon"
               android:hardwareAccelerated="true"
               android:supportsRtl="true"
               android:theme="@style/EmacsStyle"
diff --git a/java/INSTALL b/java/INSTALL
index 0646db426e0..fb235af1346 100644
--- a/java/INSTALL
+++ b/java/INSTALL
@@ -5,8 +5,9 @@ See the end of the file for license conditions.
 Please read the entirety of this file before attempting to build Emacs
 as an application package which can run on Android devices.
 
-When building from the source repository, make sure to read
-INSTALL.REPO as well.
+When building from the source repository (as opposed to from a release
+tarball), make sure to read INSTALL.REPO in the top-level directory as
+well.
 
 
 
@@ -38,8 +39,7 @@ script like so:
 Replacing the paths in the command line above with:
 
   - the path to the `android.jar' headers which come with the Android
-    SDK.  They must correspond to Android version 13 (API level 33) or
-    later.
+    SDK.  They must correspond to Android version 13 (API level 33).
 
   - the path to the C compiler in the Android NDK, for the kind of CPU
     you are building Emacs to run on.
@@ -68,6 +68,57 @@ The generated package can be uploaded onto an SD card (or 
similar
 medium) and installed on-device.
 
 
+LOCATING NECESSARY FILES
+
+As illustrated above, building Emacs for Android requires the presence
+three separate components of the Android SDK and NDK.  Subsequent to
+their installation, the contents of the Android development tools are
+organized into several directories, of which those pertinent to the
+Emacs compilation process are:
+
+  platforms
+  ndk
+  build-tools
+
+The platforms directory contains one subdirectory for each API level
+whose headers have been installed.  Each of these directories in turn
+includes the android.jar archive for that version of Android, also
+necessary for compiling Emacs.
+
+It is imperative that Emacs is compiled using the headers for the
+exact API level that it is written for.  This is currently API level
+33, so the correct android.jar archive is located within a directory
+whose name begins with `android-33'.  Minor revisions to the headers
+are inconsequential towards the Emacs compilation process; if there is
+a directory named `android-33-extN' (where N represents a revision to
+the Android SDK), whether you provide `configure' with that
+directory's android.jar or the android.jar contained within the
+directory named `android-33' is of no special importance.
+
+The ndk directory contains one subdirectory for each version of the
+Android NDK installed.  This directory in turn contains the C and C++
+compilation system.  In contrast to the Java headers mentioned within
+the previous paragraph, the version of the NDK used does not affect
+Emacs to the extent the version of android.jar does.  Having said
+that, each version of the NDK only supports a limited range of API
+levels; your choice of C compiler binary (or __ANDROID_API__) bears
+upon the earliest version of Android the compiled package will
+support.
+
+In most cases, each subdirectory contains a folder named `toolchains',
+holding an `llvm' directory and one directory for each GCC toolchain
+supplied by the NDK.  The C compiler is then positioned within
+`prebuilt/*/bin' inside that directory.
+
+The build-tools directory holds subdirectories containing the utility
+programs used to convert class files output by the Java compiler to
+the DEX format employed by Android.  There is one subdirectory for
+each version of the build tools, but the version you opt for is not of
+paramount significance: if your version does not work, configure will
+protest, so install a newer one.  We anticipate that most recent
+releases will work, such as those from the 33.0.x and 34.0.x series.
+
+
 BUILDING WITH OLD NDK VERSIONS
 
 Building Emacs with an old version of the Android NDK requires special
diff --git a/java/org/gnu/emacs/EmacsDesktopNotification.java 
b/java/org/gnu/emacs/EmacsDesktopNotification.java
new file mode 100644
index 00000000000..c6ebbc6ae48
--- /dev/null
+++ b/java/org/gnu/emacs/EmacsDesktopNotification.java
@@ -0,0 +1,175 @@
+/* Communication module for Android terminals.  -*- c-file-style: "GNU" -*-
+
+Copyright (C) 2023 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/>.  */
+
+package org.gnu.emacs;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
+
+import android.content.Context;
+import android.content.Intent;
+
+import android.os.Build;
+
+import android.widget.RemoteViews;
+
+
+
+/* Structure designating a single desktop notification.
+
+   New versions of Android also organize notifications into individual
+   ``channels'', which are used to implement groups.  Unlike on other
+   systems, notification importance is set for each group, not for
+   each individual notification.  */
+
+
+
+public final class EmacsDesktopNotification
+{
+  /* The content of this desktop notification.  */
+  public final String content;
+
+  /* The title of this desktop notification.  */
+  public final String title;
+
+  /* The notification group.  */
+  public final String group;
+
+  /* String identifying this notification for future replacement.
+     Typically a string resembling ``XXXX.NNNN.YYYY'', where XXXX is
+     the system boot time, NNNN is the PID of this Emacs instance, and
+     YYYY is the counter value returned by the notifications display
+     function.  */
+  public final String tag;
+
+  /* The identifier of this notification's icon.  */
+  public final int icon;
+
+  /* The importance of this notification's group.  */
+  public final int importance;
+
+  public
+  EmacsDesktopNotification (String title, String content,
+                           String group, String tag, int icon,
+                           int importance)
+  {
+    this.content    = content;
+    this.title     = title;
+    this.group     = group;
+    this.tag        = tag;
+    this.icon       = icon;
+    this.importance = importance;
+  }
+
+
+
+  /* Functions for displaying desktop notifications.  */
+
+  /* Internal helper for `display' executed on the main thread.  */
+
+  @SuppressWarnings ("deprecation") /* Notification.Builder (Context).  */
+  private void
+  display1 (Context context)
+  {
+    NotificationManager manager;
+    NotificationChannel channel;
+    Notification notification;
+    Object tem;
+    RemoteViews contentView;
+    Intent intent;
+    PendingIntent pending;
+
+    tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
+    manager = (NotificationManager) tem;
+
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+      {
+       /* Create the notification channel for this group.  If a group
+          already exists with the same name, its linked attributes
+          (such as its importance) will be overridden.  */
+        channel = new NotificationChannel (group, group, importance);
+       manager.createNotificationChannel (channel);
+
+       /* Create a notification object and display it.  */
+       notification = (new Notification.Builder (context, group)
+                       .setContentTitle (title)
+                       .setContentText (content)
+                       .setSmallIcon (icon)
+                       .build ());
+      }
+    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+      notification = (new Notification.Builder (context)
+                     .setContentTitle (title)
+                     .setContentText (content)
+                     .setSmallIcon (icon)
+                     .build ());
+    else
+      {
+       notification = new Notification ();
+       notification.icon = icon;
+
+       /* This remote widget tree is defined in
+          java/res/layout/sdk8_notifications_view.xml.  */
+       notification.contentView
+         = contentView
+         = new RemoteViews ("org.gnu.emacs",
+                            R.layout.sdk8_notifications_view);
+       contentView.setTextViewText (R.id.sdk8_notifications_title,
+                                    title);
+       contentView.setTextViewText (R.id.sdk8_notifications_content,
+                                    content);
+      }
+
+    /* Provide a content intent which starts Emacs when the
+       notification is clicked.  */
+
+    intent = new Intent (context, EmacsActivity.class);
+    intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
+
+    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S)
+      pending = PendingIntent.getActivity (context, 0, intent,
+                                          PendingIntent.FLAG_IMMUTABLE);
+    else
+      pending = PendingIntent.getActivity (context, 0, intent, 0);
+
+    notification.contentIntent = pending;
+
+    manager.notify (tag, 2, notification);
+  }
+
+  /* Display this desktop notification.
+
+     Create a notification channel named GROUP or update its
+     importance if such a channel is already defined.  */
+
+  public void
+  display ()
+  {
+    EmacsService.SERVICE.runOnUiThread (new Runnable () {
+       @Override
+       public void
+       run ()
+       {
+         display1 (EmacsService.SERVICE);
+       }
+      });
+  }
+};
diff --git a/java/org/gnu/emacs/EmacsDialog.java 
b/java/org/gnu/emacs/EmacsDialog.java
index e4ed2271741..2291207fbcc 100644
--- a/java/org/gnu/emacs/EmacsDialog.java
+++ b/java/org/gnu/emacs/EmacsDialog.java
@@ -394,6 +394,7 @@ public final class EmacsDialog implements 
DialogInterface.OnDismissListener
     final EmacsHolder<Boolean> rc;
 
     rc = new EmacsHolder<Boolean> ();
+    rc.thing = false;
     runnable = new Runnable () {
        @Override
        public void
diff --git a/java/org/gnu/emacs/EmacsSafThread.java 
b/java/org/gnu/emacs/EmacsSafThread.java
index 3ae3c0839ce..1b62662b4fc 100644
--- a/java/org/gnu/emacs/EmacsSafThread.java
+++ b/java/org/gnu/emacs/EmacsSafThread.java
@@ -437,11 +437,14 @@ public final class EmacsSafThread extends HandlerThread
   /* Cache file status for DOCUMENTID within TOPLEVEL.  Value is the
      new cache entry.  CURSOR is the cursor from where to retrieve the
      file status, in the form of the columns COLUMN_FLAGS,
-     COLUMN_SIZE, COLUMN_MIME_TYPE and COLUMN_LAST_MODIFIED.  */
+     COLUMN_SIZE, COLUMN_MIME_TYPE and COLUMN_LAST_MODIFIED.
+
+     If NO_CACHE, don't cache the file status; just return the
+     entry.  */
 
   private StatCacheEntry
   cacheFileStatus (String documentId, CacheToplevel toplevel,
-                  Cursor cursor)
+                  Cursor cursor, boolean no_cache)
   {
     StatCacheEntry entry;
     int flagsIndex, columnIndex, typeIndex;
@@ -482,7 +485,8 @@ public final class EmacsSafThread extends HandlerThread
       entry.mtime = cursor.getLong (mtimeIndex);
 
     /* Finally, add this entry to the cache and return.  */
-    toplevel.statCache.put (documentId, entry);
+    if (!no_cache)
+      toplevel.statCache.put (documentId, entry);
     return entry;
   }
 
@@ -546,7 +550,7 @@ public final class EmacsSafThread extends HandlerThread
               directory listing is being requested, it's very likely
               that a series of calls for file status will follow.  */
 
-           cacheFileStatus (id, toplevel, cursor);
+           cacheFileStatus (id, toplevel, cursor, false);
 
            /* If this constituent is a directory, don't cache any
               information about it.  It cannot be cached without
@@ -1217,7 +1221,7 @@ public final class EmacsSafThread extends HandlerThread
 
   private long[]
   statDocument1 (String uri, String documentId,
-                CancellationSignal signal)
+                CancellationSignal signal, boolean noCache)
   {
     Uri uriObject, tree;
     String[] projection;
@@ -1266,7 +1270,8 @@ public final class EmacsSafThread extends HandlerThread
            if (!cursor.moveToFirst ())
              return null;
 
-           cache = cacheFileStatus (documentId, toplevel, cursor);
+           cache = cacheFileStatus (documentId, toplevel, cursor,
+                                    noCache);
          }
        finally
          {
@@ -1332,18 +1337,22 @@ public final class EmacsSafThread extends HandlerThread
      last modification to this file in milliseconds since 00:00,
      January 1st, 1970.
 
+     If NOCACHE, refrain from placing the file status within the
+     status cache.
+
      OperationCanceledException and other typical exceptions may be
      signaled upon receiving async input or other errors.  */
 
   public long[]
-  statDocument (final String uri, final String documentId)
+  statDocument (final String uri, final String documentId,
+               final boolean noCache)
   {
     return (long[]) runObjectFunction (new SafObjectFunction () {
        @Override
        public Object
        runObject (CancellationSignal signal)
        {
-         return statDocument1 (uri, documentId, signal);
+         return statDocument1 (uri, documentId, signal, noCache);
        }
       });
   }
@@ -1565,8 +1574,9 @@ public final class EmacsSafThread extends HandlerThread
      signal.  */
 
   public ParcelFileDescriptor
-  openDocument1 (String uri, String documentId, boolean write,
-                boolean truncate, CancellationSignal signal)
+  openDocument1 (String uri, String documentId, boolean read,
+                boolean write, boolean truncate,
+                CancellationSignal signal)
     throws Throwable
   {
     Uri treeUri, documentUri;
@@ -1586,10 +1596,19 @@ public final class EmacsSafThread extends HandlerThread
 
     if (write)
       {
-       if (truncate)
-         mode = "rwt";
+       if (read)
+         {
+           if (truncate)
+             mode = "rwt";
+           else
+             mode = "rw";
+         }
        else
-         mode = "rw";
+         /* Set mode to w when WRITE && !READ, disregarding TRUNCATE.
+            In contradiction with the ContentResolver documentation,
+            document providers seem to truncate files whenever w is
+            specified, at least superficially.  (But see below.)  */
+         mode = "w";
       }
     else
       mode = "r";
@@ -1598,13 +1617,13 @@ public final class EmacsSafThread extends HandlerThread
       = resolver.openFileDescriptor (documentUri, mode,
                                     signal);
 
-    /* If a writable file descriptor is requested and TRUNCATE is set,
-       then probe the file descriptor to detect if it is actually
-       readable.  If not, close this file descriptor and reopen it
-       with MODE set to rw; some document providers granting access to
-       Samba shares don't implement rwt, but these document providers
-       invariably truncate the file opened even when the mode is
-       merely rw.
+    /* If a writable on-disk file descriptor is requested and TRUNCATE
+       is set, then probe the file descriptor to detect if it is
+       actually readable.  If not, close this file descriptor and
+       reopen it with MODE set to rw; some document providers granting
+       access to Samba shares don't implement rwt, but these document
+       providers invariably truncate the file opened even when the
+       mode is merely w.
 
        This may be ascribed to a mix-up in Android's documentation
        regardin DocumentsProvider: the `openDocument' function is only
@@ -1612,7 +1631,7 @@ public final class EmacsSafThread extends HandlerThread
        implementation of the `openFile' function (which documents rwt)
        delegates to `openDocument'.  */
 
-    if (write && truncate && fileDescriptor != null
+    if (read && write && truncate && fileDescriptor != null
        && !EmacsNative.ftruncate (fileDescriptor.getFd ()))
       {
        try
@@ -1633,6 +1652,12 @@ public final class EmacsSafThread extends HandlerThread
        if (fileDescriptor != null)
          EmacsNative.ftruncate (fileDescriptor.getFd ());
       }
+    else if (!read && write && truncate && fileDescriptor != null)
+      /* Moreover, document providers that return actual seekable
+        files characteristically neglect to truncate the file
+        returned when the access mode is merely w, so attempt to
+        truncate it by hand.  */
+      EmacsNative.ftruncate (fileDescriptor.getFd ());
 
     /* Every time a document is opened, remove it from the file status
        cache.  */
@@ -1647,15 +1672,13 @@ public final class EmacsSafThread extends HandlerThread
      TRUNCATE and the document already exists, truncate its contents
      before returning.
 
-     On Android 9.0 and earlier, always open the document in
-     ``read-write'' mode; this instructs the document provider to
-     return a seekable file that is stored on disk and returns correct
-     file status.
+     If READ && WRITE, open the file under either the `rw' or `rwt'
+     access mode, which implies that the value must be a seekable
+     on-disk file.  If WRITE && !READ or TRUNC && WRITE, also truncate
+     the file after it is opened.
 
-     Under newer versions of Android, open the document in a
-     non-writable mode if WRITE is false.  This is possible because
-     these versions allow Emacs to explicitly request a seekable
-     on-disk file.
+     If only READ or WRITE is set, value may be a non-seekable FIFO or
+     one end of a socket pair.
 
      Value is NULL upon failure or a parcel file descriptor upon
      success.  Call `ParcelFileDescriptor.close' on this file
@@ -1667,7 +1690,8 @@ public final class EmacsSafThread extends HandlerThread
 
   public ParcelFileDescriptor
   openDocument (final String uri, final String documentId,
-               final boolean write, final boolean truncate)
+               final boolean read, final boolean write,
+               final boolean truncate)
   {
     Object tem;
 
@@ -1677,8 +1701,8 @@ public final class EmacsSafThread extends HandlerThread
        runObject (CancellationSignal signal)
          throws Throwable
        {
-         return openDocument1 (uri, documentId, write, truncate,
-                               signal);
+         return openDocument1 (uri, documentId, read,
+                               write, truncate, signal);
        }
       });
 
diff --git a/java/org/gnu/emacs/EmacsService.java 
b/java/org/gnu/emacs/EmacsService.java
index d91d8f66009..404796cd08c 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -171,7 +171,7 @@ public final class EmacsService extends Service
                     + " may disable it if you want;"
                     + " see (emacs)Android Environment.");
        channel
-         = new NotificationChannel ("emacs", "Emacs persistent notification",
+         = new NotificationChannel ("emacs", "Emacs Background Service",
                                     NotificationManager.IMPORTANCE_DEFAULT);
        manager.createNotificationChannel (channel);
        notification = (new Notification.Builder (this, "emacs")
@@ -960,44 +960,30 @@ public final class EmacsService extends Service
       }
   }
 
+  /* Return whether Emacs is directly permitted to access the
+     content:// URI NAME.  This is not a suitable test for files which
+     Emacs can access by virtue of their containing document
+     trees.  */
+
   public boolean
-  checkContentUri (byte[] string, boolean readable, boolean writable)
+  checkContentUri (String name, boolean readable, boolean writable)
   {
-    String mode, name;
+    String mode;
     ParcelFileDescriptor fd;
+    Uri uri;
+    int rc, flags;
 
-    /* Decode this into a URI.  */
-
-    try
-      {
-       /* The usual file name encoding question rears its ugly head
-          again.  */
-       name = new String (string, "UTF-8");
-      }
-    catch (UnsupportedEncodingException exception)
-      {
-       name = null;
-       throw new RuntimeException (exception);
-      }
+    uri = Uri.parse (name);
+    flags = 0;
 
-    mode = "r";
+    if (readable)
+      flags |= Intent.FLAG_GRANT_READ_URI_PERMISSION;
 
     if (writable)
-      mode += "w";
-
-    try
-      {
-       fd = resolver.openFileDescriptor (Uri.parse (name), mode);
-       fd.close ();
-
-       return true;
-      }
-    catch (Exception exception)
-      {
-       /* Fall through.  */
-      }
+      flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
 
-    return false;
+    rc = checkCallingUriPermission (uri, flags);
+    return rc == PackageManager.PERMISSION_GRANTED;
   }
 
   /* Build a content file name for URI.
@@ -1389,11 +1375,14 @@ public final class EmacsService extends Service
      last modification to this file in milliseconds since 00:00,
      January 1st, 1970.
 
+     If NOCACHE, refrain from placing the file status within the
+     status cache.
+
      OperationCanceledException and other typical exceptions may be
      signaled upon receiving async input or other errors.  */
 
   public long[]
-  statDocument (String uri, String documentId)
+  statDocument (String uri, String documentId, boolean noCache)
   {
     /* Start the thread used to run SAF requests if it isn't already
        running.  */
@@ -1404,7 +1393,7 @@ public final class EmacsService extends Service
        storageThread.start ();
       }
 
-    return storageThread.statDocument (uri, documentId);
+    return storageThread.statDocument (uri, documentId, noCache);
   }
 
   /* Find out whether Emacs has access to the document designated by
@@ -1500,9 +1489,13 @@ public final class EmacsService extends Service
            return entry;
          }
 
-       /* Skip this entry if its name cannot be represented.  */
+       /* Skip this entry if its name cannot be represented.  NAME
+          can still be null here, since some Cursors are permitted to
+          return NULL if INDEX is not a string.  */
 
-       if (name.equals ("..") || name.equals (".") || name.contains ("/"))
+       if (name == null || name.equals ("..")
+           || name.equals (".") || name.contains ("/")
+           || name.contains ("\0"))
          continue;
 
        /* Now, look for its type.  */
@@ -1537,15 +1530,13 @@ public final class EmacsService extends Service
      TRUNCATE and the document already exists, truncate its contents
      before returning.
 
-     On Android 9.0 and earlier, always open the document in
-     ``read-write'' mode; this instructs the document provider to
-     return a seekable file that is stored on disk and returns correct
-     file status.
+     If READ && WRITE, open the file under either the `rw' or `rwt'
+     access mode, which implies that the value must be a seekable
+     on-disk file.  If TRUNC && WRITE, also truncate the file after it
+     is opened.
 
-     Under newer versions of Android, open the document in a
-     non-writable mode if WRITE is false.  This is possible because
-     these versions allow Emacs to explicitly request a seekable
-     on-disk file.
+     If only READ or WRITE is set, value may be a non-seekable FIFO or
+     one end of a socket pair.
 
      Value is NULL upon failure or a parcel file descriptor upon
      success.  Call `ParcelFileDescriptor.close' on this file
@@ -1555,8 +1546,8 @@ public final class EmacsService extends Service
      UnsupportedOperationException may be thrown upon failure.  */
 
   public ParcelFileDescriptor
-  openDocument (String uri, String documentId, boolean write,
-               boolean truncate)
+  openDocument (String uri, String documentId,
+               boolean read, boolean write, boolean truncate)
   {
     /* Start the thread used to run SAF requests if it isn't already
        running.  */
@@ -1567,7 +1558,7 @@ public final class EmacsService extends Service
        storageThread.start ();
       }
 
-    return storageThread.openDocument (uri, documentId, write,
+    return storageThread.openDocument (uri, documentId, read, write,
                                       truncate);
   }
 
diff --git a/java/org/gnu/emacs/EmacsWindow.java 
b/java/org/gnu/emacs/EmacsWindow.java
index a1f70644e16..aff5046b22e 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -1356,7 +1356,7 @@ public final class EmacsWindow extends EmacsHandleObject
          if (on)
            view.showOnScreenKeyboard ();
          else
-           view.hideOnScreenKeyboard ();         
+           view.hideOnScreenKeyboard ();
        }
       });
   }
diff --git a/java/res/drawable/emacs_background.xml 
b/java/res/drawable/emacs_background.xml
new file mode 100644
index 00000000000..c4562d754d5
--- /dev/null
+++ b/java/res/drawable/emacs_background.xml
@@ -0,0 +1,42 @@
+<!-- Adaptive icon for Emacs.
+
+Copyright (C) 2023 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/>. -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+       xmlns:aapt="http://schemas.android.com/aapt";
+       android:width="108dp"
+       android:height="108dp"
+       android:viewportWidth="512"
+       android:viewportHeight="512">
+  <path
+      android:pathData="M-4.99,-5.79h521.12v526.76h-521.12z"
+      android:strokeWidth="10.6667">
+    <aapt:attr name="android:fillColor">
+      <gradient 
+          android:startX="0"
+          android:startY="0"
+          android:endX="512"
+          android:endY="512"
+          android:type="linear">
+        <item android:offset="0" android:color="#FF8381C5"/>
+        <item android:offset="0.34" android:color="#FE806BBC"/>
+        <item android:offset="1" android:color="#FDA52ECB"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+</vector>
diff --git a/java/res/drawable/emacs_foreground.xml 
b/java/res/drawable/emacs_foreground.xml
new file mode 100644
index 00000000000..ff9e854d038
--- /dev/null
+++ b/java/res/drawable/emacs_foreground.xml
@@ -0,0 +1,53 @@
+<!-- Adaptive icon for Emacs.
+
+Copyright (C) 2023 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/>. -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+       xmlns:aapt="http://schemas.android.com/aapt";
+       android:width="108dp"
+       android:height="108dp"
+       android:viewportWidth="512"
+       android:viewportHeight="512">
+  <group android:scaleX="0.6"
+        android:scaleY="0.6"
+        android:translateX="102.4"
+        android:translateY="102.4">
+    <path
+        android:pathData="M0,0h512v512h-512z">
+      <aapt:attr name="android:fillColor">
+        <gradient 
+            android:startX="-0"
+            android:startY="256"
+            android:endX="512"
+            android:endY="256"
+            android:type="linear">
+          <item android:offset="1" android:color="#00000000"/>
+          <item android:offset="1" android:color="#FF5B2A85"/>
+        </gradient>
+      </aapt:attr>
+    </path>
+    <path
+        android:pathData="m174.83,422.11c0,0 19.74,1.4 45.13,-0.84 10.28,-0.91 
49.33,-4.74 78.52,-11.14 0,0 35.59,-7.62 54.63,-14.63 19.92,-7.34 30.76,-13.57 
35.64,-22.4 -0.21,-1.81 1.5,-8.22 -7.68,-12.08 -23.49,-9.85 -50.73,-8.07 
-104.63,-9.21 -59.78,-2.05 -79.66,-12.06 -90.26,-20.12 -10.16,-8.18 
-5.05,-30.79 38.47,-50.71 21.92,-10.61 107.87,-30.19 107.87,-30.19 
-28.95,-14.31 -82.92,-39.46 -94.01,-44.89 -9.73,-4.76 -25.3,-11.94 
-28.68,-20.61 -3.83,-8.33 9.04,-15.51 16.22,-17.56 23.14,-6 [...]
+        android:strokeLineJoin="miter"
+        android:strokeWidth="0"
+        android:fillColor="#ffffff"
+        android:strokeColor="#000000"
+        android:fillType="evenOdd"
+        android:strokeLineCap="butt"/>
+  </group>
+</vector>
diff --git a/java/res/layout/sdk8_notifications_view.xml 
b/java/res/layout/sdk8_notifications_view.xml
new file mode 100644
index 00000000000..0572f350cff
--- /dev/null
+++ b/java/res/layout/sdk8_notifications_view.xml
@@ -0,0 +1,33 @@
+<!-- Notification content widget tree for GNU Emacs on Android 2.3.
+
+Copyright (C) 2023 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/>. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android";
+             android:orientation="vertical"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:padding="8dp">
+  <TextView android:id="@+id/sdk8_notifications_title"
+           android:textColor="#000000"
+           android:layout_width="wrap_content"
+           android:layout_height="wrap_content"/>
+  <TextView android:id="@+id/sdk8_notifications_content"
+           android:textColor="#000000"
+           android:layout_width="wrap_content"
+           android:layout_height="wrap_content"/>
+</LinearLayout>
diff --git a/exec/mipsel-user.h b/java/res/mipmap-v26/emacs_icon.xml
similarity index 58%
copy from exec/mipsel-user.h
copy to java/res/mipmap-v26/emacs_icon.xml
index dc3f98eb4e7..9f070e3f3d2 100644
--- a/exec/mipsel-user.h
+++ b/java/res/mipmap-v26/emacs_icon.xml
@@ -1,4 +1,4 @@
-/* Program execution for Emacs.
+<!-- Adaptive icon for Emacs.
 
 Copyright (C) 2023 Free Software Foundation, Inc.
 
@@ -6,8 +6,8 @@ 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.
+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
@@ -15,29 +15,9 @@ 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/>.  */
-
-
-
-#ifndef _MIPSEL_USER_H_
-#define _MIPSEL_USER_H_
-
-#include <sys/user.h>
-
-#ifndef ELF_NGREG
-#define ELF_NGREG       45
-#endif /* ELF_NGREG */
-
-
-
-/* This file defines a structure containing user mode general purpose
-   registers on 32-bit mipsel systems.  */
-
-struct mipsel_regs
-{
-  /* General purpose registers.  */
-  uint64_t gregs[ELF_NGREG];
-};
-
-#endif /* _MIPSEL_USER_H_ */
+along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
 
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android";>
+  <background android:drawable="@drawable/emacs_background"/>
+  <foreground android:drawable="@drawable/emacs_foreground"/>
+</adaptive-icon>
diff --git a/java/res/mipmap/emacs_icon.png b/java/res/mipmap/emacs_icon.png
new file mode 100644
index 00000000000..9ab43d704be
Binary files /dev/null and b/java/res/mipmap/emacs_icon.png differ
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 8a11cb007ee..0bf1ef0ac9b 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -17,7 +17,7 @@ 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/>. -->
 
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<resources>
   <string name="start_quick_title">
     Restart Emacs with -Q
   </string>
diff --git a/lib-src/ChangeLog.1 b/lib-src/ChangeLog.1
index 84f566262c4..136e8917d50 100644
--- a/lib-src/ChangeLog.1
+++ b/lib-src/ChangeLog.1
@@ -8281,7 +8281,7 @@
        * etags.c (C_entries): Save the definedef status even when a
        newline is met inside a string.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * Makefile.in (EXECUTABLES): Add rcs-checkin.
 
@@ -8482,7 +8482,7 @@
 
 1992-08-07  Jim Blandy  (jimb@pogo.cs.oberlin.edu)
 
-       * timer.c: Installed new version from Eric Raymond; this is more
+       * timer.c: Installed new version from Eric S. Raymond; this is more
        portable, since it doesn't try to use SIGIO.
 
 1992-07-17  Jim Blandy  (jimb@wookumz.gnu.ai.mit.edu)
diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h
new file mode 100644
index 00000000000..e59a0fd03c7
--- /dev/null
+++ b/lib/boot-time-aux.h
@@ -0,0 +1,317 @@
+/* Auxiliary functions for determining the time when the machine last booted.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file 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 file 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/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>.  */
+
+#define SIZEOF(a) (sizeof(a)/sizeof(a[0]))
+
+#if defined __linux__ || defined __ANDROID__
+
+/* Store the uptime counter, as managed by the Linux kernel, in *P_UPTIME.
+   Return 0 upon success, -1 upon failure.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED
+static int
+get_linux_uptime (struct timespec *p_uptime)
+{
+  /* The clock_gettime facility returns the uptime with a resolution of 1 µsec.
+     It is available with glibc >= 2.14, Android, or musl libc.
+     In glibc < 2.17 it required linking with librt.  */
+# if !defined __GLIBC__ || 2 < __GLIBC__ + (17 <= __GLIBC_MINOR__)
+  if (clock_gettime (CLOCK_BOOTTIME, p_uptime) >= 0)
+    return 0;
+# endif
+
+  /* /proc/uptime contains the uptime with a resolution of 0.01 sec.
+     But it does not have read permissions on Android.  */
+# if !defined __ANDROID__
+  FILE *fp = fopen ("/proc/uptime", "re");
+  if (fp != NULL)
+    {
+      char buf[32 + 1];
+      size_t n = fread (buf, 1, sizeof (buf) - 1, fp);
+      fclose (fp);
+      if (n > 0)
+        {
+          buf[n] = '\0';
+          /* buf now contains two values: the uptime and the idle time.  */
+          time_t s = 0;
+          char *p;
+          for (p = buf; '0' <= *p && *p <= '9'; p++)
+            s = 10 * s + (*p - '0');
+          if (buf < p)
+            {
+              long ns = 0;
+              if (*p++ == '.')
+                for (int i = 0; i < 9; i++)
+                  ns = 10 * ns + ('0' <= *p && *p <= '9' ? *p++ - '0' : 0);
+              p_uptime->tv_sec = s;
+              p_uptime->tv_nsec = ns;
+              return 0;
+            }
+        }
+    }
+# endif
+
+# if HAVE_DECL_SYSINFO /* not available in Android API < 9 */
+  /* The sysinfo call returns the uptime with a resolution of 1 sec only.  */
+  struct sysinfo info;
+  if (sysinfo (&info) >= 0)
+    {
+      p_uptime->tv_sec = info.uptime;
+      p_uptime->tv_nsec = 0;
+      return 0;
+    }
+# endif
+
+  return -1;
+}
+
+#endif
+
+#if defined __linux__ && !defined __ANDROID__
+
+static int
+get_linux_boot_time_fallback (struct timespec *p_boot_time)
+{
+  /* On Alpine Linux, UTMP_FILE is not filled.  It is always empty.
+     So, get the time stamp of a file that gets touched only during the
+     boot process.  */
+
+  const char * const boot_touched_files[] =
+    {
+      "/var/lib/systemd/random-seed", /* seen on distros with systemd */
+      "/var/run/utmp",                /* seen on distros with OpenRC */
+      "/var/lib/random-seed"          /* seen on older distros */
+    };
+  for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++)
+    {
+      const char *filename = boot_touched_files[i];
+      struct stat statbuf;
+      if (stat (filename, &statbuf) >= 0)
+        {
+          *p_boot_time = get_stat_mtime (&statbuf);
+          return 0;
+        }
+    }
+  return -1;
+}
+
+/* The following approach is only usable as a fallback, because it is of
+   the form
+     boot_time = (time now) - (kernel's ktime_get_boottime[_ts64] ())
+   and therefore produces wrong values after the date has been bumped in the
+   running system, which happens frequently if the system is running in a
+   virtual machine and this VM has been put into "saved" or "sleep" state
+   and then resumed.  */
+static int
+get_linux_boot_time_final_fallback (struct timespec *p_boot_time)
+{
+  struct timespec uptime;
+  if (get_linux_uptime (&uptime) >= 0)
+    {
+      struct timespec result;
+# if !defined __GLIBC__ || 2 < __GLIBC__ + (16 <= __GLIBC_MINOR__)
+      /* Better than:
+      if (0 <= clock_gettime (CLOCK_REALTIME, &result))
+         because timespec_get does not need -lrt in glibc 2.16.
+      */
+      if (! timespec_get (&result, TIME_UTC))
+        return -1;
+#  else
+      /* Fall back on lower-res approach that does not need -lrt.
+         This is good enough; on these hosts UPTIME is even lower-res.  */
+      struct timeval tv;
+      int r = gettimeofday (&tv, NULL);
+      if (r < 0)
+        return r;
+      result.tv_sec = tv.tv_sec;
+      result.tv_nsec = tv.tv_usec * 1000;
+#  endif
+
+      if (result.tv_nsec < uptime.tv_nsec)
+        {
+          result.tv_nsec += 1000000000;
+          result.tv_sec -= 1;
+        }
+      result.tv_sec -= uptime.tv_sec;
+      result.tv_nsec -= uptime.tv_nsec;
+      *p_boot_time = result;
+      return 0;
+    }
+  return -1;
+}
+
+#endif
+
+#if defined __ANDROID__
+
+static int
+get_android_boot_time (struct timespec *p_boot_time)
+{
+  /* On Android, there is no /var, and normal processes don't have access
+     to system files.  Therefore use the kernel's uptime counter, although
+     it produces wrong values after the date has been bumped in the running
+     system.  */
+  struct timespec uptime;
+  if (get_linux_uptime (&uptime) >= 0)
+    {
+      struct timespec result;
+      if (clock_gettime (CLOCK_REALTIME, &result) >= 0)
+        {
+          if (result.tv_nsec < uptime.tv_nsec)
+            {
+              result.tv_nsec += 1000000000;
+              result.tv_sec -= 1;
+            }
+          result.tv_sec -= uptime.tv_sec;
+          result.tv_nsec -= uptime.tv_nsec;
+          *p_boot_time = result;
+          return 0;
+        }
+    }
+  return -1;
+}
+
+#endif
+
+#if defined __OpenBSD__
+
+static int
+get_openbsd_boot_time (struct timespec *p_boot_time)
+{
+  /* On OpenBSD, UTMP_FILE is not filled.  It contains only dummy entries.
+     So, get the time stamp of a file that gets touched only during the
+     boot process.  */
+  const char * const boot_touched_files[] =
+    {
+      "/var/db/host.random",
+      "/var/run/utmp"
+    };
+  for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++)
+    {
+      const char *filename = boot_touched_files[i];
+      struct stat statbuf;
+      if (stat (filename, &statbuf) >= 0)
+        {
+          *p_boot_time = get_stat_mtime (&statbuf);
+          return 0;
+        }
+    }
+  return -1;
+}
+
+#endif
+
+#if HAVE_SYS_SYSCTL_H && HAVE_SYSCTL \
+    && defined CTL_KERN && defined KERN_BOOTTIME \
+    && !defined __minix
+/* macOS, FreeBSD, GNU/kFreeBSD, NetBSD, OpenBSD */
+/* On Minix 3.3 this sysctl produces garbage results.  Therefore avoid it.  */
+
+/* The following approach is only usable as a fallback, because it produces
+   wrong values after the date has been bumped in the running system, which
+   happens frequently if the system is running in a virtual machine and this
+   VM has been put into "saved" or "sleep" state and then resumed.  */
+static int
+get_bsd_boot_time_final_fallback (struct timespec *p_boot_time)
+{
+  static int request[2] = { CTL_KERN, KERN_BOOTTIME };
+  struct timeval result;
+  size_t result_len = sizeof result;
+
+  if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0)
+    {
+      p_boot_time->tv_sec = result.tv_sec;
+      p_boot_time->tv_nsec = result.tv_usec * 1000;
+      return 0;
+    }
+  return -1;
+}
+
+#endif
+
+#if defined __HAIKU__
+
+static int
+get_haiku_boot_time (struct timespec *p_boot_time)
+{
+  /* On Haiku, /etc/utmp does not exist.  During boot,
+       1. the current time is restored, but possibly with a wrong time zone,
+          that is, with an offset of a few hours,
+       2. some symlinks and files get created,
+       3. the various devices are brought up, in particular the network device,
+       4. the correct date and time is set,
+       5. some more device nodes get created.
+     The boot time can be retrieved by looking at a directory created during
+     phase 5, such as /dev/input.  */
+  const char * const boot_touched_file = "/dev/input";
+  struct stat statbuf;
+  if (stat (boot_touched_file, &statbuf) >= 0)
+    {
+      *p_boot_time = get_stat_mtime (&statbuf);
+      return 0;
+    }
+  return -1;
+}
+
+#endif
+
+#if HAVE_OS_H /* BeOS, Haiku */
+
+/* The following approach is only usable as a fallback, because it produces
+   wrong values after the date has been bumped in the running system, which
+   happens frequently if the system is running in a virtual machine and this
+   VM has been put into "saved" or "sleep" state and then resumed.  */
+static int
+get_haiku_boot_time_final_fallback (struct timespec *p_boot_time)
+{
+  system_info si;
+
+  get_system_info (&si);
+  p_boot_time->tv_sec = si.boot_time / 1000000;
+  p_boot_time->tv_nsec = (si.boot_time % 1000000) * 1000;
+  return 0;
+}
+
+#endif
+
+#if defined __CYGWIN__ || defined _WIN32
+
+static int
+get_windows_boot_time (struct timespec *p_boot_time)
+{
+  /* On Cygwin, /var/run/utmp is empty.
+     On native Windows, <utmpx.h> and <utmp.h> don't exist.
+     Instead, on Windows, the boot time can be retrieved by looking at the
+     time stamp of a file that (normally) gets touched only during the boot
+     process, namely C:\pagefile.sys.  */
+  const char * const boot_touched_file =
+    #if defined __CYGWIN__ && !defined _WIN32
+    "/cygdrive/c/pagefile.sys"
+    #else
+    "C:\\pagefile.sys"
+    #endif
+    ;
+  struct stat statbuf;
+  if (stat (boot_touched_file, &statbuf) >= 0)
+    {
+      *p_boot_time = get_stat_mtime (&statbuf);
+      return 0;
+    }
+  return -1;
+}
+
+#endif
diff --git a/lib/boot-time.c b/lib/boot-time.c
new file mode 100644
index 00000000000..fe5b5b88c8e
--- /dev/null
+++ b/lib/boot-time.c
@@ -0,0 +1,287 @@
+/* Determine the time when the machine last booted.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file 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 file 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/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "boot-time.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined __linux__ || defined __ANDROID__
+# include <sys/sysinfo.h>
+# include <time.h>
+#endif
+
+#if HAVE_SYS_SYSCTL_H && !(defined __GLIBC__ && defined __linux__) && !defined 
__minix
+# if HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+# endif
+# include <sys/sysctl.h>
+#endif
+
+#if HAVE_OS_H
+# include <OS.h>
+#endif
+
+#include "idx.h"
+#include "readutmp.h"
+#include "stat-time.h"
+
+/* Each of the FILE streams in this file is only used in a single thread.  */
+#include "unlocked-io.h"
+
+/* Some helper functions.  */
+#include "boot-time-aux.h"
+
+/* The following macros describe the 'struct UTMP_STRUCT_NAME',
+   *not* 'struct gl_utmp'.  */
+#undef UT_USER
+
+/* Accessor macro for the member named ut_user or ut_name.  */
+#if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_NAME \
+     : HAVE_UTMP_H && HAVE_STRUCT_UTMP_UT_NAME)
+# define UT_USER(UT) ((UT)->ut_name)
+#else
+# define UT_USER(UT) ((UT)->ut_user)
+#endif
+
+#if !HAVE_UTMPX_H && HAVE_UTMP_H && defined UTMP_NAME_FUNCTION
+# if !HAVE_DECL_ENDUTENT /* Android */
+void endutent (void);
+# endif
+#endif
+
+#if defined __linux__ || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ || 
defined _WIN32
+
+static int
+get_boot_time_uncached (struct timespec *p_boot_time)
+{
+  struct timespec found_boot_time = {0};
+
+# if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE)
+
+  /* Try to find the boot time in the /var/run/utmp file.  */
+
+#  if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, 
Minix, AIX, IRIX, Solaris, Cygwin, Android */
+
+  /* Ignore the return value for now.
+     Solaris' utmpname returns 1 upon success -- which is contrary
+     to what the GNU libc version does.  In addition, older GNU libc
+     versions are actually void.   */
+  UTMP_NAME_FUNCTION ((char *) UTMP_FILE);
+
+  SET_UTMP_ENT ();
+
+#   if (defined __linux__ && !defined __ANDROID__) || defined __minix
+  /* Timestamp of the "runlevel" entry, if any.  */
+  struct timespec runlevel_ts = {0};
+#   endif
+
+  void const *entry;
+
+  while ((entry = GET_UTMP_ENT ()) != NULL)
+    {
+      struct UTMP_STRUCT_NAME const *ut = (struct UTMP_STRUCT_NAME const *) 
entry;
+
+      struct timespec ts =
+        #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV)
+        { .tv_sec = ut->ut_tv.tv_sec, .tv_nsec = ut->ut_tv.tv_usec * 1000 };
+        #else
+        { .tv_sec = ut->ut_time, .tv_nsec = 0 };
+        #endif
+
+      if (ut->ut_type == BOOT_TIME)
+        found_boot_time = ts;
+
+#   if defined __linux__ && !defined __ANDROID__
+      if (memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0
+          && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0)
+        runlevel_ts = ts;
+#   endif
+#   if defined __minix
+      if (UT_USER (ut)[0] == '\0'
+          && memcmp (ut->ut_line, "run-level ", strlen ("run-level ")) == 0)
+        runlevel_ts = ts;
+#   endif
+    }
+
+  END_UTMP_ENT ();
+
+#   if defined __linux__ && !defined __ANDROID__
+  /* On Raspbian, which runs on hardware without a real-time clock, during 
boot,
+       1. the clock gets set to 1970-01-01 00:00:00,
+       2. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME,
+          ut_user = "reboot", ut_line = "~", time = 1970-01-01 00:00:05 or so,
+       3. the clock gets set to a correct value through NTP,
+       4. an entry gets written into /var/run/utmp, with
+          ut_user = "runlevel", ut_line = "~", time = correct value.
+     In this case, get the time from the "runlevel" entry.  */
+
+  /* Workaround for Raspbian:  */
+  if (found_boot_time.tv_sec <= 60 && runlevel_ts.tv_sec != 0)
+    found_boot_time = runlevel_ts;
+  if (found_boot_time.tv_sec == 0)
+    {
+      /* Workaround for Alpine Linux:  */
+      get_linux_boot_time_fallback (&found_boot_time);
+    }
+#   endif
+
+#   if defined __ANDROID__
+  if (found_boot_time.tv_sec == 0)
+    {
+      /* Workaround for Android:  */
+      get_android_boot_time (&found_boot_time);
+    }
+#   endif
+
+#   if defined __minix
+  /* On Minix, during boot,
+       1. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME,
+          ut_user = "", ut_line = "system boot", time = 1970-01-01 00:00:00,
+       2. an entry gets written into /var/run/utmp, with
+          ut_user = "", ut_line = "run-level m", time = correct value.
+     In this case, copy the time from the "run-level m" entry to the
+     "system boot" entry.  */
+  if (found_boot_time.tv_sec <= 60 && runlevel_ts.tv_sec != 0)
+    found_boot_time = runlevel_ts;
+#   endif
+
+#  else /* HP-UX, Haiku */
+
+  FILE *f = fopen (UTMP_FILE, "re");
+
+  if (f != NULL)
+    {
+      for (;;)
+        {
+          struct UTMP_STRUCT_NAME ut;
+
+          if (fread (&ut, sizeof ut, 1, f) == 0)
+            break;
+
+          struct timespec ts =
+            #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV)
+            { .tv_sec = ut.ut_tv.tv_sec, .tv_nsec = ut.ut_tv.tv_usec * 1000 };
+            #else
+            { .tv_sec = ut.ut_time, .tv_nsec = 0 };
+            #endif
+
+          if (ut.ut_type == BOOT_TIME)
+            found_boot_time = ts;
+        }
+
+      fclose (f);
+    }
+
+#  endif
+
+#  if defined __linux__ && !defined __ANDROID__
+  if (found_boot_time.tv_sec == 0)
+    {
+      get_linux_boot_time_final_fallback (&found_boot_time);
+    }
+#  endif
+
+# else /* old FreeBSD, OpenBSD, native Windows */
+
+#  if defined __OpenBSD__
+  /* Workaround for OpenBSD:  */
+  get_openbsd_boot_time (&found_boot_time);
+#  endif
+
+# endif
+
+# if HAVE_SYS_SYSCTL_H && HAVE_SYSCTL \
+     && defined CTL_KERN && defined KERN_BOOTTIME \
+     && !defined __minix
+  if (found_boot_time.tv_sec == 0)
+    {
+      get_bsd_boot_time_final_fallback (&found_boot_time);
+    }
+# endif
+
+# if defined __HAIKU__
+  if (found_boot_time.tv_sec == 0)
+    {
+      get_haiku_boot_time (&found_boot_time);
+    }
+# endif
+
+# if HAVE_OS_H
+  if (found_boot_time.tv_sec == 0)
+    {
+      get_haiku_boot_time_final_fallback (&found_boot_time);
+    }
+# endif
+
+# if defined __CYGWIN__ || defined _WIN32
+  if (found_boot_time.tv_sec == 0)
+    {
+      /* Workaround for Windows:  */
+      get_windows_boot_time (&found_boot_time);
+    }
+# endif
+
+  if (found_boot_time.tv_sec != 0)
+    {
+      *p_boot_time = found_boot_time;
+      return 0;
+    }
+  else
+    return -1;
+}
+
+int
+get_boot_time (struct timespec *p_boot_time)
+{
+  /* Cache the result from get_boot_time_uncached.  */
+  static int volatile cached_result = -1;
+  static struct timespec volatile cached_boot_time;
+
+  if (cached_result < 0)
+    {
+      struct timespec boot_time;
+      int result = get_boot_time_uncached (&boot_time);
+      cached_boot_time = boot_time;
+      cached_result = result;
+    }
+
+  if (cached_result == 0)
+    {
+      *p_boot_time = cached_boot_time;
+      return 0;
+    }
+  else
+    return -1;
+}
+
+#else
+
+int
+get_boot_time (struct timespec *p_boot_time)
+{
+  return -1;
+}
+
+#endif
diff --git a/lib/boot-time.h b/lib/boot-time.h
new file mode 100644
index 00000000000..401e854adbb
--- /dev/null
+++ b/lib/boot-time.h
@@ -0,0 +1,44 @@
+/* Determine the time when the machine last booted.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file 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 file 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/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>.  */
+
+#ifndef _BOOT_TIME_H
+#define _BOOT_TIME_H
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Store the approximate time when the machine last booted in *P_BOOT_TIME,
+   and return 0.  If it cannot be determined, return -1.
+
+   This function is not multithread-safe, since on many platforms it
+   invokes the functions setutxent, getutxent, endutxent.  These
+   functions are needed because they may lock FILE (so that we don't
+   read garbage when a concurrent process writes to FILE), but their
+   drawback is that they have a common global state.  */
+extern int get_boot_time (struct timespec *p_boot_time);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOOT_TIME_H */
diff --git a/lib/diffseq.h b/lib/diffseq.h
index 06e1465bf1b..3f85ab2ec41 100644
--- a/lib/diffseq.h
+++ b/lib/diffseq.h
@@ -92,20 +92,11 @@
 # define NOTE_ORDERED false
 #endif
 
-/* Use this to suppress gcc's "...may be used before initialized" warnings.
-   Beware: The Code argument must not contain commas.  */
+/* Suppress gcc's "...may be used before initialized" warnings,
+   generated by GCC versions up to at least GCC 13.2.  */
 #if __GNUC__ + (__GNUC_MINOR__ >= 7) > 4
 # pragma GCC diagnostic push
-#endif
-#ifndef IF_LINT
-# if defined GCC_LINT || defined lint
-#  define IF_LINT(Code) Code
-# else
-#  define IF_LINT(Code) /* empty */
-#  if __GNUC__ + (__GNUC_MINOR__ >= 7) > 4
-#   pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#  endif
-# endif
+# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
 #endif
 
 /*
@@ -388,13 +379,8 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, 
bool find_minimal,
          and report halfway between our best results so far.  */
       if (c >= ctxt->too_expensive)
         {
-          OFFSET fxybest;
-          OFFSET fxbest IF_LINT (= 0);
-          OFFSET bxybest;
-          OFFSET bxbest IF_LINT (= 0);
-
           /* Find forward diagonal that maximizes X + Y.  */
-          fxybest = -1;
+          OFFSET fxybest = -1, fxbest;
           for (d = fmax; d >= fmin; d -= 2)
             {
               OFFSET x = MIN (fd[d], xlim);
@@ -412,7 +398,7 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, 
bool find_minimal,
             }
 
           /* Find backward diagonal that minimizes X + Y.  */
-          bxybest = OFFSET_MAX;
+          OFFSET bxybest = OFFSET_MAX, bxbest;
           for (d = bmax; d >= bmin; d -= 2)
             {
               OFFSET x = MAX (xoff, bd[d]);
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 1bfa1daa0b3..3b33f39f73b 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -41,6 +41,10 @@
 #  --avoid=dup \
 #  --avoid=fchdir \
 #  --avoid=fstat \
+#  --avoid=iswblank \
+#  --avoid=iswctype \
+#  --avoid=iswdigit \
+#  --avoid=iswxdigit \
 #  --avoid=langinfo \
 #  --avoid=lock \
 #  --avoid=mbrtowc \
@@ -67,10 +71,12 @@
 #  --avoid=utime-h \
 #  --avoid=wchar \
 #  --avoid=wcrtomb \
+#  --avoid=wctype \
 #  --avoid=wctype-h \
 #  alignasof \
 #  alloca-opt \
 #  binary-io \
+#  boot-time \
 #  byteswap \
 #  c-ctype \
 #  c-strcase \
@@ -152,7 +158,6 @@
 #  stddef \
 #  stdio \
 #  stpcpy \
-#  stpncpy \
 #  strnlen \
 #  strtoimax \
 #  symlink \
@@ -331,7 +336,6 @@ GL_COND_OBJ_SIGDESCR_NP_CONDITION = 
@GL_COND_OBJ_SIGDESCR_NP_CONDITION@
 GL_COND_OBJ_STDIO_READ_CONDITION = @GL_COND_OBJ_STDIO_READ_CONDITION@
 GL_COND_OBJ_STDIO_WRITE_CONDITION = @GL_COND_OBJ_STDIO_WRITE_CONDITION@
 GL_COND_OBJ_STPCPY_CONDITION = @GL_COND_OBJ_STPCPY_CONDITION@
-GL_COND_OBJ_STPNCPY_CONDITION = @GL_COND_OBJ_STPNCPY_CONDITION@
 GL_COND_OBJ_STRNLEN_CONDITION = @GL_COND_OBJ_STRNLEN_CONDITION@
 GL_COND_OBJ_STRTOIMAX_CONDITION = @GL_COND_OBJ_STRTOIMAX_CONDITION@
 GL_COND_OBJ_STRTOLL_CONDITION = @GL_COND_OBJ_STRTOLL_CONDITION@
@@ -658,7 +662,6 @@ GL_GNULIB__EXIT = @GL_GNULIB__EXIT@
 GMALLOC_OBJ = @GMALLOC_OBJ@
 GMP_H = @GMP_H@
 GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@
-GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
 GNULIB_WARN_CFLAGS = @GNULIB_WARN_CFLAGS@
 GNUSTEP_CFLAGS = @GNUSTEP_CFLAGS@
 GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@
@@ -1599,6 +1602,16 @@ libgnu_a_SOURCES += binary-io.h binary-io.c
 endif
 ## end   gnulib module binary-io
 
+## begin gnulib module boot-time
+ifeq (,$(OMIT_GNULIB_MODULE_boot-time))
+
+libgnu_a_SOURCES += boot-time.c
+
+EXTRA_DIST += boot-time-aux.h boot-time.h readutmp.h
+
+endif
+## end   gnulib module boot-time
+
 ## begin gnulib module byteswap
 ifeq (,$(OMIT_GNULIB_MODULE_byteswap))
 
@@ -3450,16 +3463,6 @@ endif
 endif
 ## end   gnulib module stpcpy
 
-## begin gnulib module stpncpy
-ifeq (,$(OMIT_GNULIB_MODULE_stpncpy))
-
-ifneq (,$(GL_COND_OBJ_STPNCPY_CONDITION))
-libgnu_a_SOURCES += stpncpy.c
-endif
-
-endif
-## end   gnulib module stpncpy
-
 ## begin gnulib module string
 ifeq (,$(OMIT_GNULIB_MODULE_string))
 
diff --git a/lib/nproc.c b/lib/nproc.c
index 2740c458c11..e3de1873a96 100644
--- a/lib/nproc.c
+++ b/lib/nproc.c
@@ -46,7 +46,7 @@
 # include <sys/param.h>
 #endif
 
-#if HAVE_SYS_SYSCTL_H && ! defined __GLIBC__
+#if HAVE_SYS_SYSCTL_H && !(defined __GLIBC__ && defined __linux__)
 # include <sys/sysctl.h>
 #endif
 
@@ -306,7 +306,7 @@ num_processors_ignoring_omp (enum nproc_query query)
   /* Finally, as fallback, use the APIs that don't distinguish between
      NPROC_CURRENT and NPROC_ALL.  */
 
-#if HAVE_SYSCTL && ! defined __GLIBC__ && defined HW_NCPU
+#if HAVE_SYSCTL && !(defined __GLIBC__ && defined __linux__) && defined HW_NCPU
   { /* This works on macOS, FreeBSD, NetBSD, OpenBSD.
        macOS 10.14 does not allow mib to be const.  */
     int nprocs;
diff --git a/lib/readutmp.h b/lib/readutmp.h
new file mode 100644
index 00000000000..fa30fa9a004
--- /dev/null
+++ b/lib/readutmp.h
@@ -0,0 +1,334 @@
+/* Declarations for GNU's read utmp module.
+
+   Copyright (C) 1992-2007, 2009-2023 Free Software Foundation, Inc.
+
+   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/>.  */
+
+/* Written by jla; revised by djm */
+
+#ifndef __READUTMP_H__
+#define __READUTMP_H__
+
+/* This file uses _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_RETURNS_NONNULL,
+   HAVE_UTMP_H, HAVE_UTMPX_H, HAVE_STRUCT_UTMP_*, HAVE_STRUCT_UTMPX_*,
+   HAVE_UTMPNAME, HAVE_UTMPXNAME.  */
+#if !_GL_CONFIG_H_INCLUDED
+# error "Please include config.h first."
+#endif
+
+#include "idx.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <time.h>
+
+/* AIX 4.3.3 has both utmp.h and utmpx.h, but only struct utmp
+   has the ut_exit member.  */
+#if (HAVE_UTMPX_H && HAVE_UTMP_H && HAVE_STRUCT_UTMP_UT_EXIT \
+     && ! HAVE_STRUCT_UTMPX_UT_EXIT)
+# undef HAVE_UTMPX_H
+#endif
+
+/* HPUX 10.20 needs utmp.h, for the definition of e.g., UTMP_FILE.  */
+#if HAVE_UTMP_H
+# include <utmp.h>
+#endif
+
+/* Needed for BOOT_TIME and USER_PROCESS.  */
+#if HAVE_UTMPX_H
+# if defined _THREAD_SAFE && defined UTMP_DATA_INIT
+    /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE
+       defined, work around the duplicate struct utmp_data declaration.  */
+#  define utmp_data gl_aix_4_3_workaround_utmp_data
+# endif
+# include <utmpx.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Type of entries returned by read_utmp on all platforms.  */
+struct gl_utmp
+{
+  /* All 'char *' here are of arbitrary length and point to storage
+     with lifetime equal to that of this struct.  */
+  char *ut_user;                /* User name */
+  char *ut_id;                  /* Session ID */
+  char *ut_line;                /* seat / device */
+  char *ut_host;                /* for remote sessions: user@host or host,
+                                   for local sessions: the X11 display :N */
+  struct timespec ut_ts;        /* time */
+  pid_t ut_pid;                 /* process ID of ? */
+  pid_t ut_session;             /* process ID of session leader */
+  short ut_type;                /* BOOT_TIME, USER_PROCESS, or other */
+  struct { int e_termination; int e_exit; } ut_exit;
+};
+
+/* The following types, macros, and constants describe the 'struct gl_utmp'.  
*/
+#define UT_USER(UT) ((UT)->ut_user)
+#define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec)
+#define UT_PID(UT) ((UT)->ut_pid)
+#define UT_TYPE_EQ(UT, V) ((UT)->ut_type == (V))
+#define UT_TYPE_NOT_DEFINED 0
+#define UT_EXIT_E_TERMINATION(UT) ((UT)->ut_exit.e_termination)
+#define UT_EXIT_E_EXIT(UT) ((UT)->ut_exit.e_exit)
+
+/* Type of entry returned by read_utmp().  */
+typedef struct gl_utmp STRUCT_UTMP;
+
+/* Size of the UT_USER (ut) member, or -1 if unbounded.  */
+enum { UT_USER_SIZE = -1 };
+
+/* Size of the ut->ut_id member, or -1 if unbounded.  */
+enum { UT_ID_SIZE = -1 };
+
+/* Size of the ut->ut_line member, or -1 if unbounded.  */
+enum { UT_LINE_SIZE = -1 };
+
+/* Size of the ut->ut_host member, or -1 if unbounded.  */
+enum { UT_HOST_SIZE = -1 };
+
+
+/* When read_utmp accesses a file (as opposed to fetching the information
+   from systemd), it uses the following low-level types and macros.
+   Keep them here, rather than moving them into readutmp.c, for backward
+   compatibility.  */
+
+#if HAVE_UTMPX_H
+
+/* <utmpx.h> defines 'struct utmpx' with the following fields:
+
+     Field        Type                       Platforms
+     ----------   ------                     ---------
+   ⎡ ut_user      char[]                     glibc, musl, macOS, FreeBSD, AIX, 
HP-UX, IRIX, Solaris, Cygwin
+   ⎣ ut_name      char[]                     NetBSD, Minix
+     ut_id        char[]                     glibc, musl, macOS, FreeBSD, 
NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+     ut_line      char[]                     glibc, musl, macOS, FreeBSD, 
NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+     ut_pid       pid_t                      glibc, musl, macOS, FreeBSD, 
NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+     ut_type      short                      glibc, musl, macOS, FreeBSD, 
NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+   ⎡ ut_tv        struct                     glibc, musl, macOS, FreeBSD, 
NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+   ⎢              { tv_sec; tv_usec; }
+   ⎣ ut_time      time_t                     Cygwin
+     ut_host      char[]                     glibc, musl, macOS, FreeBSD, 
NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+     ut_exit      struct                     glibc, musl, NetBSD, Minix, 
HP-UX, IRIX, Solaris
+                  { e_termination; e_exit; }
+     ut_session   [long] int                 glibc, musl, NetBSD, Minix, IRIX, 
Solaris
+   ⎡ ut_addr      [long] int                 HP-UX, Cygwin
+   ⎢ ut_addr_v6   [u]int[4]                  glibc, musl
+   ⎣ ut_ss        struct sockaddr_storage    NetBSD, Minix
+ */
+
+# if __GLIBC__ && _TIME_BITS == 64
+/* This is a near-copy of glibc's struct utmpx, which stops working
+   after the year 2038.  Unlike the glibc version, struct utmpx32
+   describes the file format even if time_t is 64 bits.  */
+#define _GL_UT_USER_SIZE  sizeof (((struct utmpx *) 0)->ut_user)
+#define _GL_UT_ID_SIZE    sizeof (((struct utmpx *) 0)->ut_id)
+#define _GL_UT_LINE_SIZE  sizeof (((struct utmpx *) 0)->ut_line)
+#define _GL_UT_HOST_SIZE  sizeof (((struct utmpx *) 0)->ut_host)
+struct utmpx32
+{
+  short int ut_type;               /* Type of login.  */
+  pid_t ut_pid;                    /* Process ID of login process.  */
+  char ut_line[_GL_UT_LINE_SIZE];  /* Devicename.  */
+  char ut_id[_GL_UT_ID_SIZE];      /* Inittab ID.  */
+  char ut_user[_GL_UT_USER_SIZE];  /* Username.  */
+  char ut_host[_GL_UT_HOST_SIZE];  /* Hostname for remote login. */
+  struct __exit_status ut_exit;    /* Exit status of a process marked
+                                      as DEAD_PROCESS.  */
+  /* The fields ut_session and ut_tv must be the same size when compiled
+     32- and 64-bit.  This allows files and shared memory to be shared
+     between 32- and 64-bit applications.  */
+  int ut_session;                  /* Session ID, used for windowing.  */
+  struct
+  {
+    /* Seconds.  Unsigned not signed, as glibc did not exist before 1970,
+       and if the format is still in use after 2038 its timestamps
+       will surely have the sign bit on.  This hack stops working
+       at 2106-02-07 06:28:16 UTC.  */
+    unsigned int tv_sec;
+    int tv_usec;                   /* Microseconds.  */
+  } ut_tv;                         /* Time entry was made.  */
+  int ut_addr_v6[4];               /* Internet address of remote host.  */
+  char ut_reserved[20];            /* Reserved for future use.  */
+};
+#  define UTMP_STRUCT_NAME utmpx32
+# else
+#  define UTMP_STRUCT_NAME utmpx
+# endif
+# define SET_UTMP_ENT setutxent
+# define GET_UTMP_ENT getutxent
+# define END_UTMP_ENT endutxent
+# ifdef HAVE_UTMPXNAME /* glibc, musl, macOS, NetBSD, Minix, IRIX, Solaris, 
Cygwin */
+#  define UTMP_NAME_FUNCTION utmpxname
+# elif defined UTXDB_ACTIVE /* FreeBSD */
+#  define UTMP_NAME_FUNCTION(x) setutxdb (UTXDB_ACTIVE, x)
+# endif
+
+#elif HAVE_UTMP_H
+
+/* <utmp.h> defines 'struct utmp' with the following fields:
+
+     Field        Type                       Platforms
+     ----------   ------                     ---------
+   ⎡ ut_user      char[]                     glibc, musl, AIX, HP-UX, IRIX, 
Solaris, Cygwin, Android
+   ⎣ ut_name      char[]                     macOS, old FreeBSD, NetBSD, 
OpenBSD, Minix
+     ut_id        char[]                     glibc, musl, AIX, HP-UX, IRIX, 
Solaris, Cygwin, Android
+     ut_line      char[]                     glibc, musl, macOS, old FreeBSD, 
NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android
+     ut_pid       pid_t                      glibc, musl, AIX, HP-UX, IRIX, 
Solaris, Cygwin, Android
+     ut_type      short                      glibc, musl, AIX, HP-UX, IRIX, 
Solaris, Cygwin, Android
+   ⎡ ut_tv        struct                     glibc, musl, Android
+   ⎢              { tv_sec; tv_usec; }
+   ⎣ ut_time      time_t                     macOS, old FreeBSD, NetBSD, 
OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin
+     ut_host      char[]                     glibc, musl, macOS, old FreeBSD, 
NetBSD, OpenBSD, Minix, AIX, HP-UX, Cygwin, Android
+     ut_exit      struct                     glibc, musl, AIX, HP-UX, IRIX, 
Solaris, Android
+                  { e_termination; e_exit; }
+     ut_session   [long] int                 glibc, musl, Android
+   ⎡ ut_addr      [long] int                 HP-UX, Cygwin
+   ⎣ ut_addr_v6   [u]int[4]                  glibc, musl, Android
+ */
+
+# define UTMP_STRUCT_NAME utmp
+# define SET_UTMP_ENT setutent
+# define GET_UTMP_ENT getutent
+# define END_UTMP_ENT endutent
+# ifdef HAVE_UTMPNAME /* glibc, musl, NetBSD, Minix, AIX, HP-UX, IRIX, 
Solaris, Cygwin, Android */
+#  define UTMP_NAME_FUNCTION utmpname
+# endif
+
+#endif
+
+/* Evaluates to 1 if gl_utmp's ut_id field may ever have a non-zero value.  */
+#define HAVE_STRUCT_XTMP_UT_ID \
+  (READUTMP_USE_SYSTEMD \
+   || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_ID : HAVE_STRUCT_UTMP_UT_ID))
+
+/* Evaluates to 1 if gl_utmp's ut_pid field may ever have a non-zero value.  */
+#define HAVE_STRUCT_XTMP_UT_PID \
+  (READUTMP_USE_SYSTEMD \
+   || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_PID : HAVE_STRUCT_UTMP_UT_PID))
+
+/* Evaluates to 1 if gl_utmp's ut_host field may ever be non-empty.  */
+#define HAVE_STRUCT_XTMP_UT_HOST \
+  (READUTMP_USE_SYSTEMD \
+   || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_HOST : HAVE_STRUCT_UTMP_UT_HOST))
+
+/* Definition of UTMP_FILE.
+   On glibc systems, UTMP_FILE is "/var/run/utmp".  */
+#if !defined UTMP_FILE && defined _PATH_UTMP
+# define UTMP_FILE _PATH_UTMP
+#endif
+#ifdef UTMPX_FILE /* Solaris, SysVr4 */
+# undef UTMP_FILE
+# define UTMP_FILE UTMPX_FILE
+#endif
+#ifndef UTMP_FILE
+# define UTMP_FILE "/etc/utmp"
+#endif
+
+/* Definition of WTMP_FILE.
+   On glibc systems, UTMP_FILE is "/var/log/wtmp".  */
+#if !defined WTMP_FILE && defined _PATH_WTMP
+# define WTMP_FILE _PATH_WTMP
+#endif
+#ifdef WTMPX_FILE /* Solaris, SysVr4 */
+# undef WTMP_FILE
+# define WTMP_FILE WTMPX_FILE
+#endif
+#ifndef WTMP_FILE
+# define WTMP_FILE "/etc/wtmp"
+#endif
+
+/* In early versions of Android, <utmp.h> did not define BOOT_TIME, only
+   USER_PROCESS.  We need to use the value that is defined in newer versions
+   of Android.  */
+#if defined __ANDROID__ && !defined BOOT_TIME
+# define BOOT_TIME 2
+#endif
+
+/* Some platforms, such as OpenBSD, don't have an ut_type field and don't have
+   the BOOT_TIME and USER_PROCESS macros.  But we want to support them in
+   'struct gl_utmp'.  */
+#if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE)
+# define BOOT_TIME 2
+# define USER_PROCESS 0
+#endif
+
+/* Macros that test (UT)->ut_type.  */
+#ifdef BOOT_TIME
+# define UT_TYPE_BOOT_TIME(UT) ((UT)->ut_type == BOOT_TIME)
+#else
+# define UT_TYPE_BOOT_TIME(UT) 0
+#endif
+#ifdef USER_PROCESS
+# define UT_TYPE_USER_PROCESS(UT) ((UT)->ut_type == USER_PROCESS)
+#else
+# define UT_TYPE_USER_PROCESS(UT) 0
+#endif
+
+/* Determines whether an entry *UT corresponds to a user process.  */
+#define IS_USER_PROCESS(UT)                                    \
+  ((UT)->ut_user[0] && UT_TYPE_USER_PROCESS (UT))
+
+/* Define if read_utmp is not just a dummy.  */
+#if READUTMP_USE_SYSTEMD || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ 
|| defined _WIN32
+# define READ_UTMP_SUPPORTED 1
+#endif
+
+/* Options for read_utmp.  */
+enum
+  {
+    READ_UTMP_CHECK_PIDS   = 1,
+    READ_UTMP_USER_PROCESS = 2,
+    READ_UTMP_BOOT_TIME    = 4,
+    READ_UTMP_NO_BOOT_TIME = 8
+  };
+
+/* Return a copy of (UT)->ut_user, without trailing spaces,
+   as a freshly allocated string.  */
+char *extract_trimmed_name (const STRUCT_UTMP *ut)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
+  _GL_ATTRIBUTE_RETURNS_NONNULL;
+
+/* Read the utmp entries corresponding to file FILE into freshly-
+   malloc'd storage, set *UTMP_BUF to that pointer, set *N_ENTRIES to
+   the number of entries, and return zero.  If there is any error,
+   return -1, setting errno, and don't modify the parameters.
+   A good candidate for FILE is UTMP_FILE.
+   If OPTIONS & READ_UTMP_CHECK_PIDS is nonzero, omit entries whose
+   process-IDs do not currently exist.
+   If OPTIONS & READ_UTMP_USER_PROCESS is nonzero, omit entries which
+   do not correspond to a user process.
+   If OPTIONS & READ_UTMP_BOOT_TIME is nonzero, omit all entries except
+   the one that contains the boot time.
+   If OPTIONS & READ_UTMP_NO_BOOT_TIME is nonzero, omit the boot time
+   entries.
+
+   This function is not multithread-safe, since on many platforms it
+   invokes the functions setutxent, getutxent, endutxent.  These
+   functions are needed because they may lock FILE (so that we don't
+   read garbage when a concurrent process writes to FILE), but their
+   drawback is that they have a common global state.  */
+int read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
+               int options);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __READUTMP_H__ */
diff --git a/lib/stpncpy.c b/lib/stpncpy.c
deleted file mode 100644
index d1422a927df..00000000000
--- a/lib/stpncpy.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (C) 1993, 1995-1997, 2002-2003, 2005-2007, 2009-2023 Free Software
- * Foundation, Inc.
-
-   NOTE: The canonical source of this file is maintained with the GNU C 
Library.
-   Bugs can be reported to bug-glibc@gnu.org.
-
-   This file is free software: you can redistribute it and/or modify
-   it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   This file 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 Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public License
-   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
-
-/* This is almost copied from strncpy.c, written by Torbjorn Granlund.  */
-
-#include <config.h>
-
-/* Specification.  */
-#include <string.h>
-
-#ifndef weak_alias
-# define __stpncpy stpncpy
-#endif
-
-/* Copy no more than N bytes of SRC to DST, returning a pointer past the
-   last non-NUL byte written into DST.  */
-char *
-(__stpncpy) (char *dest, const char *src, size_t n)
-{
-  char c;
-  char *s = dest;
-
-  if (n >= 4)
-    {
-      size_t n4 = n >> 2;
-
-      for (;;)
-        {
-          c = *src++;
-          *dest++ = c;
-          if (c == '\0')
-            break;
-          c = *src++;
-          *dest++ = c;
-          if (c == '\0')
-            break;
-          c = *src++;
-          *dest++ = c;
-          if (c == '\0')
-            break;
-          c = *src++;
-          *dest++ = c;
-          if (c == '\0')
-            break;
-          if (--n4 == 0)
-            goto last_chars;
-        }
-      n -= dest - s;
-      goto zero_fill;
-    }
-
- last_chars:
-  n &= 3;
-  if (n == 0)
-    return dest;
-
-  for (;;)
-    {
-      c = *src++;
-      --n;
-      *dest++ = c;
-      if (c == '\0')
-        break;
-      if (n == 0)
-        return dest;
-    }
-
- zero_fill:
-  while (n-- > 0)
-    dest[n] = '\0';
-
-  return dest - 1;
-}
-#ifdef weak_alias
-weak_alias (__stpncpy, stpncpy)
-#endif
diff --git a/lib/time.in.h b/lib/time.in.h
index 06428adb1d0..06824da9d3d 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -143,6 +143,12 @@ _GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, 
int base));
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (timespec_get);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef timespec_get
+#  if HAVE_RAW_DECL_TIMESPEC_GET
+_GL_WARN_ON_USE (timespec_get, "timespec_get is unportable - "
+                 "use gnulib module timespec_get for portability");
+#  endif
 # endif
 
 /* Set *TS to the current time resolution, and return BASE.
@@ -154,6 +160,12 @@ _GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec 
*ts, int base)
 #  endif
 _GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base));
 _GL_CXXALIASWARN (timespec_getres);
+# elif defined GNULIB_POSIXCHECK
+#  undef timespec_getres
+#  if HAVE_RAW_DECL_TIMESPEC_GETRES
+_GL_WARN_ON_USE (timespec_getres, "timespec_getres is unportable - "
+                 "use gnulib module timespec_getres for portability");
+#  endif
 # endif
 
 /* Return the number of seconds that have elapsed since the Epoch.  */
@@ -170,6 +182,12 @@ _GL_CXXALIAS_SYS (time, time_t, (time_t *__tp));
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (time);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef time
+#  if HAVE_RAW_DECL_TIME
+_GL_WARN_ON_USE (time, "time has consistency problems - "
+                 "use gnulib module time for portability");
+#  endif
 # endif
 
 /* Sleep for at least RQTP seconds unless interrupted,  If interrupted,
@@ -195,6 +213,12 @@ _GL_CXXALIAS_SYS (nanosleep, int,
                   (struct timespec const *__rqtp, struct timespec *__rmtp));
 #  endif
 _GL_CXXALIASWARN (nanosleep);
+# elif defined GNULIB_POSIXCHECK
+#  undef nanosleep
+#  if HAVE_RAW_DECL_NANOSLEEP
+_GL_WARN_ON_USE (nanosleep, "nanosleep is unportable - "
+                 "use gnulib module nanosleep for portability");
+#  endif
 # endif
 
 /* Initialize time conversion information.  */
@@ -230,6 +254,12 @@ _GL_CXXALIAS_MDA (tzset, void, (void));
 _GL_CXXALIAS_SYS (tzset, void, (void));
 #  endif
 _GL_CXXALIASWARN (tzset);
+# elif defined GNULIB_POSIXCHECK
+#  undef tzset
+#  if HAVE_RAW_DECL_TZSET
+_GL_WARN_ON_USE (tzset, "tzset has portability problems - "
+                 "use gnulib module tzset for portability");
+#  endif
 # endif
 
 /* Return the 'time_t' representation of TP and normalize TP.  */
@@ -246,6 +276,12 @@ _GL_CXXALIAS_SYS (mktime, time_t, (struct tm *__tp));
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (mktime);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef mktime
+#  if HAVE_RAW_DECL_MKTIME
+_GL_WARN_ON_USE (mktime, "mktime has portability problems - "
+                 "use gnulib module mktime for portability");
+#  endif
 # endif
 
 /* Convert TIMER to RESULT, assuming local time and UTC respectively.  See
@@ -296,6 +332,17 @@ _GL_CXXALIAS_SYS (gmtime_r, struct tm *, (time_t const 
*restrict __timer,
 #  if @HAVE_DECL_LOCALTIME_R@
 _GL_CXXALIASWARN (gmtime_r);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef localtime_r
+#  if HAVE_RAW_DECL_LOCALTIME_R
+_GL_WARN_ON_USE (localtime_r, "localtime_r is unportable - "
+                 "use gnulib module time_r for portability");
+#  endif
+#  undef gmtime_r
+#  if HAVE_RAW_DECL_GMTIME_R
+_GL_WARN_ON_USE (gmtime_r, "gmtime_r is unportable - "
+                 "use gnulib module time_r for portability");
+#  endif
 # endif
 
 /* Convert TIMER to RESULT, assuming local time and UTC respectively.  See
@@ -316,6 +363,12 @@ _GL_CXXALIAS_SYS (localtime, struct tm *, (time_t const 
*__timer));
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (localtime);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef localtime
+#  if HAVE_RAW_DECL_LOCALTIME
+_GL_WARN_ON_USE (localtime, "localtime has portability problems - "
+                 "use gnulib module localtime for portability");
+#  endif
 # endif
 
 # if 0 || @REPLACE_GMTIME@
@@ -347,6 +400,12 @@ _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict 
__buf,
                                      char const *restrict __format,
                                      struct tm *restrict __tm));
 _GL_CXXALIASWARN (strptime);
+# elif defined GNULIB_POSIXCHECK
+#  undef strptime
+#  if HAVE_RAW_DECL_STRPTIME
+_GL_WARN_ON_USE (strptime, "strptime is unportable - "
+                 "use gnulib module strptime for portability");
+#  endif
 # endif
 
 /* Convert *TP to a date and time string.  See
@@ -368,6 +427,12 @@ _GL_CXXALIAS_SYS (ctime, char *, (time_t const *__tp));
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (ctime);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef ctime
+#  if HAVE_RAW_DECL_CTIME
+_GL_WARN_ON_USE (ctime, "ctime has portability problems - "
+                 "use gnulib module ctime for portability");
+#  endif
 # endif
 
 /* Convert *TP to a date and time string.  See
@@ -392,6 +457,12 @@ _GL_CXXALIAS_SYS (strftime, size_t,
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (strftime);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef strftime
+#  if HAVE_RAW_DECL_STRFTIME
+_GL_WARN_ON_USE (strftime, "strftime has portability problems - "
+                 "use gnulib module strftime-fixes for portability");
+#  endif
 # endif
 
 # if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@
@@ -469,6 +540,12 @@ _GL_CXXALIAS_SYS (timegm, time_t, (struct tm *__tm));
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (timegm);
 #  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef timegm
+#  if HAVE_RAW_DECL_TIMEGM
+_GL_WARN_ON_USE (timegm, "timegm is unportable - "
+                 "use gnulib module timegm for portability");
+#  endif
 # endif
 
 /* Encourage applications to avoid unsafe functions that can overrun
@@ -476,8 +553,10 @@ _GL_CXXALIASWARN (timegm);
    applications should use strftime (or even sprintf) instead.  */
 # if defined GNULIB_POSIXCHECK
 #  undef asctime
+#  if HAVE_RAW_DECL_ASCTIME
 _GL_WARN_ON_USE (asctime, "asctime can overrun buffers in some cases - "
                  "better use strftime (or even sprintf) instead");
+#  endif
 # endif
 # if defined GNULIB_POSIXCHECK
 #  undef asctime_r
@@ -488,8 +567,10 @@ _GL_WARN_ON_USE (asctime_r, "asctime_r can overrun buffers 
in some cases - "
 # endif
 # if defined GNULIB_POSIXCHECK
 #  undef ctime
+#  if HAVE_RAW_DECL_CTIME
 _GL_WARN_ON_USE (ctime, "ctime can overrun buffers in some cases - "
                  "better use strftime (or even sprintf) instead");
+#  endif
 # endif
 # if defined GNULIB_POSIXCHECK
 #  undef ctime_r
diff --git a/lisp/ChangeLog.13 b/lisp/ChangeLog.13
index 820110e2fba..49ff87f464c 100644
--- a/lisp/ChangeLog.13
+++ b/lisp/ChangeLog.13
@@ -4251,7 +4251,7 @@
        * doc-view.el (doc-view-mode): Support tramp, compressed files and
        files inside archives uniformly.
 
-2008-01-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-01-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * textmodes/sgml-mode.el (sgml-tag-syntax-table): Initialize this
        constant with a computation on sgml-specials rather than a literal
@@ -4656,7 +4656,7 @@
        (vc-git-dir-state): Use it instead of processing the status
        results here.
 
-2008-01-02  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-01-02  Eric S. Raymond  <esr@thyrsus.com>
 
        * progmodes/grep.el (grep-find-ignored-directories):
        Initialize from the value of vc-directory-exclusion-list.
@@ -4718,7 +4718,7 @@
        MS-Windows and MS-DOS.
        (ispell-grep-options): Use "-Ei" on MS-Windows and MS-DOS.
 
-2008-01-02  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-01-02  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-svn.el (vc-svn-modify-change comment): New function.
 
@@ -4727,7 +4727,7 @@
        * vc-git.el (vc-git-dir-state): Set the vc-backend property.
        Do not disable undo, with-temp-buffer does it by default.
 
-2008-01-01  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-01-01  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-svn.el (vc-svn-parse-status): Set the `unregistered' property
        correctly.
@@ -4802,7 +4802,7 @@
 
        * vc-hg.el (vc-hg-dir-state): Set the vc-backend property.
 
-2007-12-29  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-12-29  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-svn.el (vc-svn-parse-status): Recognize 'unregistered,
        'added, 'removed.
@@ -4943,7 +4943,7 @@
 
        * menu-bar.el (menu-bar-describe-menu): Remove dots from menu text.
 
-2007-12-28  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-12-28  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-hooks.el, vc.el: Move vc-directory-exclusion-list from vc.el
        to vc-hooks.el so it will be available to other modes, such as
@@ -4997,7 +4997,7 @@
        * calc/calccomp.el (math-to-percentsigns): Change placeholder
        for percent signs.
 
-2007-12-27  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-12-27  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-dired-ignorable-p, vc-dired-hook): Speed optimization;
        use completion-ignored-extensions to detect files that should be
@@ -5015,7 +5015,7 @@
        (ps-print-preprint-region): Use `ps-mark-active-p' instead of
        `region-active-p' for error checking.
 
-2007-12-27  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-12-27  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el, vc-sccs.el, vc-rcs.el, vc-cvs.el, vc-mcvs.el:
        Put new machinery in place to support editing of change comments
@@ -5029,7 +5029,7 @@
        * international/mule-cmds.el (select-safe-coding-system):
        When a buffer is modified, cancel the writing.
 
-2007-12-26  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-12-26  Eric S. Raymond  <esr@thyrsus.com>
 
        * log-view.el: Add Subversion and Mercurial log format samples.
 
@@ -9147,7 +9147,7 @@
        don't try other `or' branches regardless of the value returned by
        fill-region; just return t.
 
-2007-10-20  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-20  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-do-command): Condition out a misleading message when
        running asynchronously.
@@ -9197,7 +9197,7 @@
 
        * vc-hg.el: Require log-view at compile time.
 
-2007-10-20  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-20  Eric S. Raymond  <esr@thyrsus.com>
 
        * log-view.el (log-view-diff): Adapt log-view-diff for new VC API.
 
@@ -9812,7 +9812,7 @@
        * bs.el (bs--mark-unmark): New function.
        (bs-mark-current, bs-unmark-current): Use it.
 
-2007-10-11  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-11  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-diff):
        (vc-diff-internal): Merge a patch by Juanma Barranquero.  Also,
@@ -9830,7 +9830,7 @@
        Use `follow-call-process-filter' rather than `process-filter'.
        Simplify.
 
-2007-10-11  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-11  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-hooks.el (vc-registered): Robustify this function a bit
        against filenames with no directory component.
@@ -9919,7 +9919,7 @@
        * help-fns.el (describe-variable): Add missing "  " for multiline
        obsolescence info and missing EOL after global value.
 
-2007-10-10  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-10  Eric S. Raymond  <esr@thyrsus.com>
 
        * add-log.el:
        * ediff-vers.el:
@@ -9950,7 +9950,7 @@
        mode" in docstrings and messages.
        (follow-menu-filter): Fix arg passed to `bound-and-true-p'.
 
-2007-10-10  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-10  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-next-action): Rewrite completely; this principal
        entry point now operates on a current fileset selected either
@@ -10329,7 +10329,7 @@
        (smerge-refine-subst): New function holding most of smerge-refine.
        (smerge-refine): Use it.
 
-2007-10-08  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-08  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-default-wash-log): Remove unused code, the
        log washers all live in the backends now.
@@ -10390,7 +10390,7 @@
        * net/tramp-fish.el (tramp-fish-handle-process-file):
        Rewrite temporary file handling.
 
-2007-10-06  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-10-06  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el: Workfile version -> focus version change.  Port various
        comments from new VC to reduce the noise in the diff.
@@ -12758,7 +12758,7 @@
 2007-08-20  Thien-Thi Nguyen  <ttn@gnuvola.org>
 
        * vc-rcs.el (vc-rcs-annotate-command):
-       Fix bug introduced 2007-07-18T16:32:40Z!esr@snark.thyrsus.com:
+       Fix bug introduced 2007-07-18T16:32:40Z!esr@thyrsus.com:
        Add back :vc-annotate-prefix propertization.
 
 2007-08-20  Andreas Schwab  <schwab@suse.de>
@@ -14226,7 +14226,7 @@
        * vc-hooks.el (vc-find-root): Walk up the tree to find an existing
        `file' from which to start the search.
 
-2007-07-19  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-07-19  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-cvs.el (vc-cvs-checkin, vc-cvs-diff): Finish transition from
        having a single file argument to having a list of files as the
@@ -14245,7 +14245,7 @@
 
        * uniquify.el: Docstring fixes.
 
-2007-07-18  Eric S. Raymond  <esr@snark.thyrsus.com>
+2007-07-18  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (revision-granularity, create-repo): Document new vc
        backend properties.
diff --git a/lisp/ChangeLog.14 b/lisp/ChangeLog.14
index 09bc4f6c4eb..129621791c0 100644
--- a/lisp/ChangeLog.14
+++ b/lisp/ChangeLog.14
@@ -12125,7 +12125,7 @@
        * vc-dispatcher.el (top-level): Revert previous change: require cl
        when compiling.
 
-2008-05-16  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-16  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-default-status-printer)
        (vc-default-prettify-state-info): Enhance the state prettyprinter
@@ -12143,7 +12143,7 @@
        * net/tramp.el (tramp-handle-write-region): Fix check for short track.
        Reported by Glenn Morris <rgm@gnu.org>.
 
-2008-05-16  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-16  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el: Remove my analysis of SCCS/RCS concurrency issues from
        the end of the file, it was good work at one time but has been
@@ -12179,7 +12179,7 @@
        (ses-mode): Set indent-tabs-mode to nil.
        (ses-center): Use string-width rather than length.
 
-2008-05-15  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-15  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-cvs.el, vc-git.el, vc-hg.el, vc-hooks.el, vc-mcvs.el,
        * vc-rcs.el, vc-sccs.el, vc-svn.el, vc.el:
@@ -12204,7 +12204,7 @@
        * progmodes/cc-mode.el (declare-function): Add compat definition.
        (awk-mode-syntax-table, c-awk-unstick-NL-prop): Declare for compiler.
 
-2008-05-14  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-14  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-dispatcher.el (vc-dispatcher-selection): Change the returned
        list to a cons so the caller can get back both expanded and
@@ -12251,7 +12251,7 @@
        (tramp-echo-mark-marker): New defconst.
        (tramp-check-for-regexp): Use it.
 
-2008-05-14  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-14  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-deduce-fileset): Do the right thing when visiting a
        buffer (say, a log buffer or diff buffer) with a vc-dir buffer
@@ -12343,7 +12343,7 @@
        (dired-toggle-marks, dired-change-marks, dired-unmark-all-files):
        buffer-read-only -> inhibit-read-only.
 
-2008-05-12  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-12  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-expand-dirs): Stop this function from tossing out
        explicitly specified files.
@@ -12395,7 +12395,7 @@
        * emulation/cua-base.el: Put isearch-scroll property
        on cua-scroll-up and cua-scroll-down.
 
-2008-05-11  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-11  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-hooks.el (vc-recompute-state): Remove (dead code).
 
@@ -12416,7 +12416,7 @@
 
        * smerge-mode.el (smerge-command-prefix): Fix custom type.
 
-2008-05-10  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-10  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-dispatcher.el (vc-dir-next-directory, vc-dir-prev-directory):
        New functions implementing motion to next and previous directory.
@@ -12449,7 +12449,7 @@
 
        * vc-hooks.el (vc-prefix-map): Remove duplicate binding.
 
-2008-05-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-dir):
        * vc-hooks.el: Tweak the VC directory bindings.  These are now
@@ -12466,7 +12466,7 @@
 
        * simple.el (start-file-process): Clarify docstring.
 
-2008-05-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-sccs.el, vc-svn.el, vc-git.el, vc-hg.el, vc-mtn.el:
        Remove stub implementations of, and references to, wash-log.
@@ -12515,7 +12515,7 @@
        * vc.el (vc-version-diff, vc-print-log, vc-revert, vc-rollback)
        (vc-update): Remove unused let bindings.
 
-2008-05-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-deduce-fileset, vc-next-action, vc-version-diff)
        (vc-diff, vc-revert, vc-rollback, vc-update):
@@ -12609,7 +12609,7 @@
        (robin-current-package-name): Doc fix.
        (robin-activate): Don't use `iff' in docstring.
 
-2008-05-07  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-07  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el, vc-dispatcher.el: VC-Dired support removed.
        The code uses a ewoc-based implementation now.
@@ -12639,7 +12639,7 @@
        * progmodes/fortran.el (fortran-mode): Fix font-lock-syntactic-keywords
        oddness.
 
-2008-05-06  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-06  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-hooks.el (vc-find-file-hook):
        * vc-dispatcher.el (vc-resynch-window): Decouple vc-dispatcher
@@ -12692,7 +12692,7 @@
 
        * dired.el (dired-read-dir-and-switches): Fix up last change.
 
-2008-05-05  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-05  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-deduce-fileset): Lift all the policy and UI stuff
        out of this function, move it to vc-dispatcher-selection-set.
@@ -12770,7 +12770,7 @@
        * ls-lisp.el (ls-lisp-insert-directory): Use `string-width'
        instead of `length' for comparing length of user and group names.
 
-2008-05-03  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-03  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-dispatcher.el: New file, separates out the UI and command
        execution machinery from VCS-specific logic left in vc.el.
@@ -12789,7 +12789,7 @@
        * progmodes/grep.el (grep-mode-map): Bind "g" to recompile (like
        in dired &c).
 
-2008-05-02  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-02  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-arch.el, vc-bzr.el, vc-cvs.el, vc-git.el, vc-hg.el,
        * vc-hooks.el, vc-mcvs.el, vc-mtn.el, vc-rcs.el, vc-sccs.el,
@@ -12846,7 +12846,7 @@
        function that is no longer there.
        (hilit-chg-set): Remove running of highlight-changes-enable-hook.
 
-2008-05-02  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-02  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-default-dired-state-info): Change name of primitive
        to prettify-state-info, in preparation for ripping out dired mode.
@@ -12879,7 +12879,7 @@
        * progmodes/compile.el (compilation-auto-jump):
        Set window point to `pos' explicitly.
 
-2008-05-01  Eric S. Raymond  <esr@snark.thyrsus.com>
+2008-05-01  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-bzr.el (vc-bzr-state): Allow this to return 'ignored
        when appropriate.
diff --git a/lisp/ChangeLog.15 b/lisp/ChangeLog.15
index af3203444ae..6bd61211d47 100644
--- a/lisp/ChangeLog.15
+++ b/lisp/ChangeLog.15
@@ -11888,7 +11888,7 @@
        (log-edit-mode, log-edit-extra-flags, log-edit-mode):
        New declarations.
 
-2010-04-09  Eric Raymond  <esr@snark.thyrsus.com>
+2010-04-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc-hooks.el, vc-git.el: Improve documentation comments.
 
diff --git a/lisp/ChangeLog.17 b/lisp/ChangeLog.17
index 5036eabf0fd..3377da7c54d 100644
--- a/lisp/ChangeLog.17
+++ b/lisp/ChangeLog.17
@@ -4218,7 +4218,7 @@
        (package-activate-1): Reload files given by 
`package--list-loaded-files'.
        Fix bug#10125, bug#18443, and bug#18448.
 
-2014-12-13  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-13  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc-svn.el (vc-svn-diff): Fix bug #19312.
 
@@ -4253,7 +4253,7 @@
        * files.el (directory-files-recursively): Don't follow symlinks to
        other directories.
 
-2014-12-12  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-12  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc-dav.el, vc/vc-git.el, vc/vc-hg.el, vc/vc-src.el:
        * vc/vc.el: latest-on-branch-p is no longer a public method.
@@ -4276,7 +4276,7 @@
 
        * emacs-lisp/let-alist.el: Add new package and macro.
 
-2014-12-10  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-10  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc-dispatcher.el, vc/vc-hooks.el, vc/vc-rcs.el:
        * vc/vc-sccs.el, vc/vc.el: Righteous featurectomy of vc-keep-workfiles,
@@ -4308,7 +4308,7 @@
        (ruby-toggle-string-quotes): New command that allows you to quickly
        toggle between single-quoted and double-quoted string literals.
 
-2014-12-09  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-09  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc-src.el (vc-src-do-comand): Prepend -- to file argument
        list, avoids problems witt names containing hyphens.
@@ -4429,7 +4429,7 @@
        * vc/vc-hg.el (vc-hg-dir-status-files): Only include ignores files
        when FILES is non-nil (bug#19304).
 
-2014-12-08  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-08  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc-arch.el: Move to obsolete directory so a test framework
        won't trip over bit-rot in it.  There has been no Arch snapshot
@@ -4593,7 +4593,7 @@
        more extensions when generating includes (programs)
        (bug#19254).
 
-2014-12-03  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-03  Eric S. Raymond  <esr@thyrsus.com>
 
        * files.el (file-tree-walk): Fix docstring.
 
@@ -4636,7 +4636,7 @@
 
        * whitespace.el (whitespace-big-indent-regexp): Add :version.
 
-2014-12-02  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-02  Eric S. Raymond  <esr@thyrsus.com>
 
        * subr.el (filter): New macro.  Because it's just silly for a Lisp
        not to have this in 2014.  And VC needs it.
@@ -4659,7 +4659,7 @@
        is no longer a public method.  It is now local to the one place
        it's used, in the RCS steal-lock method.
 
-2014-12-01  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-01  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc.el: In all backends: API simplification; could-register
        is no longer a public method.  (vc-cvs.el still has a private
@@ -4772,7 +4772,7 @@
        * net/eww.el (eww): Leave point in a place that doesn't cause
        scrolling when displaying "Loading...".
 
-2014-12-01  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-01  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc.el, vc/vc-cvs.el, vc/vc-rcs.el, vc/vc-svn.el: The 'merge'
        backend method of RCS/CVS/SVN is now 'merge-file', to contrast with
@@ -4791,7 +4791,7 @@
 
        * emacs-lisp/inline.el: New file.
 
-2014-12-01  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-12-01  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc.el, vc-hooks.el: All backends: API simplification;
        vc-state-heuristic is no longer a public method, having been
@@ -5226,7 +5226,7 @@
 
        * vc/vc.el: Fix a typo in the commentary.
 
-2014-11-20  Eric S. Raymond  <esr@snark.thyrsus.com>
+2014-11-20  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc/vc-src.el, vc/vc.el: Added support for SRC.  Needs more
        testing and a real log-view mode.
diff --git a/lisp/ChangeLog.3 b/lisp/ChangeLog.3
index 5c4d1e7a82a..29585129a8a 100644
--- a/lisp/ChangeLog.3
+++ b/lisp/ChangeLog.3
@@ -990,7 +990,7 @@
        (compilation-minor-mode): New function to toggle
        compilation-minor-mode; if setting it, call compilation-setup.
 
-1993-04-28  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-28  Eric S. Raymond  (esr@thyrsus.com)
 
        * bibtex.el: Installed Aaron Larson's new bibtex.el.  See the
        header comment for details.
@@ -1004,7 +1004,7 @@
 
        * files.el (file-truename): Undo last change.
 
-1993-04-27  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * files.el (file-truename): Do the right thing when $HOME = "".
 
@@ -1058,7 +1058,7 @@
        (find-tag-noselect): If NEXT-P is '-, pop location off
        tags-location-stack.
 
-1993-04-26  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * cmacexp.el: Installed Francesco Potortì's enhanced and
        cleaned-up version, see its commentary for details.
@@ -1070,13 +1070,13 @@
        Defvars added for many variables.
        (te-stty-string): Specify the characters explicitly--not `stty dec'.
 
-1993-04-26  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * files.el (cd): Handle leading "~" like an absolute filename.
 
        * dired.el: Changed fsets to defaliases.
 
-1993-04-25  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-25  Eric S. Raymond  (esr@thyrsus.com)
 
        * comint.el (comint-mod): Nuked.  A call to ring-mod replaces it.
        (comint-mem): Nuked.  A call to member replaces it.
@@ -1099,7 +1099,7 @@
        (vc-finish-logentry, vc-next-comment, vc-previous-comment):
        Replace *VC-comment-buffer* with a ring vector.
 
-1993-04-25  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-25  Eric S. Raymond  (esr@thyrsus.com)
 
        * simple.el (down-arrow): New function.
        Uses next-line-add-newlines to suppress addition of new lines at end of
@@ -1138,11 +1138,11 @@
        * shell.el (shell-prompt-pattern): Add `;' as potential prompt
        delimiter (for `es' and `rc' shells most particularly).
 
-1993-04-23  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * isearch.el: Replaced all fsets with defaliases.
 
-1993-04-23  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * bytecomp.el (define-function): Change name back to defaliases
        to get things in a known-good state.  The unload patch had been
@@ -1190,7 +1190,7 @@
        * ange-ftp.el (ange-ftp-binary-file-name-regexp):
        Match .z and .z-part-?? files.
 
-1993-04-21  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-21  Eric S. Raymond  (esr@thyrsus.com)
 
        * makefile.el: Rewritten and simplified, commentary added.  It now
        will usually detect when the makefile target or macro lists need
@@ -1223,7 +1223,7 @@
        * sendmail.el (mail-do-fcc): Make a numeric time zone indicator
        with current-time-zone--don't run `date'.
 
-1993-04-16  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-16  Eric S. Raymond  (esr@thyrsus.com)
 
        * bytecomp.el (byte-compile, byte-compile-keep-pending)
        (byte-compile-file-form-defmumble): Generate define-function
@@ -1237,7 +1237,7 @@
        * diff.el (diff-parse-differences): Small robustification ---
        don't lose if we call this with compilation-parsing-end nil
 
-1993-04-16  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-16  Eric S. Raymond  (esr@thyrsus.com)
 
        * electric.el (shrink-window-if-larger-than-buffer):
        Move to window.el.
@@ -1286,14 +1286,14 @@
 
        * isearch.el: Doc fixes.
 
-1993-04-14  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-14  Eric S. Raymond  (esr@thyrsus.com)
 
        * gud.el (gud-mode): Created C-c synonym bindings in the GUD
        buffer's local map.
 
        (gud-key-prefix): Change to C-x C-a.
 
-1993-04-14  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-14  Eric S. Raymond  (esr@thyrsus.com)
 
        * help-macro.el: Name changed from help-screen.el to fit in a
        14-character limit.
@@ -1301,7 +1301,7 @@
        * sun-curs.el: Name changed from sun-cursors.el to protect the
        innocents.
 
-1993-04-14  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-14  Eric S. Raymond  (esr@thyrsus.com)
 
        * finder.el: Rewritten.  The Finder is now a major mode with the
        ability to browse package commentary sections and a completely
@@ -1352,7 +1352,7 @@
        * rot13.el (rot13-other-window): Add autoload.
        (rot13-display-table): Use `vector', not `make-rope'.
 
-1993-04-10  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-10  Eric S. Raymond  (esr@thyrsus.com)
 
        * gud.el (gdb, sdb, dbx): Improve prompting a la grep.
 
@@ -1369,7 +1369,7 @@
        empty string in response to the keyword prompt, restore the old
        window configuration properly.
 
-1993-04-09  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-04-09  Eric S. Raymond  (esr@thyrsus.com)
 
        * emerge.el (emerge-with-ancestor): Applied Donald Erway's fix
        patch, which included the following explanatory comment: "D.Erway
@@ -1394,7 +1394,7 @@
 
        * autoload.el (generate-file-autoloads): Doc fix.
 
-1993-04-08  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-04-08  Eric S. Raymond  (esr@thyrsus.com)
 
        * gud.el: Massive changes, amounting nearly to a rewrite.  The new
        features include auto-configuring support for SVr4, more commands,
@@ -1508,7 +1508,7 @@
        Change MIPS RISC CC regexp (last one) to
        be anchored at bol, and to never match multiple lines.
 
-1993-04-03  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-04-03  Eric S. Raymond  (esr@thyrsus.com)
 
        * man.el, assoc.el: Installed Barry Warsaw's new and much more
        featureful man page browser.
@@ -1520,7 +1520,7 @@
 
        * comint.el: New comint-read-noecho.
 
-1993-04-02  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-04-02  Eric S. Raymond  (esr@thyrsus.com)
 
        * chistory.el (repeat-history-command): Bug fix.  Someone forgot a car.
 
@@ -1595,7 +1595,7 @@
        editing ability and be able to abort when called from a process
        filter.  Re-arranged and updated docstring.
 
-1993-03-30  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-30  Eric S. Raymond  (esr@thyrsus.com)
 
        * ring.el: Changed summary line.
 
@@ -1611,7 +1611,7 @@
 
        * buff-menu.el: Put back removed years in copyright notice.
 
-1993-03-29  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-29  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.el (vc-next-action, vc-print-log, vc-diff, vc-revert-buffer):
        Improve logic for parent buffer finding.
@@ -1652,7 +1652,7 @@
        rlogin-password-paranoia is set.
        (rlogin-with-args, rlogin-password): New functions.
 
-1993-03-28  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-28  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.el (vc-comment-to-changelog): A useful vc-checkin hook, added.
        (vc-checkout): Now rejects attempts to check out files via FTP.
@@ -1674,7 +1674,7 @@
        * ebuff-menu.el (electric-buffer-menu-mode-map): fillarray isn't a
        valid operation on maps any more.
 
-1993-03-27  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * refer.el: Installed.
 
@@ -1682,7 +1682,7 @@
 
        * lucid.el (try-face-font, find-face, get-face): New aliases.
 
-1993-03-27  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * abbrevlist.el, old-inf-lisp.el, old-screen.el, old-shell.el,
        * oshell.el: Removed.
@@ -1702,13 +1702,13 @@
        (set-case-syntax-delims, set-case-syntax-pair, set-case-syntax):
        Rename arg STRING to TABLE.  Do not set the standard case table.
 
-1993-03-26  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * loaddefs.el: Commented out function-key-error definition and
        uses in the global keymaps.  RMS and jimb objected to the amount
        of space these took up in the keybinding listings.
 
-1993-03-27  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * lpr.el (printify-buffer): Add, debugged from Roland McGrath's
        printify-buffer code in LCD.
@@ -1739,7 +1739,7 @@
        (set-visited-file-name): Kill local-write-file-hooks as local var.
        (basic-save-buffer): Use local-write-file-hooks.
 
-1993-03-26  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * yow.el (psychoanalyze-pinhead): Needed a prefrontal lobotomy.
        I gave it one.
@@ -1752,7 +1752,7 @@
 
        * uncompress.el: Add provide call.
 
-1993-03-25  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-25  Eric S. Raymond  (esr@thyrsus.com)
 
        * lisp-mnt.el (lm-last-modified-date): Fix return bug.
 
@@ -1784,7 +1784,7 @@
        * term/x-win.el: Bind M-next to an alias scroll-other-window-1
        to get better doc string output.
 
-1993-03-23  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * compile.el: Fix library headers.
 
@@ -1793,7 +1793,7 @@
        * files.el (insert-directory): Do chase symlinks before passing
        the directory name to ls.
 
-1993-03-23  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * buff-menu.el: Incorporated changes from Bob Weiner's enhanced
        buff-menu from the LCD archive.
@@ -1802,7 +1802,7 @@
 
        * replace.el (query-replace-map): Define backspace like delete.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * cookie.el: Created.  This file contains what was formerly the
        guts of spook.el, lightly hacked to support more than one
@@ -1822,7 +1822,7 @@
        * term/x-win.el (x-win-suspend-error):
        suspend-hook renamed from suspend-hooks.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * help.el, register.el, replace.el, reposition.el, rfc822.el,
        * rlogin.el, rot13.el, scribe.el, scroll-bar.el, sendmail.el,
@@ -1835,14 +1835,14 @@
        * diary-insert.el: Change the name to diary-ins.el.
        * calendar.el: Change all autoload references to diary-ins.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * man.el, mlconvert.el, mlsupport.el, modula2.el, mouse.el,
        * mpuz.el, netunam.el, novice.el, nroff-mode.el, options.el,
        * outline.el, page.el, paragraphs.el, picture.el, prolog.el,
        * rect.el: Add or correct Commentary sections.
 
-1993-03-22  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * abbrev.el, ada.el, add-log.el, array.el, autoinsert.el,
        * autoload.el, awk-mode.el, bib-mode.el, bibtex.el, buff-menu.el,
@@ -1889,19 +1889,19 @@
        * lucid.el: Alias lower-screen and raise-screen to lower-frame and
        raise-frame, the new names for those functions.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * bush.el: Deleted.
 
        * finder.el: Make sure that when new keywords are compiled, we see them
        immediately.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * vt100-led.el, bg-mouse.el, sup-mouse.el, sun-mouse.el:
        Moved to term directory.
 
-1993-03-18  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-18  Eric S. Raymond  (esr@thyrsus.com)
 
        * Makefile: Created.  This exists mainly so developers elsewhere
        can unlock the lisp files to accept an update tar, then relock
@@ -1916,7 +1916,7 @@
 
        * solar.el (solar-time-string): Round the time properly.
 
-1993-03-18  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-18  Eric S. Raymond  (esr@thyrsus.com)
 
        * abbrev.el, abbrevlist.el, add-log.el, apropos.el, array.el,
        * autoload.el, awk-mode.el, cal-french.el, cal-mayan.el,
@@ -1938,7 +1938,7 @@
        * tex-mode.el (tex-send-command): Fix the command sent so that no
        blank is inserted when replacing the asterisk with the file name.
 
-1993-03-18  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-18  Eric S. Raymond  (esr@thyrsus.com)
 
        * term/wyse50.el (function-key-map): Nuke code no longer bound to keys.
 
@@ -1949,7 +1949,7 @@
        Fix things so that bindings are added to the keymap already created by
        terminal initialization.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * help-screen.el: Installed, following release.  Now package
        writers can easily implement help screens resembling Emacs's
@@ -1961,7 +1961,7 @@
 
        * finder-inf.el: Deleted the RCS file.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * isearch.el, lselect.el, select.el, scroll-bar.el, texinfo.el,
        * pending-del.el, profile.el, texinfmt.el, ls-lisp.el, meese.el,
@@ -1974,14 +1974,14 @@
        * case-table.el, byte-run.el, ange-ftp.el, backquote.el:
        Add or correct library header comments.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * finder.el (finder-compile-keywords): Treat nil in a path
        argument as $PWD.
 
        (finder-by-keyword): Handle LFD as input gracefully.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc-hooks.el: Increment version number to match vc.el's.
 
@@ -2017,7 +2017,7 @@
        * loaddefs.el (minor-mode-alist): Make the mode line element for
        overwrite-mode be the symbol `overwrite-mode'.
 
-1993-03-16  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-16  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.el, vc-hooks.el: The macro vc-error-occurred has to move from
        vc.el to vc-hooks.el for C-x C-f of a nonexistent file to work.
@@ -2074,11 +2074,11 @@
        (rmail-summary-rmail-update): Do nothing if rmail buffer not visible.
        (rmail-summary-mode-map): Don't bind C-n, C-p.  Use ordinary move cmds.
 
-1993-03-12  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-12  Eric S. Raymond  (esr@thyrsus.com)
 
        * term/x-win.el: Added library headers.
 
-1993-03-12  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-12  Eric S. Raymond  (esr@thyrsus.com)
 
        * loaddefs.el (global-map): Fix a typo in the binding of
        [kp-backtab].
@@ -2092,7 +2092,7 @@
        * term/x-win.el: Cancel previous change, since it discarded
        earlier necessary changes.
 
-1993-03-11  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-11  Eric S. Raymond  (esr@thyrsus.com)
 
        * term/vt100.el:
        Added headers, commented out code the duplicates startup effects.
@@ -2115,7 +2115,7 @@
        suspend-hooks, not suspend-hook.  The latter is an obsolete name.
        Use add-hook instead of setting suspend-hooks directly.
 
-1993-03-11  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-11  Eric S. Raymond  (esr@thyrsus.com)
 
        A boatload of changes to terminal support and terminal capability
        initialization that make it a lot smarter, with a more uniform
@@ -2197,7 +2197,7 @@
        Likewise their Meta versions.
        Also add `ascii-character' properties.
 
-1993-03-09  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-09  Eric S. Raymond  (esr@thyrsus.com)
 
        * term/at386.el: Removed.  The new terminal initialization stuff
        makes it superfluous.  I wrote it, so I should know. :-)
@@ -3300,7 +3300,7 @@
        (ange-ftp-read-passwd, ange-ftp-process-filter): Uncomment out the
        calls to ange-ftp-repaint-buffer.
 
-1992-11-11  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-11-11  Eric S. Raymond  (esr@thyrsus.com)
 
        * c-mode.el (c-style-alist): Add quotes around C++ style name.
 
@@ -4680,7 +4680,7 @@
        * compile.el (compilation-parse-errors): Write progress messages
        on all regexp matches, not just errors.
 
-1992-08-04  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-08-04  Eric S. Raymond  (esr@thyrsus.com)
 
        * view.el (view-mode): Teach this how to use help-char.
 
@@ -4727,7 +4727,7 @@
 
        * etags.el (complete-tag): Error if no tags table loaded.
 
-1992-08-03  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-08-03  Eric S. Raymond  (esr@thyrsus.com)
 
        * ebuff-menu.el, echistory.el, help.el, hexl.el: Teach these packages
        to use help-char, and add the appropriate magic to doc strings.
@@ -5085,7 +5085,7 @@
 
        * diff.el (diff-rcs, diff-sccs): Delete.
 
-1992-07-27  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * tar-mode.el (tar-subfile-save-buffer): Whoever changed
        current-time forgot to check for breakage.  Added code to print
@@ -5201,7 +5201,7 @@
        * c++-mode.el (indent-c++-exp): Fix typo "innerloop-done".
        Make last-depth local.
 
-1992-07-23  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * flow-ctrl.el: Fixed set-input-mode call broken by new third
        arg for meta control.
@@ -5266,11 +5266,11 @@
        * byte-opt.el (disassemble-offset, byte-decompile-bytecode-1):
        Support for relative jumps removed.
 
-1992-07-22  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-22  Eric S. Raymond  (esr@thyrsus.com)
 
        * Removed all Last-Modified headers.
 
-1992-07-21  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-21  Eric S. Raymond  (esr@thyrsus.com)
 
        * files.el (trim-versions-without-asking): Non-nil, non-t value
        suppresses all trimming of excess backups.  This is so we can make
@@ -5335,7 +5335,7 @@
        Modified the remaining version by adding new argument GLOBAL
        and setting the parameters locally if GLOBAL is nil.
 
-1992-07-21  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-21  Eric S. Raymond  (esr@thyrsus.com)
 
        * Turfed r2bibtex.el.  Refbib.el turns out to be a newer version
        of the same package.
@@ -5484,7 +5484,7 @@
        (find-file-noselect): Don't remove the automount prefix here; let
        abbreviate-file-name take care of it.
 
-1992-07-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * Keywords added for [n-z]*.el.  Finder now under construction.
 
@@ -5495,7 +5495,7 @@
        ending with the latter may be deleted accidentally when space is
        low.
 
-1992-07-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * Keywords added for [a-m]*.el.  The keyword categories will
        probably need some tuning, but at least this will suffice
@@ -5508,7 +5508,7 @@
 
        * Changed all copying notices to GPL version 2.
 
-1992-07-16  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-16  Eric S. Raymond  (esr@thyrsus.com)
 
        * Finished decorating the library files with new standard headers.
 
@@ -5537,14 +5537,14 @@
        * byte-run.el (defsubst): Remove extra closing paren at the end
        of this function.
 
-1992-07-16  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-16  Eric S. Raymond  (esr@thyrsus.com)
 
        * At RMS's request, all occurrences of `elisp' changed to `Emacs Lisp'.
 
        * New library headers for [fghijklmn]*.el.  First steps towards
        keyword-based code finder via Keywords header.
 
-1992-07-15  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-15  Eric S. Raymond  (esr@thyrsus.com)
 
        * New library headers for [opqrst]*.el.  Ghod, this is boring.
 
@@ -5594,7 +5594,7 @@
        (set-frame-height, set-frame-width): Functions deleted; they are
        defined in frame.c.
 
-1992-07-14  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-14  Eric S. Raymond  (esr@thyrsus.com)
 
        * [uvwxy]*.el: Added headers for new Emacs Lisp documentation
        conventions.
@@ -5604,7 +5604,7 @@
        * calendar.el (calendar-mode): Change key bindings for all
        functions to make them consistent with Version 19 requirements.
 
-1992-07-13  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-13  Eric S. Raymond  (esr@thyrsus.com)
 
        * comint.el: Minor changes to comments to reflect the fact that
        comint has won its war and replaced shell mode.
@@ -5750,7 +5750,7 @@
        * etags.el (visit-tags-table): Remove automounter prefixes before
        setting tags-file-name.
 
-1992-07-06  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-07-06  Eric S. Raymond  (esr@thyrsus.com)
 
        * Moved gdb.el to =gdb.el.  The autoload generation for
        loaddefs.el was getting screwed up by the conflicting autoloads
@@ -6157,7 +6157,7 @@
 
        * info.el (Info-enable-edit): Now a user option.
 
-1992-06-03  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-06-03  Eric S. Raymond  (esr@thyrsus.com)
 
        * sendmail.el (mail-signature): Suppress move to end of buffer if
        we gave a prefix argument (requested by Bob Chassell).
@@ -6250,7 +6250,7 @@
 
        * flow-ctrl.el (evade-flow-control-memstr=): Rename from memstr=.
 
-1992-05-31  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-05-31  Eric S. Raymond  (esr@thyrsus.com)
 
        * bibtex.el: Merged in alarson's changes.
 
@@ -6261,7 +6261,7 @@
 
        * subr.el (lambda): Add docstring.
 
-1992-05-31  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-05-31  Eric S. Raymond  (esr@thyrsus.com)
 
        * gdb.el: Nuked --- subsumed by gdb entry point of gud.el.
 
@@ -6275,7 +6275,7 @@
        old version still exists in the ~n~ files if this loses, but
        the code looks good.
 
-1992-05-30  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-05-30  Eric S. Raymond  (esr@thyrsus.com)
 
        * profile.el: Installed.
 
@@ -6715,7 +6715,7 @@
 
        * term/new-at386.el: Rewritten to use function-key-map.
 
-1992-01-10  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1992-01-10  Eric S. Raymond  (esr@thyrsus.com)
 
        * flow-ctrl.el: Installed.
 
@@ -6751,14 +6751,14 @@
        (sendmail-send-it): Delete code for mail-aliases.
        (build-mail-aliases, expand-mail-aliases): Autoloads deleted.
 
-1991-12-14  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1991-12-14  Eric S. Raymond  (esr@thyrsus.com)
 
        * etags.el (find-tag-noselect): Fix subtle bug due to
        save-excursion.
 
        (tags-tag-match): New function, made smarter about exact matches.
 
-1991-12-13  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1991-12-13  Eric S. Raymond  (esr@thyrsus.com)
 
        * perl-mode.el: Installed.
 
@@ -6767,7 +6767,7 @@
        * sendmail.el (mail-default-headers): New user variable.
        (mail-setup): Insert value of that variable.
 
-1991-12-11  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1991-12-11  Eric S. Raymond  (esr@thyrsus.com)
 
        * c-mode.el: Added C++ style to c-style-alist.
 
@@ -6777,7 +6777,7 @@
 
        * man.el (nuke-nroff-bs): Simplify o^H+.  Delete "reformatting" msg.
 
-1991-12-08  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1991-12-08  Eric S. Raymond  (esr@thyrsus.com)
 
        * blackbox.el: Applied doc patch.  No functions affected.
 
@@ -12032,7 +12032,7 @@
 
 1988-12-22  Richard Stallman  (rms@mole.ai.mit.edu)
 
-       * term/at386.el: Eric Raymond's changes to work with keypad.el.
+       * term/at386.el: Eric S. Raymond's changes to work with keypad.el.
 
        * loaddefs.el (completion-ignored-extensions): Add .a and .ln.
 
diff --git a/lisp/ChangeLog.4 b/lisp/ChangeLog.4
index ecadb4a30d5..f0dd1295dd7 100644
--- a/lisp/ChangeLog.4
+++ b/lisp/ChangeLog.4
@@ -3384,7 +3384,7 @@
 
        * font-lock.el (shell-font-lock-keywords): Doc fix.
 
-1994-02-02  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1994-02-02  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc-hooks.el (vc-mode-line): Use force-mode-line-update instead
        of the Emacs 18 kluge.
@@ -3402,7 +3402,7 @@
        * files.el (file-relative-name): Allow for ancestors as well
        as descendants.
 
-1994-02-02  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1994-02-02  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.el (vc-parse-buffer): Arrange for old properties to get
        cleared when their match string is not found in the master file.
@@ -4811,7 +4811,7 @@
        (add-new-page): Insert new page in specified location.
        (original-page-delimiter): Set default value to "^^L".
 
-1993-11-15  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-11-15  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.el: vc-static-header-alist shouldn't have been declared const.
 
@@ -5535,7 +5535,7 @@
        * rmail.el (rmail-convert-to-babyl-format): Protect against
        nonsensical content-length values.
 
-1993-10-04  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-10-04  Eric S. Raymond  (esr@thyrsus.com)
 
        * vc.el (vc-next-action): Fix (throw ... ) invocation to work with 19;
        allows vc-next-action on all marked files in a dired buffer to work.
diff --git a/lisp/ChangeLog.5 b/lisp/ChangeLog.5
index 63cf5db94c4..96bda7650e2 100644
--- a/lisp/ChangeLog.5
+++ b/lisp/ChangeLog.5
@@ -4253,7 +4253,7 @@
        the autogenerated label in the minibuffer caused the killed text
        to appear in front of the bibtex entry.
 
-1995-01-05  Eric S. Raymond  <esr@locke.ccil.org>
+1995-01-05  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-do-command): Change RCS handling so rcsdiff won't strip
        away relative-pathname information.  This function no longer sets the
diff --git a/lisp/ChangeLog.6 b/lisp/ChangeLog.6
index 4e7366c80a8..0fc8ffcf591 100644
--- a/lisp/ChangeLog.6
+++ b/lisp/ChangeLog.6
@@ -7910,7 +7910,7 @@
 
        * paths.el (remote-shell-program): Fix typo checking /usr/bin/remsh.
 
-1995-06-26  Eric S. Raymond  <esr@snark.thyrsus.com>
+1995-06-26  Eric S. Raymond  <esr@thyrsus.com>
 
        * vc.el (vc-start-entry): Prevent lossage when doing a mass checkin
        from a VC-dired buffer.
diff --git a/lisp/ChangeLog.7 b/lisp/ChangeLog.7
index 667cd5e850a..17464042b76 100644
--- a/lisp/ChangeLog.7
+++ b/lisp/ChangeLog.7
@@ -3825,7 +3825,7 @@
 
        * progmodes/perl-mode.el (perl-mode): Add autoload cookie.
 
-1998-04-29  Eric S. Raymond  <esr@snark.thyrsus.com>
+1998-04-29  Eric S. Raymond  <esr@thyrsus.com>
 
        Many small changes that mostly eliminate the explicit mail separator
        variable and use the new rfc822-goto-eoh primitive instead:
@@ -13054,7 +13054,7 @@
        * mail/sendmail.el (mail-mode): Make adaptive-fill-regexp
        match more values.  Bind adaptive-fill-first-line-regexp too.
 
-1997-07-26  Eric S. Raymond  <esr@snark.thyrsus.com>
+1997-07-26  Eric S. Raymond  <esr@thyrsus.com>
 
        * telnet.el (telnet): Handle multiple telnet programs better.
        (telnet-host-properties): New variable.
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 5af2168a827..c4dd1e7a1f3 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -351,11 +351,7 @@ compile-first: $(COMPILE_FIRST)
 # TARGETS is set dynamically in the recursive call from 'compile-main'.
 # Do not build comp.el unless necessary not to exceed max-lisp-eval-depth
 # in normal builds.
-ifneq ($(HAVE_NATIVE_COMP),yes)
-compile-targets: $(filter-out ./emacs-lisp/comp-cstr.elc,$(filter-out 
./emacs-lisp/comp.elc,$(TARGETS)))
-else
 compile-targets: $(TARGETS)
-endif
 
 # Compile all the Elisp files that need it.  Beware: it approximates
 # 'no-byte-compile', so watch out for false-positives!
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index e51fc02724a..66de763f671 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -1958,20 +1958,23 @@ entries for git.gnus.org:
          (hosts (if (and hosts (listp hosts)) hosts `(,hosts)))
          (ports (plist-get spec :port))
          (ports (if (and ports (listp ports)) ports `(,ports)))
+         (users (plist-get spec :user))
+         (users (if (and users (listp users)) users `(,users)))
          ;; Loop through all combinations of host/port and pass each of these 
to
          ;; auth-source-macos-keychain-search-items
          (items (catch 'match
                   (dolist (host hosts)
                     (dolist (port ports)
-                      (let* ((port (if port (format "%S" port)))
-                             (items (apply 
#'auth-source-macos-keychain-search-items
-                                           coll
-                                           type
-                                           max
-                                           host port
-                                           search-spec)))
-                        (when items
-                          (throw 'match items)))))))
+                      (dolist (user users)
+                        (let ((items (apply
+                                      #'auth-source-macos-keychain-search-items
+                                      coll
+                                      type
+                                      max
+                                      host port user
+                                      search-spec)))
+                          (when items
+                            (throw 'match items))))))))
 
          ;; ensure each item has each key in `returned-keys'
          (items (mapcar (lambda (plist)
@@ -2003,8 +2006,9 @@ entries for git.gnus.org:
                      collect var))
      'utf-8)))
 
-(cl-defun auth-source-macos-keychain-search-items (coll _type _max host port
-                                                   &key label type user
+(cl-defun auth-source-macos-keychain-search-items (coll _type _max
+                                                        host port user
+                                                   &key label type
                                                    &allow-other-keys)
   (let* ((keychain-generic (eq type 'macos-keychain-generic))
          (args `(,(if keychain-generic
@@ -2022,47 +2026,49 @@ entries for git.gnus.org:
     (when port
       (if keychain-generic
           (setq args (append args (list "-s" port)))
-        (setq args (append args (list
-                                 (if (string-match "[0-9]+" port) "-P" "-r")
-                                 port)))))
+        (setq args (append args (if (string-match "[0-9]+" port)
+                                    (list "-P" port)
+                                  (list "-r" (substring
+                                              (format "%-4s" port)
+                                              0 4)))))))
 
-      (unless (equal coll "default")
-        (setq args (append args (list coll))))
+    (unless (equal coll "default")
+      (setq args (append args (list coll))))
 
-      (with-temp-buffer
-        (apply #'call-process "/usr/bin/security" nil t nil args)
-        (goto-char (point-min))
-        (while (not (eobp))
-          (cond
-           ((looking-at "^password: \\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"")
-            (setq ret (auth-source-macos-keychain-result-append
-                       ret
-                       keychain-generic
-                       "secret"
-                       (let ((v (auth-source--decode-octal-string
-                                 (match-string 1))))
-                         (lambda () v)))))
-           ;; TODO: check if this is really the label
-           ;; match 0x00000007 <blob>="AppleID"
-           ((looking-at
-             "^[ ]+0x00000007 <blob>=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"")
-            (setq ret (auth-source-macos-keychain-result-append
-                       ret
-                       keychain-generic
-                       "label"
-                       (auth-source--decode-octal-string (match-string 1)))))
-           ;; match "crtr"<uint32>="aapl"
-           ;; match "svce"<blob>="AppleID"
-           ((looking-at
-             "^[ ]+\"\\([a-z]+\\)\"[^=]+=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"")
-            (setq ret (auth-source-macos-keychain-result-append
-                       ret
-                       keychain-generic
-                       (auth-source--decode-octal-string (match-string 1))
-                       (auth-source--decode-octal-string (match-string 2))))))
-          (forward-line)))
-      ;; return `ret' iff it has the :secret key
-      (and (plist-get ret :secret) (list ret))))
+    (with-temp-buffer
+      (apply #'call-process "/usr/bin/security" nil t nil args)
+      (goto-char (point-min))
+      (while (not (eobp))
+        (cond
+         ((looking-at "^password: \\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"")
+          (setq ret (auth-source-macos-keychain-result-append
+                     ret
+                     keychain-generic
+                     "secret"
+                     (let ((v (auth-source--decode-octal-string
+                               (match-string 1))))
+                       (lambda () v)))))
+         ;; TODO: check if this is really the label
+         ;; match 0x00000007 <blob>="AppleID"
+         ((looking-at
+           "^[ ]+0x00000007 <blob>=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"")
+          (setq ret (auth-source-macos-keychain-result-append
+                     ret
+                     keychain-generic
+                     "label"
+                     (auth-source--decode-octal-string (match-string 1)))))
+         ;; match "crtr"<uint32>="aapl"
+         ;; match "svce"<blob>="AppleID"
+         ((looking-at
+           "^[ ]+\"\\([a-z]+\\)\"[^=]+=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"")
+          (setq ret (auth-source-macos-keychain-result-append
+                     ret
+                     keychain-generic
+                     (auth-source--decode-octal-string (match-string 1))
+                     (auth-source--decode-octal-string (match-string 2))))))
+        (forward-line)))
+    ;; return `ret' iff it has the :secret key
+    (and (plist-get ret :secret) (list ret))))
 
 (defun auth-source-macos-keychain-result-append (result generic k v)
   (push v result)
diff --git a/lisp/calendar/cal-move.el b/lisp/calendar/cal-move.el
index 07a813bb705..b494659a8ee 100644
--- a/lisp/calendar/cal-move.el
+++ b/lisp/calendar/cal-move.el
@@ -157,9 +157,9 @@ EVENT is an event like `last-nonmenu-event'."
   (interactive (list (prefix-numeric-value current-prefix-arg)
                      last-nonmenu-event))
   (unless arg (setq arg 1))
-  (save-selected-window
-    ;; Nil if called from menu-bar.
-    (if (setq event (event-start event)) (select-window (posn-window event)))
+  (save-current-buffer
+    (when (event-start event)
+      (set-buffer (calendar-event-buffer event)))
     (calendar-cursor-to-nearest-date)
     (unless (zerop arg)
       (let ((old-date (calendar-cursor-to-date))
diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el
index faa88e7f52f..02167d84b3e 100644
--- a/lisp/calendar/calendar.el
+++ b/lisp/calendar/calendar.el
@@ -1554,6 +1554,15 @@ first INDENT characters on the line."
       (when (window-live-p (get-buffer-window))
         (set-window-point (get-buffer-window) (point))))))
 
+(defun calendar-event-buffer (event)
+  "Return the Calendar buffer where EVENT happened.
+If EVENT's start falls within a window, use that window's buffer.
+Otherwise, use the selected window of EVENT's frame."
+  (let ((window-or-frame (posn-window (event-start event))))
+    (if (windowp window-or-frame)
+        (window-buffer window-or-frame)
+      (window-buffer (frame-selected-window window-or-frame)))))
+
 (defvar calendar-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map)
@@ -1916,10 +1925,13 @@ parameter ERROR is non-nil, otherwise just returns nil.
 If EVENT is non-nil, it's an event indicating the buffer position to
 use instead of point."
   (with-current-buffer
-      (if event (window-buffer (posn-window (event-start event)))
+      (if event (calendar-event-buffer event)
         (current-buffer))
     (save-excursion
       (and event (setq event (event-start event))
+           ;; (posn-point event) can be `menu-bar' if this command is
+           ;; invoked from the menu bar.
+           (integerp (posn-point event))
            (goto-char (posn-point event)))
       (let* ((segment (calendar-column-to-segment))
              (month (% (+ displayed-month (1- segment)) 12)))
@@ -2002,10 +2014,8 @@ handle dates in years BC."
 EVENT is an event like `last-nonmenu-event'."
   (interactive (let ((event (list last-nonmenu-event)))
                  (append (calendar-read-date 'noday) event)))
-  (save-selected-window
-    (and event
-         (setq event (event-start event))
-         (select-window (posn-window event)))
+  (with-current-buffer (or (and (not event) (current-buffer))
+                           (calendar-event-buffer event))
     (unless (and (= month displayed-month)
                  (= year displayed-year))
       (let ((old-date (calendar-cursor-to-date))
diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el
index f30c5653c11..a65beca0e5b 100644
--- a/lisp/calendar/holidays.el
+++ b/lisp/calendar/holidays.el
@@ -359,7 +359,7 @@ use instead of point."
   (interactive (list last-nonmenu-event))
   ;; If called from a menu, with the calendar window not selected.
   (with-current-buffer
-      (if event (window-buffer (posn-window (event-start event)))
+      (if event (calendar-event-buffer event)
         (current-buffer))
     (message "Looking up holidays...")
     (let ((holiday-list (calendar-holiday-list))
@@ -590,7 +590,7 @@ use instead of point."
   (interactive (list last-nonmenu-event))
   ;; If called from a menu, with the calendar window not selected.
   (with-current-buffer
-      (if event (window-buffer (posn-window (event-start event)))
+      (if event (calendar-event-buffer event)
         (current-buffer))
     (setq calendar-mark-holidays-flag t)
     (message "Marking holidays...")
diff --git a/lisp/calendar/lunar.el b/lisp/calendar/lunar.el
index 5b22043102d..a9c3597a3f9 100644
--- a/lisp/calendar/lunar.el
+++ b/lisp/calendar/lunar.el
@@ -226,7 +226,7 @@ use instead of point."
   (interactive (list last-nonmenu-event))
   ;; If called from a menu, with the calendar window not selected.
   (with-current-buffer
-      (if event (window-buffer (posn-window (event-start event)))
+      (if event (calendar-event-buffer event)
         (current-buffer))
     (message "Computing phases of the moon...")
     (let ((m1 displayed-month)
diff --git a/lisp/comint.el b/lisp/comint.el
index 5161d01515c..777795bcb46 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -1440,7 +1440,7 @@ actual side-effect."
                (if dry-run (throw dry-run 'message))
               (goto-char (match-end 0))
               (message "Absolute reference cannot be expanded"))
-             ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?")
+             ((looking-at "!-\\([0-9]+\\):?\\([0-9^$*-]+\\)?")
               ;; Just a number of args from `number' lines backward.
                (if dry-run (throw dry-run 'history))
               (let ((number (1- (string-to-number
@@ -1464,7 +1464,7 @@ actual side-effect."
                              t t)
               (message "History item: previous"))
              ((looking-at
-               "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
+               "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\):?\\([0-9^$*-]+\\)?")
               ;; Most recent input starting with or containing (possibly
               ;; protected) string, maybe just a number of args.  Phew.
                (if dry-run (throw dry-run 'expand))
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index f5143bdb53f..9b73a72b238 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -3751,7 +3751,7 @@ WIDGET should be a `custom-face' widget."
     ;; If the user has changed this face in some other way,
     ;; edit it as the user has specified it.
     (if (not (face-spec-match-p face spec (selected-frame)))
-       (setq spec `((t ,(face-attr-construct face (selected-frame))))))
+        (setq spec `((t ,(face-attr-construct face)))))
     spec))
 
 (defun custom-face-get-current-spec (face)
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 3e8b4c3c8fc..28513a2c61a 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -2480,87 +2480,97 @@ Optional arg HOW-TO determines how to treat the target.
 
    For any other return value, TARGET is treated as a directory."
   (or op1 (setq op1 operation))
-  (let* ((fn-list (dired-get-marked-files nil arg nil nil t))
-        (rfn-list (mapcar #'dired-make-relative fn-list))
-        (dired-one-file        ; fluid variable inside dired-create-files
-         (and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
-        (target-dir (dired-dwim-target-directory))
-        (default (and dired-one-file
-                      (not dired-dwim-target) ; Bug#25609
-                      (expand-file-name (file-name-nondirectory (car fn-list))
-                                        target-dir)))
-        (defaults (dired-dwim-target-defaults fn-list target-dir))
-        (target (expand-file-name ; fluid variable inside dired-create-files
-                 (minibuffer-with-setup-hook
-                     (lambda ()
-                        (setq-local minibuffer-default-add-function nil)
-                       (setq minibuffer-default defaults))
-                   (dired-mark-read-file-name
-                     (format "%s %%s %s: "
-                             (if dired-one-file op1 operation)
-                             (if (memq op-symbol '(symlink hardlink))
-                                 ;; Linking operations create links
-                                 ;; from the prompted file name; the
-                                 ;; other operations copy (etc) to the
-                                 ;; prompted file name.
-                                 "from" "to"))
-                    target-dir op-symbol arg rfn-list default))))
-        (into-dir
-          (progn
-            (when
-                (or
-                 (not dired-one-file)
-                 (and dired-create-destination-dirs-on-trailing-dirsep
-                      (directory-name-p target)))
-              (dired-maybe-create-dirs target))
-            (cond ((null how-to)
-                  ;; Allow users to change the letter case of
-                  ;; a directory on a case-insensitive
-                  ;; filesystem.  If we don't test these
-                  ;; conditions up front, file-directory-p
-                  ;; below will return t on a case-insensitive
-                  ;; filesystem, and Emacs will try to move
-                  ;; foo -> foo/foo, which fails.
-                  (if (and (file-name-case-insensitive-p (car fn-list))
-                           (eq op-symbol 'move)
-                           dired-one-file
-                           (string= (downcase
-                                     (expand-file-name (car fn-list)))
-                                    (downcase
-                                     (expand-file-name target)))
-                           (not (string=
-                                 (file-name-nondirectory (car fn-list))
-                                 (file-name-nondirectory target))))
-                      nil
-                    (file-directory-p target)))
-                 ((eq how-to t) nil)
-                 (t (funcall how-to target))))))
-    (if (and (consp into-dir) (functionp (car into-dir)))
-       (apply (car into-dir) operation rfn-list fn-list target (cdr into-dir))
-      (if (not (or dired-one-file into-dir))
-         (error "Marked %s: target must be a directory: %s" operation target))
-      (if (and (not (file-directory-p (car fn-list)))
-               (not (file-directory-p target))
-               (directory-name-p target))
-          (error "%s: Target directory does not exist: %s" operation target))
-      ;; rename-file bombs when moving directories unless we do this:
-      (or into-dir (setq target (directory-file-name target)))
-      (prog1
-          (dired-create-files
-           file-creator operation fn-list
-           (if into-dir                        ; target is a directory
-              ;; This function uses fluid variable target when called
-              ;; inside dired-create-files:
-              (lambda (from)
-                (expand-file-name (file-name-nondirectory from) target))
-            (lambda (_from) target))
-           marker-char)
-        (when (or (eq dired-do-revert-buffer t)
-                  (and (functionp dired-do-revert-buffer)
-                       (funcall dired-do-revert-buffer target)))
-          (dired-fun-in-all-buffers (file-name-directory target) nil
-                                    #'revert-buffer)))))
-  (dired-post-do-command))
+  (let ((ret nil))
+    (let* ((fn-list (dired-get-marked-files nil arg nil nil t))
+          (rfn-list (mapcar #'dired-make-relative fn-list))
+          (dired-one-file      ; fluid variable inside dired-create-files
+           (and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
+          (target-dir (dired-dwim-target-directory))
+          (default (and dired-one-file
+                        (not dired-dwim-target) ; Bug#25609
+                        (expand-file-name (file-name-nondirectory
+                                            (car fn-list))
+                                          target-dir)))
+          (defaults (dired-dwim-target-defaults fn-list target-dir))
+          (target (expand-file-name ; fluid variable inside dired-create-files
+                   (minibuffer-with-setup-hook
+                       (lambda ()
+                          (setq-local minibuffer-default-add-function nil)
+                         (setq minibuffer-default defaults))
+                     (dired-mark-read-file-name
+                       (format "%s %%s %s: "
+                               (if dired-one-file op1 operation)
+                               (if (memq op-symbol '(symlink hardlink))
+                                   ;; Linking operations create links
+                                   ;; from the prompted file name; the
+                                   ;; other operations copy (etc) to the
+                                   ;; prompted file name.
+                                   "from" "to"))
+                      target-dir op-symbol arg rfn-list default))))
+          (into-dir
+            (progn
+              (when
+                  (or
+                   (not dired-one-file)
+                   (and dired-create-destination-dirs-on-trailing-dirsep
+                        (directory-name-p target)))
+                (dired-maybe-create-dirs target))
+              (cond ((null how-to)
+                    ;; Allow users to change the letter case of
+                    ;; a directory on a case-insensitive
+                    ;; filesystem.  If we don't test these
+                    ;; conditions up front, file-directory-p
+                    ;; below will return t on a case-insensitive
+                    ;; filesystem, and Emacs will try to move
+                    ;; foo -> foo/foo, which fails.
+                    (if (and (file-name-case-insensitive-p (car fn-list))
+                             (eq op-symbol 'move)
+                             dired-one-file
+                             (string= (downcase
+                                       (expand-file-name (car fn-list)))
+                                      (downcase
+                                       (expand-file-name target)))
+                             (not (string=
+                                   (file-name-nondirectory (car fn-list))
+                                   (file-name-nondirectory target))))
+                        nil
+                      (file-directory-p target)))
+                   ((eq how-to t) nil)
+                   (t (funcall how-to target))))))
+      (setq ret
+            (if (and (consp into-dir) (functionp (car into-dir)))
+               (apply (car into-dir) operation rfn-list fn-list target
+                       (cdr into-dir))
+              (if (not (or dired-one-file into-dir))
+                 (error "Marked %s: target must be a directory: %s"
+                         operation target))
+              (if (and (not (file-directory-p (car fn-list)))
+                       (not (file-directory-p target))
+                       (directory-name-p target))
+                  (error "%s: Target directory does not exist: %s"
+                         operation target))
+              ;; rename-file bombs when moving directories unless we do this:
+              (or into-dir (setq target (directory-file-name target)))
+              (prog1
+                  (dired-create-files
+                   file-creator operation fn-list
+                   (if into-dir                        ; target is a directory
+                      ;; This function uses fluid variable target when called
+                      ;; inside dired-create-files:
+                      (lambda (from)
+                        (expand-file-name (file-name-nondirectory from)
+                                           target))
+                    (lambda (_from) target))
+                   marker-char)
+                (when (or (eq dired-do-revert-buffer t)
+                          (and (functionp dired-do-revert-buffer)
+                               (funcall dired-do-revert-buffer target)))
+                  (dired-fun-in-all-buffers (file-name-directory target) nil
+                                            #'revert-buffer))))))
+    (dired-post-do-command)
+    ;; The return value isn't very well defined but is used by
+    ;; `dired-test-bug30624'.
+    ret))
 
 ;; Read arguments for a marked-files command that wants a file name,
 ;; perhaps popping up the list of marked files.
diff --git a/lisp/dired.el b/lisp/dired.el
index 255d79fa42c..27172c50a9f 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -218,14 +218,19 @@ If t, they are marked if and as the files linked to were 
marked.
 If a character, new links are unconditionally marked with that character.")
 
 (defcustom dired-free-space 'first
-  "Whether and how to display the amount of free disk space in Dired buffers.
+  "Whether and how to display the disk space usage info in Dired buffers.
 If nil, don't display.
-If `separate', display on a separate line (along with used count).
-If `first', display only the free disk space on the first line,
-following the directory name."
-  :type '(choice (const :tag "On a separate line" separate)
-                 (const :tag "On the first line, after directory name" first)
-                 (const :tag "Don't display" nil))
+If `separate', display on a separate line, and include both the used
+and the free disk space.
+If `first', the default, display only the free disk space on the first
+line, following the directory name."
+  :type '(choice (const
+                  :tag
+                  "On separate line, display both used and free space" 
separate)
+                 (const
+                  :tag
+                  "On first line, after directory name, display only free 
space" first)
+                 (const :tag "Don't display disk space usage" nil))
   :version "29.1"
   :group 'dired)
 
@@ -577,9 +582,6 @@ element, for the listed directory.")
   "Keeps track of which switches to use for inserted subdirectories.
 This is an alist of the form (SUBDIR . SWITCHES).")
 
-(defvaralias 'dired-move-to-filename-regexp
-  'directory-listing-before-filename-regexp)
-
 (defvar dired-subdir-regexp "^. \\(.+\\)\\(:\\)\n"
   "Regexp matching a maybe hidden subdirectory line in `ls -lR' output.
 Subexpression 1 is the subdirectory proper, no trailing colon.
@@ -1773,7 +1775,10 @@ see `dired-use-ls-dired' for more details.")
          ((eq dired-free-space 'separate)
          (end-of-line)
          (insert " available " available)
-          (forward-line 1)
+          ;; The separate free-space line is considered part of the
+          ;; directory content, for the purposes of
+          ;; 'dired-hide-details-mode'.
+          (beginning-of-line)
           (point))
          ((eq dired-free-space 'first)
           (goto-char beg)
@@ -5040,6 +5045,9 @@ completes."
   ;; Redisplay the tool bar.
   (force-mode-line-update))
 
+(define-obsolete-variable-alias 'dired-move-to-filename-regexp
+  'directory-listing-before-filename-regexp "30.1")
+
 (provide 'dired)
 
 (run-hooks 'dired-load-hook)           ; for your customizations
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index c7edbd6e150..e25e63a97ee 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -703,7 +703,7 @@ Typically \"page-%s.png\".")
                                    map doc-view-mode-map :vert-only t
                                    :enable '(< (doc-view-current-page)
                                                (doc-view-last-page-number))
-                                   :help "Move to the next page.")
+                                   :help "Move to the last page.")
     map)
   "Like the default `tool-bar-map', but with additions for DocView.")
 
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 12c2bc51b92..ecc5fff3b67 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1052,23 +1052,26 @@ See Info node `(elisp) Integer Basics'."
   (and (integerp o) (<= -536870912 o 536870911)))
 
 (defun byte-optimize-equal (form)
-  ;; Replace `equal' or `eql' with `eq' if at least one arg is a
-  ;; symbol or fixnum.
-  (byte-optimize-binary-predicate
-   (if (= (length (cdr form)) 2)
-       (if (or (byte-optimize--constant-symbol-p (nth 1 form))
-               (byte-optimize--constant-symbol-p (nth 2 form))
-               (byte-optimize--fixnump (nth 1 form))
-               (byte-optimize--fixnump (nth 2 form)))
-           (cons 'eq (cdr form))
-         form)
-     ;; Arity errors reported elsewhere.
-     form)))
+  (cond ((/= (length (cdr form)) 2) form)  ; Arity errors reported elsewhere.
+        ;; Anything is identical to itself.
+        ((and (eq (nth 1 form) (nth 2 form)) (symbolp (nth 1 form))) t)
+        ;; Replace `equal' or `eql' with `eq' if at least one arg is a
+        ;; symbol or fixnum.
+        ((or (byte-optimize--constant-symbol-p (nth 1 form))
+             (byte-optimize--constant-symbol-p (nth 2 form))
+             (byte-optimize--fixnump (nth 1 form))
+             (byte-optimize--fixnump (nth 2 form)))
+         (byte-optimize-binary-predicate (cons 'eq (cdr form))))
+        (t (byte-optimize-binary-predicate form))))
 
 (defun byte-optimize-eq (form)
-  (pcase (cdr form)
-    ((or `(,x nil) `(nil ,x)) `(not ,x))
-    (_ (byte-optimize-binary-predicate form))))
+  (cond ((/= (length (cdr form)) 2) form)  ; arity error
+        ;; Anything is identical to itself.
+        ((and (eq (nth 1 form) (nth 2 form)) (symbolp (nth 1 form))) t)
+        ;; Strength-reduce comparison with `nil'.
+        ((null (nth 1 form)) `(not ,(nth 2 form)))
+        ((null (nth 2 form)) `(not ,(nth 1 form)))
+        (t (byte-optimize-binary-predicate form))))
 
 (defun byte-optimize-member (form)
   (cond
@@ -1741,6 +1744,7 @@ See Info node `(elisp) Integer Basics'."
          base64-decode-string base64-encode-string base64url-encode-string
          buffer-hash buffer-line-statistics
          compare-strings concat copy-alist copy-hash-table copy-sequence elt
+         equal equal-including-properties
          featurep get
          gethash hash-table-count hash-table-rehash-size
          hash-table-rehash-threshold hash-table-size hash-table-test
@@ -1874,7 +1878,7 @@ See Info node `(elisp) Integer Basics'."
          ;; fileio.c
          default-file-modes
          ;; fns.c
-         eql equal equal-including-properties
+         eql
          hash-table-p identity proper-list-p safe-length
          secure-hash-algorithms
          ;; frame.c
@@ -2158,7 +2162,7 @@ See Info node `(elisp) Integer Basics'."
 
 (defconst byte-compile-side-effect-and-error-free-ops
   '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp
-    byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe
+    byte-integerp byte-numberp byte-eq byte-not byte-car-safe
     byte-cdr-safe byte-cons byte-list1 byte-list2 byte-list3 byte-list4
     byte-listN byte-point byte-point-max
     byte-point-min byte-following-char byte-preceding-char
@@ -2169,10 +2173,11 @@ See Info node `(elisp) Integer Basics'."
   (append
    '(byte-varref byte-nth byte-memq byte-car byte-cdr byte-length byte-aref
      byte-symbol-value byte-get byte-concat2 byte-concat3 byte-sub1 byte-add1
-     byte-eqlsign byte-gtr byte-lss byte-leq byte-geq byte-diff byte-negate
-     byte-plus byte-max byte-min byte-mult byte-char-after byte-char-syntax
-     byte-buffer-substring byte-string= byte-string< byte-nthcdr byte-elt
-     byte-member byte-assq byte-quo byte-rem byte-substring)
+     byte-eqlsign byte-equal byte-gtr byte-lss byte-leq byte-geq byte-diff
+     byte-negate byte-plus byte-max byte-min byte-mult byte-char-after
+     byte-char-syntax byte-buffer-substring byte-string= byte-string<
+     byte-nthcdr byte-elt byte-member byte-assq byte-quo byte-rem
+     byte-substring)
    byte-compile-side-effect-and-error-free-ops))
 
 ;; This crock is because of the way DEFVAR_BOOL variables work.
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index baa3e6b57ce..85dd6bedc41 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -489,8 +489,7 @@ Return the compile-time value of FORM."
   ;; 3.2.3.1, "Processing of Top Level Forms".  The semantics are very
   ;; subtle: see test/lisp/emacs-lisp/bytecomp-tests.el for interesting
   ;; cases.
-  (let ((print-symbols-bare t))         ; Possibly redundant binding.
-    (setf form (macroexp-macroexpand form byte-compile-macro-environment)))
+  (setf form (macroexp-macroexpand form byte-compile-macro-environment))
   (if (eq (car-safe form) 'progn)
       (cons (car form)
             (mapcar (lambda (subform)
@@ -568,11 +567,10 @@ Only conses are traversed and duplicated, not arrays or 
any other structure."
                               ;; Don't compile here, since we don't know
                               ;; whether to compile as byte-compile-form
                               ;; or byte-compile-file-form.
-                              (let* ((print-symbols-bare t) ; Possibly 
redundant binding.
-                                     (expanded
-                                      (macroexpand--all-toplevel
-                                       form
-                                       macroexpand-all-environment)))
+                              (let ((expanded
+                                     (macroexpand--all-toplevel
+                                      form
+                                      macroexpand-all-environment)))
                                 (eval (byte-run-strip-symbol-positions
                                        (bytecomp--copy-tree expanded))
                                       lexical-binding)
@@ -2491,8 +2489,7 @@ Call from the source buffer."
     ;; Spill output for the native compiler here
     (push (make-byte-to-native-top-level :form form :lexical lexical-binding)
           byte-to-native-top-level-forms))
-  (let ((print-symbols-bare t)          ; Possibly redundant binding.
-        (print-escape-newlines t)
+  (let ((print-escape-newlines t)
         (print-length nil)
         (print-level nil)
         (print-quoted t)
@@ -2526,8 +2523,7 @@ list that represents a doc string reference.
   ;; in the input buffer (now current), not in the output buffer.
   (let ((dynamic-docstrings byte-compile-dynamic-docstrings))
     (with-current-buffer byte-compile--outbuffer
-      (let (position
-            (print-symbols-bare t))     ; Possibly redundant binding.
+      (let (position)
         ;; Insert the doc string, and make it a comment with #@LENGTH.
         (when (and (>= (nth 1 info) 0) dynamic-docstrings)
           (setq position (byte-compile-output-as-comment
@@ -2623,8 +2619,7 @@ list that represents a doc string reference.
               byte-compile-jump-tables nil))))
 
 (defun byte-compile-preprocess (form &optional _for-effect)
-  (let ((print-symbols-bare t))         ; Possibly redundant binding.
-    (setq form (macroexpand-all form byte-compile-macro-environment)))
+  (setq form (macroexpand-all form byte-compile-macro-environment))
   ;; FIXME: We should run byte-optimize-form here, but it currently does not
   ;; recurse through all the code, so we'd have to fix this first.
   ;; Maybe a good fix would be to merge byte-optimize-form into
@@ -5784,6 +5779,74 @@ and corresponding effects."
       form    ; arity error
     `(forward-word (- (or ,arg 1)))))
 
+(defun bytecomp--check-keyword-args (form arglist allowed-keys required-keys)
+  (let ((fun (car form)))
+    (cl-flet ((missing (form keyword)
+               (byte-compile-warn-x
+                form
+                "`%S´ called without required keyword argument %S"
+                fun keyword))
+             (unrecognized (form keyword)
+               (byte-compile-warn-x
+                form
+                "`%S´ called with unknown keyword argument %S"
+                fun keyword))
+             (duplicate (form keyword)
+               (byte-compile-warn-x
+                form
+                "`%S´ called with repeated keyword argument %S"
+                fun keyword))
+              (missing-val (form keyword)
+               (byte-compile-warn-x
+                form
+                "missing value for keyword argument %S"
+                keyword)))
+      (let* ((seen '())
+            (l arglist))
+       (while (consp l)
+         (let ((key (car l)))
+           (cond ((and (keywordp key) (memq key allowed-keys))
+                  (cond ((memq key seen)
+                         (duplicate l key))
+                        (t
+                         (push key seen))))
+                 (t (unrecognized l key)))
+            (when (null (cdr l))
+              (missing-val l key)))
+         (setq l (cddr l)))
+        (dolist (key required-keys)
+         (unless (memq key seen)
+           (missing form key))))))
+  form)
+
+(put 'make-process 'compiler-macro
+     #'(lambda (form &rest args)
+         (bytecomp--check-keyword-args
+          form args
+          '(:name
+            :buffer :command :coding :noquery :stop :connection-type
+            :filter :sentinel :stderr :file-handler)
+          '(:name :command))))
+
+(put 'make-pipe-process 'compiler-macro
+     #'(lambda (form &rest args)
+         (bytecomp--check-keyword-args
+          form args
+          '(:name :buffer :coding :noquery :stop :filter :sentinel)
+          '(:name))))
+
+(put 'make-network-process 'compiler-macro
+     #'(lambda (form &rest args)
+         (bytecomp--check-keyword-args
+          form args
+          '(:name
+            :buffer :host :service :type :family :local :remote :coding
+            :nowait :noquery :stop :filter :filter-multibyte :sentinel
+            :log :plist :tls-parameters :server :broadcast :dontroute
+            :keepalive :linger :oobinline :priority :reuseaddr :bindtodevice
+            :use-external-socket)
+          '(:name :service))))
+
 (provide 'byte-compile)
 (provide 'bytecomp)
 
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index b062c280a41..dec14bd5df6 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -1101,10 +1101,10 @@ MET-NAME is as returned by 
`cl--generic-load-hist-format'."
          (qualifiers   (cl--generic-method-qualifiers method))
          (call-con     (cl--generic-method-call-con method))
          (function     (cl--generic-method-function method))
-         (args (help-function-arglist (if (not (eq call-con 'curried))
-                                          function
-                                        (funcall function #'ignore))
-                                      'names))
+         (function (if (not (eq call-con 'curried))
+                              function
+                            (funcall function #'ignore)))
+         (args (help-function-arglist function 'names))
          (docstring (documentation function))
          (qual-string
           (if (null qualifiers) ""
diff --git a/lisp/emacs-lisp/cl-indent.el b/lisp/emacs-lisp/cl-indent.el
index 8920579755e..ee50f572157 100644
--- a/lisp/emacs-lisp/cl-indent.el
+++ b/lisp/emacs-lisp/cl-indent.el
@@ -192,7 +192,7 @@ the standard Lisp indent package."
     (list
      (cond ((not (lisp-extended-loop-p (elt state 1)))
            (+ loop-indentation lisp-simple-loop-indentation))
-          ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)")
+          ((looking-at "^\\s-*\\(?::?\\sw+\\|;\\)")
            (+ loop-indentation lisp-loop-keyword-indentation))
           (t
            (+ loop-indentation lisp-loop-forms-indentation)))
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 0a3181561bd..4cc43995c12 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -389,7 +389,7 @@ more details.
 \(fn NAME ARGLIST [DOCSTRING] BODY...)"
   (declare (debug
             ;; Same as defun but use cl-lambda-list.
-            (&define [&name sexp]   ;Allow (setf ...) additionally to symbols.
+            (&define [&name symbolp]
                      cl-lambda-list
                      cl-declarations-or-string
                      [&optional ("interactive" interactive)]
@@ -2037,7 +2037,16 @@ a `let' form, except that the list of symbols can be 
computed at run-time."
    ;; *after* handling `function', but we want to stop macroexpansion from
    ;; being applied infinitely, so we use a cache to return the exact `form'
    ;; being expanded even though we don't receive it.
-   ((eq f (car cl--labels-convert-cache)) (cdr cl--labels-convert-cache))
+   ;; In Common Lisp, we'd use the `&whole' arg instead (see
+   ;; "Macro Lambda Lists" in the CLHS).
+   ((let ((symbols-with-pos-enabled nil)) ;Don't rewrite #'<X@5> => #'<X@3>
+      (eq f (car cl--labels-convert-cache)))
+    ;; This value should be `eq' to the `&whole' form.
+    ;; If this is not the case, we have a bug.
+    (prog1 (cdr cl--labels-convert-cache)
+      ;; Drop it, so it can't accidentally interfere with some
+      ;; unrelated subsequent use of `function' with the same symbol.
+      (setq cl--labels-convert-cache nil)))
    (t
     (let* ((found (assq f macroexpand-all-environment))
            (replacement (and found
@@ -2045,6 +2054,8 @@ a `let' form, except that the list of symbols can be 
computed at run-time."
                                (funcall (cdr found) cl--labels-magic)))))
       (if (and replacement (eq cl--labels-magic (car replacement)))
           (nth 1 replacement)
+        ;; FIXME: Here, we'd like to return the `&whole' form, but since ELisp
+        ;; doesn't have that, we approximate it via `cl--labels-convert-cache'.
         (let ((res `(function ,f)))
           (setq cl--labels-convert-cache (cons f res))
           res))))))
@@ -2064,13 +2075,15 @@ info node `(cl) Function Bindings' for details.
 
 \(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
   (declare (indent 1)
-           (debug ((&rest [&or (symbolp form)
-                               (&define [&name symbolp "@cl-flet@"]
+           (debug ((&rest [&or (&define [&name symbolp "@cl-flet@"]
                                         [&name [] gensym] ;Make it unique!
                                         cl-lambda-list
                                         cl-declarations-or-string
                                         [&optional ("interactive" interactive)]
-                                        def-body)])
+                                        def-body)
+                               (&define [&name symbolp "@cl-flet@"]
+                                        [&name [] gensym] ;Make it unique!
+                                        def-form)])
                    cl-declarations body)))
   (let ((binds ()) (newenv macroexpand-all-environment))
     (dolist (binding bindings)
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index b35e1b97e9d..ad0077dadda 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -39,6 +39,23 @@
 (require 'warnings)
 (require 'comp-cstr)
 
+;; These variables and functions are defined in comp.c
+(defvar native-comp-enable-subr-trampolines)
+(defvar comp-installed-trampolines-h)
+(defvar comp-subr-arities-h)
+(defvar native-comp-eln-load-path)
+(defvar comp-native-version-dir)
+(defvar comp-deferred-pending-h)
+(defvar comp--no-native-compile)
+
+(declare-function comp-el-to-eln-rel-filename "comp.c")
+(declare-function native-elisp-load "comp.c")
+(declare-function comp--release-ctxt "comp.c")
+(declare-function comp--init-ctxt "comp.c")
+(declare-function comp--compile-ctxt-to-file "comp.c")
+(declare-function comp-el-to-eln-filename "comp.c")
+(declare-function comp--install-trampoline "comp.c")
+
 (defgroup comp nil
   "Emacs Lisp native compiler."
   :group 'lisp)
@@ -1431,11 +1448,8 @@ clashes."
   (unless byte-to-native-top-level-forms
     (signal 'native-compiler-error-empty-byte (list filename)))
   (unless (comp-ctxt-output comp-ctxt)
-    (setf (comp-ctxt-output comp-ctxt) (comp-el-to-eln-filename
-                                        filename
-                                        (or native-compile-target-directory
-                                            (when byte+native-compile
-                                              (car (last 
native-comp-eln-load-path)))))))
+    (setf (comp-ctxt-output comp-ctxt)
+          (comp-el-to-eln-filename filename native-compile-target-directory)))
   (setf (comp-ctxt-speed comp-ctxt) (alist-get 'native-comp-speed
                                                byte-native-qualities)
         (comp-ctxt-debug comp-ctxt) (alist-get 'native-comp-debug
@@ -4374,8 +4388,9 @@ last directory in `native-comp-eln-load-path')."
   (comp-ensure-native-compiler)
   (let ((comp-running-batch-compilation t)
         (native-compile-target-directory
-            (if for-tarball
-                (car (last native-comp-eln-load-path)))))
+         (if for-tarball
+             (car (last native-comp-eln-load-path))
+           native-compile-target-directory)))
     (cl-loop for file in command-line-args-left
              if (or (null byte+native-compile)
                     (cl-notany (lambda (re) (string-match re file))
@@ -4417,6 +4432,8 @@ variable \"NATIVE_DISABLED\" is set, only byte compile."
       (batch-byte-compile)
     (cl-assert (length= command-line-args-left 1))
     (let* ((byte+native-compile t)
+           (native-compile-target-directory
+            (car (last native-comp-eln-load-path)))
            (byte-to-native-output-buffer-file nil)
            (eln-file (car (batch-native-compile))))
       (comp-write-bytecode-file eln-file)
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index be9f013ebcf..4ea894f4ede 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -237,7 +237,9 @@ in batch mode, an error is signaled.
                             `(:expected-result-type ,expected-result))
                         ,@(when tags-supplied-p
                             `(:tags ,tags))
-                        :body (lambda () ,@body)
+                        ;; Add `nil' after the body to enable compiler warnings
+                        ;; about unused computations at the end.
+                        :body (lambda () ,@body nil)
                         :file-name ,(or (macroexp-file-name) 
buffer-file-name)))
          ',name))))
 
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index bf890fc35a9..d393ccc759a 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -591,7 +591,7 @@ otherwise uses `variable-at-point'."
     (list (intern (completing-read
                    (format-prompt "Find %s" symb prompt-type)
                    obarray predicate
-                   t nil nil (and symb (symbol-name symb)))))))
+                   'lambda nil nil (and symb (symbol-name symb)))))))
 
 (defun find-function-do-it (symbol type switch-fn)
   "Find Emacs Lisp SYMBOL in a buffer and display it.
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index 67c9db29b7f..cb7cff43555 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1992-2023 Free Software Foundation, Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Created: 14 Jul 1992
 ;; Keywords: docs
@@ -67,7 +67,7 @@
 ;; ;;  Noah Friedman <friedman@ai.mit.edu>
 ;; ;;  Joe Wells <jbw@maverick.uswest.com>
 ;; ;;  Dave Brennan <brennan@hal.com>
-;; ;;  Eric Raymond <esr@snark.thyrsus.com>
+;; ;;  Eric S. Raymond <esr@thyrsus.com>
 ;;
 ;;    * Maintainer line --- should be a single name/address as in the Author
 ;; line, or an address only.  If there is no maintainer
@@ -519,6 +519,7 @@ says display \"OK\" in temp buffer for files that have no 
problems.
 Optional argument VERBOSE specifies verbosity level.
 Optional argument NON-FSF-OK if non-nil means a non-FSF
 copyright notice is allowed."
+  ;; FIXME: Make obsolete in favor of checkdoc?
   (interactive (list nil nil t))
   (let* ((ret (and verbose "Ok"))
         name)
@@ -562,9 +563,8 @@ copyright notice is allowed."
                  (goto-char (point-max))
                  (not
                   (re-search-backward
-                   (concat "^;;;[ \t]+" name "[ \t]+ends here[ \t]*$"
-                           "\\|^;;;[ \t]+ End of file[ \t]+" name)
-                   nil t)))
+                    (rx bol ";;; " (regexp name) " ends here")
+                    nil t)))
                "Can't find the footer line")
               ((not (and (lm-copyright-mark) (lm-crack-copyright)))
                "Can't find a valid copyright notice")
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index ac89697e966..6d5cf8723f9 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -107,8 +107,7 @@ each clause."
 
 (defun macroexp--compiler-macro (handler form)
   (condition-case-unless-debug err
-      (let ((symbols-with-pos-enabled t))
-        (apply handler form (cdr form)))
+      (apply handler form (cdr form))
     (error
      (message "Warning: Optimization failure for %S: Handler: %S\n%S"
               (car form) handler err)
@@ -760,40 +759,38 @@ test of free variables in the following ways:
 
 (defun internal-macroexpand-for-load (form full-p)
   ;; Called from the eager-macroexpansion in readevalloop.
-  (let ((symbols-with-pos-enabled t)
-        (print-symbols-bare t))
-    (cond
-     ;; Don't repeat the same warning for every top-level element.
-     ((eq 'skip (car macroexp--pending-eager-loads)) form)
-     ;; If we detect a cycle, skip macro-expansion for now, and output a 
warning
-     ;; with a trimmed backtrace.
-     ((and load-file-name (member load-file-name 
macroexp--pending-eager-loads))
-      (let* ((bt (delq nil
-                       (mapcar #'macroexp--trim-backtrace-frame
-                               (macroexp--backtrace))))
-             (elem `(load ,(file-name-nondirectory load-file-name)))
-             (tail (member elem (cdr (member elem bt)))))
-        (if tail (setcdr tail (list '…)))
-        (if (eq (car-safe (car bt)) 'macroexpand-all) (setq bt (cdr bt)))
-        (if macroexp--debug-eager
-            (debug 'eager-macroexp-cycle)
-          (error "Eager macro-expansion skipped due to cycle:\n  %s"
-                 (mapconcat #'prin1-to-string (nreverse bt) " => ")))
-        (push 'skip macroexp--pending-eager-loads)
-        form))
-     (t
-      (condition-case err
-          (let ((macroexp--pending-eager-loads
-                 (cons load-file-name macroexp--pending-eager-loads)))
-            (if full-p
-                (macroexpand--all-toplevel form)
-              (macroexpand form)))
-        (error
-         ;; Hopefully this shouldn't happen thanks to the cycle detection,
-         ;; but in case it does happen, let's catch the error and give the
-         ;; code a chance to macro-expand later.
-         (error "Eager macro-expansion failure: %S in %S" err form)
-         form))))))
+  (cond
+   ;; Don't repeat the same warning for every top-level element.
+   ((eq 'skip (car macroexp--pending-eager-loads)) form)
+   ;; If we detect a cycle, skip macro-expansion for now, and output a warning
+   ;; with a trimmed backtrace.
+   ((and load-file-name (member load-file-name macroexp--pending-eager-loads))
+    (let* ((bt (delq nil
+                     (mapcar #'macroexp--trim-backtrace-frame
+                             (macroexp--backtrace))))
+           (elem `(load ,(file-name-nondirectory load-file-name)))
+           (tail (member elem (cdr (member elem bt)))))
+      (if tail (setcdr tail (list '…)))
+      (if (eq (car-safe (car bt)) 'macroexpand-all) (setq bt (cdr bt)))
+      (if macroexp--debug-eager
+          (debug 'eager-macroexp-cycle)
+        (error "Eager macro-expansion skipped due to cycle:\n  %s"
+               (mapconcat #'prin1-to-string (nreverse bt) " => ")))
+      (push 'skip macroexp--pending-eager-loads)
+      form))
+   (t
+    (condition-case err
+        (let ((macroexp--pending-eager-loads
+               (cons load-file-name macroexp--pending-eager-loads)))
+          (if full-p
+              (macroexpand--all-toplevel form)
+            (macroexpand form)))
+      (error
+       ;; Hopefully this shouldn't happen thanks to the cycle detection,
+       ;; but in case it does happen, let's catch the error and give the
+       ;; code a chance to macro-expand later.
+       (error "Eager macro-expansion failure: %S" err)
+       form)))))
 
 ;; ¡¡¡ Big Ugly Hack !!!
 ;; src/bootstrap-emacs is mostly used to compile .el files, so it needs
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 6ce00bf4d6d..e1172d69bf0 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2330,12 +2330,25 @@ from ELPA by either using `\\[package-upgrade]' or
       (mapc #'package-upgrade upgradeable))))
 
 (defun package--dependencies (pkg)
-  "Return a list of all dependencies PKG has.
-This is done recursively."
-  ;; Can we have circular dependencies?  Assume "nope".
-  (when-let* ((desc (cadr (assq pkg package-archive-contents)))
-              (deps (mapcar #'car (package-desc-reqs desc))))
-    (delete-dups (apply #'nconc deps (mapcar #'package--dependencies deps)))))
+  "Return a list of all transitive dependencies of PKG.
+If PKG is a package descriptor, the return value is a list of
+package descriptors.  If PKG is a symbol designating a package,
+the return value is a list of symbols designating packages."
+  (when-let* ((desc (if (package-desc-p pkg) pkg
+                      (cadr (assq pkg package-archive-contents)))))
+    ;; Can we have circular dependencies?  Assume "nope".
+    (let ((all (named-let more ((pkg-desc desc))
+                 (let (deps)
+                   (dolist (req (package-desc-reqs pkg-desc))
+                     (setq deps (nconc
+                                 (catch 'found
+                                   (dolist (p (apply #'append (mapcar #'cdr 
(package--alist))))
+                                     (when (and (string= (car req) 
(package-desc-name p))
+                                                (version-list-<= (cadr req) 
(package-desc-version p)))
+                                       (throw 'found (more p)))))
+                                 deps)))
+                   (delete-dups (cons pkg-desc deps))))))
+      (remq pkg (mapcar (if (package-desc-p pkg) #'identity 
#'package-desc-name) all)))))
 
 (defun package-strip-rcs-id (str)
   "Strip RCS version ID from the version string STR.
@@ -2625,6 +2638,57 @@ will be deleted."
                   removable))
         (message "Nothing to autoremove")))))
 
+(defun package-isolate (packages &optional temp-init)
+  "Start an uncustomised Emacs and only load a set of PACKAGES.
+If TEMP-INIT is non-nil, or when invoked with a prefix argument,
+the Emacs user directory is set to a temporary directory."
+  (interactive
+   (cl-loop for p in (cl-loop for p in (package--alist) append (cdr p))
+           unless (package-built-in-p p)
+           collect (cons (package-desc-full-name p) p) into table
+           finally return
+           (list (cl-loop for c in (completing-read-multiple
+                                     "Isolate packages: " table
+                                     nil t)
+                          collect (alist-get c table nil nil #'string=))
+                  current-prefix-arg)))
+  (let* ((name (concat "package-isolate-"
+                       (mapconcat #'package-desc-full-name packages ",")))
+         (all-packages (delete-consecutive-dups
+                        (sort (append packages (mapcan #'package--dependencies 
packages))
+                              (lambda (p0 p1)
+                                (string< (package-desc-name p0) 
(package-desc-name p1))))))
+         initial-scratch-message package-load-list)
+    (with-temp-buffer
+      (insert ";; This is an isolated testing environment, with these packages 
enabled:\n\n")
+      (dolist (package all-packages)
+        (push (list (package-desc-name package)
+                    (package-version-join (package-desc-version package)))
+              package-load-list)
+        (insert ";; - " (package-desc-full-name package))
+        (unless (memq package packages)
+          (insert " (dependency)"))
+        (insert "\n"))
+      (insert "\n")
+      (setq initial-scratch-message (buffer-string)))
+    (apply #'start-process (concat "*" name "*") nil
+           (list (expand-file-name invocation-name invocation-directory)
+                 "--quick" "--debug-init"
+                 "--init-directory" (if temp-init
+                                        (make-temp-file name t)
+                                      user-emacs-directory)
+                 (format "--eval=%S"
+                         `(progn
+                            (setq initial-scratch-message 
,initial-scratch-message)
+
+                            (require 'package)
+                            ,@(mapcar
+                               (lambda (dir)
+                                 `(add-to-list 'package-directory-list ,dir))
+                               (cons package-user-dir package-directory-list))
+                            (setq package-load-list ',package-load-list)
+                            (package-initialize)))))))
+
 
 ;;;; Package description buffer.
 
@@ -3088,18 +3152,36 @@ either a full name or nil, and EMAIL is a valid email 
address."
 
     "--"
     ("Filter Packages"
-     ["Filter by Archive" package-menu-filter-by-archive :help "Filter 
packages by archive"]
-     ["Filter by Description" package-menu-filter-by-description :help "Filter 
packages by description"]
-     ["Filter by Keyword" package-menu-filter-by-keyword :help "Filter 
packages by keyword"]
-     ["Filter by Name" package-menu-filter-by-name :help "Filter packages by 
name"]
+     ["Filter by Archive" package-menu-filter-by-archive
+      :help
+      "Prompt for archive(s), display only packages from those archives"]
+     ["Filter by Description" package-menu-filter-by-description
+      :help
+      "Prompt for regexp, display only packages with matching description"]
+     ["Filter by Keyword" package-menu-filter-by-keyword
+      :help
+      "Prompt for keyword(s), display only packages with matching keywords"]
+     ["Filter by Name" package-menu-filter-by-name
+      :help
+      "Prompt for regexp, display only packages whose names match the regexp"]
      ["Filter by Name or Description" 
package-menu-filter-by-name-or-description
-      :help "Filter packages by name or description"]
-     ["Filter by Status" package-menu-filter-by-status :help "Filter packages 
by status"]
-     ["Filter by Version" package-menu-filter-by-version :help "Filter 
packages by version"]
-     ["Filter Marked" package-menu-filter-marked :help "Filter packages marked 
for upgrade"]
-     ["Clear Filter" package-menu-clear-filter :help "Clear package list 
filter"])
-
-    ["Hide by Regexp" package-menu-hide-package :help "Hide all packages 
matching a regexp"]
+      :help
+      "Prompt for regexp, display only packages whose name or description 
matches"]
+     ["Filter by Status" package-menu-filter-by-status
+      :help
+      "Prompt for status(es), display only packages with those statuses"]
+     ["Filter by Upgrades available" package-menu-filter-upgradable
+      :help "Display only installed packages for which upgrades are available"]
+     ["Filter by Version" package-menu-filter-by-version
+      :help
+      "Prompt for version and comparison operator, display only packages of 
matching versions"]
+     ["Filter Marked" package-menu-filter-marked
+      :help "Display only packages marked for installation or deletion"]
+     ["Clear Filter" package-menu-clear-filter
+      :help "Clear package list filtering, display the entire list again"])
+
+    ["Hide by Regexp" package-menu-hide-package
+     :help "Toggle visibility of obsolete and unwanted packages"]
     ["Display Older Versions" package-menu-toggle-hiding
      :style toggle :selected (not package-menu--hide-packages)
      :help "Display package even if a newer version is already installed"]
@@ -4295,7 +4377,7 @@ STATUS can be a single status, a string, or a list of 
strings.
 If STATUS is nil or the empty string, show all packages.
 
 When called interactively, prompt for STATUS.  To specify
-several possible status values, type them seperated by commas."
+several possible status values, type them separated by commas."
   (interactive (list (completing-read "Filter by status: "
                                       '("avail-obso"
                                         "available"
diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el
index 550fab2f4b3..95ad222cc4d 100644
--- a/lisp/emacs-lisp/pp.el
+++ b/lisp/emacs-lisp/pp.el
@@ -226,8 +226,10 @@ it inserts and pretty-prints that arg at point."
                     (if (eq lif 'defun) (setq lif 2))
                     (when (natnump lif)
                       (goto-char (match-end 0))
-                      (forward-sexp lif)
-                      (funcall newline)))))
+                      ;; Do nothing if there aren't enough args.
+                      (ignore-error scan-error
+                        (forward-sexp lif)
+                        (funcall newline))))))
               (save-excursion
                 (pp-fill (1+ paired) (1- (point)))))
             ;; Now the sexp either ends beyond `fill-column' or is
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index d46d0ca5a98..afc9826eefa 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -26,7 +26,7 @@
 ;; The translation to string regexp is done by a macro and does not
 ;; incur any extra processing during run time.  Example:
 ;;
-;;  (rx bos (or (not (any "^"))
+;;  (rx bos (or (not "^")
 ;;              (seq "^" (or " *" "["))))
 ;;
 ;; => "\\`\\(?:[^^]\\|\\^\\(?: \\*\\|\\[\\)\\)"
@@ -161,27 +161,23 @@ Each entry is:
   (or (cdr (assq name rx--local-definitions))
       (get name 'rx-definition)))
 
-(defun rx--expand-def (form)
-  "FORM expanded (once) if a user-defined construct; otherwise nil."
-  (cond ((symbolp form)
-         (let ((def (rx--lookup-def form)))
-           (and def
-                (if (cdr def)
-                    (error "Not an `rx' symbol definition: %s" form)
-                  (car def)))))
-        ((and (consp form) (symbolp (car form)))
-         (let* ((op (car form))
-                (def (rx--lookup-def op)))
+(defun rx--expand-def-form (form)
+  "List FORM expanded (once) if a user-defined construct; otherwise nil."
+  (let ((op (car form)))
+    (and (symbolp op)
+         (let ((def (rx--lookup-def op)))
            (and def
                 (if (cdr def)
-                    (rx--expand-template
-                     op (cdr form) (nth 0 def) (nth 1 def))
+                    (rx--expand-template op (cdr form) (nth 0 def) (nth 1 def))
                   (error "Not an `rx' form definition: %s" op)))))))
 
-;; TODO: Additions to consider:
-;; - A construct like `or' but without the match order guarantee,
-;;   maybe `unordered-or'.  Useful for composition or generation of
-;;   alternatives; permits more effective use of regexp-opt.
+(defun rx--expand-def-symbol (symbol)
+  "SYM expanded (once) if a user-defined name; otherwise nil."
+  (let ((def (rx--lookup-def symbol)))
+    (and def
+         (if (cdr def)
+             (error "Not an `rx' symbol definition: %s" symbol)
+           (car def)))))
 
 (defun rx--translate-symbol (sym)
   "Translate an rx symbol.  Return (REGEXP . PRECEDENCE)."
@@ -208,22 +204,13 @@ Each entry is:
       ((let ((class (cdr (assq sym rx--char-classes))))
          (and class (cons (list (concat "[[:" (symbol-name class) ":]]")) t))))
 
-      ((let ((expanded (rx--expand-def sym)))
+      ((let ((expanded (rx--expand-def-symbol sym)))
          (and expanded (rx--translate expanded))))
 
       ;; For compatibility with old rx.
       ((let ((entry (assq sym rx-constituents)))
-         (and (progn
-                (while (and entry (not (stringp (cdr entry))))
-                  (setq entry
-                        (if (symbolp (cdr entry))
-                            ;; Alias for another entry.
-                            (assq (cdr entry) rx-constituents)
-                          ;; Wrong type, try further down the list.
-                          (assq (car entry)
-                                (cdr (memq entry rx-constituents))))))
-                entry)
-              (cons (list (cdr entry)) nil))))
+         (and entry (rx--translate-compat-symbol-entry entry))))
+
       (t (error "Unknown rx symbol `%s'" sym))))))
 
 (defun rx--enclose (left-str rexp right-str)
@@ -289,83 +276,225 @@ Left-fold the list L, starting with X, by the binary 
function F."
     (setq l (cdr l)))
   x)
 
-(defun rx--normalise-or-arg (form)
-  "Normalize the `or' argument FORM.
-Characters become strings, user-definitions and `eval' forms are expanded,
-and `or' forms are normalized recursively."
-  (cond ((characterp form)
+;; FIXME: flatten nested `or' patterns when performing char-pattern combining.
+;; The only reason for not flattening is to ensure regexp-opt processing
+;; (which we do for entire `or' patterns, not subsequences), but we
+;; obviously want to translate
+;;   (or "a" space (or "b" (+ nonl) word) "c")
+;;   -> (or (in "ab" space) (+ nonl) (in "c" word))
+
+;; FIXME: normalise `seq', both the construct and implicit sequences,
+;; so that they are flattened, adjacent strings concatenated, and
+;; empty strings removed. That would give more opportunities for regexp-opt:
+;;  (or "a" (seq "ab" (seq "c" "d") "")) -> (or "a" "abcd")
+
+;; FIXME: Since `rx--normalise-char-pattern' recurses through `or', `not' and
+;; `intersection', we may end up normalising subtrees multiple times
+;; which wastes time (but should be idempotent).
+;; One way to avoid this is to aggressively normalise the entire tree
+;; before translating anything at all, but we must then recurse through
+;; all constructs and probably copy them.
+;; Such normalisation could normalise synonyms, eliminate `minimal-match'
+;; and `maximal-match' and convert affected `1+' to either `+' or `+?' etc.
+;; We would also consolidate the user-def lookup, both modern and legacy,
+;; in one place.
+
+(defun rx--normalise-char-pattern (form)
+  "Normalize FORM as a pattern matching a single-character.
+Characters become strings, `any' forms and character classes become
+`rx--char-alt' forms, user-definitions and `eval' forms are expanded,
+and `or', `not' and `intersection' forms are normalized recursively.
+
+A `rx--char-alt' form is shaped (rx--char-alt INTERVALS . CLASSES)
+where INTERVALS is a sorted list of disjoint nonadjacent intervals,
+each a cons of characters, and CLASSES an unordered list of unique
+name-normalised character classes."
+  (defvar rx--builtin-forms)
+  (defvar rx--builtin-symbols)
+  (cond ((consp form)
+         (let ((op (car form))
+               (body (cdr form)))
+           (cond ((memq op '(or |))
+                  ;; Normalise the constructor to `or' and the args 
recursively.
+                  (cons 'or (mapcar #'rx--normalise-char-pattern body)))
+                 ;; Convert `any' forms and char classes now so that we
+                 ;; don't need to do it later on.
+                 ((memq op '(any in char))
+                  (cons 'rx--char-alt (rx--parse-any body)))
+                 ((memq op '(not intersection))
+                  (cons op (mapcar #'rx--normalise-char-pattern body)))
+                 ((eq op 'eval)
+                  (rx--normalise-char-pattern (rx--expand-eval body)))
+                 ((memq op rx--builtin-forms) form)
+                 ((let ((expanded (rx--expand-def-form form)))
+                    (and expanded
+                         (rx--normalise-char-pattern expanded))))
+                 (t form))))
+        ;; FIXME: Should we expand legacy definitions from
+        ;; `rx-constituents' here as well?
+        ((symbolp form)
+         (cond ((let ((class (assq form rx--char-classes)))
+                  (and class
+                       `(rx--char-alt nil . (,(cdr class))))))
+               ((memq form rx--builtin-symbols) form)
+               ((let ((expanded (rx--expand-def-symbol form)))
+                  (and expanded
+                       (rx--normalise-char-pattern expanded))))
+               (t form)))
+        ((characterp form)
          (char-to-string form))
-        ((and (consp form) (memq (car form) '(or |)))
-         (cons (car form) (mapcar #'rx--normalise-or-arg (cdr form))))
-        ((and (consp form) (eq (car form) 'eval))
-         (rx--normalise-or-arg (rx--expand-eval (cdr form))))
-        (t
-         (let ((expanded (rx--expand-def form)))
-           (if expanded
-               (rx--normalise-or-arg expanded)
-             form)))))
-
-(defun rx--all-string-or-args (body)
-  "If BODY only consists of strings or such `or' forms, return all the strings.
-Otherwise throw `rx--nonstring'."
+        (t form)))
+
+(defun rx--char-alt-union (a b)
+  "Union of the (INTERVALS . CLASSES) pairs A and B."
+  (let* ((a-cl (cdr a))
+         (b-cl (cdr b))
+         (classes (if (and a-cl b-cl)
+                      (let ((acc a-cl))
+                        (dolist (c b-cl)
+                          (unless (memq c a-cl)
+                            (push c acc)))
+                        acc)
+                    (or a-cl b-cl))))
+    (cons (rx--interval-set-union (car a) (car b)) classes)))
+
+(defun rx--intersection-intervals (forms)
+  "Intersection of the normalised FORMS, as an interval set."
+  (rx--foldl #'rx--interval-set-intersection '((0 . #x3fffff))
+             (mapcar (lambda (x)
+                       (let ((char (rx--reduce-to-char-alt x)))
+                         (if (and char (null (cdr char)))
+                             (car char)
+                           (error "Cannot be used in rx intersection: %S"
+                                  (rx--human-readable x)))))
+                     forms)))
+
+(defun rx--reduce-to-char-alt (form)
+  "Transform FORM into (INTERVALS . CLASSES) or nil if not possible.
+Process `or', `intersection' and `not'.
+FORM must be normalised (from `rx--normalise-char-pattern')."
+  (cond
+   ((stringp form)
+    (and (= (length form) 1)
+         (let ((c (aref form 0)))
+           (list (list (cons c c))))))
+   ((consp form)
+    (let ((head (car form)))
+      (cond
+       ;; FIXME: Transform `digit', `xdigit', `cntrl', `ascii', `nonascii'
+       ;; to ranges? That would allow them to be negated and intersected.
+       ((eq head 'rx--char-alt) (cdr form))
+       ((eq head 'not)
+        (unless (= (length form) 2)
+          (error "rx `not' form takes exactly one argument"))
+        (let ((arg (rx--reduce-to-char-alt (cadr form))))
+          ;; Only interval sets without classes are closed under complement.
+          (and arg (null (cdr arg))
+               (list (rx--interval-set-complement (car arg))))))
+       ((eq head 'or)
+        (let ((args (cdr form)))
+          (let ((acc '(nil)))  ; union identity
+            (while (and args
+                        (let ((char (rx--reduce-to-char-alt (car args))))
+                          (setq acc (and char (rx--char-alt-union acc char)))))
+              (setq args (cdr args)))
+            acc)))
+       ((eq head 'intersection)
+        (list (rx--intersection-intervals (cdr form))))
+       )))
+   ((memq form '(nonl not-newline any))
+    '(((0 . 9) (11 . #x3fffff))))
+   ((memq form '(anychar anything))
+    '(((0 . #x3fffff))))
+   ;; FIXME: A better handling of `unmatchable' would be:
+   ;;   * (seq ... unmatchable ...) -> unmatchable
+   ;;   * any or-pattern branch that is `unmatchable' is deleted
+   ;;   * (REPEAT unmatchable) -> "", if REPEAT accepts 0 repetitions
+   ;;   * (REPEAT unmatchable) -> unmatchable, otherwise
+   ;; if it's worth the trouble (probably not).
+   ((eq form 'unmatchable)
+    '(nil))
+   ))
+
+(defun rx--optimise-or-args (args)
+  "Optimise `or' arguments.  Return a new rx form.
+Each element of ARGS should have been normalised using
+`rx--normalise-char-pattern'."
+  (if (null args)
+      ;; No arguments.
+      '(rx--char-alt nil . nil)         ; FIXME: not `unmatchable'?
+    ;; Join consecutive single-char branches into a char alt where possible.
+    ;; Ideally we should collect all single-char branches but that might
+    ;; alter matching order in some cases.
+    (let ((branches nil)
+          (prev-char nil))
+      (while args
+        (let* ((item (car args))
+               (item-char (rx--reduce-to-char-alt item)))
+          (if item-char
+              (setq prev-char (if prev-char
+                                  (rx--char-alt-union prev-char item-char)
+                                item-char))
+            (when prev-char
+              (push (cons 'rx--char-alt prev-char) branches)
+              (setq prev-char nil))
+            (push item branches)))
+        (setq args (cdr args)))
+      (when prev-char
+        (push (cons 'rx--char-alt prev-char) branches))
+      (if (cdr branches)
+          (cons 'or (nreverse branches))
+        (car branches)))))
+
+(defun rx--all-string-branches-p (forms)
+  "Whether FORMS are all strings or `or' forms with the same property."
+  (rx--every (lambda (x) (or (stringp x)
+                             (and (eq (car-safe x) 'or)
+                                  (rx--all-string-branches-p (cdr x)))))
+             forms))
+
+(defun rx--collect-or-strings (forms)
+  "All strings from FORMS, which are strings or `or' forms."
   (mapcan (lambda (form)
-            (cond ((stringp form) (list form))
-                  ((and (consp form) (memq (car form) '(or |)))
-                   (rx--all-string-or-args (cdr form)))
-                  (t (throw 'rx--nonstring nil))))
-          body))
+            (if (stringp form)
+                (list form)
+              ;; must be an `or' form
+              (rx--collect-or-strings (cdr form))))
+          forms))
+
+;; TODO: Write a more general rx-level factoriser to replace
+;; `regexp-opt' for our purposes.  It would handle non-literals:
+;;
+;;    (or "ab" (: "a" space) "bc" (: "b" (+ digit)))
+;; -> (or (: "a" (in "b" space)) (: "b" (or "c" (+ digit))))
+;;
+;; As a minor side benefit we would get less useless bracketing.
+;; The main problem is how to deal with matching order, which `regexp-opt'
+;; alters in its own way.
 
 (defun rx--translate-or (body)
   "Translate an or-pattern of zero or more rx items.
 Return (REGEXP . PRECEDENCE)."
-  ;; FIXME: Possible improvements:
-  ;;
-  ;; - Flatten sub-patterns first: (or (or A B) (or C D)) -> (or A B C D)
-  ;;   Then call regexp-opt on runs of string arguments. Example:
-  ;;   (or (+ digit) "CHARLIE" "CHAN" (+ blank))
-  ;;   -> (or (+ digit) (or "CHARLIE" "CHAN") (+ blank))
-  ;;
-  ;; - Optimize single-character alternatives better:
-  ;;     * classes: space, alpha, ...
-  ;;     * (syntax S), for some S (whitespace, word)
-  ;;   so that (or "@" "%" digit (any "A-Z" space) (syntax word))
-  ;;        -> (any "@" "%" digit "A-Z" space word)
-  ;;        -> "[A-Z@%[:digit:][:space:][:word:]]"
   (cond
    ((null body)                    ; No items: a never-matching regexp.
     (rx--empty))
    ((null (cdr body))              ; Single item.
     (rx--translate (car body)))
    (t
-    (let* ((args (mapcar #'rx--normalise-or-arg body))
-           (all-strings (catch 'rx--nonstring (rx--all-string-or-args args))))
-      (cond
-       (all-strings                       ; Only strings.
-        (cons (list (regexp-opt all-strings nil))
-              t))
-       ((rx--every #'rx--charset-p args)  ; All charsets.
-        (rx--translate-union nil args))
-       (t
-        (cons (append (car (rx--translate (car args)))
-                      (mapcan (lambda (item)
-                                (cons "\\|" (car (rx--translate item))))
-                              (cdr args)))
-              nil)))))))
-
-(defun rx--charset-p (form)
-  "Whether FORM looks like a charset, only consisting of character intervals
-and set operations."
-  (or (and (consp form)
-           (or (and (memq (car form) '(any in char))
-                    (rx--every (lambda (x) (not (symbolp x))) (cdr form)))
-               (and (memq (car form) '(not or | intersection))
-                    (rx--every #'rx--charset-p (cdr form)))))
-      (characterp form)
-      (and (stringp form) (= (length form) 1))
-      (and (or (symbolp form) (consp form))
-           (let ((expanded (rx--expand-def form)))
-             (and expanded
-                  (rx--charset-p expanded))))))
+    (let ((args (mapcar #'rx--normalise-char-pattern body)))
+      (if (rx--all-string-branches-p args)
+          ;; All branches are strings: use `regexp-opt'.
+          (cons (list (regexp-opt (rx--collect-or-strings args) nil))
+                t)
+        (let ((form (rx--optimise-or-args args)))
+          (if (eq (car-safe form) 'or)
+              (let ((branches (cdr form)))
+                (cons (append (car (rx--translate (car branches)))
+                              (mapcan (lambda (item)
+                                        (cons "\\|" (car (rx--translate 
item))))
+                                      (cdr branches)))
+                      nil))
+            (rx--translate form))))))))
 
 (defun rx--string-to-intervals (str)
   "Decode STR as intervals: A-Z becomes (?A . ?Z), and the single
@@ -420,7 +549,7 @@ INTERVALS is a list of (START . END) with START ≤ END, 
sorted by START."
 (defun rx--parse-any (body)
   "Parse arguments of an (any ...) construct.
 Return (INTERVALS . CLASSES), where INTERVALS is a sorted list of
-disjoint intervals (each a cons of chars), and CLASSES
+disjoint nonadjacent intervals (each a cons of chars), and CLASSES
 a list of named character classes in the order they occur in BODY."
   (let ((classes nil)
         (strings nil)
@@ -447,7 +576,7 @@ a list of named character classes in the order they occur 
in BODY."
            (sort (append conses
                          (mapcan #'rx--string-to-intervals strings))
                  #'car-less-than-car))
-          (reverse classes))))
+          (nreverse classes))))
 
 (defun rx--generate-alt (negated intervals classes)
   "Generate a character alternative.  Return (REGEXP . PRECEDENCE).
@@ -456,6 +585,19 @@ list of disjoint intervals and CLASSES a list of named 
character
 classes."
   ;; No, this is not pretty code.  You try doing it in a way that is both
   ;; elegant and efficient.  Or just one of the two.  I dare you.
+
+  ;; Detect whether the interval set is better described in
+  ;; complemented form.  This is not just a matter of aesthetics: any
+  ;; range that straddles the char-raw boundary will be mutilated by the
+  ;; regexp engine.  Ranges from ASCII to raw bytes will exclude the
+  ;; all non-ASCII non-raw bytes, and ranges from non-ASCII Unicode
+  ;; to raw bytes are ignored.
+  (unless (or classes
+              ;; Any interval set covering #x3fff7f should be negated.
+              (rx--every (lambda (iv) (not (<= (car iv) #x3fff7f (cdr iv))))
+                         intervals))
+    (setq negated (not negated))
+    (setq intervals (rx--interval-set-complement intervals)))
   (cond
    ;; Single character.
    ((and intervals (eq (caar intervals) (cdar intervals))
@@ -474,7 +616,7 @@ classes."
    ;; Empty set (or any char).
    ((and (null intervals) (null classes))
     (if negated
-        (rx--translate-symbol 'anything)
+        (rx--translate-symbol 'anychar)
       (rx--empty)))
 
    ;; More than one character, or at least one class.
@@ -547,28 +689,18 @@ classes."
          "]"))
        t)))))
 
+(defun rx--translate-char-alt (negated body)
+  "Translate a (rx--char-alt ...) construct.  Return (REGEXP . PRECEDENCE).
+If NEGATED, negate the sense."
+  (rx--generate-alt negated (car body) (cdr body)))
+
 (defun rx--translate-any (negated body)
   "Translate an (any ...) construct.  Return (REGEXP . PRECEDENCE).
 If NEGATED, negate the sense."
   (let ((parsed (rx--parse-any body)))
     (rx--generate-alt negated (car parsed) (cdr parsed))))
 
-(defun rx--intervals-to-alt (negated intervals)
-  "Generate a character alternative from an interval set.
-Return (REGEXP . PRECEDENCE).
-INTERVALS is a sorted list of disjoint intervals.
-If NEGATED, negate the sense."
-  ;; Detect whether the interval set is better described in
-  ;; complemented form.  This is not just a matter of aesthetics: any
-  ;; range from ASCII to raw bytes will automatically exclude the
-  ;; entire non-ASCII Unicode range by the regexp engine.
-  (if (rx--every (lambda (iv) (not (<= (car iv) #x3ffeff (cdr iv))))
-                 intervals)
-      (rx--generate-alt negated intervals nil)
-    (rx--generate-alt
-     (not negated) (rx--complement-intervals intervals) nil)))
-
-;; FIXME: Consider turning `not' into a variadic operator, following SRE:
+;; TODO: Consider turning `not' into a variadic operator, following SRE:
 ;; (not A B) = (not (or A B)) = (intersection (not A) (not B)), and
 ;; (not) = anychar.
 ;; Maybe allow singleton characters as arguments.
@@ -578,43 +710,27 @@ If NEGATED, negate the sense."
 If NEGATED, negate the sense (thus making it positive)."
   (unless (and body (null (cdr body)))
     (error "rx `not' form takes exactly one argument"))
-  (let ((arg (car body)))
-    (cond
-     ((and (consp arg)
-           (pcase (car arg)
-             ((or 'any 'in 'char)
-              (rx--translate-any      (not negated) (cdr arg)))
-             ('syntax
-              (rx--translate-syntax   (not negated) (cdr arg)))
-             ('category
-              (rx--translate-category (not negated) (cdr arg)))
-             ('not
-              (rx--translate-not      (not negated) (cdr arg)))
-             ((or 'or '|)
-              (rx--translate-union    (not negated) (cdr arg)))
-             ('intersection
-              (rx--translate-intersection (not negated) (cdr arg))))))
-     ((let ((class (cdr (assq arg rx--char-classes))))
-        (and class
-             (rx--generate-alt (not negated) nil (list class)))))
-     ((eq arg 'word-boundary)
-      (rx--translate-symbol
-       (if negated 'word-boundary 'not-word-boundary)))
-     ((characterp arg)
-      (rx--generate-alt (not negated) (list (cons arg arg)) nil))
-     ((and (stringp arg) (= (length arg) 1))
-      (let ((char (string-to-char arg)))
-        (rx--generate-alt (not negated) (list (cons char char)) nil)))
-     ((let ((expanded (rx--expand-def arg)))
-        (and expanded
-             (rx--translate-not negated (list expanded)))))
-     (t (error "Illegal argument to rx `not': %S" arg)))))
-
-(defun rx--complement-intervals (intervals)
-  "Complement of the interval list INTERVALS."
+  (let ((arg (rx--normalise-char-pattern (car body))))
+    (pcase arg
+      (`(not . ,args)
+       (rx--translate-not      (not negated) args))
+      (`(syntax . ,args)
+       (rx--translate-syntax   (not negated) args))
+      (`(category . ,args)
+       (rx--translate-category (not negated) args))
+      ('word-boundary                     ; legacy syntax
+       (rx--translate-symbol (if negated 'word-boundary 'not-word-boundary)))
+      (_ (let ((char (rx--reduce-to-char-alt arg)))
+           (if char
+               (rx--generate-alt (not negated) (car char) (cdr char))
+             (error "Illegal argument to rx `not': %S"
+                    (rx--human-readable arg))))))))
+
+(defun rx--interval-set-complement (ivs)
+  "Complement of the interval set IVS."
   (let ((compl nil)
         (c 0))
-    (dolist (iv intervals)
+    (dolist (iv ivs)
       (when (< c (car iv))
         (push (cons c (1- (car iv))) compl))
       (setq c (1+ (cdr iv))))
@@ -622,8 +738,8 @@ If NEGATED, negate the sense (thus making it positive)."
       (push (cons c (max-char)) compl))
     (nreverse compl)))
 
-(defun rx--intersect-intervals (ivs-a ivs-b)
-  "Intersection of the interval lists IVS-A and IVS-B."
+(defun rx--interval-set-intersection (ivs-a ivs-b)
+  "Intersection of the interval sets IVS-A and IVS-B."
   (let ((isect nil))
     (while (and ivs-a ivs-b)
       (let ((a (car ivs-a))
@@ -645,8 +761,8 @@ If NEGATED, negate the sense (thus making it positive)."
                        ivs-a)))))))
     (nreverse isect)))
 
-(defun rx--union-intervals (ivs-a ivs-b)
-  "Union of the interval lists IVS-A and IVS-B."
+(defun rx--interval-set-union (ivs-a ivs-b)
+  "Union of the interval sets IVS-A and IVS-B."
   (let ((union nil))
     (while (and ivs-a ivs-b)
       (let ((a (car ivs-a))
@@ -670,53 +786,66 @@ If NEGATED, negate the sense (thus making it positive)."
                   ivs-a))))))
     (nconc (nreverse union) (or ivs-a ivs-b))))
 
-(defun rx--charset-intervals (charset)
-  "Return a sorted list of non-adjacent disjoint intervals from CHARSET.
-CHARSET is any expression allowed in a character set expression:
-characters, single-char strings, `any' forms (no classes permitted),
-or `not', `or' or `intersection' forms whose arguments are charsets."
-  (pcase charset
-    (`(,(or 'any 'in 'char) . ,body)
-     (let ((parsed (rx--parse-any body)))
-       (when (cdr parsed)
-         (error
-          "Character class not permitted in set operations: %S"
-          (cadr parsed)))
-       (car parsed)))
-    (`(not ,x) (rx--complement-intervals (rx--charset-intervals x)))
-    (`(,(or 'or '|) . ,body) (rx--charset-union body))
-    (`(intersection . ,body) (rx--charset-intersection body))
-    ((pred characterp)
-     (list (cons charset charset)))
-    ((guard (and (stringp charset) (= (length charset) 1)))
-     (let ((char (string-to-char charset)))
-       (list (cons char char))))
-    (_ (let ((expanded (rx--expand-def charset)))
-         (if expanded
-             (rx--charset-intervals expanded)
-           (error "Bad character set: %S" charset))))))
-
-(defun rx--charset-union (charsets)
-  "Union of CHARSETS, as a set of intervals."
-  (rx--foldl #'rx--union-intervals nil
-             (mapcar #'rx--charset-intervals charsets)))
-
-(defconst rx--charset-all (list (cons 0 (max-char))))
-
-(defun rx--charset-intersection (charsets)
-  "Intersection of CHARSETS, as a set of intervals."
-  (rx--foldl #'rx--intersect-intervals rx--charset-all
-             (mapcar #'rx--charset-intervals charsets)))
-
-(defun rx--translate-union (negated body)
-  "Translate an (or ...) construct of charsets.  Return (REGEXP . PRECEDENCE).
-If NEGATED, negate the sense."
-  (rx--intervals-to-alt negated (rx--charset-union body)))
+(defun rx--human-readable (form)
+  "Turn FORM into something that is more human-readable, for error messages."
+  ;; FIXME: Should we produce a string instead?
+  ;; That way we wouldn't have problems with ? and ??, and we could escape
+  ;; single chars.
+  ;; We could steal `xr--rx-to-string' and just file off the serials.
+  (let ((recurse (lambda (op skip)
+                   (cons op (append (take skip (cdr form))
+                                    (mapcar #'rx--human-readable
+                                            (nthcdr skip (cdr form))))))))
+  (pcase form
+    ;; strings are more readable than numbers for single chars
+    ((pred characterp) (char-to-string form))
+    ;; resugar `rx--char-alt'
+    (`(rx--char-alt ((,c . ,c)) . nil)
+     (char-to-string form))
+    (`(rx--char-alt nil . (,class))
+     class)
+    ;; TODO: render in complemented form if more readable that way?
+    (`(rx--char-alt ,ivs . ,classes)
+     (let ((strings (mapcan (lambda (iv)
+                              (let ((beg (car iv))
+                                    (end (cdr iv)))
+                                (cond
+                                 ;; single char
+                                 ((eq beg end)
+                                  (list (string beg)))
+                                 ;; two chars
+                                 ((eq end (1+ beg))
+                                  (list (string beg) (string end)))
+                                 ;; first char is hyphen
+                                 ((eq beg ?-)
+                                  (cons (string "-")
+                                        (if (eq end (+ ?- 2))
+                                            (list (string (1+ ?-) end))
+                                          (list (string (1+ ?-) ?- end)))))
+                                 ;; other range
+                                 (t (list (string beg ?- end))))))
+                            ivs)))
+       `(any ,@strings ,@classes)))
+    ;; avoid numbers as ops
+    (`(?  . ,_) (funcall recurse '\? 0))
+    (`(??  . ,_) (funcall recurse '\?? 0))
+    ;; recurse on arguments
+    (`(repeat ,_ ,_) (funcall recurse (car form) 1))
+    (`(,(or '** 'repeat) . ,_) (funcall recurse (car form) 2))
+    (`(,(or '= '>= 'group-n 'submatch-n) . ,_) (funcall recurse (car form) 1))
+    (`(,(or 'backref 'syntax 'not-syntax 'category
+            'eval 'regex 'regexp 'literal)
+       . ,_)
+     form)
+    (`(,_ . ,_) (funcall recurse (car form) 0))
+    (_ form))))
 
 (defun rx--translate-intersection (negated body)
   "Translate an (intersection ...) construct.  Return (REGEXP . PRECEDENCE).
 If NEGATED, negate the sense."
-  (rx--intervals-to-alt negated (rx--charset-intersection body)))
+  (rx--generate-alt negated (rx--intersection-intervals
+                             (mapcar #'rx--normalise-char-pattern body))
+                    nil))
 
 (defun rx--atomic-regexp (item)
   "ITEM is (REGEXP . PRECEDENCE); return a regexp of precedence t."
@@ -966,15 +1095,15 @@ Return (REGEXP . PRECEDENCE)."
                                (opt "^")
                                (opt "]")
                                (* (or (seq "[:" (+ (any "a-z")) ":]")
-                                      (not (any "]"))))
+                                      (not "]")))
                                "]")
                           (not (any "*+?^$[\\"))
                           (seq "\\"
-                               (or anything
-                                   (seq (any "sScC_") anything)
+                               (or anychar
+                                   (seq (any "sScC_") anychar)
                                    (seq "("
-                                        (* (or (not (any "\\"))
-                                               (seq "\\" (not (any ")")))))
+                                        (* (or (not "\\")
+                                               (seq "\\" (not ")"))))
                                         "\\)"))))
                       eos)
                     t)))
@@ -1006,6 +1135,36 @@ DEF is the definition tuple.  Return (REGEXP . 
PRECEDENCE)."
         (error "The `%s' form did not expand to a string" (car form)))
       (cons (list regexp) nil))))
 
+(defun rx--translate-compat-symbol-entry (entry)
+  "Translate a compatibility symbol definition for ENTRY.
+Return (REGEXP . PRECEDENCE) or nil if none."
+  (and (progn
+         (while (and entry (not (stringp (cdr entry))))
+           (setq entry
+                 (if (symbolp (cdr entry))
+                     ;; Alias for another entry.
+                     (assq (cdr entry) rx-constituents)
+                   ;; Wrong type, try further down the list.
+                   (assq (car entry)
+                         (cdr (memq entry rx-constituents))))))
+         entry)
+       (cons (list (cdr entry)) nil)))
+
+(defun rx--translate-compat-form-entry (orig-form entry)
+  "Translate a compatibility ORIG-FORM definition for ENTRY.
+Return (REGEXP . PRECEDENCE) or nil if none."
+  (and (progn
+         (while (and entry (not (consp (cdr entry))))
+           (setq entry
+                 (if (symbolp (cdr entry))
+                     ;; Alias for another entry.
+                     (assq (cdr entry) rx-constituents)
+                   ;; Wrong type, try further down the list.
+                   (assq (car entry)
+                         (cdr (memq entry rx-constituents))))))
+         entry)
+       (rx--translate-compat-form (cdr entry) orig-form)))
+
 (defun rx--substitute (bindings form)
   "Substitute BINDINGS in FORM.  BINDINGS is an alist of (NAME . VALUES)
 where VALUES is a list to splice into FORM wherever NAME occurs.
@@ -1101,6 +1260,7 @@ can expand to any number of values."
       ((or 'seq : 'and 'sequence) (rx--translate-seq body))
       ((or 'or '|)              (rx--translate-or body))
       ((or 'any 'in 'char)      (rx--translate-any nil body))
+      ('rx--char-alt            (rx--translate-char-alt nil body))
       ('not-char                (rx--translate-any t body))
       ('not                     (rx--translate-not nil body))
       ('intersection            (rx--translate-intersection nil body))
@@ -1141,23 +1301,13 @@ can expand to any number of values."
        (cond
         ((not (symbolp op)) (error "Bad rx operator `%S'" op))
 
-        ((let ((expanded (rx--expand-def form)))
+        ((let ((expanded (rx--expand-def-form form)))
            (and expanded
                 (rx--translate expanded))))
 
         ;; For compatibility with old rx.
         ((let ((entry (assq op rx-constituents)))
-           (and (progn
-                  (while (and entry (not (consp (cdr entry))))
-                    (setq entry
-                          (if (symbolp (cdr entry))
-                              ;; Alias for another entry.
-                              (assq (cdr entry) rx-constituents)
-                            ;; Wrong type, try further down the list.
-                            (assq (car entry)
-                                  (cdr (memq entry rx-constituents))))))
-                  entry)
-                (rx--translate-compat-form (cdr entry) form))))
+           (and entry (rx--translate-compat-form-entry form entry))))
 
         (t (error "Unknown rx form `%s'" op)))))))
 
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 89a6cd131c0..bfaf4fa821a 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -279,8 +279,13 @@ themselves."
          " entries are deprecated. Either use a variable or a function"
          " that conditionally calls `erc-button-add-button'.")))))
 
-(defvar erc-button-nickname-callback-function #'erc-nick-popup
-  "Escape hatch for those needing a different nickname callback.")
+(defvar erc-button-nickname-callback-function #'erc-button--perform-nick-popup
+  "Escape hatch for users needing a non-standard nick-button callback.
+Value should be a function accepting a NICK and any number of
+trailing arguments that are as yet unspecified.  Runs when
+clicking \\`<mouse-1>' or hitting \\`RET' atop a nickname button.")
+(make-obsolete-variable 'erc-button-nickname-callback-function
+                        "default provides essential functionality" "30.1")
 
 (defun erc-button-add-buttons ()
   "Find external references in the current buffer and make buttons of them.
@@ -745,6 +750,10 @@ In server buffers, also prompt for a channel."
           (funcall code nick)
         (eval code `((nick . ,nick)))))))
 
+(defun erc-button--perform-nick-popup (nick &rest _)
+  "Call `erc-nick-popup' with NICK."
+  (erc-nick-popup nick))
+
 ;;; Callback functions
 (defun erc-button-describe-symbol (symbol-name)
   "Describe SYMBOL-NAME.
diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el
index e2a82582a3f..f4835f71278 100644
--- a/lisp/erc/erc-fill.el
+++ b/lisp/erc/erc-fill.el
@@ -137,9 +137,8 @@ user-defined functions."
 
 (defcustom erc-fill-line-spacing nil
   "Extra space between messages on graphical displays.
-This may need adjusting depending on how your faces are
-configured.  Its value should be larger than that of the variable
-`line-spacing', if set.  If unsure, try 0.5."
+Its value should be larger than that of the variable
+`line-spacing', if set.  When unsure, start with 0.5."
   :package-version '(ERC . "5.6") ; FIXME sync on release
   :type '(choice (const nil) number))
 
@@ -262,6 +261,14 @@ messages less than a day apart."
   ;; `kill-line' anyway so that users can see the error.
   (erc-fill--wrap-move #'kill-line #'kill-visual-line arg))
 
+(defun erc-fill--wrap-escape-hidden-speaker ()
+  "Move to start of message text when left of speaker.
+Basically mimic what `move-beginning-of-line' does with invisible text."
+  (when-let ((erc-fill-wrap-merge)
+             (prop (get-text-property (point) 'display))
+             ((or (equal prop "") (eq 'margin (car-safe (car-safe prop))))))
+    (goto-char (text-property-not-all (point) (pos-eol) 'display prop))))
+
 (defun erc-fill--wrap-beginning-of-line (arg)
   "Defer to `move-beginning-of-line' or `beginning-of-visual-line'."
   (interactive "^p")
@@ -271,10 +278,22 @@ messages less than a day apart."
   (if (get-text-property (point) 'erc-prompt)
       (goto-char erc-input-marker)
     ;; Mimic what `move-beginning-of-line' does with invisible text.
-    (when-let ((erc-fill-wrap-merge)
-               (prop (get-text-property (point) 'display))
-               ((or (equal prop "") (eq 'margin (car-safe (car-safe prop))))))
-      (goto-char (text-property-not-all (point) (pos-eol) 'display prop)))))
+    (erc-fill--wrap-escape-hidden-speaker)))
+
+(defun erc-fill--wrap-previous-line (&optional arg try-vscroll)
+  "Move to ARGth previous logical or screen line."
+  (interactive "^p\np")
+  (if erc-fill--wrap-visual-keys
+      (with-no-warnings (previous-line arg try-vscroll))
+    (prog1 (previous-logical-line arg try-vscroll)
+      (erc-fill--wrap-escape-hidden-speaker))))
+
+(defun erc-fill--wrap-next-line (&optional arg try-vscroll)
+  "Move to ARGth next logical or screen line."
+  (interactive "^p\np")
+  (if erc-fill--wrap-visual-keys
+      (with-no-warnings (next-line arg try-vscroll))
+    (next-logical-line arg try-vscroll)))
 
 (defun erc-fill--wrap-end-of-line (arg)
   "Defer to `move-end-of-line' or `end-of-visual-line'."
@@ -320,6 +339,8 @@ is 0, reset to value of `erc-fill-wrap-visual-keys'."
   "<remap> <move-end-of-line>" #'erc-fill--wrap-end-of-line
   "<remap> <move-beginning-of-line>" #'erc-fill--wrap-beginning-of-line
   "<remap> <toggle-truncate-lines>" #'erc-fill-wrap-toggle-truncate-lines
+  "<remap> <next-line>" #'erc-fill--wrap-next-line
+  "<remap> <previous-line>" #'erc-fill--wrap-previous-line
   "C-c a" #'erc-fill-wrap-cycle-visual-movement
   ;; Not sure if this is problematic because `erc-bol' takes no args.
   "<remap> <erc-bol>" #'erc-fill--wrap-beginning-of-line)
@@ -359,28 +380,38 @@ is 0, reset to value of `erc-fill-wrap-visual-keys'."
 ;;;###autoload(put 'fill-wrap 'erc--feature 'erc-fill)
 (define-erc-module fill-wrap nil
   "Fill style leveraging `visual-line-mode'.
-This local module displays nicks overhanging leftward to a common
-offset, as determined by the option `erc-fill-static-center'.  It
-depends on the `fill', `stamp', and `button' modules and assumes
-users who've defined their own `erc-insert-timestamp-function'
-have also customized the option `erc-fill-wrap-margin-side' to an
-explicit side.  To use this module, either include `fill-wrap' in
-`erc-modules' or set `erc-fill-function' to `erc-fill-wrap'.
-Manually invoking one of the minor-mode toggles is not
-recommended.
+This module displays nicks overhanging leftward to a common
+offset, as determined by the option `erc-fill-static-center'.  To
+use it, either include `fill-wrap' in `erc-modules' or set
+`erc-fill-function' to `erc-fill-wrap'.  Most users will want to
+enable the `scrolltobottom' module as well.  Once active, use
+\\[erc-fill-wrap-nudge] to adjust the width of the indent and the
+stamp margin, and use \\[erc-fill-wrap-toggle-truncate-lines] for
+cycling between logical- and screen-line oriented command
+movement.  Also see related options `erc-fill-line-spacing' and
+`erc-fill-wrap-merge'.
 
 This module imposes various restrictions on the appearance of
 timestamps.  Most notably, it insists on displaying them in the
 margins.  Users preferring left-sided stamps may notice that ERC
 also displays the prompt in the left margin, possibly truncating
-or padding it to constrain it to the margin's width.  When stamps
+or padding it to constrain it to the margin's width.
+Additionally, this module assumes that users providing their own
+`erc-insert-timestamp-function' have also customized the option
+`erc-fill-wrap-margin-side' to an explicit side.  When stamps
 appear in the right margin, which they do by default, users may
 find that ERC actually appends them to copy-as-killed messages
 without an intervening space.  This normally poses at most a
 minor inconvenience, however users of the `log' module may prefer
 a workaround provided by `erc-stamp-prefix-log-filter', which
 strips trailing stamps from logged messages and instead prepends
-them to every line."
+them to every line.
+
+As a so-called \"local\" module, `fill-wrap' depends on the
+global modules `fill', `stamp', and `button'; it activates them
+as needed when initializing.  Please note that enabling and
+disabling this module by invoking one of its minor-mode toggles
+is not recommended."
   ((erc-fill--wrap-ensure-dependencies)
    (erc--restore-initialize-priors erc-fill-wrap-mode
      erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys
@@ -548,8 +579,8 @@ decorations applied by third-party modules."
     (user-error "Command called in an undisplayed buffer"))
   (let* ((total (erc-fill--wrap-nudge arg))
          (leftp erc-stamp--margin-left-p)
-         (win-ratio (/ (float (- (window-point) (window-start)))
-                       (- (window-end nil t) (window-start)))))
+         ;; Anchor current line vertically.
+         (line (count-screen-lines (window-start) (window-point))))
     (when (zerop arg)
       (setq arg 1))
     (erc-compat-call
@@ -564,7 +595,7 @@ decorations applied by third-party modules."
                        (lambda ()
                          (interactive)
                          (cl-incf total (erc-fill--wrap-nudge a))
-                         (recenter (round (* win-ratio (window-height))))))))
+                         (recenter line)))))
        (dolist (key '(?\) ?_ ?+))
          (let ((a (pcase key
                     (?\) 0)
@@ -575,7 +606,7 @@ decorations applied by third-party modules."
                          (interactive)
                          (erc-stamp--adjust-margin (- a) (zerop a))
                          (when leftp (erc-stamp--refresh-left-margin-prompt))
-                         (recenter (round (* win-ratio (window-height))))))))
+                         (recenter line)))))
        map)
      t
      (lambda ()
@@ -584,7 +615,7 @@ decorations applied by third-party modules."
                 (if leftp left-margin-width right-margin-width)))
      "Use %k for further adjustment"
      1)
-    (recenter (round (* win-ratio (window-height))))))
+    (recenter line)))
 
 (defun erc-fill-regarding-timestamp ()
   "Fills a text such that messages start at column `erc-fill-static-center'."
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index d9ededa8e68..b37855cbecc 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -800,9 +800,7 @@ servers.  If called from a program, PROC specifies the 
server process."
    (list (read-string "Search for: ")
          (if current-prefix-arg
              nil erc-server-process)))
-  (if (fboundp 'multi-occur)
-      (multi-occur (erc-buffer-list nil proc) string)
-    (error "`multi-occur' is not defined as a function")))
+  (multi-occur (erc-buffer-list nil proc) string))
 
 (provide 'erc-goodies)
 
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index b7ef0f0c40c..509b2d31819 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -692,19 +692,56 @@ Concatenate FILE(s), or standard input, to standard 
output.")
 
 ;; special front-end functions for compilation-mode buffers
 
+(defun eshell-compile (command args &optional method mode)
+  "Run an external COMMAND with ARGS using a compilation buffer when possible.
+COMMAND should be a list of command-line arguments.  By default,
+if the command is outputting to the screen and is not part of a
+pipeline or subcommand, open an compilation buffer to hold the
+results; otherwise, write the output on stdout.
+
+If METHOD is `interactive', always open a compilation buffer.  If
+METHOD is `plain', always write to stdout.
+
+MODE, if specified, is the major mode to set in the compilation
+buffer (see `compilation-start')."
+  (if (and (not (eq method 'interactive))
+           (or (eq method 'plain)
+               eshell-in-pipeline-p
+               eshell-in-subcommand-p
+               (not (eshell-interactive-output-p))))
+      (throw 'eshell-replace-command
+              (eshell-parse-command (concat "*" command) args))
+    (compile
+     (mapconcat #'shell-quote-argument
+                (eshell-stringify-list (flatten-tree (cons command args)))
+                " ")
+     mode)))
+
+(defun eshell/compile (&rest args)
+  "Run an external COMMAND using a compilation buffer when possible.
+See `eshell-compile'."
+  (eshell-eval-using-options
+   "compile" args
+   '((?m "mode" t mode "the mode to set in the compilation buffer")
+     (?i "interactive" 'interactive method "always open a compilation buffer")
+     (?p "plain" 'plain method "always write to stdout")
+     :usage "[-p | -i] [-m MODE] COMMAND...
+Run COMMAND in a compilation buffer when outputting to the screen and
+not part of a pipeline or subcommand."
+     :parse-leading-options-only)
+   (when (stringp mode)
+     (setq mode (intern mode)))
+   (eshell-compile (car args) (cdr args) method mode)))
+
+(put 'eshell/compile 'eshell-no-numeric-conversions t)
+
 (defun eshell/make (&rest args)
   "Use `compile' to do background makes.
 Fallback to standard make when called synchronously."
-  (if (and eshell-current-subjob-p
-          (eshell-interactive-output-p))
-      (let ((compilation-process-setup-function
-            (list 'lambda nil
-                  (list 'setq 'process-environment
-                        (list 'quote (eshell-copy-environment))))))
-       (compile (concat "make " (eshell-flatten-and-stringify args))))
-    (throw 'eshell-replace-command
-          (eshell-parse-command "*make" (eshell-stringify-list
-                                         (flatten-tree args))))))
+  (eshell-compile "make" args
+                  ;; Use plain output unless we're executing in the
+                  ;; background.
+                  (not eshell-current-subjob-p)))
 
 (put 'eshell/make 'eshell-no-numeric-conversions t)
 
@@ -777,22 +814,10 @@ and if it's not part of a command pipeline.  Otherwise, 
it calls the
 external command."
   (if (and maybe-use-occur eshell-no-grep-available)
       (eshell-poor-mans-grep args)
-    (if (or eshell-plain-grep-behavior
-           (not (and (eshell-interactive-output-p)
-                     (not eshell-in-pipeline-p)
-                     (not eshell-in-subcommand-p))))
-       (throw 'eshell-replace-command
-              (eshell-parse-command (concat "*" command)
-                                    (eshell-stringify-list
-                                     (flatten-tree args))))
-      (let* ((args (mapconcat 'identity
-                             (mapcar 'shell-quote-argument
-                                     (eshell-stringify-list
-                                      (flatten-tree args)))
-                             " "))
-            (cmd (format "%s -n %s" command args))
-            compilation-scroll-output)
-       (grep cmd)))))
+    (eshell-compile command (cons "-n" args)
+                    (and eshell-plain-grep-behavior
+                         'interactive)
+                     #'grep-mode)))
 
 (defun eshell/grep (&rest args)
   "Use Emacs grep facility instead of calling external grep."
@@ -816,8 +841,7 @@ external command."
 
 (defun eshell/glimpse (&rest args)
   "Use Emacs grep facility instead of calling external glimpse."
-  (let (null-device)
-    (eshell-grep "glimpse" (append '("-z" "-y") args))))
+  (eshell-grep "glimpse" (append '("-z" "-y") args)))
 
 ;; completions rules for some common UNIX commands
 
@@ -998,14 +1022,6 @@ Show wall-clock time elapsed during execution of 
COMMAND.")
   "Make \"whoami\" Tramp aware."
   (eshell-user-login-name))
 
-(defvar eshell-diff-window-config nil)
-
-(defun eshell-diff-quit ()
-  "Restore the window configuration previous to diff'ing."
-  (interactive)
-  (if eshell-diff-window-config
-      (set-window-configuration eshell-diff-window-config)))
-
 (defun eshell-nil-blank-string (string)
   "Return STRING, or nil if STRING contains only blank characters."
   (cond
@@ -1028,8 +1044,7 @@ Show wall-clock time elapsed during execution of 
COMMAND.")
          (throw 'eshell-replace-command
                 (eshell-parse-command "*diff" orig-args)))
       (let ((old (car (last args 2)))
-           (new (car (last args)))
-           (config (current-window-configuration)))
+            (new (car (last args))))
        (if (= (length args) 2)
            (setq args nil)
          (setcdr (last args 3) nil))
@@ -1041,18 +1056,6 @@ Show wall-clock time elapsed during execution of 
COMMAND.")
              (error
               (throw 'eshell-replace-command
                      (eshell-parse-command "*diff" orig-args))))
-         (when (fboundp 'diff-mode)
-           (add-hook
-            'compilation-finish-functions
-            (lambda (buff _msg)
-               (with-current-buffer buff
-                 (diff-mode)
-                  (setq-local eshell-diff-window-config config)
-                 (local-set-key [?q] #'eshell-diff-quit)
-                 (if (fboundp 'turn-on-font-lock-if-enabled)
-                     (turn-on-font-lock-if-enabled))
-                 (goto-char (point-min))))
-            nil t))
          (pop-to-buffer (current-buffer))))))
   nil)
 
@@ -1088,6 +1091,9 @@ Show wall-clock time elapsed during execution of 
COMMAND.")
 (put 'eshell/occur 'eshell-no-numeric-conversions t)
 
 (define-obsolete-function-alias 'nil-blank-string #'eshell-nil-blank-string 
"29.1")
+(defvar eshell-diff-window-config nil)
+(make-obsolete-variable 'eshell-diff-window-config "no longer used." "30.1")
+(define-obsolete-function-alias 'eshell-diff-quit #'ignore "30.1")
 
 (provide 'em-unix)
 
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el
index aa1e8f77ea5..26be1127880 100644
--- a/lisp/eshell/esh-arg.el
+++ b/lisp/eshell/esh-arg.el
@@ -541,7 +541,7 @@ If the form has no `type', the syntax is parsed as if 
`type' were
 (defun eshell-parse-delimiter ()
   "Parse an argument delimiter, which is essentially a command operator."
   ;; this `eshell-operator' keyword gets parsed out by
-  ;; `eshell-separate-commands'.  Right now the only possibility for
+  ;; `eshell-split-commands'.  Right now the only possibility for
   ;; error is an incorrect output redirection specifier.
   (when (looking-at "[&|;\n]\\s-*")
     (let ((end (match-end 0)))
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 94aa2ed8906..80066263396 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -364,8 +364,6 @@ This only returns external (non-Lisp) processes."
 
 ;; Command parsing
 
-(defvar eshell--sep-terms)
-
 (defmacro eshell-with-temp-command (region &rest body)
   "Narrow the buffer to REGION and execute the forms in BODY.
 
@@ -404,38 +402,33 @@ COMMAND can either be a string, or a cons cell 
demarcating a buffer
 region.  TOPLEVEL, if non-nil, means that the outermost command (the
 user's input command) is being parsed, and that pre and post command
 hooks should be run before and after the command."
-  (let* (eshell--sep-terms
-        (terms
-         (append
-          (if (consp command)
-              (eshell-parse-arguments (car command) (cdr command))
-             (eshell-with-temp-command command
-               (goto-char (point-max))
-               (eshell-parse-arguments (point-min) (point-max))))
-          args))
-        (commands
-         (mapcar
-           (lambda (cmd)
-             (setq cmd
-                   (if (or (not (car eshell--sep-terms))
-                           (string= (car eshell--sep-terms) ";"))
-                       (eshell-parse-pipeline cmd)
-                     `(eshell-do-subjob
-                       (cons :eshell-background
-                             ,(eshell-parse-pipeline cmd)))))
-             (setq eshell--sep-terms (cdr eshell--sep-terms))
-             (if eshell-in-pipeline-p
-                 cmd
-               `(eshell-trap-errors ,cmd)))
-          (eshell-separate-commands terms "[&;]" nil 'eshell--sep-terms))))
-    (let ((cmd commands))
-      (while cmd
-        ;; Copy I/O handles so each full statement can manipulate them
-        ;; if they like.  Steal the handles for the last command in
-        ;; the list; we won't use the originals again anyway.
-        (setcar cmd `(eshell-with-copied-handles
-                      ,(car cmd) ,(not (cdr cmd))))
-       (setq cmd (cdr cmd))))
+  (pcase-let*
+    ((terms
+      (append
+       (if (consp command)
+           (eshell-parse-arguments (car command) (cdr command))
+         (eshell-with-temp-command command
+           (goto-char (point-max))
+           (eshell-parse-arguments (point-min) (point-max))))
+       args))
+     (`(,sub-chains . ,sep-terms)
+      (eshell-split-commands terms "[&;]" nil t))
+     (commands
+      (mapcar
+       (lambda (cmd)
+         (let ((sep (pop sep-terms)))
+           (setq cmd (eshell-parse-pipeline cmd))
+           (when (equal sep "&")
+             (setq cmd `(eshell-do-subjob (cons :eshell-background ,cmd))))
+           (unless eshell-in-pipeline-p
+             (setq cmd `(eshell-trap-errors ,cmd)))
+           ;; Copy I/O handles so each full statement can manipulate
+           ;; them if they like.  Steal the handles for the last
+           ;; command in the list; we won't use the originals again
+           ;; anyway.
+           (setq cmd `(eshell-with-copied-handles ,cmd ,(not sep)))
+           cmd))
+       sub-chains)))
     (if toplevel
        `(eshell-commands (progn
                             (run-hooks 'eshell-pre-command-hook)
@@ -635,49 +628,40 @@ This means an exit code of 0."
 
 (defun eshell-parse-pipeline (terms)
   "Parse a pipeline from TERMS, return the appropriate Lisp forms."
-  (let* (eshell--sep-terms
-        (bigpieces (eshell-separate-commands terms "\\(&&\\|||\\)"
-                                             nil 'eshell--sep-terms))
-        (bp bigpieces)
-        (results (list t))
-        final)
-    (while bp
-      (let ((subterms (car bp)))
-       (let* ((pieces (eshell-separate-commands subterms "|"))
-              (p pieces))
-         (while p
-           (let ((cmd (car p)))
-             (run-hook-with-args 'eshell-pre-rewrite-command-hook cmd)
-             (setq cmd (run-hook-with-args-until-success
-                        'eshell-rewrite-command-hook cmd))
-             (let ((eshell--cmd cmd))
-               (run-hook-with-args 'eshell-post-rewrite-command-hook
-                                   'eshell--cmd)
-               (setq cmd eshell--cmd))
-             (setcar p (funcall eshell-post-rewrite-command-function cmd)))
-           (setq p (cdr p)))
-         (nconc results
-                (list
-                 (if (<= (length pieces) 1)
-                     (car pieces)
-                   (cl-assert (not eshell-in-pipeline-p))
-                   `(eshell-execute-pipeline (quote ,pieces))))))
-       (setq bp (cdr bp))))
+  (pcase-let*
+      ((`(,bigpieces . ,sep-terms)
+        (eshell-split-commands terms "\\(&&\\|||\\)" nil t))
+       (results) (final))
+    (dolist (subterms bigpieces)
+      (let* ((pieces (eshell-split-commands subterms "|"))
+             (p pieces))
+        (while p
+          (let ((cmd (car p)))
+            (run-hook-with-args 'eshell-pre-rewrite-command-hook cmd)
+            (setq cmd (run-hook-with-args-until-success
+                       'eshell-rewrite-command-hook cmd))
+            (let ((eshell--cmd cmd))
+              (run-hook-with-args 'eshell-post-rewrite-command-hook
+                                  'eshell--cmd)
+              (setq cmd eshell--cmd))
+            (setcar p (funcall eshell-post-rewrite-command-function cmd)))
+          (setq p (cdr p)))
+        (push (if (<= (length pieces) 1)
+                  (car pieces)
+                (cl-assert (not eshell-in-pipeline-p))
+                `(eshell-execute-pipeline (quote ,pieces)))
+              results)))
     ;; `results' might be empty; this happens in the case of
     ;; multi-line input
-    (setq results (cdr results)
-         results (nreverse results)
-         final (car results)
-         results (cdr results)
-         eshell--sep-terms (nreverse eshell--sep-terms))
+    (setq final (car results)
+          results (cdr results)
+          sep-terms (nreverse sep-terms))
     (while results
-      (cl-assert (car eshell--sep-terms))
+      (cl-assert (car sep-terms))
       (setq final (eshell-structure-basic-command
-                  'if (string= (car eshell--sep-terms) "&&") "if"
-                  `(eshell-protect ,(car results))
-                  `(eshell-protect ,final))
-           results (cdr results)
-           eshell--sep-terms (cdr eshell--sep-terms)))
+                   'if (string= (pop sep-terms) "&&") "if"
+                   `(eshell-protect ,(pop results))
+                   `(eshell-protect ,final))))
     final))
 
 (defun eshell-parse-subcommand-argument ()
@@ -712,6 +696,34 @@ This means an exit code of 0."
               (eshell-lisp-command (quote ,obj)))
          (ignore (goto-char here))))))
 
+(defun eshell-split-commands (terms separator &optional
+                                    reversed return-seps)
+  "Split TERMS using SEPARATOR.
+If REVERSED is non-nil, the list of separated term groups will be
+returned in reverse order.
+
+If RETURN-SEPS is nil, return just the separated terms as a list;
+otherwise, return both the separated terms and their separators
+as a pair of lists."
+  (let (sub-chains sub-terms sep-terms)
+    (dolist (term terms)
+      (if (and (eq (car-safe term) 'eshell-operator)
+               (string-match (concat "^" separator "$")
+                             (nth 1 term)))
+          (progn
+            (push (nth 1 term) sep-terms)
+            (push (nreverse sub-terms) sub-chains)
+            (setq sub-terms nil))
+        (push term sub-terms)))
+    (when sub-terms
+      (push (nreverse sub-terms) sub-chains))
+    (unless reversed
+      (setq sub-chains (nreverse sub-chains)
+            sep-terms (nreverse sep-terms)))
+    (if return-seps
+        (cons sub-chains sep-terms)
+      sub-chains)))
+
 (defun eshell-separate-commands (terms separator &optional
                                       reversed last-terms-sym)
   "Separate TERMS using SEPARATOR.
@@ -719,30 +731,14 @@ If REVERSED is non-nil, the list of separated term groups 
will be
 returned in reverse order.  If LAST-TERMS-SYM is a symbol, its value
 will be set to a list of all the separator operators found (or (nil)
 if none)."
-  (let ((sub-terms (list t))
-       (eshell-sep-terms (list t))
-       subchains)
-    (while terms
-      (if (and (consp (car terms))
-              (eq (caar terms) 'eshell-operator)
-              (string-match (concat "^" separator "$")
-                            (nth 1 (car terms))))
-         (progn
-           (nconc eshell-sep-terms (list (nth 1 (car terms))))
-           (setq subchains (cons (cdr sub-terms) subchains)
-                 sub-terms (list t)))
-       (nconc sub-terms (list (car terms))))
-      (setq terms (cdr terms)))
-    (if (> (length sub-terms) 1)
-       (setq subchains (cons (cdr sub-terms) subchains)))
-    (if reversed
-       (progn
-         (if last-terms-sym
-             (set last-terms-sym (reverse (cdr eshell-sep-terms))))
-         subchains)                    ; already reversed
-      (if last-terms-sym
-         (set last-terms-sym (cdr eshell-sep-terms)))
-      (nreverse subchains))))
+  (declare (obsolete eshell-split-commands "30.1"))
+  (let ((split-terms (eshell-split-commands terms separator reversed
+                                            last-terms-sym)))
+    (if last-terms-sym
+        (progn
+          (set last-terms-sym (cdr split-terms))
+          (car split-terms))
+      split-terms)))
 
 ;;_* Command evaluation macros
 ;;
diff --git a/lisp/faces.el b/lisp/faces.el
index 8017f5fa65e..1a446aacacd 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -1540,15 +1540,12 @@ argument, prompt for a regular expression using 
`read-regexp'."
 ;;; Face specifications (defface).
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-;; Parameter FRAME Is kept for call compatibility to with previous
-;; face implementation.
-
 (defun face-attr-construct (face &optional _frame)
   "Return a `defface'-style attribute list for FACE.
 Value is a property list of pairs ATTRIBUTE VALUE for all specified
 face attributes of FACE where ATTRIBUTE is the attribute name and
-VALUE is the specified value of that attribute.
-Argument FRAME is ignored and retained for compatibility."
+VALUE is the specified value of that attribute."
+  (declare (advertised-calling-convention (face) "30.1"))
   (let (result)
     (dolist (entry face-attribute-name-alist result)
       (let* ((attribute (car entry))
diff --git a/lisp/ffap.el b/lisp/ffap.el
index 57f5271708b..907f56763ff 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -558,10 +558,6 @@ Looks at `ffap-ftp-default-user', returns \"\" for 
\"localhost\"."
    (ffap-ftp-regexp (ffap-host-to-filename mach))
    ))
 
-(defvaralias 'ffap-newsgroup-regexp 'thing-at-point-newsgroup-regexp)
-(defvaralias 'ffap-newsgroup-heads  'thing-at-point-newsgroup-heads)
-(defalias 'ffap-newsgroup-p 'thing-at-point-newsgroup-p)
-
 (defun ffap-url-p (string)
   "If STRING looks like an URL, return it (maybe improved), else nil."
   (when (and (stringp string) ffap-url-regexp)
@@ -2144,6 +2140,10 @@ Of course if you do not like these bindings, just roll 
your own!")
   (interactive)
   (eval (cons 'progn ffap-bindings)))
 
+(define-obsolete-variable-alias 'ffap-newsgroup-regexp 
'thing-at-point-newsgroup-regexp "30.1")
+(define-obsolete-variable-alias 'ffap-newsgroup-heads  
'thing-at-point-newsgroup-heads "30.1")
+(define-obsolete-function-alias 'ffap-newsgroup-p #'thing-at-point-newsgroup-p 
"30.1")
+
 
 (provide 'ffap)
 
diff --git a/lisp/files.el b/lisp/files.el
index 7248a439ad5..26fd1eee5d7 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1998,6 +1998,8 @@ INHIBIT-BUFFER-HOOKS non-nil.
 Note: Be careful with let-binding this hook considering it is
 frequently used for cleanup.")
 
+(defvar find-alternate-file-dont-kill-client nil
+  "If non-nil, `server-buffer-done' should not delete the client.")
 (defun find-alternate-file (filename &optional wildcards)
   "Find file FILENAME, select its buffer, kill previous buffer.
 If the current buffer now contains an empty file that you just visited
@@ -2044,7 +2046,8 @@ killed."
     ;; save a modified buffer visiting a file.  Rather, `kill-buffer'
     ;; asks that itself.  Thus, there's no need to temporarily do
     ;; `(set-buffer-modified-p nil)' before running this hook.
-    (run-hooks 'kill-buffer-hook)
+    (let ((find-alternate-file-dont-kill-client 'dont-kill-client))
+      (run-hooks 'kill-buffer-hook))
     ;; Okay, now we can end-of-life the old buffer.
     (if (get-buffer " **lose**")
        (kill-buffer " **lose**"))
@@ -5873,8 +5876,10 @@ Before and after saving the buffer, this function runs
                     buffer-file-name)))
                  (setq tempsetmodes t)
                (error "Attempt to save to a file that you aren't allowed to 
write"))))))
-    (or buffer-backed-up
-       (setq setmodes (backup-buffer)))
+    (with-demoted-errors
+        "Backing up buffer: %s"
+      (or buffer-backed-up
+         (setq setmodes (backup-buffer))))
     (let* ((dir (file-name-directory buffer-file-name))
            (dir-writable (file-writable-p dir)))
       (if (or (and file-precious-flag dir-writable)
@@ -6374,7 +6379,8 @@ With a prefix argument, TRASH is nil."
                      (null current-prefix-arg)))
   (if (and (file-directory-p filename) (not (file-symlink-p filename)))
       (signal 'file-error (list "Removing old name: is a directory" filename)))
-  (let* ((handler (find-file-name-handler filename 'delete-file)))
+  (let* ((filename (expand-file-name filename))
+         (handler (find-file-name-handler filename 'delete-file)))
     (cond (handler (funcall handler 'delete-file filename trash))
           ((and delete-by-moving-to-trash trash) (move-file-to-trash filename))
           (t (delete-file-internal filename)))))
@@ -6761,7 +6767,10 @@ This function binds `revert-buffer-in-progress-p' 
non-nil while it operates.
 This function calls the function that `revert-buffer-function' specifies
 to do the work, with arguments IGNORE-AUTO and NOCONFIRM.
 The default function runs the hooks `before-revert-hook' and
-`after-revert-hook'
+`after-revert-hook'.
+Return value is whatever `revert-buffer-function' returns.  For historical
+reasons, that return value is non-nil when `revert-buffer-function'
+succeeds in its job and returns non-nil.
 
 Reverting a buffer will try to preserve markers in the buffer,
 but it cannot always preserve all of them.  For better results,
@@ -6778,17 +6787,20 @@ preserve markers and overlays, at the price of being 
slower."
         (revert-buffer-preserve-modes preserve-modes)
         (state (and (boundp 'read-only-mode--state)
                     (list read-only-mode--state))))
-    (funcall (or revert-buffer-function #'revert-buffer--default)
-             ignore-auto noconfirm)
-    (when state
-      (setq buffer-read-only (car state))
-      (setq-local read-only-mode--state (car state)))))
+    ;; Return whatever 'revert-buffer-function' returns.
+    (prog1 (funcall (or revert-buffer-function #'revert-buffer--default)
+                    ignore-auto noconfirm)
+      (when state
+        (setq buffer-read-only (car state))
+        (setq-local read-only-mode--state (car state))))))
 
 (defun revert-buffer--default (ignore-auto noconfirm)
   "Default function for `revert-buffer'.
 The arguments IGNORE-AUTO and NOCONFIRM are as described for `revert-buffer'.
 Runs the hooks `before-revert-hook' and `after-revert-hook' at the
 start and end.
+The function returns non-nil if it reverts the buffer; signals
+an error if the buffer is not associated with a file.
 
 Calls `revert-buffer-insert-file-contents-function' to reread the
 contents of the visited file, with two arguments: the first is the file
@@ -6896,9 +6908,9 @@ an auto-save file."
       (if revert-buffer-preserve-modes
           (let ((buffer-file-format buffer-file-format))
             (insert-file-contents file-name (not auto-save-p)
-                                  nil nil t))
+                                  nil nil 'if-regular))
         (insert-file-contents file-name (not auto-save-p)
-                              nil nil t))))))
+                              nil nil 'if-regular))))))
 
 (defvar revert-buffer-with-fine-grain-max-seconds 2.0
   "Maximum time that `revert-buffer-with-fine-grain' should use.
@@ -7742,7 +7754,6 @@ If DIR's free space cannot be obtained, this function 
returns nil."
       (if avail
           (funcall byte-count-to-string-function avail)))))
 
-;; The following expression replaces `dired-move-to-filename-regexp'.
 (defvar directory-listing-before-filename-regexp
   (let* ((l "\\([A-Za-z]\\|[^\0-\177]\\)")
         (l-or-quote "\\([A-Za-z']\\|[^\0-\177]\\)")
@@ -8547,7 +8558,7 @@ the leading `-' character."
 (defun file-modes-symbolic-to-number (modes &optional from)
   "Convert symbolic file modes to numeric file modes.
 MODES is the string to convert, it should match
-\"[ugoa]*([+-=][rwxXstugo]*)+,...\".
+\"[ugoa]*([+=-][rwxXstugo]*)+,...\".
 See Info node `(coreutils)File permissions' for more information on this
 notation.
 FROM (or 0 if nil) gives the mode bits on which to base permissions if
diff --git a/lisp/finder.el b/lisp/finder.el
index 5aec0149b89..f5bf2641537 100644
--- a/lisp/finder.el
+++ b/lisp/finder.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1992-2023 Free Software Foundation, Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Created: 16 Jun 1992
 ;; Keywords: help
 
diff --git a/lisp/gnus/nnspool.el b/lisp/gnus/nnspool.el
index 3508c388897..ca97afcb7f1 100644
--- a/lisp/gnus/nnspool.el
+++ b/lisp/gnus/nnspool.el
@@ -35,7 +35,7 @@
 ;; It's only used to init nnspool-spool-directory, so why not just
 ;; set that variable's default directly?
 (eval-and-compile
-  (defvaralias 'news-path 'news-directory)
+  (define-obsolete-variable-alias 'news-path 'news-directory "30.1")
   (defvar news-directory (if (file-exists-p "/usr/spool/news/")
                             "/usr/spool/news/"
                           "/var/spool/news/")
@@ -62,9 +62,7 @@ This is most commonly `inews' or `injnews'.")
 If you are using Cnews, you probably should set this variable to nil.")
 
 (defvoo nnspool-spool-directory
-    (file-name-as-directory (if (boundp 'news-directory)
-                               (symbol-value 'news-directory)
-                             news-path))
+    (file-name-as-directory news-directory)
   "Local news spool directory.")
 
 (defvoo nnspool-nov-directory (concat nnspool-spool-directory "over.view/")
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index fc8f431fd11..11854680dc2 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -152,6 +152,12 @@ edited even if this option is enabled."
   :group 'help
   :version "28.1")
 
+(defcustom help-display-function-type t
+  "If non-nil, display the type of a function when available."
+  :type 'boolean
+  :group 'help
+  :version "30.1")
+
 (defun help--symbol-class (s)
   "Return symbol class characters for symbol S."
   (when (stringp s)
@@ -229,11 +235,11 @@ interactive command."
                (lambda (f) (if want-command
                           (commandp f)
                         (or (fboundp f) (get f 'function-documentation))))
-               ;; We use 'confirm' here, unlike in other describe-*
-               ;; commands, for cases like a function that is advised
-               ;; but not yet defined (e.g., if 'advice-add' is called
-               ;; before defining the function).
-               'confirm nil nil
+               ;; We used `confirm' for a while because we may want to see the
+               ;; meta-info about a function even if the function itself is not
+               ;; defined, but this use case is too marginal and rarely tested,
+               ;; not worth the trouble (bug#64902).
+               t nil nil
                (and fn (symbol-name fn)))))
     (unless (equal val "")
       (setq fn (intern val)))
@@ -715,7 +721,8 @@ the C sources, too."
           (unless (and (symbolp function)
                        (get function 'reader-construct))
             (insert high-usage "\n")
-            (when-let* ((res (comp-function-type-spec function))
+            (when-let* ((gate help-display-function-type)
+                        (res (comp-function-type-spec function))
                         (type-spec (car res))
                         (kind (cdr res)))
               (insert (format
diff --git a/lisp/help.el b/lisp/help.el
index 6f55136049b..f522cfac2a1 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1493,7 +1493,7 @@ If PREFIX is non-nil, mention only keys that start with 
PREFIX.
 If TITLE is non-nil, is a string to insert at the beginning.
 TITLE should not end with a colon or a newline; we supply that.
 
-If NOMENU is non-nil, then omit menu-bar commands.
+If NO-MENU is non-nil, then omit menu-bar commands.
 
 If TRANSL is non-nil, the definitions are actually key
 translations so print strings and vectors differently.
diff --git a/lisp/ielm.el b/lisp/ielm.el
index b45db3ec97e..f7d025b8c01 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -148,9 +148,8 @@ such as `edebug-defun' to work with such inputs."
 This variable is buffer-local.")
 
 (defvar ielm-header
-  (substitute-command-keys
    "*** Welcome to IELM ***  Type (describe-mode) or press \
-\\[describe-mode] for help.\n")
+\\[describe-mode] for help.\n"
   "Message to display when IELM is started.")
 
 (defvaralias 'inferior-emacs-lisp-mode-map 'ielm-map)
@@ -622,7 +621,7 @@ Customized bindings may be defined in `ielm-map', which 
currently contains:
     (setq-local comint-inhibit-carriage-motion t)
 
     ;; Add a silly header
-    (insert ielm-header)
+    (insert (substitute-command-keys ielm-header))
     (ielm-set-pm (point-max))
     (unless comint-use-prompt-regexp
       (let ((inhibit-read-only t))
diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el
index 9a92cae8ad5..8e2e4c6f644 100644
--- a/lisp/image/image-dired.el
+++ b/lisp/image/image-dired.el
@@ -770,6 +770,24 @@ On reaching end or beginning of buffer, stop and show a 
message."
   (interactive nil image-dired-thumbnail-mode)
   (image-dired--movement-command (pos-eol) 'reverse))
 
+(defun image-dired-scroll (&optional down)
+  "Scroll in the thumbnail buffer."
+  (let ((goal-column (current-column)))
+    (if down (scroll-down) (scroll-up))
+    (move-to-column goal-column)
+    (image-dired--movement-ensure-point-pos down)
+    (when image-dired-track-movement
+      (image-dired-track-original-file))
+    (image-dired--update-header-line)))
+
+(defun image-dired-scroll-up ()
+  (interactive nil image-dired-thumbnail-mode)
+  (image-dired-scroll))
+
+(defun image-dired-scroll-down ()
+  (interactive nil image-dired-thumbnail-mode)
+  (image-dired-scroll 'down))
+
 
 ;;; Header line
 
@@ -980,6 +998,8 @@ You probably want to use this together with
   "<remap> <end-of-buffer>"          #'image-dired-end-of-buffer
   "<remap> <move-beginning-of-line>" #'image-dired-move-beginning-of-line
   "<remap> <move-end-of-line>"       #'image-dired-move-end-of-line
+  "<remap> <scroll-up-command>"      #'image-dired-scroll-up
+  "<remap> <scroll-down-command>"    #'image-dired-scroll-down
 
   :menu
   '("Image-Dired"
diff --git a/lisp/indent-aux.el b/lisp/indent-aux.el
new file mode 100644
index 00000000000..ed41d4926f7
--- /dev/null
+++ b/lisp/indent-aux.el
@@ -0,0 +1,76 @@
+;;; indent-aux.el --- Autoloaded indentation commands for Emacs  -*- 
lexical-binding:t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; Maintainer: emacs-devel@gnu.org
+;; 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:
+
+;; Autoloaded commands for making and changing indentation in text and
+;; killed text
+
+;;; Code:
+
+
+
+;; Indent Filter mode.  When enabled, this minor mode filters all
+;; killed text to remove leading indentation.
+
+(defun kill-ring-deindent-buffer-substring-function (beg end delete)
+  "Save the text within BEG and END to kill-ring, decreasing indentation.
+Delete the saved text if DELETE is non-nil.
+
+In the saved copy of the text, remove some of the indentation, such
+that the buffer position at BEG will be at column zero when the text
+is yanked."
+  (let ((a beg)
+        (b end))
+    (setq beg (min a b)
+          end (max a b)))
+  (let ((indentation (save-excursion (goto-char beg)
+                                     (current-column)))
+        (text (if delete
+                  (delete-and-extract-region beg end)
+                (buffer-substring beg end))))
+    (with-temp-buffer
+      (insert text)
+      (indent-rigidly (point-min) (point-max)
+                      (- indentation))
+      (buffer-string))))
+
+;;;###autoload
+(define-minor-mode kill-ring-deindent-mode
+  "Toggle removal of indentation from text saved to the kill ring.
+
+When this minor mode is enabled, text saved into the kill ring is
+indented towards the left by the column number at the start of
+that text."
+  :global 't
+  :group 'killing
+  (if kill-ring-deindent-mode
+      (add-function :override filter-buffer-substring-function
+                    #'kill-ring-deindent-buffer-substring-function
+                    '(:depth 100))
+    (remove-function filter-buffer-substring-function
+                     #'kill-ring-deindent-buffer-substring-function)))
+
+
+
+(provide 'indent-aux)
+;;; indent-aux.el ends here.
diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..463aea93376 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -1587,7 +1587,7 @@ escaped (\\\",\\\\)."
   (let ((start 0)
        (parameter-alist))
     (while (string-match
-           "\\s *\\([^=]+\\)=\\(?:\\([^\\s 
\"]+\\)\\|\\(?:\"\\(\\(?:[^\\\"]\\|\\\\[\\\"]\\)*\\)\"\\)\\)"
+           "\\s 
*\\([^=]+\\)=\\(?:\\([^\"[:space:]]+\\)\\|\\(?:\"\\(\\(?:[^\\\"]\\|\\\\[\\\"]\\)*\\)\"\\)\\)"
            parameter-string start)
       (setq start (match-end 0))
       (push (cons (match-string 1 parameter-string)
diff --git a/lisp/international/iso-transl.el b/lisp/international/iso-transl.el
index 80f14f3e8cb..459d1ff7f97 100644
--- a/lisp/international/iso-transl.el
+++ b/lisp/international/iso-transl.el
@@ -203,11 +203,15 @@
     ("^I"   . [?Î])
     ("^O"   . [?Ô])
     ("^U"   . [?Û])
+    ("^W"   . [?Ŵ])
+    ("^Y"   . [?Ŷ])
     ("^a"   . [?â])
     ("^e"   . [?ê])
     ("^i"   . [?î])
     ("^o"   . [?ô])
     ("^u"   . [?û])
+    ("^w"   . [?ŵ])
+    ("^y"   . [?ŷ])
     ("^^A"  . [?Ǎ])
     ("^^C"  . [?Č])
     ("^^E"  . [?Ě])
diff --git a/lisp/isearch.el b/lisp/isearch.el
index daf884d3d53..4d231fba469 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1342,10 +1342,14 @@ used to set the value of `isearch-regexp-function'."
 
   ;; If the keyboard is not up and the last event did not come from
   ;; a keyboard, bring it up so that the user can type.
-  (when (or (not last-event-frame)
-            (not (eq (device-class last-event-frame
-                                   last-event-device)
-                     'keyboard)))
+  ;;
+  ;; last-event-frame may be `macro', since people apparently make use
+  ;; of I-search in keyboard macros.  (bug#65175)
+  (when (and (not (eq last-event-frame 'macro))
+             (or (not last-event-frame)
+                 (not (eq (device-class last-event-frame
+                                        last-event-device)
+                          'keyboard))))
     (frame-toggle-on-screen-keyboard (selected-frame) nil))
 
   ;; Disable text conversion so that isearch can behave correctly.
@@ -4667,6 +4671,7 @@ CASE-FOLD non-nil means the search was case-insensitive."
        isearch-message message
        isearch-case-fold-search case-fold)
   (isearch-search)
+  (isearch-push-state)
   (isearch-update))
 
 
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 7489076ea2e..588b2d14943 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -1189,7 +1189,10 @@ following additional answers: `insert', `insert-1', 
`replace', `replace-1',
        (setq act (lookup-key kmacro-step-edit-map
                              (vector (with-current-buffer (current-buffer) 
(read-event))))))))
 
-    ;; Resume macro execution and perform the action
+    ;; Resume macro execution and perform the action.
+    ;; Suffixing executing-kbd-macro with `dummy-event'
+    ;; is done when pre-command-hook must be called
+    ;; again as part of this keyboard macro's execution.
     (cond
      ((cond
        ((eq act 'act)
@@ -1220,18 +1223,21 @@ following additional answers: `insert', `insert-1', 
`replace', `replace-1',
        ((member act '(replace-1 replace))
        (setq kmacro-step-edit-inserting (if (eq act 'replace-1) 1 t))
        (if (= executing-kbd-macro-index (length executing-kbd-macro))
-           (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
+           (setq executing-kbd-macro (vconcat executing-kbd-macro
+                                               [dummy-event])
                  kmacro-step-edit-appending t))
        nil)
        ((eq act 'append)
        (setq kmacro-step-edit-inserting t)
        (if (= executing-kbd-macro-index (length executing-kbd-macro))
-           (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
+           (setq executing-kbd-macro (vconcat executing-kbd-macro
+                                               [dummy-event])
                  kmacro-step-edit-appending t))
        t)
        ((eq act 'append-end)
        (if (= executing-kbd-macro-index (length executing-kbd-macro))
-           (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
+           (setq executing-kbd-macro (vconcat executing-kbd-macro
+                                               [dummy-event])
                  kmacro-step-edit-inserting t
                  kmacro-step-edit-appending t)
          (setq kmacro-step-edit-active 'append-end))
@@ -1314,7 +1320,8 @@ following additional answers: `insert', `insert-1', 
`replace', `replace-1',
       (setq this-command #'ignore))
      ((eq kmacro-step-edit-active 'append-end)
       (if (= executing-kbd-macro-index (length executing-kbd-macro))
-         (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
+         (setq executing-kbd-macro (vconcat executing-kbd-macro
+                                             [dummy-event])
                kmacro-step-edit-inserting t
                kmacro-step-edit-appending t
                kmacro-step-edit-active t)))
diff --git a/lisp/language/tibetan.el b/lisp/language/tibetan.el
index 31ff37016fe..21b3fc03417 100644
--- a/lisp/language/tibetan.el
+++ b/lisp/language/tibetan.el
@@ -126,6 +126,7 @@
 ;;; Definitions of conversion data.
 ;;;
 
+(eval-and-compile
 
 ;;; alists for tibetan char <-> transcription conversion
 ;;; longer transcription should come first
@@ -333,6 +334,7 @@
 
 
 (defconst tibetan-subjoined-transcription-alist
+ (eval-when-compile
   (sort
    (copy-sequence
        '(("+k"  . "ྐ")
@@ -381,7 +383,7 @@
          ("+Y" . "ྻ") ;; fixed form subscribed YA
          ("+R" . "ྼ") ;; fixed form subscribed RA
          ))
-   (lambda (x y) (> (length (car x)) (length (car y))))))
+   (lambda (x y) (> (length (car x)) (length (car y)))))))
 
 ;;;
 ;;; alist for Tibetan base consonant <-> subjoined consonant conversion.
@@ -557,32 +559,34 @@
     ("སྦ" . "����")
     ("སྨ" . "����")))
 
+)   ; eval-and-compile
+
 (defconst tibetan-regexp
-  (mapconcat (lambda (x) (regexp-quote (car x)))
-             (append tibetan-precomposed-transcription-alist
-                    tibetan-consonant-transcription-alist
-                    tibetan-vowel-transcription-alist
-                    tibetan-modifier-transcription-alist
-                    tibetan-subjoined-transcription-alist)
-             "\\|")
+  (eval-when-compile
+    (regexp-opt (mapcar #'car
+                        (append tibetan-precomposed-transcription-alist
+                               tibetan-consonant-transcription-alist
+                               tibetan-vowel-transcription-alist
+                               tibetan-modifier-transcription-alist
+                               tibetan-subjoined-transcription-alist))))
   "Regexp matching a Tibetan transcription of a composable Tibetan sequence.
 The result of matching is to be used for indexing alists at conversion
 from a roman transcription to the corresponding Tibetan character.")
 
 (defvar tibetan-precomposed-regexp
   (purecopy
-   (concat "^\\("
-           (mapconcat #'car tibetan-precomposed-transcription-alist "\\|")
-           "\\)"))
+   (eval-when-compile
+     (concat "^"
+             (regexp-opt (mapcar #'car tibetan-precomposed-transcription-alist)
+                         t))))
   "Regexp string to match a romanized Tibetan complex consonant.
 The result of matching is to be used for indexing alists when the input key
 from an input method is converted to the corresponding precomposed glyph.")
 
 (defvar tibetan-precomposition-rule-regexp
   (purecopy
-   (concat "\\("
-           (mapconcat #'car tibetan-precomposition-rule-alist "\\|")
-           "\\)"))
+   (eval-when-compile
+     (regexp-opt (mapcar #'car tibetan-precomposition-rule-alist) t)))
   "Regexp string to match a sequence of Tibetan consonantic components.
 That is, one base consonant and one or more subjoined consonants.
 The result of matching is to be used for indexing alist when the component
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index 898dcd55f58..f062f3bf8de 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -302,6 +302,7 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] 
FLAG...)
 (fn FUNCTION ARGS &rest BODY)" nil t)
 (function-put 'defadvice 'doc-string-elt 3)
 (function-put 'defadvice 'lisp-indent-function 2)
+(make-obsolete 'defadvice '"use advice-add or define-advice" "30.1")
 (register-definition-prefixes "advice" '("ad-"))
 
 
@@ -2544,6 +2545,13 @@ The optional argument NEW-WINDOW is not used.
 Browse URL with the system default browser.
 Default to the URL around or before point.
 
+(fn URL &optional NEW-WINDOW)" t)
+(autoload 'browse-url-default-android-browser "browse-url" "\
+Browse URL with the system default browser.
+If `browse-url-android-share' is non-nil, try to share URL using
+an external program instead.  Default to the URL around or before
+point.
+
 (fn URL &optional NEW-WINDOW)" t)
 (autoload 'browse-url-emacs "browse-url" "\
 Ask Emacs to load URL into a buffer and show it in another window.
@@ -4645,12 +4653,6 @@ But if you just want to print something, don't call this 
directly:
 call other entry points instead, such as `cl-prin1'.
 
 (fn OBJECT STREAM)")
-(autoload 'cl-print-expand-ellipsis "cl-print" "\
-Print the expansion of an ellipsis to STREAM.
-VALUE should be the value of the `cl-print-ellipsis' text property
-which was attached to the ellipsis by `cl-prin1'.
-
-(fn VALUE STREAM)")
 (autoload 'cl-prin1 "cl-print" "\
 Print OBJECT on STREAM according to its type.
 Output is further controlled by the variables
@@ -4671,13 +4673,12 @@ characters with appropriate settings of `print-level' 
and
 the arguments VALUE and STREAM and which should respect
 `print-length' and `print-level'.  LIMIT may be nil or zero in
 which case PRINT-FUNCTION will be called with `print-level' and
-`print-length' bound to nil.
+`print-length' bound to nil, and it can also be t in which case
+PRINT-FUNCTION will be called with the current values of `print-level'
+and `print-length'.
 
 Use this function with `cl-prin1' to print an object,
-abbreviating it with ellipses to fit within a size limit.  Use
-this function with `cl-prin1-expand-ellipsis' to expand an
-ellipsis, abbreviating the expansion to stay within a size
-limit.
+abbreviating it with ellipses to fit within a size limit.
 
 (fn PRINT-FUNCTION VALUE LIMIT)")
 (register-definition-prefixes "cl-print" '("cl-print-" "help-byte-code"))
@@ -4873,6 +4874,36 @@ The files to be removed are those produced from the 
original source
 filename (including FILE).
 
 (fn FILE)")
+(autoload 'native--compile-async "comp" "\
+Compile FILES asynchronously.
+FILES is one filename or a list of filenames or directories.
+
+If optional argument RECURSIVELY is non-nil, recurse into
+subdirectories of given directories.
+
+If optional argument LOAD is non-nil, request to load the file
+after compiling.
+
+The optional argument SELECTOR has the following valid values:
+
+nil -- Select all files.
+a string -- A regular expression selecting files with matching names.
+a function -- A function selecting files with matching names.
+
+The variable `native-comp-async-jobs-number' specifies the number
+of (commands) to run simultaneously.
+
+LOAD can also be the symbol `late'.  This is used internally if
+the byte code has already been loaded when this function is
+called.  It means that we request the special kind of load
+necessary in that situation, called \"late\" loading.
+
+During a \"late\" load, instead of executing all top-level forms
+of the original files, only function definitions are
+loaded (paying attention to have these effective only if the
+bytecode definition was not changed in the meantime).
+
+(fn FILES &optional RECURSIVELY LOAD SELECTOR)")
 (autoload 'comp-lookup-eln "comp" "\
 Given a Lisp source FILENAME return the corresponding .eln file if found.
 Search happens in `native-comp-eln-load-path'.
@@ -4939,7 +4970,7 @@ inferred from the code itself by the native compiler; if 
it is
 `know', the type specifier comes from `comp-known-type-specifiers'.
 
 (fn FUNCTION)")
-(register-definition-prefixes "comp" '("comp-" "make-comp-edge" "native-" 
"no-native-compile"))
+(register-definition-prefixes "comp" '("comp-" "make-comp-edge" "native-comp" 
"no-native-compile"))
 
 
 ;;; Generated autoloads from cedet/semantic/wisent/comp.el
@@ -5638,7 +5669,7 @@ Run `perldoc' on WORD.
 (fn WORD)" t)
 (autoload 'cperl-perldoc-at-point "cperl-mode" "\
 Run a `perldoc' on the word around point." t)
-(register-definition-prefixes "cperl-mode" '("cperl-"))
+(register-definition-prefixes "cperl-mode" '("cperl-" "imenu-max-items"))
 
 
 ;;; Generated autoloads from progmodes/cpp.el
@@ -8171,7 +8202,6 @@ Switch to *dungeon* buffer and start game." t)
 
 ;;; Generated autoloads from emacs-lisp/easy-mmode.el
 
-(defalias 'easy-mmode-define-minor-mode #'define-minor-mode)
 (autoload 'define-minor-mode "easy-mmode" "\
 Define a new minor mode MODE.
 This defines the toggle command MODE and (by default) a control variable
@@ -8246,7 +8276,6 @@ INIT-VALUE LIGHTER KEYMAP.
 (fn MODE DOC [KEYWORD VAL ... &rest BODY])" nil t)
 (function-put 'define-minor-mode 'doc-string-elt 2)
 (function-put 'define-minor-mode 'lisp-indent-function 'defun)
-(defalias 'easy-mmode-define-global-mode #'define-globalized-minor-mode)
 (defalias 'define-global-minor-mode #'define-globalized-minor-mode)
 (autoload 'define-globalized-minor-mode "easy-mmode" "\
 Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE.
@@ -8254,14 +8283,17 @@ TURN-ON is a function that will be called with no args 
in every buffer
 and that should try to turn MODE on if applicable for that buffer.
 
 Each of KEY VALUE is a pair of CL-style keyword arguments.
-The :predicate argument specifies in which major modes should the
+The :predicate key specifies in which major modes should the
 globalized minor mode be switched on.  The value should be t (meaning
 switch on the minor mode in all major modes), nil (meaning don't
 switch on in any major mode), a list of modes (meaning switch on only
 in those modes and their descendants), or a list (not MODES...),
 meaning switch on in any major mode except MODES.  The value can also
 mix all of these forms, see the info node `Defining Minor Modes' for
-details.
+details.  The :predicate key causes the macro to create a user option
+named the same as MODE, but ending with \"-modes\" instead of \"-mode\".
+That user option can then be used to customize in which modes this
+globalized minor mode will be switched on.
 As the minor mode defined by this function is always global, any
 :global keyword is ignored.
 Other keywords have the same meaning as in `define-minor-mode',
@@ -8325,6 +8357,8 @@ CSS contains a list of syntax specifications of the form 
(CHAR . SYNTAX).
 (fn ST CSS DOC &rest ARGS)" nil t)
 (function-put 'easy-mmode-defsyntax 'doc-string-elt 3)
 (function-put 'easy-mmode-defsyntax 'lisp-indent-function 1)
+(define-obsolete-function-alias 'easy-mmode-define-minor-mode 
#'define-minor-mode "30.1")
+(define-obsolete-function-alias 'easy-mmode-define-global-mode 
#'define-globalized-minor-mode "30.1")
 (register-definition-prefixes "easy-mmode" '("easy-mmode-"))
 
 
@@ -8633,7 +8667,7 @@ A second call of this function without changing point 
inserts the next match.
 A call with prefix PREFIX reads the symbol to insert from the minibuffer with
 completion.
 
-(fn PREFIX)" '("P"))
+(fn PREFIX)" t)
 (autoload 'ebrowse-tags-loop-continue "ebrowse" "\
 Repeat last operation on files in tree.
 FIRST-TIME non-nil means this is not a repetition, but the first time.
@@ -10234,6 +10268,9 @@ Look at CONFIG and try to expand GROUP.
 (autoload 'erc-select-read-args "erc" "\
 Prompt the user for values of nick, server, port, and password.
 With prefix arg, also prompt for user and full name.")
+(autoload 'erc-server-select "erc" "\
+Interactively connect to a server from `erc-server-alist'." t)
+(make-obsolete 'erc-server-select 'erc-tls "30.1")
 (autoload 'erc "erc" "\
 ERC is a powerful, modular, and extensible IRC client.
 This function is the main entry point for ERC.
@@ -10259,7 +10296,7 @@ for the values of the other parameters.
 
 See `erc-tls' for the meaning of ID.
 
-(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME ID)" 
'((erc-select-read-args)))
+(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME ID)" t)
 (defalias 'erc-select #'erc)
 (autoload 'erc-tls "erc" "\
 ERC is a powerful, modular, and extensible IRC client.
@@ -10307,7 +10344,7 @@ See Info node `(erc) Network Identifier' for details.  
Like
 CLIENT-CERTIFICATE, this parameter cannot be specified
 interactively.
 
-(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME CLIENT-CERTIFICATE ID)" 
'((let ((erc-default-port erc-default-port-tls)) (erc-select-read-args))))
+(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME CLIENT-CERTIFICATE ID)" t)
 (autoload 'erc-handle-irc-url "erc" "\
 Use ERC to IRC on HOST:PORT in CHANNEL.
 If ERC is already connected to HOST:PORT, simply /join CHANNEL.
@@ -10432,11 +10469,14 @@ Return the name of the network or \"Unknown\" as a 
symbol.
 Use the server parameter NETWORK if provided, otherwise parse the
 server name and search for a match in `erc-networks-alist'.")
 (make-obsolete 'erc-determine-network '"maybe see `erc-networks--determine'" 
"29.1")
-(autoload 'erc-server-select "erc-networks" "\
-Interactively select a server to connect to using `erc-server-alist'." t)
 (register-definition-prefixes "erc-networks" '("erc-"))
 
 
+;;; Generated autoloads from erc/erc-nicks.el
+
+(register-definition-prefixes "erc-nicks" '("erc-nicks-"))
+
+
 ;;; Generated autoloads from erc/erc-notify.el
 
 (register-definition-prefixes "erc-notify" '("erc-"))
@@ -10536,7 +10576,9 @@ it has to be wrapped in `(eval (quote ...))'.
 If NAME is already defined as a test and Emacs is running
 in batch mode, an error is signaled.
 
-(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] 
BODY...)" nil 'macro)
+(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] 
BODY...)" nil t)
+(function-put 'ert-deftest 'doc-string-elt 3)
+(function-put 'ert-deftest 'lisp-indent-function 2)
 (autoload 'ert-run-tests-batch "ert" "\
 Run the tests specified by SELECTOR, printing results to the terminal.
 
@@ -14830,9 +14872,8 @@ to specify a command to run.
 If CONFIRM is non-nil, the user will be given an opportunity to edit the
 command before it's run.
 
-Interactively, the user can use the \\`M-c' command while entering
-the regexp to indicate whether the grep should be case sensitive
-or not.
+Interactively, the user can use 
\\<read-regexp-map>\\[read-regexp-toggle-case-fold] while entering the regexp
+to indicate whether the grep should be case sensitive or not.
 
 (fn REGEXP &optional FILES DIR CONFIRM)" t)
 (autoload 'zrgrep "grep" "\
@@ -16409,7 +16450,8 @@ inlined into the compiled format versions.  This means 
that if you
 change its definition, you should explicitly call
 `ibuffer-recompile-formats'.
 
-(fn SYMBOL (&key NAME INLINE PROPS SUMMARIZER) &rest BODY)" nil 'macro)
+(fn SYMBOL (&key NAME INLINE PROPS SUMMARIZER) &rest BODY)" nil t)
+(function-put 'define-ibuffer-column 'lisp-indent-function 'defun)
 (autoload 'define-ibuffer-sorter "ibuf-macs" "\
 Define a method of sorting named NAME.
 DOCUMENTATION is the documentation of the function, which will be called
@@ -16420,7 +16462,9 @@ For sorting, the forms in BODY will be evaluated with 
`a' bound to one
 buffer object, and `b' bound to another.  BODY should return a non-nil
 value if and only if `a' is \"less than\" `b'.
 
-(fn NAME DOCUMENTATION (&key DESCRIPTION) &rest BODY)" nil 'macro)
+(fn NAME DOCUMENTATION (&key DESCRIPTION) &rest BODY)" nil t)
+(function-put 'define-ibuffer-sorter 'lisp-indent-function 1)
+(function-put 'define-ibuffer-sorter 'doc-string-elt 2)
 (autoload 'define-ibuffer-op "ibuf-macs" "\
 Generate a function which operates on a buffer.
 OP becomes the name of the function; if it doesn't begin with
@@ -16459,7 +16503,9 @@ BODY define the operation; they are forms to evaluate 
per each
 marked buffer.  BODY is evaluated with `buf' bound to the
 buffer object.
 
-(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING 
ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)" nil 'macro)
+(fn OP ARGS DOCUMENTATION (&key INTERACTIVE MARK MODIFIER-P DANGEROUS OPSTRING 
ACTIVE-OPSTRING BEFORE AFTER COMPLEX) &rest BODY)" nil t)
+(function-put 'define-ibuffer-op 'lisp-indent-function 2)
+(function-put 'define-ibuffer-op 'doc-string-elt 3)
 (autoload 'define-ibuffer-filter "ibuf-macs" "\
 Define a filter named NAME.
 DOCUMENTATION is the documentation of the function.
@@ -16474,7 +16520,9 @@ not a particular buffer should be displayed or not.  
The forms in BODY
 will be evaluated with BUF bound to the buffer object, and QUALIFIER
 bound to the current value of the filter.
 
-(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" nil 'macro)
+(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" nil t)
+(function-put 'define-ibuffer-filter 'lisp-indent-function 2)
+(function-put 'define-ibuffer-filter 'doc-string-elt 2)
 (register-definition-prefixes "ibuf-macs" '("ibuffer-"))
 
 
@@ -18954,7 +19002,7 @@ The macro is now available for use via 
\\[kmacro-call-macro],
 or it can be given a name with \\[kmacro-name-last-macro] and then invoked
 under that name.
 
-With numeric arg, repeat macro now that many times,
+With numeric ARG, repeat the macro that many times,
 counting the definition just completed as the first repetition.
 An argument of zero means repeat until error.
 
@@ -19179,7 +19227,7 @@ A major mode to edit GNU ld script files.
 (put 'less-css-input-file-name 'safe-local-variable #'stringp)
  (add-to-list 'auto-mode-alist '("\\.less\\'" . less-css-mode))
 (autoload 'less-css-mode "less-css-mode" "\
-Major mode for editing Less files (http://lesscss.org/).
+Major mode for editing Less files (https://lesscss.org/).
 Special commands:
 \\{less-css-mode-map}
 
@@ -20706,6 +20754,8 @@ Also see the `duplicate-line' command.
 (autoload 'duplicate-line "misc" "\
 Duplicate the current line N times.
 Interactively, N is the prefix numeric argument, and defaults to 1.
+The user option `duplicate-line-final-position' specifies where to
+move point after duplicating the line.
 Also see the `copy-from-above-command' command.
 
 (fn &optional N)" t)
@@ -20715,6 +20765,9 @@ If the region is inactive, duplicate the current line 
(like `duplicate-line').
 Otherwise, duplicate the region, which remains active afterwards.
 If the region is rectangular, duplicate on its right-hand side.
 Interactively, N is the prefix numeric argument, and defaults to 1.
+The variables `duplicate-line-final-position' and
+`duplicate-region-final-position' control the position of point
+and the region after the duplication.
 
 (fn &optional N)" t)
 (autoload 'zap-up-to-char "misc" "\
@@ -20766,7 +20819,7 @@ Optional argument BUFFER specifies a buffer to use, 
instead of
 The return value is always nil.
 
 (fn &optional LOADED-ONLY-P BUFFER)" t)
-(register-definition-prefixes "misc" '("list-dynamic-libraries--"))
+(register-definition-prefixes "misc" '("duplicate-" 
"list-dynamic-libraries--"))
 
 
 ;;; Generated autoloads from misearch.el
@@ -22508,7 +22561,7 @@ Coloring:
 
 ;;; Generated autoloads from org/org.el
 
-(push (purecopy '(org 9 6 6)) package--builtin-versions)
+(push (purecopy '(org 9 6 7)) package--builtin-versions)
 (autoload 'org-babel-do-load-languages "org" "\
 Load the languages defined in `org-babel-load-languages'.
 
@@ -24489,11 +24542,6 @@ they are not by default assigned to keys." t)
 (register-definition-prefixes "picture" '("picture-"))
 
 
-;;; Generated autoloads from language/pinyin.el
-
-(register-definition-prefixes "pinyin" '("pinyin-character-map"))
-
-
 ;;; Generated autoloads from textmodes/pixel-fill.el
 
 (register-definition-prefixes "pixel-fill" '("pixel-fill-"))
@@ -24527,6 +24575,18 @@ The mode's hook is called both when the mode is 
enabled and when
 it is disabled.
 
 (fn &optional ARG)" t)
+(autoload 'pixel-scroll-precision-scroll-down-page "pixel-scroll" "\
+Scroll the current window down by DELTA pixels.
+Note that this function doesn't work if DELTA is larger than
+the height of the current window.
+
+(fn DELTA)")
+(autoload 'pixel-scroll-precision-scroll-up-page "pixel-scroll" "\
+Scroll the current window up by DELTA pixels.
+Note that this function doesn't work if DELTA is larger than
+the height of the current window.
+
+(fn DELTA)")
 (defvar pixel-scroll-precision-mode nil "\
 Non-nil if Pixel-Scroll-Precision mode is enabled.
 See the `pixel-scroll-precision-mode' command
@@ -24618,8 +24678,9 @@ Use streaming commands.
 Return a string containing the pretty-printed representation of OBJECT.
 OBJECT can be any Lisp object.  Quoting characters are used as needed
 to make output that `read' can handle, whenever this is possible.
+Optional argument PP-FUNCTION overrides `pp-default-function'.
 
-(fn OBJECT)")
+(fn OBJECT &optional PP-FUNCTION)")
 (autoload 'pp-buffer "pp" "\
 Prettify the current buffer with printed representation of a Lisp object." t)
 (autoload 'pp "pp" "\
@@ -24627,11 +24688,7 @@ Output the pretty-printed representation of OBJECT, 
any Lisp object.
 Quoting characters are printed as needed to make output that `read'
 can handle, whenever this is possible.
 
-This function does not apply special formatting rules for Emacs
-Lisp code.  See `pp-emacs-lisp-code' instead.
-
-By default, this function won't limit the line length of lists
-and vectors.  Bind `pp-use-max-width' to a non-nil value to do so.
+Uses the pretty-printing code specified in `pp-default-function'.
 
 Output stream is STREAM, or value of `standard-output' (which see).
 
@@ -24669,8 +24726,10 @@ Ignores leading comment characters.
 Insert SEXP into the current buffer, formatted as Emacs Lisp code.
 Use the `pp-max-width' variable to control the desired line length.
 Note that this could be slow for large SEXPs.
+Can also be called with two arguments, in which case they're taken to be
+the bounds of a region containing Lisp code to pretty-print.
 
-(fn SEXP)")
+(fn SEXP &optional END)")
 (register-definition-prefixes "pp" '("pp-"))
 
 
@@ -25261,8 +25320,10 @@ Return the project instance in DIRECTORY, defaulting 
to `default-directory'.
 
 When no project is found in that directory, the result depends on
 the value of MAYBE-PROMPT: if it is nil or omitted, return nil,
-else ask the user for a directory in which to look for the
-project, and if no project is found there, return a \"transient\"
+else prompt the user for the project to use.  To prompt for a
+project, call the function specified by `project-prompter', which
+returns the directory in which to look for the project.  If no
+project is found in that directory, return a \"transient\"
 project instance.
 
 The \"transient\" project instance is a special kind of value
@@ -25468,6 +25529,15 @@ When called in a program, it will use the project 
corresponding
 to directory DIR.
 
 (fn DIR)" t)
+(autoload 'project-uniquify-dirname-transform "project" "\
+Uniquify name of directory DIRNAME using `project-name', if in a project.
+
+If you set `uniquify-dirname-transform' to this function,
+slash-separated components from `project-name' will be appended to
+the buffer's directory name when buffers from two different projects
+would otherwise have the same name.
+
+(fn DIRNAME)")
 (register-definition-prefixes "project" '("project-"))
 
 
@@ -25832,6 +25902,7 @@ Major mode for editing Python files, using tree-sitter 
library.
 \\{python-ts-mode-map}
 
 (fn)" t)
+(add-to-list 'auto-mode-alist '("/\\(?:Pipfile\\|\\.?flake8\\)\\'" . 
conf-mode))
 (register-definition-prefixes "python" '("inferior-python-mode" "python-" 
"run-python-internal"))
 
 
@@ -27501,8 +27572,8 @@ Currently there are `ruby-mode' and `ruby-ts-mode'.
 Major mode for editing Ruby code.
 
 (fn)" t)
-(add-to-list 'auto-mode-alist (cons (purecopy (concat "\\(?:\\.\\(?:" 
"rbw?\\|ru\\|rake\\|thor" "\\|jbuilder\\|rabl\\|gemspec\\|podspec" "\\)" "\\|/" 
"\\(?:Gem\\|Rake\\|Cap\\|Thor" "\\|Puppet\\|Berks\\|Brew" 
"\\|Vagrant\\|Guard\\|Pod\\)file" "\\)\\'")) 'ruby-mode))
-(dolist (name (list "ruby" "rbx" "jruby" "ruby1.9" "ruby1.8")) (add-to-list 
'interpreter-mode-alist (cons (purecopy name) 'ruby-mode)))
+(add-to-list 'auto-mode-alist (cons (purecopy (concat "\\(?:\\.\\(?:" 
"rbw?\\|ru\\|rake\\|thor\\|axlsx" "\\|jbuilder\\|rabl\\|gemspec\\|podspec" 
"\\)" "\\|/" "\\(?:Gem\\|Rake\\|Cap\\|Thor" "\\|Puppet\\|Berks\\|Brew\\|Fast" 
"\\|Vagrant\\|Guard\\|Pod\\)file" "\\)\\'")) 'ruby-mode))
+(dolist (name (list "ruby" "rbx" "jruby" "j?ruby\\(?:[0-9.]+\\)")) 
(add-to-list 'interpreter-mode-alist (cons (purecopy name) 'ruby-mode)))
 (register-definition-prefixes "ruby-mode" '("ruby-"))
 
 
@@ -30433,7 +30504,7 @@ this defaults to the current buffer.
 Query the user for a process and return the process object.
 
 (fn PROMPT)")
-(register-definition-prefixes "subr-x" '("emacs-etc--hide-local-variables" 
"eval-command-interactive-spec" "hash-table-" "internal--thread-argument" 
"replace-region-contents" "string-" "thread-" 
"with-buffer-unmodified-if-unchanged"))
+(register-definition-prefixes "subr-x" '("emacs-etc--hide-local-variables" 
"hash-table-" "internal--thread-argument" "replace-region-contents" "string-" 
"thread-" "with-buffer-unmodified-if-unchanged"))
 
 
 ;;; Generated autoloads from progmodes/subword.el
@@ -31307,7 +31378,7 @@ See also: variables `tar-update-datestamp' and 
`tar-anal-blocksize'.
 \\{tar-mode-map}
 
 (fn)" t)
-(register-definition-prefixes "tar-mode" '("tar-"))
+(register-definition-prefixes "tar-mode" '("pax-" "tar-"))
 
 
 ;;; Generated autoloads from progmodes/tcl.el
@@ -32670,7 +32741,7 @@ FROM-MAP must contain appropriate binding for 
`[menu-bar]' which
 holds a keymap.
 
 (fn COMMAND ICON IN-MAP &optional FROM-MAP &rest PROPS)")
-(register-definition-prefixes "tool-bar" '("toggle-tool-bar-mode-from-frame" 
"tool-bar-"))
+(register-definition-prefixes "tool-bar" '("modifier-bar-" 
"secondary-tool-bar-map" "toggle-tool-bar-mode-from-frame" "tool-bar-"))
 
 
 ;;; Generated autoloads from tooltip.el
@@ -32771,6 +32842,11 @@ Add Tramp file name handlers to 
`file-name-handler-alist' during autoload." (unl
  (tramp-register-autoload-file-name-handlers)
 (defun tramp-unload-file-name-handlers nil "\
 Unload Tramp file name handlers from `file-name-handler-alist'." (dolist (fnh 
file-name-handler-alist) (when (and (symbolp (cdr fnh)) (string-prefix-p 
"tramp-" (symbol-name (cdr fnh)))) (setq file-name-handler-alist (delq fnh 
file-name-handler-alist)))))
+(defun inhibit-remote-files nil "\
+Deactivate remote file names." (interactive) (when (fboundp 
'tramp-cleanup-all-connections) (funcall 'tramp-cleanup-all-connections)) 
(tramp-unload-file-name-handlers) (setq tramp-mode nil))
+(defmacro without-remote-files (&rest body) "\
+Deactivate remote file names temporarily.
+Run BODY." (declare (indent 0) (debug ((form body) body))) `(let 
((file-name-handler-alist (copy-tree file-name-handler-alist)) tramp-mode) 
(tramp-unload-file-name-handlers) ,@body))
 (defun tramp-unload-tramp nil "\
 Discard Tramp from loading remote files." (interactive) (ignore-errors 
(unload-feature 'tramp 'force)))
 (register-definition-prefixes "tramp" '("tramp-" "with-"))
@@ -32847,6 +32923,11 @@ Add archive file name handler to 
`file-name-handler-alist'." (when (and tramp-ar
 (register-definition-prefixes "tramp-integration" '("tramp-"))
 
 
+;;; Generated autoloads from net/tramp-message.el
+
+(register-definition-prefixes "tramp-message" '("tramp-" 
"with-tramp-debug-message"))
+
+
 ;;; Generated autoloads from net/tramp-rclone.el
 
 (register-definition-prefixes "tramp-rclone" '("tramp-rclone-"))
@@ -33245,7 +33326,7 @@ The JSX-specific faces are used when 
`treesit-font-lock-level' is
 at least 3 (which is the default value).
 
 (fn)" t)
-(register-definition-prefixes "typescript-ts-mode" '("typescript-ts-mode-"))
+(register-definition-prefixes "typescript-ts-mode" '("tsx-ts-mode--" 
"typescript-ts-mode-"))
 
 
 ;;; Generated autoloads from international/ucs-normalize.el
@@ -36636,7 +36717,7 @@ The optional ARGS are additional keyword arguments.
 Call `insert' with ARGS even if surrounding text is read only.
 
 (fn &rest ARGS)")
-(defvar widget-keymap (let ((map (make-sparse-keymap))) (define-key map "\11" 
'widget-forward) (define-key map "\33\11" 'widget-backward) (define-key map 
[(shift tab)] 'widget-backward) (put 'widget-backward :advertised-binding 
[(shift tab)]) (define-key map [backtab] 'widget-backward) (define-key map 
[down-mouse-2] 'widget-button-click) (define-key map [down-mouse-1] 
'widget-button-click) (define-key map [(control 109)] 'widget-button-press) 
map) "\
+(defvar widget-keymap (let ((map (make-sparse-keymap))) (define-key map "\11" 
'widget-forward) (define-key map "\33\11" 'widget-backward) (define-key map 
[(shift tab)] 'widget-backward) (put 'widget-backward :advertised-binding 
[(shift tab)]) (define-key map [backtab] 'widget-backward) (define-key map 
[down-mouse-2] 'widget-button-click) (define-key map [down-mouse-1] 
'widget-button-click) (define-key map [touchscreen-begin] 'widget-button-click) 
(define-key map [(control 109)] 'widget-b [...]
 Keymap containing useful binding for buffers containing widgets.
 Recommended as a parent keymap for modes using widgets.
 Note that such modes will need to require wid-edit.")
diff --git a/lisp/loadhist.el b/lisp/loadhist.el
index 1609542e5fa..eb87016695c 100644
--- a/lisp/loadhist.el
+++ b/lisp/loadhist.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1995, 1998, 2000-2023 Free Software Foundation, Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: internal
 
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 8679fba68f9..dab8579be24 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -566,7 +566,8 @@ lost after dumping")))
 
 
 
-(if (eq system-type 'android)
+(if (and (eq system-type 'android)
+         (featurep 'android))
     (progn
       ;; Dumping Emacs on Android works slightly differently from
       ;; everywhere else.  The first time Emacs starts, Emacs dumps
@@ -603,7 +604,7 @@ lost after dumping")))
                    (equal dump-mode "pdump"))
           ;; Don't enable this before bootstrap is completed, as the
           ;; compiler infrastructure may not be usable yet.
-          (setq comp-enable-subr-trampolines t))
+          (setq native-comp-enable-subr-trampolines t))
         (message "Dumping under the name %s" output)
         (condition-case ()
             (delete-file output)
@@ -631,7 +632,11 @@ lost after dumping")))
                      ;; There's no point keeping old dumps around for
                      ;; the binary used to build Lisp on the build
                      ;; machine.
-                     (featurep 'android)
+                     (or (featurep 'android)
+                         ;; And if this branch is reached with
+                         ;; `system-type' set to Android, this is a
+                         ;; regular Emacs TTY build.  (bug#65339)
+                         (eq system-type 'android))
                      ;; Don't bother adding another name if we're just
                      ;; building bootstrap-emacs.
                      (member dump-mode '("pbootstrap" "bootstrap"))))
diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el
index 3893e93238f..bebaad720db 100644
--- a/lisp/mail/emacsbug.el
+++ b/lisp/mail/emacsbug.el
@@ -144,6 +144,10 @@ This requires either the macOS \"open\" command, or the 
freedesktop
                (goto-char (point-min))
                (buffer-substring (line-beginning-position)
                                  (line-end-position))))))
+        ((eq system-type 'android)
+         ;; This is a short string containing the Android version,
+         ;; build number, and window system distributor.
+         (symbol-value 'android-build-fingerprint))
         ;; TODO Cygwin, Solaris (usg-unix-v).
         (t
          (or (let ((file "/etc/os-release"))
@@ -408,12 +412,6 @@ copy text to your preferred mail program.\n"
                   "', version "
                  (mapconcat #'number-to-string (x-server-version) ".") "\n")
        (error t)))
-  (when (and (boundp 'android-build-fingerprint)
-             (symbol-value 'android-build-fingerprint))
-    ;; This is used on Android.
-    (insert "Android version and manufacturer: "
-            (symbol-value 'android-build-fingerprint)
-            "\n"))
   (let ((os (ignore-errors (report-emacs-bug--os-description))))
     (if (stringp os)
         (insert "System Description: " os "\n\n")))
diff --git a/lisp/mail/supercite.el b/lisp/mail/supercite.el
index 1a48c64a663..8d9cb5511ed 100644
--- a/lisp/mail/supercite.el
+++ b/lisp/mail/supercite.el
@@ -620,9 +620,6 @@ the list should be unique."
         ((setq elt (rassq char alist))
          (message "%s%s" p (car elt))
          (setq p (cdr elt)))
-        ((if (fboundp 'button-release-event-p)
-             (button-release-event-p event)) ; ignore them
-         nil)
         (t
          (message "%s%s" p (single-key-description event))
          (ding)
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index 8d81b3ec9d8..ca706c3c6e9 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -23,18 +23,18 @@
 ;;; Commentary:
 
 ;; dictionary allows you to interact with dictionary servers.
-;; Use M-x customize-group dictionary to modify user settings.
+;;
+;; Use `M-x customize-group RET dictionary RET' to modify user settings.
 ;;
 ;; Main commands for interaction are:
-;; M-x dictionary        - opens a new dictionary buffer
-;; M-x dictionary-search - search for the definition of a word
+;; `M-x dictionary'        - open a new dictionary buffer
+;; `M-x dictionary-search' - search for the definition of a word
 ;;
 ;; You can find more information in the README file of the GitHub
 ;; repository https://github.com/myrkr/dictionary-el
 
 ;;; Code:
 
-(require 'cl-lib)
 (require 'custom)
 (require 'dictionary-connection)
 (require 'button)
@@ -409,20 +409,10 @@ Otherwise, `dictionary-search' displays definitions in a 
*Dictionary* buffer."
   nil
   "The current network connection.")
 
-(defvar dictionary-instances
-  0
-  "The number of open dictionary buffers.")
-
 (defvar dictionary-marker
   nil
   "Stores the point position while buffer display.")
 
-(defvar dictionary-color-support
-  (condition-case nil
-      (display-color-p)
-    (error nil))
-  "Determines if the Emacs has support to display color.")
-
 (defvar dictionary-word-history
   '()
   "History list of searched word.")
@@ -434,47 +424,35 @@ Otherwise, `dictionary-search' displays definitions in a 
*Dictionary* buffer."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;;;###autoload
-(defun dictionary-mode ()
-  ;; FIXME: Use define-derived-mode.
+(define-derived-mode dictionary-mode special-mode "Dictionary"
   "Mode for searching a dictionary.
+
 This is a mode for searching a dictionary server implementing the
 protocol defined in RFC 2229.
 
 This is a quick reference to this mode describing the default key bindings:
 \\<dictionary-mode-map>
-* \\[dictionary-close] close the dictionary buffer
-* \\[describe-mode] display this help information
-* \\[dictionary-search] ask for a new word to search
-* \\[dictionary-lookup-definition] search the word at point
-* \\[forward-button] or TAB place point to the next link
-* \\[backward-button] or S-TAB place point to the prev link
-
-* \\[dictionary-match-words] ask for a pattern and list all matching words.
-* \\[dictionary-select-dictionary] select the default dictionary
-* \\[dictionary-select-strategy] select the default search strategy
-
-* \\`RET' or \\`<mouse-2>' visit that link"
-
-  (unless (eq major-mode 'dictionary-mode)
-    (cl-incf dictionary-instances))
-
-  (kill-all-local-variables)
+ \\[dictionary-close]  close the dictionary buffer
+ \\[describe-mode]     display this help
+ \\[dictionary-search] ask for a new word to search
+ \\[dictionary-lookup-definition]      search for word at point
+ \\[forward-button] or \\`TAB' move point to the next link
+ \\[backward-button] or \\`S-TAB'      move point to the previous link
+
+ \\[dictionary-match-words]    ask for a pattern and list all matching words
+ \\[dictionary-select-dictionary]      select the default dictionary
+ \\[dictionary-select-strategy]        select the default search strategy
+
+ \\`RET'       visit link at point
+ \\`<mouse-2>' visit clicked link"
   (buffer-disable-undo)
-  (use-local-map dictionary-mode-map)
-  (setq major-mode 'dictionary-mode)
-  (setq mode-name "Dictionary")
-
   (setq-local dictionary-data-stack nil)
   (setq-local dictionary-position-stack nil)
-
   (make-local-variable 'dictionary-current-data)
   (make-local-variable 'dictionary-positions)
-
   (make-local-variable 'dictionary-default-dictionary)
   (make-local-variable 'dictionary-default-strategy)
-
-  (add-hook 'kill-buffer-hook #'dictionary-close t t)
-  (run-hooks 'dictionary-mode-hook))
+  (add-hook 'kill-buffer-hook #'dictionary-close t t))
 
 ;;;###autoload
 (defun dictionary ()
@@ -598,16 +576,15 @@ The connection takes the proxy setting in customization 
group
 (defun dictionary-close (&rest _ignored)
   "Close the current dictionary buffer and its connection."
   (interactive)
-  (if (eq major-mode 'dictionary-mode)
-      (progn
-       (setq major-mode nil)
-       (if (<= (cl-decf dictionary-instances) 0)
-           (dictionary-connection-close dictionary-connection))
-       (let ((configuration dictionary-window-configuration)
-             (selected-window dictionary-selected-window))
-         (kill-buffer (current-buffer))
-         (set-window-configuration configuration)
-         (select-window selected-window)))))
+  (when (derived-mode-p 'dictionary-mode)
+    (setq major-mode nil)
+    (if (<= (length (match-buffers '(derived-mode . dictionary-mode))) 0)
+        (dictionary-connection-close dictionary-connection))
+    (let ((configuration dictionary-window-configuration)
+          (selected-window dictionary-selected-window))
+      (kill-buffer (current-buffer))
+      (set-window-configuration configuration)
+      (select-window selected-window))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Helpful functions
@@ -900,7 +877,7 @@ them with buttons to perform a new search."
        (if (search-forward-regexp regexp nil t)
            (let ((match-start (match-beginning 2))
                  (match-end (match-end 2)))
-             (if dictionary-color-support
+              (if (display-color-p)
                  ;; Compensate for the replacement
                  (let ((brace-match-length (- (match-end 1)
                                               (match-beginning 1))))
@@ -1222,9 +1199,12 @@ If PATTERN is omitted, it defaults to \"[ 
\\f\\t\\n\\r\\v]+\"."
 
 ;;;###autoload
 (defun dictionary-search (word &optional dictionary)
-  "Search the WORD in DICTIONARY if given or in all if nil.
-It presents the selection or word at point as default input and
-allows editing it."
+  "Search for WORD in all the known dictionaries.
+Interactively, prompt for WORD, and offer the word at point as default.
+
+Optional argument DICTIONARY means restrict the search to only
+that one dictionary.  Interactively, with prefix argument,
+prompt for DICTIONARY."
   (interactive
    (let ((dict
           (if current-prefix-arg
@@ -1559,5 +1539,9 @@ Further arguments are currently ignored."
                             (match-string 1)
                             dictionary))))))
 
+(defvar dictionary-color-support (display-color-p)
+  "Determines if the Emacs has support to display color.")
+(make-obsolete-variable 'dictionary-color-support 'display-color-p "30.1")
+
 (provide 'dictionary)
 ;;; dictionary.el ends here
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index cb73926f462..3cdbe9dd471 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -542,24 +542,35 @@ for the search engine used."
           (call-interactively #'eww)))
     (call-interactively #'eww)))
 
-(defun eww-open-in-new-buffer ()
-  "Fetch link at point in a new EWW buffer."
-  (interactive)
-  (let ((url (eww-suggested-uris)))
-    (if (null url) (user-error "No link at point")
-      (when (or (eq eww-browse-url-new-window-is-tab t)
-                (and (eq eww-browse-url-new-window-is-tab 'tab-bar)
-                     tab-bar-mode))
-        (let ((tab-bar-new-tab-choice t))
-          (tab-new)))
-      ;; clone useful to keep history, but
-      ;; should not clone from non-eww buffer
-      (with-current-buffer
-          (if (eq major-mode 'eww-mode) (clone-buffer)
-            (generate-new-buffer "*eww*"))
-        (unless (equal url (eww-current-url))
-          (eww-mode)
-          (eww (if (consp url) (car url) url)))))))
+(defun eww--open-url-in-new-buffer (url)
+  "Open the URL in a new EWW buffer."
+  ;; Clone is useful to keep history, but we
+  ;; should not clone from a non-eww buffer.
+  (with-current-buffer
+      (if (eq major-mode 'eww-mode) (clone-buffer)
+        (generate-new-buffer "*eww*"))
+    (unless (equal url (eww-current-url))
+      (eww-mode)
+      (eww (if (consp url) (car url) url)))))
+
+(defun eww-open-in-new-buffer (&optional no-select url)
+  "Fetch URL (interactively, the link at point) into a new EWW buffer.
+
+NO-SELECT non-nil means do not make the new buffer the current buffer."
+  (interactive "P")
+  (if-let ((url (or url (eww-suggested-uris))))
+      (if (or (eq eww-browse-url-new-window-is-tab t)
+              (and (eq eww-browse-url-new-window-is-tab 'tab-bar)
+                   tab-bar-mode))
+          (let ((tab-bar-new-tab-choice t))
+            (tab-new)
+            (eww--open-url-in-new-buffer url)
+            (when no-select
+              (tab-bar-switch-to-prev-tab)))
+        (if no-select
+            (save-window-excursion (eww--open-url-in-new-buffer url))
+          (eww--open-url-in-new-buffer url)))
+    (user-error "No link at point")))
 
 (defun eww-html-p (content-type)
   "Return non-nil if CONTENT-TYPE designates an HTML content type.
diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el
index b284ca84bfc..55fa19cbf2a 100644
--- a/lisp/net/newst-plainview.el
+++ b/lisp/net/newst-plainview.el
@@ -1175,9 +1175,7 @@ The mode-line is changed accordingly."
 
 (defun newsticker--buffer-redraw ()
   "Redraw the newsticker window."
-  (if (fboundp 'force-window-update)
-      (force-window-update (current-buffer))
-    (redraw-frame))
+  (force-window-update (current-buffer))
   (run-hooks 'newsticker-buffer-change-hook)
   (sit-for 0))
 
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index eec00b17b4c..076103e8ae4 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -538,6 +538,8 @@ Emacs dired can't find files."
          (set-file-modes tmpfile (logior (or (file-modes tmpfile) 0) #o0600)))
        (let (create-lockfiles)
           (write-region start end tmpfile append 'no-message))
+       ;; Now, `last-coding-system-used' has the right value.  Remember it.
+       (setq coding-system-used last-coding-system-used)
        (with-tramp-progress-reporter
            v 3 (format-message
                 "Moving tmp file `%s' to `%s'" tmpfile filename)
diff --git a/lisp/net/tramp-message.el b/lisp/net/tramp-message.el
index cca22a28d7c..c91af638449 100644
--- a/lisp/net/tramp-message.el
+++ b/lisp/net/tramp-message.el
@@ -32,9 +32,8 @@
 ;;   This buffer is created when `tramp-verbose' is greater than or
 ;;   equal 4.  It contains all messages with a level up to `tramp-verbose'.
 ;;
-;;   When `tramp-debug-command-messages' is non-nil and
-;;   `tramp-verbose' is greater than or equal 6, the buffer contains
-;;   all messages with level 6 and the entry/exit messages of
+;;   When `tramp-debug-command-messages' is non-nil, the buffer
+;;   contains all messages with level 6 and the entry/exit messages of
 ;;   `tramp-file-name-handler'.  This is intended to analyze which
 ;;   remote commands are sent for a given file name operation.
 ;;
@@ -85,7 +84,7 @@ The debug file has the same name as the debug buffer, written 
to
 
 (defcustom tramp-debug-command-messages nil
   "Whether to write only command messages to the debug buffer.
-This has only effect if `tramp-verbose' is greater than or equal 6."
+This increases `tramp-verbose' to 6 if necessary."
   :group 'tramp
   :version "30.1"
   :type 'boolean)
@@ -298,44 +297,47 @@ control string and the remaining ARGUMENTS to actually 
emit the message (if
 applicable)."
   ;; (declare (tramp-suppress-trace t))
   (ignore-errors
-    (when (<= level tramp-verbose)
-      ;; Display only when there is a minimum level, and the progress
-      ;; reporter doesn't suppress further messages.
-      (when (and (<= level 3) (null tramp-inhibit-progress-reporter))
-       (apply #'message
-              (concat
-               (cond
-                ((= level 0) "")
-                ((= level 1) "")
-                ((= level 2) "Warning: ")
-                (t           "Tramp: "))
-               fmt-string)
-              arguments))
-      ;; Log only when there is a minimum level.
-      (when (>= tramp-verbose 4)
-       (let ((tramp-verbose 0))
-         ;; Append connection buffer for error messages, if exists.
-         (when (= level 1)
-           (ignore-errors
-             (setq fmt-string (concat fmt-string "\n%s")
-                   arguments
-                   (append
-                    arguments
-                    `(,(tramp-get-buffer-string
-                        (if (processp vec-or-proc)
-                            (process-buffer vec-or-proc)
-                          (tramp-get-connection-buffer
-                           vec-or-proc 'dont-create))))))))
-         ;; Translate proc to vec.
-         (when (processp vec-or-proc)
-           (setq vec-or-proc (process-get vec-or-proc 'tramp-vector))))
-       ;; Do it.
-       (when (and (tramp-file-name-p vec-or-proc)
-                  (or (null tramp-debug-command-messages) (= level 6)))
-         (apply #'tramp-debug-message
-                vec-or-proc
-                (concat (format "(%d) # " level) fmt-string)
-                arguments))))))
+    (let ((tramp-verbose
+          (if tramp-debug-command-messages
+              (max tramp-verbose 6) tramp-verbose)))
+      (when (<= level tramp-verbose)
+       ;; Display only when there is a minimum level, and the
+       ;; progress reporter doesn't suppress further messages.
+       (when (and (<= level 3) (null tramp-inhibit-progress-reporter))
+         (apply #'message
+                (concat
+                 (cond
+                  ((= level 0) "")
+                  ((= level 1) "")
+                  ((= level 2) "Warning: ")
+                  (t           "Tramp: "))
+                 fmt-string)
+                arguments))
+       ;; Log only when there is a minimum level.
+       (when (>= tramp-verbose 4)
+         (let ((tramp-verbose 0))
+           ;; Append connection buffer for error messages, if exists.
+           (when (= level 1)
+             (ignore-errors
+               (setq fmt-string (concat fmt-string "\n%s")
+                     arguments
+                     (append
+                      arguments
+                      `(,(tramp-get-buffer-string
+                          (if (processp vec-or-proc)
+                              (process-buffer vec-or-proc)
+                            (tramp-get-connection-buffer
+                             vec-or-proc 'dont-create))))))))
+           ;; Translate proc to vec.
+           (when (processp vec-or-proc)
+             (setq vec-or-proc (process-get vec-or-proc 'tramp-vector))))
+         ;; Do it.
+         (when (and (tramp-file-name-p vec-or-proc)
+                    (or (null tramp-debug-command-messages) (= level 6)))
+           (apply #'tramp-debug-message
+                  vec-or-proc
+                  (concat (format "(%d) # " level) fmt-string)
+                  arguments)))))))
 
 ;; We cannot use the `declare' form for `tramp-suppress-trace' in
 ;; autoloaded functions, because the tramp-loaddefs.el generation
@@ -531,7 +533,7 @@ Bound in `tramp-*-file-name-handler' functions.")
 If BODY does not raise a debug message, MESSAGE is ignored."
   (declare (indent 2) (debug t))
   (let ((result (make-symbol "result")))
-    `(if (and tramp-debug-command-messages (>= tramp-verbose 6))
+    `(if tramp-debug-command-messages
         (save-match-data
           (let ((tramp-debug-nesting
                  (concat tramp-debug-nesting "#"))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 2b1d26dd232..0599f89655c 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -634,16 +634,20 @@ characters need to be doubled.")
 
 (defconst tramp-perl-file-name-all-completions
   "%p -e '
-opendir(d, $ARGV[0]) || die(\"$ARGV[0]: $!\\nfail\\n\");
+($dir = $ARGV[0]) =~ s#/+$##;
+opendir(d, $dir) || die(\"$dir: $!\\nfail\\n\");
 @files = readdir(d); closedir(d);
+print \"(\\n\";
 foreach $f (@files) {
- if (-d \"$ARGV[0]/$f\") {
-  print \"$f/\\n\";
- }
- else {
-  print \"$f\\n\";
- }
+  ($p = $f) =~ s/\\\"/\\\\\\\"/g;
+  ($q = \"$dir/$f\") =~ s/\\\"/\\\\\\\"/g;
+  print \"(\",
+    ((-d \"$q\") ? \"\\\"$p/\\\" \\\"$q\\\" t\" : \"\\\"$p\\\" \\\"$q\\\" 
nil\"),
+    ((-e \"$q\") ? \" t\" : \" nil\"),
+    ((-r \"$q\") ? \" t\" : \" nil\"),
+    \")\\n\";
 }
+print \")\\n\";
 ' \"$1\" %n"
   "Perl script to produce output suitable for use with
 `file-name-all-completions' on the remote file system.
@@ -1073,21 +1077,10 @@ characters need to be doubled.")
   "echo \"(\"
 while read file; do
     quoted=`echo \"$file\" | sed -e \"s/\\\"/\\\\\\\\\\\\\\\\\\\"/\"`
-    if %s \"$file\"; then
-       echo \"(\\\"$quoted\\\" \\\"file-exists-p\\\" t)\"
-    else
-       echo \"(\\\"$quoted\\\" \\\"file-exists-p\\\" nil)\"
-    fi
-    if %s \"$file\"; then
-       echo \"(\\\"$quoted\\\" \\\"file-readable-p\\\" t)\"
-    else
-       echo \"(\\\"$quoted\\\" \\\"file-readable-p\\\" nil)\"
-    fi
-    if %s \"$file\"; then
-       echo \"(\\\"$quoted\\\" \\\"file-directory-p\\\" t)\"
-    else
-       echo \"(\\\"$quoted\\\" \\\"file-directory-p\\\" nil)\"
-    fi
+    printf \"(%%b\" \"\\\"$quoted\\\"\"
+    if %s \"$file\"; then printf \" %%b\" t; else printf \" %%b\" nil; fi
+    if %s \"$file\"; then printf \" %%b\" t; else printf \" %%b\" nil; fi
+    if %s \"$file\"; then printf \" %%b)\n\" t; else printf \" %%b)\n\" nil; fi
 done
 echo \")\""
   "Script to check file attributes of a bundle of files.
@@ -1095,7 +1088,8 @@ It must be sent formatted with three strings; the tests 
for file
 existence, file readability, and file directory.  Input shall be
 read via here-document, otherwise the command could exceed
 maximum length of command line.
-Format specifiers \"%s\" are replaced before the script is used.")
+Format specifiers \"%s\" are replaced before the script is used,
+percent characters need to be doubled.")
 
 ;; New handlers should be added here.
 ;;;###tramp-autoload
@@ -1870,34 +1864,48 @@ ID-FORMAT valid values are `string' and `integer'."
             ;; Get a list of directories and files, including
             ;; reliably tagging the directories with a trailing "/".
             ;; Because I rock.  --daniel@danann.net
-            (when (tramp-send-command-and-check
-                   v
-                   (if (tramp-get-remote-perl v)
-                       (progn
-                         (tramp-maybe-send-script
-                          v tramp-perl-file-name-all-completions
-                          "tramp_perl_file_name_all_completions")
-                         (format "tramp_perl_file_name_all_completions %s"
-                                 (tramp-shell-quote-argument localname)))
-
-                     (format (concat
-                              "cd %s 2>&1 && %s -a 2>%s"
-                              " | while IFS= read f; do"
-                              " if %s -d \"$f\" 2>%s;"
-                              " then echo \"$f/\"; else echo \"$f\"; fi;"
-                              " done")
-                             (tramp-shell-quote-argument localname)
-                             (tramp-get-ls-command v)
-                             (tramp-get-remote-null-device v)
-                             (tramp-get-test-command v)
-                             (tramp-get-remote-null-device v))))
-
-              ;; Now grab the output.
-              (with-current-buffer (tramp-get-buffer v)
-                (goto-char (point-max))
-                (while (zerop (forward-line -1))
-                  (push (buffer-substring (point) (line-end-position)) 
result)))
-              result)))))))))
+            (if (tramp-get-remote-perl v)
+                (progn
+                  (tramp-maybe-send-script
+                   v tramp-perl-file-name-all-completions
+                   "tramp_perl_file_name_all_completions")
+                  (setq result
+                        (tramp-send-command-and-read
+                         v (format "tramp_perl_file_name_all_completions %s"
+                                   (tramp-shell-quote-argument localname))
+                         'noerror))
+                  ;; Cached values.
+                  (dolist (elt result)
+                    (tramp-set-file-property
+                     v (cadr elt) "file-directory-p" (nth 2 elt))
+                    (tramp-set-file-property
+                     v (cadr elt) "file-exists-p" (nth 3 elt))
+                    (tramp-set-file-property
+                     v (cadr elt) "file-readable-p" (nth 4 elt)))
+                  ;; Result.
+                  (mapcar #'car result))
+
+              ;; Do it with ls.
+              (when (tramp-send-command-and-check
+                     v (format (concat
+                                "cd %s 2>&1 && %s -a 2>%s"
+                                " | while IFS= read f; do"
+                                " if %s -d \"$f\" 2>%s;"
+                                " then echo \"$f/\"; else echo \"$f\"; fi;"
+                                " done")
+                               (tramp-shell-quote-argument localname)
+                               (tramp-get-ls-command v)
+                               (tramp-get-remote-null-device v)
+                               (tramp-get-test-command v)
+                               (tramp-get-remote-null-device v)))
+
+                ;; Now grab the output.
+                (with-current-buffer (tramp-get-buffer v)
+                  (goto-char (point-max))
+                  (while (zerop (forward-line -1))
+                    (push
+                     (buffer-substring (point) (line-end-position)) result)))
+                result))))))))))
 
 ;; cp, mv and ln
 
@@ -2842,7 +2850,8 @@ the result will be a local, non-Tramp, file name."
            ;; appropriate either, because ssh and companions might
            ;; use a user name from the config file.
            (when (and (tramp-string-empty-or-nil-p uname)
-                      (string-match-p (rx bos "su" (? "do") eos) method))
+                      (string-match-p
+                       (rx bos (| "su" "sudo" "doas" "ksu") eos) method))
              (setq uname user))
            (when (setq hname (tramp-get-home-directory v uname))
              (setq localname (concat hname fname)))))
@@ -3442,15 +3451,6 @@ implementation will be used."
 
        (let* ((modes (tramp-default-file-modes
                       filename (and (eq mustbenew 'excl) 'nofollow)))
-              ;; We use this to save the value of
-              ;; `last-coding-system-used' after writing the tmp
-              ;; file.  At the end of the function, we set
-              ;; `last-coding-system-used' to this saved value.  This
-              ;; way, any intermediary coding systems used while
-              ;; talking to the remote shell or suchlike won't hose
-              ;; this variable.  This approach was snarfed from
-              ;; ange-ftp.el.
-              coding-system-used
               ;; Write region into a tmp file.  This isn't really
               ;; needed if we use an encoding function, but currently
               ;; we use it always because this makes the logic
@@ -3480,11 +3480,11 @@ implementation will be used."
              ((error quit)
               (setq tramp-temp-buffer-file-name nil)
               (delete-file tmpfile)
-              (signal (car err) (cdr err))))
+              (signal (car err) (cdr err)))))
 
-           ;; Now, `last-coding-system-used' has the right value.
-           ;; Remember it.
-           (setq coding-system-used last-coding-system-used))
+         ;; Now, `last-coding-system-used' has the right value.
+         ;; Remember it.
+         (setq coding-system-used last-coding-system-used)
 
          ;; The permissions of the temporary file should be set.  If
          ;; FILENAME does not exist (eq modes nil) it has been
@@ -3614,11 +3614,7 @@ implementation will be used."
               v 'file-error
               (concat "Method `%s' should specify both encoding and "
                       "decoding command or an scp program")
-              method))))
-
-         ;; Make `last-coding-system-used' have the right value.
-         (when coding-system-used
-           (setq last-coding-system-used coding-system-used)))))))
+              method)))))))))
 
 (defun tramp-bundle-read-file-names (vec files)
   "Read file attributes of FILES and with one command fill the cache.
@@ -3643,17 +3639,16 @@ filled are described in `tramp-bundle-read-file-names'."
            (format
             "tramp_bundle_read_file_names <<'%s'\n%s\n%s\n"
             tramp-end-of-heredoc
-            (mapconcat #'tramp-shell-quote-argument
-                       files
-                       "\n")
+            (mapconcat #'tramp-shell-quote-argument files "\n")
             tramp-end-of-heredoc))
           (with-current-buffer (tramp-get-connection-buffer vec)
             ;; Read the expression.
             (goto-char (point-min))
             (read (current-buffer)))))
 
-      (tramp-set-file-property
-       vec (car elt) (cadr elt) (cadr (cdr elt))))))
+      (tramp-set-file-property vec (car elt) "file-exists-p" (nth 1 elt))
+      (tramp-set-file-property vec (car elt) "file-readable-p" (nth 2 elt))
+      (tramp-set-file-property vec (car elt) "file-directory-p" (nth 3 elt)))))
 
 (defvar tramp-vc-registered-file-names nil
   "List used to collect file names, which are checked during `vc-registered'.")
@@ -4261,14 +4256,17 @@ file exists and nonzero exit status otherwise."
                     vec (format "%s %s" result existing))
                    (not (tramp-send-command-and-check
                          vec (format "%s %s" result nonexistent)))))
+            ;; We cannot use `tramp-get-ls-command', this results in an 
infloop.
+            ;; (Bug#65321)
             (ignore-errors
-              (and (setq result (format "%s -d" (tramp-get-ls-command vec)))
+              (and (setq result (format "ls -d >%s" 
(tramp-get-remote-null-device vec)))
                    (tramp-send-command-and-check
                     vec (format "%s %s" result existing))
                    (not (tramp-send-command-and-check
                          vec (format "%s %s" result nonexistent))))))
       (tramp-error
        vec 'file-error "Couldn't find command to check if file exists"))
+    (tramp-set-file-property vec existing "file-exists-p" t)
     result))
 
 (defun tramp-get-sh-extra-args (shell)
@@ -5660,7 +5658,7 @@ Nonexistent directories are removed from spec."
               remote-path :test #'string-equal :from-end t))
 
        ;; Remove non-existing directories.
-       (let ((remote-file-name-inhibit-cache nil))
+       (let (remote-file-name-inhibit-cache)
          (tramp-bundle-read-file-names vec remote-path)
          (cl-remove-if
           (lambda (x) (not (tramp-get-file-property vec x "file-directory-p")))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 9c96a3f6851..f3f2c40e62c 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -1537,6 +1537,8 @@ VEC or USER, or if there is no home directory, return 
nil."
       ;; `set-visited-file-modtime' ourselves later on.
       (let (create-lockfiles)
         (write-region start end tmpfile append 'no-message))
+      ;; Now, `last-coding-system-used' has the right value.  Remember it.
+      (setq coding-system-used last-coding-system-used)
 
       (with-tramp-progress-reporter
          v 3 (format "Moving tmp file %s to %s" tmpfile filename)
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el
index 86cf63507c6..131f632a0fe 100644
--- a/lisp/net/tramp-sshfs.el
+++ b/lisp/net/tramp-sshfs.el
@@ -382,7 +382,9 @@ arguments to pass to the OPERATION."
   (tramp-skeleton-write-region start end filename append visit lockname 
mustbenew
     (let (create-lockfiles)
       (write-region
-       start end (tramp-fuse-local-file-name filename) append 'nomessage))))
+       start end (tramp-fuse-local-file-name filename) append 'nomessage))
+    ;; Now, `last-coding-system-used' has the right value.  Remember it.
+    (setq coding-system-used last-coding-system-used)))
 
 
 ;; File name conversions.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 40efea7bbd0..30602c353b3 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1410,6 +1410,7 @@ during direct remote copying with scp.")
 
 (defconst tramp-completion-file-name-handler-alist
   '((expand-file-name . tramp-completion-handle-expand-file-name)
+    (file-directory-p . tramp-completion-handle-file-directory-p)
     (file-exists-p . tramp-completion-handle-file-exists-p)
     (file-name-all-completions
      . tramp-completion-handle-file-name-all-completions)
@@ -2643,6 +2644,29 @@ not in completion mode."
       (concat dir filename))
      (t (tramp-run-real-handler #'expand-file-name (list filename 
directory))))))
 
+;; This is needed in pcomplete.el.
+(defun tramp-completion-handle-file-directory-p (filename)
+  "Like `file-directory-p' for partial Tramp files."
+  ;; We need special handling only when a method is needed.  Then we
+  ;; regard all files "/method:" or "/[method/" as existent, if
+  ;; "method" is a valid Tramp method.
+  (or (string-equal filename "/")
+      (and ;; Is it a valid method?
+           (not (string-empty-p tramp-postfix-method-format))
+           (string-match
+           (rx
+            (regexp tramp-prefix-regexp)
+            (* (regexp tramp-remote-file-name-spec-regexp)
+               (regexp tramp-postfix-hop-regexp))
+            (group-n 9 (regexp tramp-method-regexp))
+            (? (regexp tramp-postfix-method-regexp))
+             eos)
+            filename)
+          (assoc (match-string 9 filename) tramp-methods)
+          t)
+
+      (tramp-run-real-handler #'file-directory-p (list filename))))
+
 (defun tramp-completion-handle-file-exists-p (filename)
   "Like `file-exists-p' for partial Tramp files."
   ;; We need special handling only when a method is needed.  Then we
@@ -2650,7 +2674,7 @@ not in completion mode."
   ;; "method" is a valid Tramp method.  And we regard all files
   ;; "/method:user@", "/user@" or "/[method/user@" as existent, if
   ;; "user@" is a valid file name completion.  Host completion is
-  ;; performed in the respective backen operation.
+  ;; performed in the respective backend operation.
   (or (and (cond
             ;; Completion styles like `flex' and `substring' check for
             ;; the file name "/".  This does exist.
@@ -3467,7 +3491,15 @@ BODY is the backend specific code."
                                 tramp-crypt-file-name-handler
                                 . inhibit-file-name-handlers))
                              (inhibit-file-name-operation 'write-region))
-                         (find-file-name-handler ,visit 'write-region)))))
+                         (find-file-name-handler ,visit 'write-region))))
+         ;; We use this to save the value of
+         ;; `last-coding-system-used' after writing the tmp file.  At
+         ;; the end of the function, we set `last-coding-system-used'
+         ;; to this saved value.  This way, any intermediary coding
+         ;; systems used while talking to the remote shell or
+         ;; suchlike won't hose this variable.  This approach was
+         ;; snarfed from ange-ftp.el.
+         coding-system-used)
      (with-parsed-tramp-file-name filename nil
        (if handler
           (progn
@@ -3514,8 +3546,6 @@ BODY is the backend specific code."
           ;; likely that it is needed shortly after `write-region'.
           (tramp-set-file-property v localname "file-exists-p" t)
 
-          ;; We must protect `last-coding-system-used', now we have
-          ;; set it to its correct value.
           (let (last-coding-system-used (need-chown t))
             ;; Set file modification time.
             (when (or (eq ,visit t) (stringp ,visit))
@@ -3535,7 +3565,7 @@ BODY is the backend specific code."
                (tramp-set-file-uid-gid filename uid gid))
 
             ;; Set extended attributes.  We ignore possible errors,
-            ;; because ACL strings could be incompatible.
+            ;; because ACL strings or SELinux contexts could be incompatible.
             (when attributes
               (ignore-errors
                 (set-file-extended-attributes filename attributes)))
@@ -3554,7 +3584,11 @@ BODY is the backend specific code."
             (when (and (null noninteractive)
                        (or (eq ,visit t) (string-or-null-p ,visit)))
               (tramp-message v 0 "Wrote %s" filename))
-            (run-hooks 'tramp-handle-write-region-hook)))))))
+            (run-hooks 'tramp-handle-write-region-hook))))
+
+       ;; Make `last-coding-system-used' have the right value.
+       (when coding-system-used
+        (setq last-coding-system-used coding-system-used)))))
 
 ;;; Common file name handler functions for different backends:
 
@@ -5202,6 +5236,8 @@ of."
       ;; `set-visited-file-modtime' ourselves later on.
       (let (create-lockfiles)
         (write-region start end tmpfile append 'no-message))
+      ;; Now, `last-coding-system-used' has the right value.  Remember it.
+      (setq coding-system-used last-coding-system-used)
       (condition-case nil
          (rename-file tmpfile filename 'ok-if-already-exists)
        (error
diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el
index 0b816a7c13c..a833037ca2b 100644
--- a/lisp/org/ob-tangle.el
+++ b/lisp/org/ob-tangle.el
@@ -357,7 +357,7 @@ Did you give the decimal value %1$d by mistake?" mode)))
     (error "File mode %S not recognized as a valid format." mode))
    ((string-match-p "^o0?[0-7][0-7][0-7]$" mode)
     (string-to-number (replace-regexp-in-string "^o" "" mode) 8))
-   ((string-match-p 
"^[ugoa]*\\(?:[+-=][rwxXstugo]*\\)+\\(,[ugoa]*\\(?:[+-=][rwxXstugo]*\\)+\\)*$" 
mode)
+   ((string-match-p 
"^[ugoa]*\\(?:[+=-][rwxXstugo]*\\)+\\(,[ugoa]*\\(?:[+=-][rwxXstugo]*\\)+\\)*$" 
mode)
     ;; Match regexp taken from `file-modes-symbolic-to-number'.
     (file-modes-symbolic-to-number mode org-babel-tangle-default-file-mode))
    ((string-match-p "^[r-][w-][xs-][r-][w-][xs-][r-][w-][x-]$" mode)
diff --git a/lisp/org/ol-bibtex.el b/lisp/org/ol-bibtex.el
index fd9517233e0..a16a4b39277 100644
--- a/lisp/org/ol-bibtex.el
+++ b/lisp/org/ol-bibtex.el
@@ -761,7 +761,10 @@ drawer."
   "If kill ring holds a bibtex entry yank it as an Org headline."
   (interactive)
   (let (entry)
-    (with-temp-buffer (yank 1) (setf entry (org-bibtex-read)))
+    (with-temp-buffer
+      (yank 1)
+      (bibtex-mode)
+      (setf entry (org-bibtex-read)))
     (if entry
        (org-bibtex-write)
       (error "Yanked text does not appear to contain a BibTeX entry"))))
diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el
index d7fe14cd5e1..6ab313e1218 100644
--- a/lisp/org/org-clock.el
+++ b/lisp/org/org-clock.el
@@ -51,6 +51,8 @@
 (declare-function org-dynamic-block-define "org" (type func))
 (declare-function w32-notification-notify "w32fns.c" (&rest params))
 (declare-function w32-notification-close "w32fns.c" (&rest params))
+(declare-function haiku-notifications-notify "haikuselect.c")
+(declare-function android-notifications-notify "androidselect.c")
 
 (defvar org-frame-title-format-backup nil)
 (defvar org-state)
@@ -855,6 +857,18 @@ use libnotify if available, or fall back on a message."
        ((stringp org-show-notification-handler)
         (start-process "emacs-timer-notification" nil
                        org-show-notification-handler notification))
+        ((fboundp 'haiku-notifications-notify)
+         ;; N.B. timeouts are not available under Haiku.
+         (haiku-notifications-notify :title "Org mode message"
+                                     :body notification
+                                     :urgency 'low))
+        ((fboundp 'android-notifications-notify)
+         ;; N.B. timeouts are not available under Haiku or Android.
+         (android-notifications-notify :title "Org mode message"
+                                       :body notification
+                                       ;; Low urgency notifications
+                                       ;; are by default hidden.
+                                       :urgency 'normal))
        ((fboundp 'w32-notification-notify)
         (let ((id (w32-notification-notify
                    :title "Org mode message"
@@ -2069,6 +2083,7 @@ Use `\\[org-clock-remove-overlays]' to remove the subtree 
times."
               h m))))
 
 (defvar-local org-clock-overlays nil)
+(put 'org-clock-overlays 'permanent-local t)
 
 (defun org-clock-put-overlay (time)
   "Put an overlay on the headline at point, displaying TIME.
diff --git a/lisp/org/org-colview.el b/lisp/org/org-colview.el
index 92a3b473d15..28cfd0d910c 100644
--- a/lisp/org/org-colview.el
+++ b/lisp/org/org-colview.el
@@ -116,6 +116,7 @@ in `org-columns-summary-types-default', which see."
 
 (defvar-local org-columns-overlays nil
   "Holds the list of current column overlays.")
+(put 'org-columns-overlays 'permanent-local t)
 
 (defvar-local org-columns-current-fmt nil
   "Local variable, holds the currently active column format.")
diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el
index df43ebcf0c5..296468eed1a 100644
--- a/lisp/org/org-element.el
+++ b/lisp/org/org-element.el
@@ -6567,7 +6567,9 @@ If you observe Emacs hangs frequently, please report this 
to Org mode mailing li
                  ;; Make sure that we return referenced element in cache
                  ;; that can be altered directly.
                  (if element
-                     (setq element (or (org-element--cache-put element) 
element))
+                     (progn
+                       (org-element-put-property element :granularity 'element)
+                       (setq element (or (org-element--cache-put element) 
element)))
                    ;; Nothing to parse (i.e. empty file).
                    (throw 'exit parent))
                  (unless (or (not (org-element--cache-active-p)) parent)
@@ -6942,12 +6944,13 @@ known element in cache (it may start after END)."
                           (let ((current (org-with-point-at 
(org-element-property :begin up)
                                            (org-element-with-disabled-cache
                                              (and (looking-at-p 
org-element-headline-re)
-                                                  
(org-element-headline-parser))))))
+                                                  (org-element-headline-parser 
nil 'fast))))))
                             (when (eq 'headline (org-element-type current))
                               (org-element--cache-log-message
                                "Found non-robust headline that can be updated 
individually: %S"
                                (org-element--format-element current))
                               (org-element-set-element up current)
+                              (org-element-put-property up :granularity 
'element)
                               t)))
                      ;; If UP is org-data, the situation is similar to
                      ;; headline case.  We just need to re-parse the
diff --git a/lisp/org/org-num.el b/lisp/org/org-num.el
index cbe5e455ea6..807fa66223b 100644
--- a/lisp/org/org-num.el
+++ b/lisp/org/org-num.el
@@ -156,6 +156,7 @@ control tag inheritance."
 
 (defvar-local org-num--overlays nil
   "Ordered list of overlays used for numbering outlines.")
+(put 'org-num--overlays 'permanent-local t)
 
 (defvar-local org-num--skip-level nil
   "Level below which headlines from current tree are not numbered.
diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el
index 9a72eb5f314..221497f53b7 100644
--- a/lisp/org/org-table.el
+++ b/lisp/org/org-table.el
@@ -477,6 +477,7 @@ This may be useful when columns have been shrunk."
       (format "|%s" (mapconcat #'identity (reverse str) "")))))
 
 (defvar-local org-table-header-overlay nil)
+(put 'org-table-header-overlay 'permanent-local t)
 (defun org-table-header-set-header ()
   "Display the header of the table at point."
   (let ((gcol temporary-goal-column))
@@ -3812,6 +3813,7 @@ FACE, when non-nil, for the highlight."
 
 (defvar-local org-table-coordinate-overlays nil
   "Collects the coordinate grid overlays, so that they can be removed.")
+(put 'org-table-coordinate-overlays 'permanent-local t)
 
 (defun org-table-overlay-coordinates ()
   "Add overlays to the table at point, to show row/column coordinates."
diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el
index 9116e298aa9..57e406b24fc 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.6.7-5-gd1d0c3"))
+   (let ((org-git-version "release_9.6.7-13-g99cc96"))
      org-git-version))
 
 (provide 'org-version)
diff --git a/lisp/org/org.el b/lisp/org/org.el
index d49bc9645f5..175e095e806 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -5893,6 +5893,8 @@ needs to be inserted at a specific position in the 
font-lock sequence.")
 
 (defvar-local org-custom-properties-overlays nil
   "List of overlays used for custom properties.")
+;; Preserve when switching modes or when restarting Org.
+(put 'org-custom-properties-overlays 'permanent-local t)
 
 (defun org-toggle-custom-properties-visibility ()
   "Display or hide properties in `org-custom-properties'."
@@ -10673,6 +10675,7 @@ D      Show deadlines and scheduled items between a 
date range."
 
 (defvar-local org-occur-highlights nil
   "List of overlays used for occur matches.")
+(put 'org-occur-highlights 'permanent-local t)
 (defvar-local org-occur-parameters nil
   "Parameters of the active org-occur calls.
 This is a list, each call to org-occur pushes as cons cell,
@@ -16159,6 +16162,10 @@ SNIPPETS-P indicates if this is run to create snippet 
images for HTML."
 ;; Image display
 
 (defvar-local org-inline-image-overlays nil)
+;; Preserve when switching modes or when restarting Org.
+;; If we clear the overlay list and later enable Or mode, the existing
+;; image overlays will never be cleared by `org-toggle-inline-images'.
+(put 'org-inline-image-overlays 'permanent-local t)
 
 (defun org--inline-image-overlays (&optional beg end)
   "Return image overlays between BEG and END."
diff --git a/lisp/org/ox-publish.el b/lisp/org/ox-publish.el
index f9c3877d7df..cff34f05882 100644
--- a/lisp/org/ox-publish.el
+++ b/lisp/org/ox-publish.el
@@ -1183,7 +1183,8 @@ references with `org-export-get-reference'."
                     (org-link-search search nil t)
                   (error
                    (signal 'org-link-broken (cdr err)))))
-              (and (org-at-heading-p)
+              (and (derived-mode-p 'org-mode)
+                    (org-at-heading-p)
                    (org-string-nw-p (org-entry-get (point) "CUSTOM_ID"))))))))
    ((not org-publish-cache)
     (progn
diff --git a/lisp/org/ox.el b/lisp/org/ox.el
index 6f819def93a..94cc5a22881 100644
--- a/lisp/org/ox.el
+++ b/lisp/org/ox.el
@@ -5684,11 +5684,8 @@ transcoding it."
      (primary-closing
       :utf-8 " »" :html "&nbsp;&raquo;" :latex "\\fg{}"
       :texinfo "@tie{}@guillemetright{}")
-     (secondary-opening
-      :utf-8 "« " :html "&laquo;&nbsp;" :latex "\\og "
-      :texinfo "@guillemetleft{}@tie{}")
-     (secondary-closing :utf-8 " »" :html "&nbsp;&raquo;" :latex "\\fg{}"
-                       :texinfo "@tie{}@guillemetright{}")
+     (secondary-opening :utf-8 "“" :html "&ldquo;" :latex "``" :texinfo "``")
+     (secondary-closing :utf-8 "”" :html "&rdquo;" :latex "''" :texinfo "''")
      (apostrophe :utf-8 "’" :html "&rsquo;"))
     ("is"
      (primary-opening
diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el
index 1a77e3b248f..e6b67256a4c 100644
--- a/lisp/pcmpl-unix.el
+++ b/lisp/pcmpl-unix.el
@@ -227,7 +227,7 @@ documentation), this function returns nil."
 ;;;###autoload(defalias 'pcomplete/sha224sum 'pcomplete/md5sum)
 ;;;###autoload(defalias 'pcomplete/sha256sum 'pcomplete/md5sum)
 ;;;###autoload(defalias 'pcomplete/sha384sum 'pcomplete/md5sum)
-;;;###autoload(defalias 'pcomplete/sha521sum 'pcomplete/md5sum)
+;;;###autoload(defalias 'pcomplete/sha512sum 'pcomplete/md5sum)
 
 ;;;###autoload
 (defun pcomplete/sort ()
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index c7ec228c1db..151611f94b7 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -138,6 +138,11 @@
   "A regexp of names to be disregarded during directory completion."
   :type '(choice regexp (const :tag "None" nil)))
 
+(defcustom pcomplete-remote-file-ignore nil
+  "Whether to ignore remote file names."
+  :version "30.1"
+  :type 'boolean)
+
 (define-obsolete-variable-alias 'pcomplete-ignore-case 'completion-ignore-case
   "28.1")
 
@@ -924,7 +929,10 @@ this is `comint-dynamic-complete-functions'."
                            (sort comps pcomplete-compare-entry-function)))
                      ,@(cdr (completion-file-name-table s p a)))
         (let ((completion-ignored-extensions nil)
-             (completion-ignore-case completion-ignore-case))
+             (completion-ignore-case completion-ignore-case)
+              (tramp-mode (and tramp-mode (not pcomplete-remote-file-ignore)))
+              (non-essential (not (file-remote-p s)))
+              (minibuffer-completing-file-name (not (file-remote-p s))))
           (completion-table-with-predicate
            #'comint-completion-file-name-table pred 'strict s p a))))))
 
@@ -1322,7 +1330,8 @@ If specific documentation can't be given, be generic."
   "Sort and remove multiples in SEQUENCE.
 Sequence should be a vector or list of strings."
   (sort (seq-uniq sequence) #'string-lessp))
-(define-obsolete-function-alias 'pcomplete-uniqify-list 
#'pcomplete-uniquify-list "27.1")
+(define-obsolete-function-alias
+  'pcomplete-uniqify-list #'pcomplete-uniquify-list "27.1")
 
 (defun pcomplete-process-result (cmd &rest args)
   "Call CMD using `call-process' and return the simplest result."
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index ac867a1351c..488f6781254 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -519,38 +519,41 @@ the height of the current window."
         (desired-vscroll (if start-posn
                               (- delta (cdr (posn-x-y start-posn)))
                             (+ current-vs delta)))
-         (edges (window-edges nil t))
-         (usable-height (- (nth 3 edges)
-                           (nth 1 edges)))
-         (next-pos (save-excursion
-                     (goto-char desired-start)
-                     (when (zerop (vertical-motion (1+ scroll-margin)))
-                       (set-window-start nil desired-start)
-                       (signal 'end-of-buffer nil))
-                     (while (when-let ((posn (posn-at-point)))
-                              (< (cdr (posn-x-y posn)) delta))
-                       (when (zerop (vertical-motion 1))
-                         (set-window-start nil desired-start)
-                         (signal 'end-of-buffer nil)))
-                     (point)))
          (scroll-preserve-screen-position nil)
-         (auto-window-vscroll nil))
-    (when (and (or (< (point) next-pos))
-               (let ((pos-visibility (pos-visible-in-window-p next-pos nil t)))
-                 (and pos-visibility
-                      (or (eq (length pos-visibility) 2)
-                          (when-let* ((posn (posn-at-point next-pos)))
-                            (> (cdr (posn-object-width-height posn))
-                               usable-height))))))
-      (goto-char next-pos))
-    (set-window-start nil (if (zerop (window-hscroll))
-                              desired-start
-                            (save-excursion
-                              (goto-char desired-start)
-                              (beginning-of-visual-line)
-                              (point)))
-                      t)
-    (set-window-vscroll nil desired-vscroll t t)))
+         (auto-window-vscroll nil)
+         (new-start-position (if (zerop (window-hscroll))
+                                 desired-start
+                               (save-excursion
+                                 (goto-char desired-start)
+                                 (beginning-of-visual-line)
+                                 (point)))))
+    (set-window-start nil new-start-position
+                      (not (zerop desired-vscroll)))
+    (set-window-vscroll nil desired-vscroll t t)
+    ;; Constrain point to a location that will not result in
+    ;; recentering, if it is no longer completely visible.
+    (unless (pos-visible-in-window-p (point))
+      ;; If desired-vscroll is 0, target the window start itself.  But
+      ;; in any other case, target the line immediately below the
+      ;; window start, unless that line is itself invisible.  This
+      ;; improves the appearance of the window by maintaining the
+      ;; cursor row in a fully visible state.
+      (if (zerop desired-vscroll)
+          (goto-char new-start-position)
+        (let ((line-after (save-excursion
+                            (goto-char new-start-position)
+                            (if (zerop (vertical-motion 1))
+                                (progn
+                                  (set-window-vscroll nil 0 t t)
+                                  nil) ; nil means move to new-start-position.
+                              (point)))))
+          (if (not line-after)
+              (progn
+                (goto-char new-start-position)
+                (signal 'end-of-buffer nil))
+            (if (pos-visible-in-window-p line-after nil t)
+                (goto-char line-after)
+              (goto-char new-start-position))))))))
 
 (defun pixel-scroll-precision-scroll-down (delta)
   "Scroll the current window down by DELTA pixels."
@@ -569,27 +572,12 @@ the height of the current window."
   (let* ((edges (window-edges nil t nil t))
          (max-y (- (nth 3 edges)
                    (nth 1 edges)))
-         (usable-height max-y)
          (posn (posn-at-x-y 0 (+ (window-tab-line-height)
                                  (window-header-line-height)
                                  (- max-y delta))))
-         (point (posn-point posn))
-         (up-point (and point
-                        (save-excursion
-                          (goto-char point)
-                          (vertical-motion (- (1+ scroll-margin)))
-                          (point)))))
-    (when (and point (> (point) up-point))
-      (when (let ((pos-visible (pos-visible-in-window-p up-point nil t)))
-              (or (eq (length pos-visible) 2)
-                  (when-let* ((posn (posn-at-point up-point))
-                              (edges (window-edges nil t))
-                              (usable-height (- (nth 3 edges)
-                                                (nth 1 edges))))
-                    (> (cdr (posn-object-width-height posn))
-                       usable-height))))
-        (goto-char up-point)))
-    (let ((current-vscroll (window-vscroll nil t)))
+         (point (posn-point posn)))
+    (let ((current-vscroll (window-vscroll nil t))
+          (wanted-pos (window-start)))
       (setq delta (- delta current-vscroll))
       (set-window-vscroll nil 0 t t)
       (when (> delta 0)
@@ -598,16 +586,25 @@ the height of the current window."
                                              start nil nil nil t))
                (height (nth 1 dims))
                (position (nth 2 dims)))
-          (set-window-start nil position t)
-          ;; If the line above is taller than the window height (i.e. there's
-          ;; a very tall image), keep point on it.
-          (when (> height usable-height)
-            (goto-char position))
+          (setq wanted-pos position)
           (when (or (not position) (eq position start))
             (signal 'beginning-of-buffer nil))
           (setq delta (- delta height))))
+      (set-window-start nil wanted-pos
+                        (not (zerop delta)))
       (when (< delta 0)
-        (set-window-vscroll nil (- delta) t t)))))
+        (set-window-vscroll nil (- delta) t t))
+      ;; vscroll and the window start are now set.  Move point to a
+      ;; position where redisplay will not recenter, if it is now
+      ;; outside the window.
+      (unless (pos-visible-in-window-p (point))
+        (let ((up-pos (save-excursion
+                        (goto-char point)
+                        (vertical-motion -1)
+                        (point))))
+          (if (pos-visible-in-window-p up-pos nil t)
+              (goto-char up-pos)
+            (goto-char (window-start))))))))
 
 (defun pixel-scroll-precision-interpolate (delta &optional old-window factor)
   "Interpolate a scroll of DELTA pixels.
@@ -860,7 +857,9 @@ precisely, according to the turning of the mouse wheel."
   :group 'mouse
   :keymap pixel-scroll-precision-mode-map
   (setq mwheel-coalesce-scroll-events
-        (not pixel-scroll-precision-mode)))
+        (not pixel-scroll-precision-mode))
+  (setq-default make-cursor-line-fully-visible
+                (not pixel-scroll-precision-mode)))
 
 (provide 'pixel-scroll)
 ;;; pixel-scroll.el ends here
diff --git a/lisp/play/cookie1.el b/lisp/play/cookie1.el
index 559b74084e1..e5c0d6a14d2 100644
--- a/lisp/play/cookie1.el
+++ b/lisp/play/cookie1.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1993, 2001-2023 Free Software Foundation, Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: games, extensions
 ;; Created: Mon Mar 22 17:06:26 1993
diff --git a/lisp/progmodes/asm-mode.el b/lisp/progmodes/asm-mode.el
index 2a5105fe164..0f5af9803a5 100644
--- a/lisp/progmodes/asm-mode.el
+++ b/lisp/progmodes/asm-mode.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1991, 2001-2023 Free Software Foundation, Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: languages
 
@@ -23,7 +23,7 @@
 
 ;;; Commentary:
 
-;; This mode was written by Eric S. Raymond <esr@snark.thyrsus.com>,
+;; This mode was written by Eric S. Raymond <esr@thyrsus.com>,
 ;; inspired by an earlier `asm-mode' by Martin Neitzel.
 
 ;; This major mode is based on `prog-mode'.  It defines a private
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 6d151db8a83..f85cc0909dd 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -1862,6 +1862,9 @@ process from additional information inserted by Emacs."
     (apply #'insert args)
     (put-text-property start (point) 'compilation-annotation t)))
 
+(defvar-local compilation--start-time nil
+  "The time when the compilation started as returned by `float-time'.")
+
 ;;;###autoload
 (defun compilation-start (command &optional mode name-function highlight-regexp
                                   continue)
@@ -1993,6 +1996,7 @@ Returns the compilation buffer created."
                  mode-name
                 (substring (current-time-string) 0 19))
         command "\n")
+        (setq compilation--start-time (float-time))
        (setq thisdir default-directory))
       (set-buffer-modified-p nil))
     ;; Pop up the compilation buffer.
@@ -2480,7 +2484,14 @@ commands of Compilation major mode are available.  See
        (message "%s" (cdr status)))
     (if (bolp)
        (forward-char -1))
-    (compilation-insert-annotation " at " (substring (current-time-string) 0 
19))
+    (compilation-insert-annotation
+     " at "
+     (substring (current-time-string) 0 19)
+     ", duration "
+     (let ((elapsed (- (float-time) compilation--start-time)))
+       (cond ((< elapsed 10) (format "%.2f s" elapsed))
+             ((< elapsed 60) (format "%.1f s" elapsed))
+             (t (format-seconds "%h:%02m:%02s" elapsed)))))
     (goto-char (point-max))
     ;; Prevent that message from being recognized as a compilation error.
     (add-text-properties omax (point)
diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el
index db036aab685..5291efda175 100644
--- a/lisp/progmodes/csharp-mode.el
+++ b/lisp/progmodes/csharp-mode.el
@@ -816,7 +816,7 @@ compilation and evaluation time conflicts."
    :language 'c-sharp
    :feature 'definition
    :override t
-   '((qualified_name (identifier) @font-lock-type-face)
+   `((qualified_name (identifier) @font-lock-type-face)
      (using_directive (identifier) @font-lock-type-face)
      (using_directive (name_equals
                        (identifier) @font-lock-type-face))
@@ -843,8 +843,13 @@ compilation and evaluation time conflicts."
      (class_declaration (identifier) @font-lock-type-face)
 
      (constructor_declaration name: (_) @font-lock-type-face)
-
-     (method_declaration type: [(identifier) (void_keyword)] 
@font-lock-type-face)
+     ;;; Handle different releases of tree-sitter-c-sharp.
+     ;;; Check if keyword void_keyword is available, then return the correct 
rule."
+     ,@(condition-case nil
+           (progn (treesit-query-capture 'csharp '((void_keyword) @capture))
+                  `((method_declaration type: [(identifier) (void_keyword)] 
@font-lock-type-face)))
+         (error
+          `((method_declaration type: [(identifier) (predefined_type)] 
@font-lock-type-face))))
      (method_declaration type: (generic_name (identifier) 
@font-lock-type-face))
      (method_declaration name: (_) @font-lock-function-name-face)
 
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 37875e3d7f1..65daa0941d5 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -219,9 +219,11 @@ chosen (interactively or automatically)."
                                  . ("dart" "language-server"
                                     "--client-id" "emacs.eglot-dart"))
                                 ((elixir-mode elixir-ts-mode heex-ts-mode)
-                                 . ,(if (and (fboundp 
'w32-shell-dos-semantics)                                             
(w32-shell-dos-semantics))
+                                 . ,(if (and (fboundp 'w32-shell-dos-semantics)
+                                             (w32-shell-dos-semantics))
                                         '("language_server.bat")
-                                      '("language_server.sh")))
+                                      (eglot-alternatives
+                                       '("language_server.sh" 
"start_lexical.sh"))))
                                 (ada-mode . ("ada_language_server"))
                                 (scala-mode . ,(eglot-alternatives
                                                 '("metals" "metals-emacs")))
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 955b708aee9..3e1803fcc98 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -84,6 +84,12 @@ All commands in `lisp-mode-shared-map' are inherited by this 
map."
      :help "Byte-compile the current file (if it has changed), then load 
compiled code"]
     ["Byte-recompile Directory..." byte-recompile-directory
      :help "Recompile every `.el' file in DIRECTORY that needs recompilation"]
+    ["Native-compile This File" emacs-lisp-native-compile
+     :help "Compile the current file containing the current buffer to native 
code"
+     :active (native-comp-available-p)]
+    ["Native-compile and Load" emacs-lisp-native-compile-and-load
+     :help "Compile the current file to native code, then load compiled native 
code"
+     :active (native-comp-available-p)]
     ["Disassemble Byte Compiled Object..." disassemble
      :help "Print disassembled code for OBJECT in a buffer"]
     "---"
@@ -217,6 +223,16 @@ All commands in `lisp-mode-shared-map' are inherited by 
this map."
 (declare-function native-compile "comp")
 (declare-function comp-write-bytecode-file "comp")
 
+(defun emacs-lisp-native-compile ()
+  "Native-compile synchronously the current file (if it has changed)."
+  (interactive nil emacs-lisp-mode)
+  (emacs-lisp--before-compile-buffer)
+  (let* ((byte+native-compile t)
+         (byte-to-native-output-buffer-file nil)
+         (eln (native-compile buffer-file-name)))
+    (when eln
+      (comp-write-bytecode-file eln))))
+
 (defun emacs-lisp-native-compile-and-load ()
   "Native-compile synchronously the current file (if it has changed).
 Load the compiled code when finished.
@@ -225,11 +241,8 @@ Use `emacs-lisp-byte-compile-and-load' in combination with
 `native-comp-jit-compilation' set to t to achieve asynchronous
 native compilation."
   (interactive nil emacs-lisp-mode)
-  (emacs-lisp--before-compile-buffer)
-  (let ((byte+native-compile t)
-        (byte-to-native-output-buffer-file nil))
-    (when-let ((eln (native-compile buffer-file-name)))
-      (load (file-name-sans-extension (comp-write-bytecode-file eln))))))
+  (when-let ((byte-file (emacs-lisp-native-compile)))
+    (load (file-name-sans-extension byte-file))))
 
 (defun emacs-lisp-macroexpand ()
   "Macroexpand the form after point.
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 2b178e50684..09860a4cbde 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 1992-1996, 1998, 2000-2023 Free Software Foundation,
 ;; Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: unix, tools
 
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el
index 488e6aa3d2d..7bdaa6b1b6f 100644
--- a/lisp/progmodes/idlwave.el
+++ b/lisp/progmodes/idlwave.el
@@ -4311,10 +4311,7 @@ automatically when called interactively.  When you need 
routine
 information updated immediately, leave NO-CONCATENATE nil."
   (interactive "P\np")
   ;; Stop any idle processing
-  (if (or (and (fboundp 'itimerp)
-              (itimerp idlwave-load-rinfo-idle-timer))
-         (and (fboundp 'timerp)
-              (timerp idlwave-load-rinfo-idle-timer)))
+  (if (timerp idlwave-load-rinfo-idle-timer)
       (cancel-timer idlwave-load-rinfo-idle-timer))
   (cond
    ((equal arg '(64))
@@ -4388,10 +4385,7 @@ information updated immediately, leave NO-CONCATENATE 
nil."
 (defvar idlwave-load-rinfo-steps-done (make-vector 6 nil))
 (defvar idlwave-load-rinfo-idle-timer nil)
 (defun idlwave-start-load-rinfo-timer ()
-  (if (or (and (fboundp 'itimerp)
-              (itimerp idlwave-load-rinfo-idle-timer))
-         (and (fboundp 'timerp)
-              (timerp idlwave-load-rinfo-idle-timer)))
+  (if (timerp idlwave-load-rinfo-idle-timer)
       (cancel-timer idlwave-load-rinfo-idle-timer))
   (setq idlwave-load-rinfo-steps-done (make-vector 6 nil))
   (setq idlwave-load-rinfo-idle-timer nil)
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index f2d7d3d3ecb..c7a031697f1 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3474,7 +3474,7 @@ Check if a node type is available, then return the right 
indent rules."
        ((parent-is "statement_block") parent-bol js-indent-level)
 
        ;; JSX
-       (js-jsx--treesit-indent-compatibility-bb1f97b)
+       ,@(js-jsx--treesit-indent-compatibility-bb1f97b)
        ((node-is "jsx_closing_element") parent 0)
        ((match "jsx_element" "statement") parent js-indent-level)
        ((parent-is "jsx_element") parent js-indent-level)
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
index 308ba69cb9a..017a551bc05 100644
--- a/lisp/progmodes/make-mode.el
+++ b/lisp/progmodes/make-mode.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 1992-2023 Free Software Foundation, Inc.
 
 ;; Author: Thomas Neumann <tom@smart.bo.open.de>
-;;     Eric S. Raymond <esr@snark.thyrsus.com>
+;;     Eric S. Raymond <esr@thyrsus.com>
 ;; Maintainer: emacs-devel@gnu.org
 ;; Adapted-By: ESR
 ;; Keywords: unix, tools
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 2c5b07ce750..6f35b3cc1b1 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -994,7 +994,8 @@ pattern to search for."
   "Visit a file (with completion) in the current project.
 
 The filename at point (determined by `thing-at-point'), if any,
-is available as part of \"future history\".
+is available as part of \"future history\".  If none, the current
+buffer's file name is used.
 
 If INCLUDE-ALL is non-nil, or with prefix argument when called
 interactively, include all files under the project root, except
@@ -1005,7 +1006,16 @@ for VCS directories listed in 
`vc-directory-exclusion-list'."
          (dirs (list root)))
     (project-find-file-in
      (or (thing-at-point 'filename)
-         (and buffer-file-name (file-relative-name buffer-file-name root)))
+         (and buffer-file-name
+              (if-let (buffer-proj (and project-current-directory-override
+                                        (project-current nil 
default-directory)))
+                  ;; Allow using the relative file name of the current
+                  ;; buffer in "other project" as well.
+                  (let ((buffer-root (project-root buffer-proj)))
+                    ;; file-name-concat requires Emacs 28+
+                    (concat (file-name-as-directory root)
+                            (file-relative-name buffer-file-name buffer-root)))
+                buffer-file-name)))
      dirs pr include-all)))
 
 ;;;###autoload
@@ -1058,6 +1068,11 @@ by the user at will."
                          (setq all-files
                                (delete common-parent-directory all-files))
                          t))
+         (mb-default (if (and common-parent-directory
+                              mb-default
+                              (file-name-absolute-p mb-default))
+                         (file-relative-name mb-default 
common-parent-directory)
+                       mb-default))
          (substrings (mapcar (lambda (s) (substring s cpd-length)) all-files))
          (_ (when included-cpd
               (setq substrings (cons "./" substrings))))
@@ -1092,7 +1107,7 @@ by the user at will."
 (defun project-find-file-in (suggested-filename dirs project &optional 
include-all)
   "Complete a file name in DIRS in PROJECT and visit the result.
 
-SUGGESTED-FILENAME is a relative file name, or part of it, which
+SUGGESTED-FILENAME is a file name, or part of it, which
 is used as part of \"future history\".
 
 If INCLUDE-ALL is non-nil, or with prefix argument when called
@@ -1476,6 +1491,7 @@ Used by `project-kill-buffers'."
   :package-version '(project . "0.8.2"))
 ;;;###autoload(put 'project-kill-buffers-display-buffer-list 
'safe-local-variable #'booleanp)
 
+;; FIXME: Could this be replaced by `buffer-match-p' in Emacs 29+?
 (defun project--buffer-check (buf conditions)
   "Check if buffer BUF matches any element of the list CONDITIONS.
 See `project-kill-buffer-conditions' or
@@ -1828,9 +1844,13 @@ listed in the dispatch menu produced from 
`project-switch-commands'."
      (let ((key (if key
                     (vector key)
                   (where-is-internal cmd (list project-prefix-map) t))))
-       (format "[%s] %s"
-               (propertize (key-description key) 'face 'bold)
-               label)))
+       (if (facep 'help-key-binding)
+           (format "%s %s"
+                   (propertize (key-description key) 'face 'help-key-binding)
+                   label)
+         (format "[%s] %s"
+                 (propertize (key-description key) 'face 'bold)
+                 label))))
    project-switch-commands
    "  "))
 
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 1930f68617c..4b940b3f13b 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -6911,6 +6911,10 @@ implementations: `python-mode' and `python-ts-mode'."
                python-shell-completion-complete-or-indent))
   (function-put sym 'command-modes '(python-base-mode inferior-python-mode)))
 
+;;;###autoload
+(add-to-list 'auto-mode-alist
+             '("/\\(?:Pipfile\\|\\.?flake8\\)\\'" . conf-mode))
+
 (provide 'python)
 
 ;;; python.el ends here
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 89d62ab3a61..61c8525b77a 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -3096,9 +3096,7 @@ displayed."
 (defun sql-accumulate-and-indent ()
   "Continue SQL statement on the next line."
   (interactive)
-  (if (fboundp 'comint-accumulate)
-      (comint-accumulate)
-    (newline))
+  (comint-accumulate)
   (indent-according-to-mode))
 
 (defun sql-help-list-products (indent freep)
@@ -4033,7 +4031,7 @@ The list is maintained in SQL interactive buffers.")
 (defun sql--completion-table (string pred action)
   (when sql-completion-sqlbuf
     (with-current-buffer sql-completion-sqlbuf
-      (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" 
string)
+      (let ((schema (and (string-match "\\`\\(\\sw\\(?:\\sw\\|\\s_\\)*\\)[.]" 
string)
                          (downcase (match-string 1 string)))))
 
         ;; If we haven't loaded any object name yet, load local schema
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 643eea1b0a3..3f75f8d7132 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1613,7 +1613,8 @@ 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* ((query-replace-read-from-default 'find-tag-default)
+   (let* ((query-replace-read-from-default
+           (lambda () (xref-backend-identifier-at-point (xref-find-backend))))
           (common
            (query-replace-read-args "Query replace identifier" nil)))
      (list (nth 0 common) (nth 1 common))))
diff --git a/lisp/server.el b/lisp/server.el
index ba7e02d2555..10f15598221 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -330,6 +330,9 @@ ENV should be in the same format as `process-environment'."
 (defun server-delete-client (proc &optional noframe)
   "Delete PROC, including its buffers, terminals and frames.
 If NOFRAME is non-nil, let the frames live.
+If NOFRAME is the symbol \\='dont-kill-client, also don't
+delete PROC or its terminals, just kill its buffers: this is
+for when `find-alternate-file' calls this via `kill-buffer-hook'.
 Updates `server-clients'."
   (server-log (concat "server-delete-client" (if noframe " noframe")) proc)
   ;; Force a new lookup of client (prevents infinite recursion).
@@ -366,23 +369,28 @@ Updates `server-clients'."
            (set-frame-parameter frame 'client nil)
            (delete-frame frame))))
 
-      (setq server-clients (delq proc server-clients))
+      (or (eq noframe 'dont-kill-client)
+          (setq server-clients (delq proc server-clients)))
 
       ;; Delete the client's tty, except on Windows (both GUI and
       ;; console), where there's only one terminal and does not make
       ;; sense to delete it, or if we are explicitly told not.
       (unless (or (eq system-type 'windows-nt)
+                  ;; 'find-alternate-file' caused the last client
+                  ;; buffer to be killed, but we will reuse the client
+                  ;; for another buffer.
+                  (eq noframe 'dont-kill-client)
                   (process-get proc 'no-delete-terminal))
        (let ((terminal (process-get proc 'terminal)))
          ;; Only delete the terminal if it is non-nil.
          (when (and terminal (eq (terminal-live-p terminal) t))
            (delete-terminal terminal))))
 
-      ;; Delete the client's process.
-      (if (eq (process-status proc) 'open)
-         (delete-process proc))
-
-      (server-log "Deleted" proc))))
+      ;; Delete the client's process (or don't).
+      (unless (eq noframe 'dont-kill-client)
+        (if (eq (process-status proc) 'open)
+           (delete-process proc))
+        (server-log "Deleted" proc)))))
 
 (defvar server-log-time-function #'current-time-string
   "Function to generate timestamps for `server-buffer'.")
@@ -1590,7 +1598,8 @@ FOR-KILLING if non-nil indicates that we are called from 
`kill-buffer'."
                ;; frames, which might change the current buffer.  We
                ;; don't want that (bug#640).
                (save-current-buffer
-                 (server-delete-client proc))
+                 (server-delete-client proc
+                                        find-alternate-file-dont-kill-client))
              (server-delete-client proc))))))
     (when (and (bufferp buffer) (buffer-name buffer))
       ;; We may or may not kill this buffer;
diff --git a/lisp/shell.el b/lisp/shell.el
index 7ea9d1c2ead..b554ee5add9 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -595,6 +595,8 @@ Shell buffers.  It implements `shell-completion-execonly' 
for
   ;; Don't use pcomplete's defaulting mechanism, rely on
   ;; shell-dynamic-complete-functions instead.
   (setq-local pcomplete-default-completion-function #'ignore)
+  ;; Do not expand remote file names.
+  (setq-local pcomplete-remote-file-ignore t)
   (setq-local comint-input-autoexpand shell-input-autoexpand)
   ;; Not needed in shell-mode because it's inherited from comint-mode, but
   ;; placed here for read-shell-command.
diff --git a/lisp/simple.el b/lisp/simple.el
index e21976c30ee..1bc35e87554 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -11140,8 +11140,6 @@ seconds."
           (setq undo-auto-current-boundary-timer
                 (run-at-time 5 nil #'undo-auto--boundary-timer)))))))
 
-
-
 (provide 'simple)
 
 ;;; simple.el ends here
diff --git a/lisp/startup.el b/lisp/startup.el
index 43d6bf7fd59..4d0e59ba4f3 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1023,6 +1023,7 @@ init-file, or to a default value if loading is not 
possible."
          ;; Use (startup--witness) instead of nil, so we can detect when the
          ;; init files set `debug-ignored-errors' to nil.
          (if init-file-debug '(startup--witness) debug-ignored-errors))
+        (d-i-e-standard debug-ignored-errors)
         ;; The init file might contain byte-code with embedded NULs,
         ;; which can cause problems when read back, so disable nul
         ;; byte detection.  (Bug#52554)
@@ -1111,8 +1112,16 @@ the `--debug-init' option to view a complete error 
backtrace."
 
       ;; If we can tell that the init file altered debug-on-error,
       ;; arrange to preserve the value that it set up.
-      (or (eq debug-ignored-errors d-i-e-initial)
-          (setq d-i-e-from-init-file (list debug-ignored-errors)))
+      (unless (eq debug-ignored-errors d-i-e-initial)
+        (if (memq 'startup--witness debug-ignored-errors)
+            ;; The init file wants to add errors to the standard
+            ;; value, so we need to emulate that.
+            (setq d-i-e-from-init-file
+                  (list (append d-i-e-standard
+                                (remq 'startup--witness
+                                      debug-ignored-errors))))
+          ;; The init file _replaces_ the standard value.
+          (setq d-i-e-from-init-file (list debug-ignored-errors))))
       (or (eq debug-on-error debug-on-error-initial)
           (setq debug-on-error-should-be-set t
                 debug-on-error-from-init-file debug-on-error)))
diff --git a/lisp/subr.el b/lisp/subr.el
index 58ec642dd92..f6332ce35e6 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1651,8 +1651,9 @@ in the current Emacs session, then this function may 
return nil."
 
 (defun event-start (event)
   "Return the starting position of EVENT.
-EVENT should be a mouse click, drag, or key press event.  If
-EVENT is nil, the value of `posn-at-point' is used instead.
+EVENT should be a mouse click, drag, touch screen, or key press
+event.  If EVENT is nil, the value of `posn-at-point' is used
+instead.
 
 The following accessor functions are used to access the elements
 of the position:
@@ -1675,27 +1676,34 @@ nil or (STRING . POSITION)'.
 
 For more information, see Info node `(elisp)Click Events'."
   (declare (side-effect-free t))
-  (or (and (consp event)
-           ;; Ignore touchscreen events.  They store the posn in a
-           ;; different format, and can have multiple posns.
-           (not (memq (car event) '(touchscreen-begin
-                                    touchscreen-update
-                                    touchscreen-end)))
-           (nth 1 event))
-      (event--posn-at-point)))
+  (if (and (consp event)
+           (or (eq (car event) 'touchscreen-begin)
+               (eq (car event) 'touchscreen-end)))
+      ;; Touch screen begin and end events save their information in a
+      ;; different format, where the mouse position list is the cdr of
+      ;; (nth 1 event).
+      (cdadr event)
+    (or (and (consp event)
+             ;; Ignore touchscreen update events.  They store the posn
+             ;; in a different format, and can have multiple posns.
+             (not (eq (car event) 'touchscreen-update))
+             (nth 1 event))
+        (event--posn-at-point))))
 
 (defun event-end (event)
   "Return the ending position of EVENT.
-EVENT should be a click, drag, or key press event.
+EVENT should be a click, drag, touch screen, or key press event.
 
 See `event-start' for a description of the value returned."
   (declare (side-effect-free t))
-  (or (and (consp event)
-           (not (memq (car event) '(touchscreen-begin
-                                    touchscreen-update
-                                    touchscreen-end)))
-           (nth (if (consp (nth 2 event)) 2 1) event))
-      (event--posn-at-point)))
+  (if (and (consp event)
+           (or (eq (car event) 'touchscreen-begin)
+               (eq (car event) 'touchscreen-end)))
+      (cdadr event)
+    (or (and (consp event)
+             (not (eq (car event) 'touchscreen-update))
+             (nth (if (consp (nth 2 event)) 2 1) event))
+        (event--posn-at-point))))
 
 (defsubst event-click-count (event)
   "Return the multi-click count of EVENT, a click or drag event.
@@ -3561,7 +3569,12 @@ There is no need to explicitly add `help-char' to CHARS;
                 read-char-from-minibuffer-map))
          ;; Protect this-command when called from pre-command-hook (bug#45029)
          (this-command this-command)
-         (result (read-from-minibuffer prompt nil map nil (or history t)))
+         (result (progn
+                   ;; Disable text conversion if it is enabled.
+                   ;; (bug#65370)
+                   (when (fboundp 'set-text-conversion-style)
+                     (set-text-conversion-style text-conversion-style))
+                   (read-from-minibuffer prompt nil map nil (or history t))))
          (char
           (if (> (length result) 0)
               ;; We have a string (with one character), so return the first 
one.
@@ -3745,9 +3758,6 @@ like) while `y-or-n-p' is running)."
       (while
           (let* ((scroll-actions '(recenter scroll-up scroll-down
                                             scroll-other-window 
scroll-other-window-down))
-                 ;; Disable text conversion so that real key events
-                 ;; are sent.
-                 (overriding-text-conversion-style nil)
                  (key
                   (let ((cursor-in-echo-area t))
                     (when minibuffer-auto-raise
@@ -4116,17 +4126,10 @@ buffer, use `without-restriction' with the same LABEL 
argument.
 \(fn START END [:label LABEL] BODY)"
   (declare (indent 2) (debug t))
   (if (eq (car rest) :label)
-      `(internal--with-restriction ,start ,end (lambda () ,@(cddr rest))
-                                 ,(cadr rest))
-    `(internal--with-restriction ,start ,end (lambda () ,@rest))))
-
-(defun internal--with-restriction (start end body &optional label)
-  "Helper function for `with-restriction', which see."
-  (save-restriction
-    (if label
-        (internal--labeled-narrow-to-region start end label)
-      (narrow-to-region start end))
-    (funcall body)))
+      `(save-restriction
+         (internal--labeled-narrow-to-region ,start ,end ,(cadr rest))
+         ,@(cddr rest))
+    `(save-restriction (narrow-to-region ,start ,end) ,@rest)))
 
 (defmacro without-restriction (&rest rest)
   "Execute BODY without restrictions.
@@ -4139,16 +4142,8 @@ by `with-restriction' with the same LABEL argument are 
lifted.
 \(fn [:label LABEL] BODY)"
   (declare (indent 0) (debug t))
   (if (eq (car rest) :label)
-      `(internal--without-restriction (lambda () ,@(cddr rest))
-                                    ,(cadr rest))
-    `(internal--without-restriction (lambda () ,@rest))))
-
-(defun internal--without-restriction (body &optional label)
-  "Helper function for `without-restriction', which see."
-  (save-restriction
-    (if label (internal--unlabel-restriction label))
-    (widen)
-    (funcall body)))
+      `(save-restriction (internal--labeled-widen ,(cadr rest)) ,@(cddr rest))
+    `(save-restriction (widen) ,@rest)))
 
 (defun find-tag-default-bounds ()
   "Determine the boundaries of the default tag, based on text at point.
@@ -5140,30 +5135,41 @@ the function `undo--wrap-and-run-primitive-undo'."
              (kill-local-variable 'before-change-functions))
            (if local-acf (setq after-change-functions acf)
              (kill-local-variable 'after-change-functions))))
-        (when (not (eq buffer-undo-list t))
-          (let ((ap-elt
-                (list 'apply
-                      (- end end-marker)
-                      beg
-                      (marker-position end-marker)
-                      #'undo--wrap-and-run-primitive-undo
-                      beg (marker-position end-marker)
-                      ;; We will truncate this list by side-effect below.
-                      buffer-undo-list))
-               (ptr buffer-undo-list))
-           (if (not (eq buffer-undo-list old-bul))
-               (progn
-                 (while (and (not (eq (cdr ptr) old-bul))
-                             ;; In case garbage collection has removed OLD-BUL.
-                             (or (cdr ptr)
-                                 (progn
-                                   (message "combine-change-calls: 
buffer-undo-list broken")
-                                   nil)))
-                   (setq ptr (cdr ptr)))
-                 ;; Truncate the list that's in the `apply' entry.
-                 (setcdr ptr nil)
-                 (push ap-elt buffer-undo-list)
-                 (setcdr buffer-undo-list old-bul)))))
+       ;; If buffer-undo-list is neither t (in which case undo
+       ;; information is not recorded) nor equal to buffer-undo-list
+       ;; before body was funcalled (in which case (funcall body) did
+       ;; not add items to buffer-undo-list) ...
+       (unless (or (eq buffer-undo-list t)
+                   (eq buffer-undo-list old-bul))
+         (let ((ptr buffer-undo-list) body-undo-list)
+           ;; ... then loop over buffer-undo-list, until the head of
+           ;; buffer-undo-list before body was funcalled is found, or
+           ;; ptr is nil (which may happen if garbage-collect has
+           ;; been called after (funcall body) and has removed
+           ;; entries of buffer-undo-list that were added by (funcall
+           ;; body)), and add these entries to body-undo-list.
+           (while (and ptr (not (eq ptr old-bul)))
+             (push (car ptr) body-undo-list)
+             (setq ptr (cdr ptr)))
+           (setq body-undo-list (nreverse body-undo-list))
+           ;; Warn if garbage-collect has truncated buffer-undo-list
+           ;; behind our back.
+           (when (and old-bul (not ptr))
+             (message
+               "combine-change-calls: buffer-undo-list has been truncated"))
+           ;; Add an (apply ...) entry to buffer-undo-list, using
+           ;; body-undo-list ...
+           (push (list 'apply
+                       (- end end-marker)
+                       beg
+                       (marker-position end-marker)
+                       #'undo--wrap-and-run-primitive-undo
+                       beg (marker-position end-marker)
+                       body-undo-list)
+                 buffer-undo-list)
+           ;; ... and set the cdr of buffer-undo-list to
+           ;; buffer-undo-list before body was funcalled.
+           (setcdr buffer-undo-list old-bul)))
        (if (not inhibit-modification-hooks)
            (run-hook-with-args 'after-change-functions
                                beg (marker-position end-marker)
diff --git a/lisp/term.el b/lisp/term.el
index 5d43ea56791..b8466b21332 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -972,12 +972,7 @@ underlying shell."
 (defun term--update-term-menu (&optional force)
   (when (and (lookup-key term-mode-map [menu-bar terminal])
              (or force (frame-or-buffer-changed-p)))
-    (let ((buffer-list
-           (seq-filter
-            (lambda (buffer)
-              (provided-mode-derived-p (buffer-local-value 'major-mode buffer)
-                                       'term-mode))
-            (buffer-list))))
+    (let ((buffer-list (match-buffers '(derived-mode . term-mode))))
       (easy-menu-change
        nil
        "Terminal Buffers"
@@ -1129,6 +1124,7 @@ Commands in line mode:
 \\{term-mode-map}
 
 Entry to this mode runs the hooks on `term-mode-hook'."
+  :interactive nil
   ;; we do not want indent to sneak in any tabs
   (setq indent-tabs-mode nil)
   (setq buffer-display-table term-display-table)
@@ -2067,7 +2063,7 @@ See `term-replace-by-expanded-history'.  Returns t if 
successful."
               ;; We cannot know the interpreter's idea of input line numbers.
               (goto-char (match-end 0))
               (message "Absolute reference cannot be expanded"))
-             ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?")
+             ((looking-at "!-\\([0-9]+\\):?\\([0-9^$*-]+\\)?")
               ;; Just a number of args from `number' lines backward.
               (let ((number (1- (string-to-number
                                  (buffer-substring (match-beginning 1)
@@ -2090,7 +2086,7 @@ See `term-replace-by-expanded-history'.  Returns t if 
successful."
                t t)
               (message "History item: previous"))
              ((looking-at
-               "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
+               "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\):?\\([0-9^$*-]+\\)?")
               ;; Most recent input starting with or containing (possibly
               ;; protected) string, maybe just a number of args.  Phew.
               (let* ((mb1 (match-beginning 1)) (me1 (match-end 1))
diff --git a/lisp/term/AT386.el b/lisp/term/AT386.el
index 27065b73591..541b7c5aad0 100644
--- a/lisp/term/AT386.el
+++ b/lisp/term/AT386.el
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1992, 2001-2023 Free Software Foundation, Inc.
 
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+;; Author: Eric S. Raymond <esr@thyrsus.com>
 ;; Keywords: terminals
 
 ;; This file is part of GNU Emacs.
diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el
index c7a297d5dac..c8a45f068d1 100644
--- a/lisp/textmodes/reftex-index.el
+++ b/lisp/textmodes/reftex-index.el
@@ -539,11 +539,7 @@ SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan 
[f]ollow [?]Help
       (if (reftex-use-fonts)
           (put-text-property (point-min) (point)
                              'face reftex-index-header-face))
-      (if (fboundp 'cursor-intangible-mode)
-          (cursor-intangible-mode 1)
-        ;; If `cursor-intangible' is not available, fallback on the old
-        ;; intrusive `intangible' property.
-        (put-text-property (point-min) (point) 'intangible t))
+      (cursor-intangible-mode 1)
       (add-text-properties (point-min) (point)
                            '(cursor-intangible t
                              front-sticky (cursor-intangible)
diff --git a/lisp/textmodes/reftex-ref.el b/lisp/textmodes/reftex-ref.el
index da0779c8e8d..d0a44eca17c 100644
--- a/lisp/textmodes/reftex-ref.el
+++ b/lisp/textmodes/reftex-ref.el
@@ -784,7 +784,7 @@ When called with 2 \\[universal-argument] prefix args, 
disable magic word recogn
 (defvar font-lock-mode)
 (defun reftex-show-entry (beg-hlt end-hlt)
   ;; Show entry if point is hidden
-  (let* ((n (/ (reftex-window-height) 2))
+  (let* ((n (/ (window-height) 2))
          (beg (save-excursion
                (re-search-backward "[\n\r]" nil 1 n) (point)))
          (end (save-excursion
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index 3b3f892a688..de49b7c6c70 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -1,6 +1,6 @@
 ;;; reftex-toc.el --- RefTeX's table of contents mode  -*- lexical-binding: t; 
-*-
 
-;; Copyright (C) 1997-2000, 2003-2023 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2023 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <dominik@science.uva.nl>
 ;; Maintainer: auctex-devel@gnu.org
@@ -215,9 +215,7 @@ When called with a raw \\[universal-argument] prefix, 
rescan the document first.
          (here-I-am (if reftex--rebuilding-toc
                         (get 'reftex-toc :reftex-data)
                       (car (reftex-where-am-I))))
-         (unsplittable (if (fboundp 'frame-property)
-                           (frame-property (selected-frame) 'unsplittable)
-                         (frame-parameter nil 'unsplittable)))
+         (unsplittable (frame-parameter nil 'unsplittable))
          offset toc-window)
 
     (if (setq toc-window (get-buffer-window
@@ -267,11 +265,7 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels 
[f]ollow [x]r [?]Help
 
       (if (reftex-use-fonts)
           (put-text-property (point-min) (point) 'font-lock-face 
reftex-toc-header-face))
-      (if (fboundp 'cursor-intangible-mode)
-          (cursor-intangible-mode 1)
-        ;; If `cursor-intangible' is not available, fallback on the old
-        ;; intrusive `intangible' property.
-        (put-text-property (point-min) (point) 'intangible t))
+      (cursor-intangible-mode 1)
       (add-text-properties (point-min) (point)
                            '(cursor-intangible t
                              front-sticky (cursor-intangible)
@@ -385,11 +379,8 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels 
[f]ollow [x]r [?]Help
   ;; Check if FRAME is the dedicated TOC frame.
   ;; If yes, and ERROR is non-nil, throw an error.
   (setq frame (or frame (selected-frame)))
-  (let ((res (equal
-              (if (fboundp 'frame-property)
-                  (frame-property frame 'name)
-                (frame-parameter  frame 'name))
-              "RefTeX TOC Frame")))
+  (let ((res (equal (frame-parameter frame 'name)
+                    "RefTeX TOC Frame")))
     (if (and res error)
         (error (substitute-command-keys
                 "This frame is view-only.  Use \\[reftex-toc] \
@@ -586,10 +577,7 @@ With prefix arg 1, restrict index to the section at point."
 (defun reftex-toc-revert (&rest _)
   "Regenerate the TOC from the internal lists."
   (interactive)
-  (let ((unsplittable
-         (if (fboundp 'frame-property)
-             (frame-property (selected-frame) 'unsplittable)
-           (frame-parameter nil 'unsplittable)))
+  (let ((unsplittable (frame-parameter nil 'unsplittable))
         (reftex--rebuilding-toc t))
     (if unsplittable
         (switch-to-buffer
@@ -1036,12 +1024,9 @@ always show the current section in connection with the 
option
 `reftex-auto-recenter-toc'."
   (interactive)
   (catch 'exit
-    (let* ((frames (frame-list)) frame
-           (get-frame-prop-func (if (fboundp 'frame-property)
-                                    'frame-property
-                                  'frame-parameter)))
+    (let* ((frames (frame-list)) frame)
       (while (setq frame (pop frames))
-        (if (equal (funcall get-frame-prop-func frame 'name)
+        (if (equal (frame-parameter frame 'name)
                    "RefTeX TOC Frame")
             (progn
               (delete-frame frame)
diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el
index 916e0d89a1d..50bec6ef172 100644
--- a/lisp/textmodes/reftex.el
+++ b/lisp/textmodes/reftex.el
@@ -1,6 +1,6 @@
 ;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX  
-*- lexical-binding: t; -*-
 
-;; Copyright (C) 1997-2000, 2003-2023 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2023 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <dominik@science.uva.nl>
 ;; Maintainer: auctex-devel@gnu.org
@@ -1664,11 +1664,6 @@ When DIE is non-nil, throw an error if file not found."
       (pop alist))
     (nreverse out)))
 
-(defun reftex-window-height ()
-  (if (fboundp 'window-displayed-height)
-      (window-displayed-height)
-    (window-height)))
-
 (defun reftex-enlarge-to-fit (buf2 &optional keep-current)
   ;; Enlarge other window displaying buffer to show whole buffer if possible.
   ;; If KEEP-CURRENT in non-nil, current buffer must remain visible.
@@ -1680,7 +1675,7 @@ When DIE is non-nil, throw an error if file not found."
       (unless (and (pos-visible-in-window-p (point-min))
                    (pos-visible-in-window-p (point-max)))
         (enlarge-window (1+ (- (count-lines (point-min) (point-max))
-                               (reftex-window-height))))))
+                               (window-height))))))
     (cond
      ((window-live-p win1) (select-window win1))
      (keep-current
@@ -1705,7 +1700,7 @@ When DIE is non-nil, throw an error if file not found."
           (unless (and (pos-visible-in-window-p (point-min))
                        (pos-visible-in-window-p (point-max)))
             (enlarge-window (1+ (- (count-lines (point-min) (point-max))
-                                   (reftex-window-height)))))
+                                   (window-height)))))
           (setq truncate-lines t))
         (if (and (pos-visible-in-window-p (point-min))
                  (pos-visible-in-window-p (point-max)))
@@ -2274,20 +2269,17 @@ IGNORE-WORDS List of words which should be removed from 
the string."
 (defun reftex-create-customize-menu ()
   "Create a full customization menu for RefTeX, insert it into the menu."
   (interactive)
-  (if (fboundp 'customize-menu-create)
-      (progn
-        (easy-menu-change
-         '("Ref") "Customize"
-         `(["Browse RefTeX group" reftex-customize t]
-           "--"
-           ,(customize-menu-create 'reftex)
-           ["Set" Custom-set t]
-           ["Save" Custom-save t]
-           ["Reset to Current" Custom-reset-current t]
-           ["Reset to Saved" Custom-reset-saved t]
-           ["Reset to Standard Settings" Custom-reset-standard t]))
-        (message "\"Ref\"-menu now contains full customization menu"))
-    (error "Cannot expand menu (outdated version of cus-edit.el)")))
+  (easy-menu-change
+   '("Ref") "Customize"
+   `(["Browse RefTeX group" reftex-customize t]
+     "--"
+     ,(customize-menu-create 'reftex)
+     ["Set" Custom-set t]
+     ["Save" Custom-save t]
+     ["Reset to Current" Custom-reset-current t]
+     ["Reset to Saved" Custom-reset-saved t]
+     ["Reset to Standard Settings" Custom-reset-standard t]))
+  (message "\"Ref\"-menu now contains full customization menu"))
 
 
 ;;; Misc
@@ -2348,6 +2340,8 @@ Your bug report will be posted to the AUCTeX bug 
reporting list.
 
 (setq reftex-tables-dirty t)  ; in case this file is evaluated by hand
 
+(define-obsolete-function-alias 'reftex-window-height #'window-height "30.1")
+
 (provide 'reftex)
 
 ;;; reftex.el ends here
diff --git a/lisp/tooltip.el b/lisp/tooltip.el
index 0881a7c7bf9..6f8a489e60c 100644
--- a/lisp/tooltip.el
+++ b/lisp/tooltip.el
@@ -200,7 +200,7 @@ This might return nil if the event did not occur over a 
buffer."
 (defun tooltip-start-delayed-tip ()
   "Add a one-shot timeout to call function `tooltip-timeout'."
   (setq tooltip-timeout-id
-        (run-with-timer (tooltip-delay) 'tooltip-timeout nil)))
+        (run-with-timer (tooltip-delay) nil 'tooltip-timeout nil)))
 
 (defun tooltip-timeout (_object)
   "Function called when timer with id `tooltip-timeout-id' fires."
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index 0914071f2a0..577c993efcf 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -1122,16 +1122,33 @@ is not read-only."
                     ;; If the position of the touch point hasn't
                     ;; changed, or it doesn't start or end on a
                     ;; window...
-                    (if (and (eq new-window old-window)
-                             (eq new-point old-point)
-                             (windowp new-window)
-                             (windowp old-window))
-                        ;; ... generate a mouse-1 event...
-                        (list 'mouse-1 posn)
-                      ;; ... otherwise, generate a drag-mouse-1 event.
-                      (list 'drag-mouse-1 (cons old-window
-                                                old-posn)
-                            (cons new-window posn))))))
+                    (if (and (not old-point) (not new-point))
+                        ;; Should old-point and new-point both equal
+                        ;; nil, compare the posn areas and nominal
+                        ;; column position.  If either are different,
+                        ;; generate a drag event.
+                        (let ((new-col-row (posn-col-row posn))
+                              (new-area (posn-area posn))
+                              (old-col-row (posn-col-row old-posn))
+                              (old-area (posn-area old-posn)))
+                          (if (and (equal new-col-row old-col-row)
+                                   (eq new-area old-area))
+                              ;; ... generate a mouse-1 event...
+                              (list 'mouse-1 posn)
+                            ;; ... otherwise, generate a drag-mouse-1 event.
+                            (list 'drag-mouse-1 (cons old-window
+                                                      old-posn)
+                                  (cons new-window posn))))
+                      (if (and (eq new-window old-window)
+                               (eq new-point old-point)
+                               (windowp new-window)
+                               (windowp old-window))
+                          ;; ... generate a mouse-1 event...
+                          (list 'mouse-1 posn)
+                        ;; ... otherwise, generate a drag-mouse-1 event.
+                        (list 'drag-mouse-1 (cons old-window
+                                                  old-posn)
+                              (cons new-window posn)))))))
           ((eq what 'mouse-1-menu)
            ;; Generate a `down-mouse-1' event at the position the tap
            ;; took place.
diff --git a/lisp/type-break.el b/lisp/type-break.el
index 1aa2b9d2997..494ed80c496 100644
--- a/lisp/type-break.el
+++ b/lisp/type-break.el
@@ -584,13 +584,13 @@ INTERVAL is the full length of an interval (defaults to 
TIME)."
   (type-break-check-post-command-hook)
   (type-break-cancel-schedule)
   (type-break-time-warning-schedule time 'reset)
-  (type-break-run-at-time (max 1 time) nil 'type-break-alarm)
+  (run-at-time (max 1 time) nil 'type-break-alarm)
   (setq type-break-time-next-break
         (type-break-time-sum start (or interval time))))
 
 (defun type-break-cancel-schedule ()
   (type-break-cancel-time-warning-schedule)
-  (type-break-cancel-function-timers 'type-break-alarm)
+  (cancel-function-timers 'type-break-alarm)
   (setq type-break-alarm-p nil)
   (setq type-break-time-next-break nil))
 
@@ -621,7 +621,7 @@ INTERVAL is the full length of an interval (defaults to 
TIME)."
 
       ;(let (type-break-current-time-warning-interval)
       ;  (type-break-cancel-time-warning-schedule))
-      (type-break-run-at-time (max 1 time) nil 'type-break-time-warning-alarm)
+      (run-at-time (max 1 time) nil 'type-break-time-warning-alarm)
 
       (cond
        (resetp
@@ -631,7 +631,7 @@ INTERVAL is the full length of an interval (defaults to 
TIME)."
         (setq type-break-warning-countdown-string-type "seconds"))))))))
 
 (defun type-break-cancel-time-warning-schedule ()
-  (type-break-cancel-function-timers 'type-break-time-warning-alarm)
+  (cancel-function-timers 'type-break-time-warning-alarm)
   (remove-hook 'type-break-post-command-hook 'type-break-time-warning)
   (setq type-break-current-time-warning-interval
         type-break-time-warning-intervals)
@@ -984,21 +984,6 @@ With optional non-nil ALL, force redisplay of all 
mode-lines."
   (add-hook 'post-command-hook 'type-break-run-tb-post-command-hook 'append))
 
 
-;;; Timer wrapper functions
-;;
-;; These shield type-break from variations in the interval timer packages
-;; for different versions of Emacs.
-
-(defun type-break-run-at-time (time repeat function)
-  (condition-case nil (or (require 'timer) (require 'itimer)) (error nil))
-  (run-at-time time repeat function))
-
-(defvar timer-dont-exit)
-(defun type-break-cancel-function-timers (function)
-  (let ((timer-dont-exit t))
-    (cancel-function-timers function)))
-
-
 ;;; Demo wrappers
 
 (defun type-break-catch-up-event ()
@@ -1144,6 +1129,8 @@ With optional non-nil ALL, force redisplay of all 
mode-lines."
             (kill-buffer buffer-name))))))
 
 (define-obsolete-function-alias 'timep 'type-break-timep "29.1")
+(define-obsolete-function-alias 'type-break-run-at-time #'run-at-time "30.1")
+(define-obsolete-function-alias 'type-break-cancel-function-timers 
#'cancel-function-timers "30.1")
 
 
 (provide 'type-break)
diff --git a/lisp/use-package/use-package-core.el 
b/lisp/use-package/use-package-core.el
index 21a831ce26d..34c45b7aec3 100644
--- a/lisp/use-package/use-package-core.el
+++ b/lisp/use-package/use-package-core.el
@@ -1039,15 +1039,23 @@ meaning:
   Configured        :config has been processed (the package is loaded!)
   Initialized       :init has been processed (load status unknown)
   Prefaced          :preface has been processed
-  Declared          the use-package declaration was seen"
+  Declared          the use-package declaration was seen
+
+Customize the user option `use-package-compute-statistics' to
+enable gathering statistics."
   (interactive)
-  (with-current-buffer (get-buffer-create "*use-package statistics*")
-    (setq tabulated-list-entries
-          (mapcar #'use-package-statistics-convert
-                  (hash-table-keys use-package-statistics)))
-    (use-package-statistics-mode)
-    (tabulated-list-print)
-    (display-buffer (current-buffer))))
+  (let ((statistics (hash-table-keys use-package-statistics)))
+    (unless statistics
+      (if use-package-compute-statistics
+          (user-error "No use-package statistics available")
+        (user-error (concat "Customize `use-package-compute-statistics'"
+                            " to enable reporting"))))
+    (with-current-buffer (get-buffer-create "*use-package statistics*")
+      (setq tabulated-list-entries
+            (mapcar #'use-package-statistics-convert statistics))
+      (use-package-statistics-mode)
+      (tabulated-list-print)
+      (display-buffer (current-buffer)))))
 
 (defvar use-package-statistics-status-order
   '(("Declared"    . 0)
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index dfca944dc74..a7763360795 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -1342,8 +1342,10 @@ This prompts for a branch to merge from."
 (defun vc-git-repository-url (file-or-dir &optional remote-name)
   (let ((default-directory (vc-git-root file-or-dir)))
     (with-temp-buffer
-      (vc-git-command (current-buffer) 0 nil "remote" "get-url"
-                      (or remote-name "origin"))
+      ;; The "get-url" subcommand of "git remote" was new in git 2.7.0;
+      ;; "git config" also works in older versions.  -- rgr, 15-Aug-23.
+      (let ((opt-name (concat "remote." (or remote-name "origin") ".url")))
+       (vc-git-command (current-buffer) 0 (list "config" "--get" opt-name)))
       (buffer-substring-no-properties (point-min) (1- (point-max))))))
 
 ;; Everywhere but here, follows vc-git-command, which uses vc-do-command
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 00a7659209e..e75165ea2e9 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -321,8 +321,7 @@ backend is tried first."
      ((and (file-name-directory file)
            (string-match vc-ignore-dir-regexp (file-name-directory file)))
       nil)
-     ((and (boundp 'file-name-handler-alist)
-          (setq handler (find-file-name-handler file 'vc-registered)))
+     ((setq handler (find-file-name-handler file 'vc-registered))
       ;; handler should set vc-backend and return t if registered
       (funcall handler 'vc-registered file))
      (t
diff --git a/lisp/version.el b/lisp/version.el
index ca61f8cfeee..0eb4ea76f4f 100644
--- a/lisp/version.el
+++ b/lisp/version.el
@@ -61,13 +61,19 @@ returned by `current-time'."
          (string-to-number (match-string 1 emacs-version)))
   "Minor version number of this version of Emacs.")
 
-(defconst emacs-build-system (or (and (eq system-type 'android)
+;; N.B. (featurep 'android) is tested for in addition to
+;; `system-type', because that can also be Android on a TTY-only
+;; Android build that doesn't employ the window system packaging
+;; support.  (bug#65319)
+(defconst emacs-build-system (or (and (featurep 'android)
+                                      (eq system-type 'android)
                                       (android-read-build-system))
                                  (system-name))
   "Name of the system on which Emacs was built, or nil if not available.")
 
 (defconst emacs-build-time (if emacs-build-system
-                               (or (and (eq system-type 'android)
+                               (or (and (featurep 'android)
+                                        (eq system-type 'android)
                                         (android-read-build-time))
                                    (current-time)))
   "Time at which Emacs was dumped out, or nil if not available.")
@@ -183,7 +189,8 @@ correspond to the running Emacs.
 
 Optional argument DIR is a directory to use instead of `source-directory'.
 Optional argument EXTERNAL is ignored."
-  (cond ((eq system-type 'android)
+  (cond ((and (featurep 'android)
+              (eq system-type 'android))
          (emacs-repository-version-android))
         (t (emacs-repository-version-git
             (or dir source-directory)))))
@@ -229,7 +236,8 @@ this reports on the current state of the sources, which may 
not
 correspond to the running Emacs.
 
 Optional argument DIR is a directory to use instead of `source-directory'."
-  (cond ((eq system-type 'android)
+  (cond ((and (featurep 'android)
+              (eq system-type 'android))
          (emacs-repository-branch-android))
         (t (emacs-repository-branch-git
             (or dir source-directory)))))
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 47531113ba8..a70598bb6c9 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -64,12 +64,10 @@
 
 ;;; Compatibility.
 
-(defun widget-event-point (event)
+(defsubst widget-event-point (event)
   "Character position of the end of event if that exists, or nil.
 EVENT can either be a mouse event or a touch screen event."
-  (if (eq (car-safe event) 'touchscreen-begin)
-      (posn-point (cdadr event))
-    (posn-point (event-end event))))
+  (posn-point (event-end event)))
 
 (defun widget-button-release-event-p (event)
   "Non-nil if EVENT is a mouse-button-release event object."
@@ -1084,15 +1082,6 @@ Note that such modes will need to require wid-edit.")
   "If non-nil, `widget-button-click' moves point to a button after invoking it.
 If nil, point returns to its original position after invoking a button.")
 
-(defun widget-event-start (event)
-  "Return the start of EVENT.
-If EVENT is not a touchscreen event, simply return its
-`event-start'.  Otherwise, it is a touchscreen event, so return
-the posn of its touchpoint."
-  (if (eq (car event) 'touchscreen-begin)
-      (cdadr event)
-    (event-start event)))
-
 (defun widget-button--check-and-call-button (event button)
   "Call BUTTON if BUTTON is a widget and EVENT is correct for it.
 EVENT can either be a mouse event or a touchscreen-begin event.
@@ -1106,9 +1095,9 @@ If nothing was called, return non-nil."
       ;; in a save-excursion so that the click on the button
       ;; doesn't change point.
       (save-selected-window
-        (select-window (posn-window (widget-event-start event)))
+        (select-window (posn-window (event-start event)))
         (save-excursion
-         (goto-char (posn-point (widget-event-start event)))
+         (goto-char (posn-point (event-start event)))
          (let* ((overlay (widget-get button :button-overlay))
                 (pressed-face (or (widget-get button :pressed-face)
                                   widget-button-pressed-face))
@@ -1179,7 +1168,7 @@ If nothing was called, return non-nil."
   (if (widget-event-point event)
       (let* ((mouse-1 (memq (event-basic-type event) '(mouse-1 down-mouse-1)))
             (pos (widget-event-point event))
-            (start (widget-event-start event))
+            (start (event-start event))
              (button (get-char-property
                      pos 'button (and (windowp (posn-window start))
                                       (window-buffer (posn-window start))))))
@@ -3812,8 +3801,19 @@ like the newline character or the tab character."
 (define-widget 'list 'group
   "A Lisp list."
   :tag "List"
+  :default-get #'widget-list-default-get
   :format "%{%t%}:\n%v")
 
+(defun widget-list-default-get (widget)
+  "Return the default external value for a list WIDGET.
+
+The default value is the one stored in the :value property, even if it is nil,
+or a list with the default value of each component of the list WIDGET."
+  (widget-apply widget :value-to-external
+                (if (widget-member widget :value)
+                    (widget-get widget :value)
+                  (widget-group-default-get widget))))
+
 (define-widget 'vector 'group
   "A Lisp vector."
   :tag "Vector"
@@ -3942,7 +3942,6 @@ example:
            value-type widget-plist-value-type))
     `(group :format "Key: %v" :inline t ,key-type ,value-type)))
 
-
 ;;; The `alist' Widget.
 ;;
 ;; Association lists.
@@ -3952,6 +3951,7 @@ example:
   :key-type '(sexp :tag "Key")
   :value-type '(sexp :tag "Value")
   :convert-widget 'widget-alist-convert-widget
+  :default-get #'widget-alist-default-get
   :tag "Alist")
 
 (defvar widget-alist-value-type)       ;Dynamic variable
@@ -3986,6 +3986,25 @@ example:
       (setq key-type `(const ,option)
            value-type widget-alist-value-type))
     `(cons :format "Key: %v" ,key-type ,value-type)))
+
+(defun widget-alist-default-get (widget)
+  "Return the default value for WIDGET, an alist widget.
+
+The default value may be one of:
+- The one stored in the :value property, even if it is nil.
+- If WIDGET has options available, an alist consisting of the
+default values for each option.
+- nil, otherwise."
+  (widget-apply widget :value-to-external
+                (cond ((widget-member widget :value)
+                       (widget-get widget :value))
+                      ((widget-get widget :options)
+                       (mapcar #'widget-default-get
+                               ;; Last one is the editable-list part, and
+                               ;; we don't want those showing up as
+                               ;; part of the default value.  (Bug#63290)
+                               (butlast (widget-get widget :args))))
+                      (t nil))))
 
 (define-widget 'choice 'menu-choice
   "A union of several sexp types.
diff --git a/m4/clock_time.m4 b/m4/clock_time.m4
index d624a73d35d..28534db1c76 100644
--- a/m4/clock_time.m4
+++ b/m4/clock_time.m4
@@ -1,4 +1,4 @@
-# clock_time.m4 serial 12
+# clock_time.m4 serial 13
 dnl Copyright (C) 2002-2006, 2009-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,9 +12,17 @@ dnl with or without modifications, as long as this notice is 
preserved.
 
 AC_DEFUN([gl_CLOCK_TIME],
 [
+  AC_REQUIRE([AC_CANONICAL_HOST])
+
   dnl Persuade glibc and Solaris <time.h> to declare these functions.
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
 
+  # On mingw, these functions are defined in the libwinpthread library,
+  # which is better avoided.  In fact, the clock_gettime function is buggy
+  # in 32-bit mingw, when -D__MINGW_USE_VC2005_COMPAT is used (which Gnulib's
+  # year2038 module does): It leaves the upper 32 bits of the tv_sec field
+  # of the result uninitialized.
+
   # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
   # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
 
@@ -23,12 +31,22 @@ AC_DEFUN([gl_CLOCK_TIME],
   # library, inducing unnecessary run-time overhead.
   CLOCK_TIME_LIB=
   AC_SUBST([CLOCK_TIME_LIB])
-  gl_saved_libs=$LIBS
-    AC_SEARCH_LIBS([clock_gettime], [rt posix4],
-                   [test "$ac_cv_search_clock_gettime" = "none required" ||
-                    CLOCK_TIME_LIB=$ac_cv_search_clock_gettime])
-    AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime])
-  LIBS=$gl_saved_libs
+  case "$host_os" in
+    mingw*)
+      ac_cv_func_clock_getres=no
+      ac_cv_func_clock_gettime=no
+      ac_cv_func_clock_settime=no
+      ;;
+    *)
+      gl_saved_libs=$LIBS
+        AC_SEARCH_LIBS([clock_gettime], [rt posix4],
+                       [test "$ac_cv_search_clock_gettime" = "none required" ||
+                        CLOCK_TIME_LIB=$ac_cv_search_clock_gettime])
+        AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime])
+      LIBS=$gl_saved_libs
+      ;;
+  esac
+
   # For backward compatibility.
   LIB_CLOCK_GETTIME="$CLOCK_TIME_LIB"
   AC_SUBST([LIB_CLOCK_GETTIME])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 72adcf90d5e..14ff92040a4 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -51,6 +51,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module at-internal:
   # Code from module attribute:
   # Code from module binary-io:
+  # Code from module boot-time:
   # Code from module builtin-expect:
   # Code from module byteswap:
   # Code from module c-ctype:
@@ -181,7 +182,6 @@ AC_DEFUN([gl_EARLY],
   gl_STDIO_H_EARLY
   # Code from module stdlib:
   # Code from module stpcpy:
-  # Code from module stpncpy:
   # Code from module string:
   # Code from module strnlen:
   # Code from module strtoimax:
@@ -244,6 +244,7 @@ AC_DEFUN([gl_INIT],
   gl_ASSERT_H
   gl_CONDITIONAL_HEADER([assert.h])
   AC_PROG_MKDIR_P
+  gl_PREREQ_READUTMP_H
   gl___BUILTIN_EXPECT
   gl_BYTESWAP
   gl_CONDITIONAL_HEADER([byteswap.h])
@@ -567,13 +568,6 @@ AC_DEFUN([gl_INIT],
     gl_PREREQ_STPCPY
   ])
   gl_STRING_MODULE_INDICATOR([stpcpy])
-  gl_FUNC_STPNCPY
-  gl_CONDITIONAL([GL_COND_OBJ_STPNCPY],
-                 [test $HAVE_STPNCPY = 0 || test $REPLACE_STPNCPY = 1])
-  AM_COND_IF([GL_COND_OBJ_STPNCPY], [
-    gl_PREREQ_STPNCPY
-  ])
-  gl_STRING_MODULE_INDICATOR([stpncpy])
   gl_STRING_H
   gl_STRING_H_REQUIRE_DEFAULTS
   AC_PROG_MKDIR_P
@@ -1260,6 +1254,9 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/attribute.h
   lib/binary-io.c
   lib/binary-io.h
+  lib/boot-time-aux.h
+  lib/boot-time.c
+  lib/boot-time.h
   lib/byteswap.in.h
   lib/c++defs.h
   lib/c-ctype.c
@@ -1391,6 +1388,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/rawmemchr.valgrind
   lib/readlink.c
   lib/readlinkat.c
+  lib/readutmp.h
   lib/realloc.c
   lib/regcomp.c
   lib/regex.c
@@ -1422,7 +1420,6 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/stdio.in.h
   lib/stdlib.in.h
   lib/stpcpy.c
-  lib/stpncpy.c
   lib/str-two-way.h
   lib/strftime.h
   lib/string.in.h
@@ -1551,6 +1548,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/rawmemchr.m4
   m4/readlink.m4
   m4/readlinkat.m4
+  m4/readutmp.m4
   m4/realloc.m4
   m4/regex.m4
   m4/sha1.m4
@@ -1569,7 +1567,6 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/stdio_h.m4
   m4/stdlib_h.m4
   m4/stpcpy.m4
-  m4/stpncpy.m4
   m4/string_h.m4
   m4/strnlen.m4
   m4/strtoimax.m4
diff --git a/m4/mktime.m4 b/m4/mktime.m4
index e9d31f35a46..69cce86da5a 100644
--- a/m4/mktime.m4
+++ b/m4/mktime.m4
@@ -1,4 +1,4 @@
-# serial 37
+# serial 38
 dnl Copyright (C) 2002-2003, 2005-2007, 2009-2023 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -280,7 +280,6 @@ AC_DEFUN([gl_FUNC_MKTIME],
   AC_REQUIRE([AC_CANONICAL_HOST])
   AC_REQUIRE([gl_FUNC_MKTIME_WORKS])
 
-  REPLACE_MKTIME=0
   if test "$gl_cv_func_working_mktime" != yes; then
     REPLACE_MKTIME=1
     AC_DEFINE([NEED_MKTIME_WORKING], [1],
diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4
index e21a3e343cb..b7f22d7b606 100644
--- a/m4/nanosleep.m4
+++ b/m4/nanosleep.m4
@@ -1,4 +1,4 @@
-# serial 43
+# serial 44
 
 dnl From Jim Meyering.
 dnl Check for the nanosleep function.
@@ -126,9 +126,7 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
        ])
     ])
    case "$gl_cv_func_nanosleep" in
-     *yes)
-       REPLACE_NANOSLEEP=0
-       ;;
+     *yes) ;;
      *)
        REPLACE_NANOSLEEP=1
        case "$gl_cv_func_nanosleep" in
diff --git a/m4/ndk-build.m4 b/m4/ndk-build.m4
index 8769e294452..ab4e88ca168 100644
--- a/m4/ndk-build.m4
+++ b/m4/ndk-build.m4
@@ -152,8 +152,7 @@ ndk_resolve_import_module () {
     # tree build system sets it to a meaning value, but build files
     # just use it to test whether or not the NDK is being used.
     ndk_commands=`ndk_run_test`
-
-    AS_IF([test -n "${ndk_commands//\n }"], [eval "$ndk_commands"])
+    eval "$ndk_commands"
 
     if test -n "$module_name"; then
       break;
diff --git a/m4/readutmp.m4 b/m4/readutmp.m4
new file mode 100644
index 00000000000..0a47f4bb77d
--- /dev/null
+++ b/m4/readutmp.m4
@@ -0,0 +1,121 @@
+# readutmp.m4 serial 30
+dnl Copyright (C) 2002-2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_READUTMP],
+[
+  AC_REQUIRE([gl_SYSTEMD_CHOICE])
+
+  dnl Set READUTMP_LIB to '-lsystemd' or '', depending on whether use of
+  dnl systemd APIs is possible and desired (only the systemd login API, here).
+  dnl AC_LIB_LINKFLAGS_BODY would be overkill here, since few people install
+  dnl libsystemd in non-system directories.
+  READUTMP_LIB=
+  if test "$SYSTEMD_CHOICE" = yes; then
+    AC_CHECK_HEADER([systemd/sd-login.h])
+    if test $ac_cv_header_systemd_sd_login_h = yes; then
+      AC_CACHE_CHECK([for libsystemd version >= 254],
+        [gl_cv_lib_readutmp_systemd],
+        [gl_save_LIBS="$LIBS"
+         LIBS="$LIBS -lsystemd"
+         AC_LINK_IFELSE(
+           [AC_LANG_PROGRAM([[
+              #include <stdint.h>
+              #include <systemd/sd-login.h>
+              ]], [[
+              uint64_t st;
+              sd_session_get_start_time ("1", &st);
+              ]])
+           ],
+           [gl_cv_lib_readutmp_systemd=yes],
+           [gl_cv_lib_readutmp_systemd=no])
+         LIBS="$gl_save_LIBS"
+        ])
+      if test $gl_cv_lib_readutmp_systemd = yes; then
+        AC_DEFINE([READUTMP_USE_SYSTEMD], [1],
+          [Define if the readutmp module should use the systemd login API.])
+        READUTMP_LIB='-lsystemd'
+      fi
+    fi
+  fi
+  AC_SUBST([READUTMP_LIB])
+
+  gl_PREREQ_READUTMP_H
+])
+
+# Prerequisites of readutmp.h and boot-time-aux.h.
+AC_DEFUN_ONCE([gl_PREREQ_READUTMP_H],
+[
+  dnl Persuade utmpx.h to declare utmpxname
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_HEADERS_ONCE([utmp.h utmpx.h])
+  if test $ac_cv_header_utmp_h = yes || test $ac_cv_header_utmpx_h = yes; then
+    dnl Prerequisites of lib/readutmp.h and lib/readutmp.c.
+    AC_CHECK_FUNCS_ONCE([utmpname utmpxname])
+    AC_CHECK_DECLS([endutent],,,[[
+/* <sys/types.h> is a prerequisite of <utmp.h> on FreeBSD 8.0, OpenBSD 4.6.  */
+#include <sys/types.h>
+#ifdef HAVE_UTMP_H
+# include <utmp.h>
+#endif
+]])
+    utmp_includes="\
+AC_INCLUDES_DEFAULT
+#ifdef HAVE_UTMPX_H
+# include <utmpx.h>
+#endif
+#ifdef HAVE_UTMP_H
+# if defined _THREAD_SAFE && defined UTMP_DATA_INIT
+   /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE
+      defined, work around the duplicate struct utmp_data declaration.  */
+#  define utmp_data gl_aix_4_3_workaround_utmp_data
+# endif
+# include <utmp.h>
+#endif
+"
+    AC_CHECK_MEMBERS([struct utmpx.ut_user],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_user],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_name],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_name],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_type],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_type],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_pid],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_pid],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_tv],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_host],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_host],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_id],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_id],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_session],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_session],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_exit],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_exit],,,[$utmp_includes])
+
+    AC_CHECK_MEMBERS([struct utmpx.ut_exit.ut_exit],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_exit],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_exit.e_exit],,,[$utmp_includes])
+
+    AC_CHECK_MEMBERS([struct utmpx.ut_exit.ut_termination],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_termination],,,[$utmp_includes])
+    AC_CHECK_MEMBERS([struct utmp.ut_exit.e_termination],,,[$utmp_includes])
+  fi
+
+  AC_CHECK_DECLS([sysinfo],,,[[
+    #include <sys/sysinfo.h>
+    ]])
+
+  AC_CHECK_HEADERS_ONCE([sys/param.h])
+  dnl <sys/sysctl.h> requires <sys/param.h> on OpenBSD 4.0.
+  AC_CHECK_HEADERS([sys/sysctl.h],,,
+    [AC_INCLUDES_DEFAULT
+     #if HAVE_SYS_PARAM_H
+     # include <sys/param.h>
+     #endif
+    ])
+  AC_CHECK_FUNCS([sysctl])
+
+  AC_CHECK_HEADERS_ONCE([OS.h])
+])
diff --git a/m4/stdalign.m4 b/m4/stdalign.m4
index 1a236d66d2f..6a39ffe7565 100644
--- a/m4/stdalign.m4
+++ b/m4/stdalign.m4
@@ -68,8 +68,10 @@ AC_DEFUN([gl_ALIGNASOF],
   dnl The "zz" puts this toward config.h's end, to avoid potential
   dnl collisions with other definitions.
   AH_VERBATIM([zzalignas],
-[#if !defined HAVE_C_ALIGNASOF && __cplusplus < 201103 && !defined alignof
-# if HAVE_STDALIGN_H
+[#if !defined HAVE_C_ALIGNASOF \
+    && !(defined __cplusplus && 201103 <= __cplusplus) \
+    && !defined alignof
+# if defined HAVE_STDALIGN_H
 #  include <stdalign.h>
 # endif
 
@@ -166,7 +168,7 @@ AC_DEFUN([gl_ALIGNASOF],
 #   define _Alignas(a) __declspec (align (a))
 #  endif
 # endif
-# if !HAVE_STDALIGN_H
+# if !defined HAVE_STDALIGN_H
 #  if ((defined _Alignas \
         && !(defined __cplusplus \
              && (201103 <= __cplusplus || defined _MSC_VER))) \
@@ -175,7 +177,7 @@ AC_DEFUN([gl_ALIGNASOF],
 #  endif
 # endif
 
-# if _GL_STDALIGN_NEEDS_STDDEF
+# if defined _GL_STDALIGN_NEEDS_STDDEF
 #  include <stddef.h>
 # endif
 #endif])
diff --git a/m4/stdint.m4 b/m4/stdint.m4
index d6961b0993e..b9f764d4c1c 100644
--- a/m4/stdint.m4
+++ b/m4/stdint.m4
@@ -1,4 +1,4 @@
-# stdint.m4 serial 61
+# stdint.m4 serial 62
 dnl Copyright (C) 2001-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -150,7 +150,10 @@ intmax_t i = INTMAX_MAX;
 uintmax_t j = UINTMAX_MAX;
 
 /* Check that SIZE_MAX has the correct type, if possible.  */
-#if 201112 <= __STDC_VERSION__
+/* ISO C 11 mandates _Generic, but GCC versions < 4.9 lack it.  */
+#if 201112 <= __STDC_VERSION__ \
+    && (!defined __GNUC__ || 4 < __GNUC__ + (9 <= __GNUC_MINOR__) \
+        || defined __clang__)
 int k = _Generic (SIZE_MAX, size_t: 0);
 #elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \
        || (0x5110 <= __SUNPRO_C && !__STDC__))
diff --git a/m4/stpncpy.m4 b/m4/stpncpy.m4
deleted file mode 100644
index 073607004be..00000000000
--- a/m4/stpncpy.m4
+++ /dev/null
@@ -1,108 +0,0 @@
-# stpncpy.m4 serial 22
-dnl Copyright (C) 2002-2003, 2005-2007, 2009-2023 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([gl_FUNC_STPNCPY],
-[
-  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
-
-  dnl Persuade glibc <string.h> to declare stpncpy().
-  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
-
-  dnl The stpncpy() declaration in lib/string.in.h uses 'restrict'.
-  AC_REQUIRE([AC_C_RESTRICT])
-
-  AC_REQUIRE([gl_STRING_H_DEFAULTS])
-
-  dnl Both glibc and AIX (4.3.3, 5.1) have an stpncpy() function
-  dnl declared in <string.h>. Its side effects are the same as those
-  dnl of strncpy():
-  dnl      stpncpy (dest, src, n)
-  dnl overwrites dest[0..n-1], min(strlen(src),n) bytes coming from src,
-  dnl and the remaining bytes being NULs.  However, the return value is
-  dnl   in glibc:   dest + min(strlen(src),n)
-  dnl   in AIX:     dest + max(0,n-1)
-  dnl Only the glibc return value is useful in practice.
-
-  AC_CHECK_DECLS_ONCE([stpncpy])
-  gl_CHECK_FUNCS_ANDROID([stpncpy], [[#include <string.h>]])
-  if test $ac_cv_func_stpncpy = yes; then
-    AC_CACHE_CHECK([for working stpncpy], [gl_cv_func_stpncpy], [
-      AC_RUN_IFELSE(
-        [AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <string.h> /* for strcpy */
-/* The stpncpy prototype is missing in <string.h> on AIX 4.  */
-#if !HAVE_DECL_STPNCPY
-extern
-# ifdef __cplusplus
-"C"
-# endif
-char *stpncpy (char *dest, const char *src, size_t n);
-#endif
-int main ()
-{
-  int result = 0;
-  const char *src = "Hello";
-  char dest[10];
-  /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+1 here.  */
-  {
-    strcpy (dest, "\377\377\377\377\377\377");
-    if (stpncpy (dest, src, 2) != dest + 2)
-      result |= 1;
-  }
-  /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+4 here.  */
-  {
-    strcpy (dest, "\377\377\377\377\377\377");
-    if (stpncpy (dest, src, 5) != dest + 5)
-      result |= 2;
-  }
-  /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+6 here.  */
-  {
-    strcpy (dest, "\377\377\377\377\377\377");
-    if (stpncpy (dest, src, 7) != dest + 5)
-      result |= 4;
-  }
-  return result;
-}
-]])],
-        [gl_cv_func_stpncpy=yes],
-        [gl_cv_func_stpncpy=no],
-        [dnl Guess yes on glibc systems and musl systems.
-         AC_EGREP_CPP([Thanks for using GNU], [
-#include <features.h>
-#ifdef __GNU_LIBRARY__
-  Thanks for using GNU
-#endif
-],         [gl_cv_func_stpncpy="guessing yes"],
-           [case "$host_os" in
-              *-musl* | midipix*) gl_cv_func_stpncpy="guessing yes" ;;
-              *)                  gl_cv_func_stpncpy="$gl_cross_guess_normal" 
;;
-            esac
-           ])
-        ])
-    ])
-    case "$gl_cv_func_stpncpy" in
-      *yes)
-        AC_DEFINE([HAVE_STPNCPY], [1],
-          [Define if you have the stpncpy() function and it works.])
-        ;;
-      *)
-        REPLACE_STPNCPY=1
-        ;;
-    esac
-  else
-    HAVE_STPNCPY=0
-    case "$gl_cv_onwards_func_stpncpy" in
-      future*) REPLACE_STPNCPY=1 ;;
-    esac
-  fi
-])
-
-# Prerequisites of lib/stpncpy.c.
-AC_DEFUN([gl_PREREQ_STPNCPY], [
-  :
-])
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index 51d553a2f1a..632d18fc071 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -2,7 +2,7 @@
 
 # Copyright (C) 2000-2001, 2003-2007, 2009-2023 Free Software Foundation, Inc.
 
-# serial 22
+# serial 24
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -23,7 +23,10 @@ AC_DEFUN_ONCE([gl_TIME_H],
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[
 #include <time.h>
-    ]], [asctime_r ctime_r])
+    ]], [
+      asctime asctime_r ctime ctime_r gmtime_r localtime localtime_r mktime
+      nanosleep strftime strptime time timegm timespec_get timespec_getres 
tzset
+    ])
 
   AC_REQUIRE([AC_C_RESTRICT])
 
@@ -162,25 +165,15 @@ AC_DEFUN([gl_TIME_H_DEFAULTS],
   HAVE_TIMESPEC_GETRES=1;                AC_SUBST([HAVE_TIMESPEC_GETRES])
   dnl Even GNU libc does not have timezone_t yet.
   HAVE_TIMEZONE_T=0;                     AC_SUBST([HAVE_TIMEZONE_T])
-  dnl If another module says to replace or to not replace, do that.
-  dnl Otherwise, replace only if someone compiles with -DGNULIB_PORTCHECK;
-  dnl this lets maintainers check for portability.
-  REPLACE_CTIME=GNULIB_PORTCHECK;        AC_SUBST([REPLACE_CTIME])
-  REPLACE_LOCALTIME_R=GNULIB_PORTCHECK;  AC_SUBST([REPLACE_LOCALTIME_R])
-  REPLACE_MKTIME=GNULIB_PORTCHECK;       AC_SUBST([REPLACE_MKTIME])
-  REPLACE_NANOSLEEP=GNULIB_PORTCHECK;    AC_SUBST([REPLACE_NANOSLEEP])
-  REPLACE_STRFTIME=GNULIB_PORTCHECK;     AC_SUBST([REPLACE_STRFTIME])
-  REPLACE_TIME=0;                        AC_SUBST([REPLACE_TIME])
-  REPLACE_TIMEGM=GNULIB_PORTCHECK;       AC_SUBST([REPLACE_TIMEGM])
-  REPLACE_TIMESPEC_GET=GNULIB_PORTCHECK; AC_SUBST([REPLACE_TIMESPEC_GET])
-  REPLACE_TZSET=GNULIB_PORTCHECK;        AC_SUBST([REPLACE_TZSET])
-
-  dnl Hack so that the time module doesn't depend on the sys_time module.
-  dnl First, default GNULIB_GETTIMEOFDAY to 0 if sys_time is absent.
-  : ${GNULIB_GETTIMEOFDAY=0};            AC_SUBST([GNULIB_GETTIMEOFDAY])
-  dnl Second, it's OK to not use GNULIB_PORTCHECK for REPLACE_GMTIME
-  dnl and REPLACE_LOCALTIME, as portability to Solaris 2.6 and earlier
-  dnl is no longer a big deal.
+  REPLACE_CTIME=0;                       AC_SUBST([REPLACE_CTIME])
   REPLACE_GMTIME=0;                      AC_SUBST([REPLACE_GMTIME])
   REPLACE_LOCALTIME=0;                   AC_SUBST([REPLACE_LOCALTIME])
+  REPLACE_LOCALTIME_R=0;                 AC_SUBST([REPLACE_LOCALTIME_R])
+  REPLACE_MKTIME=0;                      AC_SUBST([REPLACE_MKTIME])
+  REPLACE_NANOSLEEP=0;                   AC_SUBST([REPLACE_NANOSLEEP])
+  REPLACE_STRFTIME=0;                    AC_SUBST([REPLACE_STRFTIME])
+  REPLACE_TIME=0;                        AC_SUBST([REPLACE_TIME])
+  REPLACE_TIMEGM=0;                      AC_SUBST([REPLACE_TIMEGM])
+  REPLACE_TIMESPEC_GET=0;                AC_SUBST([REPLACE_TIMESPEC_GET])
+  REPLACE_TZSET=0;                       AC_SUBST([REPLACE_TZSET])
 ])
diff --git a/m4/time_r.m4 b/m4/time_r.m4
index adce438abf1..4831eb26f90 100644
--- a/m4/time_r.m4
+++ b/m4/time_r.m4
@@ -57,9 +57,7 @@ AC_DEFUN([gl_TIME_R],
          [gl_cv_time_r_posix=yes],
          [gl_cv_time_r_posix=no])
       ])
-    if test $gl_cv_time_r_posix = yes; then
-      REPLACE_LOCALTIME_R=0
-    else
+    if test $gl_cv_time_r_posix != yes; then
       REPLACE_LOCALTIME_R=1
     fi
   else
diff --git a/m4/timegm.m4 b/m4/timegm.m4
index 8ab265e65fe..6da07807698 100644
--- a/m4/timegm.m4
+++ b/m4/timegm.m4
@@ -1,4 +1,4 @@
-# timegm.m4 serial 15
+# timegm.m4 serial 16
 dnl Copyright (C) 2003, 2007, 2009-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,7 +8,6 @@ AC_DEFUN([gl_FUNC_TIMEGM],
 [
   AC_REQUIRE([gl_TIME_H_DEFAULTS])
   AC_REQUIRE([gl_FUNC_MKTIME_WORKS])
-  REPLACE_TIMEGM=0
   gl_CHECK_FUNCS_ANDROID([timegm], [[#include <time.h>]])
   if test $ac_cv_func_timegm = yes; then
     if test "$gl_cv_func_working_mktime" != yes; then
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index dd7f650e8e3..d299ec17574 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -186,6 +186,7 @@ s/ *@WEBP_LIBS@//
 /^HARFBUZZ_CFLAGS *=/s/@HARFBUZZ_CFLAGS@//
 /^HARFBUZZ_LIBS *=/s/@HARFBUZZ_LIBS@//
 /^QCOPY_ACL_LIB *=/s/@QCOPY_ACL_LIB@//
+/^TIMER_TIME_LIB *=/s/@TIMER_TIME_LIB@//
 /^LCMS2_CFLAGS *=/s/@LCMS2_CFLAGS@//
 /^LCMS2_LIBS *=/s/@LCMS2_LIBS@//
 /^LIBGMP *=/s/@LIBGMP@//
diff --git a/msdos/sedlibmk.inp b/msdos/sedlibmk.inp
index f3554e7b001..664bfaf693c 100644
--- a/msdos/sedlibmk.inp
+++ b/msdos/sedlibmk.inp
@@ -489,6 +489,7 @@ OMIT_GNULIB_MODULE_strtoll = true\
 OMIT_GNULIB_MODULE_symlink = true\
 OMIT_GNULIB_MODULE_sys_select = true\
 OMIT_GNULIB_MODULE_sys_time = true\
+OMIT_GNULIB_MODULE_boot-time = true\
 OMIT_GNULIB_MODULE_crypto\/md5 = true
 /^arg-nonnull\.h:/,/^[         ][      ]*mv /c\
 arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h\
diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h
index 58be1199345..fce15fcbd8c 100644
--- a/nt/inc/ms-w32.h
+++ b/nt/inc/ms-w32.h
@@ -111,18 +111,6 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 # endif
 #endif
 
-/* This isn't perfect, as some systems might have the page file in
-   another place.  Also, I suspect that the time stamp of that file
-   might also change when Windows enlarges the file due to
-   insufficient VM.  Still, this seems to be the most reliable way;
-   the alternative (of using GetSystemTimes) won't work on laptops
-   that hibernate, because the system clock is stopped then.  Other
-   possibility would be to run "net statistics workstation" and parse
-   the output, but that's gross.  So this should do; if the file is
-   not there, the boot time will be returned as zero, and filelock.c
-   already handles that.  */
-#define BOOT_TIME_FILE "C:/pagefile.sys"
-
 /* ============================================================ */
 
 /* Here, add any special hacks needed to make Emacs work on this
diff --git a/src/ChangeLog.3 b/src/ChangeLog.3
index 31fb11b06d7..fbfb36fdb2a 100644
--- a/src/ChangeLog.3
+++ b/src/ChangeLog.3
@@ -1250,7 +1250,7 @@
 
        * data.c (Fdefine_function): New function (same code as Fdefalias).
 
-1993-04-28  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-28  Eric S. Raymond  (esr@thyrsus.com)
 
        * eval.c (do_autoload): Fixed the bug in the autoload-saving code.
 
@@ -1258,7 +1258,7 @@
 
        * keyboard.c (Fcurrent_input_mode): New function.
 
-1993-04-27  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-27  Eric S. Raymond  (esr@thyrsus.com)
 
        * eval.c (un_autoload): Don't try to save old autoload forms when
        we load something in.  Something about the code now conditioned
@@ -1311,7 +1311,7 @@
        * dispnew.c (Fsleep_for, Fsit_for): Allow SECONDS to be a
        floating point value.
 
-1993-04-26  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-26  Eric S. Raymond  (esr@thyrsus.com)
 
        * sysdep.c (read_pending_input):
        Fix the garbaged-modifiers bug under System Vs previous
@@ -1330,7 +1330,7 @@
        beginning or end of the original text to float to the
        corresponding position in the replacement text.
 
-1993-04-25  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-25  Eric S. Raymond  (esr@thyrsus.com)
 
        * window.c (Fset-window-buffer):
        Set horizontal-scrolling on a window to zero when
@@ -1351,7 +1351,7 @@
        (apply_modifiers): Don't abort if you see extra modifier bits,
        just remove them.
 
-1993-04-23  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-23  Eric S. Raymond  (esr@thyrsus.com)
 
        * data.c (Fdefine_function):
        Changed name back to Fdefalias, so we get things
@@ -1386,7 +1386,7 @@
        (eval_region, eval_buffer): Call readevalloop with new arg.
        (load_history): New variable.
 
-1993-04-16  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-04-16  Eric S. Raymond  (esr@thyrsus.com)
 
        * lread.c (readevalloop): New argument is the source file name (or
        nil if none).  All calls changed.  Do the two-step
@@ -1928,7 +1928,7 @@
        * xfns.c (Fx_display_color_p): Renamed from Fx_color_display_p.
        (syms_of_xfns): Use new name in defsubr.
 
-1993-03-19  Eric S. Raymond  (eric@geech.gnu.ai.mit.edu)
+1993-03-19  Eric S. Raymond  (esr@thyrsus.com)
 
        * Makefile.in (unlock, relock): New productions to assist with
        version control.
@@ -1960,7 +1960,7 @@
        * xfns.c (x_screen): Make this var file scope.
        (Fx_server_version): Use Fcons, not list3.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * xterm.c (term_get_fkeys): Less klugey version of the last fix.
 
@@ -1976,7 +1976,7 @@
        * xterm.c (x_display_box_cursor, x_display_bar_cursor): Don't
        display the cursor on garbaged frames.
 
-1993-03-17  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-17  Eric S. Raymond  (esr@thyrsus.com)
 
        * term.c (term_get_fkeys) Supply second args for all tgetstr calls.
 
@@ -2182,7 +2182,7 @@
        * cmd.c (internal_self_insert): Check that tab_width does not
        exceed 20, to be consistent with indent.c and xdisp.c.
 
-1993-03-12  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-12  Eric S. Raymond  (esr@thyrsus.com)
 
        * term.c (CONDITIONAL_REASSIGN): Fixed reference to tigetstr.
        This should have been tgetstr, but I typoed and tigetstr happens
@@ -2215,7 +2215,7 @@
        (make_lispy_event): Handle menu bar events.
        (read_key_sequence): Make dummy prefix `menu-bar' for menu bar events.
 
-1993-03-11  Eric S. Raymond  (eric@mole.gnu.ai.mit.edu)
+1993-03-11  Eric S. Raymond  (esr@thyrsus.com)
 
        * term.c (fkey_table): Added many more keycap cookies to the
        fkey_table; it now supports the full intersection of the set of X
@@ -2289,7 +2289,7 @@
        have the data_start symbol defined, so we'll just use the address
        of environ.
 
-       * s/usg5-4.h: Changes from Eric Raymond:
+       * s/usg5-4.h: Changes from Eric S. Raymond:
        If we're doing ordinary linking, define LIB_STANDARD appropriately.
        Give LIBS_DEBUG a null definition; usg5-4 has no -lg.
        #define LIBS_STANDARD as "-lc"; usg5-4 has no -lPW.
@@ -2297,7 +2297,7 @@
        #define HAVE_TERMIOS instead of HAVE_TCATTR.
        Provide our own definition of LIB_X11_LIB.
 
-       * s/usg5-3.h (LIBX11_SYSTEM): Eric Raymond says the libraries here
+       * s/usg5-3.h (LIBX11_SYSTEM): Eric S. Raymond says the libraries here
        were slightly wrong.
 
        * m/intel386.h (LIB_STANDARD): If USG5_4 is #defined, there's no
@@ -4335,7 +4335,7 @@
        * Makefile.in: Rearrange dependencies to make sure that xmakefile
        is built before we try to use it, even using a parallel make.
 
-       Changes for SYSV from Eric Raymond:
+       Changes for SYSV from Eric S. Raymond:
        * process.c [SYSV]: Don't include <termios.h>, <termio.h>, or
        <fcntl.h>.
        (process_send_signal): Don't try to send SIGTSTP
@@ -6187,7 +6187,7 @@
 
        * xterm.c: Doc fixes.
 
-       More SYSV portability changes from Eric Raymond:
+       More SYSV portability changes from Eric S. Raymond:
 
        * xterm.c [USG5]: Don't include <sys/types.h>.
 
@@ -6222,7 +6222,7 @@
 
 1992-08-14  Jim Blandy  (jimb@pogo.cs.oberlin.edu)
 
-       Applied SYSV portability changes from Eric Raymond:
+       Applied SYSV portability changes from Eric S. Raymond:
 
        * xrdb.c [USG5]: Define SYSV, and then include <unistd.h>.
        Apparently, Xlib.h include string.h if SYSV is defined, and
@@ -6279,7 +6279,7 @@
 
        * sysdep.c [USG5]: Don't include fcntl.h.
 
-       * s/usg5-3.h: Eric Raymond writes:
+       * s/usg5-3.h: Eric S. Raymond writes:
        Define HAVE_SELECT and BSTRINGS only if HAVE_X_WINDOWS is on,
        because that means we'll be linking in the shared libraries
        containing the BSD emulations.  Teach the file about the shared
@@ -6333,7 +6333,7 @@
        wasn't written portably, and it should probably go somewhere else
        anyway - say, funcall or eval.
 
-       End of changes from Eric Raymond.
+       End of changes from Eric S. Raymond.
 
        * xfns.c (Fx_create_frame): Make the default for the icon-type
        parameter nil, not t.  It seems to cause problems with some X
diff --git a/src/Makefile.in b/src/Makefile.in
index 87f03261a41..0f16b485a3e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -167,7 +167,7 @@ CLOCK_TIME_LIB=@CLOCK_TIME_LIB@
 EUIDACCESS_LIBGEN=@EUIDACCESS_LIBGEN@
 NANOSLEEP_LIB=@NANOSLEEP_LIB@
 QCOPY_ACL_LIB=@QCOPY_ACL_LIB@
-LIB_TIMER_TIME=@LIB_TIMER_TIME@
+TIMER_TIME_LIB=@TIMER_TIME_LIB@
 
 DBUS_CFLAGS = @DBUS_CFLAGS@
 DBUS_LIBS = @DBUS_LIBS@
@@ -597,7 +597,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) 
$(LIBX_BASE) $(LIBIMAGE
    $(LIBX_OTHER) $(LIBSOUND) \
    $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(CLOCK_TIME_LIB) \
    $(NANOSLEEP_LIB) $(QCOPY_ACL_LIB) $(WEBKIT_LIBS) \
-   $(EUIDACCESS_LIBGEN) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
+   $(EUIDACCESS_LIBGEN) $(TIMER_TIME_LIB) $(DBUS_LIBS) \
    $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \
    $(XDBE_LIBS) $(XSYNC_LIBS) \
    $(LIBXML2_LIBS) $(LIBGPM) $(LIBS_SYSTEM) $(CAIRO_LIBS) \
diff --git a/src/android-emacs.c b/src/android-emacs.c
index e64caf9a9d4..2c405795860 100644
--- a/src/android-emacs.c
+++ b/src/android-emacs.c
@@ -37,7 +37,7 @@ main (int argc, char **argv)
 {
   char **args;
   int i;
-  char *bootclasspath, *emacs_class_path;
+  char *bootclasspath, *emacs_class_path, *ld_library_path;
 
   /* Allocate enough to hold the arguments to app_process.  */
   args = alloca ((10 + argc) * sizeof *args);
@@ -46,11 +46,11 @@ main (int argc, char **argv)
   memset (args, 0, (10 + argc) * sizeof *args);
 
   /* First, figure out what program to start.  */
-#if defined __x86_64__ || defined __aarch64__
+#if defined __x86_64__ || defined __aarch64__ || defined __mips64
   args[0] = (char *) "/system/bin/app_process64";
-#else
+#else /* i386 || regular mips || arm */
   args[0] = (char *) "/system/bin/app_process";
-#endif
+#endif /* __x86_64__ || __aarch64__ || __mips64 */
 
   /* Machines with ART require the boot classpath to be manually
      specified.  Machines with Dalvik however refuse to do so, as they
@@ -72,13 +72,13 @@ main (int argc, char **argv)
       bootclasspath = NULL;
       goto skip_setup;
     }
-#else
+#else /* !HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL */
   if (__ANDROID_API__ < 21)
     {
       bootclasspath = NULL;
       goto skip_setup;
     }
-#endif
+#endif /* HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL */
 
   /* Next, obtain the boot class path.  */
   bootclasspath = getenv ("BOOTCLASSPATH");
@@ -106,6 +106,15 @@ main (int argc, char **argv)
       return 1;
     }
 
+  /* Restore LD_LIBRARY_PATH to its original value, the app library
+     directory, to guarantee that it is possible for Java to find the
+     Emacs C code later.  */
+
+  ld_library_path = getenv ("EMACS_LD_LIBRARY_PATH");
+
+  if (ld_library_path)
+    setenv ("LD_LIBRARY_PATH", ld_library_path, 1);
+
   if (bootclasspath)
     {
       if (asprintf (&bootclasspath, "-Djava.class.path=%s:%s",
@@ -146,7 +155,7 @@ main (int argc, char **argv)
     }
   else
     {
-#endif
+#endif /* HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL */
       args[3] = (char *) "org.gnu.emacs.EmacsNoninteractive";
 
       /* Arguments from here on are passed to main in
@@ -158,7 +167,7 @@ main (int argc, char **argv)
        args[4 + i] = argv[i];
 #if HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL
     }
-#endif
+#endif /* HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL */
 
   /* Finally, try to start the app_process.  */
   execvp (args[0], args);
diff --git a/src/android.c b/src/android.c
index bd19107f53a..ed304baf0e6 100644
--- a/src/android.c
+++ b/src/android.c
@@ -18,31 +18,28 @@ You should have received a copy of the GNU General Public 
License
 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <allocator.h>
+#include <assert.h>
+#include <careadlinkat.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
-#include <pthread.h>
+#include <fingerprint.h>
+#include <intprops.h>
+#include <libgen.h>
 #include <limits.h>
-#include <signal.h>
-#include <semaphore.h>
-#include <dlfcn.h>
-#include <errno.h>
 #include <math.h>
-#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
 #include <stdckdint.h>
-#include <intprops.h>
-#include <timespec.h>
-#include <libgen.h>
-
-#include <sys/stat.h>
-#include <sys/mman.h>
+#include <string.h>
 #include <sys/param.h>
+#include <timespec.h>
+#include <unistd.h>
 
 /* Old NDK versions lack MIN and MAX.  */
 #include <minmax.h>
 
-#include <assert.h>
-#include <fingerprint.h>
-
 #include "android.h"
 #include "androidgui.h"
 
@@ -1110,41 +1107,6 @@ android_get_content_name (const char *filename)
   return NULL;
 }
 
-/* Return whether or not the specified FILENAME is an accessible
-   content URI.  MODE specifies what to check.  */
-
-static bool
-android_check_content_access (const char *filename, int mode)
-{
-  const char *name;
-  jobject string;
-  size_t length;
-  jboolean rc;
-
-  name = android_get_content_name (filename);
-  length = strlen (name);
-
-  string = (*android_java_env)->NewByteArray (android_java_env,
-                                             length);
-  android_exception_check ();
-
-  (*android_java_env)->SetByteArrayRegion (android_java_env,
-                                          string, 0, length,
-                                          (jbyte *) name);
-  rc = (*android_java_env)->CallBooleanMethod (android_java_env,
-                                              emacs_service,
-                                              service_class.check_content_uri,
-                                              string,
-                                              (jboolean) ((mode & R_OK)
-                                                          != 0),
-                                              (jboolean) ((mode & W_OK)
-                                                          != 0));
-  android_exception_check_1 (string);
-  ANDROID_DELETE_LOCAL_REF (string);
-
-  return rc;
-}
-
 #endif /* 0 */
 
 /* Return the current user's ``home'' directory, which is actually the
@@ -1157,24 +1119,23 @@ android_get_home_directory (void)
 }
 
 /* Return the name of the file behind a file descriptor FD by reading
-   /proc/self/fd/.  Place the name in BUFFER, which should be able to
-   hold size bytes.  Value is 0 upon success, and 1 upon failure.  */
+   /proc/self/fd/.  Value is allocated memory holding the file name
+   upon success, and 0 upon failure.  */
 
-static int
-android_proc_name (int fd, char *buffer, size_t size)
+static char *
+android_proc_name (int fd)
 {
   char format[sizeof "/proc/self/fd/"
              + INT_STRLEN_BOUND (int)];
-  ssize_t read;
+  static struct allocator allocator = {
+    /* Fill the allocator with C library malloc functions.  xmalloc
+       and so aren't thread safe.  */
+    malloc, realloc, free, NULL,
+  };
 
   sprintf (format, "/proc/self/fd/%d", fd);
-  read = readlink (format, buffer, size - 1);
-
-  if (read == -1)
-    return 1;
-
-  buffer[read] = '\0';
-  return 0;
+  return careadlinkat (AT_FDCWD, format, NULL, 0,
+                      &allocator, readlinkat);
 }
 
 /* Try to guarantee the existence of the `lib' directory within the
@@ -1424,6 +1385,12 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject 
object,
   /* Set LD_LIBRARY_PATH to an appropriate value.  */
   setenv ("LD_LIBRARY_PATH", android_lib_dir, 1);
 
+  /* EMACS_LD_LIBRARY_PATH records the location of the app library
+     directory.  android-emacs refers to this, since users have valid
+     reasons for changing LD_LIBRARY_PATH to a value that precludes
+     the possibility of Java locating libemacs later.  */
+  setenv ("EMACS_LD_LIBRARY_PATH", android_lib_dir, 1);
+
   /* Make a reference to the Emacs service.  */
 
   if (emacs_service_object)
@@ -1459,11 +1426,12 @@ NATIVE_NAME (getProcName) (JNIEnv *env, jobject object, 
jint fd)
 {
   JNI_STACK_ALIGNMENT_PROLOGUE;
 
-  char buffer[PATH_MAX + 1];
+  char *buffer;
   size_t length;
   jbyteArray array;
 
-  if (android_proc_name (fd, buffer, PATH_MAX + 1))
+  buffer = android_proc_name (fd);
+  if (!buffer)
     return NULL;
 
   /* Return a byte array, as Java strings cannot always encode file
@@ -1471,11 +1439,13 @@ NATIVE_NAME (getProcName) (JNIEnv *env, jobject object, 
jint fd)
   length = strlen (buffer);
   array = (*env)->NewByteArray (env, length);
   if (!array)
-    return NULL;
+    goto finish;
 
   (*env)->SetByteArrayRegion (env, array, 0, length,
                              (jbyte *) buffer);
 
+ finish:
+  free (buffer);
   return array;
 }
 
@@ -1544,7 +1514,7 @@ android_init_emacs_service (void)
   FIND_METHOD (open_content_uri, "openContentUri",
               "([BZZZ)I");
   FIND_METHOD (check_content_uri, "checkContentUri",
-              "([BZZ)Z");
+              "(Ljava/lang/String;ZZ)Z");
   FIND_METHOD (query_battery, "queryBattery", "()[J");
   FIND_METHOD (update_extracted_text, "updateExtractedText",
               "(Lorg/gnu/emacs/EmacsWindow;"
@@ -1564,7 +1534,7 @@ android_init_emacs_service (void)
               "(Ljava/lang/String;Ljava/lang/String;)"
               "Ljava/lang/String;");
   FIND_METHOD (stat_document, "statDocument",
-              "(Ljava/lang/String;Ljava/lang/String;)[J");
+              "(Ljava/lang/String;Ljava/lang/String;Z)[J");
   FIND_METHOD (access_document, "accessDocument",
               "(Ljava/lang/String;Ljava/lang/String;Z)I");
   FIND_METHOD (open_document_directory, "openDocumentDirectory",
@@ -1574,7 +1544,7 @@ android_init_emacs_service (void)
               "(Landroid/database/Cursor;)Lorg/gnu/emacs/"
               "EmacsDirectoryEntry;");
   FIND_METHOD (open_document, "openDocument",
-              "(Ljava/lang/String;Ljava/lang/String;ZZ)"
+              "(Ljava/lang/String;Ljava/lang/String;ZZZ)"
               "Landroid/os/ParcelFileDescriptor;");
   FIND_METHOD (create_document, "createDocument",
               "(Ljava/lang/String;Ljava/lang/String;"
diff --git a/src/android.h b/src/android.h
index a052d3a3b21..e865d7da665 100644
--- a/src/android.h
+++ b/src/android.h
@@ -75,6 +75,8 @@ extern int android_renameat_noreplace (int, const char *,
                                       int, const char *);
 extern int android_rename (const char *, const char *);
 extern int android_fchmodat (int, const char *, mode_t, int);
+extern ssize_t android_readlinkat (int, const char *restrict, char *restrict,
+                                  size_t);
 
 
 
diff --git a/src/androidfns.c b/src/androidfns.c
index 0270f58b6b9..9e8372f524b 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -2410,11 +2410,16 @@ DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
   (void)
 {
 #ifdef ANDROID_STUBIFY
+  /* Fx_hide_tip is called from pre-command-hook (in turn called from
+     the tests.)  Since signaling here prevents any tests from being
+     run, refrain from protesting if this stub is called.  */
+#if 0
   error ("Android cross-compilation stub called!");
+#endif /* 0 */
   return Qnil;
-#else
+#else /* !ANDROID_STUBIFY */
   return android_hide_tip (true);
-#endif
+#endif /* ANDROID_STUBIFY */
 }
 
 DEFUN ("android-detect-mouse", Fandroid_detect_mouse,
diff --git a/src/androidselect.c b/src/androidselect.c
index 9910e7921de..5735eda2dd5 100644
--- a/src/androidselect.c
+++ b/src/androidselect.c
@@ -22,6 +22,9 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <minmax.h>
 #include <unistd.h>
 
+#include <boot-time.h>
+#include <sys/types.h>
+
 #include "lisp.h"
 #include "blockinput.h"
 #include "coding.h"
@@ -466,6 +469,286 @@ does not have any corresponding data.  In that case, use
 
 
 
+/* Desktop notifications.  `android-desktop-notify' implements a
+   facsimile of `notifications-notify'.  */
+
+/* Structure describing the EmacsDesktopNotification class.  */
+
+struct android_emacs_desktop_notification
+{
+  jclass class;
+  jmethodID init;
+  jmethodID display;
+};
+
+/* Methods provided by the EmacsDesktopNotification class.  */
+static struct android_emacs_desktop_notification notification_class;
+
+/* Initialize virtual function IDs and class pointers tied to the
+   EmacsDesktopNotification class.  */
+
+static void
+android_init_emacs_desktop_notification (void)
+{
+  jclass old;
+
+  notification_class.class
+    = (*android_java_env)->FindClass (android_java_env,
+                                     "org/gnu/emacs/EmacsDesktopNotification");
+  eassert (notification_class.class);
+
+  old = notification_class.class;
+  notification_class.class
+    = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
+                                                 old);
+  ANDROID_DELETE_LOCAL_REF (old);
+
+  if (!notification_class.class)
+    emacs_abort ();
+
+#define FIND_METHOD(c_name, name, signature)                           \
+  notification_class.c_name                                            \
+    = (*android_java_env)->GetMethodID (android_java_env,              \
+                                       notification_class.class,       \
+                                       name, signature);               \
+  assert (notification_class.c_name);
+
+  FIND_METHOD (init, "<init>", "(Ljava/lang/String;"
+              "Ljava/lang/String;Ljava/lang/String;"
+              "Ljava/lang/String;II)V");
+  FIND_METHOD (display, "display", "()V");
+#undef FIND_METHOD
+}
+
+/* Return the numeric resource ID designating the icon within the
+   ``android.R.drawable'' package by the supplied NAME.
+
+   If no icon is found, return that of
+   ``android.R.drawable.ic_dialog_alert''.  */
+
+static jint
+android_locate_icon (const char *name)
+{
+  jclass drawable;
+  jfieldID field;
+  jint rc;
+
+  if (android_verify_jni_string (name))
+    /* If NAME isn't valid, return the default value.  */
+    return 17301543; /* android.R.drawable.ic_dialog_alert.  */
+
+  drawable = (*android_java_env)->FindClass (android_java_env,
+                                            "android/R$drawable");
+  android_exception_check ();
+
+  field = (*android_java_env)->GetStaticFieldID (android_java_env,
+                                                drawable, name, "I");
+  (*android_java_env)->ExceptionClear (android_java_env);
+
+  if (!field)
+    rc = 17301543; /* android.R.drawable.ic_dialog_alert.  */
+  else
+    rc = (*android_java_env)->GetStaticIntField (android_java_env,
+                                                drawable, field);
+
+  ANDROID_DELETE_LOCAL_REF (drawable);
+  return rc;
+}
+
+/* Display a desktop notification with the provided TITLE, BODY,
+   REPLACES_ID, GROUP, ICON, and URGENCY.  Return an identifier for
+   the resulting notification.  */
+
+static intmax_t
+android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
+                               Lisp_Object replaces_id,
+                               Lisp_Object group, Lisp_Object icon,
+                               Lisp_Object urgency)
+{
+  static intmax_t counter;
+  intmax_t id;
+  jstring title1, body1, group1, identifier1;
+  jint type, icon1;
+  jobject notification;
+  char identifier[INT_STRLEN_BOUND (int)
+                 + INT_STRLEN_BOUND (long int)
+                 + INT_STRLEN_BOUND (intmax_t)
+                 + sizeof "..."];
+  struct timespec boot_time;
+
+  if (EQ (urgency, Qlow))
+    type = 2; /* IMPORTANCE_LOW */
+  else if (EQ (urgency, Qnormal))
+    type = 3; /* IMPORTANCE_DEFAULT */
+  else if (EQ (urgency, Qcritical))
+    type = 4; /* IMPORTANCE_HIGH */
+  else
+    signal_error ("Invalid notification importance given", urgency);
+
+  if (NILP (replaces_id))
+    {
+      /* Generate a new identifier.  */
+      INT_ADD_WRAPV (counter, 1, &counter);
+      id = counter;
+    }
+  else
+    {
+      CHECK_INTEGER (replaces_id);
+      if (!integer_to_intmax (replaces_id, &id))
+       id = -1; /* Overflow.  */
+    }
+
+  /* Locate the integer ID linked to ICON.  */
+  icon1 = android_locate_icon (SSDATA (icon));
+
+  /* Generate a unique identifier for this notification.  Because
+     Android persists notifications past system shutdown, also include
+     the boot time within IDENTIFIER.  Scale it down to avoid being
+     perturbed by minor instabilities in the returned boot time,
+     however.  */
+
+  boot_time.tv_sec = 0;
+  get_boot_time (&boot_time);
+  sprintf (identifier, "%d.%ld.%jd", (int) getpid (),
+          (long int) (boot_time.tv_sec / 2), id);
+
+  /* Encode all strings into their Java counterparts.  */
+  title1 = android_build_string (title);
+  body1  = android_build_string (body);
+  group1 = android_build_string (group);
+  identifier1 = android_build_jstring (identifier);
+
+  /* Create the notification.  */
+  notification
+    = (*android_java_env)->NewObject (android_java_env,
+                                     notification_class.class,
+                                     notification_class.init,
+                                     title1, body1, group1,
+                                     identifier1, icon1, type);
+  android_exception_check_4 (title1, body1, group1, identifier1);
+
+  /* Delete unused local references.  */
+  ANDROID_DELETE_LOCAL_REF (title1);
+  ANDROID_DELETE_LOCAL_REF (body1);
+  ANDROID_DELETE_LOCAL_REF (group1);
+  ANDROID_DELETE_LOCAL_REF (identifier1);
+
+  /* Display the notification.  */
+  (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
+                                                notification,
+                                                notification_class.class,
+                                                notification_class.display);
+  android_exception_check_1 (notification);
+  ANDROID_DELETE_LOCAL_REF (notification);
+
+  /* Return the ID.  */
+  return id;
+}
+
+DEFUN ("android-notifications-notify", Fandroid_notifications_notify,
+       Sandroid_notifications_notify, 0, MANY, 0, doc:
+       /* Display a desktop notification.
+ARGS must contain keywords followed by values.  Each of the following
+keywords is understood:
+
+  :title        The notification title.
+  :body         The notification body.
+  :replaces-id  The ID of a previous notification to supersede.
+  :group        The notification group, or nil.
+  :urgency      One of the symbols `low', `normal' or `critical',
+                defining the importance of the notification group.
+  :icon         The name of a drawable resource to display as the
+                notification's icon.
+
+The notification group and urgency are ignored on Android 7.1 and
+earlier versions of Android.  Outside such older systems, it
+identifies a category that will be displayed in the system Settings
+menu.  The urgency provided always extends to affect all notifications
+displayed within that category.  If the group is not provided, it
+defaults to the string "Desktop Notifications".
+
+The provided icon should be the name of a "drawable resource" present
+within the "android.R.drawable" class designating an icon with a
+transparent background.  If no icon is provided (or the icon is absent
+from this system), it defaults to "ic_dialog_alert".
+
+When the system is running Android 13 or later, notifications sent
+will be silently disregarded unless permission to display
+notifications is expressly granted from the "App Info" settings panel
+corresponding to Emacs.
+
+A title and body must be supplied.  Value is an integer (fixnum or
+bignum) uniquely designating the notification displayed, which may
+subsequently be specified as the `:replaces-id' of another call to
+this function.
+
+usage: (android-notifications-notify &rest ARGS) */)
+  (ptrdiff_t nargs, Lisp_Object *args)
+{
+  Lisp_Object title, body, replaces_id, group, urgency;
+  Lisp_Object icon;
+  Lisp_Object key, value;
+  ptrdiff_t i;
+
+  if (!android_init_gui)
+    error ("No Android display connection!");
+
+  /* Clear each variable above.  */
+  title = body = replaces_id = group = icon = urgency = Qnil;
+
+  /* If NARGS is odd, error.  */
+
+  if (nargs & 1)
+    error ("Odd number of arguments in call to 
`android-notifications-notify'");
+
+  /* Next, iterate through ARGS, searching for arguments.  */
+
+  for (i = 0; i < nargs; i += 2)
+    {
+      key = args[i];
+      value = args[i + 1];
+
+      if (EQ (key, QCtitle))
+       title = value;
+      else if (EQ (key, QCbody))
+       body = value;
+      else if (EQ (key, QCreplaces_id))
+       replaces_id = value;
+      else if (EQ (key, QCgroup))
+       group = value;
+      else if (EQ (key, QCurgency))
+       urgency = value;
+      else if (EQ (key, QCicon))
+       icon = value;
+    }
+
+  /* Demand at least TITLE and BODY be present.  */
+
+  if (NILP (title) || NILP (body))
+    error ("Title or body not provided");
+
+  /* Now check the type and possibly expand each non-nil argument.  */
+
+  CHECK_STRING (title);
+  CHECK_STRING (body);
+
+  if (NILP (urgency))
+    urgency = Qlow;
+
+  if (NILP (group))
+    group = build_string ("Desktop Notifications");
+
+  if (NILP (icon))
+    icon = build_string ("ic_dialog_alert");
+  else
+    CHECK_STRING (icon);
+
+  return make_int (android_notifications_notify_1 (title, body, replaces_id,
+                                                  group, icon, urgency));
+}
+
+
+
 void
 init_androidselect (void)
 {
@@ -476,6 +759,7 @@ init_androidselect (void)
     return;
 
   android_init_emacs_clipboard ();
+  android_init_emacs_desktop_notification ();
 
   make_clipboard = clipboard_class.make_clipboard;
   tem
@@ -496,6 +780,17 @@ init_androidselect (void)
 void
 syms_of_androidselect (void)
 {
+  DEFSYM (QCtitle, ":title");
+  DEFSYM (QCbody, ":body");
+  DEFSYM (QCreplaces_id, ":replaces-id");
+  DEFSYM (QCgroup, ":group");
+  DEFSYM (QCurgency, ":urgency");
+  DEFSYM (QCicon, ":icon");
+
+  DEFSYM (Qlow, "low");
+  DEFSYM (Qnormal, "normal");
+  DEFSYM (Qcritical, "critical");
+
   defsubr (&Sandroid_clipboard_owner_p);
   defsubr (&Sandroid_set_clipboard);
   defsubr (&Sandroid_get_clipboard);
@@ -503,4 +798,6 @@ syms_of_androidselect (void)
   defsubr (&Sandroid_browse_url);
   defsubr (&Sandroid_get_clipboard_targets);
   defsubr (&Sandroid_get_clipboard_data);
+
+  defsubr (&Sandroid_notifications_notify);
 }
diff --git a/src/androidterm.c b/src/androidterm.c
index f74463f88cd..473bea76ef5 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -4869,17 +4869,17 @@ android_perform_conversion_query (void *data)
   context->success = true;
 }
 
-/* Convert a string BUFFERS containing N characters in Emacs's
-   internal multibyte encoding to a Java string utilizing the
-   specified JNI environment.
+/* Convert a string in BUFFER, containing N characters in Emacs's
+   internal multibyte encoding, to a Java string utilizing the
+   specified JNI environment ENV.
 
-   If N is equal to BYTES, then BUFFER is a single byte buffer.
-   Otherwise, BUFFER is a multibyte buffer.
+   If N is equal to BYTES, then BUFFER holds unibyte or plain-ASCII
+   characters.  Otherwise, BUFFER holds multibyte characters.
 
    Make sure N and BYTES are absolutely correct, or you are asking for
    trouble.
 
-   Value is the string upon success, NULL otherwise.  Any exceptions
+   Value is a jstring upon success, NULL otherwise.  Any exceptions
    generated are not cleared.  */
 
 static jstring
diff --git a/src/androidvfs.c b/src/androidvfs.c
index 4234e337acb..d6b832d6caf 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -214,6 +214,10 @@ struct android_vops
      AT_SYMLINK_NOFOLLOW.  */
   int (*chmod) (struct android_vnode *, mode_t, int);
 
+  /* Return the target of VNODE if it is a symbolic link, or -1.
+     Value and errno are the same as with `readlink'.  */
+  ssize_t (*readlink) (struct android_vnode *, char *, size_t);
+
   /* Open the specified VNODE as a directory.
      Value is a ``directory handle'', or NULL upon failure.  */
   struct android_vdir *(*opendir) (struct android_vnode *);
@@ -625,6 +629,8 @@ static int android_unix_stat (struct android_vnode *, 
struct stat *);
 static int android_unix_access (struct android_vnode *, int);
 static int android_unix_mkdir (struct android_vnode *, mode_t);
 static int android_unix_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_unix_readlink (struct android_vnode *, char *,
+                                     size_t);
 static struct android_vdir *android_unix_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with Unix filesystem VFS
@@ -643,6 +649,7 @@ static struct android_vops unix_vfs_ops =
     android_unix_access,
     android_unix_mkdir,
     android_unix_chmod,
+    android_unix_readlink,
     android_unix_opendir,
   };
 
@@ -898,6 +905,16 @@ android_unix_chmod (struct android_vnode *vnode, mode_t 
mode,
   return fchmodat (AT_FDCWD, vp->name, mode, flags);
 }
 
+static ssize_t
+android_unix_readlink (struct android_vnode *vnode, char *buffer,
+                      size_t size)
+{
+  struct android_unix_vnode *vp;
+
+  vp = (struct android_unix_vnode *) vnode;
+  return readlink (vp->name, buffer, size);
+}
+
 static struct dirent *
 android_unix_readdir (struct android_vdir *vdir)
 {
@@ -1606,6 +1623,8 @@ static int android_afs_stat (struct android_vnode *, 
struct stat *);
 static int android_afs_access (struct android_vnode *, int);
 static int android_afs_mkdir (struct android_vnode *, mode_t);
 static int android_afs_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_afs_readlink (struct android_vnode *, char *,
+                                    size_t);
 static struct android_vdir *android_afs_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with asset VFS nodes.  */
@@ -1623,6 +1642,7 @@ static struct android_vops afs_vfs_ops =
     android_afs_access,
     android_afs_mkdir,
     android_afs_chmod,
+    android_afs_readlink,
     android_afs_opendir,
   };
 
@@ -2139,6 +2159,28 @@ android_afs_chmod (struct android_vnode *vnode, mode_t 
mode,
   return -1;
 }
 
+static ssize_t
+android_afs_readlink (struct android_vnode *vnode, char *buffer,
+                     size_t size)
+{
+  struct android_afs_vnode *vp;
+  const char *dir;
+
+  vp = (struct android_afs_vnode *) vnode;
+  dir = android_scan_directory_tree (vp->name, NULL);
+
+  /* As there are no symlinks in /assets, just return -1 with errno
+     set to a reasonable value contingent upon whether VP->name
+     actually exists.  */
+
+  if (dir)
+    errno = EINVAL;
+  else
+    errno = ENOENT;
+
+  return -1;
+}
+
 static struct dirent *
 android_afs_readdir (struct android_vdir *vdir)
 {
@@ -2379,6 +2421,8 @@ static int android_content_stat (struct android_vnode *, 
struct stat *);
 static int android_content_access (struct android_vnode *, int);
 static int android_content_mkdir (struct android_vnode *, mode_t);
 static int android_content_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_content_readlink (struct android_vnode *, char *,
+                                        size_t);
 static struct android_vdir *android_content_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with the content VFS node.  */
@@ -2396,6 +2440,7 @@ static struct android_vops content_vfs_ops =
     android_content_access,
     android_content_mkdir,
     android_content_chmod,
+    android_content_readlink,
     android_content_opendir,
   };
 
@@ -2600,7 +2645,7 @@ static int
 android_content_mkdir (struct android_vnode *vnode, mode_t mode)
 {
   errno = EEXIST;
-  return 0;
+  return -1;
 }
 
 static int
@@ -2608,7 +2653,15 @@ android_content_chmod (struct android_vnode *vnode, 
mode_t mode,
                       int flags)
 {
   errno = EACCES;
-  return 0;
+  return -1;
+}
+
+static ssize_t
+android_content_readlink (struct android_vnode *vnode, char *buffer,
+                         size_t size)
+{
+  errno = EINVAL;
+  return -1;
 }
 
 static struct dirent *
@@ -2765,14 +2818,13 @@ android_content_initial (char *name, size_t length)
 /* Return the content URI corresponding to a `/content/by-authority'
    file name, or NULL if it is invalid for some reason.  FILENAME
    should be relative to /content/by-authority, with no leading
-   directory separator character.
+   directory separator character.  */
 
-   This function is not reentrant.  */
-
-static const char *
+static char *
 android_get_content_name (const char *filename)
 {
-  static char buffer[PATH_MAX + 1], *fill;
+  char *fill, *buffer;
+  size_t length;
 
   /* Make sure FILENAME isn't obviously invalid: it must contain an
      authority name and a file name component.  */
@@ -2784,48 +2836,50 @@ android_get_content_name (const char *filename)
       return NULL;
     }
 
-  /* FILENAME must also not be a directory.  */
+  /* FILENAME must also not be a directory.  Accessing content
+     provider directories is not supported by this interface.  */
 
-  if (filename[strlen (filename)] == '/')
+  length = strlen (filename);
+  if (filename[length] == '/')
     {
       errno = ENOTDIR;
       return NULL;
     }
 
-  snprintf (buffer, PATH_MAX + 1, "content://%s", filename);
+  /* Prefix FILENAME with content:// and return the buffer containing
+     that URI.  */
+
+  buffer = xmalloc (sizeof "content://" + length);
+  sprintf (buffer, "content://%s", filename);
   return buffer;
 }
 
 /* Return whether or not the specified URI is an accessible content
-   URI.  MODE specifies what to check.  */
+   URI.  MODE specifies what to check.
+
+   URI must be a string in the JVM's extended UTF-8 format.  */
 
 static bool
 android_check_content_access (const char *uri, int mode)
 {
   jobject string;
-  size_t length;
-  jboolean rc;
-
-  length = strlen (uri);
+  jboolean rc, read, write;
 
-  string = (*android_java_env)->NewByteArray (android_java_env,
-                                             length);
+  string = (*android_java_env)->NewStringUTF (android_java_env, uri);
   android_exception_check ();
 
-  (*android_java_env)->SetByteArrayRegion (android_java_env,
-                                          string, 0, length,
-                                          (jbyte *) uri);
+  /* Establish what is being checked.  Checking for read access is
+     identical to checking if the file exists.  */
+
+  read = (bool) (mode & R_OK || (mode == F_OK));
+  write = (bool) (mode & W_OK);
+
   rc = (*android_java_env)->CallBooleanMethod (android_java_env,
                                               emacs_service,
                                               service_class.check_content_uri,
-                                              string,
-                                              (jboolean) ((mode & R_OK)
-                                                          != 0),
-                                              (jboolean) ((mode & W_OK)
-                                                          != 0));
+                                              string, read, write);
   android_exception_check_1 (string);
   ANDROID_DELETE_LOCAL_REF (string);
-
   return rc;
 }
 
@@ -2864,6 +2918,8 @@ static int android_authority_stat (struct android_vnode 
*, struct stat *);
 static int android_authority_access (struct android_vnode *, int);
 static int android_authority_mkdir (struct android_vnode *, mode_t);
 static int android_authority_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_authority_readlink (struct android_vnode *, char *,
+                                          size_t);
 static struct android_vdir *android_authority_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with the content VFS node.  */
@@ -2881,6 +2937,7 @@ static struct android_vops authority_vfs_ops =
     android_authority_access,
     android_authority_mkdir,
     android_authority_chmod,
+    android_authority_readlink,
     android_authority_opendir,
   };
 
@@ -2889,7 +2946,7 @@ android_authority_name (struct android_vnode *vnode, char 
*name,
                        size_t length)
 {
   struct android_authority_vnode *vp;
-  const char *uri_name;
+  char *uri_name;
 
   if (!android_init_gui)
     {
@@ -2922,6 +2979,12 @@ android_authority_name (struct android_vnode *vnode, 
char *name,
       if (*name == '/')
        name++, length -= 1;
 
+      /* NAME must be a valid JNI string, so that it can be encoded
+        properly.  */
+
+      if (android_verify_jni_string (name))
+       goto no_entry;
+
       uri_name = android_get_content_name (name);
       if (!uri_name)
        goto error;
@@ -2931,11 +2994,12 @@ android_authority_name (struct android_vnode *vnode, 
char *name,
       vp->vnode.ops = &authority_vfs_ops;
       vp->vnode.type = ANDROID_VNODE_CONTENT_AUTHORITY;
       vp->vnode.flags = 0;
-      vp->uri = xstrdup (uri_name);
+      vp->uri = uri_name;
       return &vp->vnode;
     }
 
   /* Content files can't have children.  */
+ no_entry:
   errno = ENOENT;
  error:
   return NULL;
@@ -3168,6 +3232,14 @@ android_authority_chmod (struct android_vnode *vnode, 
mode_t mode,
   return -1;
 }
 
+static ssize_t
+android_authority_readlink (struct android_vnode *vnode, char *buffer,
+                           size_t size)
+{
+  errno = EINVAL;
+  return -1;
+}
+
 static struct android_vdir *
 android_authority_opendir (struct android_vnode *vnode)
 {
@@ -3274,6 +3346,8 @@ static int android_saf_root_stat (struct android_vnode *, 
struct stat *);
 static int android_saf_root_access (struct android_vnode *, int);
 static int android_saf_root_mkdir (struct android_vnode *, mode_t);
 static int android_saf_root_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_saf_root_readlink (struct android_vnode *, char *,
+                                         size_t);
 static struct android_vdir *android_saf_root_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with the SAF root VFS node.  */
@@ -3291,6 +3365,7 @@ static struct android_vops saf_root_vfs_ops =
     android_saf_root_access,
     android_saf_root_mkdir,
     android_saf_root_chmod,
+    android_saf_root_readlink,
     android_saf_root_opendir,
   };
 
@@ -3577,6 +3652,14 @@ android_saf_root_chmod (struct android_vnode *vnode, 
mode_t mode,
   return -1;
 }
 
+static ssize_t
+android_saf_root_readlink (struct android_vnode *vnode, char *buffer,
+                          size_t size)
+{
+  errno = EINVAL;
+  return -1;
+}
+
 static struct dirent *
 android_saf_root_readdir (struct android_vdir *vdir)
 {
@@ -3932,12 +4015,15 @@ android_saf_exception_check (int n, ...)
 /* Return file status for the document designated by ID_NAME within
    the document tree identified by URI_NAME.
 
+   If NO_CACHE, don't cache the resulting file status.  Enable this
+   option if the file status is subject to imminent change.
+
    If the file status is available, place it within *STATB and return
    0.  If not, return -1 and set errno to EPERM.  */
 
 static int
 android_saf_stat (const char *uri_name, const char *id_name,
-                 struct stat *statb)
+                 struct stat *statb, bool no_cache)
 {
   jmethodID method;
   jstring uri, id;
@@ -3969,10 +4055,12 @@ android_saf_stat (const char *uri_name, const char 
*id_name,
   /* Try to retrieve the file status.  */
   method = service_class.stat_document;
   inside_saf_critical_section = true;
-  status = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env,
-                                                           emacs_service,
-                                                           service_class.class,
-                                                           method, uri, id);
+  status
+    = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env,
+                                                      emacs_service,
+                                                      service_class.class,
+                                                      method, uri, id,
+                                                      (jboolean) no_cache);
   inside_saf_critical_section = false;
 
   /* Check for exceptions and release unneeded local references.  */
@@ -4013,6 +4101,7 @@ android_saf_stat (const char *uri_name, const char 
*id_name,
   memset (statb, 0, sizeof *statb);
   statb->st_size = MAX (0, MIN (TYPE_MAXIMUM (off_t), size));
   statb->st_mode = mode;
+  statb->st_dev = -4;
 #ifdef STAT_TIMESPEC
   STAT_TIMESPEC (statb, st_mtim).tv_sec = mtim / 1000;
   STAT_TIMESPEC (statb, st_mtim).tv_nsec = (mtim % 1000) * 1000000;
@@ -4412,6 +4501,8 @@ static int android_saf_tree_stat (struct android_vnode *, 
struct stat *);
 static int android_saf_tree_access (struct android_vnode *, int);
 static int android_saf_tree_mkdir (struct android_vnode *, mode_t);
 static int android_saf_tree_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_saf_tree_readlink (struct android_vnode *, char *,
+                                         size_t);
 static struct android_vdir *android_saf_tree_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with SAF tree VFS nodes.  */
@@ -4429,6 +4520,7 @@ static struct android_vops saf_tree_vfs_ops =
     android_saf_tree_access,
     android_saf_tree_mkdir,
     android_saf_tree_chmod,
+    android_saf_tree_readlink,
     android_saf_tree_opendir,
   };
 
@@ -5075,7 +5167,7 @@ android_saf_tree_stat (struct android_vnode *vnode,
   vp = (struct android_saf_tree_vnode *) vnode;
 
   return android_saf_stat (vp->tree_uri, vp->document_id,
-                          statb);
+                          statb, false);
 }
 
 static int
@@ -5124,6 +5216,16 @@ android_saf_tree_chmod (struct android_vnode *vnode, 
mode_t mode,
   return 0;
 }
 
+static ssize_t
+android_saf_tree_readlink (struct android_vnode *vnode, char *buffer,
+                          size_t size)
+{
+  /* Return EINVAL.  Symlinks aren't exposed to clients by the
+     SAF.  */
+  errno = EINVAL;
+  return -1;
+}
+
 /* Open a database Cursor containing each directory entry within the
    supplied SAF tree vnode VP.
 
@@ -5548,6 +5650,7 @@ static struct android_vops saf_file_vfs_ops =
     android_saf_tree_access,
     android_saf_tree_mkdir,
     android_saf_tree_chmod,
+    android_saf_tree_readlink,
     android_saf_file_opendir,
   };
 
@@ -5590,7 +5693,7 @@ android_saf_file_open (struct android_vnode *vnode, int 
flags,
   struct android_saf_file_vnode *vp;
   jobject uri, id, descriptor;
   jmethodID method;
-  jboolean trunc, write;
+  jboolean read, trunc, write;
   jint fd;
   struct android_parcel_fd *info;
   struct stat statb;
@@ -5601,6 +5704,15 @@ android_saf_file_open (struct android_vnode *vnode, int 
flags,
       return -1;
     }
 
+  /* O_APPEND isn't supported as a consequence of Android content
+     providers defaulting to truncating the file.  */
+
+  if (flags & O_APPEND)
+    {
+      errno = EOPNOTSUPP;
+      return -1;
+    }
+
   /* Build strings for both the URI and ID.  */
 
   vp = (struct android_saf_file_vnode *) vnode;
@@ -5611,18 +5723,45 @@ android_saf_file_open (struct android_vnode *vnode, int 
flags,
                                          vp->document_id);
   android_exception_check_1 (uri);
 
-  /* Open a parcel file descriptor according to flags.  */
+  /* Open a parcel file descriptor according to flags.  Documentation
+     for the SAF openDocument operation is scant and seldom helpful.
+     From observations made, it is clear that their file access modes
+     are inconsistently implemented, and that at least:
+
+       r   = either an FIFO or a real file, without truncation.
+       w   = either an FIFO or a real file, with OR without truncation.
+       wt  = either an FIFO or a real file, with truncation.
+       rw  = a real file, without truncation.
+       rwt = a real file, with truncation.
+
+     This diverges from the self-contradicting documentation, where
+     openDocument says nothing about truncation, and openFile mentions
+     that w can elect not to truncate and programs which rely on
+     truncation should use wt.
+
+     Since Emacs is prepared to handle FIFOs within fileio.c, simply
+     specify the straightforward relationship between FLAGS and the
+     file access modes listed above.  */
 
   method = service_class.open_document;
-  trunc  = (flags & O_TRUNC);
-  write  = (((flags & O_RDWR) == O_RDWR) || (flags & O_WRONLY));
+  read = trunc = write = false;
+
+  if ((flags & O_RDWR) == O_RDWR || (flags & O_WRONLY))
+    write = true;
+
+  if (flags & O_TRUNC)
+    trunc = true;
+
+  if ((flags & O_RDWR) == O_RDWR || !write)
+    read = true;
+
   inside_saf_critical_section = true;
   descriptor
     = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env,
                                                       emacs_service,
                                                       service_class.class,
                                                       method, uri, id,
-                                                      write, trunc);
+                                                      read, write, trunc);
   inside_saf_critical_section = false;
 
   if (android_saf_exception_check (2, uri, id))
@@ -5679,10 +5818,15 @@ android_saf_file_open (struct android_vnode *vnode, int 
flags,
   ANDROID_DELETE_LOCAL_REF (descriptor);
 
   /* Try to retrieve the modification time of this file from the
-     content provider.  */
+     content provider.
+
+     Refrain from introducing the file status into the file status
+     cache if FLAGS & O_RDWR or FLAGS & O_WRONLY: the cached file
+     status will contain a size and modification time inconsistent
+     with the result of any modifications that later transpire.  */
 
   if (!android_saf_stat (vp->tree_uri, vp->document_id,
-                        &statb))
+                        &statb, write))
     info->mtime = get_stat_mtime (&statb);
   else
     info->mtime = invalid_timespec ();
@@ -5787,6 +5931,8 @@ static int android_saf_new_stat (struct android_vnode *, 
struct stat *);
 static int android_saf_new_access (struct android_vnode *, int);
 static int android_saf_new_mkdir (struct android_vnode *, mode_t);
 static int android_saf_new_chmod (struct android_vnode *, mode_t, int);
+static ssize_t android_saf_new_readlink (struct android_vnode *, char *,
+                                        size_t);
 static struct android_vdir *android_saf_new_opendir (struct android_vnode *);
 
 /* Vector of VFS operations associated with SAF new VFS nodes.  */
@@ -5804,6 +5950,7 @@ static struct android_vops saf_new_vfs_ops =
     android_saf_new_access,
     android_saf_new_mkdir,
     android_saf_new_chmod,
+    android_saf_new_readlink,
     android_saf_new_opendir,
   };
 
@@ -6073,6 +6220,14 @@ android_saf_new_chmod (struct android_vnode *vnode, 
mode_t mode,
   return -1;
 }
 
+static ssize_t
+android_saf_new_readlink (struct android_vnode *vnode, char *buffer,
+                         size_t size)
+{
+  errno = ENOENT;
+  return -1;
+}
+
 static struct android_vdir *
 android_saf_new_opendir (struct android_vnode *vnode)
 {
@@ -6133,7 +6288,14 @@ NATIVE_NAME (safPostRequest) (JNIEnv *env, jobject 
object)
 JNIEXPORT jboolean JNICALL
 NATIVE_NAME (ftruncate) (JNIEnv *env, jobject object, jint fd)
 {
-  return ftruncate (fd, 0) != -1;
+  if (ftruncate (fd, 0) < 0)
+    return false;
+
+  /* Reset the file pointer.  */
+  if (lseek (fd, 0, SEEK_SET) < 0)
+    return false;
+
+  return true;
 }
 
 #ifdef __clang__
@@ -6167,6 +6329,7 @@ static struct android_vops root_vfs_ops =
     android_unix_access,
     android_unix_mkdir,
     android_unix_chmod,
+    android_unix_readlink,
     android_unix_opendir,
   };
 
@@ -6448,6 +6611,8 @@ android_vfs_init (JNIEnv *env, jobject manager)
    vnodes may not be reentrant, but operating on them from within an
    async input handler will at worst cause an error to be returned.
 
+   The eight is that some vnode types do not support O_APPEND.
+
    And the final drawback is that directories cannot be directly
    opened.  Instead, `dirfd' must be called on a directory stream used
    by `openat'.
@@ -6684,6 +6849,11 @@ android_fstat (int fd, struct stat *statb)
   parcel_fd = open_parcel_fds;
   for (; parcel_fd; parcel_fd = parcel_fd->next)
     {
+      if (parcel_fd->fd == fd)
+       /* Set STATB->st_dev to a negative device number, signifying
+          that it's contained within a content provider.  */
+       statb->st_dev = -4;
+
       if (parcel_fd->fd == fd
          && timespec_valid_p (parcel_fd->mtime))
        {
@@ -6893,6 +7063,42 @@ android_fchmodat (int dirfd, const char *pathname, 
mode_t mode,
   return rc;
 }
 
+/* Like `android_fstatat', but return the target of any symbolic link
+   at PATHNAME instead of checking file status.  */
+
+ssize_t
+android_readlinkat (int dirfd, const char *restrict pathname,
+                   char *restrict buf, size_t bufsiz)
+{
+  char buffer[PATH_MAX + 1];
+  struct android_vnode *vp;
+  ssize_t rc;
+
+  if (dirfd == AT_FDCWD || pathname[0] == '/')
+    goto vfs;
+
+  /* Now establish whether DIRFD is a file descriptor corresponding to
+     an open VFS directory stream.  */
+
+  if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1))
+    {
+      pathname = buffer;
+      goto vfs;
+    }
+
+  /* Fall back to readlinkat.  */
+  return readlinkat (dirfd, pathname, buf, bufsiz);
+
+ vfs:
+  vp = android_name_file (pathname);
+  if (!vp)
+    return -1;
+
+  rc = (*vp->ops->readlink) (vp, buf, bufsiz);
+  (*vp->ops->close) (vp);
+  return rc;
+}
+
 /* Like `fdopen', but if FD is a parcel file descriptor, ``detach'' it
    from the original.
 
diff --git a/src/callproc.c b/src/callproc.c
index 0645c2c3e18..dc37dfdc01f 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -170,10 +170,11 @@ get_current_directory (bool encode)
   /* If DIR is an asset directory or a content directory, return
      the home directory instead.  */
 
-  if (encode && (!strcmp (SSDATA (dir), "/assets")
-                || !strncmp (SSDATA (dir), "/assets/", 8)
-                || !strcmp (SSDATA (dir), "/content")
-                || !strncmp (SSDATA (dir), "/content/", 9)))
+  if (encode
+      && (android_is_special_directory (SSDATA (dir),
+                                       "/assets")
+         || android_is_special_directory (SSDATA (dir),
+                                          "/content")))
     dir = build_string ("~");
 
 #endif /* HAVE_ANDROID && ANDROID_STUBIFY */
diff --git a/src/data.c b/src/data.c
index 71e52e727b7..06b114afd0c 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2222,17 +2222,18 @@ Instead, use `add-hook' and specify t for the LOCAL 
argument.  */)
   if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
     xsignal1 (Qsetting_constant, variable);
 
-  if (blv ? blv->local_if_set
-      : (forwarded && BUFFER_OBJFWDP (valcontents.fwd)))
-    {
-      tem = Fboundp (variable);
-      /* Make sure the symbol has a local value in this particular buffer,
-        by setting it to the same value it already has.  */
-      Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound));
-      return variable;
-    }
   if (!blv)
     {
+      if (forwarded && BUFFER_OBJFWDP (valcontents.fwd))
+        {
+          int offset = XBUFFER_OBJFWD (valcontents.fwd)->offset;
+          int idx = PER_BUFFER_IDX (offset);
+          eassert (idx);
+          if (idx > 0)
+            /* If idx < 0, it's always buffer local, like `mode-name`.  */
+            SET_PER_BUFFER_VALUE_P (current_buffer, idx, true);
+          return variable;
+        }
       blv = make_blv (sym, forwarded, valcontents);
       sym->u.s.redirect = SYMBOL_LOCALIZED;
       SET_SYMBOL_BLV (sym, blv);
diff --git a/src/editfns.c b/src/editfns.c
index 5d32fd31c12..1b739128a20 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2691,7 +2691,7 @@ DEFUN ("delete-and-extract-region", 
Fdelete_and_extract_region,
    labeled restriction was entered (which may be a narrowing that was
    set by the user and is visible on display).  This alist is used
    internally by narrow-to-region, internal--labeled-narrow-to-region,
-   widen, internal--unlabel-restriction and save-restriction.  For
+   widen, internal--labeled-widen and save-restriction.  For
    efficiency reasons, an alist is used instead of a buffer-local
    variable: otherwise reset_outermost_restrictions, which is called
    during each redisplay cycle, would have to loop through all live
@@ -2867,8 +2867,7 @@ labeled_restrictions_restore (Lisp_Object 
buf_and_restrictions)
 static void
 unwind_labeled_narrow_to_region (Lisp_Object label)
 {
-  Finternal__unlabel_restriction (label);
-  Fwiden ();
+  Finternal__labeled_widen (label);
 }
 
 /* Narrow current_buffer to BEGV-ZV with a restriction labeled with
@@ -2991,7 +2990,7 @@ argument.  To gain access to other portions of the 
buffer, use
 
 DEFUN ("internal--labeled-narrow-to-region", 
Finternal__labeled_narrow_to_region,
        Sinternal__labeled_narrow_to_region, 3, 3, 0,
-       doc: /* Restrict editing in this buffer to START-END, and label the 
restriction with LABEL.
+       doc: /* Restrict this buffer to START-END, and label the restriction 
with LABEL.
 
 This is an internal function used by `with-restriction'.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object label)
@@ -3009,9 +3008,9 @@ This is an internal function used by `with-restriction'.  
*/)
   return Qnil;
 }
 
-DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction,
-       Sinternal__unlabel_restriction, 1, 1, 0,
-       doc: /* If the current restriction is labeled with LABEL, remove its 
label.
+DEFUN ("internal--labeled-widen", Finternal__labeled_widen,
+       Sinternal__labeled_widen, 1, 1, 0,
+       doc: /* Remove the current restriction if it is labeled with LABEL, and 
widen.
 
 This is an internal function used by `without-restriction'.  */)
   (Lisp_Object label)
@@ -3019,6 +3018,7 @@ This is an internal function used by 
`without-restriction'.  */)
   Lisp_Object buf = Fcurrent_buffer ();
   if (EQ (labeled_restrictions_peek_label (buf), label))
     labeled_restrictions_pop (buf);
+  Fwiden ();
   return Qnil;
 }
 
@@ -4958,7 +4958,7 @@ it to be non-nil.  */);
   defsubr (&Swiden);
   defsubr (&Snarrow_to_region);
   defsubr (&Sinternal__labeled_narrow_to_region);
-  defsubr (&Sinternal__unlabel_restriction);
+  defsubr (&Sinternal__labeled_widen);
   defsubr (&Ssave_restriction);
   defsubr (&Stranspose_regions);
 }
diff --git a/src/emacs.c b/src/emacs.c
index 796ff294042..de553f31980 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2081,15 +2081,16 @@ Using an Emacs configured with --with-x-toolkit=lucid 
does not have this problem
     }
 #endif /* HAVE_NS */
 
-#ifdef HAVE_X_WINDOWS
   /* Stupid kludge to catch command-line display spec.  We can't
      handle this argument entirely in window system dependent code
      because we don't even know which window system dependent code
      to run until we've recognized this argument.  */
   {
-    char *displayname = 0;
     int count_before = skip_args;
 
+#ifdef HAVE_X_WINDOWS
+    char *displayname = 0;
+
     /* Skip any number of -d options, but only use the last one.  */
     while (!only_version)
       {
@@ -2119,12 +2120,15 @@ Using an Emacs configured with --with-x-toolkit=lucid 
does not have this problem
          }
        argv[count_before + 1] = (char *) "-d";
       }
+#endif /* HAVE_X_WINDOWS */
 
     if (! no_site_lisp)
       {
-        if (argmatch (argv, argc, "-Q", "--quick", 3, NULL, &skip_args)
+
+       if (argmatch (argv, argc, "-Q", "--quick", 3, NULL, &skip_args)
             || argmatch (argv, argc, "-quick", 0, 2, NULL, &skip_args))
-          no_site_lisp = 1;
+         no_site_lisp = 1;
+
       }
 
     if (argmatch (argv, argc, "-x", 0, 1, &junk, &skip_args))
@@ -2140,18 +2144,6 @@ Using an Emacs configured with --with-x-toolkit=lucid 
does not have this problem
     /* Don't actually discard this arg.  */
     skip_args = count_before;
   }
-#else  /* !HAVE_X_WINDOWS */
-  if (! no_site_lisp)
-  {
-    int count_before = skip_args;
-
-    if (argmatch (argv, argc, "-Q", "--quick", 3, NULL, &skip_args)
-        || argmatch (argv, argc, "-quick", 0, 2, NULL, &skip_args))
-      no_site_lisp = 1;
-
-    skip_args = count_before;
-  }
-#endif
 
   /* argmatch must not be used after here,
      except when building temacs
diff --git a/src/eval.c b/src/eval.c
index 9e54d489a3b..9268b65aa85 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4296,6 +4296,10 @@ See also the variable `debug-on-quit' and 
`inhibit-debugger'.  */);
 Each element may be a condition-name or a regexp that matches error messages.
 If any element applies to a given error, that error skips the debugger
 and just returns to top level.
+If you invoke Emacs with --debug-init, and want to remove some
+elements from the default value of this variable, use `setq' to
+change the value of the variable to a new list, rather than `delq'
+to remove some errors from the list.
 This overrides the variable `debug-on-error'.
 It does not apply to errors handled by `condition-case'.  */);
   Vdebug_ignored_errors = Qnil;
diff --git a/src/fileio.c b/src/fileio.c
index b5c3add836e..51e3e8849d1 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -200,6 +200,25 @@ check_vfs_filename (Lisp_Object encoded, const char 
*reason)
 #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
 }
 
+#ifdef HAVE_LIBSELINUX
+
+/* Return whether SELinux is enabled and pertinent to FILE.  Provide
+   for cases where FILE is or is a constitutent of a special
+   directory, such as /assets or /content on Android.  */
+
+static bool
+selinux_enabled_p (const char *file)
+{
+  return (is_selinux_enabled ()
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+         && !android_is_special_directory (file, "/assets")
+         && !android_is_special_directory (file, "/content")
+#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
+         );
+}
+
+#endif /* HAVE_LIBSELINUX */
+
 
 /* Test whether FILE is accessible for AMODE.
    Return true if successful, false (setting errno) otherwise.  */
@@ -824,10 +843,10 @@ For that reason, you should normally use `make-temp-file' 
instead.  */)
 
 DEFUN ("file-name-concat", Ffile_name_concat, Sfile_name_concat, 1, MANY, 0,
        doc: /* Append COMPONENTS to DIRECTORY and return the resulting string.
-Elements in COMPONENTS must be a string or nil.
+Each element in COMPONENTS must be a string or nil.
 DIRECTORY or the non-final elements in COMPONENTS may or may not end
 with a slash -- if they don't end with a slash, a slash will be
-inserted before contatenating.
+inserted before concatenating.
 usage: (record DIRECTORY &rest COMPONENTS) */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
@@ -2311,7 +2330,10 @@ permissions.  */)
   if (!NILP (preserve_permissions))
     {
 #if HAVE_LIBSELINUX
-      if (is_selinux_enabled ()
+      if (selinux_enabled_p (SSDATA (encoded_file))
+         /* Eschew copying SELinux contexts if they're inapplicable
+            to the destination file.  */
+         && selinux_enabled_p (SSDATA (encoded_newname))
          && emacs_fd_to_int (ifd) != -1)
        {
          conlength = fgetfilecon (emacs_fd_to_int (ifd),
@@ -2319,7 +2341,7 @@ permissions.  */)
          if (conlength == -1)
            report_file_error ("Doing fgetfilecon", file);
        }
-#endif
+#endif /* HAVE_LIBSELINUX */
     }
 
   /* We can copy only regular files.  */
@@ -2474,11 +2496,18 @@ permissions.  */)
     {
       /* Set the modified context back to the file.  */
       bool fail = fsetfilecon (ofd, con) != 0;
+      freecon (con);
+
       /* See https://debbugs.gnu.org/11245 for ENOTSUP.  */
-      if (fail && errno != ENOTSUP)
+      if (fail
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+         /* Treat SELinux errors copying files leniently on Android,
+            since the system usually forbids user programs from
+            changing file contexts.  */
+         && errno != EACCES
+#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
+         && errno != ENOTSUP)
        report_file_error ("Doing fsetfilecon", newname);
-
-      freecon (con);
     }
 #endif
 
@@ -2573,6 +2602,7 @@ If file has multiple names, it continues to exist with 
the other names. */)
 {
   Lisp_Object encoded_file;
 
+  CHECK_STRING (filename);
   filename = Fexpand_file_name (filename, Qnil);
   encoded_file = ENCODE_FILE (filename);
 
@@ -3070,15 +3100,29 @@ If there is no error, returns nil.  */)
 
 /* Relative to directory FD, return the symbolic link value of FILENAME.
    On failure, return nil (setting errno).  */
+
 static Lisp_Object
 emacs_readlinkat (int fd, char const *filename)
 {
-  static struct allocator const emacs_norealloc_allocator =
-    { xmalloc, NULL, xfree, memory_full };
+  static struct allocator const emacs_norealloc_allocator = {
+    xmalloc,
+    NULL,
+    xfree,
+    memory_full,
+  };
+
   Lisp_Object val;
   char readlink_buf[1024];
-  char *buf = careadlinkat (fd, filename, readlink_buf, sizeof readlink_buf,
-                           &emacs_norealloc_allocator, readlinkat);
+  char *buf;
+
+  buf = careadlinkat (fd, filename, readlink_buf, sizeof readlink_buf,
+                     &emacs_norealloc_allocator,
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+                     android_readlinkat
+#else /* !HAVE_ANDROID || ANDROID_STUBIFY */
+                     readlinkat
+#endif /* HAVE_ANDROID && !ANDROID_STUBIFY */
+                     );
   if (!buf)
     return Qnil;
 
@@ -3353,6 +3397,9 @@ or if SELinux is disabled, or if Emacs lacks SELinux 
support.  */)
 {
   Lisp_Object user = Qnil, role = Qnil, type = Qnil, range = Qnil;
   Lisp_Object absname = expand_and_dir_to_file (filename);
+#ifdef HAVE_LIBSELINUX
+  const char *file;
+#endif /* HAVE_LIBSELINUX */
 
   /* If the file name has special constructs in it,
      call the corresponding file name handler.  */
@@ -3361,11 +3408,13 @@ or if SELinux is disabled, or if Emacs lacks SELinux 
support.  */)
   if (!NILP (handler))
     return call2 (handler, Qfile_selinux_context, absname);
 
-#if HAVE_LIBSELINUX
-  if (is_selinux_enabled ())
+#ifdef HAVE_LIBSELINUX
+  file = SSDATA (ENCODE_FILE (absname));
+
+  if (selinux_enabled_p (file))
     {
       char *con;
-      int conlength = lgetfilecon (SSDATA (ENCODE_FILE (absname)), &con);
+      int conlength = lgetfilecon (file, &con);
       if (conlength > 0)
        {
          context_t context = context_new (con);
@@ -3384,7 +3433,7 @@ or if SELinux is disabled, or if Emacs lacks SELinux 
support.  */)
                  || errno == ENOTSUP))
        report_file_error ("getting SELinux context", absname);
     }
-#endif
+#endif /* HAVE_LIBSELINUX */
 
   return list4 (user, role, type, range);
 }
@@ -3410,10 +3459,11 @@ or if Emacs was not compiled with SELinux support.  */)
   Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context)));
   Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context))));
   char *con;
+  const char *name;
   bool fail;
   int conlength;
   context_t parsed_con;
-#endif
+#endif /* HAVE_LIBSELINUX */
 
   absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
 
@@ -3424,11 +3474,13 @@ or if Emacs was not compiled with SELinux support.  */)
     return call3 (handler, Qset_file_selinux_context, absname, context);
 
 #if HAVE_LIBSELINUX
-  if (is_selinux_enabled ())
+  encoded_absname = ENCODE_FILE (absname);
+  name = SSDATA (encoded_absname);
+
+  if (selinux_enabled_p (name))
     {
       /* Get current file context. */
-      encoded_absname = ENCODE_FILE (absname);
-      conlength = lgetfilecon (SSDATA (encoded_absname), &con);
+      conlength = lgetfilecon (name, &con);
       if (conlength > 0)
        {
          parsed_con = context_new (con);
@@ -3458,18 +3510,18 @@ or if Emacs was not compiled with SELinux support.  */)
          fail = (lsetfilecon (SSDATA (encoded_absname),
                               context_str (parsed_con))
                  != 0);
+         context_free (parsed_con);
+         freecon (con);
+
           /* See https://debbugs.gnu.org/11245 for ENOTSUP.  */
          if (fail && errno != ENOTSUP)
            report_file_error ("Doing lsetfilecon", absname);
-
-         context_free (parsed_con);
-         freecon (con);
          return fail ? Qnil : Qt;
        }
       else
        report_file_error ("Doing lgetfilecon", absname);
     }
-#endif
+#endif /* HAVE_LIBSELINUX */
 
   return Qnil;
 }
@@ -3565,10 +3617,10 @@ support.  */)
       fail = (acl_set_file (SSDATA (encoded_absname), ACL_TYPE_ACCESS,
                            acl)
              != 0);
+      acl_free (acl);
       if (fail && acl_errno_valid (errno))
        report_file_error ("Setting ACL", absname);
 
-      acl_free (acl);
       return fail ? Qnil : Qt;
     }
 # endif
@@ -3860,11 +3912,12 @@ static Lisp_Object
 read_non_regular (Lisp_Object state)
 {
   union read_non_regular *data = XFIXNUMPTR (state);
-  int nbytes = emacs_fd_read (data->s.fd,
-                             ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
-                              + data->s.inserted),
-                             data->s.trytry);
-  return make_fixnum (nbytes);
+  intmax_t nbytes
+    = emacs_fd_read (data->s.fd,
+                    ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
+                     + data->s.inserted),
+                    data->s.trytry);
+  return make_int (nbytes);
 }
 
 
@@ -3992,15 +4045,22 @@ characters in the buffer.  If VISIT is non-nil, BEG and 
END must be nil.
 
 When inserting data from a special file (e.g., /dev/urandom), you
 can't specify VISIT or BEG, and END should be specified to avoid
-inserting unlimited data into the buffer.
-
-If optional fifth argument REPLACE is non-nil, replace the current
-buffer contents (in the accessible portion) with the file contents.
-This is better than simply deleting and inserting the whole thing
-because (1) it preserves some marker positions (in unchanged portions
-at the start and end of the buffer) and (2) it puts less data in the
-undo list.  When REPLACE is non-nil, the second return value is the
-number of characters that replace previous buffer contents.
+inserting unlimited data into the buffer from some special files
+which otherwise could supply infinite amounts of data.
+
+If optional fifth argument REPLACE is non-nil and FILENAME names a
+regular file, replace the current buffer contents (in the accessible
+portion) with the file's contents.  This is better than simply
+deleting and inserting the whole thing because (1) it preserves some
+marker positions (in unchanged portions at the start and end of the
+buffer) and (2) it puts less data in the undo list.  When REPLACE is
+non-nil, the second element of the return value is the number of
+characters that replace the previous buffer contents.
+
+If FILENAME is not a regular file and REPLACE is `if-regular', erase
+the accessible portion of the buffer and insert the new contents.  Any
+other non-nil value of REPLACE will signal an error if FILENAME is not
+a regular file.
 
 This function does code conversion according to the value of
 `coding-system-for-read' or `file-coding-system-alist', and sets the
@@ -4008,7 +4068,8 @@ variable `last-coding-system-used' to the coding system 
actually used.
 
 In addition, this function decodes the inserted text from known formats
 by calling `format-decode', which see.  */)
-  (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, 
Lisp_Object replace)
+  (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end,
+   Lisp_Object replace)
 {
   struct stat st;
   struct timespec mtime;
@@ -4123,28 +4184,38 @@ by calling `format-decode', which see.  */)
     report_file_error ("Input file status", orig_filename);
   mtime = get_stat_mtime (&st);
 
-  /* This code will need to be changed in order to work on named
-     pipes, and it's probably just not worth it.  So we should at
-     least signal an error.  */
+  /* The REPLACE code will need to be changed in order to work on
+     named pipes, and it's probably just not worth it.  So we should
+     at least signal an error.  */
+
   if (!S_ISREG (st.st_mode))
     {
       regular = false;
 
-      if (! NILP (visit))
-        {
-          eassert (inserted == 0);
-         goto notfound;
-        }
-
       if (!NILP (replace))
-       xsignal2 (Qfile_error,
-                 build_string ("not a regular file"), orig_filename);
+       {
+         if (!EQ (replace, Qif_regular))
+           xsignal2 (Qfile_error,
+                     build_string ("not a regular file"), orig_filename);
+         else
+           /* Set REPLACE to Qunbound, indicating that we are trying
+              to replace the buffer contents with that of a
+              non-regular file.  */
+           replace = Qunbound;
+       }
+
+      /* Forbid specifying BEG together with a special file, as per
+        the doc string.  */
 
-      seekable = emacs_fd_lseek (fd, 0, SEEK_CUR) < 0;
-      if (!NILP (beg) && !seekable)
+      if (!NILP (beg))
        xsignal2 (Qfile_error,
                  build_string ("cannot use a start position in a non-seekable 
file/device"),
                  orig_filename);
+
+      /* Now ascertain if this file is seekable, by detecting if
+        seeking leads to -1 being returned.  */
+      seekable
+       = emacs_fd_lseek (fd, 0, SEEK_CUR) != (off_t) -1;
     }
 
   if (end_offset < 0)
@@ -4316,7 +4387,8 @@ by calling `format-decode', which see.  */)
      method and hope for the best.
      But if we discover the need for conversion, we give up on this method
      and let the following if-statement handle the replace job.  */
-  if (!NILP (replace)
+  if ((!NILP (replace)
+       && !BASE_EQ (replace, Qunbound))
       && BEGV < ZV
       && (NILP (coding_system)
          || ! CODING_REQUIRE_DECODING (&coding)))
@@ -4503,7 +4575,9 @@ by calling `format-decode', which see.  */)
      is needed, in a simple way that needs a lot of memory.
      The preceding if-statement handles the case of no conversion
      in a more optimized way.  */
-  if (!NILP (replace) && ! replace_handled && BEGV < ZV)
+  if ((!NILP (replace)
+       && !BASE_EQ (replace, Qunbound))
+      && ! replace_handled && BEGV < ZV)
     {
       ptrdiff_t same_at_start_charpos;
       ptrdiff_t inserted_chars;
@@ -4688,6 +4762,13 @@ by calling `format-decode', which see.  */)
       prepare_to_modify_buffer (PT, PT, NULL);
     }
 
+  /* If REPLACE is Qunbound, buffer contents are being replaced with
+     text read from a FIFO or a device.  Erase the entire accessible
+     portion of the buffer.  */
+
+  if (BASE_EQ (replace, Qunbound))
+    del_range (BEGV, ZV);
+
   move_gap_both (PT, PT_BYTE);
 
   /* Ensure the gap is at least one byte larger than needed for the
@@ -4696,7 +4777,8 @@ by calling `format-decode', which see.  */)
   if (GAP_SIZE <= total)
     make_gap (total - GAP_SIZE + 1);
 
-  if (beg_offset != 0 || !NILP (replace))
+  if (beg_offset != 0 || (!NILP (replace)
+                         && !EQ (replace, Qunbound)))
     {
       if (emacs_fd_lseek (fd, beg_offset, SEEK_SET) < 0)
        report_file_error ("Setting file position", orig_filename);
@@ -4729,6 +4811,7 @@ by calling `format-decode', which see.  */)
        if (!seekable && NILP (end))
          {
            Lisp_Object nbytes;
+           intmax_t number;
 
            /* Read from the file, capturing `quit'.  When an
               error occurs, end the loop, and arrange for a quit
@@ -4744,18 +4827,20 @@ by calling `format-decode', which see.  */)
                break;
              }
 
-           this = XFIXNUM (nbytes);
+           if (!integer_to_intmax (nbytes, &number)
+               && number > PTRDIFF_MAX)
+             buffer_overflow ();
+
+           this = number;
          }
        else
-         {
-           /* Allow quitting out of the actual I/O.  We don't make text
-              part of the buffer until all the reading is done, so a C-g
-              here doesn't do any harm.  */
-           this = emacs_fd_read (fd,
-                                 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
-                                  + inserted),
-                                 trytry);
-         }
+         /* Allow quitting out of the actual I/O.  We don't make text
+            part of the buffer until all the reading is done, so a
+            C-g here doesn't do any harm.  */
+         this = emacs_fd_read (fd,
+                               ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
+                                + inserted),
+                               trytry);
 
        if (this <= 0)
          {
@@ -4940,9 +5025,14 @@ by calling `format-decode', which see.  */)
            Funlock_file (BVAR (current_buffer, file_truename));
          Funlock_file (filename);
        }
+
+#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
+      /* Under Android, modtime and st.st_size can be valid even if FD
+        is not a regular file.  */
       if (!regular)
        xsignal2 (Qfile_error,
                  build_string ("not a regular file"), orig_filename);
+#endif /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
     }
 
   if (set_coding_system)
@@ -5529,42 +5619,44 @@ write_region (Lisp_Object start, Lisp_Object end, 
Lisp_Object filename,
   if (timespec_valid_p (modtime)
       && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system))
     {
-      int desc1 = emacs_open (fn, O_WRONLY, 0);
-      if (desc1 >= 0)
+      struct stat st1;
+
+      /* The code below previously tried to open FN O_WRONLY,
+         subsequently calling fstat on the opened file descriptor.
+         This proved inefficient and resulted in FN being truncated
+         under several Android filesystems, and as such has been
+         changed to a call to `stat'.  */
+
+      if (emacs_fstatat (AT_FDCWD, fn, &st1, 0) == 0
+         && st.st_dev == st1.st_dev && st.st_ino == st1.st_ino)
        {
-         struct stat st1;
-         if (sys_fstat (desc1, &st1) == 0
-             && st.st_dev == st1.st_dev && st.st_ino == st1.st_ino)
+         /* Use the heuristic if it appears to be valid.  With neither
+            O_EXCL nor O_TRUNC, if Emacs happened to write nothing to the
+            file, the time stamp won't change.  Also, some non-POSIX
+            systems don't update an empty file's time stamp when
+            truncating it.  Finally, file systems with 100 ns or worse
+            resolution sometimes seem to have bugs: on a system with ns
+            resolution, checking ns % 100 incorrectly avoids the heuristic
+            1% of the time, but the problem should be temporary as we will
+            try again on the next time stamp.  */
+         bool use_heuristic
+           = ((open_flags & (O_EXCL | O_TRUNC)) != 0
+              && st.st_size != 0
+              && modtime.tv_nsec % 100 != 0);
+
+         struct timespec modtime1 = get_stat_mtime (&st1);
+         if (use_heuristic
+             && timespec_cmp (modtime, modtime1) == 0
+             && st.st_size == st1.st_size)
            {
-             /* Use the heuristic if it appears to be valid.  With neither
-                O_EXCL nor O_TRUNC, if Emacs happened to write nothing to the
-                file, the time stamp won't change.  Also, some non-POSIX
-                systems don't update an empty file's time stamp when
-                truncating it.  Finally, file systems with 100 ns or worse
-                resolution sometimes seem to have bugs: on a system with ns
-                resolution, checking ns % 100 incorrectly avoids the heuristic
-                1% of the time, but the problem should be temporary as we will
-                try again on the next time stamp.  */
-             bool use_heuristic
-               = ((open_flags & (O_EXCL | O_TRUNC)) != 0
-                  && st.st_size != 0
-                  && modtime.tv_nsec % 100 != 0);
-
-             struct timespec modtime1 = get_stat_mtime (&st1);
-             if (use_heuristic
-                 && timespec_cmp (modtime, modtime1) == 0
-                 && st.st_size == st1.st_size)
-               {
-                 timestamp_file_system = st.st_dev;
-                 valid_timestamp_file_system = 1;
-               }
-             else
-               {
-                 st.st_size = st1.st_size;
-                 modtime = modtime1;
-               }
+             timestamp_file_system = st.st_dev;
+             valid_timestamp_file_system = 1;
+           }
+         else
+           {
+             st.st_size = st1.st_size;
+             modtime = modtime1;
            }
-         emacs_close (desc1);
        }
     }
 
@@ -6737,9 +6829,6 @@ This includes interactive calls to `delete-file' and
   /* Lisp function for interactive file delete with trashing */
   DEFSYM (Qdelete_file, "delete-file");
 
-  /* Lisp function for moving files to trash.  */
-  DEFSYM (Qmove_file_to_trash, "move-file-to-trash");
-
   /* Lisp function for recursively copying directories.  */
   DEFSYM (Qcopy_directory, "copy-directory");
 
@@ -6810,9 +6899,11 @@ This includes interactive calls to `delete-file' and
 
 #ifndef DOS_NT
   defsubr (&Sfile_system_info);
-#endif
+#endif /* DOS_NT */
 
 #ifdef HAVE_SYNC
   defsubr (&Sunix_sync);
-#endif
+#endif /* HAVE_SYNC */
+
+  DEFSYM (Qif_regular, "if-regular");
 }
diff --git a/src/filelock.c b/src/filelock.c
index 66b8fd2ceac..c2b306ab47d 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -36,13 +36,9 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <sys/file.h>
 #include <fcntl.h>
 #include <unistd.h>
-
-#ifdef __FreeBSD__
-#include <sys/sysctl.h>
-#endif /* __FreeBSD__ */
-
 #include <errno.h>
 
+#include <boot-time.h>
 #include <c-ctype.h>
 
 #include "lisp.h"
@@ -55,26 +51,6 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #ifndef MSDOS
 
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-
-/* A file whose last-modified time is just after the most recent boot.
-   Define this to be NULL to disable checking for this file.  */
-#ifndef BOOT_TIME_FILE
-#define BOOT_TIME_FILE "/var/run/random-seed"
-#endif
-
-/* Boot time is not available on Android.  */
-
-#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
-#undef BOOT_TIME
-#endif
-
-#if !defined WTMP_FILE && !defined WINDOWSNT && defined BOOT_TIME
-#define WTMP_FILE "/var/log/wtmp"
-#endif
-
 #ifdef HAVE_ANDROID
 #include "android.h" /* For `android_is_special_directory'.  */
 #endif /* HAVE_ANDROID */
@@ -131,154 +107,22 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
      hard nor symbolic links.  */
 
 
-/* Return the time of the last system boot.  */
-
-static time_t boot_time;
-static bool boot_time_initialized;
-
-#ifdef BOOT_TIME
-static void get_boot_time_1 (const char *, bool);
-#endif
+/* Return the time of the last system boot, or 0 if that information
+   is unavailable.  */
 
 static time_t
-get_boot_time (void)
+get_boot_sec (void)
 {
-  if (boot_time_initialized)
-    return boot_time;
-  boot_time_initialized = 1;
-
-#if defined (CTL_KERN) && defined (KERN_BOOTTIME)
-  {
-    int mib[2];
-    size_t size;
-    struct timeval boottime_val;
-
-    mib[0] = CTL_KERN;
-    mib[1] = KERN_BOOTTIME;
-    size = sizeof (boottime_val);
-
-    if (sysctl (mib, 2, &boottime_val, &size, NULL, 0) >= 0 && size != 0)
-      {
-       boot_time = boottime_val.tv_sec;
-       return boot_time;
-      }
-  }
-#endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */
-
-  if (BOOT_TIME_FILE)
-    {
-      struct stat st;
-      if (stat (BOOT_TIME_FILE, &st) == 0)
-       {
-         boot_time = st.st_mtime;
-         return boot_time;
-       }
-    }
-
-#if defined (BOOT_TIME)
-  /* The utmp routines maintain static state.  Don't touch that state
+  /* get_boot_time maintains static state.  Don't touch that state
      if we are going to dump, since it might not survive dumping.  */
   if (will_dump_p ())
-    return boot_time;
-
-  /* Try to get boot time from utmp before wtmp,
-     since utmp is typically much smaller than wtmp.
-     Passing a null pointer causes get_boot_time_1
-     to inspect the default file, namely utmp.  */
-  get_boot_time_1 (0, 0);
-  if (boot_time)
-    return boot_time;
-
-  /* Try to get boot time from the current wtmp file.  */
-  get_boot_time_1 (WTMP_FILE, 1);
-
-  /* If we did not find a boot time in wtmp, look at wtmp.1,
-     wtmp.1.gz, wtmp.2, wtmp.2.gz, and so on.  */
-  for (int counter = 0; counter < 20 && ! boot_time; counter++)
-    {
-      Lisp_Object filename = Qnil;
-      bool delete_flag = false;
-      char cmd_string[sizeof WTMP_FILE ".19.gz"];
-      AUTO_STRING_WITH_LEN (tempname, cmd_string,
-                           sprintf (cmd_string, "%s.%d", WTMP_FILE, counter));
-      if (! NILP (Ffile_exists_p (tempname)))
-       filename = tempname;
-      else
-       {
-         tempname = make_formatted_string (cmd_string, "%s.%d.gz",
-                                           WTMP_FILE, counter);
-         if (! NILP (Ffile_exists_p (tempname)))
-           {
-             /* The utmp functions on older systems accept only file
-                names up to 8 bytes long.  Choose a 2 byte prefix, so
-                the 6-byte suffix does not make the name too long.  */
-             filename = Fmake_temp_file_internal (build_string ("wt"), Qnil,
-                                                  empty_unibyte_string, Qnil);
-             CALLN (Fcall_process, build_string ("gzip"), Qnil,
-                    list2 (QCfile, filename), Qnil,
-                    build_string ("-cd"), tempname);
-             delete_flag = true;
-           }
-       }
-
-      if (! NILP (filename))
-       {
-         get_boot_time_1 (SSDATA (filename), 1);
-         if (delete_flag)
-           emacs_unlink (SSDATA (filename));
-       }
-    }
-
-  return boot_time;
-#else
-  return 0;
-#endif
-}
+    return 0;
 
-#ifdef BOOT_TIME
-/* Try to get the boot time from wtmp file FILENAME.
-   This succeeds if that file contains a reboot record.
-
-   If FILENAME is zero, use the same file as before;
-   if no FILENAME has ever been specified, this is the utmp file.
-   Use the newest reboot record if NEWEST,
-   the first reboot record otherwise.
-   Ignore all reboot records on or before BOOT_TIME.
-   Success is indicated by setting BOOT_TIME to a larger value.  */
-
-void
-get_boot_time_1 (const char *filename, bool newest)
-{
-  struct utmp ut, *utp;
-
-  if (filename)
-    utmpname (filename);
-
-  setutent ();
-
-  while (1)
-    {
-      /* Find the next reboot record.  */
-      ut.ut_type = BOOT_TIME;
-      utp = getutid (&ut);
-      if (! utp)
-       break;
-      /* Compare reboot times and use the newest one.  */
-      if (utp->ut_time > boot_time)
-       {
-         boot_time = utp->ut_time;
-         if (! newest)
-           break;
-       }
-      /* Advance on element in the file
-        so that getutid won't repeat the same one.  */
-      utp = getutent ();
-      if (! utp)
-       break;
-    }
-  endutent ();
+  struct timespec boot_time;
+  boot_time.tv_sec = 0;
+  get_boot_time (&boot_time);
+  return boot_time.tv_sec;
 }
-#endif /* BOOT_TIME */
 
 /* An arbitrary limit on lock contents length.  8 K should be plenty
    big enough in practice.  */
@@ -423,7 +267,7 @@ create_lock_file (char *lfname, char *lock_info_str, bool 
force)
 static int
 lock_file_1 (Lisp_Object lfname, bool force)
 {
-  intmax_t boot = get_boot_time ();
+  intmax_t boot = get_boot_sec ();
   Lisp_Object luser_name = Fuser_login_name (Qnil);
   Lisp_Object lhost_name = Fsystem_name ();
 
@@ -609,7 +453,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object 
lfname)
                && (kill (pid, 0) >= 0 || errno == EPERM)
               && (boot_time == 0
                   || (boot_time <= TYPE_MAXIMUM (time_t)
-                      && within_one_second (boot_time, get_boot_time ()))))
+                      && within_one_second (boot_time, get_boot_sec ()))))
         return ANOTHER_OWNS_IT;
       /* The owner process is dead or has a strange pid, so try to
          zap the lockfile.  */
diff --git a/src/fns.c b/src/fns.c
index ee2c68e46ae..766216bd1a8 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -6192,6 +6192,9 @@ from the absolute start of the buffer, disregarding the 
narrowing.  */)
 {
   ptrdiff_t pos_byte, start_byte = BEGV_BYTE;
 
+  if (!BUFFER_LIVE_P (current_buffer))
+    error ("Attempt to count lines in a dead buffer");
+
   if (MARKERP (position))
     {
       /* We don't trust the byte position if the marker's buffer is
diff --git a/src/haiku_io.c b/src/haiku_io.c
index 4f1b1435b4b..c6d7108bf49 100644
--- a/src/haiku_io.c
+++ b/src/haiku_io.c
@@ -111,6 +111,8 @@ haiku_len (enum haiku_event_type type)
       return sizeof (struct haiku_clipboard_changed_event);
     case FONT_CHANGE_EVENT:
       return sizeof (struct haiku_font_change_event);
+    case NOTIFICATION_CLICK_EVENT:
+      return sizeof (struct haiku_notification_click_event);
     }
 
   emacs_abort ();
diff --git a/src/haiku_select.cc b/src/haiku_select.cc
index fe46075a007..76e2d829204 100644
--- a/src/haiku_select.cc
+++ b/src/haiku_select.cc
@@ -17,15 +17,24 @@ You should have received a copy of the GNU General Public 
License
 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <intprops.h>
 
 #include <Application.h>
+#include <Bitmap.h>
 #include <Clipboard.h>
+#include <Entry.h>
 #include <Message.h>
+#include <Notification.h>
+#include <OS.h>
 #include <Path.h>
-#include <Entry.h>
+#include <String.h>
+
+#include <translation/TranslationUtils.h>
 
 #include <cstdlib>
 #include <cstring>
+#include <cstdint>
+#include <cstdio>
 
 #include "haikuselect.h"
 
@@ -58,6 +67,10 @@ static bool owned_secondary;
 /* And the clipboard.  */
 static bool owned_clipboard;
 
+
+
+/* C++ clipboard support.  */
+
 static BClipboard *
 get_clipboard_object (enum haiku_clipboard clipboard)
 {
@@ -517,3 +530,134 @@ be_get_clipboard_count (enum haiku_clipboard id)
   clipboard = get_clipboard_object (id);
   return clipboard->SystemCount ();
 }
+
+
+
+/* C++ notifications support.
+
+   Desktop notifications on Haiku lack some of the features furnished
+   by notifications.el, specifically displaying multiple titled
+   actions within a single notification, sending callbacks when the
+   notification is dismissed, and providing a timeout after which the
+   notification is hidden.
+
+   Other features, such as notification categories and identifiers,
+   have clean straightforward relationships with their counterparts in
+   notifications.el.  */
+
+/* The last notification ID allocated.  */
+static intmax_t last_notification_id;
+
+/* Return the `enum notification_type' for TYPE.  TYPE is the TYPE
+   argument to a call to `be_display_notification'.  */
+
+static enum notification_type
+type_for_type (int type)
+{
+  switch (type)
+    {
+    case 0:
+      return B_INFORMATION_NOTIFICATION;
+
+    case 1:
+      return B_IMPORTANT_NOTIFICATION;
+
+    case 2:
+      return B_ERROR_NOTIFICATION;
+    }
+
+  abort ();
+}
+
+/* Return the ID of this team.  */
+
+static team_id
+my_team_id (void)
+{
+  thread_id id;
+  thread_info info;
+
+  id = find_thread (NULL);
+  get_thread_info (id, &info);
+
+  return info.team;
+}
+
+/* Display a desktop notification and return its identifier.
+
+   TITLE is the title text of the notification, encoded as UTF-8 text.
+
+   BODY is the text to be displayed within the body of the
+   notification.
+
+   SUPERSEDES is the identifier of a previous notification to replace,
+   or -1 if a new notification should be displayed.
+
+   TYPE states the urgency of the notification.  If 0, the
+   notification is displayed without special decoration.  If 1, the
+   notification is displayed with a blue band to its left, identifying
+   it as a notification of medium importance.  If 2, the notification
+   is displayed with a red band to its left, marking it as one of
+   critical importance.
+
+   ICON is the name of a file containing the icon of the notification,
+   or NULL, in which case Emacs's app icon will be displayed.  */
+
+intmax_t
+be_display_notification (const char *title, const char *body,
+                        intmax_t supersedes, int type, const char *icon)
+{
+  intmax_t id;
+  BNotification notification (type_for_type (type));
+  char buffer[INT_STRLEN_BOUND (team_id)
+             + INT_STRLEN_BOUND (intmax_t)
+             + sizeof "."];
+  BBitmap *bitmap;
+
+  if (supersedes < 0)
+    {
+      /* SUPERSEDES hasn't been provided, so allocate a new
+        notification ID.  */
+
+      INT_ADD_WRAPV (last_notification_id, 1,
+                    &last_notification_id);
+      id = last_notification_id;
+    }
+  else
+    id = supersedes;
+
+  /* Set the title and body text.  */
+  notification.SetTitle (title);
+  notification.SetContent (body);
+
+  /* Derive the notification ID from the ID of this team, so as to
+     avoid abrogating notifications from other Emacs sessions.  */
+  sprintf (buffer, "%d.%jd", my_team_id (), id);
+  notification.SetMessageID (BString (buffer));
+
+  /* Now set the bitmap icon, if given.  */
+
+  if (icon)
+    {
+      bitmap = BTranslationUtils::GetBitmap (icon);
+
+      if (bitmap)
+       {
+         notification.SetIcon (bitmap);
+         delete bitmap;
+       }
+    }
+
+  /* After this, Emacs::ArgvReceived should be called when the
+     notification is clicked.  Lamentably, this does not come about,
+     probably because arguments are only passed to applications if
+     they are not yet running.  */
+#if 0
+  notification.SetOnClickApp ("application/x-vnd.GNU-emacs");
+  notification.AddOnClickArg (BString ("-Notification,") += buffer);
+#endif /* 0 */
+
+  /* Finally, send the notification.  */
+  notification.Send ();
+  return id;
+}
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 28d8fae39b7..d5649e4d2ce 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -581,6 +581,24 @@ public:
   }
 };
 
+#if 0
+
+/* Return the ID of this team.  */
+
+static team_id
+my_team_id (void)
+{
+  thread_id id;
+  thread_info info;
+
+  id = find_thread (NULL);
+  get_thread_info (id, &info);
+
+  return info.team;
+}
+
+#endif /* 0 */
+
 class Emacs : public BApplication
 {
 public:
@@ -621,7 +639,8 @@ public:
   {
     BAlert *about = new BAlert (PACKAGE_NAME,
                                PACKAGE_STRING
-                               "\nThe extensible, self-documenting, real-time 
display editor.",
+                               "\nThe extensible, self-documenting, "
+                               "real-time display editor.",
                                "Close");
     about->Go ();
   }
@@ -674,6 +693,39 @@ public:
     else
       BApplication::MessageReceived (msg);
   }
+
+  /* The code below doesn't function; see `be_display_notification'
+     for further specifics.  */
+
+#if 0
+  void
+  ArgvReceived (int32 argc, char **argv)
+  {
+    struct haiku_notification_click_event rq;
+    intmax_t id;
+    team_id team;
+
+    /* ArgvReceived is called after Emacs is first started, with each
+       command line argument passed to Emacs.  It is, moreover, called
+       with ARGC set to 1 and ARGV[0] a string starting with
+       -Notification, after a notification is clicked.  This string
+       both incorporates the team ID and the notification ID.  */
+
+    if (argc == 1
+       && sscanf (argv[0], "-Notification,%d.%jd", &team, &id) == 2)
+      {
+       /* Since this is a valid notification message, generate an
+          event if the team ID matches.  */
+       if (team == my_team_id ())
+         {
+           rq.id = id;
+           haiku_write (NOTIFICATION_CLICK_EVENT, &rq);
+         }
+      }
+
+    BApplication::ArgvReceived (argc, argv);
+  }
+#endif /* 0 */
 };
 
 class EmacsWindow : public BWindow
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 564f61f57c7..5c22eb3b0db 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -116,6 +116,7 @@ enum haiku_event_type
     MENU_BAR_LEFT,
     CLIPBOARD_CHANGED_EVENT,
     FONT_CHANGE_EVENT,
+    NOTIFICATION_CLICK_EVENT,
   };
 
 struct haiku_clipboard_changed_event
@@ -464,6 +465,12 @@ struct haiku_font_change_event
   enum haiku_what_font what;
 };
 
+struct haiku_notification_click_event
+{
+  /* ID uniquely designating a single notification.  */
+  intmax_t id;
+};
+
 struct haiku_session_manager_reply
 {
   bool quit_reply;
diff --git a/src/haikuselect.c b/src/haikuselect.c
index b57c336c264..608b8e8fe30 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -1255,6 +1255,120 @@ haiku_start_watching_selections (void)
   be_start_watching_selection (CLIPBOARD_SECONDARY);
 }
 
+
+
+/* Notification support.  */
+
+static intmax_t
+haiku_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
+                             Lisp_Object replaces_id,
+                             Lisp_Object app_icon, Lisp_Object urgency)
+{
+  int type;
+  intmax_t supersedes;
+  const char *icon;
+
+  if (EQ (urgency, Qlow))
+    type = 0;
+  else if (EQ (urgency, Qnormal))
+    type = 1;
+  else if (EQ (urgency, Qcritical))
+    type = 2;
+  else
+    signal_error ("Invalid notification type provided", urgency);
+
+  supersedes = -1;
+
+  if (!NILP (replaces_id))
+    {
+      CHECK_INTEGER (replaces_id);
+      if (!integer_to_intmax (replaces_id, &supersedes))
+       supersedes = -1;
+    }
+
+  icon = NULL;
+
+  if (!NILP (app_icon))
+    icon = SSDATA (ENCODE_FILE (app_icon));
+
+  /* GC should not transpire from here onwards.  */
+  return be_display_notification (SSDATA (title), SSDATA (body),
+                                 supersedes, type, icon);
+}
+
+DEFUN ("haiku-notifications-notify", Fhaiku_notifications_notify,
+       Shaiku_notifications_notify, 0, MANY, 0, doc:
+       /* Display a desktop notification.
+ARGS must contain keywords followed by values.  Each of the following
+keywords is understood:
+
+  :title        The notification title.
+  :body         The notification body.
+  :replaces-id  The ID of a previous notification to supersede.
+  :app-icon     The file name of the notification's icon, if any.
+  :urgency      One of the symbols `low', `normal' or `critical',
+                specifying the importance of the notification.
+
+:title and :body must be provided.  Value is an integer (fixnum or
+bignum) identifying the notification displayed.
+
+usage: (haiku-notifications-notify &rest ARGS)  */)
+  (ptrdiff_t nargs, Lisp_Object *args)
+{
+  Lisp_Object title, body, replaces_id, app_icon, urgency;
+  Lisp_Object key, value;
+  ptrdiff_t i;
+
+  /* First, clear each of the variables above.  */
+  title = body = replaces_id = app_icon = urgency = Qnil;
+
+  /* If NARGS is odd, error.  */
+
+  if (nargs & 1)
+    error ("Odd number of arguments in call to `haiku-notifications-notify'");
+
+  /* Next, iterate through ARGS, searching for arguments.  */
+
+  for (i = 0; i < nargs; i += 2)
+    {
+      key = args[i];
+      value = args[i + 1];
+
+      if (EQ (key, QCtitle))
+       title = value;
+      else if (EQ (key, QCbody))
+       body = value;
+      else if (EQ (key, QCreplaces_id))
+       replaces_id = value;
+      else if (EQ (key, QCapp_icon))
+       app_icon = value;
+      else if (EQ (key, QCurgency))
+       urgency = value;
+    }
+
+  /* Demand at least TITLE and BODY be present.  */
+
+  if (NILP (title) || NILP (body))
+    error ("Title or body not provided");
+
+  /* Now check the type and possibly expand each non-nil argument.  */
+
+  CHECK_STRING (title);
+  title = ENCODE_UTF_8 (title);
+  CHECK_STRING (body);
+  body = ENCODE_UTF_8 (body);
+
+  if (NILP (urgency))
+    urgency = Qlow;
+
+  if (!NILP (app_icon))
+    app_icon = Fexpand_file_name (app_icon, Qnil);
+
+  return make_int (haiku_notifications_notify_1 (title, body,
+                                                replaces_id,
+                                                app_icon, urgency));
+}
+
 void
 syms_of_haikuselect (void)
 {
@@ -1312,6 +1426,16 @@ keyboard modifiers currently held down.  */);
   DEFSYM (Qdouble, "double");
   DEFSYM (Qalready_running, "already-running");
 
+  DEFSYM (QCtitle, ":title");
+  DEFSYM (QCbody, ":body");
+  DEFSYM (QCreplaces_id, ":replaces-id");
+  DEFSYM (QCapp_icon, ":app-icon");
+  DEFSYM (QCurgency, ":urgency");
+
+  DEFSYM (Qlow, "low");
+  DEFSYM (Qnormal, "normal");
+  DEFSYM (Qcritical, "critical");
+
   defsubr (&Shaiku_selection_data);
   defsubr (&Shaiku_selection_timestamp);
   defsubr (&Shaiku_selection_put);
@@ -1320,6 +1444,7 @@ keyboard modifiers currently held down.  */);
   defsubr (&Shaiku_roster_launch);
   defsubr (&Shaiku_write_node_attribute);
   defsubr (&Shaiku_send_message);
+  defsubr (&Shaiku_notifications_notify);
 
   haiku_dnd_frame = NULL;
 }
diff --git a/src/haikuselect.h b/src/haikuselect.h
index 28a1682e587..c117a2ab4f9 100644
--- a/src/haikuselect.h
+++ b/src/haikuselect.h
@@ -21,9 +21,11 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #ifdef __cplusplus
 #include <cstdio>
-#else
+#include <cstdint>
+#else /* !__cplusplus */
 #include <stdio.h>
-#endif
+#include <stdint.h>
+#endif /* __cplusplus */
 
 #include <SupportDefs.h>
 
@@ -37,15 +39,16 @@ enum haiku_clipboard
 #ifdef __cplusplus
 extern "C"
 {
-#endif
+#endif /* __cplusplus */
 /* Defined in haikuselect.c.  */
 extern void haiku_selection_disowned (enum haiku_clipboard, int64);
 
 /* Defined in haiku_select.cc.  */
 extern void be_clipboard_init (void);
-extern char *be_find_clipboard_data (enum haiku_clipboard, const char *, 
ssize_t *);
-extern void be_set_clipboard_data (enum haiku_clipboard, const char *, const 
char *,
-                                  ssize_t, bool);
+extern char *be_find_clipboard_data (enum haiku_clipboard, const char *,
+                                    ssize_t *);
+extern void be_set_clipboard_data (enum haiku_clipboard, const char *,
+                                  const char *, ssize_t, bool);
 extern bool be_clipboard_owner_p (enum haiku_clipboard);
 extern void be_update_clipboard_count (enum haiku_clipboard);
 
@@ -58,7 +61,8 @@ extern uint32 be_get_message_type (void *);
 extern void be_set_message_type (void *, uint32);
 extern void *be_get_message_message (void *, const char *, int32);
 extern void *be_create_simple_message (void);
-extern int be_add_message_data (void *, const char *, int32, const void *, 
ssize_t);
+extern int be_add_message_data (void *, const char *, int32, const void *,
+                               ssize_t);
 extern int be_add_refs_data (void *, const char *, const char *);
 extern int be_add_point_data (void *, const char *, float, float);
 extern int be_add_message_message (void *, const char *, void *);
@@ -69,9 +73,14 @@ extern void be_start_watching_selection (enum 
haiku_clipboard);
 extern bool be_selection_outdated_p (enum haiku_clipboard, int64);
 extern int64 be_get_clipboard_count (enum haiku_clipboard);
 
+
+
+extern intmax_t be_display_notification (const char *, const char *,
+                                        intmax_t, int, const char *);
+
 #ifdef __cplusplus
 };
-#endif
+#endif /* __cplusplus */
 #endif /* _HAIKU_SELECT_H_ */
 
 // Local Variables:
diff --git a/src/haikuterm.c b/src/haikuterm.c
index ed28a806ff2..70984936bf9 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -4042,6 +4042,19 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
             handled in Lisp.  */
          haiku_handle_font_change_event (buf, &inev);
          break;
+
+       case NOTIFICATION_CLICK_EVENT:
+         /* This code doesn't function, but the why is unknown.  */
+#if 0
+         {
+           struct haiku_notification_click_event *b = buf;
+
+           inev.kind = NOTIFICATION_CLICKED_EVENT;
+           inev.arg  = make_int (b->id);
+           break;
+         }
+#endif /* 0 */
+
        case KEY_UP:
        case DUMMY_EVENT:
        default:
diff --git a/src/image.c b/src/image.c
index 5eaafdf2af3..5ac97618742 100644
--- a/src/image.c
+++ b/src/image.c
@@ -8214,7 +8214,6 @@ png_load_body (struct frame *f, struct image *img, struct 
png_load_context *c)
      simple transparency, we prefer a clipping mask.  */
   if (!transparent_p)
     {
-      /* png_color_16 *image_bg; */
       Lisp_Object specified_bg
        = image_spec_value (img->spec, QCbackground, NULL);
       Emacs_Color color;
@@ -8840,7 +8839,8 @@ jpeg_load_body (struct frame *f, struct image *img,
       jpeg_destroy_decompress (&mgr->cinfo);
 
       /* If we already have an XImage, free that.  */
-      image_destroy_x_image (ximg);
+      if (ximg)
+       image_destroy_x_image (ximg);
       /* Free pixmap and colors.  */
       image_clear_image (f, img);
       return 0;
@@ -11742,6 +11742,12 @@ svg_css_length_to_pixels (RsvgLength length, double 
dpi, int font_size)
 {
   double value = length.length;
 
+#if ! LIBRSVG_CHECK_VERSION (2, 48, 0)
+  /* librsvg 2.48 lets us define the font size, but earlier versions
+     default to 12 pixels.  */
+  font_size = 12;
+#endif
+
   switch (length.unit)
     {
     case RSVG_UNIT_PX:
@@ -11766,16 +11772,31 @@ svg_css_length_to_pixels (RsvgLength length, double 
dpi, int font_size)
     case RSVG_UNIT_IN:
       value *= dpi;
       break;
-#if LIBRSVG_CHECK_VERSION (2, 48, 0)
-      /* We don't know exactly what font size is used on older librsvg
-        versions.  */
     case RSVG_UNIT_EM:
       value *= font_size;
       break;
-#endif
+    case RSVG_UNIT_EX:
+      /* librsvg uses an ex height of half the em height, so we match
+        that here.  */
+      value = value * font_size / 2.0;
+      break;
+    case RSVG_UNIT_PERCENT:
+      /* Percent is a ratio of the containing "viewport".  We don't
+        have a viewport, as such, as we try to draw the image to it's
+        'natural' size rather than dictate the size as if we were
+        drawing icons on a toolbar or similar.  This means that
+        percent values are useless to us and we are best off just
+        drawing the image according to whatever other sizes we can
+        derive.
+
+        If we do set explicit width and height values in the image
+        spec, this will work out correctly as librsvg will still
+        honour the percentage sizes in its final rendering no matter
+        what size we make the image.  */
+      value = 0;
+      break;
     default:
-      /* Probably ex or %.  We can't know what the pixel value is
-         without more information.  */
+      /* We should never reach this.  */
       value = 0;
     }
 
@@ -11906,7 +11927,8 @@ svg_load_image (struct frame *f, struct image *img, 
char *contents,
     }
   else
     {
-      RsvgRectangle zero_rect, viewbox, out_logical_rect;
+      RsvgRectangle  viewbox;
+      double explicit_width = 0, explicit_height = 0;
 
       /* Try the intrinsic dimensions first.  */
       gboolean has_width, has_height;
@@ -11918,34 +11940,27 @@ svg_load_image (struct frame *f, struct image *img, 
char *contents,
                                            &has_height, &iheight,
                                            &has_viewbox, &viewbox);
 
-      if (has_width && has_height)
-       {
-         /* Success!  We can use these values directly.  */
-         viewbox_width = svg_css_length_to_pixels (iwidth, dpi,
+      if (has_width)
+       explicit_width = svg_css_length_to_pixels (iwidth, dpi,
+                                                  img->face_font_size);
+      if (has_height)
+       explicit_height = svg_css_length_to_pixels (iheight, dpi,
                                                    img->face_font_size);
-         viewbox_height = svg_css_length_to_pixels (iheight, dpi,
-                                                    img->face_font_size);
 
-         /* Here one dimension could be zero because in percent unit.
-            So calculate this dimension with the other.  */
-         if (! (0 < viewbox_width) && (iwidth.unit == RSVG_UNIT_PERCENT))
-           viewbox_width = (viewbox_height * viewbox.width / viewbox.height)
-             * iwidth.length;
-         else if (! (0 < viewbox_height) && (iheight.unit == 
RSVG_UNIT_PERCENT))
-           viewbox_height = (viewbox_width * viewbox.height / viewbox.width)
-             * iheight.length;
+      if (explicit_width > 0 && explicit_height > 0)
+       {
+         viewbox_width = explicit_width;
+         viewbox_height = explicit_height;
        }
-      else if (has_width && has_viewbox)
+      else if (explicit_width > 0 && has_viewbox)
        {
-         viewbox_width = svg_css_length_to_pixels (iwidth, dpi,
-                                                   img->face_font_size);
-         viewbox_height = viewbox_width * viewbox.height / viewbox.width;
+         viewbox_width = explicit_width;
+         viewbox_height = explicit_width * viewbox.height / viewbox.width;
        }
-      else if (has_height && has_viewbox)
+      else if (explicit_height > 0 && has_viewbox)
        {
-         viewbox_height = svg_css_length_to_pixels (iheight, dpi,
-                                                    img->face_font_size);
-         viewbox_width = viewbox_height * viewbox.width / viewbox.height;
+         viewbox_height = explicit_height;
+         viewbox_width = explicit_height * viewbox.width / viewbox.height;
        }
       else if (has_viewbox)
        {
@@ -11959,8 +11974,15 @@ svg_load_image (struct frame *f, struct image *img, 
char *contents,
        {
          /* We haven't found a usable set of sizes, so try working out
             the visible area.  */
+
+         /* FIXME: I'm not sure exactly how librsvg uses this
+            viewport input here, so I'm not sure what values I should
+            set. */
+         RsvgRectangle max_viewport_rect = {0, 0, UINT_MAX, UINT_MAX};
+         RsvgRectangle out_logical_rect;
+
          rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL,
-                                             &zero_rect, &viewbox,
+                                             &max_viewport_rect, &viewbox,
                                              &out_logical_rect, NULL);
          viewbox_width = viewbox.x + viewbox.width;
          viewbox_height = viewbox.y + viewbox.height;
@@ -12814,8 +12836,10 @@ non-numeric, there is no explicit limit on the size of 
images.  */);
   add_image_type (Qpng);
 #endif
 
-#if defined (HAVE_WEBP) || (defined (HAVE_NATIVE_IMAGE_API) \
-                           && defined (HAVE_HAIKU))
+#if defined (HAVE_WEBP)                                                \
+  || (defined (HAVE_NATIVE_IMAGE_API)                          \
+      && ((defined (HAVE_NS) && defined (NS_IMPL_COCOA))       \
+         || defined (HAVE_HAIKU)))
   DEFSYM (Qwebp, "webp");
   DEFSYM (Qwebpdemux, "webpdemux");
   add_image_type (Qwebp);
diff --git a/src/lread.c b/src/lread.c
index e300485f08d..e6ef7930f50 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -795,9 +795,9 @@ static void substitute_in_interval (INTERVAL, void *);
    If SECONDS is a number, wait that many seconds for input, and
    return Qnil if no input arrives within that time.
 
-   If text conversion is enabled and ASCII_REQUIRED && ERROR_NONASCII,
-   temporarily disable any input method which wants to perform
-   edits, unless `disable-inhibit-text-conversion'.  */
+   If text conversion is enabled and ASCII_REQUIRED, temporarily
+   disable any input method which wants to perform edits, unless
+   `disable-inhibit-text-conversion'.  */
 
 static Lisp_Object
 read_filtered_event (bool no_switch_frame, bool ascii_required,
@@ -820,8 +820,7 @@ read_filtered_event (bool no_switch_frame, bool 
ascii_required,
   /* Don't use text conversion when trying to just read a
      character.  */
 
-  if (ascii_required && error_nonascii
-      && !disable_inhibit_text_conversion)
+  if (ascii_required && !disable_inhibit_text_conversion)
     {
       disable_text_conversion ();
       record_unwind_protect_void (resume_text_conversion);
diff --git a/src/nsfns.m b/src/nsfns.m
index f962de02cb9..b846b490ff7 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -3796,6 +3796,27 @@ all_nonzero_ascii (unsigned char *str, ptrdiff_t n)
   return true;
 }
 
+/* Count the number of characters in STR, NBYTES long.
+   The string must be valid UTF-8.  */
+static ptrdiff_t
+count_utf8_chars (const char *str, ptrdiff_t nbytes)
+{
+  /* This is faster than parse_str_as_multibyte, and much faster than
+     [NSString lengthOfBytesUsingEncoding: NSUTF32StringEncoding].  */
+  const char *end = str + nbytes;
+  ptrdiff_t nc = 0;
+  while (str < end)
+    {
+      nc++;
+      unsigned char c = *str;
+      str += (  c <= 0x7f ? 1    // 0xxxxxxx
+              : c <= 0xdf ? 2    // 110xxxxx 10xxxxxx
+              : c <= 0xef ? 3    // 1110xxxx 10xxxxxx 10xxxxxx
+              :             4);  // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+    }
+  return nc;
+}
+
 @implementation NSString (EmacsString)
 /* Make an NSString from a Lisp string.  STRING must not be in an
    encoded form (e.g. UTF-8).  */
@@ -3840,9 +3861,11 @@ all_nonzero_ascii (unsigned char *str, ptrdiff_t n)
 /* Make a Lisp string from an NSString.  */
 - (Lisp_Object)lispString
 {
-  // make_string behaves predictably and correctly with UTF-8 input.
-  return make_string ([self UTF8String],
-                      [self lengthOfBytesUsingEncoding: NSUTF8StringEncoding]);
+  /* If the input string includes unpaired surrogates, then the result
+     will be an empty string.  */
+  const char *utf8 = [self UTF8String];
+  ptrdiff_t bytes = [self lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
+  return make_multibyte_string (utf8, count_utf8_chars (utf8, bytes), bytes);
 }
 @end
 
diff --git a/src/nsimage.m b/src/nsimage.m
index af8eb629989..b33124900bb 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -77,6 +77,10 @@ ns_can_use_native_image_api (Lisp_Object type)
 #ifndef HAVE_RSVG
   else if (EQ (type, Qsvg))
     imageType = @"public.svg-image";
+#endif
+#ifndef HAVE_WEBP
+  else if (EQ (type, Qwebp))
+    imageType = @"org.webmproject.webp";
 #endif
   else if (EQ (type, Qheic))
     imageType = @"public.heic";
diff --git a/src/pdumper.c b/src/pdumper.c
index 4f9710ee610..92747223968 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2745,7 +2745,7 @@ dump_hash_table (struct dump_context *ctx,
 static dump_off
 dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
 {
-#if CHECK_STRUCTS && !defined HASH_buffer_85D317CE74
+#if CHECK_STRUCTS && !defined HASH_buffer_6C25F9C3BC
 # error "buffer changed. See CHECK_STRUCTS comment in config.h."
 #endif
   struct buffer munged_buffer = *in_buffer;
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 9c1fc7bef4e..a7c687d811d 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -1328,14 +1328,17 @@ fill_background_by_face (struct frame *f, struct face 
*face, int x, int y,
                         int width, int height)
 {
   cairo_t *cr = pgtk_begin_cr_clip (f);
+  double r, g, b, a;
 
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
   cairo_rectangle (cr, x, y, width, height);
   cairo_clip (cr);
 
-  double r = ((face->background >> 16) & 0xff) / 255.0;
-  double g = ((face->background >> 8) & 0xff) / 255.0;
-  double b = ((face->background >> 0) & 0xff) / 255.0;
-  cairo_set_source_rgb (cr, r, g, b);
+  r = ((face->background >> 16) & 0xff) / 255.0;
+  g = ((face->background >> 8) & 0xff) / 255.0;
+  b = ((face->background >> 0) & 0xff) / 255.0;
+  a = f->alpha_background;
+  cairo_set_source_rgba (cr, r, g, b, a);
   cairo_paint (cr);
 
   if (face->stipple != 0)
@@ -1343,10 +1346,10 @@ fill_background_by_face (struct frame *f, struct face 
*face, int x, int y,
       cairo_pattern_t *mask
        = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].pattern;
 
-      double r = ((face->foreground >> 16) & 0xff) / 255.0;
-      double g = ((face->foreground >> 8) & 0xff) / 255.0;
-      double b = ((face->foreground >> 0) & 0xff) / 255.0;
-      cairo_set_source_rgb (cr, r, g, b);
+      r = ((face->foreground >> 16) & 0xff) / 255.0;
+      g = ((face->foreground >> 8) & 0xff) / 255.0;
+      b = ((face->foreground >> 0) & 0xff) / 255.0;
+      cairo_set_source_rgba (cr, r, g, b, a);
       cairo_mask (cr, mask);
     }
 
diff --git a/src/process.c b/src/process.c
index d836f4ff476..4e7103d5cbc 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1737,6 +1737,18 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 
0, 0,
 }
 
 
+static Lisp_Object
+get_required_string_keyword_param (Lisp_Object kwargs, Lisp_Object keyword)
+{
+  Lisp_Object arg = plist_member (kwargs, keyword);
+  if (NILP (arg) || !CONSP (arg) || !CONSP (XCDR (arg)))
+    error ("Missing %s keyword parameter", SSDATA (SYMBOL_NAME (keyword)));
+  Lisp_Object val = XCAR (XCDR (arg));
+  if (!STRINGP (val))
+    error ("%s value not a string", SSDATA (SYMBOL_NAME (keyword)));
+  return val;
+}
+
 /* Starting asynchronous inferior processes.  */
 
 DEFUN ("make-process", Fmake_process, Smake_process, 0, MANY, 0,
@@ -1801,7 +1813,7 @@ such handler, proceed as if FILE-HANDLER were nil.
 usage: (make-process &rest ARGS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
-  Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem;
+  Lisp_Object buffer, command, program, proc, contact, current_dir, tem;
   Lisp_Object xstderr, stderrproc;
   specpdl_ref count = SPECPDL_INDEX ();
 
@@ -1830,8 +1842,7 @@ usage: (make-process &rest ARGS)  */)
      chdir, since it's in a vfork.  */
   current_dir = get_current_directory (true);
 
-  name = plist_get (contact, QCname);
-  CHECK_STRING (name);
+  Lisp_Object name = get_required_string_keyword_param (contact, QCname);
 
   command = plist_get (contact, QCcommand);
   if (CONSP (command))
@@ -2408,7 +2419,7 @@ usage:  (make-pipe-process &rest ARGS)  */)
 {
   Lisp_Object proc, contact;
   struct Lisp_Process *p;
-  Lisp_Object name, buffer;
+  Lisp_Object buffer;
   Lisp_Object tem;
   int inchannel, outchannel;
 
@@ -2417,8 +2428,7 @@ usage:  (make-pipe-process &rest ARGS)  */)
 
   contact = Flist (nargs, args);
 
-  name = plist_get (contact, QCname);
-  CHECK_STRING (name);
+  Lisp_Object name = get_required_string_keyword_param (contact, QCname);
   proc = make_process (name);
   specpdl_ref specpdl_count = SPECPDL_INDEX ();
   record_unwind_protect (remove_process, proc);
@@ -3938,7 +3948,7 @@ usage: (make-network-process &rest ARGS)  */)
 #endif
   EMACS_INT port = 0;
   Lisp_Object tem;
-  Lisp_Object name, buffer, host, service, address;
+  Lisp_Object buffer, host, service, address;
   Lisp_Object filter, sentinel, use_external_socket_p;
   Lisp_Object addrinfos = Qnil;
   int socktype;
@@ -3975,7 +3985,7 @@ usage: (make-network-process &rest ARGS)  */)
   else
     error ("Unsupported connection type");
 
-  name = plist_get (contact, QCname);
+  Lisp_Object name = get_required_string_keyword_param (contact, QCname);
   buffer = plist_get (contact, QCbuffer);
   filter = plist_get (contact, QCfilter);
   sentinel = plist_get (contact, QCsentinel);
@@ -3985,7 +3995,6 @@ usage: (make-network-process &rest ARGS)  */)
 
   if (!NILP (server) && nowait)
     error ("`:server' is incompatible with `:nowait'");
-  CHECK_STRING (name);
 
   /* :local ADDRESS or :remote ADDRESS */
   if (NILP (server))
diff --git a/src/sfnt.c b/src/sfnt.c
index 876db70bcda..14e353013cd 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -15,8 +15,7 @@ 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, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
@@ -1006,7 +1005,7 @@ sfnt_read_cmap_table (int fd, struct sfnt_offset_subtable 
*subtable,
       /* Read the common part of the new subtable.  */
       rc = read (fd, &(*subtables)[i], sizeof (*subtables)[i]);
 
-      if (rc < sizeof (*subtables))
+      if (rc < sizeof (*subtables)[i])
        {
          xfree (cmap);
          xfree (*subtables);
@@ -2443,11 +2442,7 @@ sfnt_free_glyph (struct sfnt_glyph *glyph)
    the array of points of length NUM_COORDINATES given as X and Y.
 
    Also, apply the fixed point offsets X_OFF and Y_OFF to each X and Y
-   coordinate.
-
-   See sfnt_decompose_compound_glyph for an explanation of why offsets
-   might be applied here, and not while reading the subglyph
-   itself.  */
+   coordinate after transforms within COMPONENT are effected.  */
 
 static void
 sfnt_transform_coordinates (struct sfnt_compound_glyph_component *component,
@@ -2461,56 +2456,59 @@ sfnt_transform_coordinates (struct 
sfnt_compound_glyph_component *component,
 
   if (component->flags & 010) /* WE_HAVE_A_SCALE */
     {
-      for (i = 0; i < num_coordinates; ++i)
-       {
-         x[i] *= component->u.scale / 16384.0;
-         y[i] *= component->u.scale / 16384.0;
-         x[i] += x_off;
-         y[i] += y_off;
-       }
+      m1 = component->u.scale / 16384.0;
+      m2 = m3 = m4 = 0;
+      m5 = component->u.scale / 16384.0;
+      m6 = 0;
     }
   else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */
     {
-      for (i = 0; i < num_coordinates; ++i)
-       {
-         x[i] *= component->u.a.xscale / 16384.0;
-         y[i] *= component->u.a.yscale / 16384.0;
-         x[i] += x_off;
-         y[i] += y_off;
-       }
+      m1 = component->u.a.xscale / 16384.0;
+      m2 = m3 = m4 = 0;
+      m5 = component->u.a.yscale / 16384.0;
+      m6 = 0;
     }
   else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
     {
-      /* Apply the specified affine transformation.
-        A transform looks like:
-
-          M1 M2 M3     X
-          M4 M5 M6   * Y
-
-          =
-
-          M1*X + M2*Y + M3*1 = X1
-          M4*X + M5*Y + M6*1 = Y1
-
-        (In most transforms, there is another row at the bottom for
-         mathematical reasons.  Since Z1 is always 1.0, the row is
-         simply implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 =
-         1.0.  See the definition of matrix3x3 in image.c for some
-         more explanations about this.) */
       m1 = component->u.b.xscale / 16384.0;
       m2 = component->u.b.scale01 / 16384.0;
       m3 = 0;
       m4 = component->u.b.scale10 / 16384.0;
       m5 = component->u.b.yscale / 16384.0;
       m6 = 0;
-
+    }
+  else /* No scale, just apply x_off and y_off.  */
+    {
       for (i = 0; i < num_coordinates; ++i)
-       {
-         x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
-         y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
-         x[i] += x_off;
-         y[i] += y_off;
-       }
+       x[i] += x_off, y[i] += y_off;
+
+      return;
+    }
+
+  m3 = x_off;
+  m6 = y_off;
+
+  /* Apply the specified affine transformation.
+     A transform looks like:
+
+     M1 M2 M3     X
+     M4 M5 M6   * Y
+
+     =
+
+     M1*X + M2*Y + M3*1 = X1
+     M4*X + M5*Y + M6*1 = Y1
+
+     (In most transforms, there is another row at the bottom for
+     mathematical reasons.  Since Z1 is always 1.0, the row is simply
+     implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 = 1.0.  See
+     the definition of matrix3x3 in image.c for some more explanations
+     about this.) */
+
+  for (i = 0; i < num_coordinates; ++i)
+    {
+      x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
+      y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
     }
 }
 
@@ -2630,9 +2628,9 @@ sfnt_round_fixed (int32_t number)
 /* Decompose GLYPH, a compound glyph, into an array of points and
    contours.
 
-   CONTEXT should be zeroed and put on the stack.  OFF_X and OFF_Y
-   should be zero, as should RECURSION_COUNT.  GET_GLYPH and
-   FREE_GLYPH, along with DCONTEXT, mean the same as in
+   CONTEXT should be zeroed and put on the stack. RECURSION_COUNT
+   should be initialized to 0.  GET_GLYPH, FREE_GLYPH, and
+   GET_METRICS, along with DCONTEXT, mean the same as in
    sfnt_decompose_glyph.
 
    Value is 1 upon failure, else 0.  */
@@ -2642,7 +2640,7 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
                               struct sfnt_compound_glyph_context *context,
                               sfnt_get_glyph_proc get_glyph,
                               sfnt_free_glyph_proc free_glyph,
-                              sfnt_fixed off_x, sfnt_fixed off_y,
+                              sfnt_get_metrics_proc get_metrics,
                               int recursion_count,
                               void *dcontext)
 {
@@ -2658,6 +2656,8 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
   unsigned char *flags_base;
   size_t base_index, contour_start;
   bool defer_offsets;
+  struct sfnt_glyph_metrics sub_metrics;
+  sfnt_fixed f1, f2;
 
   /* Set up the base index.  This is the index from where on point
      renumbering starts.
@@ -2760,6 +2760,42 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
            {
              if (point2 >= subglyph->simple->number_of_points)
                {
+                 if (point2 < subglyph->simple->number_of_points + 2)
+                   {
+                     /* POINT2 is one of SUBGLYPH's phantom points.
+                        Retrieve the glyph's metrics.  */
+
+                     if ((*get_metrics) (component->glyph_index, &sub_metrics,
+                                         dcontext))
+                       {
+                         if (need_free)
+                           free_glyph (subglyph, dcontext);
+
+                         return 1;
+                       }
+
+                     /* Derive the phantom points from those metrics.  */
+                     f1 = glyph->xmin - sub_metrics.lbearing;
+                     f2 = f1 + sub_metrics.advance;
+
+                     /* Apply the metrics distortion.  */
+                     f1 += glyph->origin_distortion;
+                     f2 += glyph->advance_distortion;
+
+                     /* Get the points and use them to compute the offsets.  */
+
+                     if (!(point2 - subglyph->simple->number_of_points))
+                       x = f1 * 65536;
+                     else
+                       x = f2 * 65536;
+
+                     x = context->x_coordinates[point] - x;
+                     y = context->y_coordinates[point];
+
+                     /* X and Y offsets have been ascertained.  */
+                     goto skip_computation;
+                   }
+
                  if (need_free)
                    free_glyph (subglyph, dcontext);
 
@@ -2771,6 +2807,9 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
              ytemp = context->y_coordinates[point];
              x = (xtemp - subglyph->simple->x_coordinates[point2] * 65536);
              y = (ytemp - subglyph->simple->y_coordinates[point2] * 65536);
+
+           skip_computation:
+             ;
            }
          else
            {
@@ -2823,16 +2862,14 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
 
              for (i = 0; i <= last_point; ++i)
                {
-                 x_base[i] = ((subglyph->simple->x_coordinates[i] * 65536)
-                              + off_x + x);
-                 y_base[i] = ((subglyph->simple->y_coordinates[i] * 65536)
-                              + off_y + y);
+                 x_base[i] = (subglyph->simple->x_coordinates[i] * 65536);
+                 y_base[i] = (subglyph->simple->y_coordinates[i] * 65536);
                  flags_base[i] = subglyph->simple->flags[i];
                }
 
              /* Apply the transform to the points.  */
              sfnt_transform_coordinates (component, x_base, y_base,
-                                         last_point + 1, 0, 0);
+                                         last_point + 1, x, y);
 
              /* Copy over the contours.  */
              for (i = 0; i < number_of_contours; ++i)
@@ -2848,8 +2885,7 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
                                              context,
                                              get_glyph,
                                              free_glyph,
-                                             off_x + x,
-                                             off_y + y,
+                                             get_metrics,
                                              recursion_count + 1,
                                              dcontext);
 
@@ -2887,6 +2923,38 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
 
              if (point2 >= context->num_points)
                {
+                 /* POINT2 might fall within the phantom points of
+                    that glyph.  */
+
+                 if (point2 - context->num_points < 2)
+                   {
+                     if ((*get_metrics) (component->glyph_index, &sub_metrics,
+                                         dcontext))
+                       goto error_in_defer_offsets;
+
+                     /* Derive the phantom points from those metrics.  */
+                     f1 = glyph->xmin - sub_metrics.lbearing;
+                     f2 = f1 + sub_metrics.advance;
+
+                     /* Apply the metrics distortion.  */
+                     f1 += glyph->origin_distortion;
+                     f2 += glyph->advance_distortion;
+
+                     /* Get the points and use them to compute the offsets.  */
+
+                     if (!(point2 - context->num_points))
+                       x = f1 * 65536;
+                     else
+                       x = f2 * 65536;
+
+                     x = context->x_coordinates[point] - x;
+                     y = context->y_coordinates[point];
+
+                     /* X and Y offsets have been ascertained.  */
+                     goto skip_computation_from_defer_offsets;
+                   }
+
+               error_in_defer_offsets:
                  if (need_free)
                    free_glyph (subglyph, dcontext);
 
@@ -2900,12 +2968,15 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
              ytemp = context->y_coordinates[point];
              x = (xtemp - context->x_coordinates[point2]);
              y = (ytemp - context->y_coordinates[point2]);
+
+           skip_computation_from_defer_offsets:
+             ;
            }
 
          sfnt_transform_coordinates (component,
                                      context->x_coordinates + contour_start,
                                      context->y_coordinates + contour_start,
-                                     contour_start - context->num_points,
+                                     context->num_points - contour_start,
                                      x, y);
        }
 
@@ -3212,7 +3283,10 @@ sfnt_decompose_glyph_2 (size_t here, size_t last,
 
    If GLYPH is compound, use GET_GLYPH to obtain subglyphs.  PROC must
    return whether or not FREE_GLYPH will be called with the glyph
-   after sfnt_decompose_glyph is done with it.
+   after sfnt_decompose_glyph is done with it.  If GLYPH moreover
+   incorporates components whose anchor points are phantom points, use
+   GET_METRICS to obtain glyph metrics prerequisite for establishing
+   their coordinates.
 
    All functions will be called with DCONTEXT as an argument.
 
@@ -3230,6 +3304,7 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
                      sfnt_curve_to_proc curve_to,
                      sfnt_get_glyph_proc get_glyph,
                      sfnt_free_glyph_proc free_glyph,
+                     sfnt_get_metrics_proc get_metrics,
                      void *dcontext)
 {
   size_t here, last, n;
@@ -3277,7 +3352,8 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
 
   if (sfnt_decompose_compound_glyph (glyph, &context,
                                     get_glyph, free_glyph,
-                                    0, 0, 0, dcontext))
+                                    get_metrics, 0,
+                                    dcontext))
     {
       xfree (context.x_coordinates);
       xfree (context.y_coordinates);
@@ -3841,7 +3917,8 @@ sfnt_curve_to_and_build (struct sfnt_point control,
    outline.
 
    Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain
-   glyphs for compound glyph subcomponents.  */
+   glyphs for compound glyph subcomponents, and GET_METRICS with the
+   provided DCONTEXT for unscaled glyph metrics.  */
 
 TEST_STATIC struct sfnt_glyph_outline *
 sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
@@ -3849,6 +3926,7 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
                          struct sfnt_glyph_metrics *metrics,
                          sfnt_get_glyph_proc get_glyph,
                          sfnt_free_glyph_proc free_glyph,
+                         sfnt_get_metrics_proc get_metrics,
                          void *dcontext)
 {
   struct sfnt_glyph_outline *outline;
@@ -3883,7 +3961,8 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
   rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build,
                             sfnt_line_to_and_build,
                             sfnt_curve_to_and_build,
-                            get_glyph, free_glyph, dcontext);
+                            get_glyph, free_glyph, get_metrics,
+                            dcontext);
 
   /* Synchronize the outline object with what might have changed
      inside sfnt_decompose_glyph.  */
@@ -6636,16 +6715,19 @@ sfnt_interpret_trap (struct sfnt_interpreter 
*interpreter,
 #define GXAXIS()                               \
   {                                            \
     uint32_t v;                                        \
-    int i;                                     \
+    int i, naxis;                              \
                                                \
-    for (i = 0; i < interpreter->n_axis; ++i)  \
+    naxis = interpreter->n_axis;               \
+    CHECK_STACK_AVAILABLE (naxis);             \
+                                               \
+    for (i = 0; i < naxis; ++i)                        \
       {                                                \
        if (interpreter->norm_coords)           \
          v = interpreter->norm_coords[i] / 4;  \
        else                                    \
          v = 0;                                \
                                                \
-       PUSH (v);                               \
+       PUSH_UNCHECKED (v);                     \
       }                                                \
   }
 
@@ -9725,7 +9807,8 @@ sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
 {
   sfnt_f26dot6 x, y, original_x, original_y;
   sfnt_f26dot6 magnitude;
-  size_t start, end, n;
+  uint16_t reference_point;
+  size_t start, end, start1, end1, n;
 
   if (!interpreter->glyph_zone)
     TRAP ("SHC without glyph zone");
@@ -9738,10 +9821,12 @@ sfnt_interpret_shc (struct sfnt_interpreter 
*interpreter,
      projection vector.  */
 
   if (opcode == 0x35)
-    sfnt_address_zp0 (interpreter, interpreter->state.rp1,
+    sfnt_address_zp0 (interpreter,
+                     (reference_point = interpreter->state.rp1),
                      &x, &y, &original_x, &original_y);
   else
-    sfnt_address_zp1 (interpreter, interpreter->state.rp2,
+    sfnt_address_zp1 (interpreter,
+                     (reference_point = interpreter->state.rp2),
                      &x, &y, &original_x, &original_y);
 
   magnitude = sfnt_project_vector (interpreter,
@@ -9752,7 +9837,7 @@ sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
      Verify that both are valid.  */
 
   if (contour)
-    start = interpreter->glyph_zone->contour_end_points[contour - 1];
+    start = interpreter->glyph_zone->contour_end_points[contour - 1] + 1;
   else
     start = 0;
 
@@ -9761,6 +9846,31 @@ sfnt_interpret_shc (struct sfnt_interpreter *interpreter,
   if (start > end || end >= interpreter->glyph_zone->num_points)
     TRAP ("invalid contour data in glyph");
 
+  /* If the reference point falls between end and start, split the
+     range formed by end and start at the reference point and keep the
+     latter intact.  */
+
+  if (start <= reference_point && reference_point <= end)
+    {
+      /* Do the points between start and rpN.  */
+      start1 = start;
+      end1   = reference_point - 1;
+
+      if (start1 <= end1)
+       sfnt_move_glyph_zone (interpreter, start1,
+                             end1 - start1 + 1, magnitude);
+
+      /* Now the points between rpN + 1 and end.  */
+      start1 = reference_point + 1;
+      end1   = end;
+
+      if (start1 <= end1)
+       sfnt_move_glyph_zone (interpreter, start1,
+                             end1 - start1 + 1, magnitude);
+
+      return;
+    }
+
   /* Compute the number of points to move.  */
   n = end - start + 1;
 
@@ -11345,11 +11455,8 @@ sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
    Treat X and Y as arrays of 26.6 fixed point values.
 
    Also, apply the 26.6 fixed point offsets X_OFF and Y_OFF to each X
-   and Y coordinate.
-
-   See sfnt_decompose_compound_glyph for an explanation of why offsets
-   might be applied here, and not while reading the subglyph
-   itself.  */
+   and Y coordinate after the transforms in COMPONENT are
+   effected.  */
 
 static void
 sfnt_transform_f26dot6 (struct sfnt_compound_glyph_component *component,
@@ -11363,56 +11470,62 @@ sfnt_transform_f26dot6 (struct 
sfnt_compound_glyph_component *component,
 
   if (component->flags & 010) /* WE_HAVE_A_SCALE */
     {
-      for (i = 0; i < num_coordinates; ++i)
-       {
-         x[i] *= component->u.scale / 16384.0;
-         y[i] *= component->u.scale / 16384.0;
-         x[i] += x_off;
-         y[i] += y_off;
-       }
+      m1 = component->u.scale / 16384.0;
+      m2 = m3 = m4 = 0;
+      m5 = component->u.scale / 16384.0;
+      m6 = 0;
     }
   else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */
     {
-      for (i = 0; i < num_coordinates; ++i)
-       {
-         x[i] *= component->u.a.xscale / 16384.0;
-         y[i] *= component->u.a.yscale / 16384.0;
-         x[i] += x_off;
-         y[i] += y_off;
-       }
+      m1 = component->u.a.xscale / 16384.0;
+      m2 = m3 = m4 = 0;
+      m5 = component->u.a.yscale / 16384.0;
+      m6 = 0;
     }
   else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
     {
-      /* Apply the specified affine transformation.
-        A transform looks like:
-
-          M1 M2 M3     X
-          M4 M5 M6   * Y
-
-          =
-
-          M1*X + M2*Y + M3*1 = X1
-          M4*X + M5*Y + M6*1 = Y1
-
-        (In most transforms, there is another row at the bottom for
-         mathematical reasons.  Since Z1 is always 1.0, the row is
-         simply implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 =
-         1.0.  See the definition of matrix3x3 in image.c for some
-         more explanations about this.) */
       m1 = component->u.b.xscale / 16384.0;
       m2 = component->u.b.scale01 / 16384.0;
       m3 = 0;
       m4 = component->u.b.scale10 / 16384.0;
       m5 = component->u.b.yscale / 16384.0;
       m6 = 0;
-
-      for (i = 0; i < num_coordinates; ++i)
+    }
+  else /* No scale, just apply x_off and y_off.  */
+    {
+      if (x_off || y_off)
        {
-         x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
-         y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
-         x[i] += x_off;
-         y[i] += y_off;
+         for (i = 0; i < num_coordinates; ++i)
+           x[i] += x_off, y[i] += y_off;
        }
+
+      return;
+    }
+
+  m3 = x_off;
+  m6 = y_off;
+
+  /* Apply the specified affine transformation.
+     A transform looks like:
+
+     M1 M2 M3     X
+     M4 M5 M6   * Y
+
+     =
+
+     M1*X + M2*Y + M3*1 = X1
+     M4*X + M5*Y + M6*1 = Y1
+
+     (In most transforms, there is another row at the bottom for
+     mathematical reasons.  Since Z1 is always 1.0, the row is simply
+     implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 = 1.0.  See
+     the definition of matrix3x3 in image.c for some more explanations
+     about this.) */
+
+  for (i = 0; i < num_coordinates; ++i)
+    {
+      x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
+      y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
     }
 }
 
@@ -11426,6 +11539,8 @@ sfnt_transform_f26dot6 (struct 
sfnt_compound_glyph_component *component,
 
    CONTEXT contains the points and contours of this compound glyph,
    numbered starting from BASE_INDEX and BASE_CONTOUR respectively.
+   In addition, CONTEXT also contains two additional ``phantom
+   points'' supplying the left and right side bearings of GLYPH.
 
    Value is NULL upon success, or a description of the error upon
    failure.  */
@@ -11441,10 +11556,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph 
*glyph,
   size_t zone_size, temp;
   struct sfnt_interpreter_zone *zone;
   struct sfnt_interpreter_zone *volatile preserved_zone;
-  sfnt_f26dot6 phantom_point_1_x;
-  sfnt_f26dot6 phantom_point_1_y;
-  sfnt_f26dot6 phantom_point_2_x;
-  sfnt_f26dot6 phantom_point_2_y;
   volatile bool zone_was_allocated;
   int rc;
   sfnt_f26dot6 *x_base, *y_base;
@@ -11492,7 +11603,7 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph 
*glyph,
     }
 
   /* Now load the zone with data.  */
-  zone->num_points = num_points + 2;
+  zone->num_points = num_points;
   zone->num_contours = num_contours;
   zone->contour_end_points = (size_t *) (zone + 1);
   zone->x_points = (sfnt_f26dot6 *) (zone->contour_end_points
@@ -11519,17 +11630,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph 
*glyph,
       zone->x_points[i] = context->x_coordinates[i + base_index];
     }
 
-  /* Compute phantom points.  */
-  sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
-                              &phantom_point_1_x, &phantom_point_1_y,
-                              &phantom_point_2_x, &phantom_point_2_y);
-
-  /* Load phantom points.  */
-  zone->x_points[i] = phantom_point_1_x;
-  zone->x_points[i + 1] = phantom_point_2_x;
-  zone->x_current[i] = phantom_point_1_x;
-  zone->x_current[i + 1] = phantom_point_2_x;
-
   for (i = 0; i < num_points; ++i)
     {
       zone->y_current[i] = context->y_coordinates[i + base_index];
@@ -11540,16 +11640,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph 
*glyph,
                        & ~SFNT_POINT_TOUCHED_BOTH);
     }
 
-    /* Load phantom points.  */
-  zone->y_points[i] = phantom_point_1_y;
-  zone->y_points[i + 1] = phantom_point_2_y;
-  zone->y_current[i] = phantom_point_1_x;
-  zone->y_current[i + 1] = phantom_point_2_x;
-
-  /* Load phantom point flags.  */
-  zone->flags[i] = SFNT_POINT_PHANTOM;
-  zone->flags[i + 1] = SFNT_POINT_PHANTOM;
-
   /* Load the compound glyph program.  */
   interpreter->IP = 0;
   interpreter->SP = interpreter->stack;
@@ -11615,7 +11705,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph 
*glyph,
 
 /* Internal helper for sfnt_interpret_compound_glyph.
    RECURSION_COUNT is the number of times this function has called itself.
-   OFF_X and OFF_Y are the offsets to apply to the glyph outline.
 
    METRICS are the unscaled metrics of this compound glyph.
 
@@ -11634,7 +11723,6 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
                                 struct sfnt_hhea_table *hhea,
                                 struct sfnt_maxp_table *maxp,
                                 struct sfnt_glyph_metrics *metrics,
-                                sfnt_fixed off_x, sfnt_fixed off_y,
                                 int recursion_count,
                                 void *dcontext)
 {
@@ -11653,6 +11741,10 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
   bool defer_offsets;
   struct sfnt_instructed_outline *value;
   struct sfnt_glyph_metrics sub_metrics;
+  sfnt_f26dot6 phantom_point_1_x;
+  sfnt_f26dot6 phantom_point_1_y;
+  sfnt_f26dot6 phantom_point_2_x;
+  sfnt_f26dot6 phantom_point_2_y;
 
   error = NULL;
 
@@ -11670,7 +11762,7 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
      maximum valid value of `max_component_depth', which is 16.  */
 
   if (recursion_count > 16)
-    return "Overly deep recursion in compound glyph data";
+    return "Excessive recursion in compound glyph data";
 
   /* Pacify -Wmaybe-uninitialized.  */
   point = point2 = 0;
@@ -11760,30 +11852,27 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
              if (need_free)
                free_glyph (subglyph, dcontext);
 
-             return "Invalid anchor point";
+             return "Invalid anchor reference point";
            }
 
          if (!subglyph->compound)
            {
-             if (point2 >= subglyph->simple->number_of_points)
+             if (point2 >= subglyph->simple->number_of_points + 2)
                {
+                 /* If POINT2 is placed within a phantom point, use
+                    that.  */
+
                  if (need_free)
                    free_glyph (subglyph, dcontext);
 
-                 return "Invalid anchored point";
+                 return "Invalid component anchor point";
                }
 
-             /* Get the points and use them to compute the offsets.  */
-             xtemp = context->x_coordinates[point];
-             ytemp = context->y_coordinates[point];
-             x = (xtemp - subglyph->simple->x_coordinates[point2] * 64);
-             y = (ytemp - subglyph->simple->y_coordinates[point2] * 64);
-           }
-         else
-           {
              /* First, set offsets to 0, because it is not yet
-                possible to determine the position of the anchor
-                point in the child.  */
+                possible to ascertain the position of the anchor
+                point in the child.  That position cannot be
+                established prior to the completion of
+                grid-fitting.  */
              x = 0;
              y = 0;
 
@@ -11833,10 +11922,12 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
                }
 
              /* Figure out how many more points and contours are
-                needed.  Here, last_point is not the end of the
-                glyph's contours, as two phantom points are
-                included.  */
-             last_point = value->num_points;
+                needed.  While phantom points are not included within
+                the outline ultimately produced, they are temporarily
+                appended to the outline here, so as to enable
+                defer_offsets below to refer to them.  */
+             assert (value->num_points >= 2);
+             last_point = value->num_points - 2;
              number_of_contours = value->num_contours;
 
              /* Grow various arrays.  */
@@ -11868,8 +11959,8 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
 
              for (i = 0; i < last_point; ++i)
                {
-                 x_base[i] = value->x_points[i] + off_x + x;
-                 y_base[i] = value->y_points[i] + off_y + y;
+                 x_base[i] = value->x_points[i];
+                 y_base[i] = value->y_points[i];
                  flags_base[i] = value->flags[i];
                }
 
@@ -11878,11 +11969,35 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
                contour_base[i] = (contour_start
                                   + value->contour_end_points[i]);
 
+             /* Establish offsets for anchor points here.  It is
+                possible for glyph anchors to be set to phantom
+                points, whose coordinates cannot be established until
+                grid fitting completes.  */
+
+             if (defer_offsets)
+               {
+                 x = 0;
+                 y = 0;
+
+                 /* Assert the child anchor is within the confines of
+                    the zone.  */
+                 assert (point2 < value->num_points);
+
+                 /* Get the points and use them to compute the
+                    offsets.  */
+
+                 xtemp = context->x_coordinates[point];
+                 ytemp = context->y_coordinates[point];
+                 x = (xtemp - value->x_points[point2]);
+                 y = (ytemp - value->y_points[point2]);
+               }
+
              xfree (value);
 
-             /* Apply the transform to the points.  */
+             /* Apply the transform to the points, excluding phantom
+                points within.  */
              sfnt_transform_f26dot6 (component, x_base, y_base,
-                                     last_point, 0, 0);
+                                     last_point, x, y);
            }
        }
       else
@@ -11895,7 +12010,6 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
                                                   context, get_glyph,
                                                   free_glyph, hmtx, hhea,
                                                   maxp, &sub_metrics,
-                                                  off_x + x, off_y + y,
                                                   recursion_count + 1,
                                                   dcontext);
 
@@ -11907,22 +12021,19 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
              return error;
            }
 
-         /* When an anchor point is being used to translate the
-            glyph, and the subglyph in question is actually a
-            compound glyph, it is impossible to know which offset to
-            use until the compound subglyph has actually been
-            loaded.
-
-            As a result, the offset is calculated here, using the
-            points in the loaded child compound glyph.  But first, X
-            and Y must be reset to 0, as otherwise the translation
-            might be applied twice if defer_offsets is not set.  */
+         /* Anchor points for glyphs with instructions must be
+            computed after grid fitting completes.
 
-         x = 0;
-         y = 0;
+            As such, the offset is calculated here, using the points
+            in the loaded child compound glyph.  At present, CONTEXT
+            incorporates the two phantom points after the end of the
+            last component within SUBGLYPH.  */
 
          if (defer_offsets)
            {
+             x = 0;
+             y = 0;
+
              /* Renumber the non renumbered point2 to point into the
                 decomposed component.  */
              point2 += contour_start;
@@ -11936,7 +12047,7 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
                  if (need_free)
                    free_glyph (subglyph, dcontext);
 
-                 return "Invalid point2";
+                 return "Invalid anchor reference point";
                }
 
              /* Get the points and use them to compute the
@@ -11948,10 +12059,18 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
              y = (ytemp - context->y_coordinates[point2]);
            }
 
+         /* Subtract the two phantom points from context->num_points.
+            This behavior is correct, as only the subglyph's phantom
+            points may be provided as anchor points.  */
+         assert (context->num_points - contour_start >= 2);
+         context->num_points -= 2;
+
          sfnt_transform_f26dot6 (component,
                                  context->x_coordinates + contour_start,
                                  context->y_coordinates + contour_start,
-                                 contour_start - context->num_points,
+                                 /* Exclude phantom points from
+                                    transformations.  */
+                                 context->num_points - contour_start,
                                  x, y);
        }
 
@@ -11960,7 +12079,33 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph 
*glyph,
        free_glyph (subglyph, dcontext);
     }
 
-  /* Run the program for the entire compound glyph, if any.  */
+  /* Run the program for the entire compound glyph, if any.  CONTEXT
+     should not contain phantom points by this point, so append its
+     own.  */
+
+  /* Compute phantom points.  */
+  sfnt_compute_phantom_points (glyph, metrics, interpreter->scale,
+                              &phantom_point_1_x, &phantom_point_1_y,
+                              &phantom_point_2_x, &phantom_point_2_y);
+
+  /* Grow various arrays to include those points.  */
+  rc = sfnt_expand_compound_glyph_context (context,
+                                          /* Number of new contours
+                                             required.  */
+                                          0,
+                                          /* Number of new points
+                                             required.  */
+                                          2,
+                                          &x_base, &y_base,
+                                          &flags_base, &contour_base);
+
+  /* Store the phantom points within the compound glyph.  */
+  x_base[0] = phantom_point_1_x;
+  x_base[1] = phantom_point_2_x;
+  y_base[0] = phantom_point_1_y;
+  y_base[1] = phantom_point_2_y;
+  flags_base[0] = SFNT_POINT_PHANTOM;
+  flags_base[1] = SFNT_POINT_PHANTOM;
 
   if (glyph->compound->instruction_length)
     {
@@ -12026,8 +12171,7 @@ sfnt_interpret_compound_glyph (struct sfnt_glyph *glyph,
                                           state, &context,
                                           get_glyph, free_glyph,
                                           hmtx, hhea, maxp,
-                                          metrics, 0, 0, 0,
-                                          dcontext);
+                                          metrics, 0, dcontext);
 
   /* If an error occurs, free the data in the context and return.  */
 
@@ -15113,6 +15257,9 @@ struct sfnt_test_dcontext
   struct sfnt_glyf_table *glyf;
   struct sfnt_loca_table_short *loca_short;
   struct sfnt_loca_table_long *loca_long;
+  struct sfnt_hmtx_table *hmtx;
+  struct sfnt_hhea_table *hhea;
+  struct sfnt_maxp_table *maxp;
   struct sfnt_blend *blend;
 };
 
@@ -15179,6 +15326,18 @@ sfnt_test_free_glyph (struct sfnt_glyph *glyph, void 
*dcontext)
   sfnt_free_glyph (glyph);
 }
 
+static int
+sfnt_test_get_metrics (sfnt_glyph glyph, struct sfnt_glyph_metrics *metrics,
+                      void *dcontext)
+{
+  struct sfnt_test_dcontext *tables;
+
+  tables = dcontext;
+  return sfnt_lookup_glyph_metrics (glyph, -1, metrics,
+                                   tables->hmtx, tables->hhea,
+                                   NULL, tables->maxp);
+}
+
 static void
 sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y,
                void *dcontext)
@@ -19072,8 +19231,8 @@ main (int argc, char **argv)
       return 1;
     }
 
-#define FANCY_PPEM 12
-#define EASY_PPEM  12
+#define FANCY_PPEM 18
+#define EASY_PPEM  18
 
   interpreter = NULL;
   head = sfnt_read_head_table (fd, font);
@@ -19511,6 +19670,9 @@ main (int argc, char **argv)
              dcontext.glyf = glyf;
              dcontext.loca_short = loca_short;
              dcontext.loca_long = loca_long;
+             dcontext.hmtx = hmtx;
+             dcontext.hhea = hhea;
+             dcontext.maxp = maxp;
 
              if (instance && gvar)
                dcontext.blend = &blend;
@@ -19547,6 +19709,7 @@ main (int argc, char **argv)
                                        sfnt_test_curve_to,
                                        sfnt_test_get_glyph,
                                        sfnt_test_free_glyph,
+                                       sfnt_test_get_metrics,
                                        &dcontext))
                printf ("decomposition failure\n");
 
@@ -19565,6 +19728,7 @@ main (int argc, char **argv)
                                                  &metrics,
                                                  sfnt_test_get_glyph,
                                                  sfnt_test_free_glyph,
+                                                 sfnt_test_get_metrics,
                                                  &dcontext);
 
              clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
diff --git a/src/sfnt.h b/src/sfnt.h
index 365595fa37d..0fb67e918a6 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -15,8 +15,7 @@ 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, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #ifndef _SFNT_H_
 #define _SFNT_H_
@@ -624,16 +623,16 @@ struct sfnt_compound_glyph_component
 
   /* Various scale formats.  */
   union {
-    uint16_t scale;
+    int16_t scale;
     struct {
-      uint16_t xscale;
-      uint16_t yscale;
+      int16_t xscale;
+      int16_t yscale;
     } a;
     struct {
-      uint16_t xscale;
-      uint16_t scale01;
-      uint16_t scale10;
-      uint16_t yscale;
+      int16_t xscale;
+      int16_t scale01;
+      int16_t scale10;
+      int16_t yscale;
     } b;
   } u;
 };
@@ -689,9 +688,15 @@ typedef void (*sfnt_curve_to_proc) (struct sfnt_point,
                                    struct sfnt_point,
                                    void *);
 
+/* Forward declaration for use in sfnt_get_metrics_proc.  */
+struct sfnt_glyph_metrics;
+
 typedef struct sfnt_glyph *(*sfnt_get_glyph_proc) (sfnt_glyph, void *,
                                                   bool *);
 typedef void (*sfnt_free_glyph_proc) (struct sfnt_glyph *, void *);
+typedef int (*sfnt_get_metrics_proc) (sfnt_glyph,
+                                     struct sfnt_glyph_metrics *,
+                                     void *);
 
 
 
@@ -1373,6 +1378,7 @@ extern void sfnt_free_glyph (struct sfnt_glyph *);
   struct sfnt_glyph_metrics *, \
   sfnt_get_glyph_proc,         \
   sfnt_free_glyph_proc,                \
+  sfnt_get_metrics_proc,       \
   void *
 extern struct sfnt_glyph_outline *sfnt_build_glyph_outline (PROTOTYPE);
 #undef PROTOTYPE
diff --git a/src/sfntfont-android.c b/src/sfntfont-android.c
index de2a9253b57..53589078cda 100644
--- a/src/sfntfont-android.c
+++ b/src/sfntfont-android.c
@@ -15,8 +15,7 @@ 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, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <dirent.h>
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 6927b185721..c48339b6b66 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -15,8 +15,7 @@ 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, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
@@ -1104,7 +1103,12 @@ sfnt_enum_font (const char *file)
 
          subtables = sfnt_read_table_directory (fd);
 
-         if (!subtables)
+         if (!subtables
+             /* This value means that FD was pointing at a TTC
+                header.  Since FD should already have been moved to
+                the beginning of the TrueType header above, it
+                follows that the font format is invalid.  */
+             || (subtables == (struct sfnt_offset_subtable *) -1))
            continue;
 
          sfnt_enum_font_1 (fd, file, subtables,
@@ -1341,9 +1345,22 @@ sfntfont_read_cmap (struct sfnt_font_desc *desc,
   if (fd < 0)
     return;
 
+  /* Seek to the start of the font itself within its collection.  */
+
+  if (desc->offset
+      && lseek (fd, desc->offset, SEEK_SET) != desc->offset)
+    {
+      emacs_close (fd);
+      return;
+    }
+
   font = sfnt_read_table_directory (fd);
 
-  if (!font)
+  /* Return if FONT is a TrueType collection: the file pointer should
+     already have been moved to the start of the table directory if
+     so.  */
+
+  if (!font || (font == (struct sfnt_offset_subtable *) -1))
     {
       emacs_close (fd);
       return;
@@ -1786,7 +1803,7 @@ sfntfont_desc_to_entity (struct sfnt_font_desc *desc, int 
instance)
                      AREF (vector, 3));
       FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
                      AREF (vector, 4));
-      ASET (entity, FONT_ADSTYLE_INDEX, AREF (vector, 1));      
+      ASET (entity, FONT_ADSTYLE_INDEX, AREF (vector, 1));
     }
   else
     {
@@ -1926,6 +1943,11 @@ struct sfntfont_get_glyph_outline_dcontext
   /* glyf table.  */
   struct sfnt_glyf_table *glyf;
 
+  /* hmtx, hhea and maxp tables utilized to acquire glyph metrics.  */
+  struct sfnt_hmtx_table *hmtx;
+  struct sfnt_hhea_table *hhea;
+  struct sfnt_maxp_table *maxp;
+
   /* Variation settings, or NULL.  */
   struct sfnt_blend *blend;
 };
@@ -1970,6 +1992,23 @@ sfntfont_free_glyph (struct sfnt_glyph *glyph, void 
*dcontext)
   sfnt_free_glyph (glyph);
 }
 
+/* Return unscaled glyph metrics for the glyph designated by the ID
+   GLYPH within *METRICS, utilizing tables within DCONTEXT.
+
+   Value is 1 upon failure, 0 otherwise.  */
+
+static int
+sfntfont_get_metrics (sfnt_glyph glyph, struct sfnt_glyph_metrics *metrics,
+                     void *dcontext)
+{
+  struct sfntfont_get_glyph_outline_dcontext *tables;
+
+  tables = dcontext;
+  return sfnt_lookup_glyph_metrics (glyph, -1, metrics,
+                                   tables->hmtx, tables->hhea,
+                                   NULL, tables->maxp);
+}
+
 /* Dereference the outline OUTLINE.  Free it once refcount reaches
    0.  */
 
@@ -2095,6 +2134,9 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
   dcontext.loca_long = loca_long;
   dcontext.loca_short = loca_short;
   dcontext.glyf = glyf;
+  dcontext.hhea = hhea;
+  dcontext.hmtx = hmtx;
+  dcontext.maxp = maxp;
   dcontext.blend = (index != -1 ? blend : NULL);
 
   /* Now load the glyph's unscaled metrics into TEMP.  */
@@ -2143,12 +2185,14 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
                                            &temp,
                                            sfntfont_get_glyph,
                                            sfntfont_free_glyph,
+                                           sfntfont_get_metrics,
                                            &dcontext);
       else
        outline = sfnt_build_glyph_outline (glyph, scale,
                                            &temp,
                                            sfntfont_get_glyph,
                                            sfntfont_free_glyph,
+                                           sfntfont_get_metrics,
                                            &dcontext);
     }
 
@@ -2723,7 +2767,7 @@ sfnt_open_tables (struct sfnt_font_desc *desc)
   /* Read the offset subtable.  */
   subtable = sfnt_read_table_directory (fd);
 
-  if (!subtable)
+  if (!subtable || (subtable == (struct sfnt_offset_subtable *) -1))
     goto bail1;
 
   /* Read required tables.  This font backend is supposed to be used
@@ -3174,7 +3218,7 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
                          AREF (tem, 3));
          FONT_SET_STYLE (font_object, FONT_SLANT_INDEX,
                          AREF (tem, 4));
-         ASET (font_object, FONT_ADSTYLE_INDEX, Qnil);   
+         ASET (font_object, FONT_ADSTYLE_INDEX, Qnil);
        }
     }
 
diff --git a/src/sfntfont.h b/src/sfntfont.h
index df387512d0d..28267cdb1d6 100644
--- a/src/sfntfont.h
+++ b/src/sfntfont.h
@@ -15,8 +15,7 @@ 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, write to the Free Software Foundation,
-Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #ifndef _SFNTFONT_H_
 #define _SFNTFONT_H_
diff --git a/src/sysdep.c b/src/sysdep.c
index 0f8b70c8248..52fbfbd1eb1 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2972,14 +2972,16 @@ void
 close_output_streams (void)
 {
   /* Android comes with some kind of ``file descriptor sanitizer''
-     that aborts when stdout or stderr is closed.  */
+     that aborts when stdout or stderr is closed.  (bug#65340)
 
-#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+     Perform this unconditionally as long as __ANDROID__ is defined,
+     since the file descriptor sanitizer also applies to regular TTY
+     builds under Android.  */
+
+#ifdef __ANDROID__
   fflush (stderr);
   fflush (stdout);
-  return;
-#endif
-
+#else /* !__ANDROID__ */
   if (close_stream (stdout) != 0)
     {
       emacs_perror ("Write error to standard output");
@@ -2993,6 +2995,7 @@ close_output_streams (void)
             ? fflush (stderr) != 0 || ferror (stderr)
             : close_stream (stderr) != 0))
     _exit (EXIT_FAILURE);
+#endif /* __ANDROID__ */
 }
 
 #ifndef DOS_NT
diff --git a/src/termhooks.h b/src/termhooks.h
index d978819aeca..6bf507aae33 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -337,6 +337,12 @@ enum event_kind
      monitor configuration changed.  .timestamp gives the time on
      which the monitors changed.  */
   , MONITORS_CHANGED_EVENT
+
+#ifdef HAVE_HAIKU
+  /* In a NOTIFICATION_CLICKED_EVENT, .arg is an integer identifying
+     the notification that was clicked.  */
+  , NOTIFICATION_CLICKED_EVENT
+#endif /* HAVE_HAIKU */
 };
 
 /* Bit width of an enum event_kind tag at the start of structs and unions.  */
diff --git a/src/textconv.c b/src/textconv.c
index 60f3ba80577..57daa7e53b6 100644
--- a/src/textconv.c
+++ b/src/textconv.c
@@ -78,14 +78,14 @@ enum textconv_batch_edit_flags
 
 
 
-/* Copy the portion of the current buffer described by BEG, BEG_BYTE,
-   END, END_BYTE to the buffer BUFFER, which is END_BYTE - BEG_BYTEs
-   long.  */
+/* Copy the portion of the current buffer's text described by BEG,
+   BEG_BYTE, END, END_BYTE to the char * buffer BUFFER, which should
+   be at least END_BYTE - BEG_BYTEs long.  */
 
 static void
-copy_buffer (ptrdiff_t beg, ptrdiff_t beg_byte,
-            ptrdiff_t end, ptrdiff_t end_byte,
-            char *buffer)
+copy_buffer_text (ptrdiff_t beg, ptrdiff_t beg_byte,
+                 ptrdiff_t end, ptrdiff_t end_byte,
+                 char *buffer)
 {
   ptrdiff_t beg0, end0, beg1, end1, size;
 
@@ -130,7 +130,7 @@ get_mark (void)
   return -1;
 }
 
-/* Like Fselect_window.  However, if WINDOW is a mini buffer window
+/* Like Fselect_window.  However, if WINDOW is a minibuffer window
    but not the active minibuffer window, select its frame's selected
    window instead.  */
 
@@ -152,8 +152,8 @@ select_window (Lisp_Object window, Lisp_Object norecord)
 /* Perform the text conversion operation specified in QUERY and return
    the results.
 
-   Find the text between QUERY->position from point on F's selected
-   window and QUERY->factor times QUERY->direction from that
+   Find the text between QUERY->position from point on frame F's
+   selected window and QUERY->factor times QUERY->direction from that
    position.  Return it in QUERY->text.
 
    If QUERY->position is TYPE_MINIMUM (EMACS_INT) or EMACS_INT_MAX,
@@ -163,8 +163,9 @@ select_window (Lisp_Object window, Lisp_Object norecord)
    Then, either delete that text from the buffer if QUERY->operation
    is TEXTCONV_SUBSTITUTION, or return 0.
 
-   If FLAGS & TEXTCONV_SKIP_CONVERSION_REGION, then first move PT past
-   the conversion region in the specified direction if it is inside.
+   If FLAGS & TEXTCONV_SKIP_CONVERSION_REGION, then first move point
+   past the conversion region in the specified direction if it is
+   inside.
 
    Value is 0 if QUERY->operation was not TEXTCONV_SUBSTITUTION
    or if deleting the text was successful, and 1 otherwise.  */
@@ -291,7 +292,7 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
       break;
 
     case TEXTCONV_FORWARD_WORD:
-      /* Move forward by query->factor word.  */
+      /* Move forward by query->factor words.  */
       end = scan_words (pos, (EMACS_INT) query->factor);
 
       if (!end)
@@ -305,7 +306,7 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
       break;
 
     case TEXTCONV_BACKWARD_WORD:
-      /* Move backwards by query->factor word.  */
+      /* Move backwards by query->factor words.  */
       end = scan_words (pos, 0 - (EMACS_INT) query->factor);
 
       if (!end)
@@ -392,7 +393,7 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
 
   /* Return the string first.  */
   buffer = xmalloc (end_byte - pos_byte);
-  copy_buffer (pos, pos_byte, end, end_byte, buffer);
+  copy_buffer_text (pos, pos_byte, end, end_byte, buffer);
   query->text.text = buffer;
   query->text.length = end - pos;
   query->text.bytes = end_byte - pos_byte;
@@ -418,8 +419,8 @@ textconv_query (struct frame *f, struct 
textconv_callback_struct *query,
   return 0;
 }
 
-/* Update the overlay displaying the conversion area on F after a
-   change to the conversion region.  */
+/* Update the overlay displaying the conversion area on frame F after
+   a change to the conversion region.  */
 
 static void
 sync_overlay (struct frame *f)
@@ -449,7 +450,7 @@ sync_overlay (struct frame *f)
 }
 
 /* Record a change to the current buffer as a result of an
-   asynchronous text conversion operation on F.
+   asynchronous text conversion operation.
 
    Consult the doc string of `text-conversion-edits' for the meaning
    of BEG, END, and EPHEMERAL.  */
@@ -487,7 +488,7 @@ record_buffer_change (ptrdiff_t beg, ptrdiff_t end,
             Vtext_conversion_edits);
 }
 
-/* Reset F's text conversion state.  Delete any overlays or
+/* Reset text conversion state of frame F.  Delete any overlays or
    markers inside.  */
 
 void
@@ -562,9 +563,9 @@ restore_selected_window (Lisp_Object window)
 }
 
 /* Commit the given text in the composing region.  If there is no
-   composing region, then insert the text after F's selected window's
-   last point instead, unless the mark is active.  Finally, remove the
-   composing region.
+   composing region, then insert the text after frame F's selected
+   window's last point instead, unless the mark is active.  Finally,
+   remove the composing region.
 
    If the mark is active, delete the text between mark and point.
 
@@ -580,7 +581,7 @@ really_commit_text (struct frame *f, EMACS_INT position,
   ptrdiff_t wanted, start, end, mark;
   struct window *w;
 
-  /* If F's old selected window is no longer live, fail.  */
+  /* If F's old selected window is no longer alive, fail.  */
 
   if (!WINDOW_LIVE_P (f->old_selected_window))
     return;
@@ -769,7 +770,7 @@ really_finish_composing_text (struct frame *f, bool update)
   TEXTCONV_DEBUG ("conversion region removed");
 }
 
-/* Set the composing text on F to TEXT.  Then, move point to an
+/* Set the composing text on frame F to TEXT.  Then, move point to an
    appropriate position relative to POSITION, and call
    `compose_region_changed' in the text conversion interface should
    point not have been changed relative to F's old selected window's
@@ -927,8 +928,8 @@ really_set_composing_text (struct frame *f, ptrdiff_t 
position,
   unbind_to (count, Qnil);
 }
 
-/* Set the composing region to START by END.  Make it that it is not
-   already set.  */
+/* Set the composing region of frame F to START by END.  Make it if
+   it is not already set.  */
 
 static void
 really_set_composing_region (struct frame *f, ptrdiff_t start,
@@ -986,8 +987,8 @@ really_set_composing_region (struct frame *f, ptrdiff_t 
start,
 }
 
 /* Delete LEFT and RIGHT chars around point or the active mark,
-   whichever is larger, avoiding the composing region if
-   necessary.  */
+   whichever is larger, in frame F's selected window, avoiding the
+   composing region if necessary.  */
 
 static void
 really_delete_surrounding_text (struct frame *f, ptrdiff_t left,
@@ -1077,8 +1078,8 @@ really_delete_surrounding_text (struct frame *f, 
ptrdiff_t left,
   unbind_to (count, Qnil);
 }
 
-/* Update the interface with F's new point and mark.  If a batch edit
-   is in progress, schedule the update for when it finishes
+/* Update the interface with frame F's new point and mark.  If a batch
+   edit is in progress, schedule the update for when it finishes
    instead.  */
 
 static void
@@ -1097,10 +1098,10 @@ really_request_point_update (struct frame *f)
                                   current_buffer);
 }
 
-/* Set point in F to POSITION.  If MARK is not POSITION, activate the
-   mark and set MARK to that as well.
+/* Set point in frame F's selected window to POSITION.  If MARK is not
+   at POSITION, activate the mark and set MARK to that as well.
 
-   If it has not changed, signal an update through the text input
+   If point was not changed, signal an update through the text input
    interface, which is necessary for the IME to acknowledge that the
    change has completed.  */
 
@@ -1173,9 +1174,9 @@ struct complete_edit_check_context
   bool check;
 };
 
-/* If CONTEXT->check is false, then update W's ephemeral last point
-   and give it to the input method, the assumption being that an
-   editing operation signalled.  */
+/* Convert PTR to CONTEXT.  If CONTEXT->check is false, then update
+   CONTEXT->w's ephemeral last point and give it to the input method,
+   the assumption being that an editing operation signalled.  */
 
 static void
 complete_edit_check (void *ptr)
@@ -1429,8 +1430,8 @@ handle_pending_conversion_events (void)
   unbind_to (count, Qnil);
 }
 
-/* Start a ``batch edit'' in F.  During a batch edit, point_changed
-   will not be called until the batch edit ends.
+/* Start a ``batch edit'' in frame F.  During a batch edit,
+   point_changed will not be called until the batch edit ends.
 
    Process the actual operation in the event loop in keyboard.c; then,
    call `notify_conversion' in the text conversion interface with
@@ -1473,8 +1474,9 @@ end_batch_edit (struct frame *f, unsigned long counter)
   input_pending = true;
 }
 
-/* Insert the specified STRING into F's current buffer's composition
-   region, and set point to POSITION relative to STRING.
+/* Insert the specified STRING into frame F's selected-window's
+   buffer's composition region, and set point to POSITION relative to
+   STRING.
 
    If there is no composition region, use the active region instead.
    If that doesn't exist either, insert STRING after point.
@@ -1498,8 +1500,9 @@ commit_text (struct frame *f, Lisp_Object string,
   input_pending = true;
 }
 
-/* Remove the composition region and its overlay from F's current
-   buffer.  Leave the text being composed intact.
+/* Remove the composition region and its overlay from frame F's
+   selected-window's current buffer.  Leave the text being composed
+   intact.
 
    If UPDATE, call `compose_region_changed' after the region is
    removed.
@@ -1557,7 +1560,7 @@ set_composing_text (struct frame *f, Lisp_Object object,
 }
 
 /* Make the region between START and END the currently active
-   ``composing region''.
+   ``composing region'' on frame F.
 
    The ``composing region'' is a region of text in the buffer that is
    about to undergo editing by the input method.  */
@@ -1586,7 +1589,8 @@ set_composing_region (struct frame *f, ptrdiff_t start,
   input_pending = true;
 }
 
-/* Move point in F's selected buffer to POINT and maybe push MARK.
+/* Move point in frame F's selected-window's buffer to POINT and maybe
+   push MARK.
 
    COUNTER means the same as in `start_batch_edit'.  */
 
@@ -1611,8 +1615,8 @@ textconv_set_point_and_mark (struct frame *f, ptrdiff_t 
point,
   input_pending = true;
 }
 
-/* Delete LEFT and RIGHT characters around point in F's old selected
-   window.  */
+/* Delete LEFT and RIGHT characters around point in frame F's old
+   selected window.  */
 
 void
 delete_surrounding_text (struct frame *f, ptrdiff_t left,
@@ -1632,8 +1636,9 @@ delete_surrounding_text (struct frame *f, ptrdiff_t left,
   input_pending = true;
 }
 
-/* Request an immediate call to INTERFACE->point_changed with the new
-   details of F's region unless a batch edit is in progress.  */
+/* Request an immediate call to TEXT_INTERFACE->point_changed with the
+   new details of frame F's region unless a batch edit is in
+   progress.  */
 
 void
 request_point_update (struct frame *f, unsigned long counter)
@@ -1651,8 +1656,8 @@ request_point_update (struct frame *f, unsigned long 
counter)
   input_pending = true;
 }
 
-/* Request that text conversion on F pause until the keyboard buffer
-   becomes empty.
+/* Request that text conversion on frame F pause until the keyboard
+   buffer becomes empty.
 
    Use this function to ensure that edits associated with a keyboard
    event complete before the text conversion edits after the barrier
@@ -1674,19 +1679,18 @@ textconv_barrier (struct frame *f, unsigned long 
counter)
   input_pending = true;
 }
 
-/* Return N characters of text around point in F's old selected
+/* Return N characters of text around point in frame F's old selected
    window.
 
    If N is -1, return the text between point and mark instead, given
    that the mark is active.
 
-   Set *N to the actual number of characters returned, *START_RETURN
-   to the position of the first character returned, *START_OFFSET to
-   the offset of the lesser of mark and point within that text,
-   *END_OFFSET to the greater of mark and point within that text, and
-   *LENGTH to the actual number of characters returned, *BYTES to the
-   actual number of bytes returned, and *MARK_ACTIVE to whether or not
-   the mark is active.
+   Set *START_RETURN to the position of the first character returned,
+   *START_OFFSET to the offset of the lesser of mark and point within
+   that text, *END_OFFSET to the greater of mark and point within that
+   text, and *LENGTH to the actual number of characters returned,
+   *BYTES to the actual number of bytes returned, and *MARK_ACTIVE to
+   whether or not the mark is active.
 
    Value is NULL upon failure, and a malloced string upon success.  */
 
@@ -1763,8 +1767,7 @@ get_extracted_text (struct frame *f, ptrdiff_t n,
 
   /* Extract the text from the buffer.  */
   buffer = xmalloc (end_byte - start_byte);
-  copy_buffer (start, start_byte, end, end_byte,
-              buffer);
+  copy_buffer_text (start, start_byte, end, end_byte, buffer);
 
   /* Get the mark.  If it's not active, use PT.  */
 
@@ -1792,7 +1795,8 @@ get_extracted_text (struct frame *f, ptrdiff_t n,
   return buffer;
 }
 
-/* Return the text between the positions PT - LEFT and PT + RIGHT.  If
+/* Return the text between the positions pt - LEFT and pt + RIGHT,
+   where pt is the position of point in frame F's selected window.  If
    the mark is active, return the range of text relative to the bounds
    of the region instead.
 
@@ -1868,8 +1872,7 @@ get_surrounding_text (struct frame *f, ptrdiff_t left,
 
   /* Extract the text from the buffer.  */
   buffer = xmalloc (end_byte - start_byte);
-  copy_buffer (start, start_byte, end, end_byte,
-              buffer);
+  copy_buffer_text (start, start_byte, end, end_byte, buffer);
 
   /* Get the mark.  If it's not active, use PT.  */
 
@@ -1907,7 +1910,7 @@ conversion_disabled_p (void)
 /* Window system interface.  These are called from the rest of
    Emacs.  */
 
-/* Notice that F's selected window has been set from redisplay.
+/* Notice that frame F's selected window has been set from redisplay.
    Reset F's input method state.  */
 
 void
@@ -1934,11 +1937,11 @@ report_selected_window_change (struct frame *f)
   text_interface->reset (f);
 }
 
-/* Notice that the point in F's selected window's current buffer has
+/* Notice that point in frame F's selected window's current buffer has
    changed.
 
-   F is the frame whose selected window was changed, W is the window
-   in question, and BUFFER is that window's current buffer.
+   F is the frame whose selected window was changed, WINDOW is the
+   window in question, and BUFFER is that window's buffer.
 
    Tell the text conversion interface about the change; it will likely
    pass the information on to the system input method.  */
@@ -2081,10 +2084,11 @@ check_postponed_buffers (void)
 
 DEFUN ("set-text-conversion-style", Fset_text_conversion_style,
        Sset_text_conversion_style, 1, 2, 0,
-       doc: /* Set the text conversion style in the current buffer.
+       doc: /* Set the current buffer's text conversion style to VALUE.
 
-Set `text-conversion-style' to VALUE, then force any input method
-editing frame displaying this buffer to stop itself.
+After setting `text-conversion-style', force input methods
+editing in a selected window displaying this buffer on any frame
+to stop themselves.
 
 This can lead to a significant amount of time being taken by the input
 method resetting itself, so you should not use this function lightly;
@@ -2110,7 +2114,7 @@ replacement key sequence returned starts a new key 
sequence and makes
   if (!text_interface)
     return Qnil;
 
-  /* If there are any seleted windows displaying this buffer, reset
+  /* If there are any selected windows displaying this buffer, reset
      text conversion on their associated frames.  */
 
   if (buffer_window_count (current_buffer))
@@ -2137,8 +2141,11 @@ replacement key sequence returned starts a new key 
sequence and makes
 
          if (WINDOW_LIVE_P (f->old_selected_window)
              && FRAME_WINDOW_P (f)
-             && EQ (XWINDOW (f->old_selected_window)->contents,
-                    buffer))
+             && (EQ (XWINDOW (f->old_selected_window)->contents,
+                     buffer)
+                 /* Always reset the text conversion style of the
+                    selected frame.  */
+                 || (f == SELECTED_FRAME ())))
            {
              block_input ();
              reset_frame_state (f);
@@ -2164,13 +2171,13 @@ syms_of_textconv (void)
          "overriding-text-conversion-style");
 
   DEFVAR_LISP ("text-conversion-edits", Vtext_conversion_edits,
-    doc: /* List of buffers that were last edited as a result of text 
conversion.
+    doc: /* List of buffers that were last edited as result of text conversion.
 
 This list can be used while handling a `text-conversion' event to
 determine which changes have taken place.
 
-Each element of the list describes a single edit in a buffer, of the
-form:
+Each element of the list describes a single edit in a buffer, and
+is of the form:
 
     (BUFFER BEG END EPHEMERAL)
 
@@ -2186,8 +2193,8 @@ as indenting or automatically filling text, should not 
take place.
 Otherwise, it is either a string containing text that was inserted,
 text deleted before point, or nil if text was deleted after point.
 
-The list contents are ordered later edits first, so you must iterate
-through the list in reverse.  */);
+The list contents are ordered in the reverse order of editing, i.e.
+the latest edit first, so you must iterate through the list in reverse.  */);
   Vtext_conversion_edits = Qnil;
 
   DEFVAR_LISP ("overriding-text-conversion-style",
@@ -2195,14 +2202,14 @@ through the list in reverse.  */);
     doc: /* Non-buffer local version of `text-conversion-style'.
 
 If this variable is the symbol `lambda', it means to consult the
-buffer local variable `text-conversion-style' to determine whether or
-not to activate the input method.  Otherwise, its value is used in
-preference to any buffer local value of `text-conversion-style'.  */);
+buffer-local value of `text-conversion-style' to determine whether or
+not to activate the input method.  Otherwise, the value is used in
+preference to any buffer-local value of `text-conversion-style'.  */);
   Voverriding_text_conversion_style = Qlambda;
 
   DEFVAR_LISP ("text-conversion-face", Vtext_conversion_face,
     doc: /* Face in which to display temporary edits by an input method.
-nil means to display no indication of a temporary edit.  */);
+The value nil means to display no indication of a temporary edit.  */);
   Vtext_conversion_face = Qunderline;
 
   defsubr (&Sset_text_conversion_style);
diff --git a/src/xdisp.c b/src/xdisp.c
index d055bb3bf6a..8970d5aaaf2 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8339,9 +8339,17 @@ get_next_display_element (struct it *it)
       && success_p
       && FRAME_WINDOW_P (it->f))
     {
-      struct face *face = FACE_FROM_ID (it->f, it->face_id);
+      struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
 
-      if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
+      /* It shouldn't happen, ever, that FACE is NULL here, but
+         evidently some faulty fonts/fontsets can sometimes cause it.
+         In that case, we punt and consider the stuff undisplayable.  */
+      if (!face)
+       {
+         it->what = IT_GLYPHLESS;
+         it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
+       }
+      else if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
        {
          /* Automatic composition with glyph-string.   */
          Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
@@ -15588,7 +15596,7 @@ redisplay_tool_bar (struct frame *f)
                  h = (extra + rows - 1) / rows;
                  extra -= h;
                }
-         
+
              display_tool_bar_line (&it, height + h);
            }
        }
@@ -27908,6 +27916,8 @@ are the selected window and the WINDOW's buffer).  */)
   if (NILP (buffer))
     buffer = w->contents;
   CHECK_BUFFER (buffer);
+  if (!BUFFER_LIVE_P (XBUFFER (buffer)))
+    error ("Attempt to format a mode line for a dead buffer");
 
   /* Make formatting the modeline a non-op when noninteractive, otherwise
      there will be problems later caused by a partially initialized frame.  */
@@ -32098,9 +32108,12 @@ produce_glyphless_glyph (struct it *it, bool 
for_no_font, Lisp_Object acronym)
   int len;
 
   /* Get the metrics of the base font.  We always refer to the current
-     ASCII face.  */
-  face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
-  font = face->font ? face->font : FRAME_FONT (it->f);
+     ASCII face, but if some faulty setup of fontsets causes that to
+     be NULL, we fall back to the frame's default font.  */
+  face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
+  if (face)
+    face = face->ascii_face;
+  font = (face && face->font) ? face->font : FRAME_FONT (it->f);
   normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
   it->ascent += font->baseline_offset;
   it->descent -= font->baseline_offset;
@@ -33790,6 +33803,7 @@ display_and_set_cursor (struct window *w, bool on,
      completely erased, to avoid the extra work of erasing the cursor
      twice.  In other words, phys_cursor_on_p can be true and the cursor
      still not be visible, or it has only been partly erased.  */
+
   if (on)
     {
       w->phys_cursor_ascent = glyph_row->ascent;
@@ -33803,9 +33817,15 @@ display_and_set_cursor (struct window *w, bool on,
       w->phys_cursor.vpos = vpos;
     }
 
-  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
-                                     new_cursor_type, new_cursor_width,
-                                     on, active_cursor);
+  /* If make_cursor_line_fully_visible is nil and the row is in fact
+     vscrolled out of the window, then glyph_row->y +
+     glyph_row->height will be less than or equal to 0.  Eschew
+     displaying the cursor in that case.  */
+
+  if (MATRIX_ROW_BOTTOM_Y (glyph_row) > 0)
+    FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
+                                      new_cursor_type, new_cursor_width,
+                                      on, active_cursor);
 }
 
 
diff --git a/src/xmenu.c b/src/xmenu.c
index 6d32aa3e078..2d405d54deb 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1617,6 +1617,7 @@ popup_selection_callback (Widget widget, LWLIB_ID id, 
XtPointer client_data)
 
 
 #ifdef HAVE_XINPUT2
+
 static void
 prepare_for_entry_into_toolkit_menu (struct frame *f)
 {
@@ -1680,6 +1681,19 @@ leave_toolkit_menu (void *data)
   XISetMask (m, XI_Enter);
   XISetMask (m, XI_Leave);
 
+#ifdef HAVE_XINPUT2_4
+  /* Select for gesture events.  Emacs selects for gesture events from
+     all master devices on non-GTK3 builds, so that event mask is also
+     clobbered by prepare_for_entry_into_toolkit_menu.  (bug#65129) */
+
+  if (dpyinfo->xi2_version >= 4)
+    {
+      XISetMask (m, XI_GesturePinchBegin);
+      XISetMask (m, XI_GesturePinchUpdate);
+      XISetMask (m, XI_GesturePinchEnd);
+    }
+#endif /* HAVE_XINPUT2_4 */
+
   FOR_EACH_FRAME (tail, frame)
     {
       f = XFRAME (frame);
@@ -1691,7 +1705,8 @@ leave_toolkit_menu (void *data)
                        &mask, 1);
     }
 }
-#endif
+
+#endif /* HAVE_XINPUT2 */
 
 /* ID is the LWLIB ID of the dialog box.  */
 
diff --git a/src/xterm.c b/src/xterm.c
index f454733c659..6a1642ff56e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1215,6 +1215,8 @@ static void x_set_input_focus (struct x_display_info *, 
Window, Time);
 static void x_scroll_bar_redraw (struct scroll_bar *);
 #endif
 
+
+
 /* Global state maintained during a drag-and-drop operation.  */
 
 /* Flag that indicates if a drag-and-drop operation is in progress.  */
@@ -1543,6 +1545,8 @@ static struct x_client_list_window *x_dnd_toplevels;
    for `x_dnd_toplevels' to work.  */
 static bool x_dnd_use_toplevels;
 
+
+
 /* Motif drag-and-drop protocol support.  */
 
 /* Pointer to a variable which stores whether or not an X error
@@ -2914,6 +2918,11 @@ x_dnd_send_xm_leave_for_drop (struct x_display_info 
*dpyinfo,
                                     wdesc, &lmsg);
 }
 
+
+
+/* Drag-and-drop and XDND protocol primitives employed by the event
+   loop.  */
+
 static void
 x_dnd_free_toplevels (bool display_alive)
 {
@@ -3259,9 +3268,10 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
       if (!xm_property_reply)
        free (error);
 
-      extent_property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
-                                                     
extent_property_cookies[i],
-                                                     &error);
+      extent_property_reply
+       = xcb_get_property_reply (dpyinfo->xcb_connection,
+                                 extent_property_cookies[i],
+                                 &error);
 
       if (!extent_property_reply)
        free (error);
@@ -3342,7 +3352,8 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
 #else
          if (xm_property_reply
              && xm_property_reply->format == 8
-             && xm_property_reply->type == 
dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO
+             && (xm_property_reply->type
+                 == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO)
              && xcb_get_property_value_length (xm_property_reply) >= 4)
            {
              xmdata = xcb_get_property_value (xm_property_reply);
@@ -3391,9 +3402,10 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
                  XFree (rects);
                }
 #else
-             bounding_rect_reply = xcb_shape_get_rectangles_reply 
(dpyinfo->xcb_connection,
-                                                                   
bounding_rect_cookies[i],
-                                                                   &error);
+             bounding_rect_reply
+               = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
+                                                 bounding_rect_cookies[i],
+                                                 &error);
 
              if (bounding_rect_reply)
                {
@@ -3404,7 +3416,8 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
                                                 * sizeof *tem->bounding_rects);
                  tem->n_bounding_rects = 0;
 
-                 for (; bounding_rect_iterator.rem; xcb_rectangle_next 
(&bounding_rect_iterator))
+                 for (; bounding_rect_iterator.rem;
+                      xcb_rectangle_next (&bounding_rect_iterator))
                    {
                      tem->bounding_rects[tem->n_bounding_rects].x
                        = bounding_rect_iterator.data->x;
@@ -3429,9 +3442,10 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
                  || (dpyinfo->xshape_major == 1
                      && dpyinfo->xshape_minor >= 1))
                {
-                 input_rect_reply = xcb_shape_get_rectangles_reply 
(dpyinfo->xcb_connection,
-                                                                    
input_rect_cookies[i],
-                                                                    &error);
+                 input_rect_reply
+                   = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
+                                                     input_rect_cookies[i],
+                                                     &error);
 
                  if (input_rect_reply)
                    {
@@ -3442,7 +3456,8 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
                                                  * sizeof *tem->input_rects);
                      tem->n_input_rects = 0;
 
-                     for (; input_rect_iterator.rem; xcb_rectangle_next 
(&input_rect_iterator))
+                     for (; input_rect_iterator.rem;
+                          xcb_rectangle_next (&input_rect_iterator))
                        {
                          tem->input_rects[tem->n_input_rects].x
                            = input_rect_iterator.data->x;
@@ -3509,17 +3524,25 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
          if (tem->n_input_rects == -1
              && tem->n_bounding_rects == 1
 #ifdef USE_XCB
-             && tem->bounding_rects[0].width == (geometry_reply->width
-                                                 + 
geometry_reply->border_width)
-             && tem->bounding_rects[0].height == (geometry_reply->height
-                                                  + 
geometry_reply->border_width)
-             && tem->bounding_rects[0].x == -geometry_reply->border_width
-             && tem->bounding_rects[0].y == -geometry_reply->border_width
+             && (tem->bounding_rects[0].width
+                 == (geometry_reply->width
+                     + geometry_reply->border_width))
+             && (tem->bounding_rects[0].height
+                 == (geometry_reply->height
+                     + geometry_reply->border_width))
+             && (tem->bounding_rects[0].x
+                 == -geometry_reply->border_width)
+             && (tem->bounding_rects[0].y
+                 == -geometry_reply->border_width)
 #else
-             && tem->bounding_rects[0].width == attrs.width + 
attrs.border_width
-             && tem->bounding_rects[0].height == attrs.height + 
attrs.border_width
-             && tem->bounding_rects[0].x == -attrs.border_width
-             && tem->bounding_rects[0].y == -attrs.border_width
+             && (tem->bounding_rects[0].width
+                 == attrs.width + attrs.border_width)
+             && (tem->bounding_rects[0].height
+                 == attrs.height + attrs.border_width)
+             && (tem->bounding_rects[0].x
+                 == -attrs.border_width)
+             && (tem->bounding_rects[0].y
+                 == -attrs.border_width)
 #endif
              )
            {
@@ -3542,9 +3565,10 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
 #ifdef HAVE_XCB_SHAPE
          if (dpyinfo->xshape_supported_p)
            {
-             bounding_rect_reply = xcb_shape_get_rectangles_reply 
(dpyinfo->xcb_connection,
-                                                                   
bounding_rect_cookies[i],
-                                                                   &error);
+             bounding_rect_reply
+               = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
+                                                 bounding_rect_cookies[i],
+                                                 &error);
 
              if (bounding_rect_reply)
                free (bounding_rect_reply);
@@ -3559,9 +3583,10 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
                  || (dpyinfo->xshape_major == 1
                      && dpyinfo->xshape_minor >= 1)))
            {
-             input_rect_reply = xcb_shape_get_rectangles_reply 
(dpyinfo->xcb_connection,
-                                                                
input_rect_cookies[i],
-                                                                &error);
+             input_rect_reply
+               = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
+                                                 input_rect_cookies[i],
+                                                 &error);
 
              if (input_rect_reply)
                free (input_rect_reply);
@@ -3784,8 +3809,10 @@ x_dnd_get_target_window_1 (struct x_display_info 
*dpyinfo,
              if (tem->n_input_rects == -1
                  || x_dnd_get_target_window_2 (tem->input_rects,
                                                tem->n_input_rects,
-                                               tem->border_width + root_x - 
tem->x,
-                                               tem->border_width + root_y - 
tem->y))
+                                               (tem->border_width
+                                                + root_x - tem->x),
+                                               (tem->border_width
+                                                + root_y - tem->y)))
                {
                  chosen = tem;
                  break;
@@ -3872,11 +3899,12 @@ x_dnd_get_wm_state_and_proto (struct x_display_info 
*dpyinfo,
                                        (xcb_window_t) window,
                                        (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
                                        XA_WINDOW, 0, 1);
-  xm_style_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
-                                     (xcb_window_t) window,
-                                     (xcb_atom_t) 
dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
-                                     (xcb_atom_t) 
dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
-                                     0, 4);
+  xm_style_cookie
+    = xcb_get_property (dpyinfo->xcb_connection, 0,
+                       (xcb_window_t) window,
+                       (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
+                       (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
+                       0, 4);
 
   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
                                  wmstate_cookie, &error);
@@ -4920,6 +4948,11 @@ x_dnd_cleanup_drag_and_drop (void *frame)
   x_restore_events_after_dnd (f, &x_dnd_old_window_attrs);
 }
 
+
+
+/* Primitives for simplified drag-and-drop tracking when items are
+   being dragged between frames comprising the same Emacs session.  */
+
 static void
 x_dnd_note_self_position (struct x_display_info *dpyinfo, Window target,
                          unsigned short root_x, unsigned short root_y)
@@ -5050,6 +5083,10 @@ x_dnd_note_self_drop (struct x_display_info *dpyinfo, 
Window target,
   kbd_buffer_store_event (&ie);
 }
 
+
+
+/* Miscellaneous X event and graphics extension functions.  */
+
 /* Flush display of frame F.  */
 
 static void
@@ -5134,28 +5171,9 @@ record_event (char *locus, int type)
 
 #endif
 
-#ifdef HAVE_XINPUT2
-bool
-xi_frame_selected_for (struct frame *f, unsigned long event)
-{
-  XIEventMask *masks;
-  int i;
-
-  masks = FRAME_X_OUTPUT (f)->xi_masks;
-
-  if (!masks)
-    return false;
-
-  for (i = 0; i < FRAME_X_OUTPUT (f)->num_xi_masks; ++i)
-    {
-      if (masks[i].mask_len >= XIMaskLen (event)
-         && XIMaskIsSet (masks[i].mask, event))
-       return true;
-    }
+
 
-  return false;
-}
-#endif
+/* Miscelaneous event handling functions.  */
 
 static void
 x_toolkit_position (struct frame *f, int x, int y,
@@ -5300,10 +5318,36 @@ x_extension_initialize (struct x_display_info *dpyinfo)
 
 #endif /* HAVE_CAIRO */
 
+
+
+/* X input extension device and event mask management functions.  */
+
 #ifdef HAVE_XINPUT2
 
+bool
+xi_frame_selected_for (struct frame *f, unsigned long event)
+{
+  XIEventMask *masks;
+  int i;
+
+  masks = FRAME_X_OUTPUT (f)->xi_masks;
+
+  if (!masks)
+    return false;
+
+  for (i = 0; i < FRAME_X_OUTPUT (f)->num_xi_masks; ++i)
+    {
+      if (masks[i].mask_len >= XIMaskLen (event)
+         && XIMaskIsSet (masks[i].mask, event))
+       return true;
+    }
+
+  return false;
+}
+
 /* Convert XI2 button state IN to a standard X button modifier
    mask, and place it in OUT.  */
+
 static void
 xi_convert_button_state (XIButtonState *in, unsigned int *out)
 {
@@ -5325,7 +5369,7 @@ xi_convert_button_state (XIButtonState *in, unsigned int 
*out)
 
 #ifdef USE_GTK
 static
-#endif
+#endif /* USE_GTK */
 unsigned int
 xi_convert_event_state (XIDeviceEvent *xev)
 {
@@ -5351,12 +5395,13 @@ xi_convert_event_keyboard_state (XIDeviceEvent *xev)
 }
 
 /* Free all XI2 devices on DPYINFO.  */
+
 static void
 x_free_xi_devices (struct x_display_info *dpyinfo)
 {
 #ifdef HAVE_XINPUT2_2
   struct xi_touch_point_t *tem, *last;
-#endif
+#endif /* HAVE_XINPUT2_2 */
 
   block_input ();
 
@@ -5366,7 +5411,7 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
        {
 #ifdef HAVE_XINPUT2_1
          xfree (dpyinfo->devices[i].valuators);
-#endif
+#endif /* HAVE_XINPUT2_1 */
 
 #ifdef HAVE_XINPUT2_2
          tem = dpyinfo->devices[i].touchpoints;
@@ -5376,7 +5421,7 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
              tem = tem->next;
              xfree (last);
            }
-#endif
+#endif /* HAVE_XINPUT2_2 */
        }
 
       xfree (dpyinfo->devices);
@@ -5441,7 +5486,7 @@ xi_populate_scroll_valuator (struct xi_device_t *device,
   valuator->number = info->number;
 }
 
-#endif
+#endif /* HAVE_XINPUT2_1 */
 
 static void
 xi_populate_device_from_info (struct x_display_info *dpyinfo,
@@ -5453,14 +5498,14 @@ xi_populate_device_from_info (struct x_display_info 
*dpyinfo,
   int actual_valuator_count, c;
   XIScrollClassInfo *info;
   XIValuatorClassInfo *valuator_info;
-#endif
+#endif /* HAVE_XINPUT2_1 */
 #ifdef HAVE_XINPUT2_2
   XITouchClassInfo *touch_info;
-#endif
+#endif /* HAVE_XINPUT2_2 */
 
 #ifdef HAVE_XINPUT2_1
   USE_SAFE_ALLOCA;
-#endif
+#endif /* HAVE_XINPUT2_1 */
 
   /* Initialize generic information about the device: its ID, which
      buttons are currently pressed and thus presumably actively
@@ -5917,8 +5962,12 @@ xi_reset_scroll_valuators_for_device_id (struct 
x_display_info *dpyinfo,
 }
 
 #endif /* HAVE_XINPUT2_1 */
+#endif /* HAVE_XINPUT2 */
 
-#endif
+
+
+/* Cairo context, X rendering extension, and GC auxiliary data
+   management functions.  */
 
 #ifdef USE_CAIRO
 
@@ -6404,6 +6453,7 @@ x_cr_export_frames (Lisp_Object frames, 
cairo_surface_type_t surface_type)
 #endif /* USE_CAIRO */
 
 #if defined HAVE_XRENDER
+
 void
 x_xr_apply_ext_clip (struct frame *f, GC gc)
 {
@@ -6427,7 +6477,8 @@ x_xr_reset_ext_clip (struct frame *f)
                        FRAME_X_PICTURE (f),
                        CPClipMask, &attrs);
 }
-#endif
+
+#endif /* HAVE_XRENDER */
 
 static void
 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
@@ -6631,6 +6682,9 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, 
int width, int height,
 #endif
 }
 
+
+
+/* Graphics primitives.  */
 
 static void
 x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
@@ -6923,6 +6977,8 @@ x_set_frame_alpha (struct frame *f)
   x_stop_ignoring_errors (dpyinfo);
 }
 
+
+
 /***********************************************************************
                    Starting and ending an update
  ***********************************************************************/
@@ -7618,6 +7674,8 @@ XTbuffer_flipping_unblocked_hook (struct frame *f)
 }
 #endif
 
+
+
 /**
  * x_clear_under_internal_border:
  *
diff --git a/test/Makefile.in b/test/Makefile.in
index e2a14c4dd92..4e53efeb9a8 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -326,6 +326,9 @@ check-all: mostlyclean check-no-automated-subdir
 check-maybe: check-no-automated-subdir
        @${MAKE} check-doit SELECTOR="${SELECTOR_ACTUAL}"
 
+check-byte-compile:
+       @${MAKE} $(ELFILES:.el=.elc)
+
 ## Run the tests.
 .PHONY: check-doit
 ## We can't put LOGFILES as prerequisites, because that would stop the
diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el
index ef915e5fc5b..ab1a437b303 100644
--- a/test/lisp/auth-source-tests.el
+++ b/test/lisp/auth-source-tests.el
@@ -435,5 +435,25 @@ machine c1 port c2 user c3 password c4\n"
             '((("machine" . "XM") ("login" . "XL") ("password" . "XP"))
               (("machine" . "YM") ("login" . "YL") ("password" . "YP")))))))
 
+(ert-deftest test-macos-keychain-search ()
+  "Test if the constructed command line arglist is correct."
+  (let ((auth-sources '(macos-keychain-internet macos-keychain-generic)))
+    ;; Redefine `call-process' to check command line arguments.
+    (cl-letf (((symbol-function 'call-process)
+               (lambda (_program _infile _destination _display
+                                 &rest args)
+                 ;; Arguments must be all strings
+                 (should (cl-every #'stringp args))
+                 ;; Argument number should be even
+                 (should (cl-evenp (length args)))
+                 (should (cond ((string= (car args) "find-internet-password")
+                                (let ((protocol (cl-member "-r" args :test 
#'string=)))
+                                  (if protocol
+                                      (= 4 (length (cadr protocol)))
+                                    t)))
+                               ((string= (car args) "find-generic-password")
+                                t))))))
+      (auth-source-search :user '("a" "b") :host '("example.org") :port 
'("irc" "ftp" "https")))))
+
 (provide 'auth-source-tests)
 ;;; auth-source-tests.el ends here
diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el
index 41c47e5332c..5b11dd950ba 100644
--- a/test/lisp/calc/calc-tests.el
+++ b/test/lisp/calc/calc-tests.el
@@ -698,8 +698,8 @@ An existing calc stack is reused, otherwise a new one is 
created."
                      (calc-tests--not x w)))
 
       (dolist (n '(0 1 4 16 32 -1 -4 -16 -32))
-        (equal (calcFunc-clip x n)
-               (calc-tests--clip x n)))
+        (should (equal (calcFunc-clip x n)
+                       (calc-tests--clip x n))))
 
       (dolist (y '(0 1 #x1234 #x8000 #xabcd #xffff
                      #x12345678 #xabcdef12 #x80000000 #xffffffff
diff --git a/test/lisp/calculator-tests.el b/test/lisp/calculator-tests.el
index 7ac3b9ba37a..8786d5c6c3b 100644
--- a/test/lisp/calculator-tests.el
+++ b/test/lisp/calculator-tests.el
@@ -47,5 +47,11 @@
        (let ((calculator-input-radix nil))
          (should (equal (calculator-string-to-number str) expected)))))))
 
+(ert-deftest calculator-expt ()
+  (should (= (calculator-expt 2 -1) 0.5))
+  (should (= (calculator-expt -2 2) 4))
+  (should (= (calculator-expt -2 3) -8))
+  (should (= (calculator-expt 2 64) 18446744073709551616)))
+
 (provide 'calculator-tests)
 ;;; calculator-tests.el ends here
diff --git a/test/lisp/cus-edit-tests.el b/test/lisp/cus-edit-tests.el
index eca35d7c96a..3a788f19745 100644
--- a/test/lisp/cus-edit-tests.el
+++ b/test/lisp/cus-edit-tests.el
@@ -92,5 +92,48 @@
             (buffer-substring-no-properties (point-min) (point-max)))))
     (should (string-search "Value `:foo' does not match type number"
                            warn-txt))))
+
+(defcustom cus-edit-test-bug63290-option nil
+  "Choice option for testing Bug#63290."
+  :type '(choice (alist
+                  :key-type (string :tag "key")
+                  :value-type (string :tag "value"))
+                 (const :tag "auto" auto)))
+
+(defcustom cus-edit-test-bug63290-option2 'some
+  "Choice option for testing Bug#63290."
+  :type '(choice
+          (const :tag "some" some)
+          (alist
+           :key-type (string :tag "key")
+           :value-type (string :tag "value"))))
+
+(ert-deftest cus-edit-test-bug63290 ()
+  "Test that changing a choice value back to an alist respects its nil value."
+  (customize-variable 'cus-edit-test-bug63290-option)
+  (search-forward "Value")
+  ;; Simulate changing the value.
+  (let* ((choice (widget-at))
+         (args (widget-get choice :args))
+         (list-opt (car (widget-get choice :children)))
+         (const-opt (nth 1 args)))
+    (widget-put choice :explicit-choice const-opt)
+    (widget-value-set choice (widget-default-get const-opt))
+    (widget-put choice :explicit-choice list-opt)
+    (widget-value-set choice (widget-default-get list-opt)))
+  ;; No empty key/value pairs should show up.
+  (should-not (search-forward "key" nil t))
+  (customize-variable 'cus-edit-test-bug63290-option2)
+  (search-forward "Value")
+  ;; Simulate changing the value.
+  (let* ((choice (widget-at))
+         (args (widget-get choice :args))
+         (const-opt (car (widget-get choice :children)))
+         (list-opt (nth 1 args)))
+    (widget-put choice :explicit-choice list-opt)
+    (widget-value-set choice (widget-default-get list-opt)))
+  ;; No empty key/value pairs should show up.
+  (should-not (search-forward "key" nil t)))
+
 (provide 'cus-edit-tests)
 ;;; cus-edit-tests.el ends here
diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el
index 0701b229edd..8f2b9af09c0 100644
--- a/test/lisp/dired-tests.el
+++ b/test/lisp/dired-tests.el
@@ -241,12 +241,12 @@
             (let ((buffers (find-file (concat (file-name-as-directory test-dir)
                                               "*")
                                       t)))
+              (setq allbufs (append buffers allbufs))
               (dolist (buf buffers)
                 (let ((pt (with-current-buffer buf (point))))
                   (switch-to-buffer (find-file-noselect test-dir))
                   (find-file (buffer-name buf))
-                  (should (equal (point) pt))))
-              (append buffers allbufs)))
+                  (should (equal (point) pt))))))
         (dolist (buf allbufs)
           (when (buffer-live-p buf) (kill-buffer buf)))))))
 
diff --git 
a/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-missing-keyword-arg.el
 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-missing-keyword-arg.el
new file mode 100644
index 00000000000..9369e78ff54
--- /dev/null
+++ 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-missing-keyword-arg.el
@@ -0,0 +1,3 @@
+;;; -*- lexical-binding: t -*-
+(defun foo ()
+  (make-process :name "ls"))
diff --git 
a/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-missing-keyword-value.el
 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-missing-keyword-value.el
new file mode 100644
index 00000000000..4226349afef
--- /dev/null
+++ 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-missing-keyword-value.el
@@ -0,0 +1,3 @@
+;;; -*- lexical-binding: t -*-
+(defun foo ()
+  (make-process :name "ls" :command))
diff --git 
a/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-repeated-keyword-arg.el
 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-repeated-keyword-arg.el
new file mode 100644
index 00000000000..18250f14ee9
--- /dev/null
+++ 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-repeated-keyword-arg.el
@@ -0,0 +1,3 @@
+;;; -*- lexical-binding: t -*-
+(defun foo ()
+  (make-process :name "ls" :command "ls" :name "ls"))
diff --git 
a/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-unknown-keyword-arg.el
 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-unknown-keyword-arg.el
new file mode 100644
index 00000000000..4721035780b
--- /dev/null
+++ 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-make-process-unknown-keyword-arg.el
@@ -0,0 +1,4 @@
+;;; -*- lexical-binding: t -*-
+(defun foo ()
+  (make-process :name "ls" :command "ls"
+                :coding-system 'binary))
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el 
b/test/lisp/emacs-lisp/bytecomp-tests.el
index 246ffff532f..26325c1ef11 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -677,16 +677,18 @@ inner loops respectively."
                      (list x (funcall g))))))))
       (funcall (funcall f 'b)))
     (let ((f (lambda (x)
-               (let ((g (lambda () x))
-                     (h (lambda () (setq x (list x x)))))
-                 (let ((x 'a))
-                   (list x (funcall g) (funcall h)))))))
+               (lambda ()
+                 (let ((g (lambda () x))
+                       (h (lambda () (setq x (list x x)))))
+                   (let ((x 'a))
+                     (list x (funcall g) (funcall h))))))))
       (funcall (funcall f 'b)))
     (let ((f (lambda (x)
-               (let ((g (lambda () x))
-                     (h (lambda () (setq x (list x x)))))
-                 (let* ((x 'a))
-                   (list x (funcall g) (funcall h)))))))
+               (lambda ()
+                 (let ((g (lambda () x))
+                       (h (lambda () (setq x (list x x)))))
+                   (let* ((x 'a))
+                     (list x (funcall g) (funcall h))))))))
       (funcall (funcall f 'b)))
 
     ;; Test constant-propagation of access to captured variables.
@@ -785,6 +787,9 @@ inner loops respectively."
     (let ((x 0))
       (list (= (setq x 1))
             x))
+    ;; Aristotelian identity optimisation
+    (let ((x (bytecomp-test-identity 1)))
+      (list (eq x x) (eql x x) (equal x x)))
     )
   "List of expressions for cross-testing interpreted and compiled code.")
 
@@ -1199,6 +1204,22 @@ byte-compiled.  Run with dynamic binding."
  "nowarn-inline-after-defvar.el"
  "Lexical argument shadows" 'reverse)
 
+(bytecomp--define-warning-file-test
+ "warn-make-process-missing-keyword-arg.el"
+ "called without required keyword argument :command")
+
+(bytecomp--define-warning-file-test
+ "warn-make-process-unknown-keyword-arg.el"
+ "called with unknown keyword argument :coding-system")
+
+(bytecomp--define-warning-file-test
+ "warn-make-process-repeated-keyword-arg.el"
+ "called with repeated keyword argument :name")
+
+(bytecomp--define-warning-file-test
+ "warn-make-process-missing-keyword-value.el"
+ "missing value for keyword argument :command")
+
 
 ;;;; Macro expansion.
 
diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el 
b/test/lisp/emacs-lisp/cl-macs-tests.el
index 983cbfc8bc7..56a49fd865a 100644
--- a/test/lisp/emacs-lisp/cl-macs-tests.el
+++ b/test/lisp/emacs-lisp/cl-macs-tests.el
@@ -708,6 +708,23 @@ collection clause."
                            (f lex-var)))))
       (should (equal (f nil) 'a)))))
 
+(ert-deftest cl-flet/edebug ()
+  "Check that we can instrument `cl-flet' forms (bug#65344)."
+  (with-temp-buffer
+    (print '(cl-flet (;; "Obscure" form of binding supported by cl-flet
+                      (x (progn (list 1 2) (lambda ())))
+                      ;; Destructuring lambda-list
+                      (y ((min max)) (list min max))
+                      ;; Regular binding plus shadowing.
+                      (z (a) a)
+                      (z (a) a))
+              (y '(1 2)))
+           (current-buffer))
+    (let ((edebug-all-forms t)
+          (edebug-initial-mode 'Go-nonstop))
+      ;; Just make sure the forms can be instrumented.
+      (eval-buffer))))
+
 (ert-deftest cl-macs--progv ()
   (defvar cl-macs--test)
   (defvar cl-macs--test1)
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index ae83f28d9c4..e773ddf158e 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -41,19 +41,31 @@
   (should (equal (rx "" (or "ab" nonl) "")
                  "ab\\|.")))
 
+;; FIXME: Extend tests for `or', `not' etc to cover char pattern combination,
+;; including (syntax whitespace) and (syntax word).
+
 (ert-deftest rx-or ()
-  (should (equal (rx (or "ab" (| "c" nonl) "de"))
-                 "ab\\|c\\|.\\|de"))
+  (should (equal (rx (or "ab" (| "cd" nonl) "de"))
+                 "ab\\|cd\\|.\\|de"))
   (should (equal (rx (or "ab" "abc" ?a))
                  "\\(?:a\\(?:bc?\\)?\\)"))
   (should (equal (rx (or "ab" (| (or "abcd" "abcde")) (or "a" "abc")))
                  "\\(?:a\\(?:b\\(?:c\\(?:de?\\)?\\)?\\)?\\)"))
   (should (equal (rx (or "a" (eval (string ?a ?b))))
                  "\\(?:ab?\\)"))
+  (should (equal (rx (| nonl "ac") (| "bd" blank))
+                 "\\(?:.\\|ac\\)\\(?:bd\\|[[:blank:]]\\)"))
   (should (equal (rx (| nonl "a") (| "b" blank))
-                 "\\(?:.\\|a\\)\\(?:b\\|[[:blank:]]\\)"))
+                 ".[b[:blank:]]"))
   (should (equal (rx (|))
-                 "\\`a\\`")))
+                 "\\`a\\`"))
+  (should (equal (rx (or "a" (not anychar) punct ?c "b" (not (not ?d))))
+                 "[a-d[:punct:]]"))
+  (should (equal (rx (or nonl ?\n))
+                 "[^z-a]"))
+  (should (equal (rx (or "ab" "a" "b" blank (syntax whitespace) word "z"))
+                 "ab\\|[ab[:blank:]]\\|\\s-\\|[z[:word:]]"))
+  )
 
 (ert-deftest rx-def-in-or ()
   (rx-let ((a b)
@@ -101,14 +113,18 @@
                  "[\177ÿ\200-\377]"))
   ;; Range between normal chars and raw bytes: must be split to be parsed
   ;; correctly by the Emacs regexp engine.
-  (should (equal
-           (rx (any (0 . #x3fffff)) (any (?G . #x3fff9a)) (any (?Ü . 
#x3ffff2)))
-           "[\0-\x3fff7f\x80-\xff][G-\x3fff7f\x80-\x9a][Ü-\x3fff7f\x80-\xf2]"))
+  (should (equal (rx (any (0 . #x3fffff) word) (any (?G . #x3fff9a) word)
+                     (any (?Ü . #x3ffff2) word))
+                 (concat "[\0-\x3fff7f\x80-\xff[:word:]]"
+                         "[G-\x3fff7f\x80-\x9a[:word:]]"
+                         "[Ü-\x3fff7f\x80-\xf2[:word:]]")))
   ;; As above but with ranges in string form. For historical reasons,
   ;; we special-case ASCII-to-raw ranges to exclude non-ASCII unicode.
-  (should (equal
-           (rx (any "\x00-\xff") (any "G-\x9a") (any "Ü-\xf2"))
-           "[\0-\x7f\x80-\xff][G-\x7f\x80-\x9a][Ü-\x3fff7f\x80-\xf2]")))
+  (should (equal (rx (any "\x00-\xff" alpha) (any "G-\x9a" alpha)
+                     (any "Ü-\xf2" alpha))
+                 (concat "[\0-\x7f\x80-\xff[:alpha:]]"
+                         "[G-\x7f\x80-\x9a[:alpha:]]"
+                         "[Ü-\x3fff7f\x80-\xf2[:alpha:]]"))))
 
 (ert-deftest rx-any ()
   (should (equal (rx (any ?A (?C . ?D) "F-H" "J-L" "M" "N-P" "Q" "RS"))
@@ -175,7 +191,10 @@
                  "[a[:space:][:digit:]]"))
   (should (equal (rx (not "\n") (not ?\n) (not (any "\n")) (not-char ?\n)
                      (| (not (in "a\n")) (not (char ?\n (?b . ?b)))))
-          ".....")))
+                 "....."))
+  (should (equal (rx (or (in "g-k") (in "a-f") (or ?r (in "i-m" "n-q"))))
+                     "[a-r]"))
+  )
 
 (ert-deftest rx-pcase ()
   (should (equal (pcase "i18n" ((rx (let x (+ digit))) (list 'ok x)))
@@ -392,7 +411,16 @@
   (should (equal (rx (or (not (in "abc")) (not (char "bcd"))))
                  "[^bc]"))
   (should (equal (rx (or "x" (? "yz")))
-                 "x\\|\\(?:yz\\)?")))
+                 "x\\|\\(?:yz\\)?"))
+  (should (equal (rx (or anychar (not anychar)))
+                 "[^z-a]"))
+  (should (equal (rx (or (not (in "a-p")) (not (in "k-u"))))
+                 "[^k-p]"))
+  (should (equal (rx (or (not (in "a-p")) word (not (in "k-u"))))
+                 "[\0-jq-\x3fff7f\x80-\xff[:word:]]"))
+  (should (equal (rx (or (in "a-f" blank) (in "c-z") blank))
+                 "[a-z[:blank:]]"))
+  )
 
 (ert-deftest rx-def-in-charset-or ()
   (rx-let ((a (any "badc"))
@@ -613,52 +641,52 @@
 
 ;;; unit tests for internal functions
 
-(ert-deftest rx--complement-intervals ()
-  (should (equal (rx--complement-intervals '())
+(ert-deftest rx--interval-set-complement ()
+  (should (equal (rx--interval-set-complement '())
                  '((0 . #x3fffff))))
-  (should (equal (rx--complement-intervals '((10 . 20) (30 . 40)))
+  (should (equal (rx--interval-set-complement '((10 . 20) (30 . 40)))
                  '((0 . 9) (21 . 29) (41 . #x3fffff))))
-  (should (equal (rx--complement-intervals '((0 . #x3fffff)))
+  (should (equal (rx--interval-set-complement '((0 . #x3fffff)))
                  '()))
-  (should (equal (rx--complement-intervals
+  (should (equal (rx--interval-set-complement
                   '((0 . 10) (20 . 20) (30 . #x3fffff)))
                  '((11 . 19) (21 . 29)))))
 
-(ert-deftest rx--union-intervals ()
-  (should (equal (rx--union-intervals '() '()) '()))
-  (should (equal (rx--union-intervals '() '((10 . 20) (30 . 40)))
+(ert-deftest rx--interval-set-union ()
+  (should (equal (rx--interval-set-union '() '()) '()))
+  (should (equal (rx--interval-set-union '() '((10 . 20) (30 . 40)))
                  '((10 . 20) (30 . 40))))
-  (should (equal (rx--union-intervals '((10 . 20) (30 . 40)) '())
+  (should (equal (rx--interval-set-union '((10 . 20) (30 . 40)) '())
                  '((10 . 20) (30 . 40))))
-  (should (equal (rx--union-intervals '((5 . 15) (18 . 24) (32 . 40))
+  (should (equal (rx--interval-set-union '((5 . 15) (18 . 24) (32 . 40))
                                       '((10 . 20) (30 . 40) (50 . 60)))
                  '((5 . 24) (30 . 40) (50 . 60))))
-  (should (equal (rx--union-intervals '((10 . 20) (30 . 40) (50 . 60))
+  (should (equal (rx--interval-set-union '((10 . 20) (30 . 40) (50 . 60))
                                       '((0 . 9) (21 . 29) (41 . 50)))
                  '((0 . 60))))
-  (should (equal (rx--union-intervals '((10 . 20) (30 . 40))
+  (should (equal (rx--interval-set-union '((10 . 20) (30 . 40))
                                       '((12 . 18) (28 . 42)))
                  '((10 . 20) (28 . 42))))
-  (should (equal (rx--union-intervals '((10 . 20) (30 . 40))
+  (should (equal (rx--interval-set-union '((10 . 20) (30 . 40))
                                       '((0 . #x3fffff)))
                  '((0 . #x3fffff)))))
 
-(ert-deftest rx--intersect-intervals ()
-  (should (equal (rx--intersect-intervals '() '()) '()))
-  (should (equal (rx--intersect-intervals '() '((10 . 20) (30 . 40)))
+(ert-deftest rx--interval-set-intersection ()
+  (should (equal (rx--interval-set-intersection '() '()) '()))
+  (should (equal (rx--interval-set-intersection '() '((10 . 20) (30 . 40)))
                  '()))
-  (should (equal (rx--intersect-intervals '((10 . 20) (30 . 40)) '())
+  (should (equal (rx--interval-set-intersection '((10 . 20) (30 . 40)) '())
                  '()))
-  (should (equal (rx--intersect-intervals '((5 . 15) (18 . 24) (32 . 40))
+  (should (equal (rx--interval-set-intersection '((5 . 15) (18 . 24) (32 . 40))
                                           '((10 . 20) (30 . 40) (50 . 60)))
                  '((10 . 15) (18 . 20) (32 . 40))))
-  (should (equal (rx--intersect-intervals '((10 . 20) (30 . 40) (50 . 60))
+  (should (equal (rx--interval-set-intersection '((10 . 20) (30 . 40) (50 . 
60))
                                           '((0 . 9) (21 . 29) (41 . 50)))
                  '((50 . 50))))
-  (should (equal (rx--intersect-intervals '((10 . 20) (30 . 40))
+  (should (equal (rx--interval-set-intersection '((10 . 20) (30 . 40))
                                           '((12 . 18) (28 . 42)))
                  '((12 . 18) (30 . 40))))
-  (should (equal (rx--intersect-intervals '((10 . 20) (30 . 40))
+  (should (equal (rx--interval-set-intersection '((10 . 20) (30 . 40))
                                           '((0 . #x3fffff)))
                  '((10 . 20) (30 . 40)))))
 
diff --git a/test/lisp/erc/erc-scenarios-base-renick.el 
b/test/lisp/erc/erc-scenarios-base-renick.el
index f1723200533..2bf3ef46257 100644
--- a/test/lisp/erc/erc-scenarios-base-renick.el
+++ b/test/lisp/erc/erc-scenarios-base-renick.el
@@ -275,8 +275,8 @@
         (funcall expect 3 "I never saw her before")
         (erc-scenarios-common-say "You aren't with Wage?")))
 
-    (erc-d-t-wait-for 3 (get-buffer "frenemy@foonet"))
-    (erc-d-t-wait-for 3 (get-buffer "frenemy@barnet"))
+    (erc-d-t-wait-for 10 (get-buffer "frenemy@foonet"))
+    (erc-d-t-wait-for 10 (get-buffer "frenemy@barnet"))
     (should-not (get-buffer "rando@foonet"))
     (should-not (get-buffer "rando@barnet"))
 
diff --git a/test/lisp/erc/resources/base/netid/bouncer/barnet.eld 
b/test/lisp/erc/resources/base/netid/bouncer/barnet.eld
index d0fe3af8ea4..204d01fef77 100644
--- a/test/lisp/erc/resources/base/netid/bouncer/barnet.eld
+++ b/test/lisp/erc/resources/base/netid/bouncer/barnet.eld
@@ -1,7 +1,7 @@
 ;; -*- mode: lisp-data; -*-
-((pass 3 "PASS :barnet:changeme"))
-((nick 3 "NICK tester"))
-((user 3 "USER user 0 * :tester")
+((pass 10 "PASS :barnet:changeme"))
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :tester")
  (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
  (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version 
oragono-2.6.0-7481bf0385b95b16")
  (0 ":irc.barnet.org 003 tester :This server was created Wed, 12 May 2021 
07:41:08 UTC")
@@ -17,19 +17,19 @@
  (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
  (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
 
-((mode-user 10.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  ;; No mode answer ^
  (0 ":irc.znc.in 306 tester :You have been marked as being away")
  (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
 
-((join 1 "JOIN #chan")
+((join 10 "JOIN #chan")
  (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan")
  (0 ":irc.barnet.org 353 tester = #chan :@joe mike tester")
  (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
  (0.1 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :tester, welcome!")
  (0 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :tester, welcome!"))
 
-((mode 3 "MODE #chan")
+((mode 10 "MODE #chan")
  (0 ":irc.barnet.org 324 tester #chan +nt")
  (0 ":irc.barnet.org 329 tester #chan 1620805269")
  (0.1 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: But you have outfaced 
them all.")
diff --git a/test/lisp/erc/resources/base/netid/bouncer/foonet.eld 
b/test/lisp/erc/resources/base/netid/bouncer/foonet.eld
index b0964fb9537..4445350ca0c 100644
--- a/test/lisp/erc/resources/base/netid/bouncer/foonet.eld
+++ b/test/lisp/erc/resources/base/netid/bouncer/foonet.eld
@@ -1,7 +1,7 @@
 ;; -*- mode: lisp-data; -*-
-((pass 3 "PASS :foonet:changeme"))
-((nick 3 "NICK tester"))
-((user 3 "USER user 0 * :tester")
+((pass 10 "PASS :foonet:changeme"))
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :tester")
  (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
  (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version 
oragono-2.6.0-7481bf0385b95b16")
  (0 ":irc.foonet.org 003 tester :This server was created Wed, 12 May 2021 
07:41:09 UTC")
@@ -17,19 +17,19 @@
  (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
  (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
 
-((mode-user 4.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  ;; No mode answer ^
  (0 ":irc.znc.in 306 tester :You have been marked as being away")
  (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
 
-((join 1 "JOIN #chan")
+((join 10 "JOIN #chan")
  (0 ":tester!~u@ertp7idh9jtgi.irc JOIN #chan")
  (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
  (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
  (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :tester, welcome!")
  (0 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :tester, welcome!"))
 
-((mode 3 "MODE #chan")
+((mode 10 "MODE #chan")
  (0 ":irc.foonet.org 324 tester #chan +nt")
  (0 ":irc.foonet.org 329 tester #chan 1620805271")
  (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: He cannot be heard of. 
Out of doubt he is transported.")
diff --git a/test/lisp/erc/resources/base/reconnect/options.eld 
b/test/lisp/erc/resources/base/reconnect/options.eld
index 3b305d85594..e0952a2aece 100644
--- a/test/lisp/erc/resources/base/reconnect/options.eld
+++ b/test/lisp/erc/resources/base/reconnect/options.eld
@@ -1,7 +1,7 @@
 ;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :changeme"))
-((nick 1 "NICK tester"))
-((user 1 "USER user 0 * :tester")
+((pass 10 "PASS :changeme"))
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :tester")
  (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
  (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version 
oragono-2.6.0-7481bf0385b95b16")
  (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 
05:06:18 UTC")
@@ -18,7 +18,7 @@
  (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
  (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
 
-((mode-user 3.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  (0 ":irc.foonet.org 221 tester +i")
  (0 ":irc.foonet.org NOTICE tester :This server is in debug mode.")
 
@@ -26,7 +26,7 @@
  (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
  (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
 
-((mode-chan 4 "MODE #chan")
+((mode-chan 10 "MODE #chan")
  (0 ":irc.foonet.org 324 tester #chan +nt")
  (0 ":irc.foonet.org 329 tester #chan 1620104779")
  (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
diff --git a/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld 
b/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld
index 0c8cdac0379..c9080cf39e9 100644
--- a/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld
+++ b/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld
@@ -1,7 +1,7 @@
 ;; -*- mode: lisp-data; -*-
-((pass 3 "PASS :barnet:changeme"))
-((nick 3 "NICK tester"))
-((user 3 "USER user 0 * :tester")
+((pass 10 "PASS :barnet:changeme"))
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :tester")
  (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
  (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version 
oragono-2.6.0-7481bf0385b95b16")
  (0 ":irc.barnet.org 003 tester :This server was created Tue, 01 Jun 2021 
07:49:23 UTC")
@@ -17,7 +17,7 @@
  (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
  (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
 
-((mode-user 3.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  ;; No mode answer
  (0 ":irc.znc.in 306 tester :You have been marked as being away")
  (0 ":tester!~u@286u8jcpis84e.irc JOIN #chan")
@@ -32,18 +32,18 @@
  (0 ":irc.barnet.org NOTICE tester :[09:13:24] This server is in debug mode 
and is logging all user I/O. If you do not wish for everything you send to be 
readable by the server owner(s), please disconnect.")
  (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
 
-((mode 5 "MODE #chan")
+((mode 10 "MODE #chan")
  (0 ":irc.barnet.org 324 tester #chan +nt")
  (0 ":irc.barnet.org 329 tester #chan 1622538742")
  (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: By favors several which 
they did bestow.")
  (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: You, Roderigo! come, 
sir, I am for you."))
 
-((privmsg-a 5 "PRIVMSG rando :Linda said you were gonna kill me.")
+((privmsg-a 10 "PRIVMSG rando :Linda said you were gonna kill me.")
  (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: Play, music, then! Nay, 
you must do it soon.")
  (0.1 ":rando!~u@95i756tt32ym8.irc PRIVMSG tester :Linda said? I never saw her 
before I came up here.")
  (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: Of arts inhibited and 
out of warrant."))
 
-((privmsg-b 3 "PRIVMSG rando :You aren't with Wage?")
+((privmsg-b 10 "PRIVMSG rando :You aren't with Wage?")
  (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: But most of all, 
agreeing with the proclamation.")
  (0.1 ":rando!~u@95i756tt32ym8.irc PRIVMSG tester :I think you screwed up, 
Case.")
  (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: Good gentleman, go your 
gait, and let poor volk pass. An chud ha' bin zwaggered out of my life, 'twould 
not ha' bin zo long as 'tis by a vortnight. Nay, come not near th' old man; 
keep out, che vor ye, or ise try whether your costard or my ballow be the 
harder. Chill be plain with you.")
diff --git a/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld 
b/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld
index 162e8bf9655..2421651ebe8 100644
--- a/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld
+++ b/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld
@@ -1,7 +1,7 @@
 ;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :foonet:changeme"))
-((nick 1 "NICK tester"))
-((user 1 "USER user 0 * :tester")
+((pass 10 "PASS :foonet:changeme"))
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :tester")
  (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
  (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version 
oragono-2.6.0-7481bf0385b95b16")
  (0 ":irc.foonet.org 003 tester :This server was created Tue, 01 Jun 2021 
07:49:22 UTC")
@@ -17,7 +17,7 @@
  (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
  (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
 
-((mode-user 5.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  ;; No mode answer
  (0 ":irc.znc.in 306 tester :You have been marked as being away")
  (0 ":tester!~u@u4mvbswyw8gbg.irc JOIN #chan")
@@ -38,12 +38,12 @@
  (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: When there is nothing 
living but thee, thou shalt be welcome. I had rather be a beggar's dog than 
Apemantus.")
  (0.1 ":alice!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :bob: You have simply misused 
our sex in your love-prate: we must have your doublot and hose plucked over 
your head, and show the world what the bird hath done to her own nest."))
 
-((privmsg-a 6 "PRIVMSG rando :I here")
+((privmsg-a 10 "PRIVMSG rando :I here")
  (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: And I will make thee 
think thy swan a crow.")
  (0.1 ":rando!~u@bivkhq8yav938.irc PRIVMSG tester :u are dumb")
  (0.1 ":alice!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :bob: Lie not, to say mine 
eyes are murderers."))
 
-((privmsg-b 3 "PRIVMSG rando :not so")
+((privmsg-b 10 "PRIVMSG rando :not so")
  (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: Commit myself, my 
person, and the cause.")
  ;; Nick change
  (0.1 ":rando!~u@bivkhq8yav938.irc NICK frenemy")
diff --git a/test/lisp/erc/resources/erc-scenarios-common.el 
b/test/lisp/erc/resources/erc-scenarios-common.el
index 32e7556d602..972faa5c73f 100644
--- a/test/lisp/erc/resources/erc-scenarios-common.el
+++ b/test/lisp/erc/resources/erc-scenarios-common.el
@@ -288,7 +288,7 @@ buffer-naming collisions involving bouncers in ERC."
         (erc-d-t-search-for 1 "<bob>")
         (erc-d-t-absent-for 0.1 "<joe>")
         (should (eq erc-server-process erc-server-process-foo))
-        (erc-d-t-search-for 10 "ape is dead")
+        (erc-d-t-search-for 15 "ape is dead")
         (erc-d-t-wait-for 5 (not (erc-server-process-alive)))))
 
     (ert-info ("#chan@<esid> is exclusive to barnet")
diff --git a/test/lisp/erc/resources/services/auth-source/libera.eld 
b/test/lisp/erc/resources/services/auth-source/libera.eld
index c8dbc9d425a..dfc25221508 100644
--- a/test/lisp/erc/resources/services/auth-source/libera.eld
+++ b/test/lisp/erc/resources/services/auth-source/libera.eld
@@ -1,6 +1,6 @@
 ;; -*- mode: lisp-data; -*-
-((nick 1 "NICK tester"))
-((user 1 "USER user 0 * :tester")
+((nick 10 "NICK tester"))
+((user 5 "USER user 0 * :tester")
  (0.26 ":zirconium.libera.chat NOTICE * :*** Checking Ident")
  (0.01 ":zirconium.libera.chat NOTICE * :*** Looking up your hostname...")
  (0.01 ":zirconium.libera.chat NOTICE * :*** No Ident response")
@@ -35,15 +35,15 @@
  (0.01 ":zirconium.libera.chat 372 tester :- Email:                      
support@libera.chat")
  (0.00 ":zirconium.libera.chat 376 tester :End of /MOTD command."))
 
-((mode-user 1.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  (0.02 ":tester MODE tester :+Zi")
  (0.02 ":NickServ!NickServ@services.libera.chat NOTICE tester :This nickname 
is registered. Please choose a different nickname, or identify via \2/msg 
NickServ IDENTIFY tester <password>\2"))
 
-((privmsg 2 "PRIVMSG NickServ :IDENTIFY changeme")
+((privmsg 10 "PRIVMSG NickServ :IDENTIFY changeme")
  (0.96 ":NickServ!NickServ@services.libera.chat NOTICE tester :You are now 
identified for \2tester\2.")
  (0.25 ":NickServ!NickServ@services.libera.chat NOTICE tester :Last login 
from: \2~tester@school.edu/tester\2 on Jun 18 01:15:56 2021 +0000."))
 
-((quit 5 "QUIT :\2ERC\2")
+((quit 10 "QUIT :\2ERC\2")
  (0.19 ":tester!~user@static-198-54-131-100.cust.tzulo.com QUIT :Client Quit"))
 
 ((linger 1 LINGER))
diff --git a/test/lisp/eshell/em-extpipe-tests.el 
b/test/lisp/eshell/em-extpipe-tests.el
index 1184b5df5f8..bdffcd9b320 100644
--- a/test/lisp/eshell/em-extpipe-tests.el
+++ b/test/lisp/eshell/em-extpipe-tests.el
@@ -48,26 +48,29 @@
             ;; buffer into `input'.  The substitution logic is
             ;; appropriate for only the use we put it to in this file.
             `(ert-with-temp-file temp
-               (let ((temp-buffer (generate-new-buffer " *temp*" t)))
+               (let ((temp-buffer (generate-new-buffer " *tmp*" t)))
                  (unwind-protect
                      (let ((input
                             (replace-regexp-in-string
                              "temp\\([^>]\\|\\'\\)" temp
-                             (string-replace "#<buffer temp>"
-                                             (buffer-name temp-buffer)
-                                             input))))
+                             (string-replace
+                              "#<buffer temp>"
+                              (concat "#<buffer " (buffer-name temp-buffer) 
">")
+                              input))))
                        ,@body)
                    (when (buffer-name temp-buffer)
                      (kill-buffer temp-buffer))))))
           (temp-should-string= (expected)
-            `(string= ,expected (string-trim-right
-                                 (with-temp-buffer
-                                   (insert-file-contents temp)
-                                   (buffer-string)))))
+            `(should (string= ,expected
+                              (string-trim-right
+                               (with-temp-buffer
+                                 (insert-file-contents temp)
+                                 (buffer-string))))))
           (temp-buffer-should-string= (expected)
-            `(string= ,expected (string-trim-right
-                                 (with-current-buffer temp-buffer
-                                   (buffer-string))))))
+            `(should (string= ,expected
+                              (string-trim-right
+                               (with-current-buffer temp-buffer
+                                 (buffer-string)))))))
        (skip-unless shell-file-name)
        (skip-unless shell-command-switch)
        (skip-unless (executable-find shell-file-name))
diff --git a/test/lisp/eshell/em-unix-tests.el 
b/test/lisp/eshell/em-unix-tests.el
new file mode 100644
index 00000000000..d7b6c55fe45
--- /dev/null
+++ b/test/lisp/eshell/em-unix-tests.el
@@ -0,0 +1,68 @@
+;;; em-unix-tests.el --- em-unix test suite  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2023 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:
+
+;; Tests for Eshell's implementation of various UNIX commands.
+
+;;; Code:
+
+(require 'ert)
+(require 'em-unix)
+
+(require 'eshell-tests-helpers
+         (expand-file-name "eshell-tests-helpers"
+                           (file-name-directory (or load-file-name
+                                                    default-directory))))
+
+;;; Tests:
+
+(ert-deftest em-unix-test/compile/interactive ()
+  "Check that `eshell/compile' opens a compilation buffer interactively."
+  (skip-unless (executable-find "echo"))
+  (with-temp-eshell
+   (eshell-match-command-output "compile echo hello"
+                                "#<buffer \\*compilation\\*>")
+   (with-current-buffer "*compilation*"
+     (forward-line 3)
+     (should (looking-at "echo hello")))))
+
+(ert-deftest em-unix-test/compile/noninteractive ()
+  "Check that `eshell/compile' writes to stdout noninteractively."
+  (skip-unless (executable-find "echo"))
+  (eshell-command-result-equal "compile echo hello"
+                               "hello\n"))
+
+(ert-deftest em-unix-test/compile/pipeline ()
+  "Check that `eshell/compile' writes to stdout from a pipeline."
+  (skip-unless (and (executable-find "echo")
+                    (executable-find "cat")))
+  (with-temp-eshell
+   (eshell-match-command-output "compile echo hello | *cat"
+                                "\\`hello\n")))
+
+(ert-deftest em-unix-test/compile/subcommand ()
+  "Check that `eshell/compile' writes to stdout from a subcommand."
+  (skip-unless (and (executable-find "echo")
+                    (executable-find "cat")))
+  (with-temp-eshell
+   (eshell-match-command-output "echo ${compile echo hello}"
+                                "\\`hello\n")))
+
+;; em-unix-tests.el ends here
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 390f75cfbb9..46c9482ecf4 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -162,16 +162,13 @@ This test uses a pipeline for the command."
   "Test moving across command arguments"
   (with-temp-eshell
    (eshell-insert-command "echo $(+ 1 (- 4 3)) \"alpha beta\" file" 'ignore)
-   (let ((here (point)) begin valid)
+   (let ((end (point)) begin)
      (beginning-of-line)
      (setq begin (point))
      (eshell-forward-argument 4)
-     (setq valid (= here (point)))
+     (should (= end (point)))
      (eshell-backward-argument 4)
-     (prog1
-         (and valid (= begin (point)))
-       (beginning-of-line)
-       (delete-region (point) (point-max))))))
+     (should (= begin (point))))))
 
 (ert-deftest eshell-test/queue-input ()
   "Test queuing command input.
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index f6c7be88b05..0e460009cea 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1204,30 +1204,30 @@ unquoted file names."
     (let ((process-environment (cons "FOO=foo" process-environment))
           (nospecial-foo (files-tests--new-name nospecial "$FOO")))
       ;; The "/:" prevents substitution.
-      (equal (substitute-in-file-name nospecial-foo) nospecial-foo)))
+      (should (equal (substitute-in-file-name nospecial-foo) nospecial-foo))))
   (files-tests--with-temp-non-special-and-file-name-handler (tmpfile nospecial)
     (let ((process-environment (cons "FOO=foo" process-environment))
           (nospecial-foo (files-tests--new-name nospecial "$FOO")))
       ;; The "/:" prevents substitution.
-      (equal (substitute-in-file-name nospecial-foo) nospecial-foo))))
+      (should (equal (substitute-in-file-name nospecial-foo) nospecial-foo)))))
 
 (ert-deftest files-tests-file-name-non-special-temporary-file-directory ()
   (files-tests--with-temp-non-special (tmpdir nospecial-dir t)
     (let ((default-directory nospecial-dir))
-      (equal (temporary-file-directory) temporary-file-directory)))
+      (should (equal (temporary-file-directory) temporary-file-directory))))
   (files-tests--with-temp-non-special-and-file-name-handler
       (tmpdir nospecial-dir t)
     (let ((default-directory nospecial-dir))
-      (equal (temporary-file-directory) temporary-file-directory))))
+      (should (equal (temporary-file-directory) temporary-file-directory)))))
 
 (ert-deftest files-tests-file-name-non-special-unhandled-file-name-directory ()
   (files-tests--with-temp-non-special (tmpdir nospecial-dir t)
-    (equal (unhandled-file-name-directory nospecial-dir)
-           (file-name-as-directory tmpdir)))
+    (should (equal (unhandled-file-name-directory nospecial-dir)
+                   (file-name-as-directory tmpdir))))
   (files-tests--with-temp-non-special-and-file-name-handler
       (tmpdir nospecial-dir t)
-    (equal (unhandled-file-name-directory nospecial-dir)
-           (file-name-as-directory tmpdir))))
+    (should-not (equal (unhandled-file-name-directory nospecial-dir)
+                       (file-name-as-directory tmpdir)))))
 
 (ert-deftest files-tests-file-name-non-special-vc-registered ()
   (files-tests--with-temp-non-special (tmpfile nospecial)
diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el
index a67fc555772..ff58d35eb3e 100644
--- a/test/lisp/minibuffer-tests.el
+++ b/test/lisp/minibuffer-tests.el
@@ -139,7 +139,7 @@
 (defun test-completion-all-sorted-completions (base def history-var 
history-list)
   (with-temp-buffer
     (insert base)
-    (cl-letf (((symbol-function #'minibufferp) (lambda (&rest _) t)))
+    (cl-letf (((symbol-function #'minibufferp) #'always))
       (let ((completion-styles '(basic))
             (completion-category-defaults nil)
             (completion-category-overrides nil)
diff --git a/test/lisp/net/tramp-archive-tests.el 
b/test/lisp/net/tramp-archive-tests.el
index e34e830cb83..9500ce0efca 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -895,11 +895,16 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
   (skip-unless (and (fboundp 'file-user-uid)
                     (fboundp 'file-group-gid)))
 
-  (let ((default-directory tramp-archive-test-archive))
-    ;; `file-user-uid' and `file-group-gid' exist since Emacs 30.1.
-    ;; We don't want to see compiler warnings for older Emacsen.
-    (should (integerp (with-no-warnings (file-user-uid))))
-    (should (integerp (with-no-warnings (file-group-gid))))))
+  ;; `file-user-uid' and `file-group-gid' exist since Emacs 30.1.
+  ;; We don't want to see compiler warnings for older Emacsen.
+  (let* ((default-directory tramp-archive-test-archive)
+        (uid (with-no-warnings (file-user-uid)))
+        (gid (with-no-warnings (file-group-gid))))
+    (should (integerp uid))
+    (should (integerp gid))
+    (let ((default-directory tramp-archive-test-file-archive))
+      (should (equal uid (with-no-warnings (file-user-uid))))
+      (should (equal gid (with-no-warnings (file-group-gid)))))))
 
 (ert-deftest tramp-archive-test48-auto-load ()
   "Check that `tramp-archive' autoloads properly."
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index a6c430fb1c0..50687dfe993 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -2711,7 +2711,20 @@ This checks also `file-name-as-directory', 
`file-name-directory',
              :type 'file-already-exists)
            (should-error
             (write-region "foo" nil tmp-name nil nil nil 'excl)
-            :type 'file-already-exists))
+            :type 'file-already-exists)
+           (delete-file tmp-name)
+
+           ;; Check `buffer-file-coding-system'.  Bug#65022.
+           (with-temp-buffer
+             (setq buffer-file-name tmp-name)
+             (insert "foo")
+             (set-buffer-file-coding-system 'cp1251)
+             (let ((bfcs buffer-file-coding-system))
+               (should (buffer-modified-p))
+               (should (null (save-buffer)))
+               (should
+                 (eq (coding-system-get buffer-file-coding-system 
:mime-charset)
+                     (coding-system-get bfcs :mime-charset))))))
 
        ;; Cleanup.
        (ignore-errors (delete-file tmp-name))))))
@@ -5370,7 +5383,7 @@ If UNSTABLE is non-nil, the test is tagged as 
`:unstable'."
     (let ((default-directory ert-remote-temporary-file-directory)
          (tmp-name (tramp--test-make-temp-name nil quoted))
          kill-buffer-query-functions command proc)
-      (should-not (make-process))
+      (should-not (apply #'make-process nil)) ; Use `apply' to avoid warnings.
 
       ;; Simple process.
       (unwind-protect
@@ -7398,6 +7411,7 @@ This requires restrictions of file name syntax."
   (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 245s
   (skip-unless (not (tramp--test-rsync-p)))
   (skip-unless (not (tramp--test-rclone-p)))
+  (skip-unless (not (or (eq system-type 'darwin) (tramp--test-macos-p))))
 
   ;; Newlines, slashes and backslashes in file names are not
   ;; supported.  So we don't test.  And we don't test the tab
@@ -7473,14 +7487,12 @@ This requires restrictions of file name syntax."
   (skip-unless (not (tramp--test-gdrive-p)))
   (skip-unless (not (tramp--test-crypt-p)))
   (skip-unless (not (tramp--test-rclone-p)))
+  (skip-unless (not (or (eq system-type 'darwin) (tramp--test-macos-p))))
 
-  (let* ((utf8 (if (and (eq system-type 'darwin)
-                       (memq 'utf-8-hfs (coding-system-list)))
-                  'utf-8-hfs 'utf-8))
-        (coding-system-for-read utf8)
-        (coding-system-for-write utf8)
-        (file-name-coding-system
-         (coding-system-change-eol-conversion utf8 'unix)))
+  (let ((coding-system-for-read 'utf-8)
+       (coding-system-for-write 'utf-8)
+       (file-name-coding-system
+        (coding-system-change-eol-conversion 'utf-8 'unix)))
     (apply
      #'tramp--test-check-files
      (append
diff --git a/test/lisp/progmodes/python-tests.el 
b/test/lisp/progmodes/python-tests.el
index 54e32cbf07b..9f935f2748c 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -5973,9 +5973,9 @@ def func():
         else
 "
    (python-tests-look-at "else\n")
-    (should
-     (equal (list (python-tests-look-at "if (" -1 t))
-            (python-info-dedenter-opening-block-positions)))))
+   (should
+    (equal (list (python-tests-look-at "if (" -1 t))
+           (python-info-dedenter-opening-block-positions)))))
 
 (ert-deftest python-info-dedenter-opening-block-positions-7 ()
   "Test case blocks."
@@ -5993,9 +5993,9 @@ match a:
    (python-tests-look-at "case 2:")
    (should-not (python-info-dedenter-opening-block-positions))
    (python-tests-look-at "case 3:")
-   (equal (list (python-tests-look-at "case 2:" -1)
-                (python-tests-look-at "case 1:" -1 t))
-            (python-info-dedenter-opening-block-positions))))
+   (should (equal (list (python-tests-look-at "case 2:" -1 t)
+                        (python-tests-look-at "case 1:" -1 t))
+                  (python-info-dedenter-opening-block-positions)))))
 
 (ert-deftest python-info-dedenter-opening-block-message-1 ()
   "Test dedenters inside strings are ignored."
diff --git a/test/lisp/server-tests.el b/test/lisp/server-tests.el
index ffafa74925f..de1aa80c272 100644
--- a/test/lisp/server-tests.el
+++ b/test/lisp/server-tests.el
@@ -25,12 +25,18 @@
 
 (defconst server-tests/can-create-frames-p
   (and (not (memq system-type '(windows-nt ms-dos)))
-       (not (member (getenv "TERM") '("dumb" "" nil))))
+       (not (member (getenv "TERM") '("dumb" "" nil)))
+       (or (not (eq system-type 'cygwin))
+           (featurep 'gfilenotify)
+           (featurep 'dbus)
+           (featurep 'threads)))
   "Non-nil if we can create a new frame in the tests.
 Some tests below need to create new frames for the emacsclient.
 However, this doesn't work on all platforms.  In particular,
-MS-Windows fails to create frames from a batch Emacs session.  In
-cases like that, we just skip the test.")
+MS-Windows fails to create frames from a batch Emacs session.
+The same is true on Cygwin unless Emacs has at least one of the
+features gfilenotify, dbus, or threads (bug#65325).  In cases
+like that, we just skip the test.")
 
 (defconst server-tests/max-wait-time 5
   "The maximum time to wait in `server-tests/wait-until', in seconds.")
diff --git a/test/lisp/wid-edit-tests.el b/test/lisp/wid-edit-tests.el
index b379c7c91a8..ebfe729bc9a 100644
--- a/test/lisp/wid-edit-tests.el
+++ b/test/lisp/wid-edit-tests.el
@@ -349,4 +349,35 @@ return nil, even with a non-nil bubblep argument."
     (should-not (widget-apply widget :match "someundefinedcolorihope"))
     (should-not (widget-apply widget :match "#11223"))))
 
+(ert-deftest widget-test-alist-default-value-1 ()
+  "Test getting the default value for an alist widget with options."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer
+                                    :options (("0" (integer)))))))
+      (should (equal '(("0" . 0)) (widget-default-get w))))))
+
+(ert-deftest widget-test-alist-default-value-2 ()
+  "Test getting the default value for an alist widget without :value."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer))))
+      (should-not (widget-default-get w)))))
+
+(ert-deftest widget-test-alist-default-value-3 ()
+  "Test getting the default value for an alist widget with nil :value."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer
+                                    :value nil))))
+      (should-not (widget-default-get w)))))
+
+(ert-deftest widget-test-alist-default-value-4 ()
+  "Test getting the default value for an alist widget with non-nil :value."
+  (with-temp-buffer
+    (let ((w (widget-create '(alist :key-type string
+                                    :value-type integer
+                                    :value (("1" . 1) ("2" . 2))))))
+      (should (equal '(("1" . 1) ("2" . 2)) (widget-default-get w))))))
+
 ;;; wid-edit-tests.el ends here
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index 89b1eefb1dc..4444ab61219 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -64,6 +64,7 @@
 
 
 
+(defvar native-comp-eln-load-path)
 (ert-deftest comp-tests-bootstrap ()
   "Compile the compiler and load it to compile it-self.
 Check that the resulting binaries do not differ."
@@ -72,9 +73,11 @@ Check that the resulting binaries do not differ."
     :suffix "-comp-stage1.el"
     (ert-with-temp-file comp2-src
       :suffix "-comp-stage2.el"
-      (let* ((byte+native-compile t)     ; FIXME HACK
+      (let* ((byte+native-compile t)
+             (native-compile-target-directory
+              (car (last native-comp-eln-load-path)))
              (comp-src (expand-file-name "../../../lisp/emacs-lisp/comp.el"
-                                     (ert-resource-directory)))
+                                         (ert-resource-directory)))
              ;; Can't use debug symbols.
              (native-comp-debug 0))
         (copy-file comp-src comp1-src t)
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index 680fdd57d71..8167cccdd18 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -768,6 +768,31 @@ comparing the subr with a much slower Lisp implementation."
                          (default-value 'last-coding-system-used))
                    '(no-conversion bug34318)))))
 
+(defvar-local data-tests--bug65209 :default-value)
+
+(ert-deftest data-tests-make-local-bug65209 ()
+  (dolist (sym '(data-tests--bug65209   ;A normal always-local Lisp var.
+                 cursor-in-non-selected-windows)) ;Same but DEFVAR_PER_BUFFER.
+    ;; Note: For vars like `mode-name' that are *really* always buffer-local,
+    ;; this test isn't right because the `cl-progv' only binds the
+    ;; buffer-local value!
+    (let ((default (default-value sym))
+          vli vlo vgi vgo)
+      (with-temp-buffer
+        (cl-progv (list sym) '(:let-bound-value)
+          ;; While `setq' would not make the var buffer-local
+          ;; (because we'd be setq-ing the let-binding instead),
+          ;; `setq-local' definitely should.
+          (set (make-local-variable sym) :buffer-local-value)
+          (setq vgi (with-temp-buffer (symbol-value sym)))
+          (setq vli (symbol-value sym)))
+      (setq vgo (with-temp-buffer (symbol-value sym)))
+      (setq vlo (symbol-value sym)))
+      (should (equal (list vgo vgi vlo vli)
+                     (cons default
+                           '(:let-bound-value
+                             :buffer-local-value :buffer-local-value)))))))
+
 (ert-deftest data-tests-make_symbol_constant ()
   "Can't set variable marked with 'make_symbol_constant'."
   (should-error (setq most-positive-fixnum 1) :type 'setting-constant))
diff --git a/test/src/keyboard-tests.el b/test/src/keyboard-tests.el
index 3393c1d9018..bbb9c19e2e7 100644
--- a/test/src/keyboard-tests.el
+++ b/test/src/keyboard-tests.el
@@ -23,6 +23,11 @@
 
 (ert-deftest keyboard-unread-command-events ()
   "Test `unread-command-events'."
+  ;; Avoid hang on Cygwin; see bug#65325.
+  (skip-unless (or (not (eq system-type 'cygwin))
+                   (featurep 'gfilenotify)
+                   (featurep 'dbus)
+                   (featurep 'threads)))
   (let ((unread-command-events nil))
     (should (equal (progn (push ?\C-a unread-command-events)
                           (read-event nil nil 1))
diff --git a/test/src/syntax-tests.el b/test/src/syntax-tests.el
index 0ad3667c060..9e4740c17cc 100644
--- a/test/src/syntax-tests.el
+++ b/test/src/syntax-tests.el
@@ -518,7 +518,6 @@ the `parse-partial-sexp's are expected to stop.  See
         (modify-syntax-entry (unibyte-char-to-multibyte 128) "_" st)
         (set-syntax-table st)
         (should (equal (eval '(char-syntax 128) t) ?_))
-        (should (equal (funcall cs 128) ?_))))
-    (list (char-syntax 128) (funcall cs 128))))
+        (should (equal (funcall cs 128) ?_))))))
 
 ;;; syntax-tests.el ends here



reply via email to

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