From 7a7aad89773903d0e5b1bac6da12dc968715972d Mon Sep 17 00:00:00 2001 From: "Peter F. Patel-Schneider" Date: Wed, 7 Oct 2020 05:16:21 -0400 Subject: [PATCH] device: use FRIENDLY NAME for codename if needed and available --- lib/logitech_receiver/device.py | 21 +++++++++++---------- lib/logitech_receiver/hidpp20.py | 25 ++++++++++++++++++++++++- lib/solaar/ui/window.py | 5 ++--- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/logitech_receiver/device.py b/lib/logitech_receiver/device.py index 33af91bc..91023d83 100644 --- a/lib/logitech_receiver/device.py +++ b/lib/logitech_receiver/device.py @@ -195,16 +195,17 @@ class Device(object): @property def codename(self): if not self._codename: - codename = self.receiver.read_register(_R.receiver_info, 0x40 + self.number - 1) if self.receiver else None - if codename: - codename_length = ord(codename[1:2]) - codename = codename[2:2 + codename_length] - self._codename = codename.decode('ascii') - # if _log.isEnabledFor(_DEBUG): - # _log.debug("device %d codename %s", self.number, self._codename) - else: - self._codename = '? (%s)' % (self.wpid or self.product_id) - return self._codename + if self.online and self.protocol >= 2.0: + self._codename = _hidpp20.get_friendly_name(self) + elif self.receiver: + codename = self.receiver.read_register(_R.receiver_info, 0x40 + self.number - 1) + if codename: + codename_length = ord(codename[1:2]) + codename = codename[2:2 + codename_length] + self._codename = codename.decode('utf-8') + elif self.protocol < 2.0: + self._codename = '? (%s)' % (self.wpid or self.product_id) + return self._codename if self._codename else '?? (%s)' % (self.wpid or self.product_id) @property def name(self): diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py index 6d7fa901..3efeb962 100644 --- a/lib/logitech_receiver/hidpp20.py +++ b/lib/logitech_receiver/hidpp20.py @@ -1100,7 +1100,30 @@ def get_name(device): _log.error('failed to read whole name of %s (expected %d chars)', device, name_length) return None - return name.decode('ascii') + return name.decode('utf-8') + + +def get_friendly_name(device): + """Reads a device's friendly name. + + :returns: a string with the device name, or ``None`` if the device is not + available or does not support the ``DEVICE_NAME`` feature. + """ + name_length = feature_request(device, FEATURE.DEVICE_FRIENDLY_NAME) + if name_length: + name_length = ord(name_length[:1]) + + name = b'' + while len(name) < name_length: + fragment = feature_request(device, FEATURE.DEVICE_FRIENDLY_NAME, 0x10, len(name)) + if fragment: + initial_null = 0 if fragment[0] else 1 # initial null actually seen on a device + name += fragment[initial_null:name_length + initial_null - len(name)] + else: + _log.error('failed to read whole name of %s (expected %d chars)', device, name_length) + return None + + return name.decode('utf-8') def get_battery(device): diff --git a/lib/solaar/ui/window.py b/lib/solaar/ui/window.py index ff43d24b..2fc1a57c 100644 --- a/lib/solaar/ui/window.py +++ b/lib/solaar/ui/window.py @@ -460,10 +460,9 @@ def _device_row(receiver_path, device_number, device=None): icon_name = _icons.device_icon_name(device.name, device.kind) status_text = None status_icon = None - codename = device.codename if device.codename and device.codename[0] != '?' else ( - device.name.split()[0] if device.name.split() else device.codename + row_data = ( + receiver_path, device_number, bool(device.online), device.codename, icon_name, status_text, status_icon, device ) - row_data = (receiver_path, device_number, bool(device.online), codename, icon_name, status_text, status_icon, device) assert len(row_data) == len(_TREE_SEPATATOR) if _log.isEnabledFor(_DEBUG): _log.debug('new device row %s at index %d', row_data, new_child_index)