~alan-griffiths/miral/debug

« back to all changes in this revision

Viewing changes to miral-qt/src/platforms/mirserver/qteventfeeder.cpp

  • Committer: Gerry Boland
  • Date: 2016-06-01 22:06:51 UTC
  • mto: This revision was merged to the branch mainline in revision 178.
  • Revision ID: gerry.boland@canonical.com-20160601220651-ge508tffql4e7u7c
Import QtMir code into miral-qt subdirectory. Disabled by default, use -DMIRAL_ENABLE_QT=1 to build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2013-2016 Canonical, Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it under
 
5
 * the terms of the GNU Lesser General Public License version 3, as published by
 
6
 * the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
9
 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
 
10
 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
 * Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 */
 
16
 
 
17
#include "qteventfeeder.h"
 
18
#include "cursor.h"
 
19
#include "logging.h"
 
20
#include "timestamp.h"
 
21
#include "tracepoints.h" // generated from tracepoints.tp
 
22
#include "screen.h" // NEEDED?
 
23
#include "screensmodel.h"
 
24
 
 
25
#include <qpa/qplatforminputcontext.h>
 
26
#include <qpa/qplatformintegration.h>
 
27
#include <QGuiApplication>
 
28
#include <private/qguiapplication_p.h>
 
29
#include <QTextCodec>
 
30
#include <QDebug>
 
31
 
 
32
#include <xkbcommon/xkbcommon.h>
 
33
#include <xkbcommon/xkbcommon-keysyms.h>
 
34
 
 
35
// common dir
 
36
#include <debughelpers.h>
 
37
 
 
38
// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
 
