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

tdecore

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

tdecore

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

tdecore

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