Release 980614

Sun Jun 15 10:30:35 1998  Andreas Mohr <100.30936@germany.net>

	* [files/dos_fs.c] [files/file.c] [if1632/wprocs.spec]
	  [misc/aspi.c]
	Added support for scanners that need Adaptec's ASPI2DOS.

	* [graphics/env.c] [misc/printerdrv.c] [graphics/win16drv/init.c]
	  [if1632/gdi.spec] [include/gdi.h]
	Enhanced printer support (especially Win95):
	Drv[GS]etPrinterData, [GS]etEnvironment; added AbortProc handling.

	* [misc/tapi32.c] [relay32/tapi32.spec]
	Added some stubs.

	* [configure.in] [graphics/fontengine.c] [include/windows.h]
	  [misc/comm.c] [misc/w32skrnl.c] [misc/win32s16.c]
	Made Wine compile on HP-UX (just for fun ;)

	* [controls/menu.c] [include/windows.h]
	Complete rewrite of EnableMenuItem32.
	Free Agent 32 still doesn't work :(

	* [misc/version.c] [if1632/kernel.spec] [include/winbase.h]
	Implemented GetVersionEx16.

	* [misc/network.c] [if1632/user.spec]
	Fixed arguments of WNetGetPropertyText.

	* [misc/version.c] [relay32/comctl32.spec] [relay32/oleaut32.spec]
	Implemented COMCTL32_DllGetVersion, OaBuildVersion.

	* [win32/file.c]
	Fixed UNC handling of CreateFile32.

Sat Jun 13 22:35:12 1998  Douglas Ridgway  <ridgway@winehq.com>

	* [Makefile.in] [Make.rules.in]
	Added pattern for CVS merge files to 'make clean'

	* [ole/olecli.c] [windows/scroll.c] [windows/grahics.c]
	Add some DC handle unlocking. (When hdc's are always unlocked,
	they can be made moveable.)

	* [documentation/wine.texinfo] 
	Started a Wine Design chapter with discussion of 
	graphics driver model.

Sat Jun 13 11:19:25 1998  David Luyer <luyer@ucs.uwa.edu.au>

	* [misc/main.c] [relay32/relay386.c]
	Added new option -debugmsg +relay=.... or -debugmsg -relay=...

