Index: trunk/src/gui/kernel/qapplication_pm.cpp
===================================================================
--- trunk/src/gui/kernel/qapplication_pm.cpp	(revision 446)
+++ trunk/src/gui/kernel/qapplication_pm.cpp	(revision 447)
@@ -64,4 +64,5 @@
 #include "qkeymapper_p.h"
 #include "qcursor_p.h"
+#include "qdnd_p.h"
 
 #define WM_KBDLAYERCHANGED   0x0BD4 // defined in OS2TK45/h/pmbidi.h
@@ -702,8 +703,4 @@
 #define SV_WORKAREA_XLEFT   54
 
-#ifndef QT_NO_DRAGANDDROP
-extern MRESULT qt_dispatchDragAndDrop(QWidget *, const QMSG &); // qdnd_pm.cpp
-#endif
-
 /*!
     \internal
@@ -921,5 +918,5 @@
 #ifndef QT_NO_DRAGANDDROP
         } else if (msg >= WM_DRAGFIRST && msg <= WM_DRAGLAST) {
-            return qt_dispatchDragAndDrop(widget, qmsg);
+            return QDragManager::self()->dispatchDragAndDrop(widget, qmsg);
 #endif
         } else {
@@ -2142,5 +2139,4 @@
     if (rc == RGN_ERROR) { // The update bounding rect is invalid
         GpiDestroyRegion(displayPS, hrgn);
-        d_func()->hd = NULLHANDLE;
         setAttribute(Qt::WA_PendingUpdate, false);
         return false;
@@ -2166,6 +2162,6 @@
     if (rcl.xRight <= rcl.xLeft || rcl.yTop <= rcl.yBottom) {
         WinEndPaint(d_func()->hd);
+        d_func()->hd = NULLHANDLE;
         GpiDestroyRegion(displayPS, hrgn);
-        d_func()->hd = NULLHANDLE;
         setAttribute(Qt::WA_PendingUpdate, false);
         return true;
@@ -2173,10 +2169,7 @@
 
     // flip y coordinate
-    rcl.yBottom = height() - (rcl.yBottom + 1);
-    rcl.yTop = height() - (rcl.yTop + 1);
-
     // note: right top point is exlusive in rcl
-    QRect updRect(QPoint(rcl.xLeft, rcl.yTop + 1),
-                  QPoint(rcl.xRight - 1, rcl.yBottom));
+    QRect updRect(QPoint(rcl.xLeft, height() - rcl.yTop),
+                  QPoint(rcl.xRight - 1, height() - (rcl.yBottom + 1)));
 
     // Mapping region from system to qt (32 bit) coordinate system.
Index: trunk/src/gui/kernel/qdnd.cpp
===================================================================
--- trunk/src/gui/kernel/qdnd.cpp	(revision 446)
+++ trunk/src/gui/kernel/qdnd.cpp	(revision 447)
@@ -358,4 +358,7 @@
     xdndMimeTransferedPixmapIndex = 0;
 #endif
+#ifdef Q_WS_PM
+    init_sys();
+#endif
 }
 
@@ -363,4 +366,7 @@
 QDragManager::~QDragManager()
 {
+#ifdef Q_WS_PM
+    uninit_sys();
+#endif
 #ifndef QT_NO_CURSOR
     if (restoreCursor)
Index: trunk/src/gui/kernel/qdnd_p.h
===================================================================
--- trunk/src/gui/kernel/qdnd_p.h	(revision 446)
+++ trunk/src/gui/kernel/qdnd_p.h	(revision 447)
@@ -63,4 +63,8 @@
 #ifdef Q_WS_MAC
 # include "private/qt_mac_p.h"
+#endif
+
+#if defined(Q_WS_PM)
+#include "qt_os2.h"
 #endif
 
@@ -205,5 +209,5 @@
     LPDATAOBJECT currentDataObject;
 #elif defined(Q_WS_PM)
-    friend class QPMDragData;
+    friend class QDragManager;
     QPMDragData *d;
 #endif
@@ -267,4 +271,12 @@
 #endif
 
+#ifdef Q_WS_PM
+    void init_sys();
+    void uninit_sys();
+    void sendDropEvent(QWidget *receiver, QEvent *event);
+    MRESULT dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg);
+    bool isInDrag() const { return inDrag; }
+#endif
+
 private:
     QPixmap *pm_cursor;
@@ -272,4 +284,7 @@
 #ifdef Q_WS_QWS
     Qt::DropAction currentActionForOverrideCursor;
+#endif
+#ifdef Q_WS_PM
+    bool inDrag;
 #endif
 
Index: trunk/src/gui/kernel/qdnd_pm.cpp
===================================================================
--- trunk/src/gui/kernel/qdnd_pm.cpp	(revision 446)
+++ trunk/src/gui/kernel/qdnd_pm.cpp	(revision 447)
@@ -93,4 +93,5 @@
 
 private:
+    friend class QDragManager;
 
     void initWorkers();
@@ -102,4 +103,16 @@
     DRAGINFO *di;
     QList<QPMMime::DropWorker*> workers;
+
+    QWidget *lastDragOverWidget; // last target widget
+    USHORT lastDragOverOp; // last DM_DRAGOVER operation
+
+    USHORT supportedOps; // operations supported by all items
+    bool sourceAllowsOp : 1; // does source allow requested operation
+
+    USHORT lastDropReply; // last reply to DM_DRAGOVER
+    USHORT lastOpRequest; // last op requested in DM_DRAGOVER
+
+    Qt::DropAction lastProposedAction; // last proposed action
+    QRect lastAnswerRect; // last accepted rectangle from the target
 };
 
@@ -107,8 +120,9 @@
     : initialized(false), dropped(false)
     , gotWorkers(false), di(NULL)
-{
-    QDragManager *manager = QDragManager::self();
-    Q_ASSERT(!manager->dropData->d);
-    manager->dropData->d = this;
+    , lastDragOverWidget(0), lastDragOverOp(0)
+    , supportedOps(0), sourceAllowsOp(false)
+    , lastDropReply(DOR_NEVERDROP), lastOpRequest(DO_UNKNOWN)
+    , lastProposedAction(Qt::CopyAction)
+{
 }
 
@@ -116,10 +130,4 @@
 {
     reset();
-
-    QDragManager *manager = QDragManager::self();
-    if (manager) {
-        Q_ASSERT(manager->dropData->d == this);
-        manager->dropData->d = 0;
-    }
 }
 
@@ -265,25 +273,40 @@
 }
 
+void QDragManager::init_sys()
+{
+    inDrag = false;
+
+    Q_ASSERT(dropData);
+    Q_ASSERT(!dropData->d);
+    dropData->d = new QPMDragData();
+}
+
+void QDragManager::uninit_sys()
+{
+    Q_ASSERT(dropData);
+    Q_ASSERT(dropData->d);
+    delete dropData->d;
+    dropData->d = 0;
+}
+
+void QDragManager::sendDropEvent(QWidget *receiver, QEvent *event)
+{
+    Q_ASSERT(!inDrag);
+    inDrag = true;
+    QApplication::sendEvent(receiver, event);
+    // make sure that all issued update requests are handled before we
+    // return from the DM_DRAGOVER/DM_DRAGLEAVE/DM_DROP message; otherwise
+    // we'll get screen corruption due to unexpected screen updates while
+    // dragging
+    QApplication::sendPostedEvents(0, QEvent::UpdateRequest);
+    inDrag = false;
+}
+
 /*!
  *  \internal
  *  Direct manipulation (Drag & Drop) event handler
  */
