Release 960928

Fri Sep 27 14:18:42 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/button.c]
	Fixed focus rectangle size and clipping.

	* [controls/scroll.c]
	Converted to Win32 and added support for scroll page.
	Completed SetScrollInfo() and implemented other Win32 functions.

	* [files/file.c]
	Removed FILE_Read() (use _lread32 instead).

	* [objects/dce.c] [include/dce.h]
	Allocate DCE on the Win32 heap, and use pointers instead of
	handles.
	Implemented Win32 version of DC functions.

	* [windows/painting.c]
	Attempt to make CS_PARENTDC style work again.

Wed Sep 25 23:40:52 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/dce.c] [windows/winpos.c]
	Override SaveUnder attribute when painting took place
	in a window below. Force X to raise activated window 
	in seamless mode.

	* [misc/clipboard.c] [windows/event.c]
	Translation between DOS and Unix text formats and several
	other fixes for the sudden selection loss.

	* [windows/message.c]
	Apply "first" and "last" when checking for WM_QUIT in 
        MSG_PeekMessage().

	* [windows/win.c]
	Rearranged DestroyWindow() to fit "Windows Internals"
	description.

	* [windows/win.c] [windows/winpos.c] [windows/nonclient.c]
	Misc. fixes to CBT hook calls.

	* [controls/menu.c] [misc/user.c]
	Fixup resident popup menu window so that it doesn't get
	destroyed by USER_AppExit().

	* [loader/module.c] [loader/task.c] [windows/event.c]
	Process "unsafe" X events outside the scheduler to prevent
	deadlocks.

	* [windows/message.c] [windows/queue.c] [windows/winpos.c]
	Lots of fixes for better Win16 multitasking.

Wed Sep 25 20:36:30 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [include/windows.h]
	Added some missing HOOK defines.

	* [misc/shell.c][if1632/shell32.spec][include/shell.h]
	SHGetFileInfoA stub added (win95 mplayer.exe /play bla.avi).

	* [win32/console.c][include/wincon.h]
	GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize added.

	* [misc/registry.c]
	Some null ptr fixes.

	* [loader/pe_image.c]
	Fixed exported function lookup. (msvcrt20.dll)
	Add debugsyms for entrypoint, exported functions and sections.

	* [multimedia/mmsystem.c]
	MCIOpen: support for element opens (mplayer.exe /play bla.avi).

	* [several]
	Added several missing things/stubs/simple thunks from win32
	to win16 code.

Sat Sep 21 17:27:44 1996  O.Flebbe  <flebbe@science-computing.uni-tuebingen.de>

	* [windows/property.c]
	Fixed debugging of 16 Bit RemoveProp().

	* [debugger/memory.c]
	Added DEBUG_checkmap_bad() for linux.

Thu Sep 19 20:48:31 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/event.c] [windows/hook.c]
	Use EnableHardwareInput() for JournalPlayback hook.

	* [controls/listbox.c]
	Changed handling of LB_GETITEMRECT in empty listboxes.

Thu Sep 19 13:34:35 1996  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [misc/main.c]
	Fixes to X resources handling.	

Wed Sep 18 00:31:15 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/metafile.c] [include/gdi.h] [objects/dc.c]
	Individual handle table created for each metafile. Fixed
 	GlobalReAlloc() bug in MF_AddHandleDC() (was MF_AddHandleInternal).

	* [windows/graphics.c] [objects/dc.c]
	Rectangle() changed to work better with wide pens and PS_NULL.
	Use JoinMiter.

	* [windows/winpos.c]
	Make the whole (non X) window invalid on resize if CS_[VH]REDRAW
 	is set.

	* [windows/nonclient.c]
	AdjustWindowRectEx() should perform calculations even if the
 	window is minimized.

	* [windows/mdi.c]
	Better handling of system button painting. Maximized windows can
 	contain scroll bars. Icons now maximize properly.

	* [windows/defwnd.c] [windows/nonclient.c] [controls/menu.c]
	Improved greying of items in system menu. WM_INITMEMUPOPUP no
 	longer caught in DefWndProc, DEFWND_InitSysMenuPopup moved to
 	menu.c.

Mon Sep 16 21:30:00 1996  Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>

	* [several files]
	Fix missing includes and wrong printing arguments.

	* [controls/listbox.c]
	Don't sort drives in ListBoxDirectory().
	
Sat Sep 14 09:05:47 1996  Petri Tuomola <ptuomola@xs4all.nl>

	* [windows/dialog.c]
	Fixed handling of Shift-TAB in dialogs.

Thu Sep 12 18:31:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [if1632/gdi32.spec]
	Added SelectClipRgn - call win16 version.

	* [if1632/user32.spec]
	Added GetAsyncKeyState, GetMenuItemID and GetMenuStringA.

	* [include/wincon.h]
	Added COORD and SMALL_RECT typedefs, moved CONSOLE_SCREEN_BUFFER_INFO
	out of #if 0 protected portion of file.

	* [loader/pe_image.c]
	PE_InitTEB() - Tidy up, bug fix to stack pointer value (Borland
	programs now work better)

	* [win32/console.c]
	Added stub functions for GetConsoleScreenBufferInfo and 
	GetLargestConsoleWindowSize

	* [win32/findfile.c]
	FindFirstFile32A() - removed erroneous strcpy

	* [windows/keyboard.c]
	GetAsyncKeyState() - bug fix - now returns value as per Microsoft
	specification. NB - I still have doubts about some other functions
	in this file.
diff --git a/misc/clipboard.c b/misc/clipboard.c
index d25775c..03d80ca 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -30,7 +30,7 @@
     WORD	wRefCount;
     WORD	wDataPresent;
     LPSTR	Name;
-    HANDLE	hData;
+    HANDLE16	hData;
     DWORD	BufSize;
     struct tagCLIPFORMAT *PrevFormat;
     struct tagCLIPFORMAT *NextFormat;
@@ -47,42 +47,80 @@
 static BOOL bClipChanged  = FALSE;
 static WORD LastRegFormat = CF_REGFORMATBASE;
 
