diff options
Diffstat (limited to 'vendor/gioui.org/app/internal/window/os_android.go')
-rw-r--r-- | vendor/gioui.org/app/internal/window/os_android.go | 684 |
1 files changed, 0 insertions, 684 deletions
diff --git a/vendor/gioui.org/app/internal/window/os_android.go b/vendor/gioui.org/app/internal/window/os_android.go deleted file mode 100644 index 3458b26..0000000 --- a/vendor/gioui.org/app/internal/window/os_android.go +++ /dev/null @@ -1,684 +0,0 @@ -// SPDX-License-Identifier: Unlicense OR MIT - -package window - -/* -#cgo CFLAGS: -Werror -#cgo LDFLAGS: -landroid - -#include <android/native_window_jni.h> -#include <android/configuration.h> -#include <android/keycodes.h> -#include <android/input.h> -#include <stdlib.h> - -__attribute__ ((visibility ("hidden"))) jint gio_jni_GetEnv(JavaVM *vm, JNIEnv **env, jint version); -__attribute__ ((visibility ("hidden"))) jint gio_jni_GetJavaVM(JNIEnv *env, JavaVM **jvm); -__attribute__ ((visibility ("hidden"))) jint gio_jni_AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args); -__attribute__ ((visibility ("hidden"))) jint gio_jni_DetachCurrentThread(JavaVM *vm); - -__attribute__ ((visibility ("hidden"))) jobject gio_jni_NewGlobalRef(JNIEnv *env, jobject obj); -__attribute__ ((visibility ("hidden"))) void gio_jni_DeleteGlobalRef(JNIEnv *env, jobject obj); -__attribute__ ((visibility ("hidden"))) jclass gio_jni_GetObjectClass(JNIEnv *env, jobject obj); -__attribute__ ((visibility ("hidden"))) jmethodID gio_jni_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); -__attribute__ ((visibility ("hidden"))) jmethodID gio_jni_GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); -__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"))) void gio_jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args); -__attribute__ ((visibility ("hidden"))) void gio_jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); -__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"))) jsize gio_jni_GetArrayLength(JNIEnv *env, jbyteArray arr); -__attribute__ ((visibility ("hidden"))) jstring gio_jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len); -__attribute__ ((visibility ("hidden"))) jsize gio_jni_GetStringLength(JNIEnv *env, jstring str); -__attribute__ ((visibility ("hidden"))) const jchar *gio_jni_GetStringChars(JNIEnv *env, jstring str); -__attribute__ ((visibility ("hidden"))) jthrowable gio_jni_ExceptionOccurred(JNIEnv *env); -__attribute__ ((visibility ("hidden"))) void gio_jni_ExceptionClear(JNIEnv *env); -__attribute__ ((visibility ("hidden"))) jobject gio_jni_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args); -__attribute__ ((visibility ("hidden"))) jobject gio_jni_CallStaticObjectMethodA(JNIEnv *env, jclass cls, jmethodID method, jvalue *args); -*/ -import "C" - -import ( - "errors" - "fmt" - "image" - "reflect" - "runtime" - "runtime/debug" - "sync" - "time" - "unicode/utf16" - "unsafe" - - "gioui.org/f32" - "gioui.org/io/key" - "gioui.org/io/pointer" - "gioui.org/io/system" - "gioui.org/unit" -) - -type window struct { - callbacks Callbacks - - view C.jobject - - dpi int - fontScale float32 - insets system.Insets - - stage system.Stage - started bool - - mu sync.Mutex - win *C.ANativeWindow - animating bool - - // Cached Java methods. - mgetDensity C.jmethodID - mgetFontScale C.jmethodID - mshowTextInput C.jmethodID - mhideTextInput C.jmethodID - mpostFrameCallback C.jmethodID -} - -type jvalue uint64 // The largest JNI type fits in 64 bits. - -var dataDirChan = make(chan string, 1) - -var android struct { - // mu protects all fields of this structure. However, once a - // non-nil jvm is returned from javaVM, all the other fields may - // be accessed unlocked. - mu sync.Mutex - jvm *C.JavaVM - - // appCtx is the global Android App context. - appCtx C.jobject - // gioCls is the class of the Gio class. - gioCls C.jclass - - mwriteClipboard C.jmethodID - mreadClipboard C.jmethodID - mwakeupMainThread C.jmethodID -} - -var views = make(map[C.jlong]*window) - -var mainWindow = newWindowRendezvous() - -var mainFuncs = make(chan func(env *C.JNIEnv), 1) - -func getMethodID(env *C.JNIEnv, class C.jclass, method, sig string) C.jmethodID { - m := C.CString(method) - defer C.free(unsafe.Pointer(m)) - s := C.CString(sig) - defer C.free(unsafe.Pointer(s)) - jm := C.gio_jni_GetMethodID(env, class, m, s) - if err := exception(env); err != nil { - panic(err) - } - return jm -} - -func getStaticMethodID(env *C.JNIEnv, class C.jclass, method, sig string) C.jmethodID { - m := C.CString(method) - defer C.free(unsafe.Pointer(m)) - s := C.CString(sig) - defer C.free(unsafe.Pointer(s)) - jm := C.gio_jni_GetStaticMethodID(env, class, m, s) - if err := exception(env); err != nil { - panic(err) - } - return jm -} - -//export Java_org_gioui_Gio_runGoMain -func Java_org_gioui_Gio_runGoMain(env *C.JNIEnv, class C.jclass, jdataDir C.jbyteArray, context C.jobject) { - initJVM(env, class, context) - dirBytes := C.gio_jni_GetByteArrayElements(env, jdataDir) - if dirBytes == nil { - panic("runGoMain: GetByteArrayElements failed") - } - n := C.gio_jni_GetArrayLength(env, jdataDir) - dataDir := C.GoStringN((*C.char)(unsafe.Pointer(dirBytes)), n) - dataDirChan <- dataDir - C.gio_jni_ReleaseByteArrayElements(env, jdataDir, dirBytes) - - runMain() -} - -func initJVM(env *C.JNIEnv, gio C.jclass, ctx C.jobject) { - android.mu.Lock() - defer android.mu.Unlock() - if res := C.gio_jni_GetJavaVM(env, &android.jvm); res != 0 { - panic("gio: GetJavaVM failed") - } - android.appCtx = C.gio_jni_NewGlobalRef(env, ctx) - android.gioCls = C.jclass(C.gio_jni_NewGlobalRef(env, C.jobject(gio))) - android.mwriteClipboard = getStaticMethodID(env, gio, "writeClipboard", "(Landroid/content/Context;Ljava/lang/String;)V") - android.mreadClipboard = getStaticMethodID(env, gio, "readClipboard", "(Landroid/content/Context;)Ljava/lang/String;") - android.mwakeupMainThread = getStaticMethodID(env, gio, "wakeupMainThread", "()V") -} - -func JavaVM() uintptr { - jvm := javaVM() - return uintptr(unsafe.Pointer(jvm)) -} - -func javaVM() *C.JavaVM { - android.mu.Lock() - defer android.mu.Unlock() - return android.jvm -} - -func AppContext() uintptr { - android.mu.Lock() - defer android.mu.Unlock() - return uintptr(android.appCtx) -} - -func GetDataDir() string { - return <-dataDirChan -} - -//export Java_org_gioui_GioView_onCreateView -func Java_org_gioui_GioView_onCreateView(env *C.JNIEnv, class C.jclass, view C.jobject) C.jlong { - view = C.gio_jni_NewGlobalRef(env, view) - w := &window{ - view: view, - mgetDensity: getMethodID(env, class, "getDensity", "()I"), - mgetFontScale: getMethodID(env, class, "getFontScale", "()F"), - mshowTextInput: getMethodID(env, class, "showTextInput", "()V"), - mhideTextInput: getMethodID(env, class, "hideTextInput", "()V"), - mpostFrameCallback: getMethodID(env, class, "postFrameCallback", "()V"), - } - wopts := <-mainWindow.out - w.callbacks = wopts.window - w.callbacks.SetDriver(w) - handle := C.jlong(view) - views[handle] = w - w.loadConfig(env, class) - w.setStage(system.StagePaused) - return handle -} - -//export Java_org_gioui_GioView_onDestroyView -func Java_org_gioui_GioView_onDestroyView(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.callbacks.SetDriver(nil) - delete(views, handle) - C.gio_jni_DeleteGlobalRef(env, w.view) - w.view = 0 -} - -//export Java_org_gioui_GioView_onStopView -func Java_org_gioui_GioView_onStopView(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.started = false - w.setStage(system.StagePaused) -} - -//export Java_org_gioui_GioView_onStartView -func Java_org_gioui_GioView_onStartView(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.started = true - if w.aNativeWindow() != nil { - w.setVisible() - } -} - -//export Java_org_gioui_GioView_onSurfaceDestroyed -func Java_org_gioui_GioView_onSurfaceDestroyed(env *C.JNIEnv, class C.jclass, handle C.jlong) { - w := views[handle] - w.mu.Lock() - w.win = nil - w.mu.Unlock() - w.setStage(system.StagePaused) -} - -//export Java_org_gioui_GioView_onSurfaceChanged -func Java_org_gioui_GioView_onSurfaceChanged(env *C.JNIEnv, class C.jclass, handle C.jlong, surf C.jobject) { - w := views[handle] - w.mu.Lock() - w.win = C.ANativeWindow_fromSurface(env, surf) - w.mu.Unlock() - if w.started { - w.setVisible() - } -} - -//export Java_org_gioui_GioView_onLowMemory -func Java_org_gioui_GioView_onLowMemory() { - runtime.GC() - debug.FreeOSMemory() -} - -//export Java_org_gioui_GioView_onConfigurationChanged -func Java_org_gioui_GioView_onConfigurationChanged(env *C.JNIEnv, class C.jclass, view C.jlong) { - w := views[view] - w.loadConfig(env, class) - if w.stage >= system.StageRunning { - w.draw(true) - } -} - -//export Java_org_gioui_GioView_onFrameCallback -func Java_org_gioui_GioView_onFrameCallback(env *C.JNIEnv, class C.jclass, view C.jlong, nanos C.jlong) { - w, exist := views[view] - if !exist { - return - } - if w.stage < system.StageRunning { - return - } - w.mu.Lock() - anim := w.animating - w.mu.Unlock() - if anim { - runInJVM(javaVM(), func(env *C.JNIEnv) { - callVoidMethod(env, w.view, w.mpostFrameCallback) - }) - w.draw(false) - } -} - -//export Java_org_gioui_GioView_onBack -func Java_org_gioui_GioView_onBack(env *C.JNIEnv, class C.jclass, view C.jlong) C.jboolean { - w := views[view] - ev := &system.CommandEvent{Type: system.CommandBack} - w.callbacks.Event(ev) - if ev.Cancel { - return C.JNI_TRUE - } - return C.JNI_FALSE -} - -//export Java_org_gioui_GioView_onFocusChange -func Java_org_gioui_GioView_onFocusChange(env *C.JNIEnv, class C.jclass, view C.jlong, focus C.jboolean) { - w := views[view] - w.callbacks.Event(key.FocusEvent{Focus: focus == C.JNI_TRUE}) -} - -//export Java_org_gioui_GioView_onWindowInsets -func Java_org_gioui_GioView_onWindowInsets(env *C.JNIEnv, class C.jclass, view C.jlong, top, right, bottom, left C.jint) { - w := views[view] - w.insets = system.Insets{ - Top: unit.Px(float32(top)), - Right: unit.Px(float32(right)), - Bottom: unit.Px(float32(bottom)), - Left: unit.Px(float32(left)), - } - if w.stage >= system.StageRunning { - w.draw(true) - } -} - -func (w *window) setVisible() { - win := w.aNativeWindow() - width, height := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win) - if width == 0 || height == 0 { - return - } - w.setStage(system.StageRunning) - w.draw(true) -} - -func (w *window) setStage(stage system.Stage) { - if stage == w.stage { - return - } - w.stage = stage - w.callbacks.Event(system.StageEvent{stage}) -} - -func (w *window) nativeWindow(visID int) (*C.ANativeWindow, int, int) { - win := w.aNativeWindow() - var width, height int - if win != nil { - if C.ANativeWindow_setBuffersGeometry(win, 0, 0, C.int32_t(visID)) != 0 { - panic(errors.New("ANativeWindow_setBuffersGeometry failed")) - } - w, h := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win) - width, height = int(w), int(h) - } - return win, width, height -} - -func (w *window) aNativeWindow() *C.ANativeWindow { - w.mu.Lock() - defer w.mu.Unlock() - return w.win -} - -func (w *window) loadConfig(env *C.JNIEnv, class C.jclass) { - dpi := int(C.gio_jni_CallIntMethod(env, w.view, w.mgetDensity)) - w.fontScale = float32(C.gio_jni_CallFloatMethod(env, w.view, w.mgetFontScale)) - switch dpi { - case C.ACONFIGURATION_DENSITY_NONE, - C.ACONFIGURATION_DENSITY_DEFAULT, - C.ACONFIGURATION_DENSITY_ANY: - // Assume standard density. - w.dpi = C.ACONFIGURATION_DENSITY_MEDIUM - default: - w.dpi = int(dpi) - } -} - -func (w *window) SetAnimating(anim bool) { - w.mu.Lock() - w.animating = anim - w.mu.Unlock() - if anim { - runOnMain(func(env *C.JNIEnv) { - if w.view == 0 { - // View was destroyed while switching to main thread. - return - } - callVoidMethod(env, w.view, w.mpostFrameCallback) - }) - } -} - -func (w *window) draw(sync bool) { - win := w.aNativeWindow() - width, height := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win) - if width == 0 || height == 0 { - return - } - const inchPrDp = 1.0 / 160 - ppdp := float32(w.dpi) * inchPrDp - w.callbacks.Event(FrameEvent{ - FrameEvent: system.FrameEvent{ - Now: time.Now(), - Size: image.Point{ - X: int(width), - Y: int(height), - }, - Insets: w.insets, - Metric: unit.Metric{ - PxPerDp: ppdp, - PxPerSp: w.fontScale * ppdp, - }, - }, - Sync: sync, - }) -} - -type keyMapper func(devId, keyCode C.int32_t) rune - -func runInJVM(jvm *C.JavaVM, f func(env *C.JNIEnv)) { - if jvm == nil { - panic("nil JVM") - } - runtime.LockOSThread() - defer runtime.UnlockOSThread() - var env *C.JNIEnv - if res := C.gio_jni_GetEnv(jvm, &env, C.JNI_VERSION_1_6); res != C.JNI_OK { - if res != C.JNI_EDETACHED { - panic(fmt.Errorf("JNI GetEnv failed with error %d", res)) - } - if C.gio_jni_AttachCurrentThread(jvm, &env, nil) != C.JNI_OK { - panic(errors.New("runInJVM: AttachCurrentThread failed")) - } - defer C.gio_jni_DetachCurrentThread(jvm) - } - - f(env) -} - -func convertKeyCode(code C.jint) (string, bool) { - var n string - switch code { - case C.AKEYCODE_DPAD_UP: - n = key.NameUpArrow - case C.AKEYCODE_DPAD_DOWN: - n = key.NameDownArrow - case C.AKEYCODE_DPAD_LEFT: - n = key.NameLeftArrow - case C.AKEYCODE_DPAD_RIGHT: - n = key.NameRightArrow - case C.AKEYCODE_FORWARD_DEL: - n = key.NameDeleteForward - case C.AKEYCODE_DEL: - n = key.NameDeleteBackward - default: - return "", false - } - return n, true -} - -//export Java_org_gioui_GioView_onKeyEvent -func Java_org_gioui_GioView_onKeyEvent(env *C.JNIEnv, class C.jclass, handle C.jlong, keyCode, r C.jint, t C.jlong) { - w := views[handle] - if n, ok := convertKeyCode(keyCode); ok { - w.callbacks.Event(key.Event{Name: n}) - } - if r != 0 { - w.callbacks.Event(key.EditEvent{Text: string(rune(r))}) - } -} - -//export Java_org_gioui_GioView_onTouchEvent -func Java_org_gioui_GioView_onTouchEvent(env *C.JNIEnv, class C.jclass, handle C.jlong, action, pointerID, tool C.jint, x, y, scrollX, scrollY C.jfloat, jbtns C.jint, t C.jlong) { - w := views[handle] - var typ pointer.Type - switch action { - case C.AMOTION_EVENT_ACTION_DOWN, C.AMOTION_EVENT_ACTION_POINTER_DOWN: - typ = pointer.Press - case C.AMOTION_EVENT_ACTION_UP, C.AMOTION_EVENT_ACTION_POINTER_UP: - typ = pointer.Release - case C.AMOTION_EVENT_ACTION_CANCEL: - typ = pointer.Cancel - case C.AMOTION_EVENT_ACTION_MOVE: - typ = pointer.Move - case C.AMOTION_EVENT_ACTION_SCROLL: - typ = pointer.Scroll - default: - return - } - var src pointer.Source - var btns pointer.Buttons - if jbtns&C.AMOTION_EVENT_BUTTON_PRIMARY != 0 { - btns |= pointer.ButtonLeft - } - if jbtns&C.AMOTION_EVENT_BUTTON_SECONDARY != 0 { - btns |= pointer.ButtonRight - } - if jbtns&C.AMOTION_EVENT_BUTTON_TERTIARY != 0 { - btns |= pointer.ButtonMiddle - } - switch tool { - case C.AMOTION_EVENT_TOOL_TYPE_FINGER: - src = pointer.Touch - case C.AMOTION_EVENT_TOOL_TYPE_MOUSE: - src = pointer.Mouse - case C.AMOTION_EVENT_TOOL_TYPE_UNKNOWN: - // For example, triggered via 'adb shell input tap'. - // Instead of discarding it, treat it as a touch event. - src = pointer.Touch - default: - return - } - w.callbacks.Event(pointer.Event{ - Type: typ, - Source: src, - Buttons: btns, - PointerID: pointer.ID(pointerID), - Time: time.Duration(t) * time.Millisecond, - Position: f32.Point{X: float32(x), Y: float32(y)}, - Scroll: f32.Pt(float32(scrollX), float32(scrollY)), - }) -} - -func (w *window) ShowTextInput(show bool) { - if w.view == 0 { - return - } - runInJVM(javaVM(), func(env *C.JNIEnv) { - if show { - callVoidMethod(env, w.view, w.mshowTextInput) - } else { - 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))) -} - -// Do invokes the function with a global JNI handle to the view. If -// the view is destroyed, Do returns false and does not invoke the -// function. -// -// NOTE: Do must be invoked on the Android main thread. -func (w *window) Do(f func(view uintptr)) bool { - if w.view == 0 { - return false - } - runInJVM(javaVM(), func(env *C.JNIEnv) { - view := C.gio_jni_NewGlobalRef(env, w.view) - defer C.gio_jni_DeleteGlobalRef(env, view) - f(uintptr(view)) - }) - return true -} - -func varArgs(args []jvalue) *C.jvalue { - if len(args) == 0 { - return nil - } - return (*C.jvalue)(unsafe.Pointer(&args[0])) -} - -func callStaticVoidMethod(env *C.JNIEnv, cls C.jclass, method C.jmethodID, args ...jvalue) error { - C.gio_jni_CallStaticVoidMethodA(env, cls, method, varArgs(args)) - return exception(env) -} - -func callStaticObjectMethod(env *C.JNIEnv, cls C.jclass, method C.jmethodID, args ...jvalue) (C.jobject, error) { - res := C.gio_jni_CallStaticObjectMethodA(env, cls, method, varArgs(args)) - return res, exception(env) -} - -func callVoidMethod(env *C.JNIEnv, obj C.jobject, method C.jmethodID, args ...jvalue) error { - C.gio_jni_CallVoidMethodA(env, obj, method, varArgs(args)) - return exception(env) -} - -func callObjectMethod(env *C.JNIEnv, obj C.jobject, method C.jmethodID, args ...jvalue) (C.jobject, error) { - res := C.gio_jni_CallObjectMethodA(env, obj, method, varArgs(args)) - return res, exception(env) -} - -// exception returns an error corresponding to the pending -// exception, or nil if no exception is pending. The pending -// exception is cleared. -func exception(env *C.JNIEnv) error { - thr := C.gio_jni_ExceptionOccurred(env) - if thr == 0 { - return nil - } - C.gio_jni_ExceptionClear(env) - cls := getObjectClass(env, C.jobject(thr)) - toString := getMethodID(env, cls, "toString", "()Ljava/lang/String;") - msg, err := callObjectMethod(env, C.jobject(thr), toString) - if err != nil { - return err - } - return errors.New(goString(env, C.jstring(msg))) -} - -func getObjectClass(env *C.JNIEnv, obj C.jobject) C.jclass { - if obj == 0 { - panic("null object") - } - cls := C.gio_jni_GetObjectClass(env, C.jobject(obj)) - if err := exception(env); err != nil { - // GetObjectClass should never fail. - panic(err) - } - return cls -} - -// goString converts the JVM jstring to a Go string. -func goString(env *C.JNIEnv, str C.jstring) string { - if str == 0 { - return "" - } - strlen := C.gio_jni_GetStringLength(env, C.jstring(str)) - chars := C.gio_jni_GetStringChars(env, C.jstring(str)) - var utf16Chars []uint16 - hdr := (*reflect.SliceHeader)(unsafe.Pointer(&utf16Chars)) - hdr.Data = uintptr(unsafe.Pointer(chars)) - hdr.Cap = int(strlen) - hdr.Len = int(strlen) - utf8 := utf16.Decode(utf16Chars) - return string(utf8) -} - -func Main() { -} - -func NewWindow(window Callbacks, opts *Options) error { - mainWindow.in <- windowAndOptions{window, opts} - return <-mainWindow.errs -} - -func (w *window) WriteClipboard(s string) { - runOnMain(func(env *C.JNIEnv) { - jstr := javaString(env, s) - callStaticVoidMethod(env, android.gioCls, android.mwriteClipboard, - jvalue(android.appCtx), jvalue(jstr)) - }) -} - -func (w *window) ReadClipboard() { - runOnMain(func(env *C.JNIEnv) { - c, err := callStaticObjectMethod(env, android.gioCls, android.mreadClipboard, - jvalue(android.appCtx)) - if err != nil { - return - } - content := goString(env, C.jstring(c)) - w.callbacks.Event(system.ClipboardEvent{Text: content}) - }) -} - -// Close the window. Not implemented for Android. -func (w *window) Close() {} - -// RunOnMain is the exported version of runOnMain without a JNI -// environement. -func RunOnMain(f func()) { - runOnMain(func(_ *C.JNIEnv) { - f() - }) -} - -// runOnMain runs a function on the Java main thread. -func runOnMain(f func(env *C.JNIEnv)) { - go func() { - mainFuncs <- f - runInJVM(javaVM(), func(env *C.JNIEnv) { - callStaticVoidMethod(env, android.gioCls, android.mwakeupMainThread) - }) - }() -} - -//export Java_org_gioui_Gio_scheduleMainFuncs -func Java_org_gioui_Gio_scheduleMainFuncs(env *C.JNIEnv, cls C.jclass) { - for { - select { - case f := <-mainFuncs: - f(env) - default: - return - } - } -} |