Added basic functions dynamically loaded for macos
parent
ef2e0f8ec6
commit
10449a124f
@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.metznet.ca/MetzNet/go-ncurses"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := ncurses.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
window := ncurses.InitScr.Load()()
|
||||
|
||||
x := ncurses.GetMaxX.Load()(window)
|
||||
y := ncurses.GetMaxY.Load()(window)
|
||||
|
||||
fmt.Printf("%d x %d\n", x, y)
|
||||
|
||||
ncurses.EndWin.Load()()
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
module git.metznet.ca/MetzNet/go-ncurses
|
||||
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.7.1 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
)
|
@ -0,0 +1,4 @@
|
||||
github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
|
||||
github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
@ -0,0 +1,79 @@
|
||||
package ncurses
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
var ncurses atomic.Value
|
||||
|
||||
func Init() error {
|
||||
if ncurses.Load() == nil {
|
||||
lib, err := purego.Dlopen(LIBRARY_PATH, purego.RTLD_GLOBAL | purego.RTLD_LAZY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ncurses.CompareAndSwap(nil, lib)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type loaded_function[T any] struct {
|
||||
name string
|
||||
value atomic.Value
|
||||
library *atomic.Value
|
||||
}
|
||||
|
||||
func NewLoadedFunction[T any](library *atomic.Value, name string) loaded_function[T] {
|
||||
return loaded_function[T]{
|
||||
name: name,
|
||||
value: atomic.Value{},
|
||||
library: library,
|
||||
}
|
||||
}
|
||||
|
||||
func(f *loaded_function[T]) Load() T {
|
||||
if f.library.Load() == nil {
|
||||
panic(fmt.Sprintf("Attempted to call library function %s before loading library", f.name))
|
||||
} else if f.value.Load() == nil {
|
||||
var tmp T
|
||||
purego.RegisterLibFunc(&tmp, f.library.Load().(uintptr), f.name)
|
||||
f.value.CompareAndSwap(nil, tmp)
|
||||
}
|
||||
return f.value.Load().(T)
|
||||
}
|
||||
|
||||
type Window uintptr
|
||||
|
||||
type voidFP func() int
|
||||
type winFP func(window Window) int
|
||||
|
||||
type initscrFP func() Window
|
||||
var InitScr = NewLoadedFunction[initscrFP](&ncurses, "initscr")
|
||||
var EndWin = NewLoadedFunction[voidFP](&ncurses, "endwin")
|
||||
|
||||
type newwinFP func(nlines, ncols, begin_x, begin_y int) Window
|
||||
var NewWin = NewLoadedFunction[newwinFP](&ncurses, "newwin")
|
||||
var DelWin = NewLoadedFunction[winFP](&ncurses, "delwin")
|
||||
type dupwinFP func(window Window) Window
|
||||
var DupWin = NewLoadedFunction[dupwinFP](&ncurses, "dupwin")
|
||||
|
||||
var Refresh = NewLoadedFunction[voidFP](&ncurses, "refresh")
|
||||
var WRefresh = NewLoadedFunction[winFP](&ncurses, "wrefresh")
|
||||
var WNOutRefresh = NewLoadedFunction[winFP](&ncurses, "wnoutrefresh")
|
||||
var DoUpdate = NewLoadedFunction[voidFP](&ncurses, "doupdate")
|
||||
|
||||
type waddstrFP func(window Window, str string) int
|
||||
var WAddStr = NewLoadedFunction[waddstrFP](&ncurses, "waddstr")
|
||||
|
||||
type waddnstrFP func(window Window, str string, n int) int
|
||||
var WAddNStr = NewLoadedFunction[waddstrFP](&ncurses, "waddnstr")
|
||||
|
||||
var GetMaxY = NewLoadedFunction[winFP](&ncurses, "getmaxy")
|
||||
var GetMaxX = NewLoadedFunction[winFP](&ncurses, "getmaxx")
|
||||
|
||||
type mvwaddstrFP func(window Window, x, y int, str string) int
|
||||
var MvWAddStr = NewLoadedFunction[mvwaddstrFP](&ncurses, "mvwaddstr")
|
@ -0,0 +1,3 @@
|
||||
package ncurses
|
||||
|
||||
const LIBRARY_PATH = "libncurses.dylib"
|
@ -0,0 +1,43 @@
|
||||
package ncurses
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func StartTest(t *testing.T) Window {
|
||||
err := Init()
|
||||
if err != nil {
|
||||
t.Fatalf("Init err - %s", err)
|
||||
}
|
||||
|
||||
window := InitScr.Load()()
|
||||
return window
|
||||
}
|
||||
|
||||
func EndTest(t *testing.T) {
|
||||
ret := EndWin.Load()()
|
||||
if ret != 0 {
|
||||
t.Fatalf("EndWin result - 0x%x", ret)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitScr(t *testing.T) {
|
||||
window := StartTest(t)
|
||||
t.Logf("InitScr result - 0x%x", window)
|
||||
EndTest(t)
|
||||
}
|
||||
|
||||
func TestNewWin(t *testing.T) {
|
||||
StartTest(t)
|
||||
|
||||
window := NewWin.Load()(10, 10, 0, 0)
|
||||
t.Logf("NewWin result - 0x%x", window)
|
||||
|
||||
ret := DelWin.Load()(window)
|
||||
if ret != 0 {
|
||||
t.Fatalf("DelWin result - 0x%x", ret)
|
||||
}
|
||||
|
||||
EndTest(t)
|
||||
}
|
||||
|
Loading…
Reference in New Issue