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