Fixes for ignored WVR_[VH]REDRAW flags, made minimization in managed
mode go through window manager, small bugfixes for menu and window
code, extended clipboard driver model to handle formats other than
text.

diff --git a/windows/clipboard.c b/windows/clipboard.c
index 75a1a1e..031fc08 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -250,7 +250,7 @@
 
     hWndClipOwner = hWndClipWindow;
 
-    CLIPBOARD_Driver->pEmptyClipboard();
+    CLIPBOARD_Driver->pEmpty();
 
     return TRUE;
 }
@@ -293,7 +293,7 @@
     if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
 	(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0; 
 
-    CLIPBOARD_Driver->pSetClipboardData(wFormat);
+    CLIPBOARD_Driver->pSetData(wFormat);
 
     if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 ) 
     {
@@ -323,7 +323,7 @@
 
 
 /**************************************************************************
- *            SetClipboardData32   (USER32.470)
+ *            SetClipboardData   (USER32.470)
  */
 HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
 {
@@ -341,7 +341,7 @@
     if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
 	(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0; 
 
-    CLIPBOARD_Driver->pSetClipboardData(wFormat);
+    CLIPBOARD_Driver->pSetData(wFormat);
 
     if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 ) 
     {
@@ -395,6 +395,9 @@
  *                      CLIPBOARD_RenderText
  *
  * Convert text between UNIX and DOS formats.
+ *
+ * FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
+ *
  */
 static BOOL CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget, LPWINE_CLIPFORMAT lpSource)
 {
@@ -608,15 +611,13 @@
 
     TRACE(clipboard,"(void)\n");
 
-    /* FIXME: Returns BOOL32 */
-    CLIPBOARD_Driver->pRequestSelection();
-
-    FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
-		       lpFormat[CF_OEMTEXT-1].wDataPresent); 
-
     while(TRUE) 
     {
 	if (lpFormat == NULL) break;
+
+ 	if( lpFormat->wFormatID != CF_TEXT )
+ 	    CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
+ 
 	if (lpFormat->wDataPresent) 
 	{
             TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
@@ -625,6 +626,11 @@
 	lpFormat = lpFormat->NextFormat;
     }
 
+    /* these two are equivalent, adjust the total */
+
+    FormatCount += abs(ClipFormats[CF_TEXT-1].wDataPresent -
+                       ClipFormats[CF_OEMTEXT-1].wDataPresent);
+
     TRACE(clipboard,"\ttotal %d\n", FormatCount);
     return FormatCount;
 }
@@ -650,29 +656,30 @@
 
     if( hqClipLock != GetFastQueue16() ) return 0;
 
-    if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) ) 
-        CLIPBOARD_Driver->pRequestSelection();
+    if( wFormat < CF_OEMTEXT )
+        CLIPBOARD_Driver->pGetData( CF_OEMTEXT );
 
-    if (wFormat == 0)
+    if (wFormat == 0) /* start from the beginning */
+	lpFormat = ClipFormats;
+    else
     {
-	if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent) 
-	    return lpFormat->wFormatID;
-	else 
-	    wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
+	/* walk up to the specified format record */
+
+	if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) 
+	    return 0;
+	lpFormat = lpFormat->NextFormat; /* right */
     }
 
-    /* walk up to the specified format record */
-
-    if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
-
-    /* find next format with available data */
-
-    lpFormat = lpFormat->NextFormat;
     while(TRUE) 
     {
 	if (lpFormat == NULL) return 0;
-	if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT && 
-				       ClipFormats[CF_TEXT-1].wDataPresent)) 
+
+	if( lpFormat->wFormatID != CF_OEMTEXT && lpFormat->wFormatID != CF_TEXT )
+	    CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
+
+	if (lpFormat->wDataPresent || 
+	   (lpFormat->wFormatID == CF_OEMTEXT && ClipFormats[CF_TEXT-1].wDataPresent) ||
+	   (lpFormat->wFormatID == CF_TEXT && ClipFormats[CF_OEMTEXT-1].wDataPresent) )
 	    break;
 	lpFormat = lpFormat->NextFormat;
     }
@@ -877,8 +884,7 @@
 {
     TRACE(clipboard,"(%04X) !\n", wFormat);
 
-    if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
-        CLIPBOARD_Driver->pRequestSelection();
+    CLIPBOARD_Driver->pGetData( (wFormat == CF_TEXT) ? CF_OEMTEXT : wFormat );
 
     return CLIPBOARD_IsPresent(wFormat);
 }
diff --git a/windows/message.c b/windows/message.c
index acb89ff..f188849 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -502,12 +502,14 @@
 
     qmsg = sysMsgQueue->firstMsg;
     
-#if 0 
     /* If the queue is empty, attempt to fill it */
     if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() )
                                && EVENT_Pending())
-        EVENT_WaitNetEvent( FALSE, FALSE );
-#endif
+    {
+	LeaveCriticalSection(&sysMsgQueue->cSection);
+        EVENT_WaitNetEvent( FALSE, TRUE );
+	EnterCriticalSection(&sysMsgQueue->cSection);
+    }
 
     for ( kbd_msg = 0; qmsg; qmsg = nextqmsg)
     {
diff --git a/windows/ttydrv/clipboard.c b/windows/ttydrv/clipboard.c
index f6c0c3c..f608b7c 100644
--- a/windows/ttydrv/clipboard.c
+++ b/windows/ttydrv/clipboard.c
@@ -15,7 +15,7 @@
 /***********************************************************************
  *		TTYDRV_CLIPBOARD_EmptyClipboard
  */
-void TTYDRV_CLIPBOARD_EmptyClipboard()
+void TTYDRV_CLIPBOARD_Empty()
 {
   if(TTYDRV_CLIPBOARD_szSelection)
     {
@@ -25,16 +25,16 @@
 }
 
 /***********************************************************************
- *		TTYDRV_CLIPBOARD_SetClipboardData
+ *		TTYDRV_CLIPBOARD_SetData
  */
-void TTYDRV_CLIPBOARD_SetClipboardData(UINT wFormat)
+void TTYDRV_CLIPBOARD_SetData(UINT wFormat)
 {
 }
 
 /***********************************************************************
- *		TTYDRV_CLIPBOARD_RequestSelection
+ *		TTYDRV_CLIPBOARD_GetData
  */
-BOOL TTYDRV_CLIPBOARD_RequestSelection()
+BOOL TTYDRV_CLIPBOARD_GetData(UINT wFormat)
 {
   return FALSE;
 }
diff --git a/windows/ttydrv/init.c b/windows/ttydrv/init.c
index 7f6a15b..f58434c 100644
--- a/windows/ttydrv/init.c
+++ b/windows/ttydrv/init.c
@@ -24,9 +24,9 @@
 
 CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver =
 {
-  TTYDRV_CLIPBOARD_EmptyClipboard,
-  TTYDRV_CLIPBOARD_SetClipboardData,
-  TTYDRV_CLIPBOARD_RequestSelection,
+  TTYDRV_CLIPBOARD_Empty,
+  TTYDRV_CLIPBOARD_SetData,
+  TTYDRV_CLIPBOARD_GetData,
   TTYDRV_CLIPBOARD_ResetOwner
 };
 
diff --git a/windows/win.c b/windows/win.c
index 402319d..67c21f0 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -836,10 +836,14 @@
 
     /* Correct the window style */
 
-    if (!(cs->style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
+    if (!(cs->style & WS_CHILD))
     {
-        wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
-        wndPtr->flags |= WIN_NEED_SIZE;
+	wndPtr->dwStyle |= WS_CLIPSIBLINGS;
+	if (!(cs->style & WS_POPUP))
+	{
+            wndPtr->dwStyle |= WS_CAPTION;
+            wndPtr->flags |= WIN_NEED_SIZE;
+	}
     }
     if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
 
@@ -2701,13 +2705,10 @@
     pWnd = WIN_LockWndPtr(wndPtr->child);
     while (pWnd)
     {
-	if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
-        if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
-        {
+	if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
+           (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
             count++;
-            WIN_UpdateWndPtr(&pWnd,pWnd->next);
-    }
-
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
 
     if( count )
diff --git a/windows/winpos.c b/windows/winpos.c
index aadcd07..d98a4d7 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -48,6 +48,8 @@
 #define SWP_EX_NOCOPY		0x0001
 #define SWP_EX_PAINTSELF	0x0002
 
+#define MINMAX_NOSWP		0x00010000
+
 /* ----- internal variables ----- */
 
 static HWND hwndPrevActive  = 0;  /* Previously active window */
@@ -1138,9 +1140,9 @@
  * This function assumes that 'cmd' is different from the current window
  * state.
  */
-UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
+UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
 {
-    UINT16 swpFlags = 0;
+    UINT swpFlags = 0;
     POINT pt;
     POINT size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top };
     LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size,
@@ -1168,6 +1170,10 @@
 		     wndPtr->flags &= ~WIN_RESTORE_MAX;
 		 wndPtr->dwStyle |= WS_MINIMIZE;
 
+		 if( wndPtr->flags & WIN_NATIVE )
+		     if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
+			 swpFlags |= MINMAX_NOSWP;
+
 		 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
 
 		 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
@@ -1182,6 +1188,10 @@
 
 		 if( wndPtr->dwStyle & WS_MINIMIZE )
 		 {
+		     if( wndPtr->flags & WIN_NATIVE )
+			 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
+			     swpFlags |= MINMAX_NOSWP;
+
 		     WINPOS_ShowIconTitle( wndPtr, FALSE );
 		     wndPtr->dwStyle &= ~WS_MINIMIZE;
 		 }
@@ -1194,8 +1204,13 @@
 	    case SW_RESTORE:
 		 if( wndPtr->dwStyle & WS_MINIMIZE )
 		 {
+		     if( wndPtr->flags & WIN_NATIVE )
+			 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
+			     swpFlags |= MINMAX_NOSWP;
+
 		     wndPtr->dwStyle &= ~WS_MINIMIZE;
 		     WINPOS_ShowIconTitle( wndPtr, FALSE );
+
 		     if( wndPtr->flags & WIN_RESTORE_MAX)
 		     {
 			 /* Restore to maximized position */
@@ -1253,7 +1268,7 @@
     WND* 	wndPtr = WIN_FindWndPtr( hwnd );
     BOOL 	wasVisible, showFlag;
     RECT16 	newPos = {0, 0, 0, 0};
-    int 	swp = 0;
+    UINT 	swp = 0;
 
     if (!wndPtr) return FALSE;
 
@@ -1335,8 +1350,9 @@
     {
         /* We can't activate a child window */
         if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-        SetWindowPos( hwnd, HWND_TOP, 
-			newPos.left, newPos.top, newPos.right, newPos.bottom, swp );
+	if (!(swp & MINMAX_NOSWP))
+	    SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top, 
+					  newPos.right, newPos.bottom, LOWORD(swp) );
         if (!IsWindow( hwnd )) goto END;
 	else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
     }
@@ -1610,8 +1626,8 @@
     HQUEUE16 hOldActiveQueue, hNewActiveQueue;
     MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
     WORD     wIconized = 0;
-    HWND   hwndActive = 0;
-    BOOL   bRet = 0;
+    HWND     hwndActive = 0;
+    BOOL     bRet = 0;
 
     /* Get current active window from the active queue */
     if ( hActiveQueue )
@@ -1622,7 +1638,8 @@
     }
 
     /* paranoid checks */
-    if( hWnd == GetDesktopWindow() || hWnd == hwndActive ) goto CLEANUP;
+    if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
+	goto CLEANUP_END;
 
 /*  if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
  *	return 0;
@@ -1641,20 +1658,12 @@
     /* call CBT hook chain */
     if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
     {
-        LRESULT wRet;
         cbtStruct->fMouse     = fMouse;
         cbtStruct->hWndActive = hwndActive;
-        wRet = HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
-                                 (LPARAM)SEGPTR_GET(cbtStruct) );
+        bRet = (BOOL)HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
+                                     (LPARAM)SEGPTR_GET(cbtStruct) );
         SEGPTR_FREE(cbtStruct);
-        if (wRet)
-        {
-            /* Unlock the active queue before returning */
-            if ( pOldActiveQueue )
-                QUEUE_Unlock( pOldActiveQueue );
-            WIN_ReleaseWndPtr(wndPtr);
-            return wRet;
-        }
+        if (bRet) goto CLEANUP_END;
     }
 
     /* set prev active wnd to current active wnd and send notification */
@@ -1664,20 +1673,14 @@
         
         if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
         {
-	    if (GetSysModalWindow16() != hWnd) goto CLEANUP;
+	    if (GetSysModalWindow16() != hWnd) 
+		goto CLEANUP_END;
 	    /* disregard refusal if hWnd is sysmodal */
         }
 
-#if 1
 	SendMessageA( hwndPrevActive, WM_ACTIVATE,
                         MAKEWPARAM( WA_INACTIVE, wIconized ),
                         (LPARAM)hWnd );
-#else
-	/* FIXME: must be SendMessage16() because A doesn't do
-	 * intertask at this time */
-	SendMessage16( hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
-				MAKELPARAM( (HWND16)hWnd, wIconized ) );
-#endif
 
         /* check if something happened during message processing
          * (global active queue may have changed)
@@ -1686,7 +1689,7 @@
         hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
         QUEUE_Unlock( pTempActiveQueue );
         if( hwndPrevActive != hwndActive )
-            goto CLEANUP;
+            goto CLEANUP_END;
     }
 
     /* Set new active window in the message queue */
@@ -1722,7 +1725,8 @@
 	if( wndTemp != wndPtr )
 	    SetWindowPos(hWnd, HWND_TOP, 0,0,0,0, 
 			   SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
-        if (!IsWindow(hWnd))  goto CLEANUP;
+        if (!IsWindow(hWnd))  
+	    goto CLEANUP;
     }
 
     /* Get a handle to the new active queue */
@@ -1780,15 +1784,9 @@
         wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
         WIN_ReleaseWndPtr(wndTemp);
         SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
-#if 1
         SendMessageA( hWnd, WM_ACTIVATE,
 		 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
 		 (LPARAM)hwndPrevActive );
-#else
-        SendMessage16(hWnd, WM_ACTIVATE, (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE,
-                      MAKELPARAM( (HWND16)hwndPrevActive, wIconized) );
-#endif
-
         if( !IsWindow(hWnd) ) goto CLEANUP;
     }
 
@@ -1807,17 +1805,20 @@
     /* if active wnd is minimized redraw icon title */
     if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
 
-    bRet = 1;  // Success
+    bRet = (hWnd == hwndActive);  /* Success? */
     
-CLEANUP:
+CLEANUP: /* Unlock the message queues before returning */
 
-    /* Unlock the message queues before returning */
-    if ( pOldActiveQueue )
-        QUEUE_Unlock( pOldActiveQueue );
     if ( pNewActiveQueue )
         QUEUE_Unlock( pNewActiveQueue );
+
+CLEANUP_END:
+
+    if ( pOldActiveQueue )
+        QUEUE_Unlock( pOldActiveQueue );
+
     WIN_ReleaseWndPtr(wndPtr);
-    return bRet ? (hWnd == hwndActive) : 0;
+    return bRet;
 }
 
 /*******************************************************************
@@ -2231,35 +2232,70 @@
 
 /***********************************************************************
  *           SWP_DoSimpleFrameChanged
+ *
+ * NOTE: old and new client rect origins are identical, only
+ *	 extents may have changed. Window extents are the same.
  */
-static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pNewClientRect, RECT* pOldClientRect )
+static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pOldClientRect, WORD swpFlags, UINT uFlags )
 {
-    WORD wErase = 0;
+    INT	 i = 0;
     RECT rect;
+    HRGN hrgn = 0;
 
-    if( pNewClientRect->right > pOldClientRect->right ) /* redraw exposed client area on the right */
+    if( !(swpFlags & SWP_NOCLIENTSIZE) )
     {
-	rect.top = 0; rect.bottom = pNewClientRect->bottom - pNewClientRect->top;
-	rect.left = pOldClientRect->right - pNewClientRect->left;
-	rect.right = pNewClientRect->right - pNewClientRect->left;
-	wErase = 1;
-	PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | 
-			    RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME );
-     }
-     if( pNewClientRect->bottom > pOldClientRect->bottom ) /* redraw exposed client area on the bottom */
-     {
-	rect.left = 0; rect.right = ((wErase)? pOldClientRect->right : pNewClientRect->right) - pNewClientRect->left;
-	rect.top = pOldClientRect->bottom - pNewClientRect->top;
-	rect.bottom = pNewClientRect->bottom - pNewClientRect->top;
-        wErase = 1;
-        PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | 
-			    RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME );
-     }
-     if( !wErase ) /* IMMEDIATELY update the nonclient area */
-     {
-	HRGN h;
-        if( (h = WIN_UpdateNCRgn(wndPtr, TRUE, TRUE)) > 1) DeleteObject( h );
-     }
+	/* FIXME: WVR alignment flags */
+
+	if( wndPtr->rectClient.right >  pOldClientRect->right ) /* right edge */
+	{
+	    i++;
+	    rect.top = 0; 
+	    rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+	    rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
+	    if(!(uFlags & SWP_EX_NOCOPY))
+		rect.left = pOldClientRect->right - wndPtr->rectClient.left;
+	    else
+	    {
+		rect.left = 0;
+		goto redraw;
+	    }
+	}
+
+	if( wndPtr->rectClient.bottom > pOldClientRect->bottom ) /* bottom edge */
+	{
+	    if( i )
+		hrgn = CreateRectRgnIndirect( &rect );
+	    rect.left = 0;
+	    rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
+	    rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+	    if(!(uFlags & SWP_EX_NOCOPY))
+		rect.top = pOldClientRect->bottom - wndPtr->rectClient.top;
+	    else
+		rect.top = 0;
+	    if( i++ ) 
+		REGION_UnionRectWithRgn( hrgn, &rect );
+	}
+
+	if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
+	{
+	    rect = wndPtr->rectWindow;
+	    OffsetRect( &rect, wndPtr->rectWindow.left - wndPtr->rectClient.left,
+			       wndPtr->rectWindow.top - wndPtr->rectClient.top );
+	    i++;
+	}
+    }
+
+    if( i )
+    {
+redraw:
+	PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
+			    RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
+    }
+    else
+	hrgn = WIN_UpdateNCRgn(wndPtr, TRUE, TRUE);
+
+    if( hrgn > 1 )
+	DeleteObject( hrgn );
 }
 
 /***********************************************************************
@@ -2482,7 +2518,7 @@
 
     /* Common operations */
 
