Update Android port

* INSTALL.android: Document support for gnutls and libgmp.
* build-aux/ndk-build-helper-1.mk (NDK_SO_NAMES, NDK_INCLUDES)
(SYSTEM_LIBRARIES):
* build-aux/ndk-build-helper-2.mk: Recursively resolve and add
shared library dependencies; even those of static libraries.
* build-aux/ndk-module-extract.awk: Fix makefile_imports code.
* configure.ac (ANDROID_SDK_18_OR_EARLIER, XCONFIGURE)
(LIBGMP_CFLAGS): Enable GMP and gnutls on Android.

* cross/ndk-build/Makefile.in (LOCAL_EXPORT_C_INCLUDES):
* cross/ndk-build/ndk-build-shared-library.mk: ($(call
objname,$(LOCAL_MODULE),$(basename $(1))))::($$(error
Unsupported suffix)::($(LOCAL_MODULE_FILENAME)):
* cross/ndk-build/ndk-build-static-library.mk: ($(call
objname,$(LOCAL_MODULE),$(basename $(1))))::($$(error
Unsupported suffix):
* cross/ndk-build/ndk-clear-vars.mk:
* cross/ndk-build/ndk-resolve.mk (NDK_SYSTEM_LIBRARIES):
(NDK_LOCAL_EXPORT_C_INCLUDES_$(LOCAL_MODULE)):
(NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)):
Implement ``LOCAL_ASM_RULE'' and ``LOCAL_C_ADDITIONAL_FLAGS''
extensions for libgmp.

* doc/emacs/input.texi (Touchscreens): Document how to
horizontally scroll.
* java/org/gnu/emacs/EmacsActivity.java (attachWindow): Give the
view focus again if necessary.
(onPause): Call right super function.
* java/org/gnu/emacs/EmacsPreferencesActivity.java (onClick):
Clear dumpFileName lest Emacs try to load a nonexistent dump
file.
* java/org/gnu/emacs/EmacsView.java (onDetachedFromWindow)
(onAttachedToWindow): Call super functions.
(onCreateInputConnection): Make sure the IME never obscures
Emacs.
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, onKeyDown)
(onKeyUp): Improve tracking of quit keys.