Fri Jun 12 22:56:09 1998  Marcus Meissner <marcus@jet.franken.de>

	* [relay32/snoop.c][relay32/builtin.c][loader/pe_image.c]
	Added inter win32 dll snooping. Use -debugmsg +snoop.
	Number of arguments and string references are autodetected.
	Some small bugfixes in the PE loader.

	* [misc/system.c]
	Disabled SystemTimers. They do not work with the current
	%fs handling in the 32->16 relaycode. (helps labview)

	* [msdos/dpmi.c][msdos/int2f.c][files/drive.c]
	Added a monoton linear increasing memory allocator for DPMI (required
	for LabView, HAFAS, ...)
	mscdex handling in emulated realmode interrupts (for mcicda.drv)
	allocate logical drives only once. (helps Myst)

	* [files/profile.c]
	Handle ^Z as space. Found on CDROMS (helps Myst Installer).

	* [multimedia/mmio.c]
	mmio* partially updated to win32. No funny additions.

	* [windows/driver.c]
	Added win32 driver handling (will be used for win32 multimedia/
	msvideo drivers).

	* [win32/device.c]
	Added device handling (K32OBJ_DEVICE_IOCTL). Implemented 
	VTDAPI.5 (used by win95' WINMM.timeGetTime())

Fri Jun 12 18:01:18 1998 Rein Klazes <rklazes@casema.net>

	* [ole/compobj.c relay32/ole32.spec]
	Add a stub for CoLockObjectExternal32.

	* [objects/clipping.c]
	Fix in IntersectClipRect(), when there is no initial clipping
	region.

	* [graphics/x11drv/graphics.c]
	Corrected several "one-off" errors for the Ellipse, Rectangle
	and RoundRectangle (especially small ones) draw routines. 
	Arc and friends still have to be done.

Fri Jun 12 06:23:19 1998  Matthew Becker <mbecker@glasscity.net>

	* [misc/ntdll.c]
	Fixed some of the parameter counts.

	* [misc/registry.c]
	General cleanup, documentation.
	Standard keys are allowed to be 'closed' and succeed.

	* [misc/shell.c]
	Check for correct return values from Reg* functions.

	* [win32/newfns.c]
	Added stubs for OpenDesktopA, SetThreadDesktop, and
	SetUserObjectInformationA.

Wed Jun 10  20:28:08 1998  James Juran  <jrj120@psu.edu>

	* [debugger/break.c]
	Fixed bug introduced in 980503 that broke the -debug command 
	line option for PE executable files.

	* [configure.in] [include/acconfig.h] [include/debugtools.h]
	  [documentation/debug-msgs]
	Added 'configure' options to compile out debugging messages.
	Use --disable-debug to disable all debugging messages, and
	--disable-trace to just disable TRACE messages.  This results
	in a stripped executable that is 15-20% smaller.  This option
	is very much untested--don't expect it to work.

	* [documentation/debug-msgs] [documentation/debugging]
	Minor updates.

	* [*/*.c]
	Fixed some compile warnings.  This also includes the
	compile_warnings_trivial patch from WineHQ.

Tue Jun 10 22:00:18 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [windows/sysmetrics.c][include/sysmetrics.h]
	Fixed some Win95 values.

	* [windows/nonclient.c][include/windows.h]
	Fixed some Win95 drawing bugs.
	Added extended window style flags (WS_EX_xxx).

	* [misc/printdrv.c][relay32/winspool.spec]
	Added stubs for DeletePrinterDriver32A, DeleteMonitor32A
	and DeletePort32A.

	* [windows/mdi.c][include/windows.h][relay32/user32.spec]
	Added stubs for CascadeWindows and TileWindows.

	* [controls/toolbar.c][include/toolbar.h]
	Fixed a few bugs and implemented new features.

	* [misc/shellord.c][relay32/shell32.spec]
	Added stubs for SHELL32_60, SHELL32_61 and SHELL32_184.

	* [controls/comctl32undoc.c][relay32/comctl32.spec]
	New file comctl32undoc.c. Contains undocumented functions
	of COMCTL32.DLL. These functions are needed to run EXPLORER.EXE
	IEXPLORE.EXE and TASKMAN.EXE.

	* [controls/status.c]
	Added text alignment.

Tue Jun  8 22:00:00 1998  Bertho Stultiens <bertho@akhphd.au.dk>

	* [programs/*/Makefile.in]
	Changed the rules to use wrc as resource compiler but
	passing the source through gcc first for macro expansion.

	* [programs/*/*.rc]
	Added #include "windows.h" for the resource compiler in the
	appropriate files.

	* [tools/wrc/wrc.[ch]] [tools/wrc/writeres.c]
	Added commandline option -A for autoregister code.
	Corrected the underscore problem by checking the proper define
	from config.h.

Sun Jun  7 22:09:29 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>

	* [ole/ole2nls.c] [memory/string.c]
	Improved LCMapString32A, and changed CompareString32A,
	lstrcmp, lstrcmpi to use it.

Sat Jun  6 19:00:50 1998  Martin Strömberg <ams@ludd.luth.se>

	* [include/winnt.h]
	Added typedefs for security and tokens.

Sat Jun  6 12:26:31 1998  Morten Welinder  <terra@diku.dk>

	* [objects/text.c]
	Use debugstr_an in DrawText16.

	* [loader/resource.c]
	Use debugres_w in FindResourceEx32W.  Avoid crashing during
	debug when wm is NULL.

	* [if1632/relay.c]
	In RELAY_DebugCallTo16, send output to the right place and
	avoid side effects in macro arguments.

Wed Jun  3 20:56:03 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [controls/scroll.c] [windows/nonclient.c]
	Fix several off by one errors in scrollbar painting.

Tue Jun  2 23:58:59 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>

	* [graphics/dsound.c]
	Rewrote mixer code to handle panning and volume for 16->16, 16->8,
	8->16, and 8->8 bit mixes.  Conforms to DirectX's "logarithmic
	hearing scale" as specified in M$VC docs.  Still does not handle
	mixing of different frequencies (I am still working on that). 
	Tested 16->16 extensively with StarCraft.  Other mixing combinations
	untested but should work fine.  Still kind of a work in progress,
	so be warned.

Tue Jun  2 03:31:33 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [tools/wrc/utils.c]
	dup_basename: fix to strip directory.

Mon Jun  1 20:00:00 1998  Juergen Schmied <juergen.schmied@metronet.de>

	* [include/windows.h] [objects/cursoricon.c] [relay32/user32.spec]
	Added stubs LoadCursorFromFileW and LoadCursorFromFileA.
diff --git a/windows/defwnd.c b/windows/defwnd.c
index ec0ade8..1a57fa4 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -153,7 +153,7 @@
 
     case WM_RBUTTONDOWN:
     case WM_NCRBUTTONDOWN:
-        if( wndPtr->flags & WIN_ISWIN32 ) 
+        if ((wndPtr->flags & WIN_ISWIN32) || TWEAK_Win95Look)
         {
 	    ClientToScreen16(wndPtr->hwndSelf, (LPPOINT16)&lParam);
             SendMessage32A( wndPtr->hwndSelf, WM_CONTEXTMENU,
@@ -167,7 +167,6 @@
 
      /* else 
       *     FIXME: Track system popup if click was in the caption area. */
-
 	break;
 
     case WM_NCACTIVATE:
diff --git a/windows/dialog.c b/windows/dialog.c
index 53e891e..2226a2e 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -576,6 +576,7 @@
     {
           /* The font height must be negative as it is a point size */
           /* (see CreateFont() documentation in the Windows SDK).   */
+
 	if (win32Template)
 	    hFont = CreateFont32W( -template.pointSize, 0, 0, 0,
                                    template.weight, template.italic, FALSE,
@@ -583,9 +584,9 @@
                                    FF_DONTCARE, (LPCWSTR)template.faceName );
 	else
 	    hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
-			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
-			    PROOF_QUALITY, FF_DONTCARE,
-                            template.faceName );
+				  FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
+				  PROOF_QUALITY, FF_DONTCARE,
+				  template.faceName );
 	if (hFont)
 	{
 	    TEXTMETRIC16 tm;
diff --git a/windows/driver.c b/windows/driver.c
index 79333fa..f62b3f1 100644
--- a/windows/driver.c
+++ b/windows/driver.c
@@ -1,10 +1,12 @@
 /*
- * Wine Drivers functions
+ * WINE Drivers functions
  *
  * Copyright 1994 Martin Ayotte
-*/
+ * Copyright 1998 Marcus Meissner
+ */
 
 #include "windows.h"
+#include "heap.h"
 #include "win.h"
 #include "callback.h"
 #include "driver.h"
@@ -12,6 +14,7 @@
 #include "debug.h"
 
 LPDRIVERITEM lpDrvItemList = NULL;
+LPDRIVERITEM32A lpDrvItemList32 = NULL;
 
 /**************************************************************************
  *	LoadStartupDrivers
@@ -33,20 +36,19 @@
     while (lstrlen32A( ptr ) != 0)
     {
 	TRACE(driver, "str='%s'\n", ptr );
-	hDrv = OpenDriver( ptr, "drivers", 0L );
+	hDrv = OpenDriver16( ptr, "drivers", 0L );
 	TRACE(driver, "hDrv=%04x\n", hDrv );
 	ptr += lstrlen32A(ptr) + 1;
     }
     TRACE(driver, "end of list !\n" );
-
     return;
 }
 
 /**************************************************************************
  *				SendDriverMessage		[USER.251]
  */
-LRESULT WINAPI SendDriverMessage(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
-                                 LPARAM lParam2)
+LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
+                                   LPARAM lParam2)
 {
     LPDRIVERITEM lpdrv;
     LRESULT retval;
@@ -71,21 +73,48 @@
 }
 
 /**************************************************************************
+ *				SendDriverMessage		[WINMM.19]
+ */
+LRESULT WINAPI SendDriverMessage32(HDRVR32 hDriver, UINT32 msg, LPARAM lParam1,
+                                   LPARAM lParam2)
+{
+    LPDRIVERITEM32A lpdrv;
+    LRESULT retval;
+
+    TRACE(driver, "(%04x, %04X, %08lX, %08lX)\n",
+		    hDriver, msg, lParam1, lParam2 );
+
+    lpdrv = (LPDRIVERITEM32A)hDriver;
+    if (!lpdrv)
+	return 0;
+
+    retval = lpdrv->driverproc(lpdrv->dis.hDriver,hDriver,msg,lParam1,lParam2);
+
+    TRACE(driver, "retval = %ld\n", retval );
+
+    return retval;
+}
+
+/**************************************************************************
  *				OpenDriver		        [USER.252]
  */
-HDRVR16 WINAPI OpenDriver(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
-{
+HDRVR16 WINAPI OpenDriver16(
+	LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam
+) {
     HDRVR16 hDrvr;
     LPDRIVERITEM lpdrv, lpnewdrv;
     char DrvName[128];
-    WORD ordinal;
 
     TRACE(driver,"('%s', '%s', %08lX);\n",
 		    lpDriverName, lpSectionName, lParam );
 
-    if (lpSectionName == NULL) lpSectionName = "drivers";
-    GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
-			     sizeof(DrvName), "SYSTEM.INI" );
+    if (lpSectionName == NULL) {
+    	lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName));
+	FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName);
+    } else {
+        GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
+				     sizeof(DrvName), "SYSTEM.INI" );
+    }
     TRACE(driver,"DrvName='%s'\n", DrvName );
     if (lstrlen32A(DrvName) < 1) return 0;
 
