summaryrefslogtreecommitdiff
path: root/kvmd
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2024-11-20 17:50:27 +0200
committerMaxim Devaev <[email protected]>2024-11-20 17:50:27 +0200
commit3cbeabe2e86ba988f58c3a269889f1cc241b3ca8 (patch)
tree3dc7505c8018313a549eb1859e6a1926d2973740 /kvmd
parente9e7f9bd0553b77a993f560d64ec814f520852fb (diff)
VNC: Supported ExtendedMouseButtons
Diffstat (limited to 'kvmd')
-rw-r--r--kvmd/apps/vnc/rfb/__init__.py9
-rw-r--r--kvmd/apps/vnc/rfb/encodings.py18
-rw-r--r--kvmd/apps/vnc/server.py2
3 files changed, 20 insertions, 9 deletions
diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py
index d2c6b50b..fc6e435c 100644
--- a/kvmd/apps/vnc/rfb/__init__.py
+++ b/kvmd/apps/vnc/rfb/__init__.py
@@ -464,6 +464,10 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute
if self._encodings.has_ext_keys: # Preferred method
await self._write_fb_update("ExtKeys FBUR", 0, 0, RfbEncodings.EXT_KEYS, drain=True)
+
+ if self._encodings.has_ext_mouse: # Preferred too
+ await self._write_fb_update("ExtMouse FBUR", 0, 0, RfbEncodings.EXT_MOUSE, drain=True)
+
await self._on_set_encodings()
async def __handle_fb_update_request(self) -> None:
@@ -486,11 +490,16 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute
async def __handle_pointer_event(self) -> None:
(buttons, to_x, to_y) = await self._read_struct("pointer event", "B HH")
+ ext_buttons = 0
+ if self._encodings.has_ext_mouse and (buttons & 0x80): # Marker bit 7 for ext event
+ ext_buttons = await self._read_number("ext pointer event buttons", "B")
await self._on_pointer_event(
buttons={
"left": bool(buttons & 0x1),
"right": bool(buttons & 0x4),
"middle": bool(buttons & 0x2),
+ "up": bool(ext_buttons & 0x2),
+ "down": bool(ext_buttons & 0x1),
},
wheel={
"x": (-4 if buttons & 0x40 else (4 if buttons & 0x20 else 0)),
diff --git a/kvmd/apps/vnc/rfb/encodings.py b/kvmd/apps/vnc/rfb/encodings.py
index 597e3a92..940a383f 100644
--- a/kvmd/apps/vnc/rfb/encodings.py
+++ b/kvmd/apps/vnc/rfb/encodings.py
@@ -31,6 +31,7 @@ class RfbEncodings:
RENAME = -307 # DesktopName Pseudo-encoding
LEDS_STATE = -261 # QEMU LED State Pseudo-encoding
EXT_KEYS = -258 # QEMU Extended Key Events Pseudo-encoding
+ EXT_MOUSE = -316 # ExtendedMouseButtons Pseudo-encoding
CONT_UPDATES = -313 # ContinuousUpdates Pseudo-encoding
TIGHT = 7
@@ -50,16 +51,17 @@ def _make_meta(variants: (int | frozenset[int])) -> dict:
class RfbClientEncodings: # pylint: disable=too-many-instance-attributes
encodings: frozenset[int]
- has_resize: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RESIZE)) # noqa: E224
- has_rename: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RENAME)) # noqa: E224
- has_leds_state: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.LEDS_STATE)) # noqa: E224
- has_ext_keys: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.EXT_KEYS)) # noqa: E224
- has_cont_updates: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.CONT_UPDATES)) # noqa: E224
+ has_resize: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RESIZE)) # noqa: E224
+ has_rename: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RENAME)) # noqa: E224
+ has_leds_state: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.LEDS_STATE)) # noqa: E224
+ has_ext_keys: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.EXT_KEYS)) # noqa: E224
+ has_ext_mouse: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.EXT_MOUSE)) # noqa: E224
+ has_cont_updates: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.CONT_UPDATES)) # noqa: E224
- has_tight: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.TIGHT)) # noqa: E224
- tight_jpeg_quality: int = dataclasses.field(default=0, metadata=_make_meta(frozenset(RfbEncodings.TIGHT_JPEG_QUALITIES))) # noqa: E224
+ has_tight: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.TIGHT)) # noqa: E224
+ tight_jpeg_quality: int = dataclasses.field(default=0, metadata=_make_meta(frozenset(RfbEncodings.TIGHT_JPEG_QUALITIES))) # noqa: E224
- has_h264: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.H264)) # noqa: E224
+ has_h264: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.H264)) # noqa: E224
def get_summary(self) -> list[str]:
summary: list[str] = [f"encodings -- {sorted(self.encodings)}"]
diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py
index 5abca7b0..6bb7caed 100644
--- a/kvmd/apps/vnc/server.py
+++ b/kvmd/apps/vnc/server.py
@@ -130,7 +130,7 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
# Эти состояния шарить не обязательно - бекенд исключает дублирующиеся события.
# Все это нужно только чтобы не посылать лишние жсоны в сокет KVMD
- self.__mouse_buttons: dict[str, (bool | None)] = dict.fromkeys(["left", "right", "middle"], None)
+ self.__mouse_buttons: dict[str, (bool | None)] = dict.fromkeys(["left", "right", "middle", "up", "down"], None)
self.__mouse_move = {"x": -1, "y": -1}
self.__modifiers = 0