mirror of https://github.com/jetkvm/kvm.git
Compare commits
3 Commits
fb166e9d58
...
b707596f89
Author | SHA1 | Date |
---|---|---|
|
b707596f89 | |
|
b3243b2742 | |
|
3fa3af2d5b |
20
config.go
20
config.go
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/jetkvm/kvm/internal/logging"
|
||||
|
@ -102,6 +103,25 @@ type Config struct {
|
|||
DefaultLogLevel string `json:"default_log_level"`
|
||||
}
|
||||
|
||||
func (c *Config) GetDisplayRotation() uint16 {
|
||||
rotationInt, err := strconv.ParseUint(c.DisplayRotation, 10, 16)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("invalid display rotation, using default")
|
||||
return 270
|
||||
}
|
||||
return uint16(rotationInt)
|
||||
}
|
||||
|
||||
func (c *Config) SetDisplayRotation(rotation string) error {
|
||||
_, err := strconv.ParseUint(rotation, 10, 16)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("invalid display rotation, using default")
|
||||
return err
|
||||
}
|
||||
c.DisplayRotation = rotation
|
||||
return nil
|
||||
}
|
||||
|
||||
const configPath = "/userdata/kvm_config.json"
|
||||
|
||||
var defaultConfig = &Config{
|
||||
|
|
64
display.go
64
display.go
|
@ -35,24 +35,24 @@ func updateDisplay() {
|
|||
nativeInstance.UpdateLabelIfChanged("home_info_ipv4_addr", networkState.IPv4String())
|
||||
nativeInstance.UpdateLabelAndChangeVisibility("home_info_ipv6_addr", networkState.IPv6String())
|
||||
|
||||
nativeInstance.ObjHide("menu_btn_network")
|
||||
nativeInstance.ObjHide("menu_btn_access")
|
||||
nativeInstance.UIObjHide("menu_btn_network")
|
||||
nativeInstance.UIObjHide("menu_btn_access")
|
||||
|
||||
nativeInstance.UpdateLabelIfChanged("home_info_mac_addr", networkState.MACString())
|
||||
|
||||
if usbState == "configured" {
|
||||
nativeInstance.UpdateLabelIfChanged("usb_status_label", "Connected")
|
||||
_, _ = nativeInstance.ObjSetState("usb_status", "LV_STATE_DEFAULT")
|
||||
_, _ = nativeInstance.UIObjSetState("usb_status", "LV_STATE_DEFAULT")
|
||||
} else {
|
||||
nativeInstance.UpdateLabelIfChanged("usb_status_label", "Disconnected")
|
||||
_, _ = nativeInstance.ObjSetState("usb_status", "LV_STATE_DISABLED")
|
||||
_, _ = nativeInstance.UIObjSetState("usb_status", "LV_STATE_DISABLED")
|
||||
}
|
||||
if lastVideoState.Ready {
|
||||
nativeInstance.UpdateLabelIfChanged("hdmi_status_label", "Connected")
|
||||
_, _ = nativeInstance.ObjSetState("hdmi_status", "LV_STATE_DEFAULT")
|
||||
_, _ = nativeInstance.UIObjSetState("hdmi_status", "LV_STATE_DEFAULT")
|
||||
} else {
|
||||
nativeInstance.UpdateLabelIfChanged("hdmi_status_label", "Disconnected")
|
||||
_, _ = nativeInstance.ObjSetState("hdmi_status", "LV_STATE_DISABLED")
|
||||
_, _ = nativeInstance.UIObjSetState("hdmi_status", "LV_STATE_DISABLED")
|
||||
}
|
||||
nativeInstance.UpdateLabelIfChanged("cloud_status_label", fmt.Sprintf("%d active", actionSessions))
|
||||
|
||||
|
@ -63,20 +63,20 @@ func updateDisplay() {
|
|||
}
|
||||
|
||||
if cloudConnectionState == CloudConnectionStateNotConfigured {
|
||||
_, _ = nativeInstance.ObjHide("cloud_status_icon")
|
||||
_, _ = nativeInstance.UIObjHide("cloud_status_icon")
|
||||
} else {
|
||||
_, _ = nativeInstance.ObjShow("cloud_status_icon")
|
||||
_, _ = nativeInstance.UIObjShow("cloud_status_icon")
|
||||
}
|
||||
|
||||
switch cloudConnectionState {
|
||||
case CloudConnectionStateDisconnected:
|
||||
_, _ = nativeInstance.ImgSetSrc("cloud_status_icon", "cloud_disconnected")
|
||||
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud_disconnected")
|
||||
stopCloudBlink()
|
||||
case CloudConnectionStateConnecting:
|
||||
_, _ = nativeInstance.ImgSetSrc("cloud_status_icon", "cloud")
|
||||
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud")
|
||||
startCloudBlink()
|
||||
case CloudConnectionStateConnected:
|
||||
_, _ = nativeInstance.ImgSetSrc("cloud_status_icon", "cloud")
|
||||
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud")
|
||||
stopCloudBlink()
|
||||
}
|
||||
}
|
||||
|
@ -100,9 +100,9 @@ func startCloudBlink() {
|
|||
if cloudConnectionState != CloudConnectionStateConnecting {
|
||||
continue
|
||||
}
|
||||
_, _ = nativeInstance.ObjFadeOut("cloud_status_icon", 1000)
|
||||
_, _ = nativeInstance.UIObjFadeOut("cloud_status_icon", 1000)
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
_, _ = nativeInstance.ObjFadeIn("cloud_status_icon", 1000)
|
||||
_, _ = nativeInstance.UIObjFadeIn("cloud_status_icon", 1000)
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
}
|
||||
}()
|
||||
|
@ -153,13 +153,6 @@ func waitCtrlAndRequestDisplayUpdate(shouldWakeDisplay bool) {
|
|||
func updateStaticContents() {
|
||||
//contents that never change
|
||||
nativeInstance.UpdateLabelIfChanged("home_info_mac_addr", networkState.MACString())
|
||||
systemVersion, appVersion, err := GetLocalVersion()
|
||||
if err == nil {
|
||||
nativeInstance.UpdateLabelIfChanged("boot_screen_version", systemVersion.String())
|
||||
nativeInstance.UpdateLabelIfChanged("boot_screen_app_version", appVersion.String())
|
||||
nativeInstance.UpdateLabelAndChangeVisibility("system_version", systemVersion.String())
|
||||
nativeInstance.UpdateLabelAndChangeVisibility("app_version", appVersion.String())
|
||||
}
|
||||
|
||||
// get cpu info
|
||||
cpuInfo, err := os.ReadFile("/proc/cpuinfo")
|
||||
|
@ -266,34 +259,6 @@ func wakeDisplay(force bool) {
|
|||
backlightState = 0
|
||||
}
|
||||
|
||||
// watchTsEvents monitors the touchscreen for events and simply calls wakeDisplay() to ensure the
|
||||
// touchscreen interface still works even with LCD dimming/off.
|
||||
// TODO: This is quite a hack, really we should be getting an event from jetkvm_native, or the whole display backlight
|
||||
// control should be hoisted up to jetkvm_native.
|
||||
func watchTsEvents() {
|
||||
ts, err := os.OpenFile(touchscreenDevice, os.O_RDONLY, 0666)
|
||||
if err != nil {
|
||||
displayLogger.Warn().Err(err).Msg("failed to open touchscreen device")
|
||||
return
|
||||
}
|
||||
|
||||
defer ts.Close()
|
||||
|
||||
// This buffer is set to 24 bytes as that's the normal size of events on /dev/input
|
||||
// Reference: https://www.kernel.org/doc/Documentation/input/input.txt
|
||||
// This could potentially be set higher, to require multiple events to wake the display.
|
||||
buf := make([]byte, 24)
|
||||
for {
|
||||
_, err := ts.Read(buf)
|
||||
if err != nil {
|
||||
displayLogger.Warn().Err(err).Msg("failed to read from touchscreen device")
|
||||
return
|
||||
}
|
||||
|
||||
wakeDisplay(false)
|
||||
}
|
||||
}
|
||||
|
||||
// startBacklightTickers starts the two tickers for dimming and switching off the display
|
||||
// if they're not already set. This is done separately to the init routine as the "never dim"
|
||||
// option has the value set to zero, but time.NewTicker only accept positive values.
|
||||
|
@ -347,7 +312,6 @@ func initDisplay() {
|
|||
go func() {
|
||||
displayLogger.Info().Msg("setting initial display contents")
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
_, _ = nativeInstance.DispSetRotation(config.DisplayRotation)
|
||||
updateStaticContents()
|
||||
displayInited = true
|
||||
displayLogger.Info().Msg("display inited")
|
||||
|
@ -355,6 +319,4 @@ func initDisplay() {
|
|||
wakeDisplay(true)
|
||||
requestDisplayUpdate(true)
|
||||
}()
|
||||
|
||||
go watchTsEvents()
|
||||
}
|
||||
|
|
54
go.mod
54
go.mod
|
@ -8,34 +8,34 @@ require (
|
|||
github.com/Masterminds/semver/v3 v3.3.1
|
||||
github.com/beevik/ntp v1.4.3
|
||||
github.com/coder/websocket v1.8.13
|
||||
github.com/coreos/go-oidc/v3 v3.11.0
|
||||
github.com/creack/pty v1.1.23
|
||||
github.com/coreos/go-oidc/v3 v3.14.1
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/gin-contrib/logger v1.2.5
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/gin-contrib/logger v1.2.6
|
||||
github.com/gin-gonic/gin v1.10.1
|
||||
github.com/google/gopacket v1.1.19
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/guregu/null/v6 v6.0.0
|
||||
github.com/gwatts/rootcerts v0.0.0-20240401182218-3ab9db955caf
|
||||
github.com/hanwen/go-fuse/v2 v2.5.1
|
||||
github.com/gwatts/rootcerts v0.0.0-20250601184604-370a9a75f341
|
||||
github.com/hanwen/go-fuse/v2 v2.8.0
|
||||
github.com/hashicorp/go-getter/v2 v2.2.3
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0
|
||||
github.com/pion/logging v0.2.3
|
||||
github.com/pion/logging v0.2.4
|
||||
github.com/pion/mdns/v2 v2.0.7
|
||||
github.com/pion/webrtc/v4 v4.0.16
|
||||
github.com/pion/webrtc/v4 v4.1.2
|
||||
github.com/pojntfx/go-nbd v0.3.2
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/prometheus/common v0.62.0
|
||||
github.com/prometheus/common v0.65.0
|
||||
github.com/prometheus/procfs v0.16.1
|
||||
github.com/psanford/httpreadat v0.1.0
|
||||
github.com/rs/zerolog v1.34.0
|
||||
github.com/sourcegraph/tf-dag v0.2.2-0.20250131204052-3e8ff1477b4f
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/vishvananda/netlink v1.3.0
|
||||
go.bug.st/serial v1.6.2
|
||||
golang.org/x/crypto v0.37.0
|
||||
golang.org/x/net v0.39.0
|
||||
golang.org/x/sys v0.32.0
|
||||
github.com/vishvananda/netlink v1.3.1
|
||||
go.bug.st/serial v1.6.4
|
||||
golang.org/x/crypto v0.39.0
|
||||
golang.org/x/net v0.41.0
|
||||
golang.org/x/sys v0.33.0
|
||||
)
|
||||
|
||||
replace github.com/pojntfx/go-nbd v0.3.2 => github.com/chemhack/go-nbd v0.0.0-20241006125820-59e45f5b1e7b
|
||||
|
@ -43,11 +43,11 @@ replace github.com/pojntfx/go-nbd v0.3.2 => github.com/chemhack/go-nbd v0.0.0-20
|
|||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic v1.13.3 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/creack/goselect v0.1.2 // indirect
|
||||
github.com/creack/goselect v0.1.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
|
@ -63,7 +63,7 @@ require (
|
|||
github.com/hashicorp/go-version v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
|
@ -80,25 +80,25 @@ require (
|
|||
github.com/pion/interceptor v0.1.40 // indirect
|
||||
github.com/pion/randutil v0.1.0 // indirect
|
||||
github.com/pion/rtcp v1.2.15 // indirect
|
||||
github.com/pion/rtp v1.8.18 // indirect
|
||||
github.com/pion/rtp v1.8.19 // indirect
|
||||
github.com/pion/sctp v1.8.39 // indirect
|
||||
github.com/pion/sdp/v3 v3.0.13 // indirect
|
||||
github.com/pion/srtp/v3 v3.0.5 // indirect
|
||||
github.com/pion/sdp/v3 v3.0.14 // indirect
|
||||
github.com/pion/srtp/v3 v3.0.6 // indirect
|
||||
github.com/pion/stun/v3 v3.0.0 // indirect
|
||||
github.com/pion/transport/v3 v3.0.7 // indirect
|
||||
github.com/pion/turn/v4 v4.0.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.8 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/vishvananda/netns v0.0.5 // indirect
|
||||
github.com/wlynxg/anet v0.0.5 // indirect
|
||||
golang.org/x/arch v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.24.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/arch v0.18.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
115
go.sum
115
go.sum
|
@ -6,8 +6,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0=
|
||||
github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
|
@ -20,13 +20,13 @@ github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ
|
|||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
|
||||
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
|
||||
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
||||
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
|
||||
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
|
||||
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/creack/goselect v0.1.3 h1:MaGNMclRo7P2Jl21hBpR1Cn33ITSbKP6E49RtfblLKc=
|
||||
github.com/creack/goselect v0.1.3/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
|
||||
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -34,12 +34,12 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
|
|||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/gin-contrib/logger v1.2.5 h1:qVQI4omayQecuN4zX9ZZnsOq7w9J/ZLds3J/FMn8ypM=
|
||||
github.com/gin-contrib/logger v1.2.5/go.mod h1:/bj+vNMuA2xOEQ1aRHoJ1m9+uyaaXIAxQTvM2llsc6I=
|
||||
github.com/gin-contrib/logger v1.2.6 h1:EPolruKUTzNXMVBD9LuAFQmRjTs7AH7yKGuXgYqrKWc=
|
||||
github.com/gin-contrib/logger v1.2.6/go.mod h1:7niPrd7F0Nscw/zvgz8RiGJxSdbKM2yfQNy8xCHcm64=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
|
@ -62,10 +62,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/guregu/null/v6 v6.0.0 h1:N14VRS+4di81i1PXRiprbQJ9EM9gqBa0+KVMeS/QSjQ=
|
||||
github.com/guregu/null/v6 v6.0.0/go.mod h1:hrMIhIfrOZeLPZhROSn149tpw2gHkidAqxoXNyeX3iQ=
|
||||
github.com/gwatts/rootcerts v0.0.0-20240401182218-3ab9db955caf h1:JO6ISZIvEUitto5zjQ3/VEnDM5rPbqIFuOhS0U0ByeA=
|
||||
github.com/gwatts/rootcerts v0.0.0-20240401182218-3ab9db955caf/go.mod h1:5Kt9XkWvkGi2OHOq0QsGxebHmhCcqJ8KCbNg/a6+n+g=
|
||||
github.com/hanwen/go-fuse/v2 v2.5.1 h1:OQBE8zVemSocRxA4OaFJbjJ5hlpCmIWbGr7r0M4uoQQ=
|
||||
github.com/hanwen/go-fuse/v2 v2.5.1/go.mod h1:xKwi1cF7nXAOBCXujD5ie0ZKsxc8GGSA1rlMJc+8IJs=
|
||||
github.com/gwatts/rootcerts v0.0.0-20250601184604-370a9a75f341 h1:zPrkLSKi7kKJoNJH4uUmsQ86+0/QqpwEns0NyNLwKv0=
|
||||
github.com/gwatts/rootcerts v0.0.0-20250601184604-370a9a75f341/go.mod h1:5Kt9XkWvkGi2OHOq0QsGxebHmhCcqJ8KCbNg/a6+n+g=
|
||||
github.com/hanwen/go-fuse/v2 v2.8.0 h1:wV8rG7rmCz8XHSOwBZhG5YcVqcYjkzivjmbaMafPlAs=
|
||||
github.com/hanwen/go-fuse/v2 v2.8.0/go.mod h1:yE6D2PqWwm3CbYRxFXV9xUd8Md5d6NG0WBs5spCswmI=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
|
||||
|
@ -85,8 +85,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
|||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
|
@ -95,7 +95,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
|
@ -111,8 +110,8 @@ github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnG
|
|||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -132,39 +131,39 @@ github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4=
|
|||
github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
|
||||
github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4=
|
||||
github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic=
|
||||
github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI=
|
||||
github.com/pion/logging v0.2.3/go.mod h1:z8YfknkquMe1csOrxK5kc+5/ZPAzMxbKLX5aXpbpC90=
|
||||
github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=
|
||||
github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so=
|
||||
github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM=
|
||||
github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA=
|
||||
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
|
||||
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
|
||||
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
|
||||
github.com/pion/rtp v1.8.18 h1:yEAb4+4a8nkPCecWzQB6V/uEU18X1lQCGAQCjP+pyvU=
|
||||
github.com/pion/rtp v1.8.18/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk=
|
||||
github.com/pion/rtp v1.8.19 h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c=
|
||||
github.com/pion/rtp v1.8.19/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk=
|
||||
github.com/pion/sctp v1.8.39 h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE=
|
||||
github.com/pion/sctp v1.8.39/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
|
||||
github.com/pion/sdp/v3 v3.0.13 h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4=
|
||||
github.com/pion/sdp/v3 v3.0.13/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
|
||||
github.com/pion/srtp/v3 v3.0.5 h1:8XLB6Dt3QXkMkRFpoqC3314BemkpMQK2mZeJc4pUKqo=
|
||||
github.com/pion/srtp/v3 v3.0.5/go.mod h1:r1G7y5r1scZRLe2QJI/is+/O83W2d+JoEsuIexpw+uM=
|
||||
github.com/pion/sdp/v3 v3.0.14 h1:1h7gBr9FhOWH5GjWWY5lcw/U85MtdcibTyt/o6RxRUI=
|
||||
github.com/pion/sdp/v3 v3.0.14/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
|
||||
github.com/pion/srtp/v3 v3.0.6 h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4=
|
||||
github.com/pion/srtp/v3 v3.0.6/go.mod h1:BxvziG3v/armJHAaJ87euvkhHqWe9I7iiOy50K2QkhY=
|
||||
github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw=
|
||||
github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU=
|
||||
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
|
||||
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
|
||||
github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps=
|
||||
github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs=
|
||||
github.com/pion/webrtc/v4 v4.0.16 h1:5f8QMVIbNvJr2mPRGi2QamkPa/LVUB6NWolOCwphKHA=
|
||||
github.com/pion/webrtc/v4 v4.0.16/go.mod h1:C3uTCPzVafUA0eUzru9f47OgNt3nEO7ZJ6zNY6VSJno=
|
||||
github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54=
|
||||
github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/psanford/httpreadat v0.1.0 h1:VleW1HS2zO7/4c7c7zNl33fO6oYACSagjJIyMIwZLUE=
|
||||
|
@ -188,51 +187,49 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
|||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
||||
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
|
||||
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
|
||||
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
||||
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||
go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8=
|
||||
go.bug.st/serial v1.6.2/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
||||
go.bug.st/serial v1.6.4 h1:7FmqNPgVp3pu2Jz5PoPtbZ9jJO5gnEnZIvnI1lzve8A=
|
||||
go.bug.st/serial v1.6.4/go.mod h1:nofMJxTeNVny/m6+KaafC6vJGj3miwQZ6vW4BZUGJPI=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU=
|
||||
golang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc=
|
||||
golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
||||
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
build
|
||||
deps
|
||||
ui_index.c
|
File diff suppressed because it is too large
Load Diff
|
@ -1,53 +1,43 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
include(FetchContent)
|
||||
include(ExternalProject)
|
||||
|
||||
project(jknative LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Specify path to own LVGL config header
|
||||
set(
|
||||
LV_CONF_PATH
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lv_conf.h
|
||||
CACHE STRING "" FORCE
|
||||
)
|
||||
|
||||
set(
|
||||
LV_DRIVERS_PUBLIC_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lv_drv_conf.h
|
||||
CACHE STRING "" FORCE
|
||||
)
|
||||
|
||||
# Rockchip SDK paths
|
||||
set(RK_SDK_BASE "/opt/jetkvm-native-buildkit")
|
||||
set(RK_MEDIA_OUTPUT "${RK_SDK_BASE}/media/out")
|
||||
set(RK_MEDIA_INCLUDE_PATH "${RK_MEDIA_OUTPUT}/include")
|
||||
set(RK_APP_MEDIA_LIBS_PATH "${RK_MEDIA_OUTPUT}/lib")
|
||||
|
||||
set(LV_BUILD_EXAMPLES 0 CACHE BOOL "" FORCE)
|
||||
set(LV_USE_KCONFIG ON CACHE BOOL "" FORCE)
|
||||
set(LV_BUILD_DEFCONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lvgl_defconfig CACHE PATH "" FORCE)
|
||||
|
||||
# # libgpiod
|
||||
|
||||
# ExternalProject_Add(libgpiod-project
|
||||
# URL https://mirrors.edge.kernel.org/pub/software/libs/libgpiod/libgpiod-2.2.tar.gz
|
||||
# URL_HASH SHA256=f89c2176250f1a9563265479eb8ad5f22a63f42db6a1f438effc570f0254d2f5
|
||||
# SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/libgpiod
|
||||
# BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/libgpiod
|
||||
# CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CPPFLAGS=-fPIC ${CMAKE_CURRENT_SOURCE_DIR}/deps/libgpiod/configure --enable-tools=no CC=${CMAKE_C_COMPILER} --host=${CMAKE_HOST_SYSTEM_PROCESSOR}
|
||||
# BUILD_COMMAND make && make install
|
||||
# BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/deps/libgpiod/lib/libgpiod.a
|
||||
# )
|
||||
|
||||
|
||||
# Fetch LVGL from GitHub
|
||||
FetchContent_Declare(
|
||||
lvgl
|
||||
GIT_REPOSITORY https://github.com/lvgl/lvgl.git
|
||||
GIT_TAG v8.3.11
|
||||
GIT_TAG v9.3.0
|
||||
GIT_SHALLOW 1
|
||||
UPDATE_DISCONNECTED 1
|
||||
PATCH_COMMAND
|
||||
git apply ${CMAKE_CURRENT_SOURCE_DIR}/lvgl-no-examples.patch
|
||||
COMMAND rm -rf demos examples
|
||||
)
|
||||
)
|
||||
FetchContent_MakeAvailable(lvgl)
|
||||
|
||||
# Fetch LVGL drivers from GitHub
|
||||
FetchContent_Declare(
|
||||
lv_drivers
|
||||
GIT_REPOSITORY https://github.com/lvgl/lv_drivers.git
|
||||
GIT_TAG v8.3.0
|
||||
UPDATE_DISCONNECTED 1
|
||||
)
|
||||
FetchContent_MakeAvailable(lv_drivers)
|
||||
|
||||
# Get source files, excluding CMake generated files
|
||||
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "*.c" "ui/*.c")
|
||||
list(FILTER sources EXCLUDE REGEX "CMakeFiles.*CompilerId.*\\.c$")
|
||||
|
@ -60,18 +50,21 @@ target_include_directories(jknative PRIVATE
|
|||
${RK_MEDIA_INCLUDE_PATH}/libdrm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ui
|
||||
${CMAKE_CURRENT_BINARY_DIR}/deps/libgpiod/include
|
||||
)
|
||||
|
||||
# Set library search path
|
||||
target_link_directories(jknative PRIVATE ${RK_APP_MEDIA_LIBS_PATH})
|
||||
|
||||
# target_link_directories(jknative PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/deps/libgpiod/lib)
|
||||
|
||||
target_link_libraries(jknative PRIVATE
|
||||
lvgl::lvgl
|
||||
lvgl::drivers
|
||||
pthread
|
||||
rockit
|
||||
rockchip_mpp
|
||||
rga
|
||||
m
|
||||
)
|
||||
# libgpiod
|
||||
)
|
||||
|
||||
install(TARGETS jknative DESTINATION lib)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,53 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
C_RST="$(tput sgr0)"
|
||||
C_ERR="$(tput setaf 1)"
|
||||
C_OK="$(tput setaf 2)"
|
||||
C_WARN="$(tput setaf 3)"
|
||||
C_INFO="$(tput setaf 5)"
|
||||
|
||||
msg() { printf '%s%s%s\n' $2 "$1" $C_RST; }
|
||||
|
||||
msg_info() { msg "$1" $C_INFO; }
|
||||
msg_ok() { msg "$1" $C_OK; }
|
||||
msg_err() { msg "$1" $C_ERR; }
|
||||
msg_warn() { msg "$1" $C_WARN; }
|
||||
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
BUILD_DIR=${SCRIPT_DIR}/build
|
||||
|
||||
CMAKE_TOOLCHAIN_FILE=/opt/jetkvm-native-buildkit/rv1106-jetkvm-v2.cmake
|
||||
CLEAN_ALL=${CLEAN_ALL:-0}
|
||||
|
||||
if [ "$CLEAN_ALL" -eq 1 ]; then
|
||||
find . -name build -exec rm -r {} +
|
||||
rm -rf "${BUILD_DIR}"
|
||||
fi
|
||||
|
||||
set -x
|
||||
VERBOSE=1 cmake -B build \
|
||||
TMP_DIR=$(mktemp -d)
|
||||
pushd "${SCRIPT_DIR}" > /dev/null
|
||||
|
||||
msg_info "▶ Generating UI index"
|
||||
./ui_index.gen.sh
|
||||
|
||||
msg_info "▶ Building native library"
|
||||
VERBOSE=1 cmake -B "${BUILD_DIR}" \
|
||||
-DCMAKE_SYSTEM_PROCESSOR=armv7l \
|
||||
-DCMAKE_SYSTEM_NAME=Linux \
|
||||
-DCMAKE_CROSSCOMPILING=1 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE \
|
||||
-DLV_BUILD_USE_KCONFIG=ON \
|
||||
-DLV_BUILD_DEFCONFIG_PATH=${SCRIPT_DIR}/lvgl_defconfig \
|
||||
-DCONFIG_LV_BUILD_EXAMPLES=OFF \
|
||||
-DCONFIG_LV_BUILD_DEMOS=OFF \
|
||||
-DSKIP_GLIBC_NAMES=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="${TMP_DIR}"
|
||||
|
||||
cmake --build build
|
||||
msg_info "▶ Copying built library and header files"
|
||||
cmake --build "${BUILD_DIR}" --target install
|
||||
cp -r "${TMP_DIR}/include" ../
|
||||
cp -r "${TMP_DIR}/lib" ../
|
||||
rm -rf "${TMP_DIR}"
|
||||
|
||||
popd > /dev/null
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "edid.h"
|
||||
#include "ctrl.h"
|
||||
#include <lvgl.h>
|
||||
#include "ui/vars.h"
|
||||
#include "ui_index.h"
|
||||
#include "log.h"
|
||||
#include "log_handler.h"
|
||||
|
||||
|
@ -30,6 +30,15 @@ void jetkvm_set_video_handler(jetkvm_video_handler_t *handler) {
|
|||
video_handler = handler;
|
||||
}
|
||||
|
||||
void jetkvm_set_indev_handler(jetkvm_indev_handler_t *handler) {
|
||||
lvgl_set_indev_handler(handler);
|
||||
}
|
||||
|
||||
const char *jetkvm_ui_event_code_to_name(int code) {
|
||||
lv_event_code_t cCode = (lv_event_code_t)code;
|
||||
return lv_event_code_get_name(code);
|
||||
}
|
||||
|
||||
void video_report_format(bool ready, const char *error, u_int16_t width, u_int16_t height, double frame_per_second)
|
||||
{
|
||||
state.ready = ready;
|
||||
|
@ -154,12 +163,28 @@ lv_obj_flag_t str_to_lv_obj_flag(const char *flag)
|
|||
}
|
||||
}
|
||||
|
||||
void jetkvm_set_app_version(const char *version) {
|
||||
set_var_app_version(version);
|
||||
void jetkvm_ui_set_var(const char *name, const char *value) {
|
||||
for (int i = 0; i < ui_vars_size; i++) {
|
||||
if (strcmp(ui_vars[i].name, name) == 0) {
|
||||
ui_vars[i].setter(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
log_error("variable %s not found", name);
|
||||
}
|
||||
|
||||
void jetkvm_ui_init() {
|
||||
lvgl_init();
|
||||
const char *jetkvm_ui_get_var(const char *name) {
|
||||
for (int i = 0; i < ui_vars_size; i++) {
|
||||
if (strcmp(ui_vars[i].name, name) == 0) {
|
||||
return ui_vars[i].getter();
|
||||
}
|
||||
}
|
||||
log_error("variable %s not found", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void jetkvm_ui_init(u_int16_t rotation) {
|
||||
lvgl_init(rotation);
|
||||
}
|
||||
|
||||
void jetkvm_ui_tick() {
|
||||
|
@ -170,19 +195,9 @@ void jetkvm_set_video_state_handler(jetkvm_video_state_handler_t *handler) {
|
|||
video_state_handler = handler;
|
||||
}
|
||||
|
||||
void jetkvm_ui_set_rotation(u_int8_t rotation)
|
||||
void jetkvm_ui_set_rotation(u_int16_t rotation)
|
||||
{
|
||||
printf("setting rotation to %d\n", rotation);
|
||||
if (rotation == 90)
|
||||
{
|
||||
lv_disp_set_rotation(NULL, LV_DISP_ROT_90);
|
||||
} else if (rotation == 180) {
|
||||
lv_disp_set_rotation(NULL, LV_DISP_ROT_180);
|
||||
} else if (rotation == 270) {
|
||||
lv_disp_set_rotation(NULL, LV_DISP_ROT_270);
|
||||
} else {
|
||||
lv_disp_set_rotation(NULL, LV_DISP_ROT_NONE);
|
||||
}
|
||||
lvgl_set_rotation(NULL, rotation);
|
||||
}
|
||||
|
||||
const char *jetkvm_ui_get_current_screen() {
|
||||
|
|
|
@ -16,20 +16,22 @@ typedef struct
|
|||
|
||||
typedef void (jetkvm_video_state_handler_t)(jetkvm_video_state_t *state);
|
||||
typedef void (jetkvm_log_handler_t)(int level, const char *filename, const char *funcname, int line, const char *message);
|
||||
|
||||
typedef void (jetkvm_video_handler_t)(const uint8_t *frame, ssize_t len);
|
||||
typedef void (jetkvm_indev_handler_t)(int code);
|
||||
|
||||
void jetkvm_set_log_handler(jetkvm_log_handler_t *handler);
|
||||
void jetkvm_set_video_handler(jetkvm_video_handler_t *handler);
|
||||
|
||||
void jetkvm_set_app_version(const char *version);
|
||||
|
||||
void jetkvm_ui_init();
|
||||
void jetkvm_ui_tick();
|
||||
|
||||
void jetkvm_set_indev_handler(jetkvm_indev_handler_t *handler);
|
||||
void jetkvm_set_video_state_handler(jetkvm_video_state_handler_t *handler);
|
||||
|
||||
void jetkvm_ui_set_rotation(u_int8_t rotation);
|
||||
void jetkvm_ui_set_var(const char *name, const char *value);
|
||||
const char *jetkvm_ui_get_var(const char *name);
|
||||
|
||||
void jetkvm_ui_init(u_int16_t rotation);
|
||||
void jetkvm_ui_tick();
|
||||
|
||||
|
||||
void jetkvm_ui_set_rotation(u_int16_t rotation);
|
||||
const char *jetkvm_ui_get_current_screen();
|
||||
void jetkvm_ui_load_screen(const char *obj_name);
|
||||
int jetkvm_ui_set_text(const char *obj_name, const char *text);
|
||||
|
@ -41,6 +43,8 @@ void jetkvm_ui_set_opacity(const char *obj_name, u_int8_t opacity);
|
|||
int jetkvm_ui_add_flag(const char *obj_name, const char *flag_name);
|
||||
int jetkvm_ui_clear_flag(const char *obj_name, const char *flag_name);
|
||||
|
||||
const char *jetkvm_ui_event_code_to_name(int code);
|
||||
|
||||
int jetkvm_video_init();
|
||||
void jetkvm_video_shutdown();
|
||||
void jetkvm_video_start();
|
||||
|
@ -54,4 +58,6 @@ jetkvm_video_state_t *jetkvm_video_get_status();
|
|||
void video_report_format(bool ready, const char *error, u_int16_t width, u_int16_t height, double frame_per_second);
|
||||
int video_send_frame(const uint8_t *frame, ssize_t len);
|
||||
|
||||
|
||||
|
||||
#endif //VIDEO_DAEMON_CTRL_H
|
||||
|
|
|
@ -1,608 +0,0 @@
|
|||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for v8.1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copy this file as `lv_conf.h`
|
||||
* 1. simply next to the `lvgl` folder
|
||||
* 2. or any other places and
|
||||
* - define `LV_CONF_INCLUDE_SIMPLE`
|
||||
* - add the path as include path
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
#if 1 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*====================
|
||||
COLOR SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
|
||||
/*Enable more complex drawing routines to manage screens transparency.
|
||||
*Can be used if the UI is above another layer, e.g. an OSD menu or video player.
|
||||
*Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
|
||||
* 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
|
||||
#define LV_COLOR_MIX_ROUND_OFS (LV_COLOR_DEPTH == 32 ? 0: 128)
|
||||
|
||||
/*Images pixels with this color will not be drawn if they are chroma keyed)*/
|
||||
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/
|
||||
|
||||
/*=========================
|
||||
MEMORY SETTINGS
|
||||
*=========================*/
|
||||
|
||||
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
|
||||
#define LV_MEM_CUSTOM 1
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (32U * 1024U) /*[bytes]*/
|
||||
|
||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
||||
# define LV_MEM_ADR 0 /*0: unused*/
|
||||
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
|
||||
#if LV_MEM_ADR == 0
|
||||
//#define LV_MEM_POOL_INCLUDE your_alloc_library /* Uncomment if using an external allocator*/
|
||||
//#define LV_MEM_POOL_ALLOC your_alloc /* Uncomment if using an external allocator*/
|
||||
#endif
|
||||
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc
|
||||
# define LV_MEM_CUSTOM_FREE free
|
||||
# define LV_MEM_CUSTOM_REALLOC realloc
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms.
|
||||
*You will see an error log message if there wasn't enough buffers. */
|
||||
#define LV_MEM_BUF_MAX_NUM 16
|
||||
|
||||
/*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/
|
||||
#define LV_MEMCPY_MEMSET_STD 0
|
||||
|
||||
/*====================
|
||||
HAL SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*Default display refresh period. LVG will redraw changed areas with this period time*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 10 /*[ms]*/
|
||||
|
||||
/*Input device read period in milliseconds*/
|
||||
#define LV_INDEV_DEF_READ_PERIOD 10 /*[ms]*/
|
||||
|
||||
/*Use a custom tick source that tells the elapsed time in milliseconds.
|
||||
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
|
||||
// #define LV_TICK_CUSTOM 0
|
||||
// #if LV_TICK_CUSTOM
|
||||
// #define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||
// #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||
// #endif /*LV_TICK_CUSTOM*/
|
||||
#define LV_TICK_CUSTOM 1
|
||||
#if LV_TICK_CUSTOM
|
||||
#define LV_TICK_CUSTOM_INCLUDE <stdint.h> /*Header for the system time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (custom_tick_get()) /*Expression evaluating to current system time in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
||||
*(Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI_DEF 130 /*[px/inch]*/
|
||||
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
/*-------------
|
||||
* Drawing
|
||||
*-----------*/
|
||||
|
||||
/*Enable complex draw engine.
|
||||
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
|
||||
#define LV_DRAW_COMPLEX 1
|
||||
#if LV_DRAW_COMPLEX != 0
|
||||
|
||||
/*Allow buffering some shadow calculation.
|
||||
*LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
|
||||
*Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
|
||||
#define LV_SHADOW_CACHE_SIZE 0
|
||||
|
||||
/* Set number of maximally cached circle data.
|
||||
* The circumference of 1/4 circle are saved for anti-aliasing
|
||||
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
|
||||
* 0: to disable caching */
|
||||
#define LV_CIRCLE_CACHE_SIZE 4
|
||||
|
||||
#endif /*LV_DRAW_COMPLEX*/
|
||||
|
||||
/*Default image cache size. Image caching keeps the images opened.
|
||||
*If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added)
|
||||
*With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||
*However the opened images might consume additional RAM.
|
||||
*0: to disable caching*/
|
||||
#define LV_IMG_CACHE_DEF_SIZE 0
|
||||
|
||||
/*Maximum buffer size to allocate for rotation. Only used if software rotation is enabled in the display driver.*/
|
||||
#define LV_DISP_ROT_MAX_BUF (10*1024)
|
||||
|
||||
/*-------------
|
||||
* GPU
|
||||
*-----------*/
|
||||
|
||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
||||
#define LV_USE_GPU_STM32_DMA2D 0
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
/*Must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
#endif
|
||||
|
||||
/*Use NXP's PXP GPU iMX RTxxx platforms*/
|
||||
#define LV_USE_GPU_NXP_PXP 0
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
|
||||
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
||||
*/
|
||||
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
||||
#endif
|
||||
|
||||
/*Use NXP's VG-Lite GPU iMX RTxxx platforms*/
|
||||
#define LV_USE_GPU_NXP_VG_LITE 0
|
||||
|
||||
/*Use exnternal renderer*/
|
||||
#define LV_USE_EXTERNAL_RENDERER 0
|
||||
|
||||
/*Use SDL renderer API. Requires LV_USE_EXTERNAL_RENDERER*/
|
||||
#define LV_USE_GPU_SDL 0
|
||||
#if LV_USE_GPU_SDL
|
||||
# define LV_GPU_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
/*-------------
|
||||
* Logging
|
||||
*-----------*/
|
||||
|
||||
/*Enable the log module*/
|
||||
#define LV_USE_LOG 0
|
||||
#if LV_USE_LOG
|
||||
|
||||
/*How important log should be added:
|
||||
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
*LV_LOG_LEVEL_INFO Log important events
|
||||
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
# define LV_LOG_PRINTF 0
|
||||
|
||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
||||
# define LV_LOG_TRACE_MEM 1
|
||||
# define LV_LOG_TRACE_TIMER 1
|
||||
# define LV_LOG_TRACE_INDEV 1
|
||||
# define LV_LOG_TRACE_DISP_REFR 1
|
||||
# define LV_LOG_TRACE_EVENT 1
|
||||
# define LV_LOG_TRACE_OBJ_CREATE 1
|
||||
# define LV_LOG_TRACE_LAYOUT 1
|
||||
# define LV_LOG_TRACE_ANIM 1
|
||||
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*-------------
|
||||
* Asserts
|
||||
*-----------*/
|
||||
|
||||
/*Enable asserts if an operation is failed or an invalid data is found.
|
||||
*If LV_USE_LOG is enabled an error message will be printed on failure*/
|
||||
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
||||
#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
|
||||
|
||||
/*Add a custom handler when assert happens e.g. to restart the MCU*/
|
||||
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
|
||||
#define LV_ASSERT_HANDLER while(1); /*Halt by default*/
|
||||
|
||||
/*-------------
|
||||
* Others
|
||||
*-----------*/
|
||||
|
||||
/*1: Show CPU usage and FPS count in the right bottom corner*/
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
||||
#endif
|
||||
|
||||
/*1: Show the used memory and the memory fragmentation in the left bottom corner
|
||||
* Requires LV_MEM_CUSTOM = 0*/
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
|
||||
#endif
|
||||
|
||||
/*1: Draw random colored rectangles over the redrawn areas*/
|
||||
#define LV_USE_REFR_DEBUG 0
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
# define lv_snprintf snprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#else /*LV_SPRINTF_CUSTOM*/
|
||||
# define LV_SPRINTF_USE_FLOAT 0
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
#define LV_USE_USER_DATA 1
|
||||
|
||||
/*Garbage Collector settings
|
||||
*Used if lvgl is bound to higher level language and the memory is managed by that language*/
|
||||
#define LV_ENABLE_GC 0
|
||||
#if LV_ENABLE_GC != 0
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*For big endian systems set to 1*/
|
||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||
|
||||
/*Define a custom attribute to `lv_tick_inc` function*/
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/*Define a custom attribute to `lv_timer_handler` function*/
|
||||
#define LV_ATTRIBUTE_TIMER_HANDLER
|
||||
|
||||
/*Define a custom attribute to `lv_disp_flush_ready` function*/
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
|
||||
/*Required alignment size for buffers*/
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
|
||||
|
||||
/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
|
||||
* E.g. __attribute__((aligned(4)))*/
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
/*Attribute to mark large constant arrays for example font's bitmaps*/
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/*Complier prefix for a big array declaration in RAM*/
|
||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
||||
|
||||
/*Place performance critical functions into a faster memory (e.g RAM)*/
|
||||
#define LV_ATTRIBUTE_FAST_MEM
|
||||
|
||||
/*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/
|
||||
#define LV_ATTRIBUTE_DMA
|
||||
|
||||
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
|
||||
*should also appear on LVGL binding API such as Micropython.*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/
|
||||
|
||||
/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/
|
||||
#define LV_USE_LARGE_COORD 0
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
|
||||
*https://fonts.google.com/specimen/Montserrat*/
|
||||
#define LV_FONT_MONTSERRAT_8 0
|
||||
#define LV_FONT_MONTSERRAT_10 0
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
#define LV_FONT_MONTSERRAT_24 0
|
||||
#define LV_FONT_MONTSERRAT_26 0
|
||||
#define LV_FONT_MONTSERRAT_28 0
|
||||
#define LV_FONT_MONTSERRAT_30 0
|
||||
#define LV_FONT_MONTSERRAT_32 0
|
||||
#define LV_FONT_MONTSERRAT_34 0
|
||||
#define LV_FONT_MONTSERRAT_36 0
|
||||
#define LV_FONT_MONTSERRAT_38 0
|
||||
#define LV_FONT_MONTSERRAT_40 0
|
||||
#define LV_FONT_MONTSERRAT_42 0
|
||||
#define LV_FONT_MONTSERRAT_44 0
|
||||
#define LV_FONT_MONTSERRAT_46 0
|
||||
#define LV_FONT_MONTSERRAT_48 0
|
||||
|
||||
/*Demonstrate special features*/
|
||||
#define LV_FONT_MONTSERRAT_12_SUBPX 0
|
||||
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
|
||||
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Perisan letters and all their forms*/
|
||||
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
|
||||
|
||||
/*Pixel perfect monospace fonts*/
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
#define LV_FONT_UNSCII_16 0
|
||||
|
||||
/*Optionally declare custom fonts here.
|
||||
*You can use these fonts as default font too and they will be available globally.
|
||||
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font*/
|
||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||
|
||||
/*Enable handling large font and/or fonts with a lot of characters.
|
||||
*The limit depends on the font size, font face and bpp.
|
||||
*Compiler error will be triggered if a font needs it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/*Enables/disables support for compressed fonts.*/
|
||||
#define LV_USE_FONT_COMPRESSED 0
|
||||
|
||||
/*Enable subpixel rendering*/
|
||||
#define LV_USE_FONT_SUBPX 0
|
||||
#if LV_USE_FONT_SUBPX
|
||||
/*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/
|
||||
#define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/
|
||||
#endif
|
||||
|
||||
/*=================
|
||||
* TEXT SETTINGS
|
||||
*=================*/
|
||||
|
||||
/**
|
||||
* Select a character encoding for strings.
|
||||
* Your IDE or editor should have the same character encoding
|
||||
* - LV_TXT_ENC_UTF8
|
||||
* - LV_TXT_ENC_ASCII
|
||||
*/
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
|
||||
/*If a word is at least this long, will break wherever "prettiest"
|
||||
*To disable, set to a value <= 0*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 0
|
||||
|
||||
/*Minimum number of characters in a long word to put on a line before a break.
|
||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
|
||||
/*Minimum number of characters in a long word to put on a line after a break.
|
||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
|
||||
/*The control character to use for signalling text recoloring.*/
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
|
||||
/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
*The direction will be processed according to the Unicode Bidirectional Algorithm:
|
||||
*https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#define LV_USE_BIDI 0
|
||||
#if LV_USE_BIDI
|
||||
/*Set the default direction. Supported values:
|
||||
*`LV_BASE_DIR_LTR` Left-to-Right
|
||||
*`LV_BASE_DIR_RTL` Right-to-Left
|
||||
*`LV_BASE_DIR_AUTO` detect texts base direction*/
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
|
||||
#endif
|
||||
|
||||
/*Enable Arabic/Persian processing
|
||||
*In these languages characters should be replaced with an other form based on their position in the text*/
|
||||
#define LV_USE_ARABIC_PERSIAN_CHARS 0
|
||||
|
||||
/*==================
|
||||
* WIDGET USAGE
|
||||
*================*/
|
||||
|
||||
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
|
||||
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
#define LV_USE_ANIMIMG 1
|
||||
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
#define LV_USE_BTN 1
|
||||
|
||||
#define LV_USE_BTNMATRIX 1
|
||||
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
#define LV_USE_CHECKBOX 1
|
||||
|
||||
#define LV_USE_DROPDOWN 0 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_IMG 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL
|
||||
# define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
|
||||
# define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
#define LV_USE_ROLLER 0 /*Requires: lv_label*/
|
||||
#if LV_USE_ROLLER
|
||||
# define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
|
||||
|
||||
#define LV_USE_SWITCH 1
|
||||
|
||||
#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/
|
||||
#if LV_USE_TEXTAREA != 0
|
||||
# define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_TABLE 0
|
||||
|
||||
/*==================
|
||||
* EXTRA COMPONENTS
|
||||
*==================*/
|
||||
|
||||
/*-----------
|
||||
* Widgets
|
||||
*----------*/
|
||||
#define LV_USE_CALENDAR 0
|
||||
#if LV_USE_CALENDAR
|
||||
# define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
# if LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
# define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
|
||||
# else
|
||||
# define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
|
||||
# endif
|
||||
|
||||
# define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
|
||||
# define LV_USE_CALENDAR_HEADER_ARROW 1
|
||||
# define LV_USE_CALENDAR_HEADER_DROPDOWN 1
|
||||
#endif /*LV_USE_CALENDAR*/
|
||||
|
||||
#define LV_USE_CHART 0
|
||||
|
||||
#define LV_USE_COLORWHEEL 0
|
||||
|
||||
#define LV_USE_IMGBTN 1
|
||||
|
||||
#define LV_USE_KEYBOARD 1
|
||||
|
||||
#define LV_USE_LED 0
|
||||
|
||||
#define LV_USE_LIST 1
|
||||
|
||||
#define LV_USE_METER 0
|
||||
|
||||
#define LV_USE_MSGBOX 0
|
||||
|
||||
#define LV_USE_SPINBOX 0
|
||||
|
||||
#define LV_USE_SPINNER 0
|
||||
|
||||
#define LV_USE_TABVIEW 0
|
||||
|
||||
#define LV_USE_TILEVIEW 0
|
||||
|
||||
#define LV_USE_WIN 0
|
||||
|
||||
#define LV_USE_SPAN 1
|
||||
#if LV_USE_SPAN
|
||||
/*A line text can contain maximum num of span descriptor */
|
||||
# define LV_SPAN_SNIPPET_STACK_SIZE 64
|
||||
#endif
|
||||
|
||||
/*-----------
|
||||
* Themes
|
||||
*----------*/
|
||||
|
||||
/*A simple, impressive and very complete theme*/
|
||||
#define LV_USE_THEME_DEFAULT 1
|
||||
#if LV_USE_THEME_DEFAULT
|
||||
|
||||
/*0: Light mode; 1: Dark mode*/
|
||||
# define LV_THEME_DEFAULT_DARK 0
|
||||
|
||||
/*1: Enable grow on press*/
|
||||
# define LV_THEME_DEFAULT_GROW 1
|
||||
|
||||
/*Default transition time in [ms]*/
|
||||
# define LV_THEME_DEFAULT_TRANSITION_TIME 80
|
||||
#endif /*LV_USE_THEME_DEFAULT*/
|
||||
|
||||
/*A very simple theme that is a good starting point for a custom theme*/
|
||||
#define LV_USE_THEME_BASIC 1
|
||||
|
||||
/*A theme designed for monochrome displays*/
|
||||
#define LV_USE_THEME_MONO 0
|
||||
|
||||
/*-----------
|
||||
* Layouts
|
||||
*----------*/
|
||||
|
||||
/*A layout similar to Flexbox in CSS.*/
|
||||
#define LV_USE_FLEX 1
|
||||
|
||||
/*A layout similar to Grid in CSS.*/
|
||||
#define LV_USE_GRID 1
|
||||
|
||||
/*---------------------
|
||||
* 3rd party libraries
|
||||
*--------------------*/
|
||||
|
||||
/*File system interfaces for common APIs
|
||||
*To enable set a driver letter for that API*/
|
||||
#define LV_USE_FS_STDIO '\0' /*Uses fopen, fread, etc*/
|
||||
//#define LV_FS_STDIO_PATH "/home/john/" /*Set the working directory. If commented it will be "./" */
|
||||
|
||||
#define LV_USE_FS_POSIX '\0' /*Uses open, read, etc*/
|
||||
//#define LV_FS_POSIX_PATH "/home/john/" /*Set the working directory. If commented it will be "./" */
|
||||
|
||||
#define LV_USE_FS_WIN32 '\0' /*Uses CreateFile, ReadFile, etc*/
|
||||
//#define LV_FS_WIN32_PATH "C:\\Users\\john\\" /*Set the working directory. If commented it will be ".\\" */
|
||||
|
||||
#define LV_USE_FS_FATFS '\0' /*Uses f_open, f_read, etc*/
|
||||
|
||||
/*PNG decoder library*/
|
||||
#define LV_USE_PNG 0
|
||||
|
||||
/*BMP decoder library*/
|
||||
#define LV_USE_BMP 0
|
||||
|
||||
/* JPG + split JPG decoder library.
|
||||
* Split JPG is a custom format optimized for embedded systems. */
|
||||
#define LV_USE_SJPG 0
|
||||
|
||||
/*GIF decoder library*/
|
||||
#define LV_USE_GIF 0
|
||||
|
||||
/*QR code library*/
|
||||
#define LV_USE_QRCODE 0
|
||||
|
||||
/*FreeType library*/
|
||||
#define LV_USE_FREETYPE 0
|
||||
#if LV_USE_FREETYPE
|
||||
/*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
|
||||
# define LV_FREETYPE_CACHE_SIZE (16 * 1024)
|
||||
#endif
|
||||
|
||||
/*Rlottie library*/
|
||||
#define LV_USE_RLOTTIE 0
|
||||
|
||||
/*-----------
|
||||
* Others
|
||||
*----------*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#define LV_USE_SNAPSHOT 1
|
||||
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
/*Enable the examples to be built with the library*/
|
||||
#define LV_BUILD_EXAMPLES 0
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
|
@ -0,0 +1,23 @@
|
|||
CONFIG_LV_OS_PTHREAD=y
|
||||
CONFIG_LV_USE_OBJ_ID=y
|
||||
CONFIG_LV_USE_OBJ_NAME=y
|
||||
CONFIG_LV_USE_OBJ_ID_BUILTIN=y
|
||||
CONFIG_LV_USE_OBJ_PROPERTY=y
|
||||
CONFIG_LV_USE_OBJ_PROPERTY_NAME=y
|
||||
CONFIG_LV_USE_PRIVATE_API=y
|
||||
# CONFIG_LV_USE_CALENDAR is not set
|
||||
# CONFIG_LV_USE_CHART is not set
|
||||
# CONFIG_LV_USE_CHECKBOX is not set
|
||||
# CONFIG_LV_USE_MSGBOX is not set
|
||||
# CONFIG_LV_USE_ROLLER is not set
|
||||
# CONFIG_LV_USE_SCALE is not set
|
||||
# CONFIG_LV_USE_SLIDER is not set
|
||||
# CONFIG_LV_USE_TABLE is not set
|
||||
# CONFIG_LV_USE_TABVIEW is not set
|
||||
# CONFIG_LV_USE_TILEVIEW is not set
|
||||
CONFIG_LV_USE_QRCODE=y
|
||||
CONFIG_LV_USE_LINUX_FBDEV=y
|
||||
CONFIG_LV_USE_EVDEV=y
|
||||
CONFIG_LV_USE_ST7789=y
|
||||
CONFIG_LV_BUILD_EXAMPLES=n
|
||||
CONFIG_LV_BUILD_DEMOS=n
|
|
@ -6,45 +6,74 @@
|
|||
#include "log.h"
|
||||
#include "screen.h"
|
||||
#include <lvgl.h>
|
||||
#include <display/fbdev.h>
|
||||
#include <indev/evdev.h>
|
||||
// #include "st7789/lcd.h"
|
||||
#include "ui/ui.h"
|
||||
#include "ui_index.h"
|
||||
|
||||
#define DISP_BUF_SIZE (300 * 240 * 2)
|
||||
static lv_color_t buf[DISP_BUF_SIZE];
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
static lv_disp_drv_t disp_drv;
|
||||
static lv_indev_drv_t indev_drv;
|
||||
|
||||
void lvgl_init(void) {
|
||||
indev_handler_t *indev_handler = NULL;
|
||||
|
||||
void lvgl_set_indev_handler(indev_handler_t *handler) {
|
||||
indev_handler = handler;
|
||||
}
|
||||
|
||||
void handle_indev_event(lv_event_t *e) {
|
||||
if (indev_handler == NULL) {
|
||||
return;
|
||||
}
|
||||
indev_handler(lv_event_get_code(e));
|
||||
}
|
||||
|
||||
void lvgl_init(u_int16_t rotation) {
|
||||
log_trace("initalizing lvgl");
|
||||
|
||||
/*LittlevGL init*/
|
||||
lv_init();
|
||||
|
||||
log_trace("initalizing fbdev");
|
||||
fbdev_init();
|
||||
lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.draw_buf = &disp_buf;
|
||||
disp_drv.flush_cb = fbdev_flush;
|
||||
disp_drv.hor_res = 240;
|
||||
disp_drv.ver_res = 300;
|
||||
disp_drv.rotated = LV_DISP_ROT_270;
|
||||
disp_drv.sw_rotate = true;
|
||||
// disp_drv.full_refresh = true;
|
||||
/*Linux frame buffer device init*/
|
||||
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
/*Linux frame buffer device init*/
|
||||
lv_display_t *disp = lv_linux_fbdev_create();
|
||||
// lv_display_set_physical_resolution(disp, 240, 300);
|
||||
lv_display_set_resolution(disp, 240, 300);
|
||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");
|
||||
|
||||
log_trace("initalizing evdev");
|
||||
evdev_init();
|
||||
evdev_set_file("/dev/input/event1");
|
||||
lvgl_set_rotation(disp, rotation);
|
||||
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = evdev_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
// lv_display_t *disp = lv_st7789_create(LCD_H_RES, LCD_V_RES, LV_LCD_FLAG_NONE, lcd_send_cmd, lcd_send_color);
|
||||
// lv_display_set_resolution(disp, 240, 300);
|
||||
// lv_display_set_rotation(disp, LV_DISP_ROTATION_270);
|
||||
|
||||
// lv_color_t * buf1 = NULL;
|
||||
// lv_color_t * buf2 = NULL;
|
||||
|
||||
// uint32_t buf_size = LCD_H_RES * LCD_V_RES / 10 * lv_color_format_get_size(lv_display_get_color_format(disp));
|
||||
|
||||
// buf1 = lv_malloc(buf_size);
|
||||
// if(buf1 == NULL) {
|
||||
// log_error("display draw buffer malloc failed");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// buf2 = lv_malloc(buf_size);
|
||||
// if(buf2 == NULL) {
|
||||
// log_error("display buffer malloc failed");
|
||||
// lv_free(buf1);
|
||||
// return;
|
||||
// }
|
||||
// lv_display_set_buffers(disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
/* Linux input device init */
|
||||
lv_indev_t *mouse = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event1");
|
||||
lv_indev_set_group(mouse, lv_group_get_default());
|
||||
lv_indev_set_display(mouse, disp);
|
||||
|
||||
lv_indev_add_event_cb(mouse, handle_indev_event, LV_EVENT_ALL, NULL);
|
||||
|
||||
log_trace("initalizing ui");
|
||||
|
||||
ui_init();
|
||||
|
||||
log_info("ui initalized");
|
||||
|
@ -58,6 +87,45 @@ void lvgl_tick(void) {
|
|||
ui_tick();
|
||||
}
|
||||
|
||||
void lvgl_set_rotation(lv_display_t *disp, u_int16_t rotation) {
|
||||
log_info("setting rotation to %d", rotation);
|
||||
if (rotation == 0) {
|
||||
lv_display_set_rotation(disp, LV_DISP_ROTATION_0);
|
||||
} else if (rotation == 90) {
|
||||
lv_display_set_rotation(disp, LV_DISP_ROTATION_90);
|
||||
} else if (rotation == 180) {
|
||||
lv_display_set_rotation(disp, LV_DISP_ROTATION_180);
|
||||
} else if (rotation == 270) {
|
||||
lv_display_set_rotation(disp, LV_DISP_ROTATION_270);
|
||||
} else {
|
||||
log_error("invalid rotation %d", rotation);
|
||||
}
|
||||
|
||||
lv_style_t *flex_screen_style = ui_get_style("flex_screen");
|
||||
if (flex_screen_style == NULL) {
|
||||
log_error("flex_screen style not found");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_style_t *flex_screen_menu_style = ui_get_style("flex_screen_menu");
|
||||
if (flex_screen_menu_style == NULL) {
|
||||
log_error("flex_screen_menu style not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rotation == 90) {
|
||||
lv_style_set_pad_left(flex_screen_style, 24);
|
||||
lv_style_set_pad_right(flex_screen_style, 44);
|
||||
} else if (rotation == 270) {
|
||||
lv_style_set_pad_left(flex_screen_style, 44);
|
||||
lv_style_set_pad_right(flex_screen_style, 24);
|
||||
}
|
||||
|
||||
log_info("refreshing objects");
|
||||
lv_obj_report_style_change(&flex_screen_style);
|
||||
lv_obj_report_style_change(&flex_screen_menu_style);
|
||||
}
|
||||
|
||||
uint32_t custom_tick_get(void)
|
||||
{
|
||||
static uint64_t start_ms = 0;
|
||||
|
@ -85,6 +153,16 @@ lv_obj_t *ui_get_obj(const char *name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lv_style_t *ui_get_style(const char *name) {
|
||||
for (size_t i = 0; i < ui_styles_size; i++) {
|
||||
if (strcmp(ui_styles[i].name, name) == 0) {
|
||||
return ui_styles[i].getter();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *ui_get_current_screen() {
|
||||
lv_obj_t *scr = lv_scr_act();
|
||||
if (scr == NULL) {
|
||||
|
|
|
@ -3,11 +3,19 @@
|
|||
|
||||
#include <lvgl.h>
|
||||
|
||||
void lvgl_init(void);
|
||||
typedef void (indev_handler_t)(lv_event_code_t code);
|
||||
|
||||
void lvgl_set_indev_handler(indev_handler_t *handler);
|
||||
|
||||
void lvgl_init(u_int16_t rotation);
|
||||
void lvgl_tick(void);
|
||||
|
||||
void lvgl_set_rotation(lv_display_t *disp, u_int16_t rotation);
|
||||
|
||||
void ui_set_text(const char *name, const char *text);
|
||||
|
||||
lv_obj_t *ui_get_obj(const char *name);
|
||||
lv_style_t *ui_get_style(const char *name);
|
||||
lv_img_dsc_t *ui_get_image(const char *name);
|
||||
|
||||
#endif // SCREEN_H
|
||||
|
|
|
@ -12,6 +12,14 @@ done)
|
|||
|
||||
const int ui_objects_size = sizeof(ui_objects) / sizeof(ui_objects[0]);
|
||||
|
||||
ui_style_map ui_styles[] = {
|
||||
$(grep 'lv_style_t \*get_style_' ui/styles.h | sed 's/lv_style_t \*get_style_//g' | sed 's/_MAIN_DEFAULT();//g' | sed 's/\r//' | while read -r line; do
|
||||
echo " {\"$line\", &get_style_${line}_MAIN_DEFAULT},"
|
||||
done)
|
||||
};
|
||||
|
||||
const int ui_styles_size = sizeof(ui_styles) / sizeof(ui_styles[0]);
|
||||
|
||||
ui_img_map ui_images[] = {
|
||||
$(grep "extern const lv_img_dsc_t " ui/images.h | sed 's/extern const lv_img_dsc_t //g' | sed 's/;//g' | while read -r line; do
|
||||
echo " {\"$line\", &$line},"
|
||||
|
@ -19,6 +27,14 @@ done)
|
|||
};
|
||||
|
||||
const int ui_images_size = sizeof(ui_images) / sizeof(ui_images[0]);
|
||||
|
||||
ui_var_map ui_vars[] = {
|
||||
$(grep 'extern const char \*get_var_' ui/vars.h | sed 's/extern const char \*get_var_//g' | sed 's/();//g' | sed 's/\r//' | while read -r line; do
|
||||
echo " {\"$line\", &get_var_$line, &set_var_$line},"
|
||||
done)
|
||||
};
|
||||
|
||||
const int ui_vars_size = sizeof(ui_vars) / sizeof(ui_vars[0]);
|
||||
EOF
|
||||
|
||||
echo "ui_index.c has been generated successfully."
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include "ui/ui.h"
|
||||
#include "ui/screens.h"
|
||||
#include "ui/styles.h"
|
||||
#include "ui/images.h"
|
||||
#include "ui/vars.h"
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
@ -13,6 +15,14 @@ typedef struct {
|
|||
extern ui_obj_map ui_objects[];
|
||||
extern const int ui_objects_size;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
lv_style_t *(*getter)();
|
||||
} ui_style_map;
|
||||
|
||||
extern ui_style_map ui_styles[];
|
||||
extern const int ui_styles_size;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const lv_img_dsc_t *img; // Pointer to the image descriptor const
|
||||
|
@ -21,5 +31,13 @@ typedef struct {
|
|||
extern ui_img_map ui_images[];
|
||||
extern const int ui_images_size;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *(*getter)();
|
||||
void (*setter)(const char *value);
|
||||
} ui_var_map;
|
||||
|
||||
extern ui_var_map ui_vars[];
|
||||
extern const int ui_vars_size;
|
||||
|
||||
#endif // UI_INDEX_H
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
//go:build linux
|
||||
|
||||
package native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -Llib -ljknative -llvgl
|
||||
#cgo CFLAGS: -Iinclude
|
||||
#include "ctrl.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef const char cchar_t;
|
||||
typedef const uint8_t cuint8_t;
|
||||
|
||||
extern void jetkvm_go_log_handler(int level, cchar_t *filename, cchar_t *funcname, int line, cchar_t *message);
|
||||
static inline void jetkvm_cgo_setup_log_handler() {
|
||||
jetkvm_set_log_handler(&jetkvm_go_log_handler);
|
||||
}
|
||||
|
||||
extern void jetkvm_go_video_state_handler(jetkvm_video_state_t *state);
|
||||
static inline void jetkvm_cgo_setup_video_state_handler() {
|
||||
jetkvm_set_video_state_handler(&jetkvm_go_video_state_handler);
|
||||
}
|
||||
|
||||
extern void jetkvm_go_video_handler(cuint8_t *frame, ssize_t len);
|
||||
static inline void jetkvm_cgo_setup_video_handler() {
|
||||
jetkvm_set_video_handler(&jetkvm_go_video_handler);
|
||||
}
|
||||
|
||||
extern void jetkvm_go_indev_handler(int code);
|
||||
static inline void jetkvm_cgo_setup_indev_handler() {
|
||||
jetkvm_set_indev_handler(&jetkvm_go_indev_handler);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
//export jetkvm_go_video_state_handler
|
||||
func jetkvm_go_video_state_handler(state *C.jetkvm_video_state_t) {
|
||||
videoState := VideoState{
|
||||
Ready: bool(state.ready),
|
||||
Error: C.GoString(state.error),
|
||||
Width: int(state.width),
|
||||
Height: int(state.height),
|
||||
FramePerSecond: float64(state.frame_per_second),
|
||||
}
|
||||
videoStateChan <- videoState
|
||||
}
|
||||
|
||||
//export jetkvm_go_log_handler
|
||||
func jetkvm_go_log_handler(level C.int, filename *C.cchar_t, funcname *C.cchar_t, line C.int, message *C.cchar_t) {
|
||||
logMessage := nativeLogMessage{
|
||||
Level: zerolog.Level(level),
|
||||
Message: C.GoString(message),
|
||||
File: C.GoString(filename),
|
||||
FuncName: C.GoString(funcname),
|
||||
Line: int(line),
|
||||
}
|
||||
|
||||
logChan <- logMessage
|
||||
}
|
||||
|
||||
//export jetkvm_go_video_handler
|
||||
func jetkvm_go_video_handler(frame *C.cuint8_t, len C.ssize_t) {
|
||||
videoFrameChan <- C.GoBytes(unsafe.Pointer(frame), C.int(len))
|
||||
}
|
||||
|
||||
//export jetkvm_go_indev_handler
|
||||
func jetkvm_go_indev_handler(code C.int) {
|
||||
indevEventChan <- int(code)
|
||||
}
|
||||
|
||||
var eventCodeToNameMap = map[int]string{}
|
||||
|
||||
func uiEventCodeToName(code int) string {
|
||||
name, ok := eventCodeToNameMap[code]
|
||||
if !ok {
|
||||
cCode := C.int(code)
|
||||
cName := C.jetkvm_ui_event_code_to_name(cCode)
|
||||
name = C.GoString(cName)
|
||||
eventCodeToNameMap[code] = name
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func setUpNativeHandlers() {
|
||||
C.jetkvm_cgo_setup_log_handler()
|
||||
C.jetkvm_cgo_setup_video_state_handler()
|
||||
C.jetkvm_cgo_setup_video_handler()
|
||||
C.jetkvm_cgo_setup_indev_handler()
|
||||
}
|
||||
|
||||
func uiInit(rotation uint16) {
|
||||
cRotation := C.u_int16_t(rotation)
|
||||
defer C.free(unsafe.Pointer(&cRotation))
|
||||
|
||||
C.jetkvm_ui_init(cRotation)
|
||||
}
|
||||
|
||||
func uiTick() {
|
||||
C.jetkvm_ui_tick()
|
||||
}
|
||||
|
||||
func videoInit() error {
|
||||
ret := C.jetkvm_video_init()
|
||||
if ret != 0 {
|
||||
return fmt.Errorf("failed to initialize video: %d", ret)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func videoShutdown() {
|
||||
C.jetkvm_video_shutdown()
|
||||
}
|
||||
|
||||
func videoStart() {
|
||||
C.jetkvm_video_start()
|
||||
}
|
||||
|
||||
func videoStop() {
|
||||
C.jetkvm_video_stop()
|
||||
}
|
||||
|
||||
func uiSetVar(name string, value string) {
|
||||
nameCStr := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(nameCStr))
|
||||
|
||||
valueCStr := C.CString(value)
|
||||
defer C.free(unsafe.Pointer(valueCStr))
|
||||
|
||||
C.jetkvm_ui_set_var(nameCStr, valueCStr)
|
||||
}
|
||||
|
||||
func uiGetVar(name string) string {
|
||||
nameCStr := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(nameCStr))
|
||||
|
||||
return C.GoString(C.jetkvm_ui_get_var(nameCStr))
|
||||
}
|
||||
|
||||
func uiSwitchToScreen(screen string) {
|
||||
screenCStr := C.CString(screen)
|
||||
defer C.free(unsafe.Pointer(screenCStr))
|
||||
C.jetkvm_ui_load_screen(screenCStr)
|
||||
}
|
||||
|
||||
func uiGetCurrentScreen() string {
|
||||
screenCStr := C.jetkvm_ui_get_current_screen()
|
||||
return C.GoString(screenCStr)
|
||||
}
|
||||
|
||||
func uiObjSetState(objName string, state string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
stateCStr := C.CString(state)
|
||||
defer C.free(unsafe.Pointer(stateCStr))
|
||||
C.jetkvm_ui_set_state(objNameCStr, stateCStr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// TODO: use Enum instead of string but it's not a hot path and performance is not a concern now
|
||||
func uiObjAddFlag(objName string, flag string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
flagCStr := C.CString(flag)
|
||||
defer C.free(unsafe.Pointer(flagCStr))
|
||||
C.jetkvm_ui_add_flag(objNameCStr, flagCStr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uiObjClearFlag(objName string, flag string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
flagCStr := C.CString(flag)
|
||||
defer C.free(unsafe.Pointer(flagCStr))
|
||||
C.jetkvm_ui_clear_flag(objNameCStr, flagCStr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uiObjHide(objName string) (bool, error) {
|
||||
return uiObjAddFlag(objName, "LV_OBJ_FLAG_HIDDEN")
|
||||
}
|
||||
|
||||
func uiObjShow(objName string) (bool, error) {
|
||||
return uiObjClearFlag(objName, "LV_OBJ_FLAG_HIDDEN")
|
||||
}
|
||||
|
||||
func uiObjSetOpacity(objName string, opacity int) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
C.jetkvm_ui_set_opacity(objNameCStr, C.u_int8_t(opacity))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uiObjFadeIn(objName string, duration uint32) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
C.jetkvm_ui_fade_in(objNameCStr, C.u_int32_t(duration))
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uiObjFadeOut(objName string, duration uint32) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
C.jetkvm_ui_fade_out(objNameCStr, C.u_int32_t(duration))
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uiLabelSetText(objName string, text string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
textCStr := C.CString(text)
|
||||
defer C.free(unsafe.Pointer(textCStr))
|
||||
|
||||
ret := C.jetkvm_ui_set_text(objNameCStr, textCStr)
|
||||
if ret < 0 {
|
||||
return false, fmt.Errorf("failed to set text: %d", ret)
|
||||
}
|
||||
return ret == 0, nil
|
||||
}
|
||||
|
||||
func uiImgSetSrc(objName string, src string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
srcCStr := C.CString(src)
|
||||
defer C.free(unsafe.Pointer(srcCStr))
|
||||
|
||||
C.jetkvm_ui_set_image(objNameCStr, srcCStr)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uiDispSetRotation(rotation uint16) (bool, error) {
|
||||
nativeLogger.Info().Uint16("rotation", rotation).Msg("setting rotation")
|
||||
|
||||
cRotation := C.u_int16_t(rotation)
|
||||
defer C.free(unsafe.Pointer(&cRotation))
|
||||
|
||||
C.jetkvm_ui_set_rotation(cRotation)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func videoGetStreamQualityFactor() (float64, error) {
|
||||
factor := C.jetkvm_video_get_quality_factor()
|
||||
return float64(factor), nil
|
||||
}
|
||||
|
||||
func videoSetStreamQualityFactor(factor float64) error {
|
||||
C.jetkvm_video_set_quality_factor(C.float(factor))
|
||||
return nil
|
||||
}
|
||||
|
||||
func videoGetEDID() (string, error) {
|
||||
edidCStr := C.jetkvm_video_get_edid_hex()
|
||||
return C.GoString(edidCStr), nil
|
||||
}
|
||||
|
||||
func videoSetEDID(edid string) error {
|
||||
edidCStr := C.CString(edid)
|
||||
defer C.free(unsafe.Pointer(edidCStr))
|
||||
C.jetkvm_video_set_edid(edidCStr)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
//go:build !linux
|
||||
|
||||
package native
|
||||
|
||||
func panicPlatformNotSupported() {
|
||||
panic("platform not supported")
|
||||
}
|
||||
|
||||
func setUpNativeHandlers() {
|
||||
panicPlatformNotSupported()
|
||||
}
|
||||
|
||||
func uiSetVar(name string, value string) {
|
||||
panicPlatformNotSupported()
|
||||
}
|
||||
|
||||
func uiGetVar(name string) string {
|
||||
panicPlatformNotSupported()
|
||||
return ""
|
||||
}
|
||||
|
||||
func uiSwitchToScreen(screen string) {
|
||||
panicPlatformNotSupported()
|
||||
}
|
||||
|
||||
func uiGetCurrentScreen() string {
|
||||
panicPlatformNotSupported()
|
||||
return ""
|
||||
}
|
||||
|
||||
func uiObjSetState(objName string, state string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjAddFlag(objName string, flag string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjClearFlag(objName string, flag string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjHide(objName string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjShow(objName string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjSetOpacity(objName string, opacity int) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjFadeIn(objName string, duration uint32) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiObjFadeOut(objName string, duration uint32) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiLabelSetText(objName string, text string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiImgSetSrc(objName string, src string) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiDispSetRotation(rotation uint16) (bool, error) {
|
||||
panicPlatformNotSupported()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func uiEventCodeToName(code int) string {
|
||||
panicPlatformNotSupported()
|
||||
return ""
|
||||
}
|
||||
|
||||
func videoGetStreamQualityFactor() (float64, error) {
|
||||
panicPlatformNotSupported()
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func videoSetStreamQualityFactor(factor float64) error {
|
||||
panicPlatformNotSupported()
|
||||
return nil
|
||||
}
|
||||
|
||||
func videoGetEDID() (string, error) {
|
||||
panicPlatformNotSupported()
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func videoSetEDID(edid string) error {
|
||||
panicPlatformNotSupported()
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package native
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
var (
|
||||
videoFrameChan chan []byte = make(chan []byte)
|
||||
videoStateChan chan VideoState = make(chan VideoState)
|
||||
logChan chan nativeLogMessage = make(chan nativeLogMessage)
|
||||
indevEventChan chan int = make(chan int)
|
||||
)
|
||||
|
||||
func (n *Native) handleVideoFrameChan() {
|
||||
lastFrame := time.Now()
|
||||
for {
|
||||
frame := <-videoFrameChan
|
||||
now := time.Now()
|
||||
sinceLastFrame := now.Sub(lastFrame)
|
||||
lastFrame = now
|
||||
n.onVideoFrameReceived(frame, sinceLastFrame)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Native) handleVideoStateChan() {
|
||||
for {
|
||||
state := <-videoStateChan
|
||||
n.onVideoStateChange(state)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Native) handleLogChan() {
|
||||
for {
|
||||
entry := <-logChan
|
||||
l := n.l.With().
|
||||
Str("file", entry.File).
|
||||
Str("func", entry.FuncName).
|
||||
Int("line", entry.Line).
|
||||
Logger()
|
||||
|
||||
switch entry.Level {
|
||||
case zerolog.DebugLevel:
|
||||
l.Debug().Msg(entry.Message)
|
||||
case zerolog.InfoLevel:
|
||||
l.Info().Msg(entry.Message)
|
||||
case zerolog.WarnLevel:
|
||||
l.Warn().Msg(entry.Message)
|
||||
case zerolog.ErrorLevel:
|
||||
l.Error().Msg(entry.Message)
|
||||
case zerolog.PanicLevel:
|
||||
l.Panic().Msg(entry.Message)
|
||||
case zerolog.FatalLevel:
|
||||
l.Fatal().Msg(entry.Message)
|
||||
case zerolog.TraceLevel:
|
||||
l.Trace().Msg(entry.Message)
|
||||
case zerolog.NoLevel:
|
||||
l.Info().Msg(entry.Message)
|
||||
default:
|
||||
l.Info().Msg(entry.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Native) handleIndevEventChan() {
|
||||
for {
|
||||
event := <-indevEventChan
|
||||
name := uiEventCodeToName(event)
|
||||
n.onIndevEvent(name)
|
||||
}
|
||||
}
|
|
@ -1,282 +0,0 @@
|
|||
//go:build linux
|
||||
|
||||
package native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// #cgo LDFLAGS: -Lcgo/build -Lcgo/build/lib -ljknative -llvgl
|
||||
// #cgo CFLAGS: -Icgo -Icgo/ui -Icgo/build/_deps/lvgl-src
|
||||
// #include "ctrl.h"
|
||||
// #include <stdlib.h>
|
||||
// typedef const char cchar_t;
|
||||
// typedef const uint8_t cuint8_t;
|
||||
// extern void jetkvm_video_state_handler(jetkvm_video_state_t *state);
|
||||
// static inline void jetkvm_setup_video_state_handler() {
|
||||
// jetkvm_set_video_state_handler(&jetkvm_video_state_handler);
|
||||
// }
|
||||
// extern void jetkvm_go_log_handler(int level, cchar_t *filename, cchar_t *funcname, int line, cchar_t *message);
|
||||
// static inline void jetkvm_setup_log_handler() {
|
||||
// jetkvm_set_log_handler(&jetkvm_go_log_handler);
|
||||
// }
|
||||
// extern void jetkvm_video_handler(cuint8_t *frame, ssize_t len);
|
||||
// static inline void jetkvm_setup_video_handler() {
|
||||
// jetkvm_set_video_handler(&jetkvm_video_handler);
|
||||
// }
|
||||
import "C"
|
||||
|
||||
var (
|
||||
jkInstance *Native
|
||||
jkInstanceLock sync.RWMutex
|
||||
jkVideoChan chan []byte = make(chan []byte)
|
||||
)
|
||||
|
||||
func setUpJkInstance(instance *Native) {
|
||||
jkInstanceLock.Lock()
|
||||
defer jkInstanceLock.Unlock()
|
||||
|
||||
if jkInstance == nil {
|
||||
jkInstance = instance
|
||||
}
|
||||
|
||||
if jkInstance != instance {
|
||||
panic("jkInstance is already set")
|
||||
}
|
||||
}
|
||||
|
||||
//export jetkvm_video_state_handler
|
||||
func jetkvm_video_state_handler(state *C.jetkvm_video_state_t) {
|
||||
jkInstanceLock.RLock()
|
||||
defer jkInstanceLock.RUnlock()
|
||||
|
||||
if jkInstance != nil {
|
||||
// convert state to VideoState
|
||||
videoState := VideoState{
|
||||
Ready: bool(state.ready),
|
||||
Error: C.GoString(state.error),
|
||||
Width: int(state.width),
|
||||
Height: int(state.height),
|
||||
FramePerSecond: float64(state.frame_per_second),
|
||||
}
|
||||
jkInstance.handleVideoStateMessage(videoState)
|
||||
}
|
||||
}
|
||||
|
||||
//export jetkvm_go_log_handler
|
||||
func jetkvm_go_log_handler(level C.int, filename *C.cchar_t, funcname *C.cchar_t, line C.int, message *C.cchar_t) {
|
||||
l := nativeLogger.With().
|
||||
Str("file", C.GoString(filename)).
|
||||
Str("function", C.GoString(funcname)).
|
||||
Int("line", int(line)).
|
||||
Logger()
|
||||
|
||||
gLevel := zerolog.Level(level)
|
||||
switch gLevel {
|
||||
case zerolog.DebugLevel:
|
||||
l.Debug().Msg(C.GoString(message))
|
||||
case zerolog.InfoLevel:
|
||||
l.Info().Msg(C.GoString(message))
|
||||
case zerolog.WarnLevel:
|
||||
l.Warn().Msg(C.GoString(message))
|
||||
case zerolog.ErrorLevel:
|
||||
l.Error().Msg(C.GoString(message))
|
||||
case zerolog.PanicLevel:
|
||||
l.Panic().Msg(C.GoString(message))
|
||||
case zerolog.FatalLevel:
|
||||
l.Fatal().Msg(C.GoString(message))
|
||||
case zerolog.TraceLevel:
|
||||
l.Trace().Msg(C.GoString(message))
|
||||
case zerolog.NoLevel:
|
||||
l.Info().Msg(C.GoString(message))
|
||||
default:
|
||||
l.Info().Msg(C.GoString(message))
|
||||
}
|
||||
}
|
||||
|
||||
//export jetkvm_video_handler
|
||||
func jetkvm_video_handler(frame *C.cuint8_t, len C.ssize_t) {
|
||||
jkVideoChan <- C.GoBytes(unsafe.Pointer(frame), C.int(len))
|
||||
}
|
||||
|
||||
func setVideoStateHandler() {
|
||||
C.jetkvm_setup_video_state_handler()
|
||||
}
|
||||
|
||||
func setLogHandler() {
|
||||
C.jetkvm_setup_log_handler()
|
||||
}
|
||||
|
||||
func setVideoHandler() {
|
||||
C.jetkvm_setup_video_handler()
|
||||
}
|
||||
|
||||
func (n *Native) StartNativeVideo() {
|
||||
setUpJkInstance(n)
|
||||
|
||||
setVideoStateHandler()
|
||||
setLogHandler()
|
||||
setVideoHandler()
|
||||
|
||||
C.jetkvm_set_app_version(C.CString(n.appVersion.String()))
|
||||
|
||||
C.jetkvm_ui_init()
|
||||
|
||||
n.UpdateLabelIfChanged("boot_screen_version", n.appVersion.String())
|
||||
|
||||
go func() {
|
||||
for {
|
||||
C.jetkvm_ui_tick()
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
}()
|
||||
|
||||
if C.jetkvm_video_init() != 0 {
|
||||
nativeLogger.Error().Msg("failed to initialize video")
|
||||
return
|
||||
}
|
||||
|
||||
C.jetkvm_video_start()
|
||||
|
||||
close(n.ready)
|
||||
}
|
||||
|
||||
func (n *Native) StopNativeVideo() {
|
||||
C.jetkvm_video_stop()
|
||||
}
|
||||
|
||||
func (n *Native) SwitchToScreen(screen string) {
|
||||
screenCStr := C.CString(screen)
|
||||
defer C.free(unsafe.Pointer(screenCStr))
|
||||
C.jetkvm_ui_load_screen(screenCStr)
|
||||
}
|
||||
|
||||
func (n *Native) GetCurrentScreen() string {
|
||||
screenCStr := C.jetkvm_ui_get_current_screen()
|
||||
return C.GoString(screenCStr)
|
||||
}
|
||||
|
||||
func (n *Native) ObjSetState(objName string, state string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
stateCStr := C.CString(state)
|
||||
defer C.free(unsafe.Pointer(stateCStr))
|
||||
C.jetkvm_ui_set_state(objNameCStr, stateCStr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjAddFlag(objName string, flag string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
flagCStr := C.CString(flag)
|
||||
defer C.free(unsafe.Pointer(flagCStr))
|
||||
C.jetkvm_ui_add_flag(objNameCStr, flagCStr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjClearFlag(objName string, flag string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
flagCStr := C.CString(flag)
|
||||
defer C.free(unsafe.Pointer(flagCStr))
|
||||
C.jetkvm_ui_clear_flag(objNameCStr, flagCStr)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjHide(objName string) (bool, error) {
|
||||
return n.ObjAddFlag(objName, "LV_OBJ_FLAG_HIDDEN")
|
||||
}
|
||||
|
||||
func (n *Native) ObjShow(objName string) (bool, error) {
|
||||
return n.ObjClearFlag(objName, "LV_OBJ_FLAG_HIDDEN")
|
||||
}
|
||||
|
||||
func (n *Native) ObjSetOpacity(objName string, opacity int) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
C.jetkvm_ui_set_opacity(objNameCStr, C.u_int8_t(opacity))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjFadeIn(objName string, duration uint32) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
C.jetkvm_ui_fade_in(objNameCStr, C.u_int32_t(duration))
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjFadeOut(objName string, duration uint32) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
C.jetkvm_ui_fade_out(objNameCStr, C.u_int32_t(duration))
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) LabelSetText(objName string, text string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
textCStr := C.CString(text)
|
||||
defer C.free(unsafe.Pointer(textCStr))
|
||||
|
||||
ret := C.jetkvm_ui_set_text(objNameCStr, textCStr)
|
||||
if ret < 0 {
|
||||
return false, fmt.Errorf("failed to set text: %d", ret)
|
||||
}
|
||||
return ret == 0, nil
|
||||
}
|
||||
|
||||
func (n *Native) ImgSetSrc(objName string, src string) (bool, error) {
|
||||
objNameCStr := C.CString(objName)
|
||||
defer C.free(unsafe.Pointer(objNameCStr))
|
||||
|
||||
srcCStr := C.CString(src)
|
||||
defer C.free(unsafe.Pointer(srcCStr))
|
||||
|
||||
C.jetkvm_ui_set_image(objNameCStr, srcCStr)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) DispSetRotation(rotation string) (bool, error) {
|
||||
rotationInt, err := strconv.Atoi(rotation)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
nativeLogger.Info().Int("rotation", rotationInt).Msg("setting rotation")
|
||||
// C.jetkvm_ui_set_rotation(C.u_int8_t(rotationInt))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (n *Native) GetStreamQualityFactor() (float64, error) {
|
||||
factor := C.jetkvm_video_get_quality_factor()
|
||||
return float64(factor), nil
|
||||
}
|
||||
|
||||
func (n *Native) SetStreamQualityFactor(factor float64) error {
|
||||
C.jetkvm_video_set_quality_factor(C.float(factor))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Native) GetEDID() (string, error) {
|
||||
edidCStr := C.jetkvm_video_get_edid_hex()
|
||||
return C.GoString(edidCStr), nil
|
||||
}
|
||||
|
||||
func (n *Native) SetEDID(edid string) error {
|
||||
edidCStr := C.CString(edid)
|
||||
defer C.free(unsafe.Pointer(edidCStr))
|
||||
C.jetkvm_video_set_edid(edidCStr)
|
||||
return nil
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
//go:build !linux
|
||||
|
||||
package native
|
||||
|
||||
func panicNotImplemented() {
|
||||
panic("not supported")
|
||||
}
|
||||
|
||||
func (n *Native) StartNativeVideo() {
|
||||
panicNotImplemented()
|
||||
}
|
||||
|
||||
func (n *Native) StopNativeVideo() {
|
||||
panicNotImplemented()
|
||||
}
|
||||
|
||||
func (n *Native) SwitchToScreen(screen string) {
|
||||
panicNotImplemented()
|
||||
}
|
||||
|
||||
func (n *Native) GetCurrentScreen() string {
|
||||
panicNotImplemented()
|
||||
}
|
||||
|
||||
func (n *Native) ObjSetState(objName string, state string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjAddFlag(objName string, flag string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjClearFlag(objName string, flag string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjHide(objName string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjShow(objName string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjSetOpacity(objName string, opacity int) (bool, error) { // nolint:unused
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjFadeIn(objName string, duration uint32) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ObjFadeOut(objName string, duration uint32) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) LabelSetText(objName string, text string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) ImgSetSrc(objName string, src string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) DispSetRotation(rotation string) (bool, error) {
|
||||
panicNotImplemented()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (n *Native) GetStreamQualityFactor() (float64, error) {
|
||||
panicNotImplemented()
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (n *Native) SetStreamQualityFactor(factor float64) error {
|
||||
panicNotImplemented()
|
||||
return nil
|
||||
}
|
|
@ -1,11 +1,75 @@
|
|||
package native
|
||||
|
||||
import "slices"
|
||||
import (
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (n *Native) setUIVars() {
|
||||
uiSetVar("app_version", n.appVersion.String())
|
||||
uiSetVar("system_version", n.systemVersion.String())
|
||||
}
|
||||
|
||||
func (n *Native) initUI() {
|
||||
uiInit(n.displayRotation)
|
||||
n.setUIVars()
|
||||
}
|
||||
|
||||
func (n *Native) tickUI() {
|
||||
for {
|
||||
uiTick()
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Native) UIObjHide(objName string) (bool, error) {
|
||||
return uiObjHide(objName)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjShow(objName string) (bool, error) {
|
||||
return uiObjShow(objName)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjSetState(objName string, state string) (bool, error) {
|
||||
return uiObjSetState(objName, state)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjAddFlag(objName string, flag string) (bool, error) {
|
||||
return uiObjAddFlag(objName, flag)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjClearFlag(objName string, flag string) (bool, error) {
|
||||
return uiObjClearFlag(objName, flag)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjSetOpacity(objName string, opacity int) (bool, error) {
|
||||
return uiObjSetOpacity(objName, opacity)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjFadeIn(objName string, duration uint32) (bool, error) {
|
||||
return uiObjFadeIn(objName, duration)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjFadeOut(objName string, duration uint32) (bool, error) {
|
||||
return uiObjFadeOut(objName, duration)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjSetLabelText(objName string, text string) (bool, error) {
|
||||
return uiLabelSetText(objName, text)
|
||||
}
|
||||
|
||||
func (n *Native) UIObjSetImageSrc(objName string, image string) (bool, error) {
|
||||
return uiImgSetSrc(objName, image)
|
||||
}
|
||||
|
||||
func (n *Native) DisplaySetRotation(rotation uint16) (bool, error) {
|
||||
return uiDispSetRotation(rotation)
|
||||
}
|
||||
|
||||
func (n *Native) UpdateLabelIfChanged(objName string, newText string) {
|
||||
l := n.lD.Trace().Str("obj", objName).Str("text", newText)
|
||||
|
||||
changed, err := n.LabelSetText(objName, newText)
|
||||
changed, err := n.UIObjSetLabelText(objName, newText)
|
||||
if err != nil {
|
||||
n.lD.Warn().Str("obj", objName).Str("text", newText).Err(err).Msg("failed to update label")
|
||||
return
|
||||
|
@ -21,27 +85,27 @@ func (n *Native) UpdateLabelIfChanged(objName string, newText string) {
|
|||
func (n *Native) UpdateLabelAndChangeVisibility(objName string, newText string) {
|
||||
containerName := objName + "_container"
|
||||
if newText == "" {
|
||||
_, _ = n.ObjHide(objName)
|
||||
_, _ = n.ObjHide(containerName)
|
||||
_, _ = n.UIObjHide(objName)
|
||||
_, _ = n.UIObjHide(containerName)
|
||||
} else {
|
||||
_, _ = n.ObjShow(objName)
|
||||
_, _ = n.ObjShow(containerName)
|
||||
_, _ = n.UIObjShow(objName)
|
||||
_, _ = n.UIObjShow(containerName)
|
||||
}
|
||||
|
||||
n.UpdateLabelIfChanged(objName, newText)
|
||||
}
|
||||
|
||||
func (n *Native) SwitchToScreenIf(screenName string, shouldSwitch []string) {
|
||||
currentScreen := n.GetCurrentScreen()
|
||||
currentScreen := uiGetCurrentScreen()
|
||||
if currentScreen == screenName {
|
||||
return
|
||||
}
|
||||
if !slices.Contains(shouldSwitch, currentScreen) {
|
||||
displayLogger.Trace().Str("from", currentScreen).Str("to", screenName).Msg("skipping screen switch")
|
||||
n.lD.Trace().Str("from", currentScreen).Str("to", screenName).Msg("skipping screen switch")
|
||||
return
|
||||
}
|
||||
displayLogger.Info().Str("from", currentScreen).Str("to", screenName).Msg("switching screen")
|
||||
n.SwitchToScreen(screenName)
|
||||
n.lD.Info().Str("from", currentScreen).Str("to", screenName).Msg("switching screen")
|
||||
uiSwitchToScreen(screenName)
|
||||
}
|
||||
|
||||
func (n *Native) SwitchToScreenIfDifferent(screenName string) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"navigation": {
|
||||
"selectedUserPageObject": "[jetkvm.eez-project]:/userPages/0",
|
||||
"selectedUserWidgetObject": "[jetkvm.eez-project]:/userWidgets/-1",
|
||||
"selectedActionObject": "[jetkvm.eez-project]:/actions/7",
|
||||
"selectedGlobalVariableObject": "[jetkvm.eez-project]:/variables/globalVariables/0",
|
||||
"selectedUserPageObject": "[jetkvm.eez-project]:/userPages/5",
|
||||
"selectedActionObject": "[jetkvm.eez-project]:/actions/0",
|
||||
"selectedGlobalVariableObject": "[jetkvm.eez-project]:/variables/globalVariables/1",
|
||||
"selectedStyleObject": "[jetkvm.eez-project]:/lvglStyles/styles/0",
|
||||
"selectedThemeObject": "[jetkvm.eez-project]:/themes/0",
|
||||
"selectedFontObject": "[jetkvm.eez-project]:/fonts/1",
|
||||
"selectedFontObject": "[jetkvm.eez-project]:/fonts/4",
|
||||
"selectedBitmapObject": "[jetkvm.eez-project]:/bitmaps/11",
|
||||
"subnavigationSelectedItems": {
|
||||
"variables-tab/sub-navigation/selected-item": "Global"
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
|||
},
|
||||
{
|
||||
"type": "border",
|
||||
"selected": 4,
|
||||
"selected": 2,
|
||||
"size": 113.5,
|
||||
"location": "right",
|
||||
"children": [
|
||||
|
@ -77,7 +77,7 @@
|
|||
},
|
||||
{
|
||||
"type": "border",
|
||||
"selected": 0,
|
||||
"selected": 1,
|
||||
"location": "bottom",
|
||||
"children": [
|
||||
{
|
||||
|
@ -130,7 +130,6 @@
|
|||
"type": "tabset",
|
||||
"id": "#2e3d9a08-c69c-42b5-b434-525109f2a5a7",
|
||||
"weight": 1,
|
||||
"selected": 1,
|
||||
"enableClose": false,
|
||||
"children": [
|
||||
{
|
||||
|
@ -189,7 +188,8 @@
|
|||
"enableClose": false,
|
||||
"icon": "svg:variable"
|
||||
}
|
||||
]
|
||||
],
|
||||
"active": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -197,46 +197,46 @@
|
|||
"type": "tabset",
|
||||
"id": "EDITORS",
|
||||
"weight": 49.31058517127421,
|
||||
"selected": 1,
|
||||
"selected": 4,
|
||||
"enableDeleteWhenEmpty": false,
|
||||
"enableClose": false,
|
||||
"children": [
|
||||
{
|
||||
"type": "tab",
|
||||
"id": "#467ae6a9-0f08-4392-a580-25f8916524e4",
|
||||
"name": "BootScreen",
|
||||
"id": "#aec56ae8-5b75-4a2f-ad81-f0d7d683c77a",
|
||||
"name": "FontBook24",
|
||||
"component": "editor",
|
||||
"config": {
|
||||
"objectPath": "[jetkvm.eez-project]:/userPages/0",
|
||||
"objectPath": "[jetkvm.eez-project]:/fonts/4",
|
||||
"permanent": false
|
||||
},
|
||||
"icon": "material:font_download"
|
||||
},
|
||||
{
|
||||
"type": "tab",
|
||||
"id": "#c8dece00-e490-46b8-8a14-5dcfa8bbce36",
|
||||
"name": "AboutScreen",
|
||||
"component": "editor",
|
||||
"config": {
|
||||
"objectPath": "[jetkvm.eez-project]:/userPages/5",
|
||||
"permanent": false
|
||||
},
|
||||
"icon": "svg:page"
|
||||
},
|
||||
{
|
||||
"type": "tab",
|
||||
"id": "#d1704ae1-993d-4a7d-bade-0903bb61e9c6",
|
||||
"name": "AboutScreen",
|
||||
"id": "#e9afee88-d3be-4069-aa77-22930d1efcf3",
|
||||
"name": "HomeScreen",
|
||||
"component": "editor",
|
||||
"config": {
|
||||
"objectPath": "[jetkvm.eez-project]:/userPages/5",
|
||||
"objectPath": "[jetkvm.eez-project]:/userPages/1",
|
||||
"permanent": true
|
||||
},
|
||||
"icon": "svg:page"
|
||||
},
|
||||
{
|
||||
"type": "tab",
|
||||
"id": "#b444e818-4663-4332-ab40-a34acb670c8c",
|
||||
"name": "MenuAdvancedScreen",
|
||||
"component": "editor",
|
||||
"config": {
|
||||
"objectPath": "[jetkvm.eez-project]:/userPages/4",
|
||||
"permanent": true
|
||||
},
|
||||
"icon": "svg:page"
|
||||
},
|
||||
{
|
||||
"type": "tab",
|
||||
"id": "#f8258cf3-e12a-4be9-8021-33199674dbe6",
|
||||
"id": "#f5a057a5-977c-46be-8702-5447d603a34f",
|
||||
"name": "MenuScreen",
|
||||
"component": "editor",
|
||||
"config": {
|
||||
|
@ -247,7 +247,7 @@
|
|||
},
|
||||
{
|
||||
"type": "tab",
|
||||
"id": "#5dcfc8a4-36a7-4dea-a0cc-8dbeb4aab914",
|
||||
"id": "#8af97439-79ee-4705-be34-53ca8814f3a0",
|
||||
"name": "Settings",
|
||||
"component": "editor",
|
||||
"config": {
|
||||
|
@ -257,8 +257,7 @@
|
|||
},
|
||||
"icon": "material:settings"
|
||||
}
|
||||
],
|
||||
"active": true
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "row",
|
||||
|
@ -1066,7 +1065,8 @@
|
|||
"0": {
|
||||
"0": {
|
||||
"0": {
|
||||
"1": {}
|
||||
"1": {},
|
||||
"$selected": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1090,6 +1090,7 @@
|
|||
"0": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": {},
|
||||
"1": {
|
||||
"0": {}
|
||||
}
|
||||
|
@ -1101,7 +1102,9 @@
|
|||
"3": {
|
||||
"0": {
|
||||
"0": {},
|
||||
"1": {}
|
||||
"1": {
|
||||
"$selected": true
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"0": {},
|
||||
|
@ -1154,8 +1157,8 @@
|
|||
},
|
||||
"transform": {
|
||||
"translate": {
|
||||
"x": -194,
|
||||
"y": -454
|
||||
"x": -230,
|
||||
"y": -94
|
||||
},
|
||||
"scale": 1
|
||||
},
|
||||
|
@ -1171,9 +1174,8 @@
|
|||
"0": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": {
|
||||
"$selected": true
|
||||
}
|
||||
"0": {},
|
||||
"$selected": true
|
||||
},
|
||||
"1": {
|
||||
"0": {
|
||||
|
@ -1201,11 +1203,28 @@
|
|||
}
|
||||
},
|
||||
"[jetkvm.eez-project]:/userPages/4[flow-state]": {
|
||||
"selection": {},
|
||||
"selection": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": {
|
||||
"$selected": true
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"0": {
|
||||
"0": {},
|
||||
"1": {},
|
||||
"2": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"transform": {
|
||||
"translate": {
|
||||
"x": -150,
|
||||
"y": -120
|
||||
"x": -176,
|
||||
"y": -127
|
||||
},
|
||||
"scale": 1
|
||||
},
|
||||
|
@ -1226,12 +1245,19 @@
|
|||
"1": {
|
||||
"0": {
|
||||
"0": {},
|
||||
"1": {},
|
||||
"1": {
|
||||
"1": {}
|
||||
},
|
||||
"2": {},
|
||||
"3": {},
|
||||
"4": {},
|
||||
"5": {},
|
||||
"6": {}
|
||||
"5": {
|
||||
"1": {
|
||||
"$selected": true
|
||||
}
|
||||
},
|
||||
"6": {},
|
||||
"7": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1266,6 +1292,38 @@
|
|||
"secondToPx": 200,
|
||||
"scrollLeft": 0
|
||||
}
|
||||
},
|
||||
"[jetkvm.eez-project]:/userPages/6[flow-state]": {
|
||||
"selection": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": {},
|
||||
"1": {
|
||||
"0": {
|
||||
"0": {},
|
||||
"2": {
|
||||
"1": {
|
||||
"$selected": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"transform": {
|
||||
"translate": {
|
||||
"x": -138,
|
||||
"y": -122
|
||||
},
|
||||
"scale": 1
|
||||
},
|
||||
"timeline": {
|
||||
"isEditorActive": false,
|
||||
"position": 0,
|
||||
"secondToPx": 200,
|
||||
"scrollLeft": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"activeOutputSection": 0,
|
||||
|
@ -1281,13 +1339,10 @@
|
|||
"logsPanelFilter": "all",
|
||||
"selectedStylePropertyName": "",
|
||||
"lvglPart": "MAIN",
|
||||
"lvglState": "DEFAULT",
|
||||
"lvglState": "DISABLED",
|
||||
"lvglExpandedPropertiesGroup": [
|
||||
"POSITION AND SIZE",
|
||||
"PADDING",
|
||||
"MARGIN",
|
||||
"TEXT",
|
||||
"BACKGROUND"
|
||||
"TEXT"
|
||||
],
|
||||
"showInactiveFlowsInDebugger": true,
|
||||
"globalFlowZoom": true,
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
package native
|
||||
|
||||
import "github.com/jetkvm/kvm/internal/logging"
|
||||
import (
|
||||
"github.com/jetkvm/kvm/internal/logging"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
var nativeLogger = logging.GetSubsystemLogger("native")
|
||||
var displayLogger = logging.GetSubsystemLogger("display")
|
||||
|
||||
type nativeLogMessage struct {
|
||||
Level zerolog.Level
|
||||
Message string
|
||||
File string
|
||||
FuncName string
|
||||
Line int
|
||||
}
|
||||
|
|
|
@ -13,15 +13,19 @@ type Native struct {
|
|||
lD *zerolog.Logger
|
||||
systemVersion *semver.Version
|
||||
appVersion *semver.Version
|
||||
displayRotation uint16
|
||||
onVideoStateChange func(state VideoState)
|
||||
onVideoFrameReceived func(frame []byte, duration time.Duration)
|
||||
onIndevEvent func(event string)
|
||||
}
|
||||
|
||||
type NativeOptions struct {
|
||||
SystemVersion *semver.Version
|
||||
AppVersion *semver.Version
|
||||
DisplayRotation uint16
|
||||
OnVideoStateChange func(state VideoState)
|
||||
OnVideoFrameReceived func(frame []byte, duration time.Duration)
|
||||
OnIndevEvent func(event string)
|
||||
}
|
||||
|
||||
func NewNative(opts NativeOptions) *Native {
|
||||
|
@ -39,123 +43,39 @@ func NewNative(opts NativeOptions) *Native {
|
|||
}
|
||||
}
|
||||
|
||||
onIndevEvent := opts.OnIndevEvent
|
||||
if onIndevEvent == nil {
|
||||
onIndevEvent = func(event string) {
|
||||
nativeLogger.Info().Str("event", event).Msg("indev event")
|
||||
}
|
||||
}
|
||||
|
||||
return &Native{
|
||||
ready: make(chan struct{}),
|
||||
l: nativeLogger,
|
||||
lD: displayLogger,
|
||||
systemVersion: opts.SystemVersion,
|
||||
appVersion: opts.AppVersion,
|
||||
displayRotation: opts.DisplayRotation,
|
||||
onVideoStateChange: opts.OnVideoStateChange,
|
||||
onVideoFrameReceived: opts.OnVideoFrameReceived,
|
||||
onIndevEvent: opts.OnIndevEvent,
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Native) Start() {
|
||||
go n.StartNativeVideo()
|
||||
go n.HandleVideoChan()
|
||||
// set up singleton
|
||||
setInstance(n)
|
||||
setUpNativeHandlers()
|
||||
|
||||
// start the native video
|
||||
go n.handleLogChan()
|
||||
go n.handleVideoStateChan()
|
||||
go n.handleVideoFrameChan()
|
||||
go n.handleIndevEventChan()
|
||||
|
||||
n.initUI()
|
||||
go n.tickUI()
|
||||
|
||||
close(n.ready)
|
||||
}
|
||||
|
||||
func (n *Native) HandleVideoChan() {
|
||||
lastFrame := time.Now()
|
||||
|
||||
for {
|
||||
frame := <-jkVideoChan
|
||||
now := time.Now()
|
||||
sinceLastFrame := now.Sub(lastFrame)
|
||||
lastFrame = now
|
||||
n.onVideoFrameReceived(frame, sinceLastFrame)
|
||||
}
|
||||
}
|
||||
|
||||
// func handleCtrlClient(conn net.Conn) {
|
||||
// defer conn.Close()
|
||||
|
||||
// scopedLogger := nativeLogger.With().
|
||||
// Str("addr", conn.RemoteAddr().String()).
|
||||
// Str("type", "ctrl").
|
||||
// Logger()
|
||||
|
||||
// scopedLogger.Info().Msg("native ctrl socket client connected")
|
||||
// if ctrlSocketConn != nil {
|
||||
// scopedLogger.Debug().Msg("closing existing native socket connection")
|
||||
// ctrlSocketConn.Close()
|
||||
// }
|
||||
|
||||
// ctrlSocketConn = conn
|
||||
|
||||
// // Restore HDMI EDID if applicable
|
||||
// go restoreHdmiEdid()
|
||||
|
||||
// readBuf := make([]byte, 4096)
|
||||
// for {
|
||||
// n, err := conn.Read(readBuf)
|
||||
// if err != nil {
|
||||
// scopedLogger.Warn().Err(err).Msg("error reading from ctrl sock")
|
||||
// break
|
||||
// }
|
||||
// readMsg := string(readBuf[:n])
|
||||
|
||||
// ctrlResp := CtrlResponse{}
|
||||
// err = json.Unmarshal([]byte(readMsg), &ctrlResp)
|
||||
// if err != nil {
|
||||
// scopedLogger.Warn().Err(err).Str("data", readMsg).Msg("error parsing ctrl sock msg")
|
||||
// continue
|
||||
// }
|
||||
// scopedLogger.Trace().Interface("data", ctrlResp).Msg("ctrl sock msg")
|
||||
|
||||
// if ctrlResp.Seq != 0 {
|
||||
// responseChan, ok := ongoingRequests[ctrlResp.Seq]
|
||||
// if ok {
|
||||
// responseChan <- &ctrlResp
|
||||
// }
|
||||
// }
|
||||
// switch ctrlResp.Event {
|
||||
// case "video_input_state":
|
||||
// HandleVideoStateMessage(ctrlResp)
|
||||
// }
|
||||
// }
|
||||
|
||||
// scopedLogger.Debug().Msg("ctrl sock disconnected")
|
||||
// }
|
||||
|
||||
// func handleVideoClient(conn net.Conn) {
|
||||
// defer conn.Close()
|
||||
|
||||
// scopedLogger := nativeLogger.With().
|
||||
// Str("addr", conn.RemoteAddr().String()).
|
||||
// Str("type", "video").
|
||||
// Logger()
|
||||
|
||||
// scopedLogger.Info().Msg("native video socket client connected")
|
||||
|
||||
// inboundPacket := make([]byte, maxFrameSize)
|
||||
// lastFrame := time.Now()
|
||||
// for {
|
||||
// n, err := conn.Read(inboundPacket)
|
||||
// if err != nil {
|
||||
// scopedLogger.Warn().Err(err).Msg("error during read")
|
||||
// return
|
||||
// }
|
||||
// now := time.Now()
|
||||
// sinceLastFrame := now.Sub(lastFrame)
|
||||
// lastFrame = now
|
||||
// if currentSession != nil {
|
||||
// err := currentSession.VideoTrack.WriteSample(media.Sample{Data: inboundPacket[:n], Duration: sinceLastFrame})
|
||||
// if err != nil {
|
||||
// scopedLogger.Warn().Err(err).Msg("error writing sample")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Restore the HDMI EDID value from the config.
|
||||
// // Called after successful connection to jetkvm_native.
|
||||
// func restoreHdmiEdid() {
|
||||
// if config.EdidString != "" {
|
||||
// nativeLogger.Info().Str("edid", config.EdidString).Msg("Restoring HDMI EDID")
|
||||
// _, err := CallCtrlAction("set_edid", map[string]interface{}{"edid": config.EdidString})
|
||||
// if err != nil {
|
||||
// nativeLogger.Warn().Err(err).Msg("Failed to restore HDMI EDID")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package native
|
||||
|
||||
import "sync"
|
||||
|
||||
var (
|
||||
instance *Native
|
||||
instanceLock sync.RWMutex
|
||||
)
|
||||
|
||||
func setInstance(n *Native) {
|
||||
instanceLock.Lock()
|
||||
defer instanceLock.Unlock()
|
||||
|
||||
if instance == nil {
|
||||
instance = n
|
||||
}
|
||||
|
||||
if instance != n {
|
||||
panic("instance is already set")
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package native
|
||||
|
||||
import "fmt"
|
||||
|
||||
type VideoState struct {
|
||||
Ready bool `json:"ready"`
|
||||
Error string `json:"error,omitempty"` //no_signal, no_lock, out_of_range
|
||||
|
@ -10,7 +8,18 @@ type VideoState struct {
|
|||
FramePerSecond float64 `json:"fps"`
|
||||
}
|
||||
|
||||
func (n *Native) handleVideoStateMessage(state VideoState) {
|
||||
nativeLogger.Info().Msg("video state handler")
|
||||
nativeLogger.Info().Msg(fmt.Sprintf("state: %+v", state))
|
||||
func (n *Native) VideoSetQualityFactor(factor float64) error {
|
||||
return videoSetStreamQualityFactor(factor)
|
||||
}
|
||||
|
||||
func (n *Native) VideoGetQualityFactor() (float64, error) {
|
||||
return videoGetStreamQualityFactor()
|
||||
}
|
||||
|
||||
func (n *Native) VideoSetEDID(edid string) error {
|
||||
return videoSetEDID(edid)
|
||||
}
|
||||
|
||||
func (n *Native) VideoGetEDID() (string, error) {
|
||||
return videoGetEDID()
|
||||
}
|
||||
|
|
31
jsonrpc.go
31
jsonrpc.go
|
@ -200,7 +200,7 @@ func rpcGetStreamQualityFactor() (float64, error) {
|
|||
|
||||
func rpcSetStreamQualityFactor(factor float64) error {
|
||||
logger.Info().Float64("factor", factor).Msg("Setting stream quality factor")
|
||||
err := nativeInstance.SetStreamQualityFactor(factor)
|
||||
err := nativeInstance.VideoSetQualityFactor(factor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ func rpcSetAutoUpdateState(enabled bool) (bool, error) {
|
|||
}
|
||||
|
||||
func rpcGetEDID() (string, error) {
|
||||
resp, err := nativeInstance.GetEDID()
|
||||
resp, err := nativeInstance.VideoGetEDID()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ func rpcSetEDID(edid string) error {
|
|||
} else {
|
||||
logger.Info().Str("edid", edid).Msg("Setting EDID")
|
||||
}
|
||||
err := nativeInstance.SetEDID(edid)
|
||||
err := nativeInstance.VideoSetEDID(edid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -286,14 +286,25 @@ func rpcTryUpdate() error {
|
|||
}
|
||||
|
||||
func rpcSetDisplayRotation(params DisplayRotationSettings) error {
|
||||
var err error
|
||||
_, err = nativeInstance.DispSetRotation(params.Rotation)
|
||||
if err == nil {
|
||||
config.DisplayRotation = params.Rotation
|
||||
if err := SaveConfig(); err != nil {
|
||||
return fmt.Errorf("failed to save config: %w", err)
|
||||
}
|
||||
currentRotation := config.DisplayRotation
|
||||
if currentRotation == params.Rotation {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := config.SetDisplayRotation(params.Rotation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = nativeInstance.DisplaySetRotation(config.GetDisplayRotation())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := SaveConfig(); err != nil {
|
||||
return fmt.Errorf("failed to save config: %w", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
10
native.go
10
native.go
|
@ -11,14 +11,20 @@ import (
|
|||
var nativeInstance *native.Native
|
||||
|
||||
func initNative(systemVersion *semver.Version, appVersion *semver.Version) {
|
||||
|
||||
nativeInstance = native.NewNative(native.NativeOptions{
|
||||
SystemVersion: systemVersion,
|
||||
AppVersion: appVersion,
|
||||
SystemVersion: systemVersion,
|
||||
AppVersion: appVersion,
|
||||
DisplayRotation: config.GetDisplayRotation(),
|
||||
OnVideoStateChange: func(state native.VideoState) {
|
||||
lastVideoState = state
|
||||
triggerVideoStateUpdate()
|
||||
requestDisplayUpdate(true)
|
||||
},
|
||||
OnIndevEvent: func(event string) {
|
||||
nativeLogger.Trace().Str("event", event).Msg("indev event received")
|
||||
wakeDisplay(false)
|
||||
},
|
||||
OnVideoFrameReceived: func(frame []byte, duration time.Duration) {
|
||||
if currentSession != nil {
|
||||
err := currentSession.VideoTrack.WriteSample(media.Sample{Data: frame, Duration: duration})
|
||||
|
|
Loading…
Reference in New Issue