]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Thu, 2 Mar 2023 01:27:37 +0000 (09:27 +0800)
committerPo Lu <luangruo@yahoo.com>
Thu, 2 Mar 2023 01:27:37 +0000 (09:27 +0800)
* 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.

12 files changed:
doc/emacs/android.texi
java/org/gnu/emacs/EmacsActivity.java
java/org/gnu/emacs/EmacsContextMenu.java
java/org/gnu/emacs/EmacsFontDriver.java
java/org/gnu/emacs/EmacsSdk7FontDriver.java
java/org/gnu/emacs/EmacsService.java
java/org/gnu/emacs/EmacsWindow.java
src/android.c
src/android.h
src/androidfns.c
src/androidselect.c
src/androidterm.c

index 65ebdfa9ab14d3f325cc9f1f8882ced41689e24e..9852755d649f9b29c32c7bdddcfd1d4dc3b4a756 100644 (file)
@@ -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
index 1c5d7605caadfaded7ae0e998205f7a821eb77d0..c444110de60586155622a302fee51fd62acc8b7d 100644 (file)
@@ -207,7 +207,7 @@ public class EmacsActivity extends Activity
   }
 
   @Override
-  public void
+  public final void
   onDestroy ()
   {
     EmacsWindowAttachmentManager manager;
index 0de292af21a932e4eb969be8d7b4169148985c5c..a1bca98daa047bac08298affd5996d8ef5385ecd 100644 (file)
@@ -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;
index 39bda5a456df8f86f1b1e03b954113b36fadfd58..e142a3121d31b81882dd1af484f6865a5a0e2649 100644 (file)
@@ -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.  */
   };
index ba92d4cef4982a0b46febb629d7df3f24113751b..ae91c299de81be35406583cd7257c6111e94af3f 100644 (file)
@@ -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;
index e61d9487375ce063cbb988ad84388e2e09f8ef73..67de5d26f53c3df91c9da2065f8760f4c04b9588 100644 (file)
@@ -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<T>
 {
@@ -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 ();
+       }
+      });
+  }
 };
index 5c481aa3ef45ba10e8f55b38316b7da04989a888..ea4cf48090d3a291cb5f6d73274373884f65c940 100644 (file)
@@ -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;
index 3bccaab041a168d27c3339e8483caa0931fa08ba..daeb7ab70f6dea64efe8354418daf6613354602d 100644 (file)
@@ -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);
+}
+
 \f
 
 /* Whether or not a query is currently being made.  */
index 806be4f9954c10d1b10a7c5a8fb7a5700ec5b924..95206b77979f7a0556bdf510dcce7c5c0f94b1ca 100644 (file)
@@ -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 *);
 
 \f
 
index dc68cef8a021af85faf8233b7fc34c6a6085caac..4837b00a21e65718b7a23681504ee496be7c247e 100644 (file)
@@ -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;
index 3947ab99166a676d665b97fd6196b5964315be0e..f54a6d6f52ca2522481f2ca28c5b139b65931629 100644 (file)
@@ -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);
 
index 8a67d12834895956f5541b6519073169be17b9da..814af87819be9f2171a81c36e7a5e2842f0da8b9 100644 (file)
@@ -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: