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

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.13
This website is maintained by Timothy Pearson.