• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • tdehw
tdehardwaredevices.cpp
1 /* This file is part of the TDE libraries
2  Copyright (C) 2012-2014 Timothy Pearson <kb9vqf@pearsoncomputing.net>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 */
18 
19 #include "tdehardwaredevices.h"
20 
21 #include <tqfile.h>
22 #include <tqdir.h>
23 #include <tqtimer.h>
24 #include <tqsocketnotifier.h>
25 #include <tqstringlist.h>
26 
27 #include <tdeconfig.h>
28 #include <kstandarddirs.h>
29 
30 #include <tdeglobal.h>
31 #include <tdelocale.h>
32 
33 #include <tdeapplication.h>
34 #include <dcopclient.h>
35 
36 extern "C" {
37 #include <libudev.h>
38 }
39 
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 
44 // Network devices
45 #include <sys/types.h>
46 #include <ifaddrs.h>
47 #include <netdb.h>
48 
49 // Backlight devices
50 #include <linux/fb.h>
51 
52 // Input devices
53 #include <linux/input.h>
54 
55 #include "kiconloader.h"
56 
57 #include "tdegenericdevice.h"
58 #include "tdestoragedevice.h"
59 #include "tdecpudevice.h"
60 #include "tdebatterydevice.h"
61 #include "tdemainspowerdevice.h"
62 #include "tdenetworkdevice.h"
63 #include "tdebacklightdevice.h"
64 #include "tdemonitordevice.h"
65 #include "tdesensordevice.h"
66 #include "tderootsystemdevice.h"
67 #include "tdeeventdevice.h"
68 #include "tdeinputdevice.h"
69 
70 // Compile-time configuration
71 #include "config.h"
72 
73 // Profiling stuff
74 //#define CPUPROFILING
75 //#define STATELESSPROFILING
76 
77 #include <time.h>
78 timespec diff(timespec start, timespec end)
79 {
80  timespec temp;
81  if ((end.tv_nsec-start.tv_nsec)<0) {
82  temp.tv_sec = end.tv_sec-start.tv_sec-1;
83  temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
84  } else {
85  temp.tv_sec = end.tv_sec-start.tv_sec;
86  temp.tv_nsec = end.tv_nsec-start.tv_nsec;
87  }
88  return temp;
89 }
90 
91 // BEGIN BLOCK
92 // Copied from include/linux/genhd.h
93 #define GENHD_FL_REMOVABLE 1
94 #define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
95 #define GENHD_FL_CD 8
96 #define GENHD_FL_UP 16
97 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32
98 #define GENHD_FL_EXT_DEVT 64
99 #define GENHD_FL_NATIVE_CAPACITY 128
100 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256
101 // END BLOCK
102 
103 // NOTE TO DEVELOPERS
104 // This command will greatly help when attempting to find properties to distinguish one device from another
105 // udevadm info --query=all --path=/sys/....
106 
107 // This routine is courtsey of an answer on "Stack Overflow"
108 // It takes an LSB-first int and makes it an MSB-first int (or vice versa)
109 unsigned int reverse_bits(register unsigned int x)
110 {
111  x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
112  x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
113  x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
114  x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
115  return((x >> 16) | (x << 16));
116 }
117 
118 // Helper function implemented in tdestoragedevice.cpp
119 TQString decodeHexEncoding(TQString str);
120 
121 #if defined(WITH_TDEHWLIB_DAEMONS) || defined(WITH_UDISKS) || defined(WITH_UDISKS2) || defined(WITH_NETWORK_MANAGER_BACKEND)
122 #include <tqdbusvariant.h>
123 #include <tqdbusdata.h>
124 // Convenience method for tdehwlib DBUS calls
125 // FIXME
126 // Should probably be part of dbus-1-tqt
127 TQT_DBusData convertDBUSDataToVariantData(TQT_DBusData object) {
128  TQT_DBusVariant variant;
129  variant.value = object;
130  variant.signature = variant.value.buildDBusSignature();
131  return TQT_DBusData::fromVariant(variant);
132 }
133 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) || defined(WITH_NETWORK_MANAGER_BACKEND)
134 
135 TDEHardwareDevices::TDEHardwareDevices() {
136  // Initialize members
137  pci_id_map = 0;
138  usb_id_map = 0;
139  pnp_id_map = 0;
140  dpy_id_map = 0;
141 
142  // Set up device list
143  m_deviceList.setAutoDelete( TRUE ); // the list owns the objects
144 
145  // Initialize udev interface
146  m_udevStruct = udev_new();
147  if (!m_udevStruct) {
148  printf("Unable to create udev interface\n");
149  }
150 
151  if (m_udevStruct) {
152  // Set up device add/remove monitoring
153  m_udevMonitorStruct = udev_monitor_new_from_netlink(m_udevStruct, "udev");
154  udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitorStruct, NULL, NULL);
155  udev_monitor_enable_receiving(m_udevMonitorStruct);
156 
157  int udevmonitorfd = udev_monitor_get_fd(m_udevMonitorStruct);
158  if (udevmonitorfd >= 0) {
159  m_devScanNotifier = new TQSocketNotifier(udevmonitorfd, TQSocketNotifier::Read, this);
160  connect( m_devScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processHotPluggedHardware()) );
161  }
162 
163  // Read in the current mount table
164  // Yes, a race condition exists between this and the mount monitor start below, but it shouldn't be a problem 99.99% of the time
165  m_mountTable.clear();
166  TQFile file( "/proc/mounts" );
167  if ( file.open( IO_ReadOnly ) ) {
168  TQTextStream stream( &file );
169  while ( !stream.atEnd() ) {
170  m_mountTable.append(stream.readLine());
171  }
172  file.close();
173  }
174 
175  // Monitor for changed mounts
176  m_procMountsFd = open("/proc/mounts", O_RDONLY, 0);
177  if (m_procMountsFd >= 0) {
178  m_mountScanNotifier = new TQSocketNotifier(m_procMountsFd, TQSocketNotifier::Exception, this);
179  connect( m_mountScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processModifiedMounts()) );
180  }
181 
182  // Read in the current cpu information
183  // Yes, a race condition exists between this and the cpu monitor start below, but it shouldn't be a problem 99.99% of the time
184  m_cpuInfo.clear();
185  TQFile cpufile( "/proc/cpuinfo" );
186  if ( cpufile.open( IO_ReadOnly ) ) {
187  TQTextStream stream( &cpufile );
188  while ( !stream.atEnd() ) {
189  m_cpuInfo.append(stream.readLine());
190  }
191  cpufile.close();
192  }
193 
194 // [FIXME 0.01]
195 // Apparently the Linux kernel just does not notify userspace applications of CPU frequency changes
196 // This is STUPID, as it means I have to poll the CPU information structures with a 0.5 second or so timer just to keep the information up to date
197 #if 0
198  // Monitor for changed cpu information
199  // Watched directories are set up during the initial CPU scan
200  m_cpuWatch = new KSimpleDirWatch(this);
201  connect( m_cpuWatch, TQT_SIGNAL(dirty(const TQString &)), this, TQT_SLOT(processModifiedCPUs()) );
202 #else
203  m_cpuWatchTimer = new TQTimer(this);
204  connect( m_cpuWatchTimer, SIGNAL(timeout()), this, SLOT(processModifiedCPUs()) );
205 #endif
206 
207  // Some devices do not receive update signals from udev
208  // These devices must be polled, and a good polling interval is 1 second
209  m_deviceWatchTimer = new TQTimer(this);
210  connect( m_deviceWatchTimer, SIGNAL(timeout()), this, SLOT(processStatelessDevices()) );
211 
212  // Special case for battery polling (longer delay, 5 seconds)
213  m_batteryWatchTimer = new TQTimer(this);
214  connect( m_batteryWatchTimer, SIGNAL(timeout()), this, SLOT(processBatteryDevices()) );
215 
216  // Update internal device information
217  queryHardwareInformation();
218  }
219 }
220 
221 TDEHardwareDevices::~TDEHardwareDevices() {
222  // Stop device scanning
223  m_deviceWatchTimer->stop();
224  m_batteryWatchTimer->stop();
225 
226 // [FIXME 0.01]
227 #if 0
228  // Stop CPU scanning
229  m_cpuWatch->stopScan();
230 #else
231  m_cpuWatchTimer->stop();
232 #endif
233 
234  // Stop mount scanning
235  close(m_procMountsFd);
236 
237  // Tear down udev interface
238  if(m_udevMonitorStruct) {
239  udev_monitor_unref(m_udevMonitorStruct);
240  }
241  udev_unref(m_udevStruct);
242 
243  // Delete members
244  if (pci_id_map) {
245  delete pci_id_map;
246  }
247  if (usb_id_map) {
248  delete usb_id_map;
249  }
250  if (pnp_id_map) {
251  delete pnp_id_map;
252  }
253  if (dpy_id_map) {
254  delete dpy_id_map;
255  }
256 }
257 
258 void TDEHardwareDevices::setTriggerlessHardwareUpdatesEnabled(bool enable) {
259  if (enable) {
260  TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
261  if (nodezerocpufreq.exists()) {
262  m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
263  }
264  m_batteryWatchTimer->stop(); // Battery devices are included in stateless devices
265  m_deviceWatchTimer->start( 1000, FALSE ); // 1 second repeating timer
266  }
267  else {
268  m_cpuWatchTimer->stop();
269  m_deviceWatchTimer->stop();
270  }
271 }
272 
273 void TDEHardwareDevices::setBatteryUpdatesEnabled(bool enable) {
274  if (enable) {
275  TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
276  if (nodezerocpufreq.exists()) {
277  m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
278  }
279  m_batteryWatchTimer->start( 5000, FALSE ); // 5 second repeating timer
280  }
281  else {
282  m_cpuWatchTimer->stop();
283  m_batteryWatchTimer->stop();
284  }
285 }
286 
287 void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) {
288  rescanDeviceInformation(hwdevice, true);
289 }
290 
291 void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice, bool regenerateDeviceTree) {
292  struct udev_device *dev;
293  dev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
294  updateExistingDeviceInformation(hwdevice);
295  if (regenerateDeviceTree) {
296  updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
297  }
298  udev_device_unref(dev);
299 }
300 
301 TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
302  if (!syspath.endsWith("/")) {
303  syspath += "/";
304  }
305  TDEGenericDevice *hwdevice;
306 
307  // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
308  TDEGenericHardwareList devList = listAllPhysicalDevices();
309  for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
310  if (hwdevice->systemPath() == syspath) {
311  return hwdevice;
312  }
313  }
314 
315  return 0;
316 }
317 
318 TDECPUDevice* TDEHardwareDevices::findCPUBySystemPath(TQString syspath, bool inCache=true) {
319  TDECPUDevice* cdevice;
320 
321  // Look for the device in the cache first
322  if(inCache && !m_cpuByPathCache.isEmpty()) {
323  cdevice = m_cpuByPathCache.find(syspath);
324  if(cdevice) {
325  return cdevice;
326  }
327  }
328 
329  // If the CPU was not found in cache, we need to parse the entire device list to get it.
330  cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(syspath));
331  if(cdevice) {
332  if(inCache) {
333  m_cpuByPathCache.insert(syspath, cdevice); // Add the device to the cache
334  }
335  return cdevice;
336  }
337 
338  return 0;
339 }
340 
341 
342 TDEGenericDevice* TDEHardwareDevices::findByUniqueID(TQString uid) {
343  TDEGenericDevice *hwdevice;
344  // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
345  TDEGenericHardwareList devList = listAllPhysicalDevices();
346  for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
347  if (hwdevice->uniqueID() == uid) {
348  return hwdevice;
349  }
350  }
351 
352  return 0;
353 }
354 
355 TDEGenericDevice* TDEHardwareDevices::findByDeviceNode(TQString devnode) {
356  TDEGenericDevice *hwdevice;
357  for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
358  if (hwdevice->deviceNode() == devnode) {
359  return hwdevice;
360  }
361  }
362 
363  return 0;
364 }
365 
366 TDEStorageDevice* TDEHardwareDevices::findDiskByUID(TQString uid) {
367  TDEGenericDevice *hwdevice;
368  for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
369  if (hwdevice->type() == TDEGenericDeviceType::Disk) {
370  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
371  if (sdevice->uniqueID() == uid) {
372  return sdevice;
373  }
374  }
375  }
376 
377  return 0;
378 }
379 
380 void TDEHardwareDevices::processHotPluggedHardware() {
381  udev_device* dev = udev_monitor_receive_device(m_udevMonitorStruct);
382  if (dev) {
383  TQString actionevent(udev_device_get_action(dev));
384  if (actionevent == "add") {
385  TDEGenericDevice* device = classifyUnknownDevice(dev);
386 
387  // Make sure this device is not a duplicate
388  TDEGenericDevice *hwdevice;
389  for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
390  if (hwdevice->systemPath() == device->systemPath()) {
391  delete device;
392  device = 0;
393  break;
394  }
395  }
396 
397  if (device) {
398  m_deviceList.append(device);
399  updateParentDeviceInformation(device); // Update parent/child tables for this device
400  emit hardwareAdded(device);
401  emit hardwareEvent(TDEHardwareEvent::HardwareAdded, device->uniqueID());
402  }
403  }
404  else if (actionevent == "remove") {
405  // Delete device from hardware listing
406  TQString systempath(udev_device_get_syspath(dev));
407  systempath += "/";
408  TDEGenericDevice *hwdevice;
409  for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
410  if (hwdevice->systemPath() == systempath) {
411  // Temporarily disable auto-deletion to ensure object validity when calling the Removed events below
412  m_deviceList.setAutoDelete(false);
413 
414  // If the device is a storage device and has a slave, update it as well
415  if (hwdevice->type() == TDEGenericDeviceType::Disk) {
416  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
417  TQStringList slavedevices = sdevice->slaveDevices();
418  m_deviceList.remove(hwdevice);
419  for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
420  TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
421  if (slavedevice) {
422  rescanDeviceInformation(slavedevice);
423  emit hardwareUpdated(slavedevice);
424  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
425  }
426  }
427  }
428  else {
429  m_deviceList.remove(hwdevice);
430  }
431 
432  emit hardwareRemoved(hwdevice);
433  emit hardwareEvent(TDEHardwareEvent::HardwareRemoved, hwdevice->uniqueID());
434 
435  // Reenable auto-deletion and delete the removed device object
436  m_deviceList.setAutoDelete(true);
437  delete hwdevice;
438 
439  break;
440  }
441  }
442  }
443  else if (actionevent == "change") {
444  // Update device and emit change event
445  TQString systempath(udev_device_get_syspath(dev));
446  systempath += "/";
447  TDEGenericDevice *hwdevice;
448  for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
449  if (hwdevice->systemPath() == systempath) {
450  if (!hwdevice->blacklistedForUpdate()) {
451  classifyUnknownDevice(dev, hwdevice, false);
452  updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
453  emit hardwareUpdated(hwdevice);
454  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
455  }
456  }
457  else if ((hwdevice->type() == TDEGenericDeviceType::Monitor)
458  && (hwdevice->systemPath().contains(systempath))) {
459  if (!hwdevice->blacklistedForUpdate()) {
460  struct udev_device *slavedev;
461  slavedev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
462  classifyUnknownDevice(slavedev, hwdevice, false);
463  udev_device_unref(slavedev);
464  updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
465  emit hardwareUpdated(hwdevice);
466  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
467  }
468  }
469  }
470  }
471  udev_device_unref(dev);
472  }
473 }
474 
475 void TDEHardwareDevices::processModifiedCPUs() {
476  // Detect what changed between the old cpu information and the new information,
477  // and emit appropriate events
478 
479 #ifdef CPUPROFILING
480  timespec time1, time2, time3;
481  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
482  time3 = time1;
483  printf("TDEHardwareDevices::processModifiedCPUs() : begin at '%u'\n", time1.tv_nsec);
484 #endif
485 
486  // Read new CPU information table
487  m_cpuInfo.clear();
488  TQFile cpufile( "/proc/cpuinfo" );
489  if ( cpufile.open( IO_ReadOnly ) ) {
490  TQTextStream stream( &cpufile );
491  // Using read() instead of readLine() inside a loop is 4 times faster !
492  m_cpuInfo = TQStringList::split('\n', stream.read(), true);
493  cpufile.close();
494  }
495 
496 #ifdef CPUPROFILING
497  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
498  printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint1 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
499  time1 = time2;
500 #endif
501 
502  // Ensure "processor" is the first entry in each block and determine which cpuinfo type is in use
503  bool cpuinfo_format_x86 = true;
504  bool cpuinfo_format_arm = false;
505 
506  TQString curline1;
507  TQString curline2;
508  int blockNumber = 0;
509  TQStringList::Iterator blockBegin = m_cpuInfo.begin();
510  for (TQStringList::Iterator cpuit1 = m_cpuInfo.begin(); cpuit1 != m_cpuInfo.end(); ++cpuit1) {
511  curline1 = *cpuit1;
512  if (!(*blockBegin).startsWith("processor")) {
513  bool found = false;
514  TQStringList::Iterator cpuit2;
515  for (cpuit2 = blockBegin; cpuit2 != m_cpuInfo.end(); ++cpuit2) {
516  curline2 = *cpuit2;
517  if (curline2.startsWith("processor")) {
518  found = true;
519  break;
520  }
521  else if (curline2 == NULL || curline2 == "") {
522  break;
523  }
524  }
525  if (found) {
526  m_cpuInfo.insert(blockBegin, (*cpuit2));
527  }
528  else if(blockNumber == 0) {
529  m_cpuInfo.insert(blockBegin, "processor : 0");
530  }
531  }
532  if (curline1 == NULL || curline1 == "") {
533  blockNumber++;
534  blockBegin = cpuit1;
535  blockBegin++;
536  }
537  else if (curline1.startsWith("Processor")) {
538  cpuinfo_format_x86 = false;
539  cpuinfo_format_arm = true;
540  }
541  }
542 
543 #ifdef CPUPROFILING
544  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
545  printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint2 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
546  time1 = time2;
547 #endif
548 
549  // Parse CPU information table
550  TDECPUDevice *cdevice;
551  cdevice = 0;
552  bool modified = false;
553  bool have_frequency = false;
554 
555  TQString curline;
556  int processorNumber = 0;
557  int processorCount = 0;
558 
559  if (cpuinfo_format_x86) {
560  // ===================================================================================================================================
561  // x86/x86_64
562  // ===================================================================================================================================
563  TQStringList::Iterator cpuit;
564  for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
565  curline = *cpuit;
566  if (curline.startsWith("processor")) {
567  curline.remove(0, curline.find(":")+2);
568  processorNumber = curline.toInt();
569  if (!cdevice) {
570  cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
571  }
572  if (cdevice) {
573  if (cdevice->coreNumber() != processorNumber) {
574  modified = true;
575  cdevice->internalSetCoreNumber(processorNumber);
576  }
577  }
578  }
579  else if (cdevice && curline.startsWith("model name")) {
580  curline.remove(0, curline.find(":")+2);
581  if (cdevice->name() != curline) {
582  modified = true;
583  cdevice->internalSetName(curline);
584  }
585  }
586  else if (cdevice && curline.startsWith("cpu MHz")) {
587  curline.remove(0, curline.find(":")+2);
588  if (cdevice->frequency() != curline.toDouble()) {
589  modified = true;
590  cdevice->internalSetFrequency(curline.toDouble());
591  }
592  have_frequency = true;
593  }
594  else if (cdevice && curline.startsWith("vendor_id")) {
595  curline.remove(0, curline.find(":")+2);
596  if (cdevice->vendorName() != curline) {
597  modified = true;
598  cdevice->internalSetVendorName(curline);
599  }
600  if (cdevice->vendorEncoded() != curline) {
601  modified = true;
602  cdevice->internalSetVendorEncoded(curline);
603  }
604  }
605  else if (curline == NULL || curline == "") {
606  cdevice = 0;
607  }
608  }
609  }
610  else if (cpuinfo_format_arm) {
611  // ===================================================================================================================================
612  // ARM
613  // ===================================================================================================================================
614  TQStringList::Iterator cpuit;
615  TQString modelName;
616  TQString vendorName;
617  TQString serialNumber;
618  for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
619  curline = *cpuit;
620  if (curline.startsWith("Processor")) {
621  curline.remove(0, curline.find(":")+2);
622  modelName = curline;
623  }
624  else if (curline.startsWith("Hardware")) {
625  curline.remove(0, curline.find(":")+2);
626  vendorName = curline;
627  }
628  else if (curline.startsWith("Serial")) {
629  curline.remove(0, curline.find(":")+2);
630  serialNumber = curline;
631  }
632  }
633  for (TQStringList::Iterator cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
634  curline = *cpuit;
635  if (curline.startsWith("processor")) {
636  curline.remove(0, curline.find(":")+2);
637  processorNumber = curline.toInt();
638  if (!cdevice) {
639  cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
640  if (cdevice) {
641  // Set up CPU information structures
642  if (cdevice->coreNumber() != processorNumber) modified = true;
643  cdevice->internalSetCoreNumber(processorNumber);
644  if (cdevice->name() != modelName) modified = true;
645  cdevice->internalSetName(modelName);
646  if (cdevice->vendorName() != vendorName) modified = true;
647  cdevice->internalSetVendorName(vendorName);
648  if (cdevice->vendorEncoded() != vendorName) modified = true;
649  cdevice->internalSetVendorEncoded(vendorName);
650  if (cdevice->serialNumber() != serialNumber) modified = true;
651  cdevice->internalSetSerialNumber(serialNumber);
652  }
653  }
654  }
655  if (curline == NULL || curline == "") {
656  cdevice = 0;
657  }
658  }
659  }
660 
661  processorCount = processorNumber+1;
662 
663 #ifdef CPUPROFILING
664  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
665  printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
666  time1 = time2;
667 #endif
668 
669  TDECPUDevice* firstCPU = NULL;
670 
671  // Read in other information from cpufreq, if available
672  for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
673  cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
674  TQDir cpufreq_dir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber));
675  TQString scalinggovernor;
676  TQString scalingdriver;
677  double minfrequency = -1;
678  double maxfrequency = -1;
679  double trlatency = -1;
680  TQStringList affectedcpulist;
681  TQStringList frequencylist;
682  TQStringList governorlist;
683  if (cpufreq_dir.exists()) {
684  TQString nodename;
685  if ((processorNumber == 0) || (!firstCPU)) {
686  // Remember the first CPU options so that we can reuse it later.
687  firstCPU = cdevice;
688 
689  nodename = cpufreq_dir.path();
690  nodename.append("/scaling_governor");
691  TQFile scalinggovernorfile(nodename);
692  if (scalinggovernorfile.open(IO_ReadOnly)) {
693  TQTextStream stream( &scalinggovernorfile );
694  scalinggovernor = stream.readLine();
695  scalinggovernorfile.close();
696  }
697  nodename = cpufreq_dir.path();
698  nodename.append("/scaling_driver");
699  TQFile scalingdriverfile(nodename);
700  if (scalingdriverfile.open(IO_ReadOnly)) {
701  TQTextStream stream( &scalingdriverfile );
702  scalingdriver = stream.readLine();
703  scalingdriverfile.close();
704  }
705  nodename = cpufreq_dir.path();
706  nodename.append("/cpuinfo_min_freq");
707  TQFile minfrequencyfile(nodename);
708  if (minfrequencyfile.open(IO_ReadOnly)) {
709  TQTextStream stream( &minfrequencyfile );
710  minfrequency = stream.readLine().toDouble()/1000.0;
711  minfrequencyfile.close();
712  }
713  nodename = cpufreq_dir.path();
714  nodename.append("/cpuinfo_max_freq");
715  TQFile maxfrequencyfile(nodename);
716  if (maxfrequencyfile.open(IO_ReadOnly)) {
717  TQTextStream stream( &maxfrequencyfile );
718  maxfrequency = stream.readLine().toDouble()/1000.0;
719  maxfrequencyfile.close();
720  }
721  nodename = cpufreq_dir.path();
722  nodename.append("/cpuinfo_transition_latency");
723  TQFile trlatencyfile(nodename);
724  if (trlatencyfile.open(IO_ReadOnly)) {
725  TQTextStream stream( &trlatencyfile );
726  trlatency = stream.readLine().toDouble()/1000.0;
727  trlatencyfile.close();
728  }
729  nodename = cpufreq_dir.path();
730  nodename.append("/scaling_available_frequencies");
731  TQFile availfreqsfile(nodename);
732  if (availfreqsfile.open(IO_ReadOnly)) {
733  TQTextStream stream( &availfreqsfile );
734  frequencylist = TQStringList::split(" ", stream.readLine());
735  availfreqsfile.close();
736  }
737  nodename = cpufreq_dir.path();
738  nodename.append("/scaling_available_governors");
739  TQFile availgvrnsfile(nodename);
740  if (availgvrnsfile.open(IO_ReadOnly)) {
741  TQTextStream stream( &availgvrnsfile );
742  governorlist = TQStringList::split(" ", stream.readLine());
743  availgvrnsfile.close();
744  }
745  }
746  // Other CPU should have the same values as the first one. Simply copy them.
747  else {
748  scalinggovernor = firstCPU->governor();
749  scalingdriver = firstCPU->scalingDriver();
750  minfrequency = firstCPU->minFrequency();
751  maxfrequency = firstCPU->maxFrequency();
752  trlatency = firstCPU->transitionLatency();
753  frequencylist = firstCPU->availableFrequencies();
754  governorlist = firstCPU->availableGovernors();
755  }
756 
757  // The following data are different on each CPU
758  nodename = cpufreq_dir.path();
759  nodename.append("/affected_cpus");
760  TQFile tiedcpusfile(nodename);
761  if (tiedcpusfile.open(IO_ReadOnly)) {
762  TQTextStream stream( &tiedcpusfile );
763  affectedcpulist = TQStringList::split(" ", stream.readLine());
764  tiedcpusfile.close();
765  }
766 
767  // We may already have the CPU Mhz information in '/proc/cpuinfo'
768  if (!have_frequency) {
769  nodename = cpufreq_dir.path();
770  nodename.append("/cpuinfo_cur_freq");
771  TQFile cpufreqfile(nodename);
772  if (cpufreqfile.open(IO_ReadOnly)) {
773  TQTextStream stream( &cpufreqfile );
774  if (cdevice) {
775  cdevice->internalSetFrequency(stream.readLine().toDouble()/1000.0);
776  }
777  cpufreqfile.close();
778  have_frequency = true;
779  }
780  }
781 
782  bool minfrequencyFound = false;
783  bool maxfrequencyFound = false;
784  TQStringList::Iterator freqit;
785  for ( freqit = frequencylist.begin(); freqit != frequencylist.end(); ++freqit ) {
786  double thisfrequency = (*freqit).toDouble()/1000.0;
787  if (thisfrequency == minfrequency) {
788  minfrequencyFound = true;
789  }
790  if (thisfrequency == maxfrequency) {
791  maxfrequencyFound = true;
792  }
793 
794  }
795  if (!minfrequencyFound) {
796  int minFrequencyInt = (minfrequency*1000.0);
797  frequencylist.prepend(TQString("%1").arg(minFrequencyInt));
798  }
799  if (!maxfrequencyFound) {
800  int maxfrequencyInt = (maxfrequency*1000.0);
801  frequencylist.append(TQString("%1").arg(maxfrequencyInt));
802  }
803 
804 #ifdef CPUPROFILING
805  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
806  printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3.%u at %u [%u]\n", processorNumber, time2.tv_nsec, diff(time1,time2).tv_nsec);
807  time1 = time2;
808 #endif
809  }
810  else {
811  if (have_frequency) {
812  if (cdevice) {
813  minfrequency = cdevice->frequency();
814  maxfrequency = cdevice->frequency();
815  }
816  }
817  }
818 
819  // Update CPU information structure
820  if (cdevice) {
821  if (cdevice->governor() != scalinggovernor) {
822  modified = true;
823  cdevice->internalSetGovernor(scalinggovernor);
824  }
825  if (cdevice->scalingDriver() != scalingdriver) {
826  modified = true;
827  cdevice->internalSetScalingDriver(scalingdriver);
828  }
829  if (cdevice->minFrequency() != minfrequency) {
830  modified = true;
831  cdevice->internalSetMinFrequency(minfrequency);
832  }
833  if (cdevice->maxFrequency() != maxfrequency) {
834  modified = true;
835  cdevice->internalSetMaxFrequency(maxfrequency);
836  }
837  if (cdevice->transitionLatency() != trlatency) {
838  modified = true;
839  cdevice->internalSetTransitionLatency(trlatency);
840  }
841  if (cdevice->dependentProcessors().join(" ") != affectedcpulist.join(" ")) {
842  modified = true;
843  cdevice->internalSetDependentProcessors(affectedcpulist);
844  }
845  if (cdevice->availableFrequencies().join(" ") != frequencylist.join(" ")) {
846  modified = true;
847  cdevice->internalSetAvailableFrequencies(frequencylist);
848  }
849  if (cdevice->availableGovernors().join(" ") != governorlist.join(" ")) {
850  modified = true;
851  cdevice->internalSetAvailableGovernors(governorlist);
852  }
853  }
854  }
855 
856 #ifdef CPUPROFILING
857  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
858  printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint4 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
859  time1 = time2;
860 #endif
861 
862  if (modified) {
863  for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
864  TDEGenericDevice* hwdevice = findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
865  if (hwdevice) {
866  // Signal new information available
867  emit hardwareUpdated(hwdevice);
868  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
869  }
870  }
871  }
872 
873 #ifdef CPUPROFILING
874  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
875  printf("TDEHardwareDevices::processModifiedCPUs() : end at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
876  printf("TDEHardwareDevices::processModifiedCPUs() : total time: %u\n", diff(time3,time2).tv_nsec);
877 #endif
878 }
879 
880 void TDEHardwareDevices::processStatelessDevices() {
881  // Some devices do not emit changed signals
882  // So far, network cards and sensors need to be polled
883  TDEGenericDevice *hwdevice;
884 
885 #ifdef STATELESSPROFILING
886  timespec time1, time2, time3;
887  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
888  printf("TDEHardwareDevices::processStatelessDevices() : begin at '%u'\n", time1.tv_nsec);
889  time3 = time1;
890 #endif
891 
892  // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
893  TDEGenericHardwareList devList = listAllPhysicalDevices();
894  for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
895  if ((hwdevice->type() == TDEGenericDeviceType::RootSystem) || (hwdevice->type() == TDEGenericDeviceType::Network) || (hwdevice->type() == TDEGenericDeviceType::OtherSensor) || (hwdevice->type() == TDEGenericDeviceType::Event) || (hwdevice->type() == TDEGenericDeviceType::Battery) || (hwdevice->type() == TDEGenericDeviceType::PowerSupply)) {
896  rescanDeviceInformation(hwdevice, false);
897  emit hardwareUpdated(hwdevice);
898  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
899 #ifdef STATELESSPROFILING
900  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
901  printf("TDEHardwareDevices::processStatelessDevices() : '%s' finished at %u [%u]\n", (hwdevice->name()).ascii(), time2.tv_nsec, diff(time1,time2).tv_nsec);
902  time1 = time2;
903 #endif
904  }
905  }
906 
907 #ifdef STATELESSPROFILING
908  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
909  printf("TDEHardwareDevices::processStatelessDevices() : end at '%u'\n", time2.tv_nsec);
910  printf("TDEHardwareDevices::processStatelessDevices() : took '%u'\n", diff(time3,time2).tv_nsec);
911 #endif
912 }
913 
914 void TDEHardwareDevices::processBatteryDevices() {
915  TDEGenericDevice *hwdevice;
916 
917  // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
918  TDEGenericHardwareList devList = listAllPhysicalDevices();
919  for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
920  if (hwdevice->type() == TDEGenericDeviceType::Battery) {
921  rescanDeviceInformation(hwdevice, false);
922  emit hardwareUpdated(hwdevice);
923  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
924  }
925  }
926 }
927 
928 
929 void TDEHardwareDevices::processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice) {
930  emit eventDeviceKeyPressed(keycode, edevice);
931 }
932 
933 void TDEHardwareDevices::processModifiedMounts() {
934  // Detect what changed between the old mount table and the new one,
935  // and emit appropriate events
936 
937  TQStringList deletedEntries = m_mountTable;
938 
939  // Read in the new mount table
940  m_mountTable.clear();
941  TQFile file( "/proc/mounts" );
942  if ( file.open( IO_ReadOnly ) ) {
943  TQTextStream stream( &file );
944  while ( !stream.atEnd() ) {
945  m_mountTable.append(stream.readLine());
946  }
947  file.close();
948  }
949 
950  TQStringList addedEntries = m_mountTable;
951 
952  // Remove all entries that are identical in both tables
953  processModifiedMounts_removeagain:
954  for ( TQStringList::Iterator delit = deletedEntries.begin(); delit != deletedEntries.end(); ++delit ) {
955  for ( TQStringList::Iterator addit = addedEntries.begin(); addit != addedEntries.end(); ++addit ) {
956  if ((*delit) == (*addit)) {
957  deletedEntries.remove(delit);
958  addedEntries.remove(addit);
959  // Reset iterators to prevent bugs/crashes
960  // FIXME
961  // Is there any way to completely reset both loops without using goto?
962  goto processModifiedMounts_removeagain;
963  }
964  }
965  }
966 
967  TQStringList::Iterator it;
968  for ( it = addedEntries.begin(); it != addedEntries.end(); ++it ) {
969  TQStringList mountInfo = TQStringList::split(" ", (*it), true);
970  // Try to find a device that matches the altered node
971  TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
972  if (hwdevice) {
973  emit hardwareUpdated(hwdevice);
974  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
975  // If the device is a storage device and has a slave, update it as well
976  if (hwdevice->type() == TDEGenericDeviceType::Disk) {
977  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
978  TQStringList slavedevices = sdevice->slaveDevices();
979  for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
980  TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
981  if (slavedevice) {
982  emit hardwareUpdated(slavedevice);
983  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
984  }
985  }
986  }
987  }
988  }
989  for ( it = deletedEntries.begin(); it != deletedEntries.end(); ++it ) {
990  TQStringList mountInfo = TQStringList::split(" ", (*it), true);
991  // Try to find a device that matches the altered node
992  TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
993  if (hwdevice) {
994  emit hardwareUpdated(hwdevice);
995  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
996  // If the device is a storage device and has a slave, update it as well
997  if (hwdevice->type() == TDEGenericDeviceType::Disk) {
998  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
999  TQStringList slavedevices = sdevice->slaveDevices();
1000  for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
1001  TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
1002  if (slavedevice) {
1003  emit hardwareUpdated(slavedevice);
1004  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
1005  }
1006  }
1007  }
1008  }
1009  }
1010 
1011  emit mountTableModified();
1012  emit hardwareEvent(TDEHardwareEvent::MountTableModified, TQString());
1013 }
1014 
1015 TDEDiskDeviceType::TDEDiskDeviceType classifyDiskType(udev_device* dev, const TQString devicenode, const TQString devicebus, const TQString disktypestring, const TQString systempath, const TQString devicevendor, const TQString devicemodel, const TQString filesystemtype, const TQString devicedriver) {
1016  // Classify a disk device type to the best of our ability
1017  TDEDiskDeviceType::TDEDiskDeviceType disktype = TDEDiskDeviceType::Null;
1018 
1019  if (devicebus.upper() == "USB") {
1020  disktype = disktype | TDEDiskDeviceType::USB;
1021  }
1022 
1023  if (disktypestring.upper() == "DISK") {
1024  disktype = disktype | TDEDiskDeviceType::HDD;
1025  }
1026 
1027  if ((disktypestring.upper() == "FLOPPY")
1028  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY")) == "1")) {
1029  disktype = disktype | TDEDiskDeviceType::Floppy;
1030  disktype = disktype & ~TDEDiskDeviceType::HDD;
1031  }
1032 
1033  if ((disktypestring.upper() == "ZIP")
1034  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY_ZIP")) == "1")
1035  || ((devicevendor.upper() == "IOMEGA") && (devicemodel.upper().contains("ZIP")))) {
1036  disktype = disktype | TDEDiskDeviceType::Zip;
1037  disktype = disktype & ~TDEDiskDeviceType::HDD;
1038  }
1039 
1040  if ((devicevendor.upper() == "APPLE") && (devicemodel.upper().contains("IPOD"))) {
1041  disktype = disktype | TDEDiskDeviceType::MediaDevice;
1042  }
1043  if ((devicevendor.upper() == "SANDISK") && (devicemodel.upper().contains("SANSA"))) {
1044  disktype = disktype | TDEDiskDeviceType::MediaDevice;
1045  }
1046 
1047  if (disktypestring.upper() == "TAPE") {
1048  disktype = disktype | TDEDiskDeviceType::Tape;
1049  }
1050 
1051  if ((disktypestring.upper() == "COMPACT_FLASH")
1052  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_CF")) == "1")
1053  || (TQString(udev_device_get_property_value(dev, "ID_ATA_CFA")) == "1")) {
1054  disktype = disktype | TDEDiskDeviceType::CompactFlash;
1055  disktype = disktype | TDEDiskDeviceType::HDD;
1056  }
1057 
1058  if ((disktypestring.upper() == "MEMORY_STICK")
1059  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MS")) == "1")) {
1060  disktype = disktype | TDEDiskDeviceType::MemoryStick;
1061  disktype = disktype | TDEDiskDeviceType::HDD;
1062  }
1063 
1064  if ((disktypestring.upper() == "SMART_MEDIA")
1065  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SM")) == "1")) {
1066  disktype = disktype | TDEDiskDeviceType::SmartMedia;
1067  disktype = disktype | TDEDiskDeviceType::HDD;
1068  }
1069 
1070  if ((disktypestring.upper() == "SD_MMC")
1071  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SD")) == "1")
1072  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SDHC")) == "1")
1073  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MMC")) == "1")) {
1074  disktype = disktype | TDEDiskDeviceType::SDMMC;
1075  disktype = disktype | TDEDiskDeviceType::HDD;
1076  }
1077 
1078  if ((disktypestring.upper() == "FLASHKEY")
1079  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH")) == "1")) {
1080  disktype = disktype | TDEDiskDeviceType::Flash;
1081  disktype = disktype | TDEDiskDeviceType::HDD;
1082  }
1083 
1084  if (disktypestring.upper() == "OPTICAL") {
1085  disktype = disktype | TDEDiskDeviceType::Optical;
1086  }
1087 
1088  if (disktypestring.upper() == "JAZ") {
1089  disktype = disktype | TDEDiskDeviceType::Jaz;
1090  }
1091 
1092  if (disktypestring.upper() == "CD") {
1093  disktype = disktype | TDEDiskDeviceType::Optical;
1094 
1095  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) == "1") {
1096  disktype = disktype | TDEDiskDeviceType::CDROM;
1097  }
1098  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_R")) == "1") {
1099  disktype = disktype | TDEDiskDeviceType::CDR;
1100  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1101  }
1102  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_RW")) == "1") {
1103  disktype = disktype | TDEDiskDeviceType::CDRW;
1104  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1105  disktype = disktype & ~TDEDiskDeviceType::CDR;
1106  }
1107  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW")) == "1") {
1108  disktype = disktype | TDEDiskDeviceType::CDMRRW;
1109  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1110  disktype = disktype & ~TDEDiskDeviceType::CDR;
1111  disktype = disktype & ~TDEDiskDeviceType::CDRW;
1112  }
1113  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW_W")) == "1") {
1114  disktype = disktype | TDEDiskDeviceType::CDMRRWW;
1115  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1116  disktype = disktype & ~TDEDiskDeviceType::CDR;
1117  disktype = disktype & ~TDEDiskDeviceType::CDRW;
1118  disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
1119  }
1120  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MO")) == "1") {
1121  disktype = disktype | TDEDiskDeviceType::CDMO;
1122  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1123  disktype = disktype & ~TDEDiskDeviceType::CDR;
1124  disktype = disktype & ~TDEDiskDeviceType::CDRW;
1125  disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
1126  disktype = disktype & ~TDEDiskDeviceType::CDMRRWW;
1127  }
1128  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD")) == "1") {
1129  disktype = disktype | TDEDiskDeviceType::DVDROM;
1130  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1131  }
1132  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RAM")) == "1") {
1133  disktype = disktype | TDEDiskDeviceType::DVDRAM;
1134  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1135  }
1136  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R")) == "1") {
1137  disktype = disktype | TDEDiskDeviceType::DVDR;
1138  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1139  }
1140  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R_DL")) == "1") {
1141  disktype = disktype | TDEDiskDeviceType::DVDRDL;
1142  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1143  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1144  }
1145  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R")) == "1") {
1146  disktype = disktype | TDEDiskDeviceType::DVDPLUSR;
1147  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1148  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1149  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1150  }
1151  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R_DL")) == "1") {
1152  disktype = disktype | TDEDiskDeviceType::DVDPLUSRDL;
1153  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1154  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1155  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1156  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1157  }
1158  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW")) == "1") {
1159  disktype = disktype | TDEDiskDeviceType::DVDRW;
1160  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1161  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1162  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1163  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1164  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1165  }
1166  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW_DL")) == "1") {
1167  disktype = disktype | TDEDiskDeviceType::DVDRWDL;
1168  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1169  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1170  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1171  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1172  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1173  disktype = disktype & ~TDEDiskDeviceType::DVDRW;
1174  }
1175  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW")) == "1") {
1176  disktype = disktype | TDEDiskDeviceType::DVDPLUSRW;
1177  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1178  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1179  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1180  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1181  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1182  disktype = disktype & ~TDEDiskDeviceType::DVDRW;
1183  disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
1184  }
1185  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW_DL")) == "1") {
1186  disktype = disktype | TDEDiskDeviceType::DVDPLUSRWDL;
1187  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1188  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1189  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1190  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1191  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1192  disktype = disktype & ~TDEDiskDeviceType::DVDRW;
1193  disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
1194  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRW;
1195  }
1196  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD")) == "1") {
1197  disktype = disktype | TDEDiskDeviceType::BDROM;
1198  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1199  }
1200  if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_R")) == "1")
1201  || (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_R_DL")) == "1") // FIXME There is no official udev attribute for this type of disc (yet!)
1202  ) {
1203  disktype = disktype | TDEDiskDeviceType::BDR;
1204  disktype = disktype & ~TDEDiskDeviceType::BDROM;
1205  }
1206  if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_RE")) == "1")
1207  || (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_RE_DL")) == "1") // FIXME There is no official udev attribute for this type of disc (yet!)
1208  ) {
1209  disktype = disktype | TDEDiskDeviceType::BDRW;
1210  disktype = disktype & ~TDEDiskDeviceType::BDROM;
1211  disktype = disktype & ~TDEDiskDeviceType::BDR;
1212  }
1213  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD")) == "1") {
1214  disktype = disktype | TDEDiskDeviceType::HDDVDROM;
1215  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1216  }
1217  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_R")) == "1") {
1218  disktype = disktype | TDEDiskDeviceType::HDDVDR;
1219  disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
1220  }
1221  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_RW")) == "1") {
1222  disktype = disktype | TDEDiskDeviceType::HDDVDRW;
1223  disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
1224  disktype = disktype & ~TDEDiskDeviceType::HDDVDR;
1225  }
1226  if (!TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO")).isNull()) {
1227  disktype = disktype | TDEDiskDeviceType::CDAudio;
1228  }
1229  if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_VCD")) == "1") || (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_SDVD")) == "1")) {
1230  disktype = disktype | TDEDiskDeviceType::CDVideo;
1231  }
1232 
1233  if ((disktype & TDEDiskDeviceType::DVDROM)
1234  || (disktype & TDEDiskDeviceType::DVDRAM)
1235  || (disktype & TDEDiskDeviceType::DVDR)
1236  || (disktype & TDEDiskDeviceType::DVDRW)
1237  || (disktype & TDEDiskDeviceType::DVDRDL)
1238  || (disktype & TDEDiskDeviceType::DVDRWDL)
1239  || (disktype & TDEDiskDeviceType::DVDPLUSR)
1240  || (disktype & TDEDiskDeviceType::DVDPLUSRW)
1241  || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
1242  || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
1243  ) {
1244  // Every VideoDVD must have a VIDEO_TS.IFO file
1245  // Read this info via tdeiso_info, since udev couldn't be bothered to check DVD type on its own
1246  int retcode = system(TQString("tdeiso_info --exists=ISO9660/VIDEO_TS/VIDEO_TS.IFO %1").arg(devicenode).ascii());
1247  if (retcode == 0) {
1248  disktype = disktype | TDEDiskDeviceType::DVDVideo;
1249  }
1250  }
1251 
1252  }
1253 
1254  // Detect RAM and Loop devices, since udev can't seem to...
1255  if (systempath.startsWith("/sys/devices/virtual/block/ram")) {
1256  disktype = disktype | TDEDiskDeviceType::RAM;
1257  }
1258  if (systempath.startsWith("/sys/devices/virtual/block/loop")) {
1259  disktype = disktype | TDEDiskDeviceType::Loop;
1260  }
1261 
1262  if (disktype == TDEDiskDeviceType::Null) {
1263  // Fallback
1264  // If we can't recognize the disk type then set it as a simple HDD volume
1265  disktype = disktype | TDEDiskDeviceType::HDD;
1266  }
1267 
1268  if (filesystemtype.upper() == "CRYPTO_LUKS") {
1269  disktype = disktype | TDEDiskDeviceType::LUKS;
1270  }
1271  else if (filesystemtype.upper() == "CRYPTO") {
1272  disktype = disktype | TDEDiskDeviceType::OtherCrypted;
1273  }
1274 
1275  return disktype;
1276 }
1277 
1278  // TDEStandardDirs::kde_default
1279 
1280 typedef TQMap<TQString, TQString> TDEConfigMap;
1281 
1282 TQString readUdevAttribute(udev_device* dev, TQString attr) {
1283  return TQString(udev_device_get_property_value(dev, attr.ascii()));
1284 }
1285 
1286 TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQString query) {
1287  TDEGenericDeviceType::TDEGenericDeviceType ret = TDEGenericDeviceType::Other;
1288 
1289  // Keep this in sync with the TDEGenericDeviceType definition in the header
1290  if (query == "Root") {
1291  ret = TDEGenericDeviceType::Root;
1292  }
1293  else if (query == "RootSystem") {
1294  ret = TDEGenericDeviceType::RootSystem;
1295  }
1296  else if (query == "CPU") {
1297  ret = TDEGenericDeviceType::CPU;
1298  }
1299  else if (query == "GPU") {
1300  ret = TDEGenericDeviceType::GPU;
1301  }
1302  else if (query == "RAM") {
1303  ret = TDEGenericDeviceType::RAM;
1304  }
1305  else if (query == "Bus") {
1306  ret = TDEGenericDeviceType::Bus;
1307  }
1308  else if (query == "I2C") {
1309  ret = TDEGenericDeviceType::I2C;
1310  }
1311  else if (query == "MDIO") {
1312  ret = TDEGenericDeviceType::MDIO;
1313  }
1314  else if (query == "Mainboard") {
1315  ret = TDEGenericDeviceType::Mainboard;
1316  }
1317  else if (query == "Disk") {
1318  ret = TDEGenericDeviceType::Disk;
1319  }
1320  else if (query == "SCSI") {
1321  ret = TDEGenericDeviceType::SCSI;
1322  }
1323  else if (query == "StorageController") {
1324  ret = TDEGenericDeviceType::StorageController;
1325  }
1326  else if (query == "Mouse") {
1327  ret = TDEGenericDeviceType::Mouse;
1328  }
1329  else if (query == "Keyboard") {
1330  ret = TDEGenericDeviceType::Keyboard;
1331  }
1332  else if (query == "HID") {
1333  ret = TDEGenericDeviceType::HID;
1334  }
1335  else if (query == "Modem") {
1336  ret = TDEGenericDeviceType::Modem;
1337  }
1338  else if (query == "Monitor") {
1339  ret = TDEGenericDeviceType::Monitor;
1340  }
1341  else if (query == "Network") {
1342  ret = TDEGenericDeviceType::Network;
1343  }
1344  else if (query == "Printer") {
1345  ret = TDEGenericDeviceType::Printer;
1346  }
1347  else if (query == "Scanner") {
1348  ret = TDEGenericDeviceType::Scanner;
1349  }
1350  else if (query == "Sound") {
1351  ret = TDEGenericDeviceType::Sound;
1352  }
1353  else if (query == "VideoCapture") {
1354  ret = TDEGenericDeviceType::VideoCapture;
1355  }
1356  else if (query == "IEEE1394") {
1357  ret = TDEGenericDeviceType::IEEE1394;
1358  }
1359  else if (query == "PCMCIA") {
1360  ret = TDEGenericDeviceType::PCMCIA;
1361  }
1362  else if (query == "Camera") {
1363  ret = TDEGenericDeviceType::Camera;
1364  }
1365  else if (query == "Serial") {
1366  ret = TDEGenericDeviceType::Serial;
1367  }
1368  else if (query == "Parallel") {
1369  ret = TDEGenericDeviceType::Parallel;
1370  }
1371  else if (query == "TextIO") {
1372  ret = TDEGenericDeviceType::TextIO;
1373  }
1374  else if (query == "Peripheral") {
1375  ret = TDEGenericDeviceType::Peripheral;
1376  }
1377  else if (query == "Backlight") {
1378  ret = TDEGenericDeviceType::Backlight;
1379  }
1380  else if (query == "Battery") {
1381  ret = TDEGenericDeviceType::Battery;
1382  }
1383  else if (query == "Power") {
1384  ret = TDEGenericDeviceType::PowerSupply;
1385  }
1386  else if (query == "Dock") {
1387  ret = TDEGenericDeviceType::Dock;
1388  }
1389  else if (query == "ThermalSensor") {
1390  ret = TDEGenericDeviceType::ThermalSensor;
1391  }
1392  else if (query == "ThermalControl") {
1393  ret = TDEGenericDeviceType::ThermalControl;
1394  }
1395  else if (query == "Bluetooth") {
1396  ret = TDEGenericDeviceType::BlueTooth;
1397  }
1398  else if (query == "Bridge") {
1399  ret = TDEGenericDeviceType::Bridge;
1400  }
1401  else if (query == "Platform") {
1402  ret = TDEGenericDeviceType::Platform;
1403  }
1404  else if (query == "Cryptography") {
1405  ret = TDEGenericDeviceType::Cryptography;
1406  }
1407  else if (query == "Event") {
1408  ret = TDEGenericDeviceType::Event;
1409  }
1410  else if (query == "Input") {
1411  ret = TDEGenericDeviceType::Input;
1412  }
1413  else if (query == "PNP") {
1414  ret = TDEGenericDeviceType::PNP;
1415  }
1416  else if (query == "OtherACPI") {
1417  ret = TDEGenericDeviceType::OtherACPI;
1418  }
1419  else if (query == "OtherUSB") {
1420  ret = TDEGenericDeviceType::OtherUSB;
1421  }
1422  else if (query == "OtherMultimedia") {
1423  ret = TDEGenericDeviceType::OtherMultimedia;
1424  }
1425  else if (query == "OtherPeripheral") {
1426  ret = TDEGenericDeviceType::OtherPeripheral;
1427  }
1428  else if (query == "OtherSensor") {
1429  ret = TDEGenericDeviceType::OtherSensor;
1430  }
1431  else if (query == "OtherVirtual") {
1432  ret = TDEGenericDeviceType::OtherVirtual;
1433  }
1434  else {
1435  ret = TDEGenericDeviceType::Other;
1436  }
1437 
1438  return ret;
1439 }
1440 
1441 TDEDiskDeviceType::TDEDiskDeviceType readDiskDeviceSubtypeFromString(TQString query, TDEDiskDeviceType::TDEDiskDeviceType flagsIn=TDEDiskDeviceType::Null) {
1442  TDEDiskDeviceType::TDEDiskDeviceType ret = flagsIn;
1443 
1444  // Keep this in sync with the TDEDiskDeviceType definition in the header
1445  if (query == "MediaDevice") {
1446  ret = ret | TDEDiskDeviceType::MediaDevice;
1447  }
1448  if (query == "Floppy") {
1449  ret = ret | TDEDiskDeviceType::Floppy;
1450  }
1451  if (query == "CDROM") {
1452  ret = ret | TDEDiskDeviceType::CDROM;
1453  }
1454  if (query == "CDR") {
1455  ret = ret | TDEDiskDeviceType::CDR;
1456  }
1457  if (query == "CDRW") {
1458  ret = ret | TDEDiskDeviceType::CDRW;
1459  }
1460  if (query == "CDMO") {
1461  ret = ret | TDEDiskDeviceType::CDMO;
1462  }
1463  if (query == "CDMRRW") {
1464  ret = ret | TDEDiskDeviceType::CDMRRW;
1465  }
1466  if (query == "CDMRRWW") {
1467  ret = ret | TDEDiskDeviceType::CDMRRWW;
1468  }
1469  if (query == "DVDROM") {
1470  ret = ret | TDEDiskDeviceType::DVDROM;
1471  }
1472  if (query == "DVDRAM") {
1473  ret = ret | TDEDiskDeviceType::DVDRAM;
1474  }
1475  if (query == "DVDR") {
1476  ret = ret | TDEDiskDeviceType::DVDR;
1477  }
1478  if (query == "DVDRW") {
1479  ret = ret | TDEDiskDeviceType::DVDRW;
1480  }
1481  if (query == "DVDRDL") {
1482  ret = ret | TDEDiskDeviceType::DVDRDL;
1483  }
1484  if (query == "DVDRWDL") {
1485  ret = ret | TDEDiskDeviceType::DVDRWDL;
1486  }
1487  if (query == "DVDPLUSR") {
1488  ret = ret | TDEDiskDeviceType::DVDPLUSR;
1489  }
1490  if (query == "DVDPLUSRW") {
1491  ret = ret | TDEDiskDeviceType::DVDPLUSRW;
1492  }
1493  if (query == "DVDPLUSRDL") {
1494  ret = ret | TDEDiskDeviceType::DVDPLUSRDL;
1495  }
1496  if (query == "DVDPLUSRWDL") {
1497  ret = ret | TDEDiskDeviceType::DVDPLUSRWDL;
1498  }
1499  if (query == "BDROM") {
1500  ret = ret | TDEDiskDeviceType::BDROM;
1501  }
1502  if (query == "BDR") {
1503  ret = ret | TDEDiskDeviceType::BDR;
1504  }
1505  if (query == "BDRW") {
1506  ret = ret | TDEDiskDeviceType::BDRW;
1507  }
1508  if (query == "HDDVDROM") {
1509  ret = ret | TDEDiskDeviceType::HDDVDROM;
1510  }
1511  if (query == "HDDVDR") {
1512  ret = ret | TDEDiskDeviceType::HDDVDR;
1513  }
1514  if (query == "HDDVDRW") {
1515  ret = ret | TDEDiskDeviceType::HDDVDRW;
1516  }
1517  if (query == "Zip") {
1518  ret = ret | TDEDiskDeviceType::Zip;
1519  }
1520  if (query == "Jaz") {
1521  ret = ret | TDEDiskDeviceType::Jaz;
1522  }
1523  if (query == "Camera") {
1524  ret = ret | TDEDiskDeviceType::Camera;
1525  }
1526  if (query == "LUKS") {
1527  ret = ret | TDEDiskDeviceType::LUKS;
1528  }
1529  if (query == "OtherCrypted") {
1530  ret = ret | TDEDiskDeviceType::OtherCrypted;
1531  }
1532  if (query == "CDAudio") {
1533  ret = ret | TDEDiskDeviceType::CDAudio;
1534  }
1535  if (query == "CDVideo") {
1536  ret = ret | TDEDiskDeviceType::CDVideo;
1537  }
1538  if (query == "DVDVideo") {
1539  ret = ret | TDEDiskDeviceType::DVDVideo;
1540  }
1541  if (query == "BDVideo") {
1542  ret = ret | TDEDiskDeviceType::BDVideo;
1543  }
1544  if (query == "Flash") {
1545  ret = ret | TDEDiskDeviceType::Flash;
1546  }
1547  if (query == "USB") {
1548  ret = ret | TDEDiskDeviceType::USB;
1549  }
1550  if (query == "Tape") {
1551  ret = ret | TDEDiskDeviceType::Tape;
1552  }
1553  if (query == "HDD") {
1554  ret = ret | TDEDiskDeviceType::HDD;
1555  }
1556  if (query == "Optical") {
1557  ret = ret | TDEDiskDeviceType::Optical;
1558  }
1559  if (query == "RAM") {
1560  ret = ret | TDEDiskDeviceType::RAM;
1561  }
1562  if (query == "Loop") {
1563  ret = ret | TDEDiskDeviceType::Loop;
1564  }
1565  if (query == "CompactFlash") {
1566  ret = ret | TDEDiskDeviceType::CompactFlash;
1567  }
1568  if (query == "MemoryStick") {
1569  ret = ret | TDEDiskDeviceType::MemoryStick;
1570  }
1571  if (query == "SmartMedia") {
1572  ret = ret | TDEDiskDeviceType::SmartMedia;
1573  }
1574  if (query == "SDMMC") {
1575  ret = ret | TDEDiskDeviceType::SDMMC;
1576  }
1577  if (query == "UnlockedCrypt") {
1578  ret = ret | TDEDiskDeviceType::UnlockedCrypt;
1579  }
1580 
1581  return ret;
1582 }
1583 
1584 TDEGenericDevice* createDeviceObjectForType(TDEGenericDeviceType::TDEGenericDeviceType type) {
1585  TDEGenericDevice* ret = 0;
1586 
1587  if (type == TDEGenericDeviceType::Disk) {
1588  ret = new TDEStorageDevice(type);
1589  }
1590  else {
1591  ret = new TDEGenericDevice(type);
1592  }
1593 
1594  return ret;
1595 }
1596 
1597 TDEGenericDevice* TDEHardwareDevices::classifyUnknownDeviceByExternalRules(udev_device* dev, TDEGenericDevice* existingdevice, bool classifySubDevices) {
1598  // This routine expects to see the hardware config files into <prefix>/share/apps/tdehwlib/deviceclasses/, suffixed with "hwclass"
1599  TDEGenericDevice* device = existingdevice;
1600  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
1601 
1602  // Handle subtype if needed/desired
1603  // To speed things up we rely on the prior scan results stored in m_externalSubtype
1604  if (classifySubDevices) {
1605  if (!device->m_externalRulesFile.isNull()) {
1606  if (device->type() == TDEGenericDeviceType::Disk) {
1607  // Disk class
1608  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
1609  TQStringList subtype = device->m_externalSubtype;
1610  TDEDiskDeviceType::TDEDiskDeviceType desiredSubdeviceType = TDEDiskDeviceType::Null;
1611  if (subtype.count()>0) {
1612  for ( TQStringList::Iterator paramit = subtype.begin(); paramit != subtype.end(); ++paramit ) {
1613  desiredSubdeviceType = readDiskDeviceSubtypeFromString(*paramit, desiredSubdeviceType);
1614  }
1615  if (desiredSubdeviceType != sdevice->diskType()) {
1616  printf("[tdehardwaredevices] Rules file %s used to set device subtype for device at path %s\n", device->m_externalRulesFile.ascii(), device->systemPath().ascii()); fflush(stdout);
1617  sdevice->internalSetDiskType(desiredSubdeviceType);
1618  }
1619  }
1620  }
1621  }
1622  }
1623  else {
1624  TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
1625  TQString hardware_info_directory_suffix("tdehwlib/deviceclasses/");
1626  TQString hardware_info_directory;
1627 
1628  // Scan the hardware_info_directory for configuration files
1629  // For each one, open it with TDEConfig() and apply its rules to classify the device
1630  // FIXME
1631  // Should this also scan up to <n> subdirectories for the files? That feature might end up being too expensive...
1632 
1633  device->m_externalRulesFile = TQString::null;
1634  for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
1635  hardware_info_directory = (*it);
1636  hardware_info_directory += hardware_info_directory_suffix;
1637 
1638  if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
1639  TQDir d(hardware_info_directory);
1640  d.setFilter( TQDir::Files | TQDir::Hidden );
1641 
1642  const TQFileInfoList *list = d.entryInfoList();
1643  TQFileInfoListIterator it( *list );
1644  TQFileInfo *fi;
1645 
1646  while ((fi = it.current()) != 0) {
1647  if (fi->extension(false) == "hwclass") {
1648  bool match = true;
1649 
1650  // Open the rules file
1651  TDEConfig rulesFile(fi->absFilePath(), true, false);
1652  rulesFile.setGroup("Conditions");
1653  TDEConfigMap conditionmap = rulesFile.entryMap("Conditions");
1654  TDEConfigMap::Iterator cndit;
1655  for (cndit = conditionmap.begin(); cndit != conditionmap.end(); ++cndit) {
1656  TQStringList conditionList = TQStringList::split(',', cndit.data(), false);
1657  bool atleastonematch = false;
1658  bool allmatch = true;
1659  TQString matchtype = rulesFile.readEntry("MATCH_TYPE", "All");
1660  if (conditionList.count() < 1) {
1661  allmatch = false;
1662  }
1663  else {
1664  for ( TQStringList::Iterator paramit = conditionList.begin(); paramit != conditionList.end(); ++paramit ) {
1665  if ((*paramit) == "MatchType") {
1666  continue;
1667  }
1668  if (cndit.key() == "VENDOR_ID") {
1669  if (device->vendorID() == (*paramit)) {
1670  atleastonematch = true;
1671  }
1672  else {
1673  allmatch = false;
1674  }
1675  }
1676  else if (cndit.key() == "MODEL_ID") {
1677  if (device->modelID() == (*paramit)) {
1678  atleastonematch = true;
1679  }
1680  else {
1681  allmatch = false;
1682  }
1683  }
1684  else if (cndit.key() == "DRIVER") {
1685  if (device->deviceDriver() == (*paramit)) {
1686  atleastonematch = true;
1687  }
1688  else {
1689  allmatch = false;
1690  }
1691  }
1692  else {
1693  if (readUdevAttribute(dev, cndit.key()) == (*paramit)) {
1694  atleastonematch = true;
1695  }
1696  else {
1697  allmatch = false;
1698  }
1699  }
1700  }
1701  }
1702  if (matchtype == "All") {
1703  if (!allmatch) {
1704  match = false;
1705  }
1706  }
1707  else if (matchtype == "Any") {
1708  if (!atleastonematch) {
1709  match = false;
1710  }
1711  }
1712  else {
1713  match = false;
1714  }
1715  }
1716 
1717  if (match) {
1718  rulesFile.setGroup("DeviceType");
1719  TQString gentype = rulesFile.readEntry("GENTYPE");
1720  TDEGenericDeviceType::TDEGenericDeviceType desiredDeviceType = device->type();
1721  if (!gentype.isNull()) {
1722  desiredDeviceType = readGenericDeviceTypeFromString(gentype);
1723  }
1724 
1725  // Handle main type
1726  if (desiredDeviceType != device->type()) {
1727  printf("[tdehardwaredevices] Rules file %s used to set device type for device at path %s\n", fi->absFilePath().ascii(), device->systemPath().ascii()); fflush(stdout);
1728  if (m_deviceList.contains(device)) {
1729  m_deviceList.remove(device);
1730  }
1731  else {
1732  delete device;
1733  }
1734  device = createDeviceObjectForType(desiredDeviceType);
1735  }
1736 
1737  // Parse subtype and store in m_externalSubtype for later
1738  // This speeds things up considerably due to the expense of the file scanning/parsing/matching operation
1739  device->m_externalSubtype = rulesFile.readListEntry("SUBTYPE", ',');
1740  device->m_externalRulesFile = fi->absFilePath();
1741 
1742  // Process blacklist entries
1743  rulesFile.setGroup("DeviceSettings");
1744  device->internalSetBlacklistedForUpdate(rulesFile.readBoolEntry("UPDATE_BLACKLISTED", device->blacklistedForUpdate()));
1745  }
1746  }
1747  ++it;
1748  }
1749  }
1750  }
1751  }
1752 
1753  return device;
1754 }
1755 
1756 TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice, bool force_full_classification) {
1757  // Classify device and create TDEHW device object
1758  TQString devicename;
1759  TQString devicetype;
1760  TQString devicedriver;
1761  TQString devicesubsystem;
1762  TQString devicenode;
1763  TQString systempath;
1764  TQString devicevendorid;
1765  TQString devicemodelid;
1766  TQString devicevendoridenc;
1767  TQString devicemodelidenc;
1768  TQString devicesubvendorid;
1769  TQString devicesubmodelid;
1770  TQString devicetypestring;
1771  TQString devicetypestring_alt;
1772  TQString devicepciclass;
1773  TDEGenericDevice* device = existingdevice;
1774  bool temp_udev_device = !dev;
1775  if (dev) {
1776  devicename = (udev_device_get_sysname(dev));
1777  devicetype = (udev_device_get_devtype(dev));
1778  devicedriver = (udev_device_get_driver(dev));
1779  devicesubsystem = (udev_device_get_subsystem(dev));
1780  devicenode = (udev_device_get_devnode(dev));
1781  systempath = (udev_device_get_syspath(dev));
1782  systempath += "/";
1783  devicevendorid = (udev_device_get_property_value(dev, "ID_VENDOR_ID"));
1784  devicemodelid = (udev_device_get_property_value(dev, "ID_MODEL_ID"));
1785  devicevendoridenc = (udev_device_get_property_value(dev, "ID_VENDOR_ENC"));
1786  devicemodelidenc = (udev_device_get_property_value(dev, "ID_MODEL_ENC"));
1787  devicesubvendorid = (udev_device_get_property_value(dev, "ID_SUBVENDOR_ID"));
1788  devicesubmodelid = (udev_device_get_property_value(dev, "ID_SUBMODEL_ID"));
1789  devicetypestring = (udev_device_get_property_value(dev, "ID_TYPE"));
1790  devicetypestring_alt = (udev_device_get_property_value(dev, "DEVTYPE"));
1791  devicepciclass = (udev_device_get_property_value(dev, "PCI_CLASS"));
1792  }
1793  else {
1794  if (device) {
1795  devicename = device->name();
1796  devicetype = device->m_udevtype;
1797  devicedriver = device->deviceDriver();
1798  devicesubsystem = device->subsystem();
1799  devicenode = device->deviceNode();
1800  systempath = device->systemPath();
1801  devicevendorid = device->vendorID();
1802  devicemodelid = device->modelID();
1803  devicevendoridenc = device->vendorEncoded();
1804  devicemodelidenc = device->modelEncoded();
1805  devicesubvendorid = device->subVendorID();
1806  devicesubmodelid = device->subModelID();
1807  devicetypestring = device->m_udevdevicetypestring;
1808  devicetypestring_alt = device->udevdevicetypestring_alt;
1809  devicepciclass = device->PCIClass();
1810  }
1811  TQString syspathudev = systempath;
1812  syspathudev.truncate(syspathudev.length()-1); // Remove trailing slash
1813  dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
1814  }
1815 
1816  // FIXME
1817  // Only a small subset of devices are classified right now
1818  // Figure out the remaining udev logic to classify the rest!
1819  // Helpful file: http://www.enlightenment.org/svn/e/trunk/PROTO/enna-explorer/src/bin/udev.c
1820 
1821  bool done = false;
1822  TQString current_path = systempath;
1823  TQString devicemodalias = TQString::null;
1824 
1825  while (done == false) {
1826  TQString malnodename = current_path;
1827  malnodename.append("/modalias");
1828  TQFile malfile(malnodename);
1829  if (malfile.open(IO_ReadOnly)) {
1830  TQTextStream stream( &malfile );
1831  devicemodalias = stream.readLine();
1832  malfile.close();
1833  }
1834  if (devicemodalias.startsWith("pci") || devicemodalias.startsWith("usb")) {
1835  done = true;
1836  }
1837  else {
1838  devicemodalias = TQString::null;
1839  current_path.truncate(current_path.findRev("/"));
1840  if (!current_path.startsWith("/sys/devices")) {
1841  // Abort!
1842  done = true;
1843  }
1844  }
1845  }
1846 
1847  // Many devices do not provide their vendor/model ID via udev
1848  // Worse, sometimes udev provides an invalid model ID!
1849  // Go after it manually if needed...
1850  if (devicevendorid.isNull() || devicemodelid.isNull() || devicemodelid.contains("/")) {
1851  if (devicemodalias != TQString::null) {
1852  // For added fun the device string lengths differ between pci and usb
1853  if (devicemodalias.startsWith("pci")) {
1854  int vloc = devicemodalias.find("v");
1855  int dloc = devicemodalias.find("d", vloc);
1856  int svloc = devicemodalias.find("sv");
1857  int sdloc = devicemodalias.find("sd", vloc);
1858 
1859  devicevendorid = devicemodalias.mid(vloc+1, 8).lower();
1860  devicemodelid = devicemodalias.mid(dloc+1, 8).lower();
1861  if (svloc != -1) {
1862  devicesubvendorid = devicemodalias.mid(svloc+1, 8).lower();
1863  devicesubmodelid = devicemodalias.mid(sdloc+1, 8).lower();
1864  }
1865  devicevendorid.remove(0,4);
1866  devicemodelid.remove(0,4);
1867  devicesubvendorid.remove(0,4);
1868  devicesubmodelid.remove(0,4);
1869  }
1870  if (devicemodalias.startsWith("usb")) {
1871  int vloc = devicemodalias.find("v");
1872  int dloc = devicemodalias.find("p", vloc);
1873  int svloc = devicemodalias.find("sv");
1874  int sdloc = devicemodalias.find("sp", vloc);
1875 
1876  devicevendorid = devicemodalias.mid(vloc+1, 4).lower();
1877  devicemodelid = devicemodalias.mid(dloc+1, 4).lower();
1878  if (svloc != -1) {
1879  devicesubvendorid = devicemodalias.mid(svloc+1, 4).lower();
1880  devicesubmodelid = devicemodalias.mid(sdloc+1, 4).lower();
1881  }
1882  }
1883  }
1884  }
1885 
1886  // Most of the time udev doesn't barf up a device driver either, so go after it manually...
1887  if (devicedriver.isNull()) {
1888  TQString driverSymlink = udev_device_get_syspath(dev);
1889  TQString driverSymlinkDir = driverSymlink;
1890  driverSymlink.append("/device/driver");
1891  driverSymlinkDir.append("/device/");
1892  TQFileInfo dirfi(driverSymlink);
1893  if (dirfi.isSymLink()) {
1894  char* collapsedPath = realpath((driverSymlinkDir + dirfi.readLink()).ascii(), NULL);
1895  devicedriver = TQString(collapsedPath);
1896  free(collapsedPath);
1897  devicedriver.remove(0, devicedriver.findRev("/")+1);
1898  }
1899  }
1900 
1901  // udev removes critical leading zeroes in the PCI device class, so go after it manually...
1902  TQString classnodename = systempath;
1903  classnodename.append("/class");
1904  TQFile classfile( classnodename );
1905  if ( classfile.open( IO_ReadOnly ) ) {
1906  TQTextStream stream( &classfile );
1907  devicepciclass = stream.readLine();
1908  devicepciclass.replace("0x", "");
1909  devicepciclass = devicepciclass.lower();
1910  classfile.close();
1911  }
1912 
1913  // Classify generic device type and create appropriate object
1914 
1915  // Pull out all event special devices and stuff them under Event
1916  TQString syspath_tail = systempath.lower();
1917  syspath_tail.truncate(syspath_tail.length()-1);
1918  syspath_tail.remove(0, syspath_tail.findRev("/")+1);
1919  if (syspath_tail.startsWith("event")) {
1920  if (!device) device = new TDEEventDevice(TDEGenericDeviceType::Event);
1921  }
1922  // Pull out all input special devices and stuff them under Input
1923  if (syspath_tail.startsWith("input")) {
1924  if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
1925  }
1926  // Pull out remote-control devices and stuff them under Input
1927  if (devicesubsystem == "rc") {
1928  if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
1929  }
1930 
1931  // Check for keyboard
1932  // Linux doesn't actually ID the keyboard device itself as such, it instead IDs the input device that is underneath the actual keyboard itseld
1933  // Therefore we need to scan <syspath>/input/input* for the ID_INPUT_KEYBOARD attribute
1934  bool is_keyboard = false;
1935  TQString inputtopdirname = udev_device_get_syspath(dev);
1936  inputtopdirname.append("/input/");
1937  TQDir inputdir(inputtopdirname);
1938  inputdir.setFilter(TQDir::All);
1939  const TQFileInfoList *dirlist = inputdir.entryInfoList();
1940  if (dirlist) {
1941  TQFileInfoListIterator inputdirsit(*dirlist);
1942  TQFileInfo *dirfi;
1943  while ( (dirfi = inputdirsit.current()) != 0 ) {
1944  if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
1945  struct udev_device *slavedev;
1946  slavedev = udev_device_new_from_syspath(m_udevStruct, (inputtopdirname + dirfi->fileName()).ascii());
1947  if (udev_device_get_property_value(slavedev, "ID_INPUT_KEYBOARD") != 0) {
1948  is_keyboard = true;
1949  }
1950  udev_device_unref(slavedev);
1951  }
1952  ++inputdirsit;
1953  }
1954  }
1955  if (is_keyboard) {
1956  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
1957  }
1958 
1959  // Classify specific known devices
1960  if (((devicetype == "disk")
1961  || (devicetype == "partition")
1962  || (devicedriver == "floppy")
1963  || (devicesubsystem == "scsi_disk")
1964  || (devicesubsystem == "scsi_tape"))
1965  && ((devicenode != "")
1966  )) {
1967  if (!device) device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
1968  }
1969  else if (devicetype == "host") {
1970  if (devicesubsystem == "bluetooth") {
1971  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BlueTooth);
1972  }
1973  }
1974  else if (devicetype.isNull()) {
1975  if (devicesubsystem == "acpi") {
1976  // If the ACPI device exposes a system path ending in /PNPxxxx:yy, the device type can be precisely determined
1977  // See ftp://ftp.microsoft.com/developr/drg/plug-and-play/devids.txt for more information
1978  TQString pnpgentype = systempath;
1979  pnpgentype.remove(0, pnpgentype.findRev("/")+1);
1980  pnpgentype.truncate(pnpgentype.find(":"));
1981  if (pnpgentype.startsWith("PNP")) {
1982  // If a device has been classified as belonging to the ACPI subsystem usually there is a "real" device related to it elsewhere in the system
1983  // Furthermore, the "real" device elsewhere almost always has more functionality exposed via sysfs
1984  // Therefore all ACPI subsystem devices should be stuffed in the OtherACPI category and largely ignored
1985  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
1986  }
1987  else {
1988  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
1989  }
1990  }
1991  else if (devicesubsystem == "input") {
1992  // Figure out if this device is a mouse, keyboard, or something else
1993  // Check for mouse
1994  // udev doesn't reliably help here, so guess from the device name
1995  if (systempath.contains("/mouse")) {
1996  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
1997  }
1998  if (!device) {
1999  // Second mouse check
2000  // Look for ID_INPUT_MOUSE property presence
2001  if (udev_device_get_property_value(dev, "ID_INPUT_MOUSE") != 0) {
2002  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
2003  }
2004  }
2005  if (!device) {
2006  // Check for keyboard
2007  // Look for ID_INPUT_KEYBOARD property presence
2008  if (udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD") != 0) {
2009  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
2010  }
2011  }
2012  if (!device) {
2013  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
2014  }
2015  }
2016  else if (devicesubsystem == "tty") {
2017  if (devicenode.contains("/ttyS")) {
2018  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2019  }
2020  else {
2021  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TextIO);
2022  }
2023  }
2024  else if (devicesubsystem == "usb-serial") {
2025  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2026  }
2027  else if ((devicesubsystem == "spi_master")
2028  || (devicesubsystem == "spidev")) {
2029  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2030  }
2031  else if (devicesubsystem == "spi") {
2032  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2033  }
2034  else if (devicesubsystem == "watchdog") {
2035  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2036  }
2037  else if (devicesubsystem == "node") {
2038  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2039  }
2040  else if (devicesubsystem == "regulator") {
2041  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2042  }
2043  else if (devicesubsystem == "memory") {
2044  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2045  }
2046  else if (devicesubsystem == "clockevents") {
2047  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2048  }
2049  else if (devicesubsystem == "thermal") {
2050  // FIXME
2051  // Figure out a way to differentiate between ThermalControl (fans and coolers) and ThermalSensor types
2052  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalControl);
2053  }
2054  else if (devicesubsystem == "hwmon") {
2055  // FIXME
2056  // This might pick up thermal sensors
2057  if (!device) device = new TDESensorDevice(TDEGenericDeviceType::OtherSensor);
2058  }
2059  else if (devicesubsystem == "virtio") {
2060  if (devicedriver == "virtio_blk") {
2061  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
2062  }
2063  if (devicedriver == "virtio_net") {
2064  if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
2065  }
2066  if (devicedriver == "virtio_balloon") {
2067  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
2068  }
2069  }
2070  }
2071 
2072  // Try to at least generally classify unclassified devices
2073  if (device == 0) {
2074  if (devicesubsystem == "backlight") {
2075  if (!device) device = new TDEBacklightDevice(TDEGenericDeviceType::Backlight);
2076  }
2077  if (systempath.lower().startsWith("/sys/module/")
2078  || (systempath.lower().startsWith("/sys/kernel/"))) {
2079  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform); // FIXME Should go into a new kernel module category when the tdelibs ABI can be broken again
2080  }
2081  if ((devicetypestring == "audio")
2082  || (devicesubsystem == "sound")
2083  || (devicesubsystem == "ac97")) {
2084  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Sound);
2085  }
2086  if ((devicesubsystem == "video4linux")
2087  || (devicesubsystem == "dvb")) {
2088  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::VideoCapture);
2089  }
2090  if ((devicetypestring_alt == "scsi_target")
2091  || (devicesubsystem == "scsi_host")
2092  || (devicesubsystem == "scsi_disk")
2093  || (devicesubsystem == "scsi_device")
2094  || (devicesubsystem == "scsi_generic")
2095  || (devicesubsystem == "scsi")
2096  || (devicetypestring_alt == "sas_target")
2097  || (devicesubsystem == "sas_host")
2098  || (devicesubsystem == "sas_port")
2099  || (devicesubsystem == "sas_device")
2100  || (devicesubsystem == "sas_expander")
2101  || (devicesubsystem == "sas_generic")
2102  || (devicesubsystem == "sas_phy")
2103  || (devicesubsystem == "sas_end_device")
2104  || (devicesubsystem == "spi_transport")
2105  || (devicesubsystem == "spi_host")
2106  || (devicesubsystem == "ata_port")
2107  || (devicesubsystem == "ata_link")
2108  || (devicesubsystem == "ata_disk")
2109  || (devicesubsystem == "ata_device")
2110  || (devicesubsystem == "ata")) {
2111  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2112  }
2113  if (devicesubsystem == "infiniband") {
2114  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Peripheral);
2115  }
2116  if ((devicesubsystem == "infiniband_cm")
2117  || (devicesubsystem == "infiniband_mad")
2118  || (devicesubsystem == "infiniband_verbs")) {
2119  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2120  }
2121  if (devicesubsystem == "infiniband_srp") {
2122  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
2123  }
2124  if ((devicesubsystem == "enclosure")
2125  || (devicesubsystem == "clocksource")
2126  || (devicesubsystem == "amba")) {
2127  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2128  }
2129  if ((devicesubsystem == "ipmi")
2130  || (devicesubsystem == "ipmi_si")) {
2131  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
2132  }
2133  if (devicesubsystem == "misc") {
2134  if (devicedriver.startsWith("tpm_")) {
2135  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Cryptography);
2136  }
2137  else {
2138  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2139  }
2140  }
2141  if (devicesubsystem == "leds") {
2142  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
2143  }
2144  if (devicesubsystem == "net") {
2145  if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
2146  }
2147  if ((devicesubsystem == "i2c")
2148  || (devicesubsystem == "i2c-dev")) {
2149  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::I2C);
2150  }
2151  if (devicesubsystem == "mdio_bus") {
2152  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::MDIO);
2153  }
2154  if (devicesubsystem == "graphics") {
2155  if (devicenode.isNull()) { // GPUs do not have associated device nodes
2156  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
2157  }
2158  else {
2159  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2160  }
2161  }
2162  if (devicesubsystem == "tifm_adapter") {
2163  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
2164  }
2165  if ((devicesubsystem == "mmc_host")
2166  || (devicesubsystem == "memstick_host")) {
2167  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
2168  }
2169  if (devicesubsystem == "mmc") {
2170  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2171  }
2172  if ((devicesubsystem == "event_source")
2173  || (devicesubsystem == "rtc")) {
2174  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
2175  }
2176  if (devicesubsystem == "bsg") {
2177  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
2178  }
2179  if (devicesubsystem == "firewire") {
2180  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::IEEE1394);
2181  }
2182  if (devicesubsystem == "drm") {
2183  if (devicenode.isNull()) { // Monitors do not have associated device nodes
2184  if (!device) device = new TDEMonitorDevice(TDEGenericDeviceType::Monitor);
2185  }
2186  else {
2187  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2188  }
2189  }
2190  if (devicesubsystem == "serio") {
2191  if (devicedriver.contains("atkbd")) {
2192  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
2193  }
2194  else if (devicedriver.contains("mouse")) {
2195  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
2196  }
2197  else {
2198  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2199  }
2200  }
2201  if ((devicesubsystem == "ppdev")
2202  || (devicesubsystem == "parport")) {
2203  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Parallel);
2204  }
2205  if (devicesubsystem == "printer") {
2206  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Printer);
2207  }
2208  if (devicesubsystem == "bridge") {
2209  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
2210  }
2211  if ((devicesubsystem == "pci_bus")
2212  || (devicesubsystem == "pci_express")) {
2213  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bus);
2214  }
2215  if (devicesubsystem == "pcmcia_socket") {
2216  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PCMCIA);
2217  }
2218  if (devicesubsystem == "platform") {
2219  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2220  }
2221  if (devicesubsystem == "ieee80211") {
2222  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2223  }
2224  if (devicesubsystem == "rfkill") {
2225  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2226  }
2227  if (devicesubsystem == "machinecheck") {
2228  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2229  }
2230  if (devicesubsystem == "pnp") {
2231  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PNP);
2232  }
2233  if ((devicesubsystem == "hid")
2234  || (devicesubsystem == "hidraw")
2235  || (devicesubsystem == "usbhid")) {
2236  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
2237  }
2238  if (devicesubsystem == "power_supply") {
2239  TQString powersupplyname(udev_device_get_property_value(dev, "POWER_SUPPLY_NAME"));
2240  if ((devicedriver == "ac")
2241  || (powersupplyname.upper().startsWith("AC"))) {
2242  if (!device) device = new TDEMainsPowerDevice(TDEGenericDeviceType::PowerSupply);
2243  }
2244  else {
2245  if (!device) device = new TDEBatteryDevice(TDEGenericDeviceType::Battery);
2246  }
2247  }
2248  if (systempath.lower().startsWith("/sys/devices/virtual")) {
2249  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherVirtual);
2250  }
2251 
2252  // Moderate accuracy classification, if PCI device class is available
2253  // See http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html for codes and meanings
2254  if (!devicepciclass.isNull()) {
2255  // Pre PCI 2.0
2256  if (devicepciclass.startsWith("0001")) {
2257  if (devicenode.isNull()) { // GPUs do not have associated device nodes
2258  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
2259  }
2260  else {
2261  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2262  }
2263  }
2264  // Post PCI 2.0
2265  TQString devicepcisubclass = devicepciclass;
2266  devicepcisubclass = devicepcisubclass.remove(0,2);
2267  if (devicepciclass.startsWith("01")) {
2268  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
2269  }
2270  if (devicepciclass.startsWith("02")) {
2271  if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
2272  }
2273  if (devicepciclass.startsWith("03")) {
2274  if (devicenode.isNull()) { // GPUs do not have associated device nodes
2275  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
2276  }
2277  else {
2278  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2279  }
2280  }
2281  if (devicepciclass.startsWith("04")) {
2282  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherMultimedia);
2283  }
2284  if (devicepciclass.startsWith("05")) {
2285  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
2286  }
2287  if (devicepciclass.startsWith("06")) {
2288  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
2289  }
2290  if (devicepciclass.startsWith("07")) {
2291  if (devicepcisubclass.startsWith("03")) {
2292  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Modem);
2293  }
2294  }
2295  if (devicepciclass.startsWith("0a")) {
2296  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Dock);
2297  }
2298  if (devicepciclass.startsWith("0b")) {
2299  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::CPU);
2300  }
2301  if (devicepciclass.startsWith("0c")) {
2302  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2303  }
2304  }
2305 
2306  if ((devicesubsystem == "usb")
2307  && (devicedriver == "uvcvideo")) {
2308  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2309  }
2310 
2311  // Last ditch attempt at classification
2312  // Likely inaccurate and sweeping
2313  if ((devicesubsystem == "usb")
2314  || (devicesubsystem == "usbmisc")
2315  || (devicesubsystem == "usb_device")
2316  || (devicesubsystem == "usbmon")) {
2317  // Get USB interface class for further classification
2318  int usbInterfaceClass = -1;
2319  {
2320  TQFile ifaceprotofile(current_path + "/bInterfaceClass");
2321  if (ifaceprotofile.open(IO_ReadOnly)) {
2322  TQTextStream stream( &ifaceprotofile );
2323  usbInterfaceClass = stream.readLine().toUInt();
2324  ifaceprotofile.close();
2325  }
2326  }
2327  // Get USB interface subclass for further classification
2328  int usbInterfaceSubClass = -1;
2329  {
2330  TQFile ifaceprotofile(current_path + "/bInterfaceSubClass");
2331  if (ifaceprotofile.open(IO_ReadOnly)) {
2332  TQTextStream stream( &ifaceprotofile );
2333  usbInterfaceSubClass = stream.readLine().toUInt();
2334  ifaceprotofile.close();
2335  }
2336  }
2337  // Get USB interface protocol for further classification
2338  int usbInterfaceProtocol = -1;
2339  {
2340  TQFile ifaceprotofile(current_path + "/bInterfaceProtocol");
2341  if (ifaceprotofile.open(IO_ReadOnly)) {
2342  TQTextStream stream( &ifaceprotofile );
2343  usbInterfaceProtocol = stream.readLine().toUInt();
2344  ifaceprotofile.close();
2345  }
2346  }
2347  if ((usbInterfaceClass == 6) && (usbInterfaceSubClass == 1) && (usbInterfaceProtocol == 1)) {
2348  // PictBridge
2349  if (!device) {
2350  device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
2351  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
2352  sdevice->internalSetDiskType(TDEDiskDeviceType::Camera);
2353  TQString parentsyspathudev = systempath;
2354  parentsyspathudev.truncate(parentsyspathudev.length()-1); // Remove trailing slash
2355  parentsyspathudev.truncate(parentsyspathudev.findRev("/"));
2356  struct udev_device *parentdev;
2357  parentdev = udev_device_new_from_syspath(m_udevStruct, parentsyspathudev.ascii());
2358  devicenode = (udev_device_get_devnode(parentdev));
2359  udev_device_unref(parentdev);
2360  }
2361  }
2362  else {
2363  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherUSB);
2364  }
2365  }
2366  if (devicesubsystem == "pci") {
2367  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherPeripheral);
2368  }
2369  if (devicesubsystem == "cpu") {
2370  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2371  }
2372  }
2373 
2374  if (device == 0) {
2375  // Unhandled
2376  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
2377  printf("[FIXME] UNCLASSIFIED DEVICE name: %s type: %s subsystem: %s driver: %s [Node Path: %s] [Syspath: %s] [%s:%s]\n", devicename.ascii(), devicetype.ascii(), devicesubsystem.ascii(), devicedriver.ascii(), devicenode.ascii(), udev_device_get_syspath(dev), devicevendorid.ascii(), devicemodelid.ascii()); fflush(stdout);
2378  }
2379 
2380  // Root devices are special
2381  if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
2382  systempath = device->systemPath();
2383  }
2384 
2385  // Set preliminary basic device information
2386  device->internalSetName(devicename);
2387  device->internalSetDeviceNode(devicenode);
2388  device->internalSetSystemPath(systempath);
2389  device->internalSetVendorID(devicevendorid);
2390  device->internalSetModelID(devicemodelid);
2391  device->internalSetVendorEncoded(devicevendoridenc);
2392  device->internalSetModelEncoded(devicemodelidenc);
2393  device->internalSetSubVendorID(devicesubvendorid);
2394  device->internalSetSubModelID(devicesubmodelid);
2395  device->internalSetModuleAlias(devicemodalias);
2396  device->internalSetDeviceDriver(devicedriver);
2397  device->internalSetSubsystem(devicesubsystem);
2398  device->internalSetPCIClass(devicepciclass);
2399 
2400  updateBlacklists(device, dev);
2401 
2402  if (force_full_classification) {
2403  // Check external rules for possible device type overrides
2404  device = classifyUnknownDeviceByExternalRules(dev, device, false);
2405  }
2406 
2407  // Internal use only!
2408  device->m_udevtype = devicetype;
2409  device->m_udevdevicetypestring = devicetypestring;
2410  device->udevdevicetypestring_alt = devicetypestring_alt;
2411 
2412  updateExistingDeviceInformation(device, dev);
2413 
2414  if (temp_udev_device) {
2415  udev_device_unref(dev);
2416  }
2417 
2418  return device;
2419 }
2420 
2421 void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* existingdevice, udev_device* dev) {
2422  TQString devicename;
2423  TQString devicetype;
2424  TQString devicedriver;
2425  TQString devicesubsystem;
2426  TQString devicenode;
2427  TQString systempath;
2428  TQString devicevendorid;
2429  TQString devicemodelid;
2430  TQString devicevendoridenc;
2431  TQString devicemodelidenc;
2432  TQString devicesubvendorid;
2433  TQString devicesubmodelid;
2434  TQString devicetypestring;
2435  TQString devicetypestring_alt;
2436  TQString devicepciclass;
2437  TDEGenericDevice* device = existingdevice;
2438  bool temp_udev_device = !dev;
2439 
2440  devicename = device->name();
2441  devicetype = device->m_udevtype;
2442  devicedriver = device->deviceDriver();
2443  devicesubsystem = device->subsystem();
2444  devicenode = device->deviceNode();
2445  systempath = device->systemPath();
2446  devicevendorid = device->vendorID();
2447  devicemodelid = device->modelID();
2448  devicevendoridenc = device->vendorEncoded();
2449  devicemodelidenc = device->modelEncoded();
2450  devicesubvendorid = device->subVendorID();
2451  devicesubmodelid = device->subModelID();
2452  devicetypestring = device->m_udevdevicetypestring;
2453  devicetypestring_alt = device->udevdevicetypestring_alt;
2454  devicepciclass = device->PCIClass();
2455 
2456  if (!dev) {
2457  TQString syspathudev = systempath;
2458  syspathudev.truncate(syspathudev.length()-1); // Remove trailing slash
2459  dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
2460  }
2461 
2462  if (device->type() == TDEGenericDeviceType::Disk) {
2463  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
2464  if (sdevice->diskType() & TDEDiskDeviceType::Camera) {
2465  // PictBridge cameras are special and should not be classified by standard rules
2466  sdevice->internalSetDiskStatus(TDEDiskDeviceStatus::Removable);
2467  sdevice->internalSetFileSystemName("pictbridge");
2468  }
2469  else {
2470  bool removable = false;
2471  bool hotpluggable = false;
2472 
2473  // We can get the removable flag, but we have no idea if the device has the ability to notify on media insertion/removal
2474  // If there is no such notification possible, then we should not set the removable flag
2475  // udev can be such an amazing pain at times
2476  // It exports a /capabilities node with no info on what the bits actually mean
2477  // This information is very poorly documented as a set of #defines in include/linux/genhd.h
2478  // We are specifically interested in GENHD_FL_REMOVABLE and GENHD_FL_MEDIA_CHANGE_NOTIFY
2479  // The "removable" flag should also really be renamed to "hotpluggable", as that is far more precise...
2480  TQString capabilitynodename = systempath;
2481  capabilitynodename.append("/capability");
2482  TQFile capabilityfile( capabilitynodename );
2483  unsigned int capabilities = 0;
2484  if ( capabilityfile.open( IO_ReadOnly ) ) {
2485  TQTextStream stream( &capabilityfile );
2486  TQString capabilitystring;
2487  capabilitystring = stream.readLine();
2488  capabilities = capabilitystring.toUInt();
2489  capabilityfile.close();
2490  }
2491  if (capabilities & GENHD_FL_REMOVABLE) {
2492  // FIXME
2493  // For added fun this is not always true; i.e. GENHD_FL_REMOVABLE can be set when the device cannot be hotplugged (floppy drives).
2494  hotpluggable = true;
2495  }
2496  if (capabilities & GENHD_FL_MEDIA_CHANGE_NOTIFY) {
2497  removable = true;
2498  }
2499 
2500  // See if any other devices are exclusively using this device, such as the Device Mapper
2501  TQStringList holdingDeviceNodes;
2502  TQString holdersnodename = udev_device_get_syspath(dev);
2503  holdersnodename.append("/holders/");
2504  TQDir holdersdir(holdersnodename);
2505  holdersdir.setFilter(TQDir::All);
2506  const TQFileInfoList *dirlist = holdersdir.entryInfoList();
2507  if (dirlist) {
2508  TQFileInfoListIterator holdersdirit(*dirlist);
2509  TQFileInfo *dirfi;
2510  while ( (dirfi = holdersdirit.current()) != 0 ) {
2511  if (dirfi->isSymLink()) {
2512  char* collapsedPath = realpath((holdersnodename + dirfi->readLink()).ascii(), NULL);
2513  holdingDeviceNodes.append(TQString(collapsedPath));
2514  free(collapsedPath);
2515  }
2516  ++holdersdirit;
2517  }
2518  }
2519 
2520  // See if any other physical devices underlie this device, for example when the Device Mapper is in use
2521  TQStringList slaveDeviceNodes;
2522  TQString slavesnodename = udev_device_get_syspath(dev);
2523  slavesnodename.append("/slaves/");
2524  TQDir slavedir(slavesnodename);
2525  slavedir.setFilter(TQDir::All);
2526  dirlist = slavedir.entryInfoList();
2527  if (dirlist) {
2528  TQFileInfoListIterator slavedirit(*dirlist);
2529  TQFileInfo *dirfi;
2530  while ( (dirfi = slavedirit.current()) != 0 ) {
2531  if (dirfi->isSymLink()) {
2532  char* collapsedPath = realpath((slavesnodename + dirfi->readLink()).ascii(), NULL);
2533  slaveDeviceNodes.append(TQString(collapsedPath));
2534  free(collapsedPath);
2535  }
2536  ++slavedirit;
2537  }
2538  }
2539 
2540  // Determine generic disk information
2541  TQString devicevendor(udev_device_get_property_value(dev, "ID_VENDOR"));
2542  TQString devicemodel(udev_device_get_property_value(dev, "ID_MODEL"));
2543  TQString devicebus(udev_device_get_property_value(dev, "ID_BUS"));
2544 
2545  // Get disk specific info
2546  TQString disklabel(decodeHexEncoding(TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))));
2547  if (disklabel == "") {
2548  disklabel = TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL"));
2549  }
2550  TQString diskuuid(udev_device_get_property_value(dev, "ID_FS_UUID"));
2551  TQString filesystemtype(udev_device_get_property_value(dev, "ID_FS_TYPE"));
2552  TQString filesystemusage(udev_device_get_property_value(dev, "ID_FS_USAGE"));
2553 
2554  device->internalSetVendorName(devicevendor);
2555  device->internalSetVendorModel(devicemodel);
2556  device->internalSetDeviceBus(devicebus);
2557 
2558  TDEDiskDeviceType::TDEDiskDeviceType disktype = sdevice->diskType();
2559  TDEDiskDeviceStatus::TDEDiskDeviceStatus diskstatus = TDEDiskDeviceStatus::Null;
2560 
2561  TDEStorageDevice* parentdisk = NULL;
2562  if (!(TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER")).isEmpty())) {
2563  TQString parentsyspath = systempath;
2564  parentsyspath.truncate(parentsyspath.length()-1); // Remove trailing slash
2565  parentsyspath.truncate(parentsyspath.findRev("/"));
2566  parentdisk = static_cast<TDEStorageDevice*>(findBySystemPath(parentsyspath));
2567  }
2568  disktype = classifyDiskType(dev, devicenode, devicebus, devicetypestring, systempath, devicevendor, devicemodel, filesystemtype, devicedriver);
2569  if (parentdisk) {
2570  // Set partition disk type and status based on the parent device
2571  disktype = disktype | parentdisk->diskType();
2572  diskstatus = diskstatus | parentdisk->diskStatus();
2573  }
2574  sdevice->internalSetDiskType(disktype);
2575  device = classifyUnknownDeviceByExternalRules(dev, device, true); // Check external rules for possible subtype overrides
2576  disktype = sdevice->diskType(); // The type can be overridden by an external rule
2577 
2578  if (TQString(udev_device_get_property_value(dev, "UDISKS_IGNORE")) == "1") {
2579  diskstatus = diskstatus | TDEDiskDeviceStatus::Hidden;
2580  }
2581 
2582  if ((disktype & TDEDiskDeviceType::CDROM)
2583  || (disktype & TDEDiskDeviceType::CDR)
2584  || (disktype & TDEDiskDeviceType::CDRW)
2585  || (disktype & TDEDiskDeviceType::CDMO)
2586  || (disktype & TDEDiskDeviceType::CDMRRW)
2587  || (disktype & TDEDiskDeviceType::CDMRRWW)
2588  || (disktype & TDEDiskDeviceType::DVDROM)
2589  || (disktype & TDEDiskDeviceType::DVDRAM)
2590  || (disktype & TDEDiskDeviceType::DVDR)
2591  || (disktype & TDEDiskDeviceType::DVDRW)
2592  || (disktype & TDEDiskDeviceType::DVDRDL)
2593  || (disktype & TDEDiskDeviceType::DVDRWDL)
2594  || (disktype & TDEDiskDeviceType::DVDPLUSR)
2595  || (disktype & TDEDiskDeviceType::DVDPLUSRW)
2596  || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
2597  || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
2598  || (disktype & TDEDiskDeviceType::BDROM)
2599  || (disktype & TDEDiskDeviceType::BDR)
2600  || (disktype & TDEDiskDeviceType::BDRW)
2601  || (disktype & TDEDiskDeviceType::HDDVDROM)
2602  || (disktype & TDEDiskDeviceType::HDDVDR)
2603  || (disktype & TDEDiskDeviceType::HDDVDRW)
2604  || (disktype & TDEDiskDeviceType::CDAudio)
2605  || (disktype & TDEDiskDeviceType::CDVideo)
2606  || (disktype & TDEDiskDeviceType::DVDVideo)
2607  || (disktype & TDEDiskDeviceType::BDVideo)
2608  ) {
2609  // These drives are guaranteed to be optical
2610  disktype = disktype | TDEDiskDeviceType::Optical;
2611  }
2612 
2613  if (disktype & TDEDiskDeviceType::Floppy) {
2614  // Floppy drives don't work well under udev
2615  // I have to look for the block device name manually
2616  TQString floppyblknodename = systempath;
2617  floppyblknodename.append("/block");
2618  TQDir floppyblkdir(floppyblknodename);
2619  floppyblkdir.setFilter(TQDir::All);
2620  const TQFileInfoList *floppyblkdirlist = floppyblkdir.entryInfoList();
2621  if (floppyblkdirlist) {
2622  TQFileInfoListIterator floppyblkdirit(*floppyblkdirlist);
2623  TQFileInfo *dirfi;
2624  while ( (dirfi = floppyblkdirit.current()) != 0 ) {
2625  if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
2626  // Does this routine work with more than one floppy drive in the system?
2627  devicenode = TQString("/dev/").append(dirfi->fileName());
2628  }
2629  ++floppyblkdirit;
2630  }
2631  }
2632 
2633  // Some interesting information can be gleaned from the CMOS type file
2634  // 0 : Defaults
2635  // 1 : 5 1/4 DD
2636  // 2 : 5 1/4 HD
2637  // 3 : 3 1/2 DD
2638  // 4 : 3 1/2 HD
2639  // 5 : 3 1/2 ED
2640  // 6 : 3 1/2 ED
2641  // 16 : unknown or not installed
2642  TQString floppycmsnodename = systempath;
2643  floppycmsnodename.append("/cmos");
2644  TQFile floppycmsfile( floppycmsnodename );
2645  TQString cmosstring;
2646  if ( floppycmsfile.open( IO_ReadOnly ) ) {
2647  TQTextStream stream( &floppycmsfile );
2648  cmosstring = stream.readLine();
2649  floppycmsfile.close();
2650  }
2651  // FIXME
2652  // Do something with the information in cmosstring
2653 
2654  if (devicenode.isNull()) {
2655  // This floppy drive cannot be mounted, so ignore it
2656  disktype = disktype & ~TDEDiskDeviceType::Floppy;
2657  }
2658  }
2659 
2660  if (devicetypestring.upper() == "CD") {
2661  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_STATE")).upper() == "BLANK") {
2662  diskstatus = diskstatus | TDEDiskDeviceStatus::Blank;
2663  }
2664  sdevice->internalSetMediaInserted((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) != ""));
2665  }
2666 
2667  if (disktype & TDEDiskDeviceType::Zip) {
2668  // A Zip drive does not advertise its status via udev, but it can be guessed from the size parameter
2669  TQString zipnodename = systempath;
2670  zipnodename.append("/size");
2671  TQFile namefile( zipnodename );
2672  TQString zipsize;
2673  if ( namefile.open( IO_ReadOnly ) ) {
2674  TQTextStream stream( &namefile );
2675  zipsize = stream.readLine();
2676  namefile.close();
2677  }
2678  if (!zipsize.isNull()) {
2679  sdevice->internalSetMediaInserted((zipsize.toInt() != 0));
2680  }
2681  }
2682 
2683  if (removable) {
2684  diskstatus = diskstatus | TDEDiskDeviceStatus::Removable;
2685  }
2686  if (hotpluggable) {
2687  diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
2688  }
2689  // Force removable flag for flash disks
2690  // udev reports disks as non-removable for card readers on PCI controllers
2691  if (((disktype & TDEDiskDeviceType::CompactFlash)
2692  || (disktype & TDEDiskDeviceType::MemoryStick)
2693  || (disktype & TDEDiskDeviceType::SmartMedia)
2694  || (disktype & TDEDiskDeviceType::SDMMC))
2695  && !(diskstatus & TDEDiskDeviceStatus::Removable)
2696  && !(diskstatus & TDEDiskDeviceStatus::Hotpluggable)) {
2697  diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
2698  }
2699 
2700  if ((filesystemtype.upper() != "CRYPTO_LUKS") && (filesystemtype.upper() != "CRYPTO") && (filesystemtype.upper() != "SWAP") && (!filesystemtype.isEmpty())) {
2701  diskstatus = diskstatus | TDEDiskDeviceStatus::ContainsFilesystem;
2702  }
2703  else {
2704  diskstatus = diskstatus & ~TDEDiskDeviceStatus::ContainsFilesystem;
2705  }
2706 
2707  // Set mountable flag if device is likely to be mountable
2708  diskstatus = diskstatus | TDEDiskDeviceStatus::Mountable;
2709  if ((devicetypestring.upper().isNull()) && (disktype & TDEDiskDeviceType::HDD)) {
2710  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2711  }
2712  if (removable) {
2713  if (sdevice->mediaInserted()) {
2714  diskstatus = diskstatus | TDEDiskDeviceStatus::Inserted;
2715  }
2716  else {
2717  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2718  }
2719  }
2720  // Swap partitions cannot be mounted
2721  if (filesystemtype.upper() == "SWAP") {
2722  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2723  }
2724  // Partition tables cannot be mounted
2725  if ((TQString(udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE")) != "")
2726  && ((TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")).isEmpty())
2727  || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0x5")
2728  || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0xf")
2729  || (TQString(udev_device_get_property_value(dev, "ID_FS_USAGE")).upper() == "RAID"))) {
2730  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2731  }
2732  // If certain disk types do not report the presence of a filesystem, they are likely not mountable
2733  if ((disktype & TDEDiskDeviceType::HDD) || (disktype & TDEDiskDeviceType::Optical)) {
2734  if (!(diskstatus & TDEDiskDeviceStatus::ContainsFilesystem)) {
2735  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2736  }
2737  }
2738 
2739  if (holdingDeviceNodes.count() > 0) {
2740  diskstatus = diskstatus | TDEDiskDeviceStatus::UsedByDevice;
2741  }
2742 
2743  if (slaveDeviceNodes.count() > 0) {
2744  diskstatus = diskstatus | TDEDiskDeviceStatus::UsesDevice;
2745  }
2746 
2747  // See if any slaves were crypted
2748  for ( TQStringList::Iterator slaveit = slaveDeviceNodes.begin(); slaveit != slaveDeviceNodes.end(); ++slaveit ) {
2749  struct udev_device *slavedev;
2750  slavedev = udev_device_new_from_syspath(m_udevStruct, (*slaveit).ascii());
2751  TQString slavediskfstype(udev_device_get_property_value(slavedev, "ID_FS_TYPE"));
2752  if ((slavediskfstype.upper() == "CRYPTO_LUKS") || (slavediskfstype.upper() == "CRYPTO")) {
2753  disktype = disktype | TDEDiskDeviceType::UnlockedCrypt;
2754  // Set disk type based on parent device
2755  disktype = disktype | classifyDiskType(slavedev, devicenode, TQString(udev_device_get_property_value(dev, "ID_BUS")), TQString(udev_device_get_property_value(dev, "ID_TYPE")), (*slaveit), TQString(udev_device_get_property_value(dev, "ID_VENDOR")), TQString(udev_device_get_property_value(dev, "ID_MODEL")), TQString(udev_device_get_property_value(dev, "ID_FS_TYPE")), TQString(udev_device_get_driver(dev)));
2756  }
2757  udev_device_unref(slavedev);
2758  }
2759 
2760  sdevice->internalSetDiskType(disktype);
2761  sdevice->internalSetDiskUUID(diskuuid);
2762  sdevice->internalSetDiskStatus(diskstatus);
2763  sdevice->internalSetFileSystemName(filesystemtype);
2764  sdevice->internalSetFileSystemUsage(filesystemusage);
2765  sdevice->internalSetSlaveDevices(slaveDeviceNodes);
2766  sdevice->internalSetHoldingDevices(holdingDeviceNodes);
2767 
2768  // Clean up disk label
2769  if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
2770  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDR))
2771  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
2772  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMO))
2773  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRW))
2774  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRWW))
2775  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
2776  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
2777  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDR))
2778  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
2779  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRDL))
2780  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRWDL))
2781  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSR))
2782  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRW))
2783  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRDL))
2784  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRWDL))
2785  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
2786  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDR))
2787  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
2788  || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDROM))
2789  || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDR))
2790  || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDRW))
2791  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
2792  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
2793  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
2794  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
2795  ) {
2796  if (disklabel == "" && sdevice->diskLabel().isNull()) {
2797  // Read the volume label in via volname, since udev couldn't be bothered to do this on its own
2798  FILE *exepipe = popen(((TQString("volname %1").arg(devicenode).ascii())), "r");
2799  if (exepipe) {
2800  char buffer[8092];
2801  disklabel = fgets(buffer, sizeof(buffer), exepipe);
2802  pclose(exepipe);
2803  }
2804  }
2805  }
2806 
2807  sdevice->internalSetDiskLabel(disklabel);
2808  }
2809  }
2810 
2811  if (device->type() == TDEGenericDeviceType::Network) {
2812  // Network devices don't have devices nodes per se, but we can at least return the Linux network name...
2813  TQString potentialdevicenode = systempath;
2814  if (potentialdevicenode.endsWith("/")) potentialdevicenode.truncate(potentialdevicenode.length()-1);
2815  potentialdevicenode.remove(0, potentialdevicenode.findRev("/")+1);
2816  TQString potentialparentnode = systempath;
2817  if (potentialparentnode.endsWith("/")) potentialparentnode.truncate(potentialparentnode.length()-1);
2818  potentialparentnode.remove(0, potentialparentnode.findRev("/", potentialparentnode.findRev("/")-1)+1);
2819  if (potentialparentnode.startsWith("net/")) {
2820  devicenode = potentialdevicenode;
2821  }
2822 
2823  if (devicenode.isNull()) {
2824  // Platform device, not a physical device
2825  // HACK
2826  // This only works because devices of type Platform only access the TDEGenericDevice class!
2827  device->m_deviceType = TDEGenericDeviceType::Platform;
2828  }
2829  else {
2830  // Gather network device information
2831  TDENetworkDevice* ndevice = dynamic_cast<TDENetworkDevice*>(device);
2832  TQString valuesnodename = systempath + "/";
2833  TQDir valuesdir(valuesnodename);
2834  valuesdir.setFilter(TQDir::All);
2835  TQString nodename;
2836  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
2837  if (dirlist) {
2838  TQFileInfoListIterator valuesdirit(*dirlist);
2839  TQFileInfo *dirfi;
2840  while ( (dirfi = valuesdirit.current()) != 0 ) {
2841  nodename = dirfi->fileName();
2842  TQFile file( valuesnodename + nodename );
2843  if ( file.open( IO_ReadOnly ) ) {
2844  TQTextStream stream( &file );
2845  TQString line;
2846  line = stream.readLine();
2847  if (nodename == "address") {
2848  ndevice->internalSetMacAddress(line);
2849  }
2850  else if (nodename == "carrier") {
2851  ndevice->internalSetCarrierPresent(line.toInt());
2852  }
2853  else if (nodename == "dormant") {
2854  ndevice->internalSetDormant(line.toInt());
2855  }
2856  else if (nodename == "operstate") {
2857  TQString friendlyState = line.lower();
2858  friendlyState[0] = friendlyState[0].upper();
2859  ndevice->internalSetState(friendlyState);
2860  }
2861  file.close();
2862  }
2863  ++valuesdirit;
2864  }
2865  }
2866  // Gather connection information such as IP addresses
2867  if ((ndevice->state().upper() == "UP")
2868  || (ndevice->state().upper() == "UNKNOWN")) {
2869  struct ifaddrs *ifaddr, *ifa;
2870  int family, s;
2871  char host[NI_MAXHOST];
2872 
2873  if (getifaddrs(&ifaddr) != -1) {
2874  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
2875  if (ifa->ifa_addr == NULL) {
2876  continue;
2877  }
2878 
2879  family = ifa->ifa_addr->sa_family;
2880 
2881  if (TQString(ifa->ifa_name) == devicenode) {
2882  if ((family == AF_INET) || (family == AF_INET6)) {
2883  s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
2884  if (s == 0) {
2885  TQString address(host);
2886  if (family == AF_INET) {
2887  ndevice->internalSetIpV4Address(address);
2888  }
2889  else if (family == AF_INET6) {
2890  address.truncate(address.findRev("%"));
2891  ndevice->internalSetIpV6Address(address);
2892  }
2893  }
2894  s = getnameinfo(ifa->ifa_netmask, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
2895  if (s == 0) {
2896  TQString address(host);
2897  if (family == AF_INET) {
2898  ndevice->internalSetIpV4Netmask(address);
2899  }
2900  else if (family == AF_INET6) {
2901  address.truncate(address.findRev("%"));
2902  ndevice->internalSetIpV6Netmask(address);
2903  }
2904  }
2905  s = getnameinfo(ifa->ifa_ifu.ifu_broadaddr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
2906  if (s == 0) {
2907  TQString address(host);
2908  if (family == AF_INET) {
2909  ndevice->internalSetIpV4Broadcast(address);
2910  }
2911  else if (family == AF_INET6) {
2912  address.truncate(address.findRev("%"));
2913  ndevice->internalSetIpV6Broadcast(address);
2914  }
2915  }
2916  s = getnameinfo(ifa->ifa_ifu.ifu_dstaddr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
2917  if (s == 0) {
2918  TQString address(host);
2919  if (family == AF_INET) {
2920  ndevice->internalSetIpV4Destination(address);
2921  }
2922  else if (family == AF_INET6) {
2923  address.truncate(address.findRev("%"));
2924  ndevice->internalSetIpV6Destination(address);
2925  }
2926  }
2927  }
2928  }
2929  }
2930  }
2931 
2932  freeifaddrs(ifaddr);
2933 
2934  // Gather statistics
2935  TQString valuesnodename = systempath + "/statistics/";
2936  TQDir valuesdir(valuesnodename);
2937  valuesdir.setFilter(TQDir::All);
2938  TQString nodename;
2939  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
2940  if (dirlist) {
2941  TQFileInfoListIterator valuesdirit(*dirlist);
2942  TQFileInfo *dirfi;
2943  while ( (dirfi = valuesdirit.current()) != 0 ) {
2944  nodename = dirfi->fileName();
2945  TQFile file( valuesnodename + nodename );
2946  if ( file.open( IO_ReadOnly ) ) {
2947  TQTextStream stream( &file );
2948  TQString line;
2949  line = stream.readLine();
2950  if (nodename == "rx_bytes") {
2951  ndevice->internalSetRxBytes(line.toDouble());
2952  }
2953  else if (nodename == "tx_bytes") {
2954  ndevice->internalSetTxBytes(line.toDouble());
2955  }
2956  else if (nodename == "rx_packets") {
2957  ndevice->internalSetRxPackets(line.toDouble());
2958  }
2959  else if (nodename == "tx_packets") {
2960  ndevice->internalSetTxPackets(line.toDouble());
2961  }
2962  file.close();
2963  }
2964  ++valuesdirit;
2965  }
2966  }
2967  }
2968  }
2969  }
2970 
2971  if ((device->type() == TDEGenericDeviceType::OtherSensor) || (device->type() == TDEGenericDeviceType::ThermalSensor)) {
2972  // Populate all sensor values
2973  TDESensorClusterMap sensors;
2974  TQString valuesnodename = systempath + "/";
2975  TQDir valuesdir(valuesnodename);
2976  valuesdir.setFilter(TQDir::All);
2977  TQString nodename;
2978  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
2979  if (dirlist) {
2980  TQFileInfoListIterator valuesdirit(*dirlist);
2981  TQFileInfo *dirfi;
2982  while ( (dirfi = valuesdirit.current()) != 0 ) {
2983  nodename = dirfi->fileName();
2984  if (nodename.contains("_")) {
2985  TQFile file( valuesnodename + nodename );
2986  if ( file.open( IO_ReadOnly ) ) {
2987  TQTextStream stream( &file );
2988  TQString line;
2989  line = stream.readLine();
2990  TQStringList sensornodelist = TQStringList::split("_", nodename);
2991  TQString sensornodename = *(sensornodelist.at(0));
2992  TQString sensornodetype = *(sensornodelist.at(1));
2993  double lineValue = line.toDouble();
2994  if (!sensornodename.contains("fan")) {
2995  lineValue = lineValue / 1000.0;
2996  }
2997  if (sensornodetype == "label") {
2998  sensors[sensornodename].label = line;
2999  }
3000  else if (sensornodetype == "input") {
3001  sensors[sensornodename].current = lineValue;
3002  }
3003  else if (sensornodetype == "min") {
3004  sensors[sensornodename].minimum = lineValue;
3005  }
3006  else if (sensornodetype == "max") {
3007  sensors[sensornodename].maximum = lineValue;
3008  }
3009  else if (sensornodetype == "warn") {
3010  sensors[sensornodename].warning = lineValue;
3011  }
3012  else if (sensornodetype == "crit") {
3013  sensors[sensornodename].critical = lineValue;
3014  }
3015  file.close();
3016  }
3017  }
3018  ++valuesdirit;
3019  }
3020  }
3021 
3022  TDESensorDevice* sdevice = dynamic_cast<TDESensorDevice*>(device);
3023  sdevice->internalSetValues(sensors);
3024  }
3025 
3026  if (device->type() == TDEGenericDeviceType::Battery) {
3027  // Populate all battery values
3028  TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(device);
3029  TQString valuesnodename = systempath + "/";
3030  TQDir valuesdir(valuesnodename);
3031  valuesdir.setFilter(TQDir::All);
3032  TQString nodename;
3033  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3034  if (dirlist) {
3035  TQFileInfoListIterator valuesdirit(*dirlist);
3036  TQFileInfo *dirfi;
3037  while ( (dirfi = valuesdirit.current()) != 0 ) {
3038  nodename = dirfi->fileName();
3039  TQFile file( valuesnodename + nodename );
3040  if ( file.open( IO_ReadOnly ) ) {
3041  TQTextStream stream( &file );
3042  TQString line;
3043  line = stream.readLine();
3044  if (nodename == "alarm") {
3045  bdevice->internalSetAlarmEnergy(line.toDouble()/1000000.0);
3046  }
3047  else if (nodename == "charge_full" || nodename == "energy_full") {
3048  bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0);
3049  }
3050  else if (nodename == "charge_full_design" || nodename == "energy_full_design") {
3051  bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0);
3052  }
3053  else if (nodename == "charge_now" || nodename == "energy_now") {
3054  bdevice->internalSetEnergy(line.toDouble()/1000000.0);
3055  }
3056  else if (nodename == "manufacturer") {
3057  bdevice->internalSetVendorName(line.stripWhiteSpace());
3058  }
3059  else if (nodename == "model_name") {
3060  bdevice->internalSetVendorModel(line.stripWhiteSpace());
3061  }
3062  else if (nodename == "power_now" || nodename == "current_now") {
3063  bdevice->internalSetDischargeRate(line.toDouble()/1000000.0);
3064  }
3065  else if (nodename == "present") {
3066  bdevice->internalSetInstalled(line.toInt());
3067  }
3068  else if (nodename == "serial_number") {
3069  bdevice->internalSetSerialNumber(line.stripWhiteSpace());
3070  }
3071  else if (nodename == "status") {
3072  bdevice->internalSetStatus(line);
3073  }
3074  else if (nodename == "technology") {
3075  bdevice->internalSetTechnology(line);
3076  }
3077  else if (nodename == "voltage_min_design") {
3078  bdevice->internalSetMinimumVoltage(line.toDouble()/1000000.0);
3079  }
3080  else if (nodename == "voltage_now") {
3081  bdevice->internalSetVoltage(line.toDouble()/1000000.0);
3082  }
3083  file.close();
3084  }
3085  ++valuesdirit;
3086  }
3087  }
3088 
3089  // Calculate time remaining
3090  // Discharge/charge rate is in watt-hours
3091  // Energy is in watt-hours
3092  // Therefore, energy/rate = time in hours
3093  // Convert to seconds...
3094  if (bdevice->status() == TDEBatteryStatus::Charging) {
3095  bdevice->internalSetTimeRemaining(((bdevice->maximumEnergy()-bdevice->energy())/bdevice->dischargeRate())*60*60);
3096  }
3097  else {
3098  bdevice->internalSetTimeRemaining((bdevice->energy()/bdevice->dischargeRate())*60*60);
3099  }
3100  }
3101 
3102  if (device->type() == TDEGenericDeviceType::PowerSupply) {
3103  // Populate all power supply values
3104  TDEMainsPowerDevice* pdevice = dynamic_cast<TDEMainsPowerDevice*>(device);
3105  TQString valuesnodename = systempath + "/";
3106  TQDir valuesdir(valuesnodename);
3107  valuesdir.setFilter(TQDir::All);
3108  TQString nodename;
3109  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3110  if (dirlist) {
3111  TQFileInfoListIterator valuesdirit(*dirlist);
3112  TQFileInfo *dirfi;
3113  while ( (dirfi = valuesdirit.current()) != 0 ) {
3114  nodename = dirfi->fileName();
3115  TQFile file( valuesnodename + nodename );
3116  if ( file.open( IO_ReadOnly ) ) {
3117  TQTextStream stream( &file );
3118  TQString line;
3119  line = stream.readLine();
3120  if (nodename == "manufacturer") {
3121  pdevice->internalSetVendorName(line.stripWhiteSpace());
3122  }
3123  else if (nodename == "model_name") {
3124  pdevice->internalSetVendorModel(line.stripWhiteSpace());
3125  }
3126  else if (nodename == "online") {
3127  pdevice->internalSetOnline(line.toInt());
3128  }
3129  else if (nodename == "serial_number") {
3130  pdevice->internalSetSerialNumber(line.stripWhiteSpace());
3131  }
3132  file.close();
3133  }
3134  ++valuesdirit;
3135  }
3136  }
3137  }
3138 
3139  if (device->type() == TDEGenericDeviceType::Backlight) {
3140  // Populate all backlight values
3141  TDEBacklightDevice* bdevice = dynamic_cast<TDEBacklightDevice*>(device);
3142  TQString valuesnodename = systempath + "/";
3143  TQDir valuesdir(valuesnodename);
3144  valuesdir.setFilter(TQDir::All);
3145  TQString nodename;
3146  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3147  if (dirlist) {
3148  TQFileInfoListIterator valuesdirit(*dirlist);
3149  TQFileInfo *dirfi;
3150  while ( (dirfi = valuesdirit.current()) != 0 ) {
3151  nodename = dirfi->fileName();
3152  TQFile file( valuesnodename + nodename );
3153  if ( file.open( IO_ReadOnly ) ) {
3154  TQTextStream stream( &file );
3155  TQString line;
3156  line = stream.readLine();
3157  if (nodename == "bl_power") {
3158  TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
3159  int rpl = line.toInt();
3160  if (rpl == FB_BLANK_UNBLANK) {
3161  pl = TDEDisplayPowerLevel::On;
3162  }
3163  else if (rpl == FB_BLANK_POWERDOWN) {
3164  pl = TDEDisplayPowerLevel::Off;
3165  }
3166  bdevice->internalSetPowerLevel(pl);
3167  }
3168  else if (nodename == "max_brightness") {
3169  bdevice->internalSetMaximumRawBrightness(line.toInt());
3170  }
3171  else if (nodename == "actual_brightness") {
3172  bdevice->internalSetCurrentRawBrightness(line.toInt());
3173  }
3174  file.close();
3175  }
3176  ++valuesdirit;
3177  }
3178  }
3179  }
3180 
3181  if (device->type() == TDEGenericDeviceType::Monitor) {
3182  TDEMonitorDevice* mdevice = dynamic_cast<TDEMonitorDevice*>(device);
3183  TQString valuesnodename = systempath + "/";
3184  TQDir valuesdir(valuesnodename);
3185  valuesdir.setFilter(TQDir::All);
3186  TQString nodename;
3187  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3188  if (dirlist) {
3189  TQFileInfoListIterator valuesdirit(*dirlist);
3190  TQFileInfo *dirfi;
3191  while ( (dirfi = valuesdirit.current()) != 0 ) {
3192  nodename = dirfi->fileName();
3193  TQFile file( valuesnodename + nodename );
3194  if ( file.open( IO_ReadOnly ) ) {
3195  TQTextStream stream( &file );
3196  TQString line;
3197  line = stream.readLine();
3198  if (nodename == "status") {
3199  mdevice->internalSetConnected(line.lower() == "connected");
3200  }
3201  else if (nodename == "enabled") {
3202  mdevice->internalSetEnabled(line.lower() == "enabled");
3203  }
3204  else if (nodename == "modes") {
3205  TQStringList resinfo;
3206  TQStringList resolutionsStringList = line.upper();
3207  while ((!stream.atEnd()) && (!line.isNull())) {
3208  line = stream.readLine();
3209  if (!line.isNull()) {
3210  resolutionsStringList.append(line.upper());
3211  }
3212  }
3213  TDEResolutionList resolutions;
3214  resolutions.clear();
3215  for (TQStringList::Iterator it = resolutionsStringList.begin(); it != resolutionsStringList.end(); ++it) {
3216  resinfo = TQStringList::split('X', *it, true);
3217  resolutions.append(TDEResolutionPair((*(resinfo.at(0))).toUInt(), (*(resinfo.at(1))).toUInt()));
3218  }
3219  mdevice->internalSetResolutions(resolutions);
3220  }
3221  else if (nodename == "dpms") {
3222  TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
3223  if (line == "On") {
3224  pl = TDEDisplayPowerLevel::On;
3225  }
3226  else if (line == "Standby") {
3227  pl = TDEDisplayPowerLevel::Standby;
3228  }
3229  else if (line == "Suspend") {
3230  pl = TDEDisplayPowerLevel::Suspend;
3231  }
3232  else if (line == "Off") {
3233  pl = TDEDisplayPowerLevel::Off;
3234  }
3235  mdevice->internalSetPowerLevel(pl);
3236  }
3237  file.close();
3238  }
3239  ++valuesdirit;
3240  }
3241  }
3242 
3243  TQString genericPortName = mdevice->systemPath();
3244  genericPortName.remove(0, genericPortName.find("-")+1);
3245  genericPortName.truncate(genericPortName.findRev("-"));
3246  mdevice->internalSetPortType(genericPortName);
3247 
3248  if (mdevice->connected()) {
3249  TQPair<TQString,TQString> monitor_info = getEDIDMonitorName(device->systemPath());
3250  if (!monitor_info.first.isNull()) {
3251  mdevice->internalSetVendorName(monitor_info.first);
3252  mdevice->internalSetVendorModel(monitor_info.second);
3253  mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second;
3254  }
3255  else {
3256  mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName);
3257  }
3258  mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
3259  }
3260  else {
3261  mdevice->m_friendlyName = i18n("Disconnected %1 Port").arg(genericPortName);
3262  mdevice->internalSetEdid(TQByteArray());
3263  mdevice->internalSetResolutions(TDEResolutionList());
3264  }
3265 
3266  // FIXME
3267  // Much of the code in libtderandr should be integrated into/interfaced with this library
3268  }
3269 
3270  if (device->type() == TDEGenericDeviceType::RootSystem) {
3271  // Try to obtain as much generic information about this system as possible
3272  TDERootSystemDevice* rdevice = dynamic_cast<TDERootSystemDevice*>(device);
3273 
3274  // Guess at my form factor
3275  // dmidecode would tell me this, but is somewhat unreliable
3276  TDESystemFormFactor::TDESystemFormFactor formfactor = TDESystemFormFactor::Desktop;
3277  if (listByDeviceClass(TDEGenericDeviceType::Backlight).count() > 0) { // Is this really a good way to determine if a machine is a laptop?
3278  formfactor = TDESystemFormFactor::Laptop;
3279  }
3280  rdevice->internalSetFormFactor(formfactor);
3281 
3282  TQString valuesnodename = "/sys/power/";
3283  TQDir valuesdir(valuesnodename);
3284  valuesdir.setFilter(TQDir::All);
3285  TQString nodename;
3286  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3287  if (dirlist) {
3288  TQFileInfoListIterator valuesdirit(*dirlist);
3289  TQFileInfo *dirfi;
3290  while ( (dirfi = valuesdirit.current()) != 0 ) {
3291  nodename = dirfi->fileName();
3292  TQFile file( valuesnodename + nodename );
3293  if ( file.open( IO_ReadOnly ) ) {
3294  TQTextStream stream( &file );
3295  TQString line;
3296  line = stream.readLine();
3297  if (nodename == "state") {
3298  TDESystemPowerStateList powerstates;
3299  // Always assume that these two fully on/fully off states are available
3300  powerstates.append(TDESystemPowerState::Active);
3301  powerstates.append(TDESystemPowerState::PowerOff);
3302  if (line.contains("standby")) {
3303  powerstates.append(TDESystemPowerState::Standby);
3304  }
3305  if (line.contains("freeze")) {
3306  powerstates.append(TDESystemPowerState::Freeze);
3307  }
3308  if (line.contains("mem")) {
3309  powerstates.append(TDESystemPowerState::Suspend);
3310  }
3311  if (line.contains("disk")) {
3312  powerstates.append(TDESystemPowerState::Hibernate);
3313  }
3314  rdevice->internalSetPowerStates(powerstates);
3315  }
3316  if (nodename == "disk") {
3317  // Get list of available hibernation methods
3318  TDESystemHibernationMethodList hibernationmethods;
3319  if (line.contains("platform")) {
3320  hibernationmethods.append(TDESystemHibernationMethod::Platform);
3321  }
3322  if (line.contains("shutdown")) {
3323  hibernationmethods.append(TDESystemHibernationMethod::Shutdown);
3324  }
3325  if (line.contains("reboot")) {
3326  hibernationmethods.append(TDESystemHibernationMethod::Reboot);
3327  }
3328  if (line.contains("testproc")) {
3329  hibernationmethods.append(TDESystemHibernationMethod::TestProc);
3330  }
3331  if (line.contains("test")) {
3332  hibernationmethods.append(TDESystemHibernationMethod::Test);
3333  }
3334  rdevice->internalSetHibernationMethods(hibernationmethods);
3335 
3336  // Get current hibernation method
3337  line.truncate(line.findRev("]"));
3338  line.remove(0, line.findRev("[")+1);
3339  TDESystemHibernationMethod::TDESystemHibernationMethod hibernationmethod = TDESystemHibernationMethod::Unsupported;
3340  if (line.contains("platform")) {
3341  hibernationmethod = TDESystemHibernationMethod::Platform;
3342  }
3343  if (line.contains("shutdown")) {
3344  hibernationmethod = TDESystemHibernationMethod::Shutdown;
3345  }
3346  if (line.contains("reboot")) {
3347  hibernationmethod = TDESystemHibernationMethod::Reboot;
3348  }
3349  if (line.contains("testproc")) {
3350  hibernationmethod = TDESystemHibernationMethod::TestProc;
3351  }
3352  if (line.contains("test")) {
3353  hibernationmethod = TDESystemHibernationMethod::Test;
3354  }
3355  rdevice->internalSetHibernationMethod(hibernationmethod);
3356  }
3357  if (nodename == "image_size") {
3358  rdevice->internalSetDiskSpaceNeededForHibernation(line.toULong());
3359  }
3360  file.close();
3361  }
3362  ++valuesdirit;
3363  }
3364  }
3365  }
3366 
3367  // NOTE
3368  // Keep these two handlers (Event and Input) in sync!
3369 
3370  if (device->type() == TDEGenericDeviceType::Event) {
3371  // Try to obtain as much type information about this event device as possible
3372  TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
3373  if (edevice->systemPath().contains("PNP0C0D")) {
3374  edevice->internalSetEventType(TDEEventDeviceType::ACPILidSwitch);
3375  }
3376  else if (edevice->systemPath().contains("PNP0C0E") || edevice->systemPath().contains("/LNXSLPBN")) {
3377  edevice->internalSetEventType(TDEEventDeviceType::ACPISleepButton);
3378  }
3379  else if (edevice->systemPath().contains("PNP0C0C") || edevice->systemPath().contains("/LNXPWRBN")) {
3380  edevice->internalSetEventType(TDEEventDeviceType::ACPIPowerButton);
3381  }
3382  else if (edevice->systemPath().contains("_acpi")) {
3383  edevice->internalSetEventType(TDEEventDeviceType::ACPIOtherInput);
3384  }
3385  else {
3386  edevice->internalSetEventType(TDEEventDeviceType::Unknown);
3387  }
3388  }
3389 
3390  if (device->type() == TDEGenericDeviceType::Input) {
3391  // Try to obtain as much type information about this input device as possible
3392  TDEInputDevice* idevice = dynamic_cast<TDEInputDevice*>(device);
3393  if (idevice->systemPath().contains("PNP0C0D")) {
3394  idevice->internalSetInputType(TDEInputDeviceType::ACPILidSwitch);
3395  }
3396  else if (idevice->systemPath().contains("PNP0C0E") || idevice->systemPath().contains("/LNXSLPBN")) {
3397  idevice->internalSetInputType(TDEInputDeviceType::ACPISleepButton);
3398  }
3399  else if (idevice->systemPath().contains("PNP0C0C") || idevice->systemPath().contains("/LNXPWRBN")) {
3400  idevice->internalSetInputType(TDEInputDeviceType::ACPIPowerButton);
3401  }
3402  else if (idevice->systemPath().contains("_acpi")) {
3403  idevice->internalSetInputType(TDEInputDeviceType::ACPIOtherInput);
3404  }
3405  else {
3406  idevice->internalSetInputType(TDEInputDeviceType::Unknown);
3407  }
3408  }
3409 
3410  if (device->type() == TDEGenericDeviceType::Event) {
3411  // Try to obtain as much specific information about this event device as possible
3412  TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
3413 
3414  // Try to open input event device
3415  if (edevice->m_fd < 0 && access (edevice->deviceNode().ascii(), R_OK) == 0) {
3416  edevice->m_fd = open(edevice->deviceNode().ascii(), O_RDONLY);
3417  }
3418 
3419  // Start monitoring of input event device
3420  edevice->internalStartMonitoring(this);
3421  }
3422 
3423  // Root devices are still special
3424  if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
3425  systempath = device->systemPath();
3426  }
3427 
3428  // Set basic device information again, as some information may have changed
3429  device->internalSetName(devicename);
3430  device->internalSetDeviceNode(devicenode);
3431  device->internalSetSystemPath(systempath);
3432  device->internalSetVendorID(devicevendorid);
3433  device->internalSetModelID(devicemodelid);
3434  device->internalSetVendorEncoded(devicevendoridenc);
3435  device->internalSetModelEncoded(devicemodelidenc);
3436  device->internalSetSubVendorID(devicesubvendorid);
3437  device->internalSetSubModelID(devicesubmodelid);
3438  device->internalSetDeviceDriver(devicedriver);
3439  device->internalSetSubsystem(devicesubsystem);
3440  device->internalSetPCIClass(devicepciclass);
3441 
3442  // Internal use only!
3443  device->m_udevtype = devicetype;
3444  device->m_udevdevicetypestring = devicetypestring;
3445  device->udevdevicetypestring_alt = devicetypestring_alt;
3446 
3447  if (temp_udev_device) {
3448  udev_device_unref(dev);
3449  }
3450 }
3451 
3452 void TDEHardwareDevices::updateBlacklists(TDEGenericDevice* hwdevice, udev_device* dev) {
3453  // HACK
3454  // I am lucky enough to have a Flash drive that spams udev continually with device change events
3455  // I imagine I am not the only one, so here is a section in which specific devices can be blacklisted!
3456 
3457  // For "U3 System" fake CD
3458  if ((hwdevice->vendorID() == "08ec") && (hwdevice->modelID() == "0020") && (TQString(udev_device_get_property_value(dev, "ID_TYPE")) == "cd")) {
3459  hwdevice->internalSetBlacklistedForUpdate(true);
3460  }
3461 }
3462 
3463 bool TDEHardwareDevices::queryHardwareInformation() {
3464  if (!m_udevStruct) {
3465  return false;
3466  }
3467 
3468  // Prepare the device list for repopulation
3469  m_deviceList.clear();
3470  addCoreSystemDevices();
3471 
3472  struct udev_enumerate *enumerate;
3473  struct udev_list_entry *devices, *dev_list_entry;
3474  struct udev_device *dev;
3475 
3476  // Create a list of all devices
3477  enumerate = udev_enumerate_new(m_udevStruct);
3478  udev_enumerate_add_match_subsystem(enumerate, NULL);
3479  udev_enumerate_scan_devices(enumerate);
3480  devices = udev_enumerate_get_list_entry(enumerate);
3481  // Get detailed information on each detected device
3482  udev_list_entry_foreach(dev_list_entry, devices) {
3483  const char *path;
3484 
3485  // Get the filename of the /sys entry for the device and create a udev_device object (dev) representing it
3486  path = udev_list_entry_get_name(dev_list_entry);
3487  dev = udev_device_new_from_syspath(m_udevStruct, path);
3488 
3489  TDEGenericDevice* device = classifyUnknownDevice(dev);
3490 
3491  // Make sure this device is not a duplicate
3492  TDEGenericDevice *hwdevice;
3493  for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
3494  if (hwdevice->systemPath() == device->systemPath()) {
3495  delete device;
3496  device = 0;
3497  break;
3498  }
3499  }
3500 
3501  if (device) {
3502  m_deviceList.append(device);
3503  }
3504 
3505  udev_device_unref(dev);
3506  }
3507 
3508  // Free the enumerator object
3509  udev_enumerate_unref(enumerate);
3510 
3511  // Update parent/child tables for all devices
3512  updateParentDeviceInformation();
3513 
3514  emit hardwareEvent(TDEHardwareEvent::HardwareListModified, TQString());
3515 
3516  return true;
3517 }
3518 
3519 void TDEHardwareDevices::updateParentDeviceInformation(TDEGenericDevice* hwdevice) {
3520  // Scan for the first path up the sysfs tree that is available in the main hardware table
3521  bool done = false;
3522  TQString current_path = hwdevice->systemPath();
3523  TDEGenericDevice* parentdevice = 0;
3524 
3525  if (current_path.endsWith("/")) {
3526  current_path.truncate(current_path.findRev("/"));
3527  }
3528  while (done == false) {
3529  current_path.truncate(current_path.findRev("/"));
3530  if (current_path.startsWith("/sys/devices")) {
3531  if (current_path.endsWith("/")) {
3532  current_path.truncate(current_path.findRev("/"));
3533  }
3534  parentdevice = findBySystemPath(current_path);
3535  if (parentdevice) {
3536  done = true;
3537  }
3538  }
3539  else {
3540  // Abort!
3541  done = true;
3542  }
3543  }
3544 
3545  hwdevice->internalSetParentDevice(parentdevice);
3546 }
3547 
3548 void TDEHardwareDevices::updateParentDeviceInformation() {
3549  TDEGenericDevice *hwdevice;
3550 
3551  // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
3552  TDEGenericHardwareList devList = listAllPhysicalDevices();
3553  for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
3554  updateParentDeviceInformation(hwdevice);
3555  }
3556 }
3557 
3558 void TDEHardwareDevices::addCoreSystemDevices() {
3559  TDEGenericDevice *hwdevice;
3560 
3561  // Add the Main Root System Device, which provides all other devices
3562  hwdevice = new TDERootSystemDevice(TDEGenericDeviceType::RootSystem);
3563  hwdevice->internalSetSystemPath("/sys/devices");
3564  m_deviceList.append(hwdevice);
3565  rescanDeviceInformation(hwdevice);
3566 
3567  // Add core top-level devices in /sys/devices to the hardware listing
3568  TQStringList holdingDeviceNodes;
3569  TQString devicesnodename = "/sys/devices";
3570  TQDir devicesdir(devicesnodename);
3571  devicesdir.setFilter(TQDir::All);
3572  TQString nodename;
3573  const TQFileInfoList *dirlist = devicesdir.entryInfoList();
3574  if (dirlist) {
3575  TQFileInfoListIterator devicesdirit(*dirlist);
3576  TQFileInfo *dirfi;
3577  while ( (dirfi = devicesdirit.current()) != 0 ) {
3578  nodename = dirfi->fileName();
3579  if (nodename != "." && nodename != "..") {
3580  hwdevice = new TDEGenericDevice(TDEGenericDeviceType::Root);
3581  hwdevice->internalSetSystemPath(dirfi->absFilePath());
3582  m_deviceList.append(hwdevice);
3583  }
3584  ++devicesdirit;
3585  }
3586  }
3587 
3588  // Handle CPUs, which are currently handled terribly by udev
3589  // Parse /proc/cpuinfo to extract some information about the CPUs
3590  hwdevice = 0;
3591  TQDir d("/sys/devices/system/cpu/");
3592  d.setFilter( TQDir::Dirs );
3593  const TQFileInfoList *list = d.entryInfoList();
3594  if (list) {
3595  TQFileInfoListIterator it( *list );
3596  TQFileInfo *fi;
3597  while ((fi = it.current()) != 0) {
3598  TQString directoryName = fi->fileName();
3599  if (directoryName.startsWith("cpu")) {
3600  directoryName = directoryName.remove(0,3);
3601  bool isInt;
3602  int processorNumber = directoryName.toUInt(&isInt, 10);
3603  if (isInt) {
3604  hwdevice = new TDECPUDevice(TDEGenericDeviceType::CPU);
3605  hwdevice->internalSetSystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
3606  m_deviceList.append(hwdevice);
3607  }
3608  }
3609  ++it;
3610  }
3611  }
3612 
3613  // Populate CPU information
3614  processModifiedCPUs();
3615 }
3616 
3617 TQString TDEHardwareDevices::findPCIDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
3618  TQString vendorName = TQString::null;
3619  TQString modelName = TQString::null;
3620  TQString friendlyName = TQString::null;
3621 
3622  if (!pci_id_map) {
3623  pci_id_map = new TDEDeviceIDMap;
3624 
3625  TQString database_filename = "/usr/share/pci.ids";
3626  if (!TQFile::exists(database_filename)) {
3627  database_filename = "/usr/share/misc/pci.ids";
3628  }
3629  if (!TQFile::exists(database_filename)) {
3630  printf("[tdehardwaredevices] Unable to locate PCI information database pci.ids\n"); fflush(stdout);
3631  return i18n("Unknown PCI Device");
3632  }
3633 
3634  TQFile database(database_filename);
3635  if (database.open(IO_ReadOnly)) {
3636  TQTextStream stream(&database);
3637  TQString line;
3638  TQString vendorID;
3639  TQString modelID;
3640  TQString subvendorID;
3641  TQString submodelID;
3642  TQString deviceMapKey;
3643  TQStringList devinfo;
3644  while (!stream.atEnd()) {
3645  line = stream.readLine();
3646  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3647  line.replace("\t", "");
3648  devinfo = TQStringList::split(' ', line, false);
3649  vendorID = *(devinfo.at(0));
3650  vendorName = line;
3651  vendorName.remove(0, vendorName.find(" "));
3652  vendorName = vendorName.stripWhiteSpace();
3653  modelName = TQString::null;
3654  deviceMapKey = vendorID.lower() + ":::";
3655  }
3656  else {
3657  if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
3658  line.replace("\t", "");
3659  devinfo = TQStringList::split(' ', line, false);
3660  modelID = *(devinfo.at(0));
3661  modelName = line;
3662  modelName.remove(0, modelName.find(" "));
3663  modelName = modelName.stripWhiteSpace();
3664  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
3665  }
3666  else {
3667  if (line.upper().startsWith("\t\t")) {
3668  line.replace("\t", "");
3669  devinfo = TQStringList::split(' ', line, false);
3670  subvendorID = *(devinfo.at(0));
3671  submodelID = *(devinfo.at(1));
3672  modelName = line;
3673  modelName.remove(0, modelName.find(" "));
3674  modelName = modelName.stripWhiteSpace();
3675  modelName.remove(0, modelName.find(" "));
3676  modelName = modelName.stripWhiteSpace();
3677  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
3678  }
3679  }
3680  }
3681  if (modelName.isNull()) {
3682  pci_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
3683  }
3684  else {
3685  pci_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
3686  }
3687  }
3688  database.close();
3689  }
3690  else {
3691  printf("[tdehardwaredevices] Unable to open PCI information database %s\n", database_filename.ascii()); fflush(stdout);
3692  }
3693  }
3694 
3695  if (pci_id_map) {
3696  TQString deviceName;
3697  TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
3698 
3699  deviceName = (*pci_id_map)[deviceMapKey];
3700  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3701  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
3702  deviceName = (*pci_id_map)[deviceMapKey];
3703  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3704  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
3705  deviceName = (*pci_id_map)[deviceMapKey];
3706  }
3707  }
3708 
3709  if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3710  deviceName.replace("***UNKNOWN DEVICE*** ", "");
3711  deviceName.prepend(i18n("Unknown PCI Device") + " ");
3712  if (subvendorid.isNull()) {
3713  deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
3714  }
3715  else {
3716  deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
3717  }
3718  }
3719 
3720  return deviceName;
3721  }
3722  else {
3723  return i18n("Unknown PCI Device");
3724  }
3725 }
3726 
3727 TQString TDEHardwareDevices::findUSBDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
3728  TQString vendorName = TQString::null;
3729  TQString modelName = TQString::null;
3730  TQString friendlyName = TQString::null;
3731 
3732  if (!usb_id_map) {
3733  usb_id_map = new TDEDeviceIDMap;
3734 
3735  TQString database_filename = "/usr/share/usb.ids";
3736  if (!TQFile::exists(database_filename)) {
3737  database_filename = "/usr/share/misc/usb.ids";
3738  }
3739  if (!TQFile::exists(database_filename)) {
3740  printf("[tdehardwaredevices] Unable to locate USB information database usb.ids\n"); fflush(stdout);
3741  return i18n("Unknown USB Device");
3742  }
3743 
3744  TQFile database(database_filename);
3745  if (database.open(IO_ReadOnly)) {
3746  TQTextStream stream(&database);
3747  TQString line;
3748  TQString vendorID;
3749  TQString modelID;
3750  TQString subvendorID;
3751  TQString submodelID;
3752  TQString deviceMapKey;
3753  TQStringList devinfo;
3754  while (!stream.atEnd()) {
3755  line = stream.readLine();
3756  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3757  line.replace("\t", "");
3758  devinfo = TQStringList::split(' ', line, false);
3759  vendorID = *(devinfo.at(0));
3760  vendorName = line;
3761  vendorName.remove(0, vendorName.find(" "));
3762  vendorName = vendorName.stripWhiteSpace();
3763  modelName = TQString::null;
3764  deviceMapKey = vendorID.lower() + ":::";
3765  }
3766  else {
3767  if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
3768  line.replace("\t", "");
3769  devinfo = TQStringList::split(' ', line, false);
3770  modelID = *(devinfo.at(0));
3771  modelName = line;
3772  modelName.remove(0, modelName.find(" "));
3773  modelName = modelName.stripWhiteSpace();
3774  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
3775  }
3776  else {
3777  if (line.upper().startsWith("\t\t")) {
3778  line.replace("\t", "");
3779  devinfo = TQStringList::split(' ', line, false);
3780  subvendorID = *(devinfo.at(0));
3781  submodelID = *(devinfo.at(1));
3782  modelName = line;
3783  modelName.remove(0, modelName.find(" "));
3784  modelName = modelName.stripWhiteSpace();
3785  modelName.remove(0, modelName.find(" "));
3786  modelName = modelName.stripWhiteSpace();
3787  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
3788  }
3789  }
3790  }
3791  if (modelName.isNull()) {
3792  usb_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
3793  }
3794  else {
3795  usb_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
3796  }
3797  }
3798  database.close();
3799  }
3800  else {
3801  printf("[tdehardwaredevices] Unable to open USB information database %s\n", database_filename.ascii()); fflush(stdout);
3802  }
3803  }
3804 
3805  if (usb_id_map) {
3806  TQString deviceName;
3807  TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
3808 
3809  deviceName = (*usb_id_map)[deviceMapKey];
3810  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3811  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
3812  deviceName = (*usb_id_map)[deviceMapKey];
3813  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3814  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
3815  deviceName = (*usb_id_map)[deviceMapKey];
3816  }
3817  }
3818 
3819  if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3820  deviceName.replace("***UNKNOWN DEVICE*** ", "");
3821  deviceName.prepend(i18n("Unknown USB Device") + " ");
3822  if (subvendorid.isNull()) {
3823  deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
3824  }
3825  else {
3826  deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
3827  }
3828  }
3829 
3830  return deviceName;
3831  }
3832  else {
3833  return i18n("Unknown USB Device");
3834  }
3835 }
3836 
3837 TQString TDEHardwareDevices::findPNPDeviceName(TQString pnpid) {
3838  TQString friendlyName = TQString::null;
3839 
3840  if (!pnp_id_map) {
3841  pnp_id_map = new TDEDeviceIDMap;
3842 
3843  TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
3844  TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
3845  TQString hardware_info_directory;
3846  TQString database_filename;
3847 
3848  for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
3849  hardware_info_directory = (*it);
3850  hardware_info_directory += hardware_info_directory_suffix;
3851 
3852  if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
3853  database_filename = hardware_info_directory + "pnp.ids";
3854  if (TQFile::exists(database_filename)) {
3855  break;
3856  }
3857  }
3858  }
3859 
3860  if (!TQFile::exists(database_filename)) {
3861  printf("[tdehardwaredevices] Unable to locate PNP information database pnp.ids\n"); fflush(stdout);
3862  return i18n("Unknown PNP Device");
3863  }
3864 
3865  TQFile database(database_filename);
3866  if (database.open(IO_ReadOnly)) {
3867  TQTextStream stream(&database);
3868  TQString line;
3869  TQString pnpID;
3870  TQString vendorName;
3871  TQString deviceMapKey;
3872  TQStringList devinfo;
3873  while (!stream.atEnd()) {
3874  line = stream.readLine();
3875  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3876  devinfo = TQStringList::split('\t', line, false);
3877  if (devinfo.count() > 1) {
3878  pnpID = *(devinfo.at(0));
3879  vendorName = *(devinfo.at(1));;
3880  vendorName = vendorName.stripWhiteSpace();
3881  deviceMapKey = pnpID.upper().stripWhiteSpace();
3882  if (!deviceMapKey.isNull()) {
3883  pnp_id_map->insert(deviceMapKey, vendorName, true);
3884  }
3885  }
3886  }
3887  }
3888  database.close();
3889  }
3890  else {
3891  printf("[tdehardwaredevices] Unable to open PNP information database %s\n", database_filename.ascii()); fflush(stdout);
3892  }
3893  }
3894 
3895  if (pnp_id_map) {
3896  TQString deviceName;
3897 
3898  deviceName = (*pnp_id_map)[pnpid];
3899 
3900  return deviceName;
3901  }
3902  else {
3903  return i18n("Unknown PNP Device");
3904  }
3905 }
3906 
3907 TQString TDEHardwareDevices::findMonitorManufacturerName(TQString dpyid) {
3908  TQString friendlyName = TQString::null;
3909 
3910  if (!dpy_id_map) {
3911  dpy_id_map = new TDEDeviceIDMap;
3912 
3913  TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
3914  TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
3915  TQString hardware_info_directory;
3916  TQString database_filename;
3917 
3918  for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
3919  hardware_info_directory = (*it);
3920  hardware_info_directory += hardware_info_directory_suffix;
3921 
3922  if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
3923  database_filename = hardware_info_directory + "dpy.ids";
3924  if (TQFile::exists(database_filename)) {
3925  break;
3926  }
3927  }
3928  }
3929 
3930  if (!TQFile::exists(database_filename)) {
3931  printf("[tdehardwaredevices] Unable to locate monitor information database dpy.ids\n"); fflush(stdout);
3932  return i18n("Unknown Monitor Device");
3933  }
3934 
3935  TQFile database(database_filename);
3936  if (database.open(IO_ReadOnly)) {
3937  TQTextStream stream(&database);
3938  TQString line;
3939  TQString dpyID;
3940  TQString vendorName;
3941  TQString deviceMapKey;
3942  TQStringList devinfo;
3943  while (!stream.atEnd()) {
3944  line = stream.readLine();
3945  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3946  devinfo = TQStringList::split('\t', line, false);
3947  if (devinfo.count() > 1) {
3948  dpyID = *(devinfo.at(0));
3949  vendorName = *(devinfo.at(1));;
3950  vendorName = vendorName.stripWhiteSpace();
3951  deviceMapKey = dpyID.upper().stripWhiteSpace();
3952  if (!deviceMapKey.isNull()) {
3953  dpy_id_map->insert(deviceMapKey, vendorName, true);
3954  }
3955  }
3956  }
3957  }
3958  database.close();
3959  }
3960  else {
3961  printf("[tdehardwaredevices] Unable to open monitor information database %s\n", database_filename.ascii()); fflush(stdout);
3962  }
3963  }
3964 
3965  if (dpy_id_map) {
3966  TQString deviceName;
3967 
3968  deviceName = (*dpy_id_map)[dpyid];
3969 
3970  return deviceName;
3971  }
3972  else {
3973  return i18n("Unknown Monitor Device");
3974  }
3975 }
3976 
3977 TQPair<TQString,TQString> TDEHardwareDevices::getEDIDMonitorName(TQString path) {
3978  TQPair<TQString,TQString> edid;
3979  TQByteArray binaryedid = getEDID(path);
3980  if (binaryedid.isNull()) {
3981  return TQPair<TQString,TQString>(TQString::null, TQString::null);
3982  }
3983 
3984  // Get the manufacturer ID
3985  unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
3986  unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
3987  unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
3988  TQChar qletter_1 = TQChar(letter_1);
3989  TQChar qletter_2 = TQChar(letter_2);
3990  TQChar qletter_3 = TQChar(letter_3);
3991  TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
3992 
3993  // Get the model ID
3994  unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
3995  // Reverse the bit order
3996  unsigned int model_id = reverse_bits(raw_model_id);
3997 
3998  // Try to get the model name
3999  bool has_friendly_name = false;
4000  unsigned char descriptor_block[18];
4001  int i;
4002  for (i=72;i<90;i++) {
4003  descriptor_block[i-72] = binaryedid[i] & 0xFF;
4004  }
4005  if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
4006  for (i=90;i<108;i++) {
4007  descriptor_block[i-90] = binaryedid[i] & 0xFF;
4008  }
4009  if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
4010  for (i=108;i<126;i++) {
4011  descriptor_block[i-108] = binaryedid[i] & 0xFF;
4012  }
4013  }
4014  }
4015 
4016  TQString monitor_name;
4017  if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
4018  char* pos = strchr((char *)(descriptor_block+5), '\n');
4019  if (pos) {
4020  *pos = 0;
4021  has_friendly_name = true;
4022  monitor_name = TQString((char *)(descriptor_block+5));
4023  }
4024  else {
4025  has_friendly_name = false;
4026  }
4027  }
4028 
4029  // Look up manufacturer name
4030  TQString manufacturer_name = findMonitorManufacturerName(manufacturer_id);
4031  if (manufacturer_name.isNull()) {
4032  manufacturer_name = manufacturer_id;
4033  }
4034 
4035  if (has_friendly_name) {
4036  edid.first = TQString("%1").arg(manufacturer_name);
4037  edid.second = TQString("%2").arg(monitor_name);
4038  }
4039  else {
4040  edid.first = TQString("%1").arg(manufacturer_name);
4041  edid.second = TQString("0x%2").arg(model_id, 0, 16);
4042  }
4043 
4044  return edid;
4045 }
4046 
4047 TQByteArray TDEHardwareDevices::getEDID(TQString path) {
4048  TQFile file(TQString("%1/edid").arg(path));
4049  if (!file.open (IO_ReadOnly)) {
4050  return TQByteArray();
4051  }
4052  TQByteArray binaryedid = file.readAll();
4053  file.close();
4054  return binaryedid;
4055 }
4056 
4057 TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDeviceType::TDEGenericDeviceType query) {
4058  TQString ret = "Unknown Device";
4059 
4060  // Keep this in sync with the TDEGenericDeviceType definition in the header
4061  if (query == TDEGenericDeviceType::Root) {
4062  ret = i18n("Root");
4063  }
4064  else if (query == TDEGenericDeviceType::RootSystem) {
4065  ret = i18n("System Root");
4066  }
4067  else if (query == TDEGenericDeviceType::CPU) {
4068  ret = i18n("CPU");
4069  }
4070  else if (query == TDEGenericDeviceType::GPU) {
4071  ret = i18n("Graphics Processor");
4072  }
4073  else if (query == TDEGenericDeviceType::RAM) {
4074  ret = i18n("RAM");
4075  }
4076  else if (query == TDEGenericDeviceType::Bus) {
4077  ret = i18n("Bus");
4078  }
4079  else if (query == TDEGenericDeviceType::I2C) {
4080  ret = i18n("I2C Bus");
4081  }
4082  else if (query == TDEGenericDeviceType::MDIO) {
4083  ret = i18n("MDIO Bus");
4084  }
4085  else if (query == TDEGenericDeviceType::Mainboard) {
4086  ret = i18n("Mainboard");
4087  }
4088  else if (query == TDEGenericDeviceType::Disk) {
4089  ret = i18n("Disk");
4090  }
4091  else if (query == TDEGenericDeviceType::SCSI) {
4092  ret = i18n("SCSI");
4093  }
4094  else if (query == TDEGenericDeviceType::StorageController) {
4095  ret = i18n("Storage Controller");
4096  }
4097  else if (query == TDEGenericDeviceType::Mouse) {
4098  ret = i18n("Mouse");
4099  }
4100  else if (query == TDEGenericDeviceType::Keyboard) {
4101  ret = i18n("Keyboard");
4102  }
4103  else if (query == TDEGenericDeviceType::HID) {
4104  ret = i18n("HID");
4105  }
4106  else if (query == TDEGenericDeviceType::Modem) {
4107  ret = i18n("Modem");
4108  }
4109  else if (query == TDEGenericDeviceType::Monitor) {
4110  ret = i18n("Monitor and Display");
4111  }
4112  else if (query == TDEGenericDeviceType::Network) {
4113  ret = i18n("Network");
4114  }
4115  else if (query == TDEGenericDeviceType::Printer) {
4116  ret = i18n("Printer");
4117  }
4118  else if (query == TDEGenericDeviceType::Scanner) {
4119  ret = i18n("Scanner");
4120  }
4121  else if (query == TDEGenericDeviceType::Sound) {
4122  ret = i18n("Sound");
4123  }
4124  else if (query == TDEGenericDeviceType::VideoCapture) {
4125  ret = i18n("Video Capture");
4126  }
4127  else if (query == TDEGenericDeviceType::IEEE1394) {
4128  ret = i18n("IEEE1394");
4129  }
4130  else if (query == TDEGenericDeviceType::PCMCIA) {
4131  ret = i18n("PCMCIA");
4132  }
4133  else if (query == TDEGenericDeviceType::Camera) {
4134  ret = i18n("Camera");
4135  }
4136  else if (query == TDEGenericDeviceType::TextIO) {
4137  ret = i18n("Text I/O");
4138  }
4139  else if (query == TDEGenericDeviceType::Serial) {
4140  ret = i18n("Serial Communications Controller");
4141  }
4142  else if (query == TDEGenericDeviceType::Parallel) {
4143  ret = i18n("Parallel Port");
4144  }
4145  else if (query == TDEGenericDeviceType::Peripheral) {
4146  ret = i18n("Peripheral");
4147  }
4148  else if (query == TDEGenericDeviceType::Backlight) {
4149  ret = i18n("Backlight");
4150  }
4151  else if (query == TDEGenericDeviceType::Battery) {
4152  ret = i18n("Battery");
4153  }
4154  else if (query == TDEGenericDeviceType::PowerSupply) {
4155  ret = i18n("Power Supply");
4156  }
4157  else if (query == TDEGenericDeviceType::Dock) {
4158  ret = i18n("Docking Station");
4159  }
4160  else if (query == TDEGenericDeviceType::ThermalSensor) {
4161  ret = i18n("Thermal Sensor");
4162  }
4163  else if (query == TDEGenericDeviceType::ThermalControl) {
4164  ret = i18n("Thermal Control");
4165  }
4166  else if (query == TDEGenericDeviceType::BlueTooth) {
4167  ret = i18n("Bluetooth");
4168  }
4169  else if (query == TDEGenericDeviceType::Bridge) {
4170  ret = i18n("Bridge");
4171  }
4172  else if (query == TDEGenericDeviceType::Platform) {
4173  ret = i18n("Platform");
4174  }
4175  else if (query == TDEGenericDeviceType::Cryptography) {
4176  ret = i18n("Cryptography");
4177  }
4178  else if (query == TDEGenericDeviceType::Event) {
4179  ret = i18n("Platform Event");
4180  }
4181  else if (query == TDEGenericDeviceType::Input) {
4182  ret = i18n("Platform Input");
4183  }
4184  else if (query == TDEGenericDeviceType::PNP) {
4185  ret = i18n("Plug and Play");
4186  }
4187  else if (query == TDEGenericDeviceType::OtherACPI) {
4188  ret = i18n("Other ACPI");
4189  }
4190  else if (query == TDEGenericDeviceType::OtherUSB) {
4191  ret = i18n("Other USB");
4192  }
4193  else if (query == TDEGenericDeviceType::OtherMultimedia) {
4194  ret = i18n("Other Multimedia");
4195  }
4196  else if (query == TDEGenericDeviceType::OtherPeripheral) {
4197  ret = i18n("Other Peripheral");
4198  }
4199  else if (query == TDEGenericDeviceType::OtherSensor) {
4200  ret = i18n("Other Sensor");
4201  }
4202  else if (query == TDEGenericDeviceType::OtherVirtual) {
4203  ret = i18n("Other Virtual");
4204  }
4205  else {
4206  ret = i18n("Unknown Device");
4207  }
4208 
4209  return ret;
4210 }
4211 
4212 TQPixmap TDEHardwareDevices::getDeviceTypeIconFromType(TDEGenericDeviceType::TDEGenericDeviceType query, TDEIcon::StdSizes size) {
4213  TQPixmap ret = DesktopIcon("misc", size);
4214 
4215 // // Keep this in sync with the TDEGenericDeviceType definition in the header
4216  if (query == TDEGenericDeviceType::Root) {
4217  ret = DesktopIcon("kcmdevices", size);
4218  }
4219  else if (query == TDEGenericDeviceType::RootSystem) {
4220  ret = DesktopIcon("kcmdevices", size);
4221  }
4222  else if (query == TDEGenericDeviceType::CPU) {
4223  ret = DesktopIcon("kcmprocessor", size);
4224  }
4225  else if (query == TDEGenericDeviceType::GPU) {
4226  ret = DesktopIcon("kcmpci", size);
4227  }
4228  else if (query == TDEGenericDeviceType::RAM) {
4229  ret = DesktopIcon("memory", size);
4230  }
4231  else if (query == TDEGenericDeviceType::Bus) {
4232  ret = DesktopIcon("kcmpci", size);
4233  }
4234  else if (query == TDEGenericDeviceType::I2C) {
4235  ret = DesktopIcon("preferences-desktop-peripherals", size);
4236  }
4237  else if (query == TDEGenericDeviceType::MDIO) {
4238  ret = DesktopIcon("preferences-desktop-peripherals", size);
4239  }
4240  else if (query == TDEGenericDeviceType::Mainboard) {
4241  ret = DesktopIcon("kcmpci", size); // FIXME
4242  }
4243  else if (query == TDEGenericDeviceType::Disk) {
4244  ret = DesktopIcon("drive-harddisk", size);
4245  }
4246  else if (query == TDEGenericDeviceType::SCSI) {
4247  ret = DesktopIcon("kcmscsi", size);
4248  }
4249  else if (query == TDEGenericDeviceType::StorageController) {
4250  ret = DesktopIcon("kcmpci", size);
4251  }
4252  else if (query == TDEGenericDeviceType::Mouse) {
4253  ret = DesktopIcon("input-mouse", size);
4254  }
4255  else if (query == TDEGenericDeviceType::Keyboard) {
4256  ret = DesktopIcon("input-keyboard", size);
4257  }
4258  else if (query == TDEGenericDeviceType::HID) {
4259  ret = DesktopIcon("kcmdevices", size); // FIXME
4260  }
4261  else if (query == TDEGenericDeviceType::Modem) {
4262  ret = DesktopIcon("kcmpci", size);
4263  }
4264  else if (query == TDEGenericDeviceType::Monitor) {
4265  ret = DesktopIcon("background", size);
4266  }
4267  else if (query == TDEGenericDeviceType::Network) {
4268  ret = DesktopIcon("kcmpci", size);
4269  }
4270  else if (query == TDEGenericDeviceType::Printer) {
4271  ret = DesktopIcon("printer", size);
4272  }
4273  else if (query == TDEGenericDeviceType::Scanner) {
4274  ret = DesktopIcon("scanner", size);
4275  }
4276  else if (query == TDEGenericDeviceType::Sound) {
4277  ret = DesktopIcon("kcmsound", size);
4278  }
4279  else if (query == TDEGenericDeviceType::VideoCapture) {
4280  ret = DesktopIcon("tv", size); // FIXME
4281  }
4282  else if (query == TDEGenericDeviceType::IEEE1394) {
4283  ret = DesktopIcon("ieee1394", size);
4284  }
4285  else if (query == TDEGenericDeviceType::PCMCIA) {
4286  ret = DesktopIcon("kcmdevices", size); // FIXME
4287  }
4288  else if (query == TDEGenericDeviceType::Camera) {
4289  ret = DesktopIcon("camera-photo", size);
4290  }
4291  else if (query == TDEGenericDeviceType::Serial) {
4292  ret = DesktopIcon("preferences-desktop-peripherals", size);
4293  }
4294  else if (query == TDEGenericDeviceType::Parallel) {
4295  ret = DesktopIcon("preferences-desktop-peripherals", size);
4296  }
4297  else if (query == TDEGenericDeviceType::TextIO) {
4298  ret = DesktopIcon("chardevice", size);
4299  }
4300  else if (query == TDEGenericDeviceType::Peripheral) {
4301  ret = DesktopIcon("kcmpci", size);
4302  }
4303  else if (query == TDEGenericDeviceType::Backlight) {
4304  ret = DesktopIcon("tdescreensaver", size); // FIXME
4305  }
4306  else if (query == TDEGenericDeviceType::Battery) {
4307  ret = DesktopIcon("energy", size);
4308  }
4309  else if (query == TDEGenericDeviceType::PowerSupply) {
4310  ret = DesktopIcon("energy", size);
4311  }
4312  else if (query == TDEGenericDeviceType::Dock) {
4313  ret = DesktopIcon("kcmdevices", size); // FIXME
4314  }
4315  else if (query == TDEGenericDeviceType::ThermalSensor) {
4316  ret = DesktopIcon("kcmdevices", size); // FIXME
4317  }
4318  else if (query == TDEGenericDeviceType::ThermalControl) {
4319  ret = DesktopIcon("kcmdevices", size); // FIXME
4320  }
4321  else if (query == TDEGenericDeviceType::BlueTooth) {
4322  ret = DesktopIcon("kcmpci", size); // FIXME
4323  }
4324  else if (query == TDEGenericDeviceType::Bridge) {
4325  ret = DesktopIcon("kcmpci", size);
4326  }
4327  else if (query == TDEGenericDeviceType::Platform) {
4328  ret = DesktopIcon("preferences-system", size);
4329  }
4330  else if (query == TDEGenericDeviceType::Cryptography) {
4331  ret = DesktopIcon("password", size);
4332  }
4333  else if (query == TDEGenericDeviceType::Event) {
4334  ret = DesktopIcon("preferences-system", size);
4335  }
4336  else if (query == TDEGenericDeviceType::Input) {
4337  ret = DesktopIcon("preferences-system", size);
4338  }
4339  else if (query == TDEGenericDeviceType::PNP) {
4340  ret = DesktopIcon("preferences-system", size);
4341  }
4342  else if (query == TDEGenericDeviceType::OtherACPI) {
4343  ret = DesktopIcon("kcmdevices", size); // FIXME
4344  }
4345  else if (query == TDEGenericDeviceType::OtherUSB) {
4346  ret = DesktopIcon("usb", size);
4347  }
4348  else if (query == TDEGenericDeviceType::OtherMultimedia) {
4349  ret = DesktopIcon("kcmsound", size);
4350  }
4351  else if (query == TDEGenericDeviceType::OtherPeripheral) {
4352  ret = DesktopIcon("kcmpci", size);
4353  }
4354  else if (query == TDEGenericDeviceType::OtherSensor) {
4355  ret = DesktopIcon("kcmdevices", size); // FIXME
4356  }
4357  else if (query == TDEGenericDeviceType::OtherVirtual) {
4358  ret = DesktopIcon("preferences-system", size);
4359  }
4360  else {
4361  ret = DesktopIcon("hwinfo", size);
4362  }
4363 
4364  return ret;
4365 }
4366 
4367 TDERootSystemDevice* TDEHardwareDevices::rootSystemDevice() {
4368  TDEGenericDevice *hwdevice;
4369  for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
4370  if (hwdevice->type() == TDEGenericDeviceType::RootSystem) {
4371  return dynamic_cast<TDERootSystemDevice*>(hwdevice);
4372  }
4373  }
4374 
4375  return 0;
4376 }
4377 
4378 TQString TDEHardwareDevices::bytesToFriendlySizeString(double bytes) {
4379  TQString prettystring;
4380 
4381  prettystring = TQString("%1B").arg(bytes);
4382 
4383  if (bytes > 1024) {
4384  bytes = bytes / 1024;
4385  prettystring = TQString("%1KB").arg(bytes, 0, 'f', 1);
4386  }
4387 
4388  if (bytes > 1024) {
4389  bytes = bytes / 1024;
4390  prettystring = TQString("%1MB").arg(bytes, 0, 'f', 1);
4391  }
4392 
4393  if (bytes > 1024) {
4394  bytes = bytes / 1024;
4395  prettystring = TQString("%1GB").arg(bytes, 0, 'f', 1);
4396  }
4397 
4398  if (bytes > 1024) {
4399  bytes = bytes / 1024;
4400  prettystring = TQString("%1TB").arg(bytes, 0, 'f', 1);
4401  }
4402 
4403  if (bytes > 1024) {
4404  bytes = bytes / 1024;
4405  prettystring = TQString("%1PB").arg(bytes, 0, 'f', 1);
4406  }
4407 
4408  if (bytes > 1024) {
4409  bytes = bytes / 1024;
4410  prettystring = TQString("%1EB").arg(bytes, 0, 'f', 1);
4411  }
4412 
4413  if (bytes > 1024) {
4414  bytes = bytes / 1024;
4415  prettystring = TQString("%1ZB").arg(bytes, 0, 'f', 1);
4416  }
4417 
4418  if (bytes > 1024) {
4419  bytes = bytes / 1024;
4420  prettystring = TQString("%1YB").arg(bytes, 0, 'f', 1);
4421  }
4422 
4423  return prettystring;
4424 }
4425 
4426 TDEGenericHardwareList TDEHardwareDevices::listByDeviceClass(TDEGenericDeviceType::TDEGenericDeviceType cl) {
4427  TDEGenericHardwareList ret;
4428  ret.setAutoDelete(false);
4429 
4430  TDEGenericDevice *hwdevice;
4431  for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
4432  if (hwdevice->type() == cl) {
4433  ret.append(hwdevice);
4434  }
4435  }
4436 
4437  return ret;
4438 }
4439 
4440 TDEGenericHardwareList TDEHardwareDevices::listAllPhysicalDevices() {
4441  TDEGenericHardwareList ret = m_deviceList;
4442  ret.setAutoDelete(false);
4443 
4444  return ret;
4445 }
4446 
4447 #include "tdehardwaredevices.moc"

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.1.2
This website is maintained by Timothy Pearson.