diff --git a/README.rst b/README.rst index 5fb936a..1ff2bb6 100644 --- a/README.rst +++ b/README.rst @@ -248,7 +248,7 @@ Changelog * **[NEXT]** (changes on ``master`` that have not been released yet): - * Nothing yet ;) + * feat: Added button binding support for Rival 600 (@flozz) * **v4.12.0:** diff --git a/doc/devices/images/rival_600_buttons.svg b/doc/devices/images/rival_600_buttons.svg new file mode 100644 index 0000000..7b0c275 --- /dev/null +++ b/doc/devices/images/rival_600_buttons.svg @@ -0,0 +1,1122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Button1 + Button2 + Button3 + Button6 + + + + + Button7 + + + + + + Button5 + + + + + + Button4 + + diff --git a/doc/devices/rival600.rst b/doc/devices/rival600.rst index 501547a..068f80a 100644 --- a/doc/devices/rival600.rst +++ b/doc/devices/rival600.rst @@ -28,6 +28,15 @@ RGB Gradients .. include:: ./_rgbgradient.rst +Buttons +------- + +.. figure:: ./images/rival_600_buttons.svg + :alt: Rival 600 buttons schema + +.. include:: ./_buttons.rst + + Python API ---------- diff --git a/rivalcfg/devices/rival600.py b/rivalcfg/devices/rival600.py index 2fca1d8..8295a67 100644 --- a/rivalcfg/devices/rival600.py +++ b/rivalcfg/devices/rival600.py @@ -162,6 +162,33 @@ "led_id": 0x07, "default": _DEFAULT_RGBGRADIENT, }, + "buttons_mapping": { + "label": "Buttons mapping", + "description": "Set the mapping of the buttons", + "cli": ["-b", "--buttons"], + "report_type": usbhid.HID_REPORT_TYPE_FEATURE, + "command": [0x31, 0x00], + "value_type": "buttons", + # fmt: off + "buttons": { + "Button1": {"id": 0x01, "offset": 0x00, "default": "button1"}, + "Button2": {"id": 0x02, "offset": 0x05, "default": "button2"}, + "Button3": {"id": 0x03, "offset": 0x0A, "default": "button3"}, + "Button4": {"id": 0x04, "offset": 0x0F, "default": "button4"}, + "Button5": {"id": 0x05, "offset": 0x14, "default": "button5"}, + "Button6": {"id": 0x06, "offset": 0x19, "default": "disabled"}, + "Button7": {"id": 0x00, "offset": 0x1E, "default": "dpi"}, + }, + "button_field_length": 5, + "button_disable": 0x00, + "button_keyboard": 0x51, + "button_multimedia": 0x61, + "button_dpi_switch": 0x30, + "button_scroll_up": 0x31, + "button_scroll_down": 0x32, + # fmt: on + "default": "buttons(button1=button1; button2=button2; button3=button3; button4=button4; button5=button5; button6=disabled; button7=dpi)", + }, }, "save_command": { "report_type": usbhid.HID_REPORT_TYPE_OUTPUT, diff --git a/test/devices/test_rival600.py b/test/devices/test_rival600.py index f49fb4f..dae57fc 100644 --- a/test/devices/test_rival600.py +++ b/test/devices/test_rival600.py @@ -297,6 +297,65 @@ def test_set_z7_color(self, mouse): assert hid_report == expected_hid_report + @pytest.mark.parametrize( + "value,expected_hid_report", + [ + ( + "default", + b"\x03\x00" + b"\x31\x00" + b"\x01\x00\x00\x00\x00" + b"\x02\x00\x00\x00\x00" + b"\x03\x00\x00\x00\x00" + b"\x04\x00\x00\x00\x00" + b"\x05\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00" + b"\x30\x00\x00\x00\x00", + ), + ( + "buttons(button2=button6)", + b"\x03\x00" + b"\x31\x00" + b"\x01\x00\x00\x00\x00" + b"\x06\x00\x00\x00\x00" + b"\x03\x00\x00\x00\x00" + b"\x04\x00\x00\x00\x00" + b"\x05\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00" + b"\x30\x00\x00\x00\x00", + ), + ( + {"buttons": {"button2": "button6"}}, + b"\x03\x00" + b"\x31\x00" + b"\x01\x00\x00\x00\x00" + b"\x06\x00\x00\x00\x00" + b"\x03\x00\x00\x00\x00" + b"\x04\x00\x00\x00\x00" + b"\x05\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00" + b"\x30\x00\x00\x00\x00", + ), + ( + "buttons(Button1=ScrollDown; Button2=ScrollUp)", + b"\x03\x00" + b"\x31\x00" + b"\x32\x00\x00\x00\x00" + b"\x31\x00\x00\x00\x00" + b"\x03\x00\x00\x00\x00" + b"\x04\x00\x00\x00\x00" + b"\x05\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00" + b"\x30\x00\x00\x00\x00", + ), + ], + ) + def test_set_buttons_mapping(self, mouse, value, expected_hid_report): + mouse.set_buttons_mapping(value) + mouse._hid_device.bytes.seek(0) + hid_report = mouse._hid_device.bytes.read() + assert hid_report == expected_hid_report + def test_save(self, mouse): mouse.save() mouse._hid_device.bytes.seek(0)