~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/plugins/platforms/xcb/qxcbkeyboard.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the plugins of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include "qxcbkeyboard.h"
 
43
#include "qxcbwindow.h"
 
44
#include "qxcbscreen.h"
 
45
#include "qxlibconvenience.h"
 
46
#include <xcb/xcb_keysyms.h>
 
47
#include <X11/keysym.h>
 
48
#include <qpa/qwindowsysteminterface.h>
 
49
#include <QtCore/QTextCodec>
 
50
#include <QtCore/QMetaMethod>
 
51
#include <private/qguiapplication_p.h>
 
52
#include <stdio.h>
 
53
 
 
54
#include <qpa/qplatforminputcontext.h>
 
55
#include <qpa/qplatformintegration.h>
 
56
#include <qpa/qplatformcursor.h>
 
57
 
 
58
#ifndef XK_ISO_Left_Tab
 
59
#define XK_ISO_Left_Tab         0xFE20
 
60
#endif
 
61
 
 
62
#ifndef XK_dead_hook
 
63
#define XK_dead_hook            0xFE61
 
64
#endif
 
65
 
 
66
#ifndef XK_dead_horn
 
67
#define XK_dead_horn            0xFE62
 
68
#endif
 
69
 
 
70
#ifndef XK_Codeinput
 
71
#define XK_Codeinput            0xFF37
 
72
#endif
 
73
 
 
74
#ifndef XK_Kanji_Bangou
 
75
#define XK_Kanji_Bangou         0xFF37 /* same as codeinput */
 
76
#endif
 
77
 
 
78
// Fix old X libraries
 
79
#ifndef XK_KP_Home
 
80
#define XK_KP_Home              0xFF95
 
81
#endif
 
82
#ifndef XK_KP_Left
 
83
#define XK_KP_Left              0xFF96
 
84
#endif
 
85
#ifndef XK_KP_Up
 
86
#define XK_KP_Up                0xFF97
 
87
#endif
 
88
#ifndef XK_KP_Right
 
89
#define XK_KP_Right             0xFF98
 
90
#endif
 
91
#ifndef XK_KP_Down
 
92
#define XK_KP_Down              0xFF99
 
93
#endif
 
94
#ifndef XK_KP_Prior
 
95
#define XK_KP_Prior             0xFF9A
 
96
#endif
 
97
#ifndef XK_KP_Next
 
98
#define XK_KP_Next              0xFF9B
 
99
#endif
 
100
#ifndef XK_KP_End
 
101
#define XK_KP_End               0xFF9C
 
102
#endif
 
103
#ifndef XK_KP_Insert
 
104
#define XK_KP_Insert            0xFF9E
 
105
#endif
 
106
#ifndef XK_KP_Delete
 
107
#define XK_KP_Delete            0xFF9F
 
108
#endif
 
109
 
 
110
// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
 
111
// multimedia keys. They are included here as not every system has them.
 
112
#define XF86XK_MonBrightnessUp     0x1008FF02
 
113
#define XF86XK_MonBrightnessDown   0x1008FF03
 
114
#define XF86XK_KbdLightOnOff       0x1008FF04
 
115
#define XF86XK_KbdBrightnessUp     0x1008FF05
 
116
#define XF86XK_KbdBrightnessDown   0x1008FF06
 
117
#define XF86XK_Standby             0x1008FF10
 
118
#define XF86XK_AudioLowerVolume    0x1008FF11
 
119
#define XF86XK_AudioMute           0x1008FF12
 
120
#define XF86XK_AudioRaiseVolume    0x1008FF13
 
121
#define XF86XK_AudioPlay           0x1008FF14
 
122
#define XF86XK_AudioStop           0x1008FF15
 
123
#define XF86XK_AudioPrev           0x1008FF16
 
124
#define XF86XK_AudioNext           0x1008FF17
 
125
#define XF86XK_HomePage            0x1008FF18
 
126
#define XF86XK_Mail                0x1008FF19
 
127
#define XF86XK_Start               0x1008FF1A
 
128
#define XF86XK_Search              0x1008FF1B
 
129
#define XF86XK_AudioRecord         0x1008FF1C
 
130
#define XF86XK_Calculator          0x1008FF1D
 
131
#define XF86XK_Memo                0x1008FF1E
 
132
#define XF86XK_ToDoList            0x1008FF1F
 
133
#define XF86XK_Calendar            0x1008FF20
 
134
#define XF86XK_PowerDown           0x1008FF21
 
135
#define XF86XK_ContrastAdjust      0x1008FF22
 
136
#define XF86XK_Back                0x1008FF26
 
137
#define XF86XK_Forward             0x1008FF27
 
138
#define XF86XK_Stop                0x1008FF28
 
139
#define XF86XK_Refresh             0x1008FF29
 
140
#define XF86XK_PowerOff            0x1008FF2A
 
141
#define XF86XK_WakeUp              0x1008FF2B
 
142
#define XF86XK_Eject               0x1008FF2C
 
143
#define XF86XK_ScreenSaver         0x1008FF2D
 
144
#define XF86XK_WWW                 0x1008FF2E
 
145
#define XF86XK_Sleep               0x1008FF2F
 
146
#define XF86XK_Favorites           0x1008FF30
 
147
#define XF86XK_AudioPause          0x1008FF31
 
148
#define XF86XK_AudioMedia          0x1008FF32
 
149
#define XF86XK_MyComputer          0x1008FF33
 
150
#define XF86XK_LightBulb           0x1008FF35
 
151
#define XF86XK_Shop                0x1008FF36
 
152
#define XF86XK_History             0x1008FF37
 
153
#define XF86XK_OpenURL             0x1008FF38
 
154
#define XF86XK_AddFavorite         0x1008FF39
 
155
#define XF86XK_HotLinks            0x1008FF3A
 
156
#define XF86XK_BrightnessAdjust    0x1008FF3B
 
157
#define XF86XK_Finance             0x1008FF3C
 
158
#define XF86XK_Community           0x1008FF3D
 
159
#define XF86XK_AudioRewind         0x1008FF3E
 
160
#define XF86XK_BackForward         0x1008FF3F
 
161
#define XF86XK_Launch0             0x1008FF40
 
162
#define XF86XK_Launch1             0x1008FF41
 
163
#define XF86XK_Launch2             0x1008FF42
 
164
#define XF86XK_Launch3             0x1008FF43
 
165
#define XF86XK_Launch4             0x1008FF44
 
166
#define XF86XK_Launch5             0x1008FF45
 
167
#define XF86XK_Launch6             0x1008FF46
 
168
#define XF86XK_Launch7             0x1008FF47
 
169
#define XF86XK_Launch8             0x1008FF48
 
170
#define XF86XK_Launch9             0x1008FF49
 
171
#define XF86XK_LaunchA             0x1008FF4A
 
172
#define XF86XK_LaunchB             0x1008FF4B
 
173
#define XF86XK_LaunchC             0x1008FF4C
 
174
#define XF86XK_LaunchD             0x1008FF4D
 
175
#define XF86XK_LaunchE             0x1008FF4E
 
176
#define XF86XK_LaunchF             0x1008FF4F
 
177
#define XF86XK_ApplicationLeft     0x1008FF50
 
178
#define XF86XK_ApplicationRight    0x1008FF51
 
179
#define XF86XK_Book                0x1008FF52
 
180
#define XF86XK_CD                  0x1008FF53
 
181
#define XF86XK_Calculater          0x1008FF54
 
182
#define XF86XK_Clear               0x1008FF55
 
183
#define XF86XK_ClearGrab           0x1008FE21
 
184
#define XF86XK_Close               0x1008FF56
 
185
#define XF86XK_Copy                0x1008FF57
 
186
#define XF86XK_Cut                 0x1008FF58
 
187
#define XF86XK_Display             0x1008FF59
 
188
#define XF86XK_DOS                 0x1008FF5A
 
189
#define XF86XK_Documents           0x1008FF5B
 
190
#define XF86XK_Excel               0x1008FF5C
 
191
#define XF86XK_Explorer            0x1008FF5D
 
192
#define XF86XK_Game                0x1008FF5E
 
193
#define XF86XK_Go                  0x1008FF5F
 
194
#define XF86XK_iTouch              0x1008FF60
 
195
#define XF86XK_LogOff              0x1008FF61
 
196
#define XF86XK_Market              0x1008FF62
 
197
#define XF86XK_Meeting             0x1008FF63
 
198
#define XF86XK_MenuKB              0x1008FF65
 
199
#define XF86XK_MenuPB              0x1008FF66
 
200
#define XF86XK_MySites             0x1008FF67
 
201
#define XF86XK_News                0x1008FF69
 
202
#define XF86XK_OfficeHome          0x1008FF6A
 
203
#define XF86XK_Option              0x1008FF6C
 
204
#define XF86XK_Paste               0x1008FF6D
 
205
#define XF86XK_Phone               0x1008FF6E
 
206
#define XF86XK_Reply               0x1008FF72
 
207
#define XF86XK_Reload              0x1008FF73
 
208
#define XF86XK_RotateWindows       0x1008FF74
 
209
#define XF86XK_RotationPB          0x1008FF75
 
210
#define XF86XK_RotationKB          0x1008FF76
 
211
#define XF86XK_Save                0x1008FF77
 
212
#define XF86XK_Send                0x1008FF7B
 
213
#define XF86XK_Spell               0x1008FF7C
 
214
#define XF86XK_SplitScreen         0x1008FF7D
 
215
#define XF86XK_Support             0x1008FF7E
 
216
#define XF86XK_TaskPane            0x1008FF7F
 
217
#define XF86XK_Terminal            0x1008FF80
 
218
#define XF86XK_Tools               0x1008FF81
 
219
#define XF86XK_Travel              0x1008FF82
 
220
#define XF86XK_Video               0x1008FF87
 
221
#define XF86XK_Word                0x1008FF89
 
222
#define XF86XK_Xfer                0x1008FF8A
 
223
#define XF86XK_ZoomIn              0x1008FF8B
 
224
#define XF86XK_ZoomOut             0x1008FF8C
 
225
#define XF86XK_Away                0x1008FF8D
 
226
#define XF86XK_Messenger           0x1008FF8E
 
227
#define XF86XK_WebCam              0x1008FF8F
 
228
#define XF86XK_MailForward         0x1008FF90
 
229
#define XF86XK_Pictures            0x1008FF91
 
230
#define XF86XK_Music               0x1008FF92
 
231
#define XF86XK_Battery             0x1008FF93
 
232
#define XF86XK_Bluetooth           0x1008FF94
 
233
#define XF86XK_WLAN                0x1008FF95
 
234
#define XF86XK_UWB                 0x1008FF96
 
235
#define XF86XK_AudioForward        0x1008FF97
 
236
#define XF86XK_AudioRepeat         0x1008FF98
 
237
#define XF86XK_AudioRandomPlay     0x1008FF99
 
238
#define XF86XK_Subtitle            0x1008FF9A
 
239
#define XF86XK_AudioCycleTrack     0x1008FF9B
 
240
#define XF86XK_Time                0x1008FF9F
 
241
#define XF86XK_Select              0x1008FFA0
 
242
#define XF86XK_View                0x1008FFA1
 
243
#define XF86XK_TopMenu             0x1008FFA2
 
244
#define XF86XK_Suspend             0x1008FFA7
 
245
#define XF86XK_Hibernate           0x1008FFA8
 
246
#define XF86XK_TouchpadToggle      0x1008FFA9
 
247
#define XF86XK_TouchpadOn          0x1008FFB0
 
248
#define XF86XK_TouchpadOff         0x1008FFB1
 
249
 
 
250
 
 
251
// end of XF86keysyms.h
 
252
 
 
253
QT_BEGIN_NAMESPACE
 
254
 
 
255
// keyboard mapping table
 
256
static const unsigned int KeyTbl[] = {
 
257
 
 
258
    // misc keys
 
259
 
 
260
    XK_Escape,                  Qt::Key_Escape,
 
261
    XK_Tab,                     Qt::Key_Tab,
 
262
    XK_ISO_Left_Tab,            Qt::Key_Backtab,
 
263
    XK_BackSpace,               Qt::Key_Backspace,
 
264
    XK_Return,                  Qt::Key_Return,
 
265
    XK_Insert,                  Qt::Key_Insert,
 
266
    XK_Delete,                  Qt::Key_Delete,
 
267
    XK_Clear,                   Qt::Key_Delete,
 
268
    XK_Pause,                   Qt::Key_Pause,
 
269
    XK_Print,                   Qt::Key_Print,
 
270
    0x1005FF60,                 Qt::Key_SysReq,         // hardcoded Sun SysReq
 
271
    0x1007ff00,                 Qt::Key_SysReq,         // hardcoded X386 SysReq
 
272
 
 
273
    // cursor movement
 
274
 
 
275
    XK_Home,                    Qt::Key_Home,
 
276
    XK_End,                     Qt::Key_End,
 
277
    XK_Left,                    Qt::Key_Left,
 
278
    XK_Up,                      Qt::Key_Up,
 
279
    XK_Right,                   Qt::Key_Right,
 
280
    XK_Down,                    Qt::Key_Down,
 
281
    XK_Prior,                   Qt::Key_PageUp,
 
282
    XK_Next,                    Qt::Key_PageDown,
 
283
 
 
284
    // modifiers
 
285
 
 
286
    XK_Shift_L,                 Qt::Key_Shift,
 
287
    XK_Shift_R,                 Qt::Key_Shift,
 
288
    XK_Shift_Lock,              Qt::Key_Shift,
 
289
    XK_Control_L,               Qt::Key_Control,
 
290
    XK_Control_R,               Qt::Key_Control,
 
291
    XK_Meta_L,                  Qt::Key_Meta,
 
292
    XK_Meta_R,                  Qt::Key_Meta,
 
293
    XK_Alt_L,                   Qt::Key_Alt,
 
294
    XK_Alt_R,                   Qt::Key_Alt,
 
295
    XK_Caps_Lock,               Qt::Key_CapsLock,
 
296
    XK_Num_Lock,                Qt::Key_NumLock,
 
297
    XK_Scroll_Lock,             Qt::Key_ScrollLock,
 
298
    XK_Super_L,                 Qt::Key_Super_L,
 
299
    XK_Super_R,                 Qt::Key_Super_R,
 
300
    XK_Menu,                    Qt::Key_Menu,
 
301
    XK_Hyper_L,                 Qt::Key_Hyper_L,
 
302
    XK_Hyper_R,                 Qt::Key_Hyper_R,
 
303
    XK_Help,                    Qt::Key_Help,
 
304
    0x1000FF74,                 Qt::Key_Backtab,        // hardcoded HP backtab
 
305
    0x1005FF10,                 Qt::Key_F11,            // hardcoded Sun F36 (labeled F11)
 
306
    0x1005FF11,                 Qt::Key_F12,            // hardcoded Sun F37 (labeled F12)
 
307
 
 
308
    // numeric and function keypad keys
 
309
 
 
310
    XK_KP_Space,                Qt::Key_Space,
 
311
    XK_KP_Tab,                  Qt::Key_Tab,
 
312
    XK_KP_Enter,                Qt::Key_Enter,
 
313
    //XK_KP_F1,                 Qt::Key_F1,
 
314
    //XK_KP_F2,                 Qt::Key_F2,
 
315
    //XK_KP_F3,                 Qt::Key_F3,
 
316
    //XK_KP_F4,                 Qt::Key_F4,
 
317
    XK_KP_Home,                 Qt::Key_Home,
 
318
    XK_KP_Left,                 Qt::Key_Left,
 
319
    XK_KP_Up,                   Qt::Key_Up,
 
320
    XK_KP_Right,                Qt::Key_Right,
 
321
    XK_KP_Down,                 Qt::Key_Down,
 
322
    XK_KP_Prior,                Qt::Key_PageUp,
 
323
    XK_KP_Next,                 Qt::Key_PageDown,
 
324
    XK_KP_End,                  Qt::Key_End,
 
325
    XK_KP_Begin,                Qt::Key_Clear,
 
326
    XK_KP_Insert,               Qt::Key_Insert,
 
327
    XK_KP_Delete,               Qt::Key_Delete,
 
328
    XK_KP_Equal,                Qt::Key_Equal,
 
329
    XK_KP_Multiply,             Qt::Key_Asterisk,
 
330
    XK_KP_Add,                  Qt::Key_Plus,
 
331
    XK_KP_Separator,            Qt::Key_Comma,
 
332
    XK_KP_Subtract,             Qt::Key_Minus,
 
333
    XK_KP_Decimal,              Qt::Key_Period,
 
334
    XK_KP_Divide,               Qt::Key_Slash,
 
335
 
 
336
    // International input method support keys
 
337
 
 
338
    // International & multi-key character composition
 
339
    XK_ISO_Level3_Shift,        Qt::Key_AltGr,
 
340
    XK_Multi_key,               Qt::Key_Multi_key,
 
341
    XK_Codeinput,               Qt::Key_Codeinput,
 
342
    XK_SingleCandidate,         Qt::Key_SingleCandidate,
 
343
    XK_MultipleCandidate,       Qt::Key_MultipleCandidate,
 
344
    XK_PreviousCandidate,       Qt::Key_PreviousCandidate,
 
345
 
 
346
    // Misc Functions
 
347
    XK_Mode_switch,             Qt::Key_Mode_switch,
 
348
    XK_script_switch,           Qt::Key_Mode_switch,
 
349
 
 
350
    // Japanese keyboard support
 
351
    XK_Kanji,                   Qt::Key_Kanji,
 
352
    XK_Muhenkan,                Qt::Key_Muhenkan,
 
353
    //XK_Henkan_Mode,           Qt::Key_Henkan_Mode,
 
354
    XK_Henkan_Mode,             Qt::Key_Henkan,
 
355
    XK_Henkan,                  Qt::Key_Henkan,
 
356
    XK_Romaji,                  Qt::Key_Romaji,
 
357
    XK_Hiragana,                Qt::Key_Hiragana,
 
358
    XK_Katakana,                Qt::Key_Katakana,
 
359
    XK_Hiragana_Katakana,       Qt::Key_Hiragana_Katakana,
 
360
    XK_Zenkaku,                 Qt::Key_Zenkaku,
 
361
    XK_Hankaku,                 Qt::Key_Hankaku,
 
362
    XK_Zenkaku_Hankaku,         Qt::Key_Zenkaku_Hankaku,
 
363
    XK_Touroku,                 Qt::Key_Touroku,
 
364
    XK_Massyo,                  Qt::Key_Massyo,
 
365
    XK_Kana_Lock,               Qt::Key_Kana_Lock,
 
366
    XK_Kana_Shift,              Qt::Key_Kana_Shift,
 
367
    XK_Eisu_Shift,              Qt::Key_Eisu_Shift,
 
368
    XK_Eisu_toggle,             Qt::Key_Eisu_toggle,
 
369
    //XK_Kanji_Bangou,          Qt::Key_Kanji_Bangou,
 
370
    //XK_Zen_Koho,              Qt::Key_Zen_Koho,
 
371
    //XK_Mae_Koho,              Qt::Key_Mae_Koho,
 
372
    XK_Kanji_Bangou,            Qt::Key_Codeinput,
 
373
    XK_Zen_Koho,                Qt::Key_MultipleCandidate,
 
374
    XK_Mae_Koho,                Qt::Key_PreviousCandidate,
 
375
 
 
376
#ifdef XK_KOREAN
 
377
    // Korean keyboard support
 
378
    XK_Hangul,                  Qt::Key_Hangul,
 
379
    XK_Hangul_Start,            Qt::Key_Hangul_Start,
 
380
    XK_Hangul_End,              Qt::Key_Hangul_End,
 
381
    XK_Hangul_Hanja,            Qt::Key_Hangul_Hanja,
 
382
    XK_Hangul_Jamo,             Qt::Key_Hangul_Jamo,
 
383
    XK_Hangul_Romaja,           Qt::Key_Hangul_Romaja,
 
384
    //XK_Hangul_Codeinput,      Qt::Key_Hangul_Codeinput,
 
385
    XK_Hangul_Codeinput,        Qt::Key_Codeinput,
 
386
    XK_Hangul_Jeonja,           Qt::Key_Hangul_Jeonja,
 
387
    XK_Hangul_Banja,            Qt::Key_Hangul_Banja,
 
388
    XK_Hangul_PreHanja,         Qt::Key_Hangul_PreHanja,
 
389
    XK_Hangul_PostHanja,        Qt::Key_Hangul_PostHanja,
 
390
    //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
 
391
    //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
 
392
    //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
 
393
    XK_Hangul_SingleCandidate,  Qt::Key_SingleCandidate,
 
394
    XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
 
395
    XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
 
396
    XK_Hangul_Special,          Qt::Key_Hangul_Special,
 
397
    //XK_Hangul_switch,         Qt::Key_Hangul_switch,
 
398
    XK_Hangul_switch,           Qt::Key_Mode_switch,
 
399
#endif  // XK_KOREAN
 
400
 
 
401
    // dead keys
 
402
    XK_dead_grave,              Qt::Key_Dead_Grave,
 
403
    XK_dead_acute,              Qt::Key_Dead_Acute,
 
404
    XK_dead_circumflex,         Qt::Key_Dead_Circumflex,
 
405
    XK_dead_tilde,              Qt::Key_Dead_Tilde,
 
406
    XK_dead_macron,             Qt::Key_Dead_Macron,
 
407
    XK_dead_breve,              Qt::Key_Dead_Breve,
 
408
    XK_dead_abovedot,           Qt::Key_Dead_Abovedot,
 
409
    XK_dead_diaeresis,          Qt::Key_Dead_Diaeresis,
 
410
    XK_dead_abovering,          Qt::Key_Dead_Abovering,
 
411
    XK_dead_doubleacute,        Qt::Key_Dead_Doubleacute,
 
412
    XK_dead_caron,              Qt::Key_Dead_Caron,
 
413
    XK_dead_cedilla,            Qt::Key_Dead_Cedilla,
 
414
    XK_dead_ogonek,             Qt::Key_Dead_Ogonek,
 
415
    XK_dead_iota,               Qt::Key_Dead_Iota,
 
416
    XK_dead_voiced_sound,       Qt::Key_Dead_Voiced_Sound,
 
417
    XK_dead_semivoiced_sound,   Qt::Key_Dead_Semivoiced_Sound,
 
418
    XK_dead_belowdot,           Qt::Key_Dead_Belowdot,
 
419
    XK_dead_hook,               Qt::Key_Dead_Hook,
 
420
    XK_dead_horn,               Qt::Key_Dead_Horn,
 
421
 
 
422
    // Special keys from X.org - This include multimedia keys,
 
423
        // wireless/bluetooth/uwb keys, special launcher keys, etc.
 
424
    XF86XK_Back,                Qt::Key_Back,
 
425
    XF86XK_Forward,             Qt::Key_Forward,
 
426
    XF86XK_Stop,                Qt::Key_Stop,
 
427
    XF86XK_Refresh,             Qt::Key_Refresh,
 
428
    XF86XK_Favorites,           Qt::Key_Favorites,
 
429
    XF86XK_AudioMedia,          Qt::Key_LaunchMedia,
 
430
    XF86XK_OpenURL,             Qt::Key_OpenUrl,
 
431
    XF86XK_HomePage,            Qt::Key_HomePage,
 
432
    XF86XK_Search,              Qt::Key_Search,
 
433
    XF86XK_AudioLowerVolume,    Qt::Key_VolumeDown,
 
434
    XF86XK_AudioMute,           Qt::Key_VolumeMute,
 
435
    XF86XK_AudioRaiseVolume,    Qt::Key_VolumeUp,
 
436
    XF86XK_AudioPlay,           Qt::Key_MediaPlay,
 
437
    XF86XK_AudioStop,           Qt::Key_MediaStop,
 
438
    XF86XK_AudioPrev,           Qt::Key_MediaPrevious,
 
439
    XF86XK_AudioNext,           Qt::Key_MediaNext,
 
440
    XF86XK_AudioRecord,         Qt::Key_MediaRecord,
 
441
    XF86XK_Mail,                Qt::Key_LaunchMail,
 
442
    XF86XK_MyComputer,          Qt::Key_Launch0,  // ### Qt 6: remap properly
 
443
    XF86XK_Calculator,          Qt::Key_Launch1,
 
444
    XF86XK_Memo,                Qt::Key_Memo,
 
445
    XF86XK_ToDoList,            Qt::Key_ToDoList,
 
446
    XF86XK_Calendar,            Qt::Key_Calendar,
 
447
    XF86XK_PowerDown,           Qt::Key_PowerDown,
 
448
    XF86XK_ContrastAdjust,      Qt::Key_ContrastAdjust,
 
449
    XF86XK_Standby,             Qt::Key_Standby,
 
450
    XF86XK_MonBrightnessUp,     Qt::Key_MonBrightnessUp,
 
451
    XF86XK_MonBrightnessDown,   Qt::Key_MonBrightnessDown,
 
452
    XF86XK_KbdLightOnOff,       Qt::Key_KeyboardLightOnOff,
 
453
    XF86XK_KbdBrightnessUp,     Qt::Key_KeyboardBrightnessUp,
 
454
    XF86XK_KbdBrightnessDown,   Qt::Key_KeyboardBrightnessDown,
 
455
    XF86XK_PowerOff,            Qt::Key_PowerOff,
 
456
    XF86XK_WakeUp,              Qt::Key_WakeUp,
 
457
    XF86XK_Eject,               Qt::Key_Eject,
 
458
    XF86XK_ScreenSaver,         Qt::Key_ScreenSaver,
 
459
    XF86XK_WWW,                 Qt::Key_WWW,
 
460
    XF86XK_Sleep,               Qt::Key_Sleep,
 
461
    XF86XK_LightBulb,           Qt::Key_LightBulb,
 
462
    XF86XK_Shop,                Qt::Key_Shop,
 
463
    XF86XK_History,             Qt::Key_History,
 
464
    XF86XK_AddFavorite,         Qt::Key_AddFavorite,
 
465
    XF86XK_HotLinks,            Qt::Key_HotLinks,
 
466
    XF86XK_BrightnessAdjust,    Qt::Key_BrightnessAdjust,
 
467
    XF86XK_Finance,             Qt::Key_Finance,
 
468
    XF86XK_Community,           Qt::Key_Community,
 
469
    XF86XK_AudioRewind,         Qt::Key_AudioRewind,
 
470
    XF86XK_BackForward,         Qt::Key_BackForward,
 
471
    XF86XK_ApplicationLeft,     Qt::Key_ApplicationLeft,
 
472
    XF86XK_ApplicationRight,    Qt::Key_ApplicationRight,
 
473
    XF86XK_Book,                Qt::Key_Book,
 
474
    XF86XK_CD,                  Qt::Key_CD,
 
475
    XF86XK_Calculater,          Qt::Key_Calculator,
 
476
    XF86XK_Clear,               Qt::Key_Clear,
 
477
    XF86XK_ClearGrab,           Qt::Key_ClearGrab,
 
478
    XF86XK_Close,               Qt::Key_Close,
 
479
    XF86XK_Copy,                Qt::Key_Copy,
 
480
    XF86XK_Cut,                 Qt::Key_Cut,
 
481
    XF86XK_Display,             Qt::Key_Display,
 
482
    XF86XK_DOS,                 Qt::Key_DOS,
 
483
    XF86XK_Documents,           Qt::Key_Documents,
 
484
    XF86XK_Excel,               Qt::Key_Excel,
 
485
    XF86XK_Explorer,            Qt::Key_Explorer,
 
486
    XF86XK_Game,                Qt::Key_Game,
 
487
    XF86XK_Go,                  Qt::Key_Go,
 
488
    XF86XK_iTouch,              Qt::Key_iTouch,
 
489
    XF86XK_LogOff,              Qt::Key_LogOff,
 
490
    XF86XK_Market,              Qt::Key_Market,
 
491
    XF86XK_Meeting,             Qt::Key_Meeting,
 
492
    XF86XK_MenuKB,              Qt::Key_MenuKB,
 
493
    XF86XK_MenuPB,              Qt::Key_MenuPB,
 
494
    XF86XK_MySites,             Qt::Key_MySites,
 
495
    XF86XK_News,                Qt::Key_News,
 
496
    XF86XK_OfficeHome,          Qt::Key_OfficeHome,
 
497
    XF86XK_Option,              Qt::Key_Option,
 
498
    XF86XK_Paste,               Qt::Key_Paste,
 
499
    XF86XK_Phone,               Qt::Key_Phone,
 
500
    XF86XK_Reply,               Qt::Key_Reply,
 
501
    XF86XK_Reload,              Qt::Key_Reload,
 
502
    XF86XK_RotateWindows,       Qt::Key_RotateWindows,
 
503
    XF86XK_RotationPB,          Qt::Key_RotationPB,
 
504
    XF86XK_RotationKB,          Qt::Key_RotationKB,
 
505
    XF86XK_Save,                Qt::Key_Save,
 
506
    XF86XK_Send,                Qt::Key_Send,
 
507
    XF86XK_Spell,               Qt::Key_Spell,
 
508
    XF86XK_SplitScreen,         Qt::Key_SplitScreen,
 
509
    XF86XK_Support,             Qt::Key_Support,
 
510
    XF86XK_TaskPane,            Qt::Key_TaskPane,
 
511
    XF86XK_Terminal,            Qt::Key_Terminal,
 
512
    XF86XK_Tools,               Qt::Key_Tools,
 
513
    XF86XK_Travel,              Qt::Key_Travel,
 
514
    XF86XK_Video,               Qt::Key_Video,
 
515
    XF86XK_Word,                Qt::Key_Word,
 
516
    XF86XK_Xfer,                Qt::Key_Xfer,
 
517
    XF86XK_ZoomIn,              Qt::Key_ZoomIn,
 
518
    XF86XK_ZoomOut,             Qt::Key_ZoomOut,
 
519
    XF86XK_Away,                Qt::Key_Away,
 
520
    XF86XK_Messenger,           Qt::Key_Messenger,
 
521
    XF86XK_WebCam,              Qt::Key_WebCam,
 
522
    XF86XK_MailForward,         Qt::Key_MailForward,
 
523
    XF86XK_Pictures,            Qt::Key_Pictures,
 
524
    XF86XK_Music,               Qt::Key_Music,
 
525
    XF86XK_Battery,             Qt::Key_Battery,
 
526
    XF86XK_Bluetooth,           Qt::Key_Bluetooth,
 
527
    XF86XK_WLAN,                Qt::Key_WLAN,
 
528
    XF86XK_UWB,                 Qt::Key_UWB,
 
529
    XF86XK_AudioForward,        Qt::Key_AudioForward,
 
530
    XF86XK_AudioRepeat,         Qt::Key_AudioRepeat,
 
531
    XF86XK_AudioRandomPlay,     Qt::Key_AudioRandomPlay,
 
532
    XF86XK_Subtitle,            Qt::Key_Subtitle,
 
533
    XF86XK_AudioCycleTrack,     Qt::Key_AudioCycleTrack,
 
534
    XF86XK_Time,                Qt::Key_Time,
 
535
    XF86XK_Select,              Qt::Key_Select,
 
536
    XF86XK_View,                Qt::Key_View,
 
537
    XF86XK_TopMenu,             Qt::Key_TopMenu,
 
538
    XF86XK_Bluetooth,           Qt::Key_Bluetooth,
 
539
    XF86XK_Suspend,             Qt::Key_Suspend,
 
540
    XF86XK_Hibernate,           Qt::Key_Hibernate,
 
541
    XF86XK_TouchpadToggle,      Qt::Key_TouchpadToggle,
 
542
    XF86XK_TouchpadOn,          Qt::Key_TouchpadOn,
 
543
    XF86XK_TouchpadOff,         Qt::Key_TouchpadOff,
 
544
    XF86XK_Launch0,             Qt::Key_Launch2, // ### Qt 6: remap properly
 
545
    XF86XK_Launch1,             Qt::Key_Launch3,
 
546
    XF86XK_Launch2,             Qt::Key_Launch4,
 
547
    XF86XK_Launch3,             Qt::Key_Launch5,
 
548
    XF86XK_Launch4,             Qt::Key_Launch6,
 
549
    XF86XK_Launch5,             Qt::Key_Launch7,
 
550
    XF86XK_Launch6,             Qt::Key_Launch8,
 
551
    XF86XK_Launch7,             Qt::Key_Launch9,
 
552
    XF86XK_Launch8,             Qt::Key_LaunchA,
 
553
    XF86XK_Launch9,             Qt::Key_LaunchB,
 
554
    XF86XK_LaunchA,             Qt::Key_LaunchC,
 
555
    XF86XK_LaunchB,             Qt::Key_LaunchD,
 
556
    XF86XK_LaunchC,             Qt::Key_LaunchE,
 
557
    XF86XK_LaunchD,             Qt::Key_LaunchF,
 
558
    XF86XK_LaunchE,             Qt::Key_LaunchG,
 
559
    XF86XK_LaunchF,             Qt::Key_LaunchH,
 
560
 
 
561
    0,                          0
 
562
};
 
563
 
 
564
static const unsigned short katakanaKeysymsToUnicode[] = {
 
565
    0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1,
 
566
    0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3,
 
567
    0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
 
568
    0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD,
 
569
    0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC,
 
570
    0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE,
 
571
    0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9,
 
572
    0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C
 
573
};
 
574
 
 
575
static const unsigned short cyrillicKeysymsToUnicode[] = {
 
576
    0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
 
577
    0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f,
 
578
    0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
 
579
    0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f,
 
580
    0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
 
581
    0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
 
582
    0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
 
583
    0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
 
584
    0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
 
585
    0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
 
586
    0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
 
587
    0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
 
588
};
 
589
 
 
590
static const unsigned short greekKeysymsToUnicode[] = {
 
591
    0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
 
592
    0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015,
 
593
    0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
 
594
    0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000,
 
595
    0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
 
596
    0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
 
597
    0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
 
598
    0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
599
    0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
 
600
    0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
 
601
    0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
 
602
    0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
 
603
};
 
604
 
 
605
static const unsigned short technicalKeysymsToUnicode[] = {
 
606
    0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1,
 
607
    0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8,
 
608
    0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
609
    0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B,
 
610
    0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000,
 
611
    0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261,
 
612
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000,
 
613
    0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228,
 
614
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
615
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202,
 
616
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000,
 
617
    0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000
 
618
};
 
