Release 971116

Sun Nov 16 07:42:44 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/dce.c] [windows/clipboard.c] [windows/nonclient.c]
	Bug fixes.

	* [misc/shell.c] [resources/*]
	New "About" dialog.

Sat Nov 15 17:30:18 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in] [Makefile.in]
	Replaced --with-library option by --disable-emulator. The default
 	is now to build both the library and the emulator.
	Renamed --with options to --enable to follow autoconf guidelines.

	* [loader/main.c] [miscemu/main.c] (New file)
	Split initialization in WinelibInit/EmulatorInit.

	* [loader/*.c]
	Removed all remaining #ifdef's WINELIB.

	* [controls/widgets.c] [windows/mdi.c]
	Converted MDIClientWndProc to 32-bit.

	* [debugger/break.c] [if1632/signal.c] [include/selectors.h]
	  [scheduler/thread.c]
	Code and data selector values are now computed at run-time.

	* [library/libres.c]
	Moved to loader/ directory.

	* [misc/main.c] [misc/version.c] (New file)
	Moved all version stuff to version.c. Cleaned up a bit.

	* [msdos/dpmi.c]
	Update the REALMODECALL structure on return from real-mode
	interrupt.

	* [windows/event.c] [windows/keyboard.c]
	Changed the way event coordinates are determined. Don't rely on
	the ConfigureNotify event values. This should fix all problems
	with cursor position in -desktop and -managed modes.

Sat Nov 15 16:09:36 1997  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [controls/button.c]
	(BUTTON_CheckAutoRadioButton): Prevent possible endless loop.

Wed Nov 12 03:42:45 1997  Chris Faherty <chrisf@america.com>

	* [misc/ver.c]
	Changed VerInstall32A to assume srcdir as destination if destdir
	is blank.  This was causing alot of DLL installation into SYSTEM
	directory to fail.

	* [loader/ne_image.c]
	NE_LoadSegment buffer[100] was too small and getting overruns.
	Changed it to buffer[200].

Sat Nov  8 06:09:57 1997  Len White <phreak@cgocable.net>

	* [misc/ddeml.c] [include/ddeml.h] [if1632/ddeml.spec]
	Added stub functions DdeConnectList(), DdeQueryNextServer(),
	DdeDisconnectList(), DdeSetUserHandle(), DdeAbandonTransaction(),
	DdePostAdvise(), DdeCreateDataHandle(), DdeAddData(), DdeGetData(),
	DdeAccessData(), DdeUnaccessData(), DdeEnableCallback(),
	DdeCmpStringHandles().

Fri Nov  7 19:44:26 1997  Olaf Flebbe  <o.flebbe@science-computing.de>

	* [files/directory.c]
	Fix typo in directory.c [broke loading of cdplayer on nt40]

	* [misc/main.c]
	Implemented -winver nt40.

	* [loader/resource.c] [user32.spec]
	Stubs for CopyAcceleratorTable, Destroy AcceleratorTable.

Thu Nov  6 22:37:04 1997  Morten Welinder  <welinder@rentec.com>

	* [files/drive.c]
	(GetDiskFreeSpace32A): Cap at 2GB.

	* [include/windows.h]
	Prototype DrawIconEx and CreateDIBSection32.
	Define OBM_RADIOCHECK.
	Add DI_* macros.

	* [objects/dib.c] [if1632/gdi.spec]
	CreateDIBSection is a WINAPI.  Renamed to CreateDIBSection32.
	Implement CreateDIBSection16.

	* [if1632/user.spec] [if1632/user32.spec]
	Add DrawIconEx.

	* [objects/cursoricon.c]
	(CopyIcon32): Fix bogus implementation.

	* [objects/bitmap.c]
	(CopyBitmap32): New function.
	(CopyImage32): Do bitmaps.

	* [graphics/x11drv/text.c]
	(X11DRV_ExtTextOut): Change ascent and descent default to avoid
	zero-thinkness overstrike line.

	* [include/debugstr.h] [misc/debugstr.c]
	New files.

	* [msdos/dpmi.c]
	Don't prototype do_mscdex. In INT_Int31Handler, handle real-mode
	int 0x21, ah=0x52.

	* [msdos/int2f.c]
	Add dummys for 0x1681 and 0x1682.

	* [misc/registry.c]
	Fix memory leaks in RegDeleteKey32W.

	* [objects/text.c]
	In TEXT_NextLine, fix another off-by-one bug.

	* [include/bitmaps/obm_radiocheck]
	New file.  (It a small circle used to radio-button menu items
	when selected.)
	
	* [objects/oembitmap.c]
	Add obm_radiocheck.

	* [include/windows.h] [if1632/user32.spec] [controls/menu.c]
	  [if1632/user.spec]
	Define CheckMenuRadioItem{16,32}.  Define GetMenuItemRect{16,32}.

Wed Nov  5 11:30:14 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
	* [misc/main.c]
	Auto adjust versions depending on binary.

Tue Nov  4 15:21:00 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [controls/listbox.c]
	Paint full background in listbox items with tab stops enabled.

	* [if1632/thunk.c]
	Copy some more message parameter structures (DRAWITEMSTRUCT16,
	COMPAREITEMSTRUCT16) to the stack segment to fix broken programs
	that need this.

	* [windows/dce.c]
	Only clip sibling windows when the parent has the WS_CLIPSIBLINGS
	style set.

	* [windows/focus.c]
	Make order of events in FOCUS_SwitchFocus() reflect API docs.

	* [windows/defdlg.c]
	Fix problem with loss of focus in some dialogs.

	* [win32/code_page.c]
	Fix return value for MultiByteToWideChar().

	* [BUGS]
	BCW now works.
diff --git a/windows/Makefile.in b/windows/Makefile.in
index 70cbec2..c18a470 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -1,4 +1,4 @@
-DEFS      = -D__WINE__
+DEFS      = @DLLFLAGS@ -D__WINE__
 TOPSRCDIR = @top_srcdir@
 TOPOBJDIR = ..
 SRCDIR    = @srcdir@
diff --git a/windows/clipboard.c b/windows/clipboard.c
index d51dbd4..7a262bd 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -1,5 +1,5 @@
 /*
- * 'Wine' Clipboard function handling
+ * WINE clipboard function handling
  *
  * Copyright 1994 Martin Ayotte
  *	     1996 Alex Korobka
@@ -41,11 +41,13 @@
  *			internal variables
  */
 
+static HQUEUE16 hqClipLock   = 0;
+static BOOL32 bCBHasChanged  = FALSE;
+
 static HWND32 hWndClipOwner  = 0;   /* current clipboard owner */
 static HWND32 hWndClipWindow = 0;   /* window that opened clipboard */
 static HWND32 hWndViewer     = 0;   /* start of viewers chain */
 
-static BOOL32 bClipChanged  = FALSE;
 static WORD LastRegFormat = CF_REGFORMATBASE;
 
 static Bool   selectionWait = False;
@@ -72,70 +74,104 @@
     { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE16)NULL, 0, &ClipFormats[14], NULL }
     };
 
