Release 951212

Mon Dec 11 19:08:55 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [misc/lstr.c]
	Replaced wine_strncpy() by a 32-bit version of lstrcpyn(), since
 	they do the same job.

	* [tools/build.c]
	Fixed __attribute__((stdcall)) to make it compile with gcc
	versions under 2.7. Doesn't mean it will run OK though...

Sat Dec 09 13:22:58 1995  Cameron Heide  <heide@ee.ualberta.ca>

	* [include/kernel32.h] [include/winerror.h]
	Added file attribute definitions and more error codes.

	* [win32/error.c]
	Added some rudimentary errno-to-Win32 error conversion
	code.

	* [win32/file.c]
	Added to GetFileInformationByHandle, filled in some known
	error codes, and switched to dprintf_win32.

	* [win32/time.c]
	Added GetLocalTime.

Fri Dec  8 14:37:39 1995  Jim Peterson <jspeter@birch.ee.vt.edu>

	* [controls/combo.c]
	Converted functions of the type LONG _(HWND,WORD,LONG) to the type
	LRESULT _(HWND,WPARAM,LPARAM) where needed.

	* [include/libres.h]
	Restructured libres prototypes to closer match the windows API.

	* [include/windows.h]
	Changed several API prototypes' parameter types from 'short' to INT,
	which is #defined as short in the emulator, but is a normal int in
	WINELIB32.  Also changed SEGPTR from DWORD to void* when WINELIB32.
	(This creates a lot of warnings at library-compile time, but less
	warnings at app-compile time.  I'll remove the warnings soon.)

	* [loader/resource.c]
	Fixed parameter mismatch in call to LIBRES_FindResource().  Changed
	various implementations of the LIBRES_* API functions.

	* [loader/signal.c]
	Deleted local 'i' from win_fault(), since it was unused.

	* [objects/bitblt.c]
	Mirrored changes to include/windows.h mentioned above.

	* [toolkit/hello3.c]
	Changed LoadMenuIndirect() call to LoadMenu() to test the new
	resource registration technique.

	* [toolkit/libres.c]
	Removed definition of 'struct resource' and fixed bugs in the resource
	implementation.  Implemented LIBRES_FindResource.

	* [windows/graphics.c]
	Mirrored changes to include/windows.h mentioned above.

Thu Dec  7 23:15:56 1995     Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [controls/edit.c]
	LOCAL_HeapExists: Changed parameter to HANDLE. For WineLib, return true

	* [controls/listbox.c]
	CreateListBoxStruct: Initialize HeapSel to 0 for WineLib

	* [include/listbox.h]
	change HeapSel from WORD to HANDLE

	* [include/resource.h][rc/winerc.c]
	struct ResourceTable: removed
	struct resource: moved to header file
	autoregister resources if supported by compiler

	* [memory/local.h]
	LOCAL_GetHeap: expect HANDLE rather than WORD
	
	* [toolkit/Makefile.in]
	Add ALLCFLAGS to make hello3

	* [toolkit/heap.c]
	LocalFree, HEAP_Free: handle 0 parameter gracefully

Wed Dec 06 15:34:23 1995  Greg Cooper <cooper@ima-inc.com>

	* [misc/winsocket.c]
	Fixed the msgsnd and msgrcv errors that winsock programs get.

Wed Dec 06 12:47:23 MET 1995 Sven Verdoolaege <skimo@dns.ufsia.ac.be>
	
	* [if1632/kernel.spec]
	Fixed _hread and _hwrite return type

	* [if1632/relay32.c] [loader/pe_image.c]
	Hacked loading of PE-dll's in

	* [win32/advapi.c]
	Added stubs for RegCreateKeyEx, RegSetValueEx, RegQueryValueEx

	* [win32/file.c]
	Added stubs for OpenFileMapping, CreateFileMapping, MapViewOfFileEx

	* [win32/process.c]
	Added stubs for CreateMutexA, ReleaseMutex, CreateEventA,
	WaitForSingleObject, DuplicateHandle, GetCurrentProcess
	
Mon Dec 04 13:06:37 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

	* [include/wine.h] [misc/lstr.c]
	Define wine_strncpy(). This function does not pad the buffer with 
	zeroes like GNU strncpy(), which might break some Windows programs
	that pass bogus size arguments.

	* [loader/module.c]: GetModuleFileName(),
	[misc/commdlg.c]: GetFileTitle(),
	[misc/keyboard.c], [misc/lstr.c]: lstrcpyn(),
	[misc/ole2nls.c], [misc/profile.c], [multimedia/mcistring.c],
	[multimedia/mmsystem.c], [objects/font.c]:
	Use wine_strncpy() where strings are returned to Windows programs.
	
	* [objects/metafile.c]
	PlayMetafile(): Clear the handle table before using it.

	* [misc/shell.c] [misc/main.c]
	Rename SHELL_RegCheckForRoot() to SHELL_Init() and call it from main().
	
	* [misc/profile.c]
	load(): Need to handle comments.
	
	* [toolkit/libres.c]
	Make it compile.
	
	* [windows/nonclient.c]
	Use MAKE_SEGPTR macro in two places where a user heap block used
	to be allocated instead.

Sat Dec 02 16:43:43 1995 Ramon Garcia <ramon@ie3.clubs.etsit.upm.es>

	* [windows/winpos.c]
	In function SetWindowPos: do not redraw the parent of
	a window if the specified window is placed on the top.
	This avoids that ShowWindow(hwnd,1) hides hwnd instead
	of showing it.

Sat Dec 02 11:00:00 1995 Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/scroll.c]
	Now it can scroll children along with the client region of parent 
        window. Tried to optimize update region calculation. 

	* [windows/mdi.c]
	ScrollChildren function, more other features added. Basically
	a rewrite.

	* [windows/winpos.c] [windows/focus.c]
	Reimplemented window activation and focus handling.

	* [windows/nonclient.c]
	Added new flag WIN_NCACTIVATED.

	* [windows/message.c] [loader/task.c]
	Small changes (to maintain linked list of message queues).