619
 
 
620
static const unsigned short specialKeysymsToUnicode[] = {
 
621
    0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000,
 
622
    0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
 
623
    0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
 
624
    0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
 
625
};
 
626
 
 
627
static const unsigned short publishingKeysymsToUnicode[] = {
 
628
    0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009,
 
629
    0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025,
 
630
    0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a,
 
631
    0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000,
 
632
    0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000,
 
633
    0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af,
 
634
    0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033,
 
635
    0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae,
 
636
    0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa,
 
637
    0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000,
 
638
    0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642,
 
639
    0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000
 
640
};
 
641
 
 
642
static const unsigned short aplKeysymsToUnicode[] = {
 
643
    0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000,
 
644
    0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
645
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
646
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
647
    0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000,
 
648
    0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb,
 
649
    0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000,
 
650
    0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000,
 
651
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
652
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
653
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 
654
    0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000
 
655
};
 
656
 
 
657
static const unsigned short koreanKeysymsToUnicode[] = {
 
658
    0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
 
659
    0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
 
660
    0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
 
661
    0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f,
 
662
    0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157,
 
663
    0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f,
 
664
    0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab,
 
665
    0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3,
 
666
    0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb,
 
667
    0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d,
 
668
    0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e,
 
669
    0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9
 
670
};
 
