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

tdecore

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