mirror of
https://github.com/luckfox-eng29/kvm.git
synced 2026-05-28 17:11:20 +02:00
refactor(hid): improve keyboard layout compatibility in HID handling functions
Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
This commit is contained in:
47
internal/hidrpc/hidrpc.go
Normal file
47
internal/hidrpc/hidrpc.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package hidrpc
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Handler interface {
|
||||
HandleKeyboardReport(modifier byte, keys []byte) error
|
||||
HandleKeypressReport(key byte, press bool) error
|
||||
HandleKeypressKeepAlive() error
|
||||
HandleKeyboardMacroReport(data []byte) error
|
||||
HandleCancelKeyboardMacro() error
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
handler Handler
|
||||
}
|
||||
|
||||
func NewServer(handler Handler) *Server {
|
||||
return &Server{handler: handler}
|
||||
}
|
||||
|
||||
func (s *Server) HandleMessage(data []byte) error {
|
||||
msg, err := UnmarshalMessage(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch msg.Type {
|
||||
case MessageTypeKeyboardReport:
|
||||
if len(msg.Data) < 7 {
|
||||
return fmt.Errorf("invalid keyboard report length: %d", len(msg.Data))
|
||||
}
|
||||
return s.handler.HandleKeyboardReport(msg.Data[0], msg.Data[1:7])
|
||||
case MessageTypeKeypressReport:
|
||||
if len(msg.Data) < 2 {
|
||||
return fmt.Errorf("invalid keypress report length: %d", len(msg.Data))
|
||||
}
|
||||
return s.handler.HandleKeypressReport(msg.Data[0], msg.Data[1] != 0)
|
||||
case MessageTypeKeypressKeepAlive:
|
||||
return s.handler.HandleKeypressKeepAlive()
|
||||
case MessageTypeKeyboardMacroReport:
|
||||
return s.handler.HandleKeyboardMacroReport(msg.Data)
|
||||
case MessageTypeCancelKeyboardMacro:
|
||||
return s.handler.HandleCancelKeyboardMacro()
|
||||
default:
|
||||
return fmt.Errorf("unknown message type: 0x%02x", msg.Type)
|
||||
}
|
||||
}
|
||||
66
internal/hidrpc/message.go
Normal file
66
internal/hidrpc/message.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package hidrpc
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
MessageTypeHandshake = 0x01
|
||||
MessageTypeKeyboardReport = 0x02
|
||||
MessageTypePointerReport = 0x03
|
||||
MessageTypeWheelReport = 0x04
|
||||
MessageTypeKeypressReport = 0x05
|
||||
MessageTypeMouseReport = 0x06
|
||||
MessageTypeKeyboardMacroReport = 0x07
|
||||
MessageTypeCancelKeyboardMacro = 0x08
|
||||
MessageTypeKeypressKeepAlive = 0x09
|
||||
MessageTypeKeyboardLedState = 0x32
|
||||
MessageTypeKeysDownState = 0x33
|
||||
MessageTypeKeyboardMacroState = 0x34
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Type byte
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func MarshalKeyboardReport(modifier byte, keys []byte) []byte {
|
||||
data := make([]byte, 8)
|
||||
data[0] = MessageTypeKeyboardReport
|
||||
data[1] = modifier
|
||||
copy(data[2:], keys)
|
||||
return data
|
||||
}
|
||||
|
||||
func MarshalKeypressReport(key byte, press bool) []byte {
|
||||
data := make([]byte, 3)
|
||||
data[0] = MessageTypeKeypressReport
|
||||
data[1] = key
|
||||
if press {
|
||||
data[2] = 1
|
||||
} else {
|
||||
data[2] = 0
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func MarshalKeypressKeepAlive() []byte {
|
||||
return []byte{MessageTypeKeypressKeepAlive}
|
||||
}
|
||||
|
||||
func MarshalKeyboardLedState(state byte) []byte {
|
||||
return []byte{MessageTypeKeyboardLedState, state}
|
||||
}
|
||||
|
||||
func MarshalKeysDownState(modifier byte, keys []byte) []byte {
|
||||
data := make([]byte, 8)
|
||||
data[0] = MessageTypeKeysDownState
|
||||
data[1] = modifier
|
||||
copy(data[2:], keys)
|
||||
return data
|
||||
}
|
||||
|
||||
func UnmarshalMessage(data []byte) (Message, error) {
|
||||
if len(data) < 1 {
|
||||
return Message{}, fmt.Errorf("empty message")
|
||||
}
|
||||
return Message{Type: data[0], Data: data[1:]}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user