671
 
 
672
static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
 
673
{
 
674
    switch (byte3) {
 
675
    case 0x04:
 
676
        // katakana
 
677
        if (byte4 > 0xa0 && byte4 < 0xe0)
 
678
            return QChar(katakanaKeysymsToUnicode[byte4 - 0xa0]);
 
679
        else if (byte4 == 0x7e)
 
680
            return QChar(0x203e); // Overline
 
681
        break;
 
682
    case 0x06:
 
683
        // russian, use lookup table
 
684
        if (byte4 > 0xa0)
 
685
            return QChar(cyrillicKeysymsToUnicode[byte4 - 0xa0]);
 
686
        break;
 
687
    case 0x07:
 
688
        // greek
 
689
        if (byte4 > 0xa0)
 
690
            return QChar(greekKeysymsToUnicode[byte4 - 0xa0]);
 
691
        break;
 
692
    case 0x08:
 
693
        // technical
 
694
        if (byte4 > 0xa0)
 
695
            return QChar(technicalKeysymsToUnicode[byte4 - 0xa0]);
 
696
        break;
 
697
    case 0x09:
 
698
        // special
 
699
        if (byte4 >= 0xe0)
 
700
            return QChar(specialKeysymsToUnicode[byte4 - 0xe0]);
 
701
        break;
 
702
    case 0x0a:
 
703
        // publishing
 
704
        if (byte4 > 0xa0)
 
705
            return QChar(publishingKeysymsToUnicode[byte4 - 0xa0]);
 
706
        break;
 
707
    case 0x0b:
 
708
        // APL
 
709
        if (byte4 > 0xa0)
 
710
            return QChar(aplKeysymsToUnicode[byte4 - 0xa0]);
 
711
        break;
 
712
    case 0x0e:
 
713
        // Korean
 
714
        if (byte4 > 0xa0)
 
715
            return QChar(koreanKeysymsToUnicode[byte4 - 0xa0]);
 
716
        break;
 
717
    default:
 
718
        break;
 
719
    }
 
720
    return QChar(0x0);
 
721
}
 
722
 
 
723
Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s)
 
724
{
 
725
    Qt::KeyboardModifiers ret = 0;
 
726
    if (s & XCB_MOD_MASK_SHIFT)
 
727
        ret |= Qt::ShiftModifier;
 
728
    if (s & XCB_MOD_MASK_CONTROL)
 
729
        ret |= Qt::ControlModifier;
 
730
    if (s & m_alt_mask)
 
731
        ret |= Qt::AltModifier;
 
732
    if (s & m_meta_mask)
 
733
        ret |= Qt::MetaModifier;
 
734
    return ret;
 
735
}
 
736
 
 
737
int QXcbKeyboard::translateKeySym(uint key) const
 
738
{
 
739
    int code = -1;
 
740
    int i = 0;                                // any other keys
 
741
    while (KeyTbl[i]) {
 
742
        if (key == KeyTbl[i]) {
 
743
            code = (int)KeyTbl[i+1];
 
744
            break;
 
745
        }
 
746
        i += 2;
 
747
    }
 
748
    if (m_meta_mask) {
 
749
        // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
 
750
        if (m_meta_mask == m_super_mask && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) {
 
751
            code = Qt::Key_Meta;
 
752
        } else if (m_meta_mask == m_hyper_mask && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) {
 
753
            code = Qt::Key_Meta;
 
754
        }
 
755
    }
 
756
    return code;
 
757
}
 
758
 
 
759
QString QXcbKeyboard::translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
 
760
                                      int &code, Qt::KeyboardModifiers &modifiers,
 
761
                                      QByteArray &chars, int &count)
 
762
{
 
763
    // all keysyms smaller than 0xff00 are actally keys that can be mapped to unicode chars
 
764
 
 
765
    QTextCodec *mapper = QTextCodec::codecForLocale();
 
766
    QChar converted;
 
767
 
 
768
    if (/*count == 0 &&*/ keysym < 0xff00) {
 
769
        unsigned char byte3 = (unsigned char)(keysym >> 8);
 
770
        int mib = -1;
 
771
        switch(byte3) {
 
772
        case 0: // Latin 1
 
773
        case 1: // Latin 2
 
774
        case 2: //latin 3
 
775
        case 3: // latin4
 
776
            mib = byte3 + 4; break;
 
777
        case 5: // arabic
 
778
            mib = 82; break;
 
779
        case 12: // Hebrew
 
780
            mib = 85; break;
 
781
        case 13: // Thai
 
782
            mib = 2259; break;
 
783
        case 4: // kana
 
784
        case 6: // cyrillic
 
785
        case 7: // greek
 
786
        case 8: // technical, no mapping here at the moment
 
787
        case 9: // Special
 
788
        case 10: // Publishing
 
789
        case 11: // APL
 
790
        case 14: // Korean, no mapping
 
791
            mib = -1; // manual conversion
 
792
            mapper= 0;
 
793
#if !defined(QT_NO_XIM)
 
794
            converted = keysymToUnicode(byte3, keysym & 0xff);
 
795
#endif
 
796
        case 0x20:
 
797
            // currency symbols
 
798
            if (keysym >= 0x20a0 && keysym <= 0x20ac) {
 
799
                mib = -1; // manual conversion
 
800
                mapper = 0;
 
801
                converted = (uint)keysym;
 
802
            }
 
803
            break;
 
804
        default:
 
805
            break;
 
806
        }
 
807
        if (mib != -1) {
 
808
            mapper = QTextCodec::codecForMib(mib);
 
809
            if (chars.isEmpty())
 
810
                chars.resize(1);
 
811
            chars[0] = (unsigned char) (keysym & 0xff); // get only the fourth bit for conversion later
 
812
            count = 1;
 
813
        }
 
814
    } else if (keysym >= 0x1000000 && keysym <= 0x100ffff) {
 
815
        converted = (ushort) (keysym - 0x1000000);
 
816
        mapper = 0;
 
817
    }
 
818
    if (count < (int)chars.size()-1)
 
819
        chars[count] = '\0';
 
820
 
 
821
    QString text;
 
822
    if (!mapper && converted.unicode() != 0x0) {
 
823
        text = converted;
 
824
    } else if (!chars.isEmpty()) {
 
825
        // convert chars (8bit) to text (unicode).
 
826
        if (mapper)
 
827
            text = mapper->toUnicode(chars.data(), count, 0);
 
828
        if (text.isEmpty()) {
 
829
            // no mapper, or codec couldn't convert to unicode (this
 
830
            // can happen when running in the C locale or with no LANG
 
831
            // set). try converting from latin-1
 
832
            text = QString::fromLatin1(chars);
 
833
        }
 
834
    }
 
835
 
 
836
    modifiers = translateModifiers(xmodifiers);
 
837
 
 
838
    // Commentary in X11/keysymdef says that X codes match ASCII, so it
 
839
    // is safe to use the locale functions to process X codes in ISO8859-1.
 
840
    //
 
841
    // This is mainly for compatibility - applications should not use the
 
842
    // Qt keycodes between 128 and 255, but should rather use the
 
843
    // QKeyEvent::text().
 
844
    //
 
845
    if (keysym < 128 || (keysym < 256 && (!mapper || mapper->mibEnum()==4))) {
 
846
        // upper-case key, if known
 
847
        code = isprint((int)keysym) ? toupper((int)keysym) : 0;
 
848
    } else if (keysym >= XK_F1 && keysym <= XK_F35) {
 
849
        // function keys
 
850
        code = Qt::Key_F1 + ((int)keysym - XK_F1);
 
851
    } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) {
 
852
        if (keysym >= XK_KP_0) {
 
853
            // numeric keypad keys
 
854
            code = Qt::Key_0 + ((int)keysym - XK_KP_0);
 
855
        } else {
 
856
            code = translateKeySym(keysym);
 
857
        }
 
858
        modifiers |= Qt::KeypadModifier;
 
859
    } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) {
 
860
        code = text.unicode()->toUpper().unicode();
 
861
    } else {
 
862
        // any other keys
 
863
        code = translateKeySym(keysym);
 
864
 
 
865
        if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) {
 
866
            // map shift+tab to shift+backtab, QShortcutMap knows about it
 
867
            // and will handle it.
 
868
            code = Qt::Key_Backtab;
 
869
            text = QString();
 
870
        }
 
