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

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