mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
app/internal/window: [Android] use correct JNI Call variant for registerFragment
While we're here, - replace the registerFragment trampoline with a general variadic CallVoidMethod trampoline. - Use UTF-16 for passing strings to Java. Java's modified UTF-8 encoding differ from Go's in corner cases. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -147,8 +147,8 @@ jint gio_jni_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID) {
|
|||||||
return (*env)->CallIntMethod(env, obj, methodID);
|
return (*env)->CallIntMethod(env, obj, methodID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gio_jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID) {
|
void gio_jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args) {
|
||||||
(*env)->CallVoidMethod(env, obj, methodID);
|
(*env)->CallVoidMethodA(env, obj, methodID, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr) {
|
jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr) {
|
||||||
@@ -163,7 +163,6 @@ jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr) {
|
|||||||
return (*env)->GetArrayLength(env, arr);
|
return (*env)->GetArrayLength(env, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gio_jni_RegisterFragment(JNIEnv *env, jobject view, jmethodID mid, char* del) {
|
jstring gio_jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len) {
|
||||||
jstring jdel = (*env)->NewStringUTF(env, del);
|
return (*env)->NewString(env, unicodeChars, len);
|
||||||
(*env)->CallObjectMethod(env, view, mid, jdel);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf16"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
@@ -57,6 +58,8 @@ type window struct {
|
|||||||
mRegisterFragment C.jmethodID
|
mRegisterFragment C.jmethodID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type jvalue uint64 // The largest JNI type fits in 64 bits.
|
||||||
|
|
||||||
var dataDirChan = make(chan string, 1)
|
var dataDirChan = make(chan string, 1)
|
||||||
|
|
||||||
var theJVM *C.JavaVM
|
var theJVM *C.JavaVM
|
||||||
@@ -212,7 +215,7 @@ func onFrameCallback(env *C.JNIEnv, class C.jclass, view C.jlong, nanos C.jlong)
|
|||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
if anim {
|
if anim {
|
||||||
runInJVM(func(env *C.JNIEnv) {
|
runInJVM(func(env *C.JNIEnv) {
|
||||||
C.gio_jni_CallVoidMethod(env, w.view, w.mpostFrameCallback)
|
callVoidMethod(env, w.view, w.mpostFrameCallback)
|
||||||
})
|
})
|
||||||
w.draw(false)
|
w.draw(false)
|
||||||
}
|
}
|
||||||
@@ -306,7 +309,7 @@ func (w *window) SetAnimating(anim bool) {
|
|||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
if anim {
|
if anim {
|
||||||
runInJVM(func(env *C.JNIEnv) {
|
runInJVM(func(env *C.JNIEnv) {
|
||||||
C.gio_jni_CallVoidMethod(env, w.view, w.mpostFrameCallbackOnMainThread)
|
callVoidMethod(env, w.view, w.mpostFrameCallbackOnMainThread)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,21 +451,39 @@ func (w *window) ShowTextInput(show bool) {
|
|||||||
}
|
}
|
||||||
runInJVM(func(env *C.JNIEnv) {
|
runInJVM(func(env *C.JNIEnv) {
|
||||||
if show {
|
if show {
|
||||||
C.gio_jni_CallVoidMethod(env, w.view, w.mshowTextInput)
|
callVoidMethod(env, w.view, w.mshowTextInput)
|
||||||
} else {
|
} else {
|
||||||
C.gio_jni_CallVoidMethod(env, w.view, w.mhideTextInput)
|
callVoidMethod(env, w.view, w.mhideTextInput)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func javaString(env *C.JNIEnv, str string) C.jstring {
|
||||||
|
if str == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
utf16Chars := utf16.Encode([]rune(str))
|
||||||
|
return C.gio_jni_NewString(env, (*C.jchar)(unsafe.Pointer(&utf16Chars[0])), C.int(len(utf16Chars)))
|
||||||
|
}
|
||||||
|
|
||||||
func (w *window) RegisterFragment(del string) {
|
func (w *window) RegisterFragment(del string) {
|
||||||
runInJVM(func(env *C.JNIEnv) {
|
runInJVM(func(env *C.JNIEnv) {
|
||||||
cdel := C.CString(del)
|
jstr := javaString(env, del)
|
||||||
defer C.free(unsafe.Pointer(cdel))
|
callVoidMethod(env, w.view, w.mRegisterFragment, jvalue(jstr))
|
||||||
C.gio_jni_RegisterFragment(env, w.view, w.mRegisterFragment, cdel)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func varArgs(args []jvalue) *C.jvalue {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (*C.jvalue)(unsafe.Pointer(&args[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func callVoidMethod(env *C.JNIEnv, obj C.jobject, method C.jmethodID, args ...jvalue) {
|
||||||
|
C.gio_jni_CallVoidMethod(env, obj, method, varArgs(args))
|
||||||
|
}
|
||||||
|
|
||||||
func Main() {
|
func Main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ __attribute__ ((visibility ("hidden"))) jmethodID gio_jni_GetMethodID(JNIEnv *en
|
|||||||
__attribute__ ((visibility ("hidden"))) jint gio_jni_CallStaticIntMethodII(JNIEnv *env, jclass clazz, jmethodID methodID, jint a1, jint a2);
|
__attribute__ ((visibility ("hidden"))) jint gio_jni_CallStaticIntMethodII(JNIEnv *env, jclass clazz, jmethodID methodID, jint a1, jint a2);
|
||||||
__attribute__ ((visibility ("hidden"))) jfloat gio_jni_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID);
|
__attribute__ ((visibility ("hidden"))) jfloat gio_jni_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID);
|
||||||
__attribute__ ((visibility ("hidden"))) jint gio_jni_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID);
|
__attribute__ ((visibility ("hidden"))) jint gio_jni_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID);
|
||||||
__attribute__ ((visibility ("hidden"))) void gio_jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID);
|
__attribute__ ((visibility ("hidden"))) void gio_jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
|
||||||
__attribute__ ((visibility ("hidden"))) jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr);
|
__attribute__ ((visibility ("hidden"))) jbyte *gio_jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr);
|
||||||
__attribute__ ((visibility ("hidden"))) void gio_jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *bytes);
|
__attribute__ ((visibility ("hidden"))) void gio_jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *bytes);
|
||||||
__attribute__ ((visibility ("hidden"))) jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr);
|
__attribute__ ((visibility ("hidden"))) jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr);
|
||||||
__attribute__ ((visibility ("hidden"))) void gio_jni_RegisterFragment(JNIEnv *env, jobject view, jmethodID mid, char* del);
|
__attribute__ ((visibility ("hidden"))) jstring gio_jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len);
|
||||||
|
|||||||
Reference in New Issue
Block a user