[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [Gluon] b0234ea: Integrate libudev mechanism into the input subsyst
From: Laszlo Papp <djszapi () archlinux ! us>
Date: 2010-11-08 17:35:13
Message-ID: 20101108173513.78D45A60A6 () git ! kde ! org
[Download RAW message or body]
commit b0234ea92e5ce54ea900c07a388b2b5735982203
branch master
Author: Laszlo Papp <djszapi@archlinux.us>
Date: Mon Nov 8 19:31:06 2010 -0800
Integrate libudev mechanism into the input subsystem and linker option.
diff --git a/input/CMakeLists.txt b/input/CMakeLists.txt
index 96e0a0e..48b71a9 100644
--- a/input/CMakeLists.txt
+++ b/input/CMakeLists.txt
@@ -158,7 +158,7 @@ if(GLUON_BUILD_ALL)
add_dependencies(GluonInput GluonCore)
endif()
-target_link_libraries(GluonInput ${GLUON_CORE_LIBS})
+target_link_libraries(GluonInput ${GLUON_CORE_LIBS} -ludev)
set(GLUON_INPUT_LIBS
GluonInput
diff --git a/input/linux/detectlinux.cpp b/input/linux/detectlinux.cpp
index c606388..4c2ab62 100644
--- a/input/linux/detectlinux.cpp
+++ b/input/linux/detectlinux.cpp
@@ -30,6 +30,8 @@
#include <QtGui/QMessageBox>
#include <QtCore/QDebug>
+#include <libudev.h>
+
using namespace GluonInput;
DetectLinux::DetectLinux( QObject* parent )
@@ -57,6 +59,15 @@ void DetectLinux::detectDevices()
QString file;
QFileInfoList inputFileInfoList;
QList<struct input_id> processedInputs;
+ bool processed;
+
+ struct udev *udev;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices;
+ struct udev_list_entry *dev_list_entry;
+ struct udev_device *dev;
+ struct udev_device *parent_dev;
+ struct input_id currentInputDeviceInfo;
inputFileInfoList = event.entryInfoList( QDir::Files );
foreach( QFileInfo inputFileInfo, inputFileInfoList )
@@ -111,6 +122,106 @@ void DetectLinux::detectDevices()
detect->addInput( device );
}
}
+
+ /* Create the udev object */
+ udev = udev_new();
+ if (!udev)
+ qWarning() << "Cannot create udev" << endl;
+
+ /* Create a list of the devices in the 'hidraw' subsystem. */
+ enumerate = udev_enumerate_new(udev);
+ udev_enumerate_add_match_subsystem(enumerate, "input");
+ udev_enumerate_scan_devices(enumerate);
+ devices = udev_enumerate_get_list_entry(enumerate);
+ /* For each item enumerated, print out its information.
+ * udev_list_entry_foreach is a macro which expands to
+ * a loop. The loop will be executed for each member in
+ * devices, setting dev_list_entry to a list entry
+ * which contains the device's path in /sys.
+ */
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ const char *path;
+
+ /* Get the filename of the /sys entry for the device
+ and create a udev_device object (dev) representing it */
+ path = udev_list_entry_get_name(dev_list_entry);
+ dev = udev_device_new_from_syspath(udev, path);
+
+ parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", 0);
+ if (parent_dev) {
+ udev_device_unref(parent_dev);
+ continue;
+ }
+
+ if (udev_device_get_sysattr_value(dev, "id/bustype"))
+ currentInputDeviceInfo.bustype = atoi(udev_device_get_sysattr_value(dev, \
"id/bustype")); + if (udev_device_get_sysattr_value(dev, "id/vendor"))
+ currentInputDeviceInfo.vendor = \
atoi(udev_device_get_sysattr_value(dev,"id/vendor")); + if \
(udev_device_get_sysattr_value(dev, "id/product")) + \
currentInputDeviceInfo.product = atoi(udev_device_get_sysattr_value(dev, \
"id/product")); + if (udev_device_get_sysattr_value(dev, "id/version"))
+ currentInputDeviceInfo.version = atoi(udev_device_get_sysattr_value(dev, \
"id/version")); +
+ /* The input device has been already processed, has read access
+ * credential
+ */
+ processed = false;
+ foreach(struct input_id inputID, processedInputs) {
+ if (inputID.bustype == currentInputDeviceInfo.bustype
+ && inputID.vendor == currentInputDeviceInfo.vendor
+ && inputID.product == currentInputDeviceInfo.product
+ && inputID.version == currentInputDeviceInfo.version) {
+ processed = true;
+ break;
+ }
+ }
+
+ if (processed)
+ continue;
+
+ InputDevice *device = 0;
+ InputThread *thread = new InputThread(dev);
+ if (!thread->error()) {
+ switch (thread->deviceType()) {
+ case GluonInput::KeyboardDevice:
+ device = new Keyboard(thread);
+ detect->addKeyboard(static_cast<Keyboard *>(device));
+ break;
+
+ case GluonInput::MouseDevice:
+ device = new Mouse(thread);
+ detect->addMouse(static_cast<Mouse *>(device));
+ break;
+
+ case GluonInput::TouchpadDevice:
+ device = new Mouse(thread);
+ detect->addMouse(static_cast<Mouse *>(device));
+ break;
+
+ case GluonInput::JoystickDevice:
+ device = new Joystick(thread);
+ detect->addJoystick(static_cast<Joystick *>(device));
+ break;
+
+ case GluonInput::TouchDevice:
+ device = new Touch(thread);
+ detect->addTouch(static_cast<Touch *>(device));
+ break;
+
+ case GluonInput::UnknownDevice:
+ device = new InputDevice(thread);
+ detect->addUnknown(device);
+ break;
+ }
+
+ detect->addInput(device);
+ }
+ }
+
+ /* Free the enumerator object */
+ udev_enumerate_unref(enumerate);
+
+ udev_unref(udev);
}
void DetectLinux::setAllEnabled( bool enable )
diff --git a/input/linux/inputthread.cpp b/input/linux/inputthread.cpp
index 7b287c0..5ec84a5 100644
--- a/input/linux/inputthread.cpp
+++ b/input/linux/inputthread.cpp
@@ -28,6 +28,7 @@
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QEvent>
+#include <QtCore/QStringList>
#include <fcntl.h>
#include <sys/stat.h>
@@ -52,6 +53,15 @@ InputThread::InputThread( const QString& devicePath, QObject* \
parent ) readInformation();
}
+InputThread::InputThread(struct udev_device *dev, QObject *parent)
+ : QThread(parent)
+ , d(new InputThreadPrivate)
+{
+ d->m_udevDevice = dev;
+ readSystemFS();
+}
+
+
InputThread::~InputThread()
{
closeDevice();
@@ -98,6 +108,131 @@ bool InputThread::openDevice( const QString& devicePath )
return true;
}
+int InputThread::readSystemFS()
+{
+
+ /* From here, we can call get_sysattr_value() for each file
+ in the device's /sys entry. The strings passed into these
+ functions (idProduct, idVendor, serial, etc.) correspond
+ directly to the files in the directory which represents
+ the USB device. Note that USB strings are Unicode, UCS2
+ encoded, but the strings returned from
+ udev_device_get_sysattr_value() are UTF-8 encoded. */
+ d->m_deviceName = \
QString::fromAscii(udev_device_get_sysattr_value(d->m_udevDevice, "name")); +
+ ///this next bit can be shared across platform
+ quint64 bit[EV_MAX][NBITS(KEY_MAX)];
+ int abs[5];
+ memset(bit, 0, sizeof(bit));
+
+ bool ok;
+ int k;
+ // qDebug() << udev_device_get_sysattr_value(d->m_udevDevice, "capabilities/ev") \
<< udev_device_get_sysattr_value(d->m_udevDevice, "name"); + bit[0][0] = \
QString::fromAscii(udev_device_get_sysattr_value(d->m_udevDevice, \
"capabilities/ev")).toULong(&ok, 16); +
+ for (int i = 1; i < EV_MAX; ++i) {
+ if (test_bit(i, bit[0])) {
+ if (!i)
+ continue;
+ switch (i) {
+ case EV_KEY:
+ {
+ k = 0;
+ QStringList keySections = \
QString::fromAscii(udev_device_get_sysattr_value(d->m_udevDevice, \
"capabilities/key")).split(" "); + for (QStringList::iterator istr = \
keySections.end(); istr != keySections.begin(); ++k) + bit[i][k] = \
(--istr)->toULongLong(&ok, 16); +
+ for (int j = 0; j < KEY_MAX; ++j) {
+ if (test_bit(j, bit[i]))
+ d->m_buttonCapabilities.append(j);
+ }
+ }
+ break;
+ case EV_REL:
+ {
+ k = 0;
+ QStringList relSections = \
QString::fromAscii(udev_device_get_sysattr_value(d->m_udevDevice, \
"capabilities/rel")).split(" "); + for (QStringList::iterator istr \
= relSections.end(); istr != relSections.begin(); ++k) + \
bit[i][k] = (--istr)->toULongLong(&ok, 16); +
+ for (int j = 0; j < KEY_MAX; ++j) {
+ if (test_bit(j, bit[i]))
+ d->m_relAxisCapabilities.append(j);
+ }
+ }
+ break;
+ case EV_ABS:
+ {
+ for (int j = 0; j < ABS_MAX; ++j) {
+ if (test_bit(j, bit[i])) {
+ // Get abs value/limits
+ k = 0;
+ QStringList absSections = \
QString::fromAscii(udev_device_get_sysattr_value(d->m_udevDevice, \
"capabilities/abs")).split(" "); + for \
(QStringList::iterator istr = absSections.end(); istr != absSections.begin(); ++k) + \
abs[k++] = (--istr)->toULongLong(&ok, 16); +
+ AbsVal cabs(0, 0, 0, 0);
+ for (int k = 0; k < 5; ++k) {
+ if ((k < 3) || abs[k]) {
+ switch (k) {
+ case 0:
+ cabs.value = abs[k];
+ break;
+ case 1:
+ cabs.min = abs[k];
+ break;
+ case 2:
+ cabs.max = abs[k];
+ break;
+ case 3:
+ cabs.fuzz = abs[k];
+ break;
+ case 4:
+ cabs.flat = abs[k];
+ break;
+ }
+ }
+ }
+ d->m_absAxisCapabilities.append(j);
+ d->m_absAxisInfos.append(cabs);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ //===============Find Force feedback ?? ===============
+
+ d->m_deviceType = GluonInput::UnknownDevice;
+
+ if (d->m_buttonCapabilities.contains(BTN_TOUCH)) {
+ d->m_deviceType = GluonInput::TouchDevice;
+ }
+
+ if (d->m_buttonCapabilities.contains(BTN_STYLUS)
+ || d->m_buttonCapabilities.contains(ABS_PRESSURE)) {
+ d->m_deviceType = GluonInput::MouseDevice;
+ }
+
+ if (d->m_buttonCapabilities.contains(BTN_TRIGGER)) {
+ d->m_deviceType = GluonInput::JoystickDevice;
+ }
+
+ if (d->m_buttonCapabilities.contains(BTN_MOUSE)) {
+ d->m_deviceType = GluonInput::MouseDevice;
+ }
+
+ if (d->m_buttonCapabilities.contains(KEY_ENTER)) {
+ d->m_deviceType = GluonInput::KeyboardDevice;
+ }
+
+ return 0;
+}
+
void InputThread::readInformation()
{
if( d->m_fd == -1 )
diff --git a/input/linux/inputthread.h b/input/linux/inputthread.h
index 1a52081..ecfa8e9 100644
--- a/input/linux/inputthread.h
+++ b/input/linux/inputthread.h
@@ -28,6 +28,8 @@
#include <QtCore/QMap>
#include <QtCore/QSharedData>
+#include <libudev.h>
+
/**
* \defgroup KCL KCL
*/
@@ -43,6 +45,7 @@ namespace GluonInput
public:
explicit InputThread( const QString& devicePath, QObject* parent = 0 );
+ explicit InputThread(udev_device *dev, QObject *parent = 0);
~InputThread();
void run();
@@ -84,6 +87,7 @@ namespace GluonInput
bool openDevice( const QString& devicePath );
void closeDevice();
+ int readSystemFS();
void readInformation();
QSharedDataPointer<InputThreadPrivate> d;
diff --git a/input/linux/inputthreadprivate.h b/input/linux/inputthreadprivate.h
index 5f57692..57c81e8 100644
--- a/input/linux/inputthreadprivate.h
+++ b/input/linux/inputthreadprivate.h
@@ -28,6 +28,8 @@
#include <QtCore/QMap>
#include <QtCore/QString>
+#include <libudev.h>
+
namespace GluonInput
{
class InputThreadPrivate : public QSharedData
@@ -39,6 +41,7 @@ namespace GluonInput
int m_fd;
struct input_id m_device_info;
struct input_event m_currentEvent;
+ udev_device *m_udevDevice;
QString m_devicePath;
QString m_deviceName;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic