2
* Copyright (C) 2011 Canonical, Ltd.
5
* Michał Sawicz <michal.sawicz@canonical.com>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; version 3.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21
#include "keymonitor.h"
24
#include <QtConcurrentRun>
29
#include <X11/keysym.h>
34
#define INVALID_EVENT_TYPE -1
36
static int key_press_type = INVALID_EVENT_TYPE;
37
static int notify_type = INVALID_EVENT_TYPE;
40
KeyMonitor::KeyMonitor(QObject* parent)
43
if (this->registerEvents()) {
45
m_future = QtConcurrent::run(this, &KeyMonitor::run);
49
KeyMonitor::~KeyMonitor()
51
/* let the running thread know that it should stop */
56
KeyMonitor* KeyMonitor::instance()
58
static KeyMonitor* monitor = new KeyMonitor();
63
void KeyMonitor::getModifiers()
65
if(!m_modList.empty()) {
69
XModifierKeymap *xmodmap = XGetModifierMapping(m_display);
71
// 8 is for Shift, Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5
72
for (int i=0; i<8*xmodmap->max_keypermod; i++) {
73
if (xmodmap->modifiermap[i] > 0 && !m_modList.contains(xmodmap->modifiermap[i])) {
74
m_modList.append(xmodmap->modifiermap[i]);
79
bool KeyMonitor::registerEvents()
89
XInputClassInfo *info;
91
XEventClass event_class;
93
m_display = XOpenDisplay(NULL);
95
screen = DefaultScreen(m_display);
96
window = RootWindow(m_display, screen);
98
devices = XListInputDevices(m_display, &num_devices);
100
for(i=0; i<num_devices; i++) {
101
device = XOpenDevice(m_display, devices[i].id);
102
if (device == NULL) {
103
/* That's not critical since "Virtual core..." devices don't
105
UQ_DEBUG << "Could not open device: " << devices[i].name;
109
if (devices[i].use == IsXExtensionKeyboard) {
110
for (info=device->classes, j=0; j < device->num_classes; j++, info++) {
111
if (info->input_class == KeyClass) {
112
DeviceKeyPress(device, key_press_type, event_class);
113
m_eventList.append(event_class);
114
DeviceMappingNotify(device, notify_type, event_class);
115
m_eventList.append(event_class);
121
if (m_eventList.size() == 0) {
122
UQ_WARNING << "No input devices found.";
126
if (XSelectExtensionEvent(m_display, window, m_eventList.data(), m_eventList.size())) {
127
UQ_WARNING << "Error selecting events.";
135
void KeyMonitor::run()
139
while(!m_stop && !XNextEvent(m_display, &event)) {
140
if (event.type == key_press_type) {
141
XDeviceKeyEvent *keyEvent = (XDeviceKeyEvent *) &event;
142
if (!m_modList.contains((KeyCode) keyEvent->keycode)) {
147
else if (event.type == notify_type) {
153
#include "keymonitor.moc"