aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-01-28 16:29:22 +0800
committerPo Lu2023-01-28 16:29:22 +0800
commit198b8160cfeeb178d3b2073c8d03afdafe338908 (patch)
tree590c73006536ddfcc8acd8eff8fb80e31c2a009b
parent5bd38905ac67221503f027737912fa0df3602a02 (diff)
downloademacs-198b8160cfeeb178d3b2073c8d03afdafe338908.tar.gz
emacs-198b8160cfeeb178d3b2073c8d03afdafe338908.zip
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. * 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.
-rw-r--r--doc/emacs/android.texi20
-rw-r--r--java/AndroidManifest.xml.in4
-rw-r--r--java/README63
-rw-r--r--java/org/gnu/emacs/EmacsContextMenu.java22
-rw-r--r--java/org/gnu/emacs/EmacsCopyArea.java6
-rw-r--r--lisp/menu-bar.el5
-rw-r--r--src/androidmenu.c17
-rw-r--r--src/menu.c2
8 files changed, 123 insertions, 16 deletions
diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi
index 98d7f1e1d9e..ae4080994b8 100644
--- a/doc/emacs/android.texi
+++ b/doc/emacs/android.texi
@@ -177,17 +177,27 @@ makes the system more secure. Unfortunately, it also means that Emacs
177cannot access files in those directories, despite holding the 177cannot access files in those directories, despite holding the
178necessary permissions. Thankfully, the Open Handset Alliance's 178necessary permissions. Thankfully, the Open Handset Alliance's
179version of Android allows this restriction to be disabled on a 179version of Android allows this restriction to be disabled on a
180per-program basis; the corresponding option in the system settings 180per-program basis; on Android 10, the corresponding option in the
181panel is: 181system settings panel is:
182 182
183@indentedblock 183@indentedblock
184System -> Developer Options -> App Compatibility Changes -> Emacs -> 184System -> Developer Options -> App Compatibility Changes -> Emacs ->
185DEFAULT_SCOPED_STORAGE 185DEFAULT_SCOPED_STORAGE
186@end indentedblock 186@end indentedblock
187 187
188 After you disable this setting and grant Emacs the ``Files and 188 And on Android 11 and later, the corresponding option in the systems
189Media'' permission, it will be able to access files under 189settings panel is:
190@file{/sdcard} as usual. 190
191@indentedblock
192System -> Apps -> Special App Access -> All files access -> Emacs
193@end indentedblock
194
195 After you disable or enable this setting as appropriate and grant
196Emacs the ``Files and Media'' permission, it will be able to access
197files under @file{/sdcard} as usual.
198
199 These settings are not present on many proprietary versions of
200Android.
191 201
192@node Android Environment 202@node Android Environment
193@section Running Emacs under Android 203@section Running Emacs under Android
diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in
index 527ce74c474..09e4e788e0b 100644
--- a/java/AndroidManifest.xml.in
+++ b/java/AndroidManifest.xml.in
@@ -52,6 +52,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
52 <uses-permission android:name="android.permission.RECORD_AUDIO" /> 52 <uses-permission android:name="android.permission.RECORD_AUDIO" />
53 <uses-permission android:name="android.permission.CAMERA" /> 53 <uses-permission android:name="android.permission.CAMERA" />
54 54
55 <!-- This is required on Android 11 or later to access /sdcard. -->
56
57 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
58
55 <uses-sdk android:minSdkVersion="@ANDROID_MIN_SDK@" 59 <uses-sdk android:minSdkVersion="@ANDROID_MIN_SDK@"
56 android:targetSdkVersion="33"/> 60 android:targetSdkVersion="33"/>
57 61
diff --git a/java/README b/java/README
index 44f5a415162..3bce2556403 100644
--- a/java/README
+++ b/java/README
@@ -292,15 +292,15 @@ public class EmacsFrobinicator
292 } 292 }
293} 293}
294 294
295Java arrays are similar to C arrays in that they can not grow. But 295Java arrays are similar to C arrays in that they can not grow. But
296they are very much unlike C arrays in that they are always references 296they are very much unlike C arrays in that they are always references
297(as opposed to decaying into pointers in various situations), and 297(as opposed to decaying into pointers in only some situations), and
298contain information about their length. 298contain information about their length.
299 299
300If another function named ``frobinicate1'' takes an array as an 300If another function named ``frobinicate1'' takes an array as an
301argument, then it need not take the length of the array. 301argument, then it need not take the length of the array.
302 302
303Instead, it simply iterates over the array like so: 303Instead, it may simply iterate over the array like so:
304 304
305int i, k; 305int i, k;
306 306
@@ -339,10 +339,65 @@ struct emacs_array_container
339 339
340or, possibly even better, 340or, possibly even better,
341 341
342typedef int my_array[10]; 342typedef int emacs_array_container[10];
343 343
344Alas, Java has no equivalent of `typedef'. 344Alas, Java has no equivalent of `typedef'.
345 345
346Like in C, Java string literals are delimited by double quotes.
347Unlike C, however, strings are not NULL-terminated arrays of
348characters, but a distinct type named ``String''. They store their
349own length, characters in Java's 16-bit ``char'' type, and are capable
350of holding NULL bytes.
351
352Instead of writing:
353
354wchar_t character;
355extern char *s;
356size_t s;
357
358 for (/* determine n, s in a loop. */)
359 s += mbstowc (&character, s, n);
360
361or:
362
363const char *byte;
364
365for (byte = my_string; *byte; ++byte)
366 /* do something with *byte. */;
367
368or perhaps even:
369
370size_t length, i;
371char foo;
372
373length = strlen (my_string);
374
375for (i = 0; i < length; ++i)
376 foo = my_string[i];
377
378you write:
379
380char foo;
381int i;
382
383for (i = 0; i < myString.length (); ++i)
384 foo = myString.charAt (0);
385
386Java also has stricter rules on what can be used as a truth value in a
387conditional. While in C, any non-zero value is true, Java requires
388that every truth value be of the boolean type ``boolean''.
389
390What this means is that instead of simply writing:
391
392 if (foo || bar)
393
394where foo can either be 1 or 0, and bar can either be NULL or a
395pointer to something, you must explicitly write:
396
397 if (foo != 0 || bar != null)
398
399in Java.
400
346JAVA NATIVE INTERFACE 401JAVA NATIVE INTERFACE
347 402
348Java also provides an interface for C code to interface with Java. 403Java also provides an interface for C code to interface with Java.
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java
index 056d8fb692c..92429410d03 100644
--- a/java/org/gnu/emacs/EmacsContextMenu.java
+++ b/java/org/gnu/emacs/EmacsContextMenu.java
@@ -56,7 +56,7 @@ public class EmacsContextMenu
56 public int itemID; 56 public int itemID;
57 public String itemName; 57 public String itemName;
58 public EmacsContextMenu subMenu; 58 public EmacsContextMenu subMenu;
59 public boolean isEnabled; 59 public boolean isEnabled, isCheckable, isChecked;
60 60
61 @Override 61 @Override
62 public boolean 62 public boolean
@@ -108,10 +108,15 @@ public class EmacsContextMenu
108 108
109 /* Add a normal menu item to the context menu with the id ITEMID and 109 /* Add a normal menu item to the context menu with the id ITEMID and
110 the name ITEMNAME. Enable it if ISENABLED, else keep it 110 the name ITEMNAME. Enable it if ISENABLED, else keep it
111 disabled. */ 111 disabled.
112
113 If this is not a submenu and ISCHECKABLE is set, make the item
114 checkable. Likewise, if ISCHECKED is set, make the item
115 checked. */
112 116
113 public void 117 public void
114 addItem (int itemID, String itemName, boolean isEnabled) 118 addItem (int itemID, String itemName, boolean isEnabled,
119 boolean isCheckable, boolean isChecked)
115 { 120 {
116 Item item; 121 Item item;
117 122
@@ -119,6 +124,8 @@ public class EmacsContextMenu
119 item.itemID = itemID; 124 item.itemID = itemID;
120 item.itemName = itemName; 125 item.itemName = itemName;
121 item.isEnabled = isEnabled; 126 item.isEnabled = isEnabled;
127 item.isCheckable = isCheckable;
128 item.isChecked = isChecked;
122 129
123 menuItems.add (item); 130 menuItems.add (item);
124 } 131 }
@@ -198,6 +205,15 @@ public class EmacsContextMenu
198 /* If the item ID is zero, then disable the item. */ 205 /* If the item ID is zero, then disable the item. */
199 if (item.itemID == 0 || !item.isEnabled) 206 if (item.itemID == 0 || !item.isEnabled)
200 menuItem.setEnabled (false); 207 menuItem.setEnabled (false);
208
209 /* Now make the menu item display a checkmark as
210 appropriate. */
211
212 if (item.isCheckable)
213 menuItem.setCheckable (true);
214
215 if (item.isChecked)
216 menuItem.setChecked (true);
201 } 217 }
202 } 218 }
203 } 219 }
diff --git a/java/org/gnu/emacs/EmacsCopyArea.java b/java/org/gnu/emacs/EmacsCopyArea.java
index 7a97d706794..f8974e17c2e 100644
--- a/java/org/gnu/emacs/EmacsCopyArea.java
+++ b/java/org/gnu/emacs/EmacsCopyArea.java
@@ -99,6 +99,12 @@ public class EmacsCopyArea
99 if (src_y + height > srcBitmap.getHeight ()) 99 if (src_y + height > srcBitmap.getHeight ())
100 height = srcBitmap.getHeight () - src_y; 100 height = srcBitmap.getHeight () - src_y;
101 101
102 /* If width and height are empty or negative, then skip the entire
103 CopyArea operation lest createBitmap throw an exception. */
104
105 if (width <= 0 || height <= 0)
106 return;
107
102 rect = new Rect (dest_x, dest_y, dest_x + width, 108 rect = new Rect (dest_x, dest_y, dest_x + width,
103 dest_y + height); 109 dest_y + height);
104 110
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index d020cf6e90a..2d907fb3827 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -472,6 +472,11 @@
472(defvar menu-bar-edit-menu 472(defvar menu-bar-edit-menu
473 (let ((menu (make-sparse-keymap "Edit"))) 473 (let ((menu (make-sparse-keymap "Edit")))
474 474
475 (bindings--define-key menu [execute-extended-command]
476 '(menu-item "Execute Command" execute-extended-command
477 :enable t
478 :help "Read a command name, its arguments, then call it."))
479
475 ;; ns-win.el said: Add spell for platform consistency. 480 ;; ns-win.el said: Add spell for platform consistency.
476 (if (featurep 'ns) 481 (if (featurep 'ns)
477 (bindings--define-key menu [spell] 482 (bindings--define-key menu [spell]
diff --git a/src/androidmenu.c b/src/androidmenu.c
index 7b27825ad60..acad775f26a 100644
--- a/src/androidmenu.c
+++ b/src/androidmenu.c
@@ -98,7 +98,7 @@ android_init_emacs_context_menu (void)
98 FIND_METHOD_STATIC (create_context_menu, "createContextMenu", 98 FIND_METHOD_STATIC (create_context_menu, "createContextMenu",
99 "(Ljava/lang/String;)Lorg/gnu/emacs/EmacsContextMenu;"); 99 "(Ljava/lang/String;)Lorg/gnu/emacs/EmacsContextMenu;");
100 100
101 FIND_METHOD (add_item, "addItem", "(ILjava/lang/String;Z)V"); 101 FIND_METHOD (add_item, "addItem", "(ILjava/lang/String;ZZZ)V");
102 FIND_METHOD (add_submenu, "addSubmenu", "(Ljava/lang/String;" 102 FIND_METHOD (add_submenu, "addSubmenu", "(Ljava/lang/String;"
103 "Ljava/lang/String;)Lorg/gnu/emacs/EmacsContextMenu;"); 103 "Ljava/lang/String;)Lorg/gnu/emacs/EmacsContextMenu;");
104 FIND_METHOD (add_pane, "addPane", "(Ljava/lang/String;)V"); 104 FIND_METHOD (add_pane, "addPane", "(Ljava/lang/String;)V");
@@ -241,7 +241,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
241 Lisp_Object pane_name, prefix; 241 Lisp_Object pane_name, prefix;
242 const char *pane_string; 242 const char *pane_string;
243 specpdl_ref count, count1; 243 specpdl_ref count, count1;
244 Lisp_Object item_name, enable, def, tem, entry; 244 Lisp_Object item_name, enable, def, tem, entry, type, selected;
245 jmethodID method; 245 jmethodID method;
246 jobject store; 246 jobject store;
247 bool rc; 247 bool rc;
@@ -250,6 +250,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
250 struct android_dismiss_menu_data data; 250 struct android_dismiss_menu_data data;
251 struct android_menu_subprefix *subprefix, *temp_subprefix; 251 struct android_menu_subprefix *subprefix, *temp_subprefix;
252 struct android_menu_subprefix *subprefix_1; 252 struct android_menu_subprefix *subprefix_1;
253 bool checkmark;
253 254
254 count = SPECPDL_INDEX (); 255 count = SPECPDL_INDEX ();
255 256
@@ -351,6 +352,8 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
351 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 352 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
352 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 353 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
353 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); 354 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
355 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
356 selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
354 357
355 /* This is an actual menu item (or submenu). Add it to the 358 /* This is an actual menu item (or submenu). Add it to the
356 menu. */ 359 menu. */
@@ -392,12 +395,20 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
392 title_string = (!NILP (item_name) 395 title_string = (!NILP (item_name)
393 ? android_build_string (item_name) 396 ? android_build_string (item_name)
394 : NULL); 397 : NULL);
398
399 /* Determine whether or not to display a check box. */
400
401 checkmark = (EQ (type, QCtoggle)
402 || EQ (type, QCradio));
403
395 (*android_java_env)->CallVoidMethod (android_java_env, 404 (*android_java_env)->CallVoidMethod (android_java_env,
396 current_context_menu, 405 current_context_menu,
397 menu_class.add_item, 406 menu_class.add_item,
398 (jint) item_id, 407 (jint) item_id,
399 title_string, 408 title_string,
400 (jboolean) !NILP (enable)); 409 (jboolean) !NILP (enable),
410 (jboolean) checkmark,
411 (jboolean) !NILP (selected));
401 android_exception_check (); 412 android_exception_check ();
402 413
403 if (title_string) 414 if (title_string)
diff --git a/src/menu.c b/src/menu.c
index e02ee880119..6ab34a16996 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -48,7 +48,7 @@ static bool
48have_boxes (void) 48have_boxes (void)
49{ 49{
50#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined (HAVE_NS) \ 50#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined (HAVE_NS) \
51 || defined (HAVE_HAIKU) 51 || defined (HAVE_HAIKU) || defined (HAVE_ANDROID)
52 if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame))) 52 if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame)))
53 return 1; 53 return 1;
54#endif 54#endif