diff options
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 150 | ||||
-rw-r--r-- | src/gui/kernel/qt_s60_p.h | 19 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_s60.cpp | 6 | ||||
-rw-r--r-- | tests/benchmarks/corelib/tools/qstring/main.cpp | 4 |
4 files changed, 138 insertions, 41 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index a9634d8..46b16cb 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -92,6 +92,10 @@ #include <graphics/wstfxconst.h> #endif +#ifdef COE_GROUPED_POINTER_EVENT_VERSION +#include <coeeventdata.h> +#endif + QT_BEGIN_NAMESPACE // Goom Events through Window Server @@ -677,71 +681,121 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons } #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER +#ifdef COE_GROUPED_POINTER_EVENT_VERSION +void QSymbianControl::translateMultiEventPointerEvent(const CCoeEventData &eventData ) +{ + TUint count = eventData.Count(); + QVector<TouchEventParams> touches; + touches.reserve(count); + for (int i = 0; i < count; i++) { + const TPointerEvent *pointerEvent = eventData.Pointer(i); + const TAdvancedPointerEvent *advEvent = pointerEvent->AdvancedPointerEvent(); + if (advEvent) + touches.push_back(TouchEventFromAdvancedPointerEvent(advEvent)); + } + if (touches.size()) + processTouchEvents(touches); +} +#endif + void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event) { + processTouchEvents(QVector<TouchEventParams>(1, TouchEventFromAdvancedPointerEvent(event))); +} + +QSymbianControl::TouchEventParams QSymbianControl::TouchEventFromAdvancedPointerEvent(const TAdvancedPointerEvent *event) +{ QApplicationPrivate *d = QApplicationPrivate::instance(); QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition)); qreal pressure; - if(d->pressureSupported + if (d->pressureSupported && event->Pressure() > 0) //workaround for misconfigured HAL pressure = event->Pressure() / qreal(d->maxTouchPressure); else pressure = qreal(1.0); - processTouchEvent(event->PointerNumber(), event->iType, screenPos, pressure); + return TouchEventParams(event->PointerNumber(), event->iType, screenPos, pressure); } #endif -void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure) +QSymbianControl::TouchEventParams::TouchEventParams() +{} + +QSymbianControl::TouchEventParams::TouchEventParams(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure) + : pointerNumber(pointerNumber), + type(type), + screenPos(screenPos), + pressure(pressure) +{} + +void QSymbianControl::processTouchEvents(const QVector<TouchEventParams> &touches) { QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget); QApplicationPrivate *d = QApplicationPrivate::instance(); + // get the maximum pointer number + int numUpdates = touches.size(); + int maxPointerNumber = 0; + for (int i = 0; i < numUpdates; ++i) { + const TouchEventParams &touch = touches[i]; + maxPointerNumber = qMax(maxPointerNumber, touch.pointerNumber); + } + + // ensure there are sufficient touch events in the list, + // touch events will be indexed by pointerNumber QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints; - while (points.count() <= pointerNumber) + while (points.count() <= maxPointerNumber) points.append(QTouchEvent::TouchPoint(points.count())); - Qt::TouchPointStates allStates = 0; + // first set all active touch points to stationary for (int i = 0; i < points.count(); ++i) { QTouchEvent::TouchPoint &touchPoint = points[i]; + if (touchPoint.state() != Qt::TouchPointReleased) { + touchPoint.setState(Qt::TouchPointStationary); + } + } - if (touchPoint.id() == pointerNumber) { - Qt::TouchPointStates state; - switch (type) { - case TPointerEvent::EButton1Down: + // Add all info about moving or state changed touch points + for (int i = 0; i < numUpdates; ++i) { + const TouchEventParams &touch = touches[i]; + QTouchEvent::TouchPoint &touchPoint = points[touch.pointerNumber]; + Qt::TouchPointStates state; + switch (touch.type) { + case TPointerEvent::EButton1Down: #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER - case TPointerEvent::EEnterHighPressure: + case TPointerEvent::EEnterHighPressure: #endif - state = Qt::TouchPointPressed; - break; - case TPointerEvent::EButton1Up: + state = Qt::TouchPointPressed; + break; + case TPointerEvent::EButton1Up: #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER - case TPointerEvent::EExitCloseProximity: -#endif - state = Qt::TouchPointReleased; - break; - case TPointerEvent::EDrag: - state = Qt::TouchPointMoved; - break; - default: - // how likely is this to happen? - state = Qt::TouchPointStationary; - break; - } - if (pointerNumber == 0) - state |= Qt::TouchPointPrimary; - touchPoint.setState(state); + case TPointerEvent::EExitCloseProximity: +#endif + state = Qt::TouchPointReleased; + break; + case TPointerEvent::EDrag: + state = Qt::TouchPointMoved; + break; + default: + // how likely is this to happen? + state = Qt::TouchPointStationary; + break; + } + if (touch.pointerNumber == 0) + state |= Qt::TouchPointPrimary; + touchPoint.setState(state); - touchPoint.setScreenPos(screenPos); - touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), - screenPos.y() / screenGeometry.height())); + touchPoint.setScreenPos(touch.screenPos); + touchPoint.setNormalizedPos(QPointF(touch.screenPos.x() / screenGeometry.width(), + touch.screenPos.y() / screenGeometry.height())); - touchPoint.setPressure(pressure); - } else if (touchPoint.state() != Qt::TouchPointReleased) { - // all other active touch points should be marked as stationary - touchPoint.setState(Qt::TouchPointStationary); - } + touchPoint.setPressure(touch.pressure); + } + // check the resulting state of all touch points + Qt::TouchPointStates allStates = 0; + for (int i = 0; i < points.count(); ++i) { + QTouchEvent::TouchPoint &touchPoint = points[i]; allStates |= touchPoint.state(); } @@ -760,6 +814,28 @@ void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) { #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER +#ifdef COE_GROUPED_POINTER_EVENT_VERSION + if (pEvent.iType == TPointerEvent::EDataCCoeEventData) { + // only advanced pointers can be data type pointer events + const TAdvancedPointerEvent *advEvent = pEvent.AdvancedPointerEvent(); + if (!advEvent) + return; + const CCoeEventData& eventData = CCoeEventData::EventData(*advEvent); + if (eventData.Type() == CWsEventWithData::EPointerEvent) { + QT_TRYCATCH_LEAVING(translateMultiEventPointerEvent(eventData)); + // pointer 0 events and unnumbered events should also be handled as mouse events + for (int i=0; i<eventData.Count(); i++) { + const TPointerEvent *pointerEvent = eventData.Pointer(i); + const TAdvancedPointerEvent *advEvent = pointerEvent->AdvancedPointerEvent(); + if (!advEvent || advEvent->PointerNumber() == 0) { + m_longTapDetector->PointerEventL(*pointerEvent); + QT_TRYCATCH_LEAVING(HandlePointerEvent(*pointerEvent)); + } + } + return; + } + } +#endif if (pEvent.IsAdvancedPointerEvent()) { const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent(); translateAdvancedPointerEvent(advancedPointerEvent); @@ -833,7 +909,7 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) //Generate single touch event for S60 5.0 (has touchscreen, does not have advanced pointers) #ifndef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER if (S60->hasTouchscreen) { - processTouchEvent(0, pEvent.iType, QPointF(globalPos), 1.0); + processTouchEvents(QVector<TouchEventParams>(1, TouchEventParams(0, pEvent.iType, QPointF(globalPos), 1.0))); } #endif diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 5ad5b00..5b5d5ce 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -102,6 +102,10 @@ class QSymbianTypeFaceExtras; typedef QHash<QString, const QSymbianTypeFaceExtras *> QSymbianTypeFaceExtrasHash; typedef void (*QThreadLocalReleaseFunc)(); +#ifdef COE_GROUPED_POINTER_EVENT_VERSION +class CCoeEventData; +#endif + class Q_AUTOTEST_EXPORT QS60ThreadLocalData { public: @@ -308,10 +312,23 @@ private: const QPoint &globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers); - void processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure); + struct TouchEventParams + { + TouchEventParams(); + TouchEventParams(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure); + int pointerNumber; + TPointerEvent::TType type; + QPointF screenPos; + qreal pressure; + }; + void processTouchEvents(const QVector<TouchEventParams> &touches); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER +#ifdef COE_GROUPED_POINTER_EVENT_VERSION + void translateMultiEventPointerEvent(const CCoeEventData &eventData ); +#endif void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); + TouchEventParams TouchEventFromAdvancedPointerEvent(const TAdvancedPointerEvent *event); #endif bool isSplitViewWidget(QWidget *widget); bool hasFocusedAndVisibleChild(QWidget *parentWidget); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 396c306..a37c265 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1040,8 +1040,12 @@ void QWidgetPrivate::registerTouchWindow() RWindow *rwindow = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow()); QSymbianControl *window = static_cast<QSymbianControl *>(q->effectiveWinId()); //Enabling advanced pointer events for controls that already have active windows causes a panic. - if (!window->isControlActive()) + if (!window->isControlActive()) { rwindow->EnableAdvancedPointers(); +#ifdef COE_GROUPED_POINTER_EVENT_VERSION + qt_symbian_throwIfError(window->ConfigureEventData(CCoeControl::EEventDataAllowGroupedPointerEvents)); +#endif + } } #endif } diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp index 5b5f0f7..daefe12 100644 --- a/tests/benchmarks/corelib/tools/qstring/main.cpp +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp @@ -784,7 +784,7 @@ void tst_QString::equals2_data() const static void __attribute__((noinline)) equals2_selftest() { -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) const long pagesize = sysconf(_SC_PAGESIZE); void *page1, *page3; ushort *page2; @@ -1341,7 +1341,7 @@ void tst_QString::ucstrncmp() const }; static const int functionCount = sizeof func / sizeof func[0]; -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) const long pagesize = sysconf(_SC_PAGESIZE); void *page1, *page3; ushort *page2; |