-/**************************************************************************
- *                      CLIPBOARD_CheckSelection
- */
-static void CLIPBOARD_CheckSelection(WND* pWnd)
+static LPCLIPFORMAT __lookup_format( LPCLIPFORMAT lpFormat, WORD wID )
 {
-  dprintf_clipboard(stddeb,"\tchecking %08x\n", (unsigned)pWnd->window);
-
-  if( selectionAcquired && selectionWindow != None &&
-      pWnd->window == selectionWindow )
-  {
-    selectionPrevWindow = selectionWindow;
-    selectionWindow = None;
-
-    if( pWnd->next ) 
-         selectionWindow = pWnd->next->window;
-    else if( pWnd->parent )
-             if( pWnd->parent->child != pWnd ) 
-                 selectionWindow = pWnd->parent->child->window;
-
-    dprintf_clipboard(stddeb,"\tswitching selection from %08x to %08x\n", 
-                    (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
-
-    if( selectionWindow != None )
+    while(TRUE)
     {
-        XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
-        if( XGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
-            selectionWindow = None;
+	if (lpFormat == NULL ||
+	    lpFormat->wFormatID == wID) break;
+	lpFormat = lpFormat->NextFormat;
     }
-  }
+    return lpFormat;
 }
 
 /**************************************************************************
- *			CLIPBOARD_DisOwn
+ *                      CLIPBOARD_CheckSelection
+ *
+ * Prevent X selection from being lost when a top level window is
+ * destroyed.
+ */
+static void CLIPBOARD_CheckSelection(WND* pWnd)
+{
+    dprintf_clipboard(stddeb,"\tchecking %08x\n", (unsigned)pWnd->window);
+
+    if( selectionAcquired && selectionWindow != None &&
+        pWnd->window == selectionWindow )
+    {
+	selectionPrevWindow = selectionWindow;
+	selectionWindow = None;
+
+	if( pWnd->next ) 
+	    selectionWindow = pWnd->next->window;
+	else if( pWnd->parent )
+             if( pWnd->parent->child != pWnd ) 
+                 selectionWindow = pWnd->parent->child->window;
+
+	dprintf_clipboard(stddeb,"\tswitching selection from %08x to %08x\n", 
+                    (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
+
+	if( selectionWindow != None )
+	{
+	    XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+	    if( XGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
+		selectionWindow = None;
+	}
+    }
+}
+
+/**************************************************************************
+ *                      CLIPBOARD_ResetLock
+ */
+void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
+{
+    if( hqClipLock == hqCurrent )
+    {
+	if( hqNew )
+	    hqClipLock = hqNew;
+	else
+	{
+ 	    hWndClipOwner = 0;
+	    hWndClipWindow = 0;
+	    EmptyClipboard32();
+	    hqClipLock = 0;
+	}
+    }
+}
+
+/**************************************************************************
+ *			CLIPBOARD_ResetOwner
  *
  * Called from DestroyWindow().
  */
-void CLIPBOARD_DisOwn(WND* pWnd)
+void CLIPBOARD_ResetOwner(WND* pWnd)
 {
-  LPCLIPFORMAT lpFormat = ClipFormats;
+    LPCLIPFORMAT lpFormat = ClipFormats;
 
-  dprintf_clipboard(stddeb,"DisOwn: clipboard owner = %04x, selection = %08x\n", 
+    dprintf_clipboard(stddeb,"DisOwn: clipboard owner = %04x, selection = %08x\n", 
 				hWndClipOwner, (unsigned)selectionWindow);
 
-  if( pWnd->hwndSelf == hWndClipOwner)
-  {
-      SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
+    if( pWnd->hwndSelf == hWndClipOwner)
+    {
+	SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
 
-      /* check if all formats were rendered */
+	/* check if all formats were rendered */
 
-      while(lpFormat)
-      { 
-         if( lpFormat->wDataPresent && !lpFormat->hData )
-	 {
-	   dprintf_clipboard(stddeb,"\tdata missing for clipboard format %i\n", lpFormat->wFormatID); 
-	   lpFormat->wDataPresent = 0;
-	 }
-         lpFormat = lpFormat->NextFormat;
-      }
-      hWndClipOwner = 0;
-  }
+	while(lpFormat)
+	{
+	    if( lpFormat->wDataPresent && !lpFormat->hData )
+	    {
+		dprintf_clipboard( stddeb,"\tdata missing for clipboard format %i\n", 
+				   lpFormat->wFormatID); 
+		lpFormat->wDataPresent = 0;
+	    }
+	    lpFormat = lpFormat->NextFormat;
+	}
+	hWndClipOwner = 0;
+    }
 
-  /* now try to salvage current selection from being destroyed by X */
+    /* now try to salvage current selection from being destroyed by X */
 
-  if( pWnd->window ) CLIPBOARD_CheckSelection(pWnd);
+    if( pWnd->window ) CLIPBOARD_CheckSelection(pWnd);
 }
 
 /**************************************************************************
@@ -143,16 +179,16 @@
  */
 static void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat, BOOL32 bChange)
 {
-  if( lpFormat->wFormatID >= CF_GDIOBJFIRST &&
-      lpFormat->wFormatID <= CF_GDIOBJLAST )
-      DeleteObject32(lpFormat->hData);
-  else if( lpFormat->hData )
-           GlobalFree16(lpFormat->hData);
+    if( lpFormat->wFormatID >= CF_GDIOBJFIRST &&
+	lpFormat->wFormatID <= CF_GDIOBJLAST )
+	DeleteObject32(lpFormat->hData);
+    else if( lpFormat->hData )
+	GlobalFree16(lpFormat->hData);
 
-  lpFormat->wDataPresent = 0; 
-  lpFormat->hData = 0;
+    lpFormat->wDataPresent = 0; 
+    lpFormat->hData = 0;
 
-  if( bChange ) bClipChanged = TRUE;
+    if( bChange ) bCBHasChanged = TRUE;
 }
 
 /**************************************************************************
@@ -160,31 +196,34 @@
  */
 static BOOL32 CLIPBOARD_RequestXSelection()
 {
-  HWND32 hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow32();
+    HWND32 hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow32();
 
-  if( !hWnd ) return FALSE;
+    if( !hWnd ) return FALSE;
 
-  dprintf_clipboard(stddeb,"Requesting selection...\n");
+    dprintf_clipboard(stddeb,"Requesting selection...\n");
 
   /* request data type XA_STRING, later
    * CLIPBOARD_ReadSelection() will be invoked 
    * from the SelectionNotify event handler */
 
-  XConvertSelection(display,XA_PRIMARY,XA_STRING,
-                    XInternAtom(display,"PRIMARY_TEXT",False),
-                    WIN_GetXWindow(hWnd),CurrentTime);
+    XConvertSelection(display,XA_PRIMARY,XA_STRING,
+                      XInternAtom(display,"PRIMARY_TEXT",False),
+                      WIN_GetXWindow(hWnd),CurrentTime);
 
-  /* wait until SelectionNotify is processed */
+  /* wait until SelectionNotify is processed 
+   *
+   * FIXME: Use XCheckTypedWindowEvent() instead ( same in the 
+   *	    CLIPBOARD_CheckSelection() ). 
+   */
 
-  selectionWait=True;
-  while(selectionWait) 
-        EVENT_WaitNetEvent( TRUE, FALSE );
+    selectionWait=True;
+    while(selectionWait) EVENT_WaitNetEvent( TRUE, FALSE );
 
   /* we treat Unix text as CF_OEMTEXT */
-  dprintf_clipboard(stddeb,"\tgot CF_OEMTEXT = %i\n", 
-		    ClipFormats[CF_OEMTEXT-1].wDataPresent);
+    dprintf_clipboard(stddeb,"\tgot CF_OEMTEXT = %i\n", 
+		      ClipFormats[CF_OEMTEXT-1].wDataPresent);
 
-  return (BOOL32)ClipFormats[CF_OEMTEXT-1].wDataPresent;
+    return (BOOL32)ClipFormats[CF_OEMTEXT-1].wDataPresent;
 }
 
 /**************************************************************************
@@ -192,21 +231,17 @@
  */
 BOOL32 CLIPBOARD_IsPresent(WORD wFormat)
 {
-    LPCLIPFORMAT lpFormat = ClipFormats; 
-
     /* special case */
 
     if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
-        return lpFormat[CF_TEXT-1].wDataPresent ||
-               lpFormat[CF_OEMTEXT-1].wDataPresent;
-
-    while(TRUE) {
-        if (lpFormat == NULL) return FALSE;
-        if (lpFormat->wFormatID == wFormat) break;
-        lpFormat = lpFormat->NextFormat;
-        }
-
-    return (lpFormat->wDataPresent);
+        return ClipFormats[CF_TEXT-1].wDataPresent ||
+               ClipFormats[CF_OEMTEXT-1].wDataPresent;
+    else
+    {
+	LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
+	if( lpFormat ) return (lpFormat->wDataPresent);
+    }
+    return FALSE;
 }
 
 /**************************************************************************
@@ -220,18 +255,23 @@
 
 /**************************************************************************
  *            OpenClipboard32   (USER32.406)
+ *
+ * Note: Netscape uses NULL hWnd to open the clipboard.
  */
 BOOL32 WINAPI OpenClipboard32( HWND32 hWnd )
 {
-    BOOL32 bRet = FALSE;
+    BOOL32 bRet;
+
     dprintf_clipboard(stddeb,"OpenClipboard(%04x) = ", hWnd);
 
-    if (!hWndClipWindow)
-       {
+    if (!hqClipLock)
+    {
+	 hqClipLock = GetTaskQueue(0);
     	 hWndClipWindow = hWnd;
+	 bCBHasChanged = FALSE;
 	 bRet = TRUE;
-       }
-    bClipChanged = FALSE;
+    }
+    else bRet = FALSE;
 
     dprintf_clipboard(stddeb,"%i\n", bRet);
     return bRet;
@@ -254,11 +294,14 @@
 {
     dprintf_clipboard(stddeb,"CloseClipboard(); !\n");
 
-    if (hWndClipWindow == 0) return FALSE;
-    hWndClipWindow = 0;
+    if (hqClipLock == GetTaskQueue(0))
+    {
+	hWndClipWindow = 0;
 
-    if (bClipChanged && hWndViewer) SendMessage16(hWndViewer,WM_DRAWCLIPBOARD,0,0L);
-
+        if (bCBHasChanged && hWndViewer) 
+	    SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
+	hqClipLock = 0;
+    }
     return TRUE;
 }
 
@@ -281,20 +324,20 @@
 
     dprintf_clipboard(stddeb,"EmptyClipboard()\n");
 
-    if (hWndClipWindow == 0) return FALSE;
+    if (hqClipLock != GetTaskQueue(0)) return FALSE;
 
     /* destroy private objects */
 
     if (hWndClipOwner)
-	SendMessage16(hWndClipOwner,WM_DESTROYCLIPBOARD,0,0L);
+	SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
   
     while(lpFormat) 
-      {
+    {
 	if ( lpFormat->wDataPresent || lpFormat->hData )
 	     CLIPBOARD_DeleteRecord( lpFormat, TRUE );
 
 	lpFormat = lpFormat->NextFormat;
-      }
+    }
 
     hWndClipOwner = hWndClipWindow;
 
@@ -307,7 +350,7 @@
 	dprintf_clipboard(stddeb, "\tgiving up selection (spw = %08x)\n", 
 				 	(unsigned)selectionPrevWindow);
 
-	XSetSelectionOwner(display,XA_PRIMARY,None,CurrentTime);
+	XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
     }
     return TRUE;
 }
@@ -336,34 +379,37 @@
  */
 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
 {
-    LPCLIPFORMAT lpFormat = ClipFormats; 
+    LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
     Window       owner;
 
     dprintf_clipboard(stddeb,
 		"SetClipboardData(%04X, %04x) !\n", wFormat, hData);
 
-    while(TRUE) 
-      {
-	if (lpFormat == NULL) return 0;
-	if (lpFormat->wFormatID == wFormat) break;
-	lpFormat = lpFormat->NextFormat;
-      }
+    /* NOTE: If the hData is zero and current owner doesn't match
+     * the window that opened the clipboard then this application
+     * is screwed because WM_RENDERFORMAT will go to the owner
+     * (to become the owner it must call EmptyClipboard() before
+     *  adding new data).
+     */
+
+    if( (hqClipLock != GetTaskQueue(0)) || !lpFormat ||
+	(!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0; 
 
     /* Acquire X selection if text format */
 
     if( !selectionAcquired && 
 	(wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
     {
-      owner = WIN_GetXWindow(hWndClipWindow);
-      XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
-      if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
-      {
-        selectionAcquired = True;
-	selectionWindow = owner;
+	owner = WIN_GetXWindow( hWndClipWindow ? hWndClipWindow : AnyPopup32() );
+	XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
+	if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
+	{
+	    selectionAcquired = True;
+	    selectionWindow = owner;
 
-        dprintf_clipboard(stddeb,"Grabbed X selection, owner=(%08x)\n", 
+	    dprintf_clipboard(stddeb,"Grabbed X selection, owner=(%08x)\n", 
 						(unsigned) owner);
-      }
+	}
     }
 
     if ( lpFormat->wDataPresent || lpFormat->hData ) 
@@ -380,7 +426,7 @@
 	    CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
     }
 
-    bClipChanged = TRUE;
+    bCBHasChanged = TRUE;
     lpFormat->wDataPresent = 1;
     lpFormat->hData = hData;          /* 0 is legal, see WM_RENDERFORMAT */
 
@@ -403,7 +449,7 @@
  */
 static BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
 {
- if( lpFormat->wDataPresent && !lpFormat->hData )
+   if( lpFormat->wDataPresent && !lpFormat->hData )
    if( IsWindow32(hWndClipOwner) )
        SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
                      (WPARAM16)lpFormat->wFormatID,0L);
@@ -414,37 +460,39 @@
        hWndClipOwner = 0; lpFormat->wDataPresent = 0;
        return FALSE;
    }
- return (lpFormat->hData) ? TRUE : FALSE;
+   return (lpFormat->hData) ? TRUE : FALSE;
 }
 
 /**************************************************************************
  *                      CLIPBOARD_RenderText
+ *
+ * Convert text between UNIX and DOS formats.
  */
 static BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
 {
-  UINT16 size = GlobalSize16( lpSource->hData );
-  LPCSTR	lpstrS = (LPSTR)GlobalLock16(lpSource->hData);
-  LPSTR		lpstrT;
+    UINT16 size = GlobalSize16( lpSource->hData );
+    LPCSTR lpstrS = (LPSTR)GlobalLock16(lpSource->hData);
+    LPSTR  lpstrT;
 
-  if( !lpstrS ) return FALSE;
-  dprintf_clipboard(stddeb,"\tconverting from '%s' to '%s', %i chars\n",
+    if( !lpstrS ) return FALSE;
+    dprintf_clipboard(stddeb,"\tconverting from '%s' to '%s', %i chars\n",
 			   	      lpSource->Name, lpTarget->Name, size);
 
-  lpTarget->hData = GlobalAlloc16(GMEM_ZEROINIT, size); 
-  lpstrT = (LPSTR)GlobalLock16(lpTarget->hData);
+    lpTarget->hData = GlobalAlloc16(GMEM_ZEROINIT, size); 
+    lpstrT = (LPSTR)GlobalLock16(lpTarget->hData);
 
-  if( lpstrT )
-  {
-    if( lpSource->wFormatID == CF_TEXT )
-	CharToOemBuff32A(lpstrS, lpstrT, size);
-    else
-	OemToCharBuff32A(lpstrS, lpstrT, size);
-    dprintf_clipboard(stddeb,"\tgot %s\n", lpstrT);
-    return TRUE;
-  }
+    if( lpstrT )
+    {
+	if( lpSource->wFormatID == CF_TEXT )
+	    CharToOemBuff32A(lpstrS, lpstrT, size);
+	else
+	    OemToCharBuff32A(lpstrS, lpstrT, size);
+	dprintf_clipboard(stddeb,"\tgot %s\n", lpstrT);
+	return TRUE;
+    }
 
-  lpTarget->hData = 0;
-  return FALSE;
+    lpTarget->hData = 0;
+    return FALSE;
 }
 
 /**************************************************************************
@@ -455,7 +503,7 @@
     LPCLIPFORMAT lpRender = ClipFormats; 
     LPCLIPFORMAT lpUpdate = NULL;
 
-    if (!hWndClipWindow) return 0;
+    if (hqClipLock != GetTaskQueue(0)) return 0;
 
     dprintf_clipboard(stddeb,"GetClipboardData(%04X)\n", wFormat);
 
@@ -477,18 +525,13 @@
     }
     else
     {
-      while(TRUE) 
-      {
-	if (lpRender == NULL) return 0;
-	if (lpRender->wFormatID == wFormat) break;
-	lpRender = lpRender->NextFormat;
-      }
-      lpUpdate = lpRender;
+	lpRender = __lookup_format( ClipFormats, wFormat );
+	lpUpdate = lpRender;
     }
    
-    if( !CLIPBOARD_RenderFormat(lpRender) ) return 0; 
-    if( lpUpdate != lpRender &&
-	!lpUpdate->hData ) CLIPBOARD_RenderText(lpUpdate, lpRender);
+    if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0; 
+    if( lpUpdate != lpRender && !lpUpdate->hData ) 
+	CLIPBOARD_RenderText(lpUpdate, lpRender);
 
     dprintf_clipboard(stddeb,"\treturning %04x (type %i)\n", 
 			      lpUpdate->hData, lpUpdate->wFormatID);
@@ -529,16 +572,16 @@
     FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
 		       lpFormat[CF_OEMTEXT-1].wDataPresent); 
 
-    while(TRUE) {
+    while(TRUE) 
+    {
 	if (lpFormat == NULL) break;
 	if (lpFormat->wDataPresent) 
-	    {
-               dprintf_clipboard(stddeb, "\tdata found for format %i\n", lpFormat->wFormatID);
-
-	       FormatCount++;
-	    }
-	lpFormat = lpFormat->NextFormat;
+	{
+            dprintf_clipboard(stddeb, "\tdata found for format %i\n", lpFormat->wFormatID);
+	    FormatCount++;
 	}
+	lpFormat = lpFormat->NextFormat;
+    }
 
     dprintf_clipboard(stddeb,"\ttotal %d\n", FormatCount);
     return FormatCount;
@@ -563,7 +606,7 @@
 
     dprintf_clipboard(stddeb,"EnumClipboardFormats(%04X)\n", wFormat);
 
-    if( !hWndClipWindow ) return 0;
+    if( hqClipLock != GetTaskQueue(0) ) return 0;
 
     if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) 
 	 && !selectionAcquired) CLIPBOARD_RequestXSelection();
@@ -576,22 +619,19 @@
 
     /* walk up to the specified format record */
 
-    while(TRUE) {
-	if (lpFormat == NULL) return 0;
-	if (lpFormat->wFormatID == wFormat) break;
-	lpFormat = lpFormat->NextFormat;
-	}
+    if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
 
     /* find next format with available data */
 
     lpFormat = lpFormat->NextFormat;
-    while(TRUE) {
+    while(TRUE) 
+    {
 	if (lpFormat == NULL) return 0;
-	if (lpFormat->wDataPresent ||
-	       (lpFormat->wFormatID == CF_OEMTEXT &&
-		ClipFormats[CF_TEXT-1].wDataPresent)) break;
+	if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT && 
+				       ClipFormats[CF_TEXT-1].wDataPresent)) 
+	    break;
 	lpFormat = lpFormat->NextFormat;
-	}
+    }
 
     return lpFormat->wFormatID;
 }
@@ -611,17 +651,18 @@
 
     /* walk format chain to see if it's already registered */
 
-    while(TRUE) {
+    while(TRUE) 
+    {
 	if ( !strcmp(lpFormat->Name,FormatName) )
-	   {
+	{
 	     lpFormat->wRefCount++;
 	     return lpFormat->wFormatID;
-	   }
+	}
  
 	if ( lpFormat->NextFormat == NULL ) break;
 
 	lpFormat = lpFormat->NextFormat;
-	}
+    }
 
     /* allocate storage for new format entry */
 
@@ -677,18 +718,12 @@
  */
 INT32 WINAPI GetClipboardFormatName32A( UINT32 wFormat, LPSTR retStr, INT32 maxlen )
 {
-    LPCLIPFORMAT lpFormat = ClipFormats; 
+    LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
 
     dprintf_clipboard(stddeb,
 	"GetClipboardFormatName(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
 
-    while(TRUE) {
-	if (lpFormat == NULL) return 0;
-	if (lpFormat->wFormatID == wFormat) break;
-	lpFormat = lpFormat->NextFormat;
-	}
-
-    if (lpFormat->Name == NULL || 
+    if (lpFormat == NULL || lpFormat->Name == NULL || 
 	lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
 
     dprintf_clipboard(stddeb,
@@ -758,7 +793,7 @@
  */
 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
 {
-    return ChangeClipboardChain32(hWnd,hWndNext);
+    return ChangeClipboardChain32(hWnd, hWndNext);
 }
 
 /**************************************************************************
@@ -771,10 +806,10 @@
     dprintf_clipboard(stdnimp, "ChangeClipboardChain(%04x, %04x)\n", hWnd, hWndNext);
 
     if( hWndViewer )
-      bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
+	bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
                              (WPARAM16)hWnd, (LPARAM)hWndNext);   
     else
-      dprintf_clipboard(stddeb,"ChangeClipboardChain: hWndViewer is lost\n");
+	dprintf_clipboard(stddeb,"ChangeClipboardChain: hWndViewer is lost\n");
 
     if( hWnd == hWndViewer ) hWndViewer = hWndNext;
 
@@ -929,32 +964,31 @@
  */
 void CLIPBOARD_ReleaseSelection(Window w, HWND32 hwnd)
 {
-  /* w is the window that lost selection,
-   * 
-   * selectionPrevWindow is nonzero if CheckSelection() was called. 
-   */
+    /* w is the window that lost selection,
+     * 
+     * selectionPrevWindow is nonzero if CheckSelection() was called. 
+     */
 
-  dprintf_clipboard(stddeb,"\tevent->window = %08x (sw = %08x, spw=%08x)\n", 
+    dprintf_clipboard(stddeb,"\tevent->window = %08x (sw = %08x, spw=%08x)\n", 
 	  (unsigned)w, (unsigned)selectionWindow, (unsigned)selectionPrevWindow );
 
-  if( selectionAcquired )
-    if( w == selectionWindow || selectionPrevWindow == None)
-    {
-      /* alright, we really lost it */
+    if( selectionAcquired )
+	if( w == selectionWindow || selectionPrevWindow == None)
+	{
+	    /* alright, we really lost it */
 
-      selectionAcquired = False;
-      selectionWindow = None; 
+	    selectionAcquired = False;
+	    selectionWindow = None; 
 
-      /* but we'll keep existing data for internal use */
-    }
-    else if( w == selectionPrevWindow )
-    {
-      w =  XGetSelectionOwner(display, XA_PRIMARY);
+	    /* but we'll keep existing data for internal use */
+	}
+	else if( w == selectionPrevWindow )
+	{
+	    w = XGetSelectionOwner(display, XA_PRIMARY);
+	    if( w == None )
+		XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+	}
 
-      if( w == None )
-        XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
-    }
-
-  selectionPrevWindow = None;
+    selectionPrevWindow = None;
 }
 
diff --git a/windows/dce.c b/windows/dce.c
index 8576190..df98a11 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -40,7 +40,7 @@
 /***********************************************************************
  *           DCE_DumpCache
  */
-static void DCE_DumpCache()
+static void DCE_DumpCache(void)
 {
     DCE* dce = firstDCE;
     
@@ -206,7 +206,7 @@
  * rectangle. wndScope is the immediate parent of the window(s) that 
  * was(were) moved and(or) resized.
  */
-BOOL32 DCE_InvalidateDCE(WND* wndScope, RECT32* pRectUpdate)
+BOOL32 DCE_InvalidateDCE(WND* wndScope, const RECT32* pRectUpdate)
 {
     BOOL32 bRet = FALSE;
 
@@ -219,8 +219,6 @@
 				        pRectUpdate->right,pRectUpdate->bottom);
 	if( debugging_dc ) DCE_DumpCache();
 
-	if( !Options.desktopGeometry && wndScope == WIN_GetDesktop() ) return TRUE;
-
  	/* walk all DCEs and fixup non-empty entries */
 
 	for (dce = firstDCE; (dce); dce = dce->next)
@@ -234,8 +232,7 @@
 		    WND* wnd = wndCurrent;
 		    INT32 xoffset = 0, yoffset = 0;
 
-		    if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) )
-			continue;
+		    if( (wndCurrent == wndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN) ) continue;
 
 		    /* check if DCE window is within the z-order scope */
 
@@ -288,7 +285,7 @@
 /***********************************************************************
  *           DCE_Init
  */
-void DCE_Init()
+void DCE_Init(void)
 {
     int i;
     DCE * dce;
@@ -448,13 +445,20 @@
 		    DCE_AddClipRects( wndPtr->parent->child,
 				      wndPtr, hrgnClip, &rect, xoffset, yoffset );
 
+		/* Clip siblings of all ancestors that have the
+                 * WS_CLIPSIBLINGS style
+		 */
+
 		while (wndPtr->dwStyle & WS_CHILD)
 		{
 		    wndPtr = wndPtr->parent;
 		    xoffset -= wndPtr->rectClient.left;
 		    yoffset -= wndPtr->rectClient.top;
-		    DCE_AddClipRects( wndPtr->parent->child, wndPtr,
-					hrgnClip, &rect, xoffset, yoffset );
+		    if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
+		    {
+			DCE_AddClipRects( wndPtr->parent->child, wndPtr,
+					  hrgnClip, &rect, xoffset, yoffset );
+		    }
 		}
 
 		/* Now once we've got a jumbo clip region we have
@@ -665,13 +669,9 @@
 		   ((dce->DCXflags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
 				      DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)) == dcxFlags))
 		{
-		    dprintf_dc(stddeb,"\tfound valid %08x dce [%04x]\n", (unsigned)dce, hwnd );
-
-/* Eventually, this won't be commented out but at this time
- * there are still some problems with DC reuse.
- * 
-		    bUpdateVisRgn = TRUE; 
- */
+		    dprintf_dc(stddeb,"\tfound valid %08x dce [%04x], flags %08x\n", 
+					(unsigned)dce, hwnd, (unsigned)dcxFlags );
+		    bUpdateVisRgn = FALSE; 
 		    bUpdateClipOrigin = TRUE;
 		    break;
 		}
@@ -718,7 +718,7 @@
     DCE_SetDrawable( wndPtr, dc, flags, bUpdateClipOrigin );
     if( bUpdateVisRgn )
     {
-	dprintf_dc(stddeb,"updating %08x dce, visrgn [%04x]\n", (unsigned)dce, hwnd);
+	dprintf_dc(stddeb,"updating visrgn for %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd);
 
 	if (flags & DCX_PARENTCLIP)
         {
@@ -772,6 +772,8 @@
 	dc->w.flags &= ~DC_DIRTY;
 	SelectVisRgn( hdc, hrgnVisible );
     }
+    else
+	dprintf_dc(stddeb,"no visrgn update %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd);
 
     /* apply additional region operation (if any) */
 
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 1285d73..36c146a 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -54,7 +54,8 @@
     if (!infoPtr->hwndFocus || IsIconic32(hwnd)) return FALSE;
     if (!IsWindow32( infoPtr->hwndFocus )) return FALSE;
     DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
-    infoPtr->hwndFocus = 0;
+    /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
+       sometimes losing focus when receiving WM_SETFOCUS messages. */
     return TRUE;
 }
 
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 8a2a7b3..80a8d92 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -71,6 +71,25 @@
     }
 }
 
+/***********************************************************************
+ *           DEFWND_ControlColor
+ *
+ * Default colors for control painting.
+ */
+HBRUSH32 DEFWND_ControlColor( HDC32 hDC, UINT16 ctlType )
+{
+    if( ctlType == CTLCOLOR_SCROLLBAR)
+    {
+	SetBkColor32( hDC, RGB(255, 255, 255) );
+	SetTextColor32( hDC, RGB(0, 0, 0) );
+	UnrealizeObject32( sysColorObjects.hbrushScrollbar );
+        return sysColorObjects.hbrushScrollbar;
+    }
+
+    SetBkColor32( hDC, GetSysColor32(COLOR_WINDOW) );
+    SetTextColor32( hDC, GetSysColor32(COLOR_WINDOWTEXT));
+    return sysColorObjects.hbrushWindow;
+}
 
 /***********************************************************************
  *           DEFWND_DefWinProc
@@ -89,7 +108,7 @@
         return NC_HandleNCHitTest( wndPtr->hwndSelf, MAKEPOINT16(lParam) );
 
     case WM_NCLBUTTONDOWN:
-	return NC_HandleNCLButtonDown( wndPtr->hwndSelf, wParam, lParam );
+	return NC_HandleNCLButtonDown( wndPtr, wParam, lParam );
 
     case WM_LBUTTONDBLCLK:
     case WM_NCLBUTTONDBLCLK:
@@ -206,32 +225,11 @@
     case WM_CTLCOLORBTN:
     case WM_CTLCOLORDLG:
     case WM_CTLCOLORSTATIC:
-        SetBkColor32( (HDC32)wParam, GetSysColor32(COLOR_WINDOW) );
-        SetTextColor32( (HDC32)wParam, GetSysColor32(COLOR_WINDOWTEXT) );
-        return (LRESULT)sysColorObjects.hbrushWindow;
-
     case WM_CTLCOLORSCROLLBAR:
-        SetBkColor32( (HDC32)wParam, RGB(255, 255, 255) );
-        SetTextColor32( (HDC32)wParam, RGB(0, 0, 0) );
-        UnrealizeObject32( sysColorObjects.hbrushScrollbar );
-        return (LRESULT)sysColorObjects.hbrushScrollbar;
+	return (LRESULT)DEFWND_ControlColor( (HDC32)wParam, msg - WM_CTLCOLORMSGBOX );
 
     case WM_CTLCOLOR:
-	{
-	    if (HIWORD(lParam) == CTLCOLOR_SCROLLBAR)
-	    {
-		SetBkColor32( (HDC32)wParam, RGB(255, 255, 255) );
-		SetTextColor32( (HDC32)wParam, RGB(0, 0, 0) );
-		UnrealizeObject32( sysColorObjects.hbrushScrollbar );
-		return (LRESULT)sysColorObjects.hbrushScrollbar;
-	    }
-	    else
-	    {
-		SetBkColor32( (HDC32)wParam, GetSysColor32(COLOR_WINDOW) );
-		SetTextColor32((HDC32)wParam, GetSysColor32(COLOR_WINDOWTEXT));
-		return (LRESULT)sysColorObjects.hbrushWindow;
-	    }
-	}
+	return (LRESULT)DEFWND_ControlColor( (HDC32)wParam, HIWORD(lParam) );
 	
     case WM_GETTEXTLENGTH:
         if (wndPtr->text) return (LRESULT)strlen(wndPtr->text);
diff --git a/windows/event.c b/windows/event.c
index b54769a..69c40ec 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -5,6 +5,7 @@
  * 
  */
 
+#include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -27,6 +28,7 @@
 #include "win.h"
 #include "class.h"
 #include "clipboard.h"
+#include "dce.h"
 #include "message.h"
 #include "module.h"
 #include "options.h"
@@ -86,7 +88,7 @@
 };
 
   /* Event handlers */
-static void EVENT_Key( XKeyEvent *event );
+static void EVENT_Key( WND *pWnd, XKeyEvent *event );
 static void EVENT_ButtonPress( WND *pWnd, XButtonEvent *event );
 static void EVENT_ButtonRelease( WND *pWnd, XButtonEvent *event );
 static void EVENT_MotionNotify( WND *pWnd, XMotionEvent *event );
@@ -94,7 +96,7 @@
 static void EVENT_FocusOut( WND *pWnd, XFocusChangeEvent *event );
 static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
-static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *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);
@@ -160,8 +162,7 @@
     {
     case KeyPress:
     case KeyRelease:
-        if (InputEnabled)
-            EVENT_Key( (XKeyEvent*)event );
+        if (InputEnabled) EVENT_Key( pWnd, (XKeyEvent*)event );
 	break;
 	
     case ButtonPress:
@@ -208,7 +209,7 @@
         break;
 
     case ConfigureNotify:
-	EVENT_ConfigureNotify( pWnd->hwndSelf, (XConfigureEvent*)event );
+	EVENT_ConfigureNotify( pWnd, (XConfigureEvent*)event );
 	break;
 
     case SelectionRequest:
@@ -414,6 +415,7 @@
 	  }
 
 	  if( pWnd )
+          {
             if( (pQ = (MESSAGEQUEUE*)GlobalLock16(pWnd->hmemTaskQ)) )
             {
               pQ->flags |= QUEUE_FLAG_XEVENT;
@@ -421,9 +423,9 @@
 	      XPutBackEvent(display, &event);
               break;
 	    }
+          }
         }
-        else
-          EVENT_ProcessEvent( &event );
+        else EVENT_ProcessEvent( &event );
     }
     while (XPending( display ));
     return TRUE;
@@ -615,9 +617,9 @@
  *
  * Handle a X key event
  */
-static void EVENT_Key( XKeyEvent *event )
+static void EVENT_Key( WND *pWnd, XKeyEvent *event )
 {
-    KEYBOARD_HandleEvent( event );
+    KEYBOARD_HandleEvent( pWnd, event );
 }
 
 
@@ -627,8 +629,9 @@
 static void EVENT_MotionNotify( WND *pWnd, XMotionEvent *event )
 {
     hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L,
-		    event->x_root - desktopX, event->y_root - desktopY,
-		    event->time - MSG_WineStartTicks, (DWORD)pWnd->hwndSelf );
+                    pWnd->rectWindow.left + event->x,
+                    pWnd->rectWindow.top + event->y,
+                    event->time - MSG_WineStartTicks, pWnd->hwndSelf );
 }
 
 
@@ -640,14 +643,14 @@
 void EVENT_DummyMotionNotify(void)
 {
     Window root, child;
-    int rootX, rootY, childX, childY;
+    int rootX, rootY, winX, winY;
     unsigned int state;
 
     if (XQueryPointer( display, rootWindow, &root, &child,
-                       &rootX, &rootY, &childX, &childY, &state ))
+                       &rootX, &rootY, &winX, &winY, &state ))
     {
-        hardware_event(WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
-                       rootX - desktopX, rootY - desktopY, GetTickCount(), 0 );
+        hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
+                        winX, winY, GetTickCount(), 0 );
     }
 }
 
@@ -667,8 +670,9 @@
     AsyncMouseButtonsStates[buttonNum] = 0x8000;
     hardware_event( messages[buttonNum],
 		    EVENT_XStateToKeyState( event->state ), 0L,
-		    event->x_root - desktopX, event->y_root - desktopY,
-		    event->time - MSG_WineStartTicks, (DWORD)pWnd->hwndSelf );
+                    pWnd->rectWindow.left + event->x,
+                    pWnd->rectWindow.top + event->y,
+		    event->time - MSG_WineStartTicks, pWnd->hwndSelf );
 }
 
 
@@ -683,11 +687,12 @@
 
     if (buttonNum >= NB_BUTTONS) return;    
     if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum;
-    MouseButtonsStates[buttonNum] = FALSE;
+    MouseButtonsStates[buttonNum] = 0;
     hardware_event( messages[buttonNum],
 		    EVENT_XStateToKeyState( event->state ), 0L,
-		    event->x_root - desktopX, event->y_root - desktopY,
-		    event->time - MSG_WineStartTicks, (DWORD)pWnd->hwndSelf );
+                    pWnd->rectWindow.left + event->x,
+                    pWnd->rectWindow.top + event->y,
+		    event->time - MSG_WineStartTicks, pWnd->hwndSelf );
 }
 
 
@@ -744,83 +749,118 @@
     return TRUE;
 }
 
+
+/**********************************************************************
+ *              EVENT_GetGeometry
+ *
+ * Helper function for ConfigureNotify handling.
+ * Get the new geometry of a window relative to the root window.
+ */
+static void EVENT_GetGeometry( Window win, int *px, int *py,
+                               unsigned int *pwidth, unsigned int *pheight )
+{
+    Window root, parent, *children;
+    int xpos, ypos;
+    unsigned int width, height, border, depth, nb_children;
+
+    if (!XGetGeometry( display, win, &root, px, py, pwidth, pheight,
+                       &border, &depth )) return;
+    if (win == rootWindow)
+    {
+        *px = *py = 0;
+        return;
+    }
+
+    for (;;)
+    {
+        if (!XQueryTree(display, win, &root, &parent, &children, &nb_children))
+            return;
+        XFree( children );
+        if (parent == rootWindow) break;
+        win = parent;
+        if (!XGetGeometry( display, win, &root, &xpos, &ypos,
+                           &width, &height, &border, &depth )) return;
+        *px += xpos;
+        *py += ypos;
+    }
+}
+
+
 /**********************************************************************
  *              EVENT_ConfigureNotify
  *
- * The ConfigureNotify event is only selected on the desktop window
- * and on top-level windows when the -managed flag is used.
+ * The ConfigureNotify event is only selected on top-level windows
+ * when the -managed flag is used.
  */
-static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *event )
+static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event )
 {
-    /* FIXME: with -desktop xxx we get this event _before_ desktop 
-     * window structure is created. WIN_GetDesktop() check is a hack.
-     */
+    WINDOWPOS32 winpos;
+    RECT32 newWindowRect, newClientRect;
+    HRGN32 hrgnOldPos, hrgnNewPos;
+    Window above = event->above;
+    int x, y;
+    unsigned int width, height;
 
-    if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow32())
-    {
-        desktopX = event->x;
-	desktopY = event->y;
-    }
+    assert (pWnd->flags & WIN_MANAGED);
+
+    /* We don't rely on the event geometry info, because it is relative
+     * to parent and not to root, and it may be wrong (XFree sets x,y to 0,0
+     * if the window hasn't moved).
+     */
+    EVENT_GetGeometry( event->window, &x, &y, &width, &height );
+
+    /* Fill WINDOWPOS struct */
+    winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER;
+    winpos.hwnd = pWnd->hwndSelf;
+    winpos.x = x;
+    winpos.y = y;
+    winpos.cx = width;
+    winpos.cy = height;
+
+    /* Check for unchanged attributes */
+    if (winpos.x == pWnd->rectWindow.left && winpos.y == pWnd->rectWindow.top)
+        winpos.flags |= SWP_NOMOVE;
+    if ((winpos.cx == pWnd->rectWindow.right - pWnd->rectWindow.left) &&
+        (winpos.cy == pWnd->rectWindow.bottom - pWnd->rectWindow.top))
+        winpos.flags |= SWP_NOSIZE;
     else
     {
-        WND *wndPtr = WIN_FindWndPtr( hwnd );
-	WINDOWPOS32 winpos;
-	RECT32 newWindowRect, newClientRect;
-	HRGN32 hrgnOldPos, hrgnNewPos;
-	Window above = event->above;
-
-	if (!wndPtr || !(wndPtr->flags & WIN_MANAGED)) return;
-
-	/* Fill WINDOWPOS struct */
-	winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER;
-	winpos.hwnd = hwnd;
-        /* FIXME: position should be relative to root window */
-	winpos.x = event->x;
-	winpos.y = event->y;
-	winpos.cx = event->width;
-	winpos.cy = event->height;
-
-	/* Check for unchanged attributes */
-	if(winpos.x == wndPtr->rectWindow.left &&
-	   winpos.y == wndPtr->rectWindow.top)
-	    winpos.flags |= SWP_NOMOVE;
-	if(winpos.cx == wndPtr->rectWindow.right - wndPtr->rectWindow.left &&
-	   winpos.cy == wndPtr->rectWindow.bottom - wndPtr->rectWindow.top)
-	    winpos.flags |= SWP_NOSIZE;
-
-	/* Send WM_WINDOWPOSCHANGING */
-	SendMessage32A( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&winpos );
-
-	/* Calculate new position and size */
-	newWindowRect.left = event->x;
-	newWindowRect.right = event->x + event->width;
-	newWindowRect.top = event->y;
-	newWindowRect.bottom = event->y + event->height;
-
-	WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
-                               &wndPtr->rectWindow, &wndPtr->rectClient,
-                               &winpos, &newClientRect );
-
-        hrgnOldPos = CreateRectRgnIndirect32( &wndPtr->rectWindow );
-        hrgnNewPos = CreateRectRgnIndirect32( &newWindowRect );
-        CombineRgn32( hrgnOldPos, hrgnOldPos, hrgnNewPos, RGN_DIFF );
- 
-	/* Set new size and position */
-	wndPtr->rectWindow = newWindowRect;
-	wndPtr->rectClient = newClientRect;
-	SendMessage32A( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
-
-	if( IsWindow32( hwnd ) )
-	    if( above == None )			/* absolute bottom */
-	    {
-        	WIN_UnlinkWindow( hwnd );
-        	WIN_LinkWindow( hwnd, HWND_BOTTOM);
-	    }
-	    else EVENT_QueryZOrder( wndPtr );	/* try to outsmart window manager */
-
-        DeleteObject32(hrgnOldPos);
-        DeleteObject32(hrgnNewPos);
+        RECT32 rect = { 0, 0, pWnd->rectWindow.right - pWnd->rectWindow.left,
+                        pWnd->rectWindow.bottom - pWnd->rectWindow.top };
+        DCE_InvalidateDCE( pWnd, &rect );
     }
+
+    /* Send WM_WINDOWPOSCHANGING */
+    SendMessage32A( winpos.hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&winpos );
+
+    /* Calculate new position and size */
+    newWindowRect.left = x;
+    newWindowRect.right = x + width;
+    newWindowRect.top = y;
+    newWindowRect.bottom = y + height;
+
+    WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
+                           &pWnd->rectWindow, &pWnd->rectClient,
+                           &winpos, &newClientRect );
+
+    hrgnOldPos = CreateRectRgnIndirect32( &pWnd->rectWindow );
+    hrgnNewPos = CreateRectRgnIndirect32( &newWindowRect );
+    CombineRgn32( hrgnOldPos, hrgnOldPos, hrgnNewPos, RGN_DIFF );
+    DeleteObject32(hrgnOldPos);
+    DeleteObject32(hrgnNewPos);
+ 
+    /* Set new size and position */
+    pWnd->rectWindow = newWindowRect;
+    pWnd->rectClient = newClientRect;
+    SendMessage32A( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
+
+    if (!IsWindow32( winpos.hwnd )) return;
+    if( above == None )			/* absolute bottom */
+    {
+        WIN_UnlinkWindow( winpos.hwnd );
+        WIN_LinkWindow( winpos.hwnd, HWND_BOTTOM);
+    }
+    else EVENT_QueryZOrder( pWnd );	/* try to outsmart window manager */
 }
 
 
@@ -1185,7 +1225,7 @@
      * SI = mouse event flags (?)
      */
     Window root, child;
-    int rootX, rootY, childX, childY;
+    int rootX, rootY, winX, winY;
     unsigned int state;
 
     if (AX_reg(context) & ME_MOVE)
@@ -1196,19 +1236,19 @@
         return;
     }
     if (!XQueryPointer( display, rootWindow, &root, &child,
-                        &rootX, &rootY, &childX, &childY, &state )) return;
+                        &rootX, &rootY, &winX, &winY, &state )) return;
     if (AX_reg(context) & ME_LDOWN)
-        hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
-                        rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
+        hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ),
+                        0L, winX, winY, GetTickCount(), 0 );
     if (AX_reg(context) & ME_LUP)
-        hardware_event( WM_LBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
-                        rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
+        hardware_event( WM_LBUTTONUP, EVENT_XStateToKeyState( state ),
+                        0L, winX, winY, GetTickCount(), 0 );
     if (AX_reg(context) & ME_RDOWN)
-        hardware_event( WM_RBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
-                        rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
+        hardware_event( WM_RBUTTONDOWN, EVENT_XStateToKeyState( state ),
+                        0L, winX, winY, GetTickCount(), 0 );
     if (AX_reg(context) & ME_RUP)
-        hardware_event( WM_RBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
-                        rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
+        hardware_event( WM_RBUTTONUP, EVENT_XStateToKeyState( state ),
+                        0L, winX, winY, GetTickCount(), 0 );
 }
 
 
diff --git a/windows/focus.c b/windows/focus.c
index 28aa847..9f7bb9b 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -69,12 +69,15 @@
     if( !hFocusTo || hFocusTo != hwndFocus )
 	return;
 
+    /* According to API docs, the WM_SETFOCUS message is sent AFTER the window
+       has received the keyboard focus. */
+    FOCUS_SetXFocus( hFocusTo );
+
 #if 0
     SendMessage32A( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
 #else
     SendMessage16( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
 #endif
-    FOCUS_SetXFocus( hFocusTo );
 }
 
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 60c8cd6..8301094 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -26,7 +26,6 @@
 #include "stddebug.h"
 /* #define DEBUG_KEYBOARD */
 #include "debug.h"
-#include "accel.h"
 #include "struct32.h"
 
 BOOL32 MouseButtonsStates[3];
@@ -309,7 +308,8 @@
 
 static BOOL32 NumState=FALSE, CapsState=FALSE;
 
-void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, XKeyEvent * event, KEYLP localkeylp )
+void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
+                           DWORD event_time, KEYLP localkeylp )
 {
   BOOL32 * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
 
@@ -328,10 +328,10 @@
 		dprintf_keyboard(stddeb,"ON + KeyRelease => generating DOWN and UP messages.\n");
 		localkeylp.lp1.previous = 0; /* ? */
 		localkeylp.lp1.transition = 0;
-		hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2, event->x_root - desktopX,
-				event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
-		hardware_event( WM_KEYUP, vkey, localkeylp.lp2, event->x_root - desktopX,
-				event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+		hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2,
+                                event_x, event_y, event_time, 0 );
+		hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
+                                event_x, event_y, event_time, 0 );
 		*State=FALSE;
 		InputKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */ 
 	      } 
