mirror of https://github.com/jetkvm/kvm.git
refactor functions
This commit is contained in:
parent
fb166e9d58
commit
3fa3af2d5b
28
display.go
28
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")
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,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) {
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
{
|
||||
"objID": "316b04e4-a7de-4afc-c413-31f5f36d3843",
|
||||
"fileName": "vars.c",
|
||||
"template": "#include <string.h>\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 <string.h>\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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue