home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / hal / device-manager / DeviceManager.py < prev    next >
Encoding:
Python Source  |  2006-08-30  |  19.9 KB  |  501 lines

  1. """This file contains the DeviceManager class."""
  2.  
  3. import LaunchpadIntegration
  4. import sys
  5. import os
  6. import gobject
  7. import gtk
  8. import dbus
  9. if getattr(dbus, "version", (0,0,0)) >= (0,41,0):
  10.     import dbus.glib
  11.  
  12.  
  13.  
  14. try:
  15.     import gnome.ui
  16.  
  17. except ImportError:
  18.     gnome_imported = 0
  19. else:
  20.     gnome_imported = 1
  21.  
  22. import Const
  23. from Representation import Representation
  24. from Device import Device
  25.  
  26. from LibGladeApplication import LibGladeApplication
  27.  
  28. class DeviceManager(LibGladeApplication):
  29.     """This is the main window for the application."""
  30.  
  31.  
  32.     def on_about_activate(self, w):
  33.         """Show the about dialog."""
  34.         gnome.ui.About(Const.NAME_LONG, Const.VERSION, Const.COPYRIGHT,
  35.                        Const.INFO, Const.AUTHORS).show()
  36.  
  37.     def on_virtual_devices_activate(self, obj):
  38.         self.dont_show_virtual = 1 - self.dont_show_virtual
  39.         self.update_device_list()
  40.  
  41.     def on_hwdb_activate(self, w):
  42.         """ run the hwdb client, no need for a test, its a dependency now """
  43.         os.spawnl(os.P_WAIT, "/usr/bin/hwdb-gui")
  44.  
  45.     def __init__(self):
  46.         """Init the GUI and connect to the HAL daemon."""
  47.         LibGladeApplication.__init__(self, Const.DATADIR + "/hal-device-manager.glade")
  48.  
  49.         LaunchpadIntegration.set_sourcepackagename("hal")
  50.     widget = self.xml.get_widget("help1_menu")
  51.     print widget
  52.         LaunchpadIntegration.add_items (widget, -1, False, True);
  53.  
  54.         ver = getattr(dbus, 'version', (0, 0, 0))
  55.         if ver < (0, 40, 0):
  56.             dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, 
  57.                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
  58.                                        "The DBus Python Bindings you are using are too old. "
  59.                                        "Make sure you have the latest version!")
  60.             dialog.run()
  61.             sys.exit(1)
  62.  
  63.         if not gnome_imported:
  64.             self.xml.get_widget("about1").set_sensitive(0)
  65.  
  66.         self.representation = Representation()
  67.  
  68.         self.bus = dbus.SystemBus()
  69.         self.hal_manager_obj = self.bus.get_object("org.freedesktop.Hal", 
  70.                                                    "/org/freedesktop/Hal/Manager")
  71.         self.hal_manager = dbus.Interface(self.hal_manager_obj,
  72.                                           "org.freedesktop.Hal.Manager")
  73.  
  74.         # gdl_changed will be invoked when the Global Device List is changed
  75.         # per the hal spec
  76.         self.hal_manager.connect_to_signal("DeviceAdded", 
  77.                          lambda *args: self.gdl_changed("DeviceAdded", *args))
  78.         self.hal_manager.connect_to_signal("DeviceRemoved", 
  79.                          lambda *args: self.gdl_changed("DeviceRemoved", *args))
  80.         self.hal_manager.connect_to_signal("NewCapability", 
  81.                          lambda *args: self.gdl_changed("NewCapability", *args))
  82.  
  83.         # Add listeners for all devices
  84.         try:
  85.             device_names = self.hal_manager.GetAllDevices()
  86.         except:
  87.             dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, 
  88.                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
  89.                                        "Could not get device list. "
  90.                                        "Make sure hald is running!")
  91.             dialog.run()
  92.             sys.exit(1)
  93.  
  94.         for name in device_names:
  95.         self.add_device_signal_recv (name);
  96.  
  97.         self.dont_show_virtual = 1
  98.         self.update_device_list()
  99.         self.main_window.show()
  100.  
  101.     def add_device_signal_recv (self, udi):
  102.     self.bus.add_signal_receiver(lambda *args: self.property_modified(udi, *args),
  103.                      "PropertyModified",
  104.                      "org.freedesktop.Hal.Device",
  105.                      "org.freedesktop.Hal",
  106.                      udi)
  107.  
  108.     def remove_device_signal_recv (self, udi):
  109.         try:
  110.             self.bus.remove_signal_receiver(None,
  111.                             "PropertyModified",
  112.                             "org.freedesktop.Hal.Device",
  113.                             "org.freedesktop.Hal",
  114.                             udi)
  115.         except Exception, e:
  116.             print "Older versions of the D-BUS bindings have an error when removing signals. Please upgrade."
  117.             print e
  118.  
  119.     def get_current_focus_udi(self):
  120.         """Get the UDI of the currently focused device"""
  121.         (tree_model, tree_iter) = self.tree_selection.get_selected()
  122.         if tree_iter:
  123.             device_udi = tree_model.get_value(tree_iter, Const.UDI_COLUMN)
  124.             return device_udi
  125.         return None
  126.  
  127.     def on_device_tree_selection_changed(self, tree_selection):
  128.         """This method is called when the selection has changed in the
  129.         device tree"""
  130.         device_udi = self.get_current_focus_udi()
  131.         if device_udi != None:
  132.             device = self.udi_to_device(device_udi)
  133.             self.update_device_notebook(device)
  134.  
  135.  
  136.     def device_condition(self, device_udi, condition_name, condition_details):
  137.         """This method is called when signals on the Device interface is
  138.         received"""
  139.  
  140.     print "\nCondition device=%s"%device_udi
  141.     print "  (condition_name, condition_details) = ('%s', '%s')"%(condition_name, condition_details)
  142.  
  143.     def property_modified(self, device_udi, num_changes, change_list):
  144.         """This method is called when signals on the Device interface is
  145.         received"""
  146.  
  147.     print "\nPropertyModified, device=%s"%device_udi
  148.     for i in change_list:
  149.         property_name = i[0]
  150.         removed = i[1]
  151.         added = i[2]
  152.  
  153.         print "  key=%s, rem=%d, add=%d"%(property_name, removed, added)
  154.         if property_name=="info.parent":
  155.         self.update_device_list()        
  156.         else:
  157.         device_udi_obj = self.bus.get_object("org.freedesktop.Hal", device_udi)
  158.         device_obj = self.udi_to_device(device_udi)
  159.  
  160.         if device_udi_obj.PropertyExists(property_name, dbus_interface="org.freedesktop.Hal.Device"):
  161.             device_obj.properties[property_name] = device_udi_obj.GetProperty(property_name, 
  162.                                               dbus_interface="org.freedesktop.Hal.Device")
  163.             print "  value=%s"%(device_obj.properties[property_name])
  164.         else:
  165.             if device_obj != None:
  166.             try:
  167.                 del device_obj.properties[property_name]
  168.             except:
  169.                 pass
  170.  
  171.         device_focus_udi = self.get_current_focus_udi()
  172.         if device_focus_udi != None:
  173.             device = self.udi_to_device(device_udi)
  174.             if device_focus_udi==device_udi:
  175.             self.update_device_notebook(device)
  176.             
  177.     def gdl_changed(self, signal_name, device_udi, *args):
  178.         """This method is called when a HAL device is added or removed."""
  179.  
  180.         if signal_name=="DeviceAdded":
  181.             print "\nDeviceAdded, udi=%s"%(device_udi)
  182.         self.add_device_signal_recv (device_udi)
  183.             self.update_device_list()
  184.         elif signal_name=="DeviceRemoved":
  185.             print "\nDeviceRemoved, udi=%s"%(device_udi)
  186.         self.remove_device_signal_recv (device_udi)
  187.             self.update_device_list()
  188.         elif signal_name=="NewCapability":
  189.             [cap] = args 
  190.             print "\nNewCapability, cap=%s, udi=%s"%(cap, device_udi)
  191.         else:
  192.             print "*** Unknown signal %s"% signal_name
  193.  
  194.  
  195.     def update_device_list(self):
  196.         """Builds, or rebuilds, the device tree"""
  197.         # We use a virtual root device so we have a single tree
  198.         self.virtual_root = self.build_device_tree()
  199.  
  200.         # (Name to display, device UDI)
  201.         try:
  202.             if self.tree_model:
  203.                 pass
  204.         except:
  205.             self.tree_model = gtk.TreeStore(gtk.gdk.Pixbuf,
  206.                                             gobject.TYPE_STRING, gobject.TYPE_STRING)
  207.         while 1:
  208.             it = self.tree_model.get_iter_first()
  209.             if not it:
  210.                 break
  211.             self.tree_model.remove(it)
  212.  
  213.         self.virtual_root.populate_gtk_tree(self.tree_model,
  214.                                             self.dont_show_virtual,
  215.                                             self.representation)
  216.  
  217.         tree_view = self.xml.get_widget("device_tree")
  218.         try:
  219.             if self.tree_selection:
  220.                 pass
  221.         except:
  222.             self.tree_selection = tree_view.get_selection()
  223.             self.tree_selection.connect("changed",
  224.                                         self.on_device_tree_selection_changed)
  225.  
  226.         # add new columns only first time
  227.         try:
  228.             if self.column_dt:
  229.                 pass
  230.         except:
  231.             self.column_dt = gtk.TreeViewColumn()
  232.             self.column_dt.set_title("Devices")
  233.             render_pixbuf = gtk.CellRendererPixbuf()
  234.             self.column_dt.pack_start(render_pixbuf, expand=False)
  235.             self.column_dt.add_attribute(render_pixbuf, "pixbuf",
  236.                                          Const.PIXBUF_COLUMN)
  237.             render_text = gtk.CellRendererText()
  238.             self.column_dt.pack_start(render_text, expand=True)
  239.             self.column_dt.add_attribute(render_text, "text",
  240.                                          Const.TITLE_COLUMN)
  241.             tree_view.append_column(self.column_dt)
  242.  
  243.         tree_view.set_model(self.tree_model)
  244.         tree_view.expand_all()
  245.  
  246.         # Set focus to first element
  247.         tree_view.grab_focus()
  248.         self.update_device_notebook(self.virtual_root.children[0])
  249.  
  250.  
  251.     def udi_to_device(self, device_udi):
  252.         """Given a HAL UDI (Unique Device Identifier) this method returns
  253.         the corresponding HAL device"""
  254.         return self.virtual_root.find_by_udi(device_udi)
  255.  
  256.     def build_device_tree(self):
  257.         """Retrieves the device list from the HAL daemon and builds
  258.         a tree of Device (Python) objects. The root is a virtual
  259.         device"""
  260.         device_names = self.hal_manager.GetAllDevices()
  261.         device_names.sort()
  262.  
  263.         virtual_root = Device("virtual_root", None, {})
  264.         self.device_list = [virtual_root]
  265.         
  266.         # first build list of Device objects
  267.         for name in device_names:
  268.             device_dbus_obj = self.bus.get_object("org.freedesktop.Hal" ,name)
  269.             properties = device_dbus_obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
  270.             try:
  271.                 parent_name = properties["info.parent"]
  272.             except KeyError:
  273.                 # no parent, must be parent of virtual_root
  274.                 parent_name = "/"
  275.             except TypeError:
  276.                 print "Error: no properties for device %s"%name
  277.                 continue
  278.             device = Device(name, parent_name, properties)
  279.             self.device_list.append(device)
  280.  
  281.         # set parent_device and children for each Device object
  282.         for device in self.device_list:
  283.             parent_name = device.parent_name
  284.             device.parent_device = virtual_root
  285.             if parent_name!="/":
  286.                 for p in self.device_list:
  287.                     if p.device_name==parent_name:
  288.                         device.parent_device = p
  289.                         p.children.append(device)
  290.             if device!=virtual_root and device.parent_device==virtual_root:
  291.                 virtual_root.children.append(device)
  292.             if device==virtual_root:
  293.                 device.parent_device=None
  294.         return virtual_root
  295.  
  296.  
  297.     def update_tab_device(self, device):
  298.         """Updates the 'Device' tab given a Device object"""
  299.         bus = self.xml.get_widget("ns_device_bus")
  300.         #state = self.xml.get_widget("ns_device_status")
  301.         vendor = self.xml.get_widget("ns_device_vendor")
  302.         product = self.xml.get_widget("ns_device_name")
  303.         category = self.xml.get_widget("ns_device_category")
  304.         capabilities = self.xml.get_widget("ns_device_capabilities")
  305.  
  306.     if not device.properties.has_key("info.bus"):
  307.             product.set_label("Unknown")
  308.             vendor.set_label("Unknown")
  309.     else:
  310.         bus.set_label(Const.BUS_NAMES[device.properties["info.bus"]])        
  311.         #state.set_label(Const.STATE_NAMES[device.properties["State"]])
  312.  
  313.         # guestimate product and vendor if we have no device information file
  314.         if device.properties.has_key("info.bus") and device.properties["info.bus"]=="usb":
  315.             if device.properties.has_key("info.product"):
  316.                 product.set_label("%s"%device.properties["info.product"])
  317.             elif device.properties.has_key("usb.product"):
  318.                 product.set_label("%s"%device.properties["usb.product"])
  319.             elif device.properties.has_key("usb.product_id"):
  320.                 product.set_label("Unknown (0x%x)"%device.properties["usb.product_id"])
  321.             else:
  322.                 product.set_label("Unknown")
  323.  
  324.             if device.properties.has_key("info.vendor"):
  325.                 vendor.set_label("%s"%device.properties["info.vendor"])
  326.             elif device.properties.has_key("usb.vendor"):
  327.                 vendor.set_label("%s"%device.properties["usb.vendor"])
  328.             elif device.properties.has_key("usb.vendor_id"):
  329.                 vendor.set_label("Unknown (0x%x)"%device.properties["usb.vendor_id"])
  330.             else:
  331.                 vendor.set_label("Unknown")
  332.  
  333.  
  334.         elif device.properties.has_key("info.bus") and device.properties["info.bus"]=="pci":
  335.             if device.properties.has_key("info.product"):
  336.                 product.set_label("%s"%device.properties["info.product"])
  337.             elif device.properties.has_key("pci.product"):
  338.                 product.set_label("%s"%device.properties["pci.product"])
  339.             elif device.properties.has_key("pci.product_id"):
  340.                 product.set_label("Unknown (0x%x)"%device.properties["pci.product_id"])
  341.             else:
  342.                 product.set_label("Unknown")
  343.  
  344.             if device.properties.has_key("info.vendor"):
  345.                 vendor.set_label("%s"%device.properties["info.vendor"])
  346.             elif device.properties.has_key("pci.vendor"):
  347.                 vendor.set_label("%s"%device.properties["pci.vendor"])
  348.             elif device.properties.has_key("pci.vendor_id"):
  349.                 vendor.set_label("Unknown (0x%x)"%device.properties["pci.vendor_id"])
  350.             else:
  351.                 vendor.set_label("Unknown")
  352.         elif device.properties.has_key("info.bus") and device.properties["info.bus"]=="block":
  353.             if device.properties.has_key("info.product"):
  354.                 product.set_label("%s"%device.properties["info.product"])
  355.             else:
  356.                 product.set_label("Unknown")
  357.  
  358.             if device.properties.has_key("info.vendor"):
  359.                 vendor.set_label("%s"%device.properties["info.vendor"])
  360.             else:
  361.                 vendor.set_label("Unknown")
  362.         else:
  363.             product.set_label("Unknown")
  364.             vendor.set_label("Unknown")
  365.  
  366.         # clear category, capabilities
  367.         # set category, capabilities
  368.         if device.properties.has_key("info.category"):
  369.             category.set_label("%s"%device.properties["info.category"])
  370.         else:
  371.         category.set_label("Unknown")
  372.  
  373.     if device.properties.has_key("info.capabilities"):
  374.             capabilities.set_label(", ".join(device.properties["info.capabilities"]))
  375.     else:
  376.         capabilities.set_label("Unknown")
  377.  
  378.     def update_tab_usb(self, device):
  379.         """Updates the 'USB' tab given a Device object; may hide it"""
  380.         page = self.xml.get_widget("device_notebook").get_nth_page(1)
  381.         if not device.properties.has_key("info.bus") or device.properties["info.bus"]!="usb":
  382.             page.hide_all()
  383.             return
  384.  
  385.         page.show_all()
  386.  
  387.         version = self.xml.get_widget("ns_usb_version")
  388.         bandwidth = self.xml.get_widget("ns_usb_bandwidth")
  389.         maxpower = self.xml.get_widget("ns_usb_maxpower")
  390.         man_id = self.xml.get_widget("ns_usb_man_id")
  391.         prod_id = self.xml.get_widget("ns_usb_prod_id")
  392.         revision = self.xml.get_widget("ns_usb_rev")
  393.  
  394.         bcdVersion = device.properties["usb.version_bcd"]
  395.         version.set_label("%x.%x"%(bcdVersion>>8, bcdVersion&0xff))
  396.  
  397.         bcdSpeed = device.properties["usb.speed_bcd"]
  398.         bandwidth.set_label("%x.%x Mbit/s"%(bcdSpeed>>8, bcdSpeed&0xff))
  399.         maxpower.set_label("%d mA"%(device.properties["usb.max_power"]))
  400.         if not device.properties.has_key("usb.vendor"):
  401.             man_id.set_label("0x%04x"%(device.properties["usb.vendor_id"]))
  402.         else:
  403.             man_id.set_label("%s"%(device.properties["usb.vendor"]))
  404.         if not device.properties.has_key("usb.product"):
  405.             prod_id.set_label("0x%04x"%(device.properties["usb.product_id"]))
  406.         else:
  407.             prod_id.set_label("%s"%(device.properties["usb.product"]))
  408.         bcdDevice = device.properties["usb.device_revision_bcd"]
  409.         revision.set_label("%x.%x"%((bcdDevice>>8), bcdDevice&0xff))
  410.  
  411.  
  412.     def update_tab_pci(self, device):
  413.         """Updates the 'PCI' tab given a Device object; may hide it"""
  414.         page = self.xml.get_widget("device_notebook").get_nth_page(2)
  415.         if not device.properties.has_key("info.bus") or device.properties["info.bus"]!="pci":
  416.             page.hide_all()
  417.             return
  418.  
  419.         page.show_all()
  420.  
  421.         man_id = self.xml.get_widget("ns_pci_man_id")
  422.         prod_id = self.xml.get_widget("ns_pci_prod_id")
  423.         subsys_man_id = self.xml.get_widget("ns_pci_subsys_man_id")
  424.         subsys_prod_id = self.xml.get_widget("ns_pci_subsys_prod_id")
  425.  
  426.         if not device.properties.has_key("pci.vendor"):
  427.             man_id.set_label("Unknown (0x%04x)"%(device.properties["pci.vendor_id"]))
  428.         else:
  429.             man_id.set_label("%s"%(device.properties["pci.vendor"]))
  430.         if not device.properties.has_key("pci.product"):
  431.             prod_id.set_label("Unknown (0x%04x)"%(device.properties["pci.product_id"]))
  432.         else:
  433.             prod_id.set_label("%s"%(device.properties["pci.product"]))
  434.  
  435.         if not device.properties.has_key("pci.subsys_vendor"):
  436.             subsys_man_id.set_label("Unknown (0x%04x)"%(device.properties["pci.subsys_vendor_id"]))
  437.         else:
  438.             subsys_man_id.set_label("%s"%(device.properties["pci.subsys_vendor"]))
  439.         if not device.properties.has_key("pci.subsys_product"):
  440.             subsys_prod_id.set_label("Unknown (0x%04x)"%(device.properties["pci.subsys_product_id"]))
  441.         else:
  442.             subsys_prod_id.set_label("%s"%(device.properties["pci.subsys_product"]))
  443.  
  444.     def update_tab_advanced(self, device):
  445.         """Updates the 'Advanced' tab given a Device object"""
  446.         store = gtk.ListStore(gobject.TYPE_STRING,
  447.                               gobject.TYPE_STRING,
  448.                               gobject.TYPE_STRING)
  449.         keys = device.properties.keys()
  450.         keys.sort()
  451.         for p in keys:
  452.             iter = store.append()
  453.             val = device.properties[p]
  454.             ptype = type(val)
  455.             if ptype==str:
  456.                 store.set(iter, 0, p, 1, "string", 2, "%s"%val)
  457.             elif ptype==int:
  458.                 store.set(iter, 0, p, 1, "int", 2, "%d (0x%x)"%(val, val))
  459.             elif ptype==long:
  460.                 store.set(iter, 0, p, 1, "long", 2, "%d (0x%x)"%(val, val))
  461.             elif ptype==bool:
  462.                 if val:
  463.                     store.set(iter, 0, p, 1, "bool", 2, "true")
  464.                 else:
  465.                     store.set(iter, 0, p, 1, "bool", 2, "false")
  466.             elif ptype==float:
  467.                 store.set(iter, 0, p, 1, "float", 2, "%f"%val)
  468.         elif ptype==list:
  469.         store.set(iter, 0, p, 1, "list", 2, ", ".join(val))
  470.         else:
  471.         # assume strlist
  472.         store.set(iter, 0, p, 1, "strlist", 2, val)
  473.  
  474.  
  475.         prop_tree_view = self.xml.get_widget("ns_adv_properties")
  476.  
  477.         # remove old columns, if any
  478.         cols = prop_tree_view.get_columns()
  479.         for cr in cols:
  480.             prop_tree_view.remove_column(cr)
  481.         
  482.         cell_renderer = gtk.CellRendererText()
  483.         cell_renderer.set_property("editable", True)
  484.         
  485.         column0 = gtk.TreeViewColumn("Key", cell_renderer, text=0)
  486.         column1 = gtk.TreeViewColumn("Type", cell_renderer, text=1)
  487.         column2 = gtk.TreeViewColumn("Value", cell_renderer, text=2)
  488.         prop_tree_view.append_column(column0)
  489.         prop_tree_view.append_column(column1)
  490.         prop_tree_view.append_column(column2)
  491.  
  492.         prop_tree_view.set_model(store)
  493.  
  494.  
  495.     def update_device_notebook(self, device):
  496.         """Updates the entire notebook of tabs given a Device object"""
  497.         self.update_tab_device(device)
  498.         self.update_tab_advanced(device)
  499.         self.update_tab_usb(device)
  500.         self.update_tab_pci(device)
  501.