Add ability to read switch states

pull/16/head
Timothy Pearson 13 years ago
parent c1fcbb1852
commit 11b3e92216

@ -44,6 +44,9 @@
// Backlight devices
#include <linux/fb.h>
// Input devices
#include <linux/input.h>
// Network devices
#include <sys/types.h>
#include <ifaddrs.h>
@ -53,7 +56,6 @@
#include <sys/socket.h>
#include <netdb.h>
// BEGIN BLOCK
// Copied from include/linux/genhd.h
#define GENHD_FL_REMOVABLE 1
@ -81,6 +83,8 @@ unsigned int reverse_bits(register unsigned int x)
return((x >> 16) | (x << 16));
}
#define BIT_IS_SET(bits, n) (bits[n >> 3] & (1 << (n & 0x7)))
TDESensorCluster::TDESensorCluster() {
label = TQString::null;
current = -1;
@ -1501,9 +1505,13 @@ void TDEMonitorDevice::internalSetPowerLevel(TDEDisplayPowerLevel::TDEDisplayPow
}
TDEEventDevice::TDEEventDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn) {
m_fd = -1;
}
TDEEventDevice::~TDEEventDevice() {
if (m_fd >= 0) {
close(m_fd);
}
}
TDEEventDeviceType::TDEEventDeviceType TDEEventDevice::eventType() {
@ -1514,6 +1522,89 @@ void TDEEventDevice::internalSetEventType(TDEEventDeviceType::TDEEventDeviceType
m_eventType = et;
}
TDESwitchType::TDESwitchType TDEEventDevice::providedSwitches() {
return m_providedSwitches;
}
void TDEEventDevice::internalSetProvidedSwitches(TDESwitchType::TDESwitchType sl) {
m_providedSwitches = sl;
}
TDESwitchType::TDESwitchType TDEEventDevice::activeSwitches() {
return m_switchActive;
}
void TDEEventDevice::internalSetActiveSwitches(TDESwitchType::TDESwitchType sl) {
m_switchActive = sl;
}
// Keep this in sync with the TDESwitchType definition in the header
TQStringList TDEEventDevice::friendlySwitchList(TDESwitchType::TDESwitchType switches) {
TQStringList ret;
if (switches & TDESwitchType::Lid) {
ret.append(i18n("Lid Switch"));
}
if (switches & TDESwitchType::TabletMode) {
ret.append(i18n("Tablet Mode"));
}
if (switches & TDESwitchType::HeadphoneInsert) {
ret.append(i18n("Headphone Inserted"));
}
if (switches & TDESwitchType::RFKill) {
ret.append(i18n("Radio Frequency Device Kill Switch"));
}
if (switches & TDESwitchType::Radio) {
ret.append(i18n("Enable Radio"));
}
if (switches & TDESwitchType::MicrophoneInsert) {
ret.append(i18n("Microphone Inserted"));
}
if (switches & TDESwitchType::Dock) {
ret.append(i18n("Docked"));
}
if (switches & TDESwitchType::LineOutInsert) {
ret.append(i18n("Line Out Inserted"));
}
if (switches & TDESwitchType::JackPhysicalInsert) {
ret.append(i18n("Physical Jack Inserted"));
}
if (switches & TDESwitchType::VideoOutInsert) {
ret.append(i18n("Video Out Inserted"));
}
if (switches & TDESwitchType::CameraLensCover) {
ret.append(i18n("Camera Lens Cover"));
}
if (switches & TDESwitchType::KeypadSlide) {
ret.append(i18n("Keypad Slide"));
}
if (switches & TDESwitchType::FrontProximity) {
ret.append(i18n("Front Proximity"));
}
if (switches & TDESwitchType::RotateLock) {
ret.append(i18n("Rotate Lock"));
}
if (switches & TDESwitchType::LineInInsert) {
ret.append(i18n("Line In Inserted"));
}
return ret;
}
TDEInputDevice::TDEInputDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn) {
}
TDEInputDevice::~TDEInputDevice() {
}
TDEInputDeviceType::TDEInputDeviceType TDEInputDevice::inputType() {
return m_inputType;
}
void TDEInputDevice::internalSetInputType(TDEInputDeviceType::TDEInputDeviceType it) {
m_inputType = it;
}
TDEHardwareDevices::TDEHardwareDevices() {
// Initialize members
pci_id_map = 0;
@ -1653,6 +1744,19 @@ TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
return 0;
}
TDEGenericDevice* TDEHardwareDevices::findByUniqueID(TQString uid) {
TDEGenericDevice *hwdevice;
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
TDEGenericHardwareList devList = listAllPhysicalDevices();
for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
if (hwdevice->uniqueID() == uid) {
return hwdevice;
}
}
return 0;
}
TDEGenericDevice* TDEHardwareDevices::findByDeviceNode(TQString devnode) {
TDEGenericDevice *hwdevice;
for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
@ -1919,7 +2023,7 @@ void TDEHardwareDevices::processStatelessDevices() {
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
TDEGenericHardwareList devList = listAllPhysicalDevices();
for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
if ((hwdevice->type() == TDEGenericDeviceType::RootSystem) || (hwdevice->type() == TDEGenericDeviceType::Network) || (hwdevice->type() == TDEGenericDeviceType::OtherSensor)) {
if ((hwdevice->type() == TDEGenericDeviceType::RootSystem) || (hwdevice->type() == TDEGenericDeviceType::Network) || (hwdevice->type() == TDEGenericDeviceType::OtherSensor) || (hwdevice->type() == TDEGenericDeviceType::Event)) {
rescanDeviceInformation(hwdevice);
emit hardwareUpdated(hwdevice);
}
@ -2553,22 +2657,58 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDeviceByExternalRules(udev_
TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice, bool force_full_classification) {
// Classify device and create TDEHW device object
TQString devicename(udev_device_get_sysname(dev));
TQString devicetype(udev_device_get_devtype(dev));
TQString devicedriver(udev_device_get_driver(dev));
TQString devicesubsystem(udev_device_get_subsystem(dev));
TQString devicenode(udev_device_get_devnode(dev));
TQString systempath(udev_device_get_syspath(dev));
TQString devicevendorid(udev_device_get_property_value(dev, "ID_VENDOR_ID"));
TQString devicemodelid(udev_device_get_property_value(dev, "ID_MODEL_ID"));
TQString devicevendoridenc(udev_device_get_property_value(dev, "ID_VENDOR_ENC"));
TQString devicemodelidenc(udev_device_get_property_value(dev, "ID_MODEL_ENC"));
TQString devicesubvendorid(udev_device_get_property_value(dev, "ID_SUBVENDOR_ID"));
TQString devicesubmodelid(udev_device_get_property_value(dev, "ID_SUBMODEL_ID"));
TQString devicetypestring(udev_device_get_property_value(dev, "ID_TYPE"));
TQString devicetypestring_alt(udev_device_get_property_value(dev, "DEVTYPE"));
TQString devicepciclass(udev_device_get_property_value(dev, "PCI_CLASS"));
TQString devicename;
TQString devicetype;
TQString devicedriver;
TQString devicesubsystem;
TQString devicenode;
TQString systempath;
TQString devicevendorid;
TQString devicemodelid;
TQString devicevendoridenc;
TQString devicemodelidenc;
TQString devicesubvendorid;
TQString devicesubmodelid;
TQString devicetypestring;
TQString devicetypestring_alt;
TQString devicepciclass;
TDEGenericDevice* device = existingdevice;
if (dev) {
devicename = (udev_device_get_sysname(dev));
devicetype = (udev_device_get_devtype(dev));
devicedriver = (udev_device_get_driver(dev));
devicesubsystem = (udev_device_get_subsystem(dev));
devicenode = (udev_device_get_devnode(dev));
systempath = (udev_device_get_syspath(dev));
devicevendorid = (udev_device_get_property_value(dev, "ID_VENDOR_ID"));
devicemodelid = (udev_device_get_property_value(dev, "ID_MODEL_ID"));
devicevendoridenc = (udev_device_get_property_value(dev, "ID_VENDOR_ENC"));
devicemodelidenc = (udev_device_get_property_value(dev, "ID_MODEL_ENC"));
devicesubvendorid = (udev_device_get_property_value(dev, "ID_SUBVENDOR_ID"));
devicesubmodelid = (udev_device_get_property_value(dev, "ID_SUBMODEL_ID"));
devicetypestring = (udev_device_get_property_value(dev, "ID_TYPE"));
devicetypestring_alt = (udev_device_get_property_value(dev, "DEVTYPE"));
devicepciclass = (udev_device_get_property_value(dev, "PCI_CLASS"));
}
else {
if (device) {
devicename = device->name();
devicetype = device->m_udevtype;
devicedriver = device->deviceDriver();
devicesubsystem = device->subsystem();
devicenode = device->deviceNode();
systempath = device->systemPath();
devicevendorid = device->vendorID();
devicemodelid = device->modelID();
devicevendoridenc = device->vendorEncoded();
devicemodelidenc = device->modelEncoded();
devicesubvendorid = device->subVendorID();
devicesubmodelid = device->subModelID();
devicetypestring = device->m_udevdevicetypestring;
devicetypestring_alt = device->udevdevicetypestring_alt;
devicepciclass = device->PCIClass();
}
}
// FIXME
// Only a small subset of devices are classified right now
@ -2676,7 +2816,7 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
}
// Pull out all input special devices and stuff them under Input
if (syspath_tail.startsWith("input")) {
if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Input);
if (!device) device = new TDEInputDevice(TDEGenericDeviceType::Input);
}
// Check for keyboard
@ -3753,7 +3893,7 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
// Get current hibernation method
line.truncate(line.findRev("]"));
line.remove(0, line.findRev("[")+1);
TDESystemHibernationMethod::TDESystemHibernationMethod hibernationmethod = TDESystemHibernationMethod::None;
TDESystemHibernationMethod::TDESystemHibernationMethod hibernationmethod = TDESystemHibernationMethod::Unsupported;
if (line.contains("platform")) {
hibernationmethod = TDESystemHibernationMethod::Platform;
}
@ -3781,8 +3921,11 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
}
}
// NOTE
// Keep these two handlers (Event and Input) in sync!
if (device->type() == TDEGenericDeviceType::Event) {
// Try to obtain as much generic information about this event device as possible
// Try to obtain as much type information about this event device as possible
TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
if (edevice->systemPath().contains("PNP0C0D")) {
edevice->internalSetEventType(TDEEventDeviceType::ACPILidSwitch);
@ -3798,6 +3941,135 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
}
}
if (device->type() == TDEGenericDeviceType::Input) {
// Try to obtain as much type information about this input device as possible
TDEInputDevice* idevice = dynamic_cast<TDEInputDevice*>(device);
if (idevice->systemPath().contains("PNP0C0D")) {
idevice->internalSetInputType(TDEInputDeviceType::ACPILidSwitch);
}
else if (idevice->systemPath().contains("PNP0C0E")) {
idevice->internalSetInputType(TDEInputDeviceType::ACPISleepButton);
}
else if (idevice->systemPath().contains("PNP0C0C")) {
idevice->internalSetInputType(TDEInputDeviceType::ACPIPowerButton);
}
else {
idevice->internalSetInputType(TDEInputDeviceType::Unknown);
}
}
if (device->type() == TDEGenericDeviceType::Event) {
// Try to obtain as much specific information about this event device as possible
TDEEventDevice* edevice = dynamic_cast<TDEEventDevice*>(device);
int r;
char switches[SW_CNT];
// Figure out which switch types are supported, if any
TDESwitchType::TDESwitchType supportedSwitches = TDESwitchType::Null;
if (edevice->m_fd < 0) {
edevice->m_fd = open(edevice->deviceNode().ascii(), O_RDONLY);
}
r = ioctl(edevice->m_fd, EVIOCGBIT(EV_SW, sizeof(switches)), switches);
if (r > 0) {
if (BIT_IS_SET(switches, SW_LID)) {
supportedSwitches = supportedSwitches | TDESwitchType::Lid;
}
if (BIT_IS_SET(switches, SW_TABLET_MODE)) {
supportedSwitches = supportedSwitches | TDESwitchType::TabletMode;
}
if (BIT_IS_SET(switches, SW_RFKILL_ALL)) {
supportedSwitches = supportedSwitches | TDESwitchType::RFKill;
}
if (BIT_IS_SET(switches, SW_RADIO)) {
supportedSwitches = supportedSwitches | TDESwitchType::Radio;
}
if (BIT_IS_SET(switches, SW_MICROPHONE_INSERT)) {
supportedSwitches = supportedSwitches | TDESwitchType::MicrophoneInsert;
}
if (BIT_IS_SET(switches, SW_DOCK)) {
supportedSwitches = supportedSwitches | TDESwitchType::Dock;
}
if (BIT_IS_SET(switches, SW_LINEOUT_INSERT)) {
supportedSwitches = supportedSwitches | TDESwitchType::LineOutInsert;
}
if (BIT_IS_SET(switches, SW_JACK_PHYSICAL_INSERT)) {
supportedSwitches = supportedSwitches | TDESwitchType::JackPhysicalInsert;
}
if (BIT_IS_SET(switches, SW_VIDEOOUT_INSERT)) {
supportedSwitches = supportedSwitches | TDESwitchType::VideoOutInsert;
}
#if 0 // Some old kernels don't provide these defines... [FIXME]
if (BIT_IS_SET(switches, SW_CAMERA_LENS_COVER)) {
supportedSwitches = supportedSwitches | TDESwitchType::CameraLensCover;
}
if (BIT_IS_SET(switches, SW_KEYPAD_SLIDE)) {
supportedSwitches = supportedSwitches | TDESwitchType::KeypadSlide;
}
if (BIT_IS_SET(switches, SW_FRONT_PROXIMITY)) {
supportedSwitches = supportedSwitches | TDESwitchType::FrontProximity;
}
if (BIT_IS_SET(switches, SW_ROTATE_LOCK)) {
supportedSwitches = supportedSwitches | TDESwitchType::RotateLock;
}
if (BIT_IS_SET(switches, SW_LINEIN_INSERT)) {
supportedSwitches = supportedSwitches | TDESwitchType::LineInInsert;
}
#endif
}
edevice->internalSetProvidedSwitches(supportedSwitches);
// Figure out which switch types are active, if any
TDESwitchType::TDESwitchType activeSwitches = TDESwitchType::Null;
r = ioctl(edevice->m_fd, EVIOCGSW(sizeof(switches)), switches);
if (r > 0) {
if (BIT_IS_SET(switches, SW_LID)) {
activeSwitches = activeSwitches | TDESwitchType::Lid;
}
if (BIT_IS_SET(switches, SW_TABLET_MODE)) {
activeSwitches = activeSwitches | TDESwitchType::TabletMode;
}
if (BIT_IS_SET(switches, SW_RFKILL_ALL)) {
activeSwitches = activeSwitches | TDESwitchType::RFKill;
}
if (BIT_IS_SET(switches, SW_RADIO)) {
activeSwitches = activeSwitches | TDESwitchType::Radio;
}
if (BIT_IS_SET(switches, SW_MICROPHONE_INSERT)) {
activeSwitches = activeSwitches | TDESwitchType::MicrophoneInsert;
}
if (BIT_IS_SET(switches, SW_DOCK)) {
activeSwitches = activeSwitches | TDESwitchType::Dock;
}
if (BIT_IS_SET(switches, SW_LINEOUT_INSERT)) {
activeSwitches = activeSwitches | TDESwitchType::LineOutInsert;
}
if (BIT_IS_SET(switches, SW_JACK_PHYSICAL_INSERT)) {
activeSwitches = activeSwitches | TDESwitchType::JackPhysicalInsert;
}
if (BIT_IS_SET(switches, SW_VIDEOOUT_INSERT)) {
activeSwitches = activeSwitches | TDESwitchType::VideoOutInsert;
}
#if 0 // Some old kernels don't provide these defines... [FIXME]
if (BIT_IS_SET(switches, SW_CAMERA_LENS_COVER)) {
activeSwitches = activeSwitches | TDESwitchType::CameraLensCover;
}
if (BIT_IS_SET(switches, SW_KEYPAD_SLIDE)) {
activeSwitches = activeSwitches | TDESwitchType::KeypadSlide;
}
if (BIT_IS_SET(switches, SW_FRONT_PROXIMITY)) {
activeSwitches = activeSwitches | TDESwitchType::FrontProximity;
}
if (BIT_IS_SET(switches, SW_ROTATE_LOCK)) {
activeSwitches = activeSwitches | TDESwitchType::RotateLock;
}
if (BIT_IS_SET(switches, SW_LINEIN_INSERT)) {
activeSwitches = activeSwitches | TDESwitchType::LineInInsert;
}
#endif
}
edevice->internalSetActiveSwitches(activeSwitches);
}
// Root devices are still special
if ((device->type() == TDEGenericDeviceType::Root) || (device->type() == TDEGenericDeviceType::RootSystem)) {
systempath = device->systemPath();
@ -3817,6 +4089,11 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
device->internalSetSubsystem(devicesubsystem);
device->internalSetPCIClass(devicepciclass);
// Internal use only!
device->m_udevtype = devicetype;
device->m_udevdevicetypestring = devicetypestring;
device->udevdevicetypestring_alt = devicetypestring_alt;
return device;
}

@ -485,6 +485,9 @@ class TDECORE_EXPORT TDEGenericDevice
// Internal use only!
TQStringList m_externalSubtype;
TQString m_externalRulesFile;
TQString m_udevtype;
TQString m_udevdevicetypestring;
TQString udevdevicetypestring_alt;
friend class TDEHardwareDevices;
};
@ -1484,7 +1487,7 @@ enum TDESystemPowerState {
namespace TDESystemHibernationMethod {
enum TDESystemHibernationMethod {
None,
Unsupported,
Platform,
Shutdown,
Reboot,
@ -1622,6 +1625,43 @@ enum TDEEventDeviceType {
};
};
// Keep friendlySwitchList() in tdehardwaredevices.cpp in sync with this enum
namespace TDESwitchType {
enum TDESwitchType {
Null = 0x00000000,
Lid = 0x00000001,
TabletMode = 0x00000002,
HeadphoneInsert = 0x00000004,
RFKill = 0x00000008,
Radio = 0x00000010,
MicrophoneInsert = 0x00000020,
Dock = 0x00000040,
LineOutInsert = 0x00000080,
JackPhysicalInsert = 0x00000100,
VideoOutInsert = 0x00000200,
CameraLensCover = 0x00000400,
KeypadSlide = 0x00000800,
FrontProximity = 0x00001000,
RotateLock = 0x00002000,
LineInInsert = 0x00004000
};
inline TDESwitchType operator|(TDESwitchType a, TDESwitchType b)
{
return static_cast<TDESwitchType>(static_cast<int>(a) | static_cast<int>(b));
}
inline TDESwitchType operator&(TDESwitchType a, TDESwitchType b)
{
return static_cast<TDESwitchType>(static_cast<int>(a) & static_cast<int>(b));
}
inline TDESwitchType operator~(TDESwitchType a)
{
return static_cast<TDESwitchType>(~static_cast<int>(a));
}
};
class TDECORE_EXPORT TDEEventDevice : public TDEGenericDevice
{
public:
@ -1641,6 +1681,22 @@ class TDECORE_EXPORT TDEEventDevice : public TDEGenericDevice
*/
TDEEventDeviceType::TDEEventDeviceType eventType();
/**
* @return a TDESwitchType::TDESwitchType with all switches provided by this device
*/
TDESwitchType::TDESwitchType providedSwitches();
/**
* @return a TDESwitchType::TDESwitchType with all active switches provided by this device
*/
TDESwitchType::TDESwitchType activeSwitches();
/**
* @param switches a TDESwitchType::TDESwitchType with any switch flags set
* @return a TQStringList with friendly names for all set switch flags
*/
static TQStringList friendlySwitchList(TDESwitchType::TDESwitchType switches);
protected:
/**
* @param et a TDEEventDeviceType::TDEEventDeviceType with the event device type, if known
@ -1648,12 +1704,69 @@ class TDECORE_EXPORT TDEEventDevice : public TDEGenericDevice
*/
void internalSetEventType(TDEEventDeviceType::TDEEventDeviceType et);
/**
* @param sl a TDESwitchType::TDESwitchType with all switches provided by this device
* @internal
*/
void internalSetProvidedSwitches(TDESwitchType::TDESwitchType sl);
/**
* @param sl a TDESwitchType::TDESwitchType with all active switches provided by this device
* @internal
*/
void internalSetActiveSwitches(TDESwitchType::TDESwitchType sl);
private:
TDEEventDeviceType::TDEEventDeviceType m_eventType;
TDESwitchType::TDESwitchType m_providedSwitches;
TDESwitchType::TDESwitchType m_switchActive;
int m_fd;
friend class TDEHardwareDevices;
};
namespace TDEInputDeviceType {
enum TDEInputDeviceType {
Unknown,
ACPILidSwitch,
ACPISleepButton,
ACPIPowerButton,
Other = 0x80000000
};
};
class TDECORE_EXPORT TDEInputDevice : public TDEGenericDevice
{
public:
/**
* Constructor.
* @param Device type
*/
TDEInputDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn=TQString::null);
/**
* Destructor.
*/
~TDEInputDevice();
/**
* @return a TDEInputDeviceType::TDEInputDeviceType with the input device type, if known
*/
TDEInputDeviceType::TDEInputDeviceType inputType();
protected:
/**
* @param it a TDEInputDeviceType::TDEInputDeviceType with the input device type, if known
* @internal
*/
void internalSetInputType(TDEInputDeviceType::TDEInputDeviceType it);
private:
TDEInputDeviceType::TDEInputDeviceType m_inputType;
friend class TDEHardwareDevices;
};
typedef TQPtrList<TDEGenericDevice> TDEGenericHardwareList;
typedef TQMap<TQString, TQString> TDEDeviceIDMap;
@ -1707,6 +1820,12 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
*/
TDEGenericDevice* findBySystemPath(TQString syspath);
/**
* Return the device with unique ID @arg uid, or 0 if no device exists for that uid
* @return TDEGenericDevice
*/
TDEGenericDevice* findByUniqueID(TQString uid);
/**
* Return the device with device node @arg devnode, or 0 if no device exists at that node
* @return TDEGenericDevice

Loading…
Cancel
Save