diff --git a/lib/logitech/unifying_receiver/descriptors.py b/lib/logitech/unifying_receiver/descriptors.py index dec0b065..f3309d2b 100644 --- a/lib/logitech/unifying_receiver/descriptors.py +++ b/lib/logitech/unifying_receiver/descriptors.py @@ -41,8 +41,8 @@ def _register_dpi(register, choices): def check_features(device, already_known): - if _hidpp20.FEATURE.FN_STATUS in device.features and not any(s.name == 'fn-swap' for s in already_known): - tfn = _settings.feature_toggle(_FN_SWAP[0], _hidpp20.FEATURE.FN_STATUS, write_returns_value=True, + if _hidpp20.FEATURE.FN_INVERSION in device.features and not any(s.name == 'fn-swap' for s in already_known): + tfn = _settings.feature_toggle(_FN_SWAP[0], _hidpp20.FEATURE.FN_INVERSION, write_returns_value=True, label=_FN_SWAP[1], description=_FN_SWAP[2]) already_known.append(tfn(device)) diff --git a/lib/logitech/unifying_receiver/hidpp20.py b/lib/logitech/unifying_receiver/hidpp20.py index fd6e29dd..fa487dc4 100644 --- a/lib/logitech/unifying_receiver/hidpp20.py +++ b/lib/logitech/unifying_receiver/hidpp20.py @@ -37,18 +37,34 @@ A particular device might not support all these features, and may support other unknown features as well. """ FEATURE = _NamedInts( - ROOT=0x0000, - FEATURE_SET=0x0001, - FIRMWARE=0x0003, - NAME=0x0005, - BATTERY=0x1000, - REPROGRAMMABLE_KEYS=0x1B00, - WIRELESS=0x1D4B, - MOUSE_POINTER=0x2200, - FN_STATUS=0x40A0, - SOLAR_CHARGE=0x4301, - TOUCH_PAD=0x6100, - TOUCH_MOUSE=0x6110) + ROOT=0x0000, + FEATURE_SET=0x0001, + FEATURE_INFO=0x0002, + DEVICE_FW_VERSION=0x0003, + DEVICE_NAME=0x0005, + DEVICE_GROUPS=0x0006, + DFUCONTROL=0x00C0, + BATTERY_STATUS=0x1000, + BACKLIGHT=0x1981, + REPROG_CONTROLS=0x1B00, + REPROG_CONTROLS_V2=0x1B01, + REPROG_CONTROLS_V3=0x1B03, + WIRELESS_DEVICE_STATUS=0x1D4B, + LEFT_RIGHT_SWAP=0x2001, + VERTICAL_SCROLLING=0x2100, + HI_RES_SCROLLING=0x2120, + MOUSE_POINTER=0x2200, + FN_INVERSION=0x40A0, + NEW_FN_INVERSION=0x40A2, + ENCRYPTION=0x4100, + SOLAR_DASHBOARD=0x4301, + KEYBOARD_LAYOUT=0x4520, + TOUCHPAD_FW_ITEMS=0x6010, + TOUCHPAD_SW_ITEMS=0x6011, + TOUCHPAD_WIN8_FW_ITEMS=0x6012, + TOUCHPAD_RAW_XY=0x6100, + TOUCHMOUSE_RAW_POINTS=0x6110, +) FEATURE._fallback = lambda x: 'unknown:%04X' % x FEATURE_FLAG = _NamedInts( @@ -259,7 +275,7 @@ class KeysArray(object): raise IndexError(index) if self.keys[index] is None: - keydata = feature_request(self.device, FEATURE.REPROGRAMMABLE_KEYS, 0x10, index) + keydata = feature_request(self.device, FEATURE.REPROG_CONTROLS, 0x10, index) if keydata: key, key_task, flags = _unpack('!HHB', keydata[:5]) ctrl_id_text = special_keys.CONTROL[key] @@ -306,13 +322,13 @@ def get_firmware(device): :returns: a list of FirmwareInfo tuples, ordered by firmware layer. """ - count = feature_request(device, FEATURE.FIRMWARE) + count = feature_request(device, FEATURE.DEVICE_FW_VERSION) if count: count = ord(count[:1]) fw = [] for index in range(0, count): - fw_info = feature_request(device, FEATURE.FIRMWARE, 0x10, index) + fw_info = feature_request(device, FEATURE.DEVICE_FW_VERSION, 0x10, index) if fw_info: level = ord(fw_info[:1]) & 0x0F if level == 0 or level == 1: @@ -337,9 +353,9 @@ def get_kind(device): :see DEVICE_KIND: :returns: a string describing the device type, or ``None`` if the device is - not available or does not support the ``NAME`` feature. + not available or does not support the ``DEVICE_NAME`` feature. """ - kind = feature_request(device, FEATURE.NAME, 0x20) + kind = feature_request(device, FEATURE.DEVICE_NAME, 0x20) if kind: kind = ord(kind[:1]) # _log.debug("device %d type %d = %s", devnumber, kind, DEVICE_KIND[kind]) @@ -350,15 +366,15 @@ def get_name(device): """Reads a device's name. :returns: a string with the device name, or ``None`` if the device is not - available or does not support the ``NAME`` feature. + available or does not support the ``DEVICE_NAME`` feature. """ - name_length = feature_request(device, FEATURE.NAME) + name_length = feature_request(device, FEATURE.DEVICE_NAME) if name_length: name_length = ord(name_length[:1]) name = b'' while len(name) < name_length: - fragment = feature_request(device, FEATURE.NAME, 0x10, len(name)) + fragment = feature_request(device, FEATURE.DEVICE_NAME, 0x10, len(name)) if fragment: name += fragment[:name_length - len(name)] else: @@ -373,7 +389,7 @@ def get_battery(device): :raises FeatureNotSupported: if the device does not support this feature. """ - battery = feature_request(device, FEATURE.BATTERY) + battery = feature_request(device, FEATURE.BATTERY_STATUS) if battery: discharge, dischargeNext, status = _unpack('!BBB', battery[:3]) if _log.isEnabledFor(_DEBUG): @@ -383,7 +399,7 @@ def get_battery(device): def get_keys(device): - count = feature_request(device, FEATURE.REPROGRAMMABLE_KEYS) + count = feature_request(device, FEATURE.REPROG_CONTROLS) if count: return KeysArray(device, ord(count[:1])) diff --git a/lib/logitech/unifying_receiver/status.py b/lib/logitech/unifying_receiver/status.py index ad71b3c7..26b07833 100644 --- a/lib/logitech/unifying_receiver/status.py +++ b/lib/logitech/unifying_receiver/status.py @@ -165,10 +165,10 @@ class DeviceStatus(dict): if battery is None and d.protocol >= 2.0: battery = _hidpp20.get_battery(d) - # really unnecessary, if the device has SOLAR_CHARGE it should be + # really unnecessary, if the device has SOLAR_DASHBOARD it should be # broadcasting it's battery status anyway, it will just take a little while - # if battery is None and _hidpp20.FEATURE.SOLAR_CHARGE in d.features: - # d.feature_request(_hidpp20.FEATURE.SOLAR_CHARGE, 0x00, 1, 1) + # if battery is None and _hidpp20.FEATURE.SOLAR_DASHBOARD in d.features: + # d.feature_request(_hidpp20.FEATURE.SOLAR_DASHBOARD, 0x00, 1, 1) # return if battery: @@ -339,7 +339,7 @@ class DeviceStatus(dict): _log.warn("%s: unrecognized %s", self._device, n) def _process_feature_notification(self, n, feature): - if feature == _hidpp20.FEATURE.BATTERY: + if feature == _hidpp20.FEATURE.BATTERY_STATUS: if n.address == 0x00: discharge = ord(n.data[:1]) battery_status = ord(n.data[1:2]) @@ -348,14 +348,15 @@ class DeviceStatus(dict): _log.info("%s: unknown BATTERY %s", self._device, n) return True - if feature == _hidpp20.FEATURE.REPROGRAMMABLE_KEYS: + # TODO: what are REPROG_CONTROLS_V{2,3}? + if feature == _hidpp20.FEATURE.REPROG_CONTROLS: if n.address == 0x00: _log.info("%s: reprogrammable key: %s", self._device, n) else: _log.info("%s: unknown REPROGRAMMABLE KEYS %s", self._device, n) return True - if feature == _hidpp20.FEATURE.WIRELESS: + if feature == _hidpp20.FEATURE.WIRELESS_DEVICE_STATUS: if n.address == 0x00: if _log.isEnabledFor(_DEBUG): _log.debug("wireless status: %s", n) @@ -367,7 +368,7 @@ class DeviceStatus(dict): _log.info("%s: unknown WIRELESS %s", self._device, n) return True - if feature == _hidpp20.FEATURE.SOLAR_CHARGE: + if feature == _hidpp20.FEATURE.SOLAR_DASHBOARD: if n.data[5:9] == b'GOOD': charge, lux, adc = _unpack('!BHH', n.data[:5]) self[BATTERY_LEVEL] = charge @@ -385,18 +386,18 @@ class DeviceStatus(dict): _log.debug("%s: Light Check button pressed", self._device) self._changed(alert=ALERT.SHOW_WINDOW) # first cancel any reporting - self._device.feature_request(_hidpp20.FEATURE.SOLAR_CHARGE) + self._device.feature_request(_hidpp20.FEATURE.SOLAR_DASHBOARD) # trigger a new report chain reports_count = 15 reports_period = 2 # seconds - self._device.feature_request(_hidpp20.FEATURE.SOLAR_CHARGE, 0x00, reports_count, reports_period) + self._device.feature_request(_hidpp20.FEATURE.SOLAR_DASHBOARD, 0x00, reports_count, reports_period) else: _log.info("%s: unknown SOLAR CHAGE %s", self._device, n) else: _log.warn("%s: SOLAR CHARGE not GOOD? %s", self._device, n) return True - if feature == _hidpp20.FEATURE.TOUCH_MOUSE: + if feature == _hidpp20.FEATURE.TOUCHMOUSE_RAW_POINTS: if n.address == 0x00: _log.info("%s: TOUCH MOUSE points %s", self._device, n) elif n.address == 0x10: diff --git a/lib/solaar/cli.py b/lib/solaar/cli.py index 8d1ed3ef..f30a4868 100644 --- a/lib/solaar/cli.py +++ b/lib/solaar/cli.py @@ -141,7 +141,7 @@ def _print_device(dev, verbose=False): flags = dev.request(0x0000, feature.bytes(2)) flags = 0 if flags is None else ord(flags[1:2]) flags = hidpp20.FEATURE_FLAG.flag_names(flags) - print (" %2d: %-20s {%04X} %s" % (index, feature, feature, ', '.join(flags))) + print (" %2d: %-22s {%04X} %s" % (index, feature, feature, ', '.join(flags))) if dev.keys: print (" Has %d reprogrammable keys:" % len(dev.keys))