Wed Nov 29 15:51:48 1995  Daniel Schepler  <daniel@shep13.wustl.edu>

	* [include/options.h] [misc/main.c] [windows/defwnd.c]
	  [windows/event.c] [windows/nonclient.c] [windows/win.c] [Wine.man]
	Implemented a -managed option to replace the standard Windows
	frame of top-level windows with the window manager's decorations.
	If a top-level window makes its own frame, this will still show
	up, inside the window manager decorations (I believe ctl3dv2.dll
	would do this, although I can't test this).
diff --git a/ANNOUNCE b/ANNOUNCE
index a486e16..3b5dff6 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,13 @@
-This is release 951124 of Wine the MS Windows emulator.  This is still a
+This is release 951212 of Wine the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work.
 
 Patches should be submitted to "wine-new@amscons.com".  Please don't forget
 to include a ChangeLog entry.  I'll make a new release every other week.
 
-WHAT'S NEW with Wine-951124: (see ChangeLog for details)
-	- Drag and drop implemented.
-	- Unixware is now fully supported.
-	- Many Win32 improvements.
+WHAT'S NEW with Wine-951212: (see ChangeLog for details)
+	- Many more Winelib and Win32 fixes.
+	- Window management and MDI improvements.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,11 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-951124.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-951124.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-951124.tar.gz
-    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-951124.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-951124.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-951212.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-951212.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-951212.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-951212.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 9fcdf03..efd9fa4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,183 @@
 ----------------------------------------------------------------------
+Mon Dec 11 19:08:55 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>
+
+	* [misc/lstr.c]
+	Replaced wine_strncpy() by a 32-bit version of lstrcpyn(), since
+ 	they do the same job.
+
+	* [tools/build.c]
+	Fixed __attribute__((stdcall)) to make it compile with gcc
+	versions under 2.7. Doesn't mean it will run OK though...
+
+Sat Dec 09 13:22:58 1995  Cameron Heide  <heide@ee.ualberta.ca>
+
+	* [include/kernel32.h] [include/winerror.h]
+	Added file attribute definitions and more error codes.
+
+	* [win32/error.c]
+	Added some rudimentary errno-to-Win32 error conversion
+	code.
+
+	* [win32/file.c]
+	Added to GetFileInformationByHandle, filled in some known
+	error codes, and switched to dprintf_win32.
+
+	* [win32/time.c]
+	Added GetLocalTime.
+
+Fri Dec  8 14:37:39 1995  Jim Peterson <jspeter@birch.ee.vt.edu>
+
+	* [controls/combo.c]
+	Converted functions of the type LONG _(HWND,WORD,LONG) to the type
+	LRESULT _(HWND,WPARAM,LPARAM) where needed.
+
+	* [include/libres.h]
+	Restructured libres prototypes to closer match the windows API.
+
+	* [include/windows.h]
+	Changed several API prototypes' parameter types from 'short' to INT,
+	which is #defined as short in the emulator, but is a normal int in
+	WINELIB32.  Also changed SEGPTR from DWORD to void* when WINELIB32.
+	(This creates a lot of warnings at library-compile time, but less
+	warnings at app-compile time.  I'll remove the warnings soon.)
+
+	* [loader/resource.c]
+	Fixed parameter mismatch in call to LIBRES_FindResource().  Changed
+	various implementations of the LIBRES_* API functions.
+
+	* [loader/signal.c]
+	Deleted local 'i' from win_fault(), since it was unused.
+
+	* [objects/bitblt.c]
+	Mirrored changes to include/windows.h mentioned above.
+
+	* [toolkit/hello3.c]
+	Changed LoadMenuIndirect() call to LoadMenu() to test the new
+	resource registration technique.
+
+	* [toolkit/libres.c]
+	Removed definition of 'struct resource' and fixed bugs in the resource
+	implementation.  Implemented LIBRES_FindResource.
+
+	* [windows/graphics.c]
+	Mirrored changes to include/windows.h mentioned above.
+
+Thu Dec  7 23:15:56 1995     Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+	* [controls/edit.c]
+	LOCAL_HeapExists: Changed parameter to HANDLE. For WineLib, return true
+
+	* [controls/listbox.c]
+	CreateListBoxStruct: Initialize HeapSel to 0 for WineLib
+
+	* [include/listbox.h]
+	change HeapSel from WORD to HANDLE
+
+	* [include/resource.h][rc/winerc.c]
+	struct ResourceTable: removed
+	struct resource: moved to header file
+	autoregister resources if supported by compiler
+
+	* [memory/local.h]
+	LOCAL_GetHeap: expect HANDLE rather than WORD
+	
+	* [toolkit/Makefile.in]
+	Add ALLCFLAGS to make hello3
+
+	* [toolkit/heap.c]
+	LocalFree, HEAP_Free: handle 0 parameter gracefully
+
+Wed Dec 06 15:34:23 1995  Greg Cooper <cooper@ima-inc.com>
+
+	* [misc/winsocket.c]
+	Fixed the msgsnd and msgrcv errors that winsock programs get.
+
+Wed Dec 06 12:47:23 MET 1995 Sven Verdoolaege <skimo@dns.ufsia.ac.be>
+	
+	* [if1632/kernel.spec]
+	Fixed _hread and _hwrite return type
+
+	* [if1632/relay32.c] [loader/pe_image.c]
+	Hacked loading of PE-dll's in
+
+	* [win32/advapi.c]
+	Added stubs for RegCreateKeyEx, RegSetValueEx, RegQueryValueEx
+
+	* [win32/file.c]
+	Added stubs for OpenFileMapping, CreateFileMapping, MapViewOfFileEx
+
+	* [win32/process.c]
+	Added stubs for CreateMutexA, ReleaseMutex, CreateEventA,
+	WaitForSingleObject, DuplicateHandle, GetCurrentProcess
+	
+Mon Dec 04 13:06:37 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+	* [include/wine.h] [misc/lstr.c]
+	Define wine_strncpy(). This function does not pad the buffer with 
+	zeroes like GNU strncpy(), which might break some Windows programs
+	that pass bogus size arguments.
+
+	* [loader/module.c]: GetModuleFileName(),
+	[misc/commdlg.c]: GetFileTitle(),
+	[misc/keyboard.c], [misc/lstr.c]: lstrcpyn(),
+	[misc/ole2nls.c], [misc/profile.c], [multimedia/mcistring.c],
+	[multimedia/mmsystem.c], [objects/font.c]:
+	Use wine_strncpy() where strings are returned to Windows programs.
+	
+	* [objects/metafile.c]
+	PlayMetafile(): Clear the handle table before using it.
+
+	* [misc/shell.c] [misc/main.c]
+	Rename SHELL_RegCheckForRoot() to SHELL_Init() and call it from main().
+	
+	* [misc/profile.c]
+	load(): Need to handle comments.
+	
+	* [toolkit/libres.c]
+	Make it compile.
+	
+	* [windows/nonclient.c]
+	Use MAKE_SEGPTR macro in two places where a user heap block used
+	to be allocated instead.
+
+Sat Dec 02 16:43:43 1995 Ramon Garcia <ramon@ie3.clubs.etsit.upm.es>
+
+	* [windows/winpos.c]
+	In function SetWindowPos: do not redraw the parent of
+	a window if the specified window is placed on the top.
+	This avoids that ShowWindow(hwnd,1) hides hwnd instead
+	of showing it.
+
+Sat Dec 02 11:00:00 1995 Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+	* [windows/scroll.c]
+	Now it can scroll children along with the client region of parent 
+        window. Tried to optimize update region calculation. 
+
+	* [windows/mdi.c]
+	ScrollChildren function, more other features added. Basically
+	a rewrite.
+
+	* [windows/winpos.c] [windows/focus.c]
+	Reimplemented window activation and focus handling.
+
+	* [windows/nonclient.c]
+	Added new flag WIN_NCACTIVATED.
+
+	* [windows/message.c] [loader/task.c]
+	Small changes (to maintain linked list of message queues).
+
+Wed Nov 29 15:51:48 1995  Daniel Schepler  <daniel@shep13.wustl.edu>
+
+	* [include/options.h] [misc/main.c] [windows/defwnd.c]
+	  [windows/event.c] [windows/nonclient.c] [windows/win.c] [Wine.man]
+	Implemented a -managed option to replace the standard Windows
+	frame of top-level windows with the window manager's decorations.
+	If a top-level window makes its own frame, this will still show
+	up, inside the window manager decorations (I believe ctl3dv2.dll
+	would do this, although I can't test this).
+
+----------------------------------------------------------------------
 Tue Nov 21 18:49:10 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>
 
 	* [configure.in] [Makefile] [misc/dos_fs.c]
diff --git a/Wine.man b/Wine.man
index 789a503..f585a53 100644
--- a/Wine.man
+++ b/Wine.man
@@ -67,6 +67,14 @@
 .I -debug
 Enter the debugger before starting application
 .TP
+.I -language xx
+Set the language to
+.I xx
+(one of En, Es, De, No, Fr, Fi, Da)
+.TP
+.I -managed
+Create each top-level window as a properly managed X window
+.TP
 .I -name name
 Set the application name
 .TP
diff --git a/controls/combo.c b/controls/combo.c
index bed192e..e82deaa 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -82,7 +82,7 @@
 /***********************************************************************
  *           CBNCCreate
  */
-static LONG CBNCCreate(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBNCCreate(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   CREATESTRUCT *createStruct;
 
@@ -100,7 +100,7 @@
 /***********************************************************************
  *           CBCreate
  */
-static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBCreate(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST   lphl;
   LPHEADCOMBO  lphc;
@@ -178,7 +178,7 @@
 /***********************************************************************
  *           CBDestroy
  */
-static LONG CBDestroy(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
 
@@ -191,7 +191,7 @@
 /***********************************************************************
  *           CBPaint
  */
-static LONG CBPaint(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
@@ -255,7 +255,7 @@
 /***********************************************************************
  *           CBGetDlgCode
  */
-static LONG CBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetDlgCode(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
@@ -263,7 +263,7 @@
 /***********************************************************************
  *           CBLButtonDown
  */
-static LONG CBLButtonDown(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBLButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
   SendMessage(hwnd,CB_SHOWDROPDOWN,!lphc->DropDownVisible,0);
@@ -273,7 +273,7 @@
 /***********************************************************************
  *           CBKeyDown
  */
-static LONG CBKeyDown(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBKeyDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD       newFocused = lphl->ItemFocused;
@@ -312,7 +312,7 @@
 /***********************************************************************
  *           CBChar
  */
-static LONG CBChar(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBChar(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD       newFocused;
@@ -337,7 +337,7 @@
 /***********************************************************************
  *           CBKillFocus
  */
-static LONG CBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBKillFocus(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   return 0;
 }
@@ -345,7 +345,7 @@
 /***********************************************************************
  *           CBSetFocus
  */
-static LONG CBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBSetFocus(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   return 0;
 }
@@ -353,7 +353,7 @@
 /***********************************************************************
  *           CBResetContent
  */
-static LONG CBResetContent(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBResetContent(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
@@ -366,7 +366,7 @@
 /***********************************************************************
  *           CBDir
  */
-static LONG CBDir(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBDir(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   WORD wRet;
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
@@ -380,7 +380,7 @@
 /***********************************************************************
  *           CBInsertString
  */
-static LONG CBInsertString(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBInsertString(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   WORD  wRet;
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
@@ -398,7 +398,7 @@
 /***********************************************************************
  *           CBAddString
  */
-static LONG CBAddString(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBAddString(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   WORD  wRet;
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
@@ -416,7 +416,7 @@
 /***********************************************************************
  *           CBDeleteString
  */
-static LONG CBDeleteString(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBDeleteString(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
@@ -429,7 +429,7 @@
 /***********************************************************************
  *           CBSelectString
  */
-static LONG CBSelectString(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBSelectString(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD  wRet;
@@ -444,7 +444,7 @@
 /***********************************************************************
  *           CBFindString
  */
-static LONG CBFindString(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBFindString(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxFindString(lphl, wParam, lParam);
@@ -453,7 +453,7 @@
 /***********************************************************************
  *           CBGetCount
  */
-static LONG CBGetCount(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetCount(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return lphl->ItemsCount;
@@ -462,7 +462,7 @@
 /***********************************************************************
  *           CBSetCurSel
  */
-static LONG CBSetCurSel(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBSetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD  wRet;
@@ -478,7 +478,7 @@
 /***********************************************************************
  *           CBGetCurSel
  */
-static LONG CBGetCurSel(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return lphl->ItemFocused;
@@ -487,7 +487,7 @@
 /***********************************************************************
  *           CBGetItemHeight
  */
-static LONG CBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetItemHeight(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);
@@ -499,7 +499,7 @@
 /***********************************************************************
  *           CBSetItemHeight
  */
-static LONG CBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBSetItemHeight(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxSetItemHeight(lphl, wParam, lParam);
@@ -508,7 +508,7 @@
 /***********************************************************************
  *           CBSetRedraw
  */
-static LONG CBSetRedraw(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBSetRedraw(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   lphl->bRedrawFlag = wParam;
@@ -518,7 +518,7 @@
 /***********************************************************************
  *           CBSetFont
  */
-static LONG CBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT CBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST  lphl = ComboGetListHeader(hwnd);
 
@@ -533,7 +533,7 @@
 /***********************************************************************
  *           CBGetLBTextLen
  */
-static LONG CBGetLBTextLen(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetLBTextLen(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST   lphl = ComboGetListHeader(hwnd);
   LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);
@@ -545,7 +545,7 @@
 /***********************************************************************
  *           CBGetLBText
  */
-static LONG CBGetLBText(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetLBText(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
@@ -554,7 +554,7 @@
 /***********************************************************************
  *           CBGetItemData
  */
-static LONG CBGetItemData(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBGetItemData(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxGetItemData(lphl, wParam);
@@ -563,7 +563,7 @@
 /***********************************************************************
  *           CBSetItemData
  */
-static LONG CBSetItemData(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBSetItemData(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxSetItemData(lphl, wParam, lParam);
@@ -572,7 +572,7 @@
 /***********************************************************************
  *           CBShowDropDown
  */
-static LONG CBShowDropDown(HWND hwnd, WORD wParam, LONG lParam)
+static LRESULT CBShowDropDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
   RECT rect;
@@ -650,7 +650,7 @@
 /***********************************************************************
  *           CBLCreate
  */
-static LONG CBLCreate( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLCreate( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   CREATESTRUCT *createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
 #ifdef WINELIB32
@@ -664,7 +664,7 @@
 /***********************************************************************
  *           CBLGetDlgCode
  */
-static LONG CBLGetDlgCode( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLGetDlgCode( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
@@ -672,7 +672,7 @@
 /***********************************************************************
  *           CBLKeyDown
  */
-static LONG CBLKeyDown( HWND hwnd, WORD wParam, LONG lParam ) 
+static LRESULT CBLKeyDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) 
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   WORD newFocused = lphl->ItemFocused;
@@ -720,7 +720,7 @@
 /***********************************************************************
  *           CBLChar
  */
-static LONG CBLChar( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLChar( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   return 0;
 }
@@ -728,7 +728,7 @@
 /***********************************************************************
  *           CBLPaint
  */
-static LONG CBLPaint( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLPaint( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST   lphl = CLBoxGetListHeader(hwnd);
   LPLISTSTRUCT lpls;
@@ -805,7 +805,7 @@
 /***********************************************************************
  *           CBLKillFocus
  */
-static LONG CBLKillFocus( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLKillFocus( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
 /*  SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);*/
   return 0;
@@ -814,7 +814,7 @@
 /***********************************************************************
  *           CBLActivate
  */
-static LONG CBLActivate( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLActivate( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   if (wParam == WA_INACTIVE)
     SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
@@ -824,7 +824,7 @@
 /***********************************************************************
  *           CBLLButtonDown
  */
-static LONG CBLLButtonDown( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   int        y;
@@ -849,7 +849,7 @@
 /***********************************************************************
  *           CBLLButtonUp
  */
-static LONG CBLLButtonUp( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLLButtonUp( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
 
@@ -873,7 +873,7 @@
 /***********************************************************************
  *           CBLMouseMove
  */
-static LONG CBLMouseMove( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   int  y;
@@ -916,7 +916,7 @@
 /***********************************************************************
  *           CBLVScroll
  */
-static LONG CBLVScroll( HWND hwnd, WORD wParam, LONG lParam )
+static LRESULT CBLVScroll( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   int  y;
diff --git a/controls/edit.c b/controls/edit.c
index 04383fb..8663d40 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -2210,10 +2210,13 @@
     EndPaint(hwnd, &ps);
 }
 
-static BOOL LOCAL_HeapExists(WORD ds)
+static BOOL LOCAL_HeapExists(HANDLE ds)
 {
+/* There is always a local heap in WineLib */
+#ifndef WINELIB
     INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 );
     if (!ptr->heap) return 0;
+#endif
     return 1;
 }
 
@@ -2249,7 +2252,7 @@
     {
         DWORD globalSize;
         globalSize = GlobalSize(ds);
-        printf("No local heap allocated global size is %d 0x%x\n",globalSize, globalSize);
+        dprintf_edit(stddeb, "No local heap allocated global size is %ld 0x%lx\n",globalSize, globalSize);
         /*
          * I assume the local heap should start at 0 
          */
diff --git a/controls/listbox.c b/controls/listbox.c
index a215ec3..0beca3e 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -111,8 +111,13 @@
   HeapBase = GlobalLock(HeapHandle);
   HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE);
 #endif
+/* WINELIBS list boxes do not operate on local heaps */
+#ifndef WINELIB
   lphl->HeapSel = GlobalAlloc(GMEM_FIXED,LIST_HEAP_SIZE);
   LocalInit( lphl->HeapSel, 0, LIST_HEAP_SIZE-1);
+#else
+  lphl->HeapSel = 0;
+#endif
 }
 
 void DestroyListBoxStruct(LPHEADLIST lphl)
@@ -896,6 +901,8 @@
   int        y;
   RECT       rectsel;
   LONG	     dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
+  POINT      tmpPOINT;
+  tmpPOINT.x = LOWORD(lParam); tmpPOINT.y = HIWORD(lParam);
 
   SetFocus(hwnd);
   SetCapture(hwnd);
@@ -928,11 +935,11 @@
 
   if (dwStyle & LBS_NOTIFY)
     SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam);
-
+#ifndef WINELIB
   if (GetWindowLong(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT)
-     if( DragDetect(lphl->hSelf,MAKEPOINT(lParam)) )
+     if( DragDetect(lphl->hSelf,tmpPOINT) )
          SendMessage(lphl->hParent, WM_BEGINDRAG,0,0L);
-
+#endif
   return 0;
 }
 
diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec
index 2676a5c..b5de7d9 100644
--- a/if1632/advapi32.spec
+++ b/if1632/advapi32.spec
@@ -127,11 +127,11 @@
 0123 stub QueryServiceStatus
 0124 stub ReadEventLogA
 0125 stub ReadEventLogW
-0126 stub RegCloseKey
+0126 	stdcall RegCloseKey(long) RegCloseKey
 0127 stub RegConnectRegistryA
 0128 stub RegConnectRegistryW
 0129 stub RegCreateKeyA
-0130 stub RegCreateKeyExA
+0130 	stdcall RegCreateKeyExA(long ptr long ptr long long ptr ptr ptr) RegCreateKeyEx
 0131 stub RegCreateKeyExW
 0132 stub RegCreateKeyW
 0133 stub RegDeleteKeyA
@@ -158,7 +158,7 @@
 0154 stub RegQueryMultipleValuesA
 0155 stub RegQueryMultipleValuesW
 0156 stub RegQueryValueA
-0157 stub RegQueryValueExA
+0157 	stdcall RegQueryValueExA(long ptr long long ptr ptr) RegQueryValueEx
 0158 stub RegQueryValueExW
 0159 stub RegQueryValueW
 0160 stub RegRemapPreDefKey
@@ -170,7 +170,7 @@
 0166 stub RegSaveKeyW
 0167 stub RegSetKeySecurity
 0168 stub RegSetValueA
-0169 stub RegSetValueExA
+0169 	stdcall RegSetValueExA(long ptr long long ptr long) RegSetValueEx
 0170 stub RegSetValueExW
 0171 stub RegSetValueW
 0172 stub RegUnLoadKeyA
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 7f9b7c6..2899a60 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -256,11 +256,11 @@
 346 pascal16 IsBadHugeReadPtr(segptr long) IsBadHugeReadPtr
 347 pascal16 IsBadHugeWritePtr(segptr long) IsBadHugeWritePtr
 348 pascal hmemcpy(ptr ptr long) hmemcpy
-349 pascal16 _hread(word ptr long) _hread
-350 pascal16 _hwrite(word ptr long) _hwrite
+349 pascal _hread(word ptr long) _hread
+350 pascal _hwrite(word ptr long) _hwrite
 #351 BUNNY_351
 352 stub lstrcatn
-353 pascal lstrcpyn(segptr segptr word) lstrcpyn
+353 pascal lstrcpyn(segptr segptr word) WIN16_lstrcpyn
 354 stub GetAppCompatFlags
 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo
 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index e9e9abf..bb122a0 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -44,16 +44,16 @@
 0040 stub CreateDirectoryExA
 0041 stub CreateDirectoryExW
 0042 stub CreateDirectoryW
-0043 stub CreateEventA
+0043 	stdcall CreateEventA(ptr long long ptr) CreateEventA
 0044 stub CreateEventW
 0045   stdcall CreateFileA(ptr long long ptr long long long) CreateFileA
-0046 stub CreateFileMappingA
+0046 	stdcall CreateFileMappingA(long ptr long long long ptr) CreateFileMapping
 0047 stub CreateFileMappingW
 0048 stub CreateFileW
 0049 stub CreateIoCompletionPort
 0050 stub CreateMailslotA
 0051 stub CreateMailslotW
-0052 stub CreateMutexA
+0052 	stdcall CreateMutexA(ptr long ptr) CreateMutexA
 0053 stub CreateMutexW
 0054 stub CreateNamedPipeA
 0055 stub CreateNamedPipeW
@@ -79,7 +79,7 @@
 0075 stub DisconnectNamedPipe
 0076 stub DosDateTimeToFileTime
 0077 stub DuplicateConsoleHandle
-0078 stub DuplicateHandle
+0078 	stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle
 0079 stub EndUpdateResourceA
 0080 stub EndUpdateResourceW
 0081 stub EnterCriticalSection
@@ -199,9 +199,9 @@
 0195 stub GetCurrentConsoleFont
 0196 stub GetCurrentDirectoryA
 0197 stub GetCurrentDirectoryW
-0198 stub GetCurrentProcess
+0198 	stdcall GetCurrentProcess() GetCurrentProcess
 0199 stdcall GetCurrentProcessId() GetCurrentThreadId
-0200 stub GetCurrentThread
+0200 	stdcall GetCurrentThread() GetCurrentThread
 0201	stdcall GetCurrentThreadId()	GetCurrentThreadId
 0202 stub GetDateFormatA
 0203 stub GetDateFormatW
@@ -229,7 +229,7 @@
 0225 stub GetHandleInformation
 0226 stub GetLargestConsoleWindowSize
 0227    stdcall GetLastError() GetLastError
-0228 stub GetLocalTime
+0228    stdcall GetLocalTime(ptr) GetLocalTime
 0229 stub GetLocaleInfoA
 0230 stub GetLocaleInfoW
 0231 stub GetLogicalDriveStringsA
@@ -388,7 +388,7 @@
 0383 stub LockFileEx
 0384 stub LockResource
 0385 stub MapViewOfFile
-0386 stub MapViewOfFileEx
+0386 	stdcall MapViewOfFileEx(long long long long long long) MapViewOfFileEx
 0387 stub MoveFileA
 0388 stub MoveFileExA
 0389 stub MoveFileExW
@@ -399,7 +399,7 @@
 0394 stub OpenEventA
 0395 stub OpenEventW
 0396 stub OpenFile
-0397 stub OpenFileMappingA
+0397 	stdcall OpenFileMappingA(long long ptr) OpenFileMapping
 0398 stub OpenFileMappingW
 0399 stub OpenMutexA
 0400 stub OpenMutexW
@@ -437,11 +437,11 @@
 0432 stub RegisterWaitForInputIdle
 0433 stub RegisterWowBaseHandlers
 0434 stub RegisterWowExec
-0435 stub ReleaseMutex
+0435 	stdcall ReleaseMutex(long) ReleaseMutex
 0436 stub ReleaseSemaphore
 0437 stub RemoveDirectoryA
 0438 stub RemoveDirectoryW
-0439 stub ResetEvent
+0439 	stdcall ResetEvent(long) ResetEvent
 0440 stub ResumeThread
 0441 stub RtlFillMemory
 0442 stub RtlMoveMemory
@@ -489,7 +489,7 @@
 0484    stdcall SetEnvironmentVariableA(ptr ptr) SetEnvironmentVariableA
 0485 stub SetEnvironmentVariableW
 0486 stub SetErrorMode
-0487 stub SetEvent
+0487 	stdcall	SetEvent(long) SetEvent
 0488 stub SetFileApisToANSI
 0489 stub SetFileApisToOEM
 0490 stub SetFileAttributesA
@@ -563,7 +563,7 @@
 0558 stub WaitForDebugEvent
 0559 stub WaitForMultipleObjects
 0560 stub WaitForMultipleObjectsEx
-0561 stub WaitForSingleObject
+0561 	stdcall WaitForSingleObject(long long) WaitForSingleObject
 0562 stub WaitForSingleObjectEx
 0563 stub WaitNamedPipeA
 0564 stub WaitNamedPipeW
diff --git a/if1632/relay32.c b/if1632/relay32.c
index 0d906d4..67c6461 100644
--- a/if1632/relay32.c
+++ b/if1632/relay32.c
@@ -13,6 +13,7 @@
 #include "windows.h"
 #include "dlls.h"
 #include "pe_image.h"
+#include "peexe.h"
 #include "relay32.h"
 #include "stddebug.h"
 /* #define DEBUG_RELAY */
@@ -48,8 +49,12 @@
 WIN32_builtin *RELAY32_GetBuiltinDLL(char *name)
 {
 	WIN32_builtin *it;
+	size_t len;
+	char *cp;
+
+	len = (cp=strchr(name,'.')) ? (cp-name) : strlen(name);
 	for(it=WIN32_builtin_list;it;it=it->next)
-	if(strcasecmp(name,it->name)==0)
+	if(strncasecmp(name,it->name,len)==0)
 		return it;
 	return NULL;
 }
@@ -71,10 +76,57 @@
 {
 	WIN32_builtin *dll;
 	int i;
+  	u_short * ordinal;
+  	u_long * function;
+  	u_char ** name, *ename;
+	struct PE_Export_Directory * pe_exports;
+	unsigned int load_addr;
+
 	dprintf_module(stddeb, "Looking for %s in %s, hint %x\n",
 		item ? item: "(no name)", dll_name, hint);
 	dll=RELAY32_GetBuiltinDLL(dll_name);
-	if(!dll)return 0;
+	if(!dll) {
+		if(!wine_files || !wine_files->name ||
+		   strcasecmp(dll_name, wine_files->name)) {
+			LoadModule(dll_name, (LPVOID) -1);
+			if(!wine_files || !wine_files->name ||
+		   	   strcasecmp(dll_name, wine_files->name)) 
+				return 0;
+		}
+		load_addr = wine_files->load_addr;
+		pe_exports = wine_files->pe->pe_export;
+  		ordinal = (u_short *) (((char *) load_addr) + (int) pe_exports->Address_Of_Name_Ordinals);
+  		function = (u_long *)  (((char *) load_addr) + (int) pe_exports->AddressOfFunctions);
+  		name = (u_char **)  (((char *) load_addr) + (int) pe_exports->AddressOfNames);
+		/* import by ordinal */
+		if(!item){
+			return 0;
+		}
+		/* hint is correct */
+		#if 0
+		if(hint && hint<dll->size && 
+			dll->functions[hint].name &&
+			strcmp(item,dll->functions[hint].name)==0)
+			return dll->functions[hint].definition;
+		#endif
+		/* hint is incorrect, search for name */
+		for(i=0;i<pe_exports->Number_Of_Functions;i++)
+	            if (name[i] && !strcmp(item,name[i]+load_addr))
+	                return function[i]+(char *)load_addr;
+	
+		/* function at hint has no name (unimplemented) */
+		#if 0
+		if(hint && hint<dll->size && !dll->functions[hint].name)
+		{
+			dll->functions[hint].name=strdup(item);
+			dprintf_module(stddeb, "Returning unimplemented function %s.%d\n",
+				dll_name,hint);
+			return dll->functions[hint].definition;
+		}
+		#endif
+		printf("Not found\n");
+		return 0;
+	}
 	/* import by ordinal */
 	if(!item){
 		if(hint && hint<dll->size)return dll->functions[hint].definition;
diff --git a/if1632/user.spec b/if1632/user.spec
index fae1cc0..240daa5 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -409,7 +409,7 @@
 460 pascal16 GetInternalWindowPos(word ptr ptr) GetInternalWindowPos
 461 pascal16 SetInternalWindowPos(word word ptr ptr) SetInternalWindowPos
 462 pascal16 CalcChildScroll(word word) CalcChildScroll
-463 stub ScrollChildren
+463 pascal16 ScrollChildren(word word word long) ScrollChildren
 464 pascal   DragObject(word word word word word word) DragObject
 465 pascal16 DragDetect(word long) DragDetect
 466 pascal16 DrawFocusRect(word ptr) DrawFocusRect
diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec
index b770e4d..e564fa5 100644
--- a/if1632/winprocs.spec
+++ b/if1632/winprocs.spec
@@ -29,6 +29,7 @@
 26 register Win32CallToStart() PE_Win32CallToStart
 27 pascal EntryAddrProc(word word) MODULE_GetEntryPoint
 28 pascal MyAlloc(word word word) MODULE_AllocateSegment
+29 pascal16 ActivateAppProc(word long) ACTIVATEAPP_callback
 
 # Interrupt vectors 0-255 are ordinals 100-355
 # The 'word' parameter are the flags pushed on the stack by the interrupt
diff --git a/include/advapi32.h b/include/advapi32.h
new file mode 100644
index 0000000..634c3f4
--- /dev/null
+++ b/include/advapi32.h
@@ -0,0 +1,31 @@
+#ifndef __WINE_ADVAPI32_H
+#define __WINE_ADVAPI32_H
+#include "shell.h"
+#include "kernel32.h"
+#define REGSAM long
+BOOL WINAPI GetUserNameA (char * lpBuffer, DWORD  *nSize);
+WINAPI LONG RegCreateKeyEx(HKEY key,
+                            const char *subkey,
+                            long dontuse,
+                            const char *keyclass,
+                            DWORD options,
+                            REGSAM sam,
+                            SECURITY_ATTRIBUTES *atts,
+                            HKEY *res,
+                            DWORD *disp);
+WINAPI LONG RegSetValueExA (HKEY key,
+                const char *name,
+                DWORD dontuse,
+                DWORD type,
+                const void* data,
+                DWORD len
+                );
+WINAPI LONG RegQueryValueExA(HKEY key,
+                             const char *subkey,
+                             DWORD dontuse,
+                             DWORD *type,
+                             void *ptr,
+                             DWORD *len);
+
+
+#endif  /* __WINE_ADVAPI32_H */
diff --git a/include/dlls.h b/include/dlls.h
index 4b4b606..89c434a 100644
--- a/include/dlls.h
+++ b/include/dlls.h
@@ -12,10 +12,6 @@
 #define MAX_NAME_LENGTH		64
 
 
-#define DLL	0
-#define EXE	1
-
-
 struct dll_table_s
 {
     char *  name;          /* DLL name */
diff --git a/include/handle32.h b/include/handle32.h
index f4e0d9e..e6d07a7 100644
--- a/include/handle32.h
+++ b/include/handle32.h
@@ -41,6 +41,13 @@
 } FILE_OBJECT;
 
 typedef struct {
+    KERNEL_OBJECT	common;
+    FILE_OBJECT	       *file_obj;
+    int			prot;
+    unsigned long	size;
+} FILEMAP_OBJECT;
+
+typedef struct {
     KERNEL_OBJECT       common;
 } SEMAPHORE_OBJECT;
 
@@ -65,6 +72,7 @@
 #define KERNEL_OBJECT_SEMAPHORE (KERNEL_OBJECT_UNUSED + 4)
 #define KERNEL_OBJECT_EVENT     (KERNEL_OBJECT_UNUSED + 5)
 #define KERNEL_OBJECT_REGKEY    (KERNEL_OBJECT_UNUSED + 6)
+#define KERNEL_OBJECT_FILEMAP   (KERNEL_OBJECT_UNUSED + 7)
 
 /* Define the invalid handle value
  */
diff --git a/include/kernel32.h b/include/kernel32.h
index dd38cdc..501e8d8 100644
--- a/include/kernel32.h
+++ b/include/kernel32.h
@@ -106,11 +106,14 @@
 #define STD_OUTPUT_HANDLE       ((DWORD) -11)
 #define STD_ERROR_HANDLE        ((DWORD) -12)
 
-/* The security attributes structure (not filled in yet)
+/* The security attributes structure 
  */
 typedef struct {
-    void *junk;
+    DWORD nLength;
+    void *lpSecurityDescriptor;
+    BOOL bInheritHandle;
 } SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
+
 typedef struct
 {
   int dwLowDateTime;
@@ -131,4 +134,17 @@
   int nFileIndexLow;
 } BY_HANDLE_FILE_INFORMATION ;
 
+/* File attribute flags
+ */
+#define FILE_ATTRIBUTE_ARCHIVE          0x0020
+#define FILE_ATTRIBUTE_COMPRESSED       0x0800
+#define FILE_ATTRIBUTE_DIRECTORY        0x0010
+#define FILE_ATTRIBUTE_HIDDEN           0x0002
+#define FILE_ATTRIBUTE_NORMAL           0x0080
+#define FILE_ATTRIBUTE_READONLY         0x0001
+#define FILE_ATTRIBUTE_SYSTEM           0x0004
+#define FILE_ATTRIBUTE_TEMPORARY        0x0100
+#define FILE_ATTRIBUTE_ATOMIC_WRITE     0x0200
+#define FILE_ATTRIBUTE_XACTION_WRITE    0x0400
+
 #endif  /* __WINE_KERNEL32_H */
diff --git a/include/libres.h b/include/libres.h
index 68ada6f..918f042 100644
--- a/include/libres.h
+++ b/include/libres.h
@@ -4,16 +4,21 @@
 #ifndef __WINE_LIBRES_H
 #define __WINE_LIBRES_H
 
-#include "windows.h"
-
 #ifdef WINELIB
-HRSRC LIBRES_FindResource( HMODULE hModule, SEGPTR name, SEGPTR type );
-HGLOBAL LIBRES_LoadResource( HMODULE hModule, HRSRC hRsrc );
-LPSTR LIBRES_LockResource( HMODULE hModule, HGLOBAL handle );
-BOOL LIBRES_FreeResource( HMODULE hModule, HGLOBAL handle );
-INT LIBRES_AccessResource( HINSTANCE hModule, HRSRC hRsrc );
-DWORD LIBRES_SizeofResource( HMODULE hModule, HRSRC hRsrc );
-HGLOBAL LIBRES_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size );
-#endif
+
+#include "windows.h"
+#include "resource.h"
+
+void    LIBRES_RegisterResources(struct resource** Res);
+
+INT     LIBRES_AccessResource( HINSTANCE hModule, HRSRC hRsrc );
+HGLOBAL LIBRES_AllocResource( HINSTANCE hModule, HRSRC hRsrc, DWORD size );
+HRSRC   LIBRES_FindResource( HINSTANCE hModule, LPCSTR name, LPCSTR type );
+BOOL    LIBRES_FreeResource( HGLOBAL handle );
+HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc );
+LPVOID  LIBRES_LockResource( HGLOBAL handle );
+DWORD   LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc );
+
+#endif /* WINELIB */
 
 #endif
diff --git a/include/listbox.h b/include/listbox.h
index 1ca0891..e266b8a 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -34,7 +34,7 @@
 	LPINT   TabStops;
 	HANDLE  hDrawItemStruct;
         BOOL    needMeasure;
-	WORD	HeapSel;
+	HANDLE	HeapSel;
 /*	MDESC   *Heap; */
 } HEADLIST,*LPHEADLIST;
 
diff --git a/include/mdi.h b/include/mdi.h
index d2d1434..e7c2573 100644
--- a/include/mdi.h
+++ b/include/mdi.h
@@ -1,6 +1,7 @@
 /* MDI.H
  *
  * Copyright 1994, Bob Amstadt
+ *           1995  Alex Korobka
  *
  * MDI structure definitions.
  */
@@ -10,29 +11,32 @@
 
 #include "windows.h"
 
-#define MDI_MAXLISTLENGTH	64
+#define MDI_MAXLISTLENGTH	0x40
+
+#define WM_MDICALCCHILDSCROLL   0x10AC /* this is exactly what Windows uses */
+
 extern LRESULT MDIClientWndProc(HWND hwnd, UINT message, 
 				WPARAM wParam, LPARAM lParam); /* mdi.c */
 
-
-typedef struct
+typedef struct tagMDIWCL
 {
-    HLOCAL next, prev;
-    HWND hwnd;
-} MDICHILDINFO;
+  HWND		 	 hChild;
+  struct tagMDIWCL	*prev;
+} MDIWCL;
 
 typedef struct 
 {
-    HMENU  hWindowMenu;
-    HLOCAL infoActiveChildren;
     WORD   nActiveChildren;
-    WORD   idFirstChild;
+    HWND   flagChildMaximized;
     HWND   hwndActiveChild;
+    HMENU  hWindowMenu;
+    WORD   idFirstChild;       /* order is 3.1-like up to this point */
+    WORD   sbStop;
+    WORD   sbRecalc;
     HWND   hwndHitTest;
-    BOOL   flagMenuAltered;
-    BOOL   flagChildMaximized;
     RECT   rectMaximize;
     RECT   rectRestore;
 } MDICLIENTINFO;
 
+
 #endif /* MDI_H */
diff --git a/include/message.h b/include/message.h
index e604a41..8956faf 100644
--- a/include/message.h
+++ b/include/message.h
@@ -70,6 +70,8 @@
 extern void MSG_Synchronize();
 extern BOOL MSG_WaitXEvent( LONG maxWait );
 extern BOOL MSG_CreateSysMsgQueue( int size );
+extern BOOL MSG_DeleteMsgQueue( HANDLE hQueue );
+extern HTASK MSG_GetQueueTask( HANDLE hQueue );
 extern void hardware_event( WORD message, WORD wParam, LONG lParam,
 			    int xPos, int yPos, DWORD time, DWORD extraInfo );
 extern BOOL MSG_GetHardwareMessage( LPMSG msg );
diff --git a/include/msdos.h b/include/msdos.h
index 5ee696a..5964d82 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -16,7 +16,6 @@
 	char search_attribute;
 	long filesize;
 	long filetime;
-        int telldirnum;
         short entnum;           /* Directory entry number */
         struct dosdirent *next;
 };
diff --git a/include/options.h b/include/options.h
index 834713c..7d3bbf1 100644
--- a/include/options.h
+++ b/include/options.h
@@ -34,6 +34,7 @@
     int    enhanced;        /* Start Wine in enhanced mode */
     int    ipc;             /* Use IPC mechanisms */
     WINE_LANGUAGE language; /* Current language */
+    int    managed;	    /* Managed windows */
 };
 
 extern struct options Options;
diff --git a/include/pe_image.h b/include/pe_image.h
index a65c756..b83e651 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -25,6 +25,7 @@
     struct mz_header_s *mz_header;
     struct pe_data *pe;
 	OFSTRUCT ofs;
+    unsigned int load_addr;
 };
 
 
@@ -33,6 +34,7 @@
 extern void PE_InitDLL(struct w_files *wpnt);
 extern HINSTANCE PE_LoadImage(struct w_files *wpnt);
 extern void my_wcstombs(char * result, u_short * source, int len);
+extern struct w_files *wine_files;
 
 typedef struct _WIN32_function{
     char *name;
diff --git a/include/peexe.h b/include/peexe.h
index 6f54811..43aa48a 100644
--- a/include/peexe.h
+++ b/include/peexe.h
@@ -167,6 +167,7 @@
   u_long * AddressOfFunctions;
   u_long * AddressOfNames;
   u_short * Address_Of_Name_Ordinals;
+  u_char ModuleName[1];
 };
 
 /*
diff --git a/include/resource.h b/include/resource.h
index d389ce4..26d5897 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -17,12 +17,19 @@
 extern HGLOBAL NE_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size );
 extern HGLOBAL NE_LoadResource( HMODULE hModule,  HRSRC hRsrc );
 
-struct ResourceTable
+struct resource
 {
         int id,type;
         char *name;
-        unsigned char* value;
+        unsigned char* bytes;
         unsigned size;
 };
 
+#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)
+#define WINE_CONSTRUCTOR  __attribute__((constructor))
+#define HAVE_WINE_CONSTRUCTOR
+#else
+#define WINE_CONSTRUCTOR
+#endif
+
 #endif /* __WINE_RESOURCE_H */
diff --git a/include/shell.h b/include/shell.h
index 5a546ec..652f481 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -3,6 +3,9 @@
  */
 
 extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon);
+extern void SHELL_LoadRegistry();
+extern void SHELL_SaveRegistry();
+extern BOOL SHELL_Init();
 
 #define ERROR_SUCCESS           0L
 #define ERROR_BADDB             1L
@@ -33,15 +36,14 @@
 	struct tagKEYSTRUCT *lpPrevKey;
 	struct tagKEYSTRUCT *lpNextKey;
 	struct tagKEYSTRUCT *lpSubLvl;
-	} KEYSTRUCT;
-typedef KEYSTRUCT *LPKEYSTRUCT;
+} KEYSTRUCT, *LPKEYSTRUCT;
 
-typedef struct tagDROPFILESTRUCT { 	   /* structure for dropped files */ 
+typedef struct { 	   /* structure for dropped files */ 
 	WORD		wSize;
 	POINT		ptMousePos;   
 	BOOL		fInNonClientArea;
 	/* memory block with filenames follows */     
-        } DROPFILESTRUCT,FAR *LPDROPFILESTRUCT; 
+} DROPFILESTRUCT, *LPDROPFILESTRUCT; 
 
 #define SE_ERR_SHARE            26
 #define SE_ERR_ASSOCINCOMPLETE  27
diff --git a/include/win.h b/include/win.h
index 49491a2..f5f7ba1 100644
--- a/include/win.h
+++ b/include/win.h
@@ -43,7 +43,6 @@
     POINT        ptMaxPos;       /* Maximized window position */
     HGLOBAL      hmemTaskQ;      /* Task queue global memory handle */
     HRGN         hrgnUpdate;     /* Update region */
-    HWND         hwndPrevActive; /* Previous active top-level window */
     HWND         hwndLastActive; /* Last active popup hwnd */
     WNDPROC      lpfnWndProc;    /* Window procedure */
     DWORD        dwStyle;        /* Window style (from CreateWindow) */
@@ -68,6 +67,7 @@
 #define WIN_INTERNAL_PAINT      0x10  /* Internal WM_PAINT message pending */
 #define WIN_NO_REDRAW           0x20  /* WM_SETREDRAW called for this window */
 #define WIN_GOT_SIZEMSG         0x40  /* WM_SIZE has been sent to the window */
+#define WIN_NCACTIVATED		0x80  /* last WM_NCACTIVATE was positive */
 
 #define WIN_CLASS_INFO(wndPtr)   (CLASS_FindClassPtr((wndPtr)->hClass)->wc)
 #define WIN_CLASS_STYLE(wndPtr)  (WIN_CLASS_INFO(wndPtr).style)
diff --git a/include/windows.h b/include/windows.h
index 02542d0..e0430aa 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1428,22 +1428,69 @@
 
 /* Messages */
 
-enum {  WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE,
-	WM_SETFOCUS, WM_KILLFOCUS, WM_SETVISIBLE, WM_ENABLE, WM_SETREDRAW, 
-	WM_SETTEXT, WM_GETTEXT, WM_GETTEXTLENGTH, WM_PAINT, WM_CLOSE, 
-	WM_QUERYENDSESSION, WM_QUIT, WM_QUERYOPEN, WM_ERASEBKGND, 
-	WM_SYSCOLORCHANGE, WM_ENDSESSION, WM_SYSTEMERROR,
-	WM_SHOWWINDOW, WM_CTLCOLOR, WM_WININICHANGE, WM_DEVMODECHANGE,
-	WM_ACTIVATEAPP, WM_FONTCHANGE, WM_TIMECHANGE, WM_CANCELMODE, WM_SETCURSOR,
-	WM_MOUSEACTIVATE, WM_CHILDACTIVATE, WM_QUEUESYNC, WM_GETMINMAXINFO,
-	WM_UNUSED3, WM_PAINTICON, WM_ICONERASEBKGND, WM_NEXTDLGCTL, 
-	WM_UNUSED4, WM_SPOOLERSTATUS, WM_DRAWITEM, WM_MEASUREITEM, 
-	WM_DELETEITEM, WM_VKEYTOITEM,
-	WM_CHARTOITEM, WM_SETFONT, WM_GETFONT };
+#define WM_NULL                 0x0000
+#define WM_CREATE               0x0001
+#define WM_DESTROY              0x0002
+#define WM_MOVE                 0x0003
+#define WM_SIZEWAIT             0x0004
+#define WM_SIZE                 0x0005
+#define WM_ACTIVATE             0x0006
+#define WM_SETFOCUS             0x0007
+#define WM_KILLFOCUS            0x0008
+#define WM_SETVISIBLE           0x0009
+#define WM_ENABLE               0x000a
+#define WM_SETREDRAW            0x000b
+#define WM_SETTEXT              0x000c
+#define WM_GETTEXT              0x000d
+#define WM_GETTEXTLENGTH        0x000e
+#define WM_PAINT                0x000f
+#define WM_CLOSE                0x0010
+#define WM_QUERYENDSESSION      0x0011
+#define WM_QUIT                 0x0012
+#define WM_QUERYOPEN            0x0013
+#define WM_ERASEBKGND           0x0014
+#define WM_SYSCOLORCHANGE       0x0015
+#define WM_ENDSESSION           0x0016
+#define WM_SYSTEMERROR          0x0017
+#define WM_SHOWWINDOW           0x0018
+#define WM_CTLCOLOR             0x0019
+#define WM_WININICHANGE         0x001a
+#define WM_DEVMODECHANGE        0x001b
+#define WM_ACTIVATEAPP          0x001c
+#define WM_FONTCHANGE           0x001d
+#define WM_TIMECHANGE           0x001e
+#define WM_CANCELMODE           0x001f
+#define WM_SETCURSOR            0x0020
+#define WM_MOUSEACTIVATE        0x0021
+#define WM_CHILDACTIVATE        0x0022
+#define WM_QUEUESYNC            0x0023
+#define WM_GETMINMAXINFO        0x0024
 
-#define WM_QUERYDRAGICON    0x0037
+#define WM_PAINTICON            0x0026
+#define WM_ICONERASEBKGND       0x0027
+#define WM_NEXTDLGCTL           0x0028
+#define WM_ALTTABACTIVE         0x0029
+#define WM_SPOOLERSTATUS        0x002a
+#define WM_DRAWITEM             0x002b
+#define WM_MEASUREITEM          0x002c
+#define WM_DELETEITEM           0x002d
+#define WM_VKEYTOITEM           0x002e
+#define WM_CHARTOITEM           0x002f
+#define WM_SETFONT              0x0030
+#define WM_GETFONT              0x0031
+#define WM_SETHOTKEY            0x0032
+#define WM_GETHOTKEY            0x0033
+#define WM_FILESYSCHANGE        0x0034
+#define WM_ISACTIVEICON         0x0035
+#define WM_QUERYPARKICON        0x0036
+#define WM_QUERYDRAGICON        0x0037
+#define WM_QUERYSAVESTATE       0x0038
+#define WM_COMPAREITEM          0x0039
+#define WM_TESTING              0x003a
 
-#define WM_COMPAREITEM	    0x0039
+#define WM_OTHERWINDOWCREATED	0x003c
+#define WM_OTHERWINDOWDESTROYED	0x003d
+#define WM_ACTIVATESHELLWINDOW	0x003e
 
 #define WM_COMPACTING	    0x0041
 
@@ -1461,6 +1508,7 @@
 
 #define WM_GETDLGCODE	    0x0087
 #define WM_SYNCPAINT	    0x0088
+#define WM_SYNCTASK	    0x0089
 
   /* Non-client mouse messages */
 #define WM_NCMOUSEMOVE      0x00a0
@@ -1532,6 +1580,7 @@
 #define WM_PARENTNOTIFY     0x0210
 #define WM_ENTERMENULOOP    0x0211
 #define WM_EXITMENULOOP     0x0212
+#define WM_NEXTMENU	    0x0213
 
 #define WM_MDICREATE	    0x0220
 #define WM_MDIDESTROY	    0x0221
@@ -1943,10 +1992,6 @@
 #define LBN_SETFOCUS        4
 #define LBN_KILLFOCUS       5
 
-/* Listbox notification messages */
-#define WM_VKEYTOITEM       0x002E
-#define WM_CHARTOITEM       0x002F
-
 /* Listbox message return values */
 #define LB_OKAY             0
 #define LB_ERR              (-1)
@@ -2095,8 +2140,6 @@
 #define EN_VSCROLL      0x0602
 
 
-#define WM_DRAWITEM         0x002B
-
 typedef struct
 {
     UINT        CtlType;
@@ -2112,8 +2155,6 @@
 typedef DRAWITEMSTRUCT NEAR* PDRAWITEMSTRUCT;
 typedef DRAWITEMSTRUCT FAR* LPDRAWITEMSTRUCT;
 
-#define WM_MEASUREITEM      0x002C
-
 typedef struct
 {
     UINT        CtlType;
@@ -2126,8 +2167,6 @@
 typedef MEASUREITEMSTRUCT NEAR* PMEASUREITEMSTRUCT;
 typedef MEASUREITEMSTRUCT FAR* LPMEASUREITEMSTRUCT;
 
-#define WM_DELETEITEM       0x002D
-
 typedef struct
 {
     UINT       CtlType;
@@ -2139,8 +2178,6 @@
 typedef DELETEITEMSTRUCT NEAR* PDELETEITEMSTRUCT;
 typedef DELETEITEMSTRUCT FAR* LPDELETEITEMSTRUCT;
 
-#define WM_COMPAREITEM      0x0039
-
 typedef struct
 {
     UINT        CtlType;
@@ -2499,13 +2536,14 @@
 UINT       AnsiUpperBuff(LPSTR,UINT);
 BOOL       AnyPopup(void);
 BOOL       AppendMenu(HMENU,UINT,UINT,LPSTR);
-BOOL       Arc(HDC,int,int,int,int,int,int,int,int);
+BOOL       Arc(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
 WORD       ArrangeIconicWindows(HWND);
 HDWP       BeginDeferWindowPos(INT);
 HDC        BeginPaint(HWND,LPPAINTSTRUCT);
-BOOL       BitBlt(HDC,short,short,short,short,HDC,short,short,DWORD);
+BOOL       BitBlt(HDC,INT,INT,INT,INT,HDC,INT,INT,DWORD);
 BOOL       BringWindowToTop(HWND);
 int        BuildCommDCB(LPSTR,DCB*);
+void       CalcChildScroll(HWND,WORD);
 BOOL       CallMsgFilter(SEGPTR,short);
 DWORD      CallNextHookEx(HHOOK,short,WPARAM,LPARAM);
 LONG       CallWindowProc(WNDPROC,HWND,UINT,WPARAM,LPARAM);
@@ -2517,7 +2555,7 @@
 BOOL       CheckMenuItem(HMENU,UINT,UINT);
 void       CheckRadioButton(HWND,WORD,WORD,WORD);
 HWND       ChildWindowFromPoint(HWND,POINT);
-BOOL       Chord(HDC,int,int,int,int,int,int,int,int);
+BOOL       Chord(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
 int        ClearCommBreak(int);
 void       ClientToScreen(HWND,LPPOINT);
 void       ClipCursor(LPRECT);
@@ -2600,13 +2638,13 @@
 BOOL       DlgDirSelect(HWND,LPSTR,int);
 BOOL       DlgDirSelectComboBox(HWND,LPSTR,int);
 BOOL       DragDetect(HWND,POINT);
-DWORD      DragObject(HWND, HWND, WORD, WORD, WORD, HCURSOR);
+DWORD      DragObject(HWND, HWND, WORD, HANDLE, WORD, HCURSOR);
 void       DrawFocusRect(HDC,LPRECT);
 BOOL       DrawIcon(HDC,short,short,HICON);
 void       DrawMenuBar(HWND);
 int        DrawText(HDC,LPSTR,int,LPRECT,WORD);
 DWORD      DumpIcon(SEGPTR,WORD*,SEGPTR*,SEGPTR*);
-BOOL       Ellipse(HDC,int,int,int,int);
+BOOL       Ellipse(HDC,INT,INT,INT,INT);
 BOOL       EmptyClipboard(void);
 BOOL       EnableHardwareInput(BOOL);
 BOOL       EnableMenuItem(HMENU,UINT,UINT);
@@ -2640,7 +2678,7 @@
 BOOL       FillRgn(HDC,HRGN,HBRUSH);
 void       FillWindow(HWND,HWND,HDC,HBRUSH);
 ATOM       FindAtom(SEGPTR);
-HANDLE     FindResource(HANDLE,SEGPTR,SEGPTR);
+HRSRC      FindResource(HINSTANCE,SEGPTR,SEGPTR);
 HWND       FindWindow(SEGPTR,LPSTR);
 BOOL       FlashWindow(HWND,BOOL);
 BOOL       FloodFill(HDC,INT,INT,COLORREF);
@@ -2650,7 +2688,7 @@
 void       FreeLibrary(HANDLE);
 BOOL       FreeModule(HANDLE);
 void       FreeProcInstance(FARPROC);
-BOOL       FreeResource(HANDLE);
+BOOL       FreeResource(HGLOBAL);
 WORD       FreeSelector(WORD);
 UINT       GDIRealizePalette(HDC);
 HPALETTE   GDISelectPalette(HDC,HPALETTE);
@@ -2897,7 +2935,7 @@
 HMENU      LoadMenu(HANDLE,SEGPTR);
 HMENU      LoadMenuIndirect(LPSTR);
 HANDLE     LoadModule(LPCSTR,LPVOID);
-HANDLE     LoadResource(HANDLE,HANDLE);
+HGLOBAL    LoadResource(HINSTANCE,HRSRC);
 int        LoadString(HANDLE,WORD,LPSTR,int);
 HANDLE     LocalAlloc(WORD,WORD);
 #ifndef WINELIB32 /* Obsolete in Win32 */
@@ -2915,7 +2953,7 @@
 #endif
 UINT       LocalSize(HLOCAL);
 BOOL       LocalUnlock(HANDLE);
-LPSTR      LockResource(HANDLE);
+LPVOID     LockResource(HGLOBAL);
 HGLOBAL    LockSegment(HGLOBAL);
 HMENU      LookupMenuHandle(HMENU,INT);
 FARPROC    MakeProcInstance(FARPROC,HANDLE);
@@ -2949,7 +2987,7 @@
 BOOL       PaintRgn(HDC,HRGN);
 BOOL       PatBlt(HDC,short,short,short,short,DWORD);
 BOOL       PeekMessage(LPMSG,HWND,WORD,WORD,WORD);
-BOOL       Pie(HDC,int,int,int,int,int,int,int,int);
+BOOL       Pie(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
 BOOL       PlayMetaFile(HDC,HANDLE);
 void       PlayMetaFileRecord(HDC,LPHANDLETABLE,LPMETARECORD,WORD);
 BOOL       PolyPolygon(HDC,LPPOINT,LPINT,WORD);
@@ -2975,7 +3013,7 @@
 UINT       RealizePalette(HDC);
 BOOL       RectInRegion(HRGN,LPRECT);
 BOOL       RectVisible(HDC,LPRECT);
-BOOL       Rectangle(HDC,int,int,int,int);
+BOOL       Rectangle(HDC,INT,INT,INT,INT);
 BOOL       RedrawWindow(HWND,LPRECT,HRGN,UINT);
 ATOM       RegisterClass(LPWNDCLASS);
 WORD       RegisterClipboardFormat(LPCSTR);
@@ -2989,7 +3027,7 @@
 BOOL       ResizePalette(HPALETTE,UINT);
 BOOL       RestoreDC(HDC,short);
 int        RestoreVisRgn(HDC);
-BOOL       RoundRect(HDC,short,short,short,short,short,short);
+BOOL       RoundRect(HDC,INT,INT,INT,INT,INT,INT);
 int        SaveDC(HDC);
 HRGN       SaveVisRgn(HDC);
 DWORD      ScaleViewportExt(HDC,short,short,short,short);
@@ -2997,6 +3035,7 @@
 DWORD      ScaleWindowExt(HDC,short,short,short,short);
 BOOL       ScaleWindowExtEx(HDC,short,short,short,short,LPSIZE);
 void       ScreenToClient(HWND,LPPOINT);
+void       ScrollChildren(HWND,UINT,WPARAM,LPARAM);
 BOOL       ScrollDC(HDC,short,short,LPRECT,LPRECT,HRGN,LPRECT);
 void       ScrollWindow(HWND,short,short,LPRECT,LPRECT);
 int        ScrollWindowEx(HWND,short,short,LPRECT,LPRECT,HRGN,LPRECT,WORD);
@@ -3103,7 +3142,7 @@
 void       ShowOwnedPopups(HWND,BOOL);
 void       ShowScrollBar(HWND,WORD,BOOL);
 BOOL       ShowWindow(HWND,int);
-DWORD      SizeofResource(HANDLE,HRSRC);
+DWORD      SizeofResource(HINSTANCE,HRSRC);
 int        StartSound(void);
 int        StopSound(void);
 BOOL       StretchBlt(HDC,short,short,short,short,HDC,short,short,short,short,DWORD);
@@ -3139,6 +3178,7 @@
 WORD       VkKeyScan(WORD);
 SEGPTR     WIN16_GlobalLock(HGLOBAL);
 SEGPTR     WIN16_LockResource(HANDLE);
+SEGPTR     WIN16_lstrcpyn(SEGPTR,SEGPTR,WORD);
 void       WaitMessage(void);
 int        WaitSoundState(int);
 HANDLE     WinExec(LPSTR,WORD);
@@ -3160,7 +3200,7 @@
 INT        lstrcmp(LPCSTR,LPCSTR);
 INT        lstrcmpi(LPCSTR,LPCSTR);
 SEGPTR     lstrcpy(SEGPTR,SEGPTR);
-SEGPTR     lstrcpyn(SEGPTR,SEGPTR,WORD);
+char *     lstrcpyn(char *,char *,int);
 INT        lstrlen(LPCSTR);
 int        wvsprintf(LPSTR,LPSTR,LPSTR);
 
diff --git a/include/winerror.h b/include/winerror.h
index ec4ba25..67e8d71 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -7,6 +7,21 @@
  */
 #define     ERROR_UNKNOWN               99999
 
+#define     ERROR_FILE_NOT_FOUND        2
+#define     ERROR_TOO_MANY_OPEN_FILES   4
+#define     ERROR_ACCESS_DENIED         5
 #define     ERROR_INVALID_HANDLE        6
+#define     ERROR_BAD_FORMAT            11
+#define     ERROR_OUTOFMEMORY           14
+#define     ERROR_FILE_EXISTS           80
 #define     ERROR_INVALID_PARAMETER     87
+#define     ERROR_BROKEN_PIPE           109
+#define     ERROR_DISK_FULL             112
 #define     ERROR_CALL_NOT_IMPLEMENTED  120
+#define     ERROR_SEEK_ON_DEVICE        132
+#define     ERROR_DIR_NOT_EMPTY         145
+#define     ERROR_BUSY                  170
+#define     ERROR_FILENAME_EXCED_RANGE  206
+#define     ERROR_IO_DEVICE             1117
+#define     ERROR_POSSIBLE_DEADLOCK     1131
+#define     ERROR_BAD_DEVICE            1200
diff --git a/include/winpos.h b/include/winpos.h
index 68edbd8..56cabb7 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -19,8 +19,15 @@
     WINDOWPOS   winPos[1];
 } DWP;
 
+typedef struct
+{
+  HTASK        hWindowTask;
+  HTASK        hTaskSendTo;
+  BOOL         wFlag;
+} ACTIVATESTRUCT, *LPACTIVATESTRUCT;
 
 extern void WINPOS_FindIconPos( HWND hwnd );
+extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus);
 extern HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg );
 extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
 				   RECT *newWindowRect, RECT *oldWindowRect,
diff --git a/include/wintypes.h b/include/wintypes.h
index eb917b5..0d7689a 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -31,6 +31,7 @@
 typedef LONG WPARAM;
 typedef void* HANDLE;
 typedef void* NPVOID;
+typedef void* SEGPTR;
 #define UIFMT "%u"
 #define NPFMT "%p"
 #else
@@ -39,13 +40,13 @@
 typedef UINT WPARAM;
 typedef WORD HANDLE;
 typedef WORD NPVOID;
+typedef DWORD SEGPTR;
 #define UIFMT "%hu"
 #define NPFMT "%04X"
 #endif
 typedef LONG LPARAM;
 typedef LONG LRESULT;
 typedef DWORD HHOOK;
-typedef DWORD SEGPTR;
 typedef char *LPSTR;
 typedef const char *LPCSTR;
 typedef char *NPSTR;
diff --git a/loader/module.c b/loader/module.c
index 2a95c4a..1137f3d 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1184,8 +1184,7 @@
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
     name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
-    strncpy( lpFileName, name, nSize );
-    lpFileName[nSize-1] = '\0';
+    lstrcpyn( lpFileName, name, nSize );
     dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName );
     return strlen(lpFileName);
 }
diff --git a/loader/pe_image.c b/loader/pe_image.c
index cfd9e08..8a05457 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -5,6 +5,8 @@
  *	based on Eric Youndale's pe-test and:
  *
  *	ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
+ * make that:
+ *	ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP
  */
 
 #include <ctype.h>
@@ -35,8 +37,6 @@
 
 struct w_files *wine_files = NULL;
 
-unsigned int load_addr;
-
 void my_wcstombs(char * result, u_short * source, int len)
 {
   while(len--) {
@@ -76,7 +76,7 @@
   return vaddr;
 };
 
-void dump_exports(struct PE_Export_Directory * pe_exports)
+void dump_exports(struct PE_Export_Directory * pe_exports, unsigned int load_addr)
 { 
   char * Module;
   int i;
@@ -85,7 +85,7 @@
   u_char ** name, *ename;
 
   Module = ((char *) load_addr) + pe_exports->Name;
-  printf("\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n", 
+  dprintf_win32(stddeb,"\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n", 
 	 Module,
 	 pe_exports->Number_Of_Functions,
 	 pe_exports->Number_Of_Names);
@@ -94,15 +94,15 @@
   function = (u_long *)  (((char *) load_addr) + (int) pe_exports->AddressOfFunctions);
   name = (u_char **)  (((char *) load_addr) + (int) pe_exports->AddressOfNames);
 
-  printf("%-32s Ordinal Virt Addr\n", "Function Name");
+  dprintf_win32(stddeb,"%-32s Ordinal Virt Addr\n", "Function Name");
   for(i=0; i< pe_exports->Number_Of_Functions; i++)
     {
       ename =  (char *) (((char *) load_addr) + (int) *name++);
-      printf("%-32s %4d    %8.8lx\n", ename, *ordinal++, *function++);
+      dprintf_win32(stddeb,"%-32s %4d    %8.8lx\n", ename, *ordinal++, *function++);
     }
 }
 
-void fixup_imports(struct PE_Import_Directory *pe_imports)
+void fixup_imports(struct PE_Import_Directory *pe_imports,unsigned int load_addr)
 { 
   struct PE_Import_Directory * pe_imp;
   int fixup_failed=0;
@@ -115,12 +115,16 @@
       char * Module;
       struct pe_import_name * pe_name;
       unsigned int * import_list, *thunk_list;
+#if 0
       char * c;
+#endif
 
       Module = ((char *) load_addr) + pe_imp->ModuleName;
       dprintf_win32(stddeb, "%s\n", Module);
+#if 0
       c = strchr(Module, '.');
       if (c) *c = 0;
+#endif
 
       import_list = (unsigned int *) 
 	(((unsigned int) load_addr) + pe_imp->Import_List);
@@ -185,6 +189,7 @@
 HINSTANCE PE_LoadImage(struct w_files *wpnt)
 {
 	int i, result;
+        unsigned int load_addr;
 
 	wpnt->pe = xmalloc(sizeof(struct pe_data));
 	memset(wpnt->pe,0,sizeof(struct pe_data));
@@ -239,10 +244,11 @@
 	    }
 	}
 
-	if(wpnt->pe->pe_import) fixup_imports(wpnt->pe->pe_import);
-	if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export);
+	if(wpnt->pe->pe_import) fixup_imports(wpnt->pe->pe_import,load_addr);
+	if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export,load_addr);
   
 	wpnt->hinstance = (HINSTANCE)0x8000;
+	wpnt->load_addr = load_addr;
 	return (wpnt->hinstance);
 }
 
@@ -264,8 +270,6 @@
 	ALIAS_UseAliases=1;
 
 	wpnt=xmalloc(sizeof(struct w_files));
-	wpnt->next=wine_files;
-	wine_files=wpnt;
 	wpnt->ofs=*ofs;
 	wpnt->fd=fd;
 	wpnt->type=0;
@@ -295,7 +299,7 @@
 	pModule = (NE_MODULE*)GlobalLock(hModule);
 
 	/* Set all used entries */
-	pModule->magic=NE_SIGNATURE;
+	pModule->magic=PE_SIGNATURE;
 	pModule->count=1;
 	pModule->next=0;
 	pModule->flags=0;
@@ -353,6 +357,18 @@
 	hInstance=MODULE_CreateInstance(hModule,NULL /* FIX: NULL? really? */);
 	wpnt->hinstance=hInstance;
 
+	if (wpnt->pe->pe_export) {
+		wpnt->name = xmalloc(strlen(wpnt->pe->pe_export->ModuleName)+1);
+		strcpy(wpnt->name, wpnt->pe->pe_export->ModuleName);
+	} else {
+		wpnt->name = xmalloc(strlen(ofs->szPathName)+1);
+		strcpy(wpnt->name, ofs->szPathName);
+	}
+
+	wpnt->next=wine_files;
+	wine_files=wpnt;
+
+	if (!(wpnt->pe->pe_header->coff.Characteristics & IMAGE_FILE_DLL))
 	TASK_CreateTask(hModule,hInstance,0,
 		params->hEnvironment,(LPSTR)PTR_SEG_TO_LIN(params->cmdLine),
 		*((WORD*)PTR_SEG_TO_LIN(params->showCmd)+1));
@@ -371,7 +387,7 @@
 	InitTask(context);
 	USER_InitApp(wpnt->hModule);
 	__asm__ __volatile__("movw %w0,%%fs"::"r" (fs));
-	((void(*)())(load_addr+wpnt->pe->pe_header->opt_coff.AddressOfEntryPoint))();
+	((void(*)())(wpnt->load_addr+wpnt->pe->pe_header->opt_coff.AddressOfEntryPoint))();
 }
 
 int PE_UnloadImage(struct w_files *wpnt)
diff --git a/loader/resource.c b/loader/resource.c
index 42b45cc..4ded636 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -64,7 +64,7 @@
         return 0;
     }
 #else
-    return LIBRES_FindResource( hModule, type, name );
+    return LIBRES_FindResource( hModule, name, type );
 #endif
 }
 
@@ -103,6 +103,7 @@
 /* 16-bit version */
 SEGPTR WIN16_LockResource( HGLOBAL handle )
 {
+#ifndef WINELIB
     HMODULE hModule;
     WORD *pModule;
 
@@ -110,7 +111,6 @@
     if (!handle) return (SEGPTR)0;
     hModule = GetExePtr( handle );
     if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
-#ifndef WINELIB
     switch(*pModule)
     {
       case NE_SIGNATURE:
@@ -121,13 +121,14 @@
         return 0;
     }
 #else
-    return LIBRES_LockResource( hModule, handle );
+    return LIBRES_LockResource( handle );
 #endif
 }
 
 /* 32-bit version */
-LPSTR LockResource( HGLOBAL handle )
+LPVOID LockResource( HGLOBAL handle )
 {
+#ifndef WINELIB
     HMODULE hModule;
     WORD *pModule;
 
@@ -135,7 +136,6 @@
     if (!handle) return NULL;
     hModule = GetExePtr( handle );
     if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
-#ifndef WINELIB
     switch(*pModule)
     {
       case NE_SIGNATURE:
@@ -146,7 +146,7 @@
         return 0;
     }
 #else
-    return LIBRES_LockResource( hModule, handle );
+    return LIBRES_LockResource( handle );
 #endif
 }
 
@@ -156,6 +156,7 @@
  */
 BOOL FreeResource( HGLOBAL handle )
 {
+#ifndef WINELIB
     HMODULE hModule;
     WORD *pModule;
 
@@ -163,7 +164,6 @@
     if (!handle) return FALSE;
     hModule = GetExePtr( handle );
     if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0;
-#ifndef WINELIB
     switch(*pModule)
     {
       case NE_SIGNATURE:
@@ -174,7 +174,7 @@
         return FALSE;
     }
 #else
-    return LIBRES_FreeResource( hModule, handle );
+    return LIBRES_FreeResource( handle );
 #endif
 }
 
diff --git a/loader/signal.c b/loader/signal.c
index 6150f72..1968046 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -56,8 +56,6 @@
 static void win_fault(int signal, int code, struct sigcontext *context)
 {
 #endif
-    int i;
-    
     if (signal != SIGTRAP)
     {
         if (CS_reg(context) == WINE_CODE_SELECTOR)
diff --git a/loader/task.c b/loader/task.c
index bf383cd..345b9f7 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -14,6 +14,7 @@
 #include "debugger.h"
 #include "global.h"
 #include "instance.h"
+#include "message.h"
 #include "miscemu.h"
 #include "module.h"
 #include "neexe.h"
@@ -31,6 +32,7 @@
   /* Must not be greater than 64k, or MAKE_SEGPTR won't work */
 #define STACK32_SIZE 0x10000
 
+/* ------ Internal variables ------ */
 
 static HTASK hFirstTask = 0;
 static HTASK hCurrentTask = 0;
@@ -39,6 +41,8 @@
 static WORD nTaskCount = 0;
 static HANDLE hDOSEnvironment = 0;
 
+/* ------ Internal declarations ------ */
+
   /* TASK_Reschedule() 16-bit entry point */
 static FARPROC TASK_RescheduleProc;
 
@@ -48,7 +52,6 @@
 #define TASK_SCHEDULE()  CallTo16_word_(TASK_RescheduleProc,0)
 #endif
 
-
 static HANDLE TASK_CreateDOSEnvironment(void);
 
 /***********************************************************************
@@ -565,6 +568,10 @@
 
     GlobalFreeAll( pTask->hPDB );
 
+      /* Free message queue */
+
+    MSG_DeleteMsgQueue( pTask->hQueue );
+
       /* Free the selector aliases */
 
     GLOBAL_FreeBlock( pTask->hCSAlias );
@@ -604,8 +611,12 @@
     
     hTaskToKill = hCurrentTask;
     hLockedTask = 0;
+
     Yield();
-    /* We never return from Yield() */
+    /* We should never return from this Yield() */
+
+    fprintf(stderr,"It's alive! Alive!!!\n");
+    exit(1);
 }
 
 
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 26ac02d..f4c201e 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -14,12 +14,12 @@
 	keyboard.c \
 	lstr.c \
 	main.c \
+	network.c \
 	ole2.c \
 	ole2disp.c \
 	ole2nls.c \
 	olecli.c \
 	olesvr.c \
-	network.c \
 	profile.c \
 	rect.c \
 	shell.c \
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 73df1d1..d6c8815 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -858,29 +858,30 @@
  */
 int GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf)
 {
-  int i, len;
-  printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
-  if (lpFile == NULL || lpTitle == NULL)
-    return -1;
-  len = strlen(lpFile);
-  if (len == 0)
-    return -1;
-  if (strpbrk(lpFile, "*[]"))
-    return -1;
-  len--;
-  if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
-    return -1;
-  for (i = len; i >= 0; i--)
-    if (lpFile[i] == '/' ||  lpFile[i] == '\\' ||  lpFile[i] == ':')
-      {
+    int i, len;
+    printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
+    if (lpFile == NULL || lpTitle == NULL)
+    	return -1;
+    len = strlen(lpFile);
+    if (len == 0)
+    	return -1;
+    if (strpbrk(lpFile, "*[]"))
+    	return -1;
+    len--;
+    if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
+    	return -1;
+    for (i = len; i >= 0; i--)
+    	if (lpFile[i] == '/' ||  lpFile[i] == '\\' ||  lpFile[i] == ':')
+    {
 	i++;
 	break;
-      }
-  printf("\n---> '%s' ", &lpFile[i]);
-  len = MIN(cbBuf, strlen(&lpFile[i]) + 1);
-  strncpy(lpTitle, &lpFile[i], len + 1);
-  if (len != cbBuf)
-    return len;
-  else
+    }
+    printf("\n---> '%s' ", &lpFile[i]);
+    
+    len = strlen(lpFile+i)+1;
+    if (cbBuf < len);
+    	return len;
+
+    strncpy(lpTitle, &lpFile[i], len);
     return 0;
 }
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index 28cdf30..0d88d8f 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -885,12 +885,6 @@
     strcpy(dp->unixpath, dirname);
     dp->entnum = 0;
 
-    if ((dp->telldirnum=telldir(ds)) == -1)
-    {
-        dp->inuse = 0;
-	closedir(ds);
-	return NULL;
-    }
     if (closedir(ds) == -1) 
     {
         dp->inuse = 0;
@@ -906,11 +900,16 @@
 	struct dirent *d;
 	struct stat st;
 	DIR	*ds;
+	int	i;
 
 	if (!de->inuse)
 		return NULL;
 	if (!(ds=opendir(de->unixpath))) return NULL;
-	seekdir(ds,de->telldirnum); /* returns no error value. strange */
+	/* skip all already read directory entries. 
+	 * the dir has hopefully not been modified in the meantime
+	 */
+	for (i=de->entnum;i--;)
+		readdir(ds);
    
         if (de->search_attribute & FA_LABEL)  {	
 	    int drive;
@@ -927,13 +926,11 @@
 	}
     
 	do {
+	    de->entnum++;   /* Increment the directory entry number */
 	    if ((d = readdir(ds)) == NULL)  {
-		de->telldirnum=telldir(ds);
 		closedir(ds);
 		return NULL;
 	    }
-
-	    de->entnum++;   /* Increment the directory entry number */
 	    strcpy(de->filename, d->d_name);
 	    if (d->d_reclen > 12)
 	    de->filename[12] = '\0';
@@ -954,7 +951,6 @@
 	de->filesize = st.st_size;
 	de->filetime = st.st_mtime;
 
-	de->telldirnum = telldir(ds);
 	closedir(ds);
 	return de;
 }
diff --git a/misc/keyboard.c b/misc/keyboard.c
index ce2c0ec..8058a7c 100644
--- a/misc/keyboard.c
+++ b/misc/keyboard.c
@@ -124,7 +124,7 @@
 
 	for (i = 0 ; i != KeyTableSize ; i++) 
 		if (KeyTable[i].scancode == lParam)  {
-			strncpy(lpBuffer, KeyTable[i].name, nSize);
+			lstrcpyn(lpBuffer, KeyTable[i].name, nSize);
 			return strlen(lpBuffer);
 		}
 
diff --git a/misc/lstr.c b/misc/lstr.c
index b79c3b3..5d03363 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -54,7 +54,6 @@
 "\205\240\203\141\204\206\221\207\212\202\210\211\215\241\214\213"
 "\144\244\225\242\223\157\224\366\157\227\243\226\201\171\137\230";
 
-
 /* Funny to divide them between user and kernel. */
 
 /* KERNEL.89 */
@@ -87,10 +86,20 @@
     return target;
 }
 
-/* KERNEL.353 */
-SEGPTR lstrcpyn( SEGPTR target, SEGPTR source, WORD n )
+/* KERNEL.353 32-bit version*/
+char *lstrcpyn(char *dst, char *src, int n)
 {
-    strncpy((char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source), n);
+    char *tmp = dst;
+    while(n-- > 1 && *src)
+    	*dst++ = *src++;
+    *dst = 0;
+    return tmp;
+}
+
+/* KERNEL.353 16-bit version*/
+SEGPTR WIN16_lstrcpyn( SEGPTR target, SEGPTR source, WORD n )
+{
+    lstrcpyn((char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source),n);
     return target;
 }
 
diff --git a/misc/main.c b/misc/main.c
index 8f2a426..9226c08 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -23,6 +23,7 @@
 #include "winsock.h"
 #include "options.h"
 #include "desktop.h"
+#include "shell.h"
 #include "dlls.h"
 #define DEBUG_DEFINE_VARIABLES
 #include "stddebug.h"
@@ -89,11 +90,11 @@
     FALSE,          /* Enhanced mode */
     FALSE,          /* IPC enabled */
 #ifdef DEFAULT_LANG
-    DEFAULT_LANG    /* Default language */
+    DEFAULT_LANG,   /* Default language */
 #else
-    LANG_En
+    LANG_En,
 #endif
-
+    FALSE	    /* Managed windows */
 };
 
 
@@ -114,7 +115,8 @@
     { "-debugmsg",      ".debugmsg",        XrmoptionSepArg, (caddr_t)NULL },
     { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL },
     { "-allowreadonly", ".allowreadonly",   XrmoptionNoArg,  (caddr_t)"on" },
-    { "-enhanced",      ".enhanced",        XrmoptionNoArg,  (caddr_t)"off"}
+    { "-enhanced",      ".enhanced",        XrmoptionNoArg,  (caddr_t)"off"},
+    { "-managed",       ".managed",         XrmoptionNoArg,  (caddr_t)"off"}
 };
 
 #define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
@@ -130,6 +132,7 @@
   "    -ipc            Enable IPC facilities\n" \
   "    -debug          Enter debugger before starting application\n" \
   "    -language xx    Set the language (one of En,Es,De,No,Fr,Fi,Da)\n" \
+  "    -managed        Allow the window manager to manage created windows\n" \
   "    -name name      Set the application name\n" \
   "    -privatemap     Use a private color map\n" \
   "    -fixedmap       Use a \"standard\" color map\n" \
@@ -373,6 +376,8 @@
 	Options.desktopGeometry = value.addr;
     if (MAIN_GetResource( db, ".language", &value))
         MAIN_ParseLanguageOption( (char *)value.addr );
+    if (MAIN_GetResource( db, ".managed", &value))
+        Options.managed = TRUE;
 #ifdef DEBUG_RUNTIME
     if (MAIN_GetResource( db, ".debugoptions", &value))
 	ParseDebugOptions((char*)value.addr);
@@ -530,7 +535,6 @@
 static void called_at_exit(void)
 {
     extern void sync_profiles(void);
-    extern void SHELL_SaveRegistry(void);
 
     sync_profiles();
     MAIN_RestoreSetup();
@@ -548,7 +552,6 @@
     int *depth_list;
 
     extern int _WinMain(int argc, char **argv);
-    extern void SHELL_LoadRegistry(void);
 
     setbuf(stdout,NULL);
     setbuf(stderr,NULL);
@@ -575,6 +578,7 @@
     }
 #endif
 
+    SHELL_Init();
     SHELL_LoadRegistry();
 
     screen       = DefaultScreenOfDisplay( display );
@@ -652,66 +656,67 @@
  */
 int SetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nCount)
 {
-	LPENVENTRY	lpNewEnv;
-	LPENVENTRY	lpEnv = lpEnvList;
-	dprintf_env(stddeb, "SetEnvironnement('%s', '%s', %d) !\n", 
-				lpPortName, lpEnviron, nCount);
-	if (lpPortName == NULL) return -1;
-	while (lpEnv != NULL) {
-		if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
-			if (nCount == 0 || lpEnviron == NULL) {
-				if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next;
-				if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev;
-				free(lpEnv->Value);
-				free(lpEnv->Name);
-				free(lpEnv);
-				dprintf_env(stddeb, "SetEnvironnement() // entry deleted !\n");
-				return -1;
-				}
-			free(lpEnv->Value);
-			lpEnv->Value = malloc(nCount);
-			if (lpEnv->Value == NULL) {
-				dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
-				return 0;
-			}
-			memcpy(lpEnv->Value, lpEnviron, nCount);
-			lpEnv->wSize = nCount;
-			dprintf_env(stddeb, "SetEnvironnement() // entry modified !\n");
-			return nCount;
-			}
-		if (lpEnv->Next == NULL) break;
-		lpEnv = lpEnv->Next;
-		}
-	if (nCount == 0 || lpEnviron == NULL) return -1;
-	dprintf_env(stddeb, "SetEnvironnement() // new entry !\n");
-	lpNewEnv = malloc(sizeof(ENVENTRY));
-	if (lpNewEnv == NULL) {
-		dprintf_env(stddeb, "SetEnvironment() // Error allocating new entry !\n");
-		return 0;
-		}
-	if (lpEnvList == NULL) {
-		lpEnvList = lpNewEnv;
-		lpNewEnv->Prev = NULL;
-		}
-	else {
-		lpEnv->Next = lpNewEnv;
-		lpNewEnv->Prev = lpEnv;
-		}
-	lpNewEnv->Next = NULL;
-	lpNewEnv->Name = malloc(strlen(lpPortName) + 1);
-	if (lpNewEnv->Name == NULL) {
-		dprintf_env(stddeb, "SetEnvironment() // Error allocating entry name !\n");
-		return 0;
-		}
-	strcpy(lpNewEnv->Name, lpPortName);
-	lpNewEnv->Value = malloc(nCount);
-	if (lpNewEnv->Value == NULL) {
+    LPENVENTRY	lpNewEnv;
+    LPENVENTRY	lpEnv = lpEnvList;
+    dprintf_env(stddeb, "SetEnvironment('%s', '%s', %d) !\n", 
+		lpPortName, lpEnviron, nCount);
+    if (lpPortName == NULL) return -1;
+    while (lpEnv != NULL) {
+	if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
+	    if (nCount == 0 || lpEnviron == NULL) {
+		if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next;
+		if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev;
+		free(lpEnv->Value);
+		free(lpEnv->Name);
+		free(lpEnv);
+		dprintf_env(stddeb, "SetEnvironment() // entry deleted !\n");
+		return -1;
+	    }
+	    free(lpEnv->Value);
+	    lpEnv->Value = malloc(nCount);
+	    if (lpEnv->Value == NULL) {
 		dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
 		return 0;
-		}
-	memcpy(lpNewEnv->Value, lpEnviron, nCount);
-	lpNewEnv->wSize = nCount;
-	return nCount;
+	    }
+	    memcpy(lpEnv->Value, lpEnviron, nCount);
+	    lpEnv->wSize = nCount;
+	    dprintf_env(stddeb, "SetEnvironment() // entry modified !\n");
+	    return nCount;
+	}
+	if (lpEnv->Next == NULL) break;
+	lpEnv = lpEnv->Next;
+    }
+    if (nCount == 0 || lpEnviron == NULL) return -1;
+    dprintf_env(stddeb, "SetEnvironment() // new entry !\n");
+    lpNewEnv = malloc(sizeof(ENVENTRY));
+    if (lpNewEnv == NULL) {
+	dprintf_env(stddeb, "SetEnvironment() // Error allocating new entry !\n");
+	return 0;
+    }
+    if (lpEnvList == NULL) {
+	lpEnvList = lpNewEnv;
+	lpNewEnv->Prev = NULL;
+    }
+    else 
+    {
+	lpEnv->Next = lpNewEnv;
+	lpNewEnv->Prev = lpEnv;
+    }
+    lpNewEnv->Next = NULL;
+    lpNewEnv->Name = malloc(strlen(lpPortName) + 1);
+    if (lpNewEnv->Name == NULL) {
+	dprintf_env(stddeb, "SetEnvironment() // Error allocating entry name !\n");
+	return 0;
+    }
+    strcpy(lpNewEnv->Name, lpPortName);
+    lpNewEnv->Value = malloc(nCount);
+    if (lpNewEnv->Value == NULL) {
+	dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n");
+	return 0;
+    }
+    memcpy(lpNewEnv->Value, lpEnviron, nCount);
+    lpNewEnv->wSize = nCount;
+    return nCount;
 }
 
 /***********************************************************************
@@ -730,21 +735,21 @@
  */
 int GetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nMaxSiz)
 {
-	WORD		nCount;
-	LPENVENTRY	lpEnv = lpEnvList;
-	dprintf_env(stddeb, "GetEnvironnement('%s', '%s', %d) !\n",
-					lpPortName, lpEnviron, nMaxSiz);
-	while (lpEnv != NULL) {
-		if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
-			nCount = MIN(nMaxSiz, lpEnv->wSize);
-			memcpy(lpEnviron, lpEnv->Value, nCount);
-			dprintf_env(stddeb, "GetEnvironnement() // found '%s' !\n", lpEnviron);
-			return nCount;
-			}
-		lpEnv = lpEnv->Next;
-		}
-	dprintf_env(stddeb, "GetEnvironnement() // not found !\n");
-	return 0;
+    WORD       nCount;
+    LPENVENTRY lpEnv = lpEnvList;
+    dprintf_env(stddeb, "GetEnvironment('%s', '%s', %d) !\n",
+		lpPortName, lpEnviron, nMaxSiz);
+    while (lpEnv != NULL) {
+	if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) {
+	    nCount = MIN(nMaxSiz, lpEnv->wSize);
+	    memcpy(lpEnviron, lpEnv->Value, nCount);
+	    dprintf_env(stddeb, "GetEnvironment() // found '%s' !\n", lpEnviron);
+	    return nCount;
+	}
+	lpEnv = lpEnv->Next;
+    }
+    dprintf_env(stddeb, "GetEnvironment() // not found !\n");
+    return 0;
 }
 
 /***********************************************************************
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index f0dc52f..0a20cf9 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -432,7 +432,7 @@
 	}
 
 	if(retLen>len)retLen=len;
-	strncpy(buf,retString,len);
+	lstrcpyn(buf,retString,len);
 	return retLen;
 }
 
diff --git a/misc/profile.c b/misc/profile.c
index 080c3dc..043eb28 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -14,9 +14,7 @@
  *         has a NULL KeyValue returning a list of KeyNames, and a NULL
  *         AppName undefined.  I changed GetSetProfile to match.  This makes
  *         PROGMAN.EXE do the right thing.
- *
-static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza";
-*/
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -25,15 +23,12 @@
 #include "wine.h"
 #include "windows.h"
 #include "dos_fs.h"
-#include "module.h"
 #include "toolhelp.h"
 #include "stddebug.h"
-/* #define DEBUG_PROFILE */
 #include "debug.h"
 #include "xmalloc.h"
 
 #define STRSIZE 255
-#define overflow (next == &CharBuffer [STRSIZE-1])
 
 typedef struct TKeys {
     char *KeyName;
@@ -143,7 +138,12 @@
 	
 	if (isspace(c))
 	    continue;
-	
+	if (c == ';') {
+	    do {
+		c = fgetc(f);
+	    } while (!(c == EOF || c == '\n'));
+	    if (c == EOF) goto finished;
+	}
 	if (c == '[') {
 	    TSecHeader *temp = SecHeader;
 	    
@@ -206,23 +206,26 @@
 	    skipspc = TRUE;
 	    do {
 		c = fgetc(f);
-		if (c == EOF) break;
-		if (c != '\n') {
-		    if (!isspace(c) || !skipspc) {
-			skipspc = FALSE;
-			bufsize++;
-			*bufptr++ = c;
-			if (!isspace(c))
-		    	    lastnonspc = bufptr;
-		    }
-		} else
-		    break;
+		if (c == EOF || c == '\n' || c == ';') break;
+		if (!isspace(c) || !skipspc) {
+		    skipspc = FALSE;
+		    bufsize++;
+		    *bufptr++ = c;
+		    if (!isspace(c))
+		    	lastnonspc = bufptr;
+		}
 	    } while(bufsize < STRSIZE-1);
 	    *lastnonspc = 0;
 	    SecHeader->Keys->Value = strdup (CharBuffer);
 	    dprintf_profile (stddeb, "[%s] (%s)=%s\n", SecHeader->AppName,
 			     SecHeader->Keys->KeyName, SecHeader->Keys->Value);
-	    
+	    if (c == ';') {
+		do {
+		    c = fgetc(f);
+		} while (!(c == EOF || c == '\n'));
+		if (c == EOF)
+		    goto finished;
+	    }
 	}
 
     }
@@ -266,6 +269,7 @@
 	section = New->Section;
 	Current = New;
     }
+
     /* Start search */
     for (; section; section = section->link){
 	if (strcasecmp (section->AppName, AppName))
@@ -280,20 +284,17 @@
 	    dprintf_profile(stddeb,"GetSetProfile // KeyName == NULL, Enumeration !\n");
 	    for (key = section->Keys; key; key = key->link){
 		if (left < 1) {
-			dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n");
-			return (Size - 2);
+		    dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n");
+		    return Size - 2;
 		}
 		slen = MIN(strlen(key->KeyName) + 1, left);
-		dprintf_profile(stddeb,"GetSetProfile // strncpy(%p, %p, %d);\n", 
-				ReturnedString, key->Value, slen);
-		strncpy (p, key->KeyName, slen);
+		lstrcpyn(p, key->KeyName, slen);
 		dprintf_profile(stddeb,"GetSetProfile // enum '%s' !\n", p);
 		left -= slen;
 		p += slen;
 	    }
-		*p = '\0';
-		dprintf_profile(stddeb,"GetSetProfile // normal end of enum !\n");
-	    return (Size - 2 - left);
+	    *p = '\0';
+	    return Size - 2 - left;
 	}
 	for (key = section->Keys; key; key = key->link){
 	    int slen;
@@ -305,9 +306,8 @@
 		Current->changed=TRUE;
 		return 1;
 	    }
-	    slen = MIN(strlen(key->Value), Size - 1);
-	    ReturnedString[slen] = 0;
-	    strncpy (ReturnedString, key->Value, slen);
+	    slen = MIN(strlen(key->Value)+1, Size);
+	    lstrcpyn(ReturnedString, key->Value, slen);
 	    dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString);
 	    return 1; 
 	}
@@ -317,13 +317,13 @@
 	if (set) {
 	    new_key (section, KeyName, Default);
         } else {
-	    int slen = MIN(strlen(Default), Size - 1);
-            ReturnedString[slen] = 0;
-            strncpy(ReturnedString, Default, slen);
+	    int slen = MIN(strlen(Default)+1, Size);
+            lstrcpyn(ReturnedString, Default, slen);
 	    dprintf_profile(stddeb,"GetSetProfile // Key not found\n");
 	}
 	return 1;
     }
+
     /* Non existent section */
     if (set){
 	section = (TSecHeader *) xmalloc (sizeof (TSecHeader));
@@ -334,9 +334,8 @@
 	Current->Section = section;
 	Current->changed = TRUE;
     } else {
-	int slen = MIN(strlen(Default), Size - 1);
-	ReturnedString[slen] = 0;
-	strncpy(ReturnedString, Default, slen);
+	int slen = MIN(strlen(Default)+1, Size);
+	lstrcpyn(ReturnedString, Default, slen);
 	dprintf_profile(stddeb,"GetSetProfile // Section not found\n");
     }
     return 1;
diff --git a/misc/shell.c b/misc/shell.c
index 86d60ee..5e1911c 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -25,48 +25,48 @@
 static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]";
 
 /*************************************************************************
- *                        SHELL_RegCheckForRoot()     internal use only
+ *                        SHELL_Init()
  */
-static LONG SHELL_RegCheckForRoot()
+BOOL SHELL_Init()
 {
     HKEY hNewKey;
-
-    if (lphRootKey == NULL){
-      hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
-      lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
-      if (lphRootKey == NULL) {
+    
+    hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
+    lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
+    if (lphRootKey == NULL) {
         printf("SHELL_RegCheckForRoot: Couldn't allocate root key!\n");
-        return ERROR_OUTOFMEMORY;
-      }
-      lphRootKey->hKey = (HKEY)1;
-      lphRootKey->lpSubKey = RootKeyName;
-      lphRootKey->dwType = 0;
-      lphRootKey->lpValue = NULL;
-      lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL;
-
-      hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
-      lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
-      if (lphTopKey == NULL) {
-        printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n");
-        return ERROR_OUTOFMEMORY;
-      }
-      lphTopKey->hKey = 0;
-      lphTopKey->lpSubKey = TopKeyName;
-      lphTopKey->dwType = 0;
-      lphTopKey->lpValue = NULL;
-      lphTopKey->lpSubLvl = lphRootKey;
-      lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL;
-
-      dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n");
+        return FALSE;
     }
-    return ERROR_SUCCESS;
+    lphRootKey->hKey = (HKEY)1;
+    lphRootKey->lpSubKey = RootKeyName;
+    lphRootKey->dwType = 0;
+    lphRootKey->lpValue = NULL;
+    lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL;
+    
+    hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
+    lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
+    if (lphTopKey == NULL) {
+        printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n");
+        return FALSE;
+    }
+    lphTopKey->hKey = 0;
+    lphTopKey->lpSubKey = TopKeyName;
+    lphTopKey->dwType = 0;
+    lphTopKey->lpValue = NULL;
+    lphTopKey->lpSubLvl = lphRootKey;
+    lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL;
+
+    dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n");
+
+    return TRUE;
 }
 
 /* FIXME: the loading and saving of the registry database is rather messy.
  * bad input (while reading) may crash wine.
  */
 void
-_DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs) {
+_DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs)
+{
 	LPKEYSTRUCT	lpKey;
 
 	lpKey=lpTKey->lpSubLvl;
@@ -86,7 +86,8 @@
 }
 
 static void
-_SaveKey(HKEY hKey,char *where) {
+_SaveKey(HKEY hKey,char *where)
+{
 	FILE		*f;
 	LPKEYSTRUCT	lpKey;
 
@@ -106,7 +107,8 @@
 }
 
 void
-SHELL_SaveRegistry(void) {
+SHELL_SaveRegistry(void)
+{
 	/* FIXME: 
 	 * -implement win95 additional keytypes here
 	 * (HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER or whatever)
@@ -117,7 +119,8 @@
 
 #define BUFSIZE	256
 void
-_LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf) {
+_LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf)
+{
 	int		i;
 	char		*s,*t;
 	HKEY		hNewKey;
@@ -184,7 +187,8 @@
 }
 
 void
-_LoadKey(HKEY hKey,char *from) {
+_LoadKey(HKEY hKey,char *from) 
+{
 	FILE		*f;
 	LPKEYSTRUCT	lpKey;
 	char		buf[BUFSIZE]; /* FIXME: long enough? */
@@ -204,12 +208,8 @@
 }
 
 void
-SHELL_LoadRegistry(void) {
-	DWORD	dwRet;
-
-	dwRet=SHELL_RegCheckForRoot();
-	if (dwRet!=ERROR_SUCCESS) 
-		return;/*very bad magic, if we can't even allocate the rootkeys*/
+SHELL_LoadRegistry(void) 
+{
 	_LoadKey((HKEY)HKEY_CLASSES_ROOT,"/tmp/winereg");
 }
 
@@ -221,10 +221,7 @@
 	LPKEYSTRUCT	lpKey,lpNextKey;
 	LPCSTR		ptr;
 	char		str[128];
-	LONG            dwRet;
 
-        dwRet = SHELL_RegCheckForRoot();
-        if (dwRet != ERROR_SUCCESS) return dwRet;
 	dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n",
 				       (DWORD)hKey, lpSubKey, lpSubKey, lphKey);
 	if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
@@ -274,12 +271,9 @@
 	LPKEYSTRUCT	lpNewKey;
 	LPKEYSTRUCT	lpKey;
 	LPKEYSTRUCT	lpPrevKey;
-	LONG		dwRet;
 	LPCSTR		ptr;
 	char		str[128];
 
-	dwRet = SHELL_RegCheckForRoot();
-        if (dwRet != ERROR_SUCCESS) return dwRet;
 	dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n",	(DWORD)hKey, lpSubKey, lphKey);
 	if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
         switch((DWORD)hKey) {
@@ -439,11 +433,8 @@
 LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
 {
 	LPKEYSTRUCT	lpKey;
-	LONG		dwRet;
 	LONG            len;
 
-	dwRet = SHELL_RegCheckForRoot();
-        if (dwRet != ERROR_SUCCESS) return dwRet;
 	dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", (DWORD)hKey, dwSubKey);
 	if (lpBuf == NULL) return ERROR_INVALID_PARAMETER;
         switch((DWORD)hKey) {
@@ -478,11 +469,12 @@
  */
 void DragAcceptFiles(HWND hWnd, BOOL b)
 {
- /* flips WS_EX_ACCEPTFILES bit according to the value of b (TRUE or FALSE) */
+    /* flips WS_EX_ACCEPTFILES bit according to the value of b */
+    dprintf_reg(stddeb,"DragAcceptFiles("NPFMT", %u) old exStyle %08lx\n",
+		hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE));
 
- dprintf_reg(stddeb,"DragAcceptFiles("NPFMT", %u) old exStyle %08lx\n",hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE));
-
- SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES); 
+    SetWindowLong(hWnd,GWL_EXSTYLE,
+		  GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES);
 }
 
 
@@ -491,42 +483,42 @@
  */
 UINT DragQueryFile(HDROP hDrop, WORD wFile, LPSTR lpszFile, WORD wLength)
 {
- /* hDrop is a global memory block allocated with GMEM_SHARE 
-    with DROPFILESTRUCT as a header and filenames following
-    it, zero length filename is in the end */       
-
- LPDROPFILESTRUCT lpDropFileStruct;
- LPSTR		  lpCurrent;
- WORD		  i;
-
- dprintf_reg(stddeb,"DragQueryFile("NPFMT", %i, %p, %u)\n",
-                           hDrop,wFile,lpszFile,wLength);
-
- lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); 
- if(!lpDropFileStruct)
+    /* hDrop is a global memory block allocated with GMEM_SHARE 
+     * with DROPFILESTRUCT as a header and filenames following
+     * it, zero length filename is in the end */       
+    
+    LPDROPFILESTRUCT lpDropFileStruct;
+    LPSTR lpCurrent;
+    WORD  i;
+    
+    dprintf_reg(stddeb,"DragQueryFile("NPFMT", %i, %p, %u)\n",
+		hDrop,wFile,lpszFile,wLength);
+    
+    lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); 
+    if(!lpDropFileStruct)
     {
-       dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n");
-       return 0;
+	dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n");
+	return 0;
     } 
- lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
-
- i = 0;
- while(i++ < wFile)
+    lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
+    
+    i = 0;
+    while (i++ < wFile)
     {
-       while(*lpCurrent++);  /* skip filename */
-       if(!*lpCurrent) 
-          return (wFile == 0xFFFF)? i : 0;  
+	while (*lpCurrent++);  /* skip filename */
+	if (!*lpCurrent) 
+	    return (wFile == 0xFFFF) ? i : 0;  
     }
-
- i = strlen(lpCurrent); 
- if(!lpszFile) return i+1;   /* needed buffer size */
-
- i = ( wLength > i)? i : wLength-1;
- strncpy(lpszFile,lpCurrent,i);
- lpszFile[i]='\0';
-
- GlobalUnlock(hDrop);
- return i;
+    
+    i = strlen(lpCurrent); 
+    if (!lpszFile) return i+1;   /* needed buffer size */
+    
+    i = (wLength > i) ? i : wLength-1;
+    strncpy(lpszFile, lpCurrent, i);
+    lpszFile[i] = '\0';
+    
+    GlobalUnlock(hDrop);
+    return i;
 }
 
 
@@ -535,7 +527,7 @@
  */
 void DragFinish(HDROP h)
 {
- GlobalFree((HGLOBAL)h);
+    GlobalFree((HGLOBAL)h);
 }
 
 
@@ -544,16 +536,16 @@
  */
 BOOL DragQueryPoint(HDROP hDrop, POINT FAR *p)
 {
- LPDROPFILESTRUCT lpDropFileStruct;  
- BOOL             bRet;
+    LPDROPFILESTRUCT lpDropFileStruct;  
+    BOOL             bRet;
 
- lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
+    lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
 
- memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT));
- bRet = lpDropFileStruct->fInNonClientArea;
+    memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT));
+    bRet = lpDropFileStruct->fInNonClientArea;
 
- GlobalUnlock(hDrop);
- return bRet; 
+    GlobalUnlock(hDrop);
+    return bRet;
 }
 
 
diff --git a/misc/spy.c b/misc/spy.c
index 6c9692a..e547e1c 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -25,7 +25,7 @@
     "WM_CREATE",	
     "WM_DESTROY",    
     "WM_MOVE",
-    "WM_UNUSED0",
+    "WM_SIZEWAIT",
     "WM_SIZE",
     "WM_ACTIVATE",
     "WM_SETFOCUS",
@@ -62,7 +62,7 @@
     "WM_PAINTICON",
     "WM_ICONERASEBKGND",
     "WM_NEXTDLGCTL",
-    "WM_UNUSED4",
+    "WM_ALTTABACTIVE",
     "WM_SPOOLERSTATUS",
     "WM_DRAWITEM",
     "WM_MEASUREITEM",
@@ -70,9 +70,19 @@
     "WM_VKEYTOITEM",
     "WM_CHARTOITEM",
     "WM_SETFONT",		/* 0x30 */
-    "WM_GETFONT", NULL, NULL, NULL, NULL, NULL, 
-    "WM_QUERYDRAGICON", NULL, 
-    "WM_COMPAREITEM", NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_GETFONT",
+    "WM_SETHOTKEY", 
+    "WM_GETHOTKEY", 
+    "WM_FILESYSCHANGE", 
+    "WM_ISACTIVEICON",
+    "WM_QUERYPARKICON",
+    "WM_QUERYDRAGICON",
+    "WM_QUERYSAVESTATE",
+    "WM_COMPAREITEM", 
+    "WM_TESTING", NULL, 
+    "WM_OTHERWINDOWCREATED", 
+    "WM_OTHERWINDOWDESTROYED", 
+    "WM_ACTIVATESHELLWINDOW", NULL,
 
     NULL, 		        /* 0x40 */
     "WM_COMPACTING", NULL, NULL, 
@@ -101,7 +111,8 @@
     "WM_NCPAINT",          	/* 0x0085 */
     "WM_NCACTIVATE",       	/* 0x0086 */
     "WM_GETDLGCODE",		/* 0x0087 */
-    "WM_SYNCPAINT", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_SYNCPAINT", 
+    "WM_SYNCTASK", NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0090 */
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -149,7 +160,10 @@
     "WM_SYSCHAR",		/* 0x0106 */
     "WM_SYSDEADCHAR",		/* 0x0107 */
     "WM_KEYLAST",		/* 0x0108 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, 
+    "WM_CONVERTREQUEST",
+    "WM_CONVERTRESULT", 
+    "WM_INTERIM", NULL, NULL, NULL,
 
     "WM_INITDIALOG",		/* 0x0110 */
     "WM_COMMAND",		/* 0x0111 */
@@ -169,8 +183,7 @@
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0130 */
-    NULL, 
-    "wm_lbtrackpoint", 
+    NULL, "wm_lbtrackpoint", 
     NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
@@ -237,7 +250,8 @@
     "WM_PARENTNOTIFY",		/* 0x0210 */
     "WM_ENTERMENULOOP",         /* 0x0211 */
     "WM_EXITMENULOOP",          /* 0x0212 */
-    NULL, NULL, NULL, NULL, NULL,
+    "WM_NEXTMENU", 		/* 0x0213 */
+                            NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     "WM_MDICREATE",             /* 0x0220 */
@@ -344,10 +358,11 @@
     /* 0x0380 */
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
     "WM_COALESCE_FIRST", 
+          NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
     "WM_COALESCE_LAST", 
-                NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/misc/winsocket.c b/misc/winsocket.c
index 318c38e..536e5db 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -35,6 +35,10 @@
 static FARPROC BlockFunction;
 static fd_set fd_in_use;
 
+#ifdef __FreeBSD__
+extern int h_errno;
+#endif /* __FreeBSD__ */
+
 struct ipc_packet {
 	long	mtype;
 	HANDLE	handle;
@@ -48,7 +52,8 @@
 #endif
 
 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
-#define MTYPE 0xb0b0eb05
+/*#define MTYPE 0xb0b0eb05*/
+#define MTYPE 0x30b0eb05
 
 /* These structures are Win16 only */
 
@@ -831,23 +836,32 @@
 
 static void recv_message(int sig)
 {
-	struct ipc_packet message;
+	static struct ipc_packet message;
+	static int message_is_valid = 0;
+	BOOL result;
 
-/* FIXME: something about no message of desired type */
-	if (msgrcv(wine_key, (struct msgbuf*)&(message), 
-		   IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1)
-		perror("wine: msgrcv");
-
-	fprintf(stderr, 
-		"WSA: PostMessage (hwnd "NPFMT", wMsg %d, wParam "NPFMT", lParam %ld)\n",
-		message.hWnd,
-		message.wMsg,
-		message.handle,
-		message.lParam);
-
-	PostMessage(message.hWnd, message.wMsg, (WPARAM)message.handle, message.lParam);
-		
 	signal(SIGUSR1, recv_message);
+	while (1) {
+
+		if (!message_is_valid) {
+			if (msgrcv(wine_key, (struct msgbuf*)&(message), 
+				   IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1) {
+				perror("wine: msgrcv");
+				break;
+			}
+		}
+
+		result = PostMessage(message.hWnd, message.wMsg,
+				     (WPARAM)message.handle, message.lParam);
+		if (result == FALSE) {
+			message_is_valid = 1;
+			break;
+		}
+		else
+			message_is_valid = 0;
+		
+	}
+		
 }
 
 
@@ -861,13 +875,8 @@
 	message.wMsg = wMsg;
 	message.lParam = lParam;
 
-	fprintf(stderr, 
-		"WSA: send (hwnd "NPFMT", wMsg %d, handle "NPFMT", lParam %ld)\n",
-		hWnd, wMsg, handle, lParam);
-	
-/* FIXME: something about invalid argument */
 	if (msgsnd(wine_key, (struct msgbuf*)&(message),  
-		   IPC_PACKET_SIZE, IPC_NOWAIT) == -1)
+		   IPC_PACKET_SIZE, 0/*IPC_NOWAIT*/) == -1)
 		perror("wine: msgsnd");
 		
 	kill(getppid(), SIGUSR1);
@@ -1136,12 +1145,14 @@
         "WINE Sockets",
 #ifdef linux
         "LINUX/i386",
-#endif
-#ifdef __NetBSD__
+#elif defined(__NetBSD__)
         "NetBSD/i386",
-#endif
-#ifdef sunos
+#elif defined(sunos)
 	"SunOS",
+#elif defined(__FreeBSD__)
+	"FreeBSD",
+#else
+	"Unknown",
 #endif
         128,
 	1024,
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index 3ea208f..dc99c2a 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -57,16 +57,10 @@
  * for use in mciSendString()
  */
 #define _MCI_STR(s) do {\
-	int __l__;\
 	dprintf_mci(stddeb,"->returns \"%s\"",s);\
 	if (lpstrReturnString) {\
-		__l__=strlen(s);\
-		if(__l__>uReturnLength) {\
-			strncpy(lpstrReturnString,s,uReturnLength-1);\
-			lpstrReturnString[uReturnLength-1]='\0';\
-		} else\
-			strcpy(lpstrReturnString,s);\
-		dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
+	    lstrcpyn(lpstrReturnString,s,uReturnLength);\
+	    dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
 	}\
 } while(0)
 
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 81f1c1b..152ee9a 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -284,7 +284,6 @@
 BOOL mciGetErrorString (DWORD wError, LPSTR lpstrBuffer, UINT uLength)
 {
 	LPSTR	msgptr;
-	int		maxbuf;
 	dprintf_mmsys(stddeb, "mciGetErrorString(%08lX, %p, %d);\n", wError, lpstrBuffer, uLength);
 	if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
 	lpstrBuffer[0] = '\0';
@@ -534,10 +533,8 @@
 			msgptr = "Unknown MCI Error !\n";
 			break;
 		}
-	maxbuf = MIN(uLength - 1, strlen(msgptr));
-	if (maxbuf > 0) strncpy(lpstrBuffer, msgptr, maxbuf);
-	lpstrBuffer[maxbuf + 1] = '\0';
-	return(TRUE);
+        lstrcpyn(lpstrBuffer, msgptr, uLength);
+	return TRUE;
 }
 
 
@@ -708,12 +705,10 @@
 					ptr += len;
 					InstalledListLen += len;
 					InstalledCount++;
-					}
 				}
-			if (lpParms->dwRetSize < InstalledListLen) {
-				strncpy(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 2);
-				lpstrReturn[lpParms->dwRetSize - 1] = '\0';
-				}
+			}
+			if (lpParms->dwRetSize < InstalledListLen)
+				lstrcpyn(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
 			else
 				strcpy(lpstrReturn, lpInstallNames);
 			return 0;
@@ -781,7 +776,7 @@
 }
 
 /**************************************************************************
-* 				mciGetDeviceID			[MMSYSTEM.703]
+* 				mciGetDeviceID	       	[MMSYSTEM.703]
 */
 UINT mciGetDeviceID (LPCSTR lpstrName)
 {
@@ -860,12 +855,11 @@
 
 
 /**************************************************************************
-* 				midiGetErrorText 		[internal]
+* 				midiGetErrorText       	[internal]
 */
 UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
 {
 	LPSTR	msgptr;
-	int		maxbuf;
 	if ((lpText == NULL) || (uSize < 1)) return(FALSE);
 	lpText[0] = '\0';
 	switch(uError) {
@@ -901,17 +895,15 @@
 			msgptr = "Unknown MIDI Error !\n";
 			break;
 		}
-	maxbuf = MIN(uSize - 1, strlen(msgptr));
-	if (maxbuf > 0) strncpy(lpText, msgptr, maxbuf);
-	lpText[maxbuf + 1] = '\0';
-	return(TRUE);
+	lstrcpyn(lpText, msgptr, uSize);
+	return TRUE;
 }
 
 /**************************************************************************
-* 				midiOutOpen			[MMSYSTEM.204]
+* 				midiOutOpen    		[MMSYSTEM.204]
 */
 UINT midiOutOpen(HMIDIOUT FAR* lphMidiOut, UINT uDeviceID,
-    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+		 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
 {
 	HMIDI	hMidiOut;
 	LPMIDIOPENDESC	lpDesc;
@@ -925,7 +917,7 @@
 		dprintf_mmsys(stddeb, "midiOutOpen	// MIDI_MAPPER mode requested !\n");
 		bMapperFlg = TRUE;
 		uDeviceID = 0;
-		}
+	}
 	hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
 	if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
 	lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiOut);
@@ -1300,7 +1292,6 @@
 UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
 {
 	LPSTR	msgptr;
-	int		maxbuf;
 	dprintf_mmsys(stddeb, "waveGetErrorText(%04X, %p, %d);\n", uError, lpText, uSize);
 	if ((lpText == NULL) || (uSize < 1)) return(FALSE);
 	lpText[0] = '\0';
@@ -1357,10 +1348,8 @@
 			msgptr = "Unknown MMSYSTEM Error !\n";
 			break;
 		}
-	maxbuf = MIN(uSize - 1, strlen(msgptr));
-	if (maxbuf > 0) strncpy(lpText, msgptr, maxbuf);
-	lpText[maxbuf + 1] = '\0';
-	return(TRUE);
+	lstrcpyn(lpText, msgptr, uSize);
+	return TRUE;
 }
 
 /**************************************************************************
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 89ae404..d6e182c 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -1249,8 +1249,8 @@
 /***********************************************************************
  *           BitBlt    (GDI.34)
  */
-BOOL BitBlt( HDC hdcDst, short xDst, short yDst, short width, short height,
-	     HDC hdcSrc, short xSrc, short ySrc, DWORD rop )
+BOOL BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width, INT height,
+	     HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
 {
     DC *dcDst, *dcSrc;
 
diff --git a/objects/font.c b/objects/font.c
index be7ac76..407d15e 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -484,8 +484,7 @@
     if (!dc) return 0;
     if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
         return 0;
-    strncpy( name, font->logfont.lfFaceName, count );
-    name[count-1] = '\0';
+    lstrcpyn( name, font->logfont.lfFaceName, count );
     return strlen(name);
 }
 
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 7f0e6a3..bde259b 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -417,7 +417,7 @@
   HANDLE       	hLog;
   int	       	nRet = 0;
   
-  if (lpEnumFunc == NULL) {
+  if (lpEnumFunc == 0) {
     fprintf(stderr,"EnumObjects // Bad EnumProc callback address !\n");
     return 0;
   }
diff --git a/objects/metafile.c b/objects/metafile.c
index 6cc68b6..297f514 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -245,7 +245,8 @@
 	return FALSE;
 
     /* create the handle table */
-    hHT = GlobalAlloc(GMEM_MOVEABLE, sizeof(HANDLETABLE) * mh->mtNoObjects);
+    hHT = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
+		      sizeof(HANDLETABLE) * mh->mtNoObjects);
     ht = (HANDLETABLE *)GlobalLock(hHT);
 
     /* loop through metafile playing records */
diff --git a/rc/winerc.c b/rc/winerc.c
index 4e1aa52..c01227f 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -12,7 +12,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <windows.h>
-#include <neexe.h>
+/* #include <neexe.h> */
 #include "parser.h"
 #include "y.tab.h"
 
@@ -539,16 +539,7 @@
     fprintf( header, "/* %s\n"
                      " * This file is automatically generated. Do not edit!\n"
                      " */\n\n"
-                     "#ifndef __RESOURCE_DEFINED__\n"
-                     "#define __RESOURCE_DEFINED__\n"
-                     "struct resource\n"
-                     "{\n"
-                     "    int id, type;\n"
-                     "    char *name;\n"
-                     "    unsigned char *bytes;\n"
-                     "    unsigned int size;\n"
-                     "};\n"
-                     "#endif\n", hname );
+                     "#include \"resource.h\"\n", hname );
 
     /* Declare the resources */
 
@@ -583,15 +574,15 @@
         int type;
         switch(it->type)
         {
-        case acc:type=NE_RSCTYPE_ACCELERATOR;break;
-        case bmp:type=NE_RSCTYPE_BITMAP;break;
-        case cur:type=NE_RSCTYPE_CURSOR;break;
-        case dlg:type=NE_RSCTYPE_DIALOG;break;
-        case fnt:type=NE_RSCTYPE_FONT;break;
-        case ico:type=NE_RSCTYPE_ICON;break;
-        case men:type=NE_RSCTYPE_MENU;break;
-        case rdt:type=NE_RSCTYPE_RCDATA;break;
-        case str:type=NE_RSCTYPE_STRING;break;
+        case acc:type=RT_ACCELERATOR;break;
+        case bmp:type=RT_BITMAP;break;
+        case cur:type=RT_CURSOR;break;
+        case dlg:type=RT_DIALOG;break;
+        case fnt:type=RT_FONT;break;
+        case ico:type=RT_ICON;break;
+        case men:type=RT_MENU;break;
+        case rdt:type=RT_RCDATA;break;
+        case str:type=RT_STRING;break;
         default:fprintf(stderr,"Unknown restype\n");type=-1;break;
         }
         if(it->n_type)
@@ -610,6 +601,22 @@
     for (it=top;it;it=it->next)
         fprintf( code, "  &%s,\n", get_resource_name(it) );
     fprintf( code, "  0\n};\n" );
+
+        /* Perform autoregistration */
+        fprintf( code, 
+                "#ifdef WINELIB\n"
+                "static void DoIt() WINE_CONSTRUCTOR;\n"
+                "static void DoIt()\n"
+                "{\n"
+                "\tLIBRES_RegisterResources(%sTable);\n"
+                "}\n\n"
+                "#ifndef HAVE_WINE_CONSTRUCTOR\n"
+                "void LIBWINE_Register_%s(){\n"
+                "\tDoIt();\n"
+                "}\n"
+                "#endif\n"
+                "#endif /*WINELIB*/\n"
+                ,prefix,prefix);
 }
 
 gen_res* make_font(gen_res* res)
diff --git a/toolkit/Makefile.in b/toolkit/Makefile.in
index a1e6cb0..46befbf 100644
--- a/toolkit/Makefile.in
+++ b/toolkit/Makefile.in
@@ -30,7 +30,7 @@
 	echo WINDOWS_H_ENDS_HERE >>hello3res.rct
 	cat hello3res.rc  >>hello3res.rct
 	$(CC) $(ALLCFLAGS) -E -x c -P hello3res.rct | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ../rc/winerc -o hello3res -v -p hello3
-	gcc -c hello3res.c
+	gcc -c $(ALLCFLAGS) hello3res.c
 
 @MAKE_RULES@
 
diff --git a/toolkit/heap.c b/toolkit/heap.c
index 40e52cb..7bb3afd 100644
--- a/toolkit/heap.c
+++ b/toolkit/heap.c
@@ -108,7 +108,10 @@
 
 HANDLE LocalFree (HANDLE hMem)
 {
-    void **m = HEAP_FindSlot (hMem);
+    void **m;
+  if(!hMem)
+    return 0;
+  m = HEAP_FindSlot (hMem);
 
     free (*m);
     *m = 0;
@@ -232,7 +235,10 @@
 
 HANDLE HEAP_Free (HANDLE hMem)
 {
-  HeapData* m=(HeapData*)hMem;
+  HeapData* m;
+  if(!hMem)
+    return 0;
+  m=(HeapData*)hMem;
   free(m-1);
   return 0;
 }
@@ -296,7 +302,6 @@
   return HEAP_Size(hMem);
 }
 
-
 BOOL LocalUnlock (HANDLE hMem)
 {
   return 0;
diff --git a/toolkit/hello3.c b/toolkit/hello3.c
index 90fadb1..5b9cd51 100644
--- a/toolkit/hello3.c
+++ b/toolkit/hello3.c
@@ -87,7 +87,7 @@
 
     wnd = CreateWindow ("class", "Test app", WS_OVERLAPPEDWINDOW,
 			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 
-			LoadMenuIndirect(hello3_MENU_MAIN.bytes), inst, 0);
+			LoadMenu(inst,"MAIN"), inst, 0);
     ShowWindow (wnd, show);
     UpdateWindow (wnd);
 
diff --git a/toolkit/libres.c b/toolkit/libres.c
index c983ff6..ae23b41 100644
--- a/toolkit/libres.c
+++ b/toolkit/libres.c
@@ -5,19 +5,12 @@
  */
 
 #include <stdio.h>
-#include "windows.h"
-
-struct resource /* This needs to coincide with what winerc generates. */
-{               /* It should really only appear in one place.         */
-  int id, type;
-  char *name;
-  unsigned char *bytes;
-  unsigned int size;
-};
+#include <stdlib.h>
+#include "libres.h"
 
 typedef struct RLE
 {
-  struct resource** Resources  /* NULL-terminated array of pointers */
+  struct resource** Resources;  /* NULL-terminated array of pointers */
   struct RLE* next;
 } ResListE;
 
@@ -28,11 +21,11 @@
   ResListE** Curr;
   ResListE* n;
   for(Curr=&ResourceList; *Curr; Curr=&((*Curr)->next)) { }
-  n=malloc(sizeof(ResListE));
+  n=xmalloc(sizeof(ResListE));
   if(n)
   {
-    n.Resources=Res;
-    n.next=NULL;
+    n->Resources=Res;
+    n->next=NULL;
     *Curr=n;
   }
   else
@@ -42,9 +35,48 @@
 /**********************************************************************
  *	    LIBRES_FindResource    
  */
-HRSRC LIBRES_FindResource( HMODULE hModule, SEGPTR name, SEGPTR type )
+HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCSTR name, LPCSTR type )
 {
-  WINELIB_UNIMP("LIBRES_FindResource()");
+  int nameid=0,typeid;
+  ResListE* ResBlock;
+  struct resource** Res;
+
+  if(HIWORD(name))
+  {
+    if(*name=='#')
+    {
+      nameid=atoi(name+1);
+      name=NULL;
+    }
+  }
+  else
+  {
+    nameid=LOWORD(name);
+    name=NULL;
+  }
+  if(HIWORD(type))
+  {
+    if(*type=='#')
+      typeid=atoi(type+1);
+    else
+    {
+      WINELIB_UNIMP("LIBRES_FindResource(*,*,type=string)");
+      return 0;
+    }
+  }
+  else
+    typeid=LOWORD(type);
+  
+  for(ResBlock=ResourceList; ResBlock; ResBlock=ResBlock->next)
+    for(Res=ResBlock->Resources; *Res; Res++)
+      if(name)
+      {
+	if((*Res)->type==typeid && !strcmp((*Res)->name,name))
+	  return (HRSRC)*Res;
+      }
+      else
+	if((*Res)->type==typeid && (*Res)->id==nameid)
+	  return (HRSRC)*Res;
   return 0;
 }
 
@@ -52,7 +84,7 @@
 /**********************************************************************
  *	    LIBRES_LoadResource    
  */
-HGLOBAL LIBRES_LoadResource( HMODULE hModule, HRSRC hRsrc )
+HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc )
 {
   return (HGLOBAL)(((struct resource*)hRsrc)->bytes);
 }
@@ -61,7 +93,7 @@
 /**********************************************************************
  *	    LIBRES_LockResource    
  */
-LPVOID LIBRES_LockResource( HMODULE hModule, HGLOBAL handle )
+LPVOID LIBRES_LockResource( HGLOBAL handle )
 {
   return handle;
 }
@@ -70,9 +102,10 @@
 /**********************************************************************
  *	    LIBRES_FreeResource    
  */
-BOOL LIBRES_FreeResource( HMODULE hModule, HGLOBAL handle )
+BOOL LIBRES_FreeResource( HGLOBAL handle )
 {
-  return 0;
+  WINELIB_UNIMP("LIBRES_FreeResource()");
+  return 0; /* Obsolete in Win32 */
 }
 
 
@@ -82,25 +115,25 @@
 INT LIBRES_AccessResource( HINSTANCE hModule, HRSRC hRsrc )
 {
   WINELIB_UNIMP("LIBRES_AccessResource()");
-  return -1;
+  return -1; /* Obsolete in Win32 */
 }
 
 
 /**********************************************************************
  *	    LIBRES_SizeofResource    
  */
-DWORD LIBRES_SizeofResource( HMODULE hModule, HRSRC hRsrc )
+DWORD LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
 {
-  return (HGLOBAL)(((struct resource*)hRsrc)->size);
+  return (DWORD)(((struct resource*)hRsrc)->size);
 }
 
 
 /**********************************************************************
  *	    LIBRES_AllocResource    
  */
-HGLOBAL LIBRES_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size )
+HGLOBAL LIBRES_AllocResource( HINSTANCE hModule, HRSRC hRsrc, DWORD size )
 {
   WINELIB_UNIMP("LIBRES_AllocResource()");
-  return 0;
+  return 0; /* Obsolete in Win32 */
 }
 
diff --git a/tools/build.c b/tools/build.c
index 499f688..53a0150 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -789,7 +789,29 @@
         case TYPE_CDECL:
 	    varargs=0;
             argc=strlen(fdp->arg_types);
-	    printf( "void %s_%d(", UpperDLLName, i);
+	    if(odp->type == TYPE_STDCALL)
+	    {
+		/* Output a function prototype with stdcall attribute */
+		printf( "void %s_%d(", UpperDLLName, i);
+		for(argno=0;argno<argc;argno++)
+		{
+		    switch(fdp->arg_types[argno])
+		    {
+		    case 'p': printf( "void *");break;
+		    case 'l': printf( "int ");break;
+		    case '.': printf( "... ");varargs=argno;break;
+		    default:
+			fprintf(stderr, "Not supported argument type %c\n",
+				fdp->arg_types[argno]);
+			exit(1);
+		    }
+		    if(fdp->arg_types[argno]!='.') putchar( 'a'+argno );
+		    if (argno!=argc-1) putchar( ',' );
+		}
+		printf( ") __attribute((stdcall));" );
+	    }
+
+            printf( "void %s_%d(", UpperDLLName, i);
             for(argno=0;argno<argc;argno++)
             {
                 switch(fdp->arg_types[argno])
@@ -806,7 +828,6 @@
                 if (argno!=argc-1) putchar( ',' );
             }
             printf( ")" );
-	    if(odp->type == TYPE_STDCALL) printf(" /*__attribute__ ((stdcall))*/");
             printf( "\n{\n" );
 	    if (varargs) printf( "\tva_list valist;\n\n\tva_start(valist, %c);",
 	    			 'a'+varargs-1 );
diff --git a/win32/advapi.c b/win32/advapi.c
index be633d8..7c9baf2 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -1,14 +1,14 @@
 /*
  * Win32 advapi functions
  *
- * Copyright 1995 Martin von Loewis
+ * Copyright 1995 Sven Verdoolaege
  */
 
 #include <stdio.h>
 #include <unistd.h>
 #include "windows.h"
 #include "winerror.h"
-/*#include "kernel32.h"*/
+#include "advapi32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -16,7 +16,7 @@
  *           GetUserNameA   (ADVAPI32.67)
  */
 
-int GetUserNameA(LPSTR lpszName, LPDWORD lpSize)
+BOOL WINAPI GetUserNameA(LPSTR lpszName, LPDWORD lpSize)
 {
   size_t len;
   char *name;
@@ -32,3 +32,49 @@
   return 1;
 }
 
+/***********************************************************************
+ *           RegCreateKeyEx   (ADVAPI32.130)
+ */
+WINAPI LONG RegCreateKeyEx(HKEY key,
+                            const char *subkey,
+                            long dontuse,
+                            const char *keyclass,
+                            DWORD options,
+                            REGSAM sam,
+                            SECURITY_ATTRIBUTES *atts,
+                            HKEY *res,
+                            DWORD *disp)
+{
+	/* ahum */
+	return RegCreateKey(key, subkey, res);
+}
+
+/***********************************************************************
+ *           RegSetValueEx   (ADVAPI32.169)
+ */
+
+WINAPI LONG RegSetValueEx (HKEY key,
+                const char *name,
+                DWORD dontuse,
+                DWORD type,
+                const void* data,
+                DWORD len
+                )
+{
+	return 0;
+}
+
+/***********************************************************************
+ *           RegQueryValueEx   (ADVAPI32.157)
+ */
+
+WINAPI LONG RegQueryValueEx(HKEY key,
+                             const char *subkey,
+                             DWORD dontuse,
+                             DWORD *type,
+                             void *ptr,
+                             DWORD *len)
+{
+	return 0;
+}
+
diff --git a/win32/environment.c b/win32/environment.c
index 17e2966..e754f41 100644
--- a/win32/environment.c
+++ b/win32/environment.c
@@ -6,10 +6,12 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 #include "windows.h"
 #include "winerror.h"
 #include "kernel32.h"
 #include "task.h"
+#include "pe_image.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -20,8 +22,13 @@
 LPSTR GetCommandLineA(void)
 {
     static char buffer[256];
+    char *cp;
     PDB *pdb = (PDB *)GlobalLock( GetCurrentPDB() );
-    memcpy( buffer, &pdb->cmdLine[1], pdb->cmdLine[0] );
+
+    strcpy(buffer, wine_files->name);
+    cp = buffer+strlen(buffer);
+    *cp++ = ' ';
+    memcpy( cp, &pdb->cmdLine[1], pdb->cmdLine[0] );
     dprintf_win32(stddeb,"CommandLine = %s\n", buffer );
     return buffer;
 }
diff --git a/win32/error.c b/win32/error.c
index 7204884..242bcc0 100644
--- a/win32/error.c
+++ b/win32/error.c
@@ -5,14 +5,100 @@
  */
 
 #include <stdio.h>
+#include <errno.h>
 #include "windows.h"
 #include "winerror.h"
 #include "kernel32.h"
 #include "stddebug.h"
 #include "debug.h"
 
+/* WIN32_LastError contains the last error that occurred in the
+ * Win32 API.  This value should be stored separately for each
+ * thread, when we eventually get thread support.
+ */
 static int WIN32_LastError;
 
+/* The errno_xlat_table contains the errno-to-Win32 error
+ * mapping.  Since this is a single table, it can't easily
+ * take into account function-specific differences, so there
+ * will probably be quite a few points where we don't exactly
+ * match what NT would return.  Then again, neither does
+ * Windows 95. :-)
+ */
+typedef struct {
+    int         errno;
+    DWORD       win32err;
+} ERRNO_XLAT_TABLE;
+
+/* The table looks pretty ugly due to the preprocessor stuff,
+ * but I honestly have no idea how many of these values are
+ * portable.  I'm not even sure how many of them are even
+ * used at all. :-)
+ */
+static ERRNO_XLAT_TABLE errno_xlat_table[] = {
+#if defined(EPERM)
+    {   EPERM,          ERROR_ACCESS_DENIED             },
+#endif
+#if defined(ENOENT)
+    {   ENOENT,         ERROR_FILE_NOT_FOUND            },
+#endif
+#if defined(ESRCH)
+    {   ESRCH,          ERROR_INVALID_PARAMETER         },
+#endif
+#if defined(EIO)
+    {   EIO,            ERROR_IO_DEVICE                 },
+#endif
+#if defined(ENOEXEC)
+    {   ENOEXEC,        ERROR_BAD_FORMAT                },
+#endif
+#if defined(EBADF)
+    {   EBADF,          ERROR_INVALID_HANDLE            },
+#endif
+#if defined(ENOMEM)
+    {   ENOMEM,         ERROR_OUTOFMEMORY               },
+#endif
+#if defined(EACCES)
+    {   EACCES,         ERROR_ACCESS_DENIED             },
+#endif
+#if defined(EBUSY)
+    {   EBUSY,          ERROR_BUSY                      },
+#endif
+#if defined(EEXIST)
+    {   EEXIST,         ERROR_FILE_EXISTS               },
+#endif
+#if defined(ENODEV)
+    {   ENODEV,         ERROR_BAD_DEVICE                },
+#endif
+#if defined(EINVAL)
+    {   EINVAL,         ERROR_INVALID_PARAMETER         },
+#endif
+#if defined(EMFILE)
+    {   EMFILE,         ERROR_TOO_MANY_OPEN_FILES       },
+#endif
+#if defined(ETXTBSY)
+    {   ETXTBSY,        ERROR_BUSY,                     },
+#endif
+#if defined(ENOSPC)
+    {   ENOSPC,         ERROR_DISK_FULL                 },
+#endif
+#if defined(ESPIPE)
+    {   ESPIPE,         ERROR_SEEK_ON_DEVICE            },
+#endif
+#if defined(EPIPE)
+    {   EPIPE,          ERROR_BROKEN_PIPE               },
+#endif
+#if defined(EDEADLK)
+    {   EDEADLK,        ERROR_POSSIBLE_DEADLOCK         },
+#endif
+#if defined(ENAMETOOLONG)
+    {   ENAMETOOLONG,   ERROR_FILENAME_EXCED_RANGE      },
+#endif
+#if defined(ENOTEMPTY)
+    {   ENOTEMPTY,      ERROR_DIR_NOT_EMPTY             },
+#endif
+    {   -1,             0                               }
+};
+
 /**********************************************************************
  *              GetLastError            (KERNEL32.227)
  */
@@ -34,5 +120,18 @@
 
 DWORD ErrnoToLastError(int errno_num)
 {
-    return errno_num;   /* Obviously not finished yet. :-) */
+    DWORD rc = ERROR_UNKNOWN;
+    int i = 0;
+
+    while(errno_xlat_table[i].errno != -1)
+    {
+        if(errno_xlat_table[i].errno == errno_num)
+        {
+            rc = errno_xlat_table[i].win32err;
+            break;
+        }
+        i++;
+    }
+
+    return rc;
 }
diff --git a/win32/file.c b/win32/file.c
index a914e23..9146964 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -1,7 +1,7 @@
 /*
  * Win32 kernel functions
  *
- * Copyright 1995 Martin von Loewis and Cameron Heide
+ * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide
  */
 
 #include <errno.h>
@@ -9,8 +9,10 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/mman.h>
 #include <fcntl.h>
 #include <string.h>
+#include <time.h>
 #include "windows.h"
 #include "winerror.h"
 #include "kernel32.h"
@@ -25,31 +27,151 @@
 extern FILE_OBJECT *hstdout;
 extern FILE_OBJECT *hstderr;
 
+static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime);
 static int TranslateCreationFlags(DWORD create_flags);
 static int TranslateAccessFlags(DWORD access_flags);
 
 /***********************************************************************
- *           GetFileInformationByHandle       (KERNEL32.219)
+ *           OpenFileMappingA             (KERNEL32.397)
  *
  */
-HANDLE WINAPI  CreateFileA(const char * filename, DWORD a, DWORD b, void * c,
-                           DWORD d, DWORD e, DWORD f)
+WINAPI HANDLE32 OpenFileMapping(DWORD access, BOOL inherit,const char *fname)
 {
-   dprintf_win32(stderr, "CreateFileA: %s\n", filename);
-   return -1;
+	return 0;
+}
+/***********************************************************************
+ *           CreateFileMappingA		(KERNEL32.46)
+ *
+ */
+WINAPI HANDLE32 CreateFileMapping(HANDLE32 h,SECURITY_ATTRIBUTES *ats,
+  DWORD pot,  DWORD sh,  DWORD hlow,  const char * lpName )
+{
+    FILE_OBJECT *file_obj;
+    FILEMAP_OBJECT *filemap_obj;
+    int fd;
+
+    if (sh)
+    {
+        SetLastError(ErrnoToLastError(errno));
+        return INVALID_HANDLE_VALUE;
+    }
+    fd = open(lpName, O_CREAT, 0666);
+    #if 0
+    fd = open(DOS_GetUnixFileName(lpName), 0, 0666);
+    #endif
+    if(fd == -1)
+    {
+        SetLastError(ErrnoToLastError(errno));
+        return INVALID_HANDLE_VALUE;
+    }
+    file_obj = (FILE_OBJECT *)
+	                 CreateKernelObject(sizeof(FILE_OBJECT));
+    if(file_obj == NULL)
+    {
+        SetLastError(ERROR_UNKNOWN);
+        return 0;
+    }
+    filemap_obj = (FILEMAP_OBJECT *)
+	                 CreateKernelObject(sizeof(FILEMAP_OBJECT));
+    if(filemap_obj == NULL)
+    {
+	ReleaseKernelObject(file_obj);
+        SetLastError(ERROR_UNKNOWN);
+        return 0;
+    }
+    file_obj->common.magic = KERNEL_OBJECT_FILE;
+    file_obj->fd = fd;
+    file_obj->type = FILE_TYPE_DISK;
+    filemap_obj->common.magic = KERNEL_OBJECT_FILEMAP;
+    filemap_obj->file_obj = file_obj;
+    filemap_obj->prot = TranslateProtectionFlags(pot);
+    filemap_obj->size = hlow;
+    return (HANDLE32)filemap_obj;;
+}
+
+/***********************************************************************
+ *           MapViewOfFileEx                  (KERNEL32.386)
+ *
+ */
+WINAPI void *MapViewOfFileEx(HANDLE32 handle, DWORD access, DWORD offhi,
+                             DWORD offlo, DWORD size, DWORD st)
+{
+    if (!size) size = ((FILEMAP_OBJECT *)handle)->size;
+    return mmap (st, size, ((FILEMAP_OBJECT *)handle)->prot, 
+                 MAP_ANON|MAP_PRIVATE, 
+		 ((FILEMAP_OBJECT *)handle)->file_obj->fd,
+		 offlo);
 }
 
 /***********************************************************************
  *           GetFileInformationByHandle       (KERNEL32.219)
  *
  */
-DWORD WINAPI GetFileInformationByHandle(HANDLE hFile, 
+DWORD WINAPI GetFileInformationByHandle(FILE_OBJECT *hFile, 
                                         BY_HANDLE_FILE_INFORMATION *lpfi)
 {
-    memset(lpfi, 0, sizeof(BY_HANDLE_FILE_INFORMATION));
+  struct stat file_stat;
+    int rc;
+
+    if(ValidateKernelObject((HANDLE32)hFile) != 0)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return 0;
+    }
+    if(hFile->common.magic != KERNEL_OBJECT_FILE)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return 0;
+    }
+
+    rc = fstat(hFile->fd, &file_stat);
+    if(rc == -1)
+    {
+        SetLastError(ErrnoToLastError(errno));
+        return 0;
+    }
+
+    /* Translate the file attributes.
+     */
+    lpfi->dwFileAttributes = 0;
+    if(file_stat.st_mode & S_IFREG)
+        lpfi->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL;
+    if(file_stat.st_mode & S_IFDIR)
+        lpfi->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+    if(file_stat.st_mode & S_IWRITE == 0)
+        lpfi->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
+
+    /* Translate the file times.  Use the last modification time
+     * for both the creation time and write time.
+     */
+    UnixTimeToFileTime(file_stat.st_mtime, &(lpfi->ftCreationTime));
+    UnixTimeToFileTime(file_stat.st_mtime, &(lpfi->ftLastWriteTime));
+    UnixTimeToFileTime(file_stat.st_atime, &(lpfi->ftLastAccessTime));
+
+    lpfi->nFileSizeLow = file_stat.st_size;
+    lpfi->nNumberOfLinks = file_stat.st_nlink;
+    lpfi->nFileIndexLow = file_stat.st_ino;
+
+    /* Zero out currently unused fields.
+     */
+    lpfi->dwVolumeSerialNumber = 0;
+    lpfi->nFileSizeHigh = 0;
+    lpfi->nFileIndexHigh = 0;
+
     return 1;
 }
 
+
+static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime)
+{
+    /* This isn't anywhere close to being correct, but should
+     * work for now.
+     */
+    filetime->dwLowDateTime  = (unix_time & 0x0000FFFF) << 16;
+    filetime->dwHighDateTime = (unix_time & 0xFFFF0000) >> 16;
+}
+
+
 /***********************************************************************
  *           GetFileType              (KERNEL32.222)
  *
@@ -95,7 +217,7 @@
 
         default:
             rc = INVALID_HANDLE_VALUE;
-            SetLastError(ERROR_UNKNOWN);
+            SetLastError(ERROR_INVALID_HANDLE);
             break;
     }
 
@@ -115,12 +237,12 @@
 
     if(ValidateKernelObject((HANDLE32)hFile) != 0)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return ((DWORD)0xFFFFFFFF);
     }
     if(hFile->common.magic != KERNEL_OBJECT_FILE)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return ((DWORD)0xFFFFFFFF);
     }
 
@@ -149,12 +271,12 @@
 
     if(ValidateKernelObject((HANDLE32)hFile) != 0)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
     if(hFile->common.magic != KERNEL_OBJECT_FILE)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
 
@@ -175,12 +297,12 @@
 
     if(ValidateKernelObject((HANDLE32)hFile) != 0)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
     if(hFile->common.magic != KERNEL_OBJECT_FILE)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
 
@@ -199,11 +321,12 @@
 /*************************************************************************
  *              CreateFile              (KERNEL32.45)
  *
- * Doesn't support character devices or pipes yet.
+ * Doesn't support character devices, pipes, template files, or a
+ * lot of the 'attributes' flags yet.
  */
-HANDLE32 CreateFile(LPSTR filename, DWORD access, DWORD sharing,
-                    LPSECURITY_ATTRIBUTES security, DWORD creation,
-                    DWORD attributes, HANDLE32 template)
+HANDLE32 CreateFileA(LPSTR filename, DWORD access, DWORD sharing,
+                     LPSECURITY_ATTRIBUTES security, DWORD creation,
+                     DWORD attributes, HANDLE32 template)
 {
     int access_flags, create_flags;
     int fd;
@@ -216,7 +339,7 @@
     create_flags = TranslateCreationFlags(creation);
 
     if(template)
-        printf("CreateFile: template handles not supported.\n");
+        dprintf_win32(stddeb, "CreateFile: template handles not supported.\n");
 
     /* If the name starts with '\\?' or '\\.', ignore the first 3 chars.
      */
@@ -227,7 +350,7 @@
      */
     if(!strncmp(filename, "\\\\", 2))
     {
-        printf("CreateFile: UNC names not supported.\n");
+        dprintf_win32(stddeb, "CreateFile: UNC names not supported.\n");
         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
         return INVALID_HANDLE_VALUE;
     }
@@ -266,7 +389,7 @@
     file_obj = (FILE_OBJECT *)CreateKernelObject(sizeof(FILE_OBJECT));
     if(file_obj == NULL)
     {
-        SetLastError(ERROR_UNKNOWN);
+        SetLastError(ERROR_INVALID_HANDLE);
         return INVALID_HANDLE_VALUE;
     }
     file_obj->common.magic = KERNEL_OBJECT_FILE;
diff --git a/win32/init.c b/win32/init.c
index b4d3f0d..d2e8936 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -12,6 +12,7 @@
 #include "kernel32.h"
 #include "handle32.h"
 #include "stddebug.h"
+#define DEBUG_WIN32
 #include "debug.h"
   
 /* The global error value
@@ -48,7 +49,7 @@
             break;
 
         default:
-            printf("CloseHandle: type %ld not implemented yet.\n",
+            dprintf_win32(stddeb, "CloseHandle: type %ld not implemented yet.\n",
                    handle->magic);
             break;
     }
diff --git a/win32/memory.c b/win32/memory.c
index 2ee8eb5..78b04fe 100644
--- a/win32/memory.c
+++ b/win32/memory.c
@@ -17,6 +17,10 @@
 #include "stddebug.h"
 #include "debug.h"
 
+#ifndef PROT_NONE  /* FreeBSD doesn't define PROT_NONE */
+#define PROT_NONE 0
+#endif
+
 typedef struct {
     caddr_t	ptr;
     long	size;
@@ -72,33 +76,8 @@
         ptr = lpvAddress;
     }
     if (fdwAllocationType & MEM_COMMIT) {
-        switch(fdwProtect & ~(PAGE_GUARD | PAGE_NOCACHE)) {
-	    case PAGE_READONLY:
-	        prot=PROT_READ;
-		break;
-	    case PAGE_READWRITE:
-	        prot=PROT_READ|PROT_WRITE;
-		break;
-	    case PAGE_WRITECOPY:
-	        prot=PROT_WRITE;
-		break;
-	    case PAGE_EXECUTE:
-	        prot=PROT_EXEC;
-		break;
-	    case PAGE_EXECUTE_READ:
-	        prot=PROT_EXEC|PROT_READ;
-		break;
-	    case PAGE_EXECUTE_READWRITE:
-	        prot=PROT_EXEC|PROT_READ|PROT_WRITE;
-		break;
-	    case PAGE_EXECUTE_WRITECOPY:
-	        prot=PROT_EXEC|PROT_WRITE;
-		break;
-	    case PAGE_NOACCESS:
-	    default:
-	        prot=PROT_NONE;
-		break;
-	}
+        prot = TranslateProtectionFlags(fdwProtect & 
+                                          ~(PAGE_GUARD | PAGE_NOCACHE));
 	mprotect(ptr, cbSize, prot);
     }
     return ptr;
@@ -144,3 +123,36 @@
     return 1;
 }
 
+int TranslateProtectionFlags(DWORD protection_flags)
+{
+    int prot;
+
+        switch(protection_flags) {
+	    case PAGE_READONLY:
+	        prot=PROT_READ;
+		break;
+	    case PAGE_READWRITE:
+	        prot=PROT_READ|PROT_WRITE;
+		break;
+	    case PAGE_WRITECOPY:
+	        prot=PROT_WRITE;
+		break;
+	    case PAGE_EXECUTE:
+	        prot=PROT_EXEC;
+		break;
+	    case PAGE_EXECUTE_READ:
+	        prot=PROT_EXEC|PROT_READ;
+		break;
+	    case PAGE_EXECUTE_READWRITE:
+	        prot=PROT_EXEC|PROT_READ|PROT_WRITE;
+		break;
+	    case PAGE_EXECUTE_WRITECOPY:
+	        prot=PROT_EXEC|PROT_WRITE;
+		break;
+	    case PAGE_NOACCESS:
+	    default:
+	        prot=PROT_NONE;
+		break;
+	}
+   return prot;
+}
diff --git a/win32/object_mgt.c b/win32/object_mgt.c
index 668a13a..07a6ed4 100644
--- a/win32/object_mgt.c
+++ b/win32/object_mgt.c
@@ -14,6 +14,6 @@
 
 int ValidateKernelObject(KERNEL_OBJECT *ptr)
 {
-    return 0;
+  return (!ptr || (short int)ptr==-1);
 }
 
diff --git a/win32/process.c b/win32/process.c
index 3773dbb..8fb8fe4 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -9,6 +9,7 @@
 #include "windows.h"
 #include "winerror.h"
 #include "kernel32.h"
+#include "handle32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -21,3 +22,63 @@
         exit(status);
 }
 
+/***********************************************************************
+ *           CreateMutexA    (KERNEL32.52)
+ */
+WINAPI HANDLE32 CreateMutexA (SECURITY_ATTRIBUTES *sa, BOOL on, const char *a)
+{
+	return 0;
+}
+
+/***********************************************************************
+ *           ReleaseMutex    (KERNEL32.435)
+ */
+WINAPI BOOL ReleaseMutex (HANDLE32 h)
+{
+	return 0;
+}
+
+/***********************************************************************
+ *           CreateEventA    (KERNEL32.43)
+ */
+WINAPI HANDLE32 CreateEventA (SECURITY_ATTRIBUTES *sa, BOOL au, BOOL on, const char
+*name)
+{
+	return 0;
+}
+/***********************************************************************
+ *           SetEvent    (KERNEL32.487)
+ */
+WINAPI BOOL SetEvent (HANDLE32 h)
+{
+	return 0;
+}
+/***********************************************************************
+ *           ResetEvent    (KERNEL32.439)
+ */
+WINAPI BOOL ResetEvent (HANDLE32 h)
+{
+	return 0;
+}
+/***********************************************************************
+ *           WaitForSingleObject    (KERNEL32.561)
+ */
+DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD a)
+{
+	return 0;
+}
+/***********************************************************************
+ *           DuplicateHandle    (KERNEL32.78)
+ */
+BOOL WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL f, DWORD g)
+{
+	*d = b;
+	return 1;
+}
+/***********************************************************************
+ *           GetCurrentProcess    (KERNEL32.198)
+ */
+HANDLE32 WINAPI GetCurrentProcess(void)
+{
+	return 0;
+}
diff --git a/win32/thread.c b/win32/thread.c
index ec77af5..c88dda4 100644
--- a/win32/thread.c
+++ b/win32/thread.c
@@ -28,4 +28,11 @@
 {
         return FALSE;
 }
+/***********************************************************************
+ *           GetCurrentThread    (KERNEL32.200)
+ */
+HANDLE WINAPI GetCurrentThread(void)
+{
+	return 0;
+}
 
diff --git a/win32/time.c b/win32/time.c
index 29b20ba..04d6780 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -6,6 +6,7 @@
 
 #include <string.h>
 #include <time.h>
+#include <sys/time.h>
 #include <unistd.h>
 #include "windows.h"
 #include "winerror.h"
@@ -14,6 +15,29 @@
 #include "debug.h"
 
 /***********************************************************************
+ *              GetLocalTime            (KERNEL32.228)
+ */
+VOID GetLocalTime(LPSYSTEMTIME systime)
+{
+    time_t local_time;
+    struct tm *local_tm;
+    struct timeval tv;
+
+    time(&local_time);
+    local_tm = localtime(&local_time);
+    gettimeofday(&tv, NULL);
+
+    systime->wYear = local_tm->tm_year + 1900;
+    systime->wMonth = local_tm->tm_mon + 1;
+    systime->wDayOfWeek = local_tm->tm_wday;
+    systime->wDay = local_tm->tm_mday;
+    systime->wHour = local_tm->tm_hour;
+    systime->wMinute = local_tm->tm_min;
+    systime->wSecond = local_tm->tm_sec;
+    systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
+}
+
+/***********************************************************************
  *              GetTimeZoneInformation  (KERNEL32.302)
  */
 DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION tzinfo)
diff --git a/windows/dce.c b/windows/dce.c
index 7cb9df3..15ea232 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -184,7 +184,7 @@
  * clipped by the client area of all ancestors, and then optionally
  * by siblings and children.
  */
-static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags )
+HRGN DCE_GetVisRgn( HWND hwnd, WORD flags )
 {
     RECT rect;
     HRGN hrgn;
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 786c0a7..bc901b0 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -39,6 +39,8 @@
     wndPtr->hText = USER_HEAP_ALLOC( strlen(text) + 1 );
     textPtr = (LPSTR) USER_HEAP_LIN_ADDR( wndPtr->hText );
     strcpy( textPtr, text );
+    if (wndPtr->window)
+        XStoreName( display, wndPtr->window, text );
 }
 
 
diff --git a/windows/event.c b/windows/event.c
index 28f21e1..301e91f 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -18,6 +18,7 @@
 #include "class.h"
 #include "message.h"
 #include "clipboard.h"
+#include "options.h"
 #include "winpos.h"
 #include "registers.h"
 #include "stackframe.h"
@@ -137,6 +138,7 @@
 static void EVENT_ButtonPress( XButtonEvent *event );
 static void EVENT_ButtonRelease( XButtonEvent *event );
 static void EVENT_MotionNotify( XMotionEvent *event );
+static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event );
 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event );
 static void EVENT_Expose( HWND hwnd, XExposeEvent *event );
 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
@@ -190,6 +192,10 @@
 	EVENT_MotionNotify( (XMotionEvent*)event );
 	break;
 
+    case FocusIn:
+        EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event );
+	break;
+
     case FocusOut:
 	EVENT_FocusOut( hwnd, (XFocusChangeEvent*)event );
 	break;
@@ -455,6 +461,17 @@
 
 
 /**********************************************************************
+ *              EVENT_FocusIn
+ */
+static void EVENT_FocusIn (HWND hwnd, XFocusChangeEvent *event )
+{
+    if (event->detail == NotifyPointer) return;
+    if (hwnd != GetActiveWindow()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
+    if ((hwnd != GetFocus()) && ! IsChild( hwnd, GetFocus())) SetFocus( hwnd );
+}
+
+
+/**********************************************************************
  *              EVENT_FocusOut
  *
  * Note: only top-level override-redirect windows get FocusOut events.
@@ -470,12 +487,70 @@
 /**********************************************************************
  *              EVENT_ConfigureNotify
  *
- * The ConfigureNotify event is only selected on the desktop window.
+ * The ConfigureNotify event is only selected on the desktop window
+ * and on top-level windows when the -managed flag is used.
  */
 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
 {
-    desktopX = event->x;
-    desktopY = event->y;
+    if (hwnd == GetDesktopWindow())
+    {
+        desktopX = event->x;
+	desktopY = event->y;
+    }
+    else
+    {
+      /* A managed window; most of this code is shamelessly
+       * stolen from SetWindowPos
+       */
+      
+        WND *wndPtr;
+	WINDOWPOS winpos;
+	RECT newWindowRect, newClientRect;
+
+	if (!(wndPtr = WIN_FindWndPtr( hwnd )))
+	{
+	    dprintf_event(stddeb, "ConfigureNotify: invalid HWND "NPFMT"\n", hwnd);
+	    return;
+	}
+	
+	/* Artificial messages */
+	SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0);
+	SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
+
+	/* Fill WINDOWPOS struct */
+	winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER;
+	winpos.hwnd = hwnd;
+	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 */
+	SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, MAKE_SEGPTR(&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 );
+
+	/* Set new size and position */
+	wndPtr->rectWindow = newWindowRect;
+	wndPtr->rectClient = newClientRect;
+	SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, MAKE_SEGPTR(&winpos));
+    }
 }
 
 
diff --git a/windows/focus.c b/windows/focus.c
index 141bede..6e8e46a 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -2,16 +2,18 @@
  * Focus functions
  *
  * Copyright 1993 David Metcalfe
- * Copyright 1994 Alexandre Julliard
+ *           1994 Alexandre Julliard
+ * 	     1995 Alex Korobka
  *
-static char Copyright[] = "Copyright  David Metcalfe, 1993";
-static char Copyright2[] = "Copyright  Alexandre Julliard, 1994";
-*/
+ */
 
 #include "win.h"
+#include "winpos.h"
+#include "hook.h"
 #include "color.h"
 
-static HWND hWndFocus = 0;
+
+static HWND hwndFocus = 0;
 
 /*****************************************************************
  *               FOCUS_SetXFocus
@@ -44,53 +46,67 @@
 	XInstallColormap( display, COLOR_WinColormap );
 }
 
+/*****************************************************************
+ *	         FOCUS_SwitchFocus 
+ */
+void FOCUS_SwitchFocus(HWND hFocusFrom, HWND hFocusTo)
+{
+    hwndFocus = hFocusTo;
+
+    if (hFocusFrom) SendMessage( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0L);
+    if( !hFocusTo || hFocusTo != hwndFocus )
+	return;
+
+    SendMessage( hFocusTo, WM_SETFOCUS, hFocusFrom, 0L);
+    FOCUS_SetXFocus( hFocusTo );
+}
+
 
 /*****************************************************************
  *               SetFocus            (USER.22)
  */
-
 HWND SetFocus(HWND hwnd)
 {
-    HWND hWndPrevFocus, hwndParent;
-    WND *wndPtr;
+    HWND hWndPrevFocus, hwndTop;
+    WND *wndPtr = WIN_FindWndPtr( hwndTop = hwnd );
 
-    if (hwnd == hWndFocus) return hWndFocus;  /* Nothing to do! */    
-
-    if (hwnd)
+    if (wndPtr)
     {
 	  /* Check if we can set the focus to this window */
 
-	hwndParent = hwnd;
-	while ((wndPtr = WIN_FindWndPtr( hwndParent )) != NULL)
+	while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD  )
 	{
-	    if ((wndPtr->dwStyle & WS_MINIMIZE) ||
-		(wndPtr->dwStyle & WS_DISABLED)) return 0;
-	    if (!(wndPtr->dwStyle & WS_CHILD)) break;
-	    hwndParent = wndPtr->hwndParent;
+	    if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) )
+		 return 0;
+
+	    hwndTop = wndPtr->hwndParent;
+	    wndPtr  = WIN_FindWndPtr( hwndTop );
+	    if ( !wndPtr )
+	         return 0;
 	}
 
-	  /* Now hwndParent is the top-level ancestor. Activate it. */
+	if( hwnd == hwndFocus ) return hwnd;
 
-	if (hwndParent != GetActiveWindow())
+	/* call hooks */
+	if( HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, hwnd, hwndFocus) )
+	    return 0;
+
+        /* activate hwndTop if needed. */
+	if (hwndTop != GetActiveWindow())
 	{
-	    SetWindowPos( hwndParent, HWND_TOP, 0, 0, 0, 0,
-			  SWP_NOSIZE | SWP_NOMOVE );
+	    if (!WINPOS_SetActiveWindow(hwndTop, 0, 0)) return 0;
+
 	    if (!IsWindow( hwnd )) return 0;  /* Abort if window destroyed */
 	}
     }
