diff options
| author | Po Lu | 2023-07-12 09:45:58 +0800 |
|---|---|---|
| committer | Po Lu | 2023-07-12 09:45:58 +0800 |
| commit | c8c2bec5f8e4964f23345e1150a7ab85003e688b (patch) | |
| tree | 198fe374222ff1846d20e3f96275b44f85192d94 /src | |
| parent | fe7861f8088b481584b8122769121d2bfe26f643 (diff) | |
| download | emacs-c8c2bec5f8e4964f23345e1150a7ab85003e688b.tar.gz emacs-c8c2bec5f8e4964f23345e1150a7ab85003e688b.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc.c | 79 |
1 files changed, 69 insertions, 10 deletions
| @@ -37,6 +37,41 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 37 | #include "intervals.h" | 37 | #include "intervals.h" |
| 38 | #include "keymap.h" | 38 | #include "keymap.h" |
| 39 | 39 | ||
| 40 | |||
| 41 | |||
| 42 | #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY \ | ||
| 43 | || (__ANDROID_API__ < 9) | ||
| 44 | #define doc_fd int | ||
| 45 | #define doc_fd_p(fd) ((fd) >= 0) | ||
| 46 | #define doc_open emacs_open | ||
| 47 | #define doc_close emacs_close | ||
| 48 | #define doc_read_quit emacs_read_quit | ||
| 49 | #define doc_lseek lseek | ||
| 50 | #else /* HAVE_ANDROID && !defined ANDROID_STUBIFY | ||
| 51 | && __ANDROID_API__ >= 9 */ | ||
| 52 | |||
| 53 | #include "android.h" | ||
| 54 | |||
| 55 | /* Use an Android file descriptor under Android instead, as this | ||
| 56 | allows loading directly from asset files without loading each asset | ||
| 57 | into memory and creating a separate file descriptor every time. | ||
| 58 | |||
| 59 | However, lread requires the ability to seek inside asset files, | ||
| 60 | which is not provided under Android 2.2. So when building for that | ||
| 61 | particular system, fall back to the usual file descriptor-based | ||
| 62 | code. */ | ||
| 63 | |||
| 64 | #define doc_fd struct android_fd_or_asset | ||
| 65 | #define doc_fd_p(fd) ((fd).asset != (void *) -1) | ||
| 66 | #define doc_open android_open_asset | ||
| 67 | #define doc_close android_close_asset | ||
| 68 | #define doc_read_quit android_asset_read_quit | ||
| 69 | #define doc_lseek android_asset_lseek | ||
| 70 | #define USE_ANDROID_ASSETS | ||
| 71 | #endif /* !HAVE_ANDROID || ANDROID_STUBIFY || __ANDROID_API__ < 9 */ | ||
| 72 | |||
| 73 | |||
| 74 | |||
| 40 | /* Buffer used for reading from documentation file. */ | 75 | /* Buffer used for reading from documentation file. */ |
| 41 | static char *get_doc_string_buffer; | 76 | static char *get_doc_string_buffer; |
| 42 | static ptrdiff_t get_doc_string_buffer_size; | 77 | static ptrdiff_t get_doc_string_buffer_size; |
| @@ -59,6 +94,22 @@ read_bytecode_char (bool unreadflag) | |||
| 59 | return *read_bytecode_pointer++; | 94 | return *read_bytecode_pointer++; |
| 60 | } | 95 | } |
| 61 | 96 | ||
| 97 | #ifdef USE_ANDROID_ASSETS | ||
| 98 | |||
| 99 | /* Like `close_file_unwind'. However, PTR is a pointer to an Android | ||
| 100 | file descriptor instead of a system file descriptor. */ | ||
| 101 | |||
| 102 | static void | ||
| 103 | close_file_unwind_android_fd (void *ptr) | ||
| 104 | { | ||
| 105 | struct android_fd_or_asset *fd; | ||
| 106 | |||
| 107 | fd = ptr; | ||
| 108 | android_close_asset (*fd); | ||
| 109 | } | ||
| 110 | |||
| 111 | #endif /* USE_ANDROID_ASSETS */ | ||
| 112 | |||
| 62 | /* Extract a doc string from a file. FILEPOS says where to get it. | 113 | /* Extract a doc string from a file. FILEPOS says where to get it. |
| 63 | If it is an integer, use that position in the standard DOC file. | 114 | If it is an integer, use that position in the standard DOC file. |
| 64 | If it is (FILE . INTEGER), use FILE as the file name | 115 | 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) | |||
| 123 | name = SAFE_ALLOCA (docdir_sizemax + SBYTES (file)); | 174 | name = SAFE_ALLOCA (docdir_sizemax + SBYTES (file)); |
| 124 | lispstpcpy (lispstpcpy (name, docdir), file); | 175 | lispstpcpy (lispstpcpy (name, docdir), file); |
| 125 | 176 | ||
| 126 | int fd = emacs_open (name, O_RDONLY, 0); | 177 | doc_fd fd = doc_open (name, O_RDONLY, 0); |
| 127 | if (fd < 0) | 178 | if (!doc_fd_p (fd)) |
| 128 | { | 179 | { |
| 129 | if (will_dump_p ()) | 180 | if (will_dump_p ()) |
| 130 | { | 181 | { |
| @@ -132,9 +183,9 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) | |||
| 132 | So check in ../etc. */ | 183 | So check in ../etc. */ |
| 133 | lispstpcpy (stpcpy (name, sibling_etc), file); | 184 | lispstpcpy (stpcpy (name, sibling_etc), file); |
| 134 | 185 | ||
| 135 | fd = emacs_open (name, O_RDONLY, 0); | 186 | fd = doc_open (name, O_RDONLY, 0); |
| 136 | } | 187 | } |
| 137 | if (fd < 0) | 188 | if (!doc_fd_p (fd)) |
| 138 | { | 189 | { |
| 139 | if (errno != ENOENT && errno != ENOTDIR) | 190 | if (errno != ENOENT && errno != ENOTDIR) |
| 140 | report_file_error ("Read error on documentation file", file); | 191 | report_file_error ("Read error on documentation file", file); |
| @@ -145,14 +196,18 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) | |||
| 145 | return concat3 (cannot_open, file, quote_nl); | 196 | return concat3 (cannot_open, file, quote_nl); |
| 146 | } | 197 | } |
| 147 | } | 198 | } |
| 199 | #ifndef USE_ANDROID_ASSETS | ||
| 148 | record_unwind_protect_int (close_file_unwind, fd); | 200 | record_unwind_protect_int (close_file_unwind, fd); |
| 201 | #else /* USE_ANDROID_ASSETS */ | ||
| 202 | record_unwind_protect_ptr (close_file_unwind_android_fd, &fd); | ||
| 203 | #endif /* !USE_ANDROID_ASSETS */ | ||
| 149 | 204 | ||
| 150 | /* Seek only to beginning of disk block. */ | 205 | /* Seek only to beginning of disk block. */ |
| 151 | /* Make sure we read at least 1024 bytes before `position' | 206 | /* Make sure we read at least 1024 bytes before `position' |
| 152 | so we can check the leading text for consistency. */ | 207 | so we can check the leading text for consistency. */ |
| 153 | int offset = min (position, max (1024, position % (8 * 1024))); | 208 | int offset = min (position, max (1024, position % (8 * 1024))); |
| 154 | if (TYPE_MAXIMUM (off_t) < position | 209 | if (TYPE_MAXIMUM (off_t) < position |
| 155 | || lseek (fd, position - offset, 0) < 0) | 210 | || doc_lseek (fd, position - offset, 0) < 0) |
| 156 | error ("Position %"pI"d out of range in doc string file \"%s\"", | 211 | error ("Position %"pI"d out of range in doc string file \"%s\"", |
| 157 | position, name); | 212 | position, name); |
| 158 | 213 | ||
| @@ -181,7 +236,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) | |||
| 181 | If we read the same block last time, maybe skip this? */ | 236 | If we read the same block last time, maybe skip this? */ |
| 182 | if (space_left > 1024 * 8) | 237 | if (space_left > 1024 * 8) |
| 183 | space_left = 1024 * 8; | 238 | space_left = 1024 * 8; |
| 184 | int nread = emacs_read_quit (fd, p, space_left); | 239 | int nread = doc_read_quit (fd, p, space_left); |
| 185 | if (nread < 0) | 240 | if (nread < 0) |
| 186 | report_file_error ("Read error on documentation file", file); | 241 | report_file_error ("Read error on documentation file", file); |
| 187 | p[nread] = 0; | 242 | p[nread] = 0; |
| @@ -504,7 +559,7 @@ That file is found in `../etc' now; later, when the dumped Emacs is run, | |||
| 504 | the same file name is found in the `doc-directory'. */) | 559 | the same file name is found in the `doc-directory'. */) |
| 505 | (Lisp_Object filename) | 560 | (Lisp_Object filename) |
| 506 | { | 561 | { |
| 507 | int fd; | 562 | doc_fd fd; |
| 508 | char buf[1024 + 1]; | 563 | char buf[1024 + 1]; |
| 509 | int filled; | 564 | int filled; |
| 510 | EMACS_INT pos; | 565 | EMACS_INT pos; |
| @@ -551,21 +606,25 @@ the same file name is found in the `doc-directory'. */) | |||
| 551 | Vbuild_files = Fpurecopy (Vbuild_files); | 606 | Vbuild_files = Fpurecopy (Vbuild_files); |
| 552 | } | 607 | } |
| 553 | 608 | ||
| 554 | fd = emacs_open (name, O_RDONLY, 0); | 609 | fd = doc_open (name, O_RDONLY, 0); |
| 555 | if (fd < 0) | 610 | if (!doc_fd_p (fd)) |
| 556 | { | 611 | { |
| 557 | int open_errno = errno; | 612 | int open_errno = errno; |
| 558 | report_file_errno ("Opening doc string file", build_string (name), | 613 | report_file_errno ("Opening doc string file", build_string (name), |
| 559 | open_errno); | 614 | open_errno); |
| 560 | } | 615 | } |
| 616 | #ifndef USE_ANDROID_ASSETS | ||
| 561 | record_unwind_protect_int (close_file_unwind, fd); | 617 | record_unwind_protect_int (close_file_unwind, fd); |
| 618 | #else /* USE_ANDROID_ASSETS */ | ||
| 619 | record_unwind_protect_ptr (close_file_unwind_android_fd, &fd); | ||
| 620 | #endif /* !USE_ANDROID_ASSETS */ | ||
| 562 | Vdoc_file_name = filename; | 621 | Vdoc_file_name = filename; |
| 563 | filled = 0; | 622 | filled = 0; |
| 564 | pos = 0; | 623 | pos = 0; |
| 565 | while (true) | 624 | while (true) |
| 566 | { | 625 | { |
| 567 | if (filled < 512) | 626 | if (filled < 512) |
| 568 | filled += emacs_read_quit (fd, &buf[filled], sizeof buf - 1 - filled); | 627 | filled += doc_read_quit (fd, &buf[filled], sizeof buf - 1 - filled); |
| 569 | if (!filled) | 628 | if (!filled) |
| 570 | break; | 629 | break; |
| 571 | 630 | ||