summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-01-26 22:11:04 +0800
committerPo Lu <luangruo@yahoo.com>2023-01-26 22:11:04 +0800
commitb0e7ae6d5b68a56da40256c395141f071172a622 (patch)
treef754ea796e34235be911acb338cbd29db8f03fc6
parent22f7ad1057e1a1e20933e0a1ff2a858ecd9e3fec (diff)
downloademacs-b0e7ae6d5b68a56da40256c395141f071172a622.tar.gz
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'.
-rw-r--r--INSTALL.android4
-rw-r--r--configure.ac6
-rw-r--r--cross/Makefile.in5
-rw-r--r--doc/emacs/input.texi12
-rw-r--r--java/org/gnu/emacs/EmacsNative.java4
-rw-r--r--java/org/gnu/emacs/EmacsWindow.java19
-rw-r--r--m4/ndk-build.m42
-rw-r--r--src/android.c8
-rw-r--r--src/androidmenu.c6
-rw-r--r--src/xterm.c80
-rw-r--r--src/xterm.h7
11 files changed, 141 insertions, 12 deletions
diff --git a/INSTALL.android b/INSTALL.android
index 06211e5ec93..e5d7162140d 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 879e4ab74aa..aaee65016b2 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 92f8d068975..a44550c6563 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 1a58d1ca0ac..3894d4872e0 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 7bf8b5f6081..4e91a7be322 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 8511af9193e..39eaf2fff80 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 bcfe0fed6fe..0ab6197d735 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 1676cbf9942..379b54a65be 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 f65b5d3ffd1..7b27825ad60 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 1325d923be9..eeefed34d4b 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 28ae00ca190..406a7c5c060 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