@@ -95,7 +124,7 @@
 	if (!lstrcmpi32A( lpDriverName, lpdrv->dis.szAliasName ))
 	{
 	    lpdrv->count++;
-	    SendDriverMessage( lpdrv->dis.hDriver, DRV_OPEN, 0L, lParam );
+	    SendDriverMessage16( lpdrv->dis.hDriver, DRV_OPEN, 0L, lParam );
 	    return lpdrv->dis.hDriver;
 	}
 	lpdrv = lpdrv->lpNextItem;
@@ -120,10 +149,7 @@
     lpnewdrv->dis.hDriver = hDrvr;
     lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName );
     lpnewdrv->count = 1;
-    ordinal = NE_GetOrdinal( lpnewdrv->dis.hModule, "DRIVERPROC" );
-    if (!ordinal ||
-        !(lpnewdrv->lpDrvProc = (DRIVERPROC16)NE_GetEntryPoint(
-                                             lpnewdrv->dis.hModule, ordinal )))
+    if (!(lpnewdrv->lpDrvProc = (DRIVERPROC16)WIN32_GetProcAddress16(lpnewdrv->dis.hModule, "DRIVERPROC" )))
     {
 	FreeModule16( lpnewdrv->dis.hModule );
 	GlobalUnlock16( hDrvr );
@@ -143,18 +169,104 @@
 	lpnewdrv->lpPrevItem = lpdrv;
     }
 
