emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android b0e7ae6d5b 2/4: Update Android port


From: Po Lu
Subject: feature/android b0e7ae6d5b 2/4: Update Android port
Date: Thu, 26 Jan 2023 09:19:49 -0500 (EST)

branch: feature/android
commit b0e7ae6d5b68a56da40256c395141f071172a622
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Update Android port
    
    * 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                     |  4 +-
 configure.ac                        |  6 +--
 cross/Makefile.in                   |  5 ++-
 doc/emacs/input.texi                | 12 ++++++
 java/org/gnu/emacs/EmacsNative.java |  4 ++
 java/org/gnu/emacs/EmacsWindow.java | 19 +++++++++
 m4/ndk-build.m4                     |  2 +-
 src/android.c                       |  8 +++-
 src/androidmenu.c                   |  6 +++
 src/xterm.c                         | 80 ++++++++++++++++++++++++++++++++++++-
 src/xterm.h                         |  7 ++++
 11 files changed, 141 insertions(+), 12 deletions(-)

diff --git a/INSTALL.android b/INSTALL.android
index 06211e5ec9..e5d7162140 100644
--- a/INSTALL.android
+++ b/INSTALL.android
@@ -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:
 
diff --git a/configure.ac b/configure.ac
index 879e4ab74a..aaee65016b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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.
diff --git a/cross/Makefile.in b/cross/Makefile.in
index 92f8d06897..a44550c656 100644
--- a/cross/Makefile.in
+++ b/cross/Makefile.in
@@ -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
diff --git a/doc/emacs/input.texi b/doc/emacs/input.texi
index 1a58d1ca0a..3894d4872e 100644
--- a/doc/emacs/input.texi
+++ b/doc/emacs/input.texi
@@ -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.
diff --git a/java/org/gnu/emacs/EmacsNative.java 
b/java/org/gnu/emacs/EmacsNative.java
index 7bf8b5f608..4e91a7be32 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -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,
diff --git a/java/org/gnu/emacs/EmacsWindow.java 
b/java/org/gnu/emacs/EmacsWindow.java
index 8511af9193..39eaf2fff8 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -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
diff --git a/m4/ndk-build.m4 b/m4/ndk-build.m4
index bcfe0fed6f..0ab6197d73 100644
--- a/m4/ndk-build.m4
+++ b/m4/ndk-build.m4
@@ -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.
diff --git a/src/android.c b/src/android.c
index 1676cbf994..379b54a65b 100644
--- a/src/android.c
+++ b/src/android.c
@@ -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,
diff --git a/src/androidmenu.c b/src/androidmenu.c
index f65b5d3ffd..7b27825ad6 100644
--- a/src/androidmenu.c
+++ b/src/androidmenu.c
@@ -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.  */
diff --git a/src/xterm.c b/src/xterm.c
index 1325d923be..eeefed34d4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -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)));
 }
diff --git a/src/xterm.h b/src/xterm.h
index 28ae00ca19..406a7c5c06 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]