39
static const uint32_t KeyTable[] = {
 
40
    // misc keys
 
41
    XKB_KEY_Escape,             Qt::Key_Escape,
 
42
    XKB_KEY_Tab,                Qt::Key_Tab,
 
43
    XKB_KEY_ISO_Left_Tab,       Qt::Key_Backtab,
 
44
    XKB_KEY_BackSpace,          Qt::Key_Backspace,
 
45
    XKB_KEY_Return,             Qt::Key_Return,
 
46
    XKB_KEY_Insert,             Qt::Key_Insert,
 
47
    XKB_KEY_Delete,             Qt::Key_Delete,
 
48
    XKB_KEY_Clear,              Qt::Key_Delete,
 
49
    XKB_KEY_Pause,              Qt::Key_Pause,
 
50
    XKB_KEY_Print,              Qt::Key_Print,
 
51
    0x1005FF60,                 Qt::Key_SysReq,         // hardcoded Sun SysReq
 
52
    0x1007ff00,                 Qt::Key_SysReq,         // hardcoded X386 SysReq
 
53
 
 
54
    // cursor movement
 
55
 
 
56
    XKB_KEY_Home,               Qt::Key_Home,
 
57
    XKB_KEY_End,                Qt::Key_End,
 
58
    XKB_KEY_Left,               Qt::Key_Left,
 
59
    XKB_KEY_Up,                 Qt::Key_Up,
 
60
    XKB_KEY_Right,              Qt::Key_Right,
 
61
    XKB_KEY_Down,               Qt::Key_Down,
 
62
    XKB_KEY_Prior,              Qt::Key_PageUp,
 
63
    XKB_KEY_Next,               Qt::Key_PageDown,
 
64
 
 
65
    // modifiers
 
66
 
 
67
    XKB_KEY_Shift_L,            Qt::Key_Shift,
 
68
    XKB_KEY_Shift_R,            Qt::Key_Shift,
 
69
    XKB_KEY_Shift_Lock,         Qt::Key_Shift,
 
70
    XKB_KEY_Control_L,          Qt::Key_Control,
 
71
    XKB_KEY_Control_R,          Qt::Key_Control,
 
72
    XKB_KEY_Meta_L,             Qt::Key_Meta,
 
73
    XKB_KEY_Meta_R,             Qt::Key_Meta,
 
74
    XKB_KEY_Alt_L,              Qt::Key_Alt,
 
75
    XKB_KEY_Alt_R,              Qt::Key_Alt,
 
76
    XKB_KEY_Caps_Lock,          Qt::Key_CapsLock,
 
77
    XKB_KEY_Num_Lock,           Qt::Key_NumLock,
 
78
    XKB_KEY_Scroll_Lock,        Qt::Key_ScrollLock,
 
79
    XKB_KEY_Super_L,            Qt::Key_Super_L,
 
80
    XKB_KEY_Super_R,            Qt::Key_Super_R,
 
81
    XKB_KEY_Menu,               Qt::Key_Menu,
 
82
    XKB_KEY_Hyper_L,            Qt::Key_Hyper_L,
 
83
    XKB_KEY_Hyper_R,            Qt::Key_Hyper_R,
 
84
    XKB_KEY_Help,               Qt::Key_Help,
 
85
    0x1000FF74,                 Qt::Key_Backtab,        // hardcoded HP backtab
 
86
    0x1005FF10,                 Qt::Key_F11,            // hardcoded Sun F36 (labeled F11)
 
87
    0x1005FF11,                 Qt::Key_F12,            // hardcoded Sun F37 (labeled F12)
 
88
 
 
89
    // numeric and function keypad keys
 
90
 
 
91
    XKB_KEY_KP_Space,           Qt::Key_Space,
 
92
    XKB_KEY_KP_Tab,             Qt::Key_Tab,
 
93
    XKB_KEY_KP_Enter,           Qt::Key_Enter,
 
94
    //XKB_KEY_KP_F1,            Qt::Key_F1,
 
95
    //XKB_KEY_KP_F2,            Qt::Key_F2,
 
96
    //XKB_KEY_KP_F3,            Qt::Key_F3,
 
97
    //XKB_KEY_KP_F4,            Qt::Key_F4,
 
98
    XKB_KEY_KP_Home,            Qt::Key_Home,
 
99
    XKB_KEY_KP_Left,            Qt::Key_Left,
 
100
    XKB_KEY_KP_Up,              Qt::Key_Up,
 
101
    XKB_KEY_KP_Right,           Qt::Key_Right,
 
102
    XKB_KEY_KP_Down,            Qt::Key_Down,
 
103
    XKB_KEY_KP_Prior,           Qt::Key_PageUp,
 
104
    XKB_KEY_KP_Next,            Qt::Key_PageDown,
 
105
    XKB_KEY_KP_End,             Qt::Key_End,
 
106
    XKB_KEY_KP_Begin,           Qt::Key_Clear,
 
107
    XKB_KEY_KP_Insert,          Qt::Key_Insert,
 
108
    XKB_KEY_KP_Delete,          Qt::Key_Delete,
 
109
    XKB_KEY_KP_Equal,           Qt::Key_Equal,
 
110
    XKB_KEY_KP_Multiply,        Qt::Key_Asterisk,
 
111
    XKB_KEY_KP_Add,             Qt::Key_Plus,
 
112
    XKB_KEY_KP_Separator,       Qt::Key_Comma,
 
113
    XKB_KEY_KP_Subtract,        Qt::Key_Minus,
 
114
    XKB_KEY_KP_Decimal,         Qt::Key_Period,
 
115
    XKB_KEY_KP_Divide,          Qt::Key_Slash,
 
116
 
 
117
    // International input method support keys
 
118
 
 
119
    // International & multi-key character composition
 
120
    XKB_KEY_ISO_Level3_Shift,   Qt::Key_AltGr,
 
121
    XKB_KEY_Multi_key,          Qt::Key_Multi_key,
 
122
    XKB_KEY_Codeinput,          Qt::Key_Codeinput,
 
123
    XKB_KEY_SingleCandidate,    Qt::Key_SingleCandidate,
 
124
    XKB_KEY_MultipleCandidate,  Qt::Key_MultipleCandidate,
 
125
    XKB_KEY_PreviousCandidate,  Qt::Key_PreviousCandidate,
 
126
 
 
127
    // Misc Functions
 
128
    XKB_KEY_Mode_switch,        Qt::Key_Mode_switch,
 
129
    XKB_KEY_script_switch,      Qt::Key_Mode_switch,
 
130
 
 
131
    // Japanese keyboard support
 
132
    XKB_KEY_Kanji,              Qt::Key_Kanji,
 
133
    XKB_KEY_Muhenkan,           Qt::Key_Muhenkan,
 
134
    //XKB_KEY_Henkan_Mode,      Qt::Key_Henkan_Mode,
 
135
    XKB_KEY_Henkan_Mode,        Qt::Key_Henkan,
 
136
    XKB_KEY_Henkan,             Qt::Key_Henkan,
 
137
    XKB_KEY_Romaji,             Qt::Key_Romaji,
 
138
    XKB_KEY_Hiragana,           Qt::Key_Hiragana,
 
139
    XKB_KEY_Katakana,           Qt::Key_Katakana,
 
140
    XKB_KEY_Hiragana_Katakana,  Qt::Key_Hiragana_Katakana,
 
141
    XKB_KEY_Zenkaku,            Qt::Key_Zenkaku,
 
142
    XKB_KEY_Hankaku,            Qt::Key_Hankaku,
 
143
    XKB_KEY_Zenkaku_Hankaku,    Qt::Key_Zenkaku_Hankaku,
 
144
    XKB_KEY_Touroku,            Qt::Key_Touroku,
 
145
    XKB_KEY_Massyo,             Qt::Key_Massyo,
 
146
    XKB_KEY_Kana_Lock,          Qt::Key_Kana_Lock,
 
147
    XKB_KEY_Kana_Shift,         Qt::Key_Kana_Shift,
 
148
    XKB_KEY_Eisu_Shift,         Qt::Key_Eisu_Shift,
 
149
    XKB_KEY_Eisu_toggle,        Qt::Key_Eisu_toggle,
 
150
    //XKB_KEY_Kanji_Bangou,     Qt::Key_Kanji_Bangou,
 
151
    //XKB_KEY_Zen_Koho,         Qt::Key_Zen_Koho,
 
152
    //XKB_KEY_Mae_Koho,         Qt::Key_Mae_Koho,
 
153
    XKB_KEY_Kanji_Bangou,       Qt::Key_Codeinput,
 
154
    XKB_KEY_Zen_Koho,           Qt::Key_MultipleCandidate,
 
155
    XKB_KEY_Mae_Koho,           Qt::Key_PreviousCandidate,
 
156
 
 
157
#ifdef XKB_KEY_KOREAN
 
158
    // Korean keyboard support
 
159
    XKB_KEY_Hangul,                  Qt::Key_Hangul,
 
160
    XKB_KEY_Hangul_Start,            Qt::Key_Hangul_Start,
 
161
    XKB_KEY_Hangul_End,              Qt::Key_Hangul_End,
 
162
    XKB_KEY_Hangul_Hanja,            Qt::Key_Hangul_Hanja,
 
163
    XKB_KEY_Hangul_Jamo,             Qt::Key_Hangul_Jamo,
 
164
    XKB_KEY_Hangul_Romaja,           Qt::Key_Hangul_Romaja,
 
165
    //XKB_KEY_Hangul_Codeinput,      Qt::Key_Hangul_Codeinput,
 
166
    XKB_KEY_Hangul_Codeinput,        Qt::Key_Codeinput,
 
167
    XKB_KEY_Hangul_Jeonja,           Qt::Key_Hangul_Jeonja,
 
168
    XKB_KEY_Hangul_Banja,            Qt::Key_Hangul_Banja,
 
169
    XKB_KEY_Hangul_PreHanja,         Qt::Key_Hangul_PreHanja,
 
170
    XKB_KEY_Hangul_PostHanja,        Qt::Key_Hangul_PostHanja,
 
171
    //XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
 
172
    //XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
 
173
    //XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
 
174
    XKB_KEY_Hangul_SingleCandidate,  Qt::Key_SingleCandidate,
 
175
    XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
 
176
    XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
 
177
    XKB_KEY_Hangul_Special,          Qt::Key_Hangul_Special,
 
178
    //XKB_KEY_Hangul_switch,         Qt::Key_Hangul_switch,
 
179
    XKB_KEY_Hangul_switch,           Qt::Key_Mode_switch,
 
180
#endif  // XKB_KEY_KOREAN
 
181
 
 
182
    // dead keys
 
183
    XKB_KEY_dead_grave,              Qt::Key_Dead_Grave,
 
184
    XKB_KEY_dead_acute,              Qt::Key_Dead_Acute,
 
185
    XKB_KEY_dead_circumflex,         Qt::Key_Dead_Circumflex,
 
186
    XKB_KEY_dead_tilde,              Qt::Key_Dead_Tilde,
 
187
    XKB_KEY_dead_macron,             Qt::Key_Dead_Macron,
 
188
    XKB_KEY_dead_breve,              Qt::Key_Dead_Breve,
 
189
    XKB_KEY_dead_abovedot,           Qt::Key_Dead_Abovedot,
 
190
    XKB_KEY_dead_diaeresis,          Qt::Key_Dead_Diaeresis,
 
191
    XKB_KEY_dead_abovering,          Qt::Key_Dead_Abovering,
 
192
    XKB_KEY_dead_doubleacute,        Qt::Key_Dead_Doubleacute,
 
193
    XKB_KEY_dead_caron,              Qt::Key_Dead_Caron,
 
194
    XKB_KEY_dead_cedilla,            Qt::Key_Dead_Cedilla,
 
195
    XKB_KEY_dead_ogonek,             Qt::Key_Dead_Ogonek,
 
196
    XKB_KEY_dead_iota,               Qt::Key_Dead_Iota,
 
197
    XKB_KEY_dead_voiced_sound,       Qt::Key_Dead_Voiced_Sound,
 
198
    XKB_KEY_dead_semivoiced_sound,   Qt::Key_Dead_Semivoiced_Sound,
 
199
    XKB_KEY_dead_belowdot,           Qt::Key_Dead_Belowdot,
 
200
    XKB_KEY_dead_hook,               Qt::Key_Dead_Hook,
 
201
    XKB_KEY_dead_horn,               Qt::Key_Dead_Horn,
 
202
 
 
203
    // Special keys from X.org - This include multimedia keys,
 
204
    // wireless/bluetooth/uwb keys, special launcher keys, etc.
 
205
    XKB_KEY_XF86Back,                Qt::Key_Back,
 
206
    XKB_KEY_XF86Forward,             Qt::Key_Forward,
 
207
    XKB_KEY_XF86Stop,                Qt::Key_Stop,
 
208
    XKB_KEY_XF86Refresh,             Qt::Key_Refresh,
 
209
    XKB_KEY_XF86Favorites,           Qt::Key_Favorites,
 
210
    XKB_KEY_XF86AudioMedia,          Qt::Key_LaunchMedia,
 
211
    XKB_KEY_XF86OpenURL,             Qt::Key_OpenUrl,
 
212
    XKB_KEY_XF86HomePage,            Qt::Key_HomePage,
 
213
    XKB_KEY_XF86Search,              Qt::Key_Search,
 
214
    XKB_KEY_XF86AudioLowerVolume,    Qt::Key_VolumeDown,
 
215
    XKB_KEY_XF86AudioMute,           Qt::Key_VolumeMute,
 
216
    XKB_KEY_XF86AudioRaiseVolume,    Qt::Key_VolumeUp,
 
217
    XKB_KEY_XF86AudioPlay,           Qt::Key_MediaPlay,
 
218
    XKB_KEY_XF86AudioStop,           Qt::Key_MediaStop,
 
219
    XKB_KEY_XF86AudioPrev,           Qt::Key_MediaPrevious,
 
220
    XKB_KEY_XF86AudioNext,           Qt::Key_MediaNext,
 
221
    XKB_KEY_XF86AudioRecord,         Qt::Key_MediaRecord,
 
222
    XKB_KEY_XF86AudioPause,          Qt::Key_MediaPause,
 
223
    XKB_KEY_XF86Mail,                Qt::Key_LaunchMail,
 
224
    XKB_KEY_XF86MyComputer,          Qt::Key_Launch0,  // ### Qt 6: remap properly
 
225
    XKB_KEY_XF86Calculator,          Qt::Key_Launch1,
 
226
    XKB_KEY_XF86Memo,                Qt::Key_Memo,
 
227
    XKB_KEY_XF86ToDoList,            Qt::Key_ToDoList,
 
228
    XKB_KEY_XF86Calendar,            Qt::Key_Calendar,
 
229
    XKB_KEY_XF86PowerDown,           Qt::Key_PowerDown,
 
230
    XKB_KEY_XF86ContrastAdjust,      Qt::Key_ContrastAdjust,
 
231
    XKB_KEY_XF86Standby,             Qt::Key_Standby,
 
232
    XKB_KEY_XF86MonBrightnessUp,     Qt::Key_MonBrightnessUp,
 
233
    XKB_KEY_XF86MonBrightnessDown,   Qt::Key_MonBrightnessDown,
 
234
    XKB_KEY_XF86KbdLightOnOff,       Qt::Key_KeyboardLightOnOff,
 
235
    XKB_KEY_XF86KbdBrightnessUp,     Qt::Key_KeyboardBrightnessUp,
 
236
    XKB_KEY_XF86KbdBrightnessDown,   Qt::Key_KeyboardBrightnessDown,
 
237
    XKB_KEY_XF86PowerOff,            Qt::Key_PowerOff,
 
238
    XKB_KEY_XF86WakeUp,              Qt::Key_WakeUp,
 
239
    XKB_KEY_XF86Eject,               Qt::Key_Eject,
 
240
    XKB_KEY_XF86ScreenSaver,         Qt::Key_ScreenSaver,
 
241
    XKB_KEY_XF86WWW,                 Qt::Key_WWW,
 
242
    XKB_KEY_XF86Sleep,               Qt::Key_Sleep,
 
243
    XKB_KEY_XF86LightBulb,           Qt::Key_LightBulb,
 
244
    XKB_KEY_XF86Shop,                Qt::Key_Shop,
 
245
    XKB_KEY_XF86History,             Qt::Key_History,
 
246
    XKB_KEY_XF86AddFavorite,         Qt::Key_AddFavorite,
 
247
    XKB_KEY_XF86HotLinks,            Qt::Key_HotLinks,
 
248
    XKB_KEY_XF86BrightnessAdjust,    Qt::Key_BrightnessAdjust,
 
249
    XKB_KEY_XF86Finance,             Qt::Key_Finance,
 
250
    XKB_KEY_XF86Community,           Qt::Key_Community,
 
251
    XKB_KEY_XF86AudioRewind,         Qt::Key_AudioRewind,
 
252
    XKB_KEY_XF86BackForward,         Qt::Key_BackForward,
 
253
    XKB_KEY_XF86ApplicationLeft,     Qt::Key_ApplicationLeft,
 
254
    XKB_KEY_XF86ApplicationRight,    Qt::Key_ApplicationRight,
 
255
    XKB_KEY_XF86Book,                Qt::Key_Book,
 
256
    XKB_KEY_XF86CD,                  Qt::Key_CD,
 
257
    XKB_KEY_XF86Calculater,          Qt::Key_Calculator,
 
258
    XKB_KEY_XF86Clear,               Qt::Key_Clear,
 
259
    XKB_KEY_XF86ClearGrab,           Qt::Key_ClearGrab,
 
260
    XKB_KEY_XF86Close,               Qt::Key_Close,
 
261
    XKB_KEY_XF86Copy,                Qt::Key_Copy,
 
262
    XKB_KEY_XF86Cut,                 Qt::Key_Cut,
 
263
    XKB_KEY_XF86Display,             Qt::Key_Display,
 
264
    XKB_KEY_XF86DOS,                 Qt::Key_DOS,
 
265
    XKB_KEY_XF86Documents,           Qt::Key_Documents,
 
266
    XKB_KEY_XF86Excel,               Qt::Key_Excel,
 
267
    XKB_KEY_XF86Explorer,            Qt::Key_Explorer,
 
268
    XKB_KEY_XF86Game,                Qt::Key_Game,
 
269
    XKB_KEY_XF86Go,                  Qt::Key_Go,
 
270
    XKB_KEY_XF86iTouch,              Qt::Key_iTouch,
 
271
    XKB_KEY_XF86LogOff,              Qt::Key_LogOff,
 
272
    XKB_KEY_XF86Market,              Qt::Key_Market,
 
273
    XKB_KEY_XF86Meeting,             Qt::Key_Meeting,
 
274
    XKB_KEY_XF86MenuKB,              Qt::Key_MenuKB,
 
275
    XKB_KEY_XF86MenuPB,              Qt::Key_MenuPB,
 
276
    XKB_KEY_XF86MySites,             Qt::Key_MySites,
 
277
    XKB_KEY_XF86New,                 Qt::Key_New,
 
278
    XKB_KEY_XF86News,                Qt::Key_News,
 
279
    XKB_KEY_XF86OfficeHome,          Qt::Key_OfficeHome,
 
280
    XKB_KEY_XF86Open,                Qt::Key_Open,
 
281
    XKB_KEY_XF86Option,              Qt::Key_Option,
 
282
    XKB_KEY_XF86Paste,               Qt::Key_Paste,
 
283
    XKB_KEY_XF86Phone,               Qt::Key_Phone,
 
284
    XKB_KEY_XF86Reply,               Qt::Key_Reply,
 
285
    XKB_KEY_XF86Reload,              Qt::Key_Reload,
 
286
    XKB_KEY_XF86RotateWindows,       Qt::Key_RotateWindows,
 
287
    XKB_KEY_XF86RotationPB,          Qt::Key_RotationPB,
 
288
    XKB_KEY_XF86RotationKB,          Qt::Key_RotationKB,
 
289
    XKB_KEY_XF86Save,                Qt::Key_Save,
 
290
    XKB_KEY_XF86Send,                Qt::Key_Send,
 
291
    XKB_KEY_XF86Spell,               Qt::Key_Spell,
 
292
    XKB_KEY_XF86SplitScreen,         Qt::Key_SplitScreen,
 
293
    XKB_KEY_XF86Support,             Qt::Key_Support,
 
294
    XKB_KEY_XF86TaskPane,            Qt::Key_TaskPane,
 
295
    XKB_KEY_XF86Terminal,            Qt::Key_Terminal,
 
296
    XKB_KEY_XF86Tools,               Qt::Key_Tools,
 
297
    XKB_KEY_XF86Travel,              Qt::Key_Travel,
 
298
    XKB_KEY_XF86Video,               Qt::Key_Video,
 
299
    XKB_KEY_XF86Word,                Qt::Key_Word,
 
300
    XKB_KEY_XF86Xfer,                Qt::Key_Xfer,
 
301
    XKB_KEY_XF86ZoomIn,              Qt::Key_ZoomIn,
 
302
    XKB_KEY_XF86ZoomOut,             Qt::Key_ZoomOut,
 
303
    XKB_KEY_XF86Away,                Qt::Key_Away,
 
304
    XKB_KEY_XF86Messenger,           Qt::Key_Messenger,
 
305
    XKB_KEY_XF86WebCam,              Qt::Key_WebCam,
 
306
    XKB_KEY_XF86MailForward,         Qt::Key_MailForward,
 
307
    XKB_KEY_XF86Pictures,            Qt::Key_Pictures,
 
308
    XKB_KEY_XF86Music,               Qt::Key_Music,
 
309
    XKB_KEY_XF86Battery,             Qt::Key_Battery,
 
310
    XKB_KEY_XF86Bluetooth,           Qt::Key_Bluetooth,
 
311
    XKB_KEY_XF86WLAN,                Qt::Key_WLAN,
 
312
    XKB_KEY_XF86UWB,                 Qt::Key_UWB,
 
313
    XKB_KEY_XF86AudioForward,        Qt::Key_AudioForward,
 
314
    XKB_KEY_XF86AudioRepeat,         Qt::Key_AudioRepeat,
 
315
    XKB_KEY_XF86AudioRandomPlay,     Qt::Key_AudioRandomPlay,
 
316
    XKB_KEY_XF86Subtitle,            Qt::Key_Subtitle,
 
317
    XKB_KEY_XF86AudioCycleTrack,     Qt::Key_AudioCycleTrack,
 
318
    XKB_KEY_XF86Time,                Qt::Key_Time,
 
319
    XKB_KEY_XF86Select,              Qt::Key_Select,
 
320
    XKB_KEY_XF86View,                Qt::Key_View,
 
321
    XKB_KEY_XF86TopMenu,             Qt::Key_TopMenu,
 
322
    XKB_KEY_XF86Red,                 Qt::Key_Red,
 
323
    XKB_KEY_XF86Green,               Qt::Key_Green,
 
324
    XKB_KEY_XF86Yellow,              Qt::Key_Yellow,
 
325
    XKB_KEY_XF86Blue,                Qt::Key_Blue,
 
326
    XKB_KEY_XF86Bluetooth,           Qt::Key_Bluetooth,
 
327
    XKB_KEY_XF86Suspend,             Qt::Key_Suspend,
 
328
    XKB_KEY_XF86Hibernate,           Qt::Key_Hibernate,
 
329
    XKB_KEY_XF86TouchpadToggle,      Qt::Key_TouchpadToggle,
 
330
    XKB_KEY_XF86TouchpadOn,          Qt::Key_TouchpadOn,
 
331
    XKB_KEY_XF86TouchpadOff,         Qt::Key_TouchpadOff,
 
332
    XKB_KEY_XF86AudioMicMute,        Qt::Key_MicMute,
 
333
    XKB_KEY_XF86Launch0,             Qt::Key_Launch2, // ### Qt 6: remap properly
 
334
    XKB_KEY_XF86Launch1,             Qt::Key_Launch3,
 
335
    XKB_KEY_XF86Launch2,             Qt::Key_Launch4,
 
336
    XKB_KEY_XF86Launch3,             Qt::Key_Launch5,
 
337
    XKB_KEY_XF86Launch4,             Qt::Key_Launch6,
 
338
    XKB_KEY_XF86Launch5,             Qt::Key_Launch7,
 
339
    XKB_KEY_XF86Launch6,             Qt::Key_Launch8,
 
340
    XKB_KEY_XF86Launch7,             Qt::Key_Launch9,
 
341
    XKB_KEY_XF86Launch8,             Qt::Key_LaunchA,
 
342
    XKB_KEY_XF86Launch9,             Qt::Key_LaunchB,
 
343
    XKB_KEY_XF86LaunchA,             Qt::Key_LaunchC,
 
344
    XKB_KEY_XF86LaunchB,             Qt::Key_LaunchD,
 
345
    XKB_KEY_XF86LaunchC,             Qt::Key_LaunchE,
 
346
    XKB_KEY_XF86LaunchD,             Qt::Key_LaunchF,
 
347
    XKB_KEY_XF86LaunchE,             Qt::Key_LaunchG,
 
348
    XKB_KEY_XF86LaunchF,             Qt::Key_LaunchH,
 
349
 
 
350
    0,                          0
 
351
};
 
