]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Thu, 26 Jan 2023 14:11:04 +0000 (22:11 +0800)
committerPo Lu <luangruo@yahoo.com>
Thu, 26 Jan 2023 14:11:04 +0000 (22:11 +0800)
* INSTALL.android: Describe 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'.
* 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.
* 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
operating systems.
* src/xterm.h (struct x_display_info): New fields `quit_keysym',
`quit_keysym_time'.

INSTALL.android
configure.ac
cross/Makefile.in
doc/emacs/input.texi
java/org/gnu/emacs/EmacsNative.java
java/org/gnu/emacs/EmacsWindow.java
m4/ndk-build.m4
src/android.c
src/androidmenu.c
src/xterm.c
src/xterm.h

index 06211e5ec93e327eb2f1a8179a274f00a75d5d4e..e5d7162140de70cd056837824ee9cd4fc79d9339 100644 (file)
@@ -40,8 +40,8 @@ Replacing the paths in the command line above with:
     are building Emacs to run on.
 
   - the path to the directory in the Android SDK containing binaries
-    such as `aapt' and `d8'.  These are used to build the application
-    package.
+    such as `aapt', `apksigner', and `d8'.  These are used to build
+    the application package.
 
 After the configuration process completes, you may run:
 
index 879e4ab74aa25fbb44e85cb3684b5eaf726481c1..aaee65016b2bed7f46953c45017e6c4125016b36 100644 (file)
@@ -7411,11 +7411,7 @@ if test -f "$srcdir/$opt_makefile.in"; then
 fi
 
 if test "$ANDROID" = "yes"; then
-  SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES java/Makefile"
-fi
-
-if test "$XCOMPILE" = "yes"; then
-  SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES cross/Makefile"
+  SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES java/Makefile cross/Makefile"
 fi
 
 dnl The admin/ directory used to be excluded from tarfiles.
index 92f8d068975e7351b2e6e2b6e8fb9740a9a20e51..a44550c656331b1d7748dc24ae4baafa1151753e 100644 (file)
@@ -60,8 +60,9 @@ all: lib/libgnu.a src/libemacs.so src/android-emacs $(LIBSRC_BINARIES)
 # This Makefile relies on builddir and top_builddir being relative
 # paths in *.android.
 
-# This file is used to trick lib/gnulib.mk, it is not actually useful.
-config.status:
+# This file is used to tell lib/gnulib.mk when
+# $(top_srcdir)/config.status changes.
+config.status: $(top_srcdir)/config.status
        touch config.status
 
 src/verbose.mk: verbose.mk.android
index 1a58d1ca0accb62ac9ad2c361d83f8b86da9a1f7..3894d4872e0938c7f75111029de1bc31dfdc51f1 100644 (file)
@@ -94,3 +94,15 @@ that the user is about to enter text in to the current buffer.
   Emacs also provides a set of functions to show or hide the on-screen
 keyboard.  For more details, @pxref{On-Screen Keyboards,,, elisp, The
 Emacs Lisp Reference Manual}.
+
+@cindex quitting, without a keyboard
+  Since it may not be possible for Emacs to display the on screen
+keyboard when it is executing a command, Emacs implements a feature on
+devices with only an on-screen keyboard, by which two rapid clicks of
+a hardware button that is always present on the device results in
+Emacs quitting.  @xref{Quitting}.
+
+@defvar x-quit-keysym
+  The exact button is used to do this varies by system: on X, it is
+defined in the variable @code{x-quit-keysym}, and on Android, it is
+always the volume down button.
index 7bf8b5f6081ab8a6f33545a9bd1449382fd2fb45..4e91a7be32261a1cbbef97ae559c755f690f4ad8 100644 (file)
@@ -74,6 +74,10 @@ public class EmacsNative
   /* Abort and generate a native core dump.  */
   public static native void emacsAbort ();
 
