mirror of https://github.com/jetkvm/kvm.git
Compare commits
2 Commits
4b9b0a64e9
...
e5f58332b7
Author | SHA1 | Date |
---|---|---|
|
e5f58332b7 | |
|
1e57f4bf4f |
|
@ -100,7 +100,7 @@ func getKeyboardState(b byte) KeyboardState {
|
|||
}
|
||||
}
|
||||
|
||||
func (u *UsbGadget) updateKeyboardState(state uint8) {
|
||||
func (u *UsbGadget) updateKeyboardState(state byte) {
|
||||
u.keyboardStateLock.Lock()
|
||||
defer u.keyboardStateLock.Unlock()
|
||||
|
||||
|
@ -185,7 +185,7 @@ func (u *UsbGadget) listenKeyboardEvents() {
|
|||
l.Trace().Msg("starting")
|
||||
|
||||
go func() {
|
||||
buf := make([]uint8, hidReadBufferSize)
|
||||
buf := make([]byte, hidReadBufferSize)
|
||||
for {
|
||||
select {
|
||||
case <-u.keyboardStateCtx.Done():
|
||||
|
@ -245,12 +245,12 @@ func (u *UsbGadget) OpenKeyboardHidFile() error {
|
|||
return u.openKeyboardHidFile()
|
||||
}
|
||||
|
||||
func (u *UsbGadget) keyboardWriteHidFile(modifier uint8, keys []uint8) error {
|
||||
func (u *UsbGadget) keyboardWriteHidFile(modifier byte, keys []byte) error {
|
||||
if err := u.openKeyboardHidFile(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := u.keyboardHidFile.Write(append([]uint8{modifier, 0x00}, keys[:hidKeyBufferSize]...))
|
||||
_, err := u.keyboardHidFile.Write(append([]byte{modifier, 0x00}, keys[:hidKeyBufferSize]...))
|
||||
if err != nil {
|
||||
u.logWithSuppression("keyboardWriteHidFile", 100, u.log, err, "failed to write to hidg0")
|
||||
u.keyboardHidFile.Close()
|
||||
|
@ -261,7 +261,7 @@ func (u *UsbGadget) keyboardWriteHidFile(modifier uint8, keys []uint8) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (u *UsbGadget) KeyboardReport(modifier uint8, keys []uint8) error {
|
||||
func (u *UsbGadget) KeyboardReport(modifier byte, keys []byte) error {
|
||||
u.keyboardLock.Lock()
|
||||
defer u.keyboardLock.Unlock()
|
||||
defer u.resetUserInputTime()
|
||||
|
@ -270,7 +270,7 @@ func (u *UsbGadget) KeyboardReport(modifier uint8, keys []uint8) error {
|
|||
keys = keys[:hidKeyBufferSize]
|
||||
}
|
||||
if len(keys) < hidKeyBufferSize {
|
||||
keys = append(keys, make([]uint8, hidKeyBufferSize-len(keys))...)
|
||||
keys = append(keys, make([]byte, hidKeyBufferSize-len(keys))...)
|
||||
}
|
||||
|
||||
return u.keyboardWriteHidFile(modifier, keys)
|
||||
|
@ -290,7 +290,7 @@ const (
|
|||
)
|
||||
|
||||
// KeyCodeToMaskMap is a slice of KeyCodeMask for quick lookup
|
||||
var KeyCodeToMaskMap = map[uint8]uint8{
|
||||
var KeyCodeToMaskMap = map[byte]byte{
|
||||
LeftControl: ModifierMaskLeftControl,
|
||||
LeftShift: ModifierMaskLeftShift,
|
||||
LeftAlt: ModifierMaskLeftAlt,
|
||||
|
@ -301,14 +301,14 @@ var KeyCodeToMaskMap = map[uint8]uint8{
|
|||
RightSuper: ModifierMaskRightSuper,
|
||||
}
|
||||
|
||||
func (u *UsbGadget) KeypressReport(key uint8, press bool) (KeysDownState, error) {
|
||||
func (u *UsbGadget) KeypressReport(key byte, press bool) (KeysDownState, error) {
|
||||
u.keyboardLock.Lock()
|
||||
defer u.keyboardLock.Unlock()
|
||||
defer u.resetUserInputTime()
|
||||
|
||||
var state = u.keysDownState
|
||||
modifier := state.Modifier
|
||||
keys := state.Keys[:]
|
||||
keys := append([]byte(nil), state.Keys...)
|
||||
|
||||
if mask, exists := KeyCodeToMaskMap[key]; exists {
|
||||
// If the key is a modifier key, we update the keyboardModifier state
|
||||
|
@ -361,10 +361,12 @@ func (u *UsbGadget) KeypressReport(key uint8, press bool) (KeysDownState, error)
|
|||
u.log.Warn().Uint8("modifier", modifier).Uints8("keys", keys).Msg("Could not write keypress report to hidg0")
|
||||
}
|
||||
|
||||
state.Modifier = modifier
|
||||
state.Keys = keys
|
||||
var result = KeysDownState{
|
||||
Modifier: modifier,
|
||||
Keys: []byte(keys[:]),
|
||||
}
|
||||
|
||||
u.updateKeyDownState(state)
|
||||
u.updateKeyDownState(result)
|
||||
|
||||
return state, nil
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
@ -85,17 +85,17 @@ func (u *UsbGadget) absMouseWriteHidFile(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (u *UsbGadget) AbsMouseReport(x, y int, buttons uint8) error {
|
||||
func (u *UsbGadget) AbsMouseReport(x int, y int, buttons uint8) error {
|
||||
u.absMouseLock.Lock()
|
||||
defer u.absMouseLock.Unlock()
|
||||
|
||||
err := u.absMouseWriteHidFile([]byte{
|
||||
1, // Report ID 1
|
||||
buttons, // Buttons
|
||||
uint8(x), // X Low Byte
|
||||
uint8(x >> 8), // X High Byte
|
||||
uint8(y), // Y Low Byte
|
||||
uint8(y >> 8), // Y High Byte
|
||||
1, // Report ID 1
|
||||
buttons, // Buttons
|
||||
byte(x), // X Low Byte
|
||||
byte(x >> 8), // X High Byte
|
||||
byte(y), // Y Low Byte
|
||||
byte(y >> 8), // Y High Byte
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -75,15 +75,15 @@ func (u *UsbGadget) relMouseWriteHidFile(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (u *UsbGadget) RelMouseReport(mx, my int8, buttons uint8) error {
|
||||
func (u *UsbGadget) RelMouseReport(mx int8, my int8, buttons uint8) error {
|
||||
u.relMouseLock.Lock()
|
||||
defer u.relMouseLock.Unlock()
|
||||
|
||||
err := u.relMouseWriteHidFile([]byte{
|
||||
buttons, // Buttons
|
||||
uint8(mx), // X
|
||||
uint8(my), // Y
|
||||
0, // Wheel
|
||||
buttons, // Buttons
|
||||
byte(mx), // X
|
||||
byte(my), // Y
|
||||
0, // Wheel
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -42,8 +42,8 @@ var defaultUsbGadgetDevices = Devices{
|
|||
}
|
||||
|
||||
type KeysDownState struct {
|
||||
Modifier uint8 `json:"modifier"`
|
||||
Keys []uint8 `json:"keys"`
|
||||
Modifier byte `json:"modifier"`
|
||||
Keys ByteSlice `json:"keys"`
|
||||
}
|
||||
|
||||
// UsbGadget is a struct that represents a USB gadget.
|
||||
|
@ -65,7 +65,7 @@ type UsbGadget struct {
|
|||
relMouseHidFile *os.File
|
||||
relMouseLock sync.Mutex
|
||||
|
||||
keyboardState uint8 // keyboard latched state (NumLock, CapsLock, ScrollLock, Compose, Kana)
|
||||
keyboardState byte // keyboard latched state (NumLock, CapsLock, ScrollLock, Compose, Kana)
|
||||
keysDownState KeysDownState // keyboard dynamic state (modifier keys and pressed keys)
|
||||
|
||||
keyboardStateLock sync.Mutex
|
||||
|
@ -131,7 +131,7 @@ func newUsbGadget(name string, configMap map[string]gadgetConfigItem, enabledDev
|
|||
keyboardStateCtx: keyboardCtx,
|
||||
keyboardStateCancel: keyboardCancel,
|
||||
keyboardState: 0,
|
||||
keysDownState: KeysDownState{Modifier: 0, Keys: []uint8{0, 0, 0, 0, 0, 0}}, // must be initialized to hidKeyBufferSize (6) zero bytes
|
||||
keysDownState: KeysDownState{Modifier: 0, Keys: []byte{0, 0, 0, 0, 0, 0}}, // must be initialized to hidKeyBufferSize (6) zero bytes
|
||||
enabledDevices: *enabledDevices,
|
||||
lastUserInput: time.Now(),
|
||||
log: logger,
|
||||
|
|
|
@ -2,6 +2,7 @@ package usbgadget
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
@ -10,6 +11,31 @@ import (
|
|||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type ByteSlice []byte
|
||||
|
||||
func (s ByteSlice) MarshalJSON() ([]byte, error) {
|
||||
vals := make([]int, len(s))
|
||||
for i, v := range s {
|
||||
vals[i] = int(v)
|
||||
}
|
||||
return json.Marshal(vals)
|
||||
}
|
||||
|
||||
func (s *ByteSlice) UnmarshalJSON(data []byte) error {
|
||||
var vals []int
|
||||
if err := json.Unmarshal(data, &vals); err != nil {
|
||||
return err
|
||||
}
|
||||
*s = make([]byte, len(vals))
|
||||
for i, v := range vals {
|
||||
if v < 0 || v > 255 {
|
||||
return fmt.Errorf("value %d out of byte range", v)
|
||||
}
|
||||
(*s)[i] = byte(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func joinPath(basePath string, paths []string) string {
|
||||
pathArr := append([]string{basePath}, paths...)
|
||||
return filepath.Join(pathArr...)
|
||||
|
|
|
@ -566,7 +566,7 @@ func riskyCallRPCHandler(logger zerolog.Logger, handler RPCHandler, params map[s
|
|||
}
|
||||
}
|
||||
|
||||
logger.Trace().Interface("args", args).Msg("Calling RPC handler")
|
||||
logger.Trace().Msg("Calling RPC handler")
|
||||
results := handlerValue.Call(args)
|
||||
|
||||
if len(results) == 0 {
|
||||
|
|
|
@ -11,10 +11,14 @@ import { useJsonRpc } from "@/hooks/useJsonRpc";
|
|||
import { cx } from "@/cva.config";
|
||||
import { keys } from "@/keyboardMappings";
|
||||
import {
|
||||
MouseState,
|
||||
RTCState,
|
||||
SettingsState,
|
||||
useMouseStore,
|
||||
useRTCStore,
|
||||
useSettingsStore,
|
||||
useVideoStore,
|
||||
VideoState,
|
||||
} from "@/hooks/stores";
|
||||
|
||||
import {
|
||||
|
@ -27,15 +31,15 @@ import {
|
|||
export default function WebRTCVideo() {
|
||||
// Video and stream related refs and states
|
||||
const videoElm = useRef<HTMLVideoElement>(null);
|
||||
const mediaStream = useRTCStore(state => state.mediaStream);
|
||||
const mediaStream = useRTCStore((state: RTCState) => state.mediaStream);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const peerConnectionState = useRTCStore(state => state.peerConnectionState);
|
||||
const peerConnectionState = useRTCStore((state: RTCState) => state.peerConnectionState);
|
||||
const [isPointerLockActive, setIsPointerLockActive] = useState(false);
|
||||
// Store hooks
|
||||
const settings = useSettingsStore();
|
||||
const { sendKeypressEvent, resetKeyboardState } = useKeyboard();
|
||||
const setMousePosition = useMouseStore(state => state.setMousePosition);
|
||||
const setMouseMove = useMouseStore(state => state.setMouseMove);
|
||||
const setMousePosition = useMouseStore((state: MouseState) => state.setMousePosition);
|
||||
const setMouseMove = useMouseStore((state: MouseState) => state.setMouseMove);
|
||||
const {
|
||||
setClientSize: setVideoClientSize,
|
||||
setSize: setVideoSize,
|
||||
|
@ -46,15 +50,15 @@ export default function WebRTCVideo() {
|
|||
} = useVideoStore();
|
||||
|
||||
// Video enhancement settings
|
||||
const videoSaturation = useSettingsStore(state => state.videoSaturation);
|
||||
const videoBrightness = useSettingsStore(state => state.videoBrightness);
|
||||
const videoContrast = useSettingsStore(state => state.videoContrast);
|
||||
const videoSaturation = useSettingsStore((state: SettingsState) => state.videoSaturation);
|
||||
const videoBrightness = useSettingsStore((state: SettingsState) => state.videoBrightness);
|
||||
const videoContrast = useSettingsStore((state: SettingsState) => state.videoContrast);
|
||||
|
||||
// RTC related states
|
||||
const peerConnection = useRTCStore(state => state.peerConnection);
|
||||
const peerConnection = useRTCStore((state: RTCState ) => state.peerConnection);
|
||||
|
||||
// HDMI and UI states
|
||||
const hdmiState = useVideoStore(state => state.hdmiState);
|
||||
const hdmiState = useVideoStore((state: VideoState) => state.hdmiState);
|
||||
const hdmiError = ["no_lock", "no_signal", "out_of_range"].includes(hdmiState);
|
||||
const isVideoLoading = !isPlaying;
|
||||
|
||||
|
|
|
@ -31,9 +31,7 @@ export default function useKeyboard() {
|
|||
if ("error" in resp) {
|
||||
console.error("Failed to send keypress:", resp.error);
|
||||
} else {
|
||||
console.log(resp);
|
||||
const keyDownState = resp.result as KeysDownState;
|
||||
console.log("Key Down State:", keyDownState);
|
||||
// We do this for the info bar to display the currently pressed keys for the user
|
||||
setKeysDownState(keyDownState);
|
||||
}
|
||||
|
|
|
@ -661,7 +661,7 @@ export default function KvmIdRoute() {
|
|||
|
||||
useEffect(() => {
|
||||
if (rpcDataChannel?.readyState !== "open") return;
|
||||
send("getVideoState", {}, resp => {
|
||||
send("getVideoState", {}, (resp: JsonRpcResponse) => {
|
||||
if ("error" in resp) return;
|
||||
setHdmiState(resp.result as Parameters<VideoState["setHdmiState"]>[0]);
|
||||
});
|
||||
|
@ -673,7 +673,7 @@ export default function KvmIdRoute() {
|
|||
if (keyboardLedState !== undefined) return;
|
||||
console.log("Requesting keyboard led state");
|
||||
|
||||
send("getKeyboardLedState", {}, resp => {
|
||||
send("getKeyboardLedState", {}, (resp: JsonRpcResponse) => {
|
||||
if ("error" in resp) {
|
||||
console.error("Failed to get keyboard led state", resp.error);
|
||||
return;
|
||||
|
@ -689,7 +689,7 @@ export default function KvmIdRoute() {
|
|||
if (keysDownState !== undefined) return;
|
||||
console.log("Requesting keys down state");
|
||||
|
||||
send("getKeyDownState", {}, resp => {
|
||||
send("getKeyDownState", {}, (resp: JsonRpcResponse) => {
|
||||
if ("error" in resp) {
|
||||
console.error("Failed to get key down state", resp.error);
|
||||
return;
|
||||
|
|
8
usb.go
8
usb.go
|
@ -43,19 +43,19 @@ func initUsbGadget() {
|
|||
}
|
||||
}
|
||||
|
||||
func rpcKeyboardReport(modifier uint8, keys []uint8) error {
|
||||
func rpcKeyboardReport(modifier byte, keys []byte) error {
|
||||
return gadget.KeyboardReport(modifier, keys)
|
||||
}
|
||||
|
||||
func rpcKeypressReport(key uint8, press bool) (usbgadget.KeysDownState, error) {
|
||||
func rpcKeypressReport(key byte, press bool) (usbgadget.KeysDownState, error) {
|
||||
return gadget.KeypressReport(key, press)
|
||||
}
|
||||
|
||||
func rpcAbsMouseReport(x, y int, buttons uint8) error {
|
||||
func rpcAbsMouseReport(x int, y int, buttons uint8) error {
|
||||
return gadget.AbsMouseReport(x, y, buttons)
|
||||
}
|
||||
|
||||
func rpcRelMouseReport(dx, dy int8, buttons uint8) error {
|
||||
func rpcRelMouseReport(dx int8, dy int8, buttons uint8) error {
|
||||
return gadget.RelMouseReport(dx, dy, buttons)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue