refactoring

This commit is contained in:
Devaev Maxim 2020-11-07 12:12:40 +03:00
parent 8f4b943a8d
commit 5f407fd4a0
3 changed files with 78 additions and 33 deletions

View File

@ -20,8 +20,12 @@
# ========================================================================== # # ========================================================================== #
import struct
import dataclasses import dataclasses
from typing import List
from typing import Set
from typing import Optional
from typing import Union from typing import Union
from ....keyboard.mappings import OtgKey from ....keyboard.mappings import OtgKey
@ -67,6 +71,36 @@ def make_keyboard_event(key: str, state: bool) -> Union[KeyEvent, ModifierEvent]
return KeyEvent(otg_key, state) return KeyEvent(otg_key, state)
def get_led_caps(flags: int) -> bool:
# https://wiki.osdev.org/USB_Human_Interface_Devices#LED_lamps
return bool(flags & 2)
def get_led_scroll(flags: int) -> bool:
return bool(flags & 4)
def get_led_num(flags: int) -> bool:
return bool(flags & 1)
def make_keyboard_report(
pressed_modifiers: Set[OtgKey],
pressed_keys: List[Optional[OtgKey]],
) -> bytes:
modifiers = 0
for modifier in pressed_modifiers:
modifiers |= modifier.code
assert len(pressed_keys) == 6
keys = [
(0 if key is None else key.code)
for key in pressed_keys
]
return bytes([modifiers, 0] + keys)
# ===== # =====
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class MouseButtonEvent(BaseEvent): class MouseButtonEvent(BaseEvent):
@ -116,3 +150,21 @@ class MouseWheelEvent(BaseEvent):
def __post_init__(self) -> None: def __post_init__(self) -> None:
assert -127 <= self.delta_x <= 127 assert -127 <= self.delta_x <= 127
assert -127 <= self.delta_y <= 127 assert -127 <= self.delta_y <= 127
def make_mouse_report(
absolute: bool,
buttons: int,
move_x: int,
move_y: int,
wheel_x: Optional[int],
wheel_y: int,
) -> bytes:
# XXX: Wheel Y before X: it's ok.
# See /kvmd/apps/otg/hid/mouse.py for details
if wheel_x is not None:
return struct.pack(("<BHHbb" if absolute else "<Bbbbb"), buttons, move_x, move_y, wheel_y, wheel_x)
else:
return struct.pack(("<BHHb" if absolute else "<Bbbb"), buttons, move_x, move_y, wheel_y)

View File

@ -39,6 +39,10 @@ from .events import ResetEvent
from .events import KeyEvent from .events import KeyEvent
from .events import ModifierEvent from .events import ModifierEvent
from .events import make_keyboard_event from .events import make_keyboard_event
from .events import get_led_caps
from .events import get_led_scroll
from .events import get_led_num
from .events import make_keyboard_report
# ===== # =====
@ -74,12 +78,11 @@ class KeyboardProcess(BaseDeviceProcess):
# ===== # =====
def _process_read_report(self, report: bytes) -> None: def _process_read_report(self, report: bytes) -> None:
# https://wiki.osdev.org/USB_Human_Interface_Devices#LED_lamps
assert len(report) == 1, report assert len(report) == 1, report
self._update_state( self._update_state(
caps=bool(report[0] & 2), caps=get_led_caps(report[0]),
scroll=bool(report[0] & 4), scroll=get_led_scroll(report[0]),
num=bool(report[0] & 1), num=get_led_num(report[0]),
) )
# ===== # =====
@ -132,7 +135,8 @@ class KeyboardProcess(BaseDeviceProcess):
# ===== # =====
def __send_current_state(self, reopen: bool=False) -> bool: def __send_current_state(self, reopen: bool=False) -> bool:
if not self._ensure_write(self.__make_report(), reopen=reopen): report = make_keyboard_report(self.__pressed_modifiers, self.__pressed_keys)
if not self._ensure_write(report, reopen=reopen):
self.__clear_modifiers() self.__clear_modifiers()
self.__clear_keys() self.__clear_keys()
return False return False
@ -143,16 +147,3 @@ class KeyboardProcess(BaseDeviceProcess):
def __clear_keys(self) -> None: def __clear_keys(self) -> None:
self.__pressed_keys = [None] * 6 self.__pressed_keys = [None] * 6
def __make_report(self) -> bytes:
modifiers = 0
for modifier in self.__pressed_modifiers:
modifiers |= modifier.code
assert len(self.__pressed_keys) == 6
keys = [
(0 if key is None else key.code)
for key in self.__pressed_keys
]
return bytes([modifiers, 0] + keys)

View File

@ -20,8 +20,6 @@
# ========================================================================== # # ========================================================================== #
import struct
from typing import Optional from typing import Optional
from typing import Any from typing import Any
@ -36,6 +34,7 @@ from .events import MouseButtonEvent
from .events import MouseMoveEvent from .events import MouseMoveEvent
from .events import MouseRelativeEvent from .events import MouseRelativeEvent
from .events import MouseWheelEvent from .events import MouseWheelEvent
from .events import make_mouse_report
# ===== # =====
@ -58,10 +57,14 @@ class MouseProcess(BaseDeviceProcess):
def cleanup(self) -> None: def cleanup(self) -> None:
self._stop() self._stop()
get_logger().info("Clearing HID-mouse events ...") get_logger().info("Clearing HID-mouse events ...")
if self.__absolute: report = make_mouse_report(
report = self.__make_report(0, self.__x, self.__y, 0, 0) absolute=self.__absolute,
else: buttons=0,
report = self.__make_report(0, 0, 0, 0, 0) move_x=(self.__x if self.__absolute else 0),
move_y=(self.__y if self.__absolute else 0),
wheel_x=(0 if self.__horizontal_wheel else None),
wheel_y=0,
)
self._ensure_write(report, close=True) # Release all buttons self._ensure_write(report, close=True) # Release all buttons
def send_clear_event(self) -> None: def send_clear_event(self) -> None:
@ -157,7 +160,14 @@ class MouseProcess(BaseDeviceProcess):
else: else:
wheel_x = wheel_y = 0 wheel_x = wheel_y = 0
report = self.__make_report(self.__pressed_buttons, move_x, move_y, wheel_x, wheel_y) report = make_mouse_report(
absolute=self.__absolute,
buttons=self.__pressed_buttons,
move_x=move_x,
move_y=move_y,
wheel_x=(wheel_x if self.__horizontal_wheel else None),
wheel_y=wheel_y,
)
if not self._ensure_write(report, reopen=reopen): if not self._ensure_write(report, reopen=reopen):
self.__clear_state() self.__clear_state()
return False return False
@ -167,11 +177,3 @@ class MouseProcess(BaseDeviceProcess):
self.__pressed_buttons = 0 self.__pressed_buttons = 0
self.__x = 0 self.__x = 0
self.__y = 0 self.__y = 0
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
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)