352
 
 
353
static uint32_t translateKeysym(uint32_t sym, const QString &text) {
 
354
    int code = 0;
 
355
 
 
356
    QTextCodec *systemCodec = QTextCodec::codecForLocale();
 
357
    if (sym < 128 || (sym < 256 && systemCodec->mibEnum() == 4)) {
 
358
        // upper-case key, if known
 
359
        code = isprint((int)sym) ? toupper((int)sym) : 0;
 
360
    } else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35) {
 
361
        return Qt::Key_F1 + (int(sym) - XKB_KEY_F1);
 
362
    } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
 
363
               && text.unicode()->unicode() != 0x7f
 
364
               && !(sym >= XKB_KEY_dead_grave && sym <= XKB_KEY_dead_currency)) {
 
365
        code = text.unicode()->toUpper().unicode();
 
366
    } else {
 
367
        for (int i = 0; KeyTable[i]; i += 2)
 
368
            if (sym == KeyTable[i])
 
369
                code = KeyTable[i + 1];
 
370
    }
 
371
 
 
372
    return code;
 
373
}
 
374
 
 
375
namespace {
 
376
 
 
377
class QtWindowSystem : public QtEventFeeder::QtWindowSystemInterface
 
378
{
 
379
public:
 
380
    QtWindowSystem()
 
381
    {
 
382
        // because we're using QMetaObject::invoke with arguments of those types
 
383
        qRegisterMetaType<Qt::KeyboardModifiers>("Qt::KeyboardModifiers");
 
384
        qRegisterMetaType<Qt::MouseButtons>("Qt::MouseButtons");
 
385
    }
 
386
 
 
387
    void setScreensModel(const QSharedPointer<ScreensModel> &sc) override
 
388
    {
 
389
        m_screensModel = sc;
 
390
    }
 
391
 
 
392
    virtual QWindow* focusedWindow() override
 
393
    {
 
394
        return QGuiApplication::focusWindow();
 
395
    }
 
396
 
 
397
    QWindow* getWindowForTouchPoint(const QPoint &point) override //FIXME: not efficient, not updating focused window
 
398
    {
 
399
        return m_screensModel->getWindowForPoint(point);
 
400
    }
 
401
 
 
402
    void registerTouchDevice(QTouchDevice *device) override
 
403
    {
 
404
        QWindowSystemInterface::registerTouchDevice(device);
 
405
    }
 
406
 
 
407
    void handleExtendedKeyEvent(QWindow *window, ulong timestamp, QEvent::Type type, int key,
 
408
                Qt::KeyboardModifiers modifiers,
 
409
                quint32 nativeScanCode, quint32 nativeVirtualKey,
 
410
                quint32 nativeModifiers,
 
411
                const QString& text, bool autorep, ushort count) override
 
412
    {
 
413
        QWindowSystemInterface::handleExtendedKeyEvent(window, timestamp, type, key, modifiers,
 
414
                nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
 
415
    }
 
416
 
 
417
    void handleTouchEvent(QWindow *window, ulong timestamp, QTouchDevice *device,
 
418
            const QList<struct QWindowSystemInterface::TouchPoint> &points, Qt::KeyboardModifiers mods) override
 
419
    {
 
420
        QWindowSystemInterface::handleTouchEvent(window, timestamp, device, points, mods);
 
421
    }
 
422
 
 
423
    void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
 
424
                          Qt::KeyboardModifiers modifiers) override
 
425
    {
 
426
        // Send to the first screen that handles the mouse event
 
427
        // TODO: Have a mechanism to tell which screen currently has the logical mouse pointer
 
428
        //       (because they all might have their own separate graphical mouse pointer item)
 
429
        //       This will probably come once we implement the feature of having the mouse pointer
 
430
        //       crossing adjacent screens.
 
431
 
 
432
        QList<Screen*> screens = m_screensModel->screens();
 
433
        bool eventHandled = false;
 
434
        int i = 0;
 
435
        while (i < screens.count() && !eventHandled) {
 
436
            auto platformCursor = static_cast<qtmir::Cursor*>(screens[i]->cursor());
 
437
            eventHandled = platformCursor->handleMouseEvent(timestamp, movement, buttons, modifiers);
 
438
            ++i;
 
439
        }
 
440
    }
 
441
 
 
442
    void handleWheelEvent(ulong timestamp, QPoint angleDelta, Qt::KeyboardModifiers mods) override
 
443
    {
 
444
        // Send to the first screen that handles the mouse event
 
445
        // TODO: Have a mechanism to tell which screen currently has the logical mouse pointer
 
446
        //       (because they all might have their own separate graphical mouse pointer item)
 
447
        //       This will probably come once we implement the feature of having the mouse pointer
 
448
        //       crossing adjacent screens.
 
449
 
 
450
        QList<Screen*> screens = m_screensModel->screens();
 
451
        bool eventHandled = false;
 
452
        int i = 0;
 
453
        while (i < screens.count() && !eventHandled) {
 
454
            auto platformCursor = static_cast<qtmir::Cursor*>(screens.at(i)->cursor());
 
455
            eventHandled = platformCursor->handleWheelEvent(timestamp, angleDelta, mods);
 
456
            ++i;
 
457
        }
 
458
    }
 
459
 
 
460
private:
 
461
    QSharedPointer<ScreensModel> m_screensModel;
 
462
};
 
463
 
 
464
} // anonymous namespace
 
