Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorvald Natvig <slicer@users.sourceforge.net>2008-02-01 15:52:09 +0300
committerThorvald Natvig <slicer@users.sourceforge.net>2008-02-01 15:52:09 +0300
commite094fc9364b8290a74225340c0121dab78d67de6 (patch)
treeb92555c57fa01711419186e64af848b3da0855d5 /src/mumble
parent786a5d7f3e9b9c1cd57a56befc271740f23fdabe (diff)
Automatically add/remove /dev/input devices [mkrautz]
git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@929 05730e5d-ab1b-0410-a4ac-84af385074fa
Diffstat (limited to 'src/mumble')
-rw-r--r--src/mumble/GlobalShortcut_unix.cpp80
-rw-r--r--src/mumble/GlobalShortcut_unix.h3
2 files changed, 56 insertions, 27 deletions
diff --git a/src/mumble/GlobalShortcut_unix.cpp b/src/mumble/GlobalShortcut_unix.cpp
index 92a22d1f2..a8929c3b6 100644
--- a/src/mumble/GlobalShortcut_unix.cpp
+++ b/src/mumble/GlobalShortcut_unix.cpp
@@ -51,32 +51,13 @@ GlobalShortcutX::GlobalShortcutX() {
display = NULL;
#ifdef Q_OS_LINUX
-#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))
-
- QDir d(QLatin1String("/dev/input"), QLatin1String("event*"), 0, QDir::System);
- foreach(QFileInfo fi, d.entryInfoList()) {
- QFile *f = new QFile(fi.absoluteFilePath(), this);
- if (f->open(QIODevice::ReadOnly)) {
- int fd = f->handle();
- int version;
- char name[256];
- uint8_t events[EV_MAX/8 + 1];
- memset(events, 0, sizeof(events));
- if ((ioctl(fd, EVIOCGVERSION, &version) >= 0) && (ioctl(fd, EVIOCGNAME(sizeof(name)), name)>=0) && (ioctl(fd, EVIOCGBIT(0,sizeof(events)), &events) >= 0) && test_bit(EV_KEY, events)) {
- name[255]=0;
- qWarning("GlobalShortcutX: Linux Input v%d.%d.%d: %s", (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF, name);
- fcntl(f->handle(), F_SETFL, O_NONBLOCK);
- connect(new QSocketNotifier(f->handle(), QSocketNotifier::Read, f), SIGNAL(activated(int)), this, SLOT(inputReadyRead(int)));
- qlInputDevices << f;
- } else {
- delete f;
- }
- } else {
- delete f;
- }
- }
-
- if (qlInputDevices.isEmpty()) {
+ QString dir = QLatin1String("/dev/input");
+ QFileSystemWatcher *fsw = new QFileSystemWatcher(QStringList(dir), this);
+ connect(fsw, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
+ directoryChanged(dir);
+
+ if (qmInputDevices.isEmpty()) {
+ delete fsw;
qWarning("GlobalShortcutX: Unable to open any input devices under /dev/input, falling back to XEVIE");
} else {
return;
@@ -171,7 +152,11 @@ void GlobalShortcutX::inputReadyRead(int) {
QFile *f=qobject_cast<QFile *>(sender()->parent());
if (!f)
return;
+
+ bool found = false;
+
while (f->read(reinterpret_cast<char *>(&ev), sizeof(ev)) == sizeof(ev)) {
+ found = true;
if (ev.type != EV_KEY)
continue;
bool down;
@@ -188,6 +173,49 @@ void GlobalShortcutX::inputReadyRead(int) {
int evtcode = ev.code + 8;
handleButton(evtcode, down);
}
+
+ if (! found) {
+ int fd = f->handle();
+ int version = 0;
+ if ((ioctl(fd, EVIOCGVERSION, &version) < 0) || (((version >> 16) & 0xFF) < 1)) {
+ qWarning("GlobalShortcutX: Removing dead input device %s", qPrintable(f->fileName()));
+ qmInputDevices.remove(f->fileName());
+ delete f;
+ }
+ }
+#endif
+}
+
+#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))
+
+void GlobalShortcutX::directoryChanged(const QString &dir) {
+ qWarning("Rescan!");
+#ifdef Q_OS_LINUX
+ QDir d(dir, QLatin1String("event*"), 0, QDir::System);
+ foreach(QFileInfo fi, d.entryInfoList()) {
+ QString path = fi.absoluteFilePath();
+ if (! qmInputDevices.contains(path)) {
+ QFile *f = new QFile(path, this);
+ if (f->open(QIODevice::ReadOnly)) {
+ int fd = f->handle();
+ int version;
+ char name[256];
+ uint8_t events[EV_MAX/8 + 1];
+ memset(events, 0, sizeof(events));
+ if ((ioctl(fd, EVIOCGVERSION, &version) >= 0) && (ioctl(fd, EVIOCGNAME(sizeof(name)), name)>=0) && (ioctl(fd, EVIOCGBIT(0,sizeof(events)), &events) >= 0) && test_bit(EV_KEY, events) && (((version >> 16) & 0xFF) > 0)) {
+ name[255]=0;
+ qWarning("GlobalShortcutX: %s: %s", qPrintable(f->fileName()), name);
+ fcntl(f->handle(), F_SETFL, O_NONBLOCK);
+ connect(new QSocketNotifier(f->handle(), QSocketNotifier::Read, f), SIGNAL(activated(int)), this, SLOT(inputReadyRead(int)));
+ qmInputDevices.insert(f->fileName(), f);
+ } else {
+ delete f;
+ }
+ } else {
+ delete f;
+ }
+ }
+ }
#endif
}
diff --git a/src/mumble/GlobalShortcut_unix.h b/src/mumble/GlobalShortcut_unix.h
index e0ebab2a7..070aaeb3a 100644
--- a/src/mumble/GlobalShortcut_unix.h
+++ b/src/mumble/GlobalShortcut_unix.h
@@ -38,7 +38,7 @@ class GlobalShortcutX : public GlobalShortcutEngine {
public:
Display *display;
volatile bool bRunning;
- QList<QFile *> qlInputDevices;
+ QMap<QString, QFile *> qmInputDevices;
GlobalShortcutX();
~GlobalShortcutX();
@@ -46,4 +46,5 @@ class GlobalShortcutX : public GlobalShortcutEngine {
QString buttonName(const QVariant &);
public slots:
void inputReadyRead(int);
+ void directoryChanged(const QString &);
};