settings: add write_prefix_bytes argument to Boolean Validator

This commit is contained in:
Peter F. Patel-Schneider 2021-12-05 13:14:14 -05:00
parent 8ad648b868
commit 791f19269d
2 changed files with 28 additions and 19 deletions

View File

@ -602,16 +602,22 @@ class FeatureRWMap(FeatureRW):
class BooleanValidator:
__slots__ = ('true_value', 'false_value', 'read_offset', 'mask', 'needs_current_value')
__slots__ = ('true_value', 'false_value', 'read_skip_byte_count', 'write_prefix_bytes', 'mask', 'needs_current_value')
kind = KIND.toggle
default_true = 0x01
default_false = 0x00
# mask specifies all the affected bits in the value
default_mask = 0xFF
default_read_offset = 0
def __init__(self, true_value=default_true, false_value=default_false, mask=default_mask, read_offset=default_read_offset):
def __init__(
self,
true_value=default_true,
false_value=default_false,
mask=default_mask,
read_skip_byte_count=0,
write_prefix_bytes=b''
):
if isinstance(true_value, int):
assert isinstance(false_value, int)
if mask is None:
@ -645,10 +651,11 @@ class BooleanValidator:
self.true_value = true_value
self.false_value = false_value
self.mask = mask
self.read_offset = read_offset
self.read_skip_byte_count = read_skip_byte_count
self.write_prefix_bytes = write_prefix_bytes
def validate_read(self, reply_bytes):
reply_bytes = reply_bytes[self.read_offset:]
reply_bytes = reply_bytes[self.read_skip_byte_count:]
if isinstance(self.mask, int):
reply_value = ord(reply_bytes[:1]) & self.mask
if _log.isEnabledFor(_DEBUG):
@ -711,7 +718,7 @@ class BooleanValidator:
if _log.isEnabledFor(_DEBUG):
_log.debug('BooleanValidator: prepare_write(%s, %s) => %r', new_value, current_value, to_write)
return to_write
return self.write_prefix_bytes + to_write
class BitFieldValidator:
@ -837,7 +844,7 @@ class ChoicesValidator:
:param choices: a list of NamedInts
:param byte_count: the size of the derived byte sequence. If None, it
will be calculated from the choices."""
def __init__(self, choices, byte_count=None, read_skip_byte_count=None, write_prefix_bytes=b''):
def __init__(self, choices, byte_count=None, read_skip_byte_count=0, write_prefix_bytes=b''):
assert choices is not None
assert isinstance(choices, _NamedInts)
assert len(choices) > 1
@ -850,7 +857,7 @@ class ChoicesValidator:
assert self._byte_count <= byte_count
self._byte_count = byte_count
assert self._byte_count < 8
self._read_skip_byte_count = read_skip_byte_count if read_skip_byte_count else 0
self._read_skip_byte_count = read_skip_byte_count
self._write_prefix_bytes = write_prefix_bytes if write_prefix_bytes else b''
assert self._byte_count + self._read_skip_byte_count <= 14
assert self._byte_count + len(self._write_prefix_bytes) <= 14
@ -916,7 +923,7 @@ class ChoicesMapValidator(ChoicesValidator):
self.choices = choices_map
self.needs_current_value = False
self.extra_default = extra_default
self._read_skip_byte_count = read_skip_byte_count if read_skip_byte_count else 0
self._read_skip_byte_count = read_skip_byte_count
self._write_prefix_bytes = write_prefix_bytes if write_prefix_bytes else b''
self.activate = activate
self.mask = mask
@ -1091,10 +1098,8 @@ class ActionSettingRW:
self.pressed = False
self.release_action()
else:
print(self.key.key, cids)
for key in cids:
if key and not key == self.key.key: # some other diverted key pressed
print(key, self.key, cids)
self.key_action(key)
elif n.address == 0x10:
if self.pressed:

View File

@ -224,13 +224,17 @@ _DISABLE_KEYS_LABEL_SUB = _('Disables the %s key.')
# _FeatureRW is for feature-based settings and takes the feature name as positional argument plus the following:
# read_fnid is the feature function (times 16) to read the value (default 0x00),
# write_fnid is the feature function (times 16) to write the value (default 0x10),
# prefix is a prefix to add to the data being written and the read request (default b''), used for features
# that provide and set multiple settings (e.g., to read and write function key inversion for current host)
# no_reply is whether to wait for a reply (default false) (USE WITH EXTREME CAUTION).
#
# There are three simple validators - _BooleanV, _RangeV, and _ChoicesV
# _BooleanV is for boolean values. It takes three keyword arguments that can be integers or byte strings:
# true_value is the raw value for true (default 0x01),
# false_value is the raw value for false (default 0x00),
# mask is used to keep only some bits from a sequence of bits.
# _BooleanV is for boolean values. It takes five keyword arguments
# true_value is the raw value for true (default 0x01), this can be an integer or a byte string,
# false_value is the raw value for false (default 0x00), this can be an integer or a byte string,
# mask is used to keep only some bits from a sequence of bits, this can be an integer or a byte string,
# read_skip_byte_count is the number of bytes to ignore at the beginning of the read value (default 0),
# write_prefix_bytes is a byte string to write before the value (default empty).
# _RangeV is for an integer in a range. It takes three keyword arguments:
# min_value is the minimum value for the setting,
# max_value is the maximum value for the setting,
@ -238,8 +242,8 @@ _DISABLE_KEYS_LABEL_SUB = _('Disables the %s key.')
# _ChoicesV is for symbolic choices. It takes one positional and three keyword arguments:
# the positional argument is a list of named integers that are the valid choices,
# byte_count is the number of bytes for the integer (default size of largest choice integer),
# read_skip_byte_count is the number of bytes to ignore at the beginning of the read value (default 0),
# write_prefix_bytes is a byte string to write before the value (default empty).
# read_skip_byte_count is as for _BooleanV,
# write_prefix_bytes is as for _BooleanV.
#
# The _Settings class is for settings that are maps from keys to values.
# The _BitFieldSetting class is for settings that have multiple boolean values packed into a bit field.
@ -292,7 +296,7 @@ def _feature_new_fn_swap():
# ignore the capabilities part of the feature - all devices should be able to swap Fn state
# just use the current host (first byte = 0xFF) part of the feature to read and set the Fn state
def _feature_k375s_fn_swap():
validator = _BooleanV(true_value=b'\x01', false_value=b'\x00', read_offset=1)
validator = _BooleanV(true_value=b'\x01', false_value=b'\x00', read_skip_byte_count=1)
return _Setting(_FN_SWAP, _FeatureRW(_F.K375S_FN_INVERSION, prefix=b'\xFF'), validator, device_kind=(_DK.keyboard, ))
@ -480,7 +484,7 @@ def _feature_speed_change():
keys = [_NamedInt(0, _('Off')), key.key]
return _ChoicesV(_NamedInts.list(keys), byte_count=2)
rw = _SpeedChangeRW('speed change', _DIVERT_KEYS[0]),
rw = _SpeedChangeRW('speed change', _DIVERT_KEYS[0])
return _Setting(_SPEED_CHANGE, rw, callback=callback, device_kind=(_DK.mouse, _DK.trackball))