+    else if( HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, hwndFocus ) )
+             return 0;
 
       /* Change focus and send messages */
+    hWndPrevFocus = hwndFocus;
 
-    hWndPrevFocus = hWndFocus;
-    hWndFocus = hwnd;    
-    if (hWndPrevFocus) SendMessage( hWndPrevFocus, WM_KILLFOCUS, 
-				    (WPARAM)hwnd, 0 );
-    if (hwnd == hWndFocus)  /* Maybe already changed during WM_KILLFOCUS */
-    {
-	if (hwnd) SendMessage( hWndFocus, WM_SETFOCUS, 
-			       (WPARAM)hWndPrevFocus, 0 );
-	FOCUS_SetXFocus( hwnd );
-    }
+    FOCUS_SwitchFocus( hwndFocus , hwnd );
+
     return hWndPrevFocus;
 }
 
@@ -98,10 +114,9 @@
 /*****************************************************************
  *               GetFocus            (USER.23)
  */
-
 HWND GetFocus(void)
 {
-    return hWndFocus;
+    return hwndFocus;
 }
 
 
diff --git a/windows/graphics.c b/windows/graphics.c
index d4475ba..517d74b 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -23,15 +23,6 @@
 #include "debug.h"
 #include "xmalloc.h"
 
-static __inline__ void swap_int(int *a, int *b)
-{
-	int c;
-	
-	c = *a;
-	*a = *b;
-	*b = c;
-}
-
 /***********************************************************************
  *           LineTo    (GDI.19)
  */
@@ -108,7 +99,7 @@
 static BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom,
 		    int xstart, int ystart, int xend, int yend, int lines )
 {
-    int xcenter, ycenter, istart_angle, idiff_angle;
+    int xcenter, ycenter, istart_angle, idiff_angle, tmp;
     double start_angle, end_angle;
     XPoint points[3];
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -155,8 +146,8 @@
     istart_angle = (int)(start_angle * 180 * 64 / PI);
     idiff_angle  = (int)((end_angle - start_angle) * 180 * 64 / PI );
     if (idiff_angle <= 0) idiff_angle += 360 * 64;
-    if (left > right) swap_int( &left, &right );
-    if (top > bottom) swap_int( &top, &bottom );
+    if (left > right) { tmp=left; left=right; right=tmp; }
+    if (top > bottom) { tmp=top; top=bottom; bottom=tmp; }
 
       /* Fill arc with brush if Chord() or Pie() */
 
@@ -195,8 +186,8 @@
 /***********************************************************************
  *           Arc    (GDI.23)
  */
-BOOL Arc( HDC hdc, int left, int top, int right, int bottom,
-	  int xstart, int ystart, int xend, int yend )
+BOOL Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
+	  INT xstart, INT ystart, INT xend, INT yend )
 {
     return GRAPH_DrawArc( hdc, left, top, right, bottom,
 			  xstart, ystart, xend, yend, 0 );
@@ -206,8 +197,8 @@
 /***********************************************************************
  *           Pie    (GDI.26)
  */
-BOOL Pie( HDC hdc, int left, int top, int right, int bottom,
-	  int xstart, int ystart, int xend, int yend )
+BOOL Pie( HDC hdc, INT left, INT top, INT right, INT bottom,
+	  INT xstart, INT ystart, INT xend, INT yend )
 {
     return GRAPH_DrawArc( hdc, left, top, right, bottom,
 			  xstart, ystart, xend, yend, 2 );
@@ -217,8 +208,8 @@
 /***********************************************************************
  *           Chord    (GDI.348)
  */
-BOOL Chord( HDC hdc, int left, int top, int right, int bottom,
-	    int xstart, int ystart, int xend, int yend )
+BOOL Chord( HDC hdc, INT left, INT top, INT right, INT bottom,
+	    INT xstart, INT ystart, INT xend, INT yend )
 {
     return GRAPH_DrawArc( hdc, left, top, right, bottom,
 			  xstart, ystart, xend, yend, 1 );
@@ -228,7 +219,7 @@
 /***********************************************************************
  *           Ellipse    (GDI.24)
  */
-BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom )
+BOOL Ellipse( HDC hdc, INT left, INT top, INT right, INT bottom )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) 
@@ -245,11 +236,8 @@
     bottom = YLPTODP( dc, bottom );
     if ((left == right) || (top == bottom)) return FALSE;
 
-    if (right < left)
-    	swap_int(&right, &left);
-
-    if (bottom < top)
-    	swap_int(&bottom, &top);
+    if (right < left) { INT tmp = right; right = left; left = tmp; }
+    if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
     
     if ((dc->u.x.pen.style == PS_INSIDEFRAME) &&
         (dc->u.x.pen.width < right-left-1) &&
@@ -276,7 +264,7 @@
 /***********************************************************************
  *           Rectangle    (GDI.27)
  */
-BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom )
+BOOL Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) 
@@ -291,11 +279,8 @@
     right  = XLPTODP( dc, right );
     bottom = YLPTODP( dc, bottom );
 