-static Bool wait_for_selection = False;
-static Bool wineOwnsSelection = False;
+static Bool   selectionWait = False;
+static Bool   selectionAcquired = False;
+static Window selectionWindow = None;
+static Window selectionPrevWindow = None;
 
 static CLIPFORMAT ClipFormats[16]  = {
-    { CF_TEXT, 1, 0, "Text", (HANDLE)NULL, 0, NULL, &ClipFormats[1] },
-    { CF_BITMAP, 1, 0, "Bitmap", (HANDLE)NULL, 0, &ClipFormats[0], &ClipFormats[2] },
-    { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[1], &ClipFormats[3] },
-    { CF_SYLK, 1, 0, "Sylk", (HANDLE)NULL, 0, &ClipFormats[2], &ClipFormats[4] },
-    { CF_DIF, 1, 0, "DIF", (HANDLE)NULL, 0, &ClipFormats[3], &ClipFormats[5] },
-    { CF_TIFF, 1, 0, "TIFF", (HANDLE)NULL, 0, &ClipFormats[4], &ClipFormats[6] },
-    { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE)NULL, 0, &ClipFormats[5], &ClipFormats[7] },
-    { CF_DIB, 1, 0, "DIB", (HANDLE)NULL, 0, &ClipFormats[6], &ClipFormats[8] },
-    { CF_PALETTE, 1, 0, "Palette", (HANDLE)NULL, 0, &ClipFormats[7], &ClipFormats[9] },
-    { CF_PENDATA, 1, 0, "PenData", (HANDLE)NULL, 0, &ClipFormats[8], &ClipFormats[10] },
-    { CF_RIFF, 1, 0, "RIFF", (HANDLE)NULL, 0, &ClipFormats[9], &ClipFormats[11] },
-    { CF_WAVE, 1, 0, "Wave", (HANDLE)NULL, 0, &ClipFormats[10], &ClipFormats[12] },
-    { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE)NULL, 0, &ClipFormats[11], &ClipFormats[13] },
-    { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE)NULL, 0, &ClipFormats[12], &ClipFormats[14] },
-    { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[13], &ClipFormats[15] },
-    { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE)NULL, 0, &ClipFormats[14], NULL }
+    { CF_TEXT, 1, 0, "Text", (HANDLE16)NULL, 0, NULL, &ClipFormats[1] },
+    { CF_BITMAP, 1, 0, "Bitmap", (HANDLE16)NULL, 0, &ClipFormats[0], &ClipFormats[2] },
+    { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE16)NULL, 0, &ClipFormats[1], &ClipFormats[3] },
+    { CF_SYLK, 1, 0, "Sylk", (HANDLE16)NULL, 0, &ClipFormats[2], &ClipFormats[4] },
+    { CF_DIF, 1, 0, "DIF", (HANDLE16)NULL, 0, &ClipFormats[3], &ClipFormats[5] },
+    { CF_TIFF, 1, 0, "TIFF", (HANDLE16)NULL, 0, &ClipFormats[4], &ClipFormats[6] },
+    { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE16)NULL, 0, &ClipFormats[5], &ClipFormats[7] },
+    { CF_DIB, 1, 0, "DIB", (HANDLE16)NULL, 0, &ClipFormats[6], &ClipFormats[8] },
+    { CF_PALETTE, 1, 0, "Palette", (HANDLE16)NULL, 0, &ClipFormats[7], &ClipFormats[9] },
+    { CF_PENDATA, 1, 0, "PenData", (HANDLE16)NULL, 0, &ClipFormats[8], &ClipFormats[10] },
+    { CF_RIFF, 1, 0, "RIFF", (HANDLE16)NULL, 0, &ClipFormats[9], &ClipFormats[11] },
+    { CF_WAVE, 1, 0, "Wave", (HANDLE16)NULL, 0, &ClipFormats[10], &ClipFormats[12] },
+    { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE16)NULL, 0, &ClipFormats[11], &ClipFormats[13] },
+    { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE16)NULL, 0, &ClipFormats[12], &ClipFormats[14] },
+    { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE16)NULL, 0, &ClipFormats[13], &ClipFormats[15] },
+    { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE16)NULL, 0, &ClipFormats[14], NULL }
     };
 
 /**************************************************************************
- *			CLIPBOARD_DisOwn
+ *                      CLIPBOARD_CheckSelection
  */
-void CLIPBOARD_DisOwn(HWND hWnd)
+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_DisOwn
+ *
+ * Called from DestroyWindow().
+ */
+void CLIPBOARD_DisOwn(WND* pWnd)
 {
   LPCLIPFORMAT lpFormat = ClipFormats;
 
-  if( hWnd != hWndClipOwner || !hWndClipOwner ) return;
+  dprintf_clipboard(stddeb,"DisOwn: clipboard owner = %04x, sw = %08x\n", 
+				hWndClipOwner, (unsigned)selectionWindow);
 
-  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)
+    while(lpFormat)
     { 
        if( lpFormat->wDataPresent && !lpFormat->hData )
 	 {
@@ -91,8 +129,12 @@
 	 }
        lpFormat = lpFormat->NextFormat;
     }
+    hWndClipOwner = 0;
+  }
 
-  hWndClipOwner = 0;
+  /* now try to salvage current selection from being destroyed by X */
+
+  CLIPBOARD_CheckSelection(pWnd);
 }
 
 /**************************************************************************
@@ -117,21 +159,31 @@
  */
 BOOL CLIPBOARD_RequestXSelection()
 {
-  HWND hWnd = hWndClipWindow;
+  HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
 
-  if( !hWnd ) hWnd = GetActiveWindow(); 
+  if( !hWnd ) return FALSE;
 
-  wait_for_selection=True;
-  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);
 
-  /* TODO: need time-out for broken clients */
-  while(wait_for_selection) EVENT_WaitXEvent( TRUE );
+  /* wait until SelectionNotify is processed */
 
-  return (BOOL)ClipFormats[0].wDataPresent;
+  selectionWait=True;
+  while(selectionWait) 
+        EVENT_WaitXEvent( TRUE, FALSE );
+
+  /* we treat Unix text as CF_OEMTEXT */
+  dprintf_clipboard(stddeb,"\tgot CF_OEMTEXT = %i\n", 
+		    ClipFormats[CF_OEMTEXT-1].wDataPresent);
+
+  return (BOOL)ClipFormats[CF_OEMTEXT-1].wDataPresent;
 }
 
 /**************************************************************************
@@ -141,11 +193,18 @@
 {
     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);
 }
 
@@ -203,7 +262,7 @@
   
     while(lpFormat) 
       {
-	if ( lpFormat->wDataPresent )
+	if ( lpFormat->wDataPresent || lpFormat->hData )
 	     CLIPBOARD_DeleteRecord( lpFormat );
 
 	lpFormat = lpFormat->NextFormat;
@@ -211,9 +270,15 @@
 
     hWndClipOwner = hWndClipWindow;
 
-    if(wineOwnsSelection){
-        dprintf_clipboard(stddeb,"Losing selection\n");
-	wineOwnsSelection=False;
+    if(selectionAcquired)
+    {
+	selectionAcquired	= False;
+	selectionPrevWindow 	= selectionWindow;
+	selectionWindow 	= None;
+
+	dprintf_clipboard(stddeb, "\tgiving up selection (spw = %08x)\n", 
+				 	(unsigned)selectionPrevWindow);
+
 	XSetSelectionOwner(display,XA_PRIMARY,None,CurrentTime);
     }
     return TRUE;
@@ -240,7 +305,7 @@
     Window       owner;
 
     dprintf_clipboard(stddeb,
-		"SetClipboardDate(%04X, %04x) !\n", wFormat, hData);
+		"SetClipboardData(%04X, %04x) !\n", wFormat, hData);
 
     while(TRUE) 
       {
@@ -249,59 +314,138 @@
 	lpFormat = lpFormat->NextFormat;
       }
 
-    /* Acquire X selection:
-     *
-     * doc says we shouldn't use CurrentTime 
-     * should we become owner of CLIPBOARD as well? 
-     */
+    /* Acquire X selection if text format */
 