871
    }
 
872
 
 
873
    return text;
 
874
}
 
875
 
 
876
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
 
877
    : QXcbObject(connection)
 
878
    , m_autorepeat_code(0)
 
879
{
 
880
    m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
 
881
    setupModifiers();
 
882
}
 
883
 
 
884
QXcbKeyboard::~QXcbKeyboard()
 
885
{
 
886
    xcb_key_symbols_free(m_key_symbols);
 
887
}
 
888
 
 
889
void QXcbKeyboard::setupModifiers()
 
890
{
 
891
    m_alt_mask = 0;
 
892
    m_super_mask = 0;
 
893
    m_hyper_mask = 0;
 
894
    m_meta_mask = 0;
 
895
    m_mode_switch_mask = 0;
 
896
    m_num_lock_mask = 0;
 
897
    m_caps_lock_mask = 0;
 
898
 
 
899
    xcb_generic_error_t *error = 0;
 
900
    xcb_connection_t *conn = xcb_connection();
 
901
    xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn);
 
902
    xcb_get_modifier_mapping_reply_t *modMapReply =
 
903
        xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
 
904
    if (error) {
 
905
        qWarning("QXcbKeyboard: failed to get modifier mapping");
 
906
        free(error);
 
907
        return;
 
908
    }
 
909
 
 
910
    // for Alt and Meta L and R are the same
 
911
    static const xcb_keysym_t symbols[] = {
 
912
        XK_Alt_L, XK_Meta_L, XK_Super_L, XK_Super_R,
 
913
        XK_Hyper_L, XK_Hyper_R, XK_Num_Lock, XK_Mode_switch, XK_Caps_Lock,
 
914
    };
 
915
    static const size_t numSymbols = sizeof symbols / sizeof *symbols;
 
916
 
 
917
    // Figure out the modifier mapping, ICCCM 6.6
 
918
    xcb_keycode_t* modKeyCodes[numSymbols];
 
919
    for (size_t i = 0; i < numSymbols; ++i)
 
920
        modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]);
 
921
 
 
922
    xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply);
 
923
    const int w = modMapReply->keycodes_per_modifier;
 
924
    for (size_t i = 0; i < numSymbols; ++i) {
 
925
        for (int bit = 0; bit < 8; ++bit) {
 
926
            uint mask = 1 << bit;
 
927
            for (int x = 0; x < w; ++x) {
 
928
                xcb_keycode_t keyCode = modMap[x + bit * w];
 
929
                xcb_keycode_t *itk = modKeyCodes[i];
 
930
                while (itk && *itk != XCB_NO_SYMBOL)
 
931
                    if (*itk++ == keyCode)
 
932
                        setMask(symbols[i], mask);
 
933
            }
 
934
        }
 
935
    }
 
936
 
 
937
    for (size_t i = 0; i < numSymbols; ++i)
 
938
        free(modKeyCodes[i]);
 
939
    free(modMapReply);
 
940
}
 
941
 
 
942
void QXcbKeyboard::setMask(uint sym, uint mask)
 
943
{
 
944
    if (m_alt_mask == 0
 
945
        && m_meta_mask != mask
 
946
        && m_super_mask != mask
 
947
        && m_hyper_mask != mask
 
948
        && (sym == XK_Alt_L || sym == XK_Alt_R))
 
949
        m_alt_mask = mask;
 
950
 
 
951
    if (m_meta_mask == 0
 
952
        && m_alt_mask != mask
 
953
        && m_super_mask != mask
 
954
        && m_hyper_mask != mask
 
955
        && (sym == XK_Meta_L || sym == XK_Meta_R))
 
956
        m_meta_mask = mask;
 
957
 
 
958
    if (m_super_mask == 0
 
959
        && m_alt_mask != mask
 
960
        && m_meta_mask != mask
 
961
        && m_hyper_mask != mask
 
962
        && (sym == XK_Super_L || sym == XK_Super_R))
 
963
        m_super_mask = mask;
 
964
 
 
965
    if (m_hyper_mask == 0
 
966
        && m_alt_mask != mask
 
967
        && m_meta_mask != mask
 
968
        && m_super_mask != mask
 
969
        && (sym == XK_Hyper_L || sym == XK_Hyper_R))
 
970
        m_hyper_mask = mask;
 
971
 
 
972
    if (m_mode_switch_mask == 0
 
973
        && m_alt_mask != mask
 
974
        && m_meta_mask != mask
 
975
        && m_super_mask != mask
 
976
        && m_hyper_mask != mask
 
977
        && sym == XK_Mode_switch)
 
978
        m_mode_switch_mask = mask;
 
979
 
 
980
    if (m_num_lock_mask == 0 && sym == XK_Num_Lock)
 
981
        m_num_lock_mask = mask;
 
982
 
 
983
    if (m_caps_lock_mask == 0 && sym == XK_Caps_Lock)
 
984
        m_caps_lock_mask = mask;
 
985
}
 
986
 
 
987
// #define XCB_KEYBOARD_DEBUG
 
988
 
 
989
class KeyChecker
 
990
{
 
991
public:
 
992
    KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time)
 
993
        : m_window(window)
 
994
        , m_code(code)
 
995
        , m_time(time)
 
996
        , m_error(false)
 
997
        , m_release(true)
 
998
    {
 
999
    }
 
1000
 
 
1001
    bool checkEvent(xcb_generic_event_t *ev)
 
1002
    {
 
1003
        if (m_error || !ev)
 
1004
            return false;
 
1005
 
 
1006
        int type = ev->response_type & ~0x80;
 
1007
        if (type != XCB_KEY_PRESS && type != XCB_KEY_RELEASE)
 
1008
            return false;
 
1009
 
 
1010
        xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev;
 
1011
 
 
1012
        if (event->event != m_window || event->detail != m_code) {
 
1013
            m_error = true;
 
1014
            return false;
 
1015
        }
 
1016
 
 
1017
        if (type == XCB_KEY_PRESS) {
 
1018
            m_error = !m_release || event->time - m_time > 10;
 
1019
            return !m_error;
 
1020
        }
 
1021
 
 
1022
        if (m_release) {
 
1023
            m_error = true;
 
1024
            return false;
 
1025
        }
 
1026
 
 
1027
        m_release = true;
 
1028
        m_time = event->time;
 
1029
 
 
1030
        return false;
 
1031
    }
 
