Skip to content

Commit

Permalink
Work around broken XI2 master devices
Browse files Browse the repository at this point in the history
  • Loading branch information
thorvald committed Feb 27, 2011
1 parent 4774dab commit 2cd9863
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
39 changes: 34 additions & 5 deletions src/mumble/GlobalShortcut_unix.cpp
Expand Up @@ -39,8 +39,6 @@ GlobalShortcutX::GlobalShortcutX() {

display = NULL;

iKeyPress = iKeyRelease = iButtonPress = iButtonRelease = -1;

#ifdef Q_OS_LINUX
QString dir = QLatin1String("/dev/input");
QFileSystemWatcher *fsw = new QFileSystemWatcher(QStringList(dir), this);
Expand Down Expand Up @@ -78,6 +76,8 @@ GlobalShortcutX::GlobalShortcutX() {
if (rc != BadRequest) {
qWarning("GlobalShortcutX: Using XI2 %d.%d", major, minor);

queryXIMasterList();

XIEventMask evmask;
unsigned char mask[(XI_LASTEVENT + 7)/8];

Expand All @@ -88,8 +88,9 @@ GlobalShortcutX::GlobalShortcutX() {
XISetMask(mask, XI_RawButtonRelease);
XISetMask(mask, XI_RawKeyPress);
XISetMask(mask, XI_RawKeyRelease);
XISetMask(mask, XI_HierarchyChanged);

evmask.deviceid = XIAllMasterDevices;
evmask.deviceid = XIAllDevices;
evmask.mask_len = sizeof(mask);
evmask.mask = mask;

Expand Down Expand Up @@ -160,6 +161,29 @@ void GlobalShortcutX::run() {
}
}

// Find XI2 master devices so they can be ignored.
void GlobalShortcutX::queryXIMasterList() {
XIDeviceInfo *info, *dev;
int ndevices;

qsMasterDevices.clear();

dev = info = XIQueryDevice(display, XIAllDevices, &ndevices);
for(int i=0;i<ndevices;++i) {
switch (dev->use) {
case XIMasterPointer:
case XIMasterKeyboard:
qsMasterDevices.insert(dev->deviceid);
break;
default:
break;
}

++dev;
}
XIFreeDeviceInfo(info);
}

// XInput2 event is ready on socketnotifier.
void GlobalShortcutX::displayReadyRead(int) {
XEvent evt;
Expand All @@ -175,15 +199,20 @@ void GlobalShortcutX::displayReadyRead(int) {
continue;

XIDeviceEvent *xide = reinterpret_cast<XIDeviceEvent *>(cookie->data);

switch(cookie->evtype) {
case XI_RawKeyPress:
case XI_RawKeyRelease:
handleButton(xide->detail, cookie->evtype == XI_RawKeyPress);
if (! qsMasterDevices.contains(xide->deviceid))
handleButton(xide->detail, cookie->evtype == XI_RawKeyPress);
break;
case XI_RawButtonPress:
case XI_RawButtonRelease:
handleButton(xide->detail + 0x117, cookie->evtype == XI_RawButtonPress);
if (! qsMasterDevices.contains(xide->deviceid))
handleButton(xide->detail + 0x117, cookie->evtype == XI_RawButtonPress);
break;
case XI_HierarchyChanged:
queryXIMasterList();
}

XFreeEventData(display, cookie);
Expand Down
6 changes: 3 additions & 3 deletions src/mumble/GlobalShortcut_unix.h
Expand Up @@ -52,6 +52,8 @@ class GlobalShortcutX : public GlobalShortcutEngine {
Display *display;
QSet<Window> qsRootWindows;
int iXIopcode;
QSet<int> qsMasterDevices;

volatile bool bRunning;
QSet<QString> qsKeyboards;
QMap<QString, QFile *> qmInputDevices;
Expand All @@ -61,9 +63,7 @@ class GlobalShortcutX : public GlobalShortcutEngine {
void run();
QString buttonName(const QVariant &);

int iKeyPress, iKeyRelease, iButtonPress, iButtonRelease;

void initXInput(Display *);
void queryXIMasterList();
public slots:
void displayReadyRead(int);
void inputReadyRead(int);
Expand Down

0 comments on commit 2cd9863

Please sign in to comment.