-    owner = WIN_GetXWindow(hWndClipWindow);
-
-    XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
-    if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
+    if( !selectionAcquired && 
+	(wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
+    {
+      owner = WIN_GetXWindow(hWndClipWindow);
+      XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
+      if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
       {
-        wineOwnsSelection = True;
-        dprintf_clipboard(stddeb,"Getting selection\n");
-      }
+        selectionAcquired = True;
+	selectionWindow = owner;
 
-    if ( lpFormat->wDataPresent ) 
-         CLIPBOARD_DeleteRecord(lpFormat);
+        dprintf_clipboard(stddeb,"Grabbed X selection, owner=(%08x)\n", 
+						(unsigned) owner);
+      }
+    }
+
+    if ( lpFormat->wDataPresent || lpFormat->hData ) 
+    {
+	CLIPBOARD_DeleteRecord(lpFormat);
+
+	/* delete existing CF_TEXT/CF_OEMTEXT aliases */
+
+	if( wFormat == CF_TEXT && ClipFormats[CF_OEMTEXT-1].hData
+	    && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
+	    CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1]);
+        if( wFormat == CF_OEMTEXT && ClipFormats[CF_TEXT-1].hData
+	    && !ClipFormats[CF_TEXT-1].wDataPresent )
+	    CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1]);
+    }
 
     bClipChanged = TRUE;
-    lpFormat->wDataPresent = TRUE;
-    lpFormat->hData = hData;
+    lpFormat->wDataPresent = 1;
+    lpFormat->hData = hData;          /* 0 is legal, see WM_RENDERFORMAT */
 
     return lpFormat->hData;
 }
 
+/**************************************************************************
+ *                      CLIPBOARD_RenderFormat
+ */
+BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
+{
+ if( lpFormat->wDataPresent && !lpFormat->hData )
+   if( IsWindow(hWndClipOwner) )
+       SendMessage16(hWndClipOwner,WM_RENDERFORMAT,(WPARAM)lpFormat->wFormatID,0L);
+   else
+   {
+       dprintf_clipboard(stddeb,"\thWndClipOwner (%04x) is lost!\n", 
+                                      hWndClipOwner);
+       hWndClipOwner = 0; lpFormat->wDataPresent = 0;
+       return FALSE;
+   }
+ return (lpFormat->hData) ? TRUE : FALSE;
+}
+
+/**************************************************************************
+ *                      CLIPBOARD_RenderText
+ */
+BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
+{
+  UINT		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",
+			   	      lpSource->Name, lpTarget->Name, size);
+
+  lpTarget->hData = GlobalAlloc16(GMEM_ZEROINIT, size); 
+  lpstrT = (LPSTR)GlobalLock16(lpTarget->hData);
+
+  if( lpstrT )
+  {
+    if( lpSource->wFormatID == CF_TEXT )
+	AnsiToOemBuff(lpstrS, lpstrT, size);
+    else
+	OemToAnsiBuff(lpstrS, lpstrT, size);
+    dprintf_clipboard(stddeb,"\tgot %s\n", lpstrT);
+    return TRUE;
+  }
+
+  lpTarget->hData = 0;
+  return FALSE;
+}
 
 /**************************************************************************
  *			GetClipboardData	[USER.142]
  */
 HANDLE GetClipboardData(WORD wFormat)
 {
-    LPCLIPFORMAT lpFormat = ClipFormats; 
-    dprintf_clipboard(stddeb,"GetClipboardData(%04X)\n", wFormat);
+    LPCLIPFORMAT lpRender = ClipFormats; 
+    LPCLIPFORMAT lpUpdate = NULL;
 
     if (!hWndClipWindow) return 0;
 
-    /*  if(wFormat == CF_TEXT && !wineOwnsSelection)
-        CLIPBOARD_RequestXSelection(); 
-     */
+    dprintf_clipboard(stddeb,"GetClipboardData(%04X)\n", wFormat);
 
-    while(TRUE) {
-	if (lpFormat == NULL) return 0;
-	if (lpFormat->wFormatID == wFormat) break;
-	lpFormat = lpFormat->NextFormat;
-	}
+    if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent 
+			   &&  lpRender[CF_OEMTEXT-1].wDataPresent )
+    {
+	lpRender = &ClipFormats[CF_OEMTEXT-1];
+	lpUpdate = &ClipFormats[CF_TEXT-1];
 
-    if( lpFormat->wDataPresent && !lpFormat->hData )
-      if( IsWindow(hWndClipOwner) )
-	  SendMessage16(hWndClipOwner,WM_RENDERFORMAT,(WPARAM)lpFormat->wFormatID,0L);
-      else
-	  dprintf_clipboard(stddeb,"\thWndClipOwner is lost\n");
-      
-    return lpFormat->hData;
+	dprintf_clipboard(stddeb,"\tOEMTEXT -> TEXT\n");
+    }
+    else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
+				   &&  lpRender[CF_TEXT-1].wDataPresent )
+    {
+        lpRender = &ClipFormats[CF_TEXT-1];
+	lpUpdate = &ClipFormats[CF_OEMTEXT-1];
+	
+	dprintf_clipboard(stddeb,"\tTEXT -> OEMTEXT\n");
+    }
+    else
+    {
+      while(TRUE) 
+      {
+	if (lpRender == NULL) return 0;
+	if (lpRender->wFormatID == wFormat) break;
+	lpRender = lpRender->NextFormat;
+      }
+      lpUpdate = lpRender;
+    }
+   
+    if( !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);
+    return lpUpdate->hData;
 }
 
 
@@ -315,6 +459,11 @@
 
     dprintf_clipboard(stddeb,"CountClipboardFormats()\n");
 
+    if( !selectionAcquired ) CLIPBOARD_RequestXSelection();
+
+    FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
+		       lpFormat[CF_OEMTEXT-1].wDataPresent); 
+
     while(TRUE) {
 	if (lpFormat == NULL) break;
 	if (lpFormat->wDataPresent) 
@@ -334,21 +483,22 @@
 /**************************************************************************
  *			EnumClipboardFormats	[USER.144]
  */
-UINT EnumClipboardFormats(UINT wFormat)
+UINT16 EnumClipboardFormats(UINT16 wFormat)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
 
     dprintf_clipboard(stddeb,"EnumClipboardFormats(%04X)\n", wFormat);
 
-    if( (!wFormat || wFormat == CF_TEXT) && !wineOwnsSelection)
-        CLIPBOARD_RequestXSelection();
+    if( !hWndClipWindow ) return 0;
 
-    if (wFormat == 0) {
-	if (lpFormat->wDataPresent) 
+    if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) 
+	 && !selectionAcquired) CLIPBOARD_RequestXSelection();
+
+    if (wFormat == 0)
+	if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent) 
 	    return lpFormat->wFormatID;
 	else 
-	    wFormat = lpFormat->wFormatID;
-	}
+	    wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
 
     /* walk up to the specified format record */
 
@@ -363,12 +513,12 @@
     lpFormat = lpFormat->NextFormat;
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
-	if (lpFormat->wDataPresent ) break;
+	if (lpFormat->wDataPresent ||
+	       (lpFormat->wFormatID == CF_OEMTEXT &&
+		ClipFormats[CF_TEXT-1].wDataPresent)) break;
 	lpFormat = lpFormat->NextFormat;
 	}
 
-    dprintf_clipboard(stddeb, "\t got not empty - Id=%04X hData=%04x !\n",
-				lpFormat->wFormatID, lpFormat->hData);
     return lpFormat->wFormatID;
 }
 
@@ -500,8 +650,8 @@
 {
     dprintf_clipboard(stddeb,"IsClipboardFormatAvailable(%04X) !\n", wFormat);
 
-    if(wFormat == CF_TEXT && !wineOwnsSelection)
-	CLIPBOARD_RequestXSelection();
+    if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) &&
+        !selectionAcquired ) CLIPBOARD_RequestXSelection();
 
     return CLIPBOARD_IsPresent(wFormat);
 }
@@ -533,72 +683,112 @@
 /**************************************************************************
  *			CLIPBOARD_ReadSelection
  *
- *	The current selection owner has set prop at our window w
- *	Transfer the property contents into the Clipboard
+ * Called from the SelectionNotify event handler. 
  */
 void CLIPBOARD_ReadSelection(Window w,Atom prop)
 {
-    HANDLE hText;
+    HANDLE16 	 hText = 0;
     LPCLIPFORMAT lpFormat = ClipFormats; 
-    if(prop==None)
-        hText=0;
-    else
-      {
-	Atom atype=None;
-	int aformat;
-	unsigned long nitems,remain;
-	unsigned char *val=NULL;
 
-        dprintf_clipboard(stddeb,"Received prop %s\n",XGetAtomName(display,prop));
+    dprintf_clipboard(stddeb,"ReadSelection callback\n");
+
+    if(prop != None)
+    {
+	Atom		atype=AnyPropertyType;
+	int		aformat;
+	unsigned long 	nitems,remain;
+	unsigned char*	val=NULL;
+
+        dprintf_clipboard(stddeb,"\tgot property %s\n",XGetAtomName(display,prop));
 
         /* TODO: Properties longer than 64K */
 
 	if(XGetWindowProperty(display,w,prop,0,0x3FFF,True,XA_STRING,
-	    &atype, &aformat, &nitems, &remain, &val)!=Success)
-		fprintf(stderr,"couldn't read property\n");
+	    &atype, &aformat, &nitems, &remain, &val) != Success)
+	    dprintf_clipboard(stddeb,"\tcouldn't read property\n");
+	else
+	{
+           dprintf_clipboard(stddeb,"\tType %s,Format %d,nitems %ld,value %s\n",
+		             XGetAtomName(display,atype),aformat,nitems,val);
 
-        dprintf_clipboard(stddeb,"Type %s,Format %d,nitems %ld,value %s\n",
-		XGetAtomName(display,atype),aformat,nitems,val);
+	   if(atype == XA_STRING && aformat == 8)
+	   {
+	      int 	i,inlcount = 0;
+	      char*	lpstr;
 
-	if(atype!=XA_STRING || aformat!=8){
-	    fprintf(stderr,"Property not set\n");
-	    hText=0;
-	} else {
-	    dprintf_clipboard(stddeb,"Selection is %s\n",val);
-	    hText=GlobalAlloc16(GMEM_MOVEABLE, nitems+1);
-	    memcpy(GlobalLock16(hText),val,nitems+1);
-	    GlobalUnlock16(hText);
+	      dprintf_clipboard(stddeb,"\tselection is '%s'\n",val);
+
+	      for(i=0; i <= nitems; i++)
+		  if( val[i] == '\n' ) inlcount++;
+
+	      if( nitems )
+	      {
+	        hText=GlobalAlloc16(GMEM_MOVEABLE, nitems + inlcount + 1);
+	        if( (lpstr = (char*)GlobalLock16(hText)) )
+	          for(i=0,inlcount=0; i <= nitems; i++)
+	          {
+	  	     if( val[i] == '\n' ) lpstr[inlcount++]='\r';
+		     lpstr[inlcount++]=val[i];
+		  }
+	        else hText = 0;
+	      }
+	   }
+	   XFree(val);
 	}
-	XFree(val);
-      }
+   }
 
-    while(TRUE) {
-	if (lpFormat == NULL) return;
-	if (lpFormat->wFormatID == CF_TEXT) break;
-	lpFormat = lpFormat->NextFormat;
-	}
+   /* delete previous CF_TEXT and CF_OEMTEXT data */
 
-    if (lpFormat->wDataPresent) 
-       CLIPBOARD_DeleteRecord(lpFormat);
+   if( hText )
+   {
+     lpFormat = &ClipFormats[CF_TEXT-1];
+     if (lpFormat->wDataPresent || lpFormat->hData) 
+         CLIPBOARD_DeleteRecord(lpFormat);
+     lpFormat = &ClipFormats[CF_OEMTEXT-1];
+     if (lpFormat->wDataPresent || lpFormat->hData) 
+         CLIPBOARD_DeleteRecord(lpFormat);
 
-    wait_for_selection=False;
+     lpFormat->wDataPresent = 1;
+     lpFormat->hData = hText;
+   }
 
-    lpFormat->wDataPresent = TRUE;
-    lpFormat->hData = hText;
-    dprintf_clipboard(stddeb,"Received selection\n");
+   selectionWait=False;
 }
 
 /**************************************************************************
  *			CLIPBOARD_ReleaseSelection
  *
- *	Wine lost the primary selection.
- *	Empty the clipboard, but don't set the current owner to None.
- *	Make sure current get/put attempts fail.
+ * Wine might have lost XA_PRIMARY selection because of
+ * EmptyClipboard() or other client. 
  */
-void CLIPBOARD_ReleaseSelection(HWND hwnd)
+void CLIPBOARD_ReleaseSelection(Window w, HWND hwnd)
 {
-    wineOwnsSelection=False;
-    OpenClipboard(hwnd);
-    EmptyClipboard();
-    CloseClipboard();
+  /* 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", 
+	  (unsigned)w, (unsigned)selectionWindow, (unsigned)selectionPrevWindow );
+
+  if( selectionAcquired )
+    if( w == selectionWindow || selectionPrevWindow == None)
+    {
+      /* alright, we really lost it */
+
+      selectionAcquired = False;
+      selectionWindow = None; 
+
+      /* 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);
+    }
+
+  selectionPrevWindow = None;
 }
+
diff --git a/misc/comm.c b/misc/comm.c
index 8fda4ae..613957b 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1576,7 +1576,7 @@
  *	GetCommTimeouts		(KERNEL32.160)
  */
 BOOL32 GetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
-	dprintf_comm(stddeb,"GetCommTimeouts(%lx,%p), empty stub.\n",
+	dprintf_comm(stddeb,"GetCommTimeouts(%x,%p), empty stub.\n",
 		fd,lptimeouts
 	);
 	return TRUE;
@@ -1586,7 +1586,7 @@
  *	SetCommTimeouts		(KERNEL32.453)
  */
 BOOL32 SetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
-	dprintf_comm(stddeb,"SetCommTimeouts(%lx,%p), empty stub.\n",
+	dprintf_comm(stddeb,"SetCommTimeouts(%x,%p), empty stub.\n",
 		fd,lptimeouts
 	);
 	return TRUE;
diff --git a/misc/commdlg.c b/misc/commdlg.c
index e356a82..cb24335 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -1475,12 +1475,12 @@
 static void CC_PaintSelectedColor(HWND hDlg,COLORREF cr)
 {
  RECT16 rect;
- HDC  hdc;
+ HDC32  hdc;
  HBRUSH hBrush;
  HWND hwnd=GetDlgItem(hDlg,0x2c5);
  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
  {
-  hdc=GetDC(hwnd);
+  hdc=GetDC32(hwnd);
   GetClientRect16 (hwnd, &rect) ;
   hBrush = CreateSolidBrush(cr);
   if (hBrush)
@@ -1496,7 +1496,7 @@
     DeleteObject (SelectObject (hdc, hBrush)) ;
    }
   }
-  ReleaseDC(hwnd,hdc);
+  ReleaseDC32(hwnd,hdc);
  }
 }
 
@@ -1505,7 +1505,7 @@
  */
 static void CC_PaintTriangle(HWND hDlg,int y)
 {
- HDC hDC;
+ HDC32 hDC;
  long temp;
  int w=GetDialogBaseUnits();
  POINT16 points[3];
@@ -1519,7 +1519,7 @@
  {
    GetClientRect16(hwnd,&rect);
    height=rect.bottom;
-   hDC=GetDC(hDlg);
+   hDC=GetDC32(hDlg);
 
    points[0].y=rect.top;
    points[0].x=rect.right;           /*  |  /|  */
@@ -1540,7 +1540,7 @@
    lpp->old3angle.top   =points[2].y-1;
    lpp->old3angle.bottom=points[1].y+1;
    Polygon16(hDC,points,3);
-   ReleaseDC(hDlg,hDC);
+   ReleaseDC32(hDlg,hDC);
  }
 }
 
@@ -1550,7 +1550,7 @@
  */
 static void CC_PaintCross(HWND hDlg,int x,int y)
 {
- HDC hDC;
+ HDC32 hDC;
  int w=GetDialogBaseUnits();
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
@@ -1561,7 +1561,7 @@
  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
  {
    GetClientRect16(hwnd,&rect);
-   hDC=GetDC(hwnd);
+   hDC=GetDC32(hwnd);
    SelectClipRgn(hDC,CreateRectRgnIndirect16(&rect));   
    hPen=CreatePen(PS_SOLID,2,0);
    hPen=SelectObject(hDC,hPen);
@@ -1582,7 +1582,7 @@
    MoveTo(hDC,point.x,point.y-w); 
    LineTo(hDC,point.x,point.y+w);
    DeleteObject(SelectObject(hDC,hPen));
-   ReleaseDC(hwnd,hDC);
+   ReleaseDC32(hwnd,hDC);
  }
 }
 
@@ -1600,12 +1600,12 @@
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER);  
  HBRUSH hbrush;
- HDC hdc ;
+ HDC32 hdc ;
  RECT16 rect,client;
  HCURSOR16 hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
 
  GetClientRect16(hwnd,&client);
- hdc=GetDC(hwnd);
+ hdc=GetDC32(hwnd);
  lpp->hdcMem = CreateCompatibleDC(hdc);
  lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
  SelectObject(lpp->hdcMem,lpp->hbmMem);
@@ -1631,7 +1631,7 @@
   }
   rect.left=rect.right;
  }
- ReleaseDC(hwnd,hdc);
+ ReleaseDC32(hwnd,hdc);
  SetCursor(hcursor);
 }
 