-    if (right < left)
-    	swap_int(&right, &left);
-
-    if (bottom < top)
-    	swap_int(&bottom, &top);
+    if (right < left) { INT tmp = right; right = left; left = tmp; }
+    if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
 
     if ((left == right) || (top == bottom))
     {
@@ -333,8 +318,8 @@
 /***********************************************************************
  *           RoundRect    (GDI.28)
  */
-BOOL RoundRect( HDC hDC, short left, short top, short right, short bottom,
-                short ell_width, short ell_height )
+BOOL RoundRect( HDC hDC, INT left, INT top, INT right, INT bottom,
+                INT ell_width, INT ell_height )
 {
     DC * dc = (DC *) GDI_GetObjPtr(hDC, DC_MAGIC);
     if (!dc) 
@@ -357,8 +342,8 @@
 
     /* Fix the coordinates */
 
-    if (left > right) { short t = left; left = right; right = t; }
-    if (top > bottom) { short t = top; top = bottom; bottom = t; }
+    if (right < left) { INT tmp = right; right = left; left = tmp; }
+    if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; }
     if (ell_width > right - left) ell_width = right - left;
     if (ell_height > bottom - top) ell_height = bottom - top;
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 7610ae9..c8c0e53 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -17,16 +17,16 @@
  */
 int GetKeyState(int keycode)
 {
-	switch(keycode) {
-		case VK_LBUTTON:
-		    return MouseButtonsStates[0];
-		case VK_MBUTTON:
-		    return MouseButtonsStates[1];
-		case VK_RBUTTON:
-		    return MouseButtonsStates[2];
-		default:
-		    return KeyStateTable[keycode];
-		}
+    switch(keycode) {
+     case VK_LBUTTON:
+	return MouseButtonsStates[0];
+     case VK_MBUTTON:
+	return MouseButtonsStates[1];
+     case VK_RBUTTON:
+	return MouseButtonsStates[2];
+     default:
+	return KeyStateTable[keycode];
+    }
 }
 
 /**********************************************************************
@@ -47,13 +47,14 @@
  */
 void SetKeyboardState(BYTE FAR *lpKeyState)
 {
-	if (lpKeyState != NULL) {
+    if (lpKeyState != NULL) {
 	memcpy(KeyStateTable, lpKeyState, 256);
 	MouseButtonsStates[0] = KeyStateTable[VK_LBUTTON];
 	MouseButtonsStates[1] = KeyStateTable[VK_MBUTTON];
 	MouseButtonsStates[2] = KeyStateTable[VK_RBUTTON];
-	}
+    }
 }
+
 /**********************************************************************
  *            GetAsyncKeyState        (USER.249)
  *
@@ -69,31 +70,30 @@
  */
 int GetAsyncKeyState(int nKey)
 {
-	short 	retval;	
+    short retval;	
 
-	switch (nKey) {
+    switch (nKey) {
+     case VK_LBUTTON:
+	retval = AsyncMouseButtonsStates[0] | 
+	(MouseButtonsStates[0] << 8);
+	break;
+     case VK_MBUTTON:
+	retval = AsyncMouseButtonsStates[1] |
+	(MouseButtonsStates[1] << 8);
+	break;
+     case VK_RBUTTON:
+	retval = AsyncMouseButtonsStates[2] |
+	(MouseButtonsStates[2] << 8);
+	break;
+     default:
+	retval = AsyncKeyStateTable[nKey] | 
+	(KeyStateTable[nKey] << 8);
+	break;
+    }
 
-           case VK_LBUTTON:
-		retval = AsyncMouseButtonsStates[0] | 
-                              (MouseButtonsStates[0] << 8);
-		break;
-           case VK_MBUTTON:
-                retval = AsyncMouseButtonsStates[1] |
-                              (MouseButtonsStates[1] << 8);
-		break;
-           case VK_RBUTTON:
-                retval = AsyncMouseButtonsStates[2] |
-                              (MouseButtonsStates[2] << 8);
-		break;
-           default:
-                retval = AsyncKeyStateTable[nKey] | 
-		              (KeyStateTable[nKey] << 8);
-		break;
-        }
+    bzero(AsyncMouseButtonsStates, 3);	/* all states to false */
+    bzero(AsyncKeyStateTable, 256);
 
-	bzero(AsyncMouseButtonsStates, 3);	/* all states to false */
-	bzero(AsyncKeyStateTable, 256);
-
-	return retval;
+    return retval;
 }
 
diff --git a/windows/mdi.c b/windows/mdi.c
index e1a3ddf..0fe19aa 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -1,10 +1,20 @@
 /* MDI.C
  *
  * Copyright 1994, Bob Amstadt
+ *           1995, Alex Korobka
  *
  * This file contains routines to support MDI features.
+ *
+ * Notes: Windows keeps ID of MDI menu item in the wIDenu field
+ *        of corresponding MDI child.
+ *
+ *	  Basic child activation routine is MDI_ChildActivate and 
+ *        SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE i
+ *        is not used.
  */
+
 #include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
 #include <math.h>
 #include "windows.h"
@@ -17,50 +27,168 @@
 #include "stddebug.h"
 #include "debug.h"
 
-/**********************************************************************
- *					MDIRecreateMenuList
+void ScrollChildren(HWND , UINT , WPARAM , LPARAM );
+void CalcChildScroll(HWND, WORD);
+
+/* ----------------- declarations ----------------- */
+
+static LONG MDI_ChildActivate(WND* ,HWND );
+
+/* -------- Miscellaneous service functions ----------
+ *
+ *			MDI_GetChildByID
  */
-void MDIRecreateMenuList(MDICLIENTINFO *ci)
+
+static HWND MDI_GetChildByID(WND* mdiClient,int id)
 {
-    HLOCAL hinfo;
+ HWND	hWnd   = mdiClient->hwndChild;
+ WND* 	wndPtr = WIN_FindWndPtr( hWnd );
     
-    char buffer[128];
-    int id, n, index;
+ if( !wndPtr ) return 0;
 
-    dprintf_mdi(stddeb, "MDIRecreateMenuList: hWindowMenu "NPFMT"\n", 
-	    ci->hWindowMenu);
-    
-    id = ci->idFirstChild; 
-    while (DeleteMenu(ci->hWindowMenu, id, MF_BYCOMMAND))
-	id++;
+ while( wndPtr )
+  {
+	if( wndPtr->wIDmenu == id ) return hWnd;
+ 	wndPtr = WIN_FindWndPtr(hWnd = wndPtr->hwndNext);
+  }
 
-    dprintf_mdi(stddeb, "MDIRecreateMenuList: id %04x, idFirstChild %04x\n", 
-	    id, ci->idFirstChild);
-
-    if (!ci->flagMenuAltered)
-    {
-	ci->flagMenuAltered = TRUE;
-	AppendMenu(ci->hWindowMenu, MF_SEPARATOR, 0, NULL);
-    }
-    
-    id = ci->idFirstChild;
-    index = 1;
-    for (hinfo = ci->infoActiveChildren; hinfo != 0;)
-    {
-	MDICHILDINFO *chi = USER_HEAP_LIN_ADDR(hinfo);
-	
-	n = sprintf(buffer, "%d ", index++);
-	GetWindowText(chi->hwnd, buffer + n, sizeof(buffer) - n - 1);
-
-	dprintf_mdi(stddeb, "MDIRecreateMenuList: id %04x, '%s'\n",
-		id, buffer);
-
-	AppendMenu(ci->hWindowMenu, MF_STRING, id++, buffer);
-	hinfo = chi->next;
-    }
+ return 0;
 }
 
 /**********************************************************************
+ *			MDI_MenuAppendItem
+ */
+static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND hWndChild)
+{
+    char buffer[128];
+ MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
+ WND		*wndPtr     = WIN_FindWndPtr(hWndChild);
+ LPSTR		 lpWndText  = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText);
+ int 		 n          = sprintf(buffer, "%d ", 
+				      clientInfo->nActiveChildren);
+
+ if( !clientInfo->hWindowMenu ) return 0; 
+    
+ if( lpWndText )
+     strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1);
+ return AppendMenu(clientInfo->hWindowMenu,MF_STRING,
+                       wndPtr->wIDmenu,(LPSTR)buffer);
+}
+
+/**********************************************************************
+ *			MDI_MenuModifyItem
+ */
+static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild )
+{
+ char            buffer[128];
+ MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
+ WND            *wndPtr     = WIN_FindWndPtr(hWndChild);
+ LPSTR           lpWndText  = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText);
+ UINT		 n          = sprintf(buffer, "%d ",
+                              wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
+ BOOL		 bRet	    = 0;
+
+ if( !clientInfo->hWindowMenu ) return 0;
+
+ if( lpWndText )
+     strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1);
+
+ n    = GetMenuState(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); 
+ bRet = ModifyMenu(clientInfo->hWindowMenu , wndPtr->wIDmenu , 
+                   MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu ,(LPSTR)buffer );
+        CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
+ return bRet;
+}
+
+/**********************************************************************
+ *			MDI_MenuDeleteItem
+ */
+static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
+{
+ char    	 buffer[128];
+ MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
+ WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
+ LPSTR		 lpWndText;
+ INT		 index      = 0,id,n;
+
+ if( !clientInfo->nActiveChildren ||
+     !clientInfo->hWindowMenu ) return 0;
+
+ id = wndPtr->wIDmenu;
+ DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
+
+ /* walk the rest of MDI children to prevent gaps in the id 
+  * sequence and in the menu child list 
+  */
+
+ for( index = id+1; index <= clientInfo->nActiveChildren + 
+                             clientInfo->idFirstChild; index++ )
+    {
+	wndPtr = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index));
+	if( !wndPtr )
+	     {
+	      dprintf_mdi(stddeb,"MDIMenuDeleteItem: no window for id=%i\n",index);
+	      continue;
+    }
+    
+	/* set correct id */
+	wndPtr->wIDmenu--;
+
+	n          = sprintf(buffer, "%d ",index - clientInfo->idFirstChild);
+	lpWndText  = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText);
+
+	if( lpWndText )
+	    strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1);	
+
+	/* change menu */
+	ModifyMenu(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
+		   index - 1 ,(LPSTR)buffer ); 
+    }
+ return 1;
+}
+
+/**********************************************************************
+ * 			MDI_GetWindow
+ *
+ * returns "activateable" child  or zero
+ */
+HWND MDI_GetWindow(WND  *clientWnd, HWND hWnd, WORD wTo )
+{
+ HWND            hWndNext;
+ MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
+ WND            *wndPtr;
+
+ if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
+
+ if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0;
+
+ hWndNext = hWnd;
+ wTo      = wTo ? GW_HWNDPREV : GW_HWNDNEXT;
+
+ while( hWndNext )
+    {
+        if( clientWnd->hwndChild == hWndNext && wTo == GW_HWNDPREV )
+             hWndNext = GetWindow( hWndNext, GW_HWNDLAST);
+        else if( wndPtr->hwndNext == 0 && wTo == GW_HWNDNEXT )
+                 hWndNext = clientWnd->hwndChild;
+             else
+                 hWndNext = GetWindow( hWndNext, wTo );
+	
+        wndPtr = WIN_FindWndPtr( hWndNext );
+
+        if( (wndPtr->dwStyle & WS_VISIBLE) &&
+           !(wndPtr->dwStyle & WS_DISABLED) )
+             break;
+
+        /* check if all windows were iterated through */
+        if( hWndNext == hWnd ) break;
+    }
+
+ return ( hWnd == hWndNext )? 0 : hWndNext;
+}
+
+
+/**********************************************************************
  *					MDISetMenu
  * FIXME: This is not complete.
  */
