[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/android c8c2bec5f8e: Update Android port
From: |
Po Lu |
Subject: |
feature/android c8c2bec5f8e: Update Android port |
Date: |
Tue, 11 Jul 2023 21:46:14 -0400 (EDT) |
branch: feature/android
commit c8c2bec5f8e4964f23345e1150a7ab85003e688b
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Update Android port
* java/org/gnu/emacs/EmacsWindow.java (whatButtonWasIt): Handle
back and forward buttons along with styluses.
* src/doc.c (close_file_unwind_android_fd): New function.
(get_doc_string, Fsnarf_documentation): Don't create a temporary
fd if it can be avoided.
---
java/org/gnu/emacs/EmacsWindow.java | 53 +++++++++++++++++++------
src/doc.c | 79 ++++++++++++++++++++++++++++++++-----
2 files changed, 110 insertions(+), 22 deletions(-)
diff --git a/java/org/gnu/emacs/EmacsWindow.java
b/java/org/gnu/emacs/EmacsWindow.java
index 6816f3e8e71..5e45275631b 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -700,29 +700,36 @@ public final class EmacsWindow extends EmacsHandleObject
Android does not conceptually distinguish between mouse events
(those coming from a device whose movement affects the on-screen
- pointer image) and touch screen events. When a touch, click, or
- pointer motion takes place, several kinds of event can be sent:
+ pointer image) and touch screen events. Each click or touch
+ starts a single pointer gesture sequence, and subsequent motion
+ of the device will result in updates being reported relative to
+ that sequence until the mouse button or touch is released.
+
+ When a touch, click, or pointer motion takes place, several kinds
+ of event can be sent:
ACTION_DOWN or ACTION_POINTER_DOWN is sent with a new coordinate
- and an associated ``pointer ID'' identifying the event when a
- click or touch takes place. Emacs is responsible for recording
- both the position of this click for the purpose of determining
- future changes to the position of that touch.
+ and an associated ``pointer ID'' identifying the event and its
+ gesture sequence when a click or touch takes place. Emacs is
+ responsible for recording both the position and pointer ID of
+ this click for the purpose of determining future changes to its
+ position.
ACTION_UP or ACTION_POINTER_UP is sent with a pointer ID when the
click associated with a previous ACTION_DOWN event is released.
ACTION_CANCEL (or ACTION_POINTER_UP with FLAG_CANCELED) is sent
if a similar situation transpires: the window system has chosen
- to grab of the click, and future movement will no longer be
- reported to Emacs.
+ to grab the click, and future changes to its position will no
+ longer be reported to Emacs.
ACTION_MOVE is sent if a coordinate tied to a click that has not
been released changes. Emacs processes this event by comparing
each of the coordinates within the event with its recollection of
those contained within prior ACTION_DOWN and ACTION_MOVE events;
- the pointer ID of the difference is then reported within a touch
- or pointer motion event along with its new position.
+ the pointer ID of the differing coordinate is then reported
+ within a touch or pointer motion event along with its new
+ position.
The events described above are all sent for both touch and mouse
click events. Determining whether an ACTION_DOWN event is
@@ -746,7 +753,12 @@ public final class EmacsWindow extends EmacsHandleObject
coordinate.
ACTION_HOVER_ENTER and ACTION_HOVER_LEAVE are respectively sent
- when the mouse pointer enters and leaves a frame.
+ when the mouse pointer enters and leaves a frame. Moreover,
+ ACTION_HOVER_LEAVE events are sent immediately before an
+ ACTION_DOWN event associated with a mouse click. These
+ extraneous events are distinct in that their button states always
+ contain an additional button compared to the button state
+ recorded at the time of the last ACTION_UP event.
On Android 6.0 and later, ACTION_BUTTON_PRESS is sent with the
coordinate of the mouse pointer if a mouse click occurs,
@@ -789,8 +801,25 @@ public final class EmacsWindow extends EmacsHandleObject
if ((notIn & MotionEvent.BUTTON_TERTIARY) != 0)
return 2;
+ /* Buttons 4, 5, 6 and 7 are actually scroll wheels under X.
+ Thus, report additional buttons starting at 8. */
+
+ if ((notIn & MotionEvent.BUTTON_BACK) != 0)
+ return 8;
+
+ if ((notIn & MotionEvent.BUTTON_FORWARD) != 0)
+ return 9;
+
+ /* Report stylus events as touch screen events. */
+
+ if ((notIn & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0)
+ return 0;
+
+ if ((notIn & MotionEvent.BUTTON_STYLUS_SECONDARY) != 0)
+ return 0;
+
/* Not a real value. */
- return 4;
+ return 11;
}
/* Return the mouse button associated with the specified ACTION_DOWN
diff --git a/src/doc.c b/src/doc.c
index 174341523d7..56991ffcdfe 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -37,6 +37,41 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include "intervals.h"
#include "keymap.h"
+
+
+#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY \
+ || (__ANDROID_API__ < 9)
+#define doc_fd int
+#define doc_fd_p(fd) ((fd) >= 0)
+#define doc_open emacs_open
+#define doc_close emacs_close
+#define doc_read_quit emacs_read_quit
+#define doc_lseek lseek
+#else /* HAVE_ANDROID && !defined ANDROID_STUBIFY
+ && __ANDROID_API__ >= 9 */
+
+#include "android.h"
+
+/* Use an Android file descriptor under Android instead, as this
+ allows loading directly from asset files without loading each asset
+ into memory and creating a separate file descriptor every time.
+
+ However, lread requires the ability to seek inside asset files,
+ which is not provided under Android 2.2. So when building for that
+ particular system, fall back to the usual file descriptor-based
+ code. */
+
+#define doc_fd struct android_fd_or_asset
+#define doc_fd_p(fd) ((fd).asset != (void *) -1)
+#define doc_open android_open_asset
+#define doc_close android_close_asset
+#define doc_read_quit android_asset_read_quit
+#define doc_lseek android_asset_lseek
+#define USE_ANDROID_ASSETS
+#endif /* !HAVE_ANDROID || ANDROID_STUBIFY || __ANDROID_API__ < 9 */
+
+
+
/* Buffer used for reading from documentation file. */
static char *get_doc_string_buffer;
static ptrdiff_t get_doc_string_buffer_size;
@@ -59,6 +94,22 @@ read_bytecode_char (bool unreadflag)
return *read_bytecode_pointer++;
}
+#ifdef USE_ANDROID_ASSETS
+
+/* Like `close_file_unwind'. However, PTR is a pointer to an Android
+ file descriptor instead of a system file descriptor. */
+
+static void
+close_file_unwind_android_fd (void *ptr)
+{
+ struct android_fd_or_asset *fd;
+
+ fd = ptr;
+ android_close_asset (*fd);
+}
+
+#endif /* USE_ANDROID_ASSETS */
+
/* Extract a doc string from a file. FILEPOS says where to get it.
If it is an integer, use that position in the standard DOC file.
If it is (FILE . INTEGER), use FILE as the file name
@@ -123,8 +174,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool
definition)
name = SAFE_ALLOCA (docdir_sizemax + SBYTES (file));
lispstpcpy (lispstpcpy (name, docdir), file);
- int fd = emacs_open (name, O_RDONLY, 0);
- if (fd < 0)
+ doc_fd fd = doc_open (name, O_RDONLY, 0);
+ if (!doc_fd_p (fd))
{
if (will_dump_p ())
{
@@ -132,9 +183,9 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool
definition)
So check in ../etc. */
lispstpcpy (stpcpy (name, sibling_etc), file);
- fd = emacs_open (name, O_RDONLY, 0);
+ fd = doc_open (name, O_RDONLY, 0);
}
- if (fd < 0)
+ if (!doc_fd_p (fd))
{
if (errno != ENOENT && errno != ENOTDIR)
report_file_error ("Read error on documentation file", file);
@@ -145,14 +196,18 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool
definition)
return concat3 (cannot_open, file, quote_nl);
}
}
+#ifndef USE_ANDROID_ASSETS
record_unwind_protect_int (close_file_unwind, fd);
+#else /* USE_ANDROID_ASSETS */
+ record_unwind_protect_ptr (close_file_unwind_android_fd, &fd);
+#endif /* !USE_ANDROID_ASSETS */
/* Seek only to beginning of disk block. */
/* Make sure we read at least 1024 bytes before `position'
so we can check the leading text for consistency. */
int offset = min (position, max (1024, position % (8 * 1024)));
if (TYPE_MAXIMUM (off_t) < position
- || lseek (fd, position - offset, 0) < 0)
+ || doc_lseek (fd, position - offset, 0) < 0)
error ("Position %"pI"d out of range in doc string file \"%s\"",
position, name);
@@ -181,7 +236,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool
definition)
If we read the same block last time, maybe skip this? */
if (space_left > 1024 * 8)
space_left = 1024 * 8;
- int nread = emacs_read_quit (fd, p, space_left);
+ int nread = doc_read_quit (fd, p, space_left);
if (nread < 0)
report_file_error ("Read error on documentation file", file);
p[nread] = 0;
@@ -504,7 +559,7 @@ That file is found in `../etc' now; later, when the dumped
Emacs is run,
the same file name is found in the `doc-directory'. */)
(Lisp_Object filename)
{
- int fd;
+ doc_fd fd;
char buf[1024 + 1];
int filled;
EMACS_INT pos;
@@ -551,21 +606,25 @@ the same file name is found in the `doc-directory'. */)
Vbuild_files = Fpurecopy (Vbuild_files);
}
- fd = emacs_open (name, O_RDONLY, 0);
- if (fd < 0)
+ fd = doc_open (name, O_RDONLY, 0);
+ if (!doc_fd_p (fd))
{
int open_errno = errno;
report_file_errno ("Opening doc string file", build_string (name),
open_errno);
}
+#ifndef USE_ANDROID_ASSETS
record_unwind_protect_int (close_file_unwind, fd);
+#else /* USE_ANDROID_ASSETS */
+ record_unwind_protect_ptr (close_file_unwind_android_fd, &fd);
+#endif /* !USE_ANDROID_ASSETS */
Vdoc_file_name = filename;
filled = 0;
pos = 0;
while (true)
{
if (filled < 512)
- filled += emacs_read_quit (fd, &buf[filled], sizeof buf - 1 - filled);
+ filled += doc_read_quit (fd, &buf[filled], sizeof buf - 1 - filled);
if (!filled)
break;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- feature/android c8c2bec5f8e: Update Android port,
Po Lu <=