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

tdecore

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

tdecore

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