diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py index 8481e7e8..e2e92041 100644 --- a/lib/logitech_receiver/hidpp20.py +++ b/lib/logitech_receiver/hidpp20.py @@ -343,7 +343,6 @@ class ReprogrammableKeyV4(ReprogrammableKey): class PersistentRemappableAction: def __init__(self, device, index, cid, actionId, remapped, modifierMask, cidStatus): - print("PRA", index, cid, actionId, remapped, modifierMask, cidStatus) self._device = device self.index = index self._cid = cid @@ -544,7 +543,6 @@ class KeysArrayPersistent(KeysArray): return self._capabilities def _query_key(self, index: int): - print("QK", index) if index < 0 or index >= len(self.keys): raise IndexError(index) keydata = self.device.feature_request(FEATURE.PERSISTENT_REMAPPABLE_ACTION, 0x20, index, 0xFF) diff --git a/lib/logitech_receiver/settings.py b/lib/logitech_receiver/settings.py index 26feaf77..9bec5a01 100644 --- a/lib/logitech_receiver/settings.py +++ b/lib/logitech_receiver/settings.py @@ -1471,7 +1471,7 @@ class ActionSettingRW: if logger.isEnabledFor(logging.WARNING): logger.warning("cannot disable %s on %s", self.name, device) self.deactivate_action() - return True + return data_bytes class RawXYProcessing: diff --git a/tests/logitech_receiver/hidpp.py b/tests/logitech_receiver/hidpp.py index b108da1e..ac2e8135 100644 --- a/tests/logitech_receiver/hidpp.py +++ b/tests/logitech_receiver/hidpp.py @@ -18,6 +18,7 @@ import errno +import threading from dataclasses import dataclass from dataclasses import field @@ -129,6 +130,46 @@ r_mouse_3 = [ # a HID++ 2.0 mouse Response("444544000000000000000000000000", 0x0510, "0F"), # name - last 3 characters ] +responses_gestures = [ # the commented-out messages are not used by either the setting or other testing + Response("4203410141020400320480148C21A301", 0x0400, "0000"), # items + Response("A302A11EA30A4105822C852DAD2AAD2B", 0x0400, "0008"), + Response("8F408F418F434204AF54912282558264", 0x0400, "0010"), + Response("01000000000000000000000000000000", 0x0400, "0018"), + Response("01000000000000000000000000000000", 0x0410, "000101"), # enable + # Response("02000000000000000000000000000000", 0x0410, "000102"), + # Response("04000000000000000000000000000000", 0x0410, "000104"), + # Response("08000000000000000000000000000000", 0x0410, "000108"), + Response("00000000000000000000000000000000", 0x0410, "000110"), + # Response("20000000000000000000000000000000", 0x0410, "000120"), + # Response("40000000000000000000000000000000", 0x0410, "000140"), + # Response("00000000000000000000000000000000", 0x0410, "000180"), + # Response("00000000000000000000000000000000", 0x0410, "010101"), + # Response("00000000000000000000000000000000", 0x0410, "010102"), + # Response("04000000000000000000000000000000", 0x0410, "010104"), + # Response("00000000000000000000000000000000", 0x0410, "010108"), + Response("6F000000000000000000000000000000", 0x0410, "0001FF"), + Response("04000000000000000000000000000000", 0x0410, "01010F"), + Response("00000000000000000000000000000000", 0x0430, "000101"), # divert + # Response("00000000000000000000000000000000", 0x0430, "000102"), + # Response("00000000000000000000000000000000", 0x0430, "000104"), + # Response("00000000000000000000000000000000", 0x0430, "000108"), + Response("00000000000000000000000000000000", 0x0430, "000110"), + # Response("00000000000000000000000000000000", 0x0430, "000120"), + # Response("00000000000000000000000000000000", 0x0430, "000140"), + # Response("00000000000000000000000000000000", 0x0430, "000180"), + # Response("00000000000000000000000000000000", 0x0430, "010101"), + # Response("00000000000000000000000000000000", 0x0430, "010102"), + Response("00000000000000000000000000000000", 0x0430, "0001FF"), + Response("00000000000000000000000000000000", 0x0430, "010103"), + Response("08000000000000000000000000000000", 0x0450, "01FF"), + Response("08000000000000000000000000000000", 0x0450, "02FF"), + Response("08000000000000000000000000000000", 0x0450, "03FF"), + Response("00040000000000000000000000000000", 0x0450, "04FF"), + Response("5C020000000000000000000000000000", 0x0450, "05FF"), + Response("01000000000000000000000000000000", 0x0460, "00FF"), + Response("01000000000000000000000000000000", 0x0470, "00FF"), +] + # A fake device that uses provided data (responses) to respond to HID++ commands. # Some methods from the real device are used to set up data structures needed for settings @@ -145,7 +186,8 @@ class Device: wpid: Optional[str] = "0000" setting_callback: Any = None settings = [] - sliding = profiles = _backlight = _keys = _remap_keys = _led_effects = None + sliding = profiles = _backlight = _keys = _remap_keys = _led_effects = _gestures = None + _gestures_lock = threading.Lock() read_register = device.Device.read_register write_register = device.Device.write_register @@ -153,6 +195,7 @@ class Device: keys = device.Device.keys remap_keys = device.Device.remap_keys led_effects = device.Device.led_effects + gestures = device.Device.gestures __hash__ = device.Device.__hash__ def __post_init__(self): diff --git a/tests/logitech_receiver/test_hidpp20_complex.py b/tests/logitech_receiver/test_hidpp20_complex.py index c82a31e2..94b312a5 100644 --- a/tests/logitech_receiver/test_hidpp20_complex.py +++ b/tests/logitech_receiver/test_hidpp20_complex.py @@ -340,47 +340,7 @@ def test_KeysArrayPersistent_key(key, expected_index, expected_mapped_to): assert mapped_to == expected_mapped_to -# TODO SubParam, Gesture, Param, Gestures - -responses_gestures = [ - hidpp.Response("4203410141020400320480148C21A301", 0x0400, "0000"), # items - hidpp.Response("A302A11EA30A4105822C852DAD2AAD2B", 0x0400, "0008"), - hidpp.Response("8F408F418F434204AF54912282558264", 0x0400, "0010"), - hidpp.Response("01000000000000000000000000000000", 0x0400, "0018"), - hidpp.Response("6F000000000000000000000000000000", 0x0410, "0001FF"), # item 0 enable - hidpp.Response("01000000000000000000000000000000", 0x0410, "000101"), - hidpp.Response("02000000000000000000000000000000", 0x0410, "000102"), - hidpp.Response("04000000000000000000000000000000", 0x0410, "000104"), - hidpp.Response("08000000000000000000000000000000", 0x0410, "000108"), - hidpp.Response("00000000000000000000000000000000", 0x0410, "000110"), - hidpp.Response("20000000000000000000000000000000", 0x0410, "000120"), - hidpp.Response("40000000000000000000000000000000", 0x0410, "000140"), - hidpp.Response("00000000000000000000000000000000", 0x0410, "000180"), - hidpp.Response("00000000000000000000000000000000", 0x0410, "010101"), - hidpp.Response("00000000000000000000000000000000", 0x0410, "010102"), - hidpp.Response("04000000000000000000000000000000", 0x0410, "010104"), - hidpp.Response("00000000000000000000000000000000", 0x0410, "010108"), - hidpp.Response("04000000000000000000000000000000", 0x0410, "01010F"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000101"), # item 1 divert - hidpp.Response("00000000000000000000000000000000", 0x0430, "000102"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000104"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000108"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000110"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000120"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000140"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "000180"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "010101"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "010102"), - hidpp.Response("00000000000000000000000000000000", 0x0430, "0001FF"), - hidpp.Response("08000000000000000000000000000000", 0x0450, "03FF"), - hidpp.Response("08000000000000000000000000000000", 0x0450, "01FF"), - hidpp.Response("08000000000000000000000000000000", 0x0450, "02FF"), - hidpp.Response("5C020000000000000000000000000000", 0x0450, "05FF"), - hidpp.Response("00040000000000000000000000000000", 0x0450, "04FF"), - hidpp.Response("01000000000000000000000000000000", 0x0460, "00FF"), - hidpp.Response("01000000000000000000000000000000", 0x0470, "00FF"), -] -device_gestures = hidpp.Device("GESTURES", responses=responses_gestures, feature=hidpp20_constants.FEATURE.GESTURE_2) +device_gestures = hidpp.Device("GESTURES", responses=hidpp.responses_gestures, feature=hidpp20_constants.FEATURE.GESTURE_2) def test_Gestures(): @@ -397,8 +357,6 @@ def test_Gestures(): assert len(gestures.params) == 1 assert gestures.params[4].value == 256 assert gestures.params[4].default_value == 256 - - print("SPEC", gestures.specs) assert len(gestures.specs) == 5 assert gestures.specs[2].value == 8 assert gestures.specs[4].value == 4 diff --git a/tests/logitech_receiver/test_setting_templates.py b/tests/logitech_receiver/test_setting_templates.py index f24e1f83..bc2568df 100644 --- a/tests/logitech_receiver/test_setting_templates.py +++ b/tests/logitech_receiver/test_setting_templates.py @@ -31,8 +31,7 @@ from logitech_receiver import special_keys from . import hidpp -# TODO DpiSlidingXY, MouseGesturesXY, SpeedChange -# TODO Gesture2Gestures, Gesture2Divert, Gesture2Params +# TODO action part of DpiSlidingXY, MouseGesturesXY, SpeedChange class Setup: @@ -456,6 +455,17 @@ simple_tests = [ hidpp.Response("01", 0x0430), # on hidpp.Response("00", 0x0440, "00"), # set off ), + Setup( + FeatureTest(settings_templates.SpeedChange, 0, None, 0), # need to set up all settings to successfully write + common.NamedInts(**{"Off": 0, "DPI Change": 0xED}), + hidpp.Response("040001", 0x0000, "2205"), # POINTER_SPEED + hidpp.Response("0100", 0x0400), + hidpp.Response("0120", 0x0410, "0120"), + hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4 + hidpp.Response("01", 0x0500), + hidpp.Response("00ED009D310003070500000000000000", 0x0510, "00"), # DPI Change + hidpp.Response("00ED0000000000000000000000000000", 0x0520, "00ED"), # DPI Change current + ), ] @@ -471,22 +481,22 @@ def test_simple_template(test, mocker, mock_gethostname): spy_request = mocker.spy(device, "request") setting = settings_templates.check_feature(device, tst.sclass) - - assert setting - + assert setting is not None if isinstance(setting, list): setting = setting[0] - value = setting.read(cached=False) - cached_value = setting.read(cached=True) - write_value = setting.write(tst.write_value) - - if isinstance(test.choices, common.NamedInts): - assert setting.choices == test.choices if isinstance(test.choices, list): assert setting._validator.min_value == test.choices[0] assert setting._validator.max_value == test.choices[1] + elif test.choices is not None: + assert setting.choices == test.choices + + value = setting.read(cached=False) assert value == tst.initial_value + + cached_value = setting.read(cached=True) assert cached_value == tst.initial_value + + write_value = setting.write(tst.write_value) if tst.write_value is not None else None assert write_value == tst.write_value for i in range(0 - tst.matched_calls, 0): @@ -529,8 +539,9 @@ key_tests = [ ), Setup( FeatureTest(settings_templates.DivertKeys, {0xC4: 0}, {0xC4: 2}, 2, offset=0x05), - {common.NamedInt(0xC4, "Smart Shift"): common.NamedInts(Regular=0, Diverted=1, Mouse_Gestures=2)}, + {common.NamedInt(0xC4, "Smart Shift"): common.NamedInts(Regular=0, Diverted=1, Mouse_Gestures=2, Sliding_DPI=3)}, *responses_reprog_controls, + hidpp.Response("0A0001", 0x0000, "2201"), # ADJUSTABLE_DPI hidpp.Response("00C4300000", 0x0530, "00C4300000"), # Smart Shift write hidpp.Response("00C4030000", 0x0530, "00C4030000"), # Smart Shift divert write ), @@ -554,13 +565,54 @@ key_tests = [ hidpp.Response("0051FF01005100", 0x0440, "0051FF01005100"), # right button set write ), Setup( - FeatureTest(settings_templates.Equalizer, {0: 0x10, 1: 0x14}, {1: 0x20}, 2), - [16, 32], - hidpp.Response("0220001020", 0x0400), - hidpp.Response("0001000200000000000000", 0x0410, "00"), - hidpp.Response("1014", 0x0420, "00"), - hidpp.Response("1014", 0x0430, "021014"), - hidpp.Response("1020", 0x0430, "021020"), + FeatureTest( + settings_templates.Gesture2Gestures, + { + 1: True, + 2: True, + 30: True, + 10: True, + 45: False, + 42: True, + 43: True, + 64: False, + 65: False, + 67: False, + 84: True, + 34: False, + }, + {45: True}, + 4, + ), + *hidpp.responses_gestures, + hidpp.Response("0001FF6F", 0x0420, "0001FF6F"), # write + hidpp.Response("01010F04", 0x0420, "01010F04"), + hidpp.Response("0001FF7F", 0x0420, "0001FF7F"), # write 45 + hidpp.Response("01010F04", 0x0420, "01010F04"), + ), + Setup( + FeatureTest( + settings_templates.Gesture2Divert, + {1: False, 2: False, 10: False, 44: False, 64: False, 65: False, 67: False, 84: False, 85: False, 100: False}, + {44: True}, + 4, + ), + *hidpp.responses_gestures, + hidpp.Response("0001FF00", 0x0440, "0001FF00"), # write + hidpp.Response("01010300", 0x0440, "01010300"), + hidpp.Response("0001FF08", 0x0440, "0001FF08"), # write 44 + hidpp.Response("01010300", 0x0440, "01010300"), + ), + Setup( + FeatureTest( + settings_templates.Gesture2Params, + {4: {"scale": 256}}, + {4: {"scale": 128}}, + 2, + ), + *hidpp.responses_gestures, + hidpp.Response("000100FF000000000000000000000000", 0x0480, "000100FF"), + hidpp.Response("000080FF000000000000000000000000", 0x0480, "000080FF"), ), Setup( FeatureTest(settings_templates.Equalizer, {0: -0x20, 1: 0x10}, {1: 0x18}, 2), @@ -650,17 +702,17 @@ def test_key_template(test, mocker): assert setting is not None if isinstance(setting, list): setting = setting[0] - if isinstance(test.choices, dict): - assert setting.choices == test.choices - elif isinstance(test.choices, list): + if isinstance(test.choices, list): assert setting._validator.min_value == test.choices[0] assert setting._validator.max_value == test.choices[1] + elif test.choices is not None: + assert setting.choices == test.choices value = setting.read(cached=False) assert value == tst.initial_value - wvalue = setting.write(value) - assert wvalue == tst.initial_value + write_value = setting.write(value) + assert write_value == tst.initial_value for key, value in tst.write_value.items(): write_value = setting.write_key_value(key, value) @@ -673,21 +725,6 @@ def test_key_template(test, mocker): assert param == test.responses[i].params -failing_tests = [ # needs settings to be set up!! - Setup( - FeatureTest(settings_templates.SpeedChange, 0, 0xED), - common.NamedInts(**{"Off": 0, "DPI Change": 0xED}), - hidpp.Response("040001", 0x0000, "2205"), # POINTER_SPEED - hidpp.Response("0100", 0x0400), - hidpp.Response("0120", 0x0410, "0120"), - hidpp.Response("050001", 0x0000, "1B04"), # REPROG_CONTROLS_V4 - hidpp.Response("01", 0x0500), - hidpp.Response("00ED009D310003070500000000000000", 0x0510, "00"), # DPI Change - hidpp.Response("00ED0000000000000000000000000000", 0x0520, "00ED"), # DPI Change current - ), -] - - @pytest.mark.parametrize("test", simple_tests + key_tests) def test_check_feature_settings(test, mocker): tst = test.test