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