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

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