1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the plugins of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qwaylandinputdevice.h"
44 #include "qwaylandintegration.h"
45 #include "qwaylandwindow.h"
46 #include "qwaylandbuffer.h"
48 #include <QWindowSystemInterface>
50 #include <QtGui/private/qpixmap_raster_p.h>
51 #include <QtGui/QPlatformWindow>
56 #ifndef QT_NO_WAYLAND_XKB
57 #include <X11/extensions/XKBcommon.h>
58 #include <X11/keysym.h>
61 QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
64 , mInputDevice(wl_input_device_create(display, id))
66 , mKeyboardFocus(NULL)
69 wl_input_device_add_listener(mInputDevice,
72 wl_input_device_set_user_data(mInputDevice, this);
74 #ifndef QT_NO_WAYLAND_XKB
75 struct xkb_rule_names names;
76 names.rules = "evdev";
77 names.model = "pc105";
82 mXkb = xkb_compile_keymap_from_rules(&names);
86 void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
88 if (window == mPointerFocus)
90 if (window == mKeyboardFocus)
94 void QWaylandInputDevice::inputHandleMotion(void *data,
95 struct wl_input_device *input_device,
98 int32_t surface_x, int32_t surface_y)
100 Q_UNUSED(input_device);
101 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
102 QWaylandWindow *window = inputDevice->mPointerFocus;
104 inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
105 inputDevice->mGlobalPos = QPoint(x, y);
106 inputDevice->mTime = time;
107 QWindowSystemInterface::handleMouseEvent(window->widget(),
109 inputDevice->mSurfacePos,
110 inputDevice->mGlobalPos,
111 inputDevice->mButtons);
114 void QWaylandInputDevice::inputHandleButton(void *data,
115 struct wl_input_device *input_device,
116 uint32_t time, uint32_t button, uint32_t state)
118 Q_UNUSED(input_device);
119 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
120 QWaylandWindow *window = inputDevice->mPointerFocus;
121 Qt::MouseButton qt_button;
125 qt_button = Qt::LeftButton;
128 qt_button = Qt::RightButton;
131 qt_button = Qt::MiddleButton;
138 inputDevice->mButtons |= qt_button;
140 inputDevice->mButtons &= ~qt_button;
142 inputDevice->mTime = time;
143 QWindowSystemInterface::handleMouseEvent(window->widget(),
145 inputDevice->mSurfacePos,
146 inputDevice->mGlobalPos,
147 inputDevice->mButtons);
150 #ifndef QT_NO_WAYLAND_XKB
151 static Qt::KeyboardModifiers translateModifiers(int s)
153 const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK;
154 const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK;
156 Qt::KeyboardModifiers ret = 0;
157 if (s & XKB_COMMON_SHIFT_MASK)
158 ret |= Qt::ShiftModifier;
159 if (s & XKB_COMMON_CONTROL_MASK)
160 ret |= Qt::ControlModifier;
162 ret |= Qt::AltModifier;
163 if (s & qt_meta_mask)
164 ret |= Qt::MetaModifier;
169 static uint32_t translateKey(uint32_t sym, char *string, size_t size)
175 case XK_Escape: return Qt::Key_Escape;
176 case XK_Tab: return Qt::Key_Tab;
177 case XK_ISO_Left_Tab: return Qt::Key_Backtab;
178 case XK_BackSpace: return Qt::Key_Backspace;
179 case XK_Return: return Qt::Key_Return;
180 case XK_Insert: return Qt::Key_Insert;
181 case XK_Delete: return Qt::Key_Delete;
182 case XK_Clear: return Qt::Key_Delete;
183 case XK_Pause: return Qt::Key_Pause;
184 case XK_Print: return Qt::Key_Print;
186 case XK_Home: return Qt::Key_Home;
187 case XK_End: return Qt::Key_End;
188 case XK_Left: return Qt::Key_Left;
189 case XK_Up: return Qt::Key_Up;
190 case XK_Right: return Qt::Key_Right;
191 case XK_Down: return Qt::Key_Down;
192 case XK_Prior: return Qt::Key_PageUp;
193 case XK_Next: return Qt::Key_PageDown;
195 case XK_Shift_L: return Qt::Key_Shift;
196 case XK_Shift_R: return Qt::Key_Shift;
197 case XK_Shift_Lock: return Qt::Key_Shift;
198 case XK_Control_L: return Qt::Key_Control;
199 case XK_Control_R: return Qt::Key_Control;
200 case XK_Meta_L: return Qt::Key_Meta;
201 case XK_Meta_R: return Qt::Key_Meta;
202 case XK_Alt_L: return Qt::Key_Alt;
203 case XK_Alt_R: return Qt::Key_Alt;
204 case XK_Caps_Lock: return Qt::Key_CapsLock;
205 case XK_Num_Lock: return Qt::Key_NumLock;
206 case XK_Scroll_Lock: return Qt::Key_ScrollLock;
207 case XK_Super_L: return Qt::Key_Super_L;
208 case XK_Super_R: return Qt::Key_Super_R;
209 case XK_Menu: return Qt::Key_Menu;
219 void QWaylandInputDevice::inputHandleKey(void *data,
220 struct wl_input_device *input_device,
221 uint32_t time, uint32_t key, uint32_t state)
223 #ifndef QT_NO_WAYLAND_XKB
224 Q_UNUSED(input_device);
225 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
226 QWaylandWindow *window = inputDevice->mKeyboardFocus;
227 uint32_t code, sym, level;
228 Qt::KeyboardModifiers modifiers;
232 code = key + inputDevice->mXkb->min_key_code;
235 if (inputDevice->mModifiers & Qt::ShiftModifier &&
236 XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1)
239 sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0);
241 modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]);
244 inputDevice->mModifiers |= modifiers;
245 type = QEvent::KeyPress;
247 inputDevice->mModifiers &= ~modifiers;
248 type = QEvent::KeyRelease;
251 sym = translateKey(sym, s, sizeof s);
253 qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
254 code, sym, s[0], (int) inputDevice->mModifiers);
257 QWindowSystemInterface::handleKeyEvent(window->widget(),
259 inputDevice->mModifiers,
260 QString::fromLatin1(s));
265 void QWaylandInputDevice::inputHandlePointerFocus(void *data,
266 struct wl_input_device *input_device,
267 uint32_t time, struct wl_surface *surface,
268 int32_t x, int32_t y, int32_t sx, int32_t sy)
270 Q_UNUSED(input_device);
275 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
276 QWaylandWindow *window;
278 if (inputDevice->mPointerFocus) {
279 window = inputDevice->mPointerFocus;
280 QWindowSystemInterface::handleLeaveEvent(window->widget());
281 inputDevice->mPointerFocus = NULL;
285 window = (QWaylandWindow *) wl_surface_get_user_data(surface);
286 QWindowSystemInterface::handleEnterEvent(window->widget());
287 inputDevice->mPointerFocus = window;
290 inputDevice->mTime = time;
293 void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
294 struct wl_input_device *input_device,
296 struct wl_surface *surface,
297 struct wl_array *keys)
299 #ifndef QT_NO_WAYLAND_XKB
300 Q_UNUSED(input_device);
302 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
303 QWaylandWindow *window;
307 end = (uint32_t *) ((char *) keys->data + keys->size);
308 inputDevice->mModifiers = 0;
309 for (k = (uint32_t *) keys->data; k < end; k++) {
310 code = *k + inputDevice->mXkb->min_key_code;
311 inputDevice->mModifiers |=
312 translateModifiers(inputDevice->mXkb->map->modmap[code]);
316 window = (QWaylandWindow *) wl_surface_get_user_data(surface);
317 inputDevice->mKeyboardFocus = window;
318 QWindowSystemInterface::handleWindowActivated(window->widget());
320 inputDevice->mKeyboardFocus = NULL;
321 QWindowSystemInterface::handleWindowActivated(0);
326 const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
327 QWaylandInputDevice::inputHandleMotion,
328 QWaylandInputDevice::inputHandleButton,
329 QWaylandInputDevice::inputHandleKey,
330 QWaylandInputDevice::inputHandlePointerFocus,
331 QWaylandInputDevice::inputHandleKeyboardFocus,
334 void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
336 wl_input_device_attach(mInputDevice, mTime, buffer->buffer(), x, y);