aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c295
1 files changed, 270 insertions, 25 deletions
diff --git a/src/android.c b/src/android.c
index 479eb9b10d4..8f446224dab 100644
--- a/src/android.c
+++ b/src/android.c
@@ -98,6 +98,8 @@ struct android_emacs_service
98 jmethodID sync; 98 jmethodID sync;
99 jmethodID browse_url; 99 jmethodID browse_url;
100 jmethodID restart_emacs; 100 jmethodID restart_emacs;
101 jmethodID update_ic;
102 jmethodID reset_ic;
101}; 103};
102 104
103struct android_emacs_pixmap 105struct android_emacs_pixmap
@@ -207,7 +209,7 @@ static struct android_emacs_window window_class;
207 209
208/* The last event serial used. This is a 32 bit value, but it is 210/* The last event serial used. This is a 32 bit value, but it is
209 stored in unsigned long to be consistent with X. */ 211 stored in unsigned long to be consistent with X. */
210static unsigned int event_serial; 212unsigned int event_serial;
211 213
212/* Unused pointer used to control compiler optimizations. */ 214/* Unused pointer used to control compiler optimizations. */
213void *unused_pointer; 215void *unused_pointer;
@@ -408,6 +410,10 @@ android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg)
408 410
409#endif 411#endif
410 412
413/* Semaphore used to indicate completion of a query.
414 This should ideally be defined further down. */
415static sem_t android_query_sem;
416
411/* Set up the global event queue by initializing the mutex and two 417/* Set up the global event queue by initializing the mutex and two
412 condition variables, and the linked list of events. This must be 418 condition variables, and the linked list of events. This must be
413 called before starting the Emacs thread. Also, initialize the 419 called before starting the Emacs thread. Also, initialize the
@@ -438,6 +444,7 @@ android_init_events (void)
438 444
439 sem_init (&android_pselect_sem, 0, 0); 445 sem_init (&android_pselect_sem, 0, 0);
440 sem_init (&android_pselect_start_sem, 0, 0); 446 sem_init (&android_pselect_start_sem, 0, 0);
447 sem_init (&android_query_sem, 0, 0);
441 448
442 event_queue.events.next = &event_queue.events; 449 event_queue.events.next = &event_queue.events;
443 event_queue.events.last = &event_queue.events; 450 event_queue.events.last = &event_queue.events;
@@ -538,7 +545,7 @@ android_next_event (union android_event *event_return)
538 pthread_mutex_unlock (&event_queue.mutex); 545 pthread_mutex_unlock (&event_queue.mutex);
539} 546}
540 547
541static void 548void
542android_write_event (union android_event *event) 549android_write_event (union android_event *event)
543{ 550{
544 struct android_event_container *container; 551 struct android_event_container *container;
@@ -576,6 +583,10 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
576 static char byte; 583 static char byte;
577#endif 584#endif
578 585
586 /* Check for and run anything the UI thread wants to run on the main
587 thread. */
588 android_check_query ();
589
579 pthread_mutex_lock (&event_queue.mutex); 590 pthread_mutex_lock (&event_queue.mutex);
580 591
581 if (event_queue.num_events) 592 if (event_queue.num_events)
@@ -634,6 +645,10 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
634 if (nfds_return < 0) 645 if (nfds_return < 0)
635 errno = EINTR; 646 errno = EINTR;
636 647
648 /* Now check for and run anything the UI thread wants to run in the
649 main thread. */
650 android_check_query ();
651
637 return nfds_return; 652 return nfds_return;
638} 653}
639 654
@@ -1431,7 +1446,7 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
1431 1446
1432 /* This may be called from multiple threads. setEmacsParams should 1447 /* This may be called from multiple threads. setEmacsParams should
1433 only ever be called once. */ 1448 only ever be called once. */
1434 if (__atomic_fetch_add (&emacs_initialized, -1, __ATOMIC_RELAXED)) 1449 if (__atomic_fetch_add (&emacs_initialized, -1, __ATOMIC_SEQ_CST))
1435 { 1450 {
1436 ANDROID_THROW (env, "java/lang/IllegalArgumentException", 1451 ANDROID_THROW (env, "java/lang/IllegalArgumentException",
1437 "Emacs was already initialized!"); 1452 "Emacs was already initialized!");
@@ -1705,6 +1720,10 @@ android_init_emacs_service (void)
1705 FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;)" 1720 FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;)"
1706 "Ljava/lang/String;"); 1721 "Ljava/lang/String;");
1707 FIND_METHOD (restart_emacs, "restartEmacs", "()V"); 1722 FIND_METHOD (restart_emacs, "restartEmacs", "()V");
1723 FIND_METHOD (update_ic, "updateIC",
1724 "(Lorg/gnu/emacs/EmacsWindow;IIII)V");
1725 FIND_METHOD (reset_ic, "resetIC",
1726 "(Lorg/gnu/emacs/EmacsWindow;I)V");
1708#undef FIND_METHOD 1727#undef FIND_METHOD
1709} 1728}
1710 1729
@@ -1834,7 +1853,7 @@ android_init_emacs_window (void)
1834#undef FIND_METHOD 1853#undef FIND_METHOD
1835} 1854}
1836 1855
1837extern JNIEXPORT void JNICALL 1856JNIEXPORT void JNICALL
1838NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv, 1857NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv,
1839 jobject dump_file_object, jint api_level) 1858 jobject dump_file_object, jint api_level)
1840{ 1859{
@@ -1928,19 +1947,19 @@ NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv,
1928 emacs_abort (); 1947 emacs_abort ();
1929} 1948}
1930 1949
1931extern JNIEXPORT void JNICALL 1950JNIEXPORT void JNICALL
1932NATIVE_NAME (emacsAbort) (JNIEnv *env, jobject object) 1951NATIVE_NAME (emacsAbort) (JNIEnv *env, jobject object)
1933{ 1952{
1934 emacs_abort (); 1953 emacs_abort ();
1935} 1954}
1936 1955
1937extern JNIEXPORT void JNICALL 1956JNIEXPORT void JNICALL
1938NATIVE_NAME (quit) (JNIEnv *env, jobject object) 1957NATIVE_NAME (quit) (JNIEnv *env, jobject object)
1939{ 1958{
1940 Vquit_flag = Qt; 1959 Vquit_flag = Qt;
1941} 1960}
1942 1961
1943extern JNIEXPORT jlong JNICALL 1962JNIEXPORT jlong JNICALL
1944NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object, 1963NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
1945 jshort window, jlong time, 1964 jshort window, jlong time,
1946 jint x, jint y, jint width, 1965 jint x, jint y, jint width,
@@ -1961,7 +1980,7 @@ NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
1961 return event_serial; 1980 return event_serial;
1962} 1981}
1963 1982
1964extern JNIEXPORT jlong JNICALL 1983JNIEXPORT jlong JNICALL
1965NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object, 1984NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
1966 jshort window, jlong time, 1985 jshort window, jlong time,
1967 jint state, jint keycode, 1986 jint state, jint keycode,
@@ -1981,7 +2000,7 @@ NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
1981 return event_serial; 2000 return event_serial;
1982} 2001}
1983 2002
1984extern JNIEXPORT jlong JNICALL 2003JNIEXPORT jlong JNICALL
1985NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object, 2004NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
1986 jshort window, jlong time, 2005 jshort window, jlong time,
1987 jint state, jint keycode, 2006 jint state, jint keycode,
@@ -2001,7 +2020,7 @@ NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
2001 return event_serial; 2020 return event_serial;
2002} 2021}
2003 2022
2004extern JNIEXPORT jlong JNICALL 2023JNIEXPORT jlong JNICALL
2005NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object, 2024NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object,
2006 jshort window, jlong time) 2025 jshort window, jlong time)
2007{ 2026{
@@ -2016,7 +2035,7 @@ NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object,
2016 return event_serial; 2035 return event_serial;
2017} 2036}
2018 2037
2019extern JNIEXPORT jlong JNICALL 2038JNIEXPORT jlong JNICALL
2020NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object, 2039NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object,
2021 jshort window, jlong time) 2040 jshort window, jlong time)
2022{ 2041{
@@ -2031,7 +2050,7 @@ NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object,
2031 return ++event_serial; 2050 return ++event_serial;
2032} 2051}
2033 2052
2034extern JNIEXPORT jlong JNICALL 2053JNIEXPORT jlong JNICALL
2035NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object, 2054NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
2036 jshort window, jint action) 2055 jshort window, jint action)
2037{ 2056{
@@ -2046,7 +2065,7 @@ NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
2046 return event_serial; 2065 return event_serial;
2047} 2066}
2048 2067
2049extern JNIEXPORT jlong JNICALL 2068JNIEXPORT jlong JNICALL
2050NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object, 2069NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
2051 jshort window, jint x, jint y, 2070 jshort window, jint x, jint y,
2052 jlong time) 2071 jlong time)
@@ -2064,7 +2083,7 @@ NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
2064 return event_serial; 2083 return event_serial;
2065} 2084}
2066 2085
2067extern JNIEXPORT jlong JNICALL 2086JNIEXPORT jlong JNICALL
2068NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object, 2087NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
2069 jshort window, jint x, jint y, 2088 jshort window, jint x, jint y,
2070 jlong time) 2089 jlong time)
@@ -2082,7 +2101,7 @@ NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
2082 return event_serial; 2101 return event_serial;
2083} 2102}
2084 2103
2085extern JNIEXPORT jlong JNICALL 2104JNIEXPORT jlong JNICALL
2086NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object, 2105NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
2087 jshort window, jint x, jint y, 2106 jshort window, jint x, jint y,
2088 jlong time) 2107 jlong time)
@@ -2100,7 +2119,7 @@ NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
2100 return event_serial; 2119 return event_serial;
2101} 2120}
2102 2121
2103extern JNIEXPORT jlong JNICALL 2122JNIEXPORT jlong JNICALL
2104NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object, 2123NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
2105 jshort window, jint x, jint y, 2124 jshort window, jint x, jint y,
2106 jlong time, jint state, 2125 jlong time, jint state,
@@ -2121,7 +2140,7 @@ NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
2121 return event_serial; 2140 return event_serial;
2122} 2141}
2123 2142
2124extern JNIEXPORT jlong JNICALL 2143JNIEXPORT jlong JNICALL
2125NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object, 2144NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
2126 jshort window, jint x, jint y, 2145 jshort window, jint x, jint y,
2127 jlong time, jint state, 2146 jlong time, jint state,
@@ -2142,7 +2161,7 @@ NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
2142 return event_serial; 2161 return event_serial;
2143} 2162}
2144 2163
2145extern JNIEXPORT jlong JNICALL 2164JNIEXPORT jlong JNICALL
2146NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object, 2165NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
2147 jshort window, jint x, jint y, 2166 jshort window, jint x, jint y,
2148 jlong time, jint pointer_id) 2167 jlong time, jint pointer_id)
@@ -2161,7 +2180,7 @@ NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
2161 return event_serial; 2180 return event_serial;
2162} 2181}
2163 2182
2164extern JNIEXPORT jlong JNICALL 2183JNIEXPORT jlong JNICALL
2165NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object, 2184NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
2166 jshort window, jint x, jint y, 2185 jshort window, jint x, jint y,
2167 jlong time, jint pointer_id) 2186 jlong time, jint pointer_id)
@@ -2180,7 +2199,7 @@ NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
2180 return event_serial; 2199 return event_serial;
2181} 2200}
2182 2201
2183extern JNIEXPORT jlong JNICALL 2202JNIEXPORT jlong JNICALL
2184NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object, 2203NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
2185 jshort window, jint x, jint y, 2204 jshort window, jint x, jint y,
2186 jlong time, jint pointer_id) 2205 jlong time, jint pointer_id)
@@ -2199,7 +2218,7 @@ NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
2199 return event_serial; 2218 return event_serial;
2200} 2219}
2201 2220
2202extern JNIEXPORT jlong JNICALL 2221JNIEXPORT jlong JNICALL
2203NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object, 2222NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object,
2204 jshort window, jint x, jint y, 2223 jshort window, jint x, jint y,
2205 jlong time, jint state, 2224 jlong time, jint state,
@@ -2221,7 +2240,7 @@ NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object,
2221 return event_serial; 2240 return event_serial;
2222} 2241}
2223 2242
2224extern JNIEXPORT jlong JNICALL 2243JNIEXPORT jlong JNICALL
2225NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object, 2244NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object,
2226 jshort window) 2245 jshort window)
2227{ 2246{
@@ -2235,7 +2254,7 @@ NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object,
2235 return event_serial; 2254 return event_serial;
2236} 2255}
2237 2256
2238extern JNIEXPORT jlong JNICALL 2257JNIEXPORT jlong JNICALL
2239NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object, 2258NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object,
2240 jshort window) 2259 jshort window)
2241{ 2260{
@@ -2249,7 +2268,7 @@ NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object,
2249 return event_serial; 2268 return event_serial;
2250} 2269}
2251 2270
2252extern JNIEXPORT jlong JNICALL 2271JNIEXPORT jlong JNICALL
2253NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object, 2272NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object,
2254 jshort window, jint menu_event_id) 2273 jshort window, jint menu_event_id)
2255{ 2274{
@@ -2264,7 +2283,7 @@ NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object,
2264 return event_serial; 2283 return event_serial;
2265} 2284}
2266 2285
2267extern JNIEXPORT jlong JNICALL 2286JNIEXPORT jlong JNICALL
2268NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object, 2287NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object,
2269 jshort window, jint x, jint y, 2288 jshort window, jint x, jint y,
2270 jint width, jint height) 2289 jint width, jint height)
@@ -2283,6 +2302,23 @@ NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object,
2283 return event_serial; 2302 return event_serial;
2284} 2303}
2285 2304
2305/* Forward declarations of deadlock prevention functions. */
2306
2307static void android_begin_query (void);
2308static void android_end_query (void);
2309
2310JNIEXPORT void JNICALL
2311NATIVE_NAME (beginSynchronous) (JNIEnv *env, jobject object)
2312{
2313 android_begin_query ();
2314}
2315
2316JNIEXPORT void JNICALL
2317NATIVE_NAME (endSynchronous) (JNIEnv *env, jobject object)
2318{
2319 android_end_query ();
2320}
2321
2286#ifdef __clang__ 2322#ifdef __clang__
2287#pragma clang diagnostic pop 2323#pragma clang diagnostic pop
2288#else 2324#else
@@ -5155,6 +5191,215 @@ android_get_current_api_level (void)
5155 5191
5156 5192
5157 5193
5194/* Whether or not a query is currently being made. */
5195static bool android_servicing_query;
5196
5197/* Function that is waiting to be run in the Emacs thread. */
5198static void (*android_query_function) (void *);
5199
5200/* Context for that function. */
5201static void *android_query_context;
5202
5203/* Deadlock protection. The UI thread and the Emacs thread must
5204 sometimes make synchronous queries to each other, which are
5205 normally answered inside each thread's respective event loop.
5206 Deadlocks can happen when both threads simultaneously make such
5207 synchronous queries and block waiting for each others responses.
5208
5209 The Emacs thread can be interrupted to service any queries made by
5210 the UI thread, but is not possible the other way around.
5211
5212 To avoid such deadlocks, an atomic counter is provided. This
5213 counter is incremented every time a query starts, and is set to
5214 zerp every time one ends. If the UI thread tries to make a query
5215 and sees that the counter is non-zero, it simply returns so that
5216 its event loop can proceed to perform and respond to the query. If
5217 the Emacs thread sees the same thing, then it stops to service all
5218 queries being made by the input method, then proceeds to make its
5219 query. */
5220
5221/* Run any function that the UI thread has asked to run, and then
5222 signal its completion. */
5223
5224void
5225android_check_query (void)
5226{
5227 void (*proc) (void *);
5228 void *closure;
5229
5230 if (!__atomic_load_n (&android_servicing_query, __ATOMIC_SEQ_CST))
5231 return;
5232
5233 /* First, load the procedure and closure. */
5234 __atomic_load (&android_query_context, &closure, __ATOMIC_SEQ_CST);
5235 __atomic_load (&android_query_function, &proc, __ATOMIC_SEQ_CST);
5236
5237 if (!proc)
5238 return;
5239
5240 proc (closure);
5241
5242 /* Finish the query. */
5243 __atomic_store_n (&android_query_context, NULL, __ATOMIC_SEQ_CST);
5244 __atomic_store_n (&android_query_function, NULL, __ATOMIC_SEQ_CST);
5245 __atomic_clear (&android_servicing_query, __ATOMIC_SEQ_CST);
5246
5247 /* Signal completion. */
5248 sem_post (&android_query_sem);
5249}
5250
5251/* Notice that the Emacs thread will start blocking waiting for a
5252 response from the UI thread. Process any pending queries from the
5253 UI thread.
5254
5255 This function may be called from Java. */
5256
5257static void
5258android_begin_query (void)
5259{
5260 if (__atomic_test_and_set (&android_servicing_query,
5261 __ATOMIC_SEQ_CST))
5262 {
5263 /* Answer the query that is currently being made. */
5264 assert (android_query_function != NULL);
5265 android_check_query ();
5266
5267 /* Wait for that query to complete. */
5268 while (__atomic_load_n (&android_servicing_query,
5269 __ATOMIC_SEQ_CST))
5270 ;;
5271 }
5272}
5273
5274/* Notice that a query has stopped. This function may be called from
5275 Java. */
5276
5277static void
5278android_end_query (void)
5279{
5280 __atomic_clear (&android_servicing_query, __ATOMIC_SEQ_CST);
5281}
5282
5283/* Synchronously ask the Emacs thread to run the specified PROC with
5284 the given CLOSURE. Return if this fails, or once PROC is run.
5285
5286 PROC may be run from inside maybe_quit.
5287
5288 It is not okay to run Lisp code which signals or performs non
5289 trivial tasks inside PROC.
5290
5291 Return 1 if the Emacs thread is currently waiting for the UI thread
5292 to respond and PROC could not be run, or 0 otherwise. */
5293
5294int
5295android_run_in_emacs_thread (void (*proc) (void *), void *closure)
5296{
5297 union android_event event;
5298
5299 event.xaction.type = ANDROID_WINDOW_ACTION;
5300 event.xaction.serial = ++event_serial;
5301 event.xaction.window = 0;
5302 event.xaction.action = 0;
5303
5304 /* Set android_query_function and android_query_context. */
5305 __atomic_store_n (&android_query_context, closure, __ATOMIC_SEQ_CST);
5306 __atomic_store_n (&android_query_function, proc, __ATOMIC_SEQ_CST);
5307
5308 /* Don't allow deadlocks to happen; make sure the Emacs thread is
5309 not waiting for something to be done. */
5310
5311 if (__atomic_test_and_set (&android_servicing_query,
5312 __ATOMIC_SEQ_CST))
5313 {
5314 __atomic_store_n (&android_query_context, NULL,
5315 __ATOMIC_SEQ_CST);
5316 __atomic_store_n (&android_query_function, NULL,
5317 __ATOMIC_SEQ_CST);
5318
5319 return 1;
5320 }
5321
5322 /* Send a dummy event. `android_check_query' will be called inside
5323 wait_reading_process_output after the event arrives.
5324
5325 Otherwise, android_select will call android_check_thread the next
5326 time it is entered. */
5327 android_write_event (&event);
5328
5329 /* Start waiting for the function to be executed. */
5330 while (sem_wait (&android_query_sem) < 0)
5331 ;;
5332
5333 return 0;
5334}
5335
5336
5337
5338/* Input method related functions. */
5339
5340/* Change WINDOW's active selection to the characters between
5341 SELECTION_START and SELECTION_END.
5342
5343 Also, update the composing region to COMPOSING_REGION_START and
5344 COMPOSING_REGION_END.
5345
5346 If any value cannot fit in jint, then the behavior of the input
5347 method is undefined. */
5348
5349void
5350android_update_ic (android_window window, ptrdiff_t selection_start,
5351 ptrdiff_t selection_end, ptrdiff_t composing_region_start,
5352 ptrdiff_t composing_region_end)
5353{
5354 jobject object;
5355
5356 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
5357
5358 (*android_java_env)->CallVoidMethod (android_java_env,
5359 emacs_service,
5360 service_class.update_ic,
5361 object,
5362 (jint) selection_start,
5363 (jint) selection_end,
5364 (jint) composing_region_start,
5365 (jint) composing_region_end);
5366 android_exception_check ();
5367}
5368
5369/* Reinitialize any ongoing input method connection on WINDOW.
5370
5371 Any input method that is connected to WINDOW will invalidate its
5372 cache of the buffer contents.
5373
5374 MODE controls certain aspects of the input method's behavior:
5375
5376 - If MODE is ANDROID_IC_MODE_NULL, the input method will be
5377 deactivated, and an ASCII only keyboard will be displayed
5378 instead.
5379
5380 - If MODE is ANDROID_IC_MODE_ACTION, the input method will
5381 edit text normally, but send ``return'' as a key event.
5382 This is useful inside the mini buffer.
5383
5384 - If MODE is ANDROID_IC_MODE_TEXT, the input method is free
5385 to behave however it wants. */
5386
5387void
5388android_reset_ic (android_window window, enum android_ic_mode mode)
5389{
5390 jobject object;
5391
5392 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
5393
5394 (*android_java_env)->CallVoidMethod (android_java_env,
5395 emacs_service,
5396 service_class.reset_ic,
5397 object, (jint) mode);
5398 android_exception_check ();
5399}
5400
5401
5402
5158#else /* ANDROID_STUBIFY */ 5403#else /* ANDROID_STUBIFY */
5159 5404
5160/* X emulation functions for Android. */ 5405/* X emulation functions for Android. */