@@ -340,12 +340,12 @@
 	  if (Evtype==KeyPress)
 	    {
 	      dprintf_keyboard(stddeb,"OFF + Keypress => generating DOWN and UP messages.\n");
-	      hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2, event->x_root - desktopX,
-			      event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+	      hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2,
+                              event_x, event_y, event_time, 0 );
 	      localkeylp.lp1.previous = 1;
 	      localkeylp.lp1.transition = 1;
-	      hardware_event( WM_KEYUP, vkey, localkeylp.lp2, event->x_root - desktopX,
-			      event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+	      hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
+                              event_x, event_y, event_time, 0 );
 	      *State=TRUE; /* Goes to intermediary state before going to ON */
 	      InputKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
 	    }
@@ -357,7 +357,7 @@
  *
  * Handle a X key event
  */
-void KEYBOARD_HandleEvent( XKeyEvent *event )
+void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
 {
     char Str[24]; 
     XComposeStatus cs; 
@@ -368,17 +368,21 @@
 
     int ascii_chars = XLookupString(event, Str, 1, &keysym, &cs);
 
+    INT32 event_x = pWnd->rectWindow.left + event->x;
+    INT32 event_y = pWnd->rectWindow.top + event->y;
+    DWORD event_time = event->time - MSG_WineStartTicks;
+
     dprintf_key(stddeb, "EVENT_key : state = %X\n", event->state);
     if (keysym == XK_Mode_switch)
 	{
 	dprintf_key(stddeb, "Alt Gr key event received\n");
 	event->keycode = XKeysymToKeycode(event->display, XK_Control_L);
 	dprintf_key(stddeb, "Control_L is keycode 0x%x\n", event->keycode);
-	KEYBOARD_HandleEvent(event);
+	KEYBOARD_HandleEvent( pWnd, event );
 	event->keycode = XKeysymToKeycode(event->display, XK_Alt_L);
 	dprintf_key(stddeb, "Alt_L is keycode 0x%x\n", event->keycode);
 	force_extended = TRUE;
-	KEYBOARD_HandleEvent(event);
+	KEYBOARD_HandleEvent( pWnd, event );
 	force_extended = FALSE;
 	return;
 	}
@@ -416,10 +420,13 @@
     switch(vkey)
     {
     case VK_NUMLOCK:    
-      KEYBOARD_GenerateMsg(VK_NUMLOCK,event->type,event,keylp); break;
+      KEYBOARD_GenerateMsg( VK_NUMLOCK, event->type, event_x, event_y,
+                            event_time, keylp);
+      break;
     case VK_CAPITAL:
       dprintf_keyboard(stddeb,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,InputKeyStateTable[vkey]);
-      KEYBOARD_GenerateMsg(VK_CAPITAL,event->type,event,keylp); 
+      KEYBOARD_GenerateMsg( VK_CAPITAL, event->type, event_x, event_y,
+                            event_time, keylp ); 
       dprintf_keyboard(stddeb,"State after : %#.2x\n",InputKeyStateTable[vkey]);
       break;
     default:
@@ -452,14 +459,18 @@
 	if (!(InputKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
 	  { 
 	    dprintf_keyboard(stddeb,"Adjusting NumLock state. \n");
-	    KEYBOARD_GenerateMsg(VK_NUMLOCK,KeyPress,event,keylp);
-	    KEYBOARD_GenerateMsg(VK_NUMLOCK,KeyRelease,event,keylp);
+	    KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyPress, event_x, event_y,
+                                  event_time, keylp );
+	    KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyRelease, event_x, event_y,
+                                  event_time, keylp );
 	  }
 	if (!(InputKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
 	  {
 	    dprintf_keyboard(stddeb,"Adjusting Caps Lock state. State before %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
-	    KEYBOARD_GenerateMsg(VK_CAPITAL,KeyPress,event,keylp);
-	    KEYBOARD_GenerateMsg(VK_CAPITAL,KeyRelease,event,keylp);
+	    KEYBOARD_GenerateMsg( VK_CAPITAL, KeyPress, event_x, event_y,
+                                  event_time, keylp );
+	    KEYBOARD_GenerateMsg( VK_CAPITAL, KeyRelease, event_x, event_y,
+                                  event_time, keylp );
 	    dprintf_keyboard(stddeb,"State after %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
 	  }
 	/* End of intermediary states. */
@@ -471,8 +482,8 @@
 	dprintf_key(stddeb,"            InputKeyState=%X\n",
 		    InputKeyStateTable[vkey]);
 
-	hardware_event( message, vkey, keylp.lp2, event->x_root - desktopX,
-			event->y_root - desktopY, event->time - MSG_WineStartTicks, 0 );
+	hardware_event( message, vkey, keylp.lp2,
+                        event_x, event_y, event_time, 0 );
       }
     }
    }
@@ -831,7 +842,7 @@
 	      index : 1     adds 0x0100 (shift)
 	      index : ?     adds 0x0200 (ctrl)
 	      index : 2     adds 0x0600 (ctrl+alt)
-	      index : ?     adds 0x0700 (ctrl+alt+shit (used?))
+	      index : ?     adds 0x0700 (ctrl+alt+shift (used?))
 	     */
 	  }
 	dprintf_keyboard(stddeb," ... returning %#.2x\n", keyc2vkey[keycode]+highbyte);
diff --git a/windows/mdi.c b/windows/mdi.c
index ccc4bcf..54babe0 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -37,58 +37,38 @@
 DWORD SCROLL_SetNCSbState(WND*,int,int,int,int,int,int);
 
 /* ----------------- declarations ----------------- */
-static void MDI_UpdateFrameText(WND *, HWND16, BOOL32, LPCSTR);
-static BOOL32 MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND16);
-static BOOL32 MDI_RestoreFrameMenu(WND *, HWND16);
+static void MDI_UpdateFrameText(WND *, HWND32, BOOL32, LPCSTR);
+static BOOL32 MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND32);
+static BOOL32 MDI_RestoreFrameMenu(WND *, HWND32);
 
-static LONG MDI_ChildActivate(WND* ,HWND16 );
+static LONG MDI_ChildActivate( WND*, HWND32 );
 
 /* -------- Miscellaneous service functions ----------
  *
  *			MDI_GetChildByID
  */
 
-static HWND16 MDI_GetChildByID(WND* wndPtr,int id)
+static HWND32 MDI_GetChildByID(WND* wndPtr, INT32 id)
 {
     for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
         if (wndPtr->wIDmenu == id) return wndPtr->hwndSelf;
     return 0;
 }
 