+  /* Set Vquit_flag to t, resulting in Emacs quitting as soon as
+     possible.  */
+  public static native void quit ();
+
   /* Send an ANDROID_CONFIGURE_NOTIFY event.  The values of all the
      functions below are the serials of the events sent.  */
   public static native long sendConfigureNotify (short window, long time,
index 8511af9193e02bd0ad76fda0e713c70dcbb04bd0..39eaf2fff806aafcd4f99de1033f54fe0469d610 100644 (file)
@@ -124,6 +124,10 @@ public class EmacsWindow extends EmacsHandleObject
      there is no such window manager.  */
   private WindowManager windowManager;
 
+  /* The time of the last KEYCODE_VOLUME_DOWN press.  This is used to
+     quit Emacs.  */
+  private long lastVolumeButtonPress;
+
   public
   EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
               int width, int height, boolean overrideRedirect)
@@ -513,6 +517,7 @@ public class EmacsWindow extends EmacsHandleObject
   onKeyDown (int keyCode, KeyEvent event)
   {
     int state, state_1;
+    long time;
 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
       state = event.getModifiers ();
@@ -544,6 +549,20 @@ public class EmacsWindow extends EmacsHandleObject
                              state, keyCode,
                              event.getUnicodeChar (state_1));
     lastModifiers = state;
+
+    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
+      {
+       /* Check if this volume down press should quit Emacs.
+          Most Android devices have no physical keyboard, so it
+          is unreasonably hard to press C-g.  */
+
+       time = event.getEventTime ();
+
+       if (lastVolumeButtonPress - time < 350)
+         EmacsNative.quit ();
+
+       lastVolumeButtonPress = time;
+      }
   }
 
   public void
index bcfe0fed6fe685806022f5adca7ff189df4a4631..0ab6197d735df266e0cc1f38126fbbafe2bc919e 100644 (file)
@@ -166,7 +166,7 @@ that could not be found in the list of directories specified in \
 }
 
 # Look for a suitable ar in the same directory as the C compiler.
-ndk_where_cc=$(which $CC)
+ndk_where_cc=$(which $(echo "$CC" | awk -- "{ print \[$]1 }"))
 ndk_ar_search_path=$PATH
 
 # First, try to find $host_alias-ar in PATH.
index 1676cbf994282aed8005eb43100393e9235147ba..379b54a65be157a1bc986e8131095cae69ab0c83 100644 (file)
@@ -1228,7 +1228,7 @@ android_open (const char *filename, int oflag, int mode)
 {
   const char *name;
   AAsset *asset;
-  int fd, oldfd;
+  int fd;
   off_t out_start, out_length;
 
   if (asset_manager && (name = android_get_asset_name (filename)))
@@ -1889,6 +1889,12 @@ NATIVE_NAME (emacsAbort) (JNIEnv *env, jobject object)
   emacs_abort ();
 }
 
+extern JNIEXPORT void JNICALL
+NATIVE_NAME (quit) (JNIEnv *env, jobject object)
+{
+  Vquit_flag = Qt;
+}
+
 extern JNIEXPORT jlong JNICALL
 NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
                                   jshort window, jlong time,
index f65b5d3ffd12354d86da65c56817e5279c5b7204..7b27825ad60d42cff588e070e19c899826ad1656 100644 (file)
@@ -187,6 +187,12 @@ android_process_events_for_menu (int *id)
 
       /* Process pending signals.  */
       process_pending_signals ();
+
+      /* Maybe quit.  This is important because the framework (on
+        Android 4.0.3) can sometimes fail to deliver context menu
+        closed events if a submenu was opened, and the user still
+        needs to be able to quit.  */
+      maybe_quit ();
     }
 
   /* Restore the input block.  */
index 1325d923be9fb50bd1de0ce3217d43c26d0324a3..eeefed34d4bf35a0fb1e5a2bfe8b3de6649c6701 100644 (file)
@@ -20103,6 +20103,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
            }
 #endif
 
+         /* See if keysym should make Emacs quit.  */
+
+         if (keysym == dpyinfo->quit_keysym
+             && (xkey.time - dpyinfo->quit_keysym_time
+                 <= 350))
+           {
+             Vquit_flag = Qt;
+             goto done_keysym;
+           }
+
+         if (keysym == dpyinfo->quit_keysym)
+           {
+             /* Otherwise, set the last time that keysym was
+                pressed.  */
+             dpyinfo->quit_keysym_time = xkey.time;
+             goto done_keysym;
+           }
+
           /* If not using XIM/XIC, and a compose sequence is in progress,
              we break here.  Otherwise, chars_matched is always 0.  */
           if (compose_status.chars_matched > 0 && nbytes == 0)
