aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c81
1 files changed, 63 insertions, 18 deletions
diff --git a/src/android.c b/src/android.c
index 4a74f5b2af4..41481afa475 100644
--- a/src/android.c
+++ b/src/android.c
@@ -40,6 +40,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/stat.h> 42#include <sys/stat.h>
43#include <sys/select.h>
43 44
44/* Old NDK versions lack MIN and MAX. */ 45/* Old NDK versions lack MIN and MAX. */
45#include <minmax.h> 46#include <minmax.h>
@@ -112,6 +113,8 @@ struct android_emacs_window
112 jmethodID define_cursor; 113 jmethodID define_cursor;
113 jmethodID damage_rect; 114 jmethodID damage_rect;
114 jmethodID recreate_activity; 115 jmethodID recreate_activity;
116 jmethodID clear_window;
117 jmethodID clear_area;
115}; 118};
116 119
117struct android_emacs_cursor 120struct android_emacs_cursor
@@ -152,6 +155,13 @@ static char *android_files_dir;
152/* The Java environment being used for the main thread. */ 155/* The Java environment being used for the main thread. */
153JNIEnv *android_java_env; 156JNIEnv *android_java_env;
154 157
158#ifdef THREADS_ENABLED
159
160/* The Java VM new threads attach to. */
161JavaVM *android_jvm;
162
163#endif /* THREADS_ENABLED */
164
155/* The EmacsGC class. */ 165/* The EmacsGC class. */
156static jclass emacs_gc_class; 166static jclass emacs_gc_class;
157 167
@@ -496,6 +506,9 @@ android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg)
496 This should ideally be defined further down. */ 506 This should ideally be defined further down. */
497static sem_t android_query_sem; 507static sem_t android_query_sem;
498 508
509/* ID of the Emacs thread. */
510static pthread_t main_thread_id;
511
499/* Set up the global event queue by initializing the mutex and two 512/* Set up the global event queue by initializing the mutex and two
500 condition variables, and the linked list of events. This must be 513 condition variables, and the linked list of events. This must be
501 called before starting the Emacs thread. Also, initialize the 514 called before starting the Emacs thread. Also, initialize the
@@ -531,6 +544,8 @@ android_init_events (void)
531 event_queue.events.next = &event_queue.events; 544 event_queue.events.next = &event_queue.events;
532 event_queue.events.last = &event_queue.events; 545 event_queue.events.last = &event_queue.events;
533 546
547 main_thread_id = pthread_self ();
548
534#if __ANDROID_API__ >= 16 549#if __ANDROID_API__ >= 16
535 550
536 /* Before starting the select thread, make sure the disposition for 551 /* Before starting the select thread, make sure the disposition for
@@ -579,10 +594,6 @@ android_pending (void)
579 return i; 594 return i;
580} 595}
581 596
582/* Forward declaration. */
583
584static void android_check_query (void);
585
586/* Wait for events to become available synchronously. Return once an 597/* Wait for events to become available synchronously. Return once an
587 event arrives. Also, reply to the UI thread whenever it requires a 598 event arrives. Also, reply to the UI thread whenever it requires a
588 response. */ 599 response. */
@@ -732,6 +743,12 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
732 static char byte; 743 static char byte;
733#endif 744#endif
734 745
746#ifdef THREADS_ENABLED
747 if (!pthread_equal (pthread_self (), main_thread_id))
748 return pselect (nfds, readfds, writefds, exceptfds, timeout,
749 NULL);
750#endif /* THREADS_ENABLED */
751
735 /* Since Emacs is reading keyboard input again, signify that queries 752 /* Since Emacs is reading keyboard input again, signify that queries
736 from input methods are no longer ``urgent''. */ 753 from input methods are no longer ``urgent''. */
737 754
@@ -837,9 +854,11 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
837 if (nfds_return < 0) 854 if (nfds_return < 0)
838 errno = EINTR; 855 errno = EINTR;
839 856
857#ifndef THREADS_ENABLED
840 /* Now check for and run anything the UI thread wants to run in the 858 /* Now check for and run anything the UI thread wants to run in the
841 main thread. */ 859 main thread. */
842 android_check_query (); 860 android_check_query ();
861#endif /* THREADS_ENABLED */
843 862
844 return nfds_return; 863 return nfds_return;
845} 864}
@@ -1315,12 +1334,17 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
1315 const char *java_string; 1334 const char *java_string;
1316 struct stat statb; 1335 struct stat statb;
1317 1336
1337#ifdef THREADS_ENABLED
1338 /* Save the Java VM. */
1339 if ((*env)->GetJavaVM (env, &android_jvm))
1340 emacs_abort ();
1341#endif /* THREADS_ENABLED */
1342
1318 /* Set the Android API level early, as it is used by 1343 /* Set the Android API level early, as it is used by
1319 `android_vfs_init'. */ 1344 `android_vfs_init'. */
1320 android_api_level = api_level; 1345 android_api_level = api_level;
1321 1346
1322 /* This function should only be called from the main thread. */ 1347 /* This function should only be called from the main thread. */
1323
1324 android_pixel_density_x = pixel_density_x; 1348 android_pixel_density_x = pixel_density_x;
1325 android_pixel_density_y = pixel_density_y; 1349 android_pixel_density_y = pixel_density_y;
1326 android_scaled_pixel_density = scaled_density; 1350 android_scaled_pixel_density = scaled_density;
@@ -1583,16 +1607,13 @@ android_init_emacs_service (void)
1583 FIND_METHOD (draw_point, "drawPoint", 1607 FIND_METHOD (draw_point, "drawPoint",
1584 "(Lorg/gnu/emacs/EmacsDrawable;" 1608 "(Lorg/gnu/emacs/EmacsDrawable;"
1585 "Lorg/gnu/emacs/EmacsGC;II)V"); 1609 "Lorg/gnu/emacs/EmacsGC;II)V");
1586 FIND_METHOD (clear_window, "clearWindow",
1587 "(Lorg/gnu/emacs/EmacsWindow;)V");
1588 FIND_METHOD (clear_area, "clearArea",
1589 "(Lorg/gnu/emacs/EmacsWindow;IIII)V");
1590 FIND_METHOD (ring_bell, "ringBell", "(I)V"); 1610 FIND_METHOD (ring_bell, "ringBell", "(I)V");
1591 FIND_METHOD (query_tree, "queryTree", 1611 FIND_METHOD (query_tree, "queryTree",
1592 "(Lorg/gnu/emacs/EmacsWindow;)[S"); 1612 "(Lorg/gnu/emacs/EmacsWindow;)[S");
1593 FIND_METHOD (get_screen_width, "getScreenWidth", "(Z)I"); 1613 FIND_METHOD (get_screen_width, "getScreenWidth", "(Z)I");
1594 FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I"); 1614 FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I");
1595 FIND_METHOD (detect_mouse, "detectMouse", "()Z"); 1615 FIND_METHOD (detect_mouse, "detectMouse", "()Z");
1616 FIND_METHOD (detect_keyboard, "detectKeyboard", "()Z");
1596 FIND_METHOD (name_keysym, "nameKeysym", "(I)Ljava/lang/String;"); 1617 FIND_METHOD (name_keysym, "nameKeysym", "(I)Ljava/lang/String;");
1597 FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;Z)" 1618 FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;Z)"
1598 "Ljava/lang/String;"); 1619 "Ljava/lang/String;");
@@ -1809,6 +1830,8 @@ android_init_emacs_window (void)
1809 android_damage_window. */ 1830 android_damage_window. */
1810 FIND_METHOD (damage_rect, "damageRect", "(IIII)V"); 1831 FIND_METHOD (damage_rect, "damageRect", "(IIII)V");
1811 FIND_METHOD (recreate_activity, "recreateActivity", "()V"); 1832 FIND_METHOD (recreate_activity, "recreateActivity", "()V");
1833 FIND_METHOD (clear_window, "clearWindow", "()V");
1834 FIND_METHOD (clear_area, "clearArea", "(IIII)V");
1812#undef FIND_METHOD 1835#undef FIND_METHOD
1813} 1836}
1814 1837
@@ -2496,6 +2519,8 @@ JNIEXPORT jboolean JNICALL
2496NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env, 2519NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env,
2497 jobject object) 2520 jobject object)
2498{ 2521{
2522 JNI_STACK_ALIGNMENT_PROLOGUE;
2523
2499 /* Yes, android_pass_multimedia_buttons_to_system is being 2524 /* Yes, android_pass_multimedia_buttons_to_system is being
2500 read from the UI thread. */ 2525 read from the UI thread. */
2501 return !android_pass_multimedia_buttons_to_system; 2526 return !android_pass_multimedia_buttons_to_system;
@@ -2504,6 +2529,8 @@ NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env,
2504JNIEXPORT jboolean JNICALL 2529JNIEXPORT jboolean JNICALL
2505NATIVE_NAME (shouldForwardCtrlSpace) (JNIEnv *env, jobject object) 2530NATIVE_NAME (shouldForwardCtrlSpace) (JNIEnv *env, jobject object)
2506{ 2531{
2532 JNI_STACK_ALIGNMENT_PROLOGUE;
2533
2507 return !android_intercept_control_space; 2534 return !android_intercept_control_space;
2508} 2535}
2509 2536
@@ -2607,6 +2634,8 @@ JNIEXPORT void JNICALL
2607NATIVE_NAME (notifyPixelsChanged) (JNIEnv *env, jobject object, 2634NATIVE_NAME (notifyPixelsChanged) (JNIEnv *env, jobject object,
2608 jobject bitmap) 2635 jobject bitmap)
2609{ 2636{
2637 JNI_STACK_ALIGNMENT_PROLOGUE;
2638
2610 void *data; 2639 void *data;
2611 2640
2612 /* Lock and unlock the bitmap. This calls 2641 /* Lock and unlock the bitmap. This calls
@@ -2660,6 +2689,8 @@ NATIVE_NAME (answerQuerySpin) (JNIEnv *env, jobject object)
2660JNIEXPORT void JNICALL 2689JNIEXPORT void JNICALL
2661NATIVE_NAME (setupSystemThread) (void) 2690NATIVE_NAME (setupSystemThread) (void)
2662{ 2691{
2692 JNI_STACK_ALIGNMENT_PROLOGUE;
2693
2663 sigset_t sigset; 2694 sigset_t sigset;
2664 2695
2665 /* Block everything except for SIGSEGV and SIGBUS; those two are 2696 /* Block everything except for SIGSEGV and SIGBUS; those two are
@@ -3408,10 +3439,9 @@ android_clear_window (android_window handle)
3408 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 3439 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
3409 3440
3410 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3441 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
3411 emacs_service, 3442 window,
3412 service_class.class, 3443 window_class.class,
3413 service_class.clear_window, 3444 window_class.clear_window);
3414 window);
3415 android_exception_check (); 3445 android_exception_check ();
3416} 3446}
3417 3447
@@ -4722,10 +4752,10 @@ android_clear_area (android_window handle, int x, int y,
4722 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 4752 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW);
4723 4753
4724 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4754 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
4725 emacs_service, 4755 window,
4726 service_class.class, 4756 window_class.class,
4727 service_class.clear_area, 4757 window_class.clear_area,
4728 window, (jint) x, (jint) y, 4758 (jint) x, (jint) y,
4729 (jint) width, (jint) height); 4759 (jint) width, (jint) height);
4730} 4760}
4731 4761
@@ -5626,6 +5656,21 @@ android_detect_mouse (void)
5626 return rc; 5656 return rc;
5627} 5657}
5628 5658
5659bool
5660android_detect_keyboard (void)
5661{
5662 bool rc;
5663 jmethodID method;
5664
5665 method = service_class.detect_keyboard;
5666 rc = (*android_java_env)->CallNonvirtualBooleanMethod (android_java_env,
5667 emacs_service,
5668 service_class.class,
5669 method);
5670 android_exception_check ();
5671 return rc;
5672}
5673
5629void 5674void
5630android_set_dont_focus_on_map (android_window handle, 5675android_set_dont_focus_on_map (android_window handle,
5631 bool no_focus_on_map) 5676 bool no_focus_on_map)
@@ -6701,7 +6746,7 @@ static void *android_query_context;
6701/* Run any function that the UI thread has asked to run, and then 6746/* Run any function that the UI thread has asked to run, and then
6702 signal its completion. */ 6747 signal its completion. */
6703 6748
6704static void 6749void
6705android_check_query (void) 6750android_check_query (void)
6706{ 6751{
6707 void (*proc) (void *); 6752 void (*proc) (void *);