~gerboland/qtubuntu/fix_1351024

« back to all changes in this revision

Viewing changes to src/ubuntumirclient/input.cpp

  • Committer: CI bot
  • Author(s): Gerry Boland, Daniel d'Andrada
  • Date: 2014-07-28 02:37:08 UTC
  • mfrom: (231.1.14 ubuntumirclient-only)
  • Revision ID: ps-jenkins@lists.canonical.com-20140728023708-iv11mcwrd0pzjv0c
Major refactor: remove SurfaceFlinger & Mir in-server-process-client support, flatten class hierarchy. Only Mir client QPA remains


 
Approved by: Michael Terry, Ricardo Mendoza

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// This file is part of QtUbuntu, a set of Qt components for Ubuntu.
2
 
// Copyright © 2013 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/>.
 
1
/*
 
2
 * Copyright (C) 2014 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
 */
15
16
 
 
17
// Local
16
18
#include "input.h"
17
19
#include "integration.h"
18
 
#include "native_interface.h"
 
20
#include "nativeinterface.h"
 
21
#include "window.h"
19
22
#include "logging.h"
 
23
 
 
24
// Qt
20
25
#if !defined(QT_NO_DEBUG)
21
26
#include <QtCore/QThread>
22
27
#endif
24
29
#include <QtCore/QCoreApplication>
25
30
#include <private/qguiapplication_p.h>
26
31
#include <qpa/qplatforminputcontext.h>
 
32
#include <qpa/qwindowsysteminterface.h>
 
33
 
 
34
#include <xkbcommon/xkbcommon.h>
 
35
#include <xkbcommon/xkbcommon-keysyms.h>
 
36
 
 
37
// Platform API
27
38
#include <ubuntu/application/ui/input/event.h>
28
 
#include <input/input_stack_compatibility_layer_flags.h>
29
39
 
30
40
#define LOG_EVENTS 0
31
41
 
 
42
// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
 
43
static const uint32_t KeyTable[] = {
 
44
    XKB_KEY_Escape,                  Qt::Key_Escape,
 
45
    XKB_KEY_Tab,                     Qt::Key_Tab,
 
46
    XKB_KEY_ISO_Left_Tab,            Qt::Key_Backtab,
 
47
    XKB_KEY_BackSpace,               Qt::Key_Backspace,
 
48
    XKB_KEY_Return,                  Qt::Key_Return,
 
49
    XKB_KEY_Insert,                  Qt::Key_Insert,
 
50
    XKB_KEY_Delete,                  Qt::Key_Delete,
 
51
    XKB_KEY_Clear,                   Qt::Key_Delete,
 
52
    XKB_KEY_Pause,                   Qt::Key_Pause,
 
53
    XKB_KEY_Print,                   Qt::Key_Print,
 
54
 
 
55
    XKB_KEY_Home,                    Qt::Key_Home,
 
56
    XKB_KEY_End,                     Qt::Key_End,
 
57
    XKB_KEY_Left,                    Qt::Key_Left,
 
58
    XKB_KEY_Up,                      Qt::Key_Up,
 
59
    XKB_KEY_Right,                   Qt::Key_Right,
 
60
    XKB_KEY_Down,                    Qt::Key_Down,
 
61
    XKB_KEY_Prior,                   Qt::Key_PageUp,
 
62
    XKB_KEY_Next,                    Qt::Key_PageDown,
 
63
 
 
64
    XKB_KEY_Shift_L,                 Qt::Key_Shift,
 
65
    XKB_KEY_Shift_R,                 Qt::Key_Shift,
 
66
    XKB_KEY_Shift_Lock,              Qt::Key_Shift,
 
67
    XKB_KEY_Control_L,               Qt::Key_Control,
 
68
    XKB_KEY_Control_R,               Qt::Key_Control,
 
69
    XKB_KEY_Meta_L,                  Qt::Key_Meta,
 
70
    XKB_KEY_Meta_R,                  Qt::Key_Meta,
 
71
    XKB_KEY_Alt_L,                   Qt::Key_Alt,
 
72
    XKB_KEY_Alt_R,                   Qt::Key_Alt,
 
73
    XKB_KEY_Caps_Lock,               Qt::Key_CapsLock,
 
74
    XKB_KEY_Num_Lock,                Qt::Key_NumLock,
 
75
    XKB_KEY_Scroll_Lock,             Qt::Key_ScrollLock,
 
76
    XKB_KEY_Super_L,                 Qt::Key_Super_L,
 
77
    XKB_KEY_Super_R,                 Qt::Key_Super_R,
 
78
    XKB_KEY_Menu,                    Qt::Key_Menu,
 
79
    XKB_KEY_Hyper_L,                 Qt::Key_Hyper_L,
 
80
    XKB_KEY_Hyper_R,                 Qt::Key_Hyper_R,
 
81
    XKB_KEY_Help,                    Qt::Key_Help,
 
82
 
 
83
    XKB_KEY_KP_Space,                Qt::Key_Space,
 
84
    XKB_KEY_KP_Tab,                  Qt::Key_Tab,
 
85
    XKB_KEY_KP_Enter,                Qt::Key_Enter,
 
86
    XKB_KEY_KP_Home,                 Qt::Key_Home,
 
87
    XKB_KEY_KP_Left,                 Qt::Key_Left,
 
88
    XKB_KEY_KP_Up,                   Qt::Key_Up,
 
89
    XKB_KEY_KP_Right,                Qt::Key_Right,
 
90
    XKB_KEY_KP_Down,                 Qt::Key_Down,
 
91
    XKB_KEY_KP_Prior,                Qt::Key_PageUp,
 
92
    XKB_KEY_KP_Next,                 Qt::Key_PageDown,
 
93
    XKB_KEY_KP_End,                  Qt::Key_End,
 
94
    XKB_KEY_KP_Begin,                Qt::Key_Clear,
 
95
    XKB_KEY_KP_Insert,               Qt::Key_Insert,
 
96
    XKB_KEY_KP_Delete,               Qt::Key_Delete,
 
97
    XKB_KEY_KP_Equal,                Qt::Key_Equal,
 
98
    XKB_KEY_KP_Multiply,             Qt::Key_Asterisk,
 
99
    XKB_KEY_KP_Add,                  Qt::Key_Plus,
 
100
    XKB_KEY_KP_Separator,            Qt::Key_Comma,
 
101
    XKB_KEY_KP_Subtract,             Qt::Key_Minus,
 
102
    XKB_KEY_KP_Decimal,              Qt::Key_Period,
 
103
    XKB_KEY_KP_Divide,               Qt::Key_Slash,
 
104
 
 
105
    XKB_KEY_ISO_Level3_Shift,        Qt::Key_AltGr,
 
106
    XKB_KEY_Multi_key,               Qt::Key_Multi_key,
 
107
    XKB_KEY_Codeinput,               Qt::Key_Codeinput,
 
108
    XKB_KEY_SingleCandidate,         Qt::Key_SingleCandidate,
 
109
    XKB_KEY_MultipleCandidate,       Qt::Key_MultipleCandidate,
 
110
    XKB_KEY_PreviousCandidate,       Qt::Key_PreviousCandidate,
 
111
 
 
112
    XKB_KEY_Mode_switch,             Qt::Key_Mode_switch,
 
113
    XKB_KEY_script_switch,           Qt::Key_Mode_switch,
 
114
    XKB_KEY_XF86AudioRaiseVolume,    Qt::Key_VolumeUp,
 
115
    XKB_KEY_XF86AudioLowerVolume,    Qt::Key_VolumeDown,
 
116
    XKB_KEY_XF86PowerOff,            Qt::Key_PowerOff,
 
117
    XKB_KEY_XF86PowerDown,           Qt::Key_PowerDown,
 
118
 
 
119
    0,                          0
 
120
};
 
