source: trunk/src/gui/embedded/qmousetslib_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: 10.1 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 "qmousetslib_qws.h"
43
44#if !defined(QT_NO_QWS_MOUSE_TSLIB) || defined(QT_PLUGIN)
45
46#include <QtCore/qregexp.h>
47#include <QtCore/qstringlist.h>
48#include "qsocketnotifier.h"
49#include "qscreen_qws.h"
50
51#include <tslib.h>
52#include <errno.h>
53
54QT_BEGIN_NAMESPACE
55
56#ifdef TSLIBMOUSEHANDLER_DEBUG
57# include <QtCore/QDebug>
58#endif
59
60/*!
61 \internal
62
63 \class QWSTslibMouseHandler
64 \ingroup qws
65
66 \brief The QWSTslibMouseHandler class implements a mouse driver
67 for the Universal Touch Screen Library, tslib.
68
69 QWSTslibMouseHandler inherits the QWSCalibratedMouseHandler class,
70 providing calibration and noise reduction functionality in
71 addition to generating mouse events, for devices using the
72 Universal Touch Screen Library.
73
74 To be able to compile this mouse handler, \l{Qt for Embedded Linux}
75 must be configured with the \c -qt-mouse-tslib option, see the
76 \l{Pointer Handling} documentation for details. In addition, the tslib
77 headers and library must be present in the build environment. The
78 tslib sources can be downloaded from \l
79 {http://tslib.berlios.de/}. Use the \c -L and \c -I options
80 with \c configure to explicitly specify the location of the
81 library and its headers:
82
83 \snippet doc/src/snippets/code/src_gui_embedded_qmousetslib_qws.cpp 0
84
85 In order to use this mouse handler, tslib must also be correctly
86 installed on the target machine. This includes providing a \c
87 ts.conf configuration file and setting the necessary environment
88 variables, see the README file provided with tslib for details.
89
90 The ts.conf file will usually contain the following two lines
91
92 \snippet doc/src/snippets/code/src_gui_embedded_qmousetslib_qws.cpp 1
93
94 To make \l{Qt for Embedded Linux} explicitly choose the tslib mouse
95 handler, set the QWS_MOUSE_PROTO environment variable.
96
97 \sa {Pointer Handling}, {Qt for Embedded Linux}
98*/
99
100class QWSTslibMouseHandlerPrivate : public QObject
101{
102 Q_OBJECT
103public:
104 QWSTslibMouseHandlerPrivate(QWSTslibMouseHandler *h,
105 const QString &device);
106 ~QWSTslibMouseHandlerPrivate();
107
108 void suspend();
109 void resume();
110
111 void calibrate(const QWSPointerCalibrationData *data);
112 void clearCalibration();
113
114private:
115 QWSTslibMouseHandler *handler;
116 struct tsdev *dev;
117 QSocketNotifier *mouseNotifier;
118 int jitter_limit;
119
120 struct ts_sample lastSample;
121 bool wasPressed;
122 int lastdx;
123 int lastdy;
124
125 bool calibrated;
126 QString devName;
127
128 bool open();
129 void close();
130 inline bool get_sample(struct ts_sample *sample);
131
132private slots:
133 void readMouseData();
134};
135
136QWSTslibMouseHandlerPrivate::QWSTslibMouseHandlerPrivate(QWSTslibMouseHandler *h,
137 const QString &device)
138 : handler(h), dev(0), mouseNotifier(0), jitter_limit(3)
139{
140 QStringList args = device.split(QLatin1Char(':'), QString::SkipEmptyParts);
141 QRegExp jitterRegex(QLatin1String("^jitter_limit=(\\d+)$"));
142 int index = args.indexOf(jitterRegex);
143 if (index >= 0) {
144 jitter_limit = jitterRegex.cap(1).toInt();
145 args.removeAt(index);
146 }
147
148 devName = args.join(QString());
149
150 if (devName.isNull()) {
151 const char *str = getenv("TSLIB_TSDEVICE");
152 if (str)
153 devName = QString::fromLocal8Bit(str);
154 }
155
156 if (devName.isNull())
157 devName = QLatin1String("/dev/ts");
158
159 if (!open())
160 return;
161
162 calibrated = true;
163
164 int fd = ts_fd(dev);
165 mouseNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
166 connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
167 resume();
168}
169
170QWSTslibMouseHandlerPrivate::~QWSTslibMouseHandlerPrivate()
171{
172 close();
173}
174
175bool QWSTslibMouseHandlerPrivate::open()
176{
177 dev = ts_open(devName.toLocal8Bit().constData(), 1);
178 if (!dev) {
179 qCritical("QWSTslibMouseHandlerPrivate: ts_open() failed"
180 " with error: '%s'", strerror(errno));
181 qCritical("Please check your tslib installation!");
182 return false;
183 }
184
185 if (ts_config(dev)) {
186 qCritical("QWSTslibMouseHandlerPrivate: ts_config() failed"
187 " with error: '%s'", strerror(errno));
188 qCritical("Please check your tslib installation!");
189 close();
190 return false;
191 }
192
193 return true;
194}
195
196void QWSTslibMouseHandlerPrivate::close()
197{
198 if (dev)
199 ts_close(dev);
200}
201
202void QWSTslibMouseHandlerPrivate::suspend()
203{
204 if (mouseNotifier)
205 mouseNotifier->setEnabled(false);
206}
207
208void QWSTslibMouseHandlerPrivate::resume()
209{
210 memset(&lastSample, 0, sizeof(lastSample));
211 wasPressed = false;
212 lastdx = 0;
213 lastdy = 0;
214 if (mouseNotifier)
215 mouseNotifier->setEnabled(true);
216}
217
218bool QWSTslibMouseHandlerPrivate::get_sample(struct ts_sample *sample)
219{
220 if (!calibrated)
221 return (ts_read_raw(dev, sample, 1) == 1);
222
223 return (ts_read(dev, sample, 1) == 1);
224}
225
226void QWSTslibMouseHandlerPrivate::readMouseData()
227{
228 if (!qt_screen)
229 return;
230
231 for(;;) {
232 struct ts_sample sample = lastSample;
233 bool pressed = wasPressed;
234
235 // Fast return if there's no events.
236 if (!get_sample(&sample))
237 return;
238 pressed = (sample.pressure > 0);
239
240 // Only return last sample unless there's a press/release event.
241 while (pressed == wasPressed) {
242 if (!get_sample(&sample))
243 break;
244 pressed = (sample.pressure > 0);
245 }
246
247 // work around missing coordinates on mouse release in raw mode
248 if (!calibrated && !pressed && sample.x == 0 && sample.y == 0) {
249 sample.x = lastSample.x;
250 sample.y = lastSample.y;
251 }
252
253 int dx = sample.x - lastSample.x;
254 int dy = sample.y - lastSample.y;
255
256 // Remove small movements in oppsite direction
257 if (dx * lastdx < 0 && qAbs(dx) < jitter_limit) {
258 sample.x = lastSample.x;
259 dx = 0;
260 }
261 if (dy * lastdy < 0 && qAbs(dy) < jitter_limit) {
262 sample.y = lastSample.y;
263 dy = 0;
264 }
265
266 if (wasPressed == pressed && dx == 0 && dy == 0)
267 return;
268
269#ifdef TSLIBMOUSEHANDLER_DEBUG
270 qDebug() << "last" << QPoint(lastSample.x, lastSample.y)
271 << "curr" << QPoint(sample.x, sample.y)
272 << "dx,dy" << QPoint(dx, dy)
273 << "ddx,ddy" << QPoint(dx*lastdx, dy*lastdy)
274 << "pressed" << wasPressed << pressed;
275#endif
276
277 lastSample = sample;
278 wasPressed = pressed;
279 if (dx != 0)
280 lastdx = dx;
281 if (dy != 0)
282 lastdy = dy;
283
284 const QPoint p(sample.x, sample.y);
285 if (calibrated) {
286 // tslib should do all the translation and filtering, so we send a
287 // "raw" mouse event
288 handler->QWSMouseHandler::mouseChanged(p, pressed);
289 } else {
290 handler->sendFiltered(p, pressed);
291 }
292 }
293}
294
295void QWSTslibMouseHandlerPrivate::clearCalibration()
296{
297 suspend();
298 close();
299 handler->QWSCalibratedMouseHandler::clearCalibration();
300 calibrated = false;
301 open();
302 resume();
303}
304
305void QWSTslibMouseHandlerPrivate::calibrate(const QWSPointerCalibrationData *data)
306{
307 suspend();
308 close();
309 // default implementation writes to /etc/pointercal
310 // using the same format as the tslib linear module.
311 handler->QWSCalibratedMouseHandler::calibrate(data);
312 calibrated = true;
313 open();
314 resume();
315}
316
317/*!
318 \internal
319*/
320QWSTslibMouseHandler::QWSTslibMouseHandler(const QString &driver,
321 const QString &device)
322 : QWSCalibratedMouseHandler(driver, device)
323{
324 d = new QWSTslibMouseHandlerPrivate(this, device);
325}
326
327/*!
328 \internal
329*/
330QWSTslibMouseHandler::~QWSTslibMouseHandler()
331{
332 delete d;
333}
334
335/*!
336 \reimp
337*/
338void QWSTslibMouseHandler::suspend()
339{
340 d->suspend();
341}
342
343/*!
344 \reimp
345*/
346void QWSTslibMouseHandler::resume()
347{
348 d->resume();
349}
350
351/*!
352 \reimp
353*/
354void QWSTslibMouseHandler::clearCalibration()
355{
356 d->clearCalibration();
357}
358
359/*!
360 \reimp
361*/
362void QWSTslibMouseHandler::calibrate(const QWSPointerCalibrationData *data)
363{
364 d->calibrate(data);
365}
366
367QT_END_NAMESPACE
368
369#include "qmousetslib_qws.moc"
370
371#endif //QT_NO_QWS_MOUSE_TSLIB
Note: See TracBrowser for help on using the repository browser.