465
 
 
466
QtEventFeeder::QtEventFeeder(const QSharedPointer<ScreensModel> &screensModel)
 
467
    : QtEventFeeder(screensModel, new QtWindowSystem)
 
468
{
 
469
}
 
470
 
 
471
QtEventFeeder::QtEventFeeder(const QSharedPointer<ScreensModel> &screensModel,
 
472
                             QtEventFeeder::QtWindowSystemInterface *windowSystem)
 
473
    : mQtWindowSystem(windowSystem)
 
474
{
 
475
    // Initialize touch device. Hardcoded just like in qtubuntu
 
476
    // TODO: Create them from info gathered from Mir and store things like device id and source
 
477
    //       in a QTouchDevice-derived class created by us. So that we can properly assemble back
 
478
    //       MirEvents our of QTouchEvents to give to mir::scene::Surface::consume.
 
479
    mTouchDevice = new QTouchDevice();  // Qt takes ownership of mTouchDevice with registerTouchDevice
 
480
    mTouchDevice->setType(QTouchDevice::TouchScreen);
 
481
    mTouchDevice->setCapabilities(
 
482
            QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure |
 
483
            QTouchDevice::NormalizedPosition);
 
484
    mQtWindowSystem->setScreensModel(screensModel);
 
485
    mQtWindowSystem->registerTouchDevice(mTouchDevice);
 
486
}
 