-    SendDriverMessage( hDrvr, DRV_LOAD, 0L, lParam );
-    SendDriverMessage( hDrvr, DRV_ENABLE, 0L, lParam );
-    SendDriverMessage( hDrvr, DRV_OPEN, 0L, lParam );
+    SendDriverMessage16( hDrvr, DRV_LOAD, 0L, lParam );
+    SendDriverMessage16( hDrvr, DRV_ENABLE, 0L, lParam );
+    SendDriverMessage16( hDrvr, DRV_OPEN, 0L, lParam );
 
     TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr );
     return hDrvr;
 }
 
 /**************************************************************************
- *				CloseDriver				[USER.253]
+ *				OpenDriver		        [WINMM.15]
+ * (0,1,DRV_LOAD  ,0       ,0)
+ * (0,1,DRV_ENABLE,0       ,0)
+ * (0,1,DRV_OPEN  ,buf[256],0)
  */
-LRESULT WINAPI CloseDriver(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
+HDRVR32 WINAPI OpenDriver32A(
+	LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam
+) {
+    HDRVR32 hDrvr;
+    LPDRIVERITEM32A lpdrv, lpnewdrv;
+    char DrvName[128],*tmpbuf;
+
+    TRACE(driver,"('%s', '%s', %08lX);\n",
+		    lpDriverName,lpSectionName,lParam );
+
+    if (lpSectionName == NULL) {
+    	lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName));
+	FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName);
+    } else  {
+	GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
+				 sizeof(DrvName), "system.ini" );
+    }
+    TRACE(driver,"DrvName='%s'\n", DrvName );
+    if (lstrlen32A(DrvName) < 1) return 0;
+
+    lpdrv = lpDrvItemList32;
+    while (lpdrv) {
+	if (!lstrcmpi32A( lpDriverName, lpdrv->dis.szAliasName )) {
+	    lpdrv->count++;
+	    lpdrv->dis.hDriver = SendDriverMessage32( lpdrv->dis.hDriver, DRV_OPEN, ""/*FIXME*/, 0L );
+	    return (HDRVR32)lpdrv;
+	}
+	lpdrv = lpdrv->next;
+    }
+
+    hDrvr = (HDRVR32)HeapAlloc(SystemHeap,0, sizeof(DRIVERITEM32A) );
+    if (!hDrvr) {
+    	ERR(driver,"out of memory");
+	return 0;
+    }
+    lpnewdrv = (DRIVERITEM32A*)hDrvr;
+    lpnewdrv->dis.length = sizeof( DRIVERINFOSTRUCT32A );
+    lpnewdrv->dis.hModule = LoadLibrary32A( DrvName );
+    if (!lpnewdrv->dis.hModule) {
+    	FIXME(driver,"could not load library %s\n",DrvName);
+	HeapFree( SystemHeap,0,(LPVOID)hDrvr );
+	return 0;
+    }
+    lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName );
+    lpnewdrv->count = 1;
+    if (!(lpnewdrv->driverproc = (DRIVERPROC32)GetProcAddress32(lpnewdrv->dis.hModule, "DriverProc" )))
+    {
+    	FIXME(driver,"no 'DriverProc' found in %s\n",DrvName);
+	FreeModule32( lpnewdrv->dis.hModule );
+	HeapFree( SystemHeap,0, (LPVOID)hDrvr );
+	return 0;
+    }
+
+    lpnewdrv->next = lpDrvItemList32;
+    lpDrvItemList32 = lpnewdrv;
+
+    SendDriverMessage32( hDrvr, DRV_LOAD, 0L, lParam );
+    SendDriverMessage32( hDrvr, DRV_ENABLE, 0L, lParam );
+    tmpbuf = HeapAlloc(SystemHeap,0,256);
+    lpnewdrv->dis.hDriver=SendDriverMessage32(hDrvr,DRV_OPEN,tmpbuf,lParam);
+    HeapFree(SystemHeap,0,tmpbuf);
+    TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr );
+    return hDrvr;
+}
+
+/**************************************************************************
+ *				OpenDriver		        [WINMM.15]
+ */
+HDRVR32 WINAPI OpenDriver32W(
+	LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam
+) {
+	LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(),0,lpDriverName);
+	LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(),0,lpSectionName);
+	HDRVR32	ret = OpenDriver32A(dn,sn,lParam);
+
+	if (dn) HeapFree(GetProcessHeap(),0,dn);
+	if (sn) HeapFree(GetProcessHeap(),0,sn);
+	return ret;
+}
+
+/**************************************************************************
+ *			CloseDriver				[USER.253]
+ */
+LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
 {
     LPDRIVERITEM lpdrv;
 
@@ -164,11 +276,11 @@
     lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
     if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr)
     {
-	SendDriverMessage( hDrvr, DRV_CLOSE, lParam1, lParam2 );
+	SendDriverMessage16( hDrvr, DRV_CLOSE, lParam1, lParam2 );
 	if (--lpdrv->count == 0)
 	{
-	    SendDriverMessage( hDrvr, DRV_DISABLE, lParam1, lParam2 );
-	    SendDriverMessage( hDrvr, DRV_FREE, lParam1, lParam2 );
+	    SendDriverMessage16( hDrvr, DRV_DISABLE, lParam1, lParam2 );
+	    SendDriverMessage16( hDrvr, DRV_FREE, lParam1, lParam2 );
 
 	    if (lpdrv->lpPrevItem)
 	      lpdrv->lpPrevItem->lpNextItem = lpdrv->lpNextItem;
@@ -192,7 +304,7 @@
 /**************************************************************************
  *				GetDriverModuleHandle	[USER.254]
  */
-HMODULE16 WINAPI GetDriverModuleHandle(HDRVR16 hDrvr)
+HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
 {
     LPDRIVERITEM lpdrv;
     HMODULE16 hModule = 0;
@@ -209,6 +321,19 @@
 }
 
 /**************************************************************************
+ *				GetDriverModuleHandle	[USER.254]
+ */
+HMODULE32 WINAPI GetDriverModuleHandle32(HDRVR32 hDrvr)
+{
+    LPDRIVERITEM32A lpdrv = (LPDRIVERITEM32A)hDrvr;
+
+    TRACE(driver, "(%04x);\n", hDrvr);
+    if (!lpdrv)
+    	return 0;
+    return lpdrv->dis.hModule;
+}
+
+/**************************************************************************
  *				DefDriverProc			[USER.255]
  */
 LRESULT WINAPI DefDriverProc(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, 
diff --git a/windows/graphics.c b/windows/graphics.c
index e3e1d25..fcdf859 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -52,6 +52,7 @@
 	    bRet = TRUE;
 	}
 	if( hPrevPen ) SelectObject32( hdc, hPrevPen );
+	GDI_HEAP_UNLOCK( hdc );
     }
     return bRet;
 }
@@ -69,10 +70,14 @@
 {
     BITMAPOBJ *bmp;
     DC *dc;
+    BOOL32 ret = TRUE;
 
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
     if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
+    {
+        GDI_HEAP_UNLOCK( hdc );
         return FALSE;
+    }
 
     xdest += dc->w.DCOrgX; ydest += dc->w.DCOrgY;
 
@@ -104,17 +109,19 @@
 			xsrc, ysrc, width, height, xdest, ydest, plane );
 	}
 	else 
+	{
 	    TSXCopyArea( display, bmp->pixmap, dc->u.x.drawable, 
 		       dc->u.x.gc, xsrc, ysrc, width, height, xdest, ydest );
+	}
     }
     else 
     {
-      GDI_HEAP_UNLOCK( hbitmap );
-      return FALSE;
+      ret = FALSE;
     }
 
+    GDI_HEAP_UNLOCK( hdc );
     GDI_HEAP_UNLOCK( hbitmap );
-    return TRUE;
+    return ret;
 }
 
 
@@ -195,6 +202,7 @@
     }
 
     SelectObject32( hdc, hPrevBrush );
+    GDI_HEAP_UNLOCK( hdc );
 }
 
 
@@ -216,6 +224,7 @@
 	    TSXDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc, 
 			    x + dc->w.DCOrgX, y + dc->w.DCOrgY, w - 1, h - 1);
 	if( hPrevPen ) SelectObject32( hdc, hPrevPen );
+	GDI_HEAP_UNLOCK( hdc );
     }
 }
 
@@ -231,13 +240,17 @@
     if ( hMonoBitmap ) 
     {
        if ( !(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hMonoBitmap, BITMAP_MAGIC)) 
-	   || bmp->bitmap.bmBitsPixel != 1 ) return FALSE;
-	  
+	   || bmp->bitmap.bmBitsPixel != 1 ) 
+       {
+	   GDI_HEAP_UNLOCK( hdc );
+	   return FALSE;
+       }
        TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y);
     }
 
     TSXSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None );
 
+    GDI_HEAP_UNLOCK( hdc );
     GDI_HEAP_UNLOCK( hMonoBitmap );
     return TRUE;
 }
diff --git a/windows/mdi.c b/windows/mdi.c
index 185c7ce..47e7e07 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -1708,3 +1708,39 @@
 			SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
 }
 
+
+/******************************************************************************
+ * CascadeWindows [USER32.21] Cascades MDI child windows
+ *
+ * RETURNS
+ *    Success: Number of cascaded windows.
+ *    Failure: 0
+ */
+WORD WINAPI
+CascadeWindows (HWND32 hwndParent, UINT32 wFlags, const LPRECT32 lpRect,
+		UINT32 cKids, const HWND32 *lpKids)
+{
+    FIXME (mdi, "(0x%08x,0x%08x,...,%u,...): stub\n",
+	   hwndParent, wFlags, cKids);
+
+    return 0;
+}
+
+
+/******************************************************************************
+ * TileWindows [USER32.545] Tiles MDI child windows
+ *
+ * RETURNS
+ *    Success: Number of tiled windows.
+ *    Failure: 0
+ */
+WORD WINAPI
+TileWindows (HWND32 hwndParent, UINT32 wFlags, const LPRECT32 lpRect,
+	     UINT32 cKids, const HWND32 *lpKids)
+{
+    FIXME (mdi, "(0x%08x,0x%08x,...,%u,...): stub\n",
+	   hwndParent, wFlags, cKids);
+
+    return 0;
+}
+
diff --git a/windows/message.c b/windows/message.c
index ee57696..82638ed 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -1736,3 +1736,13 @@
 	);
 	return 0;
 }
+
+BOOL32 WINAPI SendMessageCallBack32A(
+	HWND32 hWnd,UINT32 Msg,WPARAM32 wParam,LPARAM lParam,
+	/*SENDASYNCPROC*/FARPROC32 lpResultCallBack,DWORD dwData
+) {
+	FIXME(msg,"(0x%04x,0x%04x,0x%08lx,0x%08lx,%p,0x%08lx),stub!\n",
+		hWnd,Msg,wParam,lParam,lpResultCallBack,dwData
+	);
+	return FALSE;
+}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 8ea40c2..521c0b1 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -98,8 +98,17 @@
     }
     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
 
-    if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL - 1;
-    if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL - 1;
+    if (style & WS_VSCROLL) {
+      rect->right  += SYSMETRICS_CXVSCROLL - 1;
+      if(!(style & WS_BORDER))
+	 rect->right++;
+    }
+
+    if (style & WS_HSCROLL) {
+      rect->bottom += SYSMETRICS_CYHSCROLL - 1;
+      if(!(style & WS_BORDER))
+	 rect->bottom++;
+    }
 }
 
 
@@ -149,7 +158,7 @@
             rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
     }
     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER + 2;
-    else  if (!(style & WS_CHILD)) rect->top += SYSMETRICS_CYBORDER;
+    else if (!(style & WS_CHILD)) rect->top += SYSMETRICS_CYBORDER;
 
     if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL;
     if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
@@ -159,7 +168,7 @@
 /***********************************************************************
  *           DrawCaptionTempA    (USER32.599)
  */
-DWORD DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,
+DWORD WINAPI DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,
     HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2)
 {
     FIXME(nonclient,"(%08x,%08x,%p,%08x,%08lx,\"%s\",%08lx): stub\n",
@@ -197,7 +206,7 @@
     if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
 	style |= WS_CAPTION;
     style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
-    exStyle &= WS_EX_DLGMODALFRAME;
+    exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE);
     if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
 
     TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
@@ -276,8 +285,6 @@
  * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
  * but without the borders (if any).
  * The rectangle is in window coordinates (for drawing with GetWindowDC()).
- *
- * FIXME:  A Win95 version of this function is needed.
  */
 static void NC_GetInsideRect( HWND32 hwnd, RECT32 *rect )
 {
@@ -309,6 +316,42 @@
 
 
 /***********************************************************************
+ *           NC_GetInsideRect95
+ *
+ * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
+ * but without the borders (if any).
+ * The rectangle is in window coordinates (for drawing with GetWindowDC()).
+ */
+
+static void
+NC_GetInsideRect95 (HWND32 hwnd, RECT32 *rect)
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+
+    rect->top    = rect->left = 0;
+    rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+    rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+
+    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
+
+      /* Remove frame from rectangle */
+    if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
+    {
+	InflateRect32( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
+    }
+    else if (HAS_THICKFRAME (wndPtr->dwStyle))
+    {
+	InflateRect32( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
+
+	if (wndPtr->dwStyle & WS_BORDER)
+	    InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
+    }
+
+    return;
+}
+
+
+/***********************************************************************
  *           NC_HandleNCHitTest
  *
  * Handle a WM_NCHITTEST message. Called from DefWindowProc().
@@ -526,29 +569,28 @@
  *
  *****************************************************************************/
 
-void  NC_DrawSysButton95(
-    HWND32  hwnd,
-    HDC32  hdc,
-    BOOL32  down )
+void
+NC_DrawSysButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
 {
     RECT32 rect;
     HDC32 hdcMem;
     HBITMAP32 hbitmap;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    SIZE32  bmsz;
 
     if( !(wndPtr->flags & WIN_MANAGED) )
     {
-	NC_GetInsideRect( hwnd, &rect );
+	BITMAP32 bmp;
+
+	NC_GetInsideRect95( hwnd, &rect );
 	hdcMem = CreateCompatibleDC32( hdc );
 	hbitmap = SelectObject32( hdcMem, hbitmapClose );
-	if(GetBitmapDimensionEx32( hbitmapClose, &bmsz )) {
-	    BitBlt32(hdc, rect.left + (sysMetrics[SM_CXSIZE] - bmsz.cx) / 2 +
+	GetObject32A (hbitmapClose, sizeof(BITMAP32), &bmp);
+	BitBlt32 (hdc, rect.left + (sysMetrics[SM_CXSIZE] - bmp.bmWidth) / 2 +
 		     NC_SysControlNudge,
-		     rect.top + (sysMetrics[SM_CYSIZE] - bmsz.cy - 1) / 2,
-		     bmsz.cx, bmsz.cy,
+		     rect.top + (sysMetrics[SM_CYSIZE] - bmp.bmHeight - 1) / 2,
+		     bmp.bmWidth, bmp.bmHeight,
 		     hdcMem, 0, 0, down ? NOTSRCCOPY : SRCCOPY );
-	}
+
 	SelectObject32( hdcMem, hbitmap );
 	DeleteDC32( hdcMem );
 	
@@ -594,7 +636,7 @@
 				(down ? hbitmapMaximizeD : hbitmapMaximize)),
 			       &bmsz)) {
 
-	NC_GetInsideRect( hwnd, &rect );
+	NC_GetInsideRect95( hwnd, &rect );
 	
 	GRAPH_DrawBitmap( hdc, bm,
 			  rect.right + NC_MaxControlNudge -
@@ -640,7 +682,7 @@
 	GetBitmapDimensionEx32((bm = down ? hbitmapMinimizeD :
 				hbitmapMinimize), &bmsz)) {
 	
-	NC_GetInsideRect( hwnd, &rect );
+	NC_GetInsideRect95( hwnd, &rect );
 
 	if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
 	    rect.right += -1 + NC_MaxControlNudge -
@@ -764,6 +806,8 @@
  *   Revision history
  *        06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation (based on NC_DrawFrame)
+ *        02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Some minor fixes.
  *
  *****************************************************************************/
 
@@ -777,19 +821,18 @@
 
     if (dlgFrame)
     {
-	width = SYSMETRICS_CXDLGFRAME - 1;
-	height = SYSMETRICS_CYDLGFRAME - 1;
-        SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
-						COLOR_INACTIVECAPTION) );
+	width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
+	height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
     }
     else
     {
 	width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE] - 1;
 	height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE] - 1;
-        SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
-						COLOR_INACTIVEBORDER) );
     }
 
