gnome-lirc-properties r33 - in trunk: . gnome_lirc_properties gnome_lirc_properties/ui



Author: hasselmm
Date: Sun May 18 20:05:05 2008
New Revision: 33
URL: http://svn.gnome.org/viewvc/gnome-lirc-properties?rev=33&view=rev

Log:
Don't add pure keyboards to the main window's receiver list, and use
the input device's human readable name instead of its device node to
configure input devices.

* gnome_lirc_properties/hardware.py
 (HalDevice.find_input_device(), HalDevice.has_capability(),
  HalDevice.read_sysfs_file(), HalDevice.get_sysfs_path(),
  HalDevice.is_real_keyboard(), HardwareManager._on_device_added(),
  HardwareManager.__find_input_layer_receivers()): Use human readable
  name instead of its device node to configure input devices. Add
  HalDevice.has_capability() to conveniently check if a HAL device has
  a certain HAL capability. Add functions to conveniently access sysfs
  files associated with a HAL device. Move keyboard detection code
  into a separate method. Don't emit 'receiver-added' signals for real
  keyboards.

* gnome_lirc_properties/ui/RemoteControlProperties.py
 (RemoteControlProperties._on_receiver_product_list_changed(),
  RemoteControlProperties.__set_selected_receiver(),
  RemoteControlProperties.__setup_models()): Refilter the remote
  vendor list when pluggable receivers are added or removed. Handle
  RuntimeErrors and prevent endless loop when the current receiver
  vendor has no models, which happens when unplugging the last Linux
  Input device.

* gnome_lirc_properties/lirc.py (HardwareConfParser.__init__()):
  Properly handle lines with more than one equal sign.


Modified:
   trunk/ChangeLog
   trunk/gnome_lirc_properties/hardware.py
   trunk/gnome_lirc_properties/lirc.py
   trunk/gnome_lirc_properties/ui/RemoteControlProperties.py

Modified: trunk/gnome_lirc_properties/hardware.py
==============================================================================
--- trunk/gnome_lirc_properties/hardware.py	(original)
+++ trunk/gnome_lirc_properties/hardware.py	Sun May 18 20:05:05 2008
@@ -43,8 +43,6 @@
         self.__bus = bus
         self.__udi = udi
 
-        self.__capabilities = None
-
     def __getitem__(self, key):
         try:
             return self.__obj.GetProperty(key)
@@ -125,9 +123,18 @@
 
     def find_input_device(self):
         '''Find the Linux Input System device node associated with this device.'''
-        for device in self.find_children():
-            if device.get('info.category') == 'input':
-                return device['input.device']
+
+        if self.get('info.category') == 'input':
+            name = self.read_sysfs_file('..', 'name')
+
+            if name is not None:
+                return 'name=' + name.replace(' ', '?')
+
+            return self['input.device']
+
+        for child in self.find_children():
+            if child.get('info.category') == 'input':
+                return child.find_input_device()
 
         return None
 
@@ -143,21 +150,46 @@
 
         return None
 
-    def __get_capabilities(self):
-        '''Query device capabilities as published in sysfs.'''
+    def has_capability(self, capability):
+        '''Checks if the device has a certain capability...'''
+        return (capability in self.get('info.capabilities', []))
+
+    def get_sysfs_path(self, *path):
+        '''Returns the path for an associated sysfs entry.'''
+        return os.path.join(self['linux.sysfs_path'], *path)
+
+    def read_sysfs_file(self, *path):
+        '''Returns the content of an associated sysfs file.'''
+        sysfs_path = self.get_sysfs_path(*path)
 
-        if self.__capabilities is None:
-            sysfs_path = self['linux.sysfs_path']
-            caps_path = os.path.join(sysfs_path, '..', 'capabilities')
-            self.__capabilities = dict()
-
-            if os.path.isdir(caps_path):
-                for name in os.listdir(caps_path):
-                    caps = open(os.path.join(caps_path, name)).read()
-                    caps = [int(value, 16) for value in caps.split()]
-                    self.__capabilities[name] = tuple(caps)
+        if os.path.isfile(sysfs_path):
+            return open(sysfs_path).read().rstrip()
 
-        return self.__capabilities
+        return None
+
+    def is_real_keyboard(self):
+        '''
+        Try figure out if this device is a keyboard. Keyboards are detected by
+        counting the number of supported keys. The original PC keyboard had 85
+        keys, so maybe this is a reasonable boundary. Maybe it would make more
+        sense to look for typical key-codes like SHIFT, CTRL, CAPSLOCK or
+        NUMLOCK?
+        '''
+
+        # check if HAL considers this device a keyboard:
+        if self.has_capability('input.keyboard'):
+            # read and parse key-code map from sysfs:
+            keys = self.read_sysfs_file('..', 'capabilities', 'key')
+
+            if keys is not None:
+                keys = [int(value, 16) for value in keys.split()]
+                keys = decode_bitmap(keys)
+
+                # check that at least 85 key-codes are supported:
+                if len(keys) >= 85:
+                    return True
+
+        return False
 
     def __str__(self):
         return self.__udi
@@ -166,7 +198,6 @@
 
     # pylint: disable-msg=W0212
     udi = property(fget=lambda self: self.__udi)
-    capabilities = property(fget=__get_capabilities)
 
 class HardwareDatabase(SafeConfigParser):
     '''Information about supported hardware.'''
@@ -249,7 +280,9 @@
 
         device = self.lookup_device(udi)
 
-        if 'input.keyboard' in device.get('info.capabilities', []):
+        if (device.has_capability('input.keyboard') and
+            not device.is_real_keyboard()):
+
             product_name = str(device['info.product'])
             device_node = str(device['input.device'])
 
