Merge lp:~oif-team/ubuntu/natty/qt4-x11/xi2.1 into lp:ubuntu/natty/qt4-x11
- Natty (11.04)
- xi2.1
- Merge into natty
Proposed by
Chase Douglas
Status: | Needs review |
---|---|
Proposed branch: | lp:~oif-team/ubuntu/natty/qt4-x11/xi2.1 |
Merge into: | lp:ubuntu/natty/qt4-x11 |
Diff against target: |
941 lines (+909/-1) 4 files modified
debian/changelog (+8/-0) debian/control (+1/-1) debian/patches/200_xi2.1.patch (+897/-0) debian/patches/series (+3/-0) |
To merge this branch: | bzr merge lp:~oif-team/ubuntu/natty/qt4-x11/xi2.1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jonathan Riddell | Pending | ||
Review via email: mp+50952@code.launchpad.net |
Commit message
Description of the change
Add in multitouch support. The patch's origin is from Denis Dzyubenko from Nokia. I have refined it some more. Hopefully this will serve as the base for multitouch support in upstream Qt when XInput 2.1 is finalized and available.
To post a comment you must log in.
Unmerged revisions
- 142. By Chase Douglas
-
* Add multitouch support through preliminary XInput 2.1
- Add debian/patches/ 200_xi2. 1.patch
- Add build dependency on new libxi-dev with XInput 2.1 support
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/changelog' | |||
2 | --- debian/changelog 2011-02-07 12:11:02 +0000 | |||
3 | +++ debian/changelog 2011-02-23 16:43:58 +0000 | |||
4 | @@ -1,3 +1,11 @@ | |||
5 | 1 | qt4-x11 (4:4.7.1-0ubuntu10) UNRELEASED; urgency=low | ||
6 | 2 | |||
7 | 3 | * Add multitouch support through preliminary XInput 2.1 | ||
8 | 4 | - Add debian/patches/200_xi2.1.patch | ||
9 | 5 | - Add build dependency on new libxi-dev with XInput 2.1 support | ||
10 | 6 | |||
11 | 7 | -- Chase Douglas <chase.douglas@ubuntu.com> Wed, 23 Feb 2011 10:59:05 -0500 | ||
12 | 8 | |||
13 | 1 | qt4-x11 (4:4.7.1-0ubuntu9) natty; urgency=high | 9 | qt4-x11 (4:4.7.1-0ubuntu9) natty; urgency=high |
14 | 2 | 10 | ||
15 | 3 | * Force Qt4 on ARM to build against gcc-4.4 due to compiler regression in | 11 | * Force Qt4 on ARM to build against gcc-4.4 due to compiler regression in |
16 | 4 | 12 | ||
17 | === modified file 'debian/control' | |||
18 | --- debian/control 2011-02-07 12:11:02 +0000 | |||
19 | +++ debian/control 2011-02-23 16:43:58 +0000 | |||
20 | @@ -13,7 +13,7 @@ | |||
21 | 13 | # libopenvg1-mesa-dev, | 13 | # libopenvg1-mesa-dev, |
22 | 14 | libpam0g-dev, libpng12-dev, libpq-dev, libreadline-dev, libsm-dev, | 14 | libpam0g-dev, libpng12-dev, libpq-dev, libreadline-dev, libsm-dev, |
23 | 15 | libsqlite0-dev, libsqlite3-dev, libtiff4-dev, libx11-dev, libxcursor-dev, | 15 | libsqlite0-dev, libsqlite3-dev, libtiff4-dev, libx11-dev, libxcursor-dev, |
25 | 16 | libxext-dev, libxft-dev, libxi-dev, libxinerama-dev, libxmu-dev, | 16 | libxext-dev, libxft-dev, libxi-dev (>= 2:1.4.1-1ubuntu1), libxinerama-dev, libxmu-dev, |
26 | 17 | libxrandr-dev, libxrender-dev, libxslt1-dev, libxt-dev, libxtst-dev, | 17 | libxrandr-dev, libxrender-dev, libxslt1-dev, libxt-dev, libxtst-dev, |
27 | 18 | libxv-dev, zlib1g-dev, freetds-dev, g++-4.4 [armel] | 18 | libxv-dev, zlib1g-dev, freetds-dev, g++-4.4 [armel] |
28 | 19 | Standards-Version: 3.9.1 | 19 | Standards-Version: 3.9.1 |
29 | 20 | 20 | ||
30 | === added file 'debian/patches/200_xi2.1.patch' | |||
31 | --- debian/patches/200_xi2.1.patch 1970-01-01 00:00:00 +0000 | |||
32 | +++ debian/patches/200_xi2.1.patch 2011-02-23 16:43:58 +0000 | |||
33 | @@ -0,0 +1,897 @@ | |||
34 | 1 | --- /dev/null | ||
35 | 2 | +++ b/config.tests/x11/xinput2/xinput2.cpp | ||
36 | 3 | @@ -0,0 +1,75 @@ | ||
37 | 4 | +/**************************************************************************** | ||
38 | 5 | +** | ||
39 | 6 | +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | ||
40 | 7 | +** All rights reserved. | ||
41 | 8 | +** Contact: Nokia Corporation (qt-info@nokia.com) | ||
42 | 9 | +** | ||
43 | 10 | +** This file is part of the config.tests of the Qt Toolkit. | ||
44 | 11 | +** | ||
45 | 12 | +** $QT_BEGIN_LICENSE:LGPL$ | ||
46 | 13 | +** No Commercial Usage | ||
47 | 14 | +** This file contains pre-release code and may not be distributed. | ||
48 | 15 | +** You may use this file in accordance with the terms and conditions | ||
49 | 16 | +** contained in the Technology Preview License Agreement accompanying | ||
50 | 17 | +** this package. | ||
51 | 18 | +** | ||
52 | 19 | +** GNU Lesser General Public License Usage | ||
53 | 20 | +** Alternatively, this file may be used under the terms of the GNU Lesser | ||
54 | 21 | +** General Public License version 2.1 as published by the Free Software | ||
55 | 22 | +** Foundation and appearing in the file LICENSE.LGPL included in the | ||
56 | 23 | +** packaging of this file. Please review the following information to | ||
57 | 24 | +** ensure the GNU Lesser General Public License version 2.1 requirements | ||
58 | 25 | +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | ||
59 | 26 | +** | ||
60 | 27 | +** In addition, as a special exception, Nokia gives you certain additional | ||
61 | 28 | +** rights. These rights are described in the Nokia Qt LGPL Exception | ||
62 | 29 | +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | ||
63 | 30 | +** | ||
64 | 31 | +** If you have questions regarding the use of this file, please contact | ||
65 | 32 | +** Nokia at qt-info@nokia.com. | ||
66 | 33 | +** | ||
67 | 34 | +** | ||
68 | 35 | +** | ||
69 | 36 | +** | ||
70 | 37 | +** | ||
71 | 38 | +** | ||
72 | 39 | +** | ||
73 | 40 | +** | ||
74 | 41 | +** $QT_END_LICENSE$ | ||
75 | 42 | +** | ||
76 | 43 | +****************************************************************************/ | ||
77 | 44 | + | ||
78 | 45 | +#include <X11/Xlib.h> | ||
79 | 46 | +#include <X11/extensions/XInput2.h> | ||
80 | 47 | +#include <X11/extensions/Xge.h> | ||
81 | 48 | + | ||
82 | 49 | +#ifndef XInput_2_1 | ||
83 | 50 | +# error "Missing XInput_2_1 #define" | ||
84 | 51 | +#endif | ||
85 | 52 | + | ||
86 | 53 | +int main(int, char **) | ||
87 | 54 | +{ | ||
88 | 55 | + // need XGenericEventCookie for XInput2 to work | ||
89 | 56 | + Display *dpy = 0; | ||
90 | 57 | + XEvent xevent; | ||
91 | 58 | + if (XGetEventData(dpy, &xevent.xcookie)) { | ||
92 | 59 | + XFreeEventData(dpy, &xevent.xcookie); | ||
93 | 60 | + } | ||
94 | 61 | + | ||
95 | 62 | + XIEvent *xievent; | ||
96 | 63 | + xievent = 0; | ||
97 | 64 | + | ||
98 | 65 | + XIDeviceEvent *xideviceevent; | ||
99 | 66 | + xideviceevent = 0; | ||
100 | 67 | + | ||
101 | 68 | + XIHierarchyEvent *xihierarchyevent; | ||
102 | 69 | + xihierarchyevent = 0; | ||
103 | 70 | + | ||
104 | 71 | + int deviceid = 0; | ||
105 | 72 | + int len = 0; | ||
106 | 73 | + Atom *atoms = XIListProperties(dpy, deviceid, &len); | ||
107 | 74 | + if (atoms) | ||
108 | 75 | + XFree(atoms); | ||
109 | 76 | + | ||
110 | 77 | + return 0; | ||
111 | 78 | +} | ||
112 | 79 | --- /dev/null | ||
113 | 80 | +++ b/config.tests/x11/xinput2/xinput2.pro | ||
114 | 81 | @@ -0,0 +1,4 @@ | ||
115 | 82 | +CONFIG += x11 | ||
116 | 83 | +CONFIG -= qt | ||
117 | 84 | +LIBS += -lXi | ||
118 | 85 | +SOURCES = xinput2.cpp | ||
119 | 86 | --- a/configure | ||
120 | 87 | +++ b/configure | ||
121 | 88 | @@ -765,6 +765,7 @@ CFG_DECORATION_AVAILABLE="styled windows | ||
122 | 89 | CFG_DECORATION_ON="${CFG_DECORATION_AVAILABLE}" # all on by default | ||
123 | 90 | CFG_DECORATION_PLUGIN_AVAILABLE= | ||
124 | 91 | CFG_DECORATION_PLUGIN= | ||
125 | 92 | +CFG_XINPUT2=auto | ||
126 | 93 | CFG_XINPUT=runtime | ||
127 | 94 | CFG_XKB=auto | ||
128 | 95 | CFG_NIS=auto | ||
129 | 96 | @@ -991,7 +992,7 @@ while [ "$#" -gt 0 ]; do | ||
130 | 97 | VAL=no | ||
131 | 98 | ;; | ||
132 | 99 | #Qt style yes options | ||
133 | 100 | - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-webkit|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles) | ||
134 | 101 | + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-webkit|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles) | ||
135 | 102 | VAR=`echo $1 | sed "s,^-\(.*\),\1,"` | ||
136 | 103 | VAL=yes | ||
137 | 104 | ;; | ||
138 | 105 | @@ -1637,6 +1638,13 @@ while [ "$#" -gt 0 ]; do | ||
139 | 106 | UNKNOWN_OPT=yes | ||
140 | 107 | fi | ||
141 | 108 | ;; | ||
142 | 109 | + xinput2) | ||
143 | 110 | + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then | ||
144 | 111 | + CFG_XINPUT2="$VAL" | ||
145 | 112 | + else | ||
146 | 113 | + UNKNOWN_OPT=yes | ||
147 | 114 | + fi | ||
148 | 115 | + ;; | ||
149 | 116 | xinput) | ||
150 | 117 | if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ] || [ "$VAL" = "runtime" ]; then | ||
151 | 118 | CFG_XINPUT="$VAL" | ||
152 | 119 | @@ -3982,6 +3990,13 @@ if [ "$PLATFORM_X11" = "yes" ]; then | ||
153 | 120 | XMY="*" | ||
154 | 121 | XMN=" " | ||
155 | 122 | fi | ||
156 | 123 | + if [ "$CFG_XINPUT2" = "no" ]; then | ||
157 | 124 | + X2Y=" " | ||
158 | 125 | + X2N="*" | ||
159 | 126 | + else | ||
160 | 127 | + X2Y="*" | ||
161 | 128 | + X2N=" " | ||
162 | 129 | + fi | ||
163 | 130 | if [ "$CFG_XINPUT" = "no" ]; then | ||
164 | 131 | XIY=" " | ||
165 | 132 | XIN="*" | ||
166 | 133 | @@ -4086,7 +4101,10 @@ Qt/X11 only: | ||
167 | 134 | Requires fontconfig/fontconfig.h, libfontconfig, | ||
168 | 135 | freetype.h and libfreetype. | ||
169 | 136 | |||
170 | 137 | - $XIN -no-xinput ......... Do not compile Xinput support. | ||
171 | 138 | + $X2N -no-xinput2......... Do not compile XInput2 support. | ||
172 | 139 | + $X2Y -xinput2............ Compile XInput2 support. | ||
173 | 140 | + | ||
174 | 141 | + $XIN -no-xinput.......... Do not compile Xinput support. | ||
175 | 142 | $XIY -xinput ............ Compile Xinput support. This also enabled tablet support | ||
176 | 143 | which requires IRIX with wacom.h and libXi or | ||
177 | 144 | XFree86 with X11/extensions/XInput.h and libXi. | ||
178 | 145 | @@ -5910,7 +5928,23 @@ if [ "$PLATFORM_X11" = "yes" ]; then | ||
179 | 146 | fi | ||
180 | 147 | fi | ||
181 | 148 | |||
182 | 149 | - # auto-detect Xinput support | ||
183 | 150 | + # auto-detect XInput2/Xinput support | ||
184 | 151 | + if [ "$CFG_XINPUT2" != "no" ]; then | ||
185 | 152 | + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinput2 "XInput2" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then | ||
186 | 153 | + CFG_XINPUT2=yes | ||
187 | 154 | + CFG_XINPUT=no | ||
188 | 155 | + else | ||
189 | 156 | + if [ "$CFG_XINPUT2" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then | ||
190 | 157 | + echo "XInput2 support cannot be enabled due to functionality tests!" | ||
191 | 158 | + echo " Turn on verbose messaging (-v) to $0 to see the final report." | ||
192 | 159 | + echo " If you believe this message is in error you may use the continue" | ||
193 | 160 | + echo " switch (-continue) to $0 to continue." | ||
194 | 161 | + exit 101 | ||
195 | 162 | + else | ||
196 | 163 | + CFG_XINPUT2=no | ||
197 | 164 | + fi | ||
198 | 165 | + fi | ||
199 | 166 | + fi | ||
200 | 167 | if [ "$CFG_XINPUT" != "no" ]; then | ||
201 | 168 | if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xinput "XInput" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then | ||
202 | 169 | if [ "$CFG_XINPUT" != "runtime" ]; then | ||
203 | 170 | @@ -6971,9 +7005,12 @@ if [ "$PLATFORM_X11" = "yes" ]; then | ||
204 | 171 | if [ "$CFG_FONTCONFIG" = "yes" ]; then | ||
205 | 172 | QT_CONFIG="$QT_CONFIG fontconfig" | ||
206 | 173 | fi | ||
207 | 174 | - if [ "$CFG_XINPUT" = "yes" ]; then | ||
208 | 175 | + if [ "$CFG_XINPUT2" = "yes" -o "$CFG_XINPUT" = "yes" ]; then | ||
209 | 176 | QMakeVar set QMAKE_LIBS_X11 '-lXi $$QMAKE_LIBS_X11' | ||
210 | 177 | fi | ||
211 | 178 | + if [ "$CFG_XINPUT2" = "yes" ]; then | ||
212 | 179 | + QT_CONFIG="$QT_CONFIG xinput2" | ||
213 | 180 | + fi | ||
214 | 181 | if [ "$CFG_XINPUT" = "yes" ]; then | ||
215 | 182 | QT_CONFIG="$QT_CONFIG xinput tablet" | ||
216 | 183 | fi | ||
217 | 184 | @@ -7846,6 +7883,7 @@ fi | ||
218 | 185 | [ "$CFG_XSHAPE" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SHAPE" | ||
219 | 186 | [ "$CFG_XVIDEO" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XVIDEO" | ||
220 | 187 | [ "$CFG_XSYNC" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XSYNC" | ||
221 | 188 | +[ "$CFG_XINPUT2" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XINPUT2" | ||
222 | 189 | [ "$CFG_XINPUT" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_XINPUT QT_NO_TABLET" | ||
223 | 190 | |||
224 | 191 | [ "$CFG_XCURSOR" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XCURSOR" | ||
225 | 192 | @@ -8376,6 +8414,7 @@ if [ "$PLATFORM_X11" = "yes" ]; then | ||
226 | 193 | echo "Xfixes support ......... $CFG_XFIXES" | ||
227 | 194 | echo "Xrandr support ......... $CFG_XRANDR" | ||
228 | 195 | echo "Xrender support ........ $CFG_XRENDER" | ||
229 | 196 | + echo "XInput2 support ........ $CFG_XINPUT2" | ||
230 | 197 | echo "Xi support ............. $CFG_XINPUT" | ||
231 | 198 | echo "MIT-SHM support ........ $CFG_MITSHM" | ||
232 | 199 | echo "FontConfig support ..... $CFG_FONTCONFIG" | ||
233 | 200 | --- a/examples/touch/fingerpaint/scribblearea.cpp | ||
234 | 201 | +++ b/examples/touch/fingerpaint/scribblearea.cpp | ||
235 | 202 | @@ -186,7 +186,9 @@ bool ScribbleArea::event(QEvent *event) | ||
236 | 203 | QRectF rect = touchPoint.rect(); | ||
237 | 204 | if (rect.isEmpty()) { | ||
238 | 205 | qreal diameter = qreal(50) * touchPoint.pressure(); | ||
239 | 206 | + QPointF center = rect.center(); | ||
240 | 207 | rect.setSize(QSizeF(diameter, diameter)); | ||
241 | 208 | + rect.moveCenter(center); | ||
242 | 209 | } | ||
243 | 210 | |||
244 | 211 | QPainter painter(&image); | ||
245 | 212 | --- a/src/gui/kernel/kernel.pri | ||
246 | 213 | +++ b/src/gui/kernel/kernel.pri | ||
247 | 214 | @@ -141,6 +141,7 @@ symbian { | ||
248 | 215 | unix:x11 { | ||
249 | 216 | INCLUDEPATH += ../3rdparty/xorg | ||
250 | 217 | HEADERS += \ | ||
251 | 218 | + kernel/qt_x11_p.h \ | ||
252 | 219 | kernel/qx11embed_x11.h \ | ||
253 | 220 | kernel/qx11info_x11.h \ | ||
254 | 221 | kernel/qkde_p.h | ||
255 | 222 | --- a/src/gui/kernel/qapplication_p.h | ||
256 | 223 | +++ b/src/gui/kernel/qapplication_p.h | ||
257 | 224 | @@ -601,6 +601,35 @@ public: | ||
258 | 225 | QList<QTouchEvent::TouchPoint> appAllTouchPoints; | ||
259 | 226 | #endif | ||
260 | 227 | |||
261 | 228 | +#if defined(Q_WS_X11) && !defined(QT_NO_XINPUT2) | ||
262 | 229 | + struct TouchDeviceInfo { | ||
263 | 230 | + int deviceid; | ||
264 | 231 | + int maxTouches; | ||
265 | 232 | + bool directTouch; | ||
266 | 233 | + int numValuators; | ||
267 | 234 | + struct Valuator { | ||
268 | 235 | + int number; | ||
269 | 236 | + unsigned long label; // Atom | ||
270 | 237 | + qreal min; | ||
271 | 238 | + qreal max; | ||
272 | 239 | + quint32 resolution; | ||
273 | 240 | + }; | ||
274 | 241 | + Valuator xivPosX; | ||
275 | 242 | + Valuator xivPosY; | ||
276 | 243 | + Valuator xivTouchMajor; | ||
277 | 244 | + Valuator xivTouchMinor; | ||
278 | 245 | + Valuator xivOrientation; | ||
279 | 246 | + }; | ||
280 | 247 | + QHash<int, TouchDeviceInfo> touchDevices; | ||
281 | 248 | + QList<QTouchEvent::TouchPoint> appTouchPoints; | ||
282 | 249 | + QTouchEvent::DeviceType activeDeviceType; | ||
283 | 250 | + QMap<int, QPointF> touchedPos; // initial value of X and Y valuators for indirect touch | ||
284 | 251 | + QMap<int, QSizeF> touchedSize; // major => height, minor => width | ||
285 | 252 | + QMap<int, qreal> touchedOrientation; // -1 => point to left, 0 => point up, 1 => point to right | ||
286 | 253 | + QTouchEvent::TouchPoint unsentAppTouchPoint; // sequence that was not delivered to a widget yet | ||
287 | 254 | + void x11GetTouchDeviceInfo(); | ||
288 | 255 | +#endif | ||
289 | 256 | + | ||
290 | 257 | private: | ||
291 | 258 | #ifdef Q_WS_QWS | ||
292 | 259 | QMap<const QScreen*, QRect> maxWindowRects; | ||
293 | 260 | --- a/src/gui/kernel/qapplication_x11.cpp | ||
294 | 261 | +++ b/src/gui/kernel/qapplication_x11.cpp | ||
295 | 262 | @@ -87,6 +87,7 @@ | ||
296 | 263 | #include <private/qgraphicssystemfactory_p.h> | ||
297 | 264 | #include "qguiplatformplugin_p.h" | ||
298 | 265 | #include "qkde_p.h" | ||
299 | 266 | +#include "qmath.h" | ||
300 | 267 | |||
301 | 268 | #if !defined (QT_NO_TABLET) | ||
302 | 269 | extern "C" { | ||
303 | 270 | @@ -126,9 +127,6 @@ extern "C" { | ||
304 | 271 | |||
305 | 272 | #define XK_MISCELLANY | ||
306 | 273 | #include <X11/keysymdef.h> | ||
307 | 274 | -#if !defined(QT_NO_XINPUT) | ||
308 | 275 | -#include <X11/extensions/XI.h> | ||
309 | 276 | -#endif | ||
310 | 277 | |||
311 | 278 | #include <stdlib.h> | ||
312 | 279 | #include <string.h> | ||
313 | 280 | @@ -327,6 +325,13 @@ static const char * x11_atomnames = { | ||
314 | 281 | // Tablet | ||
315 | 282 | "STYLUS\0" | ||
316 | 283 | "ERASER\0" | ||
317 | 284 | + | ||
318 | 285 | + // XInput 2.1 touch | ||
319 | 286 | + "Abs MT Touch Major\0" | ||
320 | 287 | + "Abs MT Touch Minor\0" | ||
321 | 288 | + "Abs MT Orientation\0" | ||
322 | 289 | + "Abs MT Position X\0" | ||
323 | 290 | + "Abs MT Position Y\0" | ||
324 | 291 | }; | ||
325 | 292 | |||
326 | 293 | Q_GUI_EXPORT QX11Data *qt_x11Data = 0; | ||
327 | 294 | @@ -578,6 +583,10 @@ public: | ||
328 | 295 | #endif | ||
329 | 296 | bool translatePropertyEvent(const XEvent *); | ||
330 | 297 | |||
331 | 298 | +#if !defined(QT_NO_XINPUT2) | ||
332 | 299 | + bool translateXI2Event(const XIEvent *); | ||
333 | 300 | +#endif | ||
334 | 301 | + | ||
335 | 302 | void doDeferredMap() | ||
336 | 303 | { | ||
337 | 304 | Q_ASSERT(testAttribute(Qt::WA_WState_Created)); | ||
338 | 305 | @@ -699,7 +708,7 @@ static int qt_x_errhandler(Display *dpy, | ||
339 | 306 | |||
340 | 307 | default: | ||
341 | 308 | #if !defined(QT_NO_XINPUT) | ||
342 | 309 | - if (err->request_code == X11->xinput_major | ||
343 | 310 | + if (err->request_code == X11->xinput_opcode | ||
344 | 311 | && err->error_code == (X11->xinput_errorbase + XI_BadDevice) | ||
345 | 312 | && err->minor_code == 3 /* X_OpenDevice */) { | ||
346 | 313 | return 0; | ||
347 | 314 | @@ -730,7 +739,7 @@ static int qt_x_errhandler(Display *dpy, | ||
348 | 315 | extensionName = "RENDER"; | ||
349 | 316 | else if (err->request_code == X11->xrandr_major) | ||
350 | 317 | extensionName = "RANDR"; | ||
351 | 318 | - else if (err->request_code == X11->xinput_major) | ||
352 | 319 | + else if (err->request_code == X11->xinput_opcode) | ||
353 | 320 | extensionName = "XInputExtension"; | ||
354 | 321 | else if (err->request_code == X11->mitshm_major) | ||
355 | 322 | extensionName = "MIT-SHM"; | ||
356 | 323 | @@ -1628,6 +1637,16 @@ static void getXDefault(const char *grou | ||
357 | 324 | } | ||
358 | 325 | #endif | ||
359 | 326 | |||
360 | 327 | +inline void copy(QApplicationPrivate::TouchDeviceInfo::Valuator &dst, | ||
361 | 328 | + const XITouchValuatorClassInfo &src) | ||
362 | 329 | +{ | ||
363 | 330 | + dst.number = src.number; | ||
364 | 331 | + dst.label = src.label; | ||
365 | 332 | + dst.min = src.min; | ||
366 | 333 | + dst.max = src.max; | ||
367 | 334 | + dst.resolution = src.resolution; | ||
368 | 335 | +} | ||
369 | 336 | + | ||
370 | 337 | // ### This should be static but it isn't because of the friend declaration | ||
371 | 338 | // ### in qpaintdevice.h which then should have a static too but can't have | ||
372 | 339 | // ### it because "storage class specifiers invalid in friend function | ||
373 | 340 | @@ -1660,9 +1679,13 @@ void qt_init(QApplicationPrivate *priv, | ||
374 | 341 | |||
375 | 342 | // XInputExtension | ||
376 | 343 | X11->use_xinput = false; | ||
377 | 344 | - X11->xinput_major = 0; | ||
378 | 345 | + X11->xinput_opcode = 0; | ||
379 | 346 | X11->xinput_eventbase = 0; | ||
380 | 347 | X11->xinput_errorbase = 0; | ||
381 | 348 | +#if !defined(QT_NO_XINPUT2) | ||
382 | 349 | + X11->xideviceinfo = 0; | ||
383 | 350 | + X11->xitouchclassinfo = 0; | ||
384 | 351 | +#endif | ||
385 | 352 | |||
386 | 353 | X11->use_xkb = false; | ||
387 | 354 | X11->xkb_major = 0; | ||
388 | 355 | @@ -2124,14 +2147,25 @@ void qt_init(QApplicationPrivate *priv, | ||
389 | 356 | #endif // QT_RUNTIME_XINERAMA | ||
390 | 357 | #endif // QT_NO_XINERAMA | ||
391 | 358 | |||
392 | 359 | -#ifndef QT_NO_XINPUT | ||
393 | 360 | +#if !defined(QT_NO_XINPUT2) | ||
394 | 361 | + X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_opcode, | ||
395 | 362 | + &X11->xinput_eventbase, &X11->xinput_errorbase); | ||
396 | 363 | + if (X11->use_xinput) { | ||
397 | 364 | + // we want XInput2 | ||
398 | 365 | + int ximajor = 2, ximinor = 1; | ||
399 | 366 | + if (XIQueryVersion(X11->display, &ximajor, &ximinor) == BadRequest) { | ||
400 | 367 | + // XInput2 not available | ||
401 | 368 | + X11->use_xinput = false; | ||
402 | 369 | + } | ||
403 | 370 | + } | ||
404 | 371 | +#elif !defined(QT_NO_XINPUT) | ||
405 | 372 | // See if Xinput is supported on the connected display | ||
406 | 373 | X11->ptrXCloseDevice = 0; | ||
407 | 374 | X11->ptrXListInputDevices = 0; | ||
408 | 375 | X11->ptrXOpenDevice = 0; | ||
409 | 376 | X11->ptrXFreeDeviceList = 0; | ||
410 | 377 | X11->ptrXSelectExtensionEvent = 0; | ||
411 | 378 | - X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_major, | ||
412 | 379 | + X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_opcode, | ||
413 | 380 | &X11->xinput_eventbase, &X11->xinput_errorbase); | ||
414 | 381 | if (X11->use_xinput) { | ||
415 | 382 | X11->ptrXCloseDevice = XINPUT_LOAD(XCloseDevice); | ||
416 | 383 | @@ -3149,6 +3183,8 @@ int QApplication::x11ProcessEvent(XEvent | ||
417 | 384 | Q_D(QApplication); | ||
418 | 385 | QScopedLoopLevelCounter loopLevelCounter(d->threadData); | ||
419 | 386 | |||
420 | 387 | + bool isXI2Event = false; | ||
421 | 388 | + | ||
422 | 389 | #ifdef ALIEN_DEBUG | ||
423 | 390 | //qDebug() << "QApplication::x11ProcessEvent:" << event->type; | ||
424 | 391 | #endif | ||
425 | 392 | @@ -3179,6 +3215,16 @@ int QApplication::x11ProcessEvent(XEvent | ||
426 | 393 | case SelectionClear: | ||
427 | 394 | X11->time = event->xselectionclear.time; | ||
428 | 395 | break; | ||
429 | 396 | +#if !defined(QT_NO_XINPUT2) | ||
430 | 397 | + case GenericEvent: | ||
431 | 398 | + if (X11->use_xinput | ||
432 | 399 | + && XGetEventData(X11->display, &event->xcookie) | ||
433 | 400 | + && event->xcookie.extension == X11->xinput_opcode) { | ||
434 | 401 | + // remember for later | ||
435 | 402 | + isXI2Event = true; | ||
436 | 403 | + } | ||
437 | 404 | + break; | ||
438 | 405 | +#endif | ||
439 | 406 | default: | ||
440 | 407 | break; | ||
441 | 408 | } | ||
442 | 409 | @@ -3190,7 +3236,43 @@ int QApplication::x11ProcessEvent(XEvent | ||
443 | 410 | } | ||
444 | 411 | #endif | ||
445 | 412 | |||
446 | 413 | - QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window); | ||
447 | 414 | + QETWidget *widget = 0; | ||
448 | 415 | +#if !defined(QT_NO_XINPUT2) | ||
449 | 416 | + if (isXI2Event) { | ||
450 | 417 | + // event->xany.window is not usable for these events | ||
451 | 418 | + // look up widget based on the type of event we received | ||
452 | 419 | + switch (event->xcookie.evtype) { | ||
453 | 420 | + case XI_TouchBegin: | ||
454 | 421 | + case XI_TouchEnd: | ||
455 | 422 | + case XI_TouchUpdate: | ||
456 | 423 | + // all of these events send XIDeviceEvents | ||
457 | 424 | + widget = (QETWidget *) QWidget::find(((XIDeviceEvent *) event->xcookie.data)->event); | ||
458 | 425 | + break; | ||
459 | 426 | + default: | ||
460 | 427 | + break; | ||
461 | 428 | + } | ||
462 | 429 | + } else | ||
463 | 430 | +#endif // !defined(QT_NO_XINPUT2) | ||
464 | 431 | + { | ||
465 | 432 | + widget = (QETWidget*)QWidget::find((WId)event->xany.window); | ||
466 | 433 | + } | ||
467 | 434 | + | ||
468 | 435 | +#if !defined(QT_NO_XINPUT2) | ||
469 | 436 | + // make sure XFreeEventData() is called at every return point | ||
470 | 437 | + class CallXFreeEventData | ||
471 | 438 | + { | ||
472 | 439 | + Display *display; | ||
473 | 440 | + XGenericEventCookie *cookie; | ||
474 | 441 | + public: | ||
475 | 442 | + CallXFreeEventData(Display *display, XGenericEventCookie *cookie) | ||
476 | 443 | + : display(display), cookie(cookie) | ||
477 | 444 | + { } | ||
478 | 445 | + ~CallXFreeEventData() | ||
479 | 446 | + { | ||
480 | 447 | + XFreeEventData(display, cookie); | ||
481 | 448 | + } | ||
482 | 449 | + } instance(X11->display, &event->xcookie); | ||
483 | 450 | +#endif | ||
484 | 451 | |||
485 | 452 | if (wPRmapper) { // just did a widget reparent? | ||
486 | 453 | if (widget == 0) { // not in std widget mapper | ||
487 | 454 | @@ -3202,6 +3284,15 @@ int QApplication::x11ProcessEvent(XEvent | ||
488 | 455 | case XKeyRelease: | ||
489 | 456 | widget = qPRFindWidget(event->xany.window); | ||
490 | 457 | break; | ||
491 | 458 | +#if !defined(QT_NO_XINPUT2) | ||
492 | 459 | + case GenericEvent: | ||
493 | 460 | + // as above, event->xany.window is unusable for these events | ||
494 | 461 | + if (isXI2Event) { | ||
495 | 462 | + widget = qPRFindWidget(((XIDeviceEvent *) event->xcookie.data)->event); | ||
496 | 463 | + break; | ||
497 | 464 | + } | ||
498 | 465 | + break; | ||
499 | 466 | +#endif | ||
500 | 467 | } | ||
501 | 468 | } | ||
502 | 469 | else if (widget->testAttribute(Qt::WA_WState_Reparented)) | ||
503 | 470 | @@ -3836,6 +3927,10 @@ int QApplication::x11ProcessEvent(XEvent | ||
504 | 471 | } | ||
505 | 472 | break; | ||
506 | 473 | |||
507 | 474 | + case GenericEvent: | ||
508 | 475 | + if (isXI2Event) | ||
509 | 476 | + widget->translateXI2Event((XIEvent *)event->xcookie.data); | ||
510 | 477 | + break; | ||
511 | 478 | default: | ||
512 | 479 | break; | ||
513 | 480 | } | ||
514 | 481 | @@ -5058,6 +5153,184 @@ bool QETWidget::translatePropertyEvent(c | ||
515 | 482 | return true; | ||
516 | 483 | } | ||
517 | 484 | |||
518 | 485 | +#if !defined(QT_NO_XINPUT2) | ||
519 | 486 | +bool QETWidget::translateXI2Event(const XIEvent *event) | ||
520 | 487 | +{ | ||
521 | 488 | + const XIDeviceEvent *dev = (const XIDeviceEvent *)event; | ||
522 | 489 | + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); | ||
523 | 490 | + const QApplicationPrivate::TouchDeviceInfo &tdi = qAppPriv->touchDevices[dev->sourceid]; | ||
524 | 491 | + const int trackingId = dev->detail; | ||
525 | 492 | + QTouchEvent::TouchPoint *tp = 0; | ||
526 | 493 | + Qt::TouchPointStates primary = Qt::TouchPointPrimary; | ||
527 | 494 | + | ||
528 | 495 | + if (!(dev->flags & XIPointerEmulated)) | ||
529 | 496 | + primary = (Qt::TouchPointStates)0; | ||
530 | 497 | + | ||
531 | 498 | + switch (event->evtype) { | ||
532 | 499 | + case XI_TouchBegin: { | ||
533 | 500 | + Q_ASSERT(qAppPriv->touchDevices.contains(dev->sourceid)); | ||
534 | 501 | + | ||
535 | 502 | + QWidget *w = childAt(QPoint(dev->event_x, dev->event_y)); | ||
536 | 503 | + if (!w) | ||
537 | 504 | + break; | ||
538 | 505 | + | ||
539 | 506 | + if (tdi.directTouch) { | ||
540 | 507 | + qAppPriv->appTouchPoints.append(QTouchEvent::TouchPoint(trackingId)); | ||
541 | 508 | + tp = &qAppPriv->appTouchPoints.last(); | ||
542 | 509 | + } else { | ||
543 | 510 | + // touch pad | ||
544 | 511 | + if (qAppPriv->appTouchPoints.isEmpty()) { | ||
545 | 512 | + if (!w->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents)) { | ||
546 | 513 | + if (qAppPriv->unsentAppTouchPoint.id() == -1) { | ||
547 | 514 | + // do not send first TouchBegin from touchpad to a widget | ||
548 | 515 | + qAppPriv->unsentAppTouchPoint = QTouchEvent::TouchPoint(trackingId); | ||
549 | 516 | + tp = &qAppPriv->unsentAppTouchPoint; | ||
550 | 517 | + } else { | ||
551 | 518 | + // second touch on a touchpad | ||
552 | 519 | + qAppPriv->unsentAppTouchPoint.setState(Qt::TouchPointPressed | primary); | ||
553 | 520 | + qAppPriv->appTouchPoints.append(qAppPriv->unsentAppTouchPoint); | ||
554 | 521 | + qAppPriv->unsentAppTouchPoint = QTouchEvent::TouchPoint(); | ||
555 | 522 | + } | ||
556 | 523 | + } | ||
557 | 524 | + } | ||
558 | 525 | + } | ||
559 | 526 | + if (!tp) { | ||
560 | 527 | + qAppPriv->appTouchPoints.append(QTouchEvent::TouchPoint(trackingId)); | ||
561 | 528 | + tp = &qAppPriv->appTouchPoints.last(); | ||
562 | 529 | + } | ||
563 | 530 | + break; | ||
564 | 531 | + } | ||
565 | 532 | + | ||
566 | 533 | + case XI_TouchEnd: | ||
567 | 534 | + case XI_TouchUpdate: { | ||
568 | 535 | + Q_ASSERT(qAppPriv->touchDevices.contains(dev->sourceid)); | ||
569 | 536 | + | ||
570 | 537 | + // find the touchpoint | ||
571 | 538 | + for (int i = 0; i < qAppPriv->appTouchPoints.size(); ++i) { | ||
572 | 539 | + QTouchEvent::TouchPoint &touchPoint = qAppPriv->appTouchPoints[i]; | ||
573 | 540 | + if (touchPoint.id() == trackingId) | ||
574 | 541 | + tp = &touchPoint; | ||
575 | 542 | + else | ||
576 | 543 | + touchPoint.setState(Qt::TouchPointStationary | primary); | ||
577 | 544 | + } | ||
578 | 545 | + if (!tp && qAppPriv->unsentAppTouchPoint.id() == trackingId) | ||
579 | 546 | + tp = &qAppPriv->unsentAppTouchPoint; | ||
580 | 547 | + if (!tp) { | ||
581 | 548 | + qWarning("Got touch without getting TouchBegin for id %d", trackingId); | ||
582 | 549 | + return false; | ||
583 | 550 | + } | ||
584 | 551 | + break; | ||
585 | 552 | + } | ||
586 | 553 | + default: | ||
587 | 554 | + qWarning() << "translateXI2Event: unknown XI2 event:" << event->evtype; | ||
588 | 555 | + return false; | ||
589 | 556 | + } | ||
590 | 557 | + | ||
591 | 558 | + qreal *values = dev->valuators.values; | ||
592 | 559 | + for (int i = 0; i < qMin(dev->valuators.mask_len * 8, tdi.numValuators); ++i) { | ||
593 | 560 | + if (XIMaskIsSet(dev->valuators.mask, i)) { | ||
594 | 561 | + if (tdi.xivPosX.number == i) { | ||
595 | 562 | + qreal value = (*values++ - tdi.xivPosX.min) / (tdi.xivPosX.max - tdi.xivPosX.min); | ||
596 | 563 | + qreal screenValue; | ||
597 | 564 | + if (tdi.directTouch) { | ||
598 | 565 | + screenValue = dev->root_x; | ||
599 | 566 | + } else { | ||
600 | 567 | + if (qAppPriv->appTouchPoints.size() > 1) { | ||
601 | 568 | + // non-first touch point, make it relative to the first one | ||
602 | 569 | + const int firstId = qAppPriv->appTouchPoints.first().id(); | ||
603 | 570 | + screenValue = dev->root_x + (value - qAppPriv->touchedPos[firstId].x()) * 300; | ||
604 | 571 | + if (event->evtype == XI_TouchBegin) | ||
605 | 572 | + qAppPriv->touchedPos[trackingId].rx() = qAppPriv->touchedPos[firstId].x(); | ||
606 | 573 | + } else { | ||
607 | 574 | + screenValue = dev->root_x; | ||
608 | 575 | + if (event->evtype == XI_TouchBegin) | ||
609 | 576 | + qAppPriv->touchedPos[trackingId].rx() = value; | ||
610 | 577 | + } | ||
611 | 578 | + } | ||
612 | 579 | + tp->d->screenRect.moveCenter(QPointF(screenValue, tp->d->screenRect.center().y())); | ||
613 | 580 | + tp->d->normalizedPos.setX(value); | ||
614 | 581 | + } else if (tdi.xivPosY.number == i) { | ||
615 | 582 | + qreal value = (*values++ - tdi.xivPosY.min) / (tdi.xivPosY.max - tdi.xivPosY.min); | ||
616 | 583 | + qreal screenValue; | ||
617 | 584 | + if (tdi.directTouch) { | ||
618 | 585 | + screenValue = dev->root_y; | ||
619 | 586 | + } else { | ||
620 | 587 | + if (qAppPriv->appTouchPoints.size() > 1) { | ||
621 | 588 | + // non-first touch point, make it relative to the first one | ||
622 | 589 | + const int firstId = qAppPriv->appTouchPoints.first().id(); | ||
623 | 590 | + screenValue = dev->root_y + (value - qAppPriv->touchedPos[firstId].y()) * 300; | ||
624 | 591 | + if (event->evtype == XI_TouchBegin) | ||
625 | 592 | + qAppPriv->touchedPos[trackingId].ry() = qAppPriv->touchedPos[firstId].y(); | ||
626 | 593 | + } else { | ||
627 | 594 | + screenValue = dev->root_y; | ||
628 | 595 | + if (event->evtype == XI_TouchBegin) | ||
629 | 596 | + qAppPriv->touchedPos[trackingId].ry() = value; | ||
630 | 597 | + } | ||
631 | 598 | + } | ||
632 | 599 | + tp->d->screenRect.moveCenter(QPointF(tp->d->screenRect.center().x(), screenValue)); | ||
633 | 600 | + tp->d->normalizedPos.setY(value); | ||
634 | 601 | + } else if (tdi.xivTouchMajor.number == i) { | ||
635 | 602 | + qreal value = (*values++ - tdi.xivTouchMajor.min) / (tdi.xivTouchMajor.max - tdi.xivTouchMajor.min); | ||
636 | 603 | + qAppPriv->touchedSize[trackingId].rheight() = value; | ||
637 | 604 | + } else if (tdi.xivTouchMinor.number == i) { | ||
638 | 605 | + qreal value = (*values++ - tdi.xivTouchMinor.min) / (tdi.xivTouchMinor.max - tdi.xivTouchMinor.min); | ||
639 | 606 | + qAppPriv->touchedSize[trackingId].rwidth() = value; | ||
640 | 607 | + } else if (tdi.xivOrientation.number == i) { | ||
641 | 608 | + qreal value = (*values++ - tdi.xivOrientation.min) / (tdi.xivOrientation.max - tdi.xivOrientation.min); | ||
642 | 609 | + qAppPriv->touchedOrientation[trackingId] = value * M_PI_2; | ||
643 | 610 | + } else | ||
644 | 611 | + ++values; | ||
645 | 612 | + } | ||
646 | 613 | + } | ||
647 | 614 | + | ||
648 | 615 | + qreal angle = qAppPriv->touchedOrientation[trackingId]; | ||
649 | 616 | + qreal width = qAppPriv->touchedSize[trackingId].height() * qFabs(qFastSin(angle)) + | ||
650 | 617 | + qAppPriv->touchedSize[trackingId].width() * qFabs(qFastCos(angle)); | ||
651 | 618 | + qreal height = qAppPriv->touchedSize[trackingId].width() * qFabs(qFastSin(angle)) + | ||
652 | 619 | + qAppPriv->touchedSize[trackingId].height() * qFabs(qFastCos(angle)); | ||
653 | 620 | + width *= tdi.directTouch ? 500 : 25; | ||
654 | 621 | + height *= tdi.directTouch ? 500 : 25; | ||
655 | 622 | + QPointF center = tp->d->screenRect.center(); | ||
656 | 623 | + tp->d->screenRect = QRectF(center.x() - width/2, center.y() - height/2, width, height); | ||
657 | 624 | + | ||
658 | 625 | + bool send = true; | ||
659 | 626 | + if (event->evtype == XI_TouchBegin) { | ||
660 | 627 | + tp->setState(Qt::TouchPointPressed | primary); | ||
661 | 628 | + if (qAppPriv->appTouchPoints.isEmpty()) | ||
662 | 629 | + send = false; | ||
663 | 630 | + } else if (event->evtype == XI_TouchUpdate) { | ||
664 | 631 | + tp->setState(Qt::TouchPointMoved | primary); | ||
665 | 632 | + QWidget *w = childAt(QPoint(dev->event_x, dev->event_y)); | ||
666 | 633 | + if (!w || (!tdi.directTouch && qAppPriv->appTouchPoints.size() == 1 && !w->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents))) | ||
667 | 634 | + send = false; | ||
668 | 635 | + } else if (event->evtype == XI_TouchEnd) { | ||
669 | 636 | + tp->setState(Qt::TouchPointReleased | primary); | ||
670 | 637 | + if (qAppPriv->appTouchPoints.isEmpty()) | ||
671 | 638 | + send = false; | ||
672 | 639 | + | ||
673 | 640 | + for (int i = 0; i < qAppPriv->appTouchPoints.size(); ++i) { | ||
674 | 641 | + if (qAppPriv->appTouchPoints[i].id() == trackingId) { | ||
675 | 642 | + qAppPriv->appTouchPoints.removeAt(i); | ||
676 | 643 | + break; | ||
677 | 644 | + } | ||
678 | 645 | + } | ||
679 | 646 | + if (qAppPriv->unsentAppTouchPoint.id() == trackingId) | ||
680 | 647 | + qAppPriv->unsentAppTouchPoint = QTouchEvent::TouchPoint(); | ||
681 | 648 | + if (qAppPriv->appTouchPoints.isEmpty()) { | ||
682 | 649 | + qAppPriv->touchedPos.clear(); | ||
683 | 650 | + qAppPriv->touchedSize.clear(); | ||
684 | 651 | + qAppPriv->touchedOrientation.clear(); | ||
685 | 652 | + } | ||
686 | 653 | + } | ||
687 | 654 | + | ||
688 | 655 | + if (send) { | ||
689 | 656 | + qAppPriv->activeDeviceType = tdi.directTouch ? QTouchEvent::TouchScreen : QTouchEvent::TouchPad; | ||
690 | 657 | + QApplicationPrivate::translateRawTouchEvent(0, qAppPriv->activeDeviceType, qAppPriv->appTouchPoints); | ||
691 | 658 | + } | ||
692 | 659 | + | ||
693 | 660 | + return true; | ||
694 | 661 | +} | ||
695 | 662 | +#endif | ||
696 | 663 | |||
697 | 664 | // | ||
698 | 665 | // Paint event translation | ||
699 | 666 | @@ -6177,11 +6450,61 @@ void QApplicationPrivate::_q_readRX71Mul | ||
700 | 667 | |||
701 | 668 | #else // !QT_RX71_MULTITOUCH | ||
702 | 669 | |||
703 | 670 | +#if !defined(QT_NO_XINPUT2) | ||
704 | 671 | +void QApplicationPrivate::x11GetTouchDeviceInfo() | ||
705 | 672 | +{ | ||
706 | 673 | + int count = 0; | ||
707 | 674 | + XIDeviceInfo *devices = XIQueryDevice(X11->display, XIAllDevices, &count); | ||
708 | 675 | + if (devices) { | ||
709 | 676 | + for (int i = 0; i < count; ++i) { | ||
710 | 677 | + if (!devices[i].enabled) | ||
711 | 678 | + continue; | ||
712 | 679 | + for (int k = 0; k < devices[i].num_classes; ++k) { | ||
713 | 680 | + XIAnyClassInfo *xiclassinfo = devices[i].classes[k]; | ||
714 | 681 | + if (xiclassinfo->type == XITouchClass) { | ||
715 | 682 | + XITouchClassInfo *t = (XITouchClassInfo *)xiclassinfo; | ||
716 | 683 | + QApplicationPrivate::TouchDeviceInfo& tdi = touchDevices[devices[i].deviceid]; | ||
717 | 684 | + tdi.deviceid = devices[i].deviceid; | ||
718 | 685 | + tdi.directTouch = t->mode == XIDirectTouch; | ||
719 | 686 | + tdi.maxTouches = t->num_touches; | ||
720 | 687 | + } else if (xiclassinfo->type == XITouchValuatorClass) { | ||
721 | 688 | + XITouchValuatorClassInfo *v = (XITouchValuatorClassInfo *)xiclassinfo; | ||
722 | 689 | + QApplicationPrivate::TouchDeviceInfo &tdi = touchDevices[devices[i].deviceid]; | ||
723 | 690 | + tdi.numValuators++; | ||
724 | 691 | + if (v->label == ATOM(XAbsMTTouchMajor)) | ||
725 | 692 | + copy(tdi.xivTouchMajor, *v); | ||
726 | 693 | + else if (v->label == ATOM(XAbsMTTouchMinor)) | ||
727 | 694 | + copy(tdi.xivTouchMinor, *v); | ||
728 | 695 | + else if (v->label == ATOM(XAbsMTOrientation)) | ||
729 | 696 | + copy(tdi.xivOrientation, *v); | ||
730 | 697 | + else if (v->label == ATOM(XAbsMTPositionX)) | ||
731 | 698 | + copy(tdi.xivPosX, *v); | ||
732 | 699 | + else if (v->label == ATOM(XAbsMTPositionY)) | ||
733 | 700 | + copy(tdi.xivPosY, *v); | ||
734 | 701 | + } | ||
735 | 702 | + } | ||
736 | 703 | + } | ||
737 | 704 | + XIFreeDeviceInfo(devices); | ||
738 | 705 | + } | ||
739 | 706 | +} | ||
740 | 707 | + | ||
741 | 708 | +void QApplicationPrivate::initializeMultitouch_sys() | ||
742 | 709 | +{ | ||
743 | 710 | + x11GetTouchDeviceInfo(); | ||
744 | 711 | +} | ||
745 | 712 | +void QApplicationPrivate::cleanupMultitouch_sys() | ||
746 | 713 | +{ | ||
747 | 714 | +} | ||
748 | 715 | + | ||
749 | 716 | +#else | ||
750 | 717 | + | ||
751 | 718 | void QApplicationPrivate::initializeMultitouch_sys() | ||
752 | 719 | { } | ||
753 | 720 | void QApplicationPrivate::cleanupMultitouch_sys() | ||
754 | 721 | { } | ||
755 | 722 | |||
756 | 723 | +#endif | ||
757 | 724 | + | ||
758 | 725 | #endif // QT_RX71_MULTITOUCH | ||
759 | 726 | |||
760 | 727 | QT_END_NAMESPACE | ||
761 | 728 | --- a/src/gui/kernel/qevent.h | ||
762 | 729 | +++ b/src/gui/kernel/qevent.h | ||
763 | 730 | @@ -791,6 +791,7 @@ public: | ||
764 | 731 | QTouchEventTouchPointPrivate *d; | ||
765 | 732 | friend class QApplication; | ||
766 | 733 | friend class QApplicationPrivate; | ||
767 | 734 | + friend class QETWidget; | ||
768 | 735 | }; | ||
769 | 736 | |||
770 | 737 | enum DeviceType { | ||
771 | 738 | --- a/src/gui/kernel/qt_x11_p.h | ||
772 | 739 | +++ b/src/gui/kernel/qt_x11_p.h | ||
773 | 740 | @@ -97,13 +97,14 @@ | ||
774 | 741 | # include <X11/extensions/shape.h> | ||
775 | 742 | #endif // QT_NO_SHAPE | ||
776 | 743 | |||
777 | 744 | - | ||
778 | 745 | -#if !defined (QT_NO_TABLET) | ||
779 | 746 | +#if !defined(QT_NO_XINPUT2) | ||
780 | 747 | +# include <X11/extensions/XInput2.h> | ||
781 | 748 | +#elif !defined (QT_NO_TABLET) | ||
782 | 749 | # include <X11/extensions/XInput.h> | ||
783 | 750 | -#if defined (Q_OS_IRIX) | ||
784 | 751 | -# include <X11/extensions/SGIMisc.h> | ||
785 | 752 | -# include <wacom.h> | ||
786 | 753 | -#endif | ||
787 | 754 | +# if defined (Q_OS_IRIX) | ||
788 | 755 | +# include <X11/extensions/SGIMisc.h> | ||
789 | 756 | +# include <wacom.h> | ||
790 | 757 | +# endif | ||
791 | 758 | #endif // QT_NO_TABLET | ||
792 | 759 | |||
793 | 760 | |||
794 | 761 | @@ -433,11 +434,15 @@ struct QX11Data | ||
795 | 762 | bool use_mitshm_pixmaps; | ||
796 | 763 | int mitshm_major; | ||
797 | 764 | |||
798 | 765 | - // true if Qt is compiled w/ Tablet support and we have a tablet. | ||
799 | 766 | + // true if Qt is compiled w/ XInput2 or Tablet support and we have a tablet. | ||
800 | 767 | bool use_xinput; | ||
801 | 768 | - int xinput_major; | ||
802 | 769 | + int xinput_opcode; | ||
803 | 770 | int xinput_eventbase; | ||
804 | 771 | int xinput_errorbase; | ||
805 | 772 | +#if !defined(QT_NO_XINPUT2) | ||
806 | 773 | + XIDeviceInfo *xideviceinfo; | ||
807 | 774 | + XITouchClassInfo *xitouchclassinfo; | ||
808 | 775 | +#endif | ||
809 | 776 | |||
810 | 777 | // for XKEYBOARD support | ||
811 | 778 | bool use_xkb; | ||
812 | 779 | @@ -683,6 +688,12 @@ struct QX11Data | ||
813 | 780 | XTabletStylus, | ||
814 | 781 | XTabletEraser, | ||
815 | 782 | |||
816 | 783 | + XAbsMTTouchMajor, | ||
817 | 784 | + XAbsMTTouchMinor, | ||
818 | 785 | + XAbsMTOrientation, | ||
819 | 786 | + XAbsMTPositionX, | ||
820 | 787 | + XAbsMTPositionY, | ||
821 | 788 | + | ||
822 | 789 | NPredefinedAtoms, | ||
823 | 790 | |||
824 | 791 | _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms, | ||
825 | 792 | --- a/src/gui/kernel/qwidget.cpp | ||
826 | 793 | +++ b/src/gui/kernel/qwidget.cpp | ||
827 | 794 | @@ -10737,7 +10737,7 @@ void QWidget::setAttribute(Qt::WidgetAtt | ||
828 | 795 | |||
829 | 796 | break; | ||
830 | 797 | case Qt::WA_AcceptTouchEvents: | ||
831 | 798 | -#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) | ||
832 | 799 | +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) | ||
833 | 800 | if (on) | ||
834 | 801 | d->registerTouchWindow(); | ||
835 | 802 | #endif | ||
836 | 803 | --- a/src/gui/kernel/qwidget_p.h | ||
837 | 804 | +++ b/src/gui/kernel/qwidget_p.h | ||
838 | 805 | @@ -667,6 +667,8 @@ public: | ||
839 | 806 | |||
840 | 807 | inline QRect mapFromWS(const QRect &r) const | ||
841 | 808 | { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; } | ||
842 | 809 | + | ||
843 | 810 | + void registerTouchWindow(); | ||
844 | 811 | #endif | ||
845 | 812 | |||
846 | 813 | // Variables. | ||
847 | 814 | @@ -776,7 +778,6 @@ public: | ||
848 | 815 | void unregisterOleDnd(QWidget *widget, QOleDropTarget *target); | ||
849 | 816 | #endif | ||
850 | 817 | void grabMouseWhileInWindow(); | ||
851 | 818 | - void registerTouchWindow(); | ||
852 | 819 | void winSetupGestures(); | ||
853 | 820 | #elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC | ||
854 | 821 | // This is new stuff | ||
855 | 822 | @@ -852,7 +853,6 @@ public: | ||
856 | 823 | static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *); | ||
857 | 824 | static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *); | ||
858 | 825 | static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); | ||
859 | 826 | - void registerTouchWindow(); | ||
860 | 827 | #elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS | ||
861 | 828 | void setMaxWindowState_helper(); | ||
862 | 829 | void setFullScreenSize_helper(); | ||
863 | 830 | @@ -872,7 +872,6 @@ public: | ||
864 | 831 | static QWidget *keyboardGrabber; | ||
865 | 832 | void s60UpdateIsOpaque(); | ||
866 | 833 | void reparentChildren(); | ||
867 | 834 | - void registerTouchWindow(); | ||
868 | 835 | #endif | ||
869 | 836 | |||
870 | 837 | }; | ||
871 | 838 | --- a/src/gui/kernel/qwidget_x11.cpp | ||
872 | 839 | +++ b/src/gui/kernel/qwidget_x11.cpp | ||
873 | 840 | @@ -871,7 +871,13 @@ void QWidgetPrivate::create_sys(WId wind | ||
874 | 841 | // else | ||
875 | 842 | XSelectInput(dpy, id, stdDesktopEventMask); | ||
876 | 843 | } else if (q->internalWinId()) { | ||
877 | 844 | - XSelectInput(dpy, id, stdWidgetEventMask); | ||
878 | 845 | + uint eventmask = stdWidgetEventMask; | ||
879 | 846 | + | ||
880 | 847 | + if (q->testAttribute(Qt::WA_AcceptTouchEvents)) | ||
881 | 848 | + registerTouchWindow(); | ||
882 | 849 | + | ||
883 | 850 | + XSelectInput(dpy, id, eventmask); | ||
884 | 851 | + | ||
885 | 852 | #if !defined (QT_NO_TABLET) | ||
886 | 853 | QTabletDeviceDataList *tablet_list = qt_tablet_devices(); | ||
887 | 854 | if (X11->ptrXSelectExtensionEvent) { | ||
888 | 855 | @@ -938,6 +944,9 @@ void QWidgetPrivate::create_sys(WId wind | ||
889 | 856 | surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint())); | ||
890 | 857 | } | ||
891 | 858 | |||
892 | 859 | + if (q->testAttribute(Qt::WA_AcceptTouchEvents)) | ||
893 | 860 | + registerTouchWindow(); | ||
894 | 861 | + | ||
895 | 862 | #ifdef ALIEN_DEBUG | ||
896 | 863 | qDebug() << "QWidgetPrivate::create_sys END:" << q; | ||
897 | 864 | #endif | ||
898 | 865 | @@ -3099,4 +3108,32 @@ void QWidgetPrivate::updateX11AcceptFocu | ||
899 | 866 | XFree((char *)h); | ||
900 | 867 | } | ||
901 | 868 | |||
902 | 869 | +void QWidgetPrivate::registerTouchWindow() | ||
903 | 870 | +{ | ||
904 | 871 | +#if !defined(QT_NO_XINPUT2) | ||
905 | 872 | + Q_Q(QWidget); | ||
906 | 873 | + | ||
907 | 874 | + if (!q->testAttribute(Qt::WA_WState_Created) || q->windowType() == Qt::Desktop) | ||
908 | 875 | + return; | ||
909 | 876 | + | ||
910 | 877 | + if (X11->use_xinput) { | ||
911 | 878 | + XIEventMask xieventmask; | ||
912 | 879 | + | ||
913 | 880 | + const int mask_len = XIMaskLen(XI_LASTEVENT); | ||
914 | 881 | + QVector<uchar> mask_vector(mask_len, 0); | ||
915 | 882 | + uchar *bitmask = mask_vector.data(); | ||
916 | 883 | + | ||
917 | 884 | + xieventmask.deviceid = XIAllDevices; | ||
918 | 885 | + xieventmask.mask = bitmask; | ||
919 | 886 | + xieventmask.mask_len = mask_len; | ||
920 | 887 | + | ||
921 | 888 | + XISetMask(bitmask, XI_TouchBegin); | ||
922 | 889 | + XISetMask(bitmask, XI_TouchEnd); | ||
923 | 890 | + XISetMask(bitmask, XI_TouchUpdate); | ||
924 | 891 | + | ||
925 | 892 | + XISelectEvents(X11->display, q->effectiveWinId(), &xieventmask, 1); | ||
926 | 893 | + } | ||
927 | 894 | +#endif | ||
928 | 895 | +} | ||
929 | 896 | + | ||
930 | 897 | QT_END_NAMESPACE | ||
931 | 0 | 898 | ||
932 | === modified file 'debian/patches/series' | |||
933 | --- debian/patches/series 2011-01-18 20:37:32 +0000 | |||
934 | +++ debian/patches/series 2011-02-23 16:43:58 +0000 | |||
935 | @@ -48,3 +48,6 @@ | |||
936 | 48 | kubuntu_25_qsortfilterproxymodel.diff | 48 | kubuntu_25_qsortfilterproxymodel.diff |
937 | 49 | kubuntu_26_dbusconnection_pointer.diff | 49 | kubuntu_26_dbusconnection_pointer.diff |
938 | 50 | kubuntu_27_dbus_signal_filter_passes_not_handled.diff | 50 | kubuntu_27_dbus_signal_filter_passes_not_handled.diff |
939 | 51 | |||
940 | 52 | # XI 2.1 multitouch support | ||
941 | 53 | 200_xi2.1.patch |