diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-08-11 07:39:26 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-09-23 13:10:40 (GMT) |
commit | 48d0f84958fdc2dcffab75f33842a9dbc3d4d7b1 (patch) | |
tree | 86bff59c6dcc57dc0ca29ffd0effaa6de4fb55ae /src/gui/kernel | |
parent | 5e11ae8dc8594f648105f8a62baf1b82c909fd2a (diff) | |
download | Qt-48d0f84958fdc2dcffab75f33842a9dbc3d4d7b1.zip Qt-48d0f84958fdc2dcffab75f33842a9dbc3d4d7b1.tar.gz Qt-48d0f84958fdc2dcffab75f33842a9dbc3d4d7b1.tar.bz2 |
Implement advanced pointer handling on S60
Since we only get one pointer event at a time, we need to keep a list of
all known touch points in QApplicationPrivate (otherwise the QTouchEvent
won't contain enough points). The QApplication machinery can handle
having inactive touch-points in the list, so at the moment we don't
clear the list.
We treat PointerNumber zero as the primary touch point, and only send
regular mouse events for that pointer, never for the others.
Reviewed-by: Jason Barron
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 76 | ||||
-rw-r--r-- | src/gui/kernel/qt_s60_p.h | 1 |
3 files changed, 80 insertions, 2 deletions
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 707caaa..aec21fd 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -576,6 +576,11 @@ public: void _q_readRX71MultiTouchEvents(); #endif +#if defined(Q_WS_S60) + int maxTouchPressure; + QList<QTouchEvent::TouchPoint> appAllTouchPoints; +#endif + private: #ifdef Q_WS_QWS QMap<const QScreen*, QRect> maxWindowRects; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index a5d07fd..58aca83 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -368,8 +368,77 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons m_previousEventLongTap = true; } +void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event) +{ + QApplicationPrivate *d = QApplicationPrivate::instance(); + + QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget); + + while (d->appAllTouchPoints.count() <= event->PointerNumber()) + d->appAllTouchPoints.append(QTouchEvent::TouchPoint(d->appAllTouchPoints.count())); + + Qt::TouchPointStates allStates = 0; + for (int i = 0; i < d->appAllTouchPoints.count(); ++i) { + QTouchEvent::TouchPoint &touchPoint = d->appAllTouchPoints[i]; + + if (touchPoint.id() == event->PointerNumber()) { + Qt::TouchPointStates state; + switch (event->iType) { + case TPointerEvent::EButton1Down: + case TPointerEvent::EEnterHighPressure: + state = Qt::TouchPointPressed; + break; + case TPointerEvent::EButton1Up: + case TPointerEvent::EExitCloseProximity: + state = Qt::TouchPointReleased; + break; + case TPointerEvent::EDrag: + state = Qt::TouchPointMoved; + break; + default: + // how likely is this to happen? + state = Qt::TouchPointStationary; + break; + } + if (event->PointerNumber() == 0) + state |= Qt::TouchPointPrimary; + touchPoint.setState(state); + + QPointF screenPos = QPointF(event->iPosition.iX, event->iPosition.iY); + touchPoint.setScreenPos(screenPos); + touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), + screenPos.y() / screenGeometry.height())); + + touchPoint.setPressure(event->Pressure() / qreal(d->maxTouchPressure)); + } else if (touchPoint.state() != Qt::TouchPointReleased) { + // all other active touch points should be marked as stationary + touchPoint.setState(Qt::TouchPointStationary); + } + + allStates |= touchPoint.state(); + } + + if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) { + // all touch points released + d->appAllTouchPoints.clear(); + } + + QApplicationPrivate::translateRawTouchEvent(qwidget, + QTouchEvent::TouchScreen, + d->appAllTouchPoints); +} + void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) { + if (pEvent.IsAdvancedPointerEvent()) { + const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent(); + translateAdvancedPointerEvent(advancedPointerEvent); + if (advancedPointerEvent->PointerNumber() != 0) { + // only send mouse events for the first touch point + return; + } + } + m_longTapDetector->PointerEventL(pEvent); QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent)); } @@ -1441,9 +1510,12 @@ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) } } - void QApplicationPrivate::initializeMultitouch_sys() -{ } +{ + if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone) + maxTouchPressure = KMaxTInt; +} + void QApplicationPrivate::cleanupMultitouch_sys() { } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index aa39f9d..9939f2c 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -167,6 +167,7 @@ private: TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); + void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); private: QWidget *qwidget; |