Qt 4.8
qmouse_qws.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qmouse_qws.h"
43 #include "qwindowsystem_qws.h"
44 #include "qscreen_qws.h"
45 #include "qapplication.h"
46 #include "qtextstream.h"
47 #include "qfile.h"
48 #include "qdebug.h"
49 #include "qscreen_qws.h"
50 
52 
110 {
111 public:
113 
114  const QScreen *screen;
115 };
116 
224  : mousePos(QWSServer::mousePosition), d_ptr(new QWSMouseHandlerPrivate)
225 {
226 }
227 
237 {
238  delete d_ptr;
239 }
240 
249 {
250  position.setX(qMin(d_ptr->screen->deviceWidth() - 1, qMax(0, position.x())));
251  position.setY(qMin(d_ptr->screen->deviceHeight() - 1, qMax(0, position.y())));
252 }
253 
265 {
266  d_ptr->screen = (screen ? screen : qt_screen);
267 }
268 
285 void QWSMouseHandler::mouseChanged(const QPoint &position, int state, int wheel)
286 {
287  mousePos = position + d_ptr->screen->offset();
288  QWSServer::sendMouseEvent(mousePos, state, wheel);
289 }
290 
383  : samples(5), currSample(0), numSamples(0)
384 {
386  readCalibration();
387 }
388 
396 {
397  const qint64 scale = qint64(a) * qint64(e) - qint64(b) * qint64(d);
398  const qint64 xOff = qint64(b) * qint64(f) - qint64(c) * qint64(e);
399  const qint64 yOff = qint64(c) * qint64(d) - qint64(a) * qint64(f);
400  for (int i = 0; i <= QWSPointerCalibrationData::LastLocation; ++i) {
401  const qint64 sX = cd->screenPoints[i].x();
402  const qint64 sY = cd->screenPoints[i].y();
403  const qint64 dX = (s*(e*sX - b*sY) + xOff) / scale;
404  const qint64 dY = (s*(a*sY - d*sX) + yOff) / scale;
405  cd->devPoints[i] = QPoint(dX, dY);
406  }
407 }
408 
417 {
418  a = 1;
419  b = 0;
420  c = 0;
421  d = 0;
422  e = 1;
423  f = 0;
424  s = 1;
425 }
426 
427 
438 {
439  QString calFile;
440  calFile = QString::fromLocal8Bit(qgetenv("POINTERCAL_FILE"));
441  if (calFile.isEmpty())
442  calFile = QLatin1String("/etc/pointercal");
443 
444 #ifndef QT_NO_TEXTSTREAM
445  QFile file(calFile);
446  if (file.open(QIODevice::WriteOnly)) {
447  QTextStream t(&file);
448  t << a << ' ' << b << ' ' << c << ' ';
449  t << d << ' ' << e << ' ' << f << ' ' << s << endl;
450  } else
451 #endif
452  {
453  qCritical("QWSCalibratedMouseHandler::writeCalibration: "
454  "Could not save calibration into %s", qPrintable(calFile));
455  }
456 }
457 
470 {
471  QString calFile = QString::fromLocal8Bit(qgetenv("POINTERCAL_FILE"));
472  if (calFile.isEmpty())
473  calFile = QLatin1String("/etc/pointercal");
474 
475 #ifndef QT_NO_TEXTSTREAM
476  QFile file(calFile);
477  if (file.open(QIODevice::ReadOnly)) {
478  QTextStream t(&file);
479  t >> a >> b >> c >> d >> e >> f >> s;
480  if (s == 0 || t.status() != QTextStream::Ok) {
481  qCritical("Corrupt calibration data");
483  }
484  } else
485 #endif
486  {
487  qDebug() << "Could not read calibration:" <<calFile;
488  }
489 }
490 
491 static int ilog2(quint32 n)
492 {
493  int result = 0;
494 
495  if (n & 0xffff0000) {
496  n >>= 16;
497  result += 16;
498  }
499  if (n & 0xff00) {
500  n >>= 8;
501  result += 8;}
502  if (n & 0xf0) {
503  n >>= 4;
504  result += 4;
505  }
506  if (n & 0xc) {
507  n >>= 2;
508  result += 2;
509  }
510  if (n & 0x2)
511  result += 1;
512 
513  return result;
514 }
515 
527 {
528  // Algorithm derived from
529  // "How To Calibrate Touch Screens" by Carlos E. Vidales,
530  // printed in Embedded Systems Programming, Vol. 15 no 6, June 2002
531  // URL: http://www.embedded.com/showArticle.jhtml?articleID=9900629
532 
539 
540  const qint64 xd0 = pd0.x();
541  const qint64 xd1 = pd1.x();
542  const qint64 xd2 = pd2.x();
543  const qint64 yd0 = pd0.y();
544  const qint64 yd1 = pd1.y();
545  const qint64 yd2 = pd2.y();
546  const qint64 x0 = p0.x();
547  const qint64 x1 = p1.x();
548  const qint64 x2 = p2.x();
549  const qint64 y0 = p0.y();
550  const qint64 y1 = p1.y();
551  const qint64 y2 = p2.y();
552 
553  qint64 scale = ((xd0 - xd2)*(yd1 - yd2) - (xd1 - xd2)*(yd0 - yd2));
554  int shift = 0;
555  qint64 absScale = qAbs(scale);
556  // use maximum 16 bit precision to reduce risk of integer overflow
557  if (absScale > (1 << 16)) {
558  shift = ilog2(absScale >> 16) + 1;
559  scale >>= shift;
560  }
561 
562  s = scale;
563  a = ((x0 - x2)*(yd1 - yd2) - (x1 - x2)*(yd0 - yd2)) >> shift;
564  b = ((xd0 - xd2)*(x1 - x2) - (x0 - x2)*(xd1 - xd2)) >> shift;
565  c = (yd0*(xd2*x1 - xd1*x2) + yd1*(xd0*x2 - xd2*x0) + yd2*(xd1*x0 - xd0*x1)) >> shift;
566  d = ((y0 - y2)*(yd1 - yd2) - (y1 - y2)*(yd0 - yd2)) >> shift;
567  e = ((xd0 - xd2)*(y1 - y2) - (y0 - y2)*(xd1 - xd2)) >> shift;
568  f = (yd0*(xd2*y1 - xd1*y2) + yd1*(xd0*y2 - xd2*y0) + yd2*(xd1*y0 - xd0*y1)) >> shift;
569 
571 }
572 
590 {
591  QPoint tp;
592 
593  tp.setX((a * position.x() + b * position.y() + c) / s);
594  tp.setY((d * position.x() + e * position.y() + f) / s);
595 
596  return tp;
597 }
598 
611 {
612  samples.resize(qMax(1, size));
613  numSamples = 0;
614  currSample = 0;
615 }
616 
640 {
641  if (!button) {
642  if (numSamples >= samples.count())
643  mouseChanged(transform(position), 0);
644  currSample = 0;
645  numSamples = 0;
646  return true;
647  }
648 
649  bool sent = false;
651  numSamples++;
652  if (numSamples >= samples.count()) {
653 
654  int ignore = -1;
655  if (samples.count() > 2) { // throw away the "worst" sample
656  int maxd = 0;
657  for (int i = 0; i < samples.count(); i++) {
658  int d = (mousePos - samples[i]).manhattanLength();
659  if (d > maxd) {
660  maxd = d;
661  ignore = i;
662  }
663  }
664  }
665 
666  // average the rest
667  QPoint pos(0, 0);
668  int numAveraged = 0;
669  for (int i = 0; i < samples.count(); i++) {
670  if (ignore == i)
671  continue;
672  pos += samples[i];
673  ++numAveraged;
674  }
675  if (numAveraged)
676  pos /= numAveraged;
677 
678  mouseChanged(transform(pos), button);
679  sent = true;
680  }
681  currSample++;
682  if (currSample >= samples.count())
683  currSample = 0;
684 
685  return sent;
686 }
687 
QPoint transform(const QPoint &)
Transforms the given position from device coordinates to screen coordinates, and returns the transfor...
Definition: qmouse_qws.cpp:589
Q_GUI_EXPORT QScreen * qt_screen
Definition: qscreen_qws.cpp:69
Status status() const
Returns the status of the text stream.
static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
Definition: qbezier.cpp:289
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static QString fromLocal8Bit(const char *, int size=-1)
Returns a QString initialized with the first size characters of the 8-bit string str.
Definition: qstring.cpp:4245
static void sendMouseEvent(const QPoint &pos, int state, int wheel=0)
Send a mouse event.
QPoint devPoints[5]
the raw device coordinates for each value of the Location enum.
Definition: qmouse_qws.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void readCalibration()
Reads previously written calibration parameters which are stored in /etc/pointercal (separated by whi...
Definition: qmouse_qws.cpp:469
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
bool open(OpenMode flags)
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition: qfile.cpp:1064
virtual void getCalibration(QWSPointerCalibrationData *) const
Fills cd with the device coordinates corresponding to the given screen coordinates.
Definition: qmouse_qws.cpp:395
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
static bool ignore(const char *test, const char *const *table)
Definition: qaxserver.cpp:660
QPoint & mousePos
Definition: qmouse_qws.h:87
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int deviceWidth() const
Returns the physical width of the framebuffer device in pixels.
Definition: qscreen_qws.h:233
virtual void calibrate(const QWSPointerCalibrationData *)
Updates the calibration parameters based on coordinate mapping of the given data. ...
Definition: qmouse_qws.cpp:526
The QString class provides a Unicode character string.
Definition: qstring.h:83
const QPoint & pos() const
Returns the current mouse position.
Definition: qmouse_qws.h:82
QPoint screenPoints[5]
the logical screen coordinates for each value of the Location enum.
Definition: qmouse_qws.h:63
void mouseChanged(const QPoint &pos, int bstate, int wheel=0)
Notifies the system of a new mouse event.
Definition: qmouse_qws.cpp:285
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
virtual void clearCalibration()
Clears the current calibration, i.e., makes the mouse driver return mouse events in raw device coordi...
Definition: qmouse_qws.cpp:416
Q_CORE_EXPORT void qDebug(const char *,...)
const QScreen * screen
Definition: qmouse_qws.cpp:114
bool sendFiltered(const QPoint &, int button)
Notifies the system of a new mouse event after applying a noise reduction filter. ...
Definition: qmouse_qws.cpp:639
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static int ilog2(quint32 n)
Definition: qmouse_qws.cpp:491
static const char * data(const QByteArray &arr)
void writeCalibration()
Saves the current calibration parameters in /etc/pointercal (separated by whitespace and in alphabeti...
Definition: qmouse_qws.cpp:437
QWSMouseHandler(const QString &driver=QString(), const QString &device=QString())
Constructs a mouse driver.
Definition: qmouse_qws.cpp:223
The QWSPointerCalibrationData class is a container for mouse calibration data in Qt for Embedded Linu...
Definition: qmouse_qws.h:57
__int64 qint64
Definition: qglobal.h:942
void setY(int y)
Sets the y coordinate of this point to the given y coordinate.
Definition: qpoint.h:137
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
The QWSServer class encapsulates a server process in Qt for Embedded Linux.
int deviceHeight() const
Returns the full height of the framebuffer device in pixels.
Definition: qscreen_qws.h:234
The QTextStream class provides a convenient interface for reading and writing text.
Definition: qtextstream.h:73
QWSMouseHandlerPrivate * d_ptr
Definition: qmouse_qws.h:88
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
unsigned int quint32
Definition: qglobal.h:938
The QScreen class is a base class for screen drivers in Qt for Embedded Linux.
Definition: qscreen_qws.h:191
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void limitToScreen(QPoint &pt)
Ensures that the given position is within the screen&#39;s boundaries, changing the position if necessary...
Definition: qmouse_qws.cpp:248
#define qPrintable(string)
Definition: qglobal.h:1750
void setX(int x)
Sets the x coordinate of this point to the given x coordinate.
Definition: qpoint.h:134
QWSCalibratedMouseHandler(const QString &driver=QString(), const QString &device=QString())
Definition: qmouse_qws.cpp:382
virtual ~QWSMouseHandler()
Destroys this mouse driver.
Definition: qmouse_qws.cpp:236
Q_CORE_EXPORT void qCritical(const char *,...)
QPoint offset() const
Returns the logical offset of the screen, i.
void setScreen(const QScreen *screen)
Sets the screen for this mouse driver to be the given screen.
Definition: qmouse_qws.cpp:264
void setFilterSize(int)
Sets the size of the filter used in noise reduction to the given size.
Definition: qmouse_qws.cpp:610
Q_CORE_EXPORT QTextStream & endl(QTextStream &s)