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

tdecore

tdehardwaredevices.cpp

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