Pad/cmd/pad/impl_android.go
Greg Pomerantz 7240b62a61 WIP baseline: Termux open-file bridge + word-wrap-aware viewport/scroll
- JNI: open_file_in_termux via ACTION_SEND intent (text/plain + file:// uri),
  global context ref kept from registerFragment
- impl_android.go: OpenFile(path) attaches current thread if needed
- NewLogic takes openfunc; State.open + ui.OpenFile now func(string)
- ChunkedBuffer.VisibleByteRange: word-wrap path using
  GlyphLayout.VisualLineStarts (+byteOffset, lineHeight, visual index param)
- GlyphLayout gains LineHeight; drawWrappedText records VisualLineStarts
- WordWrap default true; State.ByteOffset tracks first visible line
- types: VisualLineIndex
- scroll_fix_test.go (new)
- debug prints left in place (WIP; cleanup in later phase)
2026-08-16 00:31:26 -04:00

93 lines
2.0 KiB
Go

//+build !darwin !linux
package main
/*
#cgo LDFLAGS: -landroid -llog
#include <stdlib.h>
#include "jni_android.h"
*/
import "C"
import (
"errors"
"fmt"
"log"
"runtime"
"unsafe"
"gioui.org/app"
"gioui.org/io/event"
_ "gioui.org/app/permission/storage"
)
type JNIEnv = C.JNIEnv
var (
startpath="/storage/emulated/0/Notes"
jvm uintptr
theJVM *C.JavaVM
)
func impl_start() { }
func handleEvent(e event.Event) {
switch e := e.(type) {
case app.AndroidViewEvent:
log.Print("ViewEvent")
theJVM = (*C.JavaVM)(unsafe.Pointer(app.JavaVM()))
RunInJVM(func(env *JNIEnv) {
C.registerFragment(env, (C.jobject)(unsafe.Pointer(e.View)))
})
}
}
func RunInJVM(f func(env *C.JNIEnv)) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var env *C.JNIEnv
var detach bool
if res := C.GetEnv(theJVM, &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.AttachCurrentThread(theJVM, &env, nil) != C.JNI_OK {
panic(errors.New("runInJVM: AttachCurrentThread failed"))
}
detach = true
}
if detach {
defer func() {
C.DetachCurrentThread(theJVM)
}()
}
f(env)
}
func OpenFile(path string) {
log.Printf("OpenFile(%s)",path)
var env *C.JNIEnv
var detach bool
if res := C.GetEnv(theJVM, &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.AttachCurrentThread(theJVM, &env, nil) != C.JNI_OK {
panic(errors.New("OpenFile: AttachCurrentThread failed"))
}
detach = true
}
if detach {
defer func() {
C.DetachCurrentThread(theJVM)
}()
}
cpath := C.CString(path)
log.Printf("OpenFile: calling open_file_in_termux",path)
C.open_file_in_termux(env, cpath)
C.free(unsafe.Pointer(cpath))
}