@@ -1642,20 +1642,20 @@
 {
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
- HDC  hDC;
+ HDC32  hDC;
  RECT16 rect;
  if (IsWindowVisible(hwnd))   /* if full size */
  {
   if (!lpp->hdcMem)
    CC_PrepareColorGraph(hDlg);   /* should not be necessary */
 
-  hDC=GetDC(hwnd);
+  hDC=GetDC32(hwnd);
   GetClientRect16(hwnd,&rect);
   if (lpp->hdcMem)
     BitBlt(hDC,0,0,rect.right,rect.bottom,lpp->hdcMem,0,0,SRCCOPY);
   else
     fprintf(stderr,"choose color: hdcMem is not defined\n");
-  ReleaseDC(hwnd,hDC);
+  ReleaseDC32(hwnd,hDC);
  }
 }
 /***********************************************************************
@@ -1667,11 +1667,11 @@
  RECT16 rect,client;
  int lum,ldif,ydif,r,g,b;
  HBRUSH hbrush;
- HDC hDC;
+ HDC32 hDC;
 
  if (IsWindowVisible(hwnd))
  {
-  hDC=GetDC(hwnd);
+  hDC=GetDC32(hwnd);
   GetClientRect16(hwnd,&client);
   rect=client;
 
@@ -1690,7 +1690,7 @@
   }
   GetClientRect16(hwnd,&rect);
   FrameRect16(hDC,&rect,GetStockObject(BLACK_BRUSH));
-  ReleaseDC(hwnd,hDC);
+  ReleaseDC32(hwnd,hDC);
  }
 }
 
@@ -1775,7 +1775,7 @@
 {
  HWND hwnd=GetDlgItem(hDlg,0x2d0);
  RECT16 rect;
- HDC  hdc;
+ HDC32  hdc;
  HBRUSH hBrush;
  int dx,dy,i,j,k;
 
@@ -1784,7 +1784,7 @@
  dy=rect.bottom/rows;
  k=rect.left;
 
- hdc=GetDC(hwnd);
+ hdc=GetDC32(hwnd);
  GetClientRect16 (hwnd, &rect) ;
 
  for (j=0;j<rows;j++)
@@ -1804,7 +1804,7 @@
   rect.top=rect.top+dy;
   rect.left=k;
  }
- ReleaseDC(hwnd,hdc);
+ ReleaseDC32(hwnd,hdc);
  /* FIXME: draw_a_focus_rect */
 }
 /***********************************************************************
@@ -1814,7 +1814,7 @@
 {
  HWND hwnd=GetDlgItem(hDlg,0x2d1);
  RECT16 rect;
- HDC  hdc;
+ HDC32  hdc;
  HBRUSH hBrush;
  int dx,dy,i,j,k;
 
@@ -1824,7 +1824,7 @@
  dy=rect.bottom/rows;
  k=rect.left;
 
- hdc=GetDC(hwnd);
+ hdc=GetDC32(hwnd);
  if (hdc)
  {
   for (j=0;j<rows;j++)
@@ -1844,7 +1844,7 @@
    rect.top=rect.top+dy;
    rect.left=k;
   }
-  ReleaseDC(hwnd,hdc);
+  ReleaseDC32(hwnd,hdc);
  }
  /* FIXME: draw_a_focus_rect */
 }
