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