* lisp/isearch.el (isearch-mode): Bring up the onscreen
keyboard.
* lisp/touch-screen.el (touch-screen-current-tool): Add three
fields.
(touch-screen-handle-scroll): Allow hscrolling as well.
(touch-screen-handle-touch): Add additional fields to
`touch-screen-current-tool'.
* src/Makefile.in (LIBGMP_CFLAGS, EMACS_CFLAGS): Add new
variable.
* src/android.c (android_run_select_thread):
(android_write_event): Use pthread_cond_broadcast because
pthread_cond_signal does nothing on some Android
versions/devices?
feature/android
Po Lu 2023-01-28 14:29:51 +08:00
parent 65dddd7c99
commit e3b50ec8ec
19 changed files with 243 additions and 46 deletions

View File

@ -182,6 +182,12 @@ themselves:
its Android.mk includes $(BUILD_SHARED_LIBRARY), then copy
android/jansson_config.h to android/jansson_private_config.h.)
And Emacs developers have ported the following dependencies to arm64
Android systems:
gnutls, gmp - https://sourceforge.net/projects/android-ports-for-gnu-emacs
(Please see the section GNUTLS near the end of this file.)
We anticipate that most untested non-trivial ndk-build dependencies
will need adjustments in Emacs to work, as the Emacs build system
which emulates ndk-build is in an extremely early state.
@ -519,6 +525,19 @@ As a result, all three dependencies will be built and linked to Emacs,
instead of just the single ``webpdemux'' dependency that was
specified.
GNUTLS
Modified copies of GnuTLS and its dependencies (such as libgmp,
libtasn1, p11-kit) which can be built with the ndk-build system can be
found at https://sourceforge.net/projects/android-ports-for-gnu-emacs.
They have only been tested on arm64 Android systems running Android
5.0 or later, so your mileage may vary, especially if you are trying
to build Emacs for another kind of machine.
To build Emacs with GnuTLS, you must unpack each tar archive in that
site, and add the resulting folder to ``--with-ndk-path''.
This file is part of GNU Emacs.

View File

@ -46,6 +46,12 @@ else
NDK_SO_NAMES = $(LOCAL_MODULE_FILENAME).so
endif
define add-so-name-1
# Now recurse over this module's dependencies.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)),$$(eval $$(call add-so-name,$$(module))))
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_STATIC_LIBRARIES)),$$(eval $$(call add-so-name-1,$$(module))))
endef
define add-so-name
ifeq ($(findstring lib,$(1)),lib)
NDK_SO_NAME = $(1)_emacs.so
@ -58,6 +64,9 @@ NDK_SO_NAMES := $$(NDK_SO_NAMES) $$(NDK_SO_NAME)
# Now recurse over this module's dependencies.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)),$$(eval $$(call add-so-name,$$(module))))
# Recurse over static library dependencies of this shared library.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_STATIC_LIBRARIES) $$(NDK_$(1)_WHOLE_LIBRARIES)),$$(eval $$(call add-so-name-1,$$(module))))
endif
endef
@ -69,6 +78,13 @@ ifeq ($$(findstring $$(NDK_$(1)_EXPORT_INCLUDES),$$(NDK_INCLUDES)),)
NDK_INCLUDES += $$(NDK_$(1)_EXPORT_INCLUDES)
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)) $$(NDK_$(1)_STATIC_LIBRARIES),$$(eval $$(call add-includes,$$(module))))
# Recurse over shared library dependencies of this static library.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_SHARED_LIBRARIES)),$$(eval $$(call add-so-name,$$(module))))
# Recurse over static or shared library dependencies of this static
# library.
$$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_STATIC_LIBRARIES)),$$(eval $$(call add-so-name-1,$$(module))))
endif
endef
@ -80,7 +96,7 @@ endef
SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ log liblog android libandroid
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES)),$(eval $(call add-so-name,$(module))))
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES) $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_LIBRARIES)),$(eval $(call add-includes,$(module))))
$(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES) $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES)),$(eval $(call add-includes,$(module))))
$(info $(foreach dir,$(NDK_INCLUDES),-I$(dir)))
$(info $(LOCAL_EXPORT_CFLAGS))

View File

@ -96,6 +96,6 @@ $(foreach module,$(filter-out $(SYSTEM_LIBRARIES), $(LOCAL_SHARED_LIBRARIES) $(L
$(info $(foreach dir,$(NDK_INCLUDES),-I$(dir)))
$(info $(LOCAL_EXPORT_CFLAGS))
$(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR)/,$(NDK_A_NAMES))) $(and $(NDK_SO_NAMES), -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname))))
$(info $(NDK_A_NAMES))
$(info $(NDK_A_NAMES) $(NDK_SO_NAMES))
$(info $(filter %stdc++,$(LOCAL_SHARED_LIBRARIES)))
$(info End)

View File

@ -10,7 +10,7 @@
if (imports && ++imports > 2)
{
if (!match ($0, /^End Imports$/))
makefile_imports = makefile_imports " " $1
makefile_imports = makefile_imports " " $0
}
else if (!match ($0, /^End$/) && !match ($0, /^Building.+$/))
{

View File

@ -1061,6 +1061,7 @@ package will likely install on older systems but crash on startup.])
passthrough="$passthrough --with-jpeg=$with_jpeg"
passthrough="$passthrough --with-xml2=$with_xml2"
passthrough="$passthrough --with-sqlite3=$with_sqlite3"
passthrough="$passthrough --with-gnutls=$with_gnutls"
AS_IF([XCONFIGURE=android ANDROID_CC="$ANDROID_CC" \
ANDROID_SDK="$android_sdk" android_abi=$android_abi \
@ -1131,6 +1132,7 @@ if test "$ANDROID" = "yes"; then
with_jpeg=no
with_xml2=no
with_sqlite3=no
with_gnutls=no
fi
with_rsvg=no
@ -1146,7 +1148,6 @@ if test "$ANDROID" = "yes"; then
with_dbus=no
with_gsettings=no
with_selinux=no
with_gnutls=no
with_modules=no
with_threads=no
@ -7029,6 +7030,38 @@ gl_INIT
CFLAGS=$SAVE_CFLAGS
LIBS=$SAVE_LIBS
# Set up libgmp on Android. Make sure to override what gnulib has
# found.
LIBGMP_CFLAGS=
if test "$REALLY_ANDROID" == "yes" && test "$with_libgmp" != "no"; then
HAVE_LIBGMP=no
ndk_SEARCH_MODULE([libgmp], [LIBGMP], [HAVE_LIBGMP=yes])
if test "$HAVE_LIBGMP" = "yes"; then
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $LIBGMP_CFLAGS"
unset ac_cv_header_gmp_h
unset ac_cv_header_gmp_gmp_h
AC_CHECK_HEADERS([gmp.h gmp/gmp.h], [break])
CFLAGS="$SAVE_CFLAGS"
GL_GENERATE_GMP_H=
GL_GENERATE_GMP_H_CONDITION=
GL_GENERATE_GMP_GMP_H=
GL_GENERATE_GMP_GMP_H_CONDITION=
GL_GENERATE_MINI_GMP_H=
GL_GENERATE_MINI_GMP_H_CONDITION=
if test "$ac_cv_header_gmp_h" != "no" \
|| test "$ac_cv_header_gmp_gmp_h" != "no"; then
HAVE_LIBGMP=yes
GL_GENERATE_GMP_H=false
LIBGMP="$LIBGMP_LIBS"
GMP_H=
fi
fi
fi
AC_SUBST([LIBGMP_CFLAGS])
# timer_getoverrun needs the same library as timer_settime
OLD_LIBS=$LIBS
LIBS="$LIB_TIMER_TIME $LIBS"

View File

@ -118,6 +118,8 @@ LOCAL_EXPORT_CPPFLAGS :=
LOCAL_EXPORT_C_INCLUDES :=
LOCAL_EXPORT_LDFLAGS :=
LOCAL_EXPORT_LDLIBS :=
LOCAL_ASM_RULE_DEFINED :=
LOCAL_ASM_RULE :=
# Now load Android.mk.
include $(1)

View File

@ -35,7 +35,7 @@ define single-object-target
ifeq (x$(suffix $(1)),x.c)
$(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1)
$(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE))
$(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(call LOCAL_C_ADDITIONAL_FLAGS,$(1))
else
ifeq (x$(suffix $(1)),x.$(or $(LOCAL_CPP_EXTENSION),cpp))
@ -52,6 +52,13 @@ $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1)
else
ifneq (x$(suffix $(1)),x.asm)
$$(error Unsupported suffix: $(suffix $(1)))
else
ifneq (x$(LOCAL_ASM_RULE_DEFINED),x)
# Call this function to define a rule that will generate $(1) from
# $(2), a ``.asm'' file. This is an Emacs extension.
$(call LOCAL_ASM_RULE,$(call objname,$(LOCAL_MODULE),$(basename $(1))),$(LOCAL_PATH)/$(strip $(1)))
else
ifeq ($(findstring x86,$(NDK_BUILD_ARCH)),)
$$(error Trying to build nasm file on non-Intel platform!)
@ -65,6 +72,7 @@ endif
endif
endif
endif
endif
ALL_OBJECT_FILES$(LOCAL_MODULE) += $(call objname,$(LOCAL_MODULE),$(basename $(1)))
@ -125,11 +133,11 @@ $(foreach source,$(ALL_SOURCE_FILES),$(eval $(call single-object-target,$(source
# Now define the rule to build the shared library. Shared libraries
# link with all of the archive files from the static libraries on
# which they depend.
# which they depend, and also any shared libraries they depend on.
define define-module-rule
$(LOCAL_MODULE_FILENAME): $(ALL_OBJECT_FILES$(LOCAL_MODULE)) $(NDK_LOCAL_A_NAMES_$(LOCAL_MODULE)) $(NDK_WHOLE_A_NAMES_$(LOCAL_MODULE))
$(NDK_BUILD_CC) $(1) $(2) -o $$@ -shared $(NDK_LDFLAGS$(LOCAL_MODULE)) $(NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)) $(NDK_SO_DEFAULT_LDFLAGS)
$(LOCAL_MODULE_FILENAME): $(ALL_OBJECT_FILES$(LOCAL_MODULE)) $(NDK_LOCAL_A_NAMES_$(LOCAL_MODULE)) $(NDK_WHOLE_A_NAMES_$(LOCAL_MODULE)) $(NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE))
$(NDK_BUILD_CC) $(1) $(2) -o $$@ -shared $(NDK_LDFLAGS_$(LOCAL_MODULE)) $(NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)) $(NDK_SO_DEFAULT_LDFLAGS) $(foreach so,$(NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE)),-L $(abspath $(CURDIR)) -l:$(so))
endef
NDK_WHOLE_ARCHIVE_PREFIX = -Wl,--whole-archive

View File

@ -27,7 +27,7 @@ define single-object-target
ifeq (x$(suffix $(1)),x.c)
$(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1)
$(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE))
$(NDK_BUILD_CC) -c $$< -o $$@ $(NDK_CFLAGS_$(LOCAL_MODULE)) $(call LOCAL_C_ADDITIONAL_FLAGS,$(1))
else
ifeq (x$(suffix $(1)),x.$(or $(LOCAL_CPP_EXTENSION),cpp))
@ -44,6 +44,13 @@ $(call objname,$(LOCAL_MODULE),$(basename $(1))): $(LOCAL_PATH)/$(1)
else
ifneq (x$(suffix $(1)),x.asm)
$$(error Unsupported suffix: $(suffix $(1)))
else
ifneq (x$(LOCAL_ASM_RULE_DEFINED),x)
# Call this function to define a rule that will generate $(1) from
# $(2), a ``.asm'' file. This is an Emacs extension.
$(call LOCAL_ASM_RULE,$(call objname,$(LOCAL_MODULE),$(basename $(1))),$(LOCAL_PATH)/$(strip $(1)))
else
ifeq ($(findstring x86,$(NDK_BUILD_ARCH)),)
$$(error Trying to build nasm file on non-Intel platform!)
@ -57,6 +64,7 @@ endif
endif
endif
endif
endif
ALL_OBJECT_FILES$(LOCAL_MODULE) += $(call objname,$(LOCAL_MODULE),$(basename $(1)))
endef

View File

@ -45,3 +45,8 @@ undefine LOCAL_EXPORT_LDLIBS
undefine LOCAL_SRC_FILES_$(NDK_BUILD_ARCH)
undefine LOCAL_ASFLAGS_$(NDK_BUILD_ARCH)
undefine LOCAL_CFLAGS_$(NDK_BUILD_ARCH)
# Emacs extensions!
undefine LOCAL_ASM_RULE_DEFINED
undefine LOCAL_ASM_RULE
undefine LOCAL_C_ADDITIONAL_FLAGS

View File

@ -19,6 +19,9 @@
# variables, and then having those Makefiles include another makefile
# which actually builds targets.
# List of system libraries to ignore.
NDK_SYSTEM_LIBRARIES = z libz libc c libdl dl stdc++ libstdc++ log liblog android libandroid
# Save information.
NDK_LOCAL_PATH_$(LOCAL_MODULE) := $(LOCAL_PATH)
NDK_LOCAL_STATIC_LIBRARIES_$(LOCAL_MODULE) := $(LOCAL_STATIC_LIBRARIES) $(LOCAL_WHOLE_STATIC_LIBRARIES)
@ -28,6 +31,7 @@ NDK_LOCAL_EXPORT_CFLAGS_$(LOCAL_MODULE) := $(LOCAL_EXPORT_CFLAGS)
NDK_LOCAL_EXPORT_C_INCLUDES_$(LOCAL_MODULE) := $(LOCAL_EXPORT_C_INCLUDES) $(LOCAL_EXPORT_C_INCLUDE_DIRS)
NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) :=
NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) :=
NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE) :=
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) :=
# List of all dependencies resolved for this module thus far.
@ -87,6 +91,14 @@ ifeq ($(strip $(1)),android)
NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -landroid
endif
ifeq ($(findstring $(1),$(NDK_SYSTEM_LIBRARIES))$(2)$(3),)
ifneq ($(findstring lib,$(1)),)
NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE) += $(1)_emacs.so
else
NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE) += lib$(1)_emacs.so
endif
endif
ifneq ($(2),)
ifneq ($(findstring lib,$(1)),)
NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) += $(1).a

View File

@ -46,6 +46,9 @@ References}), then Emacs will follow the link instead.
or down, will result in Emacs scrolling the window contents in the
direction where the tool moves.
If the tool is moved left or right, Emacs additionally scrolls the
window horizontally to follow (@pxref{Horizontal Scrolling}.)
@item
@cindex dragging, touchscreens
``Dragging'', meaning to place a tool on the display and leave it

View File

@ -134,6 +134,10 @@ public class EmacsActivity extends Activity
layout.addView (window.view);
child.setConsumer (this);
/* If the window isn't no-focus-on-map, focus its view. */
if (!child.getDontFocusOnMap ())
window.view.requestFocus ();
/* If the activity is iconified, send that to the window. */
if (isPaused)
window.noticeIconified ();
@ -233,7 +237,7 @@ public class EmacsActivity extends Activity
isPaused = true;
EmacsWindowAttachmentManager.MANAGER.noticeIconified (this);
super.onResume ();
super.onPause ();
}
@Override

View File

@ -116,6 +116,11 @@ public class EmacsPreferencesActivity extends Activity
if (file.exists ())
file.delete ();
/* Make sure to clear EmacsApplication.dumpFileName, or
starting Emacs without restarting this program will
make Emacs try to load a nonexistent dump file. */
EmacsApplication.dumpFileName = null;
}
});
layout.addView (textView);

View File

@ -22,12 +22,16 @@ package org.gnu.emacs;
import android.content.Context;
import android.content.res.ColorStateList;
import android.text.InputType;
import android.view.ContextMenu;
import android.view.View;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.graphics.Bitmap;
@ -566,6 +570,8 @@ public class EmacsView extends ViewGroup
/* Collect the bitmap storage; it could be large. */
Runtime.getRuntime ().gc ();
}
super.onDetachedFromWindow ();
}
@Override
@ -581,6 +587,8 @@ public class EmacsView extends ViewGroup
/* Now expose the view contents again. */
EmacsNative.sendExpose (this.window.handle, 0, 0,
measuredWidth, measuredHeight);
super.onAttachedToWindow ();
}
public void
@ -615,4 +623,17 @@ public class EmacsView extends ViewGroup
drawingFinished = null;
}
}
@Override
public InputConnection
onCreateInputConnection (EditorInfo info)
{
/* Make sure the input method never displays a full screen input
box that obscures Emacs. */
info.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
/* But don't return an InputConnection, in order to force the on
screen keyboard to work correctly. */
return null;
}
};

View File

@ -124,9 +124,9 @@ 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;
/* The time of the last KEYCODE_VOLUME_DOWN release. This is used
to quit Emacs. */
private long lastVolumeButtonRelease;
public
EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
@ -517,7 +517,6 @@ 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 ();
@ -549,26 +548,13 @@ 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
onKeyUp (int keyCode, KeyEvent event)
{
int state, state_1;
long time;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
state = event.getModifiers ();
@ -600,6 +586,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 (time - lastVolumeButtonRelease < 350)
EmacsNative.quit ();
lastVolumeButtonRelease = time;
}
}
public void

View File

@ -1237,6 +1237,8 @@ does not return to the calling function until the search is completed.
To behave this way it enters a recursive edit and exits it when done
isearching.
Also display the on-screen keyboard if necessary.
The arg REGEXP-FUNCTION, if non-nil, should be a function. It is
used to set the value of `isearch-regexp-function'."
@ -1332,6 +1334,14 @@ used to set the value of `isearch-regexp-function'."
(add-hook 'mouse-leave-buffer-hook 'isearch-mouse-leave-buffer)
(add-hook 'kbd-macro-termination-hook 'isearch-done)
;; If the keyboard is not up and the last event did not come from
;; a keyboard, bring it up so that the user can type.
(when (or (not last-event-frame)
(not (eq (device-class last-event-frame
last-event-device)
'keyboard)))
(frame-toggle-on-screen-keyboard (selected-frame) nil))
;; isearch-mode can be made modal (in the sense of not returning to
;; the calling function until searching is completed) by entering
;; a recursive-edit and exiting it when done isearching.

View File

@ -30,14 +30,14 @@
(defvar touch-screen-current-tool nil
"The touch point currently being tracked, or nil.
If non-nil, this is a list of six elements: the ID of the touch
If non-nil, this is a list of nine elements: the ID of the touch
point being tracked, the window where the touch began, a cons
containing the last known position of the touch point, relative
to that window, a field used to store data while tracking the
touch point, the initial position of the touchpoint, and another
field to used store data while tracking the touch point. See
`touch-screen-handle-point-update' for the meanings of the fourth
element.")
four fields to used store data while tracking the touch point.
See `touch-screen-handle-point-update' for the meanings of the
fourth element.")
(defvar touch-screen-set-point-commands '(mouse-set-point)
"List of commands known to set the point.
@ -92,8 +92,11 @@ to the frame that they belong in."
(- (cdr xy) (cadr edges)))))))
(defun touch-screen-handle-scroll (dx dy)
"Scroll the display assuming that a touch point has moved by DX and DY."
(ignore dx)
"Scroll the display assuming that a touch point has moved by DX and DY.
Perform vertical scrolling by DY, using `pixel-scroll-precision'
if `touch-screen-precision-scroll' is enabled. Next, perform
horizontal scrolling according to the movement in DX."
;; Perform vertical scrolling first.
(if touch-screen-precision-scroll
(if (> dy 0)
(pixel-scroll-precision-scroll-down-page dy)
@ -102,7 +105,8 @@ to the frame that they belong in."
;; in which the scrolling is taking place. Load the accumulator
;; value.
(let ((accumulator (or (nth 5 touch-screen-current-tool) 0))
(window (cadr touch-screen-current-tool)))
(window (cadr touch-screen-current-tool))
(lines-vscrolled (or (nth 7 touch-screen-current-tool) 0)))
(setq accumulator (+ accumulator dy)) ; Add dy.
;; Figure out how much it has scrolled and how much remains on
;; the top or bottom of the window.
@ -113,6 +117,7 @@ to the frame that they belong in."
(progn
(setq accumulator (+ accumulator line-height))
(scroll-down 1)
(setq lines-vscrolled (1+ lines-vscrolled))
(when (not (zerop accumulator))
;; If there is still an outstanding amount to
;; scroll, do this again.
@ -120,15 +125,58 @@ to the frame that they belong in."
(when (and (> accumulator 0)
(>= accumulator line-height))
(setq accumulator (- accumulator line-height))
(scroll-up 1)
(scroll-up 1)
(setq lines-vscrolled (1+ lines-vscrolled))
(when (not (zerop accumulator))
;; If there is still an outstanding amount to
;; scroll, do this again.
(throw 'again t)))))
;; Scrolling is done. Move the accumulator back to
;; touch-screen-current-tool and break out of the loop.
(setcar (nthcdr 5 touch-screen-current-tool) accumulator)
(setcar (nthcdr 7 touch-screen-current-tool)
lines-vscrolled)
nil))))
;; Perform horizontal scrolling by DX, as this does not signal at
;; the beginning of the buffer.
(let ((accumulator (or (nth 6 touch-screen-current-tool) 0))
(window (cadr touch-screen-current-tool))
(lines-vscrolled (or (nth 7 touch-screen-current-tool) 0))
(lines-hscrolled (or (nth 8 touch-screen-current-tool) 0)))
(setq accumulator (+ accumulator dx)) ; Add dx;
;; Figure out how much it has scrolled and how much remains on the
;; left or right of the window. If a line has already been
;; vscrolled but no hscrolling has happened, don't hscroll, as
;; otherwise it is too easy to hscroll by accident.
(if (or (> lines-hscrolled 0)
(< lines-vscrolled 1))
(while (catch 'again
(let* ((column-width (frame-char-width (window-frame window))))
(if (and (< accumulator 0)
(>= (- accumulator) column-width))
(progn
(setq accumulator (+ accumulator column-width))
(scroll-right 1)
(setq lines-hscrolled (1+ lines-hscrolled))
(when (not (zerop accumulator))
;; If there is still an outstanding amount to
;; scroll, do this again.
(throw 'again t)))
(when (and (> accumulator 0)
(>= accumulator column-width))
(setq accumulator (- accumulator column-width))
(scroll-left 1)
(setq lines-hscrolled (1+ lines-hscrolled))
(when (not (zerop accumulator))
;; If there is still an outstanding amount to
;; scroll, do this again.
(throw 'again t)))))
;; Scrolling is done. Move the accumulator back to
;; touch-screen-current-tool and break out of the loop.
(setcar (nthcdr 5 touch-screen-current-tool) accumulator)
nil)))))
;; Scrolling is done. Move the accumulator back to
;; touch-screen-current-tool and break out of the loop.
(setcar (nthcdr 6 touch-screen-current-tool) accumulator)
(setcar (nthcdr 8 touch-screen-current-tool) lines-hscrolled)
nil)))))
(defun touch-screen-handle-timeout (arg)
"Start the touch screen timeout or handle it depending on ARG.
@ -377,7 +425,8 @@ touchscreen-end event."
(list touchpoint
(posn-window position)
(posn-x-y position)
nil position nil)))
nil position nil nil
nil nil)))
;; Start the long-press timer.
(touch-screen-handle-timeout nil)))
((eq (car event) 'touchscreen-update)

View File

@ -391,6 +391,8 @@ ANDROID_LIBS = @ANDROID_LIBS@
ANDROID_LDFLAGS = @ANDROID_LDFLAGS@
ANDROID_CFLAGS = @ANDROID_CFLAGS@
LIBGMP_CFLAGS = @LIBGMP_CFLAGS@
DUMPING=@DUMPING@
CHECK_STRUCTS = @CHECK_STRUCTS@
HAVE_PDUMPER = @HAVE_PDUMPER@
@ -433,7 +435,8 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) $(TREE_SITTER_CFLAGS) \
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
$(WERROR_CFLAGS) $(HAIKU_CFLAGS) $(XCOMPOSITE_CFLAGS) $(XSHAPE_CFLAGS) \
$(ANDROID_CFLAGS) $(GIF_CFLAGS) $(JPEG_CFLAGS) $(SQLITE3_CFLAGS)
$(ANDROID_CFLAGS) $(GIF_CFLAGS) $(JPEG_CFLAGS) $(SQLITE3_CFLAGS) \
$(LIBGMP_CFLAGS)
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \
$(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \

View File

@ -334,12 +334,11 @@ android_run_select_thread (void *data)
the event queue lock, because android_select will always
wait for this to complete before returning. */
android_pselect_completed = true;
pthread_cond_signal (&event_queue.read_var);
pthread_cond_broadcast (&event_queue.read_var);
/* Read a single byte from the select pipe. */
read (select_pipe[0], &byte, 1);
/* Signal the Emacs thread that pselect is done. If read_var
was signaled by android_write_event, event_queue.mutex could
still be locked, so this must come before. */
@ -378,7 +377,7 @@ android_run_select_thread (void *data)
the event queue lock, because android_select will always
wait for this to complete before returning. */
android_pselect_completed = true;
pthread_cond_signal (&event_queue.read_var);
pthread_cond_broadcast (&event_queue.read_var);
if (rc != -1 || errno != EINTR)
/* Now, wait for SIGUSR1, unless pselect was interrupted and
@ -559,7 +558,7 @@ android_write_event (union android_event *event)
container->last->next = container;
container->event = *event;
event_queue.num_events++;
pthread_cond_signal (&event_queue.read_var);
pthread_cond_broadcast (&event_queue.read_var);
pthread_mutex_unlock (&event_queue.mutex);
/* Now set pending_signals to true. This allows C-g to be handled