487
 
 
488
QtEventFeeder::~QtEventFeeder()
 
489
{
 
490
    delete mQtWindowSystem;
 
491
}
 
492
 
 
493
bool QtEventFeeder::dispatch(MirEvent const& event)
 
494
{
 
495
    auto type = mir_event_get_type(&event);
 
496
    if (type != mir_event_type_input)
 
497
        return false;
 
498
 
 
499
    auto iev = mir_event_get_input_event(&event);
 
500
 
 
501
    switch (mir_input_event_get_type(iev)) {
 
502
    case mir_input_event_type_key:
 
503
        dispatchKey(iev);
 
504
        break;
 
505
    case mir_input_event_type_touch:
 
506
        dispatchTouch(iev);
 
507
        break;
 
508
    case mir_input_event_type_pointer:
 
509
        dispatchPointer(iev);
 
510
    default:
 
511
        break;
 
512
    }
 
513
 
 
514
    return true;
 
515
}
 
516
 
 
517
namespace
 
518
{
 
519
 
 
520
Qt::KeyboardModifiers getQtModifiersFromMir(MirInputEventModifiers modifiers)
 
521
{
 
522
    Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
 
523
    if (modifiers & mir_input_event_modifier_shift) {
 
524
        qtModifiers |= Qt::ShiftModifier;
 
525
    }
 
526
    if (modifiers & mir_input_event_modifier_ctrl) {
 
527
        qtModifiers |= Qt::ControlModifier;
 
528
    }
 
529
    if (modifiers & mir_input_event_modifier_alt) {
 
530
        qtModifiers |= Qt::AltModifier;
 
531
    }
 
532
    if (modifiers & mir_input_event_modifier_meta) {
 
533
        qtModifiers |= Qt::MetaModifier;
 
534
    }
 
535
    if (modifiers & mir_input_event_modifier_alt_right) {
 
536
        qtModifiers |= Qt::GroupSwitchModifier;
 
537
    }
 
538
    return qtModifiers;
 
539
}
 
540
 
 
541
Qt::MouseButtons getQtMouseButtonsfromMirPointerEvent(MirPointerEvent const* pev)
 
542
{
 
543
    Qt::MouseButtons buttons = Qt::NoButton;
 
544
    if (mir_pointer_event_button_state(pev, mir_pointer_button_primary))
 
545
        buttons |= Qt::LeftButton;
 
546
    if (mir_pointer_event_button_state(pev, mir_pointer_button_secondary))
 
547
        buttons |= Qt::RightButton;
 
548
    if (mir_pointer_event_button_state(pev, mir_pointer_button_tertiary))
 
549
        buttons |= Qt::MiddleButton;
 
550
    if (mir_pointer_event_button_state(pev, mir_pointer_button_back))
 
551
        buttons |= Qt::BackButton;
 
552
    if (mir_pointer_event_button_state(pev, mir_pointer_button_forward))
 
553
        buttons |= Qt::ForwardButton;
 
554
 
 
555
    return buttons;
 
556
}
 
557
}
 
