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::inputHandleMotion(void *data,
87 struct wl_input_device *input_device,
90 int32_t surface_x, int32_t surface_y)
92 Q_UNUSED(input_device);
93 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
94 QWaylandWindow *window = inputDevice->mPointerFocus;
96 inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
97 inputDevice->mGlobalPos = QPoint(x, y);
98 inputDevice->mTime = time;
99 QWindowSystemInterface::handleMouseEvent(window->widget(),
101 inputDevice->mSurfacePos,
102 inputDevice->mGlobalPos,
103 inputDevice->mButtons);
106 void QWaylandInputDevice::inputHandleButton(void *data,
107 struct wl_input_device *input_device,
108 uint32_t time, uint32_t button, uint32_t state)
110 Q_UNUSED(input_device);
111 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
112 QWaylandWindow *window = inputDevice->mPointerFocus;
113 Qt::MouseButton qt_button;
117 qt_button = Qt::LeftButton;
120 qt_button = Qt::RightButton;
123 qt_button = Qt::MiddleButton;
130 inputDevice->mButtons |= qt_button;
132 inputDevice->mButtons &= ~qt_button;
134 inputDevice->mTime = time;
135 QWindowSystemInterface::handleMouseEvent(window->widget(),
137 inputDevice->mSurfacePos,
138 inputDevice->mGlobalPos,
139 inputDevice->mButtons);
142 #ifndef QT_NO_WAYLAND_XKB
143 static Qt::KeyboardModifiers translateModifiers(int s)
145 const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK;
146 const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK;
148 Qt::KeyboardModifiers ret = 0;
149 if (s & XKB_COMMON_SHIFT_MASK)
150 ret |= Qt::ShiftModifier;
151 if (s & XKB_COMMON_CONTROL_MASK)
152 ret |= Qt::ControlModifier;
154 ret |= Qt::AltModifier;
155 if (s & qt_meta_mask)
156 ret |= Qt::MetaModifier;
161 static uint32_t translateKey(uint32_t sym, char *string, size_t size)
167 case XK_Escape: return Qt::Key_Escape;
168 case XK_Tab: return Qt::Key_Tab;
169 case XK_ISO_Left_Tab: return Qt::Key_Backtab;
170 case XK_BackSpace: return Qt::Key_Backspace;
171 case XK_Return: return Qt::Key_Return;
172 case XK_Insert: return Qt::Key_Insert;
173 case XK_Delete: return Qt::Key_Delete;
174 case XK_Clear: return Qt::Key_Delete;
175 case XK_Pause: return Qt::Key_Pause;
176 case XK_Print: return Qt::Key_Print;
178 case XK_Home: return Qt::Key_Home;
179 case XK_End: return Qt::Key_End;
180 case XK_Left: return Qt::Key_Left;
181 case XK_Up: return Qt::Key_Up;
182 case XK_Right: return Qt::Key_Right;
183 case XK_Down: return Qt::Key_Down;
184 case XK_Prior: return Qt::Key_PageUp;
185 case XK_Next: return Qt::Key_PageDown;
187 case XK_Shift_L: return Qt::Key_Shift;
188 case XK_Shift_R: return Qt::Key_Shift;
189 case XK_Shift_Lock: return Qt::Key_Shift;
190 case XK_Control_L: return Qt::Key_Control;
191 case XK_Control_R: return Qt::Key_Control;
192 case XK_Meta_L: return Qt::Key_Meta;
193 case XK_Meta_R: return Qt::Key_Meta;
194 case XK_Alt_L: return Qt::Key_Alt;
195 case XK_Alt_R: return Qt::Key_Alt;
196 case XK_Caps_Lock: return Qt::Key_CapsLock;
197 case XK_Num_Lock: return Qt::Key_NumLock;
198 case XK_Scroll_Lock: return Qt::Key_ScrollLock;
199 case XK_Super_L: return Qt::Key_Super_L;
200 case XK_Super_R: return Qt::Key_Super_R;
201 case XK_Menu: return Qt::Key_Menu;
211 void QWaylandInputDevice::inputHandleKey(void *data,
212 struct wl_input_device *input_device,
213 uint32_t time, uint32_t key, uint32_t state)
215 #ifndef QT_NO_WAYLAND_XKB
216 Q_UNUSED(input_device);
217 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
218 QWaylandWindow *window = inputDevice->mKeyboardFocus;
219 uint32_t code, sym, level;
220 Qt::KeyboardModifiers modifiers;
224 code = key + inputDevice->mXkb->min_key_code;
227 if (inputDevice->mModifiers & Qt::ShiftModifier &&
228 XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1)
231 sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0);
233 modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]);
236 inputDevice->mModifiers |= modifiers;
237 type = QEvent::KeyPress;
239 inputDevice->mModifiers &= ~modifiers;
240 type = QEvent::KeyRelease;
243 sym = translateKey(sym, s, sizeof s);
245 qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
246 code, sym, s[0], (int) inputDevice->mModifiers);
249 QWindowSystemInterface::handleKeyEvent(window->widget(),
251 inputDevice->mModifiers,
252 QString::fromLatin1(s));
257 void QWaylandInputDevice::inputHandlePointerFocus(void *data,
258 struct wl_input_device *input_device,
259 uint32_t time, struct wl_surface *surface,
260 int32_t x, int32_t y, int32_t sx, int32_t sy)
262 Q_UNUSED(input_device);
267 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
268 QWaylandWindow *window;
270 if (inputDevice->mPointerFocus) {
271 window = inputDevice->mPointerFocus;
272 QWindowSystemInterface::handleLeaveEvent(window->widget());
273 inputDevice->mPointerFocus = NULL;
277 window = (QWaylandWindow *) wl_surface_get_user_data(surface);
278 QWindowSystemInterface::handleEnterEvent(window->widget());
279 inputDevice->mPointerFocus = window;
282 inputDevice->mTime = time;
285 void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
286 struct wl_input_device *input_device,
288 struct wl_surface *surface,
289 struct wl_array *keys)
291 #ifndef QT_NO_WAYLAND_XKB
292 Q_UNUSED(input_device);
294 QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
295 QWaylandWindow *window;
299 end = (uint32_t *) ((char *) keys->data + keys->size);
300 inputDevice->mModifiers = 0;
301 for (k = (uint32_t *) keys->data; k < end; k++) {
302 code = *k + inputDevice->mXkb->min_key_code;
303 inputDevice->mModifiers |=
304 translateModifiers(inputDevice->mXkb->map->modmap[code]);
308 window = (QWaylandWindow *) wl_surface_get_user_data(surface);
309 inputDevice->mKeyboardFocus = window;
310 QWindowSystemInterface::handleWindowActivated(window->widget());
312 inputDevice->mKeyboardFocus = NULL;
313 QWindowSystemInterface::handleWindowActivated(0);
318 const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = {
319 QWaylandInputDevice::inputHandleMotion,
320 QWaylandInputDevice::inputHandleButton,
321 QWaylandInputDevice::inputHandleKey,
322 QWaylandInputDevice::inputHandlePointerFocus,
323 QWaylandInputDevice::inputHandleKeyboardFocus,
326 void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y)
328 wl_input_device_attach(mInputDevice, mTime, buffer->buffer(), x, y);