@@ -23851,6 +23869,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                    }
 #endif
 
+                 /* See if keysym should make Emacs quit.  */
+
+                 if (keysym == dpyinfo->quit_keysym
+                     && (xev->time - dpyinfo->quit_keysym_time
+                         <= 350))
+                   {
+                     Vquit_flag = Qt;
+                     goto xi_done_keysym;
+                   }
+
+                 if (keysym == dpyinfo->quit_keysym)
+                   {
+                     /* Otherwise, set the last time that keysym was
+                        pressed.  */
+                     dpyinfo->quit_keysym_time = xev->time;
+                     goto xi_done_keysym;
+                   }
+
                  /* First deal with keysyms which have defined
                     translations to characters.  */
                  if (keysym >= 32 && keysym < 128)
@@ -29855,6 +29891,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
+  Lisp_Object tem, quit_keysym;
 #ifdef USE_XCB
   xcb_connection_t *xcb_conn;
 #endif
@@ -29865,7 +29902,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   GdkScreen *gscr;
 #endif
 #ifdef HAVE_XFIXES
-  Lisp_Object tem, lisp_name;
+  Lisp_Object lisp_name;
   int num_fast_selections;
   Atom selection_name;
 #ifdef USE_XCB
@@ -30142,6 +30179,28 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
     terminal->kboard->reference_count++;
   }
 
+  /* Now look through Vx_quit_keysym for the quit keysym associated
+     with this display.  */
+  tem = Vx_quit_keysym;
+  FOR_EACH_TAIL_SAFE (tem)
+    {
+      quit_keysym = XCAR (tem);
+
+      /* Check if its car is a string and its cdr a valid keysym.
+        Skip if it is not.  */
+
+      if (!CONSP (quit_keysym) || !FIXNUMP (XCDR (quit_keysym))
+         || !STRINGP (XCAR (quit_keysym)))
+       continue;
+
+      /* Check if this is the keysym to be used.  */
+
+      if (strcmp (SSDATA (XCAR (quit_keysym)), ServerVendor (dpy)))
+       continue;
+
+      dpyinfo->quit_keysym = XFIXNUM (XCDR (quit_keysym));
+    }
+
   /* Put this display on the chain.  */
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
@@ -32200,4 +32259,23 @@ frame placement via frame parameters, `set-frame-position', and
 `set-frame-size', along with the actual state of a frame after
 `x_make_frame_invisible'.  */);
   Vx_lax_frame_positioning = Qnil;
+
+  DEFVAR_LISP ("x-quit-keysym", Vx_quit_keysym,
+    doc: /* Keysyms which will cause Emacs to quit if rapidly pressed twice.
+
+This is used to support quitting on devices that do not have any kind
+of physical keyboard, or where the physical keyboard is incapable of
+entering `C-g'.  It defaults to `XF86XK_AudioLowerVolume' on XFree86
+and X.Org servers, and is unset.
+
+The value is an alist associating between strings, describing X server
+vendor names, and a single number describing the keysym to use.  The
+keysym to use for each display connection is determined upon
+connection setup, and does not reflect further changes to this
+variable.  */);
+  Vx_quit_keysym
+    = list2 (Fcons (build_string ("The X.Org Foundation"),
+                   make_int (269025041)),
+            Fcons (build_string ("The XFree86 Project, Inc."),
+                   make_int (269025041)));
 }
index 28ae00ca19011f7bf156b5c9f5e27d71954ad07a..406a7c5c06049eafadeeb99ece6eedcf1a3f6a77 100644 (file)
@@ -920,6 +920,13 @@ struct x_display_info
      server_time_monotonic_p will be true).  */
   int_fast64_t server_time_offset;
 #endif
+
+  /* Keysym that will cause Emacs to quit if pressed twice within 150
+     ms.  */
+  KeySym quit_keysym;
+
+  /* The last time that keysym was pressed.  */
+  Time quit_keysym_time;
 };
 
 #ifdef HAVE_X_I18N