• 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 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  }
923 }
924 
925 
926 void TDEHardwareDevices::processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice) {
927  emit eventDeviceKeyPressed(keycode, edevice);
928 }
929 
930 void TDEHardwareDevices::processModifiedMounts() {
931  // Detect what changed between the old mount table and the new one,
932  // and emit appropriate events
933 
934  TQMap<TQString, bool> deletedEntries = m_mountTable;
935 
936  // Read in the new mount table
937  m_mountTable.clear();
938  TQFile file( "/proc/mounts" );
939  if ( file.open( IO_ReadOnly ) ) {
940  TQTextStream stream( &file );
941  while ( !stream.atEnd() ) {
942  TQString line = stream.readLine();
943  if (!line.isEmpty()) {
944  m_mountTable[line] = true;
945  }
946  }
947  file.close();
948  }
949  TQMap<TQString, bool> addedEntries = m_mountTable;
950 
951  // Remove all entries that are identical in both tables
952  for ( TQMap<TQString, bool>::ConstIterator mtIt = m_mountTable.begin(); mtIt != m_mountTable.end(); ++mtIt ) {
953  if (deletedEntries.contains(mtIt.key())) {
954  deletedEntries.remove(mtIt.key());
955  addedEntries.remove(mtIt.key());
956  }
957  }
958 
959  TQMap<TQString, bool>::Iterator it;
960  for ( it = addedEntries.begin(); it != addedEntries.end(); ++it ) {
961  TQStringList mountInfo = TQStringList::split(" ", it.key(), true);
962  // Try to find a device that matches the altered node
963  TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
964  if (hwdevice) {
965  emit hardwareUpdated(hwdevice);
966  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
967  // If the device is a storage device and has a slave, update it as well
968  if (hwdevice->type() == TDEGenericDeviceType::Disk) {
969  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
970  TQStringList slavedevices = sdevice->slaveDevices();
971  for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
972  TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
973  if (slavedevice) {
974  emit hardwareUpdated(slavedevice);
975  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
976  }
977  }
978  }
979  }
980  }
981  for ( it = deletedEntries.begin(); it != deletedEntries.end(); ++it ) {
982  TQStringList mountInfo = TQStringList::split(" ", it.key(), true);
983  // Try to find a device that matches the altered node
984  TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
985  if (hwdevice) {
986  emit hardwareUpdated(hwdevice);
987  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
988  // If the device is a storage device and has a slave, update it as well
989  if (hwdevice->type() == TDEGenericDeviceType::Disk) {
990  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
991  TQStringList slavedevices = sdevice->slaveDevices();
992  for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
993  TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
994  if (slavedevice) {
995  emit hardwareUpdated(slavedevice);
996  emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
997  }
998  }
999  }
1000  }
1001  }
1002 
1003  emit mountTableModified();
1004  emit hardwareEvent(TDEHardwareEvent::MountTableModified, TQString());
1005 }
1006 
1007 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) {
1008  // Classify a disk device type to the best of our ability
1009  TDEDiskDeviceType::TDEDiskDeviceType disktype = TDEDiskDeviceType::Null;
1010 
1011  if (devicebus.upper() == "USB") {
1012  disktype = disktype | TDEDiskDeviceType::USB;
1013  }
1014 
1015  if (disktypestring.upper() == "DISK") {
1016  disktype = disktype | TDEDiskDeviceType::HDD;
1017  }
1018 
1019  if ((disktypestring.upper() == "FLOPPY")
1020  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY")) == "1")) {
1021  disktype = disktype | TDEDiskDeviceType::Floppy;
1022  disktype = disktype & ~TDEDiskDeviceType::HDD;
1023  }
1024 
1025  if ((disktypestring.upper() == "ZIP")
1026  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY_ZIP")) == "1")
1027  || ((devicevendor.upper() == "IOMEGA") && (devicemodel.upper().contains("ZIP")))) {
1028  disktype = disktype | TDEDiskDeviceType::Zip;
1029  disktype = disktype & ~TDEDiskDeviceType::HDD;
1030  }
1031 
1032  if ((devicevendor.upper() == "APPLE") && (devicemodel.upper().contains("IPOD"))) {
1033  disktype = disktype | TDEDiskDeviceType::MediaDevice;
1034  }
1035  if ((devicevendor.upper() == "SANDISK") && (devicemodel.upper().contains("SANSA"))) {
1036  disktype = disktype | TDEDiskDeviceType::MediaDevice;
1037  }
1038 
1039  if (disktypestring.upper() == "TAPE") {
1040  disktype = disktype | TDEDiskDeviceType::Tape;
1041  }
1042 
1043  if ((disktypestring.upper() == "COMPACT_FLASH")
1044  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_CF")) == "1")
1045  || (TQString(udev_device_get_property_value(dev, "ID_ATA_CFA")) == "1")) {
1046  disktype = disktype | TDEDiskDeviceType::CompactFlash;
1047  disktype = disktype | TDEDiskDeviceType::HDD;
1048  }
1049 
1050  if ((disktypestring.upper() == "MEMORY_STICK")
1051  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MS")) == "1")) {
1052  disktype = disktype | TDEDiskDeviceType::MemoryStick;
1053  disktype = disktype | TDEDiskDeviceType::HDD;
1054  }
1055 
1056  if ((disktypestring.upper() == "SMART_MEDIA")
1057  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SM")) == "1")) {
1058  disktype = disktype | TDEDiskDeviceType::SmartMedia;
1059  disktype = disktype | TDEDiskDeviceType::HDD;
1060  }
1061 
1062  if ((disktypestring.upper() == "SD_MMC")
1063  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SD")) == "1")
1064  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SDHC")) == "1")
1065  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MMC")) == "1")) {
1066  disktype = disktype | TDEDiskDeviceType::SDMMC;
1067  disktype = disktype | TDEDiskDeviceType::HDD;
1068  }
1069 
1070  if ((disktypestring.upper() == "FLASHKEY")
1071  || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH")) == "1")) {
1072  disktype = disktype | TDEDiskDeviceType::Flash;
1073  disktype = disktype | TDEDiskDeviceType::HDD;
1074  }
1075 
1076  if (disktypestring.upper() == "OPTICAL") {
1077  disktype = disktype | TDEDiskDeviceType::Optical;
1078  }
1079 
1080  if (disktypestring.upper() == "JAZ") {
1081  disktype = disktype | TDEDiskDeviceType::Jaz;
1082  }
1083 
1084  if (disktypestring.upper() == "CD") {
1085  disktype = disktype | TDEDiskDeviceType::Optical;
1086 
1087  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) == "1") {
1088  disktype = disktype | TDEDiskDeviceType::CDROM;
1089  }
1090  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_R")) == "1") {
1091  disktype = disktype | TDEDiskDeviceType::CDR;
1092  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1093  }
1094  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_RW")) == "1") {
1095  disktype = disktype | TDEDiskDeviceType::CDRW;
1096  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1097  disktype = disktype & ~TDEDiskDeviceType::CDR;
1098  }
1099  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW")) == "1") {
1100  disktype = disktype | TDEDiskDeviceType::CDMRRW;
1101  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1102  disktype = disktype & ~TDEDiskDeviceType::CDR;
1103  disktype = disktype & ~TDEDiskDeviceType::CDRW;
1104  }
1105  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW_W")) == "1") {
1106  disktype = disktype | TDEDiskDeviceType::CDMRRWW;
1107  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1108  disktype = disktype & ~TDEDiskDeviceType::CDR;
1109  disktype = disktype & ~TDEDiskDeviceType::CDRW;
1110  disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
1111  }
1112  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MO")) == "1") {
1113  disktype = disktype | TDEDiskDeviceType::CDMO;
1114  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1115  disktype = disktype & ~TDEDiskDeviceType::CDR;
1116  disktype = disktype & ~TDEDiskDeviceType::CDRW;
1117  disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
1118  disktype = disktype & ~TDEDiskDeviceType::CDMRRWW;
1119  }
1120  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD")) == "1") {
1121  disktype = disktype | TDEDiskDeviceType::DVDROM;
1122  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1123  }
1124  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RAM")) == "1") {
1125  disktype = disktype | TDEDiskDeviceType::DVDRAM;
1126  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1127  }
1128  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R")) == "1") {
1129  disktype = disktype | TDEDiskDeviceType::DVDR;
1130  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1131  }
1132  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R_DL")) == "1") {
1133  disktype = disktype | TDEDiskDeviceType::DVDRDL;
1134  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1135  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1136  }
1137  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R")) == "1") {
1138  disktype = disktype | TDEDiskDeviceType::DVDPLUSR;
1139  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1140  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1141  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1142  }
1143  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R_DL")) == "1") {
1144  disktype = disktype | TDEDiskDeviceType::DVDPLUSRDL;
1145  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1146  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1147  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1148  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1149  }
1150  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW")) == "1") {
1151  disktype = disktype | TDEDiskDeviceType::DVDRW;
1152  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1153  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1154  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1155  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1156  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1157  }
1158  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW_DL")) == "1") {
1159  disktype = disktype | TDEDiskDeviceType::DVDRWDL;
1160  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1161  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1162  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1163  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1164  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1165  disktype = disktype & ~TDEDiskDeviceType::DVDRW;
1166  }
1167  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW")) == "1") {
1168  disktype = disktype | TDEDiskDeviceType::DVDPLUSRW;
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  disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
1176  }
1177  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW_DL")) == "1") {
1178  disktype = disktype | TDEDiskDeviceType::DVDPLUSRWDL;
1179  disktype = disktype & ~TDEDiskDeviceType::DVDROM;
1180  disktype = disktype & ~TDEDiskDeviceType::DVDR;
1181  disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
1182  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
1183  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
1184  disktype = disktype & ~TDEDiskDeviceType::DVDRW;
1185  disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
1186  disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRW;
1187  }
1188  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD")) == "1") {
1189  disktype = disktype | TDEDiskDeviceType::BDROM;
1190  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1191  }
1192  if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_R")) == "1")
1193  || (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!)
1194  ) {
1195  disktype = disktype | TDEDiskDeviceType::BDR;
1196  disktype = disktype & ~TDEDiskDeviceType::BDROM;
1197  }
1198  if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_RE")) == "1")
1199  || (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!)
1200  ) {
1201  disktype = disktype | TDEDiskDeviceType::BDRW;
1202  disktype = disktype & ~TDEDiskDeviceType::BDROM;
1203  disktype = disktype & ~TDEDiskDeviceType::BDR;
1204  }
1205  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD")) == "1") {
1206  disktype = disktype | TDEDiskDeviceType::HDDVDROM;
1207  disktype = disktype & ~TDEDiskDeviceType::CDROM;
1208  }
1209  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_R")) == "1") {
1210  disktype = disktype | TDEDiskDeviceType::HDDVDR;
1211  disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
1212  }
1213  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_RW")) == "1") {
1214  disktype = disktype | TDEDiskDeviceType::HDDVDRW;
1215  disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
1216  disktype = disktype & ~TDEDiskDeviceType::HDDVDR;
1217  }
1218  if (!TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO")).isNull()) {
1219  disktype = disktype | TDEDiskDeviceType::CDAudio;
1220  }
1221  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")) {
1222  disktype = disktype | TDEDiskDeviceType::CDVideo;
1223  }
1224 
1225  if ((disktype & TDEDiskDeviceType::DVDROM)
1226  || (disktype & TDEDiskDeviceType::DVDRAM)
1227  || (disktype & TDEDiskDeviceType::DVDR)
1228  || (disktype & TDEDiskDeviceType::DVDRW)
1229  || (disktype & TDEDiskDeviceType::DVDRDL)
1230  || (disktype & TDEDiskDeviceType::DVDRWDL)
1231  || (disktype & TDEDiskDeviceType::DVDPLUSR)
1232  || (disktype & TDEDiskDeviceType::DVDPLUSRW)
1233  || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
1234  || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
1235  ) {
1236  // Every VideoDVD must have a VIDEO_TS.IFO file
1237  // Read this info via tdeiso_info, since udev couldn't be bothered to check DVD type on its own
1238  int retcode = system(TQString("tdeiso_info --exists=ISO9660/VIDEO_TS/VIDEO_TS.IFO %1").arg(devicenode).ascii());
1239  if (retcode == 0) {
1240  disktype = disktype | TDEDiskDeviceType::DVDVideo;
1241  }
1242  }
1243 
1244  }
1245 
1246  // Detect RAM and Loop devices, since udev can't seem to...
1247  if (systempath.startsWith("/sys/devices/virtual/block/ram")) {
1248  disktype = disktype | TDEDiskDeviceType::RAM;
1249  }
1250  if (systempath.startsWith("/sys/devices/virtual/block/loop")) {
1251  disktype = disktype | TDEDiskDeviceType::Loop;
1252  }
1253 
1254  if (disktype == TDEDiskDeviceType::Null) {
1255  // Fallback
1256  // If we can't recognize the disk type then set it as a simple HDD volume
1257  disktype = disktype | TDEDiskDeviceType::HDD;
1258  }
1259 
1260  if (filesystemtype.upper() == "CRYPTO_LUKS") {
1261  disktype = disktype | TDEDiskDeviceType::LUKS;
1262  }
1263  else if (filesystemtype.upper() == "CRYPTO") {
1264  disktype = disktype | TDEDiskDeviceType::OtherCrypted;
1265  }
1266 
1267  return disktype;
1268 }
1269 
1270  // TDEStandardDirs::kde_default
1271 
1272 typedef TQMap<TQString, TQString> TDEConfigMap;
1273 
1274 TQString readUdevAttribute(udev_device* dev, TQString attr) {
1275  return TQString(udev_device_get_property_value(dev, attr.ascii()));
1276 }
1277 
1278 TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQString query) {
1279  TDEGenericDeviceType::TDEGenericDeviceType ret = TDEGenericDeviceType::Other;
1280 
1281  // Keep this in sync with the TDEGenericDeviceType definition in the header
1282  if (query == "Root") {
1283  ret = TDEGenericDeviceType::Root;
1284  }
1285  else if (query == "RootSystem") {
1286  ret = TDEGenericDeviceType::RootSystem;
1287  }
1288  else if (query == "CPU") {
1289  ret = TDEGenericDeviceType::CPU;
1290  }
1291  else if (query == "GPU") {
1292  ret = TDEGenericDeviceType::GPU;
1293  }
1294  else if (query == "RAM") {
1295  ret = TDEGenericDeviceType::RAM;
1296  }
1297  else if (query == "Bus") {
1298  ret = TDEGenericDeviceType::Bus;
1299  }
1300  else if (query == "I2C") {
1301  ret = TDEGenericDeviceType::I2C;
1302  }
1303  else if (query == "MDIO") {
1304  ret = TDEGenericDeviceType::MDIO;
1305  }
1306  else if (query == "Mainboard") {
1307  ret = TDEGenericDeviceType::Mainboard;
1308  }
1309  else if (query == "Disk") {
1310  ret = TDEGenericDeviceType::Disk;
1311  }
1312  else if (query == "SCSI") {
1313  ret = TDEGenericDeviceType::SCSI;
1314  }
1315  else if (query == "StorageController") {
1316  ret = TDEGenericDeviceType::StorageController;
1317  }
1318  else if (query == "Mouse") {
1319  ret = TDEGenericDeviceType::Mouse;
1320  }
1321  else if (query == "Keyboard") {
1322  ret = TDEGenericDeviceType::Keyboard;
1323  }
1324  else if (query == "HID") {
1325  ret = TDEGenericDeviceType::HID;
1326  }
1327  else if (query == "Modem") {
1328  ret = TDEGenericDeviceType::Modem;
1329  }
1330  else if (query == "Monitor") {
1331  ret = TDEGenericDeviceType::Monitor;
1332  }
1333  else if (query == "Network") {
1334  ret = TDEGenericDeviceType::Network;
1335  }
1336  else if (query == "Printer") {
1337  ret = TDEGenericDeviceType::Printer;
1338  }
1339  else if (query == "Scanner") {
1340  ret = TDEGenericDeviceType::Scanner;
1341  }
1342  else if (query == "Sound") {
1343  ret = TDEGenericDeviceType::Sound;
1344  }
1345  else if (query == "VideoCapture") {
1346  ret = TDEGenericDeviceType::VideoCapture;
1347  }
1348  else if (query == "IEEE1394") {
1349  ret = TDEGenericDeviceType::IEEE1394;
1350  }
1351  else if (query == "PCMCIA") {
1352  ret = TDEGenericDeviceType::PCMCIA;
1353  }
1354  else if (query == "Camera") {
1355  ret = TDEGenericDeviceType::Camera;
1356  }
1357  else if (query == "Serial") {
1358  ret = TDEGenericDeviceType::Serial;
1359  }
1360  else if (query == "Parallel") {
1361  ret = TDEGenericDeviceType::Parallel;
1362  }
1363  else if (query == "TextIO") {
1364  ret = TDEGenericDeviceType::TextIO;
1365  }
1366  else if (query == "Peripheral") {
1367  ret = TDEGenericDeviceType::Peripheral;
1368  }
1369  else if (query == "Backlight") {
1370  ret = TDEGenericDeviceType::Backlight;
1371  }
1372  else if (query == "Battery") {
1373  ret = TDEGenericDeviceType::Battery;
1374  }
1375  else if (query == "Power") {
1376  ret = TDEGenericDeviceType::PowerSupply;
1377  }
1378  else if (query == "Dock") {
1379  ret = TDEGenericDeviceType::Dock;
1380  }
1381  else if (query == "ThermalSensor") {
1382  ret = TDEGenericDeviceType::ThermalSensor;
1383  }
1384  else if (query == "ThermalControl") {
1385  ret = TDEGenericDeviceType::ThermalControl;
1386  }
1387  else if (query == "Bluetooth") {
1388  ret = TDEGenericDeviceType::BlueTooth;
1389  }
1390  else if (query == "Bridge") {
1391  ret = TDEGenericDeviceType::Bridge;
1392  }
1393  else if (query == "Platform") {
1394  ret = TDEGenericDeviceType::Platform;
1395  }
1396  else if (query == "Cryptography") {
1397  ret = TDEGenericDeviceType::Cryptography;
1398  }
1399  else if (query == "Event") {
1400  ret = TDEGenericDeviceType::Event;
1401  }
1402  else if (query == "Input") {
1403  ret = TDEGenericDeviceType::Input;
1404  }
1405  else if (query == "PNP") {
1406  ret = TDEGenericDeviceType::PNP;
1407  }
1408  else if (query == "OtherACPI") {
1409  ret = TDEGenericDeviceType::OtherACPI;
1410  }
1411  else if (query == "OtherUSB") {
1412  ret = TDEGenericDeviceType::OtherUSB;
1413  }
1414  else if (query == "OtherMultimedia") {
1415  ret = TDEGenericDeviceType::OtherMultimedia;
1416  }
1417  else if (query == "OtherPeripheral") {
1418  ret = TDEGenericDeviceType::OtherPeripheral;
1419  }
1420  else if (query == "OtherSensor") {
1421  ret = TDEGenericDeviceType::OtherSensor;
1422  }
1423  else if (query == "OtherVirtual") {
1424  ret = TDEGenericDeviceType::OtherVirtual;
1425  }
1426  else {
1427  ret = TDEGenericDeviceType::Other;
1428  }
1429 
1430  return ret;
1431 }
1432 
1433 TDEDiskDeviceType::TDEDiskDeviceType readDiskDeviceSubtypeFromString(TQString query, TDEDiskDeviceType::TDEDiskDeviceType flagsIn=TDEDiskDeviceType::Null) {
1434  TDEDiskDeviceType::TDEDiskDeviceType ret = flagsIn;
1435 
1436  // Keep this in sync with the TDEDiskDeviceType definition in the header
1437  if (query == "MediaDevice") {
1438  ret = ret | TDEDiskDeviceType::MediaDevice;
1439  }
1440  if (query == "Floppy") {
1441  ret = ret | TDEDiskDeviceType::Floppy;
1442  }
1443  if (query == "CDROM") {
1444  ret = ret | TDEDiskDeviceType::CDROM;
1445  }
1446  if (query == "CDR") {
1447  ret = ret | TDEDiskDeviceType::CDR;
1448  }
1449  if (query == "CDRW") {
1450  ret = ret | TDEDiskDeviceType::CDRW;
1451  }
1452  if (query == "CDMO") {
1453  ret = ret | TDEDiskDeviceType::CDMO;
1454  }
1455  if (query == "CDMRRW") {
1456  ret = ret | TDEDiskDeviceType::CDMRRW;
1457  }
1458  if (query == "CDMRRWW") {
1459  ret = ret | TDEDiskDeviceType::CDMRRWW;
1460  }
1461  if (query == "DVDROM") {
1462  ret = ret | TDEDiskDeviceType::DVDROM;
1463  }
1464  if (query == "DVDRAM") {
1465  ret = ret | TDEDiskDeviceType::DVDRAM;
1466  }
1467  if (query == "DVDR") {
1468  ret = ret | TDEDiskDeviceType::DVDR;
1469  }
1470  if (query == "DVDRW") {
1471  ret = ret | TDEDiskDeviceType::DVDRW;
1472  }
1473  if (query == "DVDRDL") {
1474  ret = ret | TDEDiskDeviceType::DVDRDL;
1475  }
1476  if (query == "DVDRWDL") {
1477  ret = ret | TDEDiskDeviceType::DVDRWDL;
1478  }
1479  if (query == "DVDPLUSR") {
1480  ret = ret | TDEDiskDeviceType::DVDPLUSR;
1481  }
1482  if (query == "DVDPLUSRW") {
1483  ret = ret | TDEDiskDeviceType::DVDPLUSRW;
1484  }
1485  if (query == "DVDPLUSRDL") {
1486  ret = ret | TDEDiskDeviceType::DVDPLUSRDL;
1487  }
1488  if (query == "DVDPLUSRWDL") {
1489  ret = ret | TDEDiskDeviceType::DVDPLUSRWDL;
1490  }
1491  if (query == "BDROM") {
1492  ret = ret | TDEDiskDeviceType::BDROM;
1493  }
1494  if (query == "BDR") {
1495  ret = ret | TDEDiskDeviceType::BDR;
1496  }
1497  if (query == "BDRW") {
1498  ret = ret | TDEDiskDeviceType::BDRW;
1499  }
1500  if (query == "HDDVDROM") {
1501  ret = ret | TDEDiskDeviceType::HDDVDROM;
1502  }
1503  if (query == "HDDVDR") {
1504  ret = ret | TDEDiskDeviceType::HDDVDR;
1505  }
1506  if (query == "HDDVDRW") {
1507  ret = ret | TDEDiskDeviceType::HDDVDRW;
1508  }
1509  if (query == "Zip") {
1510  ret = ret | TDEDiskDeviceType::Zip;
1511  }
1512  if (query == "Jaz") {
1513  ret = ret | TDEDiskDeviceType::Jaz;
1514  }
1515  if (query == "Camera") {
1516  ret = ret | TDEDiskDeviceType::Camera;
1517  }
1518  if (query == "LUKS") {
1519  ret = ret | TDEDiskDeviceType::LUKS;
1520  }
1521  if (query == "OtherCrypted") {
1522  ret = ret | TDEDiskDeviceType::OtherCrypted;
1523  }
1524  if (query == "CDAudio") {
1525  ret = ret | TDEDiskDeviceType::CDAudio;
1526  }
1527  if (query == "CDVideo") {
1528  ret = ret | TDEDiskDeviceType::CDVideo;
1529  }
1530  if (query == "DVDVideo") {
1531  ret = ret | TDEDiskDeviceType::DVDVideo;
1532  }
1533  if (query == "BDVideo") {
1534  ret = ret | TDEDiskDeviceType::BDVideo;
1535  }
1536  if (query == "Flash") {
1537  ret = ret | TDEDiskDeviceType::Flash;
1538  }
1539  if (query == "USB") {
1540  ret = ret | TDEDiskDeviceType::USB;
1541  }
1542  if (query == "Tape") {
1543  ret = ret | TDEDiskDeviceType::Tape;
1544  }
1545  if (query == "HDD") {
1546  ret = ret | TDEDiskDeviceType::HDD;
1547  }
1548  if (query == "Optical") {
1549  ret = ret | TDEDiskDeviceType::Optical;
1550  }
1551  if (query == "RAM") {
1552  ret = ret | TDEDiskDeviceType::RAM;
1553  }
1554  if (query == "Loop") {
1555  ret = ret | TDEDiskDeviceType::Loop;
1556  }
1557  if (query == "CompactFlash") {
1558  ret = ret | TDEDiskDeviceType::CompactFlash;
1559  }
1560  if (query == "MemoryStick") {
1561  ret = ret | TDEDiskDeviceType::MemoryStick;
1562  }
1563  if (query == "SmartMedia") {
1564  ret = ret | TDEDiskDeviceType::SmartMedia;
1565  }
1566  if (query == "SDMMC") {
1567  ret = ret | TDEDiskDeviceType::SDMMC;
1568  }
1569  if (query == "UnlockedCrypt") {
1570  ret = ret | TDEDiskDeviceType::UnlockedCrypt;
1571  }
1572 
1573  return ret;
1574 }
1575 
1576 TDEGenericDevice* createDeviceObjectForType(TDEGenericDeviceType::TDEGenericDeviceType type) {
1577  TDEGenericDevice* ret = 0;
1578 
1579  if (type == TDEGenericDeviceType::Disk) {
1580  ret = new TDEStorageDevice(type);
1581  }
1582  else {
1583  ret = new TDEGenericDevice(type);
1584  }
1585 
1586  return ret;
1587 }
1588 
1589 TDEGenericDevice* TDEHardwareDevices::classifyUnknownDeviceByExternalRules(udev_device* dev, TDEGenericDevice* existingdevice, bool classifySubDevices) {
1590  // This routine expects to see the hardware config files into <prefix>/share/apps/tdehwlib/deviceclasses/, suffixed with "hwclass"
1591  TDEGenericDevice* device = existingdevice;
1592  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
1593 
1594  // Handle subtype if needed/desired
1595  // To speed things up we rely on the prior scan results stored in m_externalSubtype
1596  if (classifySubDevices) {
1597  if (!device->m_externalRulesFile.isNull()) {
1598  if (device->type() == TDEGenericDeviceType::Disk) {
1599  // Disk class
1600  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
1601  TQStringList subtype = device->m_externalSubtype;
1602  TDEDiskDeviceType::TDEDiskDeviceType desiredSubdeviceType = TDEDiskDeviceType::Null;
1603  if (subtype.count()>0) {
1604  for ( TQStringList::Iterator paramit = subtype.begin(); paramit != subtype.end(); ++paramit ) {
1605  desiredSubdeviceType = readDiskDeviceSubtypeFromString(*paramit, desiredSubdeviceType);
1606  }
1607  if (desiredSubdeviceType != sdevice->diskType()) {
1608  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);
1609  sdevice->internalSetDiskType(desiredSubdeviceType);
1610  }
1611  }
1612  }
1613  }
1614  }
1615  else {
1616  TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
1617  TQString hardware_info_directory_suffix("tdehwlib/deviceclasses/");
1618  TQString hardware_info_directory;
1619 
1620  // Scan the hardware_info_directory for configuration files
1621  // For each one, open it with TDEConfig() and apply its rules to classify the device
1622  // FIXME
1623  // Should this also scan up to <n> subdirectories for the files? That feature might end up being too expensive...
1624 
1625  device->m_externalRulesFile = TQString::null;
1626  for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
1627  hardware_info_directory = (*it);
1628  hardware_info_directory += hardware_info_directory_suffix;
1629 
1630  if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
1631  TQDir d(hardware_info_directory);
1632  d.setFilter( TQDir::Files | TQDir::Hidden );
1633 
1634  const TQFileInfoList *list = d.entryInfoList();
1635  TQFileInfoListIterator it( *list );
1636  TQFileInfo *fi;
1637 
1638  while ((fi = it.current()) != 0) {
1639  if (fi->extension(false) == "hwclass") {
1640  bool match = true;
1641 
1642  // Open the rules file
1643  TDEConfig rulesFile(fi->absFilePath(), true, false);
1644  rulesFile.setGroup("Conditions");
1645  TDEConfigMap conditionmap = rulesFile.entryMap("Conditions");
1646  TDEConfigMap::Iterator cndit;
1647  for (cndit = conditionmap.begin(); cndit != conditionmap.end(); ++cndit) {
1648  TQStringList conditionList = TQStringList::split(',', cndit.data(), false);
1649  bool atleastonematch = false;
1650  bool allmatch = true;
1651  TQString matchtype = rulesFile.readEntry("MATCH_TYPE", "All");
1652  if (conditionList.count() < 1) {
1653  allmatch = false;
1654  }
1655  else {
1656  for ( TQStringList::Iterator paramit = conditionList.begin(); paramit != conditionList.end(); ++paramit ) {
1657  if ((*paramit) == "MatchType") {
1658  continue;
1659  }
1660  if (cndit.key() == "VENDOR_ID") {
1661  if (device->vendorID() == (*paramit)) {
1662  atleastonematch = true;
1663  }
1664  else {
1665  allmatch = false;
1666  }
1667  }
1668  else if (cndit.key() == "MODEL_ID") {
1669  if (device->modelID() == (*paramit)) {
1670  atleastonematch = true;
1671  }
1672  else {
1673  allmatch = false;
1674  }
1675  }
1676  else if (cndit.key() == "DRIVER") {
1677  if (device->deviceDriver() == (*paramit)) {
1678  atleastonematch = true;
1679  }
1680  else {
1681  allmatch = false;
1682  }
1683  }
1684  else {
1685  if (readUdevAttribute(dev, cndit.key()) == (*paramit)) {
1686  atleastonematch = true;
1687  }
1688  else {
1689  allmatch = false;
1690  }
1691  }
1692  }
1693  }
1694  if (matchtype == "All") {
1695  if (!allmatch) {
1696  match = false;
1697  }
1698  }
1699  else if (matchtype == "Any") {
1700  if (!atleastonematch) {
1701  match = false;
1702  }
1703  }
1704  else {
1705  match = false;
1706  }
1707  }
1708 
1709  if (match) {
1710  rulesFile.setGroup("DeviceType");
1711  TQString gentype = rulesFile.readEntry("GENTYPE");
1712  TDEGenericDeviceType::TDEGenericDeviceType desiredDeviceType = device->type();
1713  if (!gentype.isNull()) {
1714  desiredDeviceType = readGenericDeviceTypeFromString(gentype);
1715  }
1716 
1717  // Handle main type
1718  if (desiredDeviceType != device->type()) {
1719  printf("[tdehardwaredevices] Rules file %s used to set device type for device at path %s\n", fi->absFilePath().ascii(), device->systemPath().ascii()); fflush(stdout);
1720  if (m_deviceList.contains(device)) {
1721  m_deviceList.remove(device);
1722  }
1723  else {
1724  delete device;
1725  }
1726  device = createDeviceObjectForType(desiredDeviceType);
1727  }
1728 
1729  // Parse subtype and store in m_externalSubtype for later
1730  // This speeds things up considerably due to the expense of the file scanning/parsing/matching operation
1731  device->m_externalSubtype = rulesFile.readListEntry("SUBTYPE", ',');
1732  device->m_externalRulesFile = fi->absFilePath();
1733 
1734  // Process blacklist entries
1735  rulesFile.setGroup("DeviceSettings");
1736  device->internalSetBlacklistedForUpdate(rulesFile.readBoolEntry("UPDATE_BLACKLISTED", device->blacklistedForUpdate()));
1737  }
1738  }
1739  ++it;
1740  }
1741  }
1742  }
1743  }
1744 
1745  return device;
1746 }
1747 
1748 TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice, bool force_full_classification) {
1749  // Classify device and create TDEHW device object
1750  TQString devicename;
1751  TQString devicetype;
1752  TQString devicedriver;
1753  TQString devicesubsystem;
1754  TQString devicenode;
1755  TQString systempath;
1756  TQString devicevendorid;
1757  TQString devicemodelid;
1758  TQString devicevendoridenc;
1759  TQString devicemodelidenc;
1760  TQString devicesubvendorid;
1761  TQString devicesubmodelid;
1762  TQString devicetypestring;
1763  TQString devicetypestring_alt;
1764  TQString devicepciclass;
1765  TDEGenericDevice* device = existingdevice;
1766  bool temp_udev_device = !dev;
1767  if (dev) {
1768  devicename = (udev_device_get_sysname(dev));
1769  devicetype = (udev_device_get_devtype(dev));
1770  devicedriver = (udev_device_get_driver(dev));
1771  devicesubsystem = (udev_device_get_subsystem(dev));
1772  devicenode = (udev_device_get_devnode(dev));
1773  systempath = (udev_device_get_syspath(dev));
1774  systempath += "/";
1775  devicevendorid = (udev_device_get_property_value(dev, "ID_VENDOR_ID"));
1776  devicemodelid = (udev_device_get_property_value(dev, "ID_MODEL_ID"));
1777  devicevendoridenc = (udev_device_get_property_value(dev, "ID_VENDOR_ENC"));
1778  devicemodelidenc = (udev_device_get_property_value(dev, "ID_MODEL_ENC"));
1779  devicesubvendorid = (udev_device_get_property_value(dev, "ID_SUBVENDOR_ID"));
1780  devicesubmodelid = (udev_device_get_property_value(dev, "ID_SUBMODEL_ID"));
1781  devicetypestring = (udev_device_get_property_value(dev, "ID_TYPE"));
1782  devicetypestring_alt = (udev_device_get_property_value(dev, "DEVTYPE"));
1783  devicepciclass = (udev_device_get_property_value(dev, "PCI_CLASS"));
1784  }
1785  else {
1786  if (device) {
1787  devicename = device->name();
1788  devicetype = device->m_udevtype;
1789  devicedriver = device->deviceDriver();
1790  devicesubsystem = device->subsystem();
1791  devicenode = device->deviceNode();
1792  systempath = device->systemPath();
1793  devicevendorid = device->vendorID();
1794  devicemodelid = device->modelID();
1795  devicevendoridenc = device->vendorEncoded();
1796  devicemodelidenc = device->modelEncoded();
1797  devicesubvendorid = device->subVendorID();
1798  devicesubmodelid = device->subModelID();
1799  devicetypestring = device->m_udevdevicetypestring;
1800  devicetypestring_alt = device->udevdevicetypestring_alt;
1801  devicepciclass = device->PCIClass();
1802  }
1803  TQString syspathudev = systempath;
1804  syspathudev.truncate(syspathudev.length()-1); // Remove trailing slash
1805  dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
1806  }
1807 
1808  // FIXME
1809  // Only a small subset of devices are classified right now
1810  // Figure out the remaining udev logic to classify the rest!
1811  // Helpful file: http://www.enlightenment.org/svn/e/trunk/PROTO/enna-explorer/src/bin/udev.c
1812 
1813  bool done = false;
1814  TQString current_path = systempath;
1815  TQString devicemodalias = TQString::null;
1816 
1817  while (done == false) {
1818  TQString malnodename = current_path;
1819  malnodename.append("/modalias");
1820  TQFile malfile(malnodename);
1821  if (malfile.open(IO_ReadOnly)) {
1822  TQTextStream stream( &malfile );
1823  devicemodalias = stream.readLine();
1824  malfile.close();
1825  }
1826  if (devicemodalias.startsWith("pci") || devicemodalias.startsWith("usb")) {
1827  done = true;
1828  }
1829  else {
1830  devicemodalias = TQString::null;
1831  current_path.truncate(current_path.findRev("/"));
1832  if (!current_path.startsWith("/sys/devices")) {
1833  // Abort!
1834  done = true;
1835  }
1836  }
1837  }
1838 
1839  // Many devices do not provide their vendor/model ID via udev
1840  // Worse, sometimes udev provides an invalid model ID!
1841  // Go after it manually if needed...
1842  if (devicevendorid.isNull() || devicemodelid.isNull() || devicemodelid.contains("/")) {
1843  if (devicemodalias != TQString::null) {
1844  // For added fun the device string lengths differ between pci and usb
1845  if (devicemodalias.startsWith("pci")) {
1846  int vloc = devicemodalias.find("v");
1847  int dloc = devicemodalias.find("d", vloc);
1848  int svloc = devicemodalias.find("sv");
1849  int sdloc = devicemodalias.find("sd", vloc);
1850 
1851  devicevendorid = devicemodalias.mid(vloc+1, 8).lower();
1852  devicemodelid = devicemodalias.mid(dloc+1, 8).lower();
1853  if (svloc != -1) {
1854  devicesubvendorid = devicemodalias.mid(svloc+1, 8).lower();
1855  devicesubmodelid = devicemodalias.mid(sdloc+1, 8).lower();
1856  }
1857  devicevendorid.remove(0,4);
1858  devicemodelid.remove(0,4);
1859  devicesubvendorid.remove(0,4);
1860  devicesubmodelid.remove(0,4);
1861  }
1862  if (devicemodalias.startsWith("usb")) {
1863  int vloc = devicemodalias.find("v");
1864  int dloc = devicemodalias.find("p", vloc);
1865  int svloc = devicemodalias.find("sv");
1866  int sdloc = devicemodalias.find("sp", vloc);
1867 
1868  devicevendorid = devicemodalias.mid(vloc+1, 4).lower();
1869  devicemodelid = devicemodalias.mid(dloc+1, 4).lower();
1870  if (svloc != -1) {
1871  devicesubvendorid = devicemodalias.mid(svloc+1, 4).lower();
1872  devicesubmodelid = devicemodalias.mid(sdloc+1, 4).lower();
1873  }
1874  }
1875  }
1876  }
1877 
1878  // Most of the time udev doesn't barf up a device driver either, so go after it manually...
1879  if (devicedriver.isNull()) {
1880  TQString driverSymlink = udev_device_get_syspath(dev);
1881  TQString driverSymlinkDir = driverSymlink;
1882  driverSymlink.append("/device/driver");
1883  driverSymlinkDir.append("/device/");
1884  TQFileInfo dirfi(driverSymlink);
1885  if (dirfi.isSymLink()) {
1886  char* collapsedPath = realpath((driverSymlinkDir + dirfi.readLink()).ascii(), NULL);
1887  devicedriver = TQString(collapsedPath);
1888  free(collapsedPath);
1889  devicedriver.remove(0, devicedriver.findRev("/")+1);
1890  }
1891  }
1892 
1893  // udev removes critical leading zeroes in the PCI device class, so go after it manually...
1894  TQString classnodename = systempath;
1895  classnodename.append("/class");
1896  TQFile classfile( classnodename );
1897  if ( classfile.open( IO_ReadOnly ) ) {
1898  TQTextStream stream( &classfile );
1899  devicepciclass = stream.readLine();
1900  devicepciclass.replace("0x", "");
1901  devicepciclass = devicepciclass.lower();
1902  classfile.close();
1903  }
1904 
1905  // Classify generic device type and create appropriate object
1906 
1907  // Pull out all event special devices and stuff them under Event
1908  TQString syspath_tail = systempath.lower();
1909  syspath_tail.truncate(syspath_tail.length()-1);
1910  syspath_tail.remove(0, syspath_tail.findRev("/")+1);
1911  if (syspath_tail.startsWith("event")) {
1912  if (!device) device = new TDEEventDevice(TDEGenericDeviceType::Event);
1913  }
1914  // Pull out all input special devices and stuff them under Input
1915  if (syspath_tail.startsWith("input")) {
1916  if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
1917  }
1918  // Pull out remote-control devices and stuff them under Input
1919  if (devicesubsystem == "rc") {
1920  if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
1921  }
1922 
1923  // Check for keyboard
1924  // Linux doesn't actually ID the keyboard device itself as such, it instead IDs the input device that is underneath the actual keyboard itseld
1925  // Therefore we need to scan <syspath>/input/input* for the ID_INPUT_KEYBOARD attribute
1926  bool is_keyboard = false;
1927  TQString inputtopdirname = udev_device_get_syspath(dev);
1928  inputtopdirname.append("/input/");
1929  TQDir inputdir(inputtopdirname);
1930  inputdir.setFilter(TQDir::All);
1931  const TQFileInfoList *dirlist = inputdir.entryInfoList();
1932  if (dirlist) {
1933  TQFileInfoListIterator inputdirsit(*dirlist);
1934  TQFileInfo *dirfi;
1935  while ( (dirfi = inputdirsit.current()) != 0 ) {
1936  if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
1937  struct udev_device *slavedev;
1938  slavedev = udev_device_new_from_syspath(m_udevStruct, (inputtopdirname + dirfi->fileName()).ascii());
1939  if (udev_device_get_property_value(slavedev, "ID_INPUT_KEYBOARD") != 0) {
1940  is_keyboard = true;
1941  }
1942  udev_device_unref(slavedev);
1943  }
1944  ++inputdirsit;
1945  }
1946  }
1947  if (is_keyboard) {
1948  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
1949  }
1950 
1951  // Classify specific known devices
1952  if (((devicetype == "disk")
1953  || (devicetype == "partition")
1954  || (devicedriver == "floppy")
1955  || (devicesubsystem == "scsi_disk")
1956  || (devicesubsystem == "scsi_tape"))
1957  && ((devicenode != "")
1958  )) {
1959  if (!device) device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
1960  }
1961  else if (devicetype == "host") {
1962  if (devicesubsystem == "bluetooth") {
1963  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BlueTooth);
1964  }
1965  }
1966  else if (devicetype.isNull()) {
1967  if (devicesubsystem == "acpi") {
1968  // If the ACPI device exposes a system path ending in /PNPxxxx:yy, the device type can be precisely determined
1969  // See ftp://ftp.microsoft.com/developr/drg/plug-and-play/devids.txt for more information
1970  TQString pnpgentype = systempath;
1971  pnpgentype.remove(0, pnpgentype.findRev("/")+1);
1972  pnpgentype.truncate(pnpgentype.find(":"));
1973  if (pnpgentype.startsWith("PNP")) {
1974  // 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
1975  // Furthermore, the "real" device elsewhere almost always has more functionality exposed via sysfs
1976  // Therefore all ACPI subsystem devices should be stuffed in the OtherACPI category and largely ignored
1977  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
1978  }
1979  else {
1980  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
1981  }
1982  }
1983  else if (devicesubsystem == "input") {
1984  // Figure out if this device is a mouse, keyboard, or something else
1985  // Check for mouse
1986  // udev doesn't reliably help here, so guess from the device name
1987  if (systempath.contains("/mouse")) {
1988  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
1989  }
1990  if (!device) {
1991  // Second mouse check
1992  // Look for ID_INPUT_MOUSE property presence
1993  if (udev_device_get_property_value(dev, "ID_INPUT_MOUSE") != 0) {
1994  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
1995  }
1996  }
1997  if (!device) {
1998  // Check for keyboard
1999  // Look for ID_INPUT_KEYBOARD property presence
2000  if (udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD") != 0) {
2001  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
2002  }
2003  }
2004  if (!device) {
2005  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
2006  }
2007  }
2008  else if (devicesubsystem == "tty") {
2009  if (devicenode.contains("/ttyS")) {
2010  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2011  }
2012  else {
2013  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TextIO);
2014  }
2015  }
2016  else if (devicesubsystem == "usb-serial") {
2017  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2018  }
2019  else if ((devicesubsystem == "spi_master")
2020  || (devicesubsystem == "spidev")) {
2021  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2022  }
2023  else if (devicesubsystem == "spi") {
2024  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2025  }
2026  else if (devicesubsystem == "watchdog") {
2027  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2028  }
2029  else if (devicesubsystem == "node") {
2030  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2031  }
2032  else if (devicesubsystem == "regulator") {
2033  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2034  }
2035  else if (devicesubsystem == "memory") {
2036  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2037  }
2038  else if (devicesubsystem == "clockevents") {
2039  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2040  }
2041  else if (devicesubsystem == "thermal") {
2042  // FIXME
2043  // Figure out a way to differentiate between ThermalControl (fans and coolers) and ThermalSensor types
2044  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalControl);
2045  }
2046  else if (devicesubsystem == "hwmon") {
2047  // FIXME
2048  // This might pick up thermal sensors
2049  if (!device) device = new TDESensorDevice(TDEGenericDeviceType::OtherSensor);
2050  }
2051  else if (devicesubsystem == "virtio") {
2052  if (devicedriver == "virtio_blk") {
2053  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
2054  }
2055  if (devicedriver == "virtio_net") {
2056  if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
2057  }
2058  if (devicedriver == "virtio_balloon") {
2059  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
2060  }
2061  }
2062  }
2063 
2064  // Try to at least generally classify unclassified devices
2065  if (device == 0) {
2066  if (devicesubsystem == "backlight") {
2067  if (!device) device = new TDEBacklightDevice(TDEGenericDeviceType::Backlight);
2068  }
2069  if (systempath.lower().startsWith("/sys/module/")
2070  || (systempath.lower().startsWith("/sys/kernel/"))) {
2071  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform); // FIXME Should go into a new kernel module category when the tdelibs ABI can be broken again
2072  }
2073  if ((devicetypestring == "audio")
2074  || (devicesubsystem == "sound")
2075  || (devicesubsystem == "ac97")) {
2076  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Sound);
2077  }
2078  if ((devicesubsystem == "video4linux")
2079  || (devicesubsystem == "dvb")) {
2080  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::VideoCapture);
2081  }
2082  if ((devicetypestring_alt == "scsi_target")
2083  || (devicesubsystem == "scsi_host")
2084  || (devicesubsystem == "scsi_disk")
2085  || (devicesubsystem == "scsi_device")
2086  || (devicesubsystem == "scsi_generic")
2087  || (devicesubsystem == "scsi")
2088  || (devicetypestring_alt == "sas_target")
2089  || (devicesubsystem == "sas_host")
2090  || (devicesubsystem == "sas_port")
2091  || (devicesubsystem == "sas_device")
2092  || (devicesubsystem == "sas_expander")
2093  || (devicesubsystem == "sas_generic")
2094  || (devicesubsystem == "sas_phy")
2095  || (devicesubsystem == "sas_end_device")
2096  || (devicesubsystem == "spi_transport")
2097  || (devicesubsystem == "spi_host")
2098  || (devicesubsystem == "ata_port")
2099  || (devicesubsystem == "ata_link")
2100  || (devicesubsystem == "ata_disk")
2101  || (devicesubsystem == "ata_device")
2102  || (devicesubsystem == "ata")) {
2103  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2104  }
2105  if (devicesubsystem == "infiniband") {
2106  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Peripheral);
2107  }
2108  if ((devicesubsystem == "infiniband_cm")
2109  || (devicesubsystem == "infiniband_mad")
2110  || (devicesubsystem == "infiniband_verbs")) {
2111  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2112  }
2113  if (devicesubsystem == "infiniband_srp") {
2114  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
2115  }
2116  if ((devicesubsystem == "enclosure")
2117  || (devicesubsystem == "clocksource")
2118  || (devicesubsystem == "amba")) {
2119  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2120  }
2121  if ((devicesubsystem == "ipmi")
2122  || (devicesubsystem == "ipmi_si")) {
2123  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
2124  }
2125  if (devicesubsystem == "misc") {
2126  if (devicedriver.startsWith("tpm_")) {
2127  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Cryptography);
2128  }
2129  else {
2130  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2131  }
2132  }
2133  if (devicesubsystem == "leds") {
2134  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
2135  }
2136  if (devicesubsystem == "net") {
2137  if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
2138  }
2139  if ((devicesubsystem == "i2c")
2140  || (devicesubsystem == "i2c-dev")) {
2141  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::I2C);
2142  }
2143  if (devicesubsystem == "mdio_bus") {
2144  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::MDIO);
2145  }
2146  if (devicesubsystem == "graphics") {
2147  if (devicenode.isNull()) { // GPUs do not have associated device nodes
2148  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
2149  }
2150  else {
2151  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2152  }
2153  }
2154  if (devicesubsystem == "tifm_adapter") {
2155  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
2156  }
2157  if ((devicesubsystem == "mmc_host")
2158  || (devicesubsystem == "memstick_host")) {
2159  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
2160  }
2161  if (devicesubsystem == "mmc") {
2162  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2163  }
2164  if ((devicesubsystem == "event_source")
2165  || (devicesubsystem == "rtc")) {
2166  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
2167  }
2168  if (devicesubsystem == "bsg") {
2169  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
2170  }
2171  if (devicesubsystem == "firewire") {
2172  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::IEEE1394);
2173  }
2174  if (devicesubsystem == "drm") {
2175  if (devicenode.isNull()) { // Monitors do not have associated device nodes
2176  if (!device) device = new TDEMonitorDevice(TDEGenericDeviceType::Monitor);
2177  }
2178  else {
2179  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2180  }
2181  }
2182  if (devicesubsystem == "serio") {
2183  if (devicedriver.contains("atkbd")) {
2184  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
2185  }
2186  else if (devicedriver.contains("mouse")) {
2187  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
2188  }
2189  else {
2190  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2191  }
2192  }
2193  if ((devicesubsystem == "ppdev")
2194  || (devicesubsystem == "parport")) {
2195  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Parallel);
2196  }
2197  if (devicesubsystem == "printer") {
2198  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Printer);
2199  }
2200  if (devicesubsystem == "bridge") {
2201  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
2202  }
2203  if ((devicesubsystem == "pci_bus")
2204  || (devicesubsystem == "pci_express")) {
2205  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bus);
2206  }
2207  if (devicesubsystem == "pcmcia_socket") {
2208  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PCMCIA);
2209  }
2210  if (devicesubsystem == "platform") {
2211  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2212  }
2213  if (devicesubsystem == "ieee80211") {
2214  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2215  }
2216  if (devicesubsystem == "rfkill") {
2217  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2218  }
2219  if (devicesubsystem == "machinecheck") {
2220  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2221  }
2222  if (devicesubsystem == "pnp") {
2223  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PNP);
2224  }
2225  if ((devicesubsystem == "hid")
2226  || (devicesubsystem == "hidraw")
2227  || (devicesubsystem == "usbhid")) {
2228  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
2229  }
2230  if (devicesubsystem == "power_supply") {
2231  TQString powersupplyname(udev_device_get_property_value(dev, "POWER_SUPPLY_NAME"));
2232  if ((devicedriver == "ac")
2233  || (devicedriver.contains("charger"))
2234  || (powersupplyname.upper().startsWith("AC"))) {
2235  if (!device) device = new TDEMainsPowerDevice(TDEGenericDeviceType::PowerSupply);
2236  }
2237  else {
2238  if (!device) device = new TDEBatteryDevice(TDEGenericDeviceType::Battery);
2239  }
2240  }
2241  if (systempath.lower().startsWith("/sys/devices/virtual")) {
2242  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherVirtual);
2243  }
2244 
2245  // Moderate accuracy classification, if PCI device class is available
2246  // See http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html for codes and meanings
2247  if (!devicepciclass.isNull()) {
2248  // Pre PCI 2.0
2249  if (devicepciclass.startsWith("0001")) {
2250  if (devicenode.isNull()) { // GPUs do not have associated device nodes
2251  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
2252  }
2253  else {
2254  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2255  }
2256  }
2257  // Post PCI 2.0
2258  TQString devicepcisubclass = devicepciclass;
2259  devicepcisubclass = devicepcisubclass.remove(0,2);
2260  if (devicepciclass.startsWith("01")) {
2261  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
2262  }
2263  if (devicepciclass.startsWith("02")) {
2264  if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
2265  }
2266  if (devicepciclass.startsWith("03")) {
2267  if (devicenode.isNull()) { // GPUs do not have associated device nodes
2268  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
2269  }
2270  else {
2271  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2272  }
2273  }
2274  if (devicepciclass.startsWith("04")) {
2275  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherMultimedia);
2276  }
2277  if (devicepciclass.startsWith("05")) {
2278  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
2279  }
2280  if (devicepciclass.startsWith("06")) {
2281  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
2282  }
2283  if (devicepciclass.startsWith("07")) {
2284  if (devicepcisubclass.startsWith("03")) {
2285  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Modem);
2286  }
2287  }
2288  if (devicepciclass.startsWith("0a")) {
2289  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Dock);
2290  }
2291  if (devicepciclass.startsWith("0b")) {
2292  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::CPU);
2293  }
2294  if (devicepciclass.startsWith("0c")) {
2295  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
2296  }
2297  }
2298 
2299  if ((devicesubsystem == "usb")
2300  && (devicedriver == "uvcvideo")) {
2301  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2302  }
2303 
2304  // Last ditch attempt at classification
2305  // Likely inaccurate and sweeping
2306  if ((devicesubsystem == "usb")
2307  || (devicesubsystem == "usbmisc")
2308  || (devicesubsystem == "usb_device")
2309  || (devicesubsystem == "usbmon")) {
2310  // Get USB interface class for further classification
2311  int usbInterfaceClass = -1;
2312  {
2313  TQFile ifaceprotofile(current_path + "/bInterfaceClass");
2314  if (ifaceprotofile.open(IO_ReadOnly)) {
2315  TQTextStream stream( &ifaceprotofile );
2316  usbInterfaceClass = stream.readLine().toUInt();
2317  ifaceprotofile.close();
2318  }
2319  }
2320  // Get USB interface subclass for further classification
2321  int usbInterfaceSubClass = -1;
2322  {
2323  TQFile ifaceprotofile(current_path + "/bInterfaceSubClass");
2324  if (ifaceprotofile.open(IO_ReadOnly)) {
2325  TQTextStream stream( &ifaceprotofile );
2326  usbInterfaceSubClass = stream.readLine().toUInt();
2327  ifaceprotofile.close();
2328  }
2329  }
2330  // Get USB interface protocol for further classification
2331  int usbInterfaceProtocol = -1;
2332  {
2333  TQFile ifaceprotofile(current_path + "/bInterfaceProtocol");
2334  if (ifaceprotofile.open(IO_ReadOnly)) {
2335  TQTextStream stream( &ifaceprotofile );
2336  usbInterfaceProtocol = stream.readLine().toUInt();
2337  ifaceprotofile.close();
2338  }
2339  }
2340  if ((usbInterfaceClass == 6) && (usbInterfaceSubClass == 1) && (usbInterfaceProtocol == 1)) {
2341  // PictBridge
2342  if (!device) {
2343  device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
2344  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
2345  sdevice->internalSetDiskType(TDEDiskDeviceType::Camera);
2346  TQString parentsyspathudev = systempath;
2347  parentsyspathudev.truncate(parentsyspathudev.length()-1); // Remove trailing slash
2348  parentsyspathudev.truncate(parentsyspathudev.findRev("/"));
2349  struct udev_device *parentdev;
2350  parentdev = udev_device_new_from_syspath(m_udevStruct, parentsyspathudev.ascii());
2351  devicenode = (udev_device_get_devnode(parentdev));
2352  udev_device_unref(parentdev);
2353  }
2354  }
2355  else {
2356  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherUSB);
2357  }
2358  }
2359  if (devicesubsystem == "pci") {
2360  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherPeripheral);
2361  }
2362  if (devicesubsystem == "cpu") {
2363  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
2364  }
2365  }
2366 
2367  if (device == 0) {
2368  // Unhandled
2369  if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
2370  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);
2371  }
2372 
2373  // Root devices are special
2374  if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
2375  systempath = device->systemPath();
2376  }
2377 
2378  // Set preliminary basic device information
2379  device->internalSetName(devicename);
2380  device->internalSetDeviceNode(devicenode);
2381  device->internalSetSystemPath(systempath);
2382  device->internalSetVendorID(devicevendorid);
2383  device->internalSetModelID(devicemodelid);
2384  device->internalSetVendorEncoded(devicevendoridenc);
2385  device->internalSetModelEncoded(devicemodelidenc);
2386  device->internalSetSubVendorID(devicesubvendorid);
2387  device->internalSetSubModelID(devicesubmodelid);
2388  device->internalSetModuleAlias(devicemodalias);
2389  device->internalSetDeviceDriver(devicedriver);
2390  device->internalSetSubsystem(devicesubsystem);
2391  device->internalSetPCIClass(devicepciclass);
2392 
2393  updateBlacklists(device, dev);
2394 
2395  if (force_full_classification) {
2396  // Check external rules for possible device type overrides
2397  device = classifyUnknownDeviceByExternalRules(dev, device, false);
2398  }
2399 
2400  // Internal use only!
2401  device->m_udevtype = devicetype;
2402  device->m_udevdevicetypestring = devicetypestring;
2403  device->udevdevicetypestring_alt = devicetypestring_alt;
2404 
2405  updateExistingDeviceInformation(device, dev);
2406 
2407  if (temp_udev_device) {
2408  udev_device_unref(dev);
2409  }
2410 
2411  return device;
2412 }
2413 
2414 void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* existingdevice, udev_device* dev) {
2415  TQString devicename;
2416  TQString devicetype;
2417  TQString devicedriver;
2418  TQString devicesubsystem;
2419  TQString devicenode;
2420  TQString systempath;
2421  TQString devicevendorid;
2422  TQString devicemodelid;
2423  TQString devicevendoridenc;
2424  TQString devicemodelidenc;
2425  TQString devicesubvendorid;
2426  TQString devicesubmodelid;
2427  TQString devicetypestring;
2428  TQString devicetypestring_alt;
2429  TQString devicepciclass;
2430  TDEGenericDevice* device = existingdevice;
2431  bool temp_udev_device = !dev;
2432 
2433  devicename = device->name();
2434  devicetype = device->m_udevtype;
2435  devicedriver = device->deviceDriver();
2436  devicesubsystem = device->subsystem();
2437  devicenode = device->deviceNode();
2438  systempath = device->systemPath();
2439  devicevendorid = device->vendorID();
2440  devicemodelid = device->modelID();
2441  devicevendoridenc = device->vendorEncoded();
2442  devicemodelidenc = device->modelEncoded();
2443  devicesubvendorid = device->subVendorID();
2444  devicesubmodelid = device->subModelID();
2445  devicetypestring = device->m_udevdevicetypestring;
2446  devicetypestring_alt = device->udevdevicetypestring_alt;
2447  devicepciclass = device->PCIClass();
2448 
2449  if (!dev) {
2450  TQString syspathudev = systempath;
2451  syspathudev.truncate(syspathudev.length()-1); // Remove trailing slash
2452  dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
2453  }
2454 
2455  if (device->type() == TDEGenericDeviceType::Disk) {
2456  TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
2457  if (sdevice->diskType() & TDEDiskDeviceType::Camera) {
2458  // PictBridge cameras are special and should not be classified by standard rules
2459  sdevice->internalSetDiskStatus(TDEDiskDeviceStatus::Removable);
2460  sdevice->internalSetFileSystemName("pictbridge");
2461  }
2462  else {
2463  bool removable = false;
2464  bool hotpluggable = false;
2465 
2466  // We can get the removable flag, but we have no idea if the device has the ability to notify on media insertion/removal
2467  // If there is no such notification possible, then we should not set the removable flag
2468  // udev can be such an amazing pain at times
2469  // It exports a /capabilities node with no info on what the bits actually mean
2470  // This information is very poorly documented as a set of #defines in include/linux/genhd.h
2471  // We are specifically interested in GENHD_FL_REMOVABLE and GENHD_FL_MEDIA_CHANGE_NOTIFY
2472  // The "removable" flag should also really be renamed to "hotpluggable", as that is far more precise...
2473  TQString capabilitynodename = systempath;
2474  capabilitynodename.append("/capability");
2475  TQFile capabilityfile( capabilitynodename );
2476  unsigned int capabilities = 0;
2477  if ( capabilityfile.open( IO_ReadOnly ) ) {
2478  TQTextStream stream( &capabilityfile );
2479  TQString capabilitystring;
2480  capabilitystring = stream.readLine();
2481  capabilities = capabilitystring.toUInt();
2482  capabilityfile.close();
2483  }
2484  if (capabilities & GENHD_FL_REMOVABLE) {
2485  // FIXME
2486  // For added fun this is not always true; i.e. GENHD_FL_REMOVABLE can be set when the device cannot be hotplugged (floppy drives).
2487  hotpluggable = true;
2488  }
2489  if (capabilities & GENHD_FL_MEDIA_CHANGE_NOTIFY) {
2490  removable = true;
2491  }
2492 
2493  // See if any other devices are exclusively using this device, such as the Device Mapper
2494  TQStringList holdingDeviceNodes;
2495  TQString holdersnodename = udev_device_get_syspath(dev);
2496  holdersnodename.append("/holders/");
2497  TQDir holdersdir(holdersnodename);
2498  holdersdir.setFilter(TQDir::All);
2499  const TQFileInfoList *dirlist = holdersdir.entryInfoList();
2500  if (dirlist) {
2501  TQFileInfoListIterator holdersdirit(*dirlist);
2502  TQFileInfo *dirfi;
2503  while ( (dirfi = holdersdirit.current()) != 0 ) {
2504  if (dirfi->isSymLink()) {
2505  char* collapsedPath = realpath((holdersnodename + dirfi->readLink()).ascii(), NULL);
2506  holdingDeviceNodes.append(TQString(collapsedPath));
2507  free(collapsedPath);
2508  }
2509  ++holdersdirit;
2510  }
2511  }
2512 
2513  // See if any other physical devices underlie this device, for example when the Device Mapper is in use
2514  TQStringList slaveDeviceNodes;
2515  TQString slavesnodename = udev_device_get_syspath(dev);
2516  slavesnodename.append("/slaves/");
2517  TQDir slavedir(slavesnodename);
2518  slavedir.setFilter(TQDir::All);
2519  dirlist = slavedir.entryInfoList();
2520  if (dirlist) {
2521  TQFileInfoListIterator slavedirit(*dirlist);
2522  TQFileInfo *dirfi;
2523  while ( (dirfi = slavedirit.current()) != 0 ) {
2524  if (dirfi->isSymLink()) {
2525  char* collapsedPath = realpath((slavesnodename + dirfi->readLink()).ascii(), NULL);
2526  slaveDeviceNodes.append(TQString(collapsedPath));
2527  free(collapsedPath);
2528  }
2529  ++slavedirit;
2530  }
2531  }
2532 
2533  // Determine generic disk information
2534  TQString devicevendor(udev_device_get_property_value(dev, "ID_VENDOR"));
2535  TQString devicemodel(udev_device_get_property_value(dev, "ID_MODEL"));
2536  TQString devicebus(udev_device_get_property_value(dev, "ID_BUS"));
2537 
2538  // Get disk specific info
2539  TQString disklabel(decodeHexEncoding(TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))));
2540  if (disklabel == "") {
2541  disklabel = TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL"));
2542  }
2543  TQString diskuuid(udev_device_get_property_value(dev, "ID_FS_UUID"));
2544  TQString filesystemtype(udev_device_get_property_value(dev, "ID_FS_TYPE"));
2545  TQString filesystemusage(udev_device_get_property_value(dev, "ID_FS_USAGE"));
2546 
2547  device->internalSetVendorName(devicevendor);
2548  device->internalSetVendorModel(devicemodel);
2549  device->internalSetDeviceBus(devicebus);
2550 
2551  TDEDiskDeviceType::TDEDiskDeviceType disktype = sdevice->diskType();
2552  TDEDiskDeviceStatus::TDEDiskDeviceStatus diskstatus = TDEDiskDeviceStatus::Null;
2553 
2554  TDEStorageDevice* parentdisk = NULL;
2555  if (!(TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER")).isEmpty())) {
2556  TQString parentsyspath = systempath;
2557  parentsyspath.truncate(parentsyspath.length()-1); // Remove trailing slash
2558  parentsyspath.truncate(parentsyspath.findRev("/"));
2559  parentdisk = static_cast<TDEStorageDevice*>(findBySystemPath(parentsyspath));
2560  }
2561  disktype = classifyDiskType(dev, devicenode, devicebus, devicetypestring, systempath, devicevendor, devicemodel, filesystemtype, devicedriver);
2562  if (parentdisk) {
2563  // Set partition disk type and status based on the parent device
2564  disktype = disktype | parentdisk->diskType();
2565  diskstatus = diskstatus | parentdisk->diskStatus();
2566  }
2567  sdevice->internalSetDiskType(disktype);
2568  device = classifyUnknownDeviceByExternalRules(dev, device, true); // Check external rules for possible subtype overrides
2569  disktype = sdevice->diskType(); // The type can be overridden by an external rule
2570 
2571  if (TQString(udev_device_get_property_value(dev, "UDISKS_IGNORE")) == "1") {
2572  diskstatus = diskstatus | TDEDiskDeviceStatus::Hidden;
2573  }
2574 
2575  if ((disktype & TDEDiskDeviceType::CDROM)
2576  || (disktype & TDEDiskDeviceType::CDR)
2577  || (disktype & TDEDiskDeviceType::CDRW)
2578  || (disktype & TDEDiskDeviceType::CDMO)
2579  || (disktype & TDEDiskDeviceType::CDMRRW)
2580  || (disktype & TDEDiskDeviceType::CDMRRWW)
2581  || (disktype & TDEDiskDeviceType::DVDROM)
2582  || (disktype & TDEDiskDeviceType::DVDRAM)
2583  || (disktype & TDEDiskDeviceType::DVDR)
2584  || (disktype & TDEDiskDeviceType::DVDRW)
2585  || (disktype & TDEDiskDeviceType::DVDRDL)
2586  || (disktype & TDEDiskDeviceType::DVDRWDL)
2587  || (disktype & TDEDiskDeviceType::DVDPLUSR)
2588  || (disktype & TDEDiskDeviceType::DVDPLUSRW)
2589  || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
2590  || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
2591  || (disktype & TDEDiskDeviceType::BDROM)
2592  || (disktype & TDEDiskDeviceType::BDR)
2593  || (disktype & TDEDiskDeviceType::BDRW)
2594  || (disktype & TDEDiskDeviceType::HDDVDROM)
2595  || (disktype & TDEDiskDeviceType::HDDVDR)
2596  || (disktype & TDEDiskDeviceType::HDDVDRW)
2597  || (disktype & TDEDiskDeviceType::CDAudio)
2598  || (disktype & TDEDiskDeviceType::CDVideo)
2599  || (disktype & TDEDiskDeviceType::DVDVideo)
2600  || (disktype & TDEDiskDeviceType::BDVideo)
2601  ) {
2602  // These drives are guaranteed to be optical
2603  disktype = disktype | TDEDiskDeviceType::Optical;
2604  }
2605 
2606  if (disktype & TDEDiskDeviceType::Floppy) {
2607  // Floppy drives don't work well under udev
2608  // I have to look for the block device name manually
2609  TQString floppyblknodename = systempath;
2610  floppyblknodename.append("/block");
2611  TQDir floppyblkdir(floppyblknodename);
2612  floppyblkdir.setFilter(TQDir::All);
2613  const TQFileInfoList *floppyblkdirlist = floppyblkdir.entryInfoList();
2614  if (floppyblkdirlist) {
2615  TQFileInfoListIterator floppyblkdirit(*floppyblkdirlist);
2616  TQFileInfo *dirfi;
2617  while ( (dirfi = floppyblkdirit.current()) != 0 ) {
2618  if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
2619  // Does this routine work with more than one floppy drive in the system?
2620  devicenode = TQString("/dev/").append(dirfi->fileName());
2621  }
2622  ++floppyblkdirit;
2623  }
2624  }
2625 
2626  // Some interesting information can be gleaned from the CMOS type file
2627  // 0 : Defaults
2628  // 1 : 5 1/4 DD
2629  // 2 : 5 1/4 HD
2630  // 3 : 3 1/2 DD
2631  // 4 : 3 1/2 HD
2632  // 5 : 3 1/2 ED
2633  // 6 : 3 1/2 ED
2634  // 16 : unknown or not installed
2635  TQString floppycmsnodename = systempath;
2636  floppycmsnodename.append("/cmos");
2637  TQFile floppycmsfile( floppycmsnodename );
2638  TQString cmosstring;
2639  if ( floppycmsfile.open( IO_ReadOnly ) ) {
2640  TQTextStream stream( &floppycmsfile );
2641  cmosstring = stream.readLine();
2642  floppycmsfile.close();
2643  }
2644  // FIXME
2645  // Do something with the information in cmosstring
2646 
2647  if (devicenode.isNull()) {
2648  // This floppy drive cannot be mounted, so ignore it
2649  disktype = disktype & ~TDEDiskDeviceType::Floppy;
2650  }
2651  }
2652 
2653  if (devicetypestring.upper() == "CD") {
2654  if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_STATE")).upper() == "BLANK") {
2655  diskstatus = diskstatus | TDEDiskDeviceStatus::Blank;
2656  }
2657  sdevice->internalSetMediaInserted((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) != ""));
2658  }
2659 
2660  if (disktype & TDEDiskDeviceType::Zip) {
2661  // A Zip drive does not advertise its status via udev, but it can be guessed from the size parameter
2662  TQString zipnodename = systempath;
2663  zipnodename.append("/size");
2664  TQFile namefile( zipnodename );
2665  TQString zipsize;
2666  if ( namefile.open( IO_ReadOnly ) ) {
2667  TQTextStream stream( &namefile );
2668  zipsize = stream.readLine();
2669  namefile.close();
2670  }
2671  if (!zipsize.isNull()) {
2672  sdevice->internalSetMediaInserted((zipsize.toInt() != 0));
2673  }
2674  }
2675 
2676  if (removable) {
2677  diskstatus = diskstatus | TDEDiskDeviceStatus::Removable;
2678  }
2679  if (hotpluggable) {
2680  diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
2681  }
2682  // Force removable flag for flash disks
2683  // udev reports disks as non-removable for card readers on PCI controllers
2684  if (((disktype & TDEDiskDeviceType::CompactFlash)
2685  || (disktype & TDEDiskDeviceType::MemoryStick)
2686  || (disktype & TDEDiskDeviceType::SmartMedia)
2687  || (disktype & TDEDiskDeviceType::SDMMC))
2688  && !(diskstatus & TDEDiskDeviceStatus::Removable)
2689  && !(diskstatus & TDEDiskDeviceStatus::Hotpluggable)) {
2690  diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
2691  }
2692 
2693  if ((filesystemtype.upper() != "CRYPTO_LUKS") && (filesystemtype.upper() != "CRYPTO") && (filesystemtype.upper() != "SWAP") && (!filesystemtype.isEmpty())) {
2694  diskstatus = diskstatus | TDEDiskDeviceStatus::ContainsFilesystem;
2695  }
2696  else {
2697  diskstatus = diskstatus & ~TDEDiskDeviceStatus::ContainsFilesystem;
2698  }
2699 
2700  // Set mountable flag if device is likely to be mountable
2701  diskstatus = diskstatus | TDEDiskDeviceStatus::Mountable;
2702  if ((devicetypestring.upper().isNull()) && (disktype & TDEDiskDeviceType::HDD)) {
2703  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2704  }
2705  if (removable) {
2706  if (sdevice->mediaInserted()) {
2707  diskstatus = diskstatus | TDEDiskDeviceStatus::Inserted;
2708  }
2709  else {
2710  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2711  }
2712  }
2713  // Swap partitions cannot be mounted
2714  if (filesystemtype.upper() == "SWAP") {
2715  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2716  }
2717  // Partition tables cannot be mounted
2718  if ((TQString(udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE")) != "")
2719  && ((TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")).isEmpty())
2720  || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0x5")
2721  || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0xf")
2722  || (TQString(udev_device_get_property_value(dev, "ID_FS_USAGE")).upper() == "RAID"))) {
2723  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2724  }
2725  // If certain disk types do not report the presence of a filesystem, they are likely not mountable
2726  if ((disktype & TDEDiskDeviceType::HDD) || (disktype & TDEDiskDeviceType::Optical)) {
2727  if (!(diskstatus & TDEDiskDeviceStatus::ContainsFilesystem)) {
2728  diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
2729  }
2730  }
2731 
2732  if (holdingDeviceNodes.count() > 0) {
2733  diskstatus = diskstatus | TDEDiskDeviceStatus::UsedByDevice;
2734  }
2735 
2736  if (slaveDeviceNodes.count() > 0) {
2737  diskstatus = diskstatus | TDEDiskDeviceStatus::UsesDevice;
2738  }
2739 
2740  // See if any slaves were crypted
2741  for ( TQStringList::Iterator slaveit = slaveDeviceNodes.begin(); slaveit != slaveDeviceNodes.end(); ++slaveit ) {
2742  struct udev_device *slavedev;
2743  slavedev = udev_device_new_from_syspath(m_udevStruct, (*slaveit).ascii());
2744  TQString slavediskfstype(udev_device_get_property_value(slavedev, "ID_FS_TYPE"));
2745  if ((slavediskfstype.upper() == "CRYPTO_LUKS") || (slavediskfstype.upper() == "CRYPTO")) {
2746  disktype = disktype | TDEDiskDeviceType::UnlockedCrypt;
2747  // Set disk type based on parent device
2748  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)));
2749  }
2750  udev_device_unref(slavedev);
2751  }
2752 
2753  sdevice->internalSetDiskType(disktype);
2754  sdevice->internalSetDiskUUID(diskuuid);
2755  sdevice->internalSetDiskStatus(diskstatus);
2756  sdevice->internalSetFileSystemName(filesystemtype);
2757  sdevice->internalSetFileSystemUsage(filesystemusage);
2758  sdevice->internalSetSlaveDevices(slaveDeviceNodes);
2759  sdevice->internalSetHoldingDevices(holdingDeviceNodes);
2760 
2761  // Clean up disk label
2762  if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
2763  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDR))
2764  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
2765  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMO))
2766  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRW))
2767  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRWW))
2768  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
2769  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
2770  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDR))
2771  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
2772  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRDL))
2773  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRWDL))
2774  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSR))
2775  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRW))
2776  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRDL))
2777  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRWDL))
2778  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
2779  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDR))
2780  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
2781  || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDROM))
2782  || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDR))
2783  || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDRW))
2784  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
2785  || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
2786  || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
2787  || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
2788  ) {
2789  if (disklabel == "" && sdevice->diskLabel().isNull()) {
2790  // Read the volume label in via volname, since udev couldn't be bothered to do this on its own
2791  FILE *exepipe = popen(((TQString("volname %1").arg(devicenode).ascii())), "r");
2792  if (exepipe) {
2793  char buffer[8092];
2794  disklabel = fgets(buffer, sizeof(buffer), exepipe);
2795  pclose(exepipe);
2796  }
2797  }
2798  }
2799 
2800  sdevice->internalSetDiskLabel(disklabel);
2801  }
2802  }
2803 
2804  if (device->type() == TDEGenericDeviceType::Network) {
2805  // Network devices don't have devices nodes per se, but we can at least return the Linux network name...
2806  TQString potentialdevicenode = systempath;
2807  if (potentialdevicenode.endsWith("/")) potentialdevicenode.truncate(potentialdevicenode.length()-1);
2808  potentialdevicenode.remove(0, potentialdevicenode.findRev("/")+1);
2809  TQString potentialparentnode = systempath;
2810  if (potentialparentnode.endsWith("/")) potentialparentnode.truncate(potentialparentnode.length()-1);
2811  potentialparentnode.remove(0, potentialparentnode.findRev("/", potentialparentnode.findRev("/")-1)+1);
2812  if (potentialparentnode.startsWith("net/")) {
2813  devicenode = potentialdevicenode;
2814  }
2815 
2816  if (devicenode.isNull()) {
2817  // Platform device, not a physical device
2818  // HACK
2819  // This only works because devices of type Platform only access the TDEGenericDevice class!
2820  device->m_deviceType = TDEGenericDeviceType::Platform;
2821  }
2822  else {
2823  // Gather network device information
2824  TDENetworkDevice* ndevice = dynamic_cast<TDENetworkDevice*>(device);
2825  TQString valuesnodename = systempath + "/";
2826  TQDir valuesdir(valuesnodename);
2827  valuesdir.setFilter(TQDir::All);
2828  TQString nodename;
2829  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
2830  if (dirlist) {
2831  TQFileInfoListIterator valuesdirit(*dirlist);
2832  TQFileInfo *dirfi;
2833  while ( (dirfi = valuesdirit.current()) != 0 ) {
2834  nodename = dirfi->fileName();
2835  TQFile file( valuesnodename + nodename );
2836  if ( file.open( IO_ReadOnly ) ) {
2837  TQTextStream stream( &file );
2838  TQString line;
2839  line = stream.readLine();
2840  if (nodename == "address") {
2841  ndevice->internalSetMacAddress(line);
2842  }
2843  else if (nodename == "carrier") {
2844  ndevice->internalSetCarrierPresent(line.toInt());
2845  }
2846  else if (nodename == "dormant") {
2847  ndevice->internalSetDormant(line.toInt());
2848  }
2849  else if (nodename == "operstate") {
2850  TQString friendlyState = line.lower();
2851  friendlyState[0] = friendlyState[0].upper();
2852  ndevice->internalSetState(friendlyState);
2853  }
2854  file.close();
2855  }
2856  ++valuesdirit;
2857  }
2858  }
2859  // Gather connection information such as IP addresses
2860  if ((ndevice->state().upper() == "UP")
2861  || (ndevice->state().upper() == "UNKNOWN")) {
2862  struct ifaddrs *ifaddr, *ifa;
2863  int family, s;
2864  char host[NI_MAXHOST];
2865 
2866  if (getifaddrs(&ifaddr) != -1) {
2867  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
2868  if (ifa->ifa_addr == NULL) {
2869  continue;
2870  }
2871 
2872  family = ifa->ifa_addr->sa_family;
2873 
2874  if (TQString(ifa->ifa_name) == devicenode) {
2875  if ((family == AF_INET) || (family == AF_INET6)) {
2876  s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
2877  if (s == 0) {
2878  TQString address(host);
2879  if (family == AF_INET) {
2880  ndevice->internalSetIpV4Address(address);
2881  }
2882  else if (family == AF_INET6) {
2883  address.truncate(address.findRev("%"));
2884  ndevice->internalSetIpV6Address(address);
2885  }
2886  }
2887  s = getnameinfo(ifa->ifa_netmask, (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->internalSetIpV4Netmask(address);
2892  }
2893  else if (family == AF_INET6) {
2894  address.truncate(address.findRev("%"));
2895  ndevice->internalSetIpV6Netmask(address);
2896  }
2897  }
2898  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);
2899  if (s == 0) {
2900  TQString address(host);
2901  if (family == AF_INET) {
2902  ndevice->internalSetIpV4Broadcast(address);
2903  }
2904  else if (family == AF_INET6) {
2905  address.truncate(address.findRev("%"));
2906  ndevice->internalSetIpV6Broadcast(address);
2907  }
2908  }
2909  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);
2910  if (s == 0) {
2911  TQString address(host);
2912  if (family == AF_INET) {
2913  ndevice->internalSetIpV4Destination(address);
2914  }
2915  else if (family == AF_INET6) {
2916  address.truncate(address.findRev("%"));
2917  ndevice->internalSetIpV6Destination(address);
2918  }
2919  }
2920  }
2921  }
2922  }
2923  }
2924 
2925  freeifaddrs(ifaddr);
2926 
2927  // Gather statistics
2928  TQString valuesnodename = systempath + "/statistics/";
2929  TQDir valuesdir(valuesnodename);
2930  valuesdir.setFilter(TQDir::All);
2931  TQString nodename;
2932  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
2933  if (dirlist) {
2934  TQFileInfoListIterator valuesdirit(*dirlist);
2935  TQFileInfo *dirfi;
2936  while ( (dirfi = valuesdirit.current()) != 0 ) {
2937  nodename = dirfi->fileName();
2938  TQFile file( valuesnodename + nodename );
2939  if ( file.open( IO_ReadOnly ) ) {
2940  TQTextStream stream( &file );
2941  TQString line;
2942  line = stream.readLine();
2943  if (nodename == "rx_bytes") {
2944  ndevice->internalSetRxBytes(line.toDouble());
2945  }
2946  else if (nodename == "tx_bytes") {
2947  ndevice->internalSetTxBytes(line.toDouble());
2948  }
2949  else if (nodename == "rx_packets") {
2950  ndevice->internalSetRxPackets(line.toDouble());
2951  }
2952  else if (nodename == "tx_packets") {
2953  ndevice->internalSetTxPackets(line.toDouble());
2954  }
2955  file.close();
2956  }
2957  ++valuesdirit;
2958  }
2959  }
2960  }
2961  }
2962  }
2963 
2964  if ((device->type() == TDEGenericDeviceType::OtherSensor) || (device->type() == TDEGenericDeviceType::ThermalSensor)) {
2965  // Populate all sensor values
2966  TDESensorClusterMap sensors;
2967  TQString valuesnodename = systempath + "/";
2968  TQDir valuesdir(valuesnodename);
2969  valuesdir.setFilter(TQDir::All);
2970  TQString nodename;
2971  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
2972  if (dirlist) {
2973  TQFileInfoListIterator valuesdirit(*dirlist);
2974  TQFileInfo *dirfi;
2975  while ( (dirfi = valuesdirit.current()) != 0 ) {
2976  nodename = dirfi->fileName();
2977  if (nodename.contains("_")) {
2978  TQFile file( valuesnodename + nodename );
2979  if ( file.open( IO_ReadOnly ) ) {
2980  TQTextStream stream( &file );
2981  TQString line;
2982  line = stream.readLine();
2983  TQStringList sensornodelist = TQStringList::split("_", nodename);
2984  TQString sensornodename = *(sensornodelist.at(0));
2985  TQString sensornodetype = *(sensornodelist.at(1));
2986  double lineValue = line.toDouble();
2987  if (!sensornodename.contains("fan")) {
2988  lineValue = lineValue / 1000.0;
2989  }
2990  if (sensornodetype == "label") {
2991  sensors[sensornodename].label = line;
2992  }
2993  else if (sensornodetype == "input") {
2994  sensors[sensornodename].current = lineValue;
2995  }
2996  else if (sensornodetype == "min") {
2997  sensors[sensornodename].minimum = lineValue;
2998  }
2999  else if (sensornodetype == "max") {
3000  sensors[sensornodename].maximum = lineValue;
3001  }
3002  else if (sensornodetype == "warn") {
3003  sensors[sensornodename].warning = lineValue;
3004  }
3005  else if (sensornodetype == "crit") {
3006  sensors[sensornodename].critical = lineValue;
3007  }
3008  file.close();
3009  }
3010  }
3011  ++valuesdirit;
3012  }
3013  }
3014 
3015  TDESensorDevice* sdevice = dynamic_cast<TDESensorDevice*>(device);
3016  sdevice->internalSetValues(sensors);
3017  }
3018 
3019  if (device->type() == TDEGenericDeviceType::Battery) {
3020  // Populate all battery values
3021  TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(device);
3022  TQString valuesnodename = systempath + "/";
3023  TQDir valuesdir(valuesnodename);
3024  valuesdir.setFilter(TQDir::All);
3025  TQString nodename;
3026  double bdevice_capacity = 0;
3027  double bdevice_voltage = 0;
3028  int bdevice_time_to_empty = 0;
3029  int bdevice_time_to_full = 0;
3030  bool bdevice_has_energy = false;
3031  bool bdevice_has_time_to_empty = false;
3032  bool bdevice_has_time_to_full = false;
3033  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3034  if (dirlist) {
3035  TQFileInfoListIterator valuesdirit(*dirlist);
3036  TQFileInfo *dirfi;
3037  // Get the voltage as first...
3038  TQFile file( valuesnodename + "voltage_now" );
3039  if ( file.open( IO_ReadOnly ) ) {
3040  TQTextStream stream( &file );
3041  TQString line;
3042  line = stream.readLine();
3043  bdevice_voltage = line.toDouble()/1000000.0;
3044  bdevice->internalSetVoltage(bdevice_voltage);
3045  file.close();
3046  }
3047  // ...and then the other values
3048  while ( (dirfi = valuesdirit.current()) != 0 ) {
3049  nodename = dirfi->fileName();
3050  file.setName( valuesnodename + nodename );
3051  if ( file.open( IO_ReadOnly ) ) {
3052  TQTextStream stream( &file );
3053  TQString line;
3054  line = stream.readLine();
3055  if (nodename == "alarm") {
3056  bdevice->internalSetAlarmEnergy(line.toDouble()/1000000.0);
3057  }
3058  else if (nodename == "capacity") {
3059  bdevice_capacity = line.toDouble();
3060  }
3061  else if (nodename == "charge_full") {
3062  bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0);
3063  }
3064  else if (nodename == "energy_full") {
3065  if (bdevice_voltage > 0) {
3066  // Convert from mWh do Ah
3067  bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0/bdevice_voltage);
3068  }
3069  }
3070  else if (nodename == "charge_full_design") {
3071  bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0);
3072  }
3073  else if (nodename == "energy_full_design") {
3074  if (bdevice_voltage > 0) {
3075  // Convert from mWh do Ah
3076  bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0/bdevice_voltage);
3077  }
3078  }
3079  else if (nodename == "charge_now") {
3080  bdevice->internalSetEnergy(line.toDouble()/1000000.0);
3081  bdevice_has_energy = true;
3082  }
3083  else if (nodename == "energy_now") {
3084  if (bdevice_voltage > 0) {
3085  // Convert from mWh do Ah
3086  bdevice->internalSetEnergy(line.toDouble()/1000000.0/bdevice_voltage);
3087  bdevice_has_energy = true;
3088  }
3089  }
3090  else if (nodename == "manufacturer") {
3091  bdevice->internalSetVendorName(line.stripWhiteSpace());
3092  }
3093  else if (nodename == "model_name") {
3094  bdevice->internalSetVendorModel(line.stripWhiteSpace());
3095  }
3096  else if (nodename == "current_now") {
3097  bdevice->internalSetDischargeRate(line.toDouble()/1000000.0);
3098  }
3099  else if (nodename == "power_now") {
3100  if (bdevice_voltage > 0) {
3101  // Convert from mW do A
3102  bdevice->internalSetDischargeRate(line.toDouble()/1000000.0/bdevice_voltage);
3103  }
3104  }
3105  else if (nodename == "present") {
3106  bdevice->internalSetInstalled(line.toInt());
3107  }
3108  else if (nodename == "serial_number") {
3109  bdevice->internalSetSerialNumber(line.stripWhiteSpace());
3110  }
3111  else if (nodename == "status") {
3112  bdevice->internalSetStatus(line);
3113  }
3114  else if (nodename == "technology") {
3115  bdevice->internalSetTechnology(line);
3116  }
3117  else if (nodename == "time_to_empty_now") {
3118  // Convert from minutes to seconds
3119  bdevice_time_to_empty = line.toDouble()*60;
3120  bdevice_has_time_to_empty = true;
3121  }
3122  else if (nodename == "time_to_full_now") {
3123  // Convert from minutes to seconds
3124  bdevice_time_to_full = line.toDouble()*60;
3125  bdevice_has_time_to_full = true;
3126  }
3127  else if (nodename == "voltage_min_design") {
3128  bdevice->internalSetMinimumVoltage(line.toDouble()/1000000.0);
3129  }
3130  file.close();
3131  }
3132  ++valuesdirit;
3133  }
3134  }
3135 
3136  // Calculate current energy if missing
3137  if (!bdevice_has_energy) {
3138  bdevice->internalSetEnergy(bdevice_capacity*bdevice->maximumEnergy()/100);
3139  }
3140 
3141  // Calculate time remaining
3142  // Discharge/charge rate is in amper
3143  // Energy is in amper-hours
3144  // Therefore, energy/rate = time in hours
3145  // Convert to seconds...
3146  if (bdevice->status() == TDEBatteryStatus::Charging) {
3147  if (!bdevice_has_time_to_full && bdevice->dischargeRate() > 0) {
3148  bdevice->internalSetTimeRemaining(((bdevice->maximumEnergy()-bdevice->energy())/bdevice->dischargeRate())*60*60);
3149  }
3150  else {
3151  bdevice->internalSetTimeRemaining(bdevice_time_to_full);
3152  }
3153  }
3154  else {
3155  if (!bdevice_has_time_to_empty && bdevice->dischargeRate() > 0) {
3156  bdevice->internalSetTimeRemaining((bdevice->energy()/bdevice->dischargeRate())*60*60);
3157  }
3158  else {
3159  bdevice->internalSetTimeRemaining(bdevice_time_to_empty);
3160  }
3161  }
3162  }
3163 
3164  if (device->type() == TDEGenericDeviceType::PowerSupply) {
3165  // Populate all power supply values
3166  TDEMainsPowerDevice* pdevice = dynamic_cast<TDEMainsPowerDevice*>(device);
3167  TQString valuesnodename = systempath + "/";
3168  TQDir valuesdir(valuesnodename);
3169  valuesdir.setFilter(TQDir::All);
3170  TQString nodename;
3171  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3172  if (dirlist) {
3173  TQFileInfoListIterator valuesdirit(*dirlist);
3174  TQFileInfo *dirfi;
3175  while ( (dirfi = valuesdirit.current()) != 0 ) {
3176  nodename = dirfi->fileName();
3177  TQFile file( valuesnodename + nodename );
3178  if ( file.open( IO_ReadOnly ) ) {
3179  TQTextStream stream( &file );
3180  TQString line;
3181  line = stream.readLine();
3182  if (nodename == "manufacturer") {
3183  pdevice->internalSetVendorName(line.stripWhiteSpace());
3184  }
3185  else if (nodename == "model_name") {
3186  pdevice->internalSetVendorModel(line.stripWhiteSpace());
3187  }
3188  else if (nodename == "online") {
3189  pdevice->internalSetOnline(line.toInt());
3190  }
3191  else if (nodename == "serial_number") {
3192  pdevice->internalSetSerialNumber(line.stripWhiteSpace());
3193  }
3194  file.close();
3195  }
3196  ++valuesdirit;
3197  }
3198  }
3199  }
3200 
3201  if (device->type() == TDEGenericDeviceType::Backlight) {
3202  // Populate all backlight values
3203  TDEBacklightDevice* bdevice = dynamic_cast<TDEBacklightDevice*>(device);
3204  TQString valuesnodename = systempath + "/";
3205  TQDir valuesdir(valuesnodename);
3206  valuesdir.setFilter(TQDir::All);
3207  TQString nodename;
3208  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3209  if (dirlist) {
3210  TQFileInfoListIterator valuesdirit(*dirlist);
3211  TQFileInfo *dirfi;
3212  while ( (dirfi = valuesdirit.current()) != 0 ) {
3213  nodename = dirfi->fileName();
3214  TQFile file( valuesnodename + nodename );
3215  if ( file.open( IO_ReadOnly ) ) {
3216  TQTextStream stream( &file );
3217  TQString line;
3218  line = stream.readLine();
3219  if (nodename == "bl_power") {
3220  TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
3221  int rpl = line.toInt();
3222  if (rpl == FB_BLANK_UNBLANK) {
3223  pl = TDEDisplayPowerLevel::On;
3224  }
3225  else if (rpl == FB_BLANK_POWERDOWN) {
3226  pl = TDEDisplayPowerLevel::Off;
3227  }
3228  bdevice->internalSetPowerLevel(pl);
3229  }
3230  else if (nodename == "max_brightness") {
3231  bdevice->internalSetMaximumRawBrightness(line.toInt());
3232  }
3233  else if (nodename == "actual_brightness") {
3234  bdevice->internalSetCurrentRawBrightness(line.toInt());
3235  }
3236  file.close();
3237  }
3238  ++valuesdirit;
3239  }
3240  }
3241  }
3242 
3243  if (device->type() == TDEGenericDeviceType::Monitor) {
3244  TDEMonitorDevice* mdevice = dynamic_cast<TDEMonitorDevice*>(device);
3245  TQString valuesnodename = systempath + "/";
3246  TQDir valuesdir(valuesnodename);
3247  valuesdir.setFilter(TQDir::All);
3248  TQString nodename;
3249  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3250  if (dirlist) {
3251  TQFileInfoListIterator valuesdirit(*dirlist);
3252  TQFileInfo *dirfi;
3253  while ( (dirfi = valuesdirit.current()) != 0 ) {
3254  nodename = dirfi->fileName();
3255  TQFile file( valuesnodename + nodename );
3256  if ( file.open( IO_ReadOnly ) ) {
3257  TQTextStream stream( &file );
3258  TQString line;
3259  line = stream.readLine();
3260  if (nodename == "status") {
3261  mdevice->internalSetConnected(line.lower() == "connected");
3262  }
3263  else if (nodename == "enabled") {
3264  mdevice->internalSetEnabled(line.lower() == "enabled");
3265  }
3266  else if (nodename == "modes") {
3267  TQStringList resinfo;
3268  TQStringList resolutionsStringList = line.upper();
3269  while ((!stream.atEnd()) && (!line.isNull())) {
3270  line = stream.readLine();
3271  if (!line.isNull()) {
3272  resolutionsStringList.append(line.upper());
3273  }
3274  }
3275  TDEResolutionList resolutions;
3276  resolutions.clear();
3277  for (TQStringList::Iterator it = resolutionsStringList.begin(); it != resolutionsStringList.end(); ++it) {
3278  resinfo = TQStringList::split('X', *it, true);
3279  resolutions.append(TDEResolutionPair((*(resinfo.at(0))).toUInt(), (*(resinfo.at(1))).toUInt()));
3280  }
3281  mdevice->internalSetResolutions(resolutions);
3282  }
3283  else if (nodename == "dpms") {
3284  TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
3285  if (line == "On") {
3286  pl = TDEDisplayPowerLevel::On;
3287  }
3288  else if (line == "Standby") {
3289  pl = TDEDisplayPowerLevel::Standby;
3290  }
3291  else if (line == "Suspend") {
3292  pl = TDEDisplayPowerLevel::Suspend;
3293  }
3294  else if (line == "Off") {
3295  pl = TDEDisplayPowerLevel::Off;
3296  }
3297  mdevice->internalSetPowerLevel(pl);
3298  }
3299  file.close();
3300  }
3301  ++valuesdirit;
3302  }
3303  }
3304 
3305  TQString genericPortName = mdevice->systemPath();
3306  genericPortName.remove(0, genericPortName.find("-")+1);
3307  genericPortName.truncate(genericPortName.findRev("-"));
3308  mdevice->internalSetPortType(genericPortName);
3309 
3310  if (mdevice->connected()) {
3311  TQPair<TQString,TQString> monitor_info = getEDIDMonitorName(device->systemPath());
3312  if (!monitor_info.first.isNull()) {
3313  mdevice->internalSetVendorName(monitor_info.first);
3314  mdevice->internalSetVendorModel(monitor_info.second);
3315  mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second;
3316  }
3317  else {
3318  mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName);
3319  }
3320  mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
3321  }
3322  else {
3323  mdevice->m_friendlyName = i18n("Disconnected %1 Port").arg(genericPortName);
3324  mdevice->internalSetEdid(TQByteArray());
3325  mdevice->internalSetResolutions(TDEResolutionList());
3326  }
3327 
3328  // FIXME
3329  // Much of the code in libtderandr should be integrated into/interfaced with this library
3330  }
3331 
3332  if (device->type() == TDEGenericDeviceType::RootSystem) {
3333  // Try to obtain as much generic information about this system as possible
3334  TDERootSystemDevice* rdevice = dynamic_cast<TDERootSystemDevice*>(device);
3335 
3336  // Guess at my form factor
3337  // dmidecode would tell me this, but is somewhat unreliable
3338  TDESystemFormFactor::TDESystemFormFactor formfactor = TDESystemFormFactor::Desktop;
3339  if (listByDeviceClass(TDEGenericDeviceType::Backlight).count() > 0) { // Is this really a good way to determine if a machine is a laptop?
3340  formfactor = TDESystemFormFactor::Laptop;
3341  }
3342  rdevice->internalSetFormFactor(formfactor);
3343 
3344  TQString valuesnodename = "/sys/power/";
3345  TQDir valuesdir(valuesnodename);
3346  valuesdir.setFilter(TQDir::All);
3347  TQString nodename;
3348  const TQFileInfoList *dirlist = valuesdir.entryInfoList();
3349  if (dirlist) {
3350  TQFileInfoListIterator valuesdirit(*dirlist);
3351  TQFileInfo *dirfi;
3352  while ( (dirfi = valuesdirit.current()) != 0 ) {
3353  nodename = dirfi->fileName();
3354  TQFile file( valuesnodename + nodename );
3355  if ( file.open( IO_ReadOnly ) ) {
3356  TQTextStream stream( &file );
3357  TQString line;
3358  line = stream.readLine();
3359  if (nodename == "state") {
3360  TDESystemPowerStateList powerstates;
3361  // Always assume that these two fully on/fully off states are available
3362  powerstates.append(TDESystemPowerState::Active);
3363  powerstates.append(TDESystemPowerState::PowerOff);
3364  if (line.contains("standby")) {
3365  powerstates.append(TDESystemPowerState::Standby);
3366  }
3367  if (line.contains("freeze")) {
3368  powerstates.append(TDESystemPowerState::Freeze);
3369  }
3370  if (line.contains("mem")) {
3371  powerstates.append(TDESystemPowerState::Suspend);
3372  }
3373  if (line.contains("disk")) {
3374  powerstates.append(TDESystemPowerState::Hibernate);
3375  }
3376  rdevice->internalSetPowerStates(powerstates);
3377  }
3378  if (nodename == "disk") {
3379  // Get list of available hibernation methods
3380  TDESystemHibernationMethodList hibernationmethods;
3381  if (line.contains("platform")) {
3382  hibernationmethods.append(TDESystemHibernationMethod::Platform);
3383  }
3384  if (line.contains("shutdown")) {
3385  hibernationmethods.append(TDESystemHibernationMethod::Shutdown);
3386  }
3387  if (line.contains("reboot")) {
3388  hibernationmethods.append(TDESystemHibernationMethod::Reboot);
3389  }
3390  if (line.contains("testproc")) {
3391  hibernationmethods.append(TDESystemHibernationMethod::TestProc);
3392  }
3393  if (line.contains("test")) {
3394  hibernationmethods.append(TDESystemHibernationMethod::Test);
3395  }
3396  rdevice->internalSetHibernationMethods(hibernationmethods);
3397 
3398  // Get current hibernation method
3399  line.truncate(line.findRev("]"));
3400  line.remove(0, line.findRev("[")+1);
3401  TDESystemHibernationMethod::TDESystemHibernationMethod hibernationmethod = TDESystemHibernationMethod::Unsupported;
3402  if (line.contains("platform")) {
3403  hibernationmethod = TDESystemHibernationMethod::Platform;
3404  }
3405  if (line.contains("shutdown")) {
3406  hibernationmethod = TDESystemHibernationMethod::Shutdown;
3407  }
3408  if (line.contains("reboot")) {
3409  hibernationmethod = TDESystemHibernationMethod::Reboot;
3410  }
3411  if (line.contains("testproc")) {
3412  hibernationmethod = TDESystemHibernationMethod::TestProc;
3413  }
3414  if (line.contains("test")) {
3415  hibernationmethod = TDESystemHibernationMethod::Test;
3416  }
3417  rdevice->internalSetHibernationMethod(hibernationmethod);
3418  }
3419  if (nodename == "image_size") {
3420  rdevice->internalSetDiskSpaceNeededForHibernation(line.toULong());
3421  }
3422  file.close();
3423  }
3424  ++valuesdirit;
3425  }
3426  }
3427  }
3428 
3429  // NOTE
3430  // Keep these two handlers (Event and Input) in sync!
3431 
3432  if (device->type() == TDEGenericDeviceType::Event) {
3433  // Try to obtain as much type information about this event device as possible
3434  TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
3435  TDESwitchType::TDESwitchType edevice_switches = edevice->providedSwitches();
3436  if (edevice->systemPath().contains("PNP0C0D")
3437  || (edevice_switches & TDESwitchType::Lid)) {
3438  edevice->internalSetEventType(TDEEventDeviceType::ACPILidSwitch);
3439  }
3440  else if (edevice->systemPath().contains("PNP0C0E")
3441  || edevice->systemPath().contains("/LNXSLPBN")
3442  || (edevice_switches & TDESwitchType::SleepButton)) {
3443  edevice->internalSetEventType(TDEEventDeviceType::ACPISleepButton);
3444  }
3445  else if (edevice->systemPath().contains("PNP0C0C")
3446  || edevice->systemPath().contains("/LNXPWRBN")
3447  || (edevice_switches & TDESwitchType::PowerButton)) {
3448  edevice->internalSetEventType(TDEEventDeviceType::ACPIPowerButton);
3449  }
3450  else if (edevice->systemPath().contains("_acpi")) {
3451  edevice->internalSetEventType(TDEEventDeviceType::ACPIOtherInput);
3452  }
3453  else {
3454  edevice->internalSetEventType(TDEEventDeviceType::Unknown);
3455  }
3456  }
3457 
3458  if (device->type() == TDEGenericDeviceType::Input) {
3459  // Try to obtain as much type information about this input device as possible
3460  TDEInputDevice* idevice = dynamic_cast<TDEInputDevice*>(device);
3461  if (idevice->systemPath().contains("PNP0C0D")) {
3462  idevice->internalSetInputType(TDEInputDeviceType::ACPILidSwitch);
3463  }
3464  else if (idevice->systemPath().contains("PNP0C0E") || idevice->systemPath().contains("/LNXSLPBN")) {
3465  idevice->internalSetInputType(TDEInputDeviceType::ACPISleepButton);
3466  }
3467  else if (idevice->systemPath().contains("PNP0C0C") || idevice->systemPath().contains("/LNXPWRBN")) {
3468  idevice->internalSetInputType(TDEInputDeviceType::ACPIPowerButton);
3469  }
3470  else if (idevice->systemPath().contains("_acpi")) {
3471  idevice->internalSetInputType(TDEInputDeviceType::ACPIOtherInput);
3472  }
3473  else {
3474  idevice->internalSetInputType(TDEInputDeviceType::Unknown);
3475  }
3476  }
3477 
3478  if (device->type() == TDEGenericDeviceType::Event) {
3479  // Try to obtain as much specific information about this event device as possible
3480  TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
3481 
3482  // Try to open input event device
3483  if (edevice->m_fd < 0 && access (edevice->deviceNode().ascii(), R_OK) == 0) {
3484  edevice->m_fd = open(edevice->deviceNode().ascii(), O_RDONLY);
3485  }
3486 
3487  // Start monitoring of input event device
3488  edevice->internalStartMonitoring(this);
3489  }
3490 
3491  // Root devices are still special
3492  if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
3493  systempath = device->systemPath();
3494  }
3495 
3496  // Set basic device information again, as some information may have changed
3497  device->internalSetName(devicename);
3498  device->internalSetDeviceNode(devicenode);
3499  device->internalSetSystemPath(systempath);
3500  device->internalSetVendorID(devicevendorid);
3501  device->internalSetModelID(devicemodelid);
3502  device->internalSetVendorEncoded(devicevendoridenc);
3503  device->internalSetModelEncoded(devicemodelidenc);
3504  device->internalSetSubVendorID(devicesubvendorid);
3505  device->internalSetSubModelID(devicesubmodelid);
3506  device->internalSetDeviceDriver(devicedriver);
3507  device->internalSetSubsystem(devicesubsystem);
3508  device->internalSetPCIClass(devicepciclass);
3509 
3510  // Internal use only!
3511  device->m_udevtype = devicetype;
3512  device->m_udevdevicetypestring = devicetypestring;
3513  device->udevdevicetypestring_alt = devicetypestring_alt;
3514 
3515  if (temp_udev_device) {
3516  udev_device_unref(dev);
3517  }
3518 }
3519 
3520 void TDEHardwareDevices::updateBlacklists(TDEGenericDevice* hwdevice, udev_device* dev) {
3521  // HACK
3522  // I am lucky enough to have a Flash drive that spams udev continually with device change events
3523  // I imagine I am not the only one, so here is a section in which specific devices can be blacklisted!
3524 
3525  // For "U3 System" fake CD
3526  if ((hwdevice->vendorID() == "08ec") && (hwdevice->modelID() == "0020") && (TQString(udev_device_get_property_value(dev, "ID_TYPE")) == "cd")) {
3527  hwdevice->internalSetBlacklistedForUpdate(true);
3528  }
3529 }
3530 
3531 bool TDEHardwareDevices::queryHardwareInformation() {
3532  if (!m_udevStruct) {
3533  return false;
3534  }
3535 
3536  // Prepare the device list for repopulation
3537  m_deviceList.clear();
3538  addCoreSystemDevices();
3539 
3540  struct udev_enumerate *enumerate;
3541  struct udev_list_entry *devices, *dev_list_entry;
3542  struct udev_device *dev;
3543 
3544  // Create a list of all devices
3545  enumerate = udev_enumerate_new(m_udevStruct);
3546  udev_enumerate_add_match_subsystem(enumerate, NULL);
3547  udev_enumerate_scan_devices(enumerate);
3548  devices = udev_enumerate_get_list_entry(enumerate);
3549  // Get detailed information on each detected device
3550  udev_list_entry_foreach(dev_list_entry, devices) {
3551  const char *path;
3552 
3553  // Get the filename of the /sys entry for the device and create a udev_device object (dev) representing it
3554  path = udev_list_entry_get_name(dev_list_entry);
3555  dev = udev_device_new_from_syspath(m_udevStruct, path);
3556 
3557  TDEGenericDevice* device = classifyUnknownDevice(dev);
3558 
3559  // Make sure this device is not a duplicate
3560  TDEGenericDevice *hwdevice;
3561  for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
3562  if (hwdevice->systemPath() == device->systemPath()) {
3563  delete device;
3564  device = 0;
3565  break;
3566  }
3567  }
3568 
3569  if (device) {
3570  m_deviceList.append(device);
3571  }
3572 
3573  udev_device_unref(dev);
3574  }
3575 
3576  // Free the enumerator object
3577  udev_enumerate_unref(enumerate);
3578 
3579  // Update parent/child tables for all devices
3580  updateParentDeviceInformation();
3581 
3582  emit hardwareEvent(TDEHardwareEvent::HardwareListModified, TQString());
3583 
3584  return true;
3585 }
3586 
3587 void TDEHardwareDevices::updateParentDeviceInformation(TDEGenericDevice* hwdevice) {
3588  // Scan for the first path up the sysfs tree that is available in the main hardware table
3589  bool done = false;
3590  TQString current_path = hwdevice->systemPath();
3591  TDEGenericDevice* parentdevice = 0;
3592 
3593  if (current_path.endsWith("/")) {
3594  current_path.truncate(current_path.findRev("/"));
3595  }
3596  while (done == false) {
3597  current_path.truncate(current_path.findRev("/"));
3598  if (current_path.startsWith("/sys/devices")) {
3599  if (current_path.endsWith("/")) {
3600  current_path.truncate(current_path.findRev("/"));
3601  }
3602  parentdevice = findBySystemPath(current_path);
3603  if (parentdevice) {
3604  done = true;
3605  }
3606  }
3607  else {
3608  // Abort!
3609  done = true;
3610  }
3611  }
3612 
3613  hwdevice->internalSetParentDevice(parentdevice);
3614 }
3615 
3616 void TDEHardwareDevices::updateParentDeviceInformation() {
3617  TDEGenericDevice *hwdevice;
3618 
3619  // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
3620  TDEGenericHardwareList devList = listAllPhysicalDevices();
3621  for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
3622  updateParentDeviceInformation(hwdevice);
3623  }
3624 }
3625 
3626 void TDEHardwareDevices::addCoreSystemDevices() {
3627  TDEGenericDevice *hwdevice;
3628 
3629  // Add the Main Root System Device, which provides all other devices
3630  hwdevice = new TDERootSystemDevice(TDEGenericDeviceType::RootSystem);
3631  hwdevice->internalSetSystemPath("/sys/devices");
3632  m_deviceList.append(hwdevice);
3633  rescanDeviceInformation(hwdevice);
3634 
3635  // Add core top-level devices in /sys/devices to the hardware listing
3636  TQStringList holdingDeviceNodes;
3637  TQString devicesnodename = "/sys/devices";
3638  TQDir devicesdir(devicesnodename);
3639  devicesdir.setFilter(TQDir::All);
3640  TQString nodename;
3641  const TQFileInfoList *dirlist = devicesdir.entryInfoList();
3642  if (dirlist) {
3643  TQFileInfoListIterator devicesdirit(*dirlist);
3644  TQFileInfo *dirfi;
3645  while ( (dirfi = devicesdirit.current()) != 0 ) {
3646  nodename = dirfi->fileName();
3647  if (nodename != "." && nodename != "..") {
3648  hwdevice = new TDEGenericDevice(TDEGenericDeviceType::Root);
3649  hwdevice->internalSetSystemPath(dirfi->absFilePath());
3650  m_deviceList.append(hwdevice);
3651  }
3652  ++devicesdirit;
3653  }
3654  }
3655 
3656  // Handle CPUs, which are currently handled terribly by udev
3657  // Parse /proc/cpuinfo to extract some information about the CPUs
3658  hwdevice = 0;
3659  TQDir d("/sys/devices/system/cpu/");
3660  d.setFilter( TQDir::Dirs );
3661  const TQFileInfoList *list = d.entryInfoList();
3662  if (list) {
3663  TQFileInfoListIterator it( *list );
3664  TQFileInfo *fi;
3665  while ((fi = it.current()) != 0) {
3666  TQString directoryName = fi->fileName();
3667  if (directoryName.startsWith("cpu")) {
3668  directoryName = directoryName.remove(0,3);
3669  bool isInt;
3670  int processorNumber = directoryName.toUInt(&isInt, 10);
3671  if (isInt) {
3672  hwdevice = new TDECPUDevice(TDEGenericDeviceType::CPU);
3673  hwdevice->internalSetSystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
3674  m_deviceList.append(hwdevice);
3675  }
3676  }
3677  ++it;
3678  }
3679  }
3680 
3681  // Populate CPU information
3682  processModifiedCPUs();
3683 }
3684 
3685 TQString TDEHardwareDevices::findPCIDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
3686  TQString vendorName = TQString::null;
3687  TQString modelName = TQString::null;
3688  TQString friendlyName = TQString::null;
3689 
3690  if (!pci_id_map) {
3691  pci_id_map = new TDEDeviceIDMap;
3692 
3693  TQString database_filename = "/usr/share/pci.ids";
3694  if (!TQFile::exists(database_filename)) {
3695  database_filename = "/usr/share/misc/pci.ids";
3696  }
3697  if (!TQFile::exists(database_filename)) {
3698  printf("[tdehardwaredevices] Unable to locate PCI information database pci.ids\n"); fflush(stdout);
3699  return i18n("Unknown PCI Device");
3700  }
3701 
3702  TQFile database(database_filename);
3703  if (database.open(IO_ReadOnly)) {
3704  TQTextStream stream(&database);
3705  TQString line;
3706  TQString vendorID;
3707  TQString modelID;
3708  TQString subvendorID;
3709  TQString submodelID;
3710  TQString deviceMapKey;
3711  TQStringList devinfo;
3712  while (!stream.atEnd()) {
3713  line = stream.readLine();
3714  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3715  line.replace("\t", "");
3716  devinfo = TQStringList::split(' ', line, false);
3717  vendorID = *(devinfo.at(0));
3718  vendorName = line;
3719  vendorName.remove(0, vendorName.find(" "));
3720  vendorName = vendorName.stripWhiteSpace();
3721  modelName = TQString::null;
3722  deviceMapKey = vendorID.lower() + ":::";
3723  }
3724  else {
3725  if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
3726  line.replace("\t", "");
3727  devinfo = TQStringList::split(' ', line, false);
3728  modelID = *(devinfo.at(0));
3729  modelName = line;
3730  modelName.remove(0, modelName.find(" "));
3731  modelName = modelName.stripWhiteSpace();
3732  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
3733  }
3734  else {
3735  if (line.upper().startsWith("\t\t")) {
3736  line.replace("\t", "");
3737  devinfo = TQStringList::split(' ', line, false);
3738  subvendorID = *(devinfo.at(0));
3739  submodelID = *(devinfo.at(1));
3740  modelName = line;
3741  modelName.remove(0, modelName.find(" "));
3742  modelName = modelName.stripWhiteSpace();
3743  modelName.remove(0, modelName.find(" "));
3744  modelName = modelName.stripWhiteSpace();
3745  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
3746  }
3747  }
3748  }
3749  if (modelName.isNull()) {
3750  pci_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
3751  }
3752  else {
3753  pci_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
3754  }
3755  }
3756  database.close();
3757  }
3758  else {
3759  printf("[tdehardwaredevices] Unable to open PCI information database %s\n", database_filename.ascii()); fflush(stdout);
3760  }
3761  }
3762 
3763  if (pci_id_map) {
3764  TQString deviceName;
3765  TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
3766 
3767  deviceName = (*pci_id_map)[deviceMapKey];
3768  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3769  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
3770  deviceName = (*pci_id_map)[deviceMapKey];
3771  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3772  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
3773  deviceName = (*pci_id_map)[deviceMapKey];
3774  }
3775  }
3776 
3777  if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3778  deviceName.replace("***UNKNOWN DEVICE*** ", "");
3779  deviceName.prepend(i18n("Unknown PCI Device") + " ");
3780  if (subvendorid.isNull()) {
3781  deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
3782  }
3783  else {
3784  deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
3785  }
3786  }
3787 
3788  return deviceName;
3789  }
3790  else {
3791  return i18n("Unknown PCI Device");
3792  }
3793 }
3794 
3795 TQString TDEHardwareDevices::findUSBDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
3796  TQString vendorName = TQString::null;
3797  TQString modelName = TQString::null;
3798  TQString friendlyName = TQString::null;
3799 
3800  if (!usb_id_map) {
3801  usb_id_map = new TDEDeviceIDMap;
3802 
3803  TQString database_filename = "/usr/share/usb.ids";
3804  if (!TQFile::exists(database_filename)) {
3805  database_filename = "/usr/share/misc/usb.ids";
3806  }
3807  if (!TQFile::exists(database_filename)) {
3808  printf("[tdehardwaredevices] Unable to locate USB information database usb.ids\n"); fflush(stdout);
3809  return i18n("Unknown USB Device");
3810  }
3811 
3812  TQFile database(database_filename);
3813  if (database.open(IO_ReadOnly)) {
3814  TQTextStream stream(&database);
3815  TQString line;
3816  TQString vendorID;
3817  TQString modelID;
3818  TQString subvendorID;
3819  TQString submodelID;
3820  TQString deviceMapKey;
3821  TQStringList devinfo;
3822  while (!stream.atEnd()) {
3823  line = stream.readLine();
3824  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3825  line.replace("\t", "");
3826  devinfo = TQStringList::split(' ', line, false);
3827  vendorID = *(devinfo.at(0));
3828  vendorName = line;
3829  vendorName.remove(0, vendorName.find(" "));
3830  vendorName = vendorName.stripWhiteSpace();
3831  modelName = TQString::null;
3832  deviceMapKey = vendorID.lower() + ":::";
3833  }
3834  else {
3835  if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
3836  line.replace("\t", "");
3837  devinfo = TQStringList::split(' ', line, false);
3838  modelID = *(devinfo.at(0));
3839  modelName = line;
3840  modelName.remove(0, modelName.find(" "));
3841  modelName = modelName.stripWhiteSpace();
3842  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
3843  }
3844  else {
3845  if (line.upper().startsWith("\t\t")) {
3846  line.replace("\t", "");
3847  devinfo = TQStringList::split(' ', line, false);
3848  subvendorID = *(devinfo.at(0));
3849  submodelID = *(devinfo.at(1));
3850  modelName = line;
3851  modelName.remove(0, modelName.find(" "));
3852  modelName = modelName.stripWhiteSpace();
3853  modelName.remove(0, modelName.find(" "));
3854  modelName = modelName.stripWhiteSpace();
3855  deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
3856  }
3857  }
3858  }
3859  if (modelName.isNull()) {
3860  usb_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
3861  }
3862  else {
3863  usb_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
3864  }
3865  }
3866  database.close();
3867  }
3868  else {
3869  printf("[tdehardwaredevices] Unable to open USB information database %s\n", database_filename.ascii()); fflush(stdout);
3870  }
3871  }
3872 
3873  if (usb_id_map) {
3874  TQString deviceName;
3875  TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
3876 
3877  deviceName = (*usb_id_map)[deviceMapKey];
3878  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3879  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
3880  deviceName = (*usb_id_map)[deviceMapKey];
3881  if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3882  deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
3883  deviceName = (*usb_id_map)[deviceMapKey];
3884  }
3885  }
3886 
3887  if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
3888  deviceName.replace("***UNKNOWN DEVICE*** ", "");
3889  deviceName.prepend(i18n("Unknown USB Device") + " ");
3890  if (subvendorid.isNull()) {
3891  deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
3892  }
3893  else {
3894  deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
3895  }
3896  }
3897 
3898  return deviceName;
3899  }
3900  else {
3901  return i18n("Unknown USB Device");
3902  }
3903 }
3904 
3905 TQString TDEHardwareDevices::findPNPDeviceName(TQString pnpid) {
3906  TQString friendlyName = TQString::null;
3907 
3908  if (!pnp_id_map) {
3909  pnp_id_map = new TDEDeviceIDMap;
3910 
3911  TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
3912  TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
3913  TQString hardware_info_directory;
3914  TQString database_filename;
3915 
3916  for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
3917  hardware_info_directory = (*it);
3918  hardware_info_directory += hardware_info_directory_suffix;
3919 
3920  if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
3921  database_filename = hardware_info_directory + "pnp.ids";
3922  if (TQFile::exists(database_filename)) {
3923  break;
3924  }
3925  }
3926  }
3927 
3928  if (!TQFile::exists(database_filename)) {
3929  printf("[tdehardwaredevices] Unable to locate PNP information database pnp.ids\n"); fflush(stdout);
3930  return i18n("Unknown PNP Device");
3931  }
3932 
3933  TQFile database(database_filename);
3934  if (database.open(IO_ReadOnly)) {
3935  TQTextStream stream(&database);
3936  TQString line;
3937  TQString pnpID;
3938  TQString vendorName;
3939  TQString deviceMapKey;
3940  TQStringList devinfo;
3941  while (!stream.atEnd()) {
3942  line = stream.readLine();
3943  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
3944  devinfo = TQStringList::split('\t', line, false);
3945  if (devinfo.count() > 1) {
3946  pnpID = *(devinfo.at(0));
3947  vendorName = *(devinfo.at(1));;
3948  vendorName = vendorName.stripWhiteSpace();
3949  deviceMapKey = pnpID.upper().stripWhiteSpace();
3950  if (!deviceMapKey.isNull()) {
3951  pnp_id_map->insert(deviceMapKey, vendorName, true);
3952  }
3953  }
3954  }
3955  }
3956  database.close();
3957  }
3958  else {
3959  printf("[tdehardwaredevices] Unable to open PNP information database %s\n", database_filename.ascii()); fflush(stdout);
3960  }
3961  }
3962 
3963  if (pnp_id_map) {
3964  TQString deviceName;
3965 
3966  deviceName = (*pnp_id_map)[pnpid];
3967 
3968  return deviceName;
3969  }
3970  else {
3971  return i18n("Unknown PNP Device");
3972  }
3973 }
3974 
3975 TQString TDEHardwareDevices::findMonitorManufacturerName(TQString dpyid) {
3976  TQString friendlyName = TQString::null;
3977 
3978  if (!dpy_id_map) {
3979  dpy_id_map = new TDEDeviceIDMap;
3980 
3981  TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
3982  TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
3983  TQString hardware_info_directory;
3984  TQString database_filename;
3985 
3986  for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
3987  hardware_info_directory = (*it);
3988  hardware_info_directory += hardware_info_directory_suffix;
3989 
3990  if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
3991  database_filename = hardware_info_directory + "dpy.ids";
3992  if (TQFile::exists(database_filename)) {
3993  break;
3994  }
3995  }
3996  }
3997 
3998  if (!TQFile::exists(database_filename)) {
3999  printf("[tdehardwaredevices] Unable to locate monitor information database dpy.ids\n"); fflush(stdout);
4000  return i18n("Unknown Monitor Device");
4001  }
4002 
4003  TQFile database(database_filename);
4004  if (database.open(IO_ReadOnly)) {
4005  TQTextStream stream(&database);
4006  TQString line;
4007  TQString dpyID;
4008  TQString vendorName;
4009  TQString deviceMapKey;
4010  TQStringList devinfo;
4011  while (!stream.atEnd()) {
4012  line = stream.readLine();
4013  if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
4014  devinfo = TQStringList::split('\t', line, false);
4015  if (devinfo.count() > 1) {
4016  dpyID = *(devinfo.at(0));
4017  vendorName = *(devinfo.at(1));;
4018  vendorName = vendorName.stripWhiteSpace();
4019  deviceMapKey = dpyID.upper().stripWhiteSpace();
4020  if (!deviceMapKey.isNull()) {
4021  dpy_id_map->insert(deviceMapKey, vendorName, true);
4022  }
4023  }
4024  }
4025  }
4026  database.close();
4027  }
4028  else {
4029  printf("[tdehardwaredevices] Unable to open monitor information database %s\n", database_filename.ascii()); fflush(stdout);
4030  }
4031  }
4032 
4033  if (dpy_id_map) {
4034  TQString deviceName;
4035 
4036  deviceName = (*dpy_id_map)[dpyid];
4037 
4038  return deviceName;
4039  }
4040  else {
4041  return i18n("Unknown Monitor Device");
4042  }
4043 }
4044 
4045 TQPair<TQString,TQString> TDEHardwareDevices::getEDIDMonitorName(TQString path) {
4046  TQPair<TQString,TQString> edid;
4047  TQByteArray binaryedid = getEDID(path);
4048  if (binaryedid.isNull()) {
4049  return TQPair<TQString,TQString>(TQString::null, TQString::null);
4050  }
4051 
4052  // Get the manufacturer ID
4053  unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
4054  unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
4055  unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
4056  TQChar qletter_1 = TQChar(letter_1);
4057  TQChar qletter_2 = TQChar(letter_2);
4058  TQChar qletter_3 = TQChar(letter_3);
4059  TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
4060 
4061  // Get the model ID
4062  unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
4063  // Reverse the bit order
4064  unsigned int model_id = reverse_bits(raw_model_id);
4065 
4066  // Try to get the model name
4067  bool has_friendly_name = false;
4068  unsigned char descriptor_block[18];
4069  int i;
4070  for (i=72;i<90;i++) {
4071  descriptor_block[i-72] = binaryedid[i] & 0xFF;
4072  }
4073  if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
4074  for (i=90;i<108;i++) {
4075  descriptor_block[i-90] = binaryedid[i] & 0xFF;
4076  }
4077  if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
4078  for (i=108;i<126;i++) {
4079  descriptor_block[i-108] = binaryedid[i] & 0xFF;
4080  }
4081  }
4082  }
4083 
4084  TQString monitor_name;
4085  if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
4086  char* pos = strchr((char *)(descriptor_block+5), '\n');
4087  if (pos) {
4088  *pos = 0;
4089  has_friendly_name = true;
4090  monitor_name = TQString((char *)(descriptor_block+5));
4091  }
4092  else {
4093  has_friendly_name = false;
4094  }
4095  }
4096 
4097  // Look up manufacturer name
4098  TQString manufacturer_name = findMonitorManufacturerName(manufacturer_id);
4099  if (manufacturer_name.isNull()) {
4100  manufacturer_name = manufacturer_id;
4101  }
4102 
4103  if (has_friendly_name) {
4104  edid.first = TQString("%1").arg(manufacturer_name);
4105  edid.second = TQString("%2").arg(monitor_name);
4106  }
4107  else {
4108  edid.first = TQString("%1").arg(manufacturer_name);
4109  edid.second = TQString("0x%2").arg(model_id, 0, 16);
4110  }
4111 
4112  return edid;
4113 }
4114 
4115 TQByteArray TDEHardwareDevices::getEDID(TQString path) {
4116  TQFile file(TQString("%1/edid").arg(path));
4117  if (!file.open (IO_ReadOnly)) {
4118  return TQByteArray();
4119  }
4120  TQByteArray binaryedid = file.readAll();
4121  file.close();
4122  return binaryedid;
4123 }
4124 
4125 TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDeviceType::TDEGenericDeviceType query) {
4126  TQString ret = "Unknown Device";
4127 
4128  // Keep this in sync with the TDEGenericDeviceType definition in the header
4129  if (query == TDEGenericDeviceType::Root) {
4130  ret = i18n("Root");
4131  }
4132  else if (query == TDEGenericDeviceType::RootSystem) {
4133  ret = i18n("System Root");
4134  }
4135  else if (query == TDEGenericDeviceType::CPU) {
4136  ret = i18n("CPU");
4137  }
4138  else if (query == TDEGenericDeviceType::GPU) {
4139  ret = i18n("Graphics Processor");
4140  }
4141  else if (query == TDEGenericDeviceType::RAM) {
4142  ret = i18n("RAM");
4143  }
4144  else if (query == TDEGenericDeviceType::Bus) {
4145  ret = i18n("Bus");
4146  }
4147  else if (query == TDEGenericDeviceType::I2C) {
4148  ret = i18n("I2C Bus");
4149  }
4150  else if (query == TDEGenericDeviceType::MDIO) {
4151  ret = i18n("MDIO Bus");
4152  }
4153  else if (query == TDEGenericDeviceType::Mainboard) {
4154  ret = i18n("Mainboard");
4155  }
4156  else if (query == TDEGenericDeviceType::Disk) {
4157  ret = i18n("Disk");
4158  }
4159  else if (query == TDEGenericDeviceType::SCSI) {
4160  ret = i18n("SCSI");
4161  }
4162  else if (query == TDEGenericDeviceType::StorageController) {
4163  ret = i18n("Storage Controller");
4164  }
4165  else if (query == TDEGenericDeviceType::Mouse) {
4166  ret = i18n("Mouse");
4167  }
4168  else if (query == TDEGenericDeviceType::Keyboard) {
4169  ret = i18n("Keyboard");
4170  }
4171  else if (query == TDEGenericDeviceType::HID) {
4172  ret = i18n("HID");
4173  }
4174  else if (query == TDEGenericDeviceType::Modem) {
4175  ret = i18n("Modem");
4176  }
4177  else if (query == TDEGenericDeviceType::Monitor) {
4178  ret = i18n("Monitor and Display");
4179  }
4180  else if (query == TDEGenericDeviceType::Network) {
4181  ret = i18n("Network");
4182  }
4183  else if (query == TDEGenericDeviceType::Printer) {
4184  ret = i18n("Printer");
4185  }
4186  else if (query == TDEGenericDeviceType::Scanner) {
4187  ret = i18n("Scanner");
4188  }
4189  else if (query == TDEGenericDeviceType::Sound) {
4190  ret = i18n("Sound");
4191  }
4192  else if (query == TDEGenericDeviceType::VideoCapture) {
4193  ret = i18n("Video Capture");
4194  }
4195  else if (query == TDEGenericDeviceType::IEEE1394) {
4196  ret = i18n("IEEE1394");
4197  }
4198  else if (query == TDEGenericDeviceType::PCMCIA) {
4199  ret = i18n("PCMCIA");
4200  }
4201  else if (query == TDEGenericDeviceType::Camera) {
4202  ret = i18n("Camera");
4203  }
4204  else if (query == TDEGenericDeviceType::TextIO) {
4205  ret = i18n("Text I/O");
4206  }
4207  else if (query == TDEGenericDeviceType::Serial) {
4208  ret = i18n("Serial Communications Controller");
4209  }
4210  else if (query == TDEGenericDeviceType::Parallel) {
4211  ret = i18n("Parallel Port");
4212  }
4213  else if (query == TDEGenericDeviceType::Peripheral) {
4214  ret = i18n("Peripheral");
4215  }
4216  else if (query == TDEGenericDeviceType::Backlight) {
4217  ret = i18n("Backlight");
4218  }
4219  else if (query == TDEGenericDeviceType::Battery) {
4220  ret = i18n("Battery");
4221  }
4222  else if (query == TDEGenericDeviceType::PowerSupply) {
4223  ret = i18n("Power Supply");
4224  }
4225  else if (query == TDEGenericDeviceType::Dock) {
4226  ret = i18n("Docking Station");
4227  }
4228  else if (query == TDEGenericDeviceType::ThermalSensor) {
4229  ret = i18n("Thermal Sensor");
4230  }
4231  else if (query == TDEGenericDeviceType::ThermalControl) {
4232  ret = i18n("Thermal Control");
4233  }
4234  else if (query == TDEGenericDeviceType::BlueTooth) {
4235  ret = i18n("Bluetooth");
4236  }
4237  else if (query == TDEGenericDeviceType::Bridge) {
4238  ret = i18n("Bridge");
4239  }
4240  else if (query == TDEGenericDeviceType::Platform) {
4241  ret = i18n("Platform");
4242  }
4243  else if (query == TDEGenericDeviceType::Cryptography) {
4244  ret = i18n("Cryptography");
4245  }
4246  else if (query == TDEGenericDeviceType::Event) {
4247  ret = i18n("Platform Event");
4248  }
4249  else if (query == TDEGenericDeviceType::Input) {
4250  ret = i18n("Platform Input");
4251  }
4252  else if (query == TDEGenericDeviceType::PNP) {
4253  ret = i18n("Plug and Play");
4254  }
4255  else if (query == TDEGenericDeviceType::OtherACPI) {
4256  ret = i18n("Other ACPI");
4257  }
4258  else if (query == TDEGenericDeviceType::OtherUSB) {
4259  ret = i18n("Other USB");
4260  }
4261  else if (query == TDEGenericDeviceType::OtherMultimedia) {
4262  ret = i18n("Other Multimedia");
4263  }
4264  else if (query == TDEGenericDeviceType::OtherPeripheral) {
4265  ret = i18n("Other Peripheral");
4266  }
4267  else if (query == TDEGenericDeviceType::OtherSensor) {
4268  ret = i18n("Other Sensor");
4269  }
4270  else if (query == TDEGenericDeviceType::OtherVirtual) {
4271  ret = i18n("Other Virtual");
4272  }
4273  else {
4274  ret = i18n("Unknown Device");
4275  }
4276 
4277  return ret;
4278 }
4279 
4280 TQPixmap TDEHardwareDevices::getDeviceTypeIconFromType(TDEGenericDeviceType::TDEGenericDeviceType query, TDEIcon::StdSizes size) {
4281  TQPixmap ret = DesktopIcon("misc", size);
4282 
4283 // // Keep this in sync with the TDEGenericDeviceType definition in the header
4284  if (query == TDEGenericDeviceType::Root) {
4285  ret = DesktopIcon("kcmdevices", size);
4286  }
4287  else if (query == TDEGenericDeviceType::RootSystem) {
4288  ret = DesktopIcon("kcmdevices", size);
4289  }
4290  else if (query == TDEGenericDeviceType::CPU) {
4291  ret = DesktopIcon("kcmprocessor", size);
4292  }
4293  else if (query == TDEGenericDeviceType::GPU) {
4294  ret = DesktopIcon("kcmpci", size);
4295  }
4296  else if (query == TDEGenericDeviceType::RAM) {
4297  ret = DesktopIcon("memory", size);
4298  }
4299  else if (query == TDEGenericDeviceType::Bus) {
4300  ret = DesktopIcon("kcmpci", size);
4301  }
4302  else if (query == TDEGenericDeviceType::I2C) {
4303  ret = DesktopIcon("preferences-desktop-peripherals", size);
4304  }
4305  else if (query == TDEGenericDeviceType::MDIO) {
4306  ret = DesktopIcon("preferences-desktop-peripherals", size);
4307  }
4308  else if (query == TDEGenericDeviceType::Mainboard) {
4309  ret = DesktopIcon("kcmpci", size); // FIXME
4310  }
4311  else if (query == TDEGenericDeviceType::Disk) {
4312  ret = DesktopIcon("drive-harddisk", size);
4313  }
4314  else if (query == TDEGenericDeviceType::SCSI) {
4315  ret = DesktopIcon("kcmscsi", size);
4316  }
4317  else if (query == TDEGenericDeviceType::StorageController) {
4318  ret = DesktopIcon("kcmpci", size);
4319  }
4320  else if (query == TDEGenericDeviceType::Mouse) {
4321  ret = DesktopIcon("input-mouse", size);
4322  }
4323  else if (query == TDEGenericDeviceType::Keyboard) {
4324  ret = DesktopIcon("input-keyboard", size);
4325  }
4326  else if (query == TDEGenericDeviceType::HID) {
4327  ret = DesktopIcon("kcmdevices", size); // FIXME
4328  }
4329  else if (query == TDEGenericDeviceType::Modem) {
4330  ret = DesktopIcon("kcmpci", size);
4331  }
4332  else if (query == TDEGenericDeviceType::Monitor) {
4333  ret = DesktopIcon("background", size);
4334  }
4335  else if (query == TDEGenericDeviceType::Network) {
4336  ret = DesktopIcon("kcmpci", size);
4337  }
4338  else if (query == TDEGenericDeviceType::Printer) {
4339  ret = DesktopIcon("printer", size);
4340  }
4341  else if (query == TDEGenericDeviceType::Scanner) {
4342  ret = DesktopIcon("scanner", size);
4343  }
4344  else if (query == TDEGenericDeviceType::Sound) {
4345  ret = DesktopIcon("kcmsound", size);
4346  }
4347  else if (query == TDEGenericDeviceType::VideoCapture) {
4348  ret = DesktopIcon("tv", size); // FIXME
4349  }
4350  else if (query == TDEGenericDeviceType::IEEE1394) {
4351  ret = DesktopIcon("ieee1394", size);
4352  }
4353  else if (query == TDEGenericDeviceType::PCMCIA) {
4354  ret = DesktopIcon("kcmdevices", size); // FIXME
4355  }
4356  else if (query == TDEGenericDeviceType::Camera) {
4357  ret = DesktopIcon("camera-photo", size);
4358  }
4359  else if (query == TDEGenericDeviceType::Serial) {
4360  ret = DesktopIcon("preferences-desktop-peripherals", size);
4361  }
4362  else if (query == TDEGenericDeviceType::Parallel) {
4363  ret = DesktopIcon("preferences-desktop-peripherals", size);
4364  }
4365  else if (query == TDEGenericDeviceType::TextIO) {
4366  ret = DesktopIcon("chardevice", size);
4367  }
4368  else if (query == TDEGenericDeviceType::Peripheral) {
4369  ret = DesktopIcon("kcmpci", size);
4370  }
4371  else if (query == TDEGenericDeviceType::Backlight) {
4372  ret = DesktopIcon("tdescreensaver", size); // FIXME
4373  }
4374  else if (query == TDEGenericDeviceType::Battery) {
4375  ret = DesktopIcon("energy", size);
4376  }
4377  else if (query == TDEGenericDeviceType::PowerSupply) {
4378  ret = DesktopIcon("energy", size);
4379  }
4380  else if (query == TDEGenericDeviceType::Dock) {
4381  ret = DesktopIcon("kcmdevices", size); // FIXME
4382  }
4383  else if (query == TDEGenericDeviceType::ThermalSensor) {
4384  ret = DesktopIcon("kcmdevices", size); // FIXME
4385  }
4386  else if (query == TDEGenericDeviceType::ThermalControl) {
4387  ret = DesktopIcon("kcmdevices", size); // FIXME
4388  }
4389  else if (query == TDEGenericDeviceType::BlueTooth) {
4390  ret = DesktopIcon("kcmpci", size); // FIXME
4391  }
4392  else if (query == TDEGenericDeviceType::Bridge) {
4393  ret = DesktopIcon("kcmpci", size);
4394  }
4395  else if (query == TDEGenericDeviceType::Platform) {
4396  ret = DesktopIcon("preferences-system", size);
4397  }
4398  else if (query == TDEGenericDeviceType::Cryptography) {
4399  ret = DesktopIcon("password", size);
4400  }
4401  else if (query == TDEGenericDeviceType::Event) {
4402  ret = DesktopIcon("preferences-system", size);
4403  }
4404  else if (query == TDEGenericDeviceType::Input) {
4405  ret = DesktopIcon("preferences-system", size);
4406  }
4407  else if (query == TDEGenericDeviceType::PNP) {
4408  ret = DesktopIcon("preferences-system", size);
4409  }
4410  else if (query == TDEGenericDeviceType::OtherACPI) {
4411  ret = DesktopIcon("kcmdevices", size); // FIXME
4412  }
4413  else if (query == TDEGenericDeviceType::OtherUSB) {
4414  ret = DesktopIcon("usb", size);
4415  }
4416  else if (query == TDEGenericDeviceType::OtherMultimedia) {
4417  ret = DesktopIcon("kcmsound", size);
4418  }
4419  else if (query == TDEGenericDeviceType::OtherPeripheral) {
4420  ret = DesktopIcon("kcmpci", size);
4421  }
4422  else if (query == TDEGenericDeviceType::OtherSensor) {
4423  ret = DesktopIcon("kcmdevices", size); // FIXME
4424  }
4425  else if (query == TDEGenericDeviceType::OtherVirtual) {
4426  ret = DesktopIcon("preferences-system", size);
4427  }
4428  else {
4429  ret = DesktopIcon("hwinfo", size);
4430  }
4431 
4432  return ret;
4433 }
4434 
4435 TDERootSystemDevice* TDEHardwareDevices::rootSystemDevice() {
4436  TDEGenericDevice *hwdevice;
4437  for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
4438  if (hwdevice->type() == TDEGenericDeviceType::RootSystem) {
4439  return dynamic_cast<TDERootSystemDevice*>(hwdevice);
4440  }
4441  }
4442 
4443  return 0;
4444 }
4445 
4446 TQString TDEHardwareDevices::bytesToFriendlySizeString(double bytes) {
4447  TQString prettystring;
4448 
4449  prettystring = TQString("%1B").arg(bytes);
4450 
4451  if (bytes > 1024) {
4452  bytes = bytes / 1024;
4453  prettystring = TQString("%1KB").arg(bytes, 0, 'f', 1);
4454  }
4455 
4456  if (bytes > 1024) {
4457  bytes = bytes / 1024;
4458  prettystring = TQString("%1MB").arg(bytes, 0, 'f', 1);
4459  }
4460 
4461  if (bytes > 1024) {
4462  bytes = bytes / 1024;
4463  prettystring = TQString("%1GB").arg(bytes, 0, 'f', 1);
4464  }
4465 
4466  if (bytes > 1024) {
4467  bytes = bytes / 1024;
4468  prettystring = TQString("%1TB").arg(bytes, 0, 'f', 1);
4469  }
4470 
4471  if (bytes > 1024) {
4472  bytes = bytes / 1024;
4473  prettystring = TQString("%1PB").arg(bytes, 0, 'f', 1);
4474  }
4475 
4476  if (bytes > 1024) {
4477  bytes = bytes / 1024;
4478  prettystring = TQString("%1EB").arg(bytes, 0, 'f', 1);
4479  }
4480 
4481  if (bytes > 1024) {
4482  bytes = bytes / 1024;
4483  prettystring = TQString("%1ZB").arg(bytes, 0, 'f', 1);
4484  }
4485 
4486  if (bytes > 1024) {
4487  bytes = bytes / 1024;
4488  prettystring = TQString("%1YB").arg(bytes, 0, 'f', 1);
4489  }
4490 
4491  return prettystring;
4492 }
4493 
4494 TDEGenericHardwareList TDEHardwareDevices::listByDeviceClass(TDEGenericDeviceType::TDEGenericDeviceType cl) {
4495  TDEGenericHardwareList ret;
4496  ret.setAutoDelete(false);
4497 
4498  TDEGenericDevice *hwdevice;
4499  for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
4500  if (hwdevice->type() == cl) {
4501  ret.append(hwdevice);
4502  }
4503  }
4504 
4505  return ret;
4506 }
4507 
4508 TDEGenericHardwareList TDEHardwareDevices::listAllPhysicalDevices() {
4509  TDEGenericHardwareList ret = m_deviceList;
4510  ret.setAutoDelete(false);
4511 
4512  return ret;
4513 }
4514 
4515 #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:80
TDELocale::i18n
TQString i18n(const char *text)
Definition: tdelocale.cpp:1977
TDEGlobal::dirs
static TDEStandardDirs * dirs()
Returns the application standard dirs object.
Definition: tdeglobal.cpp:58
tdelocale.h
TDEIcon::StdSizes
StdSizes
These are the standard sizes for icons.
Definition: kicontheme.h:112
KStdAction::open
TDEAction * open(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
TDEDiskDeviceType
Definition: tdestoragedevice.h: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.13
This website is maintained by Timothy Pearson.