First stab at stem_QtGui.dll - nasty, nasty, nasty
authorWilliam Roberts <williamr@symbian.org>
Mon, 18 Oct 2010 17:18:49 +0100
changeset 136 4c8d6b2fb1da
parent 66 fc9981c83de7
First stab at stem_QtGui.dll - nasty, nasty, nasty
breakdeps/gui/gui.pro
breakdeps/gui/kernel/kernel.pri
breakdeps/gui/kernel/qapplication_s60.cpp
breakdeps/gui/kernel/qsound_s60.cpp
breakdeps/gui/prepare_qt.cmd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/gui/gui.pro	Mon Oct 18 17:18:49 2010 +0100
@@ -0,0 +1,83 @@
+TARGET     = stem_QtGui
+VPATH      = /sf/mw/qt/src/gui
+MMP_RULES += NOEXPORTLIBRARY
+defBlock = "deffile /sf/mw/qt/src/s60installs/~/QtGui.def"
+MMP_RULES += defBlock
+
+
+QPRO_PWD   = $$PWD
+
+QT = core
+DEFINES   += QT_BUILD_GUI_LIB QT_NO_USING_NAMESPACE
+win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
+
+!win32:!embedded:!mac:!symbian:CONFIG      += x11
+
+unix:QMAKE_PKGCONFIG_REQUIRES = QtCore
+
+include(/sf/mw/qt/src/qbase.pri)
+
+contains(QT_CONFIG, x11sm):CONFIG += x11sm
+
+#platforms
+x11:include(kernel/x11.pri)
+mac:include(kernel/mac.pri)
+win32:include(kernel/win.pri)
+embedded:include(embedded/embedded.pri)
+symbian {
+    include(/sf/mw/qt/src/gui/kernel/symbian.pri)
+    # include(/sf/mw/qt/src/gui/s60framework/s60framework.pri)
+}
+
+#modules
+include(/sf/mw/qt/src/gui/animation/animation.pri)
+include(kernel/kernel.pri)
+include(/sf/mw/qt/src/gui/image/image.pri)
+include(/sf/mw/qt/src/gui/painting/painting.pri)
+include(/sf/mw/qt/src/gui/text/text.pri)
+include(/sf/mw/qt/src/gui/styles/styles.pri)
+include(/sf/mw/qt/src/gui/widgets/widgets.pri)
+include(/sf/mw/qt/src/gui/dialogs/dialogs.pri)
+include(/sf/mw/qt/src/gui/accessible/accessible.pri)
+include(/sf/mw/qt/src/gui/itemviews/itemviews.pri)
+include(/sf/mw/qt/src/gui/inputmethod/inputmethod.pri)
+include(/sf/mw/qt/src/gui/graphicsview/graphicsview.pri)
+include(/sf/mw/qt/src/gui/util/util.pri)
+include(/sf/mw/qt/src/gui/statemachine/statemachine.pri)
+include(/sf/mw/qt/src/gui/math3d/math3d.pri)
+include(/sf/mw/qt/src/gui/effects/effects.pri)
+
+contains(QT_CONFIG, egl): include(/sf/mw/qt/src/gui/egl/egl.pri)
+
+embedded: QT += network
+
+QMAKE_LIBS += $$QMAKE_LIBS_GUI
+
+contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
+
+QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
+
+DEFINES += Q_INTERNAL_QAPP_SRC
+symbian: {
+    TARGET.UID3=0x2001B2DD
+
+    # ro-section in gui can exceed default allocated space, so move rw-section a little further
+    QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
+    QMAKE_LFLAGS.GCCE += -Tdata 0xC00000
+
+    # Partial upgrade SIS file
+    vendorinfo = \
+        "; Localised Vendor name" \
+        "%{\"Nokia, Qt\"}" \
+        " " \
+        "; Unique Vendor name" \
+        ":\"Nokia, Qt\"" \
+        " "
+    pu_header = "; Partial upgrade package for testing QtGui changes without reinstalling everything" \
+                "$${LITERAL_HASH}{\"Qt gui\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU"
+    partial_upgrade.pkg_prerules = pu_header vendorinfo
+    partial_upgrade.sources = qtgui.dll
+    partial_upgrade.path = c:/sys/bin
+    DEPLOYMENT = partial_upgrade $$DEPLOYMENT
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/gui/kernel/kernel.pri	Mon Oct 18 17:18:49 2010 +0100
@@ -0,0 +1,260 @@
+# Qt kernel module
+
+# Only used on platforms with CONFIG += precompile_header
+PRECOMPILED_HEADER = kernel/qt_gui_pch.h
+
+
+KERNEL_P= kernel
+HEADERS += \
+	kernel/qaction.h \
+    kernel/qaction_p.h \
+	kernel/qactiongroup.h \
+	kernel/qapplication.h \
+	kernel/qapplication_p.h \
+	kernel/qboxlayout.h \
+	kernel/qclipboard.h \
+	kernel/qcursor.h \
+	kernel/qdesktopwidget.h \
+	kernel/qdrag.h \
+	kernel/qdnd_p.h \
+	kernel/qevent.h \
+	kernel/qevent_p.h \
+	kernel/qformlayout.h \
+	kernel/qgridlayout.h \
+	kernel/qkeysequence.h \
+	kernel/qlayout.h \
+	kernel/qlayout_p.h \
+	kernel/qlayoutengine_p.h \
+	kernel/qlayoutitem.h \
+	kernel/qmime.h \
+	kernel/qsessionmanager.h \
+	kernel/qshortcut.h \
+	kernel/qshortcutmap_p.h \
+	kernel/qsizepolicy.h \
+	kernel/qpalette.h \
+	kernel/qsound.h \
+	kernel/qsound_p.h \
+	kernel/qstackedlayout.h \
+	kernel/qtooltip.h \
+	kernel/qwhatsthis.h \
+    kernel/qwidget.h \
+    kernel/qwidget_p.h \
+	kernel/qwidgetaction.h \
+	kernel/qwidgetaction_p.h \
+	kernel/qwindowdefs.h \
+	kernel/qkeymapper_p.h \
+	kernel/qgesture.h \
+	kernel/qgesture_p.h \
+	kernel/qstandardgestures_p.h \
+	kernel/qgesturerecognizer.h \
+	kernel/qgesturemanager_p.h \
+	kernel/qsoftkeymanager_p.h \
+    kernel/qsoftkeymanager_common_p.h \
+	kernel/qguiplatformplugin_p.h
+
+SOURCES += \
+	kernel/qaction.cpp \
+	kernel/qactiongroup.cpp \
+	kernel/qapplication.cpp \
+	kernel/qboxlayout.cpp \
+	kernel/qclipboard.cpp \
+	kernel/qcursor.cpp \
+	kernel/qdrag.cpp \
+	kernel/qdnd.cpp \
+	kernel/qevent.cpp \
+	kernel/qformlayout.cpp \
+	kernel/qgridlayout.cpp \
+	kernel/qkeysequence.cpp \
+	kernel/qlayout.cpp \
+	kernel/qlayoutengine.cpp \
+	kernel/qlayoutitem.cpp \
+	kernel/qmime.cpp \
+	kernel/qpalette.cpp \
+	kernel/qshortcut.cpp \
+	kernel/qshortcutmap.cpp \
+	kernel/qsound.cpp \
+	kernel/qstackedlayout.cpp \
+	kernel/qtooltip.cpp \
+	kernel/qguivariant.cpp \
+	kernel/qwhatsthis.cpp \
+	kernel/qwidget.cpp \
+	kernel/qwidgetaction.cpp \
+	kernel/qkeymapper.cpp \
+	kernel/qgesture.cpp \
+	kernel/qstandardgestures.cpp \
+	kernel/qgesturerecognizer.cpp \
+	kernel/qgesturemanager.cpp \
+	kernel/qsoftkeymanager.cpp \
+    kernel/qdesktopwidget.cpp \
+	kernel/qguiplatformplugin.cpp
+
+win32 {
+	DEFINES += QT_NO_DIRECTDRAW
+
+    HEADERS += \
+        kernel/qwinnativepangesturerecognizer_win_p.h
+
+	SOURCES += \
+		kernel/qapplication_win.cpp \
+		kernel/qclipboard_win.cpp \
+		kernel/qcursor_win.cpp \
+		kernel/qdesktopwidget_win.cpp \
+		kernel/qdnd_win.cpp \
+		kernel/qmime_win.cpp \
+		kernel/qsound_win.cpp \
+		kernel/qwidget_win.cpp \
+		kernel/qole_win.cpp \
+        kernel/qkeymapper_win.cpp \
+        kernel/qwinnativepangesturerecognizer_win.cpp
+
+    !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib
+}
+
+symbian {
+    SOURCES += \
+        kernel/qapplication_s60.cpp \
+        kernel/qeventdispatcher_s60.cpp \
+        kernel/qwidget_s60.cpp \
+        kernel/qcursor_s60.cpp \
+        kernel/qdesktopwidget_s60.cpp \
+        kernel/qkeymapper_s60.cpp\
+        kernel/qclipboard_s60.cpp\
+        kernel/qdnd_s60.cpp \
+        kernel/qsound_s60.cpp \
+        kernel/qsoftkeymanager_s60.cpp
+
+    HEADERS += \
+        kernel/qt_s60_p.h \
+        kernel/qeventdispatcher_s60_p.h \
+        kernel/qsoftkeymanager_s60_p.h
+
+    LIBS += -lbafl -lestor
+
+    INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+    INCLUDEPATH += ../3rdparty/s60
+}
+
+
+unix:x11 {
+	INCLUDEPATH += ../3rdparty/xorg
+	HEADERS += \
+		kernel/qx11embed_x11.h \
+		kernel/qx11info_x11.h \
+        kernel/qkde_p.h
+
+	SOURCES += \
+		kernel/qapplication_x11.cpp \
+		kernel/qclipboard_x11.cpp \
+		kernel/qcursor_x11.cpp \
+		kernel/qdnd_x11.cpp \
+		kernel/qdesktopwidget_x11.cpp \
+		kernel/qmotifdnd_x11.cpp \
+		kernel/qsound_x11.cpp \
+		kernel/qwidget_x11.cpp \
+		kernel/qwidgetcreate_x11.cpp \
+		kernel/qx11embed_x11.cpp \
+		kernel/qx11info_x11.cpp \
+		kernel/qkeymapper_x11.cpp \
+		kernel/qkde.cpp
+
+        contains(QT_CONFIG, glib) {
+            SOURCES += \
+		kernel/qguieventdispatcher_glib.cpp
+            HEADERS += \
+                kernel/qguieventdispatcher_glib_p.h
+            QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
+	    LIBS_PRIVATE +=$$QT_LIBS_GLIB
+	}
+            SOURCES += \
+		kernel/qeventdispatcher_x11.cpp
+            HEADERS += \
+                kernel/qeventdispatcher_x11_p.h
+}
+
+embedded {
+	HEADERS += \
+		kernel/qeventdispatcher_qws_p.h
+
+	SOURCES += \
+		kernel/qapplication_qws.cpp \
+		kernel/qclipboard_qws.cpp \
+		kernel/qcursor_qws.cpp \
+		kernel/qdesktopwidget_qws.cpp \
+		kernel/qdnd_qws.cpp \
+		kernel/qeventdispatcher_qws.cpp \
+		kernel/qsound_qws.cpp \
+		kernel/qwidget_qws.cpp \
+		kernel/qkeymapper_qws.cpp \
+		kernel/qsessionmanager_qws.cpp
+
+        contains(QT_CONFIG, glib) {
+            SOURCES += \
+		kernel/qeventdispatcher_glib_qws.cpp
+            HEADERS += \
+                kernel/qeventdispatcher_glib_qws_p.h
+            QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
+            LIBS_PRIVATE +=$$QT_LIBS_GLIB
+	}
+}
+
+!embedded:!x11:mac {
+	SOURCES += \
+		kernel/qclipboard_mac.cpp \
+		kernel/qmime_mac.cpp \
+		kernel/qt_mac.cpp \
+		kernel/qkeymapper_mac.cpp
+
+        OBJECTIVE_HEADERS += \
+                qcocoawindow_mac_p.h \
+                qcocoawindowdelegate_mac_p.h \
+                qcocoaview_mac_p.h \
+                qcocoaapplication_mac_p.h \
+                qcocoaapplicationdelegate_mac_p.h \
+                qmacgesturerecognizer_mac_p.h \
+                qmultitouch_mac_p.h \
+                qcocoasharedwindowmethods_mac_p.h
+
+        OBJECTIVE_SOURCES += \
+                kernel/qcursor_mac.mm \
+                kernel/qdnd_mac.mm \
+                kernel/qsound_mac.mm  \
+                kernel/qapplication_mac.mm \
+		        kernel/qwidget_mac.mm \
+		        kernel/qcocoapanel_mac.mm \
+                kernel/qcocoaview_mac.mm \
+                kernel/qcocoawindow_mac.mm \
+                kernel/qcocoawindowdelegate_mac.mm \
+                kernel/qcocoamenuloader_mac.mm \
+                kernel/qcocoaapplication_mac.mm \
+                kernel/qcocoaapplicationdelegate_mac.mm \
+                kernel/qt_cocoa_helpers_mac.mm \
+                kernel/qdesktopwidget_mac.mm \
+                kernel/qeventdispatcher_mac.mm \
+                kernel/qcocoawindowcustomthemeframe_mac.mm \
+                kernel/qmacgesturerecognizer_mac.mm \
+                kernel/qmultitouch_mac.mm
+
+        HEADERS += \
+                kernel/qt_cocoa_helpers_mac_p.h \
+                kernel/qcocoaapplication_mac_p.h \
+                kernel/qcocoaapplicationdelegate_mac_p.h \
+                kernel/qeventdispatcher_mac_p.h
+
+        MENU_NIB.files = mac/qt_menu.nib
+        MENU_NIB.path = Resources
+        MENU_NIB.version = Versions
+        QMAKE_BUNDLE_DATA += MENU_NIB
+        RESOURCES += mac/macresources.qrc
+
+        LIBS_PRIVATE += -framework AppKit
+}
+
+wince*: {
+        HEADERS += \
+                ../corelib/kernel/qfunctions_wince.h \
+                kernel/qguifunctions_wince.h
+
+        SOURCES += \
+                ../corelib/kernel/qfunctions_wince.cpp \
+                kernel/qguifunctions_wince.cpp
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/gui/kernel/qapplication_s60.cpp	Mon Oct 18 17:18:49 2010 +0100
@@ -0,0 +1,2034 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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"
+
+#include "apgwgnam.h" // For CApaWindowGroupName
+#include <mdaaudiotoneplayer.h>     // For CMdaAudioToneUtility
+
+#if defined(Q_WS_S60)
+# if !defined(QT_NO_IM)
+#  include "qinputcontext.h"
+#  include <private/qcoefepinputcontext_p.h>
+# endif
+# include <private/qs60mainapplication_p.h>
+# include <centralrepository.h>
+# include "qs60mainappui.h"
+#endif
+
+#include "private/qstylesheetstyle_p.h"
+
+#include <hal.h>
+#include <hal_data.h>
+
+QT_BEGIN_NAMESPACE
+
+#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();
+}
+
+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;
+}
+
+
+QHash<TInt, TUint> QApplicationPrivate::scanCodeCache;
+
+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)
+{
+}
+
+void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
+{
+    if (!desktop)
+    {
+        if (isWindowOwning or !qwidget->parentWidget())
+            CreateWindowL(S60->windowGroup());
+        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);
+
+        DrawableWindow()->SetPointerGrab(ETrue);
+    }
+}
+
+QSymbianControl::~QSymbianControl()
+{
+    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;
+}
+void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
+{
+    QWidget *alienWidget;
+    QPoint widgetPos = QPoint(aPenEventLocation.iX, aPenEventLocation.iY);
+    QPoint globalPos = QPoint(aPenEventScreenLocation.iX,aPenEventScreenLocation.iY);
+    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();
+
+    QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget);
+
+    while (d->appAllTouchPoints.count() <= event->PointerNumber())
+        d->appAllTouchPoints.append(QTouchEvent::TouchPoint(d->appAllTouchPoints.count()));
+
+    Qt::TouchPointStates allStates = 0;
+    for (int i = 0; i < d->appAllTouchPoints.count(); ++i) {
+        QTouchEvent::TouchPoint &touchPoint = d->appAllTouchPoints[i];
+
+        if (touchPoint.id() == event->PointerNumber()) {
+            Qt::TouchPointStates state;
+            switch (event->iType) {
+            case TPointerEvent::EButton1Down:
+            case TPointerEvent::EEnterHighPressure:
+                state = Qt::TouchPointPressed;
+                break;
+            case TPointerEvent::EButton1Up:
+            case TPointerEvent::EExitCloseProximity:
+                state = Qt::TouchPointReleased;
+                break;
+            case TPointerEvent::EDrag:
+                state = Qt::TouchPointMoved;
+                break;
+            default:
+                // how likely is this to happen?
+                state = Qt::TouchPointStationary;
+                break;
+            }
+            if (event->PointerNumber() == 0)
+                state |= Qt::TouchPointPrimary;
+            touchPoint.setState(state);
+
+            QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));
+            touchPoint.setScreenPos(screenPos);
+            touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
+                                                screenPos.y() / screenGeometry.height()));
+
+            touchPoint.setPressure(event->Pressure() / qreal(d->maxTouchPressure));
+        } else if (touchPoint.state() != Qt::TouchPointReleased) {
+            // all other active touch points should be marked as stationary
+            touchPoint.setState(Qt::TouchPointStationary);
+        }
+
+        allStates |= touchPoint.state();
+    }
+
+    if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
+        // all touch points released
+        d->appAllTouchPoints.clear();
+    }
+
+    QApplicationPrivate::translateRawTouchEvent(qwidget,
+                                                QTouchEvent::TouchScreen,
+                                                d->appAllTouchPoints);
+}
+#endif
+
+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 = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
+    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
+
+    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)
+{
+    switch (type) {
+    //case EEventKeyDown: // <-- Intentionally left out. See below.
+    case EEventKeyUp:
+    case EEventKey:
+    {
+        // S60 has a confusing way of delivering key events. There are three types of
+        // events: EKeyEvent, EKeyEventDown and EKeyEventUp. When a key is pressed, the
+        // two first events are generated. When releasing the key, the last one is
+        // generated.
+        // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp events,
+        // we need to do some special tricks to map it to the Qt way. First, we completely
+        // discard EKeyEventDown events, since they are redundant. Second, since
+        // EKeyEventUp does not give us a keysym, we need to cache the keysyms from
+        // the EKeyEvent events. This is what resolveS60ScanCode does.
+
+
+        // ### hackish way to send Qt application to background when pressing right softkey
+        /*
+        if( keyEvent.iScanCode == EStdKeyDevice1 ) {
+            S60->window_group->SetOrdinalPosition(-1);
+            qApp->setActiveWindow(0);
+            return EKeyWasNotConsumed;
+        }
+        */
+
+        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);
+        }
+
+#ifndef QT_NO_CURSOR
+        if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
+            //translate keys to pointer
+            if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) {
+                /*Explanation about virtualMouseAccel:
+                 Tapping an arrow key allows precise pixel positioning
+                 Holding an arrow key down, acceleration is applied to allow cursor
+                 to be quickly moved to another part of the screen by key repeats.
+                 */
+                if (S60->virtualMouseLastKey == keyCode) {
+                    S60->virtualMouseAccel *= 2;
+                    if (S60->virtualMouseAccel > S60->virtualMouseMaxAccel)
+                        S60->virtualMouseAccel = S60->virtualMouseMaxAccel;
+                }
+                else
+                    S60->virtualMouseAccel = 1;
+                S60->virtualMouseLastKey = keyCode;
+
+                QPoint pos = QCursor::pos();
+                TPointerEvent fakeEvent;
+                TInt x = pos.x();
+                TInt y = pos.y();
+                if (type == EEventKeyUp) {
+                    if (keyCode == Qt::Key_Select)
+                        fakeEvent.iType = TPointerEvent::EButton1Up;
+                    S60->virtualMouseAccel = 1;
+                    S60->virtualMouseLastKey = 0;
+                    switch (keyCode) {
+                    case Qt::Key_Left:
+                        S60->virtualMousePressedKeys &= ~QS60Data::Left;
+                        break;
+                    case Qt::Key_Right:
+                        S60->virtualMousePressedKeys &= ~QS60Data::Right;
+                        break;
+                    case Qt::Key_Up:
+                        S60->virtualMousePressedKeys &= ~QS60Data::Up;
+                        break;
+                    case Qt::Key_Down:
+                        S60->virtualMousePressedKeys &= ~QS60Data::Down;
+                        break;
+                    case Qt::Key_Select:
+                        S60->virtualMousePressedKeys &= ~QS60Data::Select;
+                        break;
+                    }
+                }
+                else if (type == EEventKey) {
+                    switch (keyCode) {
+                    case Qt::Key_Left:
+                        S60->virtualMousePressedKeys |= QS60Data::Left;
+                        x -= S60->virtualMouseAccel;
+                        fakeEvent.iType = TPointerEvent::EMove;
+                        break;
+                    case Qt::Key_Right:
+                        S60->virtualMousePressedKeys |= QS60Data::Right;
+                        x += S60->virtualMouseAccel;
+                        fakeEvent.iType = TPointerEvent::EMove;
+                        break;
+                    case Qt::Key_Up:
+                        S60->virtualMousePressedKeys |= QS60Data::Up;
+                        y -= S60->virtualMouseAccel;
+                        fakeEvent.iType = TPointerEvent::EMove;
+                        break;
+                    case Qt::Key_Down:
+                        S60->virtualMousePressedKeys |= QS60Data::Down;
+                        y += S60->virtualMouseAccel;
+                        fakeEvent.iType = TPointerEvent::EMove;
+                        break;
+                    case Qt::Key_Select:
+                        // 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 != 0) {
+                            S60->virtualMousePressedKeys |= QS60Data::Select;
+                            return EKeyWasConsumed;
+                        } else {
+                            S60->virtualMousePressedKeys |= QS60Data::Select;
+                            fakeEvent.iType = TPointerEvent::EButton1Down;
+                        }
+                        break;
+                    }
+                }
+                //clip to screen size (window server allows a sprite hotspot to be outside the screen)
+                if (x < 0)
+                    x = 0;
+                else if (x >= S60->screenWidthInPixels)
+                    x = S60->screenWidthInPixels - 1;
+                if (y < 0)
+                    y = 0;
+                else if (y >= S60->screenHeightInPixels)
+                    y = S60->screenHeightInPixels - 1;
+                TPoint epos(x, y);
+                TPoint cpos = epos - PositionRelativeToScreen();
+                fakeEvent.iModifiers = keyEvent.iModifiers;
+                fakeEvent.iPosition = cpos;
+                fakeEvent.iParentPosition = epos;
+                HandlePointerEvent(fakeEvent);
+                return EKeyWasConsumed;
+            }
+            else {
+                S60->virtualMouseLastKey = keyCode;
+                S60->virtualMouseAccel = 1;
+            }
+        }
+#endif
+
+        Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
+        QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode,
+                mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
+                (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
+//        WId wid = reinterpret_cast<RWindowGroup *>(keyEvent.Handle())->Child();
+//        if (!wid)
+//             Could happen if window isn't shown yet.
+//            return EKeyWasNotConsumed;
+        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);
+    }
+    }
+    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_WS_S60)
+
+    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);
+    if (!topExtra->inExpose) {
+        topExtra->inExpose = true;
+        QRect exposeRect = qt_TRect2QRect(controlRect);
+        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(controlRect);
+        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 = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
+        CFbsBitmap *bitmap = s60Surface->symbianBitmap();
+        CWindowGc &gc = SystemGc();
+
+        switch(qwidget->d_func()->extraData()->nativePaintMode) {
+        case QWExtra::Disable:
+            // Do nothing
+            break;
+
+        case QWExtra::Blit:
+            if (qwidget->d_func()->isOpaque)
+                gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+            gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
+            break;
+
+        case QWExtra::ZeroFill:
+            if (Window().DisplayMode() == EColor16MA) {
+                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(controlRect);
+        // 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::SizeChanged()
+{
+    CCoeControl::SizeChanged();
+
+    QSize oldSize = qwidget->size();
+    QSize newSize(Size().iWidth, Size().iHeight);
+
+    if (oldSize != newSize) {
+        QRect cr = qwidget->geometry();
+        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;
+        }
+    }
+
+    // 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;
+
+    // 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 widget is fullscreen/minimized, hide status pane and button container otherwise show them.
+        CEikStatusPane *statusPane = S60->statusPane();
+        CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
+        TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
+        if (statusPane)
+            statusPane->MakeVisible(visible);
+        if (buttonGroup) {
+            // Visibility
+            const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+            const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+            buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint));
+
+            // Responsiviness
+            CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
+            TUint cbaFlags = cba->ButtonGroupFlags();
+            if(qwidget->windowFlags() & Qt::WindowSoftkeysRespondHint)
+                cbaFlags |= EAknCBAFlagRespondWhenInvisible;
+            else
+                cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
+            cba->SetButtonGroupFlags(cbaFlags);
+        }
+#endif
+    } else if (QApplication::activeWindow() == qwidget->window()) {
+        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
+        }
+    }
+}
+
+void QSymbianControl::HandleResourceChange(int resourceType)
+{
+    switch (resourceType) {
+    case KInternalStatusPaneChange:
+        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();
+        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()).
+    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);
+    }
+}
+
+/*!
+    \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))
+{
+    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))
+{
+    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 initalized. We need to do it.
+        TApaApplicationFactory factory(S60->s60ApplicationFactory ?
+                S60->s60ApplicationFactory : newS60Application);
+        CApaCommandLine* commandLine = 0;
+        TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(commandLine);
+        // After this construction, CEikonEnv will be available from CEikonEnv::Static().
+        // (much like our qApp).
+        CEikonEnv* coe = new CEikonEnv;
+        //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
+        if(err == KErrNone)
+            TRAP(err, coe->ConstructAppFromCommandLineL(factory,*commandLine));
+        delete 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;
+        }
+    }
+#endif
+
+    if (touch) {
+        QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
+    } else {
+        QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
+    }
+
+#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);
+
+/*
+ ### 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 invokation in order
+    // to destroy WId objects during reparenting.
+    qRegisterMetaType<WId>("WId");
+}
+
+/*****************************************************************************
+  qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+void qt_cleanup()
+{
+    if(qt_S60Beep) {
+        delete qt_S60Beep;
+        qt_S60Beep = 0;
+    }
+    QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles
+// 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);
+
+    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)
+{
+    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)
+{
+    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:
+        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();
+            QWidget *w = QWidgetPrivate::mapper->value(control);
+            if (!w->d_func()->maybeTopData())
+                break;
+            if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
+                delete w->d_func()->topData()->backingStore;
+                w->d_func()->topData()->backingStore = 0;
+                // In order to ensure that any resources used by the window surface
+                // are immediately freed, we flush the WSERV command buffer.
+                S60->wsSession().Flush();
+            } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
+                       && !w->d_func()->maybeBackingStore()) {
+                w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
+                w->d_func()->invalidateBuffer(w->rect());
+                w->repaint();
+            }
+            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
+        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;
+    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:
+        bool handled = QSoftKeyManager::handleCommand(command);
+        if (handled)
+            ret = 1;
+#ifdef Q_WS_S60
+        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 (keysym) {
+        // If keysym is specified, cache it.
+        scanCodeCache.insert(scanCode, keysym);
+        return keysym;
+    } else {
+        // If not, retrieve the cached version.
+        return scanCodeCache[scanCode];
+    }
+}
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+    if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone)
+        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
+
+QT_END_NAMESPACE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/gui/kernel/qsound_s60.cpp	Mon Oct 18 17:18:49 2010 +0100
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+#ifndef QT_NO_SOUND
+
+#include "qdir.h"
+#include "qapplication.h"
+#include "qsound.h"
+#include "qsound_p.h"
+#include "qfileinfo.h"
+#include <private/qcore_symbian_p.h>
+
+#include <e32std.h>
+#include <mdaaudiosampleplayer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAuServerS60;
+
+class QAuBucketS60 : public QAuBucket, public MMdaAudioPlayerCallback
+{
+public:
+    QAuBucketS60(QAuServerS60 *server, QSound *sound);
+    ~QAuBucketS60();
+
+    void play();
+    void stop();
+
+    inline QSound *sound() const { return m_sound; }
+
+public: // from MMdaAudioPlayerCallback
+    void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
+    void MapcPlayComplete(TInt aError);
+
+private:
+    QSound *m_sound;
+    QAuServerS60 *m_server;
+    bool m_prepared;
+    bool m_playCalled;
+    CMdaAudioPlayerUtility *m_playUtility;
+};
+
+
+class QAuServerS60 : public QAuServer
+{
+public:
+    QAuServerS60(QObject *parent);
+
+    void init(QSound *s)
+    {
+        QAuBucketS60 *bucket = new QAuBucketS60(this, s);
+        setBucket(s, bucket);
+    }
+
+    void play(QSound *s)
+    {
+        bucket(s)->play();
+    }
+
+    void stop(QSound *s)
+    {
+        bucket(s)->stop();
+    }
+
+    bool okay() { return true; }
+
+    void play(const QString& filename);
+
+protected:
+    void playCompleted(QAuBucketS60 *bucket, int error);
+
+protected:
+    QAuBucketS60 *bucket(QSound *s)
+    {
+        return (QAuBucketS60 *)QAuServer::bucket( s );
+    }
+
+    friend class QAuBucketS60;
+
+    // static QSound::play(filename) cannot be stopped, meaning that playCompleted
+    // will get always called and QSound gets removed form this list.
+    QList<QSound *> staticPlayingSounds;
+};
+
+QAuServerS60::QAuServerS60(QObject *parent) :
+    QAuServer(parent)
+{
+    setObjectName(QLatin1String("QAuServerS60"));
+}
+
+void QAuServerS60::play(const QString& filename)
+{
+    QSound *s = new QSound(filename);
+    staticPlayingSounds.append(s);
+    play(s);
+}
+
+void QAuServerS60::playCompleted(QAuBucketS60 *bucket, int error)
+{
+    QSound *sound = bucket->sound();
+    if (!error) {
+        // We need to handle repeats by ourselves, since with Symbian API we don't
+        // know how many loops have been played when user asks it
+        if (decLoop(sound)) {
+            play(sound);
+        } else {
+            if (staticPlayingSounds.removeAll(sound))
+                delete sound;
+        }
+    } else {
+        // We don't have a way to inform about errors -> just decrement loops
+        // in order that QSound::isFinished will return true;
+        while (decLoop(sound)) {}
+        if (staticPlayingSounds.removeAll(sound))
+            delete sound;
+    }
+}
+
+QAuServer *qt_new_audio_server()
+{
+    return new QAuServerS60(qApp);
+}
+
+QAuBucketS60::QAuBucketS60(QAuServerS60 *server, QSound *sound)
+    : m_sound(sound), m_server(server), m_prepared(false), m_playCalled(false)
+{
+    QString filepath = QFileInfo(m_sound->fileName()).absoluteFilePath();
+    filepath = QDir::toNativeSeparators(filepath);
+    TPtrC filepathPtr(qt_QString2TPtrC(filepath));
+    TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this);
+               m_playUtility->OpenFileL(filepathPtr));
+    if (err) {
+        m_server->playCompleted(this, err);
+    }
+}
+
+void QAuBucketS60::play()
+{
+    if (m_prepared) {
+        // OpenFileL call is completed we can start playing immediately
+        m_playUtility->Play();
+    } else {
+        m_playCalled = true;
+    }
+
+}
+
+void QAuBucketS60::stop()
+{
+    m_playCalled = false;
+    m_playUtility->Stop();
+}
+
+void QAuBucketS60::MapcPlayComplete(TInt aError)
+{
+    m_server->playCompleted(this, aError);
+}
+
+void QAuBucketS60::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/)
+{
+    if (aError) {
+        m_server->playCompleted(this, aError);
+    } else {
+        m_prepared = true;
+        if (m_playCalled){
+            play();
+        }
+    }
+}
+
+QAuBucketS60::~QAuBucketS60()
+{
+    if (m_playUtility){
+        m_playUtility->Stop();
+        m_playUtility->Close();
+    }
+
+    delete m_playUtility;
+}
+
+
+#endif // QT_NO_SOUND
+
+QT_END_NAMESPACE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/gui/prepare_qt.cmd	Mon Oct 18 17:18:49 2010 +0100
@@ -0,0 +1,2 @@
+cd \sf\mw\qt
+configure.exe -platform win32-g++ -xplatform symbian-sbsv2 -opensource -confirm-license -openvg -script -no-scripttools -webkit -make make -graphicssystem openvg -no-phonon-backend -usedeffiles -dont-process -nomake examples -nomake demos -nomake tools