mirror of
https://github.com/luckfox-eng29/kvm.git
synced 2026-01-18 03:28:19 +01:00
feat: send all paste keystrokes to backend (#789)
* feat: send all paste keystrokes to backend * feat: cancel paste mode * wip: send macro using hidRPC channel * add delay * feat: allow paste progress to be cancelled * allow user to override delay * chore: clear keysDownState * fix: use currentSession.reportHidRPCKeyboardMacroState * fix: jsonrpc.go:1142:21: Error return value is not checked (errcheck) * fix: performance issue of Uint8Array concat * chore: hide delay option when debugMode isn't enabled * feat: use clientSide macro if backend doesn't support macros * fix: update keysDownState handling * minor issues * refactor * fix: send duplicated keyDownState * chore: add max length for paste text --------- Co-authored-by: Adam Shiervani <adam.shiervani@gmail.com>
This commit is contained in:
@@ -10,14 +10,17 @@ import (
|
||||
type MessageType byte
|
||||
|
||||
const (
|
||||
TypeHandshake MessageType = 0x01
|
||||
TypeKeyboardReport MessageType = 0x02
|
||||
TypePointerReport MessageType = 0x03
|
||||
TypeWheelReport MessageType = 0x04
|
||||
TypeKeypressReport MessageType = 0x05
|
||||
TypeMouseReport MessageType = 0x06
|
||||
TypeKeyboardLedState MessageType = 0x32
|
||||
TypeKeydownState MessageType = 0x33
|
||||
TypeHandshake MessageType = 0x01
|
||||
TypeKeyboardReport MessageType = 0x02
|
||||
TypePointerReport MessageType = 0x03
|
||||
TypeWheelReport MessageType = 0x04
|
||||
TypeKeypressReport MessageType = 0x05
|
||||
TypeMouseReport MessageType = 0x06
|
||||
TypeKeyboardMacroReport MessageType = 0x07
|
||||
TypeCancelKeyboardMacroReport MessageType = 0x08
|
||||
TypeKeyboardLedState MessageType = 0x32
|
||||
TypeKeydownState MessageType = 0x33
|
||||
TypeKeyboardMacroState MessageType = 0x34
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -29,10 +32,13 @@ func GetQueueIndex(messageType MessageType) int {
|
||||
switch messageType {
|
||||
case TypeHandshake:
|
||||
return 0
|
||||
case TypeKeyboardReport, TypeKeypressReport, TypeKeyboardLedState, TypeKeydownState:
|
||||
case TypeKeyboardReport, TypeKeypressReport, TypeKeyboardMacroReport, TypeKeyboardLedState, TypeKeydownState, TypeKeyboardMacroState:
|
||||
return 1
|
||||
case TypePointerReport, TypeMouseReport, TypeWheelReport:
|
||||
return 2
|
||||
// we don't want to block the queue for this message
|
||||
case TypeCancelKeyboardMacroReport:
|
||||
return 3
|
||||
default:
|
||||
return 3
|
||||
}
|
||||
@@ -98,3 +104,19 @@ func NewKeydownStateMessage(state usbgadget.KeysDownState) *Message {
|
||||
d: data,
|
||||
}
|
||||
}
|
||||
|
||||
// NewKeyboardMacroStateMessage creates a new keyboard macro state message.
|
||||
func NewKeyboardMacroStateMessage(state bool, isPaste bool) *Message {
|
||||
data := make([]byte, 2)
|
||||
if state {
|
||||
data[0] = 1
|
||||
}
|
||||
if isPaste {
|
||||
data[1] = 1
|
||||
}
|
||||
|
||||
return &Message{
|
||||
t: TypeKeyboardMacroState,
|
||||
d: data,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package hidrpc
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -43,6 +44,11 @@ func (m *Message) String() string {
|
||||
return fmt.Sprintf("MouseReport{Malformed: %v}", m.d)
|
||||
}
|
||||
return fmt.Sprintf("MouseReport{DX: %d, DY: %d, Button: %d}", m.d[0], m.d[1], m.d[2])
|
||||
case TypeKeyboardMacroReport:
|
||||
if len(m.d) < 5 {
|
||||
return fmt.Sprintf("KeyboardMacroReport{Malformed: %v}", m.d)
|
||||
}
|
||||
return fmt.Sprintf("KeyboardMacroReport{IsPaste: %v, Length: %d}", m.d[0] == uint8(1), binary.BigEndian.Uint32(m.d[1:5]))
|
||||
default:
|
||||
return fmt.Sprintf("Unknown{Type: %d, Data: %v}", m.t, m.d)
|
||||
}
|
||||
@@ -84,6 +90,55 @@ func (m *Message) KeyboardReport() (KeyboardReport, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Macro ..
|
||||
type KeyboardMacroStep struct {
|
||||
Modifier byte // 1 byte
|
||||
Keys []byte // 6 bytes: hidKeyBufferSize
|
||||
Delay uint16 // 2 bytes
|
||||
}
|
||||
type KeyboardMacroReport struct {
|
||||
IsPaste bool
|
||||
StepCount uint32
|
||||
Steps []KeyboardMacroStep
|
||||
}
|
||||
|
||||
// HidKeyBufferSize is the size of the keys buffer in the keyboard report.
|
||||
const HidKeyBufferSize = 6
|
||||
|
||||
// KeyboardMacroReport returns the keyboard macro report from the message.
|
||||
func (m *Message) KeyboardMacroReport() (KeyboardMacroReport, error) {
|
||||
if m.t != TypeKeyboardMacroReport {
|
||||
return KeyboardMacroReport{}, fmt.Errorf("invalid message type: %d", m.t)
|
||||
}
|
||||
|
||||
isPaste := m.d[0] == uint8(1)
|
||||
stepCount := binary.BigEndian.Uint32(m.d[1:5])
|
||||
|
||||
// check total length
|
||||
expectedLength := int(stepCount)*9 + 5
|
||||
if len(m.d) != expectedLength {
|
||||
return KeyboardMacroReport{}, fmt.Errorf("invalid length: %d, expected: %d", len(m.d), expectedLength)
|
||||
}
|
||||
|
||||
steps := make([]KeyboardMacroStep, 0, int(stepCount))
|
||||
offset := 5
|
||||
for i := 0; i < int(stepCount); i++ {
|
||||
steps = append(steps, KeyboardMacroStep{
|
||||
Modifier: m.d[offset],
|
||||
Keys: m.d[offset+1 : offset+7],
|
||||
Delay: binary.BigEndian.Uint16(m.d[offset+7 : offset+9]),
|
||||
})
|
||||
|
||||
offset += 1 + HidKeyBufferSize + 2
|
||||
}
|
||||
|
||||
return KeyboardMacroReport{
|
||||
IsPaste: isPaste,
|
||||
Steps: steps,
|
||||
StepCount: stepCount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PointerReport ..
|
||||
type PointerReport struct {
|
||||
X int
|
||||
@@ -131,3 +186,20 @@ func (m *Message) MouseReport() (MouseReport, error) {
|
||||
Button: uint8(m.d[2]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type KeyboardMacroState struct {
|
||||
State bool
|
||||
IsPaste bool
|
||||
}
|
||||
|
||||
// KeyboardMacroState returns the keyboard macro state report from the message.
|
||||
func (m *Message) KeyboardMacroState() (KeyboardMacroState, error) {
|
||||
if m.t != TypeKeyboardMacroState {
|
||||
return KeyboardMacroState{}, fmt.Errorf("invalid message type: %d", m.t)
|
||||
}
|
||||
|
||||
return KeyboardMacroState{
|
||||
State: m.d[0] == uint8(1),
|
||||
IsPaste: m.d[1] == uint8(1),
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user