-    SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
+    wvrFlags = SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
 
     if(!(winpos.flags & SWP_NOZORDER))
     {
@@ -2505,6 +2541,23 @@
     oldWindowRect = wndPtr->rectWindow;
     oldClientRect = wndPtr->rectClient;
 
+    /* Find out if we have to redraw the whole client rect */
+
+    if( oldClientRect.bottom - oldClientRect.top ==
+        newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
+
+    if( oldClientRect.right - oldClientRect.left ==
+        newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
+
+    uFlags |=  ((winpos.flags & SWP_NOCOPYBITS) ||
+                (!(winpos.flags & SWP_NOCLIENTSIZE) && 
+		  (wvrFlags >= WVR_HREDRAW) && (wvrFlags < WVR_VALIDRECTS))) ? SWP_EX_NOCOPY : 0;
+
+    /* FIXME: actually do something with WVR_VALIDRECTS */
+
+    wndPtr->rectWindow = newWindowRect;
+    wndPtr->rectClient = newClientRect;
+
     if (wndPtr->flags & WIN_NATIVE) 	/* -------------------------------------------- hosted window */
     {
 	BOOL bCallDriver = TRUE;
@@ -2512,9 +2565,6 @@
 
         winpos.hwndInsertAfter = hwndInsertAfter;
 
-        wndPtr->rectWindow = newWindowRect;
-        wndPtr->rectClient = newClientRect;
-
 	if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
         {
 	  /* This is the only place where we need to force repainting of the contents
@@ -2533,15 +2583,15 @@
 		    winpos.hwndInsertAfter = tempInsertAfter;
 		    bCallDriver = FALSE;
 
-		    if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
-		        (oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top)   )
-			SWP_DoSimpleFrameChanged(wndPtr, &newClientRect, &oldClientRect );
+		    if( winpos.flags & SWP_NOCLIENTMOVE )
+			SWP_DoSimpleFrameChanged(wndPtr, &oldClientRect, winpos.flags, uFlags );
 		    else
 		    {
 		        /* client area moved but window extents remained the same, copy valid bits */
 
 		        visRgn = CreateRectRgn( 0, 0, x, y );
-		        uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect, &oldClientRect, SWP_EX_PAINTSELF);
+		        uFlags = SWP_CopyValidBits( wndPtr, &visRgn, &oldWindowRect, &oldClientRect, 
+						    uFlags | SWP_EX_PAINTSELF );
 		    }
 		}
 	    }
@@ -2552,9 +2602,14 @@
 	  if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
 	  {
 	    if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
-		(oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top)   )
+		(oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) &&
+		!(uFlags & SWP_EX_NOCOPY) )
 	    {
-		if( !(wndPtr->flags & WIN_MANAGED) ) /* force outer frame redraw */
+		/* The origin of the client rect didn't move so we can try to repaint
+		 * only the nonclient area by setting bit gravity hint for the host window system.
+		 */
+
+		if( !(wndPtr->flags & WIN_MANAGED) )
 		{
 		    HRGN hrgn = CreateRectRgn( 0, 0, newWindowRect.right - newWindowRect.left,
 						     newWindowRect.bottom - newWindowRect.top);
@@ -2606,20 +2661,11 @@
     }
     else 				/* -------------------------------------------- emulated window */
     {
-        wndPtr->rectWindow = newWindowRect;
-        wndPtr->rectClient = newClientRect;
-
-	if( oldClientRect.bottom - oldClientRect.top ==
-	    newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
-
-	if( oldClientRect.right - oldClientRect.left ==
-	    newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
-
 	    if( winpos.flags & SWP_SHOWWINDOW )
 	    {
 		wndPtr->dwStyle |= WS_VISIBLE;
 		uFlags |= SWP_EX_PAINTSELF;
-		visRgn = 1;
+		visRgn = 1; /* redraw the whole window */
 	    }
 	    else if( !(winpos.flags & SWP_NOREDRAW) )
 	    {
@@ -2632,16 +2678,15 @@
 		}
 		else
 		{
-		    uFlags |=  ((winpos.flags & SWP_NOCOPYBITS) || 
-			(wvrFlags >= WVR_HREDRAW && wvrFlags < WVR_VALIDRECTS)) ? SWP_EX_NOCOPY : 0;
-
 		    if( (winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE )
 		         uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect, 
 							    &oldClientRect, uFlags);
 	            else
 		    {
+			/* nothing moved, redraw frame if needed */
+			 
 		        if( winpos.flags & SWP_FRAMECHANGED )
-			    SWP_DoSimpleFrameChanged( wndPtr, &newClientRect, &oldClientRect );
+			    SWP_DoSimpleFrameChanged( wndPtr, &oldClientRect, winpos.flags, uFlags );
 		        if( visRgn )
 		        {
 			    DeleteObject( visRgn );
@@ -2669,11 +2714,6 @@
 
     /* ------------------------------------------------------------------------ FINAL */
 
-      /* Activate the window */
-
-    if (!(flags & SWP_NOACTIVATE))
-	    WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
-    
     if (wndPtr->flags & WIN_NATIVE)
         EVENT_Synchronize();  /* Synchronize with the host window system */
 
@@ -2682,7 +2722,11 @@
 
     wndTemp = WIN_GetDesktop();
 
-    /* repaint invalidated region (if any) */
+    /* repaint invalidated region (if any) 
+     *
+     * FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
+     *        and force update after ChangeActiveWindow() to avoid painting frames twice.
+     */
 
     if( visRgn )
     {
@@ -2707,6 +2751,9 @@
 
     WIN_ReleaseDesktop();
 
+    if (!(flags & SWP_NOACTIVATE))
+            WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
+
       /* And last, send the WM_WINDOWPOSCHANGED message */
 
     TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 9a730c7..92da752 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -24,7 +24,6 @@
 extern HWND hWndClipWindow;
 extern WINE_CLIPFORMAT ClipFormats[];
 
-static Bool   selectionWait = False;
 static Bool   selectionAcquired = False;
 static Window selectionWindow = None;
 static Window selectionPrevWindow = None;
@@ -67,15 +66,13 @@
 
 /**************************************************************************
  *		X11DRV_CLIPBOARD_ReadSelection
- *
- * Called from the SelectionNotify event handler. 
  */
-void X11DRV_CLIPBOARD_ReadSelection(Window w,Atom prop)
+static void X11DRV_CLIPBOARD_ReadSelection(Window w, Atom prop)
 {
     HANDLE 	 hText = 0;
     LPWINE_CLIPFORMAT lpFormat = ClipFormats; 
 
-    TRACE(clipboard,"ReadSelection callback\n");
+    TRACE(clipboard,"Reading X selection...\n");
 
     if(prop != None)
     {
@@ -126,19 +123,16 @@
 
    if( hText )
    {
-     lpFormat = &ClipFormats[CF_TEXT-1];
-     if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32) 
-         CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
-     lpFormat = &ClipFormats[CF_OEMTEXT-1];
-     if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)  
-         CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
-
-     lpFormat->wDataPresent = 1;
-     lpFormat->hData32 = hText;
-     lpFormat->hData16 = 0;
+       lpFormat = &ClipFormats[CF_TEXT-1];
+       if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32) 
+           CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
+       lpFormat = &ClipFormats[CF_OEMTEXT-1];
+       if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)  
+           CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
+       lpFormat->wDataPresent = 1;
+       lpFormat->hData32 = hText;
+       lpFormat->hData16 = 0;
    }
-
-   selectionWait=False;
 }
 
 /**************************************************************************
@@ -180,27 +174,35 @@
 }
 
 /**************************************************************************
- *		X11DRV_CLIPBOARD_EmptyClipboard
+ *		X11DRV_CLIPBOARD_Empty
  */
-void X11DRV_CLIPBOARD_EmptyClipboard()
+void X11DRV_CLIPBOARD_Empty()
 {
-  if(selectionAcquired)
+    if( selectionAcquired )
     {
-      selectionAcquired	= False;
-      selectionPrevWindow 	= selectionWindow;
-      selectionWindow 	= None;
+	XEvent xe;
+
+	selectionAcquired   = False;
+	selectionPrevWindow = selectionWindow;
+	selectionWindow     = None;
       
-      TRACE(clipboard, "\tgiving up selection (spw = %08x)\n", 
-	    (unsigned)selectionPrevWindow);
+	TRACE(clipboard, "\tgiving up selection (spw = %08x)\n", 
+	     (unsigned)selectionPrevWindow);
       
-      TSXSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
+	EnterCriticalSection(&X11DRV_CritSection);
+	XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
+
+	if( selectionPrevWindow )
+	    while( !XCheckTypedWindowEvent( display, selectionPrevWindow,
+					    SelectionClear, &xe ) );
+	LeaveCriticalSection(&X11DRV_CritSection);
     }
 }
 
 /**************************************************************************
- *		X11DRV_CLIPBOARD_SetClipboardData
+ *		X11DRV_CLIPBOARD_SetData
  */
-void X11DRV_CLIPBOARD_SetClipboardData(UINT wFormat)
+void X11DRV_CLIPBOARD_SetData(UINT wFormat)
 {
     Window       owner;
 
@@ -226,45 +228,55 @@
 }
 
 /**************************************************************************
- *		X11DRV_CLIPBOARD_RequestSelection
+ *		X11DRV_CLIPBOARD_GetData
+ *
+ * NOTE: Clipboard driver doesn't get requests for CF_TEXT data, only
+ *	 for CF_OEMTEXT.
  */
-BOOL X11DRV_CLIPBOARD_RequestSelection()
+BOOL X11DRV_CLIPBOARD_GetData(UINT wFormat)
 {
+    BOOL bRet = selectionAcquired;
     HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
-    WND *tmpWnd = WIN_FindWndPtr(hWnd);
+    WND* wnd = NULL;
 
-    if( selectionAcquired )
-      return TRUE;
+    if( wFormat != CF_OEMTEXT ) return FALSE;
 
-    if( !hWnd ) return FALSE;
+    if( !bRet && (wnd = WIN_FindWndPtr(hWnd)) )
+    {
+	XEvent xe;
+	Window w = X11DRV_WND_FindXWindow(wnd);
 
-    TRACE(clipboard,"Requesting selection...\n");
+	TRACE(clipboard, "Requesting XA_STRING selection...\n");
 
-  /* request data type XA_STRING, later
-   * CLIPBOARD_ReadSelection() will be invoked 
-   * from the SelectionNotify event handler */
-
-    TSXConvertSelection(display, XA_PRIMARY, XA_STRING,
-			TSXInternAtom(display, "PRIMARY_TEXT", False),
-			X11DRV_WND_FindXWindow(tmpWnd ),
-			CurrentTime);
+	EnterCriticalSection( &X11DRV_CritSection );
+	XConvertSelection(display, XA_PRIMARY, XA_STRING,
+			XInternAtom(display, "PRIMARY_TEXT", False),
+			w, CurrentTime);
     
-    WIN_ReleaseWndPtr(tmpWnd);
+        /* wait until SelectionNotify is received */
 
-  /* wait until SelectionNotify is processed 
-   *
-   * FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the 
-   *	    CLIPBOARD_CheckSelection() ). 
-   */
+	while( TRUE )
+	{
+	   if( XCheckTypedWindowEvent(display, w, SelectionNotify, &xe) )
+	       if( xe.xselection.selection == XA_PRIMARY )
+		   break;
+	}
+	LeaveCriticalSection( &X11DRV_CritSection );
 
-    selectionWait=True;
-    while(selectionWait) EVENT_WaitNetEvent( TRUE, FALSE );
+	if (xe.xselection.target != XA_STRING) 
+	    X11DRV_CLIPBOARD_ReadSelection( 0, None );
+	else 
+	    X11DRV_CLIPBOARD_ReadSelection( xe.xselection.requestor, 
+					    xe.xselection.property );
 
-  /* we treat Unix text as CF_OEMTEXT */
-    TRACE(clipboard,"\tgot CF_OEMTEXT = %i\n", 
-		      ClipFormats[CF_OEMTEXT-1].wDataPresent);
+	/* treat Unix text as CF_OEMTEXT */
 
-    return (BOOL)ClipFormats[CF_OEMTEXT-1].wDataPresent;
+	bRet = (BOOL)ClipFormats[CF_OEMTEXT-1].wDataPresent;
+
+	TRACE(clipboard,"\tpresent CF_OEMTEXT = %i\n", bRet );
+	WIN_ReleaseWndPtr(wnd);
+    }
+    return bRet;
 }
 
 /**************************************************************************
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 106903a..876dbfa 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -95,10 +95,10 @@
 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
 static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event );
 static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
-static void EVENT_SelectionNotify( XSelectionEvent *event);
 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
-static void EVENT_MapNotify( HWND hwnd, XMapEvent *event );
+static void EVENT_MapNotify( WND* wnd, XMapEvent *event );
+static void EVENT_UnmapNotify( WND* wnd, XUnmapEvent *event );
 
 /* Usable only with OLVWM - compile option perhaps?
 static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
@@ -387,19 +387,22 @@
   WND *pWnd;
 
   switch (event->type)
-    {
+  {
+    case SelectionNotify: /* all of these should be caught by XCheckTypedWindowEvent() */
+	 FIXME(event,"Got SelectionNotify - must not happen!\n");
+	 /* fall through */
+
       /* We get all these because of StructureNotifyMask.
          This check is placed here to avoid getting error messages below,
          as X might send some of these even for windows that have already
          been deleted ... */
-    case UnmapNotify:
     case CirculateNotify:
     case CreateNotify:
     case DestroyNotify:
     case GravityNotify:
     case ReparentNotify:
       return;
-    }
+  }
       
   if ( TSXFindContext( display, event->xany.window, winContext,
 		       (char **)&pWnd ) != 0) {
@@ -482,11 +485,6 @@
       EVENT_SelectionRequest( pWnd, (XSelectionRequestEvent *)event );
       break;
 
-    case SelectionNotify:
-      if (!pWnd) return;
-      EVENT_SelectionNotify( (XSelectionEvent *)event );
-      break;
-
     case SelectionClear:
       if (!pWnd) return;
       EVENT_SelectionClear( pWnd, (XSelectionClearEvent*) event );
@@ -508,9 +506,14 @@
       
     case MapNotify:
       if (!pWnd) return;
-      EVENT_MapNotify( pWnd->hwndSelf, (XMapEvent *)event );
+      EVENT_MapNotify( pWnd, (XMapEvent *)event );
       break;
-      
+
+    case UnmapNotify:
+      if (!pWnd) return;
+      EVENT_UnmapNotify( pWnd, (XUnmapEvent *)event );
+      break;
+
     default:    
       WARN(event, "Unprocessed event %s for hwnd %04x\n",
 	   event_names[event->type], pWnd? pWnd->hwndSelf : 0 );
@@ -1037,7 +1040,7 @@
 
   if( oldClientRect.top - oldWindowRect.top != newClientRect.top - newWindowRect.top ||
       oldClientRect.left - oldWindowRect.left != newClientRect.left - newWindowRect.left )
-      RedrawWindow( winpos.hwnd, 0, NULL, RDW_FRAME | RDW_ALLCHILDREN |
+      RedrawWindow( winpos.hwnd, NULL, 0, RDW_FRAME | RDW_ALLCHILDREN |
                                           RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
 
   SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
@@ -1059,22 +1062,26 @@
 {
   XSelectionEvent result;
   Atom 	    rprop = None;
-  Window 	    request = event->requestor;
+  Window    request = event->requestor;
 
   if(event->target == XA_STRING)
-    {
+  {
       HANDLE16 hText;
       LPSTR  text;
       int    size,i,j;
       
       rprop = event->property;
       
-      if(rprop == None) rprop = event->target;
+      if( rprop == None ) 
+	  rprop = event->target;
       
-      if(event->selection!=XA_PRIMARY) rprop = None;
-      else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None;
+      if( event->selection != XA_PRIMARY ) 
+	  rprop = None;
+      else 
+      if( !CLIPBOARD_IsPresent(CF_OEMTEXT) ) 
+	  rprop = None;
       else
-	{
+      {
 	  /* open to make sure that clipboard is available */
 
 	  BOOL couldOpen = OpenClipboard( pWnd->hwndSelf );
@@ -1088,11 +1095,11 @@
 	  
 	  lpstr = (char*)HEAP_xalloc( GetProcessHeap(), 0, size-- );
 	  for(i=0,j=0; i < size && text[i]; i++ )
-	    {
+	  {
 	      if( text[i] == '\r' && 
 		  (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
 	      lpstr[j++] = text[i];
-	    }
+	  }
 	  lpstr[j]='\0';
 	  
 	  TSXChangeProperty(display, request, rprop, 
@@ -1103,11 +1110,13 @@
 	  /* close only if we opened before */
 	  
 	  if(couldOpen) CloseClipboard();
-	}
-    }
+      }
+  }
   
-  if(rprop == None) 
-    TRACE(event,"Request for %s ignored\n", TSXGetAtomName(display,event->target));
+  if( rprop == None) 
+      TRACE(event,"Request for %s ignored\n", TSXGetAtomName(display,event->target));
+
+  /* reply to sender */
   
   result.type = SelectionNotify;
   result.display = display;
@@ -1119,21 +1128,6 @@
   TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
 }
 
-
-/***********************************************************************
- *           EVENT_SelectionNotify
- */
-static void EVENT_SelectionNotify( XSelectionEvent *event )
-{
-  if (event->selection != XA_PRIMARY) return;
-  
-  if (event->target != XA_STRING) X11DRV_CLIPBOARD_ReadSelection( 0, None );
-  else X11DRV_CLIPBOARD_ReadSelection( event->requestor, event->property );
-  
-  TRACE(event, "\tSelectionNotify done!\n");
-}
-
-
 /***********************************************************************
  *           EVENT_SelectionClear
  */
@@ -1465,18 +1459,36 @@
 /**********************************************************************
  *		EVENT_MapNotify
  */
-void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
+void EVENT_MapNotify( WND* wnd, XMapEvent *event )
 {
   HWND hwndFocus = GetFocus();
-  WND *tmpWnd = WIN_FindWndPtr(hwndFocus);
-  
-  if (hwndFocus && IsChild( hWnd, hwndFocus ))
-      X11DRV_WND_SetFocus(tmpWnd );
-  WIN_ReleaseWndPtr(tmpWnd);
+  WND *wndFocus = WIN_FindWndPtr(hwndFocus);
+
+  if (wnd->flags & WIN_MANAGED)
+      wnd->dwStyle &= ~WS_MINIMIZE;
+
+  if (hwndFocus && IsChild( wnd->hwndSelf, hwndFocus ))
+      X11DRV_WND_SetFocus(wndFocus);
+
+  WIN_ReleaseWndPtr(wndFocus);
   
   return;
 }
 
+
+/**********************************************************************
+ *              EVENT_MapNotify
+ */
+void EVENT_UnmapNotify( WND* wnd, XUnmapEvent *event )
+{
+  if (wnd->flags & WIN_MANAGED) 
+  {
+      EndMenu();
+      wnd->dwStyle |= WS_MINIMIZE;
+  }
+}
+
+
 /**********************************************************************
  *		X11DRV_EVENT_Pending
  */
diff --git a/windows/x11drv/init.c b/windows/x11drv/init.c
index d7a59e1..f3c5f65 100644
--- a/windows/x11drv/init.c
+++ b/windows/x11drv/init.c
@@ -28,9 +28,9 @@
 
 CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver =
 {
-  X11DRV_CLIPBOARD_EmptyClipboard,
-  X11DRV_CLIPBOARD_SetClipboardData,
-  X11DRV_CLIPBOARD_RequestSelection,
+  X11DRV_CLIPBOARD_Empty,
+  X11DRV_CLIPBOARD_SetData,
+  X11DRV_CLIPBOARD_GetData,
   X11DRV_CLIPBOARD_ResetOwner
 };
 
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index a877dec..1993d5e 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -16,6 +16,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include "bitmap.h"
 #include "color.h"
 #include "debug.h"
 #include "display.h"
@@ -27,10 +28,13 @@
 #include "windef.h"
 #include "class.h"
 #include "x11drv.h"
+#include "wine/winuser16.h"
 
 /**********************************************************************/
 
 extern Cursor X11DRV_MOUSE_XCursor;  /* Current X cursor */
+extern BOOL   X11DRV_CreateBitmap( HBITMAP );
+extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
 
 /**********************************************************************/
 
@@ -41,6 +45,7 @@
 Atom wmDeleteWindow = None;
 Atom dndProtocol = None;
 Atom dndSelection = None;
+Atom wmChangeState = None;
 
 /***********************************************************************
  *		X11DRV_WND_GetXWindow
@@ -152,6 +157,8 @@
 	dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
     if( dndSelection == None )
 	dndSelection = TSXInternAtom( display, "DndSelection" , False );
+    if( wmChangeState == None )
+        wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
 
     ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = 
       X11DRV_WND_GetXRootWindow( wndPtr );
@@ -160,6 +167,7 @@
     return TRUE;
 }
 
+
 /**********************************************************************
  *		X11DRV_WND_CreateWindow
  */
@@ -195,13 +203,14 @@
 	}
       wndPtr->flags |= WIN_NATIVE;
 
-      win_attr.bit_gravity   = BGNorthWest;
+      win_attr.bit_gravity   = (classPtr->style & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest;
       win_attr.colormap      = X11DRV_PALETTE_PaletteXColormap;
       win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
       win_attr.save_under    = ((classPtr->style & CS_SAVEBITS) != 0);
       win_attr.cursor        = X11DRV_MOUSE_XCursor;
 
-      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = BGNorthWest;
+      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
+      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = win_attr.bit_gravity;
       ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = 
 	TSXCreateWindow( display, 
 			 X11DRV_WND_GetXRootWindow(wndPtr), 
@@ -216,28 +225,32 @@
       if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
 	return FALSE;
 
-      if (wndPtr->flags & WIN_MANAGED) {
-	XClassHint *class_hints = TSXAllocClassHint();
+      if (wndPtr->flags & WIN_MANAGED) 
+      {
+	  XClassHint *class_hints = TSXAllocClassHint();
 
-	if (class_hints) {
-	  class_hints->res_name = "wineManaged";
-	  class_hints->res_class = "Wine";
-	  TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
-	  TSXFree (class_hints);
-	}
+	  if (class_hints) 
+	  {
+	      class_hints->res_name = "wineManaged";
+	      class_hints->res_class = "Wine";
+	      TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
+	      TSXFree (class_hints);
+	  }
 
-	if (cs->dwExStyle & WS_EX_DLGMODALFRAME) {
-	  XSizeHints* size_hints = TSXAllocSizeHints();
+	  if (cs->dwExStyle & WS_EX_DLGMODALFRAME) 
+	  {
+	      XSizeHints* size_hints = TSXAllocSizeHints();
 	  
-	  if (size_hints) {
-	      size_hints->min_width = size_hints->max_width = cs->cx;
-	      size_hints->min_height = size_hints->max_height = cs->cy;
-                size_hints->flags = (PSize | PMinSize | PMaxSize);
-                TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), size_hints,
-				   XA_WM_NORMAL_HINTS );
-                TSXFree(size_hints);
-            }
-        }
+	      if (size_hints) 
+	      {
+	          size_hints->min_width = size_hints->max_width = cs->cx;
+	          size_hints->min_height = size_hints->max_height = cs->cy;
+                  size_hints->flags = (PSize | PMinSize | PMaxSize);
+                  TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), 
+					size_hints, XA_WM_NORMAL_HINTS );
+                  TSXFree(size_hints);
+              }
+          }
       }
       
       if (cs->hwndParent)  /* Get window owner */
@@ -258,12 +271,36 @@
       {
 	  wm_hints->flags = InputHint | StateHint | WindowGroupHint;
 	  wm_hints->input = True;
-	  if( wndPtr->dwStyle & WS_VISIBLE )
-	      wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE &&
-					wndPtr->flags & WIN_MANAGED ) ? 
-					IconicState : NormalState;
+
+	  if( wndPtr->flags & WIN_MANAGED )
+	  {
+	      if( wndPtr->class->hIcon )
+	      { 
+		  CURSORICONINFO *ptr;
+
+		  if( (ptr = (CURSORICONINFO *)GlobalLock16( wndPtr->class->hIcon )) )
+		  {
+		      /* This is not entirely correct, may need to create
+		       * an icon window and set the pixmap as a background */
+
+		      HBITMAP hBitmap = CreateBitmap( ptr->nWidth, ptr->nHeight, 
+		   	  ptr->bPlanes, ptr->bBitsPerPixel, (char *)(ptr + 1) +
+                          ptr->nHeight * BITMAP_GetWidthBytes(ptr->nWidth,1) );
+
+		      if( hBitmap )
+		      {
+			((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = hBitmap;
+			  X11DRV_CreateBitmap( hBitmap );
+			  wm_hints->flags |= IconPixmapHint;
+			  wm_hints->icon_pixmap = X11DRV_BITMAP_Pixmap( hBitmap );
+		      }
+		   }
+	      }
+	      wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE) 
+					? IconicState : NormalState;
+	  }
 	  else
-	      wm_hints->initial_state = WithdrawnState;
+	      wm_hints->initial_state = NormalState;
 	  wm_hints->window_group = wGroupLeader;
 
 	  TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
@@ -279,14 +316,21 @@
  */
 BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
 {
-   if (X11DRV_WND_GetXWindow(wndPtr))
-     {
+   Window w;
+   if ((w = X11DRV_WND_GetXWindow(wndPtr)))
+   {
        XEvent xe;
-       TSXDeleteContext( display, X11DRV_WND_GetXWindow(wndPtr), winContext );
-       TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
-       while( TSXCheckWindowEvent(display, X11DRV_WND_GetXWindow(wndPtr), NoEventMask, &xe) );
+       TSXDeleteContext( display, w, winContext );
+       TSXDestroyWindow( display, w );
+       while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
+
        ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
-     }
+       if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
+       {
+	   DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
+	   ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
+       }
+   }
 
    return TRUE;
 }
@@ -449,7 +493,7 @@
 
     if(bChangePos)
     {
-      if ( !(winpos->flags & SWP_NOSIZE))
+	if ( !(winpos->flags & SWP_NOSIZE))
 	{
 	  winChanges.width     = (winpos->cx > 0 ) ? winpos->cx : 1;
 	  winChanges.height    = (winpos->cy > 0 ) ? winpos->cy : 1;
@@ -476,13 +520,13 @@
 		}
 	    }
 	}
-      if (!(winpos->flags & SWP_NOMOVE))
+	if (!(winpos->flags & SWP_NOMOVE))
 	{
 	  winChanges.x = winpos->x;
 	  winChanges.y = winpos->y;
 	  changeMask |= CWX | CWY;
 	}
-      if (!(winpos->flags & SWP_NOZORDER))
+	if (!(winpos->flags & SWP_NOZORDER))
 	{
 	  winChanges.stack_mode = Below;
 	  changeMask |= CWStackMode;
@@ -504,15 +548,18 @@
               WIN_ReleaseWndPtr(insertPtr);
 	    }
 	}
-      if (changeMask)
+	if (changeMask)
 	{
-	  TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
+	    TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
+	    if( winposPtr->class->style & (CS_VREDRAW | CS_HREDRAW) )
+		X11DRV_WND_SetHostAttr( winposPtr, HAK_BITGRAVITY, BGForget );
 	}
     }
 
     if ( winpos->flags & SWP_SHOWWINDOW )
     {
-      if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
+	if(X11DRV_WND_GetXWindow(wndPtr)) 
+	   TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
     }
     WIN_ReleaseWndPtr(winposPtr);
 }
@@ -668,7 +715,46 @@
 }
 
 /***********************************************************************
+ *              X11DRV_SetWMHint
+ */
+static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
+{
+    XWMHints* wm_hints = TSXAllocWMHints();
+    {
+        wm_hints->flags = hint;
+	switch( hint )
+	{
+	    case InputHint:
+		 wm_hints->input = val;
+		 break;
+
+	    case StateHint:
+		 wm_hints->initial_state = val;
+		 break;
+
+	    case IconPixmapHint:
+		 wm_hints->icon_pixmap = (Pixmap)val;
+		 break;
+
+	    case IconWindowHint:
+		 wm_hints->icon_window = (Window)val;
+		 break;
+	}
+
+        TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
+        TSXFree(wm_hints);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
  *              X11DRV_WND_SetHostAttr
+ *
+ * This function returns TRUE if the attribute is supported and the
+ * action was successful. Otherwise it should return FALSE and Wine will try 
+ * to get by without the functionality provided by the host window system.
  */
 BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
 {
@@ -680,7 +766,55 @@
 
 	switch( ha )
 	{
-	case HAK_BITGRAVITY:
+	case HAK_ICONICSTATE: /* called when a window is minimized/restored */
+
+		    if( (wnd->flags & WIN_MANAGED) )
+		    {
+			if( value )
+			{
+			    if( wnd->dwStyle & WS_VISIBLE )
+			    {
+				XClientMessageEvent ev;
+
+				/* FIXME: set proper icon */
+
+				ev.type = ClientMessage;
+				ev.display = display;
+				ev.message_type = wmChangeState;
+				ev.format = 32;
+				ev.data.l[0] = IconicState;
+				ev.window = w;
+
+				if( TSXSendEvent (display,
+		RootWindow( display, XScreenNumberOfScreen(X11DRV_WND_GetXScreen(wnd)) ), 
+		True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
+				{
+				    XEvent xe;
+				    TSXFlush (display);
+				    while( !TSXCheckTypedWindowEvent( display, w, UnmapNotify, &xe) );
+				}
+				else 
+				    break;
+			    }
+			    else
+				X11DRV_SetWMHint( display, wnd, StateHint, IconicState );
+			}
+			else
+			{
+			    if( !(wnd->flags & WS_VISIBLE) )
+				X11DRV_SetWMHint( display, wnd, StateHint, NormalState );
+			    else
+			    {
+				XEvent xe;
+				XMapWindow(display, w );
+				while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
+			    }
+			}
+			return TRUE;
+		    }
+		    break;
+
+	case HAK_BITGRAVITY: /* called when a window is resized */
 
 		    if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value )
 		    {
@@ -688,24 +822,12 @@
 		        ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value;
 		        TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr );
 		    }
-		    return TRUE;
+		   return TRUE;
 
-	case HAK_ACCEPTFOCUS:
+	case HAK_ACCEPTFOCUS: /* called when a window is disabled/enabled */
 
 		if( (wnd->flags & WIN_MANAGED) )
-		{
-		    XWMHints* wm_hints = TSXAllocWMHints();
-
-		    if( wm_hints )
-		    {
-			wm_hints->flags = InputHint;
-			wm_hints->input = value;
-			TSXSetWMHints( display, X11DRV_WND_GetXWindow(wnd), wm_hints );
-			TSXFree( wm_hints );
-			return TRUE;
-		    }
-		}
-		break;
+		    return X11DRV_SetWMHint( display, wnd, InputHint, value );
 	}
     }
     return FALSE;