558
 
 
559
void QtEventFeeder::dispatchPointer(MirInputEvent const* ev)
 
560
{
 
561
    auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(std::chrono::nanoseconds(mir_input_event_get_event_time(ev)));
 
562
    auto pev = mir_input_event_get_pointer_event(ev);
 
563
    auto action = mir_pointer_event_action(pev);
 
564
    qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirPointerEventToString(pev));
 
565
 
 
566
    auto modifiers = getQtModifiersFromMir(mir_pointer_event_modifiers(pev));
 
567
 
 
568
    auto movement = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x),
 
569
                            mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y));
 
570
 
 
571
    switch (action) {
 
572
    case mir_pointer_action_button_up:
 
573
    case mir_pointer_action_button_down:
 
574
    case mir_pointer_action_motion:
 
575
    {
 
576
        const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll);
 
577
        const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);
 
578
 
 
579
        if (hDelta != 0 || vDelta != 0) {
 
580
            const QPoint angleDelta = QPoint(hDelta * 15, vDelta * 15);
 
581
            mQtWindowSystem->handleWheelEvent(timestamp.count(), angleDelta, modifiers);
 
582
        }
 
583
        auto buttons = getQtMouseButtonsfromMirPointerEvent(pev);
 
584
        mQtWindowSystem->handleMouseEvent(timestamp.count(), movement, buttons, modifiers);
 
