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

tdecore

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

tdecore

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

tdecore

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