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

tdecore

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