From 7fb3c0d0397096f643f6239d50cf52eaf96e7b07 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 2 Mar 2023 09:27:37 +0800 Subject: [PATCH] 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): * java/org/gnu/emacs/EmacsSdk7FontDriver.java (EmacsSdk7FontDriver): * java/org/gnu/emacs/EmacsService.java (queryBattery): * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): Make functions final and classes static where necessary. * 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/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. * src/androidterm.c (handle_one_android_event): Fix out of date commentary. --- doc/emacs/android.texi | 5 ++-- java/org/gnu/emacs/EmacsActivity.java | 2 +- java/org/gnu/emacs/EmacsContextMenu.java | 2 +- java/org/gnu/emacs/EmacsFontDriver.java | 6 ++--- java/org/gnu/emacs/EmacsSdk7FontDriver.java | 6 ++--- java/org/gnu/emacs/EmacsService.java | 24 +++++++++++++++++- java/org/gnu/emacs/EmacsWindow.java | 3 ++- src/android.c | 28 +++++++++++++++++++++ src/android.h | 1 + src/androidfns.c | 5 ++++ src/androidselect.c | 12 +++++++++ src/androidterm.c | 7 ++---- 12 files changed, 83 insertions(+), 18 deletions(-) diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi index 65ebdfa9ab1..9852755d649 100644 --- a/doc/emacs/android.texi +++ b/doc/emacs/android.texi @@ -438,9 +438,8 @@ that window. @cindex windowing limitations, android @cindex frame parameters, android -Due to the unusual nature of the Android windowing environment, Emacs -only supports a limited subset of GUI features. Here is a list of -known limitations, and features which are not implemented: +Emacs only supports a limited subset of GUI features on Android; the +limitations are as follows: @itemize @bullet @item diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index 1c5d7605caa..c444110de60 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java @@ -207,7 +207,7 @@ public class EmacsActivity extends Activity } @Override - public void + public final void onDestroy () { EmacsWindowAttachmentManager manager; diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java index 0de292af21a..a1bca98daa0 100644 --- a/java/org/gnu/emacs/EmacsContextMenu.java +++ b/java/org/gnu/emacs/EmacsContextMenu.java @@ -52,7 +52,7 @@ public final class EmacsContextMenu /* Whether or not a submenu was selected. */ public static boolean wasSubmenuSelected; - private class Item implements MenuItem.OnMenuItemClickListener + private static class Item implements MenuItem.OnMenuItemClickListener { public int itemID; public String itemName, tooltip; diff --git a/java/org/gnu/emacs/EmacsFontDriver.java b/java/org/gnu/emacs/EmacsFontDriver.java index 39bda5a456d..e142a3121d3 100644 --- a/java/org/gnu/emacs/EmacsFontDriver.java +++ b/java/org/gnu/emacs/EmacsFontDriver.java @@ -65,7 +65,7 @@ public abstract class EmacsFontDriver public static final int MONO = 100; public static final int CHARCELL = 110; - public class FontSpec + public static class FontSpec { /* The fields below mean the same as they do in enum font_property_index in font.h. */ @@ -99,7 +99,7 @@ public abstract class EmacsFontDriver } }; - public class FontMetrics + public static class FontMetrics { public short lbearing; public short rbearing; @@ -119,7 +119,7 @@ public abstract class EmacsFontDriver } } - public class FontEntity extends FontSpec + public static class FontEntity extends FontSpec { /* No extra fields here. */ }; diff --git a/java/org/gnu/emacs/EmacsSdk7FontDriver.java b/java/org/gnu/emacs/EmacsSdk7FontDriver.java index ba92d4cef49..ae91c299de8 100644 --- a/java/org/gnu/emacs/EmacsSdk7FontDriver.java +++ b/java/org/gnu/emacs/EmacsSdk7FontDriver.java @@ -40,7 +40,7 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver private static final String EM_STRING = "m"; private static final String TAG = "EmacsSdk7FontDriver"; - protected class Sdk7Typeface + protected static final class Sdk7Typeface { /* The typeface and paint. */ public Typeface typeface; @@ -164,7 +164,7 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver } }; - protected class Sdk7FontEntity extends FontEntity + protected static final class Sdk7FontEntity extends FontEntity { /* The typeface. */ public Sdk7Typeface typeface; @@ -187,7 +187,7 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver } }; - protected class Sdk7FontObject extends FontObject + protected final class Sdk7FontObject extends FontObject { /* The typeface. */ public Sdk7Typeface typeface; diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index e61d9487375..67de5d26f53 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -54,6 +54,8 @@ import android.content.res.AssetManager; import android.database.Cursor; import android.database.MatrixCursor; +import android.hardware.input.InputManager; + import android.net.Uri; import android.os.BatteryManager; @@ -72,7 +74,7 @@ import android.provider.DocumentsContract.Document; import android.util.Log; import android.util.DisplayMetrics; -import android.hardware.input.InputManager; +import android.widget.Toast; class Holder { @@ -821,4 +823,24 @@ public final class EmacsService extends Service return new long[] { capacity, chargeCounter, currentAvg, currentNow, remaining, status, }; } + + /* Display the specified STRING in a small dialog box on the main + thread. */ + + public void + displayToast (final String string) + { + runOnUiThread (new Runnable () { + @Override + public void + run () + { + Toast toast; + + toast = Toast.makeText (getApplicationContext (), + string, Toast.LENGTH_SHORT); + toast.show (); + } + }); + } }; diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 5c481aa3ef4..ea4cf48090d 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -64,11 +64,12 @@ public final class EmacsWindow extends EmacsHandleObject { private static final String TAG = "EmacsWindow"; - private class Coordinate + private static class Coordinate { /* Integral coordinate. */ int x, y; + public Coordinate (int x, int y) { this.x = x; diff --git a/src/android.c b/src/android.c index 3bccaab041a..daeb7ab70f6 100644 --- a/src/android.c +++ b/src/android.c @@ -112,6 +112,7 @@ struct android_emacs_service jmethodID open_content_uri; jmethodID check_content_uri; jmethodID query_battery; + jmethodID display_toast; }; struct android_emacs_pixmap @@ -2124,6 +2125,8 @@ android_init_emacs_service (void) FIND_METHOD (check_content_uri, "checkContentUri", "([BZZ)Z"); FIND_METHOD (query_battery, "queryBattery", "()[J"); + FIND_METHOD (display_toast, "displayToast", + "(Ljava/lang/String;)V"); #undef FIND_METHOD } @@ -5696,6 +5699,31 @@ android_query_battery (struct android_battery_state *status) return 0; } +/* Display a small momentary notification on screen containing + TEXT, which must be in the modified UTF encoding used by the + JVM. */ + +void +android_display_toast (const char *text) +{ + jstring string; + + /* Make the string. */ + string = (*android_java_env)->NewStringUTF (android_java_env, + text); + android_exception_check (); + + /* Display the toast. */ + (*android_java_env)->CallVoidMethod (android_java_env, + emacs_service, + service_class.display_toast, + string); + android_exception_check_1 (string); + + /* Delete the local reference to the string. */ + ANDROID_DELETE_LOCAL_REF (string); +} + /* Whether or not a query is currently being made. */ diff --git a/src/android.h b/src/android.h index 806be4f9954..95206b77979 100644 --- a/src/android.h +++ b/src/android.h @@ -140,6 +140,7 @@ struct android_battery_state extern Lisp_Object android_browse_url (Lisp_Object); extern int android_query_battery (struct android_battery_state *); +extern void android_display_toast (const char *); diff --git a/src/androidfns.c b/src/androidfns.c index dc68cef8a02..4837b00a21e 100644 --- a/src/androidfns.c +++ b/src/androidfns.c @@ -2357,6 +2357,11 @@ there is no mouse. */) (void) { #ifndef ANDROID_STUBIFY + /* If no display connection is present, just return nil. */ + + if (!android_init_gui) + return Qnil; + return android_detect_mouse () ? Qt : Qnil; #else return Qnil; diff --git a/src/androidselect.c b/src/androidselect.c index 3947ab99166..f54a6d6f52c 100644 --- a/src/androidselect.c +++ b/src/androidselect.c @@ -110,6 +110,9 @@ determined. */) { jint rc; + if (!android_init_gui) + error ("Accessing clipboard without display connection"); + block_input (); rc = (*android_java_env)->CallIntMethod (android_java_env, clipboard, @@ -133,6 +136,9 @@ DEFUN ("android-set-clipboard", Fandroid_set_clipboard, { jarray bytes; + if (!android_init_gui) + error ("Accessing clipboard without display connection"); + CHECK_STRING (string); string = ENCODE_UTF_8 (string); @@ -167,6 +173,9 @@ Alternatively, return nil if the clipboard is empty. */) size_t length; jbyte *data; + if (!android_init_gui) + error ("No Android display connection!"); + method = clipboard_class.get_clipboard; bytes = (*android_java_env)->CallObjectMethod (android_java_env, @@ -217,6 +226,9 @@ URL with a scheme specified. Signal an error upon failure. */) { Lisp_Object value; + if (!android_init_gui) + error ("No Android display connection!"); + CHECK_STRING (url); value = android_browse_url (url); diff --git a/src/androidterm.c b/src/androidterm.c index 8a67d128348..814af87819b 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -866,9 +866,8 @@ handle_one_android_event (struct android_display_info *dpyinfo, if (event->xaction.action == 0) { - /* Action 0 either means to destroy a frame or to create a - new frame, depending on whether or not - event->xaction.window exists. */ + /* Action 0 either means that a window has been destroyed + and its associated frame should be as well. */ if (event->xaction.window) { @@ -878,8 +877,6 @@ handle_one_android_event (struct android_display_info *dpyinfo, inev.ie.kind = DELETE_WINDOW_EVENT; XSETFRAME (inev.ie.frame_or_window, f); } - else - ((void) 0) /* A new frame must be created. */; } case ANDROID_ENTER_NOTIFY: -- 2.39.2