From 3fa3af2d5bae0c0fdf04dcb5e3690c4630f7bca6 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Tue, 24 Jun 2025 07:10:54 +0000 Subject: [PATCH] refactor functions --- display.go | 28 +-- internal/native/cgo/ctrl.c | 22 +- internal/native/cgo/ctrl.h | 3 +- internal/native/cgo/ui_index.gen.sh | 8 + internal/native/cgo/ui_index.h | 9 + internal/native/ctrl_linux.go | 282 ------------------------- internal/native/ctrl_notlinux.go | 88 -------- internal/native/display.go | 83 +++++++- internal/native/eez/jetkvm.eez-project | 24 ++- internal/native/log.go | 13 +- internal/native/native.go | 120 ++--------- internal/native/video.go | 19 +- jsonrpc.go | 8 +- 13 files changed, 185 insertions(+), 522 deletions(-) delete mode 100644 internal/native/ctrl_linux.go delete mode 100644 internal/native/ctrl_notlinux.go diff --git a/display.go b/display.go index 1c2bd48..3e4403c 100644 --- a/display.go +++ b/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) } }() @@ -347,7 +347,7 @@ func initDisplay() { go func() { displayLogger.Info().Msg("setting initial display contents") time.Sleep(500 * time.Millisecond) - _, _ = nativeInstance.DispSetRotation(config.DisplayRotation) + _, _ = nativeInstance.DisplaySetRotation(config.DisplayRotation) updateStaticContents() displayInited = true displayLogger.Info().Msg("display inited") diff --git a/internal/native/cgo/ctrl.c b/internal/native/cgo/ctrl.c index ef8bd6f..ed999d9 100644 --- a/internal/native/cgo/ctrl.c +++ b/internal/native/cgo/ctrl.c @@ -12,7 +12,7 @@ #include "edid.h" #include "ctrl.h" #include -#include "ui/vars.h" +#include "ui_index.h" #include "log.h" #include "log_handler.h" @@ -154,8 +154,24 @@ 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); +} + +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() { diff --git a/internal/native/cgo/ctrl.h b/internal/native/cgo/ctrl.h index 80c8ab4..25d5890 100644 --- a/internal/native/cgo/ctrl.h +++ b/internal/native/cgo/ctrl.h @@ -22,7 +22,8 @@ typedef void (jetkvm_video_handler_t)(const uint8_t *frame, ssize_t len); 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_set_var(const char *name, const char *value); +const char *jetkvm_ui_get_var(const char *name); void jetkvm_ui_init(); void jetkvm_ui_tick(); diff --git a/internal/native/cgo/ui_index.gen.sh b/internal/native/cgo/ui_index.gen.sh index 02cd2c2..7df6d0e 100755 --- a/internal/native/cgo/ui_index.gen.sh +++ b/internal/native/cgo/ui_index.gen.sh @@ -19,6 +19,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." diff --git a/internal/native/cgo/ui_index.h b/internal/native/cgo/ui_index.h index e7c2258..790fc06 100644 --- a/internal/native/cgo/ui_index.h +++ b/internal/native/cgo/ui_index.h @@ -4,6 +4,7 @@ #include "ui/ui.h" #include "ui/screens.h" #include "ui/images.h" +#include "ui/vars.h" typedef struct { const char *name; @@ -21,5 +22,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 diff --git a/internal/native/ctrl_linux.go b/internal/native/ctrl_linux.go deleted file mode 100644 index ac0fe08..0000000 --- a/internal/native/ctrl_linux.go +++ /dev/null @@ -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 -// 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 -} diff --git a/internal/native/ctrl_notlinux.go b/internal/native/ctrl_notlinux.go deleted file mode 100644 index 6f4086f..0000000 --- a/internal/native/ctrl_notlinux.go +++ /dev/null @@ -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 -} diff --git a/internal/native/display.go b/internal/native/display.go index def544c..842f640 100644 --- a/internal/native/display.go +++ b/internal/native/display.go @@ -1,11 +1,74 @@ package native -import "slices" +import ( + "slices" + "time" +) + +func (n *Native) setUIVars() { + uiSetVar("app_version", n.appVersion.String()) +} + +func (n *Native) initUI() { + uiInit() + 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 string) (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 +84,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) { diff --git a/internal/native/eez/jetkvm.eez-project b/internal/native/eez/jetkvm.eez-project index 34ce176..1b92605 100644 --- a/internal/native/eez/jetkvm.eez-project +++ b/internal/native/eez/jetkvm.eez-project @@ -58,7 +58,7 @@ { "objID": "316b04e4-a7de-4afc-c413-31f5f36d3843", "fileName": "vars.c", - "template": "#include \n#include \"vars.h\"\n\nchar app_version[100] = { 0 };\n\nconst char *get_var_app_version() {\n return app_version;\n}\n\nvoid set_var_app_version(const char *value) {\n strncpy(app_version, value, sizeof(app_version) / sizeof(char));\n app_version[sizeof(app_version) / sizeof(char) - 1] = 0;\n}\n" + "template": "#include \n#include \"vars.h\"\n\nchar app_version[100] = { 0 };\nchar system_version[100] = { 0 };\n\nconst char *get_var_app_version() {\n return app_version;\n}\n\nconst char *get_var_system_version() {\n return system_version;\n}\n\nvoid set_var_app_version(const char *value) {\n strncpy(app_version, value, sizeof(app_version) / sizeof(char));\n app_version[sizeof(app_version) / sizeof(char) - 1] = 0;\n}\n\nvoid set_var_system_version(const char *value) {\n strncpy(system_version, value, sizeof(system_version) / sizeof(char));\n system_version[sizeof(system_version) / sizeof(char) - 1] = 0;\n}" }, { "objID": "cbe7cde1-8920-476a-b2a2-1761ae7451b0", @@ -124,6 +124,14 @@ "defaultValue": "\"\"", "persistent": false, "native": false + }, + { + "objID": "f20790a9-e7dd-4537-f50b-c716cee2af24", + "name": "systemVersion", + "type": "string", + "defaultValue": "\"\"", + "persistent": false, + "native": false } ], "structures": [], @@ -4048,10 +4056,11 @@ }, "group": "", "groupIndex": 0, - "text": "0.0.1", - "textType": "literal", + "text": "systemVersion", + "textType": "expression", "longMode": "WRAP", - "recolor": false + "recolor": false, + "previewValue": "0.0.1" } ], "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", @@ -4185,10 +4194,11 @@ }, "group": "", "groupIndex": 0, - "text": "0.0.1", - "textType": "literal", + "text": "appVersion", + "textType": "expression", "longMode": "WRAP", - "recolor": false + "recolor": false, + "previewValue": "0.0.1" } ], "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", diff --git a/internal/native/log.go b/internal/native/log.go index f4265b4..41ae4df 100644 --- a/internal/native/log.go +++ b/internal/native/log.go @@ -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 +} diff --git a/internal/native/native.go b/internal/native/native.go index b1432bd..14b4e3e 100644 --- a/internal/native/native.go +++ b/internal/native/native.go @@ -51,111 +51,17 @@ func NewNative(opts NativeOptions) *Native { } 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() + + 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") -// } -// } -// } diff --git a/internal/native/video.go b/internal/native/video.go index ad3cdd1..b3025a8 100644 --- a/internal/native/video.go +++ b/internal/native/video.go @@ -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() } diff --git a/jsonrpc.go b/jsonrpc.go index bc0f704..00a4918 100644 --- a/jsonrpc.go +++ b/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 } @@ -287,7 +287,7 @@ func rpcTryUpdate() error { func rpcSetDisplayRotation(params DisplayRotationSettings) error { var err error - _, err = nativeInstance.DispSetRotation(params.Rotation) + _, err = nativeInstance.DisplaySetRotation(params.Rotation) if err == nil { config.DisplayRotation = params.Rotation if err := SaveConfig(); err != nil {