-static void MDI_PostUpdate(HWND16 hwnd, MDICLIENTINFO* ci, WORD recalc)
+static void MDI_PostUpdate(HWND32 hwnd, MDICLIENTINFO* ci, WORD recalc)
 {
     if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
     {
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
-	PostMessage16( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
+	PostMessage32A( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
     }
     ci->sbRecalc = recalc;
 }
 
 /**********************************************************************
- *			MDI_MenuAppendItem
- */
-#ifdef SUPERFLUOUS_FUNCTIONS
-static BOOL32 MDI_MenuAppendItem(WND *clientWnd, HWND16 hWndChild)
-{
- char buffer[128];
- MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
- WND		*wndPtr     = WIN_FindWndPtr(hWndChild);
- int 		 n          = sprintf(buffer, "%d ", 
-				      clientInfo->nActiveChildren);
-
- if( !clientInfo->hWindowMenu ) return 0; 
-    
- if (wndPtr->text) strncpy(buffer + n, wndPtr->text, sizeof(buffer) - n - 1);
- return AppendMenu32A( clientInfo->hWindowMenu, MF_STRING,
-                       wndPtr->wIDmenu, buffer );
-}
-#endif
-
-/**********************************************************************
  *			MDI_MenuModifyItem
  */
-static BOOL32 MDI_MenuModifyItem(WND* clientWnd, HWND16 hWndChild )
+static BOOL32 MDI_MenuModifyItem(WND* clientWnd, HWND32 hWndChild )
 {
     char            buffer[128];
     MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
@@ -111,7 +91,7 @@
 /**********************************************************************
  *			MDI_MenuDeleteItem
  */
-static BOOL32 MDI_MenuDeleteItem(WND* clientWnd, HWND16 hWndChild )
+static BOOL32 MDI_MenuDeleteItem(WND* clientWnd, HWND32 hWndChild )
 {
     char    	 buffer[128];
     MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
@@ -156,7 +136,8 @@
  *
  * returns "activateable" child different from the current or zero
  */
-static HWND16 MDI_GetWindow(WND *clientWnd, HWND16 hWnd, BOOL16 bNext, DWORD dwStyleMask )
+static HWND32 MDI_GetWindow(WND *clientWnd, HWND32 hWnd, BOOL32 bNext,
+                            DWORD dwStyleMask )
 {
     MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
     WND *wndPtr, *pWnd, *pWndLast = NULL;
@@ -186,7 +167,7 @@
  *
  *  It seems that the default height is about 2/3 of the client rect
  */
-static void MDI_CalcDefaultChildPos( WND* w, WORD n, LPPOINT16 lpPos,
+static void MDI_CalcDefaultChildPos( WND* w, WORD n, LPPOINT32 lpPos,
                                      INT32 delta)
 {
     INT32  nstagger;
@@ -206,84 +187,68 @@
 /**********************************************************************
  *            MDISetMenu
  */
-static HMENU16 MDISetMenu(HWND16 hwnd, BOOL32 fRefresh, HMENU16 hmenuFrame,
-                          HMENU16 hmenuWindow)
+static LRESULT MDISetMenu( HWND32 hwnd, HMENU32 hmenuFrame,
+                           HMENU32 hmenuWindow)
 {
-    WND           *w         = WIN_FindWndPtr(hwnd);
+    WND *w = WIN_FindWndPtr(hwnd);
     MDICLIENTINFO *ci;
+    HWND32 hwndFrame = GetParent32(hwnd);
+    HMENU32 oldFrameMenu = GetMenu32(hwndFrame);
 
-    dprintf_mdi(stddeb, "WM_MDISETMENU: %04x %04x %04x %04x\n",
-                hwnd, fRefresh, hmenuFrame, hmenuWindow);
+    dprintf_mdi(stddeb, "WM_MDISETMENU: %04x %04x %04x\n",
+                hwnd, hmenuFrame, hmenuWindow);
 
     ci = (MDICLIENTINFO *) w->wExtra;
 
-    if (!fRefresh) 
+    if( ci->hwndChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
+        MDI_RestoreFrameMenu(w->parent, ci->hwndChildMaximized );
+
+    if( hmenuWindow && hmenuWindow!=ci->hWindowMenu )
     {
-	HWND16 hwndFrame = GetParent16(hwnd);
-	HMENU32 oldFrameMenu = GetMenu32(hwndFrame);
-        
-	if( ci->hwndChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
-	    MDI_RestoreFrameMenu(w->parent, ci->hwndChildMaximized );
+        /* delete menu items from ci->hWindowMenu 
+         * and add them to hmenuWindow */
 
-	if( hmenuWindow && hmenuWindow!=ci->hWindowMenu )
-	{
-	    /* delete menu items from ci->hWindowMenu 
-	     * and add them to hmenuWindow */
+        INT32 i = GetMenuItemCount32(ci->hWindowMenu) - 1;
+        INT32 pos = GetMenuItemCount32(hmenuWindow) + 1;
 
-            INT32 i = GetMenuItemCount32(ci->hWindowMenu) - 1;
-	    INT32 pos = GetMenuItemCount32(hmenuWindow) + 1;
+        AppendMenu32A( hmenuWindow, MF_SEPARATOR, 0, NULL);
 
-            AppendMenu32A( hmenuWindow, MF_SEPARATOR, 0, NULL);
+        if( ci->nActiveChildren )
+        {
+            INT32 j = i - ci->nActiveChildren + 1;
+            char buffer[100];
+            UINT32 id,state;
 
-	    if( ci->nActiveChildren )
-	    {
-	        INT32 j = i - ci->nActiveChildren + 1;
-		char buffer[100];
-		UINT32 id,state;
+            for( ; i >= j ; i-- )
+            {
+                id = GetMenuItemID32(ci->hWindowMenu,i );
+                state = GetMenuState32(ci->hWindowMenu,i,MF_BYPOSITION); 
 
-		for( ; i >= j ; i-- )
-		{
-		     id = GetMenuItemID32(ci->hWindowMenu,i );
-		     state = GetMenuState32(ci->hWindowMenu,i,MF_BYPOSITION); 
+                GetMenuString32A(ci->hWindowMenu, i, buffer, 100, MF_BYPOSITION);
 
-		     GetMenuString32A(ci->hWindowMenu, i, buffer, 100, MF_BYPOSITION);
+                DeleteMenu32(ci->hWindowMenu, i , MF_BYPOSITION);
+                InsertMenu32A(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
+                              id, buffer);
+                CheckMenuItem32(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
+            }
+        }
 
-		     DeleteMenu32(ci->hWindowMenu, i , MF_BYPOSITION);
-		     InsertMenu32A(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
-					     id, buffer);
-		     CheckMenuItem32(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
-		}
-	    }
+        /* remove separator */
+        DeleteMenu32(ci->hWindowMenu, i, MF_BYPOSITION); 
 
-	    /* remove separator */
-	    DeleteMenu32(ci->hWindowMenu, i, MF_BYPOSITION); 
+        ci->hWindowMenu = hmenuWindow;
+    } 
 
-	    ci->hWindowMenu = hmenuWindow;
-	} 
-
-	if( hmenuFrame && hmenuFrame!=oldFrameMenu)
-	{
-	    SetMenu32(hwndFrame, hmenuFrame);
-	    if( ci->hwndChildMaximized )
-	        MDI_AugmentFrameMenu(ci, w->parent, ci->hwndChildMaximized );
-	    return oldFrameMenu;
-	}
-
+    if( hmenuFrame && hmenuFrame!=oldFrameMenu)
+    {
+        SetMenu32(hwndFrame, hmenuFrame);
+        if( ci->hwndChildMaximized )
+            MDI_AugmentFrameMenu(ci, w->parent, ci->hwndChildMaximized );
+        return oldFrameMenu;
     }
     return 0;
 }
 
-/**********************************************************************
- *            MDIIconArrange
- */
-static WORD MDIIconArrange(HWND16 parent)
-{
-  return ArrangeIconicWindows16(parent);	/* Any reason why the    */
-						/* existing icon arrange */
-						/* can't be used here?	 */
-						/* -DRP			 */
-}
-
 
 /* ------------------ MDI child window functions ---------------------- */
 
@@ -291,26 +256,24 @@
 /**********************************************************************
  *					MDICreateChild
  */
-static HWND16 MDICreateChild( WND *w, MDICLIENTINFO *ci, HWND16 parent, 
-                              LPMDICREATESTRUCT16 cs, LPARAM lParam )
+static HWND32 MDICreateChild( WND *w, MDICLIENTINFO *ci, HWND32 parent, 
+                              LPMDICREATESTRUCT32A cs )
 {
-    POINT16          pos[2]; 
+    POINT32          pos[2]; 
     DWORD	     style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
-    HWND16 	     hwnd, hwndMax = 0;
+    HWND32 	     hwnd, hwndMax = 0;
     WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
     char	     lpstrDef[]="junk!";
 
     dprintf_mdi(stdnimp,"MDICreateChild: origin %i,%i - dim %i,%i, style %08x\n", 
-					 cs->x, cs->y, cs->cx, cs->cy, (unsigned)cs->style);    
+                cs->x, cs->y, cs->cx, cs->cy, (unsigned)cs->style);    
     /* calculate placement */
     MDI_CalcDefaultChildPos(w, ci->nTotalCreated++, pos, 0);
 
-    if( cs->cx == CW_USEDEFAULT16 || !cs->cx )
-        cs->cx = pos[1].x;
-    if( cs->cy == CW_USEDEFAULT16 || !cs->cy )
-        cs->cy = pos[1].y;
+    if (cs->cx == CW_USEDEFAULT32 || !cs->cx) cs->cx = pos[1].x;
+    if (cs->cy == CW_USEDEFAULT32 || !cs->cy) cs->cy = pos[1].y;
 
-    if( cs->x == CW_USEDEFAULT16 )
+    if( cs->x == CW_USEDEFAULT32 )
     {
  	cs->x = pos[0].x;
 	cs->y = pos[0].y;
@@ -320,11 +283,11 @@
     if( style & WS_VISIBLE && ci->hwndChildMaximized )
     {
 	if( style & WS_MAXIMIZE )
-	    SendMessage16(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
+	    SendMessage32A(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
 	hwndMax = ci->hwndChildMaximized;
-	ShowWindow16( hwndMax, SW_SHOWNOACTIVATE );
+	ShowWindow32( hwndMax, SW_SHOWNOACTIVATE );
 	if( style & WS_MAXIMIZE )
-	    SendMessage16(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
+	    SendMessage32A(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
     }
 
     /* this menu is needed to set a check mark in MDI_ChildActivate */
@@ -342,24 +305,30 @@
 
     if( w->flags & WIN_ISWIN32 )
     {
-    	MDICREATESTRUCT32A cs32a;
-
-	STRUCT32_MDICREATESTRUCT16to32A(cs,&cs32a);
-	cs32a.szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle);
-	cs32a.szClass = (LPCSTR)PTR_SEG_TO_LIN(cs->szClass);
-
-	hwnd = CreateWindow32A(cs32a.szClass,cs32a.szTitle, style, 
-			       cs->x, cs->y, cs->cx, cs->cy, parent, 
-			       (HMENU16)wIDmenu, cs->hOwner,
-			       (LPVOID)&cs32a);
-	STRUCT32_MDICREATESTRUCT32Ato16(&cs32a,cs);
+	hwnd = CreateWindow32A( cs->szClass, cs->szTitle, style, 
+                                cs->x, cs->y, cs->cx, cs->cy, parent, 
+                                (HMENU16)wIDmenu, cs->hOwner, cs );
     }
     else
-	hwnd = CreateWindow16( (LPCSTR)PTR_SEG_TO_LIN(cs->szClass),
-			       (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle), style, 
-			       cs->x, cs->y, cs->cx, cs->cy, parent, 
-			       (HMENU32)wIDmenu, cs->hOwner,
-			       (LPVOID)lParam);
+    {
+    	MDICREATESTRUCT16 *cs16;
+        LPSTR title, cls;
+
+        cs16 = SEGPTR_NEW(MDICREATESTRUCT16);
+        STRUCT32_MDICREATESTRUCT32Ato16( cs, cs16 );
+        title = SEGPTR_STRDUP( cs->szTitle );
+        cls   = SEGPTR_STRDUP( cs->szClass );
+        cs16->szTitle = SEGPTR_GET(title);
+        cs16->szClass = SEGPTR_GET(cls);
+
+	hwnd = CreateWindow16( cs->szClass, cs->szTitle, style, 
+			       cs16->x, cs16->y, cs16->cx, cs16->cy, parent, 
+			       (HMENU32)wIDmenu, cs16->hOwner,
+                               (LPVOID)SEGPTR_GET(cs16) );
+        SEGPTR_FREE( title );
+        SEGPTR_FREE( cls );
+        SEGPTR_FREE( cs16 );
+    }
 
     /* MDI windows are WS_CHILD so they won't be activated by CreateWindow */
 
@@ -369,7 +338,7 @@
 
 	MDI_MenuModifyItem(w ,hwnd); 
 	if( wnd->dwStyle & WS_MINIMIZE && ci->hwndActiveChild )
-	    ShowWindow16( hwnd, SW_SHOWMINNOACTIVE );
+	    ShowWindow32( hwnd, SW_SHOWMINNOACTIVE );
 	else
 	{
 	    SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );
@@ -404,7 +373,7 @@
  * Note: The rule here is that client rect of the maximized MDI child 
  *	 is equal to the client rect of the MDI client window.
  */
-static void MDI_ChildGetMinMaxInfo( WND* clientWnd, HWND16 hwnd,
+static void MDI_ChildGetMinMaxInfo( WND* clientWnd, HWND32 hwnd,
                                     MINMAXINFO16* lpMinMax )
 {
     WND*	childWnd = WIN_FindWndPtr(hwnd);
@@ -430,12 +399,12 @@
  * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
  *       being activated 
  */
-static void MDI_SwitchActiveChild( HWND16 clientHwnd, HWND16 childHwnd,
+static void MDI_SwitchActiveChild( HWND32 clientHwnd, HWND32 childHwnd,
                                    BOOL32 bNextWindow )
 {
     WND		  *w	     = WIN_FindWndPtr(clientHwnd);
-    HWND16	   hwndTo    = 0;
-    HWND16	   hwndPrev  = 0;
+    HWND32	   hwndTo    = 0;
+    HWND32	   hwndPrev  = 0;
     MDICLIENTINFO *ci;
 
     hwndTo = MDI_GetWindow(w, childHwnd, bNextWindow, 0);
@@ -465,7 +434,7 @@
 	    SetWindowPos32( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, 
 		  	    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
 	if( bOptimize )
-	    ShowWindow16( clientHwnd, SW_SHOW );
+	    ShowWindow32( clientHwnd, SW_SHOW );
     }
 }
 
@@ -473,8 +442,9 @@
 /**********************************************************************
  *                                      MDIDestroyChild
  */
-static HWND16 MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci, HWND16 parent,
-                               HWND16 child, BOOL32 flagDestroy )
+static LRESULT MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci,
+                                HWND32 parent, HWND32 child,
+                                BOOL32 flagDestroy )
 {
     WND         *childPtr = WIN_FindWndPtr(child);
 
@@ -486,7 +456,7 @@
 
 	    if( child == ci->hwndActiveChild )
 	    {
-		ShowWindow16( child, SW_HIDE);
+		ShowWindow32( child, SW_HIDE);
 		if( child == ci->hwndChildMaximized )
 		{
 		    MDI_RestoreFrameMenu(w_parent->parent, child);
@@ -505,7 +475,7 @@
 
         if (flagDestroy)
 	{
-	    MDI_PostUpdate(GetParent16(child), ci, SB_BOTH+1);
+	    MDI_PostUpdate(GetParent32(child), ci, SB_BOTH+1);
             DestroyWindow32(child);
 	}
     }
@@ -519,10 +489,10 @@
  *
  * Note: hWndChild is NULL when last child is being destroyed
  */
-static LONG MDI_ChildActivate( WND *clientPtr, HWND16 hWndChild )
+static LONG MDI_ChildActivate( WND *clientPtr, HWND32 hWndChild )
 {
     MDICLIENTINFO       *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; 
-    HWND16                 prevActiveWnd = clientInfo->hwndActiveChild;
+    HWND32               prevActiveWnd = clientInfo->hwndActiveChild;
     WND                 *wndPtr = WIN_FindWndPtr( hWndChild );
     WND			*wndPrev = WIN_FindWndPtr( prevActiveWnd );
     BOOL32		 isActiveFrameWnd = 0;	 
@@ -542,7 +512,7 @@
     {
 	wndPrev->dwStyle |= WS_SYSMENU;
 	SendMessage32A( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
-        SendMessage32A( prevActiveWnd, WM_MDIACTIVATE, (WPARAM32)prevActiveWnd, 
+        SendMessage32A( prevActiveWnd, WM_MDIACTIVATE, (WPARAM32)prevActiveWnd,
                         (LPARAM)hWndChild);
         /* uncheck menu item */
        	if( clientInfo->hWindowMenu )
@@ -556,11 +526,10 @@
         if( hWndChild )
 	{
 		  clientInfo->hwndActiveChild = hWndChild;
-		  ShowWindow16( hWndChild, SW_SHOWMAXIMIZED);
+		  ShowWindow32( hWndChild, SW_SHOWMAXIMIZED);
 	}
 	else
-		ShowWindow16( clientInfo->hwndActiveChild, 
-			    SW_SHOWNORMAL );
+		ShowWindow32( clientInfo->hwndActiveChild, SW_SHOWNORMAL );
 
     clientInfo->hwndActiveChild = hWndChild;
 
@@ -582,10 +551,10 @@
 
     if( isActiveFrameWnd )
     {
-	    SendMessage16( hWndChild, WM_NCACTIVATE, TRUE, 0L);
+	    SendMessage32A( hWndChild, WM_NCACTIVATE, TRUE, 0L);
 	    if( GetFocus32() == clientInfo->self )
-		SendMessage16( clientInfo->self, WM_SETFOCUS, 
-			    (WPARAM16)clientInfo->self, 0L );
+		SendMessage32A( clientInfo->self, WM_SETFOCUS, 
+                                (WPARAM32)clientInfo->self, 0L );
 	    else
 		SetFocus32( clientInfo->self );
     }
@@ -649,8 +618,8 @@
 	WND**	heapPtr = ppWnd;
 	if( total )
 	{
-	    INT16	delta = 0, n = 0;
-	    POINT16	pos[2];
+	    INT32	delta = 0, n = 0;
+	    POINT32	pos[2];
 	    if( total < ci->nActiveChildren )
 		delta = SYSMETRICS_CYICONSPACING + SYSMETRICS_CYICON;
 
@@ -661,30 +630,32 @@
                             (*ppWnd)->hwndSelf, pos[0].x, pos[0].y, pos[1].x, pos[1].y);
 
 		MDI_CalcDefaultChildPos(clientWnd, n++, pos, delta);
-		SetWindowPos32((*ppWnd)->hwndSelf, 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
-					      SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+		SetWindowPos32( (*ppWnd)->hwndSelf, 0, pos[0].x, pos[0].y,
+                                pos[1].x, pos[1].y,
+                                SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
 		ppWnd++;
 	    }
 	}
 	HeapFree( SystemHeap, 0, heapPtr );
     }
 
-    if( total < ci->nActiveChildren ) ArrangeIconicWindows32( clientWnd->hwndSelf );
+    if( total < ci->nActiveChildren )
+        ArrangeIconicWindows32( clientWnd->hwndSelf );
     return 0;
 }
 
 /**********************************************************************
  *					MDITile
  */
-static LONG MDITile(WND* wndClient, MDICLIENTINFO *ci,WORD wParam)
+static void MDITile( WND* wndClient, MDICLIENTINFO *ci, WPARAM32 wParam )
 {
     WND**	ppWnd;
     UINT32	total = 0;
 
     if (ci->hwndChildMaximized)
-	ShowWindow16(ci->hwndChildMaximized, SW_NORMAL);
+	ShowWindow32(ci->hwndChildMaximized, SW_NORMAL);
 
-    if (ci->nActiveChildren == 0) return 0;
+    if (ci->nActiveChildren == 0) return;
 
     ppWnd = WIN_BuildWinArray(wndClient, BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
 	    ((wParam & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
@@ -744,7 +715,6 @@
     }
   
     if( total < ci->nActiveChildren ) ArrangeIconicWindows32( wndClient->hwndSelf );
-    return 0;
 }
 
 /* ----------------------- Frame window ---------------------------- */
@@ -754,10 +724,10 @@
  *					MDI_AugmentFrameMenu
  */
 static BOOL32 MDI_AugmentFrameMenu( MDICLIENTINFO* ci, WND *frame,
-                                    HWND16 hChild )
+                                    HWND32 hChild )
 {
     WND*	child = WIN_FindWndPtr(hChild);
-    HMENU16  	hSysPopup = 0;
+    HMENU32  	hSysPopup = 0;
 
     dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame %p,child %04x\n",frame,hChild);
 
@@ -797,7 +767,7 @@
 /**********************************************************************
  *					MDI_RestoreFrameMenu
  */
-static BOOL32 MDI_RestoreFrameMenu( WND *frameWnd, HWND16 hChild )
+static BOOL32 MDI_RestoreFrameMenu( WND *frameWnd, HWND32 hChild )
 {
     INT32 nItems = GetMenuItemCount32(frameWnd->wIDmenu) - 1;
 
@@ -821,7 +791,7 @@
  *
  * Note: lpTitle can be NULL
  */
-static void MDI_UpdateFrameText( WND *frameWnd, HWND16 hClient,
+static void MDI_UpdateFrameText( WND *frameWnd, HWND32 hClient,
                                  BOOL32 repaint, LPCSTR lpTitle )
 {
     char   lpBuffer[MDI_MAXTITLELENGTH+1];
@@ -830,6 +800,12 @@
 
     dprintf_mdi(stddeb, "MDI: repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL");
 
+    if (!clientWnd)
+           return;
+
+    if (!ci)
+           return;
+
     /* store new "default" title if lpTitle is not NULL */
     if (lpTitle) 
     {
@@ -892,10 +868,10 @@
  *
  * This function handles all MDI requests.
  */
-LRESULT WINAPI MDIClientWndProc(HWND16 hwnd, UINT16 message, WPARAM16 wParam,
-                                LPARAM lParam)
+LRESULT WINAPI MDIClientWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
+                                 LPARAM lParam )
 {
-    LPCREATESTRUCT16     cs;
+    LPCREATESTRUCT32A    cs;
     MDICLIENTINFO       *ci;
     RECT32		 rect;
     WND                 *w 	  = WIN_FindWndPtr(hwnd);
@@ -908,7 +884,7 @@
     {
       case WM_CREATE:
 
-	cs = (LPCREATESTRUCT16) PTR_SEG_TO_LIN(lParam);
+	cs = (LPCREATESTRUCT32A)lParam;
 
 	/* Translation layer doesn't know what's in the cs->lpCreateParams
 	 * so we have to keep track of what environment we're in. */
@@ -966,52 +942,46 @@
 	return 0;
 
       case WM_MDIACTIVATE:
-        if( ci->hwndActiveChild != (HWND16)wParam )
-	    SetWindowPos32((HWND32)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); 
+        if( ci->hwndActiveChild != (HWND32)wParam )
+	    SetWindowPos32((HWND32)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
 	return 0;
 
       case WM_MDICASCADE:
 	return MDICascade(w, ci);
 
       case WM_MDICREATE:
-        if( lParam )
-	{
-	    MDICREATESTRUCT16* cs = (MDICREATESTRUCT16*) PTR_SEG_TO_LIN(lParam);
-	    return (LONG)MDICreateChild(w, ci, hwnd, cs, lParam );
-	}
+        if (lParam) return MDICreateChild( w, ci, hwnd,
+                                           (MDICREATESTRUCT32A*)lParam );
 	return 0;
 
       case WM_MDIDESTROY:
-	return (LONG)MDIDestroyChild(w, ci, hwnd, (HWND32)wParam, TRUE);
+	return MDIDestroyChild( w, ci, hwnd, (HWND32)wParam, TRUE );
 
       case WM_MDIGETACTIVE:
-	return ((LONG) ci->hwndActiveChild | 
-		((LONG) (ci->hwndChildMaximized>0) << 16));
+          if (lParam) *(BOOL32 *)lParam = (ci->hwndChildMaximized > 0);
+          return ci->hwndActiveChild;
 
       case WM_MDIICONARRANGE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
-	MDIIconArrange(hwnd);
+        ArrangeIconicWindows32(hwnd);
 	ci->sbRecalc = SB_BOTH+1;
-	SendMessage16(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
+	SendMessage32A(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
 	return 0;
 	
       case WM_MDIMAXIMIZE:
-	ShowWindow16((HWND16)wParam, SW_MAXIMIZE);
+	ShowWindow32( (HWND32)wParam, SW_MAXIMIZE );
 	return 0;
 
       case WM_MDINEXT: /* lParam != 0 means previous window */
-	MDI_SwitchActiveChild(hwnd, (HWND16)wParam, (lParam)? FALSE : TRUE );
+	MDI_SwitchActiveChild(hwnd, (HWND32)wParam, (lParam)? FALSE : TRUE );
 	break;
 	
       case WM_MDIRESTORE:
-	ShowWindow16( (HWND16)wParam, SW_NORMAL);
+	ShowWindow32( (HWND32)wParam, SW_NORMAL);
 	return 0;
 
       case WM_MDISETMENU:
-          /* if Winelib32:
-           * return (LRESULT)MDISetMenu(hwnd, FALSE, (HMENU16)wParam, (HMENU16)lParam);
-           */
-          return (LRESULT)MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
+          return MDISetMenu( hwnd, (HMENU32)wParam, (HMENU32)lParam );
 	
       case WM_MDITILE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
@@ -1038,19 +1008,18 @@
 	
       case WM_NCACTIVATE:
         if( ci->hwndActiveChild )
-	     SendMessage16(ci->hwndActiveChild, message, wParam, lParam);
+	     SendMessage32A(ci->hwndActiveChild, message, wParam, lParam);
 	break;
 	
       case WM_PARENTNOTIFY:
-        if( wParam == WM_LBUTTONDOWN )
+        if (LOWORD(wParam) == WM_LBUTTONDOWN)
         {
             POINT16  pt = MAKEPOINT16(lParam);
             HWND16 child = ChildWindowFromPoint16(hwnd, pt);
 
 	    dprintf_mdi(stddeb,"MDIClient: notification from %04x (%i,%i)\n",child,pt.x,pt.y);
 
-            if( child && child != hwnd &&
-			 child != ci->hwndActiveChild )
+            if( child && child != hwnd && child != ci->hwndActiveChild )
                 SetWindowPos32(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
         }
         return 0;
@@ -1059,10 +1028,10 @@
         if( ci->hwndChildMaximized )
 	{
 	    WND*	child = WIN_FindWndPtr(ci->hwndChildMaximized);
-	    RECT16	rect  = { 0, 0, LOWORD(lParam), HIWORD(lParam) };
+	    RECT32	rect  = { 0, 0, LOWORD(lParam), HIWORD(lParam) };
 
-	    AdjustWindowRectEx16(&rect, child->dwStyle, 0, child->dwExStyle);
-	    MoveWindow16(ci->hwndChildMaximized, rect.left, rect.top,
+	    AdjustWindowRectEx32(&rect, child->dwStyle, 0, child->dwExStyle);
+	    MoveWindow32(ci->hwndChildMaximized, rect.left, rect.top,
 			 rect.right - rect.left, rect.bottom - rect.top, 1);
 	}
 	else
@@ -1080,7 +1049,7 @@
 	return 0;
     }
     
-    return DefWindowProc16(hwnd, message, wParam, lParam);
+    return DefWindowProc32A( hwnd, message, wParam, lParam );
 }
 
 
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 3638ebc..9235836 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -5,6 +5,7 @@
  *
  */
 
+#include "version.h"
 #include "win.h"
 #include "message.h"
 #include "sysmetrics.h"
@@ -1332,22 +1333,6 @@
 }
 
 /***********************************************************************
- *           NC_TrackSysMenu
- *
- * Track a mouse button press on the system menu.
- * TODO: Unify with NC_TrackMinMaxBox() (and without InternalGetMessage() calls).
- */
-static void NC_TrackSysMenu( HWND32 hwnd, POINT16 pt )
-{
-    WND*	wndPtr = WIN_FindWndPtr( hwnd );
-    
-    if (wndPtr->dwStyle & WS_SYSMENU)
-	SendMessage16( hwnd, WM_SYSCOMMAND, 
-		SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
-}
-
-
-/***********************************************************************
  *           NC_StartSizeMove
  *
  * Initialisation of a move or resize, when initiatied from a menu choice.
@@ -1450,7 +1435,7 @@
     WND *     wndPtr = WIN_FindWndPtr( hwnd );
     BOOL32    thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
     BOOL32    iconic = wndPtr->dwStyle & WS_MINIMIZE;
-    int       moved = 0;
+    BOOL32    moved = FALSE;
 
     if (IsZoomed32(hwnd) || !IsWindowVisible32(hwnd) ||
         (wndPtr->flags & WIN_MANAGED)) return;
@@ -1521,19 +1506,12 @@
 	if (rootWindow == DefaultRootWindow(display)) XGrabServer( display );
     }
 
-    if( iconic )
+    if( iconic ) /* create a cursor for dragging */
     {
-	HICON16 hIcon = (wndPtr->class->hIcon)
-                      ? wndPtr->class->hIcon
+	HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
                       : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
-	if( hIcon )
-	{
-	    hDragCursor =  CURSORICON_IconToCursor( hIcon, TRUE );
-	    hOldCursor = SetCursor32(hDragCursor);
-	    ShowCursor32( TRUE );
-	} 
-	else iconic = FALSE;
-	WINPOS_ShowIconTitle( wndPtr, FALSE );
+	if( hIcon ) hDragCursor =  CURSORICON_IconToCursor( hIcon, TRUE );
+	if( !hDragCursor ) iconic = FALSE;
     }
 
     if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
@@ -1574,7 +1552,17 @@
 
 	if (dx || dy)
 	{
-            moved = 1;
+	    if( !moved )
+	    {
+		moved = TRUE;
+        	if( iconic ) /* ok, no system popup tracking */
+		{
+		    hOldCursor = SetCursor32(hDragCursor);
+		    ShowCursor32( TRUE );
+		    WINPOS_ShowIconTitle( wndPtr, FALSE );
+		}
+	    }
+
 	    if (msg.message == WM_KEYDOWN) SetCursorPos32( pt.x, pt.y );
 	    else
 	    {
@@ -1599,9 +1587,12 @@
     ReleaseCapture();
     if( iconic )
     {
-	ShowCursor32( FALSE );
-	SetCursor32(hOldCursor);
-	if( hDragCursor ) DestroyCursor32( hDragCursor );
+	if( moved ) /* restore cursors, show icon title later on */
+	{
+	    ShowCursor32( FALSE );
+	    SetCursor32( hOldCursor );
+	}
+        DestroyCursor32( hDragCursor );
     }
     else
 	NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
@@ -1616,40 +1607,43 @@
 
     if (HOOK_IsHooked( WH_CBT ))
     {
-       RECT16* pr = SEGPTR_NEW(RECT16);
-       if( pr )
-       {
-           CONV_RECT32TO16( &sizingRect, pr );
-	  if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
+	RECT16* pr = SEGPTR_NEW(RECT16);
+	if( pr )
+	{
+            CONV_RECT32TO16( &sizingRect, pr );
+	    if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
 			        (LPARAM)SEGPTR_GET(pr)) )
-	      sizingRect = wndPtr->rectWindow;
-	  else
-	      CONV_RECT16TO32( pr, &sizingRect );
-	  SEGPTR_FREE(pr);
-       }
+		sizingRect = wndPtr->rectWindow;
+	    else
+		CONV_RECT16TO32( pr, &sizingRect );
+	    SEGPTR_FREE(pr);
+	}
     }
     SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
     SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
 
-    /* Single click brings up the system menu when iconized */
-
-    if( moved )
+    if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
     {
-	if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return;
-
 	/* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
 	SetWindowPos32( hwnd, 0, sizingRect.left, sizingRect.top,
 			sizingRect.right - sizingRect.left,
 			sizingRect.bottom - sizingRect.top,
 		      ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
     }
-    if( wndPtr->dwStyle & WS_MINIMIZE )
-    {
-	WINPOS_ShowIconTitle( wndPtr, TRUE );
-	if (!moved && (wndPtr->dwStyle & WS_SYSMENU))
-            SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
-                           MAKELPARAM( pt.x, pt.y ) );
-    }
+
+    if( IsWindow32(hwnd) )
+	if( wndPtr->dwStyle & WS_MINIMIZE )
+	{
+	    /* Single click brings up the system menu when iconized */
+
+	    if( !moved ) 
+	    {
+		 if( wndPtr->dwStyle & WS_SYSMENU ) 
+		     SendMessage16( hwnd, WM_SYSCOMMAND,
+				    SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
+	    }
+	    else WINPOS_ShowIconTitle( wndPtr, TRUE );
+	}
 }
 
 
@@ -1663,18 +1657,15 @@
     MSG16 msg;
     HDC32 hdc = GetWindowDC32( hwnd );
     BOOL32 pressed = TRUE;
+    void  (*paintButton)(HWND32, HDC16, BOOL32);
 
     SetCapture32( hwnd );
     if (wParam == HTMINBUTTON)
-	if(TWEAK_Win95Look)
-	    NC_DrawMinButton95( hwnd, hdc, TRUE );
-	else
-	    NC_DrawMinButton( hwnd, hdc, TRUE );
+	paintButton = (TWEAK_Win95Look) ? &NC_DrawMinButton95 : &NC_DrawMinButton;
     else
-	if(TWEAK_Win95Look)
-	    NC_DrawMaxButton95( hwnd, hdc, TRUE );
-	else
-	    NC_DrawMaxButton( hwnd, hdc, TRUE );
+	paintButton = (TWEAK_Win95Look) ? &NC_DrawMaxButton95 : &NC_DrawMaxButton;
+
+    (*paintButton)( hwnd, hdc, TRUE );
 
     do
     {
@@ -1683,30 +1674,10 @@
 
 	pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
 	if (pressed != oldstate)
-	{
-	    if (wParam == HTMINBUTTON)
-		if(TWEAK_Win95Look)
-		    NC_DrawMinButton95( hwnd, hdc, pressed );
-		else
-		    NC_DrawMinButton( hwnd, hdc, pressed );
-	    else
-		if(TWEAK_Win95Look)
-		    NC_DrawMaxButton95( hwnd, hdc, pressed );
-		else
-		    NC_DrawMaxButton( hwnd, hdc, pressed );
-	}
+	   (*paintButton)( hwnd, hdc, pressed );
     } while (msg.message != WM_LBUTTONUP);
 
-    if (wParam == HTMINBUTTON)
-	if(TWEAK_Win95Look)
-	    NC_DrawMinButton95( hwnd, hdc, FALSE );
-	else
-	    NC_DrawMinButton( hwnd, hdc, FALSE );
-    else
-	if(TWEAK_Win95Look)
-	    NC_DrawMaxButton95( hwnd, hdc, FALSE );
-	else
-	    NC_DrawMaxButton( hwnd, hdc, FALSE );
+    (*paintButton)( hwnd, hdc, FALSE );
 
     ReleaseCapture();
     ReleaseDC32( hwnd, hdc );
@@ -1781,20 +1752,34 @@
  *
  * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
  */
-LONG NC_HandleNCLButtonDown( HWND32 hwnd, WPARAM16 wParam, LPARAM lParam )
+LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
 {
+    HWND32 hwnd = pWnd->hwndSelf;
+
     switch(wParam)  /* Hit test */
     {
     case HTCAPTION:
+	 hwnd = WIN_GetTopParent(hwnd);
 
-	if( WINPOS_SetActiveWindow(WIN_GetTopParent(hwnd), TRUE, TRUE)
-	    || (GetActiveWindow32() == WIN_GetTopParent(hwnd)) )
-		SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
-	break;
+	 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow32() == hwnd) )
+		SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
+	 break;
 
     case HTSYSMENU:
-	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
-	break;
+	 if( pWnd->dwStyle & WS_SYSMENU )
+	 {
+	     if( !(pWnd->dwStyle & WS_MINIMIZE) )
+	     {
+		HDC32 hDC = GetWindowDC32(hwnd);
+		if( TWEAK_Win95Look)
+		    NC_DrawSysButton95( hwnd, hDC, TRUE );
+		else
+		    NC_DrawSysButton( hwnd, hDC, TRUE );
+		ReleaseDC32( hwnd, hDC );
+	     }
+	     SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
+	 }
+	 break;
 
     case HTMENU:
 	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
@@ -1866,12 +1851,12 @@
 
     case HTHSCROLL:
 	SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
-            lParam );
+		       lParam );
 	break;
 
     case HTVSCROLL:
 	SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
-            lParam );
+		       lParam );
 	break;
     }
     return 0;
@@ -1938,10 +1923,7 @@
 
     case SC_SCREENSAVE:
 	if (wParam == SC_ABOUTWINE)
-	{   
-            extern const char people[];
-            ShellAbout32A(hwnd,"Wine",people,0);
-        }
+            ShellAbout32A(hwnd,"Wine", WINE_RELEASE_INFO, 0);
 	break;
   
     case SC_HOTKEY:
diff --git a/windows/painting.c b/windows/painting.c
index 77a3748..8699c2e 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -208,31 +208,50 @@
 
 
 /***********************************************************************
+ *	     PAINT_GetControlBrush
+ */
+static HBRUSH16 PAINT_GetControlBrush( HWND32 hParent, HWND32 hWnd, HDC16 hDC, UINT16 ctlType )
+{
+    HBRUSH16 bkgBrush = (HBRUSH16)SendMessage32A( hParent, WM_CTLCOLORMSGBOX + ctlType, 
+							     (WPARAM32)hDC, (LPARAM)hWnd );
+    if( !IsGDIObject(bkgBrush) )
+	bkgBrush = DEFWND_ControlColor( hDC, ctlType );
+    return bkgBrush;
+}
+
+
+/***********************************************************************
  *           PaintRect    (USER.325)
  */
 void WINAPI PaintRect( HWND16 hwndParent, HWND16 hwnd, HDC16 hdc,
                        HBRUSH16 hbrush, const RECT16 *rect)
 {
-      /* Send WM_CTLCOLOR message if needed */
-
-    if ((UINT32)hbrush <= CTLCOLOR_MAX)
-    {
-	if (!hwndParent) return;
-	hbrush = (HBRUSH16)SendMessage32A( hwndParent, 
-                                           WM_CTLCOLORMSGBOX + (UINT32)hbrush,
-                                           (WPARAM32)hdc, (LPARAM)hwnd );
-    }
-    if (hbrush) FillRect16( hdc, rect, hbrush );
+    if( hbrush <= CTLCOLOR_MAX ) 
+	if( hwndParent )
+	    hbrush = PAINT_GetControlBrush( hwndParent, hwnd, hdc, (UINT16)hbrush );
+	else 
+	    return;
+    if( hbrush ) 
+	FillRect16( hdc, rect, hbrush );
 }
 
 
 /***********************************************************************
  *           GetControlBrush    (USER.326)
  */
-HBRUSH16 WINAPI GetControlBrush( HWND16 hwnd, HDC16 hdc, UINT16 control )
+HBRUSH16 WINAPI GetControlBrush( HWND16 hwnd, HDC16 hdc, UINT16 ctlType )
 {
-    return (HBRUSH16)SendMessage32A( GetParent32(hwnd), WM_CTLCOLOR+control,
-                                     (WPARAM32)hdc, (LPARAM)hwnd );
+    WND* wndPtr = WIN_FindWndPtr( hwnd );
+
+    if((ctlType <= CTLCOLOR_MAX) && wndPtr )
+    {
+	WND* parent;
+	if( wndPtr->dwStyle & WS_POPUP ) parent = wndPtr->owner;
+	else parent = wndPtr->parent;
+	if( !parent ) parent = wndPtr;
+	return (HBRUSH16)PAINT_GetControlBrush( parent->hwndSelf, hwnd, hdc, ctlType );
+    }
+    return (HBRUSH16)0;
 }
 
 
@@ -240,7 +259,9 @@
  *           PAINT_RedrawWindow
  *
  * FIXME: Windows uses WM_SYNCPAINT to cut down the number of intertask
- * SendMessage() calls. From SDK:
+ * SendMessage() calls. This is a comment inside DefWindowProc() source 
+ * from 16-bit SDK:
+ *
  *   This message avoids lots of inter-app message traffic
  *   by switching to the other task and continuing the
  *   recursion there.
diff --git a/windows/queue.c b/windows/queue.c
index f9534cd..ecc6f30 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -11,6 +11,7 @@
 #include "queue.h"
 #include "task.h"
 #include "win.h"
+#include "clipboard.h"
 #include "hook.h"
 #include "thread.h"
 #include "process.h"
@@ -762,6 +763,7 @@
        if( WIN_GetDesktop()->hmemTaskQ == hQueue )
 	   WIN_GetDesktop()->hmemTaskQ = hNewQueue;
        WIN_ResetQueueWindows( WIN_GetDesktop(), hQueue, hNewQueue );
+       CLIPBOARD_ResetLock( hQueue, hNewQueue );
        QUEUE_DeleteMsgQueue( hQueue );
     }
 
diff --git a/windows/user.c b/windows/user.c
index dda1a28..f791b00 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -15,6 +15,7 @@
 #include "task.h"
 #include "queue.h"
 #include "win.h"
+#include "clipboard.h"
 #include "hook.h"
 #include "debug.h"
 #include "toolhelp.h"
@@ -181,6 +182,7 @@
 
     QUEUE_SetExitingQueue( hQueue );
     WIN_ResetQueueWindows( desktop, hQueue, (HQUEUE16)0);
+    CLIPBOARD_ResetLock( hQueue, 0 );
     QUEUE_SetExitingQueue( 0 );
 
     /* Free the message queue */
diff --git a/windows/win.c b/windows/win.c
index 5856606..11c45b8 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -330,6 +330,7 @@
 	    }
 	    QUEUE_RemoveMsg(msgQ, pos);
 	}
+	/* repost WM_QUIT to make sure this app exits its message loop */
 	if( bPostQuit ) PostQuitMessage32(wQuitParam);
 	wndPtr->hmemTaskQ = 0;
     }
@@ -653,7 +654,7 @@
 	    win_attr.event_mask = ExposureMask | KeyPressMask |
 	                          KeyReleaseMask | PointerMotionMask |
 	                          ButtonPressMask | ButtonReleaseMask |
-	                          FocusChangeMask | StructureNotifyMask;
+	                          FocusChangeMask;
             win_attr.override_redirect = TRUE;
 	}
         win_attr.colormap      = COLOR_GetColormap();
@@ -936,8 +937,8 @@
  */
 static void WIN_CheckFocus( WND* pWnd )
 {
-  if( GetFocus16() == pWnd->hwndSelf )
-      SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 ); 
+    if( GetFocus16() == pWnd->hwndSelf )
+	SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 ); 
 }
 
 /***********************************************************************
@@ -945,28 +946,25 @@
  */
 static void WIN_SendDestroyMsg( WND* pWnd )
 {
-  WND*	pChild;
+    WIN_CheckFocus(pWnd);
 
-  WIN_CheckFocus(pWnd);
-
-  if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
-  if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd ); 
+    if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
+    if( !pWnd->window ) CLIPBOARD_ResetOwner( pWnd ); 
   
-  SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
+    SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
 
-  if( !IsWindow32(pWnd->hwndSelf) )
-  {
-    dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
-    return;
-  }
-
-  pChild = pWnd->child;
-  while( pChild )
-  { 
-    WIN_SendDestroyMsg( pChild );
-    pChild = pChild->next;
-  }
-  WIN_CheckFocus(pWnd);
+    if( IsWindow32(pWnd->hwndSelf) )
+    {
+	WND* pChild = pWnd->child;
+	while( pChild )
+	{
+	    WIN_SendDestroyMsg( pChild );
+	    pChild = pChild->next;
+	}
+	WIN_CheckFocus(pWnd);
+    }
+    else
+	dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
 }
 
 
@@ -1013,7 +1011,7 @@
 	    if( !IsWindow32(hwnd) ) return TRUE;
 	}
 
-    if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
+    if( wndPtr->window ) CLIPBOARD_ResetOwner( wndPtr ); /* before the window is unmapped */
 
       /* Hide the window */
 
diff --git a/windows/winpos.c b/windows/winpos.c
index b916d90..1f28f5f 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -226,7 +226,7 @@
 
 
 /***********************************************************************
- *           GetWindowRect32   (USER.32)
+ *           GetWindowRect32   (USER32.308)
  */
 void WINAPI GetWindowRect32( HWND32 hwnd, LPRECT32 rect ) 
 {
@@ -2202,7 +2202,9 @@
 				    newClientRect.top != wndPtr->rectClient.top) )
 	    winpos.flags &= ~SWP_NOCLIENTMOVE;
 
-    /* Update active DCEs */
+    /* Update active DCEs 
+     * TODO: Optimize conditions that trigger DCE update.
+     */
 
     if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) && 
 					 wndPtr->dwStyle & WS_VISIBLE) || 
@@ -2211,7 +2213,7 @@
         RECT32 rect;
 
         UnionRect32(&rect, &newWindowRect, &wndPtr->rectWindow);
-        DCE_InvalidateDCE(wndPtr->parent, &rect);
+	DCE_InvalidateDCE(wndPtr->parent, &rect);
     }
 
     /* change geometry */
diff --git a/windows/winproc.c b/windows/winproc.c
index e5960bb..259b384 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -89,8 +89,6 @@
                                                UINT32 msg, WPARAM32 wParam,
                                                LPARAM lParam );
 
-extern void CallFrom16_long_wwwll(void);
-
 static HANDLE32 WinProcHeap;
 
 
@@ -211,8 +209,8 @@
                                            (void(*)())WINPROC_CallProc16To32A :
                                            (void(*)())WINPROC_CallProc16To32W;
             proc->thunk.t_from16.lcall       = 0x9a;   /* lcall cs:relay */
-            proc->thunk.t_from16.relay       = CallFrom16_long_wwwll;
-            proc->thunk.t_from16.cs          = WINE_CODE_SELECTOR;
+            proc->thunk.t_from16.relay       = Callbacks->CallFrom16WndProc;
+            GET_CS(proc->thunk.t_from16.cs);
             proc->jmp.jmp  = 0xe9;
             /* Fixup relative jump */
             proc->jmp.proc = (WNDPROC32)((DWORD)func -