source: trunk/src/gui/embedded/qmouselinuxtp_qws.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qmouselinuxtp_qws.h"
43
44#ifndef QT_NO_QWS_MOUSE_LINUXTP
45#include "qwindowsystem_qws.h"
46#include "qsocketnotifier.h"
47#include "qtimer.h"
48#include "qapplication.h"
49#include "qscreen_qws.h"
50#include <private/qcore_unix_p.h> // overrides QT_OPEN
51
52#include <unistd.h>
53#include <stdlib.h>
54#include <stdio.h>
55#include <sys/ioctl.h>
56#include <sys/types.h>
57#include <sys/stat.h>
58#include <fcntl.h>
59#include <errno.h>
60#include <termios.h>
61
62QT_BEGIN_NAMESPACE
63
64#if defined(QT_QWS_IPAQ)
65 #define QT_QWS_IPAQ_RAW
66 #define QT_QWS_SCREEN_COORDINATES
67 typedef struct {
68 unsigned short pressure;
69 unsigned short x;
70 unsigned short y;
71 unsigned short pad;
72 } TS_EVENT;
73#elif defined(QT_QWS_EBX)
74 #define QT_QWS_EBX_RAW
75 #define QT_QWS_SCREEN_COORDINATES
76#ifndef QT_QWS_SHARP
77 typedef struct {
78 unsigned short pressure;
79 unsigned short x;
80 unsigned short y;
81 unsigned short pad;
82 } TS_EVENT;
83 #else
84 typedef struct {
85 long y;
86 long x;
87 long pressure;
88 long long millisecs;
89 } TS_EVENT;
90 #define QT_QWS_TP_SAMPLE_SIZE 10
91 #define QT_QWS_TP_MINIMUM_SAMPLES 4
92 #define QT_QWS_TP_PRESSURE_THRESHOLD 500
93 #define QT_QWS_TP_MOVE_LIMIT 50
94 #define QT_QWS_TP_JITTER_LIMIT 2
95 #endif
96#else // not IPAQ, not SHARP
97 typedef struct {
98 unsigned short pressure;
99 unsigned short x;
100 unsigned short y;
101 unsigned short pad;
102 } TS_EVENT;
103#endif
104
105#ifndef QT_QWS_TP_SAMPLE_SIZE
106#define QT_QWS_TP_SAMPLE_SIZE 5
107#endif
108
109#ifndef QT_QWS_TP_MINIMUM_SAMPLES
110#define QT_QWS_TP_MINIMUM_SAMPLES 5
111#endif
112
113#ifndef QT_QWS_TP_PRESSURE_THRESHOLD
114#define QT_QWS_TP_PRESSURE_THRESHOLD 1
115#endif
116
117#ifndef QT_QWS_TP_MOVE_LIMIT
118#define QT_QWS_TP_MOVE_LIMIT 100
119#endif
120
121#ifndef QT_QWS_TP_JITTER_LIMIT
122#define QT_QWS_TP_JITTER_LIMIT 2
123#endif
124
125class QWSLinuxTPMouseHandlerPrivate : public QObject
126{
127 Q_OBJECT
128public:
129 QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHandler *h, const QString &);
130 ~QWSLinuxTPMouseHandlerPrivate();
131
132 void suspend();
133 void resume();
134private:
135 static const int mouseBufSize = 2048;
136 int mouseFD;
137 QPoint oldmouse;
138 QPoint oldTotalMousePos;
139 bool waspressed;
140 QPolygon samples;
141 int currSample;
142 int lastSample;
143 int numSamples;
144 int skipCount;
145 int mouseIdx;
146 uchar mouseBuf[mouseBufSize];
147 QWSLinuxTPMouseHandler *handler;
148 QSocketNotifier *mouseNotifier;
149
150private slots:
151 void readMouseData();
152};
153
154QWSLinuxTPMouseHandler::QWSLinuxTPMouseHandler(const QString &driver, const QString &device)
155 : QWSCalibratedMouseHandler(driver, device)
156{
157 d = new QWSLinuxTPMouseHandlerPrivate(this, device);
158}
159
160QWSLinuxTPMouseHandler::~QWSLinuxTPMouseHandler()
161{
162 delete d;
163}
164
165void QWSLinuxTPMouseHandler::suspend()
166{
167 d->suspend();
168}
169
170void QWSLinuxTPMouseHandler::resume()
171{
172 d->resume();
173}
174
175QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHandler *h,
176 const QString &device)
177 : samples(QT_QWS_TP_SAMPLE_SIZE), currSample(0), lastSample(0),
178 numSamples(0), skipCount(0), handler(h)
179{
180 QString mousedev;
181 if (device.isEmpty()) {
182#if defined(QT_QWS_IPAQ)
183# ifdef QT_QWS_IPAQ_RAW
184 mousedev = QLatin1String("/dev/h3600_tsraw");
185# else
186 mousedev = QLatin1String("/dev/h3600_ts");
187# endif
188#else
189 mousedev = QLatin1String("/dev/ts");
190#endif
191 } else {
192 mousedev = device;
193 }
194 if ((mouseFD = QT_OPEN(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) {
195 qWarning("Cannot open %s (%s)", qPrintable(mousedev), strerror(errno));
196 return;
197 }
198
199 mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read,
200 this);
201 connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
202 waspressed=false;
203 mouseIdx = 0;
204}
205
206QWSLinuxTPMouseHandlerPrivate::~QWSLinuxTPMouseHandlerPrivate()
207{
208 if (mouseFD >= 0)
209 QT_CLOSE(mouseFD);
210}
211
212void QWSLinuxTPMouseHandlerPrivate::suspend()
213{
214 if (mouseNotifier)
215 mouseNotifier->setEnabled(false);
216}
217
218void QWSLinuxTPMouseHandlerPrivate::resume()
219{
220 mouseIdx=0;
221 currSample=0;
222 lastSample=0;
223 numSamples=0;
224 skipCount=0;
225 if (mouseNotifier)
226 mouseNotifier->setEnabled(true);
227}
228
229
230void QWSLinuxTPMouseHandlerPrivate::readMouseData()
231{
232 if(!qt_screen)
233 return;
234
235 int n;
236 do {
237 n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx);
238 if (n > 0)
239 mouseIdx += n;
240 } while (n > 0 && mouseIdx < mouseBufSize);
241
242 //qDebug("readMouseData()");
243
244 TS_EVENT *data;
245 int idx = 0;
246
247 // perhaps we shouldn't be reading EVERY SAMPLE.
248 while (mouseIdx-idx >= (int)sizeof(TS_EVENT)) {
249 uchar *mb = mouseBuf+idx;
250 data = (TS_EVENT *) mb;
251
252 if(data->pressure >= QT_QWS_TP_PRESSURE_THRESHOLD) {
253#ifdef QT_QWS_SHARP
254 samples[currSample] = QPoint(1000 - data->x, data->y);
255#else
256 samples[currSample] = QPoint(data->x, data->y);
257#endif
258 numSamples++;
259 if (numSamples >= QT_QWS_TP_MINIMUM_SAMPLES) {
260 int sampleCount = qMin(numSamples + 1,samples.count());
261
262 // average the rest
263 QPoint mousePos = QPoint(0, 0);
264 QPoint totalMousePos = oldTotalMousePos;
265 totalMousePos += samples[currSample];
266 if(numSamples >= samples.count())
267 totalMousePos -= samples[lastSample];
268
269 mousePos = totalMousePos / (sampleCount - 1);
270#if defined(QT_QWS_SCREEN_COORDINATES)
271 mousePos = handler->transform(mousePos);
272#endif
273 if(!waspressed)
274 oldmouse = mousePos;
275 QPoint dp = mousePos - oldmouse;
276 int dxSqr = dp.x() * dp.x();
277 int dySqr = dp.y() * dp.y();
278 if (dxSqr + dySqr < (QT_QWS_TP_MOVE_LIMIT * QT_QWS_TP_MOVE_LIMIT)) {
279 if (waspressed) {
280 if ((dxSqr + dySqr > (QT_QWS_TP_JITTER_LIMIT * QT_QWS_TP_JITTER_LIMIT)) || skipCount > 2) {
281 handler->mouseChanged(mousePos,Qt::LeftButton);
282 oldmouse = mousePos;
283 skipCount = 0;
284 } else {
285 skipCount++;
286 }
287 } else {
288 handler->mouseChanged(mousePos,Qt::LeftButton);
289 oldmouse=mousePos;
290 waspressed=true;
291 }
292
293 // save recuring information
294 currSample++;
295 if (numSamples >= samples.count())
296 lastSample++;
297 oldTotalMousePos = totalMousePos;
298 } else {
299 numSamples--; // don't use this sample, it was bad.
300 }
301 } else {
302 // build up the average
303 oldTotalMousePos += samples[currSample];
304 currSample++;
305 }
306 if (currSample >= samples.count())
307 currSample = 0;
308 if (lastSample >= samples.count())
309 lastSample = 0;
310 } else {
311 currSample = 0;
312 lastSample = 0;
313 numSamples = 0;
314 skipCount = 0;
315 oldTotalMousePos = QPoint(0,0);
316 if (waspressed) {
317 handler->mouseChanged(oldmouse,0);
318 oldmouse = QPoint(-100, -100);
319 waspressed=false;
320 }
321 }
322 idx += sizeof(TS_EVENT);
323 }
324
325 int surplus = mouseIdx - idx;
326 for (int i = 0; i < surplus; i++)
327 mouseBuf[i] = mouseBuf[idx+i];
328 mouseIdx = surplus;
329}
330
331QT_END_NAMESPACE
332
333#include "qmouselinuxtp_qws.moc"
334
335#endif //QT_NO_QWS_MOUSE_LINUXTP
Note: See TracBrowser for help on using the repository browser.