From: Po Lu Date: Sat, 28 Jan 2023 06:29:51 +0000 (+0800) Subject: Update Android port X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e3b50ec8ec1b8d1246aa2496f3fe8bf98d354545;p=emacs.git 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? --- diff --git a/INSTALL.android b/INSTALL.android index e5d7162140d..267a3910e30 100644 --- a/INSTALL.android +++ b/INSTALL.android @@ -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. diff --git a/build-aux/ndk-build-helper-1.mk b/build-aux/ndk-build-helper-1.mk index 9035b5ca59a..50def5f1c2d 100644 --- a/build-aux/ndk-build-helper-1.mk +++ b/build-aux/ndk-build-helper-1.mk @@ -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)) diff --git a/build-aux/ndk-build-helper-2.mk b/build-aux/ndk-build-helper-2.mk index 8f2f397e534..3722437c53e 100644 --- a/build-aux/ndk-build-helper-2.mk +++ b/build-aux/ndk-build-helper-2.mk @@ -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) diff --git a/build-aux/ndk-module-extract.awk b/build-aux/ndk-module-extract.awk index 681f20237fa..6ff30973d67 100644 --- a/build-aux/ndk-module-extract.awk +++ b/build-aux/ndk-module-extract.awk @@ -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.+$/)) { diff --git a/configure.ac b/configure.ac index aaee65016b2..35e71ecb93c 100644 --- a/configure.ac +++ b/configure.ac @@ -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" diff --git a/cross/ndk-build/Makefile.in b/cross/ndk-build/Makefile.in index 125c825e506..774858697b4 100644 --- a/cross/ndk-build/Makefile.in +++ b/cross/ndk-build/Makefile.in @@ -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) diff --git a/cross/ndk-build/ndk-build-shared-library.mk b/cross/ndk-build/ndk-build-shared-library.mk index b69641ba9b0..f169e89d058 100644 --- a/cross/ndk-build/ndk-build-shared-library.mk +++ b/cross/ndk-build/ndk-build-shared-library.mk @@ -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 diff --git a/cross/ndk-build/ndk-build-static-library.mk b/cross/ndk-build/ndk-build-static-library.mk index 349b9242b1f..d5a8e93800d 100644 --- a/cross/ndk-build/ndk-build-static-library.mk +++ b/cross/ndk-build/ndk-build-static-library.mk @@ -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 diff --git a/cross/ndk-build/ndk-clear-vars.mk b/cross/ndk-build/ndk-clear-vars.mk index df2bf95fd5e..6377f373512 100644 --- a/cross/ndk-build/ndk-clear-vars.mk +++ b/cross/ndk-build/ndk-clear-vars.mk @@ -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 diff --git a/cross/ndk-build/ndk-resolve.mk b/cross/ndk-build/ndk-resolve.mk index c2e281c53ba..e2252ebdf8c 100644 --- a/cross/ndk-build/ndk-resolve.mk +++ b/cross/ndk-build/ndk-resolve.mk @@ -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 diff --git a/doc/emacs/input.texi b/doc/emacs/input.texi index d7a72e6203e..b306a63b6cb 100644 --- a/doc/emacs/input.texi +++ b/doc/emacs/input.texi @@ -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 diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index d377cf982ef..30eaf85805a 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java @@ -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 diff --git a/java/org/gnu/emacs/EmacsPreferencesActivity.java b/java/org/gnu/emacs/EmacsPreferencesActivity.java index ed1db68f732..6cef7c37516 100644 --- a/java/org/gnu/emacs/EmacsPreferencesActivity.java +++ b/java/org/gnu/emacs/EmacsPreferencesActivity.java @@ -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); diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index a1953f683bd..730ed02d4f1 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -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; + } }; diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 39eaf2fff80..5c2b77b0125 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -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 diff --git a/lisp/isearch.el b/lisp/isearch.el index bb46c89ae20..4d2cb5edb47 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -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. diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el index 855eebcc43f..fa98cbe5db9 100644 --- a/lisp/touch-screen.el +++ b/lisp/touch-screen.el @@ -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) diff --git a/src/Makefile.in b/src/Makefile.in index 60bb9c8f3a3..0921f6f1f96 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -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) \ diff --git a/src/android.c b/src/android.c index 379b54a65be..021bea1fc2f 100644 --- a/src/android.c +++ b/src/android.c @@ -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