+    SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
+		COLOR_INACTIVEBORDER) );
+
     /* Draw frame */
     PatBlt32( hdc, rect->left, rect->top,
               rect->right - rect->left, height, PATCOPY );
@@ -921,13 +964,14 @@
  *   The correct pen for the window frame must be selected in the DC.
  *
  *   Bugs
- *        Hey, a function that finally works!  Well, almost.  In Win95, the
- *        title has its own font -- not the system font.  It's being worked
- *        on.
+ *        Hey, a function that finally works!  Well, almost.
+ *        It's being worked on.
  *
  *   Revision history
  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation.
+ *        02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Some minor fixes.
  *
  *****************************************************************************/
 
@@ -957,16 +1001,6 @@
 	hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
 	hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
     }
-    
-    if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) {
-	HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) );
-	PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
-	PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
-	PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
-	r.left++;
-	r.right--;
-	SelectObject32( hdc, hbrushOld );
-    }
 
     if (style & WS_SYSMENU) {
 	NC_DrawSysButton95( hwnd, hdc, FALSE );
@@ -982,12 +1016,18 @@
     }
 
     if (GetWindowText32A( hwnd, buffer, sizeof(buffer) )) {
+	NONCLIENTMETRICS32A nclm;
+	HFONT32 hFont, hOldFont;
+	nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
+	SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
+	hFont = CreateFontIndirect32A (&nclm.lfCaptionFont);
+	hOldFont = SelectObject32 (hdc, hFont);
 	if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
 	else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
 	SetBkMode32( hdc, TRANSPARENT );
-	r.top += NC_CaptionTopNudge - 2;
-	r.left += NC_CaptionLeftNudge;
+	r.left += 2;
 	DrawText32A( hdc, buffer, -1, &r, NC_CaptionTextFlags );
+	DeleteObject32 (SelectObject32 (hdc, hOldFont));
     }
 }
 
@@ -1075,6 +1115,10 @@
         RECT32 r = rect;
         r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
         r.top  = r.bottom - SYSMETRICS_CYHSCROLL + 1;
+	if(wndPtr->dwStyle & WS_BORDER) {
+	  r.left++;
+	  r.top++;
+	}
         FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
     }    
 
@@ -1099,6 +1143,8 @@
  *   Revision history
  *        03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
  *             Original implementation
+ *        10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ *             Fixed some bugs.
  *
  *****************************************************************************/
 