-MRESULT qt_dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg)
-{
-    static QWidget *lastDragOverWidget = 0; // last target widget
-    static USHORT lastDragOverOp = 0; // last DM_DRAGOVER operation
-
-    static USHORT supportedOps = 0; // operations supported by all items
-    static bool sourceAllowsOp = false; // does source allow requested operation
-
-    static USHORT lastDropReply = DOR_NEVERDROP; // last reply to DM_DRAGOVER
-    static USHORT lastOpRequest = DO_UNKNOWN; // last op requested in DM_DRAGOVER
-
-    static Qt::DropAction lastProposedAction = Qt::CopyAction; // last proposed action
-    static QRect lastAnswerRect; // last accepted rectangle from the target
-    // @todo use lastAnswerRect to compress DM_DRAGOVER events
-
-    static QPMDragData dragData;
-
+MRESULT QDragManager::dispatchDragAndDrop(QWidget *widget, const QMSG &qmsg)
+{
     Q_ASSERT(widget);
 
@@ -291,4 +314,8 @@
 
     QDragManager *manager = QDragManager::self();
+    QPMDragData *dragData = manager->dropData->d;
+    Q_ASSERT(dragData);
+
+    // @todo use dragData->lastAnswerRect to compress DM_DRAGOVER events
 
     switch (qmsg.msg) {
@@ -312,13 +339,13 @@
                 dragOverWidget = widget;
 
-            bool first = lastDragOverWidget != dragOverWidget;
+            bool first = dragData->lastDragOverWidget != dragOverWidget;
             if (first) {
                 // the first DM_DRAGOVER message
-                if (lastDragOverWidget != 0) {
+                if (dragData->lastDragOverWidget != 0) {
                     // send drag leave to the old widget
-                    dragData.reset();
+                    dragData->reset();
                     QPointer<QWidget> dragOverWidgetGuard(dragOverWidget);
                     QDragLeaveEvent dle;
-                    QApplication::sendEvent(lastDragOverWidget, &dle);
+                    sendDropEvent(dragData->lastDragOverWidget, &dle);
                     if (!dragOverWidgetGuard) {
                         dragOverWidget = widget->childAt(pnt);
@@ -327,15 +354,16 @@
                     }
                 }
-                lastDragOverWidget = dragOverWidget;
-                lastDragOverOp = 0;
-                supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
-                sourceAllowsOp = false;
-                lastDropReply = DOR_NEVERDROP;
-                lastOpRequest = DO_UNKNOWN;
-                lastProposedAction = manager->defaultAction(toQDragDropActions(supportedOps),
-                                                            Qt::NoModifier);
-                lastAnswerRect = QRect();
+                dragData->lastDragOverWidget = dragOverWidget;
+                dragData->lastDragOverOp = 0;
+                dragData->supportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
+                dragData->sourceAllowsOp = false;
+                dragData->lastDropReply = DOR_NEVERDROP;
+                dragData->lastOpRequest = DO_UNKNOWN;
+                dragData->lastProposedAction =
+                    manager->defaultAction(toQDragDropActions(dragData->supportedOps),
+                                           Qt::NoModifier);
+                dragData->lastAnswerRect = QRect();
                 // ensure drag data is reset (just in case of a wrong msg flow...)
-                dragData.reset();
+                dragData->reset();
             }
 
@@ -362,9 +390,9 @@
                         break;
                     }
-                    supportedOps &= item->fsSupportedOps;
+                    dragData->supportedOps &= item->fsSupportedOps;
                 }
                 if (dropReply != DOR_NEVERDROP) {
                     Q_ASSERT(itemCount);
-                    if (!itemCount || !supportedOps) {
+                    if (!itemCount || !dragData->supportedOps) {
                         // items don't have even a single common operation...
                         dropReply = DOR_NEVERDROP;
@@ -375,16 +403,16 @@
             if (dropReply != DOR_NEVERDROP) {
 
-                if (first || lastDragOverOp != info->usOperation) {
+                if (first || dragData->lastDragOverOp != info->usOperation) {
                     // the current drop operation was changed by a modifier key
-                    lastDragOverOp = info->usOperation;
+                    dragData->lastDragOverOp = info->usOperation;
                     USHORT realOp = info->usOperation;
                     if (realOp == DO_DEFAULT || realOp == DO_UNKNOWN) {
                         // the default operation is requested
-                        realOp = toPmDragDropOp(lastProposedAction);
+                        realOp = toPmDragDropOp(dragData->lastProposedAction);
                     }
-                    sourceAllowsOp =
-                        ((supportedOps & DO_MOVEABLE) && realOp == DO_MOVE) ||
-                        ((supportedOps & DO_COPYABLE) && realOp == DO_COPY) ||
-                        ((supportedOps & DO_LINKABLE) && realOp == DO_LINK);
+                    dragData->sourceAllowsOp =
+                        ((dragData->supportedOps & DO_MOVEABLE) && realOp == DO_MOVE) ||
+                        ((dragData->supportedOps & DO_COPYABLE) && realOp == DO_COPY) ||
+                        ((dragData->supportedOps & DO_LINKABLE) && realOp == DO_LINK);
                 }
 
@@ -396,19 +424,20 @@
                 QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData;
 
-                Qt::DropAction action = toQDragDropAction(lastOpRequest);
+                Qt::DropAction action = toQDragDropAction(dragData->lastOpRequest);
 
                 if (first) {
-                    dragData.initialize(info);
-                    QDragEnterEvent dee(pnt, toQDragDropActions(supportedOps), data,
-                                        QApplication::mouseButtons(),
+                    dragData->initialize(info);
+                    QDragEnterEvent dee(pnt,
+                                        toQDragDropActions(dragData->supportedOps),
+                                        data, QApplication::mouseButtons(),
                                         QApplication::keyboardModifiers());
-                    QApplication::sendEvent(dragOverWidget, &dee);
+                    sendDropEvent(dragOverWidget, &dee);
                     // if not allowed or not accepted, always reply DOR_NODROP
                     // to have DM_DRAGOVER delivered to us again for a new test
-                    if (sourceAllowsOp && dee.isAccepted()) {
+                    if (dragData->sourceAllowsOp && dee.isAccepted()) {
                         dropReply = DOR_DROP;
                         action = dee.dropAction();
-                        lastProposedAction = dee.proposedAction();
-                        lastAnswerRect = dee.answerRect();
+                        dragData->lastProposedAction = dee.proposedAction();
+                        dragData->lastAnswerRect = dee.answerRect();
                     } else {
                         dropReply = DOR_NODROP;
@@ -420,16 +449,17 @@
                 // the target accepts it)
                 if (!first || dropReply == DOR_DROP) {
-                    QDragEnterEvent dme(pnt, toQDragDropActions(supportedOps), data,
-                                        QApplication::mouseButtons(),
-                                        QApplication::keyboardModifiers());
+                    QDragMoveEvent dme(pnt,
+                                       toQDragDropActions(dragData->supportedOps),
+                                       data, QApplication::mouseButtons(),
+                                       QApplication::keyboardModifiers());
                     // accept by default, since enter event was accepted.
                     dme.setDropAction(action);
                     dme.accept();
-                    QApplication::sendEvent(dragOverWidget, &dme);
-                    if (sourceAllowsOp && dme.isAccepted()) {
+                    sendDropEvent(dragOverWidget, &dme);
+                    if (dragData->sourceAllowsOp && dme.isAccepted()) {
                         dropReply = DOR_DROP;
                         action = dme.dropAction();
-                        lastProposedAction = dme.proposedAction();
-                        lastAnswerRect = dme.answerRect();
+                        dragData->lastProposedAction = dme.proposedAction();
+                        dragData->lastAnswerRect = dme.answerRect();
                     } else {
                         dropReply = DOR_NODROP;
@@ -437,11 +467,11 @@
                 }
 
-                lastDropReply = dropReply;
-                lastOpRequest = toPmDragDropOp(action);
+                dragData->lastDropReply = dropReply;
+                dragData->lastOpRequest = toPmDragDropOp(action);
             }
 
             DrgFreeDraginfo(info);
 
-            return MRFROM2SHORT(dropReply, lastOpRequest);
+            return MRFROM2SHORT(dropReply, dragData->lastOpRequest);
         }
         case DM_DRAGLEAVE: {
@@ -449,13 +479,13 @@
 
             // Odin32 apps produce incorrect message flow, ignore
-            Q_ASSERT(lastDragOverWidget != 0);
-            if (lastDragOverWidget == 0)
+            Q_ASSERT(dragData->lastDragOverWidget != 0);
+            if (dragData->lastDragOverWidget == 0)
                 return 0;
 
             QDragLeaveEvent de;
-            QApplication::sendEvent(lastDragOverWidget, &de);
-
-            lastDragOverWidget = 0;
-            dragData.reset();
+            sendDropEvent(dragData->lastDragOverWidget, &de);
+
+            dragData->lastDragOverWidget = 0;
+            dragData->reset();
 
             return 0;
@@ -465,15 +495,15 @@
 
             // Odin32 apps produce incorrect message flow, ignore
-            Q_ASSERT(lastDragOverWidget != 0);
-            if (lastDragOverWidget == 0)
+            Q_ASSERT(dragData->lastDragOverWidget != 0);
+            if (dragData->lastDragOverWidget == 0)
                 return 0;
 
             // Odin32 apps send DM_DROP even if we replied DOR_NEVERDROP or
             // DOR_NODROP, simulate DM_DRAGLEAVE
-            Q_ASSERT(lastDropReply == DOR_DROP);
-            if (lastDropReply != DOR_DROP) {
+            Q_ASSERT(dragData->lastDropReply == DOR_DROP);
+            if (dragData->lastDropReply != DOR_DROP) {
                 QMSG qmsg2 = qmsg;
                 qmsg2.msg = DM_DRAGLEAVE;
-                qt_dispatchDragAndDrop(widget, qmsg2);
+                dispatchDragAndDrop(widget, qmsg2);
                 return 0;
             }
@@ -490,8 +520,8 @@
             pnt = widget->mapFromGlobal(pnt);
 
-            Q_ASSERT(lastOpRequest == info->usOperation);
-
-            Q_ASSERT(lastDragOverWidget->acceptDrops());
-            if (!lastDragOverWidget->acceptDrops()) {
+            Q_ASSERT(dragData->lastOpRequest == info->usOperation);
+
+            Q_ASSERT(dragData->lastDragOverWidget->acceptDrops());
+            if (!dragData->lastDragOverWidget->acceptDrops()) {
                 DrgDeleteDraginfoStrHandles(info);
                 DrgFreeDraginfo(info);
@@ -499,23 +529,22 @@
             }
 
-            QDragManager *manager = QDragManager::self();
             QMimeData *data = manager->source() ? manager->dragPrivate()->data : manager->dropData;
 
-            Qt::DropAction action = toQDragDropAction(lastOpRequest);
-
-            dragData.setDropped(true);
+            Qt::DropAction action = toQDragDropAction(dragData->lastOpRequest);
+
+            dragData->setDropped(true);
 
             QDropEvent de(pnt, action, data, QApplication::mouseButtons(),
                           QApplication::keyboardModifiers());
-            if (lastDropReply == DOR_DROP)
+            if (dragData->lastDropReply == DOR_DROP)
                 de.setDropAction(action);
 
-            QApplication::sendEvent(lastDragOverWidget, &de);
-
-            if (lastDropReply == DOR_DROP)
+            sendDropEvent(dragData->lastDragOverWidget, &de);
+
+            if (dragData->lastDropReply == DOR_DROP)
                 de.accept();
 
-            lastDragOverWidget = 0;
-            dragData.reset(de.isAccepted());
+            dragData->lastDragOverWidget = 0;
+            dragData->reset(de.isAccepted());
 
             ULONG targetReply = de.isAccepted() ?
Index: trunk/src/gui/kernel/qwidget.cpp
===================================================================
--- trunk/src/gui/kernel/qwidget.cpp	(revision 446)
+++ trunk/src/gui/kernel/qwidget.cpp	(revision 447)
@@ -86,4 +86,8 @@
 #if defined (Q_WS_WIN)
 # include <private/qwininputcontext_p.h>
+#endif
+
+#if defined (Q_WS_PM)
+# include "qdnd_p.h"
 #endif
 
@@ -10411,4 +10415,8 @@
     if (d->hd != NULLHANDLE)
         return (HPS) d->hd;
+#ifndef QT_NO_DRAGANDDROP
+    if (QDragManager::self()->isInDrag())
+        return DrgGetPS(winId());
+#endif
     return WinGetPS(winId());
 }
@@ -10424,7 +10432,13 @@
     // If there is a widget's own ps, the release operation is ignored because
     // it will be released elsewhere. Otherwise, we assume that the given hps
-    // was acquired by WinGetPS in the getPS() call and release it.
-    if (d->hd == NULLHANDLE)
+    // was acquired by DrgGetPS/WinGetPS in the getPS() call and release it.
+    if (d->hd == NULLHANDLE) {
+#ifndef QT_NO_DRAGANDDROP
+        if (QDragManager::self()->isInDrag())
+            DrgReleasePS(hps);
+        else
+#endif
         WinReleasePS(hps);
+    }
 }
 #else
