summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication_s60.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication_s60.cpp')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp2715
1 files changed, 0 insertions, 2715 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
deleted file mode 100644
index f0739cdd9f..0000000000
--- a/src/gui/kernel/qapplication_s60.cpp
+++ /dev/null
@@ -1,2715 +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 "qapplication_p.h"
-#include "qsessionmanager.h"
-#include "qevent.h"
-#include "qsymbianevent.h"
-#include "qeventdispatcher_s60_p.h"
-#include "qwidget.h"
-#include "qdesktopwidget.h"
-#include "private/qbackingstore_p.h"
-#include "qt_s60_p.h"
-#include "private/qevent_p.h"
-#include "qstring.h"
-#include "qdebug.h"
-#include "qimage.h"
-#include "qcombobox.h"
-#include "private/qkeymapper_p.h"
-#include "private/qfont_p.h"
-#ifndef QT_NO_STYLE_S60
-#include "private/qs60style_p.h"
-#endif
-#include "private/qwindowsurface_s60_p.h"
-#include "qpaintengine.h"
-#include "private/qmenubar_p.h"
-#include "private/qsoftkeymanager_p.h"
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
-#include "private/qgraphicssystem_runtime_p.h"
-#endif
-
-#include "apgwgnam.h" // For CApaWindowGroupName
-#include <mdaaudiotoneplayer.h> // For CMdaAudioToneUtility
-
-#if defined(Q_OS_SYMBIAN)
-# include <private/qs60mainapplication_p.h>
-# include <centralrepository.h>
-# include "qs60mainappui.h"
-# include "qinputcontext.h"
-#endif
-
-#if defined(Q_WS_S60)
-# if !defined(QT_NO_IM)
-# include <private/qcoefepinputcontext_p.h>
-# endif
-#endif
-
-#include "private/qstylesheetstyle_p.h"
-
-#include <hal.h>
-#include <hal_data.h>
-
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
-#include <graphics/wstfxconst.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// Goom Events through Window Server
-static const int KGoomMemoryLowEvent = 0x10282DBF;
-static const int KGoomMemoryGoodEvent = 0x20026790;
-// Split view open/close events from AVKON
-static const int KSplitViewOpenEvent = 0x2001E2C0;
-static const int KSplitViewCloseEvent = 0x2001E2C1;
-
-#if defined(QT_DEBUG)
-static bool appNoGrab = false; // Grabbing enabled
-#endif
-static bool app_do_modal = false; // modal mode
-Q_GLOBAL_STATIC(QS60Data, qt_s60Data);
-
-extern bool qt_sendSpontaneousEvent(QObject*,QEvent*);
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
-
-QWidget *qt_button_down = 0; // widget got last button-down
-
-QSymbianControl *QSymbianControl::lastFocusedControl = 0;
-
-QS60Data* qGlobalS60Data()
-{
- return qt_s60Data();
-}
-
-#ifdef Q_WS_S60
-void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible)
-{
- bool buttonGroupVisibilityChanged = false;
- if (CEikButtonGroupContainer *const b = buttonGroupContainer()) {
- buttonGroupVisibilityChanged = (b->IsVisible() != buttonGroupVisible);
- b->MakeVisible(buttonGroupVisible);
- }
- bool statusPaneVisibilityChanged = false;
- if (CEikStatusPane *const s = statusPane()) {
- statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible);
- s->MakeVisible(statusPaneVisible);
- }
- if (buttonGroupVisibilityChanged || statusPaneVisibilityChanged) {
- const QSize size = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()).size();
- const QSize oldSize; // note that QDesktopWidget::resizeEvent ignores the QResizeEvent contents
- QResizeEvent event(size, oldSize);
- QApplication::instance()->sendEvent(QApplication::desktop(), &event);
- }
- if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged && QApplication::activeWindow())
- // Ensure that control rectangle is updated
- static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange();
-}
-
-bool QS60Data::setRecursiveDecorationsVisibility(QWidget *window, Qt::WindowStates newState)
-{
- // Show statusbar:
- // Topmost parent: Show unless fullscreen/minimized.
- // Child windows: Follow topmost parent, unless fullscreen, in which case do not show statusbar
- // Show CBA:
- // Topmost parent: Show unless fullscreen/minimized.
- // Exception: Show if fullscreen with Qt::WindowSoftkeysVisibleHint.
- // Child windows:
- // Minimized: Unclear if there is an use case for having focused minimized window at all.
- // Always follow topmost parent just to be safe.
- // Maximized and normal: follow topmost parent.
- // Exception: If topmost parent is not showing CBA, show CBA if any softkey actions are
- // defined.
- // Fullscreen: Show only if Qt::WindowSoftkeysVisibleHint set.
-
- Qt::WindowStates comparisonState = newState;
- QWidget *parentWindow = window->parentWidget();
- if (parentWindow) {
- while (parentWindow->parentWidget())
- parentWindow = parentWindow->parentWidget();
- comparisonState = parentWindow->windowState();
- } else {
- parentWindow = window;
- }
-
- bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized));
- const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen;
- const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint;
- bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint));
-
- // Do extra checking for child windows
- if (window->parentWidget()) {
- if (newState & Qt::WindowFullScreen) {
- decorationsVisible = false;
- if (window->windowFlags() & Qt::WindowSoftkeysVisibleHint)
- buttonGroupVisibility = true;
- else
- buttonGroupVisibility = false;
- } else if (!(newState & Qt::WindowMinimized) && !buttonGroupVisibility) {
- for (int i = 0; i < window->actions().size(); ++i) {
- if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) {
- buttonGroupVisibility = true;
- break;
- }
- }
- }
- }
-
- S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility);
-
- return decorationsVisible;
-}
-#endif
-
-void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
-{
- if (QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control)) {
- QWidget *const widget = QWidgetPrivate::mapper->value(control);
- QWidget *const window = widget->window();
- if (QTLWExtra *topData = qt_widget_private(window)->maybeTopData()) {
- QWidgetBackingStoreTracker &backingStore = topData->backingStore;
- if (visible) {
- if (backingStore.data()) {
- backingStore.registerWidget(widget);
- } else {
- backingStore.create(window);
- backingStore.registerWidget(widget);
- qt_widget_private(widget)->invalidateBuffer(widget->rect());
- widget->repaint();
- }
- } else {
- // In certain special scenarios we may get an ENotVisible event
- // without a previous EPartiallyVisible. The backingstore must
- // still be destroyed, hence the registerWidget() call below.
- if (backingStore.data() && widget->internalWinId()
- && qt_widget_private(widget)->maybeBackingStore() == backingStore.data())
- backingStore.registerWidget(widget);
- backingStore.unregisterWidget(widget);
- // In order to ensure that any resources used by the window surface
- // are immediately freed, we flush the WSERV command buffer.
- S60->wsSession().Flush();
- }
- }
- }
-}
-
-bool qt_nograb() // application no-grab option
-{
-#if defined(QT_DEBUG)
- return appNoGrab;
-#else
- return false;
-#endif
-}
-
-// Modified from http://www3.symbian.com/faq.nsf/0/0F1464EE96E737E780256D5E00503DD1?OpenDocument
-class QS60Beep : public CBase, public MMdaAudioToneObserver
-{
-public:
- static QS60Beep* NewL(TInt aFrequency, TTimeIntervalMicroSeconds iDuration);
- void Play();
- ~QS60Beep();
-private:
- void ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds iDuration);
- void MatoPrepareComplete(TInt aError);
- void MatoPlayComplete(TInt aError);
-private:
- typedef enum
- {
- EBeepNotPrepared,
- EBeepPrepared,
- EBeepPlaying
- } TBeepState;
-private:
- CMdaAudioToneUtility* iToneUtil;
- TBeepState iState;
- TInt iFrequency;
- TTimeIntervalMicroSeconds iDuration;
-};
-
-static QS60Beep* qt_S60Beep = 0;
-
-QS60Beep::~QS60Beep()
-{
- if (iToneUtil) {
- switch (iState) {
- case EBeepPlaying:
- iToneUtil->CancelPlay();
- break;
- case EBeepNotPrepared:
- iToneUtil->CancelPrepare();
- break;
- }
- }
- delete iToneUtil;
-}
-
-QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
-{
- QS60Beep* self = new (ELeave) QS60Beep();
- CleanupStack::PushL(self);
- self->ConstructL(aFrequency, aDuration);
- CleanupStack::Pop();
- return self;
-}
-
-void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
-{
- iToneUtil = CMdaAudioToneUtility::NewL(*this);
- iState = EBeepNotPrepared;
- iFrequency = aFrequency;
- iDuration = aDuration;
- iToneUtil->PrepareToPlayTone(iFrequency, iDuration);
-}
-
-void QS60Beep::Play()
-{
- if (iState == EBeepPlaying) {
- iToneUtil->CancelPlay();
- iState = EBeepPrepared;
- }
-
- iToneUtil->Play();
- iState = EBeepPlaying;
-}
-
-void QS60Beep::MatoPrepareComplete(TInt aError)
-{
- if (aError == KErrNone) {
- iState = EBeepPrepared;
- Play();
- }
-}
-
-void QS60Beep::MatoPlayComplete(TInt aError)
-{
- Q_UNUSED(aError);
- iState = EBeepPrepared;
-}
-
-
-static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers)
-{
- Qt::KeyboardModifiers result = Qt::NoModifier;
-
- if (s60Modifiers & EModifierKeypad)
- result |= Qt::KeypadModifier;
- if (s60Modifiers & EModifierShift || s60Modifiers & EModifierLeftShift
- || s60Modifiers & EModifierRightShift)
- result |= Qt::ShiftModifier;
- if (s60Modifiers & EModifierCtrl || s60Modifiers & EModifierLeftCtrl
- || s60Modifiers & EModifierRightCtrl)
- result |= Qt::ControlModifier;
- if (s60Modifiers & EModifierAlt || s60Modifiers & EModifierLeftAlt
- || s60Modifiers & EModifierRightAlt)
- result |= Qt::AltModifier;
-
- return result;
-}
-
-static void mapS60MouseEventTypeToQt(QEvent::Type *type, Qt::MouseButton *button, const TPointerEvent *pEvent)
-{
- switch (pEvent->iType) {
- case TPointerEvent::EButton1Down:
- *type = QEvent::MouseButtonPress;
- *button = Qt::LeftButton;
- break;
- case TPointerEvent::EButton1Up:
- *type = QEvent::MouseButtonRelease;
- *button = Qt::LeftButton;
- break;
- case TPointerEvent::EButton2Down:
- *type = QEvent::MouseButtonPress;
- *button = Qt::MidButton;
- break;
- case TPointerEvent::EButton2Up:
- *type = QEvent::MouseButtonRelease;
- *button = Qt::MidButton;
- break;
- case TPointerEvent::EButton3Down:
- *type = QEvent::MouseButtonPress;
- *button = Qt::RightButton;
- break;
- case TPointerEvent::EButton3Up:
- *type = QEvent::MouseButtonRelease;
- *button = Qt::RightButton;
- break;
- case TPointerEvent::EDrag:
- *type = QEvent::MouseMove;
- *button = Qt::NoButton;
- break;
- case TPointerEvent::EMove:
- // Qt makes no distinction between move and drag
- *type = QEvent::MouseMove;
- *button = Qt::NoButton;
- break;
- default:
- *type = QEvent::None;
- *button = Qt::NoButton;
- break;
- }
- if (pEvent->iModifiers & EModifierDoubleClick){
- *type = QEvent::MouseButtonDblClick;
- }
-
- if (*type == QEvent::MouseButtonPress || *type == QEvent::MouseButtonDblClick)
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons | (*button);
- else if (*type == QEvent::MouseButtonRelease)
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons &(~(*button));
-
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons & Qt::MouseButtonMask;
-}
-
-//### Can be replaced with CAknLongTapDetector if animation is required.
-//NOTE: if CAknLongTapDetector is used make sure it gets variated out of 3.1 and 3.2,.
-//also MLongTapObserver needs to be changed to MAknLongTapDetectorCallBack if CAknLongTapDetector is used.
-class QLongTapTimer : public CTimer
-{
-public:
- static QLongTapTimer* NewL(QAbstractLongTapObserver *observer);
- QLongTapTimer(QAbstractLongTapObserver *observer);
- void ConstructL();
-public:
- void PointerEventL(const TPointerEvent &event);
- void RunL();
-protected:
-private:
- QAbstractLongTapObserver *m_observer;
- TPointerEvent m_event;
- QPoint m_pressedCoordinates;
- int m_dragDistance;
-};
-
-QLongTapTimer* QLongTapTimer::NewL(QAbstractLongTapObserver *observer)
-{
- QLongTapTimer* self = new QLongTapTimer(observer);
- self->ConstructL();
- return self;
-}
-void QLongTapTimer::ConstructL()
-{
- CTimer::ConstructL();
-}
-
-QLongTapTimer::QLongTapTimer(QAbstractLongTapObserver *observer):CTimer(CActive::EPriorityHigh)
-{
- m_observer = observer;
- m_dragDistance = qApp->startDragDistance();
- CActiveScheduler::Add(this);
-}
-
-void QLongTapTimer::PointerEventL(const TPointerEvent& event)
-{
- if ( event.iType == TPointerEvent::EDrag || event.iType == TPointerEvent::EButtonRepeat)
- {
- QPoint diff(QPoint(event.iPosition.iX,event.iPosition.iY) - m_pressedCoordinates);
- if (diff.manhattanLength() < m_dragDistance)
- return;
- }
- Cancel();
- m_event = event;
- if (event.iType == TPointerEvent::EButton1Down)
- {
- m_pressedCoordinates = QPoint(event.iPosition.iX,event.iPosition.iY);
- // must be same as KLongTapDelay in aknlongtapdetector.h
- After(800000);
- }
-}
-void QLongTapTimer::RunL()
-{
- if (m_observer)
- m_observer->HandleLongTapEventL(m_event.iPosition, m_event.iParentPosition);
-}
-
-QSymbianControl::QSymbianControl(QWidget *w)
- : CCoeControl()
- , qwidget(w)
- , m_longTapDetector(0)
- , m_ignoreFocusChanged(0)
- , m_symbianPopupIsOpen(0)
- , m_inExternalScreenOverride(false)
- , m_lastStatusPaneVisibility(0)
-{
-}
-
-void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
-{
- if (!desktop)
- {
- if (isWindowOwning || !qwidget->parentWidget()
- || qwidget->parentWidget()->windowType() == Qt::Desktop) {
- RWindowGroup &wg(S60->windowGroup(qwidget));
- CreateWindowL(wg);
- } else {
- /**
- * TODO: in order to avoid creating windows for all ancestors of
- * this widget up to the root window, the parameter passed to
- * CreateWindowL should be
- * qwidget->parentWidget()->effectiveWinId(). However, if we do
- * this, then we need to take care of re-parenting when a window
- * is created for a widget between this one and the root window.
- */
- CreateWindowL(qwidget->parentWidget()->winId());
- }
-
- // Necessary in order to be able to track the activation status of
- // the control's window
- qwidget->d_func()->createExtra();
-
- SetFocusing(true);
- m_longTapDetector = QLongTapTimer::NewL(this);
- m_doubleClickTimer.invalidate();
-
- DrawableWindow()->SetPointerGrab(ETrue);
- }
-
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- if (OwnsWindow()) {
- TTfxWindowPurpose windowPurpose(ETfxPurposeNone);
- switch (qwidget->windowType()) {
- case Qt::Dialog:
- windowPurpose = ETfxPurposeDialogWindow;
- break;
- case Qt::Popup:
- windowPurpose = ETfxPurposePopupWindow;
- break;
- case Qt::Tool:
- windowPurpose = ETfxPurposeToolWindow;
- break;
- case Qt::ToolTip:
- windowPurpose = ETfxPurposeToolTipWindow;
- break;
- case Qt::SplashScreen:
- windowPurpose = ETfxPurposeSplashScreenWindow;
- break;
- default:
- windowPurpose = (isWindowOwning || !qwidget->parentWidget() || qwidget->parentWidget()->windowType() == Qt::Desktop)
- ? ETfxPurposeWindow : ETfxPurposeChildWindow;
- break;
- }
- Window().SetPurpose(windowPurpose);
- }
-#endif
-}
-
-QSymbianControl::~QSymbianControl()
-{
- // Ensure backing store is deleted before the top-level
- // window is destroyed
- qt_widget_private(qwidget)->topData()->backingStore.destroy();
-
- if (S60->curWin == this)
- S60->curWin = 0;
- if (!QApplicationPrivate::is_app_closing) {
- QT_TRY {
- setFocusSafely(false);
- } QT_CATCH(const std::exception&) {
- // ignore exceptions, nothing can be done
- }
- }
- S60->appUi()->RemoveFromStack(this);
- delete m_longTapDetector;
-}
-
-void QSymbianControl::setWidget(QWidget *w)
-{
- qwidget = w;
-}
-
-QPoint QSymbianControl::translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const
-{
- QPoint pos(pointerEventPos.iX, pointerEventPos.iY);
- if (qwidget->d_func()->fixNativeOrientationCalled) {
- QSize wsize = qwidget->size();
- TSize size = Size();
- if (size.iWidth == wsize.height() && size.iHeight == wsize.width()) {
- qreal x = pos.x();
- qreal y = pos.y();
- pos.setX(size.iHeight - y);
- pos.setY(x);
- }
- }
- return pos;
-}
-
-TRect QSymbianControl::translateRectForFixedNativeOrientation(const TRect &controlRect) const
-{
- TRect rect = controlRect;
- if (qwidget->d_func()->fixNativeOrientationCalled) {
- QPoint a = translatePointForFixedNativeOrientation(rect.iTl);
- QPoint b = translatePointForFixedNativeOrientation(rect.iBr);
- if (a.x() < b.x()) {
- rect.iTl.iX = a.x();
- rect.iBr.iX = b.x();
- } else {
- rect.iTl.iX = b.x();
- rect.iBr.iX = a.x();
- }
- if (a.y() < b.y()) {
- rect.iTl.iY = a.y();
- rect.iBr.iY = b.y();
- } else {
- rect.iTl.iY = b.y();
- rect.iBr.iY = a.y();
- }
- }
- return rect;
-}
-
-void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
-{
- QWidget *alienWidget;
- QPoint widgetPos = translatePointForFixedNativeOrientation(aPenEventLocation);
- QPoint globalPos = translatePointForFixedNativeOrientation(aPenEventScreenLocation);
- alienWidget = qwidget->childAt(widgetPos);
- if (!alienWidget)
- alienWidget = qwidget;
-
-#if !defined(QT_NO_CONTEXTMENU)
- QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, Qt::NoModifier);
- qt_sendSpontaneousEvent(alienWidget, &contextMenuEvent);
-#endif
-}
-
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
-void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event)
-{
- QApplicationPrivate *d = QApplicationPrivate::instance();
- QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition));
- qreal pressure;
- 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);
-}
-#endif
-
-void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure)
-{
- QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget);
-
- QApplicationPrivate *d = QApplicationPrivate::instance();
-
- QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints;
- while (points.count() <= pointerNumber)
- points.append(QTouchEvent::TouchPoint(points.count()));
-
- Qt::TouchPointStates allStates = 0;
- for (int i = 0; i < points.count(); ++i) {
- QTouchEvent::TouchPoint &touchPoint = points[i];
-
- if (touchPoint.id() == pointerNumber) {
- Qt::TouchPointStates state;
- switch (type) {
- case TPointerEvent::EButton1Down:
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- case TPointerEvent::EEnterHighPressure:
-#endif
- 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);
-
- touchPoint.setScreenPos(screenPos);
- touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
- 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);
- }
-
- allStates |= touchPoint.state();
- }
-
- if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
- // all touch points released
- d->appAllTouchPoints.clear();
- } else {
- d->appAllTouchPoints = points;
- }
-
- QApplicationPrivate::translateRawTouchEvent(qwidget,
- QTouchEvent::TouchScreen,
- points);
-}
-
-void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
-{
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- if (pEvent.IsAdvancedPointerEvent()) {
- const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent();
- translateAdvancedPointerEvent(advancedPointerEvent);
- if (advancedPointerEvent->PointerNumber() != 0) {
- // only send mouse events for the first touch point
- return;
- }
- }
-#endif
-
- m_longTapDetector->PointerEventL(pEvent);
- QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
-}
-
-void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
-{
- QMouseEvent::Type type;
- Qt::MouseButton button;
- mapS60MouseEventTypeToQt(&type, &button, &pEvent);
- Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
-
- QPoint widgetPos = translatePointForFixedNativeOrientation(pEvent.iPosition);
- TPoint controlScreenPos = PositionRelativeToScreen();
- QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
- S60->lastCursorPos = globalPos;
- S60->lastPointerEventPos = widgetPos;
-
- QWidget *mouseGrabber = QWidget::mouseGrabber();
-
- QWidget *popupWidget = qApp->activePopupWidget();
- QWidget *popupReceiver = 0;
- if (popupWidget) {
- QWidget *popupChild = popupWidget->childAt(popupWidget->mapFromGlobal(globalPos));
- popupReceiver = popupChild ? popupChild : popupWidget;
- }
-
- if (mouseGrabber) {
- if (popupReceiver) {
- sendMouseEvent(popupReceiver, type, globalPos, button, modifiers);
- } else {
- sendMouseEvent(mouseGrabber, type, globalPos, button, modifiers);
- }
- // No Enter/Leave events in grabbing mode.
- return;
- }
-
- QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
- if (!widgetUnderPointer)
- widgetUnderPointer = qwidget;
-
- QApplicationPrivate::dispatchEnterLeave(widgetUnderPointer, S60->lastPointerEventTarget);
- S60->lastPointerEventTarget = widgetUnderPointer;
-
- QWidget *receiver;
- if (!popupReceiver && S60->mousePressTarget && type != QEvent::MouseButtonPress) {
- receiver = S60->mousePressTarget;
- if (type == QEvent::MouseButtonRelease)
- S60->mousePressTarget = 0;
- } else {
- receiver = popupReceiver ? popupReceiver : widgetUnderPointer;
- if (type == QEvent::MouseButtonPress)
- S60->mousePressTarget = receiver;
- }
-
-#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
- if (S60->brokenPointerCursors)
- qt_symbian_move_cursor_sprite();
-#endif
-
-//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);
- }
-#endif
-
- sendMouseEvent(receiver, type, globalPos, button, modifiers);
-}
-
-#ifdef Q_WS_S60
-void QSymbianControl::HandleStatusPaneSizeChange()
-{
- QS60MainAppUi *s60AppUi = static_cast<QS60MainAppUi *>(S60->appUi());
- s60AppUi->HandleStatusPaneSizeChange();
-}
-#endif
-
-void QSymbianControl::sendMouseEvent(
- QWidget *receiver,
- QEvent::Type type,
- const QPoint &globalPos,
- Qt::MouseButton button,
- Qt::KeyboardModifiers modifiers)
-{
- Q_ASSERT(receiver);
- QMouseEvent mEvent(type, receiver->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, modifiers);
- QEventDispatcherS60 *dispatcher;
- // It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(receiver->d_func()->threadData->eventDispatcher)) != 0) {
- if (dispatcher->excludeUserInputEvents()) {
- dispatcher->saveInputEvent(this, receiver, new QMouseEvent(mEvent));
- return;
- }
- }
-
- sendMouseEvent(receiver, &mEvent);
-}
-
-bool QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent)
-{
- return qt_sendSpontaneousEvent(widget, mEvent);
-}
-
-TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
-{
- TKeyResponse r = EKeyWasNotConsumed;
- QT_TRYCATCH_LEAVING(r = OfferKeyEvent(keyEvent, type));
- return r;
-}
-
-TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type)
-{
- /*
- S60 has a confusing way of delivering key events. There are three types of
- events: EEventKey, EEventKeyDown and EEventKeyUp. When a key is pressed,
- EEventKeyDown is first generated, followed by EEventKey. Then, when the key is
- released, EEventKeyUp is generated.
- However, it is possible that only the EEventKey is generated alone, typically
- in relation to virtual keyboards. In that case we need to take care to
- generate both press and release events in Qt, since applications expect that.
- We do this by having three states for each used scan code, depending on the
- events received. See the switch below for what happens in each state
- transition.
- */
-
- if (type != EEventKeyDown)
- if (handleVirtualMouse(keyEvent, type) == EKeyWasConsumed)
- return EKeyWasConsumed;
-
- TKeyResponse ret = EKeyWasNotConsumed;
-#define GET_RETURN(x) (ret = ((x) == EKeyWasConsumed) ? EKeyWasConsumed : ret)
-
- // This top level switch corresponds to the states, and the inner switches
- // correspond to the transitions.
- QS60Data::ScanCodeState &scanCodeState = S60->scanCodeStates[keyEvent.iScanCode];
- switch (scanCodeState) {
- case QS60Data::Unpressed:
- switch (type) {
- case EEventKeyDown:
- scanCodeState = QS60Data::KeyDown;
- break;
- case EEventKey:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
- break;
- case EEventKeyUp:
- // No action.
- break;
- }
- break;
- case QS60Data::KeyDown:
- switch (type) {
- case EEventKeyDown:
- // This should never happen, just stay in this state to be safe.
- break;
- case EEventKey:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
- scanCodeState = QS60Data::KeyDownAndKey;
- break;
- case EEventKeyUp:
- scanCodeState = QS60Data::Unpressed;
- break;
- }
- break;
- case QS60Data::KeyDownAndKey:
- switch (type) {
- case EEventKeyDown:
- // This should never happen, just stay in this state to be safe.
- break;
- case EEventKey:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
- break;
- case EEventKeyUp:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
- scanCodeState = QS60Data::Unpressed;
- break;
- }
- break;
- }
- return ret;
-
-#undef GET_RETURN
-}
-
-TKeyResponse QSymbianControl::sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type)
-{
- // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp
- // events, we need to cache the keysyms from the EKeyEvent events. This is what
- // resolveS60ScanCode does.
- TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
- keyEvent.iCode);
- int keyCode;
- if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
- keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
- } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
- // Normal characters keys.
- keyCode = s60Keysym;
- } else {
- // Special S60 keys.
- keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
- }
-
- Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
- QKeyEventEx qKeyEvent(type, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
- (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
- QWidget *widget;
- widget = QWidget::keyboardGrabber();
- if (!widget) {
- if (QApplicationPrivate::popupWidgets != 0) {
- widget = QApplication::activePopupWidget()->focusWidget();
- if (!widget) {
- widget = QApplication::activePopupWidget();
- }
- } else {
- widget = QApplicationPrivate::focus_widget;
- if (!widget) {
- widget = qwidget;
- }
- }
- }
-
- QEventDispatcherS60 *dispatcher;
- // It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) {
- if (dispatcher->excludeUserInputEvents()) {
- dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent));
- return EKeyWasConsumed;
- }
- }
- return sendKeyEvent(widget, &qKeyEvent);
-}
-
-TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type)
-{
-#ifndef QT_NO_CURSOR
- if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
- //translate keys to pointer
- if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) ||
- (keyEvent.iScanCode >= EStdKeyDevice10 && keyEvent.iScanCode <= EStdKeyDevice13) ||
- keyEvent.iScanCode == EStdKeyDevice3) {
- QPoint pos = QCursor::pos();
- TPointerEvent fakeEvent;
- fakeEvent.iType = (TPointerEvent::TType)(-1);
- fakeEvent.iModifiers = keyEvent.iModifiers;
- TInt x = pos.x();
- TInt y = pos.y();
- if (type == EEventKeyUp) {
- S60->virtualMouseAccelTimeout.start();
- switch (keyEvent.iScanCode) {
- case EStdKeyLeftArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Left;
- break;
- case EStdKeyRightArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Right;
- break;
- case EStdKeyUpArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Up;
- break;
- case EStdKeyDownArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Down;
- break;
- // diagonal keys (named aliases don't exist in 3.1 SDK)
- case EStdKeyDevice10:
- S60->virtualMousePressedKeys &= ~QS60Data::LeftUp;
- break;
- case EStdKeyDevice11:
- S60->virtualMousePressedKeys &= ~QS60Data::RightUp;
- break;
- case EStdKeyDevice12:
- S60->virtualMousePressedKeys &= ~QS60Data::RightDown;
- break;
- case EStdKeyDevice13:
- S60->virtualMousePressedKeys &= ~QS60Data::LeftDown;
- break;
- case EStdKeyDevice3: //select
- if (S60->virtualMousePressedKeys & QS60Data::Select)
- fakeEvent.iType = TPointerEvent::EButton1Up;
- S60->virtualMousePressedKeys &= ~QS60Data::Select;
- break;
- }
- }
- else if (type == EEventKey) {
- int dx = 0;
- int dy = 0;
- if (keyEvent.iScanCode != EStdKeyDevice3) {
- m_doubleClickTimer.invalidate();
- //reset mouse accelleration after a short time with no moves
- const int maxTimeBetweenKeyEventsMs = 500;
- if (S60->virtualMouseAccelTimeout.isValid() &&
- S60->virtualMouseAccelTimeout.hasExpired(maxTimeBetweenKeyEventsMs)) {
- S60->virtualMouseAccelDX = 0;
- S60->virtualMouseAccelDY = 0;
- }
- S60->virtualMouseAccelTimeout.invalidate();
- }
- switch (keyEvent.iScanCode) {
- case EStdKeyLeftArrow:
- S60->virtualMousePressedKeys |= QS60Data::Left;
- dx = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyRightArrow:
- S60->virtualMousePressedKeys |= QS60Data::Right;
- dx = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyUpArrow:
- S60->virtualMousePressedKeys |= QS60Data::Up;
- dy = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDownArrow:
- S60->virtualMousePressedKeys |= QS60Data::Down;
- dy = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice10:
- S60->virtualMousePressedKeys |= QS60Data::LeftUp;
- dx = -1;
- dy = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice11:
- S60->virtualMousePressedKeys |= QS60Data::RightUp;
- dx = 1;
- dy = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice12:
- S60->virtualMousePressedKeys |= QS60Data::RightDown;
- dx = 1;
- dy = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice13:
- S60->virtualMousePressedKeys |= QS60Data::LeftDown;
- dx = -1;
- dy = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice3:
- // Platform bug. If you start pressing several keys simultaneously (for
- // example for drag'n'drop), Symbian starts producing spurious up and
- // down messages for some keys. Therefore, make sure we have a clean slate
- // of pressed keys before starting a new button press.
- if (S60->virtualMousePressedKeys & QS60Data::Select) {
- return EKeyWasConsumed;
- } else {
- S60->virtualMousePressedKeys |= QS60Data::Select;
- fakeEvent.iType = TPointerEvent::EButton1Down;
- if (m_doubleClickTimer.isValid()
- && !m_doubleClickTimer.hasExpired(QApplication::doubleClickInterval())) {
- fakeEvent.iModifiers |= EModifierDoubleClick;
- m_doubleClickTimer.invalidate();
- } else {
- m_doubleClickTimer.start();
- }
- }
- break;
- }
- if (dx) {
- int cdx = S60->virtualMouseAccelDX;
- //reset accel on change of sign, else double accel
- if (dx * cdx <= 0)
- cdx = dx;
- else
- cdx *= 4;
- //cap accelleration
- if (dx * cdx > S60->virtualMouseMaxAccel)
- cdx = dx * S60->virtualMouseMaxAccel;
- //move mouse position
- x += cdx;
- S60->virtualMouseAccelDX = cdx;
- }
-
- if (dy) {
- int cdy = S60->virtualMouseAccelDY;
- if (dy * cdy <= 0)
- cdy = dy;
- else
- cdy *= 4;
- if (dy * cdy > S60->virtualMouseMaxAccel)
- cdy = dy * S60->virtualMouseMaxAccel;
- y += cdy;
- S60->virtualMouseAccelDY = cdy;
- }
- }
- //clip to screen size (window server allows a sprite hotspot to be outside the screen)
- int screenNumber = S60->screenNumberForWidget(qwidget);
- if (x < 0)
- x = 0;
- else if (x >= S60->screenWidthInPixelsForScreen[screenNumber])
- x = S60->screenWidthInPixelsForScreen[screenNumber] - 1;
- if (y < 0)
- y = 0;
- else if (y >= S60->screenHeightInPixelsForScreen[screenNumber])
- y = S60->screenHeightInPixelsForScreen[screenNumber] - 1;
- TPoint epos(x, y);
- TPoint cpos = epos - PositionRelativeToScreen();
- fakeEvent.iPosition = cpos;
- fakeEvent.iParentPosition = epos;
- if(fakeEvent.iType != -1)
- HandlePointerEvent(fakeEvent);
- return EKeyWasConsumed;
- }
- }
-#endif
-
- return EKeyWasNotConsumed;
-}
-
-void QSymbianControl::sendInputEvent(QWidget *widget, QInputEvent *inputEvent)
-{
- switch (inputEvent->type()) {
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- sendKeyEvent(widget, static_cast<QKeyEvent *>(inputEvent));
- break;
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- sendMouseEvent(widget, static_cast<QMouseEvent *>(inputEvent));
- break;
- default:
- // Shouldn't get here.
- Q_ASSERT_X(0 == 1, "QSymbianControl::sendInputEvent()", "inputEvent->type() is unknown");
- break;
- }
-}
-
-TKeyResponse QSymbianControl::sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent)
-{
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
- if (widget && widget->isEnabled() && widget->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext *qic = widget->inputContext();
- if (qic && qic->filterEvent(keyEvent))
- return EKeyWasConsumed;
- }
-#endif // !defined(QT_NO_IM) && defined(Q_OS_SYMBIAN)
-
- if (widget && qt_sendSpontaneousEvent(widget, keyEvent))
- if (keyEvent->isAccepted())
- return EKeyWasConsumed;
-
- return EKeyWasNotConsumed;
-}
-
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
-TCoeInputCapabilities QSymbianControl::InputCapabilities() const
-{
- QWidget *w = 0;
-
- if (qwidget->hasFocus())
- w = qwidget;
- else
- w = qwidget->focusWidget();
-
- QCoeFepInputContext *ic;
- if (w && w->isEnabled() && w->testAttribute(Qt::WA_InputMethodEnabled)
- && (ic = qobject_cast<QCoeFepInputContext *>(w->inputContext()))) {
- return ic->inputCapabilities();
- } else {
- return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
- }
-}
-#endif
-
-void QSymbianControl::Draw(const TRect& controlRect) const
-{
- // Set flag to avoid calling DrawNow in window surface
- QWidget *window = qwidget->window();
- Q_ASSERT(window);
- QTLWExtra *topExtra = window->d_func()->maybeTopData();
- Q_ASSERT(topExtra);
-
- TRect wcontrolRect = translateRectForFixedNativeOrientation(controlRect);
-
- if (!topExtra->inExpose) {
- topExtra->inExpose = true;
- if (!qwidget->isWindow()) {
- // If we get here, then it means we have a native child window
- // Since no content should ever be painted to these windows, we
- // erase them with a transparent brush when they get an expose.
- CWindowGc &gc = SystemGc();
- gc.SetBrushColor(TRgb(0, 0, 0, 0));
- gc.Clear(controlRect);
- }
- QRect exposeRect = qt_TRect2QRect(wcontrolRect);
- qwidget->d_func()->syncBackingStore(exposeRect);
- topExtra->inExpose = false;
- }
-
- QWindowSurface *surface = qwidget->windowSurface();
- QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
-
- if (!engine)
- return;
-
- const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
- if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(wcontrolRect);
- QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
- }
-
- // Map source rectangle into coordinates of the backing store.
- const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY);
- const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase);
- const TRect backingStoreRect(TPoint(backingStoreBase.x(), backingStoreBase.y()), controlRect.Size());
-
- if (engine->type() == QPaintEngine::Raster) {
- QS60WindowSurface *s60Surface;
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if (QApplicationPrivate::runtime_graphics_system) {
- QRuntimeWindowSurface *rtSurface =
- static_cast<QRuntimeWindowSurface*>(qwidget->windowSurface());
- s60Surface = static_cast<QS60WindowSurface *>(rtSurface->m_windowSurface.data());
- } else
-#endif
- s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
-
- CFbsBitmap *bitmap = s60Surface->symbianBitmap();
- CWindowGc &gc = SystemGc();
-
- QWExtra::NativePaintMode nativePaintMode = qwidget->d_func()->extraData()->nativePaintMode;
- if(qwidget->d_func()->paintOnScreen())
- nativePaintMode = QWExtra::Disable;
-
- switch(nativePaintMode) {
- case QWExtra::Disable:
- // Do nothing
- break;
- case QWExtra::Blit:
- case QWExtra::BlitWriteAlpha:
- if (qwidget->d_func()->isOpaque || nativePaintMode == QWExtra::BlitWriteAlpha)
- gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
- gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
- break;
- case QWExtra::ZeroFill:
- if (Window().DisplayMode() == EColor16MA
- || Window().DisplayMode() == Q_SYMBIAN_ECOLOR16MAP) {
- gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
- gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
- gc.SetBrushColor(TRgb::Color16MA(0));
- gc.Clear(controlRect);
- } else {
- gc.SetBrushColor(TRgb(0x000000));
- gc.Clear(controlRect);
- };
- break;
- default:
- Q_ASSERT(false);
- }
- }
-
- if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(wcontrolRect);
- // The draw ops aren't actually sent to WSERV until the graphics
- // context is deactivated, which happens in the function calling
- // this one. We therefore delay the delivery of endNativePaintEvent,
- // to ensure that drawing has completed by the time the widget
- // receives the event. Note that, if the widget needs to ensure
- // that the draw ops have actually been executed into the output
- // framebuffer, a call to RWsSession::Flush is required in the
- // endNativePaintEvent implementation.
- QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r));
- }
-}
-
-void QSymbianControl::qwidgetResize_helper(const QSize &newSize)
-{
- QRect cr = qwidget->geometry();
- QSize oldSize(cr.size());
- cr.setSize(newSize);
- qwidget->data->crect = cr;
- if (qwidget->isVisible()) {
- QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
- bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = true;
- QResizeEvent e(newSize, oldSize);
- qt_sendSpontaneousEvent(qwidget, &e);
- if (!qwidget->testAttribute(Qt::WA_StaticContents))
- qwidget->d_func()->syncBackingStore();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = false;
- } else {
- if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
- QResizeEvent *e = new QResizeEvent(newSize, oldSize);
- QApplication::postEvent(qwidget, e);
- }
- }
-}
-
-void QSymbianControl::SizeChanged()
-{
- CCoeControl::SizeChanged();
-
- // When FixNativeOrientation had been called, the RWindow/CCoeControl size
- // and the surface/QWidget size have nothing to do with each other.
- if (qwidget->d_func()->fixNativeOrientationCalled)
- return;
-
- QSize oldSize = qwidget->size();
- QSize newSize(Size().iWidth, Size().iHeight);
-
- if (oldSize != newSize) {
- // Enforce the proper size for fullscreen widgets on the secondary screen.
- const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- const int screenNumber = S60->screenNumberForWidget(qwidget);
- if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
- int screenWidth = S60->screenWidthInPixelsForScreen[screenNumber];
- int screenHeight = S60->screenHeightInPixelsForScreen[screenNumber];
- TSize screenSize(screenWidth, screenHeight);
- if (screenWidth > 0 && screenHeight > 0 && screenSize != Size()) {
- m_inExternalScreenOverride = true;
- SetExtent(TPoint(0, 0), screenSize);
- return;
- }
- }
-
- qwidgetResize_helper(newSize);
- }
-
- m_inExternalScreenOverride = false;
-
- // CCoeControl::SetExtent calls SizeChanged, but does not call
- // PositionChanged, so we call it here to ensure that the widget's
- // position is updated.
- PositionChanged();
-}
-
-void QSymbianControl::PositionChanged()
-{
- CCoeControl::PositionChanged();
-
- QPoint oldPos = qwidget->geometry().topLeft();
- QPoint newPos(Position().iX, Position().iY);
-
- if (oldPos != newPos) {
- QRect cr = qwidget->geometry();
- cr.moveTopLeft(newPos);
- qwidget->data->crect = cr;
- QTLWExtra *top = qwidget->d_func()->maybeTopData();
- if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
- top->normalGeometry.moveTopLeft(newPos);
- if (qwidget->isVisible()) {
- QMoveEvent e(newPos, oldPos);
- qt_sendSpontaneousEvent(qwidget, &e);
- } else {
- QMoveEvent * e = new QMoveEvent(newPos, oldPos);
- QApplication::postEvent(qwidget, e);
- }
- }
-}
-
-void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
-{
- if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
- return;
-
-#ifdef Q_WS_S60
- if (S60->splitViewLastWidget)
- return;
-#endif
-
- // Popups never get focused, but still receive the FocusChanged when they are hidden.
- if (QApplicationPrivate::popupWidgets != 0
- || (qwidget->windowType() & Qt::Popup) == Qt::Popup)
- return;
-
- if (IsFocused() && IsVisible()) {
- if (m_symbianPopupIsOpen) {
- QWidget *fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
- QCoreApplication::sendEvent(fw, &event);
- }
- m_symbianPopupIsOpen = false;
- }
-
- QApplication::setActiveWindow(qwidget->window());
- qwidget->d_func()->setWindowIcon_sys(true);
- qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
-#ifdef Q_WS_S60
- if (qwidget->isWindow())
- S60->setRecursiveDecorationsVisibility(qwidget, qwidget->windowState());
-#endif
- } else if (QApplication::activeWindow() == qwidget->window()) {
- bool focusedControlFound = false;
- WId winId = 0;
- for (QWidget *w = qwidget->parentWidget(); w && (winId = w->internalWinId()); w = w->parentWidget()) {
- if (winId->IsFocused() && winId->IsVisible()) {
- focusedControlFound = true;
- break;
- } else if (w->isWindow())
- break;
- }
- if (!focusedControlFound) {
- if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
- QWidget *fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
- QCoreApplication::sendEvent(fw, &event);
- }
- m_symbianPopupIsOpen = true;
- return;
- }
-
- QApplication::setActiveWindow(0);
- }
- }
- // else { We don't touch the active window unless we were explicitly activated or deactivated }
-}
-
-void QSymbianControl::handleClientAreaChange()
-{
- const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
- if (qwidget->isFullScreen() && !cbaVisibilityHint) {
- SetExtentToWholeScreen();
- } else if (qwidget->isMaximized() || (qwidget->isFullScreen() && cbaVisibilityHint)) {
- TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
- SetExtent(r.iTl, r.Size());
- } else if (!qwidget->isMinimized()) { // Normal geometry
- if (!qwidget->testAttribute(Qt::WA_Resized)) {
- qwidget->adjustSize();
- qwidget->setAttribute(Qt::WA_Resized, false); //not a user resize
- }
- if (!qwidget->testAttribute(Qt::WA_Moved) && qwidget->windowType() != Qt::Dialog) {
- TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
- SetPosition(r.iTl);
- qwidget->setAttribute(Qt::WA_Moved, false); // not really an explicit position
- }
- }
-}
-
-bool QSymbianControl::isSplitViewWidget(QWidget *widget) {
- bool returnValue = true;
- //Ignore events sent to non-active windows, not visible widgets and not parents of input widget.
- if (!qwidget->isActiveWindow()
- || !qwidget->isVisible()
- || !qwidget->isAncestorOf(widget)) {
-
- returnValue = false;
- }
- return returnValue;
-}
-
-void QSymbianControl::HandleResourceChange(int resourceType)
-{
- switch (resourceType) {
- case KSplitViewCloseEvent: //intentional fall-through
- case KSplitViewOpenEvent: {
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
-
- //Fetch widget getting the text input
- QWidget *widget = QWidget::keyboardGrabber();
- if (!widget) {
- if (QApplicationPrivate::popupWidgets) {
- widget = QApplication::activePopupWidget()->focusWidget();
- if (!widget) {
- widget = QApplication::activePopupWidget();
- }
- } else {
- widget = QApplicationPrivate::focus_widget;
- if (!widget) {
- widget = qwidget;
- }
- }
- }
- if (widget) {
- QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(widget->inputContext());
- if (!ic) {
- ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
- }
- if (ic && isSplitViewWidget(widget)) {
- if (resourceType == KSplitViewCloseEvent) {
- ic->resetSplitViewWidget();
- } else {
- ic->ensureFocusWidgetVisible(widget);
- }
- }
- }
-#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
- }
- break;
- case KInternalStatusPaneChange:
- // When status pane is not visible, only handle client area change if status pane was
- // previously visible, as size changes to hidden status pane should not affect
- // client area.
- if (S60->statusPane() && (S60->statusPane()->IsVisible() || m_lastStatusPaneVisibility)) {
- m_lastStatusPaneVisibility = S60->statusPane()->IsVisible();
- handleClientAreaChange();
- }
- if (IsFocused() && IsVisible()) {
- qwidget->d_func()->setWindowIcon_sys(true);
- qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
- }
- break;
- case KUidValueCoeFontChangeEvent:
- // font change event
- break;
-#ifdef Q_WS_S60
- case KEikDynamicLayoutVariantSwitch:
- {
- handleClientAreaChange();
- // Send resize event to trigger desktopwidget workAreaResized signal
- if (qt_desktopWidget) {
- QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
- QApplication::sendEvent(qt_desktopWidget, &e);
- }
- break;
- }
-#endif
- default:
- break;
- }
-
- CCoeControl::HandleResourceChange(resourceType);
-
-}
-void QSymbianControl::CancelLongTapTimer()
-{
- m_longTapDetector->Cancel();
-}
-
-TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
-{
- if (id.iUid == ETypeId)
- return id.MakePtr(this);
-
- return CCoeControl::MopSupplyObject(id);
-}
-
-void QSymbianControl::setFocusSafely(bool focus)
-{
- // The stack hack in here is very unfortunate, but it is the only way to ensure proper
- // focus in Symbian. If this is not executed, the control which happens to be on
- // the top of the stack may randomly be assigned focus by Symbian, for example
- // when creating new windows (specifically in CCoeAppUi::HandleStackChanged()).
-
- // Close any popups.
- CEikonEnv::Static()->EikAppUi()->StopDisplayingMenuBar();
-
- if (focus) {
- S60->appUi()->RemoveFromStack(this);
- // Symbian doesn't automatically remove focus from the last focused control, so we need to
- // remember it and clear focus ourselves.
- if (lastFocusedControl && lastFocusedControl != this)
- lastFocusedControl->SetFocus(false);
- QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
- ECoeStackPriorityDefault + 1, ECoeStackFlagStandard)); // Note the + 1
- lastFocusedControl = this;
- this->SetFocus(true);
- } else {
- S60->appUi()->RemoveFromStack(this);
- QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
- ECoeStackPriorityDefault, ECoeStackFlagStandard));
- if(this == lastFocusedControl)
- lastFocusedControl = 0;
- this->SetFocus(false);
- }
-}
-
-bool QSymbianControl::isControlActive()
-{
- return IsActivated() ? true : false;
-}
-
-void QSymbianControl::ensureFixNativeOrientation()
-{
-#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION)
- if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop)
- return;
- if (S60->screenNumberForWidget(qwidget) > 0)
- return;
- const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled;
- const bool isFixEnabled = qwidget->testAttribute(Qt::WA_SymbianNoSystemRotation);
- const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
- if (isFullScreen && isFixEnabled) {
- const bool surfaceBasedGs =
- QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
- || QApplicationPrivate::graphics_system_name == QLatin1String("opengl");
- if (!surfaceBasedGs)
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
- if (!isFixed && surfaceBasedGs) {
- if (Window().FixNativeOrientation() == KErrNone) {
- qwidget->d_func()->fixNativeOrientationCalled = true;
- // The EGL window surface is now fixed to the native orientation
- // of the device, no matter what size we pass when creating it.
- // Enforce the same size for the QWidget too. For the underlying
- // CCoeControl and RWindow it is up to the system to resize them
- // when the standard auto-rotation mechanism is in use, we must not
- // change that behavior by forcing any size for those. In practice
- // this means that the QWidget and the underlying native control
- // dimensions will be out of sync when FixNativeOrientation was
- // called and the device is turned to the non-native (typically
- // landscape) orientation. The pointer event handling and certain
- // functions like Draw() will need to compensate for this.
- QSize newSize(S60->nativeScreenWidthInPixels, S60->nativeScreenHeightInPixels);
- if (qwidget->size() != newSize)
- qwidgetResize_helper(newSize);
- } else {
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
- }
- }
- } else if (isFixed) {
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
- qwidget->d_func()->fixNativeOrientationCalled = false;
- qwidget->hide();
- qwidget->d_func()->create_sys(0, false, true);
- qwidget->show();
- }
-#else
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
-#endif
-}
-
-/*!
- \typedef QApplication::QS60MainApplicationFactory
- \since 4.6
-
- This is a typedef for a pointer to a function with the following
- signature:
-
- \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 47
-
- \sa QApplication::QApplication()
-*/
-
-/*!
- \since 4.6
-
- Creates an application using the application factory given in
- \a factory, and using \a argc command line arguments in \a argv.
- \a factory can be leaving, but the error will be converted to a
- standard exception.
-
- This function is only available on S60.
-*/
-QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
-{
- Q_D(QApplication);
- S60->s60ApplicationFactory = factory;
- d->construct();
-}
-
-QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
-{
- Q_D(QApplication);
- S60->s60ApplicationFactory = factory;
- d->construct();
- QApplicationPrivate::app_compile_version = _internal;
-}
-
-void qt_init(QApplicationPrivate * /* priv */, int)
-{
- if (!CCoeEnv::Static()) {
- // The S60 framework creates a new trap handler which will render any existing traps
- // invalid as long as it is active. This means that all code in main() that occurs after
- // the QApplication construction needs to be surrounded by a new trap, despite having
- // an outer one already. To avoid this, we save the original trap handler here, and set
- // it back after the S60 framework is constructed. Then we restore it right before the S60
- // framework destruction.
- TTrapHandler *origTrapHandler = User::TrapHandler();
-
- // The S60 framework has not been initialized. We need to do it.
- TApaApplicationFactory factory(S60->s60ApplicationFactory ?
- S60->s60ApplicationFactory : newS60Application);
- CApaCommandLine* commandLine = q_check_ptr(QCoreApplicationPrivate::symbianCommandLine());
- if (commandLine) {
- // After this construction, CEikonEnv will be available from CEikonEnv::Static().
- // (much like our qApp).
- QtEikonEnv* coe = new QtEikonEnv;
- //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
- TRAPD(err, coe->ConstructAppFromCommandLineL(factory, *commandLine));
- if(err != KErrNone) {
- qWarning() << "qt_init: Eikon application construct failed ("
- << err
- << "), maybe missing resource file on S60 3.1?";
- delete coe;
- qt_symbian_throwIfError(err);
- }
- }
-
- S60->s60InstalledTrapHandler = User::SetTrapHandler(origTrapHandler);
-
- S60->qtOwnsS60Environment = true;
- } else {
- S60->qtOwnsS60Environment = false;
- }
-
-#ifdef QT_NO_DEBUG
- if (!qgetenv("QT_S60_AUTO_FLUSH_WSERV").isEmpty())
-#endif
- S60->wsSession().SetAutoFlush(ETrue);
-
-#ifdef Q_SYMBIAN_WINDOW_SIZE_CACHE
- TRAP_IGNORE(S60->wsSession().EnableWindowSizeCacheL());
-#endif
-
- S60->updateScreenSize();
-
-
- TDisplayMode mode = S60->screenDevice()->DisplayMode();
- S60->screenDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel(mode);
-
- //NB: RWsSession::GetColorModeList tells you what window modes are supported,
- //not what bitmap formats.
- if(QSysInfo::symbianVersion() == QSysInfo::SV_9_2)
- S60->supportsPremultipliedAlpha = 0;
- else
- S60->supportsPremultipliedAlpha = 1;
-
- RProcess me;
- TSecureId securId = me.SecureId();
- S60->uid = securId.operator TUid();
-
- // enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app,
- // and for dimming behind modal windows
- S60->windowGroup().EnableFocusChangeEvents();
-
- //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
- const TInt KMachineUidSamsungI8510 = 0x2000C51E;
- // HAL::Get(HALData::EPen, TInt& result) may set 'result' to 1 on some 3.1 systems (e.g. N95).
- // But we know that S60 systems below 5.0 did not support touch.
- static const bool touchIsUnsupportedOnSystem =
- QSysInfo::s60Version() == QSysInfo::SV_S60_3_1
- || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2;
- TInt machineUID;
- TInt mouse;
- TInt touch;
- TInt err;
- err = HAL::Get(HALData::EMouse, mouse);
- if (err != KErrNone)
- mouse = 0;
- err = HAL::Get(HALData::EMachineUid, machineUID);
- if (err != KErrNone)
- machineUID = 0;
- err = HAL::Get(HALData::EPen, touch);
- if (err != KErrNone || touchIsUnsupportedOnSystem)
- touch = 0;
-#ifdef __WINS__
- if(QSysInfo::symbianVersion() <= QSysInfo::SV_9_4) {
- //for symbian SDK emulator, force values to match typical devices.
- mouse = 0;
- touch = touchIsUnsupportedOnSystem ? 0 : 1;
- }
-#endif
- if (mouse || machineUID == KMachineUidSamsungI8510) {
- S60->hasTouchscreen = false;
- S60->virtualMouseRequired = false;
- }
- else if (!touch) {
- S60->hasTouchscreen = false;
- S60->virtualMouseRequired = true;
- }
- else {
- S60->hasTouchscreen = true;
- S60->virtualMouseRequired = false;
- }
-
- S60->avkonComponentsSupportTransparency = false;
- S60->menuBeingConstructed = false;
-
-#ifdef Q_WS_S60
- TUid KCRUidAvkon = { 0x101F876E };
- TUint32 KAknAvkonTransparencyEnabled = 0x0000000D;
-
- CRepository* repository = 0;
- TRAP(err, repository = CRepository::NewL(KCRUidAvkon));
-
- if(err == KErrNone) {
- TInt value = 0;
- err = repository->Get(KAknAvkonTransparencyEnabled, value);
- if(err == KErrNone) {
- S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
- }
- }
- delete repository;
- repository = 0;
-#endif
-
- qt_keymapper_private()->updateInputLanguage();
-
-#ifdef QT_KEYPAD_NAVIGATION
- if (touch) {
- QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
- } else {
- QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
- }
-#endif
-
-#ifndef QT_NO_CURSOR
- //Check if window server pointer cursors are supported or not
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- //In generic binary, use the HAL and OS version
- //Any other known good phones should be added here.
- if (machineUID == KMachineUidSamsungI8510 || (QSysInfo::symbianVersion() != QSysInfo::SV_9_4
- && QSysInfo::symbianVersion() != QSysInfo::SV_9_3 && QSysInfo::symbianVersion()
- != QSysInfo::SV_9_2)) {
- S60->brokenPointerCursors = false;
- qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
- }
- else
- S60->brokenPointerCursors = true;
-#endif
-
- if (S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors) {
- qt_symbian_set_pointer_sprite(Qt::ArrowCursor);
- qt_symbian_show_pointer_sprite();
- }
- else
-#endif
- S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
- }
-#endif
-
- QFont systemFont;
- systemFont.setFamily(systemFont.defaultFamily());
- QApplicationPrivate::setSystemFont(systemFont);
-
- QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
-
-#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
-
- const TUid KIvePropertyCat = {0x2726beef};
- enum TIvePropertyChipType {
- EVCBCM2727B1 = 0x00000000,
- EVCBCM2763A0 = 0x04000100,
- EVCBCM2763B0 = 0x04000102,
- EVCBCM2763C0 = 0x04000103,
- EVCBCM2763C1 = 0x04000104,
- EVCBCMUnknown = 0x7fffffff
- };
-
- TInt chipType = EVCBCMUnknown;
- if (RProperty::Get(KIvePropertyCat, 0 /*chip type*/, chipType) == KErrNone) {
- if (chipType == EVCBCM2727B1) {
- // We have only 32MB GPU memory. Use raster surfaces
- // for transparent TLWs.
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
- }
- } else {
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
- }
- if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
-#else
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
-#endif
-/*
- ### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
- int argc = priv->argc;
- char **argv = priv->argv;
-
- // Get command line params
- int j = argc ? 1 : 0;
- for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
-
-#if defined(QT_DEBUG)
- if (qstrcmp(argv[i], "-nograb") == 0)
- appNoGrab = !appNoGrab;
- else
-#endif // QT_DEBUG
- ;
- }
-*/
-
- // Register WId with the metatype system. This is to enable
- // QWidgetPrivate::create_sys to used delayed slot invocation in order
- // to destroy WId objects during reparenting.
- qRegisterMetaType<WId>("WId");
-}
-
-#ifdef QT_NO_FREETYPE
-extern void qt_cleanup_symbianFontDatabase(); // qfontdatabase_s60.cpp
-#endif
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-void qt_cleanup()
-{
-#ifdef Q_WS_S60
- S60->setButtonGroupContainer(0);
-#endif
- if(qt_S60Beep) {
- delete qt_S60Beep;
- qt_S60Beep = 0;
- }
- QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles
- QPixmapCache::clear(); // Has to happen now, since QS60PixmapData has FBS handles
-
-#ifdef QT_NO_FREETYPE
- qt_cleanup_symbianFontDatabase();
-#endif
-// S60 structure and window server session are freed in eventdispatcher destructor as they are needed there
-
- // It's important that this happens here, before the event dispatcher gets
- // deleted, because the input context needs the event loop one last time before
- // it dies.
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-
- //Change mouse pointer back
- S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
-
-#ifdef Q_WS_S60
- // Clear CBA
- CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(0);
- delete S60->buttonGroupContainer();
- S60->setButtonGroupContainer(0);
-#endif
-
- // Call EndFullScreen() to prevent confusing the system effect state machine.
- qt_endFullScreenEffect();
-
- if (S60->qtOwnsS60Environment) {
- // Restore the S60 framework trap handler. See qt_init().
- User::SetTrapHandler(S60->s60InstalledTrapHandler);
-
- CEikonEnv* coe = CEikonEnv::Static();
- coe->PrepareToExit();
- // The CEikonEnv itself is destroyed in here.
- coe->DestroyEnvironment();
- }
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
- // TODO: Implement QApplicationPrivate::initializeWidgetPaletteHash()
- // Possibly a task fot the S60Style guys
-}
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
- eventDispatcher = new QEventDispatcherS60(q);
-}
-
-QString QApplicationPrivate::appName() const
-{
- return QCoreApplicationPrivate::appName();
-}
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeEnter);
-#endif
- if (widget) {
- static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue);
- // Modal partial screen dialogs (like queries) capture pointer events.
- // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
- widget->effectiveWinId()->SetGloballyCapturing(ETrue);
- widget->effectiveWinId()->SetPointerCapture(ETrue);
- }
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
- qt_modal_stack->insert(0, widget);
- app_do_modal = true;
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget)
-{
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeExit);
-#endif
- if (widget) {
- static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
- // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
- widget->effectiveWinId()->SetGloballyCapturing(EFalse);
- widget->effectiveWinId()->SetPointerCapture(EFalse);
- }
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- }
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
- static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(ETrue);
-
- if (!QApplicationPrivate::popupWidgets)
- QApplicationPrivate::popupWidgets = new QWidgetList;
- QApplicationPrivate::popupWidgets->append(popup);
-
- // Cancel focus widget pointer capture and long tap timer
- if (QApplication::focusWidget()) {
- static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
- QApplication::focusWidget()->effectiveWinId()->SetPointerCapture(false);
- }
-
- if (!qt_nograb()) {
- // Cancel pointer capture and long tap timer for earlier popup
- int popupCount = QApplicationPrivate::popupWidgets->count();
- if (popupCount > 1) {
- QWidget* prevPopup = QApplicationPrivate::popupWidgets->at(popupCount-2);
- static_cast<QSymbianControl*>(prevPopup->effectiveWinId())->CancelLongTapTimer();
- prevPopup->effectiveWinId()->SetPointerCapture(false);
- }
-
- // Enable pointer capture for this (topmost) popup
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- WId id = popup->effectiveWinId();
- id->SetPointerCapture(true);
- }
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- QWidget *fw = popup->focusWidget();
- if (fw) {
- fw->setFocus(Qt::PopupFocusReason);
- } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
- fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- q_func()->sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
- static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse);
-
- if (!QApplicationPrivate::popupWidgets)
- return;
- QApplicationPrivate::popupWidgets->removeAll(popup);
-
- // Cancel pointer capture and long tap for this popup
- WId id = popup->effectiveWinId();
- id->SetPointerCapture(false);
- static_cast<QSymbianControl*>(id)->CancelLongTapTimer();
-
- if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
- if (!qt_nograb()) { // grabbing not disabled
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- if (QWidgetPrivate::mouseGrabber != 0)
- QWidgetPrivate::mouseGrabber->grabMouse();
-
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
-
- QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
- : q_func()->focusWidget();
- if (fw) {
- if(fw->window()->isModal()) // restore pointer capture for modal window
- fw->effectiveWinId()->SetPointerCapture(true);
-
- if (fw != q_func()->focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- q_func()->sendEvent(fw, &e);
- }
- }
- }
- } else {
-
- // popups are not focus-handled by the window system (the
- // first popup grabbed the keyboard), so we have to do that
- // manually: A popup was closed, so the previous popup gets
- // the focus.
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- q_func()->sendEvent(fw, &e);
- }
-
- // Enable pointer capture for previous popup
- if (aw) {
- aw->effectiveWinId()->SetPointerCapture(true);
- }
- }
-}
-
-QWidget * QApplication::topLevelAt(QPoint const& point)
-{
- QWidget *found = 0;
- int lowestZ = INT_MAX;
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; i < list.count(); ++i) {
- QWidget *widget = list.at(i);
- if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- if (widget->geometry().adjusted(0,0,1,1).contains(point)) {
- // At this point we know there is a Qt widget under the point.
- // Now we need to make sure it is the top most in the z-order.
- RDrawableWindow *const window = widget->effectiveWinId()->DrawableWindow();
- int z = window->OrdinalPosition();
- if (z < lowestZ) {
- lowestZ = z;
- found = widget;
- }
- }
- }
- }
- return found;
-}
-
-void QApplication::alert(QWidget * /* widget */, int /* duration */)
-{
- // TODO: Implement QApplication::alert(QWidget *widget, int duration)
-}
-
-int QApplication::doubleClickInterval()
-{
- TTimeIntervalMicroSeconds32 us;
- TInt distance;
- S60->wsSession().GetDoubleClickSettings(us, distance);
- return (us.Int() / 1000);
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- TTimeIntervalMicroSeconds32 newUs( ms * 1000);
- TTimeIntervalMicroSeconds32 us;
- TInt distance;
- S60->wsSession().GetDoubleClickSettings(us, distance);
- if (us != newUs)
- S60->wsSession().SetDoubleClick(newUs, distance);
-}
-
-int QApplication::keyboardInputInterval()
-{
- return QApplicationPrivate::keyboard_input_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-void QApplication::beep()
-{
- if (!qt_S60Beep) {
- TInt frequency = 880;
- TTimeIntervalMicroSeconds duration(500000);
- TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration));
- }
- if (qt_S60Beep)
- qt_S60Beep->Play();
-}
-
-static inline bool callSymbianEventFilters(const QSymbianEvent *event)
-{
- long unused;
- return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
-}
-
-/*!
- \warning This function is only available on Symbian.
- \since 4.6
-
- This function processes an individual Symbian event
- \a event. It returns 1 if the event was handled, 0 if
- the \a event was not handled, and -1 if the event was
- not handled because the event is not known to Qt.
- */
-
-int QApplication::symbianProcessEvent(const QSymbianEvent *event)
-{
- Q_D(QApplication);
-
- QScopedLoopLevelCounter counter(d->threadData);
-
- if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
- return 1;
-
- QWidget *w = qApp ? qApp->focusWidget() : 0;
- if (w) {
- QInputContext *ic = w->inputContext();
- if (ic && ic->symbianFilterEvent(w, event))
- return 1;
- }
-
- if (symbianEventFilter(event))
- return 1;
-
- switch (event->type()) {
- case QSymbianEvent::WindowServerEvent:
- return d->symbianProcessWsEvent(event);
- case QSymbianEvent::CommandEvent:
- return d->symbianHandleCommand(event);
- case QSymbianEvent::ResourceChangeEvent:
- return d->symbianResourceChange(event);
- default:
- return -1;
- }
-}
-
-int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
-{
- // Qt event handling. Handle some events regardless of if the handle is in our
- // widget map or not.
- const TWsEvent *event = symbianEvent->windowServerEvent();
- CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
- const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
- switch (event->Type()) {
- case EEventPointerEnter:
- if (controlInMap) {
- callSymbianEventFilters(symbianEvent);
- return 1; // Qt::Enter will be generated in HandlePointerL
- }
- break;
- case EEventPointerExit:
- if (controlInMap) {
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (S60) {
- // mouseEvent outside our window, send leave event to last focused widget
- QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
- Qt::NoButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
- if (S60->lastPointerEventTarget)
- qt_sendSpontaneousEvent(S60->lastPointerEventTarget,&mEvent);
- S60->lastPointerEventTarget = 0;
- }
- return 1;
- }
- break;
- case EEventScreenDeviceChanged: // fallthrough
-#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
- case EEventDisplayChanged:
-#endif
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (S60)
- S60->updateScreenSize();
- if (qt_desktopWidget) {
- QSize oldSize = qt_desktopWidget->size();
- qt_desktopWidget->data->crect.setWidth(S60->screenWidthInPixels);
- qt_desktopWidget->data->crect.setHeight(S60->screenHeightInPixels);
- QResizeEvent e(qt_desktopWidget->size(), oldSize);
- QApplication::sendEvent(qt_desktopWidget, &e);
- }
- return 0; // Propagate to CONE
- case EEventWindowVisibilityChanged:
- if (controlInMap) {
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
- if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible)
- S60->controlVisibilityChanged(control, false);
- else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
- S60->controlVisibilityChanged(control, true);
- return 1;
- }
- break;
- case EEventFocusGained:
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifndef QT_NO_CURSOR
- //re-enable mouse interaction
- if (S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_show_pointer_sprite();
- else
-#endif
- S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
- }
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- if (!CEikonEnv::Static()->EikAppUi()->IsDisplayingMenuOrDialog())
- QSoftKeyManager::updateSoftKeys();
-#endif
- break;
- case EEventFocusLost:
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifndef QT_NO_CURSOR
- //disable mouse as may be moving to application that does not support it
- if (S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_hide_pointer_sprite();
- else
-#endif
- S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
- }
-#endif
- break;
- case KGoomMemoryLowEvent:
-#ifdef QT_DEBUG
- qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryLowEvent";
-#endif
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if(QApplicationPrivate::runtime_graphics_system) {
- bool switchToSwRendering(false);
-
- foreach (QWidget *w, QApplication::topLevelWidgets()) {
- if(w->d_func()->topData()->backingStore) {
- switchToSwRendering = true;
- break;
- }
- }
-
- if (switchToSwRendering) {
- QRuntimeGraphicsSystem *gs =
- static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
- gs->setGraphicsSystem(QLatin1String("raster"));
- }
- }
-#endif
- break;
- case KGoomMemoryGoodEvent:
-#ifdef QT_DEBUG
- qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryGoodEvent";
-#endif
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if(QApplicationPrivate::runtime_graphics_system) {
- QRuntimeGraphicsSystem *gs =
- static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
- gs->setGraphicsSystem(QLatin1String("openvg"));
- }
-#endif
- break;
-#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
- case EEventUser:
- {
- // GOOM is looking for candidates to kill so indicate that we are
- // capable of cleaning up by handling this event
- TInt32 *data = reinterpret_cast<TInt32 *>(event->EventData());
- if (data[0] == EApaSystemEventShutdown && data[1] == KGoomMemoryLowEvent)
- return 1;
- }
- break;
-#endif
-
-#ifdef Q_WS_S60
- case KEikInputLanguageChange:
- qt_keymapper_private()->updateInputLanguage();
- break;
-#endif
-
- default:
- break;
- }
-
- if (!controlInMap)
- return -1;
-
- return 0;
-}
-
-/*!
- \warning This virtual function is only available on Symbian.
- \since 4.6
-
- If you create an application that inherits QApplication and reimplement
- this function, you get direct access to events that the are received
- from Symbian. The events are passed in the \a event parameter.
-
- Return true if you want to stop the event from being processed. Return
- false for normal event dispatching. The default implementation returns
- false, and does nothing with \a event.
- */
-bool QApplication::symbianEventFilter(const QSymbianEvent *event)
-{
- Q_UNUSED(event);
- return false;
-}
-
-/*!
- \warning This function is only available on Symbian.
- \since 4.6
-
- Handles \a{command}s which are typically handled by
- CAknAppUi::HandleCommandL(). Qts Ui integration into Symbian is
- partially achieved by deriving from CAknAppUi. Currently, exit,
- menu and softkey commands are handled.
-
- \sa s60EventFilter(), s60ProcessEvent()
-*/
-int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
-{
- Q_Q(QApplication);
- int ret = 0;
-
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-
- int command = symbianEvent->command();
-
- switch (command) {
-#ifdef Q_WS_S60
- case EAknSoftkeyExit: {
- QCloseEvent ev;
- QApplication::sendSpontaneousEvent(q, &ev);
- if (ev.isAccepted()) {
- q->quit();
- ret = 1;
- }
- break;
- }
-#endif
- case EEikCmdExit:
- q->quit();
- ret = 1;
- break;
- default:
-#ifdef Q_WS_S60
- bool handled = QSoftKeyManager::handleCommand(command);
- if (handled)
- ret = 1;
- else
- ret = QMenuBarPrivate::symbianCommands(command);
-#endif
- break;
- }
-
- return ret;
-}
-
-/*!
- \warning This function is only available on Symbian.
- \since 4.6
-
- Handles the resource change specified by \a type.
-
- Currently, KEikDynamicLayoutVariantSwitch and
- KAknsMessageSkinChange are handled.
- */
-int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
-{
- int ret = 0;
-
- int type = symbianEvent->resourceChangeType();
-
- switch (type) {
-#ifdef Q_WS_S60
- case KEikDynamicLayoutVariantSwitch:
- {
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (S60)
- S60->updateScreenSize();
-
-#ifndef QT_NO_STYLE_S60
- QS60Style *s60Style = 0;
-
-#ifndef QT_NO_STYLE_STYLESHEET
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplication::style());
- if (proxy)
- s60Style = qobject_cast<QS60Style*>(proxy->baseStyle());
- else
-#endif
- s60Style = qobject_cast<QS60Style*>(QApplication::style());
-
- if (s60Style) {
- s60Style->d_func()->handleDynamicLayoutVariantSwitch();
- ret = 1;
- }
-#endif
- }
- break;
-
-#ifndef QT_NO_STYLE_S60
- case KAknsMessageSkinChange:
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
- s60Style->d_func()->handleSkinChange();
- ret = 1;
- }
- break;
-#endif
-#endif // Q_WS_S60
- default:
- break;
- }
-
- return ret;
-}
-
-#ifndef QT_NO_WHEELEVENT
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-
-void QApplication::setWheelScrollLines(int n)
-{
- QApplicationPrivate::wheel_scroll_lines = n;
-}
-#endif //QT_NO_WHEELEVENT
-
-bool QApplication::isEffectEnabled(Qt::UIEffect /* effect */)
-{
- // TODO: Implement QApplication::isEffectEnabled(Qt::UIEffect effect)
- return false;
-}
-
-void QApplication::setEffectEnabled(Qt::UIEffect /* effect */, bool /* enable */)
-{
- // TODO: Implement QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-}
-
-TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym)
-{
- if (!scanCode)
- return keysym;
-
- QApplicationPrivate *d = QApplicationPrivate::instance();
-
- if (keysym) {
- // If keysym is specified, cache it.
- d->scanCodeCache.insert(scanCode, keysym);
- return keysym;
- } else {
- // If not, retrieve the cached version.
- return d->scanCodeCache[scanCode];
- }
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- if (HAL::Get(HALData::EPointer3DPressureSupported, pressureSupported) != KErrNone)
- pressureSupported = 0;
- if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone)
- maxTouchPressure = KMaxTInt;
-#else
- pressureSupported = 0;
- maxTouchPressure = KMaxTInt;
-#endif
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{ }
-
-#ifndef QT_NO_SESSIONMANAGER
-QSessionManager::QSessionManager(QApplication * /* app */, QString & /* id */, QString& /* key */)
-{
-
-}
-
-QSessionManager::~QSessionManager()
-{
-
-}
-
-bool QSessionManager::allowsInteraction()
-{
- return false;
-}
-
-void QSessionManager::cancel()
-{
-
-}
-#endif //QT_NO_SESSIONMANAGER
-
-#ifdef QT_KEYPAD_NAVIGATION
-/*
- * Show/Hide the mouse cursor depending on phone type and chosen mode
- */
-void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode)
-{
-#ifndef QT_NO_CURSOR
- const bool wasCursorOn = (QApplicationPrivate::navigationMode == Qt::NavigationModeCursorAuto
- && !S60->hasTouchscreen)
- || QApplicationPrivate::navigationMode == Qt::NavigationModeCursorForceVisible;
- const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto
- && !S60->hasTouchscreen)
- || mode == Qt::NavigationModeCursorForceVisible;
-
- if (!wasCursorOn && isCursorOn) {
- //Show the cursor, when changing from another mode to cursor mode
- qt_symbian_set_cursor_visible(true);
- }
- else if (wasCursorOn && !isCursorOn) {
- //Hide the cursor, when leaving cursor mode
- qt_symbian_set_cursor_visible(false);
- }
-#endif
- QApplicationPrivate::navigationMode = mode;
-}
-#endif
-
-#ifndef QT_NO_CURSOR
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
- qt_symbian_setGlobalCursor(cursor);
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
- if (!qApp->d_func()->cursor_list.isEmpty()) {
- qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first());
- }
- else {
- //determine which widget has focus
- QWidget *w = QApplication::widgetAt(QCursor::pos());
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors) {
- qt_symbian_set_pointer_sprite(w ? w->cursor() : Qt::ArrowCursor);
- }
- else
-#endif
- {
- //because of the internals of window server, we need to force the cursor
- //to be set in all child windows too, otherwise when the cursor is over
- //the child window it may show a widget cursor or arrow cursor instead,
- //depending on construction order.
- QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
- while (iter.hasNext()) {
- CCoeControl *ctrl = iter.next();
- if(ctrl->OwnsWindow()) {
- ctrl->DrawableWindow()->ClearPointerCursor();
- }
- }
- if (w)
- qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId());
- else
- qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
- }
- }
-}
-
-#endif // QT_NO_CURSOR
-
-void QApplicationPrivate::_q_aboutToQuit()
-{
- qt_beginFullScreenEffect();
-
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- // Send the shutdown tfx command
- S60->wsSession().SendEffectCommand(ETfxCmdAppShutDown);
-#endif
-}
-
-QS60ThreadLocalData::QS60ThreadLocalData()
-{
- CCoeEnv *env = CCoeEnv::Static();
- if (env) {
- //if this is the UI thread, share objects owned by CONE
- usingCONEinstances = true;
- wsSession = env->WsSession();
- screenDevice = env->ScreenDevice();
- }
- else {
- usingCONEinstances = false;
- qt_symbian_throwIfError(wsSession.Connect(qt_s60GetRFs()));
- screenDevice = new CWsScreenDevice(wsSession);
- screenDevice->Construct();
- }
-}
-
-QS60ThreadLocalData::~QS60ThreadLocalData()
-{
- for (int i = 0; i < releaseFuncs.count(); ++i)
- releaseFuncs[i]();
- releaseFuncs.clear();
- if (!usingCONEinstances) {
- delete screenDevice;
- wsSession.Close();
- }
-}
-
-QT_END_NAMESPACE