improved support for the Nano receiver
This commit is contained in:
parent
cd33314d0b
commit
790fc7c04b
|
@ -57,9 +57,9 @@ def exit():
|
|||
return True
|
||||
|
||||
|
||||
def _match(action, device, vendor_id=None, product_id=None, interface_number=None, driver=None):
|
||||
def _match(action, device, vendor_id=None, product_id=None, interface_number=None, hid_driver=None):
|
||||
usb_device = device.find_parent('usb', 'usb_device')
|
||||
# print (action, device, "usb:", usb_device)
|
||||
# print ("* parent", action, device, "usb:", usb_device)
|
||||
if not usb_device:
|
||||
return
|
||||
|
||||
|
@ -71,15 +71,15 @@ def _match(action, device, vendor_id=None, product_id=None, interface_number=Non
|
|||
|
||||
if action == 'add':
|
||||
hid_device = device.find_parent('hid')
|
||||
# print (action, device, "hid:", usb_device)
|
||||
# print ("** found hid", action, device, "hid:", hid_device, hid_device['DRIVER'])
|
||||
if not hid_device:
|
||||
return
|
||||
hid_driver_name = hid_device['DRIVER']
|
||||
if driver is not None and driver != hid_driver_name:
|
||||
if hid_driver is not None and hid_driver != hid_driver_name:
|
||||
return
|
||||
|
||||
intf_device = device.find_parent('usb', 'usb_interface')
|
||||
# print (action, device, "usb_interface:", usb_device)
|
||||
# print ("*** usb interface", action, device, "usb_interface:", intf_device)
|
||||
if interface_number is None:
|
||||
usb_interface = None if intf_device is None else intf_device.attributes.asint('bInterfaceNumber')
|
||||
else:
|
||||
|
@ -163,7 +163,7 @@ def monitor(callback, *device_filters):
|
|||
raise
|
||||
|
||||
|
||||
def enumerate(vendor_id=None, product_id=None, interface_number=None, driver=None):
|
||||
def enumerate(vendor_id=None, product_id=None, interface_number=None, hid_driver=None):
|
||||
"""Enumerate the HID Devices.
|
||||
|
||||
List all the HID devices attached to the system, optionally filtering by
|
||||
|
@ -172,7 +172,7 @@ def enumerate(vendor_id=None, product_id=None, interface_number=None, driver=Non
|
|||
:returns: a list of matching ``DeviceInfo`` tuples.
|
||||
"""
|
||||
for dev in _Context().list_devices(subsystem='hidraw'):
|
||||
dev_info = _match('add', dev, vendor_id, product_id, interface_number, driver)
|
||||
dev_info = _match('add', dev, vendor_id, product_id, interface_number, hid_driver)
|
||||
if dev_info:
|
||||
yield dev_info
|
||||
|
||||
|
|
|
@ -66,10 +66,10 @@ class DeviceUnreachable(_KwException):
|
|||
#
|
||||
#
|
||||
|
||||
# vendor_id, product_id, interface number, driver
|
||||
# vendor_id, product_id, usb interface number, hid driver
|
||||
DEVICE_UNIFYING_RECEIVER = (0x046d, 0xc52b, 2, 'logitech-djreceiver')
|
||||
DEVICE_UNIFYING_RECEIVER_2 = (0x046d, 0xc532, 2, 'logitech-djreceiver')
|
||||
DEVICE_NANO_RECEIVER = (0x046d, 0xc526, 1, 'generic-usb')
|
||||
DEVICE_NANO_RECEIVER = (0x046d, 0xc526, 1, 'hid-generic')
|
||||
|
||||
|
||||
def receivers():
|
||||
|
|
|
@ -33,14 +33,14 @@ class PairedDevice(object):
|
|||
self.number = number
|
||||
|
||||
self._unifying = receiver.max_devices > 1
|
||||
self._protocol = None
|
||||
self._protocol = None if self._unifying else 1.0
|
||||
self._wpid = None
|
||||
self._power_switch = None
|
||||
self._polling_rate = None
|
||||
self._polling_rate = None if self._unifying else 0
|
||||
self._codename = None
|
||||
self._name = None
|
||||
self._kind = None
|
||||
self._serial = None
|
||||
self._serial = None if self._unifying else receiver.serial
|
||||
self._firmware = None
|
||||
self._keys = None
|
||||
|
||||
|
@ -67,42 +67,49 @@ class PairedDevice(object):
|
|||
self._kind = _hidpp10.DEVICE_KIND[kind]
|
||||
if self._polling_rate is None:
|
||||
self._polling_rate = ord(pair_info[2:3])
|
||||
# else:
|
||||
# device_info = self.receiver.request(0x83B5, 0x04)
|
||||
# self.wpid = _strhex(device_info[3:5])
|
||||
else:
|
||||
# guesswork...
|
||||
device_info = self.receiver.request(0x83B5, 0x04)
|
||||
self.wpid = _strhex(device_info[3:5])
|
||||
return self._wpid
|
||||
|
||||
@property
|
||||
def polling_rate(self):
|
||||
if self._polling_rate is None and self._unifying:
|
||||
self.wpid, 0
|
||||
if self._polling_rate is None:
|
||||
if self._unifying:
|
||||
self.wpid, 0
|
||||
else:
|
||||
self._polling_rate = 0
|
||||
return self._polling_rate
|
||||
|
||||
@property
|
||||
def power_switch_location(self):
|
||||
if self._power_switch is None and self._unifying:
|
||||
ps = self.receiver.request(0x83B5, 0x30 + self.number - 1)
|
||||
if ps:
|
||||
ps = ord(ps[9:10]) & 0x0F
|
||||
self._power_switch = _hidpp10.POWER_SWITCH_LOCATION[ps]
|
||||
if self._power_switch is None:
|
||||
if self._unifying:
|
||||
ps = self.receiver.request(0x83B5, 0x30 + self.number - 1)
|
||||
if ps:
|
||||
ps = ord(ps[9:10]) & 0x0F
|
||||
self._power_switch = _hidpp10.POWER_SWITCH_LOCATION[ps]
|
||||
return self._power_switch
|
||||
|
||||
@property
|
||||
def codename(self):
|
||||
if self._codename is None and self._unifying:
|
||||
codename = self.receiver.request(0x83B5, 0x40 + self.number - 1)
|
||||
if codename:
|
||||
self._codename = codename[2:].rstrip(b'\x00').decode('utf-8')
|
||||
# _log.debug("device %d codename %s", self.number, self._codename)
|
||||
if self._codename is None:
|
||||
if self._unifying:
|
||||
codename = self.receiver.request(0x83B5, 0x40 + self.number - 1)
|
||||
if codename:
|
||||
self._codename = codename[2:].rstrip(b'\x00').decode('utf-8')
|
||||
# _log.debug("device %d codename %s", self.number, self._codename)
|
||||
return self._codename
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if self._name is None and self._unifying:
|
||||
if self.codename in _descriptors.DEVICES:
|
||||
self._name, self._kind = _descriptors.DEVICES[self._codename][:2]
|
||||
elif self.protocol >= 2.0:
|
||||
self._name = _hidpp20.get_name(self)
|
||||
if self._name is None:
|
||||
if self._unifying:
|
||||
if self.codename in _descriptors.DEVICES:
|
||||
self._name, self._kind = _descriptors.DEVICES[self._codename][:2]
|
||||
elif self.protocol >= 2.0:
|
||||
self._name = _hidpp20.get_name(self)
|
||||
return self._name or self.codename or '?'
|
||||
|
||||
@property
|
||||
|
@ -132,14 +139,15 @@ class PairedDevice(object):
|
|||
|
||||
@property
|
||||
def serial(self):
|
||||
if self._serial is None and self._unifying:
|
||||
if self._serial is None:
|
||||
self._serial = _hidpp10.get_serial(self)
|
||||
return self._serial or '?'
|
||||
|
||||
@property
|
||||
def keys(self):
|
||||
if self._keys is None and self._unifying:
|
||||
self._keys = _hidpp20.get_keys(self) or ()
|
||||
if self._keys is None:
|
||||
if self._unifying:
|
||||
self._keys = _hidpp20.get_keys(self) or ()
|
||||
return self._keys
|
||||
|
||||
@property
|
||||
|
@ -277,7 +285,8 @@ class Receiver(object):
|
|||
if not self.handle:
|
||||
return False
|
||||
|
||||
flag_bits = _hidpp10.NOTIFICATION_FLAG.all_bits() if enable else 0
|
||||
# flag_bits = _hidpp10.NOTIFICATION_FLAG.all_bits() if enable else 0
|
||||
flag_bits = 0xFFFFFF if enable else 0
|
||||
ok = _hidpp10.set_notification_flags(self, flag_bits)
|
||||
|
||||
flag_bits = _hidpp10.get_notification_flags(self)
|
||||
|
@ -303,12 +312,12 @@ class Receiver(object):
|
|||
# create a device object, but only use it if the receiver knows about it
|
||||
|
||||
# Nano receiver
|
||||
#if self.max_devices == 1 and number == 1:
|
||||
# # the Nano receiver does not provide the wpid
|
||||
# _log.info("%s: found Nano device %d (%s)", self, number, dev.serial)
|
||||
# # dev._wpid = self.serial + ':1'
|
||||
# self._devices[number] = dev
|
||||
# return dev
|
||||
if self.max_devices == 1 and number == 1:
|
||||
# the Nano receiver does not provide the wpid
|
||||
_log.info("%s: found Nano device %d (%s)", self, number, dev.serial)
|
||||
# dev._wpid = self.serial + ':1'
|
||||
self._devices[number] = dev
|
||||
return dev
|
||||
|
||||
if dev.wpid:
|
||||
_log.info("%s: found Unifying device %d (%s)", self, number, dev.wpid)
|
||||
|
|
|
@ -29,6 +29,7 @@ _MAX_DEVICES = 7
|
|||
|
||||
def _make_receiver_box(receiver):
|
||||
frame = Gtk.Frame()
|
||||
# frame.set_shadow_type(Gtk.ShadowType.NONE)
|
||||
frame._device = receiver
|
||||
|
||||
icon_set = _icons.device_icon_set(receiver.name)
|
||||
|
@ -92,8 +93,11 @@ def _make_receiver_box(receiver):
|
|||
|
||||
toggle_info_action = _action.make_toggle('dialog-information', 'Details', _toggle_info_label, frame)
|
||||
toolbar.insert(toggle_info_action.create_tool_item(), 0)
|
||||
toolbar.insert(_action.pair(frame).create_tool_item(), -1)
|
||||
# toolbar.insert(ui.action.about.create_tool_item(), -1)
|
||||
pair_action = _action.pair(frame)
|
||||
if receiver.max_devices == 1:
|
||||
pair_action.set_sensitive(False)
|
||||
pair_action.set_tooltip('Pairing not supported by this receiver')
|
||||
toolbar.insert(pair_action.create_tool_item(), -1)
|
||||
|
||||
vbox = Gtk.VBox(homogeneous=False, spacing=2)
|
||||
vbox.set_border_width(2)
|
||||
|
@ -137,7 +141,7 @@ def _make_device_box(index):
|
|||
|
||||
not_encrypted_icon = Gtk.Image.new_from_icon_name('security-low', _STATUS_ICON_SIZE)
|
||||
not_encrypted_icon.set_name('not-encrypted')
|
||||
not_encrypted_icon.set_tooltip_text('The wireless link between this device and the Unifying Receiver is not encrypted.\n'
|
||||
not_encrypted_icon.set_tooltip_text('The wireless link between this device and its receiver is not encrypted.\n'
|
||||
'\n'
|
||||
'For pointing devices (mice, trackballs, trackpads), this is a minor security issue.\n'
|
||||
'\n'
|
||||
|
@ -182,15 +186,16 @@ def _make_device_box(index):
|
|||
device = f._device
|
||||
assert device
|
||||
|
||||
items = [None, None, None, None, None, None, None, None, None]
|
||||
items = [None] * 8
|
||||
hid = device.protocol
|
||||
items[0] = ('Protocol', 'HID++ %1.1f' % hid if hid else 'unknown')
|
||||
items[1] = ('Polling rate', '%d ms' % device.polling_rate)
|
||||
items[1] = ('Polling rate', '%d ms' % device.polling_rate) if device.polling_rate else None
|
||||
items[2] = ('Wireless PID', device.wpid)
|
||||
items[3] = ('Serial', device.serial)
|
||||
firmware = device.firmware
|
||||
if firmware:
|
||||
items[4:] = [(fw.kind, (fw.name + ' ' + fw.version).strip()) for fw in firmware]
|
||||
firmware = [(fw.kind, (fw.name + ' ' + fw.version).strip()) for fw in firmware]
|
||||
items[4:4+len(firmware)] = firmware
|
||||
|
||||
if device.status:
|
||||
notification_flags = _hidpp10.get_notification_flags(device)
|
||||
|
@ -417,6 +422,11 @@ def _update_device_box(frame, dev):
|
|||
for i in frame._toolbar.get_children():
|
||||
i.set_active(False)
|
||||
|
||||
if dev.receiver.max_devices == 1:
|
||||
unpair_button = frame.get_child().get_children()[-1]
|
||||
unpair_button.set_sensitive(False)
|
||||
unpair_button.set_tooltip_text('Unpairing not supported by this device')
|
||||
|
||||
battery_icon, battery_label, light_icon, light_label, not_encrypted_icon, _ = frame._status_icons
|
||||
battery_level = dev.status.get(_status.BATTERY_LEVEL)
|
||||
|
||||
|
@ -425,7 +435,7 @@ def _update_device_box(frame, dev):
|
|||
|
||||
if battery_level is None:
|
||||
battery_icon.set_sensitive(False)
|
||||
battery_icon.set_from_icon_name(_icons.battery(-1), _STATUS_ICON_SIZE)
|
||||
battery_icon.set_from_icon_name(_icons.battery(None), _STATUS_ICON_SIZE)
|
||||
battery_label.set_markup('<small>no status</small>')
|
||||
battery_label.set_sensitive(True)
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue