diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:34:13 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:34:13 (GMT) |
commit | 67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch) | |
tree | 1dbf50b3dff8d5ca7e9344733968c72704eb15ff /src/gui/embedded/qmouselinuxtp_qws.cpp | |
download | Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2 |
Long live Qt!
Diffstat (limited to 'src/gui/embedded/qmouselinuxtp_qws.cpp')
-rw-r--r-- | src/gui/embedded/qmouselinuxtp_qws.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/src/gui/embedded/qmouselinuxtp_qws.cpp b/src/gui/embedded/qmouselinuxtp_qws.cpp new file mode 100644 index 0000000..7683be3 --- /dev/null +++ b/src/gui/embedded/qmouselinuxtp_qws.cpp @@ -0,0 +1,334 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmouselinuxtp_qws.h" + +#ifndef QT_NO_QWS_MOUSE_LINUXTP +#include "qwindowsystem_qws.h" +#include "qsocketnotifier.h" +#include "qtimer.h" +#include "qapplication.h" +#include "qscreen_qws.h" + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <termios.h> + +QT_BEGIN_NAMESPACE + +#if defined(QT_QWS_IPAQ) + #define QT_QWS_IPAQ_RAW + #define QT_QWS_SCREEN_COORDINATES + typedef struct { + unsigned short pressure; + unsigned short x; + unsigned short y; + unsigned short pad; + } TS_EVENT; +#elif defined(QT_QWS_EBX) + #define QT_QWS_EBX_RAW + #define QT_QWS_SCREEN_COORDINATES +#ifndef QT_QWS_SHARP + typedef struct { + unsigned short pressure; + unsigned short x; + unsigned short y; + unsigned short pad; + } TS_EVENT; + #else + typedef struct { + long y; + long x; + long pressure; + long long millisecs; + } TS_EVENT; + #define QT_QWS_TP_SAMPLE_SIZE 10 + #define QT_QWS_TP_MINIMUM_SAMPLES 4 + #define QT_QWS_TP_PRESSURE_THRESHOLD 500 + #define QT_QWS_TP_MOVE_LIMIT 50 + #define QT_QWS_TP_JITTER_LIMIT 2 + #endif +#else // not IPAQ, not SHARP + typedef struct { + unsigned short pressure; + unsigned short x; + unsigned short y; + unsigned short pad; + } TS_EVENT; +#endif + +#ifndef QT_QWS_TP_SAMPLE_SIZE +#define QT_QWS_TP_SAMPLE_SIZE 5 +#endif + +#ifndef QT_QWS_TP_MINIMUM_SAMPLES +#define QT_QWS_TP_MINIMUM_SAMPLES 5 +#endif + +#ifndef QT_QWS_TP_PRESSURE_THRESHOLD +#define QT_QWS_TP_PRESSURE_THRESHOLD 1 +#endif + +#ifndef QT_QWS_TP_MOVE_LIMIT +#define QT_QWS_TP_MOVE_LIMIT 100 +#endif + +#ifndef QT_QWS_TP_JITTER_LIMIT +#define QT_QWS_TP_JITTER_LIMIT 2 +#endif + +class QWSLinuxTPMouseHandlerPrivate : public QObject +{ + Q_OBJECT +public: + QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHandler *h, const QString &); + ~QWSLinuxTPMouseHandlerPrivate(); + + void suspend(); + void resume(); +private: + static const int mouseBufSize = 2048; + int mouseFD; + QPoint oldmouse; + QPoint oldTotalMousePos; + bool waspressed; + QPolygon samples; + int currSample; + int lastSample; + int numSamples; + int skipCount; + int mouseIdx; + uchar mouseBuf[mouseBufSize]; + QWSLinuxTPMouseHandler *handler; + QSocketNotifier *mouseNotifier; + +private slots: + void readMouseData(); +}; + +QWSLinuxTPMouseHandler::QWSLinuxTPMouseHandler(const QString &driver, const QString &device) + : QWSCalibratedMouseHandler(driver, device) +{ + d = new QWSLinuxTPMouseHandlerPrivate(this, device); +} + +QWSLinuxTPMouseHandler::~QWSLinuxTPMouseHandler() +{ + delete d; +} + +void QWSLinuxTPMouseHandler::suspend() +{ + d->suspend(); +} + +void QWSLinuxTPMouseHandler::resume() +{ + d->resume(); +} + +QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHandler *h, + const QString &device) + : samples(QT_QWS_TP_SAMPLE_SIZE), currSample(0), lastSample(0), + numSamples(0), skipCount(0), handler(h) +{ + QString mousedev; + if (device.isEmpty()) { +#if defined(QT_QWS_IPAQ) +# ifdef QT_QWS_IPAQ_RAW + mousedev = QLatin1String("/dev/h3600_tsraw"); +# else + mousedev = QLatin1String("/dev/h3600_ts"); +# endif +#else + mousedev = QLatin1String("/dev/ts"); +#endif + } else { + mousedev = device; + } + if ((mouseFD = open(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { + qWarning("Cannot open %s (%s)", qPrintable(mousedev), strerror(errno)); + return; + } + + mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, + this); + connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); + waspressed=false; + mouseIdx = 0; +} + +QWSLinuxTPMouseHandlerPrivate::~QWSLinuxTPMouseHandlerPrivate() +{ + if (mouseFD >= 0) + close(mouseFD); +} + +void QWSLinuxTPMouseHandlerPrivate::suspend() +{ + if (mouseNotifier) + mouseNotifier->setEnabled(false); +} + +void QWSLinuxTPMouseHandlerPrivate::resume() +{ + mouseIdx=0; + currSample=0; + lastSample=0; + numSamples=0; + skipCount=0; + if (mouseNotifier) + mouseNotifier->setEnabled(true); +} + + +void QWSLinuxTPMouseHandlerPrivate::readMouseData() +{ + if(!qt_screen) + return; + + int n; + do { + n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); + if (n > 0) + mouseIdx += n; + } while (n > 0 && mouseIdx < mouseBufSize); + + //qDebug("readMouseData()"); + + TS_EVENT *data; + int idx = 0; + + // perhaps we shouldn't be reading EVERY SAMPLE. + while (mouseIdx-idx >= (int)sizeof(TS_EVENT)) { + uchar *mb = mouseBuf+idx; + data = (TS_EVENT *) mb; + + if(data->pressure >= QT_QWS_TP_PRESSURE_THRESHOLD) { +#ifdef QT_QWS_SHARP + samples[currSample] = QPoint(1000 - data->x, data->y); +#else + samples[currSample] = QPoint(data->x, data->y); +#endif + numSamples++; + if (numSamples >= QT_QWS_TP_MINIMUM_SAMPLES) { + int sampleCount = qMin(numSamples + 1,samples.count()); + + // average the rest + QPoint mousePos = QPoint(0, 0); + QPoint totalMousePos = oldTotalMousePos; + totalMousePos += samples[currSample]; + if(numSamples >= samples.count()) + totalMousePos -= samples[lastSample]; + + mousePos = totalMousePos / (sampleCount - 1); +#if defined(QT_QWS_SCREEN_COORDINATES) + mousePos = handler->transform(mousePos); +#endif + if(!waspressed) + oldmouse = mousePos; + QPoint dp = mousePos - oldmouse; + int dxSqr = dp.x() * dp.x(); + int dySqr = dp.y() * dp.y(); + if (dxSqr + dySqr < (QT_QWS_TP_MOVE_LIMIT * QT_QWS_TP_MOVE_LIMIT)) { + if (waspressed) { + if ((dxSqr + dySqr > (QT_QWS_TP_JITTER_LIMIT * QT_QWS_TP_JITTER_LIMIT)) || skipCount > 2) { + handler->mouseChanged(mousePos,Qt::LeftButton); + oldmouse = mousePos; + skipCount = 0; + } else { + skipCount++; + } + } else { + handler->mouseChanged(mousePos,Qt::LeftButton); + oldmouse=mousePos; + waspressed=true; + } + + // save recuring information + currSample++; + if (numSamples >= samples.count()) + lastSample++; + oldTotalMousePos = totalMousePos; + } else { + numSamples--; // don't use this sample, it was bad. + } + } else { + // build up the average + oldTotalMousePos += samples[currSample]; + currSample++; + } + if (currSample >= samples.count()) + currSample = 0; + if (lastSample >= samples.count()) + lastSample = 0; + } else { + currSample = 0; + lastSample = 0; + numSamples = 0; + skipCount = 0; + oldTotalMousePos = QPoint(0,0); + if (waspressed) { + handler->mouseChanged(oldmouse,0); + oldmouse = QPoint(-100, -100); + waspressed=false; + } + } + idx += sizeof(TS_EVENT); + } + + int surplus = mouseIdx - idx; + for (int i = 0; i < surplus; i++) + mouseBuf[i] = mouseBuf[idx+i]; + mouseIdx = surplus; +} + +QT_END_NAMESPACE + +#include "qmouselinuxtp_qws.moc" + +#endif //QT_NO_QWS_MOUSE_LINUXTP |