diff options
Diffstat (limited to 'src/gui/embedded/qmouse_qws.cpp')
-rw-r--r-- | src/gui/embedded/qmouse_qws.cpp | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/src/gui/embedded/qmouse_qws.cpp b/src/gui/embedded/qmouse_qws.cpp deleted file mode 100644 index f982988d58..0000000000 --- a/src/gui/embedded/qmouse_qws.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmouse_qws.h" -#include "qwindowsystem_qws.h" -#include "qscreen_qws.h" -#include "qapplication.h" -#include "qtextstream.h" -#include "qfile.h" -#include "qdebug.h" -#include "qscreen_qws.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QWSPointerCalibrationData - \ingroup qws - - \brief The QWSPointerCalibrationData class is a container for - mouse calibration data in Qt for Embedded Linux. - - Note that this class is only available in \l{Qt for Embedded Linux}. - - QWSPointerCalibrationData stores device and screen coordinates in - the devPoints and screenPoints variables, respectively. - - A calibration program should create a QWSPointerCalibrationData - object, fill the devPoints and screenPoints variables with its - device and screen coordinates, and pass the object to the mouse - driver using the QWSMouseHandler::calibrate() function. - - \sa QWSCalibratedMouseHandler, {Mouse Calibration Example} -*/ - -/*! - \variable QWSPointerCalibrationData::devPoints - \brief the raw device coordinates for each value of the Location enum. -*/ - -/*! - \variable QWSPointerCalibrationData::screenPoints - \brief the logical screen coordinates for each value of the Location enum. -*/ - -/*! - \enum QWSPointerCalibrationData::Location - - This enum describes the various logical positions that can be - specified by the devPoints and screenPoints variables. - - \value TopLeft Index of the top left corner of the screen. - \value BottomLeft Index of the bottom left corner of the screen. - \value BottomRight Index of the bottom right corner of the screen. - \value TopRight Index of the top right corner of the screen. - \value Center Index of the center of the screen. - \value LastLocation Last index in the pointer arrays. -*/ - -class QWSMouseHandlerPrivate -{ -public: - QWSMouseHandlerPrivate() : screen(qt_screen) {} - - const QScreen *screen; -}; - -/*! - \class QWSMouseHandler - \ingroup qws - - \brief The QWSMouseHandler class is a base class for mouse drivers in - Qt for Embedded Linux. - - Note that this class is only available in \l{Qt for Embedded Linux}. - - \l{Qt for Embedded Linux} provides ready-made drivers for several mouse - protocols, see the \l{Qt for Embedded Linux Pointer Handling}{pointer - handling} documentation for details. Custom mouse drivers can be - implemented by subclassing the QWSMouseHandler class and creating - a mouse driver plugin (derived from QMouseDriverPlugin). - The default implementation of the QMouseDriverFactory class - will automatically detect the plugin, and load the driver into the - server application at run-time using Qt's \l {How to Create Qt - Plugins}{plugin system}. - - The mouse driver receives mouse events from the system device and - encapsulates each event with an instance of the QWSEvent class - which it then passes to the server application (the server is - responsible for propagating the event to the appropriate - client). To receive mouse events, a QWSMouseHandler object will - usually create a QSocketNotifier object for the given device. The - QSocketNotifier class provides support for monitoring activity on - a file descriptor. When the socket notifier receives data, it will - call the mouse driver's mouseChanged() function to send the event - to the \l{Qt for Embedded Linux} server application for relaying to - clients. - - If you are creating a driver for a device that needs calibration - or noise reduction, such as a touchscreen, use the - QWSCalibratedMouseHandler subclass instead to take advantage of - the calibrate() and clearCalibration() functions. The \l - {qws/mousecalibration}{Mouse Calibration} - demonstrates how to write a simple program using the mechanisms - provided by the QWSMouseHandler class to calibrate a mouse driver. - - Note that when deriving from the QWSMouseHandler class, the - resume() and suspend() functions must be reimplemented to control - the flow of mouse input, i.e., the default implementation does - nothing. Reimplementations of these functions typically call the - QSocketNotifier::setEnabled() function to enable or disable the - socket notifier, respectively. - - In addition, QWSMouseHandler provides the setScreen() function - that allows you to specify a screen for your mouse driver and the - limitToScreen() function that ensures that a given position is - within this screen's boundaries (changing the position if - necessary). Finally, QWSMouseHandler provides the pos() function - returning the current mouse position. - - \sa QMouseDriverPlugin, QMouseDriverFactory, {Qt for Embedded Linux Pointer - Handling} -*/ - - -/*! - \fn void QWSMouseHandler::suspend() - - Implement this function to suspend reading and handling of mouse - events, e.g., call the QSocketNotifier::setEnabled() function to - disable the socket notifier. - - \sa resume() -*/ - -/*! - \fn void QWSMouseHandler::resume() - - Implement this function to resume reading and handling mouse - events, e.g., call the QSocketNotifier::setEnabled() function to - enable the socket notifier. - - \sa suspend() -*/ - -/*! - \fn const QPoint &QWSMouseHandler::pos() const - - Returns the current mouse position. - - \sa mouseChanged(), limitToScreen() -*/ - -/*! - Constructs a mouse driver. The \a driver and \a device arguments - are passed by the QWS_MOUSE_PROTO environment variable. - - Call the QWSServer::setMouseHandler() function to make the newly - created mouse driver, the primary driver. Note that the primary - driver is controlled by the system, i.e., the system will delete - it upon exit. -*/ -QWSMouseHandler::QWSMouseHandler(const QString &, const QString &) - : mousePos(QWSServer::mousePosition), d_ptr(new QWSMouseHandlerPrivate) -{ -} - -/*! - Destroys this mouse driver. - - Do not call this function if this driver is the primary mouse - driver, i.e., if QWSServer::setMouseHandler() function has been - called passing this driver as argument. The primary mouse - driver is deleted by the system. -*/ -QWSMouseHandler::~QWSMouseHandler() -{ - delete d_ptr; -} - -/*! - Ensures that the given \a position is within the screen's - boundaries, changing the \a position if necessary. - - \sa pos(), setScreen() -*/ - -void QWSMouseHandler::limitToScreen(QPoint &position) -{ - position.setX(qMin(d_ptr->screen->deviceWidth() - 1, qMax(0, position.x()))); - position.setY(qMin(d_ptr->screen->deviceHeight() - 1, qMax(0, position.y()))); -} - -/*! - \since 4.2 - - Sets the screen for this mouse driver to be the given \a screen. - - \sa limitToScreen() -*/ -void QWSMouseHandler::setScreen(const QScreen *screen) -{ - d_ptr->screen = (screen ? screen : qt_screen); -} - -/*! - Notifies the system of a new mouse event. - - This function updates the current mouse position and sends the - event to the \l{Qt for Embedded Linux} server application for - delivery to the correct widget. Note that a custom mouse driver must call - this function whenever it wants to deliver a new mouse event. - - The given \a position is the global position of the mouse cursor. - The \a state parameter is a bitmask of the Qt::MouseButton enum's - values, indicating which mouse buttons are pressed. The \a wheel - parameter is the delta value of the mouse wheel as returned by - QWheelEvent::delta(). - - \sa pos() -*/ -void QWSMouseHandler::mouseChanged(const QPoint &position, int state, int wheel) -{ - mousePos = position + d_ptr->screen->offset(); - QWSServer::sendMouseEvent(mousePos, state, wheel); -} - -/*! - \fn QWSMouseHandler::clearCalibration() - - This virtual function allows subclasses of QWSMouseHandler to - clear the calibration information. Note that the default - implementation does nothing. - - \sa QWSCalibratedMouseHandler::clearCalibration(), calibrate() -*/ - -/*! - \fn QWSMouseHandler::calibrate(const QWSPointerCalibrationData *data) - - This virtual function allows subclasses of QWSMouseHandler to set - the calibration information passed in the given \a data. Note that - the default implementation does nothing. - - \sa QWSCalibratedMouseHandler::calibrate(), clearCalibration() -*/ - -/*! \fn QWSMouseHandler::getCalibration(QWSPointerCalibrationData *data) const - This virtual function allows subclasses of QWSMouseHandler - to fill in the device coordinates in \a data with values - that correspond to screen coordinates that are already in - \a data. Note that the default implementation does nothing. - */ - -/*! - \class QWSCalibratedMouseHandler - \ingroup qws - - \brief The QWSCalibratedMouseHandler class provides mouse - calibration and noise reduction in Qt for Embedded Linux. - - Note that this class is only available in \l{Qt for Embedded Linux}. - - \l{Qt for Embedded Linux} provides ready-made drivers for several mouse - protocols, see the \l{Qt for Embedded Linux Pointer Handling}{pointer - handling} documentation for details. In general, custom mouse - drivers can be implemented by subclassing the QWSMouseHandler - class. But when the system device does not have a fixed mapping - between device and screen coordinates and/or produces noisy events - (e.g., a touchscreen), you should derive from the - QWSCalibratedMouseHandler class instead to take advantage of its - calibration functionality. As always, you must also create a mouse - driver plugin (derived from QMouseDriverPlugin); - the implementation of the QMouseDriverFactory class will then - automatically detect the plugin, and load the driver into the - server application at run-time using Qt's - \l{How to Create Qt Plugins}{plugin system}. - - QWSCalibratedMouseHandler provides an implementation of the - calibrate() function to update the calibration parameters based on - coordinate mapping of the given calibration data. The calibration - data is represented by an QWSPointerCalibrationData object. The - linear transformation between device coordinates and screen - coordinates is performed by calling the transform() function - explicitly on the points passed to the - QWSMouseHandler::mouseChanged() function. Use the - clearCalibration() function to make the mouse driver return mouse - events in raw device coordinates and not in screen coordinates. - - The calibration parameters are recalculated whenever calibrate() - is called, and they can be stored using the writeCalibration() - function. Previously written parameters can be retrieved at any - time using the readCalibration() function (calibration parameters - are always read when the class is instantiated). Note that the - calibration parameters is written to and read from the file - currently specified by the POINTERCAL_FILE environment variable; - the default file is \c /etc/pointercal. - - To achieve noise reduction, QWSCalibratedMouseHandler provides the - sendFiltered() function. Use this function instead of - mouseChanged() whenever a mouse event occurs. The filter's size - can be manipulated using the setFilterSize() function. - - \sa QWSMouseHandler, QWSPointerCalibrationData, - {Mouse Calibration Example} -*/ - - -/*! - \internal - */ - -QWSCalibratedMouseHandler::QWSCalibratedMouseHandler(const QString &, const QString &) - : samples(5), currSample(0), numSamples(0) -{ - clearCalibration(); - readCalibration(); -} - -/*! - Fills \a cd with the device coordinates corresponding to the given - screen coordinates. - - \internal -*/ -void QWSCalibratedMouseHandler::getCalibration(QWSPointerCalibrationData *cd) const -{ - const qint64 scale = qint64(a) * qint64(e) - qint64(b) * qint64(d); - const qint64 xOff = qint64(b) * qint64(f) - qint64(c) * qint64(e); - const qint64 yOff = qint64(c) * qint64(d) - qint64(a) * qint64(f); - for (int i = 0; i <= QWSPointerCalibrationData::LastLocation; ++i) { - const qint64 sX = cd->screenPoints[i].x(); - const qint64 sY = cd->screenPoints[i].y(); - const qint64 dX = (s*(e*sX - b*sY) + xOff) / scale; - const qint64 dY = (s*(a*sY - d*sX) + yOff) / scale; - cd->devPoints[i] = QPoint(dX, dY); - } -} - -/*! - Clears the current calibration, i.e., makes the mouse - driver return mouse events in raw device coordinates instead of - screen coordinates. - - \sa calibrate() -*/ -void QWSCalibratedMouseHandler::clearCalibration() -{ - a = 1; - b = 0; - c = 0; - d = 0; - e = 1; - f = 0; - s = 1; -} - - -/*! - Saves the current calibration parameters in \c /etc/pointercal - (separated by whitespace and in alphabetical order). - - You can override the default \c /etc/pointercal by specifying - another file using the POINTERCAL_FILE environment variable. - - \sa readCalibration() -*/ -void QWSCalibratedMouseHandler::writeCalibration() -{ - QString calFile; - calFile = QString::fromLocal8Bit(qgetenv("POINTERCAL_FILE")); - if (calFile.isEmpty()) - calFile = QLatin1String("/etc/pointercal"); - -#ifndef QT_NO_TEXTSTREAM - QFile file(calFile); - if (file.open(QIODevice::WriteOnly)) { - QTextStream t(&file); - t << a << ' ' << b << ' ' << c << ' '; - t << d << ' ' << e << ' ' << f << ' ' << s << endl; - } else -#endif - { - qCritical("QWSCalibratedMouseHandler::writeCalibration: " - "Could not save calibration into %s", qPrintable(calFile)); - } -} - -/*! - Reads previously written calibration parameters which are stored - in \c /etc/pointercal (separated by whitespace and in alphabetical - order). - - You can override the default \c /etc/pointercal by specifying - another file using the POINTERCAL_FILE environment variable. - - - \sa writeCalibration() -*/ -void QWSCalibratedMouseHandler::readCalibration() -{ - QString calFile = QString::fromLocal8Bit(qgetenv("POINTERCAL_FILE")); - if (calFile.isEmpty()) - calFile = QLatin1String("/etc/pointercal"); - -#ifndef QT_NO_TEXTSTREAM - QFile file(calFile); - if (file.open(QIODevice::ReadOnly)) { - QTextStream t(&file); - t >> a >> b >> c >> d >> e >> f >> s; - if (s == 0 || t.status() != QTextStream::Ok) { - qCritical("Corrupt calibration data"); - clearCalibration(); - } - } else -#endif - { - qDebug() << "Could not read calibration:" <<calFile; - } -} - -static int ilog2(quint32 n) -{ - int result = 0; - - if (n & 0xffff0000) { - n >>= 16; - result += 16; - } - if (n & 0xff00) { - n >>= 8; - result += 8;} - if (n & 0xf0) { - n >>= 4; - result += 4; - } - if (n & 0xc) { - n >>= 2; - result += 2; - } - if (n & 0x2) - result += 1; - - return result; -} - -/*! - Updates the calibration parameters based on coordinate mapping of - the given \a data. - - Create an instance of the QWSPointerCalibrationData class, fill in - the device and screen coordinates and pass that object to the mouse - driver using this function. - - \sa clearCalibration(), transform() -*/ -void QWSCalibratedMouseHandler::calibrate(const QWSPointerCalibrationData *data) -{ - // Algorithm derived from - // "How To Calibrate Touch Screens" by Carlos E. Vidales, - // printed in Embedded Systems Programming, Vol. 15 no 6, June 2002 - // URL: http://www.embedded.com/showArticle.jhtml?articleID=9900629 - - const QPoint pd0 = data->devPoints[QWSPointerCalibrationData::TopLeft]; - const QPoint pd1 = data->devPoints[QWSPointerCalibrationData::TopRight]; - const QPoint pd2 = data->devPoints[QWSPointerCalibrationData::BottomRight]; - const QPoint p0 = data->screenPoints[QWSPointerCalibrationData::TopLeft]; - const QPoint p1 = data->screenPoints[QWSPointerCalibrationData::TopRight]; - const QPoint p2 = data->screenPoints[QWSPointerCalibrationData::BottomRight]; - - const qint64 xd0 = pd0.x(); - const qint64 xd1 = pd1.x(); - const qint64 xd2 = pd2.x(); - const qint64 yd0 = pd0.y(); - const qint64 yd1 = pd1.y(); - const qint64 yd2 = pd2.y(); - const qint64 x0 = p0.x(); - const qint64 x1 = p1.x(); - const qint64 x2 = p2.x(); - const qint64 y0 = p0.y(); - const qint64 y1 = p1.y(); - const qint64 y2 = p2.y(); - - qint64 scale = ((xd0 - xd2)*(yd1 - yd2) - (xd1 - xd2)*(yd0 - yd2)); - int shift = 0; - qint64 absScale = qAbs(scale); - // use maximum 16 bit precision to reduce risk of integer overflow - if (absScale > (1 << 16)) { - shift = ilog2(absScale >> 16) + 1; - scale >>= shift; - } - - s = scale; - a = ((x0 - x2)*(yd1 - yd2) - (x1 - x2)*(yd0 - yd2)) >> shift; - b = ((xd0 - xd2)*(x1 - x2) - (x0 - x2)*(xd1 - xd2)) >> shift; - c = (yd0*(xd2*x1 - xd1*x2) + yd1*(xd0*x2 - xd2*x0) + yd2*(xd1*x0 - xd0*x1)) >> shift; - d = ((y0 - y2)*(yd1 - yd2) - (y1 - y2)*(yd0 - yd2)) >> shift; - e = ((xd0 - xd2)*(y1 - y2) - (y0 - y2)*(xd1 - xd2)) >> shift; - f = (yd0*(xd2*y1 - xd1*y2) + yd1*(xd0*y2 - xd2*y0) + yd2*(xd1*y0 - xd0*y1)) >> shift; - - writeCalibration(); -} - -/*! - Transforms the given \a position from device coordinates to screen - coordinates, and returns the transformed position. - - This function is typically called explicitly on the points passed - to the QWSMouseHandler::mouseChanged() function. - - This implementation is a linear transformation using 7 parameters - (\c a, \c b, \c c, \c d, \c e, \c f and \c s) to transform the - device coordinates (\c Xd, \c Yd) into screen coordinates (\c Xs, - \c Ys) using the following equations: - - \snippet doc/src/snippets/code/src_gui_embedded_qmouse_qws.cpp 0 - - \sa mouseChanged() -*/ -QPoint QWSCalibratedMouseHandler::transform(const QPoint &position) -{ - QPoint tp; - - tp.setX((a * position.x() + b * position.y() + c) / s); - tp.setY((d * position.x() + e * position.y() + f) / s); - - return tp; -} - -/*! - Sets the size of the filter used in noise reduction to the given - \a size. - - The sendFiltered() function reduces noice by calculating an - average position from a collection of mouse event positions. The - filter size determines the number of positions that forms the - basis for these calculations. - - \sa sendFiltered() -*/ -void QWSCalibratedMouseHandler::setFilterSize(int size) -{ - samples.resize(qMax(1, size)); - numSamples = 0; - currSample = 0; -} - -/*! - \fn bool QWSCalibratedMouseHandler::sendFiltered(const QPoint &position, int state) - - Notifies the system of a new mouse event \e after applying a noise - reduction filter. Returns true if the filtering process is - successful; otherwise returns false. Note that if the filtering - process failes, the system is not notified about the event. - - The given \a position is the global position of the mouse. The \a - state parameter is a bitmask of the Qt::MouseButton enum's values - indicating which mouse buttons are pressed. - - The noice is reduced by calculating an average position from a - collection of mouse event positions and then calling the - mouseChanged() function with the new position. The number of - positions that is used is determined by the filter size. - - \sa mouseChanged(), setFilterSize() -*/ -bool QWSCalibratedMouseHandler::sendFiltered(const QPoint &position, int button) -{ - if (!button) { - if (numSamples >= samples.count()) - mouseChanged(transform(position), 0); - currSample = 0; - numSamples = 0; - return true; - } - - bool sent = false; - samples[currSample] = position; - numSamples++; - if (numSamples >= samples.count()) { - - int ignore = -1; - if (samples.count() > 2) { // throw away the "worst" sample - int maxd = 0; - for (int i = 0; i < samples.count(); i++) { - int d = (mousePos - samples[i]).manhattanLength(); - if (d > maxd) { - maxd = d; - ignore = i; - } - } - } - - // average the rest - QPoint pos(0, 0); - int numAveraged = 0; - for (int i = 0; i < samples.count(); i++) { - if (ignore == i) - continue; - pos += samples[i]; - ++numAveraged; - } - if (numAveraged) - pos /= numAveraged; - - mouseChanged(transform(pos), button); - sent = true; - } - currSample++; - if (currSample >= samples.count()) - currSample = 0; - - return sent; -} - -QT_END_NAMESPACE |