aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2024-07-14 12:47:51 +0800
committerPo Lu2024-07-14 12:47:51 +0800
commitf9dae55ccca065a6b27d00959db711faf59b9fa3 (patch)
treecc1946c13ca3bd2a63c9317c52ee48a94f374a45
parentf38c42d1c7a8413f63b1e56261850d3dbe8abef8 (diff)
parentb00fc31dd1d4543f8b017e8d7fef7686cd430bcc (diff)
downloademacs-f9dae55ccca065a6b27d00959db711faf59b9fa3.tar.gz
emacs-f9dae55ccca065a6b27d00959db711faf59b9fa3.zip
Merge from savannah/emacs-30
b00fc31dd1d Do not set LD_LIBRARY_PATH during Android initialization 04bf3172f03 ; Set Transient's version e6f78485aa6 ; Fix typos in 'which-key-mode' (bug#72093)
-rw-r--r--doc/emacs/android.texi22
-rw-r--r--doc/misc/transient.texi4
-rw-r--r--java/org/gnu/emacs/EmacsNoninteractive.java250
-rw-r--r--lisp/transient.el2
-rw-r--r--lisp/which-key.el6
-rw-r--r--src/android-emacs.c11
-rw-r--r--src/android.c11
7 files changed, 153 insertions, 153 deletions
diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi
index 2d95f5c8fef..edcbb971b98 100644
--- a/doc/emacs/android.texi
+++ b/doc/emacs/android.texi
@@ -378,20 +378,18 @@ definition documents, so your mileage may vary.
378 378
379@cindex EMACS_CLASS_PATH environment variable, Android 379@cindex EMACS_CLASS_PATH environment variable, Android
380 Even when the location of the @command{libandroid-emacs.so} command is 380 Even when the location of the @command{libandroid-emacs.so} command is
381known in advance, special configuration is required to run Emacs from 381known in advance, special preparation is required to run Emacs from
382elsewhere than a subprocess of an existing Emacs session, as it must be 382elsewhere than a subprocess of an existing Emacs session, as it must be
383made to understand the location of resources and shared libraries in or 383made to understand the location of resources and shared libraries in or
384extracted from the installed application package. The OS command 384extracted from the installed application package. The OS command
385@command{pm path org.gnu.emacs} will print the location of the 385@command{pm path org.gnu.emacs} will print the location of the
386application package, and the adjacent @file{lib} directory will hold 386application package, though the said command must be invoked in a
387shared libraries extracted from the same, though the said command must 387peculiar manner to satisfy system restrictions on communication between
388be invoked in a peculiar manner to satisfy system restrictions on 388pseudoterminal devices created by user applications and system services
389communication between pseudoterminal devices created by user 389such as the package manager, which is to say, with the standard IO
390applications and system services such as the package manager, which is 390streams redirected to a real file or a pipe. This value, once
391to say, with the standard IO streams redirected to a real file or a 391established, must be specified in the environment variables
392pipe. Such values, once established, must be specified in the 392@code{EMACS_CLASS_PATH}, so that this sample shell script may be
393environment variables @code{EMACS_CLASS_PATH} and
394@code{EMACS_LD_LIBRARY_PATH}, so that this sample shell script may be
395installed as @code{emacs} in any location that is accessible: 393installed as @code{emacs} in any location that is accessible:
396 394
397@example 395@example
@@ -400,7 +398,6 @@ installed as @code{emacs} in any location that is accessible:
400package_name=`pm path org.gnu.emacs 2>/dev/null </dev/null \ 398package_name=`pm path org.gnu.emacs 2>/dev/null </dev/null \
401 | sed 's/^package://'` 399 | sed 's/^package://'`
402emacs= 400emacs=
403ld_path=
404EMACS_CLASS_PATH=$package_name 401EMACS_CLASS_PATH=$package_name
405 402
406for libdir in `dirname $package_name`/lib/*; do 403for libdir in `dirname $package_name`/lib/*; do
@@ -409,10 +406,7 @@ for libdir in `dirname $package_name`/lib/*; do
409 && emacs="$libdir"/libandroid-emacs.so 406 && emacs="$libdir"/libandroid-emacs.so
410done 407done
411 408
412EMACS_LD_LIBRARY_PATH=$ld_path
413
414export EMACS_CLASS_PATH 409export EMACS_CLASS_PATH
415export EMACS_LD_LIBRARY_PATH
416test -x "$emacs" || exit 1 410test -x "$emacs" || exit 1
417exec $emacs "$@@" 411exec $emacs "$@@"
418@end example 412@end example
diff --git a/doc/misc/transient.texi b/doc/misc/transient.texi
index 22db4e82143..9245a76e66b 100644
--- a/doc/misc/transient.texi
+++ b/doc/misc/transient.texi
@@ -31,7 +31,7 @@ General Public License for more details.
31@finalout 31@finalout
32@titlepage 32@titlepage
33@title Transient User and Developer Manual 33@title Transient User and Developer Manual
34@subtitle for version 0.7.2 34@subtitle for version 0.7.2.1
35@author Jonas Bernoulli 35@author Jonas Bernoulli
36@page 36@page
37@vskip 0pt plus 1filll 37@vskip 0pt plus 1filll
@@ -53,7 +53,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial,
53available at @uref{https://github.com/positron-solutions/transient-showcase}. 53available at @uref{https://github.com/positron-solutions/transient-showcase}.
54 54
55@noindent 55@noindent
56This manual is for Transient version 0.7.2. 56This manual is for Transient version 0.7.2.1.
57 57
58@insertcopying 58@insertcopying
59@end ifnottex 59@end ifnottex
diff --git a/java/org/gnu/emacs/EmacsNoninteractive.java b/java/org/gnu/emacs/EmacsNoninteractive.java
index ba23399cb3e..9f2b9fa8b56 100644
--- a/java/org/gnu/emacs/EmacsNoninteractive.java
+++ b/java/org/gnu/emacs/EmacsNoninteractive.java
@@ -30,37 +30,69 @@ import java.lang.reflect.Method;
30 30
31/* Noninteractive Emacs. 31/* Noninteractive Emacs.
32 32
33 This is the class that libandroid-emacs.so starts. 33 When started, libandroid-emacs.so invokes `app_process(64)' with a
34 libandroid-emacs.so figures out the system classpath, then starts 34 command line placing Emacs's classes.dex file in the JVM class path,
35 dalvikvm with the framework jars. 35 which in turn transfers control to `main'. `main' creates a context,
36 36 which may be likened to a connection to the system server, and a
37 At that point, dalvikvm calls main, which sets up the main looper, 37 class loader derived from Emacs's application package, which it loads
38 creates an ActivityThread and attaches it to the main thread. 38 beforehand. From this class loader, it loads another instance of
39 39 itself, and invokes `main1', to ensure the execution of
40 Then, it obtains an application context for the LoadedApk in the 40 `EmacsNative''s static initializer within the application class
41 application thread. 41 loader, where a proper library search path is in effect. */
42
43 Finally, it obtains the necessary context specific objects and
44 initializes Emacs. */
45 42
46@SuppressWarnings ("unchecked") 43@SuppressWarnings ("unchecked")
47public final class EmacsNoninteractive 44public final class EmacsNoninteractive
48{ 45{
46 /* Prepare Emacs for startup and call `initEmacs'. This function is
47 called in an instance of `EmacsNoninteractive' loaded by the APK
48 ClassLoader acquired in `main', which guarantees that shared
49 libraries in the APK will be considered in resolving shared
50 libraries for `EmacsNative'. */
51
52 public static void
53 main1 (String[] args, Context context)
54 throws Exception
55 {
56 AssetManager assets;
57 String filesDir, libDir, cacheDir;
58
59 /* Don't actually start the looper or anything. Instead, obtain
60 an AssetManager. */
61 assets = context.getAssets ();
62
63 /* Now configure Emacs. The class path should already be set. */
64
65 filesDir = context.getFilesDir ().getCanonicalPath ();
66 libDir = EmacsService.getLibraryDirectory (context);
67 cacheDir = context.getCacheDir ().getCanonicalPath ();
68 EmacsNative.setEmacsParams (assets, filesDir,
69 libDir, cacheDir, 0.0f,
70 0.0f, 0.0f, null, null,
71 Build.VERSION.SDK_INT);
72
73 /* Now find the dump file that Emacs should use, if it has already
74 been dumped. */
75 EmacsApplication.findDumpFile (context);
76
77 /* Start Emacs. */
78 EmacsNative.initEmacs (args, EmacsApplication.dumpFileName);
79 }
80
49 public static void 81 public static void
50 main (String[] args) 82 main (String[] args)
51 { 83 {
52 Object activityThread, loadedApk; 84 Object activityThread, loadedApk;
53 Class activityThreadClass, loadedApkClass, contextImplClass; 85 Class activityThreadClass, loadedApkClass, contextImplClass;
54 Class compatibilityInfoClass; 86 Class compatibilityInfoClass, emacsNoninteractiveClass;
55 Method method; 87 Method method;
56 Context context; 88 Context context;
57 AssetManager assets; 89 ClassLoader classLoader;
58 String filesDir, libDir, cacheDir;
59 90
60 Looper.prepare (); 91 Looper.prepare ();
92
61 context = null; 93 context = null;
62 assets = null; 94 loadedApkClass = null;
63 filesDir = libDir = cacheDir = null; 95 classLoader = null;
64 96
65 try 97 try
66 { 98 {
@@ -72,7 +104,6 @@ public final class EmacsNoninteractive
72 104
73 /* Create and attach the activity thread. */ 105 /* Create and attach the activity thread. */
74 activityThread = method.invoke (null); 106 activityThread = method.invoke (null);
75 context = null;
76 107
77 /* Now get an LoadedApk. */ 108 /* Now get an LoadedApk. */
78 109
@@ -82,99 +113,88 @@ public final class EmacsNoninteractive
82 } 113 }
83 catch (ClassNotFoundException exception) 114 catch (ClassNotFoundException exception)
84 { 115 {
85 /* Android 2.2 has no LoadedApk class, but fortunately it 116 /* Android 2.2 has no LoadedApk class; the several following
86 does not need to be used, since contexts can be 117 statements will load a context and an
87 directly created. */ 118 ActivityThread.PackageInfo, as is appropriate on this
119 system. */
120 }
88 121
89 loadedApkClass = null; 122 /* Get a LoadedApk or ActivityThread.PackageInfo. How to do
90 contextImplClass = Class.forName ("android.app.ContextImpl"); 123 this varies by Android version. On Android 2.3.3 and
124 earlier, there is no ``compatibilityInfo'' argument to
125 getPackageInfo. */
91 126
92 method = activityThreadClass.getDeclaredMethod ("getSystemContext"); 127 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1)
93 context = (Context) method.invoke (activityThread); 128 {
94 method = contextImplClass.getDeclaredMethod ("createPackageContext", 129 method
95 String.class, 130 = activityThreadClass.getMethod ("getPackageInfo",
96 int.class); 131 String.class,
97 method.setAccessible (true); 132 int.class);
98 context = (Context) method.invoke (context, "org.gnu.emacs", 133 loadedApk = method.invoke (activityThread, "org.gnu.emacs",
99 0); 134 (Context.CONTEXT_INCLUDE_CODE
135 | Context.CONTEXT_IGNORE_SECURITY));
100 } 136 }
137 else
138 {
139 compatibilityInfoClass
140 = Class.forName ("android.content.res.CompatibilityInfo");
141
142 method
143 = activityThreadClass.getMethod ("getPackageInfo",
144 String.class,
145 compatibilityInfoClass,
146 int.class);
147 loadedApk = method.invoke (activityThread, "org.gnu.emacs",
148 null, (Context.CONTEXT_INCLUDE_CODE
149 | Context.CONTEXT_IGNORE_SECURITY));
150 }
151
152 if (loadedApk == null)
153 throw new RuntimeException ("getPackageInfo returned NULL");
154
155 /* If loadedApkClass remains NULL, substitute the class of
156 the object returned by getPackageInfo. */
157 if (loadedApkClass == null)
158 loadedApkClass = loadedApk.getClass ();
101 159
102 /* If the context has not already been created, then do what 160 /* Now, get a context. */
103 is appropriate for newer versions of Android. */ 161 contextImplClass = Class.forName ("android.app.ContextImpl");
104 162
105 if (context == null) 163 try
106 { 164 {
107 /* Get a LoadedApk. How to do this varies by Android version. 165 method
108 On Android 2.3.3 and earlier, there is no 166 = contextImplClass.getDeclaredMethod ("createAppContext",
109 ``compatibilityInfo'' argument to getPackageInfo. */ 167 activityThreadClass,
110 168 loadedApkClass);
111 if (Build.VERSION.SDK_INT 169 method.setAccessible (true);
112 <= Build.VERSION_CODES.GINGERBREAD_MR1) 170 context = (Context) method.invoke (null, activityThread,
113 { 171 loadedApk);
114 method 172 }
115 = activityThreadClass.getMethod ("getPackageInfo", 173 catch (NoSuchMethodException exception)
116 String.class, 174 {
117 int.class); 175 /* Older Android versions don't have createAppContext, but
118 loadedApk = method.invoke (activityThread, "org.gnu.emacs", 176 instead require creating a ContextImpl, and then
119 0); 177 calling createPackageContext. */
120 } 178 method
121 else 179 = activityThreadClass.getDeclaredMethod ("getSystemContext");
122 { 180 context = (Context) method.invoke (activityThread);
123 compatibilityInfoClass 181 method
124 = Class.forName ("android.content.res.CompatibilityInfo"); 182 = contextImplClass.getDeclaredMethod ("createPackageContext",
125 183 String.class,
126 method 184 int.class);
127 = activityThreadClass.getMethod ("getPackageInfo", 185 method.setAccessible (true);
128 String.class, 186 context = (Context) method.invoke (context, "org.gnu.emacs",
129 compatibilityInfoClass, 187 0);
130 int.class);
131 loadedApk = method.invoke (activityThread, "org.gnu.emacs",
132 null, 0);
133 }
134
135 if (loadedApk == null)
136 throw new RuntimeException ("getPackageInfo returned NULL");
137
138 /* Now, get a context. */
139 contextImplClass = Class.forName ("android.app.ContextImpl");
140
141 try
142 {
143 method
144 = contextImplClass.getDeclaredMethod ("createAppContext",
145 activityThreadClass,
146 loadedApkClass);
147 method.setAccessible (true);
148 context = (Context) method.invoke (null, activityThread,
149 loadedApk);
150 }
151 catch (NoSuchMethodException exception)
152 {
153 /* Older Android versions don't have createAppContext, but
154 instead require creating a ContextImpl, and then
155 calling createPackageContext. */
156 method
157 = activityThreadClass.getDeclaredMethod ("getSystemContext");
158 context = (Context) method.invoke (activityThread);
159 method
160 = contextImplClass.getDeclaredMethod ("createPackageContext",
161 String.class,
162 int.class);
163 method.setAccessible (true);
164 context = (Context) method.invoke (context, "org.gnu.emacs",
165 0);
166 }
167 } 188 }
168 189
169 /* Don't actually start the looper or anything. Instead, obtain 190 /* Retrieve the LoadedApk's class loader and execute the
170 an AssetManager. */ 191 remaining portion of the start-up process within its version
171 assets = context.getAssets (); 192 of EmacsNoninteractive, which will indicate to the system
172 193 that it must load shared libraries from the APK's library
173 /* Now configure Emacs. The class path should already be set. */ 194 search path. */
174 195
175 filesDir = context.getFilesDir ().getCanonicalPath (); 196 method = loadedApkClass.getDeclaredMethod ("getClassLoader");
176 libDir = EmacsService.getLibraryDirectory (context); 197 classLoader = (ClassLoader) method.invoke (loadedApk);
177 cacheDir = context.getCacheDir ().getCanonicalPath ();
178 } 198 }
179 catch (Exception e) 199 catch (Exception e)
180 { 200 {
@@ -188,16 +208,20 @@ public final class EmacsNoninteractive
188 System.exit (1); 208 System.exit (1);
189 } 209 }
190 210
191 EmacsNative.setEmacsParams (assets, filesDir, 211 try
192 libDir, cacheDir, 0.0f, 212 {
193 0.0f, 0.0f, null, null, 213 emacsNoninteractiveClass
194 Build.VERSION.SDK_INT); 214 = classLoader.loadClass ("org.gnu.emacs.EmacsNoninteractive");
195 215 method = emacsNoninteractiveClass.getMethod ("main1", String[].class,
196 /* Now find the dump file that Emacs should use, if it has already 216 Context.class);
197 been dumped. */ 217 method.setAccessible (true);
198 EmacsApplication.findDumpFile (context); 218 method.invoke (null, args, context);
199 219 }
200 /* Start Emacs. */ 220 catch (Exception e)
201 EmacsNative.initEmacs (args, EmacsApplication.dumpFileName); 221 {
222 System.err.println ("Internal error during startup: " + e);
223 e.printStackTrace ();
224 System.exit (1);
225 }
202 } 226 }
203}; 227};
diff --git a/lisp/transient.el b/lisp/transient.el
index 312ed540f73..05ad0ed8a0b 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -5,7 +5,7 @@
5;; Author: Jonas Bernoulli <jonas@bernoul.li> 5;; Author: Jonas Bernoulli <jonas@bernoul.li>
6;; URL: https://github.com/magit/transient 6;; URL: https://github.com/magit/transient
7;; Keywords: extensions 7;; Keywords: extensions
8;; Version: 0.7.2 8;; Version: 0.7.2.1
9 9
10;; SPDX-License-Identifier: GPL-3.0-or-later 10;; SPDX-License-Identifier: GPL-3.0-or-later
11 11
diff --git a/lisp/which-key.el b/lisp/which-key.el
index 677a84b328d..37b42a009f7 100644
--- a/lisp/which-key.el
+++ b/lisp/which-key.el
@@ -444,7 +444,7 @@ Note that `which-key-idle-delay' should be set before turning on
444If non-nil, save window configuration before which-key buffer is 444If non-nil, save window configuration before which-key buffer is
445shown and restore it after which-key buffer is hidden. It 445shown and restore it after which-key buffer is hidden. It
446prevents which-key from changing window position of visible 446prevents which-key from changing window position of visible
447buffers. Only takken into account when popup type is 447buffers. Only taken into account when popup type is
448side-window." 448side-window."
449 :type 'boolean 449 :type 'boolean
450 :package-version "1.0" :version "30.1") 450 :package-version "1.0" :version "30.1")
@@ -2113,7 +2113,7 @@ should be minimized."
2113(defun which-key--create-pages (keys &optional prefix-keys prefix-title) 2113(defun which-key--create-pages (keys &optional prefix-keys prefix-title)
2114 "Create page strings using `which-key--list-to-pages'. 2114 "Create page strings using `which-key--list-to-pages'.
2115Will try to find the best number of rows and columns using the 2115Will try to find the best number of rows and columns using the
2116given dimensions and the length and wdiths of KEYS. SEL-WIN-WIDTH 2116given dimensions and the length and widths of KEYS. SEL-WIN-WIDTH
2117is the width of the live window." 2117is the width of the live window."
2118 (let* ((max-dims (which-key--popup-max-dimensions)) 2118 (let* ((max-dims (which-key--popup-max-dimensions))
2119 (max-lines (car max-dims)) 2119 (max-lines (car max-dims))
@@ -2825,7 +2825,7 @@ Finally, show the buffer."
2825 (funcall which-key-this-command-keys-function))))) 2825 (funcall which-key-this-command-keys-function)))))
2826 (cancel-timer which-key--paging-timer) 2826 (cancel-timer which-key--paging-timer)
2827 (if which-key-idle-secondary-delay 2827 (if which-key-idle-secondary-delay
2828 ;; we haven't executed a command yet so the secandary 2828 ;; we haven't executed a command yet so the secondary
2829 ;; timer is more relevant here 2829 ;; timer is more relevant here
2830 (which-key--start-timer which-key-idle-secondary-delay t) 2830 (which-key--start-timer which-key-idle-secondary-delay t)
2831 (which-key--start-timer))))))) 2831 (which-key--start-timer)))))))
diff --git a/src/android-emacs.c b/src/android-emacs.c
index d68734da1bd..28b46ca1a4b 100644
--- a/src/android-emacs.c
+++ b/src/android-emacs.c
@@ -37,7 +37,7 @@ main (int argc, char **argv)
37{ 37{
38 char **args; 38 char **args;
39 int i; 39 int i;
40 char *bootclasspath, *emacs_class_path, *ld_library_path; 40 char *bootclasspath, *emacs_class_path;
41 41
42 /* Allocate enough to hold the arguments to app_process. */ 42 /* Allocate enough to hold the arguments to app_process. */
43 args = alloca ((10 + argc) * sizeof *args); 43 args = alloca ((10 + argc) * sizeof *args);
@@ -63,15 +63,6 @@ main (int argc, char **argv)
63 return 1; 63 return 1;
64 } 64 }
65 65
66 /* Restore LD_LIBRARY_PATH to its original value, the app library
67 directory, to guarantee that it is possible for Java to find the
68 Emacs C code later. */
69
70 ld_library_path = getenv ("EMACS_LD_LIBRARY_PATH");
71
72 if (ld_library_path)
73 setenv ("LD_LIBRARY_PATH", ld_library_path, 1);
74
75 if (asprintf (&bootclasspath, "-Djava.class.path=%s", 66 if (asprintf (&bootclasspath, "-Djava.class.path=%s",
76 emacs_class_path) < 0) 67 emacs_class_path) < 0)
77 { 68 {
diff --git a/src/android.c b/src/android.c
index f90ebc04925..3c96867a6b5 100644
--- a/src/android.c
+++ b/src/android.c
@@ -1338,7 +1338,7 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
1338 1338
1339 int pipefd[2]; 1339 int pipefd[2];
1340 pthread_t thread; 1340 pthread_t thread;
1341 const char *java_string; 1341 const char *java_string, *tem;
1342 struct stat statb; 1342 struct stat statb;
1343 1343
1344#ifdef THREADS_ENABLED 1344#ifdef THREADS_ENABLED
@@ -1491,15 +1491,6 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
1491 EmacsNoninteractive can be found. */ 1491 EmacsNoninteractive can be found. */
1492 setenv ("EMACS_CLASS_PATH", android_class_path, 1); 1492 setenv ("EMACS_CLASS_PATH", android_class_path, 1);
1493 1493
1494 /* Set LD_LIBRARY_PATH to an appropriate value. */
1495 setenv ("LD_LIBRARY_PATH", android_lib_dir, 1);
1496
1497 /* EMACS_LD_LIBRARY_PATH records the location of the app library
1498 directory. android-emacs refers to this, since users have valid
1499 reasons for changing LD_LIBRARY_PATH to a value that precludes
1500 the possibility of Java locating libemacs later. */
1501 setenv ("EMACS_LD_LIBRARY_PATH", android_lib_dir, 1);
1502
1503 /* If the system is Android 5.0 or later, set LANG to en_US.utf8, 1494 /* If the system is Android 5.0 or later, set LANG to en_US.utf8,
1504 which is understood by the C library. In other instances set it 1495 which is understood by the C library. In other instances set it
1505 to C, a meaningless value, for good measure. */ 1496 to C, a meaningless value, for good measure. */