aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c618
1 files changed, 208 insertions, 410 deletions
diff --git a/src/android.c b/src/android.c
index c76afdb9bf2..0dd7702b301 100644
--- a/src/android.c
+++ b/src/android.c
@@ -129,6 +129,13 @@ struct android_key_character_map
129 jmethodID get_dead_char; 129 jmethodID get_dead_char;
130}; 130};
131 131
132struct android_emacs_handle
133{
134 jclass class;
135 jmethodID destroy_handle;
136 jfieldID handle;
137};
138
132/* The API level of the current device. */ 139/* The API level of the current device. */
133static int android_api_level; 140static int android_api_level;
134 141
@@ -214,6 +221,10 @@ static struct android_emacs_cursor cursor_class;
214/* Various methods associated with the KeyCharacterMap class. */ 221/* Various methods associated with the KeyCharacterMap class. */
215static struct android_key_character_map key_character_map_class; 222static struct android_key_character_map key_character_map_class;
216 223
224/* Various methods and fields associated with the EmacsHandleObject
225 class. */
226static struct android_emacs_handle handle_class;
227
217/* The time at which Emacs was installed, which also supplies the 228/* The time at which Emacs was installed, which also supplies the
218 mtime of asset files. */ 229 mtime of asset files. */
219struct timespec emacs_installation_time; 230struct timespec emacs_installation_time;
@@ -1620,7 +1631,7 @@ android_init_emacs_service (void)
1620 "Lorg/gnu/emacs/EmacsGC;II)V"); 1631 "Lorg/gnu/emacs/EmacsGC;II)V");
1621 FIND_METHOD (ring_bell, "ringBell", "(I)V"); 1632 FIND_METHOD (ring_bell, "ringBell", "(I)V");
1622 FIND_METHOD (query_tree, "queryTree", 1633 FIND_METHOD (query_tree, "queryTree",
1623 "(Lorg/gnu/emacs/EmacsWindow;)[S"); 1634 "(Lorg/gnu/emacs/EmacsWindow;)[J");
1624 FIND_METHOD (get_screen_width, "getScreenWidth", "(Z)I"); 1635 FIND_METHOD (get_screen_width, "getScreenWidth", "(Z)I");
1625 FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I"); 1636 FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I");
1626 FIND_METHOD (detect_mouse, "detectMouse", "()Z"); 1637 FIND_METHOD (detect_mouse, "detectMouse", "()Z");
@@ -1723,7 +1734,7 @@ android_init_emacs_pixmap (void)
1723 name, signature); \ 1734 name, signature); \
1724 eassert (pixmap_class.c_name); 1735 eassert (pixmap_class.c_name);
1725 1736
1726 FIND_METHOD (constructor_mutable, "<init>", "(SIII)V"); 1737 FIND_METHOD (constructor_mutable, "<init>", "(III)V");
1727 1738
1728#undef FIND_METHOD 1739#undef FIND_METHOD
1729} 1740}
@@ -1876,7 +1887,7 @@ android_init_emacs_cursor (void)
1876 name, signature); \ 1887 name, signature); \
1877 eassert (cursor_class.c_name); 1888 eassert (cursor_class.c_name);
1878 1889
1879 FIND_METHOD (constructor, "<init>", "(SI)V"); 1890 FIND_METHOD (constructor, "<init>", "(I)V");
1880#undef FIND_METHOD 1891#undef FIND_METHOD
1881} 1892}
1882 1893
@@ -1906,6 +1917,42 @@ android_init_key_character_map (void)
1906 eassert (key_character_map_class.get_dead_char); 1917 eassert (key_character_map_class.get_dead_char);
1907} 1918}
1908 1919
1920static void
1921android_init_emacs_handle (void)
1922{
1923 jclass old;
1924
1925 handle_class.class
1926 = (*android_java_env)->FindClass (android_java_env,
1927 "org/gnu/emacs/EmacsHandleObject");
1928 eassert (handle_class.class);
1929
1930 old = handle_class.class;
1931 handle_class.class
1932 = (jclass) (*android_java_env)->NewGlobalRef (android_java_env,
1933 (jobject) old);
1934 ANDROID_DELETE_LOCAL_REF (old);
1935
1936 if (!handle_class.class)
1937 emacs_abort ();
1938
1939#define FIND_METHOD(c_name, name, signature) \
1940 handle_class.c_name \
1941 = (*android_java_env)->GetMethodID (android_java_env, \
1942 handle_class.class, \
1943 name, signature); \
1944 eassert (handle_class.c_name);
1945
1946 FIND_METHOD (destroy_handle, "destroyHandle", "()V");
1947#undef FIND_METHOD
1948
1949 handle_class.handle
1950 = (*android_java_env)->GetFieldID (android_java_env,
1951 handle_class.class,
1952 "handle", "J");
1953 eassert (handle_class.handle);
1954}
1955
1909JNIEXPORT void JNICALL 1956JNIEXPORT void JNICALL
1910NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv, 1957NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv,
1911 jobject dump_file_object) 1958 jobject dump_file_object)
@@ -1955,6 +2002,7 @@ NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv,
1955 android_init_emacs_window (); 2002 android_init_emacs_window ();
1956 android_init_emacs_cursor (); 2003 android_init_emacs_cursor ();
1957 android_init_key_character_map (); 2004 android_init_key_character_map ();
2005 android_init_emacs_handle ();
1958 2006
1959 /* Set HOME to the app data directory. */ 2007 /* Set HOME to the app data directory. */
1960 setenv ("HOME", android_files_dir, 1); 2008 setenv ("HOME", android_files_dir, 1);
@@ -2074,7 +2122,7 @@ NATIVE_NAME (onLowMemory) (JNIEnv *env, jobject object)
2074 2122
2075JNIEXPORT jlong JNICALL 2123JNIEXPORT jlong JNICALL
2076NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object, 2124NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
2077 jshort window, jlong time, 2125 jlong window, jlong time,
2078 jint x, jint y, jint width, 2126 jint x, jint y, jint width,
2079 jint height) 2127 jint height)
2080{ 2128{
@@ -2097,7 +2145,7 @@ NATIVE_NAME (sendConfigureNotify) (JNIEnv *env, jobject object,
2097 2145
2098JNIEXPORT jlong JNICALL 2146JNIEXPORT jlong JNICALL
2099NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object, 2147NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
2100 jshort window, jlong time, 2148 jlong window, jlong time,
2101 jint state, jint keycode, 2149 jint state, jint keycode,
2102 jint unicode_char) 2150 jint unicode_char)
2103{ 2151{
@@ -2120,7 +2168,7 @@ NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
2120 2168
2121JNIEXPORT jlong JNICALL 2169JNIEXPORT jlong JNICALL
2122NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object, 2170NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
2123 jshort window, jlong time, 2171 jlong window, jlong time,
2124 jint state, jint keycode, 2172 jint state, jint keycode,
2125 jint unicode_char) 2173 jint unicode_char)
2126{ 2174{
@@ -2143,7 +2191,7 @@ NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
2143 2191
2144JNIEXPORT jlong JNICALL 2192JNIEXPORT jlong JNICALL
2145NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object, 2193NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object,
2146 jshort window, jlong time) 2194 jlong window, jlong time)
2147{ 2195{
2148 JNI_STACK_ALIGNMENT_PROLOGUE; 2196 JNI_STACK_ALIGNMENT_PROLOGUE;
2149 2197
@@ -2160,7 +2208,7 @@ NATIVE_NAME (sendFocusIn) (JNIEnv *env, jobject object,
2160 2208
2161JNIEXPORT jlong JNICALL 2209JNIEXPORT jlong JNICALL
2162NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object, 2210NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object,
2163 jshort window, jlong time) 2211 jlong window, jlong time)
2164{ 2212{
2165 JNI_STACK_ALIGNMENT_PROLOGUE; 2213 JNI_STACK_ALIGNMENT_PROLOGUE;
2166 2214
@@ -2177,7 +2225,7 @@ NATIVE_NAME (sendFocusOut) (JNIEnv *env, jobject object,
2177 2225
2178JNIEXPORT jlong JNICALL 2226JNIEXPORT jlong JNICALL
2179NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object, 2227NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
2180 jshort window, jint action) 2228 jlong window, jint action)
2181{ 2229{
2182 JNI_STACK_ALIGNMENT_PROLOGUE; 2230 JNI_STACK_ALIGNMENT_PROLOGUE;
2183 2231
@@ -2194,7 +2242,7 @@ NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
2194 2242
2195JNIEXPORT jlong JNICALL 2243JNIEXPORT jlong JNICALL
2196NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object, 2244NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
2197 jshort window, jint x, jint y, 2245 jlong window, jint x, jint y,
2198 jlong time) 2246 jlong time)
2199{ 2247{
2200 JNI_STACK_ALIGNMENT_PROLOGUE; 2248 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2214,7 +2262,7 @@ NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
2214 2262
2215JNIEXPORT jlong JNICALL 2263JNIEXPORT jlong JNICALL
2216NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object, 2264NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
2217 jshort window, jint x, jint y, 2265 jlong window, jint x, jint y,
2218 jlong time) 2266 jlong time)
2219{ 2267{
2220 JNI_STACK_ALIGNMENT_PROLOGUE; 2268 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2234,7 +2282,7 @@ NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
2234 2282
2235JNIEXPORT jlong JNICALL 2283JNIEXPORT jlong JNICALL
2236NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object, 2284NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
2237 jshort window, jint x, jint y, 2285 jlong window, jint x, jint y,
2238 jlong time) 2286 jlong time)
2239{ 2287{
2240 JNI_STACK_ALIGNMENT_PROLOGUE; 2288 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2254,7 +2302,7 @@ NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
2254 2302
2255JNIEXPORT jlong JNICALL 2303JNIEXPORT jlong JNICALL
2256NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object, 2304NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
2257 jshort window, jint x, jint y, 2305 jlong window, jint x, jint y,
2258 jlong time, jint state, 2306 jlong time, jint state,
2259 jint button) 2307 jint button)
2260{ 2308{
@@ -2277,7 +2325,7 @@ NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
2277 2325
2278JNIEXPORT jlong JNICALL 2326JNIEXPORT jlong JNICALL
2279NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object, 2327NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
2280 jshort window, jint x, jint y, 2328 jlong window, jint x, jint y,
2281 jlong time, jint state, 2329 jlong time, jint state,
2282 jint button) 2330 jint button)
2283{ 2331{
@@ -2300,7 +2348,7 @@ NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
2300 2348
2301JNIEXPORT jlong JNICALL 2349JNIEXPORT jlong JNICALL
2302NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object, 2350NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
2303 jshort window, jint x, jint y, 2351 jlong window, jint x, jint y,
2304 jlong time, jint pointer_id, 2352 jlong time, jint pointer_id,
2305 jint flags) 2353 jint flags)
2306{ 2354{
@@ -2323,7 +2371,7 @@ NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
2323 2371
2324JNIEXPORT jlong JNICALL 2372JNIEXPORT jlong JNICALL
2325NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object, 2373NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
2326 jshort window, jint x, jint y, 2374 jlong window, jint x, jint y,
2327 jlong time, jint pointer_id, 2375 jlong time, jint pointer_id,
2328 jint flags) 2376 jint flags)
2329{ 2377{
@@ -2346,7 +2394,7 @@ NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
2346 2394
2347JNIEXPORT jlong JNICALL 2395JNIEXPORT jlong JNICALL
2348NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object, 2396NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
2349 jshort window, jint x, jint y, 2397 jlong window, jint x, jint y,
2350 jlong time, jint pointer_id, 2398 jlong time, jint pointer_id,
2351 jint flags) 2399 jint flags)
2352{ 2400{
@@ -2369,7 +2417,7 @@ NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
2369 2417
2370JNIEXPORT jlong JNICALL 2418JNIEXPORT jlong JNICALL
2371NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object, 2419NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object,
2372 jshort window, jint x, jint y, 2420 jlong window, jint x, jint y,
2373 jlong time, jint state, 2421 jlong time, jint state,
2374 jfloat x_delta, jfloat y_delta) 2422 jfloat x_delta, jfloat y_delta)
2375{ 2423{
@@ -2393,7 +2441,7 @@ NATIVE_NAME (sendWheel) (JNIEnv *env, jobject object,
2393 2441
2394JNIEXPORT jlong JNICALL 2442JNIEXPORT jlong JNICALL
2395NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object, 2443NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object,
2396 jshort window) 2444 jlong window)
2397{ 2445{
2398 JNI_STACK_ALIGNMENT_PROLOGUE; 2446 JNI_STACK_ALIGNMENT_PROLOGUE;
2399 2447
@@ -2409,7 +2457,7 @@ NATIVE_NAME (sendIconified) (JNIEnv *env, jobject object,
2409 2457
2410JNIEXPORT jlong JNICALL 2458JNIEXPORT jlong JNICALL
2411NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object, 2459NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object,
2412 jshort window) 2460 jlong window)
2413{ 2461{
2414 JNI_STACK_ALIGNMENT_PROLOGUE; 2462 JNI_STACK_ALIGNMENT_PROLOGUE;
2415 2463
@@ -2425,7 +2473,7 @@ NATIVE_NAME (sendDeiconified) (JNIEnv *env, jobject object,
2425 2473
2426JNIEXPORT jlong JNICALL 2474JNIEXPORT jlong JNICALL
2427NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object, 2475NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object,
2428 jshort window, jint menu_event_id, 2476 jlong window, jint menu_event_id,
2429 jint menu_event_serial) 2477 jint menu_event_serial)
2430{ 2478{
2431 JNI_STACK_ALIGNMENT_PROLOGUE; 2479 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2444,7 +2492,7 @@ NATIVE_NAME (sendContextMenu) (JNIEnv *env, jobject object,
2444 2492
2445JNIEXPORT jlong JNICALL 2493JNIEXPORT jlong JNICALL
2446NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object, 2494NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object,
2447 jshort window, jint x, jint y, 2495 jlong window, jint x, jint y,
2448 jint width, jint height) 2496 jint width, jint height)
2449{ 2497{
2450 JNI_STACK_ALIGNMENT_PROLOGUE; 2498 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2465,7 +2513,7 @@ NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object,
2465 2513
2466JNIEXPORT jlong JNICALL 2514JNIEXPORT jlong JNICALL
2467NATIVE_NAME (sendDndDrag) (JNIEnv *env, jobject object, 2515NATIVE_NAME (sendDndDrag) (JNIEnv *env, jobject object,
2468 jshort window, jint x, jint y) 2516 jlong window, jint x, jint y)
2469{ 2517{
2470 JNI_STACK_ALIGNMENT_PROLOGUE; 2518 JNI_STACK_ALIGNMENT_PROLOGUE;
2471 2519
@@ -2485,7 +2533,7 @@ NATIVE_NAME (sendDndDrag) (JNIEnv *env, jobject object,
2485 2533
2486JNIEXPORT jlong JNICALL 2534JNIEXPORT jlong JNICALL
2487NATIVE_NAME (sendDndUri) (JNIEnv *env, jobject object, 2535NATIVE_NAME (sendDndUri) (JNIEnv *env, jobject object,
2488 jshort window, jint x, jint y, 2536 jlong window, jint x, jint y,
2489 jstring string) 2537 jstring string)
2490{ 2538{
2491 JNI_STACK_ALIGNMENT_PROLOGUE; 2539 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2522,7 +2570,7 @@ NATIVE_NAME (sendDndUri) (JNIEnv *env, jobject object,
2522 2570
2523JNIEXPORT jlong JNICALL 2571JNIEXPORT jlong JNICALL
2524NATIVE_NAME (sendDndText) (JNIEnv *env, jobject object, 2572NATIVE_NAME (sendDndText) (JNIEnv *env, jobject object,
2525 jshort window, jint x, jint y, 2573 jlong window, jint x, jint y,
2526 jstring string) 2574 jstring string)
2527{ 2575{
2528 JNI_STACK_ALIGNMENT_PROLOGUE; 2576 JNI_STACK_ALIGNMENT_PROLOGUE;
@@ -2711,7 +2759,6 @@ NATIVE_NAME (blitRect) (JNIEnv *env, jobject object,
2711 x2 = MAX (x2, 0); 2759 x2 = MAX (x2, 0);
2712 y2 = MAX (y2, 0); 2760 y2 = MAX (y2, 0);
2713 2761
2714
2715 if (x1 >= src_info.width 2762 if (x1 >= src_info.width
2716 || x1 >= dest_info.width) 2763 || x1 >= dest_info.width)
2717 x1 = MIN (dest_info.width - 1, src_info.width - 1); 2764 x1 = MIN (dest_info.width - 1, src_info.width - 1);
@@ -2854,62 +2901,6 @@ NATIVE_NAME (setupSystemThread) (void)
2854 This means that every local reference must be explicitly destroyed 2901 This means that every local reference must be explicitly destroyed
2855 with DeleteLocalRef. A helper macro is provided to do this. */ 2902 with DeleteLocalRef. A helper macro is provided to do this. */
2856 2903
2857struct android_handle_entry
2858{
2859 /* The type. */
2860 enum android_handle_type type;
2861
2862 /* The handle. */
2863 jobject handle;
2864};
2865
2866/* Table of handles MAX_HANDLE long. */
2867struct android_handle_entry android_handles[USHRT_MAX];
2868
2869/* The largest handle ID currently known, but subject to
2870 wraparound. */
2871static android_handle max_handle;
2872
2873/* Allocate a new, unused, handle identifier. If Emacs is out of
2874 identifiers, return 0. */
2875
2876static android_handle
2877android_alloc_id (void)
2878{
2879 android_handle handle;
2880
2881 /* 0 is never a valid handle ID. */
2882
2883 if (!max_handle)
2884 max_handle++;
2885
2886 /* See if the handle is already occupied. */
2887
2888 if (android_handles[max_handle].handle)
2889 {
2890 /* Look for a fresh unoccupied handle. */
2891
2892 handle = max_handle;
2893 max_handle++;
2894
2895 while (handle != max_handle)
2896 {
2897 ++max_handle;
2898
2899 /* Make sure the handle is valid. */
2900 if (!max_handle)
2901 ++max_handle;
2902
2903 if (!android_handles[max_handle].handle)
2904 return max_handle++;
2905 }
2906
2907 return ANDROID_NONE;
2908 }
2909
2910 return max_handle++;
2911}
2912
2913/* Destroy the specified handle and mark it as free on the Java side 2904/* Destroy the specified handle and mark it as free on the Java side
2914 as well. */ 2905 as well. */
2915 2906
@@ -2919,13 +2910,6 @@ android_destroy_handle (android_handle handle)
2919 static jclass old, class; 2910 static jclass old, class;
2920 static jmethodID method; 2911 static jmethodID method;
2921 2912
2922 if (!android_handles[handle].handle)
2923 {
2924 __android_log_print (ANDROID_LOG_ERROR, __func__,
2925 "Trying to destroy free handle!");
2926 emacs_abort ();
2927 }
2928
2929 if (!class) 2913 if (!class)
2930 { 2914 {
2931 class 2915 class
@@ -2946,8 +2930,7 @@ android_destroy_handle (android_handle handle)
2946 ANDROID_DELETE_LOCAL_REF (old); 2930 ANDROID_DELETE_LOCAL_REF (old);
2947 } 2931 }
2948 2932
2949 (*android_java_env)->CallVoidMethod (android_java_env, 2933 (*android_java_env)->CallVoidMethod (android_java_env, (jobject) handle,
2950 android_handles[handle].handle,
2951 method); 2934 method);
2952 2935
2953 /* Just clear any exception thrown. If destroying the handle 2936 /* Just clear any exception thrown. If destroying the handle
@@ -2956,76 +2939,7 @@ android_destroy_handle (android_handle handle)
2956 (*android_java_env)->ExceptionClear (android_java_env); 2939 (*android_java_env)->ExceptionClear (android_java_env);
2957 2940
2958 /* Delete the global reference regardless of any error. */ 2941 /* Delete the global reference regardless of any error. */
2959 (*android_java_env)->DeleteGlobalRef (android_java_env, 2942 (*android_java_env)->DeleteGlobalRef (android_java_env, (jobject) handle);
2960 android_handles[handle].handle);
2961 android_handles[handle].handle = NULL;
2962}
2963
2964jobject
2965android_resolve_handle (android_handle handle,
2966 enum android_handle_type type)
2967{
2968 if (!handle)
2969 /* ANDROID_NONE. */
2970 return NULL;
2971
2972 /* CheckJNI will normally ensure that the handle exists and is
2973 the right type, but with a less informative error message.
2974 Don't waste cycles doing our own checking here. */
2975
2976#ifdef ENABLE_CHECKING
2977
2978 if (!android_handles[handle].handle)
2979 {
2980 __android_log_print (ANDROID_LOG_ERROR, __func__,
2981 "Trying to resolve free handle!");
2982 emacs_abort ();
2983 }
2984
2985 if (android_handles[handle].type != type)
2986 {
2987 __android_log_print (ANDROID_LOG_ERROR, __func__,
2988 "Handle has wrong type!");
2989 emacs_abort ();
2990 }
2991
2992#endif /* ENABLE_CHECKING */
2993
2994 return android_handles[handle].handle;
2995}
2996
2997static jobject
2998android_resolve_handle2 (android_handle handle,
2999 enum android_handle_type type,
3000 enum android_handle_type type2)
3001{
3002 if (!handle)
3003 return NULL;
3004
3005 /* CheckJNI will normally ensure that the handle exists and is
3006 the right type, but with a less informative error message.
3007 Don't waste cycles doing our own checking here. */
3008
3009#ifdef ENABLE_CHECKING
3010
3011 if (!android_handles[handle].handle)
3012 {
3013 __android_log_print (ANDROID_LOG_ERROR, __func__,
3014 "Trying to resolve free handle!");
3015 emacs_abort ();
3016 }
3017
3018 if (android_handles[handle].type != type
3019 && android_handles[handle].type != type2)
3020 {
3021 __android_log_print (ANDROID_LOG_ERROR, __func__,
3022 "Handle has wrong type!");
3023 emacs_abort ();
3024 }
3025
3026#endif /* ENABLE_CHECKING */
3027
3028 return android_handles[handle].handle;
3029} 2943}
3030 2944
3031void 2945void
@@ -3037,7 +2951,7 @@ android_change_window_attributes (android_window handle,
3037 jobject window; 2951 jobject window;
3038 jint pixel; 2952 jint pixel;
3039 2953
3040 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 2954 window = android_resolve_handle (handle);
3041 2955
3042 if (value_mask & ANDROID_CW_BACK_PIXEL) 2956 if (value_mask & ANDROID_CW_BACK_PIXEL)
3043 { 2957 {
@@ -3051,6 +2965,35 @@ android_change_window_attributes (android_window handle,
3051 } 2965 }
3052} 2966}
3053 2967
2968/* Return a reference to the local reference HANDLE suitable for
2969 indefinite retention and save its value into HANDLE, deleting HANDLE,
2970 or signal an error if such a reference cannot be allocated. */
2971
2972static android_handle
2973android_globalize_reference (jobject handle)
2974{
2975 jobject global;
2976
2977 /* Though Android 8.0 and later can support an unlimited number of
2978 active local references, they remain inappropriate in threading
2979 configurations for being local to the current thread. */
2980
2981 global = (*android_java_env)->NewGlobalRef (android_java_env,
2982 handle);
2983 (*android_java_env)->ExceptionClear (android_java_env);
2984 ANDROID_DELETE_LOCAL_REF (handle);
2985
2986 if (__builtin_expect (global == NULL, 0))
2987 error ("JNI global reference reserves exhausted");
2988
2989 /* Save the value of this handle into HANDLE. */
2990 (*android_java_env)->SetLongField (android_java_env, global,
2991 handle_class.handle,
2992 (jlong) global);
2993 verify (sizeof (jlong) >= sizeof (intptr_t));
2994 return (intptr_t) global;
2995}
2996
3054/* Create a new window with the given width, height and 2997/* Create a new window with the given width, height and
3055 attributes. */ 2998 attributes. */
3056 2999
@@ -3064,16 +3007,10 @@ android_create_window (android_window parent, int x, int y,
3064 static jmethodID constructor; 3007 static jmethodID constructor;
3065 jobject object, parent_object, old; 3008 jobject object, parent_object, old;
3066 android_window window; 3009 android_window window;
3067 android_handle prev_max_handle;
3068 bool override_redirect; 3010 bool override_redirect;
3069 3011
3070 parent_object = android_resolve_handle (parent, ANDROID_HANDLE_WINDOW); 3012 parent_object = android_resolve_handle (parent);
3071
3072 prev_max_handle = max_handle;
3073 window = android_alloc_id ();
3074 3013
3075 if (!window)
3076 error ("Out of window handles!");
3077 3014
3078 if (!class) 3015 if (!class)
3079 { 3016 {
@@ -3083,7 +3020,7 @@ android_create_window (android_window parent, int x, int y,
3083 3020
3084 constructor 3021 constructor
3085 = (*android_java_env)->GetMethodID (android_java_env, class, "<init>", 3022 = (*android_java_env)->GetMethodID (android_java_env, class, "<init>",
3086 "(SLorg/gnu/emacs/EmacsWindow;" 3023 "(Lorg/gnu/emacs/EmacsWindow;"
3087 "IIIIZ)V"); 3024 "IIIIZ)V");
3088 eassert (constructor != NULL); 3025 eassert (constructor != NULL);
3089 3026
@@ -3100,28 +3037,12 @@ android_create_window (android_window parent, int x, int y,
3100 && attrs->override_redirect); 3037 && attrs->override_redirect);
3101 3038
3102 object = (*android_java_env)->NewObject (android_java_env, class, 3039 object = (*android_java_env)->NewObject (android_java_env, class,
3103 constructor, (jshort) window, 3040 constructor, parent_object,
3104 parent_object, (jint) x, (jint) y, 3041 (jint) x, (jint) y,
3105 (jint) width, (jint) height, 3042 (jint) width, (jint) height,
3106 (jboolean) override_redirect); 3043 (jboolean) override_redirect);
3107 if (!object) 3044 android_exception_check ();
3108 { 3045 window = android_globalize_reference (object);
3109 (*android_java_env)->ExceptionClear (android_java_env);
3110
3111 max_handle = prev_max_handle;
3112 memory_full (0);
3113 }
3114
3115 android_handles[window].type = ANDROID_HANDLE_WINDOW;
3116 android_handles[window].handle
3117 = (*android_java_env)->NewGlobalRef (android_java_env,
3118 object);
3119 (*android_java_env)->ExceptionClear (android_java_env);
3120 ANDROID_DELETE_LOCAL_REF (object);
3121
3122 if (!android_handles[window].handle)
3123 memory_full (0);
3124
3125 android_change_window_attributes (window, value_mask, attrs); 3046 android_change_window_attributes (window, value_mask, attrs);
3126 return window; 3047 return window;
3127} 3048}
@@ -3139,13 +3060,6 @@ android_set_window_background (android_window window, unsigned long pixel)
3139void 3060void
3140android_destroy_window (android_window window) 3061android_destroy_window (android_window window)
3141{ 3062{
3142 if (android_handles[window].type != ANDROID_HANDLE_WINDOW)
3143 {
3144 __android_log_print (ANDROID_LOG_ERROR, __func__,
3145 "Trying to destroy something not a window!");
3146 emacs_abort ();
3147 }
3148
3149 android_destroy_handle (window); 3063 android_destroy_handle (window);
3150} 3064}
3151 3065
@@ -3193,7 +3107,7 @@ android_init_emacs_gc_class (void)
3193 emacs_gc_constructor 3107 emacs_gc_constructor
3194 = (*android_java_env)->GetMethodID (android_java_env, 3108 = (*android_java_env)->GetMethodID (android_java_env,
3195 emacs_gc_class, 3109 emacs_gc_class,
3196 "<init>", "(S)V"); 3110 "<init>", "()V");
3197 eassert (emacs_gc_constructor); 3111 eassert (emacs_gc_constructor);
3198 3112
3199 emacs_gc_mark_dirty 3113 emacs_gc_mark_dirty
@@ -3279,14 +3193,12 @@ android_create_gc (enum android_gc_value_mask mask,
3279 struct android_gc_values *values) 3193 struct android_gc_values *values)
3280{ 3194{
3281 struct android_gc *gc; 3195 struct android_gc *gc;
3282 android_handle prev_max_handle;
3283 jobject object; 3196 jobject object;
3284 3197
3285 android_init_emacs_gc_class (); 3198 android_init_emacs_gc_class ();
3286 3199
3287 gc = xmalloc (sizeof *gc); 3200 gc = xmalloc (sizeof *gc);
3288 prev_max_handle = max_handle; 3201 gc->gcontext = 0;
3289 gc->gcontext = android_alloc_id ();
3290 gc->foreground = 0; 3202 gc->foreground = 0;
3291 gc->background = 0xffffff; 3203 gc->background = 0xffffff;
3292 gc->clip_rects = NULL; 3204 gc->clip_rects = NULL;
@@ -3309,34 +3221,12 @@ android_create_gc (enum android_gc_value_mask mask,
3309 gc->dashes = NULL; 3221 gc->dashes = NULL;
3310 gc->n_segments = 0; 3222 gc->n_segments = 0;
3311 3223
3312 if (!gc->gcontext)
3313 {
3314 xfree (gc);
3315 error ("Out of GContext handles!");
3316 }
3317
3318 object = (*android_java_env)->NewObject (android_java_env, 3224 object = (*android_java_env)->NewObject (android_java_env,
3319 emacs_gc_class, 3225 emacs_gc_class,
3320 emacs_gc_constructor, 3226 emacs_gc_constructor);
3321 (jshort) gc->gcontext); 3227 android_exception_check ();
3322
3323 if (!object)
3324 {
3325 (*android_java_env)->ExceptionClear (android_java_env);
3326
3327 max_handle = prev_max_handle;
3328 memory_full (0);
3329 }
3330
3331 android_handles[gc->gcontext].type = ANDROID_HANDLE_GCONTEXT;
3332 android_handles[gc->gcontext].handle
3333 = (*android_java_env)->NewGlobalRef (android_java_env, object);
3334 (*android_java_env)->ExceptionClear (android_java_env);
3335 ANDROID_DELETE_LOCAL_REF (object);
3336
3337 if (!android_handles[gc->gcontext].handle)
3338 memory_full (0);
3339 3228
3229 gc->gcontext = android_globalize_reference (object);
3340 android_change_gc (gc, mask, values); 3230 android_change_gc (gc, mask, values);
3341 return gc; 3231 return gc;
3342} 3232}
@@ -3362,8 +3252,7 @@ android_change_gc (struct android_gc *gc,
3362 clip_changed = false; 3252 clip_changed = false;
3363 3253
3364 android_init_emacs_gc_class (); 3254 android_init_emacs_gc_class ();
3365 gcontext = android_resolve_handle (gc->gcontext, 3255 gcontext = android_resolve_handle (gc->gcontext);
3366 ANDROID_HANDLE_GCONTEXT);
3367 3256
3368 if (mask & ANDROID_GC_FOREGROUND) 3257 if (mask & ANDROID_GC_FOREGROUND)
3369 { 3258 {
@@ -3414,8 +3303,7 @@ android_change_gc (struct android_gc *gc,
3414 3303
3415 if (mask & ANDROID_GC_CLIP_MASK) 3304 if (mask & ANDROID_GC_CLIP_MASK)
3416 { 3305 {
3417 what = android_resolve_handle (values->clip_mask, 3306 what = android_resolve_handle (values->clip_mask);
3418 ANDROID_HANDLE_PIXMAP);
3419 (*android_java_env)->SetObjectField (android_java_env, 3307 (*android_java_env)->SetObjectField (android_java_env,
3420 gcontext, 3308 gcontext,
3421 emacs_gc_clip_mask, 3309 emacs_gc_clip_mask,
@@ -3436,8 +3324,7 @@ android_change_gc (struct android_gc *gc,
3436 3324
3437 if (mask & ANDROID_GC_STIPPLE) 3325 if (mask & ANDROID_GC_STIPPLE)
3438 { 3326 {
3439 what = android_resolve_handle (values->stipple, 3327 what = android_resolve_handle (values->stipple);
3440 ANDROID_HANDLE_PIXMAP);
3441 (*android_java_env)->SetObjectField (android_java_env, 3328 (*android_java_env)->SetObjectField (android_java_env,
3442 gcontext, 3329 gcontext,
3443 emacs_gc_stipple, 3330 emacs_gc_stipple,
@@ -3549,8 +3436,7 @@ android_set_clip_rectangles (struct android_gc *gc, int clip_x_origin,
3549 android_init_android_rect_class (); 3436 android_init_android_rect_class ();
3550 android_init_emacs_gc_class (); 3437 android_init_emacs_gc_class ();
3551 3438
3552 gcontext = android_resolve_handle (gc->gcontext, 3439 gcontext = android_resolve_handle (gc->gcontext);
3553 ANDROID_HANDLE_GCONTEXT);
3554 3440
3555 array = (*android_java_env)->NewObjectArray (android_java_env, 3441 array = (*android_java_env)->NewObjectArray (android_java_env,
3556 n_clip_rects, 3442 n_clip_rects,
@@ -3623,8 +3509,7 @@ android_set_dashes (struct android_gc *gc, int dash_offset,
3623 int i; 3509 int i;
3624 jobject array, gcontext; 3510 jobject array, gcontext;
3625 3511
3626 gcontext = android_resolve_handle (gc->gcontext, 3512 gcontext = android_resolve_handle (gc->gcontext);
3627 ANDROID_HANDLE_GCONTEXT);
3628 3513
3629 if (n == gc->n_segments 3514 if (n == gc->n_segments
3630 && (!gc->dashes || !memcmp (gc->dashes, dash_list, 3515 && (!gc->dashes || !memcmp (gc->dashes, dash_list,
@@ -3692,9 +3577,8 @@ android_reparent_window (android_window w, android_window parent_handle,
3692 jobject window, parent; 3577 jobject window, parent;
3693 jmethodID method; 3578 jmethodID method;
3694 3579
3695 window = android_resolve_handle (w, ANDROID_HANDLE_WINDOW); 3580 window = android_resolve_handle (w);
3696 parent = android_resolve_handle (parent_handle, 3581 parent = android_resolve_handle (parent_handle);
3697 ANDROID_HANDLE_WINDOW);
3698 3582
3699 method = window_class.reparent_to; 3583 method = window_class.reparent_to;
3700 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window, 3584 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
@@ -3708,7 +3592,7 @@ android_clear_window (android_window handle)
3708{ 3592{
3709 jobject window; 3593 jobject window;
3710 3594
3711 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 3595 window = android_resolve_handle (handle);
3712 3596
3713 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3597 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
3714 window, 3598 window,
@@ -3723,7 +3607,7 @@ android_map_window (android_window handle)
3723 jobject window; 3607 jobject window;
3724 jmethodID map_window; 3608 jmethodID map_window;
3725 3609
3726 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 3610 window = android_resolve_handle (handle);
3727 map_window = window_class.map_window; 3611 map_window = window_class.map_window;
3728 3612
3729 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3613 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -3739,7 +3623,7 @@ android_unmap_window (android_window handle)
3739 jobject window; 3623 jobject window;
3740 jmethodID unmap_window; 3624 jmethodID unmap_window;
3741 3625
3742 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 3626 window = android_resolve_handle (handle);
3743 unmap_window = window_class.unmap_window; 3627 unmap_window = window_class.unmap_window;
3744 3628
3745 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3629 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -3756,7 +3640,7 @@ android_resize_window (android_window handle, unsigned int width,
3756 jobject window; 3640 jobject window;
3757 jmethodID resize_window; 3641 jmethodID resize_window;
3758 3642
3759 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 3643 window = android_resolve_handle (handle);
3760 resize_window = window_class.resize_window; 3644 resize_window = window_class.resize_window;
3761 3645
3762 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3646 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -3774,7 +3658,7 @@ android_move_window (android_window handle, int x, int y)
3774 jobject window; 3658 jobject window;
3775 jmethodID move_window; 3659 jmethodID move_window;
3776 3660
3777 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 3661 window = android_resolve_handle (handle);
3778 move_window = window_class.move_window; 3662 move_window = window_class.move_window;
3779 3663
3780 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3664 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -3794,8 +3678,7 @@ android_swap_buffers (struct android_swap_info *swap_info,
3794 3678
3795 for (i = 0; i < num_windows; ++i) 3679 for (i = 0; i < num_windows; ++i)
3796 { 3680 {
3797 window = android_resolve_handle (swap_info[i].swap_window, 3681 window = android_resolve_handle (swap_info[i].swap_window);
3798 ANDROID_HANDLE_WINDOW);
3799 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3682 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
3800 window, 3683 window,
3801 window_class.class, 3684 window_class.class,
@@ -3856,11 +3739,8 @@ android_fill_rectangle (android_drawable handle, struct android_gc *gc,
3856{ 3739{
3857 jobject drawable, gcontext; 3740 jobject drawable, gcontext;
3858 3741
3859 drawable = android_resolve_handle2 (handle, 3742 drawable = android_resolve_handle (handle);
3860 ANDROID_HANDLE_WINDOW, 3743 gcontext = android_resolve_handle (gc->gcontext);
3861 ANDROID_HANDLE_PIXMAP);
3862 gcontext = android_resolve_handle (gc->gcontext,
3863 ANDROID_HANDLE_GCONTEXT);
3864 3744
3865 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 3745 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
3866 emacs_service, 3746 emacs_service,
@@ -4527,7 +4407,9 @@ android_copy_area (android_drawable src, android_drawable dest,
4527 /* Now damage the destination drawable accordingly, should it be a 4407 /* Now damage the destination drawable accordingly, should it be a
4528 window. */ 4408 window. */
4529 4409
4530 if (android_handles[dest].type == ANDROID_HANDLE_WINDOW) 4410 if ((*android_java_env)->IsInstanceOf (android_java_env,
4411 (jobject) dest,
4412 window_class.class))
4531 android_damage_window (dest, &bounds); 4413 android_damage_window (dest, &bounds);
4532 4414
4533 fail2: 4415 fail2:
@@ -4573,11 +4455,8 @@ android_fill_polygon (android_drawable drawable, struct android_gc *gc,
4573 jobject point, drawable_object, gcontext; 4455 jobject point, drawable_object, gcontext;
4574 int i; 4456 int i;
4575 4457
4576 drawable_object = android_resolve_handle2 (drawable, 4458 drawable_object = android_resolve_handle (drawable);
4577 ANDROID_HANDLE_WINDOW, 4459 gcontext = android_resolve_handle (gc->gcontext);
4578 ANDROID_HANDLE_PIXMAP);
4579 gcontext = android_resolve_handle (gc->gcontext,
4580 ANDROID_HANDLE_GCONTEXT);
4581 4460
4582 array = (*android_java_env)->NewObjectArray (android_java_env, 4461 array = (*android_java_env)->NewObjectArray (android_java_env,
4583 npoints, 4462 npoints,
@@ -4615,11 +4494,8 @@ android_draw_rectangle (android_drawable handle, struct android_gc *gc,
4615{ 4494{
4616 jobject drawable, gcontext; 4495 jobject drawable, gcontext;
4617 4496
4618 drawable = android_resolve_handle2 (handle, 4497 drawable = android_resolve_handle (handle);
4619 ANDROID_HANDLE_WINDOW, 4498 gcontext = android_resolve_handle (gc->gcontext);
4620 ANDROID_HANDLE_PIXMAP);
4621 gcontext = android_resolve_handle (gc->gcontext,
4622 ANDROID_HANDLE_GCONTEXT);
4623 4499
4624 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4500 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
4625 emacs_service, 4501 emacs_service,
@@ -4640,11 +4516,8 @@ android_draw_point (android_drawable handle, struct android_gc *gc,
4640{ 4516{
4641 jobject drawable, gcontext; 4517 jobject drawable, gcontext;
4642 4518
4643 drawable = android_resolve_handle2 (handle, 4519 drawable = android_resolve_handle (handle);
4644 ANDROID_HANDLE_WINDOW, 4520 gcontext = android_resolve_handle (gc->gcontext);
4645 ANDROID_HANDLE_PIXMAP);
4646 gcontext = android_resolve_handle (gc->gcontext,
4647 ANDROID_HANDLE_GCONTEXT);
4648 4521
4649 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4522 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
4650 emacs_service, 4523 emacs_service,
@@ -4664,11 +4537,8 @@ android_draw_line (android_drawable handle, struct android_gc *gc,
4664{ 4537{
4665 jobject drawable, gcontext; 4538 jobject drawable, gcontext;
4666 4539
4667 drawable = android_resolve_handle2 (handle, 4540 drawable = android_resolve_handle (handle);
4668 ANDROID_HANDLE_WINDOW, 4541 gcontext = android_resolve_handle (gc->gcontext);
4669 ANDROID_HANDLE_PIXMAP);
4670 gcontext = android_resolve_handle (gc->gcontext,
4671 ANDROID_HANDLE_GCONTEXT);
4672 4542
4673 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4543 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
4674 emacs_service, 4544 emacs_service,
@@ -4687,41 +4557,15 @@ android_pixmap
4687android_create_pixmap (unsigned int width, unsigned int height, 4557android_create_pixmap (unsigned int width, unsigned int height,
4688 int depth) 4558 int depth)
4689{ 4559{
4690 android_handle prev_max_handle;
4691 jobject object; 4560 jobject object;
4692 android_pixmap pixmap;
4693
4694 /* First, allocate the pixmap handle. */
4695 prev_max_handle = max_handle;
4696 pixmap = android_alloc_id ();
4697
4698 if (!pixmap)
4699 error ("Out of pixmap handles!");
4700 4561
4701 object = (*android_java_env)->NewObject (android_java_env, 4562 object = (*android_java_env)->NewObject (android_java_env,
4702 pixmap_class.class, 4563 pixmap_class.class,
4703 pixmap_class.constructor_mutable, 4564 pixmap_class.constructor_mutable,
4704 (jshort) pixmap,
4705 (jint) width, (jint) height, 4565 (jint) width, (jint) height,
4706 (jint) depth); 4566 (jint) depth);
4707 4567 android_exception_check ();
4708 if (!object) 4568 return android_globalize_reference (object);
4709 {
4710 (*android_java_env)->ExceptionClear (android_java_env);
4711 max_handle = prev_max_handle;
4712 memory_full (0);
4713 }
4714
4715 android_handles[pixmap].type = ANDROID_HANDLE_PIXMAP;
4716 android_handles[pixmap].handle
4717 = (*android_java_env)->NewGlobalRef (android_java_env, object);
4718 (*android_java_env)->ExceptionClear (android_java_env);
4719 ANDROID_DELETE_LOCAL_REF (object);
4720
4721 if (!android_handles[pixmap].handle)
4722 memory_full (0);
4723
4724 return pixmap;
4725} 4569}
4726 4570
4727void 4571void
@@ -4742,7 +4586,7 @@ android_clear_area (android_window handle, int x, int y,
4742{ 4586{
4743 jobject window; 4587 jobject window;
4744 4588
4745 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 4589 window = android_resolve_handle (handle);
4746 4590
4747 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4591 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
4748 window, 4592 window,
@@ -4894,8 +4738,7 @@ android_get_image (android_drawable handle,
4894 unsigned char *data1, *data2; 4738 unsigned char *data1, *data2;
4895 int i, x; 4739 int i, x;
4896 4740
4897 drawable = android_resolve_handle2 (handle, ANDROID_HANDLE_WINDOW, 4741 drawable = android_resolve_handle (handle);
4898 ANDROID_HANDLE_PIXMAP);
4899 4742
4900 /* Look up the drawable and get the bitmap corresponding to it. 4743 /* Look up the drawable and get the bitmap corresponding to it.
4901 Then, lock the bitmap's bits. */ 4744 Then, lock the bitmap's bits. */
@@ -5029,7 +4872,7 @@ android_put_image (android_pixmap handle, struct android_image *image)
5029 unsigned char *data_1, *data_2; 4872 unsigned char *data_1, *data_2;
5030 int i, x; 4873 int i, x;
5031 4874
5032 drawable = android_resolve_handle (handle, ANDROID_HANDLE_PIXMAP); 4875 drawable = android_resolve_handle (handle);
5033 4876
5034 /* Look up the drawable and get the bitmap corresponding to it. 4877 /* Look up the drawable and get the bitmap corresponding to it.
5035 Then, lock the bitmap's bits. */ 4878 Then, lock the bitmap's bits. */
@@ -5131,7 +4974,7 @@ android_set_input_focus (android_window handle, unsigned long time)
5131 jobject window; 4974 jobject window;
5132 jmethodID make_input_focus; 4975 jmethodID make_input_focus;
5133 4976
5134 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 4977 window = android_resolve_handle (handle);
5135 make_input_focus = window_class.make_input_focus; 4978 make_input_focus = window_class.make_input_focus;
5136 4979
5137 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4980 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -5148,7 +4991,7 @@ android_raise_window (android_window handle)
5148 jobject window; 4991 jobject window;
5149 jmethodID raise; 4992 jmethodID raise;
5150 4993
5151 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 4994 window = android_resolve_handle (handle);
5152 raise = window_class.raise; 4995 raise = window_class.raise;
5153 4996
5154 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 4997 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -5164,7 +5007,7 @@ android_lower_window (android_window handle)
5164 jobject window; 5007 jobject window;
5165 jmethodID lower; 5008 jmethodID lower;
5166 5009
5167 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5010 window = android_resolve_handle (handle);
5168 lower = window_class.lower; 5011 lower = window_class.lower;
5169 5012
5170 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 5013 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -5181,7 +5024,7 @@ android_reconfigure_wm_window (android_window handle,
5181{ 5024{
5182 jobject sibling, window; 5025 jobject sibling, window;
5183 5026
5184 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5027 window = android_resolve_handle (handle);
5185 5028
5186 if (!(value_mask & ANDROID_CW_STACK_MODE)) 5029 if (!(value_mask & ANDROID_CW_STACK_MODE))
5187 return; 5030 return;
@@ -5193,8 +5036,7 @@ android_reconfigure_wm_window (android_window handle,
5193 sibling = NULL; 5036 sibling = NULL;
5194 5037
5195 if (value_mask & ANDROID_CW_SIBLING) 5038 if (value_mask & ANDROID_CW_SIBLING)
5196 sibling = android_resolve_handle (values->sibling, 5039 sibling = android_resolve_handle (values->sibling);
5197 ANDROID_HANDLE_WINDOW);
5198 5040
5199 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 5041 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
5200 window, 5042 window,
@@ -5214,10 +5056,10 @@ android_query_tree (android_window handle, android_window *root_return,
5214 jobject window, array; 5056 jobject window, array;
5215 jsize nelements, i; 5057 jsize nelements, i;
5216 android_window *children; 5058 android_window *children;
5217 jshort *shorts; 5059 jlong *longs;
5218 jmethodID method; 5060 jmethodID method;
5219 5061
5220 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5062 window = android_resolve_handle (handle);
5221 5063
5222 /* window can be NULL, so this is a service method. */ 5064 /* window can be NULL, so this is a service method. */
5223 method = service_class.query_tree; 5065 method = service_class.query_tree;
@@ -5237,25 +5079,25 @@ android_query_tree (android_window handle, android_window *root_return,
5237 /* Now fill in the children. */ 5079 /* Now fill in the children. */
5238 children = xnmalloc (nelements - 1, sizeof *children); 5080 children = xnmalloc (nelements - 1, sizeof *children);
5239 5081
5240 shorts 5082 longs
5241 = (*android_java_env)->GetShortArrayElements (android_java_env, array, 5083 = (*android_java_env)->GetLongArrayElements (android_java_env, array,
5242 NULL); 5084 NULL);
5243 android_exception_check_nonnull (shorts, array); 5085 android_exception_check_nonnull (longs, array);
5244 5086
5245 for (i = 1; i < nelements; ++i) 5087 for (i = 1; i < nelements; ++i)
5246 /* Subtract one from the index into children, since the parent is 5088 /* Subtract one from the index into children, since the parent is
5247 not included. */ 5089 not included. */
5248 children[i - 1] = shorts[i]; 5090 children[i - 1] = longs[i];
5249 5091
5250 /* Finally, return the parent and other values. */ 5092 /* Finally, return the parent and other values. */
5251 *root_return = 0; 5093 *root_return = 0;
5252 *parent_return = shorts[0]; 5094 *parent_return = longs[0];
5253 *children_return = children; 5095 *children_return = children;
5254 *nchildren_return = nelements - 1; 5096 *nchildren_return = nelements - 1;
5255 5097
5256 /* Release the array contents. */ 5098 /* Release the array contents. */
5257 (*android_java_env)->ReleaseShortArrayElements (android_java_env, array, 5099 (*android_java_env)->ReleaseLongArrayElements (android_java_env, array,
5258 shorts, JNI_ABORT); 5100 longs, JNI_ABORT);
5259 5101
5260 ANDROID_DELETE_LOCAL_REF (array); 5102 ANDROID_DELETE_LOCAL_REF (array);
5261 return 1; 5103 return 1;
@@ -5274,7 +5116,7 @@ android_get_geometry (android_window handle,
5274 jmethodID get_geometry; 5116 jmethodID get_geometry;
5275 jint *ints; 5117 jint *ints;
5276 5118
5277 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5119 window = android_resolve_handle (handle);
5278 get_geometry = window_class.get_window_geometry; 5120 get_geometry = window_class.get_window_geometry;
5279 5121
5280 window_geometry 5122 window_geometry
@@ -5336,7 +5178,7 @@ android_translate_coordinates (android_window src, int x,
5336 jmethodID method; 5178 jmethodID method;
5337 jint *ints; 5179 jint *ints;
5338 5180
5339 window = android_resolve_handle (src, ANDROID_HANDLE_WINDOW); 5181 window = android_resolve_handle (src);
5340 method = window_class.translate_coordinates; 5182 method = window_class.translate_coordinates;
5341 coordinates 5183 coordinates
5342 = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env, 5184 = (*android_java_env)->CallNonvirtualObjectMethod (android_java_env,
@@ -5504,51 +5346,44 @@ android_wc_lookup_string (android_key_pressed_event *event,
5504 /* Now look up the window. */ 5346 /* Now look up the window. */
5505 rc = 0; 5347 rc = 0;
5506 5348
5507 if (!android_handles[event->window].handle 5349 window = android_resolve_handle (event->window);
5508 || (android_handles[event->window].type 5350 string
5509 != ANDROID_HANDLE_WINDOW)) 5351 = (*env)->CallNonvirtualObjectMethod (env, window,
5352 window_class.class,
5353 window_class.lookup_string,
5354 (jint) event->serial);
5355 android_exception_check ();
5356
5357 if (!string)
5510 status = ANDROID_LOOKUP_NONE; 5358 status = ANDROID_LOOKUP_NONE;
5511 else 5359 else
5512 { 5360 {
5513 window = android_handles[event->window].handle; 5361 /* Now return this input method string. */
5514 string 5362 characters = (*env)->GetStringChars (env, string, NULL);
5515 = (*env)->CallNonvirtualObjectMethod (env, window, 5363 android_exception_check_nonnull ((void *) characters, string);
5516 window_class.class,
5517 window_class.lookup_string,
5518 (jint) event->serial);
5519 android_exception_check ();
5520
5521 if (!string)
5522 status = ANDROID_LOOKUP_NONE;
5523 else
5524 {
5525 /* Now return this input method string. */
5526 characters = (*env)->GetStringChars (env, string, NULL);
5527 android_exception_check_nonnull ((void *) characters, string);
5528 5364
5529 /* Establish the size of the the string. */ 5365 /* Establish the size of the the string. */
5530 size = (*env)->GetStringLength (env, string); 5366 size = (*env)->GetStringLength (env, string);
5531 5367
5532 /* Copy over the string data. */ 5368 /* Copy over the string data. */
5533 for (i = 0; i < MIN ((unsigned int) wchars_buffer, size); ++i) 5369 for (i = 0; i < MIN ((unsigned int) wchars_buffer, size); ++i)
5534 buffer_return[i] = characters[i]; 5370 buffer_return[i] = characters[i];
5535 5371
5536 if (i < size) 5372 if (i < size)
5537 status = ANDROID_BUFFER_OVERFLOW; 5373 status = ANDROID_BUFFER_OVERFLOW;
5538 else 5374 else
5539 status = ANDROID_LOOKUP_CHARS; 5375 status = ANDROID_LOOKUP_CHARS;
5540 5376
5541 /* Return the number of characters that should have been 5377 /* Return the number of characters that should have been
5542 written. */ 5378 written. */
5543 5379
5544 if (size > INT_MAX) 5380 if (size > INT_MAX)
5545 rc = INT_MAX; 5381 rc = INT_MAX;
5546 else 5382 else
5547 rc = size; 5383 rc = size;
5548 5384
5549 (*env)->ReleaseStringChars (env, string, characters); 5385 (*env)->ReleaseStringChars (env, string, characters);
5550 ANDROID_DELETE_LOCAL_REF (string); 5386 ANDROID_DELETE_LOCAL_REF (string);
5551 }
5552 } 5387 }
5553 5388
5554 *status_return = status; 5389 *status_return = status;
@@ -5582,8 +5417,7 @@ android_lock_bitmap (android_drawable drawable,
5582 jobject object, bitmap; 5417 jobject object, bitmap;
5583 void *data; 5418 void *data;
5584 5419
5585 object = android_resolve_handle2 (drawable, ANDROID_HANDLE_WINDOW, 5420 object = android_resolve_handle (drawable);
5586 ANDROID_HANDLE_PIXMAP);
5587 5421
5588 /* Look up the drawable and get the bitmap corresponding to it. 5422 /* Look up the drawable and get the bitmap corresponding to it.
5589 Then, lock the bitmap's bits. */ 5423 Then, lock the bitmap's bits. */
@@ -5637,7 +5471,7 @@ android_damage_window (android_drawable handle,
5637{ 5471{
5638 jobject drawable; 5472 jobject drawable;
5639 5473
5640 drawable = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5474 drawable = android_resolve_handle (handle);
5641 5475
5642 /* Post the damage to the drawable. */ 5476 /* Post the damage to the drawable. */
5643 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 5477 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -5758,7 +5592,7 @@ android_set_dont_focus_on_map (android_window handle,
5758 jmethodID method; 5592 jmethodID method;
5759 jobject window; 5593 jobject window;
5760 5594
5761 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5595 window = android_resolve_handle (handle);
5762 method = window_class.set_dont_focus_on_map; 5596 method = window_class.set_dont_focus_on_map;
5763 5597
5764 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window, 5598 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
@@ -5775,7 +5609,7 @@ android_set_dont_accept_focus (android_window handle,
5775 jmethodID method; 5609 jmethodID method;
5776 jobject window; 5610 jobject window;
5777 5611
5778 window = android_resolve_handle (handle, ANDROID_HANDLE_WINDOW); 5612 window = android_resolve_handle (handle);
5779 method = window_class.set_dont_accept_focus; 5613 method = window_class.set_dont_accept_focus;
5780 5614
5781 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window, 5615 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
@@ -5854,7 +5688,7 @@ android_toggle_on_screen_keyboard (android_window window, bool show)
5854 jobject object; 5688 jobject object;
5855 jmethodID method; 5689 jmethodID method;
5856 5690
5857 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 5691 object = android_resolve_handle (window);
5858 method = window_class.toggle_on_screen_keyboard; 5692 method = window_class.toggle_on_screen_keyboard;
5859 5693
5860 /* Now display the on screen keyboard. */ 5694 /* Now display the on screen keyboard. */
@@ -6115,11 +5949,7 @@ android_build_jstring (const char *text)
6115 if global_foo cannot be allocated, and after the global reference 5949 if global_foo cannot be allocated, and after the global reference
6116 is created. */ 5950 is created. */
6117 5951
6118#if __GNUC__ >= 3
6119#define likely(cond) __builtin_expect (cond, 1) 5952#define likely(cond) __builtin_expect (cond, 1)
6120#else /* __GNUC__ < 3 */
6121#define likely(cond) (cond)
6122#endif /* __GNUC__ >= 3 */
6123 5953
6124/* Check for JNI exceptions and call memory_full in that 5954/* Check for JNI exceptions and call memory_full in that
6125 situation. */ 5955 situation. */
@@ -6831,7 +6661,7 @@ android_recreate_activity (android_window window)
6831 jobject object; 6661 jobject object;
6832 jmethodID method; 6662 jmethodID method;
6833 6663
6834 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 6664 object = android_resolve_handle (window);
6835 method = window_class.recreate_activity; 6665 method = window_class.recreate_activity;
6836 6666
6837 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, object, 6667 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, object,
@@ -7196,7 +7026,7 @@ android_update_ic (android_window window, ptrdiff_t selection_start,
7196{ 7026{
7197 jobject object; 7027 jobject object;
7198 7028
7199 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 7029 object = android_resolve_handle (window);
7200 7030
7201 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 7031 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
7202 emacs_service, 7032 emacs_service,
@@ -7233,7 +7063,7 @@ android_reset_ic (android_window window, enum android_ic_mode mode)
7233{ 7063{
7234 jobject object; 7064 jobject object;
7235 7065
7236 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 7066 object = android_resolve_handle (window);
7237 7067
7238 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 7068 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
7239 emacs_service, 7069 emacs_service,
@@ -7255,7 +7085,7 @@ android_update_extracted_text (android_window window, void *text,
7255 jobject object; 7085 jobject object;
7256 jmethodID method; 7086 jmethodID method;
7257 7087
7258 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 7088 object = android_resolve_handle (window);
7259 method = service_class.update_extracted_text; 7089 method = service_class.update_extracted_text;
7260 7090
7261 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 7091 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -7289,7 +7119,7 @@ android_update_cursor_anchor_info (android_window window, float x,
7289 jobject object; 7119 jobject object;
7290 jmethodID method; 7120 jmethodID method;
7291 7121
7292 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 7122 object = android_resolve_handle (window);
7293 method = service_class.update_cursor_anchor_info; 7123 method = service_class.update_cursor_anchor_info;
7294 7124
7295 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 7125 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -7324,7 +7154,7 @@ android_set_fullscreen (android_window window, bool fullscreen)
7324 if (android_api_level < 16) 7154 if (android_api_level < 16)
7325 return 1; 7155 return 1;
7326 7156
7327 object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 7157 object = android_resolve_handle (window);
7328 7158
7329 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 7159 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
7330 object, 7160 object,
@@ -7342,40 +7172,15 @@ android_set_fullscreen (android_window window, bool fullscreen)
7342android_cursor 7172android_cursor
7343android_create_font_cursor (enum android_cursor_shape shape) 7173android_create_font_cursor (enum android_cursor_shape shape)
7344{ 7174{
7345 android_cursor id;
7346 short prev_max_handle;
7347 jobject object; 7175 jobject object;
7348 7176
7349 /* First, allocate the cursor handle. */
7350 prev_max_handle = max_handle;
7351 id = android_alloc_id ();
7352
7353 if (!id)
7354 error ("Out of cursor handles!");
7355
7356 /* Next, create the cursor. */ 7177 /* Next, create the cursor. */
7357 object = (*android_java_env)->NewObject (android_java_env, 7178 object = (*android_java_env)->NewObject (android_java_env,
7358 cursor_class.class, 7179 cursor_class.class,
7359 cursor_class.constructor, 7180 cursor_class.constructor,
7360 (jshort) id,
7361 (jint) shape); 7181 (jint) shape);
7362 if (!object) 7182 android_exception_check ();
7363 { 7183 return android_globalize_reference (object);
7364 (*android_java_env)->ExceptionClear (android_java_env);
7365 max_handle = prev_max_handle;
7366 memory_full (0);
7367 }
7368
7369 android_handles[id].type = ANDROID_HANDLE_CURSOR;
7370 android_handles[id].handle
7371 = (*android_java_env)->NewGlobalRef (android_java_env, object);
7372 (*android_java_env)->ExceptionClear (android_java_env);
7373 ANDROID_DELETE_LOCAL_REF (object);
7374
7375 if (!android_handles[id].handle)
7376 memory_full (0);
7377
7378 return id;
7379} 7184}
7380 7185
7381void 7186void
@@ -7384,8 +7189,8 @@ android_define_cursor (android_window window, android_cursor cursor)
7384 jobject window1, cursor1; 7189 jobject window1, cursor1;
7385 jmethodID method; 7190 jmethodID method;
7386 7191
7387 window1 = android_resolve_handle (window, ANDROID_HANDLE_WINDOW); 7192 window1 = android_resolve_handle (window);
7388 cursor1 = android_resolve_handle (cursor, ANDROID_HANDLE_CURSOR); 7193 cursor1 = android_resolve_handle (cursor);
7389 method = window_class.define_cursor; 7194 method = window_class.define_cursor;
7390 7195
7391 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 7196 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -7398,13 +7203,6 @@ android_define_cursor (android_window window, android_cursor cursor)
7398void 7203void
7399android_free_cursor (android_cursor cursor) 7204android_free_cursor (android_cursor cursor)
7400{ 7205{
7401 if (android_handles[cursor].type != ANDROID_HANDLE_CURSOR)
7402 {
7403 __android_log_print (ANDROID_LOG_ERROR, __func__,
7404 "Trying to destroy something not a CURSOR!");
7405 emacs_abort ();
7406 }
7407
7408 android_destroy_handle (cursor); 7206 android_destroy_handle (cursor);
7409} 7207}
7410 7208