1032
 
 
1033
    bool release() const { return m_release; }
 
1034
    xcb_timestamp_t time() const { return m_time; }
 
1035
 
 
1036
private:
 
1037
    xcb_window_t m_window;
 
1038
    xcb_keycode_t m_code;
 
1039
    xcb_timestamp_t m_time;
 
1040
 
 
1041
    bool m_error;
 
1042
    bool m_release;
 
1043
};
 
1044
 
 
1045
void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code,
 
1046
                                  quint16 state, xcb_timestamp_t time)
 
1047
{
 
1048
    Q_XCB_NOOP(connection());
 
1049
#ifdef XCB_KEYBOARD_DEBUG
 
1050
    printf("key code: %d, state: %d, syms: ", code, state);
 
1051
    for (int i = 0; i <= 5; ++i) {
 
1052
        printf("%d ", xcb_key_symbols_get_keysym(m_key_symbols, code, i));
 
1053
    }
 
1054
    printf("\n");
 
1055
#endif
 
1056
 
 
1057
    QByteArray chars;
 
1058
    xcb_keysym_t sym = lookupString(window, state, code, type, &chars);
 
1059
    QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
 
1060
    QMetaMethod method;
 
1061
 
 
1062
    if (inputContext) {
 
1063
        int methodIndex = inputContext->metaObject()->indexOfMethod("x11FilterEvent(uint,uint,uint,bool)");
 
1064
        if (methodIndex != -1)
 
1065
            method = inputContext->metaObject()->method(methodIndex);
 
1066
    }
 
1067
 
 
1068
    if (method.isValid()) {
 
1069
        bool retval = false;
 
1070
        method.invoke(inputContext, Qt::DirectConnection,
 
1071
                      Q_RETURN_ARG(bool, retval),
 
1072
                      Q_ARG(uint, sym),
 
1073
                      Q_ARG(uint, code),
 
1074
                      Q_ARG(uint, state),
 
1075
                      Q_ARG(bool, type == QEvent::KeyPress));
 
1076
        if (retval)
 
1077
            return;
 
1078
    }
 
1079
 
 
1080
    Qt::KeyboardModifiers modifiers;
 
1081
    int qtcode = 0;
 
1082
    int count = chars.count();
 
1083
    QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count);
 
1084
 
 
1085
    bool isAutoRepeat = false;
 
1086
 
 
1087
    if (type == QEvent::KeyPress) {
 
1088
        if (m_autorepeat_code == code) {
 
1089
            isAutoRepeat = true;
 
1090
            m_autorepeat_code = 0;
 
1091
        }
 
1092
    } else {
 
1093
        // look ahead for auto-repeat
 
1094
        KeyChecker checker(((QXcbWindow *)window->handle())->xcb_window(), code, time);
 
1095
        xcb_generic_event_t *event = connection()->checkEvent(checker);
 
1096
        if (event) {
 
1097
            isAutoRepeat = true;
 
1098
            free(event);
 
1099
        }
 
1100
        m_autorepeat_code = isAutoRepeat ? code : 0;
 
1101
    }
 
1102
 
 
1103
    bool filtered = false;
 
1104
    if (inputContext) {
 
1105
        QKeyEvent event(type, qtcode, modifiers, code, sym, state, string.left(count), isAutoRepeat, count);
 
1106
        event.setTimestamp(time);
 
1107
        filtered = inputContext->filterEvent(&event);
 
1108
    }
 
1109
 
 
1110
    if (!filtered) {
 
1111
        if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
 
1112
            const QPoint globalPos = window->screen()->handle()->cursor()->pos();
 
1113
            const QPoint pos = window->mapFromGlobal(globalPos);
 
1114
            QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
 
1115
        }
 
1116
        QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
 
1117
                                                       code, sym, state, string.left(count), isAutoRepeat);
 
1118
    }
 
1119
 
 
1120
    if (isAutoRepeat && type == QEvent::KeyRelease) {
 
1121
        // since we removed it from the event queue using checkEvent we need to send the key press here
 
1122
        filtered = false;
 
1123
        if (method.isValid()) {
 
1124
            method.invoke(inputContext, Qt::DirectConnection,
 
1125
                          Q_RETURN_ARG(bool, filtered),
 
1126
                          Q_ARG(uint, sym),
 
1127
                          Q_ARG(uint, code),
 
1128
                          Q_ARG(uint, state),
 
1129
                          Q_ARG(bool, true));
 
1130
        }
 
1131
 
 
1132
        if (!filtered && inputContext) {
 
1133
            QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string.left(count), isAutoRepeat, count);
 
1134
            event.setTimestamp(time);
 
1135
            filtered = inputContext->filterEvent(&event);
 
1136
        }
 
1137
        if (!filtered)
 
1138
            QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
 
1139
                                                           code, sym, state, string.left(count), isAutoRepeat);
 
1140
    }
 
1141
}
 
1142
 
 
1143
xcb_keysym_t QXcbKeyboard::lookupString(QWindow *window, uint state, xcb_keycode_t code,
 
1144
                                        QEvent::Type type, QByteArray *chars)
 
1145
{
 
1146
#ifdef XCB_USE_XLIB
 
1147
    xcb_window_t xWindow = static_cast<QXcbWindow *>(window->handle())->xcb_window();
 
1148
    xcb_window_t root = connection()->screens().at(0)->root();
 
1149
    void *xDisplay = connection()->xlib_display();
 
1150
    int xType = (type == QEvent::KeyRelease ? 3 : 2);
 
1151
    return q_XLookupString(xDisplay, xWindow, root, state, code, xType, chars);
 
1152
#else
 
1153
 
 
1154
    // No XLookupString available. The following is really incomplete...
 
1155
 
 
1156
    int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
 
1157
    const int altGrOffset = 4;
 
1158
    if (state & 128)
 
1159
        col += altGrOffset;
 
1160
    xcb_keysym_t sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col);
 
1161
    if (sym == XCB_NO_SYMBOL)
 
1162
        sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col ^ 0x1);
 
1163
    if (state & XCB_MOD_MASK_LOCK && sym <= 0x7f && isprint(sym)) {
 
1164
        if (isupper(sym))
 
1165
            sym = tolower(sym);
 
1166
        else
 
1167
            sym = toupper(sym);
 
1168
    }
 
1169
    return sym;
 
1170
 
 
1171
#endif
 
1172
}
 
1173
 
 
1174
void QXcbKeyboard::handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event)
 
1175
{
 
1176
    window->updateNetWmUserTime(event->time);
 
1177
    handleKeyEvent(window->window(), QEvent::KeyPress, event->detail, event->state, event->time);
 
1178
}
 
1179
 
 
1180
void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event)
 
1181
{
 
1182
    handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
 
1183
}
 
1184
 
 
1185
void QXcbKeyboard::handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event)
 
1186
{
 
1187
    xcb_refresh_keyboard_mapping(m_key_symbols, const_cast<xcb_mapping_notify_event_t *>(event));
 
1188
    setupModifiers();
 
1189
}
 
1190
 
 
1191
QT_END_NAMESPACE