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

tdecore

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

tdecore

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

tdecore

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