585
        break;
 
586
    }
 
587
    default:
 
588
        qCDebug(QTMIR_MIR_INPUT) << "Unrecognized pointer event";
 
589
    }
 
590
}
 
591
 
 
592
void QtEventFeeder::dispatchKey(MirInputEvent const* event)
 
593
{
 
594
    auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(std::chrono::nanoseconds(mir_input_event_get_event_time(event)));
 
595
 
 
596
    auto kev = mir_input_event_get_keyboard_event(event);
 
597
    xkb_keysym_t xk_sym = mir_keyboard_event_key_code(kev);
 
598
 
 
599
    // Key modifier and unicode index mapping.
 
600
    auto modifiers = getQtModifiersFromMir(mir_keyboard_event_modifiers(kev));
 
601
 
 
602
    // Key action
 
603
    QEvent::Type keyType = QEvent::KeyRelease;
 
604
    bool is_auto_rep = false;
 
605
 
 
606
    switch (mir_keyboard_event_action(kev))
 
607
    {
 
608
    case mir_keyboard_action_repeat:
 
609
        is_auto_rep = true; // fall-through
 
610
    case mir_keyboard_action_down:
 
611
        keyType = QEvent::KeyPress;
 
612
        break;
 
613
    case mir_keyboard_action_up:
 
614
        keyType = QEvent::KeyRelease;
 
615
        break;
 
616
    default:
 
617
        break;
 
618
    }
 
619
 
 
620
    // Key event propagation.
 
621
    QString text;
 
622
    QVarLengthArray<char, 32> chars(32);
 
623
    {
 
624
        int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size());
 
625
 
 
626
        if (result > 0) {
 
627
            text = QString::fromUtf8(chars.constData());
 
628
        }
 
629
    }
 
630
    int keyCode = translateKeysym(xk_sym, text);
 
631
 
 
632
    QPlatformInputContext* context = QGuiApplicationPrivate::platformIntegration()->inputContext();
 
633
    if (context) {
 
634
        // TODO: consider event.repeat_count
 
635
        QKeyEvent qKeyEvent(keyType, keyCode, modifiers,
 
636
                            mir_keyboard_event_scan_code(kev),
 
637
                            mir_keyboard_event_key_code(kev),
 
638
                            mir_keyboard_event_modifiers(kev),
 
639
                            text, is_auto_rep);
 
640
        qKeyEvent.setTimestamp(timestamp.count());
 
641
        if (context->filterEvent(&qKeyEvent)) {
 
642
            qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirKeyboardEventToString(kev))
 
643
                << "but not dispatching as it was filtered out by input context";
 
644
            return;
 
645
        }
 
646
    }
 
647
 
 
648
    qCDebug(QTMIR_MIR_INPUT).nospace() << "Received" << qPrintable(mirKeyboardEventToString(kev))
 
649
        << ". Dispatching to " << mQtWindowSystem->focusedWindow();
 
650
 
 
651
    mQtWindowSystem->handleExtendedKeyEvent(mQtWindowSystem->focusedWindow(),
 
652
        timestamp.count(), keyType, keyCode, modifiers,
 
653
        mir_keyboard_event_scan_code(kev), xk_sym,
 
654
        mir_keyboard_event_modifiers(kev), text, is_auto_rep);
 
655
}
 
656
 
 
657
void QtEventFeeder::dispatchTouch(MirInputEvent const* event)
 
658
{
 
659
    auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(std::chrono::nanoseconds(mir_input_event_get_event_time(event)));
 
660
 
 
661
    tracepoint(qtmirserver, touchEventDispatch_start, std::chrono::nanoseconds(timestamp).count());
 
662
 
 
663
    auto tev = mir_input_event_get_touch_event(event);
 
664
    qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirTouchEventToString(tev));
 
665
 
 
666
    // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
 
667
    //     needs to be fixed as soon as the compat input lib adds query support.
 
668
    const float kMaxPressure = 1.28;
 
669
    const int kPointerCount = mir_touch_event_point_count(tev);
 
670
    QList<QWindowSystemInterface::TouchPoint> touchPoints;
 
671
    QWindow *window = nullptr;
 
672
 
 
673
    if (kPointerCount > 0) {
 
674
        window = mQtWindowSystem->getWindowForTouchPoint(
 
675
                    QPoint(mir_touch_event_axis_value(tev, 0, mir_touch_axis_x),
 
676
                           mir_touch_event_axis_value(tev, 0, mir_touch_axis_y)));
 
677
 
 
678
        if (!window) {
 
679
            qCDebug(QTMIR_MIR_INPUT) << "REJECTING INPUT EVENT, no matching window";
 
680
            return;
 
681
        }
 
682
 
 
683
        const QRect kWindowGeometry = window->geometry();
 
684
 
 
685
        // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
 
686
        //       as Qt::TouchPointMoved
 
687
        for (int i = 0; i < kPointerCount; ++i) {
 
688
            QWindowSystemInterface::TouchPoint touchPoint;
 
689
 
 
690
            const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x);
 
691
            const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y);
 
692
            const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
 
693
            const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
 
694
            const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
 
695
            touchPoint.id = mir_touch_event_id(tev, i);
 
696
 
 
697
            touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
 
698
            touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
 
699
            touchPoint.pressure = kP / kMaxPressure;
 
700
            switch (mir_touch_event_action(tev, i))
 
701
            {
 
702
            case mir_touch_action_up:
 
703
                touchPoint.state = Qt::TouchPointReleased;
 
704
                break;
 
705
            case mir_touch_action_down:
 
706
                touchPoint.state = Qt::TouchPointPressed;
 
707
                break;
 
708
            case mir_touch_action_change:
 
709
                touchPoint.state = Qt::TouchPointMoved;
 
710
                break;
 
711
            default:
 
712
                break;
 
713
            }
 
714
 
 
715
            touchPoints.append(touchPoint);
 