@@ -94,7 +222,9 @@
 {
     MDICREATESTRUCT *cs = (MDICREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
     HWND hwnd;
+    WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
     int spacing;
+    char	     chDef = '\0';
 
     /*
      * Create child window
@@ -107,133 +237,68 @@
     cs->x = ci->nActiveChildren * spacing;  
     cs->y = ci->nActiveChildren * spacing;
 
+    /* this menu is needed to set a check mark in MDI_ChildActivate */
+    AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, (LPSTR)&chDef);
+
     hwnd = CreateWindow( cs->szClass, cs->szTitle,
 			  WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
 			  WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
 			  WS_THICKFRAME | WS_VISIBLE | cs->style,
-			  cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0,
-			  w->hInstance, (SEGPTR)lParam);
+			  cs->x, cs->y, cs->cx, cs->cy, parent, 
+                         (HMENU) wIDmenu, w->hInstance, (SEGPTR)lParam);
 
     if (hwnd)
     {
-	HANDLE h = USER_HEAP_ALLOC( sizeof(MDICHILDINFO) );
-	MDICHILDINFO *child_info = USER_HEAP_LIN_ADDR(h);
-	
-	if (!h)
-	{
-	    DestroyWindow(hwnd);
-	    return 0;
-	}
-
 	ci->nActiveChildren++;
+	MDI_MenuModifyItem(w ,hwnd); 
 
-	child_info->next = ci->infoActiveChildren;
-	child_info->prev = 0;
-	child_info->hwnd = hwnd;
-
-	if (ci->infoActiveChildren) {
-	    MDICHILDINFO *nextinfo = USER_HEAP_LIN_ADDR(ci->infoActiveChildren);
-	    nextinfo->prev = h;
-	}
-
-	ci->infoActiveChildren = h;
-
-	SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
+	/* FIXME: at this point NC area of hwnd stays inactive */
     }
+    else
+	DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND);
 	
     return hwnd;
 }
 
 /**********************************************************************
- *					MDIDestroyChild
+ *			MDI_SwitchActiveChild
+ * 
+ * Notes: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
+ *        being activated 
+ *
+ *        Ideally consecutive SetWindowPos should be replaced by 
+ *        BeginDeferWindowPos/EndDeferWindowPos but currently it doesn't
+ *        matter.
+ *
+ *	  wTo is basically lParam of WM_MDINEXT message
  */
-HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent,
-		     HWND child, BOOL flagDestroy)
+void MDI_SwitchActiveChild(HWND clientHwnd, HWND childHwnd, WORD wTo )
 {
-    MDICHILDINFO  *chi;
-    HLOCAL hinfo;
-    
-    hinfo = ci->infoActiveChildren;
-    while (hinfo != 0) {
-	chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
-	if (chi->hwnd == child) break;
-	hinfo = chi->next;
-    }
-    
-    if (hinfo != 0)
-    {
-	if (chi->prev)
-	    ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->prev))->next = chi->next;
-	if (chi->next)
-	    ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = chi->prev;
-	if (ci->infoActiveChildren == hinfo)
-	    ci->infoActiveChildren = chi->next;
-
-	ci->nActiveChildren--;
-	
-	if (chi->hwnd == ci->hwndActiveChild)
-	    SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
-
-	USER_HEAP_FREE(hinfo);
-	
-	if (flagDestroy)
-	    DestroyWindow(child);
-    }
-    
-    return 0;
-}
-
-/**********************************************************************
- *					MDIBringChildToTop
- */
-void MDIBringChildToTop(HWND parent, WORD id, WORD by_id, BOOL send_to_bottom)
-{
-    HLOCAL hinfo;
-    MDICHILDINFO  *chi;
+    WND		  *w	     = WIN_FindWndPtr(clientHwnd);
+    HWND	   hwndTo    = MDI_GetWindow(w,childHwnd,wTo);
+    HWND	   hwndPrev;
     MDICLIENTINFO *ci;
-    WND           *w;
-    int            i;
 
-    w  = WIN_FindWndPtr(parent);
-    ci = (MDICLIENTINFO *) w->wExtra;
     
-    dprintf_mdi(stddeb, "MDIBringToTop: id %04x, by_id %d\n", id, by_id);
+    ci = (MDICLIENTINFO *) w->wExtra;
 
-    if (by_id)
-	id -= ci->idFirstChild;
-    if (!by_id || id < ci->nActiveChildren)
-    {
-	hinfo = ci->infoActiveChildren;
+    dprintf_mdi(stddeb, "MDI_SwitchActiveChild: "NPFMT", %i\n",childHwnd,wTo);
 
-	if (by_id)
-	{
-	    for (i = 0; i < id; i++)
-		hinfo = ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo))->next;
-	    chi = USER_HEAP_LIN_ADDR(hinfo);
-	}
-	else
-	{
-	    while (hinfo != 0) {
-		chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
-		if (chi->hwnd == (HWND)id) break;
-	        hinfo = chi->next;
-	    }
-	}
+    if ( !childHwnd || !hwndTo ) return; 
 
-	if (hinfo == 0)
-	    return;
+    hwndPrev = ci->hwndActiveChild;
 
-	dprintf_mdi(stddeb, "MDIBringToTop: child "NPFMT"\n", chi->hwnd);
-	if (hinfo != ci->infoActiveChildren)
+    if ( hwndTo != hwndPrev )
 	{
 	    if (ci->flagChildMaximized)
 	    {
 		RECT rectOldRestore, rect;
 
-		w = WIN_FindWndPtr(chi->hwnd);
+		w = WIN_FindWndPtr(hwndTo);
 		
+		/* save old window dimensions */
 		rectOldRestore = ci->rectRestore;
-		GetWindowRect(chi->hwnd, &ci->rectRestore);
+		GetWindowRect(hwndTo, &ci->rectRestore);
 
 		rect.top    = (ci->rectMaximize.top -
 			       (w->rectClient.top - w->rectWindow.top));
@@ -244,61 +309,99 @@
 		rect.right  = (ci->rectMaximize.right +
 			       (w->rectWindow.right - w->rectClient.right));
 		w->dwStyle |= WS_MAXIMIZE;
-		SetWindowPos(chi->hwnd, HWND_TOP, rect.left, rect.top, 
+
+		/* maximize it */
+		ci->flagChildMaximized = childHwnd; /* prevent maximization
+						     * in MDI_ChildActivate
+						     */
+
+		SetWindowPos( hwndTo, HWND_TOP, rect.left, rect.top, 
 			     rect.right - rect.left + 1,
 			     rect.bottom - rect.top + 1, 0);
-		SendMessage(chi->hwnd, WM_SIZE, SIZE_MAXIMIZED,
+
+		SendMessage( hwndTo, WM_SIZE, SIZE_MAXIMIZED,
 			    MAKELONG(w->rectClient.right-w->rectClient.left,
 				     w->rectClient.bottom-w->rectClient.top));
 
-		w = WIN_FindWndPtr(ci->hwndActiveChild);
+		w = WIN_FindWndPtr(hwndPrev);
+
+	        if( w )
+		  {
 		w->dwStyle &= ~WS_MAXIMIZE;
-		SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 
+
+		     /* push hwndPrev to the bottom if needed */
+		     if( !wTo )
+		         SetWindowPos(hwndPrev, HWND_BOTTOM, 
 			     rectOldRestore.left, rectOldRestore.top, 
 			     rectOldRestore.right - rectOldRestore.left + 1, 
 			     rectOldRestore.bottom - rectOldRestore.top + 1,
-			     SWP_NOACTIVATE | 
-			     (send_to_bottom ? 0 : SWP_NOZORDER));
+			          SWP_NOACTIVATE );
+	          }
 	    }
 	    else
 	    {
-		SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0, 
+		SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, 
 			     SWP_NOMOVE | SWP_NOSIZE );
-		if (send_to_bottom)
+		if( !wTo && hwndPrev )
 		{
-		    SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 0, 0, 0, 0, 
+		    SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, 
 				 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 		}
 	    }
+    }
 		
-	    if (chi->next)
-		((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = chi->prev;
+}
 
-	    if (chi->prev)
-		((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->prev))->next = chi->next;
 	    
-	    chi->prev              = 0;
-	    chi->next              = ci->infoActiveChildren;
-	    ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = hinfo;
-	    ci->infoActiveChildren = hinfo;
+/**********************************************************************
+ *                                      MDIDestroyChild
+ */
+HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent,
+                     HWND child, BOOL flagDestroy)
+{
+    WND         *childPtr = WIN_FindWndPtr(child);
 
-	    SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
+    if( childPtr )
+    {
+        if( child == ci->hwndActiveChild )
+          {
+	    MDI_SwitchActiveChild(parent,child,0);
+
+	    if( child == ci->hwndActiveChild )
+                MDI_ChildActivate(w_parent,0);
+
+	    MDI_MenuDeleteItem(w_parent, child);
 	}
 	
-	dprintf_mdi(stddeb, "MDIBringToTop: pos %04x, hwnd "NPFMT"\n", 
-		id, chi->hwnd);
+        ci->nActiveChildren--;
+
+        if( ci->flagChildMaximized == child )
+            ci->flagChildMaximized = 1;
+
+        if (flagDestroy)
+	   {
+            DestroyWindow(child);
+	    PostMessage(parent,WM_MDICALCCHILDSCROLL,0,0L);
+	    ci->sbRecalc |= (SB_BOTH+1);
+	   }
     }
+
+    return 0;
 }
 
