Index: trunk/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
===================================================================
--- trunk/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp	(revision 766)
+++ trunk/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp	(revision 769)
@@ -1108,4 +1108,5 @@
 #ifndef NO_OPENTYPE
 static const HB_OpenTypeFeature indic_features[] = {
+    { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty },
     { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
     { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
@@ -1116,4 +1117,5 @@
     { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
     { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
+    { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty },
     { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
     { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
@@ -1122,4 +1124,5 @@
     { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
     { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty },
+    { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty },
     { 0, 0 }
 };
@@ -1149,4 +1152,6 @@
     QString res;
     properties = ~properties;
+    if (properties & LocaProperty)
+        res += "Loca ";
     if (properties & CcmpProperty)
         res += "Ccmp ";
@@ -1169,4 +1174,6 @@
     if (properties & PostFormProperty)
         res += "PostForm ";
+    if (properties & ConjunctFormProperty)
+        res += "PostForm ";
     if (properties & VattuProperty)
         res += "Vattu ";
@@ -1183,4 +1190,6 @@
     if (properties & CligProperty)
         res += "Clig ";
+    if (properties & IndicCaltProperty)
+        res += "Calt ";
     return res;
 }
@@ -1297,7 +1306,12 @@
             int skipped = 0;
             Position pos = Post;
-            for (i = len-1; i > base; i--) {
+            for (i = len-1; i >= base; i--) {
                 if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada))
                     continue;
+
+                if (i < len-1 && position[i] == Control && position[i+1] == Consonant) {
+                    base = i+1;
+                    break;
+                }
 
                 Position charPosition = indic_position(uc[i]);
@@ -1546,7 +1560,9 @@
         // features we should always apply
         for (i = 0; i < len; ++i)
-            properties[i] = ~(CcmpProperty
+            properties[i] = ~(LocaProperty
+                              | CcmpProperty
                               | NuktaProperty
                               | VattuProperty
+                              | ConjunctFormProperty
                               | PreSubstProperty
                               | BelowSubstProperty
@@ -1554,6 +1570,8 @@
                               | PostSubstProperty
                               | HalantProperty
+                              | IndicCaltProperty
                               | PositioningProperties);
 
+        // Loca always applies
         // Ccmp always applies
         // Init
@@ -1612,4 +1630,5 @@
         // psts always applies
         // halant always applies
+        // calt always applies
 
 #ifdef INDIC_DEBUG
Index: trunk/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h
===================================================================
--- trunk/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h	(revision 766)
+++ trunk/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h	(revision 769)
@@ -58,32 +58,35 @@
 
 typedef enum {
-    CcmpProperty = 0x1,
-    InitProperty = 0x2,
-    IsolProperty = 0x4,
-    FinaProperty = 0x8,
-    MediProperty = 0x10,
-    RligProperty = 0x20,
-    CaltProperty = 0x40,
-    LigaProperty = 0x80,
-    DligProperty = 0x100,
-    CswhProperty = 0x200,
-    MsetProperty = 0x400,
+    LocaProperty = 0x1,
+    CcmpProperty = 0x2,
+    InitProperty = 0x4,
+    IsolProperty = 0x8,
+    FinaProperty = 0x10,
+    MediProperty = 0x20,
+    RligProperty = 0x40,
+    CaltProperty = 0x80,
+    LigaProperty = 0x100,
+    DligProperty = 0x200,
+    CswhProperty = 0x400,
+    MsetProperty = 0x800,
 
     /* used by indic and myanmar shaper */
-    NuktaProperty = 0x4,
-    AkhantProperty = 0x8,
-    RephProperty = 0x10,
-    PreFormProperty = 0x20,
-    BelowFormProperty = 0x40,
-    AboveFormProperty = 0x80,
-    HalfFormProperty = 0x100,
-    PostFormProperty = 0x200,
-    VattuProperty = 0x400,
-    PreSubstProperty = 0x800,
-    BelowSubstProperty = 0x1000,
-    AboveSubstProperty = 0x2000,
-    PostSubstProperty = 0x4000,
-    HalantProperty = 0x8000,
-    CligProperty = 0x10000
+    NuktaProperty = 0x8,
+    AkhantProperty = 0x10,
+    RephProperty = 0x20,
+    PreFormProperty = 0x40,
+    BelowFormProperty = 0x80,
+    AboveFormProperty = 0x100,
+    HalfFormProperty = 0x200,
+    PostFormProperty = 0x400,
+    ConjunctFormProperty = 0x800,
+    VattuProperty = 0x1000,
+    PreSubstProperty = 0x2000,
+    BelowSubstProperty = 0x4000,
+    AboveSubstProperty = 0x8000,
+    PostSubstProperty = 0x10000,
+    HalantProperty = 0x20000,
+    CligProperty = 0x40000,
+    IndicCaltProperty = 0x80000
 
 } HB_OpenTypeProperty;
Index: trunk/src/3rdparty/harfbuzz/tests/shaping/main.cpp
===================================================================
--- trunk/src/3rdparty/harfbuzz/tests/shaping/main.cpp	(revision 766)
+++ trunk/src/3rdparty/harfbuzz/tests/shaping/main.cpp	(revision 769)
@@ -137,5 +137,5 @@
 }
 
-void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics)
+void hb_getGlyphMetrics(HB_Font, HB_Glyph, HB_GlyphMetrics *metrics)
 {
     // ###
@@ -143,5 +143,5 @@
 }
 
-HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric)
+HB_Fixed hb_getFontMetric(HB_Font, HB_FontMetric )
 {
     return 0; // ####
@@ -170,4 +170,6 @@
     void cleanupTestCase();
 private slots:
+    void greek();
+
     void devanagari();
     void bengali();
@@ -204,16 +206,23 @@
 }
 
-struct ShapeTable {
-    unsigned short unicode[16];
-    unsigned short glyphs[16];
+class Shaper
+{
+public:
+    Shaper(FT_Face face, HB_Script script, const QString &str);
+
+    HB_FontRec hbFont;
+    HB_ShaperItem shaper_item;
+    QVarLengthArray<HB_Glyph> hb_glyphs;
+    QVarLengthArray<HB_GlyphAttributes> hb_attributes;
+    QVarLengthArray<HB_Fixed> hb_advances;
+    QVarLengthArray<HB_FixedPoint> hb_offsets;
+    QVarLengthArray<unsigned short> hb_logClusters;
+
 };
 
-static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script)
-{
-    QString str = QString::fromUtf16( s->unicode );
-
+Shaper::Shaper(FT_Face face, HB_Script script, const QString &str)
+{
     HB_Face hbFace = HB_NewFace(face, hb_getSFntTable);
 
-    HB_FontRec hbFont;
     hbFont.klass = &hb_fontClass;
     hbFont.userData = face;
@@ -223,5 +232,4 @@
     hbFont.y_scale = face->size->metrics.y_scale;
 
-    HB_ShaperItem shaper_item;
     shaper_item.kerning_applied = false;
     shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData());
@@ -238,9 +246,4 @@
     shaper_item.initialGlyphCount = 0;
 
-    QVarLengthArray<HB_Glyph> hb_glyphs(shaper_item.num_glyphs);
-    QVarLengthArray<HB_GlyphAttributes> hb_attributes(shaper_item.num_glyphs);
-    QVarLengthArray<HB_Fixed> hb_advances(shaper_item.num_glyphs);
-    QVarLengthArray<HB_FixedPoint> hb_offsets(shaper_item.num_glyphs);
-    QVarLengthArray<unsigned short> hb_logClusters(shaper_item.num_glyphs);
 
     while (1) {
@@ -264,8 +267,64 @@
         if (HB_ShapeItem(&shaper_item))
             break;
-
     }
 
     HB_FreeFace(hbFace);
+}
+
+
+static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch)
+{
+    QString uc = QString().append(ch);
+    Shaper shaper(face, script, uc);
+
+    uc = uc.normalized(QString::NormalizationForm_D);
+    Shaper decomposed(face, script, uc);
+
+    if( shaper.shaper_item.num_glyphs != decomposed.shaper_item.num_glyphs )
+        goto error;
+
+    for (unsigned int i = 0; i < shaper.shaper_item.num_glyphs; ++i) {
+        if ((shaper.shaper_item.glyphs[i]&0xffffff) != (decomposed.shaper_item.glyphs[i]&0xffffff))
+            goto error;
+    }
+    return true;
+ error:
+    QString str = "";
+    int i = 0;
+    while (i < uc.length()) {
+        str += QString("%1 ").arg(uc[i].unicode(), 4, 16);
+        ++i;
+    }
+    qDebug("%s: decomposedShaping of char %4x failed\n    decomposedString: %s\n   nglyphs=%d, decomposed nglyphs %d",
+           face->family_name,
+           ch.unicode(), str.toLatin1().data(),
+           shaper.shaper_item.num_glyphs,
+           decomposed.shaper_item.num_glyphs);
+
+    str = "";
+    i = 0;
+    while (i < shaper.shaper_item.num_glyphs) {
+        str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16);
+        ++i;
+    }
+    qDebug("    composed glyph result   = %s", str.toLatin1().constData());
+    str = "";
+    i = 0;
+    while (i < decomposed.shaper_item.num_glyphs) {
+        str += QString("%1 ").arg(decomposed.shaper_item.glyphs[i], 4, 16);
+        ++i;
+    }
+    qDebug("    decomposed glyph result = %s", str.toLatin1().constData());
+    return false;
+}
+
+struct ShapeTable {
+    unsigned short unicode[16];
+    unsigned short glyphs[16];
+};
+
+static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script)
+{
+    Shaper shaper(face, script, QString::fromUtf16( s->unicode ));
 
     hb_uint32 nglyphs = 0;
@@ -276,14 +335,14 @@
     }
 
-    if( nglyphs != shaper_item.num_glyphs )
+    if( nglyphs != shaper.shaper_item.num_glyphs )
 	goto error;
 
     for (hb_uint32 i = 0; i < nglyphs; ++i) {
-	if ((shaper_item.glyphs[i]&0xffffff) != s->glyphs[i])
+        if ((shaper.shaper_item.glyphs[i]&0xffffff) != s->glyphs[i])
 	    goto error;
     }
     return true;
  error:
-    str = "";
+    QString str = "";
     const unsigned short *uc = s->unicode;
     while (*uc) {
@@ -294,10 +353,10 @@
            face->family_name,
            str.toLatin1().constData(),
-           shaper_item.num_glyphs, nglyphs);
+           shaper.shaper_item.num_glyphs, nglyphs);
 
     str = "";
     hb_uint32 i = 0;
-    while (i < shaper_item.num_glyphs) {
-	str += QString("%1 ").arg(shaper_item.glyphs[i], 4, 16);
+    while (i < shaper.shaper_item.num_glyphs) {
+        str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16);
 	++i;
     }
@@ -305,4 +364,64 @@
     return false;
 }
+
+
+void tst_QScriptEngine::greek()
+{
+    FT_Face face = loadFace("DejaVuSans.ttf");
+    if (face) {
+        for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
+            QString str;
+            str.append(uc);
+            if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
+                //qDebug() << "skipping" << hex << uc;
+                continue;
+            }
+            if (uc == 0x1fc1 || uc == 0x1fed)
+                continue;
+            QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
+        }
+        FT_Done_Face(face);
+    } else {
+        QSKIP("couln't find DejaVu Sans", SkipAll);
+    }
+
+
+    face = loadFace("SBL_grk.ttf");
+    if (face) {
+        for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
+            QString str;
+            str.append(uc);
+            if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
+                //qDebug() << "skipping" << hex << uc;
+                continue;
+            }
+            if (uc == 0x1fc1 || uc == 0x1fed)
+                continue;
+            QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
+
+        }
+
+        const ShapeTable shape_table [] = {
+            { { 0x3b1, 0x300, 0x313, 0x0 },
+              { 0xb8, 0x3d3, 0x3c7, 0x0 } },
+            { { 0x3b1, 0x313, 0x300, 0x0 },
+              { 0xd4, 0x0 } },
+
+            { {0}, {0} }
+        };
+
+
+        const ShapeTable *s = shape_table;
+        while (s->unicode[0]) {
+            QVERIFY( shaping(face, s, HB_Script_Greek) );
+            ++s;
+        }
+
+        FT_Done_Face(face);
+    } else {
+        QSKIP("couln't find DejaVu Sans", SkipAll);
+    }
+}
+
 
 void tst_QScriptEngine::devanagari()
@@ -1012,4 +1131,6 @@
                 { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 },
                   { 0x2ff, 0x0 } },
+                { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 },
+                  { 0xf3, 0x350, 0x0 } },
 
                 { {0}, {0} }
Index: trunk/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
===================================================================
--- trunk/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h	(revision 766)
+++ trunk/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h	(revision 769)
@@ -325,4 +325,9 @@
 #endif
 
+/* PLATFORM(ALPHA) */
+#if defined(__alpha__)
+#define WTF_PLATFORM_ALPHA 1
+#endif
+
 /* PLATFORM(SH4) */
 #if defined(__SH4__)
@@ -738,5 +743,5 @@
 #if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX) || PLATFORM(SOLARIS) || PLATFORM(HPUX))
 #define WTF_USE_JSVALUE64 1
-#elif (PLATFORM(IA64) && !PLATFORM(IA64_32)) || PLATFORM(SPARC64)
+#elif (PLATFORM(IA64) && !PLATFORM(IA64_32)) || PLATFORM(SPARC64) || PLATFORM(ALPHA)
 #define WTF_USE_JSVALUE64 1
 #elif PLATFORM(AIX64)
Index: trunk/src/3rdparty/phonon/ds9/videowidget.cpp
===================================================================
--- trunk/src/3rdparty/phonon/ds9/videowidget.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/ds9/videowidget.cpp	(revision 769)
@@ -219,4 +219,7 @@
                 return current; //no switch here
 
+            if (!mediaObject())
+                return current;
+
             //firt we delete the renderer
             //initialization of the widgets
Index: trunk/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp	(revision 769)
@@ -21,5 +21,4 @@
 #include "abstractaudioeffect.h"
 #include "audioplayer.h"
-#include "mmf_videoplayer.h"
 
 QT_BEGIN_NAMESPACE
Index: trunk/src/3rdparty/phonon/mmf/abstractaudioeffect.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractaudioeffect.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/abstractaudioeffect.h	(revision 769)
@@ -29,5 +29,4 @@
 #include "effectparameter.h"
 #include "mmf_medianode.h"
-#include "mmf_videoplayer.h"
 
 class CMdaAudioOutputStream;
Index: trunk/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp	(revision 769)
@@ -49,5 +49,5 @@
         :   AbstractPlayer(player)
         ,   m_parent(parent)
-        ,   m_playPending(false)
+        ,   m_pending(NothingPending)
         ,   m_positionTimer(new QTimer(this))
         ,   m_bufferStatusTimer(new QTimer(this))
@@ -75,12 +75,10 @@
 
     case LoadingState:
-        m_playPending = true;
+        setPending(PlayPending);
         break;
 
     case StoppedState:
     case PausedState:
-        doPlay();
-        startPositionTimer();
-        changeState(PlayingState);
+        startPlayback();
         break;
 
@@ -104,5 +102,4 @@
     TRACE_ENTRY("state %d", privateState());
 
-    m_playPending = false;
     stopTimers();
 
@@ -110,6 +107,9 @@
     case GroundState:
     case LoadingState:
+    case StoppedState:
+        setPending(PausePending);
+        break;
+
     case PausedState:
-    case StoppedState:
         // Do nothing
         break;
@@ -136,5 +136,5 @@
     TRACE_ENTRY("state %d", privateState());
 
-    m_playPending = false;
+    setPending(NothingPending);
     stopTimers();
 
@@ -366,10 +366,29 @@
 }
 
+void MMF::AbstractMediaPlayer::loadingComplete(int error)
+{
+    Q_ASSERT(Phonon::LoadingState == state());
+
+    if (KErrNone == error) {
+        updateMetaData();
+        changeState(StoppedState);
+    } else {
+        setError(tr("Loading clip failed"), error);
+    }
+}
+
 void MMF::AbstractMediaPlayer::playbackComplete(int error)
 {
     stopTimers();
 
+    if (KErrNone == error && !m_aboutToFinishSent) {
+        const qint64 total = totalTime();
+        emit MMF::AbstractPlayer::tick(total);
+        m_aboutToFinishSent = true;
+        emit aboutToFinish();
+    }
+
     if (KErrNone == error) {
-        changeState(StoppedState);
+        changeState(PausedState);
 
         // MediaObject::switchToNextSource deletes the current player, so we
@@ -380,4 +399,5 @@
     else {
         setError(tr("Playback complete"), error);
+        emit finished();
     }
 }
@@ -394,13 +414,11 @@
 void MMF::AbstractMediaPlayer::positionTick()
 {
-    emitMarksIfReached();
-
     const qint64 current = currentTime();
+    emitMarksIfReached(current);
     emit MMF::AbstractPlayer::tick(current);
 }
 
-void MMF::AbstractMediaPlayer::emitMarksIfReached()
-{
-    const qint64 current = currentTime();
+void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
+{
     const qint64 total = totalTime();
     const qint64 remaining = total - current;
@@ -436,7 +454,35 @@
 }
 
+void MMF::AbstractMediaPlayer::setPending(Pending pending)
+{
+    const Phonon::State oldState = state();
+    m_pending = pending;
+    const Phonon::State newState = state();
+    if (newState != oldState)
+        emit stateChanged(newState, oldState);
+}
+
+void MMF::AbstractMediaPlayer::startPlayback()
+{
+    doPlay();
+    startPositionTimer();
+    changeState(PlayingState);
+}
+
 void MMF::AbstractMediaPlayer::bufferStatusTick()
 {
     emit MMF::AbstractPlayer::bufferStatus(bufferStatus());
+}
+
+Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) const
+{
+    Phonon::State result = AbstractPlayer::phononState(state);
+
+    if (PausePending == m_pending) {
+        Q_ASSERT(Phonon::StoppedState == result || Phonon::LoadingState == result);
+        result = Phonon::PausedState;
+    }
+
+    return result;
 }
 
@@ -448,18 +494,24 @@
     const Phonon::State newPhononState = phononState(newState);
 
-    // TODO: add some invariants to check that the transition is valid
-    AbstractPlayer::changeState(newState);
-
     if (LoadingState == oldPhononState && StoppedState == newPhononState) {
-        // Ensure initial volume is set on MMF API before starting playback
-        doVolumeChanged();
-
-        // Check whether play() was called while clip was being loaded.  If so,
-        // playback should be started now
-        if (m_playPending) {
-            TRACE_0("play was called while loading; starting playback now");
-            m_playPending = false;
-            play();
-        }
+        switch (m_pending) {
+        case NothingPending:
+            AbstractPlayer::changeState(newState);
+            break;
+
+        case PlayPending:
+            changeState(PlayingState); // necessary in order to apply initial volume
+            doVolumeChanged();
+            startPlayback();
+            break;
+
+        case PausePending:
+            AbstractPlayer::changeState(PausedState);
+            break;
+        }
+
+        setPending(NothingPending);
+    } else {
+        AbstractPlayer::changeState(newState);
     }
 }
Index: trunk/src/3rdparty/phonon/mmf/abstractmediaplayer.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractmediaplayer.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/abstractmediaplayer.h	(revision 769)
@@ -61,4 +61,6 @@
     // AbstractPlayer
     virtual void doSetTickInterval(qint32 interval);
+    virtual Phonon::State phononState(PrivateState state) const;
+    virtual void changeState(PrivateState newState);
 
     virtual void doPlay() = 0;
@@ -71,5 +73,4 @@
     virtual int bufferStatus() const = 0;
     virtual void close() = 0;
-    virtual void changeState(PrivateState newState);
 
     void updateMetaData();
@@ -81,4 +82,5 @@
     void bufferingComplete();
     void maxVolumeChanged(int maxVolume);
+    void loadingComplete(int error);
     void playbackComplete(int error);
 
@@ -92,6 +94,15 @@
     void stopTimers();
     void doVolumeChanged();
-    void emitMarksIfReached();
+    void emitMarksIfReached(qint64 position);
     void resetMarksIfRewound();
+    void startPlayback();
+
+    enum Pending {
+        NothingPending,
+        PausePending,
+        PlayPending
+    };
+
+    void setPending(Pending pending);
 
 private Q_SLOTS:
@@ -102,10 +113,5 @@
     MediaObject *const          m_parent;
 
-    /**
-     * This flag is set to true if play is called when the object is
-     * in a Loading state.  Once loading is complete, playback will
-     * be started.
-     */
-    bool                        m_playPending;
+    Pending                     m_pending;
 
     QScopedPointer<QTimer>      m_positionTimer;
Index: trunk/src/3rdparty/phonon/mmf/abstractplayer.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractplayer.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/abstractplayer.cpp	(revision 769)
@@ -49,4 +49,9 @@
         m_transitionTime = player->m_transitionTime;
         m_prefinishMark = player->m_prefinishMark;
+
+        // This is to prevent unwanted state transitions occurring as a result
+        // of MediaObject::switchToNextSource() during playlist playback.
+        if (StoppedState == player->m_state)
+            m_state = player->m_state;
     }
 }
@@ -97,5 +102,5 @@
 //-----------------------------------------------------------------------------
 
-void MMF::AbstractPlayer::setVideoOutput(VideoOutput* videoOutput)
+void MMF::AbstractPlayer::setVideoOutput(AbstractVideoOutput* videoOutput)
 {
     m_videoOutput = videoOutput;
@@ -142,5 +147,5 @@
 }
 
-Phonon::State MMF::AbstractPlayer::phononState(PrivateState state)
+Phonon::State MMF::AbstractPlayer::phononState(PrivateState state) const
 {
     const Phonon::State phononState =
Index: trunk/src/3rdparty/phonon/mmf/abstractplayer.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractplayer.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/abstractplayer.h	(revision 769)
@@ -25,5 +25,5 @@
 #include <QObject>
 
-#include "videooutput.h"
+#include "abstractvideooutput.h"
 
 class RFile;
@@ -35,5 +35,4 @@
 namespace MMF
 {
-class VideoOutput;
 
 /**
@@ -80,5 +79,5 @@
     virtual void volumeChanged(qreal volume);
 
-    void setVideoOutput(VideoOutput* videoOutput);
+    void setVideoOutput(AbstractVideoOutput *videoOutput);
 
     /**
@@ -135,5 +134,5 @@
      * Converts PrivateState into the corresponding Phonon::State
      */
-    static Phonon::State phononState(PrivateState state);
+    virtual Phonon::State phononState(PrivateState state) const;
 
     virtual void videoOutputChanged();
@@ -157,5 +156,5 @@
 protected:
     // Not owned
-    VideoOutput*                m_videoOutput;
+    AbstractVideoOutput*        m_videoOutput;
 
     qreal                       m_volume;
Index: trunk/src/3rdparty/phonon/mmf/abstractvideooutput.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractvideooutput.cpp	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/abstractvideooutput.cpp	(revision 769)
@@ -0,0 +1,185 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "abstractvideooutput.h"
+#include "utils.h"
+
+#ifndef QT_NO_DEBUG
+#include "objectdump.h"
+#endif
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TSize2QSize
+
+#include <QMoveEvent>
+#include <QResizeEvent>
+
+#include <QApplication> // for QApplication::activeWindow
+
+#include <coecntrl.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractVideoOutput
+  \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+static const Phonon::VideoWidget::AspectRatio DefaultAspectRatio =
+    Phonon::VideoWidget::AspectRatioAuto;
+static const Phonon::VideoWidget::ScaleMode DefaultScaleMode =
+    Phonon::VideoWidget::FitInView;
+
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AbstractVideoOutput::AbstractVideoOutput(QWidget *parent)
+    :   QWidget(parent)
+    ,   m_aspectRatio(DefaultAspectRatio)
+    ,   m_scaleMode(DefaultScaleMode)
+{
+
+}
+
+MMF::AbstractVideoOutput::~AbstractVideoOutput()
+{
+
+}
+
+void MMF::AbstractVideoOutput::setVideoSize(const QSize &frameSize)
+{
+    TRACE_CONTEXT(AbstractVideoOutput::setVideoSize, EVideoInternal);
+    TRACE("oldSize %d %d newSize %d %d",
+          m_videoFrameSize.width(), m_videoFrameSize.height(),
+          frameSize.width(), frameSize.height());
+
+    if (frameSize != m_videoFrameSize) {
+        m_videoFrameSize = frameSize;
+        updateGeometry();
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+// QWidget
+//-----------------------------------------------------------------------------
+
+QSize MMF::AbstractVideoOutput::sizeHint() const
+{
+    // TODO: replace this with a more sensible default
+    QSize result(320, 240);
+
+    if (!m_videoFrameSize.isNull())
+        result = m_videoFrameSize;
+
+    return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+RWindowBase* MMF::AbstractVideoOutput::videoWindow() const
+{
+    CCoeControl *control = internalWinId();
+    if (!control)
+        control = effectiveWinId();
+
+    RWindowBase *window = 0;
+    if (control)
+        window = control->DrawableWindow();
+
+    return window;
+}
+
+QSize MMF::AbstractVideoOutput::videoWindowSize() const
+{
+    QSize result;
+    if (RWindowBase *const window = videoWindow())
+        result = qt_TSize2QSize(window->Size());
+    return result;
+}
+
+Phonon::VideoWidget::AspectRatio MMF::AbstractVideoOutput::aspectRatio() const
+{
+    return m_aspectRatio;
+}
+
+void MMF::AbstractVideoOutput::setAspectRatio
+    (Phonon::VideoWidget::AspectRatio aspectRatio)
+{
+    if (m_aspectRatio != aspectRatio) {
+        m_aspectRatio = aspectRatio;
+        emit aspectRatioChanged();
+    }
+}
+
+Phonon::VideoWidget::ScaleMode MMF::AbstractVideoOutput::scaleMode() const
+{
+    return m_scaleMode;
+}
+
+void MMF::AbstractVideoOutput::setScaleMode
+    (Phonon::VideoWidget::ScaleMode scaleMode)
+{
+    if (m_scaleMode != scaleMode) {
+        m_scaleMode = scaleMode;
+        emit scaleModeChanged();
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoOutput::dump() const
+{
+#ifndef QT_NO_DEBUG
+    TRACE_CONTEXT(AbstractVideoOutput::dump, EVideoInternal);
+
+    QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor);
+    visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs
+    ObjectDump::addDefaultAnnotators(*visitor);
+
+    if (QWidget *window = QApplication::activeWindow()) {
+        TRACE("Dumping from root window 0x%08x:", window);
+        ObjectDump::dumpTreeFromLeaf(*window, *visitor);
+    }
+
+    TRACE("Dumping tree from leaf 0x%08x:", this);
+    ObjectDump::dumpTreeFromLeaf(*this, *visitor);
+
+    QScopedPointer<ObjectDump::QDumper> dumper(new ObjectDump::QDumper);
+    dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs
+    ObjectDump::addDefaultAnnotators(*dumper);
+    TRACE_0("Dumping AbstractVideoOutput:");
+    dumper->dumpObject(*this);
+#endif
+}
+
+QT_END_NAMESPACE
+
Index: trunk/src/3rdparty/phonon/mmf/abstractvideooutput.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractvideooutput.h	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/abstractvideooutput.h	(revision 769)
@@ -0,0 +1,93 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_ABSTRACTVIDEOOUTPUT_H
+#define PHONON_MMF_ABSTRACTVIDEOOUTPUT_H
+
+#include <QtGui/QWidget>
+#include <QVector>
+#include <QRect>
+#include "defs.h"
+
+#include <phonon/abstractvideooutput.h>
+#include <phonon/videowidget.h>
+
+#include <e32std.h>
+class RWindowBase;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short ABC for widget on which video is displayed
+ *
+ * @see DsaVideoOutput, SurfaceVideoOutput
+ */
+class AbstractVideoOutput
+    :   public QWidget
+{
+    Q_OBJECT
+
+public:
+    ~AbstractVideoOutput();
+
+    // Set size of video frame.  Called by VideoPlayer.
+    void setVideoSize(const QSize &size);
+
+    RWindowBase* videoWindow() const;
+    QSize videoWindowSize() const;
+
+    Phonon::VideoWidget::AspectRatio aspectRatio() const;
+    void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio);
+
+    Phonon::VideoWidget::ScaleMode scaleMode() const;
+    void setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode);
+
+    // Debugging output
+    void dump() const;
+
+Q_SIGNALS:
+    void videoWindowChanged();
+    void aspectRatioChanged();
+    void scaleModeChanged();
+
+protected:
+    AbstractVideoOutput(QWidget *parent);
+
+private:
+    // QWidget
+    QSize sizeHint() const;
+
+private:
+    // Dimensions of the video clip
+    QSize                   m_videoFrameSize;
+
+    Phonon::VideoWidget::AspectRatio        m_aspectRatio;
+    Phonon::VideoWidget::ScaleMode          m_scaleMode;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp	(revision 769)
@@ -0,0 +1,495 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <QUrl>
+#include <QTimer>
+#include <QWidget>
+
+#include <coemain.h>    // for CCoeEnv
+
+#include "abstractvideoplayer.h"
+#include "utils.h"
+
+#ifndef QT_NO_DEBUG
+#include "objectdump.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractVideoPlayer
+  \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AbstractVideoPlayer::AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
+    :   AbstractMediaPlayer(parent, player)
+    ,   m_wsSession(CCoeEnv::Static()->WsSession())
+    ,   m_screenDevice(*CCoeEnv::Static()->ScreenDevice())
+    ,   m_window(0)
+    ,   m_scaleWidth(1.0)
+    ,   m_scaleHeight(1.0)
+    ,   m_totalTime(0)
+{
+
+}
+
+void MMF::AbstractVideoPlayer::construct()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::AbstractVideoPlayer, EVideoApi);
+    TRACE_ENTRY_0();
+
+    if (m_videoOutput) {
+        initVideoOutput();
+        m_window = m_videoOutput->videoWindow();
+    }
+
+    createPlayer();
+
+    TRACE_EXIT_0();
+}
+
+MMF::AbstractVideoPlayer::~AbstractVideoPlayer()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::~AbstractVideoPlayer, EVideoApi);
+    TRACE_ENTRY_0();
+
+    // QObject destructor removes all signal-slot connections involving this
+    // object, so we do not need to disconnect from m_videoOutput here.
+
+    TRACE_EXIT_0();
+}
+
+CVideoPlayerUtility* MMF::AbstractVideoPlayer::nativePlayer() const
+{
+    return m_player.data();
+}
+
+//-----------------------------------------------------------------------------
+// Public API
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::doPlay()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::doPlay, EVideoApi);
+
+    handlePendingParametersChanged();
+
+    m_player->Play();
+}
+
+void MMF::AbstractVideoPlayer::doPause()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::doPause, EVideoApi);
+
+    TRAPD(err, m_player->PauseL());
+    if (KErrNone != err && state() != ErrorState) {
+        TRACE("PauseL error %d", err);
+        setError(tr("Pause failed"), err);
+    }
+}
+
+void MMF::AbstractVideoPlayer::doStop()
+{
+    m_player->Stop();
+}
+
+void MMF::AbstractVideoPlayer::doSeek(qint64 ms)
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::doSeek, EVideoApi);
+
+    TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000)));
+
+    if (KErrNone != err)
+        setError(tr("Seek failed"), err);
+}
+
+int MMF::AbstractVideoPlayer::setDeviceVolume(int mmfVolume)
+{
+    TRAPD(err, m_player->SetVolumeL(mmfVolume));
+    return err;
+}
+
+int MMF::AbstractVideoPlayer::openFile(RFile &file)
+{
+    TRAPD(err, m_player->OpenFileL(file));
+    return err;
+}
+
+int MMF::AbstractVideoPlayer::openUrl(const QString &url)
+{
+    TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url)));
+    return err;
+}
+
+int MMF::AbstractVideoPlayer::bufferStatus() const
+{
+    int result = 0;
+    TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result));
+    return result;
+}
+
+void MMF::AbstractVideoPlayer::close()
+{
+    m_player->Close();
+}
+
+bool MMF::AbstractVideoPlayer::hasVideo() const
+{
+    return true;
+}
+
+qint64 MMF::AbstractVideoPlayer::currentTime() const
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::currentTime, EVideoApi);
+
+    TTimeIntervalMicroSeconds us;
+    TRAPD(err, us = m_player->PositionL())
+
+    qint64 result = 0;
+
+    if (KErrNone == err) {
+        result = toMilliSeconds(us);
+    } else {
+        TRACE("PositionL error %d", err);
+
+        // If we don't cast away constness here, we simply have to ignore
+        // the error.
+        const_cast<AbstractVideoPlayer*>(this)->setError(tr("Getting position failed"), err);
+    }
+
+    return result;
+}
+
+qint64 MMF::AbstractVideoPlayer::totalTime() const
+{
+    return m_totalTime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Public slots
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::videoWindowChanged()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::videoWindowChanged, EVideoInternal);
+    TRACE_ENTRY("state %d", state());
+
+    m_window = m_videoOutput ? m_videoOutput->videoWindow() : 0;
+
+    if (m_videoOutput)
+        m_videoOutput->dump();
+
+    handleVideoWindowChanged();
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::aspectRatioChanged()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::aspectRatioChanged, EVideoInternal);
+    TRACE_ENTRY("state %d aspectRatio %d", state());
+
+    updateScaleFactors(m_videoOutput->videoWindowSize());
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::scaleModeChanged()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::scaleModeChanged, EVideoInternal);
+    TRACE_ENTRY("state %d", state());
+
+    updateScaleFactors(m_videoOutput->videoWindowSize());
+
+    TRACE_EXIT_0();
+}
+
+
+//-----------------------------------------------------------------------------
+// MVideoPlayerUtilityObserver callbacks
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::MvpuoOpenComplete(TInt aError)
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::MvpuoOpenComplete, EVideoApi);
+    TRACE_ENTRY("state %d error %d", state(), aError);
+
+    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+
+    if (KErrNone == aError)
+        m_player->Prepare();
+    else
+        setError(tr("Opening clip failed"), aError);
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError)
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPrepareComplete, EVideoApi);
+    TRACE_ENTRY("state %d error %d", state(), aError);
+
+    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+
+    TRAPD(err, getVideoClipParametersL(aError));
+
+    if (KErrNone == err) {
+        if (m_videoOutput)
+            m_videoOutput->dump();
+
+        maxVolumeChanged(m_player->MaxVolume());
+
+        if (m_videoOutput)
+            m_videoOutput->setVideoSize(m_videoFrameSize);
+
+        prepareCompleted();
+        handlePendingParametersChanged();
+
+        emit totalTimeChanged(totalTime());
+    }
+
+    loadingComplete(aError);
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::getVideoClipParametersL(TInt aError)
+{
+    User::LeaveIfError(aError);
+
+    // Get frame size
+    TSize size;
+    m_player->VideoFrameSizeL(size);
+    m_videoFrameSize = QSize(size.iWidth, size.iHeight);
+
+    // Get duration
+    m_totalTime = toMilliSeconds(m_player->DurationL());
+}
+
+
+void MMF::AbstractVideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::MvpuoFrameReady, EVideoApi);
+    TRACE_ENTRY("state %d error %d", state(), aError);
+
+    Q_UNUSED(aFrame);
+    Q_UNUSED(aError);   // suppress warnings in release builds
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::MvpuoPlayComplete(TInt aError)
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPlayComplete, EVideoApi)
+    TRACE_ENTRY("state %d error %d", state(), aError);
+
+    // Call base class function which handles end of playback for both
+    // audio and video clips.
+    playbackComplete(aError);
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::MvpuoEvent(const TMMFEvent &aEvent)
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::MvpuoEvent, EVideoApi);
+    TRACE_ENTRY("state %d", state());
+
+    Q_UNUSED(aEvent);
+
+    TRACE_EXIT_0();
+}
+
+
+//-----------------------------------------------------------------------------
+// MVideoLoadingObserver callbacks
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::MvloLoadingStarted()
+{
+    bufferingStarted();
+}
+
+void MMF::AbstractVideoPlayer::MvloLoadingComplete()
+{
+    bufferingComplete();
+}
+
+
+//-----------------------------------------------------------------------------
+// Video window updates
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::videoOutputChanged()
+{
+    TRACE_CONTEXT(AbstractVideoPlayer::videoOutputChanged, EVideoInternal);
+    TRACE_ENTRY_0();
+
+    if (m_videoOutput)
+        initVideoOutput();
+
+    videoWindowChanged();
+
+    TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::initVideoOutput()
+{
+    bool connected = connect(
+        m_videoOutput, SIGNAL(videoWindowChanged()),
+        this, SLOT(videoWindowChanged())
+    );
+    Q_ASSERT(connected);
+
+    connected = connect(
+        m_videoOutput, SIGNAL(aspectRatioChanged()),
+        this, SLOT(aspectRatioChanged())
+    );
+    Q_ASSERT(connected);
+
+    connected = connect(
+        m_videoOutput, SIGNAL(scaleModeChanged()),
+        this, SLOT(scaleModeChanged())
+    );
+    Q_ASSERT(connected);
+
+    // Suppress warnings in release builds
+    Q_UNUSED(connected);
+
+    // Do these after all connections are complete, to ensure
+    // that any signals generated get to their destinations.
+    m_videoOutput->winId();
+    m_videoOutput->setVideoSize(m_videoFrameSize);
+}
+
+// Helper function for aspect ratio / scale mode handling
+QSize scaleToAspect(const QSize &srcRect, int aspectWidth, int aspectHeight)
+{
+    const qreal aspectRatio = qreal(aspectWidth) / aspectHeight;
+
+    int width = srcRect.width();
+    int height = srcRect.width() / aspectRatio;
+    if (height > srcRect.height()){
+        height = srcRect.height();
+        width = srcRect.height() * aspectRatio;
+    }
+    return QSize(width, height);
+}
+
+void MMF::AbstractVideoPlayer::updateScaleFactors(const QSize &windowSize, bool apply)
+{
+    if (m_videoFrameSize.isValid()) {
+        QRect videoRect;
+
+        // Calculate size of smallest rect which contains video frame size
+        // and conforms to aspect ratio
+        switch (m_videoOutput->aspectRatio()) {
+        case Phonon::VideoWidget::AspectRatioAuto:
+            videoRect.setSize(m_videoFrameSize);
+            break;
+
+        case Phonon::VideoWidget::AspectRatioWidget:
+            videoRect.setSize(windowSize);
+            break;
+
+        case Phonon::VideoWidget::AspectRatio4_3:
+            videoRect.setSize(scaleToAspect(m_videoFrameSize, 4, 3));
+            break;
+
+        case Phonon::VideoWidget::AspectRatio16_9:
+            videoRect.setSize(scaleToAspect(m_videoFrameSize, 16, 9));
+            break;
+        }
+
+        // Scale to fill the window width
+        const int windowWidth = windowSize.width();
+        const int windowHeight = windowSize.height();
+        const qreal windowScaleFactor = qreal(windowWidth) / videoRect.width();
+        int videoWidth = windowWidth;
+        int videoHeight = videoRect.height() * windowScaleFactor;
+
+        const qreal windowToVideoHeightRatio = qreal(windowHeight) / videoHeight;
+
+        switch (m_videoOutput->scaleMode()) {
+        case Phonon::VideoWidget::ScaleAndCrop:
+            if (videoHeight < windowHeight) {
+                videoWidth *= windowToVideoHeightRatio;
+                videoHeight = windowHeight;
+            }
+            break;
+        case Phonon::VideoWidget::FitInView:
+        default:
+            if (videoHeight > windowHeight) {
+                videoWidth *= windowToVideoHeightRatio;
+                videoHeight = windowHeight;
+            }
+            break;
+        }
+
+        // Calculate scale factors
+        m_scaleWidth = 100.0f * videoWidth / m_videoFrameSize.width();
+        m_scaleHeight = 100.0f * videoHeight / m_videoFrameSize.height();
+
+        if (apply)
+            parametersChanged(ScaleFactors);
+    }
+}
+
+void MMF::AbstractVideoPlayer::parametersChanged(VideoParameters parameters)
+{
+    if (state() == LoadingState)
+        m_pendingChanges |= parameters;
+    else
+        handleParametersChanged(parameters);
+}
+
+void MMF::AbstractVideoPlayer::handlePendingParametersChanged()
+{
+    if (m_pendingChanges)
+        handleParametersChanged(m_pendingChanges);
+    m_pendingChanges = 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Metadata
+//-----------------------------------------------------------------------------
+
+int MMF::AbstractVideoPlayer::numberOfMetaDataEntries() const
+{
+    int numberOfEntries = 0;
+    TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL());
+    return numberOfEntries;
+}
+
+QPair<QString, QString> MMF::AbstractVideoPlayer::metaDataEntry(int index) const
+{
+    CMMFMetaDataEntry *entry = 0;
+    QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index));
+    return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value()));
+}
+
+QT_END_NAMESPACE
+
Index: trunk/src/3rdparty/phonon/mmf/abstractvideoplayer.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/abstractvideoplayer.h	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/abstractvideoplayer.h	(revision 769)
@@ -0,0 +1,171 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_ABSTRACTVIDEOPLAYER_H
+#define PHONON_MMF_ABSTRACTVIDEOPLAYER_H
+
+#include <videoplayer.h> // from epoc32/include
+
+#include <QSize>
+
+#include "abstractmediaplayer.h"
+#include "abstractvideooutput.h"
+#include "defs.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short ABC for classes which wrap the MMF video player utility
+ *
+ * On devices which use the legacy graphics subsystem which does not
+ * support surfaces, video rendering is done via Direct Screen Access using
+ * the CVideoPlayerUtility API.  On devices with a graphics subsystem which
+ * does support surfaces, video rendering is done using the
+ * CVideoPlayerUtility2 API.  Because CVideoPlayerUtility2 inherits from
+ * CVideoPlayerUtility, AbstractVideoPlayer holds a pointer to the latter.
+ *
+ * @see DsaVideoPlayer, SurfaceVideoPlayer
+ */
+class AbstractVideoPlayer
+    :   public AbstractMediaPlayer
+    ,   public MVideoPlayerUtilityObserver
+    ,   public MVideoLoadingObserver
+{
+    Q_OBJECT
+
+public:
+    ~AbstractVideoPlayer();
+
+    typedef CVideoPlayerUtility NativePlayer;
+    NativePlayer *nativePlayer() const;
+
+    // AbstractPlayer
+    virtual void doPlay();
+    virtual void doPause();
+    virtual void doStop();
+    virtual void doSeek(qint64 milliseconds);
+    virtual int setDeviceVolume(int mmfVolume);
+    virtual int openFile(RFile &file);
+    virtual int openUrl(const QString &url);
+    virtual int bufferStatus() const;
+    virtual void close();
+
+    // MediaObjectInterface
+    virtual bool hasVideo() const;
+    virtual qint64 currentTime() const;
+    virtual qint64 totalTime() const;
+
+    // AbstractPlayer
+    virtual void videoOutputChanged();
+
+    // AbstractMediaPlayer
+    virtual int numberOfMetaDataEntries() const;
+    virtual QPair<QString, QString> metaDataEntry(int index) const;
+
+public Q_SLOTS:
+    void videoWindowChanged();
+    void aspectRatioChanged();
+    void scaleModeChanged();
+
+protected:
+    AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player);
+    void construct();
+    virtual void initVideoOutput();
+    void updateScaleFactors(const QSize &windowSize, bool apply = true);
+
+    // Called when a video parameter changes.  If the underlying native API is
+    // ready to handle the change, it is propagated immediately, otherwise the
+    // change is recorded in m_pendingChanged and handled later by
+    // handlePendingParametersChanged().
+    void parametersChanged(VideoParameters parameter);
+
+    // Implementation must initialize the m_player pointer.
+    virtual void createPlayer() = 0;
+
+    // Called from the MvpuoPrepareComplete callback.  Allows derived class to
+    // calculate clipping rectangles and scale factors prior to starting
+    // playback.
+    virtual void prepareCompleted() = 0;
+
+    // Called when native video window handle changes.  Derived class may defer
+    // propagation of this change to the MMF video player utility by calling
+    // parametersChanged().
+    virtual void handleVideoWindowChanged() = 0;
+
+    // Called when the derived class must handle changes which have been made
+    // to video parameters such as window handle, screen rectangle and scale
+    // factors.  Guaranteed to be called only when the underlying MMF video
+    // player object is ready to handle changes to these parameters.
+    virtual void handleParametersChanged(VideoParameters parameters) = 0;
+
+private:
+    void getVideoClipParametersL(TInt aError);
+
+    // Called when native player API enters a state in which it is able to
+    // handle pending changes such as new video window handle, updated scale
+    // factors etc.
+    void handlePendingParametersChanged();
+
+private:
+    // MVideoPlayerUtilityObserver
+    virtual void MvpuoOpenComplete(TInt aError);
+    virtual void MvpuoPrepareComplete(TInt aError);
+    virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError);
+    virtual void MvpuoPlayComplete(TInt aError);
+    virtual void MvpuoEvent(const TMMFEvent &aEvent);
+
+    // MVideoLoadingObserver
+    virtual void MvloLoadingStarted();
+    virtual void MvloLoadingComplete();
+
+protected:
+    QScopedPointer<NativePlayer>        m_player;
+
+    // Not owned
+    RWsSession&                         m_wsSession;
+    CWsScreenDevice&                    m_screenDevice;
+    RWindowBase*                        m_window;
+
+    // Scaling factors for video display, expressed as percentages
+    TReal32                             m_scaleWidth;
+    TReal32                             m_scaleHeight;
+
+    // Dimensions of the video clip
+    QSize                               m_videoFrameSize;
+
+private:
+    // Bitmask of parameters which have changed while the MMF video player
+    // object is not yet ready to receive these changes.
+    // See handlePendingParametersChanged().
+    VideoParameters                     m_pendingChanges;
+
+    // Duration of the video clip
+    qint64                              m_totalTime;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp	(revision 769)
@@ -19,5 +19,6 @@
 #include "ancestormovemonitor.h"
 #include "utils.h"
-#include "videooutput.h"
+
+#include "videooutput_dsa.h"
 
 #include <QCoreApplication>
@@ -60,5 +61,5 @@
 //-----------------------------------------------------------------------------
 
-void AncestorMoveMonitor::registerTarget(VideoOutput *target)
+void AncestorMoveMonitor::registerTarget(DsaVideoOutput *target)
 {
     TRACE_CONTEXT(AncestorMoveMonitor::registerTarget, EVideoInternal);
@@ -94,5 +95,5 @@
 }
 
-void AncestorMoveMonitor::unRegisterTarget(VideoOutput *target)
+void AncestorMoveMonitor::unRegisterTarget(DsaVideoOutput *target)
 {
     TRACE_CONTEXT(AncestorMoveMonitor::unRegisterTarget, EVideoInternal);
@@ -127,5 +128,5 @@
         if(it != m_hash.end()) {
             const TargetList& targetList = it.value();
-            VideoOutput* target = 0;
+            DsaVideoOutput* target = 0;
             foreach(target, targetList) {
                 switch (event->type()) {
@@ -167,5 +168,5 @@
         TRACE("ancestor 0x%08x", ancestor);
         const TargetList& targetList = it.value();
-        VideoOutput* target = 0;
+        DsaVideoOutput* target = 0;
         foreach(target, targetList) {
             TRACE("    target 0x%08x", target);
@@ -175,6 +176,4 @@
 }
 
-
-
 QT_END_NAMESPACE
 
Index: trunk/src/3rdparty/phonon/mmf/ancestormovemonitor.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/ancestormovemonitor.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/ancestormovemonitor.h	(revision 769)
@@ -30,5 +30,5 @@
 namespace MMF
 {
-class VideoOutput;
+class DsaVideoOutput;
 
 class AncestorMoveMonitor : public QObject
@@ -50,5 +50,5 @@
      * the target receives a ParentChange event.
      */
-    void registerTarget(VideoOutput *target);
+    void registerTarget(DsaVideoOutput *target);
 
     /**
@@ -58,5 +58,5 @@
      * delivered to its ancestors.
      */
-    void unRegisterTarget(VideoOutput *target);
+    void unRegisterTarget(DsaVideoOutput *target);
 
 protected:
@@ -78,5 +78,5 @@
      * efficiency of iteration.
      */
-    typedef QList<VideoOutput *> TargetList;
+    typedef QList<DsaVideoOutput *> TargetList;
 
     /**
@@ -93,3 +93,3 @@
 QT_END_NAMESPACE
 
-#endif
+#endif // !PHONON_MMF_ANCESTORMOVEMONITOR_H
Index: trunk/src/3rdparty/phonon/mmf/audioplayer.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/audioplayer.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/audioplayer.cpp	(revision 769)
@@ -100,5 +100,5 @@
 #if !defined(__SERIES60_31__)
     const int err = m_player->SetVolume(mmfVolume);
-    if (QSysInfo::s60Version() >= QSysInfo::SV_S60_5_0)
+    if (QSysInfo::s60Version() >= QSysInfo::SV_S60_3_2)
         return err;
     else
@@ -204,9 +204,7 @@
         m_totalTime = toMilliSeconds(m_player->Duration());
         emit totalTimeChanged(m_totalTime);
-        updateMetaData();
-        changeState(StoppedState);
-    } else {
-        setError(tr("Opening clip failed"), aError);
     }
+
+    loadingComplete(aError);
 
     TRACE_EXIT_0();
Index: trunk/src/3rdparty/phonon/mmf/backend.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/backend.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/backend.cpp	(revision 769)
@@ -25,5 +25,4 @@
 
 #include "abstractaudioeffect.h"
-#include "ancestormovemonitor.h"
 #include "audiooutput.h"
 #include "audioplayer.h"
@@ -45,5 +44,7 @@
 Backend::Backend(QObject *parent)
     : QObject(parent)
+#ifndef PHONON_MMF_VIDEO_SURFACES
     , m_ancestorMoveMonitor(new AncestorMoveMonitor(this))
+#endif
     , m_effectFactory(new EffectFactory(this))
 {
@@ -87,6 +88,13 @@
         return m_effectFactory->createAudioEffect(type, parent);
     }
+
     case VideoWidgetClass:
-        result = new VideoWidget(m_ancestorMoveMonitor.data(), qobject_cast<QWidget *>(parent));
+    {
+        VideoWidget *widget = new VideoWidget(qobject_cast<QWidget *>(parent));
+#ifndef PHONON_MMF_VIDEO_SURFACES
+        widget->setAncestorMoveMonitor(m_ancestorMoveMonitor.data());
+#endif
+        result = widget;
+    }
         break;
 
Index: trunk/src/3rdparty/phonon/mmf/backend.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/backend.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/backend.h	(revision 769)
@@ -20,5 +20,8 @@
 #define PHONON_MMF_BACKEND_H
 
+#ifndef PHONON_MMF_VIDEO_SURFACES
 #include "ancestormovemonitor.h"
+#endif
+
 #include "effectfactory.h"
 
@@ -54,5 +57,7 @@
 
 private:
+#ifndef PHONON_MMF_VIDEO_SURFACES
     QScopedPointer<AncestorMoveMonitor> m_ancestorMoveMonitor;
+#endif
     QScopedPointer<EffectFactory>       m_effectFactory;
 
Index: trunk/src/3rdparty/phonon/mmf/defs.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/defs.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/defs.h	(revision 769)
@@ -36,4 +36,13 @@
     MediaTypeVideo
 };
+
+enum VideoParameter {
+    WindowHandle        = 0x1,
+    WindowScreenRect    = 0x2,
+    ScaleFactors        = 0x4
+};
+Q_DECLARE_FLAGS(VideoParameters, VideoParameter)
+Q_DECLARE_OPERATORS_FOR_FLAGS(VideoParameters)
+
 }
 }
Index: trunk/src/3rdparty/phonon/mmf/mediaobject.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/mediaobject.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/mediaobject.cpp	(revision 769)
@@ -23,5 +23,11 @@
 #include "utils.h"
 #include "utils.h"
-#include "mmf_videoplayer.h"
+
+#ifdef PHONON_MMF_VIDEO_SURFACES
+#include "videoplayer_surface.h"
+#else
+#include "videoplayer_dsa.h"
+#endif
+
 #include "videowidget.h"
 
@@ -294,5 +300,9 @@
 
     case MediaTypeVideo:
-        newPlayer = new VideoPlayer(this, oldPlayer);
+#ifdef PHONON_MMF_VIDEO_SURFACES
+        newPlayer = SurfaceVideoPlayer::create(this, oldPlayer);
+#else
+        newPlayer = DsaVideoPlayer::create(this, oldPlayer);
+#endif
         break;
     }
@@ -314,9 +324,10 @@
     connect(m_player.data(), SIGNAL(stateChanged(Phonon::State,Phonon::State)), SIGNAL(stateChanged(Phonon::State,Phonon::State)));
     connect(m_player.data(), SIGNAL(finished()), SIGNAL(finished()));
-    connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64)));
     connect(m_player.data(), SIGNAL(bufferStatus(int)), SIGNAL(bufferStatus(int)));
     connect(m_player.data(), SIGNAL(metaDataChanged(QMultiMap<QString,QString>)), SIGNAL(metaDataChanged(QMultiMap<QString,QString>)));
     connect(m_player.data(), SIGNAL(aboutToFinish()), SIGNAL(aboutToFinish()));
-    connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(tick(qint32)));
+    connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(prefinishMarkReached(qint32)));
+    connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SLOT(handlePrefinishMarkReached(qint32)));
+    connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64)));
 
     // We need to call setError() after doing the connects, otherwise the
@@ -384,5 +395,5 @@
 //-----------------------------------------------------------------------------
 
-void MMF::MediaObject::setVideoOutput(VideoOutput* videoOutput)
+void MMF::MediaObject::setVideoOutput(AbstractVideoOutput* videoOutput)
 {
     m_player->setVideoOutput(videoOutput);
@@ -405,6 +416,18 @@
         switchToSource(m_nextSource);
         play();
-    }
-}
+    } else {
+        emit finished();
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Other private functions
+//-----------------------------------------------------------------------------
+
+void MMF::MediaObject::handlePrefinishMarkReached(qint32 time)
+{
+    emit tick(time);
+}
+
 
 QT_END_NAMESPACE
Index: trunk/src/3rdparty/phonon/mmf/mediaobject.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/mediaobject.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/mediaobject.h	(revision 769)
@@ -39,5 +39,5 @@
 {
 class AbstractPlayer;
-class VideoOutput;
+class AbstractVideoOutput;
 
 /**
@@ -86,5 +86,5 @@
     AbstractPlayer *abstractPlayer() const;
 
-    void setVideoOutput(VideoOutput* videoOutput);
+    void setVideoOutput(AbstractVideoOutput* videoOutput);
 
 public Q_SLOTS:
@@ -107,4 +107,7 @@
     void finished();
     void tick(qint64 time);
+
+private Q_SLOTS:
+    void handlePrefinishMarkReached(qint32);
 
 private:
Index: trunk/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp	(revision 766)
+++ 	(revision )
@@ -1,658 +1,0 @@
-/*  This file is part of the KDE project.
-
-Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-
-This library is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 2.1 or 3 of the License.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with this library.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include <QApplication>    // for QApplication::activeWindow
-#include <QUrl>
-#include <QTimer>
-#include <QWidget>
-
-#include <coemain.h>    // for CCoeEnv
-#include <coecntrl.h>
-
-#include "mmf_videoplayer.h"
-#include "utils.h"
-
-#ifndef QT_NO_DEBUG
-#include "objectdump.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-using namespace Phonon;
-using namespace Phonon::MMF;
-
-/*! \class MMF::VideoPlayer
-  \internal
-*/
-
-//-----------------------------------------------------------------------------
-// Constructor / destructor
-//-----------------------------------------------------------------------------
-
-MMF::VideoPlayer::VideoPlayer(MediaObject *parent, const AbstractPlayer *player)
-        :   AbstractMediaPlayer(parent, player)
-        ,   m_wsSession(CCoeEnv::Static()->WsSession())
-        ,   m_screenDevice(*CCoeEnv::Static()->ScreenDevice())
-        ,   m_window(0)
-        ,   m_totalTime(0)
-        ,   m_pendingChanges(false)
-        ,   m_dsaActive(false)
-{
-    construct();
-}
-
-void MMF::VideoPlayer::construct()
-{
-    TRACE_CONTEXT(VideoPlayer::VideoPlayer, EVideoApi);
-    TRACE_ENTRY_0();
-
-    getVideoWindow();
-
-    const TInt priority = 0;
-    const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
-
-    CVideoPlayerUtility *player = 0;
-    QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL
-            (
-                 *this,
-                 priority, preference,
-                 m_wsSession, m_screenDevice,
-                 *m_window,
-                 m_videoRect, m_videoRect
-            )
-        );
-    m_player.reset(player);
-
-    // CVideoPlayerUtility::NewL starts DSA
-    m_dsaActive = true;
-
-    m_player->RegisterForVideoLoadingNotification(*this);
-
-    TRACE_EXIT_0();
-}
-
-MMF::VideoPlayer::~VideoPlayer()
-{
-    TRACE_CONTEXT(VideoPlayer::~VideoPlayer, EVideoApi);
-    TRACE_ENTRY_0();
-
-    // QObject destructor removes all signal-slot connections involving this
-    // object, so we do not need to disconnect from m_videoOutput here.
-
-    TRACE_EXIT_0();
-}
-
-CVideoPlayerUtility* MMF::VideoPlayer::nativePlayer() const
-{
-    return m_player.data();
-}
-
-//-----------------------------------------------------------------------------
-// Public API
-//-----------------------------------------------------------------------------
-
-void MMF::VideoPlayer::doPlay()
-{
-    TRACE_CONTEXT(VideoPlayer::doPlay, EVideoApi);
-
-    applyPendingChanges();
-
-    m_player->Play();
-}
-
-void MMF::VideoPlayer::doPause()
-{
-    TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi);
-
-    TRAPD(err, m_player->PauseL());
-    if (KErrNone != err && state() != ErrorState) {
-        TRACE("PauseL error %d", err);
-        setError(tr("Pause failed"), err);
-    }
-}
-
-void MMF::VideoPlayer::doStop()
-{
-    m_player->Stop();
-}
-
-void MMF::VideoPlayer::doSeek(qint64 ms)
-{
-    TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi);
-
-    TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000)));
-
-    if(KErrNone != err)
-        setError(tr("Seek failed"), err);
-}
-
-int MMF::VideoPlayer::setDeviceVolume(int mmfVolume)
-{
-    TRAPD(err, m_player->SetVolumeL(mmfVolume));
-    return err;
-}
-
-int MMF::VideoPlayer::openFile(RFile& file)
-{
-    TRAPD(err, m_player->OpenFileL(file));
-    return err;
-}
-
-int MMF::VideoPlayer::openUrl(const QString& url)
-{
-    TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url)));
-    return err;
-}
-
-int MMF::VideoPlayer::bufferStatus() const
-{
-    int result = 0;
-    TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result));
-    return result;
-}
-
-void MMF::VideoPlayer::close()
-{
-    m_player->Close();
-}
-
-bool MMF::VideoPlayer::hasVideo() const
-{
-    return true;
-}
-
-qint64 MMF::VideoPlayer::currentTime() const
-{
-    TRACE_CONTEXT(VideoPlayer::currentTime, EVideoApi);
-
-    TTimeIntervalMicroSeconds us;
-    TRAPD(err, us = m_player->PositionL())
-
-    qint64 result = 0;
-
-    if (KErrNone == err) {
-        result = toMilliSeconds(us);
-    } else {
-        TRACE("PositionL error %d", err);
-
-        // If we don't cast away constness here, we simply have to ignore
-        // the error.
-        const_cast<VideoPlayer*>(this)->setError(tr("Getting position failed"), err);
-    }
-
-    return result;
-}
-
-qint64 MMF::VideoPlayer::totalTime() const
-{
-    return m_totalTime;
-}
-
-
-//-----------------------------------------------------------------------------
-// MVideoPlayerUtilityObserver callbacks
-//-----------------------------------------------------------------------------
-
-void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError)
-{
-    TRACE_CONTEXT(VideoPlayer::MvpuoOpenComplete, EVideoApi);
-    TRACE_ENTRY("state %d error %d", state(), aError);
-
-    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
-
-    if (KErrNone == aError)
-        m_player->Prepare();
-    else
-        setError(tr("Opening clip failed"), aError);
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError)
-{
-    TRACE_CONTEXT(VideoPlayer::MvpuoPrepareComplete, EVideoApi);
-    TRACE_ENTRY("state %d error %d", state(), aError);
-
-    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
-
-    TRAPD(err, doPrepareCompleteL(aError));
-
-    if (KErrNone == err) {
-        maxVolumeChanged(m_player->MaxVolume());
-
-        if (m_videoOutput)
-            m_videoOutput->setVideoSize(m_videoFrameSize);
-
-        updateVideoRect();
-        applyPendingChanges();
-
-        emit totalTimeChanged(totalTime());
-        changeState(StoppedState);
-    } else {
-        setError(tr("Buffering clip failed"), err);
-    }
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::doPrepareCompleteL(TInt aError)
-{
-    User::LeaveIfError(aError);
-
-    // Get frame size
-    TSize size;
-    m_player->VideoFrameSizeL(size);
-    m_videoFrameSize = QSize(size.iWidth, size.iHeight);
-
-    // Get duration
-    m_totalTime = toMilliSeconds(m_player->DurationL());
-}
-
-
-void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
-{
-    TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi);
-    TRACE_ENTRY("state %d error %d", state(), aError);
-
-    Q_UNUSED(aFrame);
-    Q_UNUSED(aError);   // suppress warnings in release builds
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError)
-{
-    TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi)
-    TRACE_ENTRY("state %d error %d", state(), aError);
-
-    // Call base class function which handles end of playback for both
-    // audio and video clips.
-    playbackComplete(aError);
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent)
-{
-    TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi);
-    TRACE_ENTRY("state %d", state());
-
-    Q_UNUSED(aEvent);
-
-    TRACE_EXIT_0();
-}
-
-
-//-----------------------------------------------------------------------------
-// MVideoLoadingObserver callbacks
-//-----------------------------------------------------------------------------
-
-void MMF::VideoPlayer::MvloLoadingStarted()
-{
-    bufferingStarted();
-}
-
-void MMF::VideoPlayer::MvloLoadingComplete()
-{
-    bufferingComplete();
-}
-
-
-//-----------------------------------------------------------------------------
-// Video window updates
-//-----------------------------------------------------------------------------
-
-void MMF::VideoPlayer::getVideoWindow()
-{
-    TRACE_CONTEXT(VideoPlayer::getVideoWindow, EVideoInternal);
-    TRACE_ENTRY_0();
-
-    if(m_videoOutput) {
-        // Dump information to log, only in debug builds
-        m_videoOutput->dump();
-
-        initVideoOutput();
-        videoWindowChanged();
-    } else
-        // Top-level window
-        m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow();
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::videoOutputChanged()
-{
-    TRACE_CONTEXT(VideoPlayer::videoOutputChanged, EVideoInternal);
-    TRACE_ENTRY_0();
-
-    if (m_videoOutput) {
-        initVideoOutput();
-        videoWindowChanged();
-    }
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::initVideoOutput()
-{
-    m_videoOutput->winId();
-    m_videoOutput->setVideoSize(m_videoFrameSize);
-
-    bool connected = connect(
-        m_videoOutput, SIGNAL(videoWindowChanged()),
-        this, SLOT(videoWindowChanged())
-    );
-    Q_ASSERT(connected);
-
-    connected = connect(
-        m_videoOutput, SIGNAL(beginVideoWindowNativePaint()),
-        this, SLOT(suspendDirectScreenAccess())
-    );
-    Q_ASSERT(connected);
-
-    connected = connect(
-        m_videoOutput, SIGNAL(endVideoWindowNativePaint()),
-        this, SLOT(resumeDirectScreenAccess())
-    );
-    Q_ASSERT(connected);
-
-    connected = connect(
-        m_videoOutput, SIGNAL(aspectRatioChanged()),
-        this, SLOT(aspectRatioChanged())
-    );
-    Q_ASSERT(connected);
-
-    connected = connect(
-        m_videoOutput, SIGNAL(scaleModeChanged()),
-        this, SLOT(scaleModeChanged())
-    );
-    Q_ASSERT(connected);
-
-    // Suppress warnings in release builds
-    Q_UNUSED(connected);
-}
-
-void MMF::VideoPlayer::videoWindowChanged()
-{
-    TRACE_CONTEXT(VideoPlayer::videoOutputRegionChanged, EVideoInternal);
-    TRACE_ENTRY("state %d", state());
-
-    m_window = m_videoOutput->videoWindow();
-    updateVideoRect();
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::suspendDirectScreenAccess()
-{
-    m_dsaWasActive = stopDirectScreenAccess();
-}
-
-void MMF::VideoPlayer::resumeDirectScreenAccess()
-{
-    if(m_dsaWasActive) {
-        startDirectScreenAccess();
-        m_dsaWasActive = false;
-    }
-}
-
-void MMF::VideoPlayer::startDirectScreenAccess()
-{
-    if(!m_dsaActive) {
-        TRAPD(err, m_player->StartDirectScreenAccessL());
-        if(KErrNone == err)
-            m_dsaActive = true;
-        else
-            setError(tr("Video display error"), err);
-    }
-}
-
-bool MMF::VideoPlayer::stopDirectScreenAccess()
-{
-    const bool dsaWasActive = m_dsaActive;
-    if(m_dsaActive) {
-        TRAPD(err, m_player->StopDirectScreenAccessL());
-        if(KErrNone == err)
-            m_dsaActive = false;
-        else
-            setError(tr("Video display error"), err);
-    }
-    return dsaWasActive;
-}
-
-// Helper function for aspect ratio / scale mode handling
-QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight)
-{
-    const qreal aspectRatio = qreal(aspectWidth) / aspectHeight;
-
-    int width = srcRect.width();
-    int height = srcRect.width() / aspectRatio;
-    if (height > srcRect.height()){
-        height = srcRect.height();
-        width = srcRect.height() * aspectRatio;
-    }
-    return QSize(width, height);
-}
-
-void MMF::VideoPlayer::updateVideoRect()
-{
-    QRect videoRect;
-    QRect windowRect = m_videoOutput->videoWindowRect();
-
-    // Clip to physical window size
-    // This is due to a defect in the layout when running on S60 3.2, which
-    // results in the rectangle of the video widget extending outside the
-    // screen in certain circumstances.  These include the initial startup
-    // of the mediaplayer demo in portrait mode.  When this rectangle is
-    // passed to the CVideoPlayerUtility, no video is rendered.
-    const TSize screenSize = m_screenDevice.SizeInPixels();
-    const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight);
-    windowRect = windowRect.intersected(screenRect);
-
-    const QSize windowSize = windowRect.size();
-
-    // Calculate size of smallest rect which contains video frame size
-    // and conforms to aspect ratio
-    switch (m_videoOutput->aspectRatio()) {
-    case Phonon::VideoWidget::AspectRatioAuto:
-        videoRect.setSize(m_videoFrameSize);
-        break;
-
-    case Phonon::VideoWidget::AspectRatioWidget:
-        videoRect.setSize(windowSize);
-        break;
-
-    case Phonon::VideoWidget::AspectRatio4_3:
-        videoRect.setSize(scaleToAspect(m_videoFrameSize, 4, 3));
-        break;
-
-    case Phonon::VideoWidget::AspectRatio16_9:
-        videoRect.setSize(scaleToAspect(m_videoFrameSize, 16, 9));
-        break;
-    }
-
-    // Scale to fill the window width
-    const int windowWidth = windowSize.width();
-    const int windowHeight = windowSize.height();
-    const qreal windowScaleFactor = qreal(windowWidth) / videoRect.width();
-    int videoWidth = windowWidth;
-    int videoHeight = videoRect.height() * windowScaleFactor;
-
-    const qreal windowToVideoHeightRatio = qreal(windowHeight) / videoHeight;
-
-    switch(m_videoOutput->scaleMode()) {
-    case Phonon::VideoWidget::ScaleAndCrop:
-        if(videoHeight < windowHeight) {
-            videoWidth *= windowToVideoHeightRatio;
-            videoHeight = windowHeight;
-        }
-        break;
-    case Phonon::VideoWidget::FitInView:
-    default:
-        if(videoHeight > windowHeight) {
-            videoWidth *= windowToVideoHeightRatio;
-            videoHeight = windowHeight;
-        }
-        break;
-    }
-
-    // Calculate scale factors
-    m_scaleWidth = 100.0f * videoWidth / m_videoFrameSize.width();
-    m_scaleHeight = 100.0f * videoHeight / m_videoFrameSize.height();
-
-    m_videoRect = qt_QRect2TRect(windowRect);
-
-    if (state() == LoadingState)
-        m_pendingChanges = true;
-    else {
-        applyVideoWindowChange();
-        m_pendingChanges = false;
-    }
-}
-
-void MMF::VideoPlayer::aspectRatioChanged()
-{
-    TRACE_CONTEXT(VideoPlayer::aspectRatioChanged, EVideoInternal);
-    TRACE_ENTRY("state %d aspectRatio %d", state());
-
-    updateVideoRect();
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoPlayer::scaleModeChanged()
-{
-    TRACE_CONTEXT(VideoPlayer::scaleModeChanged, EVideoInternal);
-    TRACE_ENTRY("state %d", state());
-
-    updateVideoRect();
-
-    TRACE_EXIT_0();
-}
-
-#ifndef QT_NO_DEBUG
-
-// The following code is for debugging problems related to video visibility.  It allows
-// the VideoPlayer instance to query the window server in order to determine the
-// DSA drawing region for the video window.
-
-class CDummyAO : public CActive
-{
-public:
-    CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); }
-    void RunL() { }
-    void DoCancel() { }
-    TRequestStatus& Status() { return iStatus; }
-    void SetActive() { CActive::SetActive(); }
-};
-
-void getDsaRegion(RWsSession &session, const RWindowBase &window)
-{
-    RDirectScreenAccess dsa(session);
-    TInt err = dsa.Construct();
-    CDummyAO ao;
-    RRegion* region;
-    err = dsa.Request(region, ao.Status(), window);
-    ao.SetActive();
-    dsa.Close();
-    ao.Cancel();
-    if (region) {
-        qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count();
-        for (int i=0; i<region->Count(); ++i) {
-            const TRect& rect = region->RectangleList()[i];
-            qDebug() << "Phonon::MMF::getDsaRegion rect"
-                << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY;
-        }
-        region->Close();
-    }
-}
-
-#endif // _DEBUG
-
-void MMF::VideoPlayer::applyPendingChanges()
-{
-    if(m_pendingChanges)
-        applyVideoWindowChange();
-
-    m_pendingChanges = false;
-}
-
-void MMF::VideoPlayer::applyVideoWindowChange()
-{
-    TRACE_CONTEXT(VideoPlayer::applyVideoWindowChange, EVideoInternal);
-    TRACE_ENTRY_0();
-
-#ifndef QT_NO_DEBUG
-    getDsaRegion(m_wsSession, *m_window);
-#endif
-
-    static const TBool antialias = ETrue;
-
-    TRAPD(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias));
-    if(KErrNone != err) {
-        TRACE("SetScaleFactorL (1) err %d", err);
-        setError(tr("Video display error"), err);
-    }
-
-    if(KErrNone == err) {
-        TRAP(err,
-            m_player->SetDisplayWindowL
-                (
-                    m_wsSession, m_screenDevice,
-                    *m_window,
-                    m_videoRect, m_videoRect
-                )
-            );
-
-        if (KErrNone != err) {
-            TRACE("SetDisplayWindowL err %d", err);
-            setError(tr("Video display error"), err);
-        } else {
-            m_dsaActive = true;
-            TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias));
-            if(KErrNone != err) {
-                TRACE("SetScaleFactorL (2) err %d", err);
-                setError(tr("Video display error"), err);
-            }
-        }
-    }
-
-    TRACE_EXIT_0();
-}
-
-
-//-----------------------------------------------------------------------------
-// Metadata
-//-----------------------------------------------------------------------------
-
-int MMF::VideoPlayer::numberOfMetaDataEntries() const
-{
-    int numberOfEntries = 0;
-    TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL());
-    return numberOfEntries;
-}
-
-QPair<QString, QString> MMF::VideoPlayer::metaDataEntry(int index) const
-{
-    CMMFMetaDataEntry *entry = 0;
-    QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index));
-    return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value()));
-}
-
-QT_END_NAMESPACE
-
Index: trunk/src/3rdparty/phonon/mmf/mmf_videoplayer.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/mmf_videoplayer.h	(revision 766)
+++ 	(revision )
@@ -1,138 +1,0 @@
-/*  This file is part of the KDE project.
-
-Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-
-This library is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 2.1 or 3 of the License.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with this library.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef PHONON_MMF_VIDEOPLAYER_H
-#define PHONON_MMF_VIDEOPLAYER_H
-
-#include <videoplayer.h> // from epoc32/include
-
-#include "abstractmediaplayer.h"
-#include "videooutput.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Phonon
-{
-namespace MMF
-{
-/**
- * @short Wrapper over MMF video client utility
- *
- * See
- * <a href="http://wiki.forum.nokia.com/index.php/How_to_play_a_video_file_using_CVideoPlayerUtility">How to
- * play a video file using CVideoPlayerUtility</a>
- */
-class VideoPlayer : public AbstractMediaPlayer
-                  , public MVideoPlayerUtilityObserver
-                  , public MVideoLoadingObserver
-{
-    Q_OBJECT
-
-public:
-    VideoPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0);
-    virtual ~VideoPlayer();
-
-    typedef CVideoPlayerUtility NativePlayer;
-    NativePlayer *nativePlayer() const;
-
-    // AbstractPlayer
-    virtual void doPlay();
-    virtual void doPause();
-    virtual void doStop();
-    virtual void doSeek(qint64 milliseconds);
-    virtual int setDeviceVolume(int mmfVolume);
-    virtual int openFile(RFile& file);
-    virtual int openUrl(const QString& url);
-    virtual int bufferStatus() const;
-    virtual void close();
-
-    // MediaObjectInterface
-    virtual bool hasVideo() const;
-    virtual qint64 currentTime() const;
-    virtual qint64 totalTime() const;
-
-    // AbstractPlayer
-    virtual void videoOutputChanged();
-
-    // AbstractMediaPlayer
-    virtual int numberOfMetaDataEntries() const;
-    virtual QPair<QString, QString> metaDataEntry(int index) const;
-
-public Q_SLOTS:
-    void videoWindowChanged();
-    void aspectRatioChanged();
-    void scaleModeChanged();
-    void suspendDirectScreenAccess();
-    void resumeDirectScreenAccess();
-
-private:
-    void construct();
-
-    void doPrepareCompleteL(TInt aError);
-
-    void getVideoWindow();
-    void initVideoOutput();
-    void updateVideoRect();
-
-    void applyPendingChanges();
-    void applyVideoWindowChange();
-
-    void startDirectScreenAccess();
-    bool stopDirectScreenAccess();
-
-private:
-    // MVideoPlayerUtilityObserver
-    virtual void MvpuoOpenComplete(TInt aError);
-    virtual void MvpuoPrepareComplete(TInt aError);
-    virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError);
-    virtual void MvpuoPlayComplete(TInt aError);
-    virtual void MvpuoEvent(const TMMFEvent &aEvent);
-
-    // MVideoLoadingObserver
-    virtual void MvloLoadingStarted();
-    virtual void MvloLoadingComplete();
-
-private:
-    QScopedPointer<NativePlayer>        m_player;
-
-    // Not owned
-    RWsSession&                         m_wsSession;
-    CWsScreenDevice&                    m_screenDevice;
-    RWindowBase*                        m_window;
-
-    /* Extent of the video display - will be clipped to m_windowRect */
-    TRect                               m_videoRect;
-
-    TReal32                             m_scaleWidth;
-    TReal32                             m_scaleHeight;
-
-    QSize                               m_videoFrameSize;
-    qint64                              m_totalTime;
-
-    bool                                m_pendingChanges;
-    bool                                m_dsaActive;
-    bool                                m_dsaWasActive;
-
-};
-
-}
-}
-
-QT_END_NAMESPACE
-
-#endif
Index: trunk/src/3rdparty/phonon/mmf/utils.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/utils.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/utils.cpp	(revision 769)
@@ -53,20 +53,22 @@
 }
 
-
-static const TInt KMimePrefixLength = 6; // either "audio/" or "video/"
 _LIT(KMimePrefixAudio, "audio/");
 _LIT(KMimePrefixVideo, "video/");
+_LIT(KMimeSDP, "application/sdp");
+
+enum ConstantStringLengths {
+    KMimePrefixLength = 6, // either "audio/" or "video/",
+    KMimeSDPLength = 15 // "application/sdp"
+};
 
 MMF::MediaType MMF::Utils::mimeTypeToMediaType(const TDesC& mimeType)
 {
-    MediaType result = MediaTypeUnknown;
-
     if (mimeType.Left(KMimePrefixLength).Compare(KMimePrefixAudio) == 0) {
-        result = MediaTypeAudio;
-    } else if (mimeType.Left(KMimePrefixLength).Compare(KMimePrefixVideo) == 0) {
-        result = MediaTypeVideo;
-    }
-
-    return result;
+        return MediaTypeAudio;
+    } else if (mimeType.Left(KMimePrefixLength).Compare(KMimePrefixVideo) == 0 ||
+               mimeType.Left(KMimeSDPLength).Compare(KMimeSDP) == 0) {
+        return MediaTypeVideo;
+    } else
+        return MediaTypeUnknown;
 }
 
Index: trunk/src/3rdparty/phonon/mmf/videooutput.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videooutput.cpp	(revision 766)
+++ 	(revision )
@@ -1,303 +1,0 @@
-/*  This file is part of the KDE project.
-
-Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-
-This library is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 2.1 or 3 of the License.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with this library.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ancestormovemonitor.h"
-#include "utils.h"
-#include "videooutput.h"
-
-#ifndef QT_NO_DEBUG
-#include "objectdump.h"
-#endif
-
-#include <QPaintEvent>
-#include <QPainter>
-#include <QMoveEvent>
-#include <QResizeEvent>
-
-#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
-#include <QtGui/private/qwidget_p.h> // to access QWExtra
-
-#include <coecntrl.h>
-
-#include <coemain.h>    // for CCoeEnv
-
-QT_BEGIN_NAMESPACE
-
-using namespace Phonon;
-using namespace Phonon::MMF;
-
-/*! \class MMF::VideoOutput
-  \internal
-*/
-
-//-----------------------------------------------------------------------------
-// Constants
-//-----------------------------------------------------------------------------
-
-static const Phonon::VideoWidget::AspectRatio DefaultAspectRatio =
-    Phonon::VideoWidget::AspectRatioAuto;
-static const Phonon::VideoWidget::ScaleMode DefaultScaleMode =
-    Phonon::VideoWidget::FitInView;
-
-
-//-----------------------------------------------------------------------------
-// Constructor / destructor
-//-----------------------------------------------------------------------------
-
-MMF::VideoOutput::VideoOutput
-    (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent)
-        :   QWidget(parent)
-        ,   m_ancestorMoveMonitor(ancestorMoveMonitor)
-        ,   m_aspectRatio(DefaultAspectRatio)
-        ,   m_scaleMode(DefaultScaleMode)
-{
-    TRACE_CONTEXT(VideoOutput::VideoOutput, EVideoInternal);
-    TRACE_ENTRY("parent 0x%08x", parent);
-
-    setPalette(QPalette(Qt::black));
-    setAttribute(Qt::WA_OpaquePaintEvent, true);
-    setAttribute(Qt::WA_NoSystemBackground, true);
-    setAutoFillBackground(false);
-
-    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill;
-    qt_widget_private(this)->extraData()->receiveNativePaintEvents = true;
-
-    getVideoWindowRect();
-    registerForAncestorMoved();
-
-    dump();
-
-    TRACE_EXIT_0();
-}
-
-MMF::VideoOutput::~VideoOutput()
-{
-    TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal);
-    TRACE_ENTRY_0();
-
-    m_ancestorMoveMonitor->unRegisterTarget(this);
-
-    TRACE_EXIT_0();
-}
-
-void MMF::VideoOutput::setVideoSize(const QSize& frameSize)
-{
-    TRACE_CONTEXT(VideoOutput::setVideoSize, EVideoInternal);
-    TRACE("oldSize %d %d newSize %d %d",
-          m_videoFrameSize.width(), m_videoFrameSize.height(),
-          frameSize.width(), frameSize.height());
-
-    if (frameSize != m_videoFrameSize) {
-        m_videoFrameSize = frameSize;
-        updateGeometry();
-    }
-}
-
-void MMF::VideoOutput::ancestorMoved()
-{
-    TRACE_CONTEXT(VideoOutput::ancestorMoved, EVideoInternal);
-    TRACE_ENTRY_0();
-
-    RWindowBase *const window = videoWindow();
-
-    if(window) {
-        const TPoint newWindowPosSymbian = window->AbsPosition();
-        const QPoint newWindowPos(newWindowPosSymbian.iX, newWindowPosSymbian.iY);
-
-        if(newWindowPos != m_videoWindowRect.topLeft()) {
-            m_videoWindowRect.moveTo(newWindowPos);
-            emit videoWindowChanged();
-        }
-    }
-
-    TRACE_EXIT_0();
-}
-
-//-----------------------------------------------------------------------------
-// QWidget
-//-----------------------------------------------------------------------------
-
-QSize MMF::VideoOutput::sizeHint() const
-{
-    // TODO: replace this with a more sensible default
-    QSize result(320, 240);
-
-    if (!m_videoFrameSize.isNull())
-        result = m_videoFrameSize;
-
-    return result;
-}
-
-void MMF::VideoOutput::paintEvent(QPaintEvent* event)
-{
-    TRACE_CONTEXT(VideoOutput::paintEvent, EVideoInternal);
-    TRACE("rect %d %d - %d %d",
-          event->rect().left(), event->rect().top(),
-          event->rect().right(), event->rect().bottom());
-    TRACE("regions %d", event->region().rectCount());
-    TRACE("type %d", event->type());
-
-    // Do nothing
-}
-
-void MMF::VideoOutput::resizeEvent(QResizeEvent* event)
-{
-    TRACE_CONTEXT(VideoOutput::resizeEvent, EVideoInternal);
-    TRACE("%d %d -> %d %d",
-          event->oldSize().width(), event->oldSize().height(),
-          event->size().width(), event->size().height());
-
-    if(event->size() != event->oldSize()) {
-        m_videoWindowRect.setSize(event->size());
-        emit videoWindowChanged();
-    }
-}
-
-void MMF::VideoOutput::moveEvent(QMoveEvent* event)
-{
-    TRACE_CONTEXT(VideoOutput::moveEvent, EVideoInternal);
-    TRACE("%d %d -> %d %d",
-          event->oldPos().x(), event->oldPos().y(),
-          event->pos().x(), event->pos().y());
-
-    if(event->pos() != event->oldPos()) {
-        m_videoWindowRect.moveTo(event->pos());
-        emit videoWindowChanged();
-    }
-}
-
-bool MMF::VideoOutput::event(QEvent* event)
-{
-    TRACE_CONTEXT(VideoOutput::event, EVideoInternal);
-
-    if (event->type() == QEvent::WinIdChange) {
-        TRACE_0("WinIdChange");
-        getVideoWindowRect();
-        emit videoWindowChanged();
-        return true;
-    } else if (event->type() == QEvent::ParentChange) {
-        // Tell ancestor move monitor to update ancestor list for this widget
-        registerForAncestorMoved();
-        return true;
-    } else
-        return QWidget::event(event);
-}
-
-
-//-----------------------------------------------------------------------------
-// Public functions
-//-----------------------------------------------------------------------------
-
-RWindowBase* MMF::VideoOutput::videoWindow()
-{
-    CCoeControl *control = internalWinId();
-    if(!control)
-        control = effectiveWinId();
-
-    RWindowBase *window = 0;
-    if(control)
-        window = control->DrawableWindow();
-
-    return window;
-}
-
-const QRect& MMF::VideoOutput::videoWindowRect() const
-{
-    return m_videoWindowRect;
-}
-
-Phonon::VideoWidget::AspectRatio MMF::VideoOutput::aspectRatio() const
-{
-    return m_aspectRatio;
-}
-
-void MMF::VideoOutput::setAspectRatio
-    (Phonon::VideoWidget::AspectRatio aspectRatio)
-{
-    if(m_aspectRatio != aspectRatio) {
-        m_aspectRatio = aspectRatio;
-        emit aspectRatioChanged();
-    }
-}
-
-Phonon::VideoWidget::ScaleMode MMF::VideoOutput::scaleMode() const
-{
-    return m_scaleMode;
-}
-
-void MMF::VideoOutput::setScaleMode
-    (Phonon::VideoWidget::ScaleMode scaleMode)
-{
-    if(m_scaleMode != scaleMode) {
-        m_scaleMode = scaleMode;
-        emit scaleModeChanged();
-    }
-}
-
-
-//-----------------------------------------------------------------------------
-// Private functions
-//-----------------------------------------------------------------------------
-
-void MMF::VideoOutput::getVideoWindowRect()
-{
-    RWindowBase *const window = videoWindow();
-    if(window)
-        m_videoWindowRect =
-            qt_TRect2QRect(TRect(window->AbsPosition(), window->Size()));
-}
-
-void MMF::VideoOutput::registerForAncestorMoved()
-{
-    m_ancestorMoveMonitor->registerTarget(this);
-}
-
-void MMF::VideoOutput::dump() const
-{
-#ifndef QT_NO_DEBUG
-    TRACE_CONTEXT(VideoOutput::dump, EVideoInternal);
-
-    QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor);
-    visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs
-    ObjectDump::addDefaultAnnotators(*visitor);
-    TRACE("Dumping tree from leaf 0x%08x:", this);
-    ObjectDump::dumpTreeFromLeaf(*this, *visitor);
-
-    QScopedPointer<ObjectDump::QDumper> dumper(new ObjectDump::QDumper);
-    dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs
-    ObjectDump::addDefaultAnnotators(*dumper);
-    TRACE_0("Dumping VideoOutput:");
-    dumper->dumpObject(*this);
-#endif
-}
-
-void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/)
-{
-    emit beginVideoWindowNativePaint();
-}
-
-void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/)
-{
-    // Ensure that draw ops are executed into the WSERV output framebuffer
-    CCoeEnv::Static()->WsSession().Flush();
-
-    emit endVideoWindowNativePaint();
-}
-
-QT_END_NAMESPACE
-
Index: trunk/src/3rdparty/phonon/mmf/videooutput.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videooutput.h	(revision 766)
+++ 	(revision )
@@ -1,105 +1,0 @@
-/*  This file is part of the KDE project.
-
-Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-
-This library is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 2.1 or 3 of the License.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with this library.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef PHONON_MMF_VIDEOOUTPUT_H
-#define PHONON_MMF_VIDEOOUTPUT_H
-
-#include <QtGui/QWidget>
-#include <QVector>
-#include <QRect>
-#include "defs.h"
-
-#include <phonon/videowidget.h>
-
-#include <e32std.h>
-class RWindowBase;
-
-QT_BEGIN_NAMESPACE
-
-namespace Phonon
-{
-namespace MMF
-{
-class AncestorMoveMonitor;
-
-class VideoOutput       :   public QWidget
-{
-    Q_OBJECT
-
-public:
-    VideoOutput(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent);
-    ~VideoOutput();
-
-    // Set size of video frame.  Called by VideoPlayer.
-    void setVideoSize(const QSize& size);
-
-    RWindowBase* videoWindow();
-    const QRect& videoWindowRect() const;
-
-    Phonon::VideoWidget::AspectRatio aspectRatio() const;
-    void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio);
-
-    Phonon::VideoWidget::ScaleMode scaleMode() const;
-    void setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode);
-
-    // Called by AncestorMoveMonitor
-    void ancestorMoved();
-
-    // Debugging output
-    void dump() const;
-
-public Q_SLOTS:
-    void beginNativePaintEvent(const QRect& /*controlRect*/);
-    void endNativePaintEvent(const QRect& /*controlRect*/);
-
-Q_SIGNALS:
-    void videoWindowChanged();
-    void aspectRatioChanged();
-    void scaleModeChanged();
-    void beginVideoWindowNativePaint();
-    void endVideoWindowNativePaint();
-
-protected:
-    // Override QWidget functions
-    QSize sizeHint() const;
-    void paintEvent(QPaintEvent* event);
-    void resizeEvent(QResizeEvent* event);
-    void moveEvent(QMoveEvent* event);
-    bool event(QEvent* event);
-
-private:
-    void getVideoWindowRect();
-    void registerForAncestorMoved();
-
-private:
-    // Not owned
-    AncestorMoveMonitor*    m_ancestorMoveMonitor;
-
-    QSize                   m_videoFrameSize;
-    QRect                   m_videoWindowRect;
-
-    Phonon::VideoWidget::AspectRatio        m_aspectRatio;
-    Phonon::VideoWidget::ScaleMode          m_scaleMode;
-
-};
-}
-}
-
-QT_END_NAMESPACE
-
-#endif
Index: trunk/src/3rdparty/phonon/mmf/videooutput_dsa.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videooutput_dsa.cpp	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videooutput_dsa.cpp	(revision 769)
@@ -0,0 +1,183 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
+#include <QtGui/private/qwidget_p.h> // to access QWExtra
+#include <QResizeEvent>
+#include <QMoveEvent>
+
+#include <coemain.h> // for CCoeEnv
+
+#include "ancestormovemonitor.h"
+#include "utils.h"
+#include "videooutput_dsa.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+DsaVideoOutput::DsaVideoOutput(QWidget *parent)
+    :   AbstractVideoOutput(parent)
+    ,   m_ancestorMoveMonitor(0)
+{
+    TRACE_CONTEXT(DsaVideoOutput::DsaVideoOutput, EVideoInternal);
+    TRACE_ENTRY("parent 0x%08x", parent);
+
+    setPalette(QPalette(Qt::black));
+    setAttribute(Qt::WA_OpaquePaintEvent, true);
+    setAttribute(Qt::WA_NoSystemBackground, true);
+    setAutoFillBackground(false);
+
+    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill;
+    qt_widget_private(this)->extraData()->receiveNativePaintEvents = true;
+
+    getVideoWindowScreenRect();
+
+    dump();
+
+    TRACE_EXIT_0();
+}
+
+DsaVideoOutput::~DsaVideoOutput()
+{
+    TRACE_CONTEXT(DsaVideoOutput::~DsaVideoOutput, EVideoInternal);
+    TRACE_ENTRY_0();
+
+    m_ancestorMoveMonitor->unRegisterTarget(this);
+
+    TRACE_EXIT_0();
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoOutput::setAncestorMoveMonitor(AncestorMoveMonitor *monitor)
+{
+    m_ancestorMoveMonitor = monitor;
+    registerForAncestorMoved();
+}
+
+const QRect& MMF::DsaVideoOutput::videoWindowScreenRect() const
+{
+    return m_videoWindowScreenRect;
+}
+
+void MMF::DsaVideoOutput::ancestorMoved()
+{
+    TRACE_CONTEXT(DsaVideoOutput::ancestorMoved, EVideoInternal);
+    TRACE_ENTRY_0();
+
+    RWindowBase *const window = videoWindow();
+
+    if (window) {
+        const TPoint newWindowPosSymbian = window->AbsPosition();
+        const QPoint newWindowPos(newWindowPosSymbian.iX, newWindowPosSymbian.iY);
+
+        if (newWindowPos != m_videoWindowScreenRect.topLeft()) {
+            m_videoWindowScreenRect.moveTo(newWindowPos);
+            emit videoWindowScreenRectChanged();
+        }
+    }
+
+    TRACE_EXIT_0();
+}
+
+void MMF::DsaVideoOutput::beginNativePaintEvent(const QRect & /*controlRect*/)
+{
+    TRACE_CONTEXT(DsaVideoOutput::beginNativePaintEvent, EVideoInternal);
+    TRACE_ENTRY_0();
+
+    emit beginVideoWindowNativePaint();
+}
+
+void MMF::DsaVideoOutput::endNativePaintEvent(const QRect & /*controlRect*/)
+{
+    TRACE_CONTEXT(DsaVideoOutput::endNativePaintEvent, EVideoInternal);
+    TRACE_ENTRY_0();
+
+    // Ensure that draw ops are executed into the WSERV output framebuffer
+    CCoeEnv::Static()->WsSession().Flush();
+
+    emit endVideoWindowNativePaint();
+}
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoOutput::getVideoWindowScreenRect()
+{
+    RWindowBase *const window = videoWindow();
+    if (window)
+        m_videoWindowScreenRect =
+            qt_TRect2QRect(TRect(window->AbsPosition(), window->Size()));
+}
+
+void MMF::DsaVideoOutput::registerForAncestorMoved()
+{
+    m_ancestorMoveMonitor->registerTarget(this);
+}
+
+void MMF::DsaVideoOutput::resizeEvent(QResizeEvent *event)
+{
+    TRACE_CONTEXT(DsaVideoOutput::resizeEvent, EVideoInternal);
+    TRACE("%d %d -> %d %d",
+          event->oldSize().width(), event->oldSize().height(),
+          event->size().width(), event->size().height());
+
+    if (event->size() != event->oldSize()) {
+        m_videoWindowScreenRect.setSize(event->size());
+        emit videoWindowScreenRectChanged();
+    }
+}
+
+void MMF::DsaVideoOutput::moveEvent(QMoveEvent *event)
+{
+    TRACE_CONTEXT(DsaVideoOutput::moveEvent, EVideoInternal);
+    TRACE("%d %d -> %d %d",
+          event->oldPos().x(), event->oldPos().y(),
+          event->pos().x(), event->pos().y());
+
+    if (event->pos() != event->oldPos()) {
+        m_videoWindowScreenRect.moveTo(event->pos());
+        emit videoWindowScreenRectChanged();
+    }
+}
+
+bool MMF::DsaVideoOutput::event(QEvent *event)
+{
+    TRACE_CONTEXT(DsaVideoOutput::event, EVideoInternal);
+
+    if (event->type() == QEvent::WinIdChange) {
+        TRACE_0("WinIdChange");
+        getVideoWindowScreenRect();
+        emit videoWindowChanged();
+        return true;
+    } else if (event->type() == QEvent::ParentChange) {
+        // Tell ancestor move monitor to update ancestor list for this widget
+        registerForAncestorMoved();
+        return true;
+    } else {
+        return QWidget::event(event);
+    }
+}
+
+QT_END_NAMESPACE
+
Index: trunk/src/3rdparty/phonon/mmf/videooutput_dsa.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videooutput_dsa.h	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videooutput_dsa.h	(revision 769)
@@ -0,0 +1,109 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_VIDEOOUTPUT_DSA_H
+#define PHONON_MMF_VIDEOOUTPUT_DSA_H
+
+#include <QRect>
+
+#include "phonon/mmf/abstractvideooutput.h"
+
+QT_BEGIN_NAMESPACE
+
+class QResizeEvent;
+class QMoveEvent;
+
+namespace Phonon
+{
+namespace MMF
+{
+class AncestorMoveMonitor;
+
+/**
+ * @short Widget on which video is displayed by DSA rendering
+ *
+ * This implementation is used on devices with the legacy graphics
+ * subsystem, which does not support surfaces.  On such devices,
+ * video rendering is done via Direct Screen Access (DSA), whereby
+ * the video decoder writes directly to the framebuffer.  To ensure
+ * that the window server and video decoder do not try to draw to
+ * the same screen region at the same time, the video subsystem
+ * first requests permission to perform DSA.  If the window server
+ * needs to draw to this screen region (for example to display a
+ * message dialog), it first notifies the video subsystem that it
+ * must stop rendering to this region.
+ *
+ * @see SurfaceVideoOutput
+ */
+class DsaVideoOutput
+    :   public AbstractVideoOutput
+{
+    Q_OBJECT
+
+public:
+    DsaVideoOutput(QWidget *parent);
+    ~DsaVideoOutput();
+
+    void setAncestorMoveMonitor(AncestorMoveMonitor *monitor);
+
+    // Get absolute screen rectangle for video window
+    const QRect& videoWindowScreenRect() const;
+
+    // Called by AncestorMoveMonitor
+    void ancestorMoved();
+
+public Q_SLOTS:
+    // Callbacks received from Symbian QtGui implementation, when it
+    // begins / ends blitting the video widget's backing store to the
+    // window server.
+    void beginNativePaintEvent(const QRect & /*controlRect*/);
+    void endNativePaintEvent(const QRect & /*controlRect*/);
+
+Q_SIGNALS:
+    void videoWindowScreenRectChanged();
+
+    // Emitted when the Symbian QtGui implementation begins / ends
+    // blitting the video widget's backing store to the window server.
+    void beginVideoWindowNativePaint();
+    void endVideoWindowNativePaint();
+
+private:
+    void getVideoWindowScreenRect();
+    void registerForAncestorMoved();
+
+    // QWidget
+    void resizeEvent(QResizeEvent *event);
+    void moveEvent(QMoveEvent *event);
+    bool event(QEvent *event);
+
+private:
+    // Not owned
+    AncestorMoveMonitor*    m_ancestorMoveMonitor;
+
+    // Absolute screen rectangle on which video is displayed
+    QRect                   m_videoWindowScreenRect;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOOUTPUT_DSA_H
+
Index: trunk/src/3rdparty/phonon/mmf/videooutput_surface.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videooutput_surface.cpp	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videooutput_surface.cpp	(revision 769)
@@ -0,0 +1,87 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <QResizeEvent>
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
+#include <QtGui/private/qwidget_p.h> // to access QWExtra
+
+#include "utils.h"
+#include "videooutput_surface.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+SurfaceVideoOutput::SurfaceVideoOutput(QWidget *parent)
+    :   AbstractVideoOutput(parent)
+{
+    TRACE_CONTEXT(SurfaceVideoOutput::SurfaceVideoOutput, EVideoInternal);
+    TRACE_ENTRY("parent 0x%08x", parent);
+
+    qt_widget_private(this)->createExtra();
+    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::Disable;
+
+    TRACE_EXIT_0();
+}
+
+SurfaceVideoOutput::~SurfaceVideoOutput()
+{
+    TRACE_CONTEXT(SurfaceVideoOutput::~SurfaceVideoOutput, EVideoInternal);
+    TRACE_ENTRY_0();
+
+    TRACE_EXIT_0();
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::SurfaceVideoOutput::resizeEvent(QResizeEvent *event)
+{
+    TRACE_CONTEXT(SurfaceVideoOutput::resizeEvent, EVideoInternal);
+    TRACE("%d %d -> %d %d",
+          event->oldSize().width(), event->oldSize().height(),
+          event->size().width(), event->size().height());
+
+    if (event->size() != event->oldSize())
+        emit videoWindowSizeChanged();
+}
+
+bool MMF::SurfaceVideoOutput::event(QEvent *event)
+{
+    TRACE_CONTEXT(SurfaceVideoOutput::event, EVideoInternal);
+
+    if (event->type() == QEvent::WinIdChange) {
+        TRACE_0("WinIdChange");
+        emit videoWindowChanged();
+        return true;
+    } else {
+        return QWidget::event(event);
+    }
+}
+
+
+QT_END_NAMESPACE
+
Index: trunk/src/3rdparty/phonon/mmf/videooutput_surface.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videooutput_surface.h	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videooutput_surface.h	(revision 769)
@@ -0,0 +1,66 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_VIDEOOUTPUT_SURFACE_H
+#define PHONON_MMF_VIDEOOUTPUT_SURFACE_H
+
+#include "phonon/mmf/abstractvideooutput.h"
+
+QT_BEGIN_NAMESPACE
+
+class QResizeEvent;
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Widget on which video is displayed by rendering to a surface
+ *
+ * This implementation is used on devices with a graphics subsystem which
+ * supports surfaces.
+ *
+ * @see DsaVideoOutput
+ */
+class SurfaceVideoOutput
+    :   public AbstractVideoOutput
+{
+    Q_OBJECT
+
+public:
+    SurfaceVideoOutput(QWidget *parent);
+    ~SurfaceVideoOutput();
+
+Q_SIGNALS:
+    void videoWindowSizeChanged();
+
+private:
+    // QWidget
+    void resizeEvent(QResizeEvent *event);
+    bool event(QEvent *event);
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOOUTPUT_SURFACE_H
+
Index: trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp	(revision 769)
@@ -0,0 +1,314 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <coecntrl.h> // for CCoeControl
+
+#include <QApplication>    // for QApplication::activeWindow
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
+
+#include "utils.h"
+#include "videooutput_dsa.h"
+#include "videoplayer_dsa.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Two-phase constructor idiom is used because construct() calls virtual
+// functions and therefore cannot be called from the AbstractVideoPlayer
+// C++ constructor.
+DsaVideoPlayer* DsaVideoPlayer::create(MediaObject *parent,
+                                       const AbstractPlayer *player)
+{
+    QScopedPointer<DsaVideoPlayer> self(new DsaVideoPlayer(parent, player));
+    self->construct();
+    return self.take();
+}
+
+DsaVideoPlayer::DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
+    :   AbstractVideoPlayer(parent, player)
+    ,   m_dsaActive(false)
+    ,   m_dsaWasActive(false)
+{
+
+}
+
+DsaVideoPlayer::~DsaVideoPlayer()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoPlayer::videoWindowScreenRectChanged()
+{
+    QRect windowRect = static_cast<DsaVideoOutput *>(m_videoOutput)->videoWindowScreenRect();
+
+    // Clip to physical window size
+    // This is due to a defect in the layout when running on S60 3.2, which
+    // results in the rectangle of the video widget extending outside the
+    // screen in certain circumstances.  These include the initial startup
+    // of the mediaplayer demo in portrait mode.  When this rectangle is
+    // passed to the CVideoPlayerUtility, no video is rendered.
+    const TSize screenSize = m_screenDevice.SizeInPixels();
+    const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight);
+    windowRect = windowRect.intersected(screenRect);
+
+    // Recalculate scale factors.  Pass 'false' as second parameter in order to
+    // suppress application of the change to the player - this is done at the end
+    // of the function.
+    updateScaleFactors(windowRect.size(), false);
+
+    m_videoScreenRect = qt_QRect2TRect(windowRect);
+
+    parametersChanged(WindowScreenRect | ScaleFactors);
+}
+
+void MMF::DsaVideoPlayer::suspendDirectScreenAccess()
+{
+    m_dsaWasActive = stopDirectScreenAccess();
+}
+
+void MMF::DsaVideoPlayer::resumeDirectScreenAccess()
+{
+    if (m_dsaWasActive) {
+        startDirectScreenAccess();
+        m_dsaWasActive = false;
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoPlayer::createPlayer()
+{
+    // A window handle must be provided in order to construct
+    // CVideoPlayerUtility.  If no VideoOutput has yet been connected to this
+    // player, we temporarily use the top-level application window handle.
+    // No video ever gets rendered into this window; SetDisplayWindowL is
+    // always called before rendering actually begins.
+    if (!m_window)
+        m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow();
+
+    const TInt priority = 0;
+    const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
+
+    CVideoPlayerUtility *player = 0;
+    QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL(*this,
+                                     priority, preference,
+                                     m_wsSession, m_screenDevice,
+                                     *m_window,
+                                     m_videoScreenRect, m_videoScreenRect));
+    m_player.reset(player);
+
+    // CVideoPlayerUtility::NewL starts DSA
+    m_dsaActive = true;
+
+    m_player->RegisterForVideoLoadingNotification(*this);
+}
+
+void MMF::DsaVideoPlayer::initVideoOutput()
+{
+    bool connected = connect(
+        m_videoOutput, SIGNAL(videoWindowScreenRectChanged()),
+        this, SLOT(videoWindowScreenRectChanged())
+    );
+    Q_ASSERT(connected);
+
+    connected = connect(
+        m_videoOutput, SIGNAL(beginVideoWindowNativePaint()),
+        this, SLOT(suspendDirectScreenAccess())
+    );
+    Q_ASSERT(connected);
+
+    connected = connect(
+        m_videoOutput, SIGNAL(endVideoWindowNativePaint()),
+        this, SLOT(resumeDirectScreenAccess())
+    );
+    Q_ASSERT(connected);
+
+    // Suppress warnings in release builds
+    Q_UNUSED(connected);
+
+    AbstractVideoPlayer::initVideoOutput();
+}
+
+void MMF::DsaVideoPlayer::prepareCompleted()
+{
+    videoWindowScreenRectChanged();
+}
+
+void MMF::DsaVideoPlayer::handleVideoWindowChanged()
+{
+    if (!m_window) {
+        if (QWidget *window = QApplication::activeWindow())
+            m_window = window->effectiveWinId()->DrawableWindow();
+        else
+            m_window = 0;
+        m_videoScreenRect = TRect();
+    }
+
+    parametersChanged(WindowHandle | WindowScreenRect);
+}
+
+#ifndef QT_NO_DEBUG
+
+// The following code is for debugging problems related to video visibility.  It allows
+// the VideoPlayer instance to query the window server in order to determine the
+// DSA drawing region for the video window.
+
+class CDummyAO : public CActive
+{
+public:
+    CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); }
+    void RunL() { }
+    void DoCancel() { }
+    TRequestStatus& Status() { return iStatus; }
+    void SetActive() { CActive::SetActive(); }
+};
+
+void getDsaRegion(RWsSession &session, const RWindowBase &window)
+{
+    // Dump complete window tree
+    session.LogCommand(RWsSession::ELoggingStatusDump);
+
+    RDirectScreenAccess dsa(session);
+    TInt err = dsa.Construct();
+    CDummyAO ao;
+    RRegion* region;
+    err = dsa.Request(region, ao.Status(), window);
+    ao.SetActive();
+    dsa.Close();
+    ao.Cancel();
+    if (region) {
+        qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count();
+        for (int i=0; i<region->Count(); ++i) {
+            const TRect& rect = region->RectangleList()[i];
+            qDebug() << "Phonon::MMF::getDsaRegion rect"
+                << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY;
+        }
+        region->Close();
+    }
+}
+
+#endif // QT_NO_DEBUG
+
+void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters)
+{
+    TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal);
+    TRACE_ENTRY("parameters 0x%x", parameters.operator int());
+
+    if (!m_window)
+        return;
+
+#ifndef QT_NO_DEBUG
+    getDsaRegion(m_wsSession, *m_window);
+#endif
+
+    if (m_player) {
+        static const TBool antialias = ETrue;
+        int err = KErrNone;
+
+        if (parameters & ScaleFactors) {
+            TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
+                                                antialias));
+            if(KErrNone != err) {
+                TRACE("SetScaleFactorL (1) err %d", err);
+                setError(tr("Video display error"), err);
+            }
+        }
+
+        if (KErrNone == err) {
+            if (parameters & WindowHandle || parameters & WindowScreenRect) {
+                TRAP(err,
+                    m_player->SetDisplayWindowL(m_wsSession, m_screenDevice,
+                                                *m_window,
+                                                m_videoScreenRect,
+                                                m_videoScreenRect));
+            }
+
+            if (KErrNone != err) {
+                TRACE("SetDisplayWindowL err %d", err);
+                setError(tr("Video display error"), err);
+            } else {
+                m_dsaActive = true;
+                if (parameters & ScaleFactors) {
+                    TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
+                                                        antialias));
+                    if (KErrNone != err) {
+                        TRACE("SetScaleFactorL (2) err %d", err);
+                        setError(tr("Video display error"), err);
+                    }
+                }
+            }
+        }
+    }
+
+    TRACE_EXIT_0();
+}
+
+void MMF::DsaVideoPlayer::startDirectScreenAccess()
+{
+    TRACE_CONTEXT(DsaVideoPlayer::startDirectScreenAccess, EVideoInternal);
+    TRACE_ENTRY("dsaActive %d", m_dsaActive);
+
+    int err = KErrNone;
+
+    if (!m_dsaActive) {
+        TRAP(err, m_player->StartDirectScreenAccessL());
+        if (KErrNone == err)
+            m_dsaActive = true;
+        else
+            setError(tr("Video display error"), err);
+    }
+
+    if (m_videoOutput)
+        m_videoOutput->dump();
+
+    TRACE_EXIT("error %d", err);
+}
+
+bool MMF::DsaVideoPlayer::stopDirectScreenAccess()
+{
+    TRACE_CONTEXT(DsaVideoPlayer::stopDirectScreenAccess, EVideoInternal);
+    TRACE_ENTRY("dsaActive %d", m_dsaActive);
+
+    int err = KErrNone;
+
+    const bool dsaWasActive = m_dsaActive;
+    if (m_dsaActive) {
+        TRAP(err, m_player->StopDirectScreenAccessL());
+        if (KErrNone == err)
+            m_dsaActive = false;
+        else
+            setError(tr("Video display error"), err);
+    }
+
+    TRACE_EXIT("error %d", err);
+
+    return dsaWasActive;
+}
+
+QT_END_NAMESPACE
+
Index: trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.h	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.h	(revision 769)
@@ -0,0 +1,92 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_VIDEOPLAYER_DSA_H
+#define PHONON_MMF_VIDEOPLAYER_DSA_H
+
+#include "abstractvideoplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Wrapper over the MMF video player utility (DSA version)
+ *
+ * This implementation is used on devices with the legacy graphics
+ * subsystem, which does not support surfaces.  On such devices,
+ * video rendering is done via Direct Screen Access (DSA), whereby
+ * the video decoder writes directly to the framebuffer.  To ensure
+ * that the window server and video decoder do not try to draw to
+ * the same screen region at the same time, the video subsystem
+ * first requests permission to perform DSA.  If the window server
+ * needs to draw to this screen region (for example to display a
+ * message dialog), it first notifies the video subsystem that it
+ * must stop rendering to this region.
+ *
+ * @see SurfaceVideoPlayer
+ */
+class DsaVideoPlayer
+    :   public AbstractVideoPlayer
+{
+    Q_OBJECT
+
+public:
+    // Factory function
+    static DsaVideoPlayer* create(MediaObject *parent = 0,
+                                  const AbstractPlayer *player = 0);
+    ~DsaVideoPlayer();
+
+public Q_SLOTS:
+    void videoWindowScreenRectChanged();
+    void suspendDirectScreenAccess();
+    void resumeDirectScreenAccess();
+
+private:
+    DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player);
+
+    // AbstractVideoPlayer
+    void createPlayer();
+    void initVideoOutput();
+    void prepareCompleted();
+    void handleVideoWindowChanged();
+    void handleParametersChanged(VideoParameters parameters);
+
+    void startDirectScreenAccess();
+    bool stopDirectScreenAccess();
+
+private:
+    bool                m_dsaActive;
+    bool                m_dsaWasActive;
+
+    // Absolute screen rectangle on which video is displayed
+    TRect               m_videoScreenRect;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOPLAYER_DSA_H
+
+
Index: trunk/src/3rdparty/phonon/mmf/videoplayer_surface.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videoplayer_surface.cpp	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videoplayer_surface.cpp	(revision 769)
@@ -0,0 +1,149 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <videoplayer2.h>
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_QRect2TRect
+
+#include "utils.h"
+#include "videooutput_surface.h"
+#include "videoplayer_surface.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Two-phase constructor idiom is used because construct() calls virtual
+// functions and therefore cannot be called from the AbstractVideoPlayer
+// C++ constructor.
+SurfaceVideoPlayer* SurfaceVideoPlayer::create(MediaObject *parent,
+                                       const AbstractPlayer *player)
+{
+    QScopedPointer<SurfaceVideoPlayer> self(new SurfaceVideoPlayer(parent, player));
+    self->construct();
+    return self.take();
+}
+
+SurfaceVideoPlayer::SurfaceVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
+    :   AbstractVideoPlayer(parent, player)
+    ,   m_displayWindow(0)
+{
+
+}
+
+SurfaceVideoPlayer::~SurfaceVideoPlayer()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void MMF::SurfaceVideoPlayer::videoWindowSizeChanged()
+{
+    updateScaleFactors(m_videoOutput->videoWindowSize());
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::SurfaceVideoPlayer::createPlayer()
+{
+    const TInt priority = 0;
+    const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
+
+    CVideoPlayerUtility2 *player = 0;
+    QT_TRAP_THROWING(player = CVideoPlayerUtility2::NewL(*this,
+                                         priority, preference));
+    m_player.reset(player);
+}
+
+void MMF::SurfaceVideoPlayer::initVideoOutput()
+{
+    bool connected = connect(
+        m_videoOutput, SIGNAL(videoWindowSizeChanged()),
+        this, SLOT(videoWindowSizeChanged())
+    );
+    Q_ASSERT(connected);
+
+    // Suppress warnings in release builds
+    Q_UNUSED(connected);
+
+    AbstractVideoPlayer::initVideoOutput();
+}
+
+void MMF::SurfaceVideoPlayer::prepareCompleted()
+{
+    videoWindowSizeChanged();
+}
+
+void MMF::SurfaceVideoPlayer::handleVideoWindowChanged()
+{
+    parametersChanged(WindowHandle);
+}
+
+void MMF::SurfaceVideoPlayer::handleParametersChanged(VideoParameters parameters)
+{
+    TRect rect;
+    if (m_videoOutput) {
+        m_videoOutput->dump();
+        const QSize size = m_videoOutput->videoWindowSize();
+        rect.SetSize(TSize(size.width(), size.height()));
+    }
+
+    CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data());
+    if (player) {
+        int err = KErrNone;
+        if (parameters & WindowHandle) {
+            if (m_displayWindow)
+                player->RemoveDisplayWindow(*m_displayWindow);
+
+            RWindow *window = static_cast<RWindow *>(m_window);
+            if (window) {
+                window->SetBackgroundColor(TRgb(0, 0, 0, 255));
+                TRAP(err, player->AddDisplayWindowL(m_wsSession, m_screenDevice, *window, rect, rect));
+                if (KErrNone != err) {
+                    setError(tr("Video display error"), err);
+                    window = 0;
+                }
+            }
+            m_displayWindow = window;
+        }
+
+        if (KErrNone == err) {
+            if (parameters & ScaleFactors) {
+                Q_ASSERT(m_displayWindow);
+                TRAP(err, player->SetVideoExtentL(*m_displayWindow, rect));
+                if (KErrNone == err)
+                    TRAP(err, player->SetWindowClipRectL(*m_displayWindow, rect));
+                if (KErrNone == err)
+                    TRAP(err, player->SetScaleFactorL(*m_displayWindow, m_scaleWidth, m_scaleHeight));
+                if (KErrNone != err)
+                    setError(tr("Video display error"), err);
+            }
+        }
+    }
+}
+
+QT_END_NAMESPACE
+
Index: trunk/src/3rdparty/phonon/mmf/videoplayer_surface.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videoplayer_surface.h	(revision 769)
+++ trunk/src/3rdparty/phonon/mmf/videoplayer_surface.h	(revision 769)
@@ -0,0 +1,78 @@
+/*  This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_VIDEOPLAYER_SURFACE_H
+#define PHONON_MMF_VIDEOPLAYER_SURFACE_H
+
+#include "abstractvideoplayer.h"
+
+class RWindow;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Wrapper over the MMF video player utility (surface version)
+ *
+ * This implementation is used on devices with a graphics subsystem which
+ * supports surfaces.
+ *
+ * @see DsaVideoPlayer
+ */
+class SurfaceVideoPlayer
+    :   public AbstractVideoPlayer
+{
+    Q_OBJECT
+
+public:
+    // Factory function
+    static SurfaceVideoPlayer* create(MediaObject *parent = 0,
+                                  const AbstractPlayer *player = 0);
+    ~SurfaceVideoPlayer();
+
+public Q_SLOTS:
+    void videoWindowSizeChanged();
+
+private:
+    SurfaceVideoPlayer(MediaObject *parent, const AbstractPlayer *player);
+
+    // AbstractVideoPlayer
+    void createPlayer();
+    void initVideoOutput();
+    void prepareCompleted();
+    void handleVideoWindowChanged();
+    void handleParametersChanged(VideoParameters parameters);
+
+private:
+    // Window handle which has been passed to the MMF via
+    // CVideoPlayerUtility2::SetDisplayWindowL
+    RWindow*    m_displayWindow;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOPLAYER_SURFACE_H
+
Index: trunk/src/3rdparty/phonon/mmf/videowidget.cpp
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videowidget.cpp	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/videowidget.cpp	(revision 769)
@@ -19,7 +19,12 @@
 #include "mediaobject.h"
 #include "utils.h"
-#include "videooutput.h"
 
 #include "videowidget.h"
+
+#ifdef PHONON_MMF_VIDEO_SURFACES
+#include "videooutput_surface.h"
+#else
+#include "videooutput_dsa.h"
+#endif
 
 QT_BEGIN_NAMESPACE
@@ -46,8 +51,11 @@
 //-----------------------------------------------------------------------------
 
-MMF::VideoWidget::VideoWidget
-    (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent)
+MMF::VideoWidget::VideoWidget(QWidget *parent)
         :   MediaNode(parent)
-        ,   m_videoOutput(new VideoOutput(ancestorMoveMonitor, parent))
+#ifdef PHONON_MMF_VIDEO_SURFACES
+        ,   m_videoOutput(new SurfaceVideoOutput(parent))
+#else
+        ,   m_videoOutput(new DsaVideoOutput(parent))
+#endif
         ,   m_brightness(DefaultBrightness)
         ,   m_contrast(DefaultContrast)
@@ -68,4 +76,11 @@
     TRACE_EXIT_0();
 }
+
+#ifndef PHONON_MMF_VIDEO_SURFACES
+void MMF::VideoWidget::setAncestorMoveMonitor(AncestorMoveMonitor *monitor)
+{
+    static_cast<DsaVideoOutput *>(m_videoOutput.data())->setAncestorMoveMonitor(monitor);
+}
+#endif
 
 
@@ -109,5 +124,5 @@
 {
     TRACE_CONTEXT(VideoWidget::setScaleMode, EVideoApi);
-    TRACE("setScaleMode %d", setScaleMode);
+    TRACE("setScaleMode %d", scaleMode);
 
     m_videoOutput->setScaleMode(scaleMode);
Index: trunk/src/3rdparty/phonon/mmf/videowidget.h
===================================================================
--- trunk/src/3rdparty/phonon/mmf/videowidget.h	(revision 766)
+++ trunk/src/3rdparty/phonon/mmf/videowidget.h	(revision 769)
@@ -20,6 +20,6 @@
 #define PHONON_MMF_VIDEOWIDGET_H
 
+#include "abstractvideooutput.h"
 #include "mmf_medianode.h"
-#include "videooutput.h"
 
 #include <QtGui/QWidget>
@@ -33,6 +33,7 @@
 namespace MMF
 {
+#ifndef PHONON_MMF_VIDEO_SURFACES
 class AncestorMoveMonitor;
-class VideoOutput;
+#endif
 
 class VideoWidget       :   public MediaNode
@@ -43,6 +44,10 @@
 
 public:
-    VideoWidget(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent);
+    VideoWidget(QWidget* parent);
     ~VideoWidget();
+
+#ifndef PHONON_MMF_VIDEO_SURFACES
+    void setAncestorMoveMonitor(AncestorMoveMonitor *ancestorMoveMonitor);
+#endif
 
     // VideoWidgetInterface
@@ -67,5 +72,5 @@
 
 private:
-    QScopedPointer<VideoOutput>             m_videoOutput;
+    QScopedPointer<AbstractVideoOutput>     m_videoOutput;
 
     qreal                                   m_brightness;
Index: trunk/src/3rdparty/phonon/qt7/audiodevice.mm
===================================================================
--- trunk/src/3rdparty/phonon/qt7/audiodevice.mm	(revision 766)
+++ trunk/src/3rdparty/phonon/qt7/audiodevice.mm	(revision 769)
@@ -150,5 +150,4 @@
     err = AudioDeviceGetProperty(deviceID, 0, 0, kAudioDevicePropertyDataSourceNameForIDCFString, &size, &translation);
 	if (err != noErr){
-        CFRelease(cfName);
         return QString();
     }
Index: trunk/src/3rdparty/webkit/ChangeLog
===================================================================
--- trunk/src/3rdparty/webkit/ChangeLog	(revision 766)
+++ trunk/src/3rdparty/webkit/ChangeLog	(revision 769)
@@ -1,2 +1,10 @@
+2010-02-18  Tor Arne VestbÃž  <tor.arne.vestbo@nokia.com>
+
+        Reviewed by Eric Seidel.
+
+        Add .gitattributes file for custom ChangeLog merge-driver
+
+        * .gitattributes: Added.
+
 2009-11-30  Jan-Arve SÃŠther  <jan-arve.saether@nokia.com>
 
Index: trunk/src/3rdparty/webkit/JavaScriptCore/ChangeLog
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/ChangeLog	(revision 766)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/ChangeLog	(revision 769)
@@ -1,2 +1,43 @@
+2010-03-22  Siddharth Mathur  <siddharth.mathur@nokia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        [Symbian] More efficient aligned memory allocation for JSC Collector
+        https://bugs.webkit.org/show_bug.cgi?id=34350
+
+        * JavaScriptCore.pri: Added 2 new Symbian source files and HAL linkage
+
+        * runtime/Collector.cpp: Reduced port-specific code and added private data member
+        (JSC::Heap::Heap):
+        (JSC::Heap::~Heap):
+        (JSC::Heap::destroy):
+        (JSC::Heap::allocateBlock):
+        (JSC::Heap::freeBlockPtr):
+
+        * runtime/Collector.h: Added private data member
+
+        * wtf/symbian: Added.
+        * wtf/symbian/BlockAllocatorSymbian.cpp: Added.
+        (WTF::AlignedBlockAllocator::AlignedBlockAllocator): Helper class to allocate 
+        aligned blocks more efficiently as required by Collector
+        (WTF::AlignedBlockAllocator::alloc):
+        (WTF::AlignedBlockAllocator::free):
+        (WTF::AlignedBlockAllocator::destroy):
+        (WTF::AlignedBlockAllocator::~AlignedBlockAllocator):
+        * wtf/symbian/BlockAllocatorSymbian.h: Added.
+
+2010-02-09  Janne Koskinen  <janne.p.koskinen@digia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        [Qt] use nanval() for Symbian as nonInlineNaN
+        https://bugs.webkit.org/show_bug.cgi?id=34170
+
+        numeric_limits<double>::quiet_NaN is broken in Symbian
+        causing NaN to be evaluated as a number.
+
+        * runtime/JSValue.cpp:
+        (JSC::nonInlineNaN):
+
 2010-01-07  Norbert Leser  <norbert.leser@nokia.com>
 
Index: trunk/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri	(revision 766)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri	(revision 769)
@@ -8,4 +8,8 @@
     isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}release
     !CONFIG(QTDIR_build):OBJECTS_DIR = obj/release
+}
+
+symbian {
+    LIBS += -lhal
 }
 
@@ -24,4 +28,5 @@
     $$PWD/wrec \
     $$PWD/wtf \
+    $$PWD/wtf/symbian \
     $$PWD/wtf/unicode \
     $$PWD/yarr \
@@ -244,4 +249,5 @@
     wtf/DateMath.cpp \
     wtf/FastMalloc.cpp \
+    wtf/symbian/BlockAllocatorSymbian.cpp \
     wtf/Threading.cpp \
     wtf/qt/MainThreadQt.cpp
Index: trunk/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp	(revision 769)
@@ -53,9 +53,4 @@
 #include <mach/vm_map.h>
 
-#elif PLATFORM(SYMBIAN)
-#include <e32std.h>
-#include <e32cmn.h>
-#include <unistd.h>
-
 #elif PLATFORM(WIN_OS)
 
@@ -125,9 +120,4 @@
 #define MIN_ARRAY_SIZE (static_cast<size_t>(14))
 
-#if PLATFORM(SYMBIAN)
-const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB
-static RHeap* userChunk = 0;
-#endif
-
 #if ENABLE(JSC_MULTIPLE_THREADS)
 
@@ -166,27 +156,9 @@
 #endif
     , m_globalData(globalData)
+#if PLATFORM(SYMBIAN)
+    , m_blockallocator(JSCCOLLECTOR_VIRTUALMEM_RESERVATION, BLOCK_SIZE)
+#endif
 {
     ASSERT(globalData);
-
-#if PLATFORM(SYMBIAN)
-    // Symbian OpenC supports mmap but currently not the MAP_ANON flag.
-    // Using fastMalloc() does not properly align blocks on 64k boundaries
-    // and previous implementation was flawed/incomplete.
-    // UserHeap::ChunkHeap allows allocation of continuous memory and specification
-    // of alignment value for (symbian) cells within that heap.
-    //
-    // Clarification and mapping of terminology:
-    // RHeap (created by UserHeap::ChunkHeap below) is continuos memory chunk,
-    // which can dynamically grow up to 8 MB,
-    // that holds all CollectorBlocks of this session (static).
-    // Each symbian cell within RHeap maps to a 64kb aligned CollectorBlock.
-    // JSCell objects are maintained as usual within CollectorBlocks.
-    if (!userChunk) {
-        userChunk = UserHeap::ChunkHeap(0, 0, MAX_NUM_BLOCKS * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
-        if (!userChunk)
-            CRASH();
-    }
-#endif // PLATFORM(SYMBIAN)
-
     memset(&primaryHeap, 0, sizeof(CollectorHeap));
     memset(&numberHeap, 0, sizeof(CollectorHeap));
@@ -234,5 +206,7 @@
     }
 #endif
-
+#if PLATFORM(SYMBIAN)
+    m_blockallocator.destroy();
+#endif
     m_globalData = 0;
 }
@@ -248,10 +222,7 @@
     vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
 #elif PLATFORM(SYMBIAN)
-    // Allocate a 64 kb aligned CollectorBlock
-    unsigned char* mask = reinterpret_cast<unsigned char*>(userChunk->Alloc(BLOCK_SIZE));
-    if (!mask)
+    void* address = m_blockallocator.alloc();  
+    if (!address)
         CRASH();
-    uintptr_t address = reinterpret_cast<uintptr_t>(mask);
-
     memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
 #elif (PLATFORM(OS2) && !HAVE(POSIX_MEMALIGN))
@@ -344,5 +315,5 @@
     vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE);
 #elif PLATFORM(SYMBIAN)
-    userChunk->Free(reinterpret_cast<TAny*>(block));
+    m_blockallocator.free(reinterpret_cast<void*>(block));
 #elif (PLATFORM(OS2) && !HAVE(POSIX_MEMALIGN))
     DosFreeMem(block);
Index: trunk/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h	(revision 766)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h	(revision 769)
@@ -36,4 +36,8 @@
 #endif
 
+#if PLATFORM(SYMBIAN)
+#include <wtf/symbian/BlockAllocatorSymbian.h>
+#endif
+
 #define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell)
 
@@ -158,4 +162,9 @@
 #endif
 
+#if PLATFORM(SYMBIAN)
+        // Allocates collector blocks with correct alignment
+        WTF::AlignedBlockAllocator m_blockallocator; 
+#endif
+        
         JSGlobalData* m_globalData;
     };
Index: trunk/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp	(revision 769)
@@ -175,5 +175,9 @@
 NEVER_INLINE double nonInlineNaN()
 {
+#if PLATFORM(SYMBIAN)
+    return nanval();
+#else
     return std::numeric_limits<double>::quiet_NaN();
+#endif
 }
 
Index: trunk/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp	(revision 769)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp	(revision 769)
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if PLATFORM(SYMBIAN)
+
+#include "BlockAllocatorSymbian.h"
+
+
+namespace WTF {
+
+/** Efficiently allocates blocks of size blockSize with blockSize alignment. 
+ * Primarly designed for JSC Collector's needs. 
+ * Not thread-safe.    
+ */
+AlignedBlockAllocator::AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize )
+    : m_reservation(reservationSize), 
+      m_blockSize(blockSize)
+{
+
+     // Get system's page size value.
+     SYMBIAN_PAGESIZE(m_pageSize); 
+     
+     // We only accept multiples of system page size for both initial reservation and the alignment/block size
+     m_reservation = SYMBIAN_ROUNDUPTOMULTIPLE(m_reservation, m_pageSize);
+     __ASSERT_ALWAYS(SYMBIAN_ROUNDUPTOMULTIPLE(m_blockSize, m_pageSize), User::Panic(_L("AlignedBlockAllocator1"), KErrArgument));
+     
+     // Calculate max. bit flags we need to carve a reservationSize range into blockSize-sized blocks
+     m_map.numBits = m_reservation / m_blockSize;   
+     const TUint32 bitsPerWord = 8*sizeof(TUint32); 
+     const TUint32 numWords = (m_map.numBits + bitsPerWord -1) / bitsPerWord; 
+   
+     m_map.bits = new TUint32[numWords];
+     __ASSERT_ALWAYS(m_map.bits, User::Panic(_L("AlignedBlockAllocator2"), KErrNoMemory));
+     m_map.clearAll();
+     
+     // Open a Symbian RChunk, and reserve requested virtual address range   
+     // Any thread in this process can operate this rchunk due to EOwnerProcess access rights. 
+     TInt ret = m_chunk.CreateDisconnectedLocal(0 , 0, (TInt)m_reservation , EOwnerProcess);  
+     if (ret != KErrNone) 
+         User::Panic(_L("AlignedBlockAllocator3"), ret);
+       
+     // This is the offset to m_chunk.Base() required to make it m_blockSize-aligned
+     m_offset = SYMBIAN_ROUNDUPTOMULTIPLE(TUint32(m_chunk.Base()), m_blockSize) - TUint(m_chunk.Base()); 
+
+}
+
+void* AlignedBlockAllocator::alloc()
+{
+
+    TInt  freeRam = 0; 
+    void* address = 0;
+    
+    // Look up first free slot in bit map
+    const TInt freeIdx = m_map.findFree();
+        
+    // Pseudo OOM: We ate up the address space we reserved..
+    // ..even though the device may have free RAM left
+    if (freeIdx < 0)
+        return 0;
+        
+    TInt ret = m_chunk.Commit(m_offset + (m_blockSize * freeIdx), m_blockSize);
+    if (ret != KErrNone)  
+        return 0; // True OOM: Device didn't have physical RAM to spare
+        
+    // Updated bit to mark region as in use. 
+    m_map.set(freeIdx); 
+    
+    // Calculate address of committed region (block)
+    address = (void*)( (m_chunk.Base() + m_offset) + (TUint)(m_blockSize * freeIdx) );
+    
+    return address;
+}
+
+void AlignedBlockAllocator::free(void* block)
+{
+    // Calculate index of block to be freed
+    TInt idx = TUint(static_cast<TUint8*>(block) - m_chunk.Base() - m_offset) / m_blockSize;
+    
+    __ASSERT_DEBUG(idx >= 0 && idx < m_map.numBits, User::Panic(_L("AlignedBlockAllocator4"), KErrCorrupt)); // valid index check
+    __ASSERT_DEBUG(m_map.get(idx), User::Panic(_L("AlignedBlockAllocator5"), KErrCorrupt)); // in-use flag check    
+    
+    // Return committed region to system RAM pool (the physical RAM becomes usable by others)
+    TInt ret = m_chunk.Decommit(m_offset + m_blockSize * idx, m_blockSize);
+            
+    // mark this available again
+    m_map.clear(idx); 
+}
+
+void AlignedBlockAllocator::destroy() 
+{
+    // release everything!
+    m_chunk.Decommit(0, m_chunk.MaxSize());
+    m_map.clearAll();
+}
+
+AlignedBlockAllocator::~AlignedBlockAllocator()
+{
+    destroy();
+    m_chunk.Close();
+    delete [] m_map.bits;
+}
+
+} // end of namespace
+
+#endif // SYMBIAN
Index: trunk/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h
===================================================================
--- trunk/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h	(revision 769)
+++ trunk/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h	(revision 769)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BlockAllocatorSymbian_h
+#define BlockAllocatorSymbian_h
+
+#include <e32cmn.h>
+#include <e32std.h>
+#include <hal.h>
+
+
+#define SYMBIAN_PAGESIZE(x) (HAL::Get(HALData::EMemoryPageSize, x));
+#define SYMBIAN_FREERAM(x)  (HAL::Get(HALData::EMemoryRAMFree, x));
+#define SYMBIAN_ROUNDUPTOMULTIPLE(x, multipleof)    ( (x + multipleof - 1) & ~(multipleof - 1) )
+
+// Set sane defaults if -D<flagname=value> wasn't provided via compiler args
+#ifndef JSCCOLLECTOR_VIRTUALMEM_RESERVATION
+#if defined(__WINS__) 
+    // Emulator has limited virtual address space
+    #define JSCCOLLECTOR_VIRTUALMEM_RESERVATION (4*1024*1024)
+#else
+    // HW has plenty of virtual addresses
+    #define JSCCOLLECTOR_VIRTUALMEM_RESERVATION (128*1024*1024)
+#endif
+#endif
+
+namespace WTF {
+
+/** 
+ *  Allocates contiguous region of size blockSize with blockSize-aligned address. 
+ *  blockSize must be a multiple of system page size (typically 4K on Symbian/ARM)
+ *
+ *  @param reservationSize Virtual address range to be reserved upon creation of chunk (bytes).
+ *  @param blockSize Size of a single allocation. Returned address will also be blockSize-aligned.
+ */
+class AlignedBlockAllocator {
+    public:
+        AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize);
+        ~AlignedBlockAllocator();
+        void destroy();
+        void* alloc();
+        void free(void* data);
+    
+    private: 
+        RChunk   m_chunk; // Symbian chunk that lets us reserve/commit/decommit
+        TUint    m_offset; // offset of first committed region from base 
+        TInt     m_pageSize; // cached value of system page size, typically 4K on Symbian
+        TUint32  m_reservation;
+        TUint32  m_blockSize;  
+
+        // Tracks comitted/decommitted state of a blockSize region
+        struct {
+            
+            TUint32 *bits; // array of bit flags 
+            TUint32  numBits; // number of regions to keep track of
+            
+            bool get(TUint32 n) const
+            {
+                return !!(bits[n >> 5] & (1 << (n & 0x1F)));
+            }
+            
+            void set(TUint32 n)
+            {
+                bits[n >> 5] |= (1 << (n & 0x1F));
+            }
+            
+            void clear(TUint32 n)
+            {
+                bits[n >> 5] &= ~(1 << (n & 0x1F));
+            }
+            
+            void clearAll()
+            {
+               for (TUint32 i = 0; i < numBits; i++)
+                    clear(i);
+            }
+            
+            TInt findFree() const
+            {
+                for (TUint32 i = 0; i < numBits; i++) {
+                    if (!get(i)) 
+                        return i;
+                }
+                return -1;
+            }
+            
+        } m_map;  
+
+};
+ 
+}
+
+#endif // end of BlockAllocatorSymbian_h
+
+
Index: trunk/src/3rdparty/webkit/VERSION
===================================================================
--- trunk/src/3rdparty/webkit/VERSION	(revision 766)
+++ trunk/src/3rdparty/webkit/VERSION	(revision 769)
@@ -9,3 +9,3 @@
 and has the sha1 checksum
 
-        69dd29fbeb12d076741dce70ac6bc155101ccd6f
+        b9dcd9c168d9b25deb020837a67f30c2d72c9afb
Index: trunk/src/3rdparty/webkit/WebCore/ChangeLog
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/ChangeLog	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/ChangeLog	(revision 769)
@@ -1,3 +1,452 @@
+2010-05-04  Tucker Jay  <jay.tucker@nokia.com>
+
+        Reviewed by Holger Freyther.
+
+        Animated GIF images does not animate 10x as expected by default.
+        https://bugs.webkit.org/show_bug.cgi?id=36818
+
+        Added test case to existing manual test to test the
+        fixed functionality.
+
+        * manual-tests/qt/qt-10loop-anim.gif: Added.
+        * manual-tests/qt/qt-gif-test.html:
+        * platform/graphics/qt/ImageDecoderQt.cpp:
+        (WebCore::ImageDecoderQt::repetitionCount):
+
+2010-04-21  Zoltan Herczeg  <zherczeg@webkit.org>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] startAnimation() is not needed to preceede nativeImageForCurrentFrame()
+        https://bugs.webkit.org/show_bug.cgi?id=37844
+
+        nativeImageForCurrentFrame() resets the m_decoder parameter under Qt,
+        which is required by startAnimation() to detect frame and repetition counts.
+        Hence, Image::drawTiled cannot start animations under Qt:
+        <html><body background="animated.gif"></body></html> does not work
+
+        * platform/graphics/qt/ImageDecoderQt.cpp:
+        (WebCore::ImageDecoderQt::internalHandleCurrentImage):
+
+2010-03-10  Holger Hans Peter Freyther  <zecke@selfish.org>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Non animated gifs are animated in QtWebKit
+        https://bugs.webkit.org/show_bug.cgi?id=35955
+
+        Properly map Qt animated and non-animated values to WebCore's
+        understanding of animated and non-animated images. Currently
+        we can not map anything to the cAnimationLoopNone value.
+
+        * manual-tests/qt/qt-anim.gif: Added.
+        * manual-tests/qt/qt-gif-test.html: Added.
+        * manual-tests/qt/qt-noanim.gif: Added.
+        * platform/graphics/qt/ImageDecoderQt.cpp:
+        (WebCore::ImageDecoderQt::repetitionCount):
+
+2010-04-26  Simon Hausmann  <simon.hausmann@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] Fix compilation with RVCT 4
+        https://bugs.webkit.org/show_bug.cgi?id=37727
+
+        Swap extern and declspec to fix visibility of symbol imported from QtGui.
+
+        * page/qt/EventHandlerQt.cpp:
+
+2010-04-26  Markus Goetz  <Markus.Goetz@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] HTTP pipelining efficiency increase
+        https://bugs.webkit.org/show_bug.cgi?id=38062
+
+        Increase number of network requests that are fed into
+        QNetworkAccessManager.
+
+        * platform/network/qt/ResourceRequestQt.cpp:
+        (WebCore::initializeMaximumHTTPConnectionCountPerHost):
+
+2009-11-03  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Allow a frame to go back to copy-on-scroll when it ceases being overlapped
+
+        The code was not testing slow-scrolling frames for overlappedness, thinking the answer
+        would not matter. That is not the case if the only reason for the slow-scrolling is
+        being overlapped.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::useSlowRepaintsIfNotOverlapped): Added. Returns whether there is any
+        reason besides being overlapped that the frame would need to fully repaint on scroll.
+        * page/FrameView.h:
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paint): Use useSlowRepaintsIfNotOverlapped().
+
+2010-04-09  David Leong  <david.leong@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Symbian apps crash on exit due to a bad qObject_cast.
+
+        https://bugs.webkit.org/show_bug.cgi?id=37303
+
+        Added check for NULL to avoid the crash.
+
+        * plugins/symbian/PluginViewSymbian.cpp:
+        (WebCore::PluginView::platformDestroy):
+
+2009-11-15  Dave Tapuska  <dtapuska@rim.com>
+
+        Reviewed by George Staikos.
+        
+        Compare UChars single unit at a time as opposed to the uint32_t
+        approach as casting to unaligned addresses may cause a bus failure
+        on ARMv5 and below. This change replicates the same defines that
+        exists in AtomicString.cpp
+
+        https://bugs.webkit.org/show_bug.cgi?id=31475
+        
+        * platform/text/StringHash.h:
+        (WebCore::StringHash::equal):
+
+2010-03-25  yael aharon  <yael.aharon@nokia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        [Qt] Windowed netscape plugins don't work with QGraphicsWebView on Symbian
+        https://bugs.webkit.org/show_bug.cgi?id=35112
+
+        Add a proxy widget when loading a QWidget based plugin in a QGraphicsWebView.
+
+        * plugins/symbian/PluginContainerSymbian.cpp:
+        (PluginContainerSymbian::PluginContainerSymbian):
+        (PluginContainerSymbian::focusInEvent):
+        * plugins/symbian/PluginContainerSymbian.h:
+        (WebCore::PluginContainerSymbian::proxy):
+        * plugins/symbian/PluginViewSymbian.cpp:
+        (WebCore::PluginView::updatePluginWidget):
+        (WebCore::PluginView::platformStart):
+        (WebCore::PluginView::platformDestroy):
+
+2010-03-29  Laszlo Gombos  <laszlo.1.gombos@nokia.com>
+
+        Reviewed for the Qt 4.6 branch by Simon Hausmann.
+
+        Accept XHTML-MP content type as XHTML content
+        https://bugs.webkit.org/show_bug.cgi?id=34262
+
+        Enable processing XHTML-MP mime type as an XHTML document
+        even if XHTML-MP support is not enabled.
+
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::initializeSupportedNonImageMimeTypes):
+
+2010-03-22  Jakub Wieczorek  <jwieczorek@webkit.org>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Don't construct a QLineEdit every time when painting a text field
+        https://bugs.webkit.org/show_bug.cgi?id=36373
+
+        Instead, keep one instance per RenderTheme around.
+
+        * platform/qt/RenderThemeQt.cpp:
+        (WebCore::findFrameLineWidth):
+
+2010-03-26  Janne Koskinen  <janne.p.koskinen@digia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        Don't undefine SKIP_STATIC_CONSTRUCTORS_ON_GCC for Symbian HW targets.
+        https://bugs.webkit.org/show_bug.cgi?id=34081
+
+        Defining StringImpl instances as globals will cause a crash on process exit as 
+        StringImpl::Remove expects TLS which was already deleted at time of exiting main and ends up
+        constructing one exiting thread.
+
+        * config.h:
+
+2010-02-02  Alexey Proskuryakov  <ap@apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34076
+        <rdar://problem/7594601> Crash in mangleme in WebCore::Element::getAttribute
+
+        Test: fast/forms/misplaced-img-form-registration.html
+
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::registerImgElement): Assert that the same image isn't added
+        to vector again.
+        (WebCore::HTMLFormElement::removeImgElement): Similarly, assert that we're removing something
+        that's actually registered.
+
+        * html/HTMLImageElement.cpp: (WebCore::HTMLImageElement::~HTMLImageElement): If parser fails
+        to insert the image element, then there will be no removed from tree notification either,
+        need to unregister right away.
+
+2010-01-25  Alexey Proskuryakov  <ap@apple.com>
+
+        Rubber-stamped by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34076
+        An image remains accessible via form.property syntax after being removed from document.
+
+        Fix crashing regression tests (tables/mozilla/bugs/bug4527.html et al.)
+
+        * html/HTMLImageElement.cpp: (WebCore::HTMLImageElement::insertedIntoTree): Remove incorrect
+        assertions added in the previous patch - it's mot true that m_for is always a parent; table
+        parsing can reparent the image element, but m_form still needs to be set.
+
+2010-01-25  Alexey Proskuryakov  <ap@apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34076
+        An image remains accessible via form.property syntax after being removed from document.
+
+        Tests: fast/forms/removed-image-as-property.html
+               fast/forms/reparented-image-as-property.html
+
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::~HTMLImageElement): This is called during GC - not a good time
+        to make observable changes to DOM.
+        (WebCore::HTMLImageElement::insertedIntoTree): This is the right place to do any work that
+        depends on connectedness to some ancestor. We still allow for m_form to be set via constructor,
+        which happens during parsing.
+        (WebCore::HTMLImageElement::removedFromTree): Ditto.
+
+        * html/HTMLImageElement.h: Added removedFromTree/insertedIntoTree, moved removedFromDocument
+        and insertedIntoDocument to private section, as they shouldn't be called directly.
+
+2009-12-08  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Darin Adler.
+
+        Navigating to a cached page can result in accessing a destroyed HTMLInputElement.
+        <rdar://problem/6856662> and https://webkit.org/b/32293
+
+        Test: fast/loader/input-element-page-cache-crash.html
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::parseMappedAttribute): Make sure to unregister for the activation
+          callback after the new m_autocomplete setting has been stored so the unregistration actually
+          takes place.
+
+2009-12-13  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        <rdar://problem/7341364> Crash at HTMLParser::popOneBlockCommon() after
+        handling misnested residual style tags
+
+        Test: fast/parser/residual-style-close-ref-clone.html
+
+        * html/HTMLParser.cpp:
+        (WebCore::HTMLParser::handleResidualStyleCloseTagAcrossBlocks): Gave the
+        block stack a strong reference to the cloned residual style element. 
+
+2009-12-23  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/7487164> First line of text cannot be selected
+        https://bugs.webkit.org/show_bug.cgi?id=32749
+
+        Test: fast/text/remove-zero-length-run.html
+
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::positionLineBox): Changed code that assumed that if a box was being
+            removed, it was the only box in the RenderText. Instead, correctly preserve the list of
+            text boxes.
+        (WebCore::RenderText::checkConsistency): Updated for earlier rename.
+
+2009-12-10  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Crash in XMLTokenizer::popCurrentNode if window.close() is called during parsing
+        https://bugs.webkit.org/show_bug.cgi?id=31576
+
+        Add a RefCounted wrapper object around xmlParserCtxtPtr so we can
+        maintain it's lifetime more effectively.
+
+        Test: fast/parser/xhtml-close-while-parsing.xhtml
+
+        * dom/XMLTokenizer.cpp:
+        (WebCore::XMLTokenizer::popCurrentNode):
+        * dom/XMLTokenizer.h:
+        (WebCore::XMLParserContext::context):
+        (WebCore::XMLParserContext::XMLParserContext):
+        (WebCore::XMLTokenizer::context):
+        * dom/XMLTokenizerLibxml2.cpp:
+        (WebCore::XMLParserContext::createStringParser):
+        (WebCore::XMLParserContext::createMemoryParser):
+        (WebCore::XMLParserContext::~XMLParserContext):
+        (WebCore::XMLTokenizer::~XMLTokenizer):
+        (WebCore::XMLTokenizer::doWrite):
+        (WebCore::XMLTokenizer::initializeParserContext):
+        (WebCore::XMLTokenizer::doEnd):
+        (WebCore::XMLTokenizer::lineNumber):
+        (WebCore::XMLTokenizer::columnNumber):
+        (WebCore::XMLTokenizer::stopParsing):
+        (WebCore::parseXMLDocumentFragment):
+        (WebCore::parseAttributes):
+
+2009-11-09  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Darin Adler and Dan Bernstein.
+
+        <rdar://problem/7328395>
+        https://bugs.webkit.org/show_bug.cgi?id=31277
+
+        When an object tag's style changes (for example when child nodes are added/removed),
+        reuse its Frame (if it has one) instead of creating multiple Frames.
+
+        Test: fast/dom/HTMLObjectElement/children-changed.html
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::requestObject):
+
+2009-12-05  Adam Langley  <agl@google.com>
+
+        Reviewed by Adam Barth.
+
+        Check that a CSS format() argument is of a valid type.
+
+        https://bugs.webkit.org/show_bug.cgi?id=31815
+        http://code.google.com/p/chromium/issues/detail?id=28582
+
+        Test: fast/css/url-format-non-string.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseFontFaceSrc):
+
+2010-03-19  Miikka Heikkinen  <miikka.heikkinen@digia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Support for QT_LIBINFIX in Symbian builds
+
+        Configuring Qt with -qtlibinfix parameter will enable installing
+        an alternate version of Qt on devices that already have it on ROM.
+        This patch provides support for infixed builds of Webkit.
+
+        * WebCore.pro:
+
+2010-01-31  Benjamin Poulain  <benjamin.poulain@nokia.com>
+
+        Reviewed by Eric Seidel.
+
+        [Qt] Enable FAST_MOBILE_SCROLLING on Qt embedded platforms
+        https://bugs.webkit.org/show_bug.cgi?id=34168
+
+        Enable FAST_MOBILE_SCROLLING for Qt on Maemo 5, Linux embedded
+        and Symbian
+
+        * WebCore.pro:
+
+2010-01-19  Daniel Bates  <dbates@rim.com>
+
+        Reviewed by Adam Treat.
+
+        https://bugs.webkit.org/show_bug.cgi?id=33408
+
+        Implements an optimization to ignore fixed background images
+        (i.e. background-attachment: fixed) when a page does not contain
+        any fixed position elements so as to allow fast repaints (via bit
+        blit) when scrolling a page.
+
+        Currently, if a page has elements that specify either a fixed
+        background or a fixed position then we perform a slow repaint
+        (i.e disable blitting) so as to avoid rendering artifacts.
+        However, on low-powered/mobile devices slow repaints can cause
+        noticeable delays when scrolling a page with a fixed background
+        image. By sacrificing support for fixed background images when
+        there are no fixed elements on the page and with come care, we
+        don't need to force slow repaints and can avoid rendering artifacts.
+        Hence, on such devices we can improve the responsiveness of
+        scrolling a page with a fixed background image.
+
+        Note, this optimization is only enabled if the WebKit is built
+        with FAST_MOBILE_SCROLLING enabled.
+
+        Tests: fast/fast-mobile-scrolling/fixed-position-element.html
+               fast/fast-mobile-scrolling/no-fixed-position-elements.html
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::calculateBackgroundImageGeometry):
+        Disable fixed background attachment if we can blit on scroll.
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::styleWillChange):
+
+2010-03-11  Simon Hausmann  <simon.hausmann@nokia.com>
+
+        Reviewed by Tor Arne VestbÃž.
+
+        [Qt] Avoid double-buffering with Qt image decoders
+
+        Pass QIODevice::Unbuffered when opening the QBuffer that
+        wraps the image data, to hint to Qt that no extra buffering
+        is needed.
+
+        * platform/graphics/qt/ImageDecoderQt.cpp:
+        (WebCore::ImageDecoderQt::setData):
+
+2010-01-14  Diego Gonzalez  <diego.gonzalez@openbossa.org>
+
+        Reviewed by Kenneth Christiansen.
+
+        [Qt] Missing fileSystemPath() method in Qt KURL implementation
+        https://bugs.webkit.org/show_bug.cgi?id=33614
+
+        No new tests.
+
+        * platform/qt/KURLQt.cpp:
+        (WebCore::KURL::fileSystemPath):
+
 2010-02-01  Andreas Kling  <andreas.kling@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] In the StyledPainter determine the style from the Render and Scrollbar theme instead of from the paint device
+        https://bugs.webkit.org/show_bug.cgi?id=34054
+
+        Getting the style from the painter's paint device is a hack that breaks when
+        the paint device's style is different than the style that is used when
+        calculating the metries earlier when there is no painter available.
+
+        This change moves us closer to always using the same style.
+
+        * platform/qt/RenderThemeQt.cpp:
+        (WebCore::StylePainter::StylePainter):
+        (WebCore::StylePainter::init):
+        (WebCore::RenderThemeQt::paintButton):
+        (WebCore::RenderThemeQt::paintTextField):
+        (WebCore::RenderThemeQt::paintMenuList):
+        (WebCore::RenderThemeQt::paintMenuListButton):
+        (WebCore::RenderThemeQt::paintSliderTrack):
+        (WebCore::RenderThemeQt::paintMediaMuteButton):
+        (WebCore::RenderThemeQt::paintMediaPlayButton):
+        (WebCore::RenderThemeQt::paintMediaSliderTrack):
+        (WebCore::RenderThemeQt::paintMediaSliderThumb):
+        * platform/qt/RenderThemeQt.h:
+        * platform/qt/ScrollbarThemeQt.cpp:
+        (WebCore::ScrollbarThemeQt::paint):
+        (WebCore::ScrollbarThemeQt::hitTest):
+        (WebCore::ScrollbarThemeQt::shouldCenterOnThumb):
+        (WebCore::ScrollbarThemeQt::scrollbarThickness):
+        (WebCore::ScrollbarThemeQt::thumbLength):
+        (WebCore::ScrollbarThemeQt::trackPosition):
+        (WebCore::ScrollbarThemeQt::trackLength):
+        (WebCore::ScrollbarThemeQt::paintScrollCorner):
+        (WebCore::ScrollbarThemeQt::style):
+        * platform/qt/ScrollbarThemeQt.h:
+
+2010-01-25  Simon Hausmann  <hausmann@webkit.org>
 
         Reviewed by Kenneth Rohde Christiansen.
Index: trunk/src/3rdparty/webkit/WebCore/WebCore.pro
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/WebCore.pro	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/WebCore.pro	(revision 769)
@@ -7,7 +7,10 @@
     TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB
     TARGET.CAPABILITY = All -Tcb
-    TARGET.UID3 = 0x200267C2
-
-    webkitlibs.sources = QtWebKit.dll
+    isEmpty(QT_LIBINFIX) {
+        TARGET.UID3 = 0x200267C2
+    } else {
+        TARGET.UID3 = 0xE00267C2
+    }
+    webkitlibs.sources = QtWebKit$${QT_LIBINFIX}.dll
     webkitlibs.path = /sys/bin
     vendorinfo = \
@@ -27,5 +30,5 @@
     # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target.
     # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000.
-    QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000
+    MMP_RULES += "LINKEROPTION  armcc --rw-base 0xE00000"
 }
 
@@ -162,4 +165,8 @@
 } else {
     DEFINES += ENABLE_SVG_FONTS=0 ENABLE_SVG_FOREIGN_OBJECT=0 ENABLE_SVG_ANIMATION=0 ENABLE_SVG_AS_IMAGE=0 ENABLE_SVG_USE=0
+}
+
+mameo5|symbian|embedded {
+    DEFINES += ENABLE_FAST_MOBILE_SCROLLING=1
 }
 
Index: trunk/src/3rdparty/webkit/WebCore/config.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/config.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/config.h	(revision 769)
@@ -145,5 +145,7 @@
 #undef WIN32
 #undef _WIN32
+#if COMPILER(WINSCW)
 #undef SKIP_STATIC_CONSTRUCTORS_ON_GCC
+#endif
 #define USE_SYSTEM_MALLOC 1
 #define U_HAVE_INT8_T 0
Index: trunk/src/3rdparty/webkit/WebCore/css/CSSParser.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/css/CSSParser.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/css/CSSParser.cpp	(revision 769)
@@ -3329,4 +3329,10 @@
 }
 
+static bool isValidFormatFunction(CSSParserValue* val)
+{
+    CSSParserValueList* args = val->function->args;
+    return equalIgnoringCase(val->function->name, "format(") && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT);
+}
+
 bool CSSParser::parseFontFaceSrc()
 {
@@ -3356,5 +3362,5 @@
                     uriValue.clear();
                     parsedValue = CSSFontFaceSrcValue::createLocal(a->string);
-                } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) {
+                } else if (allowFormat && uriValue && isValidFormatFunction(val)) {
                     expectComma = true;
                     allowFormat = false;
Index: trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp	(revision 769)
@@ -92,5 +92,6 @@
 void XMLTokenizer::popCurrentNode()
 {
-    ASSERT(m_currentNode);
+    if (!m_currentNode)
+        return;
     ASSERT(m_currentNodeStack.size());
 
Index: trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h	(revision 769)
@@ -52,4 +52,21 @@
     class PendingCallbacks;
     class ScriptElement;
+
+#if !USE(QXMLSTREAM)
+    class XMLParserContext : public RefCounted<XMLParserContext> {
+    public:
+        static PassRefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void*, const char*);
+        static PassRefPtr<XMLParserContext> createStringParser(xmlSAXHandlerPtr, void*);
+        ~XMLParserContext();
+        xmlParserCtxtPtr context() const { return m_context; }
+
+    private:
+        XMLParserContext(xmlParserCtxtPtr context)
+            : m_context(context)
+        {
+        }
+        xmlParserCtxtPtr m_context;
+    };
+#endif
 
     class XMLTokenizer : public Tokenizer, public CachedResourceClient {
@@ -147,5 +164,6 @@
         bool m_wroteText;
 #else
-        xmlParserCtxtPtr m_context;
+        xmlParserCtxtPtr context() const { return m_context ? m_context->context() : 0; };
+        RefPtr<XMLParserContext> m_context;
         OwnPtr<PendingCallbacks> m_pendingCallbacks;
         Vector<xmlChar> m_bufferedText;
Index: trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp	(revision 769)
@@ -466,5 +466,5 @@
 static bool didInit = false;
 
-static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData)
+PassRefPtr<XMLParserContext> XMLParserContext::createStringParser(xmlSAXHandlerPtr handlers, void* userData)
 {
     if (!didInit) {
@@ -483,10 +483,10 @@
     xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
 
-    return parser;
+    return adoptRef(new XMLParserContext(parser));
 }
 
 
 // Chunk should be encoded in UTF-8
-static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk)
+PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk)
 {
     if (!didInit) {
@@ -519,6 +519,6 @@
     parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36);
     parser->_private = userData;
-
-    return parser;
+    
+    return adoptRef(new XMLParserContext(parser));
 }
 
@@ -610,4 +610,11 @@
 }
 
+XMLParserContext::~XMLParserContext()
+{
+    if (m_context->myDoc)
+        xmlFreeDoc(m_context->myDoc);
+    xmlFreeParserCtxt(m_context);
+}
+
 XMLTokenizer::~XMLTokenizer()
 {
@@ -617,6 +624,4 @@
     if (m_pendingScript)
         m_pendingScript->removeClient(this);
-    if (m_context)
-        xmlFreeParserCtxt(m_context);
 }
 
@@ -625,5 +630,8 @@
     if (!m_context)
         initializeParserContext();
-    
+
+    // Protect the libxml context from deletion during a callback
+    RefPtr<XMLParserContext> context = m_context;
+
     // libXML throws an error if you try to switch the encoding for an empty string.
     if (parseString.length()) {
@@ -634,13 +642,13 @@
         const UChar BOM = 0xFEFF;
         const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
-        xmlSwitchEncoding(m_context, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
+        xmlSwitchEncoding(context->context(), BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
 
         XMLTokenizerScope scope(m_doc->docLoader());
-        xmlParseChunk(m_context, reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
+        xmlParseChunk(context->context(), reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
     }
     
     if (m_doc->decoder() && m_doc->decoder()->sawError()) {
         // If the decoder saw an error, report it as fatal (stops parsing)
-        handleError(fatal, "Encoding error", lineNumber(), columnNumber());
+        handleError(fatal, "Encoding error", context->context()->input->line, context->context()->input->col);
     }
 
@@ -1278,7 +1286,7 @@
     XMLTokenizerScope scope(m_doc->docLoader());
     if (m_parsingFragment)
-        m_context = createMemoryParser(&sax, this, chunk);
+        m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
     else
-        m_context = createStringParser(&sax, this);
+        m_context = XMLParserContext::createStringParser(&sax, this);
 }
 
@@ -1301,10 +1309,7 @@
         {
             XMLTokenizerScope scope(m_doc->docLoader());
-            xmlParseChunk(m_context, 0, 0, 1);
-        }
-
-        if (m_context->myDoc)
-            xmlFreeDoc(m_context->myDoc);
-        xmlFreeParserCtxt(m_context);
+            xmlParseChunk(context(), 0, 0, 1);
+        }
+
         m_context = 0;
     }
@@ -1335,10 +1340,10 @@
 int XMLTokenizer::lineNumber() const
 {
-    return m_context ? m_context->input->line : 1;
+    return context() ? context()->input->line : 1;
 }
 
 int XMLTokenizer::columnNumber() const
 {
-    return m_context ? m_context->input->col : 1;
+    return context() ? context()->input->col : 1;
 }
 
@@ -1346,5 +1351,6 @@
 {
     Tokenizer::stopParsing();
-    xmlStopParser(m_context);
+    if (context())
+        xmlStopParser(context());
 }
 
@@ -1385,15 +1391,15 @@
     tokenizer.initializeParserContext(chunkAsUtf8.data());
 
-    xmlParseContent(tokenizer.m_context);
+    xmlParseContent(tokenizer.context());
 
     tokenizer.endDocument();
 
     // Check if all the chunk has been processed.
-    long bytesProcessed = xmlByteConsumed(tokenizer.m_context);
+    long bytesProcessed = xmlByteConsumed(tokenizer.context());
     if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length())
         return false;
 
     // No error if the chunk is well formed or it is not but we have no error.
-    return tokenizer.m_context->wellFormed || xmlCtxtGetLastError(tokenizer.m_context) == 0;
+    return tokenizer.context()->wellFormed || xmlCtxtGetLastError(tokenizer.context()) == 0;
 }
 
@@ -1438,10 +1444,7 @@
     sax.startElementNs = attributesStartElementNsHandler;
     sax.initialized = XML_SAX2_MAGIC;
-    xmlParserCtxtPtr parser = createStringParser(&sax, &state);
+    RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax, &state);
     String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />";
-    xmlParseChunk(parser, reinterpret_cast<const char*>(parseString.characters()), parseString.length() * sizeof(UChar), 1);
-    if (parser->myDoc)
-        xmlFreeDoc(parser->myDoc);
-    xmlFreeParserCtxt(parser);
+    xmlParseChunk(parser->context(), reinterpret_cast<const char*>(parseString.characters()), parseString.length() * sizeof(UChar), 1);
     attrsOK = state.gotAttributes;
     return state.attributes;
Index: trunk/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp	(revision 769)
@@ -516,4 +516,5 @@
 void HTMLFormElement::registerImgElement(HTMLImageElement* e)
 {
+    ASSERT(imgElements.find(e) == notFound);
     imgElements.append(e);
 }
@@ -521,4 +522,5 @@
 void HTMLFormElement::removeImgElement(HTMLImageElement* e)
 {
+    ASSERT(imgElements.find(e) != notFound);
     removeFromVector(imgElements, e);
 }
Index: trunk/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp	(revision 769)
@@ -210,4 +210,28 @@
 }
 
+void HTMLImageElement::insertedIntoTree(bool deep)
+{
+    if (!m_form) {
+        // m_form can be non-null if it was set in constructor.
+        for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+            if (ancestor->hasTagName(formTag)) {
+                m_form = static_cast<HTMLFormElement*>(ancestor);
+                m_form->registerImgElement(this);
+                break;
+            }
+        }
+    }
+
+    HTMLElement::insertedIntoTree(deep);
+}
+
+void HTMLImageElement::removedFromTree(bool deep)
+{
+    if (m_form)
+        m_form->removeImgElement(this);
+    m_form = 0;
+    HTMLElement::removedFromTree(deep);
+}
+
 int HTMLImageElement::width(bool ignorePendingStylesheets) const
 {
Index: trunk/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h	(revision 769)
@@ -46,6 +46,4 @@
     virtual void attach();
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
 
     virtual bool canStartSelection() const { return false; }
@@ -106,4 +104,9 @@
 
 private:
+    virtual void insertedIntoDocument();
+    virtual void removedFromDocument();
+    virtual void insertedIntoTree(bool deep);
+    virtual void removedFromTree(bool deep);
+
     HTMLImageLoader m_imageLoader;
     String usemap;
Index: trunk/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp	(revision 769)
@@ -702,10 +702,13 @@
             registerForActivationCallbackIfNeeded();
         } else {
-            if (m_autocomplete == Off)
-                unregisterForActivationCallbackIfNeeded();
+            bool needsToUnregister = m_autocomplete == Off;
+
             if (attr->isEmpty())
                 m_autocomplete = Uninitialized;
             else
                 m_autocomplete = On;
+
+            if (needsToUnregister)
+                unregisterForActivationCallbackIfNeeded();
         }
     } else if (attr->name() == typeAttr) {
Index: trunk/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp	(revision 769)
@@ -1276,5 +1276,6 @@
             ASSERT(newNodePtr);
             prevMaxElem->node = newNodePtr;
-            prevMaxElem->didRefNode = false;
+            newNodePtr->ref();
+            prevMaxElem->didRefNode = true;
         } else
             delete elem;
Index: trunk/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp	(revision 769)
@@ -1261,7 +1261,9 @@
     ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag));
     HTMLPlugInElement* element = static_cast<HTMLPlugInElement*>(renderer->node());
-    
-    // FIXME: OK to always make a new frame? When does the old frame get removed?
-    return loadSubframe(element, completedURL, frameName, m_outgoingReferrer);
+
+    // If the plug-in element already contains a subframe, requestFrame will re-use it. Otherwise,
+    // it will create a new frame and set it as the RenderPart's widget, causing what was previously 
+    // in the widget to be torn down.
+    return requestFrame(element, completedURL, frameName);
 }
 
Index: trunk/src/3rdparty/webkit/WebCore/page/FrameView.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/page/FrameView.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/page/FrameView.cpp	(revision 769)
@@ -107,4 +107,5 @@
     : m_frame(frame)
     , m_slowRepaintObjectCount(0)
+    , m_fixedObjectCount(0)
     , m_layoutTimer(this, &FrameView::layoutTimerFired)
     , m_layoutRoot(0)
@@ -736,5 +737,10 @@
 bool FrameView::useSlowRepaints() const
 {
-    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
+    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
+}
+
+bool FrameView::useSlowRepaintsIfNotOverlapped() const
+{
+    return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
 }
 
@@ -758,4 +764,76 @@
     if (!m_slowRepaintObjectCount)
         setCanBlitOnScroll(!useSlowRepaints());
+}
+
+void FrameView::addFixedObject()
+{
+    if (!m_fixedObjectCount && platformWidget())
+        setCanBlitOnScroll(false);
+    ++m_fixedObjectCount;
+}
+
+void FrameView::removeFixedObject()
+{
+    ASSERT(m_fixedObjectCount > 0);
+    m_fixedObjectCount--;
+    if (!m_fixedObjectCount)
+        setCanBlitOnScroll(!useSlowRepaints());
+}
+
+void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    const size_t fixedObjectThreshold = 5;
+
+    ListHashSet<RenderBox*>* positionedObjects = 0;
+    if (RenderView* root = m_frame->contentRenderer())
+        positionedObjects = root->positionedObjects();
+
+    if (!positionedObjects || positionedObjects->isEmpty()) {
+        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+        return;
+    }
+
+    // Get the rects of the fixed objects visible in the rectToScroll
+    Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
+    bool updateInvalidatedSubRect = true;
+    ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
+    for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
+        RenderBox* renderBox = *it;
+        if (renderBox->style()->position() != FixedPosition)
+            continue;
+        IntRect topLevelRect;
+        IntRect updateRect = renderBox->paintingRootRect(topLevelRect);
+        updateRect.move(-scrollX(), -scrollY());
+        updateRect.intersect(rectToScroll);
+        if (!updateRect.isEmpty()) {
+            if (subRectToUpdate.size() >= fixedObjectThreshold) {
+                updateInvalidatedSubRect = false;
+                break;
+            }
+            subRectToUpdate.append(updateRect);
+        }
+    }
+
+    // Scroll the view
+    if (updateInvalidatedSubRect) {
+        // 1) scroll
+        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+
+        // 2) update the area of fixed objets that has been invalidated
+        size_t fixObjectsCount = subRectToUpdate.size();
+        for (size_t i = 0; i < fixObjectsCount; ++i) {
+            IntRect updateRect = subRectToUpdate[i];
+            IntRect scrolledRect = updateRect;
+            scrolledRect.move(scrollDelta);
+            updateRect.unite(scrolledRect);
+            updateRect.intersect(rectToScroll);
+            hostWindow()->repaint(updateRect, true, false, true);
+        }
+    } else {
+        // the number of fixed objects exceed the threshold, so we repaint everything.
+        IntRect updateRect = clipRect;
+        updateRect.intersect(rectToScroll);
+        hostWindow()->repaint(updateRect, true, false, true);
+    }
 }
 
Index: trunk/src/3rdparty/webkit/WebCore/page/FrameView.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/page/FrameView.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/page/FrameView.h	(revision 769)
@@ -144,4 +144,7 @@
     void removeSlowRepaintObject();
 
+    void addFixedObject();
+    void removeFixedObject();
+
     void beginDeferredRepaints();
     void endDeferredRepaints();
@@ -197,4 +200,7 @@
     void invalidateScrollCorner();
 
+protected:
+    virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
 private:
     FrameView(Frame*);
@@ -207,4 +213,5 @@
     friend class RenderWidget;
     bool useSlowRepaints() const;
+    bool useSlowRepaintsIfNotOverlapped() const;
 
     void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
@@ -262,4 +269,5 @@
     bool m_contentIsOpaque;
     unsigned m_slowRepaintObjectCount;
+    unsigned m_fixedObjectCount;
 
     int m_borderX, m_borderY;
Index: trunk/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp	(revision 769)
@@ -52,5 +52,5 @@
 
 QT_BEGIN_NAMESPACE
-extern Q_GUI_EXPORT bool qt_tab_all_widgets; // from qapplication.cpp
+Q_GUI_EXPORT extern bool qt_tab_all_widgets; // from qapplication.cpp
 QT_END_NAMESPACE
 
Index: trunk/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp	(revision 769)
@@ -201,7 +201,5 @@
         "application/xml",
         "application/xhtml+xml",
-#if ENABLE(XHTMLMP)
         "application/vnd.wap.xhtml+xml",
-#endif
         "application/rss+xml",
         "application/atom+xml",
Index: trunk/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp	(revision 769)
@@ -510,5 +510,5 @@
     if (canBlitOnScroll()) { // The main frame can just blit the WebView window
        // FIXME: Find a way to blit subframes without blitting overlapping content
-       hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
+       scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect);
     } else { 
        // We need to go ahead and repaint the entire backing store.  Do it now before moving the
@@ -523,4 +523,9 @@
     // be very fast).
     hostWindow()->paint();
+}
+
+void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+    hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
 }
 
Index: trunk/src/3rdparty/webkit/WebCore/platform/ScrollView.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/ScrollView.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/ScrollView.h	(revision 769)
@@ -245,4 +245,7 @@
     virtual void updateScrollCorner();
     virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+
+    // Scroll the content by blitting the pixels
+    virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
     
 private:
Index: trunk/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp	(revision 769)
@@ -80,5 +80,5 @@
     m_buffer = new QBuffer;
     m_buffer->setData(imageData);
-    m_buffer->open(QBuffer::ReadOnly);
+    m_buffer->open(QBuffer::ReadOnly | QIODevice::Unbuffered);
     m_reader = new QImageReader(m_buffer, m_format);
 }
@@ -115,6 +115,21 @@
 int ImageDecoderQt::repetitionCount() const
 {
-    if (m_reader && m_reader->supportsAnimation())
-        m_repetitionCount = qMax(0, m_reader->loopCount());
+    if (m_reader && m_reader->supportsAnimation()) {
+        m_repetitionCount = m_reader->loopCount();
+
+        // Qt and WebCore have a incompatible understanding of
+        // the loop count and we can not completely map everything.
+        //  Qt   |   WebCore          | description
+        //  -1   |     0              | infinite animation
+        //   0   | cAnimationLoopOnce | show every frame once
+        //   n   |     n+1            | Qt returns the # of iterations - 1
+        //  n/a  | cAnimationNone     | show only the first frame
+        if (m_repetitionCount == -1)
+            m_repetitionCount = 0;
+        else if (m_repetitionCount == 0)
+            m_repetitionCount = cAnimationLoopOnce;
+        else
+            ++m_repetitionCount;
+    }
 
     return m_repetitionCount;
@@ -189,6 +204,9 @@
     // Now get the QImage from Qt and place it in the RGBA32Buffer
     QImage img;
-    if (!m_reader->read(&img))
+    if (!m_reader->read(&img)) {
+        frameCount();
+        repetitionCount();
         return failRead();
+    }
 
     // now into the RGBA32Buffer - even if the image is not
Index: trunk/src/3rdparty/webkit/WebCore/platform/network/ResourceRequestBase.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/network/ResourceRequestBase.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/network/ResourceRequestBase.cpp	(revision 769)
@@ -382,9 +382,17 @@
 unsigned initializeMaximumHTTPConnectionCountPerHost()
 {
+#if PLATFORM(QT)
+#ifdef Q_OS_SYMBIAN
+    return 3 * (1 + 3 + 2);
+#else
+    return 6 * (1 + 3 + 2);
+#endif
+#else
     // This is used by the loader to control the number of issued parallel load requests. 
     // Four seems to be a common default in HTTP frameworks.
     return 4;
-}
 #endif
-
-}
+}
+#endif
+
+}
Index: trunk/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp	(revision 769)
@@ -96,6 +96,8 @@
 String KURL::fileSystemPath() const
 {
-    notImplemented();
-    return String();
+    if (!isValid() || !protocolIs("file"))
+        return String();
+
+    return String(path());
 }
 
Index: trunk/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp	(revision 769)
@@ -40,5 +40,5 @@
 #include <QGraphicsScene>
 #include <QGraphicsView>
-#include <QGraphicsWebView>
+#include <qgraphicswebview.h>
 #include <QListWidget>
 #include <QListWidgetItem>
Index: trunk/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp	(revision 769)
@@ -45,4 +45,5 @@
 #include "RenderBox.h"
 #include "RenderTheme.h"
+#include "ScrollbarThemeQt.h"
 #include "UserAgentStyleSheets.h"
 #include "QWebPageClient.h"
@@ -67,15 +68,15 @@
 
 
-StylePainter::StylePainter(const RenderObject::PaintInfo& paintInfo)
-{
-    init(paintInfo.context ? paintInfo.context : 0);
-}
-
-StylePainter::StylePainter(GraphicsContext* context)
-{
-    init(context);
-}
-
-void StylePainter::init(GraphicsContext* context)
+StylePainter::StylePainter(RenderThemeQt* theme, const RenderObject::PaintInfo& paintInfo)
+{
+    init(paintInfo.context ? paintInfo.context : 0, theme->qStyle());
+}
+
+StylePainter::StylePainter(ScrollbarThemeQt* theme, GraphicsContext* context)
+{
+    init(context, theme->style());
+}
+
+void StylePainter::init(GraphicsContext* context, QStyle* themeStyle)
 {
     painter = static_cast<QPainter*>(context->platformContext());
@@ -86,5 +87,5 @@
     if (dev && dev->devType() == QInternal::Widget)
         widget = static_cast<QWidget*>(dev);
-    style = (widget ? widget->style() : QApplication::style());
+    style = themeStyle;
 
     if (painter) {
@@ -126,4 +127,5 @@
     : RenderTheme()
     , m_page(page)
+    , m_lineEdit(0)
 {
     QPushButton button;
@@ -142,4 +144,5 @@
 {
     delete m_fallbackStyle;
+    delete m_lineEdit;
 }
 
@@ -207,9 +210,11 @@
 }
 
-static int findFrameLineWidth(QStyle* style)
-{
-    QLineEdit lineEdit;
+int RenderThemeQt::findFrameLineWidth(QStyle* style) const
+{
+    if (!m_lineEdit)
+        m_lineEdit = new QLineEdit();
+
     QStyleOptionFrameV2 opt;
-    return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, &lineEdit);
+    return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, m_lineEdit);
 }
 
@@ -465,5 +470,5 @@
 bool RenderThemeQt::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
 {
-    StylePainter p(i);
+    StylePainter p(this, i);
     if (!p.isValid())
        return true;
@@ -498,5 +503,5 @@
 bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
 {
-    StylePainter p(i);
+    StylePainter p(this, i);
     if (!p.isValid())
         return true;
@@ -567,5 +572,5 @@
 bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
 {
-    StylePainter p(i);
+    StylePainter p(this, i);
     if (!p.isValid())
         return true;
@@ -607,5 +612,5 @@
                                         const IntRect& r)
 {
-    StylePainter p(i);
+    StylePainter p(this, i);
     if (!p.isValid())
         return true;
@@ -838,5 +843,5 @@
         return false;
 
-    StylePainter p(paintInfo);
+    StylePainter p(this, paintInfo);
     if (!p.isValid())
         return true;
@@ -867,5 +872,5 @@
         return false;
 
-    StylePainter p(paintInfo);
+    StylePainter p(this, paintInfo);
     if (!p.isValid())
         return true;
@@ -906,5 +911,5 @@
         return false;
 
-    StylePainter p(paintInfo);
+    StylePainter p(this, paintInfo);
     if (!p.isValid())
         return true;
@@ -933,5 +938,5 @@
         return false;
 
-    StylePainter p(paintInfo);
+    StylePainter p(this, paintInfo);
     if (!p.isValid())
         return true;
Index: trunk/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h	(revision 769)
@@ -28,4 +28,5 @@
 
 QT_BEGIN_NAMESPACE
+class QLineEdit;
 class QPainter;
 class QWidget;
@@ -36,4 +37,5 @@
 class RenderStyle;
 class HTMLMediaElement;
+class ScrollbarThemeQt;
 
 class RenderThemeQt : public RenderTheme {
@@ -75,4 +77,6 @@
     virtual String extraMediaControlsStyleSheet();
 #endif
+
+    QStyle* qStyle() const;
 
 protected:
@@ -138,5 +142,6 @@
     void setPopupPadding(RenderStyle*) const;
 
-    QStyle* qStyle() const;
+    int findFrameLineWidth(QStyle* style) const;
+
     QStyle* fallbackStyle() const;
 
@@ -149,10 +154,11 @@
 
     QStyle* m_fallbackStyle;
+    mutable QLineEdit* m_lineEdit;
 };
 
 class StylePainter {
 public:
-    explicit StylePainter(const RenderObject::PaintInfo& paintInfo);
-    explicit StylePainter(GraphicsContext* context);
+    explicit StylePainter(RenderThemeQt*, const RenderObject::PaintInfo&);
+    explicit StylePainter(ScrollbarThemeQt*, GraphicsContext*);
     ~StylePainter();
 
@@ -171,5 +177,5 @@
 
 private:
-    void init(GraphicsContext* context);
+    void init(GraphicsContext* context, QStyle*);
 
     QBrush oldBrush;
Index: trunk/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp	(revision 769)
@@ -141,5 +141,5 @@
     }
 
-    StylePainter p(graphicsContext);
+    StylePainter p(this, graphicsContext);
     if (!p.isValid())
       return true;
@@ -173,5 +173,5 @@
     const QPoint pos = scrollbar->convertFromContainingWindow(evt.pos());
     opt->rect.moveTo(QPoint(0, 0));
-    QStyle::SubControl sc = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0);
+    QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0);
     return scrollbarPart(sc);
 }
@@ -180,5 +180,5 @@
 {
     // Middle click centers slider thumb (if supported)
-    return QApplication::style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton;
+    return style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton;
 }
 
@@ -191,5 +191,4 @@
 int ScrollbarThemeQt::scrollbarThickness(ScrollbarControlSize controlSize)
 {
-    QStyle* s = QApplication::style();
     QStyleOptionSlider o;
     o.orientation = Qt::Vertical;
@@ -197,5 +196,5 @@
     if (controlSize != RegularScrollbar)
         o.state |= QStyle::State_Mini;
-    return s->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0);
+    return style()->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0);
 }
 
@@ -210,5 +209,5 @@
 {
     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
-    IntRect thumb = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0);
+    IntRect thumb = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0);
     return scrollbar->orientation() == HorizontalScrollbar ? thumb.width() : thumb.height();
 }
@@ -217,5 +216,5 @@
 {
     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
-    IntRect track = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
+    IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
     return scrollbar->orientation() == HorizontalScrollbar ? track.x() - scrollbar->x() : track.y() - scrollbar->y();
 }
@@ -224,5 +223,5 @@
 {
     QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
-    IntRect track = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
+    IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
     return scrollbar->orientation() == HorizontalScrollbar ? track.width() : track.height();
 }
@@ -238,5 +237,5 @@
     context->fillRect(rect, QApplication::palette().color(QPalette::Normal, QPalette::Window));
 #else
-    StylePainter p(context);
+    StylePainter p(this, context);
     if (!p.isValid())
         return;
@@ -248,4 +247,9 @@
 }
 
-}
-
+QStyle* ScrollbarThemeQt::style() const
+{
+    return QApplication::style();
+}
+
+}
+
Index: trunk/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h	(revision 769)
@@ -29,4 +29,10 @@
 #include "ScrollbarTheme.h"
 
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+class QStyle;
+QT_END_NAMESPACE
+
 namespace WebCore {
 
@@ -50,4 +56,6 @@
 
     virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
+
+    QStyle* style() const;
 };
 
Index: trunk/src/3rdparty/webkit/WebCore/platform/text/StringHash.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/platform/text/StringHash.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/platform/text/StringHash.h	(revision 769)
@@ -1,4 +1,5 @@
 /*
  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved
+ * Copyright (C) Research In Motion Limited 2009. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -48,4 +49,14 @@
                 return false;
 
+#if PLATFORM(ARM) || PLATFORM(SH4)
+            const UChar* aChars = a->characters();
+            const UChar* bChars = b->characters();
+            for (unsigned i = 0; i != aLength; ++i) {
+                if (*aChars++ != *bChars++)
+                    return false;
+            }
+            return true;
+#else
+            /* Do it 4-bytes-at-a-time on architectures where it's safe */
             const uint32_t* aChars = reinterpret_cast<const uint32_t*>(a->characters());
             const uint32_t* bChars = reinterpret_cast<const uint32_t*>(b->characters());
@@ -60,4 +71,5 @@
 
             return true;
+#endif
         }
 
Index: trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp	(revision 769)
@@ -33,10 +33,10 @@
 using namespace WebCore;
 
-PluginContainerSymbian::PluginContainerSymbian(PluginView* view, QWidget* parent)
-    : m_parent(parent)
+PluginContainerSymbian::PluginContainerSymbian(PluginView* view, QWidget* parent, QGraphicsProxyWidget* proxy)
+    : QWidget(parent)
     , m_pluginView(view)
+    , m_proxy(proxy)
     , m_hasPendingGeometryChange(false)
 {
-    setParent(m_parent);
 }
 
@@ -63,5 +63,5 @@
 }
 
-void PluginContainerSymbian::focusInEvent(QFocusEvent* event)
+void PluginContainerSymbian::focusInEvent(QFocusEvent*)
 {
     if (Page* page = m_pluginView->parentFrame()->page())
Index: trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h	(revision 769)
@@ -23,4 +23,6 @@
 #include <QWidget>
 
+class QGraphicsProxyWidget;
+
 namespace WebCore {
 
@@ -30,9 +32,10 @@
         Q_OBJECT
     public:
-        PluginContainerSymbian(PluginView*, QWidget* parent);
+        PluginContainerSymbian(PluginView*, QWidget* parent, QGraphicsProxyWidget* proxy = 0);
         ~PluginContainerSymbian();
 
         void requestGeometry(const QRect&, const QRegion& clip = QRegion());
         void adjustGeometry();
+        QGraphicsProxyWidget* proxy() { return m_proxy; }
 
     protected:
@@ -41,5 +44,5 @@
     private:
         PluginView* m_pluginView;
-        QWidget* m_parent;
+        QGraphicsProxyWidget* m_proxy;
         QRect m_windowRect;
         QRegion m_clipRegion;
Index: trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp	(revision 769)
@@ -53,4 +53,6 @@
 #include "runtime_root.h"
 #include "QWebPageClient.h"
+#include "qgraphicswebview.h"
+#include <QGraphicsProxyWidget>
 #include <QKeyEvent>
 #include <QPixmap.h>
@@ -85,4 +87,5 @@
     
     m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());
+    
     m_clipRect = windowClipRect();
     m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
@@ -426,10 +429,13 @@
     if (m_isWindowed) {
         QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
-        // FIXME this will not work for QGraphicsView.
-        // But we cannot use winId because it will create a window and on S60,
-        // QWidgets should not create a window. 
-        Q_ASSERT(qobject_cast<QWidget*>(client->pluginParent()));
-        setPlatformWidget(new PluginContainerSymbian(this, 
-            qobject_cast<QWidget*>(client->pluginParent())));
+        QGraphicsProxyWidget* proxy = 0;
+        if (QGraphicsWebView *webView = qobject_cast<QGraphicsWebView*>(client->pluginParent()))
+            proxy = new QGraphicsProxyWidget(webView);
+
+        PluginContainerSymbian* container = new PluginContainerSymbian(this, proxy ? 0 : client->ownerWidget(), proxy);
+        setPlatformWidget(container);
+        if (proxy)
+            proxy->setWidget(container);
+        
         m_npWindow.type = NPWindowTypeWindow;
         m_npWindow.window = (void*)platformPluginWidget();
@@ -447,5 +453,9 @@
 void PluginView::platformDestroy()
 {
-    delete platformPluginWidget();
+    QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+    if (client && qobject_cast<QGraphicsWebView*>(client->pluginParent()))
+        delete static_cast<PluginContainerSymbian*>(platformPluginWidget())->proxy();
+    else
+        delete platformPluginWidget();
 }
 
Index: trunk/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/rendering/RenderBlock.h	(revision 769)
@@ -76,4 +76,5 @@
     void removePositionedObject(RenderBox*);
     void removePositionedObjects(RenderBlock*);
+    ListHashSet<RenderBox*>* positionedObjects() const { return m_positionedObjects; }
 
     void addPercentHeightDescendant(RenderBox*);
Index: trunk/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/rendering/RenderBox.cpp	(revision 769)
@@ -144,4 +144,14 @@
             if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
                 removeFloatingOrPositionedChildFromBlockLists();
+        }
+    }
+    if (FrameView *frameView = view()->frameView()) {
+        bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
+        bool oldStyleIsFixed = style() && style()->position() == FixedPosition;
+        if (newStyleIsFixed != oldStyleIsFixed) {
+            if (newStyleIsFixed)
+                frameView->addFixedObject();
+            else
+                frameView->removeFixedObject();
         }
     }
Index: trunk/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/rendering/RenderBoxModelObject.cpp	(revision 769)
@@ -558,4 +558,15 @@
     // destRect will be adjusted later if the background is non-repeating.
     bool fixedAttachment = fillLayer->attachment() == FixedBackgroundAttachment;
+
+#if ENABLE(FAST_MOBILE_SCROLLING)
+    if (view()->frameView() && view()->frameView()->canBlitOnScroll()) {
+        // As a side effect of an optimization to blit on scroll, we do not honor the CSS
+        // property "background-attachment: fixed" because it may result in rendering
+        // artifacts. Note, these artifacts only appear if we are blitting on scroll of
+        // a page that has fixed background images.
+        fixedAttachment = false;
+    }
+#endif
+
     if (!fixedAttachment) {
         destRect = IntRect(tx, ty, w, h);
Index: trunk/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/rendering/RenderObject.cpp	(revision 769)
@@ -1592,8 +1592,15 @@
 
     if (view()->frameView()) {
-        // FIXME: A better solution would be to only invalidate the fixed regions when scrolling.  It's overkill to
-        // prevent the entire view from blitting on a scroll.
-        bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition || newStyle->hasFixedBackgroundImage());
-        bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition || m_style->hasFixedBackgroundImage());
+        bool shouldBlitOnFixedBackgroundImage = false;
+#if ENABLE(FAST_MOBILE_SCROLLING)
+        // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
+        // when scrolling a page with a fixed background image. As an optimization, assuming there are
+        // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
+        // ignore the CSS property "background-attachment: fixed".
+        shouldBlitOnFixedBackgroundImage = true;
+#endif
+
+        bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
+        bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
         if (oldStyleSlowScroll != newStyleSlowScroll) {
             if (oldStyleSlowScroll)
Index: trunk/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp	(revision 769)
@@ -1048,6 +1048,13 @@
         // We want the box to be destroyed.
         s->remove();
+        if (m_firstTextBox == s)
+            m_firstTextBox = s->nextTextBox();
+        else
+            s->prevTextBox()->setNextLineBox(s->nextTextBox());
+        if (m_lastTextBox == s)
+            m_lastTextBox = s->prevTextBox();
+        else
+            s->nextTextBox()->setPreviousLineBox(s->prevTextBox());
         s->destroy(renderArena());
-        m_firstTextBox = m_lastTextBox = 0;
         return;
     }
@@ -1350,5 +1357,5 @@
     const InlineTextBox* prev = 0;
     for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) {
-        ASSERT(child->object() == this);
+        ASSERT(child->renderer() == this);
         ASSERT(child->prevTextBox() == prev);
         prev = child;
Index: trunk/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp	(revision 769)
@@ -234,5 +234,5 @@
             m_widget->paint(paintInfo.context, paintInfo.rect);
 
-        if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaints()) {
+        if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaintsIfNotOverlapped()) {
             ASSERT(!paintInfo.overlapTestRequests->contains(this));
             paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
Index: trunk/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp	(revision 769)
@@ -31,4 +31,5 @@
 #include <QtGui/qgraphicssceneevent.h>
 #include <QtGui/qstyleoption.h>
+#include <QtGui/qinputcontext.h>
 #if defined(Q_WS_X11)
 #include <QX11Info>
@@ -64,4 +65,7 @@
     void _q_doLoadFinished(bool success);
 
+    void _q_updateMicroFocus();
+    void _q_pageDestroyed();
+
     QGraphicsWebView* q;
     QWebPage* page;
@@ -79,4 +83,24 @@
 
     emit q->loadFinished(success);
+}
+
+void QGraphicsWebViewPrivate::_q_updateMicroFocus()
+{
+#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
+    // Ideally, this should be handled by a common call to an updateMicroFocus function
+    // in QGraphicsItem. See http://bugreports.qt.nokia.com/browse/QTBUG-7578.
+    QList<QGraphicsView*> views = q->scene()->views();
+    for (int c = 0; c < views.size(); ++c) {
+        QInputContext* ic = views.at(c)->inputContext();
+        if (ic)
+            ic->update();
+    }
+#endif
+}
+
+void QGraphicsWebViewPrivate::_q_pageDestroyed()
+{
+    page = 0;
+    q->setPage(0);
 }
 
@@ -436,4 +460,8 @@
     connect(d->page, SIGNAL(linkClicked(QUrl)),
             this, SIGNAL(linkClicked(QUrl)));
+    connect(d->page, SIGNAL(microFocusChanged()),
+            this, SLOT(_q_updateMicroFocus()));
+    connect(d->page, SIGNAL(destroyed()),
+            this, SLOT(_q_pageDestroyed()));
 }
 
Index: trunk/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h	(revision 769)
@@ -135,4 +135,6 @@
 private:
     Q_PRIVATE_SLOT(d, void _q_doLoadFinished(bool success))
+    Q_PRIVATE_SLOT(d, void _q_updateMicroFocus())
+    Q_PRIVATE_SLOT(d, void _q_pageDestroyed())
 
     QGraphicsWebViewPrivate* const d;
Index: trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h	(revision 769)
@@ -21,9 +21,9 @@
 #define QWEBELEMENT_H
 
-#include <QString>
-#include <QStringList>
-#include <QRect>
-#include <QVariant>
-#include <QExplicitlySharedDataPointer>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qshareddata.h>
 
 #include "qwebkitglobal.h"
Index: trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp	(revision 769)
@@ -325,13 +325,12 @@
 }
 
-static bool webframe_scrollOverflow(WebCore::Frame* frame, int dx, int dy)
-{
-    if (!frame || !frame->document() || !frame->eventHandler())
+bool QWEBKIT_EXPORT qtwebkit_webframe_scrollOverflow(QWebFrame* qFrame, int dx, int dy, const QPoint& pos)
+{
+    WebCore::Frame* frame = QWebFramePrivate::core(qFrame);
+    if (!frame || !frame->document() || !frame->view() || !frame->eventHandler())
         return false;
 
-    Node* node = frame->document()->focusedNode();
-    if (!node)
-        node = frame->document()->elementFromPoint(frame->eventHandler()->currentMousePosition().x(),
-                                                   frame->eventHandler()->currentMousePosition().y());
+    QPoint contentsPos = frame->view()->windowToContents(pos);
+    Node* node = frame->document()->elementFromPoint(contentsPos.x(), contentsPos.y());
     if (!node)
         return false;
@@ -351,16 +350,27 @@
     bool scrolledVertical = false;
 
-    if (dx > 0)
-        scrolledHorizontal = renderLayer->scroll(ScrollRight, ScrollByPixel, dx);
-    else if (dx < 0)
-        scrolledHorizontal = renderLayer->scroll(ScrollLeft, ScrollByPixel, qAbs(dx));
-
-    if (dy > 0)
-        scrolledVertical = renderLayer->scroll(ScrollDown, ScrollByPixel, dy);
-    else if (dy < 0)
-        scrolledVertical = renderLayer->scroll(ScrollUp, ScrollByPixel, qAbs(dy));
-
-    return (scrolledHorizontal || scrolledVertical);
-}
+    do {
+        if (dx > 0)
+            scrolledHorizontal = renderLayer->scroll(ScrollRight, ScrollByPixel, dx);
+        else if (dx < 0)
+            scrolledHorizontal = renderLayer->scroll(ScrollLeft, ScrollByPixel, qAbs(dx));
+
+        if (dy > 0)
+            scrolledVertical = renderLayer->scroll(ScrollDown, ScrollByPixel, dy);
+        else if (dy < 0)
+            scrolledVertical = renderLayer->scroll(ScrollUp, ScrollByPixel, qAbs(dy));
+
+        if (scrolledHorizontal || scrolledVertical)
+            return true;
+
+        renderLayer = renderLayer->parent();
+    } while (renderLayer);
+
+    return false;
+}
+
+
+
+
 
 /*!
@@ -1048,46 +1058,39 @@
 
 /*!
-  \since 4.7
   \internal
   Scrolls nested frames starting at this frame, \a dx pixels to the right 
   and \a dy pixels downward. Both \a dx and \a dy may be negative. First attempts
-  to scroll elements with CSS overflow followed by this frame. If this 
+  to scroll elements with CSS overflow at position pos, followed by this frame. If this 
   frame doesn't scroll, attempts to scroll the parent
-
-  \sa QWebFrame::scroll
-*/
-bool QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy)
-{
-    Frame* frame = QWebFramePrivate::core(qFrame);
-    bool scrolledHorizontal = false;
-    bool scrolledVertical = false;
-    bool scrolledOverflow = webframe_scrollOverflow(frame, dx, dy);
-
-    if (!scrolledOverflow) {
-        if (!frame || !frame->view())
-            return false;
-
-        do {
-            IntSize scrollOffset = frame->view()->scrollOffset();
-            IntPoint maxScrollOffset = frame->view()->maximumScrollPosition();
-
-            if (dx > 0) // scroll right
-                scrolledHorizontal = scrollOffset.width() < maxScrollOffset.x();
-            else if (dx < 0) // scroll left
-                scrolledHorizontal = scrollOffset.width() > 0;
-
-            if (dy > 0) // scroll down
-                scrolledVertical = scrollOffset.height() < maxScrollOffset.y();
-            else if (dy < 0) //scroll up
-                scrolledVertical = scrollOffset.height() > 0;
-
-            if (scrolledHorizontal || scrolledVertical) {
-                frame->view()->scrollBy(IntSize(dx, dy));
-                return true;
-            }
-            frame = frame->tree()->parent(); 
-        } while (frame && frame->view());
-    }
-    return (scrolledHorizontal || scrolledVertical || scrolledOverflow);
+*/
+void QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy, const QPoint& pos)
+{
+    if (!qFrame)
+        return;
+
+    if (qtwebkit_webframe_scrollOverflow(qFrame, dx, dy, pos))
+        return;
+
+    bool scrollHorizontal = false;
+    bool scrollVertical = false;
+
+    do {
+        if (dx > 0)  // scroll right
+            scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) < qFrame->scrollBarMaximum(Qt::Horizontal);
+        else if (dx < 0)  // scroll left
+            scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) > qFrame->scrollBarMinimum(Qt::Horizontal);
+
+        if (dy > 0)  // scroll down
+            scrollVertical = qFrame->scrollBarValue(Qt::Vertical) < qFrame->scrollBarMaximum(Qt::Vertical);
+        else if (dy < 0) //scroll up
+            scrollVertical = qFrame->scrollBarValue(Qt::Vertical) > qFrame->scrollBarMinimum(Qt::Vertical);
+
+        if (scrollHorizontal || scrollVertical) {
+            qFrame->scroll(dx, dy);
+            return;
+        }
+
+        qFrame = qFrame->parentFrame();
+    } while (qFrame);
 }
 
Index: trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebkitversion.h
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebkitversion.h	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebkitversion.h	(revision 769)
@@ -18,5 +18,5 @@
 */
 
-#include <qstring.h>
+#include <QtCore/qstring.h>
 
 #ifndef qwebkitversion_h
Index: trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp	(revision 769)
@@ -1249,6 +1249,6 @@
         case QInputMethodEvent::Selection: {
             if (renderTextControl) {
-                renderTextControl->setSelectionStart(a.start);
-                renderTextControl->setSelectionEnd(a.start + a.length);
+                renderTextControl->setSelectionStart(qMin(a.start, (a.start + a.length)));
+                renderTextControl->setSelectionEnd(qMax(a.start, (a.start + a.length)));
             }
             break;
@@ -3072,4 +3072,6 @@
 
     "Mozilla/5.0 (%Platform%; %Security%; %Subplatform%; %Locale%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%"
+    
+    On mobile platforms such as Symbian S60 and Maemo, "Mobile Safari" is used instead of "Safari".
 
     In this string the following values are replaced at run-time:
@@ -3098,5 +3100,5 @@
     "X11"
 #elif defined Q_OS_SYMBIAN
-    "SymbianOS"
+    "Symbian"
 #else
     "Unknown"
@@ -3165,5 +3167,5 @@
     "DEC Ultrix"
 #elif defined Q_WS_S60
-    "Series60"
+    ""
 #elif defined Q_OS_UNIX
     "UNIX BSD/SYSV system"
@@ -3182,14 +3184,23 @@
     switch (symbianVersion) {
     case QSysInfo::SV_9_2:
-        osVer = "/9.2";
+        osVer = "OS/9.2";
         break;
     case QSysInfo::SV_9_3:
-        osVer = "/9.3";
+        osVer = "OS/9.3";
         break;
     case QSysInfo::SV_9_4:
-        osVer = "/9.4";
+        osVer = "OS/9.4";
+        break;
+    case QSysInfo::SV_SF_2:
+        osVer = "/2";
+        break;
+    case QSysInfo::SV_SF_3:
+        osVer = "/3";
+        break;
+    case QSysInfo::SV_SF_4:
+        osVer = "/4";
         break;
     default: 
-        osVer = "Unknown";
+        osVer = "";
     }
 #endif
@@ -3260,18 +3271,18 @@
     // SubPlatform Version
     QString subPlatformVer;
-#ifdef Q_OS_SYMBIAN
+#ifdef Q_WS_S60
     QSysInfo::S60Version s60Version = QSysInfo::s60Version();
     switch (s60Version) {
     case QSysInfo::SV_S60_3_1:
-        subPlatformVer = "/3.1";
+        subPlatformVer = "Series60/3.1";
         break;
     case QSysInfo::SV_S60_3_2:
-        subPlatformVer = "/3.2";
+        subPlatformVer = "Series60/3.2";
         break;
     case QSysInfo::SV_S60_5_0:
-        subPlatformVer = "/5.0";
+        subPlatformVer = "Series60/5.0";
         break;
     default: 
-        subPlatformVer = " Unknown";
+        subPlatformVer = "";
     }
 #endif
@@ -3283,5 +3294,5 @@
         locale = view()->locale();
     QString name = locale.name();
-    name[2] = QLatin1Char('-');
+    name.replace(QLatin1Char('_'), QLatin1Char('-'));
     ua.append(name);
     ua.append(QLatin1String(") "));
@@ -3306,6 +3317,11 @@
     }
 
+#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
+    ua.append(QString(QLatin1String(" Mobile Safari/%1"))
+                      .arg(qWebKitVersion()));
+#else
     ua.append(QString(QLatin1String(" Safari/%1"))
                       .arg(qWebKitVersion()));
+#endif
 
     return ua;
Index: trunk/src/3rdparty/webkit/WebKit/qt/ChangeLog
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/ChangeLog	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/ChangeLog	(revision 769)
@@ -1,2 +1,174 @@
+2010-05-19  Denis Dzyubenko <denis.dzyubenko@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        When creating the UA, do not sassmue the language code is a
+        two-letter iso639-1 code.
+
+        * Api/qwebpage.cpp:
+        (QWebPage::userAgentForUrl):
+
+2010-05-12  Joe Ligman  <joseph.ligman@nokia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        [Qt] Nested overflow div does not scroll
+        https://bugs.webkit.org/show_bug.cgi?id=38641
+
+        Modify qtwebkit_webframe_scrollOverflow, if the current node's render layer
+        does not scroll it will try and scroll the parent's render layer. Also export
+        qtwebkit_webframe_scrollOverflow so we can use it independently of
+        qtwebkit_webframe_scrollRecursively
+
+        * Api/qwebframe.cpp:
+        (qtwebkit_webframe_scrollOverflow):
+        (qtwebkit_webframe_scrollRecursively):
+
+2010-04-26  Thiago Macieira  <thiago.macieira@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Fix the include header <qstring.h> -> <QtCore/qstring.h>
+
+        The module/header.h style inclusion removes the need to have -I$QTDIR/include/depending-module
+        in the include search path for the application.
+
+        * Api/qwebkitversion.h:
+
+2010-04-08  Joe Ligman  <joseph.ligman@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] qtwebkit_webframe_scrollRecursively scrolls when body.style.overflow="hidden"
+        https://bugs.webkit.org/show_bug.cgi?id=36674
+
+        The scrolling check was based on the frameview's scrolloffset, and
+        maximumScrollPosition, which does not acknowledge the overflow properties.
+
+        I am now basing the scrolling off the scrollbar position. The scrollbars are
+        affected by the overflow properties indicating when not to scroll. The scrollbar
+        positions also continue to work for CSS ::-webkit-scrollbar styles.
+
+        * Api/qwebframe.cpp:
+        (qtwebkit_webframe_scrollRecursively):
+
+2010-03-24  Viatcheslav Ostapenko  <ostapenko.viatcheslav@nokia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        Auto-uppercase and predictive text need to be disabled for S60 (as for maemo)
+        https://bugs.webkit.org/show_bug.cgi?id=33176
+
+        * WebCoreSupport/EditorClientQt.cpp:
+
+2010-03-22  Jakub Wieczorek  <jwieczorek@webkit.org>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Don't construct a QLineEdit every time when painting a text field
+        https://bugs.webkit.org/show_bug.cgi?id=36373
+
+        Add a simple benchmark covering this area.
+
+        * tests/benchmarks/painting/tst_painting.cpp:
+        (tst_Painting::textAreas):
+
+2010-03-22  Yi Shen  <shenyi2006@gmail.com>
+
+        Reviewed by Simon Hausmann.
+
+        https://bugs.webkit.org/show_bug.cgi?id=35933  
+        [Qt] [Symbian] Can not backward select (highlight) text using virtual keyboard
+        Make sure the selection start index is smaller than the selection end index.
+
+        * Api/qwebpage.cpp:
+        (QWebPagePrivate::inputMethodEvent):
+        * tests/qwebpage/tst_qwebpage.cpp:
+        (tst_QWebPage::inputMethods):
+
+2010-03-25  Yael Aharon  <yael.aharon@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] QtLauncher crashes on Mac OS and Linux when exiting with QGraphicsView mode enabled
+        https://bugs.webkit.org/show_bug.cgi?id=35251
+
+        Followed the way QWebView registers for the signal QWebPage::destroyed(), to prevent
+        QGraphicsWebView from referencing QWebPage after it was deleted.        
+
+        * Api/qgraphicswebview.cpp:
+        (QGraphicsWebViewPrivate::_q_pageDestroyed):
+        (QGraphicsWebView::setPage):
+        * Api/qgraphicswebview.h:
+
+2010-03-23  David Leong  <david.leong@nokia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        Build fix for Symbian Def file.
+
+        * symbian/eabi/QtWebKitu.def:
+
+2010-03-18  Joe Ligman  <joseph.ligman@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] New API scrollRecursively has several problems.
+        https://bugs.webkit.org/show_bug.cgi?id=35873
+
+        Remove scrollRecursively from the Qt 4.7 API
+        Update the internal API to accept a hit test position 
+        for nested scrolling
+
+        * Api/qwebframe.cpp:
+        (webframe_scrollOverflow):
+        (qtwebkit_webframe_scrollRecursively):
+        * Api/qwebframe.h:
+        * Api/qwebframe_p.h:
+        * tests/qwebframe/tst_qwebframe.cpp:
+
+2009-12-18  Joe Ligman  <joseph.ligman@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] Add new API to QWebFrame to scrollRecursively starting with any css overflow 
+        then checking current frame and then ancestors
+        https://bugs.webkit.org/show_bug.cgi?id=32668
+
+        * Api/qwebframe.cpp:
+        (QWebFramePrivate::scrollOverflow):
+        (QWebFrame::scrollRecursively):
+        * Api/qwebframe.h:
+        * Api/qwebframe_p.h:
+        * tests/qwebframe/qwebframe.qrc:
+        * tests/qwebframe/testiframe.html: Added.
+        * tests/qwebframe/testiframe2.html: Added.
+        * tests/qwebframe/tst_qwebframe.cpp:
+
+2010-03-21  Kristian Amlie  <kristian.amlie@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        Fixed updating the VKB display when inputting into QGraphicsWebView.
+        https://bugs.webkit.org/show_bug.cgi?id=36292
+
+        * Api/qgraphicswebview.cpp:
+        (QGraphicsWebViewPrivate::_q_updateMicroFocus):
+        (QGraphicsWebView::setPage):
+        * Api/qgraphicswebview.h:
+
+2010-03-04  Simon Hausmann  <simon.hausmann@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] qwebelement.h does not include QtCore headers correctly
+        https://bugs.webkit.org/show_bug.cgi?id=35748
+
+        The header files of QtCore must be included as QtCore/foo.h.
+
+        See also http://bugreports.qt.nokia.com/browse/QTBUG-8661
+
+        * Api/qwebelement.h:
+
 2010-01-28  Kenneth Rohde Christiansen  <kenneth@webkit.org>
 
Index: trunk/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp	(revision 769)
@@ -616,9 +616,9 @@
         }
         webPageClient->setInputMethodHint(Qt::ImhHiddenText, isPasswordField);
-#ifdef Q_WS_MAEMO_5
-        // Maemo 5 MicroB Browser disables auto-uppercase and predictive text, thus, so do we.
+#if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN)
+        // disables auto-uppercase and predictive text for mobile devices
         webPageClient->setInputMethodHint(Qt::ImhNoAutoUppercase, true);
         webPageClient->setInputMethodHint(Qt::ImhNoPredictiveText, true);
-#endif // Q_WS_MAEMO_5
+#endif // Q_WS_MAEMO_5 || Q_OS_SYMBIAN
 #endif // QT_VERSION check
         webPageClient->setInputMethodEnabled(active);
Index: trunk/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def	(revision 769)
@@ -624,4 +624,30 @@
 	?qt_resumeActiveDOMObjects@@YAXPAVQWebFrame@@@Z @ 623 NONAME ; void qt_resumeActiveDOMObjects(class QWebFrame *)
 	?qt_suspendActiveDOMObjects@@YAXPAVQWebFrame@@@Z @ 624 NONAME ; void qt_suspendActiveDOMObjects(class QWebFrame *)
-	?qtwebkit_webframe_scrollRecursively@@YA_NPAVQWebFrame@@HH@Z @ 625 NONAME ; bool qtwebkit_webframe_scrollRecursively(class QWebFrame *, int, int)
+	?qtwebkit_webframe_scrollRecursively@@YA_NPAVQWebFrame@@HH@Z @ 625 NONAME ABSENT ; bool qtwebkit_webframe_scrollRecursively(class QWebFrame *, int, int)
+	?closeEvent@QWebInspector@@MAEXPAVQCloseEvent@@@Z @ 626 NONAME ABSENT ; void QWebInspector::closeEvent(class QCloseEvent *)
+	?inspectorUrl@QWebSettings@@QBE?AVQUrl@@XZ @ 627 NONAME ABSENT ; class QUrl QWebSettings::inspectorUrl(void) const
+	?isTiledBackingStoreFrozen@QGraphicsWebView@@QBE_NXZ @ 628 NONAME ABSENT ; bool QGraphicsWebView::isTiledBackingStoreFrozen(void) const
+	?pageChanged@QWebFrame@@IAEXXZ @ 629 NONAME ABSENT ; void QWebFrame::pageChanged(void)
+	?qt_drt_enableCaretBrowsing@@YAXPAVQWebPage@@_N@Z @ 630 NONAME ABSENT ; void qt_drt_enableCaretBrowsing(class QWebPage *, bool)
+	?qt_drt_evaluateScriptInIsolatedWorld@@YAXPAVQWebFrame@@HABVQString@@@Z @ 631 NONAME ABSENT ; void qt_drt_evaluateScriptInIsolatedWorld(class QWebFrame *, int, class QString const &)
+	?qt_drt_hasDocumentElement@@YA_NPAVQWebFrame@@@Z @ 632 NONAME ABSENT ; bool qt_drt_hasDocumentElement(class QWebFrame *)
+	?qt_drt_numberOfPages@@YAHPAVQWebFrame@@MM@Z @ 633 NONAME ABSENT ; int qt_drt_numberOfPages(class QWebFrame *, float, float)
+	?qt_drt_pageNumberForElementById@@YAHPAVQWebFrame@@ABVQString@@MM@Z @ 634 NONAME ABSENT ; int qt_drt_pageNumberForElementById(class QWebFrame *, class QString const &, float, float)
+	?qt_drt_pauseSVGAnimation@@YA_NPAVQWebFrame@@ABVQString@@N1@Z @ 635 NONAME ABSENT ; bool qt_drt_pauseSVGAnimation(class QWebFrame *, class QString const &, double, class QString const &)
+	?qt_drt_setDomainRelaxationForbiddenForURLScheme@@YAX_NABVQString@@@Z @ 636 NONAME ABSENT ; void qt_drt_setDomainRelaxationForbiddenForURLScheme(bool, class QString const &)
+	?qt_drt_setFrameFlatteningEnabled@@YAXPAVQWebPage@@_N@Z @ 637 NONAME ABSENT ; void qt_drt_setFrameFlatteningEnabled(class QWebPage *, bool)
+	?qt_drt_setMediaType@@YAXPAVQWebFrame@@ABVQString@@@Z @ 638 NONAME ABSENT ; void qt_drt_setMediaType(class QWebFrame *, class QString const &)
+	?qt_drt_setTimelineProfilingEnabled@@YAXPAVQWebPage@@_N@Z @ 639 NONAME ABSENT ; void qt_drt_setTimelineProfilingEnabled(class QWebPage *, bool)
+	?qt_drt_webinspector_close@@YAXPAVQWebPage@@@Z @ 640 NONAME ABSENT ; void qt_drt_webinspector_close(class QWebPage *)
+	?qt_drt_webinspector_executeScript@@YAXPAVQWebPage@@JABVQString@@@Z @ 641 NONAME ABSENT ; void qt_drt_webinspector_executeScript(class QWebPage *, long, class QString const &)
+	?qt_drt_webinspector_show@@YAXPAVQWebPage@@@Z @ 642 NONAME ABSENT ; void qt_drt_webinspector_show(class QWebPage *)
+	?qt_drt_workerThreadCount@@YAHXZ @ 643 NONAME ABSENT ; int qt_drt_workerThreadCount(void)
+	?qt_wrt_setViewMode@@YAXPAVQWebPage@@ABVQString@@@Z @ 644 NONAME ABSENT ; void qt_wrt_setViewMode(class QWebPage *, class QString const &)
+	?qtwebkit_webframe_scrollRecursively@@YAXPAVQWebFrame@@HHABVQPoint@@@Z @ 645 NONAME ; void qtwebkit_webframe_scrollRecursively(class QWebFrame *, int, int, class QPoint const &)
+	?resizesToContents@QGraphicsWebView@@QBE_NXZ @ 646 NONAME ABSENT ; bool QGraphicsWebView::resizesToContents(void) const
+	?scrollToAnchor@QWebFrame@@QAEXABVQString@@@Z @ 647 NONAME ABSENT ; void QWebFrame::scrollToAnchor(class QString const &)
+	?setInspectorUrl@QWebSettings@@QAEXABVQUrl@@@Z @ 648 NONAME ABSENT ; void QWebSettings::setInspectorUrl(class QUrl const &)
+	?setResizesToContents@QGraphicsWebView@@QAEX_N@Z @ 649 NONAME ABSENT ; void QGraphicsWebView::setResizesToContents(bool)
+	?setTiledBackingStoreFrozen@QGraphicsWebView@@QAEX_N@Z @ 650 NONAME ABSENT ; void QGraphicsWebView::setTiledBackingStoreFrozen(bool)
+	?qtwebkit_webframe_scrollOverflow@@YA_NPAVQWebFrame@@HHABVQPoint@@@Z @ 651 NONAME ABSENT ; bool qtwebkit_webframe_scrollOverflow(QWebFrame *, int, int, const QPoint&)
 
Index: trunk/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def	(revision 769)
@@ -694,4 +694,79 @@
 	_Z25qt_resumeActiveDOMObjectsP9QWebFrame @ 693 NONAME
 	_Z26qt_suspendActiveDOMObjectsP9QWebFrame @ 694 NONAME
-	_Z35qtwebkit_webframe_scrollRecursivelyP9QWebFrameii @ 695 NONAME
-
+	_Z35qtwebkit_webframe_scrollRecursivelyP9QWebFrameii @ 695 NONAME ABSENT
+	_Z35qtwebkit_webframe_scrollRecursivelyP9QWebFrameiiRK6QPoint @ 696 NONAME
+	_ZN9QWebFrame17scrollRecursivelyEii @ 697 NONAME ABSENT
+	_ZN16QGraphicsWebView20setResizesToContentsEb @ 698 NONAME ABSENT
+	_ZNK16QGraphicsWebView17resizesToContentsEv @ 699 NONAME ABSENT
+	_Z20qt_drt_numberOfPagesP9QWebFrameff @ 700 NONAME ABSENT
+	_Z24qt_drt_pauseSVGAnimationP9QWebFrameRK7QStringdS3_ @ 701 NONAME ABSENT
+	_Z24qt_drt_webinspector_showP8QWebPage @ 702 NONAME ABSENT
+	_Z24qt_drt_workerThreadCountv @ 703 NONAME ABSENT
+	_Z25qt_drt_hasDocumentElementP9QWebFrame @ 704 NONAME ABSENT
+	_Z25qt_drt_webinspector_closeP8QWebPage @ 705 NONAME ABSENT
+	_Z31qt_drt_pageNumberForElementByIdP9QWebFrameRK7QStringff @ 706 NONAME ABSENT
+	_Z33qt_drt_webinspector_executeScriptP8QWebPagelRK7QString @ 707 NONAME ABSENT
+	_Z34qt_drt_setTimelineProfilingEnabledP8QWebPageb @ 708 NONAME ABSENT
+	_Z32qt_drt_setFrameFlatteningEnabledP8QWebPageb @ 709 NONAME ABSENT
+	_Z36qt_drt_evaluateScriptInIsolatedWorldP9QWebFrameiRK7QString @ 710 NONAME ABSENT
+	_Z47qt_drt_setDomainRelaxationForbiddenForURLSchemebRK7QString @ 711 NONAME ABSENT
+	_ZN9QWebFrame11pageChangedEv @ 712 NONAME ABSENT
+	_ZN9QWebFrame14scrollToAnchorERK7QString @ 713 NONAME ABSENT
+	_ZN12QWebSettings15setInspectorUrlERK4QUrl @ 714 NONAME ABSENT
+	_ZN13QWebInspector10closeEventEP11QCloseEvent @ 715 NONAME ABSENT
+	_ZN16QGraphicsWebView26setTiledBackingStoreFrozenEb @ 716 NONAME ABSENT
+	_ZNK16QGraphicsWebView25isTiledBackingStoreFrozenEv @ 717 NONAME ABSENT
+	_Z18qt_wrt_setViewModeP8QWebPageRK7QString @ 718 NONAME ABSENT
+	_Z19qt_drt_setMediaTypeP9QWebFrameRK7QString @ 719 NONAME ABSENT
+	_Z26qt_drt_enableCaretBrowsingP8QWebPageb @ 720 NONAME ABSENT
+	_ZNK12QWebSettings12inspectorUrlEv @ 721 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt19webPageSetGroupNameEP8QWebPageRK7QString @ 722 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt16webPageGroupNameEP8QWebPage @ 723 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt23garbageCollectorCollectEv @ 724 NONAME ABSENT
+	_Z32qtwebkit_webframe_scrollOverflowP9QWebFrameiiRK6QPoint @ 725 NONAME
+	_ZN23DumpRenderTreeSupportQt12setMediaTypeEP9QWebFrameRK7QString @ 726 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt13numberOfPagesEP9QWebFrameff @ 727 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt13selectedRangeEP8QWebPage @ 728 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt14clearFrameNameEP9QWebFrame @ 729 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt14pauseAnimationEP9QWebFrameRK7QStringdS4_ @ 730 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt15dumpFrameLoaderEb @ 731 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt16dumpNotificationEb @ 732 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt16isCommandEnabledEP8QWebPageRK7QString @ 733 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt16webInspectorShowEP8QWebPage @ 734 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt17pauseSVGAnimationEP9QWebFrameRK7QStringdS4_ @ 735 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt17webInspectorCloseEP8QWebPage @ 736 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt17workerThreadCountEv @ 737 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt18hasDocumentElementEP9QWebFrame @ 738 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt20dumpEditingCallbacksEb @ 739 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt21markerTextForListItemERK11QWebElement @ 740 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt22javaScriptObjectsCountEv @ 741 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt23setCaretBrowsingEnabledEP8QWebPageb @ 742 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt24executeCoreCommandByNameEP8QWebPageRK7QStringS4_ @ 743 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt21dumpSetAcceptsEditingEb @744 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt22resumeActiveDOMObjectsEP9QWebFrame @745 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt23suspendActiveDOMObjectsEP9QWebFrame @746 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt24numberOfActiveAnimationsEP9QWebFrame @747 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt24pageNumberForElementByIdEP9QWebFrameRK7QStringff @748 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt25dumpResourceLoadCallbacksEb @749 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt25pauseTransitionOfPropertyEP9QWebFrameRK7QStringdS4_ @750 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt25setFrameFlatteningEnabledEP8QWebPageb @751 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt25webInspectorExecuteScriptEP8QWebPagelRK7QString @752 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt25whiteListAccessFromOriginERK7QStringS2_S2_b @753 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt26counterValueForElementByIdEP9QWebFrameRK7QString @754 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt26firstRectForCharacterRangeEP8QWebPageii @755 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt26overwritePluginDirectoriesEv @756 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt27resetOriginAccessWhiteListsEv @757 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt27setSmartInsertDeleteEnabledEP8QWebPageb @758 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt27setTimelineProfilingEnabledEP8QWebPageb @759 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt28setDumpRenderTreeModeEnabledEb @760 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt29dumpResourceLoadCallbacksPathERK7QString @761 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt29evaluateScriptInIsolatedWorldEP9QWebFrameiRK7QString @762 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt29setJavaScriptProfilingEnabledEP9QWebFrameb @763 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt29setWillSendRequestReturnsNullEb @764 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt30setWillSendRequestClearHeadersERK11QStringList @765 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt33computedStyleIncludingVisitedInfoERK11QWebElement @766 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt34setSelectTrailingWhitespaceEnabledEP8QWebPageb @767 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt39elementDoesAutoCompleteForElementWithIdEP9QWebFrameRK7QString @768 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt39setWillSendRequestReturnsNullOnRedirectEb @769 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt40garbageCollectorCollectOnAlternateThreadEb @770 NONAME ABSENT
+	_ZN23DumpRenderTreeSupportQt40setDomainRelaxationForbiddenForURLSchemeEbRK7QString @771 NONAME ABSENT
Index: trunk/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp	(revision 769)
@@ -20,4 +20,5 @@
 #include <QtTest/QtTest>
 
+#include <qwebelement.h>
 #include <qwebframe.h>
 #include <qwebview.h>
@@ -60,4 +61,5 @@
     void paint_data();
     void paint();
+    void textAreas();
 
 private:
@@ -106,4 +108,29 @@
 }
 
+void tst_Painting::textAreas()
+{
+    m_view->load(QUrl("data:text/html;<html><body></body></html>"));
+    ::waitForSignal(m_view, SIGNAL(loadFinished(bool)));
+
+    QWebElement bodyElement = m_page->mainFrame()->findFirstElement("body");
+
+    int count = 100;
+    while (count--) {
+        QString markup("<textarea cols='1' rows='1'></textarea>");
+        bodyElement.appendInside(markup);
+    }
+
+    /* force a layout */
+    QWebFrame* mainFrame = m_page->mainFrame();
+    mainFrame->toPlainText();
+
+    QPixmap pixmap(mainFrame->contentsSize());
+    QBENCHMARK {
+        QPainter painter(&pixmap);
+        mainFrame->render(&painter, QRect(QPoint(0, 0), mainFrame->contentsSize()));
+        painter.end();
+    }
+}
+
 QTEST_MAIN(tst_Painting)
 #include "tst_painting.moc"
Index: trunk/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp	(revision 769)
@@ -607,5 +607,4 @@
     void evaluateWillCauseRepaint();
     void qObjectWrapperWithSameIdentity();
-    void scrollRecursively();
 
 private:
@@ -2826,70 +2825,4 @@
 }
 
-bool QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy);
-
-void tst_QWebFrame::scrollRecursively()
-{
-    // The test content is 
-    // a nested frame set
-    // The main frame scrolls
-    // and has two children
-    // an iframe and a div overflow
-    // both scroll
-    QWebView webView;
-    QWebPage* webPage = webView.page();
-    QSignalSpy loadSpy(webPage, SIGNAL(loadFinished(bool)));
-    QUrl url = QUrl("qrc:///testiframe.html");
-    webPage->mainFrame()->load(url);
-    QTRY_COMPARE(loadSpy.count(), 1);
-
-    QList<QWebFrame*> children =  webPage->mainFrame()->childFrames();
-    QVERIFY(children.count() == 1);
-
-    // 1st test
-    // call scrollRecursively over mainframe
-    // verify scrolled
-    // verify scroll postion changed
-    QPoint scrollPosition(webPage->mainFrame()->scrollPosition());
-    QVERIFY(qtwebkit_webframe_scrollRecursively(webPage->mainFrame(), 10, 10));
-    QVERIFY(scrollPosition != webPage->mainFrame()->scrollPosition());
-
-    // 2nd test
-    // call scrollRecursively over child iframe
-    // verify scrolled
-    // verify child scroll position changed
-    // verify parent's scroll position did not change
-    scrollPosition = webPage->mainFrame()->scrollPosition();
-    QPoint childScrollPosition = children.at(0)->scrollPosition();
-    QVERIFY(qtwebkit_webframe_scrollRecursively(children.at(0), 10, 10));
-    QVERIFY(scrollPosition == webPage->mainFrame()->scrollPosition());
-    QVERIFY(childScrollPosition != children.at(0)->scrollPosition());
-
-    // 3rd test
-    // call scrollRecursively over div overflow
-    // verify scrolled == true
-    // verify parent and child frame's scroll postion did not change
-    QWebElement div = webPage->mainFrame()->documentElement().findFirst("#content1");
-    QMouseEvent evpres(QEvent::MouseMove, div.geometry().center(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
-    webPage->event(&evpres);
-    scrollPosition = webPage->mainFrame()->scrollPosition();
-    childScrollPosition = children.at(0)->scrollPosition();
-    QVERIFY(qtwebkit_webframe_scrollRecursively(webPage->mainFrame(), 5, 5));
-    QVERIFY(childScrollPosition == children.at(0)->scrollPosition());
-    QVERIFY(scrollPosition == webPage->mainFrame()->scrollPosition());
-
-    // 4th test
-    // call scrollRecursively twice over childs iframe
-    // verify scrolled == true first time
-    // verify parent's scroll == true second time
-    // verify parent and childs scroll position changed
-    childScrollPosition = children.at(0)->scrollPosition();
-    QVERIFY(qtwebkit_webframe_scrollRecursively(children.at(0), -10, -10));
-    QVERIFY(childScrollPosition != children.at(0)->scrollPosition());
-    scrollPosition = webPage->mainFrame()->scrollPosition();
-    QVERIFY(qtwebkit_webframe_scrollRecursively(children.at(0), -10, -10));
-    QVERIFY(scrollPosition != webPage->mainFrame()->scrollPosition());
-
-}
-
 QTEST_MAIN(tst_QWebFrame)
 #include "tst_qwebframe.moc"
Index: trunk/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
===================================================================
--- trunk/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp	(revision 766)
+++ trunk/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp	(revision 769)
@@ -1452,4 +1452,24 @@
     QString selectionValue = variant.value<QString>();
     QCOMPARE(selectionValue, QString("eb"));
+
+    //Set selection with negative length
+    inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 6, -5, QVariant());
+    QInputMethodEvent eventSelection2("",inputAttributes);
+    page->event(&eventSelection2);
+
+    //ImAnchorPosition
+    variant = page->inputMethodQuery(Qt::ImAnchorPosition);
+    anchorPosition =  variant.toInt();
+    QCOMPARE(anchorPosition, 1);
+
+    //ImCursorPosition
+    variant = page->inputMethodQuery(Qt::ImCursorPosition);
+    cursorPosition =  variant.toInt();
+    QCOMPARE(cursorPosition, 6);
+
+    //ImCurrentSelection
+    variant = page->inputMethodQuery(Qt::ImCurrentSelection);
+    selectionValue = variant.value<QString>();
+    QCOMPARE(selectionValue, QString("tWebK"));
 #endif
 
Index: trunk/src/activeqt/container/qaxwidget.cpp
===================================================================
--- trunk/src/activeqt/container/qaxwidget.cpp	(revision 766)
+++ trunk/src/activeqt/container/qaxwidget.cpp	(revision 769)
@@ -1439,7 +1439,4 @@
 HRESULT WINAPI QAxClientSite::EnableModeless(BOOL fEnable)
 {
-#if !defined(Q_OS_WINCE)
-    LockWindowUpdate(host->window()->winId());
-#endif
     EnableWindow(host->window()->winId(), fEnable);
 
@@ -1452,7 +1449,4 @@
     }
     qt_win_ignoreNextMouseReleaseEvent = false;
-#if !defined(Q_OS_WINCE)
-    LockWindowUpdate(0);
-#endif
     return S_OK;
 }
Index: trunk/src/corelib/animation/qanimationgroup.cpp
===================================================================
--- trunk/src/corelib/animation/qanimationgroup.cpp	(revision 766)
+++ trunk/src/corelib/animation/qanimationgroup.cpp	(revision 769)
@@ -245,5 +245,5 @@
     d->animations.removeAt(index);
     animation->setParent(0);
-    d->animationRemovedAt(index);
+    d->animationRemoved(index, animation);
     return animation;
 }
@@ -286,5 +286,5 @@
 
 
-void QAnimationGroupPrivate::animationRemovedAt(int index)
+void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *)
 {
     Q_Q(QAnimationGroup);
Index: trunk/src/corelib/animation/qanimationgroup_p.h
===================================================================
--- trunk/src/corelib/animation/qanimationgroup_p.h	(revision 766)
+++ trunk/src/corelib/animation/qanimationgroup_p.h	(revision 769)
@@ -73,6 +73,17 @@
     }
 
-    virtual void animationInsertedAt(int index) { Q_UNUSED(index) };
-    virtual void animationRemovedAt(int index);
+    virtual void animationInsertedAt(int) { }
+    virtual void animationRemoved(int, QAbstractAnimation *);
+
+    void disconnectUncontrolledAnimation(QAbstractAnimation *anim)
+    {
+        //0 for the signal here because we might be called from the animation destructor
+        QObject::disconnect(anim, 0, q_func(), SLOT(_q_uncontrolledAnimationFinished()));
+    }
+
+    void connectUncontrolledAnimation(QAbstractAnimation *anim)
+    {
+        QObject::connect(anim, SIGNAL(finished()), q_func(), SLOT(_q_uncontrolledAnimationFinished()));
+    }
 
     QList<QAbstractAnimation *> animations;
Index: trunk/src/corelib/animation/qparallelanimationgroup.cpp
===================================================================
--- trunk/src/corelib/animation/qparallelanimationgroup.cpp	(revision 766)
+++ trunk/src/corelib/animation/qparallelanimationgroup.cpp	(revision 769)
@@ -247,9 +247,7 @@
 void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations()
 {
-    Q_Q(QParallelAnimationGroup);
-
     QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
     while (it != uncontrolledFinishTime.end()) {
-        QObject::disconnect(it.key(), SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
+        disconnectUncontrolledAnimation(it.key());
         ++it;
     }
@@ -260,11 +258,9 @@
 void QParallelAnimationGroupPrivate::connectUncontrolledAnimations()
 {
-    Q_Q(QParallelAnimationGroup);
-
     for (int i = 0; i < animations.size(); ++i) {
         QAbstractAnimation *animation = animations.at(i);
         if (animation->duration() == -1 || animation->loopCount() < 0) {
             uncontrolledFinishTime[animation] = -1;
-            QObject::connect(animation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
+            connectUncontrolledAnimation(animation);
         }
     }
@@ -306,4 +302,11 @@
 }
 
+void QParallelAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim)
+{
+    QAnimationGroupPrivate::animationRemoved(index, anim);
+    disconnectUncontrolledAnimation(anim);
+    uncontrolledFinishTime.remove(anim);
+}
+
 /*!
     \reimp
Index: trunk/src/corelib/animation/qparallelanimationgroup_p.h
===================================================================
--- trunk/src/corelib/animation/qparallelanimationgroup_p.h	(revision 766)
+++ trunk/src/corelib/animation/qparallelanimationgroup_p.h	(revision 769)
@@ -81,4 +81,6 @@
     void disconnectUncontrolledAnimations();
 
+    void animationRemoved(int index, QAbstractAnimation *);
+
     // private slot
     void _q_uncontrolledAnimationFinished();
Index: trunk/src/corelib/animation/qsequentialanimationgroup.cpp
===================================================================
--- trunk/src/corelib/animation/qsequentialanimationgroup.cpp	(revision 766)
+++ trunk/src/corelib/animation/qsequentialanimationgroup.cpp	(revision 769)
@@ -480,5 +480,5 @@
     // connects to the finish signal of uncontrolled animations
     if (currentAnimation->totalDuration() == -1)
-        QObject::connect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
+        connectUncontrolledAnimation(currentAnimation);
 
     currentAnimation->start();
@@ -497,5 +497,5 @@
     actualDuration[currentAnimationIndex] = currentAnimation->currentTime();
 
-    QObject::disconnect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished()));
+    disconnectUncontrolledAnimation(currentAnimation);
 
     if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last())
@@ -544,8 +544,8 @@
     method is called.
 */
-void QSequentialAnimationGroupPrivate::animationRemovedAt(int index)
+void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim)
 {
     Q_Q(QSequentialAnimationGroup);
-    QAnimationGroupPrivate::animationRemovedAt(index);
+    QAnimationGroupPrivate::animationRemoved(index, anim);
 
     Q_ASSERT(currentAnimation); // currentAnimation should always be set
@@ -556,5 +556,8 @@
     const int currentIndex = animations.indexOf(currentAnimation);
     if (currentIndex == -1) {
-        //we're removing the current animation, let's update it to another one
+        //we're removing the current animation
+
+        disconnectUncontrolledAnimation(currentAnimation);
+
         if (index < animations.count())
             setCurrentAnimation(index); //let's try to take the next one
Index: trunk/src/corelib/animation/qsequentialanimationgroup_p.h
===================================================================
--- trunk/src/corelib/animation/qsequentialanimationgroup_p.h	(revision 766)
+++ trunk/src/corelib/animation/qsequentialanimationgroup_p.h	(revision 769)
@@ -86,5 +86,5 @@
 
     void animationInsertedAt(int index);
-    void animationRemovedAt(int index);
+    void animationRemoved(int index, QAbstractAnimation *anim);
 
     bool atEnd() const;
Index: trunk/src/corelib/arch/armv6/qatomic_generic_armv6.cpp
===================================================================
--- trunk/src/corelib/arch/armv6/qatomic_generic_armv6.cpp	(revision 766)
+++ trunk/src/corelib/arch/armv6/qatomic_generic_armv6.cpp	(revision 769)
@@ -47,4 +47,5 @@
 
 #ifdef QT_HAVE_ARMV6
+#ifndef SYMBIAN_E32_ATOMIC_API
 
 QT_BEGIN_NAMESPACE
@@ -55,4 +56,22 @@
 #pragma push
 #pragma arm
+Q_CORE_EXPORT asm
+bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue)
+{
+    CODE32
+    //fall through
+}
 Q_CORE_EXPORT asm
 bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
@@ -74,4 +93,22 @@
 
 Q_CORE_EXPORT asm
+int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
 int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
 {
@@ -88,4 +125,22 @@
 }
 
+Q_CORE_EXPORT asm
+int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd)
+{
+    CODE32
+    //fall through
+}
 Q_CORE_EXPORT asm
 int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
@@ -105,4 +160,28 @@
 }
 
+Q_CORE_EXPORT asm
+bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    CODE32
+    //fall through
+}
 Q_CORE_EXPORT asm
 bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
@@ -126,4 +205,22 @@
 
 Q_CORE_EXPORT asm
+void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
 void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
 {
@@ -140,4 +237,22 @@
 }
 
+Q_CORE_EXPORT asm
+void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    CODE32
+    //fall through
+}
+Q_CORE_EXPORT asm
+void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    CODE32
+    //fall through
+}
 Q_CORE_EXPORT asm
 void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
@@ -159,4 +274,19 @@
 #pragma pop
 #elif defined (Q_CC_GCCE)
+Q_CORE_EXPORT __declspec( naked )
+bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue)
+{
+    //fall through
+}
 Q_CORE_EXPORT __declspec( naked )
 bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
@@ -177,4 +307,19 @@
 
 Q_CORE_EXPORT __declspec( naked )
+int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
 int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
 {
@@ -190,4 +335,19 @@
 }
 
+Q_CORE_EXPORT __declspec( naked )
+int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd)
+{
+    //fall through
+}
 Q_CORE_EXPORT __declspec( naked )
 int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
@@ -206,4 +366,25 @@
 }
 
+Q_CORE_EXPORT __declspec( naked )
+bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    //fall through
+}
 Q_CORE_EXPORT __declspec( naked )
 bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
@@ -226,4 +407,19 @@
 
 Q_CORE_EXPORT __declspec( naked )
+void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
 void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
 {
@@ -239,4 +435,19 @@
 }
 
+Q_CORE_EXPORT __declspec( naked )
+void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    //fall through
+}
+Q_CORE_EXPORT __declspec( naked )
+void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    //fall through
+}
 Q_CORE_EXPORT __declspec( naked )
 void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
@@ -259,2 +470,3 @@
 QT_END_NAMESPACE
 #endif
+#endif
Index: trunk/src/corelib/arch/qatomic_alpha.h
===================================================================
--- trunk/src/corelib/arch/qatomic_alpha.h	(revision 766)
+++ trunk/src/corelib/arch/qatomic_alpha.h	(revision 769)
@@ -368,5 +368,5 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
 {
-    register void *old, *tmp;
+    register T *old, *tmp;
     asm volatile("1:\n"
                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
@@ -386,5 +386,5 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
 {
-    register void *old, *tmp;
+    register T *old, *tmp;
     asm volatile("1:\n"
                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
@@ -405,5 +405,5 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
 {
-    register void *old, *tmp;
+    register T *old, *tmp;
     asm volatile("mb\n"
                  "1:\n"
@@ -424,5 +424,5 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
 {
-    register void *old, *tmp;
+    register T *old, *tmp;
     asm volatile("1:\n"
                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
@@ -442,5 +442,5 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
 {
-    register void *old, *tmp;
+    register T *old, *tmp;
     asm volatile("1:\n"
                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
@@ -461,5 +461,5 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
 {
-    register void *old, *tmp;
+    register T *old, *tmp;
     asm volatile("mb\n"
                  "1:\n"
Index: trunk/src/corelib/arch/qatomic_s390.h
===================================================================
--- trunk/src/corelib/arch/qatomic_s390.h	(revision 766)
+++ trunk/src/corelib/arch/qatomic_s390.h	(revision 769)
@@ -367,9 +367,7 @@
 {
 #ifndef __s390x__
-    return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
-                             "", "bcr 15,0\n");
-#else
-    return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
-                              "", "bcr 15,0\n");
+    return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "");
+#else
+    return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "");
 #endif
 }
@@ -379,7 +377,7 @@
 {
 #ifndef __s390x__
-    return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", "", "");
-#else
-    return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", "", "");
+    return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n");
+#else
+    return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n");
 #endif
 }
@@ -389,9 +387,7 @@
 {
 #ifndef __s390x__
-    return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
-                             "bcr 15,0 \n", "");
-#else
-    return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
-                              "bcr 15,0\n", "");
+    return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", "");
+#else
+    return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", "");
 #endif
 }
Index: trunk/src/corelib/arch/qatomic_symbian.h
===================================================================
--- trunk/src/corelib/arch/qatomic_symbian.h	(revision 766)
+++ trunk/src/corelib/arch/qatomic_symbian.h	(revision 769)
@@ -43,5 +43,5 @@
 #define QATOMIC_SYMBIAN_H
 
-#include <qglobal.h>
+#include <QtCore/qglobal.h>
 #include <e32std.h>
 
@@ -105,8 +105,26 @@
 Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *, int);
 Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddOrdered(volatile int *, int);
+Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetRelaxed(volatile int *, int, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *, int);
+Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetAcquire(volatile int *, int, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddAcquire(volatile int *, int);
+Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetRelease(volatile int *, int, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreRelease(volatile int *, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddRelease(volatile int *, int);
 
 Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *, void *, void *);
 Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *, void *);
 Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *, qptrdiff);
+Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *, void *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *, qptrdiff);
+Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *, void *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *, qptrdiff);
+Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetRelease(void * volatile *, void *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *, qptrdiff);
 
 // Reference counting
@@ -134,15 +152,15 @@
 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
 {
-    return testAndSetOrdered(expectedValue, newValue);
+    return QBasicAtomicInt_testAndSetRelaxed(&_q_value, expectedValue, newValue);
 }
 
 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
 {
-    return testAndSetOrdered(expectedValue, newValue);
+    return QBasicAtomicInt_testAndSetAcquire(&_q_value, expectedValue, newValue);
 }
 
 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
 {
-    return testAndSetOrdered(expectedValue, newValue);
+    return QBasicAtomicInt_testAndSetRelease(&_q_value, expectedValue, newValue);
 }
 
@@ -156,15 +174,15 @@
 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
 {
-    return fetchAndStoreOrdered(newValue);
+    return QBasicAtomicInt_fetchAndStoreRelaxed(&_q_value, newValue);
 }
 
 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
 {
-    return fetchAndStoreOrdered(newValue);
+    return QBasicAtomicInt_fetchAndStoreAcquire(&_q_value, newValue);
 }
 
 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
 {
-    return fetchAndStoreOrdered(newValue);
+    return QBasicAtomicInt_fetchAndStoreRelease(&_q_value, newValue);
 }
 
@@ -178,15 +196,15 @@
 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
 {
-    return fetchAndAddOrdered(valueToAdd);
+    return QBasicAtomicInt_fetchAndAddRelaxed(&_q_value, valueToAdd);
 }
 
 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
 {
-    return fetchAndAddOrdered(valueToAdd);
+    return QBasicAtomicInt_fetchAndAddAcquire(&_q_value, valueToAdd);
 }
 
 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
 {
-    return fetchAndAddOrdered(valueToAdd);
+    return QBasicAtomicInt_fetchAndAddRelease(&_q_value, valueToAdd);
 }
 
@@ -196,7 +214,6 @@
 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
 {
-    union { T * volatile * typed; void * volatile * voidp; } pointer;
-    pointer.typed = &_q_value;
-    return QBasicAtomicPointer_testAndSetOrdered(pointer.voidp, expectedValue, newValue);
+    return QBasicAtomicPointer_testAndSetOrdered(reinterpret_cast<void * volatile *>(&_q_value),
+        expectedValue, newValue);
 }
 
@@ -204,5 +221,6 @@
 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
 {
-    return testAndSetOrdered(expectedValue, newValue);
+    return QBasicAtomicPointer_testAndSetRelaxed(reinterpret_cast<void * volatile *>(&_q_value),
+        expectedValue, newValue);
 }
 
@@ -210,5 +228,6 @@
 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
 {
-    return testAndSetOrdered(expectedValue, newValue);
+    return QBasicAtomicPointer_testAndSetAcquire(reinterpret_cast<void * volatile *>(&_q_value),
+        expectedValue, newValue);
 }
 
@@ -216,5 +235,6 @@
 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
 {
-    return testAndSetOrdered(expectedValue, newValue);
+    return QBasicAtomicPointer_testAndSetRelease(reinterpret_cast<void * volatile *>(&_q_value),
+        expectedValue, newValue);
 }
 
@@ -224,9 +244,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
 {
-    union { T * volatile * typed; void * volatile * voidp; } pointer;
-    union { T *typed; void *voidp; } returnValue;
-    pointer.typed = &_q_value;
-    returnValue.voidp = QBasicAtomicPointer_fetchAndStoreOrdered(pointer.voidp, newValue);
-    return returnValue.typed;
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreOrdered(
+        reinterpret_cast<void * volatile *>(&_q_value)
+        , newValue));
 }
 
@@ -234,5 +252,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
 {
-    return fetchAndStoreOrdered(newValue);
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreRelaxed(
+        reinterpret_cast<void * volatile *>(&_q_value)
+        , newValue));
 }
 
@@ -240,5 +260,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
 {
-    return fetchAndStoreOrdered(newValue);
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreAcquire(
+        reinterpret_cast<void * volatile *>(&_q_value)
+        , newValue));
 }
 
@@ -246,5 +268,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
 {
-    return fetchAndStoreOrdered(newValue);
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreRelease(
+        reinterpret_cast<void * volatile *>(&_q_value)
+        , newValue));
 }
 
@@ -254,9 +278,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
 {
-    union { T * volatile *typed; void * volatile *voidp; } pointer;
-    union { T *typed; void *voidp; } returnValue;
-    pointer.typed = &_q_value;
-    returnValue.voidp = QBasicAtomicPointer_fetchAndAddOrdered(pointer.voidp, valueToAdd * sizeof(T));
-    return returnValue.typed;
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndAddOrdered(
+        reinterpret_cast<void * volatile *>(&_q_value),
+        valueToAdd * sizeof(T)));
 }
 
@@ -264,5 +286,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
 {
-    return fetchAndAddOrdered(valueToAdd);
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndAddRelaxed(
+        reinterpret_cast<void * volatile *>(&_q_value),
+        valueToAdd * sizeof(T)));
 }
 
@@ -270,5 +294,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
 {
-    return fetchAndAddOrdered(valueToAdd);
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndAddAcquire(
+        reinterpret_cast<void * volatile *>(&_q_value),
+        valueToAdd * sizeof(T)));
 }
 
@@ -276,5 +302,7 @@
 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
 {
-    return fetchAndAddOrdered(valueToAdd);
+    return static_cast<T*>(QBasicAtomicPointer_fetchAndAddRelease(
+        reinterpret_cast<void * volatile *>(&_q_value),
+        valueToAdd * sizeof(T)));
 }
 
Index: trunk/src/corelib/arch/sparc/arch.pri
===================================================================
--- trunk/src/corelib/arch/sparc/arch.pri	(revision 766)
+++ trunk/src/corelib/arch/sparc/arch.pri	(revision 769)
@@ -2,5 +2,5 @@
 # SPARC architecture
 #
-*-64 {
+*-64* {
     SOURCES += $$QT_ARCH_CPP/qatomic64.s
 } 
Index: trunk/src/corelib/arch/symbian/qatomic_symbian.cpp
===================================================================
--- trunk/src/corelib/arch/symbian/qatomic_symbian.cpp	(revision 766)
+++ trunk/src/corelib/arch/symbian/qatomic_symbian.cpp	(revision 769)
@@ -42,4 +42,8 @@
 #include <QtCore/qglobal.h>
 #include <QtCore/qatomic.h>
+
+#ifdef SYMBIAN_E32_ATOMIC_API
+#include <e32atomics.h>
+#endif
 
 #include <e32debug.h>
@@ -80,5 +84,5 @@
 Q_CORE_EXPORT bool QBasicAtomicInt::isReferenceCountingNative()
 {
-#ifdef QT_HAVE_ARMV6
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
     return true;
 #else
@@ -89,5 +93,5 @@
 Q_CORE_EXPORT bool QBasicAtomicInt::isTestAndSetNative()
 {
-#ifdef QT_HAVE_ARMV6
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
     return true;
 #else
@@ -98,5 +102,5 @@
 Q_CORE_EXPORT bool QBasicAtomicInt::isFetchAndStoreNative()
 {
-#ifdef QT_HAVE_ARMV6
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
     return true;
 #else
@@ -107,5 +111,5 @@
 Q_CORE_EXPORT bool QBasicAtomicInt::isFetchAndAddNative()
 {
-#ifdef QT_HAVE_ARMV6
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
     return true;
 #else
@@ -116,5 +120,5 @@
 Q_CORE_EXPORT bool QBasicAtomicPointer_isTestAndSetNative()
 {
-#ifdef QT_HAVE_ARMV6
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
     return true;
 #else
@@ -125,5 +129,5 @@
 Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndStoreNative()
 {
-#ifdef QT_HAVE_ARMV6
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
     return true;
 #else
@@ -134,10 +138,184 @@
 Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndAddNative()
 {
-#ifdef QT_HAVE_ARMV6
-    return true;
-#else
-    return false;
-#endif
-}
+#if !defined(SYMBIAN_E32_ATOMIC_API) && defined(QT_HAVE_ARMV6)
+    return true;
+#else
+    return false;
+#endif
+}
+
+#ifdef SYMBIAN_E32_ATOMIC_API
+//Symbian's API is SMP-safe when using SMP kernel, and cheap when using uniprocessor kernel
+
+//generate compiler error if casting assumptions are wrong (symbian64?)
+__ASSERT_COMPILE(sizeof(int) == sizeof(TUint32));
+__ASSERT_COMPILE(sizeof(void *) == sizeof(TUint32));
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_ord32(_q_value,
+        reinterpret_cast<TUint32*>(&expectedValue), newValue));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_rlx32(_q_value,
+        reinterpret_cast<TUint32*>(&expectedValue), newValue));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_acq32(_q_value,
+        reinterpret_cast<TUint32*>(&expectedValue), newValue));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_rel32(_q_value,
+        reinterpret_cast<TUint32*>(&expectedValue), newValue));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
+{
+    return static_cast<int>(__e32_atomic_swp_ord32(_q_value, newValue));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue)
+{
+    return static_cast<int>(__e32_atomic_swp_rlx32(_q_value, newValue));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue)
+{
+    return static_cast<int>(__e32_atomic_swp_acq32(_q_value, newValue));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue)
+{
+    return static_cast<int>(__e32_atomic_swp_rel32(_q_value, newValue));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
+{
+    return static_cast<int>(__e32_atomic_add_ord32(_q_value, valueToAdd));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd)
+{
+    return static_cast<int>(__e32_atomic_add_rlx32(_q_value, valueToAdd));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd)
+{
+    return static_cast<int>(__e32_atomic_add_acq32(_q_value, valueToAdd));
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd)
+{
+    return static_cast<int>(__e32_atomic_add_rel32(_q_value, valueToAdd));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_ord_ptr(_q_value,
+        &expectedValue,
+        newValue));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_rlx_ptr(_q_value,
+        &expectedValue,
+        newValue));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_acq_ptr(_q_value,
+        &expectedValue,
+        newValue));
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return static_cast<bool>(__e32_atomic_cas_rel_ptr(_q_value,
+        &expectedValue,
+        newValue));
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
+{
+    return __e32_atomic_swp_ord_ptr(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue)
+{
+    return __e32_atomic_swp_rlx_ptr(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue)
+{
+    return __e32_atomic_swp_acq_ptr(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue)
+{
+    return __e32_atomic_swp_rel_ptr(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return __e32_atomic_add_ord_ptr(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return __e32_atomic_add_rlx_ptr(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return __e32_atomic_add_acq_ptr(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return __e32_atomic_add_rel_ptr(_q_value, valueToAdd);
+}
+
+#else
+//Symbian kernels 9.4 and earlier don't expose a suitable API
 
 //For ARMv6, the generic atomics are machine coded
@@ -230,5 +408,120 @@
 }
 
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetRelaxed(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return QBasicAtomicInt_testAndSetOrdered(_q_value, expectedValue, newValue);
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetAcquire(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return QBasicAtomicInt_testAndSetOrdered(_q_value, expectedValue, newValue);
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetRelease(volatile int *_q_value, int expectedValue, int newValue)
+{
+    return QBasicAtomicInt_testAndSetOrdered(_q_value, expectedValue, newValue);
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *_q_value, int newValue)
+{
+    return QBasicAtomicInt_fetchAndStoreOrdered(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *_q_value, int newValue)
+{
+    return QBasicAtomicInt_fetchAndStoreOrdered(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreRelease(volatile int *_q_value, int newValue)
+{
+    return QBasicAtomicInt_fetchAndStoreOrdered(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *_q_value, int valueToAdd)
+{
+    return QBasicAtomicInt_fetchAndAddOrdered(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddAcquire(volatile int *_q_value, int valueToAdd)
+{
+    return QBasicAtomicInt_fetchAndAddOrdered(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddRelease(volatile int *_q_value, int valueToAdd)
+{
+    return QBasicAtomicInt_fetchAndAddOrdered(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return QBasicAtomicPointer_testAndSetOrdered(_q_value, expectedValue, newValue);
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return QBasicAtomicPointer_testAndSetOrdered(_q_value, expectedValue, newValue);
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetRelease(void * volatile *_q_value,
+                                           void *expectedValue,
+                                           void *newValue)
+{
+    return QBasicAtomicPointer_testAndSetOrdered(_q_value, expectedValue, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *_q_value, void *newValue)
+{
+    return QBasicAtomicPointer_fetchAndStoreOrdered(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *_q_value, void *newValue)
+{
+    return QBasicAtomicPointer_fetchAndStoreOrdered(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *_q_value, void *newValue)
+{
+    return QBasicAtomicPointer_fetchAndStoreOrdered(_q_value, newValue);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return QBasicAtomicPointer_fetchAndAddOrdered(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return QBasicAtomicPointer_fetchAndAddOrdered(_q_value, valueToAdd);
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddRelease(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+    return QBasicAtomicPointer_fetchAndAddOrdered(_q_value, valueToAdd);
+}
+
 #endif // QT_HAVE_ARMV6
+#endif // SYMBIAN_E32_ATOMIC_API
 
 QT_END_NAMESPACE
Index: trunk/src/corelib/codecs/qiconvcodec.cpp
===================================================================
--- trunk/src/corelib/codecs/qiconvcodec.cpp	(revision 766)
+++ trunk/src/corelib/codecs/qiconvcodec.cpp	(revision 769)
@@ -169,5 +169,5 @@
 {
     if (utf16Codec == reinterpret_cast<QTextCodec *>(~0))
-        return QString::fromAscii(chars, len);
+        return QString::fromLatin1(chars, len);
 
     int invalidCount = 0;
@@ -208,7 +208,7 @@
             if (!reported++) {
                 fprintf(stderr,
-                        "QIconvCodec::convertToUnicode: using ASCII for conversion, iconv_open failed\n");
-            }
-            return QString::fromAscii(chars, len);
+                        "QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_open failed\n");
+            }
+            return QString::fromLatin1(chars, len);
         }
 
@@ -274,5 +274,5 @@
             // some other error
             // note, cannot use qWarning() since we are implementing the codecForLocale :)
-            perror("QIconvCodec::convertToUnicode: using ASCII for conversion, iconv failed");
+            perror("QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv failed");
 
             if (!convState) {
@@ -281,5 +281,5 @@
             }
 
-            return QString::fromAscii(chars, len);
+            return QString::fromLatin1(chars, len);
         }
     } while (inBytesLeft != 0);
@@ -299,4 +299,30 @@
 
 Q_GLOBAL_STATIC(QThreadStorage<QIconvCodec::IconvState *>, fromUnicodeState)
+
+static bool setByteOrder(iconv_t cd)
+{
+#if !defined(NO_BOM)
+    // give iconv() a BOM
+    char buf[4];
+    ushort bom[] = { QChar::ByteOrderMark };
+
+    char *outBytes = buf;
+    char *inBytes = reinterpret_cast<char *>(bom);
+    size_t outBytesLeft = sizeof buf;
+    size_t inBytesLeft = sizeof bom;
+
+#if defined(GNU_LIBICONV)
+    const char **inBytesPtr = const_cast<const char **>(&inBytes);
+#else
+    char **inBytesPtr = &inBytes;
+#endif
+
+    if (iconv(cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) {
+        return false;
+    }
+#endif // NO_BOM
+
+    return true;
+}
 
 QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *convState) const
@@ -326,23 +352,13 @@
     if (!state) {
         state = new IconvState(QIconvCodec::createIconv_t(0, UTF16));
-        if (state->cd != reinterpret_cast<iconv_t>(-1)) {
-            size_t outBytesLeft = len + 3; // +3 for the BOM
-            QByteArray ba(outBytesLeft, Qt::Uninitialized);
-            outBytes = ba.data();
-
-#if !defined(NO_BOM)
-            // give iconv() a BOM
-            QChar bom[] = { QChar(QChar::ByteOrderMark) };
-            inBytes = reinterpret_cast<char *>(bom);
-            inBytesLeft = sizeof(bom);
-            if (iconv(state->cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) {
-                perror("QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv failed for BOM");
+        if (state->cd == reinterpret_cast<iconv_t>(-1)) {
+            if (!setByteOrder(state->cd)) {
+                perror("QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv failed for BOM");
 
                 iconv_close(state->cd);
                 state->cd = reinterpret_cast<iconv_t>(-1);
 
-                return QString(uc, len).toAscii();
-            }
-#endif // NO_BOM
+                return QString(uc, len).toLatin1();
+            }
         }
     }
@@ -351,7 +367,7 @@
         if (!reported++) {
             fprintf(stderr,
-                    "QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv_open failed\n");
-        }
-        return QString(uc, len).toAscii();
+                    "QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open failed\n");
+        }
+        return QString(uc, len).toLatin1();
     }
  
@@ -410,10 +426,10 @@
                 {
                     // note, cannot use qWarning() since we are implementing the codecForLocale :)
-                    perror("QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv failed");
+                    perror("QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv failed");
 
                     // reset to initial state
                     iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
 
-                    return QString(uc, len).toAscii();
+                    return QString(uc, len).toLatin1();
                 }
             }
@@ -423,4 +439,5 @@
     // reset to initial state
     iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
+    setByteOrder(state->cd);
 
     ba.resize(ba.size() - outBytesLeft);
Index: trunk/src/corelib/codecs/qsimplecodec.cpp
===================================================================
--- trunk/src/corelib/codecs/qsimplecodec.cpp	(revision 766)
+++ trunk/src/corelib/codecs/qsimplecodec.cpp	(revision 769)
@@ -682,5 +682,5 @@
     const QChar* ucp = in;
     unsigned char* rp = (unsigned char *)r.data();
-    const unsigned char* rmp = (const unsigned char *)reverseMap->data();
+    const unsigned char* rmp = (const unsigned char *)reverseMap->constData();
     int rmsize = (int) reverseMap->size();
     while(i--)
Index: trunk/src/corelib/codecs/qtextcodec.cpp
===================================================================
--- trunk/src/corelib/codecs/qtextcodec.cpp	(revision 766)
+++ trunk/src/corelib/codecs/qtextcodec.cpp	(revision 769)
@@ -86,5 +86,6 @@
 #endif // QT_NO_CODECS
 #include "qlocale.h"
-#include "private/qmutexpool_p.h"
+#include "qmutex.h"
+#include "qhash.h"
 
 #include <stdlib.h>
@@ -108,4 +109,5 @@
     (QTextCodecFactoryInterface_iid, QLatin1String("/codecs")))
 #endif
+
 
 static char qtolower(register char c)
@@ -179,4 +181,5 @@
 
 static QList<QTextCodec*> *all = 0;
+static int clearCaches = 0;  // flags specifying if caches should be invalided: 0x1 codecForName, 0x2 codecForMib
 #ifdef Q_DEBUG_TEXTCODEC
 static bool destroying_is_ok = false;
@@ -221,4 +224,17 @@
 
 Q_GLOBAL_STATIC(QTextCodecCleanup, createQTextCodecCleanup)
+
+bool QTextCodec::validCodecs()
+{
+#ifdef Q_OS_SYMBIAN
+    // If we don't have a trap handler, we're outside of the main() function,
+    // ie. in global constructors or destructors. Don't use codecs in this
+    // case as it would lead to crashes because we don't have a cleanup stack on Symbian
+    return (User::TrapHandler() != NULL);
+#else
+    return true;
+#endif
+}
+
 
 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
@@ -906,13 +922,21 @@
 }
 
-
+#ifndef QT_NO_THREAD
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, textCodecsMutex, (QMutex::Recursive));
+#endif
+
+// textCodecsMutex need to be locked to enter this function
 static void setup()
 {
-#ifndef QT_NO_THREAD
-    QMutexLocker locker(QMutexPool::globalInstanceGet(&all));
-#endif
-
     if (all)
         return;
+
+#ifdef Q_OS_SYMBIAN
+    // If we don't have a trap handler, we're outside of the main() function,
+    // ie. in global constructors or destructors. Don't create codecs in this
+    // case as it would lead to crashes because of a missing cleanup stack on Symbian
+    if (User::TrapHandler() == NULL)
+        return;
+#endif
 
 #ifdef Q_DEBUG_TEXTCODEC
@@ -1164,6 +1188,4 @@
 
 /*!
-    \nonreentrant
-
     Constructs a QTextCodec, and gives it the highest precedence. The
     QTextCodec should always be constructed on the heap (i.e. with \c
@@ -1173,4 +1195,7 @@
 QTextCodec::QTextCodec()
 {
+#ifndef QT_NO_THREAD
+    QMutexLocker locker(textCodecsMutex());
+#endif
     setup();
     all->prepend(this);
@@ -1190,6 +1215,11 @@
         qWarning("QTextCodec::~QTextCodec: Called by application");
 #endif
-    if (all)
+    if (all) {
+#ifndef QT_NO_THREAD
+        QMutexLocker locker(textCodecsMutex());
+#endif
         all->removeAll(this);
+        clearCaches = 0x1 | 0x2;
+    }
 }
 
@@ -1212,17 +1242,39 @@
         return 0;
 
+#ifndef QT_NO_THREAD
+    QMutexLocker locker(textCodecsMutex());
+#endif
     setup();
+
+    if (!validCodecs())
+        return 0;
+
+    static QHash <QByteArray, QTextCodec *> cache;
+    if (clearCaches & 0x1) {
+        cache.clear();
+        clearCaches &= ~0x1;
+    }
+    QTextCodec *codec = cache.value(name);
+    if (codec)
+        return codec;
 
     for (int i = 0; i < all->size(); ++i) {
         QTextCodec *cursor = all->at(i);
-        if (nameMatch(cursor->name(), name))
+        if (nameMatch(cursor->name(), name)) {
+            cache.insert(name, cursor);
             return cursor;
+        }
         QList<QByteArray> aliases = cursor->aliases();
-        for (int i = 0; i < aliases.size(); ++i)
-            if (nameMatch(aliases.at(i), name))
+        for (int y = 0; y < aliases.size(); ++y)
+            if (nameMatch(aliases.at(y), name)) {
+                cache.insert(name, cursor);
                 return cursor;
-    }
-
-    return createForName(name);
+            }
+    }
+
+    codec = createForName(name);
+    if (codec)
+        cache.insert(name, codec);
+    return codec;
 }
 
@@ -1234,19 +1286,40 @@
 QTextCodec* QTextCodec::codecForMib(int mib)
 {
+#ifndef QT_NO_THREAD
+    QMutexLocker locker(textCodecsMutex());
+#endif
     setup();
 
-    // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map
-    // this correctly for compatibility.
-    if (mib == 1000)
-        mib = 1015;
+    if (!validCodecs())
+        return 0;
+
+    static QHash <int, QTextCodec *> cache;
+    if (clearCaches & 0x2) {
+        cache.clear();
+        clearCaches &= ~0x2;
+    }
+    QTextCodec *codec = cache.value(mib);
+    if (codec)
+        return codec;
 
     QList<QTextCodec*>::ConstIterator i;
     for (int i = 0; i < all->size(); ++i) {
         QTextCodec *cursor = all->at(i);
-        if (cursor->mibEnum() == mib)
+        if (cursor->mibEnum() == mib) {
+            cache.insert(mib, cursor);
             return cursor;
-    }
-
-    return createForMib(mib);
+        }
+    }
+
+    codec = createForMib(mib);
+
+    // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map
+    // this correctly for compatibility.
+    if (!codec && mib == 1000)
+        return codecForMib(1015);
+
+    if (codec)
+        cache.insert(mib, codec);
+    return codec;
 }
 
@@ -1262,11 +1335,23 @@
 QList<QByteArray> QTextCodec::availableCodecs()
 {
+#ifndef QT_NO_THREAD
+    QMutexLocker locker(textCodecsMutex());
+#endif
     setup();
 
     QList<QByteArray> codecs;
+
+    if (!validCodecs())
+        return codecs;
+
     for (int i = 0; i < all->size(); ++i) {
         codecs += all->at(i)->name();
         codecs += all->at(i)->aliases();
     }
+
+#ifndef QT_NO_THREAD
+    locker.unlock();
+#endif
+
 #ifndef QT_NO_TEXTCODECPLUGIN
     QFactoryLoader *l = loader();
@@ -1292,9 +1377,21 @@
 QList<int> QTextCodec::availableMibs()
 {
+#ifndef QT_NO_THREAD
+    QMutexLocker locker(textCodecsMutex());
+#endif
     setup();
 
     QList<int> codecs;
+
+    if (!validCodecs())
+        return codecs;
+
     for (int i = 0; i < all->size(); ++i)
         codecs += all->at(i)->mibEnum();
+
+#ifndef QT_NO_THREAD
+    locker.unlock();
+#endif
+
 #ifndef QT_NO_TEXTCODECPLUGIN
     QFactoryLoader *l = loader();
@@ -1341,7 +1438,13 @@
 QTextCodec* QTextCodec::codecForLocale()
 {
+    if (!validCodecs())
+        return 0;
+
     if (localeMapper)
         return localeMapper;
 
+#ifndef QT_NO_THREAD
+    QMutexLocker locker(textCodecsMutex());
+#endif
     setup();
 
Index: trunk/src/corelib/codecs/qtextcodec.h
===================================================================
--- trunk/src/corelib/codecs/qtextcodec.h	(revision 766)
+++ trunk/src/corelib/codecs/qtextcodec.h	(revision 769)
@@ -146,10 +146,11 @@
     friend class QTextCodecCleanup;
     static QTextCodec *cftr;
+    static bool validCodecs();
 };
 Q_DECLARE_OPERATORS_FOR_FLAGS(QTextCodec::ConversionFlags)
 
-inline QTextCodec* QTextCodec::codecForTr() { return cftr; }
+        inline QTextCodec* QTextCodec::codecForTr() { return validCodecs() ? cftr : 0; }
 inline void QTextCodec::setCodecForTr(QTextCodec *c) { cftr = c; }
-inline QTextCodec* QTextCodec::codecForCStrings() { return QString::codecForCStrings; }
+inline QTextCodec* QTextCodec::codecForCStrings() { return validCodecs() ? QString::codecForCStrings : 0; }
 inline void QTextCodec::setCodecForCStrings(QTextCodec *c) { QString::codecForCStrings = c; }
 
@@ -171,6 +172,8 @@
     friend class QXmlStreamWriter;
     friend class QXmlStreamWriterPrivate;
+#if defined(Q_OS_MAC32) || defined(Q_OS_AIX)
     friend class QCoreXmlStreamWriter;
     friend class QCoreXmlStreamWriterPrivate;
+#endif
 };
 
Index: trunk/src/corelib/codecs/qutfcodec.cpp
===================================================================
--- trunk/src/corelib/codecs/qutfcodec.cpp	(revision 766)
+++ trunk/src/corelib/codecs/qutfcodec.cpp	(revision 769)
@@ -327,9 +327,9 @@
             }
             if (!headerdone) {
+                headerdone = true;
                 if (endian == DetectEndianness) {
-                    if (ch == QChar::ByteOrderSwapped && endian != BigEndianness) {
+                    if (ch == QChar::ByteOrderSwapped) {
                         endian = LittleEndianness;
-                    } else if (ch == QChar::ByteOrderMark && endian != LittleEndianness) {
-                        // ignore BOM
+                    } else if (ch == QChar::ByteOrderMark) {
                         endian = BigEndianness;
                     } else {
@@ -345,5 +345,4 @@
                     *qch++ = ch;
                 }
-                headerdone = true;
             } else {
                 *qch++ = ch;
Index: trunk/src/corelib/concurrent/qfuture.h
===================================================================
--- trunk/src/corelib/concurrent/qfuture.h	(revision 766)
+++ trunk/src/corelib/concurrent/qfuture.h	(revision 769)
@@ -112,5 +112,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
Index: trunk/src/corelib/concurrent/qfuturewatcher.cpp
===================================================================
--- trunk/src/corelib/concurrent/qfuturewatcher.cpp	(revision 766)
+++ trunk/src/corelib/concurrent/qfuturewatcher.cpp	(revision 769)
@@ -500,4 +500,11 @@
 
     Starts watching the given \a future.
+
+    One of the signals might be emitted for the current state of the
+    \a future. For example, if the future is already stopped, the
+    finished signal will be emitted.
+
+    To avoid a race condition, it is important to call this function
+    \i after doing the connections.
 */
 
Index: trunk/src/corelib/corelib.pro
===================================================================
--- trunk/src/corelib/corelib.pro	(revision 766)
+++ trunk/src/corelib/corelib.pro	(revision 769)
@@ -36,3 +36,18 @@
     MMP_RULES -= PAGED
     MMP_RULES *= UNPAGED
+
+    # Partial upgrade SIS file
+    vendorinfo = \
+        "; Localised Vendor name" \
+        "%{\"Nokia, Qt\"}" \
+        " " \
+        "; Unique Vendor name" \
+        ":\"Nokia, Qt\"" \
+        " "
+    pu_header = "; Partial upgrade package for testing QtCore changes without reinstalling everything" \
+                "$${LITERAL_HASH}{\"Qt corelib\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU"
+    partial_upgrade.pkg_prerules = pu_header vendorinfo
+    partial_upgrade.sources = qtcore.dll
+    partial_upgrade.path = c:/sys/bin
+    DEPLOYMENT = partial_upgrade $$DEPLOYMENT
 }
Index: trunk/src/corelib/global/qglobal.cpp
===================================================================
--- trunk/src/corelib/global/qglobal.cpp	(revision 766)
+++ trunk/src/corelib/global/qglobal.cpp	(revision 769)
@@ -1995,5 +1995,4 @@
 }
 
-#ifndef QT_NO_EXCEPTIONS
 /* \internal
    Allows you to throw an exception without including <new>
@@ -2004,5 +2003,4 @@
     QT_THROW(std::bad_alloc());
 }
-#endif
 
 /*
@@ -2077,5 +2075,26 @@
 #endif // Q_CC_MWERKS && Q_OS_MACX
 
-
+#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \
+    defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
+namespace {
+    // There are two incompatible versions of strerror_r:
+    // a) the XSI/POSIX.1 version, which returns an int,
+    //    indicating success or not
+    // b) the GNU version, which returns a char*, which may or may not
+    //    be the beginning of the buffer we used
+    // The GNU libc manpage for strerror_r says you should use the the XSI
+    // version in portable code. However, it's impossible to do that if
+    // _GNU_SOURCE is defined so we use C++ overloading to decide what to do
+    // depending on the return type
+    static inline QString fromstrerror_helper(int, const QByteArray &buf)
+    {
+        return QString::fromLocal8Bit(buf);
+    }
+    static inline QString fromstrerror_helper(const char *str, const QByteArray &)
+    {
+        return QString::fromLocal8Bit(str);
+    }
+}
+#endif
 
 QString qt_error_string(int errorCode)
@@ -2120,10 +2139,7 @@
         if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
             ret = QString::fromLatin1("The specified module could not be found.");
-
 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX)
-
         QByteArray buf(1024, '\0');
-        strerror_r(errorCode, buf.data(), buf.size());
-        ret = QString::fromLocal8Bit(buf.constData());
+        ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
 #else
         ret = QString::fromLocal8Bit(strerror(errorCode));
Index: trunk/src/corelib/global/qglobal.h
===================================================================
--- trunk/src/corelib/global/qglobal.h	(revision 766)
+++ trunk/src/corelib/global/qglobal.h	(revision 769)
@@ -45,9 +45,9 @@
 #include <stddef.h>
 
-#define QT_VERSION_STR "4.6.2"
+#define QT_VERSION_STR "4.6.3"
 /*
    QT_VERSION is (major << 16) + (minor << 8) + patch.
 */
-#define QT_VERSION 0x040602
+#define QT_VERSION 0x040603
 /*
    can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
@@ -55,7 +55,7 @@
 #define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
 
-#define QT_PACKAGEDATE_STR "2010-02-12"
-
-#define QT_PACKAGE_TAG "244b440f11a519bbd0f6a2c5cde90edb1732f2ea"
+#define QT_PACKAGEDATE_STR "2010-06-02"
+
+#define QT_PACKAGE_TAG "76353f177cd84327c692ea31ec644df683643194"
 
 #if !defined(QT_BUILD_MOC)
@@ -813,5 +813,5 @@
 #    endif
 #  elif defined(Q_OS_SYMBIAN)
-#    if (defined(__SERIES60_31__) || defined(__S60_32__) || defined(__S60_50__)) && !defined(QT_NO_S60)
+#    if !defined(QT_NO_S60)
 #      define Q_WS_S60
 #    endif
@@ -1679,8 +1679,5 @@
 
 Q_CORE_EXPORT void qt_check_pointer(const char *, int);
-
-#ifndef QT_NO_EXCEPTIONS
 Q_CORE_EXPORT void qBadAlloc();
-#endif
 
 #ifdef QT_NO_EXCEPTIONS
@@ -2417,14 +2414,16 @@
 #if defined(Q_OS_SYMBIAN)
 
-#ifdef SYMBIAN_GRAPHICS_USE_GCE
-//RWsPointerCursor is fixed, so don't use low performance sprites
-#define Q_SYMBIAN_FIXED_POINTER_CURSORS
+#ifdef SYMBIAN_BUILD_GCE
 #define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+#define Q_SYMBIAN_WINDOW_SIZE_CACHE
+#define QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+
 //enabling new graphics resources
-#define QT_SYMBIAN_SUPPORTS_SGIMAGE
-#define QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+#  define QT_SYMBIAN_SUPPORTS_SGIMAGE
+#endif
 
 #ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
-#define Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+#  define Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
 #endif
 #endif
Index: trunk/src/corelib/global/qnamespace.h
===================================================================
--- trunk/src/corelib/global/qnamespace.h	(revision 766)
+++ trunk/src/corelib/global/qnamespace.h	(revision 769)
@@ -300,5 +300,7 @@
         BypassGraphicsProxyWidget = 0x20000000,
         WindowOkButtonHint = 0x00080000,
-        WindowCancelButtonHint = 0x00100000
+        WindowCancelButtonHint = 0x00100000,
+        WindowSoftkeysVisibleHint = 0x40000000,
+        WindowSoftkeysRespondHint = 0x80000000
 
 #ifdef QT3_SUPPORT
Index: trunk/src/corelib/global/qnamespace.qdoc
===================================================================
--- trunk/src/corelib/global/qnamespace.qdoc	(revision 766)
+++ trunk/src/corelib/global/qnamespace.qdoc	(revision 769)
@@ -158,5 +158,5 @@
     \value AA_MacDontSwapCtrlAndMeta On Mac OS X by default, Qt swaps the
            Control and Meta (Command) keys (i.e., whenever Control is pressed, Qt
-           sends Meta and whenever Meta is pressed Control is sent. When this
+           sends Meta, and whenever Meta is pressed Control is sent). When this
            attribute is true, Qt will not do the flip. QKeySequence::StandardShortcuts
            will also flip accordingly (i.e., QKeySequence::Copy will be
@@ -494,5 +494,5 @@
     \omitvalue TextForceLeftToRight
     \omitvalue TextForceRightToLeft
-    \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string
+    \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string.
 
     You can use as many modifier flags as you want, except that
@@ -1623,20 +1623,20 @@
     \value Key_LaunchMail
     \value Key_LaunchMedia
-    \value Key_Launch0
-    \value Key_Launch1
-    \value Key_Launch2
-    \value Key_Launch3
-    \value Key_Launch4
-    \value Key_Launch5
-    \value Key_Launch6
-    \value Key_Launch7
-    \value Key_Launch8
-    \value Key_Launch9
-    \value Key_LaunchA
-    \value Key_LaunchB
-    \value Key_LaunchC
-    \value Key_LaunchD
-    \value Key_LaunchE
-    \value Key_LaunchF
+    \value Key_Launch0 On X11 this key is mapped to "My Computer" (XF86XK_MyComputer) key for legacy reasons.
+    \value Key_Launch1 On X11 this key is mapped to "Calculator" (XF86XK_Calculator) key for legacy reasons.
+    \value Key_Launch2 On X11 this key is mapped to XF86XK_Launch0 key for legacy reasons.
+    \value Key_Launch3 On X11 this key is mapped to XF86XK_Launch1 key for legacy reasons.
+    \value Key_Launch4 On X11 this key is mapped to XF86XK_Launch2 key for legacy reasons.
+    \value Key_Launch5 On X11 this key is mapped to XF86XK_Launch3 key for legacy reasons.
+    \value Key_Launch6 On X11 this key is mapped to XF86XK_Launch4 key for legacy reasons.
+    \value Key_Launch7 On X11 this key is mapped to XF86XK_Launch5 key for legacy reasons.
+    \value Key_Launch8 On X11 this key is mapped to XF86XK_Launch6 key for legacy reasons.
+    \value Key_Launch9 On X11 this key is mapped to XF86XK_Launch7 key for legacy reasons.
+    \value Key_LaunchA On X11 this key is mapped to XF86XK_Launch8 key for legacy reasons.
+    \value Key_LaunchB On X11 this key is mapped to XF86XK_Launch9 key for legacy reasons.
+    \value Key_LaunchC On X11 this key is mapped to XF86XK_LaunchA key for legacy reasons.
+    \value Key_LaunchD On X11 this key is mapped to XF86XK_LaunchB key for legacy reasons.
+    \value Key_LaunchE On X11 this key is mapped to XF86XK_LaunchC key for legacy reasons.
+    \value Key_LaunchF On X11 this key is mapped to XF86XK_LaunchD key for legacy reasons.
     \value Key_MonBrightnessUp
     \value Key_MonBrightnessDown
@@ -1664,5 +1664,5 @@
     \value Key_Book
     \value Key_CD
-    \value Key_Calculator
+    \value Key_Calculator On X11 this key is not mapped for legacy reasons. Use Qt::Key_Launch1 instead.
     \value Key_ToDoList
     \value Key_ClearGrab
@@ -2116,5 +2116,5 @@
 
     \value MacWindowToolBarButtonHint On Mac OS X adds a tool bar button (i.e.,
-           the oblong button that is on the top right of windows that have toolbars.
+           the oblong button that is on the top right of windows that have toolbars).
 
     \value BypassGraphicsProxyWidget Prevents the window and its children from
@@ -2146,4 +2146,12 @@
     \value WindowCancelButtonHint Adds a Cancel button to the window decoration of a dialog.
            Only supported for Windows CE.
+
+    \value WindowSoftkeysVisibleHint Makes softkeys visible when widget is fullscreen.
+           Only supported for Symbian.
+
+    \value WindowSoftkeysRespondHint Makes softkeys to receive key events even
+           when invisible. With this hint the softkey actions are triggered
+           even the softkeys are invisible i.e. the window is displayed with
+           \c showFullscreen(). Only supported for Symbian.
 
     \value WindowType_Mask  A mask for extracting the window type
Index: trunk/src/corelib/io/qdatastream.cpp
===================================================================
--- trunk/src/corelib/io/qdatastream.cpp	(revision 766)
+++ trunk/src/corelib/io/qdatastream.cpp	(revision 769)
@@ -157,4 +157,10 @@
     the data (apart from the length quint32) must be done by you.
 
+    \section1 Reading and writing Qt collection classes
+
+    The Qt container classes can also be serialized to a QDataStream.
+    These include QList, QLinkedList, QVector, QSet, QHash, and QMap.
+    The stream operators are declared as non-members of the classes.
+
     \target Serializing Qt Classes
     \section1 Reading and writing other Qt classes.
Index: trunk/src/corelib/io/qdir.cpp
===================================================================
--- trunk/src/corelib/io/qdir.cpp	(revision 766)
+++ trunk/src/corelib/io/qdir.cpp	(revision 769)
@@ -1050,13 +1050,13 @@
 /*!
     \obsolete
+
+    Use QDir::addSearchPath() with a prefix instead.
+
     Adds \a path to the search paths searched in to find resources
     that are not specified with an absolute path. The default search
     path is to search only in the root (\c{:/}).
 
-    Use QDir::addSearchPath() with a prefix instead.
-
-    \sa {The Qt Resource System}, QResource::addSearchPath()
-*/
-
+    \sa {The Qt Resource System}
+*/
 void QDir::addResourceSearchPath(const QString &path)
 {
Index: trunk/src/corelib/io/qfile.cpp
===================================================================
--- trunk/src/corelib/io/qfile.cpp	(revision 766)
+++ trunk/src/corelib/io/qfile.cpp	(revision 769)
@@ -63,9 +63,11 @@
 static QByteArray locale_encode(const QString &f)
 {
-#ifndef Q_OS_DARWIN
-    return f.toLocal8Bit();
-#else
+#if defined(Q_OS_DARWIN)
     // Mac always expects UTF-8... and decomposed...
     return f.normalized(QString::NormalizationForm_D).toUtf8();
+#elif defined(Q_OS_SYMBIAN)
+    return f.toUtf8();
+#else
+    return f.toLocal8Bit();
 #endif
 }
@@ -73,9 +75,11 @@
 static QString locale_decode(const QByteArray &f)
 {
-#ifndef Q_OS_DARWIN
-    return QString::fromLocal8Bit(f);
-#else
+#if defined(Q_OS_DARWIN)
     // Mac always gives us UTF-8 and decomposed, we want that composed...
     return QString::fromUtf8(f).normalized(QString::NormalizationForm_C);
+#elif defined(Q_OS_SYMBIAN)
+    return QString::fromUtf8(f);
+#else
+    return QString::fromLocal8Bit(f);
 #endif
 }
@@ -87,5 +91,6 @@
 QFilePrivate::QFilePrivate()
     : fileEngine(0), lastWasWrite(false),
-      writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError)
+      writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
+      cachedSize(0)
 {
 }
@@ -1257,6 +1262,8 @@
     if(d->fileEngine->setSize(sz)) {
         unsetError();
+        d->cachedSize = sz;
         return true;
     }
+    d->cachedSize = 0;
     d->setError(QFile::ResizeError, d->fileEngine->errorString());
     return false;
@@ -1420,5 +1427,6 @@
     if (!d->ensureFlushed())
         return 0;
-    return fileEngine()->size();
+    d->cachedSize = fileEngine()->size();
+    return d->cachedSize;
 }
 
@@ -1446,12 +1454,12 @@
     Q_D(const QFile);
 
+    // If there's buffered data left, we're not at the end.
+    if (!d->buffer.isEmpty())
+        return false;
+
     if (!isOpen())
         return true;
 
     if (!d->ensureFlushed())
-        return false;
-
-    // If there's buffered data left, we're not at the end.
-    if (!d->buffer.isEmpty())
         return false;
 
@@ -1463,4 +1471,9 @@
     }
 
+    // if it looks like we are at the end, or if size is not cached,
+    // fall through to bytesAvailable() to make sure.
+    if (pos() < d->cachedSize)
+        return false;
+
     // Fall back to checking how much is available (will stat files).
     return bytesAvailable() == 0;
@@ -1502,10 +1515,19 @@
         return -1;
 
-    if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
-        return d->fileEngine->readLine(data, maxlen);
-
-    // Fall back to QIODevice's readLine implementation if the engine
-    // cannot do it faster.
-    return QIODevice::readLineData(data, maxlen);
+    qint64 read;
+    if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
+        read = d->fileEngine->readLine(data, maxlen);
+    } else {
+        // Fall back to QIODevice's readLine implementation if the engine
+        // cannot do it faster.
+        read = QIODevice::readLineData(data, maxlen);
+    }
+
+    if (read < maxlen) {
+        // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
+        d->cachedSize = 0;
+    }
+
+    return read;
 }
 
@@ -1528,4 +1550,10 @@
         d->setError(err, d->fileEngine->errorString());
     }
+
+    if (read < len) {
+        // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
+        d->cachedSize = 0;
+    }
+
     return read;
 }
Index: trunk/src/corelib/io/qfile_p.h
===================================================================
--- trunk/src/corelib/io/qfile_p.h	(revision 766)
+++ trunk/src/corelib/io/qfile_p.h	(revision 769)
@@ -85,4 +85,6 @@
     void setError(QFile::FileError err, int errNum);
 
+    mutable qint64 cachedSize;
+
 private:
     static QFile::EncoderFn encoder;
Index: trunk/src/corelib/io/qfilesystemwatcher_kqueue.cpp
===================================================================
--- trunk/src/corelib/io/qfilesystemwatcher_kqueue.cpp	(revision 766)
+++ trunk/src/corelib/io/qfilesystemwatcher_kqueue.cpp	(revision 769)
@@ -261,10 +261,20 @@
             DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter;
             if (fd == kqpipe[0]) {
-                char c;
-                if (read(kqpipe[0], &c, 1) != 1) {
+                // read all pending data from the pipe
+                QByteArray ba;
+                ba.resize(kev.data);
+                if (read(kqpipe[0], ba.data(), ba.size()) != ba.size()) {
                     perror("QKqueueFileSystemWatcherEngine: error reading from pipe");
                     return;
                 }
-                switch (c) {
+                // read the command from the buffer (but break and return on 'q')
+                char cmd = 0;
+                for (int i = 0; i < ba.size(); ++i) {
+                    cmd = ba.constData()[i];
+                    if (cmd == 'q')
+                        break;
+                }
+                // handle the command
+                switch (cmd) {
                 case 'q':
                     DEBUG() << "QKqueueFileSystemWatcherEngine: thread received 'q', exiting...";
@@ -274,5 +284,5 @@
                     break;
                 default:
-                    DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << c;
+                    DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << cmd;
                     break;
                 }
Index: trunk/src/corelib/io/qfsfileengine.cpp
===================================================================
--- trunk/src/corelib/io/qfsfileengine.cpp	(revision 766)
+++ trunk/src/corelib/io/qfsfileengine.cpp	(revision 769)
@@ -146,4 +146,6 @@
     // Mac OS X 10.5.x doesn't support the realpath(X,0) extenstion we use here.
 #if defined(Q_OS_LINUX) || defined(Q_OS_SYMBIAN)
+    // ... but Linux with uClibc does not have it
+#if !defined(__UCLIBC__)
     char *ret = realpath(path.toLocal8Bit().constData(), (char*)0);
     if (ret) {
@@ -152,4 +154,5 @@
         return canonicalPath;
     }
+#endif
 #endif
 
Index: trunk/src/corelib/io/qfsfileengine_p.h
===================================================================
--- trunk/src/corelib/io/qfsfileengine_p.h	(revision 766)
+++ trunk/src/corelib/io/qfsfileengine_p.h	(revision 769)
@@ -152,4 +152,8 @@
 #endif
 
+#ifdef Q_OS_SYMBIAN
+    void setSymbianError(int symbianError, QFile::FileError defaultError, QString defaultString);
+#endif
+
 protected:
     QFSFileEnginePrivate();
Index: trunk/src/corelib/io/qfsfileengine_unix.cpp
===================================================================
--- trunk/src/corelib/io/qfsfileengine_unix.cpp	(revision 766)
+++ trunk/src/corelib/io/qfsfileengine_unix.cpp	(revision 769)
@@ -82,4 +82,38 @@
              || (fileName.at(0) == QLatin1Char('/') && fileName.at(1) == QLatin1Char('/')))));
 }
+
+/*!
+ \internal
+ convert symbian error code to the one suitable for setError.
+ example usage: setSymbianError(err, QFile::CopyError, QLatin1String("copy error"))
+*/
+void QFSFileEnginePrivate::setSymbianError(int symbianError, QFile::FileError defaultError, QString defaultString)
+{
+    Q_Q(QFSFileEngine);
+    switch (symbianError) {
+    case KErrNone:
+        q->setError(QFile::NoError, QLatin1String(""));
+        break;
+    case KErrAccessDenied:
+        q->setError(QFile::PermissionsError, QLatin1String("access denied"));
+        break;
+    case KErrPermissionDenied:
+        q->setError(QFile::PermissionsError, QLatin1String("permission denied"));
+        break;
+    case KErrAbort:
+        q->setError(QFile::AbortError, QLatin1String("aborted"));
+        break;
+    case KErrCancel:
+        q->setError(QFile::AbortError, QLatin1String("cancelled"));
+        break;
+    case KErrTimedOut:
+        q->setError(QFile::TimeOutError, QLatin1String("timed out"));
+        break;
+    default:
+        q->setError(defaultError, defaultString);
+        break;
+    }
+}
+
 #endif
 
@@ -99,5 +133,5 @@
                 && QT_STAT(QFile::encodeName(fileName), &statBuf) == 0
                 && (statBuf.st_mode & S_IFMT) == S_IFREG) {
-                mode += "+";
+                mode += '+';
             } else {
                 mode = "wb+";
@@ -428,6 +462,8 @@
     ) // End TRAP
     delete fm;
-    // ### Add error reporting on failure
-    return (err == KErrNone);
+    if (err == KErrNone)
+        return true;
+    d->setSymbianError(err, QFile::CopyError, QLatin1String("copy error"));
+    return false;
 #else
     Q_UNUSED(newName);
@@ -669,4 +705,14 @@
         } else if (fd == -1) {
             // ### actually covers two cases: d->fh and when the file is not open
+#if defined(Q_OS_SYMBIAN)
+            // Optimisation for Symbian where fileFlags() calls both doStat() and isSymlink(), but rarely on real links.
+            // When the filename is not a link, lstat will return the same info as stat, but this also removes
+            // any need for a further call to lstat to check if the file is a link.
+            need_lstat = false;
+            could_stat = (QT_LSTAT(nativeFilePath.constData(), &st) == 0);
+            is_link = could_stat ? S_ISLNK(st.st_mode) : false;
+            // if it turns out this was a link, we can call stat too.
+            if (is_link)
+#endif
             could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0);
         } else {
@@ -1271,5 +1317,5 @@
     int extra = offset % pageSize;
 
-    if (size + extra > (size_t)-1) {
+    if (quint64(size + extra) > quint64((size_t)-1)) {
         q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
         return 0;
Index: trunk/src/corelib/io/qfsfileengine_win.cpp
===================================================================
--- trunk/src/corelib/io/qfsfileengine_win.cpp	(revision 766)
+++ trunk/src/corelib/io/qfsfileengine_win.cpp	(revision 769)
@@ -1485,5 +1485,5 @@
         //### what to do with permissions if we don't use NTFS
         // for now just add all permissions and what about exe missions ??
-        // also qt_ntfs_permission_lookup is now not set by defualt ... should it ?
+        // also qt_ntfs_permission_lookup is now not set by default ... should it ?
         ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm
             | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm
Index: trunk/src/corelib/io/qiodevice.cpp
===================================================================
--- trunk/src/corelib/io/qiodevice.cpp	(revision 766)
+++ trunk/src/corelib/io/qiodevice.cpp	(revision 769)
@@ -85,8 +85,4 @@
 #endif
 
-#ifndef QIODEVICE_BUFFERSIZE
-#define QIODEVICE_BUFFERSIZE Q_INT64_C(16384)
-#endif
-
 #define Q_VOID
 
@@ -124,5 +120,7 @@
     : openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE),
       pos(0), devicePos(0)
+       , pPos(&pos), pDevicePos(&devicePos)
        , baseReadLineDataCalled(false)
+       , firstRead(true)
        , accessMode(Unset)
 #ifdef QT_NO_QOBJECT
@@ -283,6 +281,5 @@
     meaningless when used with some subclasses. Some of these
     restrictions are implied by the type of device that is represented
-    by a subclass; for example, access to a QBuffer is always
-    unbuffered. In other cases, the restriction may be due to the
+    by a subclass. In other cases, the restriction may be due to the
     implementation, or may be imposed by the underlying platform; for
     example, QTcpSocket does not support \c Unbuffered mode, and
@@ -451,9 +448,13 @@
 void QIODevice::setOpenMode(OpenMode openMode)
 {
+    Q_D(QIODevice);
 #if defined QIODEVICE_DEBUG
     printf("%p QIODevice::setOpenMode(0x%x)\n", this, int(openMode));
 #endif
-    d_func()->openMode = openMode;
-    d_func()->accessMode = QIODevicePrivate::Unset;
+    d->openMode = openMode;
+    d->accessMode = QIODevicePrivate::Unset;
+    d->firstRead = true;
+    if (!isReadable())
+        d->buffer.clear();
 }
 
@@ -539,4 +540,5 @@
     d->buffer.clear();
     d->accessMode = QIODevicePrivate::Unset;
+    d->firstRead = true;
 #if defined QIODEVICE_DEBUG
     printf("%p QIODevice::open(0x%x)\n", this, quint32(mode));
@@ -568,4 +570,5 @@
     d->pos = 0;
     d->buffer.clear();
+    d->firstRead = true;
 }
 
@@ -731,4 +734,10 @@
 }
 
+#ifdef Q_CC_RVCT
+// arm mode makes the 64-bit integer operations much faster in RVCT 2.2
+#pragma push
+#pragma arm
+#endif
+
 /*!
     Reads at most \a maxSize bytes from the device into \a data, and
@@ -747,6 +756,4 @@
 {
     Q_D(QIODevice);
-    CHECK_READABLE(read, qint64(-1));
-    CHECK_MAXLEN(read, qint64(-1));
 
 #if defined QIODEVICE_DEBUG
@@ -754,5 +761,4 @@
            this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
 #endif
-    const bool sequential = d->isSequential();
 
     // Short circuit for getChar()
@@ -760,6 +766,5 @@
         int chint;
         while ((chint = d->buffer.getChar()) != -1) {
-            if (!sequential)
-                ++d->pos;
+            ++(*d->pPos);
 
             char c = char(uchar(chint));
@@ -775,49 +780,68 @@
     }
 
+    CHECK_MAXLEN(read, qint64(-1));
     qint64 readSoFar = 0;
     bool moreToRead = true;
     do {
-        int lastReadChunkSize = 0;
-
         // Try reading from the buffer.
-        if (!d->buffer.isEmpty()) {
-            lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
+        int lastReadChunkSize = d->buffer.read(data, maxSize);
+        if (lastReadChunkSize > 0) {
+            *d->pPos += lastReadChunkSize;
             readSoFar += lastReadChunkSize;
-            if (!sequential)
-                d->pos += lastReadChunkSize;
+            // fast exit when satisfied by buffer
+            if (lastReadChunkSize == maxSize && !(d->openMode & Text))
+                return readSoFar;
+
+            data += lastReadChunkSize;
+            maxSize -= lastReadChunkSize;
 #if defined QIODEVICE_DEBUG
             printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
                    int(readSoFar) - lastReadChunkSize);
 #endif
-        } else if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
-            // In buffered mode, we try to fill up the QIODevice buffer before
-            // we do anything else.
-            int bytesToBuffer = qMax(maxSize - readSoFar, QIODEVICE_BUFFERSIZE);
-            char *writePointer = d->buffer.reserve(bytesToBuffer);
-
-            // Make sure the device is positioned correctly.
-            if (d->pos != d->devicePos && !sequential && !seek(d->pos))
-                return qint64(-1);
-            qint64 readFromDevice = readData(writePointer, bytesToBuffer);
-            d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));
-
-            if (readFromDevice > 0) {
-                if (!sequential)
-                    d->devicePos += readFromDevice;
-#if defined QIODEVICE_DEBUG
-                printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
-#endif
-
-                if (readFromDevice < bytesToBuffer)
-                    d->buffer.truncate(int(readFromDevice));
-                if (!d->buffer.isEmpty()) {
-                    lastReadChunkSize = d->buffer.read(data + readSoFar, maxSize - readSoFar);
-                    readSoFar += lastReadChunkSize;
-                    if (!sequential)
-                        d->pos += lastReadChunkSize;
-#if defined QIODEVICE_DEBUG
-                    printf("%p \treading %d bytes from buffer at position %d\n", this,
-                           lastReadChunkSize, int(readSoFar));
-#endif
+        } else {
+            if (d->firstRead) {
+                // this is the first time the file has been read, check it's valid and set up pos pointers
+                // for fast pos updates.
+                CHECK_READABLE(read, qint64(-1));
+                d->firstRead = false;
+                if (d->isSequential()) {
+                    d->pPos = &d->seqDumpPos;
+                    d->pDevicePos = &d->seqDumpPos;
+                }
+            }
+
+            if (!maxSize)
+                return readSoFar;
+
+            if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
+                // In buffered mode, we try to fill up the QIODevice buffer before
+                // we do anything else.
+                // buffer is empty at this point, try to fill it
+                int bytesToBuffer = QIODEVICE_BUFFERSIZE;
+                char *writePointer = d->buffer.reserve(bytesToBuffer);
+
+                // Make sure the device is positioned correctly.
+                if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
+                    return readSoFar ? readSoFar : qint64(-1);
+                qint64 readFromDevice = readData(writePointer, bytesToBuffer);
+                d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));
+
+                if (readFromDevice > 0) {
+                    *d->pDevicePos += readFromDevice;
+#if defined QIODEVICE_DEBUG
+                    printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
+#endif
+
+                    if (!d->buffer.isEmpty()) {
+                        lastReadChunkSize = d->buffer.read(data, maxSize);
+                        readSoFar += lastReadChunkSize;
+                        data += lastReadChunkSize;
+                        maxSize -= lastReadChunkSize;
+                        *d->pPos += lastReadChunkSize;
+#if defined QIODEVICE_DEBUG
+                        printf("%p \treading %d bytes from buffer at position %d\n", this,
+                               lastReadChunkSize, int(readSoFar));
+#endif
+                    }
                 }
             }
@@ -825,9 +849,9 @@
 
         // If we need more, try reading from the device.
-        if (readSoFar < maxSize) {
+        if (maxSize > 0) {
             // Make sure the device is positioned correctly.
-            if (d->pos != d->devicePos && !sequential && !seek(d->pos))
-                return qint64(-1);
-            qint64 readFromDevice = readData(data + readSoFar, maxSize - readSoFar);
+            if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
+                return readSoFar ? readSoFar : qint64(-1);
+            qint64 readFromDevice = readData(data, maxSize);
 #if defined QIODEVICE_DEBUG
             printf("%p \treading %d bytes from device (total %d)\n", this, int(readFromDevice), int(readSoFar));
@@ -837,25 +861,19 @@
                 return -1;
             }
-            if (readFromDevice <= 0) {
-                moreToRead = false;
-            } else {
-                // see if we read as much data as we asked for
-                if (readFromDevice < maxSize - readSoFar)
-                    moreToRead = false;
-
+            if (readFromDevice > 0) {
                 lastReadChunkSize += int(readFromDevice);
                 readSoFar += readFromDevice;
-                if (!sequential) {
-                    d->pos += readFromDevice;
-                    d->devicePos += readFromDevice;
-                }
+                data += readFromDevice;
+                maxSize -= readFromDevice;
+                *d->pPos += readFromDevice;
+                *d->pDevicePos += readFromDevice;
             }
-        } else {
-            moreToRead = false;
         }
+        // Best attempt has been made to read data, don't try again except for text mode adjustment below
+        moreToRead = false;
 
         if (readSoFar && d->openMode & Text) {
-            char *readPtr = data + readSoFar - lastReadChunkSize;
-            const char *endPtr = data + readSoFar;
+            char *readPtr = data - lastReadChunkSize;
+            const char *endPtr = data;
 
             if (readPtr < endPtr) {
@@ -872,6 +890,9 @@
                     if (ch != '\r')
                         *writePtr++ = ch;
-                    else
+                    else {
                         --readSoFar;
+                        --data;
+                        ++maxSize;
+                    }
                 }
 
@@ -887,8 +908,12 @@
     printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this,
            int(readSoFar), int(d->pos), d->buffer.size());
-    debugBinaryString(data, readSoFar);
+    debugBinaryString(data - readSoFar, readSoFar);
 #endif
     return readSoFar;
 }
+
+#ifdef Q_CC_RVCT
+#pragma pop
+#endif
 
 /*!
@@ -999,4 +1024,10 @@
 }
 
+#ifdef Q_CC_RVCT
+// arm mode makes the 64-bit integer operations much faster in RVCT 2.2
+#pragma push
+#pragma arm
+#endif
+
 /*!
     This function reads a line of ASCII characters from the device, up
@@ -1004,6 +1035,6 @@
     data, and returns the number of bytes read. If a line could not be
     read but no error ocurred, this function returns 0. If an error
-    occurs, this function returns what it could the length of what
-    could be read, or -1 if nothing was read.
+    occurs, this function returns the length of what could be read, or
+    -1 if nothing was read.
 
     A terminating '\0' byte is always appended to \a data, so \a
@@ -1230,4 +1261,8 @@
     return readSoFar;
 }
+
+#ifdef Q_CC_RVCT
+#pragma pop
+#endif
 
 /*!
@@ -1418,7 +1453,5 @@
 bool QIODevice::getChar(char *c)
 {
-    Q_D(QIODevice);
-    CHECK_READABLE(getChar, false);
-
+    // readability checked in read()
     char ch;
     return (1 == read(c ? c : &ch, 1));
Index: trunk/src/corelib/io/qiodevice_p.h
===================================================================
--- trunk/src/corelib/io/qiodevice_p.h	(revision 766)
+++ trunk/src/corelib/io/qiodevice_p.h	(revision 769)
@@ -65,4 +65,124 @@
 QT_BEGIN_NAMESPACE
 
+#ifndef QIODEVICE_BUFFERSIZE
+#define QIODEVICE_BUFFERSIZE Q_INT64_C(16384)
+#endif
+
+// This is QIODevice's read buffer, optimised for read(), isEmpty() and getChar()
+class QIODevicePrivateLinearBuffer
+{
+public:
+    QIODevicePrivateLinearBuffer(int) : len(0), first(0), buf(0), capacity(0) {
+    }
+    ~QIODevicePrivateLinearBuffer() {
+        delete [] buf;
+    }
+    void clear() {
+        first = buf;
+        len = 0;
+    }
+    int size() const {
+        return len;
+    }
+    bool isEmpty() const {
+        return len == 0;
+    }
+    void skip(int n) {
+        if (n >= len) {
+            clear();
+        } else {
+            len -= n;
+            first += n;
+        }
+    }
+    int getChar() {
+        if (len == 0)
+            return -1;
+        int ch = uchar(*first);
+        len--;
+        first++;
+        return ch;
+    }
+    int read(char* target, int size) {
+        int r = qMin(size, len);
+        memcpy(target, first, r);
+        len -= r;
+        first += r;
+        return r;
+    }
+    char* reserve(int size) {
+        makeSpace(size + len, freeSpaceAtEnd);
+        char* writePtr = first + len;
+        len += size;
+        return writePtr;
+    }
+    void chop(int size) {
+        if (size >= len) {
+            clear();
+        } else {
+            len -= size;
+        }
+    }
+    QByteArray readAll() {
+        char* f = first;
+        int l = len;
+        clear();
+        return QByteArray(f, l);
+    }
+    int readLine(char* target, int size) {
+        int r = qMin(size, len);
+        char* eol = static_cast<char*>(memchr(first, '\n', r));
+        if (eol)
+            r = 1+(eol-first);
+        memcpy(target, first, r);
+        len -= r;
+        first += r;
+        return int(r);
+        }
+    bool canReadLine() const {
+        return memchr(first, '\n', len);
+    }
+    void ungetChar(char c) {
+        if (first == buf) {
+            // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer
+            makeSpace(len+1, freeSpaceAtStart);
+        }
+        first--;
+        len++;
+        *first = c;
+    }
+
+private:
+    enum FreeSpacePos {freeSpaceAtStart, freeSpaceAtEnd};
+    void makeSpace(size_t required, FreeSpacePos where) {
+        size_t newCapacity = qMax(capacity, size_t(QIODEVICE_BUFFERSIZE));
+        while (newCapacity < required)
+            newCapacity *= 2;
+        int moveOffset = (where == freeSpaceAtEnd) ? 0 : newCapacity - len;
+        if (newCapacity > capacity) {
+            // allocate more space
+            char* newBuf = new char[newCapacity];
+            memmove(newBuf + moveOffset, first, len);
+            delete [] buf;
+            buf = newBuf;
+            capacity = newCapacity;
+        } else {
+            // shift any existing data to make space
+            memmove(buf + moveOffset, first, len);
+        }
+        first = buf + moveOffset;
+    }
+
+private:
+    // length of the unread data
+    int len;
+    // start of the unread data
+    char* first;
+    // the allocated buffer
+    char* buf;
+    // allocated buffer size
+    size_t capacity;
+};
+
 class Q_CORE_EXPORT QIODevicePrivate
 #ifndef QT_NO_QOBJECT
@@ -79,8 +199,13 @@
     QString errorString;
 
-    QRingBuffer buffer;
+    QIODevicePrivateLinearBuffer buffer;
     qint64 pos;
     qint64 devicePos;
+    // these three are for fast position updates during read, avoiding isSequential test
+    qint64 seqDumpPos;
+    qint64 *pPos;
+    qint64 *pDevicePos;
     bool baseReadLineDataCalled;
+    bool firstRead;
 
     virtual bool putCharHelper(char c);
Index: trunk/src/corelib/io/qprocess.cpp
===================================================================
--- trunk/src/corelib/io/qprocess.cpp	(revision 766)
+++ trunk/src/corelib/io/qprocess.cpp	(revision 769)
@@ -552,4 +552,14 @@
     the interpreter to execute the desired command.
 
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use the functions kill() or terminate()
+    must have the \c PowerMgmt platform security capability. If the client
+    process lacks this capability, these functions will fail.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
+
     \sa QBuffer, QFile, QTcpSocket
 */
@@ -2030,7 +2040,11 @@
     calling kill().
 
+    On Symbian, this function requires platform security capability
+    \c PowerMgmt. If absent, the process will panic with KERN-EXEC 46.
+
     \note Terminating running processes from other processes will typically
     cause a panic in Symbian due to platform security.
 
+    \sa \l {Symbian Platform Security Requirements}
     \sa kill()
 */
@@ -2047,4 +2061,8 @@
     SIGKILL signal is sent to the process.
 
+    On Symbian, this function requires platform security capability
+    \c PowerMgmt. If absent, the process will panic with KERN-EXEC 46.
+
+    \sa \l {Symbian Platform Security Requirements}
     \sa terminate()
 */
Index: trunk/src/corelib/io/qprocess_symbian.cpp
===================================================================
--- trunk/src/corelib/io/qprocess_symbian.cpp	(revision 766)
+++ trunk/src/corelib/io/qprocess_symbian.cpp	(revision 769)
@@ -238,9 +238,13 @@
                 endQuote += QLatin1String("\\");
             }
-            commandLine += QLatin1String(" \"") + tmp.left(i) + endQuote;
+            commandLine += QLatin1String("\"") + tmp.left(i) + endQuote + QLatin1Char(' ');
         } else {
-            commandLine += QLatin1Char(' ') + tmp;
+            commandLine += tmp + QLatin1Char(' ');
         }
     }
+
+    // Chop the extra trailing space if any arguments were appended
+    if (arguments.size())
+        commandLine.chop(1);
 }
 
@@ -372,4 +376,5 @@
 QProcessActive::~QProcessActive()
 {
+    Cancel();
     process = NULL;
     pproc = NULL;
@@ -478,4 +483,5 @@
 QProcessManagerMediator::~QProcessManagerMediator()
 {
+    Cancel();
     processManagerThread.Close();
     currentCommand = ENoCommand;
Index: trunk/src/corelib/io/qprocess_unix.cpp
===================================================================
--- trunk/src/corelib/io/qprocess_unix.cpp	(revision 766)
+++ trunk/src/corelib/io/qprocess_unix.cpp	(revision 769)
@@ -784,5 +784,5 @@
     // did we read an error message?
     if (i > 0)
-        q_func()->setErrorString(QString::fromUtf16(buf, i / sizeof(QChar)));
+        q_func()->setErrorString(QString((const QChar *)buf, i / sizeof(QChar)));
 
     return i <= 0;
Index: trunk/src/corelib/io/qresource.cpp
===================================================================
--- trunk/src/corelib/io/qresource.cpp	(revision 766)
+++ trunk/src/corelib/io/qresource.cpp	(revision 769)
@@ -556,4 +556,6 @@
   \obsolete
 
+  Use QDir::addSearchPath() with a prefix instead.
+
   Adds \a path to the search paths searched in to find resources that are
   not specified with an absolute path. The \a path must be an absolute
@@ -562,8 +564,5 @@
   The default search path is to search only in the root (\c{:/}). The last
   path added will be consulted first upon next QResource creation.
-
-  Use QDir::addSearchPath() with a prefix instead.
-*/
-
+*/
 void
 QResource::addSearchPath(const QString &path)
@@ -579,4 +578,8 @@
 
 /*!
+  \obsolete
+
+  Use QDir::searchPaths() instead.
+  
   Returns the current search path list. This list is consulted when
   creating a relative resource.
Index: trunk/src/corelib/io/qsettings.cpp
===================================================================
--- trunk/src/corelib/io/qsettings.cpp	(revision 766)
+++ trunk/src/corelib/io/qsettings.cpp	(revision 769)
@@ -1092,28 +1092,21 @@
 }
 
-static QString getPath(QSettings::Format format, QSettings::Scope scope)
-{
-    Q_ASSERT((int)QSettings::NativeFormat == 0);
-    Q_ASSERT((int)QSettings::IniFormat == 1);
-
+static void initDefaultPaths(QMutexLocker *locker)
+{
+    PathHash *pathHash = pathHashFunc();
     QString homePath = QDir::homePath();
     QString systemPath;
 
-    QMutexLocker locker(globalMutex());
-    PathHash *pathHash = pathHashFunc();
-    bool loadSystemPath = pathHash->isEmpty();
-    locker.unlock();
-
-    if (loadSystemPath) {
-        /*
-           QLibraryInfo::location() uses QSettings, so in order to
-           avoid a dead-lock, we can't hold the global mutex while
-           calling it.
-       */
-        systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath);
-        systemPath += QLatin1Char('/');
-    }
-
-    locker.relock();
+    locker->unlock();
+	
+    /*
+       QLibraryInfo::location() uses QSettings, so in order to
+       avoid a dead-lock, we can't hold the global mutex while
+       calling it.
+    */
+    systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath);
+    systemPath += QLatin1Char('/');
+
+    locker->relock();
     if (pathHash->isEmpty()) {
         /*
@@ -1173,4 +1166,15 @@
 #endif
     }
+}
+
+static QString getPath(QSettings::Format format, QSettings::Scope scope)
+{
+    Q_ASSERT((int)QSettings::NativeFormat == 0);
+    Q_ASSERT((int)QSettings::IniFormat == 1);
+
+    QMutexLocker locker(globalMutex());
+    PathHash *pathHash = pathHashFunc();
+    if (pathHash->isEmpty())
+        initDefaultPaths(&locker);
 
     QString result = pathHash->value(pathHashKey(format, scope));
@@ -3483,4 +3487,6 @@
     QMutexLocker locker(globalMutex());
     PathHash *pathHash = pathHashFunc();
+    if (pathHash->isEmpty())
+        initDefaultPaths(&locker);
     pathHash->insert(pathHashKey(format, scope), path + QDir::separator());
 }
Index: trunk/src/corelib/io/qurl.cpp
===================================================================
--- trunk/src/corelib/io/qurl.cpp	(revision 766)
+++ trunk/src/corelib/io/qurl.cpp	(revision 769)
@@ -339,4 +339,5 @@
     bool hasFragment;
     bool isValid;
+    bool isHostValid;
 
     char valueDelimiter;
@@ -438,7 +439,8 @@
 
 // scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-static void QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
+static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
 {
     bool first = true;
+    bool isSchemeValid = true;
 
     parseData->scheme = *ptr;
@@ -447,6 +449,7 @@
         if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
             ;
-        } else if (!first && ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.')) {
-            ;
+        } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') {
+            if (first)
+                isSchemeValid = false;
         } else {
             break;
@@ -458,4 +461,5 @@
 
     if (**ptr != ':') {
+        isSchemeValid = true;
         *ptr = parseData->scheme;
     } else {
@@ -463,4 +467,6 @@
         ++(*ptr); // skip ':'
     }
+
+    return isSchemeValid;
 }
 
@@ -2986,5 +2992,7 @@
         if (c == '-' || (c >= '0' && c <= '9')
             || (c >= 'A' && c <= 'Z')
-            || (c >= 'a' && c <= 'z'))
+            || (c >= 'a' && c <= 'z')
+            //underscore is not supposed to be allowed, but other browser accept it (QTBUG-7434)
+            || c == '_')
             continue;
 
@@ -3125,8 +3133,9 @@
 
 static const char * const idn_whitelist[] = {
-    "ac", "at",
-    "br",
+    "ac", "ar", "at",
+    "biz", "br",
     "cat", "ch", "cl", "cn",
     "de", "dk",
+    "es",
     "fi",
     "gr",
@@ -3142,4 +3151,7 @@
     "th", "tm", "tw",
     "vn",
+    "xn--mgbaam7a8h",           // UAE
+    "xn--mgberp4a5d4ar",        // Saudi Arabia
+    "xn--wgbh1c"                // Egypt
 };
 
@@ -3242,6 +3254,9 @@
         int idx = nextDotDelimiter(domain, lastIdx);
         int labelLength = idx - lastIdx;
-        if (labelLength == 0)
+        if (labelLength == 0) {
+            if (idx == domain.length())
+                break;
             return QString(); // two delimiters in a row -- empty label not allowed
+        }
 
         // RFC 3490 says, about the ToASCII operation:
@@ -3297,4 +3312,5 @@
             labelLength = result.length() - prevLen;
             register int toReserve = labelLength + 4 + 6; // "xn--" plus some extra bytes
+            aceForm.resize(0);
             if (toReserve > aceForm.capacity())
                 aceForm.reserve(toReserve);
@@ -3333,4 +3349,5 @@
     port = -1;
     isValid = false;
+    isHostValid = true;
     parsingMode = QUrl::TolerantMode;
     valueDelimiter = '=';
@@ -3359,4 +3376,5 @@
       hasFragment(copy.hasFragment),
       isValid(copy.isValid),
+      isHostValid(copy.isHostValid),
       valueDelimiter(copy.valueDelimiter),
       pairDelimiter(copy.pairDelimiter),
@@ -3389,4 +3407,6 @@
     } else {
         that->host = qt_ACE_do(host, NormalizeAce);
+        if (that->host.isNull())
+            that->isHostValid = false;
     }
     return that->host;
@@ -3465,4 +3485,5 @@
 void QUrlPrivate::setAuthority(const QString &auth)
 {
+    isHostValid = true;
     if (auth.isEmpty())
         return;
@@ -3741,5 +3762,17 @@
 
     // optional scheme
-    _scheme(ptr, &parseData);
+    bool isSchemeValid = _scheme(ptr, &parseData);
+
+    if (isSchemeValid == false) {
+        that->isValid = false;
+        char ch = *((*ptr)++);
+        that->errorInfo.setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "unexpected URL scheme"),
+                                  0, ch);
+        QURL_SETFLAG(that->stateFlags, Validated | Parsed);
+#if defined (QURL_DEBUG)
+        qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
+#endif
+        return;
+    }
 
     // hierpart
@@ -4143,5 +4176,5 @@
     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
 
-    return d->isValid;
+    return d->isValid && d->isHostValid;
 }
 
@@ -4395,5 +4428,4 @@
     detach();
     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
-
     d->setAuthority(authority);
 }
@@ -4616,4 +4648,5 @@
     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
     detach();
+    d->isHostValid = true;
     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized | QUrlPrivate::HostCanonicalized);
 
Index: trunk/src/corelib/kernel/qabstractitemmodel.cpp
===================================================================
--- trunk/src/corelib/kernel/qabstractitemmodel.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qabstractitemmodel.cpp	(revision 769)
@@ -1006,4 +1006,7 @@
     Returns the child of the model index that is stored in the given \a row and
     \a column.
+
+    \note This function does not work for an invalid model index which is often
+    used as the root index.
 
     \sa parent(), sibling()
Index: trunk/src/corelib/kernel/qcore_symbian_p.cpp
===================================================================
--- trunk/src/corelib/kernel/qcore_symbian_p.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qcore_symbian_p.cpp	(revision 769)
@@ -72,5 +72,5 @@
     return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length());
 #else
-    return QString::fromUtf16(aDescriptor.Ptr(), aDescriptor.Length());
+    return QString(reinterpret_cast<const QChar *>(aDescriptor.Ptr()), aDescriptor.Length());
 #endif
 }
@@ -133,7 +133,8 @@
     {
 #ifdef Q_WS_S60
-        _LIT(KLibName_3_1, "qts60plugin_3_1.dll");
-        _LIT(KLibName_3_2, "qts60plugin_3_2.dll");
-        _LIT(KLibName_5_0, "qts60plugin_5_0.dll");
+        _LIT(KLibName_3_1, "qts60plugin_3_1" QT_LIBINFIX_UNICODE L".dll");
+        _LIT(KLibName_3_2, "qts60plugin_3_2" QT_LIBINFIX_UNICODE L".dll");
+        _LIT(KLibName_5_0, "qts60plugin_5_0" QT_LIBINFIX_UNICODE L".dll");
+
         TPtrC libName;
         TInt uidValue;
Index: trunk/src/corelib/kernel/qcore_symbian_p.h
===================================================================
--- trunk/src/corelib/kernel/qcore_symbian_p.h	(revision 766)
+++ trunk/src/corelib/kernel/qcore_symbian_p.h	(revision 769)
@@ -60,4 +60,13 @@
 #include <qhash.h>
 #include <f32file.h>
+
+#define QT_LSTRING2(x) L##x
+#define QT_LSTRING(x) QT_LSTRING2(x)
+
+#if defined(QT_LIBINFIX)
+#  define QT_LIBINFIX_UNICODE QT_LSTRING(QT_LIBINFIX)
+#else
+#  define QT_LIBINFIX_UNICODE L""
+#endif
 
 QT_BEGIN_HEADER
Index: trunk/src/corelib/kernel/qcoreapplication.cpp
===================================================================
--- trunk/src/corelib/kernel/qcoreapplication.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qcoreapplication.cpp	(revision 769)
@@ -68,4 +68,5 @@
 #  include <exception>
 #  include <f32file.h>
+#  include <e32ldr.h>
 #  include "qeventdispatcher_symbian_p.h"
 #  include "private/qcore_symbian_p.h"
@@ -597,4 +598,25 @@
     extern void qt_core_eval_init(uint);
     qt_core_eval_init(d->application_type);
+#endif
+
+#if    defined(Q_OS_SYMBIAN)  \
+    && defined(Q_CC_NOKIAX86) \
+    && defined(QT_DEBUG)
+    /**
+     * Prevent the executable from being locked in the Symbian emulator. The
+     * code dramatically simplifies debugging on Symbian, but beyond that has
+     * no impact.
+     *
+     * Force the ZLazyUnloadTimer to fire and therefore unload code segments
+     * immediately. The code affects Symbian's file server and on the other
+     * hand needs only to be run once in each emulator run.
+     */
+    {
+        RLoader loader;
+        CleanupClosePushL(loader);
+        User::LeaveIfError(loader.Connect());
+        User::LeaveIfError(loader.CancelLazyDllUnload());
+        CleanupStack::PopAndDestroy(&loader);
+    }
 #endif
 
@@ -2250,5 +2272,6 @@
             TInt err = finder.FindByDir(tempPathPtr, tempPathPtr);
             while (err == KErrNone) {
-                QString foundDir = QString::fromUtf16(finder.File().Ptr(), finder.File().Length());
+                QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
+                                 finder.File().Length());
                 foundDir = QDir(foundDir).canonicalPath();
                 if (!app_libpaths->contains(foundDir))
Index: trunk/src/corelib/kernel/qeventdispatcher_symbian.cpp
===================================================================
--- trunk/src/corelib/kernel/qeventdispatcher_symbian.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qeventdispatcher_symbian.cpp	(revision 769)
@@ -44,10 +44,18 @@
 #include <qcoreapplication.h>
 #include <private/qcoreapplication_p.h>
-#include <qdatetime.h>
 
 #include <unistd.h>
 #include <errno.h>
 
+#include <net/if.h>
+
 QT_BEGIN_NAMESPACE
+
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+// when the system UI is Qt based, priority drop is not needed as CPU starved processes will not be killed.
+#undef QT_SYMBIAN_PRIORITY_DROP
+#else
+#define QT_SYMBIAN_PRIORITY_DROP
+#endif
 
 #define WAKE_UP_PRIORITY CActive::EPriorityStandard
@@ -93,23 +101,38 @@
 {
 public:
-    QSelectMutexGrabber(int fd, QMutex *mutex)
-        : m_mutex(mutex)
+    QSelectMutexGrabber(int fd, QMutex *threadMutex, QMutex *selectCallMutex)
+        : m_threadMutex(threadMutex), m_selectCallMutex(selectCallMutex), bHasThreadLock(false)
     {
-        if (m_mutex->tryLock())
+        // see if selectThread is waiting m_waitCond
+        // if yes ... dont write to pipe
+        if (m_threadMutex->tryLock()) {
+            bHasThreadLock = true;
             return;
+        }
+
+        // still check that SelectThread
+        // is in select call
+        if (m_selectCallMutex->tryLock()) {
+            m_selectCallMutex->unlock();
+            return;
+        }
 
         char dummy = 0;
         qt_pipe_write(fd, &dummy, 1);
 
-        m_mutex->lock();
+        m_threadMutex->lock();
+        bHasThreadLock = true;
     }
 
     ~QSelectMutexGrabber()
     {
-        m_mutex->unlock();
+        if(bHasThreadLock)
+            m_threadMutex->unlock();
     }
 
 private:
-    QMutex *m_mutex;
+    QMutex *m_threadMutex;
+    QMutex *m_selectCallMutex;
+    bool bHasThreadLock;
 };
 
@@ -393,5 +416,10 @@
         int ret;
         int savedSelectErrno;
-        ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0);
+        {
+            // helps fighting the race condition between
+            // selctthread and new socket requests (cancel, restart ...)
+            QMutexLocker locker(&m_selectCallMutex);
+            ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0);
+        }
         savedSelectErrno = errno;
 
@@ -457,7 +485,7 @@
 
                 // traversed all, so update
+                updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds);
                 updateActivatedNotifiers(QSocketNotifier::Read, &readfds);
                 updateActivatedNotifiers(QSocketNotifier::Write, &writefds);
-                updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds);
 
                 break;
@@ -469,7 +497,7 @@
             }
         } else {
+            updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds);
             updateActivatedNotifiers(QSocketNotifier::Read, &readfds);
             updateActivatedNotifiers(QSocketNotifier::Write, &writefds);
-            updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds);
         }
 
@@ -488,5 +516,7 @@
     }
 
-    QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex);
+    QMutexLocker locker(&m_grabberMutex);
+
+    QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex, &m_selectCallMutex);
 
     Q_ASSERT(!m_AOStatuses.contains(notifier));
@@ -499,5 +529,7 @@
 void QSelectThread::cancelSocketEvents ( QSocketNotifier *notifier )
 {
-    QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex);
+    QMutexLocker locker(&m_grabberMutex);
+
+    QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex, &m_selectCallMutex);
 
     m_AOStatuses.remove(notifier);
@@ -508,5 +540,7 @@
 void QSelectThread::restart()
 {
-    QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex);
+    QMutexLocker locker(&m_grabberMutex);
+
+    QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex, &m_selectCallMutex);
 
     m_waitCond.wakeAll();
@@ -564,5 +598,15 @@
              * then signal RequestComplete for it
              */
-            qWarning("exception on %d", i.key()->socket());
+            qWarning("exception on %d [will do setdefaultif(0) - hack]", i.key()->socket());
+            // quick fix; there is a bug
+            // when doing read on socket
+            // errors not preoperly mapped
+            // after offline-ing the device
+            // on some devices we do get exception
+            // close all exiting sockets
+            // and reset default IAP
+            if(::setdefaultif(0) != KErrNone) // well we can't do much about it
+                qWarning("setdefaultif(0) failed");
+
             toRemove.append(i.key());
             TRequestStatus *status = i.value();
@@ -623,4 +667,72 @@
     }
 }
+
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+class QIdleDetectorThread
+{
+public:
+    QIdleDetectorThread()
+    : m_state(STATE_RUN), m_stop(false)
+    {
+        qt_symbian_throwIfError(m_lock.CreateLocal(0));
+        TInt err = m_idleDetectorThread.Create(KNullDesC(), &idleDetectorThreadFunc, 1024, NULL, this);
+        if (err != KErrNone)
+            m_lock.Close();
+        qt_symbian_throwIfError(err);
+        m_idleDetectorThread.SetPriority(EPriorityAbsoluteBackgroundNormal);
+        m_idleDetectorThread.Resume();
+    }
+
+    ~QIdleDetectorThread()
+    {
+        // close down the idle thread because if corelib is loaded temporarily, this would leak threads into the host process
+        m_stop = true;
+        m_lock.Signal();
+        m_idleDetectorThread.SetPriority(EPriorityNormal);
+        TRequestStatus s;
+        m_idleDetectorThread.Logon(s);
+        User::WaitForRequest(s);
+        m_idleDetectorThread.Close();
+        m_lock.Close();
+    }
+
+    void kick()
+    {
+        m_state = STATE_KICKED;
+        m_lock.Signal();
+    }
+
+    bool hasRun()
+    {
+        return m_state == STATE_RUN;
+    }
+
+private:
+    static TInt idleDetectorThreadFunc(TAny* self)
+    {
+        static_cast<QIdleDetectorThread*>(self)->IdleLoop();
+        return KErrNone;
+    }
+
+    void IdleLoop()
+    {
+        while (!m_stop) {
+            m_lock.Wait();
+            m_state = STATE_RUN;
+        }
+    }
+
+private:
+    enum IdleStates {STATE_KICKED, STATE_RUN} m_state;
+    bool m_stop;
+    RThread m_idleDetectorThread;
+    RSemaphore m_lock;
+};
+
+Q_GLOBAL_STATIC(QIdleDetectorThread, idleDetectorThread);
+
+const int maxBusyTime = 2000; // maximum time we allow idle detector to be blocked before worrying, in milliseconds
+const int baseDelay = 1000; // minimum delay time used when backing off to allow idling, in microseconds
+#endif
 
 QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent)
@@ -634,9 +746,13 @@
       m_noSocketEvents(false)
 {
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+    m_delay = baseDelay;
+    m_avgEventTime = 0;
+    idleDetectorThread();
+#endif
 }
 
 QEventDispatcherSymbian::~QEventDispatcherSymbian()
 {
-    m_processHandle.Close();
 }
 
@@ -698,21 +814,7 @@
         m_interrupt = false;
 
-        /*
-         * This QTime variable is used to measure the time it takes to finish
-         * the event loop. If we take too long in the loop, other processes
-         * may be starved and killed. After the first event has completed, we
-         * take the current time, and if the remaining events take longer than
-         * a preset time, we temporarily lower the priority to force a context
-         * switch. For applications that do not take unecessarily long in the
-         * event loop, the priority will not be altered.
-         */
-        QTime time;
-        enum {
-            FirstRun,
-            SubsequentRun,
-            TimeStarted
-        } timeState = FirstRun;
-
-        TProcessPriority priority;
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+        QTime eventTimer;
+#endif
 
         while (1) {
@@ -728,15 +830,31 @@
             }
 
-            if (timeState == SubsequentRun) {
-                time.start();
-                timeState = TimeStarted;
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+            if (idleDetectorThread()->hasRun()) {
+                if (m_delay > baseDelay)
+                    m_delay -= baseDelay;
+                m_lastIdleRequestTimer.start();
+                idleDetectorThread()->kick();
+            } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) {
+                User::AfterHighRes(m_delay);
+                // allow delay to be up to 1/4 of execution time
+                if (!idleDetectorThread()->hasRun() && m_delay*3 < m_avgEventTime)
+                    m_delay += baseDelay;
             }
+            eventTimer.start();
+#endif
 
             TInt error;
-            handledSymbianEvent = CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle);
+            handledSymbianEvent = CActiveScheduler::RunIfReady(error, KMinTInt);
             if (error) {
                 qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error);
                 CActiveScheduler::Current()->Error(error);
             }
+
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+            int eventDur = eventTimer.elapsed()*1000;
+            // average is calcualted as a 5% decaying exponential average
+            m_avgEventTime = (m_avgEventTime * 95 + eventDur * 5) / 100;
+#endif
 
             if (!handledSymbianEvent) {
@@ -748,16 +866,4 @@
             }
             block = false;
-            if (timeState == TimeStarted && time.elapsed() > 100) {
-                priority = m_processHandle.Priority();
-                m_processHandle.SetPriority(EPriorityBackground);
-                time.start();
-                // Slight chance of race condition in the next lines, but nothing fatal
-                // will happen, just wrong priority.
-                if (m_processHandle.Priority() == EPriorityBackground) {
-                    m_processHandle.SetPriority(priority);
-                }
-            }
-            if (timeState == FirstRun)
-                timeState = SubsequentRun;
         };
 
Index: trunk/src/corelib/kernel/qeventdispatcher_symbian_p.h
===================================================================
--- trunk/src/corelib/kernel/qeventdispatcher_symbian_p.h	(revision 766)
+++ trunk/src/corelib/kernel/qeventdispatcher_symbian_p.h	(revision 769)
@@ -63,4 +63,5 @@
 #include <qwaitcondition.h>
 #include <qsocketnotifier.h>
+#include <qdatetime.h>
 
 #include <e32base.h>
@@ -211,4 +212,24 @@
     QWaitCondition m_waitCond;
     bool m_quit;
+
+    // to protect when several
+    // requests like:
+    // requestSocketEvents
+    // cancelSocketEvents
+    // kick in the same time
+    // all will fight for m_mutex
+    //
+    // TODO: fix more elegantely
+    //
+    QMutex m_grabberMutex;
+
+    // this one will tell
+    // if selectthread is
+    // really in select call
+    // and will prevent
+    // writing to pipe that
+    // causes later in locking
+    // of the thread in waitcond
+    QMutex m_selectCallMutex;
 };
 
@@ -280,5 +301,7 @@
     QList<QActiveObject *> m_deferredActiveObjects;
 
-    RProcess m_processHandle;
+    int m_delay;
+    int m_avgEventTime;
+    QTime m_lastIdleRequestTimer;
 };
 
Index: trunk/src/corelib/kernel/qeventdispatcher_win.cpp
===================================================================
--- trunk/src/corelib/kernel/qeventdispatcher_win.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qeventdispatcher_win.cpp	(revision 769)
@@ -69,4 +69,12 @@
 #endif
 
+#ifndef WM_TOUCH
+#  define WM_TOUCH 0x0240
+#endif
+#ifndef WM_GESTURE
+#  define WM_GESTURE 0x0119
+#  define WM_GESTURENOTIFY 0x011A
+#endif
+
 enum {
     WM_QT_SOCKETNOTIFIER = WM_USER,
@@ -503,6 +511,6 @@
                 if (localSerialNumber != d->lastSerialNumber
                     // if this message IS the one that triggers sendPostedEvents(), no need to post it again
-                    && msg->hwnd != d->internalHwnd
-                    && msg->message != WM_QT_SENDPOSTEDEVENTS) {
+                    && (msg->hwnd != d->internalHwnd
+                        || msg->message != WM_QT_SENDPOSTEDEVENTS)) {
                     PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
                 }
@@ -715,4 +723,7 @@
                         || msg.message == WM_MOUSEWHEEL
                         || msg.message == WM_MOUSEHWHEEL
+                        || msg.message == WM_TOUCH
+                        || msg.message == WM_GESTURE
+                        || msg.message == WM_GESTURENOTIFY
                         || msg.message == WM_CLOSE)) {
                     // queue user input events for later processing
Index: trunk/src/corelib/kernel/qfunctions_wince.cpp
===================================================================
--- trunk/src/corelib/kernel/qfunctions_wince.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qfunctions_wince.cpp	(revision 769)
@@ -353,14 +353,16 @@
     size_t high = num - 1;
     while (low <= high) {
-        unsigned int mid = ((unsigned) (low + high)) >> 1;
+        size_t mid = (low + high) >> 1;
         int c = compare(key, (char*)base + mid * size);
-        if (c < 0)
+        if (c < 0) {
+            if (!mid)
+                break;
             high = mid - 1;
-        else if (c > 0)
+        } else if (c > 0)
             low = mid + 1;
         else
             return (char*) base + mid * size;
     }
-    return (NULL);
+    return 0;
 }
 
Index: trunk/src/corelib/kernel/qmetaobject.cpp
===================================================================
--- trunk/src/corelib/kernel/qmetaobject.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qmetaobject.cpp	(revision 769)
@@ -944,5 +944,5 @@
         return result;
 
-    QVarLengthArray<char> stackbuf(int(strlen(type)) + 1);
+    QVarLengthArray<char> stackbuf(qstrlen(type) + 1);
     qRemoveWhitespace(type, stackbuf.data());
     int templdepth = 0;
Index: trunk/src/corelib/kernel/qobject.cpp
===================================================================
--- trunk/src/corelib/kernel/qobject.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qobject.cpp	(revision 769)
@@ -3265,10 +3265,12 @@
             const int method = c->method;
             QObjectPrivate::Sender currentSender;
-            currentSender.sender = sender;
-            currentSender.signal = signal_absolute_index;
-            currentSender.ref = 1;
+            const bool receiverInSameThread = currentThreadData == receiver->d_func()->threadData;
             QObjectPrivate::Sender *previousSender = 0;
-            if (currentThreadData == receiver->d_func()->threadData)
+            if (receiverInSameThread) {
+                currentSender.sender = sender;
+                currentSender.signal = signal_absolute_index;
+                currentSender.ref = 1;
                 previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
+            }
             locker.unlock();
 
@@ -3286,6 +3288,6 @@
             } QT_CATCH(...) {
                 locker.relock();
-
-                QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
+                if (receiverInSameThread)
+                    QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
 
                 --connectionLists->inUse;
@@ -3302,5 +3304,6 @@
             locker.relock();
 
-            QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
+            if (receiverInSameThread)
+                QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
 
             if (connectionLists->orphaned)
Index: trunk/src/corelib/kernel/qobjectdefs.h
===================================================================
--- trunk/src/corelib/kernel/qobjectdefs.h	(revision 766)
+++ trunk/src/corelib/kernel/qobjectdefs.h	(revision 769)
@@ -79,4 +79,5 @@
 #define Q_INTERFACES(x)
 #define Q_PROPERTY(text)
+#define Q_PRIVATE_PROPERTY(d, text)
 #define Q_OVERRIDE(text)
 #define Q_ENUMS(x)
@@ -179,4 +180,5 @@
 #define Q_INTERFACES(x) Q_INTERFACES(x)
 #define Q_PROPERTY(text) Q_PROPERTY(text)
+#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
 #define Q_OVERRIDE(text) Q_OVERRIDE(text)
 #define Q_ENUMS(x) Q_ENUMS(x)
Index: trunk/src/corelib/kernel/qtranslator.cpp
===================================================================
--- trunk/src/corelib/kernel/qtranslator.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qtranslator.cpp	(revision 769)
@@ -634,5 +634,5 @@
     if (!tn)
         return QString();
-    QString str = QString::fromUtf16((const ushort *)tn, tn_length/2);
+    QString str = QString((const QChar *)tn, tn_length/2);
     if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
         for (int i = 0; i < str.length(); ++i)
Index: trunk/src/corelib/kernel/qvariant.cpp
===================================================================
--- trunk/src/corelib/kernel/qvariant.cpp	(revision 766)
+++ trunk/src/corelib/kernel/qvariant.cpp	(revision 769)
@@ -467,6 +467,10 @@
      * user defined pointer types. */
     const char *const typeName = QMetaType::typeName(a->type);
-    if (typeName[qstrlen(typeName) - 1] == '*')
+    uint typeNameLen = qstrlen(typeName);
+    if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
         return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
+
+    if (a->is_null && b->is_null)
+        return true;
 
     return a_ptr == b_ptr;
Index: trunk/src/corelib/plugin/qlibrary.cpp
===================================================================
--- trunk/src/corelib/plugin/qlibrary.cpp	(revision 766)
+++ trunk/src/corelib/plugin/qlibrary.cpp	(revision 769)
@@ -540,4 +540,5 @@
     \row \i HP-UX         \i \c .sl, \c .so (HP-UXi)
     \row \i Mac OS X      \i \c .dylib, \c .bundle, \c .so
+    \row \i Symbian     \i \c .dll
     \endtable
 
Index: trunk/src/corelib/statemachine/qstatemachine.cpp
===================================================================
--- trunk/src/corelib/statemachine/qstatemachine.cpp	(revision 766)
+++ trunk/src/corelib/statemachine/qstatemachine.cpp	(revision 769)
@@ -1176,4 +1176,14 @@
 }
 
+void QStateMachinePrivate::clearHistory()
+{
+    Q_Q(QStateMachine);
+    QList<QHistoryState*> historyStates = qFindChildren<QHistoryState*>(q);
+    for (int i = 0; i < historyStates.size(); ++i) {
+        QHistoryState *h = historyStates.at(i);
+        QHistoryStatePrivate::get(h)->configuration.clear();
+    }
+}
+
 void QStateMachinePrivate::_q_start()
 {
@@ -1187,4 +1197,5 @@
     qDeleteAll(externalEventQueue);
     externalEventQueue.clear();
+    clearHistory();
 
 #ifdef QSTATEMACHINE_DEBUG
Index: trunk/src/corelib/statemachine/qstatemachine_p.h
===================================================================
--- trunk/src/corelib/statemachine/qstatemachine_p.h	(revision 766)
+++ trunk/src/corelib/statemachine/qstatemachine_p.h	(revision 769)
@@ -126,4 +126,6 @@
     QState *startState();
     void removeStartState();
+
+    void clearHistory();
 
     void microstep(QEvent *event, const QList<QAbstractTransition*> &transitionList);
Index: trunk/src/corelib/thread/qmutex.h
===================================================================
--- trunk/src/corelib/thread/qmutex.h	(revision 766)
+++ trunk/src/corelib/thread/qmutex.h	(revision 769)
@@ -96,5 +96,5 @@
 public:
     inline explicit QMutexLocker(QMutex *m)
-        : mtx(m)
+        : val(reinterpret_cast<quintptr>(m))
     {
         Q_ASSERT_X((val & quintptr(1u)) == quintptr(0),
@@ -106,8 +106,8 @@
     inline void unlock()
     {
-        if (mtx) {
+        if (val) {
             if ((val & quintptr(1u)) == quintptr(1u)) {
                 val &= ~quintptr(1u);
-                mtx->unlock();
+                mutex()->unlock();
             }
         }
@@ -116,7 +116,7 @@
     inline void relock()
     {
-        if (mtx) {
+        if (val) {
             if ((val & quintptr(1u)) == quintptr(0u)) {
-                mtx->lock();
+                mutex()->lock();
                 val |= quintptr(1u);
             }
@@ -141,8 +141,5 @@
     Q_DISABLE_COPY(QMutexLocker)
 
-    union {
-        QMutex *mtx;
-        quintptr val;
-    };
+    quintptr val;
 };
 
Index: trunk/src/corelib/thread/qreadwritelock.h
===================================================================
--- trunk/src/corelib/thread/qreadwritelock.h	(revision 766)
+++ trunk/src/corelib/thread/qreadwritelock.h	(revision 769)
@@ -97,8 +97,8 @@
     inline void unlock()
     {
-        if (q_lock) {
+        if (q_val) {
             if ((q_val & quintptr(1u)) == quintptr(1u)) {
                 q_val &= ~quintptr(1u);
-                q_lock->unlock();
+                readWriteLock()->unlock();
             }
         }
@@ -107,7 +107,7 @@
     inline void relock()
     {
-        if (q_lock) {
+        if (q_val) {
             if ((q_val & quintptr(1u)) == quintptr(0u)) {
-                q_lock->lockForRead();
+                readWriteLock()->lockForRead();
                 q_val |= quintptr(1u);
             }
@@ -120,12 +120,9 @@
 private:
     Q_DISABLE_COPY(QReadLocker)
-    union {
-        QReadWriteLock *q_lock;
-        quintptr q_val;
-    };
+    quintptr q_val;
 };
 
 inline QReadLocker::QReadLocker(QReadWriteLock *areadWriteLock)
-    : q_lock(areadWriteLock)
+    : q_val(reinterpret_cast<quintptr>(areadWriteLock))
 {
     Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0),
@@ -144,8 +141,8 @@
     inline void unlock()
     {
-        if (q_lock) {
+        if (q_val) {
             if ((q_val & quintptr(1u)) == quintptr(1u)) {
                 q_val &= ~quintptr(1u);
-                q_lock->unlock();
+                readWriteLock()->unlock();
             }
         }
@@ -154,7 +151,7 @@
     inline void relock()
     {
-        if (q_lock) {
+        if (q_val) {
             if ((q_val & quintptr(1u)) == quintptr(0u)) {
-                q_lock->lockForWrite();
+                readWriteLock()->lockForWrite();
                 q_val |= quintptr(1u);
             }
@@ -168,12 +165,9 @@
 private:
     Q_DISABLE_COPY(QWriteLocker)
-    union{
-        QReadWriteLock *q_lock;
-        quintptr q_val;
-    };
+    quintptr q_val;
 };
 
 inline QWriteLocker::QWriteLocker(QReadWriteLock *areadWriteLock)
-    : q_lock(areadWriteLock)
+    : q_val(reinterpret_cast<quintptr>(areadWriteLock))
 {
     Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0),
Index: trunk/src/corelib/thread/qthread_win.cpp
===================================================================
--- trunk/src/corelib/thread/qthread_win.cpp	(revision 766)
+++ trunk/src/corelib/thread/qthread_win.cpp	(revision 769)
@@ -41,5 +41,7 @@
 
 //#define WINVER 0x0500
+#if _WIN32_WINNT < 0x0400
 #define _WIN32_WINNT 0x0400
+#endif
 
 
Index: trunk/src/corelib/tools/qbytedata_p.h
===================================================================
--- trunk/src/corelib/tools/qbytedata_p.h	(revision 766)
+++ trunk/src/corelib/tools/qbytedata_p.h	(revision 769)
@@ -85,5 +85,5 @@
 
 
-    inline void append(QByteArray& bd)
+    inline void append(const QByteArray& bd)
     {
         if (bd.isEmpty())
Index: trunk/src/corelib/tools/qchar.cpp
===================================================================
--- trunk/src/corelib/tools/qchar.cpp	(revision 766)
+++ trunk/src/corelib/tools/qchar.cpp	(revision 769)
@@ -382,6 +382,10 @@
     \value Null A QChar with this value isNull().
     \value Nbsp Non-breaking space.
-    \value ReplacementCharacter
-    \value ObjectReplacementCharacter The character shown when a font has no glyph for a certain codepoint. The square character is normally used.
+    \value ReplacementCharacter The character shown when a font has no glyph
+           for a certain codepoint. A special question mark character is often
+           used. Codecs use this codepoint when input data cannot be
+           represented in Unicode.
+    \value ObjectReplacementCharacter Used to represent an object such as an
+           image when such objects cannot be presented.
     \value ByteOrderMark
     \value ByteOrderSwapped
Index: trunk/src/corelib/tools/qcontiguouscache.h
===================================================================
--- trunk/src/corelib/tools/qcontiguouscache.h	(revision 766)
+++ trunk/src/corelib/tools/qcontiguouscache.h	(revision 769)
@@ -98,5 +98,5 @@
     typedef value_type& reference;
     typedef const value_type& const_reference;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
     typedef int size_type;
 
@@ -222,20 +222,27 @@
     x.d->count = qMin(d->count, asize);
     x.d->offset = d->offset + d->count - x.d->count;
-    x.d->start = x.d->offset % x.d->alloc;
-    T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
-    T *src = p->array + (d->start + d->count-1) % d->alloc;
+    if(asize)
+        x.d->start = x.d->offset % x.d->alloc;
+    else
+        x.d->start = 0;
+
     int oldcount = x.d->count;
-    while (oldcount--) {
-        if (QTypeInfo<T>::isComplex) {
-            new (dest) T(*src);
-        } else {
-            *dest = *src;
+    if(oldcount)
+    {
+        T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
+        T *src = p->array + (d->start + d->count-1) % d->alloc;
+        while (oldcount--) {
+            if (QTypeInfo<T>::isComplex) {
+                new (dest) T(*src);
+            } else {
+                *dest = *src;
+            }
+            if (dest == x.p->array)
+                dest = x.p->array + x.d->alloc;
+            dest--;
+            if (src == p->array)
+                src = p->array + d->alloc;
+            src--;
         }
-        if (dest == x.p->array)
-            dest = x.p->array + x.d->alloc;
-        dest--;
-        if (src == p->array)
-            src = p->array + d->alloc;
-        src--;
     }
     /* free old */
Index: trunk/src/corelib/tools/qhash.cpp
===================================================================
--- trunk/src/corelib/tools/qhash.cpp	(revision 766)
+++ trunk/src/corelib/tools/qhash.cpp	(revision 769)
@@ -69,6 +69,6 @@
     while (n--) {
         h = (h << 4) + *p++;
-        if ((g = (h & 0xf0000000)) != 0)
-            h ^= g >> 23;
+        g = h & 0xf0000000;
+        h ^= g >> 23;
         h &= ~g;
     }
@@ -83,6 +83,6 @@
     while (n--) {
         h = (h << 4) + (*p++).unicode();
-        if ((g = (h & 0xf0000000)) != 0)
-            h ^= g >> 23;
+        g = h & 0xf0000000;
+        h ^= g >> 23;
         h &= ~g;
     }
Index: trunk/src/corelib/tools/qhash.h
===================================================================
--- trunk/src/corelib/tools/qhash.h	(revision 766)
+++ trunk/src/corelib/tools/qhash.h	(revision 769)
@@ -330,5 +330,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef T *pointer;
@@ -395,5 +395,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -479,5 +479,5 @@
     typedef T mapped_type;
     typedef Key key_type;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
     typedef int size_type;
 
@@ -928,5 +928,5 @@
 
     inline QMultiHash &operator+=(const QMultiHash &other)
-    { unite(other); return *this; }
+    { this->unite(other); return *this; }
     inline QMultiHash operator+(const QMultiHash &other) const
     { QMultiHash result = *this; result += other; return result; }
@@ -1003,10 +1003,5 @@
     while (i != end && i.key() == key) {
         if (i.value() == value) {
-#if defined(Q_CC_RVCT)
-            // RVCT has problems with scoping, apparently.
-            i = QHash<Key, T>::erase(i);
-#else
-            i = erase(i);
-#endif
+            i = this->erase(i);
             ++n;
         } else {
Index: trunk/src/corelib/tools/qlinkedlist.h
===================================================================
--- trunk/src/corelib/tools/qlinkedlist.h	(revision 766)
+++ trunk/src/corelib/tools/qlinkedlist.h	(revision 769)
@@ -114,5 +114,5 @@
     public:
         typedef std::bidirectional_iterator_tag  iterator_category;
-        typedef ptrdiff_t  difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef T *pointer;
@@ -147,5 +147,5 @@
     public:
         typedef std::bidirectional_iterator_tag  iterator_category;
-        typedef ptrdiff_t  difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -213,5 +213,5 @@
     typedef value_type &reference;
     typedef const value_type &const_reference;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
 
 #ifndef QT_NO_STL
Index: trunk/src/corelib/tools/qlist.cpp
===================================================================
--- trunk/src/corelib/tools/qlist.cpp	(revision 766)
+++ trunk/src/corelib/tools/qlist.cpp	(revision 769)
@@ -209,5 +209,5 @@
     if (n) {
         if (e + n > d->alloc)
-            realloc(grow(e + l.d->end - l.d->begin));
+            realloc(grow(e + n));
         d->end += n;
     }
Index: trunk/src/corelib/tools/qlist.h
===================================================================
--- trunk/src/corelib/tools/qlist.h	(revision 766)
+++ trunk/src/corelib/tools/qlist.h	(revision 769)
@@ -164,5 +164,5 @@
         Node *i;
         typedef std::random_access_iterator_tag  iterator_category;
-        typedef ptrdiff_t  difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef T *pointer;
@@ -211,5 +211,5 @@
         Node *i;
         typedef std::random_access_iterator_tag  iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -290,5 +290,5 @@
     typedef value_type &reference;
     typedef const value_type &const_reference;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
 
 #ifdef QT3_SUPPORT
Index: trunk/src/corelib/tools/qlocale.cpp
===================================================================
--- trunk/src/corelib/tools/qlocale.cpp	(revision 766)
+++ trunk/src/corelib/tools/qlocale.cpp	(revision 769)
@@ -774,4 +774,5 @@
 };
 
+/* NOTE: This array should be sorted by the first column! */
 static const WindowsToISOListElt windows_to_iso_list[] = {
     { 0x0401, "ar_SA" },
Index: trunk/src/corelib/tools/qlocale_symbian.cpp
===================================================================
--- trunk/src/corelib/tools/qlocale_symbian.cpp	(revision 766)
+++ trunk/src/corelib/tools/qlocale_symbian.cpp	(revision 769)
@@ -88,69 +88,73 @@
 
 /*
-  Mapping from Symbian to ISO locale
+  Mapping from Symbian to ISO locale.
+  NOTE: This array should be sorted by the first column!
 */
 static const symbianToISO symbian_to_iso_list[] = {
-    { ELangEnglish,             "en_GB" },
-    { ELangFrench,              "fr_FR" },
-    { ELangGerman,              "de_DE" },
-    { ELangSpanish,             "es_ES" },
-    { ELangItalian,             "it_IT" },
-    { ELangSwedish,             "sv_SE" },
-    { ELangDanish,              "da_DK" },
-    { ELangNorwegian,           "no_NO" },
-    { ELangFinnish,             "fi_FI" },
-    { ELangAmerican,            "en_US" },
-    { ELangPortuguese,          "pt_PT" },
-    { ELangTurkish,             "tr_TR" },
-    { ELangIcelandic,           "is_IS" },
-    { ELangRussian,             "ru_RU" },
-    { ELangHungarian,           "hu_HU" },
-    { ELangDutch,               "nl_NL" },
-    { ELangBelgianFlemish,      "nl_BE" },
-    { ELangCzech,               "cs_CZ" },
-    { ELangSlovak,              "sk_SK" },
-    { ELangPolish,              "pl_PL" },
-    { ELangSlovenian,           "sl_SI" },
-    { ELangTaiwanChinese,       "zh_TW" },
-    { ELangHongKongChinese,     "zh_HK" },
-    { ELangPrcChinese,          "zh_CN" },
-    { ELangJapanese,            "ja_JP" },
-    { ELangThai,                "th_TH" },
-    { ELangArabic,              "ar_AE" },
-    { ELangTagalog,             "tl_PH" },
-    { ELangBulgarian,           "bg_BG" },
-    { ELangCatalan,             "ca_ES" },
-    { ELangCroatian,            "hr_HR" },
-    { ELangEstonian,            "et_EE" },
-    { ELangFarsi,               "fa_IR" },
-    { ELangCanadianFrench,      "fr_CA" },
-    { ELangGreek,               "el_GR" },
-    { ELangHebrew,              "he_IL" },
-    { ELangHindi,               "hi_IN" },
-    { ELangIndonesian,          "id_ID" },
-    { ELangLatvian,             "lv_LV" },
-    { ELangLithuanian,          "lt_LT" },
-    { ELangMalay,               "ms_MY" },
-    { ELangBrazilianPortuguese, "pt_BR" },
-    { ELangRomanian,            "ro_RO" },
-    { ELangSerbian,             "sr_YU" },
-    { ELangLatinAmericanSpanish, "es" },
-    { ELangUkrainian,           "uk_UA" },
-    { ELangUrdu,                "ur_PK" }, // India/Pakistan
-    { ELangVietnamese,          "vi_VN" },
+    { ELangEnglish,             "en_GB" },  // 1
+    { ELangFrench,              "fr_FR" },  // 2
+    { ELangGerman,              "de_DE" },  // 3
+    { ELangSpanish,             "es_ES" },  // 4
+    { ELangItalian,             "it_IT" },  // 5
+    { ELangSwedish,             "sv_SE" },  // 6
+    { ELangDanish,              "da_DK" },  // 7
+    { ELangNorwegian,           "no_NO" },  // 8
+    { ELangFinnish,             "fi_FI" },  // 9
+    { ELangAmerican,            "en_US" },  // 10
+    { ELangPortuguese,          "pt_PT" },  // 13
+    { ELangTurkish,             "tr_TR" },  // 14
+    { ELangIcelandic,           "is_IS" },  // 15
+    { ELangRussian,             "ru_RU" },  // 16
+    { ELangHungarian,           "hu_HU" },  // 17
+    { ELangDutch,               "nl_NL" },  // 18
+    { ELangBelgianFlemish,      "nl_BE" },  // 19
+    { ELangCzech,               "cs_CZ" },  // 25
+    { ELangSlovak,              "sk_SK" },  // 26
+    { ELangPolish,              "pl_PL" },  // 27
+    { ELangSlovenian,           "sl_SI" },  // 28
+    { ELangTaiwanChinese,       "zh_TW" },  // 29
+    { ELangHongKongChinese,     "zh_HK" },  // 30
+    { ELangPrcChinese,          "zh_CN" },  // 31
+    { ELangJapanese,            "ja_JP" },  // 32
+    { ELangThai,                "th_TH" },  // 33
+    { ELangArabic,              "ar_AE" },  // 37
+    { ELangTagalog,             "tl_PH" },  // 39
+    { ELangBulgarian,           "bg_BG" },  // 42
+    { ELangCatalan,             "ca_ES" },  // 44
+    { ELangCroatian,            "hr_HR" },  // 45
+    { ELangEstonian,            "et_EE" },  // 49
+    { ELangFarsi,               "fa_IR" },  // 50
+    { ELangCanadianFrench,      "fr_CA" },  // 51
+    { ELangGreek,               "el_GR" },  // 54
+    { ELangHebrew,              "he_IL" },  // 57
+    { ELangHindi,               "hi_IN" },  // 58
+    { ELangIndonesian,          "id_ID" },  // 59
+    { ELangKorean,              "ko_KO" },  // 65
+    { ELangLatvian,             "lv_LV" },  // 67
+    { ELangLithuanian,          "lt_LT" },  // 68
+    { ELangMalay,               "ms_MY" },  // 70
+    { ELangNorwegianNynorsk,    "nn_NO" },  // 75
+    { ELangBrazilianPortuguese, "pt_BR" },  // 76
+    { ELangRomanian,            "ro_RO" },  // 78
+    { ELangSerbian,             "sr_RS" },  // 79
+    { ELangLatinAmericanSpanish,"es_419" }, // 83
+    { ELangUkrainian,           "uk_UA" },  // 93
+    { ELangUrdu,                "ur_PK" },  // 94 - India/Pakistan
+    { ELangVietnamese,          "vi_VN" },  // 96
 #ifdef __E32LANG_H__
 // 5.0
-    { ELangBasque,              "eu_ES" },
-    { ELangGalician,            "gl_ES" },
+    { ELangBasque,              "eu_ES" },  // 102
+    { ELangGalician,            "gl_ES" },  // 103
 #endif
 #if !defined(__SERIES60_31__)
-    { ELangEnglish_Apac,        "en" },
-    { ELangEnglish_Taiwan,      "en_TW" },
-    { ELangEnglish_HongKong,    "en_HK" },
-    { ELangEnglish_Prc,         "en_CN" },
-    { ELangEnglish_Japan,       "en_JP"},
-    { ELangEnglish_Thailand,    "en_TH" },
-    { ELangMalay_Apac,          "ms" }
+    { ELangEnglish_Apac,        "en" },     // 129
+    { ELangEnglish_Taiwan,      "en_TW" },  // 157 ### Not supported by CLDR
+    { ELangEnglish_HongKong,    "en_HK" },  // 158
+    { ELangEnglish_Prc,         "en_CN" },  // 159 ### Not supported by CLDR
+    { ELangEnglish_Japan,       "en_JP"},   // 160 ### Not supported by CLDR
+    { ELangEnglish_Thailand,    "en_TH" },  // 161 ### Not supported by CLDR
+    { ELangMalay_Apac,          "ms" },     // 326
 #endif
+    { 327/*ELangIndonesian_Apac*/,"id_ID" } // 327 - appeared in Symbian^3
 };
 
Index: trunk/src/corelib/tools/qmap.h
===================================================================
--- trunk/src/corelib/tools/qmap.h	(revision 766)
+++ trunk/src/corelib/tools/qmap.h	(revision 769)
@@ -214,5 +214,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef T *pointer;
@@ -282,5 +282,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -385,5 +385,5 @@
     typedef Key key_type;
     typedef T mapped_type;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
     typedef int size_type;
     inline bool empty() const { return isEmpty(); }
@@ -954,5 +954,5 @@
 
     inline QMultiMap &operator+=(const QMultiMap &other)
-    { unite(other); return *this; }
+    { this->unite(other); return *this; }
     inline QMultiMap operator+(const QMultiMap &other) const
     { QMultiMap result = *this; result += other; return result; }
@@ -1029,10 +1029,5 @@
     while (i != end && !qMapLessThanKey<Key>(key, i.key())) {
         if (i.value() == value) {
-#if defined(Q_CC_RVCT)
-            // RVCT has problems with scoping, apparently.
-            i = QMap<Key, T>::erase(i);
-#else
-            i = erase(i);
-#endif
+            i = this->erase(i);
             ++n;
         } else {
Index: trunk/src/corelib/tools/qpoint.cpp
===================================================================
--- trunk/src/corelib/tools/qpoint.cpp	(revision 766)
+++ trunk/src/corelib/tools/qpoint.cpp	(revision 769)
@@ -375,5 +375,5 @@
 {
     d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ')';
-    return d;
+    return d.space();
 }
 #endif
Index: trunk/src/corelib/tools/qregexp.cpp
===================================================================
--- trunk/src/corelib/tools/qregexp.cpp	(revision 766)
+++ trunk/src/corelib/tools/qregexp.cpp	(revision 769)
@@ -524,5 +524,5 @@
 
     In the mode Wildcard, the wildcard characters cannot be
-    escaped. In the mode WildcardUnix, the character '\' escapes the
+    escaped. In the mode WildcardUnix, the character '\\' escapes the
     wildcard.
 
@@ -3775,5 +3775,5 @@
     \value WildcardUnix This is similar to Wildcard but with the
     behavior of a Unix shell. The wildcard characters can be escaped
-    with the character "\".
+    with the character "\\".
 
     \value FixedString The pattern is a fixed string. This is
Index: trunk/src/corelib/tools/qscopedpointer.cpp
===================================================================
--- trunk/src/corelib/tools/qscopedpointer.cpp	(revision 766)
+++ trunk/src/corelib/tools/qscopedpointer.cpp	(revision 769)
@@ -58,5 +58,5 @@
 
     QScopedPointer guarantees that the object pointed to will get deleted when
-    the current scope dissapears.
+    the current scope disappears.
 
     Consider this function which does heap allocations, and have various exit points:
@@ -226,3 +226,58 @@
  */
 
+/*!
+  \class QScopedArrayPointer
+
+  \brief The QScopedArrayPointer class stores a pointer to a
+  dynamically allocated array of objects, and deletes it upon
+  destruction.
+
+  \since 4.6
+  \reentrant
+  \ingroup misc
+
+  A QScopedArrayPointer is a QScopedPointer that defaults to
+  deleting the object it is pointing to with the delete[] operator. It
+  also features operator[] for convenience, so we can write:
+
+  \code
+    void foo()
+    {
+        QScopedArrayPointer<int> i(new int[10]);
+        i[2] = 42;
+        ...
+        return; // our integer array is now deleted using delete[]
+    }
+  \endcode
+*/
+
+/*!
+    \fn QScopedArrayPointer::QScopedArrayPointer(T *p = 0)
+
+    Constructs this QScopedArrayPointer instance and sets its pointer
+    to \a p.
+*/
+
+/*!
+    \fn T *QScopedArrayPointer::operator[](int i)
+
+    Provides access to entry \a i of the scoped pointer's array of
+    objects.
+
+    If the contained pointer is \c null, behavior is undefined.
+
+    \sa isNull()
+*/
+
+/*!
+    \fn T *QScopedArrayPointer::operator[](int i) const
+
+    Provides access to entry \a i of the scoped pointer's array of
+    objects.
+
+    If the contained pointer is \c null, behavior is undefined.
+
+    \sa isNull()
+*/
+
 QT_END_NAMESPACE
Index: trunk/src/corelib/tools/qset.h
===================================================================
--- trunk/src/corelib/tools/qset.h	(revision 766)
+++ trunk/src/corelib/tools/qset.h	(revision 769)
@@ -98,5 +98,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -133,5 +133,5 @@
     public:
         typedef std::bidirectional_iterator_tag iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -189,9 +189,8 @@
     typedef value_type &reference;
     typedef const value_type &const_reference;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
     typedef int size_type;
 
     inline bool empty() const { return isEmpty(); }
-
     // comfort
     inline QSet<T> &operator<<(const T &value) { insert(value); return *this; }
Index: trunk/src/corelib/tools/qsharedpointer_impl.h
===================================================================
--- trunk/src/corelib/tools/qsharedpointer_impl.h	(revision 766)
+++ trunk/src/corelib/tools/qsharedpointer_impl.h	(revision 769)
@@ -133,5 +133,5 @@
         typedef value_type &reference;
         typedef const value_type &const_reference;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
 
         inline T *data() const { return value; }
@@ -542,5 +542,5 @@
     typedef value_type &reference;
     typedef const value_type &const_reference;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
 
     inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
Index: trunk/src/corelib/tools/qstring.cpp
===================================================================
--- trunk/src/corelib/tools/qstring.cpp	(revision 766)
+++ trunk/src/corelib/tools/qstring.cpp	(revision 769)
@@ -891,5 +891,5 @@
 {
     if (sizeof(wchar_t) == sizeof(QChar)) {
-        return fromUtf16((ushort *)string, size);
+        return fromUtf16((const ushort *)string, size);
     } else {
         return fromUcs4((uint *)string, size);
@@ -3191,5 +3191,5 @@
             x++;
     }
-    if((flags & SectionIncludeLeadingSep)) {
+    if((flags & SectionIncludeLeadingSep) && first_i < sections.size()) {
         const qt_section_chunk &section = sections.at(first_i);
         ret.prepend(section.string.left(section.length));
@@ -3863,4 +3863,10 @@
     with a 0.
 
+    This function checks for a Byte Order Mark (BOM). If it is missing,
+    host byte order is assumed.
+
+    This function is comparatively slow.
+    Use QString(const ushort *, int) if possible.
+
     QString makes a deep copy of the Unicode data.
 
@@ -3928,4 +3934,7 @@
     If \a unicode is 0, nothing is copied, but the string is still
     resized to \a size.
+
+    Note that unlike fromUtf16(), this function does not consider BOMs and
+    possibly differing byte ordering.
 
     \sa utf16(), setUnicode()
@@ -4705,4 +4714,6 @@
     Returns the QString as a '\\0\'-terminated array of unsigned
     shorts. The result remains valid until the string is modified.
+
+    The returned string is in host byte order.
 
     \sa unicode()
@@ -7777,5 +7788,5 @@
     if (m_size && m_position == 0 && m_size == m_string->size())
         return *m_string;
-    return QString::fromUtf16(reinterpret_cast<const ushort*>(m_string->unicode() + m_position), m_size);
+    return QString(m_string->unicode() + m_position, m_size);
 }
 
Index: trunk/src/corelib/tools/qstringbuilder.h
===================================================================
--- trunk/src/corelib/tools/qstringbuilder.h	(revision 766)
+++ trunk/src/corelib/tools/qstringbuilder.h	(revision 769)
@@ -72,5 +72,5 @@
 private:
     const int m_size;
-    const char *m_data;
+    const char * const m_data;
 };
 
Index: trunk/src/corelib/tools/qstringlist.cpp
===================================================================
--- trunk/src/corelib/tools/qstringlist.cpp	(revision 766)
+++ trunk/src/corelib/tools/qstringlist.cpp	(revision 769)
@@ -405,15 +405,5 @@
 QString QtPrivate::QStringList_join(const QStringList *that, const QString &sep)
 {
-    int totalLength = 0;
-    const int size = that->size();
-
-    for (int i = 0; i < size; ++i)
-        totalLength += that->at(i).size();
-
-    if(size > 0)
-        totalLength += sep.size() * (size - 1);
-
     QString res;
-    res.reserve(totalLength);
     for (int i = 0; i < that->size(); ++i) {
         if (i)
Index: trunk/src/corelib/tools/qvarlengtharray.h
===================================================================
--- trunk/src/corelib/tools/qvarlengtharray.h	(revision 766)
+++ trunk/src/corelib/tools/qvarlengtharray.h	(revision 769)
@@ -129,7 +129,7 @@
     void realloc(int size, int alloc);
 
-    int a;
-    int s;
-    T *ptr;
+    int a;      // capacity
+    int s;      // size
+    T *ptr;     // data
     union {
         // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size
@@ -194,6 +194,6 @@
     T *oldPtr = ptr;
     int osize = s;
-    // s = asize;
-
+
+    const int copySize = qMin(asize, osize);
     if (aalloc != a) {
         ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
@@ -206,5 +206,4 @@
                 QT_TRY {
                     // copy all the old elements
-                    const int copySize = qMin(asize, osize);
                     while (s < copySize) {
                         new (ptr+s) T(*(oldPtr+s));
@@ -222,6 +221,5 @@
                 }
             } else {
-                qMemCopy(ptr, oldPtr, qMin(asize, osize) * sizeof(T));
-                s = asize;
+                qMemCopy(ptr, oldPtr, copySize * sizeof(T));
             }
         } else {
@@ -230,10 +228,10 @@
         }
     }
-
-    if (QTypeInfo<T>::isComplex) {
+    s = copySize;
+
+    if (QTypeInfo<T>::isComplex) {
+        // destroy remaining old objects
         while (osize > asize)
             (oldPtr+(--osize))->~T();
-        if( oldPtr == ptr )
-            s = osize;
     }
 
Index: trunk/src/corelib/tools/qvector.h
===================================================================
--- trunk/src/corelib/tools/qvector.h	(revision 766)
+++ trunk/src/corelib/tools/qvector.h	(revision 769)
@@ -164,5 +164,5 @@
         T *i;
         typedef std::random_access_iterator_tag  iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef T *pointer;
@@ -197,5 +197,5 @@
         T *i;
         typedef std::random_access_iterator_tag  iterator_category;
-        typedef ptrdiff_t difference_type;
+        typedef qptrdiff difference_type;
         typedef T value_type;
         typedef const T *pointer;
@@ -261,5 +261,5 @@
     typedef value_type& reference;
     typedef const value_type& const_reference;
-    typedef ptrdiff_t difference_type;
+    typedef qptrdiff difference_type;
     typedef iterator Iterator;
     typedef const_iterator ConstIterator;
Index: trunk/src/corelib/xml/qxmlstream.g
===================================================================
--- trunk/src/corelib/xml/qxmlstream.g	(revision 766)
+++ trunk/src/corelib/xml/qxmlstream.g	(revision 769)
@@ -749,5 +749,5 @@
             return true;
         } else if (act > 0) {
-            if (++tos == stack_size)
+            if (++tos == stack_size-1)
                 reallocateStack();
 
Index: trunk/src/corelib/xml/qxmlstream_p.h
===================================================================
--- trunk/src/corelib/xml/qxmlstream_p.h	(revision 766)
+++ trunk/src/corelib/xml/qxmlstream_p.h	(revision 769)
@@ -55,5 +55,5 @@
 #define QXMLSTREAM_P_H
 
-#if defined(Q_OS_VXWORKS) && defined(ERROR)
+#if defined(ERROR)
 #  undef ERROR
 #endif
@@ -62,5 +62,5 @@
 {
 public:
-  enum {
+  enum VariousConstants {
     EOF_SYMBOL = 0,
     AMPERSAND = 5,
@@ -1243,5 +1243,5 @@
             return true;
         } else if (act > 0) {
-            if (++tos == stack_size)
+            if (++tos == stack_size-1)
                 reallocateStack();
 
Index: trunk/src/dbus/qdbusargument.cpp
===================================================================
--- trunk/src/dbus/qdbusargument.cpp	(revision 766)
+++ trunk/src/dbus/qdbusargument.cpp	(revision 769)
@@ -536,5 +536,4 @@
 /*!
     \internal
-    Returns the type signature of the D-Bus type this QDBusArgument
     \since 4.5
 
Index: trunk/src/dbus/qdbusconnection.cpp
===================================================================
--- trunk/src/dbus/qdbusconnection.cpp	(revision 766)
+++ trunk/src/dbus/qdbusconnection.cpp	(revision 769)
@@ -492,4 +492,10 @@
     QDBusMessage::ReplyMessage or QDBusMessage::ErrorMessage.
 
+    If no reply is received within \a timeout milliseconds, an automatic
+    error will be delivered indicating the expiration of the call.
+    The default \a timeout is -1, which will be replaced with an
+    implementation-defined value that is suitable for inter-process
+    communications (generally, 25 seconds).
+
     See the QDBusInterface::call() function for a more friendly way
     of placing calls.
@@ -527,7 +533,12 @@
     immediately. This function is suitable for method calls only. It
     returns an object of type QDBusPendingCall which can be used to
-    track the status of the reply. The \a timeout parameter is used to
-    determine when an auto-generated error reply may be emitted and is
-    also the upper limit for waiting in QDBusPendingCall::waitForFinished().
+    track the status of the reply.
+
+    If no reply is received within \a timeout milliseconds, an automatic
+    error will be delivered indicating the expiration of the call. The
+    default \a timeout is -1, which will be replaced with an
+    implementation-defined value that is suitable for inter-process
+    communications (generally, 25 seconds). This timeout is also the
+    upper limit for waiting in QDBusPendingCall::waitForFinished().
 
     See the QDBusInterface::asyncCall() function for a more friendly way
Index: trunk/src/dbus/qdbusintegrator.cpp
===================================================================
--- trunk/src/dbus/qdbusintegrator.cpp	(revision 766)
+++ trunk/src/dbus/qdbusintegrator.cpp	(revision 769)
@@ -524,5 +524,5 @@
 
     QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message);
-    qDBusDebug() << d << "got message:" << amsg;
+    qDBusDebug() << d << "got message (signal):" << amsg;
 
     return d->handleMessage(amsg) ?
@@ -1661,7 +1661,4 @@
 
     QString busService = QLatin1String(DBUS_SERVICE_DBUS);
-    WatchedServicesHash::mapped_type &bus = watchedServices[busService];
-    bus.refcount = 1;
-    bus.owner = getNameOwnerNoCache(busService);
     connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(),
                   this, SLOT(registerService(QString)));
@@ -1691,7 +1688,21 @@
 {
     Q_ASSERT(pcall->pending);
-    QDBusDispatchLocker locker(PendingCallBlockAction, this);
-    q_dbus_pending_call_block(pcall->pending);
-    // QDBusConnectionPrivate::processFinishedCall() is called automatically
+    Q_ASSERT(!pcall->autoDelete);
+    //Q_ASSERT(pcall->mutex.isLocked()); // there's no such function
+
+    if (pcall->waitingForFinished) {
+        // another thread is already waiting
+        pcall->waitForFinishedCondition.wait(&pcall->mutex);
+    } else {
+        pcall->waitingForFinished = true;
+        pcall->mutex.unlock();
+
+        {
+            QDBusDispatchLocker locker(PendingCallBlockAction, this);
+            q_dbus_pending_call_block(pcall->pending);
+            // QDBusConnectionPrivate::processFinishedCall() is called automatically
+        }
+        pcall->mutex.lock();
+    }
 }
 
@@ -1699,4 +1710,6 @@
 {
     QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection);
+
+    QMutexLocker locker(&call->mutex);
 
     QDBusMessage &msg = call->replyMessage;
@@ -1729,4 +1742,10 @@
     }
 
+    if (call->pending)
+        q_dbus_pending_call_unref(call->pending);
+    call->pending = 0;
+
+    locker.unlock();
+
     // Are there any watchers?
     if (call->watcherHelper)
@@ -1736,10 +1755,8 @@
         emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage);
 
-    if (call->pending)
-        q_dbus_pending_call_unref(call->pending);
-    call->pending = 0;
-
-    if (call->autoDelete)
+    if (call->autoDelete) {
+        Q_ASSERT(!call->waitingForFinished); // can't wait on a call with autoDelete!
         delete call;
+    }
 }
 
@@ -1883,8 +1900,6 @@
     if (isServiceRegisteredByThread(message.service())) {
         // special case for local calls
-        QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate;
-        pcall->sentMessage = message;
+        QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this);
         pcall->replyMessage = sendWithReplyLocal(message);
-        pcall->connection = this;
 
         return pcall;
@@ -1892,6 +1907,5 @@
 
     checkThread();
-    QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate;
-    pcall->sentMessage = message;
+    QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this);
     pcall->ref = 0;
 
@@ -1917,5 +1931,4 @@
 
             pcall->pending = pending;
-            pcall->connection = this;
             q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
 
@@ -1941,5 +1954,5 @@
     Q_ASSERT(pcall);
 
-    // has it already finished (dispatched locally)?
+    // has it already finished with success (dispatched locally)?
     if (pcall->replyMessage.type() == QDBusMessage::ReplyMessage) {
         pcall->setReplyCallback(receiver, returnMethod);
@@ -1949,11 +1962,14 @@
     }
 
+    // either it hasn't finished or it has finished with error
+    if (errorMethod) {
+        pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
+        connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod,
+                Qt::QueuedConnection);
+        pcall->watcherHelper->moveToThread(thread());
+    }
+
     // has it already finished and is an error reply message?
     if (pcall->replyMessage.type() == QDBusMessage::ErrorMessage) {
-        if (errorMethod) {
-            pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
-            connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod);
-            pcall->watcherHelper->moveToThread(thread());
-        }
         processFinishedCall(pcall);
         delete pcall;
@@ -1961,19 +1977,7 @@
     }
 
-    // has it already finished with error?
-    if (pcall->replyMessage.type() != QDBusMessage::InvalidMessage) {
-        delete pcall;
-        return 0;
-    }
-
     pcall->autoDelete = true;
     pcall->ref.ref();
-
     pcall->setReplyCallback(receiver, returnMethod);
-    if (errorMethod) {
-        pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
-        connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod);
-        pcall->watcherHelper->moveToThread(thread());
-    }
 
     return 1;
@@ -2005,5 +2009,6 @@
             entry.signature == hook.signature &&
             entry.obj == hook.obj &&
-            entry.midx == hook.midx) {
+            entry.midx == hook.midx &&
+            entry.argumentMatch == hook.argumentMatch) {
             // no need to compare the parameters if it's the same slot
             return true;        // already there
@@ -2047,8 +2052,5 @@
             if (shouldWatchService(hook.service)) {
                 WatchedServicesHash::mapped_type &data = watchedServices[hook.service];
-                if (data.refcount) {
-                    // already watching
-                    ++data.refcount;
-                } else {
+                if (++data.refcount == 1) {
                     // we need to watch for this service changing
                     QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
@@ -2090,5 +2092,6 @@
             entry.signature == hook.signature &&
             entry.obj == hook.obj &&
-            entry.midx == hook.midx) {
+            entry.midx == hook.midx &&
+            entry.argumentMatch == hook.argumentMatch) {
             // no need to compare the parameters if it's the same slot
             disconnectSignal(it);
@@ -2105,17 +2108,4 @@
 {
     const SignalHook &hook = it.value();
-
-    WatchedServicesHash::Iterator sit = watchedServices.find(hook.service);
-    if (sit != watchedServices.end()) {
-        if (sit.value().refcount == 1) {
-            watchedServices.erase(sit);
-            QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
-            disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
-                          QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
-                          this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
-        } else {
-            --sit.value().refcount;
-        }
-    }
 
     bool erase = false;
@@ -2137,4 +2127,18 @@
         qDBusDebug("Removing rule: %s", hook.matchRule.constData());
         q_dbus_bus_remove_match(connection, hook.matchRule, NULL);
+
+        // Successfully disconnected the signal
+        // Were we watching for this name?
+        WatchedServicesHash::Iterator sit = watchedServices.find(hook.service);
+        if (sit != watchedServices.end()) {
+            if (--sit.value().refcount == 0) {
+                watchedServices.erase(sit);
+                QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
+                disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
+                              QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
+                              this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
+            }
+        }
+
     }
 
Index: trunk/src/dbus/qdbusinterface.cpp
===================================================================
--- trunk/src/dbus/qdbusinterface.cpp	(revision 766)
+++ trunk/src/dbus/qdbusinterface.cpp	(revision 769)
@@ -259,5 +259,5 @@
 {
     _id = QDBusAbstractInterface::qt_metacall(_c, _id, _a);
-    if (_id < 0 || !d_func()->isValid)
+    if (_id < 0 || !d_func()->isValid || !d_func()->metaObject)
         return _id;
     return d_func()->metacall(_c, _id, _a);
Index: trunk/src/dbus/qdbusmacros.h
===================================================================
--- trunk/src/dbus/qdbusmacros.h	(revision 766)
+++ trunk/src/dbus/qdbusmacros.h	(revision 769)
@@ -49,6 +49,8 @@
 #if defined(QDBUS_MAKEDLL)
 # define QDBUS_EXPORT Q_DECL_EXPORT
+#elif defined(QT_SHARED)
+# define QDBUS_EXPORT Q_DECL_IMPORT
 #else
-# define QDBUS_EXPORT Q_DECL_IMPORT
+# define QDBUS_EXPORT
 #endif
 
Index: trunk/src/dbus/qdbusmarshaller.cpp
===================================================================
--- trunk/src/dbus/qdbusmarshaller.cpp	(revision 766)
+++ trunk/src/dbus/qdbusmarshaller.cpp	(revision 769)
@@ -41,4 +41,5 @@
 
 #include "qdbusargument_p.h"
+#include "qdbusmetatype_p.h"
 #include "qdbusutil_p.h"
 
@@ -168,5 +169,5 @@
     QByteArray tmpSignature;
     const char *signature = 0;
-    if (int(id) == qMetaTypeId<QDBusArgument>()) {
+    if (int(id) == QDBusMetaTypeId::argument) {
         // take the signature from the QDBusArgument object we're marshalling
         tmpSignature =
@@ -354,5 +355,5 @@
 
     // intercept QDBusArgument parameters here
-    if (id == qMetaTypeId<QDBusArgument>()) {
+    if (id == QDBusMetaTypeId::argument) {
         QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg);
         QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument);
Index: trunk/src/dbus/qdbuspendingcall.cpp
===================================================================
--- trunk/src/dbus/qdbuspendingcall.cpp	(revision 766)
+++ trunk/src/dbus/qdbuspendingcall.cpp	(revision 769)
@@ -209,4 +209,6 @@
 void QDBusPendingCallPrivate::checkReceivedSignature()
 {
+    // MUST BE CALLED WITH A LOCKED MUTEX!
+
     if (replyMessage.type() == QDBusMessage::InvalidMessage)
         return;                 // not yet finished - no message to
@@ -231,4 +233,6 @@
 void QDBusPendingCallPrivate::waitForFinished()
 {
+    QMutexLocker locker(&mutex);
+
     if (replyMessage.type() != QDBusMessage::InvalidMessage)
         return;                 // already finished
@@ -311,5 +315,9 @@
 bool QDBusPendingCall::isFinished() const
 {
-    return !d || (d->replyMessage.type() != QDBusMessage::InvalidMessage);
+    if (!d)
+        return true; // considered finished
+
+    QMutexLocker locker(&d->mutex);
+    return d->replyMessage.type() != QDBusMessage::InvalidMessage;
 }
 
@@ -330,5 +338,8 @@
 bool QDBusPendingCall::isValid() const
 {
-    return d ? d->replyMessage.type() == QDBusMessage::ReplyMessage : false;
+    if (!d)
+        return false;
+    QMutexLocker locker(&d->mutex);
+    return d->replyMessage.type() == QDBusMessage::ReplyMessage;
 }
 
@@ -344,5 +355,8 @@
 bool QDBusPendingCall::isError() const
 {
-    return d ? d->replyMessage.type() == QDBusMessage::ErrorMessage : true;
+    if (!d)
+        return true; // considered finished and an error
+    QMutexLocker locker(&d->mutex);
+    return d->replyMessage.type() == QDBusMessage::ErrorMessage;
 }
 
@@ -357,6 +371,8 @@
 QDBusError QDBusPendingCall::error() const
 {
-    if (d)
+    if (d) {
+        QMutexLocker locker(&d->mutex);
         return d->replyMessage;
+    }
 
     // not connected, return an error
@@ -379,5 +395,8 @@
 QDBusMessage QDBusPendingCall::reply() const
 {
-    return d ? d->replyMessage : QDBusMessage::createError(error());
+    if (!d)
+        return QDBusMessage::createError(error());
+    QMutexLocker locker(&d->mutex);
+    return d->replyMessage;
 }
 
@@ -440,7 +459,6 @@
     if (msg.type() == QDBusMessage::ErrorMessage ||
         msg.type() == QDBusMessage::ReplyMessage) {
-        d = new QDBusPendingCallPrivate;
+        d = new QDBusPendingCallPrivate(QDBusMessage(), 0);
         d->replyMessage = msg;
-        d->connection = 0;
     }
 
@@ -472,7 +490,8 @@
 {
     if (d) {                    // QDBusPendingCall::d
+        QMutexLocker locker(&d->mutex);
         if (!d->watcherHelper) {
             d->watcherHelper = new QDBusPendingCallWatcherHelper;
-            if (isFinished()) {
+            if (d->replyMessage.type() != QDBusMessage::InvalidMessage) {
                 // cause a signal emission anyways
                 QMetaObject::invokeMethod(d->watcherHelper, "finished", Qt::QueuedConnection);
Index: trunk/src/dbus/qdbuspendingcall_p.h
===================================================================
--- trunk/src/dbus/qdbuspendingcall_p.h	(revision 766)
+++ trunk/src/dbus/qdbuspendingcall_p.h	(revision 769)
@@ -58,4 +58,6 @@
 #include <qpointer.h>
 #include <qlist.h>
+#include <qmutex.h>
+#include <qwaitcondition.h>
 
 #include "qdbusmessage.h"
@@ -72,15 +74,10 @@
 {
 public:
-    QDBusMessage sentMessage;
-    QDBusMessage replyMessage;
-//    QDBusMessage pendingReplyMessage; // used in the local loop
-    QDBusPendingCallWatcherHelper *watcherHelper;
-    DBusPendingCall *pending;
-    QDBusConnectionPrivate *connection;
+    // {
+    //     set only during construction:
+    const QDBusMessage sentMessage;
+    QDBusConnectionPrivate * const connection;
 
-    QString expectedReplySignature;
-    int expectedReplyCount;
-
-    // for the callback
+    // for the callback mechanism (see setReplyCallback and QDBusConnectionPrivate::sendWithReplyAsync)
     QPointer<QObject> receiver;
     QList<int> metaTypes;
@@ -88,6 +85,22 @@
 
     bool autoDelete;
+    // }
 
-    QDBusPendingCallPrivate() : watcherHelper(0), pending(0), autoDelete(false)
+    mutable QMutex mutex;
+    QWaitCondition waitForFinishedCondition;
+
+    // {
+    //    protected by the mutex above:
+    QDBusPendingCallWatcherHelper *watcherHelper;
+    QDBusMessage replyMessage;
+    DBusPendingCall *pending;
+    volatile bool waitingForFinished;
+
+    QString expectedReplySignature;
+    int expectedReplyCount;
+    // }
+
+    QDBusPendingCallPrivate(const QDBusMessage &sent, QDBusConnectionPrivate *connection)
+        : sentMessage(sent), connection(connection), autoDelete(false), watcherHelper(0), pending(0), waitingForFinished(false)
     { }
     ~QDBusPendingCallPrivate();
Index: trunk/src/dbus/qdbuspendingreply.cpp
===================================================================
--- trunk/src/dbus/qdbuspendingreply.cpp	(revision 766)
+++ trunk/src/dbus/qdbuspendingreply.cpp	(revision 769)
@@ -253,5 +253,5 @@
 void QDBusPendingReplyData::assign(const QDBusMessage &message)
 {
-    d = new QDBusPendingCallPrivate; // drops the reference to the old one
+    d = new QDBusPendingCallPrivate(QDBusMessage(), 0); // drops the reference to the old one
     d->replyMessage = message;
 }
@@ -272,4 +272,5 @@
 {
     Q_ASSERT(d);
+    QMutexLocker locker(&d->mutex);
     d->setMetaTypes(count, types);
     d->checkReceivedSignature();
Index: trunk/src/gui/dialogs/qcolordialog.cpp
===================================================================
--- trunk/src/gui/dialogs/qcolordialog.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qcolordialog.cpp	(revision 769)
@@ -645,4 +645,5 @@
     void mouseMoveEvent(QMouseEvent *);
     void mousePressEvent(QMouseEvent *);
+    void resizeEvent(QResizeEvent *);
 
 private:
@@ -655,5 +656,5 @@
     void setCol(const QPoint &pt);
 
-    QPixmap *pix;
+    QPixmap pix;
 };
 
@@ -791,11 +792,25 @@
 
 QPoint QColorPicker::colPt()
-{ return QPoint((360-hue)*(pWidth-1)/360, (255-sat)*(pHeight-1)/255); }
+{
+    QRect r = contentsRect();
+    return QPoint((360 - hue) * (r.width() - 1) / 360, (255 - sat) * (r.height() - 1) / 255);
+}
+
 int QColorPicker::huePt(const QPoint &pt)
-{ return 360 - pt.x()*360/(pWidth-1); }
+{
+    QRect r = contentsRect();
+    return 360 - pt.x() * 360 / (r.width() - 1);
+}
+
 int QColorPicker::satPt(const QPoint &pt)
-{ return 255 - pt.y()*255/(pHeight-1) ; }
+{
+    QRect r = contentsRect();
+    return 255 - pt.y() * 255 / (r.height() - 1);
+}
+
 void QColorPicker::setCol(const QPoint &pt)
-{ setCol(huePt(pt), satPt(pt)); }
+{
+    setCol(huePt(pt), satPt(pt));
+}
 
 QColorPicker::QColorPicker(QWidget* parent)
@@ -805,9 +820,72 @@
     setCol(150, 255);
 
-    QImage img(pWidth, pHeight, QImage::Format_RGB32);
+    setAttribute(Qt::WA_NoSystemBackground);
+    setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
+}
+
+QColorPicker::~QColorPicker()
+{
+}
+
+QSize QColorPicker::sizeHint() const
+{
+    return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
+}
+
+void QColorPicker::setCol(int h, int s)
+{
+    int nhue = qMin(qMax(0,h), 359);
+    int nsat = qMin(qMax(0,s), 255);
+    if (nhue == hue && nsat == sat)
+        return;
+
+    QRect r(colPt(), QSize(20,20));
+    hue = nhue; sat = nsat;
+    r = r.united(QRect(colPt(), QSize(20,20)));
+    r.translate(contentsRect().x()-9, contentsRect().y()-9);
+    //    update(r);
+    repaint(r);
+}
+
+void QColorPicker::mouseMoveEvent(QMouseEvent *m)
+{
+    QPoint p = m->pos() - contentsRect().topLeft();
+    setCol(p);
+    emit newCol(hue, sat);
+}
+
+void QColorPicker::mousePressEvent(QMouseEvent *m)
+{
+    QPoint p = m->pos() - contentsRect().topLeft();
+    setCol(p);
+    emit newCol(hue, sat);
+}
+
+void QColorPicker::paintEvent(QPaintEvent* )
+{
+    QPainter p(this);
+    drawFrame(&p);
+    QRect r = contentsRect();
+
+    p.drawPixmap(r.topLeft(), pix);
+    QPoint pt = colPt() + r.topLeft();
+    p.setPen(Qt::black);
+
+    p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
+    p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
+
+}
+
+void QColorPicker::resizeEvent(QResizeEvent *ev)
+{
+    QFrame::resizeEvent(ev);
+
+    int w = width() - frameWidth() * 2;
+    int h = height() - frameWidth() * 2;
+    QImage img(w, h, QImage::Format_RGB32);
     int x, y;
     uint *pixel = (uint *) img.scanLine(0);
-    for (y = 0; y < pHeight; y++) {
-        const uint *end = pixel + pWidth;
+    for (y = 0; y < h; y++) {
+        const uint *end = pixel + w;
         x = 0;
         while (pixel < end) {
@@ -820,62 +898,7 @@
         }
     }
-    pix = new QPixmap(QPixmap::fromImage(img));
-    setAttribute(Qt::WA_NoSystemBackground);
-    setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
-}
-
-QColorPicker::~QColorPicker()
-{
-    delete pix;
-}
-
-QSize QColorPicker::sizeHint() const
-{
-    return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
-}
-
-void QColorPicker::setCol(int h, int s)
-{
-    int nhue = qMin(qMax(0,h), 359);
-    int nsat = qMin(qMax(0,s), 255);
-    if (nhue == hue && nsat == sat)
-        return;
-
-    QRect r(colPt(), QSize(20,20));
-    hue = nhue; sat = nsat;
-    r = r.united(QRect(colPt(), QSize(20,20)));
-    r.translate(contentsRect().x()-9, contentsRect().y()-9);
-    //    update(r);
-    repaint(r);
-}
-
-void QColorPicker::mouseMoveEvent(QMouseEvent *m)
-{
-    QPoint p = m->pos() - contentsRect().topLeft();
-    setCol(p);
-    emit newCol(hue, sat);
-}
-
-void QColorPicker::mousePressEvent(QMouseEvent *m)
-{
-    QPoint p = m->pos() - contentsRect().topLeft();
-    setCol(p);
-    emit newCol(hue, sat);
-}
-
-void QColorPicker::paintEvent(QPaintEvent* )
-{
-    QPainter p(this);
-    drawFrame(&p);
-    QRect r = contentsRect();
-
-    p.drawPixmap(r.topLeft(), *pix);
-    QPoint pt = colPt() + r.topLeft();
-    p.setPen(Qt::black);
-
-    p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
-    p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
-
-}
+    pix = QPixmap::fromImage(img);
+}
+
 
 class QColSpinBox : public QSpinBox
@@ -1079,6 +1102,5 @@
 #ifdef QT_SMALL_COLORDIALOG
 #  ifdef Q_WS_S60
-    QS60Data s60Data = QS60Data();
-    const bool nonTouchUI = !s60Data.hasTouchscreen;
+    const bool nonTouchUI = !S60->hasTouchscreen;
 #  elif defined Q_WS_MAEMO_5
     const bool nonTouchUI = false;
@@ -1507,6 +1529,5 @@
 #if defined(QT_SMALL_COLORDIALOG)
 #  if defined(Q_WS_S60)
-    QS60Data s60Data = QS60Data();
-    const bool nonTouchUI = !s60Data.hasTouchscreen;
+    const bool nonTouchUI = !S60->hasTouchscreen;
 #  elif defined(Q_WS_MAEMO_5)
     const bool nonTouchUI = false;
Index: trunk/src/gui/dialogs/qcolordialog_mac.mm
===================================================================
--- trunk/src/gui/dialogs/qcolordialog_mac.mm	(revision 766)
+++ trunk/src/gui/dialogs/qcolordialog_mac.mm	(revision 769)
@@ -97,4 +97,5 @@
 - (void)showColorPanel;
 - (void)exec;
+- (void)setResultSet:(BOOL)result;
 @end
 
@@ -157,4 +158,9 @@
     delete mQtColor;
     [super dealloc];
+}
+
+- (void)setResultSet:(BOOL)result
+{
+    mResultSet = result;
 }
 
@@ -321,5 +327,5 @@
                 mPriv->colorDialog()->accept();
             }
-        }
+        } 
     }
 }
@@ -434,5 +440,5 @@
         [colorPanel setDelegate:static_cast<QCocoaColorPanelDelegate *>(delegate)];
     }
-
+    [delegate setResultSet:false];
     setCocoaPanelColor(initial);
     [static_cast<QCocoaColorPanelDelegate *>(delegate) showColorPanel];
Index: trunk/src/gui/dialogs/qdialog.cpp
===================================================================
--- trunk/src/gui/dialogs/qdialog.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qdialog.cpp	(revision 769)
@@ -70,5 +70,4 @@
 #   include "qcolordialog.h"
 #   include "qwizard.h"
-#   include "qmenubar.h"
 #endif
 
@@ -416,6 +415,13 @@
      }
 #else
-    if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Resize ))
-        adjustPosition(parentWidget());
+    if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Resize )) {
+        if (!testAttribute(Qt::WA_Moved)) {
+            Qt::WindowStates state = windowState();
+            adjustPosition(parentWidget());
+            setAttribute(Qt::WA_Moved, false); // not really an explicit position
+            if (state != windowState())
+                setWindowState(state);
+        }
+    }
 #endif
     return result;
@@ -523,10 +529,4 @@
 
 #ifdef Q_OS_SYMBIAN
-#ifndef QT_NO_MENUBAR
-    QMenuBar *menuBar = 0;
-    if (!findChild<QMenuBar *>())
-        menuBar = new QMenuBar(this);
-#endif
-
     if (qobject_cast<QFileDialog *>(this) || qobject_cast<QFontDialog *>(this) ||
         qobject_cast<QColorDialog *>(this) || qobject_cast<QWizard *>(this))
@@ -560,11 +560,4 @@
 #endif //QT_NO_MENUBAR
 #endif //Q_WS_WINCE_WM
-#ifdef Q_OS_SYMBIAN
-#ifndef QT_NO_MENUBAR
-    else if (menuBar)
-        delete menuBar;
-#endif //QT_NO_MENUBAR
-#endif //Q_OS_SYMBIAN
-
     return res;
 }
@@ -808,9 +801,9 @@
 {
     if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) {
-	Qt::WindowStates  state = windowState();
+        Qt::WindowStates  state = windowState();
         adjustPosition(parentWidget());
         setAttribute(Qt::WA_Moved, false); // not really an explicit position
-	if (state != windowState())
-	    setWindowState(state);
+        if (state != windowState())
+            setWindowState(state);
     }
 }
@@ -912,24 +905,31 @@
                 cbaHeight = qt_TSize2QSize(bgContainer->Size()).height();
             }
-            p.setY(S60->screenHeightInPixels-height()-cbaHeight);
+            p.setY(S60->screenHeightInPixels - height() - cbaHeight);
             p.setX(0);
         } else {
             const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
-            TRect cbaRect = TRect();
-            AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect);
-            AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation();
-            switch (cbaLocation) {
-            case AknLayoutUtils::EAknCbaLocationBottom:
-                p.setY(S60->screenHeightInPixels - height()-cbaRect.Height());
-                p.setX((S60->screenWidthInPixels - width())>>1);
-                break;
-            case AknLayoutUtils::EAknCbaLocationRight:
-                p.setY((S60->screenHeightInPixels - height())>>1);
-                p.setX(qMax(0,S60->screenWidthInPixels-width()-scrollbarWidth-cbaRect.Width()));
-                break;
-            case AknLayoutUtils::EAknCbaLocationLeft:
-                p.setY((S60->screenHeightInPixels - height())>>1);
-                p.setX(qMax(0,scrollbarWidth+cbaRect.Width()));
-                break;
+            TRect staConTopRect = TRect();
+            AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect);
+            if (staConTopRect.IsEmpty()) {
+                TRect cbaRect = TRect();
+                AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect);
+                AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation();
+                switch (cbaLocation) {
+                case AknLayoutUtils::EAknCbaLocationBottom:
+                    p.setY(S60->screenHeightInPixels - height() - cbaRect.Height());
+                    p.setX((S60->screenWidthInPixels - width()) >> 1);
+                    break;
+                case AknLayoutUtils::EAknCbaLocationRight:
+                    p.setY((S60->screenHeightInPixels - height()) >> 1);
+                    p.setX(qMax(0,S60->screenWidthInPixels - width() - scrollbarWidth - cbaRect.Width()));
+                    break;
+                case AknLayoutUtils::EAknCbaLocationLeft:
+                    p.setY((S60->screenHeightInPixels - height()) >> 1);
+                    p.setX(qMax(0,scrollbarWidth + cbaRect.Width()));
+                    break;
+                }
+            } else {
+                p.setY((S60->screenHeightInPixels - height()) >> 1);
+                p.setX(qMax(0,S60->screenWidthInPixels - width()));
             }
         }
Index: trunk/src/gui/dialogs/qfiledialog.cpp
===================================================================
--- trunk/src/gui/dialogs/qfiledialog.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qfiledialog.cpp	(revision 769)
@@ -230,9 +230,8 @@
 
     \value HideNameFilterDetails Indicates if the is hidden or not.
-    This value is obsolete and does nothing since Qt 4.5:
 
     \value DontUseSheet In previous versions of Qt, the static
     functions would create a sheet by default if the static function
-    was given a parent. This is no longer supported in Qt 4.5, The
+    was given a parent. This is no longer supported and does nothing in Qt 4.5, The
     static functions will always be an application modal dialog. If
     you want to use sheets, use QFileDialog::open() instead.
Index: trunk/src/gui/dialogs/qfiledialog.ui
===================================================================
--- trunk/src/gui/dialogs/qfiledialog.ui	(revision 766)
+++ trunk/src/gui/dialogs/qfiledialog.ui	(revision 769)
@@ -84,4 +84,10 @@
         <string>Back</string>
        </property>
+       <property name="accessibleName">
+        <string>Back</string>
+       </property>
+       <property name="accessibleDescription">
+        <string>Go back</string>
+       </property>
       </widget>
      </item>
@@ -91,4 +97,10 @@
         <string>Forward</string>
        </property>
+       <property name="accessibleName">
+        <string>Forward</string>
+       </property>
+       <property name="accessibleDescription">
+        <string>Go forward</string>
+       </property>
       </widget>
      </item>
@@ -98,4 +110,10 @@
         <string>Parent Directory</string>
        </property>
+       <property name="accessibleName">
+        <string>Parent Directory</string>
+       </property>
+       <property name="accessibleDescription">
+        <string>Go to the parent directory</string>
+       </property>
       </widget>
      </item>
@@ -105,4 +123,10 @@
         <string>Create New Folder</string>
        </property>
+       <property name="accessibleName">
+        <string>Create New Folder</string>
+       </property>
+       <property name="accessibleDescription">
+        <string>Create a New Folder</string>
+       </property>
       </widget>
      </item>
@@ -112,4 +136,10 @@
         <string>List View</string>
        </property>
+       <property name="accessibleName">
+        <string>List View</string>
+       </property>
+       <property name="accessibleDescription">
+        <string>Change to list view mode</string>
+       </property>
       </widget>
      </item>
@@ -118,4 +148,10 @@
        <property name="toolTip" >
         <string>Detail View</string>
+       </property>
+       <property name="accessibleName">
+        <string>Detail View</string>
+       </property>
+       <property name="accessibleDescription">
+        <string>Change to detail view mode</string>
        </property>
       </widget>
Index: trunk/src/gui/dialogs/qfilesystemmodel.cpp
===================================================================
--- trunk/src/gui/dialogs/qfilesystemmodel.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qfilesystemmodel.cpp	(revision 769)
@@ -1361,4 +1361,14 @@
         return d->index(rootPath());
 
+    //We remove the watcher on the previous path
+    if (!rootPath().isEmpty() && rootPath() != QLatin1String(".")) {
+        //This remove the watcher for the old rootPath
+        d->fileInfoGatherer.removePath(rootPath());
+        //This line "marks" the node as dirty, so the next fetchMore
+        //call on the path will ask the gatherer to install a watcher again
+        //But it doesn't re-fetch everything
+        d->node(rootPath())->populatedChildren = false;
+    }
+
     // We have a new valid root path
     d->rootDir = newPathDir;
Index: trunk/src/gui/dialogs/qfontdialog.cpp
===================================================================
--- trunk/src/gui/dialogs/qfontdialog.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qfontdialog.cpp	(revision 769)
@@ -990,32 +990,22 @@
 {
     Q_D(QFontDialog);
-    if (visible)
-        d->selectedFont = QFont();
-
-#if defined(Q_WS_MAC)
-    bool isCurrentlyVisible = (isVisible() || d->delegate);
-
-    if (!visible == !isCurrentlyVisible)
+    if (visible) {
+        if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
+            return;
+    } else if  (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
         return;
-
-    if (visible) {
-        if (!(d->opts & DontUseNativeDialog) && QFontDialogPrivate::sharedFontPanelAvailable) {
-            d->delegate = QFontDialogPrivate::openCocoaFontPanel(
-                              currentFont(), parentWidget(), windowTitle(), options(), d);
-            QFontDialogPrivate::sharedFontPanelAvailable = false;
-            return;
+#ifdef Q_WS_MAC
+    if (d->canBeNativeDialog()){
+        if (d->setVisible_sys(visible)){
+            d->nativeDialogInUse = true;
+            // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
+            // updates the state correctly, but skips showing the non-native version:
+            setAttribute(Qt::WA_DontShowOnScreen, true);
+        } else {
+            d->nativeDialogInUse = false;
+            setAttribute(Qt::WA_DontShowOnScreen, false);
         }
-
-        setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags);
-    } else {
-        if (d->delegate) {
-            QFontDialogPrivate::closeCocoaFontPanel(d->delegate);
-            d->delegate = 0;
-            QFontDialogPrivate::sharedFontPanelAvailable = true;
-            return;
-        }
-    }
-#endif
-
+    }
+#endif // Q_WS_MAC
     QDialog::setVisible(visible);
 }
@@ -1033,9 +1023,12 @@
     QDialog::done(result);
     if (result == Accepted) {
-        d->selectedFont = currentFont();
+        // We check if this is the same font we had before, if so we emit currentFontChanged
+        QFont selectedFont = currentFont();
+        if(selectedFont != d->selectedFont)
+            emit(currentFontChanged(selectedFont));
+        d->selectedFont = selectedFont;
         emit fontSelected(d->selectedFont);
-    } else {
+    } else
         d->selectedFont = QFont();
-    }
     if (d->receiverToDisconnectOnClose) {
         disconnect(this, SIGNAL(fontSelected(QFont)),
@@ -1046,4 +1039,21 @@
 }
 
+#ifdef Q_WS_MAC
+bool QFontDialogPrivate::canBeNativeDialog()
+{
+    Q_Q(QFontDialog);
+    if (nativeDialogInUse)
+        return true;
+    if (q->testAttribute(Qt::WA_DontShowOnScreen))
+        return false;
+    if (opts & QFontDialog::DontUseNativeDialog)
+        return false;
+
+    QLatin1String staticName(QFontDialog::staticMetaObject.className());
+    QLatin1String dynamicName(q->metaObject()->className());
+    return (staticName == dynamicName);
+}
+#endif // Q_WS_MAC
+
 /*!
     \fn QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget* parent, const char* name)
Index: trunk/src/gui/dialogs/qfontdialog.h
===================================================================
--- trunk/src/gui/dialogs/qfontdialog.h	(revision 766)
+++ trunk/src/gui/dialogs/qfontdialog.h	(revision 769)
@@ -132,4 +132,7 @@
     Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int))
     Q_PRIVATE_SLOT(d_func(), void _q_updateSample())
+#if defined(Q_WS_MAC)
+    Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
+#endif
 };
 
Index: trunk/src/gui/dialogs/qfontdialog_mac.mm
===================================================================
--- trunk/src/gui/dialogs/qfontdialog_mac.mm	(revision 766)
+++ trunk/src/gui/dialogs/qfontdialog_mac.mm	(revision 769)
@@ -50,4 +50,5 @@
 #include <private/qt_cocoa_helpers_mac_p.h>
 #include <private/qt_mac_p.h>
+#include <qabstracteventdispatcher.h>
 #include <qdebug.h>
 #import <AppKit/AppKit.h>
@@ -373,5 +374,10 @@
             mModalSession = 0;
         }
-
+        // Hack alert!
+        // Since this code path was never intended to be followed when starting from exec
+        // we need to force the dialog to communicate the new font, otherwise the signal
+        // won't get emitted.
+        if(code == NSOKButton)
+            mPriv->sampleEdit->setFont([self qtFont]);
         mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected);
     } else {
@@ -568,5 +574,4 @@
         }
     }
-
     return delegate;
 }
@@ -641,4 +646,143 @@
 }
 
+void *QFontDialogPrivate::_q_constructNativePanel()
+{
+    QMacCocoaAutoReleasePool pool;
+
+    bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists];
+    NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel];
+    [sharedFontPanel setHidesOnDeactivate:false];
+
+    // hack to ensure that QCocoaApplication's validModesForFontPanel:
+    // implementation is honored
+    if (!sharedFontPanelExisted) {
+        [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel];
+        [sharedFontPanel close];
+    }
+
+    NSPanel *ourPanel = 0;
+    NSView *stolenContentView = 0;
+    NSButton *okButton = 0;
+    NSButton *cancelButton = 0;
+
+    CGFloat dialogExtraWidth = 0.0;
+    CGFloat dialogExtraHeight = 0.0;
+
+    // compute dialogExtra{Width,Height}
+    dialogExtraWidth = 2.0 * DialogSideMargin;
+    dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight
+                        + ButtonBottomMargin;
+
+    // compute initial contents rectangle
+    NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]];
+    contentRect.size.width += dialogExtraWidth;
+    contentRect.size.height += dialogExtraHeight;
+
+    // create the new panel
+    ourPanel = [[NSPanel alloc] initWithContentRect:contentRect
+                styleMask:StyleMask
+                    backing:NSBackingStoreBuffered
+                        defer:YES];
+    [ourPanel setReleasedWhenClosed:YES];
+
+    stolenContentView = [sharedFontPanel contentView];
+
+    // steal the font panel's contents view
+    [stolenContentView retain];
+    [sharedFontPanel setContentView:0];
+
+    {
+        // create a new content view and add the stolen one as a subview
+        NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } };
+        NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect];
+        [ourContentView addSubview:stolenContentView];
+
+        // create OK and Cancel buttons and add these as subviews
+        okButton = macCreateButton("&OK", ourContentView);
+        cancelButton = macCreateButton("Cancel", ourContentView);
+
+        [ourPanel setContentView:ourContentView];
+        [ourPanel setDefaultButtonCell:[okButton cell]];
+    }
+    // create a delegate and set it
+    QCocoaFontPanelDelegate *delegate =
+            [[QCocoaFontPanelDelegate alloc] initWithFontPanel:sharedFontPanel
+                                             stolenContentView:stolenContentView
+                                                      okButton:okButton
+                                                  cancelButton:cancelButton
+                                                          priv:this
+                                                    extraWidth:dialogExtraWidth
+                                                   extraHeight:dialogExtraHeight];
+    [ourPanel setDelegate:delegate];
+    [[NSFontManager sharedFontManager] setDelegate:delegate];
+#ifdef QT_MAC_USE_COCOA
+    [[NSFontManager sharedFontManager] setTarget:delegate];
+#endif
+    setFont(delegate, QApplication::font());
+
+    {
+        // hack to get correct initial layout
+        NSRect frameRect = [ourPanel frame];
+        frameRect.size.width += 1.0;
+        [ourPanel setFrame:frameRect display:NO];
+        frameRect.size.width -= 1.0;
+        frameRect.size = [delegate windowWillResize:ourPanel toSize:frameRect.size];
+        [ourPanel setFrame:frameRect display:NO];
+        [ourPanel center];
+    }
+    NSString *title = @"Select font";
+    [ourPanel setTitle:title];
+
+    [delegate setModalSession:[NSApp beginModalSessionForWindow:ourPanel]];
+    return delegate;
+}
+
+void QFontDialogPrivate::mac_nativeDialogModalHelp()
+{
+    // Copied from QFileDialogPrivate
+    // Do a queued meta-call to open the native modal dialog so it opens after the new
+    // event loop has started to execute (in QDialog::exec). Using a timer rather than
+    // a queued meta call is intentional to ensure that the call is only delivered when
+    // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
+    // running (which is the case if e.g a top-most QEventLoop has been
+    // interrupted, and the second-most event loop has not yet been reactivated (regardless
+    // if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
+    if (nativeDialogInUse) {
+        Q_Q(QFontDialog);
+        QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
+    }
+}
+
+// The problem with the native font dialog is that OS X does not
+// offer a proper dialog, but a panel (i.e. without Ok and Cancel buttons).
+// This means we need to "construct" a native dialog by taking the panel
+// and "adding" the buttons.
+void QFontDialogPrivate::_q_macRunNativeAppModalPanel()
+{
+    QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
+    Q_Q(QFontDialog);
+    QCocoaFontPanelDelegate *delegate = (QCocoaFontPanelDelegate *)_q_constructNativePanel();
+    NSWindow *ourPanel = [delegate actualPanel];
+    [ourPanel retain];
+    int rval = [NSApp runModalForWindow:ourPanel];
+    QAbstractEventDispatcher::instance()->interrupt();
+    [ourPanel release];
+    [delegate cleanUpAfterMyself];
+    [delegate release];
+    bool isOk = (rval == NSOKButton);
+    if(isOk)
+        rescode = QDialog::Accepted;
+    else
+        rescode = QDialog::Rejected;
+}
+
+bool QFontDialogPrivate::setVisible_sys(bool visible)
+{
+    Q_Q(QFontDialog);
+    if (!visible == q->isHidden())
+        return false;
+    return visible;
+}
+
 QT_END_NAMESPACE
 
Index: trunk/src/gui/dialogs/qfontdialog_p.h
===================================================================
--- trunk/src/gui/dialogs/qfontdialog_p.h	(revision 766)
+++ trunk/src/gui/dialogs/qfontdialog_p.h	(revision 769)
@@ -153,4 +153,10 @@
 
     void *delegate;
+    bool nativeDialogInUse;
+    bool canBeNativeDialog();
+    bool setVisible_sys(bool visible);
+    void *_q_constructNativePanel();
+    void _q_macRunNativeAppModalPanel();
+    void mac_nativeDialogModalHelp();
 
     static bool sharedFontPanelAvailable;
Index: trunk/src/gui/dialogs/qmessagebox.cpp
===================================================================
--- trunk/src/gui/dialogs/qmessagebox.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qmessagebox.cpp	(revision 769)
@@ -66,4 +66,8 @@
 #include <QtGui/qclipboard.h>
 
+#ifndef QT_NO_STYLE_S60
+#include <qs60style.h>
+#endif
+
 #ifdef Q_WS_WINCE
 extern bool qt_wince_is_mobile();    //defined in qguifunctions_wince.cpp
@@ -315,4 +319,5 @@
             width = hardLimit;
         }
+    }
 #ifdef Q_WS_S60
         // in S60 portait messageBoxes should always occupy maximum width
@@ -324,5 +329,4 @@
         }
 #endif
-    }
 
     if (informativeLabel) {
@@ -354,4 +358,14 @@
                      ? layout->totalHeightForWidth(width)
                      : layout->totalMinimumSize().height();
+
+#ifndef QT_NO_STYLE_S60
+        QS60Style *s60Style = 0;
+        s60Style = qobject_cast<QS60Style *>(QApplication::style());
+
+        //use custom pixel metric to deduce the minimum height of the messagebox
+        if (s60Style)
+            height = qMax(height, s60Style->pixelMetric((QStyle::PixelMetric)PM_MessageBoxHeight));
+#endif
+
     q->setFixedSize(width, height);
     QCoreApplication::removePostedEvents(q, QEvent::LayoutRequest);
Index: trunk/src/gui/dialogs/qprintdialog.h
===================================================================
--- trunk/src/gui/dialogs/qprintdialog.h	(revision 766)
+++ trunk/src/gui/dialogs/qprintdialog.h	(revision 769)
@@ -57,5 +57,5 @@
 class QPrinter;
 
-#if (defined (Q_OS_UNIX) && !defined(QTOPIA_PRINTDIALOG) && !defined(Q_WS_MAC)) || defined (Q_WS_PM)
+#if (defined (Q_OS_UNIX) && !defined(QTOPIA_PRINTDIALOG) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)) || defined (Q_WS_PM)
 class QUnixPrintWidgetPrivate;
 
@@ -98,7 +98,7 @@
 
 #if defined (Q_OS_UNIX) && defined (QT3_SUPPORT)
-    void setPrinter(QPrinter *, bool = false);
-    QPrinter *printer() const;
-    void addButton(QPushButton *button);
+    QT3_SUPPORT void setPrinter(QPrinter *, bool = false);
+    QT3_SUPPORT QPrinter *printer() const;
+    QT3_SUPPORT void addButton(QPushButton *button);
 #endif
 
Index: trunk/src/gui/dialogs/qprintdialog_unix.cpp
===================================================================
--- trunk/src/gui/dialogs/qprintdialog_unix.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qprintdialog_unix.cpp	(revision 769)
@@ -155,4 +155,7 @@
     void setupPrinter();
     void setOptionsPane(QPrintDialogPrivate *pane);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+    void setCupsProperties();
+#endif
 
 // slots
@@ -970,5 +973,5 @@
 void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked()
 {
-    if (propertiesDialog == 0) {
+    if (!propertiesDialog) {
         propertiesDialog = new QPrintPropertiesDialog(q);
         propertiesDialog->setResult(QDialog::Rejected);
@@ -989,4 +992,33 @@
     propertiesDialog->exec();
 }
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+void QUnixPrintWidgetPrivate::setCupsProperties()
+{
+    if (cups && QCUPSSupport::isAvailable() && cups->pageSizes()) {
+        QPrintEngine *engine = printer->printEngine();
+        const ppd_option_t* pageSizes = cups->pageSizes();
+        QByteArray cupsPageSize;
+        for (int i = 0; i < pageSizes->num_choices; ++i) {
+            if (static_cast<int>(pageSizes->choices[i].marked) == 1)
+                cupsPageSize = pageSizes->choices[i].choice;
+        }
+        engine->setProperty(PPK_CupsStringPageSize, QString::fromLatin1(cupsPageSize));
+        engine->setProperty(PPK_CupsOptions, cups->options());
+
+        QRect pageRect = cups->pageRect(cupsPageSize);
+        engine->setProperty(PPK_CupsPageRect, pageRect);
+
+        QRect paperRect = cups->paperRect(cupsPageSize);
+        engine->setProperty(PPK_CupsPaperRect, paperRect);
+
+        for (int ps = 0; ps < QPrinter::NPaperSize; ++ps) {
+            QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
+            if (size.width == paperRect.width() && size.height == paperRect.height())
+                printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
+        }
+    }
+}
+#endif
 
 void QUnixPrintWidgetPrivate::setupPrinter()
@@ -1018,4 +1050,8 @@
     if (propertiesDialog && propertiesDialog->result() == QDialog::Accepted)
         propertiesDialog->setupPrinter();
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+    if (!propertiesDialog)
+        setCupsProperties();
+#endif
 }
 
Index: trunk/src/gui/dialogs/qprintpreviewdialog.cpp
===================================================================
--- trunk/src/gui/dialogs/qprintpreviewdialog.cpp	(revision 766)
+++ trunk/src/gui/dialogs/qprintpreviewdialog.cpp	(revision 769)
@@ -274,5 +274,18 @@
     QVBoxLayout *vboxLayout = new QVBoxLayout;
     vboxLayout->setContentsMargins(0, 0, 0, 0);
+#ifdef Q_WS_MAC
+    // We query the widgets about their size and then we fix the size.
+    // This should do the trick for the laying out part...
+    QSize pageNumEditSize, pageNumLabelSize;
+    pageNumEditSize = pageNumEdit->minimumSizeHint();
+    pageNumLabelSize = pageNumLabel->minimumSizeHint();
+    pageNumEdit->resize(pageNumEditSize);
+    pageNumLabel->resize(pageNumLabelSize);
+#endif
     QFormLayout *formLayout = new QFormLayout;
+#ifdef Q_WS_MAC
+    // We have to change the growth policy in Mac.
+    formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
+#endif
     formLayout->setWidget(0, QFormLayout::LabelRole, pageNumEdit);
     formLayout->setWidget(0, QFormLayout::FieldRole, pageNumLabel);
Index: trunk/src/gui/effects/qgraphicseffect.cpp
===================================================================
--- trunk/src/gui/effects/qgraphicseffect.cpp	(revision 766)
+++ trunk/src/gui/effects/qgraphicseffect.cpp	(revision 769)
@@ -384,7 +384,7 @@
     if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
         && (reason == EffectRectChanged
-            || reason == TransformChanged
-               && m_cachedSystem == Qt::LogicalCoordinates))
-        return;
+            || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) {
+        return;
+    }
 
     QPixmapCache::remove(m_cacheKey);
@@ -700,5 +700,7 @@
         // No point in drawing in device coordinates (pixmap will be scaled anyways).
         const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
-        d->filter->draw(painter, offset, pixmap);
+        if (!pixmap.isNull())
+            d->filter->draw(painter, offset, pixmap);
+
         return;
     }
@@ -706,4 +708,7 @@
     // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
     const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
+    if (pixmap.isNull())
+        return;
+
     QTransform restoreTransform = painter->worldTransform();
     painter->setWorldTransform(QTransform());
@@ -722,5 +727,6 @@
     function. Use setBlurHints() to choose the blur hints.
 
-    By default, the blur radius is 5 pixels.
+    By default, the blur radius is 5 pixels. The blur radius is specified in
+    device coordinates.
 
     \img graphicseffect-blur.png
@@ -777,4 +783,7 @@
 
     By default, the blur radius is 5 pixels.
+
+    The radius is given in device coordinates, meaning it is
+    unaffected by scale.
 */
 qreal QGraphicsBlurEffect::blurRadius() const
@@ -859,7 +868,9 @@
         mode = NoPad;
 
-    // Draw pixmap in device coordinates to avoid pixmap scaling.
     QPoint offset;
     QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
+    if (pixmap.isNull())
+        return;
+
     d->filter->draw(painter, offset, pixmap);
 }
@@ -878,5 +889,6 @@
     By default, the drop shadow is a semi-transparent dark gray
     (QColor(63, 63, 63, 180)) shadow, blurred with a radius of 1 at an offset
-    of 8 pixels towards the lower right.
+    of 8 pixels towards the lower right. The drop shadow offset is specified
+    in device coordinates.
 
     \img graphicseffect-drop-shadow.png
@@ -906,4 +918,7 @@
 
     By default, the offset is 8 pixels towards the lower right.
+
+    The offset is given in device coordinates, which means it is
+    unaffected by scale.
 
     \sa xOffset(), yOffset(), blurRadius(), color()
@@ -1048,4 +1063,7 @@
     QPoint offset;
     const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
+    if (pixmap.isNull())
+        return;
+
     QTransform restoreTransform = painter->worldTransform();
     painter->setWorldTransform(QTransform());
Index: trunk/src/gui/egl/egl.pri
===================================================================
--- trunk/src/gui/egl/egl.pri	(revision 766)
+++ trunk/src/gui/egl/egl.pri	(revision 769)
@@ -1,23 +1,29 @@
-CONFIG += egl
+contains(QT_CONFIG, egl): {
+	CONFIG += egl
 
-HEADERS += \
-    egl/qegl_p.h \
-    egl/qeglproperties_p.h
+	HEADERS += \
+	    egl/qegl_p.h \
+	    egl/qeglproperties_p.h
 
-SOURCES += \
-    egl/qegl.cpp \
-    egl/qeglproperties.cpp
+	SOURCES += \
+	    egl/qegl.cpp \
+	    egl/qeglproperties.cpp
 
-wince*: SOURCES += egl/qegl_wince.cpp
+	wince*: SOURCES += egl/qegl_wince.cpp
 
-unix {
-    embedded {
-        SOURCES += egl/qegl_qws.cpp
-    } else {
-        symbian {
-            SOURCES += egl/qegl_symbian.cpp
-        } else {
-            SOURCES += egl/qegl_x11.cpp
-        }
-    }
+	unix {
+	    embedded {
+	        SOURCES += egl/qegl_qws.cpp
+	    } else {
+	        symbian {
+	            SOURCES += egl/qegl_symbian.cpp
+	        } else {
+	            SOURCES += egl/qegl_x11.cpp
+	        }
+	    }
+	}
+} else:symbian {
+	DEFINES += QT_NO_EGL
+	SOURCES += egl/qegl_stub.cpp
+	SOURCES += egl/qeglproperties_stub.cpp
 }
Index: trunk/src/gui/egl/qegl.cpp
===================================================================
--- trunk/src/gui/egl/qegl.cpp	(revision 766)
+++ trunk/src/gui/egl/qegl.cpp	(revision 769)
@@ -43,8 +43,37 @@
 #include <QtGui/qpixmap.h>
 #include <QtGui/qwidget.h>
+#include <QtCore/qatomic.h>
 #include <QtCore/qdebug.h>
 #include "qegl_p.h"
 
 QT_BEGIN_NAMESPACE
+
+
+/*
+    QEglContextTracker is used to track the EGL contexts that we
+    create internally in Qt, so that we can call eglTerminate() to
+    free additional EGL resources when the last context is destroyed.
+*/
+
+class QEglContextTracker
+{
+public:
+    static void ref() { contexts.ref(); }
+    static void deref() {
+        if (!contexts.deref()) {
+            eglTerminate(QEglContext::display());
+            displayOpen = 0;
+        }
+    }
+    static void setDisplayOpened() { displayOpen = 1; }
+    static bool displayOpened() { return displayOpen; }
+
+private:
+    static QBasicAtomicInt contexts;
+    static QBasicAtomicInt displayOpen;
+};
+
+QBasicAtomicInt QEglContextTracker::contexts = Q_BASIC_ATOMIC_INITIALIZER(0);
+QBasicAtomicInt QEglContextTracker::displayOpen = Q_BASIC_ATOMIC_INITIALIZER(0);
 
 // Current GL and VG contexts.  These are used to determine if
@@ -55,7 +84,8 @@
 static QEglContext * volatile currentVGContext = 0;
 
+EGLDisplay QEglContext::dpy = EGL_NO_DISPLAY;
+
 QEglContext::QEglContext()
     : apiType(QEgl::OpenGL)
-    , dpy(EGL_NO_DISPLAY)
     , ctx(EGL_NO_CONTEXT)
     , cfg(0)
@@ -65,9 +95,10 @@
     , sharing(false)
 {
+    QEglContextTracker::ref();
 }
 
 QEglContext::~QEglContext()
 {
-    destroy();
+    destroyContext();
 
     if (currentGLContext == this)
@@ -75,4 +106,5 @@
     if (currentVGContext == this)
         currentVGContext = 0;
+    QEglContextTracker::deref();
 }
 
@@ -85,12 +117,4 @@
 {
     return current;
-}
-
-// Open the EGL display associated with "device".
-bool QEglContext::openDisplay(QPaintDevice *device)
-{
-    if (dpy == EGL_NO_DISPLAY)
-        dpy = defaultDisplay(device);
-    return (dpy != EGL_NO_DISPLAY);
 }
 
@@ -103,5 +127,5 @@
         // Get the number of matching configurations for this set of properties.
         EGLint matching = 0;
-        if (!eglChooseConfig(dpy, props.properties(), 0, 0, &matching) || !matching)
+        if (!eglChooseConfig(display(), props.properties(), 0, 0, &matching) || !matching)
             continue;
 
@@ -109,5 +133,5 @@
         // matching configuration.
         if (match == QEgl::BestPixelFormat) {
-            eglChooseConfig(dpy, props.properties(), &cfg, 1, &matching);
+            eglChooseConfig(display(), props.properties(), &cfg, 1, &matching);
             if (matching < 1)
                 continue;
@@ -119,11 +143,11 @@
         EGLint size = matching;
         EGLConfig *configs = new EGLConfig [size];
-        eglChooseConfig(dpy, props.properties(), configs, size, &matching);
+        eglChooseConfig(display(), props.properties(), configs, size, &matching);
         for (EGLint index = 0; index < size; ++index) {
             EGLint red, green, blue, alpha;
-            eglGetConfigAttrib(dpy, configs[index], EGL_RED_SIZE, &red);
-            eglGetConfigAttrib(dpy, configs[index], EGL_GREEN_SIZE, &green);
-            eglGetConfigAttrib(dpy, configs[index], EGL_BLUE_SIZE, &blue);
-            eglGetConfigAttrib(dpy, configs[index], EGL_ALPHA_SIZE, &alpha);
+            eglGetConfigAttrib(display(), configs[index], EGL_RED_SIZE, &red);
+            eglGetConfigAttrib(display(), configs[index], EGL_GREEN_SIZE, &green);
+            eglGetConfigAttrib(display(), configs[index], EGL_BLUE_SIZE, &blue);
+            eglGetConfigAttrib(display(), configs[index], EGL_ALPHA_SIZE, &alpha);
             if (red == props.value(EGL_RED_SIZE) &&
                     green == props.value(EGL_GREEN_SIZE) &&
@@ -180,5 +204,5 @@
         shareContext = 0;
     if (shareContext) {
-        ctx = eglCreateContext(dpy, cfg, shareContext->ctx, contextProps.properties());
+        ctx = eglCreateContext(display(), cfg, shareContext->ctx, contextProps.properties());
         if (ctx == EGL_NO_CONTEXT) {
             qWarning() << "QEglContext::createContext(): Could not share context:" << errorString(eglGetError());
@@ -189,5 +213,5 @@
     }
     if (ctx == EGL_NO_CONTEXT) {
-        ctx = eglCreateContext(dpy, cfg, 0, contextProps.properties());
+        ctx = eglCreateContext(display(), cfg, 0, contextProps.properties());
         if (ctx == EGL_NO_CONTEXT) {
             qWarning() << "QEglContext::createContext(): Unable to create EGL context:" << errorString(eglGetError());
@@ -205,14 +229,13 @@
         if (surface == currentSurface)
             doneCurrent();
-        eglDestroySurface(dpy, surface);
+        eglDestroySurface(display(), surface);
     }
 }
 
 // Destroy the context.  Note: this does not destroy the surface.
-void QEglContext::destroy()
+void QEglContext::destroyContext()
 {
     if (ctx != EGL_NO_CONTEXT && ownsContext)
-        eglDestroyContext(dpy, ctx);
-    dpy = EGL_NO_DISPLAY;
+        eglDestroyContext(display(), ctx);
     ctx = EGL_NO_CONTEXT;
     cfg = 0;
@@ -249,5 +272,5 @@
 #endif
 
-    bool ok = eglMakeCurrent(dpy, surface, surface, ctx);
+    bool ok = eglMakeCurrent(display(), surface, surface, ctx);
     if (!ok)
         qWarning() << "QEglContext::makeCurrent():" << errorString(eglGetError());
@@ -278,5 +301,5 @@
 #endif
 
-    bool ok = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    bool ok = eglMakeCurrent(display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     if (!ok)
         qWarning() << "QEglContext::doneCurrent():" << errorString(eglGetError());
@@ -300,5 +323,5 @@
         return false;
 
-    bool ok = eglSwapBuffers(dpy, surface);
+    bool ok = eglSwapBuffers(display(), surface);
     if (!ok)
         qWarning() << "QEglContext::swapBuffers():" << errorString(eglGetError());
@@ -339,5 +362,15 @@
 bool QEglContext::configAttrib(int name, EGLint *value) const
 {
-    return eglGetConfigAttrib(dpy, cfg, name, value);
+    return eglGetConfigAttrib(display(), cfg, name, value);
+}
+
+void QEglContext::clearError()
+{
+    eglGetError();
+}
+
+EGLint QEglContext::error()
+{
+    return eglGetError();
 }
 
@@ -351,5 +384,5 @@
     for (int name = 0x3020; name <= 0x304F; ++name) {
         EGLint value;
-        if (name != EGL_NONE && eglGetConfigAttrib(dpy, cfg, name, &value))
+        if (name != EGL_NONE && eglGetConfigAttrib(display(), cfg, name, &value))
             props.setValue(name, value);
     }
@@ -358,24 +391,33 @@
 }
 
-// Initialize and return the default display.
-EGLDisplay QEglContext::defaultDisplay(QPaintDevice *device)
-{
-    static EGLDisplay dpy = EGL_NO_DISPLAY;
-    if (dpy == EGL_NO_DISPLAY) {
-        dpy = getDisplay(device);
+EGLDisplay QEglContext::display()
+{
+    if (!QEglContextTracker::displayOpened()) {
+        dpy = eglGetDisplay(nativeDisplay());
+        QEglContextTracker::setDisplayOpened();
         if (dpy == EGL_NO_DISPLAY) {
-            qWarning() << "QEglContext::defaultDisplay(): Cannot open EGL display";
+            qWarning("QEglContext::display(): Falling back to EGL_DEFAULT_DISPLAY");
+            dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY));
+        }
+        if (dpy == EGL_NO_DISPLAY) {
+            qWarning("QEglContext::display(): Can't even open the default display");
             return EGL_NO_DISPLAY;
         }
+
         if (!eglInitialize(dpy, NULL, NULL)) {
-            qWarning() << "QEglContext::defaultDisplay(): Cannot initialize EGL display:" << errorString(eglGetError());
+            qWarning() << "QEglContext::display(): Cannot initialize EGL display:" << errorString(eglGetError());
             return EGL_NO_DISPLAY;
         }
-#ifdef EGL_OPENGL_ES_API
-        eglBindAPI(EGL_OPENGL_ES_API);
-#endif
-    }
+    }
+
     return dpy;
 }
+
+#if !defined(Q_WS_X11) && !defined(Q_WS_WINCE) // WinCE & X11 implement this properly
+EGLNativeDisplayType QEglContext::nativeDisplay()
+{
+    return EGL_DEFAULT_DISPLAY;
+}
+#endif
 
 // Return the error string associated with a specific code.
@@ -411,8 +453,8 @@
     QEglProperties props;
     EGLint count = 0;
-    if (!eglGetConfigs(dpy, 0, 0, &count) || count < 1)
+    if (!eglGetConfigs(display(), 0, 0, &count) || count < 1)
         return;
     EGLConfig *configs = new EGLConfig [count];
-    eglGetConfigs(dpy, configs, count, &count);
+    eglGetConfigs(display(), configs, count, &count);
     for (EGLint index = 0; index < count; ++index) {
         props = configProperties(configs[index]);
@@ -424,5 +466,5 @@
 QString QEglContext::extensions()
 {
-    const char* exts = eglQueryString(QEglContext::defaultDisplay(0), EGL_EXTENSIONS);
+    const char* exts = eglQueryString(QEglContext::display(), EGL_EXTENSIONS);
     return QString(QLatin1String(exts));
 }
@@ -432,5 +474,5 @@
     QList<QByteArray> extensions =
         QByteArray(reinterpret_cast<const char *>
-            (eglQueryString(QEglContext::defaultDisplay(0), EGL_EXTENSIONS))).split(' ');
+            (eglQueryString(QEglContext::display(), EGL_EXTENSIONS))).split(' ');
     return extensions.contains(extensionName);
 }
Index: trunk/src/gui/egl/qegl_p.h
===================================================================
--- trunk/src/gui/egl/qegl_p.h	(revision 766)
+++ trunk/src/gui/egl/qegl_p.h	(revision 769)
@@ -87,11 +87,9 @@
     void setApi(QEgl::API api) { apiType = api; }
 
-    bool openDisplay(QPaintDevice *device);
     bool chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat);
     bool createContext(QEglContext *shareContext = 0, const QEglProperties *properties = 0);
+    void destroyContext();
     EGLSurface createSurface(QPaintDevice *device, const QEglProperties *properties = 0);
     void destroySurface(EGLSurface surface);
-
-    void destroy();
 
     bool makeCurrent(EGLSurface surface);
@@ -105,9 +103,9 @@
     bool configAttrib(int name, EGLint *value) const;
 
-    static void clearError() { eglGetError(); }
-    static EGLint error() { return eglGetError(); }
+    static void clearError();
+    static EGLint error();
     static QString errorString(EGLint code);
 
-    EGLDisplay display() const { return dpy; }
+    static EGLDisplay display();
 
     EGLContext context() const { return ctx; }
@@ -119,6 +117,4 @@
     QEglProperties configProperties(EGLConfig cfg = 0) const;
 
-    static EGLDisplay defaultDisplay(QPaintDevice *device);
-
     void dumpAllConfigs();
 
@@ -128,5 +124,4 @@
 private:
     QEgl::API apiType;
-    EGLDisplay dpy;
     EGLContext ctx;
     EGLConfig cfg;
@@ -136,5 +131,6 @@
     bool sharing;
 
-    static EGLDisplay getDisplay(QPaintDevice *device);
+    static EGLDisplay dpy;
+    static EGLNativeDisplayType nativeDisplay();
 
     static QEglContext *currentContext(QEgl::API api);
Index: trunk/src/gui/egl/qegl_qws.cpp
===================================================================
--- trunk/src/gui/egl/qegl_qws.cpp	(revision 766)
+++ trunk/src/gui/egl/qegl_qws.cpp	(revision 769)
@@ -65,10 +65,4 @@
 }
 
-EGLDisplay QEglContext::getDisplay(QPaintDevice *device)
-{
-    Q_UNUSED(device);
-    return eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY));
-}
-
 static QScreen *screenForDevice(QPaintDevice *device)
 {
Index: trunk/src/gui/egl/qegl_stub.cpp
===================================================================
--- trunk/src/gui/egl/qegl_stub.cpp	(revision 769)
+++ trunk/src/gui/egl/qegl_stub.cpp	(revision 769)
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** 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$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qpaintdevice.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qwidget.h>
+#include <QtCore/qdebug.h>
+
+#include "qegl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static void noegl(const char *fn)
+{
+    qWarning() << fn << " called, but Qt configured without EGL" << endl;
+}
+
+#define NOEGL noegl(__FUNCTION__);
+
+EGLDisplay QEglContext::dpy = 0;
+
+QEglContext::QEglContext()
+    : apiType(QEgl::OpenGL)
+    , ctx(0)
+    , cfg(0)
+    , currentSurface(0)
+    , current(false)
+    , ownsContext(true)
+    , sharing(false)
+{
+    NOEGL
+}
+
+QEglContext::~QEglContext()
+{
+    NOEGL
+}
+
+bool QEglContext::isValid() const
+{
+    NOEGL
+    return false;
+}
+
+bool QEglContext::isCurrent() const
+{
+    NOEGL
+    return false;
+}
+
+bool QEglContext::chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match)
+{
+    Q_UNUSED(properties)
+    Q_UNUSED(match)
+    NOEGL
+    return false;
+}
+
+EGLSurface QEglContext::createSurface(QPaintDevice* device, const QEglProperties *properties)
+{
+    Q_UNUSED(device)
+    Q_UNUSED(properties)
+    NOEGL
+    return 0;
+}
+
+
+// Create the EGLContext.
+bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties *properties)
+{
+    Q_UNUSED(shareContext)
+    Q_UNUSED(properties)
+    NOEGL
+    return false;
+}
+
+// Destroy an EGL surface object.  If it was current on this context
+// then call doneCurrent() for it first.
+void QEglContext::destroySurface(EGLSurface surface)
+{
+    Q_UNUSED(surface)
+    NOEGL
+}
+
+// Destroy the context.  Note: this does not destroy the surface.
+void QEglContext::destroyContext()
+{
+    NOEGL
+}
+
+bool QEglContext::makeCurrent(EGLSurface surface)
+{
+    Q_UNUSED(surface)
+    NOEGL
+    return false;
+}
+
+bool QEglContext::doneCurrent()
+{
+    NOEGL
+    return false;
+}
+
+// Act as though doneCurrent() was called, but keep the context
+// and the surface active for the moment.  This allows makeCurrent()
+// to skip a call to eglMakeCurrent() if we are using the same
+// surface as the last set of painting operations.  We leave the
+// currentContext() pointer as-is for now.
+bool QEglContext::lazyDoneCurrent()
+{
+    NOEGL
+    return false;
+}
+
+bool QEglContext::swapBuffers(EGLSurface surface)
+{
+    Q_UNUSED(surface)
+    NOEGL
+    return false;
+}
+
+bool QEglContext::configAttrib(int name, EGLint *value) const
+{
+    Q_UNUSED(name)
+    Q_UNUSED(value)
+    NOEGL
+    return false;
+}
+
+void QEglContext::clearError()
+{
+    NOEGL
+    return;
+}
+
+EGLint QEglContext::error()
+{
+    NOEGL
+    return 0;
+}
+
+EGLDisplay QEglContext::display()
+{
+    NOEGL
+    return 0;
+}
+
+// Return the error string associated with a specific code.
+QString QEglContext::errorString(EGLint code)
+{
+    Q_UNUSED(code)
+    NOEGL
+    return QString();
+}
+
+// Dump all of the EGL configurations supported by the system.
+void QEglContext::dumpAllConfigs()
+{
+    NOEGL
+}
+
+QString QEglContext::extensions()
+{
+    NOEGL
+    return QString();
+}
+
+bool QEglContext::hasExtension(const char* extensionName)
+{
+    Q_UNUSED(extensionName)
+    NOEGL
+    return false;
+}
+
+QEglContext *QEglContext::currentContext(QEgl::API api)
+{
+    Q_UNUSED(api)
+    NOEGL
+    return false;
+}
+
+void QEglContext::setCurrentContext(QEgl::API api, QEglContext *context)
+{
+    Q_UNUSED(api)
+    Q_UNUSED(context)
+    NOEGL
+}
+
+EGLNativeDisplayType QEglContext::nativeDisplay()
+{
+    NOEGL
+    return 0;
+}
+
+void QEglContext::waitClient()
+{
+    NOEGL
+}
+
+void QEglContext::waitNative()
+{
+    NOEGL
+}
+
+QEglProperties QEglContext::configProperties(EGLConfig cfg) const
+{
+    Q_UNUSED(cfg)
+    NOEGL
+    return QEglProperties();
+}
+
+QT_END_NAMESPACE
Index: trunk/src/gui/egl/qegl_symbian.cpp
===================================================================
--- trunk/src/gui/egl/qegl_symbian.cpp	(revision 766)
+++ trunk/src/gui/egl/qegl_symbian.cpp	(revision 769)
@@ -79,18 +79,10 @@
     EGLSurface surf;
     if (devType == QInternal::Widget)
-        surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, 0);
+        surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, props);
     else
-        surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, 0);
+        surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, props);
     if (surf == EGL_NO_SURFACE)
         qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError());
     return surf;
-}
-
-EGLDisplay QEglContext::getDisplay(QPaintDevice *device)
-{
-    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    if (dpy == EGL_NO_DISPLAY)
-        qWarning("QEglContext::defaultDisplay(): Falling back to EGL_DEFAULT_DISPLAY");
-    return dpy;
 }
 
Index: trunk/src/gui/egl/qegl_wince.cpp
===================================================================
--- trunk/src/gui/egl/qegl_wince.cpp	(revision 766)
+++ trunk/src/gui/egl/qegl_wince.cpp	(revision 769)
@@ -88,18 +88,13 @@
 }
 
-EGLDisplay QEglContext::getDisplay(QPaintDevice *device)
+EGLNativeDisplayType QEglContext::nativeDisplay()
 {
-    EGLDisplay dpy = 0;
-    HWND win = (static_cast<QWidget*>(device))->winId();
-    HDC myDc = GetDC(win);
+    HDC myDc = GetDC(0);
+
     if (!myDc) {
-        qWarning("QEglContext::defaultDisplay(): WinCE display is not open");
+        qWarning("QEglContext::nativeDisplay(): WinCE display is not open");
+        return EGL_DEFAULT_DISPLAY;
     }
-    dpy = eglGetDisplay(EGLNativeDisplayType(myDc));
-    if (dpy == EGL_NO_DISPLAY) {
-        qWarning("QEglContext::defaultDisplay(): Falling back to EGL_DEFAULT_DISPLAY");
-        dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    }
-    return dpy;
+    return EGLNativeDisplayType(myDc);
 }
 
Index: trunk/src/gui/egl/qegl_x11.cpp
===================================================================
--- trunk/src/gui/egl/qegl_x11.cpp	(revision 766)
+++ trunk/src/gui/egl/qegl_x11.cpp	(revision 769)
@@ -94,13 +94,12 @@
 }
 
-EGLDisplay QEglContext::getDisplay(QPaintDevice *device)
+EGLNativeDisplayType QEglContext::nativeDisplay()
 {
-    Q_UNUSED(device);
     Display *xdpy = QX11Info::display();
     if (!xdpy) {
         qWarning("QEglContext::getDisplay(): X11 display is not open");
-        return EGL_NO_DISPLAY;
+        return EGLNativeDisplayType(EGL_DEFAULT_DISPLAY);
     }
-    return eglGetDisplay(EGLNativeDisplayType(xdpy));
+    return EGLNativeDisplayType(xdpy);
 }
 
Index: trunk/src/gui/egl/qeglproperties.cpp
===================================================================
--- trunk/src/gui/egl/qeglproperties.cpp	(revision 766)
+++ trunk/src/gui/egl/qeglproperties.cpp	(revision 769)
@@ -40,10 +40,10 @@
 ****************************************************************************/
 
-#include "qeglproperties_p.h"
-
-QT_BEGIN_NAMESPACE
-
 #include <QtCore/qdebug.h>
 #include <QtCore/qstringlist.h>
+
+#include "qeglproperties_p.h"
+
+QT_BEGIN_NAMESPACE
 
 #include "qegl_p.h"
@@ -61,5 +61,5 @@
     for (int name = 0x3020; name <= 0x304F; ++name) {
         EGLint value;
-        if (name != EGL_NONE && eglGetConfigAttrib(QEglContext::defaultDisplay(0), cfg, name, &value))
+        if (name != EGL_NONE && eglGetConfigAttrib(QEglContext::display(), cfg, name, &value))
             setValue(name, value);
     }
@@ -274,10 +274,10 @@
 {
     EGLint count = 0;
-    eglGetConfigs(QEglContext::defaultDisplay(0), 0, 0, &count);
+    eglGetConfigs(QEglContext::display(), 0, 0, &count);
     if (count < 1)
         return;
 
     EGLConfig *configs = new EGLConfig [count];
-    eglGetConfigs(QEglContext::defaultDisplay(0), configs, count, &count);
+    eglGetConfigs(QEglContext::display(), configs, count, &count);
     for (EGLint index = 0; index < count; ++index)
         qWarning() << QEglProperties(configs[index]).toString();
Index: trunk/src/gui/egl/qeglproperties_p.h
===================================================================
--- trunk/src/gui/egl/qeglproperties_p.h	(revision 766)
+++ trunk/src/gui/egl/qeglproperties_p.h	(revision 769)
@@ -59,9 +59,33 @@
 QT_BEGIN_INCLUDE_NAMESPACE
 
+#ifndef QT_NO_EGL
+#if defined(QT_OPENGL_ES_2)
+#   include <GLES2/gl2.h>
+#endif
+
 #if defined(QT_GLES_EGL)
-#include <GLES/egl.h>
+#   include <GLES/egl.h>
 #else
-#include <EGL/egl.h>
+#   include <EGL/egl.h>
 #endif
+#else
+
+//types from egltypes.h for compiling stub without EGL headers
+typedef int EGLBoolean;
+typedef int EGLint;
+typedef int EGLenum;
+typedef int    NativeDisplayType;
+typedef void*  NativeWindowType;
+typedef void*  NativePixmapType;
+typedef int EGLDisplay;
+typedef int EGLConfig;
+typedef int EGLSurface;
+typedef int EGLContext;
+typedef int EGLClientBuffer;
+#define EGL_NONE            0x3038  /* Attrib list terminator */
+
+#endif
+
+
 
 #if defined(Q_WS_X11)
@@ -99,5 +123,5 @@
         BestPixelFormat
     };
-};
+}
 
 class QX11Info;
Index: trunk/src/gui/egl/qeglproperties_stub.cpp
===================================================================
--- trunk/src/gui/egl/qeglproperties_stub.cpp	(revision 769)
+++ trunk/src/gui/egl/qeglproperties_stub.cpp	(revision 769)
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** 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$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstringlist.h>
+
+#include "qeglproperties_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static void noegl(const char *fn)
+{
+    qWarning() << fn << " called, but Qt configured without EGL" << endl;
+}
+
+#define NOEGL noegl(__FUNCTION__);
+
+// Initialize a property block.
+QEglProperties::QEglProperties()
+{
+    NOEGL
+}
+
+QEglProperties::QEglProperties(EGLConfig cfg)
+{
+    Q_UNUSED(cfg)
+    NOEGL
+}
+
+// Fetch the current value associated with a property.
+int QEglProperties::value(int name) const
+{
+    Q_UNUSED(name)
+    NOEGL
+    return 0;
+}
+
+// Set the value associated with a property, replacing an existing
+// value if there is one.
+void QEglProperties::setValue(int name, int value)
+{
+    Q_UNUSED(name)
+    Q_UNUSED(value)
+    NOEGL
+}
+
+// Remove a property value.  Returns false if the property is not present.
+bool QEglProperties::removeValue(int name)
+{
+    Q_UNUSED(name)
+    NOEGL
+    return false;
+}
+
+// Sets the red, green, blue, and alpha sizes based on a pixel format.
+// Normally used to match a configuration request to the screen format.
+void QEglProperties::setPixelFormat(QImage::Format pixelFormat)
+{
+    Q_UNUSED(pixelFormat)
+    NOEGL
+
+}
+
+void QEglProperties::setRenderableType(QEgl::API api)
+{
+    Q_UNUSED(api);
+    NOEGL
+}
+
+// Reduce the complexity of a configuration request to ask for less
+// because the previous request did not result in success.  Returns
+// true if the complexity was reduced, or false if no further
+// reductions in complexity are possible.
+bool QEglProperties::reduceConfiguration()
+{
+    NOEGL
+    return false;
+}
+
+// Convert a property list to a string suitable for debug output.
+QString QEglProperties::toString() const
+{
+    NOEGL
+    return QString();
+}
+
+void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
+{
+    Q_UNUSED(dev)
+    NOEGL
+}
+
+void QEglProperties::dumpAllConfigs()
+{
+    NOEGL
+}
+
+QT_END_NAMESPACE
+
+
Index: trunk/src/gui/embedded/directfb.pri
===================================================================
--- trunk/src/gui/embedded/directfb.pri	(revision 766)
+++ trunk/src/gui/embedded/directfb.pri	(revision 769)
@@ -16,5 +16,5 @@
 #DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION
 #DEFINES += QT_NO_DIRECTFB_STRETCHBLIT
-#DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP|DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON|DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS|DRAW_ROUNDED_RECT
+DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP|DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON|DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS|DRAW_ROUNDED_RECT
 #DEFINES += \"QT_DIRECTFB_WARN_ON_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\"
 #DEFINES += \"QT_DIRECTFB_DISABLE_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\"
Index: trunk/src/gui/embedded/qscreen_qws.cpp
===================================================================
--- trunk/src/gui/embedded/qscreen_qws.cpp	(revision 766)
+++ trunk/src/gui/embedded/qscreen_qws.cpp	(revision 769)
@@ -2740,5 +2740,5 @@
                 break;
             }
-            spanData.setup(qwsServer->backgroundBrush(), 256, QPainter::CompositionMode_SourceOver);
+            spanData.setup(qwsServer->backgroundBrush(), 256, QPainter::CompositionMode_Source);
             spanData.dx = off.x();
             spanData.dy = off.y();
Index: trunk/src/gui/embedded/qscreenqnx_qws.cpp
===================================================================
--- trunk/src/gui/embedded/qscreenqnx_qws.cpp	(revision 766)
+++ trunk/src/gui/embedded/qscreenqnx_qws.cpp	(revision 769)
@@ -206,5 +206,5 @@
                 GF_FORMAT_ARGB8888, 0,
                 GF_SURFACE_CREATE_CPU_FAST_ACCESS | GF_SURFACE_CREATE_CPU_LINEAR_ACCESSIBLE
-                | GF_SURFACE_PHYS_CONTIG);
+                | GF_SURFACE_PHYS_CONTIG | GF_SURFACE_CREATE_SHAREABLE);
     if (ret != GF_ERR_OK) {
         qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d",
Index: trunk/src/gui/graphicsview/qgraphicsitem.cpp
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsitem.cpp	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsitem.cpp	(revision 769)
@@ -320,5 +320,5 @@
 
     \value ItemClipsToShape The item clips to its own shape. The item cannot
-    draw or receive mouse, tablet, drag and drop or hover events outside ts
+    draw or receive mouse, tablet, drag and drop or hover events outside its
     shape. It is disabled by default. This behavior is enforced by
     QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
@@ -358,17 +358,20 @@
     this flag, the child will be stacked behind it. This flag is useful for
     drop shadow effects and for decoration objects that follow the parent
-    item's geometry without drawing on top of it.
+    item's geometry without drawing on top of it. This flag was introduced
+    in Qt 4.5.
 
     \value ItemUsesExtendedStyleOption The item makes use of either
-    \l{QStyleOptionGraphicsItem::}{exposedRect} or
-    \l{QStyleOptionGraphicsItem::}{matrix} in QStyleOptionGraphicsItem. By default,
-    the \l{QStyleOptionGraphicsItem::}{exposedRect} is initialized to the item's
-    boundingRect() and the \l{QStyleOptionGraphicsItem::}{matrix} is untransformed.
-    You can enable this flag for the style options to be set up with more
-    fine-grained values.
-    Note that QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
+    \l{QStyleOptionGraphicsItem::} {exposedRect} or
+    \l{QStyleOptionGraphicsItem::} {matrix} in
+    QStyleOptionGraphicsItem. By default, the
+    \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the
+    item's boundingRect() and the
+    \l{QStyleOptionGraphicsItem::}{matrix} is untransformed.  You can
+    enable this flag for the style options to be set up with more
+    fine-grained values.  Note that
+    QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
     and always initialized to 1. Use
-    QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need a higher
-    value.
+    QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need
+    a higher value. This flag was introduced in Qt 4.6.
 
     \value ItemHasNoContents The item does not paint anything (i.e., calling
@@ -388,7 +391,8 @@
     This flag was introduced in Qt 4.6.
 
-    \value ItemNegativeZStacksBehindParent The item automatically stacks behind
-    it's parent if it's z-value is negative. This flag enables setZValue() to
-    toggle ItemStacksBehindParent.
+    \value ItemNegativeZStacksBehindParent The item automatically
+    stacks behind it's parent if it's z-value is negative. This flag
+    enables setZValue() to toggle ItemStacksBehindParent. This flag
+    was introduced in Qt 4.6.
 
     \value ItemIsPanel The item is a panel. A panel provides activation and
@@ -410,10 +414,4 @@
 /*!
     \enum QGraphicsItem::GraphicsItemChange
-
-        ItemVisibleHasChanged,
-        ItemEnabledHasChanged,
-        ItemSelectedHasChanged,
-        ItemParentHasChanged,
-        ItemSceneHasChanged
 
     This enum describes the state changes that are notified by
@@ -644,7 +642,14 @@
 
     The values are:
-    \value NonModal   The panel is not modal and does not block input to other panels.
-    \value PanelModal The panel is modal to a single item hierarchy and blocks input to its parent pane, all grandparent panels, and all siblings of its parent and grandparent panels.
-    \value SceneModal The window is modal to the entire scene and blocks input to all panels.
+
+    \value NonModal The panel is not modal and does not block input to
+    other panels. This is the default value for panels.
+
+    \value PanelModal The panel is modal to a single item hierarchy
+    and blocks input to its parent pane, all grandparent panels, and
+    all siblings of its parent and grandparent panels.
+
+    \value SceneModal The window is modal to the entire scene and
+    blocks input to all panels.
 
     \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
@@ -1126,4 +1131,7 @@
     }
 
+    // Resolve depth.
+    invalidateDepthRecursively();
+
     if ((parent = newParent)) {
         if (parent->d_func()->scene && parent->d_func()->scene != scene) {
@@ -1176,6 +1184,4 @@
     }
 
-    // Resolve depth.
-    invalidateDepthRecursively();
     dirtySceneTransform = 1;
 
@@ -1393,5 +1399,6 @@
     delete d_ptr->transformData;
 
-    qt_dataStore()->data.remove(this);
+    if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
+        dataStore->data.remove(this);
 }
 
@@ -1571,15 +1578,16 @@
 
 /*!
-    Sets this item's parent item to \a parent. If this item already has a
-    parent, it is first removed from the previous parent. If \a parent is 0,
-    this item will become a top-level item.
-
-    Note that this implicitly adds this graphics item to the scene of
-    the parent. You should not \l{QGraphicsScene::addItem()}{add} the
-    item to the scene yourself.
-
-    Calling this function on an item that is an ancestor of \a parent have undefined behaviour.
-
-    \sa parentItem(), childItems()
+  Sets this item's parent item to \a newParent. If this item already
+  has a parent, it is first removed from the previous parent. If \a
+  newParent is 0, this item will become a top-level item.
+
+  Note that this implicitly adds this graphics item to the scene of
+  the parent. You should not \l{QGraphicsScene::addItem()}{add} the
+  item to the scene yourself.
+
+  Calling this function on an item that is an ancestor of \a newParent
+  have undefined behaviour.
+
+  \sa parentItem(), childItems()
 */
 void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
@@ -1876,5 +1884,6 @@
     bool noVisualChange = (mode == NoCache && lastMode == NoCache)
                           || (mode == NoCache && lastMode == DeviceCoordinateCache)
-                          || (mode == DeviceCoordinateCache && lastMode == NoCache);
+                          || (mode == DeviceCoordinateCache && lastMode == NoCache)
+                          || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
     if (mode == NoCache) {
         d_ptr->removeExtraItemCache();
@@ -2170,9 +2179,14 @@
         if (c)
             c->purge();
-        if (scene)
+        if (scene) {
+#ifndef QT_NO_GRAPHICSEFFECT
+            invalidateParentGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
             scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
+        }
     }
 
     // Certain properties are dropped as an item becomes invisible.
+    bool hasFocus = q_ptr->hasFocus();
     if (!newVisible) {
         if (scene) {
@@ -2184,5 +2198,5 @@
                 scene->d_func()->leaveModal(q_ptr);
         }
-        if (q_ptr->hasFocus() && scene) {
+        if (hasFocus && scene) {
             // Hiding the closest non-panel ancestor of the focus item
             QGraphicsItem *focusItem = scene->focusItem();
@@ -2197,5 +2211,5 @@
             }
             if (clear)
-                q_ptr->clearFocus();
+                clearFocusHelper(/* giveFocusToParent = */ false);
         }
         if (q_ptr->isSelected())
@@ -2235,24 +2249,43 @@
 
     // Enable subfocus
-    if (scene && newVisible) {
-        QGraphicsItem *p = parent;
-        bool done = false;
-        while (p) {
-            if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
-                QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
-                if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
-                    done = true;
-                    while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
-                        fsi = fsi->d_ptr->focusScopeItem;
-                    scene->setFocusItem(fsi);
+    if (scene) {
+        if (newVisible) {
+            // Item is shown
+            QGraphicsItem *p = parent;
+            bool done = false;
+            while (p) {
+                if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+                    QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
+                    if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
+                        done = true;
+                        while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
+                            fsi = fsi->d_ptr->focusScopeItem;
+                        fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
+                                                   /* focusFromShow = */ true);
+                    }
+                    break;
                 }
-                break;
+                p = p->d_ptr->parent;
             }
-            p = p->d_ptr->parent;
-        }
-        if (!done) {
-            QGraphicsItem *fi = subFocusItem;
-            if (fi && fi != scene->focusItem()) {
-                scene->setFocusItem(fi);
+            if (!done) {
+                QGraphicsItem *fi = subFocusItem;
+                if (fi && fi != scene->focusItem()) {
+                    scene->setFocusItem(fi);
+                }
+            }
+        } else {
+            // Item is hidden
+            if (hasFocus) {
+                QGraphicsItem *p = parent;
+                while (p) {
+                    if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+                        if (p->d_ptr->visible) {
+                            p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
+                                                     /* focusFromShow = */ true);
+                        }
+                        break;
+                    }
+                    p = p->d_ptr->parent;
+                }
             }
         }
@@ -3105,5 +3138,5 @@
 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
 {
-    d_ptr->setFocusHelper(focusReason, /* climb = */ true);
+    d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromShow = */ false);
 }
 
@@ -3111,5 +3144,5 @@
     \internal
 */
-void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb)
+void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow)
 {
     // Disabled / unfocusable items cannot accept focus.
@@ -3131,5 +3164,5 @@
         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
             p->d_ptr->focusScopeItem = q_ptr;
-            if (!p->focusItem()) {
+            if (!p->focusItem() && !focusFromShow) {
                 // If you call setFocus on a child of a focus scope that
                 // doesn't currently have a focus item, then stop.
@@ -3172,22 +3205,33 @@
 void QGraphicsItem::clearFocus()
 {
-    // Pass focus to the closest parent focus scope.
-    if (!d_ptr->inDestructor) {
-        QGraphicsItem *p = d_ptr->parent;
-        while (p) {
-            if (p->flags() & ItemIsFocusScope) {
-                p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false);
-                return;
+    d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
+}
+
+/*!
+    \internal
+*/
+void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
+{
+    if (giveFocusToParent) {
+        // Pass focus to the closest parent focus scope
+        if (!inDestructor) {
+            QGraphicsItem *p = parent;
+            while (p) {
+                if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+                    p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
+                                             /* focusFromShow = */ false);
+                    return;
+                }
+                p = p->d_ptr->parent;
             }
-            p = p->d_ptr->parent;
         }
     }
 
     // Invisible items with focus must explicitly clear subfocus.
-    d_ptr->clearSubFocus(this);
-
-    if (hasFocus()) {
+    clearSubFocus(q_ptr);
+
+    if (q_ptr->hasFocus()) {
         // If this item has the scene's input focus, clear it.
-        d_ptr->scene->setFocusItem(0);
+        scene->setFocusItem(0);
     }
 }
@@ -3535,4 +3579,6 @@
     if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
         d_ptr->setPosHelper(pos);
+        if (d_ptr->isWidget)
+            static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
         return;
     }
@@ -7257,5 +7303,7 @@
         QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
         scenePrivate->index->prepareBoundingRectChange(this);
-        scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true);
+        scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
+                                /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
+                                /*updateBoundingRect=*/true);
 
         // For compatibility reasons, we have to update the item's old geometry
@@ -10802,4 +10850,5 @@
 }
 
+// sourceRect must be in the given coordinate system
 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
 {
@@ -10811,5 +10860,6 @@
     if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
         if (info) {
-            effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates));
+            QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
+            effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
             if (unpadded)
                 *unpadded = (effectRectF.size() == sourceRect.size());
@@ -10860,28 +10910,4 @@
     }
 
-    if (deviceCoordinates) {
-        // Clip to viewport rect.
-        int left, top, right, bottom;
-        effectRect.getCoords(&left, &top, &right, &bottom);
-        if (left < 0) {
-            if (offset)
-                offset->rx() += -left;
-            effectRect.setX(0);
-        }
-        if (top < 0) {
-            if (offset)
-                offset->ry() += -top;
-            effectRect.setY(0);
-        }
-        // NB! We use +-1 for historical reasons (see QRect documentation).
-        QPaintDevice *device = info->painter->device();
-        const int deviceWidth = device->width();
-        const int deviceHeight = device->height();
-        if (right + 1 > deviceWidth)
-            effectRect.setRight(deviceWidth - 1);
-        if (bottom + 1 > deviceHeight)
-            effectRect.setBottom(deviceHeight -1);
-
-    }
     if (effectRect.isEmpty())
         return QPixmap();
Index: trunk/src/gui/graphicsview/qgraphicsitem_p.h
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsitem_p.h	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsitem_p.h	(revision 769)
@@ -415,5 +415,6 @@
     inline void markParentDirty(bool updateBoundingRect = false);
 
-    void setFocusHelper(Qt::FocusReason focusReason, bool climb);
+    void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow);
+    void clearFocusHelper(bool giveFocusToParent);
     void setSubFocus(QGraphicsItem *rootItem = 0);
     void clearSubFocus(QGraphicsItem *rootItem = 0);
@@ -769,4 +770,11 @@
 {
     QGraphicsItemPrivate *parentp = this;
+#ifndef QT_NO_GRAPHICSEFFECT
+    if (updateBoundingRect && parentp->graphicsEffect && !parentp->inSetPosHelper) {
+        parentp->notifyInvalidated = 1;
+        static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+                                                        ->source->d_func())->invalidateCache();
+    }
+#endif
     while (parentp->parent) {
         parentp = parentp->parent->d_ptr.data();
Index: trunk/src/gui/graphicsview/qgraphicsproxywidget.cpp
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsproxywidget.cpp	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsproxywidget.cpp	(revision 769)
@@ -190,5 +190,5 @@
 
 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
-extern bool qt_tab_all_widgets;
+Q_GUI_EXPORT extern bool qt_tab_all_widgets;
 
 /*!
@@ -898,4 +898,27 @@
         break;
     }
+#ifndef QT_NO_TOOLTIP
+    case QEvent::GraphicsSceneHelp: {
+        // Propagate the help event (for tooltip) to the widget under mouse
+        if (d->lastWidgetUnderMouse) {
+            QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event);
+            QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();
+            QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());
+            QApplication::sendEvent(d->lastWidgetUnderMouse, &e);
+            event->setAccepted(e.isAccepted());
+            return e.isAccepted();
+        }
+        break;
+    }
+    case QEvent::ToolTipChange: {
+        // Propagate tooltip change to the widget
+        if (!d->tooltipChangeMode) {
+            d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+            d->widget->setToolTip(toolTip());
+            d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+        }
+        break;
+    }
+#endif
     default:
         break;
@@ -953,4 +976,12 @@
             }
             break;
+        case QEvent::ToolTipChange:
+            // Propagate tooltip change to the proxy.
+            if (!d->tooltipChangeMode) {
+                d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+                setToolTip(d->widget->toolTip());
+                d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+            }
+            break;
         default:
             break;
@@ -1316,4 +1347,6 @@
     }
 
+    d->proxyIsGivingFocus = true;
+
     switch (event->reason()) {
     case Qt::TabFocusReason: {
@@ -1329,8 +1362,9 @@
 	if (d->widget && d->widget->focusWidget()) {
 	    d->widget->focusWidget()->setFocus(event->reason());
-	    return;
-        }
-        break;
-    }
+        }
+        break;
+    }
+
+    d->proxyIsGivingFocus = false;
 }
 
@@ -1433,5 +1467,5 @@
 
     // Filter out repaints on the window frame.
-    const QRect exposedWidgetRect = (option->exposedRect & rect()).toRect();
+    const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect();
     if (exposedWidgetRect.isEmpty())
         return;
Index: trunk/src/gui/graphicsview/qgraphicsproxywidget_p.h
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsproxywidget_p.h	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsproxywidget_p.h	(revision 769)
@@ -73,4 +73,5 @@
           styleChangeMode(NoMode),
           paletteChangeMode(NoMode),
+          tooltipChangeMode(NoMode),
           focusFromWidgetToProxy(0)
     { }
@@ -118,5 +119,7 @@
     quint32 styleChangeMode : 2;
     quint32 paletteChangeMode : 2;
+    quint32 tooltipChangeMode : 2;
     quint32 focusFromWidgetToProxy : 1;
+    quint32 proxyIsGivingFocus : 1;
 };
 
Index: trunk/src/gui/graphicsview/qgraphicsscene.cpp
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsscene.cpp	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsscene.cpp	(revision 769)
@@ -694,4 +694,12 @@
     if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
         emit q->selectionChanged();
+
+    QHash<QGesture *, QGraphicsObject *>::iterator it;
+    for (it = gestureTargets.begin(); it != gestureTargets.end();) {
+        if (it.value() == item)
+            it = gestureTargets.erase(it);
+        else
+            ++it;
+    }
 }
 
@@ -802,5 +810,6 @@
             if (item) {
                 for (int i = 0; i < views.size(); ++i)
-                    views.at(i)->inputContext()->reset();
+                    if (views.at(i)->inputContext())
+                        views.at(i)->inputContext()->reset();
             }
         }
@@ -808,11 +817,11 @@
     }
 
+    if (item)
+        focusItem = item;
+    updateInputMethodSensitivityInViews();
     if (item) {
-        focusItem = item;
         QFocusEvent event(QEvent::FocusIn, focusReason);
         sendEvent(item, &event);
     }
-
-    updateInputMethodSensitivityInViews();
 }
 
@@ -3772,4 +3781,10 @@
     for (int i = 0; i < itemsAtPos.size(); ++i) {
         QGraphicsItem *tmp = itemsAtPos.at(i);
+        if (tmp->d_func()->isProxyWidget()) {
+            // if the item is a proxy widget, the event is forwarded to it
+            sendEvent(tmp, helpEvent);
+            if (helpEvent->isAccepted())
+                return;
+        }
         if (!tmp->toolTip().isEmpty()) {
             toolTipItem = tmp;
@@ -4285,4 +4300,5 @@
         // Blit the subpixmap into the main pixmap.
         pixmapPainter.begin(pix);
+        pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
         pixmapPainter.setClipRegion(pixmapExposed);
         pixmapPainter.drawPixmap(br.topLeft(), subPix);
@@ -4450,4 +4466,6 @@
 
         // Create or reuse offscreen pixmap, possibly scroll/blit from the old one.
+        // If the world transform is rotated we always recreate the cache to avoid
+        // wrong blending.
         bool pixModified = false;
         QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget];
@@ -4457,5 +4475,7 @@
             diff *= painter->worldTransform();
         deviceData->lastTransform = painter->worldTransform();
-        if (!invertable || diff.type() > QTransform::TxTranslate) {
+        if (!invertable
+            || diff.type() > QTransform::TxTranslate
+            || painter->worldTransform().type() > QTransform::TxScale) {
             pixModified = true;
             itemCache->allExposed = true;
@@ -4679,5 +4699,6 @@
             item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
         viewBoundingRect.adjust(-1, -1, 1, 1);
-        drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty();
+        drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
+                                 : !viewBoundingRect.normalized().isEmpty();
         if (!drawItem) {
             if (!itemHasChildren)
@@ -4713,29 +4734,16 @@
             && sourced->lastEffectTransform != painter->worldTransform())
         {
-            bool unclipped = false;
             if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
                 && painter->worldTransform().type() <= QTransform::TxTranslate)
             {
-                QRectF itemRect = item->boundingRect();
-                if (!item->d_ptr->children.isEmpty())
-                    itemRect |= item->childrenBoundingRect();
-
-                QRectF oldSourceRect = sourced->lastEffectTransform.mapRect(itemRect);
-                QRectF newSourceRect = painter->worldTransform().mapRect(itemRect);
-
-                QRect oldEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), oldSourceRect);
-                QRect newEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), newSourceRect);
-
-                QRect deviceRect(0, 0, painter->device()->width(), painter->device()->height());
-                if (deviceRect.contains(oldEffectRect) && deviceRect.contains(newEffectRect)) {
-                    sourced->setCachedOffset(newEffectRect.topLeft());
-                    unclipped = true;
-                }
+                QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
+                QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
+
+                sourced->setCachedOffset(effectRect.topLeft());
+            } else {
+                sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
             }
 
             sourced->lastEffectTransform = painter->worldTransform();
-
-            if (!unclipped)
-                sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
         }
 
@@ -4849,5 +4857,6 @@
 
 void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren,
-                                      bool force, bool ignoreOpacity, bool removingItemFromScene)
+                                      bool force, bool ignoreOpacity, bool removingItemFromScene,
+                                      bool updateBoundingRect)
 {
     Q_ASSERT(item);
@@ -4920,5 +4929,6 @@
         item->d_ptr->ignoreOpacity = 1;
 
-    item->d_ptr->markParentDirty();
+    if (!updateBoundingRect)
+        item->d_ptr->markParentDirty();
 }
 
@@ -5131,4 +5141,6 @@
 
 /*!
+    \obsolete
+
     Paints the given \a items using the provided \a painter, after the
     background has been drawn, and before the foreground has been
@@ -5153,5 +5165,5 @@
     \snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
 
-    \obsolete Since Qt 4.6, this function is not called anymore unless
+    Since Qt 4.6, this function is not called anymore unless
     the QGraphicsView::IndirectPainting flag is given as an Optimization
     flag.
@@ -5709,6 +5721,13 @@
             bool res = sendTouchBeginEvent(item, &touchEvent)
                        && touchEvent.isAccepted();
-            if (!res)
+            if (!res) {
+                // forget about these touch points, we didn't handle them
+                for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
+                    const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().at(i);
+                    itemForTouchPointId.remove(touchPoint.id());
+                    sceneCurrentTouchPoints.remove(touchPoint.id());
+                }
                 ignoreSceneTouchEvent = false;
+            }
             break;
         }
@@ -5901,11 +5920,19 @@
             QList<QGraphicsObject *> result;
             for (int j = 0; j < items.size(); ++j) {
-                QGraphicsObject *item = items.at(j)->toGraphicsObject();
-                if (!item)
-                    continue;
-                QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
-                if (d->gestureContext.contains(gestureType)) {
-                    result.append(item);
+                QGraphicsItem *item = items.at(j);
+
+                // Check if the item is blocked by a modal panel and use it as
+                // a target instead of this item.
+                (void) item->isBlockedByModalPanel(&item);
+
+                if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
+                    QGraphicsItemPrivate *d = item->d_func();
+                    if (d->gestureContext.contains(gestureType)) {
+                        result.append(itemobj);
+                    }
                 }
+                // Don't propagate through panels.
+                if (item->isPanel())
+                    break;
             }
             DEBUG() << "QGraphicsScenePrivate::getGestureTargets:"
Index: trunk/src/gui/graphicsview/qgraphicsscene_p.h
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsscene_p.h	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsscene_p.h	(revision 769)
@@ -223,5 +223,6 @@
 
     void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
-                   bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false);
+                   bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false,
+                   bool updateBoundingRect = false);
     void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false,
                                     qreal parentOpacity = qreal(1.0));
Index: trunk/src/gui/graphicsview/qgraphicssceneevent.h
===================================================================
--- trunk/src/gui/graphicsview/qgraphicssceneevent.h	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicssceneevent.h	(revision 769)
@@ -78,4 +78,6 @@
     QScopedPointer<QGraphicsSceneEventPrivate> d_ptr;
     Q_DECLARE_PRIVATE(QGraphicsSceneEvent)
+private:
+    Q_DISABLE_COPY(QGraphicsSceneEvent)
 };
 
@@ -125,4 +127,5 @@
 private:
     Q_DECLARE_PRIVATE(QGraphicsSceneMouseEvent)
+    Q_DISABLE_COPY(QGraphicsSceneMouseEvent)
 };
 
@@ -157,4 +160,5 @@
 private:
     Q_DECLARE_PRIVATE(QGraphicsSceneWheelEvent)
+    Q_DISABLE_COPY(QGraphicsSceneWheelEvent)
 };
 
@@ -185,4 +189,5 @@
 private:
     Q_DECLARE_PRIVATE(QGraphicsSceneContextMenuEvent)
+    Q_DISABLE_COPY(QGraphicsSceneContextMenuEvent)
 };
 
@@ -217,4 +222,5 @@
 private:
     Q_DECLARE_PRIVATE(QGraphicsSceneHoverEvent)
+    Q_DISABLE_COPY(QGraphicsSceneHoverEvent)
 };
 
@@ -234,4 +240,5 @@
 private:
     Q_DECLARE_PRIVATE(QGraphicsSceneHelpEvent)
+    Q_DISABLE_COPY(QGraphicsSceneHelpEvent)
 };
 
@@ -276,4 +283,5 @@
 private:
     Q_DECLARE_PRIVATE(QGraphicsSceneDragDropEvent)
+    Q_DISABLE_COPY(QGraphicsSceneDragDropEvent)
 };
 
@@ -282,4 +290,5 @@
 {
     Q_DECLARE_PRIVATE(QGraphicsSceneResizeEvent)
+    Q_DISABLE_COPY(QGraphicsSceneResizeEvent)
 public:
     QGraphicsSceneResizeEvent();
@@ -297,4 +306,5 @@
 {
     Q_DECLARE_PRIVATE(QGraphicsSceneMoveEvent)
+    Q_DISABLE_COPY(QGraphicsSceneMoveEvent)
 public:
     QGraphicsSceneMoveEvent();
Index: trunk/src/gui/graphicsview/qgraphicsview.cpp
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsview.cpp	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsview.cpp	(revision 769)
@@ -3361,10 +3361,4 @@
             if (viewTransformed)
                 backgroundPainter.setTransform(viewTransform);
-#ifdef Q_WS_X11
-#undef X11
-            if (backgroundPainter.paintEngine()->type() != QPaintEngine::X11)
-#define X11 qt_x11Data
-#endif
-                backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
             QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect();
             drawBackground(&backgroundPainter, backgroundExposedSceneRect);
@@ -3401,4 +3395,11 @@
             painter.setWorldTransform(viewTransform);
     } else {
+        // Make sure we don't have unpolished items before we draw
+        if (!d->scene->d_func()->unpolishedItems.isEmpty())
+            d->scene->d_func()->_q_polishItems();
+        // We reset updateAll here (after we've issued polish events)
+        // so that we can discard update requests coming from polishEvent().
+        d->scene->d_func()->updateAll = false;
+
         // Find all exposed items
         bool allItems = false;
@@ -3409,7 +3410,23 @@
             QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
             QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
+            QTransform transform(Qt::Uninitialized);
             for (int i = 0; i < numItems; ++i) {
-                itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform,
-                                                     d->exposedRegion, allItems);
+                QGraphicsItem *item = itemArray[i];
+                QGraphicsItemPrivate *itemd = item->d_ptr.data();
+                itemd->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
+                // Cache the item's area in view coordinates.
+                // Note that we have to do this here in case the base class implementation
+                // (QGraphicsScene::drawItems) is not called. If it is, we'll do this
+                // operation twice, but that's the price one has to pay for using indirect
+                // painting :-/.
+                const QRectF brect = adjustedItemEffectiveBoundingRect(item);
+                if (!itemd->itemIsUntransformable()) {
+                    transform = item->sceneTransform();
+                    if (viewTransformed)
+                        transform *= viewTransform;
+                } else {
+                    transform = item->deviceTransform(viewTransform);
+                }
+                itemd->paintedViewBoundingRects.insert(d->viewport, transform.mapRect(brect).toRect());
             }
             // Draw the items.
@@ -3610,4 +3627,6 @@
 
 /*!
+    \obsolete 
+
     Draws the items \a items in the scene using \a painter, after the
     background and before the foreground are drawn. \a numItems is the number
@@ -3618,5 +3637,5 @@
     The default implementation calls the scene's drawItems() function.
 
-    \obsolete Since Qt 4.6, this function is not called anymore unless
+    Since Qt 4.6, this function is not called anymore unless
     the QGraphicsView::IndirectPainting flag is given as an Optimization
     flag.
Index: trunk/src/gui/graphicsview/qgraphicsview_p.h
===================================================================
--- trunk/src/gui/graphicsview/qgraphicsview_p.h	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicsview_p.h	(revision 769)
@@ -184,6 +184,10 @@
             QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
 #else
-        QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::ExcludeSocketNotifiers
-                                        | QEventLoop::ExcludeUserInputEvents);
+        // At this point either HIViewSetNeedsDisplay (Carbon) or setNeedsDisplay: YES (Cocoa)
+        // is called, which means there's a pending update request. We want to dispatch it
+        // now because otherwise graphics view updates would require two
+        // round-trips in the event loop before the item is painted.
+        extern void qt_mac_dispatchPendingUpdateRequests(QWidget *);
+        qt_mac_dispatchPendingUpdateRequests(viewport->window());
 #endif
     }
Index: trunk/src/gui/graphicsview/qgraphicswidget.cpp
===================================================================
--- trunk/src/gui/graphicsview/qgraphicswidget.cpp	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicswidget.cpp	(revision 769)
@@ -335,5 +335,5 @@
     a move event and a resize event. Also, if the widget has a layout
     assigned, the layout will activate.
-    
+
     \sa geometry(), resize()
 */
@@ -563,5 +563,5 @@
 {
     Q_D(QGraphicsWidget);
-    if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup && 
+    if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
          (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
         QStyleOptionTitleBar bar;
@@ -1045,11 +1045,5 @@
         break;
     case ItemPositionHasChanged:
-        if (!d->inSetGeometry) {
-            d->inSetPos = 1;
-            // Ensure setGeometry is called (avoid recursion when setPos is
-            // called from within setGeometry).
-            setGeometry(QRectF(pos(), size()));
-            d->inSetPos = 0 ;
-        }
+        d->setGeometryFromSetPos();
         break;
     case ItemParentChange: {
@@ -1068,5 +1062,5 @@
         break;
     }
-    case ItemCursorChange: {
+    case ItemCursorHasChanged: {
         // Deliver CursorChange.
         QEvent event(QEvent::CursorChange);
@@ -1074,5 +1068,5 @@
         break;
     }
-    case ItemToolTipChange: {
+    case ItemToolTipHasChanged: {
         // Deliver ToolTipChange.
         QEvent event(QEvent::ToolTipChange);
@@ -1140,5 +1134,5 @@
     Returns true if \a event has been recognized and processed; otherwise,
     returns false.
-    
+
     \sa event()
 */
@@ -1197,5 +1191,5 @@
     if (!r.contains(pos))
         return Qt::NoSection;
-    
+
     const qreal left = r.left();
     const qreal top = r.top();
@@ -2323,4 +2317,4 @@
 
 QT_END_NAMESPACE
-        
+
 #endif //QT_NO_GRAPHICSVIEW
Index: trunk/src/gui/graphicsview/qgraphicswidget_p.cpp
===================================================================
--- trunk/src/gui/graphicsview/qgraphicswidget_p.cpp	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicswidget_p.cpp	(revision 769)
@@ -826,4 +826,16 @@
 }
 
+void QGraphicsWidgetPrivate::setGeometryFromSetPos()
+{
+    if (inSetGeometry)
+        return;
+    Q_Q(QGraphicsWidget);
+    inSetPos = 1;
+    // Ensure setGeometry is called (avoid recursion when setPos is
+    // called from within setGeometry).
+    q->setGeometry(QRectF(pos, q->size()));
+    inSetPos = 0 ;
+}
+
 QT_END_NAMESPACE
 
Index: trunk/src/gui/graphicsview/qgraphicswidget_p.h
===================================================================
--- trunk/src/gui/graphicsview/qgraphicswidget_p.h	(revision 766)
+++ trunk/src/gui/graphicsview/qgraphicswidget_p.h	(revision 769)
@@ -130,4 +130,6 @@
     void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event);
     bool hasDecoration() const;
+
+    void setGeometryFromSetPos();
 
     // State
Index: trunk/src/gui/gui.pro
===================================================================
--- trunk/src/gui/gui.pro	(revision 766)
+++ trunk/src/gui/gui.pro	(revision 769)
@@ -41,5 +41,5 @@
 include(effects/effects.pri)
 
-contains(QT_CONFIG, egl): include(egl/egl.pri)
+include(egl/egl.pri)
 
 embedded: QT += network
@@ -52,7 +52,25 @@
 
 DEFINES += Q_INTERNAL_QAPP_SRC
-symbian:TARGET.UID3=0x2001B2DD
+symbian: {
+    TARGET.UID3=0x2001B2DD
 
-# ro-section in gui can exceed default allocated space, so more rw-section little further
-symbian-sbsv2: QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
-symbian: QMAKE_LFLAGS.GCCE += -Tdata 0xC00000
+    # 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
+}
+
Index: trunk/src/gui/image/qicon.cpp
===================================================================
--- trunk/src/gui/image/qicon.cpp	(revision 766)
+++ trunk/src/gui/image/qicon.cpp	(revision 769)
@@ -105,4 +105,13 @@
 static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
 
+static void qt_cleanup_icon_cache();
+typedef QCache<QString, QIcon> IconCache;
+Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache))
+
+static void qt_cleanup_icon_cache()
+{
+    qtIconCache()->clear();
+}
+
 QIconPrivate::QIconPrivate()
     : engine(0), ref(1),
@@ -964,17 +973,17 @@
 QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
 {
-    static QCache <QString, QIcon> iconCache;
-
     QIcon icon;
 
-    if (iconCache.contains(name)) {
-        icon = *iconCache.object(name);
+    if (qtIconCache()->contains(name)) {
+        icon = *qtIconCache()->object(name);
     } else {
         QIcon *cachedIcon  = new QIcon(new QIconLoaderEngine(name));
-        iconCache.insert(name, cachedIcon);
+        qtIconCache()->insert(name, cachedIcon);
         icon = *cachedIcon;
     }
 
-    if (icon.availableSizes().isEmpty())
+    // Note the qapp check is to allow lazy loading of static icons
+    // Supporting fallbacks will not work for this case.
+    if (qApp && icon.availableSizes().isEmpty())
         return fallback;
 
Index: trunk/src/gui/image/qiconloader.cpp
===================================================================
--- trunk/src/gui/image/qiconloader.cpp	(revision 766)
+++ trunk/src/gui/image/qiconloader.cpp	(revision 769)
@@ -86,17 +86,28 @@
 
 QIconLoader::QIconLoader() :
-        m_themeKey(1), m_supportsSvg(false)
-{
-    m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName();
-    if (m_systemTheme.isEmpty())
-        m_systemTheme = fallbackTheme();
-
+        m_themeKey(1), m_supportsSvg(false), m_initialized(false)
+{
+}
+
+// We lazily initialize the loader to make static icons
+// work. Though we do not officially support this.
+void QIconLoader::ensureInitialized()
+{
+    if (!m_initialized) {
+        m_initialized = true;
+
+        Q_ASSERT(qApp);
+
+        m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName();
+        if (m_systemTheme.isEmpty())
+            m_systemTheme = fallbackTheme();
 #ifndef QT_NO_LIBRARY
-    QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid,
-                                     QLatin1String("/iconengines"),
-                                     Qt::CaseInsensitive);
-    if (iconFactoryLoader.keys().contains(QLatin1String("svg")))
-        m_supportsSvg = true;
+        QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid,
+                                         QLatin1String("/iconengines"),
+                                         Qt::CaseInsensitive);
+        if (iconFactoryLoader.keys().contains(QLatin1String("svg")))
+            m_supportsSvg = true;
 #endif //QT_NO_LIBRARY
+    }
 }
 
@@ -340,4 +351,7 @@
 void QIconLoaderEngine::ensureLoaded()
 {
+
+    iconLoaderInstance()->ensureInitialized();
+
     if (!(iconLoaderInstance()->themeKey() == m_key)) {
 
Index: trunk/src/gui/image/qiconloader_p.h
===================================================================
--- trunk/src/gui/image/qiconloader_p.h	(revision 766)
+++ trunk/src/gui/image/qiconloader_p.h	(revision 769)
@@ -170,4 +170,5 @@
     void updateSystemTheme();
     void invalidateKey() { m_themeKey++; }
+    void ensureInitialized();
 
 private:
@@ -177,4 +178,5 @@
     uint m_themeKey;
     bool m_supportsSvg;
+    bool m_initialized;
 
     mutable QString m_userTheme;
Index: trunk/src/gui/image/qimage.cpp
===================================================================
--- trunk/src/gui/image/qimage.cpp	(revision 766)
+++ trunk/src/gui/image/qimage.cpp	(revision 769)
@@ -119,6 +119,6 @@
 }
 
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_GUI_EXPORT extern int qt_defaultDpiX();
+Q_GUI_EXPORT extern int qt_defaultDpiY();
 
 QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
@@ -5668,5 +5668,9 @@
     detach();
 
-    *this = convertToFormat(QImage::Format_ARGB32_Premultiplied);
+    QImage converted = convertToFormat(QImage::Format_ARGB32_Premultiplied);
+    if (!converted.isNull())
+        *this = converted;
+    else
+        return;
 
     // Slight optimization since alphachannels are returned as 8-bit grays.
Index: trunk/src/gui/image/qimagepixmapcleanuphooks.cpp
===================================================================
--- trunk/src/gui/image/qimagepixmapcleanuphooks.cpp	(revision 766)
+++ trunk/src/gui/image/qimagepixmapcleanuphooks.cpp	(revision 769)
@@ -97,4 +97,9 @@
 {
     QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
+    // the global destructor for the pixmap and image hooks might have
+    // been called already if the app is "leaking" global
+    // pixmaps/images
+    if (!h)
+        return;
     for (int i = 0; i < h->pixmapModificationHooks.count(); ++i)
         h->pixmapModificationHooks[i](pmd);
@@ -107,4 +112,9 @@
 {
     QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
+    // the global destructor for the pixmap and image hooks might have
+    // been called already if the app is "leaking" global
+    // pixmaps/images
+    if (!h)
+        return;
     for (int i = 0; i < h->pixmapDestructionHooks.count(); ++i)
         h->pixmapDestructionHooks[i](pmd);
@@ -123,12 +133,13 @@
 }
 
-void QImagePixmapCleanupHooks::enableCleanupHooks(const QPixmap &pixmap)
-{
-    enableCleanupHooks(const_cast<QPixmap &>(pixmap).data_ptr().data());
-}
 
 void QImagePixmapCleanupHooks::enableCleanupHooks(QPixmapData *pixmapData)
 {
     pixmapData->is_cached = true;
+}
+
+void QImagePixmapCleanupHooks::enableCleanupHooks(const QPixmap &pixmap)
+{
+    enableCleanupHooks(const_cast<QPixmap &>(pixmap).data_ptr().data());
 }
 
@@ -138,3 +149,15 @@
 }
 
+bool QImagePixmapCleanupHooks::isImageCached(const QImage &image)
+{
+    return const_cast<QImage &>(image).data_ptr()->is_cached;
+}
+
+bool QImagePixmapCleanupHooks::isPixmapCached(const QPixmap &pixmap)
+{
+    return const_cast<QPixmap&>(pixmap).data_ptr().data()->is_cached;
+}
+
+
+
 QT_END_NAMESPACE
Index: trunk/src/gui/image/qimagepixmapcleanuphooks_p.h
===================================================================
--- trunk/src/gui/image/qimagepixmapcleanuphooks_p.h	(revision 766)
+++ trunk/src/gui/image/qimagepixmapcleanuphooks_p.h	(revision 769)
@@ -73,4 +73,7 @@
     static void enableCleanupHooks(QPixmapData *pixmapData);
 
+    static bool isImageCached(const QImage &image);
+    static bool isPixmapCached(const QPixmap &pixmap);
+
     // Gets called when a pixmap data is about to be modified:
     void addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd);
Index: trunk/src/gui/image/qimagereader.cpp
===================================================================
--- trunk/src/gui/image/qimagereader.cpp	(revision 766)
+++ trunk/src/gui/image/qimagereader.cpp	(revision 769)
@@ -264,18 +264,29 @@
     }
 
-    if (!handler && !testFormat.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
+    if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) {
         // check if any plugin supports the format (they are not allowed to
         // read from the device yet).
         const qint64 pos = device ? device->pos() : 0;
-        for (int i = 0; i < keys.size(); ++i) {
-            if (i != suffixPluginIndex) {
-                QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
-                if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
+
+        if (autoDetectImageFormat) {
+            for (int i = 0; i < keys.size(); ++i) {
+                if (i != suffixPluginIndex) {
+                    QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
+                    if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
 #ifdef QIMAGEREADER_DEBUG
-                    qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format";
-#endif
-                    handler = plugin->create(device, testFormat);
-                    break;
+                        qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format";
+#endif
+                        handler = plugin->create(device, testFormat);
+                        break;
+                    }
                 }
+            }
+        } else {
+            QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(QLatin1String(testFormat)));
+            if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) {
+#ifdef QIMAGEREADER_DEBUG
+                qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format";
+#endif
+                handler = plugin->create(device, testFormat);
             }
         }
@@ -283,4 +294,5 @@
             device->seek(pos);
     }
+
 #endif // QT_NO_LIBRARY
 
Index: trunk/src/gui/image/qimagewriter.cpp
===================================================================
--- trunk/src/gui/image/qimagewriter.cpp	(revision 766)
+++ trunk/src/gui/image/qimagewriter.cpp	(revision 769)
@@ -198,4 +198,5 @@
             QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
             if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) {
+                delete handler;
                 handler = plugin->create(device, testFormat);
                 break;
Index: trunk/src/gui/image/qnativeimage.cpp
===================================================================
--- trunk/src/gui/image/qnativeimage.cpp	(revision 766)
+++ trunk/src/gui/image/qnativeimage.cpp	(revision 769)
@@ -202,5 +202,5 @@
         ok = (xshminfo.shmaddr != (char*)-1);
         if (ok)
-            image = QImage((uchar *)xshmimg->data, width, height, systemFormat());
+            image = QImage((uchar *)xshmimg->data, width, height, format);
     }
     xshminfo.readOnly = false;
Index: trunk/src/gui/image/qpaintengine_pic.cpp
===================================================================
--- trunk/src/gui/image/qpaintengine_pic.cpp	(revision 766)
+++ trunk/src/gui/image/qpaintengine_pic.cpp	(revision 769)
@@ -478,5 +478,5 @@
 }
 
-extern int qt_defaultDpi();
+Q_GUI_EXPORT extern int qt_defaultDpi();
 
 void QPicturePaintEngine::drawTextItem(const QPointF &p , const QTextItem &ti)
Index: trunk/src/gui/image/qpicture.cpp
===================================================================
--- trunk/src/gui/image/qpicture.cpp	(revision 766)
+++ trunk/src/gui/image/qpicture.cpp	(revision 769)
@@ -109,6 +109,6 @@
 static const quint16 mfhdr_maj = 11; // major version #
 static const quint16 mfhdr_min = 0; // minor version #
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_GUI_EXPORT extern int qt_defaultDpiX();
+Q_GUI_EXPORT extern int qt_defaultDpiY();
 
 /*!
Index: trunk/src/gui/image/qpixmap.cpp
===================================================================
--- trunk/src/gui/image/qpixmap.cpp	(revision 766)
+++ trunk/src/gui/image/qpixmap.cpp	(revision 769)
@@ -832,19 +832,12 @@
         return true;
 
-    bool ok;
-
-    if (data) {
-        ok = data->fromFile(fileName, format, flags);
-    } else {
-        QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, QPixmapData::PixmapType));
-        ok = tmp->fromFile(fileName, format, flags);
-        if (ok)
-            data = tmp.take();
-    }
-
-    if (ok)
+    QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, data ? data->type : QPixmapData::PixmapType));
+    if (tmp->fromFile(fileName, format, flags)) {
+        data = tmp.take();
         QPixmapCache::insert(key, *this);
-
-    return ok;
+        return true;
+    }
+
+    return false;
 }
 
@@ -1671,8 +1664,7 @@
 
     The hasAlphaChannel() returns true if the pixmap has a format that
-    respects the alpha channel, otherwise returns false, while the
-    hasAlpha() function returns true if the pixmap has an alpha
-    channel \e or a mask (otherwise false). The mask() function returns
-    the mask as a QBitmap object, which can be set using setMask().
+    respects the alpha channel, otherwise returns false. The hasAlpha(),
+    setMask() and mask() functions are legacy and should not be used.
+    They are potentially very slow.
 
     The createHeuristicMask() function creates and returns a 1-bpp
@@ -1760,4 +1752,6 @@
     Returns true if this pixmap has an alpha channel, \e or has a
     mask, otherwise returns false.
+
+    \warning This is potentially an expensive operation.
 
     \sa hasAlphaChannel(), mask()
@@ -2028,5 +2022,5 @@
     too. The mouse cursor is generally not grabbed.
 
-    Note on X11that if the given \a window doesn't have the same depth
+    Note on X11 that if the given \a window doesn't have the same depth
     as the root window, and another window partially or entirely
     obscures the one you grab, you will \e not get pixels from the
@@ -2034,4 +2028,8 @@
     pixmap will be undefined and uninitialized.
 
+    On Windows Vista and above grabbing a layered window, which is
+    created by setting the Qt::WA_TranslucentBackground attribute, will
+    not work. Instead grabbing the desktop widget should work.
+
     \warning In general, grabbing an area outside the screen is not
     safe. This depends on the underlying window system.
Index: trunk/src/gui/image/qpixmap_raster.cpp
===================================================================
--- trunk/src/gui/image/qpixmap_raster.cpp	(revision 766)
+++ trunk/src/gui/image/qpixmap_raster.cpp	(revision 769)
@@ -358,6 +358,6 @@
 }
 
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_GUI_EXPORT extern int qt_defaultDpiX();
+Q_GUI_EXPORT extern int qt_defaultDpiY();
 
 int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
Index: trunk/src/gui/image/qpixmap_s60.cpp
===================================================================
--- trunk/src/gui/image/qpixmap_s60.cpp	(revision 766)
+++ trunk/src/gui/image/qpixmap_s60.cpp	(revision 769)
@@ -338,5 +338,5 @@
         return QPixmap();
 
-    QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
+    QScopedPointer<QPixmapData> data(QPixmapData::create(0,0, QPixmapData::PixmapType));
     data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
     QPixmap pixmap(data.take());
@@ -736,5 +736,5 @@
         return QPixmap();
 
-    QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
+    QScopedPointer<QPixmapData> data(QPixmapData::create(0,0, QPixmapData::PixmapType));
     data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
     QPixmap pixmap(data.take());
Index: trunk/src/gui/image/qpixmap_x11.cpp
===================================================================
--- trunk/src/gui/image/qpixmap_x11.cpp	(revision 766)
+++ trunk/src/gui/image/qpixmap_x11.cpp	(revision 769)
@@ -384,5 +384,5 @@
         // Will implicitly also check format and return quickly for opaque types...
         checked = true;
-        has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
+        has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
         return has;
     }
Index: trunk/src/gui/image/qpixmapfilter.cpp
===================================================================
--- trunk/src/gui/image/qpixmapfilter.cpp	(revision 766)
+++ trunk/src/gui/image/qpixmapfilter.cpp	(revision 769)
@@ -423,4 +423,7 @@
         return;
 
+    if (src.isNull())
+        return;
+
     QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
         static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
@@ -775,4 +778,7 @@
 Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source)
 {
+    if (source.width() < 2 || source.height() < 2)
+        return QImage();
+
     QImage srcImage = source;
 
@@ -867,5 +873,5 @@
 
     qreal scale = 1;
-    if (radius >= 4) {
+    if (radius >= 4 && blurImage.width() >= 2 && blurImage.height() >= 2) {
         blurImage = qt_halfScaled(blurImage);
         scale = 2;
@@ -893,5 +899,5 @@
 }
 
-bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
 
 /*!
@@ -902,4 +908,7 @@
     Q_D(const QPixmapBlurFilter);
     if (!painter->isActive())
+        return;
+
+    if (src.isNull())
         return;
 
@@ -1084,4 +1093,8 @@
 {
     Q_D(const QPixmapColorizeFilter);
+
+    if (src.isNull())
+        return;
+
     QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
         static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
@@ -1314,4 +1327,8 @@
 {
     Q_D(const QPixmapDropShadowFilter);
+
+    if (px.isNull())
+        return;
+
     QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ?
         static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0;
Index: trunk/src/gui/inputmethod/inputmethod.pri
===================================================================
--- trunk/src/gui/inputmethod/inputmethod.pri	(revision 766)
+++ trunk/src/gui/inputmethod/inputmethod.pri	(revision 769)
@@ -27,5 +27,5 @@
     HEADERS += inputmethod/qcoefepinputcontext_p.h
     SOURCES += inputmethod/qcoefepinputcontext_s60.cpp
-    LIBS += -lfepbase
+    LIBS += -lfepbase -lakninputlanguage
 }
 
Index: trunk/src/gui/inputmethod/qcoefepinputcontext_p.h
===================================================================
--- trunk/src/gui/inputmethod/qcoefepinputcontext_p.h	(revision 766)
+++ trunk/src/gui/inputmethod/qcoefepinputcontext_p.h	(revision 769)
@@ -97,5 +97,5 @@
 
 private:
-    void commitCurrentString(bool triggeredBySymbian);
+    void commitCurrentString(bool cancelFepTransaction);
     void updateHints(bool mustUpdateInputCapabilities);
     void applyHints(Qt::InputMethodHints hints);
@@ -128,5 +128,5 @@
     void DoCommitFepInlineEditL();
     MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue);
-	void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType);
+    void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType);
 
     // From MCoeFepAwareTextEditor_Extension1
@@ -152,5 +152,4 @@
     MFepInlineTextFormatRetriever *m_formatRetriever;
     MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
-    int m_longPress;
     int m_cursorPos;
     QBasicTimer m_tempPreeditStringTimeout;
Index: trunk/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
===================================================================
--- trunk/src/gui/inputmethod/qcoefepinputcontext_s60.cpp	(revision 766)
+++ trunk/src/gui/inputmethod/qcoefepinputcontext_s60.cpp	(revision 769)
@@ -59,4 +59,9 @@
 #define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7)
 
+// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards.
+// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors
+// that support text selection.
+#define QT_EAknEditorFlagSelectionVisible 0x100000
+
 QT_BEGIN_NAMESPACE
 
@@ -72,14 +77,16 @@
       m_formatRetriever(0),
       m_pointerHandler(0),
-      m_longPress(0),
       m_cursorPos(0),
       m_hasTempPreeditString(false)
 {
     m_fepState->SetObjectProvider(this);
-    m_fepState->SetFlags(EAknEditorFlagDefault);
+    if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
+        m_fepState->SetFlags(EAknEditorFlagDefault | QT_EAknEditorFlagSelectionVisible);
+    else
+        m_fepState->SetFlags(EAknEditorFlagDefault);
     m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
     m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
     m_fepState->SetDefaultCase( EAknEditorLowerCase );
-    m_fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase );
+    m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
     m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
     m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
@@ -102,5 +109,5 @@
 void QCoeFepInputContext::reset()
 {
-    commitCurrentString(false);
+    commitCurrentString(true);
 }
 
@@ -115,5 +122,5 @@
 
     // For pre-5.0 SDKs, we don't do text updates on S60 side.
-    if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) {
+    if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_0) {
         return;
     }
@@ -127,5 +134,5 @@
 void QCoeFepInputContext::setFocusWidget(QWidget *w)
 {
-    commitCurrentString(false);
+    commitCurrentString(true);
 
     QInputContext::setFocusWidget(w);
@@ -220,5 +227,5 @@
         case Qt::Key_Select:
             if (!m_preeditString.isEmpty()) {
-                commitCurrentString(false);
+                commitCurrentString(true);
                 return true;
             }
@@ -232,8 +239,9 @@
             && !keyEvent->text().isEmpty()) {
             // Send some temporary preedit text in order to make text visible for a moment.
+            m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
             m_preeditString = keyEvent->text();
             QList<QInputMethodEvent::Attribute> attributes;
             QInputMethodEvent imEvent(m_preeditString, attributes);
-            QApplication::sendEvent(focusWidget(), &imEvent);
+            sendEvent(imEvent);
             m_tempPreeditStringTimeout.start(1000, this);
             m_hasTempPreeditString = true;
@@ -294,5 +302,5 @@
 
     if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) {
-        commitCurrentString(false);
+        commitCurrentString(true);
         int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
 
@@ -433,5 +441,8 @@
     ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
 
-    flags = 0;
+    if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
+        flags = QT_EAknEditorFlagSelectionVisible;
+    else 
+        flags = 0;
     if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
             || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
@@ -474,7 +485,8 @@
 {
     TCharFormat cFormat;
-    QColor styleTextColor = QApplication::palette("QLineEdit").text().color();
-    TLogicalRgb tontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
-    cFormat.iFontPresentation.iTextColor = tontColor;
+    const QColor styleTextColor = focusWidget() ? focusWidget()->palette().text().color() : 
+        QApplication::palette("QLineEdit").text().color();
+    const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
+    cFormat.iFontPresentation.iTextColor = fontColor;
 
     TInt numChars = 0;
@@ -551,4 +563,19 @@
     m_formatRetriever = &aInlineTextFormatRetriever;
     m_pointerHandler = &aPointerEventHandlerDuringInlineEdit;
+
+    // With T9 aInitialInlineText is typically empty when StartFepInlineEditL is called,
+    // but FEP requires that selected text is always removed at StartFepInlineEditL.
+    // Let's remove the selected text if aInitialInlineText is empty and there is selected text
+    if (m_preeditString.isEmpty()) {
+        int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt();
+        int replacementLength = qAbs(m_cursorPos-anchor);
+        if (replacementLength > 0) {
+            int replacementStart = m_cursorPos < anchor ? 0 : -replacementLength;
+            QList<QInputMethodEvent::Attribute> clearSelectionAttributes;
+            QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes);
+            clearSelectionEvent.setCommitString(QLatin1String(""), replacementStart, replacementLength);
+            sendEvent(clearSelectionEvent);
+        }
+    }
 
     applyFormat(&attributes);
@@ -740,29 +767,33 @@
 void QCoeFepInputContext::DoCommitFepInlineEditL()
 {
-    commitCurrentString(true);
-}
-
-void QCoeFepInputContext::commitCurrentString(bool triggeredBySymbian)
-{
+    commitCurrentString(false);
+    if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
+        ReportAknEdStateEvent(QT_EAknCursorPositionChanged);
+
+}
+
+void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
+{
+    int longPress = 0;
+
     if (m_preeditString.size() == 0) {
         QWidget *w = focusWidget();
-        if (triggeredBySymbian && w) {
+        if (!cancelFepTransaction && w) {
             // We must replace the last character only if the input box has already accepted one 
             if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos)
-                m_longPress = 1;
-        }
-        return;
+                longPress = 1;
+        }
     }
 
     QList<QInputMethodEvent::Attribute> attributes;
     QInputMethodEvent event(QLatin1String(""), attributes);
-    event.setCommitString(m_preeditString, 0-m_longPress, m_longPress);
+    event.setCommitString(m_preeditString, 0-longPress, longPress);
     m_preeditString.clear();
     sendEvent(event);
 
     m_hasTempPreeditString = false;
-    m_longPress = 0;
-
-    if (!triggeredBySymbian) {
+    longPress = 0;
+
+    if (cancelFepTransaction) {
         CCoeFep* fep = CCoeEnv::Static()->Fep();
         if (fep)
Index: trunk/src/gui/inputmethod/qinputcontextfactory.cpp
===================================================================
--- trunk/src/gui/inputmethod/qinputcontextfactory.cpp	(revision 766)
+++ trunk/src/gui/inputmethod/qinputcontextfactory.cpp	(revision 769)
@@ -74,4 +74,5 @@
 #ifdef Q_WS_S60
 #include "qcoefepinputcontext_p.h"
+#include "akninputlanguageinfo.h"
 #endif
 
@@ -199,4 +200,40 @@
 }
 
+#if defined(Q_WS_S60)
+/*!
+    \internal
+
+    This function contains pure Symbian exception handling code for
+    getting S60 language list.
+    Returned object ownership is transfered to caller.
+*/
+static CAknInputLanguageList* s60LangListL()
+{
+    CAknInputLanguageInfo *langInfo = AknInputLanguageInfoFactory::CreateInputLanguageInfoL();
+    CleanupStack::PushL(langInfo);
+    // In rare phone there is more than 7 languages installed -> use 7 as an array granularity
+    CAknInputLanguageList *langList = new (ELeave) CAknInputLanguageList(7);
+    CleanupStack::PushL(langList);
+    langInfo->AppendAvailableLanguagesL(langList);
+    CleanupStack::Pop(langList);
+    CleanupStack::PopAndDestroy(langInfo);
+    return langList;
+}
+
+/*!
+    \internal
+
+    This function utility function return S60 language list.
+    Returned object ownership is transfered to caller.
+*/
+static CAknInputLanguageList* s60LangList()
+{
+    CAknInputLanguageList *langList = NULL;
+    TRAP_IGNORE(langList = s60LangListL());
+    q_check_ptr(langList);
+    return langList;
+}
+#endif
+
 /*!
     Returns the languages supported by the QInputContext object
@@ -230,5 +267,13 @@
 #if defined(Q_WS_S60)
     if (key == QLatin1String("coefep"))
-        return QStringList(QString());
+        {
+        CAknInputLanguageList *langList = s60LangList();
+        int count = langList->Count();
+        for (int i = 0; i < count; ++i)
+            {
+            result.append(QString(qt_symbianLocaleName(langList->At(i)->LanguageCode())));
+            }
+        delete langList;
+        }
 #endif
 #if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
Index: trunk/src/gui/itemviews/qabstractitemview.cpp
===================================================================
--- trunk/src/gui/itemviews/qabstractitemview.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qabstractitemview.cpp	(revision 769)
@@ -1541,4 +1541,9 @@
         d->doDelayedItemsLayout(); // the size of the items will change
         break;
+#ifdef QT_SOFTKEYS_ENABLED
+    case QEvent::LanguageChange:
+        d->doneSoftKey->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::DoneSoftKey));
+        break;
+#endif
     default:
         break;
@@ -1781,5 +1786,8 @@
         if (edited)
             return;
-        if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this))
+        QStyleOptionViewItemV4 option = d->viewOptionsV4();
+        if (d->pressedAlreadySelected)
+            option.state |= QStyle::State_Selected;
+        if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
             emit activated(index);
     }
@@ -2115,4 +2123,9 @@
     QAbstractScrollArea::focusOutEvent(event);
     d->viewport->update();
+
+#ifdef QT_SOFTKEYS_ENABLED
+    if(!hasEditFocus())
+        removeAction(d->doneSoftKey);
+#endif
 }
 
@@ -2140,5 +2153,10 @@
                 setEditFocus(true);
 #ifdef QT_SOFTKEYS_ENABLED
-                addAction(d->doneSoftKey);
+                // If we can't keypad navigate to any direction, there is no sense to add
+                // "Done" softkey, since it basically does nothing when there is
+                // only one widget in screen
+                if(QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
+                        || QWidgetPrivate::canKeypadNavigate(Qt::Vertical))
+                    addAction(d->doneSoftKey);
 #endif
                 return;
@@ -2156,4 +2174,24 @@
         }
         return;
+    case Qt::Key_Down:
+    case Qt::Key_Up:
+        // Let's ignore vertical navigation events, only if there is no other widget
+        // what can take the focus in vertical direction. This means widget can handle navigation events
+        // even the widget don't have edit focus, and there is no other widget in requested direction.
+        if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
+                && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
+            event->ignore();
+            return;
+        }
+        break;
+    case Qt::Key_Left:
+    case Qt::Key_Right:
+        // Similar logic as in up and down events
+        if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
+                && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this))) {
+            event->ignore();
+            return;
+        }
+        break;
     default:
         if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
@@ -2241,5 +2279,5 @@
     case Qt::Key_Up:
 #ifdef QT_KEYPAD_NAVIGATION
-        if (QApplication::keypadNavigationEnabled()) {
+        if (QApplication::keypadNavigationEnabled() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
             event->accept(); // don't change focus
             break;
@@ -2249,6 +2287,8 @@
     case Qt::Key_Right:
 #ifdef QT_KEYPAD_NAVIGATION
-        if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
-            event->accept(); // don't change horizontal focus in directional mode
+        if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+                && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
+                || (QWidgetPrivate::inTabWidget(this) && d->model->columnCount(d->root) > 1))) {
+            event->accept(); // don't change focus
             break;
         }
@@ -2532,4 +2572,5 @@
     QList<QEditorInfo>::iterator it = d->editors.begin();
     QWidgetList editorsToRelease;
+    QWidgetList editorsToHide;
     while (it != d->editors.end()) {
         QModelIndex index = it->index;
@@ -2543,5 +2584,5 @@
                     delegate->updateEditorGeometry(editor, option, index);
             } else {
-                editor->hide();
+                editorsToHide << editor;
             }
             ++it;
@@ -2552,6 +2593,9 @@
     }
 
-    //we release the editor outside of the loop because it might change the focus and try
+    //we hide and release the editor outside of the loop because it might change the focus and try
     //to change the d->editors list.
+    for (int i = 0; i < editorsToHide.count(); ++i) {
+        editorsToHide.at(i)->hide();
+    }
     for (int i = 0; i < editorsToRelease.count(); ++i) {
         d->releaseEditor(editorsToRelease.at(i));
@@ -3010,4 +3054,5 @@
         return;
     if (QWidget *oldWidget = indexWidget(index)) {
+        d->persistent.remove(oldWidget);
         d->removeEditor(oldWidget);
         oldWidget->deleteLater();
Index: trunk/src/gui/itemviews/qabstractproxymodel.cpp
===================================================================
--- trunk/src/gui/itemviews/qabstractproxymodel.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qabstractproxymodel.cpp	(revision 769)
@@ -128,4 +128,5 @@
         d->model = QAbstractItemModelPrivate::staticEmptyModel();
     }
+    d->roleNames = d->model->roleNames();
 }
 
Index: trunk/src/gui/itemviews/qfileiconprovider.cpp
===================================================================
--- trunk/src/gui/itemviews/qfileiconprovider.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qfileiconprovider.cpp	(revision 769)
@@ -69,4 +69,5 @@
 #ifndef SHGFI_ADDOVERLAYS
 #  define SHGFI_ADDOVERLAYS 0x000000020
+#  define SHGFI_OVERLAYINDEX 0x000000040
 #endif
 
@@ -254,10 +255,12 @@
 #ifndef Q_OS_WINCE
     val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
-                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
+                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
 #else
     val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
                         sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
 #endif
-    if (val) {
+
+    // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
+    if (val && info.hIcon) {
         if (fileInfo.isDir() && !fileInfo.isRoot()) {
             //using the unique icon index provided by windows save us from duplicate keys
@@ -293,10 +296,10 @@
 #ifndef Q_OS_WINCE
     val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
-                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
+                        sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
 #else
     val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
                         sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX);
 #endif
-    if (val) {
+    if (val && info.hIcon) {
         if (fileInfo.isDir() && !fileInfo.isRoot()) {
             //using the unique icon index provided by windows save us from duplicate keys
Index: trunk/src/gui/itemviews/qitemdelegate.cpp
===================================================================
--- trunk/src/gui/itemviews/qitemdelegate.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qitemdelegate.cpp	(revision 769)
@@ -1034,5 +1034,5 @@
     }
 
-    return QString::fromUtf16(ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
+    return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
 }
 
@@ -1298,12 +1298,6 @@
     }
 
-    Qt::CheckState state;
-    if ( flags & Qt::ItemIsTristate ) {
-        state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 );
-    } else {
-        state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
+    Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
                             ? Qt::Unchecked : Qt::Checked);
-    }
-
     return model->setData(index, state, Qt::CheckStateRole);
 }
Index: trunk/src/gui/itemviews/qlistview.cpp
===================================================================
--- trunk/src/gui/itemviews/qlistview.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qlistview.cpp	(revision 769)
@@ -2161,5 +2161,5 @@
         if (flowPositions.isEmpty())
             return;
-        const int max = flowPositions.count() - 1;
+        const int max = scrollValueMap.count() - 1;
         if (vertical && flow() == QListView::TopToBottom && dy != 0) {
             int currentValue = qBound(0, verticalValue, max);
Index: trunk/src/gui/itemviews/qstyleditemdelegate.cpp
===================================================================
--- trunk/src/gui/itemviews/qstyleditemdelegate.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qstyleditemdelegate.cpp	(revision 769)
@@ -748,11 +748,6 @@
     }
 
-    Qt::CheckState state;
-    if ( flags & Qt::ItemIsTristate ) {
-        state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 );
-    } else {
-        state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
+    Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
                             ? Qt::Unchecked : Qt::Checked);
-    }
     return model->setData(index, state, Qt::CheckStateRole);
 }
Index: trunk/src/gui/itemviews/qtableview.cpp
===================================================================
--- trunk/src/gui/itemviews/qtableview.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qtableview.cpp	(revision 769)
@@ -115,13 +115,12 @@
     } else if (old_height > span->height()) {
         //remove the span from all the subspans lists that intersect the columns not covered anymore
-        Index::iterator it_y = index.lowerBound(-span->bottom());
-        if (it_y == index.end())
-            it_y = index.find(-span->top());    // This is the only span remaining and we are deleting it.
+        Index::iterator it_y = index.lowerBound(-qMax(span->bottom(), span->top())); //qMax usefull if height is 0
         Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list
         while (-it_y.key() <= span->top() + old_height -1) {
             if (-it_y.key() > span->bottom()) {
-                (*it_y).remove(-span->left());
+                int removed = (*it_y).remove(-span->left());
+                Q_ASSERT(removed == 1); Q_UNUSED(removed);
                 if (it_y->isEmpty()) {
-                    it_y = index.erase(it_y) - 1;
+                    it_y = index.erase(it_y);
                 }
             }
@@ -1909,4 +1908,5 @@
         }
     } else { // nothing moved
+        const int gridAdjust = showGrid() ? 1 : 0;
         for (int i = 0; i < selection.count(); ++i) {
             QItemSelectionRange range = selection.at(i);
@@ -1917,7 +1917,14 @@
             const int rtop = rowViewportPosition(range.top());
             const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
-            const int rleft = columnViewportPosition(range.left());
-            const int rright = columnViewportPosition(range.right()) + columnWidth(range.right());
-            selectionRegion += QRect(QPoint(rleft, rtop), QPoint(rright, rbottom));
+            int rleft;
+            int rright;
+            if (isLeftToRight()) {
+                rleft = columnViewportPosition(range.left());
+                rright = columnViewportPosition(range.right()) + columnWidth(range.right());
+            } else {
+                rleft = columnViewportPosition(range.right());
+                rright = columnViewportPosition(range.left()) + columnWidth(range.left());
+            }
+            selectionRegion += QRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));
             if (d->hasSpans()) {
                 foreach (QSpanCollection::Span *s,
@@ -2547,5 +2554,5 @@
     if (!d->isIndexValid(index)
         || (d->model->parent(index) != d->root)
-        || isIndexHidden(index))
+        || isRowHidden(index.row()) || isColumnHidden(index.column()))
         return;
 
Index: trunk/src/gui/itemviews/qtreeview.cpp
===================================================================
--- trunk/src/gui/itemviews/qtreeview.cpp	(revision 766)
+++ trunk/src/gui/itemviews/qtreeview.cpp	(revision 769)
@@ -2475,8 +2475,9 @@
         QVector<QTreeViewItem> insertedItems(delta);
         for (int i = 0; i < delta; ++i) {
-            insertedItems[i].index = d->model->index(i + start, 0, parent);
-            insertedItems[i].level = childLevel;
-            insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index);
-            insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1));
+            QTreeViewItem &item = insertedItems[i];
+            item.index = d->model->index(i + start, 0, parent);
+            item.level = childLevel;
+            item.hasChildren = d->hasVisibleChildren(item.index);
+            item.hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1));
         }
         if (d->viewItems.isEmpty())
@@ -3770,8 +3771,13 @@
             viewItems[previousSibiling].hasMoreSiblings = false;
 
-
-        updateChildCount(parentItem, -removedCount);
-        if (parentItem != -1 && viewItems.at(parentItem).total == 0)
-            viewItems[parentItem].hasChildren = false; //every children have been removed;
+        if (parentItem != -1) {
+            if (viewItems.at(parentItem).expanded) {
+                updateChildCount(parentItem, -removedCount);
+                if (viewItems.at(parentItem).total == 0)
+                    viewItems[parentItem].hasChildren = false; //every children have been removed;
+            } else if (viewItems[parentItem].hasChildren && !hasVisibleChildren(parent)) {
+                viewItems[parentItem].hasChildren = false;
+            }
+        }
         if (after) {
             q->updateGeometries();
Index: trunk/src/gui/kernel/qapplication.cpp
===================================================================
--- trunk/src/gui/kernel/qapplication.cpp	(revision 766)
+++ trunk/src/gui/kernel/qapplication.cpp	(revision 769)
@@ -139,5 +139,5 @@
 QT_BEGIN_NAMESPACE
 
-extern void qt_call_post_routines();
+Q_DECL_IMPORT extern void qt_call_post_routines();
 
 int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0
@@ -895,4 +895,12 @@
     QWidgetPrivate::mapper = new QWidgetMapper;
     QWidgetPrivate::allWidgets = new QWidgetSet;
+
+#if !defined(Q_WS_X11) && !defined(Q_WS_QWS)
+    // initialize the graphics system - on X11 this is initialized inside
+    // qt_init() in qapplication_x11.cpp because of several reasons.
+    // On QWS, the graphics system is set by the QScreen plugin.
+    graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
+#endif
+
     if (qt_appType != QApplication::Tty)
         (void) QApplication::style();  // trigger creation of application style
@@ -929,10 +937,4 @@
     qInitDrawhelperAsm();
 
-#if !defined(Q_WS_X11) && !defined(Q_WS_QWS)
-    // initialize the graphics system - on X11 this is initialized inside
-    // qt_init() in qapplication_x11.cpp because of several reasons.
-    // On QWS, the graphics system is set by the QScreen plugin.
-    graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
-#endif
 #ifndef QT_NO_WHEELEVENT
     QApplicationPrivate::wheel_scroll_lines = 3;
Index: trunk/src/gui/kernel/qapplication_mac.mm
===================================================================
--- trunk/src/gui/kernel/qapplication_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qapplication_mac.mm	(revision 769)
@@ -2144,4 +2144,5 @@
 
             if (wheel_deltaX || wheel_deltaY) {
+#ifndef QT_NO_WHEELEVENT
                 if (wheel_deltaX) {
                     QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
@@ -2166,4 +2167,5 @@
                     }
                 }
+#endif // QT_NO_WHEELEVENT
             } else {
 #ifdef QMAC_SPEAK_TO_ME
@@ -2718,4 +2720,5 @@
 }
 
+#ifndef QT_NO_WHEELEVENT
 void QApplication::setWheelScrollLines(int n)
 {
@@ -2727,4 +2730,5 @@
     return QApplicationPrivate::wheel_scroll_lines;
 }
+#endif
 
 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
@@ -2889,7 +2893,9 @@
         QApplication::setCursorFlashTime(num);
 
+#ifndef QT_NO_WHEELEVENT
         num = settings.value(QLatin1String("wheelScrollLines"),
                             QApplication::wheelScrollLines()).toInt();
         QApplication::setWheelScrollLines(num);
+#endif
 
         QString colorspec = settings.value(QLatin1String("colorSpec"),
Index: trunk/src/gui/kernel/qapplication_p.h
===================================================================
--- trunk/src/gui/kernel/qapplication_p.h	(revision 766)
+++ trunk/src/gui/kernel/qapplication_p.h	(revision 769)
@@ -429,5 +429,7 @@
     static int  mouse_double_click_time;
     static int  keyboard_input_time;
+#ifndef QT_NO_WHEELEVENT
     static int  wheel_scroll_lines;
+#endif
 
     static bool animate_ui;
@@ -533,4 +535,5 @@
 
 #if defined(Q_WS_WIN)
+    static bool HasTouchSupport;
     static PtrRegisterTouchWindow RegisterTouchWindow;
     static PtrGetTouchInputInfo GetTouchInputInfo;
@@ -568,5 +571,6 @@
 #endif
 
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
+    int pressureSupported;
     int maxTouchPressure;
     QList<QTouchEvent::TouchPoint> appAllTouchPoints;
Index: trunk/src/gui/kernel/qapplication_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qapplication_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qapplication_s60.cpp	(revision 769)
@@ -53,4 +53,5 @@
 #include "qdebug.h"
 #include "qimage.h"
+#include "qcombobox.h"
 #include "private/qkeymapper_p.h"
 #include "private/qfont_p.h"
@@ -64,5 +65,5 @@
 
 #include "apgwgnam.h" // For CApaWindowGroupName
-#include <MdaAudioTonePlayer.h>     // For CMdaAudioToneUtility
+#include <mdaaudiotoneplayer.h>     // For CMdaAudioToneUtility
 
 #if defined(Q_WS_S60)
@@ -73,4 +74,5 @@
 # include <private/qs60mainapplication_p.h>
 # include <centralrepository.h>
+# include "qs60mainappui.h"
 #endif
 
@@ -372,6 +374,11 @@
     if (S60->curWin == this)
         S60->curWin = 0;
-    if (!QApplicationPrivate::is_app_closing)
-        setFocusSafely(false);
+    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;
@@ -401,13 +408,20 @@
 {
     QApplicationPrivate *d = QApplicationPrivate::instance();
+    qreal pressure;
+    if(d->pressureSupported
+        && event->Pressure() > 0) //workaround for misconfigured HAL
+        pressure = event->Pressure() / qreal(d->maxTouchPressure);
+    else
+        pressure = qreal(1.0);
 
     QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget);
 
-    while (d->appAllTouchPoints.count() <= event->PointerNumber())
-        d->appAllTouchPoints.append(QTouchEvent::TouchPoint(d->appAllTouchPoints.count()));
+    QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints;
+    while (points.count() <= event->PointerNumber())
+        points.append(QTouchEvent::TouchPoint(points.count()));
 
     Qt::TouchPointStates allStates = 0;
-    for (int i = 0; i < d->appAllTouchPoints.count(); ++i) {
-        QTouchEvent::TouchPoint &touchPoint = d->appAllTouchPoints[i];
+    for (int i = 0; i < points.count(); ++i) {
+        QTouchEvent::TouchPoint &touchPoint = points[i];
 
         if (touchPoint.id() == event->PointerNumber()) {
@@ -434,10 +448,10 @@
             touchPoint.setState(state);
 
-            QPointF screenPos = QPointF(event->iPosition.iX, event->iPosition.iY);
+            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));
+            touchPoint.setPressure(pressure);
         } else if (touchPoint.state() != Qt::TouchPointReleased) {
             // all other active touch points should be marked as stationary
@@ -451,9 +465,11 @@
         // all touch points released
         d->appAllTouchPoints.clear();
+    } else {
+        d->appAllTouchPoints = points;
     }
 
     QApplicationPrivate::translateRawTouchEvent(qwidget,
                                                 QTouchEvent::TouchScreen,
-                                                d->appAllTouchPoints);
+                                                points);
 }
 #endif
@@ -533,4 +549,12 @@
     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(
@@ -598,5 +622,7 @@
                 keyEvent.iCode);
         int keyCode;
-        if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
+        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;
@@ -626,8 +652,10 @@
                 QPoint pos = QCursor::pos();
                 TPointerEvent fakeEvent;
+                fakeEvent.iType = (TPointerEvent::TType)(-1);
                 TInt x = pos.x();
                 TInt y = pos.y();
                 if (type == EEventKeyUp) {
-                    if (keyCode == Qt::Key_Select)
+                    if (keyCode == Qt::Key_Select &&
+                        (S60->virtualMousePressedKeys & QS60Data::Select))
                         fakeEvent.iType = TPointerEvent::EButton1Up;
                     S60->virtualMouseAccel = 1;
@@ -678,6 +706,5 @@
                         // 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;
+                        if (S60->virtualMousePressedKeys & QS60Data::Select) {
                             return EKeyWasConsumed;
                         } else {
@@ -702,5 +729,6 @@
                 fakeEvent.iPosition = cpos;
                 fakeEvent.iParentPosition = epos;
-                HandlePointerEvent(fakeEvent);
+                if(fakeEvent.iType != -1)
+                    HandlePointerEvent(fakeEvent);
                 return EKeyWasConsumed;
             }
@@ -907,4 +935,7 @@
             if (!slowResize && tlwExtra)
                 tlwExtra->inTopLevelResize = false;
+        } else {
+            QResizeEvent *e = new QResizeEvent(newSize, oldSize);
+            QApplication::postEvent(qwidget, e);
         }
     }
@@ -965,14 +996,18 @@
 #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();
+        CEikStatusPane *statusPane = S60->statusPane();
+        CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
         TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
         if (statusPane)
             statusPane->MakeVisible(visible);
-        if (buttonGroup)
-            buttonGroup->MakeVisible(visible);
+        if (buttonGroup) {
+            // Visibility
+            const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+            const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+            buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint));
+        }
 #endif
     } else if (QApplication::activeWindow() == qwidget->window()) {
-        if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
+        if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
             QWidget *fw = QApplication::focusWidget();
             if (fw) {
@@ -989,14 +1024,30 @@
 }
 
+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:
-        if (qwidget->isFullScreen()) {
-            SetExtentToWholeScreen();
-        } else if (qwidget->isMaximized()) {
-            TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
-            SetExtent(r.iTl, r.Size());
-        }
+        handleClientAreaChange();
         if (IsFocused() && IsVisible()) {
             qwidget->d_func()->setWindowIcon_sys(true);
@@ -1010,10 +1061,5 @@
     case KEikDynamicLayoutVariantSwitch:
     {
-        if (qwidget->isFullScreen()) {
-            SetExtentToWholeScreen();
-        } else if (qwidget->isMaximized()) {
-            TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
-            SetExtent(r.iTl, r.Size());
-        }
+        handleClientAreaChange();
         break;
     }
@@ -1146,4 +1192,8 @@
 #endif
         S60->wsSession().SetAutoFlush(ETrue);
+
+#ifdef Q_SYMBIAN_WINDOW_SIZE_CACHE
+    TRAP_IGNORE(S60->wsSession().EnableWindowSizeCacheL());
+#endif
 
     S60->updateScreenSize();
@@ -1209,4 +1259,5 @@
 
     S60->avkonComponentsSupportTransparency = false;
+    S60->menuBeingConstructed = false;
 
 #ifdef Q_WS_S60
@@ -1224,5 +1275,5 @@
         }
     }
-#endif    
+#endif
 
     if (touch) {
@@ -1379,8 +1430,10 @@
 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
@@ -1422,4 +1475,7 @@
 void QApplicationPrivate::closePopup(QWidget *popup)
 {
+    if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+        static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse);
+
     if (!QApplicationPrivate::popupWidgets)
         return;
@@ -1445,4 +1501,7 @@
               : 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);
@@ -1870,4 +1929,6 @@
 {
 #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+    if (HAL::Get(HALData::EPointer3DPressureSupported, pressureSupported) != KErrNone)
+        pressureSupported = 0;
     if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone)
         maxTouchPressure = KMaxTInt;
Index: trunk/src/gui/kernel/qapplication_win.cpp
===================================================================
--- trunk/src/gui/kernel/qapplication_win.cpp	(revision 766)
+++ trunk/src/gui/kernel/qapplication_win.cpp	(revision 769)
@@ -116,4 +116,6 @@
 #endif
 
+#include "private/qwinnativepangesturerecognizer_win_p.h"
+
 #ifndef WM_TOUCH
 #  define WM_TOUCH 0x0240
@@ -929,5 +931,9 @@
     bool icon;
     QString cname;
-    if (flags & Qt::MSWindowsOwnDC) {
+    if (qt_widget_private(w)->isGLWidget) {
+        cname = QLatin1String("QGLWidget");
+        style = CS_DBLCLKS;
+        icon  = true;
+    } else if (flags & Qt::MSWindowsOwnDC) {
         cname = QLatin1String("QWidgetOwnDC");
         style = CS_DBLCLKS;
@@ -1022,5 +1028,5 @@
     wc.hCursor      = 0;
 #ifndef Q_WS_WINCE
-    wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
+    wc.hbrBackground = qt_widget_private(w)->isGLWidget ? 0 : (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
 #else
     wc.hbrBackground = 0;
@@ -1902,6 +1908,11 @@
 
             if (!msg.wParam) {
+#ifdef Q_WS_WINCE
+                // On Windows CE, lParam parameter is a constant, not a char pointer.
+                if (msg.lParam == INI_INTL) {
+#else
                 QString area = QString::fromWCharArray((wchar_t*)msg.lParam);
                 if (area == QLatin1String("intl")) {
+#endif
                     QLocalePrivate::updateSystemPrivate();
                     if (!widget->testAttribute(Qt::WA_SetLocale))
@@ -2437,5 +2448,5 @@
             else
 #ifndef QT_NO_MENUBAR
-                QMenuBar::wceCommands(LOWORD(wParam), (HWND) lParam);
+                QMenuBar::wceCommands(LOWORD(wParam));
 #endif
             result = true;
@@ -2516,4 +2527,5 @@
             result = false;
             break;
+#if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
         case WM_GESTURE: {
             GESTUREINFO gi;
@@ -2548,4 +2560,5 @@
             break;
         }
+#endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
         default:
             result = false;                        // event was not processed
@@ -3617,11 +3630,17 @@
 
     setAttribute(Qt::WA_PendingUpdate, false);
-    const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
-    // Make sure the invalidated region contains the region we're about to repaint.
-    // BeginPaint will set the clip to the invalidated region and it is impossible
-    // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
-    // as it may return an invalid context (especially on Windows Vista).
-    if (!dirtyInBackingStore.isEmpty())
-        InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
+
+    if (d_func()->isGLWidget) {
+        if (d_func()->usesDoubleBufferedGLContext)
+            InvalidateRect(internalWinId(), 0, false);
+    } else {
+        const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
+        // Make sure the invalidated region contains the region we're about to repaint.
+        // BeginPaint will set the clip to the invalidated region and it is impossible
+        // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
+        // as it may return an invalid context (especially on Windows Vista).
+        if (!dirtyInBackingStore.isEmpty())
+            InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
+    }
     PAINTSTRUCT ps;
     d_func()->hd = BeginPaint(internalWinId(), &ps);
@@ -3984,4 +4003,5 @@
 
 
+bool QApplicationPrivate::HasTouchSupport = false;
 PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0;
 PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0;
@@ -3990,4 +4010,36 @@
 void QApplicationPrivate::initializeMultitouch_sys()
 {
+    static const IID QT_IID_IInkTablets = {0x112086D9, 0x7779, 0x4535, {0xA6, 0x99, 0x86, 0x2B, 0x43, 0xAC, 0x18, 0x63} };
+    static const IID QT_IID_IInkTablet2 = {0x90c91ad2, 0xfa36, 0x49d6, {0x95, 0x16, 0xce, 0x8d, 0x57, 0x0f, 0x6f, 0x85} };
+    static const CLSID QT_CLSID_InkTablets = {0x6E4FCB12, 0x510A, 0x4d40, {0x93, 0x04, 0x1D, 0xA1, 0x0A, 0xE9, 0x14, 0x7C} };
+
+    IInkTablets *iInkTablets = 0;
+    HRESULT hr = CoCreateInstance(QT_CLSID_InkTablets, NULL, CLSCTX_ALL, QT_IID_IInkTablets, (void**)&iInkTablets);
+    if (SUCCEEDED(hr)) {
+        long count = 0;
+        iInkTablets->get_Count(&count);
+        for (long i = 0; i < count; ++i) {
+            IInkTablet *iInkTablet = 0;
+            hr = iInkTablets->Item(i, &iInkTablet);
+            if (FAILED(hr))
+                continue;
+            IInkTablet2 *iInkTablet2 = 0;
+            hr = iInkTablet->QueryInterface(QT_IID_IInkTablet2, (void**)&iInkTablet2);
+            iInkTablet->Release();
+            if (FAILED(hr))
+                continue;
+            TabletDeviceKind kind;
+            hr = iInkTablet2->get_DeviceKind(&kind);
+            iInkTablet2->Release();
+            if (FAILED(hr))
+                continue;
+            if (kind == TDK_Touch) {
+                QApplicationPrivate::HasTouchSupport = true;
+                break;
+            }
+        }
+        iInkTablets->Release();
+    }
+
     QLibrary library(QLatin1String("user32"));
     // MinGW (g++ 3.4.5) accepts only C casts.
Index: trunk/src/gui/kernel/qapplication_x11.cpp
===================================================================
--- trunk/src/gui/kernel/qapplication_x11.cpp	(revision 766)
+++ trunk/src/gui/kernel/qapplication_x11.cpp	(revision 769)
@@ -97,4 +97,9 @@
 #endif
 
+#ifndef QT_GUI_DOUBLE_CLICK_RADIUS
+#define QT_GUI_DOUBLE_CLICK_RADIUS 5
+#endif
+
+
 //#define ALIEN_DEBUG
 
@@ -316,7 +321,12 @@
     "_XEMBED_INFO\0"
 
+    // Wacom old. (before version 0.10)
     "Wacom Stylus\0"
     "Wacom Cursor\0"
     "Wacom Eraser\0"
+
+    // Tablet
+    "STYLUS\0"
+    "ERASER\0"
 };
 
@@ -945,8 +955,10 @@
     QApplication::setCursorFlashTime(num);
 
+#ifndef QT_NO_WHEELEVENT
     num =
         settings.value(QLatin1String("wheelScrollLines"),
                        QApplication::wheelScrollLines()).toInt();
     QApplication::setWheelScrollLines(num);
+#endif
 
     QString colorspec = settings.value(QLatin1String("colorSpec"),
@@ -2360,10 +2372,10 @@
                 }
 #else
-                if (devs->type == ATOM(XWacomStylus)) {
+                if (devs->type == ATOM(XWacomStylus) || devs->type == ATOM(XTabletStylus)) {
                     deviceType = QTabletEvent::Stylus;
                     if (wacomDeviceName()->isEmpty())
                         wacomDeviceName()->append(devs->name);
                     gotStylus = true;
-                } else if (devs->type == ATOM(XWacomEraser)) {
+                } else if (devs->type == ATOM(XWacomEraser) || devs->type == ATOM(XTabletEraser)) {
                     deviceType = QTabletEvent::XFreeEraser;
                     gotEraser = true;
@@ -4214,6 +4226,6 @@
                 (long)event->xbutton.time -(long)mouseButtonPressTime
                 < QApplication::doubleClickInterval() &&
-                qAbs(event->xbutton.x - mouseXPos) < 5 &&
-                qAbs(event->xbutton.y - mouseYPos) < 5) {
+                qAbs(event->xbutton.x - mouseXPos) < QT_GUI_DOUBLE_CLICK_RADIUS &&
+                qAbs(event->xbutton.y - mouseYPos) < QT_GUI_DOUBLE_CLICK_RADIUS) {
                 type = QEvent::MouseButtonDblClick;
                 mouseButtonPressTime -= 2000;        // no double-click next time
@@ -4402,6 +4414,8 @@
         if (popup && window() != popup)
             popup->close();
+#ifndef QT_NO_WHEELEVENT
         QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
         if (QApplication::sendSpontaneousEvent(widget, &e))
+#endif
             return true;
     }
@@ -4414,6 +4428,8 @@
         if (popup && widget != popup)
             popup->hide();
+#ifndef QT_NO_WHEELEVENT
         QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
         if (QApplication::sendSpontaneousEvent(widget, &e))
+#endif
             return true;
     }
@@ -5314,4 +5330,5 @@
 }
 
+#ifndef QT_NO_WHEELEVENT
 void QApplication::setWheelScrollLines(int n)
 {
@@ -5323,4 +5340,5 @@
     return QApplicationPrivate::wheel_scroll_lines;
 }
+#endif
 
 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
Index: trunk/src/gui/kernel/qclipboard_mac.cpp
===================================================================
--- trunk/src/gui/kernel/qclipboard_mac.cpp	(revision 766)
+++ trunk/src/gui/kernel/qclipboard_mac.cpp	(revision 769)
@@ -389,4 +389,16 @@
         QStringList formats = mime_src->formats();
 
+#ifdef QT_MAC_USE_COCOA
+        // QMimeData sub classes reimplementing the formats() might not expose the
+        // temporary "application/x-qt-mime-type-name" mimetype. So check the existence
+        // of this mime type while doing drag and drop.
+        QString dummyMimeType(QLatin1String("application/x-qt-mime-type-name"));
+        if (!formats.contains(dummyMimeType)) {
+            QByteArray dummyType = mime_src->data(dummyMimeType);
+            if (!dummyType.isEmpty()) {
+                formats.append(dummyMimeType);
+            }
+        }
+#endif
         for(int f = 0; f < formats.size(); ++f) {
             QString mimeType = formats.at(f);
Index: trunk/src/gui/kernel/qclipboard_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qclipboard_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qclipboard_s60.cpp	(revision 769)
@@ -165,5 +165,6 @@
         aStream >> mimeTypeSize;
         HBufC* mimeTypeBuf = HBufC::NewLC(aStream,mimeTypeSize);
-        QString mimeType = QString::fromUtf16(mimeTypeBuf->Des().Ptr(),mimeTypeBuf->Length());
+        QString mimeType = QString(reinterpret_cast<const QChar *>(mimeTypeBuf->Des().Ptr()),
+                                   mimeTypeBuf->Length());
         CleanupStack::PopAndDestroy(mimeTypeBuf);
         // mime data
Index: trunk/src/gui/kernel/qcocoamenuloader_mac.mm
===================================================================
--- trunk/src/gui/kernel/qcocoamenuloader_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qcocoamenuloader_mac.mm	(revision 769)
@@ -111,4 +111,10 @@
 }
 
+- (void)removeActionsFromAppMenu
+{
+    for (NSMenuItem *item in [appMenu itemArray])
+        [item setTag:nil];
+}
+
 - (void)dealloc
 {
Index: trunk/src/gui/kernel/qcocoamenuloader_mac_p.h
===================================================================
--- trunk/src/gui/kernel/qcocoamenuloader_mac_p.h	(revision 766)
+++ trunk/src/gui/kernel/qcocoamenuloader_mac_p.h	(revision 769)
@@ -71,4 +71,5 @@
 }
 - (void)ensureAppMenuInMenu:(NSMenu *)menu;
+- (void)removeActionsFromAppMenu;
 - (NSMenu *)applicationMenu;
 - (NSMenu *)menu;
Index: trunk/src/gui/kernel/qcocoapanel_mac.mm
===================================================================
--- trunk/src/gui/kernel/qcocoapanel_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qcocoapanel_mac.mm	(revision 769)
@@ -47,4 +47,7 @@
 #import <private/qcocoaview_mac_p.h>
 #import <private/qcocoawindowcustomthemeframe_mac_p.h>
+#include <private/qapplication_p.h>
+#include <private/qbackingstore_p.h>
+
 
 #include <QtGui/QWidget>
Index: trunk/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
===================================================================
--- trunk/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h	(revision 766)
+++ trunk/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h	(revision 769)
@@ -51,4 +51,7 @@
  NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel).
 ****************************************************************************/
+
+// WARNING: Don't include any header files from within this file. Put them
+// directly into qcocoawindow_mac_p.h and qcocoapanel_mac_p.h
 
 QT_BEGIN_NAMESPACE
@@ -186,2 +189,19 @@
 }
 
+- (void)displayIfNeeded
+{
+
+    QWidget *qwidget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+    if (qwidget == 0) {
+        [super displayIfNeeded];
+        return;
+    }
+
+    if (QApplicationPrivate::graphicsSystem() != 0) {
+        if (QWidgetBackingStore *bs = qt_widget_private(qwidget)->maybeBackingStore())
+            bs->sync(qwidget, qwidget->rect());
+    }
+    [super displayIfNeeded];
+}
+
+
Index: trunk/src/gui/kernel/qcocoaview_mac.mm
===================================================================
--- trunk/src/gui/kernel/qcocoaview_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qcocoaview_mac.mm	(revision 769)
@@ -521,8 +521,9 @@
 {
     if (QApplicationPrivate::graphicsSystem() != 0) {
-        if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore())
-            bs->markDirty(qwidget->rect(), qwidget);
-        qwidgetprivate->syncBackingStore(qwidget->rect());
-        return;
+        if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
+            // Drawing is handled on the window level
+            // See qcocoasharedwindowmethods_mac_p.
+            return;
+        }
     }
     CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
@@ -645,4 +646,6 @@
 - (void)mouseEntered:(NSEvent *)event
 {
+    if (qwidgetprivate->data.in_destructor)
+        return;
     QEvent enterEvent(QEvent::Enter);
     NSPoint windowPoint = [event locationInWindow];
@@ -826,4 +829,5 @@
     }
 
+#ifndef QT_NO_WHEELEVENT
     if (deltaX != 0) {
         QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);
@@ -866,4 +870,6 @@
         }
     }
+#endif //QT_NO_WHEELEVENT
+
     if (!wheelOK) {
         return [super scrollWheel:theEvent];
@@ -1402,5 +1408,5 @@
     // setup the data
     QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
-    dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray());
+    dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
     dragBoard.setMimeData(dragPrivate()->data);
 
Index: trunk/src/gui/kernel/qcocoawindow_mac_p.h
===================================================================
--- trunk/src/gui/kernel/qcocoawindow_mac_p.h	(revision 766)
+++ trunk/src/gui/kernel/qcocoawindow_mac_p.h	(revision 769)
@@ -54,4 +54,7 @@
 #include "qmacdefines_mac.h"
 #import <Cocoa/Cocoa.h>
+#include <private/qapplication_p.h>
+#include <private/qbackingstore_p.h>
+
 
 enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by
Index: trunk/src/gui/kernel/qcursor.cpp
===================================================================
--- trunk/src/gui/kernel/qcursor.cpp	(revision 766)
+++ trunk/src/gui/kernel/qcursor.cpp	(revision 769)
@@ -343,5 +343,6 @@
     \o B=0 and M=1 gives white.
     \o B=0 and M=0 gives transparent.
-    \o B=1 and M=0 gives an XOR'd result.
+    \o B=1 and M=0 gives an XOR'd result under Windows, undefined
+    results on all other platforms.
     \endlist
 
Index: trunk/src/gui/kernel/qdesktopwidget_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qdesktopwidget_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qdesktopwidget_s60.cpp	(revision 769)
@@ -89,10 +89,13 @@
 void QDesktopWidgetPrivate::init(QDesktopWidget *that)
 {
-    int screenCount=0;
+    Q_UNUSED(that);
+//    int screenCount=0;
 
-    if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
-        QDesktopWidgetPrivate::screenCount = screenCount;
-    else
-        QDesktopWidgetPrivate::screenCount = 0;
+    // ### TODO: Implement proper multi-display support
+	QDesktopWidgetPrivate::screenCount = 1;
+//    if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
+//        QDesktopWidgetPrivate::screenCount = screenCount;
+//    else
+//        QDesktopWidgetPrivate::screenCount = 0;
 
     rects = new QVector<QRect>();
@@ -101,10 +104,4 @@
     rects->resize(QDesktopWidgetPrivate::screenCount);
     workrects->resize(QDesktopWidgetPrivate::screenCount);
-
-    // ### TODO: Implement proper multi-display support
-    rects->resize(1);
-    rects->replace(0, that->rect());
-    workrects->resize(1);
-    workrects->replace(0, that->rect());
 }
 
Index: trunk/src/gui/kernel/qdnd_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qdnd_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qdnd_s60.cpp	(revision 769)
@@ -53,5 +53,5 @@
 #include "qt_s60_p.h"
 
-#include <COECNTRL.H>
+#include <coecntrl.h>
 // pointer cursor
 #include <w32std.h>
Index: trunk/src/gui/kernel/qdnd_x11.cpp
===================================================================
--- trunk/src/gui/kernel/qdnd_x11.cpp	(revision 766)
+++ trunk/src/gui/kernel/qdnd_x11.cpp	(revision 769)
@@ -618,5 +618,5 @@
             // to verify that it is utf16
             if (data.size() > 1 && data.at(1) == 0)
-                return QString::fromUtf16(reinterpret_cast<const ushort *>(data.constData()),
+                return QString::fromRawData((const QChar *)data.constData(),
                                 data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
         }
Index: trunk/src/gui/kernel/qeventdispatcher_mac.mm
===================================================================
--- trunk/src/gui/kernel/qeventdispatcher_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qeventdispatcher_mac.mm	(revision 769)
@@ -493,4 +493,12 @@
         case NSOtherMouseUp:     
         case NSOtherMouseDragged:
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+        case NSEventTypeGesture: // touch events
+        case NSEventTypeMagnify:
+        case NSEventTypeSwipe:
+        case NSEventTypeRotate:
+        case NSEventTypeBeginGesture:
+        case NSEventTypeEndGesture:
+#endif
             result    = true;
         break;
Index: trunk/src/gui/kernel/qgesturemanager.cpp
===================================================================
--- trunk/src/gui/kernel/qgesturemanager.cpp	(revision 766)
+++ trunk/src/gui/kernel/qgesturemanager.cpp	(revision 769)
@@ -46,4 +46,5 @@
 #include "private/qgraphicsitem_p.h"
 #include "private/qevent_p.h"
+#include "private/qapplication_p.h"
 #include "qgesture.h"
 #include "qevent.h"
@@ -87,5 +88,6 @@
 #if defined(Q_OS_WIN)
   #if !defined(QT_NO_NATIVE_GESTURES)
-    registerGestureRecognizer(new QWinNativePanGestureRecognizer);
+    if (QApplicationPrivate::HasTouchSupport)
+        registerGestureRecognizer(new QWinNativePanGestureRecognizer);
   #endif
 #else
Index: trunk/src/gui/kernel/qgridlayout.cpp
===================================================================
--- trunk/src/gui/kernel/qgridlayout.cpp	(revision 766)
+++ trunk/src/gui/kernel/qgridlayout.cpp	(revision 769)
@@ -1853,5 +1853,5 @@
     \fn int QGridLayout::colSpacing(int col) const
 
-    Use columnSpacing() instead.
+    Use columnMinimumWidth() instead.
 */
 
Index: trunk/src/gui/kernel/qguifunctions_wince.cpp
===================================================================
--- trunk/src/gui/kernel/qguifunctions_wince.cpp	(revision 766)
+++ trunk/src/gui/kernel/qguifunctions_wince.cpp	(revision 769)
@@ -279,5 +279,12 @@
 bool qt_wince_is_windows_mobile_65()
 {
-    return ((qt_wince_get_version() == 52) && (qt_wince_get_build() > 2000));
+    const DWORD dwFirstWM65BuildNumber = 21139;
+    OSVERSIONINFO osvi;
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+    if (!GetVersionEx(&osvi))
+        return false;
+    return osvi.dwMajorVersion > 5
+        || (osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion > 2 ||
+            (osvi.dwMinorVersion == 2 && osvi.dwBuildNumber >= dwFirstWM65BuildNumber)));
 }
 
Index: trunk/src/gui/kernel/qkeymapper_p.h
===================================================================
--- trunk/src/gui/kernel/qkeymapper_p.h	(revision 766)
+++ trunk/src/gui/kernel/qkeymapper_p.h	(revision 769)
@@ -217,10 +217,10 @@
 #elif defined(Q_WS_QWS)
 #elif defined(Q_OS_SYMBIAN)
-private:
-    QHash<TUint, int> s60ToQtKeyMap;
-    void fillKeyMap();
 public:
     QString translateKeyEvent(int keySym, Qt::KeyboardModifiers modifiers);
     int mapS60KeyToQt(TUint s60key);
+    int mapS60ScanCodesToQt(TUint s60key);
+    int mapQtToS60Key(int qtKey);
+    int mapQtToS60ScanCodes(int qtKey);
 #endif
 };
Index: trunk/src/gui/kernel/qkeymapper_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qkeymapper_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qkeymapper_s60.cpp	(revision 769)
@@ -47,5 +47,4 @@
 QKeyMapperPrivate::QKeyMapperPrivate()
 {
-    fillKeyMap();
 }
 
@@ -75,173 +74,144 @@
 }
 
-void QKeyMapperPrivate::fillKeyMap()
-{
-    using namespace Qt;
-    static const struct {
-        TUint s60Key;
-        int qtKey;
-    } map[] = {
-        {EKeyBell, Key_unknown},
-        {EKeyBackspace, Key_Backspace},
-        {EKeyTab, Key_Tab},
-        {EKeyLineFeed, Key_unknown},
-        {EKeyVerticalTab, Key_unknown},
-        {EKeyFormFeed, Key_unknown},
-        {EKeyEnter, Key_Enter},
-        {EKeyEscape, Key_Escape},
-        {EKeySpace, Key_Space},
-        {EKeyDelete, Key_Delete},
-        {EKeyPrintScreen, Key_SysReq},
-        {EKeyPause, Key_Pause},
-        {EKeyHome, Key_Home},
-        {EKeyEnd, Key_End},
-        {EKeyPageUp, Key_PageUp},
-        {EKeyPageDown, Key_PageDown},
-        {EKeyInsert, Key_Insert},
-        {EKeyLeftArrow, Key_Left},
-        {EKeyRightArrow, Key_Right},
-        {EKeyUpArrow, Key_Up},
-        {EKeyDownArrow, Key_Down},
-        {EKeyLeftShift, Key_Shift},
-        {EKeyRightShift, Key_Shift},
-        {EKeyLeftAlt, Key_Alt},
-        {EKeyRightAlt, Key_AltGr},
-        {EKeyLeftCtrl, Key_Control},
-        {EKeyRightCtrl, Key_Control},
-        {EKeyLeftFunc, Key_Super_L},
-        {EKeyRightFunc, Key_Super_R},
-        {EKeyCapsLock, Key_CapsLock},
-        {EKeyNumLock, Key_NumLock},
-        {EKeyScrollLock, Key_ScrollLock},
-        {EKeyF1, Key_F1},
-        {EKeyF2, Key_F2},
-        {EKeyF3, Key_F3},
-        {EKeyF4, Key_F4},
-        {EKeyF5, Key_F5},
-        {EKeyF6, Key_F6},
-        {EKeyF7, Key_F7},
-        {EKeyF8, Key_F8},
-        {EKeyF9, Key_F9},
-        {EKeyF10, Key_F10},
-        {EKeyF11, Key_F11},
-        {EKeyF12, Key_F12},
-        {EKeyF13, Key_F13},
-        {EKeyF14, Key_F14},
-        {EKeyF15, Key_F15},
-        {EKeyF16, Key_F16},
-        {EKeyF17, Key_F17},
-        {EKeyF18, Key_F18},
-        {EKeyF19, Key_F19},
-        {EKeyF20, Key_F20},
-        {EKeyF21, Key_F21},
-        {EKeyF22, Key_F22},
-        {EKeyF23, Key_F23},
-        {EKeyF24, Key_F24},
-        {EKeyOff, Key_unknown},
-        {EKeyIncContrast, Key_unknown},
-        {EKeyDecContrast, Key_unknown},
-        {EKeyBacklightOn, Key_unknown},
-        {EKeyBacklightOff, Key_unknown},
-        {EKeyBacklightToggle, Key_unknown},
-        {EKeySliderDown, Key_unknown},
-        {EKeySliderUp, Key_unknown},
-        {EKeyMenu, Key_Menu},
-        {EKeyDictaphonePlay, Key_unknown},
-        {EKeyDictaphoneStop, Key_unknown},
-        {EKeyDictaphoneRecord, Key_unknown},
-        {EKeyHelp, Key_unknown},
-        {EKeyDial, Key_Call},
-        {EKeyScreenDimension0, Key_unknown},
-        {EKeyScreenDimension1, Key_unknown},
-        {EKeyScreenDimension2, Key_unknown},
-        {EKeyScreenDimension3, Key_unknown},
-        {EKeyIncVolume, Key_unknown},
-        {EKeyDecVolume, Key_unknown},
-        {EKeyDevice0, Key_Context1}, // Found by manual testing, left softkey.
-        {EKeyDevice1, Key_Context2}, // Found by manual testing.
-        {EKeyDevice2, Key_unknown},
-        {EKeyDevice3, Key_Select}, // Found by manual testing.
-        {EKeyDevice4, Key_unknown},
-        {EKeyDevice5, Key_unknown},
-        {EKeyDevice6, Key_unknown},
-        {EKeyDevice7, Key_unknown},
-        {EKeyDevice8, Key_unknown},
-        {EKeyDevice9, Key_unknown},
-        {EKeyDeviceA, Key_unknown},
-        {EKeyDeviceB, Key_unknown},
-        {EKeyDeviceC, Key_unknown},
-        {EKeyDeviceD, Key_unknown},
-        {EKeyDeviceE, Key_unknown},
-        {EKeyDeviceF, Key_unknown},
-        {EKeyApplication0, Key_Launch0},
-        {EKeyApplication1, Key_Launch1},
-        {EKeyApplication2, Key_Launch2},
-        {EKeyApplication3, Key_Launch3},
-        {EKeyApplication4, Key_Launch4},
-        {EKeyApplication5, Key_Launch5},
-        {EKeyApplication6, Key_Launch6},
-        {EKeyApplication7, Key_Launch7},
-        {EKeyApplication8, Key_Launch8},
-        {EKeyApplication9, Key_Launch9},
-        {EKeyApplicationA, Key_LaunchA},
-        {EKeyApplicationB, Key_LaunchB},
-        {EKeyApplicationC, Key_LaunchC},
-        {EKeyApplicationD, Key_LaunchD},
-        {EKeyApplicationE, Key_LaunchE},
-        {EKeyApplicationF, Key_LaunchF},
-        {EKeyYes, Key_Yes},
-        {EKeyNo, Key_No},
-        {EKeyIncBrightness, Key_unknown},
-        {EKeyDecBrightness, Key_unknown},
-        {EKeyKeyboardExtend, Key_unknown},
-        {EKeyDevice10, Key_unknown},
-        {EKeyDevice11, Key_unknown},
-        {EKeyDevice12, Key_unknown},
-        {EKeyDevice13, Key_unknown},
-        {EKeyDevice14, Key_unknown},
-        {EKeyDevice15, Key_unknown},
-        {EKeyDevice16, Key_unknown},
-        {EKeyDevice17, Key_unknown},
-        {EKeyDevice18, Key_unknown},
-        {EKeyDevice19, Key_unknown},
-        {EKeyDevice1A, Key_unknown},
-        {EKeyDevice1B, Key_unknown},
-        {EKeyDevice1C, Key_unknown},
-        {EKeyDevice1D, Key_unknown},
-        {EKeyDevice1E, Key_unknown},
-        {EKeyDevice1F, Key_unknown},
-        {EKeyApplication10, Key_unknown},
-        {EKeyApplication11, Key_unknown},
-        {EKeyApplication12, Key_unknown},
-        {EKeyApplication13, Key_unknown},
-        {EKeyApplication14, Key_unknown},
-        {EKeyApplication15, Key_unknown},
-        {EKeyApplication16, Key_unknown},
-        {EKeyApplication17, Key_unknown},
-        {EKeyApplication18, Key_unknown},
-        {EKeyApplication19, Key_unknown},
-        {EKeyApplication1A, Key_unknown},
-        {EKeyApplication1B, Key_unknown},
-        {EKeyApplication1C, Key_unknown},
-        {EKeyApplication1D, Key_unknown},
-        {EKeyApplication1E, Key_unknown},
-        {EKeyApplication1F, Key_unknown}
-    };
-    const int mapSize = int(sizeof(map)/sizeof(map[0]));
-    s60ToQtKeyMap.reserve(mapSize + 5); // +5? docs: Ideally, slightly more than number of items
-    for (int i = 0; i < mapSize; ++i)
-        s60ToQtKeyMap.insert(map[i].s60Key, map[i].qtKey);
-}
+#include <e32keys.h>
+struct KeyMapping{
+    TKeyCode s60KeyCode;
+    TStdScanCode s60ScanCode;
+    Qt::Key qtKey;
+};
+
+using namespace Qt;
+
+static const KeyMapping keyMapping[] = {
+    {EKeyBackspace, EStdKeyBackspace, Key_Backspace},
+    {EKeyTab, EStdKeyTab, Key_Tab},
+    {EKeyEnter, EStdKeyEnter, Key_Enter},
+    {EKeyEscape, EStdKeyEscape, Key_Escape},
+    {EKeySpace, EStdKeySpace, Key_Space},
+    {EKeyDelete, EStdKeyDelete, Key_Delete},
+    {EKeyPrintScreen, EStdKeyPrintScreen, Key_SysReq},
+    {EKeyPause, EStdKeyPause, Key_Pause},
+    {EKeyHome, EStdKeyHome, Key_Home},
+    {EKeyEnd, EStdKeyEnd, Key_End},
+    {EKeyPageUp, EStdKeyPageUp, Key_PageUp},
+    {EKeyPageDown, EStdKeyPageDown, Key_PageDown},
+    {EKeyInsert, EStdKeyInsert, Key_Insert},
+    {EKeyLeftArrow, EStdKeyLeftArrow, Key_Left},
+    {EKeyRightArrow, EStdKeyRightArrow, Key_Right},
+    {EKeyUpArrow, EStdKeyUpArrow, Key_Up},
+    {EKeyDownArrow, EStdKeyDownArrow, Key_Down},
+    {EKeyLeftShift, EStdKeyLeftShift, Key_Shift},
+    {EKeyRightShift, EStdKeyRightShift, Key_Shift},
+    {EKeyLeftAlt, EStdKeyLeftAlt, Key_Alt},
+    {EKeyRightAlt, EStdKeyRightAlt, Key_AltGr},
+    {EKeyLeftCtrl, EStdKeyLeftCtrl, Key_Control},
+    {EKeyRightCtrl, EStdKeyRightCtrl, Key_Control},
+    {EKeyLeftFunc, EStdKeyLeftFunc, Key_Super_L},
+    {EKeyRightFunc, EStdKeyRightFunc, Key_Super_R},
+    {EKeyCapsLock, EStdKeyCapsLock, Key_CapsLock},
+    {EKeyNumLock, EStdKeyNumLock, Key_NumLock},
+    {EKeyScrollLock, EStdKeyScrollLock, Key_ScrollLock},
+    {EKeyF1, EStdKeyF1, Key_F1},
+    {EKeyF2, EStdKeyF2, Key_F2},
+    {EKeyF3, EStdKeyF3, Key_F3},
+    {EKeyF4, EStdKeyF4, Key_F4},
+    {EKeyF5, EStdKeyF5, Key_F5},
+    {EKeyF6, EStdKeyF6, Key_F6},
+    {EKeyF7, EStdKeyF7, Key_F7},
+    {EKeyF8, EStdKeyF8, Key_F8},
+    {EKeyF9, EStdKeyF9, Key_F9},
+    {EKeyF10, EStdKeyF10, Key_F10},
+    {EKeyF11, EStdKeyF11, Key_F11},
+    {EKeyF12, EStdKeyF12, Key_F12},
+    {EKeyF13, EStdKeyF13, Key_F13},
+    {EKeyF14, EStdKeyF14, Key_F14},
+    {EKeyF15, EStdKeyF15, Key_F15},
+    {EKeyF16, EStdKeyF16, Key_F16},
+    {EKeyF17, EStdKeyF17, Key_F17},
+    {EKeyF18, EStdKeyF18, Key_F18},
+    {EKeyF19, EStdKeyF19, Key_F19},
+    {EKeyF20, EStdKeyF20, Key_F20},
+    {EKeyF21, EStdKeyF21, Key_F21},
+    {EKeyF22, EStdKeyF22, Key_F22},
+    {EKeyF23, EStdKeyF23, Key_F23},
+    {EKeyF24, EStdKeyF24, Key_F24},
+    {EKeyOff, EStdKeyOff, Key_PowerOff},
+//    {EKeyMenu, EStdKeyMenu, Key_Menu}, // Menu is EKeyApplication0
+    {EKeyHelp, EStdKeyHelp, Key_Help},
+    {EKeyDial, EStdKeyDial, Key_Call},
+    {EKeyIncVolume, EStdKeyIncVolume, Key_VolumeUp},
+    {EKeyDecVolume, EStdKeyDecVolume, Key_VolumeDown},
+    {EKeyDevice0, EStdKeyDevice0, Key_Context1}, // Found by manual testing.
+    {EKeyDevice1, EStdKeyDevice1, Key_Context2}, // Found by manual testing.
+    {EKeyDevice3, EStdKeyDevice3, Key_Select},
+//    {EKeyDevice7, EStdKeyDevice7, Key_Camera},  //not supported by qt yet
+    {EKeyApplication0, EStdKeyApplication0, Key_Menu}, // Found by manual testing.
+    {EKeyApplication1, EStdKeyApplication1, Key_Launch1}, // Found by manual testing.
+    {EKeyApplication2, EStdKeyApplication2, Key_MediaPlay}, // Found by manual testing.
+    {EKeyApplication3, EStdKeyApplication3, Key_MediaStop}, // Found by manual testing.
+    {EKeyApplication4, EStdKeyApplication4, Key_MediaNext}, // Found by manual testing.
+    {EKeyApplication5, EStdKeyApplication5, Key_MediaPrevious}, // Found by manual testing.
+    {EKeyApplication6, EStdKeyApplication6, Key_Launch6},
+    {EKeyApplication7, EStdKeyApplication7, Key_Launch7},
+    {EKeyApplication8, EStdKeyApplication8, Key_Launch8},
+    {EKeyApplication9, EStdKeyApplication9, Key_Launch9},
+    {EKeyApplicationA, EStdKeyApplicationA, Key_LaunchA},
+    {EKeyApplicationB, EStdKeyApplicationB, Key_LaunchB},
+    {EKeyApplicationC, EStdKeyApplicationC, Key_LaunchC},
+    {EKeyApplicationD, EStdKeyApplicationD, Key_LaunchD},
+    {EKeyApplicationE, EStdKeyApplicationE, Key_LaunchE},
+    {EKeyApplicationF, EStdKeyApplicationF, Key_LaunchF},
+//    {EKeyApplication19, EStdKeyApplication19, Key_CameraFocus},  //not supported by qt yet
+    {EKeyYes, EStdKeyYes, Key_Yes},
+    {EKeyNo, EStdKeyNo, Key_No},
+    {TKeyCode(0), TStdScanCode(0), Qt::Key(0)}
+};
 
 int QKeyMapperPrivate::mapS60KeyToQt(TUint s60key)
 {
-    QHash<TUint, int>::const_iterator mapping;
-    mapping = s60ToQtKeyMap.find(s60key);
-    if (mapping != s60ToQtKeyMap.end()) {
-        return *mapping;
-    } else {
-        return Qt::Key_unknown;
-    }
-}
-
+    int res = Qt::Key_unknown;
+    for (int i = 0; keyMapping[i].s60KeyCode != 0; i++) {
+        if (keyMapping[i].s60KeyCode == s60key) {
+            res = keyMapping[i].qtKey;
+            break;
+        }
+    }
+    return res;
+}
+
+int QKeyMapperPrivate::mapS60ScanCodesToQt(TUint s60scanCode)
+{
+    int res = Qt::Key_unknown;
+    for (int i = 0; keyMapping[i].s60KeyCode != 0; i++) {
+        if (keyMapping[i].s60ScanCode == s60scanCode) {
+            res = keyMapping[i].qtKey;
+            break;
+        }
+    }
+    return res;
+}
+
+int QKeyMapperPrivate::mapQtToS60Key(int qtKey)
+{
+    int res = KErrUnknown;
+    for (int i = 0; keyMapping[i].s60KeyCode != 0; i++) {
+        if (keyMapping[i].qtKey == qtKey) {
+            res = keyMapping[i].s60KeyCode;
+            break;
+        }
+    }
+    return res;
+}
+
+int QKeyMapperPrivate::mapQtToS60ScanCodes(int qtKey)
+{
+    int res = KErrUnknown;
+    for (int i = 0; keyMapping[i].s60KeyCode != 0; i++) {
+        if (keyMapping[i].qtKey == qtKey) {
+            res = keyMapping[i].s60ScanCode;
+            break;
+        }
+    }
+    return res;
+}
 QT_END_NAMESPACE
Index: trunk/src/gui/kernel/qkeymapper_x11.cpp
===================================================================
--- trunk/src/gui/kernel/qkeymapper_x11.cpp	(revision 766)
+++ trunk/src/gui/kernel/qkeymapper_x11.cpp	(revision 769)
@@ -361,4 +361,11 @@
         if (code && code < 0xfffe)
             code = QChar(code).toUpper().unicode();
+
+        if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
+            // map shift+tab to shift+backtab
+            code = Qt::Key_Backtab;
+            text = QString();
+        }
+
         if (code == baseCode)
             continue;
@@ -449,4 +456,11 @@
         if (code && code < 0xfffe)
             code = QChar(code).toUpper().unicode();
+
+        if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
+            // map shift+tab to shift+backtab
+            code = Qt::Key_Backtab;
+            text = QString();
+        }
+
         if (code == baseCode)
             continue;
@@ -1060,6 +1074,6 @@
     XF86XK_AudioRecord,         Qt::Key_MediaRecord,
     XF86XK_Mail,                Qt::Key_LaunchMail,
-    XF86XK_MyComputer,          Qt::Key_Launch0,
-    XF86XK_Calculator,          Qt::Key_Calculator,
+    XF86XK_MyComputer,          Qt::Key_Launch0,  // ### Qt 5: remap properly
+    XF86XK_Calculator,          Qt::Key_Launch1,
     XF86XK_Memo,                Qt::Key_Memo,
     XF86XK_ToDoList,            Qt::Key_ToDoList,
@@ -1159,5 +1173,5 @@
     XF86XK_Suspend,             Qt::Key_Suspend,
     XF86XK_Hibernate,           Qt::Key_Hibernate,
-    XF86XK_Launch0,             Qt::Key_Launch2,
+    XF86XK_Launch0,             Qt::Key_Launch2, // ### Qt 5: remap properly
     XF86XK_Launch1,             Qt::Key_Launch3,
     XF86XK_Launch2,             Qt::Key_Launch4,
Index: trunk/src/gui/kernel/qmime_mac.cpp
===================================================================
--- trunk/src/gui/kernel/qmime_mac.cpp	(revision 766)
+++ trunk/src/gui/kernel/qmime_mac.cpp	(revision 769)
@@ -432,6 +432,6 @@
         ret = QString(str);
     } else if (flavor == QLatin1String("public.utf16-plain-text")) {
-        ret = QString::fromUtf16(reinterpret_cast<const ushort *>(firstData.constData()),
-                                 firstData.size() / sizeof(ushort));
+        ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
+                      firstData.size() / sizeof(QChar));
     } else {
         qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
Index: trunk/src/gui/kernel/qmime_win.cpp
===================================================================
--- trunk/src/gui/kernel/qmime_win.cpp	(revision 766)
+++ trunk/src/gui/kernel/qmime_win.cpp	(revision 769)
@@ -641,6 +641,8 @@
             QList<QUrl> urls = mimeData->urls();
             QByteArray result;
-            QString url = urls.at(0).toString();
-            result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort));
+            if (!urls.isEmpty()) {
+                QString url = urls.at(0).toString();
+                result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort));
+            }
             result.append('\0');
             result.append('\0');
@@ -648,5 +650,7 @@
         } else if (getCf(formatetc) == CF_INETURL) {
             QList<QUrl> urls = mimeData->urls();
-            QByteArray result = urls.at(0).toString().toLocal8Bit();
+            QByteArray result;
+            if (!urls.isEmpty())
+                result = urls.at(0).toString().toLocal8Bit();
             return setData(result, pmedium);
         }
Index: trunk/src/gui/kernel/qsoftkeymanager.cpp
===================================================================
--- trunk/src/gui/kernel/qsoftkeymanager.cpp	(revision 766)
+++ trunk/src/gui/kernel/qsoftkeymanager.cpp	(revision 769)
@@ -56,22 +56,22 @@
 QSoftKeyManager *QSoftKeyManagerPrivate::self = 0;
 
-const char *QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey)
-{
-    const char *softKeyText = 0;
+QString QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey)
+{
+    QString softKeyText;
     switch (standardKey) {
     case OkSoftKey:
-        softKeyText = QT_TRANSLATE_NOOP("QSoftKeyManager", "Ok");
+        softKeyText = QSoftKeyManager::tr("Ok");
         break;
     case SelectSoftKey:
-        softKeyText = QT_TRANSLATE_NOOP("QSoftKeyManager", "Select");
+        softKeyText = QSoftKeyManager::tr("Select");
         break;
     case DoneSoftKey:
-        softKeyText = QT_TRANSLATE_NOOP("QSoftKeyManager", "Done");
+        softKeyText = QSoftKeyManager::tr("Done");
         break;
     case MenuSoftKey:
-        softKeyText = QT_TRANSLATE_NOOP("QSoftKeyManager", "Options");
+        softKeyText = QSoftKeyManager::tr("Options");
         break;
     case CancelSoftKey:
-        softKeyText = QT_TRANSLATE_NOOP("QSoftKeyManager", "Cancel");
+        softKeyText = QSoftKeyManager::tr("Cancel");
         break;
     default:
@@ -101,6 +101,5 @@
 QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *actionWidget)
 {
-    const char* text = standardSoftKeyText(standardKey);
-    QAction *action = new QAction(QSoftKeyManager::tr(text), actionWidget);
+    QAction *action = new QAction(standardSoftKeyText(standardKey), actionWidget);
     QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey;
     switch (standardKey) {
@@ -117,4 +116,6 @@
     }
     action->setSoftKeyRole(softKeyRole);
+    action->setVisible(false);
+    setForceEnabledInSoftkeys(action);
     return action;
 }
@@ -170,12 +171,23 @@
     Q_D(QSoftKeyManager);
     bool ret = false;
-    QList<QAction*> actions = source.actions();
-    for (int i = 0; i < actions.count(); ++i) {
-        if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) {
-            d->requestedSoftKeyActions.insert(level, actions.at(i));
+    foreach(QAction *action, source.actions()) {
+        if (action->softKeyRole() != QAction::NoSoftKey
+            && (action->isVisible() || isForceEnabledInSofkeys(action))) {
+            d->requestedSoftKeyActions.insert(level, action);
             ret = true;
         }
     }
     return ret;
+}
+
+
+static bool isChildOf(const QWidget *c, const QWidget *p)
+{
+    while (c) {
+        if (c == p)
+            return true;
+        c = c->parentWidget();
+    }
+    return false;
 }
 
@@ -186,7 +198,26 @@
     if (!previousSource) {
         // Initial source is primarily focuswidget and secondarily activeWindow
-        source = QApplication::focusWidget();
-        if (!source)
-            source = QApplication::activeWindow();
+        QWidget *focus = QApplication::focusWidget();
+        QWidget *popup = QApplication::activePopupWidget();
+        if (popup) {
+            if (isChildOf(focus, popup))
+                source = focus;
+            else
+                source = popup;
+        }
+        if (!source) {
+            QWidget *modal = QApplication::activeModalWidget();
+            if (modal) {
+                if (isChildOf(focus, modal))
+                    source = focus;
+                else
+                    source = modal;
+            }
+        }
+        if (!source) {
+            source = focus;
+            if (!source)
+                source = QApplication::activeWindow();
+        }
     } else {
         // Softkey merging is based on four criterias
@@ -212,14 +243,27 @@
     bool recursiveMerging = false;
     QWidget *source = softkeySource(NULL, recursiveMerging);
-    do {
-        if (source) {
-            bool added = appendSoftkeys(*source, level);
-            source = softkeySource(source, recursiveMerging);
-            level = added ? ++level : level;
-        }
-    } while (source);
+    d->initialSoftKeySource = source;
+    while (source) {
+        if (appendSoftkeys(*source, level))
+            ++level;
+        source = softkeySource(source, recursiveMerging);
+    }
 
     d->updateSoftKeys_sys();
     return true;
+}
+
+void QSoftKeyManager::setForceEnabledInSoftkeys(QAction *action)
+{
+    action->setProperty(FORCE_ENABLED_PROPERTY, QVariant(true));
+}
+
+bool QSoftKeyManager::isForceEnabledInSofkeys(QAction *action)
+{
+    bool ret = false;
+    QVariant property = action->property(FORCE_ENABLED_PROPERTY);
+    if (property.isValid() && property.toBool())
+        ret = true;
+    return ret;
 }
 
Index: trunk/src/gui/kernel/qsoftkeymanager_common_p.h
===================================================================
--- trunk/src/gui/kernel/qsoftkeymanager_common_p.h	(revision 766)
+++ trunk/src/gui/kernel/qsoftkeymanager_common_p.h	(revision 769)
@@ -71,4 +71,5 @@
     QHash<QAction*, Qt::Key> keyedActions;
     QMultiHash<int, QAction*> requestedSoftKeyActions;
+    QWidget *initialSoftKeySource;
 
 };
Index: trunk/src/gui/kernel/qsoftkeymanager_p.h
===================================================================
--- trunk/src/gui/kernel/qsoftkeymanager_p.h	(revision 766)
+++ trunk/src/gui/kernel/qsoftkeymanager_p.h	(revision 769)
@@ -64,5 +64,6 @@
 class QSoftKeyManagerPrivate;
 
-const char MENU_ACTION_PROPERTY[] = "_q_menuaction";
+const char MENU_ACTION_PROPERTY[] = "_q_menuAction";
+const char FORCE_ENABLED_PROPERTY[] = "_q_forceEnabledInSoftkeys";
 
 class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject
@@ -88,4 +89,7 @@
     static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget);
     static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget);
+    static QString standardSoftKeyText(StandardSoftKey standardKey);
+    static void setForceEnabledInSoftkeys(QAction *action);
+    static bool isForceEnabledInSofkeys(QAction *action);
 
 protected:
@@ -95,5 +99,4 @@
     QSoftKeyManager();
     static QSoftKeyManager *instance();
-    static const char *standardSoftKeyText(StandardSoftKey standardKey);
     bool appendSoftkeys(const QWidget &source, int level);
     QWidget *softkeySource(QWidget *previousSource, bool& recursiveMerging);
Index: trunk/src/gui/kernel/qsoftkeymanager_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qsoftkeymanager_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qsoftkeymanager_s60.cpp	(revision 769)
@@ -61,5 +61,5 @@
 const int RSK_POSITION = 2;
 
-QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60()
+QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60() : cbaHasImage(4) // 4 since MSK position index is 3
 {
     cachedCbaIconSize[0] = QSize(0,0);
@@ -67,15 +67,28 @@
     cachedCbaIconSize[2] = QSize(0,0);
     cachedCbaIconSize[3] = QSize(0,0);
-    skipNextUpdate = false;
 }
 
 bool QSoftKeyManagerPrivateS60::skipCbaUpdate()
 {
-    // lets not update softkeys if
+    // Lets not update softkeys if
     // 1. We don't have application panes, i.e. cba
-    // 2. S60 native dialog or menu is shown
-    if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) ||
-        CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || skipNextUpdate) {
-        skipNextUpdate = false;
+    // 2. Our CBA is not active, i.e. S60 native dialog or menu with custom CBA is shown
+    //    2.1. Except if thre is no current CBA at all and WindowSoftkeysRespondHint is set
+
+    // Note: Cannot use IsDisplayingMenuOrDialog since CBA update can be triggered before
+    // menu/dialog CBA is actually displayed i.e. it is being costructed.
+    CEikButtonGroupContainer *appUiCba = S60->buttonGroupContainer();
+    if (!appUiCba)
+        return true;
+    // CEikButtonGroupContainer::Current returns 0 if CBA is not visible at all
+    CEikButtonGroupContainer *currentCba = CEikButtonGroupContainer::Current();
+    // Check if softkey need to be update even they are not visible
+    bool cbaRespondsWhenInvisible = false;
+    QWidget *window = QApplication::activeWindow();
+    if (window && (window->windowFlags() & Qt::WindowSoftkeysRespondHint))
+        cbaRespondsWhenInvisible = true;
+
+    if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
+            || (appUiCba != currentCba && !cbaRespondsWhenInvisible)) {
         return true;
     }
@@ -255,8 +268,12 @@
 
             EikSoftkeyImage::SetImage(cba, *myimage, left); // Takes myimage ownership
+            cbaHasImage[position] = true;
             ret = true;
         } else {
             // Restore softkey to text based
-            EikSoftkeyImage::SetLabel(cba, left);
+            if (cbaHasImage[position]) {
+                EikSoftkeyImage::SetLabel(cba, left);
+                cbaHasImage[position] = false;
+            }
         }
     }
@@ -274,5 +291,6 @@
         int command = S60_COMMAND_START + position;
         setNativeSoftkey(cba, position, command, nativeText);
-        cba.DimCommand(command, !action->isEnabled());
+        const bool dimmed = !action->isEnabled() && !QSoftKeyManager::isForceEnabledInSofkeys(action);
+        cba.DimCommand(command, dimmed);
         realSoftKeyActions.insert(command, action);
         return true;
@@ -297,20 +315,15 @@
 {
     if (!setSoftkey(cba, QAction::NegativeSoftKey, RSK_POSITION)) {
-        Qt::WindowType windowType = Qt::Window;
-        QAction *action = requestedSoftKeyActions.value(0);
-        if (action) {
-            QWidget *actionParent = action->parentWidget();
-            Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
-
-            QWidget *actionWindow = actionParent->window();
-            Q_ASSERT_X(actionWindow, Q_FUNC_INFO, "Softkey action does not have window!");
-            windowType = actionWindow->windowType();
-        }
-
+        const Qt::WindowType windowType = initialSoftKeySource
+            ? initialSoftKeySource->window()->windowType() : Qt::Window;
         if (windowType != Qt::Dialog && windowType != Qt::Popup) {
             QString text(QSoftKeyManager::tr("Exit"));
             TPtrC nativeText = qt_QString2TPtrC(text);
-            EikSoftkeyImage::SetLabel(&cba, false);
+            if (cbaHasImage[RSK_POSITION]) {
+                EikSoftkeyImage::SetLabel(&cba, false);
+                cbaHasImage[RSK_POSITION] = false;
+            }
             setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText);
+            cba.DimCommand(EAknSoftkeyExit, false);
             return true;
         }
@@ -355,4 +368,17 @@
 }
 
+static void resetMenuBeingConstructed(TAny* /*aAny*/)
+{
+    S60->menuBeingConstructed = false;
+}
+
+void QSoftKeyManagerPrivateS60::tryDisplayMenuBarL()
+{
+    CleanupStack::PushL(TCleanupItem(resetMenuBeingConstructed, NULL));
+    S60->menuBeingConstructed = true;
+    S60->menuBar()->TryDisplayMenuBarL();
+    CleanupStack::PopAndDestroy(); // Reset menuBeingConstructed to false in all cases
+}
+
 bool QSoftKeyManagerPrivateS60::handleCommand(int command)
 {
@@ -361,9 +387,9 @@
         QVariant property = action->property(MENU_ACTION_PROPERTY);
         if (property.isValid() && property.toBool()) {
-            QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL());
+            QT_TRAP_THROWING(tryDisplayMenuBarL());
         } else if (action->menu()) {
             // TODO: This is hack, in order to use exising QMenuBar implementation for Symbian
             // menubar needs to have widget to which it is associated. Since we want to associate
-            // menubar to action (which is inherited from QObejct), we create and associate QWidget
+            // menubar to action (which is inherited from QObject), we create and associate QWidget
             // to action and pass that for QMenuBar. This associates the menubar to action, and we
             // can have own menubar for each action.
@@ -384,16 +410,13 @@
             }
             qt_symbian_next_menu_from_action(actionContainer);
-            QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL());
-            // TODO: hack remove, it can happen that IsDisplayingMenuOrDialog return false
-            // in updateSoftKeys_sys, and we will override menu CBA with our own
-            skipNextUpdate = true;
-        } else {
-            Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey);
-            QWidget *actionParent = action->parentWidget();
-            Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
-            if (actionParent->isEnabled()) {
-                action->activate(QAction::Trigger);
-                return true;
-            }
+            QT_TRAP_THROWING(tryDisplayMenuBarL());
+        }
+
+        Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey);
+        QWidget *actionParent = action->parentWidget();
+        Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
+        if (actionParent->isEnabled()) {
+            action->activate(QAction::Trigger);
+            return true;
         }
     }
Index: trunk/src/gui/kernel/qsoftkeymanager_s60_p.h
===================================================================
--- trunk/src/gui/kernel/qsoftkeymanager_s60_p.h	(revision 766)
+++ trunk/src/gui/kernel/qsoftkeymanager_s60_p.h	(revision 769)
@@ -54,4 +54,5 @@
 //
 
+#include "qbitarray.h"
 #include "private/qobject_p.h"
 #include "private/qsoftkeymanager_common_p.h"
@@ -78,4 +79,5 @@
 
 private:
+    void tryDisplayMenuBarL();
     bool skipCbaUpdate();
     void ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba);
@@ -99,5 +101,5 @@
     QHash<int, QAction*> realSoftKeyActions;
     QSize cachedCbaIconSize[4];
-    bool skipNextUpdate;
+    QBitArray cbaHasImage;
 };
 
Index: trunk/src/gui/kernel/qsound.cpp
===================================================================
--- trunk/src/gui/kernel/qsound.cpp	(revision 766)
+++ trunk/src/gui/kernel/qsound.cpp	(revision 769)
@@ -155,4 +155,5 @@
     \o A built-in mixing sound server is used, accessing \c /dev/dsp
     directly. Only the WAVE format is supported.
+    \row
     \o Symbian
     \o CMdaAudioPlayerUtility is used. All formats that Symbian OS or devices support
Index: trunk/src/gui/kernel/qsound_mac.mm
===================================================================
--- trunk/src/gui/kernel/qsound_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qsound_mac.mm	(revision 769)
@@ -175,4 +175,5 @@
     QMacSoundDelegate * const delegate = [[QMacSoundDelegate alloc] initWithQSound:qSound:this];
     [nsSound setDelegate:delegate];
+    [nsFileName release];
     return nsSound;
 }
Index: trunk/src/gui/kernel/qsound_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qsound_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qsound_s60.cpp	(revision 769)
@@ -52,5 +52,5 @@
 
 #include <e32std.h>
-#include <MdaAudioSamplePlayer.h>
+#include <mdaaudiosampleplayer.h>
 
 QT_BEGIN_NAMESPACE
Index: trunk/src/gui/kernel/qt_cocoa_helpers_mac.mm
===================================================================
--- trunk/src/gui/kernel/qt_cocoa_helpers_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qt_cocoa_helpers_mac.mm	(revision 769)
@@ -144,4 +144,7 @@
 void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
 {
+#ifdef QT_MAC_USE_COCOA
+    QMacCocoaAutoReleasePool pool;
+#endif
     OSWindowRef wnd = static_cast<OSWindowRef>(window);
     if (wnd) {
@@ -1160,7 +1163,18 @@
     QDBeginCGContext(port, &context);
 #else
-    CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
+    CGContextRef context = reinterpret_cast<CGContextRef>([[qt_mac_window_for(widget) graphicsContext] graphicsPort]);
 #endif
     return context;
+}
+
+void qt_mac_dispatchPendingUpdateRequests(QWidget *widget)
+{
+    if (!widget)
+        return;
+#ifndef QT_MAC_USE_COCOA
+    HIViewRender(qt_mac_nativeview_for(widget));
+#else
+    [qt_mac_nativeview_for(widget) displayIfNeeded];
+#endif
 }
 
@@ -1279,3 +1293,16 @@
 #endif
 
+QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool()
+{
+#ifndef QT_MAC_USE_COCOA
+    NSApplicationLoad();
+#endif
+    pool = (void*)[[NSAutoreleasePool alloc] init];
+}
+
+QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool()
+{
+    [(NSAutoreleasePool*)pool release];
+}
+
 QT_END_NAMESPACE
Index: trunk/src/gui/kernel/qt_s60_p.h
===================================================================
--- trunk/src/gui/kernel/qt_s60_p.h	(revision 766)
+++ trunk/src/gui/kernel/qt_s60_p.h	(revision 769)
@@ -69,10 +69,10 @@
 
 #ifdef Q_WS_S60
-#include <aknutils.h>               // AknLayoutUtils
+#include <AknUtils.h>               // AknLayoutUtils
 #include <avkon.hrh>                // EEikStatusPaneUidTitle
 #include <akntitle.h>               // CAknTitlePane
 #include <akncontext.h>             // CAknContextPane
 #include <eikspane.h>               // CEikStatusPane
-#include <aknpopupfader.h>          // MAknFadedComponent and TAknPopupFader
+#include <AknPopupFader.h>          // MAknFadedComponent and TAknPopupFader
 #endif
 
@@ -123,4 +123,5 @@
     int supportsPremultipliedAlpha : 1;
     int avkonComponentsSupportTransparency : 1;
+    int menuBeingConstructed : 1;
     QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
     static inline void updateScreenSize();
@@ -155,5 +156,5 @@
 class QSymbianControl : public CCoeControl, public QAbstractLongTapObserver
 #ifdef Q_WS_S60
-, public MAknFadedComponent
+, public MAknFadedComponent, public MEikStatusPaneObserver
 #endif
 {
@@ -183,4 +184,5 @@
 #ifdef Q_WS_S60
     void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
+    void HandleStatusPaneSizeChange();
 
 protected: // from MAknFadedComponent
@@ -213,4 +215,5 @@
     void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
 #endif
+    void handleClientAreaChange();
 
 private:
Index: trunk/src/gui/kernel/qt_x11_p.h
===================================================================
--- trunk/src/gui/kernel/qt_x11_p.h	(revision 766)
+++ trunk/src/gui/kernel/qt_x11_p.h	(revision 769)
@@ -676,4 +676,7 @@
         XWacomEraser,
 
+        XTabletStylus,
+        XTabletEraser,
+
         NPredefinedAtoms,
 
Index: trunk/src/gui/kernel/qtooltip.cpp
===================================================================
--- trunk/src/gui/kernel/qtooltip.cpp	(revision 766)
+++ trunk/src/gui/kernel/qtooltip.cpp	(revision 769)
@@ -169,7 +169,7 @@
 QTipLabel::QTipLabel(const QString &text, QWidget *w)
 #ifndef QT_NO_STYLE_STYLESHEET
-    : QLabel(w, Qt::ToolTip), styleSheetParent(0), widget(0)
+    : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(0), widget(0)
 #else
-    : QLabel(w, Qt::ToolTip), widget(0)
+    : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), widget(0)
 #endif
 {
@@ -369,5 +369,14 @@
 
 #ifdef Q_WS_MAC
-    QRect screen = QApplication::desktop()->availableGeometry(getTipScreen(pos, w));
+    // When in full screen mode, there is no Dock nor Menu so we can use
+    // the whole screen for displaying the tooltip. However when not in
+    // full screen mode we need to save space for the dock, so we use
+    // availableGeometry instead.
+    extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
+    QRect screen;
+    if(qt_mac_app_fullscreen)
+        screen = QApplication::desktop()->screenGeometry(getTipScreen(pos, w));
+    else
+        screen = QApplication::desktop()->availableGeometry(getTipScreen(pos, w));
 #else
     QRect screen = QApplication::desktop()->screenGeometry(getTipScreen(pos, w));
Index: trunk/src/gui/kernel/qwhatsthis.cpp
===================================================================
--- trunk/src/gui/kernel/qwhatsthis.cpp	(revision 766)
+++ trunk/src/gui/kernel/qwhatsthis.cpp	(revision 769)
@@ -144,5 +144,5 @@
 */
 
-extern void qDeleteInEventHandler(QObject *o);
+Q_DECL_IMPORT extern void qDeleteInEventHandler(QObject *o);
 
 class QWhatsThat : public QWidget
Index: trunk/src/gui/kernel/qwidget.cpp
===================================================================
--- trunk/src/gui/kernel/qwidget.cpp	(revision 766)
+++ trunk/src/gui/kernel/qwidget.cpp	(revision 769)
@@ -123,4 +123,8 @@
 #include "private/qgesturemanager_p.h"
 
+#ifdef QT_KEYPAD_NAVIGATION
+#include "qtabwidget.h" // Needed in inTabWidget()
+#endif // QT_KEYPAD_NAVIGATION
+
 // widget/widget data creation count
 //#define QWIDGET_EXTRA_DEBUG
@@ -197,4 +201,5 @@
       , isScrolled(0)
       , isMoved(0)
+      , isGLWidget(0)
       , usesDoubleBufferedGLContext(0)
 #if defined(Q_WS_X11)
@@ -207,5 +212,4 @@
 #elif defined(Q_WS_MAC)
       , needWindowChange(0)
-      , isGLWidget(0)
       , window_event(0)
       , qd_hd(0)
@@ -1446,4 +1450,5 @@
 #endif
 
+#ifdef Q_OS_SYMBIAN
     if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
         // Okay, we are about to destroy the top-level window that owns
@@ -1455,5 +1460,7 @@
         delete d->extra->topextra->backingStore;
         d->extra->topextra->backingStore = 0;
-    } else if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
+    }
+#endif
+    if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
         bs->removeDirtyWidget(this);
         if (testAttribute(Qt::WA_StaticContents))
@@ -1487,6 +1494,10 @@
         QWidgetPrivate::allWidgets->remove(this);
 
-    QEvent e(QEvent::Destroy);
-    QCoreApplication::sendEvent(this, &e);
+    QT_TRY {
+        QEvent e(QEvent::Destroy);
+        QCoreApplication::sendEvent(this, &e);
+    } QT_CATCH(const std::exception&) {
+        // if this fails we can't do anything about it but at least we are not allowed to throw.
+    }
 }
 
@@ -1676,5 +1687,11 @@
         dirty = QRegion();
     } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+#ifdef QT_MAC_USE_COCOA
+        Q_UNUSED(bs);
+        void qt_mac_set_needs_display(QWidget *, QRegion);
+        qt_mac_set_needs_display(q_func(), QRegion());
+#else
         bs->sync();
+#endif
     }
 }
@@ -1684,6 +1701,13 @@
     if (paintOnScreen())
         repaint_sys(region);
-    else if (QWidgetBackingStore *bs = maybeBackingStore())
+    else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+#ifdef QT_MAC_USE_COCOA
+        Q_UNUSED(bs);
+        void qt_mac_set_needs_display(QWidget *, QRegion);
+        qt_mac_set_needs_display(q_func(), region);
+#else
         bs->sync(q_func(), region);
+#endif
+    }
 }
 
@@ -3368,5 +3392,5 @@
     appear on screen. This also applies to windows.
 
-    \sa pos, geometry, minimumSize, maximumSize, resizeEvent()
+    \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
 */
 
@@ -6110,4 +6134,6 @@
             if (previousProxyFocus && previousProxyFocus->focusProxy())
                 previousProxyFocus = previousProxyFocus->focusProxy();
+            if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
+                return;
         }
     }
@@ -7522,4 +7548,21 @@
         if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
             continue;
+#ifdef QT_MAC_USE_COCOA
+        // Before doing anything we need to make sure that we don't leave anything in a non-consistent state.
+        // When hiding a widget we need to make sure that no mouse_down events are active, because
+        // the mouse_up event will never be received by a hidden widget or one of its descendants.
+        // The solution is simple, before going through with this we check if there are any mouse_down events in
+        // progress, if so we check if it is related to this widget or not. If so, we just reset the mouse_down and
+        // then we continue.
+        // In X11 and Windows we send a mouse_release event, however we don't do that here because we were already
+        // ignoring that from before. I.e. Carbon did not send the mouse release event, so we will not send the
+        // mouse release event. There are two ways to interpret this:
+        // 1. If we don't send the mouse release event, the widget might get into an inconsistent state, i.e. it
+        // might be waiting for a release event that will never arrive.
+        // 2. If we send the mouse release event, then the widget might decide to trigger an action that is not
+        // supposed to trigger because it is not visible.
+        if(widget == qt_button_down)
+            qt_button_down = 0;
+#endif // QT_MAC_USE_COCOA
         if (spontaneous)
             widget->setAttribute(Qt::WA_Mapped, false);
@@ -7916,11 +7959,14 @@
     if(w && w->isWindow() && w->isVisible() && w->isEnabled()) {
         LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE);
+        LONG newStyle = dwStyle;
         if (setStyle)
-            dwStyle |= WS_DISABLED;
+            newStyle |= WS_DISABLED;
         else
-            dwStyle &= ~WS_DISABLED;
-        SetWindowLong(w->winId(), GWL_STYLE, dwStyle);
-        // we might need to repaint in some situations (eg. menu)
-        w->repaint();
+            newStyle &= ~WS_DISABLED;
+        if (newStyle != dwStyle) {
+            SetWindowLong(w->winId(), GWL_STYLE, newStyle);
+            // we might need to repaint in some situations (eg. menu)
+            w->repaint();
+        }
     }
 }
@@ -8262,5 +8308,5 @@
 
 #ifdef QT_SOFTKEYS_ENABLED
-        if (isWindow() && isActiveWindow())
+        if (isWindow())
             QSoftKeyManager::updateSoftKeys();
 #endif
@@ -11731,4 +11777,43 @@
     return targetWidget;
 }
+
+/*!
+    \internal
+
+    Tells us if it there is currently a reachable widget by keypad navigation in
+    a certain \a orientation.
+    If no navigation is possible, occuring key events in that \a orientation may
+    be used to interact with the value in the focussed widget, even though it
+    currently has not the editFocus.
+
+    \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
+*/
+bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
+{
+    return orientation == Qt::Horizontal?
+            (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
+                    || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
+            :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
+                    || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
+}
+/*!
+    \internal
+
+    Checks, if the \a widget is inside a QTabWidget. If is is inside
+    one, left/right key events will be used to switch between tabs in keypad
+    navigation. If there is no QTabWidget, the horizontal key events can be used
+to
+    interact with the value in the focussed widget, even though it currently has
+    not the editFocus.
+
+    \sa QWidget::hasEditFocus()
+*/
+bool QWidgetPrivate::inTabWidget(QWidget *widget)
+{
+    for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
+        if (qobject_cast<const QTabWidget*>(tabWidget))
+            return true;
+    return false;
+}
 #endif
 
Index: trunk/src/gui/kernel/qwidget_mac.mm
===================================================================
--- trunk/src/gui/kernel/qwidget_mac.mm	(revision 766)
+++ trunk/src/gui/kernel/qwidget_mac.mm	(revision 769)
@@ -153,4 +153,5 @@
 QWidget *mac_mouse_grabber = 0;
 QWidget *mac_keyboard_grabber = 0;
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
 
 #ifndef QT_MAC_USE_COCOA
@@ -563,4 +564,23 @@
     // below 'stays on top' windows. Add 1 to get above pure stay-on-top windows.
     qt_mac_set_window_group(window, Qt::Popup, qt_mac_get_group_level(kOverlayWindowClass)+1);
+}
+#endif
+
+#ifdef QT_MAC_USE_COCOA
+void qt_mac_set_needs_display(QWidget *widget, QRegion region)
+{
+    NSView *theNSView = qt_mac_nativeview_for(widget);
+    if (region.isEmpty()) {
+        [theNSView setNeedsDisplay:YES];
+        return;
+    }
+
+    QVector<QRect> rects = region.rects();
+    for (int i = 0; i<rects.count(); ++i) {
+        const QRect &rect = rects.at(i);
+        NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+        [theNSView setNeedsDisplayInRect:nsrect];
+    }
+
 }
 #endif
@@ -848,5 +868,4 @@
                 QApplication::sendSpontaneousEvent(widget, &e);
             }
-            extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
             qt_button_down = 0;
         } else if(ekind == kEventWindowCollapsed) {
@@ -876,5 +895,4 @@
             QEvent e(QEvent::Hide);
             QApplication::sendSpontaneousEvent(widget, &e);
-            extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
             qt_button_down = 0;
         } else if(ekind == kEventWindowToolbarSwitchMode) {
@@ -1250,4 +1268,9 @@
                     if(widget->testAttribute(Qt::WA_WState_InPaintEvent))
                         qWarning("QWidget::repaint: Recursive repaint detected");
+                    if (widget->isWindow() && !widget->d_func()->isOpaque
+                        && !widget->testAttribute(Qt::WA_MacBrushedMetal)) {
+                        QRect qrgnRect = qrgn.boundingRect();
+                        CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height()));
+                    }
 
                     QPoint redirectionOffset(0, 0);
@@ -1299,11 +1322,4 @@
                             widget->d_func()->restoreRedirected();
                     }
-
-                    if (widget->isWindow() && !widget->d_func()->isOpaque
-                           && !widget->testAttribute(Qt::WA_MacBrushedMetal)) {
-                        QRect qrgnRect = qrgn.boundingRect();
-                        CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height()));
-                    }
-
 
                     if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
@@ -1503,5 +1519,4 @@
                 qt_event_request_window_change(widget);
                 if (!HIViewIsVisible(HIViewRef(widget->winId()))) {
-                    extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
                     if (widget == qt_button_down)
                         qt_button_down = 0;
@@ -1512,5 +1527,4 @@
     case kEventClassMouse: {
         bool send_to_app = false;
-        extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
         if(qt_button_down)
             send_to_app = true;
@@ -3389,5 +3403,4 @@
     if((q->windowType() == Qt::Desktop)) //you can't hide the desktop!
         return;
-
     QMacCocoaAutoReleasePool pool;
     if(q->isWindow()) {
@@ -3511,4 +3524,6 @@
     if (!QWidget::mouseGrabber()){
         QWidget *enterWidget = QApplication::widgetAt(QCursor::pos());
+        if (enterWidget && enterWidget->data->in_destructor)
+            enterWidget = 0;
         QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover);
         qt_mouseover = enterWidget;
@@ -4455,6 +4470,18 @@
     }
 
+    // ### Scroll the dirty regions as well, the following is not correct.
+    QRegion displayRegion = r.isNull() ? dirtyOnWidget : (dirtyOnWidget & r);
+    const QVector<QRect> &rects = dirtyOnWidget.rects();
+    const QVector<QRect>::const_iterator end = rects.end();
+    QVector<QRect>::const_iterator it = rects.begin();
+    while (it != end) {
+	const QRect rect = *it;
+	const NSRect dirtyRect = NSMakeRect(rect.x() + dx, rect.y() + dy,
+		rect.width(), rect.height());
+	[view setNeedsDisplayInRect:dirtyRect];
+	++it;
+    }
+
     NSSize deltaSize = NSMakeSize(dx, dy);
-    [view translateRectsNeedingDisplayInRect:scrollRect by:deltaSize];
     [view scrollRect:scrollRect by:deltaSize];
     [view setNeedsDisplayInRect:deltaXRect];
@@ -4656,6 +4683,8 @@
         return;
 
-    if (extra->hasMask && extra->maskBits.size() != q->size()) {
-        extra->maskBits = QImage(q->size(), QImage::Format_Mono);
+    if (extra->hasMask) {
+        if(extra->maskBits.size() != q->size()) {
+            extra->maskBits = QImage(q->size(), QImage::Format_Mono);
+        }
         extra->maskBits.fill(QColor(Qt::color1).rgba());
         extra->maskBits.setNumColors(2);
Index: trunk/src/gui/kernel/qwidget_p.h
===================================================================
--- trunk/src/gui/kernel/qwidget_p.h	(revision 766)
+++ trunk/src/gui/kernel/qwidget_p.h	(revision 769)
@@ -242,4 +242,13 @@
 
     /**
+     * If this bit is set, each native widget receives the signals from the
+     * Symbian control immediately before and immediately after draw ops are
+     * sent to the window server for this control:
+     *      void beginNativePaintEvent(const QRect &paintRect);
+     *      void endNativePaintEvent(const QRect &paintRect);
+     */
+    uint receiveNativePaintEvents : 1;
+
+    /**
      * Defines the behaviour of QSymbianControl::Draw.
      */
@@ -266,14 +275,5 @@
     };
 
-    NativePaintMode nativePaintMode : 2;
-
-    /**
-     * If this bit is set, each native widget receives the signals from the
-     * Symbian control immediately before and immediately after draw ops are
-     * sent to the window server for this control:
-     *      void beginNativePaintEvent(const QRect &paintRect);
-     *      void endNativePaintEvent(const QRect &paintRect);
-     */
-    uint receiveNativePaintEvents : 1;
+    NativePaintMode nativePaintMode;
 
 #elif defined(Q_WS_PM) // <----------------------------------------------------- PM
@@ -483,4 +483,6 @@
     static bool navigateToDirection(Direction direction);
     static QWidget *widgetInNavigationDirection(Direction direction);
+    static bool canKeypadNavigate(Qt::Orientation orientation);
+    static bool inTabWidget(QWidget *widget);
 #endif
 
@@ -694,4 +696,5 @@
     uint isScrolled : 1;
     uint isMoved : 1;
+    uint isGLWidget : 1;
     uint usesDoubleBufferedGLContext : 1;
 
@@ -734,5 +737,4 @@
     // This is new stuff
     uint needWindowChange : 1;
-    uint isGLWidget : 1;
 
     // Each wiget keeps a list of all its child and grandchild OpenGL widgets.
Index: trunk/src/gui/kernel/qwidget_s60.cpp
===================================================================
--- trunk/src/gui/kernel/qwidget_s60.cpp	(revision 766)
+++ trunk/src/gui/kernel/qwidget_s60.cpp	(revision 769)
@@ -388,14 +388,4 @@
             drawableWindow->EnableVisibilityChangeEvents();
 
-            if (!isOpaque) {
-                RWindow *const window = static_cast<RWindow *>(drawableWindow);
-#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
-                window->SetSurfaceTransparency(true);
-#else
-                const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
-                if (window->SetTransparencyAlphaChannel() == KErrNone)
-                    window->SetBackgroundColor(TRgb(255, 255, 255, 0));
-#endif
-            }
         }
 
@@ -409,4 +399,7 @@
         // this generates a WinIdChanged event.
         setWinId(control.take());
+
+        if (!desktop)
+            s60UpdateIsOpaque(); // must be called after setWinId()
 
     } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create native child widget
@@ -488,4 +481,42 @@
 
          QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
+
+#ifdef Q_WS_S60
+        // Lazily initialize the S60 screen furniture when the first window is shown.
+        if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
+                && !S60->buttonGroupContainer() && !S60->statusPane()) {
+
+            bool isFullscreen = q->windowState() & Qt::WindowFullScreen;
+
+            if (!q->testAttribute(Qt::WA_DontShowOnScreen)) {
+
+                // Create the status pane and CBA here
+                CEikAppUi *ui = static_cast<CEikAppUi *>(S60->appUi());
+                MEikAppUiFactory *factory = CEikonEnv::Static()->AppUiFactory();
+                TRAP_IGNORE(factory->ReadAppInfoResourceL(0, ui));
+                if (S60->buttonGroupContainer())
+                    S60->buttonGroupContainer()->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+
+                if (S60->statusPane()) {
+                    // Use QDesktopWidget as the status pane observer to proxy for the AppUi.
+                    // Can't use AppUi directly because it privately inherits from MEikStatusPaneObserver.
+                    QSymbianControl *desktopControl = static_cast<QSymbianControl *>(QApplication::desktop()->winId());
+                    S60->statusPane()->SetObserver(desktopControl);
+
+                    // Hide the status pane if fullscreen OR
+                    // Fill client area if maximized OR
+                    // Put window below status pane unless the window has an explicit position.
+                    if (isFullscreen) {
+                        S60->statusPane()->MakeVisible(false);
+                    } else if (q->windowState() & Qt::WindowMaximized) {
+                        TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+                        id->SetExtent(r.iTl, r.Size());
+                    } else if (!q->testAttribute(Qt::WA_Moved)) {
+                        id->SetPosition(static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl);
+                    }
+                }
+            }
+        }
+#endif
 
         id->MakeVisible(true);
@@ -1038,4 +1069,15 @@
 }
 
+static Qt::WindowStates effectiveState(Qt::WindowStates state)
+{
+    if (state & Qt::WindowMinimized)
+        return Qt::WindowMinimized;
+    else if (state & Qt::WindowFullScreen)
+        return Qt::WindowFullScreen;
+    else if (state & Qt::WindowMaximized)
+        return Qt::WindowMaximized;
+    return Qt::WindowNoState;
+}
+
 void QWidget::setWindowState(Qt::WindowStates newstate)
 {
@@ -1043,8 +1085,19 @@
 
     Qt::WindowStates oldstate = windowState();
-    if (oldstate == newstate)
+
+    const TBool isFullscreen = newstate & Qt::WindowFullScreen;
+    const TBool cbaRequested = windowFlags() & Qt::WindowSoftkeysVisibleHint;
+    const TBool cbaVisible = CEikButtonGroupContainer::Current() ? true : false;
+    const TBool softkeyVisibilityChange = isFullscreen && (cbaRequested != cbaVisible);
+
+    if (oldstate == newstate && !softkeyVisibilityChange)
         return;
 
     if (isWindow()) {
+        createWinId();
+        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+
+        const bool wasResized = testAttribute(Qt::WA_Resized);
+        const bool wasMoved = testAttribute(Qt::WA_Moved);
 
         QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId());
@@ -1059,34 +1112,56 @@
 #ifdef Q_WS_S60
         // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
-        // The window decoration visibility has to be changed before doing actual window state 
-        // change since in that order the availableGeometry will return directly the right size and 
+        // The window decoration visibility has to be changed before doing actual window state
+        // change since in that order the availableGeometry will return directly the right size and
         // we will avoid unnecessarty redraws
-        CEikStatusPane* statusPane = S60->statusPane();
-        CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
-        TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); 
+        CEikStatusPane *statusPane = S60->statusPane();
+        CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
+        TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
         if (statusPane)
             statusPane->MakeVisible(visible);
-        if (buttonGroup)
-            buttonGroup->MakeVisible(visible);
+        if (buttonGroup) {
+            // Visibility
+            buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested));
+        }
 #endif // Q_WS_S60
 
-        createWinId();
-        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
         // Ensure the initial size is valid, since we store it as normalGeometry below.
-        if (!testAttribute(Qt::WA_Resized) && !isVisible())
+        if (!wasResized && !isVisible())
             adjustSize();
 
         QTLWExtra *top = d->topData();
-        const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
-
-        if (newstate & Qt::WindowFullScreen)
-            setGeometry(qApp->desktop()->screenGeometry(this));
-        else if (newstate & Qt::WindowMaximized)
-            setGeometry(qApp->desktop()->availableGeometry(this));
-        else
+        QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
+
+        const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
+        if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) {
+            window->SetExtentToWholeScreen();
+        } else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) {
+            TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this));
+            window->SetExtent(maxExtent.iTl, maxExtent.Size());
+        } else {
+#ifdef Q_WS_S60
+            // With delayed creation of S60 app panes, the normalGeometry calculated above is not
+            // accurate because it did not consider the status pane. This means that when returning
+            // normal mode after showing the status pane, the geometry would overlap so we should
+            // move it if it never had an explicit position.
+            if (!wasMoved && statusPane && visible) {
+                TPoint tl = static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl;
+                normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY));
+            }
+#endif
             setGeometry(normalGeometry);
+        }
 
         //restore normal geometry
         top->normalGeometry = normalGeometry;
+
+        // FixMe QTBUG-8977
+        // In some platforms, WA_Resized and WA_Moved are also not set when application window state is
+        // anything else than normal. In Symbian we can restore them only for normal window state since
+        // restoring for other modes, will make fluidlauncher to be launched in wrong size (200x100)
+        if (effectiveState(newstate) == Qt::WindowNoState) {
+            setAttribute(Qt::WA_Resized, wasResized);
+            setAttribute(Qt::WA_Moved, wasMoved);
+        }
     }
 
@@ -1221,6 +1296,8 @@
     if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-        WId id = effectiveWinId();
-        id->SetPointerCapture(false);
+        if(!window()->isModal()) {
+            WId id = effectiveWinId();
+            id->SetPointerCapture(false);
+        }
         QWidgetPrivate::mouseGrabber = 0;
 #ifndef QT_NO_CURSOR
Index: trunk/src/gui/kernel/qwidget_win.cpp
===================================================================
--- trunk/src/gui/kernel/qwidget_win.cpp	(revision 766)
+++ trunk/src/gui/kernel/qwidget_win.cpp	(revision 769)
@@ -2053,4 +2053,6 @@
         return;
 
+    if (!QApplicationPrivate::HasTouchSupport)
+        return;
     QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
     if (!qAppPriv->SetGestureConfig)
Index: trunk/src/gui/kernel/qwidget_x11.cpp
===================================================================
--- trunk/src/gui/kernel/qwidget_x11.cpp	(revision 766)
+++ trunk/src/gui/kernel/qwidget_x11.cpp	(revision 769)
@@ -347,9 +347,4 @@
 }
 
-static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
-{
-    return e->type == ConfigureNotify || e->type == Expose;
-}
-
 Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
 {
@@ -364,36 +359,40 @@
         return;
 
-    if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
-        // if the window is not override-redirect, then the window manager
-        // will reparent us to the frame decoration window.
-        while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
-            if (t.elapsed() > maximumWaitTime)
-                return;
-            qApp->syncX(); // non-busy wait
-        }
-    }
-
-    while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
+    WId winid = w->internalWinId();
+
+    // first deliver events that are already in the local queue
+    QApplication::sendPostedEvents();
+
+    // the normal sequence is:
+    //  ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
+    // with X11BypassWindowManagerHint:
+    //  ConfigureNotify ... MapNotify ... Expose
+
+    enum State {
+        Initial, Mapped
+    } state = Initial;
+
+    do {
+        if (XEventsQueued(X11->display, QueuedAlready)) {
+            XNextEvent(X11->display, &ev);
+            qApp->x11ProcessEvent(&ev);
+
+            switch (state) {
+            case Initial:
+                if (ev.type == MapNotify && ev.xany.window == winid)
+                    state = Mapped;
+                break;
+            case Mapped:
+                if (ev.type == Expose && ev.xany.window == winid)
+                    return;
+                break;
+            }
+        } else {
+            if (!XEventsQueued(X11->display, QueuedAfterFlush))
+                qApp->syncX(); // non-busy wait
+        }
         if (t.elapsed() > maximumWaitTime)
             return;
-        qApp->syncX(); // non-busy wait
-    }
-
-    qApp->x11ProcessEvent(&ev);
-
-    // ok, seems like the window manager successfully reparented us, we'll wait
-    // for the first paint event to arrive, while handling ConfigureNotify in
-    // the arrival order
-    while(1)
-    {
-        if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
-            qApp->x11ProcessEvent(&ev);
-            if (ev.type == Expose)
-                return;
-        }
-        if (t.elapsed() > maximumWaitTime)
-            return;
-        qApp->syncX(); // non-busy wait
-    }
+    } while(1);
 }
 
Index: trunk/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
===================================================================
--- trunk/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h	(revision 766)
+++ trunk/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h	(revision 769)
@@ -55,4 +55,36 @@
 
 #include <QGestureRecognizer>
+#include <objbase.h>
+
+class IInkRectangle;
+class TabletHardwareCapabilities;
+class TabletPropertyMetricUnit;
+DECLARE_INTERFACE_(IInkTablet, IDispatch)
+{
+	STDMETHOD(get_Name)(THIS_ BSTR *Name) PURE;
+	STDMETHOD(get_PlugAndPlayId)(THIS_ BSTR *Id) PURE;
+	STDMETHOD(get_MaximumInputRectangle)(THIS_ IInkRectangle **Rectangle) PURE;
+	STDMETHOD(get_HardwareCapabilities)(THIS_ TabletHardwareCapabilities *Capabilities) PURE;
+	STDMETHOD(IsPacketPropertySupported)(THIS_ BSTR packetPropertyName) PURE;
+	STDMETHOD(GetPropertyMetrics)(THIS_ BSTR propertyName, long *Minimum, long *Maximum, TabletPropertyMetricUnit *Units, float *Resolution) PURE;
+};
+enum TabletDeviceKind
+{
+	TDK_Mouse = 0,
+	TDK_Pen   = 1,
+	TDK_Touch = 2
+};
+DECLARE_INTERFACE_(IInkTablet2, IDispatch)
+{
+	STDMETHOD(get_DeviceKind)(THIS_ TabletDeviceKind *Kind) PURE;
+};
+DECLARE_INTERFACE_(IInkTablets, IDispatch)
+{
+	STDMETHOD(get_Count)(THIS_ long *Count) PURE;
+	STDMETHOD(get__NewEnum)(THIS_ IUnknown **_NewEnum) PURE;
+	STDMETHOD(get_DefaultTablet)(THIS_ IInkTablet **DefaultTablet) PURE;
+	STDMETHOD(Item)(THIS_ long Index, IInkTablet **Tablet) PURE;
+	STDMETHOD(IsPacketPropertySupported)(THIS_ BSTR packetPropertyName, VARIANT_BOOL *Supported) PURE;
+};
 
 QT_BEGIN_NAMESPACE
Index: trunk/src/gui/painting/qbackingstore.cpp
===================================================================
--- trunk/src/gui/painting/qbackingstore.cpp	(revision 766)
+++ trunk/src/gui/painting/qbackingstore.cpp	(revision 769)
@@ -353,4 +353,8 @@
     dirtyOnScreen += toClean;
 
+#ifdef Q_WS_QWS
+    toClean.translate(tlwOffset);
+#endif
+
 #ifdef QT_NO_PAINT_DEBUG
     windowSurface->beginPaint(toClean);
@@ -767,5 +771,10 @@
         return;
 
-    windowSurface->beginPaint(decorationRegion);
+    //### The QWS decorations do not always paint the pixels they promise to paint.
+    // This causes painting problems with QWSMemorySurface. Since none of the other
+    // window surfaces actually use the region, passing an empty region is a safe
+    // workaround.
+
+    windowSurface->beginPaint(QRegion());
 
     QPaintEngine *engine = windowSurface->paintDevice()->paintEngine();
Index: trunk/src/gui/painting/qbrush.cpp
===================================================================
--- trunk/src/gui/painting/qbrush.cpp	(revision 766)
+++ trunk/src/gui/painting/qbrush.cpp	(revision 769)
@@ -161,6 +161,5 @@
 }
 
-Q_GUI_EXPORT
-QImage qt_imageForBrush(int brushStyle, bool invert)
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
 {
     return qt_brushPatternImageCache()->getImage(brushStyle, invert);
@@ -990,5 +989,6 @@
      "RadialGradientPattern",
      "ConicalGradientPattern",
-     "TexturePattern"
+     0, 0, 0, 0, 0, 0,
+     "TexturePattern" // 24
     };
 
Index: trunk/src/gui/painting/qcups.cpp
===================================================================
--- trunk/src/gui/painting/qcups.cpp	(revision 766)
+++ trunk/src/gui/painting/qcups.cpp	(revision 769)
@@ -378,7 +378,6 @@
         return false;
     const char *ppdFile = _cupsGetPPD(printerName);
-    if (ppdFile != 0)
-        unlink(ppdFile);
-    return ppdFile != 0;
+    unlink(ppdFile);
+    return (ppdFile != 0);
 }
 
Index: trunk/src/gui/painting/qdrawhelper.cpp
===================================================================
--- trunk/src/gui/painting/qdrawhelper.cpp	(revision 766)
+++ trunk/src/gui/painting/qdrawhelper.cpp	(revision 769)
@@ -1268,30 +1268,26 @@
   d = d * cia
 */
+#define comp_func_Clear_impl(dest, length, const_alpha)\
+{\
+    if (const_alpha == 255) {\
+        QT_MEMFILL_UINT(dest, length, 0);\
+    } else {\
+        int ialpha = 255 - const_alpha;\
+        PRELOAD_INIT(dest)\
+        for (int i = 0; i < length; ++i) {\
+            PRELOAD_COND(dest)\
+            dest[i] = BYTE_MUL(dest[i], ialpha);\
+        }\
+    }\
+}
+
 static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
 {
-    if (const_alpha == 255) {
-        QT_MEMFILL_UINT(dest, length, 0);
-    } else {
-        int ialpha = 255 - const_alpha;
-        PRELOAD_INIT(dest)
-        for (int i = 0; i < length; ++i) {
-            PRELOAD_COND(dest)
-            dest[i] = BYTE_MUL(dest[i], ialpha);
-        }
-    }
+    comp_func_Clear_impl(dest, length, const_alpha);
 }
 
 static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
 {
-    if (const_alpha == 255) {
-        QT_MEMFILL_UINT(dest, length, 0);
-    } else {
-        int ialpha = 255 - const_alpha;
-        PRELOAD_INIT(dest)
-        for (int i = 0; i < length; ++i) {
-            PRELOAD_COND(dest)
-            dest[i] = BYTE_MUL(dest[i], ialpha);
-        }
-    }
+    comp_func_Clear_impl(dest, length, const_alpha);
 }
 
@@ -2409,5 +2405,9 @@
         return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
     else {
+#   ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2
+        return (dst * sa * 255 + da * (src2 - sa) * (qIntSqrtInt(dst_np * 255) - dst_np) + temp) / 65025;
+#   else
         return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
+#   endif
     }
 }
@@ -7175,7 +7175,7 @@
 
         int a = qGray(coverage);
-        sr = qt_div_255(sr * a);
-        sg = qt_div_255(sg * a);
-        sb = qt_div_255(sb * a);
+        sr = qt_div_255(qt_pow_rgb_invgamma[sr] * a);
+        sg = qt_div_255(qt_pow_rgb_invgamma[sg] * a);
+        sb = qt_div_255(qt_pow_rgb_invgamma[sb] * a);
 
         int ia = 255 - a;
@@ -8093,18 +8093,41 @@
         }
 #endif // 3DNOW
-        extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl,
-                                                const uchar *srcPixels, int sbpl,
-                                                int w, int h,
-                                                int const_alpha);
-        extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl,
-                                                  const uchar *srcPixels, int sbpl,
-                                                  int w, int h,
-                                                  int const_alpha);
-
-        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
-        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
-        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
-        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
-    }
+
+
+#ifdef QT_HAVE_SSE2
+        if (features & SSE2) {
+            extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
+                                                     const uchar *srcPixels, int sbpl,
+                                                     int w, int h,
+                                                     int const_alpha);
+            extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+                                                       const uchar *srcPixels, int sbpl,
+                                                       int w, int h,
+                                                       int const_alpha);
+
+
+            qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
+            qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
+            qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+            qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+        } else
+#endif
+        {
+            extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl,
+                                                    const uchar *srcPixels, int sbpl,
+                                                    int w, int h,
+                                                    int const_alpha);
+            extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl,
+                                                      const uchar *srcPixels, int sbpl,
+                                                      int w, int h,
+                                                      int const_alpha);
+
+
+            qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
+            qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
+            qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
+            qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
+        }
+}
 #endif // SSE
 
Index: trunk/src/gui/painting/qdrawhelper_mmx_p.h
===================================================================
--- trunk/src/gui/painting/qdrawhelper_mmx_p.h	(revision 766)
+++ trunk/src/gui/painting/qdrawhelper_mmx_p.h	(revision 769)
@@ -147,20 +147,22 @@
   d = d * cia
 */
+#define comp_func_Clear_impl(dest, length, const_alpha)\
+{\
+    if (const_alpha == 255) {\
+        qt_memfill(static_cast<quint32*>(dest), quint32(0), length);\
+    } else {\
+        C_FF; C_80; C_00;\
+        m64 ia = MM::negate(MM::load_alpha(const_alpha));\
+        for (int i = 0; i < length; ++i) {\
+            dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\
+        }\
+        MM::end();\
+    }\
+}
+
 template <class MM>
 static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
 {
-    if (!length)
-        return;
-
-    if (const_alpha == 255) {
-        qt_memfill(static_cast<quint32*>(dest), quint32(0), length);
-    } else {
-        C_FF; C_80; C_00;
-        m64 ia = MM::negate(MM::load_alpha(const_alpha));
-        for (int i = 0; i < length; ++i) {
-            dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));
-        }
-    }
-    MM::end();
+    comp_func_Clear_impl(dest, length, const_alpha);
 }
 
@@ -168,13 +170,5 @@
 static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
 {
-    if (const_alpha == 255) {
-        qt_memfill(static_cast<quint32*>(dest), quint32(0), length);
-    } else {
-        C_FF; C_80; C_00;
-        m64 ia = MM::negate(MM::load_alpha(const_alpha));
-        for (int i = 0; i < length; ++i)
-            dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));
-    }
-    MM::end();
+    comp_func_Clear_impl(dest, length, const_alpha);
 }
 
@@ -247,5 +241,8 @@
     if (const_alpha == 255) {
         for (int i = 0; i < length; ++i) {
-            if ((0xff000000 & src[i]) == 0xff000000) {
+            const uint alphaMaskedSource = 0xff000000 & src[i];
+            if (alphaMaskedSource == 0)
+                continue;
+            if (alphaMaskedSource == 0xff000000) {
                 dest[i] = src[i];
             } else {
@@ -258,4 +255,6 @@
         m64 ca = MM::load_alpha(const_alpha);
         for (int i = 0; i < length; ++i) {
+            if ((0xff000000 & src[i]) == 0)
+                continue;
             m64 s = MM::byte_mul(MM::load(src[i]), ca);
             m64 ia = MM::negate(MM::alpha(s));
Index: trunk/src/gui/painting/qdrawhelper_neon.cpp
===================================================================
--- trunk/src/gui/painting/qdrawhelper_neon.cpp	(revision 766)
+++ trunk/src/gui/painting/qdrawhelper_neon.cpp	(revision 769)
@@ -49,41 +49,41 @@
 QT_BEGIN_NAMESPACE
 
-static inline int16x8_t qvdiv_255_s16(int16x8_t x, int16x8_t half)
+static inline uint16x8_t qvdiv_255_u16(uint16x8_t x, uint16x8_t half)
 {
     // result = (x + (x >> 8) + 0x80) >> 8
 
-    const int16x8_t temp = vshrq_n_s16(x, 8); // x >> 8
-    const int16x8_t sum_part = vaddq_s16(x, half); // x + 0x80
-    const int16x8_t sum = vaddq_s16(temp, sum_part);
-
-    return vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(sum), 8));
-}
-
-static inline int16x8_t qvbyte_mul_s16(int16x8_t x, int16x8_t alpha, int16x8_t half)
+    const uint16x8_t temp = vshrq_n_u16(x, 8); // x >> 8
+    const uint16x8_t sum_part = vaddq_u16(x, half); // x + 0x80
+    const uint16x8_t sum = vaddq_u16(temp, sum_part);
+
+    return vshrq_n_u16(sum, 8);
+}
+
+static inline uint16x8_t qvbyte_mul_u16(uint16x8_t x, uint16x8_t alpha, uint16x8_t half)
 {
     // t = qRound(x * alpha / 255.0)
 
-    const int16x8_t t = vmulq_s16(x, alpha); // t
-    return qvdiv_255_s16(t, half);
-}
-
-static inline int16x8_t qvinterpolate_pixel_255(int16x8_t x, int16x8_t a, int16x8_t y, int16x8_t b, int16x8_t half)
+    const uint16x8_t t = vmulq_u16(x, alpha); // t
+    return qvdiv_255_u16(t, half);
+}
+
+static inline uint16x8_t qvinterpolate_pixel_255(uint16x8_t x, uint16x8_t a, uint16x8_t y, uint16x8_t b, uint16x8_t half)
 {
     // t = x * a + y * b
 
-    const int16x8_t ta = vmulq_s16(x, a);
-    const int16x8_t tb = vmulq_s16(y, b);
-
-    return qvdiv_255_s16(vaddq_s16(ta, tb), half);
-}
-
-static inline int16x8_t qvsource_over_s16(int16x8_t src16, int16x8_t dst16, int16x8_t half, int16x8_t full)
-{
-    const int16x4_t alpha16_high = vdup_lane_s16(vget_high_s16(src16), 3);
-    const int16x4_t alpha16_low = vdup_lane_s16(vget_low_s16(src16), 3);
-
-    const int16x8_t alpha16 = vsubq_s16(full, vcombine_s16(alpha16_low, alpha16_high));
-
-    return vaddq_s16(src16, qvbyte_mul_s16(dst16, alpha16, half));
+    const uint16x8_t ta = vmulq_u16(x, a);
+    const uint16x8_t tb = vmulq_u16(y, b);
+
+    return qvdiv_255_u16(vaddq_u16(ta, tb), half);
+}
+
+static inline uint16x8_t qvsource_over_u16(uint16x8_t src16, uint16x8_t dst16, uint16x8_t half, uint16x8_t full)
+{
+    const uint16x4_t alpha16_high = vdup_lane_u16(vget_high_u16(src16), 3);
+    const uint16x4_t alpha16_low = vdup_lane_u16(vget_low_u16(src16), 3);
+
+    const uint16x8_t alpha16 = vsubq_u16(full, vcombine_u16(alpha16_low, alpha16_high));
+
+    return vaddq_u16(src16, qvbyte_mul_u16(dst16, alpha16, half));
 }
 
@@ -95,19 +95,19 @@
     const uint *src = (const uint *) srcPixels;
     uint *dst = (uint *) destPixels;
-    int16x8_t half = vdupq_n_s16(0x80);
-    int16x8_t full = vdupq_n_s16(0xff);
+    uint16x8_t half = vdupq_n_u16(0x80);
+    uint16x8_t full = vdupq_n_u16(0xff);
     if (const_alpha == 256) {
         for (int y = 0; y < h; ++y) {
             int x = 0;
             for (; x < w-3; x += 4) {
-                int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+                uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]);
                 if ((src[x] & src[x+1] & src[x+2] & src[x+3]) >= 0xff000000) {
                     // all opaque
-                    vst1q_s32((int32_t *)&dst[x], src32);
+                    vst1q_u32((uint32_t *)&dst[x], src32);
                 } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
-                    int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
-
-                    const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
-                    const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+                    uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]);
+
+                    const uint8x16_t src8 = vreinterpretq_u8_u32(src32);
+                    const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32);
 
                     const uint8x8_t src8_low = vget_low_u8(src8);
@@ -117,17 +117,17 @@
                     const uint8x8_t dst8_high = vget_high_u8(dst8);
 
-                    const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
-                    const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
-
-                    const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
-                    const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
-
-                    const int16x8_t result16_low = qvsource_over_s16(src16_low, dst16_low, half, full);
-                    const int16x8_t result16_high = qvsource_over_s16(src16_high, dst16_high, half, full);
-
-                    const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
-                    const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
-
-                    vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+                    const uint16x8_t src16_low = vmovl_u8(src8_low);
+                    const uint16x8_t dst16_low = vmovl_u8(dst8_low);
+
+                    const uint16x8_t src16_high = vmovl_u8(src8_high);
+                    const uint16x8_t dst16_high = vmovl_u8(dst8_high);
+
+                    const uint16x8_t result16_low = qvsource_over_u16(src16_low, dst16_low, half, full);
+                    const uint16x8_t result16_high = qvsource_over_u16(src16_high, dst16_high, half, full);
+
+                    const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low));
+                    const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high));
+
+                    vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high));
                 }
             }
@@ -144,14 +144,14 @@
     } else if (const_alpha != 0) {
         const_alpha = (const_alpha * 255) >> 8;
-        int16x8_t const_alpha16 = vdupq_n_s16(const_alpha);
+        uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha);
         for (int y = 0; y < h; ++y) {
             int x = 0;
             for (; x < w-3; x += 4) {
                 if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
-                    int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
-                    int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
-
-                    const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
-                    const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+                    uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]);
+                    uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]);
+
+                    const uint8x16_t src8 = vreinterpretq_u8_u32(src32);
+                    const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32);
 
                     const uint8x8_t src8_low = vget_low_u8(src8);
@@ -161,20 +161,20 @@
                     const uint8x8_t dst8_high = vget_high_u8(dst8);
 
-                    const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
-                    const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
-
-                    const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
-                    const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
-
-                    const int16x8_t srcalpha16_low = qvbyte_mul_s16(src16_low, const_alpha16, half);
-                    const int16x8_t srcalpha16_high = qvbyte_mul_s16(src16_high, const_alpha16, half);
-
-                    const int16x8_t result16_low = qvsource_over_s16(srcalpha16_low, dst16_low, half, full);
-                    const int16x8_t result16_high = qvsource_over_s16(srcalpha16_high, dst16_high, half, full);
-
-                    const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
-                    const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
-
-                    vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+                    const uint16x8_t src16_low = vmovl_u8(src8_low);
+                    const uint16x8_t dst16_low = vmovl_u8(dst8_low);
+
+                    const uint16x8_t src16_high = vmovl_u8(src8_high);
+                    const uint16x8_t dst16_high = vmovl_u8(dst8_high);
+
+                    const uint16x8_t srcalpha16_low = qvbyte_mul_u16(src16_low, const_alpha16, half);
+                    const uint16x8_t srcalpha16_high = qvbyte_mul_u16(src16_high, const_alpha16, half);
+
+                    const uint16x8_t result16_low = qvsource_over_u16(srcalpha16_low, dst16_low, half, full);
+                    const uint16x8_t result16_high = qvsource_over_u16(srcalpha16_high, dst16_high, half, full);
+
+                    const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low));
+                    const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high));
+
+                    vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high));
                 }
             }
@@ -207,17 +207,17 @@
             const uint *src = (const uint *) srcPixels;
             uint *dst = (uint *) destPixels;
-            int16x8_t half = vdupq_n_s16(0x80);
+            uint16x8_t half = vdupq_n_u16(0x80);
             const_alpha = (const_alpha * 255) >> 8;
             int one_minus_const_alpha = 255 - const_alpha;
-            int16x8_t const_alpha16 = vdupq_n_s16(const_alpha);
-            int16x8_t one_minus_const_alpha16 = vdupq_n_s16(255 - const_alpha);
+            uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha);
+            uint16x8_t one_minus_const_alpha16 = vdupq_n_u16(255 - const_alpha);
             for (int y = 0; y < h; ++y) {
                 int x = 0;
                 for (; x < w-3; x += 4) {
-                    int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
-                    int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
-
-                    const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
-                    const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+                    uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]);
+                    uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]);
+
+                    const uint8x16_t src8 = vreinterpretq_u8_u32(src32);
+                    const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32);
 
                     const uint8x8_t src8_low = vget_low_u8(src8);
@@ -227,17 +227,17 @@
                     const uint8x8_t dst8_high = vget_high_u8(dst8);
 
-                    const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
-                    const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
-
-                    const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
-                    const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
-
-                    const int16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half);
-                    const int16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half);
-
-                    const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
-                    const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
-
-                    vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+                    const uint16x8_t src16_low = vmovl_u8(src8_low);
+                    const uint16x8_t dst16_low = vmovl_u8(dst8_low);
+
+                    const uint16x8_t src16_high = vmovl_u8(src8_high);
+                    const uint16x8_t dst16_high = vmovl_u8(dst8_high);
+
+                    const uint16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half);
+                    const uint16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half);
+
+                    const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low));
+                    const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high));
+
+                    vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high));
                 }
                 for (; x<w; ++x) {
Index: trunk/src/gui/painting/qdrawhelper_p.h
===================================================================
--- trunk/src/gui/painting/qdrawhelper_p.h	(revision 766)
+++ trunk/src/gui/painting/qdrawhelper_p.h	(revision 769)
@@ -1550,4 +1550,7 @@
 inline void qt_memfill(T *dest, T value, int count)
 {
+    if (!count)
+        return;
+
     int n = (count + 7) / 8;
     switch (count & 0x07)
Index: trunk/src/gui/painting/qdrawhelper_sse2.cpp
===================================================================
--- trunk/src/gui/painting/qdrawhelper_sse2.cpp	(revision 766)
+++ trunk/src/gui/painting/qdrawhelper_sse2.cpp	(revision 769)
@@ -57,4 +57,215 @@
 
 QT_BEGIN_NAMESPACE
+
+/*
+ * Multiply the components of pixelVector by alphaChannel
+ * Each 32bits components of alphaChannel must be in the form 0x00AA00AA
+ * colorMask must have 0x00ff00ff on each 32 bits component
+ * half must have the value 128 (0x80) for each 32 bits compnent
+ */
+#define BYTE_MUL_SSE2(result, pixelVector, alphaChannel, colorMask, half) \
+{ \
+    /* 1. separate the colors in 2 vectors so each color is on 16 bits \
+       (in order to be multiplied by the alpha \
+       each 32 bit of dstVectorAG are in the form 0x00AA00GG \
+       each 32 bit of dstVectorRB are in the form 0x00RR00BB */\
+    __m128i pixelVectorAG = _mm_srli_epi16(pixelVector, 8); \
+    __m128i pixelVectorRB = _mm_and_si128(pixelVector, colorMask); \
+ \
+    /* 2. multiply the vectors by the alpha channel */\
+    pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); \
+    pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); \
+ \
+    /* 3. devide by 255, that's the tricky part. \
+       we do it like for BYTE_MUL(), with bit shift: X/255 ~= (X + X/256 + rounding)/256 */ \
+    /** so first (X + X/256 + rounding) */\
+    pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); \
+    pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); \
+    pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); \
+    pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); \
+ \
+    /** second devide by 256 */\
+    pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); \
+    /** for AG, we could >> 8 to divide followed by << 8 to put the \
+        bytes in the correct position. By masking instead, we execute \
+        only one instruction */\
+    pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); \
+ \
+    /* 4. combine the 2 pairs of colors */ \
+    result = _mm_or_si128(pixelVectorAG, pixelVectorRB); \
+}
+
+/*
+ * Each 32bits components of alphaChannel must be in the form 0x00AA00AA
+ * oneMinusAlphaChannel must be 255 - alpha for each 32 bits component
+ * colorMask must have 0x00ff00ff on each 32 bits component
+ * half must have the value 128 (0x80) for each 32 bits compnent
+ */
+#define INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, alphaChannel, oneMinusAlphaChannel, colorMask, half) { \
+    /* interpolate AG */\
+    __m128i srcVectorAG = _mm_srli_epi16(srcVector, 8); \
+    __m128i dstVectorAG = _mm_srli_epi16(dstVector, 8); \
+    __m128i srcVectorAGalpha = _mm_mullo_epi16(srcVectorAG, alphaChannel); \
+    __m128i dstVectorAGoneMinusAlphalpha = _mm_mullo_epi16(dstVectorAG, oneMinusAlphaChannel); \
+    __m128i finalAG = _mm_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlphalpha); \
+    finalAG = _mm_add_epi16(finalAG, _mm_srli_epi16(finalAG, 8)); \
+    finalAG = _mm_add_epi16(finalAG, half); \
+    finalAG = _mm_andnot_si128(colorMask, finalAG); \
+ \
+    /* interpolate RB */\
+    __m128i srcVectorRB = _mm_and_si128(srcVector, colorMask); \
+    __m128i dstVectorRB = _mm_and_si128(dstVector, colorMask); \
+    __m128i srcVectorRBalpha = _mm_mullo_epi16(srcVectorRB, alphaChannel); \
+    __m128i dstVectorRBoneMinusAlphalpha = _mm_mullo_epi16(dstVectorRB, oneMinusAlphaChannel); \
+    __m128i finalRB = _mm_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlphalpha); \
+    finalRB = _mm_add_epi16(finalRB, _mm_srli_epi16(finalRB, 8)); \
+    finalRB = _mm_add_epi16(finalRB, half); \
+    finalRB = _mm_srli_epi16(finalRB, 8); \
+ \
+    /* combine */\
+    result = _mm_or_si128(finalAG, finalRB); \
+}
+
+void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+                                    const uchar *srcPixels, int sbpl,
+                                    int w, int h,
+                                    int const_alpha)
+{
+    const quint32 *src = (const quint32 *) srcPixels;
+    quint32 *dst = (uint *) destPixels;
+    if (const_alpha == 256) {
+        const __m128i alphaMask = _mm_set1_epi32(0xff000000);
+        const __m128i nullVector = _mm_set1_epi32(0);
+        const __m128i half = _mm_set1_epi16(0x80);
+        const __m128i one = _mm_set1_epi16(0xff);
+        const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+        for (int y = 0; y < h; ++y) {
+            int x = 0;
+            for (; x < w-3; x += 4) {
+                const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+                const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask);
+                if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) {
+                    // all opaque
+                    _mm_storeu_si128((__m128i *)&dst[x], srcVector);
+                } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) {
+                    // not fully transparent
+                    // result = s + d * (1-alpha)
+
+                    // extract the alpha channel on 2 x 16 bits
+                    // so we have room for the multiplication
+                    // each 32 bits will be in the form 0x00AA00AA
+                    // with A being the 1 - alpha
+                    __m128i alphaChannel = _mm_srli_epi32(srcVector, 24);
+                    alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16));
+                    alphaChannel = _mm_sub_epi16(one, alphaChannel);
+
+                    const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]);
+                    __m128i destMultipliedByOneMinusAlpha;
+                    BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half);
+
+                    // result = s + d * (1-alpha)
+                    const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha);
+                    _mm_storeu_si128((__m128i *)&dst[x], result);
+                }
+            }
+            for (; x<w; ++x) {
+                uint s = src[x];
+                if (s >= 0xff000000)
+                    dst[x] = s;
+                else if (s != 0)
+                    dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+            }
+            dst = (quint32 *)(((uchar *) dst) + dbpl);
+            src = (const quint32 *)(((const uchar *) src) + sbpl);
+        }
+    } else if (const_alpha != 0) {
+        // dest = (s + d * sia) * ca + d * cia
+        //      = s * ca + d * (sia * ca + cia)
+        //      = s * ca + d * (1 - sa*ca)
+        const_alpha = (const_alpha * 255) >> 8;
+        const __m128i nullVector = _mm_set1_epi32(0);
+        const __m128i half = _mm_set1_epi16(0x80);
+        const __m128i one = _mm_set1_epi16(0xff);
+        const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+        const __m128i constAlphaVector = _mm_set1_epi16(const_alpha);
+        for (int y = 0; y < h; ++y) {
+            int x = 0;
+            for (; x < w-3; x += 4) {
+                __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+                if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) {
+                    BYTE_MUL_SSE2(srcVector, srcVector, constAlphaVector, colorMask, half);
+
+                    __m128i alphaChannel = _mm_srli_epi32(srcVector, 24);
+                    alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16));
+                    alphaChannel = _mm_sub_epi16(one, alphaChannel);
+
+                    const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]);
+                    __m128i destMultipliedByOneMinusAlpha;
+                    BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half);
+
+                    const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha);
+                    _mm_storeu_si128((__m128i *)&dst[x], result);
+                }
+            }
+            for (; x<w; ++x) {
+                quint32 s = src[x];
+                if (s != 0) {
+                    s = BYTE_MUL(s, const_alpha);
+                    dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+                }
+            }
+            dst = (quint32 *)(((uchar *) dst) + dbpl);
+            src = (const quint32 *)(((const uchar *) src) + sbpl);
+        }
+    }
+}
+
+// qblendfunctions.cpp
+void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
+                             const uchar *srcPixels, int sbpl,
+                             int w, int h,
+                             int const_alpha);
+
+void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
+                                 const uchar *srcPixels, int sbpl,
+                                 int w, int h,
+                                 int const_alpha)
+{
+    const quint32 *src = (const quint32 *) srcPixels;
+    quint32 *dst = (uint *) destPixels;
+    if (const_alpha != 256) {
+        if (const_alpha != 0) {
+            const __m128i nullVector = _mm_set1_epi32(0);
+            const __m128i half = _mm_set1_epi16(0x80);
+            const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+
+            const_alpha = (const_alpha * 255) >> 8;
+            int one_minus_const_alpha = 255 - const_alpha;
+            const __m128i constAlphaVector = _mm_set1_epi16(const_alpha);
+            const __m128i oneMinusConstAlpha =  _mm_set1_epi16(one_minus_const_alpha);
+            for (int y = 0; y < h; ++y) {
+                int x = 0;
+                for (; x < w-3; x += 4) {
+                    __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+                    if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) {
+                        const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]);
+                        __m128i result;
+                        INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half);
+                        _mm_storeu_si128((__m128i *)&dst[x], result);
+                    }
+                }
+                for (; x<w; ++x) {
+                    quint32 s = src[x];
+                    s = BYTE_MUL(s, const_alpha);
+                    dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
+                }
+                dst = (quint32 *)(((uchar *) dst) + dbpl);
+                src = (const quint32 *)(((const uchar *) src) + sbpl);
+            }
+        }
+    } else {
+        qt_blend_rgb32_on_rgb32(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+    }
+}
 
 void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
Index: trunk/src/gui/painting/qdrawhelper_x86_p.h
===================================================================
--- trunk/src/gui/painting/qdrawhelper_x86_p.h	(revision 766)
+++ trunk/src/gui/painting/qdrawhelper_x86_p.h	(revision 769)
@@ -115,4 +115,12 @@
                           quint32 color,
                           const uchar *src, int width, int height, int stride);
+void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+                                    const uchar *srcPixels, int sbpl,
+                                    int w, int h,
+                                    int const_alpha);
+void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
+                                 const uchar *srcPixels, int sbpl,
+                                 int w, int h,
+                                 int const_alpha);
 #endif // QT_HAVE_SSE2
 
Index: trunk/src/gui/painting/qdrawutil.cpp
===================================================================
--- trunk/src/gui/painting/qdrawutil.cpp	(revision 766)
+++ trunk/src/gui/painting/qdrawutil.cpp	(revision 769)
@@ -1362,12 +1362,19 @@
         for (int i = 0; i < dataCount; ++i) {
             QTransform transform = oldTransform;
-            transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
-            transform.rotate(drawingData[i].rotation);
+            qreal xOffset = 0;
+            qreal yOffset = 0;
+            if (drawingData[i].rotation == 0) {
+                xOffset = drawingData[i].point.x();
+                yOffset = drawingData[i].point.y();
+            } else {
+                transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
+                transform.rotate(drawingData[i].rotation);
+            }
+            painter->setTransform(transform);
             painter->setOpacity(oldOpacity * drawingData[i].opacity);
-            painter->setTransform(transform);
 
             qreal w = drawingData[i].scaleX * drawingData[i].source.width();
             qreal h = drawingData[i].scaleY * drawingData[i].source.height();
-            painter->drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source);
+            painter->drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, drawingData[i].source);
         }
 
Index: trunk/src/gui/painting/qgraphicssystem_raster.cpp
===================================================================
--- trunk/src/gui/painting/qgraphicssystem_raster.cpp	(revision 766)
+++ trunk/src/gui/painting/qgraphicssystem_raster.cpp	(revision 769)
@@ -42,6 +42,11 @@
 #include "qgraphicssystem_raster_p.h"
 
+#ifdef Q_OS_SYMBIAN
+#include "private/qpixmap_s60_p.h"
+#include "private/qwindowsurface_s60_p.h"
+#else
 #include "private/qpixmap_raster_p.h"
 #include "private/qwindowsurface_raster_p.h"
+#endif
 
 QT_BEGIN_NAMESPACE
@@ -49,10 +54,18 @@
 QPixmapData *QRasterGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
 {
+#ifdef Q_OS_SYMBIAN
+    return new QS60PixmapData(type);
+#else
     return new QRasterPixmapData(type);
+#endif
 }
 
 QWindowSurface *QRasterGraphicsSystem::createWindowSurface(QWidget *widget) const
 {
+#ifdef Q_OS_SYMBIAN
+    return new QS60WindowSurface(widget);
+#else
     return new QRasterWindowSurface(widget);
+#endif
 }
 
Index: trunk/src/gui/painting/qmath_p.h
===================================================================
--- trunk/src/gui/painting/qmath_p.h	(revision 766)
+++ trunk/src/gui/painting/qmath_p.h	(revision 769)
@@ -55,4 +55,5 @@
 
 #include <math.h>
+#include <qmath.h>
 
 QT_BEGIN_NAMESPACE
@@ -62,4 +63,9 @@
 static const qreal Q_PI2  = qreal(1.57079632679489661923);   // pi/2
 
+inline int qIntSqrtInt(int v)
+{
+    return static_cast<int>(qSqrt(static_cast<qreal>(v)));
+}
+
 QT_END_NAMESPACE
 
Index: trunk/src/gui/painting/qpaintbuffer.cpp
===================================================================
--- trunk/src/gui/painting/qpaintbuffer.cpp	(revision 766)
+++ trunk/src/gui/painting/qpaintbuffer.cpp	(revision 769)
@@ -53,6 +53,6 @@
 QT_BEGIN_NAMESPACE
 
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_GUI_EXPORT extern int qt_defaultDpiX();
+Q_GUI_EXPORT extern int qt_defaultDpiY();
 extern void qt_format_text(const QFont &font,
                            const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect,
Index: trunk/src/gui/painting/qpaintengine_alpha.cpp
===================================================================
--- trunk/src/gui/painting/qpaintengine_alpha.cpp	(revision 766)
+++ trunk/src/gui/painting/qpaintengine_alpha.cpp	(revision 769)
@@ -94,6 +94,6 @@
 }
 
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_GUI_EXPORT extern int qt_defaultDpiX();
+Q_GUI_EXPORT extern int qt_defaultDpiY();
 
 bool QAlphaPaintEngine::end()
Index: trunk/src/gui/painting/qpaintengine_raster.cpp
===================================================================
--- trunk/src/gui/painting/qpaintengine_raster.cpp	(revision 766)
+++ trunk/src/gui/painting/qpaintengine_raster.cpp	(revision 769)
@@ -101,11 +101,7 @@
 #include <limits.h>
 
-#if defined(QT_NO_FPU) || (_MSC_VER >= 1300 && _MSC_VER < 1400)
-#  define FLOATING_POINT_BUGGY_OR_NO_FPU
-#endif
-
 QT_BEGIN_NAMESPACE
 
-extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
 
 #define qreal_to_fixed_26_6(f) (int(f * 64))
@@ -3680,7 +3676,4 @@
          || (qpen_style(s->lastPen) == Qt::NoPen && !s->flags.antialiased))
         && qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT
-#ifdef FLOATING_POINT_BUGGY_OR_NO_FPU
-        && qMax(rect.width(), rect.height()) < 128 // integer math breakdown
-#endif
         && s->matrix.type() <= QTransform::TxScale) // no shear
     {
@@ -4985,5 +4978,5 @@
 }
 
-extern QImage qt_imageForBrush(int brushStyle, bool invert);
+Q_GUI_EXPORT extern QImage qt_imageForBrush(int brushStyle, bool invert);
 
 void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode)
@@ -6055,13 +6048,7 @@
                                    QSpanData *pen_data, QSpanData *brush_data)
 {
-#ifdef FLOATING_POINT_BUGGY_OR_NO_FPU // no fpu, so use fixed point
-    const QFixed a = QFixed(rect.width()) >> 1;
-    const QFixed b = QFixed(rect.height()) >> 1;
-    QFixed d = b*b - (a*a*b) + ((a*a) >> 2);
-#else
     const qreal a = qreal(rect.width()) / 2;
     const qreal b = qreal(rect.height()) / 2;
     qreal d = b*b - (a*a*b) + 0.25*a*a;
-#endif
 
     int x = 0;
@@ -6086,10 +6073,5 @@
 
     // region 2
-#ifdef FLOATING_POINT_BUGGY_OR_NO_FPU
-    d = b*b*(x + (QFixed(1) >> 1))*(x + (QFixed(1) >> 1))
-        + a*a*((y - 1)*(y - 1) - b*b);
-#else
     d = b*b*(x + 0.5)*(x + 0.5) + a*a*((y - 1)*(y - 1) - b*b);
-#endif
     const int miny = rect.height() & 0x1;
     while (y > miny) {
Index: trunk/src/gui/painting/qpaintengine_x11.cpp
===================================================================
--- trunk/src/gui/painting/qpaintengine_x11.cpp	(revision 766)
+++ trunk/src/gui/painting/qpaintengine_x11.cpp	(revision 769)
@@ -1990,4 +1990,7 @@
         XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);
         restore_clip = true;
+    } else if (mono_dst && !mono_src) {
+        QBitmap bitmap(pixmap);
+        XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
     } else {
         XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
Index: trunk/src/gui/painting/qpaintengineex.cpp
===================================================================
--- trunk/src/gui/painting/qpaintengineex.cpp	(revision 766)
+++ trunk/src/gui/painting/qpaintengineex.cpp	(revision 769)
@@ -381,5 +381,5 @@
 }
 
-extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
 
 void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
Index: trunk/src/gui/painting/qpainter.cpp
===================================================================
--- trunk/src/gui/painting/qpainter.cpp	(revision 766)
+++ trunk/src/gui/painting/qpainter.cpp	(revision 769)
@@ -709,11 +709,12 @@
         if (penBrush.style() == Qt::TexturePattern)
             penTextureAlpha = qHasPixmapTexture(penBrush)
-                              ? penBrush.texture().hasAlpha()
+                              ? (penBrush.texture().depth() > 1) && penBrush.texture().hasAlpha()
                               : penBrush.textureImage().hasAlphaChannel();
         bool brushTextureAlpha = false;
-        if (s->brush.style() == Qt::TexturePattern)
+        if (s->brush.style() == Qt::TexturePattern) {
             brushTextureAlpha = qHasPixmapTexture(s->brush)
-                                ? s->brush.texture().hasAlpha()
+                                ? (s->brush.texture().depth() > 1) && s->brush.texture().hasAlpha()
                                 : s->brush.textureImage().hasAlphaChannel();
+        }
         if (((penBrush.style() == Qt::TexturePattern && penTextureAlpha)
              || (s->brush.style() == Qt::TexturePattern && brushTextureAlpha))
@@ -1987,10 +1988,23 @@
 
     Note that only the states the underlying paint engine changes will be reset
-    to their respective default states. If, for example, the OpenGL polygon
-    mode is changed by the user inside a beginNativePaint()/endNativePainting()
-    block, it will not be reset to the default state by endNativePainting().
-
-    Here is an example that shows intermixing of painter commands
-    and raw OpenGL commands:
+    to their respective default states. The states we reset may change from
+    release to release. The following states are currently reset in the OpenGL
+    2 engine:
+
+    \list
+    \i blending is disabled
+    \i the depth, stencil and scissor tests are disabled
+    \i the active texture unit is reset to 0
+    \i the depth mask, depth function and the clear depth are reset to their
+    default values
+    \i the stencil mask, stencil operation and stencil function are reset to
+    their default values
+     \i the current color is reset to solid white
+    \endlist
+
+    If, for example, the OpenGL polygon mode is changed by the user inside a
+    beginNativePaint()/endNativePainting() block, it will not be reset to the
+    default state by endNativePainting(). Here is an example that shows
+    intermixing of painter commands and raw OpenGL commands:
 
     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21
@@ -5760,10 +5774,15 @@
         gf.chars = engine.layoutData->string.unicode() + si.position;
         gf.num_chars = engine.length(item);
-        gf.width = si.width;
+        if (engine.forceJustification) {
+            for (int j=0; j<gf.glyphs.numGlyphs; ++j)
+                gf.width += gf.glyphs.effectiveAdvance(j);
+        } else {
+            gf.width = si.width;
+        }
         gf.logClusters = engine.logClusters(&si);
 
         drawTextItem(QPointF(x.toReal(), p.y()), gf);
 
-        x += si.width;
+        x += gf.width;
     }
 }
@@ -7788,8 +7807,9 @@
             QTextLine line = textLayout.lineAt(i);
 
+            qreal advance = textLayout.engine()->lines[i].textAdvance.toReal();
             if (tf & Qt::AlignRight)
-                xoff = r.width() - line.naturalTextWidth();
+                xoff = r.width() - advance;
             else if (tf & Qt::AlignHCenter)
-                xoff = (r.width() - line.naturalTextWidth())/2;
+                xoff = (r.width() - advance)/2;
 
             line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff));
Index: trunk/src/gui/painting/qpathclipper.cpp
===================================================================
--- trunk/src/gui/painting/qpathclipper.cpp	(revision 766)
+++ trunk/src/gui/painting/qpathclipper.cpp	(revision 769)
@@ -1692,5 +1692,5 @@
 
     if (rect)
-        *rect = QRectF(QPointF(x1, y1), QPointF(x2, y2));
+        rect->setCoords(x1, y1, x2, y2);
 
     return true;
Index: trunk/src/gui/painting/qpdf.cpp
===================================================================
--- trunk/src/gui/painting/qpdf.cpp	(revision 766)
+++ trunk/src/gui/painting/qpdf.cpp	(revision 769)
@@ -55,5 +55,5 @@
 QT_BEGIN_NAMESPACE
 
-extern int qt_defaultDpi();
+Q_GUI_EXPORT extern int qt_defaultDpi();
 
 #ifndef QT_NO_PRINTER
@@ -972,4 +972,5 @@
         return;
 
+    Q_D(QPdfBaseEngine);
     QPainterPath p;
     for (int i=0; i!=pointCount;++i) {
@@ -977,5 +978,9 @@
         p.lineTo(points[i] + QPointF(0, 0.001));
     }
+
+    bool hadBrush = d->hasBrush;
+    d->hasBrush = false;
     drawPath(p);
+    d->hasBrush = hadBrush;
 }
 
@@ -985,4 +990,5 @@
         return;
 
+    Q_D(QPdfBaseEngine);
     QPainterPath p;
     for (int i=0; i!=lineCount;++i) {
@@ -990,5 +996,8 @@
         p.lineTo(lines[i].p2());
     }
+    bool hadBrush = d->hasBrush;
+    d->hasBrush = false;
     drawPath(p);
+    d->hasBrush = hadBrush;
 }
 
Index: trunk/src/gui/painting/qprintengine_ps.cpp
===================================================================
--- trunk/src/gui/painting/qprintengine_ps.cpp	(revision 766)
+++ trunk/src/gui/painting/qprintengine_ps.cpp	(revision 769)
@@ -486,5 +486,4 @@
     QByteArray header;
     QPdf::ByteStream s(&header);
-    s << "%!PS-Adobe-1.0";
 
     qreal scale = 72. / ((qreal) q->metric(QPaintDevice::PdmDpiY));
@@ -498,6 +497,9 @@
     int height = pageRect.height();
     if (finished && pageCount == 1 && copies == 1 &&
-        ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps"))))
-       ) {
+        ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps")))))
+    {
+        // According to the EPSF 3.0 spec it is required that the PS
+        // version is PS-Adobe-3.0
+        s << "%!PS-Adobe-3.0";
         if (!boundingBox.isValid())
             boundingBox.setRect(0, 0, width, height);
@@ -506,18 +508,19 @@
                 boundingBox.translate(-mleft, -mtop);
             s << " EPSF-3.0\n%%BoundingBox: "
-              << (int)(printer->height() - boundingBox.bottom())*scale // llx
-              << (int)(printer->width() - boundingBox.right())*scale - 1 // lly
-              << (int)(printer->height() - boundingBox.top())*scale + 1 // urx
-              << (int)(printer->width() - boundingBox.left())*scale; // ury
+              << int((printer->height() - boundingBox.bottom())*scale) // llx
+              << int((printer->width() - boundingBox.right())*scale - 1) // lly
+              << int((printer->height() - boundingBox.top())*scale + 1) // urx
+              << int((printer->width() - boundingBox.left())*scale); // ury
         } else {
             if (!fullPage)
                 boundingBox.translate(mleft, -mtop);
             s << " EPSF-3.0\n%%BoundingBox: "
-              << (int)(boundingBox.left())*scale
-              << (int)(printer->height() - boundingBox.bottom())*scale - 1
-              << (int)(boundingBox.right())*scale + 1
-              << (int)(printer->height() - boundingBox.top())*scale;
+              << int((boundingBox.left())*scale)
+              << int((printer->height() - boundingBox.bottom())*scale - 1)
+              << int((boundingBox.right())*scale + 1)
+              << int((printer->height() - boundingBox.top())*scale);
         }
     } else {
+        s << "%!PS-Adobe-1.0";
         int w = width + (fullPage ? 0 : mleft + mright);
         int h = height + (fullPage ? 0 : mtop + mbottom);
Index: trunk/src/gui/painting/qprintengine_win.cpp
===================================================================
--- trunk/src/gui/painting/qprintengine_win.cpp	(revision 766)
+++ trunk/src/gui/painting/qprintengine_win.cpp	(revision 769)
@@ -965,10 +965,11 @@
 
     QStringList info = output.split(QLatin1Char(','));
-    if (info.size() > 0) {
+    int infoSize = info.size();
+    if (infoSize > 0) {
         if (name.isEmpty())
             name = info.at(0);
-        if (program.isEmpty())
+        if (program.isEmpty() && infoSize > 1)
             program = info.at(1);
-        if (port.isEmpty())
+        if (port.isEmpty() && infoSize > 2)
             port = info.at(2);
     }
Index: trunk/src/gui/painting/qregion.cpp
===================================================================
--- trunk/src/gui/painting/qregion.cpp	(revision 766)
+++ trunk/src/gui/painting/qregion.cpp	(revision 769)
@@ -3146,6 +3146,6 @@
 /* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */
 
-#define LARGE_COORDINATE 1000000
-#define SMALL_COORDINATE -LARGE_COORDINATE
+#define LARGE_COORDINATE INT_MAX
+#define SMALL_COORDINATE INT_MIN
 
 /*
Index: trunk/src/gui/painting/qstroker.cpp
===================================================================
--- trunk/src/gui/painting/qstroker.cpp	(revision 766)
+++ trunk/src/gui/painting/qstroker.cpp	(revision 769)
@@ -826,5 +826,5 @@
 }
 
-void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length,
+Q_GUI_EXPORT void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length,
                             QPointF* startPoint, QPointF *endPoint);
 
Index: trunk/src/gui/painting/qtransform.h
===================================================================
--- trunk/src/gui/painting/qtransform.h	(revision 766)
+++ trunk/src/gui/painting/qtransform.h	(revision 769)
@@ -294,5 +294,6 @@
     affine._dy  *= num;
     m_33        *= num;
-    m_dirty     |= TxScale;
+    if (m_dirty < TxScale)
+        m_dirty = TxScale;
     return *this;
 }
@@ -317,5 +318,5 @@
     affine._dy  += num;
     m_33        += num;
-    m_dirty     |= TxProject;
+    m_dirty     = TxProject;
     return *this;
 }
@@ -333,5 +334,5 @@
     affine._dy  -= num;
     m_33        -= num;
-    m_dirty     |= TxProject;
+    m_dirty     = TxProject;
     return *this;
 }
Index: trunk/src/gui/painting/qwindowsurface_qws.cpp
===================================================================
--- trunk/src/gui/painting/qwindowsurface_qws.cpp	(revision 766)
+++ trunk/src/gui/painting/qwindowsurface_qws.cpp	(revision 769)
@@ -81,5 +81,5 @@
 inline bool isWidgetOpaque(const QWidget *w)
 {
-    return w->d_func()->isOpaque;
+    return w->d_func()->isOpaque && !w->testAttribute(Qt::WA_TranslucentBackground);
 }
 
@@ -874,4 +874,19 @@
 }
 
+// ### copied from qwindowsurface_raster.cpp -- should be cross-platform
+void QWSMemorySurface::beginPaint(const QRegion &rgn)
+{
+    if (!isWidgetOpaque(window())) {
+        QPainter p(&img);
+        p.setCompositionMode(QPainter::CompositionMode_Source);
+        const QVector<QRect> rects = rgn.rects();
+        const QColor blank = Qt::transparent;
+        for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+            p.fillRect(*it, blank);
+        }
+    }
+    QWSWindowSurface::beginPaint(rgn);
+}
+
 // from qwindowsurface.cpp
 extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
Index: trunk/src/gui/painting/qwindowsurface_qws_p.h
===================================================================
--- trunk/src/gui/painting/qwindowsurface_qws_p.h	(revision 766)
+++ trunk/src/gui/painting/qwindowsurface_qws_p.h	(revision 769)
@@ -177,4 +177,6 @@
     QPoint painterOffset() const;
 
+    void beginPaint(const QRegion &rgn);
+
     bool lock(int timeout = -1);
     void unlock();
Index: trunk/src/gui/painting/qwindowsurface_raster.cpp
===================================================================
--- trunk/src/gui/painting/qwindowsurface_raster.cpp	(revision 766)
+++ trunk/src/gui/painting/qwindowsurface_raster.cpp	(revision 769)
@@ -560,8 +560,6 @@
 #ifndef QT_MAC_USE_COCOA
     QDEndCGContext(port, &context);
-#else
-    CGContextFlush(context);
-#endif
-#endif
+#endif
+#endif // Q_WS_MAC
 
 #ifdef Q_OS_SYMBIAN
Index: trunk/src/gui/painting/qwindowsurface_s60.cpp
===================================================================
--- trunk/src/gui/painting/qwindowsurface_s60.cpp	(revision 766)
+++ trunk/src/gui/painting/qwindowsurface_s60.cpp	(revision 769)
@@ -71,5 +71,5 @@
     CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);	// CBase derived object needs check on new
     qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
-	
+
     QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
     if (data) {
@@ -77,5 +77,5 @@
         d_ptr->device = QPixmap(data);
     }
-        
+
     setStaticContentsSupport(true);
 }
@@ -90,22 +90,13 @@
         QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
         pixmapData->beginDataAccess();
-        QImage &image = pixmapData->image;
-        QRgb *data = reinterpret_cast<QRgb *>(image.bits());
-        const int row_stride = image.bytesPerLine() / 4;
 
+        QPainter p(&pixmapData->image);
+        p.setCompositionMode(QPainter::CompositionMode_Source);
         const QVector<QRect> rects = rgn.rects();
+        const QColor blank = Qt::transparent;
         for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
-            const int x_start = it->x();
-            const int width = it->width();
+            p.fillRect(*it, blank);
+        }
 
-            const int y_start = it->y();
-            const int height = it->height();
-
-            QRgb *row = data + row_stride * y_start;
-            for (int y = 0; y < height; ++y) {
-                qt_memfill(row + x_start, 0U, width);
-                row += row_stride;
-            }
-        }
         pixmapData->endDataAccess();
     }
@@ -129,5 +120,5 @@
     const QPoint off = offset(widget);
     QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image);
-    
+
     QRect rect(off, widget->size());
     rect &= QRect(QPoint(), img->size());
@@ -150,9 +141,17 @@
     QTLWExtra *topExtra = window->d_func()->maybeTopData();
     Q_ASSERT(topExtra);
+    QRect qr = region.boundingRect();
     if (!topExtra->inExpose) {
         topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
-        TRect tr = qt_QRect2TRect(region.boundingRect());
+        TRect tr = qt_QRect2TRect(qr);
         widget->winId()->DrawNow(tr);
         topExtra->inExpose = false;
+    } else {
+        // This handles the case when syncBackingStore updates content outside of the
+        // original drawing rectangle. This might happen if there are pending update()
+        // events at the same time as we get a Draw() from Symbian.
+        QRect drawRect = qt_TRect2QRect(widget->winId()->DrawableWindow()->GetDrawRect());
+        if (!drawRect.contains(qr))
+            widget->winId()->DrawDeferred();
     }
 }
Index: trunk/src/gui/s60framework/qs60mainapplication.cpp
===================================================================
--- trunk/src/gui/s60framework/qs60mainapplication.cpp	(revision 766)
+++ trunk/src/gui/s60framework/qs60mainapplication.cpp	(revision 769)
@@ -42,4 +42,5 @@
 // INCLUDE FILES
 #include <exception>
+#include <private/qcore_symbian_p.h>
 #include "qs60maindocument.h"
 #include "qs60mainapplication_p.h"
@@ -58,5 +59,5 @@
 }
 
-_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc");
+_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main" QT_LIBINFIX_UNICODE L".rsc");
 
 /*!
@@ -64,9 +65,9 @@
   \since 4.6
   \brief The QS60MainApplication class provides support for migration from S60.
- 
+
   \warning This class is provided only to get access to S60 specific
   functionality in the application framework classes. It is not
   portable. We strongly recommend against using it in new applications.
- 
+
   The QS60MainApplication provides a helper class for use in migrating
   from existing S60 based applications to Qt based applications. It is
Index: trunk/src/gui/s60framework/qs60mainappui.cpp
===================================================================
--- trunk/src/gui/s60framework/qs60mainappui.cpp	(revision 766)
+++ trunk/src/gui/s60framework/qs60mainappui.cpp	(revision 769)
@@ -46,5 +46,13 @@
 #include <eikmenup.h>
 #include <barsread.h>
-#include <s60main.rsg>
+#include <qconfig.h>
+#if defined(QT_LIBINFIX_UNQUOTED)
+// Two level macro needed for proper expansion of libinfix
+#  define QT_S60MAIN_RSG_2(x) <s60main##x##.rsg>
+#  define QT_S60MAIN_RSG(x) QT_S60MAIN_RSG_2(x)
+#  include QT_S60MAIN_RSG(QT_LIBINFIX_UNQUOTED)
+#else
+#  include <s60main.rsg>
+#endif
 #include <avkon.rsg>
 
@@ -57,4 +65,7 @@
 #include <qdebug.h>
 
+//Animated wallpapers in Qt applications are not supported.
+const TInt KAknDisableAnimationBackground = 0x02000000;
+
 QT_BEGIN_NAMESPACE
 
@@ -105,14 +116,13 @@
     // resource files in most SDKs. S60 3rd FP1 public seems to require resource file
     // even these flags are defined
-    TInt flags = CAknAppUi::EAknEnableSkin;
-    if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) {
-        flags |= CAknAppUi::ENoScreenFurniture | CAknAppUi::ENonStandardResourceFile;
-    }
+    TInt flags = CAknAppUi::EAknEnableSkin
+                 | CAknAppUi::ENoScreenFurniture
+                 | CAknAppUi::ENonStandardResourceFile;
+    // After 5th Edition S60, native side supports animated wallpapers.
+	// However, there is no support for that feature on Qt side, so indicate to
+	// native UI framework that this application will not support background animations.
+    if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
+        flags |= KAknDisableAnimationBackground;
     BaseConstructL(flags);
-
-    if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) {
-        CEikButtonGroupContainer* nativeContainer = Cba();
-        nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
-    }
 }
 
Index: trunk/src/gui/s60framework/qs60maindocument.h
===================================================================
--- trunk/src/gui/s60framework/qs60maindocument.h	(revision 766)
+++ trunk/src/gui/s60framework/qs60maindocument.h	(revision 769)
@@ -47,5 +47,5 @@
 #ifdef Q_WS_S60
 
-#include <akndoc.h>
+#include <AknDoc.h>
 
 class CEikApplication;
Index: trunk/src/gui/s60framework/s60framework.pri
===================================================================
--- trunk/src/gui/s60framework/s60framework.pri	(revision 766)
+++ trunk/src/gui/s60framework/s60framework.pri	(revision 769)
@@ -5,6 +5,7 @@
     "SOURCEPATH s60framework" \
     "START RESOURCE s60main.rss" \
+    "TARGET s60main$${QT_LIBINFIX}" \
     "HEADER" \
-    "TARGETPATH resource\apps" \
+    "TARGETPATH /resource/apps" \
     "END"
 MMP_RULES += minimalAppResource31
@@ -18,2 +19,4 @@
            s60framework/qs60mainappui.h \
            s60framework/qs60maindocument.h
+
+!isEmpty(QT_LIBINFIX): DEFINES += QT_LIBINFIX_UNQUOTED=$$QT_LIBINFIX
Index: trunk/src/gui/styles/qcommonstyle.cpp
===================================================================
--- trunk/src/gui/styles/qcommonstyle.cpp	(revision 766)
+++ trunk/src/gui/styles/qcommonstyle.cpp	(revision 769)
@@ -1154,8 +1154,8 @@
     if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
         verticalShift = -verticalShift;
-    tr.adjust(hpadding, vpadding, horizontalShift - hpadding, verticalShift - vpadding);
+    tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);
     bool selected = opt->state & QStyle::State_Selected;
     if (selected) {
-        tr.setBottom(tr.bottom() - verticalShift);
+        tr.setTop(tr.top() - verticalShift);
         tr.setRight(tr.right() - horizontalShift);
     }
@@ -1613,5 +1613,5 @@
                     if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
                         pr.setHeight(pmSize.height() + 6);
-                        tr.adjust(0, pr.height() - 1, 0, -3);
+                        tr.adjust(0, pr.height() - 1, 0, -2);
                         pr.translate(shiftX, shiftY);
                         if (!hasArrow) {
Index: trunk/src/gui/styles/qgtkstyle.cpp
===================================================================
--- trunk/src/gui/styles/qgtkstyle.cpp	(revision 766)
+++ trunk/src/gui/styles/qgtkstyle.cpp	(revision 769)
@@ -3399,4 +3399,7 @@
 
     QRect r = QCleanlooksStyle::subElementRect(element, option, widget);
+    if (!d->isThemeAvailable())
+        return r;
+
     switch (element) {
     case SE_ProgressBarLabel:
Index: trunk/src/gui/styles/qgtkstyle_p.cpp
===================================================================
--- trunk/src/gui/styles/qgtkstyle_p.cpp	(revision 766)
+++ trunk/src/gui/styles/qgtkstyle_p.cpp	(revision 769)
@@ -92,6 +92,6 @@
 Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_bg = 0;
 Ptr_gtk_arrow_new QGtkStylePrivate::gtk_arrow_new = 0;
-Ptr_gtk_menu_item_new QGtkStylePrivate::gtk_menu_item_new = 0;
-Ptr_gtk_check_menu_item_new QGtkStylePrivate::gtk_check_menu_item_new = 0;
+Ptr_gtk_menu_item_new_with_label QGtkStylePrivate::gtk_menu_item_new_with_label = 0;
+Ptr_gtk_check_menu_item_new_with_label QGtkStylePrivate::gtk_check_menu_item_new_with_label = 0;
 Ptr_gtk_menu_bar_new QGtkStylePrivate::gtk_menu_bar_new = 0;
 Ptr_gtk_menu_new QGtkStylePrivate::gtk_menu_new = 0;
@@ -348,6 +348,6 @@
     gtk_widget_modify_bg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_bg");
     gtk_arrow_new = (Ptr_gtk_arrow_new)libgtk.resolve("gtk_arrow_new");
-    gtk_menu_item_new = (Ptr_gtk_menu_item_new)libgtk.resolve("gtk_menu_item_new");
-    gtk_check_menu_item_new = (Ptr_gtk_check_menu_item_new)libgtk.resolve("gtk_check_menu_item_new");
+    gtk_menu_item_new_with_label = (Ptr_gtk_menu_item_new_with_label)libgtk.resolve("gtk_menu_item_new_with_label");
+    gtk_check_menu_item_new_with_label = (Ptr_gtk_check_menu_item_new_with_label)libgtk.resolve("gtk_check_menu_item_new_with_label");
     gtk_menu_bar_new = (Ptr_gtk_menu_bar_new)libgtk.resolve("gtk_menu_bar_new");
     gtk_menu_new = (Ptr_gtk_menu_new)libgtk.resolve("gtk_menu_new");
@@ -440,5 +440,5 @@
     setupGtkWidget(gtkMenuBar);
 
-    GtkWidget *gtkMenuBarItem = QGtkStylePrivate::gtk_menu_item_new();
+    GtkWidget *gtkMenuBarItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
     gtk_menu_shell_append((GtkMenuShell*)(gtkMenuBar), gtkMenuBarItem);
     gtk_widget_realize(gtkMenuBarItem);
@@ -449,12 +449,9 @@
     gtk_widget_realize(gtkMenu);
 
-    GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new();
-    g_object_set(gtkMenuItem, "label", "X", NULL);
-
+    GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
     gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
     gtk_widget_realize(gtkMenuItem);
 
-    GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new();
-    g_object_set(gtkCheckMenuItem, "label", "X", NULL);
+    GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new_with_label("X");
     gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem);
     gtk_widget_realize(gtkCheckMenuItem);
@@ -534,5 +531,5 @@
             addWidget(gtkButton);
             g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0);
-            addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, NULL));
+            addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, "Qt"));
             addWidget(QGtkStylePrivate::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
             addWidget(QGtkStylePrivate::gtk_hbutton_box_new());
Index: trunk/src/gui/styles/qgtkstyle_p.h
===================================================================
--- trunk/src/gui/styles/qgtkstyle_p.h	(revision 766)
+++ trunk/src/gui/styles/qgtkstyle_p.h	(revision 769)
@@ -88,7 +88,7 @@
 typedef void (*Ptr_gtk_widget_modify_color)(GtkWidget *widget, GtkStateType state, const GdkColor *color);
 typedef GtkWidget* (*Ptr_gtk_arrow_new)(GtkArrowType, GtkShadowType);
-typedef GtkWidget* (*Ptr_gtk_menu_item_new)(void);
+typedef GtkWidget* (*Ptr_gtk_menu_item_new_with_label)(const gchar *);
 typedef GtkWidget* (*Ptr_gtk_separator_menu_item_new)(void);
-typedef GtkWidget* (*Ptr_gtk_check_menu_item_new)(void);
+typedef GtkWidget* (*Ptr_gtk_check_menu_item_new_with_label)(const gchar *);
 typedef GtkWidget* (*Ptr_gtk_menu_bar_new)(void);
 typedef GtkWidget* (*Ptr_gtk_menu_new)(void);
@@ -307,7 +307,7 @@
     static Ptr_gtk_widget_modify_color gtk_widget_modify_fg;
     static Ptr_gtk_widget_modify_color gtk_widget_modify_bg;
-    static Ptr_gtk_menu_item_new gtk_menu_item_new;
+    static Ptr_gtk_menu_item_new_with_label gtk_menu_item_new_with_label;
     static Ptr_gtk_arrow_new gtk_arrow_new;
-    static Ptr_gtk_check_menu_item_new gtk_check_menu_item_new;
+    static Ptr_gtk_check_menu_item_new_with_label gtk_check_menu_item_new_with_label;
     static Ptr_gtk_menu_bar_new gtk_menu_bar_new;
     static Ptr_gtk_menu_new gtk_menu_new;
Index: trunk/src/gui/styles/qmacstyle_mac.mm
===================================================================
--- trunk/src/gui/styles/qmacstyle_mac.mm	(revision 766)
+++ trunk/src/gui/styles/qmacstyle_mac.mm	(revision 769)
@@ -3381,6 +3381,12 @@
                             needText = true;
                             if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
-                                pr.setHeight(pixmap.size().height());
-                                cr.adjust(0, pr.bottom() + 1, 0, 1);
+                                QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
+                                if (mw && mw->unifiedTitleAndToolBarOnMac()) {
+                                    pr.setHeight(pixmap.size().height());
+                                    cr.adjust(0, pr.bottom() + 1, 0, 1);
+                                } else {
+                                    pr.setHeight(pixmap.size().height() + 6);
+                                    cr.adjust(0, pr.bottom(), 0, -3);
+                                }       
                                 alignment |= Qt::AlignCenter;
                             } else {
@@ -3744,5 +3750,5 @@
                     np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
                     QRect nr = subElementRect(SE_TabBarTabText, opt, w);
-                    nr.moveTop(+1);
+                    nr.moveTop(-1);
                     int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
                     proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
Index: trunk/src/gui/styles/qs60style.cpp
===================================================================
--- trunk/src/gui/styles/qs60style.cpp	(revision 766)
+++ trunk/src/gui/styles/qs60style.cpp	(revision 769)
@@ -51,4 +51,5 @@
 #include "qdial.h"
 #include "qdialog.h"
+#include "qmessagebox.h"
 #include "qgroupbox.h"
 #include "qheaderview.h"
@@ -62,5 +63,4 @@
 #include "qscrollbar.h"
 #include "qtabbar.h"
-#include "qtablewidget.h"
 #include "qtableview.h"
 #include "qtextedit.h"
@@ -93,8 +93,8 @@
 const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
 // *** generated layout data ***
-{240,320,1,15,"QVGA Landscape"},
-{320,240,1,15,"QVGA Portrait"},
-{360,640,1,15,"NHD Landscape"},
-{640,360,1,15,"NHD Portrait"},
+{240,320,1,19,"QVGA Landscape"},
+{320,240,1,19,"QVGA Portrait"},
+{360,640,1,19,"NHD Landscape"},
+{640,360,1,19,"NHD Portrait"},
 {352,800,1,12,"E90 Landscape"}
 // *** End of generated data ***
@@ -105,9 +105,9 @@
 const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
 // *** generated pixel metrics ***
-{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
-{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}
+{5,0,-909,0,0,2,0,0,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106},
+{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106},
+{7,0,-909,0,0,2,0,0,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
+{7,0,-909,0,0,2,0,0,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
+{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106}
 // *** End of generated data ***
 };
@@ -120,4 +120,8 @@
 // theme palette
 QPalette *QS60StylePrivate::m_themePalette = 0;
+
+qint64 QS60StylePrivate::m_webPaletteKey = 0;
+
+QPointer<QWidget> QS60StylePrivate::m_pressedWidget = 0;
 
 const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = {
@@ -126,5 +130,5 @@
     {SE_FrameLineEdit,          QS60StyleEnums::SP_QsnFrInputCenter},
     {SE_ListHighlight,          QS60StyleEnums::SP_QsnFrListCenter},
-    {SE_OptionsMenu,            QS60StyleEnums::SP_QsnFrPopupCenter},
+    {SE_PopupBackground,        QS60StyleEnums::SP_QsnFrPopupCenter},
     {SE_SettingsList,           QS60StyleEnums::SP_QsnFrSetOptCenter},
     {SE_TableItem,              QS60StyleEnums::SP_QsnFrCaleCenter},
@@ -137,4 +141,6 @@
     {SE_ButtonInactive,         QS60StyleEnums::SP_QsnFrButtonCenterInactive},
     {SE_Editor,                 QS60StyleEnums::SP_QsnFrInputCenter},
+    {SE_TableItemPressed,       QS60StyleEnums::SP_QsnFrGridCenterPressed},
+    {SE_ListItemPressed,        QS60StyleEnums::SP_QsnFrListPressed},
 };
 
@@ -249,6 +255,6 @@
         drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth);
         break;
-    case SE_OptionsMenu:
-        drawFrame(SF_OptionsMenu, painter, rect, flags | SF_PointNorth);
+    case SE_PopupBackground:
+        drawFrame(SF_PopupBackground, painter, rect, flags | SF_PointNorth);
         break;
     case SE_SettingsList:
@@ -290,4 +296,13 @@
         drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth);
         break;
+    case SE_DropArea:
+        drawPart(QS60StyleEnums::SP_QgnGrafOrgBgGrid, painter, rect, flags | SF_PointNorth);
+        break;
+    case SE_TableItemPressed:
+        drawFrame(SF_TableItemPressed, painter, rect, flags | SF_PointNorth);
+        break;
+    case SE_ListItemPressed:
+        drawFrame(SF_ListItemPressed, painter, rect, flags | SF_PointNorth);
+        break;
     default:
         break;
@@ -303,4 +318,11 @@
 short QS60StylePrivate::pixelMetric(int metric)
 {
+    //If it is a custom value, need to strip away the base to map to internal
+    //pixel metric value table
+    if (metric & QStyle::PM_CustomBase) {
+        metric -= QStyle::PM_CustomBase;
+        metric += MAX_NON_CUSTOM_PIXELMETRICS - 1;
+    }
+
     Q_ASSERT(metric < MAX_PIXELMETRICS);
     const short returnValue = m_pmPointer[metric];
@@ -403,6 +425,6 @@
     const bool cachedColorExists = m_colorCache.contains(frame);
     if (!cachedColorExists) {
-        const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth);
-        const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight);
+        const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth);
+        const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight);
         Q_ASSERT(2 * frameCornerWidth < 32);
         Q_ASSERT(2 * frameCornerHeight < 32);
@@ -531,4 +553,5 @@
 
     if (orientation == Qt::Horizontal) {
+        startRect.setHeight(rect.height());
         startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width()));
         endRect = startRect.translated(rect.width() - startRect.width(), 0);
@@ -540,4 +563,5 @@
         }
     } else {
+        startRect.setWidth(rect.width());
         startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height()));
         endRect = startRect.translated(0, rect.height() - startRect.height());
@@ -626,4 +650,10 @@
     } else if (qobject_cast<QGroupBox *>(widget)){
         fontCategory = QS60StyleEnums::FC_Title;
+    } else if (qobject_cast<QMessageBox *>(widget)){
+        fontCategory = QS60StyleEnums::FC_Primary;
+    } else if (qobject_cast<QMenu *>(widget)){
+        fontCategory = QS60StyleEnums::FC_Primary;
+    } else if (qobject_cast<QCalendarWidget *>(widget)){
+        fontCategory = QS60StyleEnums::FC_Secondary;
     }
     if (fontCategory != QS60StyleEnums::FC_Undefined) {
@@ -755,11 +785,27 @@
     widgetPalette = *palette;
 
+    widgetPalette.setColor(QPalette::Text,
+        s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
+    widgetPalette.setColor(QPalette::HighlightedText,
+        s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
+    QApplication::setPalette(widgetPalette, "QMenu");
+    widgetPalette = *palette;
+
     widgetPalette.setColor(QPalette::WindowText,
         s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0));
+    widgetPalette.setColor(QPalette::HighlightedText,
+        s60Color(QS60StyleEnums::CL_QsnTextColors, 3, 0));
     QApplication::setPalette(widgetPalette, "QTabBar");
     widgetPalette = *palette;
 
+    widgetPalette.setColor(QPalette::HighlightedText,
+        s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0));
+    QApplication::setPalette(widgetPalette, "QListView");
+    widgetPalette = *palette;
+
     widgetPalette.setColor(QPalette::Text,
         s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
+    widgetPalette.setColor(QPalette::HighlightedText,
+        s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
     QApplication::setPalette(widgetPalette, "QTableView");
     widgetPalette = *palette;
@@ -770,10 +816,4 @@
         s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
     QApplication::setPalette(widgetPalette, "QLineEdit");
-    widgetPalette = *palette;
-
-    widgetPalette.setColor(QPalette::Text,
-        s60Color(QS60StyleEnums::CL_QsnTextColors, 27, 0));
-    widgetPalette.setColor(QPalette::HighlightedText,
-        s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
     QApplication::setPalette(widgetPalette, "QTextEdit");
     widgetPalette = *palette;
@@ -785,4 +825,6 @@
 
     widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0));
+    widgetPalette.setColor(QPalette::HighlightedText,
+        s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
     QApplication::setPalette(widgetPalette, "QRadioButton");
     QApplication::setPalette(widgetPalette, "QCheckBox");
@@ -805,6 +847,10 @@
     webPalette.setColor(QPalette::WindowText, Qt::black);
     webPalette.setColor(QPalette::Text, Qt::black);
+    webPalette.setBrush(QPalette::Base, Qt::white);
+
     QApplication::setPalette(webPalette, "QWebView");
     QApplication::setPalette(webPalette, "QGraphicsWebView");
+
+    m_webPaletteKey = webPalette.cacheKey();
 }
 
@@ -831,5 +877,4 @@
         case QS60StyleEnums::SP_QgnGrafNsliderEndRight:
         case QS60StyleEnums::SP_QgnGrafNsliderMiddle:
-            result.setWidth(result.height() >> 1);
             break;
 
@@ -842,16 +887,19 @@
         case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
         case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
-            result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
-            break;
-
-        case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
+            result.setWidth(pixelMetric(PM_FrameCornerWidth));
+            break;
+
         case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
-        case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
         case QS60StyleEnums::SP_QsnCpScrollBgBottom:
-        case QS60StyleEnums::SP_QsnCpScrollBgMiddle:
         case QS60StyleEnums::SP_QsnCpScrollBgTop:
         case QS60StyleEnums::SP_QsnCpScrollHandleBottom:
+        case QS60StyleEnums::SP_QsnCpScrollHandleTop:
+        case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
+            result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent));
+            result.setWidth(pixelMetric(QStyle::PM_ScrollBarExtent));
+            break;
+        case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
+        case QS60StyleEnums::SP_QsnCpScrollBgMiddle:
         case QS60StyleEnums::SP_QsnCpScrollHandleMiddle:
-        case QS60StyleEnums::SP_QsnCpScrollHandleTop:
             result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent));
             result.setWidth(pixelMetric(QStyle::PM_ScrollBarSliderMin));
@@ -866,13 +914,13 @@
                     case 6: /* CornerBl */
                     case 5: /* CornerBr */
-                        result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
+                        result.setWidth(pixelMetric(PM_FrameCornerWidth));
                         // Falltrough intended...
                     case 4: /* SideT */
                     case 3: /* SideB */
-                        result.setHeight(pixelMetric(PM_Custom_FrameCornerHeight));
+                        result.setHeight(pixelMetric(PM_FrameCornerHeight));
                         break;
                     case 2: /* SideL */
                     case 1: /* SideR */
-                        result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
+                        result.setWidth(pixelMetric(PM_FrameCornerWidth));
                         break;
                     case 0: /* center */
@@ -891,9 +939,17 @@
 }
 
-bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush)
-{
+bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget)
+{
+    // Always return true for web pages.
+    if (widget && m_webPaletteKey == QApplication::palette(widget).cacheKey())
+        return true;
     //If brush is not changed from style's default values, draw theme graphics.
     return (backgroundBrush.color() == Qt::transparent ||
             backgroundBrush.style() == Qt::NoBrush) ? true : false;
+}
+
+bool QS60StylePrivate::isWidgetPressed(const QWidget *widget)
+{
+    return (widget && widget == m_pressedWidget);
 }
 
@@ -936,8 +992,8 @@
             QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags);
 
-            const QStyle::SubControls subControls = optionSlider->subControls;
+            const SubControls subControls = optionSlider->subControls;
 
             // select correct slider (horizontal/vertical/pressed)
-            const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider));
+            const bool sliderPressed = ((optionSlider->state & State_Sunken) && (subControls & SC_ScrollBarSlider));
             const QS60StylePrivate::SkinElements handleElement =
                 horizontal ?
@@ -960,5 +1016,5 @@
 
             //Highlight
-/*            if (optionSlider->state & QStyle::State_HasFocus)
+/*            if (optionSlider->state & State_HasFocus)
                 drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/
 
@@ -970,5 +1026,4 @@
                 QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
             } else {
-                const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
                 const QPoint sliderGrooveCenter = sliderGroove.center();
                 const bool horizontal = optionSlider->orientation == Qt::Horizontal;
@@ -986,5 +1041,5 @@
             const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget);
             QS60StylePrivate::SkinElements handleElement;
-            if (optionSlider->state & QStyle::State_Sunken)
+            if (optionSlider->state & State_Sunken)
                 handleElement =
                         horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical;
@@ -1061,9 +1116,7 @@
                     tool.state = bflags;
                     const QToolButton *toolButtonWidget = qobject_cast<const QToolButton *>(widget);
-                    QS60StylePrivate::SkinElements element;
-                    if (toolButtonWidget)
-                        element = (toolButtonWidget->isDown()) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
-                    else
-                        element = (option->state & State_Sunken) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
+                    const QS60StylePrivate::SkinElements element =
+                        ((toolButtonWidget && toolButtonWidget->isDown()) || (option->state & State_Sunken)) ?
+                            QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
                     QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags);
                     drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
@@ -1097,5 +1150,5 @@
             }
 
-            if (toolBtn->text.length()>0 ||
+            if (toolBtn->text.length() > 0 ||
                 !toolBtn->icon.isNull()) {
                 const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget);
@@ -1173,5 +1226,5 @@
             const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
             const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
-            if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
+            if (groupBox->subControls & SC_GroupBoxFrame) {
                 QStyleOptionFrameV2 frame;
                 frame.QStyleOption::operator=(*groupBox);
@@ -1184,5 +1237,5 @@
 
             // Draw title
-            if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+            if ((groupBox->subControls & SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
                 const QColor textColor = groupBox->textColor;
                 painter->save();
@@ -1191,5 +1244,5 @@
                     painter->setPen(textColor);
                 int alignment = int(groupBox->textAlignment);
-                if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+                if (!styleHint(SH_UnderlineShortcut, option, widget))
                     alignment |= Qt::TextHideMnemonic;
 
@@ -1227,4 +1280,6 @@
             if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
                 bool isRadio = (element == CE_RadioButton);
+                QStyleOptionButton subopt = *btn;
+
                 // Highlight needs to be drawn first, as it goes "underneath" the text and indicator.
                 if (btn->state & State_HasFocus) {
@@ -1234,6 +1289,8 @@
                                                         : SE_CheckBoxFocusRect, btn, widget);
                     drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+
+                    subopt.palette.setColor(QPalette::Active, QPalette::WindowText,
+                        subopt.palette.highlightedText().color());
                 }
-                QStyleOptionButton subopt = *btn;
 
                 subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
@@ -1260,11 +1317,11 @@
     case CE_PushButtonBevel:
         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
-            const bool isDisabled = !(option->state & QStyle::State_Enabled);
+            const bool isDisabled = !(option->state & State_Enabled);
             const bool isFlat = button->features & QStyleOptionButton::Flat;
             QS60StyleEnums::SkinParts skinPart;
             QS60StylePrivate::SkinElements skinElement;
             if (!isDisabled) {
-                const bool isPressed = (option->state & QStyle::State_Sunken) ||
-                                       (option->state & QStyle::State_On);
+                const bool isPressed = (option->state & State_Sunken) ||
+                                       (option->state & State_On);
                 if (isFlat) {
                     skinPart =
@@ -1291,5 +1348,5 @@
             QStyleOptionToolButton optionToolButton = *toolBtn;
 
-            if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken)
+            if (!optionToolButton.icon.isNull() && (optionToolButton.state & State_Sunken)
                     && (optionToolButton.state & State_Enabled)) {
 
@@ -1313,12 +1370,11 @@
                 optionComboBox.palette.text().color() );
             QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget);
-            painter->save();
-            painter->setClipRect(editRect);
+            const int frameW = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
 
             if (!comboBox->currentIcon.isNull()) {
-                QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
-                QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode);
+                const QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+                const QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode);
                 QRect iconRect(editRect);
-                iconRect.setWidth(comboBox->iconSize.width() + 4);
+                iconRect.setWidth(comboBox->iconSize.width() + frameW);
                 iconRect = alignedRect(comboBox->direction,
                                        Qt::AlignLeft | Qt::AlignVCenter,
@@ -1329,15 +1385,17 @@
 
                 if (comboBox->direction == Qt::RightToLeft)
-                    editRect.translate(-4 - comboBox->iconSize.width(), 0);
+                    editRect.setRight(editRect.right() - frameW - comboBox->iconSize.width());
                 else
-                    editRect.translate(comboBox->iconSize.width() + 4, 0);
+                    editRect.setLeft(comboBox->iconSize.width() + frameW);
             }
             if (!comboBox->currentText.isEmpty() && !comboBox->editable) {
+                const Qt::TextElideMode elideMode = (comboBox->direction == Qt::LeftToRight) ? Qt::ElideRight : Qt::ElideLeft;
+                const QString text = comboBox->fontMetrics.elidedText(comboBox->currentText, elideMode, editRect.width());
+
                 QCommonStyle::drawItemText(painter,
-                            editRect.adjusted(QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth), 0, -1, 0),
+                            editRect.adjusted(QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 0, -1, 0),
                             visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter),
-                            comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText);
-            }
-            painter->restore();
+                            comboBox->palette, comboBox->state & State_Enabled, text);
+            }
         }
         break;
@@ -1350,6 +1408,6 @@
 
             painter->setClipRect(voptAdj.rect);
-            const bool isSelected = (vopt->state & QStyle::State_Selected);
-            const bool hasFocus = (vopt->state & QStyle::State_HasFocus);
+            const bool isSelected = (vopt->state & State_Selected);
+            const bool hasFocus = (vopt->state & State_HasFocus);
 
             bool isScrollBarVisible = false;
@@ -1380,51 +1438,11 @@
             if (vopt->backgroundBrush == Qt::NoBrush) {
                 if (itemView) {
-                    const QModelIndex index = vopt->index;
-                    //todo: Draw cell background only once - for the first cell.
-                    QStyleOptionViewItemV4 voptAdj2 = voptAdj;
-                    const QModelIndex indexFirst = itemView->model()->index(0, 0);
-                    const QModelIndex indexLast = itemView->model()->index(
-                            itemView->model()->rowCount() - 1, itemView->model()->columnCount() -1);
-                    if (itemView->viewport())
-                        voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(),
-                                itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect());
                     drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);
                 }
             } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);}
 
-            // draw the focus rect
-            if (isSelected | hasFocus) {
-                QRect highlightRect = option->rect.adjusted(1,1,-1,-1);
-                QAbstractItemView::SelectionBehavior selectionBehavior =
-                    itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems;
-                if (selectionBehavior != QAbstractItemView::SelectItems) {
-                    // set highlight rect so that it is continuous from cell to cell, yet sligthly
-                    // smaller than cell rect
-                    int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0;
-                    if (selectionBehavior == QAbstractItemView::SelectRows) {
-                        yBeginning = 1; yEnd = -1;
-                        if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
-                            xBeginning = 1;
-                        else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
-                            xEnd = -1;
-                    } else if (selectionBehavior == QAbstractItemView::SelectColumns) {
-                        xBeginning = 1; xEnd = -1;
-                        if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
-                            yBeginning = 1;
-                        else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
-                            yEnd = -1;
-                    }
-                    highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd);
-                }
-                if (vopt->showDecorationSelected &&
-                    (vopt->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()))
-                    QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags);
-                else
-                    painter->fillRect(highlightRect, vopt->palette.highlight());
-            }
-
              // draw the icon
-             const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled;
-             const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
+             const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled;
+             const QIcon::State state = (voptAdj.state & State_Open) ? QIcon::On : QIcon::Off;
              voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state);
 
@@ -1433,32 +1451,36 @@
                  const bool singleSelection =
                      (itemView->selectionMode() == QAbstractItemView::SingleSelection ||
-                      itemView->selectionMode() == QAbstractItemView::NoSelection);
+                      itemView->selectionMode() == QAbstractItemView::NoSelection)||
+                     (itemView->selectionModel()->selectedIndexes().count() < 2 );
+
+                 const bool selectItemsOnly = (itemView->selectionBehavior() == QAbstractItemView::SelectItems);
+
                  const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget);
 
                  QStyleOptionViewItemV4 checkMarkOption(voptAdj);
+                 if (selectionRect.isValid())
+                     checkMarkOption.rect = selectionRect;
                  // Draw selection mark.
-                 if (voptAdj.state & QStyle::State_Selected && !singleSelection) {
-                     checkMarkOption.rect = selectionRect;
-                     drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
-                     if ( textRect.right() > selectionRect.left() )
+                 if (isSelected && !singleSelection && selectItemsOnly) {
+                     proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
+                     // @todo: this should happen in the rect retrievel i.e. subElementRect()
+                     if (textRect.right() > selectionRect.left())
                          textRect.setRight(selectionRect.left());
                  } else if (singleSelection &&
-                     voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator &&
-                     selectionRect.isValid()) {
-                     checkMarkOption.rect = selectionRect;
-                     checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus;
+                     voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) {
+                     checkMarkOption.state = checkMarkOption.state & ~State_HasFocus;
 
                      switch (vopt->checkState) {
                      case Qt::Unchecked:
-                         checkMarkOption.state |= QStyle::State_Off;
+                         checkMarkOption.state |= State_Off;
                          break;
                      case Qt::PartiallyChecked:
-                         checkMarkOption.state |= QStyle::State_NoChange;
+                         checkMarkOption.state |= State_NoChange;
                          break;
                      case Qt::Checked:
-                         checkMarkOption.state |= QStyle::State_On;
+                         checkMarkOption.state |= State_On;
                          break;
                      }
-                     drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
+                     drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
                  }
              }
@@ -1466,13 +1488,8 @@
              // draw the text
             if (!voptAdj.text.isEmpty()) {
-                if (isSelected) {
-                    if (qobject_cast<const QTableView *>(widget))
-                        voptAdj.palette.setColor(
-                            QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
-                    else
-                        voptAdj.palette.setColor(
-                            QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0));
-                }
-                painter->setPen(voptAdj.palette.text().color());
+                if (isSelected || hasFocus )
+                    painter->setPen(voptAdj.palette.highlightedText().color());
+                else
+                    painter->setPen(voptAdj.palette.text().color());
                 d->viewItemDrawText(painter, &voptAdj, textRect);
             }
@@ -1485,5 +1502,5 @@
         if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) {
             QStyleOptionTabV3 optionTabAdj = *optionTab;
-            const bool isSelected = optionTab->state & QStyle::State_Selected;
+            const bool isSelected = optionTab->state & State_Selected;
             const bool directionMirrored = (optionTab->direction == Qt::RightToLeft);
             QS60StylePrivate::SkinElements skinElement;
@@ -1511,29 +1528,45 @@
                     break;
             }
-            if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive||
-                    skinElement==QS60StylePrivate::SE_TabBarTabNorthInactive||
-                    skinElement==QS60StylePrivate::SE_TabBarTabSouthInactive||
-                    skinElement==QS60StylePrivate::SE_TabBarTabWestInactive||
-                    skinElement==QS60StylePrivate::SE_TabBarTabEastActive||
-                    skinElement==QS60StylePrivate::SE_TabBarTabNorthActive||
-                    skinElement==QS60StylePrivate::SE_TabBarTabSouthActive||
+            if (skinElement == QS60StylePrivate::SE_TabBarTabEastInactive ||
+                    skinElement == QS60StylePrivate::SE_TabBarTabNorthInactive ||
+                    skinElement == QS60StylePrivate::SE_TabBarTabSouthInactive ||
+                    skinElement == QS60StylePrivate::SE_TabBarTabWestInactive ||
+                    skinElement == QS60StylePrivate::SE_TabBarTabEastActive ||
+                    skinElement == QS60StylePrivate::SE_TabBarTabNorthActive ||
+                    skinElement == QS60StylePrivate::SE_TabBarTabSouthActive ||
                     skinElement==QS60StylePrivate::SE_TabBarTabWestActive) {
                 const int borderThickness =
-                    QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
+                    QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
                 const int tabOverlap =
-                    QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness;
-                //todo: draw navi wipe behind tabbar - must be drawn with first draw
-
-                if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive||
-                        skinElement==QS60StylePrivate::SE_TabBarTabEastActive||
-                        skinElement==QS60StylePrivate::SE_TabBarTabWestInactive||
-                        skinElement==QS60StylePrivate::SE_TabBarTabWestActive){
-                    optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
+                    QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
+                const bool usesScrollButtons = 
+                    (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
+                const int roomForScrollButton = 
+                    usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+
+                // adjust for overlapping tabs and scrollbuttons, if necessary
+                if (skinElement == QS60StylePrivate::SE_TabBarTabEastInactive ||
+                        skinElement == QS60StylePrivate::SE_TabBarTabEastActive ||
+                        skinElement == QS60StylePrivate::SE_TabBarTabWestInactive ||
+                        skinElement == QS60StylePrivate::SE_TabBarTabWestActive){
+                    if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+                        optionTabAdj.rect.adjust(0, roomForScrollButton, 0, tabOverlap);
+                    else if (optionTabAdj.position == QStyleOptionTabV3::End)
+                        optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
+                    else
+                        optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
                 } else {
-                    if (directionMirrored)
-                        optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0);
-                    else
-                        optionTabAdj.rect.adjust(0, 0, tabOverlap, 0);
+                    if (directionMirrored) {
+                        if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+                            optionTabAdj.rect.adjust(-tabOverlap, 0, -roomForScrollButton, 0);
+                        else
+                            optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0);
+                    } else {
+                        if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+                            optionTabAdj.rect.adjust(roomForScrollButton, 0, tabOverlap, 0);
+                        else
+                            optionTabAdj.rect.adjust(0, 0, tabOverlap, 0);
                     }
+                }
             }
             QS60StylePrivate::drawSkinElement(skinElement, painter, optionTabAdj.rect, flags);
@@ -1545,8 +1578,11 @@
             QRect tr = optionTab.rect;
             const bool directionMirrored = (optionTab.direction == Qt::RightToLeft);
-            const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
+            const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
             const int tabOverlap =
-                QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness;
-            const QRect windowRect = painter->window();
+                QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
+            const bool usesScrollButtons = 
+                (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
+            const int roomForScrollButton = 
+                usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0;
 
             switch (tab->shape) {
@@ -1576,5 +1612,5 @@
             if (selected)
                 optionTab.palette.setColor(QPalette::Active, QPalette::WindowText,
-                    QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option));
+                    optionTab.palette.highlightedText().color());
 
             const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast
@@ -1582,4 +1618,15 @@
                                 || optionTab.shape == QTabBar::TriangularEast
                                 || optionTab.shape == QTabBar::TriangularWest;
+
+            //make room for scrollbuttons
+            if (!verticalTabs) {
+                if ((tab->position == QStyleOptionTabV3::Beginning && !directionMirrored))
+                    tr.adjust(roomForScrollButton, 0, 0, 0);
+                else if ((tab->position == QStyleOptionTabV3::Beginning && directionMirrored))
+                    tr.adjust(0, 0, -roomForScrollButton, 0);
+            } else {
+                if (tab->position == QStyleOptionTabV3::Beginning)
+                    tr.adjust(0, roomForScrollButton, 0, 0);
+            }
 
             if (verticalTabs) {
@@ -1601,10 +1648,10 @@
                 painter->setTransform(m, true);
             }
-            tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget),
-                            pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget));
+            tr.adjust(0, 0, pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget),
+                            pixelMetric(PM_TabBarTabShiftVertical, tab, widget));
 
             if (selected) {
-                tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget));
-                tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget));
+                tr.setBottom(tr.bottom() - pixelMetric(PM_TabBarTabShiftVertical, tab, widget));
+                tr.setRight(tr.right() - pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget));
             }
 
@@ -1614,7 +1661,8 @@
             if (!optionTab.icon.isNull()) {
                 QSize iconSize = optionTab.iconSize;
-                int iconExtent = pixelMetric(PM_TabBarIconSize);
-                if (iconSize.height() > iconExtent || iconSize.width() > iconExtent)
+                if (!iconSize.isValid()) {
+                    const int iconExtent = pixelMetric(PM_TabBarIconSize);
                     iconSize = QSize(iconExtent, iconExtent);
+                }
                 QPixmap tabIcon = optionTab.icon.pixmap(iconSize,
                     (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
@@ -1627,5 +1675,5 @@
                                         tr.center().y() - (tabIcon.height() >> 1),
                                         tabIcon);
-                tr.setLeft(tr.left() + iconSize.width() + 4);
+                tr.setLeft(tr.left() + iconSize.width() + 4); //todo: magic four
             }
 
@@ -1709,5 +1757,6 @@
                 text_flags |= Qt::TextHideMnemonic;
 
-            if ((option->state & State_Selected) && (option->state & State_Enabled))
+            const bool selected = (option->state & State_Selected) && (option->state & State_Enabled);
+            if (selected)
                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
 
@@ -1716,11 +1765,14 @@
 
             //todo: move the vertical spacing stuff into subElementRect
-            const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+            const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
             if (checkable){
-                const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+                const int hSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
                 QStyleOptionMenuItem optionCheckBox;
                 optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
                 optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
                 optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
+                optionCheckBox.rect.moveCenter(QPoint(
+                        optionCheckBox.rect.center().x(), 
+                        menuItem->rect.center().y()));
                 const int moveByX = optionCheckBox.rect.width() + vSpacing;
                 if (optionMenuItem.direction == Qt::LeftToRight) {
@@ -1756,5 +1808,5 @@
                 arrowOptions.QStyleOption::operator=(*menuItem);
                 const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) +
-                    pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget);
+                    pixelMetric(PM_LayoutVerticalSpacing, option, widget);
                 if (optionMenuItem.direction == Qt::LeftToRight)
                     arrowOptions.rect.setLeft(textRect.right());
@@ -1779,4 +1831,8 @@
                 painter->setOpacity(0.5);
             }
+            if (selected)
+                optionMenuItem.palette.setColor(
+                    QPalette::Active, QPalette::Text, optionMenuItem.palette.highlightedText().color());
+
             QCommonStyle::drawItemText(painter, textRect, text_flags,
                     optionMenuItem.palette, enabled,
@@ -1800,6 +1856,6 @@
             QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
             const int penWidth = (header->orientation == Qt::Horizontal) ?
-                linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)
-                : linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth);
+                linePen.width() + QS60StylePrivate::pixelMetric(PM_BoldLineWidth)
+                : linePen.width() + QS60StylePrivate::pixelMetric(PM_ThinLineWidth);
             linePen.setWidth(penWidth);
             painter->setPen(linePen);
@@ -1820,5 +1876,5 @@
                 QStyleOptionHeader subopt = *header;
                 const int borderTweak =
-                    QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+                    QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1;
                 if (subopt.direction == Qt::LeftToRight)
                     subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak);
@@ -1896,5 +1952,5 @@
         if (const QTextEdit *textEdit = qobject_cast<const QTextEdit *>(widget)) {
             const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option);
-            if (QS60StylePrivate::canDrawThemeBackground(frame->palette.base()))
+            if (QS60StylePrivate::canDrawThemeBackground(frame->palette.base(), widget))
                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags);
             else
@@ -1928,9 +1984,4 @@
         break;
     case CE_FocusFrame: {
-            // The pen width should nearly fill the layoutspacings around the widget
-            const int penWidth =
-                qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing))
-                - 2; // But keep 1 pixel distance to the focus widget and 1 pixel to the adjacent widgets
-
 #ifdef QT_KEYPAD_NAVIGATION
             bool editFocus = false;
@@ -1939,27 +1990,29 @@
                     editFocus = true;
             }
-            const qreal opacity = editFocus ? 0.65 : 0.45; // Trial and error factors. Feel free to improve.
+            const qreal opacity = editFocus ? 1 : 0.75; // Trial and error factors. Feel free to improve.
 #else
-            const qreal opacity = 0.5;
+            const qreal opacity = 0.85;
 #endif
-            // Because of Qts coordinate system, we need to tweak the rect by .5 pixels, otherwise it gets blurred.
-            const qreal rectAdjustment = (penWidth % 2) ? -.5 : 0;
-
-            // Make sure that the pen stroke is inside the rect
-            const QRectF adjustedRect =
-                QRectF(option->rect).adjusted(
-                    rectAdjustment + penWidth,
-                    rectAdjustment + penWidth,
-                    -rectAdjustment - penWidth,
-                    -rectAdjustment - penWidth
-                );
-
-            const qreal roundRectRadius = penWidth * goldenRatio;
+            // We need to reduce the focus frame size if LayoutSpacing is smaller than FocusFrameMargin
+            // Otherwise, we would overlay adjacent widgets.
+            const int frameHeightReduction =
+                    qMin(0, pixelMetric(PM_LayoutVerticalSpacing)
+                            - pixelMetric(PM_FocusFrameVMargin));
+            const int frameWidthReduction =
+                    qMin(0, pixelMetric(PM_LayoutHorizontalSpacing)
+                            - pixelMetric(PM_FocusFrameHMargin));
+            const int rounding =
+                    qMin(pixelMetric(PM_FocusFrameVMargin),
+                            pixelMetric(PM_LayoutVerticalSpacing));
+            const QRect frameRect =
+                    option->rect.adjusted(-frameWidthReduction, -frameHeightReduction,
+                            frameWidthReduction, frameHeightReduction);
+            QPainterPath framePath;
+            framePath.addRoundedRect(frameRect, rounding, rounding);
 
             painter->save();
             painter->setRenderHint(QPainter::Antialiasing);
             painter->setOpacity(opacity);
-            painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth));
-            painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius);
+            painter->fillPath(framePath, option->palette.color(QPalette::Text));
             painter->restore();
         }
@@ -1986,5 +2039,4 @@
 void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
 {
-    Q_D(const QS60Style);
     const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ?  QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
     bool commonStyleDraws = false;
@@ -1994,11 +2046,15 @@
             //Draw themed highlight to radiobuttons and checkboxes.
             //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle.
-            if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color())
+            if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) {
                 if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) &&
                     (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget))))
-                        QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
-            else
+                        QS60StylePrivate::drawSkinElement(
+                            QS60StylePrivate::isWidgetPressed(widget) ? 
+                                QS60StylePrivate::SE_ListItemPressed : 
+                                QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
+            } else {
                 commonStyleDraws = true;
             }
+        }
         break;
 #ifndef QT_NO_LINEEDIT
@@ -2009,5 +2065,5 @@
                 break;
 #endif
-            if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()))
+            if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget))
                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, painter, option->rect, flags);
             else
@@ -2018,10 +2074,10 @@
     case PE_IndicatorCheckBox: {
             // Draw checkbox indicator as color skinned graphics.
-            const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
+            const QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ?
                 QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff;
             painter->save();
 
-            QColor themeColor = QS60StylePrivate::themePalette()->windowText().color();
-            QColor windowTextColor = option->palette.windowText().color();
+            const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color();
+            const QColor windowTextColor = option->palette.windowText().color();
 
             if (themeColor != windowTextColor)
@@ -2034,16 +2090,16 @@
     case PE_IndicatorViewItemCheck:
 #ifndef QT_NO_ITEMVIEWS
-        if (const QListView *listItem = (qobject_cast<const QListView *>(widget))) {
+        if (const QAbstractItemView *itemView = (qobject_cast<const QAbstractItemView *>(widget))) {
             if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
                 const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator;
-                const bool singleSelection = listItem->selectionMode() ==
-                    QAbstractItemView::SingleSelection || listItem->selectionMode() == QAbstractItemView::NoSelection;
+                const bool singleSelection = itemView->selectionMode() ==
+                    QAbstractItemView::SingleSelection || itemView->selectionMode() == QAbstractItemView::NoSelection;
                 // draw either checkbox at the beginning
                 if (checkBoxVisible && singleSelection) {
                     drawPrimitive(PE_IndicatorCheckBox, option, painter, widget);
                 // ... or normal "tick" selection at the end.
-                } else if (option->state & QStyle::State_Selected) {
+                } else if (option->state & State_Selected) {
                     QRect tickRect = option->rect;
-                    const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth);
+                    const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
                     // adjust tickmark rect to exclude frame border
                     tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth);
@@ -2070,6 +2126,6 @@
 
             painter->save();
-            QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option);
-            QColor buttonTextColor = option->palette.buttonText().color();
+            const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option);
+            const QColor buttonTextColor = option->palette.buttonText().color();
             if (themeColor != buttonTextColor)
                 painter->setPen(buttonTextColor);
@@ -2078,5 +2134,5 @@
 
             // Draw radiobutton indicator as color skinned graphics.
-            QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
+            QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ?
                 QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff;
             QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect,
@@ -2089,6 +2145,6 @@
     case PE_PanelButtonBevel:
     case PE_FrameButtonBevel:
-        if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) {
-            const bool isPressed = option->state & QStyle::State_Sunken;
+        if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) {
+            const bool isPressed = option->state & State_Sunken;
             const QS60StylePrivate::SkinElements skinElement =
                 isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
@@ -2121,10 +2177,10 @@
     case PE_IndicatorSpinUp:
         if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
-            if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base())) {
+            if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base(), widget)) {
                 QStyleOptionSpinBox optionSpinBox = *spinBox;
                 const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
                     QS60StyleEnums::SP_QgnGrafScrollArrowUp :
                     QS60StyleEnums::SP_QgnGrafScrollArrowDown;
-                const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+                const int iconMargin = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1;
                 optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
                 QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags);
@@ -2136,9 +2192,9 @@
 #ifndef QT_NO_COMBOBOX
         if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
-            if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) {
+            if (QS60StylePrivate::canDrawThemeBackground( option->palette.base(), widget)) {
                 // We want to draw down arrow here for comboboxes as well.
                 QStyleOptionFrame optionsComboBox = *cmb;
                 const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
-                const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+                const int iconMargin = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1;
                 optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
                 QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags);
@@ -2175,8 +2231,8 @@
             ) {
             //Need extra check since dialogs have their own theme background
-            if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) &&
+            if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) &&
                 option->palette.window().texture().cacheKey() ==
                     QS60StylePrivate::m_themePalette->window().texture().cacheKey())
-                QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags);
+                QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, option->rect, flags);
             else
                 commonStyleDraws = true;
@@ -2217,4 +2273,55 @@
 #ifndef QT_NO_ITEMVIEWS
     case PE_PanelItemViewItem:
+        if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+            const bool isSelected = (vopt->state & State_Selected);
+            const bool hasFocus = (vopt->state & State_HasFocus);
+            const bool isPressed = QS60StylePrivate::isWidgetPressed(widget);
+
+            if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) {
+                QRect highlightRect = vopt->rect.adjusted(1,1,-1,-1);
+                const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget);
+                QAbstractItemView::SelectionBehavior selectionBehavior =
+                    itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems;
+                // Set the draw area for highlights (focus, select rect or pressed rect)
+                if (hasFocus || isSelected || isPressed) {
+                    if (selectionBehavior != QAbstractItemView::SelectItems) {
+                        // set highlight rect so that it is continuous from cell to cell, yet sligthly
+                        // smaller than cell rect
+                        int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0;
+                        if (selectionBehavior == QAbstractItemView::SelectRows) {
+                            yBeginning = 1; yEnd = -1;
+                            if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+                                xBeginning = 1;
+                            else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
+                                xEnd = -1;
+                        } else if (selectionBehavior == QAbstractItemView::SelectColumns) {
+                            xBeginning = 1; xEnd = -1;
+                            if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+                                yBeginning = 1;
+                            else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
+                                yEnd = -1;
+                        }
+                        highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd);
+                    }
+                }
+                bool tableView = false;
+                if (itemView && qobject_cast<const QTableView *>(widget))
+                    tableView = true;
+
+                QS60StylePrivate::SkinElements element;
+                QRect elementRect = option->rect;
+
+                //draw item is drawn as pressed, if it already has focus.
+                if (isPressed && (hasFocus || isSelected)) {
+                    element = tableView ? QS60StylePrivate::SE_TableItemPressed : QS60StylePrivate::SE_ListItemPressed;
+                } else if (hasFocus || (isSelected && selectionBehavior != QAbstractItemView::SelectItems)) {
+                    element = QS60StylePrivate::SE_ListHighlight;
+                    elementRect = highlightRect;
+                }
+                QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags);
+            } else {
+                QCommonStyle::drawPrimitive(element, option, painter, widget);
+            }
+        }
         break;
 #endif //QT_NO_ITEMVIEWS
@@ -2249,37 +2356,41 @@
             QCommonStyle::drawPrimitive(element, option, painter, widget);
         } else {
-            const bool rightLine = option->state & State_Item;
-            const bool downLine = option->state & State_Sibling;
-            const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling);
-
-            QS60StyleEnums::SkinParts skinPart;
-            bool drawSkinPart = false;
-            if (rightLine && downLine && upLine) {
-                skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch;
-                drawSkinPart = true;
-            } else if (rightLine && upLine) {
-                skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd;
-                drawSkinPart = true;
-            } else if (upLine && downLine) {
-                skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight;
-                drawSkinPart = true;
-            }
-
-            if (drawSkinPart)
-                QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
-
-            if (option->state & State_Children) {
-                QS60StyleEnums::SkinParts skinPart =
-                        (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper;
-                int minDimension = qMin(option->rect.width(), option->rect.height());
-                const int resizeValue = minDimension >> 1;
-                minDimension += resizeValue; // Adjust the icon bigger because of empty space in svg icon.
-                QRect iconRect(option->rect.topLeft(), QSize(minDimension, minDimension));
-                int verticalMagic(0);
-                // magic values for positioning svg icon.
-                if (option->rect.width() <= option->rect.height())
-                    verticalMagic = 3;
-                iconRect.translate(3, verticalMagic - resizeValue);
-                QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, flags);
+            if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(option)) {
+                const bool rightLine = option->state & State_Item;
+                const bool downLine = option->state & State_Sibling;
+                const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling);
+                QS60StylePrivate::SkinElementFlags adjustedFlags = flags;
+
+                QS60StyleEnums::SkinParts skinPart;
+                bool drawSkinPart = false;
+                if (rightLine && downLine && upLine) {
+                    skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch;
+                    drawSkinPart = true;
+                } else if (rightLine && upLine) {
+                    skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd;
+                    drawSkinPart = true;
+                } else if (upLine && downLine) {
+                    skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight;
+                    drawSkinPart = true;
+                }
+
+                if (option->direction == Qt::RightToLeft)
+                    adjustedFlags |= QS60StylePrivate::SF_Mirrored_X_Axis;
+
+                if (drawSkinPart)
+                    QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, adjustedFlags);
+
+                if (option->state & State_Children) {
+                    QS60StyleEnums::SkinParts skinPart =
+                            (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper;
+                    const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
+                    const int minDimension = qMin(option->rect.width(), option->rect.height());
+                    const int magicTweak = (option->direction == Qt::RightToLeft) ? -3 : 3; //@todo: magic
+                    //The branch indicator icon in S60 is supposed to be superimposed on top of branch lines.
+                    QRect iconRect(QPoint(option->rect.left() + magicTweak, selectionRect.top() + 1), QSize(minDimension, minDimension));
+                    if (!QS60StylePrivate::isTouchSupported())
+                        iconRect.translate(0, -4); //@todo: magic
+                    QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, adjustedFlags);
+                }
             }
         }
@@ -2292,6 +2403,6 @@
                 commonStyleDraws = true;
             } else {
-                QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
-                if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+                QPalette::ColorGroup cg = vopt->state & State_Enabled ? QPalette::Normal : QPalette::Disabled;
+                if (cg == QPalette::Normal && !(vopt->state & State_Active))
                     cg = QPalette::Inactive;
                 if (vopt->features & QStyleOptionViewItemV2::Alternate)
@@ -2304,5 +2415,10 @@
     case PE_PanelScrollAreaCorner:
         break;
-
+    case PE_IndicatorItemViewItemDrop:
+        if (QS60StylePrivate::isTouchSupported())
+            QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_DropArea, painter, option->rect, flags);
+        else
+            commonStyleDraws = true;
+        break;
         // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
     case PE_FrameLineEdit:
@@ -2325,5 +2441,4 @@
 #ifndef QT_NO_COLUMNVIEW
     case PE_IndicatorColumnViewArrow:
-    case PE_IndicatorItemViewItemDrop:
 #endif //QT_NO_COLUMNVIEW
     case PE_FrameTabBarBase: // since tabs are in S60 always in navipane, let's use common style for tab base in Qt.
@@ -2343,11 +2458,8 @@
         metricValue = QCommonStyle::pixelMetric(metric, option, widget);
 
-    if (metric == PM_SubMenuOverlap && widget) {
-        const QMenu *menu = qobject_cast<const QMenu *>(widget);
-        if (menu && menu->activeAction() && menu->activeAction()->menu()) {
-            const int menuWidth = menu->activeAction()->menu()->sizeHint().width();
-            metricValue = -menuWidth;
-        }
-    }
+    // Menu scrollers should be set to zero height for combobox popups
+    if (metric == PM_MenuScrollerHeight && !qobject_cast<const QMenu *>(widget))
+        metricValue = 0;
+
     //if layout direction is mirrored, switch left and right border margins
     if (option && option->direction == Qt::RightToLeft) {
@@ -2357,4 +2469,16 @@
             metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin);
     }
+
+    if (widget && (metric == PM_LayoutTopMargin))
+        if (widget->windowType() == Qt::Dialog)
+            //double the top layout margin for dialogs, it is very close to real value
+            //without having to define custom pixel metric
+            metricValue *= 2;
+
+    if (widget && (metric == PM_FocusFrameHMargin))
+        if (qobject_cast<const QTableView *>(widget))
+            //Halve the focus frame margin for table items
+            metricValue /= 2;
+
     return metricValue;
 }
@@ -2377,8 +2501,18 @@
             sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
             //FIXME properly - style should calculate the location of border frame-part
-            sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin));
-            if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))
+            if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))  {
                 if (buttonWidget->isCheckable())
                     sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
+                const int iconHeight = (!buttonWidget->icon().isNull()) ? buttonWidget->iconSize().height() : 0;
+                const int textHeight = (buttonWidget->text().length() > 0) ?
+                    buttonWidget->fontMetrics().size(Qt::TextSingleLine, buttonWidget->text()).height() : opt->fontMetrics.height();
+                const int decoratorHeight = (buttonWidget->isCheckable()) ? pixelMetric(PM_IndicatorHeight) : 0;
+
+                const int contentHeight =
+                        qMax(qMax(iconHeight, decoratorHeight) + pixelMetric(PM_ButtonMargin),
+                             textHeight + 2*pixelMetric(PM_ButtonMargin));
+                sz.setHeight(qMax(sz.height(), contentHeight));
+                sz += QSize(2 * pixelMetric(PM_ButtonMargin), 0);
+            }
             break;
         case CT_LineEdit:
@@ -2391,30 +2525,43 @@
                 if (naviPaneSize.height() > sz.height())
                     sz.setHeight(naviPaneSize.height());
-            }
-            break;
+                // Adjust beginning tabbar item size, if scrollbuttons are used. This is to ensure that the
+                // tabbar item content fits, since scrollbuttons are making beginning tabbar item smaller.
+                int scrollButtonSize = 0;
+                if (const QTabBar *tabBar = qobject_cast<const QTabBar *>(widget))
+                    scrollButtonSize = tabBar->usesScrollButtons() ? pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+                if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+                    const bool verticalTabs = tab->shape == QTabBar::RoundedEast
+                            || tab->shape == QTabBar::RoundedWest
+                            || tab->shape == QTabBar::TriangularEast
+                            || tab->shape == QTabBar::TriangularWest;
+                    if (tab->position == QStyleOptionTab::Beginning)
+                        sz += QSize(verticalTabs ? 0 : scrollButtonSize, !verticalTabs ? 0 : scrollButtonSize);
+                }
+            }
+            break;
+        case CT_MenuItem:
         case CT_ItemViewItem:
+            if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+                if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+                    sz = QSize();
+                    break;
+                }
+            }
             sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
             if (QS60StylePrivate::isTouchSupported())
                 //Make itemview easier to use in touch devices
                 //QCommonStyle does not adjust height with horizontal margin, it only adjusts width
-                sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin));
+                sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
             break;
 #ifndef QT_NO_COMBOBOX
-        case CT_ComboBox:
-            if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
-               const int frameWidth = cmb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0;
-               const int textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1);
-               const int smallestExtraWidth = 23;
-               // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
-               const int extra = 
-                   qMax(smallestExtraWidth, 2*textMargins + pixelMetric(PM_ScrollBarExtent, opt, widget));
-               sz = QSize(sz.width() + frameWidth + extra, sz.height() + frameWidth);
-               int maxScreenWidth = QApplication::desktop()->availableGeometry().size().width();
-               if (sz.width() > maxScreenWidth) {
-                   maxScreenWidth = maxScreenWidth - (extra + frameWidth);
-                   sz.setWidth(maxScreenWidth);
-               }
-           }
-           break;
+        case CT_ComboBox: {
+                // Fixing Ui design issues with too wide QComboBoxes and greedy SizeHints
+                // Make sure, that the combobox stays within the screen.
+                const QSize desktopContentSize = QApplication::desktop()->availableGeometry().size()
+                        - QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0);
+                sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget).
+                        boundedTo(desktopContentSize);
+            }
+            break;
 #endif
         default:
@@ -2429,6 +2576,15 @@
                             QStyleHintReturn *hret) const
 {
-    int retValue = -1;
+    int retValue = 0;
     switch (sh) {
+        case SH_RequestSoftwareInputPanel:
+            if (QS60StylePrivate::isSingleClickUi())
+                retValue = RSIP_OnMouseClick;
+            else
+                retValue = RSIP_OnMouseClickAndAlreadyFocused;
+            break;
+        case SH_ComboBox_Popup:
+            retValue = true;
+            break;
         case SH_Table_GridLineColor:
             retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba());
@@ -2455,7 +2611,11 @@
             retValue = QPalette::Base;
             break;
-        case SH_ItemView_ActivateItemOnSingleClick:
-            retValue = QS60StylePrivate::isSingleClickUi();
-            break;
+        case SH_ItemView_ActivateItemOnSingleClick: {
+            if (QS60StylePrivate::isSingleClickUi())
+                retValue = true;
+            else if (opt && opt->state & QStyle::State_Selected)
+                retValue = true;
+            break;
+        }
         case SH_ProgressDialog_TextLabelAlignment:
             retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ?
@@ -2472,4 +2632,7 @@
             retValue = true;
             break;
+        case SH_Menu_MouseTracking:
+            retValue = true;
+            break;
         case SH_ItemView_ShowDecorationSelected:
             retValue = true;
@@ -2484,9 +2647,9 @@
             retValue = 0;
             break;
-        case SH_RequestSoftwareInputPanel:
-            retValue = RSIP_OnMouseClickAndAlreadyFocused;
-            break;
         case SH_FormLayoutWrapPolicy:
             retValue = QFormLayout::WrapLongRows;
+            break;
+        case SH_ScrollBar_ContextMenu:
+            retValue = false;
             break;
         default:
@@ -2568,13 +2731,21 @@
             const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
             const int buttonMargin = spinbox->frame ? 2 : 0;
-            const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin;
+            const int buttonContentWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin;
+            // Spinbox buttons should be no larger than one fourth of total width.
+            // Thus, side-by-side buttons would take half of the total width.
+            const int maxSize = qMax(spinbox->rect.width() / 4, buttonContentWidth);
             QSize buttonSize;
-            buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness));
+            buttonSize.setHeight(qMin(maxSize, qMax(8, spinbox->rect.height() - frameThickness)));
             //width should at least be equal to height
-            buttonSize.setWidth(qMax(buttonSize.height(), buttonWidth));
+            buttonSize.setWidth(qMax(buttonSize.height(), buttonContentWidth));
             buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
 
-            const int y = frameThickness + spinbox->rect.y();
-            const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width();
+            // Normally spinbuttons should be side-by-side, but if spinbox grows very big
+            // and spinbuttons reach their maximum size, they can be deployed one top of the other.
+            const bool sideBySide = (buttonSize.height() * 2 < spinbox->rect.height()) ? false : true;
+            const int y = frameThickness + spinbox->rect.y() +  
+                          (spinbox->rect.height() - (sideBySide ? 1 : 2) * buttonSize.height()) / 2;
+            const int x = spinbox->rect.x() + 
+                          spinbox->rect.width() - frameThickness - (sideBySide ? 2 : 1) * buttonSize.width();
 
             switch (scontrol) {
@@ -2587,5 +2758,7 @@
                     if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
                         return QRect();
-                    ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height());
+                    ret = QRect(x + (sideBySide ? buttonSize.width() : 0), 
+                                y + (sideBySide ? 0 : buttonSize.height()), 
+                                buttonSize.width(), buttonSize.height());
                     break;
                 case SC_SpinBoxEditField:
@@ -2617,5 +2790,5 @@
             const int width = cmb->rect.width();
             const int height = cmb->rect.height();
-            const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
+            const int buttonIconSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize);
             const int buttonMargin = cmb->frame ? 2 : 0;
             // lets use spinbox frame here as well, as no combobox specific value available.
@@ -2643,4 +2816,17 @@
                     }
                 break;
+                case SC_ComboBoxListBoxPopup: {
+                    const QRect desktopContent = QApplication::desktop()->availableGeometry();
+
+                    // take the size of this and position bottom above available area
+                    QRect popupRect;
+                    const int width = desktopContent.width() - pixelMetric(PM_LayoutRightMargin) - pixelMetric(PM_LayoutLeftMargin);
+                    popupRect.setWidth(width);
+                    popupRect.setHeight(desktopContent.height()); //combobox resets height anyway based on content
+                    popupRect.setBottom(desktopContent.bottom());
+                    popupRect.translate(pixelMetric(PM_LayoutLeftMargin), 0);
+                    ret = popupRect;
+                    }
+                break;
             default:
                 break;
@@ -2657,5 +2843,5 @@
                     //slightly indent text and boxes, so that dialog border does not mess with them.
                     const int horizontalSpacing =
-                        QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+                        QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
                     ret.adjust(2, horizontalSpacing - 3, 0, 0);
                     }
@@ -2717,9 +2903,8 @@
         case SE_LineEditContents: {
                 // in S60 the input text box doesn't start from line Edit's TL, but
-                // a bit indented.
-                QRect lineEditRect = opt->rect;
-                const int adjustment = opt->rect.height() >> 2;
-                lineEditRect.adjust(adjustment, 0, 0, 0);
-                ret = lineEditRect;
+                // a bit indented (8 pixels).
+                const int KLineEditDefaultIndention = 8;
+                ret = visualRect(
+                    opt->direction, opt->rect, opt->rect.adjusted(KLineEditDefaultIndention, 0, 0, 0));
             }
             break;
@@ -2733,7 +2918,7 @@
                 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
                     const int tabOverlapNoBorder =
-                        QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap);
+                        QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap);
                     const int tabOverlap =
-                        tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
+                        tabOverlapNoBorder - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
                     const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget);
                     int gain = (tab) ? tabOverlap * tab->count() : 0;
@@ -2784,6 +2969,6 @@
                     (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) {
                     const int verticalSpacing =
-                        QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
-                    //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+                        QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing);
+                    //const int horizontalSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing);
                     const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width();
                     ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0);
@@ -2797,7 +2982,11 @@
 
                 if (element == SE_ItemViewItemDecoration) {
-                    if (menuItem->direction == Qt::RightToLeft)
-                        ret.translate(ret.width()-indicatorWidth, 0);
-                    ret.setWidth(indicatorWidth);
+                    if (menuItem->icon.isNull()) {
+                        ret = QRect();
+                    } else {
+                        if (menuItem->direction == Qt::RightToLeft)
+                            ret.translate(ret.width() - indicatorWidth, 0);
+                        ret.setWidth(indicatorWidth);
+                    }
                 } else {
                     ret = menuItem->rect;
@@ -2820,5 +3009,5 @@
             break;
         case SE_ItemViewItemCheckIndicator:
-            if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+            if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
                 const QListWidget *listItem = qobject_cast<const QListWidget *>(widget);
 
@@ -2831,7 +3020,7 @@
 
                 // Selection check mark rect.
-                const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth);
-                const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight);
-                const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing);
+                const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth);
+                const int indicatorHeight = QS60StylePrivate::pixelMetric(PM_IndicatorHeight);
+                const int spacing = QS60StylePrivate::pixelMetric(PM_CheckBoxLabelSpacing);
 
                 const int itemHeight = opt->rect.height();
@@ -2859,7 +3048,7 @@
                 // Subtract area needed for line
                 if (opt->state & State_Horizontal)
-                    ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth));
+                    ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_BoldLineWidth));
                 else
-                    ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth));
+                    ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_ThinLineWidth));
                 }
             ret = visualRect(opt->direction, opt->rect, ret);
@@ -2967,9 +3156,11 @@
         widget->setPalette(QPalette());
 
-#ifndef QT_NO_PROGRESSBAR
+#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR)
     if (QProgressBar *bar = qobject_cast<QProgressBar *>(widget)) {
         widget->removeEventFilter(this);
         d->m_bars.removeAll(bar);
     }
+#else
+    Q_UNUSED(d)
 #endif
     QCommonStyle::unpolish(widget);
@@ -2982,6 +3173,9 @@
 {
     Q_D(QS60Style);
+    QCommonStyle::polish(qApp);
     d->m_originalPalette = application->palette();
     d->setThemePalette(application);
+    if (QS60StylePrivate::isTouchSupported())
+        qApp->installEventFilter(this);
 }
 
@@ -2992,8 +3186,12 @@
 {
     Q_UNUSED(application)
+
     Q_D(QS60Style);
+    QCommonStyle::unpolish(qApp);
     const QPalette newPalette = QApplication::style()->standardPalette();
     QApplication::setPalette(newPalette);
     QApplicationPrivate::setSystemPalette(d->m_originalPalette);
+    if (QS60StylePrivate::isTouchSupported())
+        qApp->removeEventFilter(this);
 }
 
@@ -3003,7 +3201,6 @@
 bool QS60Style::event(QEvent *e)
 {
+#ifdef QT_KEYPAD_NAVIGATION
     Q_D(QS60Style);
-
-#ifdef QT_KEYPAD_NAVIGATION
     const QEvent::Type eventType = e->type();
     if ((eventType == QEvent::FocusIn ||
@@ -3024,4 +3221,10 @@
     case QEvent::FocusIn:
         if (QWidget *focusWidget = QApplication::focusWidget()) {
+
+            // Menus and combobox popups do not draw focus frame around them
+            if (qobject_cast<QComboBoxListView *>(focusWidget) ||
+                qobject_cast<QMenu *>(focusWidget))
+                    break;
+
             if (!d->m_focusFrame)
                 d->m_focusFrame = new QFocusFrame(focusWidget);
@@ -3053,5 +3256,5 @@
     const QStyleOption *option, const QWidget *widget) const
 {
-    const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize);
+    const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize);
     const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect;
     QS60StyleEnums::SkinParts part;
@@ -3063,65 +3266,65 @@
 
     switch(standardIcon) {
-        case QStyle::SP_MessageBoxWarning:
+        case SP_MessageBoxWarning:
             part = QS60StyleEnums::SP_QgnNoteWarning;
             break;
-        case QStyle::SP_MessageBoxInformation:
+        case SP_MessageBoxInformation:
             part = QS60StyleEnums::SP_QgnNoteInfo;
             break;
-        case QStyle::SP_MessageBoxCritical:
+        case SP_MessageBoxCritical:
             part = QS60StyleEnums::SP_QgnNoteError;
             break;
-        case QStyle::SP_MessageBoxQuestion:
+        case SP_MessageBoxQuestion:
             part = QS60StyleEnums::SP_QgnNoteQuery;
             break;
-        case QStyle::SP_ArrowRight:
+        case SP_ArrowRight:
             part = QS60StyleEnums::SP_QgnIndiNaviArrowRight;
             break;
-        case QStyle::SP_ArrowLeft:
+        case SP_ArrowLeft:
             part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
             break;
-        case QStyle::SP_ArrowUp:
+        case SP_ArrowUp:
             part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
             adjustedFlags |= QS60StylePrivate::SF_PointEast;
             break;
-        case QStyle::SP_ArrowDown:
+        case SP_ArrowDown:
             part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
             adjustedFlags |= QS60StylePrivate::SF_PointWest;
             break;
-        case QStyle::SP_ArrowBack:
+        case SP_ArrowBack:
             if (QApplication::layoutDirection() == Qt::RightToLeft)
                 return QS60Style::standardIcon(SP_ArrowRight, option, widget);
             return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
-        case QStyle::SP_ArrowForward:
+        case SP_ArrowForward:
             if (QApplication::layoutDirection() == Qt::RightToLeft)
                 return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
             return QS60Style::standardIcon(SP_ArrowRight, option, widget);
-        case QStyle::SP_ComputerIcon:
+        case SP_ComputerIcon:
             part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge;
             break;
-        case QStyle::SP_DirClosedIcon:
+        case SP_DirClosedIcon:
             part = QS60StyleEnums::SP_QgnPropFolderSmall;
             break;
-        case QStyle::SP_DirOpenIcon:
+        case SP_DirOpenIcon:
             part = QS60StyleEnums::SP_QgnPropFolderCurrent;
             break;
-        case QStyle::SP_DirIcon:
+        case SP_DirIcon:
             part = QS60StyleEnums::SP_QgnPropFolderSmall;
             break;
-        case QStyle::SP_FileDialogNewFolder:
+        case SP_FileDialogNewFolder:
             part = QS60StyleEnums::SP_QgnPropFolderSmallNew;
             break;
-        case QStyle::SP_FileIcon:
+        case SP_FileIcon:
             part = QS60StyleEnums::SP_QgnPropFileSmall;
             break;
-        case QStyle::SP_TrashIcon:
+        case SP_TrashIcon:
             part = QS60StyleEnums::SP_QgnNoteErased;
             break;
-        case QStyle::SP_ToolBarHorizontalExtensionButton:
+        case SP_ToolBarHorizontalExtensionButton:
             part = QS60StyleEnums::SP_QgnIndiSubMenu;
             if (QApplication::layoutDirection() == Qt::RightToLeft)
                 adjustedFlags |= QS60StylePrivate::SF_PointSouth;
             break;
-        case QStyle::SP_ToolBarVerticalExtensionButton:
+        case SP_ToolBarVerticalExtensionButton:
             adjustedFlags |= QS60StylePrivate::SF_PointEast;
             part = QS60StyleEnums::SP_QgnIndiSubMenu;
@@ -3143,7 +3346,38 @@
 bool QS60Style::eventFilter(QObject *object, QEvent *event)
 {
+    Q_D(QS60Style);
+    switch(event->type()) {
+        case QEvent::MouseButtonPress: {
+            QWidget *w = QApplication::widgetAt(QCursor::pos());
+            if (w) {
+                QWidget *focusW = w->focusProxy();
+                if (qobject_cast<QAbstractItemView *>(focusW) ||
+                    qobject_cast<QRadioButton *>(focusW) ||
+                    qobject_cast<QCheckBox *>(focusW))
+                    d->m_pressedWidget = focusW;
+                else if (qobject_cast<QAbstractItemView *>(w)||
+                        qobject_cast<QRadioButton *>(w) ||
+                        qobject_cast<QCheckBox *>(w))
+                    d->m_pressedWidget = w;
+
+                if ( d->m_pressedWidget)
+                    d->m_pressedWidget->update();
+            }
+            break;
+        }
+        case QEvent::MouseButtonRelease: {
+            const QWidget *w = QApplication::widgetAt(QCursor::pos());
+            if (w && d->m_pressedWidget) {
+                d->m_pressedWidget->update();
+                d->m_pressedWidget = 0;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
 #ifdef Q_WS_S60
 #ifndef QT_NO_PROGRESSBAR
-    Q_D(QS60Style);
     switch(event->type()) {
     case QEvent::StyleChange:
@@ -3158,6 +3392,8 @@
     case QEvent::Destroy:
     case QEvent::Hide:
-        d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
-        d->m_bars.removeAll(reinterpret_cast<QProgressBar *>(object));
+        if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(object)) {
+            d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim);
+            d->m_bars.removeAll(bar);
+        }
         break;
     default:
@@ -3166,7 +3402,11 @@
 #endif // QT_NO_PROGRESSBAR
 #endif // Q_WS_S60
-    return QStyle::eventFilter(object, event);
-}
-
+    return QCommonStyle::eventFilter(object, event);
+}
+
+/*!
+    \internal
+    Handle the timer \a event.
+*/
 void QS60Style::timerEvent(QTimerEvent *event)
 {
Index: trunk/src/gui/styles/qs60style.h
===================================================================
--- trunk/src/gui/styles/qs60style.h	(revision 766)
+++ trunk/src/gui/styles/qs60style.h	(revision 769)
@@ -52,4 +52,14 @@
 
 #if !defined(QT_NO_STYLE_S60)
+
+//Public custom pixel metrics values.
+//These can be used to fetch custom pixel metric value from outside QS60Style.
+enum {
+    PM_FrameCornerWidth = QStyle::PM_CustomBase + 1,
+    PM_FrameCornerHeight,
+    PM_BoldLineWidth,
+    PM_ThinLineWidth,
+    PM_MessageBoxHeight
+    };
 
 class QS60StylePrivate;
Index: trunk/src/gui/styles/qs60style_p.h
===================================================================
--- trunk/src/gui/styles/qs60style_p.h	(revision 766)
+++ trunk/src/gui/styles/qs60style_p.h	(revision 769)
@@ -61,11 +61,6 @@
 
 const int MAX_NON_CUSTOM_PIXELMETRICS = 92;
-const int CUSTOMVALUESCOUNT = 4;
-enum {
-    PM_Custom_FrameCornerWidth = MAX_NON_CUSTOM_PIXELMETRICS,
-    PM_Custom_FrameCornerHeight,
-    PM_Custom_BoldLineWidth,
-    PM_Custom_ThinLineWidth
-    };
+const int CUSTOMVALUESCOUNT = 5;
+
 const int MAX_PIXELMETRICS = MAX_NON_CUSTOM_PIXELMETRICS + CUSTOMVALUESCOUNT;
 
@@ -75,5 +70,4 @@
     int major_version;
     int minor_version;
-    bool mirroring; // TODO: (nice to have) Use Qt::LayoutDirection
     const char* layoutName;
 } layoutHeader;
@@ -133,4 +127,5 @@
         SP_QgnGrafBarFrameSideR,
         SP_QgnGrafBarProgress,
+        SP_QgnGrafOrgBgGrid,
         SP_QgnGrafScrollArrowDown,
         SP_QgnGrafScrollArrowLeft,
@@ -299,4 +294,22 @@
         SP_QsnFrButtonSideRInactive,
         SP_QsnFrButtonCenterInactive,
+        SP_QsnFrGridCornerTlPressed, // Pressed table item
+        SP_QsnFrGridCornerTrPressed,
+        SP_QsnFrGridCornerBlPressed,
+        SP_QsnFrGridCornerBrPressed,
+        SP_QsnFrGridSideTPressed,
+        SP_QsnFrGridSideBPressed,
+        SP_QsnFrGridSideLPressed,
+        SP_QsnFrGridSideRPressed,
+        SP_QsnFrGridCenterPressed,
+        SP_QsnFrListCornerTlPressed,  // Pressed list item
+        SP_QsnFrListCornerTrPressed,
+        SP_QsnFrListCornerBlPressed,
+        SP_QsnFrListCornerBrPressed,
+        SP_QsnFrListSideTPressed,
+        SP_QsnFrListSideBPressed,
+        SP_QsnFrListSideLPressed,
+        SP_QsnFrListSideRPressed,
+        SP_QsnFrListPressed,
     };
 
@@ -354,10 +367,10 @@
     int currentFrame() const {return m_currentData->m_currentFrame;}
 
-    void setFrameCount(const int &frameCount) {m_currentData->m_frames = frameCount;}
-    void setInterval(const int &interval) {m_currentData->m_interval = interval;}
+    void setFrameCount(int frameCount) {m_currentData->m_frames = frameCount;}
+    void setInterval(int interval) {m_currentData->m_interval = interval;}
     void setAnimationObject(CAknBitmapAnimation* animation);
     void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;}
-    void setTimerId(const int &timerId) {m_currentData->m_timerId = timerId;}
-    void setCurrentFrame(const int &currentFrame) {m_currentData->m_currentFrame = currentFrame;}
+    void setTimerId(int timerId) {m_currentData->m_timerId = timerId;}
+    void setCurrentFrame(int currentFrame) {m_currentData->m_currentFrame = currentFrame;}
 
     void resetToDefaults();
@@ -417,5 +430,5 @@
         SE_TabBarTabWestInactive,
         SE_ListHighlight,
-        SE_OptionsMenu,
+        SE_PopupBackground,
         SE_SettingsList,
         SE_TableItem,
@@ -426,8 +439,11 @@
         SE_ToolBarButtonPressed,
         SE_PanelBackground,
-        SE_ScrollBarHandlePressedHorizontal, //only for 5.0+
+        SE_ScrollBarHandlePressedHorizontal,
         SE_ScrollBarHandlePressedVertical,
         SE_ButtonInactive,
         SE_Editor,
+        SE_DropArea,
+        SE_TableItemPressed,
+        SE_ListItemPressed,
     };
 
@@ -437,5 +453,5 @@
         SF_FrameLineEdit,
         SF_ListHighlight,
-        SF_OptionsMenu,
+        SF_PopupBackground,
         SF_SettingsList,
         SF_TableItem,
@@ -447,4 +463,6 @@
         SF_PanelBackground,
         SF_ButtonInactive,
+        SF_TableItemPressed,
+        SF_ListItemPressed,
     };
 
@@ -459,4 +477,6 @@
         SF_ColorSkinned =     0x0040, // pixmap is colored with foreground pen color
         SF_Animation =        0x0080,
+        SF_Mirrored_X_Axis =  0x0100,
+        SF_Mirrored_Y_Axis =  0x0200
     };
 
@@ -501,4 +521,5 @@
     static bool hasSliderGrooveGraphic();
     static bool isSingleClickUi();
+    static bool isWidgetPressed(const QWidget *widget);
 
     // calculates average color based on button skin graphics (minus borders).
@@ -542,5 +563,5 @@
     //Checks that the current brush is transparent or has BrushStyle NoBrush,
     //so that theme graphic background can be drawn.
-    static bool canDrawThemeBackground(const QBrush &backgroundBrush);
+    static bool canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget);
 
     static int currentAnimationFrame(QS60StyleEnums::SkinParts part);
@@ -596,4 +617,7 @@
 
     QPointer<QFocusFrame> m_focusFrame;
+    static qint64 m_webPaletteKey;
+
+    static QPointer<QWidget> m_pressedWidget;
 
 #ifdef Q_WS_S60
Index: trunk/src/gui/styles/qs60style_s60.cpp
===================================================================
--- trunk/src/gui/styles/qs60style_s60.cpp	(revision 766)
+++ trunk/src/gui/styles/qs60style_s60.cpp	(revision 769)
@@ -51,15 +51,15 @@
 
 #include <w32std.h>
-#include <aknsconstants.h>
+#include <AknsConstants.h>
 #include <aknconsts.h>
-#include <aknsitemid.h>
-#include <aknsutils.h>
-#include <aknsdrawutils.h>
-#include <aknsskininstance.h>
-#include <aknsbasicbackgroundcontrolcontext.h>
+#include <AknsItemID.h>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <AknsSkinInstance.h>
+#include <AknsBasicBackgroundControlContext.h>
 #include <avkon.mbg>
 #include <AknFontAccess.h>
 #include <AknLayoutFont.h>
-#include <aknutils.h>
+#include <AknUtils.h>
 #include <aknnavi.h>
 #include <gulicon.h>
@@ -106,5 +106,5 @@
 
 AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval),
-    m_resourceBased(false), m_animation(0), m_timerId(0)
+    m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0)
 {
 }
@@ -179,4 +179,6 @@
     /* SP_QgnGrafBarFrameSideR */          {KAknsIIDQgnGrafBarFrameSideR,          EDrawIcon,   ES60_All,    -1,-1},
     /* SP_QgnGrafBarProgress */            {KAknsIIDQgnGrafBarProgress,            EDrawIcon,   ES60_All,    -1,-1},
+    // No drop area for 3.x non-touch devices
+    /* SP_QgnGrafOrgBgGrid */              {KAknsIIDNone,                          EDrawIcon,   ES60_3_X,    EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid   
     /* SP_QgnGrafScrollArrowDown */        {KAknsIIDQgnGrafScrollArrowDown,     EDrawGulIcon,   ES60_All,    -1,-1},
     /* SP_QgnGrafScrollArrowLeft */        {KAknsIIDQgnGrafScrollArrowLeft,     EDrawGulIcon,   ES60_All,    -1,-1},
@@ -309,5 +311,5 @@
     /* SP_QsnFrPopupSideL */            {KAknsIIDQsnFrPopupSideL,               ENoDraw,     ES60_All,    -1,-1},
     /* SP_QsnFrPopupSideR */            {KAknsIIDQsnFrPopupSideR,               ENoDraw,     ES60_All,    -1,-1},
-    /* SP_QsnFrPopupCenter */           {KAknsIIDQsnFrPopupCenter,              ENoDraw,     ES60_All,    -1,-1},
+    /* SP_QsnFrPopupCenter */           {KAknsIIDQsnFrPopupCenterSubmenu,       ENoDraw,     ES60_All,    -1,-1},
 
     // ToolTip graphics different in 3.1 vs. 3.2+.
@@ -376,4 +378,25 @@
     /* SP_QsnFrButtonCenterInactive */   {KAknsIIDQsnFrButtonTbCenter,          EDrawIcon,   ES60_3_X,    EAknsMajorSkin, 0x21b9},
 
+    // No pressed down grid in 3.1/3.2
+    /* SP_QsnFrGridCornerTlPressed */    {KAknsIIDQsnFrGridCornerTl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2681}, /*KAknsIIDQsnFrGridCornerTlPressed*/
+    /* SP_QsnFrGridCornerTrPressed */    {KAknsIIDQsnFrGridCornerTr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2682},
+    /* SP_QsnFrGridCornerBlPressed */    {KAknsIIDQsnFrGridCornerBl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2683},
+    /* SP_QsnFrGridCornerBrPressed */    {KAknsIIDQsnFrGridCornerBr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2684},
+    /* SP_QsnFrGridSideTPressed */       {KAknsIIDQsnFrGridSideT,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2685},
+    /* SP_QsnFrGridSideBPressed */       {KAknsIIDQsnFrGridSideB,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2686},
+    /* SP_QsnFrGridSideLPressed */       {KAknsIIDQsnFrGridSideL,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2687},
+    /* SP_QsnFrGridSideRPressed */       {KAknsIIDQsnFrGridSideR,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2688},
+    /* SP_QsnFrGridCenterPressed */      {KAknsIIDQsnFrGridCenter,      ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2689},
+
+    // No pressed down list in 3.1/3.2
+    /* SP_QsnFrListCornerTlPressed */    {KAknsIIDQsnFrListCornerTl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268b}, /*KAknsIIDQsnFrListCornerTlPressed*/
+    /* SP_QsnFrListCornerTrPressed */    {KAknsIIDQsnFrListCornerTr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268c},
+    /* SP_QsnFrListCornerBlPressed */    {KAknsIIDQsnFrListCornerBl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268d},
+    /* SP_QsnFrListCornerBrPressed */    {KAknsIIDQsnFrListCornerBr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268e},
+    /* SP_QsnFrListSideTPressed */       {KAknsIIDQsnFrListSideT,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268f},
+    /* SP_QsnFrListSideBPressed */       {KAknsIIDQsnFrListSideB,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2690},
+    /* SP_QsnFrListSideLPressed */       {KAknsIIDQsnFrListSideL,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2691},
+    /* SP_QsnFrListSideRPressed */       {KAknsIIDQsnFrListSideR,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2692},
+    /* SP_QsnFrListPressed */            {KAknsIIDQsnFrList,            ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2693},
 };
 
@@ -632,4 +655,12 @@
         pixmap = QPixmap::fromImage(iconImage);
     }
+    if ((flags & QS60StylePrivate::SF_Mirrored_X_Axis) ||
+        (flags & QS60StylePrivate::SF_Mirrored_Y_Axis)) {
+        QImage iconImage = pixmap.toImage().mirrored(
+            flags & QS60StylePrivate::SF_Mirrored_X_Axis,
+            flags & QS60StylePrivate::SF_Mirrored_Y_Axis);
+        pixmap = QPixmap::fromImage(iconImage);
+    }
+
     return pixmap;
 }
@@ -754,5 +785,5 @@
             if (drawn)
                 result = fromFbsBitmap(background, NULL, flags, targetSize);
-            // if drawing fails in skin server, just ignore the background (probably OOM occured)
+            // if drawing fails in skin server, just ignore the background (probably OOM case)
 
             CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext
@@ -786,5 +817,5 @@
             const int currentFrame = QS60StylePrivate::currentAnimationFrame(part);
             if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
-                //Animation was created succesfully and contains frames, just fetch current frame
+                //Animation was created successfully and contains frames, just fetch current frame
                 if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count())
                     User::Leave(KErrOverflow);
@@ -858,9 +889,7 @@
     CleanupStack::PushL(bitmapGc);
 
-#ifndef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
     frame->LockHeap();
     memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4);  // 4: argb bytes
     frame->UnlockHeap();
-#endif
 
     const TRect outerRect(TPoint(0, 0), targetSize);
@@ -899,5 +928,5 @@
         }
     } else {
-        TDisplayMode maskDepth = EGray2;
+        TDisplayMode maskDepth = EGray256;
         // Query the skin item for possible frame graphics mask details.
         if (skinInstance) {
@@ -949,5 +978,5 @@
     switch(frameElement) {
         case QS60StylePrivate::SF_ToolTip:
-            if (QSysInfo::s60Version()!=QSysInfo::SV_S60_3_1) {
+            if (QSysInfo::s60Version() != QSysInfo::SV_S60_3_1) {
                 centerId.Set(EAknsMajorGeneric, 0x19c2);
                 frameId.Set(EAknsMajorSkin, 0x5300);
@@ -958,8 +987,13 @@
             break;
         case QS60StylePrivate::SF_ToolBar:
-            if (QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 || QSysInfo::s60Version()==QSysInfo::SV_S60_3_2) {
+            if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || 
+                QSysInfo::s60Version() == QSysInfo::SV_S60_3_2) {
                 centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
                 frameId.Set(KAknsIIDQsnFrPopupSub);
             }
+            break;
+        case QS60StylePrivate::SF_PopupBackground:
+            centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
+            frameId.Set(KAknsIIDQsnFrPopupSub);
             break;
         case QS60StylePrivate::SF_PanelBackground:
@@ -977,19 +1011,23 @@
 TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect)
 {
-    TInt widthShrink = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth);
-    TInt heightShrink = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerHeight);
+    TInt widthShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
+    TInt heightShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerHeight);
     switch(frameElement) {
         case QS60StylePrivate::SF_PanelBackground:
             // panel should have slightly slimmer border to enable thin line of background graphics between closest component
-            widthShrink = widthShrink-2;
-            heightShrink = heightShrink-2;
+            widthShrink = widthShrink - 2;
+            heightShrink = heightShrink - 2;
             break;
         case QS60StylePrivate::SF_ToolTip:
-            widthShrink = widthShrink>>1;
-            heightShrink = heightShrink>>1;
+            widthShrink = widthShrink >> 1;
+            heightShrink = heightShrink >> 1;
             break;
         case QS60StylePrivate::SF_ListHighlight:
-            widthShrink = widthShrink-2;
-            heightShrink = heightShrink-2;
+            widthShrink = widthShrink - 2;
+            heightShrink = heightShrink - 2;
+            break;
+        case QS60StylePrivate::SF_PopupBackground:
+            widthShrink = widthShrink + 5;
+            heightShrink = heightShrink + 5;
             break;
         default:
@@ -1095,5 +1133,5 @@
     }
 
-    m_pmPointer = data[activeLayoutIndex];
+    setCurrentLayout(activeLayoutIndex);
 }
 
@@ -1120,5 +1158,5 @@
         &KAknsIIDQsnTextColors
     };
-    Q_ASSERT((int)list <= (int)sizeof(idMap)/sizeof(idMap[0]));
+    Q_ASSERT((int)list < (int)sizeof(idMap)/sizeof(idMap[0]));
     const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1);
     return option ? QS60StylePrivate::stateColor(color, option) : color;
Index: trunk/src/gui/styles/qstylesheetstyle.cpp
===================================================================
--- trunk/src/gui/styles/qstylesheetstyle.cpp	(revision 766)
+++ trunk/src/gui/styles/qstylesheetstyle.cpp	(revision 769)
@@ -1534,5 +1534,7 @@
     if (defaultCacheIt == styleSheetCache->constEnd()) {
         defaultSs = getDefaultStyleSheet();
-        styleSheetCache->insert(baseStyle(), defaultSs);
+        QStyle *bs = baseStyle();
+        styleSheetCache->insert(bs, defaultSs);
+        QObject::connect(bs, SIGNAL(destroyed(QObject*)), this, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
     } else {
         defaultSs = defaultCacheIt.value();
@@ -2659,4 +2661,9 @@
     styleSheetCache->remove((const QWidget *)o);
     autoFillDisabledWidgets->remove((const QWidget *)o);
+}
+
+void QStyleSheetStyle::styleDestroyed(QObject *o)
+{
+    styleSheetCache->remove(o);
 }
 
@@ -4243,6 +4250,13 @@
             const QAbstractScrollAreaPrivate *sap = sa->d_func();
             rule.drawBackground(p, opt->rect, sap->contentsOffset());
-            if (rule.hasBorder())
-                rule.drawBorder(p, rule.borderRect(opt->rect));
+            if (rule.hasBorder()) {
+                QRect brect = rule.borderRect(opt->rect);
+                if (styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, opt, w)) {
+                    QRect r = brect.adjusted(0, 0, sa->verticalScrollBar()->isVisible() ? -sa->verticalScrollBar()->width() : 0,
+                                             sa->horizontalScrollBar()->isVisible() ? -sa->horizontalScrollBar()->height() : 0);
+                    brect = QStyle::visualRect(opt->direction, brect, r);
+                }
+                rule.drawBorder(p, brect);
+            }
             break;
         }
@@ -4628,4 +4642,9 @@
             return msz.width() == -1 ? msz.height() : msz.width();
         }
+        break;
+
+    case PM_ScrollView_ScrollBarSpacing:
+        if(!rule.hasNativeBorder() || rule.hasBox())
+            return 0;
         break;
 #endif // QT_NO_SCROLLBAR
@@ -5744,4 +5763,11 @@
                                    }
 
+#ifndef QT_NO_TOOLBAR
+    case SE_ToolBarHandle:
+        if (hasStyleRule(w, PseudoElement_ToolBarHandle))
+            return ParentStyle::subElementRect(se, opt, w);
+        break;
+#endif //QT_NO_TOOLBAR
+
     default:
         break;
Index: trunk/src/gui/styles/qstylesheetstyle_p.h
===================================================================
--- trunk/src/gui/styles/qstylesheetstyle_p.h	(revision 766)
+++ trunk/src/gui/styles/qstylesheetstyle_p.h	(revision 769)
@@ -148,4 +148,5 @@
 private Q_SLOTS:
     void widgetDestroyed(QObject *);
+    void styleDestroyed(QObject *);
 
 private:
Index: trunk/src/gui/styles/qwindowsmobilestyle.cpp
===================================================================
--- trunk/src/gui/styles/qwindowsmobilestyle.cpp	(revision 766)
+++ trunk/src/gui/styles/qwindowsmobilestyle.cpp	(revision 769)
@@ -4041,23 +4041,24 @@
 void QWindowsMobileStylePrivate::tintImagesButton(QColor color)
 {
-       if (currentTintButton == color)
+    if (currentTintButton == color)
         return;
-
-       imageTabEnd = QImage(tabend_xpm);
-       imageTabSelectedEnd = QImage(tabselectedend_xpm);
-       imageTabSelectedBegin = QImage(tabselectedbeginn_xpm);
-       imageTabMiddle = QImage(tabmiddle_xpm);
-       tintImage(&imageTabEnd, color, 0.0);
-       tintImage(&imageTabSelectedEnd, color, 0.0);
-       tintImage(&imageTabSelectedBegin, color, 0.0);
-       tintImage(&imageTabMiddle, color, 0.0);
-
-       if (!doubleControls) {
-           int height = imageTabMiddle.height() / 2 + 1;
-           imageTabEnd = imageTabEnd.scaledToHeight(height);
-           imageTabMiddle = imageTabMiddle.scaledToHeight(height);
-           imageTabSelectedEnd = imageTabSelectedEnd.scaledToHeight(height);
-           imageTabSelectedBegin = imageTabSelectedBegin.scaledToHeight(height);
-       }
+    currentTintButton = color;
+
+    imageTabEnd = QImage(tabend_xpm);
+    imageTabSelectedEnd = QImage(tabselectedend_xpm);
+    imageTabSelectedBegin = QImage(tabselectedbeginn_xpm);
+    imageTabMiddle = QImage(tabmiddle_xpm);
+    tintImage(&imageTabEnd, color, 0.0);
+    tintImage(&imageTabSelectedEnd, color, 0.0);
+    tintImage(&imageTabSelectedBegin, color, 0.0);
+    tintImage(&imageTabMiddle, color, 0.0);
+
+    if (!doubleControls) {
+        int height = imageTabMiddle.height() / 2 + 1;
+        imageTabEnd = imageTabEnd.scaledToHeight(height);
+        imageTabMiddle = imageTabMiddle.scaledToHeight(height);
+        imageTabSelectedEnd = imageTabSelectedEnd.scaledToHeight(height);
+        imageTabSelectedBegin = imageTabSelectedBegin.scaledToHeight(height);
+    }
 }
 
@@ -5076,4 +5077,8 @@
                 QImage image;
                 int xoffset, yoffset;
+                bool isTabBarArrow = widget && widget->parent()
+                                   && widget->inherits("QToolButton")
+                                   && widget->parent()->inherits("QTabBar");
+
                 switch (element) {
                     case PE_IndicatorArrowUp:
@@ -5090,10 +5095,10 @@
                           image = d->imageArrowLeft;
                           xoffset = 8;
-                          yoffset = 2;
+                          yoffset = isTabBarArrow ? 12 : 2;
                           break;
                     case PE_IndicatorArrowRight:
                           image = d->imageArrowRight;
                           xoffset = 8;
-                          yoffset = 2;
+                          yoffset = isTabBarArrow ? 12 : 2;
                           break;
                      case PE_IndicatorArrowUpBig:
@@ -5352,4 +5357,48 @@
         painter->drawLines(a);
         break; }
+    case PE_IndicatorBranch: {
+        // Copied from the Windows style.
+        static const int decoration_size = d->doubleControls ? 18 : 9;
+        static const int ofsA  = d->doubleControls ?  4 : 2;
+        static const int ofsB  = d->doubleControls ?  8 : 4;
+        static const int ofsC  = d->doubleControls ? 12 : 6;
+        static const int ofsD  = d->doubleControls ? 1 : 0;
+        int mid_h = option->rect.x() + option->rect.width() / 2;
+        int mid_v = option->rect.y() + option->rect.height() / 2;
+        int bef_h = mid_h;
+        int bef_v = mid_v;
+        int aft_h = mid_h;
+        int aft_v = mid_v;
+        if (option->state & State_Children) {
+            int delta = decoration_size / 2;
+            bef_h -= delta;
+            bef_v -= delta;
+            aft_h += delta;
+            aft_v += delta;
+            QPen oldPen = painter->pen();
+            QPen crossPen = oldPen;
+            crossPen.setWidth(2);
+            painter->setPen(crossPen);
+            painter->drawLine(bef_h + ofsA + ofsD, bef_v + ofsB + ofsD, bef_h + ofsC + ofsD, bef_v + ofsB + ofsD);
+            if (!(option->state & State_Open))
+                painter->drawLine(bef_h + ofsB + ofsD, bef_v + ofsA + ofsD, bef_h + ofsB + ofsD, bef_v + ofsC + ofsD);
+            painter->setPen(option->palette.dark().color());
+            painter->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1);
+            if (d->doubleControls)
+                painter->drawRect(bef_h + 1, bef_v + 1, decoration_size - 3, decoration_size - 3);
+            painter->setPen(oldPen);
+        }
+        QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+        if (option->state & State_Item) {
+            if (option->direction == Qt::RightToLeft)
+                painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+            else
+                painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+        }
+        if (option->state & State_Sibling)
+            painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+        if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
+            painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+        break; }
     case PE_Frame:
         qDrawPlainRect(painter, option->rect, option->palette.shadow().color(),
@@ -6949,8 +6998,9 @@
         ret = d->doubleControls ? windowsMobileSliderThickness * 2: windowsMobileSliderThickness;
         break;
-     case PM_TabBarScrollButtonWidth:
-         ret = d->doubleControls ? 14 * 2 : 18;
-      case PM_CheckBoxLabelSpacing:
-      case PM_RadioButtonLabelSpacing:
+    case PM_TabBarScrollButtonWidth:
+        ret = d->doubleControls ? 14 * 2 : 18;
+        break;
+    case PM_CheckBoxLabelSpacing:
+    case PM_RadioButtonLabelSpacing:
         ret = d->doubleControls ? 6 * 2 : 6;
         break;
Index: trunk/src/gui/styles/styles.pri
===================================================================
--- trunk/src/gui/styles/styles.pri	(revision 766)
+++ trunk/src/gui/styles/styles.pri	(revision 769)
@@ -165,16 +165,16 @@
 
 contains( styles, s60 ):contains(QT_CONFIG, s60) {
-	HEADERS += \
-		styles/qs60style.h \
-		styles/qs60style_p.h
-	SOURCES += styles/qs60style.cpp
-	symbian {
-		SOURCES += styles/qs60style_s60.cpp
-		LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul -lbmpanim
-	} else {
-		SOURCES += styles/qs60style_simulated.cpp
-		RESOURCES += styles/qstyle_s60_simulated.qrc
-	}
+    HEADERS += \
+        styles/qs60style.h \
+        styles/qs60style_p.h
+    SOURCES += styles/qs60style.cpp
+    symbian {
+        SOURCES += styles/qs60style_s60.cpp
+        LIBS += -lAknIcon -lAKNSKINS -lAKNSKINSRV -lFontUtils -legul -lbmpanim
+    } else {
+        SOURCES += styles/qs60style_simulated.cpp
+        RESOURCES += styles/qstyle_s60_simulated.qrc
+    }
 } else {
-	DEFINES += QT_NO_STYLE_S60
+    DEFINES += QT_NO_STYLE_S60
 }
Index: trunk/src/gui/text/qcssparser.cpp
===================================================================
--- trunk/src/gui/text/qcssparser.cpp	(revision 766)
+++ trunk/src/gui/text/qcssparser.cpp	(revision 769)
@@ -896,5 +896,5 @@
         *width = lengthValueFromData(data.width, f);
         *style = data.style;
-        *color = brushFromData(data.color, pal);
+        *color = data.color.type != BrushData::Invalid ? brushFromData(data.color, pal) : QBrush(QColor());
         return;
     }
Index: trunk/src/gui/text/qfont.cpp
===================================================================
--- trunk/src/gui/text/qfont.cpp	(revision 766)
+++ trunk/src/gui/text/qfont.cpp	(revision 769)
@@ -646,6 +646,7 @@
     Returns the name of the font within the underlying window system.
 
-    Only on X11 when Qt was built without FontConfig support the XLFD (X Logical Font Description)
-    is returned; otherwise an empty string.
+    On X11, this function will return an empty string if Qt is built with
+    FontConfig support; otherwise the XLFD (X Logical Font Description) is
+    returned.
 
     Using the return value of this function is usually \e not \e
@@ -820,4 +821,7 @@
         resolve_mask |= QFont::WeightResolved | QFont::StyleResolved;
     }
+
+    if (italic)
+        resolve_mask |= QFont::StyleResolved;
 
     d->request.family = family;
@@ -2641,4 +2645,5 @@
 QFontCache::~QFontCache()
 {
+    clear();
     {
         EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
Index: trunk/src/gui/text/qfontdatabase.cpp
===================================================================
--- trunk/src/gui/text/qfontdatabase.cpp	(revision 766)
+++ trunk/src/gui/text/qfontdatabase.cpp	(revision 769)
@@ -87,5 +87,5 @@
 #define SMOOTH_SCALABLE 0xffff
 
-extern int qt_defaultDpiY(); // in qfont.cpp
+Q_GUI_EXPORT extern int qt_defaultDpiY(); // in qfont.cpp
 
 bool qt_enable_test_font = false;
@@ -611,8 +611,8 @@
 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
 // class with virtual destructor, derived in qfontdatabase_s60.cpp
-class QFontDatabaseS60Store
+class QSymbianFontDatabaseExtras
 {
 public:
-    virtual ~QFontDatabaseS60Store() {}
+    virtual ~QSymbianFontDatabaseExtras() {}
 };
 #endif
@@ -630,5 +630,5 @@
 #endif
 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
-          , s60Store(0)
+          , symbianExtras(0)
 #endif
     { }
@@ -644,7 +644,7 @@
         count = 0;
 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
-        if (s60Store) {
-            delete s60Store;
-            s60Store = 0;
+        if (symbianExtras) {
+            delete symbianExtras;
+            symbianExtras = 0;
         }
 #endif
@@ -691,5 +691,5 @@
     QStringList fallbackFamilies;
 #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
-    const QFontDatabaseS60Store *s60Store;
+    const QSymbianFontDatabaseExtras *symbianExtras;
 #endif
 
Index: trunk/src/gui/text/qfontdatabase_s60.cpp
===================================================================
--- trunk/src/gui/text/qfontdatabase_s60.cpp	(revision 766)
+++ trunk/src/gui/text/qfontdatabase_s60.cpp	(revision 769)
@@ -51,5 +51,5 @@
 #include <private/qcore_symbian_p.h>
 #if defined(QT_NO_FREETYPE)
-#include <OPENFONT.H>
+#include <openfont.h>
 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
 #include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file
@@ -93,11 +93,11 @@
 
 #if defined(QT_NO_FREETYPE)
-class QFontDatabaseS60StoreImplementation : public QFontDatabaseS60Store
+class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
 {
 public:
-    QFontDatabaseS60StoreImplementation();
-    ~QFontDatabaseS60StoreImplementation();
-
-    const QFontEngineS60Extensions *extension(const QString &typeface) const;
+    QSymbianFontDatabaseExtrasImplementation();
+    ~QSymbianFontDatabaseExtrasImplementation();
+
+    const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
 
 private:
@@ -105,10 +105,19 @@
     CFontStore *m_store;
     COpenFontRasterizer *m_rasterizer;
-    mutable QHash<QString, const QFontEngineS60Extensions *> m_extensions;
+    mutable QList<const QSymbianTypeFaceExtras *> m_extras;
+    mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
 };
 
-QFontDatabaseS60StoreImplementation::QFontDatabaseS60StoreImplementation()
-{
-    m_heap = User::ChunkHeap(NULL, 0x1000, 0x100000);
+QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
+{
+    QStringList filters;
+    filters.append(QLatin1String("*.ttf"));
+    filters.append(QLatin1String("*.ccc"));
+    filters.append(QLatin1String("*.ltt"));
+    const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters);
+
+    const TInt heapMinLength = 0x1000;
+    const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength);
+    m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength);
     QT_TRAP_THROWING(
         m_store = CFontStore::NewL(m_heap);
@@ -118,8 +127,4 @@
         CleanupStack::Pop(m_rasterizer););
 
-    QStringList filters;
-    filters.append(QString::fromLatin1("*.ttf"));
-    filters.append(QString::fromLatin1("*.ccc"));
-    const QFileInfoList fontFiles = alternativeFilePaths(QString::fromLatin1("resource\\Fonts"), filters);
     foreach (const QFileInfo &fontFileInfo, fontFiles) {
         const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
@@ -128,8 +133,9 @@
     }
 }
-QFontDatabaseS60StoreImplementation::~QFontDatabaseS60StoreImplementation()
-{
-    typedef QHash<QString, const QFontEngineS60Extensions *>::iterator iterator;
-    for (iterator p = m_extensions.begin(); p != m_extensions.end(); ++p) {
+
+QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
+{
+    typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
+    for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) {
         m_store->ReleaseFont((*p)->fontOwner());
         delete *p;
@@ -157,11 +163,16 @@
 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM
 
-const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(const QString &typeface) const
-{
-    if (!m_extensions.contains(typeface)) {
+const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface,
+                                                                               bool bold, bool italic) const
+{
+    const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
+    if (!m_extrasHash.contains(searchKey)) {
         CFont* font = NULL;
-        TFontSpec spec(qt_QString2TPtrC(typeface), 1);
-        spec.iHeight = 1;
-        const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, spec);
+        TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
+        if (bold)
+            searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
+        if (italic)
+            searchSpec.iFontStyle.SetPosture(EPostureItalic);
+        const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
         Q_ASSERT(err == KErrNone && font);
         const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
@@ -172,7 +183,18 @@
             OpenFontFromBitmapFont(bitmapFont);
 #endif // FNTSTORE_H_INLINES_SUPPORT_FMM
-        m_extensions.insert(typeface, new QFontEngineS60Extensions(font, openFont));
-    }
-    return m_extensions.value(typeface);
+        const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
+        const QString foundKey =
+                QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
+        if (!m_extrasHash.contains(foundKey)) {
+            QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
+            m_extras.append(extras);
+            m_extrasHash.insert(searchKey, extras);
+            m_extrasHash.insert(foundKey, extras);
+        } else {
+            m_store->ReleaseFont(font);
+            m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey));
+        }
+    }
+    return m_extrasHash.value(searchKey);
 }
 #else
@@ -241,12 +263,12 @@
 
 #if defined(QT_NO_FREETYPE)
-    if (!db->s60Store)
-        db->s60Store = new QFontDatabaseS60StoreImplementation;
+    if (!db->symbianExtras)
+        db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
 
     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
     
     const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
-    const QFontDatabaseS60StoreImplementation *store =
-            static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
+    const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+            static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
     bool fontAdded = false;
     for (int i = 0; i < numTypeFaces; i++) {
@@ -274,6 +296,7 @@
             style->pixelSize(0, true);
 
-            const QFontEngineS60Extensions *extension = store->extension(familyName);
-            const QByteArray os2Table = extension->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
+            const QSymbianTypeFaceExtras *typeFaceExtras =
+                    dbExtras->extras(familyName, faceAttrib.IsBold(), faceAttrib.IsItalic());
+            const QByteArray os2Table = typeFaceExtras->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
             const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData());
             const unsigned char* ulUnicodeRange = data + 42;
@@ -333,4 +356,9 @@
 }
 
+bool QFontDatabase::removeAllApplicationFonts()
+{
+    return false;
+}
+
 bool QFontDatabase::supportsThreadedFontRendering()
 {
@@ -390,8 +418,9 @@
         request.family = fontFamily;
 #if defined(QT_NO_FREETYPE)
-        const QFontDatabaseS60StoreImplementation *store =
-                static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
-        const QFontEngineS60Extensions *extension = store->extension(fontFamily);
-        fe = new QFontEngineS60(request, extension);
+        const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+                static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
+        const QSymbianTypeFaceExtras *typeFaceExtras =
+                dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal);
+        fe = new QFontEngineS60(request, typeFaceExtras);
 #else
         QFontEngine::FaceId faceId;
Index: trunk/src/gui/text/qfontdatabase_win.cpp
===================================================================
--- trunk/src/gui/text/qfontdatabase_win.cpp	(revision 766)
+++ trunk/src/gui/text/qfontdatabase_win.cpp	(revision 769)
@@ -337,6 +337,16 @@
             };
             QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
-            for (int i = 0; i < systems.count(); ++i)
-                family->writingSystems[systems.at(i)] = QtFontFamily::Supported;
+
+            for (int i = 0; i < systems.count(); ++i) {
+                QFontDatabase::WritingSystem writingSystem = systems.at(i);
+
+                // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains
+                // the symbol for Baht, and Windows thus reports that it supports the Thai script.
+                // Since it's the default UI font on this platform, most widgets will be unable to
+                // display Thai text by default. As a temporary work around, we special case Segoe UI
+                // and remove the Thai script from its list of supported writing systems.
+                if (writingSystem != QFontDatabase::Thai || familyName != QLatin1String("Segoe UI"))
+                    family->writingSystems[writingSystem] = QtFontFamily::Supported;
+            }
         } else if (!family->writingSystemCheck) {
             //qDebug("family='%s' script=%s", family->name.latin1(), script.latin1());
Index: trunk/src/gui/text/qfontengine.cpp
===================================================================
--- trunk/src/gui/text/qfontengine.cpp	(revision 766)
+++ trunk/src/gui/text/qfontengine.cpp	(revision 769)
@@ -358,7 +358,4 @@
             }
         } else {
-            positions.resize(glyphs.numGlyphs);
-            glyphs_out.resize(glyphs.numGlyphs);
-            int i = 0;
             while (i < glyphs.numGlyphs) {
                 if (!glyphs.attributes[i].dontPrint) {
@@ -383,4 +380,13 @@
 }
 
+void QFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+    glyph_metrics_t gi = boundingBox(glyph);
+    bool isValid = gi.isValid();
+    if (leftBearing != 0)
+        *leftBearing = isValid ? gi.x.toReal() : 0.0;
+    if (rightBearing != 0)
+        *rightBearing = isValid ? (gi.xoff - gi.x - gi.width).toReal() : 0.0;
+}
 
 glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs)
@@ -1389,4 +1395,10 @@
 }
 
+void QFontEngineMulti::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+    int which = highByte(glyph);
+    engine(which)->getGlyphBearings(stripped(glyph), leftBearing, rightBearing);
+}
+
 void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
                                         QPainterPath *path, QTextItem::RenderFlags flags)
Index: trunk/src/gui/text/qfontengine_p.h
===================================================================
--- trunk/src/gui/text/qfontengine_p.h	(revision 766)
+++ trunk/src/gui/text/qfontengine_p.h	(revision 769)
@@ -207,4 +207,6 @@
     virtual qreal minRightBearing() const { return qreal(); }
 
+    virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
+
     virtual const char *name() const = 0;
 
@@ -375,4 +377,5 @@
     virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
     virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags);
+    virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
 
     virtual QFixed ascent() const;
Index: trunk/src/gui/text/qfontengine_s60.cpp
===================================================================
--- trunk/src/gui/text/qfontengine_s60.cpp	(revision 766)
+++ trunk/src/gui/text/qfontengine_s60.cpp	(revision 769)
@@ -45,5 +45,5 @@
 #include <private/qapplication_p.h>
 #include "qimage.h"
-#include "qt_s60_p.h"
+#include <private/qt_s60_p.h>
 
 #include <e32base.h>
@@ -54,5 +54,5 @@
 QT_BEGIN_NAMESPACE
 
-QFontEngineS60Extensions::QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font)
+QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font)
     : m_font(font)
     , m_cmap(0)
@@ -60,14 +60,11 @@
     , m_fontOwner(fontOwner)
 {
-    TAny *shapingExtension = NULL;
-    m_font->ExtendedInterface(KUidOpenFontShapingExtension, shapingExtension);
-    m_shapingExtension = static_cast<MOpenFontShapingExtension*>(shapingExtension);
     TAny *trueTypeExtension = NULL;
     m_font->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension);
     m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension);
-    Q_ASSERT(m_shapingExtension && m_trueTypeExtension);
-}
-
-QByteArray QFontEngineS60Extensions::getSfntTable(uint tag) const
+    Q_ASSERT(m_trueTypeExtension);
+}
+
+QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const
 {
     Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag));
@@ -80,5 +77,30 @@
 }
 
-const unsigned char *QFontEngineS60Extensions::cmap() const
+bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+    if (!m_trueTypeExtension->HasTrueTypeTable(tag))
+        return false;
+
+    bool result = true;
+    TInt error = KErrNone;
+    TInt tableByteLength;
+    TAny *table =
+        q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength));
+
+    if (error != KErrNone) {
+        return false;
+    } else if (*length > 0 && *length < tableByteLength) {
+        result = false; // Caller did not allocate enough memory
+    } else {
+        *length = tableByteLength;
+        if (buffer)
+            qMemCopy(buffer, table, tableByteLength);
+    }
+
+    m_trueTypeExtension->ReleaseTrueTypeTable(table);
+    return result;
+}
+
+const unsigned char *QSymbianTypeFaceExtras::cmap() const
 {
     if (!m_cmap) {
@@ -90,25 +112,5 @@
 }
 
-QPainterPath QFontEngineS60Extensions::glyphOutline(glyph_t glyph) const
-{
-    QPainterPath result;
-    QPolygonF polygon;
-    TInt glyphIndex = glyph;
-    TInt pointNumber = 0;
-    TInt x, y;
-    while (m_shapingExtension->GlyphPointInFontUnits(glyphIndex, pointNumber++, x, y)) {
-        const QPointF point(qreal(x) / 0xffff, qreal(y) / 0xffff);
-        if (polygon.contains(point)) {
-            result.addPolygon(polygon);
-            result.closeSubpath();
-            polygon.clear();
-        } else {
-            polygon.append(point);
-        }
-    }
-    return result;
-}
-
-CFont *QFontEngineS60Extensions::fontOwner() const
+CFont *QSymbianTypeFaceExtras::fontOwner() const
 {
     return m_fontOwner;
@@ -168,6 +170,6 @@
 }
 
-QFontEngineS60::QFontEngineS60(const QFontDef &request, const QFontEngineS60Extensions *extensions)
-    : m_extensions(extensions)
+QFontEngineS60::QFontEngineS60(const QFontDef &request, const QSymbianTypeFaceExtras *extras)
+    : m_extras(extras)
     , m_originalFont(0)
     , m_originalFontSizeInPixels((request.pixelSize >= 0)?
@@ -196,8 +198,10 @@
 
     HB_Glyph *g = glyphs->glyphs;
-    const unsigned char* cmap = m_extensions->cmap();
+    const unsigned char* cmap = m_extras->cmap();
+    const bool isRtl = (flags & QTextEngine::RightToLeft);
     for (int i = 0; i < len; ++i) {
         const unsigned int uc = getChar(characters, i, len);
-        *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap, uc);
+        *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap,
+        		isRtl ? QChar::mirroredChar(uc) : uc);
     }
 
@@ -217,6 +221,6 @@
     for (int i = 0; i < glyphs->numGlyphs; i++) {
         const glyph_metrics_t bbox = boundingBox_const(glyphs->glyphs[i]);
-        glyphs->advances_x[i] = glyphs->offsets[i].x = bbox.xoff;
-        glyphs->advances_y[i] = glyphs->offsets[i].y = bbox.yoff;
+        glyphs->advances_x[i] = bbox.xoff;
+        glyphs->advances_y[i] = bbox.yoff;
     }
 }
@@ -313,5 +317,5 @@
 bool QFontEngineS60::canRender(const QChar *string, int len)
 {
-    const unsigned char *cmap = m_extensions->cmap();
+    const unsigned char *cmap = m_extras->cmap();
     for (int i = 0; i < len; ++i) {
         const unsigned int uc = getChar(string, i, len);
@@ -324,5 +328,10 @@
 QByteArray QFontEngineS60::getSfntTable(uint tag) const
 {
-    return m_extensions->getSfntTable(tag);
+    return m_extras->getSfntTable(tag);
+}
+
+bool QFontEngineS60::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+    return m_extras->getSfntTableData(tag, buffer, length);
 }
 
Index: trunk/src/gui/text/qfontengine_s60_p.h
===================================================================
--- trunk/src/gui/text/qfontengine_s60_p.h	(revision 766)
+++ trunk/src/gui/text/qfontengine_s60_p.h	(revision 769)
@@ -57,27 +57,23 @@
 #include "qfontengine_p.h"
 #include "qsize.h"
-#include <OPENFONT.H>
+#include <openfont.h>
 
-class CFbsBitmap;
-class CFbsBitmapDevice;
-class CFbsBitGc;
 class CFont;
 
 QT_BEGIN_NAMESPACE
 
-// ..gives us access to truetype tables, UTF-16<->GlyphID mapping, and glyph outlines
-class QFontEngineS60Extensions
+// ..gives us access to truetype tables
+class QSymbianTypeFaceExtras
 {
 public:
-    QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font);
+    QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font);
 
     QByteArray getSfntTable(uint tag) const;
+    bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
     const unsigned char *cmap() const;
-    QPainterPath glyphOutline(glyph_t glyph) const;
     CFont *fontOwner() const;
 
 private:
     COpenFont *m_font;
-    const MOpenFontShapingExtension *m_shapingExtension;
     mutable MOpenFontTrueTypeExtension *m_trueTypeExtension;
     mutable const unsigned char *m_cmap;
@@ -90,5 +86,5 @@
 {
 public:
-    QFontEngineS60(const QFontDef &fontDef, const QFontEngineS60Extensions *extensions);
+    QFontEngineS60(const QFontDef &fontDef, const QSymbianTypeFaceExtras *extras);
     ~QFontEngineS60();
 
@@ -110,4 +106,5 @@
 
     QByteArray getSfntTable(uint tag) const;
+    bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
 
     static qreal pixelsToPoints(qreal pixels, Qt::Orientation orientation = Qt::Horizontal);
@@ -130,5 +127,5 @@
     static void releaseFont(CFont *&font);
 
-    const QFontEngineS60Extensions *m_extensions;
+    const QSymbianTypeFaceExtras *m_extras;
     CFont* m_originalFont;
     const qreal m_originalFontSizeInPixels;
Index: trunk/src/gui/text/qfontengine_win.cpp
===================================================================
--- trunk/src/gui/text/qfontengine_win.cpp	(revision 766)
+++ trunk/src/gui/text/qfontengine_win.cpp	(revision 769)
@@ -40,4 +40,9 @@
 ****************************************************************************/
 
+#if _WIN32_WINNT < 0x0500
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
 #include "qfontengine_p.h"
 #include "qtextengine_p.h"
@@ -650,4 +655,30 @@
 static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
 
+#ifndef Q_CC_MINGW
+void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+    HDC hdc = shared_dc();
+    SelectObject(hdc, hfont);
+
+#ifndef Q_WS_WINCE
+    if (ttf)
+#endif
+
+    {
+        ABC abcWidths;
+        GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
+        if (leftBearing)
+            *leftBearing = abcWidths.abcA;
+        if (rightBearing)
+            *rightBearing = abcWidths.abcC;
+    }
+
+#ifndef Q_WS_WINCE
+    else {
+        QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
+    }
+#endif
+}
+#endif // Q_CC_MINGW
 
 qreal QFontEngineWin::minLeftBearing() const
Index: trunk/src/gui/text/qfontengine_win_p.h
===================================================================
--- trunk/src/gui/text/qfontengine_win_p.h	(revision 766)
+++ trunk/src/gui/text/qfontengine_win_p.h	(revision 769)
@@ -107,4 +107,8 @@
     virtual QImage alphaRGBMapForGlyph(glyph_t t, int margin, const QTransform &xform);
 
+#ifndef Q_CC_MINGW
+    virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
+#endif
+
     int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
     void getCMap();
Index: trunk/src/gui/text/qfontmetrics.cpp
===================================================================
--- trunk/src/gui/text/qfontmetrics.cpp	(revision 766)
+++ trunk/src/gui/text/qfontmetrics.cpp	(revision 769)
@@ -64,5 +64,5 @@
                            int tabStops, int *tabArray, int tabArrayLen,
                            QPainter *painter);
-extern int qt_defaultDpi();
+Q_GUI_EXPORT extern int qt_defaultDpi();
 
 /*****************************************************************************
@@ -473,6 +473,7 @@
     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
     // ### can nglyphs != 1 happen at all? Not currently I think
-    glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
-    return qRound(gi.x);
+    qreal lb;
+    engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+    return qRound(lb);
 }
 
@@ -507,6 +508,7 @@
     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
     // ### can nglyphs != 1 happen at all? Not currently I think
-    glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
-    return qRound(gi.xoff - gi.x - gi.width);
+    qreal rb;
+    engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+    return qRound(rb);
 }
 
@@ -1318,6 +1320,7 @@
     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
     // ### can nglyphs != 1 happen at all? Not currently I think
-    glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
-    return gi.x.toReal();
+    qreal lb;
+    engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+    return lb;
 }
 
@@ -1352,6 +1355,8 @@
     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
     // ### can nglyphs != 1 happen at all? Not currently I think
-    glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]);
-    return (gi.xoff - gi.x - gi.width).toReal();
+    qreal rb;
+    engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+    return rb;
+
 }
 
Index: trunk/src/gui/text/qtextcontrol.cpp
===================================================================
--- trunk/src/gui/text/qtextcontrol.cpp	(revision 766)
+++ trunk/src/gui/text/qtextcontrol.cpp	(revision 769)
@@ -1200,5 +1200,6 @@
             cursor.setBlockFormat(blockFmt);
         } else {
-            cursor.deletePreviousChar();
+            QTextCursor localCursor = cursor;
+            localCursor.deletePreviousChar();
         }
         goto accept;
@@ -1233,5 +1234,6 @@
 #endif
     else if (e == QKeySequence::Delete) {
-        cursor.deleteChar();
+        QTextCursor localCursor = cursor;
+        localCursor.deleteChar();
     }
     else if (e == QKeySequence::DeleteEndOfWord) {
Index: trunk/src/gui/text/qtextdocument.cpp
===================================================================
--- trunk/src/gui/text/qtextdocument.cpp	(revision 766)
+++ trunk/src/gui/text/qtextdocument.cpp	(revision 769)
@@ -1632,5 +1632,5 @@
 }
 
-extern int qt_defaultDpi();
+Q_GUI_EXPORT extern int qt_defaultDpi();
 
 /*!
@@ -1680,5 +1680,5 @@
 
     const QTextDocument *doc = this;
-    QTextDocument *clonedDoc = 0;
+    QScopedPointer<QTextDocument> clonedDoc;
     (void)doc->documentLayout(); // make sure that there is a layout
 
@@ -1713,5 +1713,5 @@
     } else {
         doc = clone(const_cast<QTextDocument *>(this));
-        clonedDoc = const_cast<QTextDocument *>(doc);
+        clonedDoc.reset(const_cast<QTextDocument *>(doc));
 
         for (QTextBlock srcBlock = firstBlock(), dstBlock = clonedDoc->firstBlock();
@@ -1788,5 +1788,5 @@
                 if (printer->printerState() == QPrinter::Aborted
                     || printer->printerState() == QPrinter::Error)
-                    goto UserCanceled;
+                    return;
                 printPage(page, &p, doc, body, pageNumberPos);
                 if (j < pageCopies - 1)
@@ -1808,7 +1808,4 @@
             printer->newPage();
     }
-
-UserCanceled:
-    delete clonedDoc;
 }
 #endif
Index: trunk/src/gui/text/qtextdocumentlayout.cpp
===================================================================
--- trunk/src/gui/text/qtextdocumentlayout.cpp	(revision 766)
+++ trunk/src/gui/text/qtextdocumentlayout.cpp	(revision 769)
@@ -76,5 +76,5 @@
 QT_BEGIN_NAMESPACE
 
-extern int qt_defaultDpi();
+Q_GUI_EXPORT extern int qt_defaultDpi();
 
 // ################ should probably add frameFormatChange notification!
Index: trunk/src/gui/text/qtextengine.cpp
===================================================================
--- trunk/src/gui/text/qtextengine.cpp	(revision 766)
+++ trunk/src/gui/text/qtextengine.cpp	(revision 769)
@@ -82,5 +82,5 @@
     {
         if ((int)caps == (int)QFont::SmallCaps)
-            generateScriptItemsSmallCaps(m_string.utf16(), start, length);
+            generateScriptItemsSmallCaps(reinterpret_cast<const ushort *>(m_string.unicode()), start, length);
         else if(caps == QFont::Capitalize)
             generateScriptItemsCapitalize(start, length);
@@ -857,5 +857,5 @@
 }
 
-extern int qt_defaultDpiY(); // in qfont.cpp
+Q_GUI_EXPORT extern int qt_defaultDpiY(); // in qfont.cpp
 
 void QTextEngine::shapeText(int item) const
@@ -1435,7 +1435,5 @@
     }
 
-    const ushort *unicode = layoutData->string.utf16();
-    // correctly assign script, isTab and isObject to the script analysis
-    const ushort *uc = unicode;
+    const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode());
     const ushort *e = uc + length;
     int lastScript = QUnicodeTables::Common;
@@ -1651,5 +1649,5 @@
             }
 
-            glyph_t glyph = glyphs.glyphs[logClusters[pos + ilen - 1]];
+            glyph_t glyph = glyphs.glyphs[logClusters[ilen - 1]];
             glyph_metrics_t gi = fe->boundingBox(glyph);
             if (gi.isValid())
@@ -2498,5 +2496,5 @@
 }
 
-extern int qt_defaultDpiY();
+Q_GUI_EXPORT extern int qt_defaultDpiY();
 
 QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
Index: trunk/src/gui/text/qtextengine_p.h
===================================================================
--- trunk/src/gui/text/qtextengine_p.h	(revision 766)
+++ trunk/src/gui/text/qtextengine_p.h	(revision 769)
@@ -383,4 +383,5 @@
     QFixed width;
     QFixed textWidth;
+    QFixed textAdvance;
     int from;
     signed int length : 29;
Index: trunk/src/gui/text/qtextformat.cpp
===================================================================
--- trunk/src/gui/text/qtextformat.cpp	(revision 766)
+++ trunk/src/gui/text/qtextformat.cpp	(revision 769)
@@ -3086,5 +3086,6 @@
         f.d->resolveFont(defaultFnt);
 
-        hashes.insert(hash, idx);
+        if (!hashes.contains(hash, idx))
+            hashes.insert(hash, idx);
 
     } QT_CATCH(...) {
Index: trunk/src/gui/text/qtextimagehandler.cpp
===================================================================
--- trunk/src/gui/text/qtextimagehandler.cpp	(revision 766)
+++ trunk/src/gui/text/qtextimagehandler.cpp	(revision 769)
@@ -124,5 +124,5 @@
     QPaintDevice *pdev = doc->documentLayout()->paintDevice();
     if (pdev) {
-        extern int qt_defaultDpi();
+        Q_GUI_EXPORT extern int qt_defaultDpi();
         if (pm.isNull())
             pm = getPixmap(doc, format);
Index: trunk/src/gui/text/qtextlayout.cpp
===================================================================
--- trunk/src/gui/text/qtextlayout.cpp	(revision 766)
+++ trunk/src/gui/text/qtextlayout.cpp	(revision 769)
@@ -90,7 +90,7 @@
             align = Qt::AlignRight;
         if (align & Qt::AlignRight)
-            x = line.width - (line.textWidth + leadingSpaceWidth(eng, line));
+            x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line));
         else if (align & Qt::AlignHCenter)
-            x = (line.width - line.textWidth)/2;
+            x = (line.width - line.textAdvance)/2;
     }
     return x;
@@ -1332,5 +1332,5 @@
     const QScriptLine &sl = d->lines[line];
 
-    const qreal x = position.x() + l.cursorToX(cursorPosition);
+    qreal x = position.x() + l.cursorToX(cursorPosition);
 
     int itm = d->findItem(cursorPosition - 1);
@@ -1351,4 +1351,8 @@
     if (toggleAntialiasing)
         p->setRenderHint(QPainter::Antialiasing);
+#if defined(QT_MAC_USE_COCOA)
+    // Always draw the cursor aligned to pixel boundary.
+    x = qRound(x);
+#endif
     p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush());
     if (toggleAntialiasing)
@@ -1641,19 +1645,58 @@
     struct LineBreakHelper
     {
-        LineBreakHelper() : glyphCount(0), maxGlyphs(0), manualWrap(false) {}
+        LineBreakHelper()
+            : glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(0), logClusters(0),
+              manualWrap(false)
+        {
+        }
+
 
         QScriptLine tmpData;
         QScriptLine spaceData;
 
+        QGlyphLayout glyphs;
+
         int glyphCount;
         int maxGlyphs;
+        int currentPosition;
 
         QFixed minw;
         QFixed softHyphenWidth;
         QFixed rightBearing;
+        QFixed minimumRightBearing;
+
+        QFontEngine *fontEngine;
+        const unsigned short *logClusters;
 
         bool manualWrap;
 
         bool checkFullOtherwiseExtend(QScriptLine &line);
+
+        QFixed calculateNewWidth(const QScriptLine &line) const {
+            return line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth
+                    - qMin(rightBearing, QFixed());
+        }
+
+        inline glyph_t currentGlyph() const
+        {
+            Q_ASSERT(currentPosition > 0);
+            return glyphs.glyphs[logClusters[currentPosition - 1]];
+        }
+
+        inline void adjustRightBearing()
+        {
+            if (currentPosition <= 0)
+                return;
+
+            qreal rb;
+            fontEngine->getGlyphBearings(currentGlyph(), 0, &rb);
+            rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
+        }
+
+        inline void resetRightBearing()
+        {
+            rightBearing = QFixed(1); // Any positive number is defined as invalid since only
+                                      // negative right bearings are interesting to us.
+        }
     };
 
@@ -1662,5 +1705,5 @@
     LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal());
 
-    QFixed newWidth = line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth + rightBearing;
+    QFixed newWidth = calculateNewWidth(line);
     if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs))
         return true;
@@ -1738,11 +1781,10 @@
 
     const HB_CharAttributes *attributes = eng->attributes();
-    int pos = line.from;
+    lbh.currentPosition = line.from;
     int end = 0;
-    QGlyphLayout glyphs;
-    const unsigned short *logClusters = eng->layoutData->logClustersPtr;
+    lbh.logClusters = eng->layoutData->logClustersPtr;
 
     while (newItem < eng->layoutData->items.size()) {
-        lbh.rightBearing = 0;
+        lbh.resetRightBearing();
         lbh.softHyphenWidth = 0;
         if (newItem != item) {
@@ -1752,11 +1794,17 @@
                 eng->shape(item);
                 attributes = eng->attributes();
-                logClusters = eng->layoutData->logClustersPtr;
+                lbh.logClusters = eng->layoutData->logClustersPtr;
             }
-            pos = qMax(line.from, current.position);
+            lbh.currentPosition = qMax(line.from, current.position);
             end = current.position + eng->length(item);
-            glyphs = eng->shapedGlyphs(&current);
+            lbh.glyphs = eng->shapedGlyphs(&current);
         }
         const QScriptItem &current = eng->layoutData->items[item];
+        QFontEngine *fontEngine = eng->fontEngine(current);
+        if (lbh.fontEngine != fontEngine) {
+            lbh.fontEngine = fontEngine;
+            lbh.minimumRightBearing = qMin(QFixed(),
+                                           QFixed::fromReal(fontEngine->minRightBearing()));
+        }
 
         lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
@@ -1788,6 +1836,6 @@
                 line.setDefaultHeight(eng);
             if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
-                addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount,
-                               current, logClusters, glyphs);
+                addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
+                               current, lbh.logClusters, lbh.glyphs);
             } else {
                 lbh.tmpData.length++;
@@ -1808,8 +1856,8 @@
             if (lbh.checkFullOtherwiseExtend(line))
                 goto found;
-        } else if (attributes[pos].whiteSpace) {
-            while (pos < end && attributes[pos].whiteSpace)
-                addNextCluster(pos, end, lbh.spaceData, lbh.glyphCount,
-                               current, logClusters, glyphs);
+        } else if (attributes[lbh.currentPosition].whiteSpace) {
+            while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace)
+                addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount,
+                               current, lbh.logClusters, lbh.glyphs);
 
             if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) {
@@ -1820,17 +1868,17 @@
             bool sb_or_ws = false;
             do {
-                addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount,
-                               current, logClusters, glyphs);
-
-                if (attributes[pos].whiteSpace || attributes[pos-1].lineBreakType != HB_NoBreak) {
+                addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
+                               current, lbh.logClusters, lbh.glyphs);
+
+                if (attributes[lbh.currentPosition].whiteSpace || attributes[lbh.currentPosition-1].lineBreakType != HB_NoBreak) {
                     sb_or_ws = true;
                     break;
-                } else if (breakany && attributes[pos].charStop) {
+                } else if (breakany && attributes[lbh.currentPosition].charStop) {
                     break;
                 }
-            } while (pos < end);
+            } while (lbh.currentPosition < end);
             lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw);
 
-            if (pos && attributes[pos - 1].lineBreakType == HB_SoftHyphen) {
+            if (lbh.currentPosition && attributes[lbh.currentPosition - 1].lineBreakType == HB_SoftHyphen) {
                 // if we are splitting up a word because of
                 // a soft hyphen then we ...
@@ -1850,7 +1898,7 @@
                 //
                 if (line.length)
-                    lbh.softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]];
+                    lbh.softHyphenWidth = lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
                 else if (breakany)
-                    lbh.tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]];
+                    lbh.tmpData.textWidth += lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
             }
 
@@ -1859,30 +1907,29 @@
             // of the advance of the glyph, the bearing will be negative. We flip the sign
             // for the code to be more readable. Logic borrowed from qfontmetrics.cpp.
-            if (pos) {
-                QFontEngine *fontEngine = eng->fontEngine(current);
-                glyph_t glyph = glyphs.glyphs[logClusters[pos - 1]];
-                glyph_metrics_t gi = fontEngine->boundingBox(glyph);
-                if (gi.isValid())
-                    lbh.rightBearing = qMax(QFixed(), -(gi.xoff - gi.x - gi.width));
+            // We ignore the right bearing if the minimum negative bearing is too little to
+            // expand the text beyond the edge.
+            if (sb_or_ws|breakany) {
+                if (lbh.calculateNewWidth(line) + lbh.minimumRightBearing > line.width)
+                    lbh.adjustRightBearing();
+                if (lbh.checkFullOtherwiseExtend(line)) {
+                    if (!breakany) {
+                        line.textWidth += lbh.softHyphenWidth;
+                    }
+
+                    goto found;
+                }
             }
-
-            if ((sb_or_ws|breakany) && lbh.checkFullOtherwiseExtend(line)) {
-                if (!breakany) {
-                    line.textWidth += lbh.softHyphenWidth;
-                }
-
-                line.textWidth += lbh.rightBearing;
-
-                goto found;
-            }
-        }
-        if (pos == end)
+        }
+        if (lbh.currentPosition == end)
             newItem = item + 1;
     }
     LB_DEBUG("reached end of line");
     lbh.checkFullOtherwiseExtend(line);
-    line.textWidth += lbh.rightBearing;
-
 found:       
+    if (lbh.rightBearing > 0) // If right bearing has not yet been adjusted
+        lbh.adjustRightBearing();
+    line.textAdvance = line.textWidth;
+    line.textWidth -= qMin(QFixed(), lbh.rightBearing);
+
     if (line.length == 0) {
         LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f",
Index: trunk/src/gui/text/qzip.cpp
===================================================================
--- trunk/src/gui/text/qzip.cpp	(revision 766)
+++ trunk/src/gui/text/qzip.cpp	(revision 769)
@@ -55,8 +55,11 @@
 
 #if defined(Q_OS_WIN)
-#undef S_IFREG
-#define S_IFREG 0100000
+#  undef S_IFREG
+#  define S_IFREG 0100000
+#  ifndef S_IFDIR
+#    define S_IFDIR 0040000
+#  endif
 #  ifndef S_ISDIR
-#    define S_ISDIR(x) ((x) & 0040000) > 0
+#    define S_ISDIR(x) ((x) & S_IFDIR) > 0
 #  endif
 #  ifndef S_ISREG
Index: trunk/src/gui/text/qzipreader_p.h
===================================================================
--- trunk/src/gui/text/qzipreader_p.h	(revision 766)
+++ trunk/src/gui/text/qzipreader_p.h	(revision 769)
@@ -50,5 +50,5 @@
 //
 // This file is not part of the Qt API.  It exists for the convenience
-// of the QLibrary class.  This header file may change from
+// of the QZipReader class.  This header file may change from
 // version to version without notice, or even be removed.
 //
Index: trunk/src/gui/text/qzipwriter_p.h
===================================================================
--- trunk/src/gui/text/qzipwriter_p.h	(revision 766)
+++ trunk/src/gui/text/qzipwriter_p.h	(revision 769)
@@ -48,5 +48,5 @@
 //
 // This file is not part of the Qt API.  It exists for the convenience
-// of the QLibrary class.  This header file may change from
+// of the QZipWriter class.  This header file may change from
 // version to version without notice, or even be removed.
 //
Index: trunk/src/gui/util/qcompleter.cpp
===================================================================
--- trunk/src/gui/util/qcompleter.cpp	(revision 766)
+++ trunk/src/gui/util/qcompleter.cpp	(revision 769)
@@ -528,15 +528,20 @@
     cost = cost + m.indices.cost() - old.indices.cost();
     if (cost * sizeof(int) > 1024 * 1024) {
-        QMap<QModelIndex, CacheItem>::iterator it1 ;
-        for (it1 = cache.begin(); it1 != cache.end(); ++it1) {
+        QMap<QModelIndex, CacheItem>::iterator it1 = cache.begin();
+        while (it1 != cache.end()) {
             CacheItem& ci = it1.value();
             int sz = ci.count()/2;
             QMap<QString, QMatchData>::iterator it2 = ci.begin();
-            for (int i = 0; it2 != ci.end() && i < sz; i++, ++it2) {
+            int i = 0;
+            while (it2 != ci.end() && i < sz) {
                 cost -= it2.value().indices.cost();
-                ci.erase(it2);
+                it2 = ci.erase(it2);
+                i++;
             }
-            if (ci.count() == 0)
-                cache.erase(it1);
+            if (ci.count() == 0) {
+              it1 = cache.erase(it1);
+            } else {
+              ++it1;
+            }
         }
     }
@@ -1749,5 +1754,5 @@
     This signal is sent when an item in the popup() is highlighted by
     the user. It is also sent if complete() is called with the completionMode()
-    set to QCOmpleter::InlineCompletion. The item's \a text is given.
+    set to QCompleter::InlineCompletion. The item's \a text is given.
 */
 
Index: trunk/src/gui/util/qdesktopservices_s60.cpp
===================================================================
--- trunk/src/gui/util/qdesktopservices_s60.cpp	(revision 766)
+++ trunk/src/gui/util/qdesktopservices_s60.cpp	(revision 769)
@@ -49,5 +49,4 @@
 #include <private/qcore_symbian_p.h>
 
-#include <miutset.h>                // KUidMsgTypeSMTP
 #include <txtrich.h>                // CRichText
 #include <f32file.h>                // TDriveUnit etc
@@ -58,9 +57,12 @@
 #include <rsendasmessage.h>         // RSendAsMessage
 
+// copied from miutset.h, so we don't get a dependency into the app layer
+const TUid KUidMsgTypeSMTP			= {0x10001028};	// 268439592
+
 #ifdef Q_WS_S60
 #  include <pathinfo.h>             // PathInfo
 #  ifdef USE_DOCUMENTHANDLER
-#    include <documenthandler.h>    // CDocumentHandler
-#    include <aknserverapp.h>
+#    include <DocumentHandler.h>    // CDocumentHandler
+#    include <AknServerApp.h>
 #  endif
 #else
Index: trunk/src/gui/util/qsystemtrayicon_mac.mm
===================================================================
--- trunk/src/gui/util/qsystemtrayicon_mac.mm	(revision 766)
+++ trunk/src/gui/util/qsystemtrayicon_mac.mm	(revision 769)
@@ -531,5 +531,9 @@
             const QIcon icon = action->icon();
             if(!icon.isNull()) {
+#ifndef QT_MAC_USE_COCOA
+                const short scale = GetMBarHeight();
+#else
                 const short scale = [[NSApp mainMenu] menuBarHeight];
+#endif
                 NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(icon.pixmap(QSize(scale, scale))));
                 [item setImage: nsimage];
@@ -570,15 +574,2 @@
 @end
 
-
-/* Done here because this is the only .mm for now! -Sam */
-QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool()
-{
-    NSApplicationLoad();
-    pool = (void*)[[NSAutoreleasePool alloc] init];
-}
-
-QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool()
-{
-    [(NSAutoreleasePool*)pool release];
-}
-
Index: trunk/src/gui/util/qsystemtrayicon_p.h
===================================================================
--- trunk/src/gui/util/qsystemtrayicon_p.h	(revision 766)
+++ trunk/src/gui/util/qsystemtrayicon_p.h	(revision 769)
@@ -165,5 +165,7 @@
     void mousePressEvent(QMouseEvent *event);
     void mouseDoubleClickEvent(QMouseEvent *event);
+#ifndef QT_NO_WHEELEVENT
     void wheelEvent(QWheelEvent *event);
+#endif
     bool event(QEvent *e);
 
Index: trunk/src/gui/util/qsystemtrayicon_win.cpp
===================================================================
--- trunk/src/gui/util/qsystemtrayicon_win.cpp	(revision 766)
+++ trunk/src/gui/util/qsystemtrayicon_win.cpp	(revision 769)
@@ -62,15 +62,7 @@
 #include <QSettings>
 
-#if defined(Q_WS_WINCE) && !defined(STANDARDSHELL_UI_MODEL)
-#   include <streams.h>
-#endif
-
 QT_BEGIN_NAMESPACE
 
-#if defined(Q_WS_WINCE)
-static const UINT q_uNOTIFYICONID = 13;     // IDs from 0 to 12 are reserved on WinCE.
-#else
 static const UINT q_uNOTIFYICONID = 0;
-#endif
 
 static uint MYWM_TASKBARCREATED = 0;
@@ -126,8 +118,5 @@
 bool QSystemTrayIconSys::supportsMessages()
 {
-#ifndef Q_OS_WINCE
     return allowsMessages();
-#endif
-    return false;
 }
 
@@ -136,11 +125,6 @@
 
 {
-#ifndef Q_OS_WINCE
     notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, guidItem); // NOTIFYICONDATAW_V2_SIZE;
     maxTipLength = 128;
-#else
-    notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, szTip[64]); // NOTIFYICONDATAW_V1_SIZE;
-    maxTipLength = 64;
-#endif
 
     // For restoring the tray icon after explorer crashes
@@ -318,13 +302,4 @@
                 if (q->contextMenu()) {
                     q->contextMenu()->popup(gpos);
-#if defined(Q_WS_WINCE)
-                    // We must ensure that the popup menu doesn't show up behind the task bar.
-                    QRect desktopRect = qApp->desktop()->availableGeometry();
-                    int maxY = desktopRect.y() + desktopRect.height() - q->contextMenu()->height();
-                    if (gpos.y() > maxY) {
-                        gpos.ry() = maxY;
-                        q->contextMenu()->move(gpos);
-                    }
-#endif
                     q->contextMenu()->activateWindow();
                     //Must be activated for proper keyboardfocus and menu closing on windows:
@@ -333,9 +308,7 @@
                 break;
 
-#if !defined(Q_WS_WINCE)
             case NIN_BALLOONUSERCLICK:
                 emit q->messageClicked();
                 break;
-#endif
 
             case WM_MBUTTONUP:
@@ -404,21 +377,9 @@
     //find the toolbar used in the notification area
     if (trayHandle) {
-#if defined(Q_OS_WINCE)
-        trayHandle = FindWindow(L"TrayNotifyWnd", NULL);
-#else
         trayHandle = FindWindowEx(trayHandle, NULL, L"TrayNotifyWnd", NULL);
-#endif
         if (trayHandle) {
-#if defined(Q_OS_WINCE)
-            HWND hwnd = FindWindow(L"SysPager", NULL);
-#else
             HWND hwnd = FindWindowEx(trayHandle, NULL, L"SysPager", NULL);
-#endif
             if (hwnd) {
-#if defined(Q_OS_WINCE)
-                hwnd = FindWindow(L"ToolbarWindow32", NULL);
-#else
                 hwnd = FindWindowEx(hwnd, NULL, L"ToolbarWindow32", NULL);
-#endif
                 if (hwnd)
                     trayHandle = hwnd;
@@ -439,9 +400,5 @@
 
     int buttonCount = SendMessage(trayHandle, TB_BUTTONCOUNT, 0, 0);
-#if defined(Q_OS_WINCE)
-    LPVOID data = VirtualAlloc(NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
-#else
     LPVOID data = VirtualAllocEx(trayProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
-#endif
 
     if ( buttonCount < 1 || !data ) {
@@ -481,9 +438,5 @@
         }
     }
-#if defined(Q_OS_WINCE)
-    VirtualFree(data, 0, MEM_RELEASE);
-#else
     VirtualFreeEx(trayProcess, data, 0, MEM_RELEASE);
-#endif
     CloseHandle(trayProcess);
     return ret;
@@ -559,14 +512,8 @@
 void QSystemTrayIconPrivate::updateToolTip_sys()
 {
-#ifdef Q_WS_WINCE
-    // Calling sys->trayMessage(NIM_MODIFY) on an existing icon is broken on Windows CE.
-    // So we need to call updateIcon_sys() which creates a new icon handle.
-    updateIcon_sys();
-#else
     if (!sys)
         return;
 
     sys->trayMessage(NIM_MODIFY);
-#endif
 }
 
Index: trunk/src/gui/util/qsystemtrayicon_wince.cpp
===================================================================
--- trunk/src/gui/util/qsystemtrayicon_wince.cpp	(revision 769)
+++ trunk/src/gui/util/qsystemtrayicon_wince.cpp	(revision 769)
@@ -0,0 +1,299 @@
+/****************************************************************************
+**
+** 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$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsystemtrayicon_p.h"
+#ifndef QT_NO_SYSTEMTRAYICON
+#define _WIN32_IE 0x0600 //required for NOTIFYICONDATA_V2_SIZE
+
+#include <qt_windows.h>
+#include <shlwapi.h>
+#include <QApplication>
+
+QT_BEGIN_NAMESPACE
+
+static const UINT q_uNOTIFYICONID = 13;     // IDs from 0 to 12 are reserved on WinCE.
+#define MYWM_NOTIFYICON (WM_APP+101)
+
+struct Q_NOTIFYICONIDENTIFIER {
+    DWORD cbSize;
+    HWND hWnd;
+    UINT uID;
+    GUID guidItem;
+};
+
+class QSystemTrayIconSys : QWidget
+{
+public:
+    QSystemTrayIconSys(QSystemTrayIcon *object);
+    ~QSystemTrayIconSys();
+    bool winEvent( MSG *m, long *result );
+    bool trayMessage(DWORD msg);
+    void setIconContents(NOTIFYICONDATA &data);
+    void createIcon();
+    QRect findTrayGeometry();
+    HICON hIcon;
+    QPoint globalPos;
+    QSystemTrayIcon *q;
+private:
+    uint notifyIconSize;
+    int maxTipLength;
+    bool ignoreNextMouseRelease;
+};
+
+QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object)
+    : hIcon(0), q(object), ignoreNextMouseRelease(false)
+
+{
+    notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, szTip[64]); // NOTIFYICONDATAW_V1_SIZE;
+    maxTipLength = 64;
+}
+
+QSystemTrayIconSys::~QSystemTrayIconSys()
+{
+    if (hIcon)
+        DestroyIcon(hIcon);
+}
+
+QRect QSystemTrayIconSys::findTrayGeometry()
+{
+    // Use lower right corner as fallback
+    QPoint brCorner = qApp->desktop()->screenGeometry().bottomRight();
+    QRect ret(brCorner.x() - 10, brCorner.y() - 10, 10, 10);
+    return ret;
+}
+
+void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd)
+{
+    tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+    tnd.uCallbackMessage = MYWM_NOTIFYICON;
+    tnd.hIcon = hIcon;
+    QString tip = q->toolTip();
+
+    if (!tip.isNull()) {
+        tip = tip.left(maxTipLength - 1) + QChar();
+        memcpy(tnd.szTip, tip.utf16(), qMin(tip.length() + 1, maxTipLength) * sizeof(wchar_t));
+    }
+}
+
+bool QSystemTrayIconSys::trayMessage(DWORD msg)
+{
+    NOTIFYICONDATA tnd;
+    memset(&tnd, 0, notifyIconSize);
+    tnd.uID = q_uNOTIFYICONID;
+    tnd.cbSize = notifyIconSize;
+    tnd.hWnd = winId();
+
+    Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+
+    if (msg != NIM_DELETE) {
+        setIconContents(tnd);
+    }
+
+    return Shell_NotifyIcon(msg, &tnd);
+}
+
+void QSystemTrayIconSys::createIcon()
+{
+    hIcon = 0;
+    QIcon icon = q->icon();
+    if (icon.isNull())
+        return;
+
+    //const QSize preferredSize(GetSystemMetrics(SM_CXSMICON) * 2, GetSystemMetrics(SM_CYSMICON) * 2);
+    const QSize preferredSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
+    QPixmap pm = icon.pixmap(preferredSize);
+    if (pm.isNull())
+        return;
+
+    hIcon = pm.toWinHICON();
+}
+
+bool QSystemTrayIconSys::winEvent( MSG *m, long *result )
+{
+    switch(m->message) {
+    case WM_CREATE:
+        SetWindowLong(winId(), GWL_USERDATA, (LONG)((CREATESTRUCTW*)m->lParam)->lpCreateParams);
+        break;
+
+    case MYWM_NOTIFYICON:
+        {
+            RECT r;
+            GetWindowRect(winId(), &r);
+            QEvent *e = 0;
+            Qt::KeyboardModifiers keys = QApplication::keyboardModifiers();
+            QPoint gpos = QCursor::pos();
+
+            switch (m->lParam) {
+            case WM_LBUTTONUP:
+                if (ignoreNextMouseRelease)
+                    ignoreNextMouseRelease = false;
+                else
+                    emit q->activated(QSystemTrayIcon::Trigger);
+                break;
+
+            case WM_LBUTTONDBLCLK:
+                ignoreNextMouseRelease = true; // Since DBLCLICK Generates a second mouse 
+                                               // release we must ignore it
+                emit q->activated(QSystemTrayIcon::DoubleClick);
+                break;
+
+            case WM_RBUTTONUP:
+                if (q->contextMenu()) {
+                    q->contextMenu()->popup(gpos);
+
+                    // We must ensure that the popup menu doesn't show up behind the task bar.
+                    QRect desktopRect = qApp->desktop()->availableGeometry();
+                    int maxY = desktopRect.y() + desktopRect.height() - q->contextMenu()->height();
+                    if (gpos.y() > maxY) {
+                        gpos.ry() = maxY;
+                        q->contextMenu()->move(gpos);
+                    }
+
+                    q->contextMenu()->activateWindow();
+                    //Must be activated for proper keyboardfocus and menu closing on windows:
+                }
+                emit q->activated(QSystemTrayIcon::Context);
+                break;
+
+            case WM_MBUTTONUP:
+                emit q->activated(QSystemTrayIcon::MiddleClick);
+                break;
+            default:
+                break;
+            }
+            if (e) {
+                bool res = QApplication::sendEvent(q, e);
+                delete e;
+                return res;
+            }
+            break;
+        }
+    default:
+        return QWidget::winEvent(m, result);
+    }
+    return 0;
+}
+
+void QSystemTrayIconPrivate::install_sys()
+{
+    Q_Q(QSystemTrayIcon);
+    if (!sys) {
+        sys = new QSystemTrayIconSys(q);
+        sys->createIcon();
+        sys->trayMessage(NIM_ADD);
+    }
+}
+
+void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, int timeOut)
+{
+    if (!sys)
+        return;
+
+    uint uSecs = 0;
+    if ( timeOut < 0)
+        uSecs = 10000; //10 sec default
+    else uSecs = (int)timeOut;
+
+    //message is limited to 255 chars + NULL
+    QString messageString;
+    if (message.isEmpty() && !title.isEmpty())
+        messageString = QLatin1Char(' '); //ensures that the message shows when only title is set
+    else
+        messageString = message.left(255) + QChar();
+
+    //title is limited to 63 chars + NULL
+    QString titleString = title.left(63) + QChar();
+
+    //show QBalloonTip
+    QRect trayRect = sys->findTrayGeometry();
+    QBalloonTip::showBalloon(type, title, message, sys->q, QPoint(trayRect.left(),
+                             trayRect.center().y()), uSecs, false);
+}
+
+QRect QSystemTrayIconPrivate::geometry_sys() const
+{
+    return QRect();
+}
+
+void QSystemTrayIconPrivate::remove_sys()
+{
+    if (!sys)
+        return;
+
+    sys->trayMessage(NIM_DELETE);
+    delete sys;
+    sys = 0;
+}
+
+void QSystemTrayIconPrivate::updateIcon_sys()
+{
+    if (!sys)
+        return;
+
+    HICON hIconToDestroy = sys->hIcon;
+
+    sys->createIcon();
+    sys->trayMessage(NIM_MODIFY);
+
+    if (hIconToDestroy)
+        DestroyIcon(hIconToDestroy);
+}
+
+void QSystemTrayIconPrivate::updateMenu_sys()
+{
+
+}
+
+void QSystemTrayIconPrivate::updateToolTip_sys()
+{
+    // Calling sys->trayMessage(NIM_MODIFY) on an existing icon is broken on Windows CE.
+    // So we need to call updateIcon_sys() which creates a new icon handle.
+    updateIcon_sys();
+}
+
+bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
+{
+    return true;
+}
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/gui/util/qsystemtrayicon_x11.cpp
===================================================================
--- trunk/src/gui/util/qsystemtrayicon_x11.cpp	(revision 766)
+++ trunk/src/gui/util/qsystemtrayicon_x11.cpp	(revision 769)
@@ -309,8 +309,10 @@
 }
 
+#ifndef QT_NO_WHEELEVENT
 void QSystemTrayIconSys::wheelEvent(QWheelEvent *e)
 {
     QApplication::sendEvent(q, e);
 }
+#endif
 
 bool QSystemTrayIconSys::event(QEvent *e)
Index: trunk/src/gui/util/util.pri
===================================================================
--- trunk/src/gui/util/util.pri	(revision 766)
+++ trunk/src/gui/util/util.pri	(revision 769)
@@ -21,5 +21,8 @@
 
 
-win32 {
+wince* {
+		SOURCES += \
+				util/qsystemtrayicon_wince.cpp
+} else:win32 {
 		SOURCES += \
 				util/qsystemtrayicon_win.cpp
@@ -50,4 +53,4 @@
 symbian {
     LIBS += -lsendas2 -letext -lapmime
-    contains(QT_CONFIG, s60): LIBS += -lplatformenv -lcommonui
+    contains(QT_CONFIG, s60): LIBS += -lplatformenv -lCommonUI
 }
Index: trunk/src/gui/widgets/qabstractbutton.cpp
===================================================================
--- trunk/src/gui/widgets/qabstractbutton.cpp	(revision 766)
+++ trunk/src/gui/widgets/qabstractbutton.cpp	(revision 769)
@@ -58,5 +58,5 @@
 #define AUTO_REPEAT_INTERVAL 100
 
-extern bool qt_tab_all_widgets;
+Q_GUI_EXPORT extern bool qt_tab_all_widgets;
 
 /*!
Index: trunk/src/gui/widgets/qabstractscrollarea.cpp
===================================================================
--- trunk/src/gui/widgets/qabstractscrollarea.cpp	(revision 766)
+++ trunk/src/gui/widgets/qabstractscrollarea.cpp	(revision 769)
@@ -395,5 +395,5 @@
         q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {
         controlsRect = widgetRect;
-        const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing);
+        const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q);
         const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0);
         QRect frameRect = widgetRect;
Index: trunk/src/gui/widgets/qabstractslider.cpp
===================================================================
--- trunk/src/gui/widgets/qabstractslider.cpp	(revision 766)
+++ trunk/src/gui/widgets/qabstractslider.cpp	(revision 769)
@@ -48,7 +48,4 @@
 #include "qaccessible.h"
 #endif
-#ifdef QT_KEYPAD_NAVIGATION
-#include "qtabwidget.h" // Needed in inTabWidget()
-#endif // QT_KEYPAD_NAVIGATION
 #include <limits.h>
 
@@ -215,6 +212,6 @@
 
 QAbstractSliderPrivate::QAbstractSliderPrivate()
-    : minimum(0), maximum(99), singleStep(1), pageStep(10),
-      value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
+    : minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1),
+      singleStep(1), offset_accumulated(0), tracking(true),
       blocktracking(false), pressed(false),
       invertedAppearance(false), invertedControls(false),
@@ -689,4 +686,50 @@
 }
 
+bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta)
+{
+    Q_Q(QAbstractSlider);
+    int stepsToScroll = 0;
+    // in Qt scrolling to the right gives negative values.
+    if (orientation == Qt::Horizontal)
+        delta = -delta;
+    qreal offset = qreal(delta) / 120;
+
+    if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) {
+        // Scroll one page regardless of delta:
+        stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
+        offset_accumulated = 0;
+    } else {
+        // Calculate how many lines to scroll. Depending on what delta is (and
+        // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
+        // only scroll whole lines, so we keep the reminder until next event.
+        qreal stepsToScrollF =
+#ifndef QT_NO_WHEELEVENT
+                QApplication::wheelScrollLines() *
+#endif
+                offset * effectiveSingleStep();
+        // Check if wheel changed direction since last event:
+        if (offset_accumulated != 0 && (offset / offset_accumulated) < 0)
+            offset_accumulated = 0;
+
+        offset_accumulated += stepsToScrollF;
+        stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep);
+        offset_accumulated -= int(offset_accumulated);
+        if (stepsToScroll == 0)
+            return false;
+    }
+
+    if (invertedControls)
+        stepsToScroll = -stepsToScroll;
+
+    int prevValue = value;
+    position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
+    q->triggerAction(QAbstractSlider::SliderMove);
+
+    if (prevValue == value) {
+        offset_accumulated = 0;
+        return false;
+    }
+    return true;
+}
 
 /*!
@@ -698,82 +741,11 @@
     Q_D(QAbstractSlider);
     e->ignore();
-    if (e->orientation() != d->orientation && !rect().contains(e->pos()))
-        return;
-
-    int stepsToScroll = 0;
-    qreal offset = qreal(e->delta()) / 120;
-
-    if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
-        // Scroll one page regardless of delta:
-        stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep);
-        d->offset_accumulated = 0;
-    } else {
-        // Calculate how many lines to scroll. Depending on what delta is (and 
-        // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
-        // only scroll whole lines, so we keep the reminder until next event.
-        qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep();
-        // Check if wheel changed direction since last event:
-        if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0)
-            d->offset_accumulated = 0;
-
-        d->offset_accumulated += stepsToScrollF;
-        stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep);
-        d->offset_accumulated -= int(d->offset_accumulated);
-        if (stepsToScroll == 0)
-            return;
-    }
-
-    if (d->invertedControls)
-        stepsToScroll = -stepsToScroll;
-
-    int prevValue = d->value;
-    d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
-    triggerAction(SliderMove);
-
-    if (prevValue == d->value)
-        d->offset_accumulated = 0;
-    else
+    int delta = e->delta();
+    if (d->scrollByDelta(e->orientation(), e->modifiers(), delta))
         e->accept();
 }
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
-/*!
-    \internal
-
-    Tells us if it there is currently a reachable widget by keypad navigation in
-    a certain \a orientation.
-    If no navigation is possible, occuring key events in that \a orientation may
-    be used to interact with the value in the focussed widget, even though it
-    currently has not the editFocus.
-
-    \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
-*/
-inline static bool canKeypadNavigate(Qt::Orientation orientation)
-{
-    return orientation == Qt::Horizontal?
-            (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
-                    || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
-            :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
-                    || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
-}
-/*!
-    \internal
-
-    Checks, if the \a widget is inside a QTabWidget. If is is inside
-    one, left/right key events will be used to switch between tabs in keypad
-    navigation. If there is no QTabWidget, the horizontal key events can be used to
-    interact with the value in the focussed widget, even though it currently has
-    not the editFocus.
-
-    \sa QWidget::hasEditFocus()
-*/
-inline static bool inTabWidget(QWidget *widget)
-{
-    for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
-        if (qobject_cast<const QTabWidget*>(tabWidget))
-            return true;
-    return false;
-}
-#endif // QT_KEYPAD_NAVIGATION
+
+#endif
+
 /*!
     \reimp
@@ -841,5 +813,6 @@
                     && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
                     || d->orientation == Qt::Vertical
-                    || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
+                    || !hasEditFocus()
+                    && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
                 ev->ignore();
                 return;
@@ -860,5 +833,6 @@
                     && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
                     || d->orientation == Qt::Vertical
-                    || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
+                    || !hasEditFocus()
+                    && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
                 ev->ignore();
                 return;
@@ -880,5 +854,5 @@
                     && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
                     || d->orientation == Qt::Horizontal
-                    || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
+                    || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
                 ev->ignore();
                 break;
@@ -893,5 +867,5 @@
                     && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
                     || d->orientation == Qt::Horizontal
-                    || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
+                    || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
                 ev->ignore();
                 break;
Index: trunk/src/gui/widgets/qabstractslider_p.h
===================================================================
--- trunk/src/gui/widgets/qabstractslider_p.h	(revision 766)
+++ trunk/src/gui/widgets/qabstractslider_p.h	(revision 769)
@@ -139,4 +139,5 @@
         q->triggerAction(repeatAction);
     }
+    bool scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta);
 };
 
Index: trunk/src/gui/widgets/qabstractspinbox.h
===================================================================
--- trunk/src/gui/widgets/qabstractspinbox.h	(revision 766)
+++ trunk/src/gui/widgets/qabstractspinbox.h	(revision 769)
@@ -138,5 +138,7 @@
     void keyPressEvent(QKeyEvent *event);
     void keyReleaseEvent(QKeyEvent *event);
+#ifndef QT_NO_WHEELEVENT
     void wheelEvent(QWheelEvent *event);
+#endif
     void focusInEvent(QFocusEvent *event);
     void focusOutEvent(QFocusEvent *event);
Index: trunk/src/gui/widgets/qcombobox.cpp
===================================================================
--- trunk/src/gui/widgets/qcombobox.cpp	(revision 766)
+++ trunk/src/gui/widgets/qcombobox.cpp	(revision 769)
@@ -77,4 +77,8 @@
 # include <private/qeffects_p.h>
 #endif
+#if defined(Q_WS_S60)
+#include "private/qt_s60_p.h"
+#endif
+
 QT_BEGIN_NAMESPACE
 
@@ -140,5 +144,8 @@
         break;
     }
-
+    if (qVariantCanConvert<QBrush>(index.data(Qt::BackgroundRole))) {
+        menuOption.palette.setBrush(QPalette::All, QPalette::Background,
+                                    qvariant_cast<QBrush>(index.data(Qt::BackgroundRole)));
+    }
     menuOption.text = index.model()->data(index, Qt::DisplayRole).toString()
                            .replace(QLatin1Char('&'), QLatin1String("&&"));
@@ -533,6 +540,8 @@
     const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo);
 #ifndef QT_NO_SCROLLBAR
+#ifndef Q_WS_S60
     if (usePopup)
         view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+#endif
 #endif
     if (combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||
@@ -608,5 +617,11 @@
                                combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo));
         setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo));
-    }
+#ifdef QT_SOFTKEYS_ENABLED
+    } else if (e->type() == QEvent::LanguageChange) {
+        selectAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::SelectSoftKey));
+        cancelAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::CancelSoftKey));
+#endif
+    }
+
     QWidget::changeEvent(e);
 }
@@ -2411,4 +2426,5 @@
         listRect.moveLeft(above.x());
 
+#ifndef Q_WS_S60
         // Position vertically so the curently selected item lines up
         // with the combo box.
@@ -2416,4 +2432,5 @@
         const int offset = listRect.top() - currentItemRect.top();
         listRect.moveTop(above.y() + offset - listRect.top());
+#endif
 
 
@@ -2422,5 +2439,11 @@
         // important to show as much as possible of the popup.
         const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height());
+#ifdef Q_WS_S60
+        //popup needs to be stretched with screen minimum dimension
+        listRect.setHeight(qMin(screen.height(), screen.width()));
+#else
         listRect.setHeight(height);
+#endif
+
         if (boundToScreen) {
             if (listRect.top() < screen.top())
@@ -2429,4 +2452,21 @@
                 listRect.moveBottom(screen.bottom());
         }
+#ifdef Q_WS_S60
+        if (screen.width() < screen.height()) {
+            // in portait, menu should be positioned above softkeys
+            listRect.moveBottom(screen.bottom());
+        } else {
+            TRect staConTopRect = TRect();
+            AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect);
+            listRect.setWidth(listRect.height());
+            //by default popup is centered on screen in landscape
+            listRect.moveCenter(screen.center());
+            if (staConTopRect.IsEmpty()) {
+                // landscape without stacon, menu should be at the right
+                (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) :
+                                                     listRect.setLeft(screen.left());
+            }
+        }
+#endif
     } else if (!boundToScreen || listRect.height() <= belowHeight) {
         listRect.moveTopLeft(below);
@@ -2637,4 +2677,37 @@
             d->updateLineEditGeometry();
         d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
+
+#ifdef Q_WS_S60
+        if (d->container) {
+            QStyleOptionComboBox opt;
+            initStyleOption(&opt);
+
+            if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
+                const QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this));
+
+                QRect listRect(style()->subControlRect(QStyle::CC_ComboBox, &opt,
+                    QStyle::SC_ComboBoxListBoxPopup, this));
+                listRect.setHeight(qMin(screen.height(), screen.width()));
+
+                if (screen.width() < screen.height()) {
+                    // in portait, menu should be positioned above softkeys
+                    listRect.moveBottom(screen.bottom());
+                } else {
+                    TRect staConTopRect = TRect();
+                    AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect);
+                    listRect.setWidth(listRect.height());
+                    //by default popup is centered on screen in landscape
+                    listRect.moveCenter(screen.center());
+                    if (staConTopRect.IsEmpty()) {
+                        // landscape without stacon, menu should be at the right
+                        (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) :
+                                                             listRect.setLeft(screen.left());
+                    }
+                    d->container->setGeometry(listRect);
+                }
+            }
+        }
+#endif
+
         // ### need to update scrollers etc. as well here
         break;
Index: trunk/src/gui/widgets/qcombobox.h
===================================================================
--- trunk/src/gui/widgets/qcombobox.h	(revision 766)
+++ trunk/src/gui/widgets/qcombobox.h	(revision 769)
@@ -246,5 +246,7 @@
     void keyPressEvent(QKeyEvent *e);
     void keyReleaseEvent(QKeyEvent *e);
+#ifndef QT_NO_WHEELEVENT
     void wheelEvent(QWheelEvent *e);
+#endif
     void contextMenuEvent(QContextMenuEvent *e);
     void inputMethodEvent(QInputMethodEvent *);
Index: trunk/src/gui/widgets/qcombobox_p.h
===================================================================
--- trunk/src/gui/widgets/qcombobox_p.h	(revision 766)
+++ trunk/src/gui/widgets/qcombobox_p.h	(revision 769)
@@ -201,5 +201,7 @@
         if (sliderAction == QAbstractSlider::SliderSingleStepAdd)
             menuOpt.state |= QStyle::State_DownArrow;
+#ifndef Q_WS_S60
         p.eraseRect(rect());
+#endif
         style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p);
     }
@@ -271,5 +273,7 @@
                const QModelIndex &index) const {
         QStyleOptionMenuItem opt = getStyleOption(option, index);
+#ifndef Q_WS_S60
         painter->fillRect(option.rect, opt.palette.background());
+#endif
         mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo);
     }
Index: trunk/src/gui/widgets/qdialogbuttonbox.cpp
===================================================================
--- trunk/src/gui/widgets/qdialogbuttonbox.cpp	(revision 766)
+++ trunk/src/gui/widgets/qdialogbuttonbox.cpp	(revision 769)
@@ -1018,4 +1018,6 @@
     new role.
 
+    \note The button box takes ownership of the button.
+
     \sa removeButton(), clear()
 */
Index: trunk/src/gui/widgets/qdockarealayout.cpp
===================================================================
--- trunk/src/gui/widgets/qdockarealayout.cpp	(revision 766)
+++ trunk/src/gui/widgets/qdockarealayout.cpp	(revision 769)
@@ -1991,14 +1991,17 @@
             const int tabBarShape = 0;
 #endif
-            QDockAreaLayoutInfo *info = new QDockAreaLayoutInfo(sep, dockPos, o,
-                                                                tabBarShape, mainWindow);
-            QDockAreaLayoutItem item(info);
+            QDockAreaLayoutItem item(new QDockAreaLayoutInfo(sep, dockPos, o,
+                                                                tabBarShape, mainWindow));
             stream >> item.pos >> item.size >> dummy >> dummy;
-            if (!info->restoreState(stream, widgets, testing))
+            //we need to make sure the element is in the list so the dock widget can eventually be docked correctly
+            if (!testing)
+                item_list.append(item);
+            
+            //here we need to make sure we change the item in the item_list
+            QDockAreaLayoutItem &lastItem = testing ? item : item_list.last();
+
+            if (!lastItem.subinfo->restoreState(stream, widgets, testing))
                 return false;
 
-            if (!testing) {
-                item_list.append(item);
-            }
         } else {
             return false;
@@ -2636,5 +2639,5 @@
     bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
 
-    fallbackToSizeHints = !have_central;
+    fallbackToSizeHints = false;
 
     if (_ver_struct_list != 0) {
Index: trunk/src/gui/widgets/qlinecontrol.cpp
===================================================================
--- trunk/src/gui/widgets/qlinecontrol.cpp	(revision 766)
+++ trunk/src/gui/widgets/qlinecontrol.cpp	(revision 769)
@@ -66,5 +66,5 @@
     If the text has changed will emit displayTextChanged()
 */
-void QLineControl::updateDisplayText()
+void QLineControl::updateDisplayText(bool forceUpdate)
 {
     QString orig = m_textLayout.text();
@@ -103,5 +103,5 @@
     m_ascent = qRound(l.ascent());
 
-    if (str != orig)
+    if (str != orig || forceUpdate)
         emit displayTextChanged(str);
 }
@@ -477,5 +477,5 @@
     }
     m_textLayout.setAdditionalFormats(formats);
-    updateDisplayText();
+    updateDisplayText(/*force*/ true);
     if (cursorPositionChanged)
         emitCursorPositionChanged();
@@ -1372,4 +1372,6 @@
 #ifndef QT_NO_SHORTCUT
         case QEvent::ShortcutOverride:{
+            if (isReadOnly())
+                return false;
             QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
             if (ke == QKeySequence::Copy
Index: trunk/src/gui/widgets/qlinecontrol_p.h
===================================================================
--- trunk/src/gui/widgets/qlinecontrol_p.h	(revision 766)
+++ trunk/src/gui/widgets/qlinecontrol_p.h	(revision 769)
@@ -240,5 +240,5 @@
     void removeSelectedText();
     void internalSetText(const QString &txt, int pos = -1, bool edited = true);
-    void updateDisplayText();
+    void updateDisplayText(bool forceUpdate = false);
 
     void internalInsert(const QString &s);
Index: trunk/src/gui/widgets/qlineedit.cpp
===================================================================
--- trunk/src/gui/widgets/qlineedit.cpp	(revision 766)
+++ trunk/src/gui/widgets/qlineedit.cpp	(revision 769)
@@ -739,6 +739,12 @@
         return false;
     }
-    setCursorPosition(newPos);
-    setSelection(qMin(newMarkAnchor, newMarkDrag), qAbs(newMarkAnchor - newMarkDrag));
+    int selstart = qMin(newMarkAnchor, newMarkDrag);
+    int sellength = qAbs(newMarkAnchor - newMarkDrag);
+    if (selstart == newPos) {
+        selstart = qMax(newMarkAnchor, newMarkDrag);
+        sellength = -sellength;
+    }
+    //setSelection also set the position
+    setSelection(selstart, sellength);
     return true;
 }
Index: trunk/src/gui/widgets/qlineedit_p.cpp
===================================================================
--- trunk/src/gui/widgets/qlineedit_p.cpp	(revision 766)
+++ trunk/src/gui/widgets/qlineedit_p.cpp	(revision 769)
@@ -130,10 +130,10 @@
 {
     Q_Q(QLineEdit);
-    if (control->preeditAreaText().isEmpty()) {
+    if (!control->text().isEmpty() && control->preeditAreaText().isEmpty()) {
         QStyleOptionFrameV2 opt;
         q->initStyleOption(&opt);
         bool showCursor = control->hasSelectedText() ?
                           q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q):
-                          true;
+                          q->hasFocus();
         setCursorVisible(showCursor);
     }
Index: trunk/src/gui/widgets/qmainwindow.cpp
===================================================================
--- trunk/src/gui/widgets/qmainwindow.cpp	(revision 766)
+++ trunk/src/gui/widgets/qmainwindow.cpp	(revision 769)
@@ -66,7 +66,4 @@
 QT_END_NAMESPACE
 #endif
-#ifdef QT_SOFTKEYS_ENABLED
-#include <private/qsoftkeymanager_p.h>
-#endif
 
 QT_BEGIN_NAMESPACE
@@ -80,7 +77,4 @@
 #ifdef Q_WS_MAC
             , useHIToolBar(false)
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
-            , menuBarAction(0)
 #endif
 #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
@@ -95,7 +89,4 @@
     bool useHIToolBar;
 #endif
-#ifdef QT_SOFTKEYS_ENABLED
-    QAction *menuBarAction;
-#endif
     void init();
     QList<int> hoverSeparator;
@@ -118,7 +109,4 @@
     iconSize = QSize(metric, metric);
     q->setAttribute(Qt::WA_Hover);
-#ifdef QT_SOFTKEYS_ENABLED
-    menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q);
-#endif
 }
 
@@ -492,11 +480,4 @@
     }
     d->layout->setMenuBar(menuBar);
-
-#ifdef QT_SOFTKEYS_ENABLED
-    if (menuBar)
-        addAction(d->menuBarAction);
-    else
-        removeAction(d->menuBarAction);
-#endif
 }
 
Index: trunk/src/gui/widgets/qmainwindowlayout.cpp
===================================================================
--- trunk/src/gui/widgets/qmainwindowlayout.cpp	(revision 766)
+++ trunk/src/gui/widgets/qmainwindowlayout.cpp	(revision 769)
@@ -1773,4 +1773,5 @@
 #ifndef QT_NO_DOCKWIDGET
         savedState.dockAreaLayout.centralWidgetItem = layoutState.dockAreaLayout.centralWidgetItem;
+        savedState.dockAreaLayout.fallbackToSizeHints = true;
 #else
         savedState.centralWidgetItem = layoutState.centralWidgetItem;
Index: trunk/src/gui/widgets/qmainwindowlayout_mac.mm
===================================================================
--- trunk/src/gui/widgets/qmainwindowlayout_mac.mm	(revision 766)
+++ trunk/src/gui/widgets/qmainwindowlayout_mac.mm	(revision 769)
@@ -464,4 +464,6 @@
             [[qt_mac_window_for(layoutState.mainWindow->window()) toolbar]
                 removeItemAtIndex:toolbarItemsCopy.indexOf(item)];
+             unifiedToolbarHash.remove(item);
+             qtoolbarsInUnifiedToolbarList.removeAll(toolbar);
 #endif
             break;
Index: trunk/src/gui/widgets/qmenu.cpp
===================================================================
--- trunk/src/gui/widgets/qmenu.cpp	(revision 766)
+++ trunk/src/gui/widgets/qmenu.cpp	(revision 769)
@@ -118,5 +118,5 @@
             parentWidget = parentWidget->parentWidget();
         setParent(parentWidget, Qt::Window | Qt::Tool);
-	setAttribute(Qt::WA_DeleteOnClose, true);
+        setAttribute(Qt::WA_DeleteOnClose, true);
         setAttribute(Qt::WA_X11NetWmWindowTypeMenu, true);
         setWindowTitle(p->windowTitle());
@@ -169,6 +169,6 @@
     selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, q);
     cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Back, q);
-    selectAction->setVisible(false); // Don't show these in the menu
-    cancelAction->setVisible(false);
+    selectAction->setPriority(QAction::HighPriority);
+    cancelAction->setPriority(QAction::HighPriority);
     q->addAction(selectAction);
     q->addAction(cancelAction);
@@ -262,7 +262,4 @@
     const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q);
     const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);
-
-    const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
-    const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
     const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;
 
@@ -338,5 +335,5 @@
 
         if (!sz.isEmpty()) {
-            max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width()));
+            max_column_width = qMax(max_column_width, sz.width());
             //wrapping
             if (!scroll &&
@@ -352,4 +349,8 @@
 
     max_column_width += tabWidth; //finally add in the tab width
+    const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
+    const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
+    max_column_width = qMax(min_column_width, max_column_width);
+
 
     //calculate position
@@ -992,17 +993,7 @@
 }
 
-class ExceptionGuard
-{
-public:
-    inline ExceptionGuard(bool *w = 0) : watched(w) { Q_ASSERT(!(*watched)); *watched = true; }
-    inline ~ExceptionGuard() { *watched = false; }
-    inline operator bool() { return *watched; }
-private:
-    bool *watched;
-};
-
 void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)
 {
-    ExceptionGuard guard(&activationRecursionGuard);
+    QBoolBlocker guard(activationRecursionGuard);
 #ifdef QT3_SUPPORT
     const int actionId = q_func()->findIdForAction(action);
@@ -1227,5 +1218,5 @@
         option->menuItemType = QStyleOptionMenuItem::Separator;
     else if (d->defaultAction == action)
-	    option->menuItemType = QStyleOptionMenuItem::DefaultItem;
+        option->menuItemType = QStyleOptionMenuItem::DefaultItem;
     else
         option->menuItemType = QStyleOptionMenuItem::Normal;
@@ -1407,10 +1398,12 @@
 {
     Q_D(QMenu);
-    QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
-    for (; it != d->widgetItems.end(); ++it) {
-        if (QWidget *widget = it.value()) {
-            QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
-            action->releaseWidget(widget);
-            *it = 0;
+    if (!d->widgetItems.isEmpty()) {  // avoid detach on shared null hash
+        QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
+        for (; it != d->widgetItems.end(); ++it) {
+            if (QWidget *widget = it.value()) {
+                QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
+                action->releaseWidget(widget);
+                *it = 0;
+            }
         }
     }
@@ -1720,5 +1713,12 @@
 {
     QList<QAction*> acts = actions();
+
     for(int i = 0; i < acts.size(); i++) {
+#ifdef QT_SOFTKEYS_ENABLED
+        Q_D(QMenu);
+        // Lets not touch to our internal softkey actions
+        if(acts[i] == d->selectAction || acts[i] == d->cancelAction)
+            continue;
+#endif
         removeAction(acts[i]);
         if (acts[i]->parent() == this && acts[i]->d_func()->widgets.isEmpty())
@@ -2408,4 +2408,11 @@
         }
         return true;
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+    case QEvent::LanguageChange: {
+        d->selectAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::SelectSoftKey));
+        d->cancelAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::CancelSoftKey));
+        }
+        break;
 #endif
     default:
@@ -2798,5 +2805,7 @@
     QAction *action = d->actionAt(e->pos());
     if (!action) {
-        if (d->hasHadMouse)
+        if (d->hasHadMouse
+            && (!d->currentAction
+                || !(d->currentAction->menu() && d->currentAction->menu()->isVisible())))
             d->setCurrentAction(0);
         return;
@@ -2920,5 +2929,5 @@
     if (isVisible()) {
         d->updateActionRects();
-	resize(sizeHint());
+        resize(sizeHint());
         update();
     }
Index: trunk/src/gui/widgets/qmenu.h
===================================================================
--- trunk/src/gui/widgets/qmenu.h	(revision 766)
+++ trunk/src/gui/widgets/qmenu.h	(revision 769)
@@ -143,5 +143,5 @@
 
 #ifdef Q_WS_WINCE
-    HMENU wceMenu(bool create = false);
+    HMENU wceMenu();
 #endif
 
@@ -163,5 +163,7 @@
     void mousePressEvent(QMouseEvent *);
     void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
     void wheelEvent(QWheelEvent *);
+#endif
     void enterEvent(QEvent *);
     void leaveEvent(QEvent *);
Index: trunk/src/gui/widgets/qmenu_mac.mm
===================================================================
--- trunk/src/gui/widgets/qmenu_mac.mm	(revision 766)
+++ trunk/src/gui/widgets/qmenu_mac.mm	(revision 769)
@@ -176,4 +176,20 @@
 }
 
+static void cancelAllMenuTracking()
+{
+#ifdef QT_MAC_USE_COCOA
+    QMacCocoaAutoReleasePool pool;
+    NSMenu *mainMenu = [NSApp mainMenu];
+    [mainMenu cancelTracking];
+    for (NSMenuItem *item in [mainMenu itemArray]) {
+        if ([item submenu]) {
+            [[item submenu] cancelTracking];
+        }
+    }
+#else
+    CancelMenuTracking(AcquireRootMenu(), true, 0);
+#endif
+}
+
 static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp,
                                      const QMacMenuAction *action)
@@ -1831,4 +1847,10 @@
 
     if (qt_mac_current_menubar.qmenubar == q) {
+#ifdef QT_MAC_USE_COCOA
+        QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+        [loader removeActionsFromAppMenu];
+#else
+        cancelAllMenuTracking();
+#endif
         extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
         qt_event_request_menubarupdate();
@@ -1932,18 +1954,4 @@
     // if the menu bar belongs to an ancestor of modalWidget:
     return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget);
-}
-
-static void cancelAllMenuTracking()
-{
-#ifdef QT_MAC_USE_COCOA
-    QMacCocoaAutoReleasePool pool;
-    NSMenu *mainMenu = [NSApp mainMenu];
-    [mainMenu cancelTracking];
-    for (NSMenuItem *item in [mainMenu itemArray]) {
-        if ([item submenu]) {
-            [[item submenu] cancelTracking];
-        }
-    }
-#endif
 }
 
Index: trunk/src/gui/widgets/qmenu_p.h
===================================================================
--- trunk/src/gui/widgets/qmenu_p.h	(revision 766)
+++ trunk/src/gui/widgets/qmenu_p.h	(revision 769)
@@ -348,5 +348,5 @@
         inline void syncAction(QAction *a) { syncAction(findAction(a)); }
         void removeAction(QWceMenuAction *);
-        void rebuild(bool reCreate = false);
+        void rebuild();
         inline void removeAction(QAction *a) { removeAction(findAction(a)); }
         inline QWceMenuAction *findAction(QAction *a) {
@@ -359,5 +359,5 @@
         }
     } *wce_menu;
-    HMENU wceMenu(bool create = false);
+    HMENU wceMenu();
     QAction* wceCommands(uint command);
 #endif
Index: trunk/src/gui/widgets/qmenu_symbian.cpp
===================================================================
--- trunk/src/gui/widgets/qmenu_symbian.cpp	(revision 766)
+++ trunk/src/gui/widgets/qmenu_symbian.cpp	(revision 769)
@@ -150,6 +150,10 @@
 
         const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
-        QString iconText = action->action->iconText();
-        TPtrC menuItemText = qt_QString2TPtrC( underlineShortCut ? action->action->text() : iconText);
+        QString actionText;
+        if (underlineShortCut)
+            actionText = action->action->text().left(CEikMenuPaneItem::SData::ENominalTextLength);
+        else
+            actionText = action->action->iconText().left(CEikMenuPaneItem::SData::ENominalTextLength);
+        TPtrC menuItemText = qt_QString2TPtrC(actionText);
         if (action->action->menu()) {
             SymbianMenuItem* menuItem = new SymbianMenuItem();
@@ -257,4 +261,12 @@
     SymbianMenuItem* menu = qt_symbian_find_menu(id, symbianMenus);
     if (menu) {
+        // Normally first AddMenuItemL call for menuPane will create the item array.
+        // However if we don't have any items, we still need the item array. Otherwise
+        // menupane will crash. That's why we create item array here manually, and
+        // AddMenuItemL will then use the existing array.
+        CEikMenuPane::CItemArray* itemArray = q_check_ptr(new CEikMenuPane::CItemArray);
+        menuPane->SetItemArray(itemArray);
+        menuPane->SetItemArrayOwnedExternally(EFalse);
+
         for (int i = 0; i < menu->children.count(); ++i)
             QT_TRAP_THROWING(menuPane->AddMenuItemL(menu->children.at(i)->menuItemData));
@@ -317,4 +329,12 @@
 }
 
+void QMenuBarPrivate::reparentMenuBar(QWidget *oldParent, QWidget *newParent)
+{
+    if (menubars()->contains(oldParent)) {
+        QMenuBarPrivate *object = menubars()->take(oldParent);
+        menubars()->insert(newParent, object);
+    }
+}
+
 QMenuBarPrivate::QSymbianMenuBarPrivate::QSymbianMenuBarPrivate(QMenuBarPrivate *menubar)
 {
Index: trunk/src/gui/widgets/qmenu_wince.cpp
===================================================================
--- trunk/src/gui/widgets/qmenu_wince.cpp	(revision 766)
+++ trunk/src/gui/widgets/qmenu_wince.cpp	(revision 769)
@@ -102,5 +102,4 @@
 };
 
-typedef int (WINAPI *superfunc)(int, int);
 typedef BOOL (WINAPI *AygCreateMenuBar)(qt_SHMENUBARINFO*);
 typedef HRESULT (WINAPI *AygEnableSoftKey)(HWND,UINT,BOOL,BOOL);
@@ -128,4 +127,5 @@
         ptrEnableSoftKey(handle, command, false, true);
 }
+
 static void qt_wce_disable_soft_key(HWND handle, uint command) 
 {
@@ -135,5 +135,6 @@
 }
 
-static void qt_wce_delete_action_list(QList<QWceMenuAction*> *list) {
+static void qt_wce_delete_action_list(QList<QWceMenuAction*> *list)
+{
     for(QList<QWceMenuAction*>::Iterator it = list->begin(); it != list->end(); ++it) {
         QWceMenuAction *action = (*it);
@@ -145,5 +146,6 @@
 
 //search for first QuitRole in QMenuBar
-static QAction* qt_wce_get_quit_action(QList<QAction *> actionItems) {
+static QAction* qt_wce_get_quit_action(QList<QAction *> actionItems)
+{
     QAction *returnAction = 0;
     for (int i = 0; i < actionItems.size(); ++i) {
@@ -160,5 +162,6 @@
 }
 
-static QAction* qt_wce_get_quit_action(QList<QWceMenuAction*> actionItems) {
+static QAction* qt_wce_get_quit_action(QList<QWceMenuAction*> actionItems)
+{
     for (int i = 0; i < actionItems.size(); ++i) {
         if (actionItems.at(i)->action->menuRole() == QAction::QuitRole)
@@ -173,5 +176,6 @@
 }
 
-static HMODULE qt_wce_get_module_handle() {
+static HMODULE qt_wce_get_module_handle()
+{
     HMODULE module =  0; //handle to resources
     if (!(module = GetModuleHandle(L"QtGui4"))) //release dynamic
@@ -182,5 +186,6 @@
 }
 
-static void qt_wce_change_command(HWND menuHandle, int item, int command) {
+static void qt_wce_change_command(HWND menuHandle, int item, int command)
+{
 TBBUTTONINFOA tbbi;
     memset(&tbbi,0,sizeof(tbbi));
@@ -191,5 +196,6 @@
 }
 
-static void qt_wce_rename_menu_item(HWND menuHandle, int item, const QString &newText) {
+static void qt_wce_rename_menu_item(HWND menuHandle, int item, const QString &newText)
+{
     TBBUTTONINFOA tbbi;
     memset(&tbbi,0,sizeof(tbbi));
@@ -202,5 +208,6 @@
 }
 
-static HWND qt_wce_create_menubar(HWND parentHandle, HINSTANCE resourceHandle, int toolbarID, int flags = 0) {
+static HWND qt_wce_create_menubar(HWND parentHandle, HINSTANCE resourceHandle, int toolbarID, int flags = 0)
+{
     resolveAygLibs();
 
@@ -227,6 +234,6 @@
 }
 
-static void qt_wce_insert_action(HMENU menu, QWceMenuAction *action, bool created) {
-
+static void qt_wce_insert_action(HMENU menu, QWceMenuAction *action)
+{
     Q_ASSERT_X(menu, "AppendMenu", "menu is 0");
     if (action->action->isVisible()) {
@@ -242,5 +249,5 @@
             text.remove(QChar::fromLatin1('&'));
             AppendMenu (menu, MF_STRING | flags | MF_POPUP,
-            (UINT) action->action->menu()->wceMenu(created), reinterpret_cast<const wchar_t *> (text.utf16()));
+            (UINT) action->action->menu()->wceMenu(), reinterpret_cast<const wchar_t *> (text.utf16()));
         }
         else {
@@ -255,4 +262,10 @@
 }
 
+// Removes all items from the menu without destroying the handles.
+static void qt_wce_clear_menu(HMENU hMenu)
+{
+    while (RemoveMenu(hMenu, 0, MF_BYPOSITION));
+}
+
 /*!
     \internal 
@@ -261,10 +274,12 @@
 */
 
-void QMenuBar::wceRefresh() {
+void QMenuBar::wceRefresh()
+{
     for (int i = 0; i < nativeMenuBars.size(); ++i)
         nativeMenuBars.at(i)->d_func()->wceRefresh();
 }
 
-void QMenuBarPrivate::wceRefresh() {
+void QMenuBarPrivate::wceRefresh()
+{
     DrawMenuBar(wce_menubar->menubarHandle);
 }
@@ -276,5 +291,6 @@
 */
 
-QAction* QMenu::wceCommands(uint command) { 
+QAction* QMenu::wceCommands(uint command)
+{
     Q_D(QMenu);
     return d->wceCommands(command);
@@ -288,20 +304,25 @@
 */
 
-void QMenuBar::wceCommands(uint command, HWND) {
-    for (int i = 0; i < nativeMenuBars.size(); ++i)
-            nativeMenuBars.at(i)->d_func()->wceCommands(command);
-}
-
-bool QMenuBarPrivate::wceEmitSignals(QList<QWceMenuAction*> actions, uint command) {
+void QMenuBar::wceCommands(uint command)
+{
+    const HWND hwndActiveWindow = GetActiveWindow();
+    for (int i = 0; i < nativeMenuBars.size(); ++i) {
+        QMenuBarPrivate* nativeMenuBar = nativeMenuBars.at(i)->d_func();
+        if (hwndActiveWindow == nativeMenuBar->wce_menubar->parentWindowHandle)
+            nativeMenuBar->wceCommands(command);
+    }
+}
+
+bool QMenuBarPrivate::wceEmitSignals(QList<QWceMenuAction*> actions, uint command)
+{
     QAction *foundAction = 0;
     for (int i = 0; i < actions.size(); ++i) {
-        if (foundAction)
-            break;
         QWceMenuAction *action = actions.at(i);
         if (action->action->menu()) {
             foundAction = action->action->menu()->wceCommands(command);
+            if (foundAction)
+                break;
         }
         else if (action->command == command) {
-            emit q_func()->triggered(action->action);
             action->action->activate(QAction::Trigger);
             return true;
@@ -315,5 +336,6 @@
 }
 
-void QMenuBarPrivate::wceCommands(uint command) {
+void QMenuBarPrivate::wceCommands(uint command)
+{
     if (wceClassicMenu) {
         for (int i = 0; i < wce_menubar->actionItemsClassic.size(); ++i)
@@ -321,5 +343,5 @@
     } else {
         if (wceEmitSignals(wce_menubar->actionItems, command)) {
-            return ;
+            return;
         }
         else if (wce_menubar->leftButtonIsMenu) {//check if command is on the left quick button
@@ -333,5 +355,6 @@
 }
 
-QAction *QMenuPrivate::wceCommands(uint command) {
+QAction *QMenuPrivate::wceCommands(uint command)
+{
     QAction *foundAction = 0;
     for (int i  = 0; i < wce_menu->actionItems.size(); ++i) {
@@ -343,5 +366,5 @@
         }
         else if (action->command == command) {
-            action->action->activate(QAction::Trigger);
+            activateAction(action->action, QAction::Trigger);
             return action->action;
         }
@@ -352,6 +375,6 @@
 }
 
-void QMenuBarPrivate::wceCreateMenuBar(QWidget *parent) {
-
+void QMenuBarPrivate::wceCreateMenuBar(QWidget *parent)
+{
     Q_Q(QMenuBar);
     wce_menubar = new QWceMenuBarPrivate(this);
@@ -367,19 +390,23 @@
 }
 
-void QMenuBarPrivate::wceDestroyMenuBar() {
+void QMenuBarPrivate::wceDestroyMenuBar()
+{
     Q_Q(QMenuBar);
     int index = nativeMenuBars.indexOf(q);
     nativeMenuBars.removeAt(index);
-    if (wce_menubar)
-      delete wce_menubar;
-    wce_menubar = 0;
-}
-
-QMenuBarPrivate::QWceMenuBarPrivate::QWceMenuBarPrivate(QMenuBarPrivate *menubar) : 
-                                     menubarHandle(0), menuHandle(0),leftButtonMenuHandle(0) , 
-                                     leftButtonAction(0), leftButtonIsMenu(false), d(menubar) {
-}
-
-QMenuBarPrivate::QWceMenuBarPrivate::~QWceMenuBarPrivate() {
+    if (wce_menubar) {
+        delete wce_menubar;
+        wce_menubar = 0;
+    }
+}
+
+QMenuBarPrivate::QWceMenuBarPrivate::QWceMenuBarPrivate(QMenuBarPrivate *menubar)
+:   menubarHandle(0), menuHandle(0), leftButtonMenuHandle(0),
+    leftButtonAction(0), leftButtonIsMenu(false), d(menubar)
+{
+}
+
+QMenuBarPrivate::QWceMenuBarPrivate::~QWceMenuBarPrivate()
+{
     if (menubarHandle)
         DestroyWindow(menubarHandle);
@@ -399,14 +426,18 @@
 }
 
-QMenuPrivate::QWceMenuPrivate::QWceMenuPrivate() {
-    menuHandle = 0;
-}
-
-QMenuPrivate::QWceMenuPrivate::~QWceMenuPrivate() {
+QMenuPrivate::QWceMenuPrivate::QWceMenuPrivate()
+:   menuHandle(0)
+{
+}
+
+QMenuPrivate::QWceMenuPrivate::~QWceMenuPrivate()
+{
     qt_wce_delete_action_list(&actionItems);
-    menuHandle = 0;
-}
-
-void QMenuPrivate::QWceMenuPrivate::addAction(QAction *a, QWceMenuAction *before) {
+    if (menuHandle)
+        DestroyMenu(menuHandle);
+}
+
+void QMenuPrivate::QWceMenuPrivate::addAction(QAction *a, QWceMenuAction *before)
+{
     QWceMenuAction *action = new QWceMenuAction;
     action->action = a;
@@ -415,5 +446,6 @@
 }
 
-void QMenuPrivate::QWceMenuPrivate::addAction(QWceMenuAction *action, QWceMenuAction *before) {
+void QMenuPrivate::QWceMenuPrivate::addAction(QWceMenuAction *action, QWceMenuAction *before)
+{
     if (!action)
         return;
@@ -434,38 +466,47 @@
 */
 
-HMENU QMenu::wceMenu(bool create) { return d_func()->wceMenu(create); }
-
-HMENU QMenuPrivate::wceMenu(bool create) {
+HMENU QMenu::wceMenu()
+{
+    return d_func()->wceMenu();
+}
+
+HMENU QMenuPrivate::wceMenu()
+{
     if (!wce_menu)
         wce_menu = new QWceMenuPrivate;
-    if (!wce_menu->menuHandle || create) 
-        wce_menu->rebuild(create);
+    if (!wce_menu->menuHandle)
+        wce_menu->rebuild();
     return wce_menu->menuHandle;
 }
 
-void QMenuPrivate::QWceMenuPrivate::rebuild(bool reCreate) {
-    if (menuHandle && !reCreate)
-      DestroyMenu(menuHandle);
-    menuHandle = CreatePopupMenu();
+void QMenuPrivate::QWceMenuPrivate::rebuild()
+{
+    if (!menuHandle)
+        menuHandle = CreatePopupMenu();
+    else
+        qt_wce_clear_menu(menuHandle);
+
     for (int i = 0; i < actionItems.size(); ++i) {
         QWceMenuAction *action = actionItems.at(i);
         action->menuHandle = menuHandle;
-        qt_wce_insert_action(menuHandle, action, true);
+        qt_wce_insert_action(menuHandle, action);
     }
     QMenuBar::wceRefresh();
 }
 
-void QMenuPrivate::QWceMenuPrivate::syncAction(QWceMenuAction *) {
+void QMenuPrivate::QWceMenuPrivate::syncAction(QWceMenuAction *)
+{
     rebuild();
 }
 
-void QMenuPrivate::QWceMenuPrivate::removeAction(QWceMenuAction *action) {
-        actionItems.removeAll(action);
-        delete action;
-        action = 0;
-        rebuild();
-}
-
-void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QAction *a, QWceMenuAction *before) {
+void QMenuPrivate::QWceMenuPrivate::removeAction(QWceMenuAction *action)
+{
+    actionItems.removeAll(action);
+    delete action;
+    rebuild();
+}
+
+void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QAction *a, QWceMenuAction *before)
+{
     QWceMenuAction *action = new QWceMenuAction;
     action->action = a;
@@ -474,5 +515,6 @@
 }
 
-void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QWceMenuAction *action, QWceMenuAction *before) {
+void QMenuBarPrivate::QWceMenuBarPrivate::addAction(QWceMenuAction *action, QWceMenuAction *before)
+{
     if (!action)
         return;
@@ -486,23 +528,25 @@
 }
 
-void QMenuBarPrivate::QWceMenuBarPrivate::syncAction(QWceMenuAction*) {
+void QMenuBarPrivate::QWceMenuBarPrivate::syncAction(QWceMenuAction*)
+{
     QMenuBar::wceRefresh();
     rebuild();
 }
 
-void QMenuBarPrivate::QWceMenuBarPrivate::removeAction(QWceMenuAction *action) {
+void QMenuBarPrivate::QWceMenuBarPrivate::removeAction(QWceMenuAction *action)
+{
     actionItems.removeAll(action);
     delete action;
-    action = 0;
     rebuild();
 }
 
-void QMenuBarPrivate::_q_updateDefaultAction() {
+void QMenuBarPrivate::_q_updateDefaultAction()
+{
     if (wce_menubar)
         wce_menubar->rebuild();
 }
 
-void QMenuBarPrivate::QWceMenuBarPrivate::rebuild() {
-
+void QMenuBarPrivate::QWceMenuBarPrivate::rebuild()
+{
     d->q_func()->resize(0,0);
     parentWindowHandle = d->q_func()->parentWidget() ? d->q_func()->parentWidget()->winId() : d->q_func()->winId();
@@ -523,4 +567,5 @@
         }
         Q_ASSERT_X(menubarHandle, "rebuild !created", "menubar already deleted");
+        qt_wce_clear_menu(menuHandle);
         DestroyWindow(menubarHandle);
         menubarHandle = qt_wce_create_menubar(parentWindowHandle, qt_wce_get_module_handle(), resourceHandle);
@@ -550,5 +595,5 @@
                 action->menuHandle = subMenuHandle;
                 actionItemsClassic.last().append(action);
-                qt_wce_insert_action(subMenuHandle, action, true);
+                qt_wce_insert_action(subMenuHandle, action);
             }
         }
@@ -564,4 +609,5 @@
         leftButtonIsMenu = (leftButtonAction && leftButtonAction->menu());
         Q_ASSERT_X(menubarHandle, "rebuild !created", "menubar already deleted");
+        qt_wce_clear_menu(menuHandle);
         DestroyWindow(menubarHandle);
         if (leftButtonIsMenu) {
@@ -592,5 +638,5 @@
             QWceMenuAction *action = actionItems.at(i);
             action->menuHandle = menuHandle;
-            qt_wce_insert_action(menuHandle, action, true);
+            qt_wce_insert_action(menuHandle, action);
         }
         if (!leftButtonIsMenu) {
@@ -612,5 +658,5 @@
                 action->menuHandle = leftButtonMenuHandle;
                 actionItemsLeftButton.append(action);
-                qt_wce_insert_action(leftButtonMenuHandle, action, true);
+                qt_wce_insert_action(leftButtonMenuHandle, action);
             }
         }
Index: trunk/src/gui/widgets/qmenubar.cpp
===================================================================
--- trunk/src/gui/widgets/qmenubar.cpp	(revision 766)
+++ trunk/src/gui/widgets/qmenubar.cpp	(revision 769)
@@ -72,4 +72,8 @@
 #endif
 
+#ifdef QT_SOFTKEYS_ENABLED
+#include <private/qsoftkeymanager_p.h>
+#endif
+
 QT_BEGIN_NAMESPACE
 
@@ -741,14 +745,11 @@
     }
 #endif
-#ifdef Q_WS_S60
-    symbianCreateMenuBar(q->parentWidget());
-    if(symbian_menubar)
-        q->hide();
-#endif
-
     q->setBackgroundRole(QPalette::Button);
     oldWindow = oldParent = 0;
 #ifdef QT3_SUPPORT
     doAutoResize = false;
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+    menuBarAction = 0;
 #endif
     handleReparent();
@@ -1385,8 +1386,35 @@
 #endif
 #ifdef Q_WS_S60
-    if (symbian_menubar)
+
+    // Construct symbian_menubar when this code path is entered first time
+    // and when newParent != NULL
+    if (!symbian_menubar)
+        symbianCreateMenuBar(newParent);
+
+    // Reparent and rebuild menubar when parent is changed
+    if (symbian_menubar) {
+        if (oldParent != newParent)
+            reparentMenuBar(oldParent, newParent);
+        q->hide();
         symbian_menubar->rebuild();
-#endif
-
+    }
+
+#ifdef QT_SOFTKEYS_ENABLED
+    // Constuct menuBarAction when this code path is entered first time
+    if (!menuBarAction) {
+        if (newParent) {
+            menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, newParent);
+            newParent->addAction(menuBarAction);
+        }
+    } else {
+        // If reparenting i.e. we already have menuBarAction, remove it from old parent
+        // and add for a new parent
+        if (oldParent)
+            oldParent->removeAction(menuBarAction);
+        if (newParent)
+            newParent->addAction(menuBarAction);
+    }
+#endif // QT_SOFTKEYS_ENABLED
+#endif // Q_WS_S60
 }
 
@@ -1441,5 +1469,11 @@
         d->itemsDirty = true;
         d->updateGeometries();
-    }
+#ifdef QT_SOFTKEYS_ENABLED
+    } else if (e->type() == QEvent::LanguageChange) {
+        if (d->menuBarAction)
+            d->menuBarAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::MenuSoftKey));
+#endif
+    }
+
     QWidget::changeEvent(e);
 }
@@ -1924,5 +1958,5 @@
 
   Currently there is only support for the default action on Windows
-  Mobile. All other platforms ignore the default action.
+  Mobile. On all other platforms this method is not available.
 
   \sa defaultAction()
Index: trunk/src/gui/widgets/qmenubar.h
===================================================================
--- trunk/src/gui/widgets/qmenubar.h	(revision 766)
+++ trunk/src/gui/widgets/qmenubar.h	(revision 769)
@@ -116,5 +116,5 @@
     QAction *defaultAction() const;
 
-    static void wceCommands(uint command, HWND controlHandle);
+    static void wceCommands(uint command);
     static void wceRefresh();
 #endif
Index: trunk/src/gui/widgets/qmenubar_p.h
===================================================================
--- trunk/src/gui/widgets/qmenubar_p.h	(revision 766)
+++ trunk/src/gui/widgets/qmenubar_p.h	(revision 769)
@@ -244,4 +244,5 @@
     void symbianCreateMenuBar(QWidget *);
     void symbianDestroyMenuBar();
+    void reparentMenuBar(QWidget *oldParent, QWidget *newParent);
     struct QSymbianMenuBarPrivate {
         QList<QSymbianMenuAction*> actionItems;
@@ -268,5 +269,7 @@
     } *symbian_menubar;
     static int symbianCommands(int command);
-
+#ifdef QT_SOFTKEYS_ENABLED
+    QAction *menuBarAction;
+#endif
 #endif
 };
Index: trunk/src/gui/widgets/qprintpreviewwidget.cpp
===================================================================
--- trunk/src/gui/widgets/qprintpreviewwidget.cpp	(revision 766)
+++ trunk/src/gui/widgets/qprintpreviewwidget.cpp	(revision 769)
@@ -152,5 +152,9 @@
     GraphicsView(QWidget* parent = 0)
         : QGraphicsView(parent)
-        {}
+    {
+#ifdef Q_WS_MAC
+        setFrameStyle(QFrame::NoFrame);
+#endif
+    }
 signals:
     void resized();
Index: trunk/src/gui/widgets/qscrollbar.cpp
===================================================================
--- trunk/src/gui/widgets/qscrollbar.cpp	(revision 766)
+++ trunk/src/gui/widgets/qscrollbar.cpp	(revision 769)
@@ -522,4 +522,22 @@
         d_func()->updateHoverControl(he->pos());
         break;
+#ifndef QT_NO_WHEELEVENT
+    case QEvent::Wheel: {
+        // override wheel event without adding virtual function override
+        QWheelEvent *ev = static_cast<QWheelEvent *>(event);
+        int delta = ev->delta();
+        // scrollbar is a special case - in vertical mode it reaches minimum
+        // value in the upper position, however QSlider's minimum value is on
+        // the bottom. So we need to invert a value, but since the scrollbar is
+        // inverted by default, we need to inverse the delta value for the
+        // horizontal orientation.
+        if (ev->orientation() == Qt::Horizontal)
+            delta = -delta;
+        Q_D(QScrollBar);
+        if (d->scrollByDelta(ev->orientation(), ev->modifiers(), delta))
+            event->accept();
+        return true;
+    }
+#endif
     default:
         break;
Index: trunk/src/gui/widgets/qspinbox.cpp
===================================================================
--- trunk/src/gui/widgets/qspinbox.cpp	(revision 766)
+++ trunk/src/gui/widgets/qspinbox.cpp	(revision 769)
@@ -449,9 +449,10 @@
 
 /*!
-    This virtual function is used by the spin box whenever it needs
-    to display the given \a value. The default implementation returns
-    a string containing \a value printed in the standard way using
-    QWidget::locale().toString(). Reimplementations may return anything. (See
-    the example in the detailed description.)
+    This virtual function is used by the spin box whenever it needs to
+    display the given \a value. The default implementation returns a
+    string containing \a value printed in the standard way using
+    QWidget::locale().toString(), but with the thousand separator
+    removed. Reimplementations may return anything. (See the example
+    in the detailed description.)
 
     Note: QSpinBox does not call this function for specialValueText()
@@ -462,5 +463,5 @@
     valueFromText() and validate()
 
-    \sa valueFromText(), validate()
+    \sa valueFromText(), validate(), QLocale::groupSeparator()
 */
 
@@ -870,5 +871,5 @@
     valueFromText().
 
-    \sa valueFromText()
+    \sa valueFromText(), QLocale::groupSeparator()
 */
 
Index: trunk/src/gui/widgets/qtabbar.cpp
===================================================================
--- trunk/src/gui/widgets/qtabbar.cpp	(revision 766)
+++ trunk/src/gui/widgets/qtabbar.cpp	(revision 769)
@@ -68,4 +68,8 @@
 #endif
 
+#ifndef QT_NO_STYLE_S60
+#include "qs60style.h"
+#endif
+
 QT_BEGIN_NAMESPACE
 
@@ -479,4 +483,7 @@
     if (useScrollButtons && tabList.count() && last > available) {
         int extra = extraWidth();
+#ifndef QT_NO_STYLE_S60
+        QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style());
+#endif
         if (!vertTabs) {
             Qt::LayoutDirection ld = q->layoutDirection();
@@ -486,17 +493,46 @@
 
             if (ld == Qt::LeftToRight) {
+// In S60style, tab scroll buttons are layoutted separately, on the sides of the tabbar.
+#ifndef QT_NO_STYLE_S60
+                if (s60Style) {
+                    rightB->setGeometry(arrows.left() + extra / 2, arrows.top(), extra / 2, arrows.height());
+                    leftB->setGeometry(0, arrows.top(), extra / 2, arrows.height());
+                } else {
+#endif
                 leftB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
                 rightB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
                                     extra/2, arrows.height());
+#ifndef QT_NO_STYLE_S60
+                }
+#endif
                 leftB->setArrowType(Qt::LeftArrow);
                 rightB->setArrowType(Qt::RightArrow);
             } else {
+#ifndef QT_NO_STYLE_S60
+                if (s60Style) {
+                    rightB->setGeometry(arrows.left() + extra / 2, arrows.top(), extra / 2, arrows.height());
+                    leftB->setGeometry(0, arrows.top(), extra / 2, arrows.height());
+                } else {
+#endif
                 rightB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
                 leftB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
                                     extra/2, arrows.height());
+#ifndef QT_NO_STYLE_S60
+                }
+#endif
                 rightB->setArrowType(Qt::LeftArrow);
                 leftB->setArrowType(Qt::RightArrow);
             }
         } else {
+#ifndef QT_NO_STYLE_S60
+            if (s60Style) {
+                QRect arrows = QRect(0, 0, size.width(), available );
+                leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra / 2);
+                leftB->setArrowType(Qt::UpArrow);
+                rightB->setGeometry(arrows.left(), arrows.bottom() - extra / 2 + 1,
+                                    arrows.width(), extra / 2);
+                rightB->setArrowType(Qt::DownArrow);
+            } else {
+#endif
             QRect arrows = QRect(0, available - extra, size.width(), extra );
             leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra/2);
@@ -505,4 +541,7 @@
                                 arrows.width(), extra/2);
             rightB->setArrowType(Qt::DownArrow);
+#ifndef QT_NO_STYLE_S60
+            }
+#endif
         }
         leftB->setEnabled(scrollOffset > 0);
Index: trunk/src/gui/widgets/qtoolbar.cpp
===================================================================
--- trunk/src/gui/widgets/qtoolbar.cpp	(revision 766)
+++ trunk/src/gui/widgets/qtoolbar.cpp	(revision 769)
@@ -442,6 +442,5 @@
     to populate the extension pop up with widgets added to the toolbar using
     addWidget(). Please use widget actions created by inheriting QWidgetAction
-    and implementing QWidgetAction::createWidget() instead. This is a known
-    issue which will be fixed in a future release.
+    and implementing QWidgetAction::createWidget() instead.
 
     \sa QToolButton, QMenu, QAction, {Application Example}
Index: trunk/src/multimedia/audio/audio.pri
===================================================================
--- trunk/src/multimedia/audio/audio.pri	(revision 766)
+++ trunk/src/multimedia/audio/audio.pri	(revision 769)
@@ -42,4 +42,19 @@
     wince*:LIBS += -lcoredll
 
+} else:symbian {
+    INCLUDEPATH += /epoc32/include/mmf/common
+    INCLUDEPATH += /epoc32/include/mmf/server
+
+    HEADERS += $$PWD/qaudio_symbian_p.h \
+               $$PWD/qaudiodeviceinfo_symbian_p.h \
+               $$PWD/qaudioinput_symbian_p.h \
+               $$PWD/qaudiooutput_symbian_p.h
+
+    SOURCES += $$PWD/qaudio_symbian_p.cpp \
+               $$PWD/qaudiodeviceinfo_symbian_p.cpp \
+               $$PWD/qaudioinput_symbian_p.cpp \
+               $$PWD/qaudiooutput_symbian_p.cpp
+
+    LIBS += -lmmfdevsound
 } else:unix {
     unix:contains(QT_CONFIG, alsa) {
Index: trunk/src/multimedia/audio/qaudio_symbian_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudio_symbian_p.cpp	(revision 769)
+++ trunk/src/multimedia/audio/qaudio_symbian_p.cpp	(revision 769)
@@ -0,0 +1,624 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudio_symbian_p.h"
+#include <mmffourcc.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace SymbianAudio {
+namespace Utils {
+
+//-----------------------------------------------------------------------------
+// Static data
+//-----------------------------------------------------------------------------
+
+// Sample rate / frequency
+
+typedef TMMFSampleRate SampleRateNative;
+typedef int SampleRateQt;
+
+const int SampleRateCount = 12;
+
+const SampleRateNative SampleRateListNative[SampleRateCount] = {
+        EMMFSampleRate8000Hz
+    ,   EMMFSampleRate11025Hz
+    ,   EMMFSampleRate12000Hz
+    ,   EMMFSampleRate16000Hz
+    ,   EMMFSampleRate22050Hz
+    ,   EMMFSampleRate24000Hz
+    ,   EMMFSampleRate32000Hz
+    ,   EMMFSampleRate44100Hz
+    ,   EMMFSampleRate48000Hz
+    ,   EMMFSampleRate64000Hz
+    ,   EMMFSampleRate88200Hz
+    ,   EMMFSampleRate96000Hz
+};
+
+const SampleRateQt SampleRateListQt[SampleRateCount] = {
+        8000
+    ,   11025
+    ,   12000
+    ,   16000
+    ,   22050
+    ,   24000
+    ,   32000
+    ,   44100
+    ,   48000
+    ,   64000
+    ,   88200
+    ,   96000
+};
+
+// Channels
+
+typedef TMMFMonoStereo ChannelsNative;
+typedef int ChannelsQt;
+
+const int ChannelsCount = 2;
+
+const ChannelsNative ChannelsListNative[ChannelsCount] = {
+        EMMFMono
+    ,   EMMFStereo
+};
+
+const ChannelsQt ChannelsListQt[ChannelsCount] = {
+        1
+    ,   2
+};
+
+// Encoding
+
+const int EncodingCount = 6;
+
+const TUint32 EncodingFourCC[EncodingCount] = {
+        KMMFFourCCCodePCM8              // 0
+    ,   KMMFFourCCCodePCMU8             // 1
+    ,   KMMFFourCCCodePCM16             // 2
+    ,   KMMFFourCCCodePCMU16            // 3
+    ,   KMMFFourCCCodePCM16B            // 4
+    ,   KMMFFourCCCodePCMU16B           // 5
+};
+
+// The characterised DevSound API specification states that the iEncoding
+// field in TMMFCapabilities is ignored, and that the FourCC should be used
+// to specify the PCM encoding.
+// See "SGL.GT0287.102 Multimedia DevSound Baseline Compatibility.doc" in the
+// mm_info/mm_docs repository.
+const TMMFSoundEncoding EncodingNative[EncodingCount] = {
+        EMMFSoundEncoding16BitPCM       // 0
+    ,   EMMFSoundEncoding16BitPCM       // 1
+    ,   EMMFSoundEncoding16BitPCM       // 2
+    ,   EMMFSoundEncoding16BitPCM       // 3
+    ,   EMMFSoundEncoding16BitPCM       // 4
+    ,   EMMFSoundEncoding16BitPCM       // 5
+};
+
+
+const int EncodingSampleSize[EncodingCount] = {
+        8                               // 0
+    ,   8                               // 1
+    ,   16                              // 2
+    ,   16                              // 3
+    ,   16                              // 4
+    ,   16                              // 5
+};
+
+const QAudioFormat::Endian EncodingByteOrder[EncodingCount] = {
+        QAudioFormat::LittleEndian      // 0
+    ,   QAudioFormat::LittleEndian      // 1
+    ,   QAudioFormat::LittleEndian      // 2
+    ,   QAudioFormat::LittleEndian      // 3
+    ,   QAudioFormat::BigEndian         // 4
+    ,   QAudioFormat::BigEndian         // 5
+};
+
+const QAudioFormat::SampleType EncodingSampleType[EncodingCount] = {
+        QAudioFormat::SignedInt         // 0
+    ,   QAudioFormat::UnSignedInt       // 1
+    ,   QAudioFormat::SignedInt         // 2
+    ,   QAudioFormat::UnSignedInt       // 3
+    ,   QAudioFormat::SignedInt         // 4
+    ,   QAudioFormat::UnSignedInt       // 5
+};
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+// Helper functions for implementing parameter conversions
+
+template<typename Input>
+bool findValue(const Input *inputArray, int length, Input input, int &index) {
+    bool result = false;
+    for (int i=0; !result && i<length; ++i)
+        if (inputArray[i] == input) {
+            index = i;
+            result = true;
+        }
+    return result;
+}
+
+template<typename Input, typename Output>
+bool convertValue(const Input *inputArray, const Output *outputArray,
+    int length, Input input, Output &output) {
+    int index;
+    const bool result = findValue<Input>(inputArray, length, input, index);
+    if (result)
+        output = outputArray[index];
+    return result;
+}
+
+/**
+ * Macro which is used to generate the implementation of the conversion
+ * functions.  The implementation is just a wrapper around the templated
+ * convertValue function, e.g.
+ *
+ * CONVERSION_FUNCTION_IMPL(SampleRate, Qt, Native)
+ *
+ * expands to
+ *
+ * bool SampleRateQtToNative(int input, TMMFSampleRate &output) {
+ *      return convertValue<SampleRateQt, SampleRateNative>
+ *          (SampleRateListQt, SampleRateListNative, SampleRateCount,
+ *          input, output);
+ * }
+ */
+#define CONVERSION_FUNCTION_IMPL(FieldLc, Field, Input, Output)               \
+bool FieldLc##Input##To##Output(Field##Input input, Field##Output &output) {  \
+    return convertValue<Field##Input, Field##Output>(Field##List##Input,      \
+        Field##List##Output, Field##Count, input, output);                    \
+}
+
+//-----------------------------------------------------------------------------
+// Local helper functions
+//-----------------------------------------------------------------------------
+
+CONVERSION_FUNCTION_IMPL(sampleRate, SampleRate, Qt, Native)
+CONVERSION_FUNCTION_IMPL(sampleRate, SampleRate, Native, Qt)
+CONVERSION_FUNCTION_IMPL(channels, Channels, Qt, Native)
+CONVERSION_FUNCTION_IMPL(channels, Channels, Native, Qt)
+
+bool sampleInfoQtToNative(int inputSampleSize,
+                          QAudioFormat::Endian inputByteOrder,
+                          QAudioFormat::SampleType inputSampleType,
+                          TUint32 &outputFourCC,
+                          TMMFSoundEncoding &outputEncoding) {
+
+    bool found = false;
+
+    for (int i=0; i<EncodingCount && !found; ++i) {
+        if (    EncodingSampleSize[i] == inputSampleSize
+            &&  EncodingByteOrder[i] == inputByteOrder
+            &&  EncodingSampleType[i] == inputSampleType) {
+            outputFourCC = EncodingFourCC[i];
+            outputEncoding = EncodingNative[i]; // EMMFSoundEncoding16BitPCM
+            found = true;
+        }
+    }
+
+    return found;
+}
+
+void capabilitiesNativeToQt(const TMMFCapabilities &caps,
+                            const TFourCC &fourcc,
+                            QList<int> &frequencies,
+                            QList<int> &channels,
+                            QList<int> &sampleSizes,
+                            QList<QAudioFormat::Endian> &byteOrders,
+                            QList<QAudioFormat::SampleType> &sampleTypes) {
+
+    frequencies.clear();
+    sampleSizes.clear();
+    byteOrders.clear();
+    sampleTypes.clear();
+    channels.clear();
+
+    for (int i=0; i<SampleRateCount; ++i)
+        if (caps.iRate & SampleRateListNative[i])
+            frequencies += SampleRateListQt[i];
+
+    for (int i=0; i<ChannelsCount; ++i)
+        if (caps.iChannels & ChannelsListNative[i])
+            channels += ChannelsListQt[i];
+
+    for (int i=0; i<EncodingCount; ++i) {
+        if (fourcc == EncodingFourCC[i]) {
+            sampleSizes += EncodingSampleSize[i];
+            byteOrders += EncodingByteOrder[i];
+            sampleTypes += EncodingSampleType[i];
+        }
+    }
+}
+
+bool formatQtToNative(const QAudioFormat &inputFormat,
+                      TUint32 &outputFourCC,
+                      TMMFCapabilities &outputFormat) {
+
+    bool result = false;
+
+    // Need to use temporary variables because TMMFCapabilities fields are all
+    // TInt, rather than MMF enumerated types.
+    TMMFSampleRate outputSampleRate;
+    TMMFMonoStereo outputChannels;
+    TMMFSoundEncoding outputEncoding;
+
+    if (inputFormat.codec() == QLatin1String("audio/pcm")) {
+        result =
+                sampleRateQtToNative(inputFormat.frequency(), outputSampleRate)
+            &&  channelsQtToNative(inputFormat.channels(), outputChannels)
+            &&  sampleInfoQtToNative(inputFormat.sampleSize(),
+                                     inputFormat.byteOrder(),
+                                     inputFormat.sampleType(),
+                                     outputFourCC,
+                                     outputEncoding);
+    }
+
+    if (result) {
+        outputFormat.iRate = outputSampleRate;
+        outputFormat.iChannels = outputChannels;
+        outputFormat.iEncoding = outputEncoding;
+    }
+
+    return result;
+}
+
+QAudio::State stateNativeToQt(State nativeState)
+{
+    switch (nativeState) {
+    case ClosedState:
+        return QAudio::StoppedState;
+    case InitializingState:
+        return QAudio::StoppedState;
+    case ActiveState:
+        return QAudio::ActiveState;
+    case IdleState:
+        return QAudio::IdleState;
+    case SuspendedState:
+        return QAudio::SuspendedState;
+    default:
+        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid state");
+        return QAudio::StoppedState; // suppress compiler warning
+    }
+}
+
+qint64 bytesToSamples(const QAudioFormat &format, qint64 length)
+{
+    return length / ((format.sampleSize() / 8) * format.channels());
+}
+
+qint64 samplesToBytes(const QAudioFormat &format, qint64 samples)
+{
+    return samples * (format.sampleSize() / 8) * format.channels();
+}
+
+} // namespace Utils
+
+
+//-----------------------------------------------------------------------------
+// DevSoundWrapper
+//-----------------------------------------------------------------------------
+
+DevSoundWrapper::DevSoundWrapper(QAudio::Mode mode, QObject *parent)
+    :   QObject(parent)
+    ,   m_mode(mode)
+    ,   m_state(StateIdle)
+    ,   m_devsound(0)
+    ,   m_fourcc(0)
+{
+    QT_TRAP_THROWING(m_devsound = CMMFDevSound::NewL());
+
+    switch (mode) {
+    case QAudio::AudioOutput:
+        m_nativeMode = EMMFStatePlaying;
+        break;
+
+    case QAudio::AudioInput:
+        m_nativeMode = EMMFStateRecording;
+        break;
+
+    default:
+        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid mode");
+    }
+
+    getSupportedCodecs();
+}
+
+DevSoundWrapper::~DevSoundWrapper()
+{
+    delete m_devsound;
+}
+
+const QList<QString>& DevSoundWrapper::supportedCodecs() const
+{
+    return m_supportedCodecs;
+}
+
+void DevSoundWrapper::initialize(const QString& codec)
+{
+    Q_ASSERT(StateInitializing != m_state);
+    m_state = StateInitializing;
+    if (QLatin1String("audio/pcm") == codec) {
+        m_fourcc = KMMFFourCCCodePCM16;
+        TRAPD(err, m_devsound->InitializeL(*this, m_fourcc, m_nativeMode));
+        if (KErrNone != err) {
+            m_state = StateIdle;
+            emit initializeComplete(err);
+        }
+    } else {
+        emit initializeComplete(KErrNotSupported);
+    }
+}
+
+const QList<int>& DevSoundWrapper::supportedFrequencies() const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    return m_supportedFrequencies;
+}
+
+const QList<int>& DevSoundWrapper::supportedChannels() const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    return m_supportedChannels;
+}
+
+const QList<int>& DevSoundWrapper::supportedSampleSizes() const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    return m_supportedSampleSizes;
+}
+
+const QList<QAudioFormat::Endian>& DevSoundWrapper::supportedByteOrders() const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    return m_supportedByteOrders;
+}
+
+const QList<QAudioFormat::SampleType>& DevSoundWrapper::supportedSampleTypes() const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    return m_supportedSampleTypes;
+}
+
+bool DevSoundWrapper::isFormatSupported(const QAudioFormat &format) const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    return m_supportedCodecs.contains(format.codec())
+        && m_supportedFrequencies.contains(format.frequency())
+        && m_supportedChannels.contains(format.channels())
+        && m_supportedSampleSizes.contains(format.sampleSize())
+        && m_supportedSampleTypes.contains(format.sampleType())
+        && m_supportedByteOrders.contains(format.byteOrder());
+}
+
+int DevSoundWrapper::samplesProcessed() const
+{
+    Q_ASSERT(StateInitialized == m_state);
+    int result = 0;
+    switch (m_mode) {
+    case QAudio::AudioInput:
+        result = m_devsound->SamplesRecorded();
+        break;
+    case QAudio::AudioOutput:
+        result = m_devsound->SamplesPlayed();
+        break;
+    }
+    return result;
+}
+
+bool DevSoundWrapper::setFormat(const QAudioFormat &format)
+{
+    Q_ASSERT(StateInitialized == m_state);
+    bool result = false;
+    TUint32 fourcc;
+    TMMFCapabilities nativeFormat;
+    if (Utils::formatQtToNative(format, fourcc, nativeFormat)) {
+        TMMFCapabilities currentNativeFormat = m_devsound->Config();
+        nativeFormat.iBufferSize = currentNativeFormat.iBufferSize;
+        TRAPD(err, m_devsound->SetConfigL(nativeFormat));
+        result = (KErrNone == err);
+    }
+    return result;
+}
+
+bool DevSoundWrapper::start()
+{
+    Q_ASSERT(StateInitialized == m_state);
+    int err = KErrArgument;
+    switch (m_mode) {
+    case QAudio::AudioInput:
+        TRAP(err, m_devsound->RecordInitL());
+        break;
+    case QAudio::AudioOutput:
+        TRAP(err, m_devsound->PlayInitL());
+        break;
+    }
+    return (KErrNone == err);
+}
+
+void DevSoundWrapper::pause()
+{
+    Q_ASSERT(StateInitialized == m_state);
+    m_devsound->Pause();
+}
+
+void DevSoundWrapper::stop()
+{
+    m_devsound->Stop();
+}
+
+void DevSoundWrapper::bufferProcessed()
+{
+    Q_ASSERT(StateInitialized == m_state);
+    switch (m_mode) {
+    case QAudio::AudioInput:
+        m_devsound->RecordData();
+        break;
+    case QAudio::AudioOutput:
+        m_devsound->PlayData();
+        break;
+    }
+}
+
+void DevSoundWrapper::getSupportedCodecs()
+{
+/*
+ * TODO: once we support formats other than PCM, this function should
+ * convert the array of FourCC codes into MIME types for each codec.
+ *
+    RArray<TFourCC> fourcc;
+    QT_TRAP_THROWING(CleanupClosePushL(&fourcc));
+
+    TMMFPrioritySettings settings;
+    switch (mode) {
+    case QAudio::AudioOutput:
+        settings.iState = EMMFStatePlaying;
+        m_devsound->GetSupportedInputDataTypesL(fourcc, settings);
+        break;
+
+    case QAudio::AudioInput:
+        settings.iState = EMMFStateRecording;
+        m_devsound->GetSupportedInputDataTypesL(fourcc, settings);
+        break;
+
+    default:
+        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid mode");
+    }
+
+    CleanupStack::PopAndDestroy(); // fourcc
+*/
+
+    m_supportedCodecs.append(QLatin1String("audio/pcm"));
+}
+
+void DevSoundWrapper::populateCapabilities()
+{
+    m_supportedFrequencies.clear();
+    m_supportedChannels.clear();
+    m_supportedSampleSizes.clear();
+    m_supportedByteOrders.clear();
+    m_supportedSampleTypes.clear();
+
+    const TMMFCapabilities caps = m_devsound->Capabilities();
+
+    for (int i=0; i<Utils::SampleRateCount; ++i)
+        if (caps.iRate & Utils::SampleRateListNative[i])
+            m_supportedFrequencies += Utils::SampleRateListQt[i];
+
+    for (int i=0; i<Utils::ChannelsCount; ++i)
+        if (caps.iChannels & Utils::ChannelsListNative[i])
+            m_supportedChannels += Utils::ChannelsListQt[i];
+
+    for (int i=0; i<Utils::EncodingCount; ++i) {
+        if (m_fourcc == Utils::EncodingFourCC[i]) {
+            m_supportedSampleSizes += Utils::EncodingSampleSize[i];
+            m_supportedByteOrders += Utils::EncodingByteOrder[i];
+            m_supportedSampleTypes += Utils::EncodingSampleType[i];
+        }
+    }
+}
+
+void DevSoundWrapper::InitializeComplete(TInt aError)
+{
+    Q_ASSERT(StateInitializing == m_state);
+    if (KErrNone == aError) {
+        m_state = StateInitialized;
+        populateCapabilities();
+    } else {
+        m_state = StateIdle;
+    }
+    emit initializeComplete(aError);
+}
+
+void DevSoundWrapper::ToneFinished(TInt aError)
+{
+    Q_UNUSED(aError)
+    // This class doesn't use DevSound's tone playback functions, so should
+    // never receive this callback.
+    Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback");
+}
+
+void DevSoundWrapper::BufferToBeFilled(CMMFBuffer *aBuffer)
+{
+    Q_ASSERT(QAudio::AudioOutput == m_mode);
+    emit bufferToBeProcessed(aBuffer);
+}
+
+void DevSoundWrapper::PlayError(TInt aError)
+{
+    Q_ASSERT(QAudio::AudioOutput == m_mode);
+    emit processingError(aError);
+}
+
+void DevSoundWrapper::BufferToBeEmptied(CMMFBuffer *aBuffer)
+{
+    Q_ASSERT(QAudio::AudioInput == m_mode);
+    emit bufferToBeProcessed(aBuffer);
+}
+
+void DevSoundWrapper::RecordError(TInt aError)
+{
+    Q_ASSERT(QAudio::AudioInput == m_mode);
+    emit processingError(aError);
+}
+
+void DevSoundWrapper::ConvertError(TInt aError)
+{
+    Q_UNUSED(aError)
+    // This class doesn't use DevSound's format conversion functions, so
+    // should never receive this callback.
+    Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback");
+}
+
+void DevSoundWrapper::DeviceMessage(TUid aMessageType, const TDesC8 &aMsg)
+{
+    Q_UNUSED(aMessageType)
+    Q_UNUSED(aMsg)
+    // Ignore this callback.
+}
+
+
+} // namespace SymbianAudio
+
+QT_END_NAMESPACE
+
+
Index: trunk/src/multimedia/audio/qaudio_symbian_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudio_symbian_p.h	(revision 769)
+++ trunk/src/multimedia/audio/qaudio_symbian_p.h	(revision 769)
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists for the convenience
+// of other Qt classes.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIO_SYMBIAN_P_H
+#define QAUDIO_SYMBIAN_P_H
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtMultimedia/qaudioformat.h>
+#include <QtMultimedia/qaudio.h>
+#include <sounddevice.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace SymbianAudio {
+
+/**
+ * Default values used by audio input and output classes, when underlying
+ * DevSound instance has not yet been created.
+ */
+
+const int DefaultBufferSize = 4096; // bytes
+const int DefaultNotifyInterval = 1000; // ms
+
+/**
+ * Enumeration used to track state of internal DevSound instances.
+ * Values are translated to the corresponding QAudio::State values by
+ * SymbianAudio::Utils::stateNativeToQt.
+ */
+enum State {
+        ClosedState
+    ,   InitializingState
+    ,   ActiveState
+    ,   IdleState
+    ,   SuspendedState
+};
+
+/**
+ * Wrapper around DevSound instance
+ */
+class DevSoundWrapper
+    :   public QObject
+    ,   public MDevSoundObserver
+{
+    Q_OBJECT
+
+public:
+    DevSoundWrapper(QAudio::Mode mode, QObject *parent = 0);
+    ~DevSoundWrapper();
+
+public:
+    // List of supported codecs; can be called once object is constructed
+    const QList<QString>& supportedCodecs() const;
+
+    // Asynchronous initialization function; emits devsoundInitializeComplete
+    void initialize(const QString& codec);
+
+    // Capabilities, for selected codec.  Can be called once initialize has returned
+    // successfully.
+    const QList<int>& supportedFrequencies() const;
+    const QList<int>& supportedChannels() const;
+    const QList<int>& supportedSampleSizes() const;
+    const QList<QAudioFormat::Endian>& supportedByteOrders() const;
+    const QList<QAudioFormat::SampleType>& supportedSampleTypes() const;
+
+    bool isFormatSupported(const QAudioFormat &format) const;
+
+    int samplesProcessed() const;
+    bool setFormat(const QAudioFormat &format);
+    bool start();
+    void pause();
+    void stop();
+    void bufferProcessed();
+
+public:
+    // MDevSoundObserver
+    void InitializeComplete(TInt aError);
+    void ToneFinished(TInt aError);
+    void BufferToBeFilled(CMMFBuffer *aBuffer);
+    void PlayError(TInt aError);
+    void BufferToBeEmptied(CMMFBuffer *aBuffer);
+    void RecordError(TInt aError);
+    void ConvertError(TInt aError);
+    void DeviceMessage(TUid aMessageType, const TDesC8 &aMsg);
+
+signals:
+    void initializeComplete(int error);
+    void bufferToBeProcessed(CMMFBuffer *buffer);
+    void processingError(int error);
+
+private:
+    void getSupportedCodecs();
+    void populateCapabilities();
+
+private:
+    const QAudio::Mode              m_mode;
+    TMMFState                       m_nativeMode;
+
+    enum State {
+        StateIdle,
+        StateInitializing,
+        StateInitialized
+    }                               m_state;
+
+    CMMFDevSound*                   m_devsound;
+    TFourCC                         m_fourcc;
+
+    QList<QString>                  m_supportedCodecs;
+    QList<int>                      m_supportedFrequencies;
+    QList<int>                      m_supportedChannels;
+    QList<int>                      m_supportedSampleSizes;
+    QList<QAudioFormat::Endian>     m_supportedByteOrders;
+    QList<QAudioFormat::SampleType> m_supportedSampleTypes;
+
+};
+
+
+namespace Utils {
+
+/**
+ * Convert internal states to QAudio states.
+ */
+QAudio::State stateNativeToQt(State nativeState);
+
+/**
+ * Convert data length to number of samples.
+ */
+qint64 bytesToSamples(const QAudioFormat &format, qint64 length);
+
+/**
+ * Convert number of samples to data length.
+ */
+qint64 samplesToBytes(const QAudioFormat &format, qint64 samples);
+
+} // namespace Utils
+} // namespace SymbianAudio
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/multimedia/audio/qaudiodevicefactory.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiodevicefactory.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiodevicefactory.cpp	(revision 769)
@@ -59,4 +59,8 @@
 #include "qaudiooutput_alsa_p.h"
 #include "qaudioinput_alsa_p.h"
+#elif defined(Q_OS_SYMBIAN)
+#include "qaudiodeviceinfo_symbian_p.h"
+#include "qaudiooutput_symbian_p.h"
+#include "qaudioinput_symbian_p.h"
 #endif
 #endif
@@ -129,5 +133,5 @@
     QList<QAudioDeviceInfo> devices;
 #ifndef QT_NO_AUDIO_BACKEND
-#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA) || defined(Q_OS_SYMBIAN))
     foreach (const QByteArray &handle, QAudioDeviceInfoInternal::availableDevices(mode))
         devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode);
@@ -159,5 +163,5 @@
     }
 #ifndef QT_NO_AUDIO_BACKEND
-#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA) || defined(Q_OS_SYMBIAN))
     return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultInputDevice(), QAudio::AudioInput);
 #endif
@@ -176,5 +180,5 @@
     }
 #ifndef QT_NO_AUDIO_BACKEND
-#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA) || defined(Q_OS_SYMBIAN))
     return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultOutputDevice(), QAudio::AudioOutput);
 #endif
@@ -188,5 +192,5 @@
 
 #ifndef QT_NO_AUDIO_BACKEND
-#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA) || defined(Q_OS_SYMBIAN))
     if (realm == QLatin1String("builtin"))
         return new QAudioDeviceInfoInternal(handle, mode);
@@ -217,5 +221,5 @@
         return new QNullInputDevice();
 #ifndef QT_NO_AUDIO_BACKEND
-#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA) || defined(Q_OS_SYMBIAN))
     if (deviceInfo.realm() == QLatin1String("builtin"))
         return new QAudioInputPrivate(deviceInfo.handle(), format);
@@ -236,5 +240,5 @@
         return new QNullOutputDevice();
 #ifndef QT_NO_AUDIO_BACKEND
-#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA) || defined(Q_OS_SYMBIAN))
     if (deviceInfo.realm() == QLatin1String("builtin"))
         return new QAudioOutputPrivate(deviceInfo.handle(), format);
Index: trunk/src/multimedia/audio/qaudiodeviceinfo.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiodeviceinfo.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiodeviceinfo.cpp	(revision 769)
@@ -44,4 +44,5 @@
 #include <QtMultimedia/qaudiodeviceinfo.h>
 
+#include <QtCore/qmap.h>
 
 QT_BEGIN_NAMESPACE
@@ -239,5 +240,64 @@
 QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const
 {
-    return isNull() ? QAudioFormat() : d->info->nearestFormat(settings);
+    if (isFormatSupported(settings))
+        return settings;
+
+    QAudioFormat nearest = settings;
+
+    nearest.setCodec(QLatin1String("audio/pcm"));
+
+    if (nearest.sampleType() == QAudioFormat::Unknown) {
+        QAudioFormat preferred = preferredFormat();
+        nearest.setSampleType(preferred.sampleType());
+    }
+
+    QMap<int,int> testFrequencies;
+    QList<int> frequenciesAvailable = supportedFrequencies();
+    QMap<int,int> testSampleSizes;
+    QList<int> sampleSizesAvailable = supportedSampleSizes();
+
+    // Get sorted sampleSizes (equal to and ascending values only)
+    if (sampleSizesAvailable.contains(settings.sampleSize()))
+        testSampleSizes.insert(0,settings.sampleSize());
+    sampleSizesAvailable.removeAll(settings.sampleSize());
+    foreach (int size, sampleSizesAvailable) {
+        int larger  = (size > settings.sampleSize()) ? size : settings.sampleSize();
+        int smaller = (size > settings.sampleSize()) ? settings.sampleSize() : size;
+        if (size >= settings.sampleSize()) {
+            int diff = larger - smaller;
+            testSampleSizes.insert(diff, size);
+        }
+    }
+
+    // Get sorted frequencies (equal to and ascending values only)
+    if (frequenciesAvailable.contains(settings.frequency()))
+        testFrequencies.insert(0,settings.frequency());
+    frequenciesAvailable.removeAll(settings.frequency());
+    foreach (int frequency, frequenciesAvailable) {
+        int larger  = (frequency > settings.frequency()) ? frequency : settings.frequency();
+        int smaller = (frequency > settings.frequency()) ? settings.frequency() : frequency;
+        if (frequency >= settings.frequency()) {
+            int diff = larger - smaller;
+            testFrequencies.insert(diff, frequency);
+        }
+    }
+
+    // Try to find nearest
+    // Check ascending frequencies, ascending sampleSizes
+    QMapIterator<int, int> sz(testSampleSizes);
+    while (sz.hasNext()) {
+        sz.next();
+        nearest.setSampleSize(sz.value());
+        QMapIterator<int, int> i(testFrequencies);
+        while (i.hasNext()) {
+            i.next();
+            nearest.setFrequency(i.value());
+            if (isFormatSupported(nearest))
+                return nearest;
+        }
+    }
+
+    //Fallback
+    return preferredFormat();
 }
 
Index: trunk/src/multimedia/audio/qaudiodeviceinfo_symbian_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiodeviceinfo_symbian_p.cpp	(revision 769)
+++ trunk/src/multimedia/audio/qaudiodeviceinfo_symbian_p.cpp	(revision 769)
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QCoreApplication>
+#include "qaudiodeviceinfo_symbian_p.h"
+#include "qaudio_symbian_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray device,
+                                               QAudio::Mode mode)
+    :   m_deviceName(QLatin1String(device))
+    ,   m_mode(mode)
+    ,   m_updated(false)
+{
+
+}
+
+QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal()
+{
+
+}
+
+QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const
+{
+    QAudioFormat format;
+    switch (m_mode) {
+    case QAudio::AudioOutput:
+        format.setFrequency(44100);
+        format.setChannels(2);
+        format.setSampleSize(16);
+        format.setByteOrder(QAudioFormat::LittleEndian);
+        format.setSampleType(QAudioFormat::SignedInt);
+        format.setCodec(QLatin1String("audio/pcm"));
+        break;
+
+    case QAudio::AudioInput:
+        format.setFrequency(8000);
+        format.setChannels(1);
+        format.setSampleSize(16);
+        format.setByteOrder(QAudioFormat::LittleEndian);
+        format.setSampleType(QAudioFormat::SignedInt);
+        format.setCodec(QLatin1String("audio/pcm"));
+        break;
+
+    default:
+        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid mode");
+    }
+
+    if (!isFormatSupported(format)) {
+        format = QAudioFormat();
+        format.setCodec(QLatin1String("audio/pcm"));
+        if (m_capabilities.contains(format.codec())) {
+            const Capabilities &codecCaps = m_capabilities[format.codec()];
+            if (codecCaps.m_frequencies.size())
+                format.setFrequency(codecCaps.m_frequencies[0]);
+            if (codecCaps.m_channels.size())
+                format.setChannels(codecCaps.m_channels[0]);
+            if (codecCaps.m_sampleSizes.size())
+                format.setSampleSize(codecCaps.m_sampleSizes[0]);
+            if (codecCaps.m_byteOrders.size())
+                format.setByteOrder(codecCaps.m_byteOrders[0]);
+            if (codecCaps.m_sampleTypes.size())
+                format.setSampleType(codecCaps.m_sampleTypes[0]);
+        }
+    }
+
+    return format;
+}
+
+bool QAudioDeviceInfoInternal::isFormatSupported(
+                                 const QAudioFormat &format) const
+{
+    getSupportedFormats();
+    bool supported = false;
+    if (m_capabilities.contains(format.codec())) {
+        const Capabilities &codecCaps = m_capabilities[format.codec()];
+        supported = codecCaps.m_frequencies.contains(format.frequency())
+                &&  codecCaps.m_channels.contains(format.channels())
+                &&  codecCaps.m_sampleSizes.contains(format.sampleSize())
+                &&  codecCaps.m_byteOrders.contains(format.byteOrder())
+                &&  codecCaps.m_sampleTypes.contains(format.sampleType());
+    }
+    return supported;
+}
+
+QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat &format) const
+{
+    if (isFormatSupported(format))
+        return format;
+    else
+        return preferredFormat();
+}
+
+QString QAudioDeviceInfoInternal::deviceName() const
+{
+    return m_deviceName;
+}
+
+QStringList QAudioDeviceInfoInternal::codecList()
+{
+    getSupportedFormats();
+    return m_capabilities.keys();
+}
+
+QList<int> QAudioDeviceInfoInternal::frequencyList()
+{
+    getSupportedFormats();
+    return m_unionCapabilities.m_frequencies;
+}
+
+QList<int> QAudioDeviceInfoInternal::channelsList()
+{
+    getSupportedFormats();
+    return m_unionCapabilities.m_channels;
+}
+
+QList<int> QAudioDeviceInfoInternal::sampleSizeList()
+{
+    getSupportedFormats();
+    return m_unionCapabilities.m_sampleSizes;
+}
+
+QList<QAudioFormat::Endian> QAudioDeviceInfoInternal::byteOrderList()
+{
+    getSupportedFormats();
+    return m_unionCapabilities.m_byteOrders;
+}
+
+QList<QAudioFormat::SampleType> QAudioDeviceInfoInternal::sampleTypeList()
+{
+    getSupportedFormats();
+    return m_unionCapabilities.m_sampleTypes;
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultInputDevice()
+{
+    return QByteArray("default");
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
+{
+    return QByteArray("default");
+}
+
+QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode)
+{
+    QList<QByteArray> result;
+    result += QByteArray("default");
+    return result;
+}
+
+void QAudioDeviceInfoInternal::devsoundInitializeComplete(int err)
+{
+    m_intializationResult = err;
+    m_initializing = false;
+}
+
+// Helper function
+template<typename T>
+void appendUnique(QList<T> &left, const QList<T> &right)
+{
+    foreach (const T &value, right)
+        if (!left.contains(value))
+            left += value;
+}
+
+void QAudioDeviceInfoInternal::getSupportedFormats() const
+{
+    if (!m_updated) {
+        QScopedPointer<SymbianAudio::DevSoundWrapper> devsound(new SymbianAudio::DevSoundWrapper(m_mode));
+        connect(devsound.data(), SIGNAL(initializeComplete(int)),
+                this, SLOT(devsoundInitializeComplete(int)));
+
+        foreach (const QString& codec, devsound->supportedCodecs()) {
+            m_initializing = true;
+            devsound->initialize(codec);
+            while (m_initializing)
+                QCoreApplication::instance()->processEvents(QEventLoop::WaitForMoreEvents);
+            if (KErrNone == m_intializationResult) {
+                m_capabilities[codec].m_frequencies = devsound->supportedFrequencies();
+                appendUnique(m_unionCapabilities.m_frequencies, devsound->supportedFrequencies());
+
+                m_capabilities[codec].m_channels = devsound->supportedChannels();
+                appendUnique(m_unionCapabilities.m_channels, devsound->supportedChannels());
+
+                m_capabilities[codec].m_sampleSizes = devsound->supportedSampleSizes();
+                appendUnique(m_unionCapabilities.m_sampleSizes, devsound->supportedSampleSizes());
+
+                m_capabilities[codec].m_byteOrders = devsound->supportedByteOrders();
+                appendUnique(m_unionCapabilities.m_byteOrders, devsound->supportedByteOrders());
+
+                m_capabilities[codec].m_sampleTypes = devsound->supportedSampleTypes();
+                appendUnique(m_unionCapabilities.m_sampleTypes, devsound->supportedSampleTypes());
+            }
+        }
+
+        m_updated = true;
+    }
+}
+
+QT_END_NAMESPACE
Index: trunk/src/multimedia/audio/qaudiodeviceinfo_symbian_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudiodeviceinfo_symbian_p.h	(revision 769)
+++ trunk/src/multimedia/audio/qaudiodeviceinfo_symbian_p.h	(revision 769)
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists for the convenience
+// of other Qt classes.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIODEVICEINFO_SYMBIAN_P_H
+#define QAUDIODEVICEINFO_SYMBIAN_P_H
+
+#include <QtCore/QMap>
+#include <QtMultimedia/qaudioengine.h>
+#include <sounddevice.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace SymbianAudio {
+class DevSoundWrapper;
+}
+
+class QAudioDeviceInfoInternal
+    :   public QAbstractAudioDeviceInfo
+{
+    Q_OBJECT
+
+public:
+    QAudioDeviceInfoInternal(QByteArray device, QAudio::Mode mode);
+    ~QAudioDeviceInfoInternal();
+
+    // QAbstractAudioDeviceInfo
+    QAudioFormat preferredFormat() const;
+    bool isFormatSupported(const QAudioFormat &format) const;
+    QAudioFormat nearestFormat(const QAudioFormat &format) const;
+    QString deviceName() const;
+    QStringList codecList();
+    QList<int> frequencyList();
+    QList<int> channelsList();
+    QList<int> sampleSizeList();
+    QList<QAudioFormat::Endian> byteOrderList();
+    QList<QAudioFormat::SampleType> sampleTypeList();
+    static QByteArray defaultInputDevice();
+    static QByteArray defaultOutputDevice();
+    static QList<QByteArray> availableDevices(QAudio::Mode);
+
+private slots:
+    void devsoundInitializeComplete(int err);
+
+private:
+    void getSupportedFormats() const;
+
+private:
+    mutable bool m_initializing;
+    int m_intializationResult;
+
+    QString m_deviceName;
+    QAudio::Mode m_mode;
+
+    struct Capabilities
+    {
+        QList<int> m_frequencies;
+        QList<int> m_channels;
+        QList<int> m_sampleSizes;
+        QList<QAudioFormat::Endian> m_byteOrders;
+        QList<QAudioFormat::SampleType> m_sampleTypes;
+    };
+
+    // Mutable to allow lazy initialization when called from const-qualified
+    // public functions (isFormatSupported, nearestFormat)
+    mutable bool m_updated;
+    mutable QMap<QString, Capabilities> m_capabilities;
+    mutable Capabilities m_unionCapabilities;
+};
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp	(revision 769)
@@ -79,4 +79,6 @@
     device = QLatin1String(dev);
     this->mode = mode;
+
+    updateLists();
 }
 
@@ -177,20 +179,68 @@
 
     bool failed = false;
-
-    // For now, just accept only audio/pcm codec
-    if(!format.codec().startsWith(QLatin1String("audio/pcm")))
-        failed = true;
-
-    if(!failed && !(format.channels() == 1 || format.channels() == 2))
-        failed = true;
-
-    if(!failed) {
-        if(!(format.frequency() == 8000 || format.frequency() == 11025 || format.frequency() == 22050 ||
-	   format.frequency() == 44100 || format.frequency() == 48000 || format.frequency() == 96000))
-	    failed = true;
-    }
-
-    if(!failed && !(format.sampleSize() == 8 || format.sampleSize() == 16))
-        failed = true;
+    bool match = false;
+
+    // check codec
+    for( int i = 0; i < codecz.count(); i++) {
+        if (format.codec() == codecz.at(i))
+            match = true;
+    }
+    if (!match) failed = true;
+
+    // check channel
+    match = false;
+    if (!failed) {
+        for( int i = 0; i < channelz.count(); i++) {
+            if (format.channels() == channelz.at(i)) {
+                match = true;
+                break;
+            }
+        }
+    }
+    if (!match) failed = true;
+
+    // check frequency
+    match = false;
+    if (!failed) {
+        for( int i = 0; i < freqz.count(); i++) {
+            if (format.frequency() == freqz.at(i)) {
+                match = true;
+                break;
+            }
+        }
+    }
+
+    // check sample size
+    match = false;
+    if (!failed) {
+        for( int i = 0; i < sizez.count(); i++) {
+            if (format.sampleSize() == sizez.at(i)) {
+                match = true;
+                break;
+            }
+        }
+    }
+
+    // check byte order
+    match = false;
+    if (!failed) {
+        for( int i = 0; i < byteOrderz.count(); i++) {
+            if (format.byteOrder() == byteOrderz.at(i)) {
+                match = true;
+                break;
+            }
+        }
+    }
+
+    // check sample type
+    match = false;
+    if (!failed) {
+        for( int i = 0; i < typez.count(); i++) {
+            if (format.sampleType() == typez.at(i)) {
+                match = true;
+                break;
+            }
+        }
+    }
 
     if(!failed) {
@@ -333,4 +383,6 @@
 	codecz.append(QLatin1String("audio/pcm"));
     }
+    if (freqz.count() > 0)
+        freqz.prepend(8000);
 }
 
Index: trunk/src/multimedia/audio/qaudioinput.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudioinput.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudioinput.cpp	(revision 769)
@@ -96,5 +96,5 @@
       format.setSampleType(QAudioFormat::UnSignedInt);
 
-      if (QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
+      QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
       if (!info.isFormatSupported(format)) {
           qWarning()<<"default format not supported try to use nearest";
@@ -147,4 +147,18 @@
 
     \sa QAudioOutput, QAudioDeviceInfo
+
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use this class must have the
+    \c UserEnvironment platform security capability.  If the client
+    process lacks this capability, calls to either overload of start()
+    will fail.
+    This failure is indicated by the QAudioInput object setting
+    its error() value to \l{QAudio::OpenError} and then emitting a
+    \l{stateChanged()}{stateChanged}(\l{QAudio::StoppedState}) signal.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
 */
 
@@ -191,4 +205,17 @@
      All that is required is to open the QIODevice.
 
+     If able to successfully get audio data from the systems audio device the
+     state() is set to either QAudio::ActiveState or QAudio::IdleState,
+     error() is set to QAudio::NoError and the stateChanged() signal is emitted.
+
+     If a problem occurs during this process the error() is set to QAudio::OpenError,
+     state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+    In either case, the stateChanged() signal may be emitted either synchronously
+    during execution of the start() function or asynchronously after start() has
+    returned to the caller.
+
+     \sa {Symbian Platform Security Requirements}
+
      \sa QIODevice
 */
@@ -196,11 +223,4 @@
 void QAudioInput::start(QIODevice* device)
 {
-    /*
-       -If currently not StoppedState, stop
-       -If previous start was push mode, delete internal QIODevice.
-       -open audio input.
-       If ok, NoError and ActiveState, else OpenError and StoppedState.
-       -emit stateChanged()
-    */
     d->start(device);
 }
@@ -211,4 +231,17 @@
     directly.
 
+    If able to access the systems audio device the state() is set to
+    QAudio::IdleState, error() is set to QAudio::NoError
+    and the stateChanged() signal is emitted.
+
+    If a problem occurs during this process the error() is set to QAudio::OpenError,
+    state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+    In either case, the stateChanged() signal may be emitted either synchronously
+    during execution of the start() function or asynchronously after start() has
+    returned to the caller.
+
+    \sa {Symbian Platform Security Requirements}
+
     \sa QIODevice
 */
@@ -216,12 +249,4 @@
 QIODevice* QAudioInput::start()
 {
-    /*
-    -If currently not StoppedState, stop
-    -If no internal QIODevice, create one.
-    -open audio input.
-    -If ok, NoError and IdleState, else OpenError and StoppedState
-    -emit stateChanged()
-    -return internal QIODevice
-    */
     return d->start(0);
 }
@@ -237,15 +262,12 @@
 
 /*!
-    Stops the audio input.
+    Stops the audio input, detaching from the system resource.
+
+    Sets error() to QAudio::NoError, state() to QAudio::StoppedState and
+    emit stateChanged() signal.
 */
 
 void QAudioInput::stop()
 {
-    /*
-    -If StoppedState, return
-    -set to StoppedState
-    -detach from audio device
-    -emit stateChanged()
-    */
     d->stop();
 }
@@ -257,8 +279,4 @@
 void QAudioInput::reset()
 {
-    /*
-    -drop all buffered audio, set buffers to zero.
-    -call stop()
-    */
     d->reset();
 }
@@ -266,14 +284,13 @@
 /*!
     Stops processing audio data, preserving buffered audio data.
+
+    Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and
+    emit stateChanged() signal.
+
+    Note: signal will always be emitted during execution of the resume() function.
 */
 
 void QAudioInput::suspend()
 {
-    /*
-    -If not ActiveState|IdleState, return
-    -stop processing audio, saving all buffered audio data
-    -set NoError and SuspendedState
-    -emit stateChanged()
-    */
     d->suspend();
 }
@@ -281,21 +298,18 @@
 /*!
     Resumes processing audio data after a suspend().
+
+    Sets error() to QAudio::NoError.
+    Sets state() to QAudio::ActiveState if you previously called start(QIODevice*).
+    Sets state() to QAudio::IdleState if you previously called start().
+    emits stateChanged() signal.
 */
 
 void QAudioInput::resume()
 {
-    /*
-    -If SuspendedState, return
-    -resume audio
-    -(PULL MODE): set ActiveState, NoError
-    -(PUSH MODE): set IdleState, NoError
-    -kick start audio if needed
-    -emit stateChanged()
-    */
      d->resume();
 }
 
 /*!
-    Sets the audio buffer size to \a value milliseconds.
+    Sets the audio buffer size to \a value bytes.
 
     Note: This function can be called anytime before start(), calls to this
@@ -312,5 +326,5 @@
 
 /*!
-    Returns the audio buffer size in milliseconds.
+    Returns the audio buffer size in bytes.
 
     If called before start(), returns platform default value.
@@ -328,4 +342,7 @@
 /*!
     Returns the amount of audio data available to read in bytes.
+
+    NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState
+    state, otherwise returns zero.
 */
 
@@ -353,5 +370,8 @@
     Sets the interval for notify() signal to be emitted.
     This is based on the \a ms of audio data processed
-    not on actual real-time. The resolution of the timer is platform specific.
+    not on actual real-time.
+    The minimum resolution of the timer is platform specific and values
+    should be checked with notifyInterval() to confirm actual value
+    being used.
 */
 
Index: trunk/src/multimedia/audio/qaudioinput_alsa_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_alsa_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudioinput_alsa_p.cpp	(revision 769)
@@ -59,6 +59,4 @@
 //#define DEBUG_AUDIO 1
 
-static const int minimumIntervalTime = 50;
-
 QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat):
     settings(audioFormat)
@@ -122,4 +120,9 @@
         if(err < 0)
             reset = true;
+        else {
+            bytesAvailable = bytesReady();
+            if (bytesAvailable <= 0)
+                reset = true;
+        }
 
     } else if((err == -ESTRPIPE)||(err == -EIO)) {
@@ -218,7 +221,9 @@
         pullMode = true;
         audioSource = device;
+        deviceState = QAudio::ActiveState;
     } else {
         //set to push mode
         pullMode = false;
+        deviceState = QAudio::IdleState;
         audioSource = new InputPrivate(this);
         audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
@@ -414,5 +419,4 @@
 
     errorState  = QAudio::NoError;
-    deviceState = QAudio::ActiveState;
 
     totalTimeValue = 0;
@@ -423,5 +427,4 @@
 void QAudioInputPrivate::close()
 {
-    deviceState = QAudio::StoppedState;
     timer->stop();
 
@@ -440,7 +443,8 @@
         return period_size;
 
-    if(deviceState != QAudio::ActiveState)
+    if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
         return 0;
     int frames = snd_pcm_avail_update(handle);
+    if (frames < 0) return frames;
     if((int)frames > (int)buffer_frames)
         frames = buffer_frames;
@@ -451,6 +455,6 @@
 qint64 QAudioInputPrivate::read(char* data, qint64 len)
 {
-    Q_UNUSED(data)
     Q_UNUSED(len)
+
     // Read in some audio data and write it to QIODevice, pull mode
     if ( !handle )
@@ -458,4 +462,18 @@
 
     bytesAvailable = bytesReady();
+
+    if (bytesAvailable < 0) {
+        // bytesAvailable as negative is error code, try to recover from it.
+        xrun_recovery(bytesAvailable);
+        bytesAvailable = bytesReady();
+        if (bytesAvailable < 0) {
+            // recovery failed must stop and set error.
+            close();
+            errorState = QAudio::IOError;
+            deviceState = QAudio::StoppedState;
+            emit stateChanged(deviceState);
+            return 0;
+        }
+    }
 
     int count=0, err = 0;
@@ -469,5 +487,5 @@
             err = snd_pcm_frames_to_bytes(handle, readFrames);
 #ifdef DEBUG_AUDIO
-            qDebug()<<QString::fromLatin1("PULL: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData();
+            qDebug()<<QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData();
 #endif
             break;
@@ -490,26 +508,44 @@
         // got some send it onward
 #ifdef DEBUG_AUDIO
-        qDebug()<<"PULL: frames to write to QIODevice = "<<
+        qDebug()<<"frames to write to QIODevice = "<<
             snd_pcm_bytes_to_frames( handle, (int)err )<<" ("<<err<<") bytes";
 #endif
-        if(deviceState != QAudio::ActiveState)
+        if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
             return 0;
-
-        qint64 l = audioSource->write(audioBuffer,err);
-        if(l < 0) {
-            close();
-            errorState = QAudio::IOError;
-            deviceState = QAudio::StoppedState;
-            emit stateChanged(deviceState);
-        } else if(l == 0) {
-            errorState = QAudio::NoError;
-            deviceState = QAudio::IdleState;
+        if (pullMode) {
+            qint64 l = audioSource->write(audioBuffer,err);
+            if(l < 0) {
+                close();
+                errorState = QAudio::IOError;
+                deviceState = QAudio::StoppedState;
+                emit stateChanged(deviceState);
+            } else if(l == 0) {
+                if (deviceState != QAudio::IdleState) {
+                    errorState = QAudio::NoError;
+                    deviceState = QAudio::IdleState;
+                    emit stateChanged(deviceState);
+                }
+            } else {
+                totalTimeValue += err;
+                resuming = false;
+                if (deviceState != QAudio::ActiveState) {
+                    errorState = QAudio::NoError;
+                    deviceState = QAudio::ActiveState;
+                    emit stateChanged(deviceState);
+                }
+            }
+            return l;
+
         } else {
-            totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.frequency();
+            memcpy(data,audioBuffer,err);
+            totalTimeValue += err;
             resuming = false;
-            errorState = QAudio::NoError;
-            deviceState = QAudio::ActiveState;
-        }
-        return l;
+            if (deviceState != QAudio::ActiveState) {
+                errorState = QAudio::NoError;
+                deviceState = QAudio::ActiveState;
+                emit stateChanged(deviceState);
+            }
+            return err;
+        }
     }
     return 0;
@@ -557,8 +593,5 @@
 void QAudioInputPrivate::setNotifyInterval(int ms)
 {
-    if(ms >= minimumIntervalTime)
-        intervalTime = ms;
-    else
-        intervalTime = minimumIntervalTime;
+    intervalTime = qMax(0, ms);
 }
 
@@ -570,5 +603,9 @@
 qint64 QAudioInputPrivate::processedUSecs() const
 {
-    return totalTimeValue;
+    qint64 result = qint64(1000000) * totalTimeValue /
+        (settings.channels()*(settings.sampleSize()/8)) /
+        settings.frequency();
+
+    return result;
 }
 
@@ -608,5 +645,5 @@
         return true;
 
-    if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+    if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
         emit notify();
         elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
@@ -618,32 +655,8 @@
 qint64 QAudioInputPrivate::elapsedUSecs() const
 {
-    if(!handle)
-        return 0;
-
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
-    snd_pcm_status_t* status;
-    snd_pcm_status_alloca(&status);
-
-    snd_timestamp_t t1,t2;
-    if( snd_pcm_status(handle, status) >= 0) {
-        snd_pcm_status_get_tstamp(status,&t1);
-        snd_pcm_status_get_trigger_tstamp(status,&t2);
-        t1.tv_sec-=t2.tv_sec;
-
-        signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec;
-        if(l < 0) {
-            t1.tv_sec--;
-            l = -l;
-            l %= 1000000;
-        }
-        return ((t1.tv_sec * 1000000)+l);
-    } else
-        return 0;
-#else
     return clockStamp.elapsed()*1000;
-#endif
 }
 
@@ -671,41 +684,5 @@
 qint64 InputPrivate::readData( char* data, qint64 len)
 {
-    // push mode, user read() called
-    if((audioDevice->state() != QAudio::ActiveState) && !audioDevice->resuming)
-        return 0;
-
-    int readFrames;
-    int count=0, err = 0;
-
-    while(count < 5) {
-        int frames = snd_pcm_bytes_to_frames(audioDevice->handle, len);
-        readFrames = snd_pcm_readi(audioDevice->handle, data, frames);
-        if (readFrames >= 0) {
-            err = snd_pcm_frames_to_bytes(audioDevice->handle, readFrames);
-#ifdef DEBUG_AUDIO
-            qDebug()<<QString::fromLatin1("PUSH: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData();
-#endif
-            break;
-        } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
-            audioDevice->errorState = QAudio::IOError;
-            err = 0;
-            break;
-        } else {
-            if(readFrames == -EPIPE) {
-                audioDevice->errorState = QAudio::UnderrunError;
-                err = snd_pcm_prepare(audioDevice->handle);
-            } else if(readFrames == -ESTRPIPE) {
-                err = snd_pcm_prepare(audioDevice->handle);
-            }
-            if(err != 0) break;
-        }
-        count++;
-    }
-    if(err > 0 && readFrames > 0) {
-        audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.frequency()*1000;
-        audioDevice->deviceState = QAudio::ActiveState;
-        return err;
-    }
-    return 0;
+    return audioDevice->read(data,len);
 }
 
Index: trunk/src/multimedia/audio/qaudioinput_mac_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_mac_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudioinput_mac_p.cpp	(revision 769)
@@ -55,15 +55,14 @@
 #include <QtCore/qdebug.h>
 
-#include <QtMultimedia/qaudiodeviceinfo.h>
 #include <QtMultimedia/qaudioinput.h>
 
 #include "qaudio_mac_p.h"
 #include "qaudioinput_mac_p.h"
-
+#include "qaudiodeviceinfo_mac_p.h"
 
 QT_BEGIN_NAMESPACE
 
 
-namespace
+namespace QtMultimediaInternal
 {
 
@@ -170,6 +169,8 @@
     void reset()
     {
-        for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i)
+        for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i) {
             bfs->mBuffers[i].mDataByteSize = dataSize;
+            bfs->mBuffers[i].mData = 0;
+        }
     }
 
@@ -228,4 +229,5 @@
         QObject(parent),
         m_deviceError(false),
+        m_audioConverter(0),
         m_inputFormat(inputFormat),
         m_outputFormat(outputFormat)
@@ -239,5 +241,5 @@
         connect(m_flushTimer, SIGNAL(timeout()), SLOT(flushBuffer()));
 
-        if (inputFormat.mSampleRate != outputFormat.mSampleRate) {
+        if (toQAudioFormat(inputFormat) != toQAudioFormat(outputFormat)) {
             if (AudioConverterNew(&m_inputFormat, &m_outputFormat, &m_audioConverter) != noErr) {
                 qWarning() << "QAudioInput: Unable to create an Audio Converter";
@@ -518,4 +520,5 @@
         errorCode = QAudio::OpenError;
     else {
+        audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioInput);
         isOpen = false;
         audioDeviceId = AudioDeviceID(did);
@@ -524,5 +527,5 @@
         totalFrames = 0;
         audioBuffer = 0;
-        internalBufferSize = default_buffer_size;
+        internalBufferSize = QtMultimediaInternal::default_buffer_size;
         clockFrequency = AudioGetHostClockFrequency() / 1000;
         errorCode = QAudio::NoError;
@@ -538,4 +541,5 @@
 {
     close();
+    delete audioDeviceInfo;
 }
 
@@ -575,5 +579,5 @@
                                &enable,
                                sizeof(enable)) != noErr) {
-        qWarning() << "QAudioInput: Unabled to switch to input mode (Enable Input)";
+        qWarning() << "QAudioInput: Unable to switch to input mode (Enable Input)";
         return false;
     }
@@ -586,5 +590,5 @@
                             &enable,
                             sizeof(enable)) != noErr) {
-        qWarning() << "QAudioInput: Unabled to switch to input mode (Disable output)";
+        qWarning() << "QAudioInput: Unable to switch to input mode (Disable output)";
         return false;
     }
@@ -617,33 +621,38 @@
 
     // Set format
+    // Wanted
     streamFormat = toAudioStreamBasicDescription(audioFormat);
 
-    size = sizeof(deviceFormat);
-    if (AudioUnitGetProperty(audioUnit,
-                                kAudioUnitProperty_StreamFormat,
-                                kAudioUnitScope_Input,
-                                1,
-                                &deviceFormat,
-                                &size) != noErr) {
-        qWarning() << "QAudioInput: Unable to retrieve device format";
-        return false;
-    }
-
-    // If the device frequency is different to the requested use a converter
-    if (deviceFormat.mSampleRate != streamFormat.mSampleRate) {
-         AudioUnitSetProperty(audioUnit,
+    // Required on unit
+    if (audioFormat == audioDeviceInfo->preferredFormat()) {
+        deviceFormat = streamFormat;
+        AudioUnitSetProperty(audioUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Output,
                                1,
                                &deviceFormat,
-                               sizeof(streamFormat));
+                               sizeof(deviceFormat));
     }
     else {
-        AudioUnitSetProperty(audioUnit,
-                               kAudioUnitProperty_StreamFormat,
-                               kAudioUnitScope_Output,
-                               1,
-                               &streamFormat,
-                               sizeof(streamFormat));
+        size = sizeof(deviceFormat);
+        if (AudioUnitGetProperty(audioUnit,
+                                    kAudioUnitProperty_StreamFormat,
+                                    kAudioUnitScope_Input,
+                                    1,
+                                    &deviceFormat,
+                                    &size) != noErr) {
+            qWarning() << "QAudioInput: Unable to retrieve device format";
+            return false;
+        }
+
+        if (AudioUnitSetProperty(audioUnit,
+                                   kAudioUnitProperty_StreamFormat,
+                                   kAudioUnitScope_Output,
+                                   1,
+                                   &deviceFormat,
+                                   sizeof(deviceFormat)) != noErr) {
+            qWarning() << "QAudioInput: Unable to set device format";
+            return false;
+        }
     }
 
@@ -662,6 +671,6 @@
 
     // Allocate buffer
-    periodSizeBytes = (numberOfFrames * streamFormat.mSampleRate / deviceFormat.mSampleRate) *
-                        streamFormat.mBytesPerFrame;
+    periodSizeBytes = numberOfFrames * streamFormat.mBytesPerFrame;
+
     if (internalBufferSize < periodSizeBytes * 2)
         internalBufferSize = periodSizeBytes * 2;
@@ -669,5 +678,5 @@
         internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame;
 
-    audioBuffer = new QAudioInputBuffer(internalBufferSize,
+    audioBuffer = new QtMultimediaInternal::QAudioInputBuffer(internalBufferSize,
                                         periodSizeBytes,
                                         deviceFormat,
@@ -675,5 +684,5 @@
                                         this);
 
-    audioIO = new MacInputDevice(audioBuffer, this);
+    audioIO = new QtMultimediaInternal::MacInputDevice(audioBuffer, this);
 
     // Init
@@ -708,5 +717,5 @@
     QIODevice*  op = device;
 
-    if (!open()) {
+    if (!audioFormat.isValid() || !open()) {
         stateCode = QAudio::StoppedState;
         errorCode = QAudio::OpenError;
@@ -805,4 +814,10 @@
 void QAudioInputPrivate::setNotifyInterval(int milliSeconds)
 {
+    if (intervalTimer->interval() == milliSeconds)
+        return;
+
+    if (milliSeconds <= 0)
+        milliSeconds = 0;
+
     intervalTimer->setInterval(milliSeconds);
 }
@@ -884,5 +899,6 @@
 {
     audioBuffer->startFlushTimer();
-    intervalTimer->start();
+    if (intervalTimer->interval() > 0)
+        intervalTimer->start();
 }
 
Index: trunk/src/multimedia/audio/qaudioinput_mac_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_mac_p.h	(revision 766)
+++ trunk/src/multimedia/audio/qaudioinput_mac_p.h	(revision 769)
@@ -75,6 +75,7 @@
 class QTimer;
 class QIODevice;
+class QAbstractAudioDeviceInfo;
 
-namespace
+namespace QtMultimediaInternal
 {
 class QAudioInputBuffer;
@@ -98,5 +99,5 @@
     QAudio::Error   errorCode;
     QAudio::State   stateCode;
-    QAudioInputBuffer*   audioBuffer;
+    QtMultimediaInternal::QAudioInputBuffer*   audioBuffer;
     QMutex          mutex;
     QWaitCondition  threadFinished;
@@ -105,4 +106,5 @@
     AudioStreamBasicDescription streamFormat;
     AudioStreamBasicDescription deviceFormat;
+    QAbstractAudioDeviceInfo *audioDeviceInfo;
 
     QAudioInputPrivate(const QByteArray& device, QAudioFormat const& format);
Index: trunk/src/multimedia/audio/qaudioinput_symbian_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_symbian_p.cpp	(revision 769)
+++ trunk/src/multimedia/audio/qaudioinput_symbian_p.cpp	(revision 769)
@@ -0,0 +1,551 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudioinput_symbian_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const int PushInterval = 50; // ms
+
+
+//-----------------------------------------------------------------------------
+// Private class
+//-----------------------------------------------------------------------------
+
+SymbianAudioInputPrivate::SymbianAudioInputPrivate(
+                              QAudioInputPrivate *audioDevice)
+    :   m_audioDevice(audioDevice)
+{
+
+}
+
+SymbianAudioInputPrivate::~SymbianAudioInputPrivate()
+{
+
+}
+
+qint64 SymbianAudioInputPrivate::readData(char *data, qint64 len)
+{
+    qint64 totalRead = 0;
+
+    if (m_audioDevice->state() == QAudio::ActiveState ||
+        m_audioDevice->state() == QAudio::IdleState) {
+
+        while (totalRead < len) {
+            const qint64 read = m_audioDevice->read(data + totalRead,
+                                                    len - totalRead);
+            if (read > 0)
+                totalRead += read;
+            else
+                break;
+        }
+    }
+
+    return totalRead;
+}
+
+qint64 SymbianAudioInputPrivate::writeData(const char *data, qint64 len)
+{
+    Q_UNUSED(data)
+    Q_UNUSED(len)
+    return 0;
+}
+
+void SymbianAudioInputPrivate::dataReady()
+{
+    emit readyRead();
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device,
+                                     const QAudioFormat &format)
+    :   m_device(device)
+    ,   m_format(format)
+    ,   m_clientBufferSize(SymbianAudio::DefaultBufferSize)
+    ,   m_notifyInterval(SymbianAudio::DefaultNotifyInterval)
+    ,   m_notifyTimer(new QTimer(this))
+    ,   m_error(QAudio::NoError)
+    ,   m_internalState(SymbianAudio::ClosedState)
+    ,   m_externalState(QAudio::StoppedState)
+    ,   m_pullMode(false)
+    ,   m_sink(0)
+    ,   m_pullTimer(new QTimer(this))
+    ,   m_devSound(0)
+    ,   m_devSoundBuffer(0)
+    ,   m_devSoundBufferSize(0)
+    ,   m_totalBytesReady(0)
+    ,   m_devSoundBufferPos(0)
+    ,   m_totalSamplesRecorded(0)
+{
+    qRegisterMetaType<CMMFBuffer *>("CMMFBuffer *");
+
+    connect(m_notifyTimer.data(), SIGNAL(timeout()), this, SIGNAL(notify()));
+
+    m_pullTimer->setInterval(PushInterval);
+    connect(m_pullTimer.data(), SIGNAL(timeout()), this, SLOT(pullData()));
+}
+
+QAudioInputPrivate::~QAudioInputPrivate()
+{
+    close();
+}
+
+QIODevice* QAudioInputPrivate::start(QIODevice *device)
+{
+    stop();
+
+    open();
+    if (SymbianAudio::ClosedState != m_internalState) {
+        if (device) {
+            m_pullMode = true;
+            m_sink = device;
+        } else {
+            m_sink = new SymbianAudioInputPrivate(this);
+            m_sink->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+        }
+
+        m_elapsed.restart();
+    }
+
+    return m_sink;
+}
+
+void QAudioInputPrivate::stop()
+{
+    close();
+}
+
+void QAudioInputPrivate::reset()
+{
+    m_totalSamplesRecorded += getSamplesRecorded();
+    m_devSound->stop();
+    startRecording();
+}
+
+void QAudioInputPrivate::suspend()
+{
+    if (SymbianAudio::ActiveState == m_internalState
+        || SymbianAudio::IdleState == m_internalState) {
+        m_notifyTimer->stop();
+        m_pullTimer->stop();
+        m_devSound->pause();
+        const qint64 samplesRecorded = getSamplesRecorded();
+        m_totalSamplesRecorded += samplesRecorded;
+
+        if (m_devSoundBuffer) {
+            m_devSoundBufferQ.append(m_devSoundBuffer);
+            m_devSoundBuffer = 0;
+        }
+
+        setState(SymbianAudio::SuspendedState);
+    }
+}
+
+void QAudioInputPrivate::resume()
+{
+    if (SymbianAudio::SuspendedState == m_internalState) {
+        if (!m_pullMode && !bytesReady())
+            m_devSound->start();
+        startDataTransfer();
+    }
+}
+
+int QAudioInputPrivate::bytesReady() const
+{
+    Q_ASSERT(m_devSoundBufferPos <= m_totalBytesReady);
+    return m_totalBytesReady - m_devSoundBufferPos;
+}
+
+int QAudioInputPrivate::periodSize() const
+{
+    return bufferSize();
+}
+
+void QAudioInputPrivate::setBufferSize(int value)
+{
+    // Note that DevSound does not allow its client to specify the buffer size.
+    // This functionality is available via custom interfaces, but since these
+    // cannot be guaranteed to work across all DevSound implementations, we
+    // do not use them here.
+    // In order to comply with the expected bevahiour of QAudioInput, we store
+    // the value and return it from bufferSize(), but the underlying DevSound
+    // buffer size remains unchanged.
+    if (value > 0)
+        m_clientBufferSize = value;
+}
+
+int QAudioInputPrivate::bufferSize() const
+{
+    return m_devSoundBufferSize ? m_devSoundBufferSize : m_clientBufferSize;
+}
+
+void QAudioInputPrivate::setNotifyInterval(int ms)
+{
+    if (ms >= 0) {
+        const int oldNotifyInterval = m_notifyInterval;
+        m_notifyInterval = ms;
+        if (m_notifyInterval && (SymbianAudio::ActiveState == m_internalState ||
+                                 SymbianAudio::IdleState == m_internalState))
+            m_notifyTimer->start(m_notifyInterval);
+        else
+            m_notifyTimer->stop();
+    }
+}
+
+int QAudioInputPrivate::notifyInterval() const
+{
+    return m_notifyInterval;
+}
+
+qint64 QAudioInputPrivate::processedUSecs() const
+{
+    int samplesPlayed = 0;
+    if (m_devSound && SymbianAudio::SuspendedState != m_internalState)
+        samplesPlayed = getSamplesRecorded();
+
+    // Protect against division by zero
+    Q_ASSERT_X(m_format.frequency() > 0, Q_FUNC_INFO, "Invalid frequency");
+
+    const qint64 result = qint64(1000000) *
+                          (samplesPlayed + m_totalSamplesRecorded)
+                        / m_format.frequency();
+
+    return result;
+}
+
+qint64 QAudioInputPrivate::elapsedUSecs() const
+{
+    const qint64 result = (QAudio::StoppedState == state()) ?
+                              0 : m_elapsed.elapsed() * 1000;
+    return result;
+}
+
+QAudio::Error QAudioInputPrivate::error() const
+{
+    return m_error;
+}
+
+QAudio::State QAudioInputPrivate::state() const
+{
+    return m_externalState;
+}
+
+QAudioFormat QAudioInputPrivate::format() const
+{
+    return m_format;
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void QAudioInputPrivate::open()
+{
+    Q_ASSERT_X(SymbianAudio::ClosedState == m_internalState,
+        Q_FUNC_INFO, "DevSound already opened");
+
+    Q_ASSERT(!m_devSound);
+    m_devSound = new SymbianAudio::DevSoundWrapper(QAudio::AudioInput, this);
+
+    connect(m_devSound, SIGNAL(initializeComplete(int)),
+            this, SLOT(devsoundInitializeComplete(int)));
+    connect(m_devSound, SIGNAL(bufferToBeProcessed(CMMFBuffer *)),
+            this, SLOT(devsoundBufferToBeEmptied(CMMFBuffer *)));
+    connect(m_devSound, SIGNAL(processingError(int)),
+            this, SLOT(devsoundRecordError(int)));
+
+    setState(SymbianAudio::InitializingState);
+    m_devSound->initialize(m_format.codec());
+}
+
+void QAudioInputPrivate::startRecording()
+{
+    const int samplesRecorded = m_devSound->samplesProcessed();
+    Q_ASSERT(samplesRecorded == 0);
+
+    bool ok = m_devSound->setFormat(m_format);
+    if (ok)
+        ok = m_devSound->start();
+
+    if (ok) {
+        startDataTransfer();
+    } else {
+        setError(QAudio::OpenError);
+        close();
+    }
+}
+
+void QAudioInputPrivate::startDataTransfer()
+{
+    if (m_notifyInterval)
+        m_notifyTimer->start(m_notifyInterval);
+
+    if (m_pullMode)
+        m_pullTimer->start();
+
+    if (bytesReady()) {
+        setState(SymbianAudio::ActiveState);
+        if (!m_pullMode)
+            pushData();
+    } else {
+        if (SymbianAudio::SuspendedState == m_internalState)
+            setState(SymbianAudio::ActiveState);
+        else
+            setState(SymbianAudio::IdleState);
+    }
+}
+
+CMMFDataBuffer* QAudioInputPrivate::currentBuffer() const
+{
+    CMMFDataBuffer *result = m_devSoundBuffer;
+    if (!result && !m_devSoundBufferQ.empty())
+        result = m_devSoundBufferQ.front();
+    return result;
+}
+
+void QAudioInputPrivate::pushData()
+{
+    Q_ASSERT_X(bytesReady(), Q_FUNC_INFO, "No data available");
+    Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO, "pushData called when in pull mode");
+    qobject_cast<SymbianAudioInputPrivate *>(m_sink)->dataReady();
+}
+
+qint64 QAudioInputPrivate::read(char *data, qint64 len)
+{
+    // SymbianAudioInputPrivate is ready to read data
+
+    Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO,
+        "read called when in pull mode");
+
+    qint64 bytesRead = 0;
+
+    CMMFDataBuffer *buffer = 0;
+    while ((buffer = currentBuffer()) && (bytesRead < len)) {
+        if (SymbianAudio::IdleState == m_internalState)
+            setState(SymbianAudio::ActiveState);
+
+        TDesC8 &inputBuffer = buffer->Data();
+
+        const qint64 inputBytes = bytesReady();
+        const qint64 outputBytes = len - bytesRead;
+        const qint64 copyBytes = outputBytes < inputBytes ?
+                                     outputBytes : inputBytes;
+
+        memcpy(data, inputBuffer.Ptr() + m_devSoundBufferPos, copyBytes);
+
+        m_devSoundBufferPos += copyBytes;
+        data += copyBytes;
+        bytesRead += copyBytes;
+
+        if (!bytesReady())
+            bufferEmptied();
+    }
+
+    return bytesRead;
+}
+
+void QAudioInputPrivate::pullData()
+{
+    Q_ASSERT_X(m_pullMode, Q_FUNC_INFO,
+        "pullData called when in push mode");
+
+    CMMFDataBuffer *buffer = 0;
+    while (buffer = currentBuffer()) {
+        if (SymbianAudio::IdleState == m_internalState)
+            setState(SymbianAudio::ActiveState);
+
+        TDesC8 &inputBuffer = buffer->Data();
+
+        const qint64 inputBytes = bytesReady();
+        const qint64 bytesPushed = m_sink->write(
+            (char*)inputBuffer.Ptr() + m_devSoundBufferPos, inputBytes);
+
+        m_devSoundBufferPos += bytesPushed;
+
+        if (!bytesReady())
+            bufferEmptied();
+
+        if (!bytesPushed)
+            break;
+    }
+}
+
+void QAudioInputPrivate::devsoundInitializeComplete(int err)
+{
+    Q_ASSERT_X(SymbianAudio::InitializingState == m_internalState,
+        Q_FUNC_INFO, "Invalid state");
+
+    if (!err && m_devSound->isFormatSupported(m_format))
+        startRecording();
+    else
+        setError(QAudio::OpenError);
+}
+
+void QAudioInputPrivate::devsoundBufferToBeEmptied(CMMFBuffer *baseBuffer)
+{
+    // Following receipt of this signal, DevSound should not provide another
+    // buffer until we have returned the current one.
+    Q_ASSERT_X(!m_devSoundBuffer, Q_FUNC_INFO, "Buffer already held");
+
+    CMMFDataBuffer *const buffer = static_cast<CMMFDataBuffer*>(baseBuffer);
+
+    if (!m_devSoundBufferSize)
+        m_devSoundBufferSize = buffer->Data().MaxLength();
+
+    m_totalBytesReady += buffer->Data().Length();
+
+    if (SymbianAudio::SuspendedState == m_internalState) {
+        m_devSoundBufferQ.append(buffer);
+    } else {
+        // Will be returned to DevSoundWrapper by bufferProcessed().
+        m_devSoundBuffer = buffer;
+        m_devSoundBufferPos = 0;
+
+        if (bytesReady() && !m_pullMode)
+            pushData();
+    }
+}
+
+void QAudioInputPrivate::devsoundRecordError(int err)
+{
+    Q_UNUSED(err)
+    setError(QAudio::IOError);
+}
+
+void QAudioInputPrivate::bufferEmptied()
+{
+    m_devSoundBufferPos = 0;
+
+    if (m_devSoundBuffer) {
+        m_totalBytesReady -= m_devSoundBuffer->Data().Length();
+        m_devSoundBuffer = 0;
+        m_devSound->bufferProcessed();
+    } else {
+        Q_ASSERT(!m_devSoundBufferQ.empty());
+        m_totalBytesReady -= m_devSoundBufferQ.front()->Data().Length();
+        m_devSoundBufferQ.erase(m_devSoundBufferQ.begin());
+
+        // If the queue has been emptied, resume transfer from the hardware
+        if (m_devSoundBufferQ.empty())
+            if (!m_devSound->start())
+                setError(QAudio::IOError);
+    }
+
+    Q_ASSERT(m_totalBytesReady >= 0);
+}
+
+void QAudioInputPrivate::close()
+{
+    m_notifyTimer->stop();
+    m_pullTimer->stop();
+
+    m_error = QAudio::NoError;
+
+    if (m_devSound)
+        m_devSound->stop();
+    delete m_devSound;
+    m_devSound = 0;
+
+    m_devSoundBuffer = 0;
+    m_devSoundBufferSize = 0;
+    m_totalBytesReady = 0;
+
+    if (!m_pullMode) // m_sink is owned
+        delete m_sink;
+    m_pullMode = false;
+    m_sink = 0;
+
+    m_devSoundBufferQ.clear();
+    m_devSoundBufferPos = 0;
+    m_totalSamplesRecorded = 0;
+
+    setState(SymbianAudio::ClosedState);
+}
+
+qint64 QAudioInputPrivate::getSamplesRecorded() const
+{
+    qint64 result = 0;
+    if (m_devSound)
+        result = qint64(m_devSound->samplesProcessed());
+    return result;
+}
+
+void QAudioInputPrivate::setError(QAudio::Error error)
+{
+    m_error = error;
+
+    // Although no state transition actually occurs here, a stateChanged event
+    // must be emitted to inform the client that the call to start() was
+    // unsuccessful.
+    if (QAudio::OpenError == error) {
+        emit stateChanged(QAudio::StoppedState);
+    } else {
+        if (QAudio::UnderrunError == error)
+            setState(SymbianAudio::IdleState);
+        else
+            // Close the DevSound instance.  This causes a transition to
+            // StoppedState.  This must be done asynchronously in case the
+            // current function was called from a DevSound event handler, in which
+            // case deleting the DevSound instance may cause an exception.
+            QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
+    }
+}
+
+void QAudioInputPrivate::setState(SymbianAudio::State newInternalState)
+{
+    const QAudio::State oldExternalState = m_externalState;
+    m_internalState = newInternalState;
+    m_externalState = SymbianAudio::Utils::stateNativeToQt(m_internalState);
+
+    if (m_externalState != oldExternalState)
+        emit stateChanged(m_externalState);
+}
+
+QT_END_NAMESPACE
Index: trunk/src/multimedia/audio/qaudioinput_symbian_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_symbian_p.h	(revision 769)
+++ trunk/src/multimedia/audio/qaudioinput_symbian_p.h	(revision 769)
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists for the convenience
+// of other Qt classes.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIOINPUT_SYMBIAN_P_H
+#define QAUDIOINPUT_SYMBIAN_P_H
+
+#include <QtMultimedia/qaudioengine.h>
+#include <QTime>
+#include <QTimer>
+#include "qaudio_symbian_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAudioInputPrivate;
+
+class SymbianAudioInputPrivate : public QIODevice
+{
+    friend class QAudioInputPrivate;
+    Q_OBJECT
+public:
+    SymbianAudioInputPrivate(QAudioInputPrivate *audio);
+    ~SymbianAudioInputPrivate();
+
+    qint64 readData(char *data, qint64 len);
+    qint64 writeData(const char *data, qint64 len);
+
+    void dataReady();
+
+private:
+    QAudioInputPrivate *const m_audioDevice;
+};
+
+class QAudioInputPrivate
+    :   public QAbstractAudioInput
+{
+    friend class SymbianAudioInputPrivate;
+    Q_OBJECT
+public:
+    QAudioInputPrivate(const QByteArray &device,
+                      const QAudioFormat &audioFormat);
+    ~QAudioInputPrivate();
+
+    // QAbstractAudioInput
+    QIODevice* start(QIODevice *device = 0);
+    void stop();
+    void reset();
+    void suspend();
+    void resume();
+    int bytesReady() const;
+    int periodSize() const;
+    void setBufferSize(int value);
+    int bufferSize() const;
+    void setNotifyInterval(int milliSeconds);
+    int notifyInterval() const;
+    qint64 processedUSecs() const;
+    qint64 elapsedUSecs() const;
+    QAudio::Error error() const;
+    QAudio::State state() const;
+    QAudioFormat format() const;
+
+private slots:
+    void pullData();
+    void devsoundInitializeComplete(int err);
+    void devsoundBufferToBeEmptied(CMMFBuffer *);
+    void devsoundRecordError(int err);
+
+private:
+   void open();
+   void startRecording();
+   void startDataTransfer();
+   CMMFDataBuffer* currentBuffer() const;
+   void pushData();
+   qint64 read(char *data, qint64 len);
+   void bufferEmptied();
+   Q_INVOKABLE void close();
+
+   qint64 getSamplesRecorded() const;
+
+   void setError(QAudio::Error error);
+   void setState(SymbianAudio::State state);
+
+private:
+    const QByteArray m_device;
+    const QAudioFormat m_format;
+
+    int m_clientBufferSize;
+    int m_notifyInterval;
+    QScopedPointer<QTimer> m_notifyTimer;
+    QTime m_elapsed;
+    QAudio::Error m_error;
+
+    SymbianAudio::State m_internalState;
+    QAudio::State m_externalState;
+
+    bool m_pullMode;
+    QIODevice *m_sink;
+
+    QScopedPointer<QTimer> m_pullTimer;
+
+    SymbianAudio::DevSoundWrapper* m_devSound;
+
+    // Latest buffer provided by DevSound, to be empied of data.
+    CMMFDataBuffer *m_devSoundBuffer;
+
+    int m_devSoundBufferSize;
+
+    // Total amount of data in buffers provided by DevSound
+    int m_totalBytesReady;
+
+    // Queue of buffers returned after call to CMMFDevSound::Pause().
+    QList<CMMFDataBuffer *> m_devSoundBufferQ;
+
+    // Current read position within m_devSoundBuffer
+    qint64 m_devSoundBufferPos;
+
+    // Samples recorded up to the last call to suspend().  It is necessary
+    // to cache this because suspend() is implemented using
+    // CMMFDevSound::Stop(), which resets DevSound's SamplesRecorded() counter.
+    quint32 m_totalSamplesRecorded;
+
+};
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/multimedia/audio/qaudioinput_win32_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_win32_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudioinput_win32_p.cpp	(revision 769)
@@ -57,8 +57,4 @@
 
 //#define DEBUG_AUDIO 1
-
-static CRITICAL_SECTION waveInCriticalSection;
-
-static const int minimumIntervalTime = 50;
 
 QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat):
@@ -77,8 +73,4 @@
     resuming = false;
     finished = false;
-
-    connect(this,SIGNAL(processMore()),SLOT(deviceReady()));
-
-    InitializeCriticalSection(&waveInCriticalSection);
 }
 
@@ -86,5 +78,4 @@
 {
     stop();
-    DeleteCriticalSection(&waveInCriticalSection);
 }
 
@@ -101,18 +92,16 @@
         return;
 
+    QMutexLocker(&qAudio->mutex);
+
     switch(uMsg) {
         case WIM_OPEN:
             break;
         case WIM_DATA:
-            EnterCriticalSection(&waveInCriticalSection);
             if(qAudio->waveFreeBlockCount > 0)
                 qAudio->waveFreeBlockCount--;
             qAudio->feedback();
-            LeaveCriticalSection(&waveInCriticalSection);
             break;
         case WIM_CLOSE:
-            EnterCriticalSection(&waveInCriticalSection);
             qAudio->finished = true;
-            LeaveCriticalSection(&waveInCriticalSection);
             break;
         default:
@@ -159,5 +148,5 @@
 
     for(int i = 0; i < count; i++) {
-        waveInUnprepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR));
+        waveInUnprepareHeader(hWaveIn,blocks, sizeof(WAVEHDR));
         blocks+=sizeof(WAVEHDR);
     }
@@ -193,7 +182,9 @@
         pullMode = true;
         audioSource = device;
+        deviceState = QAudio::ActiveState;
     } else {
         //set to push mode
         pullMode = false;
+        deviceState = QAudio::IdleState;
         audioSource = new InputPrivate(this);
         audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
@@ -225,6 +216,6 @@
     header = 0;
     if(buffer_size == 0) {
-        // Default buffer size, 100ms, default period size is 20ms
-        buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.1;
+        // Default buffer size, 200ms, default period size is 40ms
+        buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2;
 	period_size = buffer_size/5;
     } else {
@@ -279,7 +270,7 @@
     }
 
-    EnterCriticalSection(&waveInCriticalSection);
+    mutex.lock();
     waveFreeBlockCount = buffer_size/period_size;
-    LeaveCriticalSection(&waveInCriticalSection);
+    mutex.unlock();
 
     waveCurrentBlock = 0;
@@ -307,5 +298,4 @@
     totalTimeValue = 0;
     errorState  = QAudio::NoError;
-    deviceState = QAudio::ActiveState;
     return true;
 }
@@ -316,7 +306,7 @@
         return;
 
+    deviceState = QAudio::StoppedState;
     waveInReset(hWaveIn);
     waveInClose(hWaveIn);
-    deviceState = QAudio::StoppedState;
 
     int count = 0;
@@ -326,11 +316,9 @@
     }
 
-    EnterCriticalSection(&waveInCriticalSection);
-    for(int i=0; i<waveFreeBlockCount; i++) {
-        if(waveBlocks[i].dwFlags & WHDR_PREPARED)
-            waveInUnprepareHeader(hWaveIn,&waveBlocks[i],sizeof(WAVEHDR));
-    }
-    LeaveCriticalSection(&waveInCriticalSection);
+    mutex.lock();
+    for(int i=0; i<waveFreeBlockCount; i++)
+        waveInUnprepareHeader(hWaveIn,&waveBlocks[i],sizeof(WAVEHDR));
     freeBlocks(waveBlocks);
+    mutex.unlock();
 }
 
@@ -353,5 +341,4 @@
     qint64 l = 0;
     qint64 written = 0;
-
     while(!done) {
         // Read in some audio data
@@ -374,9 +361,10 @@
 
                 } else {
-                    totalTimeValue += waveBlocks[header].dwBytesRecorded
-                        /((settings.channels()*settings.sampleSize()/8))
-                        *10000/settings.frequency()*100;
+                    totalTimeValue += waveBlocks[header].dwBytesRecorded;
                     errorState = QAudio::NoError;
-                    deviceState = QAudio::ActiveState;
+                    if (deviceState != QAudio::ActiveState) {
+                        deviceState = QAudio::ActiveState;
+                        emit stateChanged(deviceState);
+                    }
 		    resuming = false;
                 }
@@ -388,21 +376,23 @@
                 qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
 #endif
-                totalTimeValue += waveBlocks[header].dwBytesRecorded
-                    /((settings.channels()*settings.sampleSize()/8))
-                    *10000/settings.frequency()*100;
+                totalTimeValue += waveBlocks[header].dwBytesRecorded;
                 errorState = QAudio::NoError;
-                deviceState = QAudio::ActiveState;
+                if (deviceState != QAudio::ActiveState) {
+                    deviceState = QAudio::ActiveState;
+                    emit stateChanged(deviceState);
+                }
 		resuming = false;
             }
         } else {
             //no data, not ready yet, next time
-            return 0;
+            break;
         }
 
         waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
 
-        EnterCriticalSection(&waveInCriticalSection);
+        mutex.lock();
         waveFreeBlockCount++;
-        LeaveCriticalSection(&waveInCriticalSection);
+        mutex.unlock();
+
         waveBlocks[header].dwBytesRecorded=0;
         waveBlocks[header].dwFlags = 0L;
@@ -412,7 +402,9 @@
             qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result);
             errorState = QAudio::IOError;
-            EnterCriticalSection(&waveInCriticalSection);
+
+            mutex.lock();
             waveFreeBlockCount--;
-            LeaveCriticalSection(&waveInCriticalSection);
+            mutex.unlock();
+
             return 0;
         }
@@ -421,7 +413,9 @@
             qWarning("QAudioInput: failed to setup block %d,err=%d",header,result);
             errorState = QAudio::IOError;
-            EnterCriticalSection(&waveInCriticalSection);
+
+            mutex.lock();
             waveFreeBlockCount--;
-            LeaveCriticalSection(&waveInCriticalSection);
+            mutex.unlock();
+
             return 0;
         }
@@ -431,5 +425,5 @@
         p+=l;
 
-        EnterCriticalSection(&waveInCriticalSection);
+        mutex.lock();
         if(!pullMode) {
 	    if(l+period_size > len && waveFreeBlockCount == buffer_size/period_size)
@@ -439,5 +433,5 @@
 	        done = true;
 	}
-        LeaveCriticalSection(&waveInCriticalSection);
+        mutex.unlock();
 
 	written+=l;
@@ -463,7 +457,8 @@
             }
         }
-        EnterCriticalSection(&waveInCriticalSection);
+
+        mutex.lock();
         waveFreeBlockCount = buffer_size/period_size;
-        LeaveCriticalSection(&waveInCriticalSection);
+        mutex.unlock();
 
         waveCurrentBlock = 0;
@@ -493,8 +488,5 @@
 void QAudioInputPrivate::setNotifyInterval(int ms)
 {
-    if(ms >= minimumIntervalTime)
-        intervalTime = ms;
-    else
-        intervalTime = minimumIntervalTime;
+    intervalTime = qMax(0, ms);
 }
 
@@ -506,5 +498,11 @@
 qint64 QAudioInputPrivate::processedUSecs() const
 {
-    return totalTimeValue;
+    if (deviceState == QAudio::StoppedState)
+        return 0;
+    qint64 result = qint64(1000000) * totalTimeValue /
+        (settings.channels()*(settings.sampleSize()/8)) /
+        settings.frequency();
+
+    return result;
 }
 
@@ -524,16 +522,18 @@
     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this;
 #endif
+    if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState))
+        QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection);
+}
+
+bool QAudioInputPrivate::deviceReady()
+{
     bytesAvailable = bytesReady();
-
-    if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState))
-        emit processMore();
-}
-
-bool QAudioInputPrivate::deviceReady()
-{
 #ifdef DEBUG_AUDIO
     QTime now(QTime::currentTime());
     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :deviceReady() INPUT";
 #endif
+    if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+        return true;
+
     if(pullMode) {
         // reads some audio data and writes it to QIODevice
@@ -544,8 +544,6 @@
 	a->trigger();
     }
-    if(deviceState != QAudio::ActiveState)
-        return true;
-
-    if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+
+    if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
         emit notify();
         elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
@@ -578,5 +576,6 @@
 {
     // push mode, user read() called
-    if(audioDevice->deviceState != QAudio::ActiveState)
+    if(audioDevice->deviceState != QAudio::ActiveState &&
+            audioDevice->deviceState != QAudio::IdleState)
         return 0;
     // Read in some audio data
Index: trunk/src/multimedia/audio/qaudioinput_win32_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudioinput_win32_p.h	(revision 766)
+++ trunk/src/multimedia/audio/qaudioinput_win32_p.h	(revision 769)
@@ -63,4 +63,5 @@
 #include <QtCore/qstringlist.h>
 #include <QtCore/qdatetime.h>
+#include <QtCore/qmutex.h>
 
 #include <QtMultimedia/qaudio.h>
@@ -123,4 +124,6 @@
     int waveCurrentBlock;
 
+    QMutex mutex;
+
     static void CALLBACK waveInProc( HWAVEIN hWaveIn, UINT uMsg,
             DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
Index: trunk/src/multimedia/audio/qaudiooutput.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiooutput.cpp	(revision 769)
@@ -203,4 +203,15 @@
     All that is required is to open the QIODevice.
 
+    If able to successfully output audio data to the systems audio device the
+    state() is set to QAudio::ActiveState, error() is set to QAudio::NoError
+    and the stateChanged() signal is emitted.
+
+    If a problem occurs during this process the error() is set to QAudio::OpenError,
+    state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+    In either case, the stateChanged() signal may be emitted either synchronously
+    during execution of the start() function or asynchronously after start() has
+    returned to the caller.
+
     \sa QIODevice
 */
@@ -208,11 +219,4 @@
 void QAudioOutput::start(QIODevice* device)
 {
-    /*
-    -If currently not StoppedState, stop.
-    -If previous start was push mode, delete internal QIODevice.
-    -open audio output.
-    -If ok, NoError and ActiveState, else OpenError and StoppedState
-    -emit stateChanged()
-    */
     d->start(device);
 }
@@ -222,4 +226,15 @@
     transfer. This QIODevice can be used to write() audio data directly.
 
+    If able to access the systems audio device the state() is set to
+    QAudio::IdleState, error() is set to QAudio::NoError
+    and the stateChanged() signal is emitted.
+
+    If a problem occurs during this process the error() is set to QAudio::OpenError,
+    state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+    In either case, the stateChanged() signal may be emitted either synchronously
+    during execution of the start() function or asynchronously after start() has
+    returned to the caller.
+
     \sa QIODevice
 */
@@ -227,27 +242,16 @@
 QIODevice* QAudioOutput::start()
 {
-    /*
-    -If currently not StoppedState, stop.
-    -If no internal QIODevice, create one.
-    -open audio output.
-    -If ok, NoError and IdleState, else OpenError and StoppedState
-    -emit stateChanged()
-    -return internal QIODevice
-    */
     return d->start(0);
 }
 
 /*!
-    Stops the audio output.
+    Stops the audio output, detaching from the system resource.
+
+    Sets error() to QAudio::NoError, state() to QAudio::StoppedState and
+    emit stateChanged() signal.
 */
 
 void QAudioOutput::stop()
 {
-    /*
-    -If StoppedState, return
-    -set to StoppedState
-    -detach from audio device
-    -emit stateChanged()
-    */
     d->stop();
 }
@@ -259,8 +263,4 @@
 void QAudioOutput::reset()
 {
-    /*
-    -drop all buffered audio, set buffers to zero.
-    -call stop()
-    */
     d->reset();
 }
@@ -268,14 +268,11 @@
 /*!
     Stops processing audio data, preserving buffered audio data.
+
+    Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and
+    emit stateChanged() signal.
 */
 
 void QAudioOutput::suspend()
 {
-    /*
-    -If not ActiveState|IdleState, return
-    -stop processing audio, saving all buffered audio data
-    -set NoError and SuspendedState
-    -emit stateChanged()
-    */
     d->suspend();
 }
@@ -283,16 +280,15 @@
 /*!
     Resumes processing audio data after a suspend().
+
+    Sets error() to QAudio::NoError.
+    Sets state() to QAudio::ActiveState if you previously called start(QIODevice*).
+    Sets state() to QAudio::IdleState if you previously called start().
+    emits stateChanged() signal.
+
+    Note: signal will always be emitted during execution of the resume() function.
 */
 
 void QAudioOutput::resume()
 {
-    /*
-    -If SuspendedState, return
-    -resume audio
-    -(PULL MODE): set ActiveState, NoError
-    -(PUSH MODE): set IdleState, NoError
-    -kick start audio if needed
-    -emit stateChanged()
-    */
      d->resume();
 }
@@ -300,12 +296,11 @@
 /*!
     Returns the free space available in bytes in the audio buffer.
+
+    NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState
+    state, otherwise returns zero.
 */
 
 int QAudioOutput::bytesFree() const
 {
-    /*
-    -If not ActiveState|IdleState, return 0
-    -return space available in audio buffer in bytes
-    */
     return d->bytesFree();
 }
@@ -354,5 +349,8 @@
     Sets the interval for notify() signal to be emitted.
     This is based on the \a ms of audio data processed
-    not on actual real-time. The resolution of the timer is platform specific.
+    not on actual real-time.
+    The minimum resolution of the timer is platform specific and values
+    should be checked with notifyInterval() to confirm actual value
+    being used.
 */
 
@@ -372,6 +370,15 @@
 
 /*!
-    Returns the amount of audio data processed since start()
+    Returns the amount of audio data processed by the class since start()
     was called in microseconds.
+
+    Note: The amount of audio data played can be determined by subtracting
+    the microseconds of audio data still in the systems audio buffer.
+
+    \code
+    qint64 bytesInBuffer = bufferSize() - bytesFree();
+    qint64 usInBuffer = (qint64)(1000000) * bytesInBuffer / ( channels() * sampleSize() / 8 ) / frequency();
+    qint64 usPlayed = processedUSecs() - usInBuffer;
+    \endcode
 */
 
Index: trunk/src/multimedia/audio/qaudiooutput_alsa_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_alsa_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiooutput_alsa_p.cpp	(revision 769)
@@ -59,6 +59,4 @@
 //#define DEBUG_AUDIO 1
 
-static const int minimumIntervalTime = 50;
-
 QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device, const QAudioFormat& audioFormat):
     settings(audioFormat)
@@ -85,6 +83,5 @@
     opened = false;
 
-    QStringList list1 = QString(QLatin1String(device)).split(QLatin1String(":"));
-    m_device = QByteArray(list1.at(0).toLocal8Bit().constData());
+    m_device = device;
 
     timer = new QTimer(this);
@@ -260,4 +257,5 @@
     if(deviceState == QAudio::StoppedState)
         return;
+    errorState = QAudio::NoError;
     deviceState = QAudio::StoppedState;
     close();
@@ -282,9 +280,9 @@
     unsigned int freakuency=settings.frequency();
 
-    QString dev = QLatin1String(m_device.constData());
+    QString dev = QString(QLatin1String(m_device.constData()));
     QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput);
     if(dev.compare(QLatin1String("default")) == 0) {
 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
-        dev = QLatin1String(devices.first().constData());
+        dev = QLatin1String(devices.first());
 #else
         dev = QLatin1String("hw:0,0");
@@ -369,8 +367,50 @@
     }
     if ( !fatal ) {
+        unsigned int maxBufferTime = 0;
+        unsigned int minBufferTime = 0;
+        unsigned int maxPeriodTime = 0;
+        unsigned int minPeriodTime = 0;
+
+        err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &maxBufferTime, &dir);
+        if ( err >= 0)
+            err = snd_pcm_hw_params_get_buffer_time_min(hwparams, &minBufferTime, &dir);
+        if ( err >= 0)
+            err = snd_pcm_hw_params_get_period_time_max(hwparams, &maxPeriodTime, &dir);
+        if ( err >= 0)
+            err = snd_pcm_hw_params_get_period_time_min(hwparams, &minPeriodTime, &dir);
+
+        if ( err < 0 ) {
+            fatal = true;
+            errMessage = QString::fromLatin1("QAudioOutput: buffer/period min and max: err = %1").arg(err);
+        } else {
+            if (maxBufferTime < buffer_time || buffer_time < minBufferTime || maxPeriodTime < period_time || minPeriodTime > period_time) {
+#ifdef DEBUG_AUDIO
+                qDebug()<<"defaults out of range";
+                qDebug()<<"pmin="<<minPeriodTime<<", pmax="<<maxPeriodTime<<", bmin="<<minBufferTime<<", bmax="<<maxBufferTime;
+#endif
+                period_time = minPeriodTime;
+                if (period_time*4 <= maxBufferTime) {
+                    // Use 4 periods if possible
+                    buffer_time = period_time*4;
+                    chunks = 4;
+                } else if (period_time*2 <= maxBufferTime) {
+                    // Use 2 periods if possible
+                    buffer_time = period_time*2;
+                    chunks = 2;
+                } else {
+                    qWarning()<<"QAudioOutput: alsa only supports single period!";
+                    fatal = true;
+                }
+#ifdef DEBUG_AUDIO
+                qDebug()<<"used: buffer_time="<<buffer_time<<", period_time="<<period_time;
+#endif
+            }
+        }
+    }
+    if ( !fatal ) {
         err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
         if ( err < 0 ) {
             fatal = true;
-                errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
+            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
         }
     }
@@ -443,5 +483,4 @@
 void QAudioOutputPrivate::close()
 {
-    deviceState = QAudio::StoppedState;
     timer->stop();
 
@@ -495,8 +534,11 @@
     }
     if(err > 0) {
-        totalTimeValue += err*1000000/settings.frequency();
+        totalTimeValue += err;
         resuming = false;
         errorState = QAudio::NoError;
-        deviceState = QAudio::ActiveState;
+        if (deviceState != QAudio::ActiveState) {
+            deviceState = QAudio::ActiveState;
+            emit stateChanged(deviceState);
+        }
         return snd_pcm_frames_to_bytes( handle, err );
     } else
@@ -530,8 +572,5 @@
 void QAudioOutputPrivate::setNotifyInterval(int ms)
 {
-    if(ms >= minimumIntervalTime)
-        intervalTime = ms;
-    else
-        intervalTime = minimumIntervalTime;
+    intervalTime = qMax(0, ms);
 }
 
@@ -543,5 +582,5 @@
 qint64 QAudioOutputPrivate::processedUSecs() const
 {
-    return totalTimeValue;
+    return qint64(1000000) * totalTimeValue / settings.frequency();
 }
 
@@ -563,8 +602,6 @@
         }
         resuming = true;
-        if(pullMode)
-            deviceState = QAudio::ActiveState;
-        else
-            deviceState = QAudio::IdleState;
+
+        deviceState = QAudio::ActiveState;
 
         errorState = QAudio::NoError;
@@ -605,6 +642,7 @@
 void QAudioOutputPrivate::feedback()
 {
-    QMetaObject::invokeMethod(this, SLOT(updateAvailable()), Qt::QueuedConnection);
-}
+    updateAvailable();
+}
+
 
 void QAudioOutputPrivate::updateAvailable()
@@ -638,5 +676,7 @@
             if(deviceState != QAudio::ActiveState)
                 return true;
-            write(audioBuffer,l);
+            qint64 bytesWritten = write(audioBuffer,l);
+            if (bytesWritten != l)
+                audioSource->seek(audioSource->pos()-(l-bytesWritten));
             bytesAvailable = bytesFree();
 
@@ -646,21 +686,33 @@
             if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
                 // Underrun
+                if (deviceState != QAudio::IdleState) {
+                    errorState = QAudio::UnderrunError;
+                    deviceState = QAudio::IdleState;
+                    emit stateChanged(deviceState);
+                }
+            }
+
+        } else if(l < 0) {
+            close();
+            deviceState = QAudio::StoppedState;
+            errorState = QAudio::IOError;
+            emit stateChanged(deviceState);
+        }
+    } else {
+        bytesAvailable = bytesFree();
+        if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
+            // Underrun
+            if (deviceState != QAudio::IdleState) {
                 errorState = QAudio::UnderrunError;
                 deviceState = QAudio::IdleState;
                 emit stateChanged(deviceState);
             }
-
-        } else if(l < 0) {
-            close();
-            errorState = QAudio::IOError;
-            emit stateChanged(deviceState);
-        }
-    } else
-        bytesAvailable = bytesFree();
+        }
+    }
 
     if(deviceState != QAudio::ActiveState)
         return true;
 
-    if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+    if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
         emit notify();
         elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
@@ -672,33 +724,8 @@
 qint64 QAudioOutputPrivate::elapsedUSecs() const
 {
-    if(!handle)
-        return 0;
-
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
-    snd_pcm_status_t* status;
-    snd_pcm_status_alloca(&status);
-
-    snd_timestamp_t t1,t2;
-    if( snd_pcm_status(handle, status) >= 0) {
-        snd_pcm_status_get_tstamp(status,&t1);
-        snd_pcm_status_get_trigger_tstamp(status,&t2);
-        t1.tv_sec-=t2.tv_sec;
-
-        signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec;
-        if(l < 0) {
-            t1.tv_sec--;
-            l = -l;
-            l %= 1000000;
-        }
-        return ((t1.tv_sec * 1000000)+l);
-    } else
-        return 0;
-#else
     return clockStamp.elapsed()*1000;
-#endif
-    return 0;
 }
 
Index: trunk/src/multimedia/audio/qaudiooutput_mac_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_mac_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiooutput_mac_p.cpp	(revision 769)
@@ -71,5 +71,5 @@
 
 
-namespace
+namespace QtMultimediaInternal
 {
 
@@ -238,5 +238,5 @@
 
 public:
-    MacOutputDevice(QAudioOutputBuffer* audioBuffer, QObject* parent):
+    MacOutputDevice(QtMultimediaInternal::QAudioOutputBuffer* audioBuffer, QObject* parent):
         QIODevice(parent),
         m_audioBuffer(audioBuffer)
@@ -264,5 +264,5 @@
 
 private:
-    QAudioOutputBuffer*    m_audioBuffer;
+    QtMultimediaInternal::QAudioOutputBuffer*    m_audioBuffer;
 };
 
@@ -286,5 +286,5 @@
         totalFrames = 0;
         audioBuffer = 0;
-        internalBufferSize = default_buffer_size;
+        internalBufferSize = QtMultimediaInternal::default_buffer_size;
         clockFrequency = AudioGetHostClockFrequency() / 1000;
         errorCode = QAudio::NoError;
@@ -400,5 +400,5 @@
         internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame;
 
-    audioBuffer = new QAudioOutputBuffer(internalBufferSize, periodSizeBytes, audioFormat);
+    audioBuffer = new QtMultimediaInternal::QAudioOutputBuffer(internalBufferSize, periodSizeBytes, audioFormat);
     connect(audioBuffer, SIGNAL(readyRead()), SLOT(inputReady()));  // Pull
 
@@ -436,5 +436,5 @@
     QIODevice*  op = device;
 
-    if (!open()) {
+    if (!audioFormat.isValid() || !open()) {
         stateCode = QAudio::StoppedState;
         errorCode = QAudio::OpenError;
@@ -537,4 +537,10 @@
 void QAudioOutputPrivate::setNotifyInterval(int milliSeconds)
 {
+    if (intervalTimer->interval() == milliSeconds)
+        return;
+
+    if (milliSeconds <= 0)
+        milliSeconds = 0;
+
     intervalTimer->setInterval(milliSeconds);
 }
@@ -623,5 +629,6 @@
 {
     audioBuffer->startFillTimer();
-    intervalTimer->start();
+    if (intervalTimer->interval() > 0)
+        intervalTimer->start();
 }
 
Index: trunk/src/multimedia/audio/qaudiooutput_mac_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_mac_p.h	(revision 766)
+++ trunk/src/multimedia/audio/qaudiooutput_mac_p.h	(revision 769)
@@ -75,5 +75,5 @@
 class QIODevice;
 
-namespace
+namespace QtMultimediaInternal
 {
 class QAudioOutputBuffer;
@@ -97,5 +97,5 @@
     AudioStreamBasicDescription deviceFormat;
     AudioStreamBasicDescription streamFormat;
-    QAudioOutputBuffer*   audioBuffer;
+    QtMultimediaInternal::QAudioOutputBuffer*   audioBuffer;
     QAtomicInt      audioThreadState;
     QWaitCondition  threadFinished;
Index: trunk/src/multimedia/audio/qaudiooutput_symbian_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_symbian_p.cpp	(revision 769)
+++ trunk/src/multimedia/audio/qaudiooutput_symbian_p.cpp	(revision 769)
@@ -0,0 +1,646 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudiooutput_symbian_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const int UnderflowTimerInterval = 50; // ms
+
+
+//-----------------------------------------------------------------------------
+// Private class
+//-----------------------------------------------------------------------------
+
+SymbianAudioOutputPrivate::SymbianAudioOutputPrivate(
+                               QAudioOutputPrivate *audioDevice)
+    :   m_audioDevice(audioDevice)
+{
+
+}
+
+SymbianAudioOutputPrivate::~SymbianAudioOutputPrivate()
+{
+
+}
+
+qint64 SymbianAudioOutputPrivate::readData(char *data, qint64 len)
+{
+    Q_UNUSED(data)
+    Q_UNUSED(len)
+    return 0;
+}
+
+qint64 SymbianAudioOutputPrivate::writeData(const char *data, qint64 len)
+{
+    qint64 totalWritten = 0;
+
+    if (m_audioDevice->state() == QAudio::ActiveState ||
+        m_audioDevice->state() == QAudio::IdleState) {
+
+        while (totalWritten < len) {
+            const qint64 written = m_audioDevice->pushData(data + totalWritten,
+                                                           len - totalWritten);
+            if (written > 0)
+                totalWritten += written;
+            else
+                break;
+        }
+    }
+
+    return totalWritten;
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device,
+                                       const QAudioFormat &format)
+    :   m_device(device)
+    ,   m_format(format)
+    ,   m_clientBufferSize(SymbianAudio::DefaultBufferSize)
+    ,   m_notifyInterval(SymbianAudio::DefaultNotifyInterval)
+    ,   m_notifyTimer(new QTimer(this))
+    ,   m_error(QAudio::NoError)
+    ,   m_internalState(SymbianAudio::ClosedState)
+    ,   m_externalState(QAudio::StoppedState)
+    ,   m_pullMode(false)
+    ,   m_source(0)
+    ,   m_devSound(0)
+    ,   m_devSoundBuffer(0)
+    ,   m_devSoundBufferSize(0)
+    ,   m_bytesWritten(0)
+    ,   m_pushDataReady(false)
+    ,   m_bytesPadding(0)
+    ,   m_underflow(false)
+    ,   m_lastBuffer(false)
+    ,   m_underflowTimer(new QTimer(this))
+    ,   m_samplesPlayed(0)
+    ,   m_totalSamplesPlayed(0)
+{
+    qRegisterMetaType<CMMFBuffer *>("CMMFBuffer *");
+
+    connect(m_notifyTimer.data(), SIGNAL(timeout()), this, SIGNAL(notify()));
+
+    m_underflowTimer->setInterval(UnderflowTimerInterval);
+    connect(m_underflowTimer.data(), SIGNAL(timeout()), this,
+            SLOT(underflowTimerExpired()));
+}
+
+QAudioOutputPrivate::~QAudioOutputPrivate()
+{
+    close();
+}
+
+QIODevice* QAudioOutputPrivate::start(QIODevice *device)
+{
+    stop();
+
+    if (device) {
+        m_pullMode = true;
+        m_source = device;
+    }
+
+    open();
+
+    if (SymbianAudio::ClosedState != m_internalState) {
+        if (device) {
+            connect(m_source, SIGNAL(readyRead()), this, SLOT(dataReady()));
+        } else {
+            m_source = new SymbianAudioOutputPrivate(this);
+            m_source->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
+        }
+
+        m_elapsed.restart();
+    }
+
+    return m_source;
+}
+
+void QAudioOutputPrivate::stop()
+{
+    close();
+}
+
+void QAudioOutputPrivate::reset()
+{
+    m_totalSamplesPlayed += getSamplesPlayed();
+    m_devSound->stop();
+    m_bytesPadding = 0;
+    startPlayback();
+}
+
+void QAudioOutputPrivate::suspend()
+{
+    if (SymbianAudio::ActiveState == m_internalState
+        || SymbianAudio::IdleState == m_internalState) {
+        m_notifyTimer->stop();
+        m_underflowTimer->stop();
+
+        const qint64 samplesWritten = SymbianAudio::Utils::bytesToSamples(
+                                          m_format, m_bytesWritten);
+
+        const qint64 samplesPlayed = getSamplesPlayed();
+
+        m_bytesWritten = 0;
+
+        // CMMFDevSound::Pause() is not guaranteed to work correctly in all
+        // implementations, for play-mode DevSound sessions.  We therefore
+        // have to implement suspend() by calling CMMFDevSound::Stop().
+        // Because this causes buffered data to be dropped, we replace the
+        // lost data with silence following a call to resume(), in order to
+        // ensure that processedUSecs() returns the correct value.
+        m_devSound->stop();
+        m_totalSamplesPlayed += samplesPlayed;
+
+        // Calculate the amount of data dropped
+        const qint64 paddingSamples = samplesWritten - samplesPlayed;
+        Q_ASSERT(paddingSamples >= 0);
+        m_bytesPadding = SymbianAudio::Utils::samplesToBytes(m_format,
+                                                             paddingSamples);
+
+        setState(SymbianAudio::SuspendedState);
+    }
+}
+
+void QAudioOutputPrivate::resume()
+{
+    if (SymbianAudio::SuspendedState == m_internalState) {
+        if (!m_pullMode && m_devSoundBuffer && m_devSoundBuffer->Data().Length())
+            bufferFilled();
+        startPlayback();
+    }
+}
+
+int QAudioOutputPrivate::bytesFree() const
+{
+    int result = 0;
+    if (m_devSoundBuffer) {
+        const TDes8 &outputBuffer = m_devSoundBuffer->Data();
+        result = outputBuffer.MaxLength() - outputBuffer.Length();
+    }
+    return result;
+}
+
+int QAudioOutputPrivate::periodSize() const
+{
+    return bufferSize();
+}
+
+void QAudioOutputPrivate::setBufferSize(int value)
+{
+    // Note that DevSound does not allow its client to specify the buffer size.
+    // This functionality is available via custom interfaces, but since these
+    // cannot be guaranteed to work across all DevSound implementations, we
+    // do not use them here.
+    // In order to comply with the expected bevahiour of QAudioOutput, we store
+    // the value and return it from bufferSize(), but the underlying DevSound
+    // buffer size remains unchanged.
+    if (value > 0)
+        m_clientBufferSize = value;
+}
+
+int QAudioOutputPrivate::bufferSize() const
+{
+    return m_devSoundBufferSize ? m_devSoundBufferSize : m_clientBufferSize;
+}
+
+void QAudioOutputPrivate::setNotifyInterval(int ms)
+{
+    if (ms >= 0) {
+        const int oldNotifyInterval = m_notifyInterval;
+        m_notifyInterval = ms;
+        if (m_notifyInterval && (SymbianAudio::ActiveState == m_internalState ||
+                                 SymbianAudio::IdleState == m_internalState))
+            m_notifyTimer->start(m_notifyInterval);
+        else
+            m_notifyTimer->stop();
+    }
+}
+
+int QAudioOutputPrivate::notifyInterval() const
+{
+    return m_notifyInterval;
+}
+
+qint64 QAudioOutputPrivate::processedUSecs() const
+{
+    int samplesPlayed = 0;
+    if (m_devSound && SymbianAudio::SuspendedState != m_internalState)
+        samplesPlayed = getSamplesPlayed();
+
+    // Protect against division by zero
+    Q_ASSERT_X(m_format.frequency() > 0, Q_FUNC_INFO, "Invalid frequency");
+
+    const qint64 result = qint64(1000000) *
+                          (samplesPlayed + m_totalSamplesPlayed)
+                        / m_format.frequency();
+
+    return result;
+}
+
+qint64 QAudioOutputPrivate::elapsedUSecs() const
+{
+    const qint64 result = (QAudio::StoppedState == state()) ?
+                              0 : m_elapsed.elapsed() * 1000;
+    return result;
+}
+
+QAudio::Error QAudioOutputPrivate::error() const
+{
+    return m_error;
+}
+
+QAudio::State QAudioOutputPrivate::state() const
+{
+    return m_externalState;
+}
+
+QAudioFormat QAudioOutputPrivate::format() const
+{
+    return m_format;
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void QAudioOutputPrivate::dataReady()
+{
+    // Client-provided QIODevice has data ready to read.
+
+    Q_ASSERT_X(m_source->bytesAvailable(), Q_FUNC_INFO,
+        "readyRead signal received, but no data available");
+
+    if (!m_bytesPadding)
+        pullData();
+}
+
+void QAudioOutputPrivate::underflowTimerExpired()
+{
+    const TInt samplesPlayed = getSamplesPlayed();
+    if (m_samplesPlayed && (samplesPlayed == m_samplesPlayed)) {
+        setError(QAudio::UnderrunError);
+    } else {
+        m_samplesPlayed = samplesPlayed;
+        m_underflowTimer->start();
+    }
+}
+
+void QAudioOutputPrivate::devsoundInitializeComplete(int err)
+{
+    Q_ASSERT_X(SymbianAudio::InitializingState == m_internalState,
+        Q_FUNC_INFO, "Invalid state");
+
+    if (!err && m_devSound->isFormatSupported(m_format))
+        startPlayback();
+    else
+        setError(QAudio::OpenError);
+}
+
+void QAudioOutputPrivate::devsoundBufferToBeFilled(CMMFBuffer *bufferBase)
+{
+    // Following receipt of this signal, DevSound should not provide another
+    // buffer until we have returned the current one.
+    Q_ASSERT_X(!m_devSoundBuffer, Q_FUNC_INFO, "Buffer already held");
+
+    // Will be returned to DevSoundWrapper by bufferProcessed().
+    m_devSoundBuffer = static_cast<CMMFDataBuffer*>(bufferBase);
+
+    if (!m_devSoundBufferSize)
+        m_devSoundBufferSize = m_devSoundBuffer->Data().MaxLength();
+
+    writePaddingData();
+
+    if (m_pullMode && isDataReady() && !m_bytesPadding)
+        pullData();
+}
+
+void QAudioOutputPrivate::devsoundPlayError(int err)
+{
+    switch (err) {
+    case KErrUnderflow:
+        m_underflow = true;
+        if (m_pullMode && !m_lastBuffer)
+            setError(QAudio::UnderrunError);
+        else
+            setState(SymbianAudio::IdleState);
+        break;
+    default:
+        setError(QAudio::IOError);
+        break;
+    }
+}
+
+void QAudioOutputPrivate::open()
+{
+    Q_ASSERT_X(SymbianAudio::ClosedState == m_internalState,
+        Q_FUNC_INFO, "DevSound already opened");
+
+    Q_ASSERT(!m_devSound);
+    m_devSound = new SymbianAudio::DevSoundWrapper(QAudio::AudioOutput, this);
+
+    connect(m_devSound, SIGNAL(initializeComplete(int)),
+            this, SLOT(devsoundInitializeComplete(int)));
+    connect(m_devSound, SIGNAL(bufferToBeProcessed(CMMFBuffer *)),
+            this, SLOT(devsoundBufferToBeFilled(CMMFBuffer *)));
+    connect(m_devSound, SIGNAL(processingError(int)),
+            this, SLOT(devsoundPlayError(int)));
+
+    setState(SymbianAudio::InitializingState);
+    m_devSound->initialize(m_format.codec());
+}
+
+void QAudioOutputPrivate::startPlayback()
+{
+    bool ok = m_devSound->setFormat(m_format);
+    if (ok)
+        ok = m_devSound->start();
+
+    if (ok) {
+        if (isDataReady())
+            setState(SymbianAudio::ActiveState);
+        else
+            setState(SymbianAudio::IdleState);
+
+        if (m_notifyInterval)
+            m_notifyTimer->start(m_notifyInterval);
+        m_underflow = false;
+
+        Q_ASSERT(m_devSound->samplesProcessed() == 0);
+
+        writePaddingData();
+
+        if (m_pullMode && m_source->bytesAvailable() && !m_bytesPadding)
+            dataReady();
+    } else {
+        setError(QAudio::OpenError);
+        close();
+    }
+}
+
+void QAudioOutputPrivate::writePaddingData()
+{
+    // See comments in suspend()
+
+    while (m_devSoundBuffer && m_bytesPadding) {
+        if (SymbianAudio::IdleState == m_internalState)
+            setState(SymbianAudio::ActiveState);
+
+        TDes8 &outputBuffer = m_devSoundBuffer->Data();
+        const qint64 outputBytes = bytesFree();
+        const qint64 paddingBytes = outputBytes < m_bytesPadding ?
+                                        outputBytes : m_bytesPadding;
+        unsigned char *ptr = const_cast<unsigned char*>(outputBuffer.Ptr());
+        Mem::FillZ(ptr, paddingBytes);
+        outputBuffer.SetLength(outputBuffer.Length() + paddingBytes);
+        m_bytesPadding -= paddingBytes;
+        Q_ASSERT(m_bytesPadding >= 0);
+
+        if (m_pullMode && m_source->atEnd())
+            lastBufferFilled();
+        if ((paddingBytes == outputBytes) || !m_bytesPadding)
+            bufferFilled();
+    }
+}
+
+qint64 QAudioOutputPrivate::pushData(const char *data, qint64 len)
+{
+    // Data has been written to SymbianAudioOutputPrivate
+
+    Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO,
+        "pushData called when in pull mode");
+
+    const unsigned char *const inputPtr =
+        reinterpret_cast<const unsigned char*>(data);
+    qint64 bytesWritten = 0;
+
+    if (SymbianAudio::IdleState == m_internalState)
+        setState(SymbianAudio::ActiveState);
+
+    while (m_devSoundBuffer && (bytesWritten < len)) {
+        // writePaddingData() is called from BufferToBeFilled(), so we should
+        // never have any padding data left at this point.
+        Q_ASSERT_X(0 == m_bytesPadding, Q_FUNC_INFO,
+            "Padding bytes remaining in pushData");
+
+        TDes8 &outputBuffer = m_devSoundBuffer->Data();
+
+        const qint64 outputBytes = bytesFree();
+        const qint64 inputBytes = len - bytesWritten;
+        const qint64 copyBytes = outputBytes < inputBytes ?
+                                     outputBytes : inputBytes;
+
+        outputBuffer.Append(inputPtr + bytesWritten, copyBytes);
+        bytesWritten += copyBytes;
+
+        bufferFilled();
+    }
+
+    m_pushDataReady = (bytesWritten < len);
+
+    // If DevSound is still initializing (m_internalState == InitializingState),
+    // we cannot transition m_internalState to ActiveState, but we must emit
+    // an (external) state change from IdleState to ActiveState.  The following
+    // call triggers this signal.
+    setState(m_internalState);
+
+    return bytesWritten;
+}
+
+void QAudioOutputPrivate::pullData()
+{
+    Q_ASSERT_X(m_pullMode, Q_FUNC_INFO,
+        "pullData called when in push mode");
+
+    // writePaddingData() is called by BufferToBeFilled() before pullData(),
+    // so we should never have any padding data left at this point.
+    Q_ASSERT_X(0 == m_bytesPadding, Q_FUNC_INFO,
+        "Padding bytes remaining in pullData");
+
+    qint64 inputBytes = m_source->bytesAvailable();
+    while (m_devSoundBuffer && inputBytes) {
+        if (SymbianAudio::IdleState == m_internalState)
+            setState(SymbianAudio::ActiveState);
+
+        TDes8 &outputBuffer = m_devSoundBuffer->Data();
+
+        const qint64 outputBytes = bytesFree();
+        const qint64 copyBytes = outputBytes < inputBytes ?
+                                     outputBytes : inputBytes;
+
+        char *outputPtr = (char*)(outputBuffer.Ptr() + outputBuffer.Length());
+        const qint64 bytesCopied = m_source->read(outputPtr, copyBytes);
+        Q_ASSERT(bytesCopied == copyBytes);
+        outputBuffer.SetLength(outputBuffer.Length() + bytesCopied);
+        inputBytes -= bytesCopied;
+
+        if (m_source->atEnd())
+            lastBufferFilled();
+        else if (copyBytes == outputBytes)
+            bufferFilled();
+    }
+}
+
+void QAudioOutputPrivate::bufferFilled()
+{
+    Q_ASSERT_X(m_devSoundBuffer, Q_FUNC_INFO, "No buffer to return");
+
+    const TDes8 &outputBuffer = m_devSoundBuffer->Data();
+    m_bytesWritten += outputBuffer.Length();
+
+    m_devSoundBuffer = 0;
+
+    m_samplesPlayed = getSamplesPlayed();
+    m_underflowTimer->start();
+
+    if (QAudio::UnderrunError == m_error)
+        m_error = QAudio::NoError;
+
+    m_devSound->bufferProcessed();
+}
+
+void QAudioOutputPrivate::lastBufferFilled()
+{
+    Q_ASSERT_X(m_devSoundBuffer, Q_FUNC_INFO, "No buffer to fill");
+    Q_ASSERT_X(!m_lastBuffer, Q_FUNC_INFO, "Last buffer already sent");
+    m_lastBuffer = true;
+    m_devSoundBuffer->SetLastBuffer(ETrue);
+    bufferFilled();
+}
+
+void QAudioOutputPrivate::close()
+{
+    m_notifyTimer->stop();
+    m_underflowTimer->stop();
+
+    m_error = QAudio::NoError;
+
+    if (m_devSound)
+        m_devSound->stop();
+    delete m_devSound;
+    m_devSound = 0;
+
+    m_devSoundBuffer = 0;
+    m_devSoundBufferSize = 0;
+
+    if (!m_pullMode) // m_source is owned
+        delete m_source;
+    m_pullMode = false;
+    m_source = 0;
+
+    m_bytesWritten = 0;
+    m_pushDataReady = false;
+    m_bytesPadding = 0;
+    m_underflow = false;
+    m_lastBuffer = false;
+    m_samplesPlayed = 0;
+    m_totalSamplesPlayed = 0;
+
+    setState(SymbianAudio::ClosedState);
+}
+
+qint64 QAudioOutputPrivate::getSamplesPlayed() const
+{
+    qint64 result = 0;
+    if (m_devSound) {
+        const qint64 samplesWritten = SymbianAudio::Utils::bytesToSamples(
+                                          m_format, m_bytesWritten);
+
+        if (m_underflow) {
+            result = samplesWritten;
+        } else {
+            // This is necessary because some DevSound implementations report
+            // that they have played more data than has actually been provided to them
+            // by the client.
+            const qint64 devSoundSamplesPlayed(m_devSound->samplesProcessed());
+            result = qMin(devSoundSamplesPlayed, samplesWritten);
+        }
+    }
+    return result;
+}
+
+void QAudioOutputPrivate::setError(QAudio::Error error)
+{
+    m_error = error;
+
+    // Although no state transition actually occurs here, a stateChanged event
+    // must be emitted to inform the client that the call to start() was
+    // unsuccessful.
+    if (QAudio::OpenError == error) {
+        emit stateChanged(QAudio::StoppedState);
+    } else {
+        if (QAudio::UnderrunError == error)
+            setState(SymbianAudio::IdleState);
+        else
+            // Close the DevSound instance.  This causes a transition to
+            // StoppedState.  This must be done asynchronously in case the
+            // current function was called from a DevSound event handler, in which
+            // case deleting the DevSound instance may cause an exception.
+            QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
+    }
+}
+
+void QAudioOutputPrivate::setState(SymbianAudio::State newInternalState)
+{
+    const QAudio::State oldExternalState = m_externalState;
+    m_internalState = newInternalState;
+    m_externalState = SymbianAudio::Utils::stateNativeToQt(m_internalState);
+
+    if (m_externalState != oldExternalState)
+        emit stateChanged(m_externalState);
+}
+
+bool QAudioOutputPrivate::isDataReady() const
+{
+    return (m_source && m_source->bytesAvailable())
+        ||  m_bytesPadding
+        ||  m_pushDataReady;
+}
+
+QT_END_NAMESPACE
Index: trunk/src/multimedia/audio/qaudiooutput_symbian_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_symbian_p.h	(revision 769)
+++ trunk/src/multimedia/audio/qaudiooutput_symbian_p.h	(revision 769)
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists for the convenience
+// of other Qt classes.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIOOUTPUT_SYMBIAN_P_H
+#define QAUDIOOUTPUT_SYMBIAN_P_H
+
+#include <QtMultimedia/qaudioengine.h>
+#include <QTime>
+#include <QTimer>
+#include <sounddevice.h>
+#include "qaudio_symbian_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAudioOutputPrivate;
+
+class SymbianAudioOutputPrivate : public QIODevice
+{
+    friend class QAudioOutputPrivate;
+    Q_OBJECT
+public:
+    SymbianAudioOutputPrivate(QAudioOutputPrivate *audio);
+    ~SymbianAudioOutputPrivate();
+
+    qint64 readData(char *data, qint64 len);
+    qint64 writeData(const char *data, qint64 len);
+
+private:
+    QAudioOutputPrivate *const m_audioDevice;
+};
+
+class QAudioOutputPrivate
+    :   public QAbstractAudioOutput
+{
+    friend class SymbianAudioOutputPrivate;
+    Q_OBJECT
+public:
+    QAudioOutputPrivate(const QByteArray &device,
+                       const QAudioFormat &audioFormat);
+    ~QAudioOutputPrivate();
+
+    // QAbstractAudioOutput
+    QIODevice* start(QIODevice *device = 0);
+    void stop();
+    void reset();
+    void suspend();
+    void resume();
+    int bytesFree() const;
+    int periodSize() const;
+    void setBufferSize(int value);
+    int bufferSize() const;
+    void setNotifyInterval(int milliSeconds);
+    int notifyInterval() const;
+    qint64 processedUSecs() const;
+    qint64 elapsedUSecs() const;
+    QAudio::Error error() const;
+    QAudio::State state() const;
+    QAudioFormat format() const;
+
+private slots:
+    void dataReady();
+    void underflowTimerExpired();
+    void devsoundInitializeComplete(int err);
+    void devsoundBufferToBeFilled(CMMFBuffer *);
+    void devsoundPlayError(int err);
+
+private:
+   void open();
+   void startPlayback();
+   void writePaddingData();
+   qint64 pushData(const char *data, qint64 len);
+   void pullData();
+   void bufferFilled();
+   void lastBufferFilled();
+   Q_INVOKABLE void close();
+
+   qint64 getSamplesPlayed() const;
+
+   void setError(QAudio::Error error);
+   void setState(SymbianAudio::State state);
+
+   bool isDataReady() const;
+
+private:
+    const QByteArray m_device;
+    const QAudioFormat m_format;
+
+    int m_clientBufferSize;
+    int m_notifyInterval;
+    QScopedPointer<QTimer> m_notifyTimer;
+    QTime m_elapsed;
+    QAudio::Error m_error;
+
+    SymbianAudio::State m_internalState;
+    QAudio::State m_externalState;
+
+    bool m_pullMode;
+    QIODevice *m_source;
+
+    SymbianAudio::DevSoundWrapper* m_devSound;
+
+    // Buffer provided by DevSound, to be filled with data.
+    CMMFDataBuffer *m_devSoundBuffer;
+
+    int m_devSoundBufferSize;
+
+    // Number of bytes transferred from QIODevice to QAudioOutput.  It is
+    // necessary to count this because data is dropped when suspend() is
+    // called.  The difference between the position reported by DevSound and
+    // this value allows us to calculate m_bytesPadding;
+    quint32 m_bytesWritten;
+
+    // True if client has provided data while the audio subsystem was not
+    // ready to consume it.
+    bool m_pushDataReady;
+
+    // Number of zero bytes which will be written when client calls resume().
+    quint32 m_bytesPadding;
+
+    // True if PlayError(KErrUnderflow) has been called.
+    bool m_underflow;
+
+    // True if a buffer marked with the "last buffer" flag has been provided
+    // to DevSound.
+    bool m_lastBuffer;
+
+    // Some DevSound implementations ignore all underflow errors raised by the
+    // audio driver, unless the last buffer flag has been set by the client.
+    // In push-mode playback, this flag will never be set, so the underflow
+    // error will never be reported.  In order to work around this, a timer
+    // is used, which gets reset every time the client provides more data.  If
+    // the timer expires, an underflow error is raised by this object.
+    QScopedPointer<QTimer> m_underflowTimer;
+
+    // Result of previous call to CMMFDevSound::SamplesPlayed().  This value is
+    // used to determine whether, when m_underflowTimer expires, an
+    // underflow error has actually occurred.
+    quint32 m_samplesPlayed;
+
+    // Samples played up to the last call to suspend().  It is necessary
+    // to cache this because suspend() is implemented using
+    // CMMFDevSound::Stop(), which resets DevSound's SamplesPlayed() counter.
+    quint32 m_totalSamplesPlayed;
+
+};
+
+QT_END_NAMESPACE
+
+#endif
Index: trunk/src/multimedia/audio/qaudiooutput_win32_p.cpp
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_win32_p.cpp	(revision 766)
+++ trunk/src/multimedia/audio/qaudiooutput_win32_p.cpp	(revision 769)
@@ -56,8 +56,4 @@
 
 QT_BEGIN_NAMESPACE
-
-static CRITICAL_SECTION waveOutCriticalSection;
-
-static const int minimumIntervalTime = 50;
 
 QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device, const QAudioFormat& audioFormat):
@@ -76,15 +72,13 @@
     pullMode = true;
     finished = false;
-    InitializeCriticalSection(&waveOutCriticalSection);
 }
 
 QAudioOutputPrivate::~QAudioOutputPrivate()
 {
-    EnterCriticalSection(&waveOutCriticalSection);
+    mutex.lock();
     finished = true;
-    LeaveCriticalSection(&waveOutCriticalSection);
+    mutex.unlock();
 
     close();
-    DeleteCriticalSection(&waveOutCriticalSection);
 }
 
@@ -100,4 +94,6 @@
     if(!qAudio)
         return;
+
+    QMutexLocker(&qAudio->mutex);
 
     switch(uMsg) {
@@ -108,7 +104,5 @@
             return;
         case WOM_DONE:
-            EnterCriticalSection(&waveOutCriticalSection);
             if(qAudio->finished || qAudio->buffer_size == 0 || qAudio->period_size == 0) {
-                LeaveCriticalSection(&waveOutCriticalSection);
                 return;
 	    }
@@ -117,5 +111,4 @@
                 qAudio->waveFreeBlockCount = qAudio->buffer_size/qAudio->period_size;
             qAudio->feedback();
-            LeaveCriticalSection(&waveOutCriticalSection);
             break;
         default:
@@ -153,5 +146,5 @@
 
     for(int i = 0; i < count; i++) {
-        waveOutUnprepareHeader(hWaveOut,&blocks[i], sizeof(WAVEHDR));
+        waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR));
         blocks+=sizeof(WAVEHDR);
     }
@@ -212,4 +205,11 @@
     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
 #endif
+    if (!(settings.frequency() >= 8000 && settings.frequency() <= 48000)) {
+        errorState = QAudio::OpenError;
+        deviceState = QAudio::StoppedState;
+        emit stateChanged(deviceState);
+        qWarning("QAudioOutput: open error, frequency out of range.");
+        return false;
+    }
     if(buffer_size == 0) {
         // Default buffer size, 200ms, default period size is 40ms
@@ -221,7 +221,7 @@
     waveBlocks = allocateBlocks(period_size, buffer_size/period_size);
 
-    EnterCriticalSection(&waveOutCriticalSection);
+    mutex.lock();
     waveFreeBlockCount = buffer_size/period_size;
-    LeaveCriticalSection(&waveOutCriticalSection);
+    mutex.unlock();
 
     waveCurrentBlock = 0;
@@ -290,4 +290,5 @@
 
     deviceState = QAudio::StoppedState;
+    errorState = QAudio::NoError;
     int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
                   *settings.channels()*(settings.sampleSize()/8));
@@ -328,8 +329,5 @@
 void QAudioOutputPrivate::setNotifyInterval(int ms)
 {
-    if(ms >= minimumIntervalTime)
-        intervalTime = ms;
-    else
-        intervalTime = minimumIntervalTime;
+    intervalTime = qMax(0, ms);
 }
 
@@ -341,5 +339,11 @@
 qint64 QAudioOutputPrivate::processedUSecs() const
 {
-    return totalTimeValue;
+    if (deviceState == QAudio::StoppedState)
+        return 0;
+    qint64 result = qint64(1000000) * totalTimeValue /
+        (settings.channels()*(settings.sampleSize()/8)) /
+        settings.frequency();
+
+    return result;
 }
 
@@ -347,4 +351,6 @@
 {
     // Write out some audio data
+    if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+        return 0;
 
     char* p = (char*)data;
@@ -355,10 +361,10 @@
     current = &waveBlocks[waveCurrentBlock];
     while(l > 0) {
-        EnterCriticalSection(&waveOutCriticalSection);
+        mutex.lock();
         if(waveFreeBlockCount==0) {
-            LeaveCriticalSection(&waveOutCriticalSection);
+            mutex.unlock();
             break;
         }
-        LeaveCriticalSection(&waveOutCriticalSection);
+        mutex.unlock();
 
         if(current->dwFlags & WHDR_PREPARED)
@@ -377,20 +383,21 @@
         waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
 
-        EnterCriticalSection(&waveOutCriticalSection);
+        mutex.lock();
         waveFreeBlockCount--;
-        LeaveCriticalSection(&waveOutCriticalSection);
 #ifdef DEBUG_AUDIO
-        EnterCriticalSection(&waveOutCriticalSection);
         qDebug("write out l=%d, waveFreeBlockCount=%d",
                 current->dwBufferLength,waveFreeBlockCount);
-        LeaveCriticalSection(&waveOutCriticalSection);
 #endif
-        totalTimeValue += current->dwBufferLength
-            /(settings.channels()*(settings.sampleSize()/8))
-            *1000000/settings.frequency();;
+        mutex.unlock();
+        totalTimeValue += current->dwBufferLength;
         waveCurrentBlock++;
         waveCurrentBlock %= buffer_size/period_size;
         current = &waveBlocks[waveCurrentBlock];
         current->dwUser = 0;
+        errorState = QAudio::NoError;
+        if (deviceState != QAudio::ActiveState) {
+            deviceState = QAudio::ActiveState;
+            emit stateChanged(deviceState);
+        }
     }
     return (len-l);
@@ -410,6 +417,9 @@
 void QAudioOutputPrivate::suspend()
 {
-    if(deviceState == QAudio::ActiveState) {
+    if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState) {
+        int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
+                *settings.channels()*(settings.sampleSize()/8));
         waveOutPause(hWaveOut);
+        Sleep(delay+10);
         deviceState = QAudio::SuspendedState;
         errorState = QAudio::NoError;
@@ -434,4 +444,7 @@
 bool QAudioOutputPrivate::deviceReady()
 {
+    if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
+        return false;
+
     if(pullMode) {
         int chunks = bytesAvailable/period_size;
@@ -445,12 +458,14 @@
 
 	bool full=false;
-	EnterCriticalSection(&waveOutCriticalSection);
+
+        mutex.lock();
 	if(waveFreeBlockCount==0) full = true;
-	LeaveCriticalSection(&waveOutCriticalSection);
+        mutex.unlock();
+
 	if (full){
 #ifdef DEBUG_AUDIO
             qDebug() << "Skipping data as unable to write";
 #endif
-	    if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime ) {
+	    if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime ) {
                 emit notify();
 		elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
@@ -466,6 +481,14 @@
         if(l > 0) {
             int out= write(audioBuffer,l);
-            if(out > 0)
-                deviceState = QAudio::ActiveState;
+            if(out > 0) {
+                if (deviceState != QAudio::ActiveState) {
+                    deviceState = QAudio::ActiveState;
+                    emit stateChanged(deviceState);
+                }
+            }
+            if ( out < l) {
+                // Didnt write all data
+                audioSource->seek(audioSource->pos()-(l-out));
+            }
 	    if(startup)
 	        waveOutRestart(hWaveOut);
@@ -474,22 +497,40 @@
 
             int check = 0;
-            EnterCriticalSection(&waveOutCriticalSection);
+
+            mutex.lock();
             check = waveFreeBlockCount;
-            LeaveCriticalSection(&waveOutCriticalSection);
+            mutex.unlock();
+
             if(check == buffer_size/period_size) {
+                if (deviceState != QAudio::IdleState) {
+                    errorState = QAudio::UnderrunError;
+                    deviceState = QAudio::IdleState;
+                    emit stateChanged(deviceState);
+                }
+            }
+
+        } else if(l < 0) {
+            bytesAvailable = bytesFree();
+            errorState = QAudio::IOError;
+        }
+    } else {
+        int buffered;
+
+        mutex.lock();
+	buffered = waveFreeBlockCount;
+        mutex.unlock();
+
+        if (buffered >= buffer_size/period_size && deviceState == QAudio::ActiveState) {
+            if (deviceState != QAudio::IdleState) {
                 errorState = QAudio::UnderrunError;
                 deviceState = QAudio::IdleState;
                 emit stateChanged(deviceState);
             }
-
-        } else if(l < 0) {
-            bytesAvailable = bytesFree();
-            errorState = QAudio::IOError;
         }
     }
-    if(deviceState != QAudio::ActiveState)
+    if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
         return true;
 
-    if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+    if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
         emit notify();
 	elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
Index: trunk/src/multimedia/audio/qaudiooutput_win32_p.h
===================================================================
--- trunk/src/multimedia/audio/qaudiooutput_win32_p.h	(revision 766)
+++ trunk/src/multimedia/audio/qaudiooutput_win32_p.h	(revision 769)
@@ -62,4 +62,5 @@
 #include <QtCore/qstringlist.h>
 #include <QtCore/qdatetime.h>
+#include <QtCore/qmutex.h>
 
 #include <QtMultimedia/qaudio.h>
@@ -120,4 +121,6 @@
             DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
 
+    QMutex mutex;
+
     WAVEHDR* allocateBlocks(int size, int count);
     void freeBlocks(WAVEHDR* blockArray);
Index: trunk/src/multimedia/video/qabstractvideobuffer.cpp
===================================================================
--- trunk/src/multimedia/video/qabstractvideobuffer.cpp	(revision 766)
+++ trunk/src/multimedia/video/qabstractvideobuffer.cpp	(revision 769)
@@ -49,5 +49,4 @@
     \class QAbstractVideoBuffer
     \brief The QAbstractVideoBuffer class is an abstraction for video data.
-    \preliminary
     \since 4.6
 
Index: trunk/src/multimedia/video/qabstractvideosurface.cpp
===================================================================
--- trunk/src/multimedia/video/qabstractvideosurface.cpp	(revision 766)
+++ trunk/src/multimedia/video/qabstractvideosurface.cpp	(revision 769)
@@ -47,5 +47,4 @@
     \class QAbstractVideoSurface
     \brief The QAbstractVideoSurface class is a base class for video presentation surfaces.
-    \preliminary
     \since 4.6
 
Index: trunk/src/multimedia/video/qvideoframe.cpp
===================================================================
--- trunk/src/multimedia/video/qvideoframe.cpp	(revision 766)
+++ trunk/src/multimedia/video/qvideoframe.cpp	(revision 769)
@@ -103,5 +103,4 @@
     \class QVideoFrame
     \brief The QVideoFrame class provides a representation of a frame of video data.
-    \preliminary
     \since 4.6
 
Index: trunk/src/multimedia/video/qvideosurfaceformat.cpp
===================================================================
--- trunk/src/multimedia/video/qvideosurfaceformat.cpp	(revision 766)
+++ trunk/src/multimedia/video/qvideosurfaceformat.cpp	(revision 769)
@@ -137,5 +137,4 @@
     \brief The QVideoSurfaceFormat class specifies the stream format of a video presentation
     surface.
-    \preliminary
     \since 4.6
 
Index: trunk/src/network/access/qfilenetworkreply.cpp
===================================================================
--- trunk/src/network/access/qfilenetworkreply.cpp	(revision 766)
+++ trunk/src/network/access/qfilenetworkreply.cpp	(revision 769)
@@ -50,6 +50,11 @@
 
 QFileNetworkReplyPrivate::QFileNetworkReplyPrivate()
-    : QNetworkReplyPrivate(), realFileSize(0)
-{
+    : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0)
+{
+}
+
+QFileNetworkReplyPrivate::~QFileNetworkReplyPrivate()
+{
+    delete fileEngine;
 }
 
@@ -95,7 +100,6 @@
         fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
     }
-    d->realFile.setFileName(fileName);
-
-    QFileInfo fi(d->realFile);
+
+    QFileInfo fi(fileName);
     if (fi.isDir()) {
         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
@@ -107,12 +111,13 @@
     }
 
-    bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+    d->fileEngine = QAbstractFileEngine::create(fileName);
+    bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
 
     // could we open the file?
     if (!opened) {
         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
-                      .arg(d->realFile.fileName(), d->realFile.errorString());
-
-        if (d->realFile.exists()) {
+                      .arg(fileName, d->fileEngine->errorString());
+
+        if (fi.exists()) {
             setError(QNetworkReply::ContentAccessDenied, msg);
             QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
@@ -127,11 +132,11 @@
     }
 
-    d->realFileSize = fi.size();
+    d->fileSize = fi.size();
     setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
-    setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize);
+    setHeader(QNetworkRequest::ContentLengthHeader, d->fileSize);
 
     QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
     QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
-        Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize));
+        Q_ARG(qint64, d->fileSize), Q_ARG(qint64, d->fileSize));
     QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
     QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
@@ -147,5 +152,6 @@
     Q_D(QFileNetworkReply);
     QNetworkReply::close();
-    d->realFile.close();
+    if (d->fileEngine)
+        d->fileEngine->close();
 }
 
@@ -154,5 +160,6 @@
     Q_D(QFileNetworkReply);
     QNetworkReply::close();
-    d->realFile.close();
+    if (d->fileEngine)
+        d->fileEngine->close();
 }
 
@@ -160,5 +167,8 @@
 {
     Q_D(const QFileNetworkReply);
-    return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable();
+    if (!d->fileEngine)
+        return 0;
+
+    return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos;
 }
 
@@ -171,5 +181,5 @@
 {
     Q_D(const QFileNetworkReply);
-    return d->realFileSize;
+    return d->fileSize;
 }
 
@@ -180,9 +190,15 @@
 {
     Q_D(QFileNetworkReply);
-    qint64 ret = d->realFile.read(data, maxlen);
-    if (ret == 0 && bytesAvailable() == 0)
+    if (!d->fileEngine)
+        return -1;
+
+    qint64 ret = d->fileEngine->read(data, maxlen);
+    if (ret == 0 && bytesAvailable() == 0) {
         return -1; // everything had been read
-    else
-        return ret;
+    } else if (ret > 0) {
+        d->filePos += ret;
+    }
+
+    return ret;
 }
 
Index: trunk/src/network/access/qfilenetworkreply_p.h
===================================================================
--- trunk/src/network/access/qfilenetworkreply_p.h	(revision 766)
+++ trunk/src/network/access/qfilenetworkreply_p.h	(revision 769)
@@ -58,4 +58,5 @@
 #include "qnetworkaccessmanager.h"
 #include <QFile>
+#include <QAbstractFileEngine>
 
 QT_BEGIN_NAMESPACE
@@ -86,7 +87,9 @@
 public:
     QFileNetworkReplyPrivate();
+    ~QFileNetworkReplyPrivate();
 
-    QFile realFile;
-    qint64 realFileSize;
+    QAbstractFileEngine *fileEngine;
+    qint64 fileSize;
+    qint64 filePos;
 
     virtual bool isFinished() const;
Index: trunk/src/network/access/qftp.cpp
===================================================================
--- trunk/src/network/access/qftp.cpp	(revision 766)
+++ trunk/src/network/access/qftp.cpp	(revision 769)
@@ -2310,4 +2310,10 @@
 {
     Q_Q(QFtp);
+
+    if (pending.isEmpty()) {
+        qWarning() << "QFtpPrivate::_q_piError was called without pending command!";
+        return;
+    }
+
     QFtpCommand *c = pending.first();
 
Index: trunk/src/network/access/qhttpnetworkconnection.cpp
===================================================================
--- trunk/src/network/access/qhttpnetworkconnection.cpp	(revision 766)
+++ trunk/src/network/access/qhttpnetworkconnection.cpp	(revision 769)
@@ -72,7 +72,9 @@
 #endif
 
-// the maximum amount of requests that might be pipelined into a socket
-// from what was suggested, 3 seems to be OK
+// The pipeline length. So there will be 4 requests in flight.
 const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3;
+// Only re-fill the pipeline if there's defaultRePipelineLength slots free in the pipeline.
+// This means that there are 2 requests in flight and 2 slots free that will be re-filled.
+const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;
 
 
@@ -405,4 +407,5 @@
     reply->setRequest(request);
     reply->d_func()->connection = q;
+    reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later
     HttpMessagePair pair = qMakePair(request, reply);
 
@@ -416,6 +419,16 @@
         break;
     }
+
     // this used to be called via invokeMethod and a QueuedConnection
+    // It is the only place _q_startNextRequest is called directly without going
+    // through the event loop using a QueuedConnection.
+    // This is dangerous because of recursion that might occur when emitting
+    // signals as DirectConnection from this code path. Therefore all signal
+    // emissions that can come out from this code path need to
+    // be QueuedConnection.
+    // We are currently trying to fine-tune this.
     _q_startNextRequest();
+
+
     return reply;
 }
@@ -423,4 +436,6 @@
 void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair)
 {
+    Q_Q(QHttpNetworkConnection);
+
     QHttpNetworkRequest request = pair.first;
     switch (request.priority()) {
@@ -433,6 +448,6 @@
         break;
     }
-    // this used to be called via invokeMethod and a QueuedConnection
-    _q_startNextRequest();
+
+    QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
 }
 
@@ -475,52 +490,70 @@
     int i = indexOf(socket);
 
-    bool highPriorityQueueProcessingDone = false;
-    bool lowPriorityQueueProcessingDone = false;
-
-    while (!highPriorityQueueProcessingDone && !lowPriorityQueueProcessingDone) {
-        // this loop runs once per request we intend to pipeline in.
-
-        if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
-            return;
-
-        // the current request that is in must already support pipelining
-        if (!channels[i].request.isPipeliningAllowed())
-            return;
-
-        // the current request must be a idempotent (right now we only check GET)
-        if (channels[i].request.operation() != QHttpNetworkRequest::Get)
-            return;
-
-        // check if socket is connected
-        if (socket->state() != QAbstractSocket::ConnectedState)
-            return;
-
-        // check for resendCurrent
-        if (channels[i].resendCurrent)
-            return;
-
-        // we do not like authentication stuff
-        // ### make sure to be OK with this in later releases
-        if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
-            return;
-        if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
-            return;
-
-        // check for pipeline length
+    // return fast if there was no reply right now processed
+    if (channels[i].reply == 0)
+        return;
+
+    if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= defaultRePipelineLength)) {
+        return;
+    }
+
+    if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
+        return;
+
+    // the current request that is in must already support pipelining
+    if (!channels[i].request.isPipeliningAllowed())
+        return;
+
+    // the current request must be a idempotent (right now we only check GET)
+    if (channels[i].request.operation() != QHttpNetworkRequest::Get)
+        return;
+
+    // check if socket is connected
+    if (socket->state() != QAbstractSocket::ConnectedState)
+        return;
+
+    // check for resendCurrent
+    if (channels[i].resendCurrent)
+        return;
+
+    // we do not like authentication stuff
+    // ### make sure to be OK with this in later releases
+    if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
+        return;
+    if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
+        return;
+
+    // must be in ReadingState or WaitingState
+    if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
+           || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
+        return;
+
+
+    //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing highPriorityQueue, size=" << highPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
+    int lengthBefore;
+    while (!highPriorityQueue.isEmpty()) {
+        lengthBefore = channels[i].alreadyPipelinedRequests.length();
+        fillPipeline(highPriorityQueue, channels[i]);
+
         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
             return;
 
-        // must be in ReadingState or WaitingState
-        if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
-               || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
+        if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
+            break; // did not process anything, now do the low prio queue
+    }
+
+    //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing lowPriorityQueue, size=" << lowPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
+    while (!lowPriorityQueue.isEmpty()) {
+        lengthBefore = channels[i].alreadyPipelinedRequests.length();
+        fillPipeline(lowPriorityQueue, channels[i]);
+
+        if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
             return;
 
-        highPriorityQueueProcessingDone = fillPipeline(highPriorityQueue, channels[i]);
-        // not finished with highPriorityQueue? then loop again
-        if (!highPriorityQueueProcessingDone)
-            continue;
-        // highPriorityQueue was processed, now deal with the lowPriorityQueue
-        lowPriorityQueueProcessingDone = fillPipeline(lowPriorityQueue, channels[i]);
-    }
+        if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
+            break; // did not process anything
+    }
+
+
 }
 
@@ -682,4 +715,7 @@
 
 
+// This function must be called from the event loop. The only
+// exception is documented in QHttpNetworkConnectionPrivate::queueRequest
+// although it is called _q_startNextRequest, it will actually start multiple requests when possible
 void QHttpNetworkConnectionPrivate::_q_startNextRequest()
 {
@@ -689,6 +725,9 @@
             channels[i].resendCurrent = false;
             channels[i].state = QHttpNetworkConnectionChannel::IdleState;
-            if (channels[i].reply)
-                channels[i].sendRequest();
+
+            // if this is not possible, error will be emitted and connection terminated
+            if (!channels[i].resetUploadData())
+                continue;
+            channels[i].sendRequest();
         }
     }
@@ -696,24 +735,21 @@
     // dequeue new ones
 
-    QAbstractSocket *socket = 0;
+    // return fast if there is nothing to do
+    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
+        return;
+    // try to get a free AND connected socket
     for (int i = 0; i < channelCount; ++i) {
-        QAbstractSocket *chSocket = channels[i].socket;
-        // try to get a free AND connected socket
         if (!channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) {
-            socket = chSocket;
-            dequeueAndSendRequest(socket);
-            break;
-        }
-    }
-
-    if (!socket) {
-        for (int i = 0; i < channelCount; ++i) {
-            QAbstractSocket *chSocket = channels[i].socket;
-            // try to get a free unconnected socket
-            if (!channels[i].isSocketBusy()) {
-                socket = chSocket;
-                dequeueAndSendRequest(socket);
-                break;
-            }
+            dequeueAndSendRequest(channels[i].socket);
+        }
+    }
+
+    // return fast if there is nothing to do
+    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
+        return;
+    // try to get a free unconnected socket
+    for (int i = 0; i < channelCount; ++i) {
+        if (!channels[i].isSocketBusy()) {
+            dequeueAndSendRequest(channels[i].socket);
         }
     }
@@ -729,6 +765,7 @@
     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
         return;
-    for (int j = 0; j < channelCount; j++)
-        fillPipeline(channels[j].socket);
+    for (int i = 0; i < channelCount; i++)
+        if (channels[i].socket->state() == QAbstractSocket::ConnectedState)
+            fillPipeline(channels[i].socket);
 }
 
@@ -856,15 +893,4 @@
 // SSL support below
 #ifndef QT_NO_OPENSSL
-QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const
-{
-    if (!encrypt)
-        return QSslConfiguration();
-
-    for (int i = 0; i < channelCount; ++i)
-        if (channels[i].reply == &reply)
-            return static_cast<QSslSocket *>(channels[0].socket)->sslConfiguration();
-    return QSslConfiguration(); // pending or done request
-}
-
 void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config)
 {
Index: trunk/src/network/access/qhttpnetworkconnection_p.h
===================================================================
--- trunk/src/network/access/qhttpnetworkconnection_p.h	(revision 766)
+++ trunk/src/network/access/qhttpnetworkconnection_p.h	(revision 769)
@@ -157,4 +157,5 @@
     static const int defaultChannelCount;
     static const int defaultPipelineLength;
+    static const int defaultRePipelineLength;
 
     QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
@@ -211,9 +212,4 @@
     bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
 
-
-#ifndef QT_NO_OPENSSL
-    QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const;
-#endif
-
 #ifndef QT_NO_NETWORKPROXY
     QNetworkProxy networkProxy;
Index: trunk/src/network/access/qhttpnetworkconnectionchannel.cpp
===================================================================
--- trunk/src/network/access/qhttpnetworkconnectionchannel.cpp	(revision 766)
+++ trunk/src/network/access/qhttpnetworkconnectionchannel.cpp	(revision 769)
@@ -59,4 +59,26 @@
 // TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp
 
+QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
+    : socket(0)
+    , state(IdleState)
+    , reply(0)
+    , written(0)
+    , bytesTotal(0)
+    , resendCurrent(false)
+    , lastStatus(0)
+    , pendingEncrypt(false)
+    , reconnectAttempts(2)
+    , authMehtod(QAuthenticatorPrivate::None)
+    , proxyAuthMehtod(QAuthenticatorPrivate::None)
+#ifndef QT_NO_OPENSSL
+    , ignoreAllSslErrors(false)
+#endif
+    , pipeliningSupported(PipeliningSupportUnknown)
+    , connection(0)
+{
+    // Inlining this function in the header leads to compiler error on
+    // release-armv5, on at least timebox 9.2 and 10.1.
+}
+
 void QHttpNetworkConnectionChannel::init()
 {
@@ -125,4 +147,11 @@
 bool QHttpNetworkConnectionChannel::sendRequest()
 {
+    if (!reply) {
+        // heh, how should that happen!
+        qWarning() << "QHttpNetworkConnectionChannel::sendRequest() called without QHttpNetworkReply";
+        state = QHttpNetworkConnectionChannel::IdleState;
+        return false;
+    }
+
     switch (state) {
     case QHttpNetworkConnectionChannel::IdleState: { // write the header
@@ -135,11 +164,11 @@
         written = 0; // excluding the header
         bytesTotal = 0;
-        if (reply) {
-            reply->d_func()->clear();
-            reply->d_func()->connection = connection;
-            reply->d_func()->autoDecompress = request.d->autoDecompress;
-            reply->d_func()->pipeliningUsed = false;
-        }
-        state = QHttpNetworkConnectionChannel::WritingState;
+
+        reply->d_func()->clear();
+        reply->d_func()->connection = connection;
+        reply->d_func()->connectionChannel = this;
+        reply->d_func()->autoDecompress = request.d->autoDecompress;
+        reply->d_func()->pipeliningUsed = false;
+
         pendingEncrypt = false;
         // if the url contains authentication parameters, use the new ones
@@ -175,11 +204,13 @@
 
             bytesTotal = request.contentLength();
+
+            state = QHttpNetworkConnectionChannel::WritingState; // start writing data
+            sendRequest(); //recurse
         } else {
-            state = QHttpNetworkConnectionChannel::WaitingState;
-            sendRequest();
-            break;
-        }
-        // write the initial chunk together with the headers
-        // fall through
+            state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
+            sendRequest(); //recurse
+        }
+
+        break;
     }
     case QHttpNetworkConnectionChannel::WritingState:
@@ -191,5 +222,5 @@
                 emit reply->dataSendProgress(written, bytesTotal);
             state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
-            sendRequest();
+            sendRequest(); // recurse
             break;
         }
@@ -255,11 +286,12 @@
 
         // HTTP pipelining
-        connection->d_func()->fillPipeline(socket);
-        socket->flush();
+        //connection->d_func()->fillPipeline(socket);
+        //socket->flush();
 
         // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called
         // this is needed if the sends an reply before we have finished sending the request. In that
         // case receiveReply had been called before but ignored the server reply
-        QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
+        if (socket->bytesAvailable())
+            QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
         break;
     }
@@ -279,4 +311,19 @@
     Q_ASSERT(socket);
 
+    if (!reply) {
+        // heh, how should that happen!
+        qWarning() << "QHttpNetworkConnectionChannel::_q_receiveReply() called without QHttpNetworkReply,"
+                << socket->bytesAvailable() << "bytes on socket.";
+        close();
+        return;
+    }
+
+    // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
+    // this function is called from _q_disconnected which is called because
+    // of ~QHttpNetworkConnectionPrivate
+    if (!qobject_cast<QHttpNetworkConnection*>(connection)) {
+        return;
+    }
+
     qint64 bytes = 0;
     QAbstractSocket::SocketState socketState = socket->state();
@@ -284,19 +331,16 @@
     // connection might be closed to signal the end of data
     if (socketState == QAbstractSocket::UnconnectedState) {
-        if (!socket->bytesAvailable()) {
-            if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
+        if (socket->bytesAvailable() <= 0) {
+            if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
+                // finish this reply. this case happens when the server did not send a content length
                 reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
-                this->state = QHttpNetworkConnectionChannel::IdleState;
                 allDone();
+                return;
             } else {
-                // try to reconnect/resend before sending an error.
-                if (reconnectAttempts-- > 0) {
-                    closeAndResendCurrentRequest();
-                } else if (reply) {
-                    reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket);
-                    emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString);
-                    QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
-                }
-            }
+                handleUnexpectedEOF();
+                return;
+            }
+        } else {
+            // socket not connected but still bytes for reading.. just continue in this function
         }
     }
@@ -304,22 +348,18 @@
     // read loop for the response
     while (socket->bytesAvailable()) {
-        QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState;
+        QHttpNetworkReplyPrivate::ReplyState state = reply->d_func()->state;
         switch (state) {
-        case QHttpNetworkReplyPrivate::NothingDoneState:
+        case QHttpNetworkReplyPrivate::NothingDoneState: {
+            // only eat whitespace on the first call
+            eatWhitespace();
+            state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
+            // fallthrough
+        }
         case QHttpNetworkReplyPrivate::ReadingStatusState: {
-            eatWhitespace();
             qint64 statusBytes = reply->d_func()->readStatus(socket);
-            if (statusBytes == -1 && reconnectAttempts <= 0) {
-                // too many errors reading/receiving/parsing the status, close the socket and emit error
-                close();
-                reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::ProtocolFailure, socket);
-                emit reply->finishedWithError(QNetworkReply::ProtocolFailure, reply->d_func()->errorString);
-                QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
-                break;
-            } else if (statusBytes == -1) {
-                reconnectAttempts--;
-                reply->d_func()->clear();
-                closeAndResendCurrentRequest();
-                break;
+            if (statusBytes == -1) {
+                // connection broke while reading status. also handled if later _q_disconnected is called
+                handleUnexpectedEOF();
+                return;
             }
             bytes += statusBytes;
@@ -329,5 +369,11 @@
         case QHttpNetworkReplyPrivate::ReadingHeaderState: {
             QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
-            bytes += replyPrivate->readHeader(socket);
+            qint64 headerBytes = replyPrivate->readHeader(socket);
+            if (headerBytes == -1) {
+                // connection broke while reading headers. also handled if later _q_disconnected is called
+                handleUnexpectedEOF();
+                return;
+            }
+            bytes += headerBytes;
             if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
                 if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) {
@@ -338,4 +384,5 @@
                 }
                 if (replyPrivate->statusCode == 100) {
+                    replyPrivate->clearHttpLayerInformation();
                     replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
                     break; // ignore
@@ -345,7 +392,6 @@
                 if (!replyPrivate->expectContent()) {
                     replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState;
-                    this->state = QHttpNetworkConnectionChannel::IdleState;
                     allDone();
-                    return;
+                    break;
                 }
             }
@@ -417,10 +463,11 @@
                 }
             }
+            // still in ReadingDataState? This function will be called again by the socket's readyRead
             if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState)
                 break;
+
             // everything done, fall through
             }
       case QHttpNetworkReplyPrivate::AllDoneState:
-            this->state = QHttpNetworkConnectionChannel::IdleState;
             allDone();
             break;
@@ -428,4 +475,23 @@
             break;
         }
+    }
+}
+
+// called when unexpectedly reading a -1 or when data is expected but socket is closed
+void QHttpNetworkConnectionChannel::handleUnexpectedEOF()
+{
+    if (reconnectAttempts <= 0) {
+        // too many errors reading/receiving/parsing the status, close the socket and emit error
+        requeueCurrentlyPipelinedRequests();
+        close();
+        reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket);
+        emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString);
+        QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+    } else {
+        reconnectAttempts--;
+        reply->d_func()->clear();
+        reply->d_func()->connection = connection;
+        reply->d_func()->connectionChannel = this;
+        closeAndResendCurrentRequest();
     }
 }
@@ -557,5 +623,6 @@
     // ### at this point there should be no more data on the socket
     // close if server requested
-    if (reply->d_func()->isConnectionCloseEnabled())
+    bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled();
+    if (connectionCloseEnabled)
         close();
     // queue the finished signal, this is required since we might send new requests from
@@ -570,7 +637,18 @@
     detectPipeliningSupport();
 
+    // now the channel can be seen as free/idle again, all signal emissions for the reply have been done
+    this->state = QHttpNetworkConnectionChannel::IdleState;
+
+    // if it does not need to be sent again we can set it to 0
+    // the previous code did not do that and we had problems with accidental re-sending of a
+    // finished request.
+    // Note that this may trigger a segfault at some other point. But then we can fix the underlying
+    // problem.
+    if (!resendCurrent)
+        reply = 0;
+
     // move next from pipeline to current request
     if (!alreadyPipelinedRequests.isEmpty()) {
-        if (resendCurrent || reply->d_func()->isConnectionCloseEnabled() || socket->state() != QAbstractSocket::ConnectedState) {
+        if (resendCurrent || connectionCloseEnabled || socket->state() != QAbstractSocket::ConnectedState) {
             // move the pipelined ones back to the main queue
             requeueCurrentlyPipelinedRequests();
@@ -592,5 +670,6 @@
 
             // continue reading
-            _q_receiveReply();
+            //_q_receiveReply();
+            // this was wrong, allDone gets called from that function anyway.
         }
     } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) {
@@ -608,17 +687,19 @@
 {
     // detect HTTP Pipelining support
-    QByteArray serverHeaderField = reply->headerField("Server");
+    QByteArray serverHeaderField;
     if (
-            // check for broken servers in server reply header
-            // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining
-            (!serverHeaderField.contains("Microsoft-IIS/4."))
-            && (!serverHeaderField.contains("Microsoft-IIS/5."))
-            && (!serverHeaderField.contains("Netscape-Enterprise/3."))
             // check for HTTP/1.1
-            && (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1)
+            (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1)
             // check for not having connection close
             && (!reply->d_func()->isConnectionCloseEnabled())
             // check if it is still connected
             && (socket->state() == QAbstractSocket::ConnectedState)
+            // check for broken servers in server reply header
+            // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining
+            && (serverHeaderField = reply->headerField("Server"), !serverHeaderField.contains("Microsoft-IIS/4."))
+            && (!serverHeaderField.contains("Microsoft-IIS/5."))
+            && (!serverHeaderField.contains("Netscape-Enterprise/3."))
+            // this is adpoted from the knowledge of the Nokia 7.x browser team (DEF143319)
+            && (!serverHeaderField.contains("WebLogic"))
             ) {
         pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningProbablySupported;
@@ -635,5 +716,9 @@
     alreadyPipelinedRequests.clear();
 
-    QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+    // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
+    // this function is called from _q_disconnected which is called because
+    // of ~QHttpNetworkConnectionPrivate
+    if (qobject_cast<QHttpNetworkConnection*>(connection))
+        QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
 }
 
@@ -675,13 +760,6 @@
         if (connection->d_func()->handleAuthenticateChallenge(socket, reply, (statusCode == 407), resend)) {
             if (resend) {
-                QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
-                if (uploadByteDevice) {
-                    if (uploadByteDevice->reset()) {
-                        written = 0;
-                    } else {
-                        connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError);
-                        break;
-                    }
-                }
+                if (!resetUploadData())
+                    break;
 
                 reply->d_func()->eraseData();
@@ -713,4 +791,20 @@
 }
 
+bool QHttpNetworkConnectionChannel::resetUploadData()
+{
+    QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
+    if (!uploadByteDevice)
+        return true;
+
+    if (uploadByteDevice->reset()) {
+        written = 0;
+        return true;
+    } else {
+        connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError);
+        return false;
+    }
+}
+
+
 void  QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair)
 {
@@ -719,10 +813,9 @@
     QHttpNetworkRequest &request = pair.first;
     QHttpNetworkReply *reply = pair.second;
-    if (reply) {
-        reply->d_func()->clear();
-        reply->d_func()->connection = connection;
-        reply->d_func()->autoDecompress = request.d->autoDecompress;
-        reply->d_func()->pipeliningUsed = true;
-    }
+    reply->d_func()->clear();
+    reply->d_func()->connection = connection;
+    reply->d_func()->connectionChannel = this;
+    reply->d_func()->autoDecompress = request.d->autoDecompress;
+    reply->d_func()->pipeliningUsed = true;
 
 #ifndef QT_NO_NETWORKPROXY
@@ -788,7 +881,8 @@
     // read the available data before closing
     if (isSocketWaiting() || isSocketReading()) {
-        state = QHttpNetworkConnectionChannel::ReadingState;
-        if (reply)
+        if (reply) {
+            state = QHttpNetworkConnectionChannel::ReadingState;
             _q_receiveReply();
+        }
     } else if (state == QHttpNetworkConnectionChannel::IdleState && resendCurrent) {
         // re-sending request because the socket was in ClosingState
@@ -805,5 +899,12 @@
 {
     // improve performance since we get the request sent by the kernel ASAP
-    socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
+    //socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
+    // We have this commented out now. It did not have the effect we wanted. If we want to
+    // do this properly, Qt has to combine multiple HTTP requests into one buffer
+    // and send this to the kernel in one syscall and then the kernel immediately sends
+    // it as one TCP packet because of TCP_NODELAY.
+    // However, this code is currently not in Qt, so we rely on the kernel combining
+    // the requests into one TCP packet.
+
     // not sure yet if it helps, but it makes sense
     socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
@@ -872,5 +973,5 @@
         break;
     }
-    QPointer<QObject> that = connection;
+    QPointer<QHttpNetworkConnection> that = connection;
     QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
     if (send2Reply) {
@@ -927,5 +1028,13 @@
     // otherwise we do nothing
 }
-#endif
+
+#endif
+
+void QHttpNetworkConnectionChannel::setConnection(QHttpNetworkConnection *c)
+{
+    // Inlining this function in the header leads to compiler error on
+    // release-armv5, on at least timebox 9.2 and 10.1.
+    connection = c;
+}
 
 QT_END_NAMESPACE
Index: trunk/src/network/access/qhttpnetworkconnectionchannel_p.h
===================================================================
--- trunk/src/network/access/qhttpnetworkconnectionchannel_p.h	(revision 766)
+++ trunk/src/network/access/qhttpnetworkconnectionchannel_p.h	(revision 769)
@@ -66,4 +66,5 @@
 #include <private/qhttpnetworkreply_p.h>
 
+#include <private/qhttpnetworkconnection_p.h>
 
 #ifndef QT_NO_HTTP
@@ -81,5 +82,4 @@
 class QHttpNetworkReply;
 class QByteArray;
-class QHttpNetworkConnection;
 
 #ifndef HttpMessagePair
@@ -128,16 +128,8 @@
 
 
-    QHttpNetworkConnectionChannel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false),
-    lastStatus(0), pendingEncrypt(false), reconnectAttempts(2),
-    authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None)
-#ifndef QT_NO_OPENSSL
-    , ignoreAllSslErrors(false)
-#endif
-    , pipeliningSupported(PipeliningSupportUnknown)
-    , connection(0)
-    {}
-
-    void setConnection(QHttpNetworkConnection *c) {connection = c;}
-    QHttpNetworkConnection *connection;
+    QHttpNetworkConnectionChannel();
+    
+    void setConnection(QHttpNetworkConnection *c);
+    QPointer<QHttpNetworkConnection> connection;
 
     void init();
@@ -152,8 +144,11 @@
     void handleStatus(); // called from allDone()
 
+    bool resetUploadData(); // return true if resetting worked or there is no upload data
+
     void pipelineInto(HttpMessagePair &pair);
     void requeueCurrentlyPipelinedRequests();
     void detectPipeliningSupport();
 
+    void handleUnexpectedEOF();
     void closeAndResendCurrentRequest();
 
@@ -185,6 +180,4 @@
 };
 
-
-
 QT_END_NAMESPACE
 
Index: trunk/src/network/access/qhttpnetworkheader.cpp
===================================================================
--- trunk/src/network/access/qhttpnetworkheader.cpp	(revision 766)
+++ trunk/src/network/access/qhttpnetworkheader.cpp	(revision 769)
@@ -81,5 +81,5 @@
     QByteArray result;
     bool first = true;
-    foreach (QByteArray value, allValues) {
+    foreach (const QByteArray &value, allValues) {
         if (!first)
             result += ", ";
Index: trunk/src/network/access/qhttpnetworkreply.cpp
===================================================================
--- trunk/src/network/access/qhttpnetworkreply.cpp	(revision 766)
+++ trunk/src/network/access/qhttpnetworkreply.cpp	(revision 769)
@@ -180,4 +180,7 @@
 {
     Q_D(QHttpNetworkReply);
+    if (d->responseData.bufferCount() == 0)
+        return QByteArray();
+
     // we'll take the last buffer, so schedule another read from http
     if (d->downstreamLimited && d->responseData.bufferCount() == 1)
@@ -220,5 +223,5 @@
 }
 
-void QHttpNetworkReplyPrivate::clear()
+void QHttpNetworkReplyPrivate::clearHttpLayerInformation()
 {
     state = NothingDoneState;
@@ -230,5 +233,4 @@
     currentChunkRead = 0;
     connectionCloseEnabled = true;
-    connection = 0;
 #ifndef QT_NO_COMPRESS
     if (initInflate)
@@ -237,6 +239,14 @@
     initInflate = false;
     streamEnd = false;
+    fields.clear();
+}
+
+// TODO: Isn't everything HTTP layer related? We don't need to set connection and connectionChannel to 0 at all
+void QHttpNetworkReplyPrivate::clear()
+{
+    connection = 0;
+    connectionChannel = 0;
     autoDecompress = false;
-    fields.clear();
+    clearHttpLayerInformation();
 }
 
@@ -424,11 +434,24 @@
 qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
 {
+    if (fragment.isEmpty()) {
+        // reserve bytes for the status line. This is better than always append() which reallocs the byte array
+        fragment.reserve(32);
+    }
+
     qint64 bytes = 0;
     char c;
-
-    while (socket->bytesAvailable()) {
+    qint64 haveRead = 0;
+
+    do {
+        haveRead = socket->read(&c, 1);
+        if (haveRead == -1)
+            return -1; // unexpected EOF
+        else if (haveRead == 0)
+            break; // read more later
+
+        bytes++;
+
         // allow both CRLF & LF (only) line endings
-        if (socket->peek(&c, 1) == 1 && c == '\n') {
-            bytes += socket->read(&c, 1); // read the "n"
+        if (c == '\n') {
             // remove the CR at the end
             if (fragment.endsWith('\r')) {
@@ -443,9 +466,4 @@
             break;
         } else {
-            c = 0;
-            int haveRead = socket->read(&c, 1);
-            if (haveRead == -1)
-                return -1;
-            bytes += haveRead;
             fragment.append(c);
         }
@@ -457,6 +475,5 @@
             return -1;
         }
-
-    }
+    } while (haveRead == 1);
 
     return bytes;
@@ -501,18 +518,44 @@
 qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
 {
+    if (fragment.isEmpty()) {
+        // according to http://dev.opera.com/articles/view/mama-http-headers/ the average size of the header
+        // block is 381 bytes.
+        // reserve bytes. This is better than always append() which reallocs the byte array.
+        fragment.reserve(512);
+    }
+
     qint64 bytes = 0;
     char c = 0;
     bool allHeaders = false;
-    while (!allHeaders && socket->bytesAvailable()) {
-        if (socket->peek(&c, 1) == 1 && c == '\n') {
-            // check for possible header endings. As per HTTP rfc,
-            // the header endings will be marked by CRLFCRLF. But
-            // we will allow CRLFLF, LFLF & CRLFCRLF
-            if (fragment.endsWith("\n\r") || fragment.endsWith('\n'))
-                allHeaders = true;
-        }
-        bytes += socket->read(&c, 1);
-        fragment.append(c);
-    }
+    qint64 haveRead = 0;
+    do {
+        haveRead = socket->read(&c, 1);
+        if (haveRead == 0) {
+            // read more later
+            break;
+        } else if (haveRead == -1) {
+            // connection broke down
+            return -1;
+        } else {
+            fragment.append(c);
+            bytes++;
+
+            if (c == '\n') {
+                // check for possible header endings. As per HTTP rfc,
+                // the header endings will be marked by CRLFCRLF. But
+                // we will allow CRLFCRLF, CRLFLF, LFLF
+                if (fragment.endsWith("\r\n\r\n")
+                    || fragment.endsWith("\r\n\n")
+                    || fragment.endsWith("\n\n"))
+                    allHeaders = true;
+
+                // there is another case: We have no headers. Then the fragment equals just the line ending
+                if ((fragment.length() == 2 && fragment.endsWith("\r\n"))
+                    || (fragment.length() == 1 && fragment.endsWith("\n")))
+                    allHeaders = true;
+            }
+        }
+    } while (!allHeaders && haveRead > 0);
+
     // we received all headers now parse them
     if (allHeaders) {
@@ -776,7 +819,13 @@
 {
     Q_D(const QHttpNetworkReply);
-    if (d->connection)
-        return d->connection->d_func()->sslConfiguration(*this);
-    return QSslConfiguration();
+
+    if (!d->connectionChannel)
+        return QSslConfiguration();
+
+    QSslSocket *sslSocket = qobject_cast<QSslSocket*>(d->connectionChannel->socket);
+    if (!sslSocket)
+        return QSslConfiguration();
+
+    return sslSocket->sslConfiguration();
 }
 
Index: trunk/src/network/access/qhttpnetworkreply_p.h
===================================================================
--- trunk/src/network/access/qhttpnetworkreply_p.h	(revision 766)
+++ trunk/src/network/access/qhttpnetworkreply_p.h	(revision 769)
@@ -87,4 +87,5 @@
 
 class QHttpNetworkConnection;
+class QHttpNetworkConnectionChannel;
 class QHttpNetworkRequest;
 class QHttpNetworkConnectionPrivate;
@@ -172,4 +173,5 @@
     QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
     void clear();
+    void clearHttpLayerInformation();
 
     qint64 readReplyBodyRaw(QIODevice *in, QByteDataBuffer *out, qint64 size);
@@ -219,4 +221,5 @@
     qint64 currentChunkRead;
     QPointer<QHttpNetworkConnection> connection;
+    QPointer<QHttpNetworkConnectionChannel> connectionChannel;
     bool initInflate;
     bool streamEnd;
Index: trunk/src/network/access/qnetworkaccessbackend.cpp
===================================================================
--- trunk/src/network/access/qnetworkaccessbackend.cpp	(revision 766)
+++ trunk/src/network/access/qnetworkaccessbackend.cpp	(revision 769)
@@ -73,5 +73,5 @@
 {
     QMutexLocker locker(&factoryData()->mutex);
-    factoryData()->prepend(this);
+    factoryData()->append(this);
 }
 
Index: trunk/src/network/access/qnetworkaccesshttpbackend.cpp
===================================================================
--- trunk/src/network/access/qnetworkaccesshttpbackend.cpp	(revision 766)
+++ trunk/src/network/access/qnetworkaccesshttpbackend.cpp	(revision 769)
@@ -681,6 +681,5 @@
 
     while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0 && nextDownstreamBlockSize() > list.byteAmount()) {
-        QByteArray data = httpReply->readAny();
-        list.append(data);
+        list.append(httpReply->readAny());
     }
 
@@ -754,5 +753,5 @@
         if (!value.isEmpty()) {
             if (qstricmp(it->first.constData(), "set-cookie") == 0)
-                value += "\n";
+                value += '\n';
             else
                 value += ", ";
@@ -977,5 +976,5 @@
         // write to disk when only the date changes).
         // However, without the date we cannot calculate the age of the page
-        // anymore. Consider a proper fix of that problem for 4.6.1.
+        // anymore.
         //if (header == "date")
             //continue;
Index: trunk/src/network/access/qnetworkaccesshttpbackend_p.h
===================================================================
--- trunk/src/network/access/qnetworkaccesshttpbackend_p.h	(revision 766)
+++ trunk/src/network/access/qnetworkaccesshttpbackend_p.h	(revision 769)
@@ -95,6 +95,4 @@
     QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const;
 
-    qint64 deviceReadData(char *buffer, qint64 maxlen);
-
     // we return true since HTTP needs to send PUT/POST data again after having authenticated
     bool needsResetableUploadData() { return true; }
Index: trunk/src/network/access/qnetworkaccessmanager.cpp
===================================================================
--- trunk/src/network/access/qnetworkaccessmanager.cpp	(revision 766)
+++ trunk/src/network/access/qnetworkaccessmanager.cpp	(revision 769)
@@ -108,5 +108,6 @@
     it sends. It contains the proxy and cache configuration, as well as the
     signals related to such issues, and reply signals that can be used to
-    monitor the progress of a network operation.
+    monitor the progress of a network operation. One QNetworkAccessManager
+    should be enough for the whole Qt application.
 
     Once a QNetworkAccessManager object has been created, the application can
@@ -119,4 +120,5 @@
     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 0
 
+    QNetworkAccessManager has an asynchronous API.
     When the \tt replyFinished slot above is called, the parameter it
     takes is the QNetworkReply object containing the downloaded data
@@ -128,7 +130,22 @@
     deleteLater() function.
 
+    \note QNetworkAccessManager queues the requests it receives. The number
+    of requests executed in parallel is dependent on the protocol.
+    Currently, for the HTTP protocol on desktop platforms, 6 requests are
+    executed in parallel for one host/port combination.
+
     A more involved example, assuming the manager is already existent,
     can be:
     \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 1
+
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use this class must have the
+    \c NetworkServices platform security capability. If the client
+    process lacks this capability, operations will result in a panic.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
 
     \sa QNetworkRequest, QNetworkReply, QNetworkProxy
@@ -550,5 +567,5 @@
 /*!
     Posts a request to obtain the network headers for \a request
-    and returns a new QNetworkReply object which will contain such headers
+    and returns a new QNetworkReply object which will contain such headers.
 
     The function is named after the HTTP request associated (HEAD).
Index: trunk/src/network/access/qnetworkcookie.h
===================================================================
--- trunk/src/network/access/qnetworkcookie.h	(revision 766)
+++ trunk/src/network/access/qnetworkcookie.h	(revision 769)
@@ -115,5 +115,5 @@
 
 // ### Qt5 remove this include
-#include "qnetworkcookiejar.h"
+#include <QtNetwork/QNetworkCookieJar>
 
 Q_DECLARE_METATYPE(QNetworkCookie)
Index: trunk/src/network/access/qnetworkcookiejar.h
===================================================================
--- trunk/src/network/access/qnetworkcookiejar.h	(revision 766)
+++ trunk/src/network/access/qnetworkcookiejar.h	(revision 769)
@@ -47,5 +47,5 @@
 
 // ### Qt5 remove this include
-#include "qnetworkcookie.h"
+#include <QtNetwork/QNetworkCookie>
 
 QT_BEGIN_HEADER
Index: trunk/src/network/access/qnetworkdiskcache.cpp
===================================================================
--- trunk/src/network/access/qnetworkdiskcache.cpp	(revision 766)
+++ trunk/src/network/access/qnetworkdiskcache.cpp	(revision 769)
@@ -42,5 +42,4 @@
 //#define QNETWORKDISKCACHE_DEBUG
 
-#ifndef QT_NO_NETWORKDISKCACHE
 
 #include "qnetworkdiskcache.h"
@@ -60,4 +59,6 @@
 #define CACHE_POSTFIX QLatin1String(".cache")
 #define MAX_COMPRESSION_SIZE (1024 * 1024 * 3)
+
+#ifndef QT_NO_NETWORKDISKCACHE
 
 QT_BEGIN_NAMESPACE
Index: trunk/src/network/access/qnetworkdiskcache_p.h
===================================================================
--- trunk/src/network/access/qnetworkdiskcache_p.h	(revision 766)
+++ trunk/src/network/access/qnetworkdiskcache_p.h	(revision 769)
@@ -60,4 +60,6 @@
 #include <qtemporaryfile.h>
 
+#ifndef QT_NO_NETWORKDISKCACHE
+
 QT_BEGIN_NAMESPACE
 
@@ -120,3 +122,5 @@
 QT_END_NAMESPACE
 
+#endif // QT_NO_NETWORKDISKCACHE
+
 #endif // QNETWORKDISKCACHE_P_H
Index: trunk/src/network/access/qnetworkreplyimpl.cpp
===================================================================
--- trunk/src/network/access/qnetworkreplyimpl.cpp	(revision 766)
+++ trunk/src/network/access/qnetworkreplyimpl.cpp	(revision 769)
@@ -404,4 +404,35 @@
 }
 
+void QNetworkReplyImplPrivate::initCacheSaveDevice()
+{
+    Q_Q(QNetworkReplyImpl);
+
+    // save the meta data
+    QNetworkCacheMetaData metaData;
+    metaData.setUrl(url);
+    metaData = backend->fetchCacheMetaData(metaData);
+
+    // save the redirect request also in the cache
+    QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute);
+    if (redirectionTarget.isValid()) {
+        QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes();
+        attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget);
+        metaData.setAttributes(attributes);
+    }
+
+    cacheSaveDevice = networkCache()->prepare(metaData);
+
+    if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
+        if (cacheSaveDevice && !cacheSaveDevice->isOpen())
+            qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
+                  "class %s probably needs to be fixed",
+                  networkCache()->metaObject()->className());
+
+        networkCache()->remove(url);
+        cacheSaveDevice = 0;
+        cacheEnabled = false;
+    }
+}
+
 // we received downstream data and send this to the cache
 // and to our readBuffer (which in turn gets read by the user of QNetworkReply)
@@ -413,34 +444,10 @@
 
     if (cacheEnabled && !cacheSaveDevice) {
-        // save the meta data
-        QNetworkCacheMetaData metaData;
-        metaData.setUrl(url);
-        metaData = backend->fetchCacheMetaData(metaData);
-
-        // save the redirect request also in the cache
-        QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute);
-        if (redirectionTarget.isValid()) {
-            QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes();
-            attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget);
-            metaData.setAttributes(attributes);
-        }
-
-        cacheSaveDevice = networkCache()->prepare(metaData);
-
-        if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
-            if (cacheSaveDevice && !cacheSaveDevice->isOpen())
-                qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
-                      "class %s probably needs to be fixed",
-                      networkCache()->metaObject()->className());
-
-            networkCache()->remove(url);
-            cacheSaveDevice = 0;
-            cacheEnabled = false;
-        }
+        initCacheSaveDevice();
     }
 
     qint64 bytesWritten = 0;
     for (int i = 0; i < data.bufferCount(); i++) {
-        QByteArray item = data[i];
+        QByteArray const &item = data[i];
 
         if (cacheSaveDevice)
@@ -454,4 +461,11 @@
     bytesDownloaded += bytesWritten;
     lastBytesDownloaded = bytesDownloaded;
+
+    appendDownstreamDataSignalEmissions();
+}
+
+void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions()
+{
+    Q_Q(QNetworkReplyImpl);
 
     QPointer<QNetworkReplyImpl> qq = q;
@@ -496,4 +510,13 @@
 }
 
+void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data)
+{
+    // TODO implement
+
+    // TODO call
+
+    qFatal("QNetworkReplyImplPrivate::appendDownstreamData not implemented");
+}
+
 void QNetworkReplyImplPrivate::finished()
 {
@@ -581,6 +604,11 @@
 {
     Q_D(QNetworkReplyImpl);
+
+    // This code removes the data from the cache if it was prematurely aborted.
+    // See QNetworkReplyImplPrivate::completeCacheSave(), we disable caching there after the cache
+    // save had been properly finished. So if it is still enabled it means we got deleted/aborted.
     if (d->isCachingEnabled())
         d->networkCache()->remove(url());
+
     if (d->outgoingDataBuffer)
         delete d->outgoingDataBuffer;
Index: trunk/src/network/access/qnetworkreplyimpl_p.h
===================================================================
--- trunk/src/network/access/qnetworkreplyimpl_p.h	(revision 766)
+++ trunk/src/network/access/qnetworkreplyimpl_p.h	(revision 769)
@@ -146,6 +146,11 @@
     void emitUploadProgress(qint64 bytesSent, qint64 bytesTotal);
     qint64 nextDownstreamBlockSize() const;
+
+    void initCacheSaveDevice();
+    void appendDownstreamDataSignalEmissions();
     void appendDownstreamData(QByteDataBuffer &data);
     void appendDownstreamData(QIODevice *data);
+    void appendDownstreamData(const QByteArray &data);
+
     void finished();
     void error(QNetworkReply::NetworkError code, const QString &errorString);
Index: trunk/src/network/access/qnetworkrequest.cpp
===================================================================
--- trunk/src/network/access/qnetworkrequest.cpp	(revision 766)
+++ trunk/src/network/access/qnetworkrequest.cpp	(revision 769)
@@ -139,4 +139,6 @@
         determine if the requested redirection should be allowed,
         according to its security policies.
+        The returned URL might be relative. Use QUrl::resolved()
+        to create an absolute URL out of it.
 
     \value ConnectionEncryptedAttribute
@@ -650,5 +652,5 @@
     QList<QNetworkCookie> result;
     QList<QByteArray> cookieList = raw.split(';');
-    foreach (QByteArray cookie, cookieList) {
+    foreach (const QByteArray &cookie, cookieList) {
         QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie.trimmed());
         if (parsed.count() != 1)
Index: trunk/src/network/kernel/qauthenticator.cpp
===================================================================
--- trunk/src/network/kernel/qauthenticator.cpp	(revision 766)
+++ trunk/src/network/kernel/qauthenticator.cpp	(revision 769)
@@ -271,5 +271,5 @@
     case Ntlm:
         // #### extract from header
-        realm = QString();
+        realm.clear();
         break;
     case DigestMd5: {
@@ -282,5 +282,5 @@
     }
     default:
-        realm = QString();
+        realm.clear();
         challenge = QByteArray();
         phase = Invalid;
Index: trunk/src/network/kernel/qhostinfo.cpp
===================================================================
--- trunk/src/network/kernel/qhostinfo.cpp	(revision 766)
+++ trunk/src/network/kernel/qhostinfo.cpp	(revision 769)
@@ -45,12 +45,8 @@
 #include "QtCore/qscopedpointer.h"
 #include <qabstracteventdispatcher.h>
-#include <private/qunicodetables_p.h>
 #include <qcoreapplication.h>
 #include <qmetaobject.h>
-#include <qregexp.h>
-#include <private/qnativesocketengine_p.h>
 #include <qstringlist.h>
 #include <qthread.h>
-#include <qtimer.h>
 #include <qurl.h>
 
@@ -112,4 +108,11 @@
     To retrieve the name of the local host, use the static
     QHostInfo::localHostName() function.
+
+    \note Since Qt 4.6.1 QHostInfo is using multiple threads for DNS lookup
+    instead of one dedicated DNS thread. This improves performance,
+    but also changes the order of signal emissions when using lookupHost()
+    compared to previous versions of Qt.
+    \note Since Qt 4.6.3 QHostInfo is using a small internal 60 second DNS cache
+    for performance improvements.
 
     \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492}
@@ -182,7 +185,24 @@
     result.data()->emitResultsReady(hostInfo);
 #else
-    QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
-    QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
-    theHostInfoLookupManager()->scheduleLookup(runnable);
+    QHostInfoLookupManager *manager = theHostInfoLookupManager();
+    if (manager) {
+        // the application is still alive
+        if (manager->cache.isEnabled()) {
+            // check cache first
+            bool valid = false;
+            QHostInfo info = manager->cache.get(name, &valid);
+            if (valid) {
+                info.setLookupId(id);
+                QHostInfoResult result;
+                QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
+                result.emitResultsReady(info);
+                return id;
+            }
+        }
+        // cache is not enabled or it was not in the cache, do normal lookup
+        QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
+        QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
+        manager->scheduleLookup(runnable);
+    }
 #endif
 
@@ -419,12 +439,22 @@
     }
 
-    // check cache
-    // FIXME
-
-    // if not in cache: OS lookup
-    QHostInfo hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
-
-    // save to cache
-    // FIXME
+    QHostInfo hostInfo;
+
+    // QHostInfo::lookupHost already checks the cache. However we need to check
+    // it here too because it might have been cache saved by another QHostInfoRunnable
+    // in the meanwhile while this QHostInfoRunnable was scheduled but not running
+    if (manager->cache.isEnabled()) {
+        // check the cache first
+        bool valid = false;
+        hostInfo = manager->cache.get(toBeLookedUp, &valid);
+        if (!valid) {
+            // not in cache, we need to do the lookup and store the result in the cache
+            hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
+            manager->cache.put(toBeLookedUp, hostInfo);
+        }
+    } else {
+        // cache is not enabled, just do the lookup and continue
+        hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
+    }
 
     // check aborted again
@@ -446,4 +476,5 @@
 {
     moveToThread(QCoreApplicationPrivate::mainThread());
+    connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection);
     threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel
 }
@@ -452,4 +483,9 @@
 {
     wasDeleted = true;
+
+    // don't qDeleteAll currentLookups, the QThreadPool has ownership
+    qDeleteAll(postponedLookups);
+    qDeleteAll(scheduledLookups);
+    qDeleteAll(finishedLookups);
 }
 
@@ -512,11 +548,9 @@
             }
 
-            if (scheduled && threadPool.tryStart(scheduled)) {
+            if (scheduled && currentLookups.size() < threadPool.maxThreadCount()) {
                 // runnable now running in new thread, track this in currentLookups
+                threadPool.start(scheduled);
                 iterator.remove();
                 currentLookups.append(scheduled);
-            } else if (scheduled) {
-                // wanted to start, but could not because thread pool is busy
-                break;
             } else {
                 // was postponed, continue iterating
@@ -571,4 +605,104 @@
 }
 
+// This function returns immediatly when we had a result in the cache, else it will later emit a signal
+QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
+{
+    *valid = false;
+    *id = -1;
+
+    // check cache
+    QHostInfoLookupManager* manager = theHostInfoLookupManager();
+    if (manager && manager->cache.isEnabled()) {
+        QHostInfo info = manager->cache.get(name, valid);
+        if (*valid) {
+            return info;
+        }
+    }
+
+    // was not in cache, trigger lookup
+    *id = QHostInfo::lookupHost(name, receiver, member);
+
+    // return empty response, valid==false
+    return QHostInfo();
+}
+
+void qt_qhostinfo_clear_cache()
+{
+    QHostInfoLookupManager* manager = theHostInfoLookupManager();
+    if (manager) {
+        manager->cache.clear();
+    }
+}
+
+void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e)
+{
+    QHostInfoLookupManager* manager = theHostInfoLookupManager();
+    if (manager) {
+        manager->cache.setEnabled(e);
+    }
+}
+
+// cache for 60 seconds
+// cache 64 items
+QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(64)
+{
+#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
+    enabled = false;
+#endif
+}
+
+bool QHostInfoCache::isEnabled()
+{
+    return enabled;
+}
+
+// this function is currently only used for the auto tests
+// and not usable by public API
+void QHostInfoCache::setEnabled(bool e)
+{
+    enabled = e;
+}
+
+
+QHostInfo QHostInfoCache::get(const QString &name, bool *valid)
+{
+    QMutexLocker locker(&this->mutex);
+
+    *valid = false;
+    if (cache.contains(name)) {
+        QHostInfoCacheElement *element = cache.object(name);
+        if (element->age.elapsed() < max_age*1000)
+            *valid = true;
+        return element->info;
+
+        // FIXME idea:
+        // if too old but not expired, trigger a new lookup
+        // to freshen our cache
+    }
+
+    return QHostInfo();
+}
+
+void QHostInfoCache::put(const QString &name, const QHostInfo &info)
+{
+    // if the lookup failed, don't cache
+    if (info.error() != QHostInfo::NoError)
+        return;
+
+    QHostInfoCacheElement* element = new QHostInfoCacheElement();
+    element->info = info;
+    element->age = QTime();
+    element->age.start();
+
+    QMutexLocker locker(&this->mutex);
+    cache.insert(name, element); // cache will take ownership
+}
+
+void QHostInfoCache::clear()
+{
+    QMutexLocker locker(&this->mutex);
+    cache.clear();
+}
+
 #endif // QT_NO_THREAD
 
Index: trunk/src/network/kernel/qhostinfo_p.h
===================================================================
--- trunk/src/network/kernel/qhostinfo_p.h	(revision 766)
+++ trunk/src/network/kernel/qhostinfo_p.h	(revision 769)
@@ -69,4 +69,6 @@
 #include "QtCore/qlist.h"
 #include "QtCore/qqueue.h"
+#include <QTime>
+#include <QCache>
 #endif
 
@@ -112,4 +114,32 @@
 
 #ifndef QT_NO_THREAD
+// These functions are outside of the QHostInfo class and strictly internal.
+// Do NOT use them outside of QAbstractSocket.
+QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id);
+void Q_NETWORK_EXPORT qt_qhostinfo_clear_cache();
+void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e);
+
+class QHostInfoCache
+{
+public:
+    QHostInfoCache();
+    const int max_age; // seconds
+
+    QHostInfo get(const QString &name, bool *valid);
+    void put(const QString &name, const QHostInfo &info);
+    void clear();
+
+    bool isEnabled();
+    void setEnabled(bool e);
+private:
+    bool enabled;
+    struct QHostInfoCacheElement {
+        QHostInfo info;
+        QTime age;
+    };
+    QCache<QString,QHostInfoCacheElement> cache;
+    QMutex mutex;
+};
+
 // the following classes are used for the (normal) case: We use multiple threads to lookup DNS
 
@@ -142,4 +172,5 @@
     bool wasAborted(int id);
 
+    QHostInfoCache cache;
 protected:
     QList<QHostInfoRunnable*> currentLookups; // in progress
@@ -154,5 +185,9 @@
 
     bool wasDeleted;
+
+private slots:
+    void waitForThreadPoolDone() { threadPool.waitForDone(); }
 };
+
 #endif
 
Index: trunk/src/network/kernel/qhostinfo_unix.cpp
===================================================================
--- trunk/src/network/kernel/qhostinfo_unix.cpp	(revision 766)
+++ trunk/src/network/kernel/qhostinfo_unix.cpp	(revision 769)
@@ -45,4 +45,5 @@
 
 #include "qhostinfo_p.h"
+#include "private/qnativesocketengine_p.h"
 #include "qiodevice.h"
 #include <qbytearray.h>
Index: trunk/src/network/kernel/qhostinfo_win.cpp
===================================================================
--- trunk/src/network/kernel/qhostinfo_win.cpp	(revision 766)
+++ trunk/src/network/kernel/qhostinfo_win.cpp	(revision 769)
@@ -51,5 +51,4 @@
 #include <ws2tcpip.h>
 #include <qlibrary.h>
-#include <qtimer.h>
 #include <qmutex.h>
 #include <qurl.h>
Index: trunk/src/network/kernel/qnetworkinterface.cpp
===================================================================
--- trunk/src/network/kernel/qnetworkinterface.cpp	(revision 766)
+++ trunk/src/network/kernel/qnetworkinterface.cpp	(revision 769)
@@ -542,5 +542,5 @@
     QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces();
     QList<QNetworkInterface> result;
-    foreach (QSharedDataPointer<QNetworkInterfacePrivate> p, privs) {
+    foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) {
         QNetworkInterface item;
         item.d = p;
@@ -561,5 +561,5 @@
     QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces();
     QList<QHostAddress> result;
-    foreach (const QSharedDataPointer<QNetworkInterfacePrivate> p, privs) {
+    foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) {
         foreach (const QNetworkAddressEntry &entry, p->addressEntries)
             result += entry.ip();
Index: trunk/src/network/socket/qabstractsocket.cpp
===================================================================
--- trunk/src/network/socket/qabstractsocket.cpp	(revision 766)
+++ trunk/src/network/socket/qabstractsocket.cpp	(revision 769)
@@ -156,4 +156,7 @@
     examples for an overview of both approaches.
 
+    \note We discourage the use of the blocking functions together
+    with signals. One of the two possibilities should be used.
+
     QAbstractSocket can be used with QTextStream and QDataStream's
     stream operators (operator<<() and operator>>()). There is one
@@ -170,4 +173,8 @@
     the host lookup has succeeded.
 
+    \note Since Qt 4.6.3 QAbstractSocket may emit hostFound()
+    directly from the connectToHost() call since a DNS result could have been
+    cached.
+
     \sa connected()
 */
@@ -178,4 +185,8 @@
     This signal is emitted after connectToHost() has been called and
     a connection has been successfully established.
+
+    \note On some operating systems the connected() signal may
+    be directly emitted from the connectToHost() call for connections
+    to the localhost.
 
     \sa connectToHost(), disconnected()
@@ -352,4 +363,6 @@
 #include "qabstractsocket_p.h"
 
+#include "private/qhostinfo_p.h"
+
 #include <qabstracteventdispatcher.h>
 #include <qdatetime.h>
@@ -1367,6 +1380,18 @@
 #endif
     } else {
-        if (d->threadData->eventDispatcher)
-            d->hostLookupId = QHostInfo::lookupHost(hostName, this, SLOT(_q_startConnecting(QHostInfo)));
+        if (d->threadData->eventDispatcher) {
+            // this internal API for QHostInfo either immediatly gives us the desired
+            // QHostInfo from cache or later calls the _q_startConnecting slot.
+            bool immediateResultValid = false;
+            QHostInfo hostInfo = qt_qhostinfo_lookup(hostName,
+                                                     this,
+                                                     SLOT(_q_startConnecting(QHostInfo)),
+                                                     &immediateResultValid,
+                                                     &d->hostLookupId);
+            if (immediateResultValid) {
+                d->hostLookupId = -1;
+                d->_q_startConnecting(hostInfo);
+            }
+        }
     }
 
@@ -1683,6 +1708,9 @@
     If msecs is -1, this function will not time out.
 
-    Note: This function may wait slightly longer than \a msecs,
+    \note This function may wait slightly longer than \a msecs,
     depending on the time it takes to complete the host lookup.
+
+    \note Multiple calls to this functions do not accumulate the time.
+    If the function times out, the connecting process will be aborted.
 
     \sa connectToHost(), connected()
@@ -1723,5 +1751,5 @@
     }
     if (state() == UnconnectedState)
-        return false;
+        return false; // connect not im progress anymore!
 
     bool timedOut = true;
@@ -2355,4 +2383,8 @@
         qDebug("QAbstractSocket::disconnectFromHost() aborting immediately");
 #endif
+        if (d->state == HostLookupState) {
+            QHostInfo::abortHostLookup(d->hostLookupId);
+            d->hostLookupId = -1;
+        }
     } else {
         // Perhaps emit closing()
Index: trunk/src/network/socket/qlocalserver.cpp
===================================================================
--- trunk/src/network/socket/qlocalserver.cpp	(revision 766)
+++ trunk/src/network/socket/qlocalserver.cpp	(revision 769)
@@ -123,7 +123,7 @@
     d->pendingConnections.clear();
     d->closeServer();
-    d->serverName = QString();
-    d->fullServerName = QString();
-    d->errorString = QString();
+    d->serverName.clear();
+    d->fullServerName.clear();
+    d->errorString.clear();
     d->error = QAbstractSocket::UnknownSocketError;
 }
@@ -229,6 +229,6 @@
 
     if (!d->listen(name)) {
-        d->serverName = QString();
-        d->fullServerName = QString();
+        d->serverName.clear();
+        d->fullServerName.clear();
         return false;
     }
Index: trunk/src/network/socket/qlocalserver_win.cpp
===================================================================
--- trunk/src/network/socket/qlocalserver_win.cpp	(revision 766)
+++ trunk/src/network/socket/qlocalserver_win.cpp	(revision 769)
@@ -168,6 +168,6 @@
         } else {
             if (GetLastError() != ERROR_IO_INCOMPLETE) {
+                q->close();
                 setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
-                closeServer();
                 return;
             }
Index: trunk/src/network/socket/qlocalsocket_p.h
===================================================================
--- trunk/src/network/socket/qlocalsocket_p.h	(revision 766)
+++ trunk/src/network/socket/qlocalsocket_p.h	(revision 769)
@@ -129,8 +129,6 @@
     void _q_error(QAbstractSocket::SocketError newError);
 #elif defined(Q_OS_WIN)
-    ~QLocalSocketPrivate() {
-	CloseHandle(overlapped.hEvent);
-    }
-
+    ~QLocalSocketPrivate();
+    void destroyPipeHandles();
     void setErrorString(const QString &function);
     void _q_notified();
Index: trunk/src/network/socket/qlocalsocket_tcp.cpp
===================================================================
--- trunk/src/network/socket/qlocalsocket_tcp.cpp	(revision 766)
+++ trunk/src/network/socket/qlocalsocket_tcp.cpp	(revision 769)
@@ -103,6 +103,6 @@
     case QAbstractSocket::UnconnectedState:
         state = QLocalSocket::UnconnectedState;
-        serverName = QString();
-        fullServerName = QString();
+        serverName.clear();
+        fullServerName.clear();
         break;
     case QAbstractSocket::ConnectingState:
@@ -219,5 +219,5 @@
         return;
 
-    d->errorString = QString();
+    d->errorString.clear();
     d->state = ConnectingState;
     emit stateChanged(d->state);
@@ -334,6 +334,6 @@
     Q_D(QLocalSocket);
     d->tcpSocket->close();
-    d->serverName = QString();
-    d->fullServerName = QString();
+    d->serverName.clear();
+    d->fullServerName.clear();
     QIODevice::close();
 }
Index: trunk/src/network/socket/qlocalsocket_unix.cpp
===================================================================
--- trunk/src/network/socket/qlocalsocket_unix.cpp	(revision 766)
+++ trunk/src/network/socket/qlocalsocket_unix.cpp	(revision 769)
@@ -110,6 +110,6 @@
     case QAbstractSocket::UnconnectedState:
         state = QLocalSocket::UnconnectedState;
-        serverName = QString();
-        fullServerName = QString();
+        serverName.clear();
+        fullServerName.clear();
         break;
     case QAbstractSocket::ConnectingState:
@@ -226,5 +226,5 @@
         return;
 
-    d->errorString = QString();
+    d->errorString.clear();
     d->unixSocket.setSocketState(QAbstractSocket::ConnectingState);
     d->state = ConnectingState;
@@ -342,5 +342,5 @@
     }
     connectingSocket = -1;
-    connectingName = QString();
+    connectingName.clear();
     connectingOpenMode = 0;
 }
@@ -439,8 +439,8 @@
         ::close(d->connectingSocket);
     d->connectingSocket = -1;
-    d->connectingName = QString();
+    d->connectingName.clear();
     d->connectingOpenMode = 0;
-    d->serverName = QString();
-    d->fullServerName = QString();
+    d->serverName.clear();
+    d->fullServerName.clear();
     QIODevice::close();
 }
Index: trunk/src/network/socket/qlocalsocket_win.cpp
===================================================================
--- trunk/src/network/socket/qlocalsocket_win.cpp	(revision 766)
+++ trunk/src/network/socket/qlocalsocket_win.cpp	(revision 769)
@@ -40,5 +40,4 @@
 ****************************************************************************/
 
-#include "qlocalsocket.h"
 #include "qlocalsocket_p.h"
 
@@ -109,4 +108,18 @@
        state(QLocalSocket::UnconnectedState)
 {
+}
+
+QLocalSocketPrivate::~QLocalSocketPrivate()
+{
+    destroyPipeHandles();
+    CloseHandle(overlapped.hEvent);
+}
+
+void QLocalSocketPrivate::destroyPipeHandles()
+{
+    if (handle != INVALID_HANDLE_VALUE) {
+        DisconnectNamedPipe(handle);
+        CloseHandle(handle);
+    }
 }
 
@@ -389,6 +402,5 @@
     d->pendingReadyRead = false;
     d->pipeClosed = false;
-    DisconnectNamedPipe(d->handle);
-    CloseHandle(d->handle);
+    d->destroyPipeHandles();
     d->handle = INVALID_HANDLE_VALUE;
     ResetEvent(d->overlapped.hEvent);
@@ -413,4 +425,13 @@
 {
     Q_D(QLocalSocket);
+
+    // Are we still connected?
+    if (!isValid()) {
+        // If we have unwritten data, the pipeWriter is still present.
+        // It must be destroyed before close() to prevent an infinite loop.
+        delete d->pipeWriter;
+        d->pipeWriter = 0;
+    }
+
     flush();
     if (d->pipeWriter && d->pipeWriter->bytesToWrite() != 0) {
@@ -525,5 +546,8 @@
 {
     Q_D(const QLocalSocket);
-    return (d->handle != INVALID_HANDLE_VALUE);
+    if (d->handle == INVALID_HANDLE_VALUE)
+        return false;
+
+    return PeekNamedPipe(d->handle, NULL, 0, NULL, NULL, NULL);
 }
 
Index: trunk/src/network/socket/qnativesocketengine.cpp
===================================================================
--- trunk/src/network/socket/qnativesocketengine.cpp	(revision 766)
+++ trunk/src/network/socket/qnativesocketengine.cpp	(revision 769)
@@ -780,6 +780,9 @@
         return -1;
     } else if (readBytes == -1) {
-        d->setError(QAbstractSocket::NetworkError,
-                    QNativeSocketEnginePrivate::ReadErrorString);
+        if (!d->hasSetSocketError) {
+            d->hasSetSocketError = true;
+            d->socketError = QAbstractSocket::NetworkError;
+            d->socketErrorString = qt_error_string();
+        }
         close();
         return -1;
Index: trunk/src/network/socket/qnativesocketengine_unix.cpp
===================================================================
--- trunk/src/network/socket/qnativesocketengine_unix.cpp	(revision 766)
+++ trunk/src/network/socket/qnativesocketengine_unix.cpp	(revision 769)
@@ -602,8 +602,13 @@
     // well be 0, so we can't check recvfrom's return value.
     ssize_t readBytes;
+#ifdef Q_OS_SYMBIAN
+    char c;
+    readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize);
+#else
     do {
         char c;
         readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize);
     } while (readBytes == -1 && errno == EINTR);
+#endif
 
     // If there's no error, or if our buffer was too small, there must be a
@@ -662,4 +667,9 @@
 
     ssize_t recvFromResult = 0;
+#ifdef Q_OS_SYMBIAN
+    char c;
+    recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1,
+                                0, &aa.a, &sz);
+#else
     do {
         char c;
@@ -667,4 +677,5 @@
                                     0, &aa.a, &sz);
     } while (recvFromResult == -1 && errno == EINTR);
+#endif
 
     if (recvFromResult == -1) {
@@ -833,15 +844,11 @@
     qt_ignore_sigpipe();
 
-    // loop while ::write() returns -1 and errno == EINTR, in case
-    // of an interrupting signal.
     ssize_t writtenBytes;
-    do {
-#ifdef Q_OS_SYMBIAN
-	    writtenBytes = ::write(socketDescriptor, data, len);
-#else
-        writtenBytes = qt_safe_write(socketDescriptor, data, len);
-#endif
-        // writtenBytes = QT_WRITE(socketDescriptor, data, len); ### TODO S60: Should this line be removed or the one above it?
-    } while (writtenBytes < 0 && errno == EINTR);
+#ifdef Q_OS_SYMBIAN
+    // Symbian does not support signals natively and Open C returns EINTR when moving to offline
+    writtenBytes = ::write(socketDescriptor, data, len);
+#else
+    writtenBytes = qt_safe_write(socketDescriptor, data, len);
+#endif
 
     if (writtenBytes < 0) {
@@ -883,11 +890,9 @@
 
     ssize_t r = 0;
-    do {
-#ifdef Q_OS_SYMBIAN
-        r = ::read(socketDescriptor, data, maxSize);
-#else
-        r = qt_safe_read(socketDescriptor, data, maxSize);
-#endif
-    } while (r == -1 && errno == EINTR);
+#ifdef Q_OS_SYMBIAN
+    r = ::read(socketDescriptor, data, maxSize);
+#else
+    r = qt_safe_read(socketDescriptor, data, maxSize);
+#endif
 
     if (r < 0) {
@@ -904,5 +909,5 @@
         case EINVAL:
         case EIO:
-            setError(QAbstractSocket::NetworkError, ReadErrorString);
+            //error string is now set in read(), not here in nativeRead()
             break;
 #ifdef Q_OS_SYMBIAN
Index: trunk/src/network/socket/qnativesocketengine_win.cpp
===================================================================
--- trunk/src/network/socket/qnativesocketengine_win.cpp	(revision 766)
+++ trunk/src/network/socket/qnativesocketengine_win.cpp	(revision 769)
@@ -1069,5 +1069,5 @@
         case WSAEBADF:
         case WSAEINVAL:
-            setError(QAbstractSocket::NetworkError, ReadErrorString);
+            //error string is now set in read(), not here in nativeRead()
             break;
         case WSAECONNRESET:
Index: trunk/src/network/socket/qtcpserver.cpp
===================================================================
--- trunk/src/network/socket/qtcpserver.cpp	(revision 766)
+++ trunk/src/network/socket/qtcpserver.cpp	(revision 769)
@@ -79,4 +79,14 @@
     use waitForNewConnection(), which blocks until either a
     connection is available or a timeout expires.
+
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use this class must have the
+    \c NetworkServices platform security capability. If the client
+    process lacks this capability, it will lead to a panic.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
 
     \sa QTcpSocket, {Fortune Server Example}, {Threaded Fortune Server Example},
@@ -514,4 +524,8 @@
     connections.
 
+    \note The returned QTcpSocket object cannot be used from another
+    thread. If you want to use an incoming connection from another thread,
+    you need to override incomingConnection().
+
     \sa hasPendingConnections()
 */
@@ -543,4 +557,9 @@
     may not be usable with native socket functions, and should only be
     used with QTcpSocket::setSocketDescriptor().
+
+    \note If you want to handle an incoming connection as a new QTcpSocket
+    object in another thread you have to pass the socketDescriptor
+    to the other thread and create the QTcpSocket object there and
+    use its setSocketDescriptor() method.
 
     \sa newConnection(), nextPendingConnection()
Index: trunk/src/network/socket/qtcpsocket.cpp
===================================================================
--- trunk/src/network/socket/qtcpsocket.cpp	(revision 766)
+++ trunk/src/network/socket/qtcpsocket.cpp	(revision 769)
@@ -61,4 +61,14 @@
     \bold{Note:} TCP sockets cannot be opened in QIODevice::Unbuffered mode.
 
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use this class must have the
+    \c NetworkServices platform security capability. If the client
+    process lacks this capability, it will result in a panic.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
+
     \sa QTcpServer, QUdpSocket, QFtp, QNetworkAccessManager,
     {Fortune Server Example}, {Fortune Client Example},
Index: trunk/src/network/socket/qudpsocket.cpp
===================================================================
--- trunk/src/network/socket/qudpsocket.cpp	(revision 766)
+++ trunk/src/network/socket/qudpsocket.cpp	(revision 769)
@@ -86,4 +86,14 @@
     \l{network/broadcastreceiver}{Broadcast Receiver} examples
     illustrate how to use QUdpSocket in applications.
+
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use this class must have the
+    \c NetworkServices platform security capability. If the client
+    process lacks this capability, operations will result in a panic.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
 
     \sa QTcpSocket
Index: trunk/src/network/ssl/qsslcertificate.cpp
===================================================================
--- trunk/src/network/ssl/qsslcertificate.cpp	(revision 766)
+++ trunk/src/network/ssl/qsslcertificate.cpp	(revision 769)
@@ -635,9 +635,9 @@
     for (int i = 0; i <= array.size() - 64; i += 64) {
         tmp += QByteArray::fromRawData(array.data() + i, 64);
-        tmp += "\n";
+        tmp += '\n';
     }
     if (int remainder = array.size() % 64) {
         tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder);
-        tmp += "\n";
+        tmp += '\n';
     }
 
Index: trunk/src/network/ssl/qsslkey.cpp
===================================================================
--- trunk/src/network/ssl/qsslkey.cpp	(revision 766)
+++ trunk/src/network/ssl/qsslkey.cpp	(revision 769)
@@ -120,7 +120,5 @@
         return;
 
-    void *phrase = passPhrase.isEmpty()
-        ? (void *)0
-        : (void *)passPhrase.constData();
+    void *phrase = (void *)passPhrase.constData();
 
     if (algorithm == QSsl::Rsa) {
Index: trunk/src/network/ssl/qsslsocket.cpp
===================================================================
--- trunk/src/network/ssl/qsslsocket.cpp	(revision 766)
+++ trunk/src/network/ssl/qsslsocket.cpp	(revision 769)
@@ -157,4 +157,14 @@
     will get emitted as soon as data has been written to the TCP socket.
 
+    \section1 Symbian Platform Security Requirements
+
+    On Symbian, processes which use this class must have the
+    \c NetworkServices platform security capability. If the client
+    process lacks this capability, operations will fail.
+
+    Platform security capabilities are added via the
+    \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
+    qmake variable.
+
     \sa QSslCertificate, QSslCipher, QSslError
 */
@@ -1110,5 +1120,5 @@
     Q_D(QSslSocket);
     d->configuration.ciphers.clear();
-    foreach (QString cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) {
+    foreach (const QString &cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) {
         for (int i = 0; i < 3; ++i) {
             // ### Crude
Index: trunk/src/network/ssl/qsslsocket_openssl.cpp
===================================================================
--- trunk/src/network/ssl/qsslsocket_openssl.cpp	(revision 766)
+++ trunk/src/network/ssl/qsslsocket_openssl.cpp	(revision 769)
@@ -819,5 +819,5 @@
             if (!regexp.exactMatch(peerName)) {
                 bool matched = false;
-                foreach (QString altName, configuration.peerCertificate
+                foreach (const QString &altName, configuration.peerCertificate
                          .alternateSubjectNames().values(QSsl::DnsEntry)) {
                     regexp.setPattern(altName);
Index: trunk/src/network/ssl/qsslsocket_openssl_symbols.cpp
===================================================================
--- trunk/src/network/ssl/qsslsocket_openssl_symbols.cpp	(revision 766)
+++ trunk/src/network/ssl/qsslsocket_openssl_symbols.cpp	(revision 769)
@@ -743,5 +743,5 @@
 bool q_resolveOpenSslSymbols()
 {
-#ifdef QT_NO_SSL
+#ifdef QT_NO_OPENSSL
     return false;
 #endif
Index: trunk/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
===================================================================
--- trunk/src/opengl/gl2paintengineex/qglengineshadermanager.cpp	(revision 766)
+++ trunk/src/opengl/gl2paintengineex/qglengineshadermanager.cpp	(revision 769)
@@ -266,8 +266,10 @@
     do {
         QByteArray source;
+        // Insert the custom stage before the srcPixel shader to work around an ATI driver bug
+        // where you cannot forward declare a function that takes a sampler as argument.
+        if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
+            source.append(prog.customStageSource);
         source.append(qShaderSnippets[prog.mainFragShader]);
         source.append(qShaderSnippets[prog.srcPixelFragShader]);
-        if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
-            source.append(prog.customStageSource);
         if (prog.compositionFragShader)
             source.append(qShaderSnippets[prog.compositionFragShader]);
@@ -766,6 +768,6 @@
     QGLContextPrivate* ctx_d = ctx->d_func();
     ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
-    ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg->useTextureCoords);
-    ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg->useOpacityAttribute);
+    ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg && currentShaderProg->useTextureCoords);
+    ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg && currentShaderProg->useOpacityAttribute);
 
     shaderProgNeedsChanging = false;
Index: trunk/src/opengl/gl2paintengineex/qglengineshadersource_p.h
===================================================================
--- trunk/src/opengl/gl2paintengineex/qglengineshadersource_p.h	(revision 766)
+++ trunk/src/opengl/gl2paintengineex/qglengineshadersource_p.h	(revision 769)
@@ -332,12 +332,16 @@
     uniform   lowp    sampler2D imageTexture; \n\
     lowp vec4 srcPixel() \n\
-    { \n\
-        return texture2D(imageTexture, textureCoords); \n\
-    }\n";
+    { \n"
+#ifdef QT_OPENGL_ES_2
+        // work-around for driver bug
+        "return 1.0 * texture2D(imageTexture, textureCoords); \n"
+#else
+        "return texture2D(imageTexture, textureCoords); \n"
+#endif
+    "}\n";
 
 static const char* const qglslCustomSrcFragmentShader = "\n\
     varying   highp   vec2      textureCoords; \n\
     uniform   lowp    sampler2D imageTexture; \n\
-    lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \n\
     lowp vec4 srcPixel() \n\
     { \n\
Index: trunk/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
===================================================================
--- trunk/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp	(revision 766)
+++ trunk/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp	(revision 769)
@@ -90,4 +90,7 @@
 
 //#define QT_GL_NO_SCISSOR_TEST
+#if defined(Q_WS_WIN)
+extern Q_GUI_EXPORT bool qt_cleartype_enabled;
+#endif
 
 extern QImage qt_imageForBrush(int brushStyle, bool invert);
@@ -182,5 +185,5 @@
 
         glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
-        ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, true, QGLContext::InternalBindOption);
+        ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
         updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
     }
@@ -1232,12 +1235,12 @@
                                             : d->glyphCacheType;
 
-    if (txtype > QTransform::TxTranslate)
-        glyphType = QFontEngineGlyphCache::Raster_A8;
-
-    if (glyphType == QFontEngineGlyphCache::Raster_RGBMask
-        && state()->composition_mode != QPainter::CompositionMode_Source
-        && state()->composition_mode != QPainter::CompositionMode_SourceOver)
-    {
-        drawCached = false;
+
+    if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
+        if (d->device->alphaRequested() || txtype > QTransform::TxTranslate
+            || (state()->composition_mode != QPainter::CompositionMode_Source
+            && state()->composition_mode != QPainter::CompositionMode_SourceOver))
+        {
+            glyphType = QFontEngineGlyphCache::Raster_A8;
+        }
     }
 
@@ -1556,5 +1559,4 @@
 #if !defined(QT_OPENGL_ES_2)
 #if defined(Q_WS_WIN)
-    extern Q_GUI_EXPORT bool qt_cleartype_enabled;
     if (qt_cleartype_enabled)
 #endif
@@ -1596,4 +1598,5 @@
     delete d->shaderManager;
     d->shaderManager = 0;
+    d->currentBrush = QBrush();
 
 #ifdef QT_OPENGL_CACHE_AS_VBOS
Index: trunk/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
===================================================================
--- trunk/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp	(revision 766)
+++ trunk/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp	(revision 769)
@@ -42,4 +42,6 @@
 #include "qtextureglyphcache_gl_p.h"
 #include "qpaintengineex_opengl2_p.h"
+
+QT_BEGIN_NAMESPACE
 
 #ifdef Q_WS_WIN
@@ -244,2 +246,4 @@
 #endif
 }
+
+QT_END_NAMESPACE
Index: trunk/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
===================================================================
--- trunk/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp	(revision 766)
+++ trunk/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp	(revision 769)
@@ -145,9 +145,15 @@
 
     const qreal *endPts = pts + (count<<1);
-    const qreal *startPts;
+    const qreal *startPts = 0;
 
     Qt::PenCapStyle cap = m_cap_style;
 
     if (!types) {
+        // skip duplicate points
+        while((pts + 2) < endPts && pts[0] == pts[2] && pts[1] == pts[3])
+            pts += 2;
+        if ((pts + 2) == endPts)
+            return;
+
         startPts = pts;
 
@@ -162,6 +168,8 @@
         pts += 2;
         while (pts < endPts) {
-            join(pts);
-            lineTo(pts);
+            if (m_cx != pts[0] || m_cy != pts[1]) {
+                join(pts);
+                lineTo(pts);
+            }
             pts += 2;
         }
@@ -170,5 +178,5 @@
 
     } else {
-        bool endsAtStart;
+        bool endsAtStart = false;
         while (pts < endPts) {
             switch (*types) {
Index: trunk/src/opengl/qgl.cpp
===================================================================
--- trunk/src/opengl/qgl.cpp	(revision 766)
+++ trunk/src/opengl/qgl.cpp	(revision 769)
@@ -103,4 +103,8 @@
 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
+#endif
+
+#ifdef Q_WS_X11
+extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
 #endif
 
@@ -1531,5 +1535,12 @@
             for (int x=0; x < w; ++x) {
                 const uint pixel = *q;
-                *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
+                if (alpha_format && include_alpha) {
+                    *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff)
+                         | (pixel & 0xff00ff00);
+                } else {
+                    *q = 0xff000000 | ((pixel << 16) & 0xff0000)
+                         | ((pixel >> 16) & 0xff) | (pixel & 0x00ff00);
+                }
+
                 q++;
             }
@@ -1542,5 +1553,6 @@
 QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
 {
-    QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
+    QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32
+                                                     : QImage::Format_RGB32);
     int w = size.width();
     int h = size.height();
@@ -1591,7 +1603,7 @@
     qt_gl_texture_cache = this;
 
-    QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTextures);
+    QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
     QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
-    QImagePixmapCleanupHooks::instance()->addImageHook(imageCleanupHook);
+    QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
 }
 
@@ -1600,7 +1612,7 @@
     qt_gl_texture_cache = 0;
 
-    QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTextures);
+    QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
     QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
-    QImagePixmapCleanupHooks::instance()->removeImageHook(imageCleanupHook);
+    QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
 }
 
@@ -1658,24 +1670,17 @@
   is deref'ed
 */
-void QGLTextureCache::imageCleanupHook(qint64 cacheKey)
-{
-    // ### remove when the GL texture cache becomes thread-safe
-    if (qApp->thread() != QThread::currentThread())
-        return;
-    QGLTexture *texture = instance()->getTexture(cacheKey);
-    if (texture && texture->options & QGLContext::MemoryManagedBindOption)
-        instance()->remove(cacheKey);
-}
-
-
-void QGLTextureCache::cleanupTextures(QPixmapData* pmd)
+void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
 {
     // ### remove when the GL texture cache becomes thread-safe
     if (qApp->thread() == QThread::currentThread()) {
-        const qint64 cacheKey = pmd->cacheKey();
-        QGLTexture *texture = instance()->getTexture(cacheKey);
-        if (texture && texture->options & QGLContext::MemoryManagedBindOption)
-            instance()->remove(cacheKey);
-    }
+        instance()->remove(cacheKey);
+        Q_ASSERT(instance()->getTexture(cacheKey) == 0);
+    }
+}
+
+
+void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd)
+{
+    cleanupTexturesForCacheKey(pmd->cacheKey());
 }
 
@@ -1683,6 +1688,5 @@
 {
     // Remove any bound textures first:
-    cleanupTextures(pmd);
-    Q_ASSERT(instance()->getTexture(pmd->cacheKey()) == 0);
+    cleanupTexturesForPixampData(pmd);
 
 #if defined(Q_WS_X11)
@@ -2085,6 +2089,7 @@
     Q_ASSERT(texture);
 
-    if (texture->id > 0)
-        QImagePixmapCleanupHooks::enableCleanupHooks(image);
+    // Enable the cleanup hooks for this image so that the texture cache entry is removed when the
+    // image gets deleted:
+    QImagePixmapCleanupHooks::enableCleanupHooks(image);
 
     return texture;
@@ -2140,4 +2145,5 @@
 
     QImage img = image;
+
     if (!(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures)
         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
@@ -2308,4 +2314,5 @@
     QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
     QGLTextureCache::instance()->insert(q, key, texture, cost);
+
     return texture;
 }
@@ -2352,5 +2359,8 @@
 #if defined(Q_WS_X11)
     // Try to use texture_from_pixmap
-    if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) {
+    const QX11Info *xinfo = qt_x11Info(paintDevice);
+    if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
+        && xinfo && xinfo->screen() == pixmap.x11Info().screen())
+    {
         texture = bindTextureFromNativePixmap(pd, key, options);
         if (texture) {
@@ -2421,5 +2431,5 @@
 
     Q_D(QGLContext);
-    QGLTexture *texture = d->bindTexture(image, target, format, false, DefaultBindOption);
+    QGLTexture *texture = d->bindTexture(image, target, format, DefaultBindOption);
     return texture->id;
 }
@@ -2561,9 +2571,11 @@
         GLuint texture = dds_cache->value(ddsKeys.at(i));
         if (id == texture) {
-            glDeleteTextures(1, &texture);
             dds_cache->remove(ddsKeys.at(i));
-            return;
+            break;
         }
     }
+
+    // Finally, actually delete the texture ID
+    glDeleteTextures(1, &id);
 }
 
@@ -4416,6 +4428,15 @@
 
     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
+
+    QPaintEngine *engine = paintEngine();
+    if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+        qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
+                 " active on the same device is not allowed.");
+        return;
+    }
+
+    // this changes what paintEngine() returns
     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
-    QPaintEngine *engine = paintEngine();
+    engine = paintEngine();
     QPainter *p;
     bool reuse_painter = false;
@@ -4510,6 +4531,15 @@
 
     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
+    QPaintEngine *engine = paintEngine();
+
+    if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+        qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
+                 " active on the same device is not allowed.");
+        return;
+    }
+
+    // this changes what paintEngine() returns
     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
-    QPaintEngine *engine = paintEngine();
+    engine = paintEngine();
     QPainter *p;
     bool reuse_painter = false;
@@ -5430,5 +5460,5 @@
     quint32 width = pvrHeader->width;
     quint32 height = pvrHeader->height;
-    while (bufferSize > 0 && level < pvrHeader->mipMapCount) {
+    while (bufferSize > 0 && level <= pvrHeader->mipMapCount) {
         quint32 size =
             (qMax(width, minWidth) * qMax(height, minHeight) *
Index: trunk/src/opengl/qgl_mac.mm
===================================================================
--- trunk/src/opengl/qgl_mac.mm	(revision 766)
+++ trunk/src/opengl/qgl_mac.mm	(revision 769)
@@ -952,6 +952,4 @@
         current = current->parentWidget();
     }
-
-    isGLWidget = 1;
 }
 
Index: trunk/src/opengl/qgl_p.h
===================================================================
--- trunk/src/opengl/qgl_p.h	(revision 766)
+++ trunk/src/opengl/qgl_p.h	(revision 769)
@@ -81,11 +81,17 @@
 #endif //QT_OPENGL_ES_1_CL
 
-#ifdef QT_OPENGL_ES
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
 QT_BEGIN_INCLUDE_NAMESPACE
+
 #if defined(QT_OPENGL_ES_2)
-#include <EGL/egl.h>
+#   include <GLES2/gl2.h>
+#endif
+
+#if defined(QT_GLES_EGL)
+#   include <GLES/egl.h>
 #else
-#include <GLES/egl.h>
-#endif
+#   include <EGL/egl.h>
+#endif
+
 QT_END_INCLUDE_NAMESPACE
 #endif
@@ -180,5 +186,7 @@
                        , eglSurfaceWindowId(0)
 #endif
-        {}
+    {
+        isGLWidget = 1;
+    }
 
     ~QGLWidgetPrivate() {}
@@ -539,6 +547,6 @@
     static QGLTextureCache *instance();
     static void deleteIfEmpty();
-    static void imageCleanupHook(qint64 cacheKey);
-    static void cleanupTextures(QPixmapData* pixmap);
+    static void cleanupTexturesForCacheKey(qint64 cacheKey);
+    static void cleanupTexturesForPixampData(QPixmapData* pixmap);
     static void cleanupBeforePixmapDestruction(QPixmapData* pixmap);
 
@@ -571,5 +579,5 @@
 
 // One resource per group of shared contexts.
-class Q_AUTOTEST_EXPORT QGLContextResource
+class Q_OPENGL_EXPORT QGLContextResource
 {
 public:
Index: trunk/src/opengl/qgl_qws.cpp
===================================================================
--- trunk/src/opengl/qgl_qws.cpp	(revision 766)
+++ trunk/src/opengl/qgl_qws.cpp	(revision 769)
@@ -199,9 +199,4 @@
     d->eglContext = new QEglContext();
     d->eglContext->setApi(QEgl::OpenGL);
-    if (!d->eglContext->openDisplay(device())) {
-        delete d->eglContext;
-        d->eglContext = 0;
-        return false;
-    }
 
     // Construct the configuration we need for this surface.
Index: trunk/src/opengl/qgl_wince.cpp
===================================================================
--- trunk/src/opengl/qgl_wince.cpp	(revision 766)
+++ trunk/src/opengl/qgl_wince.cpp	(revision 769)
@@ -156,9 +156,4 @@
     d->eglContext = new QEglContext();
     d->eglContext->setApi(QEgl::OpenGL);
-    if (!d->eglContext->openDisplay(device())) {
-        delete d->eglContext;
-        d->eglContext = 0;
-        return false;
-    }
 
     // Construct the configuration we need for this surface.
Index: trunk/src/opengl/qgl_x11.cpp
===================================================================
--- trunk/src/opengl/qgl_x11.cpp	(revision 766)
+++ trunk/src/opengl/qgl_x11.cpp	(revision 769)
@@ -1657,6 +1657,9 @@
         int screen = xinfo ? xinfo->screen() : X11->defaultScreen;
 
-        QGLExtensionMatcher extensions(glXQueryExtensionsString(display, screen));
-        if (extensions.match("GLX_EXT_texture_from_pixmap")) {
+        QGLExtensionMatcher serverExtensions(glXQueryExtensionsString(display, screen));
+        QGLExtensionMatcher clientExtensions(glXGetClientString(display, GLX_EXTENSIONS));
+        if (serverExtensions.match("GLX_EXT_texture_from_pixmap")
+            && clientExtensions.match("GLX_EXT_texture_from_pixmap"))
+        {
             glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
             glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
Index: trunk/src/opengl/qgl_x11egl.cpp
===================================================================
--- trunk/src/opengl/qgl_x11egl.cpp	(revision 766)
+++ trunk/src/opengl/qgl_x11egl.cpp	(revision 769)
@@ -191,9 +191,4 @@
         d->eglContext = new QEglContext();
         d->eglContext->setApi(QEgl::OpenGL);
-        if (!d->eglContext->openDisplay(device())) {
-            delete d->eglContext;
-            d->eglContext = 0;
-            return false;
-        }
 
         // Construct the configuration we need for this surface.
@@ -615,5 +610,5 @@
         EGLint configCount = 0;
         do {
-            eglChooseConfig(QEglContext::defaultDisplay(0), configAttribs.properties(), targetConfig, 1, &configCount);
+            eglChooseConfig(QEglContext::display(), configAttribs.properties(), targetConfig, 1, &configCount);
             if (configCount > 0) {
                 // Got one
@@ -654,5 +649,5 @@
 
     EGLSurface pixmapSurface;
-    pixmapSurface = eglCreatePixmapSurface(QEglContext::defaultDisplay(0),
+    pixmapSurface = eglCreatePixmapSurface(QEglContext::display(),
                                            pixmapConfig,
                                            (EGLNativePixmapType) pixmapData->handle(),
@@ -763,5 +758,5 @@
     if (pixmapData->gl_surface) {
         EGLBoolean success;
-        success = eglDestroySurface(QEglContext::defaultDisplay(0), (EGLSurface)pixmapData->gl_surface);
+        success = eglDestroySurface(QEglContext::display(), (EGLSurface)pixmapData->gl_surface);
         if (success == EGL_FALSE) {
             qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: "
@@ -778,5 +773,5 @@
     if (pixmapData->gl_surface) {
         EGLBoolean success;
-        success = eglReleaseTexImage(QEglContext::defaultDisplay(0),
+        success = eglReleaseTexImage(QEglContext::display(),
                                      (EGLSurface)pixmapData->gl_surface,
                                      EGL_BACK_BUFFER);
Index: trunk/src/opengl/qglframebufferobject.cpp
===================================================================
--- trunk/src/opengl/qglframebufferobject.cpp	(revision 766)
+++ trunk/src/opengl/qglframebufferobject.cpp	(revision 769)
@@ -330,4 +330,11 @@
         fboFormat.setDepth(true);
     }
+
+    GLenum format = f->format().internalTextureFormat();
+    reqAlpha = (format != GL_RGB
+#ifndef QT_OPENGL_ES
+                && format != GL_RGB5 && format != GL_RGB8
+#endif
+    );
 }
 
Index: trunk/src/opengl/qglframebufferobject_p.h
===================================================================
--- trunk/src/opengl/qglframebufferobject_p.h	(revision 766)
+++ trunk/src/opengl/qglframebufferobject_p.h	(revision 769)
@@ -112,4 +112,5 @@
     virtual QGLContext* context() const;
     virtual QGLFormat format() const {return fboFormat;}
+    virtual bool alphaRequested() const { return reqAlpha; }
 
     void setFBO(QGLFramebufferObject* f,
@@ -117,7 +118,8 @@
 
 private:
-    bool wasBound;
     QGLFramebufferObject* fbo;
     QGLFormat fboFormat;
+    bool wasBound;
+    bool reqAlpha;
 };
 
Index: trunk/src/opengl/qglpaintdevice.cpp
===================================================================
--- trunk/src/opengl/qglpaintdevice.cpp	(revision 766)
+++ trunk/src/opengl/qglpaintdevice.cpp	(revision 769)
@@ -127,4 +127,9 @@
 {
     return context()->format();
+}
+
+bool QGLPaintDevice::alphaRequested() const
+{
+    return context()->d_func()->reqFormat.alpha();
 }
 
Index: trunk/src/opengl/qglpaintdevice_p.h
===================================================================
--- trunk/src/opengl/qglpaintdevice_p.h	(revision 766)
+++ trunk/src/opengl/qglpaintdevice_p.h	(revision 769)
@@ -76,4 +76,5 @@
     virtual QGLFormat format() const;
     virtual QSize size() const = 0;
+    virtual bool alphaRequested() const;
 
     // returns the QGLPaintDevice for the given QPaintDevice
Index: trunk/src/opengl/qglpixelbuffer_egl.cpp
===================================================================
--- trunk/src/opengl/qglpixelbuffer_egl.cpp	(revision 766)
+++ trunk/src/opengl/qglpixelbuffer_egl.cpp	(revision 769)
@@ -65,11 +65,4 @@
     ctx = new QEglContext();
     ctx->setApi(QEgl::OpenGL);
-
-    // Open the EGL display.
-    if (!ctx->openDisplay(0)) {
-        delete ctx;
-        ctx = 0;
-        return false;
-    }
 
     // Find the shared context.
@@ -216,5 +209,5 @@
 {
     // See if we have at least 1 configuration that matches the default format.
-    EGLDisplay dpy = QEglContext::defaultDisplay(0);
+    EGLDisplay dpy = QEglContext::display();
     if (dpy == EGL_NO_DISPLAY)
         return false;
Index: trunk/src/opengl/qglpixelbuffer_x11.cpp
===================================================================
--- trunk/src/opengl/qglpixelbuffer_x11.cpp	(revision 766)
+++ trunk/src/opengl/qglpixelbuffer_x11.cpp	(revision 769)
@@ -182,5 +182,9 @@
     qt_format_to_attrib_list(f, attribs);
 
-    GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs);
+    int screen = X11->defaultScreen;
+    if (shareWidget)
+        screen = shareWidget->x11Info().screen();
+
+    GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs);
     if (configs && num_configs) {
         int res;
Index: trunk/src/opengl/qglpixmapfilter.cpp
===================================================================
--- trunk/src/opengl/qglpixmapfilter.cpp	(revision 766)
+++ trunk/src/opengl/qglpixmapfilter.cpp	(revision 769)
@@ -395,4 +395,5 @@
     if (!hookAdded) {
         QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed);
+        QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(pixmapDestroyed);
         hookAdded = true;
     }
@@ -591,8 +592,9 @@
         qt_blurImage(image, r * qreal(0.5), false, 1);
 
-        GLuint texture = generateBlurTexture(image.size(), GL_ALPHA);
-
-        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_ALPHA,
-                        GL_UNSIGNED_BYTE, image.bits());
+        GLuint texture;
+        glGenTextures(1, &texture);
+        glBindTexture(GL_TEXTURE_2D, texture);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, image.width(), image.height(),
+                     0, GL_ALPHA, GL_UNSIGNED_BYTE, image.bits());
 
         info = new QGLBlurTextureInfo(image, texture, r);
Index: trunk/src/opengl/qglshaderprogram.cpp
===================================================================
--- trunk/src/opengl/qglshaderprogram.cpp	(revision 766)
+++ trunk/src/opengl/qglshaderprogram.cpp	(revision 769)
@@ -970,4 +970,7 @@
     is linked will be assigned locations automatically.
 
+    When this function is called after the program has been linked,
+    the program will need to be relinked for the change to take effect.
+
     \sa attributeLocation()
 */
@@ -975,10 +978,8 @@
 {
     Q_D(QGLShaderProgram);
-    if (!d->linked) {
-        glBindAttribLocation(d->programGuard.id(), location, name);
-    } else {
-        qWarning() << "QGLShaderProgram::bindAttributeLocation(" << name
-                   << "): cannot bind after shader program is linked";
-    }
+    if (!init())
+        return;
+    glBindAttribLocation(d->programGuard.id(), location, name);
+    d->linked = false;  // Program needs to be relinked.
 }
 
@@ -991,4 +992,7 @@
     is linked will be assigned locations automatically.
 
+    When this function is called after the program has been linked,
+    the program will need to be relinked for the change to take effect.
+
     \sa attributeLocation()
 */
@@ -1005,4 +1009,7 @@
     Any attributes that have not been explicitly bound when the program
     is linked will be assigned locations automatically.
+
+    When this function is called after the program has been linked,
+    the program will need to be relinked for the change to take effect.
 
     \sa attributeLocation()
Index: trunk/src/opengl/qpaintengine_opengl.cpp
===================================================================
--- trunk/src/opengl/qpaintengine_opengl.cpp	(revision 766)
+++ trunk/src/opengl/qpaintengine_opengl.cpp	(revision 769)
@@ -1454,4 +1454,9 @@
     qt_mask_texture_cache()->maintainCache();
 
+#if defined(Q_WS_X11)
+    // clear out the references we hold for textures bound with the
+    // texture_from_pixmap extension
+    ctx->d_func()->boundPixmaps.clear();
+#endif
     return true;
 }
Index: trunk/src/opengl/qpixmapdata_gl.cpp
===================================================================
--- trunk/src/opengl/qpixmapdata_gl.cpp	(revision 766)
+++ trunk/src/opengl/qpixmapdata_gl.cpp	(revision 769)
@@ -235,4 +235,9 @@
 }
 
+bool QGLPixmapGLPaintDevice::alphaRequested() const
+{
+    return data->m_hasAlpha;
+}
+
 void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
 {
Index: trunk/src/opengl/qpixmapdata_gl_p.h
===================================================================
--- trunk/src/opengl/qpixmapdata_gl_p.h	(revision 766)
+++ trunk/src/opengl/qpixmapdata_gl_p.h	(revision 769)
@@ -89,4 +89,5 @@
     QGLContext* context() const;
     QSize size() const;
+    bool alphaRequested() const;
 
     void setPixmapData(QGLPixmapData*);
Index: trunk/src/opengl/qpixmapdata_x11gl_egl.cpp
===================================================================
--- trunk/src/opengl/qpixmapdata_x11gl_egl.cpp	(revision 766)
+++ trunk/src/opengl/qpixmapdata_x11gl_egl.cpp	(revision 769)
@@ -97,5 +97,5 @@
             EGL_NONE
         };
-        qPixmapARGBSharedEglContext = eglCreateContext(QEglContext::defaultDisplay(0),
+        qPixmapARGBSharedEglContext = eglCreateContext(QEglContext::display(),
                                                        argbConfig, 0, contextAttribs);
 
@@ -104,5 +104,5 @@
             qPixmapRGBSharedEglContext = qPixmapARGBSharedEglContext;
         } else {
-            qPixmapRGBSharedEglContext = eglCreateContext(QEglContext::defaultDisplay(0),
+            qPixmapRGBSharedEglContext = eglCreateContext(QEglContext::display(),
                                                            rgbConfig, 0, contextAttribs);
         }
@@ -115,5 +115,5 @@
             break;
 
-        haveX11Pixmaps = eglMakeCurrent(QEglContext::defaultDisplay(0),
+        haveX11Pixmaps = eglMakeCurrent(QEglContext::display(),
                                         (EGLSurface)argbPixmapData->gl_surface,
                                         (EGLSurface)argbPixmapData->gl_surface,
@@ -135,5 +135,5 @@
                 break;
 
-            haveX11Pixmaps = eglMakeCurrent(QEglContext::defaultDisplay(0),
+            haveX11Pixmaps = eglMakeCurrent(QEglContext::display(),
                                             (EGLSurface)rgbPixmapData->gl_surface,
                                             (EGLSurface)rgbPixmapData->gl_surface,
@@ -148,5 +148,5 @@
 
     if (qPixmapARGBSharedEglContext || qPixmapRGBSharedEglContext) {
-        eglMakeCurrent(QEglContext::defaultDisplay(0),
+        eglMakeCurrent(QEglContext::display(),
                        EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     }
@@ -168,10 +168,10 @@
         // Clean up the context(s) if we can't use X11GL pixmaps
         if (qPixmapARGBSharedEglContext != EGL_NO_CONTEXT)
-            eglDestroyContext(QEglContext::defaultDisplay(0), qPixmapARGBSharedEglContext);
+            eglDestroyContext(QEglContext::display(), qPixmapARGBSharedEglContext);
 
         if (qPixmapRGBSharedEglContext != qPixmapARGBSharedEglContext &&
             qPixmapRGBSharedEglContext != EGL_NO_CONTEXT)
         {
-            eglDestroyContext(QEglContext::defaultDisplay(0), qPixmapRGBSharedEglContext);
+            eglDestroyContext(QEglContext::display(), qPixmapRGBSharedEglContext);
         }
         qPixmapRGBSharedEglContext = EGL_NO_CONTEXT;
@@ -213,5 +213,4 @@
         if (ctx->d_func()->eglContext == 0)
             ctx->d_func()->eglContext = new QEglContext();
-        ctx->d_func()->eglContext->openDisplay(0); // ;-)
         ctx->d_func()->eglContext->setApi(QEgl::OpenGL);
         ctx->d_func()->eglContext->setContext(hasAlphaChannel() ? qPixmapARGBSharedEglContext
Index: trunk/src/openvg/openvg.pro
===================================================================
--- trunk/src/openvg/openvg.pro	(revision 766)
+++ trunk/src/openvg/openvg.pro	(revision 769)
@@ -34,4 +34,6 @@
 }
 
+symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING
+
 include(../qbase.pri)
 
Index: trunk/src/openvg/qpaintengine_vg.cpp
===================================================================
--- trunk/src/openvg/qpaintengine_vg.cpp	(revision 766)
+++ trunk/src/openvg/qpaintengine_vg.cpp	(revision 769)
@@ -76,6 +76,6 @@
 #if !defined(QVG_NO_DRAW_GLYPHS)
 
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_DECL_IMPORT extern int qt_defaultDpiX();
+Q_DECL_IMPORT extern int qt_defaultDpiY();
 
 class QVGPaintEnginePrivate;
@@ -121,4 +121,33 @@
 {
 public:
+    // Extra blending modes from VG_KHR_advanced_blending extension.
+    // Use the QT_VG prefix to avoid conflicts with any definitions
+    // that may come in via <VG/vgext.h>.
+    enum AdvancedBlending {
+        QT_VG_BLEND_OVERLAY_KHR       = 0x2010,
+        QT_VG_BLEND_HARDLIGHT_KHR     = 0x2011,
+        QT_VG_BLEND_SOFTLIGHT_SVG_KHR = 0x2012,
+        QT_VG_BLEND_SOFTLIGHT_KHR     = 0x2013,
+        QT_VG_BLEND_COLORDODGE_KHR    = 0x2014,
+        QT_VG_BLEND_COLORBURN_KHR     = 0x2015,
+        QT_VG_BLEND_DIFFERENCE_KHR    = 0x2016,
+        QT_VG_BLEND_SUBTRACT_KHR      = 0x2017,
+        QT_VG_BLEND_INVERT_KHR        = 0x2018,
+        QT_VG_BLEND_EXCLUSION_KHR     = 0x2019,
+        QT_VG_BLEND_LINEARDODGE_KHR   = 0x201a,
+        QT_VG_BLEND_LINEARBURN_KHR    = 0x201b,
+        QT_VG_BLEND_VIVIDLIGHT_KHR    = 0x201c,
+        QT_VG_BLEND_LINEARLIGHT_KHR   = 0x201d,
+        QT_VG_BLEND_PINLIGHT_KHR      = 0x201e,
+        QT_VG_BLEND_HARDMIX_KHR       = 0x201f,
+        QT_VG_BLEND_CLEAR_KHR         = 0x2020,
+        QT_VG_BLEND_DST_KHR           = 0x2021,
+        QT_VG_BLEND_SRC_OUT_KHR       = 0x2022,
+        QT_VG_BLEND_DST_OUT_KHR       = 0x2023,
+        QT_VG_BLEND_SRC_ATOP_KHR      = 0x2024,
+        QT_VG_BLEND_DST_ATOP_KHR      = 0x2025,
+        QT_VG_BLEND_XOR_KHR           = 0x2026
+    };
+
     QVGPaintEnginePrivate();
     ~QVGPaintEnginePrivate();
@@ -218,4 +247,6 @@
 #endif
 
+    bool hasAdvancedBlending;
+
     QScopedPointer<QPixmapFilter> convolutionFilter;
     QScopedPointer<QPixmapFilter> colorizeFilter;
@@ -370,4 +401,6 @@
     fontEngineCleaner = 0;
 #endif
+
+    hasAdvancedBlending = false;
 
     clearModes();
@@ -447,4 +480,8 @@
     vgAppendPathData(linePath, 2, segments, coords);
 #endif
+
+    const char *extensions = reinterpret_cast<const char *>(vgGetString(VG_EXTENSIONS));
+    if (extensions)
+        hasAdvancedBlending = strstr(extensions, "VG_KHR_advanced_blending") != 0;
 }
 
@@ -497,32 +534,27 @@
 }
 
-extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+Q_DECL_IMPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
 
 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
 {
-    VGfloat devh = pdev->height() - 1;
+    VGfloat devh = pdev->height();
 
     // Construct the VG transform by combining the Qt transform with
     // the following viewport transformation:
-    //        | 1  0  0   |   | 1 0  0.5 |   | 1  0     0.5      |
-    //        | 0 -1 devh | * | 0 1 -0.5 | = | 0 -1 (0.5 + devh) |
-    //        | 0  0  1   |   | 0 0   1  |   | 0  0      1       |
+    //        | 1  0  0   |
+    //        | 0 -1 devh |
+    //        | 0  0  1   |
     // The full VG transform is effectively:
     //      1. Apply the user's transformation matrix.
-    //      2. Translate by (0.5, -0.5) to correct for Qt and VG putting
-    //         the centre of the pixel at different positions.
-    //      3. Flip the co-ordinate system upside down.
+    //      2. Flip the co-ordinate system upside down.
     QTransform viewport(1.0f, 0.0f, 0.0f,
                         0.0f, -1.0f, 0.0f,
-                        0.5f, devh + 0.5f, 1.0f);
-
-    // The image transform is always the full transformation,
-    // because it can be projective.
-    imageTransform = transform * viewport;
-
-    // Determine if the transformation is projective.
-    bool projective = (imageTransform.m13() != 0.0f ||
-                       imageTransform.m23() != 0.0f ||
-                       imageTransform.m33() != 1.0f);
+                        0.0f, devh, 1.0f);
+
+    // Compute the path transform and determine if it is projective.
+    pathTransform = transform * viewport;
+    bool projective = (pathTransform.m13() != 0.0f ||
+                       pathTransform.m23() != 0.0f ||
+                       pathTransform.m33() != 1.0f);
     if (projective) {
         // The engine cannot do projective path transforms for us,
@@ -532,8 +564,10 @@
         simpleTransform = false;
     } else {
-        pathTransform = imageTransform;
         simpleTransform = true;
     }
     pathTransformSet = false;
+
+    // The image transform is always the full transformation,
+    imageTransform = transform * viewport;
 
     // Calculate the scaling factor to use for turning cosmetic pens
@@ -968,5 +1002,5 @@
 }
 
-extern QImage qt_imageForBrush(int style, bool invert);
+Q_DECL_IMPORT extern QImage qt_imageForBrush(int style, bool invert);
 
 static QImage colorizeBitmap(const QImage &image, const QColor &color)
@@ -2063,4 +2097,5 @@
         (QVGPaintEngine *engine, int width, int height)
 {
+    scissorMask = false;
     if (maskIsSet) {
         vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height);
@@ -2295,5 +2330,5 @@
     d->dirty |= QPaintEngine::DirtyCompositionMode;
 
-    VGBlendMode vgMode = VG_BLEND_SRC_OVER;
+    VGint vgMode = VG_BLEND_SRC_OVER;
 
     switch (state()->composition_mode) {
@@ -2329,9 +2364,51 @@
         break;
     default:
-        qWarning() << "QVGPaintEngine::compositionModeChanged unsupported mode" << state()->composition_mode;
-        break;  // Fall back to VG_BLEND_SRC_OVER.
-    }
-
-    d->setBlendMode(vgMode);
+        if (d->hasAdvancedBlending) {
+            switch (state()->composition_mode) {
+            case QPainter::CompositionMode_Overlay:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_OVERLAY_KHR;
+                break;
+            case QPainter::CompositionMode_ColorDodge:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_COLORDODGE_KHR;
+                break;
+            case QPainter::CompositionMode_ColorBurn:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_COLORBURN_KHR;
+                break;
+            case QPainter::CompositionMode_HardLight:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_HARDLIGHT_KHR;
+                break;
+            case QPainter::CompositionMode_SoftLight:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_SOFTLIGHT_KHR;
+                break;
+            case QPainter::CompositionMode_Difference:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_DIFFERENCE_KHR;
+                break;
+            case QPainter::CompositionMode_Exclusion:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_EXCLUSION_KHR;
+                break;
+            case QPainter::CompositionMode_SourceOut:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_SRC_OUT_KHR;
+                break;
+            case QPainter::CompositionMode_DestinationOut:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_DST_OUT_KHR;
+                break;
+            case QPainter::CompositionMode_SourceAtop:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_SRC_ATOP_KHR;
+                break;
+            case QPainter::CompositionMode_DestinationAtop:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_DST_ATOP_KHR;
+                break;
+            case QPainter::CompositionMode_Xor:
+                vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_XOR_KHR;
+                break;
+            default: break; // Fall back to VG_BLEND_SRC_OVER.
+            }
+        }
+        if (vgMode == VG_BLEND_SRC_OVER)
+            qWarning() << "QVGPaintEngine::compositionModeChanged unsupported mode" << state()->composition_mode;
+        break;
+    }
+
+    d->setBlendMode(VGBlendMode(vgMode));
 }
 
@@ -2400,5 +2477,5 @@
 
     // Check to see if we can use vgClear() for faster filling.
-    if (brush.style() == Qt::SolidPattern &&
+    if (brush.style() == Qt::SolidPattern && brush.isOpaque() &&
             clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
             clearRect(rect, brush.color())) {
@@ -2443,5 +2520,5 @@
 
     // Check to see if we can use vgClear() for faster filling.
-    if (clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
+    if (clipTransformIsSimple(d->transform) && d->opacity == 1.0f && color.alpha() == 255 &&
             clearRect(rect, color)) {
         return;
@@ -3240,8 +3317,8 @@
             }
         }
-        origin[0] = -metrics.x.toReal() + 0.5f;
-        origin[1] = -metrics.y.toReal() + 0.5f;
-        escapement[0] = metrics.xoff.toReal();
-        escapement[1] = metrics.yoff.toReal();
+        origin[0] = -metrics.x.toReal();
+        origin[1] = -metrics.y.toReal();
+        escapement[0] = 0;
+        escapement[1] = 0;
         vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
         vgDestroyImage(vgImage);    // Reduce reference count.
@@ -3259,6 +3336,6 @@
         origin[0] = 0;
         origin[1] = 0;
-        escapement[0] = metrics.xoff.toReal();
-        escapement[1] = metrics.yoff.toReal();
+        escapement[0] = 0;
+        escapement[1] = 0;
         vgSetGlyphToPath(font, glyph, vgPath, VG_FALSE, origin, escapement);
         vgDestroyPath(vgPath);      // Reduce reference count.
@@ -3285,8 +3362,6 @@
     QVarLengthArray<QFixedPoint> positions;
     QVarLengthArray<glyph_t> glyphs;
-    QTransform matrix = d->transform;
-    matrix.translate(p.x(), p.y());
-    ti.fontEngine->getGlyphPositions
-        (ti.glyphs, matrix, ti.flags, glyphs, positions);
+    QTransform matrix;
+    ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
 
     // Find the glyph cache for this font.
@@ -3322,8 +3397,16 @@
     glyphCache->cacheGlyphs(d, ti, glyphs);
 
+    // Create the array of adjustments between glyphs
+    QVarLengthArray<VGfloat> adjustments_x(glyphs.size());
+    QVarLengthArray<VGfloat> adjustments_y(glyphs.size());
+    for (int i = 1; i < glyphs.size(); ++i) {
+        adjustments_x[i-1] = (positions[i].x - positions[i-1].x).toReal();
+        adjustments_y[i-1] = (positions[i].y - positions[i-1].y).toReal();
+    }
+
     // Set the glyph drawing origin.
     VGfloat origin[2];
-    origin[0] = 0;
-    origin[1] = 0;
+    origin[0] = positions[0].x.toReal();
+    origin[1] = positions[0].y.toReal();
     vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
 
@@ -3340,5 +3423,5 @@
     d->ensureBrush(state()->pen.brush());
     vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),
-                 NULL, NULL, VG_FILL_PATH, VG_TRUE);
+                 adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE);
 #else
     // OpenGL 1.0 does not have support for VGFont and glyphs,
@@ -3645,8 +3728,8 @@
     } else {
         // Set the path transform to the default viewport transformation.
-        VGfloat devh = screenSize.height() - 1;
+        VGfloat devh = screenSize.height();
         QTransform viewport(1.0f, 0.0f, 0.0f,
                             0.0f, -1.0f, 0.0f,
-                            -0.5f, devh + 0.5f, 1.0f);
+                            0.0f, devh, 1.0f);
         d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport);
 
@@ -3684,8 +3767,8 @@
 
     // Set the image transformation and modes.
-    VGfloat devh = screenSize.height() - 1;
+    VGfloat devh = screenSize.height();
     QTransform transform(1.0f, 0.0f, 0.0f,
                          0.0f, -1.0f, 0.0f,
-                         -0.5f, devh + 0.5f, 1.0f);
+                         0.0f, devh, 1.0f);
     transform.translate(offset.x(), offset.y());
     d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
Index: trunk/src/openvg/qpixmapdata_vg.cpp
===================================================================
--- trunk/src/openvg/qpixmapdata_vg.cpp	(revision 766)
+++ trunk/src/openvg/qpixmapdata_vg.cpp	(revision 769)
@@ -46,8 +46,10 @@
 #include "qvgimagepool_p.h"
 
-#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
+#if defined(Q_OS_SYMBIAN)
 #include <private/qt_s60_p.h>
 #include <fbs.h>
-#include <graphics/sgimage.h>
+#endif
+#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
+#include <sgresource/sgimage.h>
 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
@@ -353,6 +355,6 @@
 }
 
-extern int qt_defaultDpiX();
-extern int qt_defaultDpiY();
+Q_DECL_IMPORT extern int qt_defaultDpiX();
+Q_DECL_IMPORT extern int qt_defaultDpiY();
 
 int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
@@ -465,11 +467,7 @@
 void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
 {
+    if (type == QPixmapData::SgImage && pixmap) {
 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
-    if (type == QPixmapData::SgImage && pixmap) {
         RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
-        // when "0" used as argument then
-        // default display, context are used
-        if (!context)
-            context = qt_vg_create_context(0, QInternal::Pixmap);
 
         destroyImages();
@@ -478,13 +476,14 @@
         TInt err = 0;
 
-        err = SgDriver::Open();
-        if(err != KErrNone) {
+        RSgDriver driver;
+        err = driver.Open();
+        if (err != KErrNone) {
             cleanup();
             return;
         }
 
-        if(sgImage->IsNull()) {
+        if (sgImage->IsNull()) {
             cleanup();
-            SgDriver::Close();
+            driver.Close();
             return;
         }
@@ -492,7 +491,7 @@
         TSgImageInfo sgImageInfo;
         err = sgImage->GetInfo(sgImageInfo);
-        if(err != KErrNone) {
+        if (err != KErrNone) {
             cleanup();
-            SgDriver::Close();
+            driver.Close();
             return;
         }
@@ -502,12 +501,12 @@
         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
 
-        if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
+        if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
             cleanup();
-            SgDriver::Close();
+            driver.Close();
             return;
         }
 
         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
-        EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
+        EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),
                 EGL_NO_CONTEXT,
                 EGL_NATIVE_PIXMAP_KHR,
@@ -515,15 +514,15 @@
                 (EGLint*)KEglImageAttribs);
 
-        if(eglGetError() != EGL_SUCCESS) {
+        if (eglGetError() != EGL_SUCCESS) {
             cleanup();
-            SgDriver::Close();
+            driver.Close();
             return;
         }
 
         vgImage = vgCreateEGLImageTargetKHR(eglImage);
-        if(vgGetError() != VG_NO_ERROR) {
+        if (vgGetError() != VG_NO_ERROR) {
             cleanup();
-            eglDestroyImageKHR(context->display(), eglImage);
-            SgDriver::Close();
+            eglDestroyImageKHR(QEglContext::display(), eglImage);
+            driver.Close();
             return;
         }
@@ -538,6 +537,7 @@
         setSerialNumber(++qt_vg_pixmap_serial);
         // release stuff
-        eglDestroyImageKHR(context->display(), eglImage);
-        SgDriver::Close();
+        eglDestroyImageKHR(QEglContext::display(), eglImage);
+        driver.Close();
+#endif
     } else if (type == QPixmapData::FbsBitmap) {
         CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
@@ -585,23 +585,20 @@
             delete bitmap;
     }
-#else
-    Q_UNUSED(pixmap);
-    Q_UNUSED(type);
-#endif
 }
 
 void* QVGPixmapData::toNativeType(NativeType type)
 {
+    if (type == QPixmapData::SgImage) {
 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
-    if (type == QPixmapData::SgImage) {
         toVGImage();
 
-        if(!isValid() || vgImage == VG_INVALID_HANDLE)
+        if (!isValid() || vgImage == VG_INVALID_HANDLE)
             return 0;
 
         TInt err = 0;
 
-        err = SgDriver::Open();
-        if(err != KErrNone)
+        RSgDriver driver;
+        err = driver.Open();
+        if (err != KErrNone)
             return 0;
 
@@ -609,15 +606,10 @@
         sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
         sgInfo.iSizeInPixels.SetSize(w, h);
-        sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget;
-        sgInfo.iShareable = ETrue;
-        sgInfo.iCpuAccess = ESgCpuAccessNone;
-        sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny;
-        sgInfo.iUserAttributes = NULL;
-        sgInfo.iUserAttributeCount = 0;
+        sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
 
         RSgImage *sgImage = q_check_ptr(new RSgImage());
         err = sgImage->Create(sgInfo, NULL, NULL);
-        if(err != KErrNone) {
-            SgDriver::Close();
+        if (err != KErrNone) {
+            driver.Close();
             return 0;
         }
@@ -627,26 +619,26 @@
         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
 
-        if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
-            SgDriver::Close();
+        if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
+            driver.Close();
             return 0;
         }
 
         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
-        EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
+        EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),
                 EGL_NO_CONTEXT,
                 EGL_NATIVE_PIXMAP_KHR,
                 (EGLClientBuffer)sgImage,
                 (EGLint*)KEglImageAttribs);
-        if(eglGetError() != EGL_SUCCESS) {
+        if (eglGetError() != EGL_SUCCESS) {
             sgImage->Close();
-            SgDriver::Close();
+            driver.Close();
             return 0;
         }
 
         VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
-        if(vgGetError() != VG_NO_ERROR) {
-            eglDestroyImageKHR(context->display(), eglImage);
+        if (vgGetError() != VG_NO_ERROR) {
+            eglDestroyImageKHR(QEglContext::display(), eglImage);
             sgImage->Close();
-            SgDriver::Close();
+            driver.Close();
             return 0;
         }
@@ -656,5 +648,5 @@
                 w, h, VG_FALSE);
 
-        if(vgGetError() != VG_NO_ERROR) {
+        if (vgGetError() != VG_NO_ERROR) {
             sgImage->Close();
             sgImage = 0;
@@ -662,7 +654,8 @@
         // release stuff
         vgDestroyImage(dstVgImage);
-        eglDestroyImageKHR(context->display(), eglImage);
-        SgDriver::Close();
+        eglDestroyImageKHR(QEglContext::display(), eglImage);
+        driver.Close();
         return reinterpret_cast<void*>(sgImage);
+#endif
     } else if (type == QPixmapData::FbsBitmap) {
         CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
@@ -686,8 +679,5 @@
         return reinterpret_cast<void*>(bitmap);
     }
-#else
-    Q_UNUSED(type);
     return 0;
-#endif
 }
 #endif //Q_OS_SYMBIAN
Index: trunk/src/openvg/qwindowsurface_vg.cpp
===================================================================
--- trunk/src/openvg/qwindowsurface_vg.cpp	(revision 766)
+++ trunk/src/openvg/qwindowsurface_vg.cpp	(revision 769)
@@ -58,4 +58,5 @@
     // Create the default type of EGL window surface for windows.
     d_ptr = new QVGEGLWindowSurfaceDirect(this);
+    setStaticContentsSupport(d_ptr->supportsStaticContents());
 }
 
@@ -90,5 +91,7 @@
 bool QVGWindowSurface::scroll(const QRegion &area, int dx, int dy)
 {
-    return QWindowSurface::scroll(area, dx, dy);
+    if (!d_ptr->scroll(window(), area, dx, dy))
+        return QWindowSurface::scroll(area, dx, dy);
+    return true;
 }
 
Index: trunk/src/openvg/qwindowsurface_vgegl.cpp
===================================================================
--- trunk/src/openvg/qwindowsurface_vgegl.cpp	(revision 766)
+++ trunk/src/openvg/qwindowsurface_vgegl.cpp	(revision 769)
@@ -178,5 +178,6 @@
     } else {
         QVGSharedContext *shared = sharedContext();
-        shared->firstPixmap = pd->next;
+        if (shared)
+           shared->firstPixmap = pd->next;
     }
 }
@@ -226,15 +227,11 @@
     context = new QEglContext();
     context->setApi(QEgl::OpenVG);
-    if (!context->openDisplay(device)) {
-        delete context;
-        return 0;
-    }
 
     // Set the swap interval for the display.
     QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL");
     if (!interval.isEmpty())
-        eglSwapInterval(context->display(), interval.toInt());
+        eglSwapInterval(QEglContext::display(), interval.toInt());
     else
-        eglSwapInterval(context->display(), 1);
+        eglSwapInterval(QEglContext::display(), 1);
 
 #ifdef EGL_RENDERABLE_TYPE
@@ -250,5 +247,5 @@
         EGLConfig cfg;
         if (eglChooseConfig
-                    (context->display(), properties, &cfg, 1, &matching) &&
+                    (QEglContext::display(), properties, &cfg, 1, &matching) &&
                 matching > 0) {
             // Check that the selected configuration actually supports OpenVG
@@ -257,7 +254,7 @@
             EGLint type = 0;
             eglGetConfigAttrib
-                (context->display(), cfg, EGL_CONFIG_ID, &id);
+                (QEglContext::display(), cfg, EGL_CONFIG_ID, &id);
             eglGetConfigAttrib
-                (context->display(), cfg, EGL_RENDERABLE_TYPE, &type);
+                (QEglContext::display(), cfg, EGL_RENDERABLE_TYPE, &type);
             if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) {
                 context->setConfig(cfg);
@@ -338,5 +335,5 @@
     shared->context->doneCurrent();
     if (shared->surface != EGL_NO_SURFACE) {
-        eglDestroySurface(shared->context->display(), shared->surface);
+        eglDestroySurface(QEglContext::display(), shared->surface);
         shared->surface = EGL_NO_SURFACE;
     }
@@ -416,5 +413,5 @@
         }
         shared->surface = eglCreatePbufferSurface
-            (shared->context->display(), shared->context->config(), attribs);
+            (QEglContext::display(), shared->context->config(), attribs);
     }
     return shared->surface;
@@ -559,5 +556,5 @@
             recreateBackBuffer = false;
             if (backBufferSurface != EGL_NO_SURFACE) {
-                eglDestroySurface(context->display(), backBufferSurface);
+                eglDestroySurface(QEglContext::display(), backBufferSurface);
                 backBufferSurface = EGL_NO_SURFACE;
             }
@@ -572,5 +569,5 @@
                 // Create an EGL surface for rendering into the VGImage.
                 backBufferSurface = eglCreatePbufferFromClientBuffer
-                    (context->display(), EGL_OPENVG_IMAGE,
+                    (QEglContext::display(), EGL_OPENVG_IMAGE,
                      (EGLClientBuffer)(backBuffer),
                      context->config(), NULL);
@@ -663,4 +660,5 @@
         windowSurface = context->createSurface(widget, &surfaceProps);
         isPaintingActive = false;
+        needToSwap = true;
     }
 #else
@@ -708,5 +706,5 @@
         // Did we get a direct to window rendering surface?
         EGLint buffer = 0;
-        if (eglQueryContext(context->display(), context->context(),
+        if (eglQueryContext(QEglContext::display(), context->context(),
                             EGL_RENDER_BUFFER, &buffer) &&
                 buffer == EGL_SINGLE_BUFFER) {
@@ -714,18 +712,19 @@
         }
 #endif
-#if !defined(QVG_NO_PRESERVED_SWAP)
-        // Try to force the surface back buffer to preserve its contents.
-        if (needToSwap) {
-            eglGetError();  // Clear error state first.
-            eglSurfaceAttrib(context->display(), surface,
-                             EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-            if (eglGetError() != EGL_SUCCESS) {
-                qWarning("QVG: could not enable preserved swap");
-            }
-        }
-#endif
         windowSurface = surface;
         isPaintingActive = false;
     }
+
+#if !defined(QVG_NO_PRESERVED_SWAP)
+    // Try to force the surface back buffer to preserve its contents.
+    if (needToSwap) {
+        eglGetError();  // Clear error state first.
+        eglSurfaceAttrib(QEglContext::display(), windowSurface,
+                EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+        if (eglGetError() != EGL_SUCCESS) {
+            qWarning("QVG: could not enable preserved swap");
+        }
+    }
+#endif
     return context;
 }
@@ -760,4 +759,31 @@
 }
 
+bool QVGEGLWindowSurfaceDirect::supportsStaticContents() const
+{
+#if defined(QVG_BUFFER_SCROLLING) && !defined(QVG_NO_PRESERVED_SWAP)
+    return true;
+#else
+    return QVGEGLWindowSurfacePrivate::supportsStaticContents();
+#endif
+}
+
+bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int dx, int dy)
+{
+#ifdef QVG_BUFFER_SCROLLING
+    QEglContext *context = ensureContext(widget);
+    if (context) {
+        context->makeCurrent(windowSurface);
+        QRect scrollRect = area.boundingRect();
+        int sx = scrollRect.x();
+        int sy = size.height() - scrollRect.y() - scrollRect.height();
+        vgSeti(VG_SCISSORING, VG_FALSE);
+        vgCopyPixels(sx + dx, sy - dy, sx, sy, scrollRect.width(), scrollRect.height());
+        context->lazyDoneCurrent();
+        return true;
+    }
+#endif
+    return false;
+}
+
 QT_END_NAMESPACE
 
Index: trunk/src/openvg/qwindowsurface_vgegl_p.h
===================================================================
--- trunk/src/openvg/qwindowsurface_vgegl_p.h	(revision 766)
+++ trunk/src/openvg/qwindowsurface_vgegl_p.h	(revision 769)
@@ -78,4 +78,6 @@
     virtual VGImage surfaceImage() const;
     virtual QSize surfaceSize() const = 0;
+    virtual bool supportsStaticContents() const { return false; }
+    virtual bool scroll(QWidget *, const QRegion&, int, int) { return false; }
 
 private:
@@ -129,4 +131,6 @@
     void endPaint(QWidget *widget, const QRegion& region, QImage *image);
     QSize surfaceSize() const { return size; }
+    bool supportsStaticContents() const;
+    bool scroll(QWidget *widget, const QRegion& area, int dx, int dy);
 
 protected:
Index: trunk/src/plugins/accessible/widgets/complexwidgets.cpp
===================================================================
--- trunk/src/plugins/accessible/widgets/complexwidgets.cpp	(revision 766)
+++ trunk/src/plugins/accessible/widgets/complexwidgets.cpp	(revision 769)
@@ -725,5 +725,6 @@
             m_current = start;
         } else if (m_view && m_view->model()) {
-            m_current = view->model()->index(0, 0);
+            m_current = view->rootIndex().isValid() ? 
+                        view->rootIndex().child(0,0) : view->model()->index(0, 0);
         }
     }
Index: trunk/src/plugins/audio/audio.pro
===================================================================
--- trunk/src/plugins/audio/audio.pro	(revision 766)
+++ trunk/src/plugins/audio/audio.pro	(revision 769)
@@ -1,3 +1,3 @@
 TEMPLATE = subdirs
+SUBDIRS =
 
-#SUBDIRS += ossaudio
Index: trunk/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
===================================================================
--- trunk/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp	(revision 766)
+++ trunk/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp	(revision 769)
@@ -69,9 +69,8 @@
 
     enum CompositionModeStatus {
-        PorterDuff_None = 0x00,
-        PorterDuff_SupportedBlits = 0x01,
-        PorterDuff_SupportedPrimitives = 0x02,
-        PorterDuff_SupportedOpaquePrimitives = 0x04,
-        PorterDuff_Dirty = 0x10
+        PorterDuff_None = 0x0,
+        PorterDuff_Supported = 0x1,
+        PorterDuff_PremultiplyColors = 0x2,
+        PorterDuff_AlwaysBlend = 0x4
     };
 
@@ -98,5 +97,4 @@
     static inline void unlock(QDirectFBPaintDevice *device);
 
-    inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const;
     inline bool isSimpleBrush(const QBrush &brush) const;
 
@@ -131,4 +129,5 @@
     QDirectFBPaintDevice *dfbDevice;
     uint compositionModeStatus;
+    bool isPremultiplied;
 
     bool inClip;
@@ -169,5 +168,5 @@
 #endif
 
-#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS
+#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS || defined QT_DEBUG
 #define VOID_ARG() static_cast<bool>(false)
 enum PaintOperation {
@@ -179,7 +178,87 @@
     ALL = 0xffff
 };
-#endif
-
+
+#ifdef QT_DEBUG
+static void initRasterFallbacksMasks(int *warningMask, int *disableMask)
+{
+    struct {
+        const char *name;
+        PaintOperation operation;
+    } const operations[] = {
+        { "DRAW_RECTS", DRAW_RECTS },
+        { "DRAW_LINES", DRAW_LINES },
+        { "DRAW_IMAGE", DRAW_IMAGE },
+        { "DRAW_PIXMAP", DRAW_PIXMAP },
+        { "DRAW_TILED_PIXMAP", DRAW_TILED_PIXMAP },
+        { "STROKE_PATH", STROKE_PATH },
+        { "DRAW_PATH", DRAW_PATH },
+        { "DRAW_POINTS", DRAW_POINTS },
+        { "DRAW_ELLIPSE", DRAW_ELLIPSE },
+        { "DRAW_POLYGON", DRAW_POLYGON },
+        { "DRAW_TEXT", DRAW_TEXT },
+        { "FILL_PATH", FILL_PATH },
+        { "FILL_RECT", FILL_RECT },
+        { "DRAW_COLORSPANS", DRAW_COLORSPANS },
+        { "DRAW_ROUNDED_RECT", DRAW_ROUNDED_RECT },
+        { "ALL", ALL },
+        { 0, ALL }
+    };
+
+    QStringList warning = QString::fromLatin1(qgetenv("QT_DIRECTFB_WARN_ON_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
+                                                                                                              QString::SkipEmptyParts);
+    QStringList disable = QString::fromLatin1(qgetenv("QT_DIRECTFB_DISABLE_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
+                                                                                                              QString::SkipEmptyParts);
+    *warningMask = 0;
+    *disableMask = 0;
+    if (!warning.isEmpty() || !disable.isEmpty()) {
+        for (int i=0; operations[i].name; ++i) {
+            const QString name = QString::fromLatin1(operations[i].name);
+            int idx = warning.indexOf(name);
+            if (idx != -1) {
+                *warningMask |= operations[i].operation;
+                warning.erase(warning.begin() + idx);
+            }
+            idx = disable.indexOf(name);
+            if (idx != -1) {
+                *disableMask |= operations[i].operation;
+                disable.erase(disable.begin() + idx);
+            }
+        }
+    }
+    if (!warning.isEmpty()) {
+        qWarning("QDirectFBPaintEngine QT_DIRECTFB_WARN_ON_RASTERFALLBACKS Unknown operation(s): %s",
+                 qPrintable(warning.join(QLatin1String("|"))));
+    }
+    if (!disable.isEmpty()) {
+        qWarning("QDirectFBPaintEngine QT_DIRECTFB_DISABLE_RASTERFALLBACKS Unknown operation(s): %s",
+                 qPrintable(disable.join(QLatin1String("|"))));
+    }
+
+}
+#endif
+
+static inline int rasterFallbacksMask(bool warn)
+{
 #ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
+    if (warn)
+        return QT_DIRECTFB_WARN_ON_RASTERFALLBACKS;
+#endif
+#ifdef QT_DIRECTFB_DISABLE_RASTERFALLBACKS
+    if (!warn)
+        return QT_DIRECTFB_DISABLE_RASTERFALLBACKS;
+#endif
+#ifndef QT_DEBUG
+    return 0;
+#else
+    static int warnMask = -1;
+    static int disableMask = -1;
+    if (warnMask == -1)
+        initRasterFallbacksMasks(&warnMask, &disableMask);
+    return warn ? warnMask : disableMask;
+#endif
+}
+#endif
+
+#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DEBUG
 template <typename device, typename T1, typename T2, typename T3>
 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
@@ -191,23 +270,29 @@
 #endif
 
-#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS && defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS
+#if defined QT_DEBUG || (defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS && defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS)
 #define RASTERFALLBACK(op, one, two, three)                             \
-    if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS))                     \
-        rasterFallbackWarn("Disabled raster engine operation",          \
-                           __FUNCTION__, state()->painter->device(),    \
-                           d_func()->transformationType,                \
-                           d_func()->simplePen,                         \
-                           d_func()->clipType,                          \
-                           d_func()->compositionModeStatus,             \
-                           #one, one, #two, two, #three, three);        \
-    if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS))                     \
-        return;
+    {                                                                   \
+        const bool disable = op & rasterFallbacksMask(false);           \
+        if (op & rasterFallbacksMask(true))                             \
+            rasterFallbackWarn(disable                                  \
+                               ? "Disabled raster engine operation"     \
+                               : "Falling back to raster engine for",   \
+                               __FUNCTION__,                            \
+                               state()->painter->device(),              \
+                               d_func()->transformationType,            \
+                               d_func()->simplePen,                     \
+                               d_func()->clipType,                      \
+                               d_func()->compositionModeStatus,         \
+                               #one, one, #two, two, #three, three);    \
+        if (disable)                                                    \
+            return;                                                     \
+    }
 #elif defined QT_DIRECTFB_DISABLE_RASTERFALLBACKS
-#define RASTERFALLBACK(op, one, two, three)             \
-    if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS))     \
+#define RASTERFALLBACK(op, one, two, three)                             \
+    if (op & rasterFallbacksMask(false))                                \
         return;
 #elif defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
 #define RASTERFALLBACK(op, one, two, three)                             \
-    if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS))                     \
+    if (op & rasterFallbacksMask(true))                                 \
         rasterFallbackWarn("Falling back to raster engine for",         \
                            __FUNCTION__, state()->painter->device(),    \
@@ -288,4 +373,5 @@
                device->devType());
     }
+    d->isPremultiplied = QDirectFBScreen::isPremultiplied(d->dfbDevice->format());
 
     d->prepare(d->dfbDevice);
@@ -414,5 +500,5 @@
         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
         || !d->isSimpleBrush(brush)
-        || !d->testCompositionMode(&pen, &brush)) {
+        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
         d->lock();
@@ -444,5 +530,5 @@
         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
         || !d->isSimpleBrush(brush)
-        || !d->testCompositionMode(&pen, &brush)) {
+        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
         RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
         d->lock();
@@ -469,5 +555,5 @@
     if (!d->simplePen
         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
-        || !d->testCompositionMode(&pen, 0)) {
+        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
         d->lock();
@@ -489,5 +575,5 @@
     if (!d->simplePen
         || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
-        || !d->testCompositionMode(&pen, 0)) {
+        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
         RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
         d->lock();
@@ -527,5 +613,5 @@
 
 #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
-    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
+    if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
         || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
         || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
@@ -576,5 +662,5 @@
         Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
         QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
-        if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
+        if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
             || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
             || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
@@ -607,5 +693,5 @@
         d->lock();
         QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset);
-    } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
+    } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
                || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
                || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
@@ -720,11 +806,12 @@
         switch (brush.style()) {
         case Qt::SolidPattern: {
-            if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
-                || !d->testCompositionMode(0, &brush)) {
-                break;
-            }
             const QColor color = brush.color();
             if (!color.isValid())
                 return;
+
+            if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
+                || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
+                break;
+            }
             d->setDFBColor(color);
             const QRect r = state()->matrix.mapRect(rect).toRect();
@@ -733,5 +820,5 @@
 
         case Qt::TexturePattern: {
-            if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits)
+            if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
                 || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
                 || (!d->supportsStretchBlit() && state()->matrix.isScaling())) {
@@ -761,5 +848,5 @@
     if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
         || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
-        || !d->testCompositionMode(0, 0, &color)) {
+        || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
         RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
         d->lock();
@@ -805,5 +892,5 @@
       transformationType(0), opacity(255),
       clipType(ClipUnset), dfbDevice(0),
-      compositionModeStatus(0), inClip(false), q(p)
+      compositionModeStatus(0), isPremultiplied(false), inClip(false), q(p)
 {
     fb = QDirectFBScreen::instance()->dfb();
@@ -820,34 +907,4 @@
     return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
 }
-
-bool QDirectFBPaintEnginePrivate::testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color) const
-{
-    Q_ASSERT(!pen || pen->style() == Qt::NoPen || pen->style() == Qt::SolidLine);
-    Q_ASSERT(!brush || brush->style() == Qt::NoBrush || brush->style() == Qt::SolidPattern);
-    switch (compositionModeStatus & (QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives
-                                     |QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)) {
-    case QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives:
-        return true;
-    case QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives:
-        if (pen && pen->style() == Qt::SolidLine && pen->color().alpha() != 255)
-            return false;
-        if (brush) {
-            if (brush->style() == Qt::SolidPattern && brush->color().alpha() != 255) {
-                return false;
-            }
-        } else if (color && color->alpha() != 255) {
-            return false;
-        }
-        return true;
-    case QDirectFBPaintEnginePrivate::PorterDuff_None:
-        return false;
-    default:
-        // ### PorterDuff_SupportedOpaquePrimitives|PorterDuff_SupportedPrimitives can't be combined
-        break;
-    }
-    Q_ASSERT(0);
-    return false;
-}
-
 
 void QDirectFBPaintEnginePrivate::lock()
@@ -913,9 +970,9 @@
     static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0;
     if (forceRasterFallBack) {
-        compositionModeStatus = 0;
+        compositionModeStatus = PorterDuff_None;
         return;
     }
 
-    compositionModeStatus = PorterDuff_SupportedBlits;
+    compositionModeStatus = PorterDuff_Supported|PorterDuff_PremultiplyColors|PorterDuff_AlwaysBlend;
     switch (mode) {
     case QPainter::CompositionMode_Clear:
@@ -924,8 +981,10 @@
     case QPainter::CompositionMode_Source:
         surface->SetPorterDuff(surface, DSPD_SRC);
-        compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives;
+        compositionModeStatus &= ~PorterDuff_AlwaysBlend;
+        if (!isPremultiplied)
+            compositionModeStatus &= ~PorterDuff_PremultiplyColors;
         break;
     case QPainter::CompositionMode_SourceOver:
-        compositionModeStatus |= PorterDuff_SupportedPrimitives;
+        compositionModeStatus &= ~PorterDuff_AlwaysBlend;
         surface->SetPorterDuff(surface, DSPD_SRC_OVER);
         break;
@@ -935,4 +994,6 @@
     case QPainter::CompositionMode_SourceIn:
         surface->SetPorterDuff(surface, DSPD_SRC_IN);
+        if (!isPremultiplied)
+            compositionModeStatus &= ~PorterDuff_PremultiplyColors;
         break;
     case QPainter::CompositionMode_DestinationIn:
@@ -945,4 +1006,9 @@
         surface->SetPorterDuff(surface, DSPD_DST_OUT);
         break;
+#if (Q_DIRECTFB_VERSION >= 0x010209)
+    case QPainter::CompositionMode_Destination:
+        surface->SetPorterDuff(surface, DSPD_DST);
+        break;
+#endif
 #if (Q_DIRECTFB_VERSION >= 0x010000)
     case QPainter::CompositionMode_SourceAtop:
@@ -960,5 +1026,5 @@
 #endif
     default:
-        compositionModeStatus = 0;
+        compositionModeStatus = PorterDuff_None;
         break;
     }
@@ -982,7 +1048,4 @@
     surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
     surface->SetBlittingFlags(surface, blittingFlags);
-    if (compositionModeStatus & PorterDuff_Dirty) {
-        setCompositionMode(q->state()->composition_mode);
-    }
 }
 
@@ -997,10 +1060,18 @@
 {
     Q_ASSERT(surface);
+    Q_ASSERT(compositionModeStatus & PorterDuff_Supported);
     const quint8 alpha = (opacity == 255 ?
                           color.alpha() : ALPHA_MUL(color.alpha(), opacity));
-    surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha);
-    surface->SetPorterDuff(surface, DSPD_NONE);
-    surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND);
-    compositionModeStatus |= PorterDuff_Dirty;
+    QColor col;
+    if (compositionModeStatus & PorterDuff_PremultiplyColors) {
+        col = QColor(ALPHA_MUL(color.red(), alpha),
+                     ALPHA_MUL(color.green(), alpha),
+                     ALPHA_MUL(color.blue(), alpha),
+                     alpha);
+    } else {
+        col = QColor(color.red(), color.green(), color.blue(), alpha);
+    }
+    surface->SetColor(surface, col.red(), col.green(), col.blue(), col.alpha());
+    surface->SetDrawingFlags(surface, alpha == 255 && !(compositionModeStatus & PorterDuff_AlwaysBlend) ? DSDRAW_NOFX : DSDRAW_BLEND);
 }
 
@@ -1284,5 +1355,5 @@
 }
 
-#ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
+#if defined QT_DIRECTFB_WARN_ON_RASTERFALLBACKS || defined QT_DEBUG
 template <typename T> inline const T *ptr(const T &t) { return &t; }
 template <> inline const bool* ptr<bool>(const bool &) { return 0; }
Index: trunk/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
===================================================================
--- trunk/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp	(revision 766)
+++ trunk/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp	(revision 769)
@@ -175,4 +175,6 @@
                                    Qt::ImageConversionFlags flags)
 {
+    if (!QFile::exists(filename))
+        return false;
     if (flags == Qt::AutoColor) {
         if (filename.startsWith(QLatin1Char(':'))) { // resource
@@ -289,25 +291,20 @@
                                     Qt::ImageConversionFlags flags)
 {
-    if (img.depth() == 1 || img.format() == QImage::Format_RGB32) {
-        fromImage(img.convertToFormat(screen->alphaPixmapFormat()), flags);
-        return;
-    }
-
-    if (img.hasAlphaChannel()
+    if (img.depth() == 1) {
+        alpha = true;
 #ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
-        && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img))
-#endif
-        ) {
+    } else if (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img)) {
         alpha = true;
-        imageFormat = screen->alphaPixmapFormat();
-    } else {
-        alpha = false;
-        imageFormat = screen->pixelFormat();
-    }
+#else
+    } else if (img.hasAlphaChannel()) {
+        alpha = true;
+#endif
+    }
+    imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat();
     QImage image;
-    if (flags != Qt::AutoColor) {
+    if ((flags & ~Qt::NoOpaqueDetection) != Qt::AutoColor) {
         image = img.convertToFormat(imageFormat, flags);
         flags = Qt::AutoColor;
-    } else if (img.format() == QImage::Format_RGB32) {
+    } else if (img.format() == QImage::Format_RGB32 || img.depth() == 1) {
         image = img.convertToFormat(imageFormat, flags);
     } else {
@@ -426,5 +423,5 @@
     Q_ASSERT(dfbSurface);
 
-    alpha = (color.alpha() < 255);
+    alpha |= (color.alpha() < 255);
 
     if (alpha && isOpaqueFormat(imageFormat)) {
@@ -594,4 +591,15 @@
 }
 
+#ifndef QT_DIRECTFB_PLUGIN
+Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_pixmap(const QPixmap &pixmap)
+{
+    const QPixmapData *data = pixmap.pixmapData();
+    if (!data || data->classId() != QPixmapData::DirectFBClass)
+        return 0;
+    const QDirectFBPixmapData *dfbData = static_cast<const QDirectFBPixmapData*>(data);
+    return dfbData->directFBSurface();
+}
+#endif
+
 QT_END_NAMESPACE
 
Index: trunk/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
===================================================================
--- trunk/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp	(revision 766)
+++ trunk/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp	(revision 769)
@@ -922,5 +922,5 @@
         }
     } else {
-        flipFlags = DSFLIP_BLIT;
+        flipFlags = DSFLIP_BLIT|DSFLIP_ONSYNC;
     }
 }
@@ -1127,4 +1127,6 @@
     if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) {
         d_ptr->directFBFlags |= BoundingRectFlip;
+    } else if (displayArgs.contains(QLatin1String("nopartialflip"), Qt::CaseInsensitive)) {
+        d_ptr->directFBFlags |= NoPartialFlip;
     }
 
@@ -1139,4 +1141,6 @@
 #endif
         d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN);
+
+    const bool forcePremultiplied = displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive);
 
     DFBSurfaceDescription description;
@@ -1168,5 +1172,5 @@
     }
 
-    if (displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive)) {
+    if (forcePremultiplied) {
         description.caps |= DSCAPS_PREMULTIPLIED;
     }
@@ -1218,4 +1222,6 @@
         break;
     case QImage::Format_ARGB32:
+        if (forcePremultiplied)
+            d_ptr->alphaPixmapFormat = pixelFormat = QImage::Format_ARGB32_Premultiplied;
     case QImage::Format_ARGB32_Premultiplied:
     case QImage::Format_ARGB4444_Premultiplied:
@@ -1675,5 +1681,5 @@
 uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl)
 {
-    void *mem;
+    void *mem = 0;
     const DFBResult result = surface->Lock(surface, flags, &mem, bpl);
     if (result != DFB_OK) {
@@ -1684,9 +1690,20 @@
 }
 
+static inline bool isFullUpdate(IDirectFBSurface *surface, const QRegion &region, const QPoint &offset)
+{
+    if (offset == QPoint(0, 0) && region.rectCount() == 1) {
+	QSize size;
+	surface->GetSize(surface, &size.rwidth(), &size.rheight());
+	if (region.boundingRect().size() == size)
+	    return true;
+    }
+    return false;
+}
 
 void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
                                   const QRegion &region, const QPoint &offset)
 {
-    if (!(flipFlags & DSFLIP_BLIT)) {
+    if (d_ptr->directFBFlags & NoPartialFlip
+        || (!(flipFlags & DSFLIP_BLIT) && QT_PREPEND_NAMESPACE(isFullUpdate(surface, region, offset)))) {
         surface->Flip(surface, 0, flipFlags);
     } else {
Index: trunk/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
===================================================================
--- trunk/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h	(revision 766)
+++ trunk/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h	(revision 769)
@@ -145,5 +145,6 @@
         VideoOnly = 0x01,
         SystemOnly = 0x02,
-        BoundingRectFlip = 0x04
+        BoundingRectFlip = 0x04,
+        NoPartialFlip = 0x08
     };
 
Index: trunk/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
===================================================================
--- trunk/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp	(revision 766)
+++ trunk/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp	(revision 769)
@@ -62,4 +62,5 @@
     , flipFlags(flip)
     , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
+    , flushPending(false)
 {
 #ifdef QT_NO_DIRECTFB_WM
@@ -81,4 +82,5 @@
     , flipFlags(flip)
     , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
+    , flushPending(false)
 {
     SurfaceFlags flags = 0;
@@ -93,8 +95,4 @@
         flags = Buffered;
     }
-#else
-    noSystemBackground = widget && widget->testAttribute(Qt::WA_NoSystemBackground);
-    if (noSystemBackground)
-        flags &= ~Opaque;
 #endif
     setSurfaceFlags(flags);
@@ -135,31 +133,33 @@
         qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");
 
+    updateIsOpaque();
+
     DFBWindowDescription description;
     memset(&description, 0, sizeof(DFBWindowDescription));
 
+    description.flags = DWDESC_CAPS|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT;
     description.caps = DWCAPS_NODECORATION;
-    description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY;
-#if (Q_DIRECTFB_VERSION >= 0x010200)
-    description.flags |= DWDESC_OPTIONS;
-#endif
-
-    if (noSystemBackground) {
+    description.surface_caps = DSCAPS_NONE;
+    imageFormat = screen->pixelFormat();
+
+    if (!(surfaceFlags() & Opaque)) {
+        imageFormat = screen->alphaPixmapFormat();
         description.caps |= DWCAPS_ALPHACHANNEL;
 #if (Q_DIRECTFB_VERSION >= 0x010200)
+        description.flags |= DWDESC_OPTIONS;
         description.options |= DWOP_ALPHACHANNEL;
 #endif
     }
-
+    description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(imageFormat);
     description.posx = rect.x();
     description.posy = rect.y();
     description.width = rect.width();
     description.height = rect.height();
-    description.surface_caps = DSCAPS_NONE;
+
+    if (QDirectFBScreen::isPremultiplied(imageFormat))
+        description.surface_caps = DSCAPS_PREMULTIPLIED;
+
     if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
         description.surface_caps |= DSCAPS_VIDEOONLY;
-    const QImage::Format format = (noSystemBackground ? screen->alphaPixmapFormat() : screen->pixelFormat());
-    description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
-    if (QDirectFBScreen::isPremultiplied(format))
-        description.surface_caps = DSCAPS_PREMULTIPLIED;
 
     DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
@@ -183,5 +183,4 @@
     Q_ASSERT(!dfbSurface);
     dfbWindow->GetSurface(dfbWindow, &dfbSurface);
-    updateFormat();
 }
 
@@ -268,5 +267,6 @@
         } else { // mode == Offscreen
             if (!dfbSurface) {
-                dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface);
+                dfbSurface = screen->createDFBSurface(rect.size(), surfaceFlags() & Opaque ? screen->pixelFormat() : screen->alphaPixmapFormat(),
+                                                      QDirectFBScreen::DontTrackSurface);
             }
         }
@@ -275,6 +275,7 @@
 #endif
     }
-    if (oldSurface != dfbSurface)
-        updateFormat();
+    if (oldSurface != dfbSurface) {
+        imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
+    }
 
     if (oldRect.size() != rect.size()) {
@@ -297,30 +298,21 @@
         sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
         Q_ASSERT(sibling);
-        sibling->setSurfaceFlags(surfaceFlags());
-    }
-}
-
-static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy)
-{
+        setSurfaceFlags(sibling->surfaceFlags());
+    }
+}
+
+bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
+{
+    if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.rectCount() != 1)
+        return false;
+    if (flushPending) {
+        dfbSurface->Flip(dfbSurface, 0, DSFLIP_BLIT);
+    } else {
+        flushPending = true;
+    }
+    dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
+    const QRect r = region.boundingRect();
     const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
-    surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy);
-    const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy };
-    surface->Flip(surface, &region, DSFLIP_BLIT);
-}
-
-bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
-{
-    if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty())
-        return false;
-    dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
-    if (region.rectCount() == 1) {
-        scrollSurface(dfbSurface, region.boundingRect(), dx, dy);
-    } else {
-        const QVector<QRect> rects = region.rects();
-        const int n = rects.size();
-        for (int i=0; i<n; ++i) {
-            scrollSurface(dfbSurface, rects.at(i), dx, dy);
-        }
-    }
+    dfbSurface->Blit(dfbSurface, dfbSurface, &rect, r.x() + dx, r.y() + dy);
     return true;
 }
@@ -360,6 +352,4 @@
     const QRect windowGeometry = geometry();
 #ifdef QT_DIRECTFB_WM
-    const bool wasNoSystemBackground = noSystemBackground;
-    noSystemBackground = win->testAttribute(Qt::WA_NoSystemBackground);
     quint8 currentOpacity;
     Q_ASSERT(dfbWindow);
@@ -369,16 +359,7 @@
     }
 
-    setOpaque(noSystemBackground || windowOpacity != 0xff);
-    if (wasNoSystemBackground != noSystemBackground) {
-        releaseSurface();
-        dfbWindow->Release(dfbWindow);
-        dfbWindow = 0;
-        createWindow(windowGeometry);
-        win->update();
-        return;
-    }
     screen->flipSurface(dfbSurface, flipFlags, region, offset);
 #else
-    setOpaque(windowOpacity != 0xff);
+    setOpaque(windowOpacity == 0xff);
     if (mode == Offscreen) {
         screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
@@ -397,4 +378,5 @@
     }
 #endif
+    flushPending = false;
 }
 
@@ -404,4 +386,5 @@
         engine = new QDirectFBPaintEngine(this);
     }
+    flushPending = true;
 }
 
@@ -443,9 +426,4 @@
 }
 
-void QDirectFBWindowSurface::updateFormat()
-{
-    imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
-}
-
 void QDirectFBWindowSurface::releaseSurface()
 {
@@ -466,8 +444,36 @@
 }
 
+void QDirectFBWindowSurface::updateIsOpaque()
+{
+    const QWidget *win = window();
+    Q_ASSERT(win);
+    if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) {
+        setOpaque(true);
+        return;
+    }
+
+    if (qFuzzyCompare(static_cast<float>(win->windowOpacity()), 1.0f)) {
+        const QPalette &pal = win->palette();
+
+        if (win->autoFillBackground()) {
+            const QBrush &autoFillBrush = pal.brush(win->backgroundRole());
+            if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
+                setOpaque(true);
+                return;
+            }
+        }
+
+        if (win->isWindow() && !win->testAttribute(Qt::WA_NoSystemBackground)) {
+            const QBrush &windowBrush = win->palette().brush(QPalette::Window);
+            if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
+                setOpaque(true);
+                return;
+            }
+        }
+    }
+    setOpaque(false);
+}
 
 QT_END_NAMESPACE
 
 #endif // QT_NO_QWS_DIRECTFB
-
-
Index: trunk/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
===================================================================
--- trunk/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h	(revision 766)
+++ trunk/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h	(revision 769)
@@ -98,6 +98,6 @@
 #endif
 private:
+    void updateIsOpaque();
     void setOpaque(bool opaque);
-    void updateFormat();
     void releaseSurface();
     QDirectFBWindowSurface *sibling;
@@ -114,6 +114,6 @@
 
     DFBSurfaceFlipFlags flipFlags;
-    bool noSystemBackground;
     bool boundingRectFlip;
+    bool flushPending;
 #ifdef QT_DIRECTFB_TIMING
     int frames;
Index: trunk/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
===================================================================
--- trunk/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp	(revision 766)
+++ trunk/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp	(revision 769)
@@ -260,5 +260,5 @@
         return 0;
     return 90 * static_cast<const QTransformedScreen *>(parent)
-                    ->transformation();
+                    ->transformOrientation();
 }
 
Index: trunk/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
===================================================================
--- trunk/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp	(revision 766)
+++ trunk/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp	(revision 769)
@@ -326,4 +326,34 @@
     { 0xffe9, Qt::Key_Alt       },
     { 0xffea, Qt::Key_Alt       },
+
+    { 0xffb0, Qt::Key_0         },
+    { 0xffb1, Qt::Key_1         },
+    { 0xffb2, Qt::Key_2         },
+    { 0xffb3, Qt::Key_3         },
+    { 0xffb4, Qt::Key_4         },
+    { 0xffb5, Qt::Key_5         },
+    { 0xffb6, Qt::Key_6         },
+    { 0xffb7, Qt::Key_7         },
+    { 0xffb8, Qt::Key_8         },
+    { 0xffb9, Qt::Key_9         },
+
+    { 0xff8d, Qt::Key_Return    },
+    { 0xffaa, Qt::Key_Asterisk  },
+    { 0xffab, Qt::Key_Plus      },
+    { 0xffad, Qt::Key_Minus     },
+    { 0xffae, Qt::Key_Period    },
+    { 0xffaf, Qt::Key_Slash     },
+
+    { 0xff95, Qt::Key_Home      },
+    { 0xff96, Qt::Key_Left      },
+    { 0xff97, Qt::Key_Up        },
+    { 0xff98, Qt::Key_Right     },
+    { 0xff99, Qt::Key_Down      },
+    { 0xff9a, Qt::Key_PageUp    },
+    { 0xff9b, Qt::Key_PageDown  },
+    { 0xff9c, Qt::Key_End       },
+    { 0xff9e, Qt::Key_Insert    },
+    { 0xff9f, Qt::Key_Delete    },
+
     { 0, 0 }
 };
@@ -484,4 +514,8 @@
         i++;
     }
+
+    if (keycode >= ' ' && keycode <= '~')
+        unicode = keycode;
+
     if (!keycode) {
         if (key <= 0xff) {
@@ -2130,4 +2164,7 @@
         const int id = getDisplayId(dspec);
         QScreen *s = qt_get_screen(id, dspec.toLatin1().constData());
+        if (s->pixelFormat() == QImage::Format_Indexed8
+            || s->pixelFormat() == QImage::Format_Invalid && s->depth() == 8)
+            qFatal("QVNCScreen: unsupported screen format");
         setScreen(s);
     } else { // create virtual screen
Index: trunk/src/plugins/imageformats/ico/qicohandler.cpp
===================================================================
--- trunk/src/plugins/imageformats/ico/qicohandler.cpp	(revision 766)
+++ trunk/src/plugins/imageformats/ico/qicohandler.cpp	(revision 769)
@@ -54,4 +54,5 @@
 #include <QtCore/QFile>
 #include <QtCore/QBuffer>
+#include <qvariant.h>
 // These next two structs represent how the icon information is stored
 // in an ICO file.
@@ -773,4 +774,27 @@
 }
 
+QVariant QtIcoHandler::option(ImageOption option) const
+{
+    if (option == Size) {
+        QIODevice *device = QImageIOHandler::device();
+        qint64 oldPos = device->pos();
+        ICONDIRENTRY iconEntry;
+        if (device->seek(oldPos + ICONDIR_SIZE + (m_currentIconIndex * ICONDIRENTRY_SIZE))) {
+            if (readIconDirEntry(device, &iconEntry)) {
+                device->seek(oldPos);
+                return QSize(iconEntry.bWidth, iconEntry.bHeight);
+            }
+        }
+        if (!device->isSequential())
+            device->seek(oldPos);
+    }
+    return QVariant();
+}
+
+bool QtIcoHandler::supportsOption(ImageOption option) const
+{
+    return option == Size;
+}
+
 /*!
  * Verifies if some values (magic bytes) are set as expected in the header of the file.
Index: trunk/src/plugins/imageformats/ico/qicohandler.h
===================================================================
--- trunk/src/plugins/imageformats/ico/qicohandler.h	(revision 766)
+++ trunk/src/plugins/imageformats/ico/qicohandler.h	(revision 769)
@@ -63,4 +63,7 @@
     static bool canRead(QIODevice *device);
     
+    bool supportsOption(ImageOption option) const;
+    QVariant option(ImageOption option) const;
+
 private:
     int m_currentIconIndex;
Index: trunk/src/plugins/imageformats/jpeg/qjpeghandler.cpp
===================================================================
--- trunk/src/plugins/imageformats/jpeg/qjpeghandler.cpp	(revision 766)
+++ trunk/src/plugins/imageformats/jpeg/qjpeghandler.cpp	(revision 769)
@@ -1189,5 +1189,9 @@
     }
 
-    return device->peek(2) == "\xFF\xD8";
+    char buffer[2];
+    if (device->peek(buffer, 2) != 2)
+        return false;
+
+    return uchar(buffer[0]) == 0xff && uchar(buffer[1]) == 0xd8;
 }
 
Index: trunk/src/plugins/kbddrivers/linuxinput/main.cpp
===================================================================
--- trunk/src/plugins/kbddrivers/linuxinput/main.cpp	(revision 766)
+++ trunk/src/plugins/kbddrivers/linuxinput/main.cpp	(revision 769)
@@ -70,5 +70,5 @@
     if (driver.compare(QLatin1String("LinuxInput"), Qt::CaseInsensitive))
         return 0;
-    return new QWSLinuxInputKeyboardHandler(driver, device);
+    return new QWSLinuxInputKeyboardHandler(device);
 }
 
Index: trunk/src/plugins/phonon/mmf/mmf.pro
===================================================================
--- trunk/src/plugins/phonon/mmf/mmf.pro	(revision 766)
+++ trunk/src/plugins/phonon/mmf/mmf.pro	(revision 769)
@@ -21,4 +21,6 @@
 PREPEND_INCLUDEPATH = /epoc32/include
 
+PREPEND_INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty
+
 INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
 
@@ -27,5 +29,6 @@
            $$PHONON_MMF_DIR/abstractmediaplayer.h    \
            $$PHONON_MMF_DIR/abstractplayer.h         \
-           $$PHONON_MMF_DIR/ancestormovemonitor.h    \
+           $$PHONON_MMF_DIR/abstractvideooutput.h    \
+           $$PHONON_MMF_DIR/abstractvideoplayer.h    \
            $$PHONON_MMF_DIR/audioequalizer.h         \
            $$PHONON_MMF_DIR/audiooutput.h            \
@@ -41,5 +44,4 @@
            $$PHONON_MMF_DIR/mediaobject.h            \
            $$PHONON_MMF_DIR/mmf_medianode.h          \
-           $$PHONON_MMF_DIR/mmf_videoplayer.h        \
            $$PHONON_MMF_DIR/stereowidening.h         \
            $$PHONON_MMF_DIR/objectdump.h             \
@@ -47,5 +49,4 @@
            $$PHONON_MMF_DIR/objecttree.h             \
            $$PHONON_MMF_DIR/utils.h                  \
-           $$PHONON_MMF_DIR/videooutput.h            \
            $$PHONON_MMF_DIR/videowidget.h
 
@@ -54,8 +55,9 @@
            $$PHONON_MMF_DIR/abstractmediaplayer.cpp  \
            $$PHONON_MMF_DIR/abstractplayer.cpp       \
-           $$PHONON_MMF_DIR/ancestormovemonitor.cpp  \
            $$PHONON_MMF_DIR/audioequalizer.cpp       \
            $$PHONON_MMF_DIR/audiooutput.cpp          \
            $$PHONON_MMF_DIR/audioplayer.cpp          \
+           $$PHONON_MMF_DIR/abstractvideooutput.cpp  \
+           $$PHONON_MMF_DIR/abstractvideoplayer.cpp  \
            $$PHONON_MMF_DIR/backend.cpp              \
            $$PHONON_MMF_DIR/bassboost.cpp            \
@@ -67,5 +69,4 @@
            $$PHONON_MMF_DIR/mediaobject.cpp          \
            $$PHONON_MMF_DIR/mmf_medianode.cpp        \
-           $$PHONON_MMF_DIR/mmf_videoplayer.cpp      \
            $$PHONON_MMF_DIR/stereowidening.cpp       \
            $$PHONON_MMF_DIR/objectdump.cpp           \
@@ -73,6 +74,26 @@
            $$PHONON_MMF_DIR/objecttree.cpp           \
            $$PHONON_MMF_DIR/utils.cpp                \
-           $$PHONON_MMF_DIR/videooutput.cpp          \
            $$PHONON_MMF_DIR/videowidget.cpp
+
+# Test for whether the build environment supports video rendering to graphics
+# surfaces.
+exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) {
+    HEADERS +=                                       \
+           $$PHONON_MMF_DIR/videooutput_surface.h    \
+           $$PHONON_MMF_DIR/videoplayer_surface.h
+    SOURCES +=                                       \
+           $$PHONON_MMF_DIR/videooutput_surface.cpp  \
+           $$PHONON_MMF_DIR/videoplayer_surface.cpp
+    DEFINES += PHONON_MMF_VIDEO_SURFACES
+} else {
+    HEADERS +=                                       \
+           $$PHONON_MMF_DIR/ancestormovemonitor.h    \
+           $$PHONON_MMF_DIR/videooutput_dsa.h        \
+           $$PHONON_MMF_DIR/videoplayer_dsa.h
+    SOURCES +=                                       \
+           $$PHONON_MMF_DIR/ancestormovemonitor.cpp  \
+           $$PHONON_MMF_DIR/videooutput_dsa.cpp      \
+           $$PHONON_MMF_DIR/videoplayer_dsa.cpp      \
+}
 
 LIBS += -lcone
Index: trunk/src/plugins/qpluginbase.pri
===================================================================
--- trunk/src/plugins/qpluginbase.pri	(revision 766)
+++ trunk/src/plugins/qpluginbase.pri	(revision 769)
@@ -15,4 +15,5 @@
     TARGET.EPOCALLOWDLLDATA=1
     TARGET.CAPABILITY = All -Tcb
+    TARGET = $${TARGET}$${QT_LIBINFIX}
     load(armcc_warnings)
 }
Index: trunk/src/plugins/s60/3_1/3_1.pro
===================================================================
--- trunk/src/plugins/s60/3_1/3_1.pro	(revision 766)
+++ trunk/src/plugins/s60/3_1/3_1.pro	(revision 769)
@@ -1,5 +1,5 @@
 include(../s60pluginbase.pri)
 
-TARGET  = qts60plugin_3_1
+TARGET  = qts60plugin_3_1$${QT_LIBINFIX}
 
 SOURCES += ../src/qlocale_3_1.cpp \
Index: trunk/src/plugins/s60/3_2/3_2.pro
===================================================================
--- trunk/src/plugins/s60/3_2/3_2.pro	(revision 766)
+++ trunk/src/plugins/s60/3_2/3_2.pro	(revision 769)
@@ -1,5 +1,5 @@
 include(../s60pluginbase.pri)
 
-TARGET  = qts60plugin_3_2
+TARGET  = qts60plugin_3_2$${QT_LIBINFIX}
 
 contains(S60_VERSION, 3.1) {
@@ -11,5 +11,5 @@
         ../src/qdesktopservices_3_2.cpp \
         ../src/qcoreapplication_3_2.cpp
-    LIBS += -ldirectorylocalizer -lefsrv
+    LIBS += -lDirectoryLocalizer -lefsrv
     INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
 }
Index: trunk/src/plugins/s60/5_0/5_0.pro
===================================================================
--- trunk/src/plugins/s60/5_0/5_0.pro	(revision 766)
+++ trunk/src/plugins/s60/5_0/5_0.pro	(revision 769)
@@ -1,5 +1,5 @@
 include(../s60pluginbase.pri)
 
-TARGET  = qts60plugin_5_0
+TARGET  = qts60plugin_5_0$${QT_LIBINFIX}
 
 contains(S60_VERSION, 3.1) {
@@ -11,5 +11,5 @@
         ../src/qdesktopservices_3_2.cpp \
         ../src/qcoreapplication_3_2.cpp
-    LIBS += -ldirectorylocalizer -lefsrv
+    LIBS += -lDirectoryLocalizer -lefsrv
     INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
 }
Index: trunk/src/plugins/s60/src/qdesktopservices_3_2.cpp
===================================================================
--- trunk/src/plugins/s60/src/qdesktopservices_3_2.cpp	(revision 766)
+++ trunk/src/plugins/s60/src/qdesktopservices_3_2.cpp	(revision 769)
@@ -46,5 +46,5 @@
 #ifdef Q_WS_S60
 #include <e32base.h>                 // CBase -> Required by cdirectorylocalizer.h
-#include <cdirectorylocalizer.h>     // CDirectoryLocalizer
+#include <CDirectoryLocalizer.h>     // CDirectoryLocalizer
 
 EXPORT_C QString localizedDirectoryName(QString& rawPath)
Index: trunk/src/plugins/sqldrivers/odbc/odbc.pro
===================================================================
--- trunk/src/plugins/sqldrivers/odbc/odbc.pro	(revision 766)
+++ trunk/src/plugins/sqldrivers/odbc/odbc.pro	(revision 769)
@@ -9,4 +9,5 @@
 	    LIBS 	*= $$QT_LFLAGS_ODBC
 	}
+        DEFINES += UNICODE
 }
 
Index: trunk/src/plugins/sqldrivers/sqlite/sqlite.pro
===================================================================
--- trunk/src/plugins/sqldrivers/sqlite/sqlite.pro	(revision 766)
+++ trunk/src/plugins/sqldrivers/sqlite/sqlite.pro	(revision 769)
@@ -16,3 +16,5 @@
 }
 
+wince*: DEFINES += HAVE_LOCALTIME_S=0
+
 include(../qsqldriverbase.pri)
Index: trunk/src/qbase.pri
===================================================================
--- trunk/src/qbase.pri	(revision 766)
+++ trunk/src/qbase.pri	(revision 769)
@@ -106,4 +106,8 @@
     }
     load(armcc_warnings)
+
+    # workaround for the fact that some of our required includes in Symbian^3
+    # now depend upon files in epoc32/include/platform
+    INCLUDEPATH += $$OS_LAYER_SYSTEMINCLUDE
 }
 win32-borland:INCLUDEPATH += kernel
Index: trunk/src/qt3support/dialogs/q3filedialog.cpp
===================================================================
--- trunk/src/qt3support/dialogs/q3filedialog.cpp	(revision 766)
+++ trunk/src/qt3support/dialogs/q3filedialog.cpp	(revision 769)
@@ -476,6 +476,14 @@
 static bool detailViewMode = false;
 
-static Q3CleanupHandler<QPixmap> qfd_cleanup_pixmap;
 static Q3CleanupHandler<QString> qfd_cleanup_string;
+
+static void qt_cleanup_fd_pixmaps();
+typedef QList<QPixmap *> FDPixmaps;
+Q_GLOBAL_STATIC_WITH_INITIALIZER(FDPixmaps, qfd_pixmaps, qAddPostRoutine(qt_cleanup_fd_pixmaps))
+
+static void qt_cleanup_fd_pixmaps()
+{
+    qDeleteAll(*qfd_pixmaps());
+}
 
 static QString toRootIfNotExists( const QString &path )
@@ -534,35 +542,35 @@
 
         openFolderIcon = new QPixmap((const char **)open_xpm);
-        qfd_cleanup_pixmap.add(&openFolderIcon);
+        qfd_pixmaps()->append(openFolderIcon);
         symLinkDirIcon = new QPixmap((const char **)link_dir_xpm);
-        qfd_cleanup_pixmap.add(&symLinkDirIcon);
+        qfd_pixmaps()->append(symLinkDirIcon);
         symLinkFileIcon = new QPixmap((const char **)link_file_xpm);
-        qfd_cleanup_pixmap.add(&symLinkFileIcon);
+        qfd_pixmaps()->append(symLinkFileIcon);
         fileIcon = new QPixmap((const char **)file_xpm);
-        qfd_cleanup_pixmap.add(&fileIcon);
+        qfd_pixmaps()->append(fileIcon);
         closedFolderIcon = new QPixmap((const char **)closed_xpm);
-        qfd_cleanup_pixmap.add(&closedFolderIcon);
+        qfd_pixmaps()->append(closedFolderIcon);
         detailViewIcon = new QPixmap((const char **)detailedview_xpm);
-        qfd_cleanup_pixmap.add(&detailViewIcon);
+        qfd_pixmaps()->append(detailViewIcon);
         multiColumnListViewIcon = new QPixmap((const char **)mclistview_xpm);
-        qfd_cleanup_pixmap.add(&multiColumnListViewIcon);
+        qfd_pixmaps()->append(multiColumnListViewIcon);
         cdToParentIcon = new QPixmap((const char **)cdtoparent_xpm);
-        qfd_cleanup_pixmap.add(&cdToParentIcon);
+        qfd_pixmaps()->append(cdToParentIcon);
         newFolderIcon = new QPixmap((const char **)newfolder_xpm);
-        qfd_cleanup_pixmap.add(&newFolderIcon);
+        qfd_pixmaps()->append(newFolderIcon);
         previewInfoViewIcon
             = new QPixmap((const char **)previewinfoview_xpm);
-        qfd_cleanup_pixmap.add(&previewInfoViewIcon);
+        qfd_pixmaps()->append(previewInfoViewIcon);
         previewContentsViewIcon
             = new QPixmap((const char **)previewcontentsview_xpm);
-        qfd_cleanup_pixmap.add(&previewContentsViewIcon);
+        qfd_pixmaps()->append(previewContentsViewIcon);
         startCopyIcon = new QPixmap((const char **)start_xpm);
-        qfd_cleanup_pixmap.add(&startCopyIcon);
+        qfd_pixmaps()->append(startCopyIcon);
         endCopyIcon = new QPixmap((const char **)end_xpm);
-        qfd_cleanup_pixmap.add(&endCopyIcon);
+        qfd_pixmaps()->append(endCopyIcon);
         goBackIcon = new QPixmap((const char **)back_xpm);
-        qfd_cleanup_pixmap.add(&goBackIcon);
+        qfd_pixmaps()->append(goBackIcon);
         fifteenTransparentPixels = new QPixmap(closedFolderIcon->width(), 1);
-        qfd_cleanup_pixmap.add(&fifteenTransparentPixels);
+        qfd_pixmaps()->append(fifteenTransparentPixels);
         QBitmap m(fifteenTransparentPixels->width(), 1);
         m.fill(Qt::color0);
Index: trunk/src/qt3support/itemviews/q3iconview.cpp
===================================================================
--- trunk/src/qt3support/itemviews/q3iconview.cpp	(revision 766)
+++ trunk/src/qt3support/itemviews/q3iconview.cpp	(revision 769)
@@ -133,6 +133,13 @@
 static bool optimize_layout = false;
 
-static Q3CleanupHandler<QPixmap> qiv_cleanup_pixmap;
-
+
+static void qt_cleanup_iv_pixmaps();
+typedef QList<QPixmap *> IVPixmaps;
+Q_GLOBAL_STATIC_WITH_INITIALIZER(IVPixmaps, qiv_pixmaps, qAddPostRoutine(qt_cleanup_iv_pixmaps))
+
+static void qt_cleanup_iv_pixmaps()
+{
+    qDeleteAll(*qiv_pixmaps());
+}
 
 static QPixmap *get_qiv_buffer_pixmap(const QSize &s)
@@ -140,5 +147,5 @@
     if (!qiv_buffer_pixmap) {
         qiv_buffer_pixmap = new QPixmap(s);
-        qiv_cleanup_pixmap.add(&qiv_buffer_pixmap);
+        qiv_pixmaps()->append(qiv_buffer_pixmap);
         return qiv_buffer_pixmap;
     }
@@ -2581,5 +2588,5 @@
     if (!unknown_icon) {
         unknown_icon = new QPixmap((const char **)unknown_xpm);
-        qiv_cleanup_pixmap.add(&unknown_icon);
+        qiv_pixmaps()->append(unknown_icon);
     }
 
Index: trunk/src/qt3support/itemviews/q3listview.cpp
===================================================================
--- trunk/src/qt3support/itemviews/q3listview.cpp	(revision 766)
+++ trunk/src/qt3support/itemviews/q3listview.cpp	(revision 769)
@@ -70,7 +70,4 @@
 
 const int Unsorted = 16383;
-
-static Q3CleanupHandler<QBitmap> qlv_cleanup_bitmap;
-
 
 struct Q3ListViewPrivate
Index: trunk/src/qt3support/widgets/q3spinwidget.cpp
===================================================================
--- trunk/src/qt3support/widgets/q3spinwidget.cpp	(revision 766)
+++ trunk/src/qt3support/widgets/q3spinwidget.cpp	(revision 769)
@@ -341,9 +341,11 @@
     QStyleOptionSpinBox opt = getStyleOption(this);
 
-    if (d->theButton & 1)
+    if (d->theButton & 1) {
         opt.activeSubControls = QStyle::SC_SpinBoxDown;
-    else if (d->theButton & 2)
+        opt.state |= QStyle::State_Sunken;
+    } else if (d->theButton & 2) {
         opt.activeSubControls = QStyle::SC_SpinBoxUp;
-    else
+        opt.state |= QStyle::State_Sunken;
+    } else
         opt.activeSubControls = QStyle::SC_None;
     opt.rect = style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxFrame, this);
Index: trunk/src/qt_targets.pri
===================================================================
--- trunk/src/qt_targets.pri	(revision 766)
+++ trunk/src/qt_targets.pri	(revision 769)
@@ -5,5 +5,5 @@
 
 isEmpty(QT_MAJOR_VERSION) {
-   VERSION=4.6.2
+   VERSION=4.6.3
 } else {
    VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
Index: trunk/src/s60installs/bwins/QtCoreu.def
===================================================================
--- trunk/src/s60installs/bwins/QtCoreu.def	(revision 766)
+++ trunk/src/s60installs/bwins/QtCoreu.def	(revision 769)
@@ -4400,3 +4400,23 @@
 	?signalIndex@SignalEvent@QStateMachine@@QBEHXZ @ 4399 NONAME ; int QStateMachine::SignalEvent::signalIndex(void) const
 	?disconnectOne@QMetaObject@@SA_NPBVQObject@@H0H@Z @ 4400 NONAME ; bool QMetaObject::disconnectOne(class QObject const *, int, class QObject const *, int)
+	?QBasicAtomicInt_fetchAndAddRelease@@YAHPCHH@Z @ 4401 NONAME ; int QBasicAtomicInt_fetchAndAddRelease(int volatile *, int)
+	?QBasicAtomicPointer_testAndSetRelaxed@@YA_NPCRAXPAX1@Z @ 4402 NONAME ; bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *, void *, void *)
+	?QBasicAtomicInt_fetchAndAddRelaxed@@YAHPCHH@Z @ 4403 NONAME ; int QBasicAtomicInt_fetchAndAddRelaxed(int volatile *, int)
+	?QBasicAtomicPointer_testAndSetRelease@@YA_NPCRAXPAX1@Z @ 4404 NONAME ; bool QBasicAtomicPointer_testAndSetRelease(void * volatile *, void *, void *)
+	?QBasicAtomicInt_fetchAndStoreRelease@@YAHPCHH@Z @ 4405 NONAME ; int QBasicAtomicInt_fetchAndStoreRelease(int volatile *, int)
+	?QBasicAtomicPointer_fetchAndAddAcquire@@YAPAXPCRAXH@Z @ 4406 NONAME ; void * QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *, int)
+	?QBasicAtomicPointer_fetchAndAddRelease@@YAPAXPCRAXH@Z @ 4407 NONAME ; void * QBasicAtomicPointer_fetchAndAddRelease(void * volatile *, int)
+	?QBasicAtomicPointer_testAndSetAcquire@@YA_NPCRAXPAX1@Z @ 4408 NONAME ; bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *, void *, void *)
+	?QBasicAtomicPointer_fetchAndStoreAcquire@@YAPAXPCRAXPAX@Z @ 4409 NONAME ; void * QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *, void *)
+	?QBasicAtomicPointer_fetchAndAddRelaxed@@YAPAXPCRAXH@Z @ 4410 NONAME ; void * QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *, int)
+	?QBasicAtomicInt_testAndSetAcquire@@YA_NPCHHH@Z @ 4411 NONAME ; bool QBasicAtomicInt_testAndSetAcquire(int volatile *, int, int)
+	?QBasicAtomicPointer_fetchAndStoreRelaxed@@YAPAXPCRAXPAX@Z @ 4412 NONAME ; void * QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *, void *)
+	?QBasicAtomicInt_fetchAndStoreRelaxed@@YAHPCHH@Z @ 4413 NONAME ; int QBasicAtomicInt_fetchAndStoreRelaxed(int volatile *, int)
+	?QBasicAtomicInt_testAndSetRelaxed@@YA_NPCHHH@Z @ 4414 NONAME ; bool QBasicAtomicInt_testAndSetRelaxed(int volatile *, int, int)
+	?QBasicAtomicPointer_fetchAndStoreRelease@@YAPAXPCRAXPAX@Z @ 4415 NONAME ; void * QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *, void *)
+	?QBasicAtomicInt_testAndSetRelease@@YA_NPCHHH@Z @ 4416 NONAME ; bool QBasicAtomicInt_testAndSetRelease(int volatile *, int, int)
+	?QBasicAtomicInt_fetchAndStoreAcquire@@YAHPCHH@Z @ 4417 NONAME ; int QBasicAtomicInt_fetchAndStoreAcquire(int volatile *, int)
+	?QBasicAtomicInt_fetchAndAddAcquire@@YAHPCHH@Z @ 4418 NONAME ; int QBasicAtomicInt_fetchAndAddAcquire(int volatile *, int)
+	?validCodecs@QTextCodec@@CA_NXZ @ 4419 NONAME ; bool QTextCodec::validCodecs(void)
+	?clearHistory@QStateMachinePrivate@@QAEXXZ @ 4420 NONAME ; void QStateMachinePrivate::clearHistory(void)
 
Index: trunk/src/s60installs/bwins/QtGuiu.def
===================================================================
--- trunk/src/s60installs/bwins/QtGuiu.def	(revision 766)
+++ trunk/src/s60installs/bwins/QtGuiu.def	(revision 769)
@@ -8996,5 +8996,5 @@
 	?setFocus@QWidget@@QAEXW4FocusReason@Qt@@@Z @ 8995 NONAME ; void QWidget::setFocus(enum Qt::FocusReason)
 	?setFocus@QWidget@@QAEXXZ @ 8996 NONAME ; void QWidget::setFocus(void)
-	?setFocusHelper@QGraphicsItemPrivate@@QAEXW4FocusReason@Qt@@_N@Z @ 8997 NONAME ; void QGraphicsItemPrivate::setFocusHelper(enum Qt::FocusReason, bool)
+	?setFocusHelper@QGraphicsItemPrivate@@QAEXW4FocusReason@Qt@@_N@Z @ 8997 NONAME ABSENT ; void QGraphicsItemPrivate::setFocusHelper(enum Qt::FocusReason, bool)
 	?setFocusItem@QGraphicsScene@@QAEXPAVQGraphicsItem@@W4FocusReason@Qt@@@Z @ 8998 NONAME ; void QGraphicsScene::setFocusItem(class QGraphicsItem *, enum Qt::FocusReason)
 	?setFocusPolicy@QGraphicsWidget@@QAEXW4FocusPolicy@Qt@@@Z @ 8999 NONAME ; void QGraphicsWidget::setFocusPolicy(enum Qt::FocusPolicy)
@@ -11923,5 +11923,5 @@
 	?updateCell@QCalendarWidget@@IAEXABVQDate@@@Z @ 11922 NONAME ; void QCalendarWidget::updateCell(class QDate const &)
 	?updateCells@QCalendarWidget@@IAEXXZ @ 11923 NONAME ; void QCalendarWidget::updateCells(void)
-	?updateDisplayText@QLineControl@@AAEXXZ @ 11924 NONAME ; void QLineControl::updateDisplayText(void)
+	?updateDisplayText@QLineControl@@AAEXXZ @ 11924 NONAME ABSENT ; void QLineControl::updateDisplayText(void)
 	?updateEditorData@QAbstractItemView@@MAEXXZ @ 11925 NONAME ; void QAbstractItemView::updateEditorData(void)
 	?updateEditorGeometries@QAbstractItemView@@MAEXXZ @ 11926 NONAME ; void QAbstractItemView::updateEditorGeometries(void)
@@ -12549,3 +12549,64 @@
 	?updateAncestorFlags@QGraphicsItemPrivate@@QAEXXZ @ 12548 NONAME ; void QGraphicsItemPrivate::updateAncestorFlags(void)
 	?updateChildWithGraphicsEffectFlagRecursively@QGraphicsItemPrivate@@QAEXXZ @ 12549 NONAME ; void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively(void)
+	?api@QEglContext@@QBE?AW4API@QEgl@@XZ @ 12550 NONAME ; enum QEgl::API QEglContext::api(void) const
+	?display@QEglContext@@SAHXZ @ 12551 NONAME ; int QEglContext::display(void)
+	?isOpacityNull@QGraphicsItemPrivate@@SA_NM@Z @ 12552 NONAME ; bool QGraphicsItemPrivate::isOpacityNull(float)
+	?chooseConfig@QEglContext@@QAE_NABVQEglProperties@@W4PixelFormatMatch@QEgl@@@Z @ 12553 NONAME ; bool QEglContext::chooseConfig(class QEglProperties const &, enum QEgl::PixelFormatMatch)
+	?destroySurface@QEglContext@@QAEXH@Z @ 12554 NONAME ; void QEglContext::destroySurface(int)
+	?lazyDoneCurrent@QEglContext@@QAE_NXZ @ 12555 NONAME ; bool QEglContext::lazyDoneCurrent(void)
+	?waitNative@QEglContext@@QAEXXZ @ 12556 NONAME ; void QEglContext::waitNative(void)
+	?context@QEglContext@@QBEHXZ @ 12557 NONAME ; int QEglContext::context(void) const
+	?configAttrib@QEglContext@@QBE_NHPAH@Z @ 12558 NONAME ; bool QEglContext::configAttrib(int, int *) const
+	??0QEglProperties@@QAE@ABV0@@Z @ 12559 NONAME ; QEglProperties::QEglProperties(class QEglProperties const &)
+	?config@QEglContext@@QBEHXZ @ 12560 NONAME ; int QEglContext::config(void) const
+	?clearFocusHelper@QGraphicsItemPrivate@@QAEX_N@Z @ 12561 NONAME ; void QGraphicsItemPrivate::clearFocusHelper(bool)
+	?error@QEglContext@@SAHXZ @ 12562 NONAME ; int QEglContext::error(void)
+	?swapBuffers@QEglContext@@QAE_NH@Z @ 12563 NONAME ; bool QEglContext::swapBuffers(int)
+	?canKeypadNavigate@QWidgetPrivate@@SA_NW4Orientation@Qt@@@Z @ 12564 NONAME ; bool QWidgetPrivate::canKeypadNavigate(enum Qt::Orientation)
+	?removeAllApplicationFonts@QFontDatabase@@SA_NXZ @ 12565 NONAME ; bool QFontDatabase::removeAllApplicationFonts(void)
+	?setApi@QEglContext@@QAEXW4API@QEgl@@@Z @ 12566 NONAME ; void QEglContext::setApi(enum QEgl::API)
+	?updateDisplayText@QLineControl@@AAEX_N@Z @ 12567 NONAME ; void QLineControl::updateDisplayText(bool)
+	?makeCurrent@QEglContext@@QAE_NH@Z @ 12568 NONAME ; bool QEglContext::makeCurrent(int)
+	?isPixmapCached@QImagePixmapCleanupHooks@@SA_NABVQPixmap@@@Z @ 12569 NONAME ; bool QImagePixmapCleanupHooks::isPixmapCached(class QPixmap const &)
+	?createSurface@QEglContext@@QAEHPAVQPaintDevice@@PBVQEglProperties@@@Z @ 12570 NONAME ; int QEglContext::createSurface(class QPaintDevice *, class QEglProperties const *)
+	?dumpAllConfigs@QEglContext@@QAEXXZ @ 12571 NONAME ; void QEglContext::dumpAllConfigs(void)
+	?reduceConfiguration@QEglProperties@@QAE_NXZ @ 12572 NONAME ; bool QEglProperties::reduceConfiguration(void)
+	?nativeDisplay@QEglContext@@CAHXZ @ 12573 NONAME ; int QEglContext::nativeDisplay(void)
+	?getGlyphBearings@QFontEngine@@UAEXIPAM0@Z @ 12574 NONAME ; void QFontEngine::getGlyphBearings(unsigned int, float *, float *)
+	?removeValue@QEglProperties@@QAE_NH@Z @ 12575 NONAME ; bool QEglProperties::removeValue(int)
+	?toString@QEglProperties@@QBE?AVQString@@XZ @ 12576 NONAME ; class QString QEglProperties::toString(void) const
+	?isOpacityNull@QGraphicsItemPrivate@@QBE_NXZ @ 12577 NONAME ; bool QGraphicsItemPrivate::isOpacityNull(void) const
+	?dumpAllConfigs@QEglProperties@@SAXXZ @ 12578 NONAME ; void QEglProperties::dumpAllConfigs(void)
+	?inTabWidget@QWidgetPrivate@@SA_NPAVQWidget@@@Z @ 12579 NONAME ; bool QWidgetPrivate::inTabWidget(class QWidget *)
+	?configProperties@QEglContext@@QBE?AVQEglProperties@@H@Z @ 12580 NONAME ; class QEglProperties QEglContext::configProperties(int) const
+	?properties@QEglProperties@@QBEPBHXZ @ 12581 NONAME ; int const * QEglProperties::properties(void) const
+	?destroyContext@QEglContext@@QAEXXZ @ 12582 NONAME ; void QEglContext::destroyContext(void)
+	??0QEglContext@@QAE@XZ @ 12583 NONAME ; QEglContext::QEglContext(void)
+	??1QEglContext@@QAE@XZ @ 12584 NONAME ; QEglContext::~QEglContext(void)
+	?isValid@QEglContext@@QBE_NXZ @ 12585 NONAME ; bool QEglContext::isValid(void) const
+	?value@QEglProperties@@QBEHH@Z @ 12586 NONAME ; int QEglProperties::value(int) const
+	?clearError@QEglContext@@SAXXZ @ 12587 NONAME ; void QEglContext::clearError(void)
+	??0QEglProperties@@QAE@H@Z @ 12588 NONAME ; QEglProperties::QEglProperties(int)
+	?setValue@QEglProperties@@QAEXHH@Z @ 12589 NONAME ; void QEglProperties::setValue(int, int)
+	?setPaintDeviceFormat@QEglProperties@@QAEXPAVQPaintDevice@@@Z @ 12590 NONAME ; void QEglProperties::setPaintDeviceFormat(class QPaintDevice *)
+	?isImageCached@QImagePixmapCleanupHooks@@SA_NABVQImage@@@Z @ 12591 NONAME ; bool QImagePixmapCleanupHooks::isImageCached(class QImage const &)
+	?setRenderableType@QEglProperties@@QAEXW4API@QEgl@@@Z @ 12592 NONAME ; void QEglProperties::setRenderableType(enum QEgl::API)
+	?setContext@QEglContext@@QAEXH@Z @ 12593 NONAME ; void QEglContext::setContext(int)
+	?waitClient@QEglContext@@QAEXXZ @ 12594 NONAME ; void QEglContext::waitClient(void)
+	?isEmpty@QEglProperties@@QBE_NXZ @ 12595 NONAME ; bool QEglProperties::isEmpty(void) const
+	?dpy@QEglContext@@0HA @ 12596 NONAME ; int QEglContext::dpy
+	?isSharing@QEglContext@@QBE_NXZ @ 12597 NONAME ; bool QEglContext::isSharing(void) const
+	?isCurrent@QEglContext@@QBE_NXZ @ 12598 NONAME ; bool QEglContext::isCurrent(void) const
+	??0QEglProperties@@QAE@XZ @ 12599 NONAME ; QEglProperties::QEglProperties(void)
+	?extensions@QEglContext@@SA?AVQString@@XZ @ 12600 NONAME ; class QString QEglContext::extensions(void)
+	?setCurrentContext@QEglContext@@CAXW4API@QEgl@@PAV1@@Z @ 12601 NONAME ; void QEglContext::setCurrentContext(enum QEgl::API, class QEglContext *)
+	??1QEglProperties@@QAE@XZ @ 12602 NONAME ; QEglProperties::~QEglProperties(void)
+	?createContext@QEglContext@@QAE_NPAV1@PBVQEglProperties@@@Z @ 12603 NONAME ; bool QEglContext::createContext(class QEglContext *, class QEglProperties const *)
+	?setConfig@QEglContext@@QAEXH@Z @ 12604 NONAME ; void QEglContext::setConfig(int)
+	?hasExtension@QEglContext@@SA_NPBD@Z @ 12605 NONAME ; bool QEglContext::hasExtension(char const *)
+	?doneCurrent@QEglContext@@QAE_NXZ @ 12606 NONAME ; bool QEglContext::doneCurrent(void)
+	?setPixelFormat@QEglProperties@@QAEXW4Format@QImage@@@Z @ 12607 NONAME ; void QEglProperties::setPixelFormat(enum QImage::Format)
+	?currentContext@QEglContext@@CAPAV1@W4API@QEgl@@@Z @ 12608 NONAME ; class QEglContext * QEglContext::currentContext(enum QEgl::API)
+	?setFocusHelper@QGraphicsItemPrivate@@QAEXW4FocusReason@Qt@@_N1@Z @ 12609 NONAME ; void QGraphicsItemPrivate::setFocusHelper(enum Qt::FocusReason, bool, bool)
+	?errorString@QEglContext@@SA?AVQString@@H@Z @ 12610 NONAME ; class QString QEglContext::errorString(int)
 
Index: trunk/src/s60installs/bwins/QtNetworku.def
===================================================================
--- trunk/src/s60installs/bwins/QtNetworku.def	(revision 766)
+++ trunk/src/s60installs/bwins/QtNetworku.def	(revision 769)
@@ -963,3 +963,5 @@
 	?staticMetaObject@QUdpSocket@@2UQMetaObject@@B @ 962 NONAME ; struct QMetaObject const QUdpSocket::staticMetaObject
 	?staticMetaObject@QAbstractSocket@@2UQMetaObject@@B @ 963 NONAME ; struct QMetaObject const QAbstractSocket::staticMetaObject
+	?qt_qhostinfo_clear_cache@@YAXXZ @ 964 NONAME ; void qt_qhostinfo_clear_cache(void)
+	?qt_qhostinfo_lookup@@YA?AVQHostInfo@@ABVQString@@PAVQObject@@PBDPA_NPAH@Z @ 965 NONAME ; class QHostInfo qt_qhostinfo_lookup(class QString const &, class QObject *, char const *, bool *, int *)
 
Index: trunk/src/s60installs/bwins/QtOpenVGu.def
===================================================================
--- trunk/src/s60installs/bwins/QtOpenVGu.def	(revision 766)
+++ trunk/src/s60installs/bwins/QtOpenVGu.def	(revision 769)
@@ -49,5 +49,5 @@
 	??0QVGPainterState@@QAE@XZ @ 48 NONAME ; QVGPainterState::QVGPainterState(void)
 	?d_func@QVGPaintEngine@@ABEPBVQVGPaintEnginePrivate@@XZ @ 49 NONAME ; class QVGPaintEnginePrivate const * QVGPaintEngine::d_func(void) const
-	?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *)
+	?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ABSENT ; class QEglContext * qt_vg_create_context(class QPaintDevice *)
 	?clip@QVGPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 51 NONAME ; void QVGPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation)
 	?endNativePainting@QVGPaintEngine@@UAEXXZ @ 52 NONAME ; void QVGPaintEngine::endNativePainting(void)
@@ -79,5 +79,5 @@
 	?createState@QVGPaintEngine@@UBEPAVQPainterState@@PAV2@@Z @ 78 NONAME ; class QPainterState * QVGPaintEngine::createState(class QPainterState *) const
 	?buffer@QVGPixmapData@@UAEPAVQImage@@XZ @ 79 NONAME ; class QImage * QVGPixmapData::buffer(void)
-	?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ; void qt_vg_destroy_context(class QEglContext *)
+	?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ABSENT ; void qt_vg_destroy_context(class QEglContext *)
 	?clip@QVGPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 81 NONAME ; void QVGPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation)
 	?drawPolygon@QVGPaintEngine@@UAEXPBVQPoint@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 82 NONAME ; void QVGPaintEngine::drawPolygon(class QPoint const *, int, enum QPaintEngine::PolygonDrawMode)
@@ -140,3 +140,32 @@
 	?clip@QVGPaintEngine@@UAEXABVQPainterPath@@W4ClipOperation@Qt@@@Z @ 139 NONAME ; void QVGPaintEngine::clip(class QPainterPath const &, enum Qt::ClipOperation)
 	?vgPrivate@QVGPaintEngine@@QAEPAVQVGPaintEnginePrivate@@XZ @ 140 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::vgPrivate(void)
+	?removeFromLRU@QVGImagePool@@IAEXPAVQVGPixmapData@@@Z @ 141 NONAME ; void QVGImagePool::removeFromLRU(class QVGPixmapData *)
+	?releaseImage@QVGImagePool@@UAEXPAVQVGPixmapData@@K@Z @ 142 NONAME ; void QVGImagePool::releaseImage(class QVGPixmapData *, unsigned long)
+	?d_func@QVGImagePool@@AAEPAVQVGImagePoolPrivate@@XZ @ 143 NONAME ; class QVGImagePoolPrivate * QVGImagePool::d_func(void)
+	?detachImageFromPool@QVGPixmapData@@UAEXXZ @ 144 NONAME ; void QVGPixmapData::detachImageFromPool(void)
+	?createImageForPixmap@QVGImagePool@@UAEKW4VGImageFormat@@JJKPAVQVGPixmapData@@@Z @ 145 NONAME ; unsigned long QVGImagePool::createImageForPixmap(enum VGImageFormat, long, long, unsigned long, class QVGPixmapData *)
+	?destroyImageAndContext@QVGPixmapData@@IAEXXZ @ 146 NONAME ; void QVGPixmapData::destroyImageAndContext(void)
+	?moveToHeadOfLRU@QVGImagePool@@IAEXPAVQVGPixmapData@@@Z @ 147 NONAME ; void QVGImagePool::moveToHeadOfLRU(class QVGPixmapData *)
+	?instance@QVGImagePool@@SAPAV1@XZ @ 148 NONAME ; class QVGImagePool * QVGImagePool::instance(void)
+	?useImage@QVGImagePool@@UAEXPAVQVGPixmapData@@@Z @ 149 NONAME ; void QVGImagePool::useImage(class QVGPixmapData *)
+	??1QVGImagePool@@UAE@XZ @ 150 NONAME ; QVGImagePool::~QVGImagePool(void)
+	?destroyImages@QVGPixmapData@@IAEXXZ @ 151 NONAME ; void QVGPixmapData::destroyImages(void)
+	?reclaimSpace@QVGImagePool@@UAE_NW4VGImageFormat@@JJPAVQVGPixmapData@@@Z @ 152 NONAME ; bool QVGImagePool::reclaimSpace(enum VGImageFormat, long, long, class QVGPixmapData *)
+	?detachImage@QVGImagePool@@UAEXPAVQVGPixmapData@@@Z @ 153 NONAME ; void QVGImagePool::detachImage(class QVGPixmapData *)
+	?createPermanentImage@QVGImagePool@@UAEKW4VGImageFormat@@JJK@Z @ 154 NONAME ; unsigned long QVGImagePool::createPermanentImage(enum VGImageFormat, long, long, unsigned long)
+	?d_func@QVGImagePool@@ABEPBVQVGImagePoolPrivate@@XZ @ 155 NONAME ; class QVGImagePoolPrivate const * QVGImagePool::d_func(void) const
+	?createTemporaryImage@QVGImagePool@@UAEKW4VGImageFormat@@JJKPAVQVGPixmapData@@@Z @ 156 NONAME ; unsigned long QVGImagePool::createTemporaryImage(enum VGImageFormat, long, long, unsigned long, class QVGPixmapData *)
+	??_EQVGImagePool@@UAE@I@Z @ 157 NONAME ; QVGImagePool::~QVGImagePool(unsigned int)
+	?hibernate@QVGImagePool@@UAEXXZ @ 158 NONAME ; void QVGImagePool::hibernate(void)
+	?qt_vg_destroy_context@@YAXPAVQEglContext@@H@Z @ 159 NONAME ; void qt_vg_destroy_context(class QEglContext *, int)
+	??0QVGImagePool@@QAE@XZ @ 160 NONAME ; QVGImagePool::QVGImagePool(void)
+	?setImagePool@QVGImagePool@@SAXPAV1@@Z @ 161 NONAME ; void QVGImagePool::setImagePool(class QVGImagePool *)
+	?pixmapLRU@QVGImagePool@@IAEPAVQVGPixmapData@@XZ @ 162 NONAME ; class QVGPixmapData * QVGImagePool::pixmapLRU(void)
+	?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@H@Z @ 163 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *, int)
+	?reclaimImages@QVGPixmapData@@UAEXXZ @ 164 NONAME ; void QVGPixmapData::reclaimImages(void)
+	?hibernate@QVGPixmapData@@UAEXXZ @ 165 NONAME ; void QVGPixmapData::hibernate(void)
+	?supportsStaticContents@QVGEGLWindowSurfaceDirect@@UBE_NXZ @ 166 NONAME ; bool QVGEGLWindowSurfaceDirect::supportsStaticContents(void) const
+	?scroll@QVGEGLWindowSurfacePrivate@@UAE_NPAVQWidget@@ABVQRegion@@HH@Z @ 167 NONAME ; bool QVGEGLWindowSurfacePrivate::scroll(class QWidget *, class QRegion const &, int, int)
+	?scroll@QVGEGLWindowSurfaceDirect@@UAE_NPAVQWidget@@ABVQRegion@@HH@Z @ 168 NONAME ; bool QVGEGLWindowSurfaceDirect::scroll(class QWidget *, class QRegion const &, int, int)
+	?supportsStaticContents@QVGEGLWindowSurfacePrivate@@UBE_NXZ @ 169 NONAME ; bool QVGEGLWindowSurfacePrivate::supportsStaticContents(void) const
 
Index: trunk/src/s60installs/eabi/QtCoreu.def
===================================================================
--- trunk/src/s60installs/eabi/QtCoreu.def	(revision 766)
+++ trunk/src/s60installs/eabi/QtCoreu.def	(revision 769)
@@ -3635,3 +3635,23 @@
 	_ZTVN13QStateMachine12WrappedEventE @ 3634 NONAME
 	_ZN11QMetaObject13disconnectOneEPK7QObjectiS2_i @ 3635 NONAME
+	_Z33QBasicAtomicInt_testAndSetAcquirePViii @ 3636 NONAME
+	_Z33QBasicAtomicInt_testAndSetRelaxedPViii @ 3637 NONAME
+	_Z33QBasicAtomicInt_testAndSetReleasePViii @ 3638 NONAME
+	_Z34QBasicAtomicInt_fetchAndAddAcquirePVii @ 3639 NONAME
+	_Z34QBasicAtomicInt_fetchAndAddRelaxedPVii @ 3640 NONAME
+	_Z34QBasicAtomicInt_fetchAndAddReleasePVii @ 3641 NONAME
+	_Z36QBasicAtomicInt_fetchAndStoreAcquirePVii @ 3642 NONAME
+	_Z36QBasicAtomicInt_fetchAndStoreRelaxedPVii @ 3643 NONAME
+	_Z36QBasicAtomicInt_fetchAndStoreReleasePVii @ 3644 NONAME
+	_Z37QBasicAtomicPointer_testAndSetAcquirePVPvS_S_ @ 3645 NONAME
+	_Z37QBasicAtomicPointer_testAndSetRelaxedPVPvS_S_ @ 3646 NONAME
+	_Z37QBasicAtomicPointer_testAndSetReleasePVPvS_S_ @ 3647 NONAME
+	_Z38QBasicAtomicPointer_fetchAndAddAcquirePVPvi @ 3648 NONAME
+	_Z38QBasicAtomicPointer_fetchAndAddRelaxedPVPvi @ 3649 NONAME
+	_Z38QBasicAtomicPointer_fetchAndAddReleasePVPvi @ 3650 NONAME
+	_Z40QBasicAtomicPointer_fetchAndStoreAcquirePVPvS_ @ 3651 NONAME
+	_Z40QBasicAtomicPointer_fetchAndStoreRelaxedPVPvS_ @ 3652 NONAME
+	_Z40QBasicAtomicPointer_fetchAndStoreReleasePVPvS_ @ 3653 NONAME
+	_ZN10QTextCodec11validCodecsEv @ 3654 NONAME
+	_ZN20QStateMachinePrivate12clearHistoryEv @ 3655 NONAME
 
Index: trunk/src/s60installs/eabi/QtGuiu.def
===================================================================
--- trunk/src/s60installs/eabi/QtGuiu.def	(revision 766)
+++ trunk/src/s60installs/eabi/QtGuiu.def	(revision 769)
@@ -1819,5 +1819,5 @@
 	_ZN12QLineControl17processMouseEventEP11QMouseEvent @ 1818 NONAME
 	_ZN12QLineControl17resetInputContextEv @ 1819 NONAME
-	_ZN12QLineControl17updateDisplayTextEv @ 1820 NONAME
+	_ZN12QLineControl17updateDisplayTextEv @ 1820 NONAME ABSENT
 	_ZN12QLineControl18displayTextChangedERK7QString @ 1821 NONAME
 	_ZN12QLineControl18removeSelectedTextEv @ 1822 NONAME
@@ -4664,5 +4664,5 @@
 	_ZN20QGraphicsItemPrivate12setPosHelperERK7QPointF @ 4663 NONAME
 	_ZN20QGraphicsItemPrivate13clearSubFocusEP13QGraphicsItem @ 4664 NONAME
-	_ZN20QGraphicsItemPrivate14setFocusHelperEN2Qt11FocusReasonEb @ 4665 NONAME
+	_ZN20QGraphicsItemPrivate14setFocusHelperEN2Qt11FocusReasonEb @ 4665 NONAME ABSENT
 	_ZN20QGraphicsItemPrivate15resetFocusProxyEv @ 4666 NONAME
 	_ZN20QGraphicsItemPrivate16setEnabledHelperEbbb @ 4667 NONAME
@@ -11742,45 +11742,45 @@
 	_ZNK11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS1_S2_E @ 11741 NONAME
 	_ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbb @ 11742 NONAME
-	_ZN11QEglContext10extensionsEv @ 11743 NONAME ABSENT
+	_ZN11QEglContext10extensionsEv @ 11743 NONAME
 	_ZN11QEglContext10getDisplayEP12QPaintDevice @ 11744 NONAME ABSENT
-	_ZN11QEglContext10waitClientEv @ 11745 NONAME ABSENT
-	_ZN11QEglContext10waitNativeEv @ 11746 NONAME ABSENT
-	_ZN11QEglContext11doneCurrentEv @ 11747 NONAME ABSENT
-	_ZN11QEglContext11errorStringEi @ 11748 NONAME ABSENT
-	_ZN11QEglContext11makeCurrentEi @ 11749 NONAME ABSENT
+	_ZN11QEglContext10waitClientEv @ 11745 NONAME
+	_ZN11QEglContext10waitNativeEv @ 11746 NONAME
+	_ZN11QEglContext11doneCurrentEv @ 11747 NONAME
+	_ZN11QEglContext11errorStringEi @ 11748 NONAME
+	_ZN11QEglContext11makeCurrentEi @ 11749 NONAME
 	_ZN11QEglContext11openDisplayEP12QPaintDevice @ 11750 NONAME ABSENT
-	_ZN11QEglContext11swapBuffersEi @ 11751 NONAME ABSENT
-	_ZN11QEglContext12chooseConfigERK14QEglPropertiesN4QEgl16PixelFormatMatchE @ 11752 NONAME ABSENT
-	_ZN11QEglContext12hasExtensionEPKc @ 11753 NONAME ABSENT
-	_ZN11QEglContext13createContextEPS_PK14QEglProperties @ 11754 NONAME ABSENT
-	_ZN11QEglContext13createSurfaceEP12QPaintDevicePK14QEglProperties @ 11755 NONAME ABSENT
-	_ZN11QEglContext14currentContextEN4QEgl3APIE @ 11756 NONAME ABSENT
+	_ZN11QEglContext11swapBuffersEi @ 11751 NONAME
+	_ZN11QEglContext12chooseConfigERK14QEglPropertiesN4QEgl16PixelFormatMatchE @ 11752 NONAME
+	_ZN11QEglContext12hasExtensionEPKc @ 11753 NONAME
+	_ZN11QEglContext13createContextEPS_PK14QEglProperties @ 11754 NONAME
+	_ZN11QEglContext13createSurfaceEP12QPaintDevicePK14QEglProperties @ 11755 NONAME
+	_ZN11QEglContext14currentContextEN4QEgl3APIE @ 11756 NONAME
 	_ZN11QEglContext14defaultDisplayEP12QPaintDevice @ 11757 NONAME ABSENT
-	_ZN11QEglContext14destroySurfaceEi @ 11758 NONAME ABSENT
-	_ZN11QEglContext14dumpAllConfigsEv @ 11759 NONAME ABSENT
-	_ZN11QEglContext15lazyDoneCurrentEv @ 11760 NONAME ABSENT
-	_ZN11QEglContext17setCurrentContextEN4QEgl3APIEPS_ @ 11761 NONAME ABSENT
+	_ZN11QEglContext14destroySurfaceEi @ 11758 NONAME
+	_ZN11QEglContext14dumpAllConfigsEv @ 11759 NONAME
+	_ZN11QEglContext15lazyDoneCurrentEv @ 11760 NONAME
+	_ZN11QEglContext17setCurrentContextEN4QEgl3APIEPS_ @ 11761 NONAME
 	_ZN11QEglContext7destroyEv @ 11762 NONAME ABSENT
-	_ZN11QEglContextC1Ev @ 11763 NONAME ABSENT
-	_ZN11QEglContextC2Ev @ 11764 NONAME ABSENT
-	_ZN11QEglContextD1Ev @ 11765 NONAME ABSENT
-	_ZN11QEglContextD2Ev @ 11766 NONAME ABSENT
-	_ZN14QEglProperties11removeValueEi @ 11767 NONAME ABSENT
-	_ZN14QEglProperties14dumpAllConfigsEv @ 11768 NONAME ABSENT
-	_ZN14QEglProperties14setPixelFormatEN6QImage6FormatE @ 11769 NONAME ABSENT
-	_ZN14QEglProperties17setRenderableTypeEN4QEgl3APIE @ 11770 NONAME ABSENT
-	_ZN14QEglProperties19reduceConfigurationEv @ 11771 NONAME ABSENT
-	_ZN14QEglProperties20setPaintDeviceFormatEP12QPaintDevice @ 11772 NONAME ABSENT
-	_ZN14QEglProperties8setValueEii @ 11773 NONAME ABSENT
-	_ZN14QEglPropertiesC1Ei @ 11774 NONAME ABSENT
-	_ZN14QEglPropertiesC1Ev @ 11775 NONAME ABSENT
-	_ZN14QEglPropertiesC2Ei @ 11776 NONAME ABSENT
-	_ZN14QEglPropertiesC2Ev @ 11777 NONAME ABSENT
-	_ZNK11QEglContext12configAttribEiPi @ 11778 NONAME ABSENT
-	_ZNK11QEglContext16configPropertiesEi @ 11779 NONAME ABSENT
-	_ZNK11QEglContext7isValidEv @ 11780 NONAME ABSENT
-	_ZNK11QEglContext9isCurrentEv @ 11781 NONAME ABSENT
-	_ZNK14QEglProperties5valueEi @ 11782 NONAME ABSENT
-	_ZNK14QEglProperties8toStringEv @ 11783 NONAME ABSENT
+	_ZN11QEglContextC1Ev @ 11763 NONAME
+	_ZN11QEglContextC2Ev @ 11764 NONAME
+	_ZN11QEglContextD1Ev @ 11765 NONAME
+	_ZN11QEglContextD2Ev @ 11766 NONAME
+	_ZN14QEglProperties11removeValueEi @ 11767 NONAME
+	_ZN14QEglProperties14dumpAllConfigsEv @ 11768 NONAME
+	_ZN14QEglProperties14setPixelFormatEN6QImage6FormatE @ 11769 NONAME
+	_ZN14QEglProperties17setRenderableTypeEN4QEgl3APIE @ 11770 NONAME
+	_ZN14QEglProperties19reduceConfigurationEv @ 11771 NONAME
+	_ZN14QEglProperties20setPaintDeviceFormatEP12QPaintDevice @ 11772 NONAME
+	_ZN14QEglProperties8setValueEii @ 11773 NONAME
+	_ZN14QEglPropertiesC1Ei @ 11774 NONAME
+	_ZN14QEglPropertiesC1Ev @ 11775 NONAME
+	_ZN14QEglPropertiesC2Ei @ 11776 NONAME
+	_ZN14QEglPropertiesC2Ev @ 11777 NONAME
+	_ZNK11QEglContext12configAttribEiPi @ 11778 NONAME
+	_ZNK11QEglContext16configPropertiesEi @ 11779 NONAME
+	_ZNK11QEglContext7isValidEv @ 11780 NONAME
+	_ZNK11QEglContext9isCurrentEv @ 11781 NONAME
+	_ZNK14QEglProperties5valueEi @ 11782 NONAME
+	_ZNK14QEglProperties8toStringEv @ 11783 NONAME
 	_ZNK11QFontEngine10glyphCacheEPvN21QFontEngineGlyphCache4TypeERK10QTransform @ 11784 NONAME
 	_ZNK20QGraphicsItemPrivate21effectiveBoundingRectERK6QRectF @ 11785 NONAME
@@ -11806,3 +11806,18 @@
 	_ZN9QS60Style10timerEventEP11QTimerEvent @ 11805 NONAME
 	_ZN9QS60Style11eventFilterEP7QObjectP6QEvent @ 11806 NONAME
+	_ZN11QEglContext10clearErrorEv @ 11807 NONAME
+	_ZN11QEglContext13nativeDisplayEv @ 11808 NONAME
+	_ZN11QEglContext14destroyContextEv @ 11809 NONAME
+	_ZN11QEglContext3dpyE @ 11810 NONAME DATA 4
+	_ZN11QEglContext5errorEv @ 11811 NONAME
+	_ZN11QEglContext7displayEv @ 11812 NONAME
+	_ZN11QFontEngine16getGlyphBearingsEjPfS0_ @ 11813 NONAME
+	_ZN12QLineControl17updateDisplayTextEb @ 11814 NONAME
+	_ZN13QFontDatabase25removeAllApplicationFontsEv @ 11815 NONAME
+	_ZN14QWidgetPrivate11inTabWidgetEP7QWidget @ 11816 NONAME
+	_ZN14QWidgetPrivate17canKeypadNavigateEN2Qt11OrientationE @ 11817 NONAME
+	_ZN20QGraphicsItemPrivate14setFocusHelperEN2Qt11FocusReasonEbb @ 11818 NONAME
+	_ZN20QGraphicsItemPrivate16clearFocusHelperEb @ 11819 NONAME
+	_ZN24QImagePixmapCleanupHooks13isImageCachedERK6QImage @ 11820 NONAME
+	_ZN24QImagePixmapCleanupHooks14isPixmapCachedERK7QPixmap @ 11821 NONAME
 
Index: trunk/src/s60installs/eabi/QtNetworku.def
===================================================================
--- trunk/src/s60installs/eabi/QtNetworku.def	(revision 766)
+++ trunk/src/s60installs/eabi/QtNetworku.def	(revision 769)
@@ -994,3 +994,5 @@
 	_ZN15QNetworkRequest20setOriginatingObjectEP7QObject @ 993 NONAME
 	_ZNK15QNetworkRequest17originatingObjectEv @ 994 NONAME
+	_Z19qt_qhostinfo_lookupRK7QStringP7QObjectPKcPbPi @ 995 NONAME
+	_Z24qt_qhostinfo_clear_cachev @ 996 NONAME
 
Index: trunk/src/s60installs/eabi/QtOpenVGu.def
===================================================================
--- trunk/src/s60installs/eabi/QtOpenVGu.def	(revision 766)
+++ trunk/src/s60installs/eabi/QtOpenVGu.def	(revision 769)
@@ -174,3 +174,28 @@
 	_ZN13QVGPixmapData22destroyImageAndContextEv @ 173 NONAME
 	_ZN13QVGPixmapData9hibernateEv @ 174 NONAME
+	_ZN12QVGImagePool11detachImageEP13QVGPixmapData @ 175 NONAME
+	_ZN12QVGImagePool12reclaimSpaceE13VGImageFormatllP13QVGPixmapData @ 176 NONAME
+	_ZN12QVGImagePool12releaseImageEP13QVGPixmapDatam @ 177 NONAME
+	_ZN12QVGImagePool12setImagePoolEPS_ @ 178 NONAME
+	_ZN12QVGImagePool13removeFromLRUEP13QVGPixmapData @ 179 NONAME
+	_ZN12QVGImagePool15moveToHeadOfLRUEP13QVGPixmapData @ 180 NONAME
+	_ZN12QVGImagePool20createImageForPixmapE13VGImageFormatllmP13QVGPixmapData @ 181 NONAME
+	_ZN12QVGImagePool20createPermanentImageE13VGImageFormatllm @ 182 NONAME
+	_ZN12QVGImagePool20createTemporaryImageE13VGImageFormatllmP13QVGPixmapData @ 183 NONAME
+	_ZN12QVGImagePool8instanceEv @ 184 NONAME
+	_ZN12QVGImagePool8useImageEP13QVGPixmapData @ 185 NONAME
+	_ZN12QVGImagePool9hibernateEv @ 186 NONAME
+	_ZN12QVGImagePool9pixmapLRUEv @ 187 NONAME
+	_ZN12QVGImagePoolC1Ev @ 188 NONAME
+	_ZN12QVGImagePoolC2Ev @ 189 NONAME
+	_ZN12QVGImagePoolD0Ev @ 190 NONAME
+	_ZN12QVGImagePoolD1Ev @ 191 NONAME
+	_ZN12QVGImagePoolD2Ev @ 192 NONAME
+	_ZN13QVGPixmapData13destroyImagesEv @ 193 NONAME
+	_ZN13QVGPixmapData13reclaimImagesEv @ 194 NONAME
+	_ZN13QVGPixmapData19detachImageFromPoolEv @ 195 NONAME
+	_ZTI12QVGImagePool @ 196 NONAME
+	_ZTV12QVGImagePool @ 197 NONAME
+	_ZN25QVGEGLWindowSurfaceDirect6scrollEP7QWidgetRK7QRegionii @ 198 NONAME
+	_ZNK25QVGEGLWindowSurfaceDirect22supportsStaticContentsEv @ 199 NONAME
 
Index: trunk/src/s60installs/qt.iby
===================================================================
--- trunk/src/s60installs/qt.iby	(revision 766)
+++ trunk/src/s60installs/qt.iby	(revision 769)
@@ -4,87 +4,54 @@
 #include <bldvariant.hrh>
 
-// Dependancies for more than one module
-#include <base.iby>
-#include <openenv.iby> // QtCore, QtGui, QtNetwork, QtOpenGL, QSvgIconEngine,
-#include <cone.iby> // QtGui, QtOpenGL
-#include <stdcpp.iby> // for std C++ support
-
-// QtGui dependancies
-#include <bafl.iby>
-#include <store.iby>
-#include <fntstore.iby>
-#include <ecom.iby>
-#include <fontutils.iby>
-#include <fepbase.iby>
-#include <fbserv.iby>
-#include <bitgdi.iby>
-#include <gdi.iby>
-#include <wserv.iby>
-#include <apparc.iby>
-#include <uikon.iby>
-#include <etext.iby>
-#include <emime.iby>
-#include <eikstd.iby>
-#include <mmf.iby>
-#include <avkon.iby>
-#include <commonui.iby>
-#include <platformenv.iby>
-#include <senduiservices.iby>
-#include <aknicon.iby>
-#include <aknskins.iby>
-
-// QtNetwork dependancies
-#include <esock_core.iby>
-#include <insock.iby>
-
-// QtOpenGL dependancies
-///@todo Problem here as we need libegl.dll and libglesv2.dll but they may come from a variety of places
-/// depending on the platform we're on
-
 #warning("qt.iby: hack - BINARY_SELECTION_ORDER really needs to be at the baseport/device level as it depends on the device type");
 BINARY_SELECTION_ORDER ARMV6,ARMV5 // hack - this really needs to be at the baseport/device level as it depends on the device type
 
-file=ABI_DIR\BUILD_DIR\QtCore.dll            SHARED_LIB_DIR\QtCore.dll       PAGED
-file=ABI_DIR\BUILD_DIR\QtGui.dll             SHARED_LIB_DIR\QtGui.dll        PAGED
-file=ABI_DIR\BUILD_DIR\QtOpenGL.dll          SHARED_LIB_DIR\QtOpenGL.dll     PAGED
-file=ABI_DIR\BUILD_DIR\QtOpenVG.dll          SHARED_LIB_DIR\QtOpenVG.dll     PAGED
-file=ABI_DIR\BUILD_DIR\QtSvg.dll             SHARED_LIB_DIR\QtSvg.dll        PAGED
-file=ABI_DIR\BUILD_DIR\QtSql.dll             SHARED_LIB_DIR\QtSql.dll        PAGED
-file=ABI_DIR\BUILD_DIR\QtXml.dll             SHARED_LIB_DIR\QtXml.dll        PAGED
-file=ABI_DIR\BUILD_DIR\QtNetwork.dll         SHARED_LIB_DIR\QtNetwork.dll    PAGED
-file=ABI_DIR\BUILD_DIR\QtScript.dll          SHARED_LIB_DIR\QtScript.dll     PAGED
-file=ABI_DIR\BUILD_DIR\QtTest.dll            SHARED_LIB_DIR\QtTest.dll       PAGED
-file=ABI_DIR\BUILD_DIR\QtWebKit.dll          SHARED_LIB_DIR\QtWebKit.dll     PAGED
-file=ABI_DIR\BUILD_DIR\phonon.dll            SHARED_LIB_DIR\phonon.dll       PAGED
-file=ABI_DIR\BUILD_DIR\QtMultimedia.dll      SHARED_LIB_DIR\QtMultimedia.dll PAGED
-file=ABI_DIR\BUILD_DIR\QtXmlPatterns.dll     SHARED_LIB_DIR\QtXmlPatterns.dll       PAGED
-file=ABI_DIR\BUILD_DIR\QtDeclarative.dll     SHARED_LIB_DIR\QtDeclarative.dll       PAGED
+file=ABI_DIR\BUILD_DIR\QtCore.dll            SHARED_LIB_DIR\QtCore.dll
+file=ABI_DIR\BUILD_DIR\QtGui.dll             SHARED_LIB_DIR\QtGui.dll
+file=ABI_DIR\BUILD_DIR\QtOpenVG.dll          SHARED_LIB_DIR\QtOpenVG.dll
+file=ABI_DIR\BUILD_DIR\QtSvg.dll             SHARED_LIB_DIR\QtSvg.dll
+file=ABI_DIR\BUILD_DIR\QtSql.dll             SHARED_LIB_DIR\QtSql.dll
+file=ABI_DIR\BUILD_DIR\QtXml.dll             SHARED_LIB_DIR\QtXml.dll
+file=ABI_DIR\BUILD_DIR\QtNetwork.dll         SHARED_LIB_DIR\QtNetwork.dll
+file=ABI_DIR\BUILD_DIR\QtScript.dll          SHARED_LIB_DIR\QtScript.dll
+file=ABI_DIR\BUILD_DIR\QtTest.dll            SHARED_LIB_DIR\QtTest.dll
+file=ABI_DIR\BUILD_DIR\QtWebKit.dll          SHARED_LIB_DIR\QtWebKit.dll
+file=ABI_DIR\BUILD_DIR\phonon.dll            SHARED_LIB_DIR\phonon.dll
+file=ABI_DIR\BUILD_DIR\QtMultimedia.dll      SHARED_LIB_DIR\QtMultimedia.dll
+file=ABI_DIR\BUILD_DIR\QtXmlPatterns.dll     SHARED_LIB_DIR\QtXmlPatterns.dll
 
 // imageformats
-file=ABI_DIR\BUILD_DIR\qgif.dll              SHARED_LIB_DIR\qgif.dll         PAGED
-file=ABI_DIR\BUILD_DIR\qico.dll              SHARED_LIB_DIR\qico.dll         PAGED
-file=ABI_DIR\BUILD_DIR\qjpeg.dll             SHARED_LIB_DIR\qjpeg.dll        PAGED
-file=ABI_DIR\BUILD_DIR\qmng.dll              SHARED_LIB_DIR\qmng.dll         PAGED
-file=ABI_DIR\BUILD_DIR\qsvg.dll              SHARED_LIB_DIR\qsvg.dll         PAGED
-file=ABI_DIR\BUILD_DIR\qtiff.dll             SHARED_LIB_DIR\qtiff.dll        PAGED
+file=ABI_DIR\BUILD_DIR\qgif.dll              SHARED_LIB_DIR\qgif.dll
+file=ABI_DIR\BUILD_DIR\qico.dll              SHARED_LIB_DIR\qico.dll
+file=ABI_DIR\BUILD_DIR\qjpeg.dll             SHARED_LIB_DIR\qjpeg.dll
+file=ABI_DIR\BUILD_DIR\qmng.dll              SHARED_LIB_DIR\qmng.dll
+file=ABI_DIR\BUILD_DIR\qsvg.dll              SHARED_LIB_DIR\qsvg.dll
+file=ABI_DIR\BUILD_DIR\qtiff.dll             SHARED_LIB_DIR\qtiff.dll
 
 // codecs
-file=ABI_DIR\BUILD_DIR\qcncodecs.dll         SHARED_LIB_DIR\qcncodecs.dll    PAGED
-file=ABI_DIR\BUILD_DIR\qjpcodecs.dll         SHARED_LIB_DIR\qjpcodecs.dll    PAGED
-file=ABI_DIR\BUILD_DIR\qkrcodecs.dll         SHARED_LIB_DIR\qkrcodecs.dll    PAGED
-file=ABI_DIR\BUILD_DIR\qtwcodecs.dll         SHARED_LIB_DIR\qtwcodecs.dll    PAGED
+file=ABI_DIR\BUILD_DIR\qcncodecs.dll         SHARED_LIB_DIR\qcncodecs.dll
+file=ABI_DIR\BUILD_DIR\qjpcodecs.dll         SHARED_LIB_DIR\qjpcodecs.dll
+file=ABI_DIR\BUILD_DIR\qkrcodecs.dll         SHARED_LIB_DIR\qkrcodecs.dll
+file=ABI_DIR\BUILD_DIR\qtwcodecs.dll         SHARED_LIB_DIR\qtwcodecs.dll
 
 // iconengines
-file=ABI_DIR\BUILD_DIR\qsvgicon.dll          SHARED_LIB_DIR\qsvgicon.dll     PAGED
+file=ABI_DIR\BUILD_DIR\qsvgicon.dll          SHARED_LIB_DIR\qsvgicon.dll
 
 // Phonon MMF backend
-file=ABI_DIR\BUILD_DIR\phonon_mmf.dll        SHARED_LIB_DIR\phonon_mmf.dll   PAGED
+// This is commented out by default, as normally Helix backend will be used.
+// If the Helix backend is present, it will override MMF backend, so make sure to remove it from
+// image creation in addition to uncommenting the following lines if you want to use MMF backend.
+//file=ABI_DIR\BUILD_DIR\phonon_mmf.dll        SHARED_LIB_DIR\phonon_mmf.dll
+//data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin
+
+// QtMultimedia audio backend
+file=ABI_DIR\BUILD_DIR\qaudio.dll            SHARED_LIB_DIR\qaudio.dll
 
 // graphicssystems
-file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll     PAGED
+file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll
 
 // S60 version compatibility plugins for 5.0 (3.1 and 3.2 devices are never likely to have this in ROM,
 // so don't bother including those plugins
-file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll   SHARED_LIB_DIR\qts60plugin_5_0.dll   PAGED
+file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll   SHARED_LIB_DIR\qts60plugin_5_0.dll
 
 S60_APP_RESOURCE(s60main)
@@ -107,6 +74,7 @@
 data=\epoc32\data\z\resource\qt\plugins\iconengines\qsvgicon.qtplugin      resource\qt\plugins\iconengines\qsvgicon.qtplugin
 
-// Phonon MMF backend
-data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin
+
+// QtMultimedia audio backend
+data=\epoc32\data\qt\qtlibspluginstubs\qaudio.qtplugin resource\qt\plugins\audio\qaudio.qtplugin
 
 // graphicssystems
@@ -114,5 +82,7 @@
 
 // Stub sis file
-data=ZSYSTEM\install\qt.sis    System\Install\qt.sis
+data=ZSYSTEM\install\qt_stub.sis    System\Install\qt_stub.sis
+data=ZSYSTEM\install\qtwebkit_stub.sis    System\Install\qtwebkit_stub.sis
 
 #endif // __QT_IBY__
+
Index: trunk/src/s60installs/s60installs.pro
===================================================================
--- trunk/src/s60installs/s60installs.pro	(revision 766)
+++ trunk/src/s60installs/s60installs.pro	(revision 769)
@@ -8,35 +8,47 @@
     # WARNING: Changing TARGET name will break Symbian SISX upgrade functionality
     # DO NOT TOUCH TARGET VARIABLE IF YOU ARE NOT SURE WHAT YOU ARE DOING
-    TARGET = "Qt"
-    TARGET.UID3 = 0x2001E61C
+    TARGET = "Qt$${QT_LIBINFIX}"
+
+    isEmpty(QT_LIBINFIX) {
+        TARGET.UID3 = 0x2001E61C
+
+        # sqlite3 is expected to be already found on phone if infixed configuration is built.
+        BLD_INF_RULES.prj_exports += \
+            "sqlite3.sis $${EPOCROOT}epoc32/data/qt/sis/sqlite3.sis" \
+            "sqlite3_selfsigned.sis $${EPOCROOT}epoc32/data/qt/sis/sqlite3_selfsigned.sis"
+        sqlitedeployment = \
+            "; Deploy sqlite onto phone that does not have it already" \
+            "@\"$${EPOCROOT}epoc32/data/qt/sis/sqlite3.sis\", (0x2002af5f)"
+        qtlibraries.pkg_postrules += sqlitedeployment
+    } else {
+        # Always use experimental UID for infixed configuration to avoid UID clash
+        TARGET.UID3 = 0xE001E61C
+    }
     VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
 
-    qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main.rsc
+    qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main$${QT_LIBINFIX}.rsc
     qtresources.path = c:$$APP_RESOURCE_DIR
+    DEPLOYMENT += qtresources
 
     qtlibraries.sources = \
-        QtCore.dll \
-        QtXml.dll \
-        QtGui.dll \
-        QtNetwork.dll \
-        QtTest.dll \
-        QtSql.dll
+        QtCore$${QT_LIBINFIX}.dll \
+        QtXml$${QT_LIBINFIX}.dll \
+        QtGui$${QT_LIBINFIX}.dll \
+        QtNetwork$${QT_LIBINFIX}.dll \
+        QtTest$${QT_LIBINFIX}.dll \
+        QtSql$${QT_LIBINFIX}.dll
 
     qts60plugindeployment = \
         "IF package(0x1028315F)" \
-        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \
+        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \
         "ELSEIF package(0x102752AE)" \
-        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_2.dll\" - \"c:\\sys\\bin\\qts60plugin_3_2.dll\"" \
+        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_2$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_3_2$${QT_LIBINFIX}.dll\"" \
         "ELSEIF package(0x102032BE)" \
-        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_1.dll\" - \"c:\\sys\\bin\\qts60plugin_3_1.dll\"" \
+        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_3_1$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_3_1$${QT_LIBINFIX}.dll\"" \
         "ELSE" \
-        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \
+        "   \"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \
         "ENDIF"
     qtlibraries.pkg_postrules += qts60plugindeployment
 
-    sqlitedeployment = \
-        "; Deploy sqlite onto phone that does not have it already" \
-        "@\"$$PWD/sqlite3.sis\", (0x2002af5f)"
-    qtlibraries.pkg_postrules += sqlitedeployment
 
     qtlibraries.path = c:/sys/bin
@@ -62,16 +74,16 @@
     qtlibraries.pkg_prerules += "(0x2002af5f), 0, 5, 0, {\"sqlite3\"}"
 
-    !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += qjpeg.dll
-    !contains(QT_CONFIG, no-gif):  imageformats_plugins.sources += qgif.dll
-    !contains(QT_CONFIG, no-mng):  imageformats_plugins.sources += qmng.dll
-    !contains(QT_CONFIG, no-tiff): imageformats_plugins.sources += qtiff.dll
-    !contains(QT_CONFIG, no-ico):  imageformats_plugins.sources += qico.dll
+    !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += qjpeg$${QT_LIBINFIX}.dll
+    !contains(QT_CONFIG, no-gif):  imageformats_plugins.sources += qgif$${QT_LIBINFIX}.dll
+    !contains(QT_CONFIG, no-mng):  imageformats_plugins.sources += qmng$${QT_LIBINFIX}.dll
+    !contains(QT_CONFIG, no-tiff): imageformats_plugins.sources += qtiff$${QT_LIBINFIX}.dll
+    !contains(QT_CONFIG, no-ico):  imageformats_plugins.sources += qico$${QT_LIBINFIX}.dll
     imageformats_plugins.path = c:$$QT_PLUGINS_BASE_DIR/imageformats
 
-    codecs_plugins.sources = qcncodecs.dll qjpcodecs.dll qtwcodecs.dll qkrcodecs.dll
+    codecs_plugins.sources = qcncodecs$${QT_LIBINFIX}.dll qjpcodecs$${QT_LIBINFIX}.dll qtwcodecs$${QT_LIBINFIX}.dll qkrcodecs$${QT_LIBINFIX}.dll
     codecs_plugins.path = c:$$QT_PLUGINS_BASE_DIR/codecs
 
     contains(QT_CONFIG, phonon-backend) {
-        phonon_backend_plugins.sources += phonon_mmf.dll
+        phonon_backend_plugins.sources += phonon_mmf$${QT_LIBINFIX}.dll
 
         phonon_backend_plugins.path = c:$$QT_PLUGINS_BASE_DIR/phonon_backend
@@ -83,10 +95,10 @@
     qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,)
 
-    DEPLOYMENT += qtresources qtlibraries qtbackup imageformats_plugins codecs_plugins graphicssystems_plugins
+    DEPLOYMENT += qtlibraries qtbackup imageformats_plugins codecs_plugins graphicssystems_plugins
 
     contains(QT_CONFIG, svg): {
-       qtlibraries.sources += QtSvg.dll
-       imageformats_plugins.sources += qsvg.dll
-       iconengines_plugins.sources = qsvgicon.dll
+       qtlibraries.sources += QtSvg$${QT_LIBINFIX}.dll
+       imageformats_plugins.sources += qsvg$${QT_LIBINFIX}.dll
+       iconengines_plugins.sources = qsvgicon$${QT_LIBINFIX}.dll
        iconengines_plugins.path = c:$$QT_PLUGINS_BASE_DIR/iconengines
        DEPLOYMENT += iconengines_plugins
@@ -94,30 +106,30 @@
 
     contains(QT_CONFIG, phonon): {
-       qtlibraries.sources += phonon.dll
+       qtlibraries.sources += phonon$${QT_LIBINFIX}.dll
     }
 
     contains(QT_CONFIG, script): {
-        qtlibraries.sources += QtScript.dll
+        qtlibraries.sources += QtScript$${QT_LIBINFIX}.dll
     }
 
     contains(QT_CONFIG, xmlpatterns): {
-       qtlibraries.sources += QtXmlPatterns.dll
+       qtlibraries.sources += QtXmlPatterns$${QT_LIBINFIX}.dll
     }
 
     contains(QT_CONFIG, declarative): {
-        qtlibraries.sources += QtDeclarative.dll
+        qtlibraries.sources += QtDeclarative$${QT_LIBINFIX}.dll
     }
 
     graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems
     contains(QT_CONFIG, openvg) {
-        qtlibraries.sources += QtOpenVG.dll
-        graphicssystems_plugins.sources += qvggraphicssystem.dll
+        qtlibraries.sources += QtOpenVG$${QT_LIBINFIX}.dll
+        graphicssystems_plugins.sources += qvggraphicssystem$${QT_LIBINFIX}.dll
     }
 
     contains(QT_CONFIG, multimedia) {
-        qtlibraries.sources += QtMultimedia.dll
+        qtlibraries.sources += QtMultimedia$${QT_LIBINFIX}.dll
     }
 
     BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)"
-    BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CORE_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)"
+    BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CUSTOMER_VARIANT_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)"
 }
Index: trunk/src/script/api/qscriptengine.cpp
===================================================================
--- trunk/src/script/api/qscriptengine.cpp	(revision 766)
+++ trunk/src/script/api/qscriptengine.cpp	(revision 769)
@@ -42,4 +42,5 @@
 #include <QtCore/qmetaobject.h>
 
+#include "CodeBlock.h"
 #include "Error.h"
 #include "JSArray.h"
@@ -663,5 +664,5 @@
             encoding = QCoreApplication::UnicodeUTF8;
         else
-            return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%s'").arg(encStr));
+            return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr));
     }
     int n = -1;
@@ -697,10 +698,19 @@
         return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string");
     if ((args.size() > 2) && !args.at(2).isNumber())
-        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number");
+        return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number");
 #ifndef QT_NO_QOBJECT
     QString context;
-    QScriptContext *ctx = QScriptEnginePrivate::contextForFrame(exec);
-    if (ctx && ctx->parentContext())
-        context = QFileInfo(QScriptContextInfo(ctx->parentContext()).fileName()).baseName();
+    // The first non-empty source URL in the call stack determines the translation context.
+    {
+        JSC::ExecState *frame = exec->removeHostCallFrameFlag();
+        while (frame) {
+            if (frame->codeBlock() && frame->codeBlock()->source()
+                && !frame->codeBlock()->source()->url().isEmpty()) {
+                context = QFileInfo(frame->codeBlock()->source()->url()).baseName();
+                break;
+            }
+            frame = frame->callerFrame()->removeHostCallFrameFlag();
+        }
+    }
 #endif
     QString text(args.at(0).toString(exec));
@@ -769,5 +779,5 @@
 
 QScriptEnginePrivate::QScriptEnginePrivate()
-    : registeredScriptValues(0), freeScriptValues(0),
+    : registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
       registeredScriptStrings(0), inEval(false)
 {
@@ -1008,9 +1018,13 @@
         return;
     QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject());
-    if (object == originalGlobalObjectProxy)
+    if (object == originalGlobalObjectProxy) {
         glob->customGlobalObject = 0;
-    else {
+        // Sync the internal prototype, since JSObject::prototype() is not virtual.
+        glob->setPrototype(originalGlobalObjectProxy->prototype());
+    } else {
         Q_ASSERT(object != originalGlobalObject());
         glob->customGlobalObject = object;
+        // Sync the internal prototype, since JSObject::prototype() is not virtual.
+        glob->setPrototype(object->prototype());
     }
 }
@@ -1590,5 +1604,5 @@
 #ifndef QT_NO_REGEXP
 
-extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
+Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
 
 /*!
@@ -2922,9 +2936,9 @@
     JSC::JSGlobalObject *glob = d->originalGlobalObject();
     if (!jscObject || !jscObject.isObject())
-        jscObject = glob;
+        jscObject = d->globalObject();
 //    unsigned attribs = JSC::DontEnum;
     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate));
     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp));
-    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
+    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::PrototypeFunction(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp));
 
Index: trunk/src/script/api/qscriptengine_p.h
===================================================================
--- trunk/src/script/api/qscriptengine_p.h	(revision 766)
+++ trunk/src/script/api/qscriptengine_p.h	(revision 769)
@@ -256,4 +256,6 @@
     QScriptValuePrivate *registeredScriptValues;
     QScriptValuePrivate *freeScriptValues;
+    static const int maxFreeScriptValues = 256;
+    int freeScriptValuesCount;
     QScriptStringPrivate *registeredScriptStrings;
     QHash<int, QScriptTypeInfo*> m_typeInfos;
@@ -378,4 +380,5 @@
         QScriptValuePrivate *p = freeScriptValues;
         freeScriptValues = p->next;
+        --freeScriptValuesCount;
         return p;
     }
@@ -385,6 +388,11 @@
 inline void QScriptEnginePrivate::freeScriptValuePrivate(QScriptValuePrivate *p)
 {
-    p->next = freeScriptValues;
-    freeScriptValues = p;
+    if (freeScriptValuesCount < maxFreeScriptValues) {
+        p->next = freeScriptValues;
+        freeScriptValues = p;
+        ++freeScriptValuesCount;
+    } else {
+        qFree(p);
+    }
 }
 
Index: trunk/src/script/api/qscriptvalue.cpp
===================================================================
--- trunk/src/script/api/qscriptvalue.cpp	(revision 766)
+++ trunk/src/script/api/qscriptvalue.cpp	(revision 769)
@@ -793,4 +793,5 @@
         return;
     }
+    JSC::JSObject *thisObject = JSC::asObject(d->jscValue);
     JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype);
 
@@ -799,5 +800,5 @@
     while (nextPrototypeValue && nextPrototypeValue.isObject()) {
         JSC::JSObject *nextPrototype = JSC::asObject(nextPrototypeValue);
-        if (nextPrototype == JSC::asObject(d->jscValue)) {
+        if (nextPrototype == thisObject) {
             qWarning("QScriptValue::setPrototype() failed: cyclic prototype value");
             return;
@@ -805,5 +806,13 @@
         nextPrototypeValue = nextPrototype->prototype();
     }
-    JSC::asObject(d->jscValue)->setPrototype(other);
+
+    thisObject->setPrototype(other);
+
+    // Sync the internal Global Object prototype if appropriate.
+    if (((thisObject == d->engine->originalGlobalObjectProxy)
+         && !d->engine->customGlobalObject())
+        || (thisObject == d->engine->customGlobalObject())) {
+        d->engine->originalGlobalObject()->setPrototype(other);
+    }
 }
 
@@ -1149,8 +1158,13 @@
 
     if (d->type != other.d_ptr->type) {
-        if (d->type == QScriptValuePrivate::JavaScriptCore)
-            return JSC::JSValue::strictEqual(d->jscValue, d->engine->scriptValueToJSCValue(other));
-        else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore)
-            return JSC::JSValue::strictEqual(other.d_ptr->engine->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
+        if (d->type == QScriptValuePrivate::JavaScriptCore) {
+            QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
+            if (eng_p)
+                return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other));
+        } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) {
+            QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine;
+            if (eng_p)
+                return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
+        }
 
         return false;
@@ -1942,5 +1956,5 @@
     if (!array.isUndefinedOrNull()) {
         if (!array.isObject()) {
-            return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError));
+            return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
         }
         if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
@@ -1953,6 +1967,5 @@
                 applyArgs.append(JSC::asArray(array)->get(exec, i));
         } else {
-            Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
-//            return JSC::throwError(exec, JSC::TypeError);
+            return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
         }
     }
Index: trunk/src/script/bridge/qscriptclassobject.cpp
===================================================================
--- trunk/src/script/bridge/qscriptclassobject.cpp	(revision 766)
+++ trunk/src/script/bridge/qscriptclassobject.cpp	(revision 769)
@@ -227,5 +227,5 @@
 
     QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
-    //JSC::ExecState *oldFrame = eng_p->currentFrame;
+    JSC::ExecState *oldFrame = eng_p->currentFrame;
     eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
     QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
@@ -235,4 +235,6 @@
     if (!result.isObject())
         result = defaultObject;
+    eng_p->popContext();
+    eng_p->currentFrame = oldFrame;
     return JSC::asObject(eng_p->scriptValueToJSCValue(result));
 }
Index: trunk/src/script/bridge/qscriptqobject_p.h
===================================================================
--- trunk/src/script/bridge/qscriptqobject_p.h	(revision 766)
+++ trunk/src/script/bridge/qscriptqobject_p.h	(revision 769)
@@ -305,5 +305,5 @@
     static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
     {
-        return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));
+        return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance));
     }
 
Index: trunk/src/script/parser/qscriptlexer.cpp
===================================================================
--- trunk/src/script/parser/qscriptlexer.cpp	(revision 766)
+++ trunk/src/script/parser/qscriptlexer.cpp	(revision 769)
@@ -32,5 +32,5 @@
 QT_BEGIN_NAMESPACE
 
-extern double qstrtod(const char *s00, char const **se, bool *ok);
+Q_DECL_IMPORT extern double qstrtod(const char *s00, char const **se, bool *ok);
 
 #define shiftWindowsLineBreak() \
Index: trunk/src/sql/drivers/drivers.pri
===================================================================
--- trunk/src/sql/drivers/drivers.pri	(revision 766)
+++ trunk/src/sql/drivers/drivers.pri	(revision 769)
@@ -50,4 +50,5 @@
      mac:!contains( LIBS, .*odbc.* ):LIBS        *= -liodbc
      unix:!contains( LIBS, .*odbc.* ):LIBS       *= -lodbc
+     unix:DEFINES += UNICODE
 
      win32 {
Index: trunk/src/sql/drivers/mysql/qsql_mysql.cpp
===================================================================
--- trunk/src/sql/drivers/mysql/qsql_mysql.cpp	(revision 766)
+++ trunk/src/sql/drivers/mysql/qsql_mysql.cpp	(revision 769)
@@ -321,4 +321,14 @@
 }
 
+static bool qIsInteger(int t)
+{
+    return t == MYSQL_TYPE_TINY
+           || t == MYSQL_TYPE_SHORT
+           || t == MYSQL_TYPE_LONG
+           || t == MYSQL_TYPE_LONGLONG
+           || t == MYSQL_TYPE_INT24;
+}
+
+
 void QMYSQLResultPrivate::bindBlobs()
 {
@@ -369,4 +379,11 @@
             hasBlobs = true;
         } else {
+            // fieldInfo->length specifies the display width, which may be too
+            // small to hold valid integer values (see
+            // http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html ), so
+            // always use the MAX_BIGINT_WIDTH for integer types
+            if (qIsInteger(fieldInfo->type)) {
+                fieldInfo->length = MAX_BIGINT_WIDTH;
+            }
             fieldInfo->type = MYSQL_TYPE_STRING;
         }
Index: trunk/src/sql/drivers/oci/qsql_oci.cpp
===================================================================
--- trunk/src/sql/drivers/oci/qsql_oci.cpp	(revision 766)
+++ trunk/src/sql/drivers/oci/qsql_oci.cpp	(revision 769)
@@ -518,5 +518,5 @@
     else if (ocitype == QLatin1String("LONG") || ocitype == QLatin1String("NCLOB")
              || ocitype == QLatin1String("CLOB"))
-        type = QVariant::String;
+        type = QVariant::ByteArray;
     else if (ocitype == QLatin1String("RAW") || ocitype == QLatin1String("LONG RAW")
              || ocitype == QLatin1String("ROWID") || ocitype == QLatin1String("BLOB")
@@ -544,5 +544,4 @@
     case SQLT_RDD:
     case SQLT_LNG:
-    case SQLT_CLOB:
 #ifdef SQLT_INTERVAL_YM
     case SQLT_INTERVAL_YM:
@@ -582,4 +581,5 @@
     case SQLT_LVB:
     case SQLT_BLOB:
+    case SQLT_CLOB:
     case SQLT_FILE:
     case SQLT_NTY:
Index: trunk/src/sql/drivers/odbc/qsql_odbc.cpp
===================================================================
--- trunk/src/sql/drivers/odbc/qsql_odbc.cpp	(revision 766)
+++ trunk/src/sql/drivers/odbc/qsql_odbc.cpp	(revision 769)
@@ -67,5 +67,5 @@
 # undef UNICODE
 # define SQLTCHAR SQLCHAR
-# define SQL_C_WCHAR SQL_C_CHAR
+# define SQL_C_TCHAR SQL_C_CHAR
 #endif
 
@@ -79,9 +79,52 @@
 #endif
 
-
 static const int COLNAMESIZE = 256;
 //Map Qt parameter types to ODBC types
 static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT };
 
+inline static QString fromSQLTCHAR(const QVarLengthArray<SQLTCHAR>& input, int size=-1)
+{
+    QString result;
+
+    int realsize = qMin(size, input.size());
+    if(realsize > 0 && input[realsize-1] == 0)
+        realsize--;
+    switch(sizeof(SQLTCHAR)) {
+        case 1:
+            result=QString::fromUtf8((const char *)input.constData(), realsize);
+            break;
+        case 2:
+            result=QString::fromUtf16((const ushort *)input.constData(), realsize);
+            break;
+        case 4:
+            result=QString::fromUcs4((const uint *)input.constData(), realsize);
+            break;
+        default:
+            qCritical() << "sizeof(SQLTCHAR) is " << sizeof(SQLTCHAR) << "Don't know how to handle this";
+    }
+    return result;
+}
+
+inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input)
+{
+    QVarLengthArray<SQLTCHAR> result;
+    result.resize(input.size());
+    switch(sizeof(SQLTCHAR)) {
+        case 1:
+            memcpy(result.data(), input.toUtf8().data(), input.size());
+            break;
+        case 2:
+            memcpy(result.data(), input.unicode(), input.size() * 2);
+            break;
+        case 4:
+            memcpy(result.data(), input.toUcs4().data(), input.size() * 4);
+            break;
+        default:
+            qCritical() << "sizeof(SQLTCHAR) is " << sizeof(SQLTCHAR) << "Don't know how to handle this";
+    }
+    result.append(0); // make sure it's null terminated, doesn't matter if it already is, it does if it isn't.
+    return result;
+}
+
 class QODBCDriverPrivate
 {
@@ -89,9 +132,8 @@
     enum DefaultCase{Lower, Mixed, Upper, Sensitive};
     QODBCDriverPrivate()
-    : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false),
-           isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false),
-           isQuoteInitialized(false), quote(QLatin1Char('"'))
+    : hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), isMySqlServer(false),
+           isMSSqlServer(false), isFreeTDSDriver(false), hasSQLFetchScroll(true),
+           hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
     {
-        unicode = false;
     }
 
@@ -99,9 +141,10 @@
     SQLHANDLE hDbc;
 
-    uint unicode :1;
-    uint useSchema :1;
+    bool unicode;
+    bool useSchema;
     int disconnectCount;
     bool isMySqlServer;
     bool isMSSqlServer;
+    bool isFreeTDSDriver;
     bool hasSQLFetchScroll;
     bool hasMultiResultSets;
@@ -130,5 +173,8 @@
     : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false)
     {
-        unicode = false;
+        unicode = dpp->unicode;
+        useSchema = dpp->useSchema;
+        disconnectCount = dpp->disconnectCount;
+        hasSQLFetchScroll = dpp->hasSQLFetchScroll;
     }
 
@@ -140,6 +186,6 @@
     SQLHANDLE hStmt;
 
-    uint unicode :1;
-    uint useSchema :1;
+    bool unicode;
+    bool useSchema;
 
     QSqlRecord rInf;
@@ -178,16 +224,15 @@
 
     description_[0] = 0;
-    r = SQLGetDiagRec(handleType,
-                      handle,
-                      i,
-                      state_,
-                      &nativeCode_,
-                      0,
-                      NULL,
-                      &msgLen);
-    if(r == SQL_NO_DATA)
-        return QString();
-    description_.resize(msgLen+1);
     do {
+        r = SQLGetDiagRec(handleType,
+                          handle,
+                          i,
+                          state_,
+                          &nativeCode_,
+                          0,
+                          NULL,
+                          &msgLen);
+        if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && msgLen > 0)
+            description_.resize(msgLen+1);
         r = SQLGetDiagRec(handleType,
                             handle,
@@ -203,7 +248,7 @@
             QString tmpstore;
 #ifdef UNICODE
-            tmpstore = QString((const QChar*)description_.data(), msgLen);
+            tmpstore = fromSQLTCHAR(description_, msgLen);
 #else
-            tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen);
+            tmpstore = QString::fromUtf8((const char*)description_.constData(), msgLen);
 #endif
             if(result != tmpstore) {
@@ -224,5 +269,5 @@
     return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->dpEnv()) + QLatin1Char(' ')
              + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->dpDbc()) + QLatin1Char(' ')
-             + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode));
+             + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode)).simplified();
 }
 
@@ -230,5 +275,5 @@
 {
     return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ')
-             + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode));
+             + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode)).simplified();
 }
 
@@ -308,5 +353,7 @@
     case SQL_CHAR:
     case SQL_VARCHAR:
+#if (ODBCVER >= 0x0350)
     case SQL_GUID:
+#endif
     case SQL_LONGVARCHAR:
         type = QVariant::String;
@@ -332,43 +379,87 @@
     } else {
         colSize++; // make sure there is room for more than the 0 termination
-        if (unicode) {
-            colSize *= 2; // a tiny bit faster, since it saves a SQLGetData() call
-        }
-    }
-    QVarLengthArray<char> buf(colSize);
-    while (true) {
+    }
+    if(unicode) {
         r = SQLGetData(hStmt,
                         column+1,
-                        unicode ? SQL_C_WCHAR : SQL_C_CHAR,
-                        (SQLPOINTER)buf.data(),
-                        colSize,
+                        SQL_C_TCHAR,
+                        NULL,
+                        0,
                         &lengthIndicator);
-        if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
-            if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
+        if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
+            colSize = lengthIndicator/sizeof(SQLTCHAR) + 1;
+        QVarLengthArray<SQLTCHAR> buf(colSize);
+        memset(buf.data(), 0, colSize*sizeof(SQLTCHAR));
+        while (true) {
+            r = SQLGetData(hStmt,
+                            column+1,
+                            SQL_C_TCHAR,
+                            (SQLPOINTER)buf.data(),
+                            colSize*sizeof(SQLTCHAR),
+                            &lengthIndicator);
+            if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+                if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
+                    fieldVal.clear();
+                    break;
+                }
+                // if SQL_SUCCESS_WITH_INFO is returned, indicating that
+                // more data can be fetched, the length indicator does NOT
+                // contain the number of bytes returned - it contains the
+                // total number of bytes that CAN be fetched
+                // colSize-1: remove 0 termination when there is more data to fetch
+                int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR);
+                    fieldVal += fromSQLTCHAR(buf, rSize);
+                if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) {
+                    // workaround for Drivermanagers that don't return SQL_NO_DATA
+                    break;
+                }
+            } else if (r == SQL_NO_DATA) {
+                break;
+            } else {
+                qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
                 fieldVal.clear();
                 break;
             }
-            // if SQL_SUCCESS_WITH_INFO is returned, indicating that
-            // more data can be fetched, the length indicator does NOT
-            // contain the number of bytes returned - it contains the
-            // total number of bytes that CAN be fetched
-            // colSize-1: remove 0 termination when there is more data to fetch
-            int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-2 : colSize-1) : lengthIndicator;
-            if (unicode) {
-                fieldVal += QString((const QChar*) buf.constData(), rSize / 2);
+        }
+    } else {
+        r = SQLGetData(hStmt,
+                        column+1,
+                        SQL_C_CHAR,
+                        NULL,
+                        0,
+                        &lengthIndicator);
+        if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
+            colSize = lengthIndicator + 1;
+        QVarLengthArray<SQLCHAR> buf(colSize);
+        while (true) {
+            r = SQLGetData(hStmt,
+                            column+1,
+                            SQL_C_CHAR,
+                            (SQLPOINTER)buf.data(),
+                            colSize,
+                            &lengthIndicator);
+            if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+                if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
+                    fieldVal.clear();
+                    break;
+                }
+                // if SQL_SUCCESS_WITH_INFO is returned, indicating that
+                // more data can be fetched, the length indicator does NOT
+                // contain the number of bytes returned - it contains the
+                // total number of bytes that CAN be fetched
+                // colSize-1: remove 0 termination when there is more data to fetch
+                int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator;
+                    fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize);
+                if (lengthIndicator < (unsigned int)colSize) {
+                    // workaround for Drivermanagers that don't return SQL_NO_DATA
+                    break;
+                }
+            } else if (r == SQL_NO_DATA) {
+                break;
             } else {
-                fieldVal += QString::fromAscii(buf.constData(), rSize);
-            }
-            memset(buf.data(), 0, colSize);
-            if (lengthIndicator < colSize) {
-                // workaround for Drivermanagers that don't return SQL_NO_DATA
+                qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
+                fieldVal.clear();
                 break;
             }
-        } else if (r == SQL_NO_DATA) {
-            break;
-        } else {
-            qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
-            fieldVal.clear();
-            break;
         }
     }
@@ -387,8 +478,9 @@
     SQLRETURN r = SQL_ERROR;
 
-    SQLTCHAR colName[COLNAMESIZE];
+    QVarLengthArray<SQLTCHAR> colName(COLNAMESIZE);
+
     r = SQLDescribeCol(hStmt,
                        column + 1,
-                       colName,
+                       colName.data(),
                        COLNAMESIZE,
                        &colNameLen,
@@ -523,8 +615,8 @@
     SQLSMALLINT nullable;
     SQLRETURN r = SQL_ERROR;
-    SQLTCHAR colName[COLNAMESIZE];
+    QVarLengthArray<SQLTCHAR> colName(COLNAMESIZE);
     r = SQLDescribeCol(p->hStmt,
                         i+1,
-                        colName,
+                        colName.data(),
                         (SQLSMALLINT)COLNAMESIZE,
                         &colNameLen,
@@ -552,7 +644,7 @@
 
 #ifdef UNICODE
-    QString qColName((const QChar*)colName, colNameLen);
+    QString qColName(fromSQLTCHAR(colName, colNameLen));
 #else
-    QString qColName = QString::fromLocal8Bit((const char*)colName);
+    QString qColName = QString::fromUtf8((const char *)colName.constData());
 #endif
     // nullable can be SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN
@@ -582,5 +674,11 @@
         return SQL_OV_ODBC3;
 #endif
+    if (connOpts.contains(QLatin1String("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC2"), Qt::CaseInsensitive))
+        return SQL_OV_ODBC2;
+#ifdef _IODBCUNIX_H
+    return SQL_OV_ODBC3;
+#else
     return SQL_OV_ODBC2;
+#endif
 }
 
@@ -588,5 +686,5 @@
 {
     if (!isQuoteInitialized) {
-        char driverResponse[4];
+        SQLTCHAR driverResponse[4];
         SQLSMALLINT length;
         int r = SQLGetInfo(hDbc,
@@ -595,9 +693,12 @@
                 sizeof(driverResponse),
                 &length);
-        if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+        if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
+#ifdef UNICODE
+            quote = QChar(driverResponse[0]);
+#else
             quote = QLatin1Char(driverResponse[0]);
-        } else {
+#endif
+        else
             quote = QLatin1Char('"');
-        }
         isQuoteInitialized = true;
     }
@@ -643,9 +744,9 @@
             r = SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG,
 #ifdef UNICODE
-                                    (SQLWCHAR*) val.unicode(),
+                                    toSQLTCHAR(val).data(),
 #else
-                                    (SQLCHAR*) val.toLatin1().constData(),
-#endif
-                                    SQL_NTS);
+                                    (SQLCHAR*) val.toUtf8().data(),
+#endif
+                                    val.length()*sizeof(SQLTCHAR));
         } else if (opt.toUpper() == QLatin1String("SQL_ATTR_METADATA_ID")) {
             if (val.toUpper() == QLatin1String("SQL_TRUE")) {
@@ -665,9 +766,9 @@
             r = SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE,
 #ifdef UNICODE
-                                    (SQLWCHAR*) val.unicode(),
+                                    toSQLTCHAR(val).data(),
 #else
-                                    (SQLCHAR*) val.toLatin1().constData(),
-#endif
-                                    SQL_NTS);
+                                    (SQLCHAR*) val.toUtf8().data(),
+#endif
+                                    val.length()*sizeof(SQLTCHAR));
         } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACE")) {
             if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_OFF")) {
@@ -815,8 +916,4 @@
 {
     d = new QODBCPrivate(p);
-    d->unicode = p->unicode;
-    d->useSchema = p->useSchema;
-    d->disconnectCount = p->disconnectCount;
-    d->hasSQLFetchScroll = p->hasSQLFetchScroll;
 }
 
@@ -881,10 +978,10 @@
 #ifdef UNICODE
     r = SQLExecDirect(d->hStmt,
-                       (SQLWCHAR*) query.unicode(),
+                       toSQLTCHAR(query).data(),
                        (SQLINTEGER) query.length());
 #else
-    QByteArray query8 = query.toLocal8Bit();
+    QByteArray query8 = query.toUtf8();
     r = SQLExecDirect(d->hStmt,
-                       (SQLCHAR*) query8.constData(),
+                       (SQLCHAR*) query8.data(),
                        (SQLINTEGER) query8.length());
 #endif
@@ -1232,10 +1329,10 @@
 #ifdef UNICODE
     r = SQLPrepare(d->hStmt,
-                    (SQLWCHAR*) query.unicode(),
+                    toSQLTCHAR(query).data(),
                     (SQLINTEGER) query.length());
 #else
-    QByteArray query8 = query.toLocal8Bit();
+    QByteArray query8 = query.toUtf8();
     r = SQLPrepare(d->hStmt,
-                    (SQLCHAR*) query8.constData(),
+                    (SQLCHAR*) query8.data(),
                     (SQLINTEGER) query8.length());
 #endif
@@ -1436,15 +1533,15 @@
                 if (d->unicode) {
                     QString str = val.toString();
-                    str.utf16();
                     if (*ind != SQL_NULL_DATA)
-                        *ind = str.length() * sizeof(QChar);
-                    int strSize = str.length() * sizeof(QChar);
+                        *ind = str.length() * sizeof(SQLTCHAR);
+                    int strSize = str.length() * sizeof(SQLTCHAR);
 
                     if (bindValueType(i) & QSql::Out) {
-                        QByteArray ba((char*)str.constData(), str.capacity() * sizeof(QChar));
+                        QVarLengthArray<SQLTCHAR> ba(toSQLTCHAR(str));
+                        ba.reserve(str.capacity());
                         r = SQLBindParameter(d->hStmt,
                                             i + 1,
                                             qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
-                                            SQL_C_WCHAR,
+                                            SQL_C_TCHAR,
                                             strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
                                             0, // god knows... don't change this!
@@ -1453,18 +1550,19 @@
                                             ba.size(),
                                             ind);
-                        tmpStorage.append(ba);
+                        tmpStorage.append(QByteArray((const char *)ba.constData(), ba.size()*sizeof(SQLTCHAR)));
                         break;
                     }
-
+                    QByteArray strba((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
                     r = SQLBindParameter(d->hStmt,
                                           i + 1,
                                           qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
-                                          SQL_C_WCHAR,
+                                          SQL_C_TCHAR,
                                           strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
                                           strSize,
                                           0,
-                                          (void *)str.constData(),
-                                          strSize,
+                                          (SQLPOINTER)strba.constData(),
+                                          strba.size(),
                                           ind);
+                    tmpStorage.append(strba);
                     break;
                 }
@@ -1472,5 +1570,5 @@
 #endif
                 {
-                    QByteArray str = val.toString().toAscii();
+                    QByteArray str = val.toString().toUtf8();
                     if (*ind != SQL_NULL_DATA)
                         *ind = str.length();
@@ -1573,13 +1671,16 @@
             case QVariant::String:
                 if (d->unicode) {
-                    if (bindValueType(i) & QSql::Out)
-                        values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData());
+                    if (bindValueType(i) & QSql::Out) {
+                        QByteArray first = tmpStorage.takeFirst();
+                        QVarLengthArray<SQLTCHAR> array;
+                        array.append((SQLTCHAR *)first.constData(), first.size());
+                        values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR*));
+                    }
                     break;
                 }
                 // fall through
             default: {
-                QByteArray ba = tmpStorage.takeFirst();
                 if (bindValueType(i) & QSql::Out)
-                    values[i] = QString::fromAscii(ba.constData());
+                    values[i] = tmpStorage.takeFirst();
                 break; }
         }
@@ -1790,17 +1891,19 @@
 
     SQLSMALLINT cb;
-    SQLTCHAR connOut[1024];
+    QVarLengthArray<SQLTCHAR> connOut(1024);
+    memset(connOut.data(), 0, connOut.size() * sizeof(SQLTCHAR));
     r = SQLDriverConnect(d->hDbc,
                           NULL,
 #ifdef UNICODE
-                          (SQLWCHAR*)connQStr.unicode(),
+                          toSQLTCHAR(connQStr).data(),
 #else
-                          (SQLCHAR*)connQStr.toLatin1().constData(),
+                          (SQLCHAR*)connQStr.toUtf8().data(),
 #endif
                           (SQLSMALLINT)connQStr.length(),
-                          connOut,
+                          connOut.data(),
                           1024,
                           &cb,
-                          SQL_DRIVER_NOPROMPT);
+                          /*SQL_DRIVER_NOPROMPT*/0);
+
     if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
         setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d));
@@ -1887,4 +1990,5 @@
     if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) {
         unicode = true;
+        return;
     }
 
@@ -1896,4 +2000,5 @@
     if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) {
         unicode = true;
+        return;
     }
 
@@ -1905,5 +2010,23 @@
     if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) {
         unicode = true;
-    }
+        return;
+    }
+    SQLHANDLE hStmt;
+    r = SQLAllocHandle(SQL_HANDLE_STMT,
+                                  hDbc,
+                                  &hStmt);
+
+    r = SQLExecDirect(hStmt, toSQLTCHAR(QLatin1String("select 'test'")).data(), SQL_NTS);
+    if(r == SQL_SUCCESS) {
+        r = SQLFetch(hStmt);
+        if(r == SQL_SUCCESS) {
+            QVarLengthArray<SQLWCHAR> buffer(10);
+            r = SQLGetData(hStmt, 1, SQL_C_WCHAR, buffer.data(), buffer.size() * sizeof(SQLWCHAR), NULL);
+            if(r == SQL_SUCCESS && fromSQLTCHAR(buffer) == QLatin1String("test")) {
+                unicode = true;
+            }
+        }
+    }
+    r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
 }
 
@@ -1978,21 +2101,37 @@
 {
     SQLRETURN   r;
-    char serverString[200];
+    QVarLengthArray<SQLTCHAR> serverString(200);
     SQLSMALLINT t;
+    memset(serverString.data(), 0, serverString.size() * sizeof(SQLTCHAR));
 
     r = SQLGetInfo(hDbc,
                    SQL_DBMS_NAME,
-                   serverString,
-                   sizeof(serverString),
+                   serverString.data(),
+                   serverString.size() * sizeof(SQLTCHAR),
                    &t);
     if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
         QString serverType;
 #ifdef UNICODE
-        serverType = QString(reinterpret_cast<const QChar*>(serverString), t/sizeof(QChar));
+        serverType = fromSQLTCHAR(serverString, t/sizeof(SQLTCHAR));
 #else
-        serverType = QString::fromLocal8Bit(serverString, t);
+        serverType = QString::fromUtf8((const char *)serverString.constData(), t);
 #endif
         isMySqlServer = serverType.contains(QLatin1String("mysql"), Qt::CaseInsensitive);
         isMSSqlServer = serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive);
+    }
+    r = SQLGetInfo(hDbc,
+                   SQL_DRIVER_NAME,
+                   serverString.data(),
+                   serverString.size() * sizeof(SQLTCHAR),
+                   &t);
+    if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+        QString serverType;
+#ifdef UNICODE
+        serverType = fromSQLTCHAR(serverString, t/sizeof(SQLTCHAR));
+#else
+        serverType = QString::fromUtf8((const char *)serverString.constData(), t);
+#endif
+        isFreeTDSDriver = serverType.contains(QLatin1String("tdsodbc"), Qt::CaseInsensitive);
+        unicode = isFreeTDSDriver == false;
     }
 }
@@ -2010,16 +2149,16 @@
 void QODBCDriverPrivate::checkHasMultiResults()
 {
-    char driverResponse[4];
+    QVarLengthArray<SQLTCHAR> driverResponse(2);
     SQLSMALLINT length;
     SQLRETURN r = SQLGetInfo(hDbc,
                              SQL_MULT_RESULT_SETS,
-                             driverResponse,
-                             sizeof(driverResponse),
+                             driverResponse.data(),
+                             driverResponse.size() * sizeof(SQLTCHAR),
                              &length);
     if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
 #ifdef UNICODE
-        hasMultiResultSets = QString(reinterpret_cast<const QChar*>(driverResponse), length/sizeof(QChar)).startsWith(QLatin1Char('Y'));
+        hasMultiResultSets = fromSQLTCHAR(driverResponse, length/sizeof(SQLTCHAR)).startsWith(QLatin1Char('Y'));
 #else
-        hasMultiResultSets = QString::fromLocal8Bit(driverResponse, length).startsWith(QLatin1Char('Y'));
+        hasMultiResultSets = QString::fromUtf8((const char *)driverResponse.constData(), length).startsWith(QLatin1Char('Y'));
 #endif
 }
@@ -2135,7 +2274,7 @@
                    0,
 #ifdef UNICODE
-                   (SQLWCHAR*)joinedTableTypeString.unicode(),
+                   toSQLTCHAR(joinedTableTypeString).data(),
 #else
-                   (SQLCHAR*)joinedTableTypeString.toLatin1().constData(),
+                   (SQLCHAR*)joinedTableTypeString.toUtf8().data(),
 #endif
                    joinedTableTypeString.length() /* characters, not bytes */);
@@ -2150,4 +2289,9 @@
     else
         r = SQLFetch(hStmt);
+
+    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) {
+        qWarning() << "QODBCDriver::tables failed to retrieve table/view list: (" << r << "," << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ")";
+        return QStringList();
+    }
 
     while (r == SQL_SUCCESS) {
@@ -2209,19 +2353,19 @@
     r = SQLPrimaryKeys(hStmt,
 #ifdef UNICODE
-                        catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(),
+                        catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(),
 #else
-                        catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toLatin1().constData(),
+                        catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toUtf8().data(),
 #endif
                         catalog.length(),
 #ifdef UNICODE
-                        schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),
+                        schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
 #else
-                        schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(),
+                        schema.length() == 0 ? NULL : (SQLCHAR*)schema.toUtf8().data(),
 #endif
                         schema.length(),
 #ifdef UNICODE
-                        (SQLWCHAR*)table.unicode(),
+                        toSQLTCHAR(table).data(),
 #else
-                        (SQLCHAR*)table.toLatin1().constData(),
+                        (SQLCHAR*)table.toUtf8().data(),
 #endif
                         table.length() /* in characters, not in bytes */);
@@ -2234,19 +2378,19 @@
                         SQL_BEST_ROWID,
 #ifdef UNICODE
-                        catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(),
+                        catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(),
 #else
-                        catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toLatin1().constData(),
+                        catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toUtf8().data(),
 #endif
                         catalog.length(),
 #ifdef UNICODE
-                        schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),
+                        schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
 #else
-                        schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(),
+                        schema.length() == 0 ? NULL : (SQLCHAR*)schema.toUtf8().data(),
 #endif
                         schema.length(),
 #ifdef UNICODE
-                        (SQLWCHAR*)table.unicode(),
+                        toSQLTCHAR(table).data(),
 #else
-                        (SQLCHAR*)table.toLatin1().constData(),
+                        (SQLCHAR*)table.toUtf8().data(),
 #endif
                         table.length(),
@@ -2334,19 +2478,19 @@
     r =  SQLColumns(hStmt,
 #ifdef UNICODE
-                     catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(),
+                     catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(),
 #else
-                     catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toLatin1().constData(),
+                     catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toUtf8().data(),
 #endif
                      catalog.length(),
 #ifdef UNICODE
-                     schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),
+                     schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(),
 #else
-                     schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(),
+                     schema.length() == 0 ? NULL : (SQLCHAR*)schema.toUtf8().data(),
 #endif
                      schema.length(),
 #ifdef UNICODE
-                     (SQLWCHAR*)table.unicode(),
+                     toSQLTCHAR(table).data(),
 #else
-                     (SQLCHAR*)table.toLatin1().constData(),
+                     (SQLCHAR*)table.toUtf8().data(),
 #endif
                      table.length(),
Index: trunk/src/sql/drivers/odbc/qsql_odbc.h
===================================================================
--- trunk/src/sql/drivers/odbc/qsql_odbc.h	(revision 766)
+++ trunk/src/sql/drivers/odbc/qsql_odbc.h	(revision 769)
@@ -74,8 +74,4 @@
 #if defined(Q_CC_BOR)
 #  undef _MSC_VER
-#endif
-
-#ifndef Q_ODBC_VERSION_2
-#include <sqlucode.h>
 #endif
 
Index: trunk/src/sql/drivers/sqlite/qsql_sqlite.cpp
===================================================================
--- trunk/src/sql/drivers/sqlite/qsql_sqlite.cpp	(revision 766)
+++ trunk/src/sql/drivers/sqlite/qsql_sqlite.cpp	(revision 769)
@@ -246,7 +246,7 @@
                 break;
             default:
-                values[i + idx] = QString::fromUtf16(static_cast<const ushort *>(
+                values[i + idx] = QString(reinterpret_cast<const QChar *>(
                             sqlite3_column_text16(stmt, i)),
-                            sqlite3_column_bytes16(stmt, i) / sizeof(ushort));
+                            sqlite3_column_bytes16(stmt, i) / sizeof(QChar));
                 break;
             }
@@ -260,4 +260,5 @@
         sqlite3_reset(stmt);
         return false;
+    case SQLITE_CONSTRAINT:
     case SQLITE_ERROR:
         // SQLITE_ERROR is a generic error code and we must call sqlite3_reset()
@@ -501,30 +502,4 @@
 }
 
-static int qGetSqliteTimeout(QString opts)
-{
-    enum { DefaultTimeout = 5000 };
-
-    opts.remove(QLatin1Char(' '));
-    foreach(QString option, opts.split(QLatin1Char(';'))) {
-        if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
-            bool ok;
-            int nt = option.mid(21).toInt(&ok);
-            if (ok)
-                return nt;
-        }
-    }
-    return DefaultTimeout;
-}
-
-static int qGetSqliteOpenMode(QString opts)
-{
-    opts.remove(QLatin1Char(' '));
-    foreach(QString option, opts.split(QLatin1Char(';'))) {
-        if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
-                return SQLITE_OPEN_READONLY;
-    }
-    return SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
-}
-
 /*
    SQLite dbs have no user name, passwords, hosts or ports.
@@ -538,7 +513,24 @@
     if (db.isEmpty())
         return false;
-
-    if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, qGetSqliteOpenMode(conOpts), NULL) == SQLITE_OK) {
-        sqlite3_busy_timeout(d->access, qGetSqliteTimeout(conOpts));
+    bool sharedCache = false;
+    int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, timeOut=5000;
+    QStringList opts=QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';'));
+    foreach(const QString &option, opts) {
+        if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
+            bool ok;
+            int nt = option.mid(21).toInt(&ok);
+            if (ok)
+                timeOut = nt;
+        }
+        if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
+            openMode = SQLITE_OPEN_READONLY;
+        if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE"))
+            sharedCache = true;
+    }
+
+    sqlite3_enable_shared_cache(sharedCache);
+
+    if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) {
+        sqlite3_busy_timeout(d->access, timeOut);
         setOpen(true);
         setOpenError(false);
Index: trunk/src/sql/kernel/qsqldatabase.cpp
===================================================================
--- trunk/src/sql/kernel/qsqldatabase.cpp	(revision 766)
+++ trunk/src/sql/kernel/qsqldatabase.cpp	(revision 769)
@@ -1268,4 +1268,5 @@
     \i QSQLITE_BUSY_TIMEOUT
     \i QSQLITE_OPEN_READONLY
+    \i QSQLITE_ENABLE_SHARED_CACHE
     \endlist
 
Index: trunk/src/sql/kernel/qsqlquery.cpp
===================================================================
--- trunk/src/sql/kernel/qsqlquery.cpp	(revision 766)
+++ trunk/src/sql/kernel/qsqlquery.cpp	(revision 769)
@@ -823,4 +823,7 @@
   the result set.
 
+  \note Calling setForwardOnly after execution of the query will result
+  in unexpected results at best, and crashes at worst.
+
   \sa isForwardOnly(), next(), seek(), QSqlResult::setForwardOnly()
 */
@@ -1000,7 +1003,15 @@
   paramType is QSql::Out or QSql::InOut, the placeholder will be
   overwritten with data from the database after the exec() call.
+  In this case, sufficient space must be pre-allocated to store
+  the result into.
 
   To bind a NULL value, use a null QVariant; for example, use
   \c {QVariant(QVariant::String)} if you are binding a string.
+
+  Values cannot be bound to multiple locations in the query, eg:
+  \code
+  INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name)
+  \endcode
+  Binding to name will bind to the first :name, but not the second.
 
   \sa addBindValue(), prepare(), exec(), boundValue() boundValues()
Index: trunk/src/sql/kernel/qsqlresult.cpp
===================================================================
--- trunk/src/sql/kernel/qsqlresult.cpp	(revision 766)
+++ trunk/src/sql/kernel/qsqlresult.cpp	(revision 769)
@@ -137,5 +137,5 @@
     }
 
-    return QString::fromUtf16(arr, int(ptr - arr) + 1);
+    return QString(reinterpret_cast<const QChar *>(arr), int(ptr - arr) + 1);
 }
 
@@ -564,4 +564,7 @@
     scrollable. isForwardOnly() will always return the correct status of
     the result set.
+
+    \note Calling setForwardOnly after execution of the query will result
+    in unexpected results at best, and crashes at worst.
 
     \sa isForwardOnly(), fetchNext(), QSqlQuery::setForwardOnly()
@@ -708,5 +711,13 @@
     placeholder name in the current record (row).
 
-    Note that binding an undefined placeholder will result in undefined behavior.
+   Values cannot be bound to multiple locations in the query, eg:
+   \code
+   INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name)
+   \endcode
+   Binding to name will bind to the first :name, but not the second.
+
+    \note Binding an undefined placeholder will result in undefined behavior.
+
+    \sa QSqlQuery::bindValue()
 */
 void QSqlResult::bindValue(const QString& placeholder, const QVariant& val,
Index: trunk/src/src.pro
===================================================================
--- trunk/src/src.pro	(revision 766)
+++ trunk/src/src.pro	(revision 769)
@@ -111,4 +111,5 @@
       src_webkit.depends = src_gui src_sql src_network src_xml 
       contains(QT_CONFIG, phonon):src_webkit.depends += src_phonon
+      contains(QT_CONFIG, xmlpatterns): src_webkit.depends += src_xmlpatterns
       contains(QT_CONFIG, declarative):src_declarative.depends += src_webkit
       #exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): src_webkit.depends += src_javascriptcore
Index: trunk/src/svg/qgraphicssvgitem.cpp
===================================================================
--- trunk/src/svg/qgraphicssvgitem.cpp	(revision 766)
+++ trunk/src/svg/qgraphicssvgitem.cpp	(revision 769)
@@ -268,4 +268,5 @@
 /*!
   \property QGraphicsSvgItem::maximumCacheSize
+  \since 4.6
 
   This property holds the maximum size of the device coordinate cache
@@ -313,5 +314,6 @@
 /*!
   \property QGraphicsSvgItem::elementId
-
+  \since 4.6
+  
   This property holds the element's XML ID.
  */
Index: trunk/src/svg/qsvghandler.cpp
===================================================================
--- trunk/src/svg/qsvghandler.cpp	(revision 766)
+++ trunk/src/svg/qsvghandler.cpp	(revision 769)
@@ -75,5 +75,5 @@
 #define QT_INHERIT QLatin1String(qt_inherit_text)
 
-double qstrtod(const char *s00, char const **se, bool *ok);
+Q_DECL_IMPORT double qstrtod(const char *s00, char const **se, bool *ok);
 
 // ======== duplicated from qcolor_p
Index: trunk/src/testlib/qplaintestlogger.cpp
===================================================================
--- trunk/src/testlib/qplaintestlogger.cpp	(revision 766)
+++ trunk/src/testlib/qplaintestlogger.cpp	(revision 769)
@@ -182,4 +182,5 @@
                 RDebug::Print(format, hbuffer);
             }
+            delete hbuffer;
         }
         else {
Index: trunk/src/testlib/qtestcase.cpp
===================================================================
--- trunk/src/testlib/qtestcase.cpp	(revision 766)
+++ trunk/src/testlib/qtestcase.cpp	(revision 769)
@@ -965,5 +965,5 @@
          " -xml       : Outputs results as XML document\n"
          " -lightxml  : Outputs results as stream of XML tags\n"
-         " -flush     : Flushes the resutls\n"
+         " -flush     : Flushes the results\n"
          " -o filename: Writes all output into a file\n"
          " -silent    : Only outputs warnings and failures\n"
@@ -1114,4 +1114,12 @@
         } else if (strcmp(argv[i], "-qws") == 0) {
             // do nothing
+        } else if (strcmp(argv[i], "-graphicssystem") == 0) {
+            // do nothing
+            if (i + 1 >= argc) {
+                printf("-graphicssystem needs an extra parameter specifying the graphics system\n");
+                exit(1);
+            } else {
+                ++i;
+            }
         } else if (argv[i][0] == '-') {
             printf("Unknown option: '%s'\n\n%s", argv[i], testOptions);
@@ -1299,9 +1307,21 @@
             QTestResult::setSkipCurrentTest(false);
 
+            // Data tag requested but none available?
+            if (data && !dataCount) {
+                // Let empty data tag through.
+                if (!*data)
+                    data = 0;
+                else {
+                    printf("Unknown testdata for function %s: '%s'\n", slotName, data);
+                    printf("Function has no testdata.\n");
+                    return false;
+                }
+            }
+
             /* For each entry in the data table, do: */
             do {
                 if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
                     foundFunction = true;
-                    QTestDataSetter s(table.isEmpty() ? static_cast<QTestData *>(0)
+                    QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
                                                       : table.testData(curDataIndex));
 
Index: trunk/src/testlib/qtestlogger.cpp
===================================================================
--- trunk/src/testlib/qtestlogger.cpp	(revision 766)
+++ trunk/src/testlib/qtestlogger.cpp	(revision 769)
@@ -212,8 +212,5 @@
         failureElement->addAttribute(QTest::AI_Line, buf);
         failureElement->addAttribute(QTest::AI_Description, description);
-        const char* tag = QTestResult::currentDataTag();
-        if (tag) {
-            failureElement->addAttribute(QTest::AI_Tag, tag);
-        }
+        addTag(failureElement);
         currentLogElement->addLogElement(failureElement);
     }
@@ -278,4 +275,25 @@
 }
 
+void QTestLogger::addTag(QTestElement* element)
+{
+    const char *tag = QTestResult::currentDataTag();
+    const char *gtag = QTestResult::currentGlobalDataTag();
+    const char *filler = (tag && gtag) ? ":" : "";
+    if ((!tag || !tag[0]) && (!gtag || !gtag[0])) {
+        return;
+    }
+
+    if (!tag) {
+        tag = "";
+    }
+    if (!gtag) {
+        gtag = "";
+    }
+
+    QTestCharBuffer buf;
+    QTest::qt_asprintf(&buf, "%s%s%s", gtag, filler, tag);
+    element->addAttribute(QTest::AI_Tag, buf.constData());
+}
+
 void QTestLogger::addMessage(MessageTypes type, const char *message, const char *file, int line)
 {
@@ -298,5 +316,5 @@
     case QAbstractTestLogger::QWarning:
         ++qwarnCounter;
-        typeBuf = "qwarning";
+        typeBuf = "qwarn";
         break;
     case QAbstractTestLogger::QFatal:
@@ -319,4 +337,5 @@
     errorElement->addAttribute(QTest::AI_Type, typeBuf);
     errorElement->addAttribute(QTest::AI_Description, message);
+    addTag(errorElement);
 
     if(file)
Index: trunk/src/testlib/qtestlogger_p.h
===================================================================
--- trunk/src/testlib/qtestlogger_p.h	(revision 766)
+++ trunk/src/testlib/qtestlogger_p.h	(revision 769)
@@ -84,4 +84,5 @@
                      const char *file = 0, int line = 0);
         void addBenchmarkResult(const QBenchmarkResult &result);
+        void addTag(QTestElement* element);
 
         void addMessage(MessageTypes type, const char *message,
Index: trunk/src/testlib/qtestxmlstreamer.cpp
===================================================================
--- trunk/src/testlib/qtestxmlstreamer.cpp	(revision 766)
+++ trunk/src/testlib/qtestxmlstreamer.cpp	(revision 769)
@@ -112,5 +112,12 @@
         QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description));
 
-        QTest::qt_asprintf(formatted, "<Message type=\"%s\" %s=\"%s\" %s=\"%s\">\n    <Description><![CDATA[%s]]></Description>\n</Message>\n",
+        QTestCharBuffer tagbuf;
+        if (element->attribute(QTest::AI_Tag)) {
+            QTestCharBuffer cdataTag;
+            QXmlTestLogger::xmlCdata(&cdataTag, element->attributeValue(QTest::AI_Tag));
+            QTest::qt_asprintf(&tagbuf, "    <DataTag><![CDATA[%s]]></DataTag>\n", cdataTag.constData());
+        }
+
+        QTest::qt_asprintf(formatted, "<Message type=\"%s\" %s=\"%s\" %s=\"%s\">\n%s    <Description><![CDATA[%s]]></Description>\n</Message>\n",
                            element->attributeValue(QTest::AI_Type),
                            element->attributeName(QTest::AI_File),
@@ -118,4 +125,5 @@
                            element->attributeName(QTest::AI_Line),
                            element->attributeValue(QTest::AI_Line),
+                           tagbuf.constData(),
                            cdataDesc.constData());
         break;
@@ -150,5 +158,27 @@
 
     if (element->elementType() == QTest::LET_TestCase) {
-        QTest::qt_asprintf(formatted, "</TestFunction>\n");
+        bool failed = false;
+        for (QTestElement* child = element->childElements(); child; child = child->nextElement()) {
+            if (   child->elementType() == QTest::LET_Failure
+                && child->attribute(QTest::AI_Result)
+                && (    !strcmp(child->attributeValue(QTest::AI_Result), "fail")
+                    ||  !strcmp(child->attributeValue(QTest::AI_Result), "xpass"))
+                )
+            {
+                failed = true;
+                break;
+            }
+        }
+
+        // For passing functions, no Incident has been output yet.
+        // For failing functions, we already output one.
+        // Please note: we are outputting "pass" even if there was an xfail etc.
+        // This is by design (arguably bad design, but dangerous to change now!)
+        if (element->attribute(QTest::AI_Result) && !failed) {
+            QTest::qt_asprintf(formatted, "<Incident type=\"pass\" file=\"\" line=\"0\" />\n</TestFunction>\n");
+        }
+        else {
+            QTest::qt_asprintf(formatted, "</TestFunction>\n");
+        }
     } else {
         formatted->data()[0] = '\0';
@@ -158,27 +188,9 @@
 void QTestXmlStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
 {
-    if(!element || !formatted)
+    Q_UNUSED(element);
+    if (!formatted)
         return;
 
-    if (element->elementType() == QTest::LET_TestCase && element->attribute(QTest::AI_Result)){
-        QTestCharBuffer buf;
-        QTestCharBuffer quotedFile;
-        QXmlTestLogger::xmlQuote(&quotedFile, element->attributeValue(QTest::AI_File));
-
-        QTest::qt_asprintf(&buf, "%s=\"%s\" %s=\"%s\"",
-                           element->attributeName(QTest::AI_File),
-                           quotedFile.constData(),
-                           element->attributeName(QTest::AI_Line),
-                           element->attributeValue(QTest::AI_Line));
-
-        if( !element->childElements() ) {
-            QTest::qt_asprintf(formatted, "<Incident type=\"%s\" %s/>\n",
-                               element->attributeValue(QTest::AI_Result), buf.constData());
-        } else {
-            formatted->data()[0] = '\0';
-        }
-    } else {
-        formatted->data()[0] = '\0';
-    }
+    formatted->data()[0] = '\0';
 }
 
Index: trunk/src/tools/moc/generator.cpp
===================================================================
--- trunk/src/tools/moc/generator.cpp	(revision 766)
+++ trunk/src/tools/moc/generator.cpp	(revision 769)
@@ -739,16 +739,21 @@
                 if (p.read.isEmpty())
                     continue;
+                QByteArray prefix;
+                if (p.inPrivateClass.size()) {
+                    prefix = p.inPrivateClass;
+                    prefix.append("->");
+                }
                 if (p.gspec == PropertyDef::PointerSpec)
-                    fprintf(out, "        case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s())); break;\n",
-                            propindex, p.read.constData());
+                    fprintf(out, "        case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s%s())); break;\n",
+                            propindex, prefix.constData(), p.read.constData());
                 else if (p.gspec == PropertyDef::ReferenceSpec)
-                    fprintf(out, "        case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s())); break;\n",
-                            propindex, p.read.constData());
+                    fprintf(out, "        case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
+                            propindex, prefix.constData(), p.read.constData());
                 else if (cdef->enumDeclarations.value(p.type, false))
-                    fprintf(out, "        case %d: *reinterpret_cast<int*>(_v) = QFlag(%s()); break;\n",
-                            propindex, p.read.constData());
+                    fprintf(out, "        case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
+                            propindex, prefix.constData(), p.read.constData());
                 else
-                    fprintf(out, "        case %d: *reinterpret_cast< %s*>(_v) = %s(); break;\n",
-                            propindex, p.type.constData(), p.read.constData());
+                    fprintf(out, "        case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
+                            propindex, p.type.constData(), prefix.constData(), p.read.constData());
             }
             fprintf(out, "        }\n");
@@ -769,10 +774,15 @@
                 if (p.write.isEmpty())
                     continue;
+                QByteArray prefix;
+                if (p.inPrivateClass.size()) {
+                    prefix = p.inPrivateClass;
+                    prefix.append("->");
+                }
                 if (cdef->enumDeclarations.value(p.type, false)) {
-                    fprintf(out, "        case %d: %s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
-                            propindex, p.write.constData());
+                    fprintf(out, "        case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
+                            propindex, prefix.constData(), p.write.constData());
                 } else {
-                    fprintf(out, "        case %d: %s(*reinterpret_cast< %s*>(_v)); break;\n",
-                            propindex, p.write.constData(), p.type.constData());
+                    fprintf(out, "        case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
+                            propindex, prefix.constData(), p.write.constData(), p.type.constData());
                 }
             }
@@ -792,6 +802,11 @@
                 if (!p.reset.endsWith(')'))
                     continue;
-                fprintf(out, "        case %d: %s; break;\n",
-                        propindex, p.reset.constData());
+                QByteArray prefix;
+                if (p.inPrivateClass.size()) {
+                    prefix = p.inPrivateClass;
+                    prefix.append("->");
+                }
+                fprintf(out, "        case %d: %s%s; break;\n",
+                        propindex, prefix.constData(), p.reset.constData());
             }
             fprintf(out, "        }\n");
Index: trunk/src/tools/moc/keywords.cpp
===================================================================
--- trunk/src/tools/moc/keywords.cpp	(revision 766)
+++ trunk/src/tools/moc/keywords.cpp	(revision 769)
@@ -44,10 +44,10 @@
 
 static const short keyword_trans[][128] = {
-    {0,0,0,0,0,0,0,0,0,525,522,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     525,252,523,526,0,38,239,524,25,26,236,234,30,235,27,237,
+    {0,0,0,0,0,0,0,0,0,533,530,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     533,252,531,534,0,38,239,532,25,26,236,234,30,235,27,237,
      22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
      0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-     8,21,8,8,8,8,8,8,8,8,8,31,527,32,238,8,
+     8,21,8,8,8,8,8,8,8,8,8,31,535,32,238,8,
      0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
      14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0},
@@ -191,5 +191,5 @@
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0,
-     530,530,530,530,530,530,530,530,530,530,0,0,0,0,0,0,
+     538,538,538,538,538,538,538,538,538,538,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -350,5 +350,5 @@
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,529,0,0,0,0,528,
+     0,0,0,0,0,0,0,0,0,0,537,0,0,0,0,536,
      0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -426,4 +426,12 @@
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,450,0,506,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     522,0,0,481,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -926,10 +934,10 @@
     {CHARACTER, 0, 69, 479, CHARACTER},
     {CHARACTER, 0, 95, 480, CHARACTER},
-    {CHARACTER, 0, 83, 481, CHARACTER},
+    {CHARACTER, 48, 0, 0, CHARACTER},
     {CHARACTER, 0, 76, 482, CHARACTER},
     {CHARACTER, 0, 79, 483, CHARACTER},
     {CHARACTER, 0, 84, 484, CHARACTER},
     {Q_PRIVATE_SLOT_TOKEN, 0, 0, 0, CHARACTER},
-    {CHARACTER, 48, 0, 0, CHARACTER},
+    {CHARACTER, 49, 0, 0, CHARACTER},
     {CHARACTER, 0, 77, 487, CHARACTER},
     {CHARACTER, 0, 79, 488, CHARACTER},
@@ -968,4 +976,12 @@
     {CHARACTER, 0, 69, 521, CHARACTER},
     {Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER},
+    {CHARACTER, 0, 82, 523, CHARACTER},
+    {CHARACTER, 0, 79, 524, CHARACTER},
+    {CHARACTER, 0, 80, 525, CHARACTER},
+    {CHARACTER, 0, 69, 526, CHARACTER},
+    {CHARACTER, 0, 82, 527, CHARACTER},
+    {CHARACTER, 0, 84, 528, CHARACTER},
+    {CHARACTER, 0, 89, 529, CHARACTER},
+    {Q_PRIVATE_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
     {NEWLINE, 0, 0, 0, NOTOKEN},
     {QUOTE, 0, 0, 0, NOTOKEN},
Index: trunk/src/tools/moc/moc.cpp
===================================================================
--- trunk/src/tools/moc/moc.cpp	(revision 766)
+++ trunk/src/tools/moc/moc.cpp	(revision 769)
@@ -659,4 +659,7 @@
                     parseSlotInPrivate(&def, access);
                     break;
+                case Q_PRIVATE_PROPERTY_TOKEN:
+                    parsePrivateProperty(&def);
+                    break;
                 case ENUM: {
                     EnumDef enumDef;
@@ -873,9 +876,6 @@
 }
 
-
-void Moc::parseProperty(ClassDef *def)
-{
-    next(LPAREN);
-    PropertyDef propDef;
+void Moc::createPropertyDef(PropertyDef &propDef)
+{
     QByteArray type = parseType().name;
     if (type.isEmpty())
@@ -965,5 +965,4 @@
         }
     }
-    next(RPAREN);
     if (propDef.read.isNull()) {
         QByteArray msg;
@@ -989,4 +988,39 @@
         warning(msg.constData());
     }
+}
+
+void Moc::parseProperty(ClassDef *def)
+{
+    next(LPAREN);
+    PropertyDef propDef;
+    createPropertyDef(propDef);
+    next(RPAREN);
+
+
+    if(!propDef.notify.isEmpty())
+        def->notifyableProperties++;
+    def->propertyList += propDef;
+}
+
+void Moc::parsePrivateProperty(ClassDef *def)
+{
+    next(LPAREN);
+    PropertyDef propDef;
+    next(IDENTIFIER);
+    propDef.inPrivateClass = lexem();
+    while (test(SCOPE)) {
+        propDef.inPrivateClass += lexem();
+        next(IDENTIFIER);
+        propDef.inPrivateClass += lexem();
+    }
+    // also allow void functions
+    if (test(LPAREN)) {
+        next(RPAREN);
+        propDef.inPrivateClass += "()";
+    }
+
+    next(COMMA);
+
+    createPropertyDef(propDef);
 
     if(!propDef.notify.isEmpty())
Index: trunk/src/tools/moc/moc.h
===================================================================
--- trunk/src/tools/moc/moc.h	(revision 766)
+++ trunk/src/tools/moc/moc.h	(revision 769)
@@ -117,5 +117,5 @@
 {
     PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec){}
-    QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify;
+    QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
     int notifyId;
     bool constant;
@@ -218,4 +218,5 @@
     void parseSignals(ClassDef *def);
     void parseProperty(ClassDef *def);
+    void createPropertyDef(PropertyDef &def);
     void parseEnumOrFlag(ClassDef *def, bool isFlag);
     void parseFlag(ClassDef *def);
@@ -225,4 +226,5 @@
     void parseDeclareMetatype();
     void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access);
+    void parsePrivateProperty(ClassDef *def);
 
     void parseFunctionArguments(FunctionDef *def);
Index: trunk/src/tools/moc/token.cpp
===================================================================
--- trunk/src/tools/moc/token.cpp	(revision 766)
+++ trunk/src/tools/moc/token.cpp	(revision 769)
@@ -180,4 +180,5 @@
         case Q_SLOT_TOKEN: return "Q_SLOT_TOKEN";
         case Q_PRIVATE_SLOT_TOKEN: return "Q_PRIVATE_SLOT_TOKEN";
+        case Q_PRIVATE_PROPERTY_TOKEN: return "Q_PRIVATE_PROPERTY_TOKEN";
         case SPECIAL_TREATMENT_MARK: return "SPECIAL_TREATMENT_MARK";
         case MOC_INCLUDE_BEGIN: return "MOC_INCLUDE_BEGIN";
Index: trunk/src/tools/moc/token.h
===================================================================
--- trunk/src/tools/moc/token.h	(revision 766)
+++ trunk/src/tools/moc/token.h	(revision 769)
@@ -186,4 +186,5 @@
     Q_INVOKABLE_TOKEN,
     Q_SCRIPTABLE_TOKEN,
+    Q_PRIVATE_PROPERTY_TOKEN,
     Q_META_TOKEN_END,
     SPECIAL_TREATMENT_MARK = Q_META_TOKEN_END,
Index: trunk/src/tools/moc/util/generate_keywords.cpp
===================================================================
--- trunk/src/tools/moc/util/generate_keywords.cpp	(revision 766)
+++ trunk/src/tools/moc/util/generate_keywords.cpp	(revision 769)
@@ -249,5 +249,5 @@
     { "Q_SLOT", "Q_SLOT_TOKEN" },
     { "Q_SCRIPTABLE", "Q_SCRIPTABLE_TOKEN" },
-
+    { "Q_PRIVATE_PROPERTY", "Q_PRIVATE_PROPERTY_TOKEN" },
     { "\n", "NEWLINE" },
     { "\"", "QUOTE" },
Index: trunk/src/tools/rcc/rcc.cpp
===================================================================
--- trunk/src/tools/rcc/rcc.cpp	(revision 766)
+++ trunk/src/tools/rcc/rcc.cpp	(revision 769)
@@ -545,4 +545,6 @@
     RCCFileInfo *s = new RCCFileInfo(file);
     s->m_parent = parent;
+    if (parent->m_children.contains(filename))
+        qWarning("potential duplicate alias detected: '%s'", qPrintable(filename));
     parent->m_children.insertMulti(filename, s);
     return true;
Index: trunk/src/tools/uic/cpp/cppwriteinitialization.cpp
===================================================================
--- trunk/src/tools/uic/cpp/cppwriteinitialization.cpp	(revision 766)
+++ trunk/src/tools/uic/cpp/cppwriteinitialization.cpp	(revision 769)
@@ -2789,6 +2789,6 @@
 
     QMap<QString, bool> map; // bool is dummy. The idea is to sort that (always generate in the same order) by putting a set into a map
-    foreach (QString str, directives)
-        map[str] = true;
+    foreach (const QString &str, directives)
+        map.insert(str, true);
 
     if (map.size() == 1) {
@@ -2799,5 +2799,5 @@
     outputStream << "#if";
     bool doOr = false;
-    foreach (QString str, map.keys()) {
+    foreach (const QString &str, map.keys()) {
         if (doOr)
             outputStream << " ||";
Index: trunk/src/tools/uic/qclass_lib_map.h
===================================================================
--- trunk/src/tools/uic/qclass_lib_map.h	(revision 766)
+++ trunk/src/tools/uic/qclass_lib_map.h	(revision 769)
@@ -458,4 +458,5 @@
 QT_CLASS_LIB(QWebSettings, QtWebKit, qwebsettings.h)
 QT_CLASS_LIB(QWebView, QtWebKit, qwebview.h)
+QT_CLASS_LIB(QAudio, QtMultimedia, qaudio.h)
 QT_CLASS_LIB(QAudioDeviceInfo, QtMultimedia, qaudiodeviceinfo.h)
 QT_CLASS_LIB(QAbstractAudioDeviceInfo, QtMultimedia, qaudioengine.h)
Index: trunk/src/tools/uic3/converter.cpp
===================================================================
--- trunk/src/tools/uic3/converter.cpp	(revision 766)
+++ trunk/src/tools/uic3/converter.cpp	(revision 769)
@@ -402,5 +402,5 @@
             if (objName == receiver) {
                 // see if it's a custom slot
-                foreach (QString cs, ui_custom_slots) {
+                foreach (const QString &cs, ui_custom_slots) {
                     if (cs == slot) {
                         resolved = true;
@@ -1123,5 +1123,5 @@
                 QStringList flags = prop->elementSet().split(QLatin1Char('|'));
                 QStringList v;
-                foreach (QString fl, flags) {
+                foreach (const QString &fl, flags) {
                     QString e = WidgetInfo::resolveEnumerator(className, fl);
                     if (e.isEmpty()) {
@@ -1284,5 +1284,5 @@
     //split type name on <>*& and whitespace
     QStringList typeNames = t.split(QRegExp(QLatin1String("<|>|\\*|&| ")), QString::SkipEmptyParts);
-    foreach(QString typeName , typeNames) {
+    foreach(const QString &typeName , typeNames) {
         QString newName = fixClassName(typeName);
         if( newName != typeName ) {
Index: trunk/src/tools/uic3/main.cpp
===================================================================
--- trunk/src/tools/uic3/main.cpp	(revision 766)
+++ trunk/src/tools/uic3/main.cpp	(revision 769)
@@ -339,8 +339,8 @@
         ui3.computeDeps(e, globalIncludes, localIncludes, impl);
 
-        foreach (QString i, globalIncludes)
+        foreach (const QString &i, globalIncludes)
             printf("%s\n", i.toLatin1().constData());
 
-        foreach (QString i, localIncludes)
+        foreach (const QString &i, localIncludes)
             printf("%s\n", i.toLatin1().constData());
 
Index: trunk/src/xml/dom/qdom.cpp
===================================================================
--- trunk/src/xml/dom/qdom.cpp	(revision 766)
+++ trunk/src/xml/dom/qdom.cpp	(revision 769)
@@ -2974,5 +2974,5 @@
 
 /*!
-    Returns the next sibilng element with tag name \a tagName if \a tagName
+    Returns the next sibling element with tag name \a tagName if \a tagName
     is non-empty; otherwise returns any next sibling element.
     Returns a null element if no such sibling exists.
@@ -3488,4 +3488,5 @@
             // Dont use normal insert function since we would create infinite recursion
             notations->map.insertMulti(p->nodeName(), p);
+        p = p->next;
     }
 }
Index: trunk/src/xmlpatterns/api/qxmlresultitems.cpp
===================================================================
--- trunk/src/xmlpatterns/api/qxmlresultitems.cpp	(revision 766)
+++ trunk/src/xmlpatterns/api/qxmlresultitems.cpp	(revision 769)
@@ -70,4 +70,8 @@
   sequence and returns it, and current() always returns the QXmlItem
   that next() returned the last time it was called.
+
+  \note When using the QXmlResultItems overload of QXmlQuery::evaluateTo()
+  to execute a query, it is advisable to create a new instance of this
+  class for each new set of results rather than reusing an old instance.
 
   \sa QXmlItem::isNode(), QXmlItem::isAtomicValue(), QXmlNodeModelIndex
Index: trunk/src/xmlpatterns/data/qatomicvalue.cpp
===================================================================
--- trunk/src/xmlpatterns/data/qatomicvalue.cpp	(revision 766)
+++ trunk/src/xmlpatterns/data/qatomicvalue.cpp	(revision 769)
@@ -227,4 +227,6 @@
         case QVariant::Time:
             return BuiltinTypes::xsDateTime;
+        case QMetaType::Float:
+	    return BuiltinTypes::xsFloat;
         case QVariant::Double:
             return BuiltinTypes::xsDouble;
Index: trunk/src/xmlpatterns/data/qdecimal_p.h
===================================================================
--- trunk/src/xmlpatterns/data/qdecimal_p.h	(revision 766)
+++ trunk/src/xmlpatterns/data/qdecimal_p.h	(revision 769)
@@ -62,5 +62,5 @@
  * Defined in QtCore's qlocale.cpp.
  */
-extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp);
+Q_DECL_IMPORT extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp);
 
 namespace QPatternist
Index: trunk/src/xmlpatterns/schema/qxsdschemaparser.cpp
===================================================================
--- trunk/src/xmlpatterns/schema/qxsdschemaparser.cpp	(revision 766)
+++ trunk/src/xmlpatterns/schema/qxsdschemaparser.cpp	(revision 769)
@@ -265,4 +265,9 @@
 }
 
+void XsdSchemaParser::addIncludedSchemas(const NamespaceSet &schemas)
+{
+    m_includedSchemas += schemas;
+}
+
 void XsdSchemaParser::setIncludedSchemas(const NamespaceSet &schemas)
 {
@@ -270,7 +275,17 @@
 }
 
+void XsdSchemaParser::addImportedSchemas(const NamespaceSet &schemas)
+{
+    m_importedSchemas += schemas;
+}
+
 void XsdSchemaParser::setImportedSchemas(const NamespaceSet &schemas)
 {
     m_importedSchemas = schemas;
+}
+
+void XsdSchemaParser::addRedefinedSchemas(const NamespaceSet &schemas)
+{
+    m_redefinedSchemas += schemas;
 }
 
@@ -298,4 +313,5 @@
     m_includedSchemas.insert(uri);
     m_importedSchemas.insert(uri);
+    m_redefinedSchemas.insert(uri);
 }
 
@@ -595,6 +611,12 @@
             parser.setImportedSchemas(m_importedSchemas);
             parser.setRedefinedSchemas(m_redefinedSchemas);
-            if (!parser.parse(XsdSchemaParser::IncludeParser))
+            if (!parser.parse(XsdSchemaParser::IncludeParser)) {
                 return;
+            } else {
+                // add indirectly loaded schemas to the list of already loaded ones
+                addIncludedSchemas(parser.m_includedSchemas);
+                addImportedSchemas(parser.m_importedSchemas);
+                addRedefinedSchemas(parser.m_redefinedSchemas);
+            }
         }
     }
@@ -685,6 +707,12 @@
                 parser.setImportedSchemas(m_importedSchemas);
                 parser.setRedefinedSchemas(m_redefinedSchemas);
-                if (!parser.parse(XsdSchemaParser::ImportParser))
+                if (!parser.parse(XsdSchemaParser::ImportParser)) {
                     return;
+                } else {
+                    // add indirectly loaded schemas to the list of already loaded ones
+                    addIncludedSchemas(parser.m_includedSchemas);
+                    addImportedSchemas(parser.m_importedSchemas);
+                    addRedefinedSchemas(parser.m_redefinedSchemas);
+                }
             }
         }
@@ -703,6 +731,12 @@
                     parser.setImportedSchemas(m_importedSchemas);
                     parser.setRedefinedSchemas(m_redefinedSchemas);
-                    if (!parser.parse(XsdSchemaParser::ImportParser))
+                    if (!parser.parse(XsdSchemaParser::ImportParser)) {
                         return;
+                    } else {
+                        // add indirectly loaded schemas to the list of already loaded ones
+                        addIncludedSchemas(parser.m_includedSchemas);
+                        addImportedSchemas(parser.m_importedSchemas);
+                        addRedefinedSchemas(parser.m_redefinedSchemas);
+                    }
                 }
             }
@@ -840,6 +874,12 @@
             parser.setImportedSchemas(m_importedSchemas);
             parser.setRedefinedSchemas(m_redefinedSchemas);
-            if (!parser.parse(XsdSchemaParser::RedefineParser))
+            if (!parser.parse(XsdSchemaParser::RedefineParser)) {
                 return;
+            } else {
+                // add indirectly loaded schemas to the list of already loaded ones
+                addIncludedSchemas(parser.m_includedSchemas);
+                addImportedSchemas(parser.m_importedSchemas);
+                addRedefinedSchemas(parser.m_redefinedSchemas);
+            }
 
             delete reply;
@@ -4833,5 +4873,5 @@
             if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
                 const XsdAnnotation::Ptr annotation = parseAnnotation();
-                element->addAnnotation(annotation);
+                term->addAnnotation(annotation);
             } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
                 if (hasRefAttribute) {
Index: trunk/src/xmlpatterns/schema/qxsdschemaparser_p.h
===================================================================
--- trunk/src/xmlpatterns/schema/qxsdschemaparser_p.h	(revision 766)
+++ trunk/src/xmlpatterns/schema/qxsdschemaparser_p.h	(revision 769)
@@ -121,8 +121,20 @@
 
             /**
+             * Adds @p schemas to the list of already included schemas, so the parser
+             * can detect multiple includes of the same schema.
+             */
+            void addIncludedSchemas(const NamespaceSet &schemas);
+
+            /**
              * Sets which @p schemas have been included already, so the parser
-             * can detect circular includes.
+             * can detect multiple includes of the same schema.
              */
             void setIncludedSchemas(const NamespaceSet &schemas);
+
+            /**
+             * Adds @p schemas to the list of already imported schemas, so the parser
+             * can detect multiple imports of the same schema.
+             */
+            void addImportedSchemas(const NamespaceSet &schemas);
 
             /**
@@ -133,6 +145,12 @@
 
             /**
+             * Adds @p schemas to the list of already redefined schemas, so the parser
+             * can detect multiple redefines of the same schema.
+             */
+            void addRedefinedSchemas(const NamespaceSet &schemas);
+
+            /**
              * Sets which @p schemas have been redefined already, so the parser
-             * can detect circular redefines.
+             * can detect multiple redefines of the same schema.
              */
             void setRedefinedSchemas(const NamespaceSet &schemas);
Index: trunk/src/xmlpatterns/schema/qxsdschemaresolver.cpp
===================================================================
--- trunk/src/xmlpatterns/schema/qxsdschemaresolver.cpp	(revision 766)
+++ trunk/src/xmlpatterns/schema/qxsdschemaresolver.cpp	(revision 769)
@@ -633,5 +633,12 @@
                     // 1.2
                     const XsdSimpleType::Ptr anonType(new XsdSimpleType());
-                    anonType->setCategory(complexBaseType->contentType()->simpleType()->category());
+                    XsdSimpleType::TypeCategory baseCategory = complexBaseType->contentType()->simpleType()->category();
+                    anonType->setCategory(baseCategory);
+
+                    if (baseCategory == XsdSimpleType::SimpleTypeList) {
+                        const XsdSimpleType::Ptr baseSimpleType = complexBaseType->contentType()->simpleType();
+                        anonType->setItemType(baseSimpleType->itemType());
+                    }
+
                     anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction);
                     anonType->setWxsSuperType(complexBaseType->contentType()->simpleType());
Index: trunk/src/xmlpatterns/xmlpatterns.pro
===================================================================
--- trunk/src/xmlpatterns/xmlpatterns.pro	(revision 766)
+++ trunk/src/xmlpatterns/xmlpatterns.pro	(revision 769)
@@ -26,12 +26,13 @@
 include($$PWD/utils/utils.pri)
 include($$PWD/qobjectmodel/qobjectmodel.pri, "", true)
-wince*:# The Microsoft MIPS compiler crashes if /Og is specified
-:
 
-# -O2/1 expands to /Og plus additional arguments.
-contains(DEFINES, MIPS): { 
-    QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/
-    QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/
+wince* {
+    # The Microsoft MIPS compiler crashes if /Og is specified.
+    # -O2/1 expands to /Og plus additional arguments.
+    contains(DEFINES, MIPS) {
+        QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/
+        QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/
+    }
 }
+
 symbian:TARGET.UID3 = 0x2001E62B
-HEADERS += 