716
        }
 
717
    }
 
718
 
 
719
    // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding
 
720
    // any insanity.
 
721
    validateTouches(window, timestamp.count(), touchPoints);
 
722
 
 
723
    // Touch event propagation.
 
724
    qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
 
725
    mQtWindowSystem->handleTouchEvent(window,
 
726
        //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable
 
727
        timestamp.count(),
 
728
        mTouchDevice,
 
729
        touchPoints);
 
730
 
 
731
    tracepoint(qtmirserver, touchEventDispatch_end, std::chrono::nanoseconds(timestamp).count());
 
732
}
 
733
 
 
734
void QtEventFeeder::start()
 
735
{
 
736
    // not used
 
737
}
 
738
 
 
739
void QtEventFeeder::stop()
 
740
{
 
741
    // not used
 
742
}
 
743
 
 
744
void QtEventFeeder::validateTouches(QWindow *window, ulong timestamp,
 
745
        QList<QWindowSystemInterface::TouchPoint> &touchPoints)
 
746
{
 
747
    QSet<int> updatedTouches;
 
748
 
 
749
    {
 
750
        int i = 0;
 
751
        while (i < touchPoints.count()) {
 
752
            bool mustDiscardTouch = !validateTouch(touchPoints[i]);
 
753
            if (mustDiscardTouch) {
 
754
                touchPoints.removeAt(i);
 
755
            } else {
 
756
                updatedTouches.insert(touchPoints.at(i).id);
 
757
                ++i;
 
758
            }
 
759
        }
 
760
    }
 
761
 
 
762
    // Release all unmentioned touches, one by one.
 
763
    QHash<int, QWindowSystemInterface::TouchPoint>::iterator it = mActiveTouches.begin();
 
764
    while (it != mActiveTouches.end()) {
 
765
        if (!updatedTouches.contains(it.key())) {
 
766
            qCWarning(QTMIR_MIR_INPUT)
 
767
                << "There's a touch (id =" << it.key() << ") missing. Releasing it.";
 
768
            sendActiveTouchRelease(window, timestamp, it.key());
 
769
            it = mActiveTouches.erase(it);
 
770
        } else {
 
771
            ++it;
 
772
        }
 
773
    }
 
774
 
 
775
    // update mActiveTouches
 
776
    for (int i = 0; i < touchPoints.count(); ++i) {
 
777
        auto &touchPoint = touchPoints.at(i);
 
778
        if (touchPoint.state == Qt::TouchPointReleased) {
 
779
            mActiveTouches.remove(touchPoint.id);
 
780
        } else {
 
781
            mActiveTouches[touchPoint.id] = touchPoint;
 
782
        }
 
783
    }
 
784
}
 
785
 
 
786
void QtEventFeeder::sendActiveTouchRelease(QWindow *window, ulong timestamp, int id)
 
787
{
 
788
    QList<QWindowSystemInterface::TouchPoint> touchPoints = mActiveTouches.values();
 
789
 
 
790
    for (int i = 0; i < touchPoints.count(); ++i) {
 
791
        QWindowSystemInterface::TouchPoint &touchPoint = touchPoints[i];
 
792
        if (touchPoint.id == id) {
 
793
            touchPoint.state = Qt::TouchPointReleased;
 
794
        } else {
 
795
            touchPoint.state = Qt::TouchPointStationary;
 
796
        }
 
797
    }
 
798
 
 
799
    qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
 
800
    mQtWindowSystem->handleTouchEvent(window, timestamp, mTouchDevice, touchPoints);
 
801
}
 
802
 
 
803
bool QtEventFeeder::validateTouch(QWindowSystemInterface::TouchPoint &touchPoint)
 
804
{
 
805
    bool ok = true;
 
806
 
 
807
    switch (touchPoint.state) {
 
808
    case Qt::TouchPointPressed:
 
809
        if (mActiveTouches.contains(touchPoint.id)) {
 
810
            qCWarning(QTMIR_MIR_INPUT)
 
811
                << "Would press an already existing touch (id =" << touchPoint.id
 
812
                << "). Making it move instead.";
 
813
            touchPoint.state = Qt::TouchPointMoved;
 
814
        }
 
815
        break;
 
816
    case Qt::TouchPointMoved:
 
817
        if (!mActiveTouches.contains(touchPoint.id)) {
 
818
            qCWarning(QTMIR_MIR_INPUT)
 
819
                << "Would move a touch that wasn't pressed before (id =" << touchPoint.id
 
820
                << "). Making it press instead.";
 
821
            touchPoint.state = Qt::TouchPointPressed;
 
822
        }
 
823
        break;
 
824
    case Qt::TouchPointStationary:
 
825
        if (!mActiveTouches.contains(touchPoint.id)) {
 
826
            qCWarning(QTMIR_MIR_INPUT)
 
827
                << "There's an stationary touch that wasn't pressed before (id =" << touchPoint.id
 
828
                << "). Making it press instead.";
 
829
            touchPoint.state = Qt::TouchPointPressed;
 
830
        }
 
831
        break;
 
832
    case Qt::TouchPointReleased:
 
833
        if (!mActiveTouches.contains(touchPoint.id)) {
 
834
            qCWarning(QTMIR_MIR_INPUT)
 
835
                << "Would release a touch that wasn't pressed before (id =" << touchPoint.id
 
836
                << "). Ignoring it.";
 
837
            ok = false;
 
838
        }
 
839
        break;
 
840
    default:
 
841
        qFatal("QtEventFeeder: invalid touch state");
 
842
    }
 
843
 
 
844
    return ok;
 
845
}
 
846
 
 
847
QString QtEventFeeder::touchesToString(const QList<struct QWindowSystemInterface::TouchPoint> &points)
 
848
{
 
849
    QString result;
 
850
    for (int i = 0; i < points.count(); ++i) {
 
851
        if (i > 0) {
 
852
            result.append(",");
 
853
        }
 
854
        const struct QWindowSystemInterface::TouchPoint &point = points.at(i);
 
855
        result.append(QString("(id=%1,state=%2,normalPosition=(%3,%4))")
 
856
            .arg(point.id)
 
857
            .arg(touchPointStateToString(point.state))
 
858
            .arg(point.normalPosition.x())
 
859
            .arg(point.normalPosition.y())
 
860
            );
 
861
    }
 
862
    return result;
 
863
}