emacs-diffs
[Top][All Lists]
Advanced

[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;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]