mirror of https://github.com/jetkvm/kvm.git
129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
package usbgadget
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
var absoluteMouseConfig = gadgetConfigItem{
|
|
order: 1001,
|
|
device: "hid.usb1",
|
|
path: []string{"functions", "hid.usb1"},
|
|
configPath: []string{"hid.usb1"},
|
|
attrs: gadgetAttributes{
|
|
"protocol": "2",
|
|
"subclass": "1",
|
|
"report_length": "6",
|
|
},
|
|
reportDesc: absoluteMouseCombinedReportDesc,
|
|
}
|
|
|
|
var absoluteMouseCombinedReportDesc = []byte{
|
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
|
0x09, 0x02, // Usage (Mouse)
|
|
0xA1, 0x01, // Collection (Application)
|
|
|
|
// Report ID 1: Absolute Mouse Movement
|
|
0x85, 0x01, // Report ID (1)
|
|
0x09, 0x01, // Usage (Pointer)
|
|
0xA1, 0x00, // Collection (Physical)
|
|
0x05, 0x09, // Usage Page (Button)
|
|
0x19, 0x01, // Usage Minimum (0x01)
|
|
0x29, 0x03, // Usage Maximum (0x03)
|
|
0x15, 0x00, // Logical Minimum (0)
|
|
0x25, 0x01, // Logical Maximum (1)
|
|
0x75, 0x01, // Report Size (1)
|
|
0x95, 0x03, // Report Count (3)
|
|
0x81, 0x02, // Input (Data, Var, Abs)
|
|
0x95, 0x01, // Report Count (1)
|
|
0x75, 0x05, // Report Size (5)
|
|
0x81, 0x03, // Input (Cnst, Var, Abs)
|
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
|
0x09, 0x30, // Usage (X)
|
|
0x09, 0x31, // Usage (Y)
|
|
0x16, 0x00, 0x00, // Logical Minimum (0)
|
|
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
|
|
0x36, 0x00, 0x00, // Physical Minimum (0)
|
|
0x46, 0xFF, 0x7F, // Physical Maximum (32767)
|
|
0x75, 0x10, // Report Size (16)
|
|
0x95, 0x02, // Report Count (2)
|
|
0x81, 0x02, // Input (Data, Var, Abs)
|
|
0xC0, // End Collection
|
|
|
|
// Report ID 2: Relative Wheel Movement
|
|
0x85, 0x02, // Report ID (2)
|
|
0x09, 0x38, // Usage (Wheel)
|
|
0x15, 0x81, // Logical Minimum (-127)
|
|
0x25, 0x7F, // Logical Maximum (127)
|
|
0x75, 0x08, // Report Size (8)
|
|
0x95, 0x01, // Report Count (1)
|
|
0x81, 0x06, // Input (Data, Var, Rel)
|
|
|
|
0xC0, // End Collection
|
|
}
|
|
|
|
func (u *UsbGadget) absMouseWriteHidFile(data []byte) error {
|
|
if u.absMouseHidFile == nil {
|
|
var err error
|
|
u.absMouseHidFile, err = os.OpenFile("/dev/hidg1", os.O_RDWR, 0666)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open hidg1: %w", err)
|
|
}
|
|
}
|
|
|
|
_, err := u.absMouseHidFile.Write(data)
|
|
if err != nil {
|
|
u.log.Errorf("failed to write to hidg1: %w", err)
|
|
u.absMouseHidFile.Close()
|
|
u.absMouseHidFile = nil
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (u *UsbGadget) AbsMouseReport(x, 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
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
u.resetUserInputTime()
|
|
return nil
|
|
}
|
|
|
|
func (u *UsbGadget) AbsMouseWheelReport(wheelY int8) error {
|
|
u.absMouseLock.Lock()
|
|
defer u.absMouseLock.Unlock()
|
|
|
|
// Accumulate the wheelY value
|
|
u.absMouseAccumulatedWheelY += float64(wheelY) / 8.0
|
|
|
|
// Only send a report if the accumulated value is significant
|
|
if abs(u.absMouseAccumulatedWheelY) < 1.0 {
|
|
return nil
|
|
}
|
|
|
|
scaledWheelY := int8(u.absMouseAccumulatedWheelY)
|
|
|
|
err := u.absMouseWriteHidFile([]byte{
|
|
2, // Report ID 2
|
|
byte(scaledWheelY), // Scaled Wheel Y (signed)
|
|
})
|
|
|
|
// Reset the accumulator, keeping any remainder
|
|
u.absMouseAccumulatedWheelY -= float64(scaledWheelY)
|
|
|
|
u.resetUserInputTime()
|
|
return err
|
|
}
|