diff options
Diffstat (limited to 'kvmd/plugins/hid/otg')
-rw-r--r-- | kvmd/plugins/hid/otg/__init__.py | 45 | ||||
-rw-r--r-- | kvmd/plugins/hid/otg/events.py | 13 | ||||
-rw-r--r-- | kvmd/plugins/hid/otg/mouse.py | 19 |
3 files changed, 51 insertions, 26 deletions
diff --git a/kvmd/plugins/hid/otg/__init__.py b/kvmd/plugins/hid/otg/__init__.py index 030c551d..f4df4c63 100644 --- a/kvmd/plugins/hid/otg/__init__.py +++ b/kvmd/plugins/hid/otg/__init__.py @@ -27,7 +27,6 @@ from typing import AsyncGenerator from typing import Optional from typing import Any -from .... import tools from .... import aiomulti from ....yamlconf import Option @@ -59,30 +58,31 @@ class Plugin(BaseHid): # pylint: disable=too-many-instance-attributes self.__udc = UsbDeviceController(udc) + win98_fix = mouse.pop("absolute_win98_fix") common = { "udc": self.__udc, "noop": noop, "notifier": self.__notifier, } - self.__keyboard_proc = KeyboardProcess(**common, **keyboard) self.__mouse_current = self.__mouse_proc = MouseProcess(**common, **mouse) self.__mouse_alt_proc: Optional[MouseProcess] = None - self.__output_to_mouse: Dict[str, MouseProcess] = {} - self.__mouse_to_output: Dict[MouseProcess, str] = {} + self.__mouses: Dict[str, MouseProcess] = {} if mouse_alt["device_path"]: self.__mouse_alt_proc = MouseProcess( absolute=(not mouse["absolute"]), - absolute_win98_fix=mouse["absolute_win98_fix"], **common, **mouse_alt, ) - self.__output_to_mouse = { + self.__mouses = { "usb": (self.__mouse_proc if mouse["absolute"] else self.__mouse_alt_proc), "usb_rel": (self.__mouse_alt_proc if mouse["absolute"] else self.__mouse_proc), } - self.__mouse_to_output = tools.swapped_kvs(self.__output_to_mouse) + if win98_fix: + # На самом деле мультимышка и win95 не зависят друг от друга, + # но так было проще реализовать переключение режимов + self.__mouses["usb_win98"] = self.__mouses["usb"] @classmethod def get_plugin_options(cls) -> Dict: @@ -139,8 +139,8 @@ class Plugin(BaseHid): # pylint: disable=too-many-instance-attributes }, "mouse": { "outputs": { - "available": list(self.__output_to_mouse), - "active": (self.__mouse_to_output[self.__mouse_current] if self.__mouse_alt_proc else ""), + "available": list(self.__mouses), + "active": self.__get_current_mouse_mode(), }, **mouse_state, }, @@ -157,7 +157,9 @@ class Plugin(BaseHid): # pylint: disable=too-many-instance-attributes async def reset(self) -> None: self.__keyboard_proc.send_reset_event() - self.__mouse_current.send_reset_event() + self.__mouse_proc.send_reset_event() + if self.__mouse_alt_proc: + self.__mouse_alt_proc.send_reset_event() async def cleanup(self) -> None: try: @@ -188,12 +190,23 @@ class Plugin(BaseHid): # pylint: disable=too-many-instance-attributes def set_params(self, keyboard_output: Optional[str]=None, mouse_output: Optional[str]=None) -> None: _ = keyboard_output - if mouse_output != self.__mouse_to_output[self.__mouse_current]: - if mouse_output in self.__output_to_mouse: - self.__mouse_current.send_clear_event() - self.__mouse_current = self.__output_to_mouse[mouse_output] - self.__notifier.notify() + if mouse_output in self.__mouses and mouse_output != self.__get_current_mouse_mode(): + self.__mouse_current.send_clear_event() + self.__mouse_current = self.__mouses[mouse_output] + self.__mouse_current.set_win98_fix(mouse_output == "usb_win98") + self.__notifier.notify() def clear_events(self) -> None: self.__keyboard_proc.send_clear_event() - self.__mouse_current.send_clear_event() + self.__mouse_proc.send_clear_event() + if self.__mouse_alt_proc: + self.__mouse_alt_proc.send_clear_event() + + # ===== + + def __get_current_mouse_mode(self) -> str: + if len(self.__mouses) == 0: + return "" + if self.__mouse_current.is_absolute(): + return ("usb_win98" if self.__mouse_current.get_win98_fix() else "usb") + return "usb_rel" diff --git a/kvmd/plugins/hid/otg/events.py b/kvmd/plugins/hid/otg/events.py index 229f4faa..5bbffcd6 100644 --- a/kvmd/plugins/hid/otg/events.py +++ b/kvmd/plugins/hid/otg/events.py @@ -124,14 +124,23 @@ class MouseButtonEvent(BaseEvent): class MouseMoveEvent(BaseEvent): to_x: int to_y: int + win98_fix: bool = False to_fixed_x: int = 0 to_fixed_y: int = 0 def __post_init__(self) -> None: assert MouseRange.MIN <= self.to_x <= MouseRange.MAX assert MouseRange.MIN <= self.to_y <= MouseRange.MAX - object.__setattr__(self, "to_fixed_x", MouseRange.remap(self.to_x, 0, MouseRange.MAX)) - object.__setattr__(self, "to_fixed_y", MouseRange.remap(self.to_y, 0, MouseRange.MAX)) + to_fixed_x = MouseRange.remap(self.to_x, 0, MouseRange.MAX) + to_fixed_y = MouseRange.remap(self.to_y, 0, MouseRange.MAX) + if self.win98_fix: + # https://github.com/pikvm/pikvm/issues/159 + # For some reason, the correct implementation of this fix + # is a shift to the left, and not to the right, as in VirtualBox + to_fixed_x <<= 1 + to_fixed_y <<= 1 + object.__setattr__(self, "to_fixed_x", to_fixed_x) + object.__setattr__(self, "to_fixed_y", to_fixed_y) @dataclasses.dataclass(frozen=True) diff --git a/kvmd/plugins/hid/otg/mouse.py b/kvmd/plugins/hid/otg/mouse.py index 4ede3277..39e9657c 100644 --- a/kvmd/plugins/hid/otg/mouse.py +++ b/kvmd/plugins/hid/otg/mouse.py @@ -42,7 +42,6 @@ from .events import make_mouse_report class MouseProcess(BaseDeviceProcess): def __init__(self, **kwargs: Any) -> None: self.__absolute: bool = kwargs.pop("absolute") - self.__absolute_win98_fix: bool = kwargs.pop("absolute_win98_fix") self.__horizontal_wheel: bool = kwargs.pop("horizontal_wheel") super().__init__( @@ -55,6 +54,16 @@ class MouseProcess(BaseDeviceProcess): self.__pressed_buttons = 0 self.__x = 0 # For absolute self.__y = 0 + self.__win98_fix = False + + def is_absolute(self) -> bool: + return self.__absolute + + def set_win98_fix(self, enabled: bool) -> None: + self.__win98_fix = enabled + + def get_win98_fix(self) -> bool: + return self.__win98_fix def cleanup(self) -> None: self._stop() @@ -82,7 +91,7 @@ class MouseProcess(BaseDeviceProcess): def send_move_event(self, to_x: int, to_y: int) -> None: if self.__absolute: - self._queue_event(MouseMoveEvent(to_x, to_y)) + self._queue_event(MouseMoveEvent(to_x, to_y, self.__win98_fix)) def send_relative_event(self, delta_x: int, delta_y: int) -> None: if not self.__absolute: @@ -144,12 +153,6 @@ class MouseProcess(BaseDeviceProcess): assert relative_event is None move_x = self.__x move_y = self.__y - if self.__absolute_win98_fix: - # https://github.com/pikvm/pikvm/issues/159 - # For some reason, the correct implementation of this fix - # is a shift to the left, and not to the right, as in VirtualBox - move_x <<= 1 - move_y <<= 1 else: assert self.__x == self.__y == 0 if relative_event is not None: |