From 92c24a24c59ff6787a4ea7bc14f1812491f3cef2 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 8 Apr 2012 21:28:37 -0500 Subject: Fix USB device lookup Add proper Event and Input device handlers Add Sensor support --- tdecore/hwlibdata/pnpdev/pnp.ids | 13 +-- tdecore/tdehardwaredevices.cpp | 177 ++++++++++++++++++++++++++++++++++++--- tdecore/tdehardwaredevices.h | 48 +++++++++++ 3 files changed, 221 insertions(+), 17 deletions(-) (limited to 'tdecore') diff --git a/tdecore/hwlibdata/pnpdev/pnp.ids b/tdecore/hwlibdata/pnpdev/pnp.ids index 8fabfe093..bf4a3ce01 100644 --- a/tdecore/hwlibdata/pnpdev/pnp.ids +++ b/tdecore/hwlibdata/pnpdev/pnp.ids @@ -80,13 +80,14 @@ PNP0802 Microsoft® Sound System compatible device PNP0900 VGA Compatible Display Controller PNP09FF Plug and Play Monitor (VESA DDC) -PNP0A00 ISA Bus -PNP0A01 EISA Bus -PNP0A02 MCA Bus -PNP0A03 PCI Bus +PNP0A00 ISA Root Bus +PNP0A01 EISA Root Bus +PNP0A02 MCA Root Bus +PNP0A03 PCI Root Bus PNP0A04 VESA/VL Bus -PNP0A05 Generic ACPI Bus -PNP0A06 Generic ACPI Extended-IO Bus (EIO bus) +PNP0A05 Generic ACPI Root Bus +PNP0A06 Generic ACPI Extended-IO Root Bus (EIO Root Bus) +PNP0A08 PCI Express Root Bus PNP0800 AT-style Speaker PNP0B00 AT Real-Time Clock diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp index 24afe695f..e62abeb37 100644 --- a/tdecore/tdehardwaredevices.cpp +++ b/tdecore/tdehardwaredevices.cpp @@ -54,6 +54,15 @@ // This command will greatly help when attempting to find properties to distinguish one device from another // udevadm info --query=all --path=/sys/.... +TDESensorCluster::TDESensorCluster() { + label = TQString::null; + current = -1; + minimum = -1; + maximum = -1; + warning = -1; + critical = -1; +} + TDEGenericDevice::TDEGenericDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) { m_deviceType = dt; m_deviceName = dn; @@ -253,12 +262,18 @@ TQString TDEGenericDevice::friendlyName() { m_friendlyName = KGlobal::hardwareDevices()->findUSBDeviceName(m_vendorID, m_modelID, m_subvendorID, m_submodelID); } else { - TQString pnpgentype = systemPath(); - pnpgentype.remove(0, pnpgentype.findRev("/")+1); + TQString acpigentype = systemPath(); + acpigentype.remove(0, acpigentype.findRev("/")+1); + TQString pnpgentype = acpigentype; pnpgentype.truncate(pnpgentype.find(":")); if (pnpgentype.startsWith("PNP")) { m_friendlyName = KGlobal::hardwareDevices()->findPNPDeviceName(pnpgentype); } + else if (acpigentype.startsWith("device:")) { + acpigentype.remove(0, acpigentype.findRev(":")+1); + acpigentype.prepend("0x"); + m_friendlyName = i18n("ACPI Node %1").arg(acpigentype.toUInt(0,0)); + } } } @@ -268,6 +283,24 @@ TQString TDEGenericDevice::friendlyName() { if (type() == TDEGenericDeviceType::CPU) { m_friendlyName = name(); } + else if (type() == TDEGenericDeviceType::Event) { + // Use parent node name + if (m_parentDevice) { + return m_parentDevice->friendlyName(); + } + else { + m_friendlyName = i18n("Generic Event Device"); + } + } + else if (type() == TDEGenericDeviceType::Input) { + // Use parent node name + if (m_parentDevice) { + return m_parentDevice->friendlyName(); + } + else { + m_friendlyName = i18n("Generic Input Device"); + } + } // Guess by driver else if (!m_deviceDriver.isNull()) { TQString friendlyDriverName = m_deviceDriver.lower(); @@ -838,6 +871,20 @@ void TDECPUDevice::setAvailableFrequencies(TQStringList af) { m_frequencies = af; } +TDESensorDevice::TDESensorDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn) { +} + +TDESensorDevice::~TDESensorDevice() { +} + +TDESensorClusterMap TDESensorDevice::values() { + return m_sensorValues; +} + +void TDESensorDevice::setValues(TDESensorClusterMap cl) { + m_sensorValues = cl; +} + TDEHardwareDevices::TDEHardwareDevices() { // Initialize members pci_id_map = 0; @@ -1526,6 +1573,12 @@ TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQStr else if (query == "Platform") { ret = TDEGenericDeviceType::Platform; } + else if (query == "Event") { + ret = TDEGenericDeviceType::Event; + } + else if (query == "Input") { + ret = TDEGenericDeviceType::Input; + } else if (query == "PNP") { ret = TDEGenericDeviceType::PNP; } @@ -1844,12 +1897,13 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD // Go after it manually... if (devicevendorid.isNull() || devicemodelid.isNull()) { if (devicemodalias != TQString::null) { - int vloc = devicemodalias.find("v"); - int dloc = devicemodalias.find("d", vloc); - int svloc = devicemodalias.find("sv"); - int sdloc = devicemodalias.find("sd", vloc); // For added fun the device string lengths differ between pci and usb if (devicemodalias.startsWith("pci")) { + int vloc = devicemodalias.find("v"); + int dloc = devicemodalias.find("d", vloc); + int svloc = devicemodalias.find("sv"); + int sdloc = devicemodalias.find("sd", vloc); + devicevendorid = devicemodalias.mid(vloc+1, 8).lower(); devicemodelid = devicemodalias.mid(dloc+1, 8).lower(); if (svloc != -1) { @@ -1862,6 +1916,11 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD devicesubmodelid.remove(0,4); } if (devicemodalias.startsWith("usb")) { + int vloc = devicemodalias.find("v"); + int dloc = devicemodalias.find("p", vloc); + int svloc = devicemodalias.find("sv"); + int sdloc = devicemodalias.find("sp", vloc); + devicevendorid = devicemodalias.mid(vloc+1, 4).lower(); devicemodelid = devicemodalias.mid(dloc+1, 4).lower(); if (svloc != -1) { @@ -1901,11 +1960,43 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD // Classify generic device type and create appropriate object - // Pull out all event special devices and stuff them under Platform + // Pull out all event special devices and stuff them under Event TQString syspath_tail = systempath.lower(); syspath_tail.remove(0, syspath_tail.findRev("/")+1); if (syspath_tail.startsWith("event")) { - if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Platform); + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Event); + } + // Pull out all input special devices and stuff them under Input + if (syspath_tail.startsWith("input")) { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Input); + } + + // Check for keyboard + // Linux doesn't actually ID the keyboard device itself as such, it instead IDs the input device that is underneath the actual keyboard itseld + // Therefore we need to scan /input/input* for the ID_INPUT_KEYBOARD attribute + bool is_keyboard = false; + TQString inputtopdirname = udev_device_get_syspath(dev); + inputtopdirname.append("/input/"); + TQDir inputdir(inputtopdirname); + inputdir.setFilter(TQDir::All); + const TQFileInfoList *dirlist = inputdir.entryInfoList(); + if (dirlist) { + TQFileInfoListIterator inputdirsit(*dirlist); + TQFileInfo *dirfi; + while ( (dirfi = inputdirsit.current()) != 0 ) { + if ((dirfi->fileName() != ".") && (dirfi->fileName() != "..")) { + struct udev_device *slavedev; + slavedev = udev_device_new_from_syspath(m_udevStruct, (inputtopdirname + dirfi->fileName()).ascii()); + if (udev_device_get_property_value(slavedev, "ID_INPUT_KEYBOARD") != 0) { + is_keyboard = true; + } + udev_device_unref(slavedev); + } + ++inputdirsit; + } + } + if (is_keyboard) { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Keyboard); } // Classify specific known devices @@ -1942,7 +2033,7 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Power); } else if (pnpgentype == "PNP0C11") { - if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalSensor); + if (!device) device = new TDESensorDevice(TDEGenericDeviceType::ThermalSensor); } else { if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI); @@ -1993,7 +2084,7 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD else if (devicesubsystem == "hwmon") { // FIXME // This might pick up thermal sensors - if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherSensor); + if (!device) device = new TDESensorDevice(TDEGenericDeviceType::OtherSensor); } } @@ -2062,7 +2153,8 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::PNP); } if ((devicesubsystem == "hid") - || (devicesubsystem == "hidraw")) { + || (devicesubsystem == "hidraw") + || (devicesubsystem == "usbhid")) { if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID); } if (devicesubsystem == "power_supply") { @@ -2424,6 +2516,57 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD devicenode.remove(0, devicenode.findRev("/")+1); } + if ((device->type() == TDEGenericDeviceType::OtherSensor) || (device->type() == TDEGenericDeviceType::ThermalSensor)) { + // Populate all sensor values + TDESensorClusterMap sensors; + TQString valuesnodename = systempath + "/"; + TQDir valuesdir(valuesnodename); + valuesdir.setFilter(TQDir::All); + TQString nodename; + const TQFileInfoList *dirlist = valuesdir.entryInfoList(); + if (dirlist) { + TQFileInfoListIterator valuesdirit(*dirlist); + TQFileInfo *dirfi; + while ( (dirfi = valuesdirit.current()) != 0 ) { + nodename = dirfi->fileName(); + if (nodename.contains("_")) { + TQFile file( valuesnodename + nodename ); + if ( file.open( IO_ReadOnly ) ) { + TQTextStream stream( &file ); + TQString line; + line = stream.readLine(); + TQStringList sensornodelist = TQStringList::split("_", nodename); + TQString sensornodename = *(sensornodelist.at(0)); + TQString sensornodetype = *(sensornodelist.at(1)); + if (sensornodetype == "label") { + sensors[sensornodename].label = line; + } + if (sensornodetype == "input") { + sensors[sensornodename].current = line.toDouble(); + } + if (sensornodetype == "min") { + sensors[sensornodename].minimum = line.toDouble(); + } + if (sensornodetype == "max") { + sensors[sensornodename].maximum = line.toDouble(); + } + if (sensornodetype == "warn") { + sensors[sensornodename].warning = line.toDouble(); + } + if (sensornodetype == "crit") { + sensors[sensornodename].critical = line.toDouble(); + } + file.close(); + } + } + ++valuesdirit; + } + } + + TDESensorDevice* sdevice = dynamic_cast(device); + sdevice->setValues(sensors); + } + // Set basic device information again, as some information may have changed device->setName(devicename); device->setDeviceNode(devicenode); @@ -2994,6 +3137,12 @@ TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDevic else if (query == TDEGenericDeviceType::Platform) { ret = i18n("Platform"); } + else if (query == TDEGenericDeviceType::Event) { + ret = i18n("Platform Event"); + } + else if (query == TDEGenericDeviceType::Input) { + ret = i18n("Platform Input"); + } else if (query == TDEGenericDeviceType::PNP) { ret = i18n("Plug and Play"); } @@ -3122,6 +3271,12 @@ TQPixmap TDEHardwareDevices::getDeviceTypeIconFromType(TDEGenericDeviceType::TDE else if (query == TDEGenericDeviceType::Platform) { ret = DesktopIcon("kcmsystem", size); } + else if (query == TDEGenericDeviceType::Event) { + ret = DesktopIcon("kcmsystem", size); + } + else if (query == TDEGenericDeviceType::Input) { + ret = DesktopIcon("kcmsystem", size); + } else if (query == TDEGenericDeviceType::PNP) { ret = DesktopIcon("kcmsystem", size); } diff --git a/tdecore/tdehardwaredevices.h b/tdecore/tdehardwaredevices.h index 495a6a761..0073cb454 100644 --- a/tdecore/tdehardwaredevices.h +++ b/tdecore/tdehardwaredevices.h @@ -74,6 +74,8 @@ enum TDEGenericDeviceType { ThermalControl, Bridge, Platform, + Event, + Input, PNP, OtherACPI, OtherUSB, @@ -169,6 +171,22 @@ inline TDEDiskDeviceStatus operator~(TDEDiskDeviceStatus a) } }; +class TDECORE_EXPORT TDESensorCluster +{ + public: + /** + * Constructor. + */ + TDESensorCluster(); + + TQString label; + double current; + double minimum; + double maximum; + double warning; + double critical; +}; + class TDECORE_EXPORT TDEGenericDevice { public: @@ -741,6 +759,36 @@ class TDECORE_EXPORT TDECPUDevice : public TDEGenericDevice TQStringList m_frequencies; }; +typedef TQMap TDESensorClusterMap; + +class TDECORE_EXPORT TDESensorDevice : public TDEGenericDevice +{ + public: + /** + * Constructor. + * @param Device type + */ + TDESensorDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn=TQString::null); + + /** + * Destructor. + */ + ~TDESensorDevice(); + + /** + * @return a TDESensorClusterMap with the current sensor values + */ + TDESensorClusterMap values(); + + /** + * @param a TDESensorClusterMap with the current sensor values + */ + void setValues(TDESensorClusterMap cl); + + private: + TDESensorClusterMap m_sensorValues; +}; + typedef TQPtrList TDEGenericHardwareList; typedef TQMap TDEDeviceIDMap; -- cgit v1.2.1