121
 
32
122
// Lookup table for the key types.
33
123
// FIXME(loicm) Not sure what to do with that multiple thing.
34
124
static const QEvent::Type kEventType[] = {
35
 
  QEvent::KeyPress,    // ISCL_KEY_EVENT_ACTION_DOWN     = 0
36
 
  QEvent::KeyRelease,  // ISCL_KEY_EVENT_ACTION_UP       = 1
37
 
  QEvent::KeyPress     // ISCL_KEY_EVENT_ACTION_MULTIPLE = 2
38
 
};
39
 
 
40
 
// Lookup table for the key codes and unicode values.
41
 
static const struct {
42
 
  const quint32 keycode;
43
 
  const quint16 unicode[3];  // { no modifier, shift modifier, other modifiers }
44
 
} kKeyCode[] = {
45
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_UNKNOWN         = 0
46
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_SOFT_LEFT       = 1
47
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_SOFT_RIGHT      = 2
48
 
  { Qt::Key_Home, { 0xffff, 0xffff, 0xffff } },            // ISCL_KEYCODE_HOME            = 3
49
 
  { Qt::Key_Back, { 0xffff, 0xffff, 0xffff } },            // ISCL_KEYCODE_BACK            = 4
50
 
  { Qt::Key_Call, { 0xffff, 0xffff, 0xffff } },            // ISCL_KEYCODE_CALL            = 5
51
 
  { Qt::Key_Hangup, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_ENDCALL         = 6
52
 
  { Qt::Key_0, { 0x0030, 0x0029, 0xffff } },               // ISCL_KEYCODE_0               = 7
53
 
  { Qt::Key_1, { 0x0031, 0xffff, 0xffff } },               // ISCL_KEYCODE_1               = 8
54
 
  { Qt::Key_2, { 0x0032, 0xffff, 0xffff } },               // ISCL_KEYCODE_2               = 9
55
 
  { Qt::Key_3, { 0x0033, 0xffff, 0xffff } },               // ISCL_KEYCODE_3               = 10
56
 
  { Qt::Key_4, { 0x0034, 0xffff, 0xffff } },               // ISCL_KEYCODE_4               = 11
57
 
  { Qt::Key_5, { 0x0035, 0xffff, 0xffff } },               // ISCL_KEYCODE_5               = 12
58
 
  { Qt::Key_6, { 0x0036, 0xffff, 0xffff } },               // ISCL_KEYCODE_6               = 13
59
 
  { Qt::Key_7, { 0x0037, 0xffff, 0xffff } },               // ISCL_KEYCODE_7               = 14
60
 
  { Qt::Key_8, { 0x0038, 0xffff, 0xffff } },               // ISCL_KEYCODE_8               = 15
61
 
  { Qt::Key_9, { 0x0039, 0x0028, 0xffff } },               // ISCL_KEYCODE_9               = 16
62
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_STAR            = 17
63
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_POUND           = 18
64
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_DPAD_UP         = 19
65
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_DPAD_DOWN       = 20
66
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_DPAD_LEFT       = 21
67
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_DPAD_RIGHT      = 22
68
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_DPAD_CENTER     = 23
69
 
  { Qt::Key_VolumeUp, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_VOLUME_UP       = 24
70
 
  { Qt::Key_VolumeDown, { 0xffff, 0xffff, 0xffff } },      // ISCL_KEYCODE_VOLUME_DOWN     = 25
71
 
  { Qt::Key_PowerOff, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_POWER           = 26
72
 
  { Qt::Key_Camera, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_CAMERA          = 27
73
 
  { Qt::Key_Clear, { 0xffff, 0xffff, 0xffff } },           // ISCL_KEYCODE_CLEAR           = 28
74
 
  { Qt::Key_A, { 0x0061, 0x0041, 0xffff } },               // ISCL_KEYCODE_A               = 29
75
 
  { Qt::Key_B, { 0x0062, 0x0042, 0xffff } },               // ISCL_KEYCODE_B               = 30
76
 
  { Qt::Key_C, { 0x0063, 0x0043, 0xffff } },               // ISCL_KEYCODE_C               = 31
77
 
  { Qt::Key_D, { 0x0064, 0x0044, 0xffff } },               // ISCL_KEYCODE_D               = 32
78
 
  { Qt::Key_E, { 0x0065, 0x0045, 0xffff } },               // ISCL_KEYCODE_E               = 33
79
 
  { Qt::Key_F, { 0x0066, 0x0046, 0xffff } },               // ISCL_KEYCODE_F               = 34
80
 
  { Qt::Key_G, { 0x0067, 0x0047, 0xffff } },               // ISCL_KEYCODE_G               = 35
81
 
  { Qt::Key_H, { 0x0068, 0x0048, 0xffff } },               // ISCL_KEYCODE_H               = 36
82
 
  { Qt::Key_I, { 0x0069, 0x0049, 0xffff } },               // ISCL_KEYCODE_I               = 37
83
 
  { Qt::Key_J, { 0x006a, 0x004a, 0xffff } },               // ISCL_KEYCODE_J               = 38
84
 
  { Qt::Key_K, { 0x006b, 0x004b, 0xffff } },               // ISCL_KEYCODE_K               = 39
85
 
  { Qt::Key_L, { 0x006c, 0x004c, 0xffff } },               // ISCL_KEYCODE_L               = 40
86
 
  { Qt::Key_M, { 0x006d, 0x004d, 0xffff } },               // ISCL_KEYCODE_M               = 41
87
 
  { Qt::Key_N, { 0x006e, 0x004e, 0xffff } },               // ISCL_KEYCODE_N               = 42
88
 
  { Qt::Key_O, { 0x006f, 0x004f, 0xffff } },               // ISCL_KEYCODE_O               = 43
89
 
  { Qt::Key_P, { 0x0070, 0x0050, 0xffff } },               // ISCL_KEYCODE_P               = 44
90
 
  { Qt::Key_Q, { 0x0071, 0x0051, 0xffff } },               // ISCL_KEYCODE_Q               = 45
91
 
  { Qt::Key_R, { 0x0072, 0x0052, 0xffff } },               // ISCL_KEYCODE_R               = 46
92
 
  { Qt::Key_S, { 0x0073, 0x0053, 0xffff } },               // ISCL_KEYCODE_S               = 47
93
 
  { Qt::Key_T, { 0x0074, 0x0054, 0xffff } },               // ISCL_KEYCODE_T               = 48
94
 
  { Qt::Key_U, { 0x0075, 0x0055, 0xffff } },               // ISCL_KEYCODE_U               = 49
95
 
  { Qt::Key_V, { 0x0076, 0x0056, 0xffff } },               // ISCL_KEYCODE_V               = 50
96
 
  { Qt::Key_W, { 0x0077, 0x0057, 0xffff } },               // ISCL_KEYCODE_W               = 51
97
 
  { Qt::Key_X, { 0x0078, 0x0058, 0xffff } },               // ISCL_KEYCODE_X               = 52
98
 
  { Qt::Key_Y, { 0x0079, 0x0059, 0xffff } },               // ISCL_KEYCODE_Y               = 53
99
 
  { Qt::Key_Z, { 0x007a, 0x005a, 0xffff } },               // ISCL_KEYCODE_Z               = 54
100
 
  { Qt::Key_Comma, { 0x002c, 0xffff, 0xffff } },           // ISCL_KEYCODE_COMMA           = 55
101
 
  { Qt::Key_Period, { 0x002e, 0xffff, 0xffff } },          // ISCL_KEYCODE_PERIOD          = 56
102
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_ALT_LEFT        = 57
103
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_ALT_RIGHT       = 58
104
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_SHIFT_LEFT      = 59
105
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_SHIFT_RIGHT     = 60
106
 
  { Qt::Key_Tab, { 0xffff, 0xffff, 0xffff } },             // ISCL_KEYCODE_TAB             = 61
107
 
  { Qt::Key_Space, { 0x0020, 0xffff, 0xffff } },           // ISCL_KEYCODE_SPACE           = 62
108
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_SYM             = 63
109
 
  { Qt::Key_Explorer, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_EXPLORER        = 64
110
 
  { Qt::Key_LaunchMail, { 0xffff, 0xffff, 0xffff } },      // ISCL_KEYCODE_ENVELOPE        = 65
111
 
  { Qt::Key_Enter, { 0xffff, 0xffff, 0xffff } },           // ISCL_KEYCODE_ENTER           = 66
112
 
  { Qt::Key_Delete, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_DEL             = 67
113
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_GRAVE           = 68
114
 
  { Qt::Key_Minus, { 0x002d, 0x005f, 0xffff } },           // ISCL_KEYCODE_MINUS           = 69
115
 
  { Qt::Key_Equal, { 0x003d, 0xffff, 0xffff } },           // ISCL_KEYCODE_EQUALS          = 70
116
 
  { Qt::Key_BracketLeft, { 0x005b, 0xffff, 0xffff } },     // ISCL_KEYCODE_LEFT_BRACKET    = 71
117
 
  { Qt::Key_BracketRight, { 0x005d, 0xffff, 0xffff } },    // ISCL_KEYCODE_RIGHT_BRACKET   = 72
118
 
  { Qt::Key_Backslash, { 0x005c, 0xffff, 0xffff } },       // ISCL_KEYCODE_BACKSLASH       = 73
119
 
  { Qt::Key_Semicolon, { 0x003b, 0x003a, 0xffff } },       // ISCL_KEYCODE_SEMICOLON       = 74
120
 
  { Qt::Key_Apostrophe, { 0x0027, 0xffff, 0xffff } },      // ISCL_KEYCODE_APOSTROPHE      = 75
121
 
  { Qt::Key_Slash, { 0x002f, 0xffff, 0xffff } },           // ISCL_KEYCODE_SLASH           = 76
122
 
  { Qt::Key_At, { 0x0040, 0xffff, 0xffff } },              // ISCL_KEYCODE_AT              = 77
123
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_NUM             = 78
124
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_HEADSETHOOK     = 79
125
 
  { Qt::Key_CameraFocus, { 0xffff, 0xffff, 0xffff } },     // ISCL_KEYCODE_FOCUS           = 80  // *Camera* focus
126
 
  { Qt::Key_Plus, { 0x002b, 0xffff, 0xffff } },            // ISCL_KEYCODE_PLUS            = 81
127
 
  { Qt::Key_Menu, { 0xffff, 0xffff, 0xffff } },            // ISCL_KEYCODE_MENU            = 82
128
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_NOTIFICATION    = 83
129
 
  { Qt::Key_Search, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_SEARCH          = 84
130
 
  { Qt::Key_MediaTogglePlayPause, { 0xffff, 0xffff, 0xffff } },  // ISCL_KEYCODE_MEDIA_PLAY_PAUSE= 85
131
 
  { Qt::Key_MediaStop, { 0xffff, 0xffff, 0xffff } },       // ISCL_KEYCODE_MEDIA_STOP      = 86
132
 
  { Qt::Key_MediaNext, { 0xffff, 0xffff, 0xffff } },       // ISCL_KEYCODE_MEDIA_NEXT      = 87
133
 
  { Qt::Key_MediaPrevious, { 0xffff, 0xffff, 0xffff } },   // ISCL_KEYCODE_MEDIA_PREVIOUS  = 88
134
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_MEDIA_REWIND    = 89
135
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_MEDIA_FAST_FORWARD = 90
136
 
  { Qt::Key_VolumeMute, { 0xffff, 0xffff, 0xffff } },      // ISCL_KEYCODE_MUTE            = 91
137
 
  { Qt::Key_PageUp, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_PAGE_UP         = 92
138
 
  { Qt::Key_PageDown, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_PAGE_DOWN       = 93
139
 
  { Qt::Key_Pictures, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_PICTSYMBOLS     = 94
140
 
  { Qt::Key_Mode_switch, { 0xffff, 0xffff, 0xffff } },     // ISCL_KEYCODE_SWITCH_CHARSET  = 95
141
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_A        = 96
142
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_B        = 97
143
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_C        = 98
144
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_X        = 99
145
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_Y        = 100
146
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_Z        = 101
147
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_L1       = 102
148
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_R1       = 103
149
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_L2       = 104
150
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_R2       = 105
151
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_THUMBL   = 106
152
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_THUMBR   = 107
153
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_START    = 108
154
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_SELECT   = 109
155
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_MODE     = 110
156
 
  { Qt::Key_Escape, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_ESCAPE          = 111
157
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_FORWARD_DEL     = 112
158
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_CTRL_LEFT       = 113
159
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_CTRL_RIGHT      = 114
160
 
  { Qt::Key_CapsLock, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_CAPS_LOCK       = 115
161
 
  { Qt::Key_ScrollLock, { 0xffff, 0xffff, 0xffff } },      // ISCL_KEYCODE_SCROLL_LOCK     = 116
162
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_META_LEFT       = 117
163
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_META_RIGHT      = 118
164
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_FUNCTION        = 119
165
 
  { Qt::Key_SysReq, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_SYSRQ           = 120
166
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BREAK           = 121
167
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_MOVE_HOME       = 122
168
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_MOVE_END        = 123
169
 
  { Qt::Key_Insert, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_INSERT          = 124
170
 
  { Qt::Key_Forward, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_FORWARD         = 125
171
 
  { Qt::Key_MediaPlay, { 0xffff, 0xffff, 0xffff } },       // ISCL_KEYCODE_MEDIA_PLAY      = 126
172
 
  { Qt::Key_MediaPause, { 0xffff, 0xffff, 0xffff } },      // ISCL_KEYCODE_MEDIA_PAUSE     = 127
173
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_MEDIA_CLOSE     = 128
174
 
  { Qt::Key_Eject, { 0xffff, 0xffff, 0xffff } },           // ISCL_KEYCODE_MEDIA_EJECT     = 129
175
 
  { Qt::Key_MediaRecord, { 0xffff, 0xffff, 0xffff } },     // ISCL_KEYCODE_MEDIA_RECORD    = 130
176
 
  { Qt::Key_F1, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F1              = 131
177
 
  { Qt::Key_F2, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F2              = 132
178
 
  { Qt::Key_F3, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F3              = 133
179
 
  { Qt::Key_F4, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F4              = 134
180
 
  { Qt::Key_F5, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F5              = 135
181
 
  { Qt::Key_F6, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F6              = 136
182
 
  { Qt::Key_F7, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F7              = 137
183
 
  { Qt::Key_F8, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F8              = 138
184
 
  { Qt::Key_F9, { 0xffff, 0xffff, 0xffff } },              // ISCL_KEYCODE_F9              = 139
185
 
  { Qt::Key_F10, { 0xffff, 0xffff, 0xffff } },             // ISCL_KEYCODE_F10             = 140
186
 
  { Qt::Key_F11, { 0xffff, 0xffff, 0xffff } },             // ISCL_KEYCODE_F11             = 141
187
 
  { Qt::Key_F12, { 0xffff, 0xffff, 0xffff } },             // ISCL_KEYCODE_F12             = 142
188
 
  { Qt::Key_NumLock, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_NUM_LOCK        = 143
189
 
  { Qt::Key_0, { 0x0030, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_0        = 144
190
 
  { Qt::Key_1, { 0x0031, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_1        = 145
191
 
  { Qt::Key_2, { 0x0032, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_2        = 146
192
 
  { Qt::Key_3, { 0x0033, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_3        = 147
193
 
  { Qt::Key_4, { 0x0034, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_4        = 148
194
 
  { Qt::Key_5, { 0x0035, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_5        = 149
195
 
  { Qt::Key_6, { 0x0036, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_6        = 150
196
 
  { Qt::Key_7, { 0x0037, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_7        = 151
197
 
  { Qt::Key_8, { 0x0038, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_8        = 152
198
 
  { Qt::Key_9, { 0x0039, 0xffff, 0xffff } },               // ISCL_KEYCODE_NUMPAD_9        = 153
199
 
  { Qt::Key_Slash, { 0x002f, 0xffff, 0xffff } },           // ISCL_KEYCODE_NUMPAD_DIVIDE   = 154
200
 
  { Qt::Key_Asterisk, { 0x002a, 0xffff, 0xffff } },        // ISCL_KEYCODE_NUMPAD_MULTIPLY = 155
201
 
  { Qt::Key_Minus, { 0x002d, 0xffff, 0xffff } },           // ISCL_KEYCODE_NUMPAD_SUBTRACT = 156
202
 
  { Qt::Key_Plus, { 0x002b, 0xffff, 0xffff } },            // ISCL_KEYCODE_NUMPAD_ADD      = 157
203
 
  { Qt::Key_Period, { 0x002e, 0xffff, 0xffff } },          // ISCL_KEYCODE_NUMPAD_DOT      = 158
204
 
  { Qt::Key_Comma, { 0x002c, 0xffff, 0xffff } },           // ISCL_KEYCODE_NUMPAD_COMMA    = 159
205
 
  { Qt::Key_Enter, { 0xffff, 0xffff, 0xffff } },           // ISCL_KEYCODE_NUMPAD_ENTER    = 160
206
 
  { Qt::Key_Equal, { 0x003d, 0xffff, 0xffff } },           // ISCL_KEYCODE_NUMPAD_EQUALS   = 161
207
 
  { Qt::Key_ParenLeft, { 0x0028, 0xffff, 0xffff } },       // ISCL_KEYCODE_NUMPAD_LEFT_PAREN = 162
208
 
  { Qt::Key_ParenRight, { 0x0029, 0xffff, 0xffff } },      // ISCL_KEYCODE_NUMPAD_RIGHT_PAREN = 163
209
 
  { Qt::Key_VolumeMute, { 0xffff, 0xffff, 0xffff } },      // ISCL_KEYCODE_VOLUME_MUTE     = 164
210
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_INFO            = 165
211
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_CHANNEL_UP      = 166
212
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_CHANNEL_DOWN    = 167
213
 
  { Qt::Key_ZoomIn, { 0xffff, 0xffff, 0xffff } },          // ISCL_KEYCODE_ZOOM_IN         = 168
214
 
  { Qt::Key_ZoomOut, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_ZOOM_OUT        = 169
215
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_TV              = 170
216
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_WINDOW          = 171
217
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_GUIDE           = 172
218
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_DVR             = 173
219
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BOOKMARK        = 174
220
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_CAPTIONS        = 175
221
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_SETTINGS        = 176
222
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_TV_POWER        = 177
223
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_TV_INPUT        = 178
224
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_STB_POWER       = 179
225
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_STB_INPUT       = 180
226
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_AVR_POWER       = 181
227
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_AVR_INPUT       = 182
228
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_PROG_RED        = 183
229
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_PROG_GREEN      = 184
230
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_PROG_YELLOW     = 185
231
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_PROG_BLUE       = 186
232
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_APP_SWITCH      = 187
233
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_1        = 188
234
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_2        = 189
235
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_3        = 190
236
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_4        = 191
237
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_5        = 192
238
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_6        = 193
239
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_7        = 194
240
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_8        = 195
241
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_9        = 196
242
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_10       = 197
243
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_11       = 198
244
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_12       = 199
245
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_13       = 200
246
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_14       = 201
247
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_15       = 202
248
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_BUTTON_16       = 203
249
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_LANGUAGE_SWITCH = 204
250
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_MANNER_MODE     = 205
251
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_3D_MODE         = 206
252
 
  { Qt::Key_unknown, { 0xffff, 0xffff, 0xffff } },         // ISCL_KEYCODE_CONTACTS        = 207
253
 
  { Qt::Key_Calendar, { 0xffff, 0xffff, 0xffff } },        // ISCL_KEYCODE_CALENDAR        = 208
254
 
  { Qt::Key_Music, { 0xffff, 0xffff, 0xffff } },           // ISCL_KEYCODE_MUSIC           = 209
255
 
  { Qt::Key_Calculator, { 0xffff, 0xffff, 0xffff } }       // ISCL_KEYCODE_CALCULATOR      = 210
256
 
};
257
 
 
258
 
class QUbuntuBaseEvent : public QEvent {
259
 
 public:
260
 
  QUbuntuBaseEvent(QWindow* window, const Event* event, QEvent::Type type)
261
 
      : QEvent(type)
262
 
      , window_(window) {
263
 
    memcpy(&nativeEvent_, event, sizeof(Event));
264
 
  }
265
 
  QWindow* window_;
266
 
  Event nativeEvent_;
267
 
};
268
 
 
269
 
QUbuntuBaseInput::QUbuntuBaseInput(QUbuntuBaseIntegration* integration)
270
 
    : integration_(integration)
271
 
    , eventFilterType_(static_cast<QUbuntuBaseNativeInterface*>(
 
125
    QEvent::KeyPress,    // U_KEY_ACTION_DOWN     = 0
 
126
    QEvent::KeyRelease,  // U_KEY_ACTION_UP       = 1
 
127
    QEvent::KeyPress     // U_KEY_ACTION_MULTIPLE = 2
 
128
};
 
129
 
 
130
class UbuntuEvent : public QEvent
 
131
{
 
132
public:
 
133
    UbuntuEvent(UbuntuWindow* window, const WindowEvent* event, QEvent::Type type)
 
134
        : QEvent(type), window(window) {
 
135
        memcpy(&nativeEvent, event, sizeof(WindowEvent));
 
136
    }
 
137
    UbuntuWindow* window;
 
138
    WindowEvent nativeEvent;
 
139
};
 
140
 
 
141
UbuntuInput::UbuntuInput(UbuntuClientIntegration* integration)
 
142
    : QObject(nullptr)
 
143
    , mIntegration(integration)
 
144
    , mEventFilterType(static_cast<UbuntuNativeInterface*>(
272
145
        integration->nativeInterface())->genericEventFilterType())
273
 
    , eventType_(static_cast<QEvent::Type>(QEvent::registerEventType())) {
274
 
 
275
 
  // Initialize touch device.
276
 
  touchDevice_ = new QTouchDevice();
277
 
  touchDevice_->setType(QTouchDevice::TouchScreen);
278
 
  touchDevice_->setCapabilities(
279
 
      QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure |
280
 
      QTouchDevice::NormalizedPosition);
281
 
  QWindowSystemInterface::registerTouchDevice(touchDevice_);
282
 
 
283
 
  DLOG("QUbuntuBaseInput::QUbuntuBaseInput (this=%p, integration=%p)", this, integration);
284
 
}
285
 
 
286
 
QUbuntuBaseInput::~QUbuntuBaseInput() {
287
 
  DLOG("QUbuntuBaseInput::~QUbuntuBaseInput");
288
 
  // touchDevice_ isn't cleaned up on purpose as it crashes or asserts on "Bus Error".
289
 
}
290
 
 
291
 
void QUbuntuBaseInput::customEvent(QEvent* event) {
292
 
  DLOG("QUbuntuBaseInput::customEvent (this=%p, event=%p)", this, event);
293
 
  DASSERT(QThread::currentThread() == thread());
294
 
  QUbuntuBaseEvent* ubuntuEvent = static_cast<QUbuntuBaseEvent*>(event);
295
 
 
296
 
  // Event filtering.
297
 
  long result;
298
 
  if (QWindowSystemInterface::handleNativeEvent(
299
 
          ubuntuEvent->window_, eventFilterType_, &ubuntuEvent->nativeEvent_, &result) == true) {
300
 
    DLOG("event filtered out by native interface");
301
 
    return;
302
 
  }
303
 
 
304
 
  // Event dispatching.
305
 
  switch (ubuntuEvent->nativeEvent_.type) {
306
 
    case MOTION_EVENT_TYPE: {
307
 
      dispatchMotionEvent(ubuntuEvent->window_, &ubuntuEvent->nativeEvent_);
308
 
      break;
309
 
    }
310
 
    case KEY_EVENT_TYPE: {
311
 
      dispatchKeyEvent(ubuntuEvent->window_, &ubuntuEvent->nativeEvent_);
312
 
      break;
313
 
    }
314
 
    case HW_SWITCH_EVENT_TYPE: {
315
 
      dispatchHWSwitchEvent(ubuntuEvent->window_, &ubuntuEvent->nativeEvent_);
316
 
      break;
317
 
    }
318
 
    default: {
319
 
      DLOG("unhandled event type %d", ubuntuEvent->nativeEvent_.type);
320
 
    }
321
 
  }
322
 
}
323
 
 
324
 
void QUbuntuBaseInput::postEvent(QWindow* window, const void* event) {
325
 
  DLOG("QUbuntuBaseInput::postEvent (this=%p, window=%p, event=%p)", this, window, event);
326
 
  QCoreApplication::postEvent(this, new QUbuntuBaseEvent(
327
 
      window, reinterpret_cast<const Event*>(event), eventType_));
328
 
 
329
 
  if ((window->flags() && Qt::WindowTransparentForInput) && window->parent()) {
330
 
    DLOG("QUbuntuBaseInput::postEvent (this=%p, window=%p, event=%p)", this, window->parent(), event);
331
 
    QCoreApplication::postEvent(this, new QUbuntuBaseEvent(
332
 
        window->parent(), reinterpret_cast<const Event*>(event), eventType_));
333
 
  }
334
 
}
335
 
 
336
 
void QUbuntuBaseInput::dispatchMotionEvent(QWindow* window, const void* ev) {
337
 
  DLOG("QUbuntuBaseInput::dispatchMotionEvent (this=%p, window=%p, event=%p)", this, window, ev);
338
 
  const Event* event = reinterpret_cast<const Event*>(ev);
339
 
 
340
 
#if (LOG_EVENTS != 0)
341
 
  // Motion event logging.
342
 
  LOG("MOTION device_id:%d source_id:%d action:%d flags:%d meta_state:%d edge_flags:%d "
343
 
      "button_state:%d x_offset:%.2f y_offset:%.2f x_precision:%.2f y_precision:%.2f "
344
 
      "down_time:%lld event_time:%lld pointer_count:%d {", event->device_id,
345
 
      event->source_id, event->action, event->flags, event->meta_state,
346
 
      event->details.motion.edge_flags, event->details.motion.button_state,
347
 
      event->details.motion.x_offset, event->details.motion.y_offset,
348
 
      event->details.motion.x_precision, event->details.motion.y_precision,
349
 
      event->details.motion.down_time, event->details.motion.event_time,
350
 
      event->details.motion.pointer_count);
351
 
  for (size_t i = 0; i < event->details.motion.pointer_count; i++) {
352
 
    LOG("  id:%d x:%.2f y:%.2f rx:%.2f ry:%.2f maj:%.2f min:%.2f sz:%.2f press:%.2f",
353
 
        event->details.motion.pointer_coordinates[i].id,
354
 
        event->details.motion.pointer_coordinates[i].x,
355
 
        event->details.motion.pointer_coordinates[i].y,
356
 
        event->details.motion.pointer_coordinates[i].raw_x,
357
 
        event->details.motion.pointer_coordinates[i].raw_y,
358
 
        event->details.motion.pointer_coordinates[i].touch_major,
359
 
        event->details.motion.pointer_coordinates[i].touch_minor,
360
 
        event->details.motion.pointer_coordinates[i].size,
361
 
        event->details.motion.pointer_coordinates[i].pressure
362
 
        // event->details.motion.pointer_coordinates[i].orientation  -> Always 0.0.
363
 
        );
364
 
  }
365
 
  LOG("}");
366
 
#endif
367
 
 
368
 
  // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
369
 
  //     needs to be fixed as soon as the compat input lib adds query support.
370
 
  const float kMaxPressure = 1.28;
371
 
  const QRect kWindowGeometry = window->geometry();
372
 
  QList<QWindowSystemInterface::TouchPoint> touchPoints;
373
 
 
374
 
 
375
 
  // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
376
 
  //       as Qt::TouchPointMoved
377
 
  const int kPointerCount = event->details.motion.pointer_count;
378
 
  for (int i = 0; i < kPointerCount; ++i) {
379
 
    QWindowSystemInterface::TouchPoint touchPoint;
380
 
 
381
 
    const float kX = event->details.motion.pointer_coordinates[i].raw_x;
382
 
    const float kY = event->details.motion.pointer_coordinates[i].raw_y;
383
 
    const float kW = event->details.motion.pointer_coordinates[i].touch_major;
384
 
    const float kH = event->details.motion.pointer_coordinates[i].touch_minor;
385
 
    const float kP = event->details.motion.pointer_coordinates[i].pressure;
386
 
    touchPoint.id = event->details.motion.pointer_coordinates[i].id;
387
 
    touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
388
 
    touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
389
 
    touchPoint.pressure = kP / kMaxPressure;
390
 
    touchPoint.state = Qt::TouchPointMoved;
391
 
 
392
 
    touchPoints.append(touchPoint);
393
 
  }
394
 
 
395
 
  switch (event->action & ISCL_MOTION_EVENT_ACTION_MASK) {
396
 
    case ISCL_MOTION_EVENT_ACTION_MOVE:
397
 
      // No extra work needed.
398
 
      break;
399
 
 
400
 
    case ISCL_MOTION_EVENT_ACTION_DOWN:
401
 
      touchPoints[0].state = Qt::TouchPointPressed;
402
 
      break;
403
 
 
404
 
    case ISCL_MOTION_EVENT_ACTION_UP:
405
 
      touchPoints[0].state = Qt::TouchPointReleased;
406
 
      break;
407
 
 
408
 
    case ISCL_MOTION_EVENT_ACTION_POINTER_DOWN: {
409
 
      const int index = (event->action & ISCL_MOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
410
 
          ISCL_MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
411
 
      touchPoints[index].state = Qt::TouchPointPressed;
412
 
      break;
413
 
    }
414
 
 
415
 
    case ISCL_MOTION_EVENT_ACTION_CANCEL:
416
 
    case ISCL_MOTION_EVENT_ACTION_POINTER_UP: {
417
 
      const int index = (event->action & ISCL_MOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
418
 
          ISCL_MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
419
 
      touchPoints[index].state = Qt::TouchPointReleased;
420
 
      break;
421
 
    }
422
 
 
423
 
    case ISCL_MOTION_EVENT_ACTION_OUTSIDE:
424
 
    case ISCL_MOTION_EVENT_ACTION_HOVER_MOVE:
425
 
    case ISCL_MOTION_EVENT_ACTION_SCROLL:
426
 
    case ISCL_MOTION_EVENT_ACTION_HOVER_ENTER:
427
 
    case ISCL_MOTION_EVENT_ACTION_HOVER_EXIT:
428
 
    default:
429
 
      DLOG("unhandled motion event action %d", event->action & ISCL_MOTION_EVENT_ACTION_MASK);
430
 
  }
431
 
 
432
 
  // Touch event propagation.
433
 
  handleTouchEvent(window, event->details.motion.event_time / 1000000, touchDevice_, touchPoints);
434
 
}
435
 
 
436
 
void QUbuntuBaseInput::handleTouchEvent(
437
 
    QWindow* window, ulong timestamp, QTouchDevice* device,
438
 
    const QList<struct QWindowSystemInterface::TouchPoint> &points) {
439
 
  DLOG("QUbuntuBaseInput::handleTouchEvent (this=%p, window=%p, timestamp=%lu, device=%p)",
440
 
       this, window, timestamp, device);
441
 
  QWindowSystemInterface::handleTouchEvent(window, timestamp, device, points);
442
 
}
443
 
 
444
 
void QUbuntuBaseInput::dispatchKeyEvent(QWindow* window, const void* ev) {
445
 
  DLOG("QUbuntuBaseInput::dispatchKeyEvent (this=%p, window=%p, event=%p)", this, window, ev);
446
 
  const Event* event = reinterpret_cast<const Event*>(ev);
447
 
 
448
 
#if (LOG_EVENTS != 0)
449
 
  // Key event logging.
450
 
  LOG("KEY device_id:%d source_id:%d action:%d flags:%d meta_state:%d key_code:%d "
451
 
      "scan_code:%d repeat_count:%d down_time:%lld event_time:%lld is_system_key:%d",
452
 
      event->device_id, event->source_id, event->action, event->flags, event->meta_state,
453
 
      event->details.key.key_code, event->details.key.scan_code,
454
 
      event->details.key.repeat_count, event->details.key.down_time,
455
 
      event->details.key.event_time, event->details.key.is_system_key);
456
 
#endif
457
 
 
458
 
  // Key modifier and unicode index mapping.
459
 
  const int kMetaState = event->meta_state;
460
 
  Qt::KeyboardModifiers modifiers = Qt::NoModifier;
461
 
  int unicodeIndex = 0;
462
 
  if (kMetaState & ISCL_META_SHIFT_ON) {
463
 
    modifiers |= Qt::ShiftModifier;
464
 
    unicodeIndex = 1;
465
 
  }
466
 
  if (kMetaState & ISCL_META_CTRL_ON) {
467
 
    modifiers |= Qt::ControlModifier;
468
 
    unicodeIndex = 2;
469
 
  }
470
 
  if (kMetaState & ISCL_META_ALT_ON) {
471
 
    modifiers |= Qt::AltModifier;
472
 
    unicodeIndex = 2;
473
 
  }
474
 
  if (kMetaState & ISCL_META_META_ON) {
475
 
    modifiers |= Qt::MetaModifier;
476
 
    unicodeIndex = 2;
477
 
  }
478
 
 
479
 
  // Key event propagation.
480
 
  QEvent::Type keyType = kEventType[event->action];
481
 
  quint32 keyCode = kKeyCode[event->details.key.key_code].keycode;
482
 
  QString text(kKeyCode[event->details.key.key_code].unicode[unicodeIndex]);
483
 
  ulong timestamp = event->details.key.event_time / 1000000;
484
 
  QPlatformInputContext* context = QGuiApplicationPrivate::platformIntegration()->inputContext();
485
 
  if (context) {
486
 
    QKeyEvent qKeyEvent(keyType, keyCode, modifiers, text);
487
 
    qKeyEvent.setTimestamp(timestamp);
488
 
    if (context->filterEvent(&qKeyEvent)) {
489
 
      DLOG("key event filtered out by input context");
490
 
      return;
491
 
    }
492
 
  }
493
 
  handleKeyEvent(window, timestamp, keyType, keyCode, modifiers, text);
494
 
}
495
 
 
496
 
void QUbuntuBaseInput::handleKeyEvent(
497
 
    QWindow* window, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
498
 
    const QString& text) {
499
 
  DLOG("QUbuntuBaseInput::handleKeyEvent (this=%p window=%p, timestamp=%lu, type=%d, key=%d, "
500
 
       "modifiers=%d, text='%s')", this, window, timestamp, static_cast<int>(type), key,
501
 
       static_cast<int>(modifiers), text.toUtf8().data());
502
 
  QWindowSystemInterface::handleKeyEvent(window, timestamp, type, key, modifiers, text);
503
 
}
504
 
 
505
 
void QUbuntuBaseInput::dispatchHWSwitchEvent(QWindow* window, const void* ev) {
506
 
  Q_UNUSED(window);
507
 
  Q_UNUSED(ev);
508
 
  DLOG("QUbuntuBaseInput::dispatchSwitchEvent (this=%p, window=%p, event=%p)", this, window, ev);
509
 
 
510
 
#if (LOG_EVENTS != 0)
511
 
  // HW switch event logging.
512
 
  const Event* event = reinterpret_cast<const Event*>(ev);
513
 
  LOG("HWSWITCH device_id:%d source_id:%d action:%d flags:%d meta_state:%d event_time:%lld "
514
 
      "policy_flags:%u switch_values:%d switch_mask:%d", event->device_id, event->source_id,
515
 
      event->action, event->flags, event->meta_state, event->details.hw_switch.event_time,
516
 
      event->details.hw_switch.policy_flags, event->details.hw_switch.switch_values,
517
 
      event->details.hw_switch.switch_mask);
518
 
#endif
519
 
 
520
 
  // FIXME(loicm) Not sure how to interpret that kind of event.
521
 
  DLOG("hw switch events are not handled");
 
146
    , mEventType(static_cast<QEvent::Type>(QEvent::registerEventType()))
 
147
{
 
148
    // Initialize touch device.
 
149
    mTouchDevice = new QTouchDevice;
 
150
    mTouchDevice->setType(QTouchDevice::TouchScreen);
 
151
    mTouchDevice->setCapabilities(
 
152
            QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure |
 
153
            QTouchDevice::NormalizedPosition);
 
154
    QWindowSystemInterface::registerTouchDevice(mTouchDevice);
 
155
}
 
156
 
 
157
UbuntuInput::~UbuntuInput()
 
158
{
 
159
  // Qt will take care of deleting mTouchDevice.
 
160
}
 
161
 
 
162
#ifndef QT_NO_DEBUG
 
163
static const char* nativeEventTypeToStr(int eventType)
 
164
{
 
165
    switch (eventType) {
 
166
    case MOTION_WEVENT_TYPE:
 
167
        return "MOTION_WEVENT_TYPE";
 
168
        break;
 
169
    case KEY_WEVENT_TYPE:
 
170
        return "KEY_WEVENT_TYPE";
 
171
        break;
 
172
    case RESIZE_WEVENT_TYPE:
 
173
        return "RESIZE_WEVENT_TYPE";
 
174
        break;
 
175
    case SURFACE_WEVENT_TYPE:
 
176
        return "SURFACE_WEVENT_TYPE";
 
177
    default:
 
178
        return "INVALID!";
 
179
    }
 
180
}
 
181
#endif
 
182
 
 
183
void UbuntuInput::customEvent(QEvent* event)
 
184
{
 
185
    DASSERT(QThread::currentThread() == thread());
 
186
    UbuntuEvent* ubuntuEvent = static_cast<UbuntuEvent*>(event);
 
187
    WindowEvent *nativeEvent = &ubuntuEvent->nativeEvent;
 
188
 
 
189
    // Event filtering.
 
190
    long result;
 
191
    if (QWindowSystemInterface::handleNativeEvent(
 
192
                ubuntuEvent->window->window(), mEventFilterType, nativeEvent, &result) == true) {
 
193
        DLOG("event filtered out by native interface");
 
194
        return;
 
195
    }
 
196
 
 
197
    DLOG("UbuntuInput::customEvent(type=%s)", nativeEventTypeToStr(nativeEvent->type));
 
198
 
 
199
    // Event dispatching.
 
200
    switch (nativeEvent->type) {
 
201
    case MOTION_WEVENT_TYPE:
 
202
        dispatchMotionEvent(ubuntuEvent->window->window(), nativeEvent);
 
203
        break;
 
204
    case KEY_WEVENT_TYPE:
 
205
        dispatchKeyEvent(ubuntuEvent->window->window(), nativeEvent);
 
206
        break;
 
207
    case RESIZE_WEVENT_TYPE:
 
208
        ubuntuEvent->window->handleSurfaceResize(nativeEvent->resize.width,
 
209
                                                 nativeEvent->resize.height);
 
210
        break;
 
211
    case SURFACE_WEVENT_TYPE:
 
212
        if (nativeEvent->surface.attribute == SURFACE_ATTRIBUTE_FOCUS) {
 
213
            ubuntuEvent->window->handleSurfaceFocusChange(nativeEvent->surface.value == 1);
 
214
        }
 
215
        break;
 
216
    default:
 
217
        DLOG("unhandled event type %d", nativeEvent->type);
 
218
    }
 
219
}
 
220
 
 
221
void UbuntuInput::postEvent(UbuntuWindow* platformWindow, const void* event)
 
222
{
 
223
    QWindow *window = platformWindow->window();
 
224
 
 
225
    QCoreApplication::postEvent(this, new UbuntuEvent(
 
226
            platformWindow, reinterpret_cast<const WindowEvent*>(event), mEventType));
 
227
 
 
228
    if ((window->flags() && Qt::WindowTransparentForInput) && window->parent()) {
 
229
        QCoreApplication::postEvent(this, new UbuntuEvent(
 
230
                    static_cast<UbuntuWindow*>(platformWindow->QPlatformWindow::parent()),
 
231
                    reinterpret_cast<const WindowEvent*>(event), mEventType));
 
232
    }
 
233
}
 
234
 
 
235
void UbuntuInput::dispatchMotionEvent(QWindow* window, const void* ev)
 
236
{
 
237
    const WindowEvent* event = reinterpret_cast<const WindowEvent*>(ev);
 
238
 
 
239
    #if (LOG_EVENTS != 0)
 
240
    // Motion event logging.
 
241
    LOG("MOTION device_id:%d source_id:%d action:%d flags:%d meta_state:%d edge_flags:%d "
 
242
            "button_state:%d x_offset:%.2f y_offset:%.2f x_precision:%.2f y_precision:%.2f "
 
243
            "down_time:%lld event_time:%lld pointer_count:%d {", event->motion.device_id,
 
244
            event->motion.source_id, event->motion.action,
 
245
            event->motion.flags, event->motion.meta_state,
 
246
            event->motion.edge_flags, event->motion.button_state,
 
247
            event->motion.x_offset, event->motion.y_offset,
 
248
            event->motion.x_precision, event->motion.y_precision,
 
249
            event->motion.down_time, event->motion.event_time,
 
250
            event->motion.pointer_count);
 
251
    for (size_t i = 0; i < event->motion.pointer_count; i++) {
 
252
        LOG("  id:%d x:%.2f y:%.2f rx:%.2f ry:%.2f maj:%.2f min:%.2f sz:%.2f press:%.2f",
 
253
                event->motion.pointer_coordinates[i].id,
 
254
                event->motion.pointer_coordinates[i].x,
 
255
                event->motion.pointer_coordinates[i].y,
 
256
                event->motion.pointer_coordinates[i].raw_x,
 
257
                event->motion.pointer_coordinates[i].raw_y,
 
258
                event->motion.pointer_coordinates[i].touch_major,
 
259
                event->motion.pointer_coordinates[i].touch_minor,
 
260
                event->motion.pointer_coordinates[i].size,
 
261
                event->motion.pointer_coordinates[i].pressure
 
262
                // event->motion.pointer_coordinates[i].orientation  -> Always 0.0.
 
263
           );
 
264
    }
 
265
    LOG("}");
 
266
    #endif
 
267
 
 
268
    // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
 
269
    //     needs to be fixed as soon as the compat input lib adds query support.
 
270
    const float kMaxPressure = 1.28;
 
271
    const QRect kWindowGeometry = window->geometry();
 
272
    QList<QWindowSystemInterface::TouchPoint> touchPoints;
 
273
 
 
274
 
 
275
    // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
 
276
    //       as Qt::TouchPointMoved
 
277
    const int kPointerCount = event->motion.pointer_count;
 
278
    for (int i = 0; i < kPointerCount; ++i) {
 
279
        QWindowSystemInterface::TouchPoint touchPoint;
 
280
 
 
281
        const float kX = event->motion.pointer_coordinates[i].raw_x;
 
282
        const float kY = event->motion.pointer_coordinates[i].raw_y;
 
283
        const float kW = event->motion.pointer_coordinates[i].touch_major;
 
284
        const float kH = event->motion.pointer_coordinates[i].touch_minor;
 
285
        const float kP = event->motion.pointer_coordinates[i].pressure;
 
286
        touchPoint.id = event->motion.pointer_coordinates[i].id;
 
287
        touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
 
288
        touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
 
289
        touchPoint.pressure = kP / kMaxPressure;
 
290
        touchPoint.state = Qt::TouchPointMoved;
 
291
 
 
292
        touchPoints.append(touchPoint);
 
293
    }
 
294
 
 
295
    switch (event->motion.action & U_MOTION_ACTION_MASK) {
 
296
    case U_MOTION_ACTION_MOVE:
 
297
        // No extra work needed.
 
298
        break;
 
299
 
 
300
    case U_MOTION_ACTION_DOWN:
 
301
        touchPoints[0].state = Qt::TouchPointPressed;
 
302
        break;
 
303
 
 
304
    case U_MOTION_ACTION_UP:
 
305
        touchPoints[0].state = Qt::TouchPointReleased;
 
306
        break;
 
307
 
 
308
    case U_MOTION_ACTION_POINTER_DOWN: {
 
309
        const int index = (event->motion.action & U_MOTION_ACTION_POINTER_INDEX_MASK) >>
 
310
            U_MOTION_ACTION_POINTER_INDEX_SHIFT;
 
311
        touchPoints[index].state = Qt::TouchPointPressed;
 
312
        break;
 
313
    }
 
314
 
 
315
    case U_MOTION_ACTION_CANCEL:
 
316
    case U_MOTION_ACTION_POINTER_UP: {
 
317
        const int index = (event->motion.action & U_MOTION_ACTION_POINTER_INDEX_MASK) >>
 
318
            U_MOTION_ACTION_POINTER_INDEX_SHIFT;
 
319
        touchPoints[index].state = Qt::TouchPointReleased;
 
320
        break;
 
321
    }
 
322
 
 
323
    case U_MOTION_ACTION_OUTSIDE:
 
324
    case U_MOTION_ACTION_HOVER_MOVE:
 
325
    case U_MOTION_ACTION_SCROLL:
 
326
    case U_MOTION_ACTION_HOVER_ENTER:
 
327
    case U_MOTION_ACTION_HOVER_EXIT:
 
328
    default:
 
329
        DLOG("unhandled motion event action %d", event->motion.action & U_MOTION_ACTION_MASK);
 
330
    }
 
331
 
 
332
    QWindowSystemInterface::handleTouchEvent(window, event->motion.event_time / 1000000,
 
333
            mTouchDevice, touchPoints);
 
334
}
 
335
 
 
336
static uint32_t translateKeysym(uint32_t sym, char *string, size_t size)
 
337
{
 
338
    Q_UNUSED(size);
 
339
    string[0] = '\0';
 
340
 
 
341
    if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35)
 
342
        return Qt::Key_F1 + (int(sym) - XKB_KEY_F1);
 
343
 
 
344
    for (int i = 0; KeyTable[i]; i += 2) {
 
345
        if (sym == KeyTable[i])
 
346
            return KeyTable[i + 1];
 
347
    }
 
348
 
 
349
    string[0] = sym;
 
350
    string[1] = '\0';
 
351
    return toupper(sym);
 
352
}
 
353
 
 
354
void UbuntuInput::dispatchKeyEvent(QWindow* window, const void* ev)
 
355
{
 
356
    const WindowEvent* event = reinterpret_cast<const WindowEvent*>(ev);
 
357
 
 
358
    #if (LOG_EVENTS != 0)
 
359
    // Key event logging.
 
360
    LOG("KEY device_id:%d source_id:%d action:%d flags:%d meta_state:%d key_code:%d "
 
361
            "scan_code:%d repeat_count:%d down_time:%lld event_time:%lld is_system_key:%d",
 
362
            event->key.device_id, event->key.source_id,
 
363
            event->key.action, event->key.flags, event->key.meta_state,
 
364
            event->key.key_code, event->key.scan_code,
 
365
            event->key.repeat_count, event->key.down_time,
 
366
            event->key.event_time, event->key.is_system_key);
 
367
    #endif
 
368
 
 
369
    ulong timestamp = event->key.event_time / 1000000;
 
370
    xkb_keysym_t xk_sym = (xkb_keysym_t)event->key.key_code;
 
371
 
 
372
    // Key modifier and unicode index mapping.
 
373
    const int kMetaState = event->key.meta_state;
 
374
    Qt::KeyboardModifiers modifiers = Qt::NoModifier;
 
375
    if (kMetaState & U_KEY_MODIFIER_SHIFT) {
 
376
        modifiers |= Qt::ShiftModifier;
 
377
    }
 
378
    if (kMetaState & U_KEY_MODIFIER_CTRL) {
 
379
        modifiers |= Qt::ControlModifier;
 
380
    }
 
381
    if (kMetaState & U_KEY_MODIFIER_ALT) {
 
382
        modifiers |= Qt::AltModifier;
 
383
    }
 
384
    if (kMetaState & U_KEY_MODIFIER_META) {
 
385
        modifiers |= Qt::MetaModifier;
 
386
    }
 
387
 
 
388
    QEvent::Type keyType = event->key.action == U_KEY_ACTION_DOWN ? QEvent::KeyPress : QEvent::KeyRelease;
 
389
 
 
390
    char s[2];
 
391
    int sym = translateKeysym(xk_sym, s, sizeof(s));
 
392
    QString text = QString::fromLatin1(s);
 
393
 
 
394
    QPlatformInputContext* context = QGuiApplicationPrivate::platformIntegration()->inputContext();
 
395
    if (context) {
 
396
        QKeyEvent qKeyEvent(keyType, sym, modifiers, text);
 
397
        qKeyEvent.setTimestamp(timestamp);
 
398
        if (context->filterEvent(&qKeyEvent)) {
 
399
            DLOG("key event filtered out by input context");
 
400
            return;
 
401
        }
 
402
    }
 
403
 
 
404
    QWindowSystemInterface::handleKeyEvent(window, timestamp, keyType, sym, modifiers, text);
522
405
}