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

tdecore

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

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