TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4567 lines
158 KiB

  1. /* This file is part of the TDE libraries
  2. Copyright (C) 2012-2014 Timothy Pearson <kb9vqf@pearsoncomputing.net>
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License version 2 as published by the Free Software Foundation.
  6. This library is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  9. Library General Public License for more details.
  10. You should have received a copy of the GNU Library General Public License
  11. along with this library; see the file COPYING.LIB. If not, write to
  12. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  13. Boston, MA 02110-1301, USA.
  14. */
  15. #include "tdehardwaredevices.h"
  16. #include <tqfile.h>
  17. #include <tqdir.h>
  18. #include <tqtimer.h>
  19. #include <tqsocketnotifier.h>
  20. #include <tqstringlist.h>
  21. #include <tdeconfig.h>
  22. #include <kstandarddirs.h>
  23. #include <tdeglobal.h>
  24. #include <tdelocale.h>
  25. #include <tdeapplication.h>
  26. #include <dcopclient.h>
  27. extern "C" {
  28. #include <libudev.h>
  29. }
  30. #include <stdlib.h>
  31. #include <unistd.h>
  32. #include <fcntl.h>
  33. // Network devices
  34. #include <sys/types.h>
  35. #include <ifaddrs.h>
  36. #include <netdb.h>
  37. // Backlight devices
  38. #include <linux/fb.h>
  39. // Input devices
  40. #include <linux/input.h>
  41. #include "kiconloader.h"
  42. #include "tdegenericdevice.h"
  43. #include "tdestoragedevice.h"
  44. #include "tdecpudevice.h"
  45. #include "tdebatterydevice.h"
  46. #include "tdemainspowerdevice.h"
  47. #include "tdenetworkdevice.h"
  48. #include "tdebacklightdevice.h"
  49. #include "tdemonitordevice.h"
  50. #include "tdesensordevice.h"
  51. #include "tderootsystemdevice.h"
  52. #include "tdeeventdevice.h"
  53. #include "tdeinputdevice.h"
  54. #include "tdecryptographiccarddevice.h"
  55. // Compile-time configuration
  56. #include "config.h"
  57. // Profiling stuff
  58. //#define CPUPROFILING
  59. //#define STATELESSPROFILING
  60. #include <time.h>
  61. timespec diff(timespec start, timespec end)
  62. {
  63. timespec temp;
  64. if ((end.tv_nsec-start.tv_nsec)<0) {
  65. temp.tv_sec = end.tv_sec-start.tv_sec-1;
  66. temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
  67. } else {
  68. temp.tv_sec = end.tv_sec-start.tv_sec;
  69. temp.tv_nsec = end.tv_nsec-start.tv_nsec;
  70. }
  71. return temp;
  72. }
  73. // BEGIN BLOCK
  74. // Copied from include/linux/genhd.h
  75. #define GENHD_FL_REMOVABLE 1
  76. #define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
  77. #define GENHD_FL_CD 8
  78. #define GENHD_FL_UP 16
  79. #define GENHD_FL_SUPPRESS_PARTITION_INFO 32
  80. #define GENHD_FL_EXT_DEVT 64
  81. #define GENHD_FL_NATIVE_CAPACITY 128
  82. #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256
  83. // END BLOCK
  84. // NOTE TO DEVELOPERS
  85. // This command will greatly help when attempting to find properties to distinguish one device from another
  86. // udevadm info --query=all --path=/sys/....
  87. // This routine is courtsey of an answer on "Stack Overflow"
  88. // It takes an LSB-first int and makes it an MSB-first int (or vice versa)
  89. unsigned int reverse_bits(register unsigned int x)
  90. {
  91. x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
  92. x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
  93. x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
  94. x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
  95. return((x >> 16) | (x << 16));
  96. }
  97. // Helper function implemented in tdestoragedevice.cpp
  98. TQString decodeHexEncoding(TQString str);
  99. #if defined(WITH_TDEHWLIB_DAEMONS) || defined(WITH_UDISKS) || defined(WITH_UDISKS2) || defined(WITH_NETWORK_MANAGER_BACKEND)
  100. #include <tqdbusvariant.h>
  101. #include <tqdbusdata.h>
  102. // Convenience method for tdehwlib DBUS calls
  103. // FIXME
  104. // Should probably be part of dbus-1-tqt
  105. TQT_DBusData convertDBUSDataToVariantData(TQT_DBusData object) {
  106. TQT_DBusVariant variant;
  107. variant.value = object;
  108. variant.signature = variant.value.buildDBusSignature();
  109. return TQT_DBusData::fromVariant(variant);
  110. }
  111. #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) || defined(WITH_NETWORK_MANAGER_BACKEND)
  112. TDEHardwareDevices::TDEHardwareDevices() {
  113. // Initialize members
  114. pci_id_map = 0;
  115. usb_id_map = 0;
  116. pnp_id_map = 0;
  117. dpy_id_map = 0;
  118. // Set up device list
  119. m_deviceList.setAutoDelete( TRUE ); // the list owns the objects
  120. // Initialize udev interface
  121. m_udevStruct = udev_new();
  122. if (!m_udevStruct) {
  123. printf("Unable to create udev interface\n");
  124. }
  125. if (m_udevStruct) {
  126. // Set up device add/remove monitoring
  127. m_udevMonitorStruct = udev_monitor_new_from_netlink(m_udevStruct, "udev");
  128. udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitorStruct, NULL, NULL);
  129. udev_monitor_enable_receiving(m_udevMonitorStruct);
  130. int udevmonitorfd = udev_monitor_get_fd(m_udevMonitorStruct);
  131. if (udevmonitorfd >= 0) {
  132. m_devScanNotifier = new TQSocketNotifier(udevmonitorfd, TQSocketNotifier::Read, this);
  133. connect( m_devScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processHotPluggedHardware()) );
  134. }
  135. // Read in the current mount table
  136. // 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
  137. m_mountTable.clear();
  138. TQFile file( "/proc/mounts" );
  139. if ( file.open( IO_ReadOnly ) ) {
  140. TQTextStream stream( &file );
  141. while ( !stream.atEnd() ) {
  142. m_mountTable.append(stream.readLine());
  143. }
  144. file.close();
  145. }
  146. // Monitor for changed mounts
  147. m_procMountsFd = open("/proc/mounts", O_RDONLY, 0);
  148. if (m_procMountsFd >= 0) {
  149. m_mountScanNotifier = new TQSocketNotifier(m_procMountsFd, TQSocketNotifier::Exception, this);
  150. connect( m_mountScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processModifiedMounts()) );
  151. }
  152. // Read in the current cpu information
  153. // 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
  154. m_cpuInfo.clear();
  155. TQFile cpufile( "/proc/cpuinfo" );
  156. if ( cpufile.open( IO_ReadOnly ) ) {
  157. TQTextStream stream( &cpufile );
  158. while ( !stream.atEnd() ) {
  159. m_cpuInfo.append(stream.readLine());
  160. }
  161. cpufile.close();
  162. }
  163. // [FIXME 0.01]
  164. // Apparently the Linux kernel just does not notify userspace applications of CPU frequency changes
  165. // 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
  166. #if 0
  167. // Monitor for changed cpu information
  168. // Watched directories are set up during the initial CPU scan
  169. m_cpuWatch = new KSimpleDirWatch(this);
  170. connect( m_cpuWatch, TQT_SIGNAL(dirty(const TQString &)), this, TQT_SLOT(processModifiedCPUs()) );
  171. #else
  172. m_cpuWatchTimer = new TQTimer(this);
  173. connect( m_cpuWatchTimer, SIGNAL(timeout()), this, SLOT(processModifiedCPUs()) );
  174. #endif
  175. // Some devices do not receive update signals from udev
  176. // These devices must be polled, and a good polling interval is 1 second
  177. m_deviceWatchTimer = new TQTimer(this);
  178. connect( m_deviceWatchTimer, SIGNAL(timeout()), this, SLOT(processStatelessDevices()) );
  179. // Special case for battery polling (longer delay, 5 seconds)
  180. m_batteryWatchTimer = new TQTimer(this);
  181. connect( m_batteryWatchTimer, SIGNAL(timeout()), this, SLOT(processBatteryDevices()) );
  182. // Update internal device information
  183. queryHardwareInformation();
  184. }
  185. }
  186. TDEHardwareDevices::~TDEHardwareDevices() {
  187. // Stop device scanning
  188. m_deviceWatchTimer->stop();
  189. m_batteryWatchTimer->stop();
  190. // [FIXME 0.01]
  191. #if 0
  192. // Stop CPU scanning
  193. m_cpuWatch->stopScan();
  194. #else
  195. m_cpuWatchTimer->stop();
  196. #endif
  197. // Stop mount scanning
  198. close(m_procMountsFd);
  199. // Tear down udev interface
  200. if(m_udevMonitorStruct) {
  201. udev_monitor_unref(m_udevMonitorStruct);
  202. }
  203. udev_unref(m_udevStruct);
  204. // Delete members
  205. if (pci_id_map) {
  206. delete pci_id_map;
  207. }
  208. if (usb_id_map) {
  209. delete usb_id_map;
  210. }
  211. if (pnp_id_map) {
  212. delete pnp_id_map;
  213. }
  214. if (dpy_id_map) {
  215. delete dpy_id_map;
  216. }
  217. }
  218. void TDEHardwareDevices::setTriggerlessHardwareUpdatesEnabled(bool enable) {
  219. if (enable) {
  220. TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
  221. if (nodezerocpufreq.exists()) {
  222. m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
  223. }
  224. m_batteryWatchTimer->stop(); // Battery devices are included in stateless devices
  225. m_deviceWatchTimer->start( 1000, FALSE ); // 1 second repeating timer
  226. }
  227. else {
  228. m_cpuWatchTimer->stop();
  229. m_deviceWatchTimer->stop();
  230. }
  231. }
  232. void TDEHardwareDevices::setBatteryUpdatesEnabled(bool enable) {
  233. if (enable) {
  234. TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
  235. if (nodezerocpufreq.exists()) {
  236. m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
  237. }
  238. m_batteryWatchTimer->start( 5000, FALSE ); // 5 second repeating timer
  239. }
  240. else {
  241. m_cpuWatchTimer->stop();
  242. m_batteryWatchTimer->stop();
  243. }
  244. }
  245. void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) {
  246. rescanDeviceInformation(hwdevice, true);
  247. }
  248. void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice, bool regenerateDeviceTree) {
  249. struct udev_device *dev;
  250. dev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
  251. updateExistingDeviceInformation(hwdevice);
  252. if (regenerateDeviceTree) {
  253. updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
  254. }
  255. udev_device_unref(dev);
  256. }
  257. TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
  258. if (!syspath.endsWith("/")) {
  259. syspath += "/";
  260. }
  261. TDEGenericDevice *hwdevice;
  262. // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
  263. TDEGenericHardwareList devList = listAllPhysicalDevices();
  264. for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
  265. if (hwdevice->systemPath() == syspath) {
  266. return hwdevice;
  267. }
  268. }
  269. return 0;
  270. }
  271. TDECPUDevice* TDEHardwareDevices::findCPUBySystemPath(TQString syspath, bool inCache=true) {
  272. TDECPUDevice* cdevice;
  273. // Look for the device in the cache first
  274. if(inCache && !m_cpuByPathCache.isEmpty()) {
  275. cdevice = m_cpuByPathCache.find(syspath);
  276. if(cdevice) {
  277. return cdevice;
  278. }
  279. }
  280. // If the CPU was not found in cache, we need to parse the entire device list to get it.
  281. cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(syspath));
  282. if(cdevice) {
  283. if(inCache) {
  284. m_cpuByPathCache.insert(syspath, cdevice); // Add the device to the cache
  285. }
  286. return cdevice;
  287. }
  288. return 0;
  289. }
  290. TDEGenericDevice* TDEHardwareDevices::findByUniqueID(TQString uid) {
  291. TDEGenericDevice *hwdevice;
  292. // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
  293. TDEGenericHardwareList devList = listAllPhysicalDevices();
  294. for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
  295. if (hwdevice->uniqueID() == uid) {
  296. return hwdevice;
  297. }
  298. }
  299. return 0;
  300. }
  301. TDEGenericDevice* TDEHardwareDevices::findByDeviceNode(TQString devnode) {
  302. TDEGenericDevice *hwdevice;
  303. for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
  304. if (hwdevice->deviceNode() == devnode) {
  305. return hwdevice;
  306. }
  307. }
  308. return 0;
  309. }
  310. TDEStorageDevice* TDEHardwareDevices::findDiskByUID(TQString uid) {
  311. TDEGenericDevice *hwdevice;
  312. for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
  313. if (hwdevice->type() == TDEGenericDeviceType::Disk) {
  314. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
  315. if (sdevice->uniqueID() == uid) {
  316. return sdevice;
  317. }
  318. }
  319. }
  320. return 0;
  321. }
  322. void TDEHardwareDevices::processHotPluggedHardware() {
  323. udev_device* dev = udev_monitor_receive_device(m_udevMonitorStruct);
  324. if (dev) {
  325. TQString actionevent(udev_device_get_action(dev));
  326. if (actionevent == "add") {
  327. TDEGenericDevice* device = classifyUnknownDevice(dev);
  328. // Make sure this device is not a duplicate
  329. TDEGenericDevice *hwdevice;
  330. for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
  331. if (hwdevice->systemPath() == device->systemPath()) {
  332. delete device;
  333. device = 0;
  334. break;
  335. }
  336. }
  337. if (device) {
  338. m_deviceList.append(device);
  339. updateParentDeviceInformation(device); // Update parent/child tables for this device
  340. emit hardwareAdded(device);
  341. emit hardwareEvent(TDEHardwareEvent::HardwareAdded, device->uniqueID());
  342. }
  343. }
  344. else if (actionevent == "remove") {
  345. // Delete device from hardware listing
  346. TQString systempath(udev_device_get_syspath(dev));
  347. systempath += "/";
  348. TDEGenericDevice *hwdevice;
  349. for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
  350. if (hwdevice->systemPath() == systempath) {
  351. // Temporarily disable auto-deletion to ensure object validity when calling the Removed events below
  352. m_deviceList.setAutoDelete(false);
  353. // If the device is a storage device and has a slave, update it as well
  354. if (hwdevice->type() == TDEGenericDeviceType::Disk) {
  355. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
  356. TQStringList slavedevices = sdevice->slaveDevices();
  357. m_deviceList.remove(hwdevice);
  358. for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
  359. TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
  360. if (slavedevice) {
  361. rescanDeviceInformation(slavedevice);
  362. emit hardwareUpdated(slavedevice);
  363. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
  364. }
  365. }
  366. }
  367. else {
  368. m_deviceList.remove(hwdevice);
  369. }
  370. emit hardwareRemoved(hwdevice);
  371. emit hardwareEvent(TDEHardwareEvent::HardwareRemoved, hwdevice->uniqueID());
  372. // Reenable auto-deletion and delete the removed device object
  373. m_deviceList.setAutoDelete(true);
  374. delete hwdevice;
  375. break;
  376. }
  377. }
  378. }
  379. else if (actionevent == "change") {
  380. // Update device and emit change event
  381. TQString systempath(udev_device_get_syspath(dev));
  382. systempath += "/";
  383. TDEGenericDevice *hwdevice;
  384. for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
  385. if (hwdevice->systemPath() == systempath) {
  386. if (!hwdevice->blacklistedForUpdate()) {
  387. classifyUnknownDevice(dev, hwdevice, false);
  388. updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
  389. emit hardwareUpdated(hwdevice);
  390. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  391. }
  392. }
  393. else if ((hwdevice->type() == TDEGenericDeviceType::Monitor)
  394. && (hwdevice->systemPath().contains(systempath))) {
  395. if (!hwdevice->blacklistedForUpdate()) {
  396. struct udev_device *slavedev;
  397. slavedev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
  398. classifyUnknownDevice(slavedev, hwdevice, false);
  399. udev_device_unref(slavedev);
  400. updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
  401. emit hardwareUpdated(hwdevice);
  402. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  403. }
  404. }
  405. }
  406. }
  407. udev_device_unref(dev);
  408. }
  409. }
  410. void TDEHardwareDevices::processModifiedCPUs() {
  411. // Detect what changed between the old cpu information and the new information,
  412. // and emit appropriate events
  413. #ifdef CPUPROFILING
  414. timespec time1, time2, time3;
  415. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
  416. time3 = time1;
  417. printf("TDEHardwareDevices::processModifiedCPUs() : begin at '%u'\n", time1.tv_nsec);
  418. #endif
  419. // Read new CPU information table
  420. m_cpuInfo.clear();
  421. TQFile cpufile( "/proc/cpuinfo" );
  422. if ( cpufile.open( IO_ReadOnly ) ) {
  423. TQTextStream stream( &cpufile );
  424. // Using read() instead of readLine() inside a loop is 4 times faster !
  425. m_cpuInfo = TQStringList::split('\n', stream.read(), true);
  426. cpufile.close();
  427. }
  428. #ifdef CPUPROFILING
  429. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  430. printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint1 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
  431. time1 = time2;
  432. #endif
  433. // Ensure "processor" is the first entry in each block and determine which cpuinfo type is in use
  434. bool cpuinfo_format_x86 = true;
  435. bool cpuinfo_format_arm = false;
  436. TQString curline1;
  437. TQString curline2;
  438. int blockNumber = 0;
  439. TQStringList::Iterator blockBegin = m_cpuInfo.begin();
  440. for (TQStringList::Iterator cpuit1 = m_cpuInfo.begin(); cpuit1 != m_cpuInfo.end(); ++cpuit1) {
  441. curline1 = *cpuit1;
  442. if (!(*blockBegin).startsWith("processor")) {
  443. bool found = false;
  444. TQStringList::Iterator cpuit2;
  445. for (cpuit2 = blockBegin; cpuit2 != m_cpuInfo.end(); ++cpuit2) {
  446. curline2 = *cpuit2;
  447. if (curline2.startsWith("processor")) {
  448. found = true;
  449. break;
  450. }
  451. else if (curline2 == NULL || curline2 == "") {
  452. break;
  453. }
  454. }
  455. if (found) {
  456. m_cpuInfo.insert(blockBegin, (*cpuit2));
  457. }
  458. else if(blockNumber == 0) {
  459. m_cpuInfo.insert(blockBegin, "processor : 0");
  460. }
  461. }
  462. if (curline1 == NULL || curline1 == "") {
  463. blockNumber++;
  464. blockBegin = cpuit1;
  465. blockBegin++;
  466. }
  467. else if (curline1.startsWith("Processor")) {
  468. cpuinfo_format_x86 = false;
  469. cpuinfo_format_arm = true;
  470. }
  471. }
  472. #ifdef CPUPROFILING
  473. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  474. printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint2 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
  475. time1 = time2;
  476. #endif
  477. // Parse CPU information table
  478. TDECPUDevice *cdevice;
  479. cdevice = 0;
  480. bool modified = false;
  481. bool have_frequency = false;
  482. TQString curline;
  483. int processorNumber = 0;
  484. int processorCount = 0;
  485. if (cpuinfo_format_x86) {
  486. // ===================================================================================================================================
  487. // x86/x86_64
  488. // ===================================================================================================================================
  489. TQStringList::Iterator cpuit;
  490. for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
  491. curline = *cpuit;
  492. if (curline.startsWith("processor")) {
  493. curline.remove(0, curline.find(":")+2);
  494. processorNumber = curline.toInt();
  495. if (!cdevice) {
  496. cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
  497. }
  498. if (cdevice) {
  499. if (cdevice->coreNumber() != processorNumber) {
  500. modified = true;
  501. cdevice->internalSetCoreNumber(processorNumber);
  502. }
  503. }
  504. }
  505. else if (cdevice && curline.startsWith("model name")) {
  506. curline.remove(0, curline.find(":")+2);
  507. if (cdevice->name() != curline) {
  508. modified = true;
  509. cdevice->internalSetName(curline);
  510. }
  511. }
  512. else if (cdevice && curline.startsWith("cpu MHz")) {
  513. curline.remove(0, curline.find(":")+2);
  514. if (cdevice->frequency() != curline.toDouble()) {
  515. modified = true;
  516. cdevice->internalSetFrequency(curline.toDouble());
  517. }
  518. have_frequency = true;
  519. }
  520. else if (cdevice && curline.startsWith("vendor_id")) {
  521. curline.remove(0, curline.find(":")+2);
  522. if (cdevice->vendorName() != curline) {
  523. modified = true;
  524. cdevice->internalSetVendorName(curline);
  525. }
  526. if (cdevice->vendorEncoded() != curline) {
  527. modified = true;
  528. cdevice->internalSetVendorEncoded(curline);
  529. }
  530. }
  531. else if (curline == NULL || curline == "") {
  532. cdevice = 0;
  533. }
  534. }
  535. }
  536. else if (cpuinfo_format_arm) {
  537. // ===================================================================================================================================
  538. // ARM
  539. // ===================================================================================================================================
  540. TQStringList::Iterator cpuit;
  541. TQString modelName;
  542. TQString vendorName;
  543. TQString serialNumber;
  544. for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
  545. curline = *cpuit;
  546. if (curline.startsWith("Processor")) {
  547. curline.remove(0, curline.find(":")+2);
  548. modelName = curline;
  549. }
  550. else if (curline.startsWith("Hardware")) {
  551. curline.remove(0, curline.find(":")+2);
  552. vendorName = curline;
  553. }
  554. else if (curline.startsWith("Serial")) {
  555. curline.remove(0, curline.find(":")+2);
  556. serialNumber = curline;
  557. }
  558. }
  559. for (TQStringList::Iterator cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
  560. curline = *cpuit;
  561. if (curline.startsWith("processor")) {
  562. curline.remove(0, curline.find(":")+2);
  563. processorNumber = curline.toInt();
  564. if (!cdevice) {
  565. cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
  566. if (cdevice) {
  567. // Set up CPU information structures
  568. if (cdevice->coreNumber() != processorNumber) modified = true;
  569. cdevice->internalSetCoreNumber(processorNumber);
  570. if (cdevice->name() != modelName) modified = true;
  571. cdevice->internalSetName(modelName);
  572. if (cdevice->vendorName() != vendorName) modified = true;
  573. cdevice->internalSetVendorName(vendorName);
  574. if (cdevice->vendorEncoded() != vendorName) modified = true;
  575. cdevice->internalSetVendorEncoded(vendorName);
  576. if (cdevice->serialNumber() != serialNumber) modified = true;
  577. cdevice->internalSetSerialNumber(serialNumber);
  578. }
  579. }
  580. }
  581. if (curline == NULL || curline == "") {
  582. cdevice = 0;
  583. }
  584. }
  585. }
  586. processorCount = processorNumber+1;
  587. #ifdef CPUPROFILING
  588. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  589. printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
  590. time1 = time2;
  591. #endif
  592. TDECPUDevice* firstCPU = NULL;
  593. // Read in other information from cpufreq, if available
  594. for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
  595. cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
  596. TQDir cpufreq_dir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber));
  597. TQString scalinggovernor;
  598. TQString scalingdriver;
  599. double minfrequency = -1;
  600. double maxfrequency = -1;
  601. double trlatency = -1;
  602. TQStringList affectedcpulist;
  603. TQStringList frequencylist;
  604. TQStringList governorlist;
  605. if (cpufreq_dir.exists()) {
  606. TQString nodename;
  607. if ((processorNumber == 0) || (!firstCPU)) {
  608. // Remember the first CPU options so that we can reuse it later.
  609. firstCPU = cdevice;
  610. nodename = cpufreq_dir.path();
  611. nodename.append("/scaling_governor");
  612. TQFile scalinggovernorfile(nodename);
  613. if (scalinggovernorfile.open(IO_ReadOnly)) {
  614. TQTextStream stream( &scalinggovernorfile );
  615. scalinggovernor = stream.readLine();
  616. scalinggovernorfile.close();
  617. }
  618. nodename = cpufreq_dir.path();
  619. nodename.append("/scaling_driver");
  620. TQFile scalingdriverfile(nodename);
  621. if (scalingdriverfile.open(IO_ReadOnly)) {
  622. TQTextStream stream( &scalingdriverfile );
  623. scalingdriver = stream.readLine();
  624. scalingdriverfile.close();
  625. }
  626. nodename = cpufreq_dir.path();
  627. nodename.append("/cpuinfo_min_freq");
  628. TQFile minfrequencyfile(nodename);
  629. if (minfrequencyfile.open(IO_ReadOnly)) {
  630. TQTextStream stream( &minfrequencyfile );
  631. minfrequency = stream.readLine().toDouble()/1000.0;
  632. minfrequencyfile.close();
  633. }
  634. nodename = cpufreq_dir.path();
  635. nodename.append("/cpuinfo_max_freq");
  636. TQFile maxfrequencyfile(nodename);
  637. if (maxfrequencyfile.open(IO_ReadOnly)) {
  638. TQTextStream stream( &maxfrequencyfile );
  639. maxfrequency = stream.readLine().toDouble()/1000.0;
  640. maxfrequencyfile.close();
  641. }
  642. nodename = cpufreq_dir.path();
  643. nodename.append("/cpuinfo_transition_latency");
  644. TQFile trlatencyfile(nodename);
  645. if (trlatencyfile.open(IO_ReadOnly)) {
  646. TQTextStream stream( &trlatencyfile );
  647. trlatency = stream.readLine().toDouble()/1000.0;
  648. trlatencyfile.close();
  649. }
  650. nodename = cpufreq_dir.path();
  651. nodename.append("/scaling_available_frequencies");
  652. TQFile availfreqsfile(nodename);
  653. if (availfreqsfile.open(IO_ReadOnly)) {
  654. TQTextStream stream( &availfreqsfile );
  655. frequencylist = TQStringList::split(" ", stream.readLine());
  656. availfreqsfile.close();
  657. }
  658. nodename = cpufreq_dir.path();
  659. nodename.append("/scaling_available_governors");
  660. TQFile availgvrnsfile(nodename);
  661. if (availgvrnsfile.open(IO_ReadOnly)) {
  662. TQTextStream stream( &availgvrnsfile );
  663. governorlist = TQStringList::split(" ", stream.readLine());
  664. availgvrnsfile.close();
  665. }
  666. }
  667. // Other CPU should have the same values as the first one. Simply copy them.
  668. else {
  669. scalinggovernor = firstCPU->governor();
  670. scalingdriver = firstCPU->scalingDriver();
  671. minfrequency = firstCPU->minFrequency();
  672. maxfrequency = firstCPU->maxFrequency();
  673. trlatency = firstCPU->transitionLatency();
  674. frequencylist = firstCPU->availableFrequencies();
  675. governorlist = firstCPU->availableGovernors();
  676. }
  677. // The following data are different on each CPU
  678. nodename = cpufreq_dir.path();
  679. nodename.append("/affected_cpus");
  680. TQFile tiedcpusfile(nodename);
  681. if (tiedcpusfile.open(IO_ReadOnly)) {
  682. TQTextStream stream( &tiedcpusfile );
  683. affectedcpulist = TQStringList::split(" ", stream.readLine());
  684. tiedcpusfile.close();
  685. }
  686. // We may already have the CPU Mhz information in '/proc/cpuinfo'
  687. if (!have_frequency) {
  688. nodename = cpufreq_dir.path();
  689. nodename.append("/cpuinfo_cur_freq");
  690. TQFile cpufreqfile(nodename);
  691. if (cpufreqfile.open(IO_ReadOnly)) {
  692. TQTextStream stream( &cpufreqfile );
  693. if (cdevice) {
  694. cdevice->internalSetFrequency(stream.readLine().toDouble()/1000.0);
  695. }
  696. cpufreqfile.close();
  697. have_frequency = true;
  698. }
  699. }
  700. bool minfrequencyFound = false;
  701. bool maxfrequencyFound = false;
  702. TQStringList::Iterator freqit;
  703. for ( freqit = frequencylist.begin(); freqit != frequencylist.end(); ++freqit ) {
  704. double thisfrequency = (*freqit).toDouble()/1000.0;
  705. if (thisfrequency == minfrequency) {
  706. minfrequencyFound = true;
  707. }
  708. if (thisfrequency == maxfrequency) {
  709. maxfrequencyFound = true;
  710. }
  711. }
  712. if (!minfrequencyFound) {
  713. int minFrequencyInt = (minfrequency*1000.0);
  714. frequencylist.prepend(TQString("%1").arg(minFrequencyInt));
  715. }
  716. if (!maxfrequencyFound) {
  717. int maxfrequencyInt = (maxfrequency*1000.0);
  718. frequencylist.append(TQString("%1").arg(maxfrequencyInt));
  719. }
  720. #ifdef CPUPROFILING
  721. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  722. printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3.%u at %u [%u]\n", processorNumber, time2.tv_nsec, diff(time1,time2).tv_nsec);
  723. time1 = time2;
  724. #endif
  725. }
  726. else {
  727. if (have_frequency) {
  728. if (cdevice) {
  729. minfrequency = cdevice->frequency();
  730. maxfrequency = cdevice->frequency();
  731. }
  732. }
  733. }
  734. // Update CPU information structure
  735. if (cdevice) {
  736. if (cdevice->governor() != scalinggovernor) {
  737. modified = true;
  738. cdevice->internalSetGovernor(scalinggovernor);
  739. }
  740. if (cdevice->scalingDriver() != scalingdriver) {
  741. modified = true;
  742. cdevice->internalSetScalingDriver(scalingdriver);
  743. }
  744. if (cdevice->minFrequency() != minfrequency) {
  745. modified = true;
  746. cdevice->internalSetMinFrequency(minfrequency);
  747. }
  748. if (cdevice->maxFrequency() != maxfrequency) {
  749. modified = true;
  750. cdevice->internalSetMaxFrequency(maxfrequency);
  751. }
  752. if (cdevice->transitionLatency() != trlatency) {
  753. modified = true;
  754. cdevice->internalSetTransitionLatency(trlatency);
  755. }
  756. if (cdevice->dependentProcessors().join(" ") != affectedcpulist.join(" ")) {
  757. modified = true;
  758. cdevice->internalSetDependentProcessors(affectedcpulist);
  759. }
  760. if (cdevice->availableFrequencies().join(" ") != frequencylist.join(" ")) {
  761. modified = true;
  762. cdevice->internalSetAvailableFrequencies(frequencylist);
  763. }
  764. if (cdevice->availableGovernors().join(" ") != governorlist.join(" ")) {
  765. modified = true;
  766. cdevice->internalSetAvailableGovernors(governorlist);
  767. }
  768. }
  769. }
  770. #ifdef CPUPROFILING
  771. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  772. printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint4 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
  773. time1 = time2;
  774. #endif
  775. if (modified) {
  776. for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
  777. TDEGenericDevice* hwdevice = findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
  778. if (hwdevice) {
  779. // Signal new information available
  780. emit hardwareUpdated(hwdevice);
  781. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  782. }
  783. }
  784. }
  785. #ifdef CPUPROFILING
  786. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  787. printf("TDEHardwareDevices::processModifiedCPUs() : end at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
  788. printf("TDEHardwareDevices::processModifiedCPUs() : total time: %u\n", diff(time3,time2).tv_nsec);
  789. #endif
  790. }
  791. void TDEHardwareDevices::processStatelessDevices() {
  792. // Some devices do not emit changed signals
  793. // So far, network cards and sensors need to be polled
  794. TDEGenericDevice *hwdevice;
  795. #ifdef STATELESSPROFILING
  796. timespec time1, time2, time3;
  797. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
  798. printf("TDEHardwareDevices::processStatelessDevices() : begin at '%u'\n", time1.tv_nsec);
  799. time3 = time1;
  800. #endif
  801. // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
  802. TDEGenericHardwareList devList = listAllPhysicalDevices();
  803. for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
  804. 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)) {
  805. rescanDeviceInformation(hwdevice, false);
  806. emit hardwareUpdated(hwdevice);
  807. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  808. #ifdef STATELESSPROFILING
  809. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  810. printf("TDEHardwareDevices::processStatelessDevices() : '%s' finished at %u [%u]\n", (hwdevice->name()).ascii(), time2.tv_nsec, diff(time1,time2).tv_nsec);
  811. time1 = time2;
  812. #endif
  813. }
  814. }
  815. #ifdef STATELESSPROFILING
  816. clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  817. printf("TDEHardwareDevices::processStatelessDevices() : end at '%u'\n", time2.tv_nsec);
  818. printf("TDEHardwareDevices::processStatelessDevices() : took '%u'\n", diff(time3,time2).tv_nsec);
  819. #endif
  820. }
  821. void TDEHardwareDevices::processBatteryDevices() {
  822. TDEGenericDevice *hwdevice;
  823. // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
  824. TDEGenericHardwareList devList = listAllPhysicalDevices();
  825. for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
  826. if (hwdevice->type() == TDEGenericDeviceType::Battery) {
  827. rescanDeviceInformation(hwdevice, false);
  828. emit hardwareUpdated(hwdevice);
  829. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  830. }
  831. }
  832. }
  833. void TDEHardwareDevices::processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice) {
  834. emit eventDeviceKeyPressed(keycode, edevice);
  835. }
  836. void TDEHardwareDevices::processModifiedMounts() {
  837. // Detect what changed between the old mount table and the new one,
  838. // and emit appropriate events
  839. TQStringList deletedEntries = m_mountTable;
  840. // Read in the new mount table
  841. m_mountTable.clear();
  842. TQFile file( "/proc/mounts" );
  843. if ( file.open( IO_ReadOnly ) ) {
  844. TQTextStream stream( &file );
  845. while ( !stream.atEnd() ) {
  846. m_mountTable.append(stream.readLine());
  847. }
  848. file.close();
  849. }
  850. TQStringList addedEntries = m_mountTable;
  851. // Remove all entries that are identical in both tables
  852. processModifiedMounts_removeagain:
  853. for ( TQStringList::Iterator delit = deletedEntries.begin(); delit != deletedEntries.end(); ++delit ) {
  854. for ( TQStringList::Iterator addit = addedEntries.begin(); addit != addedEntries.end(); ++addit ) {
  855. if ((*delit) == (*addit)) {
  856. deletedEntries.remove(delit);
  857. addedEntries.remove(addit);
  858. // Reset iterators to prevent bugs/crashes
  859. // FIXME
  860. // Is there any way to completely reset both loops without using goto?
  861. goto processModifiedMounts_removeagain;
  862. }
  863. }
  864. }
  865. TQStringList::Iterator it;
  866. for ( it = addedEntries.begin(); it != addedEntries.end(); ++it ) {
  867. TQStringList mountInfo = TQStringList::split(" ", (*it), true);
  868. // Try to find a device that matches the altered node
  869. TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
  870. if (hwdevice) {
  871. emit hardwareUpdated(hwdevice);
  872. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  873. // If the device is a storage device and has a slave, update it as well
  874. if (hwdevice->type() == TDEGenericDeviceType::Disk) {
  875. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
  876. TQStringList slavedevices = sdevice->slaveDevices();
  877. for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
  878. TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
  879. if (slavedevice) {
  880. emit hardwareUpdated(slavedevice);
  881. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
  882. }
  883. }
  884. }
  885. }
  886. }
  887. for ( it = deletedEntries.begin(); it != deletedEntries.end(); ++it ) {
  888. TQStringList mountInfo = TQStringList::split(" ", (*it), true);
  889. // Try to find a device that matches the altered node
  890. TDEGenericDevice* hwdevice = findByDeviceNode(*mountInfo.at(0));
  891. if (hwdevice) {
  892. emit hardwareUpdated(hwdevice);
  893. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
  894. // If the device is a storage device and has a slave, update it as well
  895. if (hwdevice->type() == TDEGenericDeviceType::Disk) {
  896. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
  897. TQStringList slavedevices = sdevice->slaveDevices();
  898. for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
  899. TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
  900. if (slavedevice) {
  901. emit hardwareUpdated(slavedevice);
  902. emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, slavedevice->uniqueID());
  903. }
  904. }
  905. }
  906. }
  907. }
  908. emit mountTableModified();
  909. emit hardwareEvent(TDEHardwareEvent::MountTableModified, TQString());
  910. }
  911. 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) {
  912. // Classify a disk device type to the best of our ability
  913. TDEDiskDeviceType::TDEDiskDeviceType disktype = TDEDiskDeviceType::Null;
  914. if (devicebus.upper() == "USB") {
  915. disktype = disktype | TDEDiskDeviceType::USB;
  916. }
  917. if (disktypestring.upper() == "DISK") {
  918. disktype = disktype | TDEDiskDeviceType::HDD;
  919. }
  920. if ((disktypestring.upper() == "FLOPPY")
  921. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY")) == "1")) {
  922. disktype = disktype | TDEDiskDeviceType::Floppy;
  923. disktype = disktype & ~TDEDiskDeviceType::HDD;
  924. }
  925. if ((disktypestring.upper() == "ZIP")
  926. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLOPPY_ZIP")) == "1")
  927. || ((devicevendor.upper() == "IOMEGA") && (devicemodel.upper().contains("ZIP")))) {
  928. disktype = disktype | TDEDiskDeviceType::Zip;
  929. disktype = disktype & ~TDEDiskDeviceType::HDD;
  930. }
  931. if ((devicevendor.upper() == "APPLE") && (devicemodel.upper().contains("IPOD"))) {
  932. disktype = disktype | TDEDiskDeviceType::MediaDevice;
  933. }
  934. if ((devicevendor.upper() == "SANDISK") && (devicemodel.upper().contains("SANSA"))) {
  935. disktype = disktype | TDEDiskDeviceType::MediaDevice;
  936. }
  937. if (disktypestring.upper() == "TAPE") {
  938. disktype = disktype | TDEDiskDeviceType::Tape;
  939. }
  940. if ((disktypestring.upper() == "COMPACT_FLASH")
  941. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_CF")) == "1")
  942. || (TQString(udev_device_get_property_value(dev, "ID_ATA_CFA")) == "1")) {
  943. disktype = disktype | TDEDiskDeviceType::CompactFlash;
  944. disktype = disktype | TDEDiskDeviceType::HDD;
  945. }
  946. if ((disktypestring.upper() == "MEMORY_STICK")
  947. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MS")) == "1")) {
  948. disktype = disktype | TDEDiskDeviceType::MemoryStick;
  949. disktype = disktype | TDEDiskDeviceType::HDD;
  950. }
  951. if ((disktypestring.upper() == "SMART_MEDIA")
  952. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SM")) == "1")) {
  953. disktype = disktype | TDEDiskDeviceType::SmartMedia;
  954. disktype = disktype | TDEDiskDeviceType::HDD;
  955. }
  956. if ((disktypestring.upper() == "SD_MMC")
  957. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SD")) == "1")
  958. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_SDHC")) == "1")
  959. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH_MMC")) == "1")) {
  960. disktype = disktype | TDEDiskDeviceType::SDMMC;
  961. disktype = disktype | TDEDiskDeviceType::HDD;
  962. }
  963. if ((disktypestring.upper() == "FLASHKEY")
  964. || (TQString(udev_device_get_property_value(dev, "ID_DRIVE_FLASH")) == "1")) {
  965. disktype = disktype | TDEDiskDeviceType::Flash;
  966. disktype = disktype | TDEDiskDeviceType::HDD;
  967. }
  968. if (disktypestring.upper() == "OPTICAL") {
  969. disktype = disktype | TDEDiskDeviceType::Optical;
  970. }
  971. if (disktypestring.upper() == "JAZ") {
  972. disktype = disktype | TDEDiskDeviceType::Jaz;
  973. }
  974. if (disktypestring.upper() == "CD") {
  975. disktype = disktype | TDEDiskDeviceType::Optical;
  976. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) == "1") {
  977. disktype = disktype | TDEDiskDeviceType::CDROM;
  978. }
  979. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_R")) == "1") {
  980. disktype = disktype | TDEDiskDeviceType::CDR;
  981. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  982. }
  983. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_CD_RW")) == "1") {
  984. disktype = disktype | TDEDiskDeviceType::CDRW;
  985. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  986. disktype = disktype & ~TDEDiskDeviceType::CDR;
  987. }
  988. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW")) == "1") {
  989. disktype = disktype | TDEDiskDeviceType::CDMRRW;
  990. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  991. disktype = disktype & ~TDEDiskDeviceType::CDR;
  992. disktype = disktype & ~TDEDiskDeviceType::CDRW;
  993. }
  994. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MRW_W")) == "1") {
  995. disktype = disktype | TDEDiskDeviceType::CDMRRWW;
  996. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  997. disktype = disktype & ~TDEDiskDeviceType::CDR;
  998. disktype = disktype & ~TDEDiskDeviceType::CDRW;
  999. disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
  1000. }
  1001. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_MO")) == "1") {
  1002. disktype = disktype | TDEDiskDeviceType::CDMO;
  1003. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  1004. disktype = disktype & ~TDEDiskDeviceType::CDR;
  1005. disktype = disktype & ~TDEDiskDeviceType::CDRW;
  1006. disktype = disktype & ~TDEDiskDeviceType::CDMRRW;
  1007. disktype = disktype & ~TDEDiskDeviceType::CDMRRWW;
  1008. }
  1009. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD")) == "1") {
  1010. disktype = disktype | TDEDiskDeviceType::DVDROM;
  1011. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  1012. }
  1013. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RAM")) == "1") {
  1014. disktype = disktype | TDEDiskDeviceType::DVDRAM;
  1015. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1016. }
  1017. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R")) == "1") {
  1018. disktype = disktype | TDEDiskDeviceType::DVDR;
  1019. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1020. }
  1021. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_R_DL")) == "1") {
  1022. disktype = disktype | TDEDiskDeviceType::DVDRDL;
  1023. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1024. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1025. }
  1026. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R")) == "1") {
  1027. disktype = disktype | TDEDiskDeviceType::DVDPLUSR;
  1028. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1029. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1030. disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
  1031. }
  1032. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_R_DL")) == "1") {
  1033. disktype = disktype | TDEDiskDeviceType::DVDPLUSRDL;
  1034. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1035. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1036. disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
  1037. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
  1038. }
  1039. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW")) == "1") {
  1040. disktype = disktype | TDEDiskDeviceType::DVDRW;
  1041. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1042. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1043. disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
  1044. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
  1045. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
  1046. }
  1047. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_RW_DL")) == "1") {
  1048. disktype = disktype | TDEDiskDeviceType::DVDRWDL;
  1049. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1050. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1051. disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
  1052. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
  1053. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
  1054. disktype = disktype & ~TDEDiskDeviceType::DVDRW;
  1055. }
  1056. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW")) == "1") {
  1057. disktype = disktype | TDEDiskDeviceType::DVDPLUSRW;
  1058. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1059. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1060. disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
  1061. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
  1062. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
  1063. disktype = disktype & ~TDEDiskDeviceType::DVDRW;
  1064. disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
  1065. }
  1066. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_DVD_PLUS_RW_DL")) == "1") {
  1067. disktype = disktype | TDEDiskDeviceType::DVDPLUSRWDL;
  1068. disktype = disktype & ~TDEDiskDeviceType::DVDROM;
  1069. disktype = disktype & ~TDEDiskDeviceType::DVDR;
  1070. disktype = disktype & ~TDEDiskDeviceType::DVDRDL;
  1071. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSR;
  1072. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRDL;
  1073. disktype = disktype & ~TDEDiskDeviceType::DVDRW;
  1074. disktype = disktype & ~TDEDiskDeviceType::DVDRWDL;
  1075. disktype = disktype & ~TDEDiskDeviceType::DVDPLUSRW;
  1076. }
  1077. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD")) == "1") {
  1078. disktype = disktype | TDEDiskDeviceType::BDROM;
  1079. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  1080. }
  1081. if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_R")) == "1")
  1082. || (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!)
  1083. ) {
  1084. disktype = disktype | TDEDiskDeviceType::BDR;
  1085. disktype = disktype & ~TDEDiskDeviceType::BDROM;
  1086. }
  1087. if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_BD_RE")) == "1")
  1088. || (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!)
  1089. ) {
  1090. disktype = disktype | TDEDiskDeviceType::BDRW;
  1091. disktype = disktype & ~TDEDiskDeviceType::BDROM;
  1092. disktype = disktype & ~TDEDiskDeviceType::BDR;
  1093. }
  1094. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD")) == "1") {
  1095. disktype = disktype | TDEDiskDeviceType::HDDVDROM;
  1096. disktype = disktype & ~TDEDiskDeviceType::CDROM;
  1097. }
  1098. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_R")) == "1") {
  1099. disktype = disktype | TDEDiskDeviceType::HDDVDR;
  1100. disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
  1101. }
  1102. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_HDDVD_RW")) == "1") {
  1103. disktype = disktype | TDEDiskDeviceType::HDDVDRW;
  1104. disktype = disktype & ~TDEDiskDeviceType::HDDVDROM;
  1105. disktype = disktype & ~TDEDiskDeviceType::HDDVDR;
  1106. }
  1107. if (!TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO")).isNull()) {
  1108. disktype = disktype | TDEDiskDeviceType::CDAudio;
  1109. }
  1110. 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")) {
  1111. disktype = disktype | TDEDiskDeviceType::CDVideo;
  1112. }
  1113. if ((disktype & TDEDiskDeviceType::DVDROM)
  1114. || (disktype & TDEDiskDeviceType::DVDRAM)
  1115. || (disktype & TDEDiskDeviceType::DVDR)
  1116. || (disktype & TDEDiskDeviceType::DVDRW)
  1117. || (disktype & TDEDiskDeviceType::DVDRDL)
  1118. || (disktype & TDEDiskDeviceType::DVDRWDL)
  1119. || (disktype & TDEDiskDeviceType::DVDPLUSR)
  1120. || (disktype & TDEDiskDeviceType::DVDPLUSRW)
  1121. || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
  1122. || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
  1123. ) {
  1124. // Every VideoDVD must have a VIDEO_TS.IFO file
  1125. // Read this info via tdeiso_info, since udev couldn't be bothered to check DVD type on its own
  1126. int retcode = system(TQString("tdeiso_info --exists=ISO9660/VIDEO_TS/VIDEO_TS.IFO %1").arg(devicenode).ascii());
  1127. if (retcode == 0) {
  1128. disktype = disktype | TDEDiskDeviceType::DVDVideo;
  1129. }
  1130. }
  1131. }
  1132. // Detect RAM and Loop devices, since udev can't seem to...
  1133. if (systempath.startsWith("/sys/devices/virtual/block/ram")) {
  1134. disktype = disktype | TDEDiskDeviceType::RAM;
  1135. }
  1136. if (systempath.startsWith("/sys/devices/virtual/block/loop")) {
  1137. disktype = disktype | TDEDiskDeviceType::Loop;
  1138. }
  1139. if (disktype == TDEDiskDeviceType::Null) {
  1140. // Fallback
  1141. // If we can't recognize the disk type then set it as a simple HDD volume
  1142. disktype = disktype | TDEDiskDeviceType::HDD;
  1143. }
  1144. if (filesystemtype.upper() == "CRYPTO_LUKS") {
  1145. disktype = disktype | TDEDiskDeviceType::LUKS;
  1146. }
  1147. else if (filesystemtype.upper() == "CRYPTO") {
  1148. disktype = disktype | TDEDiskDeviceType::OtherCrypted;
  1149. }
  1150. return disktype;
  1151. }
  1152. // TDEStandardDirs::kde_default
  1153. typedef TQMap<TQString, TQString> TDEConfigMap;
  1154. TQString readUdevAttribute(udev_device* dev, TQString attr) {
  1155. return TQString(udev_device_get_property_value(dev, attr.ascii()));
  1156. }
  1157. TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQString query) {
  1158. TDEGenericDeviceType::TDEGenericDeviceType ret = TDEGenericDeviceType::Other;
  1159. // Keep this in sync with the TDEGenericDeviceType definition in the header
  1160. if (query == "Root") {
  1161. ret = TDEGenericDeviceType::Root;
  1162. }
  1163. else if (query == "RootSystem") {
  1164. ret = TDEGenericDeviceType::RootSystem;
  1165. }
  1166. else if (query == "CPU") {
  1167. ret = TDEGenericDeviceType::CPU;
  1168. }
  1169. else if (query == "GPU") {
  1170. ret = TDEGenericDeviceType::GPU;
  1171. }
  1172. else if (query == "RAM") {
  1173. ret = TDEGenericDeviceType::RAM;
  1174. }
  1175. else if (query == "Bus") {
  1176. ret = TDEGenericDeviceType::Bus;
  1177. }
  1178. else if (query == "I2C") {
  1179. ret = TDEGenericDeviceType::I2C;
  1180. }
  1181. else if (query == "MDIO") {
  1182. ret = TDEGenericDeviceType::MDIO;
  1183. }
  1184. else if (query == "Mainboard") {
  1185. ret = TDEGenericDeviceType::Mainboard;
  1186. }
  1187. else if (query == "Disk") {
  1188. ret = TDEGenericDeviceType::Disk;
  1189. }
  1190. else if (query == "SCSI") {
  1191. ret = TDEGenericDeviceType::SCSI;
  1192. }
  1193. else if (query == "StorageController") {
  1194. ret = TDEGenericDeviceType::StorageController;
  1195. }
  1196. else if (query == "Mouse") {
  1197. ret = TDEGenericDeviceType::Mouse;
  1198. }
  1199. else if (query == "Keyboard") {
  1200. ret = TDEGenericDeviceType::Keyboard;
  1201. }
  1202. else if (query == "HID") {
  1203. ret = TDEGenericDeviceType::HID;
  1204. }
  1205. else if (query == "Modem") {
  1206. ret = TDEGenericDeviceType::Modem;
  1207. }
  1208. else if (query == "Monitor") {
  1209. ret = TDEGenericDeviceType::Monitor;
  1210. }
  1211. else if (query == "Network") {
  1212. ret = TDEGenericDeviceType::Network;
  1213. }
  1214. else if (query == "NonvolatileMemory") {
  1215. ret = TDEGenericDeviceType::NonvolatileMemory;
  1216. }
  1217. else if (query == "Printer") {
  1218. ret = TDEGenericDeviceType::Printer;
  1219. }
  1220. else if (query == "Scanner") {
  1221. ret = TDEGenericDeviceType::Scanner;
  1222. }
  1223. else if (query == "Sound") {
  1224. ret = TDEGenericDeviceType::Sound;
  1225. }
  1226. else if (query == "VideoCapture") {
  1227. ret = TDEGenericDeviceType::VideoCapture;
  1228. }
  1229. else if (query == "IEEE1394") {
  1230. ret = TDEGenericDeviceType::IEEE1394;
  1231. }
  1232. else if (query == "PCMCIA") {
  1233. ret = TDEGenericDeviceType::PCMCIA;
  1234. }
  1235. else if (query == "Camera") {
  1236. ret = TDEGenericDeviceType::Camera;
  1237. }
  1238. else if (query == "Serial") {
  1239. ret = TDEGenericDeviceType::Serial;
  1240. }
  1241. else if (query == "Parallel") {
  1242. ret = TDEGenericDeviceType::Parallel;
  1243. }
  1244. else if (query == "TextIO") {
  1245. ret = TDEGenericDeviceType::TextIO;
  1246. }
  1247. else if (query == "Peripheral") {
  1248. ret = TDEGenericDeviceType::Peripheral;
  1249. }
  1250. else if (query == "Backlight") {
  1251. ret = TDEGenericDeviceType::Backlight;
  1252. }
  1253. else if (query == "Battery") {
  1254. ret = TDEGenericDeviceType::Battery;
  1255. }
  1256. else if (query == "Power") {
  1257. ret = TDEGenericDeviceType::PowerSupply;
  1258. }
  1259. else if (query == "Dock") {
  1260. ret = TDEGenericDeviceType::Dock;
  1261. }
  1262. else if (query == "ThermalSensor") {
  1263. ret = TDEGenericDeviceType::ThermalSensor;
  1264. }
  1265. else if (query == "ThermalControl") {
  1266. ret = TDEGenericDeviceType::ThermalControl;
  1267. }
  1268. else if (query == "Bluetooth") {
  1269. ret = TDEGenericDeviceType::BlueTooth;
  1270. }
  1271. else if (query == "Bridge") {
  1272. ret = TDEGenericDeviceType::Bridge;
  1273. }
  1274. else if (query == "Hub") {
  1275. ret = TDEGenericDeviceType::Hub;
  1276. }
  1277. else if (query == "Platform") {
  1278. ret = TDEGenericDeviceType::Platform;
  1279. }
  1280. else if (query == "Cryptography") {
  1281. ret = TDEGenericDeviceType::Cryptography;
  1282. }
  1283. else if (query == "CryptographicCard") {
  1284. ret = TDEGenericDeviceType::CryptographicCard;
  1285. }
  1286. else if (query == "BiometricSecurity") {
  1287. ret = TDEGenericDeviceType::BiometricSecurity;
  1288. }
  1289. else if (query == "TestAndMeasurement") {
  1290. ret = TDEGenericDeviceType::TestAndMeasurement;
  1291. }
  1292. else if (query == "Timekeeping") {
  1293. ret = TDEGenericDeviceType::Timekeeping;
  1294. }
  1295. else if (query == "Event") {
  1296. ret = TDEGenericDeviceType::Event;
  1297. }
  1298. else if (query == "Input") {
  1299. ret = TDEGenericDeviceType::Input;
  1300. }
  1301. else if (query == "PNP") {
  1302. ret = TDEGenericDeviceType::PNP;
  1303. }
  1304. else if (query == "OtherACPI") {
  1305. ret = TDEGenericDeviceType::OtherACPI;
  1306. }
  1307. else if (query == "OtherUSB") {
  1308. ret = TDEGenericDeviceType::OtherUSB;
  1309. }
  1310. else if (query == "OtherMultimedia") {
  1311. ret = TDEGenericDeviceType::OtherMultimedia;
  1312. }
  1313. else if (query == "OtherPeripheral") {
  1314. ret = TDEGenericDeviceType::OtherPeripheral;
  1315. }
  1316. else if (query == "OtherSensor") {
  1317. ret = TDEGenericDeviceType::OtherSensor;
  1318. }
  1319. else if (query == "OtherVirtual") {
  1320. ret = TDEGenericDeviceType::OtherVirtual;
  1321. }
  1322. else {
  1323. ret = TDEGenericDeviceType::Other;
  1324. }
  1325. return ret;
  1326. }
  1327. TDEDiskDeviceType::TDEDiskDeviceType readDiskDeviceSubtypeFromString(TQString query, TDEDiskDeviceType::TDEDiskDeviceType flagsIn=TDEDiskDeviceType::Null) {
  1328. TDEDiskDeviceType::TDEDiskDeviceType ret = flagsIn;
  1329. // Keep this in sync with the TDEDiskDeviceType definition in the header
  1330. if (query == "MediaDevice") {
  1331. ret = ret | TDEDiskDeviceType::MediaDevice;
  1332. }
  1333. if (query == "Floppy") {
  1334. ret = ret | TDEDiskDeviceType::Floppy;
  1335. }
  1336. if (query == "CDROM") {
  1337. ret = ret | TDEDiskDeviceType::CDROM;
  1338. }
  1339. if (query == "CDR") {
  1340. ret = ret | TDEDiskDeviceType::CDR;
  1341. }
  1342. if (query == "CDRW") {
  1343. ret = ret | TDEDiskDeviceType::CDRW;
  1344. }
  1345. if (query == "CDMO") {
  1346. ret = ret | TDEDiskDeviceType::CDMO;
  1347. }
  1348. if (query == "CDMRRW") {
  1349. ret = ret | TDEDiskDeviceType::CDMRRW;
  1350. }
  1351. if (query == "CDMRRWW") {
  1352. ret = ret | TDEDiskDeviceType::CDMRRWW;
  1353. }
  1354. if (query == "DVDROM") {
  1355. ret = ret | TDEDiskDeviceType::DVDROM;
  1356. }
  1357. if (query == "DVDRAM") {
  1358. ret = ret | TDEDiskDeviceType::DVDRAM;
  1359. }
  1360. if (query == "DVDR") {
  1361. ret = ret | TDEDiskDeviceType::DVDR;
  1362. }
  1363. if (query == "DVDRW") {
  1364. ret = ret | TDEDiskDeviceType::DVDRW;
  1365. }
  1366. if (query == "DVDRDL") {
  1367. ret = ret | TDEDiskDeviceType::DVDRDL;
  1368. }
  1369. if (query == "DVDRWDL") {
  1370. ret = ret | TDEDiskDeviceType::DVDRWDL;
  1371. }
  1372. if (query == "DVDPLUSR") {
  1373. ret = ret | TDEDiskDeviceType::DVDPLUSR;
  1374. }
  1375. if (query == "DVDPLUSRW") {
  1376. ret = ret | TDEDiskDeviceType::DVDPLUSRW;
  1377. }
  1378. if (query == "DVDPLUSRDL") {
  1379. ret = ret | TDEDiskDeviceType::DVDPLUSRDL;
  1380. }
  1381. if (query == "DVDPLUSRWDL") {
  1382. ret = ret | TDEDiskDeviceType::DVDPLUSRWDL;
  1383. }
  1384. if (query == "BDROM") {
  1385. ret = ret | TDEDiskDeviceType::BDROM;
  1386. }
  1387. if (query == "BDR") {
  1388. ret = ret | TDEDiskDeviceType::BDR;
  1389. }
  1390. if (query == "BDRW") {
  1391. ret = ret | TDEDiskDeviceType::BDRW;
  1392. }
  1393. if (query == "HDDVDROM") {
  1394. ret = ret | TDEDiskDeviceType::HDDVDROM;
  1395. }
  1396. if (query == "HDDVDR") {
  1397. ret = ret | TDEDiskDeviceType::HDDVDR;
  1398. }
  1399. if (query == "HDDVDRW") {
  1400. ret = ret | TDEDiskDeviceType::HDDVDRW;
  1401. }
  1402. if (query == "Zip") {
  1403. ret = ret | TDEDiskDeviceType::Zip;
  1404. }
  1405. if (query == "Jaz") {
  1406. ret = ret | TDEDiskDeviceType::Jaz;
  1407. }
  1408. if (query == "Camera") {
  1409. ret = ret | TDEDiskDeviceType::Camera;
  1410. }
  1411. if (query == "LUKS") {
  1412. ret = ret | TDEDiskDeviceType::LUKS;
  1413. }
  1414. if (query == "OtherCrypted") {
  1415. ret = ret | TDEDiskDeviceType::OtherCrypted;
  1416. }
  1417. if (query == "CDAudio") {
  1418. ret = ret | TDEDiskDeviceType::CDAudio;
  1419. }
  1420. if (query == "CDVideo") {
  1421. ret = ret | TDEDiskDeviceType::CDVideo;
  1422. }
  1423. if (query == "DVDVideo") {
  1424. ret = ret | TDEDiskDeviceType::DVDVideo;
  1425. }
  1426. if (query == "BDVideo") {
  1427. ret = ret | TDEDiskDeviceType::BDVideo;
  1428. }
  1429. if (query == "Flash") {
  1430. ret = ret | TDEDiskDeviceType::Flash;
  1431. }
  1432. if (query == "USB") {
  1433. ret = ret | TDEDiskDeviceType::USB;
  1434. }
  1435. if (query == "Tape") {
  1436. ret = ret | TDEDiskDeviceType::Tape;
  1437. }
  1438. if (query == "HDD") {
  1439. ret = ret | TDEDiskDeviceType::HDD;
  1440. }
  1441. if (query == "Optical") {
  1442. ret = ret | TDEDiskDeviceType::Optical;
  1443. }
  1444. if (query == "RAM") {
  1445. ret = ret | TDEDiskDeviceType::RAM;
  1446. }
  1447. if (query == "Loop") {
  1448. ret = ret | TDEDiskDeviceType::Loop;
  1449. }
  1450. if (query == "CompactFlash") {
  1451. ret = ret | TDEDiskDeviceType::CompactFlash;
  1452. }
  1453. if (query == "MemoryStick") {
  1454. ret = ret | TDEDiskDeviceType::MemoryStick;
  1455. }
  1456. if (query == "SmartMedia") {
  1457. ret = ret | TDEDiskDeviceType::SmartMedia;
  1458. }
  1459. if (query == "SDMMC") {
  1460. ret = ret | TDEDiskDeviceType::SDMMC;
  1461. }
  1462. if (query == "UnlockedCrypt") {
  1463. ret = ret | TDEDiskDeviceType::UnlockedCrypt;
  1464. }
  1465. return ret;
  1466. }
  1467. TDEGenericDevice* createDeviceObjectForType(TDEGenericDeviceType::TDEGenericDeviceType type) {
  1468. TDEGenericDevice* ret = 0;
  1469. if (type == TDEGenericDeviceType::Disk) {
  1470. ret = new TDEStorageDevice(type);
  1471. }
  1472. else {
  1473. ret = new TDEGenericDevice(type);
  1474. }
  1475. return ret;
  1476. }
  1477. TDEGenericDevice* TDEHardwareDevices::classifyUnknownDeviceByExternalRules(udev_device* dev, TDEGenericDevice* existingdevice, bool classifySubDevices) {
  1478. // This routine expects to see the hardware config files into <prefix>/share/apps/tdehwlib/deviceclasses/, suffixed with "hwclass"
  1479. TDEGenericDevice* device = existingdevice;
  1480. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
  1481. // Handle subtype if needed/desired
  1482. // To speed things up we rely on the prior scan results stored in m_externalSubtype
  1483. if (classifySubDevices) {
  1484. if (!device->m_externalRulesFile.isNull()) {
  1485. if (device->type() == TDEGenericDeviceType::Disk) {
  1486. // Disk class
  1487. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
  1488. TQStringList subtype = device->m_externalSubtype;
  1489. TDEDiskDeviceType::TDEDiskDeviceType desiredSubdeviceType = TDEDiskDeviceType::Null;
  1490. if (subtype.count()>0) {
  1491. for ( TQStringList::Iterator paramit = subtype.begin(); paramit != subtype.end(); ++paramit ) {
  1492. desiredSubdeviceType = readDiskDeviceSubtypeFromString(*paramit, desiredSubdeviceType);
  1493. }
  1494. if (desiredSubdeviceType != sdevice->diskType()) {
  1495. 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);
  1496. sdevice->internalSetDiskType(desiredSubdeviceType);
  1497. }
  1498. }
  1499. }
  1500. }
  1501. }
  1502. else {
  1503. TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
  1504. TQString hardware_info_directory_suffix("tdehwlib/deviceclasses/");
  1505. TQString hardware_info_directory;
  1506. // Scan the hardware_info_directory for configuration files
  1507. // For each one, open it with TDEConfig() and apply its rules to classify the device
  1508. // FIXME
  1509. // Should this also scan up to <n> subdirectories for the files? That feature might end up being too expensive...
  1510. device->m_externalRulesFile = TQString::null;
  1511. for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
  1512. hardware_info_directory = (*it);
  1513. hardware_info_directory += hardware_info_directory_suffix;
  1514. if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
  1515. TQDir d(hardware_info_directory);
  1516. d.setFilter( TQDir::Files | TQDir::Hidden );
  1517. const TQFileInfoList *list = d.entryInfoList();
  1518. TQFileInfoListIterator it( *list );
  1519. TQFileInfo *fi;
  1520. while ((fi = it.current()) != 0) {
  1521. if (fi->extension(false) == "hwclass") {
  1522. bool match = true;
  1523. // Open the rules file
  1524. TDEConfig rulesFile(fi->absFilePath(), true, false);
  1525. rulesFile.setGroup("Conditions");
  1526. TDEConfigMap conditionmap = rulesFile.entryMap("Conditions");
  1527. TDEConfigMap::Iterator cndit;
  1528. for (cndit = conditionmap.begin(); cndit != conditionmap.end(); ++cndit) {
  1529. TQStringList conditionList = TQStringList::split(',', cndit.data(), false);
  1530. bool atleastonematch = false;
  1531. bool allmatch = true;
  1532. TQString matchtype = rulesFile.readEntry("MATCH_TYPE", "All");
  1533. if (conditionList.count() < 1) {
  1534. allmatch = false;
  1535. }
  1536. else {
  1537. for ( TQStringList::Iterator paramit = conditionList.begin(); paramit != conditionList.end(); ++paramit ) {
  1538. if ((*paramit) == "MatchType") {
  1539. continue;
  1540. }
  1541. if (cndit.key() == "VENDOR_ID") {
  1542. if (device->vendorID() == (*paramit)) {
  1543. atleastonematch = true;
  1544. }
  1545. else {
  1546. allmatch = false;
  1547. }
  1548. }
  1549. else if (cndit.key() == "MODEL_ID") {
  1550. if (device->modelID() == (*paramit)) {
  1551. atleastonematch = true;
  1552. }
  1553. else {
  1554. allmatch = false;
  1555. }
  1556. }
  1557. else if (cndit.key() == "DRIVER") {
  1558. if (device->deviceDriver() == (*paramit)) {
  1559. atleastonematch = true;
  1560. }
  1561. else {
  1562. allmatch = false;
  1563. }
  1564. }
  1565. else {
  1566. if (readUdevAttribute(dev, cndit.key()) == (*paramit)) {
  1567. atleastonematch = true;
  1568. }
  1569. else {
  1570. allmatch = false;
  1571. }
  1572. }
  1573. }
  1574. }
  1575. if (matchtype == "All") {
  1576. if (!allmatch) {
  1577. match = false;
  1578. }
  1579. }
  1580. else if (matchtype == "Any") {
  1581. if (!atleastonematch) {
  1582. match = false;
  1583. }
  1584. }
  1585. else {
  1586. match = false;
  1587. }
  1588. }
  1589. if (match) {
  1590. rulesFile.setGroup("DeviceType");
  1591. TQString gentype = rulesFile.readEntry("GENTYPE");
  1592. TDEGenericDeviceType::TDEGenericDeviceType desiredDeviceType = device->type();
  1593. if (!gentype.isNull()) {
  1594. desiredDeviceType = readGenericDeviceTypeFromString(gentype);
  1595. }
  1596. // Handle main type
  1597. if (desiredDeviceType != device->type()) {
  1598. printf("[tdehardwaredevices] Rules file %s used to set device type for device at path %s\n", fi->absFilePath().ascii(), device->systemPath().ascii()); fflush(stdout);
  1599. if (m_deviceList.contains(device)) {
  1600. m_deviceList.remove(device);
  1601. }
  1602. else {
  1603. delete device;
  1604. }
  1605. device = createDeviceObjectForType(desiredDeviceType);
  1606. }
  1607. // Parse subtype and store in m_externalSubtype for later
  1608. // This speeds things up considerably due to the expense of the file scanning/parsing/matching operation
  1609. device->m_externalSubtype = rulesFile.readListEntry("SUBTYPE", ',');
  1610. device->m_externalRulesFile = fi->absFilePath();
  1611. // Process blacklist entries
  1612. rulesFile.setGroup("DeviceSettings");
  1613. device->internalSetBlacklistedForUpdate(rulesFile.readBoolEntry("UPDATE_BLACKLISTED", device->blacklistedForUpdate()));
  1614. }
  1615. }
  1616. ++it;
  1617. }
  1618. }
  1619. }
  1620. }
  1621. return device;
  1622. }
  1623. TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice, bool force_full_classification) {
  1624. // Classify device and create TDEHW device object
  1625. TQString devicename;
  1626. TQString devicetype;
  1627. TQString devicedriver;
  1628. TQString devicesubsystem;
  1629. TQString devicenode;
  1630. TQString systempath;
  1631. TQString devicevendorid;
  1632. TQString devicemodelid;
  1633. TQString devicevendoridenc;
  1634. TQString devicemodelidenc;
  1635. TQString devicesubvendorid;
  1636. TQString devicesubmodelid;
  1637. TQString devicetypestring;
  1638. TQString devicetypestring_alt;
  1639. TQString devicepciclass;
  1640. TDEGenericDevice* device = existingdevice;
  1641. bool temp_udev_device = !dev;
  1642. if (dev) {
  1643. devicename = (udev_device_get_sysname(dev));
  1644. devicetype = (udev_device_get_devtype(dev));
  1645. devicedriver = (udev_device_get_driver(dev));
  1646. devicesubsystem = (udev_device_get_subsystem(dev));
  1647. devicenode = (udev_device_get_devnode(dev));
  1648. systempath = (udev_device_get_syspath(dev));
  1649. systempath += "/";
  1650. devicevendorid = (udev_device_get_property_value(dev, "ID_VENDOR_ID"));
  1651. devicemodelid = (udev_device_get_property_value(dev, "ID_MODEL_ID"));
  1652. devicevendoridenc = (udev_device_get_property_value(dev, "ID_VENDOR_ENC"));
  1653. devicemodelidenc = (udev_device_get_property_value(dev, "ID_MODEL_ENC"));
  1654. devicesubvendorid = (udev_device_get_property_value(dev, "ID_SUBVENDOR_ID"));
  1655. devicesubmodelid = (udev_device_get_property_value(dev, "ID_SUBMODEL_ID"));
  1656. devicetypestring = (udev_device_get_property_value(dev, "ID_TYPE"));
  1657. devicetypestring_alt = (udev_device_get_property_value(dev, "DEVTYPE"));
  1658. devicepciclass = (udev_device_get_property_value(dev, "PCI_CLASS"));
  1659. }
  1660. else {
  1661. if (device) {
  1662. devicename = device->name();
  1663. devicetype = device->m_udevtype;
  1664. devicedriver = device->deviceDriver();
  1665. devicesubsystem = device->subsystem();
  1666. devicenode = device->deviceNode();
  1667. systempath = device->systemPath();
  1668. devicevendorid = device->vendorID();
  1669. devicemodelid = device->modelID();
  1670. devicevendoridenc = device->vendorEncoded();
  1671. devicemodelidenc = device->modelEncoded();
  1672. devicesubvendorid = device->subVendorID();
  1673. devicesubmodelid = device->subModelID();
  1674. devicetypestring = device->m_udevdevicetypestring;
  1675. devicetypestring_alt = device->udevdevicetypestring_alt;
  1676. devicepciclass = device->PCIClass();
  1677. }
  1678. TQString syspathudev = systempath;
  1679. syspathudev.truncate(syspathudev.length()-1); // Remove trailing slash
  1680. dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
  1681. }
  1682. // FIXME
  1683. // Only a small subset of devices are classified right now
  1684. // Figure out the remaining udev logic to classify the rest!
  1685. // Helpful file: http://www.enlightenment.org/svn/e/trunk/PROTO/enna-explorer/src/bin/udev.c
  1686. bool done = false;
  1687. TQString current_path = systempath;
  1688. TQString devicemodalias = TQString::null;
  1689. while (done == false) {
  1690. TQString malnodename = current_path;
  1691. malnodename.append("/modalias");
  1692. TQFile malfile(malnodename);
  1693. if (malfile.open(IO_ReadOnly)) {
  1694. TQTextStream stream( &malfile );
  1695. devicemodalias = stream.readLine();
  1696. malfile.close();
  1697. }
  1698. if (devicemodalias.startsWith("pci") || devicemodalias.startsWith("usb")) {
  1699. done = true;
  1700. }
  1701. else {
  1702. devicemodalias = TQString::null;
  1703. current_path.truncate(current_path.findRev("/"));
  1704. if (!current_path.startsWith("/sys/devices")) {
  1705. // Abort!
  1706. done = true;
  1707. }
  1708. }
  1709. }
  1710. // Many devices do not provide their vendor/model ID via udev
  1711. // Worse, sometimes udev provides an invalid model ID!
  1712. // Go after it manually if needed...
  1713. if (devicevendorid.isNull() || devicemodelid.isNull() || devicemodelid.contains("/")) {
  1714. if (devicemodalias != TQString::null) {
  1715. // For added fun the device string lengths differ between pci and usb
  1716. if (devicemodalias.startsWith("pci")) {
  1717. int vloc = devicemodalias.find("v");
  1718. int dloc = devicemodalias.find("d", vloc);
  1719. int svloc = devicemodalias.find("sv");
  1720. int sdloc = devicemodalias.find("sd", vloc);
  1721. devicevendorid = devicemodalias.mid(vloc+1, 8).lower();
  1722. devicemodelid = devicemodalias.mid(dloc+1, 8).lower();
  1723. if (svloc != -1) {
  1724. devicesubvendorid = devicemodalias.mid(svloc+1, 8).lower();
  1725. devicesubmodelid = devicemodalias.mid(sdloc+1, 8).lower();
  1726. }
  1727. devicevendorid.remove(0,4);
  1728. devicemodelid.remove(0,4);
  1729. devicesubvendorid.remove(0,4);
  1730. devicesubmodelid.remove(0,4);
  1731. }
  1732. if (devicemodalias.startsWith("usb")) {
  1733. int vloc = devicemodalias.find("v");
  1734. int dloc = devicemodalias.find("p", vloc);
  1735. int svloc = devicemodalias.find("sv");
  1736. int sdloc = devicemodalias.find("sp", vloc);
  1737. devicevendorid = devicemodalias.mid(vloc+1, 4).lower();
  1738. devicemodelid = devicemodalias.mid(dloc+1, 4).lower();
  1739. if (svloc != -1) {
  1740. devicesubvendorid = devicemodalias.mid(svloc+1, 4).lower();
  1741. devicesubmodelid = devicemodalias.mid(sdloc+1, 4).lower();
  1742. }
  1743. }
  1744. }
  1745. }
  1746. // Most of the time udev doesn't barf up a device driver either, so go after it manually...
  1747. if (devicedriver.isNull()) {
  1748. TQString driverSymlink = udev_device_get_syspath(dev);
  1749. TQString driverSymlinkDir = driverSymlink;
  1750. driverSymlink.append("/device/driver");
  1751. driverSymlinkDir.append("/device/");
  1752. TQFileInfo dirfi(driverSymlink);
  1753. if (dirfi.isSymLink()) {
  1754. char* collapsedPath = realpath((driverSymlinkDir + dirfi.readLink()).ascii(), NULL);
  1755. devicedriver = TQString(collapsedPath);
  1756. free(collapsedPath);
  1757. devicedriver.remove(0, devicedriver.findRev("/")+1);
  1758. }
  1759. }
  1760. // udev removes critical leading zeroes in the PCI device class, so go after it manually...
  1761. TQString classnodename = systempath;
  1762. classnodename.append("/class");
  1763. TQFile classfile( classnodename );
  1764. if ( classfile.open( IO_ReadOnly ) ) {
  1765. TQTextStream stream( &classfile );
  1766. devicepciclass = stream.readLine();
  1767. devicepciclass.replace("0x", "");
  1768. devicepciclass = devicepciclass.lower();
  1769. classfile.close();
  1770. }
  1771. // Classify generic device type and create appropriate object
  1772. // Pull out all event special devices and stuff them under Event
  1773. TQString syspath_tail = systempath.lower();
  1774. syspath_tail.truncate(syspath_tail.length()-1);
  1775. syspath_tail.remove(0, syspath_tail.findRev("/")+1);
  1776. if (syspath_tail.startsWith("event")) {
  1777. if (!device) device = new TDEEventDevice(TDEGenericDeviceType::Event);
  1778. }
  1779. // Pull out all input special devices and stuff them under Input
  1780. if (syspath_tail.startsWith("input")) {
  1781. if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
  1782. }
  1783. // Pull out remote-control devices and stuff them under Input
  1784. if (devicesubsystem == "rc") {
  1785. if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
  1786. }
  1787. // Check for keyboard
  1788. // Linux doesn't actually ID the keyboard device itself as such, it instead IDs the input device that is underneath the actual keyboard itseld
  1789. // Therefore we need to scan <syspath>/input/input* for the ID_INPUT_KEYBOARD attribute
  1790. bool is_keyboard = false;
  1791. TQString inputtopdirname = udev_device_get_syspath(dev);
  1792. inputtopdirname.append("/input/");
  1793. TQDir inputdir(inputtopdirname);
  1794. inputdir.setFilter(TQDir::All);
  1795. const TQFileInfoList *dirlist = inputdir.entryInfoList();
  1796. if (dirlist) {
  1797. TQFileInfoListIterator inputdirsit(*dirlist);
  1798. TQFileInfo *dirfi;
  1799. while ( (dirfi = inputdirsit.current()) != 0 ) {
  1800. if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
  1801. struct udev_device *slavedev;
  1802. slavedev = udev_device_new_from_syspath(m_udevStruct, (inputtopdirname + dirfi->fileName()).ascii());
  1803. if (udev_device_get_property_value(slavedev, "ID_INPUT_KEYBOARD") != 0) {
  1804. is_keyboard = true;
  1805. }
  1806. udev_device_unref(slavedev);
  1807. }
  1808. ++inputdirsit;
  1809. }
  1810. }
  1811. if (is_keyboard) {
  1812. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
  1813. }
  1814. // Classify specific known devices
  1815. if (((devicetype == "disk")
  1816. || (devicetype == "partition")
  1817. || (devicedriver == "floppy")
  1818. || (devicesubsystem == "scsi_disk")
  1819. || (devicesubsystem == "scsi_tape"))
  1820. && ((devicenode != "")
  1821. )) {
  1822. if (!device) device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
  1823. }
  1824. else if (devicetype == "host") {
  1825. if (devicesubsystem == "bluetooth") {
  1826. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BlueTooth);
  1827. }
  1828. }
  1829. else if (devicetype.isNull()) {
  1830. if (devicesubsystem == "acpi") {
  1831. // If the ACPI device exposes a system path ending in /PNPxxxx:yy, the device type can be precisely determined
  1832. // See ftp://ftp.microsoft.com/developr/drg/plug-and-play/devids.txt for more information
  1833. TQString pnpgentype = systempath;
  1834. pnpgentype.remove(0, pnpgentype.findRev("/")+1);
  1835. pnpgentype.truncate(pnpgentype.find(":"));
  1836. if (pnpgentype.startsWith("PNP")) {
  1837. // 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
  1838. // Furthermore, the "real" device elsewhere almost always has more functionality exposed via sysfs
  1839. // Therefore all ACPI subsystem devices should be stuffed in the OtherACPI category and largely ignored
  1840. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
  1841. }
  1842. else {
  1843. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
  1844. }
  1845. }
  1846. else if (devicesubsystem == "input") {
  1847. // Figure out if this device is a mouse, keyboard, or something else
  1848. // Check for mouse
  1849. // udev doesn't reliably help here, so guess from the device name
  1850. if (systempath.contains("/mouse")) {
  1851. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
  1852. }
  1853. if (!device) {
  1854. // Second mouse check
  1855. // Look for ID_INPUT_MOUSE property presence
  1856. if (udev_device_get_property_value(dev, "ID_INPUT_MOUSE") != 0) {
  1857. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
  1858. }
  1859. }
  1860. if (!device) {
  1861. // Check for keyboard
  1862. // Look for ID_INPUT_KEYBOARD property presence
  1863. if (udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD") != 0) {
  1864. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
  1865. }
  1866. }
  1867. if (!device) {
  1868. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
  1869. }
  1870. }
  1871. else if (devicesubsystem == "tty") {
  1872. if (devicenode.contains("/ttyS")) {
  1873. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
  1874. }
  1875. else {
  1876. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TextIO);
  1877. }
  1878. }
  1879. else if (devicesubsystem == "usb-serial") {
  1880. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
  1881. }
  1882. else if ((devicesubsystem == "spi_master")
  1883. || (devicesubsystem == "spidev")) {
  1884. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
  1885. }
  1886. else if (devicesubsystem == "spi") {
  1887. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1888. }
  1889. else if (devicesubsystem == "watchdog") {
  1890. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1891. }
  1892. else if (devicesubsystem == "node") {
  1893. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1894. }
  1895. else if (devicesubsystem == "regulator") {
  1896. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1897. }
  1898. else if (devicesubsystem == "memory") {
  1899. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1900. }
  1901. else if (devicesubsystem == "clockevents") {
  1902. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1903. }
  1904. else if (devicesubsystem == "thermal") {
  1905. // FIXME
  1906. // Figure out a way to differentiate between ThermalControl (fans and coolers) and ThermalSensor types
  1907. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalControl);
  1908. }
  1909. else if (devicesubsystem == "hwmon") {
  1910. // FIXME
  1911. // This might pick up thermal sensors
  1912. if (!device) device = new TDESensorDevice(TDEGenericDeviceType::OtherSensor);
  1913. }
  1914. else if (devicesubsystem == "vio") {
  1915. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1916. }
  1917. else if (devicesubsystem == "virtio") {
  1918. if (devicedriver == "virtio_blk") {
  1919. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
  1920. }
  1921. if (devicedriver == "virtio_net") {
  1922. if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
  1923. }
  1924. if (devicedriver == "virtio_balloon") {
  1925. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
  1926. }
  1927. }
  1928. }
  1929. // Try to at least generally classify unclassified devices
  1930. if (device == 0) {
  1931. if (devicesubsystem == "backlight") {
  1932. if (!device) device = new TDEBacklightDevice(TDEGenericDeviceType::Backlight);
  1933. }
  1934. if (systempath.lower().startsWith("/sys/module/")
  1935. || (systempath.lower().startsWith("/sys/kernel/"))) {
  1936. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform); // FIXME Should go into a new kernel module category when the tdelibs ABI can be broken again
  1937. }
  1938. if ((devicetypestring == "audio")
  1939. || (devicesubsystem == "sound")
  1940. || (devicesubsystem == "hdaudio")
  1941. || (devicesubsystem == "ac97")) {
  1942. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Sound);
  1943. }
  1944. if (devicesubsystem == "container") {
  1945. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
  1946. }
  1947. if ((devicesubsystem == "video4linux")
  1948. || (devicesubsystem == "dvb")) {
  1949. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::VideoCapture);
  1950. }
  1951. if ((devicetypestring_alt == "scsi_target")
  1952. || (devicesubsystem == "scsi_host")
  1953. || (devicesubsystem == "scsi_disk")
  1954. || (devicesubsystem == "scsi_device")
  1955. || (devicesubsystem == "scsi_generic")
  1956. || (devicesubsystem == "scsi")
  1957. || (devicetypestring_alt == "sas_target")
  1958. || (devicesubsystem == "sas_host")
  1959. || (devicesubsystem == "sas_port")
  1960. || (devicesubsystem == "sas_device")
  1961. || (devicesubsystem == "sas_expander")
  1962. || (devicesubsystem == "sas_generic")
  1963. || (devicesubsystem == "sas_phy")
  1964. || (devicesubsystem == "sas_end_device")
  1965. || (devicesubsystem == "spi_transport")
  1966. || (devicesubsystem == "spi_host")
  1967. || (devicesubsystem == "ata_port")
  1968. || (devicesubsystem == "ata_link")
  1969. || (devicesubsystem == "ata_disk")
  1970. || (devicesubsystem == "ata_device")
  1971. || (devicesubsystem == "ata")) {
  1972. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1973. }
  1974. if (devicesubsystem == "infiniband") {
  1975. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Peripheral);
  1976. }
  1977. if ((devicesubsystem == "infiniband_cm")
  1978. || (devicesubsystem == "infiniband_mad")
  1979. || (devicesubsystem == "infiniband_verbs")) {
  1980. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1981. }
  1982. if (devicesubsystem == "infiniband_srp") {
  1983. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
  1984. }
  1985. if ((devicesubsystem == "enclosure")
  1986. || (devicesubsystem == "clocksource")
  1987. || (devicesubsystem == "amba")) {
  1988. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  1989. }
  1990. if (devicesubsystem == "edac") {
  1991. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
  1992. }
  1993. if (devicesubsystem.startsWith("mc") && systempath.contains("/edac/")) {
  1994. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
  1995. }
  1996. if ((devicesubsystem == "ipmi")
  1997. || (devicesubsystem == "ipmi_si")) {
  1998. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
  1999. }
  2000. if (devicesubsystem == "iommu") {
  2001. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2002. }
  2003. if (devicesubsystem == "misc") {
  2004. if (devicedriver.startsWith("tpm_")) {
  2005. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Cryptography);
  2006. }
  2007. else {
  2008. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2009. }
  2010. }
  2011. if (devicesubsystem == "media") {
  2012. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2013. }
  2014. if (devicesubsystem == "nd") {
  2015. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
  2016. }
  2017. if (devicesubsystem == "ptp") {
  2018. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Timekeeping);
  2019. }
  2020. if (devicesubsystem == "leds") {
  2021. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI);
  2022. }
  2023. if (devicesubsystem == "net") {
  2024. if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
  2025. }
  2026. if ((devicesubsystem == "i2c")
  2027. || (devicesubsystem == "i2c-dev")) {
  2028. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::I2C);
  2029. }
  2030. if (devicesubsystem == "mdio_bus") {
  2031. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::MDIO);
  2032. }
  2033. if (devicesubsystem == "graphics") {
  2034. if (devicenode.isNull()) { // GPUs do not have associated device nodes
  2035. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
  2036. }
  2037. else {
  2038. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2039. }
  2040. }
  2041. if (devicesubsystem == "tifm_adapter") {
  2042. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
  2043. }
  2044. if ((devicesubsystem == "mmc_host")
  2045. || (devicesubsystem == "memstick_host")) {
  2046. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
  2047. }
  2048. if (devicesubsystem == "mmc") {
  2049. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2050. }
  2051. if ((devicesubsystem == "event_source")
  2052. || (devicesubsystem == "rtc")) {
  2053. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mainboard);
  2054. }
  2055. if (devicesubsystem == "bsg") {
  2056. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::SCSI);
  2057. }
  2058. if (devicesubsystem == "firewire") {
  2059. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::IEEE1394);
  2060. }
  2061. if (devicesubsystem == "drm") {
  2062. if (devicenode.isNull()) { // Monitors do not have associated device nodes
  2063. if (!device) device = new TDEMonitorDevice(TDEGenericDeviceType::Monitor);
  2064. }
  2065. else {
  2066. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2067. }
  2068. }
  2069. if (devicesubsystem == "nvmem") {
  2070. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::NonvolatileMemory);
  2071. }
  2072. if (devicesubsystem == "serio") {
  2073. if (devicedriver.contains("atkbd")) {
  2074. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard);
  2075. }
  2076. else if (devicedriver.contains("mouse")) {
  2077. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Mouse);
  2078. }
  2079. else {
  2080. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
  2081. }
  2082. }
  2083. if ((devicesubsystem == "ppdev")
  2084. || (devicesubsystem == "parport")) {
  2085. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Parallel);
  2086. }
  2087. if (devicesubsystem == "printer") {
  2088. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Printer);
  2089. }
  2090. if (devicesubsystem == "bridge") {
  2091. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
  2092. }
  2093. if ((devicesubsystem == "pci_bus")
  2094. || (devicesubsystem == "pci_express")) {
  2095. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bus);
  2096. }
  2097. if (devicesubsystem == "pcmcia_socket") {
  2098. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PCMCIA);
  2099. }
  2100. if (devicesubsystem == "platform") {
  2101. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2102. }
  2103. if (devicesubsystem == "ieee80211") {
  2104. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2105. }
  2106. if (devicesubsystem == "rfkill") {
  2107. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2108. }
  2109. if (devicesubsystem == "machinecheck") {
  2110. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2111. }
  2112. if (devicesubsystem == "pnp") {
  2113. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PNP);
  2114. }
  2115. if ((devicesubsystem == "hid")
  2116. || (devicesubsystem == "hidraw")
  2117. || (devicesubsystem == "usbhid")) {
  2118. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID);
  2119. }
  2120. if (devicesubsystem == "power_supply") {
  2121. TQString powersupplyname(udev_device_get_property_value(dev, "POWER_SUPPLY_NAME"));
  2122. if ((devicedriver == "ac")
  2123. || (powersupplyname.upper().startsWith("AC"))) {
  2124. if (!device) device = new TDEMainsPowerDevice(TDEGenericDeviceType::PowerSupply);
  2125. }
  2126. else {
  2127. if (!device) device = new TDEBatteryDevice(TDEGenericDeviceType::Battery);
  2128. }
  2129. }
  2130. if (systempath.lower().startsWith("/sys/devices/virtual")) {
  2131. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherVirtual);
  2132. }
  2133. // Moderate accuracy classification, if PCI device class is available
  2134. // See http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html for codes and meanings
  2135. if (!devicepciclass.isNull()) {
  2136. // Pre PCI 2.0
  2137. if (devicepciclass.startsWith("0001")) {
  2138. if (devicenode.isNull()) { // GPUs do not have associated device nodes
  2139. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
  2140. }
  2141. else {
  2142. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2143. }
  2144. }
  2145. // Post PCI 2.0
  2146. TQString devicepcisubclass = devicepciclass;
  2147. devicepcisubclass = devicepcisubclass.remove(0,2);
  2148. if (devicepciclass.startsWith("01")) {
  2149. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::StorageController);
  2150. }
  2151. if (devicepciclass.startsWith("02")) {
  2152. if (!device) device = new TDENetworkDevice(TDEGenericDeviceType::Network);
  2153. }
  2154. if (devicepciclass.startsWith("03")) {
  2155. if (devicenode.isNull()) { // GPUs do not have associated device nodes
  2156. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::GPU);
  2157. }
  2158. else {
  2159. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2160. }
  2161. }
  2162. if (devicepciclass.startsWith("04")) {
  2163. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherMultimedia);
  2164. }
  2165. if (devicepciclass.startsWith("05")) {
  2166. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::RAM);
  2167. }
  2168. if (devicepciclass.startsWith("06")) {
  2169. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Bridge);
  2170. }
  2171. if (devicepciclass.startsWith("07")) {
  2172. if (devicepcisubclass.startsWith("03")) {
  2173. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Modem);
  2174. }
  2175. }
  2176. if (devicepciclass.startsWith("0a")) {
  2177. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Dock);
  2178. }
  2179. if (devicepciclass.startsWith("0b")) {
  2180. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::CPU);
  2181. }
  2182. if (devicepciclass.startsWith("0c")) {
  2183. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
  2184. }
  2185. }
  2186. if ((devicesubsystem == "usb")
  2187. && (devicedriver == "uvcvideo")) {
  2188. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2189. }
  2190. // Last ditch attempt at classification
  2191. // Likely inaccurate and sweeping
  2192. if ((devicesubsystem == "usb")
  2193. || (devicesubsystem == "usbmisc")
  2194. || (devicesubsystem == "usb_device")
  2195. || (devicesubsystem == "usbmon")) {
  2196. // Get USB interface class for further classification
  2197. int usbInterfaceClass = -1;
  2198. {
  2199. TQFile ifaceprotofile(current_path + "/bInterfaceClass");
  2200. if (ifaceprotofile.open(IO_ReadOnly)) {
  2201. TQTextStream stream( &ifaceprotofile );
  2202. usbInterfaceClass = stream.readLine().toUInt(NULL, 16);
  2203. ifaceprotofile.close();
  2204. }
  2205. }
  2206. // Get USB interface subclass for further classification
  2207. int usbInterfaceSubClass = -1;
  2208. {
  2209. TQFile ifaceprotofile(current_path + "/bInterfaceSubClass");
  2210. if (ifaceprotofile.open(IO_ReadOnly)) {
  2211. TQTextStream stream( &ifaceprotofile );
  2212. usbInterfaceSubClass = stream.readLine().toUInt(NULL, 16);
  2213. ifaceprotofile.close();
  2214. }
  2215. }
  2216. // Get USB interface protocol for further classification
  2217. int usbInterfaceProtocol = -1;
  2218. {
  2219. TQFile ifaceprotofile(current_path + "/bInterfaceProtocol");
  2220. if (ifaceprotofile.open(IO_ReadOnly)) {
  2221. TQTextStream stream( &ifaceprotofile );
  2222. usbInterfaceProtocol = stream.readLine().toUInt(NULL, 16);
  2223. ifaceprotofile.close();
  2224. }
  2225. }
  2226. if ((usbInterfaceClass == 6) && (usbInterfaceSubClass == 1) && (usbInterfaceProtocol == 1)) {
  2227. // PictBridge
  2228. if (!device) {
  2229. device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
  2230. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
  2231. sdevice->internalSetDiskType(TDEDiskDeviceType::Camera);
  2232. TQString parentsyspathudev = systempath;
  2233. parentsyspathudev.truncate(parentsyspathudev.length()-1); // Remove trailing slash
  2234. parentsyspathudev.truncate(parentsyspathudev.findRev("/"));
  2235. struct udev_device *parentdev;
  2236. parentdev = udev_device_new_from_syspath(m_udevStruct, parentsyspathudev.ascii());
  2237. devicenode = (udev_device_get_devnode(parentdev));
  2238. udev_device_unref(parentdev);
  2239. }
  2240. }
  2241. else if (usbInterfaceClass == 9) {
  2242. // Hub
  2243. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Hub);
  2244. }
  2245. else if (usbInterfaceClass == 11) {
  2246. // Smart Card Reader
  2247. if (!device) device = new TDECryptographicCardDevice(TDEGenericDeviceType::CryptographicCard);
  2248. }
  2249. else if (usbInterfaceClass == 14) {
  2250. // Fingerprint Reader
  2251. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BiometricSecurity);
  2252. }
  2253. else if (usbInterfaceClass == 254) {
  2254. // Test and/or Measurement Device
  2255. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TestAndMeasurement);
  2256. }
  2257. else {
  2258. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherUSB);
  2259. }
  2260. }
  2261. if (devicesubsystem == "pci") {
  2262. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherPeripheral);
  2263. }
  2264. if (devicesubsystem == "cpu") {
  2265. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform);
  2266. }
  2267. }
  2268. if (device == 0) {
  2269. // Unhandled
  2270. if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Other);
  2271. 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);
  2272. }
  2273. // Root devices are special
  2274. if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
  2275. systempath = device->systemPath();
  2276. }
  2277. // Set preliminary basic device information
  2278. device->internalSetName(devicename);
  2279. device->internalSetDeviceNode(devicenode);
  2280. device->internalSetSystemPath(systempath);
  2281. device->internalSetVendorID(devicevendorid);
  2282. device->internalSetModelID(devicemodelid);
  2283. device->internalSetVendorEncoded(devicevendoridenc);
  2284. device->internalSetModelEncoded(devicemodelidenc);
  2285. device->internalSetSubVendorID(devicesubvendorid);
  2286. device->internalSetSubModelID(devicesubmodelid);
  2287. device->internalSetModuleAlias(devicemodalias);
  2288. device->internalSetDeviceDriver(devicedriver);
  2289. device->internalSetSubsystem(devicesubsystem);
  2290. device->internalSetPCIClass(devicepciclass);
  2291. updateBlacklists(device, dev);
  2292. if (force_full_classification) {
  2293. // Check external rules for possible device type overrides
  2294. device = classifyUnknownDeviceByExternalRules(dev, device, false);
  2295. }
  2296. // Internal use only!
  2297. device->m_udevtype = devicetype;
  2298. device->m_udevdevicetypestring = devicetypestring;
  2299. device->udevdevicetypestring_alt = devicetypestring_alt;
  2300. updateExistingDeviceInformation(device, dev);
  2301. if (temp_udev_device) {
  2302. udev_device_unref(dev);
  2303. }
  2304. return device;
  2305. }
  2306. void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* existingdevice, udev_device* dev) {
  2307. TQString devicename;
  2308. TQString devicetype;
  2309. TQString devicedriver;
  2310. TQString devicesubsystem;
  2311. TQString devicenode;
  2312. TQString systempath;
  2313. TQString devicevendorid;
  2314. TQString devicemodelid;
  2315. TQString devicevendoridenc;
  2316. TQString devicemodelidenc;
  2317. TQString devicesubvendorid;
  2318. TQString devicesubmodelid;
  2319. TQString devicetypestring;
  2320. TQString devicetypestring_alt;
  2321. TQString devicepciclass;
  2322. TDEGenericDevice* device = existingdevice;
  2323. bool temp_udev_device = !dev;
  2324. devicename = device->name();
  2325. devicetype = device->m_udevtype;
  2326. devicedriver = device->deviceDriver();
  2327. devicesubsystem = device->subsystem();
  2328. devicenode = device->deviceNode();
  2329. systempath = device->systemPath();
  2330. devicevendorid = device->vendorID();
  2331. devicemodelid = device->modelID();
  2332. devicevendoridenc = device->vendorEncoded();
  2333. devicemodelidenc = device->modelEncoded();
  2334. devicesubvendorid = device->subVendorID();
  2335. devicesubmodelid = device->subModelID();
  2336. devicetypestring = device->m_udevdevicetypestring;
  2337. devicetypestring_alt = device->udevdevicetypestring_alt;
  2338. devicepciclass = device->PCIClass();
  2339. if (!dev) {
  2340. TQString syspathudev = systempath;
  2341. syspathudev.truncate(syspathudev.length()-1); // Remove trailing slash
  2342. dev = udev_device_new_from_syspath(m_udevStruct, syspathudev.ascii());
  2343. }
  2344. if (device->type() == TDEGenericDeviceType::Disk) {
  2345. TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
  2346. if (sdevice->diskType() & TDEDiskDeviceType::Camera) {
  2347. // PictBridge cameras are special and should not be classified by standard rules
  2348. sdevice->internalSetDiskStatus(TDEDiskDeviceStatus::Removable);
  2349. sdevice->internalSetFileSystemName("pictbridge");
  2350. }
  2351. else {
  2352. bool removable = false;
  2353. bool hotpluggable = false;
  2354. // We can get the removable flag, but we have no idea if the device has the ability to notify on media insertion/removal
  2355. // If there is no such notification possible, then we should not set the removable flag
  2356. // udev can be such an amazing pain at times
  2357. // It exports a /capabilities node with no info on what the bits actually mean
  2358. // This information is very poorly documented as a set of #defines in include/linux/genhd.h
  2359. // We are specifically interested in GENHD_FL_REMOVABLE and GENHD_FL_MEDIA_CHANGE_NOTIFY
  2360. // The "removable" flag should also really be renamed to "hotpluggable", as that is far more precise...
  2361. TQString capabilitynodename = systempath;
  2362. capabilitynodename.append("/capability");
  2363. TQFile capabilityfile( capabilitynodename );
  2364. unsigned int capabilities = 0;
  2365. if ( capabilityfile.open( IO_ReadOnly ) ) {
  2366. TQTextStream stream( &capabilityfile );
  2367. TQString capabilitystring;
  2368. capabilitystring = stream.readLine();
  2369. capabilities = capabilitystring.toUInt();
  2370. capabilityfile.close();
  2371. }
  2372. if (capabilities & GENHD_FL_REMOVABLE) {
  2373. // FIXME
  2374. // For added fun this is not always true; i.e. GENHD_FL_REMOVABLE can be set when the device cannot be hotplugged (floppy drives).
  2375. hotpluggable = true;
  2376. }
  2377. if (capabilities & GENHD_FL_MEDIA_CHANGE_NOTIFY) {
  2378. removable = true;
  2379. }
  2380. // See if any other devices are exclusively using this device, such as the Device Mapper
  2381. TQStringList holdingDeviceNodes;
  2382. TQString holdersnodename = udev_device_get_syspath(dev);
  2383. holdersnodename.append("/holders/");
  2384. TQDir holdersdir(holdersnodename);
  2385. holdersdir.setFilter(TQDir::All);
  2386. const TQFileInfoList *dirlist = holdersdir.entryInfoList();
  2387. if (dirlist) {
  2388. TQFileInfoListIterator holdersdirit(*dirlist);
  2389. TQFileInfo *dirfi;
  2390. while ( (dirfi = holdersdirit.current()) != 0 ) {
  2391. if (dirfi->isSymLink()) {
  2392. char* collapsedPath = realpath((holdersnodename + dirfi->readLink()).ascii(), NULL);
  2393. holdingDeviceNodes.append(TQString(collapsedPath));
  2394. free(collapsedPath);
  2395. }
  2396. ++holdersdirit;
  2397. }
  2398. }
  2399. // See if any other physical devices underlie this device, for example when the Device Mapper is in use
  2400. TQStringList slaveDeviceNodes;
  2401. TQString slavesnodename = udev_device_get_syspath(dev);
  2402. slavesnodename.append("/slaves/");
  2403. TQDir slavedir(slavesnodename);
  2404. slavedir.setFilter(TQDir::All);
  2405. dirlist = slavedir.entryInfoList();
  2406. if (dirlist) {
  2407. TQFileInfoListIterator slavedirit(*dirlist);
  2408. TQFileInfo *dirfi;
  2409. while ( (dirfi = slavedirit.current()) != 0 ) {
  2410. if (dirfi->isSymLink()) {
  2411. char* collapsedPath = realpath((slavesnodename + dirfi->readLink()).ascii(), NULL);
  2412. slaveDeviceNodes.append(TQString(collapsedPath));
  2413. free(collapsedPath);
  2414. }
  2415. ++slavedirit;
  2416. }
  2417. }
  2418. // Determine generic disk information
  2419. TQString devicevendor(udev_device_get_property_value(dev, "ID_VENDOR"));
  2420. TQString devicemodel(udev_device_get_property_value(dev, "ID_MODEL"));
  2421. TQString devicebus(udev_device_get_property_value(dev, "ID_BUS"));
  2422. // Get disk specific info
  2423. TQString disklabel(decodeHexEncoding(TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))));
  2424. if (disklabel == "") {
  2425. disklabel = TQString::fromLocal8Bit(udev_device_get_property_value(dev, "ID_FS_LABEL"));
  2426. }
  2427. TQString diskuuid(udev_device_get_property_value(dev, "ID_FS_UUID"));
  2428. TQString filesystemtype(udev_device_get_property_value(dev, "ID_FS_TYPE"));
  2429. TQString filesystemusage(udev_device_get_property_value(dev, "ID_FS_USAGE"));
  2430. device->internalSetVendorName(devicevendor);
  2431. device->internalSetVendorModel(devicemodel);
  2432. device->internalSetDeviceBus(devicebus);
  2433. TDEDiskDeviceType::TDEDiskDeviceType disktype = sdevice->diskType();
  2434. TDEDiskDeviceStatus::TDEDiskDeviceStatus diskstatus = TDEDiskDeviceStatus::Null;
  2435. TDEStorageDevice* parentdisk = NULL;
  2436. if (!(TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER")).isEmpty())) {
  2437. TQString parentsyspath = systempath;
  2438. parentsyspath.truncate(parentsyspath.length()-1); // Remove trailing slash
  2439. parentsyspath.truncate(parentsyspath.findRev("/"));
  2440. parentdisk = static_cast<TDEStorageDevice*>(findBySystemPath(parentsyspath));
  2441. }
  2442. disktype = classifyDiskType(dev, devicenode, devicebus, devicetypestring, systempath, devicevendor, devicemodel, filesystemtype, devicedriver);
  2443. if (parentdisk) {
  2444. // Set partition disk type and status based on the parent device
  2445. disktype = disktype | parentdisk->diskType();
  2446. diskstatus = diskstatus | parentdisk->diskStatus();
  2447. }
  2448. sdevice->internalSetDiskType(disktype);
  2449. device = classifyUnknownDeviceByExternalRules(dev, device, true); // Check external rules for possible subtype overrides
  2450. disktype = sdevice->diskType(); // The type can be overridden by an external rule
  2451. if (TQString(udev_device_get_property_value(dev, "UDISKS_IGNORE")) == "1") {
  2452. diskstatus = diskstatus | TDEDiskDeviceStatus::Hidden;
  2453. }
  2454. if ((disktype & TDEDiskDeviceType::CDROM)
  2455. || (disktype & TDEDiskDeviceType::CDR)
  2456. || (disktype & TDEDiskDeviceType::CDRW)
  2457. || (disktype & TDEDiskDeviceType::CDMO)
  2458. || (disktype & TDEDiskDeviceType::CDMRRW)
  2459. || (disktype & TDEDiskDeviceType::CDMRRWW)
  2460. || (disktype & TDEDiskDeviceType::DVDROM)
  2461. || (disktype & TDEDiskDeviceType::DVDRAM)
  2462. || (disktype & TDEDiskDeviceType::DVDR)
  2463. || (disktype & TDEDiskDeviceType::DVDRW)
  2464. || (disktype & TDEDiskDeviceType::DVDRDL)
  2465. || (disktype & TDEDiskDeviceType::DVDRWDL)
  2466. || (disktype & TDEDiskDeviceType::DVDPLUSR)
  2467. || (disktype & TDEDiskDeviceType::DVDPLUSRW)
  2468. || (disktype & TDEDiskDeviceType::DVDPLUSRDL)
  2469. || (disktype & TDEDiskDeviceType::DVDPLUSRWDL)
  2470. || (disktype & TDEDiskDeviceType::BDROM)
  2471. || (disktype & TDEDiskDeviceType::BDR)
  2472. || (disktype & TDEDiskDeviceType::BDRW)
  2473. || (disktype & TDEDiskDeviceType::HDDVDROM)
  2474. || (disktype & TDEDiskDeviceType::HDDVDR)
  2475. || (disktype & TDEDiskDeviceType::HDDVDRW)
  2476. || (disktype & TDEDiskDeviceType::CDAudio)
  2477. || (disktype & TDEDiskDeviceType::CDVideo)
  2478. || (disktype & TDEDiskDeviceType::DVDVideo)
  2479. || (disktype & TDEDiskDeviceType::BDVideo)
  2480. ) {
  2481. // These drives are guaranteed to be optical
  2482. disktype = disktype | TDEDiskDeviceType::Optical;
  2483. }
  2484. if (disktype & TDEDiskDeviceType::Floppy) {
  2485. // Floppy drives don't work well under udev
  2486. // I have to look for the block device name manually
  2487. TQString floppyblknodename = systempath;
  2488. floppyblknodename.append("/block");
  2489. TQDir floppyblkdir(floppyblknodename);
  2490. floppyblkdir.setFilter(TQDir::All);
  2491. const TQFileInfoList *floppyblkdirlist = floppyblkdir.entryInfoList();
  2492. if (floppyblkdirlist) {
  2493. TQFileInfoListIterator floppyblkdirit(*floppyblkdirlist);
  2494. TQFileInfo *dirfi;
  2495. while ( (dirfi = floppyblkdirit.current()) != 0 ) {
  2496. if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) {
  2497. // Does this routine work with more than one floppy drive in the system?
  2498. devicenode = TQString("/dev/").append(dirfi->fileName());
  2499. }
  2500. ++floppyblkdirit;
  2501. }
  2502. }
  2503. // Some interesting information can be gleaned from the CMOS type file
  2504. // 0 : Defaults
  2505. // 1 : 5 1/4 DD
  2506. // 2 : 5 1/4 HD
  2507. // 3 : 3 1/2 DD
  2508. // 4 : 3 1/2 HD
  2509. // 5 : 3 1/2 ED
  2510. // 6 : 3 1/2 ED
  2511. // 16 : unknown or not installed
  2512. TQString floppycmsnodename = systempath;
  2513. floppycmsnodename.append("/cmos");
  2514. TQFile floppycmsfile( floppycmsnodename );
  2515. TQString cmosstring;
  2516. if ( floppycmsfile.open( IO_ReadOnly ) ) {
  2517. TQTextStream stream( &floppycmsfile );
  2518. cmosstring = stream.readLine();
  2519. floppycmsfile.close();
  2520. }
  2521. // FIXME
  2522. // Do something with the information in cmosstring
  2523. if (devicenode.isNull()) {
  2524. // This floppy drive cannot be mounted, so ignore it
  2525. disktype = disktype & ~TDEDiskDeviceType::Floppy;
  2526. }
  2527. }
  2528. if (devicetypestring.upper() == "CD") {
  2529. if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_STATE")).upper() == "BLANK") {
  2530. diskstatus = diskstatus | TDEDiskDeviceStatus::Blank;
  2531. }
  2532. sdevice->internalSetMediaInserted((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) != ""));
  2533. }
  2534. if (disktype & TDEDiskDeviceType::Zip) {
  2535. // A Zip drive does not advertise its status via udev, but it can be guessed from the size parameter
  2536. TQString zipnodename = systempath;
  2537. zipnodename.append("/size");
  2538. TQFile namefile( zipnodename );
  2539. TQString zipsize;
  2540. if ( namefile.open( IO_ReadOnly ) ) {
  2541. TQTextStream stream( &namefile );
  2542. zipsize = stream.readLine();
  2543. namefile.close();
  2544. }
  2545. if (!zipsize.isNull()) {
  2546. sdevice->internalSetMediaInserted((zipsize.toInt() != 0));
  2547. }
  2548. }
  2549. if (removable) {
  2550. diskstatus = diskstatus | TDEDiskDeviceStatus::Removable;
  2551. }
  2552. if (hotpluggable) {
  2553. diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
  2554. }
  2555. // Force removable flag for flash disks
  2556. // udev reports disks as non-removable for card readers on PCI controllers
  2557. if (((disktype & TDEDiskDeviceType::CompactFlash)
  2558. || (disktype & TDEDiskDeviceType::MemoryStick)
  2559. || (disktype & TDEDiskDeviceType::SmartMedia)
  2560. || (disktype & TDEDiskDeviceType::SDMMC))
  2561. && !(diskstatus & TDEDiskDeviceStatus::Removable)
  2562. && !(diskstatus & TDEDiskDeviceStatus::Hotpluggable)) {
  2563. diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable;
  2564. }
  2565. if ((filesystemtype.upper() != "CRYPTO_LUKS") && (filesystemtype.upper() != "CRYPTO") && (filesystemtype.upper() != "SWAP") && (!filesystemtype.isEmpty())) {
  2566. diskstatus = diskstatus | TDEDiskDeviceStatus::ContainsFilesystem;
  2567. }
  2568. else {
  2569. diskstatus = diskstatus & ~TDEDiskDeviceStatus::ContainsFilesystem;
  2570. }
  2571. // Set mountable flag if device is likely to be mountable
  2572. diskstatus = diskstatus | TDEDiskDeviceStatus::Mountable;
  2573. if ((devicetypestring.upper().isNull()) && (disktype & TDEDiskDeviceType::HDD)) {
  2574. diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
  2575. }
  2576. if (removable) {
  2577. if (sdevice->mediaInserted()) {
  2578. diskstatus = diskstatus | TDEDiskDeviceStatus::Inserted;
  2579. }
  2580. else {
  2581. diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
  2582. }
  2583. }
  2584. // Swap partitions cannot be mounted
  2585. if (filesystemtype.upper() == "SWAP") {
  2586. diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
  2587. }
  2588. // Partition tables cannot be mounted
  2589. if ((TQString(udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE")) != "")
  2590. && ((TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")).isEmpty())
  2591. || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0x5")
  2592. || (TQString(udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")) == "0xf")
  2593. || (TQString(udev_device_get_property_value(dev, "ID_FS_USAGE")).upper() == "RAID"))) {
  2594. diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
  2595. }
  2596. // If certain disk types do not report the presence of a filesystem, they are likely not mountable
  2597. if ((disktype & TDEDiskDeviceType::HDD) || (disktype & TDEDiskDeviceType::Optical)) {
  2598. if (!(diskstatus & TDEDiskDeviceStatus::ContainsFilesystem)) {
  2599. diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable;
  2600. }
  2601. }
  2602. if (holdingDeviceNodes.count() > 0) {
  2603. diskstatus = diskstatus | TDEDiskDeviceStatus::UsedByDevice;
  2604. }
  2605. if (slaveDeviceNodes.count() > 0) {
  2606. diskstatus = diskstatus | TDEDiskDeviceStatus::UsesDevice;
  2607. }
  2608. // See if any slaves were crypted
  2609. for ( TQStringList::Iterator slaveit = slaveDeviceNodes.begin(); slaveit != slaveDeviceNodes.end(); ++slaveit ) {
  2610. struct udev_device *slavedev;
  2611. slavedev = udev_device_new_from_syspath(m_udevStruct, (*slaveit).ascii());
  2612. TQString slavediskfstype(udev_device_get_property_value(slavedev, "ID_FS_TYPE"));
  2613. if ((slavediskfstype.upper() == "CRYPTO_LUKS") || (slavediskfstype.upper() == "CRYPTO")) {
  2614. disktype = disktype | TDEDiskDeviceType::UnlockedCrypt;
  2615. // Set disk type based on parent device
  2616. 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)));
  2617. }
  2618. udev_device_unref(slavedev);
  2619. }
  2620. sdevice->internalSetDiskType(disktype);
  2621. sdevice->internalSetDiskUUID(diskuuid);
  2622. sdevice->internalSetDiskStatus(diskstatus);
  2623. sdevice->internalSetFileSystemName(filesystemtype);
  2624. sdevice->internalSetFileSystemUsage(filesystemusage);
  2625. sdevice->internalSetSlaveDevices(slaveDeviceNodes);
  2626. sdevice->internalSetHoldingDevices(holdingDeviceNodes);
  2627. // Clean up disk label
  2628. if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
  2629. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDR))
  2630. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
  2631. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMO))
  2632. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRW))
  2633. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRWW))
  2634. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
  2635. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
  2636. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDR))
  2637. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
  2638. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRDL))
  2639. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRWDL))
  2640. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSR))
  2641. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRW))
  2642. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRDL))
  2643. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRWDL))
  2644. || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
  2645. || (sdevice->isDiskOfType(TDEDiskDeviceType::BDR))
  2646. || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
  2647. || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDROM))
  2648. || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDR))
  2649. || (sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDRW))
  2650. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
  2651. || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
  2652. || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
  2653. || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
  2654. ) {
  2655. if (disklabel == "" && sdevice->diskLabel().isNull()) {
  2656. // Read the volume label in via volname, since udev couldn't be bothered to do this on its own
  2657. FILE *exepipe = popen(((TQString("volname %1").arg(devicenode).ascii())), "r");
  2658. if (exepipe) {
  2659. char buffer[8092];
  2660. disklabel = fgets(buffer, sizeof(buffer), exepipe);
  2661. pclose(exepipe);
  2662. }
  2663. }
  2664. }
  2665. sdevice->internalSetDiskLabel(disklabel);
  2666. }
  2667. }
  2668. if (device->type() == TDEGenericDeviceType::Network) {
  2669. // Network devices don't have devices nodes per se, but we can at least return the Linux network name...
  2670. TQString potentialdevicenode = systempath;
  2671. if (potentialdevicenode.endsWith("/")) potentialdevicenode.truncate(potentialdevicenode.length()-1);
  2672. potentialdevicenode.remove(0, potentialdevicenode.findRev("/")+1);
  2673. TQString potentialparentnode = systempath;
  2674. if (potentialparentnode.endsWith("/")) potentialparentnode.truncate(potentialparentnode.length()-1);
  2675. potentialparentnode.remove(0, potentialparentnode.findRev("/", potentialparentnode.findRev("/")-1)+1);
  2676. if (potentialparentnode.startsWith("net/")) {
  2677. devicenode = potentialdevicenode;
  2678. }
  2679. if (devicenode.isNull()) {
  2680. // Platform device, not a physical device
  2681. // HACK
  2682. // This only works because devices of type Platform only access the TDEGenericDevice class!
  2683. device->m_deviceType = TDEGenericDeviceType::Platform;
  2684. }
  2685. else {
  2686. // Gather network device information
  2687. TDENetworkDevice* ndevice = dynamic_cast<TDENetworkDevice*>(device);
  2688. TQString valuesnodename = systempath + "/";
  2689. TQDir valuesdir(valuesnodename);
  2690. valuesdir.setFilter(TQDir::All);
  2691. TQString nodename;
  2692. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  2693. if (dirlist) {
  2694. TQFileInfoListIterator valuesdirit(*dirlist);
  2695. TQFileInfo *dirfi;
  2696. while ( (dirfi = valuesdirit.current()) != 0 ) {
  2697. nodename = dirfi->fileName();
  2698. TQFile file( valuesnodename + nodename );
  2699. if ( file.open( IO_ReadOnly ) ) {
  2700. TQTextStream stream( &file );
  2701. TQString line;
  2702. line = stream.readLine();
  2703. if (nodename == "address") {
  2704. ndevice->internalSetMacAddress(line);
  2705. }
  2706. else if (nodename == "carrier") {
  2707. ndevice->internalSetCarrierPresent(line.toInt());
  2708. }
  2709. else if (nodename == "dormant") {
  2710. ndevice->internalSetDormant(line.toInt());
  2711. }
  2712. else if (nodename == "operstate") {
  2713. TQString friendlyState = line.lower();
  2714. friendlyState[0] = friendlyState[0].upper();
  2715. ndevice->internalSetState(friendlyState);
  2716. }
  2717. file.close();
  2718. }
  2719. ++valuesdirit;
  2720. }
  2721. }
  2722. // Gather connection information such as IP addresses
  2723. if ((ndevice->state().upper() == "UP")
  2724. || (ndevice->state().upper() == "UNKNOWN")) {
  2725. struct ifaddrs *ifaddr, *ifa;
  2726. int family, s;
  2727. char host[NI_MAXHOST];
  2728. if (getifaddrs(&ifaddr) != -1) {
  2729. for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
  2730. if (ifa->ifa_addr == NULL) {
  2731. continue;
  2732. }
  2733. family = ifa->ifa_addr->sa_family;
  2734. if (TQString(ifa->ifa_name) == devicenode) {
  2735. if ((family == AF_INET) || (family == AF_INET6)) {
  2736. s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
  2737. if (s == 0) {
  2738. TQString address(host);
  2739. if (family == AF_INET) {
  2740. ndevice->internalSetIpV4Address(address);
  2741. }
  2742. else if (family == AF_INET6) {
  2743. address.truncate(address.findRev("%"));
  2744. ndevice->internalSetIpV6Address(address);
  2745. }
  2746. }
  2747. s = getnameinfo(ifa->ifa_netmask, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
  2748. if (s == 0) {
  2749. TQString address(host);
  2750. if (family == AF_INET) {
  2751. ndevice->internalSetIpV4Netmask(address);
  2752. }
  2753. else if (family == AF_INET6) {
  2754. address.truncate(address.findRev("%"));
  2755. ndevice->internalSetIpV6Netmask(address);
  2756. }
  2757. }
  2758. 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);
  2759. if (s == 0) {
  2760. TQString address(host);
  2761. if (family == AF_INET) {
  2762. ndevice->internalSetIpV4Broadcast(address);
  2763. }
  2764. else if (family == AF_INET6) {
  2765. address.truncate(address.findRev("%"));
  2766. ndevice->internalSetIpV6Broadcast(address);
  2767. }
  2768. }
  2769. 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);
  2770. if (s == 0) {
  2771. TQString address(host);
  2772. if (family == AF_INET) {
  2773. ndevice->internalSetIpV4Destination(address);
  2774. }
  2775. else if (family == AF_INET6) {
  2776. address.truncate(address.findRev("%"));
  2777. ndevice->internalSetIpV6Destination(address);
  2778. }
  2779. }
  2780. }
  2781. }
  2782. }
  2783. }
  2784. freeifaddrs(ifaddr);
  2785. // Gather statistics
  2786. TQString valuesnodename = systempath + "/statistics/";
  2787. TQDir valuesdir(valuesnodename);
  2788. valuesdir.setFilter(TQDir::All);
  2789. TQString nodename;
  2790. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  2791. if (dirlist) {
  2792. TQFileInfoListIterator valuesdirit(*dirlist);
  2793. TQFileInfo *dirfi;
  2794. while ( (dirfi = valuesdirit.current()) != 0 ) {
  2795. nodename = dirfi->fileName();
  2796. TQFile file( valuesnodename + nodename );
  2797. if ( file.open( IO_ReadOnly ) ) {
  2798. TQTextStream stream( &file );
  2799. TQString line;
  2800. line = stream.readLine();
  2801. if (nodename == "rx_bytes") {
  2802. ndevice->internalSetRxBytes(line.toDouble());
  2803. }
  2804. else if (nodename == "tx_bytes") {
  2805. ndevice->internalSetTxBytes(line.toDouble());
  2806. }
  2807. else if (nodename == "rx_packets") {
  2808. ndevice->internalSetRxPackets(line.toDouble());
  2809. }
  2810. else if (nodename == "tx_packets") {
  2811. ndevice->internalSetTxPackets(line.toDouble());
  2812. }
  2813. file.close();
  2814. }
  2815. ++valuesdirit;
  2816. }
  2817. }
  2818. }
  2819. }
  2820. }
  2821. if ((device->type() == TDEGenericDeviceType::OtherSensor) || (device->type() == TDEGenericDeviceType::ThermalSensor)) {
  2822. // Populate all sensor values
  2823. TDESensorClusterMap sensors;
  2824. TQString valuesnodename = systempath + "/";
  2825. TQDir valuesdir(valuesnodename);
  2826. valuesdir.setFilter(TQDir::All);
  2827. TQString nodename;
  2828. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  2829. if (dirlist) {
  2830. TQFileInfoListIterator valuesdirit(*dirlist);
  2831. TQFileInfo *dirfi;
  2832. while ( (dirfi = valuesdirit.current()) != 0 ) {
  2833. nodename = dirfi->fileName();
  2834. if (nodename.contains("_")) {
  2835. TQFile file( valuesnodename + nodename );
  2836. if ( file.open( IO_ReadOnly ) ) {
  2837. TQTextStream stream( &file );
  2838. TQString line;
  2839. line = stream.readLine();
  2840. TQStringList sensornodelist = TQStringList::split("_", nodename);
  2841. TQString sensornodename = *(sensornodelist.at(0));
  2842. TQString sensornodetype = *(sensornodelist.at(1));
  2843. double lineValue = line.toDouble();
  2844. if (!sensornodename.contains("fan")) {
  2845. lineValue = lineValue / 1000.0;
  2846. }
  2847. if (sensornodetype == "label") {
  2848. sensors[sensornodename].label = line;
  2849. }
  2850. else if (sensornodetype == "input") {
  2851. sensors[sensornodename].current = lineValue;
  2852. }
  2853. else if (sensornodetype == "min") {
  2854. sensors[sensornodename].minimum = lineValue;
  2855. }
  2856. else if (sensornodetype == "max") {
  2857. sensors[sensornodename].maximum = lineValue;
  2858. }
  2859. else if (sensornodetype == "warn") {
  2860. sensors[sensornodename].warning = lineValue;
  2861. }
  2862. else if (sensornodetype == "crit") {
  2863. sensors[sensornodename].critical = lineValue;
  2864. }
  2865. file.close();
  2866. }
  2867. }
  2868. ++valuesdirit;
  2869. }
  2870. }
  2871. TDESensorDevice* sdevice = dynamic_cast<TDESensorDevice*>(device);
  2872. sdevice->internalSetValues(sensors);
  2873. }
  2874. if (device->type() == TDEGenericDeviceType::Battery) {
  2875. // Populate all battery values
  2876. TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(device);
  2877. TQString valuesnodename = systempath + "/";
  2878. TQDir valuesdir(valuesnodename);
  2879. valuesdir.setFilter(TQDir::All);
  2880. TQString nodename;
  2881. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  2882. if (dirlist) {
  2883. TQFileInfoListIterator valuesdirit(*dirlist);
  2884. TQFileInfo *dirfi;
  2885. while ( (dirfi = valuesdirit.current()) != 0 ) {
  2886. nodename = dirfi->fileName();
  2887. TQFile file( valuesnodename + nodename );
  2888. if ( file.open( IO_ReadOnly ) ) {
  2889. TQTextStream stream( &file );
  2890. TQString line;
  2891. line = stream.readLine();
  2892. if (nodename == "alarm") {
  2893. bdevice->internalSetAlarmEnergy(line.toDouble()/1000000.0);
  2894. }
  2895. else if (nodename == "charge_full" || nodename == "energy_full") {
  2896. bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0);
  2897. }
  2898. else if (nodename == "charge_full_design" || nodename == "energy_full_design") {
  2899. bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0);
  2900. }
  2901. else if (nodename == "charge_now" || nodename == "energy_now") {
  2902. bdevice->internalSetEnergy(line.toDouble()/1000000.0);
  2903. }
  2904. else if (nodename == "manufacturer") {
  2905. bdevice->internalSetVendorName(line.stripWhiteSpace());
  2906. }
  2907. else if (nodename == "model_name") {
  2908. bdevice->internalSetVendorModel(line.stripWhiteSpace());
  2909. }
  2910. else if (nodename == "power_now" || nodename == "current_now") {
  2911. bdevice->internalSetDischargeRate(line.toDouble()/1000000.0);
  2912. }
  2913. else if (nodename == "present") {
  2914. bdevice->internalSetInstalled(line.toInt());
  2915. }
  2916. else if (nodename == "serial_number") {
  2917. bdevice->internalSetSerialNumber(line.stripWhiteSpace());
  2918. }
  2919. else if (nodename == "status") {
  2920. bdevice->internalSetStatus(line);
  2921. }
  2922. else if (nodename == "technology") {
  2923. bdevice->internalSetTechnology(line);
  2924. }
  2925. else if (nodename == "voltage_min_design") {
  2926. bdevice->internalSetMinimumVoltage(line.toDouble()/1000000.0);
  2927. }
  2928. else if (nodename == "voltage_now") {
  2929. bdevice->internalSetVoltage(line.toDouble()/1000000.0);
  2930. }
  2931. file.close();
  2932. }
  2933. ++valuesdirit;
  2934. }
  2935. }
  2936. // Calculate time remaining
  2937. // Discharge/charge rate is in watt-hours
  2938. // Energy is in watt-hours
  2939. // Therefore, energy/rate = time in hours
  2940. // Convert to seconds...
  2941. if (bdevice->status() == TDEBatteryStatus::Charging) {
  2942. bdevice->internalSetTimeRemaining(((bdevice->maximumEnergy()-bdevice->energy())/bdevice->dischargeRate())*60*60);
  2943. }
  2944. else {
  2945. bdevice->internalSetTimeRemaining((bdevice->energy()/bdevice->dischargeRate())*60*60);
  2946. }
  2947. }
  2948. if (device->type() == TDEGenericDeviceType::PowerSupply) {
  2949. // Populate all power supply values
  2950. TDEMainsPowerDevice* pdevice = dynamic_cast<TDEMainsPowerDevice*>(device);
  2951. TQString valuesnodename = systempath + "/";
  2952. TQDir valuesdir(valuesnodename);
  2953. valuesdir.setFilter(TQDir::All);
  2954. TQString nodename;
  2955. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  2956. if (dirlist) {
  2957. TQFileInfoListIterator valuesdirit(*dirlist);
  2958. TQFileInfo *dirfi;
  2959. while ( (dirfi = valuesdirit.current()) != 0 ) {
  2960. nodename = dirfi->fileName();
  2961. TQFile file( valuesnodename + nodename );
  2962. if ( file.open( IO_ReadOnly ) ) {
  2963. TQTextStream stream( &file );
  2964. TQString line;
  2965. line = stream.readLine();
  2966. if (nodename == "manufacturer") {
  2967. pdevice->internalSetVendorName(line.stripWhiteSpace());
  2968. }
  2969. else if (nodename == "model_name") {
  2970. pdevice->internalSetVendorModel(line.stripWhiteSpace());
  2971. }
  2972. else if (nodename == "online") {
  2973. pdevice->internalSetOnline(line.toInt());
  2974. }
  2975. else if (nodename == "serial_number") {
  2976. pdevice->internalSetSerialNumber(line.stripWhiteSpace());
  2977. }
  2978. file.close();
  2979. }
  2980. ++valuesdirit;
  2981. }
  2982. }
  2983. }
  2984. if (device->type() == TDEGenericDeviceType::Backlight) {
  2985. // Populate all backlight values
  2986. TDEBacklightDevice* bdevice = dynamic_cast<TDEBacklightDevice*>(device);
  2987. TQString valuesnodename = systempath + "/";
  2988. TQDir valuesdir(valuesnodename);
  2989. valuesdir.setFilter(TQDir::All);
  2990. TQString nodename;
  2991. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  2992. if (dirlist) {
  2993. TQFileInfoListIterator valuesdirit(*dirlist);
  2994. TQFileInfo *dirfi;
  2995. while ( (dirfi = valuesdirit.current()) != 0 ) {
  2996. nodename = dirfi->fileName();
  2997. TQFile file( valuesnodename + nodename );
  2998. if ( file.open( IO_ReadOnly ) ) {
  2999. TQTextStream stream( &file );
  3000. TQString line;
  3001. line = stream.readLine();
  3002. if (nodename == "bl_power") {
  3003. TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
  3004. int rpl = line.toInt();
  3005. if (rpl == FB_BLANK_UNBLANK) {
  3006. pl = TDEDisplayPowerLevel::On;
  3007. }
  3008. else if (rpl == FB_BLANK_POWERDOWN) {
  3009. pl = TDEDisplayPowerLevel::Off;
  3010. }
  3011. bdevice->internalSetPowerLevel(pl);
  3012. }
  3013. else if (nodename == "max_brightness") {
  3014. bdevice->internalSetMaximumRawBrightness(line.toInt());
  3015. }
  3016. else if (nodename == "actual_brightness") {
  3017. bdevice->internalSetCurrentRawBrightness(line.toInt());
  3018. }
  3019. file.close();
  3020. }
  3021. ++valuesdirit;
  3022. }
  3023. }
  3024. }
  3025. if (device->type() == TDEGenericDeviceType::Monitor) {
  3026. TDEMonitorDevice* mdevice = dynamic_cast<TDEMonitorDevice*>(device);
  3027. TQString valuesnodename = systempath + "/";
  3028. TQDir valuesdir(valuesnodename);
  3029. valuesdir.setFilter(TQDir::All);
  3030. TQString nodename;
  3031. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  3032. if (dirlist) {
  3033. TQFileInfoListIterator valuesdirit(*dirlist);
  3034. TQFileInfo *dirfi;
  3035. while ( (dirfi = valuesdirit.current()) != 0 ) {
  3036. nodename = dirfi->fileName();
  3037. TQFile file( valuesnodename + nodename );
  3038. if ( file.open( IO_ReadOnly ) ) {
  3039. TQTextStream stream( &file );
  3040. TQString line;
  3041. line = stream.readLine();
  3042. if (nodename == "status") {
  3043. mdevice->internalSetConnected(line.lower() == "connected");
  3044. }
  3045. else if (nodename == "enabled") {
  3046. mdevice->internalSetEnabled(line.lower() == "enabled");
  3047. }
  3048. else if (nodename == "modes") {
  3049. TQStringList resinfo;
  3050. TQStringList resolutionsStringList = line.upper();
  3051. while ((!stream.atEnd()) && (!line.isNull())) {
  3052. line = stream.readLine();
  3053. if (!line.isNull()) {
  3054. resolutionsStringList.append(line.upper());
  3055. }
  3056. }
  3057. TDEResolutionList resolutions;
  3058. resolutions.clear();
  3059. for (TQStringList::Iterator it = resolutionsStringList.begin(); it != resolutionsStringList.end(); ++it) {
  3060. resinfo = TQStringList::split('X', *it, true);
  3061. resolutions.append(TDEResolutionPair((*(resinfo.at(0))).toUInt(), (*(resinfo.at(1))).toUInt()));
  3062. }
  3063. mdevice->internalSetResolutions(resolutions);
  3064. }
  3065. else if (nodename == "dpms") {
  3066. TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
  3067. if (line == "On") {
  3068. pl = TDEDisplayPowerLevel::On;
  3069. }
  3070. else if (line == "Standby") {
  3071. pl = TDEDisplayPowerLevel::Standby;
  3072. }
  3073. else if (line == "Suspend") {
  3074. pl = TDEDisplayPowerLevel::Suspend;
  3075. }
  3076. else if (line == "Off") {
  3077. pl = TDEDisplayPowerLevel::Off;
  3078. }
  3079. mdevice->internalSetPowerLevel(pl);
  3080. }
  3081. file.close();
  3082. }
  3083. ++valuesdirit;
  3084. }
  3085. }
  3086. TQString genericPortName = mdevice->systemPath();
  3087. genericPortName.remove(0, genericPortName.find("-")+1);
  3088. genericPortName.truncate(genericPortName.findRev("-"));
  3089. mdevice->internalSetPortType(genericPortName);
  3090. if (mdevice->connected()) {
  3091. TQPair<TQString,TQString> monitor_info = getEDIDMonitorName(device->systemPath());
  3092. if (!monitor_info.first.isNull()) {
  3093. mdevice->internalSetVendorName(monitor_info.first);
  3094. mdevice->internalSetVendorModel(monitor_info.second);
  3095. mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second;
  3096. }
  3097. else {
  3098. mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName);
  3099. }
  3100. mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
  3101. }
  3102. else {
  3103. mdevice->m_friendlyName = i18n("Disconnected %1 Port").arg(genericPortName);
  3104. mdevice->internalSetEdid(TQByteArray());
  3105. mdevice->internalSetResolutions(TDEResolutionList());
  3106. }
  3107. // FIXME
  3108. // Much of the code in libtderandr should be integrated into/interfaced with this library
  3109. }
  3110. if (device->type() == TDEGenericDeviceType::RootSystem) {
  3111. // Try to obtain as much generic information about this system as possible
  3112. TDERootSystemDevice* rdevice = dynamic_cast<TDERootSystemDevice*>(device);
  3113. // Guess at my form factor
  3114. // dmidecode would tell me this, but is somewhat unreliable
  3115. TDESystemFormFactor::TDESystemFormFactor formfactor = TDESystemFormFactor::Desktop;
  3116. if (listByDeviceClass(TDEGenericDeviceType::Backlight).count() > 0) { // Is this really a good way to determine if a machine is a laptop?
  3117. formfactor = TDESystemFormFactor::Laptop;
  3118. }
  3119. rdevice->internalSetFormFactor(formfactor);
  3120. TQString valuesnodename = "/sys/power/";
  3121. TQDir valuesdir(valuesnodename);
  3122. valuesdir.setFilter(TQDir::All);
  3123. TQString nodename;
  3124. const TQFileInfoList *dirlist = valuesdir.entryInfoList();
  3125. if (dirlist) {
  3126. TQFileInfoListIterator valuesdirit(*dirlist);
  3127. TQFileInfo *dirfi;
  3128. TDESystemPowerStateList powerstates;
  3129. TDESystemHibernationMethodList hibernationmethods;
  3130. TDESystemHibernationMethod::TDESystemHibernationMethod hibernationmethod =
  3131. TDESystemHibernationMethod::Unsupported;
  3132. while ( (dirfi = valuesdirit.current()) != 0 ) {
  3133. nodename = dirfi->fileName();
  3134. TQFile file( valuesnodename + nodename );
  3135. if ( file.open( IO_ReadOnly ) ) {
  3136. TQTextStream stream( &file );
  3137. TQString line;
  3138. line = stream.readLine();
  3139. if (nodename == "state") {
  3140. // Always assume that these two fully on/fully off states are available
  3141. powerstates.append(TDESystemPowerState::Active);
  3142. powerstates.append(TDESystemPowerState::PowerOff);
  3143. if (line.contains("standby")) {
  3144. powerstates.append(TDESystemPowerState::Standby);
  3145. }
  3146. if (line.contains("freeze")) {
  3147. powerstates.append(TDESystemPowerState::Freeze);
  3148. }
  3149. if (line.contains("mem")) {
  3150. powerstates.append(TDESystemPowerState::Suspend);
  3151. }
  3152. if (line.contains("disk")) {
  3153. powerstates.append(TDESystemPowerState::Disk);
  3154. }
  3155. }
  3156. if (nodename == "disk") {
  3157. // Get list of available hibernation methods
  3158. if (line.contains("platform")) {
  3159. hibernationmethods.append(TDESystemHibernationMethod::Platform);
  3160. }
  3161. if (line.contains("shutdown")) {
  3162. hibernationmethods.append(TDESystemHibernationMethod::Shutdown);
  3163. }
  3164. if (line.contains("reboot")) {
  3165. hibernationmethods.append(TDESystemHibernationMethod::Reboot);
  3166. }
  3167. if (line.contains("suspend")) {
  3168. hibernationmethods.append(TDESystemHibernationMethod::Suspend);
  3169. }
  3170. if (line.contains("testproc")) {
  3171. hibernationmethods.append(TDESystemHibernationMethod::TestProc);
  3172. }
  3173. if (line.contains("test")) {
  3174. hibernationmethods.append(TDESystemHibernationMethod::Test);
  3175. }
  3176. // Get current hibernation method
  3177. line.truncate(line.findRev("]"));
  3178. line.remove(0, line.findRev("[")+1);
  3179. if (line.contains("platform")) {
  3180. hibernationmethod = TDESystemHibernationMethod::Platform;
  3181. }
  3182. if (line.contains("shutdown")) {
  3183. hibernationmethod = TDESystemHibernationMethod::Shutdown;
  3184. }
  3185. if (line.contains("reboot")) {
  3186. hibernationmethod = TDESystemHibernationMethod::Reboot;
  3187. }
  3188. if (line.contains("suspend")) {
  3189. hibernationmethod = TDESystemHibernationMethod::Suspend;
  3190. }
  3191. if (line.contains("testproc")) {
  3192. hibernationmethod = TDESystemHibernationMethod::TestProc;
  3193. }
  3194. if (line.contains("test")) {
  3195. hibernationmethod = TDESystemHibernationMethod::Test;
  3196. }
  3197. }
  3198. if (nodename == "image_size") {
  3199. rdevice->internalSetDiskSpaceNeededForHibernation(line.toULong());
  3200. }
  3201. file.close();
  3202. }
  3203. ++valuesdirit;
  3204. }
  3205. // Hibernation and Hybrid Suspend are not real power states, being just two different
  3206. // ways of suspending to disk. Since they are very common and it is very convenient to
  3207. // treat them as power states, we do so, as other power frameworks also do.
  3208. if (powerstates.contains(TDESystemPowerState::Disk) &&
  3209. hibernationmethods.contains(TDESystemHibernationMethod::Platform)) {
  3210. powerstates.append(TDESystemPowerState::Hibernate);
  3211. }
  3212. if (powerstates.contains(TDESystemPowerState::Disk) &&
  3213. hibernationmethods.contains(TDESystemHibernationMethod::Suspend)) {
  3214. powerstates.append(TDESystemPowerState::HybridSuspend);
  3215. }
  3216. powerstates.remove(TDESystemPowerState::Disk);
  3217. // Set power states and hibernation methods
  3218. rdevice->internalSetPowerStates(powerstates);
  3219. rdevice->internalSetHibernationMethods(hibernationmethods);
  3220. rdevice->internalSetHibernationMethod(hibernationmethod);
  3221. }
  3222. }
  3223. // NOTE
  3224. // Keep these two handlers (Event and Input) in sync!
  3225. if (device->type() == TDEGenericDeviceType::Event) {
  3226. // Try to obtain as much type information about this event device as possible
  3227. TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
  3228. if (edevice->systemPath().contains("PNP0C0D")) {
  3229. edevice->internalSetEventType(TDEEventDeviceType::ACPILidSwitch);
  3230. }
  3231. else if (edevice->systemPath().contains("PNP0C0E") || edevice->systemPath().contains("/LNXSLPBN")) {
  3232. edevice->internalSetEventType(TDEEventDeviceType::ACPISleepButton);
  3233. }
  3234. else if (edevice->systemPath().contains("PNP0C0C") || edevice->systemPath().contains("/LNXPWRBN")) {
  3235. edevice->internalSetEventType(TDEEventDeviceType::ACPIPowerButton);
  3236. }
  3237. else if (edevice->systemPath().contains("_acpi")) {
  3238. edevice->internalSetEventType(TDEEventDeviceType::ACPIOtherInput);
  3239. }
  3240. else {
  3241. edevice->internalSetEventType(TDEEventDeviceType::Unknown);
  3242. }
  3243. }
  3244. if (device->type() == TDEGenericDeviceType::Input) {
  3245. // Try to obtain as much type information about this input device as possible
  3246. TDEInputDevice* idevice = dynamic_cast<TDEInputDevice*>(device);
  3247. if (idevice->systemPath().contains("PNP0C0D")) {
  3248. idevice->internalSetInputType(TDEInputDeviceType::ACPILidSwitch);
  3249. }
  3250. else if (idevice->systemPath().contains("PNP0C0E") || idevice->systemPath().contains("/LNXSLPBN")) {
  3251. idevice->internalSetInputType(TDEInputDeviceType::ACPISleepButton);
  3252. }
  3253. else if (idevice->systemPath().contains("PNP0C0C") || idevice->systemPath().contains("/LNXPWRBN")) {
  3254. idevice->internalSetInputType(TDEInputDeviceType::ACPIPowerButton);
  3255. }
  3256. else if (idevice->systemPath().contains("_acpi")) {
  3257. idevice->internalSetInputType(TDEInputDeviceType::ACPIOtherInput);
  3258. }
  3259. else {
  3260. idevice->internalSetInputType(TDEInputDeviceType::Unknown);
  3261. }
  3262. }
  3263. if (device->type() == TDEGenericDeviceType::Event) {
  3264. // Try to obtain as much specific information about this event device as possible
  3265. TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
  3266. // Try to open input event device
  3267. if (edevice->m_fd < 0 && access (edevice->deviceNode().ascii(), R_OK) == 0) {
  3268. edevice->m_fd = open(edevice->deviceNode().ascii(), O_RDONLY);
  3269. }
  3270. // Start monitoring of input event device
  3271. edevice->internalStartMonitoring(this);
  3272. }
  3273. // Root devices are still special
  3274. if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
  3275. systempath = device->systemPath();
  3276. }
  3277. // Set basic device information again, as some information may have changed
  3278. device->internalSetName(devicename);
  3279. device->internalSetDeviceNode(devicenode);
  3280. device->internalSetSystemPath(systempath);
  3281. device->internalSetVendorID(devicevendorid);
  3282. device->internalSetModelID(devicemodelid);
  3283. device->internalSetVendorEncoded(devicevendoridenc);
  3284. device->internalSetModelEncoded(devicemodelidenc);
  3285. device->internalSetSubVendorID(devicesubvendorid);
  3286. device->internalSetSubModelID(devicesubmodelid);
  3287. device->internalSetDeviceDriver(devicedriver);
  3288. device->internalSetSubsystem(devicesubsystem);
  3289. device->internalSetPCIClass(devicepciclass);
  3290. // Internal use only!
  3291. device->m_udevtype = devicetype;
  3292. device->m_udevdevicetypestring = devicetypestring;
  3293. device->udevdevicetypestring_alt = devicetypestring_alt;
  3294. if (temp_udev_device) {
  3295. udev_device_unref(dev);
  3296. }
  3297. }
  3298. void TDEHardwareDevices::updateBlacklists(TDEGenericDevice* hwdevice, udev_device* dev) {
  3299. // HACK
  3300. // I am lucky enough to have a Flash drive that spams udev continually with device change events
  3301. // I imagine I am not the only one, so here is a section in which specific devices can be blacklisted!
  3302. // For "U3 System" fake CD
  3303. if ((hwdevice->vendorID() == "08ec") && (hwdevice->modelID() == "0020") && (TQString(udev_device_get_property_value(dev, "ID_TYPE")) == "cd")) {
  3304. hwdevice->internalSetBlacklistedForUpdate(true);
  3305. }
  3306. }
  3307. bool TDEHardwareDevices::queryHardwareInformation() {
  3308. if (!m_udevStruct) {
  3309. return false;
  3310. }
  3311. // Prepare the device list for repopulation
  3312. m_deviceList.clear();
  3313. addCoreSystemDevices();
  3314. struct udev_enumerate *enumerate;
  3315. struct udev_list_entry *devices, *dev_list_entry;
  3316. struct udev_device *dev;
  3317. // Create a list of all devices
  3318. enumerate = udev_enumerate_new(m_udevStruct);
  3319. udev_enumerate_add_match_subsystem(enumerate, NULL);
  3320. udev_enumerate_scan_devices(enumerate);
  3321. devices = udev_enumerate_get_list_entry(enumerate);
  3322. // Get detailed information on each detected device
  3323. udev_list_entry_foreach(dev_list_entry, devices) {
  3324. const char *path;
  3325. // Get the filename of the /sys entry for the device and create a udev_device object (dev) representing it
  3326. path = udev_list_entry_get_name(dev_list_entry);
  3327. dev = udev_device_new_from_syspath(m_udevStruct, path);
  3328. TDEGenericDevice* device = classifyUnknownDevice(dev);
  3329. // Make sure this device is not a duplicate
  3330. TDEGenericDevice *hwdevice;
  3331. for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
  3332. if (hwdevice->systemPath() == device->systemPath()) {
  3333. delete device;
  3334. device = 0;
  3335. break;
  3336. }
  3337. }
  3338. if (device) {
  3339. m_deviceList.append(device);
  3340. }
  3341. udev_device_unref(dev);
  3342. }
  3343. // Free the enumerator object
  3344. udev_enumerate_unref(enumerate);
  3345. // Update parent/child tables for all devices
  3346. updateParentDeviceInformation();
  3347. emit hardwareEvent(TDEHardwareEvent::HardwareListModified, TQString());
  3348. return true;
  3349. }
  3350. void TDEHardwareDevices::updateParentDeviceInformation(TDEGenericDevice* hwdevice) {
  3351. // Scan for the first path up the sysfs tree that is available in the main hardware table
  3352. bool done = false;
  3353. TQString current_path = hwdevice->systemPath();
  3354. TDEGenericDevice* parentdevice = 0;
  3355. if (current_path.endsWith("/")) {
  3356. current_path.truncate(current_path.findRev("/"));
  3357. }
  3358. while (done == false) {
  3359. current_path.truncate(current_path.findRev("/"));
  3360. if (current_path.startsWith("/sys/devices")) {
  3361. if (current_path.endsWith("/")) {
  3362. current_path.truncate(current_path.findRev("/"));
  3363. }
  3364. parentdevice = findBySystemPath(current_path);
  3365. if (parentdevice) {
  3366. done = true;
  3367. }
  3368. }
  3369. else {
  3370. // Abort!
  3371. done = true;
  3372. }
  3373. }
  3374. hwdevice->internalSetParentDevice(parentdevice);
  3375. }
  3376. void TDEHardwareDevices::updateParentDeviceInformation() {
  3377. TDEGenericDevice *hwdevice;
  3378. // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
  3379. TDEGenericHardwareList devList = listAllPhysicalDevices();
  3380. for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
  3381. updateParentDeviceInformation(hwdevice);
  3382. }
  3383. }
  3384. void TDEHardwareDevices::addCoreSystemDevices() {
  3385. TDEGenericDevice *hwdevice;
  3386. // Add the Main Root System Device, which provides all other devices
  3387. hwdevice = new TDERootSystemDevice(TDEGenericDeviceType::RootSystem);
  3388. hwdevice->internalSetSystemPath("/sys/devices");
  3389. m_deviceList.append(hwdevice);
  3390. rescanDeviceInformation(hwdevice);
  3391. // Add core top-level devices in /sys/devices to the hardware listing
  3392. TQStringList holdingDeviceNodes;
  3393. TQString devicesnodename = "/sys/devices";
  3394. TQDir devicesdir(devicesnodename);
  3395. devicesdir.setFilter(TQDir::All);
  3396. TQString nodename;
  3397. const TQFileInfoList *dirlist = devicesdir.entryInfoList();
  3398. if (dirlist) {
  3399. TQFileInfoListIterator devicesdirit(*dirlist);
  3400. TQFileInfo *dirfi;
  3401. while ( (dirfi = devicesdirit.current()) != 0 ) {
  3402. nodename = dirfi->fileName();
  3403. if (nodename != "." && nodename != "..") {
  3404. hwdevice = new TDEGenericDevice(TDEGenericDeviceType::Root);
  3405. hwdevice->internalSetSystemPath(dirfi->absFilePath());
  3406. m_deviceList.append(hwdevice);
  3407. }
  3408. ++devicesdirit;
  3409. }
  3410. }
  3411. // Handle CPUs, which are currently handled terribly by udev
  3412. // Parse /proc/cpuinfo to extract some information about the CPUs
  3413. hwdevice = 0;
  3414. TQDir d("/sys/devices/system/cpu/");
  3415. d.setFilter( TQDir::Dirs );
  3416. const TQFileInfoList *list = d.entryInfoList();
  3417. if (list) {
  3418. TQFileInfoListIterator it( *list );
  3419. TQFileInfo *fi;
  3420. while ((fi = it.current()) != 0) {
  3421. TQString directoryName = fi->fileName();
  3422. if (directoryName.startsWith("cpu")) {
  3423. directoryName = directoryName.remove(0,3);
  3424. bool isInt;
  3425. int processorNumber = directoryName.toUInt(&isInt, 10);
  3426. if (isInt) {
  3427. hwdevice = new TDECPUDevice(TDEGenericDeviceType::CPU);
  3428. hwdevice->internalSetSystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
  3429. m_deviceList.append(hwdevice);
  3430. }
  3431. }
  3432. ++it;
  3433. }
  3434. }
  3435. // Populate CPU information
  3436. processModifiedCPUs();
  3437. }
  3438. TQString TDEHardwareDevices::findPCIDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
  3439. TQString vendorName = TQString::null;
  3440. TQString modelName = TQString::null;
  3441. TQString friendlyName = TQString::null;
  3442. if (!pci_id_map) {
  3443. pci_id_map = new TDEDeviceIDMap;
  3444. TQString database_filename = "/usr/share/pci.ids";
  3445. if (!TQFile::exists(database_filename)) {
  3446. database_filename = "/usr/share/misc/pci.ids";
  3447. }
  3448. if (!TQFile::exists(database_filename)) {
  3449. printf("[tdehardwaredevices] Unable to locate PCI information database pci.ids\n"); fflush(stdout);
  3450. return i18n("Unknown PCI Device");
  3451. }
  3452. TQFile database(database_filename);
  3453. if (database.open(IO_ReadOnly)) {
  3454. TQTextStream stream(&database);
  3455. TQString line;
  3456. TQString vendorID;
  3457. TQString modelID;
  3458. TQString subvendorID;
  3459. TQString submodelID;
  3460. TQString deviceMapKey;
  3461. TQStringList devinfo;
  3462. while (!stream.atEnd()) {
  3463. line = stream.readLine();
  3464. if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
  3465. line.replace("\t", "");
  3466. devinfo = TQStringList::split(' ', line, false);
  3467. vendorID = *(devinfo.at(0));
  3468. vendorName = line;
  3469. vendorName.remove(0, vendorName.find(" "));
  3470. vendorName = vendorName.stripWhiteSpace();
  3471. modelName = TQString::null;
  3472. deviceMapKey = vendorID.lower() + ":::";
  3473. }
  3474. else {
  3475. if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
  3476. line.replace("\t", "");
  3477. devinfo = TQStringList::split(' ', line, false);
  3478. modelID = *(devinfo.at(0));
  3479. modelName = line;
  3480. modelName.remove(0, modelName.find(" "));
  3481. modelName = modelName.stripWhiteSpace();
  3482. deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
  3483. }
  3484. else {
  3485. if (line.upper().startsWith("\t\t")) {
  3486. line.replace("\t", "");
  3487. devinfo = TQStringList::split(' ', line, false);
  3488. subvendorID = *(devinfo.at(0));
  3489. submodelID = *(devinfo.at(1));
  3490. modelName = line;
  3491. modelName.remove(0, modelName.find(" "));
  3492. modelName = modelName.stripWhiteSpace();
  3493. modelName.remove(0, modelName.find(" "));
  3494. modelName = modelName.stripWhiteSpace();
  3495. deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
  3496. }
  3497. }
  3498. }
  3499. if (modelName.isNull()) {
  3500. pci_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
  3501. }
  3502. else {
  3503. pci_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
  3504. }
  3505. }
  3506. database.close();
  3507. }
  3508. else {
  3509. printf("[tdehardwaredevices] Unable to open PCI information database %s\n", database_filename.ascii()); fflush(stdout);
  3510. }
  3511. }
  3512. if (pci_id_map) {
  3513. TQString deviceName;
  3514. TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
  3515. deviceName = (*pci_id_map)[deviceMapKey];
  3516. if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
  3517. deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
  3518. deviceName = (*pci_id_map)[deviceMapKey];
  3519. if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
  3520. deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
  3521. deviceName = (*pci_id_map)[deviceMapKey];
  3522. }
  3523. }
  3524. if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
  3525. deviceName.replace("***UNKNOWN DEVICE*** ", "");
  3526. deviceName.prepend(i18n("Unknown PCI Device") + " ");
  3527. if (subvendorid.isNull()) {
  3528. deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
  3529. }
  3530. else {
  3531. deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
  3532. }
  3533. }
  3534. return deviceName;
  3535. }
  3536. else {
  3537. return i18n("Unknown PCI Device");
  3538. }
  3539. }
  3540. TQString TDEHardwareDevices::findUSBDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {
  3541. TQString vendorName = TQString::null;
  3542. TQString modelName = TQString::null;
  3543. TQString friendlyName = TQString::null;
  3544. if (!usb_id_map) {
  3545. usb_id_map = new TDEDeviceIDMap;
  3546. TQString database_filename = "/usr/share/usb.ids";
  3547. if (!TQFile::exists(database_filename)) {
  3548. database_filename = "/usr/share/misc/usb.ids";
  3549. }
  3550. if (!TQFile::exists(database_filename)) {
  3551. printf("[tdehardwaredevices] Unable to locate USB information database usb.ids\n"); fflush(stdout);
  3552. return i18n("Unknown USB Device");
  3553. }
  3554. TQFile database(database_filename);
  3555. if (database.open(IO_ReadOnly)) {
  3556. TQTextStream stream(&database);
  3557. TQString line;
  3558. TQString vendorID;
  3559. TQString modelID;
  3560. TQString subvendorID;
  3561. TQString submodelID;
  3562. TQString deviceMapKey;
  3563. TQStringList devinfo;
  3564. while (!stream.atEnd()) {
  3565. line = stream.readLine();
  3566. if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
  3567. line.replace("\t", "");
  3568. devinfo = TQStringList::split(' ', line, false);
  3569. vendorID = *(devinfo.at(0));
  3570. vendorName = line;
  3571. vendorName.remove(0, vendorName.find(" "));
  3572. vendorName = vendorName.stripWhiteSpace();
  3573. modelName = TQString::null;
  3574. deviceMapKey = vendorID.lower() + ":::";
  3575. }
  3576. else {
  3577. if ((line.upper().startsWith("\t")) && (!line.upper().startsWith("\t\t"))) {
  3578. line.replace("\t", "");
  3579. devinfo = TQStringList::split(' ', line, false);
  3580. modelID = *(devinfo.at(0));
  3581. modelName = line;
  3582. modelName.remove(0, modelName.find(" "));
  3583. modelName = modelName.stripWhiteSpace();
  3584. deviceMapKey = vendorID.lower() + ":" + modelID.lower() + "::";
  3585. }
  3586. else {
  3587. if (line.upper().startsWith("\t\t")) {
  3588. line.replace("\t", "");
  3589. devinfo = TQStringList::split(' ', line, false);
  3590. subvendorID = *(devinfo.at(0));
  3591. submodelID = *(devinfo.at(1));
  3592. modelName = line;
  3593. modelName.remove(0, modelName.find(" "));
  3594. modelName = modelName.stripWhiteSpace();
  3595. modelName.remove(0, modelName.find(" "));
  3596. modelName = modelName.stripWhiteSpace();
  3597. deviceMapKey = vendorID.lower() + ":" + modelID.lower() + ":" + subvendorID.lower() + ":" + submodelID.lower();
  3598. }
  3599. }
  3600. }
  3601. if (modelName.isNull()) {
  3602. usb_id_map->insert(deviceMapKey, "***UNKNOWN DEVICE*** " + vendorName, true);
  3603. }
  3604. else {
  3605. usb_id_map->insert(deviceMapKey, vendorName + " " + modelName, true);
  3606. }
  3607. }
  3608. database.close();
  3609. }
  3610. else {
  3611. printf("[tdehardwaredevices] Unable to open USB information database %s\n", database_filename.ascii()); fflush(stdout);
  3612. }
  3613. }
  3614. if (usb_id_map) {
  3615. TQString deviceName;
  3616. TQString deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":" + submodelid.lower();
  3617. deviceName = (*usb_id_map)[deviceMapKey];
  3618. if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
  3619. deviceMapKey = vendorid.lower() + ":" + modelid.lower() + ":" + subvendorid.lower() + ":";
  3620. deviceName = (*usb_id_map)[deviceMapKey];
  3621. if (deviceName.isNull() || deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
  3622. deviceMapKey = vendorid.lower() + ":" + modelid.lower() + "::";
  3623. deviceName = (*usb_id_map)[deviceMapKey];
  3624. }
  3625. }
  3626. if (deviceName.startsWith("***UNKNOWN DEVICE*** ")) {
  3627. deviceName.replace("***UNKNOWN DEVICE*** ", "");
  3628. deviceName.prepend(i18n("Unknown USB Device") + " ");
  3629. if (subvendorid.isNull()) {
  3630. deviceName.append(TQString(" [%1:%2]").arg(vendorid.lower()).arg(modelid.lower()));
  3631. }
  3632. else {
  3633. deviceName.append(TQString(" [%1:%2] [%3:%4]").arg(vendorid.lower()).arg(modelid.lower()).arg(subvendorid.lower()).arg(submodelid.lower()));
  3634. }
  3635. }
  3636. return deviceName;
  3637. }
  3638. else {
  3639. return i18n("Unknown USB Device");
  3640. }
  3641. }
  3642. TQString TDEHardwareDevices::findPNPDeviceName(TQString pnpid) {
  3643. TQString friendlyName = TQString::null;
  3644. if (!pnp_id_map) {
  3645. pnp_id_map = new TDEDeviceIDMap;
  3646. TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
  3647. TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
  3648. TQString hardware_info_directory;
  3649. TQString database_filename;
  3650. for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
  3651. hardware_info_directory = (*it);
  3652. hardware_info_directory += hardware_info_directory_suffix;
  3653. if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
  3654. database_filename = hardware_info_directory + "pnp.ids";
  3655. if (TQFile::exists(database_filename)) {
  3656. break;
  3657. }
  3658. }
  3659. }
  3660. if (!TQFile::exists(database_filename)) {
  3661. printf("[tdehardwaredevices] Unable to locate PNP information database pnp.ids\n"); fflush(stdout);
  3662. return i18n("Unknown PNP Device");
  3663. }
  3664. TQFile database(database_filename);
  3665. if (database.open(IO_ReadOnly)) {
  3666. TQTextStream stream(&database);
  3667. TQString line;
  3668. TQString pnpID;
  3669. TQString vendorName;
  3670. TQString deviceMapKey;
  3671. TQStringList devinfo;
  3672. while (!stream.atEnd()) {
  3673. line = stream.readLine();
  3674. if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
  3675. devinfo = TQStringList::split('\t', line, false);
  3676. if (devinfo.count() > 1) {
  3677. pnpID = *(devinfo.at(0));
  3678. vendorName = *(devinfo.at(1));;
  3679. vendorName = vendorName.stripWhiteSpace();
  3680. deviceMapKey = pnpID.upper().stripWhiteSpace();
  3681. if (!deviceMapKey.isNull()) {
  3682. pnp_id_map->insert(deviceMapKey, vendorName, true);
  3683. }
  3684. }
  3685. }
  3686. }
  3687. database.close();
  3688. }
  3689. else {
  3690. printf("[tdehardwaredevices] Unable to open PNP information database %s\n", database_filename.ascii()); fflush(stdout);
  3691. }
  3692. }
  3693. if (pnp_id_map) {
  3694. TQString deviceName;
  3695. deviceName = (*pnp_id_map)[pnpid];
  3696. return deviceName;
  3697. }
  3698. else {
  3699. return i18n("Unknown PNP Device");
  3700. }
  3701. }
  3702. TQString TDEHardwareDevices::findMonitorManufacturerName(TQString dpyid) {
  3703. TQString friendlyName = TQString::null;
  3704. if (!dpy_id_map) {
  3705. dpy_id_map = new TDEDeviceIDMap;
  3706. TQStringList hardware_info_directories(TDEGlobal::dirs()->resourceDirs("data"));
  3707. TQString hardware_info_directory_suffix("tdehwlib/pnpdev/");
  3708. TQString hardware_info_directory;
  3709. TQString database_filename;
  3710. for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) {
  3711. hardware_info_directory = (*it);
  3712. hardware_info_directory += hardware_info_directory_suffix;
  3713. if (TDEGlobal::dirs()->exists(hardware_info_directory)) {
  3714. database_filename = hardware_info_directory + "dpy.ids";
  3715. if (TQFile::exists(database_filename)) {
  3716. break;
  3717. }
  3718. }
  3719. }
  3720. if (!TQFile::exists(database_filename)) {
  3721. printf("[tdehardwaredevices] Unable to locate monitor information database dpy.ids\n"); fflush(stdout);
  3722. return i18n("Unknown Monitor Device");
  3723. }
  3724. TQFile database(database_filename);
  3725. if (database.open(IO_ReadOnly)) {
  3726. TQTextStream stream(&database);
  3727. TQString line;
  3728. TQString dpyID;
  3729. TQString vendorName;
  3730. TQString deviceMapKey;
  3731. TQStringList devinfo;
  3732. while (!stream.atEnd()) {
  3733. line = stream.readLine();
  3734. if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) {
  3735. devinfo = TQStringList::split('\t', line, false);
  3736. if (devinfo.count() > 1) {
  3737. dpyID = *(devinfo.at(0));
  3738. vendorName = *(devinfo.at(1));;
  3739. vendorName = vendorName.stripWhiteSpace();
  3740. deviceMapKey = dpyID.upper().stripWhiteSpace();
  3741. if (!deviceMapKey.isNull()) {
  3742. dpy_id_map->insert(deviceMapKey, vendorName, true);
  3743. }
  3744. }
  3745. }
  3746. }
  3747. database.close();
  3748. }
  3749. else {
  3750. printf("[tdehardwaredevices] Unable to open monitor information database %s\n", database_filename.ascii()); fflush(stdout);
  3751. }
  3752. }
  3753. if (dpy_id_map) {
  3754. TQString deviceName;
  3755. deviceName = (*dpy_id_map)[dpyid];
  3756. return deviceName;
  3757. }
  3758. else {
  3759. return i18n("Unknown Monitor Device");
  3760. }
  3761. }
  3762. TQPair<TQString,TQString> TDEHardwareDevices::getEDIDMonitorName(TQString path) {
  3763. TQPair<TQString,TQString> edid;
  3764. TQByteArray binaryedid = getEDID(path);
  3765. if (binaryedid.isNull()) {
  3766. return TQPair<TQString,TQString>(TQString::null, TQString::null);
  3767. }
  3768. // Get the manufacturer ID
  3769. unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
  3770. unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
  3771. unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
  3772. TQChar qletter_1 = TQChar(letter_1);
  3773. TQChar qletter_2 = TQChar(letter_2);
  3774. TQChar qletter_3 = TQChar(letter_3);
  3775. TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
  3776. // Get the model ID
  3777. unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
  3778. // Reverse the bit order
  3779. unsigned int model_id = reverse_bits(raw_model_id);
  3780. // Try to get the model name
  3781. bool has_friendly_name = false;
  3782. unsigned char descriptor_block[18];
  3783. int i;
  3784. for (i=72;i<90;i++) {
  3785. descriptor_block[i-72] = binaryedid[i] & 0xFF;
  3786. }
  3787. if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
  3788. for (i=90;i<108;i++) {
  3789. descriptor_block[i-90] = binaryedid[i] & 0xFF;
  3790. }
  3791. if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
  3792. for (i=108;i<126;i++) {
  3793. descriptor_block[i-108] = binaryedid[i] & 0xFF;
  3794. }
  3795. }
  3796. }
  3797. TQString monitor_name;
  3798. if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
  3799. char* pos = strchr((char *)(descriptor_block+5), '\n');
  3800. if (pos) {
  3801. *pos = 0;
  3802. has_friendly_name = true;
  3803. monitor_name = TQString((char *)(descriptor_block+5));
  3804. }
  3805. else {
  3806. has_friendly_name = false;
  3807. }
  3808. }
  3809. // Look up manufacturer name
  3810. TQString manufacturer_name = findMonitorManufacturerName(manufacturer_id);
  3811. if (manufacturer_name.isNull()) {
  3812. manufacturer_name = manufacturer_id;
  3813. }
  3814. if (has_friendly_name) {
  3815. edid.first = TQString("%1").arg(manufacturer_name);
  3816. edid.second = TQString("%2").arg(monitor_name);
  3817. }
  3818. else {
  3819. edid.first = TQString("%1").arg(manufacturer_name);
  3820. edid.second = TQString("0x%2").arg(model_id, 0, 16);
  3821. }
  3822. return edid;
  3823. }
  3824. TQByteArray TDEHardwareDevices::getEDID(TQString path) {
  3825. TQFile file(TQString("%1/edid").arg(path));
  3826. if (!file.open (IO_ReadOnly)) {
  3827. return TQByteArray();
  3828. }
  3829. TQByteArray binaryedid = file.readAll();
  3830. file.close();
  3831. return binaryedid;
  3832. }
  3833. TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDeviceType::TDEGenericDeviceType query) {
  3834. TQString ret = "Unknown Device";
  3835. // Keep this in sync with the TDEGenericDeviceType definition in the header
  3836. if (query == TDEGenericDeviceType::Root) {
  3837. ret = i18n("Root");
  3838. }
  3839. else if (query == TDEGenericDeviceType::RootSystem) {
  3840. ret = i18n("System Root");
  3841. }
  3842. else if (query == TDEGenericDeviceType::CPU) {
  3843. ret = i18n("CPU");
  3844. }
  3845. else if (query == TDEGenericDeviceType::GPU) {
  3846. ret = i18n("Graphics Processor");
  3847. }
  3848. else if (query == TDEGenericDeviceType::RAM) {
  3849. ret = i18n("RAM");
  3850. }
  3851. else if (query == TDEGenericDeviceType::Bus) {
  3852. ret = i18n("Bus");
  3853. }
  3854. else if (query == TDEGenericDeviceType::I2C) {
  3855. ret = i18n("I2C Bus");
  3856. }
  3857. else if (query == TDEGenericDeviceType::MDIO) {
  3858. ret = i18n("MDIO Bus");
  3859. }
  3860. else if (query == TDEGenericDeviceType::Mainboard) {
  3861. ret = i18n("Mainboard");
  3862. }
  3863. else if (query == TDEGenericDeviceType::Disk) {
  3864. ret = i18n("Disk");
  3865. }
  3866. else if (query == TDEGenericDeviceType::SCSI) {
  3867. ret = i18n("SCSI");
  3868. }
  3869. else if (query == TDEGenericDeviceType::StorageController) {
  3870. ret = i18n("Storage Controller");
  3871. }
  3872. else if (query == TDEGenericDeviceType::Mouse) {
  3873. ret = i18n("Mouse");
  3874. }
  3875. else if (query == TDEGenericDeviceType::Keyboard) {
  3876. ret = i18n("Keyboard");
  3877. }
  3878. else if (query == TDEGenericDeviceType::HID) {
  3879. ret = i18n("HID");
  3880. }
  3881. else if (query == TDEGenericDeviceType::Modem) {
  3882. ret = i18n("Modem");
  3883. }
  3884. else if (query == TDEGenericDeviceType::Monitor) {
  3885. ret = i18n("Monitor and Display");
  3886. }
  3887. else if (query == TDEGenericDeviceType::Network) {
  3888. ret = i18n("Network");
  3889. }
  3890. else if (query == TDEGenericDeviceType::NonvolatileMemory) {
  3891. ret = i18n("Nonvolatile Memory");
  3892. }
  3893. else if (query == TDEGenericDeviceType::Printer) {
  3894. ret = i18n("Printer");
  3895. }
  3896. else if (query == TDEGenericDeviceType::Scanner) {
  3897. ret = i18n("Scanner");
  3898. }
  3899. else if (query == TDEGenericDeviceType::Sound) {
  3900. ret = i18n("Sound");
  3901. }
  3902. else if (query == TDEGenericDeviceType::VideoCapture) {
  3903. ret = i18n("Video Capture");
  3904. }
  3905. else if (query == TDEGenericDeviceType::IEEE1394) {
  3906. ret = i18n("IEEE1394");
  3907. }
  3908. else if (query == TDEGenericDeviceType::PCMCIA) {
  3909. ret = i18n("PCMCIA");
  3910. }
  3911. else if (query == TDEGenericDeviceType::Camera) {
  3912. ret = i18n("Camera");
  3913. }
  3914. else if (query == TDEGenericDeviceType::TextIO) {
  3915. ret = i18n("Text I/O");
  3916. }
  3917. else if (query == TDEGenericDeviceType::Serial) {
  3918. ret = i18n("Serial Communications Controller");
  3919. }
  3920. else if (query == TDEGenericDeviceType::Parallel) {
  3921. ret = i18n("Parallel Port");
  3922. }
  3923. else if (query == TDEGenericDeviceType::Peripheral) {
  3924. ret = i18n("Peripheral");
  3925. }
  3926. else if (query == TDEGenericDeviceType::Backlight) {
  3927. ret = i18n("Backlight");
  3928. }
  3929. else if (query == TDEGenericDeviceType::Battery) {
  3930. ret = i18n("Battery");
  3931. }
  3932. else if (query == TDEGenericDeviceType::PowerSupply) {
  3933. ret = i18n("Power Supply");
  3934. }
  3935. else if (query == TDEGenericDeviceType::Dock) {
  3936. ret = i18n("Docking Station");
  3937. }
  3938. else if (query == TDEGenericDeviceType::ThermalSensor) {
  3939. ret = i18n("Thermal Sensor");
  3940. }
  3941. else if (query == TDEGenericDeviceType::ThermalControl) {
  3942. ret = i18n("Thermal Control");
  3943. }
  3944. else if (query == TDEGenericDeviceType::BlueTooth) {
  3945. ret = i18n("Bluetooth");
  3946. }
  3947. else if (query == TDEGenericDeviceType::Bridge) {
  3948. ret = i18n("Bridge");
  3949. }
  3950. else if (query == TDEGenericDeviceType::Hub) {
  3951. ret = i18n("Hub");
  3952. }
  3953. else if (query == TDEGenericDeviceType::Platform) {
  3954. ret = i18n("Platform");
  3955. }
  3956. else if (query == TDEGenericDeviceType::Cryptography) {
  3957. ret = i18n("Cryptography");
  3958. }
  3959. else if (query == TDEGenericDeviceType::CryptographicCard) {
  3960. ret = i18n("Cryptographic Card");
  3961. }
  3962. else if (query == TDEGenericDeviceType::BiometricSecurity) {
  3963. ret = i18n("Biometric Security");
  3964. }
  3965. else if (query == TDEGenericDeviceType::TestAndMeasurement) {
  3966. ret = i18n("Test and Measurement");
  3967. }
  3968. else if (query == TDEGenericDeviceType::Timekeeping) {
  3969. ret = i18n("Timekeeping");
  3970. }
  3971. else if (query == TDEGenericDeviceType::Event) {
  3972. ret = i18n("Platform Event");
  3973. }
  3974. else if (query == TDEGenericDeviceType::Input) {
  3975. ret = i18n("Platform Input");
  3976. }
  3977. else if (query == TDEGenericDeviceType::PNP) {
  3978. ret = i18n("Plug and Play");
  3979. }
  3980. else if (query == TDEGenericDeviceType::OtherACPI) {
  3981. ret = i18n("Other ACPI");
  3982. }
  3983. else if (query == TDEGenericDeviceType::OtherUSB) {
  3984. ret = i18n("Other USB");
  3985. }
  3986. else if (query == TDEGenericDeviceType::OtherMultimedia) {
  3987. ret = i18n("Other Multimedia");
  3988. }
  3989. else if (query == TDEGenericDeviceType::OtherPeripheral) {
  3990. ret = i18n("Other Peripheral");
  3991. }
  3992. else if (query == TDEGenericDeviceType::OtherSensor) {
  3993. ret = i18n("Other Sensor");
  3994. }
  3995. else if (query == TDEGenericDeviceType::OtherVirtual) {
  3996. ret = i18n("Other Virtual");
  3997. }
  3998. else {
  3999. ret = i18n("Unknown Device");
  4000. }
  4001. return ret;
  4002. }
  4003. TQPixmap TDEHardwareDevices::getDeviceTypeIconFromType(TDEGenericDeviceType::TDEGenericDeviceType query, TDEIcon::StdSizes size) {
  4004. TQPixmap ret = DesktopIcon("misc", size);
  4005. // // Keep this in sync with the TDEGenericDeviceType definition in the header
  4006. if (query == TDEGenericDeviceType::Root) {
  4007. ret = DesktopIcon("kcmdevices", size);
  4008. }
  4009. else if (query == TDEGenericDeviceType::RootSystem) {
  4010. ret = DesktopIcon("kcmdevices", size);
  4011. }
  4012. else if (query == TDEGenericDeviceType::CPU) {
  4013. ret = DesktopIcon("kcmprocessor", size);
  4014. }
  4015. else if (query == TDEGenericDeviceType::GPU) {
  4016. ret = DesktopIcon("kcmpci", size);
  4017. }
  4018. else if (query == TDEGenericDeviceType::RAM) {
  4019. ret = DesktopIcon("memory", size);
  4020. }
  4021. else if (query == TDEGenericDeviceType::Bus) {
  4022. ret = DesktopIcon("kcmpci", size);
  4023. }
  4024. else if (query == TDEGenericDeviceType::I2C) {
  4025. ret = DesktopIcon("preferences-desktop-peripherals", size);
  4026. }
  4027. else if (query == TDEGenericDeviceType::MDIO) {
  4028. ret = DesktopIcon("preferences-desktop-peripherals", size);
  4029. }
  4030. else if (query == TDEGenericDeviceType::Mainboard) {
  4031. ret = DesktopIcon("kcmpci", size); // FIXME
  4032. }
  4033. else if (query == TDEGenericDeviceType::Disk) {
  4034. ret = DesktopIcon("drive-harddisk", size);
  4035. }
  4036. else if (query == TDEGenericDeviceType::SCSI) {
  4037. ret = DesktopIcon("kcmscsi", size);
  4038. }
  4039. else if (query == TDEGenericDeviceType::StorageController) {
  4040. ret = DesktopIcon("kcmpci", size);
  4041. }
  4042. else if (query == TDEGenericDeviceType::Mouse) {
  4043. ret = DesktopIcon("input-mouse", size);
  4044. }
  4045. else if (query == TDEGenericDeviceType::Keyboard) {
  4046. ret = DesktopIcon("input-keyboard", size);
  4047. }
  4048. else if (query == TDEGenericDeviceType::HID) {
  4049. ret = DesktopIcon("kcmdevices", size); // FIXME
  4050. }
  4051. else if (query == TDEGenericDeviceType::Modem) {
  4052. ret = DesktopIcon("kcmpci", size);
  4053. }
  4054. else if (query == TDEGenericDeviceType::Monitor) {
  4055. ret = DesktopIcon("background", size);
  4056. }
  4057. else if (query == TDEGenericDeviceType::Network) {
  4058. ret = DesktopIcon("kcmpci", size);
  4059. }
  4060. else if (query == TDEGenericDeviceType::NonvolatileMemory) {
  4061. ret = DesktopIcon("memory", size);
  4062. }
  4063. else if (query == TDEGenericDeviceType::Printer) {
  4064. ret = DesktopIcon("printer", size);
  4065. }
  4066. else if (query == TDEGenericDeviceType::Scanner) {
  4067. ret = DesktopIcon("scanner", size);
  4068. }
  4069. else if (query == TDEGenericDeviceType::Sound) {
  4070. ret = DesktopIcon("kcmsound", size);
  4071. }
  4072. else if (query == TDEGenericDeviceType::VideoCapture) {
  4073. ret = DesktopIcon("tv", size); // FIXME
  4074. }
  4075. else if (query == TDEGenericDeviceType::IEEE1394) {
  4076. ret = DesktopIcon("ieee1394", size);
  4077. }
  4078. else if (query == TDEGenericDeviceType::PCMCIA) {
  4079. ret = DesktopIcon("kcmdevices", size); // FIXME
  4080. }
  4081. else if (query == TDEGenericDeviceType::Camera) {
  4082. ret = DesktopIcon("camera-photo", size);
  4083. }
  4084. else if (query == TDEGenericDeviceType::Serial) {
  4085. ret = DesktopIcon("preferences-desktop-peripherals", size);
  4086. }
  4087. else if (query == TDEGenericDeviceType::Parallel) {
  4088. ret = DesktopIcon("preferences-desktop-peripherals", size);
  4089. }
  4090. else if (query == TDEGenericDeviceType::TextIO) {
  4091. ret = DesktopIcon("chardevice", size);
  4092. }
  4093. else if (query == TDEGenericDeviceType::Peripheral) {
  4094. ret = DesktopIcon("kcmpci", size);
  4095. }
  4096. else if (query == TDEGenericDeviceType::Backlight) {
  4097. ret = DesktopIcon("tdescreensaver", size); // FIXME
  4098. }
  4099. else if (query == TDEGenericDeviceType::Battery) {
  4100. ret = DesktopIcon("energy", size);
  4101. }
  4102. else if (query == TDEGenericDeviceType::PowerSupply) {
  4103. ret = DesktopIcon("energy", size);
  4104. }
  4105. else if (query == TDEGenericDeviceType::Dock) {
  4106. ret = DesktopIcon("kcmdevices", size); // FIXME
  4107. }
  4108. else if (query == TDEGenericDeviceType::ThermalSensor) {
  4109. ret = DesktopIcon("kcmdevices", size); // FIXME
  4110. }
  4111. else if (query == TDEGenericDeviceType::ThermalControl) {
  4112. ret = DesktopIcon("kcmdevices", size); // FIXME
  4113. }
  4114. else if (query == TDEGenericDeviceType::BlueTooth) {
  4115. ret = DesktopIcon("kcmpci", size); // FIXME
  4116. }
  4117. else if (query == TDEGenericDeviceType::Bridge) {
  4118. ret = DesktopIcon("kcmpci", size);
  4119. }
  4120. else if (query == TDEGenericDeviceType::Hub) {
  4121. ret = DesktopIcon("usb", size);
  4122. }
  4123. else if (query == TDEGenericDeviceType::Platform) {
  4124. ret = DesktopIcon("preferences-system", size);
  4125. }
  4126. else if (query == TDEGenericDeviceType::Cryptography) {
  4127. ret = DesktopIcon("password", size);
  4128. }
  4129. else if (query == TDEGenericDeviceType::CryptographicCard) {
  4130. ret = DesktopIcon("password", size);
  4131. }
  4132. else if (query == TDEGenericDeviceType::BiometricSecurity) {
  4133. ret = DesktopIcon("password", size);
  4134. }
  4135. else if (query == TDEGenericDeviceType::TestAndMeasurement) {
  4136. ret = DesktopIcon("kcmdevices", size);
  4137. }
  4138. else if (query == TDEGenericDeviceType::Timekeeping) {
  4139. ret = DesktopIcon("history", size);
  4140. }
  4141. else if (query == TDEGenericDeviceType::Event) {
  4142. ret = DesktopIcon("preferences-system", size);
  4143. }
  4144. else if (query == TDEGenericDeviceType::Input) {
  4145. ret = DesktopIcon("preferences-system", size);
  4146. }
  4147. else if (query == TDEGenericDeviceType::PNP) {
  4148. ret = DesktopIcon("preferences-system", size);
  4149. }
  4150. else if (query == TDEGenericDeviceType::OtherACPI) {
  4151. ret = DesktopIcon("kcmdevices", size); // FIXME
  4152. }
  4153. else if (query == TDEGenericDeviceType::OtherUSB) {
  4154. ret = DesktopIcon("usb", size);
  4155. }
  4156. else if (query == TDEGenericDeviceType::OtherMultimedia) {
  4157. ret = DesktopIcon("kcmsound", size);
  4158. }
  4159. else if (query == TDEGenericDeviceType::OtherPeripheral) {
  4160. ret = DesktopIcon("kcmpci", size);
  4161. }
  4162. else if (query == TDEGenericDeviceType::OtherSensor) {
  4163. ret = DesktopIcon("kcmdevices", size); // FIXME
  4164. }
  4165. else if (query == TDEGenericDeviceType::OtherVirtual) {
  4166. ret = DesktopIcon("preferences-system", size);
  4167. }
  4168. else {
  4169. ret = DesktopIcon("hwinfo", size);
  4170. }
  4171. return ret;
  4172. }
  4173. TDERootSystemDevice* TDEHardwareDevices::rootSystemDevice() {
  4174. TDEGenericDevice *hwdevice;
  4175. for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
  4176. if (hwdevice->type() == TDEGenericDeviceType::RootSystem) {
  4177. return dynamic_cast<TDERootSystemDevice*>(hwdevice);
  4178. }
  4179. }
  4180. return 0;
  4181. }
  4182. TQString TDEHardwareDevices::bytesToFriendlySizeString(double bytes) {
  4183. TQString prettystring;
  4184. prettystring = TQString("%1B").arg(bytes);
  4185. if (bytes > 1024) {
  4186. bytes = bytes / 1024;
  4187. prettystring = TQString("%1KB").arg(bytes, 0, 'f', 1);
  4188. }
  4189. if (bytes > 1024) {
  4190. bytes = bytes / 1024;
  4191. prettystring = TQString("%1MB").arg(bytes, 0, 'f', 1);
  4192. }
  4193. if (bytes > 1024) {
  4194. bytes = bytes / 1024;
  4195. prettystring = TQString("%1GB").arg(bytes, 0, 'f', 1);
  4196. }
  4197. if (bytes > 1024) {
  4198. bytes = bytes / 1024;
  4199. prettystring = TQString("%1TB").arg(bytes, 0, 'f', 1);
  4200. }
  4201. if (bytes > 1024) {
  4202. bytes = bytes / 1024;
  4203. prettystring = TQString("%1PB").arg(bytes, 0, 'f', 1);
  4204. }
  4205. if (bytes > 1024) {
  4206. bytes = bytes / 1024;
  4207. prettystring = TQString("%1EB").arg(bytes, 0, 'f', 1);
  4208. }
  4209. if (bytes > 1024) {
  4210. bytes = bytes / 1024;
  4211. prettystring = TQString("%1ZB").arg(bytes, 0, 'f', 1);
  4212. }
  4213. if (bytes > 1024) {
  4214. bytes = bytes / 1024;
  4215. prettystring = TQString("%1YB").arg(bytes, 0, 'f', 1);
  4216. }
  4217. return prettystring;
  4218. }
  4219. TDEGenericHardwareList TDEHardwareDevices::listByDeviceClass(TDEGenericDeviceType::TDEGenericDeviceType cl) {
  4220. TDEGenericHardwareList ret;
  4221. ret.setAutoDelete(false);
  4222. TDEGenericDevice *hwdevice;
  4223. for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
  4224. if (hwdevice->type() == cl) {
  4225. ret.append(hwdevice);
  4226. }
  4227. }
  4228. return ret;
  4229. }
  4230. TDEGenericHardwareList TDEHardwareDevices::listAllPhysicalDevices() {
  4231. TDEGenericHardwareList ret = m_deviceList;
  4232. ret.setAutoDelete(false);
  4233. return ret;
  4234. }
  4235. #include "tdehardwaredevices.moc"