diff --git a/lib/logitech/unifying_receiver/descriptors.py b/lib/logitech/unifying_receiver/descriptors.py index 83eeec2a..32dfac90 100644 --- a/lib/logitech/unifying_receiver/descriptors.py +++ b/lib/logitech/unifying_receiver/descriptors.py @@ -23,6 +23,12 @@ _FN_SWAP = ('fn-swap', 'Swap Fx function', ('When set, the F1..F12 keys will act 'When unset, the F1..F12 keys will activate their standard function,\n' 'and you must hold the FN key to activate their special function.')) +# this register is only applicable to HID++ 1.0 devices, it should not exist with HID++ 2.0 devices +# using Features +def _register_fn_swap(register, true_value, mask): + return _settings.register_toggle(_FN_SWAP[0], register, true_value=true_value, mask=mask, + label=_FN_SWAP[1], description=_FN_SWAP[2]) + def _register_smooth_scroll(register, true_value, mask): return _settings.register_toggle(_SMOOTH_SCROLL[0], register, true_value=true_value, mask=mask, @@ -85,7 +91,16 @@ _D('Wireless Keyboard K350') _D('Wireless Keyboard K360') _D('Wireless Touch Keyboard K400') _D('Wireless Solar Keyboard K750') -_D('Wireless Illuminated Keyboard K800') +_D('Wireless Keyboard K710', + settings=[ + _register_fn_swap(0x09, true_value=b'\x00\x01', mask=b'\x00\x01'), + ], + ) +_D('Wireless Illuminated Keyboard K800', + settings=[ + _register_fn_swap(0x09, true_value=b'\x00\x01', mask=b'\x00\x01'), + ], + ) _D('Zone Touch Mouse T400') _D('Wireless Rechargeable Touchpad T650') _D('Logitech Cube', kind='mouse') diff --git a/lib/logitech/unifying_receiver/settings.py b/lib/logitech/unifying_receiver/settings.py index 11519c6c..fa9078e8 100644 --- a/lib/logitech/unifying_receiver/settings.py +++ b/lib/logitech/unifying_receiver/settings.py @@ -121,9 +121,18 @@ class _BooleanValidator(object): self.mask = mask self.write_returns_value = write_returns_value + def _validate_value(self, reply_bytes, expected_value): + if isinstance(expected_value, int): + return ord(reply_bytes[:1]) & self.mask == expected_value + else: + for i in range(0, len(self.mask)): + masked_value = ord(reply_bytes[i:i+1]) & ord(self.mask[i:i+1]) + if masked_value != ord(expected_value[i:i+1]): + return False + return True + def validate_read(self, reply_bytes): - reply_value = ord(reply_bytes[:1]) & self.mask - return reply_value == self.true_value + return self._validate_value(reply_bytes, self.true_value) def prepare_write(self, value): # FIXME: this does not work right when there is more than one flag in @@ -132,8 +141,7 @@ class _BooleanValidator(object): def validate_write(self, value, reply_bytes): if self.write_returns_value: - reply_value = ord(reply_bytes[:1]) & self.mask - return reply_value == self.true_value + return self._validate_value(reply_bytes, self.true_value) # just assume the value was written correctly, otherwise there would not # be any reply_bytes to check