From a496509cedb17109d0e6297a74e2ff8ed526333c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 19 Jan 2023 22:19:06 +0800 Subject: Update Android port * .gitignore: Add new files. * INSTALL.android: Explain how to build Emacs for ancient versions of Android. * admin/merge-gnulib (GNULIB_MODULES): Add getdelim. * build-aux/config.guess (timestamp, version): * build-aux/config.sub (timestamp, version): Autoupdate. * configure.ac (BUILD_DETAILS, ANDROID_MIN_SDK): (ANDROID_STUBIFY): Allow specifying CFLAGS via ANDROID_CFLAGS. Add new configure tests for Android API version when not explicitly specified. * doc/emacs/android.texi (Android): Add reference to ``Other Input Devices''. (Android File System): Remove restrictions on directory-files on the assets directory. * doc/emacs/emacs.texi (Top): Add Other Input Devices to menu. * doc/emacs/input.texi (Other Input Devices): New node. * doc/lispref/commands.texi (Touchscreen Events): Document changes to touchscreen input events. * doc/lispref/frames.texi (Pop-Up Menus): Likewise. * etc/NEWS: Announce changes. * java/Makefile.in: Use lib-src/asset-directory-tool to generate an `directory-tree' file placed in /assets. * java/debug.sh: Large adjustments to support Android 2.2 and later. * java/org/gnu/emacs/EmacsContextMenu.java (inflateMenuItems): * java/org/gnu/emacs/EmacsCopyArea.java (perform): * java/org/gnu/emacs/EmacsDialog.java (toAlertDialog): * java/org/gnu/emacs/EmacsDrawLine.java (perform): * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): * java/org/gnu/emacs/EmacsDrawable.java (EmacsDrawable): * java/org/gnu/emacs/EmacsFillPolygon.java (perform): * java/org/gnu/emacs/EmacsFillRectangle.java (perform): * java/org/gnu/emacs/EmacsGC.java (EmacsGC): * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): (destroyHandle): * java/org/gnu/emacs/EmacsSdk7FontDriver.java (draw): Avoid redundant canvas saves and restores. * java/org/gnu/emacs/EmacsService.java (run): * java/org/gnu/emacs/EmacsView.java (EmacsView): (handleDirtyBitmap): * java/org/gnu/emacs/EmacsWindow.java (changeWindowBackground) (EmacsWindow): Make compatible with Android 2.2 and later. * lib-src/Makefile.in (DONT_INSTALL): Add asset-directory-tool on Android.:(asset-directory-tool{EXEEXT}): New target. * lib-src/asset-directory-tool.c (struct directory_tree, xmalloc) (main_1, main_2, main): New file. * lib, m4: Merge from gnulib. This will be reverted before merging to master. * lisp/button.el (button-map): (push-button): * lisp/frame.el (display-popup-menus-p): Improve touchscreen support. * lisp/subr.el (event-start): (event-end): Handle touchscreen events. * lisp/touch-screen.el (touch-screen-handle-timeout): (touch-screen-handle-point-update): (touch-screen-handle-point-up): (touch-screen-track-tap): (touch-screen-track-drag): (touch-screen-drag-mode-line-1): (touch-screen-drag-mode-line): New functions. ([mode-line touchscreen-begin]): ([bottom-divider touchscreen-begin]): Bind new events. * lisp/wid-edit.el (widget-event-point): (widget-keymap): (widget-event-start): (widget-button--check-and-call-button): (widget-button-click): Improve touchscreen support. * src/alloc.c (make_lisp_symbol): Avoid ICE on Android NDK GCC. (mark_pinned_symbols): Likewise. * src/android.c (struct android_emacs_window): New struct. (window_class): New variable. (android_run_select_thread): Add workaround for Android platform bug. (android_extract_long, android_scan_directory_tree): New functions. (android_file_access_p): Use those functions instead. (android_init_emacs_window): New function. (android_init_emacs_gc_class): Update signature of `markDirty'. (android_change_gc, android_set_clip_rectangles): Tell the GC whether or not clip rects were dirtied. (android_swap_buffers): Do not look up method every time. (struct android_dir): Adjust for new directory tree lookup. (android_opendir, android_readdir, android_closedir): Likewise. (android_four_corners_bilinear): Fix coding style. (android_ftruncate): New function. * src/android.h: Update prototypes. Replace ftruncate with android_ftruncate when necessary. * src/androidterm.c (handle_one_android_event): Pacify GCC. Fix touch screen tool bar bug. * src/emacs.c (using_utf8): Fix compilation error. * src/fileio.c (Ffile_system_info): Return Qnil when fsusage.o is not built. * src/filelock.c (BOOT_TIME_FILE): Fix definition for Android. * src/frame.c (Fx_parse_geometry): Fix uninitialized variable uses. * src/keyboard.c (lispy_function_keys): Fix `back'. * src/menu.c (x_popup_menu_1): Handle touch screen events. (Fx_popup_menu): Document changes. * src/sfnt.c (main): Improve tests. * src/sfntfont-android.c (sfntfont_android_put_glyphs): Fix minor problem. (init_sfntfont_android): Check for HAVE_DECL_ANDROID_GET_DEVICE_API_LEVEL. * src/sfntfont.c (struct sfnt_font_desc): New fields `adstyle' and `languages'. (sfnt_parse_style): Append tokens to adstyle. (sfnt_parse_languages): New function. (sfnt_enum_font_1): Parse supported languages and adstyle. (sfntfont_list_1): Handle new fields. (sfntfont_text_extents): Fix uninitialized variable use. (syms_of_sfntfont, mark_sfntfont): Adjust accordingly. --- lisp/wid-edit.el | 122 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 48 deletions(-) (limited to 'lisp/wid-edit.el') diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 60bd2baa6fb..4c52d827980 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -65,8 +65,11 @@ ;;; Compatibility. (defun widget-event-point (event) - "Character position of the end of event if that exists, or nil." - (posn-point (event-end event))) + "Character position of the end of event if that exists, or nil. +EVENT can either be a mouse event or a touch screen event." + (if (eq (car-safe event) 'touchscreen-begin) + (posn-point (cdadr event)) + (posn-point (event-end event)))) (defun widget-button-release-event-p (event) "Non-nil if EVENT is a mouse-button-release event object." @@ -1017,6 +1020,7 @@ button end points." (define-key map [backtab] 'widget-backward) (define-key map [down-mouse-2] 'widget-button-click) (define-key map [down-mouse-1] 'widget-button-click) + (define-key map [touchscreen-begin] 'widget-button-click) ;; The following definition needs to avoid using escape sequences that ;; might get converted to ^M when building loaddefs.el (define-key map [(control ?m)] 'widget-button-press) @@ -1072,8 +1076,18 @@ Note that such modes will need to require wid-edit.") "If non-nil, `widget-button-click' moves point to a button after invoking it. If nil, point returns to its original position after invoking a button.") +(defun widget-event-start (event) + "Return the start of EVENT. +If EVENT is not a touchscreen event, simply return its +`event-start'. Otherwise, it is a touchscreen event, so return +the posn of its touchpoint." + (if (eq (car event) 'touchscreen-begin) + (cdadr event) + (event-start event))) + (defun widget-button--check-and-call-button (event button) "Call BUTTON if BUTTON is a widget and EVENT is correct for it. +EVENT can either be a mouse event or a touchscreen-begin event. If nothing was called, return non-nil." (let* ((oevent event) (mouse-1 (memq (event-basic-type event) '(mouse-1 down-mouse-1))) @@ -1084,49 +1098,58 @@ If nothing was called, return non-nil." ;; in a save-excursion so that the click on the button ;; doesn't change point. (save-selected-window - (select-window (posn-window (event-start event))) + (select-window (posn-window (widget-event-start event))) (save-excursion - (goto-char (posn-point (event-start event))) + (goto-char (posn-point (widget-event-start event))) (let* ((overlay (widget-get button :button-overlay)) (pressed-face (or (widget-get button :pressed-face) widget-button-pressed-face)) (face (overlay-get overlay 'face)) (mouse-face (overlay-get overlay 'mouse-face))) (unwind-protect - ;; Read events, including mouse-movement - ;; events, waiting for a release event. If we - ;; began with a mouse-1 event and receive a - ;; movement event, that means the user wants - ;; to perform drag-selection, so cancel the - ;; button press and do the default mouse-1 - ;; action. For mouse-2, just highlight/ - ;; unhighlight the button the mouse was - ;; initially on when we move over it. + ;; Read events, including mouse-movement events, + ;; waiting for a release event. If we began with a + ;; mouse-1 event and receive a movement event, that + ;; means the user wants to perform drag-selection, so + ;; cancel the button press and do the default mouse-1 + ;; action. For mouse-2, just highlight/ unhighlight + ;; the button the mouse was initially on when we move + ;; over it. + ;; + ;; If this function was called in response to a + ;; touchscreen event, then wait for a corresponding + ;; touchscreen-end event instead. (save-excursion (when face ; avoid changing around image (overlay-put overlay 'face pressed-face) (overlay-put overlay 'mouse-face pressed-face)) - (unless (widget-apply button :mouse-down-action event) - (let ((track-mouse t)) - (while (not (widget-button-release-event-p event)) - (setq event (read--potential-mouse-event)) - (when (and mouse-1 (mouse-movement-p event)) - (push event unread-command-events) - (setq event oevent) - (throw 'button-press-cancelled t)) - (unless (or (integerp event) - (memq (car event) - '(switch-frame select-window)) - (eq (car event) 'scroll-bar-movement)) - (setq pos (widget-event-point event)) - (if (and pos - (eq (get-char-property pos 'button) - button)) - (when face - (overlay-put overlay 'face pressed-face) - (overlay-put overlay 'mouse-face pressed-face)) - (overlay-put overlay 'face face) - (overlay-put overlay 'mouse-face mouse-face)))))) + (if (eq (car event) 'touchscreen-begin) + ;; This a touchscreen event and must be handled + ;; specially through `touch-screen-track-tap'. + (progn + (unless (touch-screen-track-tap event) + (throw 'button-press-cancelled t))) + (unless (widget-apply button :mouse-down-action event) + (let ((track-mouse t)) + (while (not (widget-button-release-event-p event)) + (setq event (read--potential-mouse-event)) + (when (and mouse-1 (mouse-movement-p event)) + (push event unread-command-events) + (setq event oevent) + (throw 'button-press-cancelled t)) + (unless (or (integerp event) + (memq (car event) + '(switch-frame select-window)) + (eq (car event) 'scroll-bar-movement)) + (setq pos (widget-event-point event)) + (if (and pos + (eq (get-char-property pos 'button) + button)) + (when face + (overlay-put overlay 'face pressed-face) + (overlay-put overlay 'mouse-face pressed-face)) + (overlay-put overlay 'face face) + (overlay-put overlay 'mouse-face mouse-face))))))) ;; When mouse is released over the button, run ;; its action function. @@ -1148,32 +1171,35 @@ If nothing was called, return non-nil." (if (widget-event-point event) (let* ((mouse-1 (memq (event-basic-type event) '(mouse-1 down-mouse-1))) (pos (widget-event-point event)) - (start (event-start event)) + (start (widget-event-start event)) (button (get-char-property pos 'button (and (windowp (posn-window start)) (window-buffer (posn-window start)))))) (when (or (null button) (widget-button--check-and-call-button event button)) - (let ((up t) + (let ((up (not (eq (car event) 'touchscreen-begin))) command) ;; Mouse click not on a widget button. Find the global ;; command to run, and check whether it is bound to an ;; up event. - (if mouse-1 - (cond ((setq command ;down event - (lookup-key widget-global-map [down-mouse-1])) - (setq up nil)) - ((setq command ;up event - (lookup-key widget-global-map [mouse-1])))) - (cond ((setq command ;down event - (lookup-key widget-global-map [down-mouse-2])) - (setq up nil)) - ((setq command ;up event - (lookup-key widget-global-map [mouse-2]))))) + (cond + ((eq (car event) 'touchscreen-begin) + (setq command (lookup-key widget-global-map + [touchscreen-begin]))) + (mouse-1 (cond ((setq command ;down event + (lookup-key widget-global-map [down-mouse-1])) + (setq up nil)) + ((setq command ;up event + (lookup-key widget-global-map [mouse-1]))))) + (t (cond ((setq command ;down event + (lookup-key widget-global-map [down-mouse-2])) + (setq up nil)) + ((setq command ;up event + (lookup-key widget-global-map [mouse-2])))))) (when up ;; Don't execute up events twice. - (while (not (widget-button-release-event-p event)) + (while (not (and (widget-button-release-event-p event))) (setq event (read--potential-mouse-event)))) (when command (call-interactively command))))) -- cgit v1.2.1