~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kcontrol/keyboard/xinput_helper.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2010 Andriy Rysin (rysin@kde.org)
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
17
 */
 
18
 
 
19
#include "xinput_helper.h"
 
20
 
 
21
#include <kapplication.h>
 
22
#include <kdebug.h>
 
23
 
 
24
#include <QtGui/QX11Info>
 
25
 
 
26
#include <X11/X.h>
 
27
#include <X11/Xlib.h>
 
28
#include <X11/Xatom.h>
 
29
 
 
30
#ifdef HAVE_XINPUT_AND_DEVICE_NOTIFY
 
31
#include <X11/extensions/XInput.h>
 
32
#endif
 
33
 
 
34
#include <fixx11h.h>
 
35
 
 
36
#include "x11_helper.h"
 
37
 
 
38
#include <fixx11h.h>
 
39
 
 
40
static int DEVICE_NONE = 0;
 
41
static int DEVICE_KEYBOARD = 1;
 
42
static int DEVICE_POINTER = 2;
 
43
 
 
44
XInputEventNotifier::XInputEventNotifier(QWidget* parent):
 
45
        XEventNotifier(parent),
 
46
        xinputEventType(-1)
 
47
{
 
48
}
 
49
 
 
50
void XInputEventNotifier::start()
 
51
{
 
52
        if( KApplication::kApplication() != NULL ) {
 
53
                registerForNewDeviceEvent(QX11Info::display());
 
54
        }
 
55
 
 
56
        XEventNotifier::start();
 
57
}
 
58
 
 
59
void XInputEventNotifier::stop()
 
60
{
 
61
        XEventNotifier::stop();
 
62
 
 
63
        if( KApplication::kApplication() != NULL ) {
 
64
        //    XEventNotifier::unregisterForNewDeviceEvent(QX11Info::display());
 
65
        }
 
66
}
 
67
 
 
68
bool XInputEventNotifier::processOtherEvents(XEvent* event)
 
69
{
 
70
        int newDeviceType = getNewDeviceEventType(event);
 
71
        if( newDeviceType == DEVICE_KEYBOARD ) {
 
72
                emit(newKeyboardDevice());
 
73
        }
 
74
        else if( newDeviceType == DEVICE_POINTER ) {
 
75
                emit(newPointerDevice());
 
76
        }
 
77
        return true;
 
78
}
 
79
 
 
80
 
 
81
#ifdef HAVE_XINPUT_AND_DEVICE_NOTIFY
 
82
 
 
83
extern "C" {
 
84
    extern int _XiGetDevicePresenceNotifyEvent(Display *);
 
85
}
 
86
 
 
87
// This is ugly but allows to skip multiple execution of setxkbmap 
 
88
// for all keyboard devices that don't care about layouts
 
89
static bool isRealKeyboard(const char* deviceName)
 
90
{
 
91
        return strstr(deviceName, "Video Bus") == NULL
 
92
                && strstr(deviceName, "Sleep Button") == NULL
 
93
                && strstr(deviceName, "Power Button") == NULL
 
94
                && strstr(deviceName, "Webcam") == NULL
 
95
                && strstr(deviceName, "WMI hotkeys") == NULL;
 
96
}
 
97
 
 
98
int XInputEventNotifier::getNewDeviceEventType(XEvent* event)
 
99
{
 
100
        int newDeviceType = DEVICE_NONE;
 
101
 
 
102
        if( xinputEventType != -1 && event->type == xinputEventType ) {
 
103
                XDevicePresenceNotifyEvent *xdpne = (XDevicePresenceNotifyEvent*) event;
 
104
                if( xdpne->devchange == DeviceEnabled ) {
 
105
                        int ndevices;
 
106
                        XDeviceInfo     *devices = XListInputDevices(xdpne->display, &ndevices);
 
107
                        if( devices != NULL ) {
 
108
//                              kDebug() << "New device id:" << xdpne->deviceid;
 
109
                                for(int i=0; i<ndevices; i++) {
 
110
//                                      kDebug() << "id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use;
 
111
                                        if( devices[i].id == xdpne->deviceid ) {
 
112
                                                if( devices[i].use == IsXKeyboard || devices[i].use == IsXExtensionKeyboard ) {
 
113
                                                        if( isRealKeyboard(devices[i].name) ) {
 
114
                                                                newDeviceType = DEVICE_KEYBOARD;
 
115
                                                                kDebug() << "new keyboard device, id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use;
 
116
                                                                break;
 
117
                                                        }
 
118
                                                }
 
119
                                                if( devices[i].use == IsXPointer || devices[i].use == IsXExtensionPointer ) {
 
120
                                                        newDeviceType = DEVICE_POINTER;
 
121
                                                        kDebug() << "new pointer device, id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use;
 
122
                                                        break;
 
123
                                                }
 
124
                                        }
 
125
                                }
 
126
                                XFreeDeviceList(devices);
 
127
                        }
 
128
                }
 
129
        }
 
130
        return newDeviceType;
 
131
}
 
132
 
 
133
int XInputEventNotifier::registerForNewDeviceEvent(Display* display)
 
134
{
 
135
        int xitype;
 
136
        XEventClass xiclass;
 
137
 
 
138
        DevicePresence(display, xitype, xiclass);
 
139
        XSelectExtensionEvent(display, DefaultRootWindow(display), &xiclass, 1);
 
140
        kDebug() << "Registered for new device events from XInput, class" << xitype;
 
141
        xinputEventType = xitype;
 
142
        return xitype;
 
143
}
 
144
 
 
145
#else
 
146
 
 
147
#ifdef __GNUC__
 
148
#warning "Keyboard daemon is compiled without XInput, keyboard settings will be reset when new keyboard device is plugged in!"
 
149
#endif
 
150
 
 
151
int XInputEventNotifier::registerForNewDeviceEvent(Display* /*display*/)
 
152
{
 
153
        kWarning() << "Keyboard kded daemon is compiled without XInput, xkb configuration will be reset when new keyboard device is plugged in!";
 
154
        return -1;
 
155
}
 
156
 
 
157
int XInputEventNotifier::getNewDeviceEventType(XEvent* /*event*/)
 
158
{
 
159
        return DEVICE_NONE;
 
160
}
 
161
 
 
162
#endif