summaryrefslogtreecommitdiff
path: root/kvmd
diff options
context:
space:
mode:
authorDevaev Maxim <[email protected]>2020-11-03 06:17:52 +0300
committerDevaev Maxim <[email protected]>2020-11-03 06:17:52 +0300
commitc31115051cb17a650e6d42e3e5cbfe05de809760 (patch)
tree457dd0414d0840a64d5de9c491413c6b1de783a3 /kvmd
parent544f4b3fecb84e2ae21eb71ec0c37c8bec38261c (diff)
configurable wheel for otg
Diffstat (limited to 'kvmd')
-rw-r--r--kvmd/apps/otg/__init__.py15
-rw-r--r--kvmd/apps/otg/hid/keyboard.py95
-rw-r--r--kvmd/apps/otg/hid/mouse.py227
-rw-r--r--kvmd/plugins/hid/otg/__init__.py1
-rw-r--r--kvmd/plugins/hid/otg/mouse.py6
5 files changed, 177 insertions, 167 deletions
diff --git a/kvmd/apps/otg/__init__.py b/kvmd/apps/otg/__init__.py
index edaf541f..2750549a 100644
--- a/kvmd/apps/otg/__init__.py
+++ b/kvmd/apps/otg/__init__.py
@@ -42,9 +42,8 @@ from ... import env
from .. import init
from .hid import Hid
-from .hid.keyboard import KEYBOARD_HID
-from .hid.mouse import MOUSE_ABSOLUTE_HID
-from .hid.mouse import MOUSE_RELATIVE_HID
+from .hid.keyboard import make_keyboard_hid
+from .hid.mouse import make_mouse_hid
# =====
@@ -203,11 +202,11 @@ def _cmd_start(config: Section) -> None:
if config.kvmd.hid.type == "otg":
logger.info("===== Required HID =====")
- _create_hid(gadget_path, config_path, 0, KEYBOARD_HID)
- if config.kvmd.hid.mouse.absolute:
- _create_hid(gadget_path, config_path, 1, MOUSE_ABSOLUTE_HID)
- else:
- _create_hid(gadget_path, config_path, 1, MOUSE_RELATIVE_HID)
+ _create_hid(gadget_path, config_path, 0, make_keyboard_hid())
+ _create_hid(gadget_path, config_path, 1, make_mouse_hid(
+ absolute=config.kvmd.hid.mouse.absolute,
+ horizontal_wheel=config.kvmd.hid.mouse.horizontal_wheel,
+ ))
if config.kvmd.msd.type == "otg":
logger.info("===== Required MSD =====")
diff --git a/kvmd/apps/otg/hid/keyboard.py b/kvmd/apps/otg/hid/keyboard.py
index 35c0af30..c38a2bfb 100644
--- a/kvmd/apps/otg/hid/keyboard.py
+++ b/kvmd/apps/otg/hid/keyboard.py
@@ -24,59 +24,60 @@ from . import Hid
# =====
-KEYBOARD_HID = Hid(
- protocol=1, # Keyboard protocol
- subclass=1, # Boot interface subclass
+def make_keyboard_hid() -> Hid:
+ return Hid(
+ protocol=1, # Keyboard protocol
+ subclass=1, # Boot interface subclass
- report_length=8,
+ report_length=8,
- report_descriptor=bytes([
- # Logitech descriptor. It's very similar to https://www.kernel.org/doc/Documentation/usb/gadget_hid.txt
- # Dumped using usbhid-dump; parsed using https://eleccelerator.com/usbdescreqparser
+ report_descriptor=bytes([
+ # Logitech descriptor. It's very similar to https://www.kernel.org/doc/Documentation/usb/gadget_hid.txt
+ # Dumped using usbhid-dump; parsed using https://eleccelerator.com/usbdescreqparser
- # Keyboard
- 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
- 0x09, 0x06, # USAGE (Keyboard)
- 0xA1, 0x01, # COLLECTION (Application)
+ # Keyboard
+ 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
+ 0x09, 0x06, # USAGE (Keyboard)
+ 0xA1, 0x01, # COLLECTION (Application)
- # Modifiers
- 0x05, 0x07, # USAGE_PAGE (Keyboard)
- 0x19, 0xE0, # USAGE_MINIMUM (Keyboard LeftControl)
- 0x29, 0xE7, # USAGE_MAXIMUM (Keyboard Right GUI)
- 0x15, 0x00, # LOGICAL_MINIMUM (0)
- 0x25, 0x01, # LOGICAL_MAXIMUM (1)
- 0x75, 0x01, # REPORT_SIZE (1)
- 0x95, 0x08, # REPORT_COUNT (8)
- 0x81, 0x02, # INPUT (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ # Modifiers
+ 0x05, 0x07, # USAGE_PAGE (Keyboard)
+ 0x19, 0xE0, # USAGE_MINIMUM (Keyboard LeftControl)
+ 0x29, 0xE7, # USAGE_MAXIMUM (Keyboard Right GUI)
+ 0x15, 0x00, # LOGICAL_MINIMUM (0)
+ 0x25, 0x01, # LOGICAL_MAXIMUM (1)
+ 0x75, 0x01, # REPORT_SIZE (1)
+ 0x95, 0x08, # REPORT_COUNT (8)
+ 0x81, 0x02, # INPUT (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
- # Reserved byte
- 0x95, 0x01, # REPORT_COUNT (1)
- 0x75, 0x08, # REPORT_SIZE (8)
- 0x81, 0x01, # INPUT (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ # Reserved byte
+ 0x95, 0x01, # REPORT_COUNT (1)
+ 0x75, 0x08, # REPORT_SIZE (8)
+ 0x81, 0x01, # INPUT (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
- # LEDs output
- 0x95, 0x05, # REPORT_COUNT (5)
- 0x75, 0x01, # REPORT_SIZE (1)
- 0x05, 0x08, # USAGE_PAGE (LEDs)
- 0x19, 0x01, # USAGE_MINIMUM (Num Lock)
- 0x29, 0x05, # USAGE_MAXIMUM (Kana)
- 0x91, 0x02, # OUTPUT (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ # LEDs output
+ 0x95, 0x05, # REPORT_COUNT (5)
+ 0x75, 0x01, # REPORT_SIZE (1)
+ 0x05, 0x08, # USAGE_PAGE (LEDs)
+ 0x19, 0x01, # USAGE_MINIMUM (Num Lock)
+ 0x29, 0x05, # USAGE_MAXIMUM (Kana)
+ 0x91, 0x02, # OUTPUT (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
- # Reserved 3 bits in output
- 0x95, 0x01, # REPORT_COUNT (1)
- 0x75, 0x03, # REPORT_SIZE (3)
- 0x91, 0x01, # OUTPUT (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ # Reserved 3 bits in output
+ 0x95, 0x01, # REPORT_COUNT (1)
+ 0x75, 0x03, # REPORT_SIZE (3)
+ 0x91, 0x01, # OUTPUT (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
- # 6 keys
- 0x95, 0x06, # REPORT_COUNT (6)
- 0x75, 0x08, # REPORT_SIZE (8)
- 0x15, 0x00, # LOGICAL_MINIMUM (0)
- 0x26, 0xFF, 0x00, # LOGICAL_MAXIMUM (0xFF)
- 0x05, 0x07, # USAGE_PAGE (Keyboard)
- 0x19, 0x00, # USAGE_MINIMUM (Reserved)
- 0x2A, 0xFF, 0x00, # USAGE_MAXIMUM (0xFF)
- 0x81, 0x00, # INPUT (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ # 6 keys
+ 0x95, 0x06, # REPORT_COUNT (6)
+ 0x75, 0x08, # REPORT_SIZE (8)
+ 0x15, 0x00, # LOGICAL_MINIMUM (0)
+ 0x26, 0xFF, 0x00, # LOGICAL_MAXIMUM (0xFF)
+ 0x05, 0x07, # USAGE_PAGE (Keyboard)
+ 0x19, 0x00, # USAGE_MINIMUM (Reserved)
+ 0x2A, 0xFF, 0x00, # USAGE_MAXIMUM (0xFF)
+ 0x81, 0x00, # INPUT (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
- 0xC0, # END_COLLECTION
- ]),
-)
+ 0xC0, # END_COLLECTION
+ ]),
+ )
diff --git a/kvmd/apps/otg/hid/mouse.py b/kvmd/apps/otg/hid/mouse.py
index dfb5adec..9dcc0e5d 100644
--- a/kvmd/apps/otg/hid/mouse.py
+++ b/kvmd/apps/otg/hid/mouse.py
@@ -24,114 +24,119 @@ from . import Hid
# =====
-MOUSE_ABSOLUTE_HID = Hid(
- protocol=0, # None protocol
- subclass=0, # No subclass
-
- report_length=7,
-
- report_descriptor=bytes([
- # https://github.com/NicoHood/HID/blob/0835e6a/src/SingleReport/SingleAbsoluteMouse.cpp
- # Репорт взят отсюда ^^^, но изменен диапазон значений координат перемещений.
- # Автор предлагает использовать -32768...32767, но семерка почему-то не хочет работать
- # с отрицательными значениями координат, как не хочет хавать 65536 и 32768.
- # Так что мы ей скармливаем диапазон 0...32767, и передаем рукожопам из микрософта привет,
- # потому что линуксы прекрасно работают с любыми двухбайтовыми диапазонами.
-
- # Absolute mouse
- 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
- 0x09, 0x02, # USAGE (Mouse)
- 0xA1, 0x01, # COLLECTION (Application)
-
- # 8 Buttons
- 0x05, 0x09, # USAGE_PAGE (Button)
- 0x19, 0x01, # USAGE_MINIMUM (Button 1)
- 0x29, 0x08, # USAGE_MAXIMUM (Button 8)
- 0x15, 0x00, # LOGICAL_MINIMUM (0)
- 0x25, 0x01, # LOGICAL_MAXIMUM (1)
- 0x95, 0x08, # REPORT_COUNT (8)
- 0x75, 0x01, # REPORT_SIZE (1)
- 0x81, 0x02, # INPUT (Data,Var,Abs)
-
- # X, Y
- 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
- 0x09, 0x30, # USAGE (X)
- 0x09, 0x31, # USAGE (Y)
- 0x16, 0x00, 0x00, # LOGICAL_MINIMUM (0)
- 0x26, 0xFF, 0x7F, # LOGICAL_MAXIMUM (32767)
- 0x75, 0x10, # REPORT_SIZE (16)
- 0x95, 0x02, # REPORT_COUNT (2)
- 0x81, 0x02, # INPUT (Data,Var,Abs)
-
- # Wheel
- 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)
-
- # Horizontal wheel
- 0x05, 0x0C, # USAGE PAGE (Consumer Devices)
- 0x0A, 0x38, 0x02, # USAGE (AC Pan)
- 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)
-
- # End
- 0xC0, # END_COLLECTION
- ]),
-)
-
-MOUSE_RELATIVE_HID = Hid(
- protocol=2, # Mouse protocol
- subclass=1, # Boot interface subclass
-
- report_length=5,
-
- report_descriptor=bytes([
- # https://github.com/NicoHood/HID/blob/0835e6a/src/SingleReport/BootMouse.cpp
-
- # Relative mouse
- 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
- 0x09, 0x02, # USAGE (Mouse)
- 0xA1, 0x01, # COLLECTION (Application)
-
- # 8 Buttons
- 0x05, 0x09, # USAGE_PAGE (Button)
- 0x19, 0x01, # USAGE_MINIMUM (Button 1)
- 0x29, 0x08, # USAGE_MAXIMUM (Button 8)
- 0x15, 0x00, # LOGICAL_MINIMUM (0)
- 0x25, 0x01, # LOGICAL_MAXIMUM (1)
- 0x95, 0x08, # REPORT_COUNT (8)
- 0x75, 0x01, # REPORT_SIZE (1)
- 0x81, 0x02, # INPUT (Data,Var,Abs)
-
- # X, Y
- 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
- 0x09, 0x30, # USAGE (X)
- 0x09, 0x31, # USAGE (Y)
-
- # Wheel
- 0x09, 0x38, # USAGE (Wheel)
- 0x15, 0x81, # LOGICAL_MINIMUM (-127)
- 0x25, 0x7F, # LOGICAL_MAXIMUM (127)
- 0x75, 0x08, # REPORT_SIZE (8)
- 0x95, 0x03, # REPORT_COUNT (3)
- 0x81, 0x06, # INPUT (Data,Var,Rel)
-
- # Horizontal wheel
- 0x05, 0x0C, # USAGE PAGE (Consumer Devices)
- 0x0A, 0x38, 0x02, # USAGE (AC Pan)
- 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)
-
- # End
- 0xC0, # END_COLLECTION
- ]),
-)
+def make_mouse_hid(absolute: bool, horizontal_wheel: bool) -> Hid:
+ maker = (_make_absolute_hid if absolute else _make_relative_hid)
+ return maker(horizontal_wheel)
+
+
+_HORIZONTAL_WHEEL = [
+ 0x05, 0x0C, # USAGE PAGE (Consumer Devices)
+ 0x0A, 0x38, 0x02, # USAGE (AC Pan)
+ 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)
+]
+
+
+def _make_absolute_hid(horizontal_wheel: bool) -> Hid:
+ return Hid(
+ protocol=0, # None protocol
+ subclass=0, # No subclass
+
+ report_length=(7 if horizontal_wheel else 6),
+
+ report_descriptor=bytes([
+ # https://github.com/NicoHood/HID/blob/0835e6a/src/SingleReport/SingleAbsoluteMouse.cpp
+ # Репорт взят отсюда ^^^, но изменен диапазон значений координат перемещений.
+ # Автор предлагает использовать -32768...32767, но семерка почему-то не хочет работать
+ # с отрицательными значениями координат, как не хочет хавать 65536 и 32768.
+ # Так что мы ей скармливаем диапазон 0...32767, и передаем рукожопам из микрософта привет,
+ # потому что линуксы прекрасно работают с любыми двухбайтовыми диапазонами.
+
+ # Absolute mouse
+ 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
+ 0x09, 0x02, # USAGE (Mouse)
+ 0xA1, 0x01, # COLLECTION (Application)
+
+ # 8 Buttons
+ 0x05, 0x09, # USAGE_PAGE (Button)
+ 0x19, 0x01, # USAGE_MINIMUM (Button 1)
+ 0x29, 0x08, # USAGE_MAXIMUM (Button 8)
+ 0x15, 0x00, # LOGICAL_MINIMUM (0)
+ 0x25, 0x01, # LOGICAL_MAXIMUM (1)
+ 0x95, 0x08, # REPORT_COUNT (8)
+ 0x75, 0x01, # REPORT_SIZE (1)
+ 0x81, 0x02, # INPUT (Data,Var,Abs)
+
+ # X, Y
+ 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
+ 0x09, 0x30, # USAGE (X)
+ 0x09, 0x31, # USAGE (Y)
+ 0x16, 0x00, 0x00, # LOGICAL_MINIMUM (0)
+ 0x26, 0xFF, 0x7F, # LOGICAL_MAXIMUM (32767)
+ 0x75, 0x10, # REPORT_SIZE (16)
+ 0x95, 0x02, # REPORT_COUNT (2)
+ 0x81, 0x02, # INPUT (Data,Var,Abs)
+
+ # Wheel
+ 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)
+
+ *(_HORIZONTAL_WHEEL if horizontal_wheel else []),
+
+ # End
+ 0xC0, # END_COLLECTION
+ ]),
+ )
+
+
+def _make_relative_hid(horizontal_wheel: bool) -> Hid:
+ return Hid(
+ protocol=2, # Mouse protocol
+ subclass=1, # Boot interface subclass
+
+ report_length=(5 if horizontal_wheel else 4),
+
+ report_descriptor=bytes([
+ # https://github.com/NicoHood/HID/blob/0835e6a/src/SingleReport/BootMouse.cpp
+
+ # Relative mouse
+ 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
+ 0x09, 0x02, # USAGE (Mouse)
+ 0xA1, 0x01, # COLLECTION (Application)
+
+ # 8 Buttons
+ 0x05, 0x09, # USAGE_PAGE (Button)
+ 0x19, 0x01, # USAGE_MINIMUM (Button 1)
+ 0x29, 0x08, # USAGE_MAXIMUM (Button 8)
+ 0x15, 0x00, # LOGICAL_MINIMUM (0)
+ 0x25, 0x01, # LOGICAL_MAXIMUM (1)
+ 0x95, 0x08, # REPORT_COUNT (8)
+ 0x75, 0x01, # REPORT_SIZE (1)
+ 0x81, 0x02, # INPUT (Data,Var,Abs)
+
+ # X, Y
+ 0x05, 0x01, # USAGE_PAGE (Generic Desktop)
+ 0x09, 0x30, # USAGE (X)
+ 0x09, 0x31, # USAGE (Y)
+
+ # Wheel
+ 0x09, 0x38, # USAGE (Wheel)
+ 0x15, 0x81, # LOGICAL_MINIMUM (-127)
+ 0x25, 0x7F, # LOGICAL_MAXIMUM (127)
+ 0x75, 0x08, # REPORT_SIZE (8)
+ 0x95, 0x03, # REPORT_COUNT (3)
+ 0x81, 0x06, # INPUT (Data,Var,Rel)
+
+ *(_HORIZONTAL_WHEEL if horizontal_wheel else []),
+
+ # End
+ 0xC0, # END_COLLECTION
+ ]),
+ )
diff --git a/kvmd/plugins/hid/otg/__init__.py b/kvmd/plugins/hid/otg/__init__.py
index 9521e764..aa3d79b2 100644
--- a/kvmd/plugins/hid/otg/__init__.py
+++ b/kvmd/plugins/hid/otg/__init__.py
@@ -76,6 +76,7 @@ class Plugin(BaseHid):
"write_retries_delay": Option(0.1, type=valid_float_f01),
"reopen_delay": Option(0.5, type=valid_float_f01),
"absolute": Option(True, type=valid_bool),
+ "horizontal_wheel": Option(True, type=valid_bool),
},
"noop": Option(False, type=valid_bool),
}
diff --git a/kvmd/plugins/hid/otg/mouse.py b/kvmd/plugins/hid/otg/mouse.py
index e8e5c6e7..079a7dc3 100644
--- a/kvmd/plugins/hid/otg/mouse.py
+++ b/kvmd/plugins/hid/otg/mouse.py
@@ -69,6 +69,7 @@ class _WheelEvent(BaseEvent):
class MouseProcess(BaseDeviceProcess):
def __init__(self, **kwargs: Any) -> None:
self.__absolute: bool = kwargs.pop("absolute")
+ self.__horizontal_wheel: bool = kwargs.pop("horizontal_wheel")
super().__init__(
name="mouse",
@@ -212,4 +213,7 @@ class MouseProcess(BaseDeviceProcess):
def __make_report(self, buttons: int, move_x: int, move_y: int, wheel_x: int, wheel_y: int) -> bytes:
# XXX: Wheel Y before X: it's ok.
# See /kvmd/apps/otg/hid/mouse.py for details
- return struct.pack(("<BHHbb" if self.__absolute else "<Bbbbb"), buttons, move_x, move_y, wheel_y, wheel_x)
+ if self.__horizontal_wheel:
+ return struct.pack(("<BHHbb" if self.__absolute else "<Bbbbb"), buttons, move_x, move_y, wheel_y, wheel_x)
+ else:
+ return struct.pack(("<BHHb" if self.__absolute else "<Bbbb"), buttons, move_x, move_y, wheel_y)