From f1448162568ef8fba266aeae286f7bce24ee97e6 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 20 Aug 2013 13:14:45 +0200 Subject: [PATCH 1/4] solaar-cli: fix argument parsing in Python 3 again Fix from e3a887f36cc6ec7ddb3760d31b47dacb6931a7eb, this got removed in: commit 3b75b6997008a6e0479cd324cc18ae0d79b279af Author: Daniel Pavel Date: Fri Aug 9 12:25:47 2013 +0200 merged solaar-cli functionality into main solaar binary --- lib/solaar/cli/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/solaar/cli/__init__.py b/lib/solaar/cli/__init__.py index 1d2d25f5..6c386e2a 100644 --- a/lib/solaar/cli/__init__.py +++ b/lib/solaar/cli/__init__.py @@ -136,6 +136,12 @@ def run(cli_args=None): args = _cli_parser.parse_args(cli_args) else: args = _cli_parser.parse_args() + # Python 3 has an undocumented 'feature' that breaks parsing empty args + # http://bugs.python.org/issue16308 + if not 'cmd' in args: + _cli_parser.print_usage(_sys.stderr) + _sys.stderr.write('%s: error: too few arguments\n' % NAME.lower()) + _sys.exit(2) action = args.action assert action in actions From 024a71b6187c4df23564bfddc6b40bd10f482b6b Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 20 Aug 2013 13:16:12 +0200 Subject: [PATCH 2/4] solaar: add --hidraw option again This options allows the devices list to be restricted which got removed in: commit 3b75b6997008a6e0479cd324cc18ae0d79b279af Author: Daniel Pavel Date: Fri Aug 9 12:25:47 2013 +0200 merged solaar-cli functionality into main solaar binary solaar-cli is still busted, but since it is deprecated, it's probably fine. --- lib/solaar/cli/__init__.py | 8 +++++--- lib/solaar/gtk.py | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/solaar/cli/__init__.py b/lib/solaar/cli/__init__.py index 6c386e2a..b94029a7 100644 --- a/lib/solaar/cli/__init__.py +++ b/lib/solaar/cli/__init__.py @@ -76,10 +76,12 @@ _cli_parser, actions = _create_parser() print_help = _cli_parser.print_help -def _receivers(): +def _receivers(dev_path=None): from logitech_receiver import Receiver from logitech_receiver.base import receivers for dev_info in receivers(): + if dev_path is not None and dev_path != dev_info.path: + continue try: r = Receiver.open(dev_info) if _log.isEnabledFor(_DEBUG): @@ -130,7 +132,7 @@ def _find_device(receivers, name): raise Exception("no device found matching '%s'" % name) -def run(cli_args=None): +def run(cli_args=None, hidraw_path=None): if cli_args: action = cli_args[0] args = _cli_parser.parse_args(cli_args) @@ -146,7 +148,7 @@ def run(cli_args=None): assert action in actions try: - c = list(_receivers()) + c = list(_receivers(hidraw_path)) if not c: raise Exception('Logitech receiver not found') diff --git a/lib/solaar/gtk.py b/lib/solaar/gtk.py index f5bef6a8..16c8549f 100644 --- a/lib/solaar/gtk.py +++ b/lib/solaar/gtk.py @@ -42,6 +42,8 @@ def _parse_arguments(): arg_parser = argparse.ArgumentParser(prog=NAME.lower()) arg_parser.add_argument('-d', '--debug', action='count', default=0, help='print logging messages, for debugging purposes (may be repeated for extra verbosity)') + arg_parser.add_argument('-D', '--hidraw', action='store', dest='hidraw_path', metavar='PATH', + help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2') arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)') arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__) @@ -81,7 +83,7 @@ def main(): args = _parse_arguments() if not args: return - if args.action: return _cli.run(args.action) + if args.action: return _cli.run(args.action, args.hidraw_path) _require('gi.repository', 'python-gi') _require('gi.repository.Gtk', 'gir1.2-gtk-3.0') From 9c465cd998026d93389adcfaabb02f45f6649422 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 21 Aug 2013 01:03:35 +0200 Subject: [PATCH 3/4] Fix wrong register name for illumination (hidpp10) Broken since 9a2a28e, this causes a lot of exceptions for every move. --- lib/logitech_receiver/notifications.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logitech_receiver/notifications.py b/lib/logitech_receiver/notifications.py index ac6df189..7a0d2664 100644 --- a/lib/logitech_receiver/notifications.py +++ b/lib/logitech_receiver/notifications.py @@ -127,7 +127,7 @@ def _process_hidpp10_custom_notification(device, status, n): status.set_battery_info(charge, status_text) return True - if n.sub_id == _R.illumination: + if n.sub_id == _R.keyboard_illumination: # message layout: 10 ix 17("address") # TODO anything we can do with this? if _log.isEnabledFor(_INFO): From b193b397011697b8fb8993d84548e30473406aa3 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 23 Aug 2013 21:23:23 +0200 Subject: [PATCH 4/4] Fix missing reprogrammable keys The assumption that the Features IDs are in increasing order does not hold. This causes the feature check for REPROG CONTROLS (1B00) to fail, therefore remove the micro-optimisation. While at it, rename variables and document the functions better. --- lib/logitech_receiver/hidpp20.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py index fd03da2e..5ab67008 100644 --- a/lib/logitech_receiver/hidpp20.py +++ b/lib/logitech_receiver/hidpp20.py @@ -210,9 +210,10 @@ class FeaturesArray(object): indices = index.indices(len(self.features)) return [self.__getitem__(i) for i in range(*indices)] - def __contains__(self, value): + def __contains__(self, featureId): + """Tests whether the list contains given Feature ID""" if self._check(): - ivalue = int(value) + ivalue = int(featureId) may_have = False for f in self.features: @@ -220,8 +221,6 @@ class FeaturesArray(object): may_have = True elif ivalue == int(f): return True - elif ivalue < int(f): - break if may_have: reply = self.device.request(0x0000, _pack('!H', ivalue)) @@ -231,17 +230,16 @@ class FeaturesArray(object): self.features[index] = FEATURE[ivalue] return True - def index(self, value): + def index(self, featureId): + """Gets the Feature Index for a given Feature ID""" if self._check(): may_have = False - ivalue = int(value) + ivalue = int(featureId) for index, f in enumerate(self.features): if f is None: may_have = True elif ivalue == int(f): return index - elif ivalue < int(f): - raise ValueError("%r not in list" % value) if may_have: reply = self.device.request(0x0000, _pack('!H', ivalue)) @@ -250,7 +248,7 @@ class FeaturesArray(object): self.features[index] = FEATURE[ivalue] return index - raise ValueError("%r not in list" % value) + raise ValueError("%r not in list" % featureId) def __iter__(self): if self._check():