1
"""This file contains the DeviceManager class."""
7
if getattr(dbus, "version", (0,0,0)) >= (0,41,0):
21
from Representation import Representation
22
from Device import Device
24
from LibGladeApplication import LibGladeApplication
26
class DeviceManager(LibGladeApplication):
27
"""This is the main window for the application."""
30
def on_about_activate(self, w):
31
"""Show the about dialog."""
35
self.about = gnome.ui.About(Const.NAME_LONG, Const.VERSION, Const.COPYRIGHT,
36
Const.INFO, Const.AUTHORS).show()
39
def on_virtual_devices_activate(self, obj):
40
self.dont_show_virtual = 1 - self.dont_show_virtual
41
self.update_device_list()
44
"""Init the GUI and connect to the HAL daemon."""
45
LibGladeApplication.__init__(self, Const.DATADIR + "/hal-device-manager.glade")
47
ver = getattr(dbus, 'version', (0, 0, 0))
49
dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
50
gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
51
"The DBus Python Bindings you are using are too old. "
52
"Make sure you have the latest version!")
56
if not gnome_imported:
57
self.xml.get_widget("about1").set_sensitive(0)
59
self.representation = Representation()
61
self.bus = dbus.SystemBus()
62
self.hal_manager_obj = self.bus.get_object("org.freedesktop.Hal",
63
"/org/freedesktop/Hal/Manager")
64
self.hal_manager = dbus.Interface(self.hal_manager_obj,
65
"org.freedesktop.Hal.Manager")
67
# gdl_changed will be invoked when the Global Device List is changed
69
self.hal_manager.connect_to_signal("DeviceAdded",
70
lambda *args: self.gdl_changed("DeviceAdded", *args))
71
self.hal_manager.connect_to_signal("DeviceRemoved",
72
lambda *args: self.gdl_changed("DeviceRemoved", *args))
73
self.hal_manager.connect_to_signal("NewCapability",
74
lambda *args: self.gdl_changed("NewCapability", *args))
76
# Add listeners for all devices
78
device_names = self.hal_manager.GetAllDevices()
80
dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
81
gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
82
"Could not get device list. "
83
"Make sure hald is running!")
87
for name in device_names:
88
self.add_device_signal_recv (name);
90
self.dont_show_virtual = 1
91
self.update_device_list()
92
self.main_window.show()
94
def add_device_signal_recv (self, udi):
95
self.bus.add_signal_receiver(lambda *args: self.property_modified(udi, *args),
97
"org.freedesktop.Hal.Device",
98
"org.freedesktop.Hal",
101
def remove_device_signal_recv (self, udi):
103
self.bus.remove_signal_receiver(None,
105
"org.freedesktop.Hal.Device",
106
"org.freedesktop.Hal",
109
print "Older versions of the D-BUS bindings have an error when removing signals. Please upgrade."
112
def get_current_focus_udi(self):
113
"""Get the UDI of the currently focused device"""
114
(tree_model, tree_iter) = self.tree_selection.get_selected()
116
device_udi = tree_model.get_value(tree_iter, Const.UDI_COLUMN)
120
def on_device_tree_selection_changed(self, tree_selection):
121
"""This method is called when the selection has changed in the
123
device_udi = self.get_current_focus_udi()
124
if device_udi != None:
125
device = self.udi_to_device(device_udi)
126
self.update_device_notebook(device)
129
def device_condition(self, device_udi, condition_name, condition_details):
130
"""This method is called when signals on the Device interface is
133
print "\nCondition device=%s"%device_udi
134
print " (condition_name, condition_details) = ('%s', '%s')"%(condition_name, condition_details)
136
def property_modified(self, device_udi, num_changes, change_list):
137
"""This method is called when signals on the Device interface is
140
print "\nPropertyModified, device=%s"%device_udi
141
for i in change_list:
146
print " key=%s, rem=%d, add=%d"%(property_name, removed, added)
147
if property_name=="info.parent":
148
self.update_device_list()
150
device_udi_obj = self.bus.get_object("org.freedesktop.Hal", device_udi)
151
device_obj = self.udi_to_device(device_udi)
153
if device_udi_obj.PropertyExists(property_name, dbus_interface="org.freedesktop.Hal.Device"):
154
device_obj.properties[property_name] = device_udi_obj.GetProperty(property_name,
155
dbus_interface="org.freedesktop.Hal.Device")
156
print " value=%s"%(device_obj.properties[property_name])
158
if device_obj != None:
160
del device_obj.properties[property_name]
164
device_focus_udi = self.get_current_focus_udi()
165
if device_focus_udi != None:
166
device = self.udi_to_device(device_udi)
167
if device_focus_udi==device_udi:
168
self.update_device_notebook(device)
170
def gdl_changed(self, signal_name, device_udi, *args):
171
"""This method is called when a HAL device is added or removed."""
173
if signal_name=="DeviceAdded":
174
print "\nDeviceAdded, udi=%s"%(device_udi)
175
self.add_device_signal_recv (device_udi)
176
self.update_device_list()
177
elif signal_name=="DeviceRemoved":
178
print "\nDeviceRemoved, udi=%s"%(device_udi)
179
self.remove_device_signal_recv (device_udi)
180
self.update_device_list()
181
elif signal_name=="NewCapability":
183
print "\nNewCapability, cap=%s, udi=%s"%(cap, device_udi)
185
print "*** Unknown signal %s"% signal_name
188
def update_device_list(self):
189
"""Builds, or rebuilds, the device tree"""
190
# We use a virtual root device so we have a single tree
191
self.virtual_root = self.build_device_tree()
193
# (Name to display, device UDI)
198
self.tree_model = gtk.TreeStore(gtk.gdk.Pixbuf,
199
gobject.TYPE_STRING, gobject.TYPE_STRING)
201
it = self.tree_model.get_iter_first()
204
self.tree_model.remove(it)
206
self.virtual_root.populate_gtk_tree(self.tree_model,
207
self.dont_show_virtual,
210
tree_view = self.xml.get_widget("device_tree")
212
if self.tree_selection:
215
self.tree_selection = tree_view.get_selection()
216
self.tree_selection.connect("changed",
217
self.on_device_tree_selection_changed)
219
# add new columns only first time
224
self.column_dt = gtk.TreeViewColumn()
225
self.column_dt.set_title("Devices")
226
render_pixbuf = gtk.CellRendererPixbuf()
227
self.column_dt.pack_start(render_pixbuf, expand=False)
228
self.column_dt.add_attribute(render_pixbuf, "pixbuf",
230
render_text = gtk.CellRendererText()
231
self.column_dt.pack_start(render_text, expand=True)
232
self.column_dt.add_attribute(render_text, "text",
234
tree_view.append_column(self.column_dt)
236
tree_view.set_model(self.tree_model)
237
tree_view.expand_all()
239
# Set focus to first element
240
tree_view.grab_focus()
241
self.update_device_notebook(self.virtual_root.children[0])
244
def udi_to_device(self, device_udi):
245
"""Given a HAL UDI (Unique Device Identifier) this method returns
246
the corresponding HAL device"""
247
return self.virtual_root.find_by_udi(device_udi)
249
def build_device_tree(self):
250
"""Retrieves the device list from the HAL daemon and builds
251
a tree of Device (Python) objects. The root is a virtual
253
device_names = self.hal_manager.GetAllDevices()
256
virtual_root = Device("virtual_root", None, {})
257
self.device_list = [virtual_root]
259
# first build list of Device objects
260
for name in device_names:
261
device_dbus_obj = self.bus.get_object("org.freedesktop.Hal" ,name)
262
properties = device_dbus_obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
264
parent_name = properties["info.parent"]
266
# no parent, must be parent of virtual_root
269
print "Error: no properties for device %s"%name
271
device = Device(name, parent_name, properties)
272
self.device_list.append(device)
274
# set parent_device and children for each Device object
275
for device in self.device_list:
276
parent_name = device.parent_name
277
device.parent_device = virtual_root
279
for p in self.device_list:
280
if p.device_name==parent_name:
281
device.parent_device = p
282
p.children.append(device)
283
if device!=virtual_root and device.parent_device==virtual_root:
284
virtual_root.children.append(device)
285
if device==virtual_root:
286
device.parent_device=None
290
def update_tab_device(self, device):
291
"""Updates the 'Device' tab given a Device object"""
292
bus = self.xml.get_widget("ns_device_bus")
293
#state = self.xml.get_widget("ns_device_status")
294
vendor = self.xml.get_widget("ns_device_vendor")
295
product = self.xml.get_widget("ns_device_name")
296
category = self.xml.get_widget("ns_device_category")
297
capabilities = self.xml.get_widget("ns_device_capabilities")
299
product.set_label("Unknown")
300
vendor.set_label("Unknown")
301
#state.set_label(Const.STATE_NAMES[device.properties["State"]])
303
# walk up the device tree to find the bus type
304
bus.set_label("Unknown")
307
if d.properties.has_key("info.subsystem"):
308
bus.set_label(Const.BUS_NAMES[d.properties["info.subsystem"]])
310
d = self.udi_to_device(d.properties["info.parent"])
312
# guestimate product and vendor if we have no device information file
313
if device.properties.has_key("info.subsystem") and device.properties["info.subsystem"]=="usb":
314
if device.properties.has_key("info.product"):
315
product.set_label("%s"%device.properties["info.product"])
316
elif device.properties.has_key("usb.product"):
317
product.set_label("%s"%device.properties["usb.product"])
318
elif device.properties.has_key("usb.product_id"):
319
product.set_label("Unknown (0x%x)"%device.properties["usb.product_id"])
321
product.set_label("Unknown")
323
if device.properties.has_key("info.vendor"):
324
vendor.set_label("%s"%device.properties["info.vendor"])
325
elif device.properties.has_key("usb.vendor"):
326
vendor.set_label("%s"%device.properties["usb.vendor"])
327
elif device.properties.has_key("usb.vendor_id"):
328
vendor.set_label("Unknown (0x%x)"%device.properties["usb.vendor_id"])
330
vendor.set_label("Unknown")
333
elif device.properties.has_key("info.subsystem") and device.properties["info.subsystem"]=="pci":
334
if device.properties.has_key("info.product"):
335
product.set_label("%s"%device.properties["info.product"])
336
elif device.properties.has_key("pci.product"):
337
product.set_label("%s"%device.properties["pci.product"])
338
elif device.properties.has_key("pci.product_id"):
339
product.set_label("Unknown (0x%x)"%device.properties["pci.product_id"])
341
product.set_label("Unknown")
343
if device.properties.has_key("info.vendor"):
344
vendor.set_label("%s"%device.properties["info.vendor"])
345
elif device.properties.has_key("pci.vendor"):
346
vendor.set_label("%s"%device.properties["pci.vendor"])
347
elif device.properties.has_key("pci.vendor_id"):
348
vendor.set_label("Unknown (0x%x)"%device.properties["pci.vendor_id"])
350
vendor.set_label("Unknown")
351
elif device.properties.has_key("info.subsystem") and device.properties["info.subsystem"]=="block":
352
if device.properties.has_key("info.product"):
353
product.set_label("%s"%device.properties["info.product"])
355
product.set_label("Unknown")
357
if device.properties.has_key("info.vendor"):
358
vendor.set_label("%s"%device.properties["info.vendor"])
360
vendor.set_label("Unknown")
362
product.set_label("Unknown")
363
vendor.set_label("Unknown")
365
# clear category, capabilities
366
# set category, capabilities
367
if device.properties.has_key("info.category"):
368
category.set_label("%s"%device.properties["info.category"])
370
category.set_label("Unknown")
372
if device.properties.has_key("info.capabilities"):
373
capabilities.set_label(", ".join(device.properties["info.capabilities"]))
375
capabilities.set_label("Unknown")
377
def update_tab_usb(self, device):
378
"""Updates the 'USB' tab given a Device object; may hide it"""
379
page = self.xml.get_widget("device_notebook").get_nth_page(1)
380
if not device.properties.has_key("info.subsystem") or device.properties["info.subsystem"]!="usb":
386
version = self.xml.get_widget("ns_usb_version")
387
bandwidth = self.xml.get_widget("ns_usb_bandwidth")
388
maxpower = self.xml.get_widget("ns_usb_maxpower")
389
man_id = self.xml.get_widget("ns_usb_man_id")
390
prod_id = self.xml.get_widget("ns_usb_prod_id")
391
revision = self.xml.get_widget("ns_usb_rev")
393
bcdVersion = device.properties["usb.version_bcd"]
394
version.set_label("%x.%x"%(bcdVersion>>8, bcdVersion&0xff))
396
bcdSpeed = device.properties["usb.speed_bcd"]
397
bandwidth.set_label("%x.%x Mbit/s"%(bcdSpeed>>8, bcdSpeed&0xff))
398
maxpower.set_label("%d mA"%(device.properties["usb.max_power"]))
399
if not device.properties.has_key("usb.vendor"):
400
man_id.set_label("0x%04x"%(device.properties["usb.vendor_id"]))
402
man_id.set_label("%s"%(device.properties["usb.vendor"]))
403
if not device.properties.has_key("usb.product"):
404
prod_id.set_label("0x%04x"%(device.properties["usb.product_id"]))
406
prod_id.set_label("%s"%(device.properties["usb.product"]))
407
bcdDevice = device.properties["usb.device_revision_bcd"]
408
revision.set_label("%x.%x"%((bcdDevice>>8), bcdDevice&0xff))
411
def update_tab_pci(self, device):
412
"""Updates the 'PCI' tab given a Device object; may hide it"""
413
page = self.xml.get_widget("device_notebook").get_nth_page(2)
414
if not device.properties.has_key("info.subsystem") or device.properties["info.subsystem"]!="pci":
420
man_id = self.xml.get_widget("ns_pci_man_id")
421
prod_id = self.xml.get_widget("ns_pci_prod_id")
422
subsys_man_id = self.xml.get_widget("ns_pci_subsys_man_id")
423
subsys_prod_id = self.xml.get_widget("ns_pci_subsys_prod_id")
425
if not device.properties.has_key("pci.vendor"):
426
man_id.set_label("Unknown (0x%04x)"%(device.properties["pci.vendor_id"]))
428
man_id.set_label("%s"%(device.properties["pci.vendor"]))
429
if not device.properties.has_key("pci.product"):
430
prod_id.set_label("Unknown (0x%04x)"%(device.properties["pci.product_id"]))
432
prod_id.set_label("%s"%(device.properties["pci.product"]))
434
if not device.properties.has_key("pci.subsys_vendor"):
435
subsys_man_id.set_label("Unknown (0x%04x)"%(device.properties["pci.subsys_vendor_id"]))
437
subsys_man_id.set_label("%s"%(device.properties["pci.subsys_vendor"]))
438
if not device.properties.has_key("pci.subsys_product"):
439
subsys_prod_id.set_label("Unknown (0x%04x)"%(device.properties["pci.subsys_product_id"]))
441
subsys_prod_id.set_label("%s"%(device.properties["pci.subsys_product"]))
443
def update_tab_advanced(self, device):
444
"""Updates the 'Advanced' tab given a Device object"""
445
store = gtk.ListStore(gobject.TYPE_STRING,
448
keys = device.properties.keys()
451
iter = store.append()
452
val = device.properties[p]
455
store.set(iter, 0, p, 1, "string", 2, "%s"%val)
457
store.set(iter, 0, p, 1, "int", 2, "%d (0x%x)"%(val, val))
459
store.set(iter, 0, p, 1, "long", 2, "%d (0x%x)"%(val, val))
462
store.set(iter, 0, p, 1, "bool", 2, "true")
464
store.set(iter, 0, p, 1, "bool", 2, "false")
466
store.set(iter, 0, p, 1, "float", 2, "%f"%val)
468
store.set(iter, 0, p, 1, "list", 2, ", ".join(val))
471
store.set(iter, 0, p, 1, "strlist", 2, val)
474
prop_tree_view = self.xml.get_widget("ns_adv_properties")
476
# remove old columns, if any
477
cols = prop_tree_view.get_columns()
479
prop_tree_view.remove_column(cr)
481
cell_renderer = gtk.CellRendererText()
482
cell_renderer.set_property("editable", True)
484
column0 = gtk.TreeViewColumn("Key", cell_renderer, text=0)
485
column1 = gtk.TreeViewColumn("Type", cell_renderer, text=1)
486
column2 = gtk.TreeViewColumn("Value", cell_renderer, text=2)
487
prop_tree_view.append_column(column0)
488
prop_tree_view.append_column(column1)
489
prop_tree_view.append_column(column2)
491
prop_tree_view.set_model(store)
494
def update_device_notebook(self, device):
495
"""Updates the entire notebook of tabs given a Device object"""
496
self.update_tab_device(device)
497
self.update_tab_advanced(device)
498
self.update_tab_usb(device)
499
self.update_tab_pci(device)