mirror of https://github.com/jetkvm/kvm.git
minor issues
This commit is contained in:
parent
ade9a4961a
commit
b5978016af
|
@ -37,7 +37,7 @@ func handleHidRPCMessage(message hidrpc.Message, session *Session) {
|
||||||
logger.Warn().Err(err).Msg("failed to get keyboard macro report")
|
logger.Warn().Err(err).Msg("failed to get keyboard macro report")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, rpcErr = rpcExecuteKeyboardMacro(keyboardMacroReport.Macro)
|
_, rpcErr = rpcExecuteKeyboardMacro(keyboardMacroReport.Steps)
|
||||||
case hidrpc.TypeCancelKeyboardMacroReport:
|
case hidrpc.TypeCancelKeyboardMacroReport:
|
||||||
rpcCancelKeyboardMacro()
|
rpcCancelKeyboardMacro()
|
||||||
return
|
return
|
||||||
|
|
|
@ -91,17 +91,19 @@ func (m *Message) KeyboardReport() (KeyboardReport, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Macro ..
|
// Macro ..
|
||||||
type KeyboardMacro struct {
|
type KeyboardMacroStep struct {
|
||||||
Modifier byte // 1 byte
|
Modifier byte // 1 byte
|
||||||
Keys []byte // 6 bytes, to make things easier, the keys length is fixed to 6
|
Keys []byte // 6 bytes: hidKeyBufferSize
|
||||||
Delay uint16 // 2 bytes
|
Delay uint16 // 2 bytes
|
||||||
}
|
}
|
||||||
type KeyboardMacroReport struct {
|
type KeyboardMacroReport struct {
|
||||||
IsPaste bool
|
IsPaste bool
|
||||||
Length uint32
|
StepCount uint32
|
||||||
Macro []KeyboardMacro
|
Steps []KeyboardMacroStep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hidKeyBufferSize = 6
|
||||||
|
|
||||||
// KeyboardMacroReport returns the keyboard macro report from the message.
|
// KeyboardMacroReport returns the keyboard macro report from the message.
|
||||||
func (m *Message) KeyboardMacroReport() (KeyboardMacroReport, error) {
|
func (m *Message) KeyboardMacroReport() (KeyboardMacroReport, error) {
|
||||||
if m.t != TypeKeyboardMacroReport {
|
if m.t != TypeKeyboardMacroReport {
|
||||||
|
@ -109,29 +111,30 @@ func (m *Message) KeyboardMacroReport() (KeyboardMacroReport, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
isPaste := m.d[0] == uint8(1)
|
isPaste := m.d[0] == uint8(1)
|
||||||
length := binary.BigEndian.Uint32(m.d[1:5])
|
stepCount := binary.BigEndian.Uint32(m.d[1:5])
|
||||||
|
|
||||||
// check total length
|
// check total length
|
||||||
expectedLength := int(length)*9 + 5
|
expectedLength := int(stepCount)*9 + 5
|
||||||
if len(m.d) != expectedLength {
|
if len(m.d) != expectedLength {
|
||||||
return KeyboardMacroReport{}, fmt.Errorf("invalid length: %d, expected: %d", len(m.d), expectedLength)
|
return KeyboardMacroReport{}, fmt.Errorf("invalid length: %d, expected: %d", len(m.d), expectedLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro := make([]KeyboardMacro, 0, int(length))
|
steps := make([]KeyboardMacroStep, 0, int(stepCount))
|
||||||
for i := 0; i < int(length); i++ {
|
offset := 5
|
||||||
offset := 5 + i*9
|
for i := 0; i < int(stepCount); i++ {
|
||||||
|
steps = append(steps, KeyboardMacroStep{
|
||||||
macro = append(macro, KeyboardMacro{
|
|
||||||
Modifier: m.d[offset],
|
Modifier: m.d[offset],
|
||||||
Keys: m.d[offset+1 : offset+7],
|
Keys: m.d[offset+1 : offset+7],
|
||||||
Delay: binary.BigEndian.Uint16(m.d[offset+7 : offset+9]),
|
Delay: binary.BigEndian.Uint16(m.d[offset+7 : offset+9]),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
offset += 1 + hidKeyBufferSize + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
return KeyboardMacroReport{
|
return KeyboardMacroReport{
|
||||||
IsPaste: isPaste,
|
IsPaste: isPaste,
|
||||||
Macro: macro,
|
Steps: steps,
|
||||||
Length: length,
|
StepCount: stepCount,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1076,7 +1076,7 @@ func setKeyboardMacroCancel(cancel context.CancelFunc) {
|
||||||
keyboardMacroCancel = cancel
|
keyboardMacroCancel = cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
func rpcExecuteKeyboardMacro(macro []hidrpc.KeyboardMacro) (usbgadget.KeysDownState, error) {
|
func rpcExecuteKeyboardMacro(macro []hidrpc.KeyboardMacroStep) (usbgadget.KeysDownState, error) {
|
||||||
cancelKeyboardMacro()
|
cancelKeyboardMacro()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
@ -1109,11 +1109,11 @@ func rpcCancelKeyboardMacro() {
|
||||||
|
|
||||||
var keyboardClearStateKeys = make([]byte, 6)
|
var keyboardClearStateKeys = make([]byte, 6)
|
||||||
|
|
||||||
func isClearKeyStep(step hidrpc.KeyboardMacro) bool {
|
func isClearKeyStep(step hidrpc.KeyboardMacroStep) bool {
|
||||||
return step.Modifier == 0 && bytes.Equal(step.Keys, keyboardClearStateKeys)
|
return step.Modifier == 0 && bytes.Equal(step.Keys, keyboardClearStateKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rpcDoExecuteKeyboardMacro(ctx context.Context, macro []hidrpc.KeyboardMacro) (usbgadget.KeysDownState, error) {
|
func rpcDoExecuteKeyboardMacro(ctx context.Context, macro []hidrpc.KeyboardMacroStep) (usbgadget.KeysDownState, error) {
|
||||||
var last usbgadget.KeysDownState
|
var last usbgadget.KeysDownState
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
|
@ -219,32 +219,32 @@ export interface KeyboardMacroStep extends KeysDownState {
|
||||||
|
|
||||||
export class KeyboardMacroReportMessage extends RpcMessage {
|
export class KeyboardMacroReportMessage extends RpcMessage {
|
||||||
isPaste: boolean;
|
isPaste: boolean;
|
||||||
length: number;
|
stepCount: number;
|
||||||
steps: KeyboardMacroStep[];
|
steps: KeyboardMacroStep[];
|
||||||
|
|
||||||
KEYS_LENGTH = 6;
|
KEYS_LENGTH = 6;
|
||||||
|
|
||||||
constructor(isPaste: boolean, length: number, steps: KeyboardMacroStep[]) {
|
constructor(isPaste: boolean, stepCount: number, steps: KeyboardMacroStep[]) {
|
||||||
super(HID_RPC_MESSAGE_TYPES.KeyboardMacroReport);
|
super(HID_RPC_MESSAGE_TYPES.KeyboardMacroReport);
|
||||||
this.isPaste = isPaste;
|
this.isPaste = isPaste;
|
||||||
this.length = length;
|
this.stepCount = stepCount;
|
||||||
this.steps = steps;
|
this.steps = steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
marshal(): Uint8Array {
|
marshal(): Uint8Array {
|
||||||
// validate if length is correct
|
// validate if length is correct
|
||||||
if (this.length !== this.steps.length) {
|
if (this.stepCount !== this.steps.length) {
|
||||||
throw new Error(`Length ${this.length} is not equal to the number of steps ${this.steps.length}`);
|
throw new Error(`Length ${this.stepCount} is not equal to the number of steps ${this.steps.length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = new Uint8Array(this.length * 9 + 6);
|
const data = new Uint8Array(this.stepCount * 9 + 6);
|
||||||
data.set(new Uint8Array([
|
data.set(new Uint8Array([
|
||||||
this.messageType,
|
this.messageType,
|
||||||
this.isPaste ? 1 : 0,
|
this.isPaste ? 1 : 0,
|
||||||
...fromUint32toUint8(this.length),
|
...fromUint32toUint8(this.stepCount),
|
||||||
]), 0);
|
]), 0);
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i++) {
|
for (let i = 0; i < this.stepCount; i++) {
|
||||||
const step = this.steps[i];
|
const step = this.steps[i];
|
||||||
if (!withinUint8Range(step.modifier)) {
|
if (!withinUint8Range(step.modifier)) {
|
||||||
throw new Error(`Modifier ${step.modifier} is not within the uint8 range`);
|
throw new Error(`Modifier ${step.modifier} is not within the uint8 range`);
|
||||||
|
@ -279,7 +279,7 @@ export class KeyboardMacroReportMessage extends RpcMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class KeyboardMacroStateReportMessage extends RpcMessage {
|
export class KeyboardMacroStateMessage extends RpcMessage {
|
||||||
state: boolean;
|
state: boolean;
|
||||||
isPaste: boolean;
|
isPaste: boolean;
|
||||||
|
|
||||||
|
@ -297,12 +297,12 @@ export class KeyboardMacroStateReportMessage extends RpcMessage {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unmarshal(data: Uint8Array): KeyboardMacroStateReportMessage | undefined {
|
public static unmarshal(data: Uint8Array): KeyboardMacroStateMessage | undefined {
|
||||||
if (data.length < 1) {
|
if (data.length < 1) {
|
||||||
throw new Error(`Invalid keyboard macro state report message length: ${data.length}`);
|
throw new Error(`Invalid keyboard macro state report message length: ${data.length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new KeyboardMacroStateReportMessage(data[0] === 1, data[1] === 1);
|
return new KeyboardMacroStateMessage(data[0] === 1, data[1] === 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +417,7 @@ export const messageRegistry = {
|
||||||
[HID_RPC_MESSAGE_TYPES.KeypressReport]: KeypressReportMessage,
|
[HID_RPC_MESSAGE_TYPES.KeypressReport]: KeypressReportMessage,
|
||||||
[HID_RPC_MESSAGE_TYPES.KeyboardMacroReport]: KeyboardMacroReportMessage,
|
[HID_RPC_MESSAGE_TYPES.KeyboardMacroReport]: KeyboardMacroReportMessage,
|
||||||
[HID_RPC_MESSAGE_TYPES.CancelKeyboardMacroReport]: CancelKeyboardMacroReportMessage,
|
[HID_RPC_MESSAGE_TYPES.CancelKeyboardMacroReport]: CancelKeyboardMacroReportMessage,
|
||||||
[HID_RPC_MESSAGE_TYPES.KeyboardMacroStateReport]: KeyboardMacroStateReportMessage,
|
[HID_RPC_MESSAGE_TYPES.KeyboardMacroStateReport]: KeyboardMacroStateMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const unmarshalHidRpcMessage = (data: Uint8Array): RpcMessage | undefined => {
|
export const unmarshalHidRpcMessage = (data: Uint8Array): RpcMessage | undefined => {
|
||||||
|
|
|
@ -76,9 +76,8 @@ export function useHidRpc(onHidRpcMessage?: (payload: RpcMessage) => void) {
|
||||||
);
|
);
|
||||||
|
|
||||||
const reportKeyboardMacroEvent = useCallback(
|
const reportKeyboardMacroEvent = useCallback(
|
||||||
(macro: KeyboardMacroStep[]) => {
|
(steps: KeyboardMacroStep[]) => {
|
||||||
const d = new KeyboardMacroReportMessage(false, macro.length, macro);
|
sendMessage(new KeyboardMacroReportMessage(false, steps.length, steps));
|
||||||
sendMessage(d);
|
|
||||||
},
|
},
|
||||||
[sendMessage],
|
[sendMessage],
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { useHidRpc } from "@/hooks/useHidRpc";
|
import { useHidRpc } from "@/hooks/useHidRpc";
|
||||||
import {
|
import {
|
||||||
KeyboardLedStateMessage,
|
KeyboardLedStateMessage,
|
||||||
KeyboardMacroStateReportMessage,
|
KeyboardMacroStateMessage,
|
||||||
KeyboardMacroStep,
|
KeyboardMacroStep,
|
||||||
KeysDownStateMessage,
|
KeysDownStateMessage,
|
||||||
} from "@/hooks/hidRpc";
|
} from "@/hooks/hidRpc";
|
||||||
|
@ -70,9 +70,9 @@ export default function useKeyboard() {
|
||||||
case KeyboardLedStateMessage:
|
case KeyboardLedStateMessage:
|
||||||
setKeyboardLedState((message as KeyboardLedStateMessage).keyboardLedState);
|
setKeyboardLedState((message as KeyboardLedStateMessage).keyboardLedState);
|
||||||
break;
|
break;
|
||||||
case KeyboardMacroStateReportMessage:
|
case KeyboardMacroStateMessage:
|
||||||
if (!(message as KeyboardMacroStateReportMessage).isPaste) break;
|
if (!(message as KeyboardMacroStateMessage).isPaste) break;
|
||||||
setPasteModeEnabled((message as KeyboardMacroStateReportMessage).state);
|
setPasteModeEnabled((message as KeyboardMacroStateMessage).state);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
2
web.go
2
web.go
|
@ -199,7 +199,7 @@ func handleWebRTCSession(c *gin.Context) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel any ongoing keyboard report multi when session changes
|
// Cancel any ongoing keyboard macro when session changes
|
||||||
cancelKeyboardMacro()
|
cancelKeyboardMacro()
|
||||||
|
|
||||||
currentSession = session
|
currentSession = session
|
||||||
|
|
Loading…
Reference in New Issue