diff options
-rw-r--r-- | hid/src/main.cpp | 18 | ||||
-rw-r--r-- | hid/src/usb/hid.h | 6 | ||||
-rw-r--r-- | kvmd/apps/vnc/rfb/__init__.py | 2 | ||||
-rw-r--r-- | kvmd/apps/vnc/server.py | 2 | ||||
-rw-r--r-- | kvmd/plugins/hid/otg/mouse.py | 2 | ||||
-rw-r--r-- | kvmd/plugins/hid/serial.py | 20 | ||||
-rw-r--r-- | kvmd/validators/kvm.py | 2 | ||||
-rw-r--r-- | testenv/tests/validators/test_kvm.py | 2 | ||||
-rw-r--r-- | web/kvm/index.html | 7 | ||||
-rw-r--r-- | web/kvm/window-stream.pug | 6 | ||||
-rw-r--r-- | web/share/js/kvm/mouse.js | 2 |
11 files changed, 54 insertions, 15 deletions
diff --git a/hid/src/main.cpp b/hid/src/main.cpp index 08ec3f65..cd3c245a 100644 --- a/hid/src/main.cpp +++ b/hid/src/main.cpp @@ -66,6 +66,11 @@ #define PROTO_CMD_MOUSE_BUTTON_MIDDLE_SELECT 0b00100000 #define PROTO_CMD_MOUSE_BUTTON_MIDDLE_STATE 0b00000010 +#define PROTO_CMD_MOUSE_BUTTON_EXTRA_UP_SELECT 0b10000000 +#define PROTO_CMD_MOUSE_BUTTON_EXTRA_UP_STATE 0b00001000 +#define PROTO_CMD_MOUSE_BUTTON_EXTRA_DOWN_SELECT 0b01000000 +#define PROTO_CMD_MOUSE_BUTTON_EXTRA_DOWN_STATE 0b00000100 + // ----------------------------------------------------------------------------- #ifdef HID_USB_KBD @@ -94,14 +99,17 @@ INLINE uint8_t cmdKeyEvent(const uint8_t *buffer) { // 2 bytes return PROTO_RESP_OK; } -INLINE uint8_t cmdMouseButtonEvent(const uint8_t *buffer) { // 1 byte +INLINE uint8_t cmdMouseButtonEvent(const uint8_t *buffer) { // 2 bytes # ifdef HID_USB_MOUSE - uint8_t state = buffer[0]; + uint8_t main_state = buffer[0]; + uint8_t extra_state = buffer[1]; hid_mouse.sendMouseButtons( - state & PROTO_CMD_MOUSE_BUTTON_LEFT_SELECT, state & PROTO_CMD_MOUSE_BUTTON_LEFT_STATE, - state & PROTO_CMD_MOUSE_BUTTON_RIGHT_SELECT, state & PROTO_CMD_MOUSE_BUTTON_RIGHT_STATE, - state & PROTO_CMD_MOUSE_BUTTON_MIDDLE_SELECT, state & PROTO_CMD_MOUSE_BUTTON_MIDDLE_STATE + main_state & PROTO_CMD_MOUSE_BUTTON_LEFT_SELECT, main_state & PROTO_CMD_MOUSE_BUTTON_LEFT_STATE, + main_state & PROTO_CMD_MOUSE_BUTTON_RIGHT_SELECT, main_state & PROTO_CMD_MOUSE_BUTTON_RIGHT_STATE, + main_state & PROTO_CMD_MOUSE_BUTTON_MIDDLE_SELECT, main_state & PROTO_CMD_MOUSE_BUTTON_MIDDLE_STATE, + extra_state & PROTO_CMD_MOUSE_BUTTON_EXTRA_UP_SELECT, extra_state & PROTO_CMD_MOUSE_BUTTON_EXTRA_UP_STATE, + extra_state & PROTO_CMD_MOUSE_BUTTON_EXTRA_DOWN_SELECT, extra_state & PROTO_CMD_MOUSE_BUTTON_EXTRA_DOWN_STATE ); # endif return PROTO_RESP_OK; diff --git a/hid/src/usb/hid.h b/hid/src/usb/hid.h index 48e99d28..b4523a6b 100644 --- a/hid/src/usb/hid.h +++ b/hid/src/usb/hid.h @@ -76,11 +76,15 @@ class UsbHidMouse { INLINE void sendMouseButtons( bool left_select, bool left_state, bool right_select, bool right_state, - bool middle_select, bool middle_state + bool middle_select, bool middle_state, + bool up_select, bool up_state, + bool down_select, bool down_state ) { if (left_select) _sendMouseButton(MOUSE_LEFT, left_state); if (right_select) _sendMouseButton(MOUSE_RIGHT, right_state); if (middle_select) _sendMouseButton(MOUSE_MIDDLE, middle_state); + if (up_select) _sendMouseButton(MOUSE_PREV, up_state); + if (down_select) _sendMouseButton(MOUSE_NEXT, down_state); } INLINE void sendMouseMove(int x, int y) { diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py index f10d7da2..27aa41ad 100644 --- a/kvmd/apps/vnc/rfb/__init__.py +++ b/kvmd/apps/vnc/rfb/__init__.py @@ -400,6 +400,8 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute "left": bool(buttons & 0x1), "right": bool(buttons & 0x4), "middle": bool(buttons & 0x2), + "up": bool(buttons & 0x8), # Back + "down": bool(buttons & 0x10), # Forward }, wheel={ "x": (-4 if buttons & 0x40 else (4 if buttons & 0x20 else 0)), diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py index 2ab03f36..cb769481 100644 --- a/kvmd/apps/vnc/server.py +++ b/kvmd/apps/vnc/server.py @@ -114,7 +114,7 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes # Эти состояния шарить не обязательно - бекенд исключает дублирующиеся события. # Все это нужно только чтобы не посылать лишние жсоны в сокет KVMD - self.__mouse_buttons: Dict[str, Optional[bool]] = {"left": None, "right": None, "middle": None} + self.__mouse_buttons: Dict[str, Optional[bool]] = dict.fromkeys(["left", "right", "middle", "up", "down"], None) self.__mouse_move = {"x": -1, "y": -1} self.__lock = asyncio.Lock() diff --git a/kvmd/plugins/hid/otg/mouse.py b/kvmd/plugins/hid/otg/mouse.py index 3c41eb40..adb2469f 100644 --- a/kvmd/plugins/hid/otg/mouse.py +++ b/kvmd/plugins/hid/otg/mouse.py @@ -91,6 +91,8 @@ class MouseProcess(BaseDeviceProcess): "left": 0x1, "right": 0x2, "middle": 0x4, + "up": 0x8, # Back + "down": 0x10, # Forward }[button] self._queue_event(_ButtonEvent(code, state)) diff --git a/kvmd/plugins/hid/serial.py b/kvmd/plugins/hid/serial.py index e9b65479..752870d7 100644 --- a/kvmd/plugins/hid/serial.py +++ b/kvmd/plugins/hid/serial.py @@ -108,17 +108,25 @@ class _MouseButtonEvent(_BaseEvent): state: bool def __post_init__(self) -> None: - assert self.name in ["left", "right", "middle"] + assert self.name in ["left", "right", "middle", "up", "down"] def make_command(self) -> bytes: - (code, state_pressed) = { - "left": (0b10000000, 0b00001000), - "right": (0b01000000, 0b00000100), - "middle": (0b00100000, 0b00000010), + (code, state_pressed, is_main) = { + "left": (0b10000000, 0b00001000, True), + "right": (0b01000000, 0b00000100, True), + "middle": (0b00100000, 0b00000010, True), + "up": (0b10000000, 0b00001000, False), # Back + "down": (0b01000000, 0b00000100, False), # Forward }[self.name] if self.state: code |= state_pressed - return struct.pack(">BBxxx", 0x13, code) + if is_main: + main_code = code + extra_code = 0 + else: + main_code = 0 + extra_code = code + return struct.pack(">BBBxx", 0x13, main_code, extra_code) @dataclasses.dataclass(frozen=True) diff --git a/kvmd/validators/kvm.py b/kvmd/validators/kvm.py index b32a785e..140c282c 100644 --- a/kvmd/validators/kvm.py +++ b/kvmd/validators/kvm.py @@ -80,7 +80,7 @@ def valid_hid_mouse_move(arg: Any) -> int: def valid_hid_mouse_button(arg: Any) -> str: - return check_string_in_list(arg, "HID mouse button", ["left", "right", "middle"]) + return check_string_in_list(arg, "HID mouse button", ["left", "right", "middle", "up", "down"]) def valid_hid_mouse_wheel(arg: Any) -> int: diff --git a/testenv/tests/validators/test_kvm.py b/testenv/tests/validators/test_kvm.py index 71ec1b26..0fdf6a9a 100644 --- a/testenv/tests/validators/test_kvm.py +++ b/testenv/tests/validators/test_kvm.py @@ -153,7 +153,7 @@ def test_fail__valid_hid_mouse_move(arg: Any) -> None: # ===== [email protected]("arg", ["LEFT ", "RIGHT "]) [email protected]("arg", ["LEFT ", "RIGHT ", "Up ", " Down", " MiDdLe "]) def test_ok__valid_hid_mouse_button(arg: Any) -> None: assert valid_hid_mouse_button(arg) == arg.strip().lower() diff --git a/web/kvm/index.html b/web/kvm/index.html index 1872c9aa..6d9b636d 100644 --- a/web/kvm/index.html +++ b/web/kvm/index.html @@ -420,6 +420,13 @@ <div class="modifier wide-2 right small" data-code="right"><span><b>•</b><br>Hold →</span></div> <div class="key wide-4 right small" data-code="right"><span>Mouse<br>Right</span></div> </div> + <div class="keypad-row" style="display:none"> + <div class="key wide-4 left small" data-code="up"><span>Mouse<br>Up/Back</span></div> + <div class="modifier wide-2 left small" data-code="up"><span><b>•</b><br>← Hold</span></div> + <div class="empty-key" style="width:10px"></div> + <div class="modifier wide-2 right small" data-code="down"><span><b>•</b><br>Hold →</span></div> + <div class="key wide-4 right small" data-code="down"><span>Mouse<br>Down/Fw</span></div> + </div> </div> </div> </div> diff --git a/web/kvm/window-stream.pug b/web/kvm/window-stream.pug index 232a3f72..f3493c39 100644 --- a/web/kvm/window-stream.pug +++ b/web/kvm/window-stream.pug @@ -13,3 +13,9 @@ div(class="empty-key" style="width:10px") div(data-code="right" class="modifier wide-2 right small") #[span #[b •]#[br]Hold →] div(data-code="right" class="key wide-4 right small") #[span Mouse#[br]Right] + div(class="keypad-row" style="display:none") + div(data-code="up" class="key wide-4 left small") #[span Mouse#[br]Up/Back] + div(data-code="up" class="modifier wide-2 left small") #[span #[b •]#[br]← Hold] + div(class="empty-key" style="width:10px") + div(data-code="down" class="modifier wide-2 right small") #[span #[b •]#[br]Hold →] + div(data-code="down" class="key wide-4 right small") #[span Mouse#[br]Down/Fw] diff --git a/web/share/js/kvm/mouse.js b/web/share/js/kvm/mouse.js index 6fb69781..33b9f56f 100644 --- a/web/share/js/kvm/mouse.js +++ b/web/share/js/kvm/mouse.js @@ -120,6 +120,8 @@ export function Mouse(record_callback) { case 0: __keypad.emit("left", state); break; case 2: __keypad.emit("right", state); break; case 1: __keypad.emit("middle", state); break; + case 3: __keypad.emit("up", state); break; + case 4: __keypad.emit("down", state); break; } }; |