+
 /**********************************************************************
  *					MDIMaximizeChild
  */
 LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci)
 {
+
     WND *w = WIN_FindWndPtr(child);
     RECT rect;
     
-    MDIBringChildToTop(parent, child, FALSE, FALSE);
+    if( !SendMessage( child, WM_QUERYOPEN, 0, 0L) )
+	 return 0;
+    
     ci->rectRestore = w->rectWindow;
 
     rect.top    = (ci->rectMaximize.top -
@@ -310,15 +413,16 @@
     rect.right  = (ci->rectMaximize.right +
 		   (w->rectWindow.right - w->rectClient.right));
     w->dwStyle |= WS_MAXIMIZE;
+
     SetWindowPos(child, 0, rect.left, rect.top, 
-		 rect.right - rect.left + 1, rect.bottom - rect.top + 1,
-		 SWP_NOACTIVATE | SWP_NOZORDER);
+		 rect.right - rect.left + 1, rect.bottom - rect.top + 1, 0);
     
-    ci->flagChildMaximized = TRUE;
+    ci->flagChildMaximized = child;
     
     SendMessage(child, WM_SIZE, SIZE_MAXIMIZED,
 		MAKELONG(w->rectClient.right-w->rectClient.left,
 			 w->rectClient.bottom-w->rectClient.top));
+
     SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
 
     return 0;
@@ -329,64 +433,163 @@
  */
 LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
 {
-    HWND    child;
+    HWND    hWnd;
 
-    dprintf_mdi(stddeb,"restoring mdi child\n");
+    hWnd = ci->hwndActiveChild;
 
-    child = ci->hwndActiveChild;
+    dprintf_mdi(stddeb,"MDIRestoreChild: restore "NPFMT"\n", hWnd);
+
     ci->flagChildMaximized = FALSE;
 
-    ShowWindow(child, SW_RESTORE);		/* display the window */
-    MDIBringChildToTop(parent, child, FALSE, FALSE);
-    SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
+    ShowWindow(hWnd, SW_RESTORE);		/* display the window */
+
+    hWnd = GetParent(parent);
+
+    SendMessage(hWnd,WM_NCPAINT , 0, 0);
 
     return 0;
 }
 
 /**********************************************************************
- *					MDIChildActivated
+ *					MDI_ChildActivate
+ *
+ * Note: hWndChild is NULL when last child is being destroyed
  */
-LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent)
+LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild)
 {
-    HLOCAL hinfo;
-    MDICHILDINFO *chi;
-    HWND          deact_hwnd;
-    HWND          act_hwnd;
-    LONG          lParam;
+    MDICLIENTINFO       *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; 
+    HWND                 prevActiveWnd = clientInfo->hwndActiveChild;
+    WND                 *wndPtr = WIN_FindWndPtr( hWndChild );
+    WND			*wndPrev = WIN_FindWndPtr( prevActiveWnd );
+    BOOL		 isActiveFrameWnd = 0;	 
 
-    dprintf_mdi(stddeb, "MDIChildActivate: top "NPFMT"\n", w->hwndChild);
+    if( hWndChild == prevActiveWnd ) return 0L;
 
-    hinfo = ci->infoActiveChildren;
-    if (hinfo)
+    if( wndPtr )
+        if( wndPtr->dwStyle & WS_DISABLED ) return 0L;
+
+    dprintf_mdi(stddeb,"MDI_ChildActivate: "NPFMT"\n", hWndChild);
+
+    if( GetActiveWindow() == clientPtr->hwndParent )
+        isActiveFrameWnd = TRUE;
+	
+    /* deactivate prev. active child */
+    if( wndPrev )
     {
-	chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
-	deact_hwnd = ci->hwndActiveChild;
-	act_hwnd   = chi->hwnd;                /* FIX: Hack */
-	lParam     = ((LONG) deact_hwnd << 16) | (LONG)act_hwnd;
+	SendMessage( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
+        SendMessage( prevActiveWnd, WM_MDIACTIVATE, FALSE,
+					    MAKELONG(hWndChild,prevActiveWnd));
+        /* uncheck menu item */
+       	if( clientInfo->hWindowMenu )
+       	        CheckMenuItem( clientInfo->hWindowMenu,
+       	                       wndPrev->wIDmenu, 0);
+      }
 
-	dprintf_mdi(stddeb, "MDIChildActivate: deact "NPFMT", act "NPFMT"\n",
-	       deact_hwnd, act_hwnd);
+    /* set appearance */
+    if( clientInfo->flagChildMaximized )
+      if( clientInfo->flagChildMaximized != hWndChild )
+        if( hWndChild )
+	        {
+		  clientInfo->hwndActiveChild = hWndChild;
+		  MDIMaximizeChild(GetParent(hWndChild),hWndChild,clientInfo);
+	        }
 
-	ci->hwndActiveChild = act_hwnd;
+    clientInfo->hwndActiveChild = hWndChild;
 
-	if (deact_hwnd != act_hwnd)
+    /* check if we have any children left */
+    if( !hWndChild )
 	{
-	    MDIRecreateMenuList(ci);
-	    SendMessage(deact_hwnd,  WM_NCACTIVATE, FALSE, 0);
-	    SendMessage(deact_hwnd, WM_MDIACTIVATE, FALSE, lParam);
+	    if( isActiveFrameWnd )
+		SetFocus( GetParent(hWndChild) );
+	    return 0;
 	}
 	
-	SendMessage(act_hwnd,  WM_NCACTIVATE, TRUE, 0);
-	SendMessage(act_hwnd, WM_MDIACTIVATE, TRUE, lParam);
+    /* check menu item */
+    if( clientInfo->hWindowMenu )
+              CheckMenuItem( clientInfo->hWindowMenu,
+                             wndPtr->wIDmenu, MF_CHECKED);
+
+    /* bring active child to the top */
+    SetWindowPos( hWndChild, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+
+    if( isActiveFrameWnd )
+	  {
+	    SendMessage( hWndChild, WM_NCACTIVATE, TRUE, 0L);
+	    if( GetFocus() == GetParent(hWndChild) )
+		SendMessage( GetParent(hWndChild), WM_SETFOCUS, 
+			     GetParent(hWndChild), 0L );
+	    else
+		SetFocus( GetParent(hWndChild) );
     }
 
-    if (hinfo || ci->nActiveChildren == 0)
+    SendMessage( hWndChild, WM_MDIACTIVATE, TRUE,
+				       MAKELONG(prevActiveWnd,hWndChild) );
+
+    return 1;
+}
+
+/**********************************************************************
+ *			MDI_BuildWCL
+ *
+ *  iTotal returns number of children available for tiling or cascading
+ */
+MDIWCL* MDI_BuildWCL(WND* clientWnd, int* iTotal)
+{
+    MDIWCL *listTop,*listNext;
+    WND    *childWnd;
+
+    if (!(listTop = (MDIWCL*)malloc( sizeof(MDIWCL) ))) return NULL;
+
+    listTop->hChild = clientWnd->hwndChild;
+    listTop->prev   = NULL;
+    *iTotal 	    = 1;
+
+    /* build linked list from top child to bottom */
+
+    childWnd  =  WIN_FindWndPtr( listTop->hChild );
+    while( childWnd && childWnd->hwndNext )
     {
-	MDIRecreateMenuList(ci);
-	SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
-    }
+	listNext = (MDIWCL*)malloc(sizeof(MDIWCL));
+	
+	if( !listNext )
+	{
+	    /* quit gracefully */
+	    listNext = listTop->prev;
+	    while( listTop )
+	    {
+                listNext = listTop->prev;
+                free(listTop);
+                listTop  = listNext;
+	    }
+	    fprintf(stdnimp,"MDICascade: allocation failed\n");
+	    return NULL;
+	}
     
-    return 0;
+	if( (childWnd->dwStyle & WS_DISABLED) ||
+	    (childWnd->dwStyle & WS_MINIMIZE) ||
+	    !(childWnd->dwStyle & WS_VISIBLE)   )
+	{
+	    listTop->hChild = 0;
+	    (*iTotal)--;
+	}
+
+	listNext->hChild = childWnd->hwndNext;
+	listNext->prev   = listTop;
+	listTop          = listNext;
+	(*iTotal)++;
+
+	childWnd  =  WIN_FindWndPtr( childWnd->hwndNext );
+    }
+
+    if( (childWnd->dwStyle & WS_DISABLED) ||
+	(childWnd->dwStyle & WS_MINIMIZE) ||
+	!(childWnd->dwStyle & WS_VISIBLE)   )
+    {
+	listTop->hChild = 0;
+	(*iTotal)--;
+    }
+ 
+    return listTop;
 }
 
 /**********************************************************************
@@ -394,19 +597,17 @@
  */
 LONG MDICascade(HWND parent, MDICLIENTINFO *ci)
 {
-    HLOCAL hinfo;
-    MDICHILDINFO *chi;
+    WND		 *clientWnd;
+    MDIWCL	 *listTop,*listPrev;
     RECT          rect;
     int           spacing, xsize, ysize;
     int		  x, y;
+    int		  iToPosition = 0;
 
     if (ci->flagChildMaximized)
 	MDIRestoreChild(parent, ci);
 
-    /* If there aren't any children, don't even bother.
-     */
-    if (ci->nActiveChildren == 0)
-        return 0;
+    if (ci->nActiveChildren == 0) return 0;
 
     GetClientRect(parent, &rect);
     spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
@@ -417,30 +618,34 @@
       "MDICascade: Client wnd at (%ld,%ld) - (%ld,%ld), spacing %d\n", 
       (LONG)rect.left, (LONG)rect.top, (LONG)rect.right, (LONG)rect.bottom,
       spacing);
-    dprintf_mdi(stddeb, "MDICascade: searching for last child\n");
-    hinfo = ci->infoActiveChildren;
-    while(1) {
-	chi = USER_HEAP_LIN_ADDR(hinfo);
-	if (chi->next == 0) break;
-	hinfo = chi->next;
-    }
     
-    dprintf_mdi(stddeb, "MDICascade: last child is "NPFMT"\n", chi->hwnd);
+    clientWnd =  WIN_FindWndPtr( parent );
+
+    listTop   =  MDI_BuildWCL(clientWnd,&iToPosition); 
+
+    if( !listTop ) return 0;
+
     x = 0;
     y = 0;
-    while (hinfo != 0)
+
+    /* walk list and move windows */
+    while ( listTop )
     {
-	chi = USER_HEAP_LIN_ADDR(hinfo);
 	dprintf_mdi(stddeb, "MDICascade: move "NPFMT" to (%d,%d) size [%d,%d]\n", 
-		chi->hwnd, x, y, xsize, ysize);
-        if (IsIconic(chi->hwnd)) continue;
-	SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize, 
+		listTop->hChild, x, y, xsize, ysize);
+
+	if( listTop->hChild )
+          {
+	   SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize, 
 		     SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
 
 	x += spacing;
 	y += spacing;
+	  }
 	
-	hinfo = chi->prev;
+	listPrev = listTop->prev;
+	free(listTop);
+	listTop = listPrev;
     }
 
     return 0;
@@ -448,57 +653,84 @@
 
 /**********************************************************************
  *					MDITile
+ *
  */
 LONG MDITile(HWND parent, MDICLIENTINFO *ci)
 {
-    HLOCAL hinfo;
-    MDICHILDINFO *chi;
+    WND		 *wndClient = WIN_FindWndPtr(parent);
+    MDIWCL       *listTop,*listPrev;
     RECT          rect;
     int           xsize, ysize;
     int		  x, y;
     int		  rows, columns;
     int           r, c;
     int           i;
+    int		  iToPosition = 0;
 
     if (ci->flagChildMaximized)
 	MDIRestoreChild(parent, ci);
 
-    /* If there aren't any children, don't even bother.
-     */
-    if (ci->nActiveChildren == 0)
-        return 0;
+    if (ci->nActiveChildren == 0) return 0;
+
+    listTop = MDI_BuildWCL(wndClient, &iToPosition);
+
+    dprintf_mdi(stddeb,"MDITile: %i windows to tile\n",iToPosition);
+
+    if( !listTop ) return 0;
 
     GetClientRect(parent, &rect);
-    rows    = (int) sqrt((double) ci->nActiveChildren);
-    columns = ci->nActiveChildren / rows;
+
+    rows    = (int) sqrt((double) iToPosition);
+    columns = iToPosition / rows;
+
+    /* hack */
+    if( iToPosition != ci->nActiveChildren)
+        {
+           y = rect.bottom - 2 * SYSMETRICS_CYICONSPACING - SYSMETRICS_CYICON;
+           rect.bottom = ( y - SYSMETRICS_CYICON < rect.top )? rect.bottom: y;
+	}
+
     ysize   = rect.bottom / rows;
     xsize   = rect.right  / columns;
     
-    hinfo   = ci->infoActiveChildren;
     x       = 0;
     i       = 0;
+
     for (c = 1; c <= columns; c++)
     {
 	if (c == columns)
 	{
-	    rows  = ci->nActiveChildren - i;
+	    rows  = iToPosition - i;
 	    ysize = rect.bottom / rows;
 	}
 
 	y = 0;
 	for (r = 1; r <= rows; r++, i++)
 	{
-	    chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
-	    SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize, 
-			 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+	    /* shouldn't happen but... */
+	    if( !listTop )
+		 break;
 
+	    if( listTop->hChild )
+		{
+	            SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize, 
+			 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
 	    y += ysize;
-	    hinfo = chi->next;
+		}
+
+            listPrev = listTop->prev;
+            free(listTop);
+            listTop = listPrev;
 	}
 
 	x += xsize;
     }
     
+    /* free the rest if any */
+    while( listTop ) {
+	 listPrev = listTop->prev;
+	 free(listTop);
+	 listTop = listPrev; }
 
     return 0;
 }
@@ -630,19 +862,18 @@
     
     switch (message)
     {
-      case WM_CHILDACTIVATE:
-	return MDIChildActivated(w, ci, hwnd);
-
       case WM_CREATE:
 	cs                      = (LPCREATESTRUCT) PTR_SEG_TO_LIN(lParam);
 	ccs                     = (LPCLIENTCREATESTRUCT) PTR_SEG_TO_LIN(cs->lpCreateParams);
 	ci->hWindowMenu         = ccs->hWindowMenu;
 	ci->idFirstChild        = ccs->idFirstChild;
-	ci->infoActiveChildren  = 0;
-	ci->flagMenuAltered     = FALSE;
 	ci->flagChildMaximized  = FALSE;
+	ci->sbStop		= 0;
+
 	w->dwStyle             |= WS_CLIPCHILDREN;
 
+	AppendMenu(ccs->hWindowMenu,MF_SEPARATOR,0,NULL);
+
 	GetClientRect(w->hwndParent, &ci->rectMaximize);
 	MoveWindow(hwnd, 0, 0, 
 		   ci->rectMaximize.right, ci->rectMaximize.bottom, 1);
@@ -650,7 +881,7 @@
 	return 0;
 
       case WM_MDIACTIVATE:
-	MDIBringChildToTop(hwnd, wParam, FALSE, FALSE);
+	SetWindowPos(wParam,0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
 	return 0;
 
       case WM_MDICASCADE:
@@ -664,16 +895,20 @@
 
       case WM_MDIGETACTIVE:
 	return ((LONG) ci->hwndActiveChild | 
-		((LONG) ci->flagChildMaximized << 16));
+		((LONG) (ci->flagChildMaximized>0) << 16));
 
       case WM_MDIICONARRANGE:
-	return MDIIconArrange(hwnd);
+	       ci->sbStop = TRUE;
+	       MDIIconArrange(hwnd);
+	       ci->sbStop = FALSE;
+	       SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
+	       return 0;
 	
       case WM_MDIMAXIMIZE:
 	return MDIMaximizeChild(hwnd, wParam, ci);
 
       case WM_MDINEXT:
-	MDIBringChildToTop(hwnd, wParam, FALSE, TRUE);
+	MDI_SwitchActiveChild(hwnd, (HWND)wParam, lParam);
 	break;
 	
       case WM_MDIRESTORE:
@@ -683,27 +918,55 @@
 	return MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
 	
       case WM_MDITILE:
-	return MDITile(hwnd, ci);
+	ci->sbStop = TRUE;
+	ShowScrollBar(hwnd,SB_BOTH,FALSE);
+	MDITile(hwnd, ci);
+        ci->sbStop = FALSE;
+        return 0;
+
+      case WM_VSCROLL:
+      case WM_HSCROLL:
+	ci->sbStop = TRUE;
+        ScrollChildren(hwnd,message,wParam,lParam);
+	ci->sbStop = FALSE;
+        return 0;
+
+      case WM_SETFOCUS:
+	if( ci->hwndActiveChild )
+	  {
+	   w = WIN_FindWndPtr( ci->hwndActiveChild );
+	   if( !(w->dwStyle & WS_MINIMIZE) )
+	       SetFocus( ci->hwndActiveChild );
+	  } 
+	return 0;
 	
       case WM_NCACTIVATE:
+        if( ci->hwndActiveChild )
 	SendMessage(ci->hwndActiveChild, message, wParam, lParam);
 	break;
 	
       case WM_PARENTNOTIFY:
-	if (wParam == WM_DESTROY)
-#ifdef WINELIB32
-	    return MDIDestroyChild(w, ci, hwnd, lParam, FALSE);
-#else
-	    return MDIDestroyChild(w, ci, hwnd, LOWORD(lParam), FALSE);
-#endif
-	else if (wParam == WM_LBUTTONDOWN)
-	    MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE, FALSE);
+	if (wParam == WM_LBUTTONDOWN)
+	     SetWindowPos(ci->hwndHitTest, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
 	break;
 
       case WM_SIZE:
 	GetClientRect(w->hwndParent, &ci->rectMaximize);
+	if( !ci->hwndActiveChild )
+	  {
+	     PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
+	     ci->sbRecalc |= (SB_BOTH+1);
+	  }
 	break;
 
+      case WM_MDICALCCHILDSCROLL:
+	if( !ci->sbStop )
+	  if( ci->sbRecalc )
+	    {
+	      CalcChildScroll(hwnd, ci->sbRecalc-1);
+	      ci->sbRecalc = 0;
+	    }
+	return 0;
     }
     
     return DefWindowProc(hwnd, message, wParam, lParam);
@@ -716,12 +979,17 @@
 LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message, 
 		     WPARAM wParam, LPARAM lParam)
 {
+    HWND	childHwnd;
+
     if (hwndMDIClient)
     {
 	switch (message)
 	{
 	  case WM_COMMAND:
-	    MDIBringChildToTop(hwndMDIClient, wParam, TRUE, FALSE);
+	    childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient),
+                                          wParam );
+ 	    if( childHwnd )
+	        SendMessage(hwndMDIClient, WM_MDIACTIVATE, childHwnd , 0L);
 	    break;
 
 	  case WM_NCLBUTTONDOWN:
@@ -739,7 +1007,7 @@
 				     message, wParam, lParam);
 	
 	  case WM_SETFOCUS:
-	    SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam);
+	    SetFocus(hwndMDIClient);
 	    break;
 
 	  case WM_SIZE:
@@ -763,10 +1031,10 @@
 #endif
 {
     MDICLIENTINFO       *ci;
-    WND                 *w;
+    WND                 *clientWnd;
 
-    w  = WIN_FindWndPtr(GetParent(hwnd));
-    ci = (MDICLIENTINFO *) w->wExtra;
+    clientWnd  = WIN_FindWndPtr(GetParent(hwnd));
+    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
     
     switch (message)
     {
@@ -774,10 +1042,29 @@
 	ci->hwndHitTest = hwnd;
 	break;
 	
-      case WM_NCPAINT:
-	NC_DoNCPaint( hwnd, hwnd == ci->hwndActiveChild, FALSE );
+      case WM_SETTEXT:
+	DefWindowProc(hwnd, message, wParam, lParam);
+	MDI_MenuModifyItem(clientWnd,hwnd);
         return 0;
 
+      case WM_CLOSE:
+	SendMessage(GetParent(hwnd),WM_MDIDESTROY,hwnd,0L);
+	return 0;
+
+      case WM_SIZE:
+	if( ci->hwndActiveChild != hwnd )
+	    MDI_ChildActivate(clientWnd, hwnd);
+	break;
+
+      case WM_CHILDACTIVATE:
+	MDI_ChildActivate(clientWnd, hwnd);
+	return 0;
+
+      case WM_NCPAINT:
+	dprintf_mdi(stddeb,"DefMDIChildProc: WM_NCPAINT for "NPFMT", active "NPFMT"\n",
+					     hwnd, ci->hwndActiveChild );
+	break;
+
       case WM_SYSCOMMAND:
 	switch (wParam)
 	{
@@ -789,6 +1076,34 @@
 	}
 	break;
 	
+      /* should also handle following messages */
+      case WM_GETMINMAXINFO:
+	   /* should return rect of MDI client 
+	    * so that normal ShowWindow will be able to handle
+	    * actions that are handled by MDIMaximize and MDIRestore */
+
+      case WM_SETVISIBLE:
+         if( !ci->sbStop )
+          {
+            PostMessage(GetParent(hwnd),WM_MDICALCCHILDSCROLL,0,0L);
+            ci->sbRecalc |= (SB_BOTH+1);
+          }
+	break;
+      case WM_SETFOCUS:
+	if( IsChild( GetActiveWindow(), GetParent(hwnd)) )
+	    SendMessage(clientWnd->hwndChild,WM_CHILDACTIVATE,0,0L);
+        if( !ci->sbStop )
+          {
+            PostMessage(GetParent(hwnd),WM_MDICALCCHILDSCROLL,0,0L);
+            ci->sbRecalc |= (SB_BOTH+1);
+          }
+	break;
+
+      case WM_MENUCHAR:
+      case WM_NEXTMENU:
+	   /* set current menu to child system menu */
+
+	break;	
     }
 	
     return DefWindowProc(hwnd, message, wParam, lParam);
@@ -836,3 +1151,81 @@
         SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE );
     }
 }
+
+/***********************************************************************
+ *           ScrollChildren   (USER.463)
+ */
+void ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ WND	*wndPtr = WIN_FindWndPtr(hWnd);
+ short 	 newPos;
+ short 	 curPos;
+ short 	 length;
+ short 	 minPos;
+ short 	 maxPos;
+ short   shift;
+
+ if( !wndPtr ) return;
+
+ if( uMsg == WM_HSCROLL )
+   {
+     GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
+     curPos = GetScrollPos(hWnd,SB_HORZ);
+     length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
+     shift = SYSMETRICS_CYHSCROLL;
+   }
+ else if( uMsg == WM_VSCROLL )
+	{
+	  GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
+	  curPos = GetScrollPos(hWnd,SB_VERT);
+	  length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
+	  shift = SYSMETRICS_CXVSCROLL;
+	}
+      else return;
+
+ switch( wParam )
+   {
+	case SB_LINEUP:	
+		        newPos = curPos - shift;
+			break;
+	case SB_LINEDOWN:    
+			newPos = curPos + shift;
+			break;
+	case SB_PAGEUP:	
+			newPos = curPos - length;
+			break;
+	case SB_PAGEDOWN:    
+			newPos = curPos + length;
+			break;
+
+	case SB_THUMBPOSITION: 
+			newPos = LOWORD(lParam);
+			break;
+
+	case SB_THUMBTRACK:  
+			return;
+
+	case SB_TOP:		
+			newPos = minPos;
+			break;
+	case SB_BOTTOM:	
+			newPos = maxPos;
+			break;
+	case SB_ENDSCROLL:
+			CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
+			return;
+   }
+
+ if( newPos > maxPos )
+     newPos = maxPos;
+ else if( newPos < minPos )
+	  newPos = minPos;
+
+ SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
+
+ if( uMsg == WM_VSCROLL )
+     ScrollWindow(hWnd ,0 ,curPos - newPos, NULL, NULL);
+ else
+     ScrollWindow(hWnd ,curPos - newPos, 0, NULL, NULL);
+}
+
diff --git a/windows/message.c b/windows/message.c
index 8360974..23afe53 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -23,20 +23,22 @@
 /* #define DEBUG_MSG */
 #include "debug.h"
 
-
 #define HWND_BROADCAST  ((HWND)0xffff)
-
 #define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
 
 
 extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg,
 			      HWND hwnd, BOOL remove );  /* timer.c */
 
-  /* System message queue (for hardware events) */
-static HANDLE hmemSysMsgQueue = 0;
-static MESSAGEQUEUE * sysMsgQueue = NULL;
+/* ------- Internal Queues ------ */
 
-  /* Double-click time */
+static HANDLE hmemSysMsgQueue = 0;
+static MESSAGEQUEUE *sysMsgQueue = NULL;
+
+HANDLE hActiveQ_G      = 0;
+static HANDLE hFirstQueue = 0;
+
+/* ------- Miscellaneous ------ */
 static int doubleClickSpeed = 452;
 
 
@@ -62,6 +64,43 @@
     return hQueue;
 }
 
+/***********************************************************************
+ *	     MSG_DeleteMsgQueue
+ */
+BOOL MSG_DeleteMsgQueue( HANDLE hQueue )
+{
+ MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue);
+
+ if( !hQueue )
+   {
+	dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n");
+	return 0;
+   }
+
+ if( !msgQueue ) return 0;
+
+ if( hQueue == hFirstQueue )
+	hFirstQueue = msgQueue->next;
+ else if( hFirstQueue )
+	{
+	  MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(hFirstQueue);
+
+	  /* walk up queue list and relink if needed */
+	  while( msgQ->next )
+	    {
+		if( msgQ->next == hQueue )
+		    msgQ->next = msgQueue->next;
+
+		/* should check for intertask sendmessages here */
+
+
+	        msgQ = (MESSAGEQUEUE*)GlobalLock(msgQ->next);
+	    }
+	}
+
+ GlobalFree( hQueue );
+ return 1;
+}
 
 /***********************************************************************
  *           MSG_CreateSysMsgQueue
@@ -169,6 +208,15 @@
     msgQueue->tempStatus = 0;
 }
 
+/***********************************************************************
+ *	     MSG_GetQueueTask
+ */
+HTASK MSG_GetQueueTask( HANDLE hQueue )
+{
+    MESSAGEQUEUE *msgQ = GlobalLock( hQueue );
+
+    return (msgQ) ? msgQ->hTask : 0 ;
+}
 
 /***********************************************************************
  *           MSG_GetWindowForEvent
@@ -624,7 +672,9 @@
  */
 BOOL SetMessageQueue( int size )
 {
-    HGLOBAL hQueue;
+    HGLOBAL  	  hQueue    = 0;
+    HGLOBAL  	  hNextQueue= hFirstQueue;
+    MESSAGEQUEUE *queuePrev = NULL;
     MESSAGEQUEUE *queuePtr;
 
     if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
@@ -632,13 +682,47 @@
       /* Free the old message queue */
     if ((hQueue = GetTaskQueue(0)) != 0)
     {
-	GlobalUnlock( hQueue );
-	GlobalFree( hQueue );
+	MESSAGEQUEUE *queuePtr = (MESSAGEQUEUE *)GlobalLock( hQueue );
+	
+	if( queuePtr )
+	{
+	    MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(hFirstQueue);
+
+	    hNextQueue = queuePtr->next;
+
+            if( msgQ )
+		if( hQueue != hFirstQueue )
+		    while( msgQ->next )
+		    { 
+			if( msgQ->next == hQueue )
+			{ 
+			    queuePrev = msgQ;
+			    break;
+			} 
+			msgQ = (MESSAGEQUEUE*)GlobalLock(msgQ->next);
+		    }
+	    GlobalUnlock( hQueue );
+	    MSG_DeleteMsgQueue( hQueue );
+	}
     }
   
-    if (!(hQueue = MSG_CreateMsgQueue( size ))) return FALSE;
+    if( !(hQueue = MSG_CreateMsgQueue( size ))) 
+    {
+	if(queuePrev) 
+	    /* it did have a queue */
+	    queuePrev->next = hNextQueue;
+	return FALSE;
+    }
+  
     queuePtr = (MESSAGEQUEUE *)GlobalLock( hQueue );
     queuePtr->hTask = GetCurrentTask();
+    queuePtr->next  = hNextQueue;
+
+    if( !queuePrev )  
+         hFirstQueue = hQueue;
+    else
+	 queuePrev->next = hQueue;
+
     SetTaskQueue( 0, hQueue );
     return TRUE;
 }
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 086dc18..9df7ae5 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -19,9 +19,11 @@
 #include "nonclient.h"
 #include "graphics.h"
 #include "selectors.h"
+#include "stackframe.h"
 #include "stddebug.h"
 /* #define DEBUG_NONCLIENT */
 #include "debug.h"
+#include "options.h"
 
 
 static HBITMAP hbitmapClose = 0;
@@ -35,12 +37,17 @@
 #define SC_ABOUTWINE    	(SC_SCREENSAVE+1)
 
   /* Some useful macros */
+#define IS_MANAGED(style) \
+    (Options.managed && !((style) & WS_CHILD))
+
 #define HAS_DLGFRAME(style,exStyle) \
