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

tdecore

tdehardwaredevices.cpp
00001 /* This file is part of the TDE libraries
00002    Copyright (C) 2012-2014 Timothy Pearson <kb9vqf@pearsoncomputing.net>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "tdehardwaredevices.h"
00020 
00021 #include <tqfile.h>
00022 #include <tqdir.h>
00023 #include <tqtimer.h>
00024 #include <tqsocketnotifier.h>
00025 #include <tqstringlist.h>
00026 
00027 #include <tdeconfig.h>
00028 #include <kstandarddirs.h>
00029 
00030 #include <tdeglobal.h>
00031 #include <tdelocale.h>
00032 
00033 #include <tdeapplication.h>
00034 #include <dcopclient.h>
00035 
00036 extern "C" {
00037 #include <libudev.h>
00038 }
00039 
00040 #include <stdlib.h>
00041 #include <unistd.h>
00042 #include <fcntl.h>
00043 
00044 // Network devices
00045 #include <sys/types.h>
00046 #include <ifaddrs.h>
00047 #include <netdb.h>
00048 
00049 // Backlight devices
00050 #include <linux/fb.h>
00051 
00052 // Input devices
00053 #include <linux/input.h>
00054 
00055 #include "kiconloader.h"
00056 
00057 #include "tdegenericdevice.h"
00058 #include "tdestoragedevice.h"
00059 #include "tdecpudevice.h"
00060 #include "tdebatterydevice.h"
00061 #include "tdemainspowerdevice.h"
00062 #include "tdenetworkdevice.h"
00063 #include "tdebacklightdevice.h"
00064 #include "tdemonitordevice.h"
00065 #include "tdesensordevice.h"
00066 #include "tderootsystemdevice.h"
00067 #include "tdeeventdevice.h"
00068 #include "tdeinputdevice.h"
00069 #include "tdecryptographiccarddevice.h"
00070 
00071 // Compile-time configuration
00072 #include "config.h"
00073 
00074 // Profiling stuff
00075 //#define CPUPROFILING
00076 //#define STATELESSPROFILING
00077 
00078 #include <time.h>
00079 timespec diff(timespec start, timespec end)
00080 {
00081     timespec temp;
00082     if ((end.tv_nsec-start.tv_nsec)<0) {
00083         temp.tv_sec = end.tv_sec-start.tv_sec-1;
00084         temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
00085     } else {
00086         temp.tv_sec = end.tv_sec-start.tv_sec;
00087         temp.tv_nsec = end.tv_nsec-start.tv_nsec;
00088     }
00089     return temp;
00090 }
00091 
00092 // BEGIN BLOCK
00093 // Copied from include/linux/genhd.h
00094 #define GENHD_FL_REMOVABLE                      1
00095 #define GENHD_FL_MEDIA_CHANGE_NOTIFY            4
00096 #define GENHD_FL_CD                             8
00097 #define GENHD_FL_UP                             16
00098 #define GENHD_FL_SUPPRESS_PARTITION_INFO        32
00099 #define GENHD_FL_EXT_DEVT                       64
00100 #define GENHD_FL_NATIVE_CAPACITY                128
00101 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE     256
00102 // END BLOCK
00103 
00104 // NOTE TO DEVELOPERS
00105 // This command will greatly help when attempting to find properties to distinguish one device from another
00106 // udevadm info --query=all --path=/sys/....
00107 
00108 // This routine is courtsey of an answer on "Stack Overflow"
00109 // It takes an LSB-first int and makes it an MSB-first int (or vice versa)
00110 unsigned int reverse_bits(unsigned int x)
00111 {
00112     x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
00113     x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
00114     x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
00115     x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
00116     return((x >> 16) | (x << 16));
00117 }
00118 
00119 // Helper function implemented in tdestoragedevice.cpp
00120 TQString decodeHexEncoding(TQString str);
00121 
00122 TDEHardwareDevices::TDEHardwareDevices() {
00123     // Initialize members
00124     pci_id_map = 0;
00125     usb_id_map = 0;
00126     pnp_id_map = 0;
00127     dpy_id_map = 0;
00128 
00129     // Set up device list
00130     m_deviceList.setAutoDelete( true ); // the list owns the objects
00131 
00132     // Initialize udev interface
00133     m_udevStruct = udev_new();
00134     if (!m_udevStruct) {
00135         printf("Unable to create udev interface\n");
00136     }
00137 
00138     if (m_udevStruct) {
00139         // Set up device add/remove monitoring
00140         m_udevMonitorStruct = udev_monitor_new_from_netlink(m_udevStruct, "udev");
00141         udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitorStruct, NULL, NULL);
00142         udev_monitor_enable_receiving(m_udevMonitorStruct);
00143 
00144         int udevmonitorfd = udev_monitor_get_fd(m_udevMonitorStruct);
00145         if (udevmonitorfd >= 0) {
00146             m_devScanNotifier = new TQSocketNotifier(udevmonitorfd, TQSocketNotifier::Read, this);
00147             connect( m_devScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processHotPluggedHardware()) );
00148         }
00149 
00150         // Read in the current mount table
00151         // 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
00152         m_mountTable.clear();
00153         TQFile file( "/proc/mounts" );
00154         if ( file.open( IO_ReadOnly ) ) {
00155             TQTextStream stream( &file );
00156             while ( !stream.atEnd() ) {
00157                 TQString line = stream.readLine();
00158                 if (!line.isEmpty()) {
00159                     m_mountTable[line] = true;
00160                 }
00161             }
00162             file.close();
00163         }
00164 
00165         // Monitor for changed mounts
00166         m_procMountsFd = open("/proc/mounts", O_RDONLY, 0);
00167         if (m_procMountsFd >= 0) {
00168             m_mountScanNotifier = new TQSocketNotifier(m_procMountsFd, TQSocketNotifier::Exception, this);
00169             connect( m_mountScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processModifiedMounts()) );
00170         }
00171 
00172         // Read in the current cpu information
00173         // 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
00174         m_cpuInfo.clear();
00175         TQFile cpufile( "/proc/cpuinfo" );
00176         if ( cpufile.open( IO_ReadOnly ) ) {
00177             TQTextStream stream( &cpufile );
00178             while ( !stream.atEnd() ) {
00179                 m_cpuInfo.append(stream.readLine());
00180             }
00181             cpufile.close();
00182         }
00183 
00184 // [FIXME 0.01]
00185 // Apparently the Linux kernel just does not notify userspace applications of CPU frequency changes
00186 // 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
00187 #if 0
00188         // Monitor for changed cpu information
00189         // Watched directories are set up during the initial CPU scan
00190         m_cpuWatch = new KSimpleDirWatch(this);
00191         connect( m_cpuWatch, TQT_SIGNAL(dirty(const TQString &)), this, TQT_SLOT(processModifiedCPUs()) );
00192 #else
00193         m_cpuWatchTimer = new TQTimer(this);
00194         connect( m_cpuWatchTimer, SIGNAL(timeout()), this, SLOT(processModifiedCPUs()) );
00195 #endif
00196 
00197         // Some devices do not receive update signals from udev
00198         // These devices must be polled, and a good polling interval is 1 second
00199         m_deviceWatchTimer = new TQTimer(this);
00200         connect( m_deviceWatchTimer, SIGNAL(timeout()), this, SLOT(processStatelessDevices()) );
00201 
00202         // Special case for battery polling (longer delay, 5 seconds)
00203         m_batteryWatchTimer = new TQTimer(this);
00204         connect( m_batteryWatchTimer, SIGNAL(timeout()), this, SLOT(processBatteryDevices()) );
00205 
00206         // Update internal device information
00207         queryHardwareInformation();
00208     }
00209 }
00210 
00211 TDEHardwareDevices::~TDEHardwareDevices() {
00212     // Stop device scanning
00213     m_deviceWatchTimer->stop();
00214     m_batteryWatchTimer->stop();
00215 
00216 // [FIXME 0.01]
00217 #if 0
00218     // Stop CPU scanning
00219     m_cpuWatch->stopScan();
00220 #else
00221     m_cpuWatchTimer->stop();
00222 #endif
00223 
00224     // Stop mount scanning
00225     close(m_procMountsFd);
00226 
00227     // Tear down udev interface
00228     if(m_udevMonitorStruct) {
00229         udev_monitor_unref(m_udevMonitorStruct);
00230     }
00231     udev_unref(m_udevStruct);
00232 
00233     // Delete members
00234     if (pci_id_map) {
00235         delete pci_id_map;
00236     }
00237     if (usb_id_map) {
00238         delete usb_id_map;
00239     }
00240     if (pnp_id_map) {
00241         delete pnp_id_map;
00242     }
00243     if (dpy_id_map) {
00244         delete dpy_id_map;
00245     }
00246 }
00247 
00248 void TDEHardwareDevices::setTriggerlessHardwareUpdatesEnabled(bool enable) {
00249     if (enable) {
00250         TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
00251         if (nodezerocpufreq.exists()) {
00252             m_cpuWatchTimer->start( 500, false ); // 0.5 second repeating timer
00253         }
00254         m_batteryWatchTimer->stop(); // Battery devices are included in stateless devices
00255         m_deviceWatchTimer->start( 1000, false ); // 1 second repeating timer
00256     }
00257     else {
00258         m_cpuWatchTimer->stop();
00259         m_deviceWatchTimer->stop();
00260     }
00261 }
00262 
00263 void TDEHardwareDevices::setBatteryUpdatesEnabled(bool enable) {
00264     if (enable) {
00265         TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
00266         if (nodezerocpufreq.exists()) {
00267             m_cpuWatchTimer->start( 500, false ); // 0.5 second repeating timer
00268         }
00269         m_batteryWatchTimer->start( 5000, false ); // 5 second repeating timer
00270     }
00271     else {
00272         m_cpuWatchTimer->stop();
00273         m_batteryWatchTimer->stop();
00274     }
00275 }
00276 
00277 void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) {
00278     rescanDeviceInformation(hwdevice, true);
00279 }
00280 
00281 void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice, bool regenerateDeviceTree) {
00282     struct udev_device *dev;
00283     dev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
00284     updateExistingDeviceInformation(hwdevice);
00285     if (regenerateDeviceTree) {
00286         updateParentDeviceInformation(hwdevice);    // Update parent/child tables for this device
00287     }
00288     udev_device_unref(dev);
00289 }
00290 
00291 TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
00292     if (!syspath.endsWith("/")) {
00293         syspath += "/";
00294     }
00295     TDEGenericDevice *hwdevice;
00296 
00297     // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
00298     TDEGenericHardwareList devList = listAllPhysicalDevices();
00299     for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
00300         if (hwdevice->systemPath() == syspath) {
00301             return hwdevice;
00302         }
00303     }
00304 
00305     return 0;
00306 }
00307 
00308 TDECPUDevice* TDEHardwareDevices::findCPUBySystemPath(TQString syspath, bool inCache=true) {
00309     TDECPUDevice* cdevice;
00310 
00311     // Look for the device in the cache first
00312     if(inCache && !m_cpuByPathCache.isEmpty()) {
00313         cdevice = m_cpuByPathCache.find(syspath);
00314         if(cdevice) {
00315             return cdevice;
00316         }
00317     }
00318 
00319     // If the CPU was not found in cache, we need to parse the entire device list to get it.
00320     cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(syspath));
00321     if(cdevice) {
00322         if(inCache) {
00323             m_cpuByPathCache.insert(syspath, cdevice); // Add the device to the cache
00324         }
00325         return cdevice;
00326     }
00327 
00328     return 0;
00329 }
00330 
00331 
00332 TDEGenericDevice* TDEHardwareDevices::findByUniqueID(TQString uid) {
00333     TDEGenericDevice *hwdevice;
00334     // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
00335     TDEGenericHardwareList devList = listAllPhysicalDevices();
00336     for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
00337         if (hwdevice->uniqueID() == uid) {
00338             return hwdevice;
00339         }
00340     }
00341 
00342     return 0;
00343 }
00344 
00345 TDEGenericDevice* TDEHardwareDevices::findByDeviceNode(TQString devnode) {
00346     TDEGenericDevice *hwdevice;
00347     for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
00348         if (hwdevice->deviceNode() == devnode) {
00349             return hwdevice;
00350         }
00351     }
00352 
00353     return 0;
00354 }
00355 
00356 TDEStorageDevice* TDEHardwareDevices::findDiskByUID(TQString uid) {
00357     TDEGenericDevice *hwdevice;
00358     for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
00359         if (hwdevice->type() == TDEGenericDeviceType::Disk) {
00360             TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
00361             if (sdevice->uniqueID() == uid) {
00362                 return sdevice;
00363             }
00364         }
00365     }
00366 
00367     return 0;
00368 }
00369 
00370 void TDEHardwareDevices::processHotPluggedHardware() {
00371     udev_device* dev = udev_monitor_receive_device(m_udevMonitorStruct);
00372     if (dev) {
00373         TQString actionevent(udev_device_get_action(dev));
00374         if (actionevent == "add") {
00375             TDEGenericDevice* device = classifyUnknownDevice(dev);
00376 
00377             // Make sure this device is not a duplicate
00378             TDEGenericDevice *hwdevice;
00379             for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
00380                 if (hwdevice->systemPath() == device->systemPath()) {
00381                     delete device;
00382                     device = 0;
00383                     break;
00384                 }
00385             }
00386 
00387             if (device) {
00388                 m_deviceList.append(device);
00389                 updateParentDeviceInformation(device);  // Update parent/child tables for this device
00390                 emit hardwareAdded(device);
00391                 emit hardwareEvent(TDEHardwareEvent::HardwareAdded, device->uniqueID());
00392             }
00393         }
00394         else if (actionevent == "remove") {
00395             // Delete device from hardware listing
00396             TQString systempath(udev_device_get_syspath(dev));
00397             systempath += "/";
00398             TDEGenericDevice *hwdevice;
00399             for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
00400                 if (hwdevice->systemPath() == systempath) {
00401                     // Temporarily disable auto-deletion to ensure object validity when calling the Removed events below
00402                     m_deviceList.setAutoDelete(false);
00403 
00404                     // If the device is a storage device and has a slave, update it as well
00405                     if (hwdevice->type() == TDEGenericDeviceType::Disk) {
00406                         TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
00407                         TQStringList slavedevices = sdevice->slaveDevices();
00408                         m_deviceList.remove(hwdevice);
00409                         for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
00410                             TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
00411                             if (slavedevice) {
00412                                 rescanDeviceInformation(slavedevice);
00413                                 emit hardwareUpdated(slavedevice);
00414                                 emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
00415                             }
00416                         }
00417                     }
00418                     else {
00419                         m_deviceList.remove(hwdevice);
00420                     }
00421 
00422                     emit hardwareRemoved(hwdevice);
00423                     emit hardwareEvent(TDEHardwareEvent::HardwareRemoved, hwdevice->uniqueID());
00424 
00425                     // Reenable auto-deletion and delete the removed device object
00426                     m_deviceList.setAutoDelete(true);
00427                     delete hwdevice;
00428 
00429                     break;
00430                 }
00431             }
00432         }
00433         else if (actionevent == "change") {
00434             // Update device and emit change event
00435             TQString systempath(udev_device_get_syspath(dev));
00436             systempath += "/";
00437             TDEGenericDevice *hwdevice;
00438             for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
00439                 if (hwdevice->systemPath() == systempath) {
00440                     if (!hwdevice->blacklistedForUpdate()) {
00441                         classifyUnknownDevice(dev, hwdevice, false);
00442                         updateParentDeviceInformation(hwdevice);    // Update parent/child tables for this device
00443                         emit hardwareUpdated(hwdevice);
00444                         emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00445                     }
00446                 }
00447                 else if ((hwdevice->type() == TDEGenericDeviceType::Monitor)
00448                         && (hwdevice->systemPath().contains(systempath))) {
00449                     if (!hwdevice->blacklistedForUpdate()) {
00450                         struct udev_device *slavedev;
00451                         slavedev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
00452                         classifyUnknownDevice(slavedev, hwdevice, false);
00453                         udev_device_unref(slavedev);
00454                         updateParentDeviceInformation(hwdevice);    // Update parent/child tables for this device
00455                         emit hardwareUpdated(hwdevice);
00456                         emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00457                     }
00458                 }
00459             }
00460         }
00461         udev_device_unref(dev);
00462     }
00463 }
00464 
00465 void TDEHardwareDevices::processModifiedCPUs() {
00466     // Detect what changed between the old cpu information and the new information,
00467     // and emit appropriate events
00468 
00469 #ifdef CPUPROFILING
00470     timespec time1, time2, time3;
00471     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
00472     time3 = time1;
00473     printf("TDEHardwareDevices::processModifiedCPUs() : begin at '%u'\n", time1.tv_nsec);
00474 #endif
00475 
00476     // Read new CPU information table
00477     m_cpuInfo.clear();
00478     TQFile cpufile( "/proc/cpuinfo" );
00479     if ( cpufile.open( IO_ReadOnly ) ) {
00480         TQTextStream stream( &cpufile );
00481         // Using read() instead of readLine() inside a loop is 4 times faster !
00482         m_cpuInfo = TQStringList::split('\n', stream.read(), true);
00483         cpufile.close();
00484     }
00485 
00486 #ifdef CPUPROFILING
00487     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00488     printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint1 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
00489     time1 = time2;
00490 #endif
00491 
00492     // Ensure "processor" is the first entry in each block and determine which cpuinfo type is in use
00493     bool cpuinfo_format_x86 = true;
00494     bool cpuinfo_format_arm = false;
00495 
00496     TQString curline1;
00497     TQString curline2;
00498     int blockNumber = 0;
00499     TQStringList::Iterator blockBegin = m_cpuInfo.begin();
00500     for (TQStringList::Iterator cpuit1 = m_cpuInfo.begin(); cpuit1 != m_cpuInfo.end(); ++cpuit1) {
00501         curline1 = *cpuit1;
00502         if (!(*blockBegin).startsWith("processor")) {
00503             bool found = false;
00504             TQStringList::Iterator cpuit2;
00505             for (cpuit2 = blockBegin; cpuit2 != m_cpuInfo.end(); ++cpuit2) {
00506                 curline2 = *cpuit2;
00507                 if (curline2.startsWith("processor")) {
00508                     found = true;
00509                     break;
00510                 }
00511                 else if (curline2 == NULL || curline2 == "") {
00512                     break;
00513                 }
00514             }
00515             if (found) {
00516                 m_cpuInfo.insert(blockBegin, (*cpuit2));
00517             }
00518             else if(blockNumber == 0) {
00519                 m_cpuInfo.insert(blockBegin, "processor : 0");
00520             }
00521         }
00522         if (curline1 == NULL || curline1 == "") {
00523             blockNumber++;
00524             blockBegin = cpuit1;
00525             blockBegin++;
00526         }
00527         else if (curline1.startsWith("Processor")) {
00528             cpuinfo_format_x86 = false;
00529             cpuinfo_format_arm = true;
00530         }
00531     }
00532 
00533 #ifdef CPUPROFILING
00534     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00535     printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint2 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
00536     time1 = time2;
00537 #endif
00538 
00539     // Parse CPU information table
00540     TDECPUDevice *cdevice;
00541     cdevice = 0;
00542     bool modified = false;
00543     bool have_frequency = false;
00544 
00545     TQString curline;
00546     int processorNumber = 0;
00547     int processorCount = 0;
00548 
00549     if (cpuinfo_format_x86) {
00550         // ===================================================================================================================================
00551         // x86/x86_64
00552         // ===================================================================================================================================
00553         TQStringList::Iterator cpuit;
00554         for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
00555             curline = *cpuit;
00556             if (curline.startsWith("processor")) {
00557                 curline.remove(0, curline.find(":")+2);
00558                 processorNumber = curline.toInt();
00559                 if (!cdevice) {
00560                     cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
00561                 }
00562                 if (cdevice) {
00563                     if (cdevice->coreNumber() != processorNumber) {
00564                         modified = true;
00565                         cdevice->internalSetCoreNumber(processorNumber);
00566                     }
00567                 }
00568             }
00569             else if (cdevice && curline.startsWith("model name")) {
00570                 curline.remove(0, curline.find(":")+2);
00571                 if (cdevice->name() != curline) {
00572                     modified = true;
00573                     cdevice->internalSetName(curline);
00574                 }
00575             }
00576             else if (cdevice && curline.startsWith("cpu MHz")) {
00577                 curline.remove(0, curline.find(":")+2);
00578                 if (cdevice->frequency() != curline.toDouble()) {
00579                     modified = true;
00580                     cdevice->internalSetFrequency(curline.toDouble());
00581                 }
00582                 have_frequency = true;
00583             }
00584             else if (cdevice && curline.startsWith("vendor_id")) {
00585                 curline.remove(0, curline.find(":")+2);
00586                 if (cdevice->vendorName() != curline) {
00587                     modified = true;
00588                     cdevice->internalSetVendorName(curline);
00589                 }
00590                 if (cdevice->vendorEncoded() != curline) {
00591                     modified = true;
00592                     cdevice->internalSetVendorEncoded(curline);
00593                 }
00594             }
00595             else if (curline == NULL || curline == "") {
00596                 cdevice = 0;
00597             }
00598         }
00599     }
00600     else if (cpuinfo_format_arm) {
00601         // ===================================================================================================================================
00602         // ARM
00603         // ===================================================================================================================================
00604         TQStringList::Iterator cpuit;
00605         TQString modelName;
00606         TQString vendorName;
00607         TQString serialNumber;
00608         for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
00609             curline = *cpuit;
00610             if (curline.startsWith("Processor")) {
00611                 curline.remove(0, curline.find(":")+2);
00612                 modelName = curline;
00613             }
00614             else if (curline.startsWith("Hardware")) {
00615                 curline.remove(0, curline.find(":")+2);
00616                 vendorName = curline;
00617             }
00618             else if (curline.startsWith("Serial")) {
00619                 curline.remove(0, curline.find(":")+2);
00620                 serialNumber = curline;
00621             }
00622         }
00623         for (TQStringList::Iterator cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
00624             curline = *cpuit;
00625             if (curline.startsWith("processor")) {
00626                 curline.remove(0, curline.find(":")+2);
00627                 processorNumber = curline.toInt();
00628                 if (!cdevice) {
00629                     cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
00630                     if (cdevice) {
00631                         // Set up CPU information structures
00632                         if (cdevice->coreNumber() != processorNumber) modified = true;
00633                         cdevice->internalSetCoreNumber(processorNumber);
00634                         if (cdevice->name() != modelName) modified = true;
00635                         cdevice->internalSetName(modelName);
00636                         if (cdevice->vendorName() != vendorName) modified = true;
00637                         cdevice->internalSetVendorName(vendorName);
00638                         if (cdevice->vendorEncoded() != vendorName) modified = true;
00639                         cdevice->internalSetVendorEncoded(vendorName);
00640                         if (cdevice->serialNumber() != serialNumber) modified = true;
00641                         cdevice->internalSetSerialNumber(serialNumber);
00642                     }
00643                 }
00644             }
00645             if (curline == NULL || curline == "") {
00646                 cdevice = 0;
00647             }
00648         }
00649     }
00650 
00651     processorCount = processorNumber+1;
00652 
00653 #ifdef CPUPROFILING
00654     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00655     printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
00656     time1 = time2;
00657 #endif
00658 
00659     // Read in other information from cpufreq, if available
00660     for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
00661         cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
00662         TQDir cpufreq_dir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber));
00663         TQString scalinggovernor;
00664         TQString scalingdriver;
00665         double minfrequency = -1;
00666         double maxfrequency = -1;
00667         double trlatency = -1;
00668         TQStringList affectedcpulist;
00669         TQStringList frequencylist;
00670         TQStringList governorlist;
00671         if (cpufreq_dir.exists()) {
00672             TQString nodename;
00673             nodename = cpufreq_dir.path();
00674             nodename.append("/scaling_governor");
00675             TQFile scalinggovernorfile(nodename);
00676             if (scalinggovernorfile.open(IO_ReadOnly)) {
00677                 TQTextStream stream( &scalinggovernorfile );
00678                 scalinggovernor = stream.readLine();
00679                 scalinggovernorfile.close();
00680             }
00681             nodename = cpufreq_dir.path();
00682             nodename.append("/scaling_driver");
00683             TQFile scalingdriverfile(nodename);
00684             if (scalingdriverfile.open(IO_ReadOnly)) {
00685                 TQTextStream stream( &scalingdriverfile );
00686                 scalingdriver = stream.readLine();
00687                 scalingdriverfile.close();
00688             }
00689             nodename = cpufreq_dir.path();
00690             nodename.append("/cpuinfo_min_freq");
00691             TQFile minfrequencyfile(nodename);
00692             if (minfrequencyfile.open(IO_ReadOnly)) {
00693                 TQTextStream stream( &minfrequencyfile );
00694                 minfrequency = stream.readLine().toDouble()/1000.0;
00695                 minfrequencyfile.close();
00696             }
00697             nodename = cpufreq_dir.path();
00698             nodename.append("/cpuinfo_max_freq");
00699             TQFile maxfrequencyfile(nodename);
00700             if (maxfrequencyfile.open(IO_ReadOnly)) {
00701                 TQTextStream stream( &maxfrequencyfile );
00702                 maxfrequency = stream.readLine().toDouble()/1000.0;
00703                 maxfrequencyfile.close();
00704             }
00705             nodename = cpufreq_dir.path();
00706             nodename.append("/cpuinfo_transition_latency");
00707             TQFile trlatencyfile(nodename);
00708             if (trlatencyfile.open(IO_ReadOnly)) {
00709                 TQTextStream stream( &trlatencyfile );
00710                 trlatency = stream.readLine().toDouble()/1000.0;
00711                 trlatencyfile.close();
00712             }
00713             nodename = cpufreq_dir.path();
00714             nodename.append("/scaling_available_frequencies");
00715             TQFile availfreqsfile(nodename);
00716             if (availfreqsfile.open(IO_ReadOnly)) {
00717                 TQTextStream stream( &availfreqsfile );
00718                 frequencylist = TQStringList::split(" ", stream.readLine());
00719                 availfreqsfile.close();
00720             }
00721             nodename = cpufreq_dir.path();
00722             nodename.append("/scaling_available_governors");
00723             TQFile availgvrnsfile(nodename);
00724             if (availgvrnsfile.open(IO_ReadOnly)) {
00725                 TQTextStream stream( &availgvrnsfile );
00726                 governorlist = TQStringList::split(" ", stream.readLine());
00727                 availgvrnsfile.close();
00728             }
00729             nodename = cpufreq_dir.path();
00730             nodename.append("/affected_cpus");
00731             TQFile tiedcpusfile(nodename);
00732             if (tiedcpusfile.open(IO_ReadOnly)) {
00733                 TQTextStream stream( &tiedcpusfile );
00734                 affectedcpulist = TQStringList::split(" ", stream.readLine());
00735                 tiedcpusfile.close();
00736             }
00737 
00738             // We may already have the CPU Mhz information in '/proc/cpuinfo'
00739             if (!have_frequency) {
00740                 bool cpufreq_have_frequency = false;
00741                 nodename = cpufreq_dir.path();
00742                 nodename.append("/scaling_cur_freq");
00743                 TQFile cpufreqfile(nodename);
00744                 if (cpufreqfile.open(IO_ReadOnly)) {
00745                     cpufreq_have_frequency = true;
00746                 }
00747                 else {
00748                     nodename = cpufreq_dir.path();
00749                     nodename.append("/cpuinfo_cur_freq");
00750                     cpufreqfile.setName(nodename);
00751                     if (cpufreqfile.open(IO_ReadOnly)) {
00752                         cpufreq_have_frequency = true;
00753                     }
00754                 }
00755                 if (cpufreq_have_frequency) {
00756                     TQTextStream stream( &cpufreqfile );
00757                     double cpuinfo_cur_freq = stream.readLine().toDouble()/1000.0;
00758                     if (cdevice && cdevice->frequency() != cpuinfo_cur_freq) {
00759                         modified = true;
00760                         cdevice->internalSetFrequency(cpuinfo_cur_freq);
00761                     }
00762                     cpufreqfile.close();
00763                 }
00764             }
00765 
00766             bool minfrequencyFound = false;
00767             bool maxfrequencyFound = false;
00768             TQStringList::Iterator freqit;
00769             for ( freqit = frequencylist.begin(); freqit != frequencylist.end(); ++freqit ) {
00770                 double thisfrequency = (*freqit).toDouble()/1000.0;
00771                 if (thisfrequency == minfrequency) {
00772                     minfrequencyFound = true;
00773                 }
00774                 if (thisfrequency == maxfrequency) {
00775                     maxfrequencyFound = true;
00776                 }
00777 
00778             }
00779             if (!minfrequencyFound) {
00780                 int minFrequencyInt = (minfrequency*1000.0);
00781                 frequencylist.prepend(TQString("%1").arg(minFrequencyInt));
00782             }
00783             if (!maxfrequencyFound) {
00784                 int maxfrequencyInt = (maxfrequency*1000.0);
00785                 frequencylist.append(TQString("%1").arg(maxfrequencyInt));
00786             }
00787 
00788 #ifdef CPUPROFILING
00789             clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00790             printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3.%u at %u [%u]\n", processorNumber, time2.tv_nsec, diff(time1,time2).tv_nsec);
00791             time1 = time2;
00792 #endif
00793         }
00794         else {
00795             if (have_frequency) {
00796                 if (cdevice) {
00797                     minfrequency = cdevice->frequency();
00798                     maxfrequency = cdevice->frequency();
00799                 }
00800             }
00801         }
00802 
00803         // Update CPU information structure
00804         if (cdevice) {
00805             if (cdevice->governor() != scalinggovernor) {
00806                 modified = true;
00807                 cdevice->internalSetGovernor(scalinggovernor);
00808             }
00809             if (cdevice->scalingDriver() != scalingdriver) {
00810                 modified = true;
00811                 cdevice->internalSetScalingDriver(scalingdriver);
00812             }
00813             if (cdevice->minFrequency() != minfrequency) {
00814                 modified = true;
00815                 cdevice->internalSetMinFrequency(minfrequency);
00816             }
00817             if (cdevice->maxFrequency() != maxfrequency) {
00818                 modified = true;
00819                 cdevice->internalSetMaxFrequency(maxfrequency);
00820             }
00821             if (cdevice->transitionLatency() != trlatency) {
00822                 modified = true;
00823                 cdevice->internalSetTransitionLatency(trlatency);
00824             }
00825             if (cdevice->dependentProcessors().join(" ") != affectedcpulist.join(" ")) {
00826                 modified = true;
00827                 cdevice->internalSetDependentProcessors(affectedcpulist);
00828             }
00829             if (cdevice->availableFrequencies().join(" ") != frequencylist.join(" ")) {
00830                 modified = true;
00831                 cdevice->internalSetAvailableFrequencies(frequencylist);
00832             }
00833             if (cdevice->availableGovernors().join(" ") != governorlist.join(" ")) {
00834                 modified = true;
00835                 cdevice->internalSetAvailableGovernors(governorlist);
00836             }
00837         }
00838     }
00839 
00840 #ifdef CPUPROFILING
00841     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00842     printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint4 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
00843     time1 = time2;
00844 #endif
00845 
00846     if (modified) {
00847         for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
00848             TDEGenericDevice* hwdevice = findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
00849             if (hwdevice) {
00850                 // Signal new information available
00851                 emit hardwareUpdated(hwdevice);
00852                 emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00853             }
00854         }
00855     }
00856 
00857 #ifdef CPUPROFILING
00858     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00859     printf("TDEHardwareDevices::processModifiedCPUs() : end at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
00860     printf("TDEHardwareDevices::processModifiedCPUs() : total time: %u\n", diff(time3,time2).tv_nsec);
00861 #endif
00862 }
00863 
00864 void TDEHardwareDevices::processStatelessDevices() {
00865     // Some devices do not emit changed signals
00866     // So far, network cards and sensors need to be polled
00867     TDEGenericDevice *hwdevice;
00868 
00869 #ifdef STATELESSPROFILING
00870     timespec time1, time2, time3;
00871     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
00872     printf("TDEHardwareDevices::processStatelessDevices() : begin at '%u'\n", time1.tv_nsec);
00873     time3 = time1;
00874 #endif
00875 
00876     // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
00877     TDEGenericHardwareList devList = listAllPhysicalDevices();
00878     for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
00879         if ((hwdevice->type() == TDEGenericDeviceType::RootSystem) || (hwdevice->type() == TDEGenericDeviceType::Network) || (hwdevice->type() == TDEGenericDeviceType::OtherSensor) || (hwdevice->type() == TDEGenericDeviceType::Event) || (hwdevice->type() == TDEGenericDeviceType::Battery) || (hwdevice->type() == TDEGenericDeviceType::PowerSupply)) {
00880             rescanDeviceInformation(hwdevice, false);
00881             emit hardwareUpdated(hwdevice);
00882             emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00883 #ifdef STATELESSPROFILING
00884             clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00885             printf("TDEHardwareDevices::processStatelessDevices() : '%s' finished at %u [%u]\n", (hwdevice->name()).ascii(), time2.tv_nsec, diff(time1,time2).tv_nsec);
00886             time1 = time2;
00887 #endif
00888         }
00889     }
00890 
00891 #ifdef STATELESSPROFILING
00892     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
00893     printf("TDEHardwareDevices::processStatelessDevices() : end at '%u'\n", time2.tv_nsec);
00894     printf("TDEHardwareDevices::processStatelessDevices() : took '%u'\n", diff(time3,time2).tv_nsec);
00895 #endif
00896 }
00897 
00898 void TDEHardwareDevices::processBatteryDevices() {
00899     TDEGenericDevice *hwdevice;
00900 
00901     // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
00902     TDEGenericHardwareList devList = listAllPhysicalDevices();
00903     for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
00904         if (hwdevice->type() == TDEGenericDeviceType::Battery) {
00905             rescanDeviceInformation(hwdevice, false);
00906             emit hardwareUpdated(hwdevice);
00907             emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00908         }
00909     }
00910 }
00911 
00912 
00913 void TDEHardwareDevices::processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice) {
00914     emit eventDeviceKeyPressed(keycode, edevice);
00915 }
00916 
00917 void TDEHardwareDevices::processModifiedMounts() {
00918     // Detect what changed between the old mount table and the new one,
00919     // and emit appropriate events
00920 
00921     TQMap<TQString, bool> deletedEntries = m_mountTable;
00922 
00923     // Read in the new mount table
00924     m_mountTable.clear();
00925     TQFile file( "/proc/mounts" );
00926     if ( file.open( IO_ReadOnly ) ) {
00927         TQTextStream stream( &file );
00928         while ( !stream.atEnd() ) {
00929             TQString line = stream.readLine();
00930             if (!line.isEmpty()) {
00931                 m_mountTable[line] = true;
00932             }
00933         }
00934         file.close();
00935     }
00936     TQMap<TQString, bool> addedEntries = m_mountTable;
00937 
00938     // Remove all entries that are identical in both tables
00939     for ( TQMap<TQString, bool>::ConstIterator mtIt = m_mountTable.begin(); mtIt != m_mountTable.end(); ++mtIt ) {
00940         if (deletedEntries.contains(mtIt.key())) {
00941             deletedEntries.remove(mtIt.key());
00942             addedEntries.remove(mtIt.key());
00943         }
00944     }
00945 
00946     TQMap<TQString, bool>::Iterator it;
00947     for ( it = addedEntries.begin(); it != addedEntries.end(); ++it ) {
00948         TQStringList mountInfo = TQStringList::split(" ", it.key(), true);
00949         // Try to find a device that matches the altered node
00950         TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
00951         if (hwdevice) {
00952             emit hardwareUpdated(hwdevice);
00953             emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00954             // If the device is a storage device and has a slave, update it as well
00955             if (hwdevice->type() == TDEGenericDeviceType::Disk) {
00956                 TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
00957                 TQStringList slavedevices = sdevice->slaveDevices();
00958                 for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
00959                     TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
00960                     if (slavedevice) {
00961                         emit hardwareUpdated(slavedevice);
00962                         emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
00963                     }
00964                 }
00965             }
00966         }
00967     }
00968     for ( it = deletedEntries.begin(); it != deletedEntries.end(); ++it ) {
00969         TQStringList mountInfo = TQStringList::split(" ", it.key(), true);
00970         // Try to find a device that matches the altered node
00971         TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
00972         if (hwdevice) {
00973             emit hardwareUpdated(hwdevice);
00974             emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
00975             // If the device is a storage device and has a slave, update it as well
00976             if (hwdevice->type() == TDEGenericDeviceType::Disk) {
00977                 TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
00978                 TQStringList slavedevices = sdevice->slaveDevices();
00979                 for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
00980                     TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
00981                     if (slavedevice) {
00982                         emit hardwareUpdated(slavedevice);
00983                         emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
00984                     }
00985                 }
00986             }
00987         }
00988     }
00989 
00990     emit mountTableModified();
00991     emit hardwareEvent(TDEHardwareEvent::MountTableModified, TQString());
00992 }
00993 
00994 TDEDiskDeviceType::TDEDiskDeviceType classifyDiskType(udev_device* dev, const TQString devicenode, const TQString devicebus, const TQString disktypestring, const TQString systempath, const TQString devicevendor, const TQString devicemodel, const TQString filesystemtype, const TQString devicedriver) {
00995     // Classify a disk device type to the best of our ability
00996     TDEDiskDeviceType::TDEDiskDeviceType disktype = TDEDiskDeviceType::Null;
00997 
00998     if (devicebus.upper() == "USB") {
00999         disktype = disktype | TDEDiskDeviceType::USB;
01000     }
01001 
01002     if (disktypestring.upper() == "DISK") {
01003         disktype = disktype | TDEDiskDeviceType::HDD;
01004     }
01005 
01006     if ((disktypestring.upper() == "FLOPPY")
01007         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY")) == "1")) {
01008         disktype = disktype | TDEDiskDeviceType::Floppy;
01009         disktype = disktype & ~TDEDiskDeviceType::HDD;
01010     }
01011 
01012     if ((disktypestring.upper() == "ZIP")
01013         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY_ZIP")) == "1")
01014         || ((devicevendor.upper() == "IOMEGA") && (devicemodel.upper().contains("ZIP")))) {
01015         disktype = disktype | TDEDiskDeviceType::Zip;
01016         disktype = disktype & ~TDEDiskDeviceType::HDD;
01017     }
01018 
01019     if ((devicevendor.upper() == "APPLE") && (devicemodel.upper().contains("IPOD"))) {
01020         disktype = disktype | TDEDiskDeviceType::MediaDevice;
01021     }
01022     if ((devicevendor.upper() == "SANDISK") && (devicemodel.upper().contains("SANSA"))) {
01023         disktype = disktype | TDEDiskDeviceType::MediaDevice;
01024     }
01025 
01026     if (disktypestring.upper() == "TAPE") {
01027         disktype = disktype | TDEDiskDeviceType::Tape;
01028     }
01029 
01030     if ((disktypestring.upper() == "COMPACT_FLASH")
01031         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_CF")) == "1")
01032         || (TQString(udev_device_get_property_value(dev, "ID_ATA_CFA")) == "1")) {
01033         disktype = disktype | TDEDiskDeviceType::CompactFlash;
01034         disktype = disktype | TDEDiskDeviceType::HDD;
01035     }
01036 
01037     if ((disktypestring.upper() == "MEMORY_STICK")
01038         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MS")) == "1")) {
01039         disktype = disktype | TDEDiskDeviceType::MemoryStick;
01040         disktype = disktype | TDEDiskDeviceType::HDD;
01041     }
01042 
01043     if ((disktypestring.upper() == "SMART_MEDIA")
01044         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SM")) == "1")) {
01045         disktype = disktype | TDEDiskDeviceType::SmartMedia;
01046         disktype = disktype | TDEDiskDeviceType::HDD;
01047     }
01048 
01049     if ((disktypestring.upper() == "SD_MMC")
01050         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SD")) == "1")
01051         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SDHC")) == "1")
01052         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MMC")) == "1")) {
01053         disktype = disktype | TDEDiskDeviceType::SDMMC;
01054         disktype = disktype | TDEDiskDeviceType::HDD;
01055     }
01056 
01057     if ((disktypestring.upper() == "FLASHKEY")
01058         || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH")) == "1")) {
01059         disktype = disktype | TDEDiskDeviceType::Flash;
01060         disktype = disktype | TDEDiskDeviceType::HDD;
01061     }
01062 
01063     if (disktypestring.upper() == "OPTICAL") {
01064         disktype = disktype | TDEDiskDeviceType::Optical;
01065     }
01066 
01067     if (disktypestring.upper() == "JAZ") {
01068         disktype = disktype | TDEDiskDeviceType::Jaz;
01069     }
01070 
01071     if (disktypestring.upper() == "CD") {
01072         disktype = disktype | TDEDiskDeviceType::Optical;
01073 
01074         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) == "1") {
01075             disktype = disktype | TDEDiskDeviceType::CDROM;
01076         }
01077         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_R")) == "1") {
01078             disktype = disktype | TDEDiskDeviceType::CDR;
01079             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01080         }
01081         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_RW")) == "1") {
01082             disktype = disktype | TDEDiskDeviceType::CDRW;
01083             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01084             disktype = disktype & ~TDEDiskDeviceType::CDR;
01085         }
01086         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW")) == "1") {
01087             disktype = disktype | TDEDiskDeviceType::CDMRRW;
01088             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01089             disktype = disktype & ~TDEDiskDeviceType::CDR;
01090             disktype = disktype & ~TDEDiskDeviceType::CDRW;
01091         }
01092         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW_W")) == "1") {
01093             disktype = disktype | TDEDiskDeviceType::CDMRRWW;
01094             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01095             disktype = disktype & ~TDEDiskDeviceType::CDR;
01096             disktype = disktype & ~TDEDiskDeviceType::CDRW;
01097             disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
01098         }
01099         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MO")) == "1") {
01100             disktype = disktype | TDEDiskDeviceType::CDMO;
01101             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01102             disktype = disktype & ~TDEDiskDeviceType::CDR;
01103             disktype = disktype & ~TDEDiskDeviceType::CDRW;
01104             disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
01105             disktype = disktype & ~TDEDiskDeviceType::CDMRRWW;
01106         }
01107         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD")) == "1") {
01108             disktype = disktype | TDEDiskDeviceType::DVDROM;
01109             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01110         }
01111         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RAM")) == "1") {
01112             disktype = disktype | TDEDiskDeviceType::DVDRAM;
01113             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01114         }
01115         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R")) == "1") {
01116             disktype = disktype | TDEDiskDeviceType::DVDR;
01117             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01118         }
01119         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R_DL")) == "1") {
01120             disktype = disktype | TDEDiskDeviceType::DVDRDL;
01121             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01122             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01123         }
01124         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R")) == "1") {
01125             disktype = disktype | TDEDiskDeviceType::DVDPLUSR;
01126             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01127             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01128             disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
01129         }
01130         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R_DL")) == "1") {
01131             disktype = disktype | TDEDiskDeviceType::DVDPLUSRDL;
01132             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01133             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01134             disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
01135             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
01136         }
01137         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW")) == "1") {
01138             disktype = disktype | TDEDiskDeviceType::DVDRW;
01139             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01140             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01141             disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
01142             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
01143             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
01144         }
01145         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW_DL")) == "1") {
01146             disktype = disktype | TDEDiskDeviceType::DVDRWDL;
01147             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01148             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01149             disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
01150             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
01151             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
01152             disktype = disktype & ~TDEDiskDeviceType::DVDRW;
01153         }
01154         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW")) == "1") {
01155             disktype = disktype | TDEDiskDeviceType::DVDPLUSRW;
01156             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01157             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01158             disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
01159             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
01160             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
01161             disktype = disktype & ~TDEDiskDeviceType::DVDRW;
01162             disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
01163         }
01164         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW_DL")) == "1") {
01165             disktype = disktype | TDEDiskDeviceType::DVDPLUSRWDL;
01166             disktype = disktype & ~TDEDiskDeviceType::DVDROM;
01167             disktype = disktype & ~TDEDiskDeviceType::DVDR;
01168             disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
01169             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
01170             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
01171             disktype = disktype & ~TDEDiskDeviceType::DVDRW;
01172             disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
01173             disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRW;
01174         }
01175         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD")) == "1") {
01176             disktype = disktype | TDEDiskDeviceType::BDROM;
01177             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01178         }
01179         if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_R")) == "1")
01180             || (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!)
01181             ) {
01182             disktype = disktype | TDEDiskDeviceType::BDR;
01183             disktype = disktype & ~TDEDiskDeviceType::BDROM;
01184         }
01185         if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_RE")) == "1")
01186             || (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!)
01187             ) {
01188             disktype = disktype | TDEDiskDeviceType::BDRW;
01189             disktype = disktype & ~TDEDiskDeviceType::BDROM;
01190             disktype = disktype & ~TDEDiskDeviceType::BDR;
01191         }
01192         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD")) == "1") {
01193             disktype = disktype | TDEDiskDeviceType::HDDVDROM;
01194             disktype = disktype & ~TDEDiskDeviceType::CDROM;
01195         }
01196         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_R")) == "1") {
01197             disktype = disktype | TDEDiskDeviceType::HDDVDR;
01198             disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
01199         }
01200         if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_RW")) == "1") {
01201             disktype = disktype | TDEDiskDeviceType::HDDVDRW;
01202             disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
01203             disktype = disktype & ~TDEDiskDeviceType::HDDVDR;
01204         }
01205         if (!TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO")).isNull()) {
01206             disktype = disktype | TDEDiskDeviceType::CDAudio;
01207         }
01208         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")) {
01209             disktype = disktype | TDEDiskDeviceType::CDVideo;
01210         }
01211 
01212         if ((disktype & TDEDiskDeviceType::DVDROM)
01213             || (disktype & TDEDiskDeviceType::DVDRAM)
01214             || (disktype & TDEDiskDeviceType::DVDR)
01215             || (disktype & TDEDiskDeviceType::DVDRW)
01216             || (disktype & TDEDiskDeviceType::DVDRDL)
01217             || (disktype & TDEDiskDeviceType::DVDRWDL)
01218             || (disktype & TDEDiskDeviceType::DVDPLUSR)
01219             || (disktype & TDEDiskDeviceType::DVDPLUSRW)
01220             || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
01221             || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
01222             ) {
01223                 // Every VideoDVD must have a VIDEO_TS.IFO file
01224                 // Read this info via tdeiso_info, since udev couldn't be bothered to check DVD type on its own
01225                 int retcode = system(TQString("tdeiso_info --exists=ISO9660/VIDEO_TS/VIDEO_TS.IFO %1").arg(devicenode).ascii());
01226                 if (retcode == 0) {
01227                     disktype = disktype | TDEDiskDeviceType::DVDVideo;
01228                 }
01229         }
01230 
01231     }
01232 
01233     // Detect RAM and Loop devices, since udev can't seem to...
01234     if (systempath.startsWith("/sys/devices/virtual/block/ram")) {
01235         disktype = disktype | TDEDiskDeviceType::RAM;
01236     }
01237     if (systempath.startsWith("/sys/devices/virtual/block/loop")) {
01238         disktype = disktype | TDEDiskDeviceType::Loop;
01239     }
01240 
01241     if (disktype == TDEDiskDeviceType::Null) {
01242         // Fallback
01243         // If we can't recognize the disk type then set it as a simple HDD volume
01244         disktype = disktype | TDEDiskDeviceType::HDD;
01245     }
01246 
01247     if (filesystemtype.upper() == "CRYPTO_LUKS") {
01248         disktype = disktype | TDEDiskDeviceType::LUKS;
01249     }
01250     else if (filesystemtype.upper() == "CRYPTO") {
01251         disktype = disktype | TDEDiskDeviceType::OtherCrypted;
01252     }
01253 
01254     return disktype;
01255 }
01256 
01257     // TDEStandardDirs::kde_default
01258 
01259 typedef TQMap<TQString, TQString> TDEConfigMap;
01260 
01261 TQString readUdevAttribute(udev_device* dev, TQString attr) {
01262     return TQString(udev_device_get_property_value(dev, attr.ascii()));
01263 }
01264 
01265 TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQString query) {
01266     TDEGenericDeviceType::TDEGenericDeviceType ret = TDEGenericDeviceType::Other;
01267 
01268     // Keep this in sync with the TDEGenericDeviceType definition in the header
01269     if (query == "Root") {
01270         ret = TDEGenericDeviceType::Root;
01271     }
01272     else if (query == "RootSystem") {
01273         ret = TDEGenericDeviceType::RootSystem;
01274     }
01275     else if (query == "CPU") {
01276         ret = TDEGenericDeviceType::CPU;
01277     }
01278     else if (query == "GPU") {
01279         ret = TDEGenericDeviceType::GPU;
01280     }
01281     else if (query == "RAM") {
01282         ret = TDEGenericDeviceType::RAM;
01283     }
01284     else if (query == "Bus") {
01285         ret = TDEGenericDeviceType::Bus;
01286     }
01287     else if (query == "I2C") {
01288         ret = TDEGenericDeviceType::I2C;
01289     }
01290     else if (query == "MDIO") {
01291         ret = TDEGenericDeviceType::MDIO;
01292     }
01293     else if (query == "Mainboard") {
01294         ret = TDEGenericDeviceType::Mainboard;
01295     }
01296     else if (query == "Disk") {
01297         ret = TDEGenericDeviceType::Disk;
01298     }
01299     else if (query == "SCSI") {
01300         ret = TDEGenericDeviceType::SCSI;
01301     }
01302     else if (query == "StorageController") {
01303         ret = TDEGenericDeviceType::StorageController;
01304     }
01305     else if (query == "Mouse") {
01306         ret = TDEGenericDeviceType::Mouse;
01307     }
01308     else if (query == "Keyboard") {
01309         ret = TDEGenericDeviceType::Keyboard;
01310     }
01311     else if (query == "HID") {
01312         ret = TDEGenericDeviceType::HID;
01313     }
01314     else if (query == "Modem") {
01315         ret = TDEGenericDeviceType::Modem;
01316     }
01317     else if (query == "Monitor") {
01318         ret = TDEGenericDeviceType::Monitor;
01319     }
01320     else if (query == "Network") {
01321         ret = TDEGenericDeviceType::Network;
01322     }
01323     else if (query == "NonvolatileMemory") {
01324         ret = TDEGenericDeviceType::NonvolatileMemory;
01325     }
01326     else if (query == "Printer") {
01327         ret = TDEGenericDeviceType::Printer;
01328     }
01329     else if (query == "Scanner") {
01330         ret = TDEGenericDeviceType::Scanner;
01331     }
01332     else if (query == "Sound") {
01333         ret = TDEGenericDeviceType::Sound;
01334     }
01335     else if (query == "VideoCapture") {
01336         ret = TDEGenericDeviceType::VideoCapture;
01337     }
01338     else if (query == "IEEE1394") {
01339         ret = TDEGenericDeviceType::IEEE1394;
01340     }
01341     else if (query == "PCMCIA") {
01342         ret = TDEGenericDeviceType::PCMCIA;
01343     }
01344     else if (query == "Camera") {
01345         ret = TDEGenericDeviceType::Camera;
01346     }
01347     else if (query == "Serial") {
01348         ret = TDEGenericDeviceType::Serial;
01349     }
01350     else if (query == "Parallel") {
01351         ret = TDEGenericDeviceType::Parallel;
01352     }
01353     else if (query == "TextIO") {
01354         ret = TDEGenericDeviceType::TextIO;
01355     }
01356     else if (query == "Peripheral") {
01357         ret = TDEGenericDeviceType::Peripheral;
01358     }
01359     else if (query == "Backlight") {
01360         ret = TDEGenericDeviceType::Backlight;
01361     }
01362     else if (query == "Battery") {
01363         ret = TDEGenericDeviceType::Battery;
01364     }
01365     else if (query == "Power") {
01366         ret = TDEGenericDeviceType::PowerSupply;
01367     }
01368     else if (query == "Dock") {
01369         ret = TDEGenericDeviceType::Dock;
01370     }
01371     else if (query == "ThermalSensor") {
01372         ret = TDEGenericDeviceType::ThermalSensor;
01373     }
01374     else if (query == "ThermalControl") {
01375         ret = TDEGenericDeviceType::ThermalControl;
01376     }
01377     else if (query == "Bluetooth") {
01378         ret = TDEGenericDeviceType::BlueTooth;
01379     }
01380     else if (query == "Bridge") {
01381         ret = TDEGenericDeviceType::Bridge;
01382     }
01383     else if (query == "Hub") {
01384         ret = TDEGenericDeviceType::Hub;
01385     }
01386     else if (query == "Platform") {
01387         ret = TDEGenericDeviceType::Platform;
01388     }
01389     else if (query == "Cryptography") {
01390         ret = TDEGenericDeviceType::Cryptography;
01391     }
01392     else if (query == "CryptographicCard") {
01393         ret = TDEGenericDeviceType::CryptographicCard;
01394     }
01395     else if (query == "BiometricSecurity") {
01396         ret = TDEGenericDeviceType::BiometricSecurity;
01397     }
01398     else if (query == "TestAndMeasurement") {
01399         ret = TDEGenericDeviceType::TestAndMeasurement;
01400     }
01401     else if (query == "Timekeeping") {
01402         ret = TDEGenericDeviceType::Timekeeping;
01403     }
01404     else if (query == "Event") {
01405         ret = TDEGenericDeviceType::Event;
01406     }
01407     else if (query == "Input") {
01408         ret = TDEGenericDeviceType::Input;
01409     }
01410     else if (query == "PNP") {
01411         ret = TDEGenericDeviceType::PNP;
01412     }
01413     else if (query == "OtherACPI") {
01414         ret = TDEGenericDeviceType::OtherACPI;
01415     }
01416     else if (query == "OtherUSB") {
01417         ret = TDEGenericDeviceType::OtherUSB;
01418     }
01419     else if (query == "OtherMultimedia") {
01420         ret = TDEGenericDeviceType::OtherMultimedia;
01421     }
01422     else if (query == "OtherPeripheral") {
01423         ret = TDEGenericDeviceType::OtherPeripheral;
01424     }
01425     else if (query == "OtherSensor") {
01426         ret = TDEGenericDeviceType::OtherSensor;
01427     }
01428     else if (query == "OtherVirtual") {
01429         ret = TDEGenericDeviceType::OtherVirtual;
01430     }
01431     else {
01432         ret = TDEGenericDeviceType::Other;
01433     }
01434 
01435     return ret;
01436 }
01437 
01438 TDEDiskDeviceType::TDEDiskDeviceType readDiskDeviceSubtypeFromString(TQString query, TDEDiskDeviceType::TDEDiskDeviceType flagsIn=TDEDiskDeviceType::Null) {
01439     TDEDiskDeviceType::TDEDiskDeviceType ret = flagsIn;
01440 
01441     // Keep this in sync with the TDEDiskDeviceType definition in the header
01442     if (query == "MediaDevice") {
01443         ret = ret | TDEDiskDeviceType::MediaDevice;
01444     }
01445     if (query == "Floppy") {
01446         ret = ret | TDEDiskDeviceType::Floppy;
01447     }
01448     if (query == "CDROM") {
01449         ret = ret | TDEDiskDeviceType::CDROM;
01450     }
01451     if (query == "CDR") {
01452         ret = ret | TDEDiskDeviceType::CDR;
01453     }
01454     if (query == "CDRW") {
01455         ret = ret | TDEDiskDeviceType::CDRW;
01456     }
01457     if (query == "CDMO") {
01458         ret = ret | TDEDiskDeviceType::CDMO;
01459     }
01460     if (query == "CDMRRW") {
01461         ret = ret | TDEDiskDeviceType::CDMRRW;
01462     }
01463     if (query == "CDMRRWW") {
01464         ret = ret | TDEDiskDeviceType::CDMRRWW;
01465     }
01466     if (query == "DVDROM") {
01467         ret = ret | TDEDiskDeviceType::DVDROM;
01468     }
01469     if (query == "DVDRAM") {
01470         ret = ret | TDEDiskDeviceType::DVDRAM;
01471     }
01472     if (query == "DVDR") {
01473         ret = ret | TDEDiskDeviceType::DVDR;
01474     }
01475     if (query == "DVDRW") {
01476         ret = ret | TDEDiskDeviceType::DVDRW;
01477     }
01478     if (query == "DVDRDL") {
01479         ret = ret | TDEDiskDeviceType::DVDRDL;
01480     }
01481     if (query == "DVDRWDL") {
01482         ret = ret | TDEDiskDeviceType::DVDRWDL;
01483     }
01484     if (query == "DVDPLUSR") {
01485         ret = ret | TDEDiskDeviceType::DVDPLUSR;
01486     }
01487     if (query == "DVDPLUSRW") {
01488         ret = ret | TDEDiskDeviceType::DVDPLUSRW;
01489     }
01490     if (query == "DVDPLUSRDL") {
01491         ret = ret | TDEDiskDeviceType::DVDPLUSRDL;
01492     }
01493     if (query == "DVDPLUSRWDL") {
01494         ret = ret | TDEDiskDeviceType::DVDPLUSRWDL;
01495     }
01496     if (query == "BDROM") {
01497         ret = ret | TDEDiskDeviceType::BDROM;
01498     }
01499     if (query == "BDR") {
01500         ret = ret | TDEDiskDeviceType::BDR;
01501     }
01502     if (query == "BDRW") {
01503         ret = ret | TDEDiskDeviceType::BDRW;
01504     }
01505     if (query == "HDDVDROM") {
01506         ret = ret | TDEDiskDeviceType::HDDVDROM;
01507     }
01508     if (query == "HDDVDR") {
01509         ret = ret | TDEDiskDeviceType::HDDVDR;
01510     }
01511     if (query == "HDDVDRW") {
01512         ret = ret | TDEDiskDeviceType::HDDVDRW;
01513     }
01514     if (query == "Zip") {
01515         ret = ret | TDEDiskDeviceType::Zip;
01516     }
01517     if (query == "Jaz") {
01518         ret = ret | TDEDiskDeviceType::Jaz;
01519     }
01520     if (query == "Camera") {
01521         ret = ret | TDEDiskDeviceType::Camera;
01522     }
01523     if (query == "LUKS") {
01524         ret = ret | TDEDiskDeviceType::LUKS;
01525     }
01526     if (query == "OtherCrypted") {
01527         ret = ret | TDEDiskDeviceType::OtherCrypted;
01528     }
01529     if (query == "CDAudio") {
01530         ret = ret | TDEDiskDeviceType::CDAudio;
01531     }
01532     if (query == "CDVideo") {
01533         ret = ret | TDEDiskDeviceType::CDVideo;
01534     }
01535     if (query == "DVDVideo") {
01536         ret = ret | TDEDiskDeviceType::DVDVideo;
01537     }
01538     if (query == "BDVideo") {
01539         ret = ret | TDEDiskDeviceType::BDVideo;
01540     }
01541     if (query == "Flash") {
01542         ret = ret | TDEDiskDeviceType::Flash;
01543     }
01544     if (query == "USB") {
01545         ret = ret | TDEDiskDeviceType::USB;
01546     }
01547     if (query == "Tape") {
01548         ret = ret | TDEDiskDeviceType::Tape;
01549     }
01550     if (query == "HDD") {
01551         ret = ret | TDEDiskDeviceType::HDD;
01552     }
01553     if (query == "Optical") {
01554         ret = ret | TDEDiskDeviceType::Optical;
01555     }
01556     if (query == "RAM") {
01557         ret = ret | TDEDiskDeviceType::RAM;
01558     }
01559     if (query == "Loop") {
01560         ret = ret | TDEDiskDeviceType::Loop;
01561     }
01562     if (query == "CompactFlash") {
01563         ret = ret | TDEDiskDeviceType::CompactFlash;
01564     }
01565     if (query == "MemoryStick") {
01566         ret = ret | TDEDiskDeviceType::MemoryStick;
01567     }
01568     if (query == "SmartMedia") {
01569         ret = ret | TDEDiskDeviceType::SmartMedia;
01570     }
01571     if (query == "SDMMC") {
01572         ret = ret | TDEDiskDeviceType::SDMMC;
01573     }
01574     if (query == "UnlockedCrypt") {
01575         ret = ret | TDEDiskDeviceType::UnlockedCrypt;
01576     }
01577 
01578     return ret;
01579 }
01580 
01581 TDEGenericDevice* createDeviceObjectForType(TDEGenericDeviceType::TDEGenericDeviceType type) {
01582     TDEGenericDevice* ret = 0;
01583 
01584     if (type == TDEGenericDeviceType::Disk) {
01585         ret = new TDEStorageDevice(type);
01586     }
01587     else {
01588         ret = new TDEGenericDevice(type);
01589     }
01590 
01591     return ret;
01592 }
01593 
01594 TDEGenericDevice* TDEHardwareDevices::classifyUnknownDeviceByExternalRules(udev_device* dev, TDEGenericDevice* existingdevice, bool classifySubDevices) {
01595     // This routine expects to see the hardware config files into <prefix>/share/apps/tdehwlib/deviceclasses/, suffixed with "hwclass"
01596     TDEGenericDevice* device = existingdevice;
01597     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
01598 
01599     // Handle subtype if needed/desired
01600     // To speed things up we rely on the prior scan results stored in m_externalSubtype
01601     if (classifySubDevices) {
01602         if (!device->m_externalRulesFile.isNull()) {
01603             if (device->type() == TDEGenericDeviceType::Disk) {
01604                 // Disk class
01605                 TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
01606                 TQStringList subtype = device->m_externalSubtype;
01607                 TDEDiskDeviceType::TDEDiskDeviceType desiredSubdeviceType = TDEDiskDeviceType::Null;
01608                 if (subtype.count()>0) {
01609                     for ( TQStringList::Iterator paramit = subtype.begin(); paramit != subtype.end(); ++paramit ) {
01610                         desiredSubdeviceType = readDiskDeviceSubtypeFromString(*paramit, desiredSubdeviceType);
01611                     }
01612                     if (desiredSubdeviceType != sdevice->diskType()) {
01613                         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);
01614                         sdevice->internalSetDiskType(desiredSubdeviceType);
01615                     }
01616                 }
01617             }
01618         }
01619     }
01620     else {
01621         TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
01622         TQString hardware_info_directory_suffix("tdehwlib/deviceclasses/");
01623         TQString hardware_info_directory;
01624 
01625         // Scan the hardware_info_directory for configuration files
01626         // For each one, open it with TDEConfig() and apply its rules to classify the device
01627         // FIXME
01628         // Should this also scan up to <n> subdirectories for the files?  That feature might end up being too expensive...
01629 
01630         device->m_externalRulesFile = TQString::null;
01631         for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
01632             hardware_info_directory = (*it);
01633             hardware_info_directory += hardware_info_directory_suffix;
01634 
01635             if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
01636                 TQDir d(hardware_info_directory);
01637                 d.setFilter( TQDir::Files | TQDir::Hidden );
01638 
01639                 const TQFileInfoList *list = d.entryInfoList();
01640                 TQFileInfoListIterator it( *list );
01641                 TQFileInfo *fi;
01642 
01643                 while ((fi = it.current()) != 0) {
01644                     if (fi->extension(false) == "hwclass") {
01645                         bool match = true;
01646 
01647                         // Open the rules file
01648                         TDEConfig rulesFile(fi->absFilePath(), true, false);
01649                         rulesFile.setGroup("Conditions");
01650                         TDEConfigMap conditionmap = rulesFile.entryMap("Conditions");
01651                         TDEConfigMap::Iterator cndit;
01652                         for (cndit = conditionmap.begin(); cndit != conditionmap.end(); ++cndit) {
01653                             TQStringList conditionList = TQStringList::split(',', cndit.data(), false);
01654                             bool atleastonematch = false;
01655                             bool allmatch = true;
01656                             TQString matchtype = rulesFile.readEntry("MATCH_TYPE", "All");
01657                             if (conditionList.count() < 1) {
01658                                 allmatch = false;
01659                             }
01660                             else {
01661                                 for ( TQStringList::Iterator paramit = conditionList.begin(); paramit != conditionList.end(); ++paramit ) {
01662                                     if ((*paramit) == "MatchType") {
01663                                         continue;
01664                                     }
01665                                     if (cndit.key() == "VENDOR_ID") {
01666                                         if (device->vendorID() == (*paramit)) {
01667                                             atleastonematch = true;
01668                                         }
01669                                         else {
01670                                             allmatch = false;
01671                                         }
01672                                     }
01673                                     else if (cndit.key() == "MODEL_ID") {
01674                                         if (device->modelID() == (*paramit)) {
01675                                             atleastonematch = true;
01676                                         }
01677                                         else {
01678                                             allmatch = false;
01679                                         }
01680                                     }
01681                                     else if (cndit.key() == "DRIVER") {
01682                                         if (device->deviceDriver() == (*paramit)) {
01683                                             atleastonematch = true;
01684                                         }
01685                                         else {
01686                                             allmatch = false;
01687                                         }
01688                                     }
01689                                     else {
01690                                         if (readUdevAttribute(dev, cndit.key()) == (*paramit)) {
01691                                             atleastonematch = true;
01692                                         }
01693                                         else {
01694                                             allmatch = false;
01695                                         }
01696                                     }
01697                                 }
01698                             }
01699                             if (matchtype == "All") {
01700                                 if (!allmatch) {
01701                                     match = false;
01702                                 }
01703                             }
01704                             else if (matchtype == "Any") {
01705                                 if (!atleastonematch) {
01706                                     match = false;
01707                                 }
01708                             }
01709                             else {
01710                                 match = false;
01711                             }
01712                         }
01713 
01714                         if (match) {
01715                             rulesFile.setGroup("DeviceType");
01716                             TQString gentype = rulesFile.readEntry("GENTYPE");
01717                             TDEGenericDeviceType::TDEGenericDeviceType desiredDeviceType = device->type();
01718                             if (!gentype.isNull()) {
01719                                 desiredDeviceType = readGenericDeviceTypeFromString(gentype);
01720                             }
01721 
01722                             // Handle main type
01723                             if (desiredDeviceType != device->type()) {
01724                                 printf("[tdehardwaredevices] Rules file %s used to set device type for device at path %s\n", fi->absFilePath().ascii(), device->systemPath().ascii()); fflush(stdout);
01725                                 if (m_deviceList.contains(device)) {
01726                                     m_deviceList.remove(device);
01727                                 }
01728                                 else {
01729                                     delete device;
01730                                 }
01731                                 device = createDeviceObjectForType(desiredDeviceType);
01732                             }
01733 
01734                             // Parse subtype and store in m_externalSubtype for later
01735                             // This speeds things up considerably due to the expense of the file scanning/parsing/matching operation
01736                             device->m_externalSubtype = rulesFile.readListEntry("SUBTYPE", ',');
01737                             device->m_externalRulesFile = fi->absFilePath();
01738 
01739                             // Process blacklist entries
01740                             rulesFile.setGroup("DeviceSettings");
01741                             device->internalSetBlacklistedForUpdate(rulesFile.readBoolEntry("UPDATE_BLACKLISTED", device->blacklistedForUpdate()));
01742                         }
01743                     }
01744                     ++it;
01745                 }
01746             }
01747         }
01748     }
01749 
01750     return device;
01751 }
01752 
01753 TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice, bool force_full_classification) {
01754     // Classify device and create TDEHW device object
01755     TQString devicename;
01756     TQString devicetype;
01757     TQString devicedriver;
01758     TQString devicesubsystem;
01759     TQString devicenode;
01760     TQString systempath;
01761     TQString devicevendorid;
01762     TQString devicemodelid;
01763     TQString devicevendoridenc;
01764     TQString devicemodelidenc;
01765     TQString devicesubvendorid;
01766     TQString devicesubmodelid;
01767     TQString devicetypestring;
01768     TQString devicetypestring_alt;
01769     TQString devicepciclass;
01770     TDEGenericDevice* device = existingdevice;
01771     bool temp_udev_device = !dev;
01772     if (dev) {
01773         devicename = (udev_device_get_sysname(dev));
01774         devicetype = (udev_device_get_devtype(dev));
01775         devicedriver = (udev_device_get_driver(dev));
01776         devicesubsystem = (udev_device_get_subsystem(dev));
01777         devicenode = (udev_device_get_devnode(dev));
01778         systempath = (udev_device_get_syspath(dev));
01779         systempath += "/";
01780         devicevendorid = (udev_device_get_property_value(dev, "ID_VENDOR_ID"));
01781         devicemodelid = (udev_device_get_property_value(dev, "ID_MODEL_ID"));
01782         devicevendoridenc = (udev_device_get_property_value(dev, "ID_VENDOR_ENC"));
01783         devicemodelidenc = (udev_device_get_property_value(dev, "ID_MODEL_ENC"));
01784         devicesubvendorid = (udev_device_get_property_value(dev, "ID_SUBVENDOR_ID"));
01785         devicesubmodelid = (udev_device_get_property_value(dev, "ID_SUBMODEL_ID"));
01786         devicetypestring = (udev_device_get_property_value(dev, "ID_TYPE"));
01787         devicetypestring_alt = (udev_device_get_property_value(dev, "DEVTYPE"));
01788         devicepciclass = (udev_device_get_property_value(dev, "PCI_CLASS"));
01789     }
01790     else {
01791         if (device) {
01792             devicename = device->name();
01793             devicetype = device->m_udevtype;
01794             devicedriver = device->deviceDriver();
01795             devicesubsystem = device->subsystem();
01796             devicenode = device->deviceNode();
01797             systempath = device->systemPath();
01798             devicevendorid = device->vendorID();
01799             devicemodelid = device->modelID();
01800             devicevendoridenc = device->vendorEncoded();
01801             devicemodelidenc = device->modelEncoded();
01802             devicesubvendorid = device->subVendorID();
01803             devicesubmodelid = device->subModelID();
01804             devicetypestring = device->m_udevdevicetypestring;
01805             devicetypestring_alt = device->udevdevicetypestring_alt;
01806             devicepciclass = device->PCIClass();
01807         }
01808         TQString syspathudev = systempath;
01809         syspathudev.truncate(syspathudev.length()-1);   // Remove trailing slash
01810         dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
01811     }
01812 
01813     // FIXME
01814     // Only a small subset of devices are classified right now
01815     // Figure out the remaining udev logic to classify the rest!
01816     // Helpful file: http://www.enlightenment.org/svn/e/trunk/PROTO/enna-explorer/src/bin/udev.c
01817 
01818     bool done = false;
01819     TQString current_path = systempath;
01820     TQString devicemodalias = TQString::null;
01821 
01822     while (done == false) {
01823         TQString malnodename = current_path;
01824         malnodename.append("/modalias");
01825         TQFile malfile(malnodename);
01826         if (malfile.open(IO_ReadOnly)) {
01827             TQTextStream stream( &malfile );
01828             devicemodalias = stream.readLine();
01829             malfile.close();
01830         }
01831         if (devicemodalias.startsWith("pci") || devicemodalias.startsWith("usb")) {
01832             done = true;
01833         }
01834         else {
01835             devicemodalias = TQString::null;
01836             current_path.truncate(current_path.findRev("/"));
01837             if (!current_path.startsWith("/sys/devices")) {
01838                 // Abort!
01839                 done = true;
01840             }
01841         }
01842     }
01843 
01844     // Many devices do not provide their vendor/model ID via udev
01845     // Worse, sometimes udev provides an invalid model ID!
01846     // Go after it manually if needed...
01847     if (devicevendorid.isNull() || devicemodelid.isNull() || devicemodelid.contains("/")) {
01848         if (devicemodalias != TQString::null) {
01849             // For added fun the device string lengths differ between pci and usb
01850             if (devicemodalias.startsWith("pci")) {
01851                 int vloc = devicemodalias.find("v");
01852                 int dloc = devicemodalias.find("d", vloc);
01853                 int svloc = devicemodalias.find("sv");
01854                 int sdloc = devicemodalias.find("sd", vloc);
01855 
01856                 devicevendorid = devicemodalias.mid(vloc+1, 8).lower();
01857                 devicemodelid = devicemodalias.mid(dloc+1, 8).lower();
01858                 if (svloc != -1) {
01859                     devicesubvendorid = devicemodalias.mid(svloc+1, 8).lower();
01860                     devicesubmodelid = devicemodalias.mid(sdloc+1, 8).lower();
01861                 }
01862                 devicevendorid.remove(0,4);
01863                 devicemodelid.remove(0,4);
01864                 devicesubvendorid.remove(0,4);
01865                 devicesubmodelid.remove(0,4);
01866             }
01867             if (devicemodalias.startsWith("usb")) {
01868                 int vloc = devicemodalias.find("v");
01869                 int dloc = devicemodalias.find("p", vloc);
01870                 int svloc = devicemodalias.find("sv");
01871                 int sdloc = devicemodalias.find("sp", vloc);
01872 
01873                 devicevendorid = devicemodalias.mid(vloc+1, 4).lower();
01874                 devicemodelid = devicemodalias.mid(dloc+1, 4).lower();
01875                 if (svloc != -1) {
01876                     devicesubvendorid = devicemodalias.mid(svloc+1, 4).lower();
01877                     devicesubmodelid = devicemodalias.mid(sdloc+1, 4).lower();
01878                 }
01879             }
01880         }
01881     }
01882 
01883     // Most of the time udev doesn't barf up a device driver either, so go after it manually...
01884     if (devicedriver.isNull()) {
01885         TQString driverSymlink = udev_device_get_syspath(dev);
01886         TQString driverSymlinkDir = driverSymlink;
01887         driverSymlink.append("/device/driver");
01888         driverSymlinkDir.append("/device/");
01889         TQFileInfo dirfi(driverSymlink);
01890         if (dirfi.isSymLink()) {
01891             char* collapsedPath = realpath((driverSymlinkDir + dirfi.readLink()).ascii(), NULL);
01892             devicedriver = TQString(collapsedPath);
01893             free(collapsedPath);
01894             devicedriver.remove(0, devicedriver.findRev("/")+1);
01895         }
01896     }
01897 
01898     // udev removes critical leading zeroes in the PCI device class, so go after it manually...
01899     TQString classnodename = systempath;
01900     classnodename.append("/class");
01901     TQFile classfile( classnodename );
01902     if ( classfile.open( IO_ReadOnly ) ) {
01903         TQTextStream stream( &classfile );
01904         devicepciclass = stream.readLine();
01905         devicepciclass.replace("0x", "");
01906         devicepciclass = devicepciclass.lower();
01907         classfile.close();
01908     }
01909 
01910     // Classify generic device type and create appropriate object
01911 
01912     // Pull out all event special devices and stuff them under Event
01913     TQString syspath_tail = systempath.lower();
01914     syspath_tail.truncate(syspath_tail.length()-1);
01915     syspath_tail.remove(0, syspath_tail.findRev("/")+1);
01916     if (syspath_tail.startsWith("event")) {
01917         if (!device) device = new TDEEventDevice(TDEGenericDeviceType::Event);
01918     }
01919     // Pull out all input special devices and stuff them under Input
01920     if (syspath_tail.startsWith("input")) {
01921         if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
01922     }
01923     // Pull out remote-control devices and stuff them under Input
01924     if (devicesubsystem == "rc") {
01925         if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
01926     }
01927 
01928     // Check for keyboard
01929     // Linux doesn't actually ID the keyboard device itself as such, it instead IDs the input device that is underneath the actual keyboard itseld
01930     // Therefore we need to scan <syspath>/input/input* for the ID_INPUT_KEYBOARD attribute
01931     bool is_keyboard = false;
01932     TQString inputtopdirname = udev_device_get_syspath(dev);
01933     inputtopdirname.append("/input/");
01934     TQDir inputdir(inputtopdirname);
01935     inputdir.setFilter(TQDir::All);
01936     const TQFileInfoList *dirlist = inputdir.entryInfoList();
01937     if (dirlist) {
01938         TQFileInfoListIterator inputdirsit(*dirlist);
01939         TQFileInfo *dirfi;
01940         while ( (dirfi = inputdirsit.current()) != 0 ) {
01941             if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
01942                 struct udev_device *slavedev;
01943                 slavedev = udev_device_new_from_syspath(m_udevStruct, (inputtopdirname + dirfi->fileName()).ascii());
01944                 if (udev_device_get_property_value(slavedev, "ID_INPUT_KEYBOARD") != 0) {
01945                     is_keyboard = true;
01946                 }
01947                 udev_device_unref(slavedev);
01948             }
01949             ++inputdirsit;
01950         }
01951     }
01952     if (is_keyboard) {
01953         if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
01954     }
01955 
01956     // Classify specific known devices
01957     if (((devicetype == "disk")
01958         || (devicetype == "partition")
01959         || (devicedriver == "floppy")
01960         || (devicesubsystem == "scsi_disk")
01961         || (devicesubsystem == "scsi_tape"))
01962         && ((devicenode != "")
01963         )) {
01964         if (!device) device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
01965     }
01966     else if (devicetype == "host") {
01967         if (devicesubsystem == "bluetooth") {
01968             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BlueTooth);
01969         }
01970     }
01971     else if (devicetype.isNull()) {
01972         if (devicesubsystem == "acpi") {
01973             // If the ACPI device exposes a system path ending in /PNPxxxx:yy, the device type can be precisely determined
01974             // See ftp://ftp.microsoft.com/developr/drg/plug-and-play/devids.txt for more information
01975             TQString pnpgentype = systempath;
01976             pnpgentype.remove(0, pnpgentype.findRev("/")+1);
01977             pnpgentype.truncate(pnpgentype.find(":"));
01978             if (pnpgentype.startsWith("PNP")) {
01979                 // 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
01980                 // Furthermore, the "real" device elsewhere almost always has more functionality exposed via sysfs
01981                 // Therefore all ACPI subsystem devices should be stuffed in the OtherACPI category and largely ignored
01982                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
01983             }
01984             else {
01985                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
01986             }
01987         }
01988         else if (devicesubsystem == "input") {
01989             // Figure out if this device is a mouse, keyboard, or something else
01990             // Check for mouse
01991             // udev doesn't reliably help here, so guess from the device name
01992             if (systempath.contains("/mouse")) {
01993                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
01994             }
01995             if (!device) {
01996                 // Second mouse check
01997                 // Look for ID_INPUT_MOUSE property presence
01998                 if (udev_device_get_property_value(dev, "ID_INPUT_MOUSE") != 0) {
01999                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
02000                 }
02001             }
02002             if (!device) {
02003                 // Check for keyboard
02004                 // Look for ID_INPUT_KEYBOARD property presence
02005                 if (udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD") != 0) {
02006                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
02007                 }
02008             }
02009             if (!device) {
02010                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
02011             }
02012         }
02013         else if (devicesubsystem == "tty") {
02014             if (devicenode.contains("/ttyS")) {
02015                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
02016             }
02017             else {
02018                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TextIO);
02019             }
02020         }
02021         else if (devicesubsystem == "usb-serial") {
02022             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
02023         }
02024         else if ((devicesubsystem == "spi_master")
02025             || (devicesubsystem == "spidev")) {
02026             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
02027         }
02028         else if (devicesubsystem == "spi") {
02029             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02030         }
02031         else if (devicesubsystem == "watchdog") {
02032             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02033         }
02034         else if (devicesubsystem == "node") {
02035             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02036         }
02037         else if (devicesubsystem == "regulator") {
02038             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02039         }
02040         else if (devicesubsystem == "memory") {
02041             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02042         }
02043         else if (devicesubsystem == "clockevents") {
02044             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02045         }
02046         else if (devicesubsystem == "thermal") {
02047             // FIXME
02048             // Figure out a way to differentiate between ThermalControl (fans and coolers) and ThermalSensor types
02049             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalControl);
02050         }
02051         else if (devicesubsystem == "hwmon") {
02052             // FIXME
02053             // This might pick up thermal sensors
02054             if (!device) device = new TDESensorDevice(TDEGenericDeviceType::OtherSensor);
02055         }
02056         else if (devicesubsystem == "vio") {
02057             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02058         }
02059         else if (devicesubsystem == "virtio") {
02060             if (devicedriver == "virtio_blk") {
02061                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
02062             }
02063             if (devicedriver == "virtio_net") {
02064                 if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
02065             }
02066             if (devicedriver == "virtio_balloon") {
02067                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
02068             }
02069         }
02070     }
02071 
02072     // Try to at least generally classify unclassified devices
02073     if (device == 0) {
02074         if (devicesubsystem == "backlight") {
02075             if (!device) device = new TDEBacklightDevice(TDEGenericDeviceType::Backlight);
02076         }
02077         if (systempath.lower().startsWith("/sys/module/")
02078             || (systempath.lower().startsWith("/sys/kernel/"))) {
02079             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform); // FIXME Should go into a new kernel module category when the tdelibs ABI can be broken again
02080         }
02081         if ((devicetypestring == "audio")
02082             || (devicesubsystem == "sound")
02083             || (devicesubsystem == "hdaudio")
02084             || (devicesubsystem == "ac97")) {
02085             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Sound);
02086         }
02087         if (devicesubsystem == "container") {
02088             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
02089         }
02090         if ((devicesubsystem == "video4linux")
02091             || (devicesubsystem == "dvb")) {
02092             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::VideoCapture);
02093         }
02094         if ((devicetypestring_alt == "scsi_target")
02095             || (devicesubsystem == "scsi_host")
02096             || (devicesubsystem == "scsi_disk")
02097             || (devicesubsystem == "scsi_device")
02098             || (devicesubsystem == "scsi_generic")
02099             || (devicesubsystem == "scsi")
02100             || (devicetypestring_alt == "sas_target")
02101             || (devicesubsystem == "sas_host")
02102             || (devicesubsystem == "sas_port")
02103             || (devicesubsystem == "sas_device")
02104             || (devicesubsystem == "sas_expander")
02105             || (devicesubsystem == "sas_generic")
02106             || (devicesubsystem == "sas_phy")
02107             || (devicesubsystem == "sas_end_device")
02108             || (devicesubsystem == "spi_transport")
02109             || (devicesubsystem == "spi_host")
02110             || (devicesubsystem == "ata_port")
02111             || (devicesubsystem == "ata_link")
02112             || (devicesubsystem == "ata_disk")
02113             || (devicesubsystem == "ata_device")
02114             || (devicesubsystem == "ata")) {
02115             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02116         }
02117         if (devicesubsystem == "infiniband") {
02118             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Peripheral);
02119         }
02120         if ((devicesubsystem == "infiniband_cm")
02121             || (devicesubsystem == "infiniband_mad")
02122             || (devicesubsystem == "infiniband_verbs")) {
02123             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02124         }
02125         if (devicesubsystem == "infiniband_srp") {
02126             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
02127         }
02128         if ((devicesubsystem == "enclosure")
02129             || (devicesubsystem == "clocksource")
02130             || (devicesubsystem == "amba")) {
02131             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02132         }
02133         if (devicesubsystem == "edac") {
02134             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
02135         }
02136         if (devicesubsystem.startsWith("mc") && systempath.contains("/edac/")) {
02137             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
02138         }
02139         if ((devicesubsystem == "ipmi")
02140             || (devicesubsystem == "ipmi_si")) {
02141             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
02142         }
02143         if (devicesubsystem == "iommu") {
02144             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02145         }
02146         if (devicesubsystem == "misc") {
02147             if (devicedriver.startsWith("tpm_")) {
02148                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Cryptography);
02149             }
02150             else {
02151                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02152             }
02153         }
02154         if (devicesubsystem == "media") {
02155             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02156         }
02157         if (devicesubsystem == "nd") {
02158             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
02159         }
02160         if (devicesubsystem == "ptp") {
02161             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Timekeeping);
02162         }
02163         if (devicesubsystem == "leds") {
02164             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
02165         }
02166         if (devicesubsystem == "net") {
02167             if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
02168         }
02169         if ((devicesubsystem == "i2c")
02170             || (devicesubsystem == "i2c-dev")) {
02171             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::I2C);
02172         }
02173         if (devicesubsystem == "mdio_bus") {
02174             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::MDIO);
02175         }
02176         if (devicesubsystem == "graphics") {
02177             if (devicenode.isNull()) {  // GPUs do not have associated device nodes
02178                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
02179             }
02180             else {
02181                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02182             }
02183         }
02184         if (devicesubsystem == "tifm_adapter") {
02185             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
02186         }
02187         if ((devicesubsystem == "mmc_host")
02188             || (devicesubsystem == "memstick_host")) {
02189             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
02190         }
02191         if (devicesubsystem == "mmc") {
02192             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02193         }
02194         if ((devicesubsystem == "event_source")
02195             || (devicesubsystem == "rtc")) {
02196             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
02197         }
02198         if (devicesubsystem == "bsg") {
02199             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
02200         }
02201         if (devicesubsystem == "firewire") {
02202             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::IEEE1394);
02203         }
02204         if (devicesubsystem == "drm") {
02205             if (devicenode.isNull()) {  // Monitors do not have associated device nodes
02206                 if (!device) device = new TDEMonitorDevice(TDEGenericDeviceType::Monitor);
02207             }
02208             else {
02209                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02210             }
02211         }
02212         if (devicesubsystem == "nvmem") {
02213             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::NonvolatileMemory);
02214         }
02215         if (devicesubsystem == "serio") {
02216             if (devicedriver.contains("atkbd")) {
02217                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
02218             }
02219             else if (devicedriver.contains("mouse")) {
02220                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
02221             }
02222             else {
02223                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
02224             }
02225         }
02226         if ((devicesubsystem == "ppdev")
02227             || (devicesubsystem == "parport")) {
02228             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Parallel);
02229         }
02230         if (devicesubsystem == "printer") {
02231             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Printer);
02232         }
02233         if (devicesubsystem == "bridge") {
02234             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
02235         }
02236         if ((devicesubsystem == "pci_bus")
02237             || (devicesubsystem == "pci_express")) {
02238             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bus);
02239         }
02240         if (devicesubsystem == "pcmcia_socket") {
02241             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PCMCIA);
02242         }
02243         if (devicesubsystem == "platform") {
02244             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02245         }
02246         if (devicesubsystem == "ieee80211") {
02247             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02248         }
02249         if (devicesubsystem == "rfkill") {
02250             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02251         }
02252         if (devicesubsystem == "machinecheck") {
02253             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02254         }
02255         if (devicesubsystem == "pnp") {
02256             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PNP);
02257         }
02258         if ((devicesubsystem == "hid")
02259             || (devicesubsystem == "hidraw")
02260             || (devicesubsystem == "usbhid")) {
02261             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
02262         }
02263         if (devicesubsystem == "power_supply") {
02264             TQString powersupplyname(udev_device_get_property_value(dev, "POWER_SUPPLY_NAME"));
02265             if ((devicedriver == "ac")
02266                 || (devicedriver.contains("charger"))
02267                 || (powersupplyname.upper().startsWith("AC"))) {
02268                 if (!device) device = new TDEMainsPowerDevice(TDEGenericDeviceType::PowerSupply);
02269             }
02270             else {
02271                 if (!device) device = new TDEBatteryDevice(TDEGenericDeviceType::Battery);
02272             }
02273         }
02274         if (systempath.lower().startsWith("/sys/devices/virtual")) {
02275             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherVirtual);
02276         }
02277 
02278         // Moderate accuracy classification, if PCI device class is available
02279         // See http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html for codes and meanings
02280         if (!devicepciclass.isNull()) {
02281             // Pre PCI 2.0
02282             if (devicepciclass.startsWith("0001")) {
02283                 if (devicenode.isNull()) {  // GPUs do not have associated device nodes
02284                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
02285                 }
02286                 else {
02287                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02288                 }
02289             }
02290             // Post PCI 2.0
02291             TQString devicepcisubclass = devicepciclass;
02292             devicepcisubclass = devicepcisubclass.remove(0,2);
02293             if (devicepciclass.startsWith("01")) {
02294                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
02295             }
02296             if (devicepciclass.startsWith("02")) {
02297                 if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
02298             }
02299             if (devicepciclass.startsWith("03")) {
02300                 if (devicenode.isNull()) {  // GPUs do not have associated device nodes
02301                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
02302                 }
02303                 else {
02304                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02305                 }
02306             }
02307             if (devicepciclass.startsWith("04")) {
02308                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherMultimedia);
02309             }
02310             if (devicepciclass.startsWith("05")) {
02311                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
02312             }
02313             if (devicepciclass.startsWith("06")) {
02314                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
02315             }
02316             if (devicepciclass.startsWith("07")) {
02317                 if (devicepcisubclass.startsWith("03")) {
02318                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Modem);
02319                 }
02320             }
02321             if (devicepciclass.startsWith("0a")) {
02322                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Dock);
02323             }
02324             if (devicepciclass.startsWith("0b")) {
02325                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::CPU);
02326             }
02327             if (devicepciclass.startsWith("0c")) {
02328                 if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
02329             }
02330         }
02331 
02332         if ((devicesubsystem == "usb")
02333             && (devicedriver == "uvcvideo")) {
02334             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02335         }
02336 
02337         // Last ditch attempt at classification
02338         // Likely inaccurate and sweeping
02339         if ((devicesubsystem == "usb")
02340             || (devicesubsystem == "usbmisc")
02341             || (devicesubsystem == "usb_device")
02342             || (devicesubsystem == "usbmon")) {
02343                 // Get USB interface class for further classification
02344                 int usbInterfaceClass = -1;
02345                 {
02346                     TQFile ifaceprotofile(current_path + "/bInterfaceClass");
02347                     if (ifaceprotofile.open(IO_ReadOnly)) {
02348                         TQTextStream stream( &ifaceprotofile );
02349                         usbInterfaceClass = stream.readLine().toUInt(NULL, 16);
02350                         ifaceprotofile.close();
02351                     }
02352                 }
02353                 // Get USB interface subclass for further classification
02354                 int usbInterfaceSubClass = -1;
02355                 {
02356                     TQFile ifaceprotofile(current_path + "/bInterfaceSubClass");
02357                     if (ifaceprotofile.open(IO_ReadOnly)) {
02358                         TQTextStream stream( &ifaceprotofile );
02359                         usbInterfaceSubClass = stream.readLine().toUInt(NULL, 16);
02360                         ifaceprotofile.close();
02361                     }
02362                 }
02363                 // Get USB interface protocol for further classification
02364                 int usbInterfaceProtocol = -1;
02365                 {
02366                     TQFile ifaceprotofile(current_path + "/bInterfaceProtocol");
02367                     if (ifaceprotofile.open(IO_ReadOnly)) {
02368                         TQTextStream stream( &ifaceprotofile );
02369                         usbInterfaceProtocol = stream.readLine().toUInt(NULL, 16);
02370                         ifaceprotofile.close();
02371                     }
02372                 }
02373                 if ((usbInterfaceClass == 6) && (usbInterfaceSubClass == 1) && (usbInterfaceProtocol == 1)) {
02374                     // PictBridge
02375                     if (!device) {
02376                         device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
02377                         TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
02378                         sdevice->internalSetDiskType(TDEDiskDeviceType::Camera);
02379                         TQString parentsyspathudev = systempath;
02380                         parentsyspathudev.truncate(parentsyspathudev.length()-1);   // Remove trailing slash
02381                         parentsyspathudev.truncate(parentsyspathudev.findRev("/"));
02382                         struct udev_device *parentdev;
02383                         parentdev = udev_device_new_from_syspath(m_udevStruct, parentsyspathudev.ascii());
02384                         devicenode = (udev_device_get_devnode(parentdev));
02385                         udev_device_unref(parentdev);
02386                     }
02387                 }
02388                 else if (usbInterfaceClass == 9) {
02389                     // Hub
02390                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Hub);
02391                 }
02392                 else if (usbInterfaceClass == 11) {
02393                     // Smart Card Reader
02394                     if (!device) device = new TDECryptographicCardDevice(TDEGenericDeviceType::CryptographicCard);
02395                 }
02396                 else if (usbInterfaceClass == 14) {
02397                     // Fingerprint Reader
02398                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BiometricSecurity);
02399                 }
02400                 else if (usbInterfaceClass == 254) {
02401                     // Test and/or Measurement Device
02402                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TestAndMeasurement);
02403                 }
02404                 else {
02405                     if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherUSB);
02406                 }
02407         }
02408         if (devicesubsystem == "pci") {
02409             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherPeripheral);
02410         }
02411         if (devicesubsystem == "cpu") {
02412             if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
02413         }
02414     }
02415 
02416     if (device == 0) {
02417         // Unhandled
02418         if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
02419         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);
02420     }
02421 
02422     // Root devices are special
02423     if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
02424         systempath = device->systemPath();
02425     }
02426 
02427     // Set preliminary basic device information
02428     device->internalSetName(devicename);
02429     device->internalSetDeviceNode(devicenode);
02430     device->internalSetSystemPath(systempath);
02431     device->internalSetVendorID(devicevendorid);
02432     device->internalSetModelID(devicemodelid);
02433     device->internalSetVendorEncoded(devicevendoridenc);
02434     device->internalSetModelEncoded(devicemodelidenc);
02435     device->internalSetSubVendorID(devicesubvendorid);
02436     device->internalSetSubModelID(devicesubmodelid);
02437     device->internalSetModuleAlias(devicemodalias);
02438     device->internalSetDeviceDriver(devicedriver);
02439     device->internalSetSubsystem(devicesubsystem);
02440     device->internalSetPCIClass(devicepciclass);
02441 
02442     updateBlacklists(device, dev);
02443 
02444     if (force_full_classification) {
02445         // Check external rules for possible device type overrides
02446         device = classifyUnknownDeviceByExternalRules(dev, device, false);
02447     }
02448 
02449     // Internal use only!
02450     device->m_udevtype = devicetype;
02451     device->m_udevdevicetypestring = devicetypestring;
02452     device->udevdevicetypestring_alt = devicetypestring_alt;
02453 
02454     updateExistingDeviceInformation(device, dev);
02455 
02456     if (temp_udev_device) {
02457         udev_device_unref(dev);
02458     }
02459 
02460     return device;
02461 }
02462 
02463 void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* existingdevice, udev_device* dev) {
02464     TQString devicename;
02465     TQString devicetype;
02466     TQString devicedriver;
02467     TQString devicesubsystem;
02468     TQString devicenode;
02469     TQString systempath;
02470     TQString devicevendorid;
02471     TQString devicemodelid;
02472     TQString devicevendoridenc;
02473     TQString devicemodelidenc;
02474     TQString devicesubvendorid;
02475     TQString devicesubmodelid;
02476     TQString devicetypestring;
02477     TQString devicetypestring_alt;
02478     TQString devicepciclass;
02479     TDEGenericDevice* device = existingdevice;
02480     bool temp_udev_device = !dev;
02481 
02482     devicename = device->name();
02483     devicetype = device->m_udevtype;
02484     devicedriver = device->deviceDriver();
02485     devicesubsystem = device->subsystem();
02486     devicenode = device->deviceNode();
02487     systempath = device->systemPath();
02488     devicevendorid = device->vendorID();
02489     devicemodelid = device->modelID();
02490     devicevendoridenc = device->vendorEncoded();
02491     devicemodelidenc = device->modelEncoded();
02492     devicesubvendorid = device->subVendorID();
02493     devicesubmodelid = device->subModelID();
02494     devicetypestring = device->m_udevdevicetypestring;
02495     devicetypestring_alt = device->udevdevicetypestring_alt;
02496     devicepciclass = device->PCIClass();
02497 
02498     if (!dev) {
02499         TQString syspathudev = systempath;
02500         syspathudev.truncate(syspathudev.length()-1);   // Remove trailing slash
02501         dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
02502     }
02503 
02504     if (device->type() == TDEGenericDeviceType::Disk) {
02505         TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
02506         if (sdevice->diskType() & TDEDiskDeviceType::Camera) {
02507             // PictBridge cameras are special and should not be classified by standard rules
02508             sdevice->internalSetDiskStatus(TDEDiskDeviceStatus::Removable);
02509             sdevice->internalSetFileSystemName("pictbridge");
02510         }
02511         else {
02512             bool removable = false;
02513             bool hotpluggable = false;
02514 
02515             // We can get the removable flag, but we have no idea if the device has the ability to notify on media insertion/removal
02516             // If there is no such notification possible, then we should not set the removable flag
02517             // udev can be such an amazing pain at times
02518             // It exports a /capabilities node with no info on what the bits actually mean
02519             // This information is very poorly documented as a set of #defines in include/linux/genhd.h
02520             // We are specifically interested in GENHD_FL_REMOVABLE and GENHD_FL_MEDIA_CHANGE_NOTIFY
02521             // The "removable" flag should also really be renamed to "hotpluggable", as that is far more precise...
02522             TQString capabilitynodename = systempath;
02523             capabilitynodename.append("/capability");
02524             TQFile capabilityfile( capabilitynodename );
02525             unsigned int capabilities = 0;
02526             if ( capabilityfile.open( IO_ReadOnly ) ) {
02527                 TQTextStream stream( &capabilityfile );
02528                 TQString capabilitystring;
02529                 capabilitystring = stream.readLine();
02530                 capabilities = capabilitystring.toUInt();
02531                 capabilityfile.close();
02532             }
02533             if (capabilities & GENHD_FL_REMOVABLE) {
02534                 // FIXME
02535                 // For added fun this is not always true; i.e. GENHD_FL_REMOVABLE can be set when the device cannot be hotplugged (floppy drives).
02536                 hotpluggable = true;
02537             }
02538             if (capabilities & GENHD_FL_MEDIA_CHANGE_NOTIFY) {
02539                 removable = true;
02540             }
02541 
02542             // See if any other devices are exclusively using this device, such as the Device Mapper
02543             TQStringList holdingDeviceNodes;
02544             TQString holdersnodename = udev_device_get_syspath(dev);
02545             holdersnodename.append("/holders/");
02546             TQDir holdersdir(holdersnodename);
02547             holdersdir.setFilter(TQDir::All);
02548             const TQFileInfoList *dirlist = holdersdir.entryInfoList();
02549             if (dirlist) {
02550                 TQFileInfoListIterator holdersdirit(*dirlist);
02551                 TQFileInfo *dirfi;
02552                 while ( (dirfi = holdersdirit.current()) != 0 ) {
02553                     if (dirfi->isSymLink()) {
02554                         char* collapsedPath = realpath((holdersnodename + dirfi->readLink()).ascii(), NULL);
02555                         holdingDeviceNodes.append(TQString(collapsedPath));
02556                         free(collapsedPath);
02557                     }
02558                     ++holdersdirit;
02559                 }
02560             }
02561 
02562             // See if any other physical devices underlie this device, for example when the Device Mapper is in use
02563             TQStringList slaveDeviceNodes;
02564             TQString slavesnodename = udev_device_get_syspath(dev);
02565             slavesnodename.append("/slaves/");
02566             TQDir slavedir(slavesnodename);
02567             slavedir.setFilter(TQDir::All);
02568             dirlist = slavedir.entryInfoList();
02569             if (dirlist) {
02570                 TQFileInfoListIterator slavedirit(*dirlist);
02571                 TQFileInfo *dirfi;
02572                 while ( (dirfi = slavedirit.current()) != 0 ) {
02573                     if (dirfi->isSymLink()) {
02574                         char* collapsedPath = realpath((slavesnodename + dirfi->readLink()).ascii(), NULL);
02575                         slaveDeviceNodes.append(TQString(collapsedPath));
02576                         free(collapsedPath);
02577                     }
02578                     ++slavedirit;
02579                 }
02580             }
02581 
02582             // Determine generic disk information
02583             TQString devicevendor(udev_device_get_property_value(dev, "ID_VENDOR"));
02584             TQString devicemodel(udev_device_get_property_value(dev, "ID_MODEL"));
02585             TQString devicebus(udev_device_get_property_value(dev, "ID_BUS"));
02586 
02587             // Get disk specific info
02588             TQString disklabel(decodeHexEncoding(TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))));
02589             if (disklabel == "") {
02590                 disklabel = TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL"));
02591             }
02592             TQString diskuuid(udev_device_get_property_value(dev, "ID_FS_UUID"));
02593             TQString filesystemtype(udev_device_get_property_value(dev, "ID_FS_TYPE"));
02594             TQString filesystemusage(udev_device_get_property_value(dev, "ID_FS_USAGE"));
02595 
02596             device->internalSetVendorName(devicevendor);
02597             device->internalSetVendorModel(devicemodel);
02598             device->internalSetDeviceBus(devicebus);
02599 
02600             TDEDiskDeviceType::TDEDiskDeviceType disktype = sdevice->diskType();
02601             TDEDiskDeviceStatus::TDEDiskDeviceStatus diskstatus = TDEDiskDeviceStatus::Null;
02602 
02603             TDEStorageDevice* parentdisk = NULL;
02604             if (!(TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER")).isEmpty())) {
02605                 TQString parentsyspath = systempath;
02606                 parentsyspath.truncate(parentsyspath.length()-1);   // Remove trailing slash
02607                 parentsyspath.truncate(parentsyspath.findRev("/"));
02608                 parentdisk = static_cast<TDEStorageDevice*>(findBySystemPath(parentsyspath));
02609             }
02610             disktype = classifyDiskType(dev, devicenode, devicebus, devicetypestring, systempath, devicevendor, devicemodel, filesystemtype, devicedriver);
02611             if (parentdisk) {
02612                 // Set partition disk type and status based on the parent device
02613                 disktype = disktype | parentdisk->diskType();
02614                 diskstatus = diskstatus | parentdisk->diskStatus();
02615             }
02616             sdevice->internalSetDiskType(disktype);
02617             device = classifyUnknownDeviceByExternalRules(dev, device, true);   // Check external rules for possible subtype overrides
02618             disktype = sdevice->diskType();                     // The type can be overridden by an external rule
02619 
02620             if (TQString(udev_device_get_property_value(dev, "UDISKS_IGNORE")) == "1") {
02621                 diskstatus = diskstatus | TDEDiskDeviceStatus::Hidden;
02622             }
02623 
02624             if ((disktype & TDEDiskDeviceType::CDROM)
02625                 || (disktype & TDEDiskDeviceType::CDR)
02626                 || (disktype & TDEDiskDeviceType::CDRW)
02627                 || (disktype & TDEDiskDeviceType::CDMO)
02628                 || (disktype & TDEDiskDeviceType::CDMRRW)
02629                 || (disktype & TDEDiskDeviceType::CDMRRWW)
02630                 || (disktype & TDEDiskDeviceType::DVDROM)
02631                 || (disktype & TDEDiskDeviceType::DVDRAM)
02632                 || (disktype & TDEDiskDeviceType::DVDR)
02633                 || (disktype & TDEDiskDeviceType::DVDRW)
02634                 || (disktype & TDEDiskDeviceType::DVDRDL)
02635                 || (disktype & TDEDiskDeviceType::DVDRWDL)
02636                 || (disktype & TDEDiskDeviceType::DVDPLUSR)
02637                 || (disktype & TDEDiskDeviceType::DVDPLUSRW)
02638                 || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
02639                 || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
02640                 || (disktype & TDEDiskDeviceType::BDROM)
02641                 || (disktype & TDEDiskDeviceType::BDR)
02642                 || (disktype & TDEDiskDeviceType::BDRW)
02643                 || (disktype & TDEDiskDeviceType::HDDVDROM)
02644                 || (disktype & TDEDiskDeviceType::HDDVDR)
02645                 || (disktype & TDEDiskDeviceType::HDDVDRW)
02646                 || (disktype & TDEDiskDeviceType::CDAudio)
02647                 || (disktype & TDEDiskDeviceType::CDVideo)
02648                 || (disktype & TDEDiskDeviceType::DVDVideo)
02649                 || (disktype & TDEDiskDeviceType::BDVideo)
02650                 ) {
02651                 // These drives are guaranteed to be optical
02652                 disktype = disktype | TDEDiskDeviceType::Optical;
02653             }
02654 
02655             if (disktype & TDEDiskDeviceType::Floppy) {
02656                 // Floppy drives don't work well under udev
02657                 // I have to look for the block device name manually
02658                 TQString floppyblknodename = systempath;
02659                 floppyblknodename.append("/block");
02660                 TQDir floppyblkdir(floppyblknodename);
02661                 floppyblkdir.setFilter(TQDir::All);
02662                 const TQFileInfoList *floppyblkdirlist = floppyblkdir.entryInfoList();
02663                 if (floppyblkdirlist) {
02664                     TQFileInfoListIterator floppyblkdirit(*floppyblkdirlist);
02665                     TQFileInfo *dirfi;
02666                     while ( (dirfi = floppyblkdirit.current()) != 0 ) {
02667                         if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
02668                             // Does this routine work with more than one floppy drive in the system?
02669                             devicenode = TQString("/dev/").append(dirfi->fileName());
02670                         }
02671                         ++floppyblkdirit;
02672                     }
02673                 }
02674 
02675                 // Some interesting information can be gleaned from the CMOS type file
02676                 // 0 : Defaults
02677                 // 1 : 5 1/4 DD
02678                 // 2 : 5 1/4 HD
02679                 // 3 : 3 1/2 DD
02680                 // 4 : 3 1/2 HD
02681                 // 5 : 3 1/2 ED
02682                 // 6 : 3 1/2 ED
02683                 // 16 : unknown or not installed
02684                 TQString floppycmsnodename = systempath;
02685                 floppycmsnodename.append("/cmos");
02686                 TQFile floppycmsfile( floppycmsnodename );
02687                 TQString cmosstring;
02688                 if ( floppycmsfile.open( IO_ReadOnly ) ) {
02689                     TQTextStream stream( &floppycmsfile );
02690                     cmosstring = stream.readLine();
02691                     floppycmsfile.close();
02692                 }
02693                 // FIXME
02694                 // Do something with the information in cmosstring
02695 
02696                 if (devicenode.isNull()) {
02697                     // This floppy drive cannot be mounted, so ignore it
02698                     disktype = disktype & ~TDEDiskDeviceType::Floppy;
02699                 }
02700             }
02701 
02702             if (devicetypestring.upper() == "CD") {
02703                 if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_STATE")).upper() == "BLANK") {
02704                     diskstatus = diskstatus | TDEDiskDeviceStatus::Blank;
02705                 }
02706                 sdevice->internalSetMediaInserted((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) != ""));
02707             }
02708 
02709             if (disktype & TDEDiskDeviceType::Zip) {
02710                 // A Zip drive does not advertise its status via udev, but it can be guessed from the size parameter
02711                 TQString zipnodename = systempath;
02712                 zipnodename.append("/size");
02713                 TQFile namefile( zipnodename );
02714                 TQString zipsize;
02715                 if ( namefile.open( IO_ReadOnly ) ) {
02716                     TQTextStream stream( &namefile );
02717                     zipsize = stream.readLine();
02718                     namefile.close();
02719                 }
02720                 if (!zipsize.isNull()) {
02721                     sdevice->internalSetMediaInserted((zipsize.toInt() != 0));
02722                 }
02723             }
02724 
02725             if (removable) {
02726                 diskstatus = diskstatus | TDEDiskDeviceStatus::Removable;
02727             }
02728             if (hotpluggable) {
02729                 diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
02730             }
02731             // Force removable flag for flash disks
02732             // udev reports disks as non-removable for card readers on PCI controllers
02733             if (((disktype & TDEDiskDeviceType::CompactFlash)
02734                  || (disktype & TDEDiskDeviceType::MemoryStick)
02735                  || (disktype & TDEDiskDeviceType::SmartMedia)
02736                  || (disktype & TDEDiskDeviceType::SDMMC))
02737                 && !(diskstatus & TDEDiskDeviceStatus::Removable)
02738                 && !(diskstatus & TDEDiskDeviceStatus::Hotpluggable)) {
02739                 diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
02740             }
02741 
02742             if ((filesystemtype.upper() != "CRYPTO_LUKS") && (filesystemtype.upper() != "CRYPTO") && (filesystemtype.upper() != "SWAP") && (!filesystemtype.isEmpty())) {
02743                 diskstatus = diskstatus | TDEDiskDeviceStatus::ContainsFilesystem;
02744             }
02745             else {
02746                 diskstatus = diskstatus & ~TDEDiskDeviceStatus::ContainsFilesystem;
02747             }
02748 
02749             // Set mountable flag if device is likely to be mountable
02750             diskstatus = diskstatus | TDEDiskDeviceStatus::Mountable;
02751             if ((devicetypestring.upper().isNull()) && (disktype & TDEDiskDeviceType::HDD)) {
02752                 diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
02753             }
02754             if (removable) {
02755                 if (sdevice->mediaInserted()) {
02756                     diskstatus = diskstatus | TDEDiskDeviceStatus::Inserted;
02757                 }
02758                 else {
02759                     diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
02760                 }
02761             }
02762             // Swap partitions cannot be mounted
02763             if (filesystemtype.upper() == "SWAP") {
02764                 diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
02765             }
02766             // Partition tables cannot be mounted
02767             if ((TQString(udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE")) != "")
02768                 && ((TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")).isEmpty())
02769                 || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0x5")
02770                 || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0xf")
02771                 || (TQString(udev_device_get_property_value(dev, "ID_FS_USAGE")).upper() == "RAID"))) {
02772                 diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
02773             }
02774             // If certain disk types do not report the presence of a filesystem, they are likely not mountable
02775             if ((disktype & TDEDiskDeviceType::HDD) || (disktype & TDEDiskDeviceType::Optical)) {
02776                 if (!(diskstatus & TDEDiskDeviceStatus::ContainsFilesystem)) {
02777                     diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
02778                 }
02779             }
02780 
02781             if (holdingDeviceNodes.count() > 0) {
02782                 diskstatus = diskstatus | TDEDiskDeviceStatus::UsedByDevice;
02783             }
02784 
02785             if (slaveDeviceNodes.count() > 0) {
02786                 diskstatus = diskstatus | TDEDiskDeviceStatus::UsesDevice;
02787             }
02788 
02789             // See if any slaves were crypted
02790             for ( TQStringList::Iterator slaveit = slaveDeviceNodes.begin(); slaveit != slaveDeviceNodes.end(); ++slaveit ) {
02791                 struct udev_device *slavedev;
02792                 slavedev = udev_device_new_from_syspath(m_udevStruct, (*slaveit).ascii());
02793                 TQString slavediskfstype(udev_device_get_property_value(slavedev, "ID_FS_TYPE"));
02794                 if ((slavediskfstype.upper() == "CRYPTO_LUKS") || (slavediskfstype.upper() == "CRYPTO")) {
02795                     disktype = disktype | TDEDiskDeviceType::UnlockedCrypt;
02796                     // Set disk type based on parent device
02797                     disktype = disktype | classifyDiskType(slavedev, devicenode, TQString(udev_device_get_property_value(dev, "ID_BUS")), TQString(udev_device_get_property_value(dev, "ID_TYPE")), (*slaveit), TQString(udev_device_get_property_value(dev, "ID_VENDOR")), TQString(udev_device_get_property_value(dev, "ID_MODEL")), TQString(udev_device_get_property_value(dev, "ID_FS_TYPE")), TQString(udev_device_get_driver(dev)));
02798                 }
02799                 udev_device_unref(slavedev);
02800             }
02801 
02802             sdevice->internalSetDiskType(disktype);
02803             sdevice->internalSetDiskUUID(diskuuid);
02804             sdevice->internalSetDiskStatus(diskstatus);
02805             sdevice->internalSetFileSystemName(filesystemtype);
02806             sdevice->internalSetFileSystemUsage(filesystemusage);
02807             sdevice->internalSetSlaveDevices(slaveDeviceNodes);
02808             sdevice->internalSetHoldingDevices(holdingDeviceNodes);
02809 
02810             // Clean up disk label
02811             if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
02812                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDR))
02813                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
02814                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMO))
02815                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRW))
02816                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRWW))
02817                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
02818                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
02819                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDR))
02820                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
02821                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRDL))
02822                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRWDL))
02823                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSR))
02824                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRW))
02825                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRDL))
02826                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRWDL))
02827                 || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
02828                 || (sdevice->isDiskOfType(TDEDiskDeviceType::BDR))
02829                 || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
02830                 || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDROM))
02831                 || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDR))
02832                 || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDRW))
02833                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
02834                 || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
02835                 || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
02836                 || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
02837                 ) {
02838                 if (disklabel == "" && sdevice->diskLabel().isNull()) {
02839                     // Read the volume label in via volname, since udev couldn't be bothered to do this on its own
02840                     FILE *exepipe = popen(((TQString("volname %1").arg(devicenode).ascii())), "r");
02841                     if (exepipe) {
02842                         char buffer[8092];
02843                         disklabel = fgets(buffer, sizeof(buffer), exepipe);
02844                         pclose(exepipe);
02845                     }
02846                 }
02847             }
02848 
02849             sdevice->internalSetDiskLabel(disklabel);
02850         }
02851     }
02852 
02853     if (device->type() == TDEGenericDeviceType::Network) {
02854         // Network devices don't have devices nodes per se, but we can at least return the Linux network name...
02855         TQString potentialdevicenode = systempath;
02856         if (potentialdevicenode.endsWith("/")) potentialdevicenode.truncate(potentialdevicenode.length()-1);
02857         potentialdevicenode.remove(0, potentialdevicenode.findRev("/")+1);
02858         TQString potentialparentnode = systempath;
02859         if (potentialparentnode.endsWith("/")) potentialparentnode.truncate(potentialparentnode.length()-1);
02860         potentialparentnode.remove(0, potentialparentnode.findRev("/", potentialparentnode.findRev("/")-1)+1);
02861         if (potentialparentnode.startsWith("net/")) {
02862             devicenode = potentialdevicenode;
02863         }
02864 
02865         if (devicenode.isNull()) {
02866             // Platform device, not a physical device
02867             // HACK
02868             // This only works because devices of type Platform only access the TDEGenericDevice class!
02869             device->m_deviceType = TDEGenericDeviceType::Platform;
02870         }
02871         else {
02872             // Gather network device information
02873             TDENetworkDevice* ndevice = dynamic_cast<TDENetworkDevice*>(device);
02874             TQString valuesnodename = systempath + "/";
02875             TQDir valuesdir(valuesnodename);
02876             valuesdir.setFilter(TQDir::All);
02877             TQString nodename;
02878             const TQFileInfoList *dirlist = valuesdir.entryInfoList();
02879             if (dirlist) {
02880                 TQFileInfoListIterator valuesdirit(*dirlist);
02881                 TQFileInfo *dirfi;
02882                 while ( (dirfi = valuesdirit.current()) != 0 ) {
02883                     nodename = dirfi->fileName();
02884                     TQFile file( valuesnodename + nodename );
02885                     if ( file.open( IO_ReadOnly ) ) {
02886                         TQTextStream stream( &file );
02887                         TQString line;
02888                         line = stream.readLine();
02889                         if (nodename == "address") {
02890                             ndevice->internalSetMacAddress(line);
02891                         }
02892                         else if (nodename == "carrier") {
02893                             ndevice->internalSetCarrierPresent(line.toInt());
02894                         }
02895                         else if (nodename == "dormant") {
02896                             ndevice->internalSetDormant(line.toInt());
02897                         }
02898                         else if (nodename == "operstate") {
02899                             TQString friendlyState = line.lower();
02900                             friendlyState[0] = friendlyState[0].upper();
02901                             ndevice->internalSetState(friendlyState);
02902                         }
02903                         file.close();
02904                     }
02905                     ++valuesdirit;
02906                 }
02907             }
02908             // Gather connection information such as IP addresses
02909             if ((ndevice->state().upper() == "UP")
02910                 || (ndevice->state().upper() == "UNKNOWN")) {
02911                 struct ifaddrs *ifaddr, *ifa;
02912                 int family, s;
02913                 char host[NI_MAXHOST];
02914 
02915                 if (getifaddrs(&ifaddr) != -1) {
02916                     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
02917                         if (ifa->ifa_addr == NULL) {
02918                             continue;
02919                         }
02920 
02921                         family = ifa->ifa_addr->sa_family;
02922 
02923                         if (TQString(ifa->ifa_name) == devicenode) {
02924                             if ((family == AF_INET) || (family == AF_INET6)) {
02925                                 s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
02926                                 if (s == 0) {
02927                                     TQString address(host);
02928                                     if (family == AF_INET) {
02929                                         ndevice->internalSetIpV4Address(address);
02930                                     }
02931                                     else if (family == AF_INET6) {
02932                                         address.truncate(address.findRev("%"));
02933                                         ndevice->internalSetIpV6Address(address);
02934                                     }
02935                                 }
02936                                 s = getnameinfo(ifa->ifa_netmask, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
02937                                 if (s == 0) {
02938                                     TQString address(host);
02939                                     if (family == AF_INET) {
02940                                         ndevice->internalSetIpV4Netmask(address);
02941                                     }
02942                                     else if (family == AF_INET6) {
02943                                         address.truncate(address.findRev("%"));
02944                                         ndevice->internalSetIpV6Netmask(address);
02945                                     }
02946                                 }
02947                                 s = getnameinfo(ifa->ifa_ifu.ifu_broadaddr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
02948                                 if (s == 0) {
02949                                     TQString address(host);
02950                                     if (family == AF_INET) {
02951                                         ndevice->internalSetIpV4Broadcast(address);
02952                                     }
02953                                     else if (family == AF_INET6) {
02954                                         address.truncate(address.findRev("%"));
02955                                         ndevice->internalSetIpV6Broadcast(address);
02956                                     }
02957                                 }
02958                                 s = getnameinfo(ifa->ifa_ifu.ifu_dstaddr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
02959                                 if (s == 0) {
02960                                     TQString address(host);
02961                                     if (family == AF_INET) {
02962                                         ndevice->internalSetIpV4Destination(address);
02963                                     }
02964                                     else if (family == AF_INET6) {
02965                                         address.truncate(address.findRev("%"));
02966                                         ndevice->internalSetIpV6Destination(address);
02967                                     }
02968                                 }
02969                             }
02970                         }
02971                     }
02972                 }
02973 
02974                 freeifaddrs(ifaddr);
02975 
02976                 // Gather statistics
02977                 TQString valuesnodename = systempath + "/statistics/";
02978                 TQDir valuesdir(valuesnodename);
02979                 valuesdir.setFilter(TQDir::All);
02980                 TQString nodename;
02981                 const TQFileInfoList *dirlist = valuesdir.entryInfoList();
02982                 if (dirlist) {
02983                     TQFileInfoListIterator valuesdirit(*dirlist);
02984                     TQFileInfo *dirfi;
02985                     while ( (dirfi = valuesdirit.current()) != 0 ) {
02986                         nodename = dirfi->fileName();
02987                         TQFile file( valuesnodename + nodename );
02988                         if ( file.open( IO_ReadOnly ) ) {
02989                             TQTextStream stream( &file );
02990                             TQString line;
02991                             line = stream.readLine();
02992                             if (nodename == "rx_bytes") {
02993                                 ndevice->internalSetRxBytes(line.toDouble());
02994                             }
02995                             else if (nodename == "tx_bytes") {
02996                                 ndevice->internalSetTxBytes(line.toDouble());
02997                             }
02998                             else if (nodename == "rx_packets") {
02999                                 ndevice->internalSetRxPackets(line.toDouble());
03000                             }
03001                             else if (nodename == "tx_packets") {
03002                                 ndevice->internalSetTxPackets(line.toDouble());
03003                             }
03004                             file.close();
03005                         }
03006                         ++valuesdirit;
03007                     }
03008                 }
03009             }
03010         }
03011     }
03012 
03013     if ((device->type() == TDEGenericDeviceType::OtherSensor) || (device->type() == TDEGenericDeviceType::ThermalSensor)) {
03014         // Populate all sensor values
03015         TDESensorClusterMap sensors;
03016         TQString valuesnodename = systempath + "/";
03017         TQDir valuesdir(valuesnodename);
03018         valuesdir.setFilter(TQDir::All);
03019         TQString nodename;
03020         const TQFileInfoList *dirlist = valuesdir.entryInfoList();
03021         if (dirlist) {
03022             TQFileInfoListIterator valuesdirit(*dirlist);
03023             TQFileInfo *dirfi;
03024             while ( (dirfi = valuesdirit.current()) != 0 ) {
03025                 nodename = dirfi->fileName();
03026                 if (nodename.contains("_")) {
03027                     TQFile file( valuesnodename + nodename );
03028                     if ( file.open( IO_ReadOnly ) ) {
03029                         TQTextStream stream( &file );
03030                         TQString line;
03031                         line = stream.readLine();
03032                         TQStringList sensornodelist = TQStringList::split("_", nodename);
03033                         TQString sensornodename = *(sensornodelist.at(0));
03034                         TQString sensornodetype = *(sensornodelist.at(1));
03035                         double lineValue = line.toDouble();
03036                         if (!sensornodename.contains("fan")) {
03037                             lineValue = lineValue / 1000.0;
03038                         }
03039                         if (sensornodetype == "label") {
03040                             sensors[sensornodename].label = line;
03041                         }
03042                         else if (sensornodetype == "input") {
03043                             sensors[sensornodename].current = lineValue;
03044                         }
03045                         else if (sensornodetype == "min") {
03046                             sensors[sensornodename].minimum = lineValue;
03047                         }
03048                         else if (sensornodetype == "max") {
03049                             sensors[sensornodename].maximum = lineValue;
03050                         }
03051                         else if (sensornodetype == "warn") {
03052                             sensors[sensornodename].warning = lineValue;
03053                         }
03054                         else if (sensornodetype == "crit") {
03055                             sensors[sensornodename].critical = lineValue;
03056                         }
03057                         file.close();
03058                     }
03059                 }
03060                 ++valuesdirit;
03061             }
03062         }
03063 
03064         TDESensorDevice* sdevice = dynamic_cast<TDESensorDevice*>(device);
03065         sdevice->internalSetValues(sensors);
03066     }
03067 
03068     if (device->type() == TDEGenericDeviceType::Battery) {
03069         // Populate all battery values
03070         TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(device);
03071         TQString valuesnodename = systempath + "/";
03072         TQDir valuesdir(valuesnodename);
03073         valuesdir.setFilter(TQDir::All);
03074         TQString nodename;
03075         double bdevice_capacity = 0;
03076         double bdevice_voltage = 0;
03077         int bdevice_time_to_empty = 0;
03078         int bdevice_time_to_full = 0;
03079         bool bdevice_has_energy = false;
03080         bool bdevice_has_time_to_empty = false;
03081         bool bdevice_has_time_to_full = false;
03082         const TQFileInfoList *dirlist = valuesdir.entryInfoList();
03083         if (dirlist) {
03084             TQFileInfoListIterator valuesdirit(*dirlist);
03085             TQFileInfo *dirfi;
03086             // Get the voltage as first...
03087             TQFile file( valuesnodename + "voltage_now" );
03088             if ( file.open( IO_ReadOnly ) ) {
03089                 TQTextStream stream( &file );
03090                 TQString line;
03091                 line = stream.readLine();
03092                 bdevice_voltage = line.toDouble()/1000000.0;
03093                 bdevice->internalSetVoltage(bdevice_voltage);
03094                 file.close();
03095             }
03096             // ...and then the other values
03097             while ( (dirfi = valuesdirit.current()) != 0 ) {
03098                 nodename = dirfi->fileName();
03099                 file.setName( valuesnodename + nodename );
03100                 if ( file.open( IO_ReadOnly ) ) {
03101                     TQTextStream stream( &file );
03102                     TQString line;
03103                     line = stream.readLine();
03104                     if (nodename == "alarm") {
03105                         bdevice->internalSetAlarmEnergy(line.toDouble()/1000000.0);
03106                     }
03107                     else if (nodename == "capacity") {
03108                         bdevice_capacity = line.toDouble();
03109                     }
03110                     else if (nodename == "charge_full") {
03111                         bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0);
03112                     }
03113                     else if (nodename == "energy_full") {
03114                         if (bdevice_voltage > 0) {
03115                             // Convert from mWh do Ah
03116                             bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0/bdevice_voltage);
03117                         }
03118                     }
03119                     else if (nodename == "charge_full_design") {
03120                         bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0);
03121                     }
03122                     else if (nodename == "energy_full_design") {
03123                         if (bdevice_voltage > 0) {
03124                             // Convert from mWh do Ah
03125                             bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0/bdevice_voltage);
03126                         }
03127                     }
03128                     else if (nodename == "charge_now") {
03129                         bdevice->internalSetEnergy(line.toDouble()/1000000.0);
03130                         bdevice_has_energy = true;
03131                     }
03132                     else if (nodename == "energy_now") {
03133                         if (bdevice_voltage > 0) {
03134                             // Convert from mWh do Ah
03135                             bdevice->internalSetEnergy(line.toDouble()/1000000.0/bdevice_voltage);
03136                             bdevice_has_energy = true;
03137                         }
03138                     }
03139                     else if (nodename == "manufacturer") {
03140                         bdevice->internalSetVendorName(line.stripWhiteSpace());
03141                     }
03142                     else if (nodename == "model_name") {
03143                         bdevice->internalSetVendorModel(line.stripWhiteSpace());
03144                     }
03145                     else if (nodename == "current_now") {
03146                         bdevice->internalSetDischargeRate(line.toDouble()/1000000.0);
03147                     }
03148                     else if (nodename == "power_now") {
03149                         if (bdevice_voltage > 0) {
03150                             // Convert from mW do A
03151                             bdevice->internalSetDischargeRate(line.toDouble()/1000000.0/bdevice_voltage);
03152                         }
03153                     }
03154                     else if (nodename == "present") {
03155                         bdevice->internalSetInstalled(line.toInt());
03156                     }
03157                     else if (nodename == "serial_number") {
03158                         bdevice->internalSetSerialNumber(line.stripWhiteSpace());
03159                     }
03160                     else if (nodename == "status") {
03161                         bdevice->internalSetStatus(line);
03162                     }
03163                     else if (nodename == "technology") {
03164                         bdevice->internalSetTechnology(line);
03165                     }
03166                     else if (nodename == "time_to_empty_now") {
03167                         // Convert from minutes to seconds
03168                         bdevice_time_to_empty = line.toDouble()*60;
03169                         bdevice_has_time_to_empty = true;
03170                     }
03171                     else if (nodename == "time_to_full_now") {
03172                         // Convert from minutes to seconds
03173                         bdevice_time_to_full = line.toDouble()*60;
03174                         bdevice_has_time_to_full = true;
03175                     }
03176                     else if (nodename == "voltage_min_design") {
03177                         bdevice->internalSetMinimumVoltage(line.toDouble()/1000000.0);
03178                     }
03179                     file.close();
03180                 }
03181                 ++valuesdirit;
03182             }
03183         }
03184 
03185         // Calculate current energy if missing
03186         if (!bdevice_has_energy) {
03187             bdevice->internalSetEnergy(bdevice_capacity*bdevice->maximumEnergy()/100);
03188         }
03189 
03190         // Calculate time remaining
03191         // Discharge/charge rate is in amper
03192         // Energy is in amper-hours
03193         // Therefore, energy/rate = time in hours
03194         // Convert to seconds...
03195         if (bdevice->status() == TDEBatteryStatus::Charging) {
03196             if (!bdevice_has_time_to_full && bdevice->dischargeRate() > 0) {
03197                 bdevice->internalSetTimeRemaining(((bdevice->maximumEnergy()-bdevice->energy())/bdevice->dischargeRate())*60*60);
03198             }
03199             else {
03200                 bdevice->internalSetTimeRemaining(bdevice_time_to_full);
03201             }
03202         }
03203         else {
03204             if (!bdevice_has_time_to_empty && bdevice->dischargeRate() > 0) {
03205                 bdevice->internalSetTimeRemaining((bdevice->energy()/bdevice->dischargeRate())*60*60);
03206             }
03207             else {
03208                 bdevice->internalSetTimeRemaining(bdevice_time_to_empty);
03209             }
03210         }
03211     }
03212 
03213     if (device->type() == TDEGenericDeviceType::PowerSupply) {
03214         // Populate all power supply values
03215         TDEMainsPowerDevice* pdevice = dynamic_cast<TDEMainsPowerDevice*>(device);
03216         TQString valuesnodename = systempath + "/";
03217         TQDir valuesdir(valuesnodename);
03218         valuesdir.setFilter(TQDir::All);
03219         TQString nodename;
03220         const TQFileInfoList *dirlist = valuesdir.entryInfoList();
03221         if (dirlist) {
03222             TQFileInfoListIterator valuesdirit(*dirlist);
03223             TQFileInfo *dirfi;
03224             while ( (dirfi = valuesdirit.current()) != 0 ) {
03225                 nodename = dirfi->fileName();
03226                 TQFile file( valuesnodename + nodename );
03227                 if ( file.open( IO_ReadOnly ) ) {
03228                     TQTextStream stream( &file );
03229                     TQString line;
03230                     line = stream.readLine();
03231                     if (nodename == "manufacturer") {
03232                         pdevice->internalSetVendorName(line.stripWhiteSpace());
03233                     }
03234                     else if (nodename == "model_name") {
03235                         pdevice->internalSetVendorModel(line.stripWhiteSpace());
03236                     }
03237                     else if (nodename == "online") {
03238                         pdevice->internalSetOnline(line.toInt());
03239                     }
03240                     else if (nodename == "serial_number") {
03241                         pdevice->internalSetSerialNumber(line.stripWhiteSpace());
03242                     }
03243                     file.close();
03244                 }
03245                 ++valuesdirit;
03246             }
03247         }
03248     }
03249 
03250     if (device->type() == TDEGenericDeviceType::Backlight) {
03251         // Populate all backlight values
03252         TDEBacklightDevice* bdevice = dynamic_cast<TDEBacklightDevice*>(device);
03253         TQString valuesnodename = systempath + "/";
03254         TQDir valuesdir(valuesnodename);
03255         valuesdir.setFilter(TQDir::All);
03256         TQString nodename;
03257         const TQFileInfoList *dirlist = valuesdir.entryInfoList();
03258         if (dirlist) {
03259             TQFileInfoListIterator valuesdirit(*dirlist);
03260             TQFileInfo *dirfi;
03261             while ( (dirfi = valuesdirit.current()) != 0 ) {
03262                 nodename = dirfi->fileName();
03263                 TQFile file( valuesnodename + nodename );
03264                 if ( file.open( IO_ReadOnly ) ) {
03265                     TQTextStream stream( &file );
03266                     TQString line;
03267                     line = stream.readLine();
03268                     if (nodename == "bl_power") {
03269                         TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
03270                         int rpl = line.toInt();
03271                         if (rpl == FB_BLANK_UNBLANK) {
03272                             pl = TDEDisplayPowerLevel::On;
03273                         }
03274                         else if (rpl == FB_BLANK_POWERDOWN) {
03275                             pl = TDEDisplayPowerLevel::Off;
03276                         }
03277                         bdevice->internalSetPowerLevel(pl);
03278                     }
03279                     else if (nodename == "max_brightness") {
03280                         bdevice->internalSetMaximumRawBrightness(line.toInt());
03281                     }
03282                     else if (nodename == "actual_brightness") {
03283                         bdevice->internalSetCurrentRawBrightness(line.toInt());
03284                     }
03285                     file.close();
03286                 }
03287                 ++valuesdirit;
03288             }
03289         }
03290     }
03291 
03292     if (device->type() == TDEGenericDeviceType::Monitor) {
03293         TDEMonitorDevice* mdevice = dynamic_cast<TDEMonitorDevice*>(device);
03294         TQString valuesnodename = systempath + "/";
03295         TQDir valuesdir(valuesnodename);
03296         valuesdir.setFilter(TQDir::All);
03297         TQString nodename;
03298         const TQFileInfoList *dirlist = valuesdir.entryInfoList();
03299         if (dirlist) {
03300             TQFileInfoListIterator valuesdirit(*dirlist);
03301             TQFileInfo *dirfi;
03302             while ( (dirfi = valuesdirit.current()) != 0 ) {
03303                 nodename = dirfi->fileName();
03304                 TQFile file( valuesnodename + nodename );
03305                 if ( file.open( IO_ReadOnly ) ) {
03306                     TQTextStream stream( &file );
03307                     TQString line;
03308                     line = stream.readLine();
03309                     if (nodename == "status") {
03310                         mdevice->internalSetConnected(line.lower() == "connected");
03311                     }
03312                     else if (nodename == "enabled") {
03313                         mdevice->internalSetEnabled(line.lower() == "enabled");
03314                     }
03315                     else if (nodename == "modes") {
03316                         TQStringList resinfo;
03317                         TQStringList resolutionsStringList = line.upper();
03318                         while ((!stream.atEnd()) && (!line.isNull())) {
03319                             line = stream.readLine();
03320                             if (!line.isNull()) {
03321                                 resolutionsStringList.append(line.upper());
03322                             }
03323                         }
03324                         TDEResolutionList resolutions;
03325                         resolutions.clear();
03326                         for (TQStringList::Iterator it = resolutionsStringList.begin(); it != resolutionsStringList.end(); ++it) {
03327                             resinfo = TQStringList::split('X', *it, true);
03328                             resolutions.append(TDEResolutionPair((*(resinfo.at(0))).toUInt(), (*(resinfo.at(1))).toUInt()));
03329                         }
03330                         mdevice->internalSetResolutions(resolutions);
03331                     }
03332                     else if (nodename == "dpms") {
03333                         TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
03334                         if (line == "On") {
03335                             pl = TDEDisplayPowerLevel::On;
03336                         }
03337                         else if (line == "Standby") {
03338                             pl = TDEDisplayPowerLevel::Standby;
03339                         }
03340                         else if (line == "Suspend") {
03341                             pl = TDEDisplayPowerLevel::Suspend;
03342                         }
03343                         else if (line == "Off") {
03344                             pl = TDEDisplayPowerLevel::Off;
03345                         }
03346                         mdevice->internalSetPowerLevel(pl);
03347                     }
03348                     file.close();
03349                 }
03350                 ++valuesdirit;
03351             }
03352         }
03353 
03354         TQString genericPortName = mdevice->systemPath();
03355         genericPortName.remove(0, genericPortName.find("-")+1);
03356         genericPortName.truncate(genericPortName.findRev("-"));
03357         mdevice->internalSetPortType(genericPortName);
03358 
03359         if (mdevice->connected()) {
03360             TQPair<TQString,TQString> monitor_info = getEDIDMonitorName(device->systemPath());
03361             if (!monitor_info.first.isNull()) {
03362                 mdevice->internalSetVendorName(monitor_info.first);
03363                 mdevice->internalSetVendorModel(monitor_info.second);
03364                 mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second;
03365             }
03366             else {
03367                 mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName);
03368             }
03369             mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
03370         }
03371         else {
03372             mdevice->m_friendlyName = i18n("Disconnected %1 Port").arg(genericPortName);
03373             mdevice->internalSetEdid(TQByteArray());
03374             mdevice->internalSetResolutions(TDEResolutionList());
03375         }
03376 
03377         // FIXME
03378         // Much of the code in libtderandr should be integrated into/interfaced with this library
03379     }
03380 
03381     if (device->type() == TDEGenericDeviceType::RootSystem) {
03382         // Try to obtain as much generic information about this system as possible
03383         TDERootSystemDevice* rdevice = dynamic_cast<TDERootSystemDevice*>(device);
03384 
03385         // Guess at my form factor
03386         // dmidecode would tell me this, but is somewhat unreliable
03387         TDESystemFormFactor::TDESystemFormFactor formfactor = TDESystemFormFactor::Desktop;
03388         if (listByDeviceClass(TDEGenericDeviceType::Backlight).count() > 0) {   // Is this really a good way to determine if a machine is a laptop?
03389             formfactor = TDESystemFormFactor::Laptop;
03390         }
03391         rdevice->internalSetFormFactor(formfactor);
03392 
03393         TQString valuesnodename = "/sys/power/";
03394         TQDir valuesdir(valuesnodename);
03395         valuesdir.setFilter(TQDir::All);
03396         TQString nodename;
03397         const TQFileInfoList *dirlist = valuesdir.entryInfoList();
03398         if (dirlist) {
03399             TQFileInfoListIterator valuesdirit(*dirlist);
03400             TQFileInfo *dirfi;
03401             TDESystemPowerStateList powerstates;
03402             TDESystemHibernationMethodList hibernationmethods;
03403             TDESystemHibernationMethod::TDESystemHibernationMethod hibernationmethod = 
03404                                                                                 TDESystemHibernationMethod::Unsupported;
03405             while ( (dirfi = valuesdirit.current()) != 0 ) {
03406                 nodename = dirfi->fileName();
03407                 TQFile file( valuesnodename + nodename );
03408                 if ( file.open( IO_ReadOnly ) ) {
03409                     TQTextStream stream( &file );
03410                     TQString line;
03411                     line = stream.readLine();
03412                     if (nodename == "state") {
03413                         // Always assume that these two fully on/fully off states are available
03414                         powerstates.append(TDESystemPowerState::Active);
03415                         powerstates.append(TDESystemPowerState::PowerOff);
03416                         if (line.contains("standby")) {
03417                             powerstates.append(TDESystemPowerState::Standby);
03418                         }
03419                         if (line.contains("freeze")) {
03420                             powerstates.append(TDESystemPowerState::Freeze);
03421                         }
03422                         if (line.contains("mem")) {
03423                             powerstates.append(TDESystemPowerState::Suspend);
03424                         }
03425                         if (line.contains("disk")) {
03426                             powerstates.append(TDESystemPowerState::Disk);
03427                         }
03428                     }
03429                     if (nodename == "disk") {
03430                         // Get list of available hibernation methods
03431                         if (line.contains("platform")) {
03432                             hibernationmethods.append(TDESystemHibernationMethod::Platform);
03433                         }
03434                         if (line.contains("shutdown")) {
03435                             hibernationmethods.append(TDESystemHibernationMethod::Shutdown);
03436                         }
03437                         if (line.contains("reboot")) {
03438                             hibernationmethods.append(TDESystemHibernationMethod::Reboot);
03439                         }
03440                         if (line.contains("suspend")) {
03441                             hibernationmethods.append(TDESystemHibernationMethod::Suspend);
03442                         }
03443                         if (line.contains("testproc")) {
03444                             hibernationmethods.append(TDESystemHibernationMethod::TestProc);
03445                         }
03446                         if (line.contains("test")) {
03447                             hibernationmethods.append(TDESystemHibernationMethod::Test);
03448                         }
03449 
03450                         // Get current hibernation method
03451                         line.truncate(line.findRev("]"));
03452                         line.remove(0, line.findRev("[")+1);
03453                         if (line.contains("platform")) {
03454                             hibernationmethod = TDESystemHibernationMethod::Platform;
03455                         }
03456                         if (line.contains("shutdown")) {
03457                             hibernationmethod = TDESystemHibernationMethod::Shutdown;
03458                         }
03459                         if (line.contains("reboot")) {
03460                             hibernationmethod = TDESystemHibernationMethod::Reboot;
03461                         }
03462                         if (line.contains("suspend")) {
03463                             hibernationmethod = TDESystemHibernationMethod::Suspend;
03464                         }
03465                         if (line.contains("testproc")) {
03466                             hibernationmethod = TDESystemHibernationMethod::TestProc;
03467                         }
03468                         if (line.contains("test")) {
03469                             hibernationmethod = TDESystemHibernationMethod::Test;
03470                         }
03471                     }
03472                     if (nodename == "image_size") {
03473                         rdevice->internalSetDiskSpaceNeededForHibernation(line.toULong());
03474                     }
03475                     file.close();
03476                 }
03477                 ++valuesdirit;
03478             }
03479             // Hibernation and Hybrid Suspend are not real power states, being just two different
03480             // ways of suspending to disk. Since they are very common and it is very convenient to
03481             // treat them as power states, we do so, as other power frameworks also do.
03482             if (powerstates.contains(TDESystemPowerState::Disk) && 
03483                 hibernationmethods.contains(TDESystemHibernationMethod::Platform)) {
03484                 powerstates.append(TDESystemPowerState::Hibernate);
03485             }
03486             if (powerstates.contains(TDESystemPowerState::Disk) && 
03487                 hibernationmethods.contains(TDESystemHibernationMethod::Suspend)) {
03488                 powerstates.append(TDESystemPowerState::HybridSuspend);
03489             }
03490             powerstates.remove(TDESystemPowerState::Disk);
03491             // Set power states and hibernation methods
03492             rdevice->internalSetPowerStates(powerstates);
03493             rdevice->internalSetHibernationMethods(hibernationmethods);
03494             rdevice->internalSetHibernationMethod(hibernationmethod);
03495         }
03496     }
03497 
03498     // NOTE
03499     // Keep these two handlers (Event and Input) in sync!
03500 
03501     if (device->type() == TDEGenericDeviceType::Event) {
03502         // Try to obtain as much type information about this event device as possible
03503         TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
03504         TDESwitchType::TDESwitchType edevice_switches = edevice->providedSwitches();
03505         if (edevice->systemPath().contains("PNP0C0D")
03506             || (edevice_switches & TDESwitchType::Lid)) {
03507             edevice->internalSetEventType(TDEEventDeviceType::ACPILidSwitch);
03508         }
03509         else if (edevice->systemPath().contains("PNP0C0E")
03510              || edevice->systemPath().contains("/LNXSLPBN")
03511              || (edevice_switches & TDESwitchType::SleepButton)) {
03512             edevice->internalSetEventType(TDEEventDeviceType::ACPISleepButton);
03513         }
03514         else if (edevice->systemPath().contains("PNP0C0C")
03515              || edevice->systemPath().contains("/LNXPWRBN")
03516              || (edevice_switches & TDESwitchType::PowerButton)) {
03517             edevice->internalSetEventType(TDEEventDeviceType::ACPIPowerButton);
03518         }
03519         else if (edevice->systemPath().contains("_acpi")) {
03520             edevice->internalSetEventType(TDEEventDeviceType::ACPIOtherInput);
03521         }
03522         else {
03523             edevice->internalSetEventType(TDEEventDeviceType::Unknown);
03524         }
03525     }
03526 
03527     if (device->type() == TDEGenericDeviceType::Input) {
03528         // Try to obtain as much type information about this input device as possible
03529         TDEInputDevice* idevice = dynamic_cast<TDEInputDevice*>(device);
03530         if (idevice->systemPath().contains("PNP0C0D")) {
03531             idevice->internalSetInputType(TDEInputDeviceType::ACPILidSwitch);
03532         }
03533         else if (idevice->systemPath().contains("PNP0C0E") || idevice->systemPath().contains("/LNXSLPBN")) {
03534             idevice->internalSetInputType(TDEInputDeviceType::ACPISleepButton);
03535         }
03536         else if (idevice->systemPath().contains("PNP0C0C") || idevice->systemPath().contains("/LNXPWRBN")) {
03537             idevice->internalSetInputType(TDEInputDeviceType::ACPIPowerButton);
03538         }
03539         else if (idevice->systemPath().contains("_acpi")) {
03540             idevice->internalSetInputType(TDEInputDeviceType::ACPIOtherInput);
03541         }
03542         else {
03543             idevice->internalSetInputType(TDEInputDeviceType::Unknown);
03544         }
03545     }
03546 
03547     if (device->type() == TDEGenericDeviceType::Event) {
03548         // Try to obtain as much specific information about this event device as possible
03549         TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
03550 
03551         // Try to open input event device
03552         if (edevice->m_fd < 0 && access (edevice->deviceNode().ascii(), R_OK) == 0) {
03553             edevice->m_fd = open(edevice->deviceNode().ascii(), O_RDONLY);
03554         }
03555 
03556         // Start monitoring of input event device
03557         edevice->internalStartMonitoring(this);
03558     }
03559 
03560     // Root devices are still special
03561     if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
03562         systempath = device->systemPath();
03563     }
03564 
03565     // Set basic device information again, as some information may have changed
03566     device->internalSetName(devicename);
03567     device->internalSetDeviceNode(devicenode);
03568     device->internalSetSystemPath(systempath);
03569     device->internalSetVendorID(devicevendorid);
03570     device->internalSetModelID(devicemodelid);
03571     device->internalSetVendorEncoded(devicevendoridenc);
03572     device->internalSetModelEncoded(devicemodelidenc);
03573     device->internalSetSubVendorID(devicesubvendorid);
03574     device->internalSetSubModelID(devicesubmodelid);
03575     device->internalSetDeviceDriver(devicedriver);
03576     device->internalSetSubsystem(devicesubsystem);
03577     device->internalSetPCIClass(devicepciclass);
03578 
03579     // Internal use only!
03580     device->m_udevtype = devicetype;
03581     device->m_udevdevicetypestring = devicetypestring;
03582     device->udevdevicetypestring_alt = devicetypestring_alt;
03583 
03584     if (temp_udev_device) {
03585         udev_device_unref(dev);
03586     }
03587 }
03588 
03589 void TDEHardwareDevices::updateBlacklists(TDEGenericDevice* hwdevice, udev_device* dev) {
03590     // HACK
03591     // I am lucky enough to have a Flash drive that spams udev continually with device change events
03592     // I imagine I am not the only one, so here is a section in which specific devices can be blacklisted!
03593 
03594     // For "U3 System" fake CD
03595     if ((hwdevice->vendorID() == "08ec") && (hwdevice->modelID() == "0020") && (TQString(udev_device_get_property_value(dev, "ID_TYPE")) == "cd")) {
03596         hwdevice->internalSetBlacklistedForUpdate(true);
03597     }
03598 }
03599 
03600 bool TDEHardwareDevices::queryHardwareInformation() {
03601     if (!m_udevStruct) {
03602         return false;
03603     }
03604 
03605     // Prepare the device list for repopulation
03606     m_deviceList.clear();
03607     addCoreSystemDevices();
03608 
03609     struct udev_enumerate *enumerate;
03610     struct udev_list_entry *devices, *dev_list_entry;
03611     struct udev_device *dev;
03612 
03613     // Create a list of all devices
03614     enumerate = udev_enumerate_new(m_udevStruct);
03615     udev_enumerate_add_match_subsystem(enumerate, NULL);
03616     udev_enumerate_scan_devices(enumerate);
03617     devices = udev_enumerate_get_list_entry(enumerate);
03618     // Get detailed information on each detected device
03619     udev_list_entry_foreach(dev_list_entry, devices) {
03620         const char *path;
03621 
03622         // Get the filename of the /sys entry for the device and create a udev_device object (dev) representing it
03623         path = udev_list_entry_get_name(dev_list_entry);
03624         dev = udev_device_new_from_syspath(m_udevStruct, path);
03625 
03626         TDEGenericDevice* device = classifyUnknownDevice(dev);
03627 
03628         // Make sure this device is not a duplicate
03629         TDEGenericDevice *hwdevice;
03630         for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
03631             if (hwdevice->systemPath() == device->systemPath()) {
03632                 delete device;
03633                 device = 0;
03634                 break;
03635             }
03636         }
03637 
03638         if (device) {
03639             m_deviceList.append(device);
03640         }
03641 
03642         udev_device_unref(dev);
03643     }
03644 
03645     // Free the enumerator object
03646     udev_enumerate_unref(enumerate);
03647 
03648     // Update parent/child tables for all devices
03649     updateParentDeviceInformation();
03650 
03651     emit hardwareEvent(TDEHardwareEvent::HardwareListModified, TQString());
03652 
03653     return true;
03654 }
03655 
03656 void TDEHardwareDevices::updateParentDeviceInformation(TDEGenericDevice* hwdevice) {
03657     // Scan for the first path up the sysfs tree that is available in the main hardware table
03658     bool done = false;
03659     TQString current_path = hwdevice->systemPath();
03660     TDEGenericDevice* parentdevice = 0;
03661 
03662     if (current_path.endsWith("/")) {
03663         current_path.truncate(current_path.findRev("/"));
03664     }
03665     while (done == false) {
03666         current_path.truncate(current_path.findRev("/"));
03667         if (current_path.startsWith("/sys/devices")) {
03668             if (current_path.endsWith("/")) {
03669                 current_path.truncate(current_path.findRev("/"));
03670             }
03671             parentdevice = findBySystemPath(current_path);
03672             if (parentdevice) {
03673                 done = true;
03674             }
03675         }
03676         else {
03677             // Abort!
03678             done = true;
03679         }
03680     }
03681 
03682     hwdevice->internalSetParentDevice(parentdevice);
03683 }
03684 
03685 void TDEHardwareDevices::updateParentDeviceInformation() {
03686     TDEGenericDevice *hwdevice;
03687 
03688     // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
03689     TDEGenericHardwareList devList = listAllPhysicalDevices();
03690     for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
03691         updateParentDeviceInformation(hwdevice);
03692     }
03693 }
03694 
03695 void TDEHardwareDevices::addCoreSystemDevices() {
03696     TDEGenericDevice *hwdevice;
03697 
03698     // Add the Main Root System Device, which provides all other devices
03699     hwdevice = new TDERootSystemDevice(TDEGenericDeviceType::RootSystem);
03700     hwdevice->internalSetSystemPath("/sys/devices");
03701     m_deviceList.append(hwdevice);
03702     rescanDeviceInformation(hwdevice);
03703 
03704     // Add core top-level devices in /sys/devices to the hardware listing
03705     TQStringList holdingDeviceNodes;
03706     TQString devicesnodename = "/sys/devices";
03707     TQDir devicesdir(devicesnodename);
03708     devicesdir.setFilter(TQDir::All);
03709     TQString nodename;
03710     const TQFileInfoList *dirlist = devicesdir.entryInfoList();
03711     if (dirlist) {
03712         TQFileInfoListIterator devicesdirit(*dirlist);
03713         TQFileInfo *dirfi;
03714         while ( (dirfi = devicesdirit.current()) != 0 ) {
03715             nodename = dirfi->fileName();
03716             if (nodename != "." && nodename != "..") {
03717                 hwdevice = new TDEGenericDevice(TDEGenericDeviceType::Root);
03718                 hwdevice->internalSetSystemPath(dirfi->absFilePath());
03719                 m_deviceList.append(hwdevice);
03720             }
03721             ++devicesdirit;
03722         }
03723     }
03724 
03725     // Handle CPUs, which are currently handled terribly by udev
03726     // Parse /proc/cpuinfo to extract some information about the CPUs
03727     hwdevice = 0;
03728     TQDir d("/sys/devices/system/cpu/");
03729     d.setFilter( TQDir::Dirs );
03730     const TQFileInfoList *list = d.entryInfoList();
03731     if (list) {
03732         TQFileInfoListIterator it( *list );
03733         TQFileInfo *fi;
03734         while ((fi = it.current()) != 0) {
03735             TQString directoryName = fi->fileName();
03736             if (directoryName.startsWith("cpu")) {
03737                 directoryName = directoryName.remove(0,3);
03738                 bool isInt;
03739                 int processorNumber = directoryName.toUInt(&isInt, 10);
03740                 if (isInt) {
03741                     hwdevice = new TDECPUDevice(TDEGenericDeviceType::CPU);
03742                     hwdevice->internalSetSystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
03743                     m_deviceList.append(hwdevice);
03744                 }
03745             }
03746             ++it;
03747         }
03748     }
03749 
03750     // Populate CPU information
03751     processModifiedCPUs();
03752 }
03753 
03754 TQString TDEHardwareDevices::findPCIDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
03755     TQString vendorName = TQString::null;
03756     TQString modelName = TQString::null;
03757     TQString friendlyName = TQString::null;
03758 
03759     if (!pci_id_map) {
03760         pci_id_map = new TDEDeviceIDMap;
03761 
03762         TQString database_filename = "/usr/share/pci.ids";
03763         if (!TQFile::exists(database_filename)) {
03764             database_filename = "/usr/share/misc/pci.ids";
03765         }
03766         if (!TQFile::exists(database_filename)) {
03767             printf("[tdehardwaredevices] Unable to locate PCI information database pci.ids\n"); fflush(stdout);
03768             return i18n("Unknown PCI Device");
03769         }
03770 
03771         TQFile database(database_filename);
03772         if (database.open(IO_ReadOnly)) {
03773             TQTextStream stream(&database);
03774             TQString line;
03775             TQString vendorID;
03776             TQString modelID;
03777             TQString subvendorID;
03778             TQString submodelID;
03779             TQString deviceMapKey;
03780             TQStringList devinfo;
03781             while (!stream.atEnd()) {
03782                 line = stream.readLine();
03783                 if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
03784                     line.replace("\t", "");
03785                     devinfo = TQStringList::split(' ', line, false);
03786                     vendorID = *(devinfo.at(0));
03787                     vendorName = line;
03788                     vendorName.remove(0, vendorName.find(" "));
03789                     vendorName = vendorName.stripWhiteSpace();
03790                     modelName = TQString::null;
03791                     deviceMapKey = vendorID.lower() + ":::";
03792                 }
03793                 else {
03794                     if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
03795                         line.replace("\t", "");
03796                         devinfo = TQStringList::split(' ', line, false);
03797                         modelID = *(devinfo.at(0));
03798                         modelName = line;
03799                         modelName.remove(0, modelName.find(" "));
03800                         modelName = modelName.stripWhiteSpace();
03801                         deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
03802                     }
03803                     else {
03804                         if (line.upper().startsWith("\t\t")) {
03805                             line.replace("\t", "");
03806                             devinfo = TQStringList::split(' ', line, false);
03807                             subvendorID = *(devinfo.at(0));
03808                             submodelID = *(devinfo.at(1));
03809                             modelName = line;
03810                             modelName.remove(0, modelName.find(" "));
03811                             modelName = modelName.stripWhiteSpace();
03812                             modelName.remove(0, modelName.find(" "));
03813                             modelName = modelName.stripWhiteSpace();
03814                             deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
03815                         }
03816                     }
03817                 }
03818                 if (modelName.isNull()) {
03819                     pci_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
03820                 }
03821                 else {
03822                     pci_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
03823                 }
03824             }
03825             database.close();
03826         }
03827         else {
03828             printf("[tdehardwaredevices] Unable to open PCI information database %s\n", database_filename.ascii()); fflush(stdout);
03829         }
03830     }
03831 
03832     if (pci_id_map) {
03833         TQString deviceName;
03834         TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
03835 
03836         deviceName = (*pci_id_map)[deviceMapKey];
03837         if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
03838             deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
03839             deviceName = (*pci_id_map)[deviceMapKey];
03840             if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
03841                 deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
03842                 deviceName = (*pci_id_map)[deviceMapKey];
03843             }
03844         }
03845 
03846         if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
03847             deviceName.replace("***UNKNOWN DEVICE*** ", "");
03848             deviceName.prepend(i18n("Unknown PCI Device") + " ");
03849             if (subvendorid.isNull()) {
03850                 deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
03851             }
03852             else {
03853                 deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
03854             }
03855         }
03856 
03857         return deviceName;
03858     }
03859     else {
03860         return i18n("Unknown PCI Device");
03861     }
03862 }
03863 
03864 TQString TDEHardwareDevices::findUSBDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
03865     TQString vendorName = TQString::null;
03866     TQString modelName = TQString::null;
03867     TQString friendlyName = TQString::null;
03868 
03869     if (!usb_id_map) {
03870         usb_id_map = new TDEDeviceIDMap;
03871 
03872         TQString database_filename = "/usr/share/usb.ids";
03873         if (!TQFile::exists(database_filename)) {
03874             database_filename = "/usr/share/misc/usb.ids";
03875         }
03876         if (!TQFile::exists(database_filename)) {
03877             printf("[tdehardwaredevices] Unable to locate USB information database usb.ids\n"); fflush(stdout);
03878             return i18n("Unknown USB Device");
03879         }
03880 
03881         TQFile database(database_filename);
03882         if (database.open(IO_ReadOnly)) {
03883             TQTextStream stream(&database);
03884             TQString line;
03885             TQString vendorID;
03886             TQString modelID;
03887             TQString subvendorID;
03888             TQString submodelID;
03889             TQString deviceMapKey;
03890             TQStringList devinfo;
03891             while (!stream.atEnd()) {
03892                 line = stream.readLine();
03893                 if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
03894                     line.replace("\t", "");
03895                     devinfo = TQStringList::split(' ', line, false);
03896                     vendorID = *(devinfo.at(0));
03897                     vendorName = line;
03898                     vendorName.remove(0, vendorName.find(" "));
03899                     vendorName = vendorName.stripWhiteSpace();
03900                     modelName = TQString::null;
03901                     deviceMapKey = vendorID.lower() + ":::";
03902                 }
03903                 else {
03904                     if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
03905                         line.replace("\t", "");
03906                         devinfo = TQStringList::split(' ', line, false);
03907                         modelID = *(devinfo.at(0));
03908                         modelName = line;
03909                         modelName.remove(0, modelName.find(" "));
03910                         modelName = modelName.stripWhiteSpace();
03911                         deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
03912                     }
03913                     else {
03914                         if (line.upper().startsWith("\t\t")) {
03915                             line.replace("\t", "");
03916                             devinfo = TQStringList::split(' ', line, false);
03917                             subvendorID = *(devinfo.at(0));
03918                             submodelID = *(devinfo.at(1));
03919                             modelName = line;
03920                             modelName.remove(0, modelName.find(" "));
03921                             modelName = modelName.stripWhiteSpace();
03922                             modelName.remove(0, modelName.find(" "));
03923                             modelName = modelName.stripWhiteSpace();
03924                             deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
03925                         }
03926                     }
03927                 }
03928                 if (modelName.isNull()) {
03929                     usb_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
03930                 }
03931                 else {
03932                     usb_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
03933                 }
03934             }
03935             database.close();
03936         }
03937         else {
03938             printf("[tdehardwaredevices] Unable to open USB information database %s\n", database_filename.ascii()); fflush(stdout);
03939         }
03940     }
03941 
03942     if (usb_id_map) {
03943         TQString deviceName;
03944         TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
03945 
03946         deviceName = (*usb_id_map)[deviceMapKey];
03947         if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
03948             deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
03949             deviceName = (*usb_id_map)[deviceMapKey];
03950             if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
03951                 deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
03952                 deviceName = (*usb_id_map)[deviceMapKey];
03953             }
03954         }
03955 
03956         if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
03957             deviceName.replace("***UNKNOWN DEVICE*** ", "");
03958             deviceName.prepend(i18n("Unknown USB Device") + " ");
03959             if (subvendorid.isNull()) {
03960                 deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
03961             }
03962             else {
03963                 deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
03964             }
03965         }
03966 
03967         return deviceName;
03968     }
03969     else {
03970         return i18n("Unknown USB Device");
03971     }
03972 }
03973 
03974 TQString TDEHardwareDevices::findPNPDeviceName(TQString pnpid) {
03975     TQString friendlyName = TQString::null;
03976 
03977     if (!pnp_id_map) {
03978         pnp_id_map = new TDEDeviceIDMap;
03979 
03980         TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
03981         TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
03982         TQString hardware_info_directory;
03983         TQString database_filename;
03984 
03985         for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
03986             hardware_info_directory = (*it);
03987             hardware_info_directory += hardware_info_directory_suffix;
03988 
03989             if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
03990                 database_filename = hardware_info_directory + "pnp.ids";
03991                 if (TQFile::exists(database_filename)) {
03992                     break;
03993                 }
03994             }
03995         }
03996 
03997         if (!TQFile::exists(database_filename)) {
03998             printf("[tdehardwaredevices] Unable to locate PNP information database pnp.ids\n"); fflush(stdout);
03999             return i18n("Unknown PNP Device");
04000         }
04001 
04002         TQFile database(database_filename);
04003         if (database.open(IO_ReadOnly)) {
04004             TQTextStream stream(&database);
04005             TQString line;
04006             TQString pnpID;
04007             TQString vendorName;
04008             TQString deviceMapKey;
04009             TQStringList devinfo;
04010             while (!stream.atEnd()) {
04011                 line = stream.readLine();
04012                 if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
04013                     devinfo = TQStringList::split('\t', line, false);
04014                     if (devinfo.count() > 1) {
04015                         pnpID = *(devinfo.at(0));
04016                         vendorName = *(devinfo.at(1));;
04017                         vendorName = vendorName.stripWhiteSpace();
04018                         deviceMapKey = pnpID.upper().stripWhiteSpace();
04019                         if (!deviceMapKey.isNull()) {
04020                             pnp_id_map->insert(deviceMapKey, vendorName, true);
04021                         }
04022                     }
04023                 }
04024             }
04025             database.close();
04026         }
04027         else {
04028             printf("[tdehardwaredevices] Unable to open PNP information database %s\n", database_filename.ascii()); fflush(stdout);
04029         }
04030     }
04031 
04032     if (pnp_id_map) {
04033         TQString deviceName;
04034 
04035         deviceName = (*pnp_id_map)[pnpid];
04036 
04037         return deviceName;
04038     }
04039     else {
04040         return i18n("Unknown PNP Device");
04041     }
04042 }
04043 
04044 TQString TDEHardwareDevices::findMonitorManufacturerName(TQString dpyid) {
04045     TQString friendlyName = TQString::null;
04046 
04047     if (!dpy_id_map) {
04048         dpy_id_map = new TDEDeviceIDMap;
04049 
04050         TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
04051         TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
04052         TQString hardware_info_directory;
04053         TQString database_filename;
04054 
04055         for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
04056             hardware_info_directory = (*it);
04057             hardware_info_directory += hardware_info_directory_suffix;
04058 
04059             if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
04060                 database_filename = hardware_info_directory + "dpy.ids";
04061                 if (TQFile::exists(database_filename)) {
04062                     break;
04063                 }
04064             }
04065         }
04066 
04067         if (!TQFile::exists(database_filename)) {
04068             printf("[tdehardwaredevices] Unable to locate monitor information database dpy.ids\n"); fflush(stdout);
04069             return i18n("Unknown Monitor Device");
04070         }
04071 
04072         TQFile database(database_filename);
04073         if (database.open(IO_ReadOnly)) {
04074             TQTextStream stream(&database);
04075             TQString line;
04076             TQString dpyID;
04077             TQString vendorName;
04078             TQString deviceMapKey;
04079             TQStringList devinfo;
04080             while (!stream.atEnd()) {
04081                 line = stream.readLine();
04082                 if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
04083                     devinfo = TQStringList::split('\t', line, false);
04084                     if (devinfo.count() > 1) {
04085                         dpyID = *(devinfo.at(0));
04086                         vendorName = *(devinfo.at(1));;
04087                         vendorName = vendorName.stripWhiteSpace();
04088                         deviceMapKey = dpyID.upper().stripWhiteSpace();
04089                         if (!deviceMapKey.isNull()) {
04090                             dpy_id_map->insert(deviceMapKey, vendorName, true);
04091                         }
04092                     }
04093                 }
04094             }
04095             database.close();
04096         }
04097         else {
04098             printf("[tdehardwaredevices] Unable to open monitor information database %s\n", database_filename.ascii()); fflush(stdout);
04099         }
04100     }
04101 
04102     if (dpy_id_map) {
04103         TQString deviceName;
04104 
04105         deviceName = (*dpy_id_map)[dpyid];
04106 
04107         return deviceName;
04108     }
04109     else {
04110         return i18n("Unknown Monitor Device");
04111     }
04112 }
04113 
04114 TQPair<TQString,TQString> TDEHardwareDevices::getEDIDMonitorName(TQString path) {
04115     TQPair<TQString,TQString> edid;
04116     TQByteArray binaryedid = getEDID(path);
04117     if (binaryedid.isNull()) {
04118         return TQPair<TQString,TQString>(TQString::null, TQString::null);
04119     }
04120 
04121     // Get the manufacturer ID
04122     unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
04123     unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
04124     unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
04125     TQChar qletter_1 = TQChar(letter_1);
04126     TQChar qletter_2 = TQChar(letter_2);
04127     TQChar qletter_3 = TQChar(letter_3);
04128     TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
04129 
04130     // Get the model ID
04131     unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
04132     // Reverse the bit order
04133     unsigned int model_id = reverse_bits(raw_model_id);
04134 
04135     // Try to get the model name
04136     bool has_friendly_name = false;
04137     unsigned char descriptor_block[18];
04138     int i;
04139     for (i=72;i<90;i++) {
04140         descriptor_block[i-72] = binaryedid[i] & 0xFF;
04141     }
04142     if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
04143         for (i=90;i<108;i++) {
04144             descriptor_block[i-90] = binaryedid[i] & 0xFF;
04145         }
04146         if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
04147             for (i=108;i<126;i++) {
04148                 descriptor_block[i-108] = binaryedid[i] & 0xFF;
04149             }
04150         }
04151     }
04152 
04153     TQString monitor_name;
04154     if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
04155         char* pos = strchr((char *)(descriptor_block+5), '\n');
04156         if (pos) {
04157             *pos = 0;
04158             has_friendly_name = true;
04159             monitor_name = TQString((char *)(descriptor_block+5));
04160         }
04161         else {
04162             has_friendly_name = false;
04163         }
04164     }
04165 
04166     // Look up manufacturer name
04167     TQString manufacturer_name = findMonitorManufacturerName(manufacturer_id);
04168     if (manufacturer_name.isNull()) {
04169         manufacturer_name = manufacturer_id;
04170     }
04171 
04172     if (has_friendly_name) {
04173         edid.first = TQString("%1").arg(manufacturer_name);
04174         edid.second = TQString("%2").arg(monitor_name);
04175     }
04176     else {
04177         edid.first = TQString("%1").arg(manufacturer_name);
04178         edid.second = TQString("0x%2").arg(model_id, 0, 16);
04179     }
04180 
04181     return edid;
04182 }
04183 
04184 TQByteArray TDEHardwareDevices::getEDID(TQString path) {
04185     TQFile file(TQString("%1/edid").arg(path));
04186     if (!file.open (IO_ReadOnly)) {
04187         return TQByteArray();
04188     }
04189     TQByteArray binaryedid = file.readAll();
04190     file.close();
04191     return binaryedid;
04192 }
04193 
04194 TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDeviceType::TDEGenericDeviceType query) {
04195     TQString ret = "Unknown Device";
04196 
04197     // Keep this in sync with the TDEGenericDeviceType definition in the header
04198     if (query == TDEGenericDeviceType::Root) {
04199         ret = i18n("Root");
04200     }
04201     else if (query == TDEGenericDeviceType::RootSystem) {
04202         ret = i18n("System Root");
04203     }
04204     else if (query == TDEGenericDeviceType::CPU) {
04205         ret = i18n("CPU");
04206     }
04207     else if (query == TDEGenericDeviceType::GPU) {
04208         ret = i18n("Graphics Processor");
04209     }
04210     else if (query == TDEGenericDeviceType::RAM) {
04211         ret = i18n("RAM");
04212     }
04213     else if (query == TDEGenericDeviceType::Bus) {
04214         ret = i18n("Bus");
04215     }
04216     else if (query == TDEGenericDeviceType::I2C) {
04217         ret = i18n("I2C Bus");
04218     }
04219     else if (query == TDEGenericDeviceType::MDIO) {
04220         ret = i18n("MDIO Bus");
04221     }
04222     else if (query == TDEGenericDeviceType::Mainboard) {
04223         ret = i18n("Mainboard");
04224     }
04225     else if (query == TDEGenericDeviceType::Disk) {
04226         ret = i18n("Disk");
04227     }
04228     else if (query == TDEGenericDeviceType::SCSI) {
04229         ret = i18n("SCSI");
04230     }
04231     else if (query == TDEGenericDeviceType::StorageController) {
04232         ret = i18n("Storage Controller");
04233     }
04234     else if (query == TDEGenericDeviceType::Mouse) {
04235         ret = i18n("Mouse");
04236     }
04237     else if (query == TDEGenericDeviceType::Keyboard) {
04238         ret = i18n("Keyboard");
04239     }
04240     else if (query == TDEGenericDeviceType::HID) {
04241         ret = i18n("HID");
04242     }
04243     else if (query == TDEGenericDeviceType::Modem) {
04244         ret = i18n("Modem");
04245     }
04246     else if (query == TDEGenericDeviceType::Monitor) {
04247         ret = i18n("Monitor and Display");
04248     }
04249     else if (query == TDEGenericDeviceType::Network) {
04250         ret = i18n("Network");
04251     }
04252     else if (query == TDEGenericDeviceType::NonvolatileMemory) {
04253         ret = i18n("Nonvolatile Memory");
04254     }
04255     else if (query == TDEGenericDeviceType::Printer) {
04256         ret = i18n("Printer");
04257     }
04258     else if (query == TDEGenericDeviceType::Scanner) {
04259         ret = i18n("Scanner");
04260     }
04261     else if (query == TDEGenericDeviceType::Sound) {
04262         ret = i18n("Sound");
04263     }
04264     else if (query == TDEGenericDeviceType::VideoCapture) {
04265         ret = i18n("Video Capture");
04266     }
04267     else if (query == TDEGenericDeviceType::IEEE1394) {
04268         ret = i18n("IEEE1394");
04269     }
04270     else if (query == TDEGenericDeviceType::PCMCIA) {
04271         ret = i18n("PCMCIA");
04272     }
04273     else if (query == TDEGenericDeviceType::Camera) {
04274         ret = i18n("Camera");
04275     }
04276     else if (query == TDEGenericDeviceType::TextIO) {
04277         ret = i18n("Text I/O");
04278     }
04279     else if (query == TDEGenericDeviceType::Serial) {
04280         ret = i18n("Serial Communications Controller");
04281     }
04282     else if (query == TDEGenericDeviceType::Parallel) {
04283         ret = i18n("Parallel Port");
04284     }
04285     else if (query == TDEGenericDeviceType::Peripheral) {
04286         ret = i18n("Peripheral");
04287     }
04288     else if (query == TDEGenericDeviceType::Backlight) {
04289         ret = i18n("Backlight");
04290     }
04291     else if (query == TDEGenericDeviceType::Battery) {
04292         ret = i18n("Battery");
04293     }
04294     else if (query == TDEGenericDeviceType::PowerSupply) {
04295         ret = i18n("Power Supply");
04296     }
04297     else if (query == TDEGenericDeviceType::Dock) {
04298         ret = i18n("Docking Station");
04299     }
04300     else if (query == TDEGenericDeviceType::ThermalSensor) {
04301         ret = i18n("Thermal Sensor");
04302     }
04303     else if (query == TDEGenericDeviceType::ThermalControl) {
04304         ret = i18n("Thermal Control");
04305     }
04306     else if (query == TDEGenericDeviceType::BlueTooth) {
04307         ret = i18n("Bluetooth");
04308     }
04309     else if (query == TDEGenericDeviceType::Bridge) {
04310         ret = i18n("Bridge");
04311     }
04312     else if (query == TDEGenericDeviceType::Hub) {
04313         ret = i18n("Hub");
04314     }
04315     else if (query == TDEGenericDeviceType::Platform) {
04316         ret = i18n("Platform");
04317     }
04318     else if (query == TDEGenericDeviceType::Cryptography) {
04319         ret = i18n("Cryptography");
04320     }
04321     else if (query == TDEGenericDeviceType::CryptographicCard) {
04322         ret = i18n("Cryptographic Card");
04323     }
04324     else if (query == TDEGenericDeviceType::BiometricSecurity) {
04325         ret = i18n("Biometric Security");
04326     }
04327     else if (query == TDEGenericDeviceType::TestAndMeasurement) {
04328         ret = i18n("Test and Measurement");
04329     }
04330     else if (query == TDEGenericDeviceType::Timekeeping) {
04331         ret = i18n("Timekeeping");
04332     }
04333     else if (query == TDEGenericDeviceType::Event) {
04334         ret = i18n("Platform Event");
04335     }
04336     else if (query == TDEGenericDeviceType::Input) {
04337         ret = i18n("Platform Input");
04338     }
04339     else if (query == TDEGenericDeviceType::PNP) {
04340         ret = i18n("Plug and Play");
04341     }
04342     else if (query == TDEGenericDeviceType::OtherACPI) {
04343         ret = i18n("Other ACPI");
04344     }
04345     else if (query == TDEGenericDeviceType::OtherUSB) {
04346         ret = i18n("Other USB");
04347     }
04348     else if (query == TDEGenericDeviceType::OtherMultimedia) {
04349         ret = i18n("Other Multimedia");
04350     }
04351     else if (query == TDEGenericDeviceType::OtherPeripheral) {
04352         ret = i18n("Other Peripheral");
04353     }
04354     else if (query == TDEGenericDeviceType::OtherSensor) {
04355         ret = i18n("Other Sensor");
04356     }
04357     else if (query == TDEGenericDeviceType::OtherVirtual) {
04358         ret = i18n("Other Virtual");
04359     }
04360     else {
04361         ret = i18n("Unknown Device");
04362     }
04363 
04364     return ret;
04365 }
04366 
04367 TQPixmap TDEHardwareDevices::getDeviceTypeIconFromType(TDEGenericDeviceType::TDEGenericDeviceType query, TDEIcon::StdSizes size) {
04368     TQPixmap ret = DesktopIcon("misc", size);
04369 
04370 //  // Keep this in sync with the TDEGenericDeviceType definition in the header
04371     if (query == TDEGenericDeviceType::Root) {
04372         ret = DesktopIcon("kcmdevices", size);
04373     }
04374     else if (query == TDEGenericDeviceType::RootSystem) {
04375         ret = DesktopIcon("kcmdevices", size);
04376     }
04377     else if (query == TDEGenericDeviceType::CPU) {
04378         ret = DesktopIcon("kcmprocessor", size);
04379     }
04380     else if (query == TDEGenericDeviceType::GPU) {
04381         ret = DesktopIcon("kcmpci", size);
04382     }
04383     else if (query == TDEGenericDeviceType::RAM) {
04384         ret = DesktopIcon("memory", size);
04385     }
04386     else if (query == TDEGenericDeviceType::Bus) {
04387         ret = DesktopIcon("kcmpci", size);
04388     }
04389     else if (query == TDEGenericDeviceType::I2C) {
04390         ret = DesktopIcon("preferences-desktop-peripherals", size);
04391     }
04392     else if (query == TDEGenericDeviceType::MDIO) {
04393         ret = DesktopIcon("preferences-desktop-peripherals", size);
04394     }
04395     else if (query == TDEGenericDeviceType::Mainboard) {
04396         ret = DesktopIcon("kcmpci", size);  // FIXME
04397     }
04398     else if (query == TDEGenericDeviceType::Disk) {
04399         ret = DesktopIcon("drive-harddisk-unmounted", size);
04400     }
04401     else if (query == TDEGenericDeviceType::SCSI) {
04402         ret = DesktopIcon("kcmscsi", size);
04403     }
04404     else if (query == TDEGenericDeviceType::StorageController) {
04405         ret = DesktopIcon("kcmpci", size);
04406     }
04407     else if (query == TDEGenericDeviceType::Mouse) {
04408         ret = DesktopIcon("input-mouse", size);
04409     }
04410     else if (query == TDEGenericDeviceType::Keyboard) {
04411         ret = DesktopIcon("input-keyboard", size);
04412     }
04413     else if (query == TDEGenericDeviceType::HID) {
04414         ret = DesktopIcon("kcmdevices", size);  // FIXME
04415     }
04416     else if (query == TDEGenericDeviceType::Modem) {
04417         ret = DesktopIcon("kcmpci", size);
04418     }
04419     else if (query == TDEGenericDeviceType::Monitor) {
04420         ret = DesktopIcon("background", size);
04421     }
04422     else if (query == TDEGenericDeviceType::Network) {
04423         ret = DesktopIcon("kcmpci", size);
04424     }
04425     else if (query == TDEGenericDeviceType::NonvolatileMemory) {
04426         ret = DesktopIcon("memory", size);
04427     }
04428     else if (query == TDEGenericDeviceType::Printer) {
04429         ret = DesktopIcon("printer", size);
04430     }
04431     else if (query == TDEGenericDeviceType::Scanner) {
04432         ret = DesktopIcon("scanner", size);
04433     }
04434     else if (query == TDEGenericDeviceType::Sound) {
04435         ret = DesktopIcon("kcmsound", size);
04436     }
04437     else if (query == TDEGenericDeviceType::VideoCapture) {
04438         ret = DesktopIcon("tv", size);      // FIXME
04439     }
04440     else if (query == TDEGenericDeviceType::IEEE1394) {
04441         ret = DesktopIcon("ieee1394", size);
04442     }
04443     else if (query == TDEGenericDeviceType::PCMCIA) {
04444         ret = DesktopIcon("kcmdevices", size);  // FIXME
04445     }
04446     else if (query == TDEGenericDeviceType::Camera) {
04447         ret = DesktopIcon("camera-photo", size);
04448     }
04449     else if (query == TDEGenericDeviceType::Serial) {
04450         ret = DesktopIcon("preferences-desktop-peripherals", size);
04451     }
04452     else if (query == TDEGenericDeviceType::Parallel) {
04453         ret = DesktopIcon("preferences-desktop-peripherals", size);
04454     }
04455     else if (query == TDEGenericDeviceType::TextIO) {
04456         ret = DesktopIcon("chardevice", size);
04457     }
04458     else if (query == TDEGenericDeviceType::Peripheral) {
04459         ret = DesktopIcon("kcmpci", size);
04460     }
04461     else if (query == TDEGenericDeviceType::Backlight) {
04462         ret = DesktopIcon("tdescreensaver", size);  // FIXME
04463     }
04464     else if (query == TDEGenericDeviceType::Battery) {
04465         ret = DesktopIcon("energy", size);
04466     }
04467     else if (query == TDEGenericDeviceType::PowerSupply) {
04468         ret = DesktopIcon("energy", size);
04469     }
04470     else if (query == TDEGenericDeviceType::Dock) {
04471         ret = DesktopIcon("kcmdevices", size);  // FIXME
04472     }
04473     else if (query == TDEGenericDeviceType::ThermalSensor) {
04474         ret = DesktopIcon("kcmdevices", size);  // FIXME
04475     }
04476     else if (query == TDEGenericDeviceType::ThermalControl) {
04477         ret = DesktopIcon("kcmdevices", size);  // FIXME
04478     }
04479     else if (query == TDEGenericDeviceType::BlueTooth) {
04480         ret = DesktopIcon("kcmpci", size);  // FIXME
04481     }
04482     else if (query == TDEGenericDeviceType::Bridge) {
04483         ret = DesktopIcon("kcmpci", size);
04484     }
04485     else if (query == TDEGenericDeviceType::Hub) {
04486         ret = DesktopIcon("usb", size);
04487     }
04488     else if (query == TDEGenericDeviceType::Platform) {
04489         ret = DesktopIcon("preferences-system", size);
04490     }
04491     else if (query == TDEGenericDeviceType::Cryptography) {
04492         ret = DesktopIcon("password", size);
04493     }
04494     else if (query == TDEGenericDeviceType::CryptographicCard) {
04495         ret = DesktopIcon("password", size);
04496     }
04497     else if (query == TDEGenericDeviceType::BiometricSecurity) {
04498         ret = DesktopIcon("password", size);
04499     }
04500     else if (query == TDEGenericDeviceType::TestAndMeasurement) {
04501         ret = DesktopIcon("kcmdevices", size);
04502     }
04503     else if (query == TDEGenericDeviceType::Timekeeping) {
04504         ret = DesktopIcon("history", size);
04505     }
04506     else if (query == TDEGenericDeviceType::Event) {
04507         ret = DesktopIcon("preferences-system", size);
04508     }
04509     else if (query == TDEGenericDeviceType::Input) {
04510         ret = DesktopIcon("preferences-system", size);
04511     }
04512     else if (query == TDEGenericDeviceType::PNP) {
04513         ret = DesktopIcon("preferences-system", size);
04514     }
04515     else if (query == TDEGenericDeviceType::OtherACPI) {
04516         ret = DesktopIcon("kcmdevices", size);  // FIXME
04517     }
04518     else if (query == TDEGenericDeviceType::OtherUSB) {
04519         ret = DesktopIcon("usb", size);
04520     }
04521     else if (query == TDEGenericDeviceType::OtherMultimedia) {
04522         ret = DesktopIcon("kcmsound", size);
04523     }
04524     else if (query == TDEGenericDeviceType::OtherPeripheral) {
04525         ret = DesktopIcon("kcmpci", size);
04526     }
04527     else if (query == TDEGenericDeviceType::OtherSensor) {
04528         ret = DesktopIcon("kcmdevices", size);  // FIXME
04529     }
04530     else if (query == TDEGenericDeviceType::OtherVirtual) {
04531         ret = DesktopIcon("preferences-system", size);
04532     }
04533     else {
04534         ret = DesktopIcon("hwinfo", size);
04535     }
04536 
04537     return ret;
04538 }
04539 
04540 TDERootSystemDevice* TDEHardwareDevices::rootSystemDevice() {
04541     TDEGenericDevice *hwdevice;
04542     for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
04543         if (hwdevice->type() == TDEGenericDeviceType::RootSystem) {
04544             return dynamic_cast<TDERootSystemDevice*>(hwdevice);
04545         }
04546     }
04547 
04548     return 0;
04549 }
04550 
04551 TQString TDEHardwareDevices::bytesToFriendlySizeString(double bytes) {
04552     TQString prettystring;
04553 
04554     prettystring = TQString("%1B").arg(bytes);
04555 
04556     if (bytes > 1024) {
04557         bytes = bytes / 1024;
04558         prettystring = TQString("%1KB").arg(bytes, 0, 'f', 1);
04559     }
04560 
04561     if (bytes > 1024) {
04562         bytes = bytes / 1024;
04563         prettystring = TQString("%1MB").arg(bytes, 0, 'f', 1);
04564     }
04565 
04566     if (bytes > 1024) {
04567         bytes = bytes / 1024;
04568         prettystring = TQString("%1GB").arg(bytes, 0, 'f', 1);
04569     }
04570 
04571     if (bytes > 1024) {
04572         bytes = bytes / 1024;
04573         prettystring = TQString("%1TB").arg(bytes, 0, 'f', 1);
04574     }
04575 
04576     if (bytes > 1024) {
04577         bytes = bytes / 1024;
04578         prettystring = TQString("%1PB").arg(bytes, 0, 'f', 1);
04579     }
04580 
04581     if (bytes > 1024) {
04582         bytes = bytes / 1024;
04583         prettystring = TQString("%1EB").arg(bytes, 0, 'f', 1);
04584     }
04585 
04586     if (bytes > 1024) {
04587         bytes = bytes / 1024;
04588         prettystring = TQString("%1ZB").arg(bytes, 0, 'f', 1);
04589     }
04590 
04591     if (bytes > 1024) {
04592         bytes = bytes / 1024;
04593         prettystring = TQString("%1YB").arg(bytes, 0, 'f', 1);
04594     }
04595 
04596     return prettystring;
04597 }
04598 
04599 TDEGenericHardwareList TDEHardwareDevices::listByDeviceClass(TDEGenericDeviceType::TDEGenericDeviceType cl) {
04600     TDEGenericHardwareList ret;
04601     ret.setAutoDelete(false);
04602 
04603     TDEGenericDevice *hwdevice;
04604     for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
04605         if (hwdevice->type() == cl) {
04606             ret.append(hwdevice);
04607         }
04608     }
04609 
04610     return ret;
04611 }
04612 
04613 TDEGenericHardwareList TDEHardwareDevices::listAllPhysicalDevices() {
04614     TDEGenericHardwareList ret = m_deviceList;
04615     ret.setAutoDelete(false);
04616 
04617     return ret;
04618 }
04619 
04620 #include "tdehardwaredevices.moc"

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