@@ -1140,8 +1186,7 @@
     if(!(wndPtr->flags & WIN_MANAGED)) {
         if((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
 	   (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)) {
-	    TWEAK_DrawReliefRect95(hdc, &rect);
-	    InflateRect32(&rect, -2, -2);
+            DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
         }
 
         if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
@@ -1189,6 +1234,7 @@
 
     InflateRect32(&rect, -1, -1);
 
+
     /* Draw the scroll-bars */
 
     if (wndPtr->dwStyle & WS_VSCROLL)
@@ -1325,7 +1371,10 @@
 	  GetWindowRect32( wndPtr->hwndSelf, rect );
       else
       {
-  	  NC_GetInsideRect( wndPtr->hwndSelf, rect );
+          if(TWEAK_Win95Look)
+              NC_GetInsideRect95( wndPtr->hwndSelf, rect );
+          else
+              NC_GetInsideRect( wndPtr->hwndSelf, rect );
   	  OffsetRect32( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
   	  if (wndPtr->dwStyle & WS_CHILD)
      	      ClientToScreen32( wndPtr->parent->hwndSelf, (POINT32 *)rect );
@@ -1354,7 +1403,10 @@
     {
 	  /* Move pointer at the center of the caption */
 	RECT32 rect;
-	NC_GetInsideRect( wndPtr->hwndSelf, &rect );
+        if(TWEAK_Win95Look)
+            NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
+        else
+            NC_GetInsideRect( wndPtr->hwndSelf, &rect );
 	if (wndPtr->dwStyle & WS_SYSMENU)
 	    rect.left += SYSMETRICS_CXSIZE + 1;
 	if (wndPtr->dwStyle & WS_MINIMIZEBOX)
diff --git a/windows/painting.c b/windows/painting.c
index d35e991..c97dad1 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -300,8 +300,7 @@
     }
     else
     {
-        TRACE(win, "%04x NULL %04x flags=%04x\n",
-                     hwnd, hrgnUpdate, flags);
+        TRACE(win, "%04x NULL %04x flags=%04x\n", hwnd, hrgnUpdate, flags);
     }
 
     GetClientRect32( hwnd, &rectClient );
diff --git a/windows/scroll.c b/windows/scroll.c
index 3acef48..d8b06b3 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include "windows.h"
 #include "class.h"
+#include "dc.h"
 #include "win.h"
 #include "gdi.h"
 #include "dce.h"
@@ -193,7 +194,10 @@
     }
 
     if( rDClip.left >= rDClip.right || rDClip.top >= rDClip.bottom )
+    {
+        GDI_HEAP_UNLOCK( hdc );
 	return FALSE;
+    }
     
     hrgnClip = GetClipRgn16(hdc);
     hrgnScrollClip = CreateRectRgnIndirect32(&rDClip);
@@ -236,7 +240,10 @@
 
 	if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy,
 		       hdc, src.x, src.y, SRCCOPY))
+	{
+	    GDI_HEAP_UNLOCK( hdc );
 	    return FALSE;
+	}
     }
 
     /* restore clipping region */
@@ -287,6 +294,7 @@
     }
 
     DeleteObject32( hrgnScrollClip );     
+    GDI_HEAP_UNLOCK( hdc );
     return TRUE;
 }
 
@@ -415,6 +423,7 @@
 		if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
 	    }
 	    ReleaseDC32(hwnd, hDC);
+	    GDI_HEAP_UNLOCK( hDC );
 	}
 
 	if( wnd->hrgnUpdate > 1 )
diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c
index b1f4ea9..b02f629 100644
--- a/windows/sysmetrics.c
+++ b/windows/sysmetrics.c
@@ -33,7 +33,7 @@
     sysMetrics[SM_CYBORDER] = sysMetrics[SM_CXBORDER];
     sysMetrics[SM_CXDLGFRAME] =
 	PROFILE_GetWineIniInt("Tweak.Layout", "DialogFrameWidth",
-			      TWEAK_Win95Look ? 2 : 4);
+			      TWEAK_Win95Look ? 3 : 4);
     sysMetrics[SM_CYDLGFRAME] = sysMetrics[SM_CXDLGFRAME];
     sysMetrics[SM_CYVTHUMB] = sysMetrics[SM_CXVSCROLL] - 1;
     sysMetrics[SM_CXHTHUMB] = sysMetrics[SM_CYVTHUMB];
@@ -118,8 +118,8 @@
     /* For the following: 0 = ok, 1 = failsafe, 2 = failsafe + network */
     sysMetrics[SM_CLEANBOOT] = 0;
 
-    sysMetrics[SM_CXDRAG] = 0;
-    sysMetrics[SM_CYDRAG] = 0;
+    sysMetrics[SM_CXDRAG] = 2;
+    sysMetrics[SM_CYDRAG] = 2;
     sysMetrics[SM_SHOWSOUNDS] = 0;
     sysMetrics[SM_CXMENUCHECK] = 2;
     sysMetrics[SM_CYMENUCHECK] = 2;
diff --git a/windows/win.c b/windows/win.c
index af2917d..e146e89 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -1647,6 +1647,15 @@
                                   (LPARAM)lpString );
 }
 
+/*******************************************************************
+ *	     InternalGetWindowText    (USER32.326)
+ */
+INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
+{
+	FIXME(win,"(0x%08lx,0x%08lx,%ld),stub!\n",hwnd,lpString,nMaxCount);
+	return GetWindowText32W(hwnd,lpString,nMaxCount);
+}
+
 
 /*******************************************************************
  *	     GetWindowText32W    (USER32.312)
@@ -2557,4 +2566,3 @@
 
     return (DWORD)(msg.lParam);
 }
-