diff options
author | Ritt Konstantin <qnx@ics.com> | 2011-06-21 11:51:13 (GMT) |
---|---|---|
committer | Harald Fernengel <harald.fernengel@nokia.com> | 2011-06-21 12:05:46 (GMT) |
commit | 72e78283d69dc4570b51c02afab8a34d1e7385c2 (patch) | |
tree | ad622ed9bfc1f004b2769f6f91217c3643932a9b /src/gui/embedded | |
parent | 47b8e218aaa50714871a789ce257c0845d04b219 (diff) | |
download | Qt-72e78283d69dc4570b51c02afab8a34d1e7385c2.zip Qt-72e78283d69dc4570b51c02afab8a34d1e7385c2.tar.gz Qt-72e78283d69dc4570b51c02afab8a34d1e7385c2.tar.bz2 |
massive improvements for the QNX mouse driver
add support for the input devices with an absolute positioning;
decrease lagging on slow machines by queueing more mouse events than just 10 of them;
fix an issue with losing the button press state between subsequent loops (ie long drag'n'drop)
Merge-request: 1259
Reviewed-by: Harald Fernengel <harald.fernengel@nokia.com>
Diffstat (limited to 'src/gui/embedded')
-rw-r--r-- | src/gui/embedded/qmouselinuxinput_qws.cpp | 18 | ||||
-rw-r--r-- | src/gui/embedded/qmouseqnx_qws.cpp | 96 | ||||
-rw-r--r-- | src/gui/embedded/qmouseqnx_qws.h | 2 |
3 files changed, 69 insertions, 47 deletions
diff --git a/src/gui/embedded/qmouselinuxinput_qws.cpp b/src/gui/embedded/qmouselinuxinput_qws.cpp index efcf6d4..19a9a99 100644 --- a/src/gui/embedded/qmouselinuxinput_qws.cpp +++ b/src/gui/embedded/qmouselinuxinput_qws.cpp @@ -135,19 +135,21 @@ void QWSLinuxInputMousePrivate::readMouseData() int n = 0; forever { - n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n); - - if (n == 0) { + int bytesRead = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n); + if (bytesRead == 0) { qWarning("Got EOF from the input device."); return; - } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { - qWarning("Could not read from input device: %s", strerror(errno)); - return; - } else if (n % sizeof(buffer[0]) == 0) { + } + if (bytesRead == -1) { + if (errno != EAGAIN) + qWarning("Could not read from input device: %s", strerror(errno)); break; } - } + n += bytesRead; + if (n % sizeof(buffer[0]) == 0) + break; + } n /= sizeof(buffer[0]); for (int i = 0; i < n; ++i) { diff --git a/src/gui/embedded/qmouseqnx_qws.cpp b/src/gui/embedded/qmouseqnx_qws.cpp index a9647c0..d0b892e 100644 --- a/src/gui/embedded/qmouseqnx_qws.cpp +++ b/src/gui/embedded/qmouseqnx_qws.cpp @@ -39,14 +39,13 @@ ** ****************************************************************************/ -#include "qplatformdefs.h" #include "qmouseqnx_qws.h" +#include "qplatformdefs.h" #include "qsocketnotifier.h" -#include "qdebug.h" +#include "private/qcore_unix_p.h" #include <sys/dcmd_input.h> - #include <errno.h> QT_BEGIN_NAMESPACE @@ -92,22 +91,28 @@ QT_BEGIN_NAMESPACE \sa QMouseDriverFactory */ -QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device) +QQnxMouseHandler::QQnxMouseHandler(const QString & driver, const QString &device) + : QObject(), QWSMouseHandler(driver, device), mouseButtons(Qt::NoButton) { // open the mouse device with O_NONBLOCK so reading won't block when there's no data mouseFD = QT_OPEN(device.isEmpty() ? "/dev/devi/mouse0" : device.toLatin1().constData(), - QT_OPEN_RDONLY | O_NONBLOCK); + QT_OPEN_RDONLY | O_NONBLOCK); if (mouseFD == -1) { qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device"); - return; + } else { + struct _pointer_info data; + if (devctl(mouseFD, _POINTERGETINFO, &data, sizeof(data), NULL) == EOK) + absolutePositioning = (data.flags & _POINTER_FLAG_ABSOLUTE); + else + absolutePositioning = !device.isEmpty() && device.contains(QLatin1String("touch")); + + // register a socket notifier on the file descriptor so we'll wake up whenever + // there's a mouse move waiting for us. + mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); + connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated())); + + qDebug("QQnxMouseHandler: connected."); } - - // register a socket notifier on the file descriptor so we'll wake up whenever - // there's a mouse move waiting for us. - mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); - connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated())); - - qDebug() << "QQnxMouseHandler: connected."; } /*! @@ -115,7 +120,8 @@ QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &de */ QQnxMouseHandler::~QQnxMouseHandler() { - QT_CLOSE(mouseFD); + if (mouseFD != -1) + QT_CLOSE(mouseFD); } /*! \reimp */ @@ -140,39 +146,45 @@ void QQnxMouseHandler::suspend() */ void QQnxMouseHandler::socketActivated() { + QPoint queuedPos = mousePos; + // _mouse_packet is a QNX structure. devi-hid is nice enough to translate // the raw byte data from mouse devices into generic format for us. - _mouse_packet packet; + struct _mouse_packet buffer[32]; + int n = 0; - int iteration = 0; - - // read mouse events in batches of 10. Since we're getting quite a lot - // of mouse events, it's better to do them in batches than to return to the - // event loop every time. - do { - int bytesRead = QT_READ(mouseFD, &packet, sizeof(packet)); + forever { + int bytesRead = QT_READ(mouseFD, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n); if (bytesRead == -1) { // EAGAIN means that there are no more mouse events to read if (errno != EAGAIN) - qErrnoWarning(errno, "QQnxMouseHandler: Unable to read from socket"); - return; + qErrnoWarning(errno, "QQnxMouseHandler: Could not read from input device"); + break; } - // bytes read should always be equal to the size of a packet. - Q_ASSERT(bytesRead == sizeof(packet)); + n += bytesRead; + if (n % sizeof(buffer[0]) == 0) + break; + } + n /= sizeof(buffer[0]); - // translate the coordinates from the QNX data structure to Qt coordinates - // note the swapped y axis - QPoint pos = mousePos; - pos += QPoint(packet.dx, -packet.dy); + for (int i = 0; i < n; ++i) { + const struct _mouse_packet &packet = buffer[i]; - // QNX only tells us relative mouse movements, not absolute ones, so limit the - // cursor position manually to the screen - limitToScreen(pos); + // translate the coordinates from the QNX data structure to the Qt coordinates + if (absolutePositioning) { + queuedPos = QPoint(packet.dx, packet.dy); + } else { + // note the swapped y axis + queuedPos += QPoint(packet.dx, -packet.dy); + + // QNX only tells us relative mouse movements, not absolute ones, so + // limit the cursor position manually to the screen + limitToScreen(queuedPos); + } // translate the QNX mouse button bitmask to Qt buttons int buttons = Qt::NoButton; - if (packet.hdr.buttons & _POINTER_BUTTON_LEFT) buttons |= Qt::LeftButton; if (packet.hdr.buttons & _POINTER_BUTTON_MIDDLE) @@ -180,11 +192,17 @@ void QQnxMouseHandler::socketActivated() if (packet.hdr.buttons & _POINTER_BUTTON_RIGHT) buttons |= Qt::RightButton; - // call mouseChanged() - this does all the magic to actually move the on-screen - // mouse cursor. - mouseChanged(pos, buttons, 0); - } while (++iteration < 11); + if (buttons != mouseButtons) { + // send the MouseEvent to avoid missing any clicks + mouseChanged(queuedPos, buttons, 0); + // mousePos updated by the mouseChanged() + queuedPos = mousePos; + mouseButtons = buttons; + } + } + + if (queuedPos != mousePos) + mouseChanged(queuedPos, mouseButtons, 0); } QT_END_NAMESPACE - diff --git a/src/gui/embedded/qmouseqnx_qws.h b/src/gui/embedded/qmouseqnx_qws.h index 2a5eef2..54deaf3 100644 --- a/src/gui/embedded/qmouseqnx_qws.h +++ b/src/gui/embedded/qmouseqnx_qws.h @@ -70,6 +70,8 @@ private Q_SLOTS: private: QSocketNotifier *mouseNotifier; int mouseFD; + int mouseButtons; + bool absolutePositioning; }; QT_END_NAMESPACE |