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'.
This commit is contained in:
parent
22f7ad1057
commit
b0e7ae6d5b
11 changed files with 141 additions and 12 deletions
|
@ -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:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -74,6 +74,10 @@ public static native void initEmacs (String argv[], String dumpFile,
|
|||
/* 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,
|
||||
|
|
|
@ -124,6 +124,10 @@ private class Coordinate
|
|||
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 @@ private class Coordinate
|
|||
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 @@ private class Coordinate
|
|||
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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
80
src/xterm.c
80
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)));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue