From ba0a1a13e35b969df1ebbb888b7ad76bb3388e50 Mon Sep 17 00:00:00 2001 From: agra Date: Tue, 19 May 2026 22:54:24 +0300 Subject: [PATCH] ffi 1.25: sx-side reimplementation of safe-insets JNI chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 1D for `library/vendors/sx_android_jni/sx_android_jni.c` starts here. Adds `sx_query_safe_insets_jni` to `library/modules/platform/ android.sx` — a sx-side implementation of the JNI dispatch chain that lives inside the C `sx_android_query_safe_insets` helper. The C version is ~50 lines of `(*env)->GetMethodID` + `CallObjectMethod` + `CallIntMethod` boilerplate with manual `goto done` early-exit plumbing on every step. The sx version collapses to four `#jni_call(*void)` chain steps + four `#jni_call(s32)` reads at the end — each #jni_call internally handles GetObjectClass + GetMethodID + CallMethod via the slot interning from 1.17. Signature differences from the C version: - The sx version takes `env: *void` directly. The C version derives it from `ANativeActivity*` via JavaVM's GetEnv/AttachCurrentThread. Bridging that gap (sx-side JavaVM dispatch OR a tiny C shim that returns the env) is the next Phase 1D step. - The activity arg here is the jobject (`ANativeActivity*.clazz`) rather than the activity pointer itself. No call sites switched yet. Chess Android still uses the foreign C function. Cross-compile + chess both targets all clean — verifies the new function typechecks and lowers, but on-device runtime verification is deferred to the integration commit. --- library/modules/platform/android.sx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/library/modules/platform/android.sx b/library/modules/platform/android.sx index 2e126c5..c1c5850 100644 --- a/library/modules/platform/android.sx +++ b/library/modules/platform/android.sx @@ -55,6 +55,33 @@ AMotionEvent_getY :: (event: *void, pointer_index: u64) -> f32 #foreig sx_android_query_safe_insets :: (activity: *void, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void #foreign; sx_android_install_input_handler :: (app: *void, handler: (*void, *void) -> s32) -> void #foreign; +// sx-side reimplementation of the JNI dispatch chain inside +// `sx_android_query_safe_insets`. Caller provides an already-attached +// `JNIEnv*` and the activity's `clazz` jobject. Outputs physical-pixel +// insets just like the C foreign helper above. Eventually replaces +// the foreign call once the JavaVM env-attach plumbing has a sx +// equivalent or a thinner C shim. +sx_query_safe_insets_jni :: (env: *void, activity: *void, top: *s32, left: *s32, bottom: *s32, right: *s32) -> void { + inline if OS != .android { return; } + + top.* = 0; left.* = 0; bottom.* = 0; right.* = 0; + if activity == null { return; } + + window := #jni_call(*void)(env, activity, "getWindow", "()Landroid/view/Window;"); + if window == null { return; } + + decor := #jni_call(*void)(env, window, "getDecorView", "()Landroid/view/View;"); + if decor == null { return; } + + insets := #jni_call(*void)(env, decor, "getRootWindowInsets", "()Landroid/view/WindowInsets;"); + if insets == null { return; } + + top.* = #jni_call(s32)(env, insets, "getSystemWindowInsetTop", "()I"); + left.* = #jni_call(s32)(env, insets, "getSystemWindowInsetLeft", "()I"); + bottom.* = #jni_call(s32)(env, insets, "getSystemWindowInsetBottom", "()I"); + right.* = #jni_call(s32)(env, insets, "getSystemWindowInsetRight", "()I"); +} + // EGL — display/surface/context/config are opaque to us. eglGetDisplay :: (display_id: *void) -> *void #foreign; eglInitialize :: (display: *void, major: *s32, minor: *s32) -> u32 #foreign;