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

tdecore

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