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