@@ -419,7 +452,7 @@
             # lookup the current device:
             device = self.lookup_device(device)
             product_name = device.get('info.product')
-            device_node = device.get('input.device')
+            device_node = device.find_input_device()
 
             # report search progress:
             self.__report_search_progress(product_name)
@@ -428,14 +461,8 @@
             if product_name is None or device_node is None:
                 continue
 
-            # Skip input devices that seem to be keyboards. Currently keyboards
-            # are detected by counting the number of supported keys. The original
-            # PC keyboard had 85 keys, so maybe this is a reasonable boundary.
-            # Maybe it would make more sense to look for typical key-codes
-            # like SHIFT, CTRL, CAPSLOCK or NUMLOCK?
-            keys = device.capabilities.get('key')
-
-            if keys and len(decode_bitmap(keys)) >= 85:
+            # skip input devices that seem to be keyboards:
+            if device.is_real_keyboard():
                 continue
 
             # report findings:

Modified: trunk/gnome_lirc_properties/lirc.py
==============================================================================
--- trunk/gnome_lirc_properties/lirc.py	(original)
+++ trunk/gnome_lirc_properties/lirc.py	Sun May 18 20:05:05 2008
@@ -1003,7 +1003,7 @@
         self.__values = dict()
 
         for line in open(filename, 'r'):
-            tokens = [t.strip() for t in line.split('=', 2)]
+            tokens = [t.strip() for t in line.split('=', 1)]
 
             if len(tokens) < 2:
                 continue

Modified: trunk/gnome_lirc_properties/ui/RemoteControlProperties.py
==============================================================================
--- trunk/gnome_lirc_properties/ui/RemoteControlProperties.py	(original)
+++ trunk/gnome_lirc_properties/ui/RemoteControlProperties.py	Sun May 18 20:05:05 2008
@@ -65,15 +65,24 @@
     def __setup_models(self):
         '''Initialize model objects of the dialog.'''
 
+        def refilter_vendor_list(*args):
+            '''Refilter the vendor list model when receivers where added/removed.'''
+
+            gobject.idle_add(lambda:
+                self.__combo_receiver_vendor_list.get_model().refilter() and
+                False)
+
         # pylint: disable-msg=W0201,E1101
 
         receivers_db = hardware.HardwareDatabase(self.__ui.relative_file('receivers.conf'))
         self.__remotes_db = lirc.RemotesDatabase()
 
         self.__hardware_manager = hardware.HardwareManager(receivers_db)
-        self.__hardware_manager.connect('search-progress', self._on_search_progress)
-        self.__hardware_manager.connect('search-finished', self._on_search_finished)
-        self.__hardware_manager.connect('receiver-found',  self._on_receiver_found)
+        self.__hardware_manager.connect('search-progress',  self._on_search_progress)
+        self.__hardware_manager.connect('search-finished',  self._on_search_finished)
+        self.__hardware_manager.connect('receiver-found',   self._on_receiver_found)
+        self.__hardware_manager.connect('receiver-added',   refilter_vendor_list)
+        self.__hardware_manager.connect('receiver-removed', refilter_vendor_list)
 
         self.__receiver_vendors = model.ReceiverVendorList(self.__hardware_manager)
         self.__receiver_vendors.load(receivers_db)
@@ -240,8 +249,7 @@
             remote.vendor, remote.product), buttons=responses))
 
     def __restore_hardware_settings(self):
-        '''Restore hardware settings from configuration files.
-	'''
+        '''Restore hardware settings from configuration files.'''
 
         # We really do not want to rewrite any configuration files
         # at that stage, so __configuration_level should be non-zero.
@@ -560,7 +568,15 @@
         tree_iter = product_list.get_active_iter()
 
         if tree_iter is None:
-            product_list.set_active(0)
+            # Select first receiver model for current vendor when none is
+            # selected yet, but we have to consider the model list to be empty
+            # when doing this to prevent endless loops. Model lists become
+            # empty for instance when unplugging the last Linux Input device.
+            tree_iter = product_list.get_model().get_iter_first()
+
+            if tree_iter is not None:
+                product_list.set_active_iter(tree_iter)
+
             return
 
         receiver, = product_list.get_model().get(tree_iter, 1)
@@ -952,18 +968,25 @@
 
         try:
             # highlight the selected receiver's vendor name:
+            visible_vendors = self.__combo_receiver_vendor_list.get_model()
             tree_iter = self.__receiver_vendors.find_iter(vendor_name)
+            products = None
+
+            if tree_iter is not None:
+                try:
+                    tree_iter = visible_vendors.convert_child_iter_to_iter(tree_iter)
 
-            if(tree_iter == None):
-                tree_iter = self.__receiver_vendors.get_iter_first()
+                except RuntimeError:
+                    # WTF? Invisible columns definitly are an error and therefore
+                    # convert_child_iter_to_iter() should return None - as in GTK+.
+                    tree_iter = None
 
-            products = None
+            if tree_iter is None:
+                tree_iter = visible_vendors.get_iter_first()
 
             if tree_iter:
-                filter = self.__combo_receiver_vendor_list.get_model()
-                filter_iter = filter.convert_child_iter_to_iter(tree_iter)
-                self.__combo_receiver_vendor_list.set_active_iter(filter_iter)
-                products, = self.__receiver_vendors.get(tree_iter, 1)
+                self.__combo_receiver_vendor_list.set_active_iter(tree_iter)
+                products, = visible_vendors.get(tree_iter, 1)
 
             # highlight the selected receiver's product name:
             tree_iter = products and products.find_iter(product_name)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]