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