diff options
| author | Po Lu | 2023-01-17 22:10:43 +0800 |
|---|---|---|
| committer | Po Lu | 2023-01-17 22:10:43 +0800 |
| commit | 1b8258a1f2b6a080a4f0e819aa4a86c1ec2da89f (patch) | |
| tree | d6c709e513882f5d430a98508e631cc503469fab /src/android.c | |
| parent | 356249d9faf2b454879ff30f06d97beb97fb9a36 (diff) | |
| download | emacs-1b8258a1f2b6a080a4f0e819aa4a86c1ec2da89f.tar.gz emacs-1b8258a1f2b6a080a4f0e819aa4a86c1ec2da89f.zip | |
Update Android port
* doc/emacs/android.texi (Android Fonts): Document that TTC
format fonts are now supported.
* doc/emacs/emacs.texi (Top): Fix menus.
* doc/lispref/commands.texi (Touchscreen Events)
(Key Sequence Input): Document changes to touchscreen events.
* etc/DEBUG: Describe how to debug 64 bit binaries on Android.
* java/org/gnu/emacs/EmacsCopyArea.java (perform): Explicitly
recycle copy bitmap.
* java/org/gnu/emacs/EmacsDialog.java (EmacsDialog): New class.
* java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Use 5
point PolyLine like X, because Android behaves like Postscript
on some devices and X elsewhere.
* java/org/gnu/emacs/EmacsFillRectangle.java (perform):
Explicitly recycle copy bitmap.
* java/org/gnu/emacs/EmacsPixmap.java (destroyHandle):
Explicitly recycle bitmap and GC if it is big.
* java/org/gnu/emacs/EmacsView.java (EmacsView): Make
`bitmapDirty' a boolean.
(handleDirtyBitmap): Reimplement in terms of that boolean.
Explicitly recycle old bitmap and GC.
(onLayout): Fix lock up.
(onDetachedFromWindow): Recycle bitmap and GC.
* java/org/gnu/emacs/EmacsWindow.java (requestViewLayout):
Update call to explicitlyDirtyBitmap.
* src/android.c (android_run_select_thread, android_select):
Really fix android_select.
(android_build_jstring): New function.
* src/android.h: Update prototypes.
* src/androidmenu.c (android_process_events_for_menu): Totally
unblock input before process_pending_signals.
(android_menu_show): Remove redundant unblock_input and
debugging code.
(struct android_emacs_dialog, android_init_emacs_dialog)
(android_dialog_show, android_popup_dialog, init_androidmenu):
Implement popup dialogs on Android.
* src/androidterm.c (android_update_tools)
(handle_one_android_event, android_frame_up_to_date): Allow
tapping tool bar items.
(android_create_terminal): Add dialog hook.
(android_wait_for_event): Adjust call to android_select.
* src/androidterm.h (struct android_touch_point): New field
`tool_bar_p'.
* src/keyboard.c (read_key_sequence, head_table)
(syms_of_keyboard): Prefix touchscreen events with posn.
* src/keyboard.h (EVENT_HEAD): Handle touchscreen events.
* src/process.c (wait_reading_process_output): Adjust call to
android_select.
* src/sfnt.c (sfnt_read_table_directory): If the first long
turns out to be ttcf, return -1.
(sfnt_read_ttc_header): New function.
(main): Test TTC support.
* src/sfnt.h (struct sfnt_ttc_header): New structure.
(enum sfnt_ttc_tag): New enum.
* src/sfntfont-android.c (struct
sfntfont_android_scanline_buffer): New structure.
(GET_SCANLINE_BUFFER): New macro. Try to avoid so much malloc
upon accessing the scanline buffer.
(sfntfont_android_put_glyphs): Do not use SAFE_ALLOCA to
allocate the scaline buffer.
(Fandroid_enumerate_fonts): Enumerate ttc fonts too.
* src/sfntfont.c (struct sfnt_font_desc): New field `offset'.
(sfnt_enum_font_1): Split out enumeration code from
sfnt_enum_font.
(sfnt_enum_font): Read TTC tables and enumerate each font
therein.
(sfntfont_open): Seek to the offset specified.
* xcompile/Makefile.in (maintainer-clean): Fix depends here.
Diffstat (limited to 'src/android.c')
| -rw-r--r-- | src/android.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/src/android.c b/src/android.c index 9b15ea9f15a..cfb79045c0b 100644 --- a/src/android.c +++ b/src/android.c | |||
| @@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 26 | #include <semaphore.h> | 26 | #include <semaphore.h> |
| 27 | #include <dlfcn.h> | 27 | #include <dlfcn.h> |
| 28 | #include <errno.h> | 28 | #include <errno.h> |
| 29 | #include <math.h> | ||
| 29 | 30 | ||
| 30 | #include <sys/stat.h> | 31 | #include <sys/stat.h> |
| 31 | #include <sys/mman.h> | 32 | #include <sys/mman.h> |
| @@ -225,7 +226,6 @@ static fd_set *volatile android_pselect_readfds; | |||
| 225 | static fd_set *volatile android_pselect_writefds; | 226 | static fd_set *volatile android_pselect_writefds; |
| 226 | static fd_set *volatile android_pselect_exceptfds; | 227 | static fd_set *volatile android_pselect_exceptfds; |
| 227 | static struct timespec *volatile android_pselect_timeout; | 228 | static struct timespec *volatile android_pselect_timeout; |
| 228 | static const sigset_t *volatile android_pselect_sigset; | ||
| 229 | 229 | ||
| 230 | /* Value of pselect. */ | 230 | /* Value of pselect. */ |
| 231 | static int android_pselect_rc; | 231 | static int android_pselect_rc; |
| @@ -242,8 +242,8 @@ static sem_t android_pselect_sem, android_pselect_start_sem; | |||
| 242 | static void * | 242 | static void * |
| 243 | android_run_select_thread (void *data) | 243 | android_run_select_thread (void *data) |
| 244 | { | 244 | { |
| 245 | sigset_t signals, sigset; | 245 | sigset_t signals, waitset; |
| 246 | int rc; | 246 | int rc, sig; |
| 247 | 247 | ||
| 248 | sigfillset (&signals); | 248 | sigfillset (&signals); |
| 249 | 249 | ||
| @@ -253,6 +253,8 @@ android_run_select_thread (void *data) | |||
| 253 | strerror (errno)); | 253 | strerror (errno)); |
| 254 | 254 | ||
| 255 | sigdelset (&signals, SIGUSR1); | 255 | sigdelset (&signals, SIGUSR1); |
| 256 | sigemptyset (&waitset); | ||
| 257 | sigaddset (&waitset, SIGUSR1); | ||
| 256 | 258 | ||
| 257 | while (true) | 259 | while (true) |
| 258 | { | 260 | { |
| @@ -262,35 +264,33 @@ android_run_select_thread (void *data) | |||
| 262 | 264 | ||
| 263 | /* Get the select lock and call pselect. */ | 265 | /* Get the select lock and call pselect. */ |
| 264 | pthread_mutex_lock (&event_queue.select_mutex); | 266 | pthread_mutex_lock (&event_queue.select_mutex); |
| 265 | |||
| 266 | /* Make sure SIGUSR1 can always wake pselect up. */ | ||
| 267 | if (android_pselect_sigset) | ||
| 268 | { | ||
| 269 | sigset = *android_pselect_sigset; | ||
| 270 | sigdelset (&sigset, SIGUSR1); | ||
| 271 | android_pselect_sigset = &sigset; | ||
| 272 | } | ||
| 273 | else | ||
| 274 | android_pselect_sigset = &signals; | ||
| 275 | |||
| 276 | rc = pselect (android_pselect_nfds, | 267 | rc = pselect (android_pselect_nfds, |
| 277 | android_pselect_readfds, | 268 | android_pselect_readfds, |
| 278 | android_pselect_writefds, | 269 | android_pselect_writefds, |
| 279 | android_pselect_exceptfds, | 270 | android_pselect_exceptfds, |
| 280 | android_pselect_timeout, | 271 | android_pselect_timeout, |
| 281 | android_pselect_sigset); | 272 | &signals); |
| 282 | android_pselect_rc = rc; | 273 | android_pselect_rc = rc; |
| 283 | pthread_mutex_unlock (&event_queue.select_mutex); | 274 | pthread_mutex_unlock (&event_queue.select_mutex); |
| 284 | 275 | ||
| 276 | /* Signal the main thread that there is now data to read. | ||
| 277 | It is ok to signal this condition variable without holding | ||
| 278 | the event queue lock, because android_select will always | ||
| 279 | wait for this to complete before returning. */ | ||
| 280 | android_pselect_completed = true; | ||
| 281 | pthread_cond_signal (&event_queue.read_var); | ||
| 282 | |||
| 283 | if (rc != -1 || errno != EINTR) | ||
| 284 | /* Now, wait for SIGUSR1, unless pselect was interrupted and | ||
| 285 | the signal was already delivered. The Emacs thread will | ||
| 286 | always send this signal after read_var is triggered or the | ||
| 287 | UI thread has sent an event. */ | ||
| 288 | sigwait (&waitset, &sig); | ||
| 289 | |||
| 285 | /* Signal the Emacs thread that pselect is done. If read_var | 290 | /* Signal the Emacs thread that pselect is done. If read_var |
| 286 | was signaled by android_write_event, event_queue.mutex could | 291 | was signaled by android_write_event, event_queue.mutex could |
| 287 | still be locked, so this must come before. */ | 292 | still be locked, so this must come before. */ |
| 288 | sem_post (&android_pselect_sem); | 293 | sem_post (&android_pselect_sem); |
| 289 | |||
| 290 | pthread_mutex_lock (&event_queue.mutex); | ||
| 291 | android_pselect_completed = true; | ||
| 292 | pthread_cond_signal (&event_queue.read_var); | ||
| 293 | pthread_mutex_unlock (&event_queue.mutex); | ||
| 294 | } | 294 | } |
| 295 | } | 295 | } |
| 296 | 296 | ||
| @@ -445,8 +445,7 @@ android_write_event (union android_event *event) | |||
| 445 | 445 | ||
| 446 | int | 446 | int |
| 447 | android_select (int nfds, fd_set *readfds, fd_set *writefds, | 447 | android_select (int nfds, fd_set *readfds, fd_set *writefds, |
| 448 | fd_set *exceptfds, struct timespec *timeout, | 448 | fd_set *exceptfds, struct timespec *timeout) |
| 449 | const sigset_t *sigset) | ||
| 450 | { | 449 | { |
| 451 | int nfds_return; | 450 | int nfds_return; |
| 452 | 451 | ||
| @@ -467,7 +466,6 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 467 | android_pselect_writefds = writefds; | 466 | android_pselect_writefds = writefds; |
| 468 | android_pselect_exceptfds = exceptfds; | 467 | android_pselect_exceptfds = exceptfds; |
| 469 | android_pselect_timeout = timeout; | 468 | android_pselect_timeout = timeout; |
| 470 | android_pselect_sigset = sigset; | ||
| 471 | pthread_mutex_unlock (&event_queue.select_mutex); | 469 | pthread_mutex_unlock (&event_queue.select_mutex); |
| 472 | 470 | ||
| 473 | /* Release the select thread. */ | 471 | /* Release the select thread. */ |
| @@ -3725,6 +3723,24 @@ android_build_string (Lisp_Object text) | |||
| 3725 | return string; | 3723 | return string; |
| 3726 | } | 3724 | } |
| 3727 | 3725 | ||
| 3726 | /* Do the same, except TEXT is constant string data. */ | ||
| 3727 | |||
| 3728 | jstring | ||
| 3729 | android_build_jstring (const char *text) | ||
| 3730 | { | ||
| 3731 | jstring string; | ||
| 3732 | |||
| 3733 | string = (*android_java_env)->NewStringUTF (android_java_env, | ||
| 3734 | text); | ||
| 3735 | if (!string) | ||
| 3736 | { | ||
| 3737 | (*android_java_env)->ExceptionClear (android_java_env); | ||
| 3738 | memory_full (0); | ||
| 3739 | } | ||
| 3740 | |||
| 3741 | return string; | ||
| 3742 | } | ||
| 3743 | |||
| 3728 | /* Check for JNI exceptions and call memory_full in that | 3744 | /* Check for JNI exceptions and call memory_full in that |
| 3729 | situation. */ | 3745 | situation. */ |
| 3730 | 3746 | ||