@@ -1940,7 +1940,7 @@
 {
     int r,g,b,i,xx;
     UINT cokmsg;
-    HDC hdc;
+    HDC32 hdc;
     COLORREF *cr;
     struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
     dprintf_commdlg(stddeb,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
@@ -2018,9 +2018,9 @@
 	       break;
 
           case 0x2c9:              /* resulting color */
-	       hdc=GetDC(hDlg);
+	       hdc=GetDC32(hDlg);
 	       lpp->lpcc->rgbResult=GetNearestColor(hdc,lpp->lpcc->rgbResult);
-	       ReleaseDC(hDlg,hdc);
+	       ReleaseDC32(hDlg,hdc);
 	       CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
 	       CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
 	       r=GetRValue(lpp->lpcc->rgbResult);
@@ -2402,10 +2402,10 @@
 
   if (!SendMessage16(hcmb2,CB_GETCOUNT,0,0))
   {
-       HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+       HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC32(hDlg);
        i=SetFontStylesToCombo2(hcmb2,hdc,lplf,lptm);
        if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
-         ReleaseDC(hDlg,hdc);
+         ReleaseDC32(hDlg,hdc);
        if (i)
         return 0;  
   }
@@ -2418,7 +2418,7 @@
  */
 LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
-  HDC hdc;
+  HDC32 hdc;
   int i,j,res,init=0;
   long l;
   LPLOGFONT16 lpxx;
@@ -2466,7 +2466,7 @@
     ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
     ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
   }
-  hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+  hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC32(hDlg);
   if (hdc)
   {
     if (!EnumFontFamilies (hdc, NULL,FontFamilyEnumProc,(LPARAM)GetDlgItem(hDlg,cmb1)))
@@ -2520,7 +2520,7 @@
   }
 
   if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
-    ReleaseDC(hDlg,hdc);
+    ReleaseDC32(hDlg,hdc);
   res=TRUE;
   if (CFn_HookCallChk(lpcf))
     res=CallWindowProc16(lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
@@ -2670,7 +2670,7 @@
   {
 	case cmb1:if (HIWORD(lParam)==CBN_SELCHANGE)
 		  {
-		    hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+		    hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC32(hDlg);
 		    if (hdc)
 		    {
                       SendDlgItemMessage16(hDlg,cmb2,CB_RESETCONTENT,0,0); 
@@ -2689,7 +2689,7 @@
                         SEGPTR_FREE(str);
 		      }
 		      if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
- 		        ReleaseDC(hDlg,hdc);
+ 		        ReleaseDC32(hDlg,hdc);
  		    }
  		    else
                     {
diff --git a/misc/lstr.c b/misc/lstr.c
index 318e3da..33b65d8 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -697,6 +697,7 @@
 				char	*fmtstr,*sprintfbuf,*x;
 				DWORD	*argliststart;
 
+				fmtstr = NULL;
 				f++;
 				if (!*f) {
 					ADD_TO_T('%');
@@ -722,7 +723,7 @@
 						f++;
 						if (NULL!=(x=strchr(f,'!'))) {
 							*x='\0';
-							fmtstr=xmalloc(strlen(f)+2);
+							fmtstr=(char*)xmalloc(strlen(f)+2);
 							sprintf(fmtstr,"%%%s",f);
 							f=x+1;
 						}
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 717b586..1c47990 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -75,7 +75,7 @@
 		*b		= lzs->get[lzs->getcur++];
 		return		1;
 	} else {
-		int ret = FILE_Read(lzs->realfd,lzs->get,GETLEN);
+		int ret = _lread32(lzs->realfd,lzs->get,GETLEN);
 		if (ret==HFILE_ERROR)
 			return HFILE_ERROR;
 		if (ret==0)
@@ -102,7 +102,7 @@
 	/* We can't directly read the lzfileheader struct due to 
 	 * structure element alignment
 	 */
-	if (FILE_Read(fd,buf,14)<14)
+	if (_lread32(fd,buf,14)<14)
 		return 0;
 	memcpy(head->magic,buf,8);
 	memcpy(&(head->compressiontype),buf+8,1);
@@ -306,7 +306,7 @@
 		if (lzstates[i].lzfd==fd)
 			break;
 	if (i==nroflzstates)
-		return FILE_Read(fd,buf,toread);
+		return _lread32(fd,buf,toread);
 	lzs=lzstates+i;
 
 /* The decompressor itself is in a define, cause we need it twice
@@ -447,7 +447,7 @@
 
 	/* not compressed? just copy */
 	if (i==nroflzstates)
-		xread=FILE_Read;
+		xread=(INT32(*)(HFILE,LPVOID,UINT32))_lread32;
 	else
 		xread=LZRead32;
 	len=0;
diff --git a/misc/main.c b/misc/main.c
index 3adf5fb..ae853fc 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -9,13 +9,14 @@
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
-#include <locale.h>
+/* #include <locale.h> */
 #ifdef MALLOC_DEBUGGING
 #include <malloc.h>
 #endif
 #include <X11/Xlib.h>
 #include <X11/Xresource.h>
 #include <X11/Xutil.h>
+#include <X11/Xlocale.h>
 #include <X11/cursorfont.h>
 #include "message.h"
 #include "module.h"
@@ -75,6 +76,8 @@
 
 #define WINE_CLASS    "Wine"    /* Class name for resources */
 
+#define WINE_APP_DEFAULTS "/usr/lib/X11/app-defaults/Wine"
+
 typedef struct tagENVENTRY {
   LPSTR	       	        Name;
   LPSTR	       	        Value;
@@ -371,14 +374,21 @@
  */
 static void MAIN_ParseOptions( int *argc, char *argv[] )
 {
-    char *display_name;
+    char *display_name = NULL;
     XrmValue value;
-    XrmDatabase db = XrmGetFileDatabase("/usr/lib/X11/app-defaults/Wine");
+    XrmDatabase db = XrmGetFileDatabase(WINE_APP_DEFAULTS);
+    int i;
+    char *xrm_string;
 
-      /* Parse command line */
     Options.programName = MAIN_GetProgramName( *argc, argv );
-    XrmParseCommand( &db, optionsTable, NB_OPTIONS,
-		     Options.programName, argc, argv );
+
+      /* Get display name from command line */
+    for (i = 1; i < *argc - 1; i++)
+        if (!strcmp( argv[i], "-display" ))
+	{
+	    display_name = argv[i+1];
+	    break;
+        }
 
 #ifdef WINELIB
     /* Need to assemble command line and pass it to WinMain */
@@ -389,8 +399,8 @@
 
       /* Open display */
 
-    if (MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
-    else display_name = NULL;
+    if (display_name == NULL &&
+	MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
 
     if (!(display = XOpenDisplay( display_name )))
     {
@@ -399,6 +409,17 @@
 	exit(1);
     }
 
+      /* Merge file and screen databases */
+    if ((xrm_string = XResourceManagerString( display )) != NULL)
+    {
+        XrmDatabase display_db = XrmGetStringDatabase( xrm_string );
+        XrmMergeDatabases( display_db, &db );
+    }
+
+      /* Parse command line */
+    XrmParseCommand( &db, optionsTable, NB_OPTIONS,
+		     Options.programName, argc, argv );
+
       /* Get all options */
     if (MAIN_GetResource( db, ".iconic", &value ))
 	Options.cmdShow = SW_SHOWMINIMIZED;
@@ -1130,7 +1151,7 @@
 			break;
 
 		case SPI_SETDESKWALLPAPER:
-			return (SetDeskWallPaper((LPSTR) lpvParam));
+			return (SetDeskWallPaper32((LPSTR) lpvParam));
 			break;
 
 		case SPI_SETDESKPATTERN:
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 5690ec9..66a7a74 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -1229,3 +1229,8 @@
 	fprintf(stdnimp,"SetLocaleInfoA(%ld,%ld,%s)\n",lcid,lctype,data);
 	return TRUE;
 }
+
+BOOL IsValidLocale(DWORD lcid,DWORD flags) {
+	fprintf(stdnimp,"IsValidLocale(%ld,%ld)\n",lcid,flags);
+	return TRUE;
+}
diff --git a/misc/registry.c b/misc/registry.c
index ac00c2c..a0606ff 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -1106,19 +1106,19 @@
 	if (hfd==HFILE_ERROR)
 		return;
 	magic[4]=0;
-	if (4!=FILE_Read(hfd,magic,4))
+	if (4!=_lread32(hfd,magic,4))
 		return;
 	if (strcmp(magic,"CREG")) {
 		fprintf(stddeb,"%s is not a w95 registry.\n",fn);
 		return;
 	}
-	if (4!=FILE_Read(hfd,&version,4))
+	if (4!=_lread32(hfd,&version,4))
 		return;
-	if (4!=FILE_Read(hfd,&rgdbsection,4))
+	if (4!=_lread32(hfd,&rgdbsection,4))
 		return;
 	if (-1==_llseek(hfd,0x20,SEEK_SET))
 		return;
-	if (4!=FILE_Read(hfd,magic,4))
+	if (4!=_lread32(hfd,magic,4))
 		return;
 	if (strcmp(magic,"RGKN")) {
 		dprintf_reg(stddeb,"second IFF header not RGKN, but %s\n",magic);
@@ -1133,7 +1133,7 @@
 
 	nrofdkes = (end-where)/sizeof(struct dke)+100;
 	data = (char*)xmalloc(end-where);
-	if ((end-where)!=FILE_Read(hfd,data,end-where))
+	if ((end-where)!=_lread32(hfd,data,end-where))
 		return;
 	curdata = data;
 
@@ -1215,7 +1215,7 @@
 	if (-1==_llseek(hfd,rgdbsection,SEEK_SET))
 		return;
 	data = (char*)xmalloc(end-rgdbsection);
-	if ((end-rgdbsection)!=FILE_Read(hfd,data,end-rgdbsection))
+	if ((end-rgdbsection)!=_lread32(hfd,data,end-rgdbsection))
 		return;
 	_lclose(hfd);
 	curdata = data;
@@ -1554,13 +1554,14 @@
 	if (!lpszSubKey || !*lpszSubKey) {
 		add_handle(++currenthandle,lpNextKey,samDesired);
 		*retkey=currenthandle;
+		lpNextKey->flags|=REG_OPTION_TAINTED;
 		return SHELL_ERROR_SUCCESS;
 	}
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i 	= 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
 	lpxkey	= lpNextKey;
-	while (i<wpc) {
+	while (wps[i]) {
 		lpxkey=lpNextKey->nextsub;
 		while (lpxkey) {
 			if (!lstrcmp32W(wps[i],lpxkey->keyname))
@@ -1574,13 +1575,15 @@
 	}
 	if (lpxkey) {
 		add_handle(++currenthandle,lpxkey,samDesired);
+		lpxkey->flags  |= REG_OPTION_TAINTED;
 		*retkey		= currenthandle;
-		*lpDispos	= REG_OPENED_EXISTING_KEY;
+		if (lpDispos)
+			*lpDispos	= REG_OPENED_EXISTING_KEY;
 		FREE_KEY_PATH;
 		return	SHELL_ERROR_SUCCESS;
 	}
 	/* good. now the hard part */
-	while (i<wpc) {
+	while (wps[i]) {
 		lplpPrevKey	= &(lpNextKey->nextsub);
 		lpxkey		= *lplpPrevKey;
 		while (lpxkey) {
@@ -1598,6 +1601,7 @@
 		(*lplpPrevKey)->nextsub	= NULL;
 		(*lplpPrevKey)->values	= NULL;
 		(*lplpPrevKey)->nrofvalues = 0;
+		(*lplpPrevKey)->flags 	= REG_OPTION_TAINTED;
 		if (lpszClass)
 			(*lplpPrevKey)->class = strdupW(lpszClass);
 		else
@@ -1608,14 +1612,14 @@
 	add_handle(++currenthandle,lpNextKey,samDesired);
 
 	/*FIXME: flag handling correct? */
-	lpNextKey->flags= fdwOptions;
+	lpNextKey->flags= fdwOptions |REG_OPTION_TAINTED;
 	if (lpszClass)
 		lpNextKey->class = strdupW(lpszClass);
 	else
 		lpNextKey->class = NULL;
-	lpNextKey->flags|=REG_OPTION_TAINTED;
 	*retkey		= currenthandle;
-	*lpDispos	= REG_CREATED_NEW_KEY;
+	if (lpDispos)
+		*lpDispos	= REG_CREATED_NEW_KEY;
 	FREE_KEY_PATH;
 	return SHELL_ERROR_SUCCESS;
 }
diff --git a/misc/shell.c b/misc/shell.c
index dd7aa3b..4e80173 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -414,11 +414,11 @@
   int		size;
   
   _llseek( hFile, 0, SEEK_SET );
-  if ((FILE_Read(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+  if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
       (mz_header.mz_magic != MZ_SIGNATURE)) return (BYTE*)-1;
 
   _llseek( hFile, mz_header.ne_offset, SEEK_SET );
-  if (FILE_Read( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
+  if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
       return NULL;
 
   if (ne_header.ne_magic == PE_SIGNATURE) 
@@ -436,7 +436,7 @@
       if( !pTypeInfo ) return NULL;
 
       _llseek(hFile, mz_header.ne_offset+ne_header.resource_tab_offset, SEEK_SET);
-      if( FILE_Read( hFile, (char*)pTypeInfo, size) != size )
+      if( _lread32( hFile, (char*)pTypeInfo, size) != size )
 	{ free(pTypeInfo); return NULL; }
       return pTypeInfo;
     }
@@ -456,7 +456,7 @@
  if( (ptr = (BYTE*)GlobalLock16( handle )) )
    {
     _llseek( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET);
-     FILE_Read( hFile, (char*)ptr, pNInfo->length << sizeShift);
+     _lread32( hFile, (char*)ptr, pNInfo->length << sizeShift);
      return handle;
    }
  return (HANDLE)0;
@@ -473,7 +473,7 @@
  if( (ptr = (BYTE*)GlobalLock16( handle )) )
    {
     _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET);
-     FILE_Read( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
+     _lread32( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
      return handle;
    }
  return (HANDLE)0;
@@ -491,7 +491,7 @@
   int		i;
  
   _llseek( hFile, 0, SEEK_SET );
-  if( FILE_Read(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0;
+  if( _lread32(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0;
 
   /* check .ICO header 
    *
@@ -504,7 +504,7 @@
 
   lpiID = (LPicoICONDIR)xmalloc(i);
 
-  if( FILE_Read(hFile,(char*)lpiID->idEntries,i) == i )
+  if( _lread32(hFile,(char*)lpiID->idEntries,i) == i )
   {  
      HANDLE	handle = DirectResAlloc( hInst, 0x10,
 					 id[2]*sizeof(ICONDIRENTRY) + sizeof(id) );
@@ -820,3 +820,16 @@
 	dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");
         return 0;
 }
+
+/*************************************************************************
+ *				SHGetFileInfoA		[SHELL32.54]
+ */
+DWORD
+SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,SHFILEINFO32A *psfi,
+	UINT32 sizeofpsfi,UINT32 flags
+) {
+	fprintf(stdnimp,"SHGetFileInfo32A(%s,0x%08lx,%p,%ld,0x%08lx)\n",
+		path,dwFileAttributes,psfi,sizeofpsfi,flags
+	);
+	return TRUE;
+}
diff --git a/misc/spy.c b/misc/spy.c
index 1a1b325..3cdf52d 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -148,8 +148,17 @@
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x00E0 - Win32 Scrollbars */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "SBM_SETPOS32",             /* 0x00e0 */
+    "SBM_GETPOS32",             /* 0x00e1 */
+    "SBM_SETRANGE32",           /* 0x00e2 */
+    "SBM_GETRANGE32",           /* 0x00e3 */
+    "SBM_ENABLE_ARROWS32",      /* 0x00e4 */
+    NULL,
+    "SBM_SETRANGEREDRAW32",     /* 0x00e6 */
+    NULL, NULL,
+    "SBM_SETSCROLLINFO32",      /* 0x00e9 */
+    "SBM_GETSCROLLINFO32",      /* 0x00ea */
+    NULL, NULL, NULL, NULL, NULL,
 
     /* 0x00F0 - Win32 Buttons */
     "BM_GETCHECK32",            /* 0x00f0 */
diff --git a/misc/user.c b/misc/user.c
index 3885e09..5763a46 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -16,11 +16,13 @@
 #include "hook.h"
 #include "debug.h"
 #include "toolhelp.h"
+#include "message.h"
 
 WORD USER_HeapSel = 0;
 
 
 extern HTASK	TASK_GetNextTask(HTASK);
+extern BOOL32   MENU_SwitchTPWndTo(HTASK);
 
 /***********************************************************************
  *           GetFreeSystemResources   (USER.284)
@@ -117,10 +119,13 @@
 
     WND* desktop = WIN_GetDesktop();
 
-    /* Patch desktop window queue */
+    /* Patch desktop window */
     if( desktop->hmemTaskQ == hQueue )
 	desktop->hmemTaskQ = GetTaskQueue(TASK_GetNextTask(hTask));
 
+    /* Patch resident popup menu window */
+    MENU_SwitchTPWndTo(0);
+
     /* Nuke timers */
 
     TIMER_RemoveQueueTimers( hQueue );
diff --git a/misc/winsocket.c b/misc/winsocket.c
index ce3c916..5cdae3d 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -1687,7 +1687,7 @@
 
 VOID
 WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,LPDWORD x5,LPDWORD x6) {
-	fprintf(stdnimp,"WsControl(%lx,%lx,%lx,%lx,%lx,%lx)\n",
+	fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p)\n",
 		x1,x2,x3,x4,x5,x6
 	);
 	fprintf(stdnimp,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",