From 70db1722879e7b8be6c36f5233a229f42c94bbf8 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Thu, 25 Sep 2025 15:08:43 +0000 Subject: [PATCH] update state --- display.go | 8 +-- internal/native/cgo/ctrl.c | 69 +++++++++++------- internal/native/cgo/ctrl.h | 3 +- internal/native/cgo_linux.go | 94 ++++++++++++++++++++++++- internal/native/cgo_notlinux.go | 7 +- internal/native/display.go | 11 ++- internal/native/eez/jetkvm.eez-project | 26 +++---- internal/native/eez/src/ui/screens.c | 15 ++-- internal/native/lib/libjknative.a | Bin 3118616 -> 3119462 bytes internal/native/native.go | 2 + 10 files changed, 180 insertions(+), 55 deletions(-) diff --git a/display.go b/display.go index f236d906..063803dc 100644 --- a/display.go +++ b/display.go @@ -38,17 +38,17 @@ func updateDisplay() { if usbState == "configured" { nativeInstance.UpdateLabelIfChanged("usb_status_label", "Connected") - _, _ = nativeInstance.UIObjSetState("usb_status", "LV_STATE_DEFAULT") + _, _ = nativeInstance.UIObjAddState("usb_status_label", "LV_STATE_CHECKED") } else { nativeInstance.UpdateLabelIfChanged("usb_status_label", "Disconnected") - _, _ = nativeInstance.UIObjSetState("usb_status", "LV_STATE_DISABLED") + _, _ = nativeInstance.UIObjClearState("usb_status_label", "LV_STATE_CHECKED") } if lastVideoState.Ready { nativeInstance.UpdateLabelIfChanged("hdmi_status_label", "Connected") - _, _ = nativeInstance.UIObjSetState("hdmi_status", "LV_STATE_DEFAULT") + _, _ = nativeInstance.UIObjAddState("hdmi_status_label", "LV_STATE_CHECKED") } else { nativeInstance.UpdateLabelIfChanged("hdmi_status_label", "Disconnected") - _, _ = nativeInstance.UIObjSetState("hdmi_status", "LV_STATE_DISABLED") + _, _ = nativeInstance.UIObjClearState("hdmi_status_label", "LV_STATE_CHECKED") } nativeInstance.UpdateLabelIfChanged("cloud_status_label", fmt.Sprintf("%d active", actionSessions)) diff --git a/internal/native/cgo/ctrl.c b/internal/native/cgo/ctrl.c index 93a49872..b98adb06 100644 --- a/internal/native/cgo/ctrl.c +++ b/internal/native/cgo/ctrl.c @@ -247,36 +247,55 @@ void jetkvm_ui_set_image(const char *obj_name, const char *image_name) { lv_img_set_src(obj, image_name); } -void jetkvm_ui_set_state(const char *obj_name, const char *state_name) { +lv_state_t str_to_lv_state(const char *state_name) { + if (strcmp(state_name, "LV_STATE_USER_1") == 0) { + return LV_STATE_USER_1; + } + else if (strcmp(state_name, "LV_STATE_USER_2") == 0) { + return LV_STATE_USER_2; + } + else if (strcmp(state_name, "LV_STATE_USER_3") == 0) { + return LV_STATE_USER_3; + } + else if (strcmp(state_name, "LV_STATE_USER_4") == 0) { + return LV_STATE_USER_4; + } + else if (strcmp(state_name, "LV_STATE_DISABLED") == 0) { + return LV_STATE_DISABLED; + } + else if (strcmp(state_name, "LV_STATE_DEFAULT") == 0) { + return LV_STATE_DEFAULT; + } + else if (strcmp(state_name, "LV_STATE_CHECKED") == 0) { + return LV_STATE_CHECKED; + } + else if (strcmp(state_name, "LV_STATE_FOCUSED") == 0) { + return LV_STATE_FOCUSED; + } + return LV_STATE_DEFAULT; +} + +void jetkvm_ui_add_state(const char *obj_name, const char *state_name) { lv_obj_t *obj = ui_get_obj(obj_name); if (obj == NULL) { return; } - lv_obj_add_state(obj, LV_STATE_USER_1); - lv_state_t state_val = LV_STATE_DEFAULT; - if (strcmp(state_name, "LV_STATE_USER_1") == 0) - { - state_val = LV_STATE_USER_1; - } - else if (strcmp(state_name, "LV_STATE_USER_2") == 0) - { - state_val = LV_STATE_USER_2; - } - else if (strcmp(state_name, "LV_STATE_USER_3") == 0) - { - state_val = LV_STATE_USER_3; - } - else if (strcmp(state_name, "LV_STATE_USER_4") == 0) - { - state_val = LV_STATE_USER_4; - } - else if (strcmp(state_name, "LV_STATE_DISABLED") == 0) - { - state_val = LV_STATE_DISABLED; - } - // TODO: use LV_STATE_USER_* once eez supports it - lv_obj_clear_state(obj, LV_STATE_USER_1 | LV_STATE_USER_2 | LV_STATE_USER_3 | LV_STATE_USER_4 | LV_STATE_DISABLED); + lv_state_t state_val = str_to_lv_state(state_name); lv_obj_add_state(obj, state_val); + + lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY); +} + +void jetkvm_ui_clear_state(const char *obj_name, const char *state_name) { + lv_obj_t *obj = ui_get_obj(obj_name); + if (obj == NULL) { + return; + } + lv_state_t state_val = str_to_lv_state(state_name); + lv_obj_clear_state(obj, state_val); + + log_info("cleared state %s from object %s: %d", state_name, obj_name, state_val); + lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY); } int jetkvm_ui_add_flag(const char *obj_name, const char *flag_name) { diff --git a/internal/native/cgo/ctrl.h b/internal/native/cgo/ctrl.h index c23b01af..254fdf7b 100644 --- a/internal/native/cgo/ctrl.h +++ b/internal/native/cgo/ctrl.h @@ -39,7 +39,8 @@ 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); void jetkvm_ui_set_image(const char *obj_name, const char *image_name); -void jetkvm_ui_set_state(const char *obj_name, const char *state_name); +void jetkvm_ui_add_state(const char *obj_name, const char *state_name); +void jetkvm_ui_clear_state(const char *obj_name, const char *state_name); void jetkvm_ui_fade_in(const char *obj_name, u_int32_t duration); void jetkvm_ui_fade_out(const char *obj_name, u_int32_t duration); void jetkvm_ui_set_opacity(const char *obj_name, u_int8_t opacity); diff --git a/internal/native/cgo_linux.go b/internal/native/cgo_linux.go index 5377cc17..54d57b55 100644 --- a/internal/native/cgo_linux.go +++ b/internal/native/cgo_linux.go @@ -4,6 +4,7 @@ package native import ( "fmt" + "sync" "unsafe" "github.com/rs/zerolog" @@ -45,6 +46,8 @@ static inline void jetkvm_cgo_setup_rpc_handler() { */ import "C" +var cgoLock sync.Mutex + //export jetkvm_go_video_state_handler func jetkvm_go_video_state_handler(state *C.jetkvm_video_state_t) { videoState := VideoState{ @@ -100,6 +103,9 @@ func uiEventCodeToName(code int) string { } func setUpNativeHandlers() { + cgoLock.Lock() + defer cgoLock.Unlock() + C.jetkvm_cgo_setup_log_handler() C.jetkvm_cgo_setup_video_state_handler() C.jetkvm_cgo_setup_video_handler() @@ -108,6 +114,9 @@ func setUpNativeHandlers() { } func uiInit(rotation uint16) { + cgoLock.Lock() + defer cgoLock.Unlock() + cRotation := C.u_int16_t(rotation) defer C.free(unsafe.Pointer(&cRotation)) @@ -115,10 +124,16 @@ func uiInit(rotation uint16) { } func uiTick() { + cgoLock.Lock() + defer cgoLock.Unlock() + C.jetkvm_ui_tick() } func videoInit() error { + cgoLock.Lock() + defer cgoLock.Unlock() + ret := C.jetkvm_video_init() if ret != 0 { return fmt.Errorf("failed to initialize video: %d", ret) @@ -127,18 +142,30 @@ func videoInit() error { } func videoShutdown() { + cgoLock.Lock() + defer cgoLock.Unlock() + C.jetkvm_video_shutdown() } func videoStart() { + cgoLock.Lock() + defer cgoLock.Unlock() + C.jetkvm_video_start() } func videoStop() { + cgoLock.Lock() + defer cgoLock.Unlock() + C.jetkvm_video_stop() } func uiSetVar(name string, value string) { + cgoLock.Lock() + defer cgoLock.Unlock() + nameCStr := C.CString(name) defer C.free(unsafe.Pointer(nameCStr)) @@ -149,6 +176,9 @@ func uiSetVar(name string, value string) { } func uiGetVar(name string) string { + cgoLock.Lock() + defer cgoLock.Unlock() + nameCStr := C.CString(name) defer C.free(unsafe.Pointer(nameCStr)) @@ -156,31 +186,58 @@ func uiGetVar(name string) string { } func uiSwitchToScreen(screen string) { + cgoLock.Lock() + defer cgoLock.Unlock() + screenCStr := C.CString(screen) defer C.free(unsafe.Pointer(screenCStr)) C.jetkvm_ui_load_screen(screenCStr) } func uiGetCurrentScreen() string { + cgoLock.Lock() + defer cgoLock.Unlock() + screenCStr := C.jetkvm_ui_get_current_screen() return C.GoString(screenCStr) } -func uiObjSetState(objName string, state string) (bool, error) { +func uiObjAddState(objName string, state string) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + 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) + C.jetkvm_ui_add_state(objNameCStr, stateCStr) + return true, nil +} + +func uiObjClearState(objName string, state string) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + + objNameCStr := C.CString(objName) + defer C.free(unsafe.Pointer(objNameCStr)) + stateCStr := C.CString(state) + defer C.free(unsafe.Pointer(stateCStr)) + C.jetkvm_ui_clear_state(objNameCStr, stateCStr) return true, nil } func uiGetLVGLVersion() string { + cgoLock.Lock() + defer cgoLock.Unlock() + return C.GoString(C.jetkvm_ui_get_lvgl_version()) } // 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) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) flagCStr := C.CString(flag) @@ -190,6 +247,9 @@ func uiObjAddFlag(objName string, flag string) (bool, error) { } func uiObjClearFlag(objName string, flag string) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) flagCStr := C.CString(flag) @@ -207,6 +267,9 @@ func uiObjShow(objName string) (bool, error) { } func uiObjSetOpacity(objName string, opacity int) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) @@ -215,6 +278,9 @@ func uiObjSetOpacity(objName string, opacity int) (bool, error) { } func uiObjFadeIn(objName string, duration uint32) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) @@ -224,6 +290,9 @@ func uiObjFadeIn(objName string, duration uint32) (bool, error) { } func uiObjFadeOut(objName string, duration uint32) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) @@ -233,6 +302,9 @@ func uiObjFadeOut(objName string, duration uint32) (bool, error) { } func uiLabelSetText(objName string, text string) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) @@ -247,6 +319,9 @@ func uiLabelSetText(objName string, text string) (bool, error) { } func uiImgSetSrc(objName string, src string) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + objNameCStr := C.CString(objName) defer C.free(unsafe.Pointer(objNameCStr)) @@ -259,6 +334,9 @@ func uiImgSetSrc(objName string, src string) (bool, error) { } func uiDispSetRotation(rotation uint16) (bool, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + nativeLogger.Info().Uint16("rotation", rotation).Msg("setting rotation") cRotation := C.u_int16_t(rotation) @@ -269,21 +347,33 @@ func uiDispSetRotation(rotation uint16) (bool, error) { } func videoGetStreamQualityFactor() (float64, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + factor := C.jetkvm_video_get_quality_factor() return float64(factor), nil } func videoSetStreamQualityFactor(factor float64) error { + cgoLock.Lock() + defer cgoLock.Unlock() + C.jetkvm_video_set_quality_factor(C.float(factor)) return nil } func videoGetEDID() (string, error) { + cgoLock.Lock() + defer cgoLock.Unlock() + edidCStr := C.jetkvm_video_get_edid_hex() return C.GoString(edidCStr), nil } func videoSetEDID(edid string) error { + cgoLock.Lock() + defer cgoLock.Unlock() + edidCStr := C.CString(edid) defer C.free(unsafe.Pointer(edidCStr)) C.jetkvm_video_set_edid(edidCStr) diff --git a/internal/native/cgo_notlinux.go b/internal/native/cgo_notlinux.go index 77d75301..1b23ab5e 100644 --- a/internal/native/cgo_notlinux.go +++ b/internal/native/cgo_notlinux.go @@ -28,7 +28,12 @@ func uiGetCurrentScreen() string { return "" } -func uiObjSetState(objName string, state string) (bool, error) { +func uiObjAddState(objName string, state string) (bool, error) { + panicPlatformNotSupported() + return false, nil +} + +func uiObjClearState(objName string, state string) (bool, error) { panicPlatformNotSupported() return false, nil } diff --git a/internal/native/display.go b/internal/native/display.go index 925a0a10..de9b9a01 100644 --- a/internal/native/display.go +++ b/internal/native/display.go @@ -47,9 +47,14 @@ func (n *Native) UIGetVar(name string) string { return uiGetVar(name) } -// UIObjSetState clears the state then adds the new state -func (n *Native) UIObjSetState(objName string, state string) (bool, error) { - return uiObjSetState(objName, state) +// UIObjAddState adds the state to the object +func (n *Native) UIObjAddState(objName string, state string) (bool, error) { + return uiObjAddState(objName, state) +} + +// UIObjClearState clears the state from the object +func (n *Native) UIObjClearState(objName string, state string) (bool, error) { + return uiObjClearState(objName, state) } // UIObjAddFlag adds the flag to the object diff --git a/internal/native/eez/jetkvm.eez-project b/internal/native/eez/jetkvm.eez-project index 0ef12470..66b9c955 100644 --- a/internal/native/eez/jetkvm.eez-project +++ b/internal/native/eez/jetkvm.eez-project @@ -1577,7 +1577,7 @@ "type": "LVGLLabelWidget", "left": 0, "top": 0, - "width": 81, + "width": 68, "height": 17, "customInputs": [], "customOutputs": [], @@ -1595,9 +1595,10 @@ "widthUnit": "content", "heightUnit": "content", "children": [], - "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE|CHECKABLE", "hiddenFlagType": "literal", "clickableFlagType": "literal", + "checkedState": false, "checkedStateType": "literal", "disabledStateType": "literal", "states": "", @@ -1607,16 +1608,16 @@ "definition": { "MAIN": { "DEFAULT": { - "text_color": "22C55E" - }, - "DISABLED": { "text_color": "808080" + }, + "CHECKED": { + "text_color": "22C55E" } } } }, "groupIndex": 0, - "text": "Connected", + "text": "Unknown", "textType": "literal", "longMode": "WRAP", "recolor": false @@ -1795,7 +1796,7 @@ "type": "LVGLLabelWidget", "left": 0, "top": 0, - "width": 100, + "width": 68, "height": 17, "customInputs": [], "customOutputs": [], @@ -1813,11 +1814,12 @@ "widthUnit": "content", "heightUnit": "content", "children": [], - "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE|CHECKABLE", "hiddenFlagType": "literal", "clickableFlagType": "literal", + "checkedState": false, "checkedStateType": "literal", - "disabledState": true, + "disabledState": false, "disabledStateType": "literal", "states": "", "useStyle": "LabelFont16", @@ -1825,17 +1827,17 @@ "objID": "00742432-4b32-47f4-a4c5-5bc75f6b458d", "definition": { "MAIN": { - "DEFAULT": { + "CHECKED": { "text_color": "22C55E" }, - "DISABLED": { + "DEFAULT": { "text_color": "808080" } } } }, "groupIndex": 0, - "text": "Disconnected", + "text": "Unknown", "textType": "literal", "longMode": "WRAP", "recolor": false diff --git a/internal/native/eez/src/ui/screens.c b/internal/native/eez/src/ui/screens.c index de01cd66..2c108906 100644 --- a/internal/native/eez/src/ui/screens.c +++ b/internal/native/eez/src/ui/screens.c @@ -432,10 +432,11 @@ void create_screen_home_screen() { objects.usb_status_label = obj; lv_obj_set_pos(obj, LV_PCT(0), LV_PCT(0)); lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE); add_style_label_font16(obj); - lv_obj_set_style_text_color(obj, lv_color_hex(0xff22c55e), LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_text_color(obj, lv_color_hex(0xff808080), LV_PART_MAIN | LV_STATE_DISABLED); - lv_label_set_text(obj, "Connected"); + lv_obj_set_style_text_color(obj, lv_color_hex(0xff808080), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(obj, lv_color_hex(0xff22c55e), LV_PART_MAIN | LV_STATE_CHECKED); + lv_label_set_text(obj, "Unknown"); } } } @@ -494,11 +495,11 @@ void create_screen_home_screen() { objects.hdmi_status_label = obj; lv_obj_set_pos(obj, LV_PCT(0), LV_PCT(0)); lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); - lv_obj_add_state(obj, LV_STATE_DISABLED); + lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE); add_style_label_font16(obj); - lv_obj_set_style_text_color(obj, lv_color_hex(0xff22c55e), LV_PART_MAIN | LV_STATE_DEFAULT); - lv_obj_set_style_text_color(obj, lv_color_hex(0xff808080), LV_PART_MAIN | LV_STATE_DISABLED); - lv_label_set_text(obj, "Disconnected"); + lv_obj_set_style_text_color(obj, lv_color_hex(0xff22c55e), LV_PART_MAIN | LV_STATE_CHECKED); + lv_obj_set_style_text_color(obj, lv_color_hex(0xff808080), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_label_set_text(obj, "Unknown"); } } } diff --git a/internal/native/lib/libjknative.a b/internal/native/lib/libjknative.a index 646eefda43c2a5842e6ce94e7b44ea1c04ceba53..35ccc81152610823ef2722a49db4e454084c089e 100644 GIT binary patch delta 27692 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 UAAayRuU~Xd>-uTq!Yii#57wrRtpET3 delta 27197 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