-    (((exStyle) & WS_EX_DLGMODALFRAME) || \
-     (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
+    (!(IS_MANAGED(style)) && \
+     (((exStyle) & WS_EX_DLGMODALFRAME) || \
+      (((style) & WS_DLGFRAME) && !((style) & WS_BORDER))))
 
 #define HAS_THICKFRAME(style) \
-    (((style) & WS_THICKFRAME) && \
+    (!(IS_MANAGED(style)) && \
+     ((style) & WS_THICKFRAME) && \
      !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
 
 #define HAS_MENU(w)  (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
@@ -63,6 +70,7 @@
 static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
 {
     if (style & WS_ICONIC) return;  /* Nothing to change for an icon */
+    if (IS_MANAGED(style)) return;
     if (HAS_DLGFRAME( style, exStyle ))
 	InflateRect( rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
     else
@@ -118,8 +126,7 @@
 void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
                        POINT *minTrack, POINT *maxTrack )
 {
-    HANDLE minmaxHandle;
-    MINMAXINFO MinMax, *pMinMax;
+    MINMAXINFO MinMax;
     short xinc, yinc;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -132,7 +139,9 @@
     MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
     MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
 
-    if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+    if (IS_MANAGED(wndPtr->dwStyle))
+	xinc = yinc = 0;
+    else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
         xinc = SYSMETRICS_CXDLGFRAME;
         yinc = SYSMETRICS_CYDLGFRAME;
@@ -165,28 +174,25 @@
         MinMax.ptMaxPosition.y = -yinc;
     }
 
-    minmaxHandle = USER_HEAP_ALLOC( sizeof(MINMAXINFO) );
-    if (minmaxHandle)
-    {
-	pMinMax = (MINMAXINFO *) USER_HEAP_LIN_ADDR( minmaxHandle );
-	memcpy( pMinMax, &MinMax, sizeof(MinMax) );	
-	SendMessage( hwnd, WM_GETMINMAXINFO, 0,
-                     (LPARAM)USER_HEAP_SEG_ADDR(minmaxHandle) );
-    }
-    else pMinMax = &MinMax;
+    SendMessage( hwnd, WM_GETMINMAXINFO, 0, MAKE_SEGPTR(&MinMax) );
 
       /* Some sanity checks */
 
-    pMinMax->ptMaxTrackSize.x = MAX( pMinMax->ptMaxTrackSize.x,
-				     pMinMax->ptMinTrackSize.x );
-    pMinMax->ptMaxTrackSize.y = MAX( pMinMax->ptMaxTrackSize.y,
-				     pMinMax->ptMinTrackSize.y );
+    dprintf_nonclient(stddeb, 
+		      "NC_GetMinMaxInfo: %d %d / %d %d / %d %d / %d %d\n",
+		      MinMax.ptMaxSize.x,MinMax.ptMaxSize.y,
+		      MinMax.ptMaxPosition.x,MinMax.ptMaxPosition.y,
+		      MinMax.ptMaxTrackSize.x,MinMax.ptMaxTrackSize.y,
+		      MinMax.ptMinTrackSize.x,MinMax.ptMinTrackSize.y);
+    MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
+				   MinMax.ptMinTrackSize.x );
+    MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
+				   MinMax.ptMinTrackSize.y );
     
-    if (maxSize) *maxSize = pMinMax->ptMaxSize;
-    if (maxPos) *maxPos = pMinMax->ptMaxPosition;
-    if (minTrack) *minTrack = pMinMax->ptMinTrackSize;
-    if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize;
-    if (minmaxHandle) USER_HEAP_FREE( minmaxHandle );
+    if (maxSize) *maxSize = MinMax.ptMaxSize;
+    if (maxPos) *maxPos = MinMax.ptMaxPosition;
+    if (minTrack) *minTrack = MinMax.ptMinTrackSize;
+    if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
 }
 
 
@@ -233,6 +239,7 @@
     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
     if (wndPtr->dwStyle & WS_ICONIC) return;  /* No border to remove */
+    if (IS_MANAGED(wndPtr->dwStyle)) return;
 
       /* Remove frame from rectangle */
     if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
@@ -319,14 +326,16 @@
     {
 	if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
 	    InflateRect(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
-	else if (wndPtr->dwStyle & WS_BORDER)
+	else if (!(IS_MANAGED(wndPtr->dwStyle)) &&
+		 (wndPtr->dwStyle & WS_BORDER))
 	    InflateRect(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
 	if (!PtInRect( &rect, pt )) return HTBORDER;
     }
 
       /* Check caption */
 
-    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    if (!(IS_MANAGED(wndPtr->dwStyle)) &&
+	((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION))
     {
 	rect.top += SYSMETRICS_CYCAPTION - 1;
 	if (!PtInRect( &rect, pt ))
@@ -663,8 +672,9 @@
 
     SelectObject( hdc, sysColorObjects.hpenWindowFrame );
 
-    if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
-        (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
+    if (((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
+	 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)) &&
+	!(IS_MANAGED(wndPtr->dwStyle)))
     {
 	MoveTo( hdc, 0, 0 );
 	LineTo( hdc, rect.right-1, 0 );
@@ -676,10 +686,12 @@
 
     if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
 	NC_DrawFrame( hdc, &rect, TRUE, active );
-    else if (wndPtr->dwStyle & WS_THICKFRAME)
+    else if ((wndPtr->dwStyle & WS_THICKFRAME) &&
+	     !(IS_MANAGED(wndPtr->dwStyle)))
 	NC_DrawFrame(hdc, &rect, FALSE, active );
 
-    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    if (((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) &&
+	!(IS_MANAGED(wndPtr->dwStyle)))
     {
 	RECT r = rect;
 	r.bottom = rect.top + SYSMETRICS_CYSIZE;
@@ -721,7 +733,9 @@
  */
 LONG NC_HandleNCPaint( HWND hwnd )
 {
-    NC_DoNCPaint( hwnd, hwnd == GetActiveWindow(), FALSE );
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    NC_DoNCPaint( hwnd, wndPtr->flags & WIN_NCACTIVATED, FALSE );
     return 0;
 }
 
@@ -733,6 +747,11 @@
  */
 LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam )
 {
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    if (wParam != 0) wndPtr->flags |= WIN_NCACTIVATED;
+    else wndPtr->flags &= ~WIN_NCACTIVATED;
+
     NC_DoNCPaint( hwnd, (wParam != 0), FALSE );
     return TRUE;
 }
@@ -1026,6 +1045,7 @@
 	if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display );
     }
     SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 );
+    SendMessage( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
 
       /* If Esc key, don't move the window */
     if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return;
@@ -1090,8 +1110,7 @@
  */
 static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt )
 {
-    MSG *msg;
-    HLOCAL hMsg;
+    MSG msg;
     WORD scrollbar;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -1106,8 +1125,6 @@
 	scrollbar = SB_VERT;
     }
 
-    hMsg = USER_HEAP_ALLOC( sizeof(MSG) );
-    msg  = (MSG *) USER_HEAP_LIN_ADDR( hMsg );
     pt.x -= wndPtr->rectWindow.left;
     pt.y -= wndPtr->rectWindow.top;
     SetCapture( hwnd );
@@ -1115,21 +1132,21 @@
 
     do
     {
-        GetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(hMsg), 0, 0, 0 );
-	switch(msg->message)
+        GetMessage( MAKE_SEGPTR(&msg), 0, 0, 0 );
+	switch(msg.message)
 	{
 	case WM_LBUTTONUP:
 	case WM_MOUSEMOVE:
         case WM_SYSTIMER:
-            pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left - 
+            pt.x = LOWORD(msg.lParam) + wndPtr->rectClient.left - 
 	      wndPtr->rectWindow.left;
-            pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top - 
+            pt.y = HIWORD(msg.lParam) + wndPtr->rectClient.top - 
 	      wndPtr->rectWindow.top;
-            SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
+            SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt );
 	    break;
         default:
-            TranslateMessage( msg );
-            DispatchMessage( msg );
+            TranslateMessage( &msg );
+            DispatchMessage( &msg );
             break;
 	}
         if (!IsWindow( hwnd ))
@@ -1137,8 +1154,7 @@
             ReleaseCapture();
             break;
         }
-    } while (msg->message != WM_LBUTTONUP);
-    USER_HEAP_FREE( hMsg );
+    } while (msg.message != WM_LBUTTONUP);
 }
 
 /***********************************************************************
diff --git a/windows/scroll.c b/windows/scroll.c
index b24fcbf..e8652cf 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -2,40 +2,157 @@
  * Scroll windows and DCs
  *
  * Copyright  David W. Metcalfe, 1993
+ *	      Alex Korobka       1995
+ *
  *
  */
 
 #include <stdlib.h>
-#include "windows.h"
+#include "wintypes.h"
+#include "class.h"
+#include "win.h"
 #include "gdi.h"
-#include "scroll.h"
+#include "sysmetrics.h"
 #include "stddebug.h"
 /* #define DEBUG_SCROLL */
 #include "debug.h"
 
 
+
+extern DCE_GetVisRgn(HWND, WORD);
+
 static int RgnType;
 
 
+/* -----------------------------------------------------------------------
+ *	       SCROLL_TraceChildren
+ * 
+ * Returns a region invalidated by children, siblings, and/or ansectors
+ * in the window rectangle or client rectangle
+ *
+ * dcx can have DCX_WINDOW, DCX_CLIPCHILDREN, DCX_CLIPSIBLINGS set
+ */
+
+HRGN	SCROLL_TraceChildren( HWND hScroll, short dx, short dy, WORD dcx)
+{
+ WND	       *wndScroll = WIN_FindWndPtr( hScroll ); 
+ HRGN		hRgnWnd;
+ HRGN		hUpdateRgn,hCombineRgn;
+
+ if( !wndScroll || ( !dx && !dy) ) return 0;
+
+ if( dcx & DCX_WINDOW )
+	 hRgnWnd   = CreateRectRgnIndirect(&wndScroll->rectWindow);
+ else
+	{
+	 RECT rect;
+
+	 GetClientRect(hScroll,&rect);
+ 	 hRgnWnd   = CreateRectRgnIndirect(&rect);
+	}
+
+ hUpdateRgn  = DCE_GetVisRgn( hScroll, dcx );
+ hCombineRgn = CreateRectRgn(0,0,0,0);
+
+ if( !hUpdateRgn || !hCombineRgn )
+      {
+	DeleteObject( hUpdateRgn? hUpdateRgn : hCombineRgn);
+	DeleteObject(hRgnWnd);
+	return 0;
+      }
+
+ OffsetRgn( hUpdateRgn, dx, dy);
+ CombineRgn(hCombineRgn, hRgnWnd, hUpdateRgn, RGN_DIFF);
+ 
+ DeleteObject(hRgnWnd);
+ DeleteObject(hUpdateRgn);
+
+ return hCombineRgn;
+}
+
+
+/* ----------------------------------------------------------------------
+ *	       SCROLL_ScrollChildren
+ */
+BOOL	SCROLL_ScrollChildren( HWND hScroll, short dx, short dy)
+{
+ WND           *wndPtr = WIN_FindWndPtr(hScroll);
+ HWND		hWnd   = wndPtr->hwndChild;
+ HRGN		hUpdateRgn;
+ BOOL		b = 0;
+
+ if( !wndPtr || ( !dx && !dy )) return 0;
+
+ dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd "NPFMT" dx=%i dy=%i\n",hScroll,dx,dy);
+
+ /* get a region in client rect invalidated by siblings and ansectors */
+ hUpdateRgn = SCROLL_TraceChildren(hScroll, dx , dy, DCX_CLIPSIBLINGS);
+
+ /* update children coordinates */
+ while( hWnd )
+  {
+	wndPtr = WIN_FindWndPtr( hWnd );
+
+	/* we can check if window intersects with clipRect parameter
+	 * and do not move it if not - just a thought.     - AK
+	 */
+
+	SetWindowPos(hWnd,0,wndPtr->rectWindow.left + dx,
+			    wndPtr->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
+			    SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
+			    SWP_DEFERERASE );
+
+	hWnd = wndPtr->hwndNext;
+  } 
+
+ /* invalidate uncovered region and paint frames */
+ b = RedrawWindow( hScroll, NULL, hUpdateRgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
+				              RDW_ERASENOW | RDW_ALLCHILDREN ); 
+
+ DeleteObject( hUpdateRgn);
+ return b;
+}
+
+
 /*************************************************************************
  *             ScrollWindow         (USER.61)
+ *
+ * FIXME: a bit broken
  */
 
 void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect)
 {
     HDC hdc;
-    HRGN hrgnUpdate;
+    HRGN hrgnUpdate,hrgnClip;
     RECT rc, cliprc;
 
-    dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, rect=%ld,%ld,%ld,%ld\n", 
-	   dx, dy, (LONG)rect->left, (LONG)rect->top, (LONG)rect->right, (LONG)rect->bottom);
+    dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n", 
+	    dx, dy, (LONG)rect, (clipRect)?clipRect->left:0,
+                                (clipRect)?clipRect->top:0,
+                                (clipRect)?clipRect->right:0, 
+                                (clipRect)?clipRect->bottom:0);
 
-    hdc = GetDC(hwnd);
-
-    if (rect == NULL)
+    /* if rect is NULL children have to be moved */
+    if ( !rect )
+       {
 	GetClientRect(hwnd, &rc);
+	  hrgnClip = CreateRectRgnIndirect( &rc );
+
+	  /* children will be Blt'ed too */
+	  hdc      = GetDCEx(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
+          DeleteObject(hrgnClip);
+       }
     else
+       {
+	  GetClientRect(hwnd,&rc);
+	  dprintf_scroll(stddeb,"\trect=%i %i %i %i client=%i %i %i %i\n",
+			 rect->left,rect->top,rect->right,rect->bottom,rc.left,rc.top,
+			 rc.right,rc.bottom);
+
 	CopyRect(&rc, rect);
+	  hdc = GetDC(hwnd);
+       }
+
     if (clipRect == NULL)
 	GetClientRect(hwnd, &cliprc);
     else
@@ -43,13 +160,41 @@
 
     hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
     ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
-    InvalidateRgn(hwnd, hrgnUpdate, TRUE);
     ReleaseDC(hwnd, hdc);
+
+    if( !rect )
+      {
+         /* FIXME: this doesn't take into account hrgnUpdate */
+         if( !SCROLL_ScrollChildren(hwnd,dx,dy) )
+	     InvalidateRgn(hwnd, hrgnUpdate, TRUE);
+      }
+    else
+      {
+        HRGN hrgnInv = SCROLL_TraceChildren(hwnd,dx,dy,DCX_CLIPCHILDREN |
+						       DCX_CLIPSIBLINGS );
+        if( hrgnInv )
+ 	  {
+	    HRGN hrgnCombine = CreateRectRgn(0,0,0,0);
+
+	    CombineRgn(hrgnCombine,hrgnInv,hrgnUpdate,RGN_OR);
+	    dprintf_scroll(stddeb,"ScrollWindow: hrgnComb="NPFMT" hrgnInv="NPFMT" hrgnUpd="NPFMT"\n",
+	 					           hrgnCombine,hrgnInv,hrgnUpdate);
+
+	    DeleteObject(hrgnUpdate); DeleteObject(hrgnInv);
+	    hrgnUpdate = hrgnCombine;
+	  }
+
+        RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW);
+      }
+
+    DeleteObject(hrgnUpdate);
 }
 
 
 /*************************************************************************
  *             ScrollDC         (USER.221)
+ *
+ * FIXME: half-broken
  */
 
 BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT rc, LPRECT cliprc,
@@ -60,8 +205,11 @@
     short width, height;
     DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
 
-    dprintf_scroll(stddeb, "ScrollDC: dx=%d, dy=%d, rc=%ld,%ld,%ld,%ld\n", dx, dy,
-	   (LONG)rc->left, (LONG)rc->top, (LONG)rc->right, (LONG)rc->bottom);
+    dprintf_scroll(stddeb,"ScrollDC: dx=%d dy=%d, hrgnUpdate="NPFMT" rc=%i %i %i %i\n",
+                                     dx,dy,hrgnUpdate,(rc)?rc->left:0,
+				                      (rc)?rc->top:0,
+				                      (rc)?rc->right:0,
+				                      (rc)?rc->bottom:0); 
 
     if (rc == NULL)
 	return FALSE;
@@ -128,6 +276,10 @@
 
 /*************************************************************************
  *             ScrollWindowEx       (USER.319)
+ *
+ * FIXME: broken
+ *
+ * SCROLL_TraceChildren can help
  */
 
 int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect,
@@ -136,9 +288,7 @@
     HDC hdc;
     RECT rc, cliprc;
 
-    dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, rect=%ld,%ld,%ld,%ld\n", 
-	   dx, dy, (LONG)rect->left, (LONG)rect->top, (LONG)rect->right,
-           (LONG)rect->bottom);
+    dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, wFlags="NPFMT"\n",dx, dy, flags);
 
     hdc = GetDC(hwnd);
 
diff --git a/windows/win.c b/windows/win.c
index 7153ee6..1848a3b 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -28,11 +28,11 @@
 /* #define DEBUG_MENU */
 #include "debug.h"
 
-static HWND hwndDesktop = 0;
-static HWND hWndSysModal = 0;
+static HWND hwndDesktop  = 0;
+static HWND hwndSysModal = 0;
 
-static WORD wDragWidth = 8;
-static WORD wDragHeight= 6;
+static WORD wDragWidth = 4;
+static WORD wDragHeight= 3;
 
 extern HCURSOR CURSORICON_IconToCursor(HICON);
 
@@ -395,7 +395,6 @@
     wndPtr->ptMaxPos.y     = -1;
     wndPtr->hmemTaskQ      = GetTaskQueue(0);
     wndPtr->hrgnUpdate     = 0;
-    wndPtr->hwndPrevActive = 0;
     wndPtr->hwndLastActive = hwnd;
     wndPtr->lpfnWndProc    = classPtr->wc.lpfnWndProc;
     wndPtr->dwStyle        = style & ~WS_VISIBLE;
@@ -446,10 +445,20 @@
 
     if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
     {
-        win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
-                              PointerMotionMask | ButtonPressMask |
-                              ButtonReleaseMask | FocusChangeMask;
-        win_attr.override_redirect = TRUE;
+	if(Options.managed && className != POPUPMENU_CLASS_ATOM) {
+	    win_attr.event_mask = ExposureMask | KeyPressMask |
+	                          KeyReleaseMask | PointerMotionMask |
+	                          ButtonPressMask | ButtonReleaseMask |
+	                          FocusChangeMask | StructureNotifyMask;
+	    win_attr.override_redirect = FALSE;
+	}
+	else {
+	    win_attr.event_mask = ExposureMask | KeyPressMask |
+	                          KeyReleaseMask | PointerMotionMask |
+	                          ButtonPressMask | ButtonReleaseMask |
+	                          FocusChangeMask;
+            win_attr.override_redirect = TRUE;
+	}
         win_attr.colormap      = COLOR_WinColormap;
         win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
         win_attr.save_under    = ((classPtr->wc.style & CS_SAVEBITS) != 0);
@@ -1238,10 +1247,10 @@
  */
 HWND SetSysModalWindow(HWND hWnd)
 {
-	HWND hWndOldModal = hWndSysModal;
-	hWndSysModal = hWnd;
-	dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow("NPFMT") !\n", hWnd);
-	return hWndOldModal;
+    HWND hWndOldModal = hwndSysModal;
+    hwndSysModal = hWnd;
+    dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow("NPFMT") !\n", hWnd);
+    return hWndOldModal;
 }
 
 
@@ -1250,7 +1259,7 @@
  */
 HWND GetSysModalWindow(void)
 {
-	return hWndSysModal;
+    return hwndSysModal;
 }
 
 /*******************************************************************
diff --git a/windows/winpos.c b/windows/winpos.c
index 08a499c..97109b7 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -2,12 +2,15 @@
  * Window position related functions.
  *
  * Copyright 1993, 1994, 1995 Alexandre Julliard
+ *                       1995 Alex Korobka
  */
 
 #include "sysmetrics.h"
+#include "selectors.h"
 #include "user.h"
 #include "win.h"
 #include "event.h"
+#include "hook.h"
 #include "message.h"
 #include "stackframe.h"
 #include "winpos.h"
@@ -16,7 +19,16 @@
 /* #define DEBUG_WIN */
 #include "debug.h"
 
-static HWND hwndActive = 0;  /* Currently active window */
+/* ----- external functions ----- */
+
+void 	FOCUS_SwitchFocus( HWND , HWND );
+
+/* ----- internal variables ----- */
+
+static HWND hwndActive      = 0;  /* Currently active window */
+static HWND hwndPrevActive  = 0;  /* Previously active window */
+
+extern HANDLE hActiveQ_G;		/* from message.c */
 
 
 /***********************************************************************
@@ -226,7 +238,12 @@
       /* Translate source window origin to screen coords */
     while(hwndFrom)
     {
-	wndPtr = WIN_FindWndPtr( hwndFrom );
+	if (!(wndPtr = WIN_FindWndPtr( hwndFrom )))
+	{
+	    fprintf( stderr, "MapWindowPoints: bad hwndFrom = "NPFMT"\n",
+		     hwndFrom); 
+	    return;
+	}
 	origin.x += wndPtr->rectClient.left;
 	origin.y += wndPtr->rectClient.top;
 	hwndFrom = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0;
@@ -235,7 +252,11 @@
       /* Translate origin to destination window coords */
     while(hwndTo)
     {
-	wndPtr = WIN_FindWndPtr( hwndTo );
+	if (!(wndPtr = WIN_FindWndPtr( hwndTo )))
+	{
+	    fprintf(stderr,"MapWindowPoints: bad hwndTo = "NPFMT"\n", hwndTo );
+	    return;
+	}
 	origin.x -= wndPtr->rectClient.left;
 	origin.y -= wndPtr->rectClient.top;
 	hwndTo = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0;
@@ -288,8 +309,11 @@
 {
     HWND prev = hwndActive;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return 0;
-    SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+
+    if (!wndPtr || (wndPtr->dwStyle & WS_DISABLED) ||
+	!(wndPtr->dwStyle & WS_VISIBLE)) return 0;
+
+    WINPOS_SetActiveWindow( hwnd, 0, 0 );
     return prev;
 }
 
@@ -377,10 +401,19 @@
                   /* Store the current position and find the maximized size */
                 if (!(wndPtr->dwStyle & WS_MINIMIZE))
                     wndPtr->rectNormal = wndPtr->rectWindow; 
+
                 NC_GetMinMaxInfo( hwnd, &maxSize,
                                   &wndPtr->ptMaxPos, NULL, NULL );
                 x  = wndPtr->ptMaxPos.x;
                 y  = wndPtr->ptMaxPos.y;
+
+		if( wndPtr->dwStyle & WS_MINIMIZE )
+		    if( !SendMessage( hwnd, WM_QUERYOPEN, 0, 0L ) )
+			{
+		         swpflags |= SWP_NOSIZE;
+			 break;
+			}
+
                 cx = maxSize.x;
                 cy = maxSize.y;
                 wndPtr->dwStyle &= ~WS_MINIMIZE;
@@ -403,8 +436,14 @@
 	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
 	case SW_RESTORE:
 	    swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+
             if (wndPtr->dwStyle & WS_MINIMIZE)
             {
+                if( !SendMessage( hwnd, WM_QUERYOPEN, 0, 0L) )
+                  {
+                    swpflags |= SWP_NOSIZE;
+                    break;
+                  }
                 wndPtr->ptIconPos.x = wndPtr->rectWindow.left;
                 wndPtr->ptIconPos.y = wndPtr->rectWindow.top;
                 wndPtr->dwStyle &= ~WS_MINIMIZE;
@@ -530,49 +569,210 @@
     return TRUE;
 }
 
+/*******************************************************************
+ *	   ACTIVATEAPP_callback
+ */
+BOOL ACTIVATEAPP_callback(HWND hWnd, LPARAM lParam)
+{
+    ACTIVATESTRUCT  *lpActStruct = (ACTIVATESTRUCT*)lParam;
+    WND             *wndPtr = WIN_FindWndPtr( hWnd );
+
+    if( !wndPtr || hWnd == GetDesktopWindow()) return 1;
+ 
+    if( MSG_GetQueueTask(wndPtr->hmemTaskQ) != lpActStruct->hTaskSendTo ) 
+	return 1;
+
+    SendMessage( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag,
+		(LPARAM)(lpActStruct->hWindowTask)?lpActStruct->hWindowTask:0);
+    return 1;
+}
+
 
 /*******************************************************************
- *         WINPOS_ChangeActiveWindow
+ *	   WINPOS_SetActiveWindow
  *
- * Change the active window and send the corresponding messages.
+ * back-end to SetActiveWindow
  */
-HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg )
+BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus )
 {
-    HWND prevActive = hwndActive;
-    if (hwnd == hwndActive) return 0;
-    if (hwndActive)
+    WND                   *wndPtr          = WIN_FindWndPtr(hWnd);
+    WND                   *wndTemp         = WIN_FindWndPtr(hwndActive);
+    CBTACTIVATESTRUCT      cbtStruct       = { fMouse , hwndActive };
+    FARPROC                enumCallback    = (FARPROC)GetWndProcEntry16("ActivateAppProc");
+    ACTIVATESTRUCT         actStruct;
+    WORD                   wIconized=0,wRet= 0;
+
+    /* paranoid checks */
+    if( !hWnd || hWnd == GetDesktopWindow() || hWnd == hwndActive )
+	return 0;
+
+    if( GetTaskQueue(0) != wndPtr->hmemTaskQ )
+	return 0;
+
+    if( wndTemp )
+	wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
+    else
+	dprintf_win(stddeb,"WINPOS_ActivateWindow: no current active window.\n");
+
+    /* call CBT hook chain */
+    wRet = HOOK_CallHooks(WH_CBT, HCBT_ACTIVATE, hWnd,
+			  (LPARAM)MAKE_SEGPTR(&cbtStruct));
+
+    if( wRet ) return wRet;
+
+    /* set prev active wnd to current active wnd and send notification */
+    if( (hwndPrevActive = hwndActive) )
     {
-	if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0;
+	if( !SendMessage(hwndPrevActive, WM_NCACTIVATE, 0, MAKELONG(hWnd,wIconized)) )
+        {
+	    if (GetSysModalWindow() != hWnd) return 0;
+	    /* disregard refusal if hWnd is sysmodal */
+        }
+
 #ifdef WINELIB32
 	SendMessage( hwndActive, WM_ACTIVATE,
-		     MAKEWPARAM( WA_INACTIVE, IsIconic(hwndActive) ),
-		     (LPARAM)hwnd );
+		     MAKEWPARAM( WA_INACTIVE, wIconized ),
+		     (LPARAM)hWnd );
 #else
-	SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE,
-		     MAKELONG( IsIconic(hwndActive), hwnd ) );
+	SendMessage(hwndPrevActive, WM_ACTIVATE, WA_INACTIVE, 
+		    MAKELONG(hWnd,wIconized));
 #endif
-	/* Send WM_ACTIVATEAPP here */
+
+	/* check if something happened during message processing */
+	if( hwndPrevActive != hwndActive ) return 0;
     }
 
-    hwndActive = hwnd;
-    if (hwndActive)
+    /* set active wnd */
+    hwndActive = hWnd;
+
+    /* send palette messages */
+    if( SendMessage( hWnd, WM_QUERYNEWPALETTE, 0, 0L) )
+	SendMessage((HWND)-1, WM_PALETTEISCHANGING, hWnd, 0L );
+
+    /* if prev wnd is minimized redraw icon title 
+  if( hwndPrevActive )
     {
-	WND *wndPtr = WIN_FindWndPtr( hwndActive );
-	wndPtr->hwndPrevActive = prevActive;
+        wndTemp = WIN_FindWndPtr( WIN_GetTopParent( hwndPrevActive ) );
+        if(wndTemp)
+          if(wndTemp->dwStyle & WS_MINIMIZE)
+            RedrawIconTitle(hwndPrevActive); 
+      } 
+  */
+    if (!(wndPtr->dwStyle & WS_CHILD) )
+    {
+	/* check Z-order and bring hWnd to the top */
+	wndTemp = WIN_FindWndPtr( GetDesktopWindow() );
 
-	/* Send WM_ACTIVATEAPP here */
-	SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 );
-#ifdef WINELIB32
-	SendMessage( hwnd, WM_ACTIVATE,
-		     MAKEWPARAM( mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE, 
-				 IsIconic(hwnd) )
-		     , (LPARAM)prevActive );
-#else
-	SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE,
-		     MAKELONG( IsIconic(hwnd), prevActive ) );
-#endif
+	for( ; wndTemp; wndTemp = WIN_FindWndPtr( wndTemp->hwndNext ))
+	    if( wndTemp->dwStyle & WS_VISIBLE )
+		break;
+
+	if( wndTemp != wndPtr )
+	    SetWindowPos(hWnd, HWND_TOP, 0,0,0,0, 
+			 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
     }
-    return prevActive;
+
+    if( !IsWindow(hWnd) ) return 0;
+
+    /* send WM_ACTIVATEAPP if necessary */
+    if( hActiveQ_G != wndPtr->hmemTaskQ )
+    {
+	HTASK hT = MSG_GetQueueTask( hActiveQ_G );
+
+	actStruct.wFlag = 0;                  /* deactivate */
+	actStruct.hWindowTask = MSG_GetQueueTask(wndPtr->hmemTaskQ);
+	actStruct.hTaskSendTo = hT;
+
+	/* send WM_ACTIVATEAPP to top-level windows
+	 * that belong to the actStruct.hTaskSendTo task
+	 */
+	EnumWindows( enumCallback , (LPARAM)&actStruct );
+
+	/* change active queue */
+	hActiveQ_G = wndPtr->hmemTaskQ;
+
+	actStruct.wFlag = 1;                  /* activate */
+	actStruct.hWindowTask = hT;
+	actStruct.hTaskSendTo = MSG_GetQueueTask( hActiveQ_G );
+
+	EnumWindows( enumCallback , (LPARAM)&actStruct );
+
+	if( !IsWindow(hWnd) ) return 0;
+    }
+
+    /* walk up to the first unowned window */
+    wndTemp = wndPtr;
+
+    while(wndTemp->hwndOwner)
+    {
+	wndTemp = WIN_FindWndPtr(wndTemp->hwndOwner);
+	if( !wndTemp)
+        {
+	    /* there must be an unowned window in hierarchy */
+	    dprintf_win(stddeb,"WINPOS_ActivateWindow: broken owner list\n");
+	    wndTemp = wndPtr;
+	    break;
+        }
+    }
+    /* and set last active owned popup */
+    wndTemp->hwndLastActive = hWnd;
+
+    wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
+    SendMessage( hWnd, WM_NCACTIVATE, 1,
+		 MAKELONG(hwndPrevActive,wIconized));
+#ifdef WINELIB32
+    SendMessage( hWnd, WM_ACTIVATE,
+		 MAKEWPARAM( (fMouse)?WA_CLICKACTIVE:WA_ACTIVE, wIconized),
+		 (LPARAM)hwndPrevActive );
+#else
+    SendMessage( hWnd, WM_ACTIVATE, (fMouse)? WA_CLICKACTIVE : WA_ACTIVE,
+		 MAKELONG(hwndPrevActive,wIconized));
+#endif
+
+    if( !IsWindow(hWnd) ) return 0;
+
+    /* change focus if possible */
+    if( fChangeFocus && GetFocus() )
+	if( WIN_GetTopParent(GetFocus()) != hwndActive )
+	    FOCUS_SwitchFocus( GetFocus(),
+			       (wndPtr->dwStyle & WS_MINIMIZE)? 0: hwndActive);
+
+    /* if active wnd is minimized redraw icon title 
+  if( hwndActive )
+      {
+        wndPtr = WIN_FindWndPtr(hwndActive);
+        if(wndPtr->dwStyle & WS_MINIMIZE)
+           RedrawIconTitle(hwndActive);
+    }
+  */
+    return (hWnd == hwndActive);
+}
+
+
+/*******************************************************************
+ *	   WINPOS_ChangeActiveWindow
+ *
+ */
+HWND WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
+{
+    WND *wndPtr = WIN_FindWndPtr(hWnd);
+
+    if( !wndPtr ) return  0;
+
+    /* minors are not allowed */
+    if( (wndPtr->dwStyle & WS_CHILD) && !( wndPtr->dwStyle & WS_POPUP))
+	return SendMessage(hWnd, WM_CHILDACTIVATE, 0, 0L);
+
+    if( hWnd == hwndActive ) return 0;     
+
+    if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
+	return 0;
+
+    /* switch desktop queue to current active here */
+    if( wndPtr->hwndParent == GetDesktopWindow())
+    { }
+
+    return 1;
 }
 
 
@@ -600,6 +800,9 @@
     }
     result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect,
                           MAKE_SEGPTR( &params ) );
+    dprintf_win(stddeb, "WINPOS_SendNCCalcSize: %d %d %d %d\n",
+		params.rgrc[0].top,    params.rgrc[0].left,
+		params.rgrc[0].bottom, params.rgrc[0].right);
     *newClientRect = params.rgrc[0];
     return result;
 }
@@ -859,7 +1062,7 @@
 
         if (!(flags & SWP_NOREDRAW) &&
             (!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE) ||
-             !(flags & SWP_NOZORDER)))
+	     (!(flags & SWP_NOZORDER) && (hwndInsertAfter != HWND_TOP))))
         {
             HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect );
             HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow );
@@ -867,12 +1070,22 @@
             CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF );
             RedrawWindow( wndPtr->hwndParent, NULL, hrgn3,
                           RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
+
+	    /* DCE_GetVisRgn should be called for old coordinates
+	     * and for new, then OffsetRgn and CombineRgn -
+	     * voila, a nice update region to use here - AK.
+	     */ 
             if ((oldWindowRect.left != wndPtr->rectWindow.left) ||
                 (oldWindowRect.top != wndPtr->rectWindow.top))
             {
                 RedrawWindow( winpos.hwnd, NULL, 0, RDW_INVALIDATE |
                               RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
             }
+ 	    else
+		if( CombineRgn( hrgn3, hrgn2, hrgn1, RGN_DIFF) != NULLREGION )
+		    RedrawWindow( winpos.hwnd, NULL, hrgn3, RDW_INVALIDATE |
+				  RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
+
             DeleteObject( hrgn1 );
             DeleteObject( hrgn2 );
             DeleteObject( hrgn3 );
@@ -890,7 +1103,8 @@
         {
             if (!(flags & SWP_NOREDRAW))
                 RedrawWindow( winpos.hwnd, NULL, 0,
-                              RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
+                              RDW_INVALIDATE | RDW_ALLCHILDREN |
+			      RDW_FRAME | RDW_ERASE );
         }
     }
     else if (flags & SWP_HIDEWINDOW)
@@ -907,15 +1121,17 @@
                               RDW_INVALIDATE | RDW_FRAME |
                               RDW_ALLCHILDREN | RDW_ERASE );
         }
+
         if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus()))
             SetFocus( GetParent(winpos.hwnd) );  /* Revert focus to parent */
+
 	if (winpos.hwnd == hwndActive)
 	{
 	      /* Activate previously active window if possible */
-	    HWND newActive = wndPtr->hwndPrevActive;
+	    HWND newActive = hwndPrevActive;
 	    if (!IsWindow(newActive) || (newActive == winpos.hwnd))
 	    {
-		newActive = GetTopWindow(GetDesktopWindow());
+		newActive = GetTopWindow( GetDesktopWindow() );
 		if (newActive == winpos.hwnd) newActive = wndPtr->hwndNext;
 	    }	    
 	    WINPOS_ChangeActiveWindow( newActive, FALSE );
@@ -925,15 +1141,14 @@
       /* Activate the window */
 
     if (!(flags & SWP_NOACTIVATE))
-    {
-	if (!(wndPtr->dwStyle & WS_CHILD))
 	    WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
-    }
     
       /* Repaint the window */
 
     if (wndPtr->window) MSG_Synchronize();  /* Wait for all expose events */
+
     EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
+
     if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW))
         RedrawWindow( winpos.hwnd, NULL, 0,
                       RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );