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

tdecore

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

tdecore

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

tdecore

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