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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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, 1))
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 if (window == NULL) {
105 /* We destroyed the pointer focus surface, but the server
106 * didn't get the message yet. */
110 inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
111 inputDevice->mGlobalPos = QPoint(x, y);
112 inputDevice->mTime = time;
113 QWindowSystemInterface::handleMouseEvent(window->widget(),
115 inputDevice->mSurfacePos,
116 inputDevice->mGlobalPos,
117 inputDevice->mButtons);
120 void QWaylandInputDevice::inputHandleButton(void *data,
121 struct wl_input_device *input_device,
122 uint32_t time, uint32_t button, uint32_t state)
124 Q_UNUSED(input_device);
125 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
126 QWaylandWindow *window = inputDevice->mPointerFocus;
127 Qt::MouseButton qt_button;
129 if (window == NULL) {
130 /* We destroyed the pointer focus surface, but the server
131 * didn't get the message yet. */
137 qt_button = Qt::LeftButton;
140 qt_button = Qt::RightButton;
143 qt_button = Qt::MiddleButton;
150 inputDevice->mButtons |= qt_button;
152 inputDevice->mButtons &= ~qt_button;
154 inputDevice->mTime = time;
155 QWindowSystemInterface::handleMouseEvent(window->widget(),
157 inputDevice->mSurfacePos,
158 inputDevice->mGlobalPos,
159 inputDevice->mButtons);
162 #ifndef QT_NO_WAYLAND_XKB
163 static Qt::KeyboardModifiers translateModifiers(int s)
165 const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK;
166 const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK;
168 Qt::KeyboardModifiers ret = 0;
169 if (s & XKB_COMMON_SHIFT_MASK)
170 ret |= Qt::ShiftModifier;
171 if (s & XKB_COMMON_CONTROL_MASK)
172 ret |= Qt::ControlModifier;
174 ret |= Qt::AltModifier;
175 if (s & qt_meta_mask)
176 ret |= Qt::MetaModifier;
181 static uint32_t translateKey(uint32_t sym, char *string, size_t size)
187 case XK_Escape: return Qt::Key_Escape;
188 case XK_Tab: return Qt::Key_Tab;
189 case XK_ISO_Left_Tab: return Qt::Key_Backtab;
190 case XK_BackSpace: return Qt::Key_Backspace;
191 case XK_Return: return Qt::Key_Return;
192 case XK_Insert: return Qt::Key_Insert;
193 case XK_Delete: return Qt::Key_Delete;
194 case XK_Clear: return Qt::Key_Delete;
195 case XK_Pause: return Qt::Key_Pause;
196 case XK_Print: return Qt::Key_Print;
198 case XK_Home: return Qt::Key_Home;
199 case XK_End: return Qt::Key_End;
200 case XK_Left: return Qt::Key_Left;
201 case XK_Up: return Qt::Key_Up;
202 case XK_Right: return Qt::Key_Right;
203 case XK_Down: return Qt::Key_Down;
204 case XK_Prior: return Qt::Key_PageUp;
205 case XK_Next: return Qt::Key_PageDown;
207 case XK_Shift_L: return Qt::Key_Shift;
208 case XK_Shift_R: return Qt::Key_Shift;
209 case XK_Shift_Lock: return Qt::Key_Shift;
210 case XK_Control_L: return Qt::Key_Control;
211 case XK_Control_R: return Qt::Key_Control;
212 case XK_Meta_L: return Qt::Key_Meta;
213 case XK_Meta_R: return Qt::Key_Meta;
214 case XK_Alt_L: return Qt::Key_Alt;
215 case XK_Alt_R: return Qt::Key_Alt;
216 case XK_Caps_Lock: return Qt::Key_CapsLock;
217 case XK_Num_Lock: return Qt::Key_NumLock;
218 case XK_Scroll_Lock: return Qt::Key_ScrollLock;
219 case XK_Super_L: return Qt::Key_Super_L;
220 case XK_Super_R: return Qt::Key_Super_R;
221 case XK_Menu: return Qt::Key_Menu;
231 void QWaylandInputDevice::inputHandleKey(void *data,
232 struct wl_input_device *input_device,
233 uint32_t time, uint32_t key, uint32_t state)
235 #ifndef QT_NO_WAYLAND_XKB
236 Q_UNUSED(input_device);
237 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
238 QWaylandWindow *window = inputDevice->mKeyboardFocus;
239 uint32_t code, sym, level;
240 Qt::KeyboardModifiers modifiers;
244 if (window == NULL) {
245 /* We destroyed the keyboard focus surface, but the server
246 * didn't get the message yet. */
250 code = key + inputDevice->mXkb->min_key_code;
253 if (inputDevice->mModifiers & Qt::ShiftModifier &&
254 XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1)
257 sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0);
259 modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]);
262 inputDevice->mModifiers |= modifiers;
263 type = QEvent::KeyPress;
265 inputDevice->mModifiers &= ~modifiers;
266 type = QEvent::KeyRelease;
269 sym = translateKey(sym, s, sizeof s);
272 QWindowSystemInterface::handleKeyEvent(window->widget(),
274 inputDevice->mModifiers,
275 QString::fromLatin1(s));
280 void QWaylandInputDevice::inputHandlePointerFocus(void *data,
281 struct wl_input_device *input_device,
282 uint32_t time, struct wl_surface *surface,
283 int32_t x, int32_t y, int32_t sx, int32_t sy)
285 Q_UNUSED(input_device);
290 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
291 QWaylandWindow *window;
293 if (inputDevice->mPointerFocus) {
294 window = inputDevice->mPointerFocus;
295 QWindowSystemInterface::handleLeaveEvent(window->widget());
296 inputDevice->mPointerFocus = NULL;
300 window = (QWaylandWindow *) wl_surface_get_user_data(surface);
301 QWindowSystemInterface::handleEnterEvent(window->widget());
302 inputDevice->mPointerFocus = window;
305 inputDevice->mTime = time;
308 void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
309 struct wl_input_device *input_device,
311 struct wl_surface *surface,
312 struct wl_array *keys)
314 #ifndef QT_NO_WAYLAND_XKB
315 Q_UNUSED(input_device);
317 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
318 QWaylandWindow *window;
322 end = (uint32_t *) ((char *) keys->data + keys->size);
323 inputDevice->mModifiers = 0;
324 for (k = (uint32_t *) keys->data; k < end; k++) {
325 code = *k + inputDevice->mXkb->min_key_code;
326 inputDevice->mModifiers |=
327 translateModifiers(inputDevice->mXkb->map->modmap[code]);
331 window = (QWaylandWindow *) wl_surface_get_user_data(surface);
332 inputDevice->mKeyboardFocus = window;
333 QWindowSystemInterface::handleWindowActivated(window->widget());
335 inputDevice->mKeyboardFocus = NULL;
336 QWindowSystemInterface::handleWindowActivated(0);
341 const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
342 QWaylandInputDevice::inputHandleMotion,
343 QWaylandInputDevice::inputHandleButton,
344 QWaylandInputDevice::inputHandleKey,
345 QWaylandInputDevice::inputHandlePointerFocus,
346 QWaylandInputDevice::inputHandleKeyboardFocus,
349 void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
351 wl_input_device_attach(mInputDevice, mTime, buffer->buffer(), x, y);