Release 940420

Wed Apr 20 14:53:35 1994  Bob Amstadt  (bob@pooh)

	* [tools/build.c] [if1632/call.S] [if1632/Imakefile]
	Fixed bug for non-Linux systems.

Apr 18, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/win.c]
	Bug fixed in CreateWindowEx() : Now use SetMenu() for menubar setup.
	New empty stub for function SetSysModalWindow().

	* [misc/exec.c]
	New empty stub for function ExitWindows().

	* [objects/font.c]
	New empty stub for function EnumFonts().

	* New file [misc/property.c]
	New functions RemoveProp(), GetProp(), SetProp() & EnumProps().

	* New file [misc/shell.c]
	New empty stubs for function RegisterShellProc(), 
			ShellExecute() & ShellProc().

	* New files [loader/task.c] & [include/task.h]
	Move functions GetWindowTask(), GetNumTask(), EnumTaskWindows()
		from 'loader/library.c'.

	* [if1632/user.c] [if1632/kernel.c]
	Put Atoms functions entries.

	* [controls/combo.c]
	New functions DirDlgSelectComboBox() & DirDlgListComboBox().

	* [controls/listbox.c]
	New functions DirDlgSelect() & DirDlgList().

Sun Apr 17 20:57:59 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [objects/test.c]
	GrayString() added.

	* [if1632/callback.c]
	CallGrayStringProc() added.

	* [if1632/relay.c] [if1632/mmsystem.spec]
	Added.

	* [if1632/kernel.spec] [if1632/user.spec]
	Added forgotten specs for atom functions.

Tue Apr 12 00:05:31 1994  Bob Amstadt  (bob@pooh)

	* misc/spy.c (SpyInit): Added more message types

	* [windows/mdi.c] [include/mdi.h]
	Maximizing and restoring child windows.
	Tiling of child windows.

Mon Apr 11 20:48:28 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [windows/winpos.c]
	Revert focus and activation to previous window when hiding a window.

	* [windows/syscolor.c]
	Implemented system color objects (brushes and pens created at
	SetSysColor() time for better performance).

	* [windows/graphics.c] [windows/nonclient.c] [controls/button.c]
	Changed painting code to use system color objects.

	* [windows/message.c]
	New function MSG_InternalGetMessage() for internal messages
	loops (e.g. for dialogs or menus).

	* [windows/hook.c] [include/hook.h]  (New files)
	Beginning of the window hooks implementation.

	* [windows/dialog.c]
	Use new function MSG_InternalGetMessage() in DialogBox().

	* [if1632/callback.c]
	Added function CallHookProc().

Apr 11, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/event.c]
	Bug fix : WM_CHARs are sent to focused window like WM_KEY???.

	* [misc/exec.c]
	Nothing much more than a stub for LoadModule(), I saw there a lot
		to be done in that corner, I will come back later ...

	* [loader/library.c]
	New functions GetWindowTask(), GetNumTask(), EnumTaskWindows() 
			and associated modules & tasks linked-lists.
	(it's only an 'emerging bud', more to come next weeks).

	* [loader/wine.c]
	Use LoadLibrary() instead of LoadImage() for 'sysres.dll'.

	* [control/menu.c]
	You can now click outside menu region without problem.
	Keyboard navig more smootly, even if a child has the focus.
	Bug fix in InsertItem(), (bad linklist when insert point not found).
	change Realloc for Free & Alloc in ModifyItem().
	MF_STRING now set BLACK_PEN to fix bug of bad color of the underscores 
		done by DrawText(), (maybe it should done in DrawText() itself ?).

Sun Apr 10 14:06:08 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [misc/profile.c]
	.INI files will now be stored in / loaded from the windows dir
	if no path is supplied.

	* [if1632/kernel.spec]
	Fixed GetDriveType's prototype.

	* [if1632/winsock.spec] [include/winsock.h] [misc/winsocket.c]
	Fixed prototypes: winsock uses a word as socket handle not an int.

	* [misc/winsocket.c]
	Added heap allocation for returned structures.
	Added non-blocking WSAAsyncGetXbyY() functions as blocking ones.

	* [loader/wine.c]
	Added IsDLLLoaded(), used in LoadImage() to prevent loading
	a dll multiple times.
	Directory is added to wine's path when a fullpath is supplied when
	starting wine.
	LoadImage(): DLL filename used instead DLL's own internal name,
	fixes 'Bad DLL name' errors.

Sat Apr  9 08:26:03 1994  David Metcalfe <david@prism.demon.co.uk>

	* [controls/edit.c] [controls/widgets.c]
	First release of edit control.
diff --git a/BUGS b/BUGS
index d005f85..3d53722 100644
--- a/BUGS
+++ b/BUGS
@@ -1,5 +1,5 @@
 - EBP and ESP are sometimes corrupted while running 16-bit code.
 - Dialog Boxes created by WM_CREATE handler aren't visible
 - RegisterClass() with hbrBackground = COLOR_APPWORKSPACE+1 does not work.
-- MDI client area needs to resize when frame does
-- Need to generate WM_CHILDACTIVATE
\ No newline at end of file
+- MDI does not send WM_GETMINMAX message.
+- InitializeLoadedDLLs() can't init LZEXPAND.DLL. (cs:ip => 0:0)
diff --git a/ChangeLog b/ChangeLog
index c69135a..d446171 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,144 @@
+Wed Apr 20 14:53:35 1994  Bob Amstadt  (bob@pooh)
+
+	* [tools/build.c] [if1632/call.S] [if1632/Imakefile]
+	Fixed bug for non-Linux systems.
+
+Apr 18, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
+
+	* [windows/win.c]
+	Bug fixed in CreateWindowEx() : Now use SetMenu() for menubar setup.
+	New empty stub for function SetSysModalWindow().
+
+	* [misc/exec.c]
+	New empty stub for function ExitWindows().
+
+	* [objects/font.c]
+	New empty stub for function EnumFonts().
+
+	* New file [misc/property.c]
+	New functions RemoveProp(), GetProp(), SetProp() & EnumProps().
+
+	* New file [misc/shell.c]
+	New empty stubs for function RegisterShellProc(), 
+			ShellExecute() & ShellProc().
+
+	* New files [loader/task.c] & [include/task.h]
+	Move functions GetWindowTask(), GetNumTask(), EnumTaskWindows()
+		from 'loader/library.c'.
+
+	* [loader/library.c]
+
+	* [if1632/user.c] [if1632/kernel.c]
+	Put Atoms functions entries.
+
+	* [controls/combo.c]
+	New functions DirDlgSelectComboBox() & DirDlgListComboBox().
+
+	* [controls/listbox.c]
+	New functions DirDlgSelect() & DirDlgList().
+
+Sun Apr 17 20:57:59 1994  Erik Bos (erik@trashcan.hacktic.nl)
+
+	* [objects/test.c]
+	GrayString() added.
+
+	* [if1632/callback.c]
+	CallGrayStringProc() added.
+
+	* [if1632/relay.c] [if1632/mmsystem.spec]
+	Added.
+
+	* [if1632/kernel.spec] [if1632/user.spec]
+	Added forgotten specs for atom functions.
+
+----------------------------------------------------------------------
+Tue Apr 12 00:05:31 1994  Bob Amstadt  (bob@pooh)
+
+	* misc/spy.c (SpyInit): Added more message types
+
+	* [windows/mdi.c] [include/mdi.h]
+	Maximizing and restoring child windows.
+	Tiling of child windows.
+
+Mon Apr 11 20:48:28 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)
+
+	* [windows/winpos.c]
+	Revert focus and activation to previous window when hiding a window.
+
+	* [windows/syscolor.c]
+	Implemented system color objects (brushes and pens created at
+	SetSysColor() time for better performance).
+
+	* [windows/graphics.c] [windows/nonclient.c] [controls/button.c]
+	Changed painting code to use system color objects.
+
+	* [windows/message.c]
+	New function MSG_InternalGetMessage() for internal messages
+	loops (e.g. for dialogs or menus).
+
+	* [windows/hook.c] [include/hook.h]  (New files)
+	Beginning of the window hooks implementation.
+
+	* [windows/dialog.c]
+	Use new function MSG_InternalGetMessage() in DialogBox().
+
+	* [if1632/callback.c]
+	Added function CallHookProc().
+
+Apr 11, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
+
+	* [windows/event.c]
+	Bug fix : WM_CHARs are sent to focused window like WM_KEY???.
+
+	* [misc/exec.c]
+	Nothing much more than a stub for LoadModule(), I saw there a lot
+		to be done in that corner, I will come back later ...
+
+	* [loader/library.c]
+	New functions GetWindowTask(), GetNumTask(), EnumTaskWindows() 
+			and associated modules & tasks linked-lists.
+	(it's only an 'emerging bud', more to come next weeks).
+
+	* [loader/wine.c]
+	Use LoadLibrary() instead of LoadImage() for 'sysres.dll'.
+
+	* [control/menu.c]
+	You can now click outside menu region without problem.
+	Keyboard navig more smootly, even if a child has the focus.
+	Bug fix in InsertItem(), (bad linklist when insert point not found).
+	change Realloc for Free & Alloc in ModifyItem().
+	MF_STRING now set BLACK_PEN to fix bug of bad color of the underscores 
+		done by DrawText(), (maybe it should done in DrawText() itself ?).
+
+Sun Apr 10 14:06:08 1994  Erik Bos (erik@trashcan.hacktic.nl)
+
+	* [misc/profile.c]
+	.INI files will now be stored in / loaded from the windows dir
+	if no path is supplied.
+
+	* [if1632/kernel.spec]
+	Fixed GetDriveType's prototype.
+
+	* [if1632/winsock.spec] [include/winsock.h] [misc/winsocket.c]
+	Fixed prototypes: winsock uses a word as socket handle not an int.
+
+	* [misc/winsocket.c]
+	Added heap allocation for returned structures.
+	Added non-blocking WSAAsyncGetXbyY() functions as blocking ones.
+
+	* [loader/wine.c]
+	Added IsDLLLoaded(), used in LoadImage() to prevent loading
+	a dll multiple times.
+	Directory is added to wine's path when a fullpath is supplied when
+	starting wine.
+	LoadImage(): DLL filename used instead DLL's own internal name,
+	fixes 'Bad DLL name' errors.
+
+Sat Apr  9 08:26:03 1994  David Metcalfe <david@prism.demon.co.uk>
+
+	* [controls/edit.c] [controls/widgets.c]
+	First release of edit control.
+
 ----------------------------------------------------------------------
 Tue Apr  5 14:36:59 1994  Bob Amstadt  (bob@pooh)
 
diff --git a/Configure b/Configure
old mode 100755
new mode 100644
diff --git a/PROPOSED_LICENSE b/PROPOSED_LICENSE
deleted file mode 100644
index a7d2f7a..0000000
--- a/PROPOSED_LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-You may without charge, royalty or other payment, copy and
-distribute copies of this work and derivative works of this work
-in source or binary form provided that: (1) 
-you appropriately publish on each copy an appropriate copyright
-notice; (2) faithfully reproduce all prior copyright notices
-included in the original work (you may also add your own
-copyright notice); and (3) agree to indemnify and hold all prior
-authors, copyright holders and licensors of the work harmless
-from and against all damages arising from use of the work.
-
-You may distribute sources of derivative works of the work
-provided that (1) (a) all source files of the original work that
-have been modified, (b) all source files of the derivative work
-that contain any party of the original work, and (c) all source
-files of the derivative work that are necessary to compile, link
-and run the derivative work without unresolved external calls and
-with the same functionality of the original work ("Necessary
-Sources") carry a prominent notice explaining the nature and date
-of the modification and/or creation.  You are encouraged to make
-the Necessary Sources available under this license in order to
-further the development and acceptance of the work.
-
-EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED
-WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING
-BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A
-PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE.  EXCEPT AS
-OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR
-LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
diff --git a/README b/README
index abc84a9..4e3c6a3 100644
--- a/README
+++ b/README
@@ -115,6 +115,9 @@
 
 	wine /usr/windows/sol.exe  (using a unixfilename)
 
+note: the path of the file will also be added to the path when
+      a full name is supplied on the commandline.
+
 Have a nice game of solitaire, but be careful.  Emulation isn't perfect.
 So, occassionally it will crash.
 
@@ -168,6 +171,20 @@
 
 7. WHAT'S NEW
 
+WHAT'S NEW with Wine-940420: (see ChangeLog for details)
+	- new property functions
+	- new listbox and combo box functions
+	- GrayString() and CallGrayStringProc()
+	- and many many bug fixes!
+
+WHAT'S NEW with Wine-940412: (see ChangeLog for details)
+	- menuing improvements
+	- drawing performance improvements
+	- beginnings of hooks
+	- MDI maximizing and tiling
+	- improvements in winsock implementation
+	- and many many bug fixes!
+
 WHAT'S NEW with Wine-940405: (see ChangeLog for details)
 	- Mouse activation of menus working again
 	- GetprocAddress()
diff --git a/WIN31-APPLETS b/WIN31-APPLETS
deleted file mode 100644
index edc64e4..0000000
--- a/WIN31-APPLETS
+++ /dev/null
@@ -1,45 +0,0 @@
-		       Status of MS Windows 3.1 Applets
-
-
-September 13, 1993
-
-I copied the following DLLs from my Windows (3.1) directory to my Wine
-directory.  Below I show how most of the programs included with
-Windows 3.1 died.
-
-        commdlg.dll   olesvr.dll    recorder.dll
-        olecli.dll    pbrush.dll    toolhelp.dll
-
-Scott Laird (lair@midway.uchicago.edu)
-
-
-calc.exe	dies no USER.89 (CreateDialog)
-calendar.exe	dies no KERNEL.60 (FindResource)
-cardfile.exe	cannot read relocation info
-charmap.exe	dies no USER.89 (CreateDialog)
-clipbrd.exe	dies no error
-clock.exe	dies no KERNEL.60 (FindResource)
-control.exe	dies no KERNEL.90 (lstrlen)
-drwatson.exe	dies no KERNEL.36 (GetCurrentTask)
-mplayer.exe	no MMSYSTEM.dll
-notepad.exe	dies no error
-nwpopup.exe	dies no KERNEL.47 (GetModuleHandle)
-packager.exe	cannot read relocation info
-pbrush.exe	cannot read relocation info
-pifedit.exe	dies no KERNEL.60 (FindResource)
-printman.exe	dies no KERNEL.107 (SetErrorMode)
-progman.exe	dies no error
-recorder.exe	cannot read relocation info
-regedit.exe	dies no KERNEL.90 (lstrlen)
-sol.exe		** RUNS **
-soundrec.exe	no MMSYSTEM.dll
-sysedit.exe	dies no USER.159 (GetSubMenu)
-terminal.exe	dies int21 2a
-winfile.exe	DOS ax=2fdf, dies no KERNEL.107
-winhelp.exe	dies no KERNEL.60 (FindResource)
-winmine.exe	dies no USER.256 (GetDesktopWindow)
-winpopup.exe	no NETAPI
-wintutor.exe	'Cannot load WINTUTOR.DAT' (file present)
-write.exe	cannot read relocation info
-
-
diff --git a/ansi2oem.trl b/ansi2oem.trl
deleted file mode 100755
index 2805bb3..0000000
--- a/ansi2oem.trl
+++ /dev/null
Binary files differ
diff --git a/autoconf.h b/autoconf.h
index 223fbc1..e6e34a8 100644
--- a/autoconf.h
+++ b/autoconf.h
@@ -1,2 +1,6 @@
 /* autoconf.h generated automatically.  Run Configure. */
-#error You must run Configure before you can build the makefiles.
+
+
+
+#define WINE_INI_GLOBAL "/home/alex/wine/wine.conf"
+#define AutoDefines  
diff --git a/controls/Imakefile b/controls/Imakefile
index 0f76706..2615294 100644
--- a/controls/Imakefile
+++ b/controls/Imakefile
@@ -9,6 +9,7 @@
 	menu.c \
 	scroll.c \
 	static.c \
+	edit.o \
 	desktop.c \
 	widgets.c
 
diff --git a/controls/button.c b/controls/button.c
index f58057b..8d96819 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -10,12 +10,10 @@
 #include <windows.h>
 #include "win.h"
 #include "user.h"
+#include "syscolor.h"
 
 LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
 
-static COLORREF color_windowtext, color_windowframe, color_btnface, 
-                color_btnshadow, color_btntext, color_btnhighlight;
-
 static BOOL pressed;
 
 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
@@ -203,14 +201,6 @@
 		    lResult = -1L;
 		else
 		{
-		    /* initialise colours used for button rendering: */
-		    color_windowtext   = GetSysColor(COLOR_WINDOWTEXT);
-		    color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
-		    color_btnface      = GetSysColor(COLOR_BTNFACE);
-		    color_btnshadow    = GetSysColor(COLOR_BTNSHADOW);
-		    color_btntext      = GetSysColor(COLOR_BTNTEXT);
-		    color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
-
 		    (WORD)(*(wndPtr->wExtra)) = 0;
 		    pressed = FALSE;
 		    lResult = 0L;
@@ -246,12 +236,6 @@
 		break;
 
 	case WM_SYSCOLORCHANGE:
-		color_windowtext   = GetSysColor(COLOR_WINDOWTEXT);
-		color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
-		color_btnface      = GetSysColor(COLOR_BTNFACE);
-		color_btnshadow    = GetSysColor(COLOR_BTNSHADOW);
-		color_btntext      = GetSysColor(COLOR_BTNTEXT);
-		color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
 		InvalidateRect(hWnd, NULL, TRUE);
 		break;
 
@@ -296,7 +280,7 @@
 
 static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
 {
-/*    SetFocus(hWnd); */
+    SetFocus(hWnd);
     SetCapture(hWnd);
     pressed = TRUE;
     InvalidateRect(hWnd, NULL, FALSE);
@@ -334,8 +318,8 @@
 
 static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
 {
-	HPEN hOldPen, hFramePen;
-	HBRUSH hOldBrush, hShadowBrush, hHighlightBrush, hBackgrndBrush;
+	HPEN hOldPen;
+	HBRUSH hOldBrush;
 	HRGN rgn1, rgn2, rgn;
 	int len;
 	static char text[50+1];
@@ -343,13 +327,9 @@
 	DWORD dwTextSize;
 	int delta;
 	TEXTMETRIC tm;
-	int i;
 
-	hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
-	hBackgrndBrush = CreateSolidBrush(color_btnface);
-
-	hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
-	hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
+	hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
+	hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
 	SetBkMode(hDC, TRANSPARENT);
 
 	rgn = CreateRectRgn(0, 0,  0,  0);
@@ -380,10 +360,9 @@
 	points[4].y = rc.top+1;
 	points[5].x = rc.left+2;
 	points[5].y = rc.top+1;
-	hHighlightBrush = CreateSolidBrush(color_btnhighlight);
 	rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
 	CombineRgn(rgn, rgn1, rgn2, RGN_AND);
-	FillRgn(hDC, rgn2, hHighlightBrush);
+	FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnHighlight);
 
 	/* draw button shadow: */
 	points[0].x = rc.left+2;
@@ -398,10 +377,9 @@
 	points[4].y = rc.top;
 	points[5].x = rc.right-1;
 	points[5].y = rc.bottom;
-	hShadowBrush = CreateSolidBrush(color_btnshadow);
 	rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
 	CombineRgn(rgn, rgn1, rgn2, RGN_AND);
-	FillRgn(hDC, rgn2, hShadowBrush);
+	FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnShadow);
 
 	/* do we have the focus? */
 	if (len >= 1 && GetFocus() == hButton) {
@@ -416,9 +394,6 @@
 
 	SelectObject(hDC, (HANDLE)hOldPen);
 	SelectObject(hDC, (HANDLE)hOldBrush);
-	DeleteObject((HANDLE)hFramePen);
-	DeleteObject((HANDLE)hShadowBrush);
-	DeleteObject((HANDLE)hBackgrndBrush);
 	DeleteObject((HANDLE)rgn1);
 	DeleteObject((HANDLE)rgn2);
 	DeleteObject((HANDLE)rgn);
@@ -427,20 +402,16 @@
 
 static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
 {
-	HPEN hOldPen, hShadowPen, hFramePen;
-	HBRUSH hOldBrush, hBackgrndBrush;
-	HRGN rgn1, rgn2, rgn;
+	HPEN hOldPen;
+	HBRUSH hOldBrush;
 	int len;
 	static char text[50+1];
 	DWORD dwTextSize;
 	int delta;
 	TEXTMETRIC tm;
 
-	hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
-	hBackgrndBrush = CreateSolidBrush(color_btnface);
-
-	hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
-	hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
+	hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
+	hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
 	SetBkMode(hDC, TRANSPARENT);
 
 	/* give parent a chance to alter parameters: */
@@ -449,11 +420,9 @@
 	Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
 
 	/* draw button shadow: */
-	hShadowPen = CreatePen(PS_SOLID, 1, color_btnshadow);
-	SelectObject(hDC, (HANDLE)hShadowPen);
-	MoveTo(hDC, rc.left+1, rc.bottom-1);
-	LineTo(hDC, rc.left+1, rc.top+1);
-	LineTo(hDC, rc.right-1, rc.top+1);
+	SelectObject(hDC, sysColorObjects.hbrushBtnShadow );
+	PatBlt(hDC, rc.left+1, rc.top+1, 1, rc.bottom-rc.top-2, PATCOPY );
+	PatBlt(hDC, rc.left+1, rc.top+1, rc.right-rc.left-2, 1, PATCOPY );
 
 	/* draw button label, if any: */
 	len = GetWindowText(hButton, text, sizeof text);
@@ -476,9 +445,6 @@
 
 	SelectObject(hDC, (HANDLE)hOldPen);
 	SelectObject(hDC, (HANDLE)hOldBrush);
-	DeleteObject((HANDLE)hBackgrndBrush);
-	DeleteObject(SelectObject(hDC, (HANDLE)hFramePen));
-	DeleteObject(SelectObject(hDC, (HANDLE)hShadowPen));
 }
 
 
@@ -491,7 +457,7 @@
     PAINTSTRUCT ps;
     RECT rc, rc3;
     HDC hDC;
-    HPEN hPen, hOldPen;
+    HPEN hOldPen;
     HBRUSH hBrush, hGrayBrush;
     int textlen, delta;
     char *text;
@@ -503,8 +469,7 @@
     hDC = BeginPaint(hWnd, &ps);
     GetClientRect(hWnd, &rc);
 
-    hPen = CreatePen(PS_SOLID, 1, color_windowtext);
-    hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
+    hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
     hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
 
     hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
@@ -555,6 +520,7 @@
 	DrawFocusRect(hDC, &rc);
     }
 
+    SelectObject(hDC, hOldPen);
     USER_HEAP_FREE(hText);
     GlobalUnlock(hWnd);
     EndPaint(hWnd, &ps);
@@ -577,7 +543,7 @@
     rc.right = tm.tmHeight;
     if (PtInRect(&rc, MAKEPOINT(lParam)))
     {
-/*	SetFocus(hWnd); */
+	SetFocus(hWnd);
 	SetCapture(hWnd);
 	pressed = TRUE;
 	InvalidateRect(hWnd, NULL, FALSE);
@@ -704,7 +670,7 @@
     PAINTSTRUCT ps;
     RECT rc;
     HDC hDC;
-    HPEN hPen, hOldPen;
+    HPEN hOldPen;
     HBRUSH hBrush, hOldBrush;
     int textlen, delta;
     char *text;
@@ -716,8 +682,7 @@
     hDC = BeginPaint(hWnd, &ps);
     GetClientRect(hWnd, &rc);
 
-    hPen = CreatePen(PS_SOLID, 1, color_windowtext);
-    hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
+    hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
 
     hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
 			 MAKELPARAM(hWnd, CTLCOLOR_BTN));
@@ -737,7 +702,7 @@
 
     if ((WORD)(*(wndPtr->wExtra)) == 1)
     {
-	hBrush = CreateSolidBrush(color_windowtext);
+	hBrush = CreateSolidBrush( GetNearestColor(hDC, GetSysColor(COLOR_WINDOWTEXT)));
 	hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBrush);
 	Ellipse(hDC, 3, rc.top + delta + 3, tm.tmHeight - 3,
 		                            tm.tmHeight + delta -3); 
@@ -759,6 +724,7 @@
 	DrawFocusRect(hDC, &rc);
     }
 
+    SelectObject(hDC, hOldPen );
     USER_HEAP_FREE(hText);
     GlobalUnlock(hWnd);
     EndPaint(hWnd, &ps);
@@ -781,7 +747,7 @@
     rc.right = tm.tmHeight;
     if (PtInRect(&rc, MAKEPOINT(lParam)))
     {
-/*	SetFocus(hWnd); */
+	SetFocus(hWnd);
 	SetCapture(hWnd);
 	pressed = TRUE;
 	InvalidateRect(hWnd, NULL, FALSE);
@@ -880,7 +846,7 @@
     PAINTSTRUCT ps;
     RECT rc;
     HDC hDC;
-    HPEN hPen, hOldPen;
+    HPEN hOldPen;
     HBRUSH hBrush;
     int textlen;
     char *text;
@@ -890,8 +856,7 @@
     hDC = BeginPaint(hWnd, &ps);
     GetClientRect(hWnd, &rc);
 
-    hPen = CreatePen(PS_SOLID, 1, color_windowtext);
-    hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
+    hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
 
     hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
 			 MAKELPARAM(hWnd, CTLCOLOR_BTN));
@@ -911,6 +876,7 @@
     rc.bottom = size.cy;
     DrawText(hDC, text, textlen, &rc, DT_SINGLELINE);
 
+    SelectObject(hDC, hOldPen );
     USER_HEAP_FREE(hText);
     EndPaint(hWnd, &ps);
 }
@@ -947,7 +913,7 @@
 {
     RECT rc;
 
-/*    SetFocus(hWnd); */
+    SetFocus(hWnd);
     SetCapture(hWnd);
     GetClientRect(hWnd, &rc);
     if (PtInRect(&rc, MAKEPOINT(lParam)))
@@ -1013,7 +979,7 @@
     HANDLE	hDis;
     LPDRAWITEMSTRUCT lpdis;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
-/*    SetFocus(hWnd); */
+    SetFocus(hWnd);
     SetCapture(hWnd);
     hDC = GetDC(hWnd);
     GetClientRect(hWnd, &rc);
diff --git a/controls/combo.c b/controls/combo.c
index ae18601..06fac4c 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -61,13 +61,12 @@
 		width = rect.right - rect.left;
 		height = rect.bottom - rect.top;
 		SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight, 
-		SWP_NOMOVE | SWP_NOZORDER); 
+										SWP_NOMOVE | SWP_NOZORDER); 
 		CreateComboStruct(hwnd);
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL) return 0;
 		if (wndPtr->dwStyle & CBS_SIMPLE)
-/*			lphc->hWndEdit = CreateWindow("EDIT", "", */
-			lphc->hWndEdit = CreateWindow("STATIC", "", 
+			lphc->hWndEdit = CreateWindow("EDIT", "", 
 				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
 				0, 0, width - bm.bmHeight, bm.bmHeight, 
 				hwnd, 1, wndPtr->hInstance, 0L);
@@ -370,3 +369,30 @@
 
 
 
+/************************************************************************
+ * 					DlgDirSelectComboBox	[USER.194]
+ */
+BOOL DlgDirSelectComboBox(HWND hDlg, LPSTR lpStr, int nIDLBox)
+{
+	printf("DlgDirSelectComboBox(%04X, '%s', %d) \n",	hDlg, lpStr, nIDLBox);
+}
+
+
+/************************************************************************
+ * 					DlgDirListComboBox		[USER.195]
+ */
+int DlgDirListComboBox(HWND hDlg, LPSTR lpPathSpec, 
+	int nIDLBox, int nIDStat, WORD wType)
+{
+	HWND		hWnd;
+    LPHEADCOMBO lphc;
+	printf("DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
+			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
+	hWnd = GetDlgItem(hDlg, nIDLBox);
+	lphc = ComboGetStorageHeader(hWnd);
+	SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
+	return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);
+}
+
+
+
diff --git a/controls/edit.c b/controls/edit.c
new file mode 100644
index 0000000..55678c0
--- /dev/null
+++ b/controls/edit.c
@@ -0,0 +1,2384 @@
+/*
+ * Edit control
+ *
+ * Copyright  David W. Metcalfe, 1994
+ *
+ * Release 1, April 1994
+ */
+
+static char Copyright[] = "Copyright  David W. Metcalfe, 1994";
+
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+#include "win.h"
+#include "class.h"
+#include "user.h"
+
+/*
+#define DEBUG_EDIT
+*/
+
+#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
+	SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
+		 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
+
+#define MAXTEXTLEN 32000   /* maximum text buffer length */
+#define EDITLEN     1024   /* starting length for multi-line control */
+#define ENTRYLEN     256   /* starting length for single line control */
+#define GROWLENGTH    64   /* buffers grow by this much */
+
+#define HSCROLLDIM (ClientWidth(wndPtr) / 3)
+                           /* "line" dimension for horizontal scroll */
+
+#define EDIT_HEAP_ALLOC(size)          USER_HEAP_ALLOC(GMEM_MOVEABLE,size)
+#define EDIT_HEAP_REALLOC(handle,size) USER_HEAP_REALLOC(handle,size,\
+							 GMEM_MOVEABLE)
+#define EDIT_HEAP_ADDR(handle)         USER_HEAP_ADDR(handle)
+#define EDIT_HEAP_FREE(handle)         USER_HEAP_FREE(handle)
+
+typedef struct
+{
+    int wlines;              /* number of lines of text */
+    int wtop;                /* top line that is displayed */
+    int wleft;               /* left pixel that is displayed */
+    unsigned int textlen;    /* text buffer length */
+    int textwidth;           /* width of longest line in pixels */
+    RECT fmtrc;              /* rectangle in which to format text */
+    int txtht;               /* height of text line in pixels */
+    HANDLE hText;            /* handle to text buffer */
+    HANDLE hCharWidths;      /* widths of chars in font */
+    HANDLE hTextPtrs;        /* list of line offsets */
+    HANDLE hBlankLine;       /* to fill blank lines quickly */
+    int CurrCol;             /* current column */
+    int CurrLine;            /* current line */
+    int WndCol;              /* current window column */
+    int WndRow;              /* current window row */
+    BOOL TextChanged;        /* TRUE if text has changed */
+    BOOL PaintBkgd;          /* paint control background */
+    unsigned int MaxTextLen; /* maximum text buffer length */
+    int SelBegLine;          /* beginning line of selection */
+    int SelBegCol;           /* beginning column of selection */
+    int SelEndLine;          /* ending line of selection */
+    int SelEndCol;           /* ending column of selection */
+} EDITSTATE;
+
+
+#define ClientWidth(wndPtr) (wndPtr->rectClient.right - \
+			     wndPtr->rectClient.left)
+#define ClientHeight(wndPtr, es) ((wndPtr->rectClient.bottom - \
+				   wndPtr->rectClient.top) / es->txtht)
+#define EditBufLen(wndPtr) (wndPtr->dwStyle & ES_MULTILINE \
+			    ? EDITLEN : ENTRYLEN)
+#define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
+#define SelMarked(es) (es->SelBegLine != -1 && es->SelBegCol != -1 && \
+		       es->SelEndLine != -1 && es->SelEndCol != -1)
+
+/* macros to access window styles */
+#define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL)
+#define IsAutoHScroll() (wndPtr->dwStyle & ES_AUTOHSCROLL)
+#define IsMultiLine() (wndPtr->dwStyle & ES_MULTILINE)
+#define IsVScrollBar() (wndPtr->dwStyle & WS_VSCROLL)
+#define IsHScrollBar() (wndPtr->dwStyle & WS_HSCROLL)
+
+/* internal variables */
+static BOOL TextMarking;         /* TRUE if text marking in progress */
+static BOOL ButtonDown;          /* TRUE if left mouse button down */
+static int ButtonRow;              /* row in text buffer when button pressed */
+static int ButtonCol;              /* col in text buffer when button pressed */
+static BOOL Print = FALSE;
+
+
+LONG EditWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
+long EDIT_CreateMsg(HWND hwnd, LONG lParam);
+void EDIT_ClearTextPointers(HWND hwnd);
+void EDIT_BuildTextPointers(HWND hwnd);
+void EDIT_ModTextPointers(HWND hwnd, int lineno, int var);
+void EDIT_PaintMsg(HWND hwnd);
+HANDLE EDIT_GetTextLine(HWND hwnd, int selection);
+char *EDIT_TextLine(HWND hwnd, int sel);
+int EDIT_LineLength(EDITSTATE *es, char *str, int len);
+void EDIT_WriteTextLine(HWND hwnd, RECT *rc, int y);
+void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, 
+		    int col, RECT *rc, BOOL blank, BOOL reverse);
+HANDLE EDIT_GetStr(EDITSTATE *es, char *lp, int off, int len, int *diff);
+void EDIT_CharMsg(HWND hwnd, WORD wParam);
+void EDIT_KeyTyped(HWND hwnd, short ch);
+int EDIT_CharWidth(EDITSTATE *es, short ch);
+void EDIT_Forward(HWND hwnd);
+void EDIT_Downward(HWND hwnd);
+void EDIT_Upward(HWND hwnd);
+void EDIT_Backward(HWND hwnd);
+void EDIT_End(HWND hwnd);
+void EDIT_Home(HWND hwnd);
+void EDIT_StickEnd(HWND hwnd);
+void EDIT_KeyDownMsg(HWND hwnd, WORD wParam);
+void EDIT_KeyHScroll(HWND hwnd, WORD opt);
+void EDIT_KeyVScrollLine(HWND hwnd, WORD opt);
+void EDIT_KeyVScrollPage(HWND hwnd, WORD opt);
+void EDIT_KeyVScrollDoc(HWND hwnd, WORD opt);
+int EDIT_ComputeVScrollPos(HWND hwnd);
+int EDIT_ComputeHScrollPos(HWND hwnd);
+void EDIT_DelKey(HWND hwnd);
+void EDIT_VScrollMsg(HWND hwnd, WORD wParam, LONG lParam);
+void EDIT_VScrollLine(HWND hwnd, WORD opt);
+void EDIT_VScrollPage(HWND hwnd, WORD opt);
+void EDIT_HScrollMsg(HWND hwnd, WORD wParam, LONG lParam);
+void EDIT_SizeMsg(HWND hwnd, WORD wParam, LONG lParam);
+void EDIT_LButtonDownMsg(HWND hwnd, WORD wParam, LONG lParam);
+void EDIT_MouseMoveMsg(HWND hwnd, WORD wParam, LONG lParam);
+int EDIT_PixelToChar(HWND hwnd, int row, int *pixel);
+LONG EDIT_SetTextMsg(HWND hwnd, LONG lParam);
+void EDIT_ClearText(HWND hwnd);
+void EDIT_SetSelMsg(HWND hwnd, LONG lParam);
+void EDIT_GetLineCol(HWND hwnd, int off, int *line, int *col);
+void EDIT_DeleteSel(HWND hwnd);
+void EDIT_ClearSel(HWND hwnd);
+int EDIT_TextLineNumber(HWND hwnd, char *lp);
+void EDIT_SetAnchor(HWND hwnd, int row, int col);
+void EDIT_ExtendSel(HWND hwnd, int x, int y);
+void EDIT_StopMarking(HWND hwnd);
+LONG EDIT_GetLineMsg(HWND hwnd, WORD wParam, LONG lParam);
+LONG EDIT_GetSelMsg(HWND hwnd);
+LONG EDIT_LineFromCharMsg(HWND hwnd, WORD wParam);
+LONG EDIT_LineIndexMsg(HWND hwnd, WORD wParam);
+void swap(int *a, int *b);
+
+
+LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam)
+{
+    LONG lResult = 0L;
+    HDC hdc;
+    char *textPtr;
+    int len;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    switch (uMsg) {
+    case EM_CANUNDO:
+	/* cannot process undo message */
+	lResult = 0L;
+	break;
+	
+    case EM_FMTLINES:
+	printf("edit: cannot process EM_FMTLINES message\n");
+	lResult = 0L;
+	break;
+
+    case EM_GETFIRSTVISIBLELINE:
+	lResult = es->wtop;
+	break;
+
+    case EM_GETHANDLE:
+	printf("edit: cannot process EM_GETHANDLE message\n");
+	break;
+
+    case EM_GETLINE:
+	if (IsMultiLine())
+	    lResult = EDIT_GetLineMsg(hwnd, wParam, lParam);
+	else
+	    lResult = 0L;
+	break;
+
+    case EM_GETLINECOUNT:
+	if (IsMultiLine())
+	    lResult = es->wlines;
+	else
+	    lResult = 0L;
+	break;
+
+    case EM_GETMODIFY:
+	lResult = es->TextChanged;
+	break;
+
+    case EM_GETPASSWORDCHAR:
+	printf("edit: cannot process EM_GETPASSWORDCHAR message\n");
+	break;
+
+    case EM_GETRECT:
+	GetWindowRect(hwnd, (LPRECT)lParam);
+	break;
+
+    case EM_GETSEL:
+	lResult = EDIT_GetSelMsg(hwnd);
+	break;
+
+    case EM_GETWORDBREAKPROC:
+	printf("edit: cannot process EM_GETWORDBREAKPROC message\n");
+	break;
+
+    case EM_LIMITTEXT:
+	es->MaxTextLen = wParam;
+	break;
+
+    case EM_LINEFROMCHAR:
+	lResult = EDIT_LineFromCharMsg(hwnd, wParam);
+	break;
+
+    case EM_LINEINDEX:
+	if (IsMultiLine())
+	    lResult = EDIT_LineIndexMsg(hwnd, wParam);
+	else
+	    lResult = 0L;
+	break;
+
+    case EM_LINELENGTH:
+	printf("edit: cannot process EM_LINELENGTH message\n");
+	break;
+
+    case EM_LINESCROLL:
+	printf("edit: cannot process EM_LINESCROLL message\n");
+	break;
+
+    case EM_REPLACESEL:
+	printf("edit: cannot process EM_REPLACESEL message\n");
+	break;
+
+    case EM_SETHANDLE:
+	printf("edit: cannot process EM_SETHANDLE message\n");
+	break;
+
+    case EM_SETMODIFY:
+	es->TextChanged = wParam;
+	break;
+
+    case EM_SETPASSWORDCHAR:
+	printf("edit: cannot process EM_SETPASSWORDCHAR message\n");
+	break;
+
+    case EM_SETREADONLY:
+	printf("edit: cannot process EM_SETREADONLY message\n");
+	break;
+
+    case EM_SETRECT:
+    case EM_SETRECTNP:
+	printf("edit: cannot process EM_SETRECT(NP) message\n");
+	break;
+
+    case EM_SETSEL:
+	HideCaret(hwnd);
+	EDIT_SetSelMsg(hwnd, lParam);
+	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+	ShowCaret(hwnd);
+	break;
+
+    case EM_SETTABSTOPS:
+	printf("edit: cannot process EM_SETTABSTOPS message\n");
+	break;
+
+    case EM_SETWORDBREAKPROC:
+	printf("edit: cannot process EM_SETWORDBREAKPROC message\n");
+	break;
+
+    case WM_CHAR:
+	EDIT_CharMsg(hwnd, wParam);
+	break;
+
+    case WM_CREATE:
+	lResult = EDIT_CreateMsg(hwnd, lParam);
+	break;
+
+    case WM_DESTROY:
+	EDIT_HEAP_FREE(es->hTextPtrs);
+	EDIT_HEAP_FREE(es->hCharWidths);
+	EDIT_HEAP_FREE((HANDLE)(*(wndPtr->wExtra)));
+	break;
+
+    case WM_ENABLE:
+	InvalidateRect(hwnd, NULL, FALSE);
+	break;
+
+    case WM_GETTEXT:
+	textPtr = (LPSTR)EDIT_HEAP_ADDR(es->hText);
+	if ((int)wParam > (len = strlen(textPtr)))
+	{
+	    strcpy((char *)lParam, textPtr);
+	    lResult = (DWORD)len;
+	}
+	else
+	    lResult = 0L;
+	break;
+
+    case WM_GETTEXTLENGTH:
+	textPtr = (LPSTR)EDIT_HEAP_ADDR(es->hText);
+	lResult = (DWORD)strlen(textPtr);
+	break;
+
+    case WM_HSCROLL:
+	EDIT_HScrollMsg(hwnd, wParam, lParam);
+	break;
+
+    case WM_KEYDOWN:
+	EDIT_KeyDownMsg(hwnd, wParam);
+	break;
+
+    case WM_KILLFOCUS:
+	DestroyCaret();
+	NOTIFY_PARENT(hwnd, EN_KILLFOCUS);
+	break;
+
+    case WM_LBUTTONDOWN:
+	HideCaret(hwnd);
+	EDIT_LButtonDownMsg(hwnd, wParam, lParam);
+	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+	ShowCaret(hwnd);
+	break;
+
+    case WM_LBUTTONUP:
+	ButtonDown = FALSE;
+	if (TextMarking)
+	    EDIT_StopMarking(hwnd);
+	break;
+
+    case WM_MOUSEMOVE:
+	HideCaret(hwnd);
+	EDIT_MouseMoveMsg(hwnd, wParam, lParam);
+	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+	ShowCaret(hwnd);
+	break;
+
+    case WM_MOVE:
+	lResult = 0;
+	break;
+
+    case WM_PAINT:
+	EDIT_PaintMsg(hwnd);
+	break;
+
+    case WM_SETFOCUS:
+	es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+	CreateCaret(hwnd, 0, 2, es->txtht);
+	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+	ShowCaret(hwnd);
+	NOTIFY_PARENT(hwnd, EN_SETFOCUS);
+	break;
+
+    case WM_SETFONT:
+	break;
+
+    case WM_SETTEXT:
+	EDIT_SetTextMsg(hwnd, lParam);
+	break;
+
+    case WM_SIZE:
+	EDIT_SizeMsg(hwnd, wParam, lParam);
+	lResult = 0;
+	break;
+
+    case WM_VSCROLL:
+	EDIT_VScrollMsg(hwnd, wParam, lParam);
+	break;
+
+    default:
+	lResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
+	break;
+    }
+
+    GlobalUnlock(hwnd);
+    return lResult;
+}
+
+
+/*********************************************************************
+ *  WM_CREATE message function
+ */
+
+long EDIT_CreateMsg(HWND hwnd, LONG lParam)
+{
+    HDC hdc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es;
+    CLASS *classPtr;
+    short *charWidths;
+    TEXTMETRIC tm;
+    char *text;
+    unsigned int *textPtrs;
+
+    /* allocate space for state variable structure */
+    (HANDLE)(*(wndPtr->wExtra)) = 
+	EDIT_HEAP_ALLOC(sizeof(EDITSTATE));
+    es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    es->hTextPtrs = EDIT_HEAP_ALLOC(sizeof(int));
+    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    es->hCharWidths = EDIT_HEAP_ALLOC(256 * sizeof(short));
+
+    /* initialize state variable structure */
+    /* --- char width array */
+    hdc = GetDC(hwnd);
+    charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+    memset(charWidths, 0, 256 * sizeof(short));
+    GetCharWidth(hdc, 0, 255, charWidths);
+
+    /* --- text buffer */
+    es->MaxTextLen = MAXTEXTLEN + 1;
+    if (!(wndPtr->hText))
+    {
+	es->textlen = EditBufLen(wndPtr);
+	es->hText = EDIT_HEAP_ALLOC(EditBufLen(wndPtr) + 2);
+	text = (LPSTR)EDIT_HEAP_ADDR(es->hText);
+	memset(text, 0, es->textlen + 2);
+	EDIT_ClearTextPointers(hwnd);
+    }
+    else
+    {
+	es->hText = wndPtr->hText;
+	wndPtr->hText = 0;
+	es->textlen = GetWindowTextLength(hwnd) + 1;
+	EDIT_BuildTextPointers(hwnd);
+    }
+
+    /* --- other structure variables */
+    GetTextMetrics(hdc, &tm);
+    es->txtht = tm.tmHeight + tm.tmExternalLeading;
+    es->wlines = 0;
+    es->wtop = es->wleft = 0;
+    es->CurrCol = es->CurrLine = 0;
+    es->WndCol = es->WndRow = 0;
+    es->TextChanged = FALSE;
+    es->textwidth = 0;
+    es->SelBegLine = es->SelBegCol = -1;
+    es->SelEndLine = es->SelEndCol = -1;
+
+    /* allocate space for a line full of blanks to speed up */
+    /* line filling */
+    es->hBlankLine = EDIT_HEAP_ALLOC((ClientWidth(wndPtr) / 
+				      charWidths[32]) + 2); 
+    text = EDIT_HEAP_ADDR(es->hBlankLine);
+    memset(text, ' ', (ClientWidth(wndPtr) / charWidths[32]) + 2);
+
+    /* set up text cursor for edit class */
+    CLASS_FindClassByName("EDIT", &classPtr);
+    classPtr->wc.hCursor = LoadCursor(0, IDC_IBEAM);
+
+    /* paint background on first WM_PAINT */
+    es->PaintBkgd = TRUE;
+
+    ReleaseDC(hwnd, hdc);
+    return 0L;
+}
+
+
+/*********************************************************************
+ *  EDIT_ClearTextPointers
+ *
+ *  Clear and initialize text line pointer array.
+ */
+
+void EDIT_ClearTextPointers(HWND hwnd)
+{
+    unsigned int *textPtrs;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    
+    es->hTextPtrs = EDIT_HEAP_REALLOC(es->hTextPtrs, sizeof(int));
+    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    *textPtrs = 0;
+}
+
+
+/*********************************************************************
+ *  EDIT_BuildTextPointers
+ *
+ *  Build array of pointers to text lines.
+ */
+
+#define INITLINES 100
+
+void EDIT_BuildTextPointers(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    char *text, *cp;
+    int incrs = INITLINES;
+    unsigned int off, len, temp;
+    EDITSTATE *es;
+    unsigned int *textPtrs;
+    short *charWidths;
+
+    es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    text = (char *)EDIT_HEAP_ADDR(es->hText);
+    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+
+    es->textwidth = es->wlines = 0;
+    cp = text;
+
+    /* advance through text buffer */
+    while (*cp)
+    {
+	/* increase size of text pointer array */ 
+	if (incrs == INITLINES)
+	{
+	    incrs = 0;
+	    es->hTextPtrs = EDIT_HEAP_REALLOC(es->hTextPtrs,
+			      (es->wlines + INITLINES) * sizeof(int));
+	    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+	}
+	off = (unsigned int)(cp - text);     /* offset of beginning of line */
+	*(textPtrs + es->wlines) = off;
+	es->wlines++;
+	incrs++;
+	len = 0;
+	
+	/* advance through current line */
+	while (*cp && *cp != '\n')
+	{
+	    len += charWidths[*cp];          /* width of line in pixels */
+	    cp++;
+	}
+	es->textwidth = max(es->textwidth, len);
+	if (*cp)
+	    cp++;                            /* skip '\n' */
+    }
+    off = (unsigned int)(cp - text);     /* offset of beginning of line */
+    *(textPtrs + es->wlines) = off;
+}
+
+
+/*********************************************************************
+ *  EDIT_ModTextPointers
+ *
+ *  Modify text pointers from a specified position.
+ */
+
+void EDIT_ModTextPointers(HWND hwnd, int lineno, int var)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+
+    while (lineno < es->wlines)
+	*(textPtrs + lineno++) += var;
+}
+
+
+/*********************************************************************
+ *  WM_PAINT message function
+ */
+
+void EDIT_PaintMsg(HWND hwnd)
+{
+    PAINTSTRUCT ps;
+    HDC hdc;
+    int y;
+    RECT rc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    hdc = BeginPaint(hwnd, &ps);
+    rc = ps.rcPaint;
+
+#ifdef DEBUG_EDIT
+    printf("WM_PAINT: rc=(%d,%d), (%d,%d)\n", rc.left, rc.top, 
+	   rc.right, rc.bottom);
+#endif
+
+    if (es->PaintBkgd)
+	FillWindow(GetParent(hwnd), hwnd, hdc, CTLCOLOR_EDIT);
+
+    for (y = (rc.top / es->txtht); y <= (rc.bottom / es->txtht); y++)
+    {
+	if (y < es->wlines - es->wtop)
+	    EDIT_WriteTextLine(hwnd, &rc, y + es->wtop);
+    }
+
+    EndPaint(hwnd, &ps);
+}
+
+
+/*********************************************************************
+ *  EDIT_GetTextLine
+ *
+ *  Get a copy of the text in the specified line.
+ */
+
+HANDLE EDIT_GetTextLine(HWND hwnd, int selection)
+{
+    char *line;
+    HANDLE hLine;
+    int len = 0;
+    char *cp, *cp1;
+
+#ifdef DEBUG_EDIT
+    printf("GetTextLine %d\n", selection);
+#endif
+    cp = cp1 = EDIT_TextLine(hwnd, selection);
+    /* advance through line */
+    while (*cp && *cp != '\n')
+    {
+	len++;
+	cp++;
+    }
+
+    /* store selected line and return handle */
+    hLine = EDIT_HEAP_ALLOC(len + 6);
+    line = (char *)EDIT_HEAP_ADDR(hLine);
+    memmove(line, cp1, len);
+    line[len] = '\0';
+    return hLine;
+}
+
+
+/*********************************************************************
+ *  EDIT_TextLine
+ *
+ *  Return a pointer to the text in the specified line.
+ */
+
+char *EDIT_TextLine(HWND hwnd, int sel)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+
+    return (text + *(textPtrs + sel));
+}
+    
+
+/*********************************************************************
+ *  EDIT_LineLength
+ *
+ *  Return length of line _str_ of length _len_ characters in pixels.
+ */
+
+int EDIT_LineLength(EDITSTATE *es, char *str, int len)
+{
+    int i, plen = 0;
+    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+
+    for (i = 0; i < len; i++)
+	plen += charWidths[*(str + i)];
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_LineLength: returning %d\n", plen);
+#endif
+    return plen;
+}
+
+
+/*********************************************************************
+ *  EDIT_WriteTextLine
+ *
+ *  Write the line of text at offset _y_ in text buffer to a window.
+ */
+
+void EDIT_WriteTextLine(HWND hwnd, RECT *rect, int y)
+{
+    int len = 0;
+    unsigned char line[200];
+    HANDLE hLine;
+    unsigned char *lp;
+    int lnlen, lnlen1;
+    int col, off = 0;
+    int sbl, sel, sbc, sec;
+    RECT rc;
+    div_t num;
+    BOOL trunc = FALSE;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    /* initialize rectangle if NULL, else copy */
+    if (rect)
+	CopyRect(&rc, rect);
+    else
+	GetClientRect(hwnd, &rc);
+
+#ifdef DEBUG_EDIT
+    printf("WriteTextLine %d\n", y);
+#endif
+
+    /* make sure y is inside the window */
+    if (y < es->wtop || y > (es->wtop + ClientHeight(wndPtr, es)))
+    {
+#ifdef DEBUG_EDIT
+	printf("EDIT_WriteTextLine: y (%d) is not a displayed line\n", y);
+#endif
+	return;
+    }
+
+    /* make sure rectangle is within window */
+    if (rc.left >= ClientWidth(wndPtr) - 1)
+    {
+#ifdef DEBUG_EDIT
+	printf("EDIT_WriteTextLine: rc.left (%d) is greater than right edge\n",
+	       rc.left);
+#endif
+	return;
+    }
+    if (rc.right <= 0)
+    {
+#ifdef DEBUG_EDIT
+	printf("EDIT_WriteTextLine: rc.right (%d) is less than left edge\n",
+	       rc.right);
+#endif
+	return;
+    }
+    if (y - es->wtop < (rc.top / es->txtht) || 
+	y - es->wtop > (rc.bottom / es->txtht))
+    {
+#ifdef DEBUG_EDIT
+	printf("EDIT_WriteTextLine: y (%d) is outside window\n", y);
+#endif
+	return;
+    }
+
+    /* get the text and length of line */
+    if ((hLine = EDIT_GetTextLine(hwnd, y)) == 0)
+	return;
+    lp = (unsigned char *)EDIT_HEAP_ADDR(hLine);
+    lnlen = EDIT_LineLength(es, lp, strlen(lp));
+    lnlen1 = lnlen;
+
+    /* build the line to display */
+    if (lnlen < es->wleft)
+	lnlen = 0;
+    else
+	off += es->wleft;
+
+    if (lnlen > rc.left)
+    {
+	off += rc.left;
+	lnlen = lnlen1 - off;
+	len = min(lnlen, rc.right - rc.left);
+    }
+
+    if (SelMarked(es))
+    {
+	sbl = es->SelBegLine;
+	sel = es->SelEndLine;
+	sbc = es->SelBegCol;
+	sec = es->SelEndCol;
+
+	/* put lowest marker first */
+	if (sbl > sel)
+	{
+	    swap(&sbl, &sel);
+	    swap(&sbc, &sec);
+	}
+	if (sbl == sel && sbc > sec)
+	    swap(&sbc, &sec);
+
+	if (y < sbl || y > sel)
+	    EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, rc.left, &rc,
+			   TRUE, FALSE);
+	else if (y > sbl && y < sel)
+	    EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, rc.left, &rc,
+			   TRUE, TRUE);
+	else if (y == sbl)
+	{
+	    col = EDIT_LineLength(es, lp, sbc);
+	    if (col > (es->wleft + rc.left))
+	    {
+		len = min(col - off, rc.right - off);
+		EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, 
+			       rc.left, &rc, FALSE, FALSE);
+		off = col;
+	    }
+	    if (y == sel)
+	    {
+		col = EDIT_LineLength(es, lp, sec);
+		if (col < (es->wleft + rc.right))
+		{
+		    len = min(col - off, rc.right - off);
+		    EDIT_WriteText(hwnd, lp, off, len, y - es->wtop,
+				   off - es->wleft, &rc, FALSE, TRUE);
+		    off = col;
+		    len = min(lnlen - off, rc.right - off);
+		    EDIT_WriteText(hwnd, lp, off, len, y - es->wtop,
+				   off - es->wleft, &rc, TRUE, FALSE);
+		}
+		else
+		{
+		    len = min(lnlen - off, rc.right - off);
+		    EDIT_WriteText(hwnd, lp, off, len, y - es->wtop,
+				   off - es->wleft, &rc, TRUE, TRUE);
+		}
+	    }
+	    else
+	    {
+		len = min(lnlen - off, rc.right - off);
+		if (col < (es->wleft + rc.right))
+		    EDIT_WriteText(hwnd, lp, off, len, y - es->wtop,
+				   off - es->wleft, &rc, TRUE, TRUE);
+	    }
+	}
+	else if (y == sel)
+	{
+	    col = EDIT_LineLength(es, lp, sec);
+	    if (col < (es->wleft + rc.right))
+	    {
+		len = min(col - off, rc.right - off);
+		EDIT_WriteText(hwnd, lp, off, len, y - es->wtop,
+			       off - es->wleft, &rc, FALSE, TRUE);
+		off = col;
+		len = min(lnlen - off, rc.right - off);
+		EDIT_WriteText(hwnd, lp, off, len, y - es->wtop,
+			       off - es->wleft, &rc, TRUE, FALSE);
+	    }
+	}
+    }
+    else
+	EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, rc.left, &rc,
+		       TRUE, FALSE);
+	      
+    EDIT_HEAP_FREE(hLine);
+}
+
+
+/*********************************************************************
+ *  EDIT_WriteText
+ *
+ *  Write text to a window
+ *     lp  - text line
+ *     off - offset in text line (in pixels)
+ *     len - length from off (in pixels)
+ *     row - line in window
+ *     col - column in window
+ *     rc  - rectangle in which to display line
+ *     blank - blank remainder of line?
+ *     reverse - reverse color of line?
+ */
+
+void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, 
+		    int col, RECT *rc, BOOL blank, BOOL reverse)
+{
+    HDC hdc;
+    HANDLE hStr;
+    char *str, *blanks;
+    int diff, num_spaces;
+    HRGN hrgnClip;
+    COLORREF oldTextColor, oldBkgdColor;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp, off, len, row, col, reverse);
+#endif
+
+    hdc = GetDC(hwnd);
+    hStr = EDIT_GetStr(es, lp, off, len, &diff);
+    str = (char *)EDIT_HEAP_ADDR(hStr);
+    hrgnClip = CreateRectRgnIndirect(rc);
+    SelectClipRgn(hdc, hrgnClip);
+
+    SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc,
+		MAKELPARAM(hwnd, CTLCOLOR_EDIT));
+
+    if (reverse)
+    {
+	oldBkgdColor = GetBkColor(hdc);
+	oldTextColor = GetTextColor(hdc);
+	SetBkColor(hdc, oldTextColor);
+	SetTextColor(hdc, oldBkgdColor);
+    }
+
+    TextOut(hdc, col - diff, row * es->txtht, str, strlen(str));
+
+    if (reverse)
+    {
+	SetBkColor(hdc, oldBkgdColor);
+	SetTextColor(hdc, oldTextColor);
+    }
+
+    /* blank out remainder of line if appropriate */
+    if (blank)
+    {
+	if ((rc->right - col) > len)
+	{
+	    blanks = EDIT_HEAP_ADDR(es->hBlankLine);
+	    num_spaces = (rc->right - col - len) / charWidths[32];
+	    TextOut(hdc, col + len, row * es->txtht, blanks, num_spaces);
+	}
+    }
+
+    EDIT_HEAP_FREE(hStr);
+    ReleaseDC(hwnd, hdc);
+}
+
+
+/*********************************************************************
+ *  EDIT_GetStr
+ *
+ *  Return sub-string starting at pixel _off_ of length _len_ pixels.
+ *  If _off_ is part way through a character, the negative offset of
+ *  the beginning of the character is returned in _diff_, else _diff_ 
+ *  will be zero.
+ */
+
+HANDLE EDIT_GetStr(EDITSTATE *es, char *lp, int off, int len, int *diff)
+{
+    HANDLE hStr;
+    char *str;
+    int ch = 0, i = 0, j, tmp;
+    int ch1;
+    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_GetStr %s %d %d\n", lp, off, len);
+#endif
+
+    while (i < off)
+    {
+	i += charWidths[*(lp + ch)];
+	ch++;
+    }
+
+    /* if stepped past _off_, go back a character */
+    if (i - off)
+	i -= charWidths[*(lp + --ch)];
+    *diff = off - i;
+    ch1 = ch;
+
+    while (i < len + off)
+    {
+	i += charWidths[*(lp + ch)];
+	ch++;
+    }
+    
+    hStr = EDIT_HEAP_ALLOC(ch - ch1 + 3);
+    str = (char *)EDIT_HEAP_ADDR(hStr);
+    for (i = ch1, j = 0; i < ch; i++, j++)
+	str[j] = lp[i];
+    str[++j] = '\0';
+#ifdef DEBUG_EDIT
+    printf("EDIT_GetStr: returning %s\n", str);
+#endif
+    return hStr;
+}
+
+
+/*********************************************************************
+ *  WM_CHAR message function
+ */
+
+void EDIT_CharMsg(HWND hwnd, WORD wParam)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_CharMsg: wParam=%c\n", (char)wParam);
+#endif
+
+    switch (wParam)
+    {
+    case '\r':
+    case '\n':
+	if (!IsMultiLine())
+	    break;
+	wParam = '\n';
+	EDIT_KeyTyped(hwnd, wParam);
+	break;
+
+    default:
+	if (wParam >= 20 && wParam <= 126)
+	    EDIT_KeyTyped(hwnd, wParam);
+	break;
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_KeyTyped
+ *
+ *  Process keystrokes that produce displayable characters.
+ */
+
+void EDIT_KeyTyped(HWND hwnd, short ch)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+    char *currchar = CurrChar;
+    RECT rc;
+    BOOL FullPaint = FALSE;
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_KeyTyped: ch=%c\n", (char)ch);
+#endif
+
+    /* delete selected text (if any) */
+    if (SelMarked(es))
+	EDIT_DeleteSel(hwnd);
+
+    /* test for typing at end of maximum buffer size */
+    if (currchar == text + es->MaxTextLen)
+    {
+	NOTIFY_PARENT(hwnd, EN_ERRSPACE);
+	return;
+    }
+
+    if (*currchar == '\0')
+    {
+	/* insert a newline at end of text */
+	*currchar = '\n';
+	*(currchar + 1) = '\0';
+	EDIT_BuildTextPointers(hwnd);
+    }
+
+    /* insert the typed character */
+    if (text[es->textlen - 1] != '\0')
+    {
+	/* current text buffer is full */
+	if (es->textlen == es->MaxTextLen)
+	{
+	    /* text buffer is at maximum size */
+	    NOTIFY_PARENT(hwnd, EN_ERRSPACE);
+	    return;
+	}
+
+	/* increase the text buffer size */
+	es->textlen += GROWLENGTH;
+	/* but not above maximum size */
+	if (es->textlen > es->MaxTextLen)
+	    es->textlen = es->MaxTextLen;
+	es->hText = EDIT_HEAP_REALLOC(es->hText, es->textlen + 2);
+	if (!es->hText)
+	    NOTIFY_PARENT(hwnd, EN_ERRSPACE);
+	text = (char *)EDIT_HEAP_ADDR(es->hText);
+	text[es->textlen - 1] = '\0';
+	currchar = CurrChar;
+    }
+    /* make space for new character and put char in buffer */
+    memmove(currchar + 1, currchar, strlen(currchar) + 1);
+    *currchar = ch;
+    EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1);
+    es->TextChanged = TRUE;
+    NOTIFY_PARENT(hwnd, EN_UPDATE);
+
+    /* re-adjust textwidth, if necessary, and redraw line */
+    HideCaret(hwnd);
+    if (IsMultiLine() && es->wlines > 1)
+    {
+	es->textwidth = max(es->textwidth,
+		    EDIT_LineLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+		    (int)(EDIT_TextLine(hwnd, es->CurrLine + 1) -
+			  EDIT_TextLine(hwnd, es->CurrLine))));
+    }
+    else
+	es->textwidth = max(es->textwidth,
+			    EDIT_LineLength(es, text, strlen(text)));
+    EDIT_WriteTextLine(hwnd, NULL, es->wtop + es->WndRow);
+
+    if (ch == '\n')
+    {
+	if (es->wleft > 0)
+	    FullPaint = TRUE;
+	es->wleft = 0;
+	EDIT_BuildTextPointers(hwnd);
+	EDIT_End(hwnd);
+	EDIT_Forward(hwnd);
+
+	/* invalidate rest of window */
+	GetClientRect(hwnd, &rc);
+	if (!FullPaint)
+	    rc.top = es->WndRow * es->txtht;
+	InvalidateRect(hwnd, &rc, FALSE);
+
+	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+	ShowCaret(hwnd);
+	UpdateWindow(hwnd);
+	NOTIFY_PARENT(hwnd, EN_CHANGE);
+	return;
+    }
+
+    /* test end of window */
+    if (es->WndCol >= ClientWidth(wndPtr) - EDIT_CharWidth(es, ch))
+    {
+	/* TODO:- Word wrap to be handled here */
+
+/*	if (!(currchar == text + es->MaxTextLen - 2)) */
+	    EDIT_KeyHScroll(hwnd, SB_LINEDOWN);
+    }
+    es->WndCol += EDIT_CharWidth(es, ch);
+    es->CurrCol++;
+    SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+    ShowCaret(hwnd);
+    NOTIFY_PARENT(hwnd, EN_CHANGE);
+}
+
+
+/*********************************************************************
+ *  EDIT_CharWidth
+ *
+ *  Return the width of the given character in pixels.
+ */
+
+int EDIT_CharWidth(EDITSTATE *es, short ch)
+{
+    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+
+    return (charWidths[ch]);
+}
+
+
+/*********************************************************************
+ *  EDIT_Forward
+ *
+ *  Cursor right key: move right one character position.
+ */
+
+void EDIT_Forward(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+    char *cc = CurrChar + 1;
+
+    if (*cc == '\0')
+	return;
+
+    if (*CurrChar == '\n')
+    {
+	EDIT_Home(hwnd);
+	EDIT_Downward(hwnd);
+    }
+    else
+    {
+	es->WndCol += EDIT_CharWidth(es, *CurrChar);
+	es->CurrCol++;
+	if (es->WndCol >= ClientWidth(wndPtr))
+	    EDIT_KeyHScroll(hwnd, SB_LINEDOWN);
+    }
+}
+
+
+
+/*********************************************************************
+ *  EDIT_Downward
+ *
+ *  Cursor down key: move down one line.
+ */
+
+void EDIT_Downward(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_Downward: WndRow=%d, wtop=%d, wlines=%d\n", es->WndRow, es->wtop, es->wlines);
+#endif
+
+    if (IsMultiLine() && (es->WndRow + es->wtop + 1 < es->wlines))
+    {
+	es->CurrLine++;
+	if (es->WndRow == ClientHeight(wndPtr, es) - 1)
+	{
+	    es->WndRow++;
+	    EDIT_KeyVScrollLine(hwnd, SB_LINEDOWN);
+	}
+	else
+	    es->WndRow++;
+	EDIT_StickEnd(hwnd);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_Upward
+ *
+ *  Cursor up key: move up one line.
+ */
+
+void EDIT_Upward(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (IsMultiLine() && es->CurrLine != 0)
+    {
+	--es->CurrLine;
+	if (es->WndRow == 0)
+	{
+	    --es->WndRow;
+	    EDIT_KeyVScrollLine(hwnd, SB_LINEUP);
+	}
+	else
+	    --es->WndRow;
+	EDIT_StickEnd(hwnd);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_Backward
+ *
+ *  Cursor left key: move left one character position.
+ */
+
+void EDIT_Backward(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+
+    if (es->CurrCol)
+    {
+	--es->CurrCol;
+	es->WndCol -= EDIT_CharWidth(es, *CurrChar);
+	if (es->WndCol < 0)
+	    EDIT_KeyHScroll(hwnd, SB_LINEUP);
+    }
+    else if (IsMultiLine() && es->CurrLine != 0)
+    {
+	EDIT_Upward(hwnd);
+	EDIT_End(hwnd);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_End
+ *
+ *  End key: move to end of line.
+ */
+
+void EDIT_End(HWND hwnd)
+{
+    RECT rc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+
+    while (*CurrChar && *CurrChar != '\n')
+    {
+	es->WndCol += EDIT_CharWidth(es, *CurrChar);
+	es->CurrCol++;
+    }
+
+    if (es->WndCol >= ClientWidth(wndPtr))
+    {
+	es->wleft = es->WndCol - ClientWidth(wndPtr) + HSCROLLDIM;
+	es->WndCol -= es->wleft;
+	InvalidateRect(hwnd, NULL, FALSE);
+	UpdateWindow(hwnd);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_Home
+ *
+ *  Home key: move to beginning of line.
+ */
+
+void EDIT_Home(HWND hwnd)
+{
+    RECT rc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    es->CurrCol = es->WndCol = 0;
+    if (es->wleft != 0)
+    {
+	es->wleft = 0;
+	InvalidateRect(hwnd, NULL, FALSE);
+	UpdateWindow(hwnd);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_StickEnd
+ *
+ *  Stick the cursor to the end of the line.
+ */
+
+void EDIT_StickEnd(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char currpel;
+
+    char *cp = EDIT_TextLine(hwnd, es->CurrLine);
+    char *cp1 = strchr(cp, '\n');
+    int len = cp1 ? (int)(cp1 - cp) : 0;
+
+    es->CurrCol = min(len, es->CurrCol);
+    es->WndCol = min(EDIT_LineLength(es, cp, len) - es->wleft, es->WndCol);
+    currpel = EDIT_LineLength(es, cp, es->CurrCol);
+
+    if (es->wleft > currpel)
+    {
+	es->wleft = max(0, currpel - 20);
+	es->WndCol = currpel - es->wleft;
+	UpdateWindow(hwnd);
+    }
+    else if (currpel - es->wleft >= ClientWidth(wndPtr))
+    {
+	es->wleft = currpel - (ClientWidth(wndPtr) - 5);
+	es->WndCol = currpel - es->wleft;
+	UpdateWindow(hwnd);
+    }
+}
+
+
+/*********************************************************************
+ *  WM_KEYDOWN message function
+ */
+
+void EDIT_KeyDownMsg(HWND hwnd, WORD wParam)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_KeyDownMsg: key=%x\n", wParam);
+#endif
+
+    HideCaret(hwnd);
+    switch (wParam)
+    {
+    case VK_UP:
+	if (SelMarked(es))
+	    EDIT_ClearSel(hwnd);
+	if (IsMultiLine())
+	    EDIT_Upward(hwnd);
+	else
+	    EDIT_Backward(hwnd);
+	break;
+
+    case VK_DOWN:
+	if (SelMarked(es))
+	    EDIT_ClearSel(hwnd);
+	if (IsMultiLine())
+	    EDIT_Downward(hwnd);
+	else
+	    EDIT_Forward(hwnd);
+	break;
+
+    case VK_RIGHT:
+	if (SelMarked(es))
+	    EDIT_ClearSel(hwnd);
+	EDIT_Forward(hwnd);
+	break;
+
+    case VK_LEFT:
+	if (SelMarked(es))
+	    EDIT_ClearSel(hwnd);
+	EDIT_Backward(hwnd);
+	break;
+
+    case VK_HOME:
+	if (SelMarked(es))
+	    EDIT_ClearSel(hwnd);
+	EDIT_Home(hwnd);
+	break;
+
+    case VK_END:
+	if (SelMarked(es))
+	    EDIT_ClearSel(hwnd);
+	EDIT_End(hwnd);
+	break;
+
+    case VK_PRIOR:
+	if (IsMultiLine())
+	{
+	    if (SelMarked(es))
+		EDIT_ClearSel(hwnd);
+	    EDIT_KeyVScrollPage(hwnd, SB_PAGEUP);
+	}
+	break;
+
+    case VK_NEXT:
+	if (IsMultiLine())
+	{
+	    if (SelMarked(es))
+		EDIT_ClearSel(hwnd);
+	    EDIT_KeyVScrollPage(hwnd, SB_PAGEDOWN);
+	}
+	break;
+
+    case VK_BACK:
+	if (SelMarked(es))
+	    EDIT_DeleteSel(hwnd);
+	else
+	{
+	    if (es->CurrCol == 0 && es->CurrLine == 0)
+		break;
+	    EDIT_Backward(hwnd);
+	    EDIT_DelKey(hwnd);
+	}
+	break;
+
+    case VK_DELETE:
+	if (SelMarked(es))
+	    EDIT_DeleteSel(hwnd);
+	else
+	    EDIT_DelKey(hwnd);
+	break;
+    }
+
+    SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+    ShowCaret(hwnd);
+}
+
+
+/*********************************************************************
+ *  EDIT_KeyHScroll
+ *
+ *  Scroll text horizontally using cursor keys.
+ */
+
+void EDIT_KeyHScroll(HWND hwnd, WORD opt)
+{
+    RECT rc;
+    int hscrollpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (opt == SB_LINEDOWN)
+    {
+	es->wleft += HSCROLLDIM;
+	es->WndCol -= HSCROLLDIM;
+    }
+    else
+    {
+	if (es->wleft == 0)
+	    return;
+	if (es->wleft - HSCROLLDIM < 0)
+	{
+	    es->WndCol += es->wleft;
+	    es->wleft = 0;
+	}	    
+	else
+	{
+	    es->wleft -= HSCROLLDIM;
+	    es->WndCol += HSCROLLDIM;
+	}
+    }
+
+    InvalidateRect(hwnd, NULL, FALSE);
+    UpdateWindow(hwnd);
+
+    if (IsHScrollBar())
+    {
+	hscrollpos = EDIT_ComputeHScrollPos(hwnd);
+	SetScrollPos(hwnd, SB_HORZ, hscrollpos, TRUE);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_KeyVScrollLine
+ *
+ *  Scroll text vertically by one line using keyboard.
+ */
+
+void EDIT_KeyVScrollLine(HWND hwnd, WORD opt)
+{
+    RECT rc;
+    int y, vscrollpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (!IsMultiLine())
+	return;
+
+    if (opt == SB_LINEDOWN)
+    {
+	/* move down one line */
+	if (es->wtop + ClientHeight(wndPtr, es) >= es->wlines)
+	    return;
+	es->wtop++;
+    }
+    else
+    {
+	/* move up one line */
+	if (es->wtop == 0)
+	    return;
+	--es->wtop;
+    }
+
+    if (IsWindowVisible(hwnd))
+    {
+	/* adjust client bottom to nearest whole line */
+	GetClientRect(hwnd, &rc);
+	rc.bottom = (rc.bottom / es->txtht) * es->txtht;
+
+	if (opt == SB_LINEUP)
+	{
+	    /* move up one line (scroll window down) */
+	    ScrollWindow(hwnd, 0, es->txtht, &rc, &rc);
+	    /* write top line */
+	    EDIT_WriteTextLine(hwnd, NULL, es->wtop);
+	    es->WndRow++;
+	}
+	else
+	{
+	    /* move down one line (scroll window up) */
+	    ScrollWindow(hwnd, 0, -(es->txtht), &rc, &rc);
+	    /* write bottom line */
+	    y = (((rc.bottom - rc.top) / es->txtht) - 1);
+	    EDIT_WriteTextLine(hwnd, NULL, es->wtop + y);
+	    --es->WndRow;
+	}
+    }
+
+    /* reset the vertical scroll bar */
+    if (IsVScrollBar())
+    {
+	vscrollpos = EDIT_ComputeVScrollPos(hwnd);
+	SetScrollPos(hwnd, SB_VERT, vscrollpos, TRUE);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_KeyVScrollPage
+ *
+ *  Scroll text vertically by one page using keyboard.
+ */
+
+void EDIT_KeyVScrollPage(HWND hwnd, WORD opt)
+{
+    RECT rc;
+    int vscrollpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (IsMultiLine())
+    {
+	if (opt == SB_PAGEUP)
+	{
+	    if (es->wtop)
+		es->wtop -= ClientHeight(wndPtr, es);
+	}
+	else
+	{
+	    if (es->wtop + ClientHeight(wndPtr, es) < es->wlines)
+	    {
+		es->wtop += ClientHeight(wndPtr, es);
+		if (es->wtop > es->wlines - ClientHeight(wndPtr, es))
+		    es->wtop = es->wlines - ClientHeight(wndPtr, es);
+	    }
+	}
+	if (es->wtop < 0)
+	    es->wtop = 0;
+
+	es->CurrLine = es->wtop + es->WndRow;
+	EDIT_StickEnd(hwnd);
+	InvalidateRect(hwnd, NULL, TRUE);
+	UpdateWindow(hwnd);
+
+	/* reset the vertical scroll bar */
+	if (IsVScrollBar())
+	{
+	    vscrollpos = EDIT_ComputeVScrollPos(hwnd);
+	    SetScrollPos(hwnd, SB_VERT, vscrollpos, TRUE);
+	}
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_KeyVScrollDoc
+ *
+ *  Scroll text to top and bottom of document using keyboard.
+ */
+
+void EDIT_KeyVScrollDoc(HWND hwnd, WORD opt)
+{
+    RECT rc;
+    int vscrollpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (!IsMultiLine())
+	return;
+
+    if (opt == SB_TOP)
+	es->wtop = es->wleft = 0;
+    else if (es->wtop + ClientHeight(wndPtr, es) < es->wlines)
+    {
+	es->wtop = es->wlines - ClientHeight(wndPtr, es);
+	es->wleft = 0;
+    }
+
+    es->CurrLine = es->wlines;
+    es->WndRow = es->wlines - es->wtop;
+    EDIT_End(hwnd);
+    InvalidateRect(hwnd, NULL, TRUE);
+    UpdateWindow(hwnd);
+
+    /* reset the vertical scroll bar */
+    if (IsVScrollBar())
+    {
+	vscrollpos = EDIT_ComputeVScrollPos(hwnd);
+	SetScrollPos(hwnd, SB_VERT, vscrollpos, TRUE);
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_ComputeVScrollPos
+ *
+ *  Compute the vertical scroll bar position from the window
+ *  position and text width.
+ */
+
+int EDIT_ComputeVScrollPos(HWND hwnd)
+{
+    int vscrollpos;
+    short minpos, maxpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    GetScrollRange(hwnd, SB_VERT, &minpos, &maxpos);
+
+    if (es->wlines > ClientHeight(wndPtr, es))
+	vscrollpos = (double)(es->wtop) / (double)(es->wlines - 
+		     ClientHeight(wndPtr, es)) * (maxpos - minpos);
+    else
+	vscrollpos = minpos;
+
+    return vscrollpos;
+}
+    
+
+/*********************************************************************
+ *  EDIT_ComputeHScrollPos
+ *
+ *  Compute the horizontal scroll bar position from the window
+ *  position and text width.
+ */
+
+int EDIT_ComputeHScrollPos(HWND hwnd)
+{
+    int hscrollpos;
+    short minpos, maxpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    GetScrollRange(hwnd, SB_HORZ, &minpos, &maxpos);
+
+    if (es->textwidth > ClientWidth(wndPtr))
+	hscrollpos = (double)(es->wleft) / (double)(es->textwidth - 
+		     ClientWidth(wndPtr)) * (maxpos - minpos);
+    else
+	hscrollpos = minpos;
+
+    return hscrollpos;
+}
+
+
+/*********************************************************************
+ *  EDIT_DelKey
+ *
+ *  Delete character to right of cursor.
+ */
+
+void EDIT_DelKey(HWND hwnd)
+{
+    RECT rc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *currchar = CurrChar;
+    BOOL repaint = *currchar == '\n';
+
+    if (IsMultiLine() && *currchar == '\n' && *(currchar + 1) == '\0')
+	return;
+    strcpy(currchar, currchar + 1);
+    NOTIFY_PARENT(hwnd, EN_UPDATE);
+    
+    if (repaint)
+    {
+	EDIT_BuildTextPointers(hwnd);
+	GetClientRect(hwnd, &rc);
+	rc.top = es->WndRow * es->txtht;
+	InvalidateRect(hwnd, &rc, FALSE);
+	UpdateWindow(hwnd);
+    }
+    else
+    {
+	EDIT_ModTextPointers(hwnd, es->CurrLine + 1, -1);
+	EDIT_WriteTextLine(hwnd, NULL, es->WndRow + es->wtop);
+    }
+
+    es->TextChanged = TRUE;
+    NOTIFY_PARENT(hwnd, EN_CHANGE);
+}
+
+/*********************************************************************
+ *  WM_VSCROLL message function
+ */
+
+void EDIT_VScrollMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (IsMultiLine())
+    {
+	HideCaret(hwnd);
+
+	switch (wParam)
+	{
+	case SB_LINEUP:
+	case SB_LINEDOWN:
+	    EDIT_VScrollLine(hwnd, wParam);
+	    break;
+
+	case SB_PAGEUP:
+	case SB_PAGEDOWN:
+	    EDIT_VScrollPage(hwnd, wParam);
+	    break;
+	}
+    }
+    
+    SetCaretPos(es->WndCol, es->WndRow);
+    ShowCaret(hwnd);
+}
+
+
+/*********************************************************************
+ *  EDIT_VScrollLine
+ *
+ *  Scroll text vertically by one line using scrollbars.
+ */
+
+void EDIT_VScrollLine(HWND hwnd, WORD opt)
+{
+    RECT rc;
+    int y;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_VScrollLine: direction=%d\n", opt);
+#endif
+
+    if (opt == SB_LINEDOWN)
+    {
+	/* move down one line */
+	if (es->wtop + ClientHeight(wndPtr, es) >= es->wlines)
+	    return;
+	es->wtop++;
+	printf("Scroll line down: wtop=%d\n", es->wtop);
+    }
+    else
+    {
+	/* move up one line */
+	if (es->wtop == 0)
+	    return;
+	--es->wtop;
+	printf("Scroll line up: wtop=%d\n", es->wtop);
+    }
+
+    if (IsWindowVisible(hwnd))
+    {
+	/* adjust client bottom to nearest whole line */
+	GetClientRect(hwnd, &rc);
+	rc.bottom = (rc.bottom / es->txtht) * es->txtht;
+
+	if (opt == SB_LINEUP)
+	{
+	    /* move up one line (scroll window down) */
+	    ScrollWindow(hwnd, 0, es->txtht, &rc, &rc);
+	    /* write top line */
+	    EDIT_WriteTextLine(hwnd, NULL, es->wtop);
+	    es->WndRow++;
+	}
+	else
+	{
+	    /* move down one line (scroll window up) */
+	    ScrollWindow(hwnd, 0, -(es->txtht), &rc, &rc);
+	    /* write bottom line */
+	    y = ((rc.bottom - rc.top / es->txtht) - 1);
+	    EDIT_WriteTextLine(hwnd, NULL, es->wtop + y);
+	    --es->WndRow;
+	}
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_VScrollPage
+ *
+ *  Scroll text vertically by one page using keyboard.
+ */
+
+void EDIT_VScrollPage(HWND hwnd, WORD opt)
+{
+    RECT rc;
+    int vscrollpos;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (opt == SB_PAGEUP)
+    {
+	if (es->wtop)
+	    es->wtop -= ClientHeight(wndPtr, es);
+    }
+    else
+    {
+	if (es->wtop + ClientHeight(wndPtr, es) < es->wlines)
+	{
+	    es->wtop += ClientHeight(wndPtr, es);
+	    if (es->wtop > es->wlines - ClientHeight(wndPtr, es))
+		es->wtop = es->wlines - ClientHeight(wndPtr, es);
+	}
+    }
+    if (es->wtop < 0)
+	es->wtop = 0;
+    
+    InvalidateRect(hwnd, NULL, TRUE);
+    UpdateWindow(hwnd);
+
+    /* reset the vertical scroll bar */
+    if (IsVScrollBar())
+    {
+	vscrollpos = EDIT_ComputeVScrollPos(hwnd);
+	SetScrollPos(hwnd, SB_VERT, vscrollpos, TRUE);
+    }
+}
+
+
+/*********************************************************************
+ *  WM_HSCROLL message function
+ */
+
+void EDIT_HScrollMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    switch (wParam)
+    {
+    case SB_LINEUP:
+    case SB_LINEDOWN:
+	HideCaret(hwnd);
+
+	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+	ShowCaret(hwnd);
+	break;
+    }
+}
+
+
+/*********************************************************************
+ *  WM_SIZE message function
+ */
+
+void EDIT_SizeMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+    RECT rc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (wParam != SIZE_MAXIMIZED && wParam != SIZE_RESTORED) return;
+
+    InvalidateRect(hwnd, NULL, TRUE);
+    es->PaintBkgd = TRUE;
+    UpdateWindow(hwnd);
+}
+
+
+/*********************************************************************
+ *  WM_LBUTTONDOWN message function
+ */
+
+void EDIT_LButtonDownMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+    char *cp, *cp1;
+    int len;
+    BOOL end = FALSE;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (SelMarked(es))
+	EDIT_ClearSel(hwnd);
+
+    es->WndRow = HIWORD(lParam) / es->txtht;
+    if (es->WndRow > es->wlines - es->wtop - 1)
+    {
+	if (es->wlines)
+	    es->WndRow = es->wlines - es->wtop - 1;
+	else
+	    es->WndRow = 0;
+	end = TRUE;
+    }
+    es->CurrLine = es->wtop + es->WndRow;
+
+    cp = EDIT_TextLine(hwnd, es->CurrLine);
+    cp1 = strchr(cp, '\n');
+    len = cp1 ? (int)(cp1 - cp) : 0;
+
+    es->WndCol = LOWORD(lParam);
+    if (es->WndCol > EDIT_LineLength(es, cp, len) - es->wleft || end)
+	es->WndCol = EDIT_LineLength(es, cp, len) - es->wleft;
+    es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
+
+    ButtonDown = TRUE;
+    ButtonRow = es->CurrLine;
+    ButtonCol = es->CurrCol;
+}
+
+
+/*********************************************************************
+ *  WM_MOUSEMOVE message function
+ */
+
+void EDIT_MouseMoveMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+    if (wParam != MK_LBUTTON)
+	return;
+
+    if (ButtonDown)
+    {
+	EDIT_SetAnchor(hwnd, ButtonRow, ButtonCol);
+	TextMarking = TRUE;
+	ButtonDown = FALSE;
+    }
+
+    if (TextMarking)
+	EDIT_ExtendSel(hwnd, LOWORD(lParam), HIWORD(lParam));
+}
+
+
+/*********************************************************************
+ *  EDIT_PixelToChar
+ *
+ *  Convert a pixel offset in the given row to a character offset,
+ *  adjusting the pixel offset to the nearest whole character if
+ *  necessary.
+ */
+
+int EDIT_PixelToChar(HWND hwnd, int row, int *pixel)
+{
+    int ch = 0, i = 0;
+    char *text;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_PixelToChar: row=%d, pixel=%d\n", row, *pixel);
+#endif
+
+    text = EDIT_TextLine(hwnd, row);
+    while (i < *pixel)
+    {
+	i += charWidths[*(text + ch)];
+	ch++;
+    }
+
+    /* if stepped past _pixel_, go back a character */
+    if (i - *pixel)
+	i -= charWidths[*(text + ch)];
+    *pixel = i;
+    return ch;
+}
+
+
+/*********************************************************************
+ *  WM_SETTEXT message function
+ */
+
+LONG EDIT_SetTextMsg(HWND hwnd, LONG lParam)
+{
+    int len;
+    char *text;
+    RECT rc;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (strlen((char *)lParam) <= es->MaxTextLen)
+    {
+	len = strlen((char *)lParam);
+	EDIT_ClearText(hwnd);
+	es->textlen = len;
+	es->hText = EDIT_HEAP_REALLOC(es->hText, len + 3);
+	text = EDIT_HEAP_ADDR(es->hText);
+	strcpy(text, (char *)lParam);
+	text[len] = '\n';
+	text[len + 1] = '\0';
+	text[len + 2] = '\0';
+	EDIT_BuildTextPointers(hwnd);
+	InvalidateRect(hwnd, NULL, TRUE);
+	es->PaintBkgd = TRUE;
+	es->TextChanged = TRUE;
+	return 0L;
+    }
+    else
+	return EN_ERRSPACE;
+}
+
+
+/*********************************************************************
+ *  EDIT_ClearText
+ *
+ *  Clear text from text buffer.
+ */
+
+void EDIT_ClearText(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    unsigned int blen = EditBufLen(wndPtr) + 2;
+    char *text;
+
+    es->hText = EDIT_HEAP_REALLOC(es->hText, blen);
+    text = EDIT_HEAP_ADDR(es->hText);
+    memset(text, 0, blen);
+    es->textlen = 0;
+    es->wlines = 0;
+    es->CurrLine = es->CurrCol = 0;
+    es->WndRow = es->WndCol = 0;
+    es->wleft = es->wtop = 0;
+    es->textwidth = 0;
+    es->TextChanged = FALSE;
+    EDIT_ClearTextPointers(hwnd);
+}
+
+
+/*********************************************************************
+ *  EM_SETSEL message function
+ */
+
+void EDIT_SetSelMsg(HWND hwnd, LONG lParam)
+{
+    int so, eo;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if ((short)(lParam) < 0 || (short)(lParam >> 16) < 0)
+	return;
+    so = LOWORD(lParam);
+    eo = HIWORD(lParam);
+    if (so > eo)
+	swap(&so, &eo);
+
+    EDIT_GetLineCol(hwnd, so, &(es->SelBegLine), &(es->SelBegCol));
+    EDIT_GetLineCol(hwnd, eo, &(es->SelEndLine), &(es->SelEndCol));
+
+    es->CurrLine = es->SelEndLine;
+    es->CurrCol = es->SelEndCol;
+    es->WndRow = es->SelEndLine - es->wtop;
+    if (es->WndRow < 0)
+    {
+	es->wtop = es->SelEndLine;
+	es->WndRow = 0;
+    }
+    es->WndCol = EDIT_LineLength(es, EDIT_TextLine(hwnd, es->SelEndLine), 
+				 es->SelEndCol) - es->wleft;
+
+    InvalidateRect(hwnd, NULL, TRUE);
+    UpdateWindow(hwnd);
+}
+
+
+/*********************************************************************
+ *  EDIT_GetLineCol
+ *
+ *  Return line and column in text buffer from character offset.
+ */
+
+void EDIT_GetLineCol(HWND hwnd, int off, int *line, int *col)
+{
+    int lineno;
+    char *cp, *cp1;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+
+    if (off > strlen(text)) off = strlen(text);
+    for (lineno = 0; lineno < es->wlines; lineno++)
+    {
+	cp = text + *(textPtrs + lineno);
+	if (off == (int)(cp - text))
+	{
+	    *line = lineno;
+	    *col = 0;
+	    return;
+	}
+	if (off < (int)(cp - text))
+	    break;
+	cp1 = cp;
+    }
+    *line = lineno - 1;
+    *col = off - (int)(cp1 - text);
+    if (*(text + *col) == '\0')
+	(*col)--;
+}
+
+
+/*********************************************************************
+ *  EDIT_DeleteSel
+ *
+ *  Delete the current selected text (if any)
+ */
+
+void EDIT_DeleteSel(HWND hwnd)
+{
+    char *bbl, *bel;
+    int len;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+
+    if (SelMarked(es))
+    {
+	bbl = EDIT_TextLine(hwnd, es->SelBegLine) + es->SelBegCol;
+	bel = EDIT_TextLine(hwnd, es->SelEndLine) + es->SelEndCol;
+	len = (int)(bel - bbl);
+	es->TextChanged = TRUE;
+	strcpy(bbl, bel);
+
+	es->CurrLine = es->SelBegLine;
+	es->CurrCol = es->SelBegCol;
+	es->WndRow = es->SelBegLine - es->wtop;
+	if (es->WndRow < 0)
+	{
+	    es->wtop = es->SelBegLine;
+	    es->WndRow = 0;
+	}
+	es->WndCol = EDIT_LineLength(es, bbl - es->SelBegCol, 
+				     es->SelBegCol) - es->wleft;
+
+	EDIT_BuildTextPointers(hwnd);
+	es->PaintBkgd = TRUE;
+	EDIT_ClearSel(hwnd);
+    }
+}
+    
+
+/*********************************************************************
+ *  EDIT_ClearSel
+ *
+ *  Clear the current selection.
+ */
+
+void EDIT_ClearSel(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    es->SelBegLine = es->SelBegCol = -1;
+    es->SelEndLine = es->SelEndCol = -1;
+
+    InvalidateRect(hwnd, NULL, TRUE);
+    UpdateWindow(hwnd);
+}
+
+
+/*********************************************************************
+ *  EDIT_TextLineNumber
+ *
+ *  Return the line number in the text buffer of the supplied
+ *  character pointer.
+ */
+
+int EDIT_TextLineNumber(HWND hwnd, char *lp)
+{
+    int lineno;
+    char *cp;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    char *text = (char *)EDIT_HEAP_ADDR(es->hText);
+    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+
+    for (lineno = 0; lineno < es->wlines; lineno++)
+    {
+	cp = text + *(textPtrs + lineno);
+	if (cp == lp)
+	    return lineno;
+	if (cp > lp)
+	    break;
+    }
+    return lineno - 1;
+}
+
+
+/*********************************************************************
+ *  EDIT_SetAnchor
+ *
+ *  Set down anchor for text marking.
+ */
+
+void EDIT_SetAnchor(HWND hwnd, int row, int col)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    EDIT_ClearSel(hwnd);
+    es->SelBegLine = es->SelEndLine = row;
+    es->SelBegCol = es->SelEndCol = col;
+    InvalidateRect(hwnd, NULL, FALSE);
+    UpdateWindow(hwnd);
+}
+
+
+/*********************************************************************
+ *  EDIT_ExtendSel
+ *
+ *  Extend selection to the given screen co-ordinates.
+ */
+
+void EDIT_ExtendSel(HWND hwnd, int x, int y)
+{
+    int bbl, bel;
+    int ptop, pbot;
+    char *cp, *cp1;
+    int len;
+    BOOL end = FALSE;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+#ifdef DEBUG_EDIT
+    printf("EDIT_ExtendSel: x=%d, y=%d\n", x, y);
+#endif
+
+    ptop = min(es->SelBegLine, es->SelEndLine);
+    pbot = max(es->SelBegLine, es->SelEndLine);
+    cp = EDIT_TextLine(hwnd, es->wtop + y / es->txtht);
+    cp1 = strchr(cp, '\n');
+    len = cp1 ? (int)(cp1 - cp) : 0;
+
+    es->WndRow = y / es->txtht;
+    if (es->WndRow > es->wlines - es->wtop - 1)
+    {
+	if (es->wlines)
+	    es->WndRow = es->wlines - es->wtop - 1;
+	else
+	    es->WndRow = 0;
+	end = TRUE;
+    }
+    es->CurrLine = es->wtop + es->WndRow;
+    es->SelEndLine = es->CurrLine;
+
+    es->WndCol = x;
+    if (es->WndCol > EDIT_LineLength(es, cp, len) - es->wleft || end)
+	es->WndCol = EDIT_LineLength(es, cp, len) - es->wleft;
+    es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
+    es->SelEndCol = es->CurrCol;
+
+    bbl = min(es->SelBegLine, es->SelEndLine);
+    bel = max(es->SelBegLine, es->SelEndLine);
+    while (ptop < bbl)
+    {
+	EDIT_WriteTextLine(hwnd, NULL, ptop);
+	ptop++;
+    }
+    for (y = bbl; y <= bel; y++)
+	EDIT_WriteTextLine(hwnd, NULL, y);
+    while (pbot > bel)
+    {
+	EDIT_WriteTextLine(hwnd, NULL, pbot);
+	--pbot;
+    }
+}
+
+
+/*********************************************************************
+ *  EDIT_StopMarking
+ *
+ *  Stop text marking (selection).
+ */
+
+void EDIT_StopMarking(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    TextMarking = FALSE;
+    if (es->SelBegLine > es->SelEndLine)
+    {
+	swap(&(es->SelBegLine), &(es->SelEndLine));
+	swap(&(es->SelBegCol), &(es->SelEndCol));
+    }
+    if (es->SelBegLine == es->SelEndLine && es->SelBegCol > es->SelEndCol)
+	swap(&(es->SelBegCol), &(es->SelEndCol));
+}
+
+
+/*********************************************************************
+ *  EM_GETLINE message function
+ */
+
+LONG EDIT_GetLineMsg(HWND hwnd, WORD wParam, LONG lParam)
+{
+    char *cp, *cp1;
+    int len;
+    char *buffer = (char *)lParam;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    cp = EDIT_TextLine(hwnd, wParam);
+    cp1 = EDIT_TextLine(hwnd, wParam + 1);
+    len = min((int)(cp1 - cp), (WORD)(*buffer));
+    strncpy(buffer, cp, len);
+
+    return (LONG)len;
+}
+
+
+/*********************************************************************
+ *  EM_GETSEL message function
+ */
+
+LONG EDIT_GetSelMsg(HWND hwnd)
+{
+    int so, eo;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+
+    so = *(textPtrs + es->SelBegLine) + es->SelBegCol;
+    eo = *(textPtrs + es->SelEndLine) + es->SelEndCol;
+
+    return MAKELONG(so, eo);
+}
+
+
+/*********************************************************************
+ *  EM_LINEFROMCHAR message function
+ */
+
+LONG EDIT_LineFromCharMsg(HWND hwnd, WORD wParam)
+{
+    int row, col;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+
+    if (wParam == 0xffff)   /* really -1 */
+	return (LONG)(es->SelBegLine);
+    else
+	EDIT_GetLineCol(hwnd, wParam, &row, &col);
+
+    return (LONG)row;
+}
+
+
+/*********************************************************************
+ *  EM_LINEINDEX message function
+ */
+
+LONG EDIT_LineIndexMsg(HWND hwnd, WORD wParam)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+
+    if (wParam == 0xffff)    /* really -1 */
+	wParam = es->CurrLine;
+
+    return (LONG)(*(textPtrs + wParam));
+}
+
+
+/*********************************************************************
+ *  Utility functions
+ */
+
+void swap(int *a, int *b)
+{
+    int x;
+
+    x = *a;
+    *a = *b;
+    *b = x;
+}
+
diff --git a/controls/listbox.c b/controls/listbox.c
index a20eea9..70a6c54 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1260,3 +1260,28 @@
 }
 
 
+/************************************************************************
+ * 					DlgDirSelect			[USER.99]
+ */
+BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox)
+{
+	printf("DlgDirSelect(%04X, '%s', %d) \n",	hDlg, lpStr, nIDLBox);
+}
+
+
+/************************************************************************
+ * 					DlgDirList				[USER.100]
+ */
+int DlgDirList(HWND hDlg, LPSTR lpPathSpec, 
+	int nIDLBox, int nIDStat, WORD wType)
+{
+	HWND	hWnd;
+	printf("DlgDirList(%04X, '%s', %d, %d, %04X) \n",
+			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
+	hWnd = GetDlgItem(hDlg, nIDLBox);
+	ListBoxResetContent(hWnd);
+	return ListBoxDirectory(hWnd, wType, lpPathSpec);
+}
+
+
+
diff --git a/controls/menu.c b/controls/menu.c
index 9ab0366..7a79e9f 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -29,7 +29,8 @@
 
 LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
 LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
-void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
+void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, 
+		    BOOL suppress_draw);
 BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
 void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
 void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
@@ -39,7 +40,7 @@
 void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex);
 LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet);
 LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet);
-BOOL ActivateMenuFocus(HWND hWnd);
+BOOL ActivateMenuBarFocus(HWND hWnd);
 BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu);
 void PopupMenuCalcSize(HWND hwnd);
 void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
@@ -87,6 +88,9 @@
 			hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
 		if (hStdMnArrow == (HBITMAP)NULL) 
 			hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
+#ifdef DEBUG_MENU
+		printf("PopupMenu End of WM_CREATE !\n");
+#endif
 		return 0;
 	case WM_DESTROY:
 		lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
@@ -137,6 +141,7 @@
 #endif
 			if (lppop->SysFlag) MenuHasFocus = FALSE;
 			SetFocus(lppop->hWndPrev);
+			if (GetCapture() != 0) ReleaseCapture(); 
 			break;
 			}
 		lppop->FocusedItem = (WORD)-1;
@@ -271,55 +276,61 @@
 		printf("PopupMenuWndProc hWnd=%04X WM_CHAR wParam=%04X !\n", hwnd, wParam);
 #endif
 		if (lParam < 0L) break;
+		hwnd = GetFocus();
 		lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
 		if (lppop == NULL) break;
-		if (wParam == VK_ESCAPE) {
-			if (lppop->BarFlag) {
+		switch(wParam) {
+			case VK_ESCAPE:
+				if (lppop->BarFlag) {
 #ifdef DEBUG_MENU
-				printf("VK_ESCAPE // Unselect all MenuBar's Items !\n");
+					printf("VK_ESCAPE // Unselect all MenuBar's Items !\n");
 #endif
-				if (lppop->FocusedItem != (WORD)-1)
-					MenuItemSelect(hwnd, lppop, -1);
-				}
-			if (lppop->SysFlag) {
+					if (lppop->FocusedItem != (WORD)-1)
+						MenuItemSelect(hwnd, lppop, -1);
+					}
+				if (lppop->SysFlag) {
 #ifdef DEBUG_MENU
-				printf("VK_ESCAPE // SysMenu !\n");
+					printf("VK_ESCAPE // SysMenu !\n");
 #endif
-				ShowWindow(hwnd, SW_HIDE);
+					ShowWindow(hwnd, SW_HIDE);
+					break;
+					}
+				if (lppop->hWndParent != 0) {
+#ifdef DEBUG_MENU
+					printf("VK_ESCAPE // Hide only SubPopup !\n");
+#endif
+					lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr);
+					if (lppop2 == NULL) break;
+					HideAllSubPopupMenu(lppop2);
+					break;
+					}
+				else {
+#ifdef DEBUG_MENU
+					printf("VK_ESCAPE // Hide Root Popup !\n");
+#endif
+					ShowWindow(hwnd, SW_HIDE);
+					MenuHasFocus = FALSE;
+					}
 				break;
-				}
-			if (lppop->hWndParent != 0) {
-#ifdef DEBUG_MENU
-				printf("VK_ESCAPE // Hide only SubPopup !\n");
-#endif
-				lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr);
-				if (lppop2 == NULL) break;
-				HideAllSubPopupMenu(lppop2);
+			default:
+				if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
+				lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet);
+				if (lpitem != NULL) {
+				    printf("ShortKey Found  wRet=%d !\n", wRet);
+					MenuItemSelect(hwnd, lppop, wRet);
+					lppop->FocusedItem = wRet;
+					goto ProceedSPACE;
+					}
+			    printf("ShortKey Not Found wParam=%04X wRet=%d lpitem=%08X !\n",
+					wParam, wRet, lpitem);
+				if (lppop->hWndParent != (HWND)NULL)
+					SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam, 
+						MAKELONG(0, 0));
+				else 
+					SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam, 
+						MAKELONG(0, 0));
 				break;
-				}
-			else {
-#ifdef DEBUG_MENU
-				printf("VK_ESCAPE // Hide Root Popup !\n");
-#endif
-				ShowWindow(hwnd, SW_HIDE);
-				MenuHasFocus = FALSE;
-				}
-			break;
 			}
-		if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
-		lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet);
-		if (lpitem != NULL) {
-		    printf("Found  wRet=%d !\n", wRet);
-			MenuItemSelect(hwnd, lppop, wRet);
-			lppop->FocusedItem = wRet;
-			goto ProceedSPACE;
-			}
-		if (lppop->hWndParent != (HWND)NULL)
-			SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam, 
-				MAKELONG(0, 0));
-		else 
-			SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam, 
-				MAKELONG(0, 0));
 		break;
 	case WM_PAINT:
 #ifdef DEBUG_MENU
@@ -352,7 +363,6 @@
 		lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
 		if (lppop2 == NULL) return FALSE;
 		lppop2->hWndParent = hWnd;
-		lppop2->hWndPrev = GetFocus();
 		GetClientRect(hWnd, &rect);
 		if (lppop->BarFlag) {
 			GetWindowRect(hWnd, &rect);
@@ -398,9 +408,11 @@
 	LPPOPUPMENU lppop2;
 	if (lppop == NULL) return;
 	lpitem = MenuFindItem(lppop, x, y, &wRet);
+	printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n", 
+											hWnd, x, y, wRet, lpitem);
 #ifdef DEBUG_MENU
-	printf("MenuButtonDown // x=%d y=%d // wRet=%d lpitem=%08X !\n", 
-												x, y, wRet, lpitem);
+	printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n", 
+											hWnd, x, y, wRet, lpitem);
 #endif
 	if (lpitem != NULL) {
 		MenuItemSelect(hWnd, lppop, wRet);
@@ -409,7 +421,6 @@
 			lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
 			if (lppop2 == NULL) return;
 			lppop2->hWndParent = hWnd;
-			lppop2->hWndPrev = GetFocus();
 			if (lppop->BarFlag) {
 				GetWindowRect(hWnd, &rect);
 				y = rect.top + lppop->rect.bottom;
@@ -517,7 +528,6 @@
 					}
 				if (lppop->BarFlag) {
 					lppop2->hWndParent = hWnd;
-					lppop2->hWndPrev = GetFocus();
 					GetWindowRect(hWnd, &rect);
 					rect.top += lppop->rect.bottom;
 					TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
@@ -534,7 +544,6 @@
 
 void ResetHiliteFlags(LPPOPUPMENU lppop)
 {
-	HDC		hDC;
 	LPMENUITEM lpitem;
 	int		i;
 	if (lppop == NULL) return;
@@ -731,6 +740,7 @@
 			FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH));
 		InflateRect(&rect3, 0, -2);
 		rect3.left += lppop->CheckWidth;
+		hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
 		if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) {
 			DrawText(hDC, lpitem->item_text, x, &rect3, 
 				DT_LEFT | DT_VCENTER | DT_SINGLELINE);
@@ -740,6 +750,7 @@
 	    else
 			DrawText(hDC, lpitem->item_text, -1, &rect3, 
 				DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+		SelectObject(hDC, hOldPen);
 		SetTextColor(hDC, OldTextColor);
 		SetBkMode(hDC, OldBkMode);
 		SelectObject(hDC, hOldFont);
@@ -764,7 +775,8 @@
 
 
 
-void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
+void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, 
+		    BOOL suppress_draw)
 {
 	LPMENUITEM 	lpitem;
 	HBRUSH 	hBrush;
@@ -782,7 +794,11 @@
 	printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
 #endif
 	MenuBarCalcSize(hDC, lprect, lppop);
+	if (suppress_draw)
+	    return;
+	
 	hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
+	hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
 	hBrush = GetStockObject(WHITE_BRUSH);
 	CopyRect(&rect, lprect);
 	FillRect(hDC, &rect, hBrush);
@@ -850,6 +866,7 @@
 		lpitem = (LPMENUITEM)lpitem->next;
 		}
 EndOfPaint:
+	SelectObject(hDC, hOldPen);
 	SelectObject(hDC, hOldFont);
 } 
 
@@ -886,12 +903,13 @@
 	LPMENUITEM 	lpitem;
 	UINT  	i;
 	if (lppop == NULL) return NULL;
+
 	if (lppop->nItems == 0) return NULL;
 	lpitem = lppop->firstItem;
 	for(i = 0; i < lppop->nItems; i++) {
 		if (lpitem == NULL) return NULL;
 #ifdef DEBUG_MENUFINDITEM
-		printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n",
+		printf("FindItemBySelKey // key=%04X lpitem->sel_key=%04X\n",
 										key, lpitem->sel_key);
 #endif
 		if (key == lpitem->sel_key) {
@@ -1289,6 +1307,7 @@
 	menu = (LPPOPUPMENU) GlobalLock(hMenu);
 	if (menu == NULL) return FALSE;
 	lpitem = FindMenuItem(hMenu, nPos, wFlags);
+	if (lpitem == NULL) lpitem = menu->firstItem;
 	hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
 	if (hNewItem == 0) {
 		GlobalUnlock(hMenu);
@@ -1303,21 +1322,31 @@
 	lpitem2->item_flags = wFlags;
 	lpitem2->item_id = wItemID;
 	if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
-			MF_MENUBREAK | MF_SEPARATOR))) {
-	        lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1);
-		strcpy(lpitem2->item_text, lpNewItem);
+		MF_MENUBREAK | MF_SEPARATOR))) {
+/*		lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); */
+		lpitem2->item_text = GlobalLock(GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1));
+		if (lpitem2->item_text != NULL)
+			strcpy(lpitem2->item_text, lpNewItem);
+		else {
+			printf("InsertMenu // Bad Alloc !\n");
+			return FALSE;
+			}
 		lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
 		}
 	else {
-	        lpitem2->item_text = lpNewItem;
-                }
-	
-	lpitem2->prev = lpitem;
-	if (lpitem->next != NULL)
-		lpitem2->next = lpitem->next;
-	else
+		lpitem2->item_text = lpNewItem;
+		}
+	if (lpitem == NULL) {
+		menu->firstItem = lpitem2;
+		lpitem2->prev = NULL;
 		lpitem2->next = NULL;
-	lpitem->next = lpitem2;
+		}
+	else {
+		lpitem2->prev = lpitem;
+		lpitem2->next = lpitem->next;
+		if (lpitem2->next != NULL) lpitem2->next->prev = lpitem2;
+		lpitem->next = lpitem2;
+		}
 	lpitem2->child = NULL;
 	lpitem2->parent = NULL;
 	menu->nItems++;
@@ -1338,10 +1367,10 @@
 #ifdef DEBUG_MENU
 	if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
 		printf("AppendMenu (%04X, %04X, %04X, '%s') !\n",
-			hMenu, wFlags, wItemID, lpNewItem);
+					hMenu, wFlags, wItemID, lpNewItem);
 	else
 		printf("AppendMenu (%04X, %04X, %04X, %08X) !\n",
-			hMenu, wFlags, wItemID, lpNewItem);
+					hMenu, wFlags, wItemID, lpNewItem);
 #endif
 	menu = (LPPOPUPMENU) GlobalLock(hMenu);
 	if (menu == NULL) return FALSE;
@@ -1365,15 +1394,20 @@
 	lpitem2->item_flags = wFlags;
 	lpitem2->item_id = wItemID;
 	if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
-			MF_MENUBREAK | MF_SEPARATOR))) {
-	        lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1);
-		strcpy(lpitem2->item_text, lpNewItem);
+		MF_MENUBREAK | MF_SEPARATOR))) {
+/*        lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); */
+		lpitem2->item_text = GlobalLock(GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1));
+		if (lpitem2->item_text != NULL)
+			strcpy(lpitem2->item_text, lpNewItem);
+		else {
+			printf("AppendMenu // Bad Alloc !\n");
+			return FALSE;
+			}
 		lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
 		}
 	else {
-	        lpitem2->item_text = lpNewItem;
-                }
-	
+		lpitem2->item_text = lpNewItem;
+		}
 	if (lpitem == NULL)
 		menu->firstItem = lpitem2;
 	else
@@ -1411,10 +1445,10 @@
 			lpitem->prev->next = lpitem->next;
 			lpitem->next->prev = lpitem->prev;
 			if (!(lpitem->item_flags & 
-			      (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
-			       MF_MENUBREAK | MF_SEPARATOR))) {
-			        GlobalFree(lpitem->item_text);
-			        }
+				(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
+				MF_MENUBREAK | MF_SEPARATOR))) {
+				GlobalFree((HANDLE)lpitem->item_text);
+				}
 			GlobalFree(lpitem);
 			GlobalUnlock(hMenu);
 			return TRUE;
@@ -1433,42 +1467,34 @@
  */
 BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags)
 {
-    LPPOPUPMENU	menu;
-    LPMENUITEM 	lpitem;
-    int		i;
+	LPPOPUPMENU	menu;
+	LPMENUITEM 	lpitem;
+	int		i;
 #ifdef DEBUG_MENU
-    printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
+	printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
 #endif
-    menu = (LPPOPUPMENU) GlobalLock(hMenu);
-    if (menu == NULL) 
-    {
+	menu = (LPPOPUPMENU) GlobalLock(hMenu);
+	if (menu == NULL) {
+		GlobalUnlock(hMenu);
+		return FALSE;
+		}
+	lpitem = FindMenuItem(hMenu, nPos, wFlags);
+	if (lpitem != NULL) {
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) 
+			DestroyMenu((HMENU)lpitem->item_id);
+		if (!(lpitem->item_flags & 
+			(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
+			MF_MENUBREAK | MF_SEPARATOR))) {
+			GlobalFree((HANDLE)lpitem->item_text);
+			}
+		if (lpitem->prev) lpitem->prev->next = lpitem->next;
+		if (lpitem->next) lpitem->next->prev = lpitem->prev;
+		GlobalFree(lpitem);
+		GlobalUnlock(hMenu);
+		return TRUE;
+		}
 	GlobalUnlock(hMenu);
 	return FALSE;
-    }
-	
-    lpitem = FindMenuItem(hMenu, nPos, wFlags);
-    if (lpitem != NULL)
-    {
-	if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) 
-	    DestroyMenu((HMENU)lpitem->item_id);
-
-	if (!(lpitem->item_flags & 
-	      (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
-	       MF_MENUBREAK | MF_SEPARATOR))) 
-	{
-	    GlobalFree(lpitem->item_text);
-	}
-	if (lpitem->prev)
-	    lpitem->prev->next = lpitem->next;
-	if (lpitem->next)
-	    lpitem->next->prev = lpitem->prev;
-	GlobalFree(lpitem);
-	GlobalUnlock(hMenu);
-	return TRUE;
-    }
-
-    GlobalUnlock(hMenu);
-    return FALSE;
 }
 
 
@@ -1477,37 +1503,42 @@
  */
 BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
 {
-    WND		*wndPtr;
-    LPPOPUPMENU	menu;
-    LPMENUITEM 	lpitem;
-    int		i;
+	WND		*wndPtr;
+	LPPOPUPMENU	menu;
+	LPMENUITEM 	lpitem;
+	int		i;
 #ifdef DEBUG_MENU
-    printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
-	hMenu, nPos, wFlags, wItemID, lpNewItem);
+	printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
+				hMenu, nPos, wFlags, wItemID, lpNewItem);
 #endif
-    menu = (LPPOPUPMENU) GlobalLock(hMenu);
-    if (menu == NULL) return FALSE;
-    lpitem = menu->firstItem;
-    for (i = 0; i < menu->nItems; i++) {
-    	if (lpitem == NULL) break;
-    	if (i == nPos) {
-    	    lpitem->item_flags = wFlags;
-    	    lpitem->item_id    = wItemID;
-	    if (!(lpitem->item_flags & 
-		  (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
-		   MF_MENUBREAK | MF_SEPARATOR))) {
-		    lpitem->item_text = GlobalReAlloc(lpitem->item_text,
-						      strlen(lpNewItem) + 1,
-						      GLOBAL_FLAGS_MOVEABLE);
-		    strcpy(lpitem->item_text, lpNewItem);
-		    }
-	    else
-		    lpitem->item_text = lpNewItem;
-	    GlobalUnlock(hMenu);
-    	    return(TRUE);
-	    }
-    	lpitem = (LPMENUITEM)lpitem->next;
-    	}
+	menu = (LPPOPUPMENU) GlobalLock(hMenu);
+	if (menu == NULL) return FALSE;
+	lpitem = menu->firstItem;
+	for (i = 0; i < menu->nItems; i++) {
+		if (lpitem == NULL) break;
+		if (i == nPos) {
+			lpitem->item_flags = wFlags;
+			lpitem->item_id    = wItemID;
+			if (!(lpitem->item_flags & 
+				(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
+				MF_MENUBREAK | MF_SEPARATOR))) {
+				GlobalFree((HANDLE)lpitem->item_text);
+/*				lpitem->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); */
+				lpitem->item_text = GlobalLock(GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1));
+				printf("ModifyMenu %08X %08X '%s') !\n",
+					lpitem->item_text, lpNewItem, lpNewItem);
+				if (lpitem->item_text != NULL)
+					strcpy(lpitem->item_text, lpNewItem);
+				else
+					printf("ModifyMenu // Bad Alloc !\n");
+				}
+			else
+				lpitem->item_text = lpNewItem;
+				GlobalUnlock(hMenu);
+				return(TRUE);
+				}
+		lpitem = (LPMENUITEM)lpitem->next;
+		}
     GlobalUnlock(hMenu);
     return FALSE;
 }
@@ -1561,13 +1592,25 @@
 		hMenu, wFlags, x, y, nReserved, hWnd, lpRect);
 #endif
 	lppop = (LPPOPUPMENU) GlobalLock(hMenu);
-	if (lppop == NULL) return FALSE;
+	if (lppop == NULL) {
+		printf("TrackPopupMenu // Bad menu handle %04X !\n", hMenu);
+		return FALSE;
+		}
 	wndPtr = WIN_FindWndPtr(hWnd);
+	if (wndPtr == NULL) {
+		printf("TrackPopupMenu // Bad window handle %04X !\n", hWnd);
+		return FALSE;
+		}
 	lppop->ownerWnd = hWnd;
+	lppop->hWndPrev = GetFocus();
 	if (lppop->hWnd == (HWND)NULL) {
 		lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE,
 			x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, 
 			wndPtr->hInstance, (LPSTR)lppop);
+		if (lppop->hWnd == 0) {
+			printf("TrackPopupMenu // Can't create PopupMenu window !\n");
+			return FALSE;
+			}
 		}
 	else {
 		ShowWindow(lppop->hWnd, SW_SHOW);
@@ -1581,12 +1624,12 @@
 		SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, 
 			SWP_NOZORDER);
 		}
+	SetFocus(lppop->hWnd);
 	if (!MenuHasFocus) {
 #ifdef DEBUG_MENU
 		printf("TrackPopupMenu // before MenuFocusLoop !\n");
 #endif
 		MenuFocusLoop(hWnd, NULL);
-/*		ActivateMenuFocus(hWnd); */
 #ifdef DEBUG_MENU
 		printf("TrackPopupMenu // after MenuFocusLoop !\n");
 #endif
@@ -1596,23 +1639,32 @@
 }
 
 
-BOOL ActivateMenuFocus(HWND hWnd)
+BOOL ActivateMenuBarFocus(HWND hWnd)
 {
 	WND		*wndPtr;
 	LPPOPUPMENU	lpmenu;
 	BOOL	bRet;
 	MSG		msg;
 	if (MenuHasFocus) return FALSE;
-    wndPtr = WIN_FindWndPtr(hWnd);
+	wndPtr = WIN_FindWndPtr(hWnd);
 	if (wndPtr == NULL) return FALSE;
 #ifdef DEBUG_MENU
-	printf("ActivateMenuFocus (%04X) !\n", hWnd);
+	printf("ActivateMenuBarFocus (%04X) !\n", hWnd);
 #endif
+	while((wndPtr->dwStyle & WS_CHILD) == WS_CHILD) {
+		hWnd = GetParent(hWnd);
+		printf("ActivateMenuBarFocus // next Parent=%04X !\n", hWnd);
+		wndPtr = WIN_FindWndPtr(hWnd);
+		if (wndPtr == NULL) return FALSE;
+		}
 	if ((wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) {
 		lpmenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
+		if (lpmenu == NULL) return FALSE;
+		lpmenu->hWndPrev = GetFocus();
+		SetFocus(hWnd);
 		MenuItemSelect(hWnd, lpmenu, 0);
 		bRet = MenuFocusLoop(hWnd, lpmenu);
-		if (lpmenu != NULL) GlobalUnlock(wndPtr->wIDmenu);
+		GlobalUnlock(wndPtr->wIDmenu);
 		return bRet;
 		}
 	return FALSE;
@@ -1688,7 +1740,6 @@
 	lpsys->hWndParent = hWnd;
 	if (!IsWindowVisible(lpsys->hWnd)) {
 		GetWindowRect(hWnd, &rect);
-		lpsys->hWndPrev = GetFocus();
 #ifdef DEBUG_MENU
 		printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd);
 #endif
@@ -1707,7 +1758,6 @@
 			printf("NC_TrackSysMenu // before MenuFocusLoop !\n");
 #endif
 			MenuFocusLoop(hWnd, NULL);
-/*			ActivateMenuFocus(hWnd); */
 #ifdef DEBUG_MENU
 			printf("NC_TrackSysMenu // after MenuFocusLoop !\n");
 #endif
@@ -1890,18 +1940,23 @@
  */
 BOOL SetMenu(HWND hWnd, HMENU hMenu)
 {
-	LPPOPUPMENU lppop;
+	LPPOPUPMENU lpmenu;
 	WND * wndPtr = WIN_FindWndPtr(hWnd);
-	if (wndPtr == NULL) return FALSE;
+	if (wndPtr == NULL) {
+		printf("SetMenu(%04X, %04X) // Bad window handle !\n", hWnd, hMenu);
+		return FALSE;
+		}
 #ifdef DEBUG_MENU
 	printf("SetMenu(%04X, %04X);\n", hWnd, hMenu);
 #endif
 	wndPtr->wIDmenu = hMenu;
-	if (hMenu == 0) return TRUE;
-	lppop = (LPPOPUPMENU) GlobalLock(hMenu);
-	if (lppop == NULL) return FALSE;
-	lppop->ownerWnd = hWnd;
-	ResetHiliteFlags(lppop);
+	lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
+	if (lpmenu == NULL) {
+		printf("SetMenu(%04X, %04X) // Bad menu handle !\n", hWnd, hMenu);
+		return FALSE;
+		}
+	lpmenu->ownerWnd = hWnd;
+	ResetHiliteFlags(lpmenu);
 	GlobalUnlock(hMenu);
 	return TRUE;
 }
@@ -1961,7 +2016,7 @@
 		if (lppop == NULL) return;
 		if ((lppop->rect.bottom - lppop->rect.top) != 0) {
 			hDC = GetWindowDC(hWnd);
-			StdDrawMenuBar(hDC, &lppop->rect, lppop);
+			StdDrawMenuBar(hDC, &lppop->rect, lppop, FALSE);
 			ReleaseDC(hWnd, hDC);
 			}
 		else
diff --git a/controls/widgets.c b/controls/widgets.c
index c56daba..356c606 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -16,6 +16,7 @@
 LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG ListBoxWndProc  ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+LONG EditWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG DesktopWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG MDIClientWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
@@ -33,6 +34,8 @@
       0, 0, 0, 0, NULL, "LISTBOX" },
     { CS_GLOBALCLASS, (LONG(*)())ComboBoxWndProc, 0, 8,
       0, 0, 0, 0, NULL, "COMBOBOX" },
+    { CS_GLOBALCLASS, (LONG(*)())EditWndProc, 0, 2, 
+      0, 0, 0, 0, NULL, "EDIT" },
     { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8,
       0, 0, 0, 0, NULL, "POPUPMENU" },
     { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO),
diff --git a/debugger/bfd.h b/debugger/bfd.h
deleted file mode 100644
index 430b0ab..0000000
--- a/debugger/bfd.h
+++ /dev/null
@@ -1,1421 +0,0 @@
-/* A -*- C -*- header file for the bfd library
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
-   Contributed by Cygnus Support.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-/* bfd.h -- The only header file required by users of the bfd library 
-
-This file is generated from various .c files, if you change it, your
-bits may be lost.
-
-All the prototypes and definitions following the comment "THE FOLLOWING
-IS EXTRACTED FROM THE SOURCE" are extracted from the source files for
-BFD.  If you change it, someone oneday will extract it from the source
-again, and your changes will be lost.  To save yourself from this bind,
-change the definitions in the source in the bfd directory.  Type "make
-docs" and then "make headers" in that directory, and magically this file
-will change to reflect your changes.
-
-If you don't have the tools to perform the extraction, then you are
-safe from someone on your system trampling over your header files.
-You should still maintain the equivalence between the source and this
-file though; every change you make to the .c file should be reflected
-here.  */
-
-#ifndef __BFD_H_SEEN__
-#define __BFD_H_SEEN__
-
-#include "ansidecl.h"
-#include "obstack.h"
-
-/* Make it easier to declare prototypes (puts conditional here) */
-#ifndef PROTO
-#	if __STDC__
-#		define PROTO(type, name, arglist) type name arglist
-#	else
-#		define PROTO(type, name, arglist) type name ()
-#	endif
-#endif
-
-#define BFD_VERSION "2.0"
-
-/* forward declaration */
-typedef struct _bfd bfd;
-
-/* General rules: functions which are boolean return true on success
-   and false on failure (unless they're a predicate).   -- bfd.doc */
-/* I'm sure this is going to break something and someone is going to
-   force me to change it. */
-/* typedef enum boolean {false, true} boolean; */
-/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h>  -fnf */
-typedef enum bfd_boolean {false, true} boolean;
-
-/* A pointer to a position in a file.  */
-/* FIXME:  This should be using off_t from <sys/types.h>.
-   For now, try to avoid breaking stuff by not including <sys/types.h> here.
-   This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
-   Probably the best long-term answer is to avoid using file_ptr AND off_t 
-   in this header file, and to handle this in the BFD implementation
-   rather than in its interface.  */
-/* typedef off_t	file_ptr; */
-typedef long int file_ptr;
-
-/* Support for different sizes of target format ints and addresses */
-
-#ifdef	HOST_64_BIT
-typedef HOST_64_BIT rawdata_offset;
-typedef HOST_64_BIT bfd_vma;
-typedef HOST_64_BIT bfd_word;
-typedef HOST_64_BIT bfd_offset;
-typedef HOST_64_BIT bfd_size_type;
-typedef HOST_64_BIT symvalue;
-typedef HOST_64_BIT bfd_64_type;
-#define fprintf_vma(s,x) \
-		fprintf(s,"%08x%08x", uint64_typeHIGH(x), uint64_typeLOW(x))
-#else
-typedef struct {int a,b;} bfd_64_type;
-typedef unsigned long rawdata_offset;
-typedef unsigned long bfd_vma;
-typedef unsigned long bfd_offset;
-typedef unsigned long bfd_word;
-typedef unsigned long bfd_size;
-typedef unsigned long symvalue;
-typedef unsigned long bfd_size_type;
-#define fprintf_vma(s,x) fprintf(s, "%08lx", x)
-#endif
-#define printf_vma(x) fprintf_vma(stdout,x)
-
-typedef unsigned int flagword;	/* 32 bits of flags */
-
-/** File formats */
-
-typedef enum bfd_format {
-	      bfd_unknown = 0,	/* file format is unknown */
-	      bfd_object,	/* linker/assember/compiler output */
-	      bfd_archive,	/* object archive file */
-	      bfd_core,		/* core dump */
-	      bfd_type_end}	/* marks the end; don't use it! */
-         bfd_format;
-
-/* Object file flag values */
-#define NO_FLAGS    	0x00
-#define HAS_RELOC   	0x01
-#define EXEC_P      	0x02
-#define HAS_LINENO  	0x04
-#define HAS_DEBUG   	0x08
-#define HAS_SYMS    	0x10
-#define HAS_LOCALS  	0x20
-#define DYNAMIC     	0x40
-#define WP_TEXT     	0x80
-#define D_PAGED     	0x100
-#define BFD_IS_RELAXABLE 0x200
-
-/* symbols and relocation */
-
-typedef unsigned long symindex;
-
-#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
-
-typedef enum bfd_symclass {
-	      bfd_symclass_unknown = 0,
-	      bfd_symclass_fcommon, /* fortran common symbols */
-	      bfd_symclass_global, /* global symbol, what a surprise */
-	      bfd_symclass_debugger, /* some debugger symbol */
-	      bfd_symclass_undefined /* none known */
-	    } symclass;
-
-
-typedef int symtype;		/* Who knows, yet? */
-
-
-/* general purpose part of a symbol;
-   target specific parts will be found in libcoff.h, liba.out.h etc */
-
-
-#define bfd_get_section(x) ((x)->section)
-#define bfd_get_output_section(x) ((x)->section->output_section)
-#define bfd_set_section(x,y) ((x)->section) = (y)
-#define bfd_asymbol_base(x) ((x)->section?((x)->section->vma):0)
-#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + x->value)
-#define bfd_asymbol_name(x) ((x)->name)
-
-/* This is a type pun with struct ranlib on purpose! */
-typedef struct carsym {
-  char *name;
-  file_ptr file_offset;		/* look here to find the file */
-} carsym;			/* to make these you call a carsymogen */
-
-  
-/* Used in generating armaps.  Perhaps just a forward definition would do? */
-struct orl {			/* output ranlib */
-  char **name;			/* symbol name */ 
-  file_ptr pos;			/* bfd* or file position */
-  int namidx;			/* index into string table */
-};
-
-
-
-/* Linenumber stuff */
-typedef struct lineno_cache_entry {
-  unsigned int line_number;	/* Linenumber from start of function*/  
-  union {
- struct symbol_cache_entry *sym;		/* Function name */
-    unsigned long offset;	/* Offset into section */
-  } u;
-} alent;
-
-/* object and core file sections */
-
-
-#define	align_power(addr, align)	\
-	( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
-
-typedef struct sec *sec_ptr;
-
-#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
-#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
-#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
-#define bfd_section_name(bfd, ptr) ((ptr)->name)
-#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
-#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
-#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
-#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
-#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
-
-#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (val)), ((ptr)->user_set_vma = true), true)
-#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true)
-#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true)
-
-typedef struct stat stat_type; 
-
-/** Error handling */
-
-typedef enum bfd_error {
-	      no_error = 0, system_call_error, invalid_target,
-	      wrong_format, invalid_operation, no_memory,
-	      no_symbols, no_relocation_info,
-	      no_more_archived_files, malformed_archive,
-	      symbol_not_found, file_not_recognized,
-	      file_ambiguously_recognized, no_contents,
-	      bfd_error_nonrepresentable_section,
-	      no_debug_section, bad_value,
-	      invalid_error_code} bfd_ec;
-
-extern bfd_ec bfd_error;
-struct reloc_cache_entry;
-struct bfd_seclet_struct ;
-
-
-typedef struct bfd_error_vector {
-  PROTO(void,(* nonrepresentable_section ),(CONST bfd  *CONST abfd,
-					    CONST char *CONST name));
-  PROTO(void,(* undefined_symbol),(CONST struct reloc_cache_entry *rel,
-				   CONST struct bfd_seclet_struct *sec
-				   ));
-  PROTO(void, (* reloc_value_truncated),(CONST struct
-					  reloc_cache_entry *rel,
-					  struct bfd_seclet_struct *sec));
-
-  PROTO(void, (* reloc_dangerous),(CONST struct reloc_cache_entry *rel,
-				   CONST struct bfd_seclet_struct *sec));
-  
-} bfd_error_vector_type;
-
-PROTO (CONST char *, bfd_errmsg, (bfd_ec error_tag));
-PROTO (void, bfd_perror, (CONST char *message));
-
-
-typedef enum bfd_print_symbol
-{ 
-  bfd_print_symbol_name,
-  bfd_print_symbol_more,
-  bfd_print_symbol_all,
-  bfd_print_symbol_nm	/* Pretty format suitable for nm program. */
-} bfd_print_symbol_type;
-    
-
-
-/* The code that implements targets can initialize a jump table with this
-   macro.  It must name all its routines the same way (a prefix plus
-   the standard routine suffix), or it must #define the routines that
-   are not so named, before calling JUMP_TABLE in the initializer.  */
-
-/* Semi-portable string concatenation in cpp */
-#ifndef CAT
-#ifdef __STDC__
-#define CAT(a,b) a##b
-#else
-#define CAT(a,b) a/**/b
-#endif
-#endif
-
-#define JUMP_TABLE(NAME)\
-CAT(NAME,_core_file_failing_command),\
-CAT(NAME,_core_file_failing_signal),\
-CAT(NAME,_core_file_matches_executable_p),\
-CAT(NAME,_slurp_armap),\
-CAT(NAME,_slurp_extended_name_table),\
-CAT(NAME,_truncate_arname),\
-CAT(NAME,_write_armap),\
-CAT(NAME,_close_and_cleanup),	\
-CAT(NAME,_set_section_contents),\
-CAT(NAME,_get_section_contents),\
-CAT(NAME,_new_section_hook),\
-CAT(NAME,_get_symtab_upper_bound),\
-CAT(NAME,_get_symtab),\
-CAT(NAME,_get_reloc_upper_bound),\
-CAT(NAME,_canonicalize_reloc),\
-CAT(NAME,_make_empty_symbol),\
-CAT(NAME,_print_symbol),\
-CAT(NAME,_get_lineno),\
-CAT(NAME,_set_arch_mach),\
-CAT(NAME,_openr_next_archived_file),\
-CAT(NAME,_find_nearest_line),\
-CAT(NAME,_generic_stat_arch_elt),\
-CAT(NAME,_sizeof_headers),\
-CAT(NAME,_bfd_debug_info_start),\
-CAT(NAME,_bfd_debug_info_end),\
-CAT(NAME,_bfd_debug_info_accumulate),\
-CAT(NAME,_bfd_get_relocated_section_contents),\
-CAT(NAME,_bfd_relax_section)
-
-#define COFF_SWAP_TABLE \
- coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, \
- coff_swap_aux_out, coff_swap_sym_out, \
- coff_swap_lineno_out, coff_swap_reloc_out, \
- coff_swap_filehdr_out, coff_swap_aouthdr_out, \
- coff_swap_scnhdr_out
-
-
-
-/* User program access to BFD facilities */
-
-extern CONST short _bfd_host_big_endian;
-#define HOST_BYTE_ORDER_BIG_P	(*(char *)&_bfd_host_big_endian)
-
-/* The bfd itself */
-
-/* Cast from const char * to char * so that caller can assign to
-   a char * without a warning.  */
-#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
-#define bfd_get_format(abfd) ((abfd)->format)
-#define bfd_get_target(abfd) ((abfd)->xvec->name)
-#define bfd_get_file_flags(abfd) ((abfd)->flags)
-#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
-#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
-#define bfd_my_archive(abfd) ((abfd)->my_archive)
-#define bfd_has_map(abfd) ((abfd)->has_armap)
-#define bfd_header_twiddle_required(abfd) \
-        ((((abfd)->xvec->header_byteorder_big_p)		\
-	  != (boolean)HOST_BYTE_ORDER_BIG_P) ? true:false)
-
-#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
-#define bfd_usrdata(abfd) ((abfd)->usrdata)
-
-#define bfd_get_start_address(abfd) ((abfd)->start_address)
-#define bfd_get_symcount(abfd) ((abfd)->symcount)
-#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
-#define bfd_count_sections(abfd) ((abfd)->section_count)
-#define bfd_get_architecture(abfd) ((abfd)->obj_arch)
-#define bfd_get_machine(abfd) ((abfd)->obj_machine)
-
-#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
-
-#define BYTE_SIZE 1
-#define SHORT_SIZE 2
-#define LONG_SIZE 4
-
-/* And more from the source.  */
-void EXFUN(bfd_init, (void));
-bfd *EXFUN(bfd_openr, (CONST char *filename, CONST char*target));
-bfd *EXFUN(bfd_fdopenr, (CONST char *filename, CONST char *target, int fd));
-bfd *EXFUN(bfd_openw, (CONST char *filename, CONST char *target));
-boolean EXFUN(bfd_close, (bfd *));
-boolean EXFUN(bfd_close_all_done, (bfd *));
-bfd_size_type EXFUN(bfd_alloc_size, (bfd *abfd));
-bfd *EXFUN(bfd_create, (CONST char *filename, bfd *template));
-#define bfd_put_8(abfd, val, ptr) \
-                (*((char *)ptr) = (char)val)
-#define bfd_get_8(abfd, ptr) \
-                (*((char *)ptr))
-#define bfd_put_16(abfd, val, ptr) \
-                BFD_SEND(abfd, bfd_putx16, (val,ptr))
-#define bfd_get_16(abfd, ptr) \
-                BFD_SEND(abfd, bfd_getx16, (ptr))
-#define bfd_put_32(abfd, val, ptr) \
-                BFD_SEND(abfd, bfd_putx32, (val,ptr))
-#define bfd_get_32(abfd, ptr) \
-                BFD_SEND(abfd, bfd_getx32, (ptr))
-#define bfd_put_64(abfd, val, ptr) \
-                BFD_SEND(abfd, bfd_putx64, (val, ptr))
-#define bfd_get_64(abfd, ptr) \
-                BFD_SEND(abfd, bfd_getx64, (ptr))
-#define bfd_h_put_8(abfd, val, ptr) \
-                (*((char *)ptr) = (char)val)
-#define bfd_h_get_8(abfd, ptr) \
-                (*((char *)ptr))
-#define bfd_h_put_16(abfd, val, ptr) \
-                BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
-#define bfd_h_get_16(abfd, ptr) \
-                BFD_SEND(abfd, bfd_h_getx16,(ptr))
-#define bfd_h_put_32(abfd, val, ptr) \
-                BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
-#define bfd_h_get_32(abfd, ptr) \
-                BFD_SEND(abfd, bfd_h_getx32,(ptr))
-#define bfd_h_put_64(abfd, val, ptr) \
-                BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
-#define bfd_h_get_64(abfd, ptr) \
-                BFD_SEND(abfd, bfd_h_getx64,(ptr))
-typedef struct sec 
-{
-         /* The name of the section, the name isn't a copy, the pointer is
-        the same as that passed to bfd_make_section. */
-
-    CONST char *name;
-
-
-         /* Which section is it 0.nth      */
-
-   int index;                      
-
-         /* The next section in the list belonging to the BFD, or NULL. */
-
-    struct sec *next;
-
-         /* The field flags contains attributes of the section. Some of
-           flags are read in from the object file, and some are
-           synthesized from other information.  */         
-
-    flagword flags;
-
-#define SEC_NO_FLAGS   0x000
-
-         /* Tells the OS to allocate space for this section when loaded.
-           This would clear for a section containing debug information
-           only. */
-          
-
-#define SEC_ALLOC      0x001
-         /* Tells the OS to load the section from the file when loading.
-           This would be clear for a .bss section */
-
-#define SEC_LOAD       0x002
-         /* The section contains data still to be relocated, so there will
-           be some relocation information too. */
-
-#define SEC_RELOC      0x004
-
-         /* Obsolete ? */
-
-#define SEC_BALIGN     0x008
-
-         /* A signal to the OS that the section contains read only
-          data. */
-#define SEC_READONLY   0x010
-
-         /* The section contains code only. */
-
-#define SEC_CODE       0x020
-
-         /* The section contains data only. */
-
-#define SEC_DATA        0x040
-
-         /* The section will reside in ROM. */
-
-#define SEC_ROM        0x080
-
-         /* The section contains constructor information. This section
-           type is used by the linker to create lists of constructors and
-           destructors used by <<g++>>. When a back end sees a symbol
-           which should be used in a constructor list, it creates a new
-           section for the type of name (eg <<__CTOR_LIST__>>), attaches
-           the symbol to it and builds a relocation. To build the lists
-           of constructors, all the linker has to to is catenate all the
-           sections called <<__CTOR_LIST__>> and relocte the data
-           contained within - exactly the operations it would peform on
-           standard data. */
-
-#define SEC_CONSTRUCTOR 0x100
-
-         /* The section is a constuctor, and should be placed at the
-          end of the . */
-
-
-#define SEC_CONSTRUCTOR_TEXT 0x1100
-
-#define SEC_CONSTRUCTOR_DATA 0x2100
-
-#define SEC_CONSTRUCTOR_BSS  0x3100
-
-
-         /* The section has contents - a bss section could be
-           <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>, a debug section could be
-           <<SEC_HAS_CONTENTS>> */
-
-#define SEC_HAS_CONTENTS 0x200
-
-         /* An instruction to the linker not to output sections
-          containing this flag even if they have information which
-          would normally be written. */
-
-#define SEC_NEVER_LOAD 0x400
-
-
-       
-   bfd_vma vma;
-   boolean user_set_vma;
-
-         /* The size of the section in bytes, as it will be output.
-           contains a value even if the section has no contents (eg, the
-           size of <<.bss>>). This will be filled in after relocation */
-
-   bfd_size_type _cooked_size;    
-
-         /* The size on disk of the section in bytes originally.  Normally this
-	    value is the same as the size, but if some relaxing has
-	    been done, then this value will be bigger.  */
-
-   bfd_size_type _raw_size;    
-
-         /* If this section is going to be output, then this value is the
-           offset into the output section of the first byte in the input
-           section. Eg, if this was going to start at the 100th byte in
-           the output section, this value would be 100. */
-
-   bfd_vma output_offset;
-
-         /* The output section through which to map on output. */
-
-   struct sec *output_section;
-
-         /* The alignment requirement of the section, as an exponent - eg
-           3 aligns to 2^3 (or 8) */
-
-   unsigned int alignment_power;
-
-         /* If an input section, a pointer to a vector of relocation
-           records for the data in this section. */
-
-   struct reloc_cache_entry *relocation;
-
-         /* If an output section, a pointer to a vector of pointers to
-           relocation records for the data in this section. */
-
-   struct reloc_cache_entry **orelocation;
-
-         /* The number of relocation records in one of the above  */
-
-   unsigned reloc_count;
-
-         /* Information below is back end specific - and not always used
-           or updated 
-
-           File position of section data    */
-
-   file_ptr filepos;      
-        
-         /* File position of relocation info */
-
-   file_ptr rel_filepos;
-
-         /* File position of line data       */
-
-   file_ptr line_filepos;
-
-         /* Pointer to data for applications */
-
-   PTR userdata;
-
-   struct lang_output_section *otheruserdata;
-
-         /* Attached line number information */
-
-   alent *lineno;
-        
-         /* Number of line number records   */
-
-   unsigned int lineno_count;
-
-         /* When a section is being output, this value changes as more
-           linenumbers are written out */
-
-   file_ptr moving_line_filepos;
-
-         /* what the section number is in the target world  */
-
-   int target_index;
-
-   PTR used_by_bfd;
-
-         /* If this is a constructor section then here is a list of the
-           relocations created to relocate items within it. */
-
-   struct relent_chain *constructor_chain;
-
-         /* The BFD which owns the section. */
-
-   bfd *owner;
-
-   boolean reloc_done;
-	  /* A symbol which points at this section only */
-   struct symbol_cache_entry *symbol;  
-   struct symbol_cache_entry **symbol_ptr_ptr;
-   struct bfd_seclet_struct *seclets_head;
-   struct bfd_seclet_struct *seclets_tail;
-} asection ;
-
-
-#define BFD_ABS_SECTION_NAME "*ABS*"
-#define BFD_UND_SECTION_NAME "*UND*"
-#define BFD_COM_SECTION_NAME "*COM*"
-
-     /* the absolute section */
- extern   asection bfd_abs_section;
-     /* Pointer to the undefined section */
- extern   asection bfd_und_section;
-     /* Pointer to the common section */
- extern asection bfd_com_section;
-
- extern struct symbol_cache_entry *bfd_abs_symbol;
- extern struct symbol_cache_entry *bfd_com_symbol;
- extern struct symbol_cache_entry *bfd_und_symbol;
-#define bfd_get_section_size_before_reloc(section) \
-     (section->reloc_done ? (abort(),1): (section)->_raw_size)
-#define bfd_get_section_size_after_reloc(section) \
-     ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
-asection *EXFUN(bfd_get_section_by_name, (bfd *abfd, CONST char *name));
-asection *EXFUN(bfd_make_section_old_way, (bfd *, CONST char *name));
-asection * EXFUN(bfd_make_section, (bfd *, CONST char *name));
-boolean EXFUN(bfd_set_section_flags, (bfd *, asection *, flagword));
-void EXFUN(bfd_map_over_sections, (bfd *abfd,
-    void (*func)(bfd *abfd,
-    asection *sect,
-    PTR obj),
-    PTR obj));
-boolean EXFUN(bfd_set_section_size, (bfd *, asection *, bfd_size_type val));
-boolean EXFUN(bfd_set_section_contents
-    , (bfd *abfd,        
-    asection *section,
-    PTR data,
-    file_ptr offset,
-    bfd_size_type count));
-boolean EXFUN(bfd_get_section_contents 
-    , (bfd *abfd, asection *section, PTR location,
-    file_ptr offset, bfd_size_type count));
-enum bfd_architecture 
-{
-  bfd_arch_unknown,    /* File arch not known */
-  bfd_arch_obscure,    /* Arch known, not one of these */
-  bfd_arch_m68k,       /* Motorola 68xxx */
-  bfd_arch_vax,        /* DEC Vax */   
-  bfd_arch_i960,       /* Intel 960 */
-     /* The order of the following is important.
-       lower number indicates a machine type that 
-       only accepts a subset of the instructions
-       available to machines with higher numbers.
-       The exception is the "ca", which is
-       incompatible with all other machines except 
-       "core". */
-
-#define bfd_mach_i960_core      1
-#define bfd_mach_i960_ka_sa     2
-#define bfd_mach_i960_kb_sb     3
-#define bfd_mach_i960_mc        4
-#define bfd_mach_i960_xa        5
-#define bfd_mach_i960_ca        6
-
-  bfd_arch_a29k,       /* AMD 29000 */
-  bfd_arch_sparc,      /* SPARC */
-  bfd_arch_mips,       /* MIPS Rxxxx */
-  bfd_arch_i386,       /* Intel 386 */
-  bfd_arch_we32k,      /* AT&T WE32xxx */
-  bfd_arch_tahoe,      /* CCI/Harris Tahoe */
-  bfd_arch_i860,       /* Intel 860 */
-  bfd_arch_romp,       /* IBM ROMP PC/RT */
-  bfd_arch_alliant,    /* Alliant */
-  bfd_arch_convex,     /* Convex */
-  bfd_arch_m88k,       /* Motorola 88xxx */
-  bfd_arch_pyramid,    /* Pyramid Technology */
-  bfd_arch_h8300,      /* Hitachi H8/300 */
-  bfd_arch_rs6000,     /* IBM RS/6000 */
-  bfd_arch_hppa,       /* HP PA RISC */
-  bfd_arch_z8k,        /* Zilog Z8000 */
-#define bfd_mach_z8001		1
-#define bfd_mach_z8002		2
-  bfd_arch_last
-  };
-
-typedef struct bfd_arch_info 
-{
-  int bits_per_word;
-  int bits_per_address;
-  int bits_per_byte;
-  enum bfd_architecture arch;
-  long mach;
-  char *arch_name;
-  CONST  char *printable_name;
-  unsigned int section_align_power;
-  /* true if this is the default machine for the architecture */
-  boolean the_default;	
-  CONST struct bfd_arch_info * EXFUN((*compatible),
-	(CONST struct bfd_arch_info *a,
-	 CONST struct bfd_arch_info *b));
-
-  boolean EXFUN((*scan),(CONST struct bfd_arch_info *,CONST char *));
-  unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data,
-				     PTR stream));
-
-  struct bfd_arch_info *next;
-} bfd_arch_info_type;
-CONST char *EXFUN(bfd_printable_name, (bfd *abfd));
-bfd_arch_info_type *EXFUN(bfd_scan_arch, (CONST char *));
-CONST bfd_arch_info_type *EXFUN(bfd_arch_get_compatible, (
-    CONST bfd *abfd,
-    CONST bfd *bbfd));
-void EXFUN(bfd_set_arch_info, (bfd *, bfd_arch_info_type *));
-enum bfd_architecture EXFUN(bfd_get_arch, (bfd *abfd));
-unsigned long EXFUN(bfd_get_mach, (bfd *abfd));
-unsigned int EXFUN(bfd_arch_bits_per_byte, (bfd *abfd));
-unsigned int EXFUN(bfd_arch_bits_per_address, (bfd *abfd));
-bfd_arch_info_type * EXFUN(bfd_get_arch_info, (bfd *));
-bfd_arch_info_type *EXFUN(bfd_lookup_arch
-    , (enum bfd_architecture
-    arch,
-    long machine));
-CONST char * EXFUN(bfd_printable_arch_mach
-    , (enum bfd_architecture arch, unsigned long machine));
-typedef enum bfd_reloc_status 
-{
-        /* No errors detected */
-  bfd_reloc_ok,
-
-        /* The relocation was performed, but there was an overflow. */
-  bfd_reloc_overflow,
-
-        /* The address to relocate was not within the section supplied*/
-  bfd_reloc_outofrange,
-
-        /* Used by special functions */
-  bfd_reloc_continue,
-
-        /* Unused */
-  bfd_reloc_notsupported,
-
-        /* Unsupported relocation size requested.  */
-  bfd_reloc_other,
-
-        /* The symbol to relocate against was undefined.*/
-  bfd_reloc_undefined,
-
-        /* The relocation was performed, but may not be ok - presently
-          generated only when linking i960 coff files with i960 b.out
-          symbols. */
-  bfd_reloc_dangerous
- }
- bfd_reloc_status_type;
-
-
-typedef struct reloc_cache_entry 
-{
-        /* A pointer into the canonical table of pointers  */
-  struct symbol_cache_entry **sym_ptr_ptr;
-
-        /* offset in section */
-  rawdata_offset address;
-
-        /* addend for relocation value */
-  bfd_vma addend;    
-
-        /* Pointer to how to perform the required relocation */
-  CONST struct reloc_howto_struct *howto;
-
-} arelent;
-
-typedef CONST struct reloc_howto_struct 
-{ 
-        /*  The type field has mainly a documetary use - the back end can
-           to what it wants with it, though the normally the back end's
-           external idea of what a reloc number would be would be stored
-           in this field. For example, the a PC relative word relocation
-           in a coff environment would have the type 023 - because that's
-           what the outside world calls a R_PCRWORD reloc. */
-  unsigned int type;
-
-        /*  The value the final relocation is shifted right by. This drops
-           unwanted data from the relocation.  */
-  unsigned int rightshift;
-
-        /*  The size of the item to be relocated - 0, is one byte, 1 is 2
-           bytes, 3 is four bytes.  A -ve value indicates that the
-	    result is to be subtracted from the data*/
-  int size;
-
-        /*  Now obsolete */
-  unsigned int bitsize;
-
-        /*  Notes that the relocation is relative to the location in the
-           data section of the addend. The relocation function will
-           subtract from the relocation value the address of the location
-           being relocated. */
-  boolean pc_relative;
-
-        /*  Now obsolete */
-  unsigned int bitpos;
-
-        /*  Now obsolete */
-  boolean absolute;
-
-        /* Causes the relocation routine to return an error if overflow
-          is detected when relocating. */
-  boolean complain_on_overflow;
-
-        /* If this field is non null, then the supplied function is
-          called rather than the normal function. This allows really
-          strange relocation methods to be accomodated (eg, i960 callj
-          instructions). */
-  bfd_reloc_status_type EXFUN ((*special_function), 
-					    (bfd *abfd,
-					     arelent *reloc_entry,
-                                            struct symbol_cache_entry *symbol,
-                                            PTR data,
-                                            asection *input_section, 
-                                            bfd *output_bfd     ));
-
-        /* The textual name of the relocation type. */
-  char *name;
-
-        /* When performing a partial link, some formats must modify the
-          relocations rather than the data - this flag signals this.*/
-  boolean partial_inplace;
-
-        /* The src_mask is used to select what parts of the read in data
-          are to be used in the relocation sum. Eg, if this was an 8 bit
-          bit of data which we read and relocated, this would be
-          0x000000ff. When we have relocs which have an addend, such as
-          sun4 extended relocs, the value in the offset part of a
-          relocating field is garbage so we never use it. In this case
-          the mask would be 0x00000000. */
-  bfd_word src_mask;
-
-        /* The dst_mask is what parts of the instruction are replaced
-          into the instruction. In most cases src_mask == dst_mask,
-          except in the above special case, where dst_mask would be
-          0x000000ff, and src_mask would be 0x00000000.   */
-  bfd_word dst_mask;           
-
-        /* When some formats create PC relative instructions, they leave
-          the value of the pc of the place being relocated in the offset
-          slot of the instruction, so that a PC relative relocation can
-          be made just by adding in an ordinary offset (eg sun3 a.out).
-          Some formats leave the displacement part of an instruction
-          empty (eg m88k bcs), this flag signals the fact.*/
-  boolean pcrel_offset;
-
-} reloc_howto_type;
-#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-  {(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
-#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,false,false,FUNCTION, NAME,false,0,0,IN)
-
-#define HOWTO_PREPARE(relocation, symbol)      \
-  {                                            \
-  if (symbol != (asymbol *)NULL) {             \
-    if (symbol->section == &bfd_com_section) { \
-      relocation = 0;                          \
-    }                                          \
-    else {                                     \
-      relocation = symbol->value;              \
-    }                                          \
-  }                                            \
-}                      
-typedef unsigned char bfd_byte;
-
-typedef struct relent_chain {
-  arelent relent;
-  struct   relent_chain *next;
-} arelent_chain;
-bfd_reloc_status_type
-EXFUN(bfd_perform_relocation
-    , (bfd * abfd,
-    arelent *reloc_entry,
-    PTR data,
-    asection *input_section,
-    bfd *output_bfd));
-typedef enum bfd_reloc_code_real 
-
-{
-        /* 16 bits wide, simple reloc */
-  BFD_RELOC_16,        
-
-        /* 8 bits wide, but used to form an address like 0xffnn */
-  BFD_RELOC_8_FFnn,
-
-        /* 8 bits wide, simple */
-  BFD_RELOC_8,
-
-        /* 8 bits wide, pc relative */
-  BFD_RELOC_8_PCREL,
-
-        /* The type of reloc used to build a contructor table - at the
-          moment probably a 32 bit wide abs address, but the cpu can
-          choose. */
-
-  BFD_RELOC_CTOR,
-
-        /* 32 bits wide, simple reloc */
-  BFD_RELOC_32,
-	 /* 32 bits, PC-relative */
-  BFD_RELOC_32_PCREL,
-
-	 /* High 22 bits of 32-bit value; simple reloc.  */
-  BFD_RELOC_HI22,
-	 /* Low 10 bits.  */
-  BFD_RELOC_LO10,
-
-	 /* Reloc types used for i960/b.out.  */
-  BFD_RELOC_24_PCREL,
-  BFD_RELOC_I960_CALLJ,
-
-  BFD_RELOC_16_PCREL,
-	 /* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
-	   word displacement, e.g. for SPARC) */
-  BFD_RELOC_32_PCREL_S2,
-
-   /* now for the sparc/elf codes */
-  BFD_RELOC_NONE,		 /* actually used */
-  BFD_RELOC_SPARC_WDISP22,
-  BFD_RELOC_SPARC22,
-  BFD_RELOC_SPARC13,
-  BFD_RELOC_SPARC_BASE13,
-  BFD_RELOC_SPARC_GOT10,
-  BFD_RELOC_SPARC_GOT13,
-  BFD_RELOC_SPARC_GOT22,
-  BFD_RELOC_SPARC_PC10,
-  BFD_RELOC_SPARC_PC22,
-  BFD_RELOC_SPARC_WPLT30,
-  BFD_RELOC_SPARC_COPY,
-  BFD_RELOC_SPARC_GLOB_DAT,
-  BFD_RELOC_SPARC_JMP_SLOT,
-  BFD_RELOC_SPARC_RELATIVE,
-  BFD_RELOC_SPARC_UA32,
-
-   /* this one is a.out specific? */
-  BFD_RELOC_SPARC_BASE22,
-
-   /* this must be the highest numeric value */
-  BFD_RELOC_UNUSED
- } bfd_reloc_code_real_type;
-CONST struct reloc_howto_struct *
-EXFUN(bfd_reloc_type_lookup , (bfd *abfd, bfd_reloc_code_real_type code));
-typedef struct symbol_cache_entry 
-{
-	 /* A pointer to the BFD which owns the symbol. This information
-	   is necessary so that a back end can work out what additional
-   	   (invisible to the application writer) information is carried
-	   with the symbol.  */
-
-  struct _bfd *the_bfd;
-
-	 /* The text of the symbol. The name is left alone, and not copied - the
-	   application may not alter it. */
-  CONST char *name;
-
-	 /* The value of the symbol.*/
-  symvalue value;
-
-	 /* Attributes of a symbol: */
-
-#define BSF_NO_FLAGS    0x00
-
-	 /* The symbol has local scope; <<static>> in <<C>>. The value
- 	   is the offset into the section of the data. */
-#define BSF_LOCAL	0x01
-
-	 /* The symbol has global scope; initialized data in <<C>>. The
-	   value is the offset into the section of the data. */
-#define BSF_GLOBAL	0x02
-
-	 /* Obsolete */
-#define BSF_IMPORT	0x04
-
-	 /* The symbol has global scope, and is exported. The value is
-	   the offset into the section of the data. */
-#define BSF_EXPORT	0x08
-
-	 /* The symbol is undefined. <<extern>> in <<C>>. The value has
-	   no meaning. */
-#define BSF_UNDEFINED_OBS 0x10	
-
-	 /* The symbol is common, initialized to zero; default in
-	   <<C>>. The value is the size of the object in bytes. */
-#define BSF_FORT_COMM_OBS	0x20	
-
-	 /* A normal C symbol would be one of:
-	   <<BSF_LOCAL>>, <<BSF_FORT_COMM>>,  <<BSF_UNDEFINED>> or
-	   <<BSF_EXPORT|BSD_GLOBAL>> */
-
-	 /* The symbol is a debugging record. The value has an arbitary
-	   meaning. */
-#define BSF_DEBUGGING	0x40
-
-	 /* Used by the linker */
-#define BSF_KEEP        0x10000
-#define BSF_KEEP_G      0x80000
-
-	 /* Unused */
-#define BSF_WEAK        0x100000
-#define BSF_CTOR        0x200000 
-
-        /* This symbol was created to point to a section, e.g. ELF's
-	   STT_SECTION symbols.  */
-#define BSF_SECTION_SYM 0x400000 
-
-	 /* The symbol used to be a common symbol, but now it is
-	   allocated. */
-#define BSF_OLD_COMMON  0x800000  
-
-	 /* The default value for common data. */
-#define BFD_FORT_COMM_DEFAULT_VALUE 0
-
-	 /* In some files the type of a symbol sometimes alters its
-	   location in an output file - ie in coff a <<ISFCN>> symbol
-	   which is also <<C_EXT>> symbol appears where it was
-	   declared and not at the end of a section.  This bit is set
-  	   by the target BFD part to convey this information. */
-
-#define BSF_NOT_AT_END    0x40000
-
-	 /* Signal that the symbol is the label of constructor section. */
-#define BSF_CONSTRUCTOR   0x1000000
-
-	 /* Signal that the symbol is a warning symbol. If the symbol
-	   is a warning symbol, then the value field (I know this is
-	   tacky) will point to the asymbol which when referenced will
-	   cause the warning. */
-#define BSF_WARNING       0x2000000
-
-	 /* Signal that the symbol is indirect. The value of the symbol
-	   is a pointer to an undefined asymbol which contains the
-	   name to use instead. */
-#define BSF_INDIRECT      0x4000000
-
-	 /* BSF_FILE marks symbols that contain a file name.  This is used
-	   for ELF STT_FILE symbols.  */
-#define BSF_FILE          0x08000000
-
-  flagword flags;
-
-	 /* A pointer to the section to which this symbol is 
-	   relative.  This will always be non NULL, there are special
-          sections for undefined and absolute symbols */
-  struct sec *section;
-
-	 /* Back end special data. This is being phased out in favour
-	   of making this a union. */
-  PTR udata;	
-
-} asymbol;
-#define get_symtab_upper_bound(abfd) \
-     BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
-#define bfd_canonicalize_symtab(abfd, location) \
-     BFD_SEND (abfd, _bfd_canonicalize_symtab,\
-                  (abfd, location))
-boolean EXFUN(bfd_set_symtab , (bfd *, asymbol **, unsigned int ));
-void EXFUN(bfd_print_symbol_vandf, (PTR file, asymbol *symbol));
-#define bfd_make_empty_symbol(abfd) \
-     BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
-#define bfd_make_debug_symbol(abfd,ptr,size) \
-        BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
-int EXFUN(bfd_decode_symclass, (asymbol *symbol));
-struct _bfd 
-{
-     /* The filename the application opened the BFD with.  */
-    CONST char *filename;                
-
-     /* A pointer to the target jump table.             */
-    struct bfd_target *xvec;
-
-     /* To avoid dragging too many header files into every file that
-       includes `<<bfd.h>>', IOSTREAM has been declared as a "char
-       *", and MTIME as a "long".  Their correct types, to which they
-       are cast when used, are "FILE *" and "time_t".    The iostream
-       is the result of an fopen on the filename. */
-    char *iostream;
-
-     /* Is the file being cached */
-
-    boolean cacheable;
-
-     /* Marks whether there was a default target specified when the
-       BFD was opened. This is used to select what matching algorithm
-       to use to chose the back end. */
-
-    boolean target_defaulted;
-
-     /* The caching routines use these to maintain a
-       least-recently-used list of BFDs */
-
-    struct _bfd *lru_prev, *lru_next;
-
-     /* When a file is closed by the caching routines, BFD retains
-       state information on the file here: 
-     */
-
-    file_ptr where;              
-
-     /* and here:*/
-
-    boolean opened_once;
-
-     /* Set if we have a locally maintained mtime value, rather than
-       getting it from the file each time: */
-
-    boolean mtime_set;
-
-     /* File modified time, if mtime_set is true: */
-
-    long mtime;          
-
-     /* Reserved for an unimplemented file locking extension.*/
-
-    int ifd;
-
-     /* The format which belongs to the BFD.*/
-
-    bfd_format format;
-
-     /* The direction the BFD was opened with*/
-
-    enum bfd_direction {no_direction = 0,
-                        read_direction = 1,
-                        write_direction = 2,
-                        both_direction = 3} direction;
-
-     /* Format_specific flags*/
-
-    flagword flags;              
-
-     /* Currently my_archive is tested before adding origin to
-       anything. I believe that this can become always an add of
-       origin, with origin set to 0 for non archive files.   */
-
-    file_ptr origin;             
-
-     /* Remember when output has begun, to stop strange things
-       happening. */
-    boolean output_has_begun;
-
-     /* Pointer to linked list of sections*/
-    struct sec  *sections;
-
-     /* The number of sections */
-    unsigned int section_count;
-
-     /* Stuff only useful for object files: 
-       The start address. */
-    bfd_vma start_address;
-
-     /* Used for input and output*/
-    unsigned int symcount;
-
-     /* Symbol table for output BFD*/
-    struct symbol_cache_entry  **outsymbols;             
-
-     /* Pointer to structure which contains architecture information*/
-    struct bfd_arch_info *arch_info;
-
-     /* Stuff only useful for archives:*/
-    PTR arelt_data;              
-    struct _bfd *my_archive;     
-    struct _bfd *next;           
-    struct _bfd *archive_head;   
-    boolean has_armap;           
-
-     /* Used by the back end to hold private data. */
-
-    union 
-      {
-      struct aout_data_struct *aout_data;
-      struct artdata *aout_ar_data;
-      struct _oasys_data *oasys_obj_data;
-      struct _oasys_ar_data *oasys_ar_data;
-      struct coff_tdata *coff_obj_data;
-      struct ieee_data_struct *ieee_data;
-      struct ieee_ar_data_struct *ieee_ar_data;
-      struct srec_data_struct *srec_data;
-      struct srec_data_struct *tekhex_data;
-      struct elf_obj_tdata *elf_obj_data;
-      struct bout_data_struct *bout_data;
-      struct sun_core_struct *sun_core_data;
-      struct trad_core_struct *trad_core_data;
-      struct hppa_data_struct *hppa_data;
-      PTR any;
-      } tdata;
-  
-     /* Used by the application to hold private data*/
-    PTR usrdata;
-
-     /* Where all the allocated stuff under this BFD goes */
-    struct obstack memory;
-
-     /* Is this really needed in addition to usrdata?  */
-    asymbol **ld_symbols;
-};
-
-unsigned int EXFUN(bfd_get_reloc_upper_bound, (bfd *abfd, asection *sect));
-unsigned int EXFUN(bfd_canonicalize_reloc
-    , (bfd *abfd,
-    asection *sec,
-    arelent **loc,
-    asymbol	**syms));
-boolean EXFUN(bfd_set_file_flags, (bfd *abfd, flagword flags));
-void EXFUN(bfd_set_reloc
-    , (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
-    
-    );
-boolean EXFUN(bfd_set_start_address, (bfd *, bfd_vma));
-long EXFUN(bfd_get_mtime, (bfd *));
-#define bfd_sizeof_headers(abfd, reloc) \
-     BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
-
-#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
-     BFD_SEND (abfd, _bfd_find_nearest_line,  (abfd, sec, syms, off, file, func, line))
-
-        /* Do these three do anything useful at all, for any back end?  */
-#define bfd_debug_info_start(abfd) \
-        BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
-
-#define bfd_debug_info_end(abfd) \
-        BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
-
-#define bfd_debug_info_accumulate(abfd, section) \
-        BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
-
-
-#define bfd_stat_arch_elt(abfd, stat) \
-        BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
-
-#define bfd_coff_swap_aux_in(a,e,t,c,i) \
-        BFD_SEND (a, _bfd_coff_swap_aux_in, (a,e,t,c,i))
-
-#define bfd_coff_swap_sym_in(a,e,i) \
-        BFD_SEND (a, _bfd_coff_swap_sym_in, (a,e,i))
-
-#define bfd_coff_swap_lineno_in(a,e,i) \
-        BFD_SEND ( a, _bfd_coff_swap_lineno_in, (a,e,i))
-
-#define bfd_set_arch_mach(abfd, arch, mach)\
-        BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
-
-#define bfd_coff_swap_reloc_out(abfd, i, o) \
-        BFD_SEND (abfd, _bfd_coff_swap_reloc_out, (abfd, i, o))
-
-#define bfd_coff_swap_lineno_out(abfd, i, o) \
-        BFD_SEND (abfd, _bfd_coff_swap_lineno_out, (abfd, i, o))
-
-#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \
-        BFD_SEND (abfd, _bfd_coff_swap_aux_out, (abfd, i,t,c, o))
-
-#define bfd_coff_swap_sym_out(abfd, i,o) \
-        BFD_SEND (abfd, _bfd_coff_swap_sym_out, (abfd, i, o))
-
-#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
-        BFD_SEND (abfd, _bfd_coff_swap_scnhdr_out, (abfd, i, o))
-
-#define bfd_coff_swap_filehdr_out(abfd, i,o) \
-        BFD_SEND (abfd, _bfd_coff_swap_filehdr_out, (abfd, i, o))
-
-#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
-        BFD_SEND (abfd, _bfd_coff_swap_aouthdr_out, (abfd, i, o))
-
-#define bfd_get_relocated_section_contents(abfd, seclet, data) \
-	BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data))
- 
-#define bfd_relax_section(abfd, section, symbols) \
-       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
-symindex EXFUN(bfd_get_next_mapent, (bfd *, symindex previous, carsym ** sym));
-boolean EXFUN(bfd_set_archive_head, (bfd *output, bfd *new_head));
-bfd *EXFUN(bfd_get_elt_at_index, (bfd * archive, int index));
-bfd* EXFUN(bfd_openr_next_archived_file, (bfd *archive, bfd *previous));
-CONST char *EXFUN(bfd_core_file_failing_command, (bfd *));
-int EXFUN(bfd_core_file_failing_signal, (bfd *));
-boolean EXFUN(core_file_matches_executable_p
-    , (bfd *core_bfd, bfd *exec_bfd));
-#define SDEF(ret, name, arglist) \
-                PROTO(ret,(*name),arglist)
-#define SDEF_FMT(ret, name, arglist) \
-                PROTO(ret,(*name[bfd_type_end]),arglist)
-#define BFD_SEND(bfd, message, arglist) \
-               ((*((bfd)->xvec->message)) arglist)
-#define BFD_SEND_FMT(bfd, message, arglist) \
-            (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
-typedef struct bfd_target
-{
-  char *name;
-  enum target_flavour {
-    bfd_target_unknown_flavour,
-    bfd_target_aout_flavour,
-    bfd_target_coff_flavour,
-    bfd_target_elf_flavour,
-    bfd_target_ieee_flavour,
-    bfd_target_oasys_flavour,
-    bfd_target_tekhex_flavour,
-    bfd_target_srec_flavour,
-    bfd_target_hppa_flavour} flavour;
-  boolean byteorder_big_p;
-  boolean header_byteorder_big_p;
-  flagword object_flags;       
-  flagword section_flags;
-  char symbol_leading_char;
-  char ar_pad_char;            
- unsigned short ar_max_namelen;
-  unsigned int align_power_min;
-  SDEF (bfd_vma,      bfd_getx64, (bfd_byte *));
-  SDEF (void,         bfd_putx64, (bfd_vma, bfd_byte *));
-  SDEF (bfd_vma, bfd_getx32, (bfd_byte *));
-  SDEF (void,         bfd_putx32, (bfd_vma, bfd_byte *));
-  SDEF (bfd_vma, bfd_getx16, (bfd_byte *));
-  SDEF (void,         bfd_putx16, (bfd_vma, bfd_byte *));
-  SDEF (bfd_vma,   bfd_h_getx64, (bfd_byte *));
-  SDEF (void,          bfd_h_putx64, (bfd_vma, bfd_byte *));
-  SDEF (bfd_vma,  bfd_h_getx32, (bfd_byte *));
-  SDEF (void,          bfd_h_putx32, (bfd_vma, bfd_byte *));
-  SDEF (bfd_vma,  bfd_h_getx16, (bfd_byte *));
-  SDEF (void,          bfd_h_putx16, (bfd_vma, bfd_byte *));
-  SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *));
-  SDEF_FMT (boolean,            _bfd_set_format, (bfd *));
-  SDEF_FMT (boolean,            _bfd_write_contents, (bfd *));
-  SDEF (char *, _core_file_failing_command, (bfd *));
-  SDEF (int,    _core_file_failing_signal, (bfd *));
-  SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *));
- SDEF (boolean, _bfd_slurp_armap, (bfd *));
- SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *));
- SDEF (void,   _bfd_truncate_arname, (bfd *, CONST char *, char *));
- SDEF (boolean, write_armap, (bfd *arch, 
-                              unsigned int elength,
-                              struct orl *map,
-                              unsigned int orl_count, 
-                              int stridx));
-  SDEF (boolean, _close_and_cleanup, (bfd *));
-  SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR,
-                                            file_ptr, bfd_size_type));
-  SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR, 
-                                            file_ptr, bfd_size_type));
-  SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
-  SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
-  SDEF (unsigned int, _bfd_canonicalize_symtab,
-           (bfd *, struct symbol_cache_entry **));
-  SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr));
-  SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **,
-                                               struct symbol_cache_entry**));
-  SDEF (struct symbol_cache_entry  *, _bfd_make_empty_symbol, (bfd *));
-  SDEF (void,     _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry  *,
-                                      bfd_print_symbol_type));
-#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
-  SDEF (alent *,   _get_lineno, (bfd *, struct symbol_cache_entry  *));
-
-  SDEF (boolean,   _bfd_set_arch_mach, (bfd *, enum bfd_architecture,
-                                       unsigned long));
-
-  SDEF (bfd *,  openr_next_archived_file, (bfd *arch, bfd *prev));
-  SDEF (boolean, _bfd_find_nearest_line,
-        (bfd *abfd, struct sec  *section,
-         struct symbol_cache_entry  **symbols,bfd_vma offset,
-        CONST char **file, CONST char **func, unsigned int *line));
-  SDEF (int,    _bfd_stat_arch_elt, (bfd *, struct stat *));
-
-  SDEF (int,    _bfd_sizeof_headers, (bfd *, boolean));
-
-  SDEF (void, _bfd_debug_info_start, (bfd *));
-  SDEF (void, _bfd_debug_info_end, (bfd *));
-  SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec  *));
-  SDEF (bfd_byte *, _bfd_get_relocated_section_contents, (bfd*,struct bfd_seclet_struct *, bfd_byte *data));
-  SDEF (boolean,_bfd_relax_section,(bfd *, struct sec *, struct symbol_cache_entry **));
-  SDEF(void, _bfd_coff_swap_aux_in,(
-       bfd            *abfd ,
-       PTR             ext,
-       int             type,
-       int             class ,
-       PTR             in));
-
-  SDEF(void, _bfd_coff_swap_sym_in,(
-       bfd            *abfd ,
-       PTR             ext,
-       PTR             in));
-
-  SDEF(void, _bfd_coff_swap_lineno_in,  (
-       bfd            *abfd,
-       PTR            ext,
-       PTR             in));
-
- SDEF(unsigned int, _bfd_coff_swap_aux_out,(
-       bfd   	*abfd,
-       PTR	in,
-       int    	type,
-       int    	class,
-       PTR    	ext));
-
- SDEF(unsigned int, _bfd_coff_swap_sym_out,(
-      bfd      *abfd,
-      PTR	in,
-      PTR	ext));
-
- SDEF(unsigned int, _bfd_coff_swap_lineno_out,(
-      	bfd   	*abfd,
-      	PTR	in,
-	PTR	ext));
-
- SDEF(unsigned int, _bfd_coff_swap_reloc_out,(
-      	bfd     *abfd,
-     	PTR	src,
-	PTR	dst));
-
- SDEF(unsigned int, _bfd_coff_swap_filehdr_out,(
-      	bfd  	*abfd,
-	PTR 	in,
-	PTR 	out));
-
- SDEF(unsigned int, _bfd_coff_swap_aouthdr_out,(
-      	bfd 	*abfd,
-	PTR 	in,
-	PTR	out));
-
- SDEF(unsigned int, _bfd_coff_swap_scnhdr_out,(
-      	bfd  	*abfd,
-      	PTR	in,
-	PTR	out));
-
-  /* See documentation on reloc types.  */
- SDEF (CONST struct reloc_howto_struct *,
-       reloc_type_lookup,
-       (bfd *abfd, bfd_reloc_code_real_type code));
-
-  /* Complete and utter crock, currently used for the assembler
-    when creating COFF files.  */
- SDEF (asymbol *, _bfd_make_debug_symbol, (
-       bfd *abfd,
-       void *ptr,
-       unsigned long size));
- PTR backend_data;
-} bfd_target;
-bfd_target *EXFUN(bfd_find_target, (CONST char *, bfd *));
-CONST char **EXFUN(bfd_target_list, (void));
-boolean EXFUN(bfd_check_format, (bfd *abfd, bfd_format format));
-boolean EXFUN(bfd_set_format, (bfd *, bfd_format));
-CONST char *EXFUN(bfd_format_string, (bfd_format));
-#endif
diff --git a/debugger/break.c b/debugger/break.c
new file mode 100644
index 0000000..4778bb7
--- /dev/null
+++ b/debugger/break.c
@@ -0,0 +1,83 @@
+
+#include <stdio.h>
+
+#define N_BP 25
+
+struct wine_bp{
+  unsigned long addr;
+  char in_use;
+  char enabled;
+  unsigned char databyte;
+};
+
+static struct wine_bp wbp[N_BP] = {{0,},};
+
+void info_break()
+{
+  int j;
+  fprintf(stderr,"Breakpoint status\n");
+  for(j=0; j<N_BP; j++)
+    if(wbp[j].in_use)
+      fprintf(stderr,"%d: %c %8.8x\n", j, (wbp[j].enabled ? 'y' : 'n'),
+	      wbp[j].addr);
+}
+
+void disable_break(int bpnum)
+{
+  if(bpnum >= N_BP || bpnum < 0)
+    fprintf(stderr,"Breakpoint number out of range\n");
+
+  wbp[bpnum].enabled = 0;
+}
+
+void enable_break(int bpnum)
+{
+  if(bpnum >= N_BP || bpnum < 0)
+    fprintf(stderr,"Breakpoint number out of range\n");
+
+  wbp[bpnum].enabled = 1;
+}
+
+void add_break(unsigned long addr)
+{
+  int j;
+  for(j=0; j<N_BP; j++)
+    if(!wbp[j].in_use)
+      {
+	wbp[j].in_use = 1;
+	wbp[j].enabled = 1;
+	wbp[j].addr = addr;
+	return;
+      }
+  fprintf(stderr,"No more breakpoints\n");
+}
+
+void insert_break(int flag)
+{
+  unsigned char * pnt;
+  int j;
+
+  for(j=0; j<N_BP; j++)
+    if(wbp[j].enabled)
+      {
+	pnt = (unsigned char *) wbp[j].addr;
+	if(flag) {
+	  wbp[j].databyte = *pnt;
+	  *pnt = 0xcc;  /* Change to an int 3 instruction */
+	} else {
+	  *pnt = wbp[j].databyte;
+	}
+      }
+}
+
+/* Get the breakpoint number that we broke upon */
+int get_bpnum(unsigned int addr)
+{
+  int j;
+
+  for(j=0; j<N_BP; j++)
+    if(wbp[j].enabled)
+      if(wbp[j].addr == addr) return j;
+
+  return -1;
+}
diff --git a/debugger/defs.h b/debugger/defs.h
deleted file mode 100644
index e789dd3..0000000
--- a/debugger/defs.h
+++ /dev/null
@@ -1,818 +0,0 @@
-/* Basic, host-specific, and target-specific definitions for GDB.
-   Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#if !defined (DEFS_H)
-#define DEFS_H 1
-
-#include <stdio.h>
-
-/* First include ansidecl.h so we can use the various macro definitions
-   here and in all subsequent file inclusions.  */
-
-#include "ansidecl.h"
-
-/* An address in the program being debugged.  Host byte order.  */
-typedef unsigned int CORE_ADDR;
-
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#define max(a, b) ((a) > (b) ? (a) : (b))
-
-/* The character C++ uses to build identifiers that must be unique from
-   the program's identifiers (such as $this and $$vptr).  */
-#define CPLUS_MARKER '$'	/* May be overridden to '.' for SysV */
-
-#include <errno.h>		/* System call error return status */
-
-extern int quit_flag;
-extern int immediate_quit;
-
-extern void
-quit PARAMS ((void));
-
-#define QUIT { if (quit_flag) quit (); }
-
-/* Command classes are top-level categories into which commands are broken
-   down for "help" purposes.  
-   Notes on classes: class_alias is for alias commands which are not
-   abbreviations of the original command.  class-pseudo is for commands
-   which are not really commands nor help topics ("stop").  */
-
-enum command_class
-{
-  /* Special args to help_list */
-  all_classes = -2, all_commands = -1,
-  /* Classes of commands */
-  no_class = -1, class_run = 0, class_vars, class_stack,
-  class_files, class_support, class_info, class_breakpoint,
-  class_alias, class_obscure, class_user, class_maintenance,
-  class_pseudo
-};
-
-/* the cleanup list records things that have to be undone
-   if an error happens (descriptors to be closed, memory to be freed, etc.)
-   Each link in the chain records a function to call and an
-   argument to give it.
-
-   Use make_cleanup to add an element to the cleanup chain.
-   Use do_cleanups to do all cleanup actions back to a given
-   point in the chain.  Use discard_cleanups to remove cleanups
-   from the chain back to a given point, not doing them.  */
-
-struct cleanup
-{
-  struct cleanup *next;
-  void (*function) PARAMS ((PTR));
-  PTR arg;
-};
-
-/* From blockframe.c */
-
-extern int
-inside_entry_func PARAMS ((CORE_ADDR));
-
-extern int
-inside_entry_file PARAMS ((CORE_ADDR addr));
-
-extern int
-inside_main_func PARAMS ((CORE_ADDR pc));
-
-/* From cplus-dem.c */
-
-extern char *
-cplus_demangle PARAMS ((const char *, int));
-
-extern char *
-cplus_mangle_opname PARAMS ((char *, int));
-
-/* From libmmalloc.a (memory mapped malloc library) */
-
-extern PTR
-mmalloc_attach PARAMS ((int, PTR));
-
-extern PTR
-mmalloc_detach PARAMS ((PTR));
-
-extern PTR
-mmalloc PARAMS ((PTR, long));
-
-extern PTR
-mrealloc PARAMS ((PTR, PTR, long));
-
-extern void
-mfree PARAMS ((PTR, PTR));
-
-extern int
-mmalloc_setkey PARAMS ((PTR, int, PTR));
-
-extern PTR
-mmalloc_getkey PARAMS ((PTR, int));
-
-/* From utils.c */
-
-extern char *
-demangle_and_match PARAMS ((const char *, const char *, int));
-
-extern int
-strcmp_iw PARAMS ((const char *, const char *));
-
-extern char *
-safe_strerror PARAMS ((int));
-
-extern char *
-safe_strsignal PARAMS ((int));
-
-extern void
-init_malloc PARAMS ((PTR));
-
-extern void
-request_quit PARAMS ((int));
-
-extern void
-do_cleanups PARAMS ((struct cleanup *));
-
-extern void
-discard_cleanups PARAMS ((struct cleanup *));
-
-/* The bare make_cleanup function is one of those rare beasts that
-   takes almost any type of function as the first arg and anything that
-   will fit in a "void *" as the second arg.
-
-   Should be, once all calls and called-functions are cleaned up:
-extern struct cleanup *
-make_cleanup PARAMS ((void (*function) (PTR), PTR));
-
-   Until then, lint and/or various type-checking compiler options will
-   complain about make_cleanup calls.  It'd be wrong to just cast things,
-   since the type actually passed when the function is called would be
-   wrong.  */
-
-extern struct cleanup *
-make_cleanup ();
-
-extern struct cleanup *
-save_cleanups PARAMS ((void));
-
-extern void
-restore_cleanups PARAMS ((struct cleanup *));
-
-extern void
-free_current_contents PARAMS ((char **));
-
-extern void
-null_cleanup PARAMS ((char **));
-
-extern int
-myread PARAMS ((int, char *, int));
-
-extern int
-query ();
-
-extern void
-wrap_here PARAMS ((char *));
-
-extern void
-reinitialize_more_filter PARAMS ((void));
-
-extern int
-print_insn PARAMS ((CORE_ADDR, CORE_ADDR, FILE *, int));
-
-extern void
-fputs_filtered PARAMS ((const char *, FILE *));
-
-extern void
-puts_filtered PARAMS ((char *));
-
-extern void
-vfprintf_filtered ();
-
-extern void
-fprintf_filtered ();
-
-extern void
-fprintfi_filtered ();
-
-extern void
-printf_filtered ();
-
-extern void
-printfi_filtered ();
-
-extern void
-print_spaces PARAMS ((int, FILE *));
-
-extern void
-print_spaces_filtered PARAMS ((int, FILE *));
-
-extern char *
-n_spaces PARAMS ((int));
-
-extern void
-printchar PARAMS ((int, FILE *, int));
-
-extern char *
-strdup_demangled PARAMS ((const char *));
-
-extern void
-fprint_symbol PARAMS ((FILE *, char *));
-
-extern void
-fputs_demangled PARAMS ((char *, FILE *, int));
-
-extern void
-perror_with_name PARAMS ((char *));
-
-extern void
-print_sys_errmsg PARAMS ((char *, int));
-
-/* From regex.c */
-
-extern char *
-re_comp PARAMS ((char *));
-
-/* From symfile.c */
-
-extern void
-symbol_file_command PARAMS ((char *, int));
-
-/* From main.c */
-
-extern char *
-skip_quoted PARAMS ((char *));
-
-extern char *
-gdb_readline PARAMS ((char *));
-
-extern char *
-command_line_input PARAMS ((char *, int));
-
-extern void
-print_prompt PARAMS ((void));
-
-extern int
-batch_mode PARAMS ((void));
-
-extern int
-input_from_terminal_p PARAMS ((void));
-
-extern int
-catch_errors PARAMS ((int (*) (char *), char *, char *));
-
-/* From printcmd.c */
-
-extern void
-set_next_address PARAMS ((CORE_ADDR));
-
-extern void
-print_address_symbolic PARAMS ((CORE_ADDR, FILE *, int, char *));
-
-extern void
-print_address PARAMS ((CORE_ADDR, FILE *));
-
-/* From source.c */
-
-extern int
-openp PARAMS ((char *, int, char *, int, int, char **));
-
-extern void
-mod_path PARAMS ((char *, char **));
-
-extern void
-directory_command PARAMS ((char *, int));
-
-extern void
-init_source_path PARAMS ((void));
-
-/* From findvar.c */
-
-extern int
-read_relative_register_raw_bytes PARAMS ((int, char *));
-
-/* From readline (but not in any readline .h files).  */
-
-extern char *
-tilde_expand PARAMS ((char *));
-
-/* Structure for saved commands lines
-   (for breakpoints, defined commands, etc).  */
-
-struct command_line
-{
-  struct command_line *next;
-  char *line;
-};
-
-extern struct command_line *
-read_command_lines PARAMS ((void));
-
-extern void
-free_command_lines PARAMS ((struct command_line **));
-
-/* String containing the current directory (what getwd would return).  */
-
-extern char *current_directory;
-
-/* Default radixes for input and output.  Only some values supported.  */
-extern unsigned input_radix;
-extern unsigned output_radix;
-
-/* Baud rate specified for communication with serial target systems.  */
-extern char *baud_rate;
-
-/* Languages represented in the symbol table and elsewhere. */
-
-enum language 
-{
-   language_unknown, 		/* Language not known */
-   language_auto,		/* Placeholder for automatic setting */
-   language_c, 			/* C */
-   language_cplus, 		/* C++ */
-   language_m2			/* Modula-2 */
-};
-
-/* Return a format string for printf that will print a number in the local
-   (language-specific) hexadecimal format.  Result is static and is
-   overwritten by the next call.  local_hex_format_custom takes printf
-   options like "08" or "l" (to produce e.g. %08x or %lx).  */
-
-#define local_hex_format() (current_language->la_hex_format)
-
-extern char *
-local_hex_format_custom PARAMS ((char *));	/* language.c */
-
-/* Return a string that contains a number formatted in the local
-   (language-specific) hexadecimal format.  Result is static and is
-   overwritten by the next call.  local_hex_string_custom takes printf
-   options like "08" or "l".  */
-
-extern char *
-local_hex_string PARAMS ((int));		/* language.c */
-
-extern char *
-local_hex_string_custom PARAMS ((int, char *));	/* language.c */
-
-
-/* Host machine definition.  This will be a symlink to one of the
-   xm-*.h files, built by the `configure' script.  */
-
-#include "xm.h"
-
-/* If the xm.h file did not define the mode string used to open the
-   files, assume that binary files are opened the same way as text
-   files */
-#ifndef FOPEN_RB
-#include "fopen-same.h"
-#endif
-
-/*
- * Allow things in gdb to be declared "const".  If compiling ANSI, it
- * just works.  If compiling with gcc but non-ansi, redefine to __const__.
- * If non-ansi, non-gcc, then eliminate "const" entirely, making those
- * objects be read-write rather than read-only.
- */
-
-#ifndef const
-#ifndef __STDC__
-# ifdef __GNUC__
-#  define const __const__
-# else
-#  define const /*nothing*/
-# endif /* GNUC */
-#endif /* STDC */
-#endif /* const */
-
-#ifndef volatile
-#ifndef __STDC__
-# ifdef __GNUC__
-#  define volatile __volatile__
-# else
-#  define volatile /*nothing*/
-# endif /* GNUC */
-#endif /* STDC */
-#endif /* volatile */
-
-/* Some compilers (many AT&T SVR4 compilers for instance), do not accept
-   declarations of functions that never return (exit for instance) as
-   "volatile void".  For such compilers "NORETURN" can be defined away
-   to keep them happy */
-
-#ifndef NORETURN
-# ifdef __lucid
-#   define NORETURN /*nothing*/
-# else
-#   define NORETURN volatile
-# endif
-#endif
-
-/* Defaults for system-wide constants (if not defined by xm.h, we fake it).  */
-
-#if !defined (UINT_MAX)
-#define UINT_MAX 0xffffffff
-#endif
-
-#if !defined (LONG_MAX)
-#define LONG_MAX 0x7fffffff
-#endif
-
-#if !defined (INT_MAX)
-#define INT_MAX 0x7fffffff
-#endif
-
-#if !defined (INT_MIN)
-/* Two's complement, 32 bit.  */
-#define INT_MIN -0x80000000
-#endif
-
-/* Number of bits in a char or unsigned char for the target machine.
-   Just like CHAR_BIT in <limits.h> but describes the target machine.  */
-#if !defined (TARGET_CHAR_BIT)
-#define TARGET_CHAR_BIT 8
-#endif
-
-/* Number of bits in a short or unsigned short for the target machine. */
-#if !defined (TARGET_SHORT_BIT)
-#define TARGET_SHORT_BIT (sizeof (short) * TARGET_CHAR_BIT)
-#endif
-
-/* Number of bits in an int or unsigned int for the target machine. */
-#if !defined (TARGET_INT_BIT)
-#define TARGET_INT_BIT (sizeof (int) * TARGET_CHAR_BIT)
-#endif
-
-/* Number of bits in a long or unsigned long for the target machine. */
-#if !defined (TARGET_LONG_BIT)
-#define TARGET_LONG_BIT (sizeof (long) * TARGET_CHAR_BIT)
-#endif
-
-/* Number of bits in a long long or unsigned long long for the target machine. */
-#if !defined (TARGET_LONG_LONG_BIT)
-#define TARGET_LONG_LONG_BIT (2 * TARGET_LONG_BIT)
-#endif
-
-/* Number of bits in a float for the target machine. */
-#if !defined (TARGET_FLOAT_BIT)
-#define TARGET_FLOAT_BIT (sizeof (float) * TARGET_CHAR_BIT)
-#endif
-
-/* Number of bits in a double for the target machine. */
-#if !defined (TARGET_DOUBLE_BIT)
-#define TARGET_DOUBLE_BIT (sizeof (double) * TARGET_CHAR_BIT)
-#endif
-
-/* Number of bits in a long double for the target machine. */
-#if !defined (TARGET_LONG_DOUBLE_BIT)
-#define TARGET_LONG_DOUBLE_BIT (2 * TARGET_DOUBLE_BIT)
-#endif
-
-/* Number of bits in a "complex" for the target machine. */
-#if !defined (TARGET_COMPLEX_BIT)
-#define TARGET_COMPLEX_BIT (2 * TARGET_FLOAT_BIT)
-#endif
-
-/* Number of bits in a "double complex" for the target machine. */
-#if !defined (TARGET_DOUBLE_COMPLEX_BIT)
-#define TARGET_DOUBLE_COMPLEX_BIT (2 * TARGET_DOUBLE_BIT)
-#endif
-
-/* Number of bits in a pointer for the target machine */
-#if !defined (TARGET_PTR_BIT)
-#define TARGET_PTR_BIT TARGET_INT_BIT
-#endif
-
-/* Convert a LONGEST to an int.  This is used in contexts (e.g. number
-   of arguments to a function, number in a value history, register
-   number, etc.) where the value must not be larger than can fit
-   in an int.  */
-#if !defined (longest_to_int)
-#if defined (LONG_LONG)
-#define longest_to_int(x) (((x) > INT_MAX || (x) < INT_MIN) \
-			   ? (error ("Value out of range."),0) : (int) (x))
-#else /* No LONG_LONG.  */
-/* Assume sizeof (int) == sizeof (long).  */
-#define longest_to_int(x) ((int) (x))
-#endif /* No LONG_LONG.  */
-#endif /* No longest_to_int.  */
-
-/* This should not be a typedef, because "unsigned LONGEST" needs
-   to work. LONG_LONG is defined if the host has "long long".  */
-
-#ifndef LONGEST
-# ifdef LONG_LONG
-#  define LONGEST long long
-# else
-#  define LONGEST long
-# endif
-#endif
-
-/* Assorted functions we can declare, now that const and volatile are 
-   defined.  */
-
-extern char *
-savestring PARAMS ((const char *, int));
-
-extern char *
-msavestring PARAMS ((void *, const char *, int));
-
-extern char *
-strsave PARAMS ((const char *));
-
-extern char *
-mstrsave PARAMS ((void *, const char *));
-
-extern char *
-concat PARAMS ((char *, ...));
-
-extern PTR
-xmalloc PARAMS ((long));
-
-extern PTR
-xrealloc PARAMS ((PTR, long));
-
-extern PTR
-xmmalloc PARAMS ((PTR, long));
-
-extern PTR
-xmrealloc PARAMS ((PTR, PTR, long));
-
-extern PTR
-mmalloc PARAMS ((PTR, long));
-
-extern PTR
-mrealloc PARAMS ((PTR, PTR, long));
-
-extern void
-mfree PARAMS ((PTR, PTR));
-
-extern int
-mmcheck PARAMS ((PTR, void (*) (void)));
-
-extern int
-mmtrace PARAMS ((void));
-
-extern int
-parse_escape PARAMS ((char **));
-
-extern const char * const reg_names[];
-
-extern NORETURN void			/* Does not return to the caller.  */
-error ();
-
-extern NORETURN void			/* Does not return to the caller.  */
-fatal ();
-
-extern NORETURN void			/* Not specified as volatile in ... */
-exit PARAMS ((int));			/* 4.10.4.3 */
-
-extern NORETURN void			/* Does not return to the caller.  */
-nomem PARAMS ((long));
-
-extern NORETURN void			/* Does not return to the caller.  */
-return_to_top_level PARAMS ((void));
-
-extern void
-warning_setup PARAMS ((void));
-
-extern void
-warning ();
-
-/* Global functions from other, non-gdb GNU thingies (libiberty for
-   instance) */
-
-extern char *
-basename PARAMS ((char *));
-
-extern char *
-getenv PARAMS ((const char *));
-
-extern char **
-buildargv PARAMS ((char *));
-
-extern void
-freeargv PARAMS ((char **));
-
-extern char *
-strerrno PARAMS ((int));
-
-extern char *
-strsigno PARAMS ((int));
-
-extern int
-errno_max PARAMS ((void));
-
-extern int
-signo_max PARAMS ((void));
-
-extern int
-strtoerrno PARAMS ((char *));
-
-extern int
-strtosigno PARAMS ((char *));
-
-extern char *
-strsignal PARAMS ((int));
-
-/* From other system libraries */
-
-#ifndef PSIGNAL_IN_SIGNAL_H
-extern void
-psignal PARAMS ((unsigned, char *));
-#endif
-
-/* For now, we can't include <stdlib.h> because it conflicts with
-   "../include/getopt.h".  (FIXME)
-
-   However, if a function is defined in the ANSI C standard and a prototype
-   for that function is defined and visible in any header file in an ANSI
-   conforming environment, then that prototype must match the definition in
-   the ANSI standard.  So we can just duplicate them here without conflict,
-   since they must be the same in all conforming ANSI environments.  If
-   these cause problems, then the environment is not ANSI conformant. */
-   
-#ifdef __STDC__
-#include <stddef.h>
-#endif
-
-extern int
-fclose PARAMS ((FILE *stream));				/* 4.9.5.1 */
-
-extern void
-perror PARAMS ((const char *));				/* 4.9.10.4 */
-
-extern double
-atof PARAMS ((const char *nptr));			/* 4.10.1.1 */
-
-extern int
-atoi PARAMS ((const char *));				/* 4.10.1.2 */
-
-#ifndef MALLOC_INCOMPATIBLE
-
-extern PTR
-malloc PARAMS ((size_t size));                          /* 4.10.3.3 */
-
-extern PTR
-realloc PARAMS ((void *ptr, size_t size));              /* 4.10.3.4 */
-
-extern void
-free PARAMS ((void *));					/* 4.10.3.2 */
-
-#endif	/* MALLOC_INCOMPATIBLE */
-
-extern void
-qsort PARAMS ((void *base, size_t nmemb,		/* 4.10.5.2 */
-	       size_t size,
-	       int (*comp)(const void *, const void *)));
-
-#ifndef	MEM_FNS_DECLARED	/* Some non-ANSI use void *, not char *.  */
-extern PTR
-memcpy PARAMS ((void *, const void *, size_t));		/* 4.11.2.1 */
-#endif
-
-extern int
-memcmp PARAMS ((const void *, const void *, size_t));	/* 4.11.4.1 */
-
-extern char *
-strchr PARAMS ((const char *, int));			/* 4.11.5.2 */
-
-extern char *
-strrchr PARAMS ((const char *, int));			/* 4.11.5.5 */
-
-extern char *
-strstr PARAMS ((const char *, const char *));		/* 4.11.5.7 */
-
-extern char *
-strtok PARAMS ((char *, const char *));			/* 4.11.5.8 */
-
-#ifndef	MEM_FNS_DECLARED	/* Some non-ANSI use void *, not char *.  */
-extern PTR
-memset PARAMS ((void *, int, size_t));			/* 4.11.6.1 */
-#endif
-
-extern char *
-strerror PARAMS ((int));				/* 4.11.6.2 */
-
-/* Various possibilities for alloca.  */
-#ifndef alloca
-# ifdef __GNUC__
-#  define alloca __builtin_alloca
-# else
-#  ifdef sparc
-#   include <alloca.h>		/* NOTE:  Doesn't declare alloca() */
-#  endif
-#  ifdef __STDC__
-   extern void *alloca (size_t);
-#  else /* __STDC__ */
-   extern char *alloca ();
-#  endif
-# endif
-#endif
-
-/* TARGET_BYTE_ORDER and HOST_BYTE_ORDER must be defined to one of these.  */
-
-#if !defined (BIG_ENDIAN)
-#define BIG_ENDIAN 4321
-#endif
-
-#if !defined (LITTLE_ENDIAN)
-#define LITTLE_ENDIAN 1234
-#endif
-
-/* Target-system-dependent parameters for GDB.
-
-   The standard thing is to include defs.h.  However, files that are
-   specific to a particular target can define TM_FILE_OVERRIDE before
-   including defs.h, then can include any particular tm-file they desire.  */
-
-/* Target machine definition.  This will be a symlink to one of the
-   tm-*.h files, built by the `configure' script.  */
-
-#ifndef TM_FILE_OVERRIDE
-#include "tm.h"
-#endif
-
-/* The bit byte-order has to do just with numbering of bits in
-   debugging symbols and such.  Conceptually, it's quite separate
-   from byte/word byte order.  */
-
-#if !defined (BITS_BIG_ENDIAN)
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-#define BITS_BIG_ENDIAN 1
-#endif /* Big endian.  */
-
-#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
-#define BITS_BIG_ENDIAN 0
-#endif /* Little endian.  */
-#endif /* BITS_BIG_ENDIAN not defined.  */
-
-/* Swap LEN bytes at BUFFER between target and host byte-order.  */
-#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
-#define SWAP_TARGET_AND_HOST(buffer,len)
-#else /* Target and host byte order differ.  */
-#define SWAP_TARGET_AND_HOST(buffer,len) \
-  {	       	       	       	       	       	       	       	       	 \
-    char tmp;								 \
-    char *p = (char *)(buffer);						 \
-    char *q = ((char *)(buffer)) + len - 1;		   		 \
-    for (; p < q; p++, q--)				 		 \
-      {									 \
-        tmp = *q;							 \
-        *q = *p;							 \
-        *p = tmp;							 \
-      }									 \
-  }
-#endif /* Target and host byte order differ.  */
-
-/* On some machines there are bits in addresses which are not really
-   part of the address, but are used by the kernel, the hardware, etc.
-   for special purposes.  ADDR_BITS_REMOVE takes out any such bits
-   so we get a "real" address such as one would find in a symbol
-   table.  ADDR_BITS_SET sets those bits the way the system wants
-   them.  */
-#if !defined (ADDR_BITS_REMOVE)
-#define ADDR_BITS_REMOVE(addr) (addr)
-#define ADDR_BITS_SET(addr) (addr)
-#endif /* No ADDR_BITS_REMOVE.  */
-
-/* From valops.c */
-
-extern CORE_ADDR
-push_bytes PARAMS ((CORE_ADDR, char *, int));
-
-/* In some modules, we don't have a definition of REGISTER_TYPE yet, so we
-   must avoid prototyping this function for now.  FIXME.  Should be:
-extern CORE_ADDR
-push_word PARAMS ((CORE_ADDR, REGISTER_TYPE));
- */
-extern CORE_ADDR
-push_word ();
-
-/* Some parts of gdb might be considered optional, in the sense that they
-   are not essential for being able to build a working, usable debugger
-   for a specific environment.  For example, the maintenance commands
-   are there for the benefit of gdb maintainers.  As another example,
-   some environments really don't need gdb's that are able to read N
-   different object file formats.  In order to make it possible (but
-   not necessarily recommended) to build "stripped down" versions of
-   gdb, the following defines control selective compilation of those
-   parts of gdb which can be safely left out when necessary.  Note that
-   the default is to include everything. */
-
-#ifndef MAINTENANCE_CMDS
-#define MAINTENANCE_CMDS 1
-#endif
-
-#endif /* !defined (DEFS_H) */
diff --git a/debugger/fopen-same.h b/debugger/fopen-same.h
deleted file mode 100644
index 0f37529..0000000
--- a/debugger/fopen-same.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Macros for the 'type' part of an fopen, freopen or fdopen. 
-
-	<Read|Write>[Update]<Binary file|text file>
-
-   This version is for "same" systems, where text and binary files are
-   the same.  An example is Unix.  Many Unix systems could also add a
-   "b" to the string, indicating binary files, but some reject this
-   (and thereby don't conform to ANSI C, but what else is new?).
-
-   This file is designed for inclusion by host-dependent .h files.  No
-   user application should include it directly, since that would make
-   the application unable to be configured for both "same" and "binary"
-   variant systems.  */
-
-#define FOPEN_RB	"r"
-#define FOPEN_WB 	"w"
-#define FOPEN_AB 	"a"
-#define FOPEN_RUB 	"r+"
-#define FOPEN_WUB 	"w+"
-#define FOPEN_AUB 	"a+"
-
-#define FOPEN_RT	"r"
-#define FOPEN_WT 	"w"
-#define FOPEN_AT 	"a"
-#define FOPEN_RUT 	"r+"
-#define FOPEN_WUT 	"w+"
-#define FOPEN_AUT 	"a+"
diff --git a/debugger/gdbcore.h b/debugger/gdbcore.h
deleted file mode 100644
index e9c8466..0000000
--- a/debugger/gdbcore.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Machine independent variables that describe the core file under GDB.
-   Copyright 1986, 1987, 1989, 1990, 1992 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-/* Interface routines for core, executable, etc.  */
-
-#if !defined (GDBCORE_H)
-#define GDBCORE_H 1
-
-#include "bfd.h"		/* Binary File Description */
-
-/* Return the name of the executable file as a string.
-   ERR nonzero means get error if there is none specified;
-   otherwise return 0 in that case.  */
-
-extern char *
-get_exec_file PARAMS ((int err));
-
-/* Nonzero if there is a core file.  */
-
-extern int
-have_core_file_p PARAMS ((void));
-
-/* Read "memory data" from whatever target or inferior we have. 
-   Returns zero if successful, errno value if not.  EIO is used
-   for address out of bounds.  If breakpoints are inserted, returns
-   shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
-
-extern int
-read_memory_nobpt PARAMS ((CORE_ADDR memaddr, char *myaddr, unsigned len));
-
-/* Report a memory error with error().  */
-
-extern void
-memory_error PARAMS ((int status, CORE_ADDR memaddr));
-
-/* Like target_read_memory, but report an error if can't read.  */
-
-extern void
-read_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
-
-/* Read an integer from debugged memory, given address and number of bytes.  */
-
-extern long
-read_memory_integer PARAMS ((CORE_ADDR memaddr, int len));
-
-/* If this is prototyped, need to deal with void* vs. char*.  */
-
-extern void
-write_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
-
-/* Hook for `exec_file_command' command to call.  */
-
-extern void (*exec_file_display_hook) PARAMS ((char *filename));
-   
-extern void
-specify_exec_file_hook PARAMS ((void (*hook) (char *filename)));
-
-/* Binary File Diddlers for the exec and core files */
-extern bfd *core_bfd;
-extern bfd *exec_bfd;
-
-/* Whether to open exec and core files read-only or read-write.  */
-
-extern int write_files;
-
-extern void
-core_file_command PARAMS ((char *filename, int from_tty));
-
-extern void
-exec_file_command PARAMS ((char *filename, int from_tty));
-
-extern void
-validate_files PARAMS ((void));
-
-extern unsigned int
-register_addr PARAMS ((int regno, int blockend));
-
-extern int
-xfer_core_file PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
-
-extern void
-fetch_core_registers PARAMS ((char *core_reg_sect, unsigned core_reg_size,
-			      int which, unsigned int reg_addr));
-
-extern void
-registers_fetched PARAMS ((void));
-
-#if !defined (KERNEL_U_ADDR)
-extern CORE_ADDR kernel_u_addr;
-#define KERNEL_U_ADDR kernel_u_addr
-#endif
-
-/* The target vector for core files */
-extern struct target_ops core_ops;
-
- /* target vector functions called directly from elsewhere */
-void
-core_open PARAMS ((char *, int));
-
-void
-core_detach PARAMS ((char *, int));
-
-#endif	/* !defined (GDBCORE_H) */
diff --git a/debugger/opcodes/Imakefile b/debugger/opcodes/Imakefile
new file mode 100644
index 0000000..1178f76
--- /dev/null
+++ b/debugger/opcodes/Imakefile
@@ -0,0 +1,29 @@
+#include "../../Wine.tmpl"
+
+MODULE = opcodes
+
+#ifdef i386
+#define xi386 1
+#undef i386
+#endif
+
+SRCS = \
+	dis-buf.c \
+	i386-dis.c
+
+OBJS = \
+	dis-buf.o \
+	i386-dis.o
+
+#ifdef xi386
+#define i386 1
+#undef xi386
+#endif
+
+WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+DependTarget()
+CleanTarget()
+
+includes::
+
+install::
diff --git a/debugger/ansidecl.h b/debugger/opcodes/ansidecl.h
similarity index 61%
rename from debugger/ansidecl.h
rename to debugger/opcodes/ansidecl.h
index 68e4d75..3c0dcb3 100644
--- a/debugger/ansidecl.h
+++ b/debugger/opcodes/ansidecl.h
@@ -1,5 +1,5 @@
 /* ANSI and traditional C compatability macros
-   Copyright 1991 Free Software Foundation, Inc.
+   Copyright 1991, 1992 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 This program is free software; you can redistribute it and/or modify
@@ -24,12 +24,14 @@
    -----	---- - ----------	----------- - ----------
    PTR		`void *'		`char *'
    LONG_DOUBLE	`long double'		`double'
-   CONST	`const'			`'
    VOLATILE	`volatile'		`'
    SIGNED	`signed'		`'
    PTRCONST	`void *const'		`char *'
+   ANSI_PROTOTYPES  1			not defined
 
-   DEFUN(name, arglist, args)
+   CONST is also defined, but is obsolete.  Just use const.
+
+   DEFUN (name, arglist, args)
 
 	Defines function NAME.
 
@@ -41,19 +43,38 @@
 	be separated with `AND'.  For functions with a variable number of
 	arguments, the last thing listed should be `DOTS'.
 
-   DEFUN_VOID(name)
+   DEFUN_VOID (name)
 
 	Defines a function NAME, which takes no arguments.
 
-   EXFUN(name, prototype)
+   obsolete --     EXFUN (name, (prototype))	-- obsolete.
 
-	Is used in an external function declaration.
-	In ANSI C it is `NAMEPROTOTYPE' (so PROTOTYPE should be enclosed in
+	Replaced by PARAMS.  Do not use; will disappear someday soon.
+	Was used in external function declarations.
+	In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
 	parentheses).  In traditional C it is `NAME()'.
-	For a function that takes no arguments, PROTOTYPE should be `(NOARGS)'.
+	For a function that takes no arguments, PROTOTYPE should be `(void)'.
+
+    PARAMS ((args))
+
+	We could use the EXFUN macro to handle prototype declarations, but
+	the name is misleading and the result is ugly.  So we just define a
+	simple macro to handle the parameter lists, as in:
+
+	      static int foo PARAMS ((int, char));
+
+	This produces:  `static int foo();' or `static int foo (int, char);'
+
+	EXFUN would have done it like this:
+
+	      static int EXFUN (foo, (int, char));
+
+	but the function is not external...and it's hard to visually parse
+	the function name out of the mess.   EXFUN should be considered
+	obsolete; new code should be written to use PARAMS.
 
     For example:
-	extern int EXFUN(printf, (CONST char *format DOTS));
+	extern int printf PARAMS ((CONST char *format DOTS));
 	int DEFUN(fprintf, (stream, format),
 		  FILE *stream AND CONST char *format DOTS) { ... }
 	void DEFUN_VOID(abort) { ... }
@@ -69,7 +90,10 @@
 /* LINTLIBRARY */
 
 
-#ifdef	__STDC__
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4))
+/* All known AIX compilers implement these things (but don't always
+   define __STDC__).  The RISC/OS MIPS compiler defines these things
+   in SVR4 mode, but does not define __STDC__.  */
 
 #define	PTR		void *
 #define	PTRCONST	void *CONST
@@ -84,24 +108,11 @@
 
 #define	EXFUN(name, proto)		name proto
 #define	DEFUN(name, arglist, args)	name(args)
-#define	DEFUN_VOID(name)		name(NOARGS)
+#define	DEFUN_VOID(name)		name(void)
 
-#define PROTO(type, name, arglist) type name arglist
-
-/* We could use the EXFUN macro to handle prototypes, but
-   the name is misleading and the result is ugly.  So just define a
-   simple macro to handle the parameter lists, as in:
-
-	static int foo PARAMS ((int, char));
-
-   EXFUN would do it like this:
-
-	static int EXFUN (foo, (int, char));
-
-   but the function is not external...  EXFUN should be considered
-   obsolete, and new code written to use PARAMS.  */
-
-#define PARAMS(paramlist) paramlist
+#define PROTO(type, name, arglist)	type name arglist
+#define PARAMS(paramlist)		paramlist
+#define ANSI_PROTOTYPES			1
 
 #else	/* Not ANSI C.  */
 
@@ -112,6 +123,9 @@
 #define	AND		;
 #define	NOARGS
 #define	CONST
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define	const
+#endif
 #define	VOLATILE
 #define	SIGNED
 #define	DOTS
diff --git a/debugger/opcodes/bfd.h b/debugger/opcodes/bfd.h
new file mode 100644
index 0000000..ed068d9
--- /dev/null
+++ b/debugger/opcodes/bfd.h
@@ -0,0 +1,2171 @@
+/* Main header file for the bfd library -- portable access to object files.
+   Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+** NOTE: bfd.h and bfd-in2.h are GENERATED files.  Don't change them;
+** instead, change bfd-in.h or the other BFD source files processed to
+** generate these files.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* bfd.h -- The only header file required by users of the bfd library 
+
+The bfd.h file is generated from bfd-in.h and various .c files; if you
+change it, your changes will probably be lost.
+
+All the prototypes and definitions following the comment "THE FOLLOWING
+IS EXTRACTED FROM THE SOURCE" are extracted from the source files for
+BFD.  If you change it, someone oneday will extract it from the source
+again, and your changes will be lost.  To save yourself from this bind,
+change the definitions in the source in the bfd directory.  Type "make
+docs" and then "make headers" in that directory, and magically this file
+will change to reflect your changes.
+
+If you don't have the tools to perform the extraction, then you are
+safe from someone on your system trampling over your header files.
+You should still maintain the equivalence between the source and this
+file though; every change you make to the .c file should be reflected
+here.  */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#include "ansidecl.h"
+#include "obstack.h"
+
+/* These two lines get substitutions done by commands in Makefile.in.  */
+#define BFD_VERSION   "cygnus-2.3"
+#define BFD_ARCH_SIZE 32
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* 64-bit type definition (if any) from bfd's sysdep.h goes here */
+
+
+/* forward declaration */
+typedef struct _bfd bfd;
+
+/* To squelch erroneous compiler warnings ("illegal pointer
+   combination") from the SVR3 compiler, we would like to typedef
+   boolean to int (it doesn't like functions which return boolean.
+   Making sure they are never implicitly declared to return int
+   doesn't seem to help).  But this file is not configured based on
+   the host.  */
+/* General rules: functions which are boolean return true on success
+   and false on failure (unless they're a predicate).   -- bfd.doc */
+/* I'm sure this is going to break something and someone is going to
+   force me to change it. */
+/* typedef enum boolean {false, true} boolean; */
+/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h>  -fnf */
+/* It gets worse if the host also defines a true/false enum... -sts */
+#ifndef TRUE_FALSE_ALREADY_DEFINED
+typedef enum bfd_boolean {false, true} boolean;
+#define BFD_TRUE_FALSE
+#else
+typedef enum bfd_boolean {bfd_false, bfd_true} boolean;
+#endif
+
+/* A pointer to a position in a file.  */
+/* FIXME:  This should be using off_t from <sys/types.h>.
+   For now, try to avoid breaking stuff by not including <sys/types.h> here.
+   This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
+   Probably the best long-term answer is to avoid using file_ptr AND off_t 
+   in this header file, and to handle this in the BFD implementation
+   rather than in its interface.  */
+/* typedef off_t	file_ptr; */
+typedef long int file_ptr;
+
+/* Support for different sizes of target format ints and addresses.  If the
+   host implements 64-bit values, it defines BFD_HOST_64_BIT to be the appropriate
+   type.  Otherwise, this code will fall back on gcc's "long long" type if gcc
+   is being used.  BFD_HOST_64_BIT must be defined in such a way as to be a valid
+   type name by itself or with "unsigned" prefixed.  It should be a signed
+   type by itself.
+
+   If neither is the case, then compilation will fail if 64-bit targets are
+   requested.  If you don't request any 64-bit targets, you should be safe. */
+
+#ifdef	BFD64
+
+#if defined (__GNUC__) && !defined (BFD_HOST_64_BIT)
+#define BFD_HOST_64_BIT long long
+typedef BFD_HOST_64_BIT int64_type;
+typedef unsigned BFD_HOST_64_BIT uint64_type;
+#endif
+
+#if !defined (uint64_type) && defined (__GNUC__)
+#define uint64_type unsigned long long
+#define int64_type long long
+#endif
+#ifndef uint64_typeLOW
+#define uint64_typeLOW(x) ((unsigned long)(((x) & 0xffffffff)))
+#define uint64_typeHIGH(x) ((unsigned long)(((x) >> 32) & 0xffffffff))
+#endif
+
+typedef unsigned BFD_HOST_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef unsigned BFD_HOST_64_BIT bfd_size_type;
+typedef unsigned BFD_HOST_64_BIT symvalue;
+#ifndef fprintf_vma
+#define fprintf_vma(s,x) \
+		fprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x))
+#define sprintf_vma(s,x) \
+		sprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x))
+#endif
+#else /* not BFD64  */
+
+/* Represent a target address.  Also used as a generic unsigned type
+   which is guaranteed to be big enough to hold any arithmetic types
+   we need to deal with.  */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+   arithmetic types we need to deal with.  Can be assumed to be compatible
+   with bfd_vma in the same way that signed and unsigned ints are compatible
+   (as parameters, in assignment, etc).  */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s.  */
+#define fprintf_vma(s,x) fprintf(s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf(s, "%08lx", x)
+#endif /* not BFD64  */
+#define printf_vma(x) fprintf_vma(stdout,x)
+
+typedef unsigned int flagword;	/* 32 bits of flags */
+
+/** File formats */
+
+typedef enum bfd_format {
+	      bfd_unknown = 0,	/* file format is unknown */
+	      bfd_object,	/* linker/assember/compiler output */
+	      bfd_archive,	/* object archive file */
+	      bfd_core,		/* core dump */
+	      bfd_type_end}	/* marks the end; don't use it! */
+         bfd_format;
+
+/* Values that may appear in the flags field of a BFD.  These also
+   appear in the object_flags field of the bfd_target structure, where
+   they indicate the set of flags used by that backend (not all flags
+   are meaningful for all object file formats) (FIXME: at the moment,
+   the object_flags values have mostly just been copied from backend
+   to another, and are not necessarily correct).  */
+
+/* No flags.  */
+#define NO_FLAGS    	0x00
+
+/* BFD contains relocation entries.  */
+#define HAS_RELOC   	0x01
+
+/* BFD is directly executable.  */
+#define EXEC_P      	0x02
+
+/* BFD has line number information (basically used for F_LNNO in a
+   COFF header).  */
+#define HAS_LINENO  	0x04
+
+/* BFD has debugging information.  */
+#define HAS_DEBUG   	0x08
+
+/* BFD has symbols.  */
+#define HAS_SYMS    	0x10
+
+/* BFD has local symbols (basically used for F_LSYMS in a COFF
+   header).  */
+#define HAS_LOCALS  	0x20
+
+/* BFD is a dynamic object.  */
+#define DYNAMIC     	0x40
+
+/* Text section is write protected (if D_PAGED is not set, this is
+   like an a.out NMAGIC file) (the linker sets this by default, but
+   clears it for -r or -N).  */
+#define WP_TEXT     	0x80
+
+/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
+   linker sets this by default, but clears it for -r or -n or -N).  */
+#define D_PAGED     	0x100
+
+/* BFD is relaxable (this means that bfd_relax_section may be able to
+   do something).  */
+#define BFD_IS_RELAXABLE 0x200
+
+/* symbols and relocation */
+
+/* A count of carsyms (canonical archive symbols).  */
+typedef unsigned long symindex;
+
+#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
+
+/* General purpose part of a symbol X;
+   target specific parts are in libcoff.h, libaout.h, etc.  */
+
+#define bfd_get_section(x) ((x)->section)
+#define bfd_get_output_section(x) ((x)->section->output_section)
+#define bfd_set_section(x,y) ((x)->section) = (y)
+#define bfd_asymbol_base(x) ((x)->section->vma)
+#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value)
+#define bfd_asymbol_name(x) ((x)->name)
+/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/
+#define bfd_asymbol_bfd(x) ((x)->the_bfd)
+#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour)
+
+/* A canonical archive symbol.  */
+/* This is a type pun with struct ranlib on purpose! */
+typedef struct carsym {
+  char *name;
+  file_ptr file_offset;		/* look here to find the file */
+} carsym;			/* to make these you call a carsymogen */
+
+  
+/* Used in generating armaps (archive tables of contents).
+   Perhaps just a forward definition would do? */
+struct orl {			/* output ranlib */
+  char **name;			/* symbol name */ 
+  file_ptr pos;			/* bfd* or file position */
+  int namidx;			/* index into string table */
+};
+
+
+
+/* Linenumber stuff */
+typedef struct lineno_cache_entry {
+  unsigned int line_number;	/* Linenumber from start of function*/  
+  union {
+    struct symbol_cache_entry *sym; /* Function name */
+    unsigned long offset;	/* Offset into section */
+  } u;
+} alent;
+
+/* object and core file sections */
+
+
+#define	align_power(addr, align)	\
+	( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
+
+typedef struct sec *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
+#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
+#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
+#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
+#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
+#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
+#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = true), true)
+#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true)
+#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true)
+
+typedef struct stat stat_type; 
+
+typedef enum bfd_print_symbol
+{ 
+  bfd_print_symbol_name,
+  bfd_print_symbol_more,
+  bfd_print_symbol_all
+} bfd_print_symbol_type;
+    
+/* Information about a symbol that nm needs.  */
+
+typedef struct _symbol_info
+{
+  symvalue value;
+  char type;
+  CONST char *name;            /* Symbol name.  */
+  char stab_other;             /* Unused. */
+  short stab_desc;             /* Info for N_TYPE.  */
+  CONST char *stab_name;
+} symbol_info;
+
+/* Hash table routines.  There is no way to free up a hash table.  */
+
+/* An element in the hash table.  Most uses will actually use a larger
+   structure, and an instance of this will be the first field.  */
+
+struct bfd_hash_entry
+{
+  /* Next entry for this hash code.  */
+  struct bfd_hash_entry *next;
+  /* String being hashed.  */
+  const char *string;
+  /* Hash code.  This is the full hash code, not the index into the
+     table.  */
+  unsigned long hash;
+};
+
+/* A hash table.  */
+
+struct bfd_hash_table
+{
+  /* The hash array.  */
+  struct bfd_hash_entry **table;
+  /* The number of slots in the hash table.  */
+  unsigned int size;
+  /* A function used to create new elements in the hash table.  The
+     first entry is itself a pointer to an element.  When this
+     function is first invoked, this pointer will be NULL.  However,
+     having the pointer permits a hierarchy of method functions to be
+     built each of which calls the function in the superclass.  Thus
+     each function should be written to allocate a new block of memory
+     only if the argument is NULL.  */
+  struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+					     struct bfd_hash_table *,
+					     const char *));
+  /* An obstack for this hash table.  */
+  struct obstack memory;
+};
+
+/* Initialize a hash table.  */
+extern boolean bfd_hash_table_init
+  PARAMS ((struct bfd_hash_table *,
+	   struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+				       struct bfd_hash_table *,
+				       const char *)));
+
+/* Initialize a hash table specifying a size.  */
+extern boolean bfd_hash_table_init_n
+  PARAMS ((struct bfd_hash_table *,
+	   struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+				       struct bfd_hash_table *,
+				       const char *),
+	   unsigned int size));
+
+/* Free up a hash table.  */
+extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *));
+
+/* Look up a string in a hash table.  If CREATE is true, a new entry
+   will be created for this string if one does not already exist.  The
+   COPY argument must be true if this routine should copy the string
+   into newly allocated memory when adding an entry.  */
+extern struct bfd_hash_entry *bfd_hash_lookup
+  PARAMS ((struct bfd_hash_table *, const char *, boolean create,
+	   boolean copy));
+
+/* Base method for creating a hash table entry.  */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+	   const char *));
+
+/* Grab some space for a hash table entry.  */
+extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *,
+				      unsigned int));
+
+/* Traverse a hash table in a random order, calling a function on each
+   element.  If the function returns false, the traversal stops.  The
+   INFO argument is passed to the function.  */
+extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *,
+				       boolean (*) (struct bfd_hash_entry *,
+						    PTR),
+				       PTR info));
+
+/* Semi-portable string concatenation in cpp.
+   The CAT4 hack is to avoid a problem with some strict ANSI C preprocessors.
+   The problem is, "32_" is not a valid preprocessing token, and we don't
+   want extra underscores (e.g., "nlm_32_").  The XCAT2 macro will cause the
+   inner CAT macros to be evaluated first, producing still-valid pp-tokens.
+   Then the final concatenation can be done.  (Sigh.)  */
+#ifndef CAT
+#ifdef SABER
+#define CAT(a,b)	a##b
+#define CAT3(a,b,c)	a##b##c
+#define CAT4(a,b,c,d)	a##b##c##d
+#else
+#if defined(__STDC__) || defined(ALMOST_STDC)
+#define CAT(a,b) a##b
+#define CAT3(a,b,c) a##b##c
+#define XCAT2(a,b)	CAT(a,b)
+#define CAT4(a,b,c,d)	XCAT2(CAT(a,b),CAT(c,d))
+#else
+#define CAT(a,b) a/**/b
+#define CAT3(a,b,c) a/**/b/**/c
+#define CAT4(a,b,c,d)	a/**/b/**/c/**/d
+#endif
+#endif
+#endif
+
+#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
+
+/* User program access to BFD facilities */
+
+/* Cast from const char * to char * so that caller can assign to
+   a char * without a warning.  */
+#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
+#define bfd_get_cacheable(abfd) ((abfd)->cacheable)
+#define bfd_get_format(abfd) ((abfd)->format)
+#define bfd_get_target(abfd) ((abfd)->xvec->name)
+#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
+#define bfd_get_file_flags(abfd) ((abfd)->flags)
+#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
+#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
+#define bfd_my_archive(abfd) ((abfd)->my_archive)
+#define bfd_has_map(abfd) ((abfd)->has_armap)
+
+#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
+#define bfd_usrdata(abfd) ((abfd)->usrdata)
+
+#define bfd_get_start_address(abfd) ((abfd)->start_address)
+#define bfd_get_symcount(abfd) ((abfd)->symcount)
+#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
+#define bfd_count_sections(abfd) ((abfd)->section_count)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (bool)), true)
+
+/* Byte swapping routines.  */
+
+bfd_vma		bfd_getb64	   PARAMS ((const unsigned char *));
+bfd_vma 	bfd_getl64	   PARAMS ((const unsigned char *));
+bfd_signed_vma	bfd_getb_signed_64 PARAMS ((const unsigned char *));
+bfd_signed_vma	bfd_getl_signed_64 PARAMS ((const unsigned char *));
+bfd_vma		bfd_getb32	   PARAMS ((const unsigned char *));
+bfd_vma		bfd_getl32	   PARAMS ((const unsigned char *));
+bfd_signed_vma	bfd_getb_signed_32 PARAMS ((const unsigned char *));
+bfd_signed_vma	bfd_getl_signed_32 PARAMS ((const unsigned char *));
+bfd_vma		bfd_getb16	   PARAMS ((const unsigned char *));
+bfd_vma		bfd_getl16	   PARAMS ((const unsigned char *));
+bfd_signed_vma	bfd_getb_signed_16 PARAMS ((const unsigned char *));
+bfd_signed_vma	bfd_getl_signed_16 PARAMS ((const unsigned char *));
+void		bfd_putb64	   PARAMS ((bfd_vma, unsigned char *));
+void		bfd_putl64	   PARAMS ((bfd_vma, unsigned char *));
+void		bfd_putb32	   PARAMS ((bfd_vma, unsigned char *));
+void		bfd_putl32	   PARAMS ((bfd_vma, unsigned char *));
+void		bfd_putb16	   PARAMS ((bfd_vma, unsigned char *));
+void		bfd_putl16	   PARAMS ((bfd_vma, unsigned char *));
+
+/* Externally visible ECOFF routines.  */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct symbol_cache_entry;
+struct bfd_link_info;
+#endif
+extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd));
+extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value));
+extern boolean bfd_ecoff_set_regmasks
+  PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+	   unsigned long *cprmask));
+extern PTR bfd_ecoff_debug_init
+  PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug,
+	   const struct ecoff_debug_swap *output_swap,
+	   struct bfd_link_info *));
+extern void bfd_ecoff_debug_free
+  PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+	   const struct ecoff_debug_swap *output_swap,
+	   struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_accumulate
+  PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+	   const struct ecoff_debug_swap *output_swap,
+	   bfd *input_bfd, struct ecoff_debug_info *input_debug,
+	   const struct ecoff_debug_swap *input_swap,
+	   struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_accumulate_other
+  PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+	   const struct ecoff_debug_swap *output_swap, bfd *input_bfd,
+	   struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_externals
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+	   const struct ecoff_debug_swap *swap,
+	   boolean relocateable,
+	   boolean (*get_extr) (struct symbol_cache_entry *,
+				struct ecoff_extr *),
+	   void (*set_index) (struct symbol_cache_entry *,
+			      bfd_size_type)));
+extern boolean bfd_ecoff_debug_one_external
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+	   const struct ecoff_debug_swap *swap,
+	   const char *name, struct ecoff_extr *esym));
+extern bfd_size_type bfd_ecoff_debug_size
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+	   const struct ecoff_debug_swap *swap));
+extern boolean bfd_ecoff_write_debug
+  PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+	   const struct ecoff_debug_swap *swap, file_ptr where));
+extern boolean bfd_ecoff_write_accumulated_debug
+  PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug,
+	   const struct ecoff_debug_swap *swap,
+	   struct bfd_link_info *info, file_ptr where));
+
+/* And more from the source.  */
+void 
+bfd_init PARAMS ((void));
+
+bfd *
+bfd_openr PARAMS ((CONST char *filename, CONST char *target));
+
+bfd *
+bfd_fdopenr PARAMS ((CONST char *filename, CONST char *target, int fd));
+
+bfd *
+bfd_openw PARAMS ((CONST char *filename, CONST char *target));
+
+boolean 
+bfd_close PARAMS ((bfd *abfd));
+
+boolean 
+bfd_close_all_done PARAMS ((bfd *));
+
+bfd_size_type 
+bfd_alloc_size PARAMS ((bfd *abfd));
+
+bfd *
+bfd_create PARAMS ((CONST char *filename, bfd *templ));
+
+
+ /* Byte swapping macros for user section data.  */
+
+#define bfd_put_8(abfd, val, ptr) \
+                (*((unsigned char *)(ptr)) = (unsigned char)(val))
+#define bfd_put_signed_8 \
+		bfd_put_8
+#define bfd_get_8(abfd, ptr) \
+                (*(unsigned char *)(ptr))
+#define bfd_get_signed_8(abfd, ptr) \
+		((*(unsigned char *)(ptr) ^ 0x80) - 0x80)
+
+#define bfd_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
+#define bfd_put_signed_16 \
+		 bfd_put_16
+#define bfd_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx16, (ptr))
+#define bfd_get_signed_16(abfd, ptr) \
+         	 BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
+
+#define bfd_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
+#define bfd_put_signed_32 \
+		 bfd_put_32
+#define bfd_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx32, (ptr))
+#define bfd_get_signed_32(abfd, ptr) \
+		 BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
+
+#define bfd_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
+#define bfd_put_signed_64 \
+		 bfd_put_64
+#define bfd_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx64, (ptr))
+#define bfd_get_signed_64(abfd, ptr) \
+		 BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
+
+
+ /* Byte swapping macros for file header data.  */
+
+#define bfd_h_put_8(abfd, val, ptr) \
+		bfd_put_8 (abfd, val, ptr)
+#define bfd_h_put_signed_8(abfd, val, ptr) \
+		bfd_put_8 (abfd, val, ptr)
+#define bfd_h_get_8(abfd, ptr) \
+		bfd_get_8 (abfd, ptr)
+#define bfd_h_get_signed_8(abfd, ptr) \
+		bfd_get_signed_8 (abfd, ptr)
+
+#define bfd_h_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
+#define bfd_h_put_signed_16 \
+		 bfd_h_put_16
+#define bfd_h_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx16,(ptr))
+#define bfd_h_get_signed_16(abfd, ptr) \
+		 BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
+
+#define bfd_h_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
+#define bfd_h_put_signed_32 \
+		 bfd_h_put_32
+#define bfd_h_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx32,(ptr))
+#define bfd_h_get_signed_32(abfd, ptr) \
+		 BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
+
+#define bfd_h_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
+#define bfd_h_put_signed_64 \
+		 bfd_h_put_64
+#define bfd_h_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx64,(ptr))
+#define bfd_h_get_signed_64(abfd, ptr) \
+		 BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
+
+typedef struct sec
+{
+         /* The name of the section; the name isn't a copy, the pointer is
+        the same as that passed to bfd_make_section. */
+
+    CONST char *name;
+
+         /* Which section is it; 0..nth.      */
+
+   int index;
+
+         /* The next section in the list belonging to the BFD, or NULL. */
+
+    struct sec *next;
+
+         /* The field flags contains attributes of the section. Some
+           flags are read in from the object file, and some are
+           synthesized from other information.  */
+
+    flagword flags;
+
+#define SEC_NO_FLAGS   0x000
+
+         /* Tells the OS to allocate space for this section when loading.
+           This is clear for a section containing debug information
+           only. */
+#define SEC_ALLOC      0x001
+
+         /* Tells the OS to load the section from the file when loading.
+           This is clear for a .bss section. */
+#define SEC_LOAD       0x002
+
+         /* The section contains data still to be relocated, so there is
+           some relocation information too. */
+#define SEC_RELOC      0x004
+
+#if 0    /* Obsolete ? */
+#define SEC_BALIGN     0x008
+#endif
+
+         /* A signal to the OS that the section contains read only
+          data. */
+#define SEC_READONLY   0x010
+
+         /* The section contains code only. */
+#define SEC_CODE       0x020
+
+         /* The section contains data only. */
+#define SEC_DATA       0x040
+
+         /* The section will reside in ROM. */
+#define SEC_ROM        0x080
+
+         /* The section contains constructor information. This section
+           type is used by the linker to create lists of constructors and
+           destructors used by <<g++>>. When a back end sees a symbol
+           which should be used in a constructor list, it creates a new
+           section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+           the symbol to it, and builds a relocation. To build the lists
+           of constructors, all the linker has to do is catenate all the
+           sections called <<__CTOR_LIST__>> and relocate the data
+           contained within - exactly the operations it would peform on
+           standard data. */
+#define SEC_CONSTRUCTOR 0x100
+
+         /* The section is a constuctor, and should be placed at the
+          end of the text, data, or bss section(?). */
+#define SEC_CONSTRUCTOR_TEXT 0x1100
+#define SEC_CONSTRUCTOR_DATA 0x2100
+#define SEC_CONSTRUCTOR_BSS  0x3100
+
+         /* The section has contents - a data section could be
+           <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
+           <<SEC_HAS_CONTENTS>> */
+#define SEC_HAS_CONTENTS 0x200
+
+         /* An instruction to the linker to not output the section
+          even if it has information which would normally be written. */
+#define SEC_NEVER_LOAD 0x400
+
+         /* The section is a shared library section.  The linker must leave
+           these completely alone, as the vma and size are used when
+           the executable is loaded. */
+#define SEC_SHARED_LIBRARY 0x800
+
+         /* The section is a common section (symbols may be defined
+           multiple times, the value of a symbol is the amount of
+           space it requires, and the largest symbol value is the one
+           used).  Most targets have exactly one of these (which we
+	    translate to bfd_com_section), but ECOFF has two. */
+#define SEC_IS_COMMON 0x8000
+
+         /* The section contains only debugging information.  For
+           example, this is set for ELF .debug and .stab sections.
+           strip tests this flag to see if a section can be
+           discarded. */
+#define SEC_DEBUGGING 0x10000
+
+         /* The contents of this section are held in memory pointed to
+           by the contents field.  This is checked by
+           bfd_get_section_contents, and the data is retrieved from
+           memory if appropriate.  */
+#define SEC_IN_MEMORY 0x20000
+
+	 /*  End of section flags.  */
+
+        /*  The virtual memory address of the section - where it will be
+           at run time.  The symbols are relocated against this.  The
+	    user_set_vma flag is maintained by bfd; if it's not set, the
+	    backend can assign addresses (for example, in <<a.out>>, where
+	    the default address for <<.data>> is dependent on the specific
+	    target and various flags).  */
+
+   bfd_vma vma;
+   boolean user_set_vma;
+
+        /*  The load address of the section - where it would be in a
+           rom image; really only used for writing section header
+	    information. */
+
+   bfd_vma lma;
+
+         /* The size of the section in bytes, as it will be output.
+           contains a value even if the section has no contents (e.g., the
+           size of <<.bss>>). This will be filled in after relocation */
+
+   bfd_size_type _cooked_size;
+
+         /* The original size on disk of the section, in bytes.  Normally this
+	    value is the same as the size, but if some relaxing has
+	    been done, then this value will be bigger.  */
+
+   bfd_size_type _raw_size;
+
+         /* If this section is going to be output, then this value is the
+           offset into the output section of the first byte in the input
+           section. E.g., if this was going to start at the 100th byte in
+           the output section, this value would be 100. */
+
+   bfd_vma output_offset;
+
+         /* The output section through which to map on output. */
+
+   struct sec *output_section;
+
+         /* The alignment requirement of the section, as an exponent of 2 -
+           e.g., 3 aligns to 2^3 (or 8). */
+
+   unsigned int alignment_power;
+
+         /* If an input section, a pointer to a vector of relocation
+           records for the data in this section. */
+
+   struct reloc_cache_entry *relocation;
+
+         /* If an output section, a pointer to a vector of pointers to
+           relocation records for the data in this section. */
+
+   struct reloc_cache_entry **orelocation;
+
+         /* The number of relocation records in one of the above  */
+
+   unsigned reloc_count;
+
+         /* Information below is back end specific - and not always used
+           or updated.  */
+
+         /* File position of section data    */
+
+   file_ptr filepos;
+
+         /* File position of relocation info */
+
+   file_ptr rel_filepos;
+
+         /* File position of line data       */
+
+   file_ptr line_filepos;
+
+         /* Pointer to data for applications */
+
+   PTR userdata;
+
+         /* If the SEC_IN_MEMORY flag is set, this points to the actual
+           contents.  */
+   unsigned char *contents;
+
+         /* Attached line number information */
+
+   alent *lineno;
+
+         /* Number of line number records   */
+
+   unsigned int lineno_count;
+
+         /* When a section is being output, this value changes as more
+           linenumbers are written out */
+
+   file_ptr moving_line_filepos;
+
+         /* What the section number is in the target world  */
+
+   int target_index;
+
+   PTR used_by_bfd;
+
+         /* If this is a constructor section then here is a list of the
+           relocations created to relocate items within it. */
+
+   struct relent_chain *constructor_chain;
+
+         /* The BFD which owns the section. */
+
+   bfd *owner;
+
+   boolean reloc_done;
+	  /* A symbol which points at this section only */
+   struct symbol_cache_entry *symbol;
+   struct symbol_cache_entry **symbol_ptr_ptr;
+
+   struct bfd_link_order *link_order_head;
+   struct bfd_link_order *link_order_tail;
+} asection ;
+
+
+     /* These sections are global, and are managed by BFD.  The application
+       and target back end are not permitted to change the values in
+	these sections.  */
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+#define BFD_IND_SECTION_NAME "*IND*"
+
+     /* the absolute section */
+extern asection bfd_abs_section;
+     /* Pointer to the undefined section */
+extern asection bfd_und_section;
+     /* Pointer to the common section */
+extern asection bfd_com_section;
+     /* Pointer to the indirect section */
+extern asection bfd_ind_section;
+
+extern struct symbol_cache_entry *bfd_abs_symbol;
+extern struct symbol_cache_entry *bfd_com_symbol;
+extern struct symbol_cache_entry *bfd_und_symbol;
+extern struct symbol_cache_entry *bfd_ind_symbol;
+#define bfd_get_section_size_before_reloc(section) \
+     (section->reloc_done ? (abort(),1): (section)->_raw_size)
+#define bfd_get_section_size_after_reloc(section) \
+     ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
+asection *
+bfd_get_section_by_name PARAMS ((bfd *abfd, CONST char *name));
+
+asection *
+bfd_make_section_old_way PARAMS ((bfd *abfd, CONST char *name));
+
+asection *
+bfd_make_section_anyway PARAMS ((bfd *abfd, CONST char *name));
+
+asection *
+bfd_make_section PARAMS ((bfd *, CONST char *name));
+
+boolean 
+bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags));
+
+void 
+bfd_map_over_sections PARAMS ((bfd *abfd,
+    void (*func)(bfd *abfd,
+    asection *sect,
+    PTR obj),
+    PTR obj));
+
+boolean 
+bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val));
+
+boolean 
+bfd_set_section_contents
+ PARAMS ((bfd *abfd,
+    asection *section,
+    PTR data,
+    file_ptr offset,
+    bfd_size_type count));
+
+boolean 
+bfd_get_section_contents
+ PARAMS ((bfd *abfd, asection *section, PTR location,
+    file_ptr offset, bfd_size_type count));
+
+boolean 
+bfd_copy_private_section_data PARAMS ((bfd *ibfd, asection *isec, bfd *obfd, asection *osec));
+
+#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+     BFD_SEND (ibfd, _bfd_copy_private_section_data, \
+		(ibfd, isection, obfd, osection))
+enum bfd_architecture 
+{
+  bfd_arch_unknown,    /* File arch not known */
+  bfd_arch_obscure,    /* Arch known, not one of these */
+  bfd_arch_m68k,       /* Motorola 68xxx */
+  bfd_arch_vax,        /* DEC Vax */   
+  bfd_arch_i960,       /* Intel 960 */
+     /* The order of the following is important.
+       lower number indicates a machine type that 
+       only accepts a subset of the instructions
+       available to machines with higher numbers.
+       The exception is the "ca", which is
+       incompatible with all other machines except 
+       "core". */
+
+#define bfd_mach_i960_core      1
+#define bfd_mach_i960_ka_sa     2
+#define bfd_mach_i960_kb_sb     3
+#define bfd_mach_i960_mc        4
+#define bfd_mach_i960_xa        5
+#define bfd_mach_i960_ca        6
+
+  bfd_arch_a29k,       /* AMD 29000 */
+  bfd_arch_sparc,      /* SPARC */
+  bfd_arch_mips,       /* MIPS Rxxxx */
+  bfd_arch_i386,       /* Intel 386 */
+  bfd_arch_we32k,      /* AT&T WE32xxx */
+  bfd_arch_tahoe,      /* CCI/Harris Tahoe */
+  bfd_arch_i860,       /* Intel 860 */
+  bfd_arch_romp,       /* IBM ROMP PC/RT */
+  bfd_arch_alliant,    /* Alliant */
+  bfd_arch_convex,     /* Convex */
+  bfd_arch_m88k,       /* Motorola 88xxx */
+  bfd_arch_pyramid,    /* Pyramid Technology */
+  bfd_arch_h8300,      /* Hitachi H8/300 */
+#define bfd_mach_h8300   1
+#define bfd_mach_h8300h  2
+  bfd_arch_powerpc,    /* PowerPC */
+  bfd_arch_rs6000,     /* IBM RS/6000 */
+  bfd_arch_hppa,       /* HP PA RISC */
+  bfd_arch_z8k,        /* Zilog Z8000 */
+#define bfd_mach_z8001		1
+#define bfd_mach_z8002		2
+  bfd_arch_h8500,      /* Hitachi H8/500 */
+  bfd_arch_sh,         /* Hitachi SH */
+  bfd_arch_alpha,      /* Dec Alpha */
+  bfd_arch_last
+  };
+
+typedef struct bfd_arch_info 
+{
+  int bits_per_word;
+  int bits_per_address;
+  int bits_per_byte;
+  enum bfd_architecture arch;
+  long mach;
+  char *arch_name;
+  CONST  char *printable_name;
+  unsigned int section_align_power;
+  /* true if this is the default machine for the architecture */
+  boolean the_default;	
+  CONST struct bfd_arch_info * (*compatible)
+	PARAMS ((CONST struct bfd_arch_info *a,
+	         CONST struct bfd_arch_info *b));
+
+  boolean (*scan) PARAMS ((CONST struct bfd_arch_info *, CONST char *));
+   /* How to disassemble an instruction, producing a printable
+     representation on a specified stdio stream.  This isn't
+     defined for most processors at present, because of the size
+     of the additional tables it would drag in, and because gdb
+     wants to use a different interface.  */
+  unsigned int (*disassemble) PARAMS ((bfd_vma addr, CONST char *data,
+				        PTR stream));
+
+  struct bfd_arch_info *next;
+} bfd_arch_info_type;
+CONST char *
+bfd_printable_name PARAMS ((bfd *abfd));
+
+bfd_arch_info_type *
+bfd_scan_arch PARAMS ((CONST char *string));
+
+CONST bfd_arch_info_type *
+bfd_arch_get_compatible PARAMS ((
+    CONST bfd *abfd,
+    CONST bfd *bbfd));
+
+void 
+bfd_set_arch_info PARAMS ((bfd *abfd, bfd_arch_info_type *arg));
+
+enum bfd_architecture 
+bfd_get_arch PARAMS ((bfd *abfd));
+
+unsigned long 
+bfd_get_mach PARAMS ((bfd *abfd));
+
+unsigned int 
+bfd_arch_bits_per_byte PARAMS ((bfd *abfd));
+
+unsigned int 
+bfd_arch_bits_per_address PARAMS ((bfd *abfd));
+
+bfd_arch_info_type * 
+bfd_get_arch_info PARAMS ((bfd *abfd));
+
+bfd_arch_info_type *
+bfd_lookup_arch
+ PARAMS ((enum bfd_architecture
+    arch,
+    long machine));
+
+CONST char *
+bfd_printable_arch_mach
+ PARAMS ((enum bfd_architecture arch, unsigned long machine));
+
+typedef enum bfd_reloc_status
+{
+        /* No errors detected */
+  bfd_reloc_ok,
+
+        /* The relocation was performed, but there was an overflow. */
+  bfd_reloc_overflow,
+
+        /* The address to relocate was not within the section supplied. */
+  bfd_reloc_outofrange,
+
+        /* Used by special functions */
+  bfd_reloc_continue,
+
+        /* Unsupported relocation size requested. */
+  bfd_reloc_notsupported,
+
+        /* Unused */
+  bfd_reloc_other,
+
+        /* The symbol to relocate against was undefined. */
+  bfd_reloc_undefined,
+
+        /* The relocation was performed, but may not be ok - presently
+          generated only when linking i960 coff files with i960 b.out
+          symbols.  If this type is returned, the error_message argument
+          to bfd_perform_relocation will be set.  */
+  bfd_reloc_dangerous
+ }
+ bfd_reloc_status_type;
+
+
+typedef struct reloc_cache_entry
+{
+        /* A pointer into the canonical table of pointers  */
+  struct symbol_cache_entry **sym_ptr_ptr;
+
+        /* offset in section */
+  bfd_size_type address;
+
+        /* addend for relocation value */
+  bfd_vma addend;
+
+        /* Pointer to how to perform the required relocation */
+  const struct reloc_howto_struct *howto;
+
+} arelent;
+enum complain_overflow
+{
+	 /* Do not complain on overflow. */
+  complain_overflow_dont,
+
+	 /* Complain if the bitfield overflows, whether it is considered
+	   as signed or unsigned. */
+  complain_overflow_bitfield,
+
+	 /* Complain if the value overflows when considered as signed
+	   number. */
+  complain_overflow_signed,
+
+	 /* Complain if the value overflows when considered as an
+	   unsigned number. */
+  complain_overflow_unsigned
+};
+
+typedef struct reloc_howto_struct
+{
+        /*  The type field has mainly a documetary use - the back end can
+           do what it wants with it, though normally the back end's
+           external idea of what a reloc number is stored
+           in this field. For example, a PC relative word relocation
+           in a coff environment has the type 023 - because that's
+           what the outside world calls a R_PCRWORD reloc. */
+  unsigned int type;
+
+        /*  The value the final relocation is shifted right by. This drops
+           unwanted data from the relocation.  */
+  unsigned int rightshift;
+
+	 /*  The size of the item to be relocated.  This is *not* a
+	    power-of-two measure.  To get the number of bytes operated
+	    on by a type of relocation, use bfd_get_reloc_size.  */
+  int size;
+
+        /*  The number of bits in the item to be relocated.  This is used
+	    when doing overflow checking.  */
+  unsigned int bitsize;
+
+        /*  Notes that the relocation is relative to the location in the
+           data section of the addend. The relocation function will
+           subtract from the relocation value the address of the location
+           being relocated. */
+  boolean pc_relative;
+
+	 /*  The bit position of the reloc value in the destination.
+	    The relocated value is left shifted by this amount. */
+  unsigned int bitpos;
+
+	 /* What type of overflow error should be checked for when
+	   relocating. */
+  enum complain_overflow complain_on_overflow;
+
+        /* If this field is non null, then the supplied function is
+          called rather than the normal function. This allows really
+          strange relocation methods to be accomodated (e.g., i960 callj
+          instructions). */
+  bfd_reloc_status_type (*special_function)
+				    PARAMS ((bfd *abfd,
+					     arelent *reloc_entry,
+                                            struct symbol_cache_entry *symbol,
+                                            PTR data,
+                                            asection *input_section,
+                                            bfd *output_bfd,
+                                            char **error_message));
+
+        /* The textual name of the relocation type. */
+  char *name;
+
+        /* When performing a partial link, some formats must modify the
+          relocations rather than the data - this flag signals this.*/
+  boolean partial_inplace;
+
+        /* The src_mask selects which parts of the read in data
+          are to be used in the relocation sum.  E.g., if this was an 8 bit
+          bit of data which we read and relocated, this would be
+          0x000000ff. When we have relocs which have an addend, such as
+          sun4 extended relocs, the value in the offset part of a
+          relocating field is garbage so we never use it. In this case
+          the mask would be 0x00000000. */
+  bfd_vma src_mask;
+
+        /* The dst_mask selects which parts of the instruction are replaced
+          into the instruction. In most cases src_mask == dst_mask,
+          except in the above special case, where dst_mask would be
+          0x000000ff, and src_mask would be 0x00000000.   */
+  bfd_vma dst_mask;
+
+        /* When some formats create PC relative instructions, they leave
+          the value of the pc of the place being relocated in the offset
+          slot of the instruction, so that a PC relative relocation can
+          be made just by adding in an ordinary offset (e.g., sun3 a.out).
+          Some formats leave the displacement part of an instruction
+          empty (e.g., m88k bcs); this flag signals the fact.*/
+  boolean pcrel_offset;
+
+} reloc_howto_type;
+#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+  {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
+
+#define HOWTO_PREPARE(relocation, symbol)      \
+  {                                            \
+  if (symbol != (asymbol *)NULL) {             \
+    if (bfd_is_com_section (symbol->section)) { \
+      relocation = 0;                          \
+    }                                          \
+    else {                                     \
+      relocation = symbol->value;              \
+    }                                          \
+  }                                            \
+}
+int 
+bfd_get_reloc_size  PARAMS ((const reloc_howto_type *));
+
+typedef unsigned char bfd_byte;
+
+typedef struct relent_chain {
+  arelent relent;
+  struct   relent_chain *next;
+} arelent_chain;
+bfd_reloc_status_type
+
+bfd_perform_relocation
+ PARAMS ((bfd *abfd,
+    arelent *reloc_entry,
+    PTR data,
+    asection *input_section,
+    bfd *output_bfd,
+    char **error_message));
+
+typedef enum bfd_reloc_code_real
+{
+   /* Basic absolute relocations */
+  BFD_RELOC_64,
+  BFD_RELOC_32,
+  BFD_RELOC_26,
+  BFD_RELOC_16,
+  BFD_RELOC_14,
+  BFD_RELOC_8,
+
+   /* PC-relative relocations */
+  BFD_RELOC_64_PCREL,
+  BFD_RELOC_32_PCREL,
+  BFD_RELOC_24_PCREL,     /* used by i960 */
+  BFD_RELOC_16_PCREL,
+  BFD_RELOC_8_PCREL,
+
+   /* Linkage-table relative */
+  BFD_RELOC_32_BASEREL,
+  BFD_RELOC_16_BASEREL,
+  BFD_RELOC_8_BASEREL,
+
+   /* The type of reloc used to build a contructor table - at the moment
+     probably a 32 bit wide abs address, but the cpu can choose. */
+  BFD_RELOC_CTOR,
+
+   /* 8 bits wide, but used to form an address like 0xffnn */
+  BFD_RELOC_8_FFnn,
+
+   /* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
+     word displacement, e.g. for SPARC) */
+  BFD_RELOC_32_PCREL_S2,
+   /* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) */
+  BFD_RELOC_16_PCREL_S2,
+   /* this is used on the Alpha */
+  BFD_RELOC_23_PCREL_S2,
+
+   /* High 22 bits of 32-bit value, placed into lower 22 bits of
+     target word; simple reloc.  */
+  BFD_RELOC_HI22,
+   /* Low 10 bits.  */
+  BFD_RELOC_LO10,
+
+   /* For systems that allocate a Global Pointer register, these are
+     displacements off that register.  These relocation types are
+     handled specially, because the value the register will have is
+     decided relatively late.  */
+  BFD_RELOC_GPREL16,
+  BFD_RELOC_GPREL32,
+
+   /* Reloc types used for i960/b.out.  */
+  BFD_RELOC_I960_CALLJ,
+
+   /* now for the sparc/elf codes */
+  BFD_RELOC_NONE,		 /* actually used */
+  BFD_RELOC_SPARC_WDISP22,
+  BFD_RELOC_SPARC22,
+  BFD_RELOC_SPARC13,
+  BFD_RELOC_SPARC_GOT10,
+  BFD_RELOC_SPARC_GOT13,
+  BFD_RELOC_SPARC_GOT22,
+  BFD_RELOC_SPARC_PC10,
+  BFD_RELOC_SPARC_PC22,
+  BFD_RELOC_SPARC_WPLT30,
+  BFD_RELOC_SPARC_COPY,
+  BFD_RELOC_SPARC_GLOB_DAT,
+  BFD_RELOC_SPARC_JMP_SLOT,
+  BFD_RELOC_SPARC_RELATIVE,
+  BFD_RELOC_SPARC_UA32,
+
+   /* these are a.out specific? */
+  BFD_RELOC_SPARC_BASE13,
+  BFD_RELOC_SPARC_BASE22,
+
+
+   /* Alpha ECOFF relocations.  Some of these treat the symbol or "addend"
+     in some special way.  */
+   /* For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+     writing; when reading, it will be the absolute section symbol.  The
+     addend is the displacement in bytes of the "lda" instruction from
+     the "ldah" instruction (which is at the address of this reloc).  */
+  BFD_RELOC_ALPHA_GPDISP_HI16,
+   /* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+     with GPDISP_HI16 relocs.  The addend is ignored when writing the
+     relocations out, and is filled in with the file's GP value on
+     reading, for convenience.  */
+  BFD_RELOC_ALPHA_GPDISP_LO16,
+
+   /* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+     the assembler turns it into a LDQ instruction to load the address of
+     the symbol, and then fills in a register in the real instruction.
+
+     The LITERAL reloc, at the LDQ instruction, refers to the .lita
+     section symbol.  The addend is ignored when writing, but is filled
+     in with the file's GP value on reading, for convenience, as with the
+     GPDISP_LO16 reloc.
+
+     The LITUSE reloc, on the instruction using the loaded address, gives
+     information to the linker that it might be able to use to optimize
+     away some literal section references.  The symbol is ignored (read
+     as the absolute section symbol), and the "addend" indicates the type
+     of instruction using the register:
+              1 - "memory" fmt insn
+              2 - byte-manipulation (byte offset reg)
+              3 - jsr (target of branch)
+
+     The GNU linker currently doesn't do any of this optimizing.  */
+  BFD_RELOC_ALPHA_LITERAL,
+  BFD_RELOC_ALPHA_LITUSE,
+
+   /* The HINT relocation indicates a value that should be filled into the
+     "hint" field of a jmp/jsr/ret instruction, for possible branch-
+     prediction logic which may be provided on some processors.  */
+  BFD_RELOC_ALPHA_HINT,
+
+   /* Bits 27..2 of the relocation address shifted right 2 bits;
+     simple reloc otherwise.  */
+  BFD_RELOC_MIPS_JMP,
+
+   /* High 16 bits of 32-bit value; simple reloc.  */
+  BFD_RELOC_HI16,
+   /* High 16 bits of 32-bit value but the low 16 bits will be sign
+     extended and added to form the final result.  If the low 16
+     bits form a negative number, we need to add one to the high value
+     to compensate for the borrow when the low bits are added.  */
+  BFD_RELOC_HI16_S,
+   /* Low 16 bits.  */
+  BFD_RELOC_LO16,
+   /* Like BFD_RELOC_HI16_S, but PC relative.  */
+  BFD_RELOC_PCREL_HI16_S,
+   /* Like BFD_RELOC_LO16, but PC relative.  */
+  BFD_RELOC_PCREL_LO16,
+
+   /* relocation relative to the global pointer.  */
+#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16
+
+   /* Relocation against a MIPS literal section.  */
+  BFD_RELOC_MIPS_LITERAL,
+
+   /* MIPS ELF relocations.  */
+  BFD_RELOC_MIPS_GOT16,
+  BFD_RELOC_MIPS_CALL16,
+#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32
+
+   /* These are, so far, specific to HPPA processors.  I'm not sure that some
+     don't duplicate other reloc types, such as BFD_RELOC_32 and _32_PCREL.
+     Also, many more were in the list I got that don't fit in well in the
+     model BFD uses, so I've omitted them for now.  If we do make this reloc
+     type get used for code that really does implement the funky reloc types,
+     they'll have to be added to this list.  */
+  BFD_RELOC_HPPA_32,
+  BFD_RELOC_HPPA_11,
+  BFD_RELOC_HPPA_14,
+  BFD_RELOC_HPPA_17,
+
+  BFD_RELOC_HPPA_L21,
+  BFD_RELOC_HPPA_R11,
+  BFD_RELOC_HPPA_R14,
+  BFD_RELOC_HPPA_R17,
+  BFD_RELOC_HPPA_LS21,
+  BFD_RELOC_HPPA_RS11,
+  BFD_RELOC_HPPA_RS14,
+  BFD_RELOC_HPPA_RS17,
+  BFD_RELOC_HPPA_LD21,
+  BFD_RELOC_HPPA_RD11,
+  BFD_RELOC_HPPA_RD14,
+  BFD_RELOC_HPPA_RD17,
+  BFD_RELOC_HPPA_LR21,
+  BFD_RELOC_HPPA_RR14,
+  BFD_RELOC_HPPA_RR17,
+
+  BFD_RELOC_HPPA_GOTOFF_11,
+  BFD_RELOC_HPPA_GOTOFF_14,
+  BFD_RELOC_HPPA_GOTOFF_L21,
+  BFD_RELOC_HPPA_GOTOFF_R11,
+  BFD_RELOC_HPPA_GOTOFF_R14,
+  BFD_RELOC_HPPA_GOTOFF_LS21,
+  BFD_RELOC_HPPA_GOTOFF_RS11,
+  BFD_RELOC_HPPA_GOTOFF_RS14,
+  BFD_RELOC_HPPA_GOTOFF_LD21,
+  BFD_RELOC_HPPA_GOTOFF_RD11,
+  BFD_RELOC_HPPA_GOTOFF_RD14,
+  BFD_RELOC_HPPA_GOTOFF_LR21,
+  BFD_RELOC_HPPA_GOTOFF_RR14,
+
+  BFD_RELOC_HPPA_DLT_32,
+  BFD_RELOC_HPPA_DLT_11,
+  BFD_RELOC_HPPA_DLT_14,
+  BFD_RELOC_HPPA_DLT_L21,
+  BFD_RELOC_HPPA_DLT_R11,
+  BFD_RELOC_HPPA_DLT_R14,
+
+  BFD_RELOC_HPPA_ABS_CALL_11,
+  BFD_RELOC_HPPA_ABS_CALL_14,
+  BFD_RELOC_HPPA_ABS_CALL_17,
+  BFD_RELOC_HPPA_ABS_CALL_L21,
+  BFD_RELOC_HPPA_ABS_CALL_R11,
+  BFD_RELOC_HPPA_ABS_CALL_R14,
+  BFD_RELOC_HPPA_ABS_CALL_R17,
+  BFD_RELOC_HPPA_ABS_CALL_LS21,
+  BFD_RELOC_HPPA_ABS_CALL_RS11,
+  BFD_RELOC_HPPA_ABS_CALL_RS14,
+  BFD_RELOC_HPPA_ABS_CALL_RS17,
+  BFD_RELOC_HPPA_ABS_CALL_LD21,
+  BFD_RELOC_HPPA_ABS_CALL_RD11,
+  BFD_RELOC_HPPA_ABS_CALL_RD14,
+  BFD_RELOC_HPPA_ABS_CALL_RD17,
+  BFD_RELOC_HPPA_ABS_CALL_LR21,
+  BFD_RELOC_HPPA_ABS_CALL_RR14,
+  BFD_RELOC_HPPA_ABS_CALL_RR17,
+
+  BFD_RELOC_HPPA_PCREL_CALL_11,
+  BFD_RELOC_HPPA_PCREL_CALL_12,
+  BFD_RELOC_HPPA_PCREL_CALL_14,
+  BFD_RELOC_HPPA_PCREL_CALL_17,
+  BFD_RELOC_HPPA_PCREL_CALL_L21,
+  BFD_RELOC_HPPA_PCREL_CALL_R11,
+  BFD_RELOC_HPPA_PCREL_CALL_R14,
+  BFD_RELOC_HPPA_PCREL_CALL_R17,
+  BFD_RELOC_HPPA_PCREL_CALL_LS21,
+  BFD_RELOC_HPPA_PCREL_CALL_RS11,
+  BFD_RELOC_HPPA_PCREL_CALL_RS14,
+  BFD_RELOC_HPPA_PCREL_CALL_RS17,
+  BFD_RELOC_HPPA_PCREL_CALL_LD21,
+  BFD_RELOC_HPPA_PCREL_CALL_RD11,
+  BFD_RELOC_HPPA_PCREL_CALL_RD14,
+  BFD_RELOC_HPPA_PCREL_CALL_RD17,
+  BFD_RELOC_HPPA_PCREL_CALL_LR21,
+  BFD_RELOC_HPPA_PCREL_CALL_RR14,
+  BFD_RELOC_HPPA_PCREL_CALL_RR17,
+
+  BFD_RELOC_HPPA_PLABEL_32,
+  BFD_RELOC_HPPA_PLABEL_11,
+  BFD_RELOC_HPPA_PLABEL_14,
+  BFD_RELOC_HPPA_PLABEL_L21,
+  BFD_RELOC_HPPA_PLABEL_R11,
+  BFD_RELOC_HPPA_PLABEL_R14,
+
+  BFD_RELOC_HPPA_UNWIND_ENTRY,
+  BFD_RELOC_HPPA_UNWIND_ENTRIES,
+
+   /* i386/elf relocations */
+  BFD_RELOC_386_GOT32,
+  BFD_RELOC_386_PLT32,
+  BFD_RELOC_386_COPY,
+  BFD_RELOC_386_GLOB_DAT,
+  BFD_RELOC_386_JUMP_SLOT,
+  BFD_RELOC_386_RELATIVE,
+  BFD_RELOC_386_GOTOFF,
+  BFD_RELOC_386_GOTPC,
+
+   /* PowerPC/POWER (RS/6000) relocs.  */
+   /* 26 bit relative branch.  Low two bits must be zero.  High 24
+     bits installed in bits 6 through 29 of instruction.  */
+  BFD_RELOC_PPC_B26,
+   /* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute.  */
+  BFD_RELOC_PPC_BA26,
+   /* 16 bit TOC relative reference.  */
+  BFD_RELOC_PPC_TOC16,
+
+   /* this must be the highest numeric value */
+  BFD_RELOC_UNUSED
+ } bfd_reloc_code_real_type;
+const struct reloc_howto_struct *
+
+bfd_reloc_type_lookup  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+
+
+typedef struct symbol_cache_entry
+{
+	 /* A pointer to the BFD which owns the symbol. This information
+	   is necessary so that a back end can work out what additional
+   	   information (invisible to the application writer) is carried
+	   with the symbol.
+
+	   This field is *almost* redundant, since you can use section->owner
+	   instead, except that some symbols point to the global sections
+	   bfd_{abs,com,und}_section.  This could be fixed by making
+	   these globals be per-bfd (or per-target-flavor).  FIXME. */
+
+  struct _bfd *the_bfd;  /* Use bfd_asymbol_bfd(sym) to access this field. */
+
+	 /* The text of the symbol. The name is left alone, and not copied; the
+	   application may not alter it. */
+  CONST char *name;
+
+	 /* The value of the symbol.  This really should be a union of a
+          numeric value with a pointer, since some flags indicate that
+          a pointer to another symbol is stored here.  */
+  symvalue value;
+
+	 /* Attributes of a symbol: */
+
+#define BSF_NO_FLAGS    0x00
+
+	 /* The symbol has local scope; <<static>> in <<C>>. The value
+ 	   is the offset into the section of the data. */
+#define BSF_LOCAL	0x01
+
+	 /* The symbol has global scope; initialized data in <<C>>. The
+	   value is the offset into the section of the data. */
+#define BSF_GLOBAL	0x02
+
+	 /* The symbol has global scope and is exported. The value is
+	   the offset into the section of the data. */
+#define BSF_EXPORT	BSF_GLOBAL  /* no real difference */
+
+	 /* A normal C symbol would be one of:
+	   <<BSF_LOCAL>>, <<BSF_FORT_COMM>>,  <<BSF_UNDEFINED>> or
+	   <<BSF_GLOBAL>> */
+
+	 /* The symbol is a debugging record. The value has an arbitary
+	   meaning. */
+#define BSF_DEBUGGING	0x08
+
+	 /* The symbol denotes a function entry point.  Used in ELF,
+	   perhaps others someday.  */
+#define BSF_FUNCTION    0x10
+
+	 /* Used by the linker. */
+#define BSF_KEEP        0x20
+#define BSF_KEEP_G      0x40
+
+	 /* A weak global symbol, overridable without warnings by
+	   a regular global symbol of the same name.  */
+#define BSF_WEAK        0x80
+
+        /* This symbol was created to point to a section, e.g. ELF's
+	   STT_SECTION symbols.  */
+#define BSF_SECTION_SYM 0x100
+
+	 /* The symbol used to be a common symbol, but now it is
+	   allocated. */
+#define BSF_OLD_COMMON  0x200
+
+	 /* The default value for common data. */
+#define BFD_FORT_COMM_DEFAULT_VALUE 0
+
+	 /* In some files the type of a symbol sometimes alters its
+	   location in an output file - ie in coff a <<ISFCN>> symbol
+	   which is also <<C_EXT>> symbol appears where it was
+	   declared and not at the end of a section.  This bit is set
+  	   by the target BFD part to convey this information. */
+
+#define BSF_NOT_AT_END    0x400
+
+	 /* Signal that the symbol is the label of constructor section. */
+#define BSF_CONSTRUCTOR   0x800
+
+	 /* Signal that the symbol is a warning symbol. If the symbol
+	   is a warning symbol, then the value field (I know this is
+	   tacky) will point to the asymbol which when referenced will
+	   cause the warning. */
+#define BSF_WARNING       0x1000
+
+	 /* Signal that the symbol is indirect. The value of the symbol
+	   is a pointer to an undefined asymbol which contains the
+	   name to use instead. */
+#define BSF_INDIRECT      0x2000
+
+	 /* BSF_FILE marks symbols that contain a file name.  This is used
+	   for ELF STT_FILE symbols.  */
+#define BSF_FILE          0x4000
+
+	 /* Symbol is from dynamic linking information.  */
+#define BSF_DYNAMIC	   0x8000
+
+  flagword flags;
+
+	 /* A pointer to the section to which this symbol is
+	   relative.  This will always be non NULL, there are special
+          sections for undefined and absolute symbols */
+  struct sec *section;
+
+	 /* Back end special data. This is being phased out in favour
+	   of making this a union. */
+  PTR udata;
+
+} asymbol;
+#define bfd_get_symtab_upper_bound(abfd) \
+     BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+boolean 
+bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym));
+
+#define bfd_is_local_label(abfd, sym) \
+     BFD_SEND (abfd, _bfd_is_local_label,(abfd, sym))
+#define bfd_canonicalize_symtab(abfd, location) \
+     BFD_SEND (abfd, _bfd_canonicalize_symtab,\
+                  (abfd, location))
+boolean 
+bfd_set_symtab  PARAMS ((bfd *abfd, asymbol **location, unsigned int count));
+
+void 
+bfd_print_symbol_vandf PARAMS ((PTR file, asymbol *symbol));
+
+#define bfd_make_empty_symbol(abfd) \
+     BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+        BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+int 
+bfd_decode_symclass PARAMS ((asymbol *symbol));
+
+void 
+bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret));
+
+struct _bfd 
+{
+     /* The filename the application opened the BFD with.  */
+    CONST char *filename;                
+
+     /* A pointer to the target jump table.             */
+    struct bfd_target *xvec;
+
+     /* To avoid dragging too many header files into every file that
+       includes `<<bfd.h>>', IOSTREAM has been declared as a "char
+       *", and MTIME as a "long".  Their correct types, to which they
+       are cast when used, are "FILE *" and "time_t".    The iostream
+       is the result of an fopen on the filename. */
+    char *iostream;
+
+     /* Is the file descriptor being cached?  That is, can it be closed as
+       needed, and re-opened when accessed later?  */
+
+    boolean cacheable;
+
+     /* Marks whether there was a default target specified when the
+       BFD was opened. This is used to select which matching algorithm
+       to use to choose the back end. */
+
+    boolean target_defaulted;
+
+     /* The caching routines use these to maintain a
+       least-recently-used list of BFDs */
+
+    struct _bfd *lru_prev, *lru_next;
+
+     /* When a file is closed by the caching routines, BFD retains
+       state information on the file here: */
+
+    file_ptr where;              
+
+     /* and here: (``once'' means at least once) */
+
+    boolean opened_once;
+
+     /* Set if we have a locally maintained mtime value, rather than
+       getting it from the file each time: */
+
+    boolean mtime_set;
+
+     /* File modified time, if mtime_set is true: */
+
+    long mtime;          
+
+     /* Reserved for an unimplemented file locking extension.*/
+
+    int ifd;
+
+     /* The format which belongs to the BFD. (object, core, etc.) */
+
+    bfd_format format;
+
+     /* The direction the BFD was opened with*/
+
+    enum bfd_direction {no_direction = 0,
+                        read_direction = 1,
+                        write_direction = 2,
+                        both_direction = 3} direction;
+
+     /* Format_specific flags*/
+
+    flagword flags;              
+
+     /* Currently my_archive is tested before adding origin to
+       anything. I believe that this can become always an add of
+       origin, with origin set to 0 for non archive files.   */
+
+    file_ptr origin;             
+
+     /* Remember when output has begun, to stop strange things
+       from happening. */
+    boolean output_has_begun;
+
+     /* Pointer to linked list of sections*/
+    struct sec  *sections;
+
+     /* The number of sections */
+    unsigned int section_count;
+
+     /* Stuff only useful for object files: 
+       The start address. */
+    bfd_vma start_address;
+
+     /* Used for input and output*/
+    unsigned int symcount;
+
+     /* Symbol table for output BFD (with symcount entries) */
+    struct symbol_cache_entry  **outsymbols;             
+
+     /* Pointer to structure which contains architecture information*/
+    struct bfd_arch_info *arch_info;
+
+     /* Stuff only useful for archives:*/
+    PTR arelt_data;              
+    struct _bfd *my_archive;      /* The containing archive BFD.  */
+    struct _bfd *next;            /* The next BFD in the archive.  */
+    struct _bfd *archive_head;    /* The first BFD in the archive.  */
+    boolean has_armap;           
+
+     /* A chain of BFD structures involved in a link.  */
+    struct _bfd *link_next;
+
+     /* A field used by _bfd_generic_link_add_archive_symbols.  This will
+       be used only for archive elements.  */
+    int archive_pass;
+
+     /* Used by the back end to hold private data. */
+
+    union 
+      {
+      struct aout_data_struct *aout_data;
+      struct artdata *aout_ar_data;
+      struct _oasys_data *oasys_obj_data;
+      struct _oasys_ar_data *oasys_ar_data;
+      struct coff_tdata *coff_obj_data;
+      struct ecoff_tdata *ecoff_obj_data;
+      struct ieee_data_struct *ieee_data;
+      struct ieee_ar_data_struct *ieee_ar_data;
+      struct srec_data_struct *srec_data;
+      struct tekhex_data_struct *tekhex_data;
+      struct elf_obj_tdata *elf_obj_data;
+      struct nlm_obj_tdata *nlm_obj_data;
+      struct bout_data_struct *bout_data;
+      struct sun_core_struct *sun_core_data;
+      struct trad_core_struct *trad_core_data;
+      struct som_data_struct *som_data;
+      struct hpux_core_struct *hpux_core_data;
+      struct hppabsd_core_struct *hppabsd_core_data;
+      struct sgi_core_struct *sgi_core_data;
+      struct lynx_core_struct *lynx_core_data;
+      struct osf_core_struct *osf_core_data;
+      struct cisco_core_struct *cisco_core_data;
+      PTR any;
+      } tdata;
+  
+     /* Used by the application to hold private data*/
+    PTR usrdata;
+
+     /* Where all the allocated stuff under this BFD goes */
+    struct obstack memory;
+};
+
+typedef enum bfd_error
+{
+  bfd_error_no_error = 0,
+  bfd_error_system_call,
+  bfd_error_invalid_target,
+  bfd_error_wrong_format,
+  bfd_error_invalid_operation,
+  bfd_error_no_memory,
+  bfd_error_no_symbols,
+  bfd_error_no_more_archived_files,
+  bfd_error_malformed_archive,
+  bfd_error_file_not_recognized,
+  bfd_error_file_ambiguously_recognized,
+  bfd_error_no_contents,
+  bfd_error_nonrepresentable_section,
+  bfd_error_no_debug_section,
+  bfd_error_bad_value,
+  bfd_error_file_truncated,
+  bfd_error_invalid_error_code
+} bfd_error_type;
+
+bfd_error_type 
+bfd_get_error  PARAMS ((void));
+
+void 
+bfd_set_error  PARAMS ((bfd_error_type error_tag));
+
+CONST char *
+bfd_errmsg  PARAMS ((bfd_error_type error_tag));
+
+void 
+bfd_perror  PARAMS ((CONST char *message));
+
+long 
+bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
+
+long 
+bfd_canonicalize_reloc
+ PARAMS ((bfd *abfd,
+    asection *sec,
+    arelent **loc,
+    asymbol	**syms));
+
+void 
+bfd_set_reloc
+ PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count)
+    
+    );
+
+boolean 
+bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags));
+
+boolean 
+bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma));
+
+long 
+bfd_get_mtime PARAMS ((bfd *abfd));
+
+long 
+bfd_get_size PARAMS ((bfd *abfd));
+
+int 
+bfd_get_gp_size PARAMS ((bfd *abfd));
+
+void 
+bfd_set_gp_size PARAMS ((bfd *abfd, int i));
+
+bfd_vma 
+bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base));
+
+boolean 
+bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
+
+#define bfd_copy_private_bfd_data(ibfd, obfd) \
+     BFD_SEND (ibfd, _bfd_copy_private_bfd_data, \
+		(ibfd, obfd))
+#define bfd_sizeof_headers(abfd, reloc) \
+     BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+     BFD_SEND (abfd, _bfd_find_nearest_line,  (abfd, sec, syms, off, file, func, line))
+
+        /* Do these three do anything useful at all, for any back end?  */
+#define bfd_debug_info_start(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+        BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+
+#define bfd_stat_arch_elt(abfd, stat) \
+        BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+
+#define bfd_set_arch_mach(abfd, arch, mach)\
+        BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
+
+#define bfd_get_relocated_section_contents(abfd, link_info, link_order, data, relocateable, symbols) \
+	BFD_SEND (abfd, _bfd_get_relocated_section_contents, \
+                 (abfd, link_info, link_order, data, relocateable, symbols))
+ 
+#define bfd_relax_section(abfd, section, link_info, again) \
+       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
+
+#define bfd_link_hash_table_create(abfd) \
+	BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
+
+#define bfd_link_add_symbols(abfd, info) \
+	BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
+
+#define bfd_final_link(abfd, info) \
+	BFD_SEND (abfd, _bfd_final_link, (abfd, info))
+
+#define bfd_free_cached_info(abfd) \
+       BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
+
+#define bfd_get_dynamic_symtab_upper_bound(abfd) \
+	BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
+
+#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
+	BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
+
+#define bfd_get_dynamic_reloc_upper_bound(abfd) \
+	BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
+
+#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
+	BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
+
+symindex 
+bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));
+
+boolean 
+bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head));
+
+bfd *
+bfd_get_elt_at_index PARAMS ((bfd *archive, int index));
+
+bfd *
+bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous));
+
+CONST char *
+bfd_core_file_failing_command PARAMS ((bfd *abfd));
+
+int 
+bfd_core_file_failing_signal PARAMS ((bfd *abfd));
+
+boolean 
+core_file_matches_executable_p
+ PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+
+#define BFD_SEND(bfd, message, arglist) \
+               ((*((bfd)->xvec->message)) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND
+#define BFD_SEND(bfd, message, arglist) \
+  (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+    ((*((bfd)->xvec->message)) arglist) : \
+    (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+#define BFD_SEND_FMT(bfd, message, arglist) \
+            (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND_FMT
+#define BFD_SEND_FMT(bfd, message, arglist) \
+  (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+   (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \
+   (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+enum bfd_flavour {
+  bfd_target_unknown_flavour,
+  bfd_target_aout_flavour,
+  bfd_target_coff_flavour,
+  bfd_target_ecoff_flavour,
+  bfd_target_elf_flavour,
+  bfd_target_ieee_flavour,
+  bfd_target_nlm_flavour,
+  bfd_target_oasys_flavour,
+  bfd_target_tekhex_flavour,
+  bfd_target_srec_flavour,
+  bfd_target_som_flavour,
+  bfd_target_os9k_flavour};
+
+ /* Forward declaration.  */
+typedef struct bfd_link_info _bfd_link_info;
+
+typedef struct bfd_target
+{
+  char *name;
+  enum bfd_flavour flavour;
+  boolean byteorder_big_p;
+  boolean header_byteorder_big_p;
+  flagword object_flags;       
+  flagword section_flags;
+  char symbol_leading_char;
+  char ar_pad_char;            
+  unsigned short ar_max_namelen;
+  unsigned int align_power_min;
+  bfd_vma      (*bfd_getx64) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *));
+  void         (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma      (*bfd_getx32) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *));
+  void         (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma      (*bfd_getx16) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *));
+  void         (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma      (*bfd_h_getx64) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *));
+  void         (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma      (*bfd_h_getx32) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *));
+  void         (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
+  bfd_vma      (*bfd_h_getx16) PARAMS ((const bfd_byte *));
+  bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *));
+  void         (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
+  struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
+  boolean             (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
+  boolean             (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
+
+   /* Generic entry points.  */
+#define BFD_JUMP_TABLE_GENERIC(NAME)\
+CAT(NAME,_close_and_cleanup),\
+CAT(NAME,_bfd_free_cached_info),\
+CAT(NAME,_new_section_hook),\
+CAT(NAME,_get_section_contents)
+   /* Called when the BFD is being closed to do any necessary cleanup.  */
+  boolean       (*_close_and_cleanup) PARAMS ((bfd *));
+   /* Ask the BFD to free all cached information.  */
+  boolean (*_bfd_free_cached_info) PARAMS ((bfd *));
+   /* Called when a new section is created.  */
+  boolean       (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
+   /* Read the contents of a section.  */
+  boolean       (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, 
+                                            file_ptr, bfd_size_type));
+
+   /* Entry points to copy private data.  */
+#define BFD_JUMP_TABLE_COPY(NAME)\
+CAT(NAME,_bfd_copy_private_bfd_data),\
+CAT(NAME,_bfd_copy_private_section_data)
+   /* Called to copy BFD general private data from one object file
+     to another.  */
+  boolean	 (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *));
+   /* Called to copy BFD private section data from one object file
+     to another.  */
+  boolean       (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr,
+                                                       bfd *, sec_ptr));
+
+   /* Core file entry points.  */
+#define BFD_JUMP_TABLE_CORE(NAME)\
+CAT(NAME,_core_file_failing_command),\
+CAT(NAME,_core_file_failing_signal),\
+CAT(NAME,_core_file_matches_executable_p)
+  char *   (*_core_file_failing_command) PARAMS ((bfd *));
+  int      (*_core_file_failing_signal) PARAMS ((bfd *));
+  boolean  (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
+
+   /* Archive entry points.  */
+#define BFD_JUMP_TABLE_ARCHIVE(NAME)\
+CAT(NAME,_slurp_armap),\
+CAT(NAME,_slurp_extended_name_table),\
+CAT(NAME,_truncate_arname),\
+CAT(NAME,_write_armap),\
+CAT(NAME,_openr_next_archived_file),\
+CAT(NAME,_generic_stat_arch_elt)
+  boolean  (*_bfd_slurp_armap) PARAMS ((bfd *));
+  boolean  (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
+  void     (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *));
+  boolean  (*write_armap) PARAMS ((bfd *arch, 
+                              unsigned int elength,
+                              struct orl *map,
+                              unsigned int orl_count, 
+                              int stridx));
+  bfd *      (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
+  int        (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
+ 
+   /* Entry points used for symbols.  */
+#define BFD_JUMP_TABLE_SYMBOLS(NAME)\
+CAT(NAME,_get_symtab_upper_bound),\
+CAT(NAME,_get_symtab),\
+CAT(NAME,_make_empty_symbol),\
+CAT(NAME,_print_symbol),\
+CAT(NAME,_get_symbol_info),\
+CAT(NAME,_bfd_is_local_label),\
+CAT(NAME,_get_lineno),\
+CAT(NAME,_find_nearest_line),\
+CAT(NAME,_bfd_make_debug_symbol)
+  long  (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *));
+  long  (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
+                                             struct symbol_cache_entry **));
+  struct symbol_cache_entry  *
+                (*_bfd_make_empty_symbol) PARAMS ((bfd *));
+  void          (*_bfd_print_symbol) PARAMS ((bfd *, PTR,
+                                      struct symbol_cache_entry *,
+                                      bfd_print_symbol_type));
+#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+  void          (*_bfd_get_symbol_info) PARAMS ((bfd *,
+                                      struct symbol_cache_entry *,
+                                      symbol_info *));
+#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e))
+  boolean	 (*_bfd_is_local_label) PARAMS ((bfd *, asymbol *));
+
+  alent *    (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
+  boolean    (*_bfd_find_nearest_line) PARAMS ((bfd *abfd,
+                    struct sec *section, struct symbol_cache_entry **symbols,
+                    bfd_vma offset, CONST char **file, CONST char **func,
+                    unsigned int *line));
+  /* Back-door to allow format-aware applications to create debug symbols
+    while using BFD for everything else.  Currently used by the assembler
+    when creating COFF files.  */
+ asymbol *  (*_bfd_make_debug_symbol) PARAMS ((
+       bfd *abfd,
+       void *ptr,
+       unsigned long size));
+
+   /* Routines for relocs.  */
+#define BFD_JUMP_TABLE_RELOCS(NAME)\
+CAT(NAME,_get_reloc_upper_bound),\
+CAT(NAME,_canonicalize_reloc),\
+CAT(NAME,_bfd_reloc_type_lookup)
+  long  (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
+  long  (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **,
+                                            struct symbol_cache_entry **));
+   /* See documentation on reloc types.  */
+  CONST struct reloc_howto_struct *
+       (*reloc_type_lookup) PARAMS ((bfd *abfd,
+                                     bfd_reloc_code_real_type code));
+
+   /* Routines used when writing an object file.  */
+#define BFD_JUMP_TABLE_WRITE(NAME)\
+CAT(NAME,_set_arch_mach),\
+CAT(NAME,_set_section_contents)
+  boolean    (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture,
+                    unsigned long));
+  boolean       (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
+                                            file_ptr, bfd_size_type));
+
+   /* Routines used by the linker.  */
+#define BFD_JUMP_TABLE_LINK(NAME)\
+CAT(NAME,_sizeof_headers),\
+CAT(NAME,_bfd_get_relocated_section_contents),\
+CAT(NAME,_bfd_relax_section),\
+CAT(NAME,_bfd_link_hash_table_create),\
+CAT(NAME,_bfd_link_add_symbols),\
+CAT(NAME,_bfd_final_link)
+  int        (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
+  bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
+                    struct bfd_link_info *, struct bfd_link_order *,
+                    bfd_byte *data, boolean relocateable,
+                    struct symbol_cache_entry **));
+
+  boolean    (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
+                    struct bfd_link_info *, boolean *again));
+
+   /* Create a hash table for the linker.  Different backends store
+     different information in this table.  */
+  struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *));
+
+   /* Add symbols from this object file into the hash table.  */
+  boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+
+   /* Do a link based on the link_order structures attached to each
+     section of the BFD.  */
+  boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
+
+  /* Routines to handle dynamic symbols and relocs.  */
+#define BFD_JUMP_TABLE_DYNAMIC(NAME)\
+CAT(NAME,_get_dynamic_symtab_upper_bound),\
+CAT(NAME,_canonicalize_dynamic_symtab),\
+CAT(NAME,_get_dynamic_reloc_upper_bound),\
+CAT(NAME,_canonicalize_dynamic_reloc)
+   /* Get the amount of memory required to hold the dynamic symbols. */
+  long  (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *));
+   /* Read in the dynamic symbols.  */
+  long  (*_bfd_canonicalize_dynamic_symtab)
+    PARAMS ((bfd *, struct symbol_cache_entry **));
+   /* Get the amount of memory required to hold the dynamic relocs.  */
+  long  (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *));
+   /* Read in the dynamic relocs.  */
+  long  (*_bfd_canonicalize_dynamic_reloc)
+    PARAMS ((bfd *, arelent **, struct symbol_cache_entry **));
+
+ PTR backend_data;
+} bfd_target;
+bfd_target *
+bfd_find_target PARAMS ((CONST char *target_name, bfd *abfd));
+
+CONST char **
+bfd_target_list PARAMS ((void));
+
+boolean 
+bfd_check_format PARAMS ((bfd *abfd, bfd_format format));
+
+boolean 
+bfd_check_format_matches PARAMS ((bfd *abfd, bfd_format format, char ***matching));
+
+boolean 
+bfd_set_format PARAMS ((bfd *abfd, bfd_format format));
+
+CONST char *
+bfd_format_string PARAMS ((bfd_format format));
+
+#endif
diff --git a/debugger/opcodes/dis-asm.h b/debugger/opcodes/dis-asm.h
new file mode 100644
index 0000000..e38f5fd
--- /dev/null
+++ b/debugger/opcodes/dis-asm.h
@@ -0,0 +1,179 @@
+/* Interface between the opcode library and its callers.
+   Written by Cygnus Support, 1993.
+
+   The opcode library (libopcodes.a) provides instruction decoders for
+   a large variety of instruction sets, callable with an identical
+   interface, for making instruction-processing programs more independent
+   of the instruction set being processed.  */
+
+#include <stdio.h>
+#include "bfd.h"
+
+typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
+
+enum dis_insn_type {
+  dis_noninsn,			/* Not a valid instruction */
+  dis_nonbranch,		/* Not a branch instruction */
+  dis_branch,			/* Unconditional branch */
+  dis_condbranch,		/* Conditional branch */
+  dis_jsr,			/* Jump to subroutine */
+  dis_condjsr,			/* Conditional jump to subroutine */
+  dis_dref,			/* Data reference instruction */
+  dis_dref2			/* Two data references in instruction */
+};
+
+/* This struct is passed into the instruction decoding routine, 
+   and is passed back out into each callback.  The various fields are used
+   for conveying information from your main routine into your callbacks,
+   for passing information into the instruction decoders (such as the
+   addresses of the callback functions), or for passing information
+   back from the instruction decoders to their callers.
+
+   It must be initialized before it is first passed; this can be done
+   by hand, or using one of the initialization macros below.  */
+
+typedef struct disassemble_info {
+  fprintf_ftype fprintf_func;
+  FILE *stream;
+  PTR application_data;
+
+  /* For use by the disassembler.  */
+  int flags;
+  PTR private_data;
+
+  /* Function used to get bytes to disassemble.  MEMADDR is the
+     address of the stuff to be disassembled, MYADDR is the address to
+     put the bytes in, and LENGTH is the number of bytes to read.
+     INFO is a pointer to this struct.
+     Returns an errno value or 0 for success.  */
+  int (*read_memory_func)
+    PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
+	     struct disassemble_info *info));
+
+  /* Function which should be called if we get an error that we can't
+     recover from.  STATUS is the errno value from read_memory_func and
+     MEMADDR is the address that we were trying to read.  INFO is a
+     pointer to this struct.  */
+  void (*memory_error_func)
+    PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
+
+  /* Function called to print ADDR.  */
+  void (*print_address_func)
+    PARAMS ((bfd_vma addr, struct disassemble_info *info));
+
+  /* These are for buffer_read_memory.  */
+  bfd_byte *buffer;
+  bfd_vma buffer_vma;
+  int buffer_length;
+
+  /* Results from instruction decoders.  Not all decoders yet support
+     this information.  This info is set each time an instruction is
+     decoded, and is only valid for the last such instruction.
+
+     To determine whether this decoder supports this information, set
+     insn_info_valid to 0, decode an instruction, then check it.  */
+
+  char insn_info_valid;		/* Branch info has been set. */
+  char branch_delay_insns;	/* How many sequential insn's will run before
+				   a branch takes effect.  (0 = normal) */
+  char data_size;		/* Size of data reference in insn, in bytes */
+  enum dis_insn_type insn_type;	/* Type of instruction */
+  bfd_vma target;		/* Target address of branch or dref, if known;
+				   zero if unknown.  */
+  bfd_vma target2;		/* Second target address for dref2 */
+
+} disassemble_info;
+
+
+
+
+
+
+/* Standard disassemblers.  Disassemble one instruction at the given
+   target address.  Return number of bytes processed.  */
+typedef int (*disassembler_ftype)
+     PARAMS((bfd_vma, disassemble_info *));
+
+extern int print_insn_big_mips		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_mips	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i286		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i386		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m68k		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z8001		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z8002		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300h		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8500		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_alpha		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_sparc		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_big_a29k		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_a29k	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i960		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_sh		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_hppa		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m88k		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_big_powerpc	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_powerpc	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_rs6000		PARAMS ((bfd_vma, disassemble_info*));
+
+/* Fetch the disassembler for a given BFD, if that support is available.  */
+extern disassembler_ftype disassembler	PARAMS ((bfd *));
+
+
+/* This block of definitions is for particular callers who read instructions
+   into a buffer before calling the instruction decoder.  */
+
+/* Here is a function which callers may wish to use for read_memory_func.
+   It gets bytes from a buffer.  */
+extern int buffer_read_memory
+  PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
+
+/* This function goes with buffer_read_memory.
+   It prints a message using info->fprintf_func and info->stream.  */
+extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
+
+
+/* Just print the address is hex.  This is included for completeness even
+   though both GDB and objdump provide their own (to print symbolic
+   addresses).  */
+extern void generic_print_address
+  PARAMS ((bfd_vma, struct disassemble_info *));
+
+#define INIT_DISASSEMBLE_INFO(INFO, STREAM) \
+  (INFO).fprintf_func = (fprintf_ftype)fprintf, \
+  (INFO).stream = (STREAM), \
+  (INFO).buffer = NULL, \
+  (INFO).buffer_vma = 0, \
+  (INFO).buffer_length = 0, \
+  (INFO).read_memory_func = buffer_read_memory, \
+  (INFO).memory_error_func = perror_memory, \
+  (INFO).print_address_func = generic_print_address, \
+  (INFO).insn_info_valid = 0
+
+
+
+
+/* This block of definitions is for calling the instruction decoders
+   from GDB.  */
+
+/* GDB--Like target_read_memory, but slightly different parameters.  */
+extern int
+dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int len,
+			     disassemble_info *info));
+
+/* GDB--Like memory_error with slightly different parameters.  */
+extern void
+dis_asm_memory_error
+  PARAMS ((int status, bfd_vma memaddr, disassemble_info *info));
+
+/* GDB--Like print_address with slightly different parameters.  */
+extern void
+dis_asm_print_address PARAMS ((bfd_vma addr, disassemble_info *info));
+
+#define GDB_INIT_DISASSEMBLE_INFO(INFO, STREAM) \
+  (INFO).fprintf_func = (fprintf_ftype)fprintf_filtered, \
+  (INFO).stream = (STREAM), \
+  (INFO).read_memory_func = dis_asm_read_memory, \
+  (INFO).memory_error_func = dis_asm_memory_error, \
+  (INFO).print_address_func = dis_asm_print_address, \
+  (INFO).insn_info_valid = 0
diff --git a/debugger/opcodes/dis-asm.h-fsf b/debugger/opcodes/dis-asm.h-fsf
new file mode 100644
index 0000000..0e02a7e
--- /dev/null
+++ b/debugger/opcodes/dis-asm.h-fsf
@@ -0,0 +1,178 @@
+/* Interface between the opcode library and its callers.
+   Written by Cygnus Support, 1993.
+
+   The opcode library (libopcodes.a) provides instruction decoders for
+   a large variety of instruction sets, callable with an identical
+   interface, for making instruction-processing programs more independent
+   of the instruction set being processed.  */
+
+#include <stdio.h>
+#include "bfd.h"
+
+typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
+
+enum dis_insn_type {
+  dis_noninsn,			/* Not a valid instruction */
+  dis_nonbranch,		/* Not a branch instruction */
+  dis_branch,			/* Unconditional branch */
+  dis_condbranch,		/* Conditional branch */
+  dis_jsr,			/* Jump to subroutine */
+  dis_condjsr,			/* Conditional jump to subroutine */
+  dis_dref,			/* Data reference instruction */
+  dis_dref2			/* Two data references in instruction */
+};
+
+/* This struct is passed into the instruction decoding routine, 
+   and is passed back out into each callback.  The various fields are used
+   for conveying information from your main routine into your callbacks,
+   for passing information into the instruction decoders (such as the
+   addresses of the callback functions), or for passing information
+   back from the instruction decoders to their callers.
+
+   It must be initialized before it is first passed; this can be done
+   by hand, or using one of the initialization macros below.  */
+
+typedef struct disassemble_info {
+  fprintf_ftype fprintf_func;
+  FILE *stream;
+  PTR application_data;
+
+  /* For use by the disassembler.  */
+  int flags;
+  PTR private_data;
+
+  /* Function used to get bytes to disassemble.  MEMADDR is the
+     address of the stuff to be disassembled, MYADDR is the address to
+     put the bytes in, and LENGTH is the number of bytes to read.
+     INFO is a pointer to this struct.
+     Returns an errno value or 0 for success.  */
+  int (*read_memory_func)
+    PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
+	     struct disassemble_info *info));
+
+  /* Function which should be called if we get an error that we can't
+     recover from.  STATUS is the errno value from read_memory_func and
+     MEMADDR is the address that we were trying to read.  INFO is a
+     pointer to this struct.  */
+  void (*memory_error_func)
+    PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
+
+  /* Function called to print ADDR.  */
+  void (*print_address_func)
+    PARAMS ((bfd_vma addr, struct disassemble_info *info));
+
+  /* These are for buffer_read_memory.  */
+  bfd_byte *buffer;
+  bfd_vma buffer_vma;
+  int buffer_length;
+
+  /* Results from instruction decoders.  Not all decoders yet support
+     this information.  This info is set each time an instruction is
+     decoded, and is only valid for the last such instruction.
+
+     To determine whether this decoder supports this information, set
+     insn_info_valid to 0, decode an instruction, then check it.  */
+
+  char insn_info_valid;		/* Branch info has been set. */
+  char branch_delay_insns;	/* How many sequential insn's will run before
+				   a branch takes effect.  (0 = normal) */
+  char data_size;		/* Size of data reference in insn, in bytes */
+  enum dis_insn_type insn_type;	/* Type of instruction */
+  bfd_vma target;		/* Target address of branch or dref, if known;
+				   zero if unknown.  */
+  bfd_vma target2;		/* Second target address for dref2 */
+
+} disassemble_info;
+
+
+
+
+
+
+/* Standard disassemblers.  Disassemble one instruction at the given
+   target address.  Return number of bytes processed.  */
+typedef int (*disassembler_ftype)
+     PARAMS((bfd_vma, disassemble_info *));
+
+extern int print_insn_big_mips		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_mips	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i386		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m68k		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z8001		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z8002		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300h		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8500		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_alpha		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_sparc		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_big_a29k		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_a29k	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i960		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_sh		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_hppa		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m88k		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_big_powerpc	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_powerpc	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_rs6000		PARAMS ((bfd_vma, disassemble_info*));
+
+/* Fetch the disassembler for a given BFD, if that support is available.  */
+extern disassembler_ftype disassembler	PARAMS ((bfd *));
+
+
+/* This block of definitions is for particular callers who read instructions
+   into a buffer before calling the instruction decoder.  */
+
+/* Here is a function which callers may wish to use for read_memory_func.
+   It gets bytes from a buffer.  */
+extern int buffer_read_memory
+  PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
+
+/* This function goes with buffer_read_memory.
+   It prints a message using info->fprintf_func and info->stream.  */
+extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
+
+
+/* Just print the address is hex.  This is included for completeness even
+   though both GDB and objdump provide their own (to print symbolic
+   addresses).  */
+extern void generic_print_address
+  PARAMS ((bfd_vma, struct disassemble_info *));
+
+#define INIT_DISASSEMBLE_INFO(INFO, STREAM) \
+  (INFO).fprintf_func = (fprintf_ftype)fprintf, \
+  (INFO).stream = (STREAM), \
+  (INFO).buffer = NULL, \
+  (INFO).buffer_vma = 0, \
+  (INFO).buffer_length = 0, \
+  (INFO).read_memory_func = buffer_read_memory, \
+  (INFO).memory_error_func = perror_memory, \
+  (INFO).print_address_func = generic_print_address, \
+  (INFO).insn_info_valid = 0
+
+
+
+
+/* This block of definitions is for calling the instruction decoders
+   from GDB.  */
+
+/* GDB--Like target_read_memory, but slightly different parameters.  */
+extern int
+dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int len,
+			     disassemble_info *info));
+
+/* GDB--Like memory_error with slightly different parameters.  */
+extern void
+dis_asm_memory_error
+  PARAMS ((int status, bfd_vma memaddr, disassemble_info *info));
+
+/* GDB--Like print_address with slightly different parameters.  */
+extern void
+dis_asm_print_address PARAMS ((bfd_vma addr, disassemble_info *info));
+
+#define GDB_INIT_DISASSEMBLE_INFO(INFO, STREAM) \
+  (INFO).fprintf_func = (fprintf_ftype)fprintf_filtered, \
+  (INFO).stream = (STREAM), \
+  (INFO).read_memory_func = dis_asm_read_memory, \
+  (INFO).memory_error_func = dis_asm_memory_error, \
+  (INFO).print_address_func = dis_asm_print_address, \
+  (INFO).insn_info_valid = 0
diff --git a/debugger/opcodes/dis-buf.c b/debugger/opcodes/dis-buf.c
new file mode 100644
index 0000000..d184b28
--- /dev/null
+++ b/debugger/opcodes/dis-buf.c
@@ -0,0 +1,70 @@
+/* Disassemble from a buffer, for GNU.
+   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "dis-asm.h"
+#include "sysdep.h"
+#include <errno.h>
+
+/* Get LENGTH bytes from info's buffer, at target address memaddr.
+   Transfer them to myaddr.  */
+int
+buffer_read_memory (memaddr, myaddr, length, info)
+     bfd_vma memaddr;
+     bfd_byte *myaddr;
+     int length;
+     struct disassemble_info *info;
+{
+  if (memaddr < info->buffer_vma
+      || memaddr + length > info->buffer_vma + info->buffer_length)
+    /* Out of bounds.  Use EIO because GDB uses it.  */
+    return EIO;
+  memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
+  return 0;
+}
+
+/* Print an error message.  We can assume that this is in response to
+   an error return from buffer_read_memory.  */
+void
+perror_memory (status, memaddr, info)
+     int status;
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  if (status != EIO)
+    /* Can't happen.  */
+    (*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
+  else
+    /* Actually, address between memaddr and memaddr + len was
+       out of bounds.  */
+    (*info->fprintf_func) (info->stream,
+			   "Address 0x%x is out of bounds.\n", memaddr);
+}
+
+/* This could be in a separate file, to save miniscule amounts of space
+   in statically linked executables.  */
+
+/* Just print the address is hex.  This is included for completeness even
+   though both GDB and objdump provide their own (to print symbolic
+   addresses).  */
+
+void
+generic_print_address (addr, info)
+     bfd_vma addr;
+     struct disassemble_info *info;
+{
+  (*info->fprintf_func) (info->stream, "0x%x", addr);
+}
diff --git a/debugger/i386-pinsn.c b/debugger/opcodes/i386-dis.c
similarity index 88%
copy from debugger/i386-pinsn.c
copy to debugger/opcodes/i386-dis.c
index 9a63361..9d5e179 100644
--- a/debugger/i386-pinsn.c
+++ b/debugger/opcodes/i386-dis.c
@@ -1,5 +1,5 @@
 /* Print i386 instructions for GDB, the GNU debugger.
-   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1989, 1991, 1993, 1994 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -20,6 +20,7 @@
 /*
  * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
  * July 1988
+ *  modified by John Hassey (hassey@dg-rtp.dg.com)
  */
 
 /*
@@ -31,12 +32,51 @@
  * the Intel manual for details.
  */
 
-#include "defs.h"
+#include "dis-asm.h"
+#include "sysdep.h"
 
-#include <ctype.h>
+#define MAXLEN 20
 
-/* For the GDB interface at the bottom of the file... */
-#include "gdbcore.h"
+#include <setjmp.h>
+
+struct dis_private
+{
+  /* Points to first byte not fetched.  */
+  bfd_byte *max_fetched;
+  bfd_byte the_buffer[MAXLEN];
+  bfd_vma insn_start;
+  jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
+   on error.  */
+#define FETCH_DATA(info, addr) \
+  ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
+   ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+     struct disassemble_info *info;
+     bfd_byte *addr;
+{
+  int status;
+  struct dis_private *priv = (struct dis_private *)info->private_data;
+  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+  status = (*info->read_memory_func) (start,
+				      priv->max_fetched,
+				      addr - priv->max_fetched,
+				      info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, start, info);
+      longjmp (priv->bailout, 1);
+    }
+  else
+    priv->max_fetched = addr;
+  return 1;
+}
 
 #define Eb OP_E, b_mode
 #define indirEb OP_indirE, b_mode
@@ -376,8 +416,8 @@
   { "stosS",	Yv, eAX },
   { "lodsb",	AL, Xb },
   { "lodsS",	eAX, Xv },
-  { "scasb",	AL, Xb },
-  { "scasS",	eAX, Xv },
+  { "scasb",	AL, Yb },
+  { "scasS",	eAX, Yv },
   /* b0 */
   { "movb",	AL, Ib },
   { "movb",	CL, Ib },
@@ -481,7 +521,9 @@
   { "clts" },
   { "(bad)" },  
   /* 08 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "invd" },
+  { "wbinvd" },
+  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 10 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -587,8 +629,8 @@
   { "(bad)" },
   { "imulS", Gv, Ev },  
   /* b0 */
-  { "(bad)" },
-  { "(bad)" },
+  { "cmpxchgb", Eb, Gb },
+  { "cmpxchgS", Ev, Gv },
   { "lssS", Gv, Mp },	/* 386 lists only Mp */
   { "btrS", Ev, Gv },  
   { "lfsS", Gv, Mp },	/* 386 lists only Mp */
@@ -605,11 +647,19 @@
   { "movsbS", Gv, Eb },
   { "movswS", Gv, Ew },  
   /* c0 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "xaddb", Eb, Gb },
+  { "xaddS", Ev, Gv },
+  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* c8 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "bswap", eAX },
+  { "bswap", eCX },
+  { "bswap", eDX },
+  { "bswap", eBX },
+  { "bswap", eSP },
+  { "bswap", eBP },
+  { "bswap", eSI },
+  { "bswap", eDI },
   /* d0 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -635,6 +685,7 @@
 static char scratchbuf[100];
 static unsigned char *start_codep;
 static unsigned char *codep;
+static disassemble_info *the_info;
 static int mod;
 static int rm;
 static int reg;
@@ -817,7 +868,7 @@
     { "smsw", Ew },
     { "(bad)" },
     { "lmsw", Ew },
-    { "(bad)" },
+    { "invlpg", Ew },
   },
   /* GRP8 */
   {
@@ -853,6 +904,7 @@
   prefixes = 0;
   while (1)
     {
+      FETCH_DATA (the_info, codep + 1);
       switch (*codep)
 	{
 	case 0xf3:
@@ -904,27 +956,20 @@
 static char op1out[100], op2out[100], op3out[100];
 static int op_address[3], op_ad, op_index[3];
 static int start_pc;
-extern void fputs_filtered ();
 
+
 /*
- * disassemble the first instruction in 'inbuf'.  You have to make
- *   sure all of the bytes of the instruction are filled in.
  *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
  *   (see topic "Redundant prefixes" in the "Differences from 8086"
  *   section of the "Virtual 8086 Mode" chapter.)
  * 'pc' should be the address of this instruction, it will
  *   be used to print the target address if this is a relative jump or call
- * 'outbuf' gets filled in with the disassembled instruction.  it should
- *   be long enough to hold the longest disassembled instruction.
- *   100 bytes is certainly enough, unless symbol printing is added later
  * The function returns the length of this instruction in bytes.
  */
-
-int
-i386dis (pc, inbuf, stream)
-     int pc;
-     unsigned char *inbuf;
-     FILE *stream;
+static int
+print_insn_i286_or_i386 (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
 {
   struct dis386 *dp;
   int i;
@@ -932,19 +977,31 @@
   char *first, *second, *third;
   int needcomma;
   
+  struct dis_private priv;
+  bfd_byte *inbuf = priv.the_buffer;
+
+  info->private_data = (PTR) &priv;
+  priv.max_fetched = priv.the_buffer;
+  priv.insn_start = pc;
+  if (setjmp (priv.bailout) != 0)
+    /* Error return.  */
+    return -1;
+
   obuf[0] = 0;
   op1out[0] = 0;
   op2out[0] = 0;
   op3out[0] = 0;
 
   op_index[0] = op_index[1] = op_index[2] = -1;
-  
+
+  the_info = info;
   start_pc = pc;
   start_codep = inbuf;
   codep = inbuf;
   
   ckprefix ();
-  
+
+  FETCH_DATA (info, codep + 1);
   if (*codep == 0xc8)
     enter_instruction = 1;
   else
@@ -963,12 +1020,10 @@
       && ((*codep < 0xd8) || (*codep > 0xdf)))
     {
       /* fwait not followed by floating point instruction */
-      fputs_filtered ("fwait", stream);
+      (*info->fprintf_func) (info->stream, "fwait");
       return (1);
     }
   
-  /* these would be initialized to 0 if disassembling for 8086 or 286 */
-
   if (prefixes & PREFIX_DATA)
     dflag ^= 1;
   
@@ -979,14 +1034,24 @@
     }
   
   if (*codep == 0x0f)
-    dp = &dis386_twobyte[*++codep];
+    {
+      FETCH_DATA (info, codep + 2);
+      dp = &dis386_twobyte[*++codep];
+    }
   else
     dp = &dis386[*codep];
   codep++;
+
+  /* Fetch the mod/reg/rm byte.  FIXME: We should be only fetching
+     this if we need it.  As it is, this code loses if there is a
+     one-byte instruction (without a mod/reg/rm byte) at the end of
+     the address space.  */
+
+  FETCH_DATA (info, codep + 1);
   mod = (*codep >> 6) & 3;
   reg = (*codep >> 3) & 7;
   rm = *codep & 7;
-  
+
   if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
     {
       dofloat ();
@@ -1018,7 +1083,7 @@
   for (i = strlen (obuf); i < 6; i++)
     oappend (" ");
   oappend (" ");
-  fputs_filtered (obuf, stream);
+  (*info->fprintf_func) (info->stream, "%s", obuf);
   
   /* enter instruction is printed with operands in the
    * same order as the intel book; everything else
@@ -1043,33 +1108,53 @@
   if (*first)
     {
       if (op_index[0] != -1)
-	print_address (op_address[op_index[0]], stream);
+	(*info->print_address_func) (op_address[op_index[0]], info);
       else
-	fputs_filtered (first, stream);
+	(*info->fprintf_func) (info->stream, "%s", first);
       needcomma = 1;
     }
   if (*second)
     {
       if (needcomma)
-	fputs_filtered (",", stream);
+	(*info->fprintf_func) (info->stream, ",");
       if (op_index[1] != -1)
-	print_address (op_address[op_index[1]], stream);
+	(*info->print_address_func) (op_address[op_index[1]], info);
       else
-	fputs_filtered (second, stream);
+	(*info->fprintf_func) (info->stream, "%s", second);
       needcomma = 1;
     }
   if (*third)
     {
       if (needcomma)
-	fputs_filtered (",", stream);
+	(*info->fprintf_func) (info->stream, ",");
       if (op_index[2] != -1)
-	print_address (op_address[op_index[2]], stream);
+	(*info->print_address_func) (op_address[op_index[2]], info);
       else
-	fputs_filtered (third, stream);
+	(*info->fprintf_func) (info->stream, "%s", third);
     }
   return (codep - inbuf);
 }
 
+int
+print_insn_i286 (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
+  dflag = 0;
+  aflag = 0;
+  return print_insn_i286_or_i386 (pc, info);
+}
+
+int
+print_insn_i386 (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
+  dflag = 1;
+  aflag = 1;
+  return print_insn_i286_or_i386 (pc, info, 36);
+}
+
 char *float_mem[] = {
   /* d8 */
   "fadds",
@@ -1321,7 +1406,9 @@
     {
       putop (fgrps[dp->bytemode1][rm]);
       /* instruction fnstsw is only one with strange arg */
-      if (floatop == 0xdf && *codep == 0xe0)
+      if (floatop == 0xdf
+	  && FETCH_DATA (the_info, codep + 1)
+	  && *codep == 0xe0)
 	strcpy (op1out, "%eax");
     }
   else
@@ -1469,59 +1556,64 @@
   append_prefix ();
 
   if (bytemode == w_mode || (bytemode == v_mode && !dflag))
-  {
+    {
       if (mod == 0 && rm == 6)
-      {
-	  sprintf(scratchbuf, "%04.4x", get16());
-	  oappend(scratchbuf);
+	{
+	  sprintf (scratchbuf, "0x%04.4x", get16 ());
+	  oappend (scratchbuf);
 	  return 0;
-      }
+	}
       
-      disp = 0;
       if (mod == 1)
+	{
+	  FETCH_DATA (the_info, codep + 1);
 	  disp = *(char *)codep++;
+	}
       else if (mod == 2)
-	  disp = get16();
+	disp = get16 ();
+      else
+	disp = 0;
       if (disp != 0)
-      {
-	  sprintf(scratchbuf, "0x%x", disp);
-	  oappend(scratchbuf);
-      }
+	{
+	  sprintf (scratchbuf, "0x%x", disp & 0xffff);
+	  oappend (scratchbuf);
+	}
 
       switch (rm)
-      {
+	{
 	case 0:
-	  oappend("(%bx,%si)");
+	  oappend ("(%bx,%si)");
 	  break;
 	case 1:
-	  oappend("(%bx,%di)");
+	  oappend ("(%bx,%di)");
 	  break;
 	case 2:
-	  oappend("(%bp,%si)");
+	  oappend ("(%bp,%si)");
 	  break;
 	case 3:
-	  oappend("(%bp,%di)");
+	  oappend ("(%bp,%di)");
 	  break;
 	case 4:
-	  oappend("(%si)");
+	  oappend ("(%si)");
 	  break;
 	case 5:
-	  oappend("(%di)");
+	  oappend ("(%di)");
 	  break;
 	case 6:
-	  oappend("(%bp)");
+	  oappend ("(%bp)");
 	  break;
 	case 7:
-	  oappend("(%bx)");
+	  oappend ("(%bx)");
 	  break;
-      }	  
+	}	  
       return 0;
-  }
-  
+    }
+
   if (rm == 4)
     {
       havesib = 1;
       havebase = 1;
+      FETCH_DATA (the_info, codep + 1);
       scale = (*codep >> 6) & 3;
       index = (*codep >> 3) & 7;
       base = *codep & 7;
@@ -1550,6 +1642,7 @@
 	}
       break;
     case 1:
+      FETCH_DATA (the_info, codep + 1);
       disp = *(char *)codep++;
       if (rm != 4)
 	{
@@ -1625,7 +1718,8 @@
 get32 ()
 {
   int x = 0;
-  
+
+  FETCH_DATA (the_info, codep + 4);
   x = *codep++ & 0xff;
   x |= (*codep++ & 0xff) << 8;
   x |= (*codep++ & 0xff) << 16;
@@ -1637,7 +1731,8 @@
 get16 ()
 {
   int x = 0;
-  
+
+  FETCH_DATA (the_info, codep + 2);
   x = *codep++ & 0xff;
   x |= (*codep++ & 0xff) << 8;
   return (x);
@@ -1696,6 +1791,7 @@
   switch (bytemode) 
     {
     case b_mode:
+      FETCH_DATA (the_info, codep + 1);
       op = *codep++ & 0xff;
       break;
     case v_mode:
@@ -1725,6 +1821,7 @@
   switch (bytemode) 
     {
     case b_mode:
+      FETCH_DATA (the_info, codep + 1);
       op = *(char *)codep++;
       break;
     case v_mode:
@@ -1755,6 +1852,7 @@
   switch (bytemode) 
     {
     case b_mode:
+      FETCH_DATA (the_info, codep + 1);
       disp = *(char *)codep++;
       break;
     case v_mode:
@@ -1929,28 +2027,3 @@
     }
   return (0);
 }
-	
-#define MAXLEN 20
-
-int
-print_insn (realmemaddr, memaddr, stream, addrlen)
-     CORE_ADDR memaddr, realmemaddr;
-     FILE *stream;
-     int addrlen;
-{
-  unsigned char buffer[MAXLEN];
-  
-  if(addrlen == 32){
-	  dflag = 1;
-	  aflag = 1;
-  } else {
-	  dflag = 0;
-	  aflag = 0;
-  };  
-
-
-  read_memory (memaddr, (char *) buffer, MAXLEN);
-  
-  return (i386dis ((int)realmemaddr, buffer, stream));
-}
-
diff --git a/debugger/i386-pinsn.c b/debugger/opcodes/i386-dis.c-fsf
similarity index 90%
rename from debugger/i386-pinsn.c
rename to debugger/opcodes/i386-dis.c-fsf
index 9a63361..7f9641d 100644
--- a/debugger/i386-pinsn.c
+++ b/debugger/opcodes/i386-dis.c-fsf
@@ -1,5 +1,5 @@
 /* Print i386 instructions for GDB, the GNU debugger.
-   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1989, 1991, 1993, 1994 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -20,6 +20,7 @@
 /*
  * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
  * July 1988
+ *  modified by John Hassey (hassey@dg-rtp.dg.com)
  */
 
 /*
@@ -31,12 +32,51 @@
  * the Intel manual for details.
  */
 
-#include "defs.h"
+#include "dis-asm.h"
+#include "sysdep.h"
 
-#include <ctype.h>
+#define MAXLEN 20
 
-/* For the GDB interface at the bottom of the file... */
-#include "gdbcore.h"
+#include <setjmp.h>
+
+struct dis_private
+{
+  /* Points to first byte not fetched.  */
+  bfd_byte *max_fetched;
+  bfd_byte the_buffer[MAXLEN];
+  bfd_vma insn_start;
+  jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
+   on error.  */
+#define FETCH_DATA(info, addr) \
+  ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
+   ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+     struct disassemble_info *info;
+     bfd_byte *addr;
+{
+  int status;
+  struct dis_private *priv = (struct dis_private *)info->private_data;
+  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+  status = (*info->read_memory_func) (start,
+				      priv->max_fetched,
+				      addr - priv->max_fetched,
+				      info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, start, info);
+      longjmp (priv->bailout, 1);
+    }
+  else
+    priv->max_fetched = addr;
+  return 1;
+}
 
 #define Eb OP_E, b_mode
 #define indirEb OP_indirE, b_mode
@@ -376,8 +416,8 @@
   { "stosS",	Yv, eAX },
   { "lodsb",	AL, Xb },
   { "lodsS",	eAX, Xv },
-  { "scasb",	AL, Xb },
-  { "scasS",	eAX, Xv },
+  { "scasb",	AL, Yb },
+  { "scasS",	eAX, Yv },
   /* b0 */
   { "movb",	AL, Ib },
   { "movb",	CL, Ib },
@@ -481,7 +521,9 @@
   { "clts" },
   { "(bad)" },  
   /* 08 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "invd" },
+  { "wbinvd" },
+  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 10 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -587,8 +629,8 @@
   { "(bad)" },
   { "imulS", Gv, Ev },  
   /* b0 */
-  { "(bad)" },
-  { "(bad)" },
+  { "cmpxchgb", Eb, Gb },
+  { "cmpxchgS", Ev, Gv },
   { "lssS", Gv, Mp },	/* 386 lists only Mp */
   { "btrS", Ev, Gv },  
   { "lfsS", Gv, Mp },	/* 386 lists only Mp */
@@ -605,11 +647,19 @@
   { "movsbS", Gv, Eb },
   { "movswS", Gv, Ew },  
   /* c0 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "xaddb", Eb, Gb },
+  { "xaddS", Ev, Gv },
+  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* c8 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "bswap", eAX },
+  { "bswap", eCX },
+  { "bswap", eDX },
+  { "bswap", eBX },
+  { "bswap", eSP },
+  { "bswap", eBP },
+  { "bswap", eSI },
+  { "bswap", eDI },
   /* d0 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -635,6 +685,7 @@
 static char scratchbuf[100];
 static unsigned char *start_codep;
 static unsigned char *codep;
+static disassemble_info *the_info;
 static int mod;
 static int rm;
 static int reg;
@@ -817,7 +868,7 @@
     { "smsw", Ew },
     { "(bad)" },
     { "lmsw", Ew },
-    { "(bad)" },
+    { "invlpg", Ew },
   },
   /* GRP8 */
   {
@@ -853,6 +904,7 @@
   prefixes = 0;
   while (1)
     {
+      FETCH_DATA (the_info, codep + 1);
       switch (*codep)
 	{
 	case 0xf3:
@@ -904,27 +956,21 @@
 static char op1out[100], op2out[100], op3out[100];
 static int op_address[3], op_ad, op_index[3];
 static int start_pc;
-extern void fputs_filtered ();
 
+
 /*
- * disassemble the first instruction in 'inbuf'.  You have to make
- *   sure all of the bytes of the instruction are filled in.
  *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
  *   (see topic "Redundant prefixes" in the "Differences from 8086"
  *   section of the "Virtual 8086 Mode" chapter.)
  * 'pc' should be the address of this instruction, it will
  *   be used to print the target address if this is a relative jump or call
- * 'outbuf' gets filled in with the disassembled instruction.  it should
- *   be long enough to hold the longest disassembled instruction.
- *   100 bytes is certainly enough, unless symbol printing is added later
  * The function returns the length of this instruction in bytes.
  */
 
 int
-i386dis (pc, inbuf, stream)
-     int pc;
-     unsigned char *inbuf;
-     FILE *stream;
+print_insn_i386 (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
 {
   struct dis386 *dp;
   int i;
@@ -932,19 +978,31 @@
   char *first, *second, *third;
   int needcomma;
   
+  struct dis_private priv;
+  bfd_byte *inbuf = priv.the_buffer;
+
+  info->private_data = (PTR) &priv;
+  priv.max_fetched = priv.the_buffer;
+  priv.insn_start = pc;
+  if (setjmp (priv.bailout) != 0)
+    /* Error return.  */
+    return -1;
+
   obuf[0] = 0;
   op1out[0] = 0;
   op2out[0] = 0;
   op3out[0] = 0;
 
   op_index[0] = op_index[1] = op_index[2] = -1;
-  
+
+  the_info = info;
   start_pc = pc;
   start_codep = inbuf;
   codep = inbuf;
   
   ckprefix ();
-  
+
+  FETCH_DATA (info, codep + 1);
   if (*codep == 0xc8)
     enter_instruction = 1;
   else
@@ -963,12 +1021,14 @@
       && ((*codep < 0xd8) || (*codep > 0xdf)))
     {
       /* fwait not followed by floating point instruction */
-      fputs_filtered ("fwait", stream);
+      (*info->fprintf_func) (info->stream, "fwait");
       return (1);
     }
   
   /* these would be initialized to 0 if disassembling for 8086 or 286 */
-
+  dflag = 1;
+  aflag = 1;
+  
   if (prefixes & PREFIX_DATA)
     dflag ^= 1;
   
@@ -979,14 +1039,24 @@
     }
   
   if (*codep == 0x0f)
-    dp = &dis386_twobyte[*++codep];
+    {
+      FETCH_DATA (info, codep + 2);
+      dp = &dis386_twobyte[*++codep];
+    }
   else
     dp = &dis386[*codep];
   codep++;
+
+  /* Fetch the mod/reg/rm byte.  FIXME: We should be only fetching
+     this if we need it.  As it is, this code loses if there is a
+     one-byte instruction (without a mod/reg/rm byte) at the end of
+     the address space.  */
+
+  FETCH_DATA (info, codep + 1);
   mod = (*codep >> 6) & 3;
   reg = (*codep >> 3) & 7;
   rm = *codep & 7;
-  
+
   if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
     {
       dofloat ();
@@ -1018,7 +1088,7 @@
   for (i = strlen (obuf); i < 6; i++)
     oappend (" ");
   oappend (" ");
-  fputs_filtered (obuf, stream);
+  (*info->fprintf_func) (info->stream, "%s", obuf);
   
   /* enter instruction is printed with operands in the
    * same order as the intel book; everything else
@@ -1043,29 +1113,29 @@
   if (*first)
     {
       if (op_index[0] != -1)
-	print_address (op_address[op_index[0]], stream);
+	(*info->print_address_func) (op_address[op_index[0]], info);
       else
-	fputs_filtered (first, stream);
+	(*info->fprintf_func) (info->stream, "%s", first);
       needcomma = 1;
     }
   if (*second)
     {
       if (needcomma)
-	fputs_filtered (",", stream);
+	(*info->fprintf_func) (info->stream, ",");
       if (op_index[1] != -1)
-	print_address (op_address[op_index[1]], stream);
+	(*info->print_address_func) (op_address[op_index[1]], info);
       else
-	fputs_filtered (second, stream);
+	(*info->fprintf_func) (info->stream, "%s", second);
       needcomma = 1;
     }
   if (*third)
     {
       if (needcomma)
-	fputs_filtered (",", stream);
+	(*info->fprintf_func) (info->stream, ",");
       if (op_index[2] != -1)
-	print_address (op_address[op_index[2]], stream);
+	(*info->print_address_func) (op_address[op_index[2]], info);
       else
-	fputs_filtered (third, stream);
+	(*info->fprintf_func) (info->stream, "%s", third);
     }
   return (codep - inbuf);
 }
@@ -1321,7 +1391,9 @@
     {
       putop (fgrps[dp->bytemode1][rm]);
       /* instruction fnstsw is only one with strange arg */
-      if (floatop == 0xdf && *codep == 0xe0)
+      if (floatop == 0xdf
+	  && FETCH_DATA (the_info, codep + 1)
+	  && *codep == 0xe0)
 	strcpy (op1out, "%eax");
     }
   else
@@ -1467,61 +1539,11 @@
     }
   
   append_prefix ();
-
-  if (bytemode == w_mode || (bytemode == v_mode && !dflag))
-  {
-      if (mod == 0 && rm == 6)
-      {
-	  sprintf(scratchbuf, "%04.4x", get16());
-	  oappend(scratchbuf);
-	  return 0;
-      }
-      
-      disp = 0;
-      if (mod == 1)
-	  disp = *(char *)codep++;
-      else if (mod == 2)
-	  disp = get16();
-      if (disp != 0)
-      {
-	  sprintf(scratchbuf, "0x%x", disp);
-	  oappend(scratchbuf);
-      }
-
-      switch (rm)
-      {
-	case 0:
-	  oappend("(%bx,%si)");
-	  break;
-	case 1:
-	  oappend("(%bx,%di)");
-	  break;
-	case 2:
-	  oappend("(%bp,%si)");
-	  break;
-	case 3:
-	  oappend("(%bp,%di)");
-	  break;
-	case 4:
-	  oappend("(%si)");
-	  break;
-	case 5:
-	  oappend("(%di)");
-	  break;
-	case 6:
-	  oappend("(%bp)");
-	  break;
-	case 7:
-	  oappend("(%bx)");
-	  break;
-      }	  
-      return 0;
-  }
-  
   if (rm == 4)
     {
       havesib = 1;
       havebase = 1;
+      FETCH_DATA (the_info, codep + 1);
       scale = (*codep >> 6) & 3;
       index = (*codep >> 3) & 7;
       base = *codep & 7;
@@ -1550,6 +1572,7 @@
 	}
       break;
     case 1:
+      FETCH_DATA (the_info, codep + 1);
       disp = *(char *)codep++;
       if (rm != 4)
 	{
@@ -1625,7 +1648,8 @@
 get32 ()
 {
   int x = 0;
-  
+
+  FETCH_DATA (the_info, codep + 4);
   x = *codep++ & 0xff;
   x |= (*codep++ & 0xff) << 8;
   x |= (*codep++ & 0xff) << 16;
@@ -1637,7 +1661,8 @@
 get16 ()
 {
   int x = 0;
-  
+
+  FETCH_DATA (the_info, codep + 2);
   x = *codep++ & 0xff;
   x |= (*codep++ & 0xff) << 8;
   return (x);
@@ -1696,6 +1721,7 @@
   switch (bytemode) 
     {
     case b_mode:
+      FETCH_DATA (the_info, codep + 1);
       op = *codep++ & 0xff;
       break;
     case v_mode:
@@ -1725,6 +1751,7 @@
   switch (bytemode) 
     {
     case b_mode:
+      FETCH_DATA (the_info, codep + 1);
       op = *(char *)codep++;
       break;
     case v_mode:
@@ -1755,6 +1782,7 @@
   switch (bytemode) 
     {
     case b_mode:
+      FETCH_DATA (the_info, codep + 1);
       disp = *(char *)codep++;
       break;
     case v_mode:
@@ -1929,28 +1957,3 @@
     }
   return (0);
 }
-	
-#define MAXLEN 20
-
-int
-print_insn (realmemaddr, memaddr, stream, addrlen)
-     CORE_ADDR memaddr, realmemaddr;
-     FILE *stream;
-     int addrlen;
-{
-  unsigned char buffer[MAXLEN];
-  
-  if(addrlen == 32){
-	  dflag = 1;
-	  aflag = 1;
-  } else {
-	  dflag = 0;
-	  aflag = 0;
-  };  
-
-
-  read_memory (memaddr, (char *) buffer, MAXLEN);
-  
-  return (i386dis ((int)realmemaddr, buffer, stream));
-}
-
diff --git a/debugger/obstack.h b/debugger/opcodes/obstack.h
similarity index 70%
rename from debugger/obstack.h
rename to debugger/opcodes/obstack.h
index 72832ee..28061a0 100644
--- a/debugger/obstack.h
+++ b/debugger/opcodes/obstack.h
@@ -1,17 +1,17 @@
 /* obstack.h - object stack macros
-   Copyright (C) 1988 Free Software Foundation, Inc.
+   Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
+under the terms of the GNU Library General Public License as published by the
 Free Software Foundation; either version 2, or (at your option) any
 later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GNU Library General Public License for more details.
 
-You should have received a copy of the GNU General Public License
+You should have received a copy of the GNU Library General Public License
 along with this program; if not, write to the Free Software
 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
@@ -41,7 +41,7 @@
 
 One motivation for this package is the problem of growing char strings
 in symbol tables.  Unless you are "fascist pig with a read-only mind"
-[Gosper's immortal quote from HAKMEM item 154, out of context] you
+--Gosper's immortal quote from HAKMEM item 154, out of context--you
 would not like to put any arbitrary upper limit on the length of your
 symbols.
 
@@ -92,7 +92,7 @@
 	Exactly one object is growing in an obstack at any one time.
 	You can run one obstack per control block.
 	You may have as many control blocks as you dare.
-	Because of the way we do it, you can `unwind' a obstack
+	Because of the way we do it, you can `unwind' an obstack
 	  back to a previous state. (You may remove objects much
 	  as you would with a stack.)
 */
@@ -100,8 +100,8 @@
 
 /* Don't do the contents of this file more than once.  */
 
-#ifndef __OBSTACKS__
-#define __OBSTACKS__
+#ifndef __OBSTACK_H__
+#define __OBSTACK_H__
 
 /* We use subtraction of (char *)0 instead of casting to int
    because on word-addressable machines a simple cast to int
@@ -115,6 +115,29 @@
 #define __INT_TO_PTR(P) ((P) + (char *)0)
 #endif
 
+/* We need the type of the resulting object.  In ANSI C it is ptrdiff_t
+   but in traditional C it is usually long.  If we are in ANSI C and
+   don't already have ptrdiff_t get it.  */
+
+#if defined (__STDC__) && ! defined (offsetof)
+#if defined (__GNUC__) && defined (IN_GCC)
+/* On Next machine, the system's stddef.h screws up if included
+   after we have defined just ptrdiff_t, so include all of stddef.h.
+   Otherwise, define just ptrdiff_t, which is all we need.  */
+#ifndef __NeXT__
+#define __need_ptrdiff_t
+#endif
+#endif
+
+#include <stddef.h>
+#endif
+
+#ifdef __STDC__
+#define PTR_INT_TYPE ptrdiff_t
+#else
+#define PTR_INT_TYPE long
+#endif
+
 struct _obstack_chunk		/* Lives at front of each chunk. */
 {
   char  *limit;			/* 1 past end of this chunk */
@@ -129,39 +152,33 @@
   char	*object_base;		/* address of object we are building */
   char	*next_free;		/* where to add next char to current object */
   char	*chunk_limit;		/* address of char after current chunk */
-  int	temp;			/* Temporary for some macros.  */
+  PTR_INT_TYPE temp;		/* Temporary for some macros.  */
   int   alignment_mask;		/* Mask of alignment for each object. */
   struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk.  */
   void (*freefun) ();		/* User's function to free a chunk.  */
-  void	*area_id;		/* Select which region to alloc/free in */
-  int   flags;			/* Miscellaneous special purpose flags */
+  char *extra_arg;		/* first arg for chunk alloc/dealloc funcs */
+  unsigned use_extra_arg:1;	/* chunk alloc/dealloc funcs take extra arg */
+  unsigned maybe_empty_object:1;/* There is a possibility that the current
+				   chunk contains a zero-length object.  This
+				   prevents freeing the chunk if we allocate
+				   a bigger chunk to replace it. */
+  unsigned alloc_failed:1;	/* chunk alloc func returned 0 */
 };
 
-/* Declare bits for flags word. */
-
-/* Means there is a possibility the current chunk contains a zero-length
-   object.  This prevents freeing the chunk if we allocate a bigger chunk
-   to replace it.  */
-
-#define OBSTACK_MAYBE_EMPTY_OBJECT	(1 << 0)
-
-/* Means that the allocation and deallocation functions take two arguments,
-   ala the mmalloc package.  The first argument is a generic pointer that
-   is saved in the area_id member of the obstack struct. */
-
-#define OBSTACK_MMALLOC_LIKE		(1 << 1)
-
 /* Declare the external functions we use; they are in obstack.c.  */
 
 #ifdef __STDC__
-  extern void _obstack_newchunk (struct obstack *, int);
-  extern void _obstack_free (struct obstack *, void *);
-  extern void _obstack_begin (struct obstack *, int, int,
-			      void *(*) (int), void (*) (int), void *, int);
+extern void _obstack_newchunk (struct obstack *, int);
+extern void _obstack_free (struct obstack *, void *);
+extern int _obstack_begin (struct obstack *, int, int,
+			    void *(*) (), void (*) ());
+extern int _obstack_begin_1 (struct obstack *, int, int,
+			      void *(*) (), void (*) (), void *);
 #else
-  extern void _obstack_newchunk ();
-  extern void _obstack_free ();
-  extern void _obstack_begin ();
+extern void _obstack_newchunk ();
+extern void _obstack_free ();
+extern int _obstack_begin ();
+extern int _obstack_begin_1 ();
 #endif
 
 #ifdef __STDC__
@@ -211,7 +228,7 @@
    Note that this might not be the final address of the object
    because a new chunk might be needed to hold the final size.  */
 
-#define obstack_base(h) ((h)->object_base)
+#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base)
 
 /* Size for allocating ordinary chunks.  */
 
@@ -219,7 +236,7 @@
 
 /* Pointer to next byte not yet allocated in current chunk.  */
 
-#define obstack_next_free(h)	((h)->next_free)
+#define obstack_next_free(h)	((h)->alloc_failed ? 0 : (h)->next_free)
 
 /* Mask specifying low bits that should be clear in address of an object.  */
 
@@ -227,16 +244,19 @@
 
 #define obstack_init(h) \
   _obstack_begin ((h), 0, 0, \
-		  (void *(*) ()) obstack_chunk_alloc, (void (*) ())obstack_chunk_free, (void *) 0, 0)
+		  (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
 
 #define obstack_begin(h, size) \
   _obstack_begin ((h), (size), 0, \
-		  (void *(*) ()) obstack_chunk_alloc, (void (*) ())obstack_chunk_free, (void *) 0, 0)
+		  (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
 
-#define obstack_full_begin(h,size,alignment,chunkfun,freefun,area_id,flags) \
+#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
   _obstack_begin ((h), (size), (alignment), \
-		  (void *(*) ()) (chunkfun), (void (*) ()) (freefun), \
-		  (area_id), (flags))
+		    (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
+
+#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+  _obstack_begin_1 ((h), (size), (alignment), \
+		    (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
 
 #define obstack_chunkfun(h, newchunkfun) \
   ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
@@ -261,6 +281,7 @@
 #define obstack_object_size(OBSTACK)					\
   __extension__								\
   ({ struct obstack *__o = (OBSTACK);					\
+     __o->alloc_failed ? 0 :						\
      (unsigned) (__o->next_free - __o->object_base); })
 
 #define obstack_room(OBSTACK)						\
@@ -268,38 +289,40 @@
   ({ struct obstack *__o = (OBSTACK);					\
      (unsigned) (__o->chunk_limit - __o->next_free); })
 
-/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
-   so that we can avoid having void expressions
-   in the arms of the conditional expression.
-   Casting the third operand to void was tried before,
-   but some compilers won't accept it.  */
 #define obstack_grow(OBSTACK,where,length)				\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
    int __len = (length);						\
-   ((__o->next_free + __len > __o->chunk_limit)				\
-    ? (_obstack_newchunk (__o, __len), 0) : 0);				\
-   bcopy (where, __o->next_free, __len);				\
-   __o->next_free += __len;						\
+   if (__o->next_free + __len > __o->chunk_limit)			\
+     _obstack_newchunk (__o, __len);					\
+   if (!__o->alloc_failed)						\
+     {									\
+        bcopy (where, __o->next_free, __len);				\
+	__o->next_free += __len;					\
+     }									\
    (void) 0; })
 
 #define obstack_grow0(OBSTACK,where,length)				\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
    int __len = (length);						\
-   ((__o->next_free + __len + 1 > __o->chunk_limit)			\
-    ? (_obstack_newchunk (__o, __len + 1), 0) : 0),			\
-   bcopy (where, __o->next_free, __len),				\
-   __o->next_free += __len,						\
-   *(__o->next_free)++ = 0;						\
+   if (__o->next_free + __len + 1 > __o->chunk_limit)			\
+     _obstack_newchunk (__o, __len + 1);				\
+   if (!__o->alloc_failed)						\
+     {									\
+       bcopy (where, __o->next_free, __len);				\
+       __o->next_free += __len;						\
+       *(__o->next_free)++ = 0;						\
+     }									\
    (void) 0; })
 
 #define obstack_1grow(OBSTACK,datum)					\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
-   ((__o->next_free + 1 > __o->chunk_limit)				\
-    ? (_obstack_newchunk (__o, 1), 0) : 0),				\
-   *(__o->next_free)++ = (datum);					\
+   if (__o->next_free + 1 > __o->chunk_limit)				\
+     _obstack_newchunk (__o, 1);					\
+   if (!__o->alloc_failed)						\
+     *(__o->next_free)++ = (datum);					\
    (void) 0; })
 
 /* These assume that the obstack alignment is good enough for pointers or ints,
@@ -309,29 +332,32 @@
 #define obstack_ptr_grow(OBSTACK,datum)					\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
-   ((__o->next_free + sizeof (void *) > __o->chunk_limit)		\
-    ? (_obstack_newchunk (__o, sizeof (void *)), 0) : 0),		\
-   *(*(void ***)&__o->next_free)++ = ((void *)datum);			\
+   if (__o->next_free + sizeof (void *) > __o->chunk_limit)		\
+     _obstack_newchunk (__o, sizeof (void *));				\
+   if (!__o->alloc_failed)						\
+     *((void **)__o->next_free)++ = ((void *)datum);			\
    (void) 0; })
 
 #define obstack_int_grow(OBSTACK,datum)					\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
-   ((__o->next_free + sizeof (int) > __o->chunk_limit)			\
-    ? (_obstack_newchunk (__o, sizeof (int)), 0) : 0),			\
-   *(*(int **)&__o->next_free)++ = ((int)datum);			\
+   if (__o->next_free + sizeof (int) > __o->chunk_limit)		\
+     _obstack_newchunk (__o, sizeof (int));				\
+   if (!__o->alloc_failed)						\
+     *((int *)__o->next_free)++ = ((int)datum);				\
    (void) 0; })
 
-#define obstack_ptr_grow_fast(h,aptr) (*(*(void ***)&(h)->next_free)++ = (void *)aptr)
-#define obstack_int_grow_fast(h,aint) (*(*(int **)&(h)->next_free)++ = (int)aint)
+#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
+#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
 
 #define obstack_blank(OBSTACK,length)					\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
    int __len = (length);						\
-   ((__o->chunk_limit - __o->next_free < __len)				\
-    ? (_obstack_newchunk (__o, __len), 0) : 0);				\
-   __o->next_free += __len;						\
+   if (__o->chunk_limit - __o->next_free < __len)			\
+     _obstack_newchunk (__o, __len);					\
+   if (!__o->alloc_failed)						\
+     __o->next_free += __len;						\
    (void) 0; })
 
 #define obstack_alloc(OBSTACK,length)					\
@@ -357,16 +383,22 @@
 #define obstack_finish(OBSTACK)  					\
 __extension__								\
 ({ struct obstack *__o1 = (OBSTACK);					\
-   void *value = (void *) __o1->object_base;				\
-   if (__o1->next_free == value)					\
-     __o1->flags |= OBSTACK_MAYBE_EMPTY_OBJECT;				\
-   __o1->next_free							\
-     = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
-		     & ~ (__o1->alignment_mask));			\
-   ((__o1->next_free - (char *)__o1->chunk				\
-     > __o1->chunk_limit - (char *)__o1->chunk)				\
-    ? (__o1->next_free = __o1->chunk_limit) : 0);			\
-   __o1->object_base = __o1->next_free;					\
+   void *value;								\
+   if (__o1->alloc_failed)						\
+     value = 0;								\
+   else									\
+     {									\
+       value = (void *) __o1->object_base;				\
+       if (__o1->next_free == value)					\
+         __o1->maybe_empty_object = 1;					\
+       __o1->next_free							\
+	 = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
+			 & ~ (__o1->alignment_mask));			\
+       if (__o1->next_free - (char *)__o1->chunk			\
+	   > __o1->chunk_limit - (char *)__o1->chunk)			\
+	 __o1->next_free = __o1->chunk_limit;				\
+       __o1->object_base = __o1->next_free;				\
+      }									\
    value; })
 
 #define obstack_free(OBSTACK, OBJ)					\
@@ -380,48 +412,61 @@
 #else /* not __GNUC__ or not __STDC__ */
 
 #define obstack_object_size(h) \
- (unsigned) ((h)->next_free - (h)->object_base)
+ (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base)
 
 #define obstack_room(h)		\
  (unsigned) ((h)->chunk_limit - (h)->next_free)
 
+/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
+   so that we can avoid having void expressions
+   in the arms of the conditional expression.
+   Casting the third operand to void was tried before,
+   but some compilers won't accept it.  */
+
 #define obstack_grow(h,where,length)					\
 ( (h)->temp = (length),							\
   (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
-  bcopy (where, (h)->next_free, (h)->temp),				\
-  (h)->next_free += (h)->temp)
+  ((h)->alloc_failed ? 0 :						\
+  (bcopy (where, (h)->next_free, (h)->temp),				\
+  (h)->next_free += (h)->temp)))
 
 #define obstack_grow0(h,where,length)					\
 ( (h)->temp = (length),							\
   (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)			\
    ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0),			\
-  bcopy (where, (h)->next_free, (h)->temp),				\
+  ((h)->alloc_failed ? 0 :						\
+  (bcopy (where, (h)->next_free, (h)->temp),				\
   (h)->next_free += (h)->temp,						\
-  *((h)->next_free)++ = 0)
+  *((h)->next_free)++ = 0)))
 
 #define obstack_1grow(h,datum)						\
 ( (((h)->next_free + 1 > (h)->chunk_limit)				\
    ? (_obstack_newchunk ((h), 1), 0) : 0),				\
-  *((h)->next_free)++ = (datum))
+ ((h)->alloc_failed ? 0 :						\
+  (*((h)->next_free)++ = (datum))))
 
 #define obstack_ptr_grow(h,datum)					\
 ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)		\
    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		\
-  *(*(char ***)&(h)->next_free)++ = ((char *)datum))
+  ((h)->alloc_failed ? 0 :						\
+  (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))))
 
 #define obstack_int_grow(h,datum)					\
 ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)			\
    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			\
-  *(*(int **)&(h)->next_free)++ = ((int)datum))
+  ((h)->alloc_failed ? 0 :						\
+  (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))))
 
-#define obstack_ptr_grow_fast(h,aptr) (*(*(char ***)&(h)->next_free)++ = (char *)aptr)
-#define obstack_int_grow_fast(h,aint) (*(*(int **)&(h)->next_free)++ = (int)aint)
+#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
+#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
+
 #define obstack_blank(h,length)						\
 ( (h)->temp = (length),							\
   (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
-  (h)->next_free += (h)->temp)
+  ((h)->alloc_failed ? 0 :						\
+  ((h)->next_free += (h)->temp)))
 
 #define obstack_alloc(h,length)						\
  (obstack_blank ((h), (length)), obstack_finish ((h)))
@@ -433,8 +478,9 @@
  (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
 
 #define obstack_finish(h)  						\
-( ((h)->next_free == (h)->object_base					\
-   ? (((h)->flags |= OBSTACK_MAYBE_EMPTY_OBJECT), 0)			\
+( (h)->alloc_failed ? 0 :						\
+  (((h)->next_free == (h)->object_base					\
+   ? (((h)->maybe_empty_object = 1), 0)					\
    : 0),								\
   (h)->temp = __PTR_TO_INT ((h)->object_base),				\
   (h)->next_free							\
@@ -444,7 +490,7 @@
     > (h)->chunk_limit - (char *)(h)->chunk)				\
    ? ((h)->next_free = (h)->chunk_limit) : 0),				\
   (h)->object_base = (h)->next_free,					\
-  __INT_TO_PTR ((h)->temp))
+  __INT_TO_PTR ((h)->temp)))
 
 #ifdef __STDC__
 #define obstack_free(h,obj)						\
@@ -464,4 +510,4 @@
 
 #endif /* not __GNUC__ or not __STDC__ */
 
-#endif /* not __OBSTACKS__ */
+#endif /* not __OBSTACK_H__ */
diff --git a/debugger/tm-i386v.h b/debugger/tm-i386v.h
deleted file mode 100644
index bfd0e35..0000000
--- a/debugger/tm-i386v.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/* Macro definitions for i386, Unix System V.
-   Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#if !defined (TM_I386V_H)
-#define TM_I386V_H 1
-
-/*
- * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu)
- * July 1988
- */
-
-#define TARGET_BYTE_ORDER LITTLE_ENDIAN
-
-/* define this if you don't have the extension to coff that allows
- * file names to appear in the string table
- * (aux.x_file.x_foff)
- */
-#define COFF_NO_LONG_FILE_NAMES
-
-/* turn this on when rest of gdb is ready */
-#define IEEE_FLOAT
-
-/* Define this if the C compiler puts an underscore at the front
-   of external names before giving them to the linker.  */
-
-/* #define NAMES_HAVE_UNDERSCORE */
-
-/* number of traps that happen between exec'ing the shell 
- * to run an inferior, and when we finally get to 
- * the inferior code.  This is 2 on most implementations.
- */
-#ifndef START_INFERIOR_TRAPS_EXPECTED
-#define START_INFERIOR_TRAPS_EXPECTED 4
-#endif
-
-/* Offset from address of function to start of its code.
-   Zero on most machines.  */
-
-#define FUNCTION_START_OFFSET 0
-
-/* Advance PC across any function entry prologue instructions
-   to reach some "real" code.  */
-
-#define SKIP_PROLOGUE(frompc)   {(frompc) = i386_skip_prologue((frompc));}
-
-extern int
-i386_skip_prologue PARAMS ((int));
-
-/* Immediately after a function call, return the saved pc.
-   Can't always go through the frames for this because on some machines
-   the new frame is not set up until the new function executes
-   some instructions.  */
-
-#define SAVED_PC_AFTER_CALL(frame) \
-  (read_memory_integer (read_register (SP_REGNUM), 4))
-
-/* Address of end of stack space.  */
-
-#define STACK_END_ADDR 0x80000000
-
-/* Stack grows downward.  */
-
-#define INNER_THAN <
-
-/* Sequence of bytes for breakpoint instruction.  */
-
-#define BREAKPOINT {0xcc}
-
-/* Amount PC must be decremented by after a breakpoint.
-   This is often the number of bytes in BREAKPOINT
-   but not always.  */
-
-#ifndef DECR_PC_AFTER_BREAK
-#define DECR_PC_AFTER_BREAK 1
-#endif
-
-/* Nonzero if instruction at PC is a return instruction.  */
-
-#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc3)
-
-/* Return 1 if P points to an invalid floating point value.
-   LEN is the length in bytes -- not relevant on the 386.  */
-
-#define INVALID_FLOAT(p, len) (0)
-
-/* Say how long (ordinary) registers are.  */
-
-#define REGISTER_TYPE long
-
-/* Number of machine registers */
-
-#define NUM_REGS 16
-
-/* Initializer for an array of names of registers.
-   There should be NUM_REGS strings in this initializer.  */
-
-/* the order of the first 8 registers must match the compiler's 
- * numbering scheme (which is the same as the 386 scheme)
- * also, this table must match regmap in i386-pinsn.c.
- */
-#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
-			 "esp", "ebp", "esi", "edi", \
-			 "eip", "ps", "cs", "ss", \
-			 "ds", "es", "fs", "gs", \
-			 }
-
-/* Register numbers of various important registers.
-   Note that some of these values are "real" register numbers,
-   and correspond to the general registers of the machine,
-   and some are "phony" register numbers which are too large
-   to be actual register numbers as far as the user is concerned
-   but do serve to get the desired values when passed to read_register.  */
-
-#define FP_REGNUM 5		/* Contains address of executing stack frame */
-#define SP_REGNUM 4		/* Contains address of top of stack */
-
-#define PC_REGNUM 8
-#define PS_REGNUM 9
-
-/* Total amount of space needed to store our copies of the machine's
-   register state, the array `registers'.  */
-#define REGISTER_BYTES (NUM_REGS * 4)
-
-/* Index within `registers' of the first byte of the space for
-   register N.  */
-
-#define REGISTER_BYTE(N) ((N)*4)
-
-/* Number of bytes of storage in the actual machine representation
-   for register N.  */
-
-#define REGISTER_RAW_SIZE(N) (4)
-
-/* Number of bytes of storage in the program's representation
-   for register N. */
-
-#define REGISTER_VIRTUAL_SIZE(N) (4)
-
-/* Largest value REGISTER_RAW_SIZE can have.  */
-
-#define MAX_REGISTER_RAW_SIZE 4
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
-
-#define MAX_REGISTER_VIRTUAL_SIZE 4
-
-/* Nonzero if register N requires conversion
-   from raw format to virtual format.  */
-
-#define REGISTER_CONVERTIBLE(N) (0)
-
-/* Convert data from raw format for register REGNUM
-   to virtual format for register REGNUM.  */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
-  {memcpy ((TO), (FROM), 4);}
-
-/* Convert data from virtual format for register REGNUM
-   to raw format for register REGNUM.  */
-
-#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
-  {memcpy ((TO), (FROM), 4);}
-
-/* Return the GDB type object for the "standard" data type
-   of data in register N.  */
-/* Perhaps si and di should go here, but potentially they could be
-   used for things other than address.  */
-#define REGISTER_VIRTUAL_TYPE(N) \
-  ((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM ?         \
-   lookup_pointer_type (builtin_type_void) : builtin_type_int)
-
-/* Store the address of the place in which to copy the structure the
-   subroutine will return.  This is called from call_function. */
-
-#define STORE_STRUCT_RETURN(ADDR, SP) \
-  { (SP) -= sizeof (ADDR);		\
-    write_memory ((SP), (char *) &(ADDR), sizeof (ADDR)); }
-
-/* Extract from an array REGBUF containing the (raw) register state
-   a function return value of type TYPE, and copy that, in virtual format,
-   into VALBUF.  */
-
-#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
-  memcpy ((VALBUF), (REGBUF), TYPE_LENGTH (TYPE))
-
-/* Write into appropriate registers a function return value
-   of type TYPE, given in virtual format.  */
-
-#define STORE_RETURN_VALUE(TYPE,VALBUF) \
-  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
-
-/* Extract from an array REGBUF containing the (raw) register state
-   the address in which a function should return its structure value,
-   as a CORE_ADDR (or an expression that can be used as one).  */
-
-#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
-
-
-/* Describe the pointer in each stack frame to the previous stack frame
-   (its caller).  */
-
-/* FRAME_CHAIN takes a frame's nominal address
-   and produces the frame's chain-pointer. */
-
-#define FRAME_CHAIN(thisframe) \
-  (!inside_entry_file ((thisframe)->pc) ? \
-   read_memory_integer ((thisframe)->frame, 4) :\
-   0)
-
-/* Define other aspects of the stack frame.  */
-
-/* A macro that tells us whether the function invocation represented
-   by FI does not have a frame on the stack associated with it.  If it
-   does not, FRAMELESS is set to 1, else 0.  */
-#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
-  (FRAMELESS) = frameless_look_for_prologue(FI)
-
-#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
-
-#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
-
-#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
-
-/* Return number of args passed to a frame.
-   Can return -1, meaning no way to tell.  */
-
-#define FRAME_NUM_ARGS(numargs, fi) (numargs) = i386_frame_num_args(fi)
-
-#ifdef __STDC__		/* Forward decl's for prototypes */
-struct frame_info;
-struct frame_saved_regs;
-#endif
-
-extern int
-i386_frame_num_args PARAMS ((struct frame_info *));
-
-/* Return number of bytes at start of arglist that are not really args.  */
-
-#define FRAME_ARGS_SKIP 8
-
-/* Put here the code to store, into a struct frame_saved_regs,
-   the addresses of the saved registers of frame described by FRAME_INFO.
-   This includes special registers such as pc and fp saved in special
-   ways in the stack frame.  sp is even more special:
-   the address we return for it IS the sp for the next frame.  */
-
-#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
-{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); }
-
-extern void
-i386_frame_find_saved_regs PARAMS ((struct frame_info *,
-				    struct frame_saved_regs *));
-
-
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); }
-
-extern void
-i386_push_dummy_frame PARAMS ((void));
-
-/* Discard from the stack the innermost frame, restoring all registers.  */
-
-#define POP_FRAME  { i386_pop_frame (); }
-
-extern void
-i386_pop_frame PARAMS ((void));
-
-/* this is 
- *   call 11223344 (32 bit relative)
- *   int3
- */
-
-#define CALL_DUMMY { 0x223344e8, 0xcc11 }
-
-#define CALL_DUMMY_LENGTH 8
-
-#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
-{ \
-	int from, to, delta, loc; \
-	loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \
-	from = loc + 5; \
-	to = (int)(fun); \
-	delta = to - from; \
-	*((char *)(dummyname) + 1) = (delta & 0xff); \
-	*((char *)(dummyname) + 2) = ((delta >> 8) & 0xff); \
-	*((char *)(dummyname) + 3) = ((delta >> 16) & 0xff); \
-	*((char *)(dummyname) + 4) = ((delta >> 24) & 0xff); \
-}
-
-extern void
-print_387_control_word PARAMS ((unsigned int));
-
-extern void
-print_387_status_word PARAMS ((unsigned int));
-
-/* Offset from SP to first arg on stack at first instruction of a function */
-
-#define SP_ARG0 (1 * 4)
-
-#endif	/* !defined (TM_I386V_H) */
diff --git a/debugger/tm.h b/debugger/tm.h
deleted file mode 100644
index f36505f..0000000
--- a/debugger/tm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Macro definitions for linux.
-   Copyright (C) 1992 Free Software Foundation, Inc.
-This file is part of GDB.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#if !defined (TM_LINUX_H)
-#define TM_LINUX_H 1
-/* number of traps that happen between exec'ing the shell
- * to run an inferior, and when we finally get to
- * the inferior code.  This is 2 on most implementations.
- */
-#define START_INFERIOR_TRAPS_EXPECTED 2
-#include "tm-i386v.h"
-/* Define this if the C compiler puts an underscore at the front
-   of external names before giving them to the linker.  */
-#define NAMES_HAVE_UNDERSCORE
-#endif		/* !defined (TM_LINUX_H) */
diff --git a/debugger/xm-i386v.h b/debugger/xm-i386v.h
deleted file mode 100644
index cff2319..0000000
--- a/debugger/xm-i386v.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Host support for i386.
-   Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
-   Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#define HOST_BYTE_ORDER LITTLE_ENDIAN
-
-/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
-Sys V/386 3.2.
-
-On some machines, gdb crashes when it's starting up while calling the
-vendor's termio tgetent() routine.  It always works when run under
-itself (actually, under 3.2, it's not an infinitely recursive bug.)
-After some poking around, it appears that depending on the environment
-size, or whether you're running YP, or the phase of the moon or something,
-the stack is not always long-aligned when main() is called, and tgetent()
-takes strong offense at that.  On some machines this bug never appears, but
-on those where it does, it occurs quite reliably.  */
-#define ALIGN_STACK_ON_STARTUP
-
-/* define USG if you are using sys5 /usr/include's */
-#define USG
-
-#define HAVE_TERMIO
-
-/* This is the amount to subtract from u.u_ar0
-   to get the offset in the core file of the register values.  */
-
-#define KERNEL_U_ADDR 0xe0000000
-
diff --git a/debugger/xm.h b/debugger/xm.h
deleted file mode 100644
index f265c73..0000000
--- a/debugger/xm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Native support for linux, for GDB, the GNU debugger.
-   Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "xm-i386v.h"
-
-/* This is the amount to subtract from u.u_ar0
-   to get the offset in the core file of the register values.  */
-#undef KERNEL_U_ADDR
-#define KERNEL_U_ADDR 0x0
-#define PSIGNAL_IN_SIGNAL_H
diff --git a/etc/commdlg-ordinals b/etc/commdlg-ordinals
new file mode 100644
index 0000000..b4c9e2a
--- /dev/null
+++ b/etc/commdlg-ordinals
@@ -0,0 +1,26 @@
+  1   2  0c17  GETOPENFILENAME exported, shared data
+  2   2  0c48  GETSAVEFILENAME exported, shared data
+  5   1  0ea1  CHOOSECOLOR exported, shared data
+  6   2  42a3  FILEOPENDLGPROC exported, shared data
+  7   2  446a  FILESAVEDLGPROC exported, shared data
+  8   1  0197  COLORDLGPROC exported, shared data
+  9   6  0000  LOADALTERBITMAP exported, shared data
+ 11   5  0000  FINDTEXT exported, shared data
+ 12   5  019c  REPLACETEXT exported, shared data
+ 13   5  036d  FINDTEXTDLGPROC exported, shared data
+ 14   5  0582  REPLACETEXTDLGPROC exported, shared data
+ 15   4  0000  CHOOSEFONT exported, shared data
+ 16   4  02b0  FORMATCHARDLGPROC exported, shared data
+ 18   4  184e  FONTSTYLEENUMPROC exported, shared data
+ 19   4  1096  FONTFAMILYENUMPROC exported, shared data
+ 20   3  0c94  PRINTDLG exported, shared data
+ 21   3  371f  PRINTDLGPROC exported, shared data
+ 22   3  307a  PRINTSETUPDLGPROC exported, shared data
+ 23   3  0000  EDITINTEGERONLY exported, shared data
+ 25   1  1b46  WANTARROWS exported, shared data
+ 26   6  01e7  COMMDLGEXTENDEDERROR exported, shared data
+ 27   2  0c79  GETFILETITLE exported, shared data
+ 28   6  01ad  WEP exported, shared data
+ 29   2  10a5  DWLBSUBCLASS exported, shared data
+ 30   3  0056  DWUPARROWHACK exported, shared data
+ 31   2  100f  DWOKSUBCLASS exported, shared data
diff --git a/etc/ddeml-ordinals b/etc/ddeml-ordinals
new file mode 100644
index 0000000..e4588c5
--- /dev/null
+++ b/etc/ddeml-ordinals
@@ -0,0 +1,38 @@
+  1   2  002c  WEP exported, shared data
+  2   1  0010  DDEINITIALIZE exported, shared data
+  3   1  03ae  DDEUNINITIALIZE exported, shared data
+  4   1  068a  DDECONNECTLIST exported, shared data
+  5   1  0948  DDEQUERYNEXTSERVER exported, shared data
+  6   1  0a46  DDEDISCONNECTLIST exported, shared data
+  7   1  0aac  DDECONNECT exported, shared data
+  8   1  0b4a  DDEDISCONNECT exported, shared data
+  9   1  0dac  DDEQUERYCONVINFO exported, shared data
+ 10   1  1020  DDESETUSERHANDLE exported, shared data
+ 11   1  1204  DDECLIENTTRANSACTION exported, shared data
+ 12   1  1bf0  DDEABANDONTRANSACTION exported, shared data
+ 13   1  1118  DDEPOSTADVISE exported, shared data
+ 14   1  14e8  DDECREATEDATAHANDLE exported, shared data
+ 15   1  1598  DDEADDDATA exported, shared data
+ 16   1  17a8  DDEGETDATA exported, shared data
+ 17   1  188a  DDEACCESSDATA exported, shared data
+ 18   1  1916  DDEUNACCESSDATA exported, shared data
+ 19   1  1946  DDEFREEDATAHANDLE exported, shared data
+ 20   1  14a8  DDEGETLASTERROR exported, shared data
+ 21   1  19a4  DDECREATESTRINGHANDLE exported, shared data
+ 22   1  1a40  DDEFREESTRINGHANDLE exported, shared data
+ 23   1  1b14  DDEQUERYSTRING exported, shared data
+ 24   1  1aac  DDEKEEPSTRINGHANDLE exported, shared data
+ 26   1  1d98  DDEENABLECALLBACK exported, shared data
+ 27   1  1ed4  DDENAMESERVICE exported, shared data
+ 28   1  4614  CLIENTWNDPROC exported, shared data
+ 29   1  523a  SERVERWNDPROC exported, shared data
+ 30   1  5480  SUBFRAMEWNDPROC exported, shared data
+ 31   1  5558  DMGWNDPROC exported, shared data
+ 32   1  5758  CONVLISTWNDPROC exported, shared data
+ 33   1  35f2  MONITORWNDPROC exported, shared data
+ 34   1  2fb0  DDESENDHOOKPROC exported, shared data
+ 35   1  309e  DDEPOSTHOOKPROC exported, shared data
+ 36   1  1bb0  DDECMPSTRINGHANDLES exported, shared data
+ 37   1  0be0  DDERECONNECT exported, shared data
+ 38   1  6b8a  INITENUM exported, shared data
+ 39   1  036a  TERMDLGPROC exported, shared data
diff --git a/etc/lzexpand-ordinals b/etc/lzexpand-ordinals
new file mode 100644
index 0000000..803da95
--- /dev/null
+++ b/etc/lzexpand-ordinals
@@ -0,0 +1,12 @@
+  1   4  015c  LZCOPY exported, shared data
+  2   2  0262  LZOPENFILE exported, shared data
+  3   2  0000  LZINIT exported, shared data
+  4   2  02ee  LZSEEK exported, shared data
+  5   2  03d6  LZREAD exported, shared data
+  6   2  06f0  LZCLOSE exported, shared data
+  7   4  0000  LZSTART exported, shared data
+  8   4  013a  COPYLZFILE exported, shared data
+  9   4  00a6  LZDONE exported, shared data
+ 10   2  01bc  GETEXPANDEDNAME exported, shared data
+ 11   3  0000  WEP exported, shared data
+ 12  11  035e  ___EXPORTEDSTUB exported, shared data
diff --git a/etc/mmsystem-ordinals b/etc/mmsystem-ordinals
new file mode 100644
index 0000000..6f0a268
--- /dev/null
+++ b/etc/mmsystem-ordinals
@@ -0,0 +1,136 @@
+  1   2  0014  WEP exported, shared data
+  2   4  0000  SNDPLAYSOUND exported, shared data
+  5   2  02b0  MMSYSTEMGETVERSION exported, shared data
+  6   4  0028  DRIVERPROC exported, shared data
+ 30   1  030a  OUTPUTDEBUGSTR exported, shared data
+ 31   1  03ab  DRIVERCALLBACK exported, shared data
+ 32   1  0312  STACKENTER exported, shared data
+ 33   1  0370  STACKLEAVE exported, shared data
+ 34   2  0484  MMDRVINSTALL exported, shared data
+101   8  005d  JOYGETNUMDEVS exported, shared data
+102   8  001a  JOYGETDEVCAPS exported, shared data
+103   8  0073  JOYGETPOS exported, shared data
+104   8  00b5  JOYGETTHRESHOLD exported, shared data
+105   8  00ec  JOYRELEASECAPTURE exported, shared data
+106   8  013e  JOYSETCAPTURE exported, shared data
+107   8  021d  JOYSETTHRESHOLD exported, shared data
+109   8  0251  JOYSETCALIBRATION exported, shared data
+1100   4  057e  DRVOPEN exported, shared data
+1101   4  0583  DRVCLOSE exported, shared data
+1102   4  058d  DRVSENDMESSAGE exported, shared data
+1103   4  0588  DRVGETMODULEHANDLE exported, shared data
+1104   4  0592  DRVDEFDRIVERPROC exported, shared data
+1210   7  02a5  MMIOOPEN exported, shared data
+1211   7  0457  MMIOCLOSE exported, shared data
+1212   7  04b4  MMIOREAD exported, shared data
+1213   7  062b  MMIOWRITE exported, shared data
+1214   7  07e9  MMIOSEEK exported, shared data
+1215   7  0929  MMIOGETINFO exported, shared data
+1216   7  0996  MMIOSETINFO exported, shared data
+1217   7  0a68  MMIOSETBUFFER exported, shared data
+1218   7  0cd8  MMIOFLUSH exported, shared data
+1219   7  0da7  MMIOADVANCE exported, shared data
+1220   7  0ed3  MMIOSTRINGTOFOURCC exported, shared data
+1221   7  0f6e  MMIOINSTALLIOPROC exported, shared data
+1222   7  1073  MMIOSENDMESSAGE exported, shared data
+1223   7  1360  MMIODESCEND exported, shared data
+1224   7  1562  MMIOASCEND exported, shared data
+1225   7  16a5  MMIOCREATECHUNK exported, shared data
+1226   7  01d2  MMIORENAME exported, shared data
+201   6  015f  MIDIOUTGETNUMDEVS exported, shared data
+202   6  016a  MIDIOUTGETDEVCAPS exported, shared data
+203   6  0266  MIDIOUTGETERRORTEXT exported, shared data
+204   6  02a7  MIDIOUTOPEN exported, shared data
+205   6  03c4  MIDIOUTCLOSE exported, shared data
+206   6  0410  MIDIOUTPREPAREHEADER exported, shared data
+207   6  0485  MIDIOUTUNPREPAREHEADER exported, shared data
+208   1  0121  MIDIOUTSHORTMSG exported, shared data
+209   1  0156  MIDIOUTLONGMSG exported, shared data
+210   1  01b4  MIDIOUTRESET exported, shared data
+211   6  01b6  MIDIOUTGETVOLUME exported, shared data
+212   6  01f7  MIDIOUTSETVOLUME exported, shared data
+213   6  04ff  MIDIOUTCACHEPATCHES exported, shared data
+214   6  0571  MIDIOUTCACHEDRUMPATCHES exported, shared data
+215   6  0a5c  MIDIOUTGETID exported, shared data
+216   1  00eb  MIDIOUTMESSAGE exported, shared data
+301   6  05e3  MIDIINGETNUMDEVS exported, shared data
+302   6  0625  MIDIINGETDEVCAPS exported, shared data
+303   6  0671  MIDIINGETERRORTEXT exported, shared data
+304   6  06b2  MIDIINOPEN exported, shared data
+305   6  07cf  MIDIINCLOSE exported, shared data
+306   6  081b  MIDIINPREPAREHEADER exported, shared data
+307   6  0890  MIDIINUNPREPAREHEADER exported, shared data
+308   6  090a  MIDIINADDBUFFER exported, shared data
+309   6  0976  MIDIINSTART exported, shared data
+310   6  09aa  MIDIINSTOP exported, shared data
+311   6  09de  MIDIINRESET exported, shared data
+312   6  0a12  MIDIINGETID exported, shared data
+313   6  05ee  MIDIINMESSAGE exported, shared data
+350   8  0531  AUXGETNUMDEVS exported, shared data
+351   8  053c  AUXGETDEVCAPS exported, shared data
+352   8  0582  AUXGETVOLUME exported, shared data
+353   8  05bd  AUXSETVOLUME exported, shared data
+354   8  04df  AUXOUTMESSAGE exported, shared data
+401   3  0866  WAVEOUTGETNUMDEVS exported, shared data
+402   3  08a6  WAVEOUTGETDEVCAPS exported, shared data
+403   3  09a2  WAVEOUTGETERRORTEXT exported, shared data
+404   3  09e3  WAVEOUTOPEN exported, shared data
+405   3  0b81  WAVEOUTCLOSE exported, shared data
+406   3  0bc8  WAVEOUTPREPAREHEADER exported, shared data
+407   3  0c54  WAVEOUTUNPREPAREHEADER exported, shared data
+408   3  0cdd  WAVEOUTWRITE exported, shared data
+409   3  0d4a  WAVEOUTPAUSE exported, shared data
+410   3  0d7c  WAVEOUTRESTART exported, shared data
+411   3  0dae  WAVEOUTRESET exported, shared data
+412   3  0e12  WAVEOUTGETPOSITION exported, shared data
+413   3  0e62  WAVEOUTGETPITCH exported, shared data
+414   3  0eb0  WAVEOUTSETPITCH exported, shared data
+415   3  08f2  WAVEOUTGETVOLUME exported, shared data
+416   3  0933  WAVEOUTSETVOLUME exported, shared data
+417   3  0ee4  WAVEOUTGETPLAYBACKRATE exported, shared data
+418   3  0f32  WAVEOUTSETPLAYBACKRATE exported, shared data
+419   3  0de0  WAVEOUTBREAKLOOP exported, shared data
+420   3  14bf  WAVEOUTGETID exported, shared data
+421   3  0871  WAVEOUTMESSAGE exported, shared data
+501   3  0f66  WAVEINGETNUMDEVS exported, shared data
+502   3  0fa6  WAVEINGETDEVCAPS exported, shared data
+503   3  0ff2  WAVEINGETERRORTEXT exported, shared data
+504   3  1033  WAVEINOPEN exported, shared data
+505   3  11d1  WAVEINCLOSE exported, shared data
+506   3  1218  WAVEINPREPAREHEADER exported, shared data
+507   3  129c  WAVEINUNPREPAREHEADER exported, shared data
+508   3  1325  WAVEINADDBUFFER exported, shared data
+509   3  138f  WAVEINSTART exported, shared data
+510   3  13c1  WAVEINSTOP exported, shared data
+511   3  13f3  WAVEINRESET exported, shared data
+512   3  1425  WAVEINGETPOSITION exported, shared data
+513   3  1475  WAVEINGETID exported, shared data
+514   3  0f71  WAVEINMESSAGE exported, shared data
+601   1  0000  TIMEGETSYSTEMTIME exported, shared data
+602   1  0029  TIMESETEVENT exported, shared data
+603   1  0292  TIMEKILLEVENT exported, shared data
+604   8  0000  TIMEGETDEVCAPS exported, shared data
+605   1  0288  TIMEBEGINPERIOD exported, shared data
+606   1  028d  TIMEENDPERIOD exported, shared data
+607   1  029a  TIMEGETTIME exported, shared data
+701   5  04af  MCISENDCOMMAND exported, shared data
+702   5  1258  MCISENDSTRING exported, shared data
+703   5  1588  MCIGETDEVICEID exported, shared data
+704   5  3994  MCIPARSECOMMAND exported, shared data
+705   5  2d4c  MCILOADCOMMANDRESOURCE exported, shared data
+706   5  136f  MCIGETERRORSTRING exported, shared data
+707   5  2a1d  MCISETDRIVERDATA exported, shared data
+708   5  29d3  MCIGETDRIVERDATA exported, shared data
+710   5  2a6f  MCIDRIVERYIELD exported, shared data
+711   1  0275  MCIDRIVERNOTIFY exported, shared data
+712   5  1293  MCIEXECUTE exported, shared data
+713   5  2fb9  MCIFREECOMMANDRESOURCE exported, shared data
+714   5  2acd  MCISETYIELDPROC exported, shared data
+715   5  1454  MCIGETDEVICEIDFROMELEMENTID exported, shared data
+716   5  2b3c  MCIGETYIELDPROC exported, shared data
+717   5  15a5  MCIGETCREATORTASK exported, shared data
+900   4  05fa  MMTASKCREATE exported, shared data
+902   4  05be  MMTASKBLOCK exported, shared data
+903   1  0264  MMTASKSIGNAL exported, shared data
+904   4  05b9  MMGETCURRENTTASK exported, shared data
+905   4  0598  MMTASKYIELD exported, shared data
diff --git a/etc/netapi20-ordinals b/etc/netapi20-ordinals
new file mode 100644
index 0000000..3666511
--- /dev/null
+++ b/etc/netapi20-ordinals
@@ -0,0 +1,146 @@
+  1   3  0000  NETACCESSADD exported, shared data
+  2   3  0128  NETACCESSDEL exported, shared data
+  3   3  01ea  NETACCESSENUM exported, shared data
+  4   3  0318  NETACCESSGETINFO exported, shared data
+  5   3  042a  NETACCESSSETINFO exported, shared data
+  6   4  0030  NETALERTRAISE exported, shared data
+  7   4  0000  NETALERTSTART exported, shared data
+  8   4  0018  NETALERTSTOP exported, shared data
+  9  10  00f4  NETAUDITCLEAR exported, shared data
+ 10  10  024a  NETAUDITOPEN exported, shared data
+ 11  10  0000  NETAUDITWRITE exported, shared data
+ 12   3  0110  NETACCESSCHECK exported, shared data
+ 13  12  0000  NETBIOSCLOSE exported, shared data
+ 14  12  0018  NETBIOSENUM exported, shared data
+ 15  12  0030  NETBIOSGETINFO exported, shared data
+ 16  12  0048  NETBIOSOPEN exported, shared data
+ 17  12  0060  NETBIOSSUBMIT exported, shared data
+ 18   7  0000  NETCHARDEVCONTROL exported, shared data
+ 19   7  0056  NETCHARDEVENUM exported, shared data
+ 20   7  00f2  NETCHARDEVGETINFO exported, shared data
+ 21   7  016e  NETCHARDEVQENUM exported, shared data
+ 22   7  043c  NETCHARDEVQGETINFO exported, shared data
+ 23   7  04b2  NETCHARDEVQPURGE exported, shared data
+ 24   7  0562  NETCHARDEVQSETINFO exported, shared data
+ 25   6  0330  NETCONFIGGET exported, shared data
+ 26   6  0150  NETCONFIGGETALL exported, shared data
+ 27  18  0000  NETCONNECTIONENUM exported, shared data
+ 28   1  00a8  WEP exported, shared data
+ 29  10  0030  NETERRORLOGCLEAR exported, shared data
+ 30  10  01c0  NETERRORLOGOPEN exported, shared data
+ 31  10  0018  NETERRORLOGWRITE exported, shared data
+ 32  18  0256  NETFILECLOSE exported, shared data
+ 33  18  044a  NETFILEENUM exported, shared data
+ 34  18  0516  NETFILEGETINFO exported, shared data
+ 35   3  05f8  NETGROUPADD exported, shared data
+ 36   3  067e  NETGROUPADDUSER exported, shared data
+ 37   3  06dc  NETGROUPDEL exported, shared data
+ 38   3  073a  NETGROUPDELUSER exported, shared data
+ 39   3  0798  NETGROUPENUM exported, shared data
+ 40   3  0894  NETGROUPGETUSERS exported, shared data
+ 43  11  01cc  NETMESSAGELOGFILEGET exported, shared data
+ 44  11  0338  NETMESSAGELOGFILESET exported, shared data
+ 45  11  0718  NETMESSAGENAMEADD exported, shared data
+ 46  11  0844  NETMESSAGENAMEDEL exported, shared data
+ 47  11  096c  NETMESSAGENAMEENUM exported, shared data
+ 48  11  0d2a  NETMESSAGENAMEFWD exported, shared data
+ 49  11  0b00  NETMESSAGENAMEGETINFO exported, shared data
+ 50  11  0d7a  NETMESSAGENAMEUNFWD exported, shared data
+ 51  13  0000  NETPROFILELOAD exported, shared data
+ 52  13  037e  NETPROFILESAVE exported, shared data
+ 53  18  0b98  NETSERVERADMINCOMMAND exported, shared data
+ 54  18  00b8  NETSERVERDISKENUM exported, shared data
+ 55  18  0c62  NETSERVERGETINFO exported, shared data
+ 56  18  0cf2  NETSERVERSETINFO exported, shared data
+ 57  19  0134  NETSERVICECONTROL exported, shared data
+ 58  19  02f0  NETSERVICEENUM exported, shared data
+ 59  19  044a  NETSERVICEINSTALL exported, shared data
+ 60  19  011c  NETSERVICESTATUS exported, shared data
+ 61  18  0676  NETSESSIONDEL exported, shared data
+ 62  18  05c4  NETSESSIONENUM exported, shared data
+ 63  18  06dc  NETSESSIONGETINFO exported, shared data
+ 64  18  0798  NETSHAREADD exported, shared data
+ 65  18  0968  NETSHARECHECK exported, shared data
+ 66  18  082a  NETSHAREDEL exported, shared data
+ 67  18  09d6  NETSHAREENUM exported, shared data
+ 68  18  0ab6  NETSHAREGETINFO exported, shared data
+ 69  18  08a2  NETSHARESETINFO exported, shared data
+ 70  18  0d88  NETSTATISTICSCLEAR exported, shared data
+ 71  18  0de0  NETSTATISTICSGET exported, shared data
+ 72  16  06f2  NETREMOTETOD exported, shared data
+ 73  21  0000  NETUSEADD exported, shared data
+ 74  21  032a  NETUSEDEL exported, shared data
+ 75  21  0502  NETUSEENUM exported, shared data
+ 76  21  0664  NETUSEGETINFO exported, shared data
+ 77   3  0ab8  NETUSERADD exported, shared data
+ 78   3  0c26  NETUSERDEL exported, shared data
+ 79   3  0c84  NETUSERENUM exported, shared data
+ 80   3  0f9a  NETUSERGETGROUPS exported, shared data
+ 81   3  0ef4  NETUSERGETINFO exported, shared data
+ 82   3  1132  NETUSERPASSWORDSET exported, shared data
+ 83   3  0d2c  NETUSERSETINFO exported, shared data
+ 84   9  0858  NETWKSTAGETINFO exported, shared data
+ 85   9  0a22  NETWKSTASETINFO exported, shared data
+ 86   9  0000  NETWKSTASETUID exported, shared data
+ 91  16  0380  NETREMOTEMOVE exported, shared data
+ 92  16  0000  NETREMOTECOPY exported, shared data
+ 93  16  0368  NETREMOTEEXEC exported, shared data
+105   3  1570  NETUSERVALIDATE exported, shared data
+116  19  0000  NETSERVICEGETINFO exported, shared data
+117   7  050a  NETCHARDEVQPURGESELF exported, shared data
+172   3  0506  NETACCESSGETUSERPERMS exported, shared data
+174   7  0226  NETHANDLEGETINFO exported, shared data
+175   7  0326  NETHANDLESETINFO exported, shared data
+176   3  0974  NETGROUPSETUSERS exported, shared data
+177   3  0816  NETGROUPGETINFO exported, shared data
+178   3  08fe  NETGROUPSETINFO exported, shared data
+179   3  1404  NETUSERSETGROUPS exported, shared data
+182   3  1588  NETUSERVALIDATE2 exported, shared data
+184   3  1004  NETUSERMODALSGET exported, shared data
+185   3  10a2  NETUSERMODALSSET exported, shared data
+186   3  0d14  NETUSERINIT exported, shared data
+189  26  0000  NETGETDCNAME exported, shared data
+196   6  01e0  NETCONFIGGET2 exported, shared data
+197   6  0000  NETCONFIGGETALL2 exported, shared data
+198  18  0e5e  NETSTATISTICSGET2 exported, shared data
+199  10  02f4  NETERRORLOGREAD exported, shared data
+200  10  04b2  NETAUDITREAD exported, shared data
+201  18  02ae  NETFILEENUM2 exported, shared data
+259  17  0000  NETUSERRESTRICT exported, shared data
+266  26  06dc  NETLOGONENUM exported, shared data
+277   9  027c  NETWKSTASETUID2 exported, shared data
+280  18  0f9e  NETFILEGETINFO2 exported, shared data
+282  18  0f40  NETFILECLOSE2 exported, shared data
+299  25  0b34  I_NETPATHTYPE exported, shared data
+300  25  0000  I_NETPATHCANONICALIZE exported, shared data
+301  25  0932  I_NETPATHCOMPARE exported, shared data
+302  25  1afe  I_NETNAMEVALIDATE exported, shared data
+303  25  173e  I_NETNAMECANONICALIZE exported, shared data
+304  25  196e  I_NETNAMECOMPARE exported, shared data
+305  25  1cee  I_NETLISTCANONICALIZE exported, shared data
+306  25  22c2  I_NETLISTTRAVERSE exported, shared data
+501   8  0000  DOSDELETEMAILSLOT exported, shared data
+502   8  0072  DOSMAILSLOTINFO exported, shared data
+503   8  00ec  DOSMAKEMAILSLOT exported, shared data
+504   8  0320  DOSPEEKMAILSLOT exported, shared data
+523   8  0454  DOSREADMAILSLOT exported, shared data
+524   8  058a  DOSWRITEMAILSLOT exported, shared data
+525  11  0000  NETMESSAGEBUFFERSEND exported, shared data
+526  11  0e1e  NETMESSAGEFILESEND exported, shared data
+527   5  0000  NETSERVERENUM exported, shared data
+528   5  013a  NETSERVERENUM2 exported, shared data
+529  20  0000  NETSPECIALSMB exported, shared data
+530   2  0010  DOSMAKENMPIPE exported, shared data
+531   2  004c  DOSCONNECTNMPIPE exported, shared data
+532   2  002e  DOSDISCONNECTNMPIPE exported, shared data
+533   2  006a  DOSSETNMPHANDSTATE exported, shared data
+534   2  010a  DOSWAITNMPIPE exported, shared data
+535   2  01d2  DOSTRANSACTNMPIPE exported, shared data
+536   2  02e5  DOSQNMPHANDSTATE exported, shared data
+537   2  0388  DOSQNMPIPEINFO exported, shared data
+538   2  044d  DOSPEEKNMPIPE exported, shared data
+539   2  057d  DOSCALLNMPIPE exported, shared data
+540   2  06cf  DOSRAWREADNMPIPE exported, shared data
+541   2  07b6  DOSRAWWRITENMPIPE exported, shared data
+542   2  0b4f  DOSREADASYNCNMPIPE exported, shared data
+543   2  0d73  DOSWRITEASYNCNMPIPE exported, shared data
diff --git a/etc/olecli-ordinals b/etc/olecli-ordinals
new file mode 100644
index 0000000..2438fa1
--- /dev/null
+++ b/etc/olecli-ordinals
@@ -0,0 +1,178 @@
+  1   1  0000  WEP exported, shared data
+  2   3  004e  OLEDELETE exported, shared data
+  3   3  00c6  OLESAVETOSTREAM exported, shared data
+  4   3  0122  OLELOADFROMSTREAM exported, shared data
+  6   3  0400  OLECLONE exported, shared data
+  7   3  04ec  OLECOPYFROMLINK exported, shared data
+  8   3  0606  OLEEQUAL exported, shared data
+  9   3  0674  OLEQUERYLINKFROMCLIP exported, shared data
+ 10   3  06a0  OLEQUERYCREATEFROMCLIP exported, shared data
+ 11   3  06cc  OLECREATELINKFROMCLIP exported, shared data
+ 12   3  08a2  OLECREATEFROMCLIP exported, shared data
+ 13   3  0b52  OLECOPYTOCLIPBOARD exported, shared data
+ 14   3  1d48  OLEQUERYTYPE exported, shared data
+ 15   3  0b8e  OLESETHOSTNAMES exported, shared data
+ 16   3  0c04  OLESETTARGETDEVICE exported, shared data
+ 17   3  0c84  OLESETBOUNDS exported, shared data
+ 18   3  0ce0  OLEQUERYBOUNDS exported, shared data
+ 19   3  0da0  OLEDRAW exported, shared data
+ 20   3  0e24  OLEQUERYOPEN exported, shared data
+ 21   3  0e60  OLEACTIVATE exported, shared data
+ 22   3  0eea  OLEUPDATE exported, shared data
+ 23   3  0f26  OLERECONNECT exported, shared data
+ 24   3  0f62  OLEGETLINKUPDATEOPTIONS exported, shared data
+ 25   3  0fbe  OLESETLINKUPDATEOPTIONS exported, shared data
+ 26   3  0ffc  OLEENUMFORMATS exported, shared data
+ 27   3  0eae  OLECLOSE exported, shared data
+ 28   3  107e  OLEGETDATA exported, shared data
+ 29   3  10dc  OLESETDATA exported, shared data
+ 30   3  0010  OLEQUERYPROTOCOL exported, shared data
+ 31   3  111e  OLEQUERYOUTOFDATE exported, shared data
+ 32   3  115a  OLEOBJECTCONVERT exported, shared data
+ 33   3  121a  OLECREATEFROMTEMPLATE exported, shared data
+ 34   3  13b4  OLECREATE exported, shared data
+ 35   3  1ba6  OLEQUERYRELEASESTATUS exported, shared data
+ 36   3  1c04  OLEQUERYRELEASEERROR exported, shared data
+ 37   3  1c40  OLEQUERYRELEASEMETHOD exported, shared data
+ 38   3  16fa  OLECREATEFROMFILE exported, shared data
+ 39   3  190a  OLECREATELINKFROMFILE exported, shared data
+ 40   3  008a  OLERELEASE exported, shared data
+ 41   2  093e  OLEREGISTERCLIENTDOC exported, shared data
+ 42   2  0a9e  OLEREVOKECLIENTDOC exported, shared data
+ 43   2  0bb6  OLERENAMECLIENTDOC exported, shared data
+ 44   2  0c8e  OLEREVERTCLIENTDOC exported, shared data
+ 45   2  0cc8  OLESAVEDCLIENTDOC exported, shared data
+ 46   3  1c7c  OLERENAME exported, shared data
+ 47   2  0cf6  OLEENUMOBJECTS exported, shared data
+ 48   3  1d00  OLEQUERYNAME exported, shared data
+ 49   3  0c42  OLESETCOLORSCHEME exported, shared data
+ 50   3  1034  OLEREQUESTDATA exported, shared data
+ 54   4  0000  OLELOCKSERVER exported, shared data
+ 55   4  025a  OLEUNLOCKSERVER exported, shared data
+ 56   3  0d3c  OLEQUERYSIZE exported, shared data
+ 57   3  1cbe  OLEEXECUTE exported, shared data
+ 58   3  152e  OLECREATEINVISIBLE exported, shared data
+ 59   3  1da4  OLEQUERYCLIENTVERSION exported, shared data
+ 60   3  46d4  OLEISDCMETA exported, shared data
+100   4  0c28  DOCWNDPROC exported, shared data
+101   4  0d2c  SRVRWNDPROC exported, shared data
+102  14  0838  MFCALLBACKFUNC exported, shared data
+110   5  0000  DEFLOADFROMSTREAM exported, shared data
+111   5  00fe  DEFCREATEFROMCLIP exported, shared data
+112   5  0180  DEFCREATELINKFROMCLIP exported, shared data
+113   5  01be  DEFCREATEFROMTEMPLATE exported, shared data
+114   5  01fe  DEFCREATE exported, shared data
+115   5  023e  DEFCREATEFROMFILE exported, shared data
+116   5  028e  DEFCREATELINKFROMFILE exported, shared data
+117   5  02e0  DEFCREATEINVISIBLE exported, shared data
+200   4  04e0  LERELEASE exported, shared data
+201   4  1e52  LESHOW exported, shared data
+202   3  2508  LEGETDATA exported, shared data
+203   4  3a54  LESETDATA exported, shared data
+204   4  37ee  LESETHOSTNAMES exported, shared data
+205   4  386e  LESETTARGETDEVICE exported, shared data
+206   4  3922  LESETBOUNDS exported, shared data
+207   3  27be  LESAVETOSTREAM exported, shared data
+208   3  1fde  LECLONE exported, shared data
+209   4  052a  LECOPYFROMLINK exported, shared data
+210   6  0134  LEEQUAL exported, shared data
+211   3  227a  LECOPY exported, shared data
+212   3  2e00  LEQUERYTYPE exported, shared data
+213   3  2370  LEQUERYBOUNDS exported, shared data
+214   3  23fc  LEDRAW exported, shared data
+215   4  2108  LEQUERYOPEN exported, shared data
+216   4  219a  LEACTIVATE exported, shared data
+218   4  2200  LEUPDATE exported, shared data
+219   4  2cb4  LERECONNECT exported, shared data
+220   3  2454  LEENUMFORMAT exported, shared data
+221   6  00c8  LEQUERYPROTOCOL exported, shared data
+222   3  2638  LEQUERYOUTOFDATE exported, shared data
+223   6  01c2  LEOBJECTCONVERT exported, shared data
+224   4  07fa  LECHANGEDATA exported, shared data
+225   4  2c16  LECLOSE exported, shared data
+226   3  2e72  LEGETUPDATEOPTIONS exported, shared data
+227   4  337a  LESETUPDATEOPTIONS exported, shared data
+228   4  4a44  LEEXECUTE exported, shared data
+229   6  0000  LEOBJECTLONG exported, shared data
+230   4  322c  LECREATEINVISIBLE exported, shared data
+300   9  0000  MFRELEASE exported, shared data
+301   9  0258  MFGETDATA exported, shared data
+302   3  42f2  MFSAVETOSTREAM exported, shared data
+303   9  0082  MFCLONE exported, shared data
+304   9  0174  MFEQUAL exported, shared data
+305   9  01f0  MFCOPY exported, shared data
+307   3  446a  MFQUERYBOUNDS exported, shared data
+308  14  05cc  MFDRAW exported, shared data
+309   9  0234  MFENUMFORMAT exported, shared data
+310   9  0302  MFCHANGEDATA exported, shared data
+400  11  0000  BMRELEASE exported, shared data
+401  11  0254  BMGETDATA exported, shared data
+402   3  4b92  BMSAVETOSTREAM exported, shared data
+403  11  006e  BMCLONE exported, shared data
+404  11  00e4  BMEQUAL exported, shared data
+405   3  4c8c  BMCOPY exported, shared data
+407   3  4ce0  BMQUERYBOUNDS exported, shared data
+408  14  0000  BMDRAW exported, shared data
+409  11  0230  BMENUMFORMAT exported, shared data
+410   3  5004  BMCHANGEDATA exported, shared data
+500  12  0000  DIBRELEASE exported, shared data
+501  12  01ea  DIBGETDATA exported, shared data
+502   3  536c  DIBSAVETOSTREAM exported, shared data
+503  12  006e  DIBCLONE exported, shared data
+504  12  00e4  DIBEQUAL exported, shared data
+505  12  011c  DIBCOPY exported, shared data
+507  12  016c  DIBQUERYBOUNDS exported, shared data
+508  14  02f2  DIBDRAW exported, shared data
+509  12  01c6  DIBENUMFORMAT exported, shared data
+510  12  028a  DIBCHANGEDATA exported, shared data
+600  10  0000  GENRELEASE exported, shared data
+601  10  049e  GENGETDATA exported, shared data
+602  10  0438  GENSETDATA exported, shared data
+603   3  4750  GENSAVETOSTREAM exported, shared data
+604  10  0082  GENCLONE exported, shared data
+605  10  012e  GENEQUAL exported, shared data
+606  10  0164  GENCOPY exported, shared data
+608   3  4b60  GENQUERYBOUNDS exported, shared data
+609  14  05b2  GENDRAW exported, shared data
+610  10  04e0  GENENUMFORMAT exported, shared data
+611  10  0222  GENCHANGEDATA exported, shared data
+701  13  0034  ERRSHOW exported, shared data
+702  13  0186  ERRSETDATA exported, shared data
+703  13  0082  ERRSETHOSTNAMES exported, shared data
+704  13  009c  ERRSETTARGETDEVICE exported, shared data
+705  13  00d0  ERRSETBOUNDS exported, shared data
+706  13  0068  ERRCOPYFROMLINK exported, shared data
+707  13  00ea  ERRQUERYOPEN exported, shared data
+708  13  0104  ERRACTIVATE exported, shared data
+709  13  0138  ERRCLOSE exported, shared data
+710  13  0152  ERRUPDATE exported, shared data
+711  13  016c  ERRRECONNECT exported, shared data
+712  13  0222  ERRQUERYPROTOCOL exported, shared data
+713  13  01ba  ERRQUERYOUTOFDATE exported, shared data
+714  13  01d4  ERROBJECTCONVERT exported, shared data
+715  13  01ee  ERRGETUPDATEOPTIONS exported, shared data
+716  13  0208  ERRSETUPDATEOPTIONS exported, shared data
+717  13  0256  ERREXECUTE exported, shared data
+718  13  0270  ERROBJECTLONG exported, shared data
+800   7  0000  PBLOADFROMSTREAM exported, shared data
+801   7  00ac  PBCREATEFROMCLIP exported, shared data
+802   7  017a  PBCREATELINKFROMCLIP exported, shared data
+803   7  0212  PBCREATEFROMTEMPLATE exported, shared data
+804   7  02a8  PBCREATE exported, shared data
+805   7  06f4  PBDRAW exported, shared data
+806   7  0626  PBQUERYBOUNDS exported, shared data
+807   7  0818  PBCOPYTOCLIPBOARD exported, shared data
+808   7  033e  PBCREATEFROMFILE exported, shared data
+809   7  03e0  PBCREATELINKFROMFILE exported, shared data
+810   7  0768  PBENUMFORMATS exported, shared data
+811   7  07a8  PBGETDATA exported, shared data
+812   7  0492  PBCREATEINVISIBLE exported, shared data
+910   3  3e50  OBJQUERYNAME exported, shared data
+911   3  3f06  OBJRENAME exported, shared data
+912   3  410e  OBJQUERYTYPE exported, shared data
+913   3  4154  OBJQUERYSIZE exported, shared data
+950   8  0456  CONNECTDLGPROC exported, shared data
+951   8  0000  SETNETNAME exported, shared data
+952   8  011a  CHECKNETDRIVE exported, shared data
+953   8  025c  SETNEXTNETDRIVE exported, shared data
+954   8  0696  GETTASKVISIBLEWINDOW exported, shared data
diff --git a/etc/olesvr-ordinals b/etc/olesvr-ordinals
new file mode 100644
index 0000000..02deb6b
--- /dev/null
+++ b/etc/olesvr-ordinals
@@ -0,0 +1,23 @@
+  1   1  0000  WEP exported, shared data
+  2   3  036e  OLEREGISTERSERVER exported, shared data
+  3   3  05f0  OLEREVOKESERVER exported, shared data
+  4   3  3d46  OLEBLOCKSERVER exported, shared data
+  5   3  3d92  OLEUNBLOCKSERVER exported, shared data
+  6   3  1108  OLEREGISTERSERVERDOC exported, shared data
+  7   3  12dc  OLEREVOKESERVERDOC exported, shared data
+  8   3  13a2  OLERENAMESERVERDOC exported, shared data
+  9   3  1528  OLEREVERTSERVERDOC exported, shared data
+ 10   3  14ba  OLESAVEDSERVERDOC exported, shared data
+ 11   3  2140  OLEREVOKEOBJECT exported, shared data
+ 12   3  0354  OLEQUERYSERVERVERSION exported, shared data
+ 21   3  07a2  SRVRWNDPROC exported, shared data
+ 22   3  1728  DOCWNDPROC exported, shared data
+ 23   3  23b2  ITEMWNDPROC exported, shared data
+ 24   3  2d3c  SENDDATAMSG exported, shared data
+ 25   3  22ac  FINDITEMWND exported, shared data
+ 26   3  2a5c  ITEMCALLBACK exported, shared data
+ 27   3  0752  TERMINATECLIENTS exported, shared data
+ 28   3  1554  TERMINATEDOCCLIENTS exported, shared data
+ 29   3  222e  DELETECLIENTINFO exported, shared data
+ 30   3  2cbc  SENDRENAMEMSG exported, shared data
+ 31   3  2c5e  ENUMFORTERMINATE exported, shared data
diff --git a/etc/shell-ordinals b/etc/shell-ordinals
new file mode 100644
index 0000000..aa26138
--- /dev/null
+++ b/etc/shell-ordinals
@@ -0,0 +1,26 @@
+  1   2  15cc  REGOPENKEY exported, shared data
+  2   2  15fa  REGCREATEKEY exported, shared data
+  3   2  1670  REGCLOSEKEY exported, shared data
+  4   2  1628  REGDELETEKEY exported, shared data
+  5   2  16f4  REGSETVALUE exported, shared data
+  6   2  168e  REGQUERYVALUE exported, shared data
+  7   2  14dc  REGENUMKEY exported, shared data
+  8   7  0000  WEP exported, shared data
+  9   6  0052  DRAGACCEPTFILES exported, shared data
+ 11   6  0094  DRAGQUERYFILE exported, shared data
+ 12   6  0142  DRAGFINISH exported, shared data
+ 13   6  0000  DRAGQUERYPOINT exported, shared data
+ 20   4  110a  SHELLEXECUTE exported, shared data
+ 21   4  1154  FINDEXECUTABLE exported, shared data
+ 22   9  0000  SHELLABOUT exported, shared data
+ 32   9  0829  WCI exported, shared data
+ 33   9  0136  ABOUTDLGPROC exported, shared data
+ 34  10  021a  EXTRACTICON exported, shared data
+ 36  10  08dc  EXTRACTASSOCIATEDICON exported, shared data
+ 37   5  00ae  DOENVIRONMENTSUBST exported, shared data
+ 38   5  0000  FINDENVIRONMENTSTRING exported, shared data
+ 39  10  026e  INTERNALEXTRACTICON exported, shared data
+100   4  0550  HERETHARBETYGARS exported, shared data
+101   8  010e  FINDEXEDLGPROC exported, shared data
+102   4  128c  REGISTERSHELLHOOK exported, shared data
+103   4  11ca  SHELLHOOKPROC exported, shared data
diff --git a/etc/toolhelp-ordinals b/etc/toolhelp-ordinals
new file mode 100644
index 0000000..2118519
--- /dev/null
+++ b/etc/toolhelp-ordinals
@@ -0,0 +1,35 @@
+  1   1  018a  WEP exported, shared data
+ 50   1  057b  GLOBALHANDLETOSEL exported, shared data
+ 51   1  0318  GLOBALFIRST exported, shared data
+ 52   1  0399  GLOBALNEXT exported, shared data
+ 53   1  02a2  GLOBALINFO exported, shared data
+ 54   1  0417  GLOBALENTRYHANDLE exported, shared data
+ 55   1  04a9  GLOBALENTRYMODULE exported, shared data
+ 56   1  090e  LOCALINFO exported, shared data
+ 57   1  095e  LOCALFIRST exported, shared data
+ 58   1  09e9  LOCALNEXT exported, shared data
+ 59   1  0a90  MODULEFIRST exported, shared data
+ 60   1  0ad9  MODULENEXT exported, shared data
+ 61   1  0b15  MODULEFINDNAME exported, shared data
+ 62   1  0b8c  MODULEFINDHANDLE exported, shared data
+ 63   1  0caa  TASKFIRST exported, shared data
+ 64   1  0ced  TASKNEXT exported, shared data
+ 65   1  0d2e  TASKFINDHANDLE exported, shared data
+ 66   1  0f1c  STACKTRACEFIRST exported, shared data
+ 67   1  0f67  STACKTRACECSIPFIRST exported, shared data
+ 68   1  0fca  STACKTRACENEXT exported, shared data
+ 69   1  28b0  CLASSFIRST exported, shared data
+ 70   1  2925  CLASSNEXT exported, shared data
+ 71   1  11ce  SYSTEMHEAPINFO exported, shared data
+ 72   1  13f4  MEMMANINFO exported, shared data
+ 73   1  1b72  NOTIFYREGISTER exported, shared data
+ 74   1  1c29  NOTIFYUNREGISTER exported, shared data
+ 75   1  2060  INTERRUPTREGISTER exported, shared data
+ 76   1  2111  INTERRUPTUNREGISTER exported, shared data
+ 77   1  26ea  TERMINATEAPP exported, shared data
+ 78   1  29c4  MEMORYREAD exported, shared data
+ 79   1  2b6c  MEMORYWRITE exported, shared data
+ 80   1  2dae  TIMERCOUNT exported, shared data
+ 81   1  0d68  TASKSETCSIP exported, shared data
+ 82   1  0d97  TASKGETCSIP exported, shared data
+ 83   1  0dc0  TASKSWITCH exported, shared data
diff --git a/etc/win87em-ordinals b/etc/win87em-ordinals
new file mode 100644
index 0000000..00ee2ab
--- /dev/null
+++ b/etc/win87em-ordinals
@@ -0,0 +1,5 @@
+  1   1  002a  __FPMATH exported
+  2   1  0089  WEP exported
+  3   1  01ab  __WIN87EMINFO exported
+  4   1  0220  __WIN87EMRESTORE exported
+  5   1  01e3  __WIN87EMSAVE exported
diff --git a/if1632/Imakefile b/if1632/Imakefile
index deee54f..72d1b09 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -46,9 +46,13 @@
 DependTarget()
 CleanTarget()
 
+pop.h: $(TOP)/tools/build
+	$(TOP)/tools/build -p
+
 includes::
 
 install::
 
 clean::
-	$(RM) dll* dtb*
+	$(RM) dll* dtb* pop.h
+	touch pop.h
diff --git a/if1632/call.S b/if1632/call.S
index 420d7bb..7210e68 100644
--- a/if1632/call.S
+++ b/if1632/call.S
@@ -361,18 +361,7 @@
 	 * address again.
 	 */
 	add	$6,%esp		/* argument count, return address */
-	popw	%gs
-	add	$2,%esp
-	popw	%fs
-	add	$2,%esp
-	popw	%es
-	add	$2,%esp
-	popw	%ds
-	add	$2,%esp
-	popal
-	add	$16,%esp	/* trapno, err, eip, cs */
-	popfl
-	add	$20,%esp	/* esp, ss, i387, oldmask, cr2 */
+#include "pop.h"		/* restore context                */
 
 	/*
 	 * Return to original caller.
diff --git a/if1632/callback.c b/if1632/callback.c
index 82c71de..ac2ab9f 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -142,6 +142,8 @@
 LONG CallWindowProc( FARPROC func, HWND hwnd, WORD message,
 		     WORD wParam, LONG lParam )
 {
+    SpyMessage(hwnd, message, wParam, lParam);
+    
     if (Is16bitAddress(func))
     {	
 	PushOn16( CALLBACK_SIZE_WORD, hwnd );
@@ -176,6 +178,44 @@
     }
 }
 
+/**********************************************************************
+ *					CallHookProc
+ */
+DWORD CallHookProc( HOOKPROC func, short code, WPARAM wParam, LPARAM lParam )
+{
+    if (Is16bitAddress(func))
+    {
+	PushOn16( CALLBACK_SIZE_WORD, code );
+	PushOn16( CALLBACK_SIZE_WORD, wParam );
+	PushOn16( CALLBACK_SIZE_LONG, lParam );
+	return CallTo16((unsigned int) func, 
+			FindDataSegmentForCode((unsigned long) func));   
+    }
+    else
+    {
+	return (*func)( code, wParam, lParam );
+    }
+}
+
+/**********************************************************************
+ *					CallGrayStringProc
+ */
+BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch )
+{
+    if (Is16bitAddress(func))
+    {
+	PushOn16( CALLBACK_SIZE_WORD, hdc );
+	PushOn16( CALLBACK_SIZE_LONG, lParam );
+	PushOn16( CALLBACK_SIZE_WORD, cch );
+	return CallTo16((unsigned int) func, 
+			FindDataSegmentForCode((unsigned long) func));   
+    }
+    else
+    {
+	return (*func)( hdc, lParam, cch );
+    }
+}
+
 /* ------------------------------------------------------------------------ */
 /*
  * The following functions realize the Catch/Throw functionality.
diff --git a/if1632/findfunc b/if1632/findfunc
old mode 100755
new mode 100644
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index b1a46fb..027100e 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -80,6 +80,7 @@
 67  pascal DPtoLP(word ptr s_word) DPtoLP(1 2 3)
 68  pascal DeleteDC(word) DeleteDC(1)
 69  pascal DeleteObject(word) DeleteObject(1)
+70  pascal EnumFonts(word ptr ptr ptr) EnumFonts(1 2 3 4)
 72  pascal EqualRgn(word word) EqualRgn(1 2)
 73  pascal ExcludeVisRect(word s_word s_word s_word s_word)
 	   ExcludeVisRect(1 2 3 4 5)
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 4472289..d21f57c 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -5,7 +5,6 @@
 length	415
 
 3   pascal GetVersion() GetVersion()
-#return GetVersion 0 0x301
 4   pascal LocalInit(word word word) WIN16_LocalInit(1 2 3)
 5   pascal LocalAlloc(word word) WIN16_LocalAlloc(1 2)
 6   pascal LocalReAlloc(word word word) WIN16_LocalReAlloc(1 2 3)
@@ -28,10 +27,12 @@
 23  pascal LockSegment(s_word) KERNEL_LockSegment(1)
 24  pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1)
 25  pascal GlobalCompact(long) GlobalCompact(1)
+#29  pascal Yield() Yield()
 30  pascal WaitEvent(word) KERNEL_WaitEvent(1)
 34  pascal SetTaskQueue(word word) SetTaskQueue(1 2)
 35  pascal GetTaskQueue(word) GetTaskQueue(1)
 36  pascal GetCurrentTask() GetCurrentTask()
+45  pascal LoadModule(ptr ptr) LoadModule(1 2)
 47  pascal GetModuleHandle(ptr) GetModuleHandle(1)
 48  pascal GetModuleUsage(word) GetModuleUsage(1)
 49  pascal GetModuleFileName(word ptr s_word) GetModuleFileName(1 2 3)
@@ -46,6 +47,12 @@
 62  pascal LockResource(word) LockResource(1)
 63  pascal FreeResource(word) FreeResource(1)
 64  pascal AccessResource(word word) AccessResource(1 2)
+68  pascal InitAtomTable(word) InitAtomTable(1)
+69  pascal FindAtom(ptr) FindAtom(1)
+70  pascal AddAtom(ptr) AddAtom(1)
+71  pascal DeleteAtom(word) DeleteAtom(1)
+72  pascal GetAtomName(word ptr word) GetAtomName(1 2 3)
+73  pascal GetAtomHandle(word) GetAtomHandle(1)
 74  pascal OpenFile(ptr ptr word) OpenFile(1 2 3)
 81  pascal _lclose(word) _lclose(1)
 82  pascal _lread(word ptr word) _lread(1 2 3)
@@ -82,9 +89,9 @@
 #132 return GetWinFlags 0 0x413
 134 pascal GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2)
 135 pascal GetSystemDirectory(ptr word) GetSystemDirectory(1 2)
-136 pascal GetDriveType(byte) GetWindowsDirectory(1)
+136 pascal GetDriveType(byte) GetDriveType(1)
 137 pascal FatalAppExit(word ptr) FatalAppExit(1 2)
-152 return GetNumTasks 0 1
+152 pascal GetNumTasks() GetNumTasks()
 154 return GlobalNotify 4 0
 163 pascal GlobalLRUOldest(word) ReturnArg(1)
 164 pascal GlobalLRUNewest(word) ReturnArg(1)
@@ -105,4 +112,11 @@
 57  pascal GetProfileInt(ptr ptr word) GetProfileInt(1 2 3)
 58  pascal GetProfileString(ptr ptr ptr ptr word) GetProfileString(1 2 3 4 5)
 199 pascal SetHandleCount(word) SetHandleCount(1)
+68  pascal InitAtomTable(word) InitAtomTable(1)
+69  pascal FindAtom(ptr) FindAtom(1)
+70  pascal AddAtom(ptr) AddAtom(1)
+71  pascal DeleteAtom(word) DeleteAtom(1)
+72  pascal GetAtomName(word ptr s_word) GetAtomName(1 2 3)
+73  pascal GetAtomHandle(word) GetAtomHandle(1)
 353 pascal lstrcpyn(ptr ptr word) lstrcpyn(1 2 3)
+
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
new file mode 100644
index 0000000..b9d01e7
--- /dev/null
+++ b/if1632/mmsystem.spec
@@ -0,0 +1,74 @@
+# $Id: mmsystem.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
+#
+name	mmsystem
+id	11
+length 706
+
+1      pascal  LIBMAIN(word word word ptr) MCI_LibMain(1 2 3 4)
+2      pascal  SNDPLAYSOUND(ptr word) sndPlaySound(1 2)
+5      pascal  MMSYSTEMGETVERSION() mmsystemGetVersion()
+30     pascal  OUTPUTDEBUGSTR(ptr) OutputDebugStr(1)
+201    pascal  MIDIOUTGETNUMDEVS() midiOutGetNumDevs()
+202    pascal  MIDIOUTGETDEVCAPS(word ptr word) midiOutGetDevCaps(1 2 3)
+203    pascal  MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText(1 2 3)
+204    pascal  MIDIOUTOPEN(ptr word ptr long long long) midiOutOpen(1 2 3 4 5 6)
+205    pascal  MIDIOUTCLOSE(word) midiOutClose(1)
+206    pascal  MIDIOUTPREPAREHEADER(word ptr word) midiOutPrepareHeader(1 2 3)
+207    pascal  MIDIOUTUNPREPAREHEADER(word ptr word) midiOutUnprepareHeader(1 2 3)
+208    pascal  MIDIOUTSHORTMSG(word long) midiOutShortMsg(1 2)
+209    pascal  MIDIOUTLONGMSG(word ptr word) midiOutLongMsg(1 2 3)
+210    pascal  MIDIOUTRESET(word) midiOutReset(1)
+211    pascal  MIDIOUTGETVOLUME(word ptr) midiOutGetVolume(1 2)
+212    pascal  MIDIOUTSETVOLUME(word long) midiOutSetVolume(1 2)
+215    pascal  MIDIOUTGETID(word ptr) midiOutGetID(1 2)
+301    pascal  MIDIINGETNUMDEVS() midiInGetNumDevs()
+302    pascal  MIDIINGETDEVCAPS(word ptr word) midiInGetDevCaps(1 2 3)
+303    pascal  MIDIINGETERRORTEXT(word ptr word) midiInGetErrorText(1 2 3)
+304    pascal  MIDIINOPEN(ptr word ptr long long long) midiInOpen(1 2 3 4 5 6)
+305    pascal  MIDIINCLOSE(word) midiInClose(1)
+306    pascal  MIDIINPREPAREHEADER(word ptr word) midiInPrepareHeader(1 2 3)
+307    pascal  MIDIINUNPREPAREHEADER(word ptr word) midiInUnprepareHeader(1 2 3)
+309    pascal  MIDIINSTART(word) midiInStart(1)
+310    pascal  MIDIINSTOP(word) midiInStop(1)
+311    pascal  MIDIINRESET(word) midiInReset(1)
+312    pascal  MIDIINGETID(word ptr) midiInGetID(1 2)
+350    pascal  AUXGETNUMDEVS() auxGetNumDevs()
+351    pascal  AUXGETDEVCAPS(word ptr word) auxGetDevCaps(1 2 3)
+352    pascal  AUXGETVOLUME(word ptr) auxGetVolume(1 2)
+353    pascal  AUXSETVOLUME(word long) auxSetVolume(1 2)
+401    pascal  WAVEOUTGETNUMDEVS() waveOutGetNumDevs()
+402    pascal  WAVEOUTGETDEVCAPS(word ptr word) waveOutGetDevCaps(1 2 3)
+403    pascal  WAVEOUTGETERRORTEXT(word ptr word) waveOutGetErrorText(1 2 3)
+404    pascal  WAVEOUTOPEN(ptr word ptr long long long) waveOutOpen(1 2 3 4 5 6)
+405    pascal  WAVEOUTCLOSE(word) waveOutClose(1)
+406    pascal  WAVEOUTPREPAREHEADER(word ptr word) waveOutPrepareHeader(1 2 3)
+407    pascal  WAVEOUTUNPREPAREHEADER(word ptr word) waveOutUnprepareHeader(1 2 3)
+408    pascal  WAVEOUTWRITE(word ptr word) waveOutWrite(1 2 3)
+409    pascal  WAVEOUTPAUSE(word) waveOutPause(1)
+410    pascal  WAVEOUTRESTART(word) waveOutRestart(1)
+411    pascal  WAVEOUTRESET(word) waveOutReset(1)
+412    pascal  WAVEOUTGETPOSITION(word ptr word) waveOutGetPosition(1 2 3)
+413    pascal  WAVEOUTGETPITCH(word ptr) waveOutGetPitch(1 2)
+414    pascal  WAVEOUTSETPITCH(word long) waveOutSetPitch(1 2)
+415    pascal  WAVEOUTGETVOLUME(word ptr) waveOutGetVolume(1 2)
+416    pascal  WAVEOUTSETVOLUME(word long) waveOutSetVolume(1 2)
+417    pascal  WAVEOUTGETPLAYBACKRATE(word ptr) waveOutGetPlaybackRate(1 2)
+418    pascal  WAVEOUTSETPLAYBACKRATE(word long) waveOutSetPlaybackRate(1 2)
+419    pascal  WAVEOUTBREAKLOOP(word) waveOutBreakLoop(1)
+420    pascal  WAVEOUTGETID(word ptr) waveOutGetID(1 2)
+501    pascal  WAVEINGETNUMDEVS() waveInGetNumDevs()
+502    pascal  WAVEINGETDEVCAPS(word ptr word) waveInGetDevCaps(1 2 3)
+503    pascal  WAVEINGETERRORTEXT(word ptr word) waveInGetErrorText(1 2 3)
+504    pascal  WAVEINOPEN(ptr word ptr long long long) waveInOpen(1 2 3 4 5 6)
+505    pascal  WAVEINCLOSE(word) waveInClose(1)
+506    pascal  WAVEINPREPAREHEADER(word ptr word) waveInPrepareHeader(1 2 3)
+507    pascal  WAVEINUNPREPAREHEADER(word ptr word) waveInUnprepareHeader(1 2 3)
+508    pascal  WAVEINADDBUFFER(word ptr word) waveInAddBuffer(1 2 3)
+509    pascal  WAVEINSTART(word) waveInStart(1)
+510    pascal  WAVEINSTOP(word) waveInStop(1)
+511    pascal  WAVEINRESET(word) waveInReset(1)
+513    pascal  WAVEINGETID(word ptr) waveInGetID(1 2)
+701    pascal  MCISENDCOMMAND(word word long long) mciSendCommand(1 2 3 4)
+702    pascal  MCISENDSTRING(ptr ptr word word) mciSendString(1 2 3 4)
+703    pascal  MCIGETDEVICEID(ptr) mciSendCommand(1)
+706    pascal  MCIGETERRORSTRING(long ptr word) mciGetErrorString(1 2 3)
diff --git a/if1632/pop.h b/if1632/pop.h
new file mode 100644
index 0000000..ff2d961
--- /dev/null
+++ b/if1632/pop.h
@@ -0,0 +1,16 @@
+	add	$8,%esp
+	popw	%es
+	add	$2,%esp
+	popw	%ds
+	add	$2,%esp
+	popl	%edi
+	popl	%esi
+	popl	%ebp
+	add	$4,%esp
+	popl	%ebx
+	popl	%edx
+	popl	%ecx
+	popl	%eax
+	add	$16,%esp
+	popfl
+	add	$20,%esp
diff --git a/if1632/shell.spec b/if1632/shell.spec
index 0a02757..16d2a9e 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -3,3 +3,39 @@
 name	shell
 id	6
 length	256
+
+#
+# WARNING ! These functions are not documented, so I didn't look for
+# 			proper parameters. It's just to have stub for PROGMAN.EXE ...
+#
+
+  1 pascal RegOpenKey() RegOpenKey()
+  2 pascal RegCreateKey() RegCreateKey()
+  3 pascal RegCloseKey() RegCloseKey()
+  4 pascal RegDeleteKey() RegDeleteKey()
+ 20 pascal ShellExecute(ptr) ShellExecute(1) 
+102 pascal RegisterShellHook(ptr) RegisterShellHook(1)
+103 pascal ShellHookProc() ShellHookProc()
+
+#  8   7  0000  WEP exported, shared data
+# 33   9  0136  ABOUTDLGPROC exported, shared data
+# 34  10  021a  EXTRACTICON exported, shared data
+# 21   4  1154  FINDEXECUTABLE exported, shared data
+#  9   6  0052  DRAGACCEPTFILES exported, shared data
+#100   4  0550  HERETHARBETYGARS exported, shared data
+# 38   5  0000  FINDENVIRONMENTSTRING exported, shared data
+#  7   2  14dc  REGENUMKEY exported, shared data
+# 37   5  00ae  DOENVIRONMENTSUBST exported, shared data
+# 20   4  110a  SHELLEXECUTE exported, shared data
+#101   8  010e  FINDEXEDLGPROC exported, shared data
+# 11   6  0094  DRAGQUERYFILE exported, shared data
+# 13   6  0000  DRAGQUERYPOINT exported, shared data
+#  5   2  16f4  REGSETVALUE exported, shared data
+# 39  10  026e  INTERNALEXTRACTICON exported, shared data
+# 22   9  0000  SHELLABOUT exported, shared data
+#  6   2  168e  REGQUERYVALUE exported, shared data
+# 32   9  0829  WCI exported, shared data
+# 36  10  08dc  EXTRACTASSOCIATEDICON exported, shared data
+# 12   6  0142  DRAGFINISH exported, shared data
+
+
diff --git a/if1632/system.spec b/if1632/system.spec
new file mode 100644
index 0000000..b37eb9f
--- /dev/null
+++ b/if1632/system.spec
@@ -0,0 +1,3 @@
+name	system
+id	12
+length	20
diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec
new file mode 100644
index 0000000..0037da9
--- /dev/null
+++ b/if1632/toolhelp.spec
@@ -0,0 +1,3 @@
+name	toolhelp
+id	13
+length	83
diff --git a/if1632/user.spec b/if1632/user.spec
index d79948c..2b6ea2f 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -7,6 +7,7 @@
 1   pascal MessageBox(word ptr ptr word) MessageBox(1 2 3 4)
 5   pascal InitApp(word) USER_InitApp(1)
 6   pascal PostQuitMessage(word) PostQuitMessage(1)
+7   pascal ExitWindows(long word) ExitWindows(1 2)
 10  pascal SetTimer(word word word ptr) SetTimer(1 2 3 4)
 11  pascal SetSystemTimer(word word word ptr) SetSystemTimer(1 2 3 4)
 12  pascal KillTimer(word word) KillTimer(1 2)
@@ -21,6 +22,10 @@
 21  pascal GetDoubleClickTime() GetDoubleClickTime()
 22  pascal SetFocus(word) SetFocus(1)
 23  pascal GetFocus() GetFocus()
+24  pascal RemoveProp(word ptr) RemoveProp(1 2)
+25  pascal GetProp(word ptr) GetProp(1 2)
+26  pascal SetProp(word ptr word) SetProp(1 2 3)
+27  pascal EnumProps(word ptr) EnumProps(1 2)
 28  pascal ClientToScreen(word ptr) ClientToScreen(1 2)
 29  pascal ScreenToClient(word ptr) ScreenToClient(1 2)
 30  pascal WindowFromPoint(long) WindowFromPoint(1)
@@ -91,6 +96,8 @@
 96  pascal CheckRadioButton(word word word word) CheckRadioButton(1 2 3 4)
 97  pascal CheckDlgButton(word word word) CheckDlgButton(1 2 3)
 98  pascal IsDlgButtonChecked(word word) IsDlgButtonChecked(1 2)
+99  pascal DlgDirSelect(word ptr word) DlgDirSelect(1 2 3)
+100 pascal DlgDirList(word ptr word word word) DlgDirList(1 2 3 4 5)
 101 pascal SendDlgItemMessage(word word word word long)
 	   SendDlgItemMessage(1 2 3 4 5)
 102 pascal AdjustWindowRect(ptr long word) AdjustWindowRect(1 2 3)
@@ -107,7 +114,9 @@
 118 pascal RegisterWindowMessage(ptr) RegisterWindowMessage(1)
 119 pascal GetMessagePos() GetMessagePos()
 120 pascal GetMessageTime() GetMessageTime()
+121 pascal SetWindowsHook(s_word ptr) SetWindowsHook(1 2)
 122 pascal CallWindowProc(ptr word word word long) CallWindowProc(1 2 3 4 5)
+123 pascal CallMsgFilter(ptr s_word) CallMsgFilter(1 2)
 124 pascal UpdateWindow(word) UpdateWindow(1)
 125 pascal InvalidateRect(word ptr word) InvalidateRect(1 2 3)
 126 pascal InvalidateRgn(word word word) InvalidateRgn(1 2 3)
@@ -164,9 +173,14 @@
 181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3)
 182 pascal KillSystemTimer(word word) KillSystemTimer(1 2)
 183 pascal GetCaretPos(ptr) GetCaretPos(1)
+185 pascal GrayString(word word ptr ptr word word word word word)
+	   GrayString(1 2 3 4 5 6 7 8 9)
+188 pascal SetSysModalWindow(word) SetSysModalWindow(1)
 190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3)
 191 pascal ChildWindowFromPoint(word long) ChildWindowFromPoint(1 2)
 193 pascal IsClipboardFormatAvailable(word) IsClipboardFormatAvailable(1)
+194  pascal DlgDirSelectComboBox(word ptr word) DlgDirSelectComboBox(1 2 3)
+195 pascal DlgDirListComboBox(word ptr word word word) DlgDirListComboBox(1 2 3 4 5)
 200 pascal OpenComm(ptr word word) OpenComm(1 2 3)
 201 pascal SetCommState(ptr) SetCommState(1)
 202 pascal GetCommState(word ptr) GetCommState(1 2)
@@ -189,12 +203,16 @@
 220 pascal LoadMenuIndirect(ptr) LoadMenuIndirect(1)
 221 pascal ScrollDC(word s_word s_word ptr ptr word ptr) 
 	   ScrollDC(1 2 3 4 5 6 7)
+224 pascal GetWindowTask(word) GetWindowTask(1)
+225 pascal EnumTaskWindows(word ptr long) EnumTaskWindows(1 2 3)
 227 pascal GetNextDlgGroupItem(word word word) GetNextDlgGroupItem(1 2 3)
 228 pascal GetNextDlgTabItem(word word word) GetNextDlgTabItem(1 2 3)
 229 pascal GetTopWindow(word) GetTopWindow(1)
 230 pascal GetNextWindow(word word) GetNextWindow(1 2)
 232 pascal SetWindowPos(word word word word word word word) 
            SetWindowPos(1 2 3 4 5 6 7)
+234 pascal UnhookWindowsHook(s_word ptr) UnhookWindowsHook(1 2)
+235 pascal DefHookProc(s_word word long ptr) DefHookProc(1 2 3 4)
 236 pascal GetCapture() GetCapture()
 237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3)
 238 pascal ExcludeUpdateRgn(word word) ExcludeUpdateRgn(1 2)
@@ -205,12 +223,17 @@
 	   CreateDialogParam(1 2 3 4 5)
 242 pascal CreateDialogIndirectParam(word ptr word ptr long)
 	   CreateDialogIndirectParam(1 2 3 4 5)
+243 pascal GetDialogBaseUnits() GetDialogBaseUnits()
 244 pascal EqualRect(ptr ptr) EqualRect(1 2)
 248 pascal GetOpenClipboardWindow() GetOpenClipboardWindow()
 258 pascal MapWindowPoints(word word ptr word) MapWindowPoints(1 2 3 4)
 262 pascal GetWindow(word word) GetWindow(1 2)
 266 pascal SetMessageQueue(word) SetMessageQueue(1)
 267 pascal ShowScrollBar(word word word) ShowScrollBar(1 2 3)
+268 pascal GlobalAddAtom(ptr) GlobalAddAtom(1)
+269 pascal GlobalDeleteAtom(word) GlobalDeleteAtom(1)
+270 pascal GlobalFindAtom(ptr) GlobalFindAtom(1)
+271 pascal GlobalGetAtomName(word ptr s_word) GlobalGetAtomName(1 2 3)
 272 pascal IsZoomed(word) IsZoomed(1)
 277 pascal GetDlgCtrlID(word) GetDlgCtrlID(1)
 282 pascal SelectPalette(word word word) SelectPalette(1 2 3)
@@ -219,6 +242,9 @@
 286 pascal GetDesktopWindow() GetDesktopWindow()
 288 pascal GetMessageExtraInfo() GetMessageExtraInfo()
 290 pascal RedrawWindow(word ptr word word) RedrawWindow(1 2 3 4)
+291 pascal SetWindowsHookEx(s_word ptr word word) SetWindowsHookEx(1 2 3 4)
+292 pascal UnhookWindowsHookEx(ptr) UnhookWindowsHookEx(1)
+293 pascal CallNextHookEx(ptr s_word word long) CallNextHookEx(1 2 3 4)
 308 pascal DefDlgProc(word word word long) DefDlgProc(1 2 3 4)
 319 pascal ScrollWindowEx(word s_word s_word ptr ptr word ptr word) 
 	   ScrollWindowEx(1 2 3 4 5 6 7 8)
diff --git a/if1632/winsock.spec b/if1632/winsock.spec
index ba0e5fb..84ade1d 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -7,44 +7,44 @@
 id	9
 length	155
 
-1   pascal accept(long ptr ptr) Winsock_accept(1 2 3)
-2   pascal bind(long ptr word) Winsock_bind(1 2 3)
-3   pascal closesocket(long) Winsock_closesocket(1)
-4   pascal connect(long ptr word) Winsock_connect(1 2 3)
-5   pascal getpeername(long ptr ptr) Winsock_getpeername(1 2 3)
-6   pascal getsockname(long ptr ptr) Winsock_getsockname(1 2 3)
-7   pascal getsockopt(long word word ptr ptr)
+1   pascal accept(word ptr ptr) Winsock_accept(1 2 3)
+2   pascal bind(word ptr word) Winsock_bind(1 2 3)
+3   pascal closesocket(word) Winsock_closesocket(1)
+4   pascal connect(word ptr word) Winsock_connect(1 2 3)
+5   pascal getpeername(word ptr ptr) Winsock_getpeername(1 2 3)
+6   pascal getsockname(word ptr ptr) Winsock_getsockname(1 2 3)
+7   pascal getsockopt(word word word ptr ptr)
            Winsock_getsockopt(1 2 3 4 5)
 8   pascal htonl(long) Winsock_htonl(1)
 9   pascal htons(word) Winsock_htons(1)
-10  pascal inet_addr(ptr) Winsock_inet_addr(1)
+10  pascal inet_addr(long) Winsock_inet_addr(1)
 11  pascal inet_ntoa(long) Winsock_inet_ntoa(1)
-12  pascal ioctlsocket(long long ptr) Winsock_ioctlsocket(1 2 3)
-13  pascal listen(long word) Winsock_listen(1 2)
+12  pascal ioctlsocket(word long ptr) Winsock_ioctlsocket(1 2 3)
+13  pascal listen(word word) Winsock_listen(1 2)
 14  pascal ntohl(long) Winsock_ntohl(1)
 15  pascal ntohs(word) Winsock_ntohs(1)
-16  pascal recv(long ptr word word) Winsock_recv(1 2 3 4)
-17  pascal recvfrom(long ptr word word ptr ptr)
+16  pascal recv(word ptr word word) Winsock_recv(1 2 3 4)
+17  pascal recvfrom(word ptr word word ptr ptr)
            Winsock_recvfrom(1 2 3 4 5 6)
 18  pascal select(word ptr ptr ptr ptr word)
            Winsock_select(1 2 3 4 5 6)
-19  pascal send(long ptr word word) Winsock_send(1 2 3 4)
-20  pascal sendto(long ptr word word ptr ptr)
+19  pascal send(word ptr word word) Winsock_send(1 2 3 4)
+20  pascal sendto(word ptr word word ptr ptr)
            Winsock_sendto(1 2 3 4 5 6)
-21  pascal setsockopt(long word word ptr word)
+21  pascal setsockopt(word word word ptr word)
            Winsock_setsockopt(1 2 3 4 5)
-22  pascal shutdown(long word) Winsock_shutdown(1 2)
+22  pascal shutdown(word word) Winsock_shutdown(1 2)
 23  pascal socket(word word word) Winsock_socket(1 2 3)
 
 51  pascal gethostbyaddr(ptr word word) Winsock_gethostbyaddr(1 2 3)
 52  pascal gethostbyname(ptr) Winsock_gethostbyname(1)
 53  pascal getprotobyname(ptr) Winsock_getprotobyname(1)
 54  pascal getprotobynumber(word) Winsock_getprotobynumber(1)
-55  pascal getservbyname(ptr) Winsock_getservbyname(1)
+55  pascal getservbyname(ptr ptr) Winsock_getservbyname(1 2)
 56  pascal getservbyport(word ptr) Winsock_getservbyport(1 2)
 57  pascal gethostname(ptr word) Winsock_gethostname(1 2)
 
-101 pascal WSAAsyncSelect(long word word long)
+101 pascal WSAAsyncSelect(word word word long)
            WSAAsyncSelect(1 2 3 4)
 102 pascal WSAAsyncGetHostByAddr(word word ptr word word ptr word)
            WSAAsyncGetHostByAddr(1 2 3 4 5 6 7)
@@ -68,4 +68,4 @@
 115 pascal WSAStartup(word ptr) WSAStartup(1 2)
 116 pascal WSACleanup() WSACleanup()
 
-151 pascal __WSAFDIsSet(long ptr) WSAFDIsSet(1 2)
+151 pascal __WSAFDIsSet(word ptr) WSAFDIsSet(1 2)
diff --git a/include/driver.h b/include/driver.h
new file mode 100644
index 0000000..efc1f0b
--- /dev/null
+++ b/include/driver.h
@@ -0,0 +1,70 @@
+/*
+ * Drivers definitions
+ */
+
+#define DRV_LOAD                0x0001
+#define DRV_ENABLE              0x0002
+#define DRV_OPEN                0x0003
+#define DRV_CLOSE               0x0004
+#define DRV_DISABLE             0x0005
+#define DRV_FREE                0x0006
+#define DRV_CONFIGURE           0x0007
+#define DRV_QUERYCONFIGURE      0x0008
+#define DRV_INSTALL             0x0009
+#define DRV_REMOVE              0x000A
+#define DRV_EXITSESSION         0x000B
+#define DRV_EXITAPPLICATION     0x000C
+#define DRV_POWER               0x000F
+
+#define DRV_RESERVED            0x0800
+#define DRV_USER                0x4000
+
+#define DRVCNF_CANCEL           0x0000
+#define DRVCNF_OK               0x0001
+#define DRVCNF_RESTART 			0x0002
+
+#define DRVEA_NORMALEXIT  		0x0001
+#define DRVEA_ABNORMALEXIT 		0x0002
+
+#define GND_FIRSTINSTANCEONLY 	0x00000001
+
+#define GND_FORWARD  			0x00000000
+#define GND_REVERSE    			0x00000002
+
+typedef struct {
+	DWORD   dwDCISize;
+	LPCSTR  lpszDCISectionName;
+	LPCSTR  lpszDCIAliasName;
+	} DRVCONFIGINFO;
+typedef DRVCONFIGINFO FAR* LPDRVCONFIGINFO;
+
+typedef struct {
+	UINT    length;
+	HDRVR   hDriver;
+	HINSTANCE hModule;
+	char    szAliasName[128];
+	} DRIVERINFOSTRUCT;
+typedef DRIVERINFOSTRUCT FAR* LPDRIVERINFOSTRUCT;
+
+typedef LRESULT (CALLBACK* DRIVERPROC)(DWORD, HDRVR, UINT, LPARAM, LPARAM);
+
+typedef struct {
+	DRIVERINFOSTRUCT dis;
+	WORD		count;
+	void		*lpPrevItem;
+	void		*lpNextItem;
+	DRIVERPROC	lpDrvProc;
+	} DRIVERITEM;
+typedef DRIVERITEM FAR* LPDRIVERITEM;
+
+LRESULT DefDriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
+						DWORD dwParam1, DWORD dwParam2);
+HDRVR   WINAPI OpenDriver(LPSTR szDriverName, LPSTR szSectionName, LPARAM lParam2);
+LRESULT WINAPI CloseDriver(HDRVR hDriver, LPARAM lParam1, LPARAM lParam2);
+LRESULT WINAPI SendDriverMessage(HDRVR hDriver, WORD message, LPARAM lParam1, LPARAM lParam2);
+HINSTANCE WINAPI GetDriverModuleHandle(HDRVR hDriver);
+HDRVR   WINAPI GetNextDriver(HDRVR, DWORD);
+BOOL    WINAPI GetDriverInfo(HDRVR, DRIVERINFOSTRUCT FAR*);
+
+
+
diff --git a/include/gdi.h b/include/gdi.h
index 3ec95ea..27b4d3d 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -290,8 +290,9 @@
 extern MDESC *GDI_Heap;
 
 #define GDI_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&GDI_Heap,f,size) & 0xffff)
-#define GDI_HEAP_ADDR(handle) ((void *)((handle)|((int)GDI_Heap & 0xffff0000)))
 #define GDI_HEAP_FREE(handle) (HEAP_Free(&GDI_Heap,GDI_HEAP_ADDR(handle)))
+#define GDI_HEAP_ADDR(handle) \
+    ((void *)((handle) ? ((handle) | ((int)GDI_Heap & 0xffff0000)) : 0))
 
 #endif
 
diff --git a/include/hook.h b/include/hook.h
new file mode 100644
index 0000000..94f23f8
--- /dev/null
+++ b/include/hook.h
@@ -0,0 +1,42 @@
+/*
+ * Windows hook definitions
+ *
+ * Copyright 1994 Alexandre Julliard
+ */
+
+#ifndef HOOK_H
+#define HOOK_H
+
+#include "windows.h"
+#include "user.h"
+
+  /* Hook data (pointed to by a HHOOK) */
+typedef struct
+{
+    HHOOK    next;   /* Next hook in chain */
+    HOOKPROC proc;   /* Hook procedure */
+    short    id;     /* Hook id (WH_???) */
+    HTASK    htask;  /* Task owning this hook */
+} HOOKDATA;
+
+
+#define FIRST_HOOK  WH_MSGFILTER
+#define LAST_HOOK   WH_SHELL
+
+#define SYSTEM_HOOK(id)  (systemHooks[(id)-FIRST_HOOK])
+#define TASK_HOOK(id)    (taskHooks[(id)-FIRST_HOOK])
+#define INTERNAL_CALL_HOOK(hhook,code,wparam,lparam) \
+    ((hhook) ? CallHookProc(((HOOKDATA*)(hhook))->proc,code,wparam,lparam) : 0)
+
+#define CALL_SYSTEM_HOOK(id,code,wparam,lparam) \
+    INTERNAL_CALL_HOOK(SYSTEM_HOOK(id),code,wparam,lparam)
+#define CALL_TASK_HOOK(id,code,wparam,lparam) \
+    INTERNAL_CALL_HOOK(TASK_HOOK(id),code,wparam,lparam)
+
+extern DWORD CallHookProc( HOOKPROC func, short code,
+			   WPARAM wParam, LPARAM lParam );  /* callback.c */
+
+extern HHOOK systemHooks[];
+extern HHOOK taskHooks[];
+
+#endif  /* HOOK_H */
diff --git a/include/mdi.h b/include/mdi.h
index b6d179e..40f4399 100644
--- a/include/mdi.h
+++ b/include/mdi.h
@@ -28,6 +28,8 @@
     HWND	  hwndHitTest;
     BOOL          flagMenuAltered;
     BOOL          flagChildMaximized;
+    RECT          rectMaximize;
+    RECT          rectRestore;
 } MDICLIENTINFO;
 
 #endif /* MDI_H */
diff --git a/include/menu.h b/include/menu.h
index 19a6644..c5f513a 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -65,7 +65,8 @@
     char	item_text[1];		/* Text for menu item		  */
 } MENUITEMTEMPLATE;
 
-void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
+void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, 
+		    BOOL suppress_draw);
 BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
 void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
 void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
diff --git a/include/message.h b/include/message.h
index 905d182..5e6e9e8 100644
--- a/include/message.h
+++ b/include/message.h
@@ -53,5 +53,7 @@
 extern void hardware_event( WORD message, WORD wParam, LONG lParam,
 			    int xPos, int yPos, DWORD time, DWORD extraInfo );
 extern BOOL MSG_GetHardwareMessage( LPMSG msg );
+extern BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd,
+				    short code, BOOL sendIdle );
 
 #endif  /* MESSAGE_H */
diff --git a/include/metafile.h b/include/metafile.h
new file mode 100644
index 0000000..0a3e5e9
--- /dev/null
+++ b/include/metafile.h
@@ -0,0 +1,45 @@
+/*
+ * Metafile definitions
+ *
+ * Copyright  David W. Metcalfe, 1994
+ */
+
+#ifndef METAFILE_H
+#define METAFILE_H
+
+#include "windows.h"
+
+#define MFHEADERSIZE (sizeof(METAHEADER))
+#define MFVERSION 0x300
+#define META_EOF 0x0000
+
+typedef struct tagMETAFILE
+{
+    WORD   wMagic;	    /* `PO' */
+    char   Filename[80];    /* metafile name, if disk based */
+    int    hFile;           /* MSDOS file handle for metafile */
+    HANDLE hMetaHdr;	    /* handle of metafile header */
+    int    MetaOffset;	    /* offset of current record in metafile */
+    HANDLE hBuffer;	    /* handle of buffer for disk based metafiles */
+} METAFILE;
+typedef METAFILE *LPMETAFILE;
+
+
+BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen);
+BOOL MF_MetaParam1(DC *dc, short func, short param1);
+BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2);
+BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4);
+BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4, short param5, short param6);
+BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4, short param5,
+		   short param6, short param7, short param8);
+BOOL MF_CreateBrushIndirect(DC *dc, LOGBRUSH *logbrush);
+BOOL MF_CreatePatternBrush(DC *dc, LOGBRUSH *logbrush);
+BOOL MF_CreatePenIndirect(DC *dc, LOGPEN *logpen);
+BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count);
+BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count);
+
+#endif   /* METAFILE_H */
+
diff --git a/include/mmsystem.h b/include/mmsystem.h
new file mode 100644
index 0000000..ac6dd22
--- /dev/null
+++ b/include/mmsystem.h
@@ -0,0 +1,1390 @@
+/* 
+ * MMSYSTEM - Multimedia Wine Extension ... :-)
+ */
+
+#ifndef MMSYSTEM_H
+#define MMSYSTEM_H
+
+typedef LPSTR		    HPSTR;          /* a huge version of LPSTR */
+typedef LPCSTR			HPCSTR;         /* a huge version of LPCSTR */
+
+#define MAXPNAMELEN      32     /* max product name length (including NULL) */
+#define MAXERRORLENGTH   128    /* max error text length (including NULL) */
+
+typedef WORD    VERSION;        /* major (high byte), minor (low byte) */
+
+typedef struct {
+    UINT    wType;              /* indicates the contents of the union */
+    union {
+        DWORD ms;               /* milliseconds */
+        DWORD sample;           /* samples */
+        DWORD cb;               /* byte count */
+        struct {                /* SMPTE */
+            BYTE hour;          /* hours */
+            BYTE min;           /* minutes */
+            BYTE sec;           /* seconds */
+            BYTE frame;         /* frames  */
+            BYTE fps;           /* frames per second */
+            BYTE dummy;         /* pad */
+            } smpte;
+        struct {                /* MIDI */
+            DWORD songptrpos;   /* song pointer position */
+            } midi;
+        } u;
+    } MMTIME;
+typedef MMTIME FAR  *LPMMTIME;
+
+#define TIME_MS         0x0001  /* time in milliseconds */
+#define TIME_SAMPLES    0x0002  /* number of wave samples */
+#define TIME_BYTES      0x0004  /* current byte offset */
+#define TIME_SMPTE      0x0008  /* SMPTE time */
+#define TIME_MIDI       0x0010  /* MIDI time */
+
+#define MM_JOY1MOVE         0x3A0           /* joystick */
+#define MM_JOY2MOVE         0x3A1
+#define MM_JOY1ZMOVE        0x3A2
+#define MM_JOY2ZMOVE        0x3A3
+#define MM_JOY1BUTTONDOWN   0x3B5
+#define MM_JOY2BUTTONDOWN   0x3B6
+#define MM_JOY1BUTTONUP     0x3B7
+#define MM_JOY2BUTTONUP     0x3B8
+
+#define MM_MCINOTIFY        0x3B9           /* MCI */
+
+#define MM_WOM_OPEN         0x3BB           /* waveform output */
+#define MM_WOM_CLOSE        0x3BC
+#define MM_WOM_DONE         0x3BD
+
+#define MM_WIM_OPEN         0x3BE           /* waveform input */
+#define MM_WIM_CLOSE        0x3BF
+#define MM_WIM_DATA         0x3C0
+
+#define MM_MIM_OPEN         0x3C1           /* MIDI input */
+#define MM_MIM_CLOSE        0x3C2
+#define MM_MIM_DATA         0x3C3
+#define MM_MIM_LONGDATA     0x3C4
+#define MM_MIM_ERROR        0x3C5
+#define MM_MIM_LONGERROR    0x3C6
+
+#define MM_MOM_OPEN         0x3C7           /* MIDI output */
+#define MM_MOM_CLOSE        0x3C8
+#define MM_MOM_DONE         0x3C9
+
+
+#define MMSYSERR_BASE          0
+#define WAVERR_BASE            32
+#define MIDIERR_BASE           64
+#define TIMERR_BASE            96
+#define JOYERR_BASE            160
+#define MCIERR_BASE            256
+
+#define MCI_STRING_OFFSET      512
+#define MCI_VD_OFFSET          1024
+#define MCI_CD_OFFSET          1088
+#define MCI_WAVE_OFFSET        1152
+#define MCI_SEQ_OFFSET         1216
+
+#define MMSYSERR_NOERROR      0                    /* no error */
+#define MMSYSERR_ERROR        (MMSYSERR_BASE + 1)  /* unspecified error */
+#define MMSYSERR_BADDEVICEID  (MMSYSERR_BASE + 2)  /* device ID out of range */
+#define MMSYSERR_NOTENABLED   (MMSYSERR_BASE + 3)  /* driver failed enable */
+#define MMSYSERR_ALLOCATED    (MMSYSERR_BASE + 4)  /* device already allocated */
+#define MMSYSERR_INVALHANDLE  (MMSYSERR_BASE + 5)  /* device handle is invalid */
+#define MMSYSERR_NODRIVER     (MMSYSERR_BASE + 6)  /* no device driver present */
+#define MMSYSERR_NOMEM        (MMSYSERR_BASE + 7)  /* memory allocation error */
+#define MMSYSERR_NOTSUPPORTED (MMSYSERR_BASE + 8)  /* function isn't supported */
+#define MMSYSERR_BADERRNUM    (MMSYSERR_BASE + 9)  /* error value out of range */
+#define MMSYSERR_INVALFLAG    (MMSYSERR_BASE + 10) /* invalid flag passed */
+#define MMSYSERR_INVALPARAM   (MMSYSERR_BASE + 11) /* invalid parameter passed */
+#define MMSYSERR_LASTERROR    (MMSYSERR_BASE + 11) /* last error in range */
+
+#define CALLBACK_TYPEMASK   0x00070000l    /* callback type mask */
+#define CALLBACK_NULL       0x00000000l    /* no callback */
+#define CALLBACK_WINDOW     0x00010000l    /* dwCallback is a HWND */
+#define CALLBACK_TASK       0x00020000l    /* dwCallback is a HTASK */
+#define CALLBACK_FUNCTION   0x00030000l    /* dwCallback is a FARPROC */
+
+typedef void (CALLBACK DRVCALLBACK) (HDRVR h, UINT uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
+
+typedef DRVCALLBACK FAR *LPDRVCALLBACK;
+
+#define MM_MICROSOFT            1       /* Microsoft Corp. */
+
+#define MM_MIDI_MAPPER          1       /* MIDI Mapper */
+#define MM_WAVE_MAPPER          2       /* Wave Mapper */
+
+#define MM_SNDBLST_MIDIOUT      3       /* Sound Blaster MIDI output port */
+#define MM_SNDBLST_MIDIIN       4       /* Sound Blaster MIDI input port  */
+#define MM_SNDBLST_SYNTH        5       /* Sound Blaster internal synthesizer */
+#define MM_SNDBLST_WAVEOUT      6       /* Sound Blaster waveform output */
+#define MM_SNDBLST_WAVEIN       7       /* Sound Blaster waveform input */
+
+#define MM_ADLIB                9       /* Ad Lib-compatible synthesizer */
+
+#define MM_MPU401_MIDIOUT       10      /* MPU401-compatible MIDI output port */
+#define MM_MPU401_MIDIIN        11      /* MPU401-compatible MIDI input port */
+
+#define MM_PC_JOYSTICK          12      /* Joystick adapter */
+
+
+WORD WINAPI mmsystemGetVersion(void);
+void WINAPI OutputDebugStr(LPCSTR);
+
+BOOL WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT uFlags);
+
+#define SND_SYNC            0x0000  /* play synchronously (default) */
+#define SND_ASYNC           0x0001  /* play asynchronously */
+#define SND_NODEFAULT       0x0002  /* don't use default sound */
+#define SND_MEMORY          0x0004  /* lpszSoundName points to a memory file */
+#define SND_LOOP            0x0008  /* loop the sound until next sndPlaySound */
+#define SND_NOSTOP          0x0010  /* don't stop any currently playing sound */
+
+/* waveform audio error return values */
+#define WAVERR_BADFORMAT      (WAVERR_BASE + 0)    /* unsupported wave format */
+#define WAVERR_STILLPLAYING   (WAVERR_BASE + 1)    /* still something playing */
+#define WAVERR_UNPREPARED     (WAVERR_BASE + 2)    /* header not prepared */
+#define WAVERR_SYNC           (WAVERR_BASE + 3)    /* device is synchronous */
+#define WAVERR_LASTERROR      (WAVERR_BASE + 3)    /* last error in range */
+
+DECLARE_HANDLE(HWAVE);
+DECLARE_HANDLE(HWAVEIN);
+DECLARE_HANDLE(HWAVEOUT);
+typedef HWAVEIN FAR *LPHWAVEIN;
+typedef HWAVEOUT FAR *LPHWAVEOUT;
+typedef DRVCALLBACK WAVECALLBACK;
+typedef WAVECALLBACK FAR *LPWAVECALLBACK;
+
+#define WOM_OPEN        MM_WOM_OPEN
+#define WOM_CLOSE       MM_WOM_CLOSE
+#define WOM_DONE        MM_WOM_DONE
+#define WIM_OPEN        MM_WIM_OPEN
+#define WIM_CLOSE       MM_WIM_CLOSE
+#define WIM_DATA        MM_WIM_DATA
+
+#define WAVE_MAPPER     (-1)
+
+#define  WAVE_FORMAT_QUERY     0x0001
+#define  WAVE_ALLOWSYNC        0x0002
+
+typedef struct {
+    LPSTR       lpData;                 /* pointer to locked data buffer */
+    DWORD       dwBufferLength;         /* length of data buffer */
+    DWORD       dwBytesRecorded;        /* used for input only */
+    DWORD       dwUser;                 /* for client's use */
+    DWORD       dwFlags;                /* assorted flags (see defines) */
+    DWORD       dwLoops;                /* loop control counter */
+    struct wavehdr_tag FAR *lpNext;     /* reserved for driver */
+    DWORD       reserved;               /* reserved for driver */
+} WAVEHDR;
+typedef WAVEHDR FAR  *LPWAVEHDR;
+
+#define WHDR_DONE       0x00000001  /* done bit */
+#define WHDR_PREPARED   0x00000002  /* set if this header has been prepared */
+#define WHDR_BEGINLOOP  0x00000004  /* loop start block */
+#define WHDR_ENDLOOP    0x00000008  /* loop end block */
+#define WHDR_INQUEUE    0x00000010  /* reserved for driver */
+
+typedef struct {
+    UINT    wMid;                  /* manufacturer ID */
+    UINT    wPid;                  /* product ID */
+    VERSION vDriverVersion;        /* version of the driver */
+    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
+    DWORD   dwFormats;             /* formats supported */
+    UINT    wChannels;             /* number of sources supported */
+    DWORD   dwSupport;             /* functionality supported by driver */
+} WAVEOUTCAPS;
+typedef WAVEOUTCAPS FAR  *LPWAVEOUTCAPS;
+
+#define WAVECAPS_PITCH          0x0001   /* supports pitch control */
+#define WAVECAPS_PLAYBACKRATE   0x0002   /* supports playback rate control */
+#define WAVECAPS_VOLUME         0x0004   /* supports volume control */
+#define WAVECAPS_LRVOLUME       0x0008   /* separate left-right volume control */
+#define WAVECAPS_SYNC           0x0010
+
+typedef struct {
+    UINT    wMid;                    /* manufacturer ID */
+    UINT    wPid;                    /* product ID */
+    VERSION vDriverVersion;          /* version of the driver */
+    char    szPname[MAXPNAMELEN];    /* product name (NULL terminated string) */
+    DWORD   dwFormats;               /* formats supported */
+    UINT    wChannels;               /* number of channels supported */
+} WAVEINCAPS;
+typedef WAVEINCAPS FAR  *LPWAVEINCAPS;
+
+#define WAVE_INVALIDFORMAT     0x00000000       /* invalid format */
+#define WAVE_FORMAT_1M08       0x00000001       /* 11.025 kHz, Mono,   8-bit  */
+#define WAVE_FORMAT_1S08       0x00000002       /* 11.025 kHz, Stereo, 8-bit  */
+#define WAVE_FORMAT_1M16       0x00000004       /* 11.025 kHz, Mono,   16-bit */
+#define WAVE_FORMAT_1S16       0x00000008       /* 11.025 kHz, Stereo, 16-bit */
+#define WAVE_FORMAT_2M08       0x00000010       /* 22.05  kHz, Mono,   8-bit  */
+#define WAVE_FORMAT_2S08       0x00000020       /* 22.05  kHz, Stereo, 8-bit  */
+#define WAVE_FORMAT_2M16       0x00000040       /* 22.05  kHz, Mono,   16-bit */
+#define WAVE_FORMAT_2S16       0x00000080       /* 22.05  kHz, Stereo, 16-bit */
+#define WAVE_FORMAT_4M08       0x00000100       /* 44.1   kHz, Mono,   8-bit  */
+#define WAVE_FORMAT_4S08       0x00000200       /* 44.1   kHz, Stereo, 8-bit  */
+#define WAVE_FORMAT_4M16       0x00000400       /* 44.1   kHz, Mono,   16-bit */
+#define WAVE_FORMAT_4S16       0x00000800       /* 44.1   kHz, Stereo, 16-bit */
+
+/* general format structure common to all formats */
+typedef struct {
+    WORD    wFormatTag;        /* format type */
+    WORD    nChannels;         /* number of channels (i.e. mono, stereo, etc.) */
+    DWORD   nSamplesPerSec;    /* sample rate */
+    DWORD   nAvgBytesPerSec;   /* for buffer estimation */
+    WORD    nBlockAlign;       /* block size of data */
+} WAVEFORMAT;
+typedef WAVEFORMAT FAR  *LPWAVEFORMAT;
+
+#define WAVE_FORMAT_PCM     1
+
+typedef struct {
+    WAVEFORMAT  wf;
+    WORD        wBitsPerSample;
+} PCMWAVEFORMAT;
+typedef PCMWAVEFORMAT FAR  *LPPCMWAVEFORMAT;
+
+UINT WINAPI waveOutGetNumDevs(void);
+UINT WINAPI waveOutGetDevCaps(UINT uDeviceID, WAVEOUTCAPS FAR* lpCaps,
+    UINT uSize);
+UINT WINAPI waveOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume);
+UINT WINAPI waveOutSetVolume(UINT uDeviceID, DWORD dwVolume);
+UINT WINAPI waveOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
+UINT WINAPI waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
+UINT WINAPI waveOutOpen(HWAVEOUT FAR* lphWaveOut, UINT uDeviceID,
+    const WAVEFORMAT FAR* lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
+UINT WINAPI waveOutClose(HWAVEOUT hWaveOut);
+UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut,
+     WAVEHDR FAR* lpWaveOutHdr, UINT uSize);
+UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
+    WAVEHDR FAR* lpWaveOutHdr, UINT uSize);
+UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, WAVEHDR FAR* lpWaveOutHdr,
+    UINT uSize);
+UINT WINAPI waveOutPause(HWAVEOUT hWaveOut);
+UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut);
+UINT WINAPI waveOutReset(HWAVEOUT hWaveOut);
+UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut);
+UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, MMTIME FAR* lpInfo,
+    UINT uSize);
+UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, DWORD FAR* lpdwPitch);
+UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dwPitch);
+UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, DWORD FAR* lpdwRate);
+UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dwRate);
+UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT FAR* lpuDeviceID);
+
+DWORD WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD dw1, DWORD dw2);
+
+UINT WINAPI waveInGetNumDevs(void);
+UINT WINAPI waveInGetDevCaps(UINT uDeviceID, WAVEINCAPS FAR* lpCaps,
+    UINT uSize);
+UINT WINAPI waveInGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
+UINT WINAPI waveInOpen(HWAVEIN FAR* lphWaveIn, UINT uDeviceID,
+    const WAVEFORMAT FAR* lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
+UINT WINAPI waveInClose(HWAVEIN hWaveIn);
+UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize);
+UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize);
+UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize);
+UINT WINAPI waveInStart(HWAVEIN hWaveIn);
+UINT WINAPI waveInStop(HWAVEIN hWaveIn);
+UINT WINAPI waveInReset(HWAVEIN hWaveIn);
+UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, MMTIME FAR* lpInfo,
+    UINT uSize);
+UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT FAR* lpuDeviceID);
+
+DWORD WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD dw1, DWORD dw2);
+
+#define MIDIERR_UNPREPARED    (MIDIERR_BASE + 0)   /* header not prepared */
+#define MIDIERR_STILLPLAYING  (MIDIERR_BASE + 1)   /* still something playing */
+#define MIDIERR_NOMAP         (MIDIERR_BASE + 2)   /* no current map */
+#define MIDIERR_NOTREADY      (MIDIERR_BASE + 3)   /* hardware is still busy */
+#define MIDIERR_NODEVICE      (MIDIERR_BASE + 4)   /* port no longer connected */
+#define MIDIERR_INVALIDSETUP  (MIDIERR_BASE + 5)   /* invalid setup */
+#define MIDIERR_LASTERROR     (MIDIERR_BASE + 5)   /* last error in range */
+
+DECLARE_HANDLE(HMIDI);
+DECLARE_HANDLE(HMIDIIN);
+DECLARE_HANDLE(HMIDIOUT);
+typedef HMIDIIN FAR *LPHMIDIIN;
+typedef HMIDIOUT FAR *LPHMIDIOUT;
+typedef DRVCALLBACK MIDICALLBACK;
+typedef MIDICALLBACK FAR *LPMIDICALLBACK;
+#define MIDIPATCHSIZE   128
+typedef WORD PATCHARRAY[MIDIPATCHSIZE];
+typedef WORD FAR *LPPATCHARRAY;
+typedef WORD KEYARRAY[MIDIPATCHSIZE];
+typedef WORD FAR *LPKEYARRAY;
+
+#define MIM_OPEN        MM_MIM_OPEN
+#define MIM_CLOSE       MM_MIM_CLOSE
+#define MIM_DATA        MM_MIM_DATA
+#define MIM_LONGDATA    MM_MIM_LONGDATA
+#define MIM_ERROR       MM_MIM_ERROR
+#define MIM_LONGERROR   MM_MIM_LONGERROR
+#define MOM_OPEN        MM_MOM_OPEN
+#define MOM_CLOSE       MM_MOM_CLOSE
+#define MOM_DONE        MM_MOM_DONE
+
+#define MIDIMAPPER     (-1)
+#define MIDI_MAPPER    (-1)
+
+/* flags for wFlags parm of 
+	midiOutCachePatches(), 
+	midiOutCacheDrumPatches() */
+#define MIDI_CACHE_ALL      1
+#define MIDI_CACHE_BESTFIT  2
+#define MIDI_CACHE_QUERY    3
+#define MIDI_UNCACHE        4
+
+typedef struct {
+    UINT    wMid;                  /* manufacturer ID */
+    UINT    wPid;                  /* product ID */
+    VERSION vDriverVersion;        /* version of the driver */
+    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
+    UINT    wTechnology;           /* type of device */
+    UINT    wVoices;               /* # of voices (internal synth only) */
+    UINT    wNotes;                /* max # of notes (internal synth only) */
+    UINT    wChannelMask;          /* channels used (internal synth only) */
+    DWORD   dwSupport;             /* functionality supported by driver */
+} MIDIOUTCAPS;
+typedef MIDIOUTCAPS FAR  *LPMIDIOUTCAPS;
+
+#define MOD_MIDIPORT    1  /* output port */
+#define MOD_SYNTH       2  /* generic internal synth */
+#define MOD_SQSYNTH     3  /* square wave internal synth */
+#define MOD_FMSYNTH     4  /* FM internal synth */
+#define MOD_MAPPER      5  /* MIDI mapper */
+
+#define MIDICAPS_VOLUME          0x0001  /* supports volume control */
+#define MIDICAPS_LRVOLUME        0x0002  /* separate left-right volume control */
+#define MIDICAPS_CACHE           0x0004
+
+typedef struct {
+    UINT    wMid;                  /* manufacturer ID */
+    UINT    wPid;                  /* product ID */
+    VERSION vDriverVersion;        /* version of the driver */
+    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
+} MIDIINCAPS;
+typedef MIDIINCAPS FAR  *LPMIDIINCAPS;
+
+typedef struct {
+    LPSTR       lpData;               /* pointer to locked data block */
+    DWORD       dwBufferLength;       /* length of data in data block */
+    DWORD       dwBytesRecorded;      /* used for input only */
+    DWORD       dwUser;               /* for client's use */
+    DWORD       dwFlags;              /* assorted flags (see defines) */
+    struct midihdr_tag FAR *lpNext;   /* reserved for driver */
+    DWORD       reserved;             /* reserved for driver */
+} MIDIHDR;
+typedef MIDIHDR FAR  *LPMIDIHDR;
+
+#define MHDR_DONE       0x00000001       /* done bit */
+#define MHDR_PREPARED   0x00000002       /* set if header prepared */
+#define MHDR_INQUEUE    0x00000004       /* reserved for driver */
+
+UINT WINAPI midiOutGetNumDevs(void);
+UINT WINAPI midiOutGetDevCaps(UINT uDeviceID,
+    MIDIOUTCAPS FAR* lpCaps, UINT uSize);
+UINT WINAPI midiOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume);
+UINT WINAPI midiOutSetVolume(UINT uDeviceID, DWORD dwVolume);
+UINT WINAPI midiOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
+UINT WINAPI midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
+UINT WINAPI midiOutOpen(HMIDIOUT FAR* lphMidiOut, UINT uDeviceID,
+    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
+UINT WINAPI midiOutClose(HMIDIOUT hMidiOut);
+UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut,
+    MIDIHDR FAR* lpMidiOutHdr, UINT uSize);
+UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut,
+    MIDIHDR FAR* lpMidiOutHdr, UINT uSize);
+UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg);
+UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
+    MIDIHDR FAR* lpMidiOutHdr, UINT uSize);
+UINT WINAPI midiOutReset(HMIDIOUT hMidiOut);
+UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut,
+    UINT uBank, WORD FAR* lpwPatchArray, UINT uFlags);
+UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut,
+    UINT uPatch, WORD FAR* lpwKeyArray, UINT uFlags);
+UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT FAR* lpuDeviceID);
+
+DWORD WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage, DWORD dw1, DWORD dw2);
+
+UINT WINAPI midiInGetNumDevs(void);
+UINT WINAPI midiInGetDevCaps(UINT uDeviceID,
+    LPMIDIINCAPS lpCaps, UINT uSize);
+UINT WINAPI midiInGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
+UINT WINAPI midiInOpen(HMIDIIN FAR* lphMidiIn, UINT uDeviceID,
+    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags);
+UINT WINAPI midiInClose(HMIDIIN hMidiIn);
+UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn,
+    MIDIHDR FAR* lpMidiInHdr, UINT uSize);
+UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn,
+    MIDIHDR FAR* lpMidiInHdr, UINT uSize);
+UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn,
+    MIDIHDR FAR* lpMidiInHdr, UINT uSize);
+UINT WINAPI midiInStart(HMIDIIN hMidiIn);
+UINT WINAPI midiInStop(HMIDIIN hMidiIn);
+UINT WINAPI midiInReset(HMIDIIN hMidiIn);
+UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT FAR* lpuDeviceID);
+
+DWORD WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage, DWORD dw1, DWORD dw2);
+
+#define AUX_MAPPER     (-1)
+
+typedef struct {
+    UINT    wMid;                  /* manufacturer ID */
+    UINT    wPid;                  /* product ID */
+    VERSION vDriverVersion;        /* version of the driver */
+    char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
+    UINT    wTechnology;           /* type of device */
+    DWORD   dwSupport;             /* functionality supported by driver */
+} AUXCAPS;
+typedef AUXCAPS FAR  *LPAUXCAPS;
+
+#define AUXCAPS_CDAUDIO    1       /* audio from internal CD-ROM drive */
+#define AUXCAPS_AUXIN      2       /* audio from auxiliary input jacks */
+
+#define AUXCAPS_VOLUME          0x0001  /* supports volume control */
+#define AUXCAPS_LRVOLUME        0x0002  /* separate left-right volume control */
+
+UINT WINAPI auxGetNumDevs(void);
+UINT WINAPI auxGetDevCaps(UINT uDeviceID, AUXCAPS FAR* lpCaps, UINT uSize);
+UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume);
+UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume);
+
+DWORD WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2);
+
+#define TIMERR_NOERROR        (0)                  /* no error */
+#define TIMERR_NOCANDO        (TIMERR_BASE+1)      /* request not completed */
+#define TIMERR_STRUCT         (TIMERR_BASE+33)     /* time struct size */
+
+typedef void (CALLBACK TIMECALLBACK) (UINT uTimerID, UINT uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
+
+typedef TIMECALLBACK FAR *LPTIMECALLBACK;
+
+#define TIME_ONESHOT    0   /* program timer for single event */
+#define TIME_PERIODIC   1   /* program for continuous periodic event */
+
+typedef struct {
+    UINT    wPeriodMin;     /* minimum period supported  */
+    UINT    wPeriodMax;     /* maximum period supported  */
+    } TIMECAPS;
+typedef TIMECAPS FAR  *LPTIMECAPS;
+
+UINT WINAPI timeGetSystemTime(MMTIME FAR* lpTime, UINT uSize);
+DWORD WINAPI timeGetTime(void);
+UINT WINAPI timeSetEvent(UINT uDelay, UINT uResolution,
+    LPTIMECALLBACK lpFunction, DWORD dwUser, UINT uFlags);
+UINT WINAPI timeKillEvent(UINT uTimerID);
+UINT WINAPI timeGetDevCaps(TIMECAPS FAR* lpTimeCaps, UINT uSize);
+UINT WINAPI timeBeginPeriod(UINT uPeriod);
+UINT WINAPI timeEndPeriod(UINT uPeriod);
+
+#define JOYERR_NOERROR        (0)                  /* no error */
+#define JOYERR_PARMS          (JOYERR_BASE+5)      /* bad parameters */
+#define JOYERR_NOCANDO        (JOYERR_BASE+6)      /* request not completed */
+#define JOYERR_UNPLUGGED      (JOYERR_BASE+7)      /* joystick is unplugged */
+
+#define JOY_BUTTON1         0x0001
+#define JOY_BUTTON2         0x0002
+#define JOY_BUTTON3         0x0004
+#define JOY_BUTTON4         0x0008
+#define JOY_BUTTON1CHG      0x0100
+#define JOY_BUTTON2CHG      0x0200
+#define JOY_BUTTON3CHG      0x0400
+#define JOY_BUTTON4CHG      0x0800
+
+#define JOYSTICKID1         0
+#define JOYSTICKID2         1
+
+typedef struct {
+    UINT wMid;                  /* manufacturer ID */
+    UINT wPid;                  /* product ID */
+    char szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
+    UINT wXmin;                 /* minimum x position value */
+    UINT wXmax;                 /* maximum x position value */
+    UINT wYmin;                 /* minimum y position value */
+    UINT wYmax;                 /* maximum y position value */
+    UINT wZmin;                 /* minimum z position value */
+    UINT wZmax;                 /* maximum z position value */
+    UINT wNumButtons;           /* number of buttons */
+    UINT wPeriodMin;            /* minimum message period when captured */
+    UINT wPeriodMax;            /* maximum message period when captured */
+    } JOYCAPS;
+typedef JOYCAPS FAR  *LPJOYCAPS;
+
+typedef struct {
+    UINT wXpos;                 /* x position */
+    UINT wYpos;                 /* y position */
+    UINT wZpos;                 /* z position */
+    UINT wButtons;              /* button states */
+    } JOYINFO;
+typedef JOYINFO FAR  *LPJOYINFO;
+
+UINT WINAPI joyGetDevCaps(UINT uJoyID, JOYCAPS FAR* lpCaps, UINT uSize);
+UINT WINAPI joyGetNumDevs(void);
+UINT WINAPI joyGetPos(UINT uJoyID, JOYINFO FAR* lpInfo);
+UINT WINAPI joyGetThreshold(UINT uJoyID, UINT FAR* lpuThreshold);
+UINT WINAPI joyReleaseCapture(UINT uJoyID);
+UINT WINAPI joySetCapture(HWND hwnd, UINT uJoyID, UINT uPeriod,
+    BOOL bChanged);
+UINT WINAPI joySetThreshold(UINT uJoyID, UINT uThreshold);
+
+#define MMIOERR_BASE            256
+#define MMIOERR_FILENOTFOUND    (MMIOERR_BASE + 1)  /* file not found */
+#define MMIOERR_OUTOFMEMORY     (MMIOERR_BASE + 2)  /* out of memory */
+#define MMIOERR_CANNOTOPEN      (MMIOERR_BASE + 3)  /* cannot open */
+#define MMIOERR_CANNOTCLOSE     (MMIOERR_BASE + 4)  /* cannot close */
+#define MMIOERR_CANNOTREAD      (MMIOERR_BASE + 5)  /* cannot read */
+#define MMIOERR_CANNOTWRITE     (MMIOERR_BASE + 6)  /* cannot write */
+#define MMIOERR_CANNOTSEEK      (MMIOERR_BASE + 7)  /* cannot seek */
+#define MMIOERR_CANNOTEXPAND    (MMIOERR_BASE + 8)  /* cannot expand file */
+#define MMIOERR_CHUNKNOTFOUND   (MMIOERR_BASE + 9)  /* chunk not found */
+#define MMIOERR_UNBUFFERED      (MMIOERR_BASE + 10) /* file is unbuffered */
+
+#define CFSEPCHAR       '+'             /* compound file name separator char. */
+
+typedef DWORD           FOURCC;         /* a four character code */
+DECLARE_HANDLE(HMMIO);                  /* a handle to an open file */
+typedef LRESULT (CALLBACK MMIOPROC)(LPSTR lpmmioinfo, UINT uMessage,
+            LPARAM lParam1, LPARAM lParam2);
+typedef MMIOPROC FAR *LPMMIOPROC;
+
+typedef struct {
+        DWORD           dwFlags;        /* general status flags */
+        FOURCC          fccIOProc;      /* pointer to I/O procedure */
+        LPMMIOPROC      pIOProc;        /* pointer to I/O procedure */
+        UINT            wErrorRet;      /* place for error to be returned */
+        HTASK           htask;          /* alternate local task */
+        /* fields maintained by MMIO functions during buffered I/O */
+        LONG            cchBuffer;      /* size of I/O buffer (or 0L) */
+        HPSTR           pchBuffer;      /* start of I/O buffer (or NULL) */
+        HPSTR           pchNext;        /* pointer to next byte to read/write */
+        HPSTR           pchEndRead;     /* pointer to last valid byte to read */
+        HPSTR           pchEndWrite;    /* pointer to last byte to write */
+        LONG            lBufOffset;     /* disk offset of start of buffer */
+        /* fields maintained by I/O procedure */
+        LONG            lDiskOffset;    /* disk offset of next read or write */
+        DWORD           adwInfo[3];     /* data specific to type of MMIOPROC */
+        /* other fields maintained by MMIO */
+        DWORD           dwReserved1;    /* reserved for MMIO use */
+        DWORD           dwReserved2;    /* reserved for MMIO use */
+        HMMIO           hmmio;          /* handle to open file */
+} MMIOINFO;
+typedef MMIOINFO FAR  *LPMMIOINFO;
+
+typedef struct _MMCKINFO
+{
+        FOURCC          ckid;           /* chunk ID */
+        DWORD           cksize;         /* chunk size */
+        FOURCC          fccType;        /* form type or list type */
+        DWORD           dwDataOffset;   /* offset of data portion of chunk */
+        DWORD           dwFlags;        /* flags used by MMIO functions */
+} MMCKINFO;
+typedef MMCKINFO FAR  *LPMMCKINFO;
+
+#define MMIO_RWMODE     0x00000003      /* open file for reading/writing/both */
+#define MMIO_SHAREMODE  0x00000070      /* file sharing mode number */
+
+#define MMIO_CREATE     0x00001000      /* create new file (or truncate file) */
+#define MMIO_PARSE      0x00000100      /* parse new file returning path */
+#define MMIO_DELETE     0x00000200      /* create new file (or truncate file) */
+#define MMIO_EXIST      0x00004000      /* checks for existence of file */
+#define MMIO_ALLOCBUF   0x00010000      /* mmioOpen() should allocate a buffer */
+#define MMIO_GETTEMP    0x00020000      /* mmioOpen() should retrieve temp name */
+
+#define MMIO_DIRTY      0x10000000      /* I/O buffer is dirty */
+
+#define MMIO_READ       0x00000000      /* open file for reading only */
+#define MMIO_WRITE      0x00000001      /* open file for writing only */
+#define MMIO_READWRITE  0x00000002      /* open file for reading and writing */
+
+#define MMIO_COMPAT     0x00000000      /* compatibility mode */
+#define MMIO_EXCLUSIVE  0x00000010      /* exclusive-access mode */
+#define MMIO_DENYWRITE  0x00000020      /* deny writing to other processes */
+#define MMIO_DENYREAD   0x00000030      /* deny reading to other processes */
+#define MMIO_DENYNONE   0x00000040      /* deny nothing to other processes */
+
+#define MMIO_FHOPEN             0x0010  /* mmioClose: keep file handle open */
+#define MMIO_EMPTYBUF           0x0010  /* mmioFlush: empty the I/O buffer */
+#define MMIO_TOUPPER            0x0010  /* mmioStringToFOURCC: to u-case */
+#define MMIO_INSTALLPROC    0x00010000  /* mmioInstallIOProc: install MMIOProc */
+#define MMIO_GLOBALPROC     0x10000000  /* mmioInstallIOProc: install globally */
+#define MMIO_REMOVEPROC     0x00020000  /* mmioInstallIOProc: remove MMIOProc */
+#define MMIO_FINDPROC       0x00040000  /* mmioInstallIOProc: find an MMIOProc */
+#define MMIO_FINDCHUNK          0x0010  /* mmioDescend: find a chunk by ID */
+#define MMIO_FINDRIFF           0x0020  /* mmioDescend: find a LIST chunk */
+#define MMIO_FINDLIST           0x0040  /* mmioDescend: find a RIFF chunk */
+#define MMIO_CREATERIFF         0x0020  /* mmioCreateChunk: make a LIST chunk */
+#define MMIO_CREATELIST         0x0040  /* mmioCreateChunk: make a RIFF chunk */
+
+#define MMIOM_READ      MMIO_READ       /* read */
+#define MMIOM_WRITE    MMIO_WRITE       /* write */
+#define MMIOM_SEEK              2       /* seek to a new position in file */
+#define MMIOM_OPEN              3       /* open file */
+#define MMIOM_CLOSE             4       /* close file */
+#define MMIOM_WRITEFLUSH        5       /* write and flush */
+
+#define MMIOM_RENAME            6       /* rename specified file */
+
+#define MMIOM_USER         0x8000       /* beginning of user-defined messages */
+
+#define FOURCC_RIFF     mmioFOURCC('R', 'I', 'F', 'F')
+#define FOURCC_LIST     mmioFOURCC('L', 'I', 'S', 'T')
+
+#define FOURCC_DOS      mmioFOURCC('D', 'O', 'S', ' ')
+#define FOURCC_MEM      mmioFOURCC('M', 'E', 'M', ' ')
+
+#define MMIO_DEFAULTBUFFER      8192    /* default buffer size */
+
+#define mmioFOURCC( ch0, ch1, ch2, ch3 )                                \
+                ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |    \
+                ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
+
+FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT uFlags);
+LPMMIOPROC WINAPI mmioInstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
+    DWORD dwFlags);
+HMMIO WINAPI mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo,
+    DWORD dwOpenFlags);
+
+UINT WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
+     MMIOINFO FAR* lpmmioinfo, DWORD dwRenameFlags);
+
+UINT WINAPI mmioClose(HMMIO hmmio, UINT uFlags);
+LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch);
+LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch);
+LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, int iOrigin);
+UINT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags);
+UINT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO FAR* lpmmioinfo, UINT uFlags);
+UINT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer,
+    UINT uFlags);
+UINT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags);
+UINT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags);
+LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
+    LPARAM lParam1, LPARAM lParam2);
+UINT WINAPI mmioDescend(HMMIO hmmio, MMCKINFO FAR* lpck,
+    const MMCKINFO FAR* lpckParent, UINT uFlags);
+UINT WINAPI mmioAscend(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags);
+UINT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags);
+
+typedef UINT (CALLBACK *YIELDPROC) (UINT uDeviceID, DWORD dwYieldData);
+
+DWORD WINAPI mciSendCommand (UINT uDeviceID, UINT uMessage,
+    DWORD dwParam1, DWORD dwParam2);
+DWORD WINAPI mciSendString (LPCSTR lpstrCommand,
+    LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback);
+UINT WINAPI mciGetDeviceID (LPCSTR lpstrName);
+UINT WINAPI mciGetDeviceIDFromElementID (DWORD dwElementID,
+    LPCSTR lpstrType);
+BOOL WINAPI mciGetErrorString (DWORD wError, LPSTR lpstrBuffer,
+    UINT uLength);
+BOOL WINAPI mciSetYieldProc (UINT uDeviceID, YIELDPROC fpYieldProc,
+    DWORD dwYieldData);
+
+HTASK WINAPI mciGetCreatorTask(UINT uDeviceID);
+YIELDPROC WINAPI mciGetYieldProc (UINT uDeviceID, DWORD FAR* lpdwYieldData);
+
+#define MCIERR_INVALID_DEVICE_ID        (MCIERR_BASE + 1)
+#define MCIERR_UNRECOGNIZED_KEYWORD     (MCIERR_BASE + 3)
+#define MCIERR_UNRECOGNIZED_COMMAND     (MCIERR_BASE + 5)
+#define MCIERR_HARDWARE                 (MCIERR_BASE + 6)
+#define MCIERR_INVALID_DEVICE_NAME      (MCIERR_BASE + 7)
+#define MCIERR_OUT_OF_MEMORY            (MCIERR_BASE + 8)
+#define MCIERR_DEVICE_OPEN              (MCIERR_BASE + 9)
+#define MCIERR_CANNOT_LOAD_DRIVER       (MCIERR_BASE + 10)
+#define MCIERR_MISSING_COMMAND_STRING   (MCIERR_BASE + 11)
+#define MCIERR_PARAM_OVERFLOW           (MCIERR_BASE + 12)
+#define MCIERR_MISSING_STRING_ARGUMENT  (MCIERR_BASE + 13)
+#define MCIERR_BAD_INTEGER              (MCIERR_BASE + 14)
+#define MCIERR_PARSER_INTERNAL          (MCIERR_BASE + 15)
+#define MCIERR_DRIVER_INTERNAL          (MCIERR_BASE + 16)
+#define MCIERR_MISSING_PARAMETER        (MCIERR_BASE + 17)
+#define MCIERR_UNSUPPORTED_FUNCTION     (MCIERR_BASE + 18)
+#define MCIERR_FILE_NOT_FOUND           (MCIERR_BASE + 19)
+#define MCIERR_DEVICE_NOT_READY         (MCIERR_BASE + 20)
+#define MCIERR_INTERNAL                 (MCIERR_BASE + 21)
+#define MCIERR_DRIVER                   (MCIERR_BASE + 22)
+#define MCIERR_CANNOT_USE_ALL           (MCIERR_BASE + 23)
+#define MCIERR_MULTIPLE                 (MCIERR_BASE + 24)
+#define MCIERR_EXTENSION_NOT_FOUND      (MCIERR_BASE + 25)
+#define MCIERR_OUTOFRANGE               (MCIERR_BASE + 26)
+#define MCIERR_FLAGS_NOT_COMPATIBLE     (MCIERR_BASE + 28)
+#define MCIERR_FILE_NOT_SAVED           (MCIERR_BASE + 30)
+#define MCIERR_DEVICE_TYPE_REQUIRED     (MCIERR_BASE + 31)
+#define MCIERR_DEVICE_LOCKED            (MCIERR_BASE + 32)
+#define MCIERR_DUPLICATE_ALIAS          (MCIERR_BASE + 33)
+#define MCIERR_BAD_CONSTANT             (MCIERR_BASE + 34)
+#define MCIERR_MUST_USE_SHAREABLE       (MCIERR_BASE + 35)
+#define MCIERR_MISSING_DEVICE_NAME      (MCIERR_BASE + 36)
+#define MCIERR_BAD_TIME_FORMAT          (MCIERR_BASE + 37)
+#define MCIERR_NO_CLOSING_QUOTE         (MCIERR_BASE + 38)
+#define MCIERR_DUPLICATE_FLAGS          (MCIERR_BASE + 39)
+#define MCIERR_INVALID_FILE             (MCIERR_BASE + 40)
+#define MCIERR_NULL_PARAMETER_BLOCK     (MCIERR_BASE + 41)
+#define MCIERR_UNNAMED_RESOURCE         (MCIERR_BASE + 42)
+#define MCIERR_NEW_REQUIRES_ALIAS       (MCIERR_BASE + 43)
+#define MCIERR_NOTIFY_ON_AUTO_OPEN      (MCIERR_BASE + 44)
+#define MCIERR_NO_ELEMENT_ALLOWED       (MCIERR_BASE + 45)
+#define MCIERR_NONAPPLICABLE_FUNCTION   (MCIERR_BASE + 46)
+#define MCIERR_ILLEGAL_FOR_AUTO_OPEN    (MCIERR_BASE + 47)
+#define MCIERR_FILENAME_REQUIRED        (MCIERR_BASE + 48)
+#define MCIERR_EXTRA_CHARACTERS         (MCIERR_BASE + 49)
+#define MCIERR_DEVICE_NOT_INSTALLED     (MCIERR_BASE + 50)
+#define MCIERR_GET_CD                   (MCIERR_BASE + 51)
+#define MCIERR_SET_CD                   (MCIERR_BASE + 52)
+#define MCIERR_SET_DRIVE                (MCIERR_BASE + 53)
+#define MCIERR_DEVICE_LENGTH            (MCIERR_BASE + 54)
+#define MCIERR_DEVICE_ORD_LENGTH        (MCIERR_BASE + 55)
+#define MCIERR_NO_INTEGER               (MCIERR_BASE + 56)
+
+#define MCIERR_WAVE_OUTPUTSINUSE        (MCIERR_BASE + 64)
+#define MCIERR_WAVE_SETOUTPUTINUSE      (MCIERR_BASE + 65)
+#define MCIERR_WAVE_INPUTSINUSE         (MCIERR_BASE + 66)
+#define MCIERR_WAVE_SETINPUTINUSE       (MCIERR_BASE + 67)
+#define MCIERR_WAVE_OUTPUTUNSPECIFIED   (MCIERR_BASE + 68)
+#define MCIERR_WAVE_INPUTUNSPECIFIED    (MCIERR_BASE + 69)
+#define MCIERR_WAVE_OUTPUTSUNSUITABLE   (MCIERR_BASE + 70)
+#define MCIERR_WAVE_SETOUTPUTUNSUITABLE (MCIERR_BASE + 71)
+#define MCIERR_WAVE_INPUTSUNSUITABLE    (MCIERR_BASE + 72)
+#define MCIERR_WAVE_SETINPUTUNSUITABLE  (MCIERR_BASE + 73)
+
+#define MCIERR_SEQ_DIV_INCOMPATIBLE     (MCIERR_BASE + 80)
+#define MCIERR_SEQ_PORT_INUSE           (MCIERR_BASE + 81)
+#define MCIERR_SEQ_PORT_NONEXISTENT     (MCIERR_BASE + 82)
+#define MCIERR_SEQ_PORT_MAPNODEVICE     (MCIERR_BASE + 83)
+#define MCIERR_SEQ_PORT_MISCERROR       (MCIERR_BASE + 84)
+#define MCIERR_SEQ_TIMER                (MCIERR_BASE + 85)
+#define MCIERR_SEQ_PORTUNSPECIFIED      (MCIERR_BASE + 86)
+#define MCIERR_SEQ_NOMIDIPRESENT        (MCIERR_BASE + 87)
+
+#define MCIERR_NO_WINDOW                (MCIERR_BASE + 90)
+#define MCIERR_CREATEWINDOW             (MCIERR_BASE + 91)
+#define MCIERR_FILE_READ                (MCIERR_BASE + 92)
+#define MCIERR_FILE_WRITE               (MCIERR_BASE + 93)
+
+#define MCIERR_CUSTOM_DRIVER_BASE       (MCIERR_BASE + 256)
+
+#define MCI_OPEN                        0x0803
+#define MCI_CLOSE                       0x0804
+#define MCI_ESCAPE                      0x0805
+#define MCI_PLAY                        0x0806
+#define MCI_SEEK                        0x0807
+#define MCI_STOP                        0x0808
+#define MCI_PAUSE                       0x0809
+#define MCI_INFO                        0x080A
+#define MCI_GETDEVCAPS                  0x080B
+#define MCI_SPIN                        0x080C
+#define MCI_SET                         0x080D
+#define MCI_STEP                        0x080E
+#define MCI_RECORD                      0x080F
+#define MCI_SYSINFO                     0x0810
+#define MCI_BREAK                       0x0811
+#define MCI_SOUND                       0x0812
+#define MCI_SAVE                        0x0813
+#define MCI_STATUS                      0x0814
+#define MCI_CUE                         0x0830
+#define MCI_REALIZE                     0x0840
+#define MCI_WINDOW                      0x0841
+#define MCI_PUT                         0x0842
+#define MCI_WHERE                       0x0843
+#define MCI_FREEZE                      0x0844
+#define MCI_UNFREEZE                    0x0845
+#define MCI_LOAD                        0x0850
+#define MCI_CUT                         0x0851
+#define MCI_COPY                        0x0852
+#define MCI_PASTE                       0x0853
+#define MCI_UPDATE                      0x0854
+#define MCI_RESUME                      0x0855
+#define MCI_DELETE                      0x0856
+
+#define MCI_USER_MESSAGES               (0x400 + DRV_MCI_FIRST)
+
+#define MCI_ALL_DEVICE_ID               0xFFFF
+
+#define MCI_DEVTYPE_VCR                 (MCI_STRING_OFFSET + 1)
+#define MCI_DEVTYPE_VIDEODISC           (MCI_STRING_OFFSET + 2)
+#define MCI_DEVTYPE_OVERLAY             (MCI_STRING_OFFSET + 3)
+#define MCI_DEVTYPE_CD_AUDIO            (MCI_STRING_OFFSET + 4)
+#define MCI_DEVTYPE_DAT                 (MCI_STRING_OFFSET + 5)
+#define MCI_DEVTYPE_SCANNER             (MCI_STRING_OFFSET + 6)
+#define MCI_DEVTYPE_ANIMATION           (MCI_STRING_OFFSET + 7)
+#define MCI_DEVTYPE_DIGITAL_VIDEO       (MCI_STRING_OFFSET + 8)
+#define MCI_DEVTYPE_OTHER               (MCI_STRING_OFFSET + 9)
+#define MCI_DEVTYPE_WAVEFORM_AUDIO      (MCI_STRING_OFFSET + 10)
+#define MCI_DEVTYPE_SEQUENCER           (MCI_STRING_OFFSET + 11)
+
+#define MCI_DEVTYPE_FIRST               MCI_DEVTYPE_VCR
+#define MCI_DEVTYPE_LAST                MCI_DEVTYPE_SEQUENCER
+
+#define MCI_MODE_NOT_READY              (MCI_STRING_OFFSET + 12)
+#define MCI_MODE_STOP                   (MCI_STRING_OFFSET + 13)
+#define MCI_MODE_PLAY                   (MCI_STRING_OFFSET + 14)
+#define MCI_MODE_RECORD                 (MCI_STRING_OFFSET + 15)
+#define MCI_MODE_SEEK                   (MCI_STRING_OFFSET + 16)
+#define MCI_MODE_PAUSE                  (MCI_STRING_OFFSET + 17)
+#define MCI_MODE_OPEN                   (MCI_STRING_OFFSET + 18)
+
+#define MCI_FORMAT_MILLISECONDS         0
+#define MCI_FORMAT_HMS                  1
+#define MCI_FORMAT_MSF                  2
+#define MCI_FORMAT_FRAMES               3
+#define MCI_FORMAT_SMPTE_24             4
+#define MCI_FORMAT_SMPTE_25             5
+#define MCI_FORMAT_SMPTE_30             6
+#define MCI_FORMAT_SMPTE_30DROP         7
+#define MCI_FORMAT_BYTES                8
+#define MCI_FORMAT_SAMPLES              9
+#define MCI_FORMAT_TMSF                 10
+
+#define MCI_MSF_MINUTE(msf)             ((BYTE)(msf))
+#define MCI_MSF_SECOND(msf)             ((BYTE)(((WORD)(msf)) >> 8))
+#define MCI_MSF_FRAME(msf)              ((BYTE)((msf)>>16))
+
+#define MCI_MAKE_MSF(m, s, f)           ((DWORD)(((BYTE)(m) | \
+                                                  ((WORD)(s)<<8)) | \
+                                                 (((DWORD)(BYTE)(f))<<16)))
+
+#define MCI_TMSF_TRACK(tmsf)            ((BYTE)(tmsf))
+#define MCI_TMSF_MINUTE(tmsf)           ((BYTE)(((WORD)(tmsf)) >> 8))
+#define MCI_TMSF_SECOND(tmsf)           ((BYTE)((tmsf)>>16))
+#define MCI_TMSF_FRAME(tmsf)            ((BYTE)((tmsf)>>24))
+
+#define MCI_MAKE_TMSF(t, m, s, f)       ((DWORD)(((BYTE)(t) | \
+                                                  ((WORD)(m)<<8)) | \
+                                                 (((DWORD)(BYTE)(s) | \
+                                                   ((WORD)(f)<<8))<<16)))
+
+#define MCI_HMS_HOUR(hms)               ((BYTE)(hms))
+#define MCI_HMS_MINUTE(hms)             ((BYTE)(((WORD)(hms)) >> 8))
+#define MCI_HMS_SECOND(hms)             ((BYTE)((hms)>>16))
+
+#define MCI_MAKE_HMS(h, m, s)           ((DWORD)(((BYTE)(h) | \
+                                                  ((WORD)(m)<<8)) | \
+                                                 (((DWORD)(BYTE)(s))<<16)))
+
+#define MCI_NOTIFY_SUCCESSFUL           0x0001
+#define MCI_NOTIFY_SUPERSEDED           0x0002
+#define MCI_NOTIFY_ABORTED              0x0004
+#define MCI_NOTIFY_FAILURE              0x0008
+
+#define MCI_NOTIFY                      0x00000001L
+#define MCI_WAIT                        0x00000002L
+#define MCI_FROM                        0x00000004L
+#define MCI_TO                          0x00000008L
+#define MCI_TRACK                       0x00000010L
+
+#define MCI_OPEN_SHAREABLE              0x00000100L
+#define MCI_OPEN_ELEMENT                0x00000200L
+#define MCI_OPEN_ALIAS                  0x00000400L
+#define MCI_OPEN_ELEMENT_ID             0x00000800L
+#define MCI_OPEN_TYPE_ID                0x00001000L
+#define MCI_OPEN_TYPE                   0x00002000L
+
+#define MCI_SEEK_TO_START               0x00000100L
+#define MCI_SEEK_TO_END                 0x00000200L
+
+#define MCI_STATUS_ITEM                 0x00000100L
+#define MCI_STATUS_START                0x00000200L
+
+#define MCI_STATUS_LENGTH               0x00000001L
+#define MCI_STATUS_POSITION             0x00000002L
+#define MCI_STATUS_NUMBER_OF_TRACKS     0x00000003L
+#define MCI_STATUS_MODE                 0x00000004L
+#define MCI_STATUS_MEDIA_PRESENT        0x00000005L
+#define MCI_STATUS_TIME_FORMAT          0x00000006L
+#define MCI_STATUS_READY                0x00000007L
+#define MCI_STATUS_CURRENT_TRACK        0x00000008L
+
+#define MCI_INFO_PRODUCT                0x00000100L
+#define MCI_INFO_FILE                   0x00000200L
+
+#define MCI_GETDEVCAPS_ITEM             0x00000100L
+
+#define MCI_GETDEVCAPS_CAN_RECORD       0x00000001L
+#define MCI_GETDEVCAPS_HAS_AUDIO        0x00000002L
+#define MCI_GETDEVCAPS_HAS_VIDEO        0x00000003L
+#define MCI_GETDEVCAPS_DEVICE_TYPE      0x00000004L
+#define MCI_GETDEVCAPS_USES_FILES       0x00000005L
+#define MCI_GETDEVCAPS_COMPOUND_DEVICE  0x00000006L
+#define MCI_GETDEVCAPS_CAN_EJECT        0x00000007L
+#define MCI_GETDEVCAPS_CAN_PLAY         0x00000008L
+#define MCI_GETDEVCAPS_CAN_SAVE         0x00000009L
+
+#define MCI_SYSINFO_QUANTITY            0x00000100L
+#define MCI_SYSINFO_OPEN                0x00000200L
+#define MCI_SYSINFO_NAME                0x00000400L
+#define MCI_SYSINFO_INSTALLNAME         0x00000800L
+
+#define MCI_SET_DOOR_OPEN               0x00000100L
+#define MCI_SET_DOOR_CLOSED             0x00000200L
+#define MCI_SET_TIME_FORMAT             0x00000400L
+#define MCI_SET_AUDIO                   0x00000800L
+#define MCI_SET_VIDEO                   0x00001000L
+#define MCI_SET_ON                      0x00002000L
+#define MCI_SET_OFF                     0x00004000L
+
+#define MCI_SET_AUDIO_ALL               0x00000000L
+#define MCI_SET_AUDIO_LEFT              0x00000001L
+#define MCI_SET_AUDIO_RIGHT             0x00000002L
+
+#define MCI_BREAK_KEY                   0x00000100L
+#define MCI_BREAK_HWND                  0x00000200L
+#define MCI_BREAK_OFF                   0x00000400L
+
+#define MCI_RECORD_INSERT               0x00000100L
+#define MCI_RECORD_OVERWRITE            0x00000200L
+
+#define MCI_SOUND_NAME                  0x00000100L
+
+#define MCI_SAVE_FILE                   0x00000100L
+
+#define MCI_LOAD_FILE                   0x00000100L
+
+typedef struct {
+	DWORD   dwCallback;
+	} MCI_GENERIC_PARMS;
+typedef MCI_GENERIC_PARMS FAR *LPMCI_GENERIC_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	UINT    wDeviceID;
+	UINT    wReserved0;
+	LPCSTR  lpstrDeviceType;
+	LPCSTR  lpstrElementName;
+	LPCSTR  lpstrAlias;
+	} MCI_OPEN_PARMS;
+typedef MCI_OPEN_PARMS FAR *LPMCI_OPEN_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrom;
+	DWORD   dwTo;
+	} MCI_PLAY_PARMS;
+typedef MCI_PLAY_PARMS FAR *LPMCI_PLAY_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwTo;
+	} MCI_SEEK_PARMS;
+typedef MCI_SEEK_PARMS FAR *LPMCI_SEEK_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwReturn;
+	DWORD   dwItem;
+	DWORD   dwTrack;
+	} MCI_STATUS_PARMS;
+typedef MCI_STATUS_PARMS FAR * LPMCI_STATUS_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPSTR   lpstrReturn;
+	DWORD   dwRetSize;
+	} MCI_INFO_PARMS;
+typedef MCI_INFO_PARMS FAR * LPMCI_INFO_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwReturn;
+	DWORD   dwItem;
+	} MCI_GETDEVCAPS_PARMS;
+typedef MCI_GETDEVCAPS_PARMS FAR * LPMCI_GETDEVCAPS_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPSTR   lpstrReturn;
+	DWORD   dwRetSize;
+	DWORD   dwNumber;
+	UINT    wDeviceType;
+	UINT    wReserved0;
+	} MCI_SYSINFO_PARMS;
+typedef MCI_SYSINFO_PARMS FAR * LPMCI_SYSINFO_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwTimeFormat;
+	DWORD   dwAudio;
+	} MCI_SET_PARMS;
+typedef MCI_SET_PARMS FAR *LPMCI_SET_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	int     nVirtKey;
+	UINT    wReserved0;
+	HWND    hwndBreak;
+	UINT    wReserved1;
+	} MCI_BREAK_PARMS;
+typedef MCI_BREAK_PARMS FAR * LPMCI_BREAK_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPCSTR  lpstrSoundName;
+	} MCI_SOUND_PARMS;
+typedef MCI_SOUND_PARMS FAR * LPMCI_SOUND_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPCSTR  lpfilename;
+	} MCI_SAVE_PARMS;
+typedef MCI_SAVE_PARMS FAR * LPMCI_SAVE_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPCSTR  lpfilename;
+	} MCI_LOAD_PARMS;
+typedef MCI_LOAD_PARMS FAR * LPMCI_LOAD_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrom;
+	DWORD   dwTo;
+	} MCI_RECORD_PARMS;
+typedef MCI_RECORD_PARMS FAR *LPMCI_RECORD_PARMS;
+
+#define MCI_VD_MODE_PARK                (MCI_VD_OFFSET + 1)
+
+#define MCI_VD_MEDIA_CLV                (MCI_VD_OFFSET + 2)
+#define MCI_VD_MEDIA_CAV                (MCI_VD_OFFSET + 3)
+#define MCI_VD_MEDIA_OTHER              (MCI_VD_OFFSET + 4)
+
+#define MCI_VD_FORMAT_TRACK             0x4001
+
+#define MCI_VD_PLAY_REVERSE             0x00010000L
+#define MCI_VD_PLAY_FAST                0x00020000L
+#define MCI_VD_PLAY_SPEED               0x00040000L
+#define MCI_VD_PLAY_SCAN                0x00080000L
+#define MCI_VD_PLAY_SLOW                0x00100000L
+
+#define MCI_VD_SEEK_REVERSE             0x00010000L
+
+#define MCI_VD_STATUS_SPEED             0x00004002L
+#define MCI_VD_STATUS_FORWARD           0x00004003L
+#define MCI_VD_STATUS_MEDIA_TYPE        0x00004004L
+#define MCI_VD_STATUS_SIDE              0x00004005L
+#define MCI_VD_STATUS_DISC_SIZE         0x00004006L
+
+#define MCI_VD_GETDEVCAPS_CLV           0x00010000L
+#define MCI_VD_GETDEVCAPS_CAV           0x00020000L
+
+#define MCI_VD_SPIN_UP                  0x00010000L
+#define MCI_VD_SPIN_DOWN                0x00020000L
+
+#define MCI_VD_GETDEVCAPS_CAN_REVERSE   0x00004002L
+#define MCI_VD_GETDEVCAPS_FAST_RATE     0x00004003L
+#define MCI_VD_GETDEVCAPS_SLOW_RATE     0x00004004L
+#define MCI_VD_GETDEVCAPS_NORMAL_RATE   0x00004005L
+
+#define MCI_VD_STEP_FRAMES              0x00010000L
+#define MCI_VD_STEP_REVERSE             0x00020000L
+
+#define MCI_VD_ESCAPE_STRING            0x00000100L
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrom;
+	DWORD   dwTo;
+	DWORD   dwSpeed;
+	} MCI_VD_PLAY_PARMS;
+typedef MCI_VD_PLAY_PARMS FAR *LPMCI_VD_PLAY_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrames;
+	} MCI_VD_STEP_PARMS;
+typedef MCI_VD_STEP_PARMS FAR *LPMCI_VD_STEP_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPCSTR  lpstrCommand;
+	} MCI_VD_ESCAPE_PARMS;
+typedef MCI_VD_ESCAPE_PARMS FAR *LPMCI_VD_ESCAPE_PARMS;
+
+#define MCI_WAVE_OPEN_BUFFER            0x00010000L
+
+#define MCI_WAVE_SET_FORMATTAG          0x00010000L
+#define MCI_WAVE_SET_CHANNELS           0x00020000L
+#define MCI_WAVE_SET_SAMPLESPERSEC      0x00040000L
+#define MCI_WAVE_SET_AVGBYTESPERSEC     0x00080000L
+#define MCI_WAVE_SET_BLOCKALIGN         0x00100000L
+#define MCI_WAVE_SET_BITSPERSAMPLE      0x00200000L
+
+#define MCI_WAVE_INPUT                  0x00400000L
+#define MCI_WAVE_OUTPUT                 0x00800000L
+
+#define MCI_WAVE_STATUS_FORMATTAG       0x00004001L
+#define MCI_WAVE_STATUS_CHANNELS        0x00004002L
+#define MCI_WAVE_STATUS_SAMPLESPERSEC   0x00004003L
+#define MCI_WAVE_STATUS_AVGBYTESPERSEC  0x00004004L
+#define MCI_WAVE_STATUS_BLOCKALIGN      0x00004005L
+#define MCI_WAVE_STATUS_BITSPERSAMPLE   0x00004006L
+#define MCI_WAVE_STATUS_LEVEL           0x00004007L
+
+#define MCI_WAVE_SET_ANYINPUT           0x04000000L
+#define MCI_WAVE_SET_ANYOUTPUT          0x08000000L
+
+#define MCI_WAVE_GETDEVCAPS_INPUTS      0x00004001L
+#define MCI_WAVE_GETDEVCAPS_OUTPUTS     0x00004002L
+
+typedef struct {
+	DWORD   dwCallback;
+	UINT    wDeviceID;
+	UINT    wReserved0;
+	LPCSTR  lpstrDeviceType;
+	LPCSTR  lpstrElementName;
+	LPCSTR  lpstrAlias;
+	DWORD   dwBufferSeconds;
+	} MCI_WAVE_OPEN_PARMS;
+typedef MCI_WAVE_OPEN_PARMS FAR *LPMCI_WAVE_OPEN_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrom;
+	DWORD   dwTo;
+	} MCI_WAVE_DELETE_PARMS;
+typedef MCI_WAVE_DELETE_PARMS FAR *LPMCI_WAVE_DELETE_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwTimeFormat;
+	DWORD   dwAudio;
+	UINT    wInput;
+	UINT    wReserved0;
+	UINT    wOutput;
+	UINT    wReserved1;
+	UINT    wFormatTag;
+	UINT    wReserved2;
+	UINT    nChannels;
+	UINT    wReserved3;
+	DWORD   nSamplesPerSec;
+	DWORD   nAvgBytesPerSec;
+	UINT    nBlockAlign;
+	UINT    wReserved4;
+	UINT    wBitsPerSample;
+	UINT    wReserved5;
+	} MCI_WAVE_SET_PARMS;
+typedef MCI_WAVE_SET_PARMS FAR * LPMCI_WAVE_SET_PARMS;
+
+#define     MCI_SEQ_DIV_PPQN            (0 + MCI_SEQ_OFFSET)
+#define     MCI_SEQ_DIV_SMPTE_24        (1 + MCI_SEQ_OFFSET)
+#define     MCI_SEQ_DIV_SMPTE_25        (2 + MCI_SEQ_OFFSET)
+#define     MCI_SEQ_DIV_SMPTE_30DROP    (3 + MCI_SEQ_OFFSET)
+#define     MCI_SEQ_DIV_SMPTE_30        (4 + MCI_SEQ_OFFSET)
+
+#define     MCI_SEQ_FORMAT_SONGPTR      0x4001
+#define     MCI_SEQ_FILE                0x4002
+#define     MCI_SEQ_MIDI                0x4003
+#define     MCI_SEQ_SMPTE               0x4004
+#define     MCI_SEQ_NONE                65533
+
+#define MCI_SEQ_STATUS_TEMPO            0x00004002L
+#define MCI_SEQ_STATUS_PORT             0x00004003L
+#define MCI_SEQ_STATUS_SLAVE            0x00004007L
+#define MCI_SEQ_STATUS_MASTER           0x00004008L
+#define MCI_SEQ_STATUS_OFFSET           0x00004009L
+#define MCI_SEQ_STATUS_DIVTYPE          0x0000400AL
+
+#define MCI_SEQ_SET_TEMPO               0x00010000L
+#define MCI_SEQ_SET_PORT                0x00020000L
+#define MCI_SEQ_SET_SLAVE               0x00040000L
+#define MCI_SEQ_SET_MASTER              0x00080000L
+#define MCI_SEQ_SET_OFFSET              0x01000000L
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwTimeFormat;
+	DWORD   dwAudio;
+	DWORD   dwTempo;
+	DWORD   dwPort;
+	DWORD   dwSlave;
+	DWORD   dwMaster;
+	DWORD   dwOffset;
+	} MCI_SEQ_SET_PARMS;
+typedef MCI_SEQ_SET_PARMS FAR * LPMCI_SEQ_SET_PARMS;
+
+#define MCI_ANIM_OPEN_WS                0x00010000L
+#define MCI_ANIM_OPEN_PARENT            0x00020000L
+#define MCI_ANIM_OPEN_NOSTATIC          0x00040000L
+
+#define MCI_ANIM_PLAY_SPEED             0x00010000L
+#define MCI_ANIM_PLAY_REVERSE           0x00020000L
+#define MCI_ANIM_PLAY_FAST              0x00040000L
+#define MCI_ANIM_PLAY_SLOW              0x00080000L
+#define MCI_ANIM_PLAY_SCAN              0x00100000L
+
+#define MCI_ANIM_STEP_REVERSE           0x00010000L
+#define MCI_ANIM_STEP_FRAMES            0x00020000L
+
+#define MCI_ANIM_STATUS_SPEED           0x00004001L
+#define MCI_ANIM_STATUS_FORWARD         0x00004002L
+#define MCI_ANIM_STATUS_HWND            0x00004003L
+#define MCI_ANIM_STATUS_HPAL            0x00004004L
+#define MCI_ANIM_STATUS_STRETCH         0x00004005L
+
+#define MCI_ANIM_INFO_TEXT              0x00010000L
+
+#define MCI_ANIM_GETDEVCAPS_CAN_REVERSE 0x00004001L
+#define MCI_ANIM_GETDEVCAPS_FAST_RATE   0x00004002L
+#define MCI_ANIM_GETDEVCAPS_SLOW_RATE   0x00004003L
+#define MCI_ANIM_GETDEVCAPS_NORMAL_RATE 0x00004004L
+#define MCI_ANIM_GETDEVCAPS_PALETTES    0x00004006L
+#define MCI_ANIM_GETDEVCAPS_CAN_STRETCH 0x00004007L
+#define MCI_ANIM_GETDEVCAPS_MAX_WINDOWS 0x00004008L
+
+#define MCI_ANIM_REALIZE_NORM           0x00010000L
+#define MCI_ANIM_REALIZE_BKGD           0x00020000L
+
+#define MCI_ANIM_WINDOW_HWND            0x00010000L
+#define MCI_ANIM_WINDOW_STATE           0x00040000L
+#define MCI_ANIM_WINDOW_TEXT            0x00080000L
+#define MCI_ANIM_WINDOW_ENABLE_STRETCH  0x00100000L
+#define MCI_ANIM_WINDOW_DISABLE_STRETCH 0x00200000L
+
+#define MCI_ANIM_WINDOW_DEFAULT         0x00000000L
+
+#define MCI_ANIM_RECT                   0x00010000L
+#define MCI_ANIM_PUT_SOURCE             0x00020000L
+#define MCI_ANIM_PUT_DESTINATION        0x00040000L
+
+#define MCI_ANIM_WHERE_SOURCE           0x00020000L
+#define MCI_ANIM_WHERE_DESTINATION      0x00040000L
+
+#define MCI_ANIM_UPDATE_HDC             0x00020000L
+
+typedef struct {
+	DWORD   dwCallback;
+	UINT    wDeviceID;
+	UINT    wReserved0;
+	LPCSTR  lpstrDeviceType;
+	LPCSTR  lpstrElementName;
+	LPCSTR  lpstrAlias;
+	DWORD   dwStyle;
+	HWND    hWndParent;
+	UINT    wReserved1;
+	} MCI_ANIM_OPEN_PARMS;
+typedef MCI_ANIM_OPEN_PARMS FAR *LPMCI_ANIM_OPEN_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrom;
+	DWORD   dwTo;
+	DWORD   dwSpeed;
+	} MCI_ANIM_PLAY_PARMS;
+typedef MCI_ANIM_PLAY_PARMS FAR *LPMCI_ANIM_PLAY_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	DWORD   dwFrames;
+	} MCI_ANIM_STEP_PARMS;
+typedef MCI_ANIM_STEP_PARMS FAR *LPMCI_ANIM_STEP_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	HWND    hWnd;
+	UINT    wReserved1;
+	UINT    nCmdShow;
+	UINT    wReserved2;
+	LPCSTR  lpstrText;
+	} MCI_ANIM_WINDOW_PARMS;
+typedef MCI_ANIM_WINDOW_PARMS FAR * LPMCI_ANIM_WINDOW_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+#ifdef MCI_USE_OFFEXT
+	POINT   ptOffset;
+	POINT   ptExtent;
+#else   /* ifdef MCI_USE_OFFEXT */
+	RECT    rc;
+#endif  /* ifdef MCI_USE_OFFEXT */
+	} MCI_ANIM_RECT_PARMS;
+typedef MCI_ANIM_RECT_PARMS FAR * LPMCI_ANIM_RECT_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	RECT    rc;
+	HDC     hDC;
+	} MCI_ANIM_UPDATE_PARMS;
+typedef MCI_ANIM_UPDATE_PARMS FAR * LPMCI_ANIM_UPDATE_PARMS;
+
+#define MCI_OVLY_OPEN_WS                0x00010000L
+#define MCI_OVLY_OPEN_PARENT            0x00020000L
+
+#define MCI_OVLY_STATUS_HWND            0x00004001L
+#define MCI_OVLY_STATUS_STRETCH         0x00004002L
+
+#define MCI_OVLY_INFO_TEXT              0x00010000L
+
+#define MCI_OVLY_GETDEVCAPS_CAN_STRETCH 0x00004001L
+#define MCI_OVLY_GETDEVCAPS_CAN_FREEZE  0x00004002L
+#define MCI_OVLY_GETDEVCAPS_MAX_WINDOWS 0x00004003L
+
+#define MCI_OVLY_WINDOW_HWND            0x00010000L
+#define MCI_OVLY_WINDOW_STATE           0x00040000L
+#define MCI_OVLY_WINDOW_TEXT            0x00080000L
+#define MCI_OVLY_WINDOW_ENABLE_STRETCH  0x00100000L
+#define MCI_OVLY_WINDOW_DISABLE_STRETCH 0x00200000L
+
+#define MCI_OVLY_WINDOW_DEFAULT         0x00000000L
+
+#define MCI_OVLY_RECT                   0x00010000L
+#define MCI_OVLY_PUT_SOURCE             0x00020000L
+#define MCI_OVLY_PUT_DESTINATION        0x00040000L
+#define MCI_OVLY_PUT_FRAME              0x00080000L
+#define MCI_OVLY_PUT_VIDEO              0x00100000L
+
+#define MCI_OVLY_WHERE_SOURCE           0x00020000L
+#define MCI_OVLY_WHERE_DESTINATION      0x00040000L
+#define MCI_OVLY_WHERE_FRAME            0x00080000L
+#define MCI_OVLY_WHERE_VIDEO            0x00100000L
+
+typedef struct {
+	DWORD   dwCallback;
+	UINT    wDeviceID;
+	UINT    wReserved0;
+	LPCSTR  lpstrDeviceType;
+	LPCSTR  lpstrElementName;
+	LPCSTR  lpstrAlias;
+	DWORD   dwStyle;
+	HWND    hWndParent;
+	UINT    wReserved1;
+	} MCI_OVLY_OPEN_PARMS;
+typedef MCI_OVLY_OPEN_PARMS FAR *LPMCI_OVLY_OPEN_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	HWND    hWnd;
+	UINT    wReserved1;
+	UINT    nCmdShow;
+	UINT    wReserved2;
+	LPCSTR  lpstrText;
+	} MCI_OVLY_WINDOW_PARMS;
+typedef MCI_OVLY_WINDOW_PARMS FAR * LPMCI_OVLY_WINDOW_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+#ifdef MCI_USE_OFFEXT
+	POINT   ptOffset;
+	POINT   ptExtent;
+#else   /* ifdef MCI_USE_OFFEXT */
+	RECT    rc;
+#endif  /* ifdef MCI_USE_OFFEXT */
+	} MCI_OVLY_RECT_PARMS;
+typedef MCI_OVLY_RECT_PARMS FAR * LPMCI_OVLY_RECT_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPCSTR  lpfilename;
+	RECT    rc;
+	} MCI_OVLY_SAVE_PARMS;
+typedef MCI_OVLY_SAVE_PARMS FAR * LPMCI_OVLY_SAVE_PARMS;
+
+typedef struct {
+	DWORD   dwCallback;
+	LPCSTR  lpfilename;
+	RECT    rc;
+	} MCI_OVLY_LOAD_PARMS;
+typedef MCI_OVLY_LOAD_PARMS FAR * LPMCI_OVLY_LOAD_PARMS;
+
+
+#endif /* MMSYSTEM_H */
+
+
diff --git a/include/msdos.h b/include/msdos.h
index b06d56c..b394555 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -15,6 +15,7 @@
 };
 
 #define DOSVERSION 0x0330;
+#define MAX_DOS_DRIVES	26
 
 #define EAX context->sc_eax
 #define EBX context->sc_ebx
diff --git a/include/regfunc.h b/include/regfunc.h
index 96f2fef..d68a2d7 100644
--- a/include/regfunc.h
+++ b/include/regfunc.h
@@ -4,19 +4,21 @@
 #ifndef REGFUNC_H
 #define REGFUNC_H
 
+#include "wine.h"
+
 extern unsigned short *Stack16Frame;
 
-#define _CONTEXT &Stack16Frame[12]
-#define _AX	Stack16Frame[34]
-#define _BX	Stack16Frame[28]
-#define _CX	Stack16Frame[32]
-#define _DX	Stack16Frame[30]
-#define _SP	Stack16Frame[26]
-#define _BP	Stack16Frame[24]
-#define _SI	Stack16Frame[22]
-#define _DI	Stack16Frame[20]
-#define _DS	Stack16Frame[18]
-#define _ES	Stack16Frame[16]
+#define _CONTEXT ((struct sigcontext_struct *) &Stack16Frame[12])
+#define _AX	(_CONTEXT->sc_eax)
+#define _BX	(_CONTEXT->sc_ebx)
+#define _CX	(_CONTEXT->sc_ecx)
+#define _DX	(_CONTEXT->sc_edx)
+#define _SP	(_CONTEXT->sc_esp)
+#define _BP	(_CONTEXT->sc_ebp)
+#define _SI	(_CONTEXT->sc_esi)
+#define _DI	(_CONTEXT->sc_edi)
+#define _DS	(_CONTEXT->sc_ds)
+#define _ES	(_CONTEXT->sc_es)
 
 extern void ReturnFromRegisterFunc(void);
 
diff --git a/include/shell.h b/include/shell.h
new file mode 100644
index 0000000..6a30151
--- /dev/null
+++ b/include/shell.h
@@ -0,0 +1,40 @@
+/*
+ * 				Shell Library definitions
+ */
+
+#define ERROR_SUCCESS           0L
+#define ERROR_BADDB             1L
+#define ERROR_BADKEY            2L
+#define ERROR_CANTOPEN          3L
+#define ERROR_CANTREAD          4L
+#define ERROR_CANTWRITE         5L
+#define ERROR_OUTOFMEMORY       6L
+#define ERROR_INVALID_PARAMETER 7L
+#define ERROR_ACCESS_DENIED     8L
+
+#define REG_SZ                  1           /* string type */
+
+#define HKEY_CLASSES_ROOT       1
+
+typedef DWORD HKEY;
+typedef HKEY FAR* LPHKEY;
+
+typedef struct tagKEYSTRUCT {
+	HKEY		hKey;
+	LPSTR		lpSubKey;
+	DWORD		dwType;
+	LPSTR		lpValue;
+	struct tagKEYSTRUCT *lpPrevKey;
+	struct tagKEYSTRUCT *lpNextKey;
+	struct tagKEYSTRUCT *lpSubLvl;
+	} KEYSTRUCT;
+typedef KEYSTRUCT *LPKEYSTRUCT;
+
+#define SE_ERR_SHARE            26
+#define SE_ERR_ASSOCINCOMPLETE  27
+#define SE_ERR_DDETIMEOUT       28
+#define SE_ERR_DDEFAIL          29
+#define SE_ERR_DDEBUSY          30
+#define SE_ERR_NOASSOC          31
+
+
diff --git a/include/syscolor.h b/include/syscolor.h
new file mode 100644
index 0000000..9bd12d5
--- /dev/null
+++ b/include/syscolor.h
@@ -0,0 +1,39 @@
+/*
+ * System color objects
+ *
+ * Copyright  Alexandre Julliard, 1994
+ */
+
+#ifndef SYSCOLOR_H
+#define SYSCOLOR_H
+
+#include "gdi.h"
+
+struct SysColorObjects
+{
+    HBRUSH hbrushScrollbar;        /* COLOR_SCROLLBAR           */
+                                   /* COLOR_BACKGROUND          */
+    HBRUSH hbrushActiveCaption;    /* COLOR_ACTIVECAPTION       */
+    HBRUSH hbrushInactiveCaption;  /* COLOR_INACTIVECAPTION     */
+                                   /* COLOR_MENU                */
+    HBRUSH hbrushWindow;           /* COLOR_WINDOW              */
+    HPEN hpenWindowFrame;          /* COLOR_WINDOWFRAME         */
+                                   /* COLOR_MENUTEXT            */
+    HPEN hpenWindowText;           /* COLOR_WINDOWTEXT          */
+                                   /* COLOR_CAPTIONTEXT         */
+    HBRUSH hbrushActiveBorder;     /* COLOR_ACTIVEBORDER        */
+    HBRUSH hbrushInactiveBorder;   /* COLOR_INACTIVEBORDER      */
+                                   /* COLOR_APPWORKSPACE        */
+                                   /* COLOR_HIGHLIGHT           */
+                                   /* COLOR_HIGHLIGHTTEXT       */
+    HBRUSH hbrushBtnFace;          /* COLOR_BTNFACE             */
+    HBRUSH hbrushBtnShadow;        /* COLOR_BTNSHADOW           */
+                                   /* COLOR_GRAYTEXT            */
+                                   /* COLOR_BTNTEXT             */
+                                   /* COLOR_INACTIVECAPTIONTEXT */
+    HBRUSH hbrushBtnHighlight;     /* COLOR_BTNHIGHLIGHT        */
+};
+
+extern struct SysColorObjects sysColorObjects;
+
+#endif  /* SYSCOLOR_H */
diff --git a/include/task.h b/include/task.h
new file mode 100644
index 0000000..05aba51
--- /dev/null
+++ b/include/task.h
@@ -0,0 +1,27 @@
+/*
+ * Task definitions
+ */
+
+#ifndef TASK_H
+#define TASK_H
+
+typedef struct {
+	HANDLE		hTask;
+	HANDLE		hModule;
+	HINSTANCE	hInst;
+	int			unix_pid;
+	HICON		hIcon;
+	HWND		*lpWndList;
+	void		*lpPrevTask;
+	void		*lpNextTask;
+} TASKENTRY;
+typedef TASKENTRY *LPTASKENTRY;
+
+#define MAXWIN_PER_TASK  256
+
+HANDLE CreateNewTask(HINSTANCE hInst);
+BOOL RemoveWindowFromTask(HTASK hTask, HWND hWnd);
+BOOL AddWindowToTask(HTASK hTask, HWND hWnd);
+
+#endif /* TASK_H */
+
diff --git a/include/user.h b/include/user.h
index 166a707..990428c 100644
--- a/include/user.h
+++ b/include/user.h
@@ -25,8 +25,9 @@
 #define USER_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&USER_Heap,f,size) & 0xffff)
 #define USER_HEAP_REALLOC(handle,size,f) ((int)HEAP_ReAlloc(&USER_Heap, \
 				       USER_HEAP_ADDR(handle),size,f) & 0xffff)
-#define USER_HEAP_ADDR(handle) ((void *)((handle)|((int)USER_Heap&0xffff0000)))
 #define USER_HEAP_FREE(handle) (HEAP_Free(&USER_Heap,USER_HEAP_ADDR(handle)))
+#define USER_HEAP_ADDR(handle) \
+    ((void *)((handle) ? ((handle) | ((int)USER_Heap & 0xffff0000)) : 0))
 
 #endif  /* WINELIB */
 
diff --git a/include/win.h b/include/win.h
index 2631911..0a4a566 100644
--- a/include/win.h
+++ b/include/win.h
@@ -36,19 +36,21 @@
     POINT        ptMaxPos;       /* Maximized window position */
     HANDLE       hmemTaskQ;      /* Task queue global memory handle */
     HRGN         hrgnUpdate;     /* Update region */
+    HWND         hwndPrevActive; /* Previous active top-level window */
     HWND         hwndLastActive; /* Last active popup hwnd */
     FARPROC      lpfnWndProc;    /* Window procedure */
     DWORD        dwStyle;        /* Window style (from CreateWindow) */
     DWORD        dwExStyle;      /* Extended style (from CreateWindowEx) */
     HANDLE       hdce;           /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
-    HMENU        hmenuSystem;    /* System menu */
-    void	 *VScroll;	 /* Vertical ScrollBar Struct Pointer */
-    void	 *HScroll;	 /* Horizontal ScrollBar Struct Pointer */
+    void		 *VScroll;		 /* Vertical ScrollBar Struct Pointer */
+    void		 *HScroll;		 /* Horizontal ScrollBar Struct Pointer */
     WORD         wIDmenu;        /* ID or hmenu (from CreateWindow) */
     HANDLE       hText;          /* Handle of window text */
     WORD         flags;          /* Misc. flags (see below) */
     Window       window;         /* X window */
-    HMENU	 hSysMenu;	 /* window's copy of System Menu */
+    HMENU		 hSysMenu;		 /* window's copy of System Menu */
+    HANDLE       hProp;          /* Handle of Properties List */
+    HTASK 		 hTask;          /* Task Handle of the owner */
     WORD         wExtra[1];      /* Window extra bytes */
 } WND;
 
diff --git a/include/windows.h b/include/windows.h
index 7986183..6d92ddd 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -9,15 +9,24 @@
 typedef unsigned short UINT;
 typedef unsigned short WORD;
 typedef unsigned long DWORD;
-#ifndef _WINMAIN
 typedef unsigned short BOOL;
 typedef unsigned char BYTE;
-#endif
+typedef char *LPSTR;
+typedef const char *LPCSTR;
+typedef char *NPSTR;
+typedef INT *LPINT;
+typedef void *LPVOID;
+typedef long (*FARPROC)();
+typedef FARPROC DLGPROC;
+typedef int CATCHBUF[9];
+typedef int *LPCATCHBUF;
+typedef FARPROC HOOKPROC;
 typedef long LONG;
 typedef UINT WPARAM;
 typedef LONG LPARAM;
 typedef LONG LRESULT;
 typedef WORD HANDLE;
+typedef DWORD HHOOK;
 #define DECLARE_HANDLE(a) typedef HANDLE a;
 
 DECLARE_HANDLE(HTASK);
@@ -37,19 +46,10 @@
 DECLARE_HANDLE(HBRUSH);
 DECLARE_HANDLE(LOCALHANDLE);
 
-typedef char *LPSTR;
-typedef const char *LPCSTR;
-typedef char *NPSTR;
-typedef short *LPINT;
-typedef void *LPVOID;
-typedef long (*FARPROC)();
-typedef FARPROC DLGPROC;
-typedef int CATCHBUF[9];
-typedef int *LPCATCHBUF;
 
 #define TRUE 1
 #define FALSE 0
-#define CW_USEDEFAULT ((short)0x8000)
+#define CW_USEDEFAULT ((INT)0x8000)
 #define FAR
 #define NEAR
 #define PASCAL
@@ -113,15 +113,15 @@
 #endif
 */
 
-typedef struct { short x, y; } POINT;
+typedef struct { INT x, y; } POINT;
 typedef POINT *PPOINT;
 typedef POINT *NPPOINT;
 typedef POINT *LPPOINT;
 
 typedef struct 
 {
-    short cx;
-    short cy;
+    INT cx;
+    INT cy;
 } SIZE, *LPSIZE;
 
 #define MAKEPOINT(l) (*((POINT *)&(l)))
@@ -129,7 +129,7 @@
 #define MAKELPARAM(low, high) ((LONG)(((WORD)(low)) | \
 			      (((DWORD)((WORD)(high))) << 16)))
 
-typedef struct { short left, top, right, bottom; } RECT;
+typedef struct { INT left, top, right, bottom; } RECT;
 typedef RECT *LPRECT;
 typedef RECT *NPRECT;
 typedef RECT *PRECT;
@@ -167,7 +167,7 @@
 #else
 	LONG	(*lpfnWndProc)() WINE_PACKED;
 #endif
-	short	cbClsExtra, cbWndExtra;
+	INT	cbClsExtra, cbWndExtra;
 	HANDLE	hInstance;
 	HICON	hIcon;
 	HCURSOR	hCursor;
@@ -209,10 +209,10 @@
     HINSTANCE hInstance;
     HMENU     hMenu;
     HWND      hwndParent;
-    short     cy;
-    short     cx;
-    short     y;
-    short     x;
+    INT	      cy;
+    INT       cx;
+    INT       y;
+    INT       x;
     LONG      style WINE_PACKED;
     char *    lpszName WINE_PACKED;
     char *    lpszClass WINE_PACKED;
@@ -230,10 +230,10 @@
     LPSTR     szClass;
     LPSTR     szTitle;
     HANDLE    hOwner;
-    short     x;
-    short     y;
-    short     cx;
-    short     cy;
+    INT       x;
+    INT       y;
+    INT       cx;
+    INT	      cy;
     LONG      style WINE_PACKED;
     LONG      lParam WINE_PACKED;
 } MDICREATESTRUCT, *LPMDICREATESTRUCT;
@@ -380,7 +380,118 @@
 #define SC_SCREENSAVE   0xf140
 #define SC_HOTKEY       0xf150
 
-  /* Dialogs */
+/***** Window hooks *****/
+
+  /* Hook values */
+#define WH_JOURNALRECORD    0
+#define WH_JOURNALPLAYBACK  1
+#define WH_KEYBOARD	    2
+#define WH_GETMESSAGE	    3
+#define WH_CALLWNDPROC	    4
+#define WH_CBT		    5
+#define WH_SYSMSGFILTER	    6
+#define WH_MOUSE	    7
+#define WH_HARDWARE	    8
+#define WH_DEBUG	    9
+#define WH_SHELL           10
+#define WH_MSGFILTER	    (-1)
+
+  /* Hook action codes */
+#define HC_ACTION           0
+#define HC_GETNEXT          1
+#define HC_SKIP             2
+#define HC_NOREMOVE         3
+#define HC_NOREM            HC_NOREMOVE
+#define HC_SYSMODALON       4
+#define HC_SYSMODALOFF      5
+
+  /* CallMsgFilter() values */
+#define MSGF_DIALOGBOX      0
+#define MSGF_MENU           2
+#define MSGF_MOVE           3
+#define MSGF_SIZE           4
+#define MSGF_SCROLLBAR      5
+#define MSGF_NEXTWINDOW     6
+#define MSGF_MAINLOOP       8
+#define MSGF_USER        4096
+
+  /* Journalling hook values */
+#define HC_GETNEXT	    1
+#define HC_SKIP 	    2
+#define HC_NOREMOVE	    3
+#define HC_NOREM	    HC_NOREMOVE
+#define HC_SYSMODALON       4
+#define HC_SYSMODALOFF	    5
+
+  /* Journalling hook structure */
+typedef struct tagEVENTMSG
+{
+    UINT    message;
+    UINT    paramL;
+    UINT    paramH;
+    DWORD   time WINE_PACKED;
+} EVENTMSG, *LPEVENTMSG;
+
+  /* Mouse hook structure */
+typedef struct tagMOUSEHOOKSTRUCT
+{
+    POINT   pt;
+    HWND    hwnd;
+    WORD    wHitTestCode;
+    DWORD   dwExtraInfo;
+} MOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT;
+
+  /* Hardware hook structure */
+typedef struct tagHARDWAREHOOKSTRUCT
+{
+    HWND    hWnd;
+    UINT    wMessage;
+    WPARAM  wParam;
+    LPARAM  lParam WINE_PACKED;
+} HARDWAREHOOKSTRUCT;
+
+  /* CBT hook values */
+#define HCBT_MOVESIZE	    0
+#define HCBT_MINMAX	    1
+#define HCBT_QS 	    2
+#define HCBT_CREATEWND	    3
+#define HCBT_DESTROYWND	    4
+#define HCBT_ACTIVATE	    5
+#define HCBT_CLICKSKIPPED   6
+#define HCBT_KEYSKIPPED     7
+#define HCBT_SYSCOMMAND	    8
+#define HCBT_SETFOCUS	    9
+
+  /* CBT hook structures */
+typedef struct tagCBT_CREATEWND
+{
+    CREATESTRUCT *lpcs;
+    HWND          hwndInsertAfter;
+} CBT_CREATEWND, *LPCBT_CREATEWND;
+
+typedef struct tagCBTACTIVATESTRUCT
+{
+    BOOL    fMouse;
+    HWND    hWndActive;
+} CBTACTIVATESTRUCT;
+
+  /* Shell hook values */
+#define HSHELL_WINDOWCREATED       1
+#define HSHELL_WINDOWDESTROYED     2
+#define HSHELL_ACTIVATESHELLWINDOW 3
+
+  /* Debug hook structure */
+typedef struct tagDEBUGHOOKINFO
+{
+    HANDLE	hModuleHook;
+    LPARAM	reserved WINE_PACKED;
+    LPARAM	lParam WINE_PACKED;
+    WPARAM	wParam;
+    short       code;
+} DEBUGHOOKINFO, *LPDEBUGHOOKINFO;
+
+
+/***** Dialogs *****/
 
   /* cbWndExtra bytes for dialog class */
 #define DLGWINDOWEXTRA      30
@@ -529,10 +640,10 @@
 
 typedef struct tagBITMAP
 {
-    short  bmType;
-    short  bmWidth;
-    short  bmHeight;
-    short  bmWidthBytes;
+    INT  bmType;
+    INT  bmWidth;
+    INT  bmHeight;
+    INT  bmWidthBytes;
     BYTE   bmPlanes;
     BYTE   bmBitsPixel;
     void * bmBits WINE_PACKED;
@@ -548,7 +659,7 @@
 { 
     WORD       lbStyle; 
     COLORREF   lbColor WINE_PACKED;
-    short      lbHatch; 
+    INT      lbHatch; 
 } LOGBRUSH, *PLOGBRUSH, *NPLOGBRUSH, *LPLOGBRUSH;
 
   /* Brush styles */
@@ -573,7 +684,7 @@
 #define LF_FACESIZE 32
 typedef struct tagLOGFONT
 {
-    short lfHeight, lfWidth, lfEscapement, lfOrientation, lfWeight;
+    INT lfHeight, lfWidth, lfEscapement, lfOrientation, lfWeight;
     BYTE lfItalic, lfUnderline, lfStrikeOut, lfCharSet;
     BYTE lfOutPrecision, lfClipPrecision, lfQuality, lfPitchAndFamily;
     BYTE lfFaceName[LF_FACESIZE] WINE_PACKED;
@@ -640,14 +751,14 @@
 
 typedef struct tagTEXTMETRIC
 {
-    short     tmHeight;
-    short     tmAscent;
-    short     tmDescent;
-    short     tmInternalLeading;
-    short     tmExternalLeading;
-    short     tmAveCharWidth;
-    short     tmMaxCharWidth;
-    short     tmWeight;
+    INT     tmHeight;
+    INT     tmAscent;
+    INT     tmDescent;
+    INT     tmInternalLeading;
+    INT     tmExternalLeading;
+    INT     tmAveCharWidth;
+    INT     tmMaxCharWidth;
+    INT     tmWeight;
     BYTE      tmItalic;
     BYTE      tmUnderlined;
     BYTE      tmStruckOut;
@@ -657,9 +768,9 @@
     BYTE      tmBreakChar;
     BYTE      tmPitchAndFamily;
     BYTE      tmCharSet;
-    short     tmOverhang;
-    short     tmDigitizedAspectX;
-    short     tmDigitizedAspectY;
+    INT     tmOverhang;
+    INT     tmDigitizedAspectX;
+    INT     tmDigitizedAspectY;
 } TEXTMETRIC, *PTEXTMETRIC, *NPTEXTMETRIC, *LPTEXTMETRIC;
 
   /* tmPitchAndFamily values */
@@ -966,10 +1077,10 @@
 typedef struct tagBITMAPCOREHEADER
 {
     unsigned long bcSize;
-    unsigned short bcWidth;
-    unsigned short bcHeight;
-    unsigned short bcPlanes;
-    unsigned short bcBitCount;
+    UINT bcWidth;
+    UINT bcHeight;
+    UINT bcPlanes;
+    UINT bcBitCount;
 } BITMAPCOREHEADER;
 
 #define DIB_RGB_COLORS   0
@@ -2214,9 +2325,9 @@
 Fa(BOOL,TranslateMessage,LPMSG,a)
 Fa(void,PostQuitMessage,int,a)
 Fa(BOOL,SetMessageQueue,int,a)
-Fa(int,_lclose,int,a)
-Fb(int,_lopen,LPSTR,a,int,b)
-Fa(int,lstrlen,LPCSTR,a)
+Fa(INT,_lclose,INT,a)
+Fb(INT,_lopen,LPSTR,a,INT,b)
+Fa(INT,lstrlen,LPCSTR,a)
 Fa(LONG,DispatchMessage,LPMSG,msg)
 Fa(void,UpdateWindow,HWND,a)
 Fa(ATOM,AddAtom,LPCSTR,a)
@@ -2257,6 +2368,7 @@
 Fa(BOOL,SetDeskWallPaper,LPSTR,a)
 Fa(BOOL,SetErrorMode,WORD,a)
 Fa(BOOL,SwapMouseButton,BOOL,a)
+Fa(BOOL,UnhookWindowsHookEx,HHOOK,a)
 Fa(BOOL,UnrealizeObject,HBRUSH,a)
 Fa(BYTE,GetTempDrive,BYTE,a)
 Fa(DWORD,GetAspectRatioFilter,HDC,a)
@@ -2351,7 +2463,7 @@
 Fa(WORD,ArrangeIconicWindows,HWND,a)
 Fa(WORD,EnumClipboardFormats,WORD,a)
 Fa(WORD,FreeSelector,WORD,a)
-Fa(WORD,GetDriveType,int,a)
+Fa(WORD,GetDriveType,INT,a)
 Fa(WORD,GetMenuItemCount,HMENU,a)
 Fa(WORD,GetTaskQueue,HANDLE,a)
 Fa(WORD,GetTextAlign,HDC,a)
@@ -2423,14 +2535,14 @@
 Fb(HDC,BeginPaint,HWND,a,LPPAINTSTRUCT,b) 
 Fb(LPSTR,lstrcat,LPSTR,a,LPCSTR,b )
 Fb(LPSTR,lstrcpy,LPSTR,a,LPCSTR,b )
-Fb(int,_lcreat,LPSTR,a,int,b)
-Fb(int,lstrcmp,LPCSTR,a,LPCSTR,b )
-Fb(int,lstrcmpi,LPCSTR,a,LPCSTR,b )
+Fb(INT,_lcreat,LPSTR,a,INT,b)
+Fb(INT,lstrcmp,LPCSTR,a,LPCSTR,b )
+Fb(INT,lstrcmpi,LPCSTR,a,LPCSTR,b )
 Fb(void,EndPaint,HWND,a,LPPAINTSTRUCT,b)
 Fb(void,GetClientRect,HWND,a,LPRECT,b)
 Fb(void,SetDCState,HDC,a,HDC,b)
 Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b)
-Fb(BOOL,CallMsgFilter,LPMSG,a,int,b)
+Fb(BOOL,CallMsgFilter,LPMSG,a,short,b)
 Fb(BOOL,ChangeClipboardChain,HWND,a,HWND,b)
 Fb(BOOL,EnableWindow,HWND,a,BOOL,b)
 Fb(BOOL,EnumWindows,FARPROC,a,LONG,b)
@@ -2454,14 +2566,14 @@
 Fb(BOOL,SetConvertParams,int,a,int,b)
 Fb(BOOL,SetMenu,HWND,a,HMENU,b)
 Fb(BOOL,TranslateMDISysAccel,HWND,a,LPMSG,b)
-Fb(BOOL,UnhookWindowsHook,int,a,FARPROC,b)
+Fb(BOOL,UnhookWindowsHook,short,a,HHOOK,b)
 Fb(DWORD,GetNearestColor,HDC,a,DWORD,b)
 Fb(DWORD,SetBkColor,HDC,a,COLORREF,b)
 Fb(DWORD,SetMapperFlags,HDC,a,DWORD,b)
 Fb(DWORD,SetTextColor,HDC,a,DWORD,b)
 Fb(FARPROC,GetProcAddress,HANDLE,a,LPSTR,b)
 Fb(FARPROC,MakeProcInstance,FARPROC,a,HANDLE,b)
-Fb(FARPROC,SetWindowsHook,int,a,FARPROC,b)
+Fb(HHOOK,SetWindowsHook,short,a,HOOKPROC,b)
 Fb(HANDLE,CopyMetaFile,HANDLE,a,LPSTR,b)
 Fb(HANDLE,GetProp,HWND,a,LPSTR,b)
 #ifndef GLOBAL_SOURCE
@@ -2524,7 +2636,7 @@
 Fb(WORD,SizeofResource,HANDLE,a,HANDLE,b)
 Fb(WORD,WinExec,LPSTR,a,WORD,b)
 Fb(int,AccessResource,HANDLE,a,HANDLE,b)
-Fb(int,AnsiToOem,LPSTR,a,LPSTR,b)
+Fb(INT,AnsiToOem,LPSTR,a,LPSTR,b)
 Fb(int,BuildCommDCB,LPSTR,a,DCB*,b)
 Fb(int,ConvertRequest,HWND,a,LPKANJISTRUCT,b)
 Fb(void,CopyRect,LPRECT,a,LPRECT,b)
@@ -2567,9 +2679,9 @@
 Fb(void,ValidateRgn,HWND,a,HRGN,b)
 Fc(BOOL,LineTo,HDC,a,short,b,short,c)
 Fc(WORD,GetInternalWindowPos,HWND,a,LPRECT,b,LPPOINT,c)
-Fc(LONG,_llseek,int,a,long,b,int,c)
-Fc(WORD,_lread,int,a,LPSTR,b,int,c)
-Fc(WORD,_lwrite,int,a,LPSTR,b,int,c)
+Fc(LONG,_llseek,INT,a,LONG,b,INT,c)
+Fc(WORD,_lread,INT,a,LPSTR,b,INT,c)
+Fc(WORD,_lwrite,INT,a,LPSTR,b,INT,c)
 Fc(int,FillRect,HDC,a,LPRECT,b,HBRUSH,c)
 Fc(DWORD,MoveTo,HDC,a,short,b,short,c)
 Fc(BOOL,CheckMenuItem,HMENU,a,WORD,b,WORD,c)
@@ -2645,7 +2757,7 @@
 Fc(int,OffsetClipRgn,HDC,a,short,b,short,c)
 Fc(int,OffsetRgn,HRGN,a,short,b,short,c)
 Fc(int,OpenComm,LPSTR,a,WORD,b,WORD,c)
-Fc(int,OpenFile,LPSTR,a,LPOFSTRUCT,b,WORD,c)
+Fc(INT,OpenFile,LPSTR,a,LPOFSTRUCT,b,WORD,c)
 Fc(int,ReadComm,int,a,LPSTR,b,int,c)
 Fc(int,SetEnvironment,LPSTR,a,LPSTR,b,WORD,c)
 Fc(int,SetVoiceEnvelope,int,a,int,b,int,c)
@@ -2655,12 +2767,12 @@
 Fc(int,wvsprintf,LPSTR,a,LPSTR,b,LPSTR,c)
 Fc(short,SetTextJustification,HDC,a,short,b,short,c)
 Fc(void,AdjustWindowRect,LPRECT,a,DWORD,b,BOOL,c)
-Fc(void,AnsiToOemBuff,LPSTR,a,LPSTR,b,int,c)
+Fc(void,AnsiToOemBuff,LPSTR,a,LPSTR,b,INT,c)
 Fc(void,CheckDlgButton,HWND,a,WORD,b,WORD,c)
 Fc(void,InflateRect,LPRECT,a,short,b,short,c)
 Fc(void,InvalidateRect,HWND,a,LPRECT,b,BOOL,c)
 Fc(void,InvalidateRgn,HWND,a,HRGN,b,BOOL,c)
-Fc(void,OemToAnsiBuff,LPSTR,a,LPSTR,b,int,c)
+Fc(void,OemToAnsiBuff,LPSTR,a,LPSTR,b,INT,c)
 Fc(void,OffsetRect,LPRECT,a,short,b,short,c)
 Fc(void,SetDlgItemText,HWND,a,WORD,b,LPSTR,c)
 Fc(void,SetSysColors,int,a,LPINT,b,COLORREF*,c)
@@ -2683,10 +2795,12 @@
 Fd(BOOL,SetBitmapDimensionEx,HBITMAP,a,short,b,short,c,LPSIZE,d)
 Fd(BOOL,WinHelp,HWND,hwndMain,LPSTR,lpszHelp,WORD,usCommand,DWORD,ulData)
 Fd(BOOL,WritePrivateProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d)
-Fd(DWORD,DefHookProc,int,a,WORD,b,DWORD,c,FARPROC FAR*,d)
+Fd(DWORD,DefHookProc,short,a,WORD,b,DWORD,c,HHOOK FAR*,d)
+Fd(DWORD,CallNextHookEx,HHOOK,a,short,b,WPARAM,c,LPARAM,d)
 Fd(COLORREF,SetPixel,HDC,a,short,b,short,c,COLORREF,d)
 Fd(HDC,CreateDC,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d)
 Fd(HDC,CreateIC,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d)
+Fd(HHOOK,SetWindowsHookEx,short,a,HOOKPROC,b,HINSTANCE,c,HTASK,d)
 Fd(HRGN,CreateEllipticRgn,short,a,short,b,short,c,short,d)
 Fd(HRGN,CreatePolyPolygonRgn,LPPOINT,a,LPINT,b,short,c,short,d)
 Fd(HRGN,CreateRectRgn,short,a,short,b,short,c,short,d)
@@ -2713,7 +2827,7 @@
 Fd(int,EnumFonts,HDC,a,LPSTR,b,FARPROC,c,LPSTR,d)
 Fd(int,EnumObjects,HDC,a,int,b,FARPROC,c,LPSTR,d)
 Fd(int,GetDlgItemText,HWND,a,WORD,b,LPSTR,c,WORD,d)
-Fd(int,GetTempFileName,BYTE,a,LPCSTR,b,UINT,c,LPSTR,d)
+Fd(INT,GetTempFileName,BYTE,a,LPCSTR,b,UINT,c,LPSTR,d)
 Fd(int,LoadString,HANDLE,a,WORD,b,LPSTR,c,int,d)
 Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d)
 Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d)
@@ -2789,7 +2903,7 @@
 Fi(BOOL,Arc,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
 Fi(BOOL,Chord,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
 Fi(BOOL,BitBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,DWORD,i)
-Fi(BOOL,GrayString,HDC,a,HBRUSH,b,FARPROC,c,DWORD,d,int,e,int,f,int,g,int,h,int,i)
+Fi(BOOL,GrayString,HDC,a,HBRUSH,b,FARPROC,gsprc,LPARAM,lParam,INT,cch,INT,x,INT,y,INT,cx,INT,cy)
 Fi(BOOL,Pie,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
 Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,short,x,short,y,short,w,short,h,HWND,d,HMENU,e,,HANDLE i,LPSTR,g)
 Fk(BOOL,StretchBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,short,i,short,j,DWORD,k)
diff --git a/include/wine.h b/include/wine.h
index 28cda57..69505e6 100644
--- a/include/wine.h
+++ b/include/wine.h
@@ -32,7 +32,8 @@
 
 extern struct  w_files * wine_files;
 
-#define MAX_DOS_DRIVES	26
+extern char *WineIniFileName(void);
+extern char *WinIniFileName(void);
 
 #define WINE_INI WineIniFileName()
 #define WIN_INI WinIniFileName()
diff --git a/include/winsock.h b/include/winsock.h
index c36be06..3429f4a 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -79,7 +79,9 @@
  * Maximum queue length specifiable by listen.
  */
 #define SOMAXCONN       5
+
 #define MSG_DONTROUTE   0x4             /* send without using routing tables */
+
 #define MSG_MAXIOVLEN   16
 
 /*
@@ -188,51 +190,6 @@
 /* no address, look for MX record */
 #define WSANO_ADDRESS           WSANO_DATA
 
-/*
- * Windows Sockets errors redefined as regular Berkeley error constants
-
-	* AAARGH! *
-
-#define EWOULDBLOCK             WSAEWOULDBLOCK
-#define EINPROGRESS             WSAEINPROGRESS
-#define EALREADY                WSAEALREADY
-#define ENOTSOCK                WSAENOTSOCK
-#define EDESTADDRREQ            WSAEDESTADDRREQ
-#define EMSGSIZE                WSAEMSGSIZE
-#define EPROTOTYPE              WSAEPROTOTYPE
-#define ENOPROTOOPT             WSAENOPROTOOPT
-#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
-#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
-#define EOPNOTSUPP              WSAEOPNOTSUPP
-#define EPFNOSUPPORT            WSAEPFNOSUPPORT
-#define EAFNOSUPPORT            WSAEAFNOSUPPORT
-#define EADDRINUSE              WSAEADDRINUSE
-#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
-#define ENETDOWN                WSAENETDOWN
-#define ENETUNREACH             WSAENETUNREACH
-#define ENETRESET               WSAENETRESET
-#define ECONNABORTED            WSAECONNABORTED
-#define ECONNRESET              WSAECONNRESET
-#define ENOBUFS                 WSAENOBUFS
-#define EISCONN                 WSAEISCONN
-#define ENOTCONN                WSAENOTCONN
-#define ESHUTDOWN               WSAESHUTDOWN
-#define ETOOMANYREFS            WSAETOOMANYREFS
-#define ETIMEDOUT               WSAETIMEDOUT
-#define ECONNREFUSED            WSAECONNREFUSED
-#define ELOOP                   WSAELOOP
-#define ENAMETOOLONG            WSAENAMETOOLONG
-#define EHOSTDOWN               WSAEHOSTDOWN
-#define EHOSTUNREACH            WSAEHOSTUNREACH
-#define ENOTEMPTY               WSAENOTEMPTY
-#define EPROCLIM                WSAEPROCLIM
-#define EUSERS                  WSAEUSERS
-#define EDQUOT                  WSAEDQUOT
-#define ESTALE                  WSAESTALE
-#define EREMOTE                 WSAEREMOTE
-
-*/
-
 /* Socket function prototypes */
 
 #ifdef __cplusplus
@@ -241,51 +198,50 @@
 
 /* Microsoft Windows Extension function prototypes */
 
-int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
+INT PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
 
-int PASCAL FAR WSACleanup(void);
+INT PASCAL FAR WSACleanup(void);
 
-void PASCAL FAR WSASetLastError(int iError);
+void PASCAL FAR WSASetLastError(INT iError);
 
-int PASCAL FAR WSAGetLastError(void);
+INT PASCAL FAR WSAGetLastError(void);
 
 BOOL PASCAL FAR WSAIsBlocking(void);
 
-int PASCAL FAR WSAUnhookBlockingHook(void);
+INT PASCAL FAR WSAUnhookBlockingHook(void);
 
 FARPROC PASCAL FAR WSASetBlockingHook(FARPROC lpBlockFunc);
 
-int PASCAL FAR WSACancelBlockingCall(void);
+INT PASCAL FAR WSACancelBlockingCall(void);
 
 HANDLE PASCAL FAR WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
-                                        const char FAR * name, 
-                                        const char FAR * proto,
-                                        char FAR * buf, int buflen);
+                                        const char FAR *name, 
+                                        const char FAR *proto,
+                                        char FAR *buf, INT buflen);
 
-HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
-                                        const char FAR * proto, char FAR * buf,
-                                        int buflen);
+HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port,
+                                        const char FAR *proto, char FAR *buf,
+                                        INT buflen);
 
 HANDLE PASCAL FAR WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
-                                         const char FAR * name, char FAR * buf,
-                                         int buflen);
+                                         const char FAR *name, char FAR *buf,
+                                         INT buflen);
 
 HANDLE PASCAL FAR WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
-                                           int number, char FAR * buf,
-                                           int buflen);
+                                           INT number, char FAR *buf,
+                                           INT buflen);
 
 HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
-                                        const char FAR * name, char FAR * buf,
-                                        int buflen);
+                                        const char FAR *name, char FAR *buf,
+                                        INT buflen);
 
 HANDLE PASCAL FAR WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
-                                        const char FAR * addr, int len, int type,
-                                        const char FAR * buf, int buflen);
+                                        const char FAR *addr, INT len, INT type,
+                                        char FAR *buf, INT buflen);
 
-int PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);
+INT PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);
 
-int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
-                               long lEvent);
+INT PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent);
 
 #ifdef __cplusplus
 }
diff --git a/loader/Imakefile b/loader/Imakefile
index df53854..68297d2 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -10,6 +10,7 @@
 	signal.c \
 	library.c \
 	resource.c \
+	task.c \
 	wine.c
 
 OBJS = $(SRCS:.c=.o)
diff --git a/loader/library.c b/loader/library.c
index 39ea0bb..4e60f1d 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -1,3 +1,8 @@
+/*
+ *        Modules & Libraries functions
+ */
+static char Copyright[] = "Copyright  Martin Ayotte, 1994";
+
 #ifndef WINELIB
 #include <stdio.h>
 #include <stdlib.h>
@@ -10,30 +15,25 @@
 #include "windows.h"
 #include "wine.h"
 #include "dlls.h"
+#include "task.h"
 
-typedef struct module_table_entry
-{
+typedef struct {
+	LPSTR		ModuleName;
+	LPSTR		FileName;
+	WORD		Count;
+	HANDLE		hModule;
 	HINSTANCE	hInst;
-	LPSTR		name;
-	WORD		count;
+	void		*lpPrevModule;
+	void		*lpNextModule;
 } MODULEENTRY;
+typedef MODULEENTRY *LPMODULEENTRY;
+
+static LPMODULEENTRY lpModList = NULL;
 
 extern struct  w_files * wine_files;
-
 #define N_BUILTINS	10
-
 extern struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS];
 
-/**********************************************************************
- *				GetCurrentTask	[KERNEL.36]
- */
-HTASK GetCurrentTask()
-{
-    int pid = getpid();
-    printf("GetCurrentTask() returned %d !\n", pid);
-    return pid;
-}
-
 
 /**********************************************************************
  *				GetModuleHandle	[KERNEL.47]
@@ -69,11 +69,11 @@
  */
 int GetModuleUsage(HANDLE hModule)
 {
-    struct w_files *w;
-    printf("GetModuleUsage(%04X);\n", hModule);
-    w = GetFileInfo(hModule);
-/*    return w->Usage; */
-    return 1;
+	struct w_files *w;
+	printf("GetModuleUsage(%04X);\n", hModule);
+	w = GetFileInfo(hModule);
+/*	return w->Usage; */
+	return 1;
 }
 
 
@@ -100,10 +100,44 @@
 HANDLE LoadLibrary(LPSTR libname)
 {
     HANDLE hModule;
+	LPMODULEENTRY lpMod = lpModList;
+	LPMODULEENTRY lpNewMod;
     printf("LoadLibrary '%s'\n", libname);
-    hModule = LoadImage(libname, DLL);
-    printf("LoadLibrary returned hModule=%04X\n", hModule);
-    return hModule;
+	if (lpMod != NULL) {
+		while (TRUE) {
+			if (strcmp(libname, lpMod->FileName) == 0) {
+				lpMod->Count++;
+			    printf("LoadLibrary // already loaded hInst=%04X\n", lpMod->hInst);
+				return lpMod->hInst;
+				}
+			if (lpMod->lpNextModule == NULL) break;
+			lpMod = lpMod->lpNextModule;
+			}
+		}
+	hModule = GlobalAlloc(GMEM_MOVEABLE, sizeof(MODULEENTRY));
+	lpNewMod = (LPMODULEENTRY) GlobalLock(hModule);	
+#ifdef DEBUG_LIBRARY
+    printf("LoadLibrary // creating new module entry %08X\n", lpNewMod);
+#endif
+	if (lpNewMod == NULL) return 0;
+	if (lpModList == NULL) {
+		lpModList = lpNewMod;
+		lpNewMod->lpPrevModule = NULL;
+		}
+	else {
+		lpMod->lpNextModule = lpNewMod;
+		lpNewMod->lpPrevModule = lpMod;
+		}
+	lpNewMod->lpNextModule = NULL;
+	lpNewMod->hModule = hModule;
+	lpNewMod->ModuleName = NULL;
+	lpNewMod->FileName = (LPSTR) malloc(strlen(libname));
+	if (lpNewMod->FileName != NULL)	strcpy(lpNewMod->FileName, libname);
+	lpNewMod->hInst = LoadImage(libname, DLL);
+	lpNewMod->Count = 1;
+    printf("LoadLibrary returned Library hInst=%04X\n", lpNewMod->hInst);
+	GlobalUnlock(hModule);	
+    return lpNewMod->hInst;
 }
 
 
@@ -112,8 +146,24 @@
  */
 void FreeLibrary(HANDLE hLib)
 {
+	LPMODULEENTRY lpMod = lpModList;
     printf("FreeLibrary(%04X);\n", hLib);
-    if (hLib != (HANDLE)NULL) GlobalFree(hLib);
+	while (lpMod != NULL) {
+		if (lpMod->hInst == hLib) {
+			if (lpMod->Count == 1) {
+				if (hLib != (HANDLE)NULL) GlobalFree(hLib);
+				if (lpMod->ModuleName != NULL) free(lpMod->ModuleName);
+				if (lpMod->FileName != NULL) free(lpMod->FileName);
+				GlobalFree(lpMod->hModule);
+				printf("FreeLibrary // freed !\n");
+				return;
+				}
+			lpMod->Count--;
+			printf("FreeLibrary // Count decremented !\n");
+			return;
+			}
+		lpMod = lpMod->lpNextModule;
+		}
 }
 
 
@@ -128,26 +178,39 @@
 	int 	ordinal, len;
 	char 	* cpnt;
 	char	C[128];
-	if (hModule == 0) {
-		printf("GetProcAddress: Bad Module handle=%#04X\n", hModule);
-		return NULL;
-		}
+	HTASK	hTask;
+	LPTASKENTRY lpTask;
 	if (hModule >= 0xF000) {
 		if ((int) proc_name & 0xffff0000) {
-			printf("GetProcAddress: builtin %#04x, '%s'\n", hModule, proc_name);
+			printf("GetProcAddress: builtin %#04X, '%s'\n", 
+										hModule, proc_name);
 /*			wOrdin = FindOrdinalFromName(struct dll_table_entry_s *dll_table, proc_name); */
 			}
 		else {
-			printf("GetProcAddress: builtin %#04x, %d\n", hModule, (int) proc_name);
+			printf("GetProcAddress: builtin %#04X, %d\n", 
+								hModule, (int)proc_name);
 			}
 		return NULL;
 		}
+	if (hModule == 0) {
+		hTask = GetCurrentTask();
+		printf("GetProcAddress // GetCurrentTask()=%04X\n", hTask);
+		lpTask = (LPTASKENTRY) GlobalLock(hTask);
+		if (lpTask == NULL) {
+			printf("GetProcAddress: can't find current module handle !\n");
+			return NULL;
+			}
+		hModule = lpTask->hInst;
+		printf("GetProcAddress: current module=%04X instance=%04X!\n", 
+			lpTask->hModule, lpTask->hInst);
+		GlobalUnlock(hTask);
+		}
 	while (w && w->hinstance != hModule) w = w->next;
-	printf("GetProcAddress // Module Found ! w->filename='%s'\n", w->filename);
 	if (w == NULL) return NULL;
-	if ((int) proc_name & 0xffff0000) {
+	printf("GetProcAddress // Module Found ! w->filename='%s'\n", w->filename);
+	if ((int)proc_name & 0xFFFF0000) {
 		AnsiUpper(proc_name);
-		printf("GetProcAddress: %#04x, '%s'\n", hModule, proc_name);
+		printf("GetProcAddress: %04X, '%s'\n", hModule, proc_name);
 		cpnt = w->nrname_table;
 		while(TRUE) {
 			if (((int) cpnt)  - ((int)w->nrname_table) >  
@@ -155,11 +218,19 @@
 			len = *cpnt++;
 			strncpy(C, cpnt, len);
 			C[len] = '\0';
+#ifdef DEBUG_MODULE
 			printf("pointing Function '%s' !\n", C);
-			if (strncmp(cpnt, proc_name, len) ==  0) break;
+#endif
+			if (strncmp(cpnt, proc_name, len) ==  0) {
+				ordinal =  *((unsigned short *)  (cpnt +  len));
+				break;
+				}
 			cpnt += len + 2;
 			};
-		ordinal =  *((unsigned short *)  (cpnt +  len));
+		if (ordinal == 0) {
+			printf("GetProcAddress // function '%s' not found !\n", proc_name);
+			return NULL;
+			}
 		}
 	else {
 		printf("GetProcAddress: %#04x, %d\n", hModule, (int) proc_name);
@@ -167,13 +238,13 @@
 		}
 	ret = GetEntryPointFromOrdinal(w, ordinal);
 	if (ret == -1) {
-		printf("GetProcAddress // Function not found !\n");
+		printf("GetProcAddress // Function #%d not found !\n", ordinal);
 		return NULL;
 		}
 	addr  = ret & 0xffff;
 	sel = (ret >> 16);
 	printf("GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret, sel, addr);
-	return ret;
+	return (FARPROC) ret;
 }
 
 #endif /* ifndef WINELIB */
diff --git a/loader/task.c b/loader/task.c
new file mode 100644
index 0000000..46bb89b
--- /dev/null
+++ b/loader/task.c
@@ -0,0 +1,159 @@
+/*
+ *        Tasks functions
+ */
+static char Copyright[] = "Copyright  Martin Ayotte, 1994";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "windows.h"
+#include "wine.h"
+#include "task.h"
+
+static LPTASKENTRY lpTaskList = NULL;
+static int nTaskCount = 0;
+
+
+
+/**********************************************************************
+ *				GetCurrentTask	[KERNEL.36]
+ */
+HTASK GetCurrentTask()
+{
+	LPTASKENTRY lpTask = lpTaskList;
+	int pid = getpid();
+	printf("GetCurrentTask() // unix_pid=%08X !\n", pid);
+	if (lpTask == NULL) return 0;
+	while (TRUE) {
+		printf("GetCurrentTask() // searching lpTask->unix_pid=%08 !\n", lpTask->unix_pid);
+		if (lpTask->unix_pid == pid) break;
+		if (lpTask->lpNextTask == NULL) return 0;
+		lpTask = lpTask->lpNextTask;
+		}
+	printf("GetCurrentTask() returned hTask=%04X !\n", lpTask->hTask);
+	return lpTask->hTask;
+}
+
+
+/**********************************************************************
+ *				GetNumTasks	[KERNEL.152]
+ */
+WORD GetNumTasks()
+{
+	printf("GetNumTasks() returned %d !\n", nTaskCount);
+	return nTaskCount;
+}
+
+
+/**********************************************************************
+ *				GetWindowTask	[USER.224]
+ */
+HTASK GetWindowTask(HWND hWnd)
+{
+	printf("GetWindowTask(%04X) !\n", hWnd);
+	return 0;
+}
+
+
+/**********************************************************************
+ *				EnumTaskWindows	[USER.225]
+ */
+BOOL EnumTaskWindows(HANDLE hTask, FARPROC lpEnumFunc, LONG lParam)
+{
+	printf("EnumTaskWindows(%04X, %08X, %08X) !\n", hTask, lpEnumFunc, lParam);
+	return FALSE;
+}
+
+
+/**********************************************************************
+ *				CreateNewTask		[internal]
+ */
+HANDLE CreateNewTask(HINSTANCE hInst)
+{
+    HANDLE hTask;
+	LPTASKENTRY lpTask = lpTaskList;
+	LPTASKENTRY lpNewTask;
+	if (lpTask != NULL) {
+		while (TRUE) {
+			if (lpTask->lpNextTask == NULL) break;
+			lpTask = lpTask->lpNextTask;
+			}
+		}
+	hTask = GlobalAlloc(GMEM_MOVEABLE, sizeof(TASKENTRY));
+	lpNewTask = (LPTASKENTRY) GlobalLock(hTask);
+#ifdef DEBUG_TASK
+    printf("CreateNewTask entry allocated %08X\n", lpNewTask);
+#endif
+	if (lpNewTask == NULL) return 0;
+	if (lpTaskList == NULL) {
+		lpTaskList = lpNewTask;
+		lpNewTask->lpPrevTask = NULL;
+		}
+	else {
+		lpTask->lpNextTask = lpNewTask;
+		lpNewTask->lpPrevTask = lpTask;
+		}
+	lpNewTask->lpNextTask = NULL;
+	lpNewTask->hIcon = 0;
+	lpNewTask->hModule = 0;
+	lpNewTask->hTask = hTask;
+	lpNewTask->lpWndList = (HWND *) malloc(MAXWIN_PER_TASK * sizeof(HWND));
+	if (lpNewTask->lpWndList != NULL) 
+		memset((LPSTR)lpNewTask->lpWndList, 0, MAXWIN_PER_TASK * sizeof(HWND));
+	lpNewTask->hInst = hInst;
+	lpNewTask->unix_pid = getpid();
+    printf("CreateNewTask // unix_pid=%08X return hTask=%04X\n", 
+									lpNewTask->unix_pid, hTask);
+	GlobalUnlock(hTask);	
+    return hTask;
+}
+
+
+/**********************************************************************
+ *				AddWindowToTask		[internal]
+ */
+BOOL AddWindowToTask(HTASK hTask, HWND hWnd)
+{
+	HWND 	*wptr;
+	int		count = 0;
+	LPTASKENTRY lpTask = lpTaskList;
+	printf("AddWindowToTask(%04X, %04X); !\n", hTask, hWnd);
+	while (TRUE) {
+		if (lpTask->hTask == hTask) break;
+		if (lpTask == NULL) return FALSE;
+		lpTask = lpTask->lpNextTask;
+		}
+	wptr = lpTask->lpWndList;
+	if (wptr == NULL) return FALSE;
+	while (*(wptr++) != 0) {
+		if (++count >= MAXWIN_PER_TASK) return FALSE;
+		}
+	*wptr = hWnd;
+	return TRUE;
+}
+
+
+/**********************************************************************
+ *				RemoveWindowFromTask		[internal]
+ */
+BOOL RemoveWindowFromTask(HTASK hTask, HWND hWnd)
+{
+	HWND 	*wptr;
+	int		count = 0;
+	LPTASKENTRY lpTask = lpTaskList;
+	printf("AddWindowToTask(%04X, %04X); !\n", hTask, hWnd);
+	while (TRUE) {
+		if (lpTask->hTask == hTask) break;
+		if (lpTask == NULL) return FALSE;
+		lpTask = lpTask->lpNextTask;
+		}
+	wptr = lpTask->lpWndList;
+	if (wptr == NULL) return FALSE;
+	while (*(wptr++) != hWnd) {
+		if (++count >= MAXWIN_PER_TASK) return FALSE;
+		}
+	*wptr = 0;
+	return TRUE;
+}
+
+
diff --git a/loader/wine.c b/loader/wine.c
index 4edecaa..8236853 100644
--- a/loader/wine.c
+++ b/loader/wine.c
@@ -49,6 +49,7 @@
 
 static char *DLL_Extensions[] = { "dll", "exe", NULL };
 static char *EXE_Extensions[] = { "exe", NULL };
+static char *WinePath = NULL;
 
 FILE *SpyFp = NULL;
 
@@ -154,7 +155,6 @@
       wpnt1->next  = wpnt;
     };
     wpnt->next = NULL;
-    wpnt->resnamtab = (RESNAMTAB *) -1;
 
     /*
      * Open file for reading.
@@ -248,6 +248,8 @@
      */
     for(i=0; i<wpnt->ne_header->n_mod_ref_tab; i++){
       char buff[14];
+      char buff2[256];
+      int  fd, j;
       GetModuleName(wpnt, i + 1, buff);
       
 #ifndef WINELIB
@@ -263,27 +265,38 @@
 }
 
 
-#ifndef WINELIB
 /**********************************************************************
  *					main
  */
-int _WinMain(int argc, char **argv)
+_WinMain(int argc, char **argv)
 {
 	int segment;
 	char *p;
 	char *sysresname;
 	char filename[100];
+	char syspath[256];
+	char exe_path[256];
 #ifdef WINESTAT
 	char * cp;
 #endif
 	struct w_files * wpnt;
 	int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
+	int i;
 	int rv;
 
 	Argc = argc - 1;
 	Argv = argv + 1;
 	
-	if (LoadImage(Argv[0], EXE) == (HINSTANCE) NULL ) {
+	WinePath = malloc(1024);
+	
+	getcwd(WinePath, 512);
+	
+	if ((p = getenv("WINEPATH")) != NULL) { 
+		strcat(WinePath, ";");
+		strcat(WinePath, p);
+	}
+	
+	if ((hInstMain = LoadImage(Argv[0], EXE)) == (HINSTANCE) NULL ) {
 		fprintf(stderr, "wine: can't find %s!.\n", Argv[0]);
 		exit(1);
 	}
@@ -380,7 +393,6 @@
 	}
     }
 }
-#endif
 
 
 /**********************************************************************
@@ -390,8 +402,10 @@
 GetImportedName(int fd, struct mz_header_s *mz_header, 
 		struct ne_header_s *ne_header, int name_offset, char *buffer)
 {
+    char *p;
     int length;
     int status;
+    int i;
     
     status = lseek(fd, mz_header->ne_offset + ne_header->iname_tab_offset +
 		   name_offset, SEEK_SET);
@@ -412,6 +426,7 @@
     int fd = wpnt->fd;
     struct mz_header_s *mz_header = wpnt->mz_header; 
     struct ne_header_s *ne_header = wpnt->ne_header;
+    char *p;
     int length;
     WORD name_offset, status;
     int i;
@@ -699,4 +714,16 @@
     return 0;
 }
 
+/**********************************************************************
+ *					GetProcAddress
+ */
+FARPROC GetProcAddress(HINSTANCE hinstance, char *proc_name)
+{
+    if ((int) proc_name & 0xffff0000)
+	printf("GetProcAddress: %#04x, '%s'\n", hinstance, proc_name);
+    else
+	printf("GetProcAddress: %#04x, %d\n", hinstance, (int) proc_name);
+
+    return NULL;
+}
 #endif
diff --git a/misc/Imakefile b/misc/Imakefile
index 2979b52..e081262 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -15,7 +15,9 @@
 	main.c \
 	message.c \
 	profile.c \
+	property.c \
 	rect.c \
+	shell.c \
 	sound.c \
 	spy.c \
 	stress.c \
diff --git a/misc/audio.c b/misc/audio.c
new file mode 100644
index 0000000..97a2e60
--- /dev/null
+++ b/misc/audio.c
@@ -0,0 +1,97 @@
+/*
+ * Sample Wine Driver for Linux
+ *
+ * Copyright 1994 Martin Ayotte
+ */
+
+static char Copyright[] = "Copyright  Martin Ayotte, 1994";
+
+#include "stdio.h"
+#include "windows.h"
+#include "win.h"
+#include "user.h"
+#include "driver.h"
+#include "mmsystem.h"
+
+
+/**************************************************************************
+* 				DriverProc			[sample driver]
+*/
+LRESULT DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
+						DWORD dwParam1, DWORD dwParam2)
+{
+	switch(wMsg) {
+		case DRV_LOAD:
+			return (LRESULT)1L;
+		case DRV_FREE:
+			return (LRESULT)1L;
+		case DRV_OPEN:
+			return (LRESULT)1L;
+		case DRV_CLOSE:
+			return (LRESULT)1L;
+		case DRV_ENABLE:
+			return (LRESULT)1L;
+		case DRV_DISABLE:
+			return (LRESULT)1L;
+		case DRV_QUERYCONFIGURE:
+			return (LRESULT)1L;
+		case DRV_CONFIGURE:
+			MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !", 
+								"MMLinux Driver", MB_OK);
+			return (LRESULT)1L;
+		case DRV_INSTALL:
+			return (LRESULT)DRVCNF_RESTART;
+		case DRV_REMOVE:
+			return (LRESULT)DRVCNF_RESTART;
+		default:
+			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+		}
+}
+
+/**************************************************************************
+* 				wodMessage			[sample driver]
+*/
+DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2)
+{
+}
+
+/**************************************************************************
+* 				widMessage			[sample driver]
+*/
+DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2)
+{
+}
+
+/**************************************************************************
+* 				auxMessage			[sample driver]
+*/
+DWORD auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2)
+{
+}
+
+/**************************************************************************
+* 				midMessage			[sample driver]
+*/
+DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2)
+{
+}
+
+/**************************************************************************
+* 				modMessage			[sample driver]
+*/
+DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
+					DWORD dwParam1, DWORD dwParam2)
+{
+}
+
+
+/*
+BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev, 
+		WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
+*/
+
+
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index 9c9e9ef..78ee54c 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -572,8 +572,6 @@
 			strncat(buffer, "/", buflen - strlen(buffer));
 			strncat(buffer, f->d_name, buflen - strlen(buffer));
 
-			fprintf(stderr,"$$%s$$\n", buffer);
-
 			stat(buffer, &filestat);
 			if (S_ISREG(filestat.st_mode)) {
 				closedir(d);
diff --git a/misc/driver.c b/misc/driver.c
new file mode 100644
index 0000000..a3e4975
--- /dev/null
+++ b/misc/driver.c
@@ -0,0 +1,181 @@
+/*
+ * Wine Drivers functions
+ *
+ * Copyright 1994 Martin Ayotte
+ */
+
+static char Copyright[] = "Copyright  Martin Ayotte, 1994";
+
+#include "stdio.h"
+#include "windows.h"
+#include "win.h"
+#include "user.h"
+#include "driver.h"
+
+LPDRIVERITEM lpDrvItemList = NULL;
+
+/**************************************************************************
+ *				SendDriverMessage		[USER.251]
+ */
+LRESULT WINAPI SendDriverMessage(HDRVR hDriver, WORD msg, LPARAM lParam1, LPARAM lParam2)
+{
+	printf("SendDriverMessage(%04X, %04X, %08X, %08X);\n",
+						hDriver, msg, lParam1, lParam2);
+}
+
+/**************************************************************************
+ *				OpenDriver				[USER.252]
+ */
+HDRVR OpenDriver(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
+{
+	HDRVR			hDrvr;
+	LPDRIVERITEM	lpnewdrv;
+	LPDRIVERITEM	lpdrv = lpDrvItemList;
+	char			DrvName[128];
+	printf("OpenDriver('%s', '%s', %08X);\n",
+		lpDriverName, lpSectionName, lParam);
+	if (lpSectionName == NULL) lpSectionName = "drivers";
+	GetPrivateProfileString(lpSectionName, lpDriverName,
+		"", DrvName, sizeof(DrvName), "SYSTEM.INI");
+	printf("OpenDriver // DrvName='%s'\n", DrvName);
+	if (strlen(DrvName) < 1) return 0;
+	while (lpdrv != NULL) {
+		if (lpdrv->lpNextItem == NULL) break;
+		lpdrv = lpdrv->lpNextItem;
+		}
+	hDrvr = GlobalAlloc(GMEM_MOVEABLE, sizeof(DRIVERITEM));
+	lpnewdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
+	if (lpnewdrv == NULL) return 0;
+	lpnewdrv->dis.length = sizeof(DRIVERINFOSTRUCT);
+	lpnewdrv->dis.hModule = LoadImage("DrvName", DLL);
+	if (lpnewdrv->dis.hModule == 0) {
+		GlobalUnlock(hDrvr);
+		GlobalFree(hDrvr);
+		return 0;
+		}
+	lpnewdrv->dis.hDriver = hDrvr;
+	strcpy(lpnewdrv->dis.szAliasName, lpDriverName);
+	lpnewdrv->count = 0;
+	lpnewdrv->lpNextItem = NULL;
+	if (lpDrvItemList == NULL || lpdrv == NULL) {
+		lpDrvItemList = lpnewdrv;
+		lpnewdrv->lpPrevItem = NULL;
+		}
+	else {
+		lpdrv->lpNextItem = lpnewdrv;
+		lpnewdrv->lpPrevItem = lpdrv;
+		}
+	lpnewdrv->lpDrvProc = NULL;
+	printf("OpenDriver // hDrvr=%04X loaded !\n", hDrvr);
+	return hDrvr;
+}
+
+/**************************************************************************
+ *				CloseDriver				[USER.253]
+ */
+LRESULT CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
+{
+	LPDRIVERITEM	lpdrv;
+	printf("CloseDriver(%04X, %08X, %08X);\n", hDrvr, lParam1, lParam2);
+	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
+	if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr) {
+		if (lpdrv->lpPrevItem)
+			((LPDRIVERITEM)lpdrv->lpPrevItem)->lpNextItem = lpdrv->lpNextItem;
+		if (lpdrv->lpNextItem)
+			((LPDRIVERITEM)lpdrv->lpNextItem)->lpPrevItem = lpdrv->lpPrevItem;
+		GlobalUnlock(hDrvr);
+		GlobalFree(hDrvr);
+		printf("CloseDriver // hDrvr=%04X closed !\n", hDrvr);
+		return TRUE;
+		}
+	return FALSE;
+}
+
+/**************************************************************************
+ *				GetDriverModuleHandle	[USER.254]
+ */
+HANDLE GetDriverModuleHandle(HDRVR hDrvr)
+{
+	LPDRIVERITEM	lpdrv;
+	HANDLE			hModule = 0;
+	printf("GetDriverModuleHandle(%04X);\n", hDrvr);
+	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
+	if (lpdrv != NULL) {
+		hModule = lpdrv->dis.hModule;
+		GlobalUnlock(hDrvr);
+		}
+	return hModule;
+}
+
+/**************************************************************************
+ *				DefDriverProc			[USER.255]
+ */
+LRESULT DefDriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
+						DWORD dwParam1, DWORD dwParam2)
+{
+	switch(wMsg) {
+		case DRV_LOAD:
+			return (LRESULT)0L;
+		case DRV_FREE:
+			return (LRESULT)0L;
+		case DRV_OPEN:
+			return (LRESULT)0L;
+		case DRV_CLOSE:
+			return (LRESULT)0L;
+		case DRV_ENABLE:
+			return (LRESULT)0L;
+		case DRV_DISABLE:
+			return (LRESULT)0L;
+		case DRV_QUERYCONFIGURE:
+			return (LRESULT)0L;
+		case DRV_CONFIGURE:
+			MessageBox((HWND)NULL, "Driver isn't configurable !", 
+									"Wine Driver", MB_OK);
+			return (LRESULT)0L;
+		case DRV_INSTALL:
+			return (LRESULT)DRVCNF_RESTART;
+		case DRV_REMOVE:
+			return (LRESULT)DRVCNF_RESTART;
+		default:
+			return (LRESULT)0L;
+		}
+}
+
+/**************************************************************************
+ *				GetDriverInfo			[USER.256]
+ */
+BOOL GetDriverInfo(HDRVR hDrvr, LPDRIVERINFOSTRUCT lpDrvInfo)
+{
+	LPDRIVERITEM	lpdrv;
+	printf("GetDriverInfo(%04X, %08X);\n", hDrvr, lpDrvInfo);
+	if (lpDrvInfo == NULL) return FALSE;
+	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
+	if (lpdrv == NULL) return FALSE;
+	memcpy(lpDrvInfo, &lpdrv->dis, sizeof(DRIVERINFOSTRUCT));
+	GlobalUnlock(hDrvr);
+	return TRUE;
+}
+
+/**************************************************************************
+ *				GetNextDriver			[USER.257]
+ */
+HDRVR GetNextDriver(HDRVR hDrvr, DWORD dwFlags)
+{
+	LPDRIVERITEM	lpdrv;
+	HDRVR			hRetDrv = 0;
+	printf("GetNextDriver(%04X, %08X);\n", hDrvr, dwFlags);
+	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
+	if (lpdrv != NULL) {
+		if (dwFlags & GND_REVERSE) 
+			if (lpdrv->lpPrevItem) 
+				hRetDrv = ((LPDRIVERITEM)lpdrv->lpPrevItem)->dis.hDriver;
+		if (dwFlags & GND_FORWARD) 
+			if (lpdrv->lpNextItem) 
+				hRetDrv = ((LPDRIVERITEM)lpdrv->lpNextItem)->dis.hDriver;
+		GlobalUnlock(hDrvr);
+		}
+	return hRetDrv;
+	
+}
+
+
diff --git a/misc/exec.c b/misc/exec.c
index f6730c6..bb37237 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -24,11 +24,37 @@
 #define HELP_MULTIKEY     0x0201
 #define HELP_SETWINPOS    0x0203
 
+typedef struct {
+	WORD	wEnvSeg;
+	LPSTR	lpCmdLine;
+	LPVOID	lpCmdShow;
+	DWORD	dwReserved;
+	} PARAMBLOCK;
 
+HANDLE CreateNewTask(HINSTANCE hInst);
+
+/**********************************************************************
+ *				LoadModule	[KERNEL.45]
+ */
+HANDLE LoadModule(LPSTR modulefile, LPVOID lpParamBlk)
+{
+	PARAMBLOCK  *pblk = lpParamBlk;
+	WORD 	*lpCmdShow;
+    printf("LoadModule '%s' %08X\n", modulefile, lpParamBlk);
+	if (lpParamBlk == NULL) return 0;
+	lpCmdShow = (WORD *)pblk->lpCmdShow;
+	return WinExec(pblk->lpCmdLine, lpCmdShow[1]);
+}
+
+
+/**********************************************************************
+ *				WinExec		[KERNEL.166]
+ */
 WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow)
 {
 	int X, X2, C;
 	char *ArgV[20];
+	HANDLE	hTask = 0;
 	printf("WinExec('%s', %04X)\n", lpCmdLine, nCmdShow);
 	ArgV[0] = "wine";
 	C = 1;
@@ -38,35 +64,47 @@
 			strncpy(ArgV[C], &lpCmdLine[X2], X - X2);
 			ArgV[C][X - X2] = '\0';
 			C++;   X2 = X + 1;
-		}							  
-	}  
+			}							  
+		}  
 	ArgV[C] = NULL;
 	for (C = 0; ; C++) {
 		if (ArgV[C] == NULL)  break;
 		printf("--> '%s' \n", ArgV[C]);
-	}  
+		}  
 	switch(fork()) {
-	case -1:
-		printf("Can't 'fork' process !\n");
-		break;
-	case 0:
-		printf("New process started !\n");
-		execvp(ArgV[0], ArgV);
-		printf("Child process died !\n");
-		exit(1);
-		break;
-	default:
-		printf("Main process stay alive !\n");
-		break;         
-	}
+		case -1:
+			printf("Can't 'fork' process !\n");
+			break;
+		case 0:
+			hTask = CreateNewTask(0);
+			printf("WinExec // New Task hTask=%04X !\n", hTask);
+			execvp(ArgV[0], ArgV);
+			printf("Child process died !\n");
+			exit(1);
+		default:
+			printf("WinExec (Main process stay alive) hTask=%04X !\n", hTask);
+			break;         
+		}
 	for (C = 0; ; C++) {
 		if (ArgV[C] == NULL)  break;
 		free(ArgV[C]);
-	}  
-	return(TRUE);
+		}  
+	return hTask;
 }
 
 
+/**********************************************************************
+ *				ExitWindows		[USER.7]
+ */
+BOOL ExitWindows(DWORD dwReserved, WORD wRetCode)
+{
+	printf("EMPTY STUB !!! ExitWindows(%08X, %04X) !\n", dwReserved, wRetCode);
+}
+
+
+/**********************************************************************
+ *				WinHelp		[USER.171]
+ */
 BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
 {
 	char	str[256];
diff --git a/misc/file.c b/misc/file.c
index 5d41f1c..47beada 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -17,7 +17,7 @@
  *
  ************************************************************************/
 
-#define DEBUG_FILE
+/* #define DEBUG_FILE */
 
 #include <stdio.h>
 #include <fcntl.h>
@@ -34,7 +34,7 @@
 
  Emulate the _lopen windows call
  ***************************************************************************/
-int _lopen (LPSTR lpPathName, int iReadWrite)
+INT _lopen (LPSTR lpPathName, INT iReadWrite)
 {
   int  handle;
   char *UnixFileName;
@@ -61,7 +61,7 @@
 /***************************************************************************
  _lread
  ***************************************************************************/
-WORD _lread (int hFile, LPSTR lpBuffer, int wBytes)
+WORD _lread (INT hFile, LPSTR lpBuffer, INT wBytes)
 {
   int result;
 
@@ -81,7 +81,7 @@
 /****************************************************************************
  _lwrite
 ****************************************************************************/
-WORD _lwrite (int hFile, LPSTR lpBuffer, int wBytes)
+WORD _lwrite (INT hFile, LPSTR lpBuffer, INT wBytes)
 {
 	int result;
 
@@ -100,7 +100,7 @@
 /***************************************************************************
  _lclose
  ***************************************************************************/
-int _lclose (int hFile)
+INT _lclose (INT hFile)
 {
 #ifdef DEBUG_FILE
 	fprintf(stderr, "_lclose: handle %d\n", hFile);
@@ -117,7 +117,7 @@
  Warning:  This is nearly totally untested.  It compiles, that's it...
                                             -SL 9/13/93
  **************************************************************************/
-int OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
+INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
 {
   int base,flags;
 
@@ -168,7 +168,7 @@
 /***************************************************************************
  _llseek
  ***************************************************************************/
-LONG _llseek (int hFile, LONG lOffset, int nOrigin)
+LONG _llseek (INT hFile, LONG lOffset, INT nOrigin)
 {
 	int origin;
 	
@@ -191,7 +191,7 @@
 /***************************************************************************
  _lcreate
  ***************************************************************************/
-LONG _lcreate (LPSTR lpszFilename, int fnAttribute)
+INT _lcreate (LPSTR lpszFilename, INT fnAttribute)
 {
 	int handle;
 	char *UnixFileName;
@@ -215,7 +215,7 @@
 /***************************************************************************
  GetDriveType
  ***************************************************************************/
-UINT GetDriveType(int drive)
+UINT GetDriveType(INT drive)
 {
 
 #ifdef DEBUG_FILE
@@ -228,7 +228,7 @@
 	if (drive == 0 || drive == 1)
 		return DRIVE_REMOVABLE;
 		 
-	return DRIVE_REMOVABLE;
+	return DRIVE_FIXED;
 }
 
 /***************************************************************************
@@ -279,7 +279,7 @@
 /***************************************************************************
  GetTempFileName
  ***************************************************************************/
-int GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
+INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
 {
 	int unique;
 	char tempname[256];
@@ -292,7 +292,7 @@
 	strcpy(tempname,lpszPrefixString);
 	tempname[3]='\0';
 
-	sprintf(lpszTempFileName,"%s\\%s%d.tmp",WindowsDirectory, tempname, 
+	sprintf(lpszTempFileName,"%s\\%s%d.tmp", TempDirectory, tempname, 
 		unique);
 
 	ToDos(lpszTempFileName);
@@ -318,46 +318,12 @@
  ***************************************************************************/
 long _hread(int hf, void FAR *hpvBuffer, long cbBuffer)
 {
-	long dataread = 0;
-	size_t status, size;
-	
-	while (cbBuffer) 
-	{
-		size = cbBuffer < 30000 ? cbBuffer : 30000;
-		
-		status = read(hf, hpvBuffer, size);
-		if (status == -1)
-			return HFILE_ERROR;
-		if (status == 0)
-			return dataread;
-
-		dataread += status;
-		hpvBuffer += status;
-		cbBuffer -= status;
-	}		
-	return dataread;
+	return read(hf, hpvBuffer, cbBuffer);
 }
 /***************************************************************************
  _hwrite
  ***************************************************************************/
 long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer)
 {
-	long datawritten = 0;
-	size_t status, size;
-	
-	while (cbBuffer) 
-	{
-		size = cbBuffer < 30000 ? cbBuffer : 30000;
-		
-		status = write(hf, hpvBuffer, size);
-		if (status == -1)
-			return HFILE_ERROR;
-		if (status == 0)
-			return datawritten;
-
-		datawritten += status;
-		hpvBuffer += status;
-		cbBuffer -= status;
-	}		
-	return datawritten;
+	return write(hf, hpvBuffer, cbBuffer);
 }
diff --git a/misc/lstr.c b/misc/lstr.c
index cec2748..e6dc701 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -23,13 +23,13 @@
 }
 
 /* USER.430 */
-int lstrcmp(LPCSTR str1,LPCSTR str2)
+INT lstrcmp(LPCSTR str1,LPCSTR str2)
 {
   return strcmp(str1,str2);
 }
 
 /* USER.471 */
-int lstrcmpi(LPCSTR str1,LPCSTR str2)
+INT lstrcmpi(LPCSTR str1,LPCSTR str2)
 {
   int i;
   i=0;
@@ -51,7 +51,7 @@
 }
 
 /* KERNEL.90 */
-int lstrlen(LPCSTR str)
+INT lstrlen(LPCSTR str)
 {
   return strlen(str);
 }
@@ -148,7 +148,7 @@
 static char Oem2Ansi[256];
 static char Ansi2Oem[256];
 
-void InitOemAnsiTranslations()
+void InitOemAnsiTranslations(void)
 {
   static int inited=0; /* should called called in some init function*/
   int transfile,i;
@@ -173,7 +173,7 @@
 }
 
 /* AnsiToOem Keyboard.5 */
-int AnsiToOem(LPSTR lpAnsiStr, LPSTR lpOemStr)   /* why is this int ??? */
+INT AnsiToOem(LPSTR lpAnsiStr, LPSTR lpOemStr)   /* why is this int ??? */
 {
   InitOemAnsiTranslations(); /* should called called in some init function*/
   while(*lpAnsiStr){
@@ -193,7 +193,7 @@
 }
 
 /* AnsiToOemBuff Keyboard.134 */
-void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, int nLength)
+void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, INT nLength)
 {
   int i;
   InitOemAnsiTranslations(); /* should called called in some init function*/
@@ -202,7 +202,7 @@
 }
 
 /* OemToAnsi Keyboard.135 */
-void OemToAnsiBuff(LPSTR lpOemStr, LPSTR lpAnsiStr, int nLength)
+void OemToAnsiBuff(LPSTR lpOemStr, LPSTR lpAnsiStr, INT nLength)
 {
   int i;
   InitOemAnsiTranslations(); /* should called called in some init function*/
diff --git a/misc/main.c b/misc/main.c
index c98b723..59106ca 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -494,17 +494,7 @@
 */
 void hmemcpy(void FAR *hpvDest, const void FAR *hpvSource, long cbCopy)
 {
-	size_t copysize;
-	
-	while (cbCopy) 
-	{
-		copysize = cbCopy < 30000 ? cbCopy : 30000;
-		
-		memcpy(hpvDest,	hpvSource, copysize);
-		hpvDest += copysize;
-		hpvSource += copysize;
-		cbCopy -= copysize;
-	}		
+	memcpy(hpvDest,	hpvSource, cbCopy);
 }
 
 /***********************************************************************
diff --git a/misc/message.c b/misc/message.c
index 57428e7..c545963 100644
--- a/misc/message.c
+++ b/misc/message.c
@@ -50,17 +50,22 @@
 	WND	    	*wndPtr;
 	WNDCLASS  	wndClass;
 	MSG	    	msg;
-	MSGBOX	mb;
-	DWORD	dwStyle;
+	MSGBOX		mb;
+	DWORD		dwStyle;
 	HINSTANCE	hInst;
 	wndPtr = WIN_FindWndPtr(hWnd);
+	if (wndPtr == NULL) {
+		hInst = hSysRes;
 #ifdef DEBUG_MSGBOX
-	printf( "MessageBox: '%s'\n", str );
+		printf("MessageBox(NULL, '%s', '%s', %04X)\n", str, title, type);
 #endif
-	if (wndPtr == NULL)
-	hInst = hSysRes;
-	else
-	hInst = wndPtr->hInstance;
+		}
+	else {
+		hInst = wndPtr->hInstance;
+#ifdef DEBUG_MSGBOX
+		printf("MessageBox(%04X, '%s', '%s', %04X)\n", hWnd, str, title, type);
+#endif
+		}
 	wndClass.style           = CS_HREDRAW | CS_VREDRAW ;
 	wndClass.lpfnWndProc     = (WNDPROC)SystemMessageBoxProc;
 	wndClass.cbClsExtra      = 0;
@@ -71,7 +76,10 @@
 	wndClass.hbrBackground   = GetStockObject(WHITE_BRUSH);
 	wndClass.lpszMenuName    = NULL;
 	wndClass.lpszClassName   = "MESSAGEBOX";
-	if (!RegisterClass(&wndClass)) return 0;
+	if (!RegisterClass(&wndClass)) {
+		printf("Unable to Register class 'MESSAGEBOX' !\n");
+		return 0;
+		}
 	memset(&mb, 0, sizeof(MSGBOX));
 	mb.Title = title;
 	mb.Str = str;
@@ -82,11 +90,28 @@
 	hWndOld = GetFocus();
 	hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120,
 				(HWND)NULL, (HMENU)NULL, hInst, (LPSTR)&mb);
-	if (hDlg == 0) return 0;
+	if (hDlg == 0) {
+		printf("Unable to create 'MESSAGEBOX' window !\n");
+		return 0;
+		}
+#ifdef DEBUG_MSGBOX
+	printf( "MessageBox // before Msg Loop !\n");
+#endif
 	while(TRUE) {
 		if (!mb.ActiveFlg) break;
 		if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
 		TranslateMessage(&msg);
+		if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 &&
+			msg.hwnd != hDlg) {
+			switch(msg.message) {
+				case WM_KEYDOWN:
+				case WM_LBUTTONDOWN:
+				case WM_MBUTTONDOWN:
+				case WM_RBUTTONDOWN:
+					MessageBeep(0);
+					break;
+				}
+			}
 		DispatchMessage(&msg);
 		}
 	SetFocus(hWndOld);
@@ -97,6 +122,7 @@
 	return(mb.wRetVal);
 }
 
+
 LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd)
 {
     WND  *wndPtr;
@@ -119,6 +145,7 @@
 	CREATESTRUCT *createStruct;
 	PAINTSTRUCT	ps;
 	HDC			hDC;
+	DWORD		OldTextColor;
 	RECT		rect;
 	LPMSGBOX	lpmb;
 	LPMSGBOX	lpmbInit;
@@ -225,21 +252,26 @@
 	    break;
 	case WM_PAINT:
 #ifdef DEBUG_MSGBOX
-	    printf("MessageBox WM_PAINT !\n");
+		printf("MessageBox WM_PAINT !\n");
 #endif
-	    lpmb = MsgBoxGetStorageHeader(hWnd);
-	    CopyRect(&rect, &lpmb->rectStr);
-	    hDC = BeginPaint(hWnd, &ps);
-	    if (lpmb->hIcon) 
-		DrawIcon(hDC, lpmb->rectIcon.left,
-		    lpmb->rectIcon.top, lpmb->hIcon);
-	    DrawText(hDC, lpmb->Str, -1, &rect, 
-		DT_CALCRECT | DT_CENTER | DT_WORDBREAK);
-	    rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2;
-	    rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2;
-	    DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK);
-	    EndPaint(hWnd, &ps);
-	    break;
+		lpmb = MsgBoxGetStorageHeader(hWnd);
+		CopyRect(&rect, &lpmb->rectStr);
+		hDC = BeginPaint(hWnd, &ps);
+		OldTextColor = SetTextColor(hDC, 0x00000000);
+		if (lpmb->hIcon) 
+			DrawIcon(hDC, lpmb->rectIcon.left,
+				lpmb->rectIcon.top, lpmb->hIcon);
+		DrawText(hDC, lpmb->Str, -1, &rect, 
+			DT_CALCRECT | DT_CENTER | DT_WORDBREAK);
+		rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2;
+		rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2;
+		DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK);
+		SetTextColor(hDC, OldTextColor);
+		EndPaint(hWnd, &ps);
+#ifdef DEBUG_MSGBOX
+		printf("MessageBox End of WM_PAINT !\n");
+#endif
+		break;
 	case WM_DESTROY:
 #ifdef DEBUG_MSGBOX
 	    printf("MessageBox WM_DESTROY !\n");
diff --git a/misc/mmsystem.c b/misc/mmsystem.c
new file mode 100644
index 0000000..042974c
--- /dev/null
+++ b/misc/mmsystem.c
@@ -0,0 +1,1031 @@
+/*
+ * MMSYTEM functions
+ *
+ * Copyright 1993 Martin Ayotte
+ */
+
+static char Copyright[] = "Copyright  Martin Ayotte, 1993";
+
+#include "stdio.h"
+#include "win.h"
+#include "mmsystem.h"
+
+
+int MCI_LibMain(HANDLE hInstance, WORD wDataSeg,
+		 WORD cbHeapSize, LPSTR lpCmdLine)
+{
+	printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
+	return(TRUE);
+}
+
+
+BOOL WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT uFlags)
+{
+	printf("sndPlaySound // lpszSoundName='%s' uFlags=%04X !\n", 
+										lpszSoundName, uFlags);
+	return 0;
+}
+
+
+
+WORD WINAPI mmsystemGetVersion()
+{
+	printf("mmsystemGetVersion // 0.4.0 ...?... :-) !\n");
+	return(0x0040);
+}
+
+
+void WINAPI OutputDebugStr(LPCSTR str)
+{
+	printf("OutputDebugStr('%s');\n", str);
+}
+
+
+UINT WINAPI auxGetNumDevs()
+{
+	printf("auxGetNumDevs !\n");
+	return 0;
+}
+
+
+UINT WINAPI auxGetDevCaps(UINT uDeviceID, AUXCAPS FAR* lpCaps, UINT uSize)
+{
+	printf("auxGetDevCaps !\n");
+	return 0;
+}
+
+
+UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
+{
+	printf("auxGetVolume !\n");
+	return 0;
+}
+
+
+
+UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
+{
+	printf("auxSetVolume !\n");
+	return 0;
+}
+
+
+DWORD WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2)
+{
+	printf("auxOutMessage !\n");
+	return 0L;
+}
+
+
+
+BOOL mciGetErrorString (DWORD wError, LPSTR lpstrBuffer, UINT uLength)
+{
+	LPSTR	msgptr;
+	int		maxbuf;
+	if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
+	lpstrBuffer[0] = '\0';
+	switch(wError) {
+		case MCIERR_INVALID_DEVICE_ID:
+			msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
+			break;
+		case MCIERR_UNRECOGNIZED_KEYWORD:
+			msgptr = "The driver cannot recognize the specified command parameter.";
+			break;
+		case MCIERR_UNRECOGNIZED_COMMAND:
+			msgptr = "The driver cannot recognize the specified command.";
+			break;
+		case MCIERR_HARDWARE:
+			msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
+			break;
+		case MCIERR_INVALID_DEVICE_NAME:
+			msgptr = "The specified device is not open or is not recognized by MCI.";
+			break;
+		case MCIERR_OUT_OF_MEMORY:
+			msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
+			break;
+		case MCIERR_DEVICE_OPEN:
+			msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
+			break;
+		case MCIERR_CANNOT_LOAD_DRIVER:
+			msgptr = "There is an undetectable problem in loading the specified device driver.";
+			break;
+		case MCIERR_MISSING_COMMAND_STRING:
+			msgptr = "No command was specified.";
+			break;
+		case MCIERR_PARAM_OVERFLOW:
+			msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
+			break;
+		case MCIERR_MISSING_STRING_ARGUMENT:
+			msgptr = "The specified command requires a character-string parameter. Please provide one.";
+			break;
+		case MCIERR_BAD_INTEGER:
+			msgptr = "The specified integer is invalid for this command.";
+			break;
+		case MCIERR_PARSER_INTERNAL:
+			msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
+			break;
+		case MCIERR_DRIVER_INTERNAL:
+			msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
+			break;
+		case MCIERR_MISSING_PARAMETER:
+			msgptr = "The specified command requires a parameter. Please supply one.";
+			break;
+		case MCIERR_UNSUPPORTED_FUNCTION:
+			msgptr = "The MCI device you are using does not support the specified command.";
+			break;
+		case MCIERR_FILE_NOT_FOUND:
+			msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
+			break;
+		case MCIERR_DEVICE_NOT_READY:
+			msgptr = "The device driver is not ready.";
+			break;
+		case MCIERR_INTERNAL:
+			msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
+			break;
+		case MCIERR_DRIVER:
+			msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
+			break;
+		case MCIERR_CANNOT_USE_ALL:
+			msgptr = "Cannot use 'all' as the device name with the specified command.";
+			break;
+		case MCIERR_MULTIPLE:
+			msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
+			break;
+		case MCIERR_EXTENSION_NOT_FOUND:
+			msgptr = "Cannot determine the device type from the given filename extension.";
+			break;
+		case MCIERR_OUTOFRANGE:
+			msgptr = "The specified parameter is out of range for the specified command.";
+			break;
+		case MCIERR_FLAGS_NOT_COMPATIBLE:
+			msgptr = "The specified parameters cannot be used together.";
+			break;
+		case MCIERR_FILE_NOT_SAVED:
+			msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
+			break;
+		case MCIERR_DEVICE_TYPE_REQUIRED:
+			msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
+			break;
+		case MCIERR_DEVICE_LOCKED:
+			msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
+			break;
+		case MCIERR_DUPLICATE_ALIAS:
+			msgptr = "The specified alias is already being used in this application. Use a unique alias.";
+			break;
+		case MCIERR_BAD_CONSTANT:
+			msgptr = "The specified parameter is invalid for this command.";
+			break;
+		case MCIERR_MUST_USE_SHAREABLE:
+			msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
+			break;
+		case MCIERR_MISSING_DEVICE_NAME:
+			msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
+			break;
+		case MCIERR_BAD_TIME_FORMAT:
+			msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
+			break;
+		case MCIERR_NO_CLOSING_QUOTE:
+			msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
+			break;
+		case MCIERR_DUPLICATE_FLAGS:
+			msgptr = "A parameter or value was specified twice. Only specify it once.";
+			break;
+		case MCIERR_INVALID_FILE:
+			msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
+			break;
+		case MCIERR_NULL_PARAMETER_BLOCK:
+			msgptr = "A null parameter block was passed to MCI.";
+			break;
+		case MCIERR_UNNAMED_RESOURCE:
+			msgptr = "Cannot save an unnamed file. Supply a filename.";
+			break;
+		case MCIERR_NEW_REQUIRES_ALIAS:
+			msgptr = "You must specify an alias when using the 'new' parameter.";
+			break;
+		case MCIERR_NOTIFY_ON_AUTO_OPEN:
+			msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
+			break;
+		case MCIERR_NO_ELEMENT_ALLOWED:
+			msgptr = "Cannot use a filename with the specified device.";
+			break;
+		case MCIERR_NONAPPLICABLE_FUNCTION:
+			msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
+			break;
+		case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
+			msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
+			break;
+		case MCIERR_FILENAME_REQUIRED:
+			msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
+			break;
+		case MCIERR_EXTRA_CHARACTERS:
+			msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
+			break;
+		case MCIERR_DEVICE_NOT_INSTALLED:
+			msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
+			break;
+		case MCIERR_GET_CD:
+			msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
+			break;
+		case MCIERR_SET_CD:
+			msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
+			break;
+		case MCIERR_SET_DRIVE:
+			msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
+			break;
+		case MCIERR_DEVICE_LENGTH:
+			msgptr = "Specify a device or driver name that is less than 79 characters.";
+			break;
+		case MCIERR_DEVICE_ORD_LENGTH:
+			msgptr = "Specify a device or driver name that is less than 69 characters.";
+			break;
+		case MCIERR_NO_INTEGER:
+			msgptr = "The specified command requires an integer parameter. Please provide one.";
+			break;
+		case MCIERR_WAVE_OUTPUTSINUSE:
+			msgptr = "All wave devices that can play files in the current format are in use. Wait until a wave device is free, and then try again.";
+			break;
+		case MCIERR_WAVE_SETOUTPUTINUSE:
+			msgptr = "Cannot set the current wave device for play back because it is in use. Wait until the device is free, and then try again.";
+			break;
+		case MCIERR_WAVE_INPUTSINUSE:
+			msgptr = "All wave devices that can record files in the current format are in use. Wait until a wave device is free, and then try again.";
+			break;
+		case MCIERR_WAVE_SETINPUTINUSE:
+			msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
+			break;
+		case MCIERR_WAVE_OUTPUTUNSPECIFIED:
+			msgptr = "Any compatible waveform playback device may be used.";
+			break;
+		case MCIERR_WAVE_INPUTUNSPECIFIED:
+			msgptr = "Any compatible waveform recording device may be used.";
+			break;
+		case MCIERR_WAVE_OUTPUTSUNSUITABLE:
+			msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
+			break;
+		case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
+			msgptr = "The device you are trying to play to cannot recognize the current file format.";
+			break;
+		case MCIERR_WAVE_INPUTSUNSUITABLE:
+			msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
+			break;
+		case MCIERR_WAVE_SETINPUTUNSUITABLE:
+			msgptr = "The device you are trying to record from cannot recognize the current file format.";
+			break;
+		case MCIERR_NO_WINDOW:
+			msgptr = "There is no display window.";
+			break;
+		case MCIERR_CREATEWINDOW:
+			msgptr = "Could not create or use window.";
+			break;
+		case MCIERR_FILE_READ:
+			msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
+			break;
+		case MCIERR_FILE_WRITE:
+			msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
+			break;
+
+/* 
+#define MCIERR_SEQ_DIV_INCOMPATIBLE     (MCIERR_BASE + 80)
+#define MCIERR_SEQ_PORT_INUSE           (MCIERR_BASE + 81)
+#define MCIERR_SEQ_PORT_NONEXISTENT     (MCIERR_BASE + 82)
+#define MCIERR_SEQ_PORT_MAPNODEVICE     (MCIERR_BASE + 83)
+#define MCIERR_SEQ_PORT_MISCERROR       (MCIERR_BASE + 84)
+#define MCIERR_SEQ_TIMER                (MCIERR_BASE + 85)
+#define MCIERR_SEQ_PORTUNSPECIFIED      (MCIERR_BASE + 86)
+#define MCIERR_SEQ_NOMIDIPRESENT        (MCIERR_BASE + 87)
+
+msg# 513 : vcr
+msg# 514 : videodisc
+msg# 515 : overlay
+msg# 516 : cdaudio
+msg# 517 : dat
+msg# 518 : scanner
+msg# 519 : animation
+msg# 520 : digitalvideo
+msg# 521 : other
+msg# 522 : waveaudio
+msg# 523 : sequencer
+msg# 524 : not ready
+msg# 525 : stopped
+msg# 526 : playing
+msg# 527 : recording
+msg# 528 : seeking
+msg# 529 : paused
+msg# 530 : open
+msg# 531 : false
+msg# 532 : true
+msg# 533 : milliseconds
+msg# 534 : hms
+msg# 535 : msf
+msg# 536 : frames
+msg# 537 : smpte 24
+msg# 538 : smpte 25
+msg# 539 : smpte 30
+msg# 540 : smpte 30 drop
+msg# 541 : bytes
+msg# 542 : samples
+msg# 543 : tmsf
+*/
+		default:
+			msgptr = "Unkown MCI Error !\n";
+			break;
+		}
+	maxbuf = min(uLength - 1, strlen(msgptr));
+	strncpy(lpstrBuffer, msgptr, maxbuf);
+	lpstrBuffer[maxbuf + 1] = '\0';
+	return(TRUE);
+}
+
+
+
+DWORD mciSendCommand(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+{
+	printf("mciSendCommand(%04X, %04X, %08X, %08X)\n", 
+					wDevID, wMsg, dwParam1, dwParam2);
+	return MCIERR_DEVICE_NOT_INSTALLED;
+}
+
+
+
+
+UINT mciGetDeviceID (LPCSTR lpstrName)
+{
+	printf("mciGetDeviceID(%s)\n", lpstrName);
+	return 0;
+}
+
+
+
+DWORD WINAPI mciSendString (LPCSTR lpstrCommand,
+    LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
+{
+	printf("mciSendString('%s', %lX, %u, %X)\n", 
+			lpstrCommand, lpstrReturnString, 
+			uReturnLength, hwndCallback);
+	return MCIERR_MISSING_COMMAND_STRING;
+}
+
+
+
+HMMIO WINAPI mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwOpenFlags)
+{
+	printf("mmioOpen('%s', %08X, %08X);\n", szFileName, lpmmioinfo, dwOpenFlags);
+	return 0;
+}
+
+
+    
+UINT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
+{
+	printf("mmioClose(%04X, %04X);\n", hmmio, uFlags);
+	return 0;
+}
+
+
+
+LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
+{
+	printf("mmioRead\n");
+	return 0;
+}
+
+
+
+LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
+{
+	printf("mmioWrite\n");
+	return 0;
+}
+
+
+LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, int iOrigin)
+{
+	printf("mmioSeek\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiOutGetNumDevs(void)
+{
+	printf("midiOutGetNumDevs\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiOutGetDevCaps(UINT uDeviceID,
+    MIDIOUTCAPS FAR* lpCaps, UINT uSize)
+{
+	printf("midiOutGetDevCaps\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
+{
+	printf("midiOutGetVolume\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutSetVolume(UINT uDeviceID, DWORD dwVolume)
+{
+	printf("midiOutSetVolume\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
+{
+	printf("midiOutGetErrorText\n");
+	return(midiGetErrorText(uError, lpText, uSize));
+}
+
+
+UINT WINAPI midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
+{
+	LPSTR	msgptr;
+	int		maxbuf;
+	if ((lpText == NULL) || (uSize < 1)) return(FALSE);
+	lpText[0] = '\0';
+	switch(uError) {
+		case MIDIERR_UNPREPARED:
+			msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
+			break;
+		case MIDIERR_STILLPLAYING:
+			msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
+			break;
+		case MIDIERR_NOMAP:
+			msgptr = "A MIDI map was not found. There may be a problem with the driver, or the MIDIMAP.CFG file may be corrupt or missing.";
+			break;
+		case MIDIERR_NOTREADY:
+			msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
+			break;
+		case MIDIERR_NODEVICE:
+			msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.";
+			break;
+		case MIDIERR_INVALIDSETUP:
+			msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
+			break;
+/*
+msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
+msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
+msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
+msg# 339 : The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.
+msg# 340 : An error occurred using the specified port.
+msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
+msg# 342 : There is no current MIDI port.
+msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
+*/
+		default:
+			msgptr = "Unkown MIDI Error !\n";
+			break;
+		}
+	maxbuf = min(uSize - 1, strlen(msgptr));
+	strncpy(lpText, msgptr, maxbuf);
+	lpText[maxbuf + 1] = '\0';
+	return(TRUE);
+}
+
+
+UINT WINAPI midiOutOpen(HMIDIOUT FAR* lphMidiOut, UINT uDeviceID,
+    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+	printf("midiOutOpen\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
+{
+	printf("midiOutClose\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut,
+    MIDIHDR FAR* lpMidiOutHdr, UINT uSize)
+{
+	printf("midiOutPrepareHeader\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut,
+    MIDIHDR FAR* lpMidiOutHdr, UINT uSize)
+{
+	printf("midiOutUnprepareHeader\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
+{
+	printf("midiOutShortMsg\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
+    MIDIHDR FAR* lpMidiOutHdr, UINT uSize)
+{
+	printf("midiOutLongMsg\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
+{
+	printf("midiOutReset\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut,
+    UINT uBank, WORD FAR* lpwPatchArray, UINT uFlags)
+{
+	printf("midiOutCachePatches\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut,
+    UINT uPatch, WORD FAR* lpwKeyArray, UINT uFlags)
+{
+	printf("midiOutCacheDrumPatches\n");
+	return 0;
+}
+
+
+UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT FAR* lpuDeviceID)
+{
+	printf("midiOutGetID\n");
+	return 0;
+}
+
+
+DWORD WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage, DWORD dw1, DWORD dw2)
+{
+	printf("midiOutMessage\n");
+	return 0;
+}
+
+
+
+
+UINT WINAPI midiInGetNumDevs(void)
+{
+	printf("midiInGetNumDevs\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiInGetDevCaps(UINT uDeviceID,
+    LPMIDIINCAPS lpCaps, UINT uSize)
+{
+	printf("midiInGetDevCaps\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiInGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
+{
+	printf("midiInGetErrorText\n");
+	return (midiGetErrorText(uError, lpText, uSize));
+}
+
+
+
+UINT WINAPI midiInOpen(HMIDIIN FAR* lphMidiIn, UINT uDeviceID,
+    DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+	printf("midiInOpen\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiInClose(HMIDIIN hMidiIn)
+{
+	printf("midiInClose\n");
+	return 0;
+}
+
+
+
+
+UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT FAR* lpuDeviceID)
+{
+	printf("midiInGetID\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn,
+    MIDIHDR FAR* lpMidiInHdr, UINT uSize)
+{
+	printf("midiInPrepareHeader\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn,
+    MIDIHDR FAR* lpMidiInHdr, UINT uSize)
+{
+	printf("midiInUnprepareHeader\n");
+	return 0;
+}
+
+
+
+UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn,
+    MIDIHDR FAR* lpMidiInHdr, UINT uSize)
+{
+	printf("midiInAddBuffer\n");
+	return 0;
+}
+
+
+UINT WINAPI midiInStart(HMIDIIN hMidiIn)
+{
+	printf("midiInStart\n");
+	return 0;
+}
+
+
+UINT WINAPI midiInStop(HMIDIIN hMidiIn)
+{
+printf("midiInStop\n");
+return 0;
+}
+
+
+
+UINT WINAPI midiInReset(HMIDIIN hMidiIn)
+{
+printf("midiInReset\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutGetNumDevs()
+{
+printf("waveOutGetNumDevs\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutGetDevCaps(UINT uDeviceID, WAVEOUTCAPS FAR* lpCaps, UINT uSize)
+{
+printf("waveOutGetDevCaps\n");
+return 0;
+}
+
+
+UINT WINAPI waveOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
+{
+   printf("waveOutGetErrorText\n");
+   return(waveGetErrorText(uError, lpText, uSize));
+}
+
+
+UINT WINAPI waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
+{
+   if ((lpText == NULL) || (uSize < 1)) return(FALSE);
+   lpText[0] = '\0';
+   switch(uError)
+      {
+      case MMSYSERR_NOERROR:
+         sprintf(lpText, "The specified command was carried out.");
+         break;
+      case MMSYSERR_ERROR:
+         sprintf(lpText, "Undefined external error.");
+         break;
+      case MMSYSERR_BADDEVICEID:
+         sprintf(lpText, "A device ID has been used that is out of range for your system.");
+         break;
+      case MMSYSERR_NOTENABLED:
+         sprintf(lpText, "The driver was not enabled.");
+         break;
+      case MMSYSERR_ALLOCATED:
+         sprintf(lpText, "The specified device is already in use. Wait until it is free, and then try again.");
+         break;
+      case MMSYSERR_INVALHANDLE:
+         sprintf(lpText, "The specified device handle is invalid.");
+         break;
+      case MMSYSERR_NODRIVER:
+         sprintf(lpText, "There is no driver installed on your system !\n");
+         break;
+      case MMSYSERR_NOMEM:
+         sprintf(lpText, "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.");
+         break;
+      case MMSYSERR_NOTSUPPORTED:
+         sprintf(lpText, "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.");
+         break;
+      case MMSYSERR_BADERRNUM:
+         sprintf(lpText, "An error number was specified that is not defined in the system.");
+         break;
+      case MMSYSERR_INVALFLAG:
+         sprintf(lpText, "An invalid flag was passed to a system function.");
+         break;
+      case MMSYSERR_INVALPARAM:
+         sprintf(lpText, "An invalid parameter was passed to a system function.");
+         break;
+      case WAVERR_BADFORMAT:
+         sprintf(lpText, "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats");
+         break;
+      case WAVERR_STILLPLAYING:
+         sprintf(lpText, "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.");
+         break;
+      case WAVERR_UNPREPARED:
+         sprintf(lpText, "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.");
+         break;
+      case WAVERR_SYNC:
+         sprintf(lpText, "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.");
+         break;
+         
+      default:
+         sprintf(lpText, "Unkown MMSYSTEM Error !\n");
+         break;
+      }
+   lpText[uSize - 1] = '\0';
+   return(TRUE);
+}
+
+
+UINT WINAPI waveOutOpen(HWAVEOUT FAR* lphWaveOut, UINT uDeviceID,
+    const WAVEFORMAT FAR* lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+printf("waveOutOpen\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
+{
+printf("waveOutClose\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut,
+     WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
+{
+printf("waveOutPrepareHeader\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
+    WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
+{
+printf("waveOutUnprepareHeader\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, WAVEHDR FAR* lpWaveOutHdr,  UINT uSize)
+{
+printf("waveOutWrite\n");
+return 0;
+}
+
+
+UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
+{
+printf("waveOutPause\n");
+return 0;
+}
+
+
+UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
+{
+printf("waveOutRestart\n");
+return 0;
+}
+
+
+UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
+{
+printf("waveOutReset\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, MMTIME FAR* lpInfo, UINT uSize)
+{
+printf("waveOutGetPosition\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
+{
+printf("waveOutGetVolume\n");
+return 0;
+}
+
+
+UINT WINAPI waveOutSetVolume(UINT uDeviceID, DWORD dwVolume)
+{
+printf("waveOutSetVolume\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT FAR* lpuDeviceID)
+{
+printf("waveOutGetID\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, DWORD FAR* lpdwPitch)
+{
+printf("waveOutGetPitch\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dwPitch)
+{
+printf("waveOutSetPitch\n");
+return 0;
+}
+
+
+UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, DWORD FAR* lpdwRate)
+{
+printf("waveOutGetPlaybackRate\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dwRate)
+{
+printf("waveOutSetPlaybackRate\n");
+return 0;
+}
+
+
+
+
+UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
+{
+printf("waveOutBreakLoop\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveInGetNumDevs()
+{
+printf("waveInGetNumDevs\n");
+return 0;
+}
+
+
+UINT WINAPI waveInGetDevCaps(UINT uDeviceID, WAVEINCAPS FAR* lpCaps, UINT uSize)
+{
+printf("waveInGetDevCaps\n");
+return 0;
+}
+
+
+UINT WINAPI waveInGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
+{
+   printf("waveInGetErrorText\n");
+   return(waveGetErrorText(uError, lpText, uSize));
+}
+
+
+UINT WINAPI waveInOpen(HWAVEIN FAR* lphWaveIn, UINT uDeviceID,
+    const WAVEFORMAT FAR* lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+printf("waveInOpen\n");
+return 0;
+}
+
+
+UINT WINAPI waveInClose(HWAVEIN hWaveIn)
+{
+printf("waveInClose\n");
+return 0;
+}
+
+
+UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize)
+{
+printf("waveInPrepareHeader\n");
+return 0;
+}
+
+
+UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize)
+{
+printf("waveInUnprepareHeader\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize)
+{
+printf("waveInAddBuffer\n");
+return 0;
+}
+
+UINT WINAPI waveInReset(HWAVEIN hWaveIn)
+{
+printf("waveInReset\n");
+return 0;
+}
+
+
+UINT WINAPI waveInStart(HWAVEIN hWaveIn)
+{
+printf("waveInStart\n");
+return 0;
+}
+
+
+UINT WINAPI waveInStop(HWAVEIN hWaveIn)
+{
+printf("waveInStop\n");
+return 0;
+}
+
+
+
+UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, MMTIME FAR* lpInfo, UINT uSize)
+{
+printf("waveInGetPosition\n");
+return 0;
+}
+
+
+UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT FAR* lpuDeviceID)
+{
+printf("waveInGetID\n");
+return 0;
+}
+
+
+/*
+UINT WINAPI mciGetDeviceIDFromElementID (DWORD dwElementID,
+    LPCSTR lpstrType);
+
+BOOL WINAPI mciSetYieldProc (UINT uDeviceID, YIELDPROC fpYieldProc,
+    DWORD dwYieldData);
+
+HTASK WINAPI mciGetCreatorTask(UINT uDeviceID);
+YIELDPROC WINAPI mciGetYieldProc (UINT uDeviceID, DWORD FAR* lpdwYieldData);
+
+
+FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT uFlags);
+LPMMIOPROC WINAPI mmioInstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
+    DWORD dwFlags);
+UINT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags);
+UINT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO FAR* lpmmioinfo, UINT uFlags);
+UINT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer,
+    UINT uFlags);
+UINT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags);
+UINT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags);
+LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
+    LPARAM lParam1, LPARAM lParam2);
+UINT WINAPI mmioDescend(HMMIO hmmio, MMCKINFO FAR* lpck,
+    const MMCKINFO FAR* lpckParent, UINT uFlags);
+UINT WINAPI mmioAscend(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags);
+UINT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags);
+
+DWORD WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage, DWORD dw1, DWORD dw2);
+
+
+DWORD WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD dw1, DWORD dw2);
+
+UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
+    WAVEHDR FAR* lpWaveInHdr, UINT uSize);
+DWORD WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD dw1, DWORD dw2);
+
+*/
+
diff --git a/misc/network.c b/misc/network.c
new file mode 100644
index 0000000..60a4bb3
--- /dev/null
+++ b/misc/network.c
@@ -0,0 +1,119 @@
+/*
+ * Network functions
+ */
+
+#include "stdio.h"
+#include "windows.h"
+#include "win.h"
+#include "user.h"
+
+#define WN_SUCCESS       			0x0000
+#define WN_NOT_SUPPORTED 			0x0001
+#define WN_NET_ERROR     			0x0002
+#define WN_MORE_DATA     			0x0003
+#define WN_BAD_POINTER   			0x0004
+#define WN_BAD_VALUE     			0x0005
+#define WN_BAD_PASSWORD  			0x0006
+#define WN_ACCESS_DENIED 			0x0007
+#define WN_FUNCTION_BUSY 			0x0008
+#define WN_WINDOWS_ERROR 			0x0009
+#define WN_BAD_USER      			0x000A
+#define WN_OUT_OF_MEMORY 			0x000B
+#define WN_CANCEL        			0x000C
+#define WN_CONTINUE      			0x000D
+#define WN_NOT_CONNECTED 			0x0030
+#define WN_OPEN_FILES    			0x0031
+#define WN_BAD_NETNAME   			0x0032
+#define WN_BAD_LOCALNAME 			0x0033
+#define WN_ALREADY_CONNECTED		0x0034
+#define WN_DEVICE_ERROR     		0x0035
+#define WN_CONNECTION_CLOSED		0x0036
+
+typedef LPSTR 	LPNETRESOURCE;
+
+/**************************************************************************
+ *				WNetGetConnection	[USER.512]
+ */
+int WNetGetConnection(LPSTR lpLocalName, 
+	LPSTR lpRemoteName, UINT FAR *cbRemoteName)
+{
+	printf("EMPTY STUB !!! WNetGetConnection('%s', %08X, %08X);\n", 
+		lpLocalName, lpRemoteName, cbRemoteName);
+	return	WN_NET_ERROR;
+}
+
+/**************************************************************************
+ *				WNetGetUser			[USER.516]
+ */
+UINT WNetGetUser(LPSTR lpLocalName, LPSTR lpUserName, DWORD *lpSize)
+{
+	printf("EMPTY STUB !!! WNetGetUser('%s', %08X, %08X);\n", 
+							lpLocalName, lpUserName, lpSize);
+	return WN_NET_ERROR;
+}
+
+/**************************************************************************
+ *				WNetAddConnection	[USER.517]
+ */
+UINT WNetAddConnection(LPSTR lpNetPath, LPSTR lpPassWord, LPSTR lpLocalName)
+{
+	printf("EMPTY STUB !!! WNetAddConnection('%s', %08X, '%s');\n",
+							lpNetPath, lpPassWord, lpLocalName);
+	return WN_NET_ERROR;
+}
+
+
+/**************************************************************************
+ *				WNetCancelConnection	[USER.518]
+ */
+UINT WNetCancelConnection(LPSTR lpName, BOOL bForce)
+{
+	printf("EMPTY STUB !!! WNetCancelConnection('%s', %04X);\n",
+											lpName, bForce);
+	return	WN_NET_ERROR;
+}
+
+/**************************************************************************
+ *				WNetAddConnection2	[USER.???]
+ */
+UINT WNetAddConnection2(LPSTR lpNetPath, LPSTR lpPassWord, 
+		LPSTR lpLocalName, LPSTR lpUserName)
+{
+	printf("EMPTY STUB !!! WNetAddConnection2('%s', %08X, '%s', '%s');\n",
+					lpNetPath, lpPassWord, lpLocalName, lpUserName);
+	return WN_NET_ERROR;
+}
+
+/**************************************************************************
+ *				WNetCloseEnum		[USER.???]
+ */
+UINT WNetCloseEnum(HANDLE hEnum)
+{
+	printf("EMPTY STUB !!! WNetCloseEnum(%04X);\n", hEnum);
+	return WN_NET_ERROR;
+}
+
+/**************************************************************************
+ *				WNetEnumResource	[USER.???]
+ */
+UINT WNetEnumResource(HANDLE hEnum, DWORD cRequ, 
+				DWORD *lpCount, LPVOID lpBuf)
+{
+	printf("EMPTY STUB !!! WNetEnumResource(%04X, %08X, %08X, %08X);\n", 
+							hEnum, cRequ, lpCount, lpBuf);
+	return WN_NET_ERROR;
+}
+
+/**************************************************************************
+ *				WNetOpenEnum		[USER.???]
+ */
+UINT WNetOpenEnum(DWORD dwScope, DWORD dwType, 
+	LPNETRESOURCE lpNet, HANDLE FAR *lphEnum)
+{
+	printf("EMPTY STUB !!! WNetOpenEnum(%08X, %08X, %08X, %08X);\n",
+							dwScope, dwType, lpNet, lphEnum);
+	return WN_NET_ERROR;
+}
+
+
+
diff --git a/misc/profile.c b/misc/profile.c
index 377924a..84cf8f5 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -64,15 +64,34 @@
     return 0;
 }
 
-static TSecHeader *load (char *file)
+static char *GetIniFileName(char *name)
+{
+	char temp[256];
+
+	if (strchr(name, '/'))
+		return name;
+
+	if (strchr(name, '\\'))
+		return GetUnixFileName(name);
+		
+	GetWindowsDirectory(temp, sizeof(temp) );
+	strcat(temp, "\\");
+	strcat(temp, name);
+	
+	return GetUnixFileName(name);
+}
+
+static TSecHeader *load (char *filename)
 {
     FILE *f;
     int state;
     TSecHeader *SecHeader = 0;
     char CharBuffer [STRSIZE];
-    char *next;
+    char *next, *file;
     char c;
-    
+
+    file = GetIniFileName(filename);
+
 #ifdef DEBUG
     printf("Load %s\n", file);
 #endif		
@@ -82,6 +101,8 @@
 #ifdef DEBUG
     printf("Loading %s\n", file);
 #endif		
+
+
     state = FirstBrace;
     while ((c = getc (f)) != EOF){
 	if (c == '\r')		/* Ignore Carriage Return */
@@ -337,13 +358,13 @@
     if (!p)
 	return;
     dump_profile (p->link);
-    if ((profile = fopen (p->FileName, "w")) != NULL){
+    if ((profile = fopen (GetIniFileName(p->FileName), "w")) != NULL){
 	dump_sections (profile, p->Section);
 	fclose (profile);
     }
 }
 
-void sync_profiles ()
+void sync_profiles (void)
 {
     dump_profile (Base);
 }
diff --git a/misc/property.c b/misc/property.c
new file mode 100644
index 0000000..55abcb9
--- /dev/null
+++ b/misc/property.c
@@ -0,0 +1,197 @@
+/*
+ * 				Windows Properties Functions
+ */
+static char Copyright[] = "Copyright Martin Ayotte, 1994";
+
+#define DEBUG_PROP
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "windows.h"
+#include "heap.h"
+#include "win.h"
+
+typedef struct {
+	LPSTR		PropName;
+	WORD		Atom;
+	HANDLE		hData;
+	void		*lpPrevProp;
+	void		*lpNextProp;
+} PROPENTRY;
+typedef PROPENTRY *LPPROPENTRY;
+
+
+/*************************************************************************
+ *				RemoveProp			[USER.24]
+ */
+HANDLE RemoveProp(HWND hWnd, LPSTR lpStr)
+{
+    WND 		*wndPtr;
+	LPPROPENTRY lpProp;
+	HANDLE		hOldData;
+#ifdef DEBUG_PROP
+	if (((DWORD)lpStr & 0xFFFF0000) == 0L)
+		printf("RemoveProp(%04X, Atom %04X)\n", hWnd, LOWORD((DWORD)lpStr));
+	else
+		printf("RemoveProp(%04X, '%s')\n", hWnd, lpStr);
+#endif
+	wndPtr = WIN_FindWndPtr(hWnd);
+    if (wndPtr == NULL) {
+    	printf("RemoveProp // Bad Window handle !\n");
+    	return FALSE;
+    	}
+	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
+	if (lpProp == NULL) return 0;
+	while (TRUE) {
+		if (strcmp(lpProp->PropName, lpStr) == 0) {
+		   	printf("RemoveProp // Property found ! hData=%04X\n", lpProp->hData);
+			hOldData = lpProp->hData;
+			if (lpProp->lpPrevProp != NULL) 
+				((LPPROPENTRY)lpProp->lpPrevProp)->lpNextProp = 
+											lpProp->lpNextProp;
+			if (lpProp->lpNextProp != NULL) 
+				((LPPROPENTRY)lpProp->lpNextProp)->lpPrevProp = 
+											lpProp->lpPrevProp;
+			free(lpProp->PropName);
+			free(lpProp);
+			GlobalUnlock(wndPtr->hProp);
+			return hOldData;
+			}
+		if (lpProp->lpNextProp == NULL) break;
+		lpProp = lpProp->lpNextProp;
+		}
+	GlobalUnlock(wndPtr->hProp);
+   	printf("RemoveProp // Property not found !\n");
+	return 0;
+}
+
+
+/*************************************************************************
+ *				GetProp			[USER.25]
+ */
+HANDLE GetProp(HWND hWnd, LPSTR lpStr)
+{
+    WND 		*wndPtr;
+	LPPROPENTRY lpProp;
+#ifdef DEBUG_PROP
+	if (((DWORD)lpStr & 0xFFFF0000) == 0L)
+		printf("GetProp(%04X, Atom %04X)\n", hWnd, LOWORD((DWORD)lpStr));
+	else
+		printf("GetProp(%04X, '%s')\n", hWnd, lpStr);
+#endif
+	wndPtr = WIN_FindWndPtr(hWnd);
+    if (wndPtr == NULL) {
+    	printf("GetProp // Bad Window handle !\n");
+    	return FALSE;
+    	}
+	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
+	if (lpProp == NULL) return 0;
+	while (TRUE) {
+		if ((((DWORD)lpStr & 0xFFFF0000) == 0L && 
+			lpProp->Atom == LOWORD((DWORD)lpStr)) ||
+			(((DWORD)lpStr & 0xFFFF0000) != 0L && 
+			strcmp(lpProp->PropName, lpStr) == 0)) {
+		   	printf("GetProp // Property found ! hData=%04X\n", lpProp->hData);
+			GlobalUnlock(wndPtr->hProp);
+			return lpProp->hData;
+			}
+		if (lpProp->lpNextProp == NULL) break;
+		lpProp = lpProp->lpNextProp;
+		}
+   	printf("GetProp // Property not found !\n");
+	GlobalUnlock(wndPtr->hProp);
+	return 0;
+}
+
+
+/*************************************************************************
+ *				SetProp			[USER.26]
+ */
+BOOL SetProp(HWND hWnd, LPSTR lpStr, HANDLE hData)
+{
+    WND 		*wndPtr;
+    HANDLE 		hNewProp;
+	LPPROPENTRY lpNewProp;
+	LPPROPENTRY lpProp;
+#ifdef DEBUG_PROP
+	if (((DWORD)lpStr & 0xFFFF0000) == 0L)
+		printf("SetProp(%04X, Atom %04X, %04X)\n", 
+				hWnd, LOWORD((DWORD)lpStr), hData);
+	else
+		printf("SetProp(%04X, '%s', %04X)\n", hWnd, lpStr, hData);
+#endif
+	wndPtr = WIN_FindWndPtr(hWnd);
+    if (wndPtr == NULL) {
+    	printf("SetProp // Bad Window handle !\n");
+    	return FALSE;
+    	}
+	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
+	if (lpProp != NULL) {
+		while (TRUE) {
+			if (strcmp(lpProp->PropName, lpStr) == 0) {
+#ifdef DEBUG_PROP
+			    printf("SetProp // change already exinsting property !\n");
+#endif
+				lpProp->hData = hData;
+				GlobalUnlock(wndPtr->hProp);
+				return TRUE;
+				}
+			if (lpProp->lpNextProp == NULL) break;
+			lpProp = lpProp->lpNextProp;
+			}
+		}
+	hNewProp = GlobalAlloc(GMEM_MOVEABLE, sizeof(PROPENTRY));
+	lpNewProp = (LPPROPENTRY) GlobalLock(hNewProp);
+	if (lpNewProp == NULL) {
+    	printf("SetProp // Can't allocate Property entry !\n");
+		GlobalUnlock(wndPtr->hProp);
+    	return FALSE;
+		}
+#ifdef DEBUG_PROP
+    printf("SetProp // entry allocated %08X\n", lpNewProp);
+#endif
+	if (lpProp == NULL) {
+		wndPtr->hProp = hNewProp;
+		lpNewProp->lpPrevProp = NULL;
+#ifdef DEBUG_PROP
+	    printf("SetProp // first entry \n");
+#endif
+		}
+	else {
+		lpProp->lpNextProp = lpNewProp;
+		lpNewProp->lpPrevProp = lpProp;
+		}
+	lpNewProp->lpNextProp = NULL;
+	lpNewProp->hData = hData;
+	if (((DWORD)lpStr & 0xFFFF0000) == 0L) {
+		lpNewProp->PropName = NULL;
+		lpNewProp->Atom = LOWORD((DWORD)lpStr);
+		}
+	else {
+		lpNewProp->Atom = 0;
+		lpNewProp->PropName = malloc(strlen(lpStr));
+		if (lpNewProp->PropName == NULL) {
+	    	printf("SetProp // Can't allocate memory for Property Name !\n");
+			GlobalUnlock(wndPtr->hProp);
+    		return FALSE;
+			}
+		strcpy(lpNewProp->PropName, lpStr);
+		}
+	GlobalUnlock(hNewProp);
+	GlobalUnlock(wndPtr->hProp);
+	return TRUE;
+}
+
+
+/*************************************************************************
+ *				EnumProps			[USER.27]
+ */
+int EnumProps(HWND hWnd, FARPROC lpEnumFunc)
+{
+	printf("EMPTY STUB !!! EnumProps(%04X, %08X)\n", hWnd, lpEnumFunc);
+	return -1;
+}
+
+
diff --git a/misc/shell.c b/misc/shell.c
new file mode 100644
index 0000000..f60d9ff
--- /dev/null
+++ b/misc/shell.c
@@ -0,0 +1,71 @@
+/*
+ * 				Shell Library Functions
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "windows.h"
+
+
+/*************************************************************************
+ *				RegOpenKey			[SHELL.1]
+ */
+int RegOpenKey(void) 
+{
+	printf("RegOpenKey : Empty Stub !!!\n");
+}
+
+/*************************************************************************
+ *				RegCreateKey		[SHELL.2]
+ */
+int RegCreateKey(void) 
+{
+	printf("RegCreateKey : Empty Stub !!!\n");
+}
+
+/*************************************************************************
+ *				RegCloseKey			[SHELL.3]
+ */
+int RegCloseKey(void) 
+{
+	printf("RegCloseKey : Empty Stub !!!\n");
+}
+
+/*************************************************************************
+ *				RegDeleteKey		[SHELL.4]
+ */
+int RegDeleteKey(void) 
+{
+	printf("RegDeleteKey : Empty Stub !!!\n");
+}
+
+
+/*************************************************************************
+ *				ShellExecute		[SHELL.20]
+ */
+int ShellExecute(LPSTR ptr)
+{
+	printf("ShellExecute : Empty Stub !!!\n");
+}
+
+
+/*************************************************************************
+ *				RegisterShellHook	[SHELL.102]
+ */
+int RegisterShellHook(void *ptr) 
+{
+	printf("RegisterShellHook : Empty Stub !!!\n");
+}
+
+/*************************************************************************
+ *				ShellHookProc		[SHELL.103]
+ */
+int ShellHookProc(void) 
+{
+	printf("ShellHookProc : Empty Stub !!!\n");
+}
+
+
+
diff --git a/misc/spy.c b/misc/spy.c
index bfc0042..c52db35 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -104,8 +104,17 @@
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x00A0 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_NCMOUSEMOVE",		/* 0x00A0 */
+    "WM_NCLBUTTONDOWN",		/* 0x00A1 */
+    "WM_NCLBUTTONUP",		/* 0x00A2 */
+    "WM_NCLBUTTONDBLCLK",	/* 0x00A3 */
+    "WM_NCRBUTTONDOWN",		/* 0x00A4 */
+    "WM_NCRBUTTONUP",		/* 0x00A5 */
+    "WM_NCRBUTTONDBLCLK",	/* 0x00A6 */
+    "WM_NCMBUTTONDOWN",		/* 0x00A7 */
+    "WM_NCMBUTTONUP",		/* 0x00A8 */
+    "WM_NCMBUTTONDBLCLK",	/* 0x00A9 */
+    NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x00B0 */
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -248,7 +257,7 @@
 	return;
     
     if (msg > SPY_MAX_MSGNUM || MessageTypeNames[msg] == NULL)
-	msg_name[0] = '\0';
+	sprintf(msg_name, "%04x", msg);
     else
 	strcpy(msg_name, MessageTypeNames[msg]);
     
diff --git a/misc/winsocket.c b/misc/winsocket.c
index 0d520db..ea56ca8 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -11,112 +11,206 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <fcntl.h>
 #include <errno.h>
 #include <netdb.h>
 #include <unistd.h>
+#include "heap.h"
 #include "winsock.h"
 
 #define DEBUG_WINSOCK
 
-/* XXX per task */
-WORD wsa_errno;
-int  wsa_initted;
+static WORD wsa_errno;
+static int wsa_initted;
 
-WORD errno_to_wsaerrno(int errno)
+#define dump_sockaddr(a) \
+	fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
+			((struct sockaddr_in *)a)->sin_family, \
+			inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
+			ntohs(((struct sockaddr_in *)a)->sin_port))
+
+struct WinSockHeap {
+	char	ntoa_buffer[32];
+
+	struct	hostent hostent_addr;
+	struct	hostent hostent_name;
+	struct	protoent protoent_name;
+	struct	protoent protoent_number;
+	struct	servent servent_name;
+	struct	servent servent_port;
+
+	struct	hostent WSAhostent_addr;
+	struct	hostent WSAhostent_name;
+	struct	protoent WSAprotoent_name;
+	struct	protoent WSAprotoent_number;	
+	struct	servent WSAservent_name;
+	struct	servent WSAservent_port;
+};
+
+static struct WinSockHeap *heap;
+
+static WORD wsaerrno(void)
 {
-        switch(errno) {
-        case ENETDOWN:
-                return WSAENETDOWN;
-        case EAFNOSUPPORT:
-                return WSAEAFNOSUPPORT;
-        case EMFILE:
-                return WSAEMFILE;
-        case ENOBUFS:
-                return WSAENOBUFS;
-        case EPROTONOSUPPORT:
-                return EPROTONOSUPPORT;
-        case EPROTOTYPE:
-                return WSAEPROTOTYPE;
-	case EBADF:
-	case ENOTSOCK:
-		return WSAENOTSOCK;
-
-        default:
+#ifdef DEBUG_WINSOCK
 #ifndef sun
 #if defined(__FreeBSD__)
-                fprintf(stderr, "winsock: errno_to_wsaerrno translation failure.\n\t: %s (%d)\n",
-                        sys_errlist[errno], errno);
+                fprintf(stderr, "winsock: errno %d, (%s).\n", 
+                			errno, sys_errlist[errno]);
 #else
-                fprintf(stderr, "winsock: errno_to_wsaerrno translation failure.\n\t: %s (%d)\n",
-                        strerror[errno], errno);
+                fprintf(stderr, "winsock: errno %d, (%s).\n", 
+                			errno, strerror(errno));
 #endif
 #else
-		fprintf (stderr, "winsock: errno_to_wsaerrno translation failure.\n");
+                fprintf(stderr, "winsock: errno %d\n", errno);
 #endif
-		return WSAENETDOWN;
-        }
+#endif
+
+        switch(errno)
+        {
+	case EINTR:		return WSAEINTR;
+	case EACCES:		return WSAEACCES;
+	case EFAULT:		return WSAEFAULT;
+	case EINVAL:		return WSAEINVAL;
+	case EMFILE:		return WSAEMFILE;
+	case EWOULDBLOCK:	return WSAEWOULDBLOCK;
+	case EINPROGRESS:	return WSAEINPROGRESS;
+	case EALREADY:		return WSAEALREADY;
+	case EBADF:
+	case ENOTSOCK:		return WSAENOTSOCK;
+	case EDESTADDRREQ:	return WSAEDESTADDRREQ;
+	case EMSGSIZE:		return WSAEMSGSIZE;
+	case EPROTOTYPE:	return WSAEPROTOTYPE;
+	case ENOPROTOOPT:	return WSAENOPROTOOPT;
+	case EPROTONOSUPPORT:	return WSAEPROTONOSUPPORT;
+	case ESOCKTNOSUPPORT:	return WSAESOCKTNOSUPPORT;
+	case EOPNOTSUPP:	return WSAEOPNOTSUPP;
+	case EPFNOSUPPORT:	return WSAEPFNOSUPPORT;
+	case EAFNOSUPPORT:	return WSAEAFNOSUPPORT;
+	case EADDRINUSE:	return WSAEADDRINUSE;
+	case EADDRNOTAVAIL:	return WSAEADDRNOTAVAIL;
+	case ENETDOWN:		return WSAENETDOWN;
+	case ENETUNREACH:	return WSAENETUNREACH;
+	case ENETRESET:		return WSAENETRESET;
+	case ECONNABORTED:	return WSAECONNABORTED;
+	case ECONNRESET:	return WSAECONNRESET;
+	case ENOBUFS:		return WSAENOBUFS;
+	case EISCONN:		return WSAEISCONN;
+	case ENOTCONN:		return WSAENOTCONN;
+	case ESHUTDOWN:		return WSAESHUTDOWN;
+	case ETOOMANYREFS:	return WSAETOOMANYREFS;
+	case ETIMEDOUT:		return WSAETIMEDOUT;
+	case ECONNREFUSED:	return WSAECONNREFUSED;
+	case ELOOP:		return WSAELOOP;
+	case ENAMETOOLONG:	return WSAENAMETOOLONG;
+	case EHOSTDOWN:		return WSAEHOSTDOWN;
+	case EHOSTUNREACH:	return WSAEHOSTUNREACH;
+	case ENOTEMPTY:		return WSAENOTEMPTY;
+/*	case EPROCLIM:		return WSAEPROCLIM; */
+	case EUSERS:		return WSAEUSERS;
+	case EDQUOT:		return WSAEDQUOT;
+	case ESTALE:		return WSAESTALE;
+	case EREMOTE:		return WSAEREMOTE;
+
+        default:
+		fprintf(stderr, "winsock: unknown error!\n");
+		return WSAEOPNOTSUPP;
+	}
+}
+
+static WORD errno_to_wsaerrno(void)
+{
+	wsa_errno = wsaerrno();
 }
  
-SOCKET Winsock_accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen)
+SOCKET Winsock_accept(SOCKET s, struct sockaddr FAR *addr, INT FAR *addrlen)
 {
 	int sock;
 
-	if ((sock = accept(s, addr, addrlen)) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_accept: socket %d, ptr %8x, length %d\n", s, (int) addr, addrlen);
+#endif
+
+	if ((sock = accept(s, addr, (int *) addrlen)) < 0) {
+        	errno_to_wsaerrno();
         	return INVALID_SOCKET;
 	}
 	return sock;
 }
 
-int Winsock_bind(SOCKET s, struct sockaddr FAR *name, int namelen)
+INT Winsock_bind(SOCKET s, struct sockaddr FAR *name, INT namelen)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_bind: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
+	dump_sockaddr(name);
+#endif
+
 	if (bind(s, name, namelen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-int Winsock_closesocket(SOCKET s)
+INT Winsock_closesocket(SOCKET s)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_closesocket: socket %d\n", s);
+#endif
+
 	if (close(s) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-int Winsock_connect(SOCKET s, struct sockaddr FAR *name, int namelen)
+INT Winsock_connect(SOCKET s, struct sockaddr FAR *name, INT namelen)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_connect: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
+	dump_sockaddr(name);
+#endif
+
 	if (connect(s, name, namelen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-int Winsock_getpeername(SOCKET s, struct sockaddr FAR *name, int FAR *namelen)
+INT Winsock_getpeername(SOCKET s, struct sockaddr FAR *name, INT FAR *namelen)
 {
-	if (getpeername(s, name, namelen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
+	dump_sockaddr(name);
+#endif
+
+	if (getpeername(s, name, (int *) namelen) < 0) {
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-int Winsock_getsockname(SOCKET s, struct sockaddr FAR *name, int FAR *namelen)
+INT Winsock_getsockname(SOCKET s, struct sockaddr FAR *name, INT FAR *namelen)
 {
-	if (getsockname(s, name, namelen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);
+#endif
+	if (getsockname(s, name, (int *) namelen) < 0) {
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-int Winsock_getsockopt(SOCKET s, int loptname, char FAR *optval, int FAR *optlen)
+INT Winsock_getsockopt(SOCKET s, INT loptname, char FAR *optval, INT FAR *optlen)
 {
-	if (getsockopt(s, 0, loptname, optval, optlen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, loptname, (int) optval, (int) *optlen);
+#endif
+	if (getsockopt(s, 0, (int) loptname, optval, (int *) optlen) < 0) {
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -141,26 +235,41 @@
 {
 	char *s;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_inet_ntoa: %8x\n", in);
+#endif
+
 	if ((s = inet_ntoa(in)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return NULL;
 	}
-	return s;
+
+	strncpy(heap->ntoa_buffer, s, sizeof(heap->ntoa_buffer) );
+
+	return (char *) &heap->ntoa_buffer;
 }
 
-int Winsock_ioctlsocket(SOCKET s, long cmd, u_long FAR *argp)
+INT Winsock_ioctlsocket(SOCKET s, long cmd, u_long FAR *argp)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_ioctl: socket %d, cmd %d, ptr %8x\n", s, cmd, (int) argp);
+#endif
+
 	if (ioctl(s, cmd, argp) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-int Winsock_listen(SOCKET s, int backlog)
+INT Winsock_listen(SOCKET s, INT backlog)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_listen: socket %d, backlog %d\n", s, backlog);
+#endif
+
 	if (listen(s, backlog) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -176,125 +285,174 @@
 	return( ntohs(netshort) );
 }
 
-int Winsock_recv(SOCKET s, char FAR *buf, int len, int flags)
+INT Winsock_recv(SOCKET s, char FAR *buf, INT len, INT flags)
 {
 	int length;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s, (int) buf, len, flags);
+#endif
+
 	if ((length = recv(s, buf, len, flags)) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return length;
 }
 
-int Winsock_recvfrom(SOCKET s, char FAR *buf, int len, int flags, 
+INT Winsock_recvfrom(SOCKET s, char FAR *buf, INT len, INT flags, 
 		struct sockaddr FAR *from, int FAR *fromlen)
 {
 	int length;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_recvfrom: socket %d, ptr %8x, length %d, flags %d\n", s, buf, len, flags);
+#endif
+
 	if ((length = recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return length;
 }
 
-int Winsock_select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds,
+INT Winsock_select(INT nfds, fd_set FAR *readfds, fd_set FAR *writefds,
 	fd_set FAR *exceptfds, struct timeval FAR *timeout)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_select: fd # %d, ptr %8x, ptr %8x, ptr %*X\n", nfds, readfds, writefds, exceptfds);
+#endif
+
 	return(select(nfds, readfds, writefds, exceptfds, timeout));
 }
 
-int Winsock_send(SOCKET s, char FAR *buf, int len, int flags)
+INT Winsock_send(SOCKET s, char FAR *buf, INT len, INT flags)
 {
 	int length;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_send: socket %d, ptr %8x, length %d, flags %d\n", s, buf, len, flags);
+#endif
+
 	if ((length = send(s, buf, len, flags)) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return length;
 }
 
-int Winsock_sendto(SOCKET s, char FAR *buf, int len, int flags,
-		struct sockaddr FAR *to, int tolen)
+INT Winsock_sendto(SOCKET s, char FAR *buf, INT len, INT flags,
+		struct sockaddr FAR *to, INT tolen)
 {
 	int length;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_sendto: socket %d, ptr %8x, length %d, flags %d\n", s, buf, len, flags);
+#endif
+
 	if ((length = sendto(s, buf, len, flags, to, tolen)) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return length;
 }
 
-int Winsock_setsockopt(SOCKET s, int level, int optname, const char FAR *optval, 
-		int optlen)
+INT Winsock_setsockopt(SOCKET s, INT level, INT optname, const char FAR *optval, 
+			INT optlen)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s, level, optname, (int) optval, optlen);
+#endif
+
 	if (setsockopt(s, level, optname, optval, optlen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }                                         
 
-int Winsock_shutdown(SOCKET s, int how)
+INT Winsock_shutdown(SOCKET s, INT how)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_shutdown: socket s %d, how %d\n", s, how);
+#endif
+
 	if (shutdown(s, how) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
 }
 
-SOCKET Winsock_socket(WORD af, WORD type, WORD protocol)
+SOCKET Winsock_socket(INT af, INT type, INT protocol)
 {
     int sock;
 
 #ifdef DEBUG_WINSOCK
-    printf("Winsock_socket: af=%d type=%d protocol=%d\n", af, type, protocol);
+    fprintf(stderr, "WSA_socket: af=%d type=%d protocol=%d\n", af, type, protocol);
 #endif
 
-/*  let the kernel do the dirty work..
-
-    if (!wsa_initted) {
-            wsa_errno = WSANOTINITIALISED;
-            return INVALID_SOCKET;
-    }
-*/
     if ((sock = socket(af, type, protocol)) < 0) {
-            wsa_errno = errno_to_wsaerrno(errno);
+            errno_to_wsaerrno();
+#ifdef DEBUG_WINSOCK
+    fprintf(stderr, "WSA_socket: failed !\n");
+#endif
             return INVALID_SOCKET;
     }
+    if (sock > 0xffff) {
+	wsa_errno = WSAEMFILE;
+	return INVALID_SOCKET;
+    }
+
+#ifdef DEBUG_WINSOCK
+    fprintf(stderr, "WSA_socket: fd %d\n", sock);
+#endif
     return sock;
 }
 
-struct hostent *Winsock_gethostbyaddr(const char FAR *addr, int len,  int type)
+struct hostent *Winsock_gethostbyaddr(const char FAR *addr, INT len, INT type)
 {
 	struct hostent *host;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr, len, type);
+#endif
+
 	if ((host = gethostbyaddr(addr, len, type)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return NULL;
 	}
-	return host;
+	memcpy(&heap->hostent_addr, host, sizeof(struct hostent));
+
+	return (struct hostent *) &heap->hostent_addr;
 }
 
 struct hostent *Winsock_gethostbyname(const char FAR *name)
 {
 	struct hostent *host;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_gethostbyname: name %s\n", name);
+#endif
+
 	if ((host = gethostbyname(name)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return NULL;
 	}
-	return host;
+	memcpy(&heap->hostent_name, host, sizeof(struct hostent));
+
+	return (struct hostent *) &heap->hostent_name;
 }
 
-int Winsock_gethostname(char FAR *name, int namelen)
+int Winsock_gethostname(char FAR *name, INT namelen)
 {
+
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_gethostname: name %d, len %d\n", name, namelen);
+#endif
+
 	if (gethostname(name, namelen) < 0) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -304,125 +462,238 @@
 {
 	struct protoent *proto;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getprotobyname: name %s\n", name);
+#endif
+
 	if ((proto = getprotobyname(name)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return NULL;
 	}
-	return proto;
+	memcpy(&heap->protoent_name, proto, sizeof(struct protoent));
+
+	return (struct protoent *) &heap->protoent_name;
 }
 
-struct protoent *Winsock_getprotobynumber(int number)
+struct protoent *Winsock_getprotobynumber(INT number)
 {
 	struct protoent *proto;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getprotobynumber: num %d\n", number);
+#endif
+
 	if ((proto = getprotobynumber(number)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return NULL;
 	}
-	return proto;
+	memcpy(&heap->protoent_number, proto, sizeof(struct protoent));
+
+	return (struct protoent *) &heap->protoent_number;
 }
 
 struct servent *Winsock_getservbyname(const char FAR *name, const char FAR *proto)
 {
 	struct servent *service;
 
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getservbyname: name %s, proto %s\n", name, proto);
+#endif
+
 	if ((service = getservbyname(name, proto)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
+        	errno_to_wsaerrno();
         	return NULL;
 	}
-	return service;
+	memcpy(&heap->servent_name, service, sizeof(struct servent));
+
+	return (struct servent *) &heap->servent_name;
 }
 
-struct servent *Winsock_getservbyport(int port, const char FAR *proto)
+struct servent *Winsock_getservbyport(INT port, const char FAR *proto)
+{
+	struct servent *service;
+
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_getservbyport: port %d, name %s\n", port, proto);
+#endif
+
+	if ((service = getservbyport(port, proto)) == NULL) {
+        	errno_to_wsaerrno();
+        	return NULL;
+	}
+	memcpy(&heap->servent_port, service, sizeof(struct servent));
+
+	return (struct servent *) &heap->servent_port;
+}
+
+/******************** winsock specific functions ************************/
+
+HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char FAR *addr,
+		 INT len, INT type, char FAR *buf, INT buflen)
+{
+	struct hostent *host;
+
+	if ((host = gethostbyaddr(addr, len, type)) == NULL) {
+		PostMessage(hWnd, wMsg, 1, wsaerrno() << 8);
+
+		return 1;
+	}
+
+	memcpy(buf, host, buflen);
+	PostMessage(hWnd, wMsg, 1, 0);
+
+	return 1;
+}                    
+
+HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, const char FAR *name, 
+			char FAR *buf, INT buflen)
+{
+	struct hostent *host;
+
+	if ((host = gethostbyname(name)) == NULL) {
+		PostMessage(hWnd, wMsg, 2, wsaerrno() << 8);
+		return 2;
+	}
+
+	memcpy(buf, host, buflen);
+	PostMessage(hWnd, wMsg, 2, 0);
+
+	return 2;
+}                     
+
+HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, const char FAR *name, 
+			char FAR *buf, INT buflen)
+{
+	struct protoent *proto;
+
+	if ((proto = getprotobyname(name)) == NULL) {
+		PostMessage(hWnd, wMsg, 3, wsaerrno() << 8);
+		return 3;
+	}
+
+	memcpy(buf, proto, buflen);
+	PostMessage(hWnd, wMsg, 3, 0);
+
+	return 3;
+}
+
+HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, INT number, 
+			char FAR *buf, INT buflen)
+{
+	struct protoent *proto;
+
+	if ((proto = getprotobynumber(number)) == NULL) {
+		PostMessage(hWnd, wMsg, 4, wsaerrno() << 8);
+		return 4;
+	}
+
+	memcpy(buf, proto, buflen);
+	PostMessage(hWnd, wMsg, 4, 0);
+
+	return 4;
+}
+
+HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, const char FAR *name, 
+			const char FAR *proto, char FAR *buf, INT buflen)
+{
+	struct servent *service;
+
+	if ((service = getservbyname(name, proto)) == NULL) {
+		PostMessage(hWnd, wMsg, 5, wsaerrno() << 8);
+        
+        	return 5;
+	}
+	memcpy(buf, service, buflen);
+	PostMessage(hWnd, wMsg, 5, 0);
+	
+	return 5;
+}
+
+HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port, const char FAR 
+			*proto, char FAR *buf, INT buflen)
 {
 	struct servent *service;
 
 	if ((service = getservbyport(port, proto)) == NULL) {
-        	wsa_errno = errno_to_wsaerrno(errno);
-        	return NULL;
+		PostMessage(hWnd, wMsg, 6, wsaerrno() << 8);
+        
+        	return 6;
 	}
-	return service;
+	memcpy(buf, service, buflen);
+	PostMessage(hWnd, wMsg, 6, 0);
+	
+	return 6;
 }
 
-HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char FAR *addr,
-		 int len, int type, const char FAR *buf, int buflen)
+INT WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_AsyncSelect: socket %d, HWND %d, wMsg %d, event %d\n", s, hWnd, wMsg, lEvent);
+#endif
+	fcntl(s, F_SETFL, O_NONBLOCK);
 
-}                    
 
-HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, const char FAR *name, 
-			char FAR *buf, int buflen)
-{
-
-}                     
-
-HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, const char FAR *name, 
-			char FAR *buf, int buflen)
-{
-
+	return 0;
 }
 
-HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, int number, 
-			char FAR *buf, int buflen)
-{
-
-}
-
-HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, const char FAR *name, 
-			const char FAR *proto, char FAR *buf, int buflen)
-{
-
-}
-
-HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port, const char FAR 
-			*proto, char FAR *buf, int buflen)
-{
-
-}
-
-int WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent)
-{
-
-}
-
-int WSAFDIsSet(int fd, fd_set *set)
+INT WSAFDIsSet(INT fd, fd_set *set)
 {
 	return( FD_ISSET(fd, set) );
 }
 
-WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
+INT WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
 {
-
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_AsyncRequest: handle %d\n", hAsyncTaskHandle);
+#endif
+	return 0;
 }
 
-WSACancelBlockingCall ( void )
+INT WSACancelBlockingCall(void)
 {
-
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_CancelBlockCall\n");
+#endif
+	return 0;
 }
           
-int WSAGetLastError(void)
+INT WSAGetLastError(void)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_GetLastError\n");
+#endif
+
     return wsa_errno;
 }
 
-void WSASetLastError(int iError)
+void WSASetLastError(INT iError)
 {
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_SetLastErorr %d\n", iError);
+#endif
+
     wsa_errno = iError;
 }
 
-BOOL WSAIsBlocking (void)
+BOOL WSAIsBlocking(void)
 {
-
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_IsBlocking\n");
+#endif
 }
 
 FARPROC WSASetBlockingHook(FARPROC lpBlockFunc)
 {
-
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_SetBlockHook\n %8x", lpBlockFunc);
+#endif
 }
 
-int WSAUnhookBlockingHook(void)
+INT WSAUnhookBlockingHook(void)
 {
-
+#ifdef DEBUG_WINSOCK
+	fprintf(stderr, "WSA_UnhookBlockingHook\n");
+#endif
 }
 
 WSADATA Winsock_data = {
@@ -443,8 +714,11 @@
         NULL
 };
 
-int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
+INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
 {
+	int HeapHandle;
+	MDESC *MyHeap;
+
 #ifdef DEBUG_WINSOCK
     fprintf(stderr, "WSAStartup: verReq=%x\n", wVersionRequested);
 #endif
@@ -452,10 +726,16 @@
     if (LOBYTE(wVersionRequested) < 1 ||
         (LOBYTE(wVersionRequested) == 1 &&
          HIBYTE(wVersionRequested) < 1))
-        return WSAVERNOTSUPPORTED;
+	return WSAVERNOTSUPPORTED;
 
     if (!lpWSAData)
         return WSAEINVAL;
+
+    if ((HeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct WinSockHeap))) == 0)
+	return WSASYSNOTREADY;
+
+    heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
+    HEAP_Init(&MyHeap, heap, sizeof(struct WinSockHeap));
     
     bcopy(&Winsock_data, lpWSAData, sizeof(Winsock_data));
 
@@ -464,7 +744,7 @@
     return(0);
 }
 
-int WSACleanup(void)
+INT WSACleanup(void)
 {
     wsa_initted = 0;
     return 0;
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 0f932bd..9ecc0d5 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include "msdos.h"
 #include "wine.h"
 
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index 0d25a77..ee2f27f 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -1,5 +1,6 @@
 #include <time.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include "msdos.h"
 #include "wine.h"
 
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 350f9e0..d0f8003 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -1246,7 +1246,9 @@
 		EBX = DOSVERSION;
 		EDX = 0x00;
 		break;
+
 	      default:
+		Barf(context);
 		break;			
 	    }
 	    break;	
@@ -1505,6 +1507,10 @@
 	    }
 	    break;
 
+	  case 0x67: /* SET HANDLE COUNT */			
+	    ResetCflag;
+	    break;
+
 	  case 0x68: /* "FFLUSH" - COMMIT FILE */
 	    ResetCflag;
 	    break;		
@@ -1525,9 +1531,6 @@
 	    ResetCflag;
 	    break;		
 
-	  case 0x67: /* SET HANDLE COUNT */			
-	    ResetCflag;
-	    break;
 
 	  default:
             Barf(context);
diff --git a/miscemu/int25.c b/miscemu/int25.c
index f08c7a9..89d188d 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include "msdos.h"
 #include "wine.h"
 
@@ -15,15 +16,12 @@
 
 		dataptr = (BYTE *) getdword(&dataptr[6]);
 			
-		fprintf(stderr, "int25: abs diskread, drive %d, sector %d, "
-	"count %d, buffer %d\n", EAX & 0xff, begin, length, (int) dataptr);
+	} else {
+		begin = EDX & 0xffff;
+		length = ECX & 0xffff;
 	}
-
-	begin = EDX & 0xffff;
-	length = ECX & 0xffff;
-	
-	fprintf(stderr,"int25: abs diskread-2, drive %d, sector %d, count %d,"
-		" buffer %d\n", EAX & 0xff, begin, length, (int) dataptr);
+	fprintf(stderr, "int25: abs diskread, drive %d, sector %d, "
+	"count %d, buffer %d\n", EAX & 0xff, begin, length, (int) dataptr);
 
 	ResetCflag;
 	return 1;
diff --git a/miscemu/int26.c b/miscemu/int26.c
index c4f8464..5fb86a3 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include "msdos.h"
 #include "wine.h"
 
@@ -13,14 +14,12 @@
 		length = getword(&dataptr[4]);
 		dataptr = (BYTE *) getdword(&dataptr[6]);
 			
-		fprintf(stderr, "int26: abs diskread, drive %d, sector %d, "
-	"count %d, buffer %d\n", EAX & 0xff, begin, length, (int) dataptr);
+	} else {
+		begin = EDX & 0xffff;
+		length = ECX & 0xffff;
 	}
-
-	begin = EDX & 0xffff;
-	length = ECX & 0xffff;
-	
-	fprintf(stderr,"int26: abs diskread-2, drive %d, sector %d, count %d,"
+		
+	fprintf(stderr,"int26: abs diskwrite, drive %d, sector %d, count %d,"
 		" buffer %d\n", EAX & 0xff, begin, length, (int) dataptr);
 
 	ResetCflag;
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
new file mode 100644
index 0000000..4780766
--- /dev/null
+++ b/miscemu/int2f.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "msdos.h"
+#include "wine.h"
+
+static void Barf(struct sigcontext_struct *context)
+{
+	fprintf(stderr, "int2f: unknown/not implemented parameters:\n");
+	fprintf(stderr, "int2f: AX %04x, BX %04x, CX %04x, DX %04x, "
+	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
+	       AX, BX, CX, DX, SI, DI, DS, ES);
+}
+
+int do_int2f(struct sigcontext_struct *context)
+{
+	switch(context->sc_eax & 0xffff)
+	{
+	case 0x1600: /* windows enhanced mode install check */
+		/* don't return anything as we're running in standard mode */
+		break;
+
+	default:
+		Barf(context);
+	};
+	return 1;
+}
diff --git a/miscemu/ioports.c b/miscemu/ioports.c
index 44fa971..bb2c877 100644
--- a/miscemu/ioports.c
+++ b/miscemu/ioports.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include <time.h>
 #include "msdos.h"
 #include "wine.h"
diff --git a/objects/font.c b/objects/font.c
index 382976b..b346d8a 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -348,6 +348,16 @@
 }
 
 
+/***********************************************************************
+ *           SetMapperFlags    (GDI.349)
+ */
+DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
+{
+    printf("SetmapperFlags(%04X, %08X) // Empty Stub !\n", hDC, dwFlag); 
+    return 0L;
+}
+
+ 
 /***********************************************************************/
 
 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
@@ -379,16 +389,6 @@
 
 
 /***********************************************************************
- *           SetMapperFlags    (GDI.349)
- */
-DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
-{
-    printf("SetmapperFlags(%04X, %08X) // Empty Stub !\n", hDC, dwFlag); 
-    return 0L;
-}
-
- 
-/***********************************************************************
  *           GetCharWidth    (GDI.350)
  */
 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
@@ -415,6 +415,22 @@
     {
 	CI_GET_CHAR_INFO(xfont, i, def, cs);
 	*(lpBuffer + j) = cs->width;
+	if (*(lpBuffer + j) < 0)
+	    *(lpBuffer + j) = 0;
     }
     return TRUE;
 }
+
+
+/*************************************************************************
+ *				EnumFonts			[GDI.70]
+ */
+int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpFontFunc, LPSTR lpData)
+{
+	printf("EMPTY STUB !!! EnumFonts(%04X, %08X, %08X, %08X)\n", 
+						hDC, lpFaceName, lpFontFunc, lpData);
+	return -1;
+}
+
+
+
diff --git a/objects/metafile.c b/objects/metafile.c
new file mode 100644
index 0000000..903cfa7
--- /dev/null
+++ b/objects/metafile.c
@@ -0,0 +1,444 @@
+/*
+ * Metafile functions
+ *
+ * Copyright  David W. Metcalfe, 1994
+ */
+
+static char Copyright[] = "Copyright  David W. Metcalfe, 1994";
+
+#include "windows.h"
+#include "gdi.h"
+#include "metafile.h"
+#include "prototypes.h"
+
+#define DEBUG_METAFILE
+
+/******************************************************************
+ *         CreateMetafile         GDI.125
+ */
+HANDLE CreateMetaFile(LPSTR lpFilename)
+{
+    DC *dc;
+    HANDLE handle;
+    METAFILE *mf;
+    METAHEADER *mh;
+
+#ifdef DEBUG_METAFILE
+    printf("CreateMetaFile: %s\n", lpFilename);
+#endif
+
+    handle = GDI_AllocObject(sizeof(DC), METAFILE_DC_MAGIC);
+    if (!handle) return 0;
+    dc = (DC *)GDI_HEAP_ADDR(handle);
+
+    if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE))))
+	return 0;
+    mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    if (!(mf->hMetaHdr = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAHEADER))))
+    {
+	GlobalFree(dc->w.hMetaFile);
+	return 0;
+    }
+    mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    mf->wMagic = METAFILE_MAGIC;
+    mh->mtHeaderSize = MFHEADERSIZE / 2;
+    mh->mtVersion = MFVERSION;
+    mh->mtSize = MFHEADERSIZE / 2;
+    mh->mtNoObjects = 0;
+    mh->mtMaxRecord = 0;
+    mh->mtNoParameters = 0;
+
+    if (lpFilename)          /* disk based metafile */
+    {
+	mh->mtType = 1;
+	strcpy(mf->Filename, lpFilename);
+	mf->hFile = _lcreat(lpFilename, 0);
+	if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
+	{
+	    GlobalFree(mf->hMetaHdr);
+	    GlobalFree(dc->w.hMetaFile);
+	    return 0;
+	}
+    }
+    else                     /* memory based metafile */
+	mh->mtType = 0;
+
+    GlobalUnlock(mf->hMetaHdr);
+    GlobalUnlock(dc->w.hMetaFile);
+    return handle;
+}
+
+
+/******************************************************************
+ *         CloseMetafile         GDI.126
+ */
+HMETAFILE CloseMetaFile(HDC hdc)
+{
+    DC *dc;
+    METAFILE *mf;
+    METAHEADER *mh;
+    HMETAFILE hmf;
+    char buffer[15];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+#ifdef DEBUG_METAFILE
+    printf("CloseMetaFile\n");
+#endif
+
+    dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+    if (!dc) return 0;
+    mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    /* Construct the end of metafile record - this is undocumented
+     * but is created by MS Windows 3.1.
+     */
+    mr->rdSize = 3;
+    mr->rdFunction = META_EOF;
+    MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+
+    if (mh->mtType == 1)        /* disk based metafile */
+    {
+	if (_llseek(mf->hFile, 0L, 0) == -1)
+	{
+	    GlobalFree(mf->hMetaHdr);
+	    GlobalFree(dc->w.hMetaFile);
+	    return 0;
+	}
+	if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
+	{
+	    GlobalFree(mf->hMetaHdr);
+	    GlobalFree(dc->w.hMetaFile);
+	    return 0;
+	}
+	_lclose(mf->hFile);
+    }
+
+    GlobalUnlock(mf->hMetaHdr);
+    hmf = dc->w.hMetaFile;
+    GDI_FreeObject(hdc);
+    return hmf;
+}
+
+
+/******************************************************************
+ *         DeleteMetafile         GDI.127
+ */
+BOOL DeleteMetaFile(HMETAFILE hmf)
+{
+    METAFILE *mf = (METAFILE *)GlobalLock(hmf);
+
+    if (mf->wMagic != METAFILE_MAGIC)
+	return FALSE;
+
+    GlobalFree(mf->hMetaHdr);
+    GlobalFree(hmf);
+    return TRUE;
+}
+
+
+/******************************************************************
+ *         MF_WriteRecord
+ */
+BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
+{
+    DWORD len;
+    METAFILE *mf = (METAFILE *)GlobalLock(hmf);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    if (mh->mtType == 0)          /* memory based metafile */
+    {
+	len = mh->mtSize * 2 + rlen;
+	GlobalUnlock(mf->hMetaHdr);
+	mf->hMetaHdr = GlobalReAlloc(mf->hMetaHdr, len, GMEM_MOVEABLE);
+	mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+	memcpy(mh + mh->mtSize * 2, mr, rlen);
+    }
+    else if (mh->mtType == 1)     /* disk based metafile */
+    {
+	if (_lwrite(mf->hFile, (char *)mr, rlen) == -1)
+	{
+	    GlobalUnlock(mf->hMetaHdr);
+	    return FALSE;
+	}
+    }
+    else
+    {
+	GlobalUnlock(mf->hMetaHdr);
+	return FALSE;
+    }
+
+    mh->mtSize += rlen / 2;
+    mh->mtMaxRecord = max(mh->mtMaxRecord, rlen / 2);
+    GlobalUnlock(mf->hMetaHdr);
+    return TRUE;
+}
+
+
+/******************************************************************
+ *         MF_MetaParam1
+ */
+BOOL MF_MetaParam1(DC *dc, short func, short param1)
+{
+    char buffer[8];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 4;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam2
+ */
+BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2)
+{
+    char buffer[10];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 5;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param2;
+    *(mr->rdParam + 1) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam4
+ */
+BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4)
+{
+    char buffer[14];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 7;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param4;
+    *(mr->rdParam + 1) = param3;
+    *(mr->rdParam + 2) = param2;
+    *(mr->rdParam + 3) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam6
+ */
+BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4, short param5, short param6)
+{
+    char buffer[18];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 9;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param6;
+    *(mr->rdParam + 1) = param5;
+    *(mr->rdParam + 2) = param4;
+    *(mr->rdParam + 3) = param3;
+    *(mr->rdParam + 4) = param2;
+    *(mr->rdParam + 5) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam8
+ */
+BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4, short param5,
+		   short param6, short param7, short param8)
+{
+    char buffer[22];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 11;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param8;
+    *(mr->rdParam + 1) = param7;
+    *(mr->rdParam + 2) = param6;
+    *(mr->rdParam + 3) = param5;
+    *(mr->rdParam + 4) = param4;
+    *(mr->rdParam + 5) = param3;
+    *(mr->rdParam + 6) = param2;
+    *(mr->rdParam + 7) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_CreateBrushIndirect
+ */
+BOOL MF_CreateBrushIndirect(DC *dc, LOGBRUSH *logbrush)
+{
+    char buffer[sizeof(METARECORD) - 2 + sizeof(LOGBRUSH)];
+    METARECORD *mr = (METARECORD *)&buffer;
+    METAFILE *mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+#ifdef DEBUG_METAFILE
+    printf("MF_CreateBrushIndirect\n");
+#endif
+    mr->rdSize = (sizeof(METARECORD) + sizeof(LOGBRUSH) - 2) / 2;
+    mr->rdFunction = META_CREATEBRUSHINDIRECT;
+    memcpy(&(mr->rdParam), logbrush, sizeof(LOGBRUSH));
+    if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
+	return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+    *(mr->rdParam) = mh->mtNoObjects++;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_CreatePatternBrush
+ */
+BOOL MF_CreatePatternBrush(DC *dc, LOGBRUSH *logbrush)
+{
+    DWORD len, bmSize, biSize;
+    HANDLE hmr;
+    METARECORD *mr;
+    BITMAPOBJ *bmp;
+    BITMAPINFO *info;
+    char buffer[sizeof(METARECORD)];
+    METAFILE *mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    switch (logbrush->lbStyle)
+    {
+    case BS_PATTERN:
+	bmp = (BITMAPOBJ *)GDI_GetObjPtr(logbrush->lbHatch, BITMAP_MAGIC);
+	if (!bmp) return FALSE;
+	len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) + 
+	      (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 2;
+	if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	    return FALSE;
+	mr = (METARECORD *)GlobalLock(hmr);
+	memset(mr, 0, len);
+	mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+	mr->rdSize = len / 2;
+	*(mr->rdParam) = logbrush->lbStyle;
+	memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 2, 
+	       bmp->bitmap.bmBits, 
+	       bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
+	break;
+
+    case BS_DIBPATTERN:
+	info = (BITMAPINFO *)GlobalLock(logbrush->lbHatch);
+	bmSize = info->bmiHeader.biSizeImage;
+	if (!bmSize)
+	    bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount 
+		    + 31) / 32 * 8 * info->bmiHeader.biHeight;
+	biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor)); 
+	len = sizeof(METARECORD) + biSize + bmSize + 2;
+	if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	    return FALSE;
+	mr = (METARECORD *)GlobalLock(hmr);
+	memset(mr, 0, len);
+	mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+	mr->rdSize = len / 2;
+	*(mr->rdParam) = logbrush->lbStyle;
+	*(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
+	memcpy(mr->rdParam + 2, info, biSize + bmSize);
+	break;
+    }
+    if (!MF_WriteRecord(dc->w.hMetaFile, mr, len))
+    {
+	GlobalFree(hmr);
+	return FALSE;
+    }
+
+    GlobalFree(hmr);
+    mr = (METARECORD *)&buffer;
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+    (WORD)(*(mr->rdParam)) = mh->mtNoObjects++;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_CreatePenIndirect
+ */
+BOOL MF_CreatePenIndirect(DC *dc, LOGPEN *logpen)
+{
+    char buffer[sizeof(METARECORD) - 2 + sizeof(LOGPEN)];
+    METARECORD *mr = (METARECORD *)&buffer;
+    METAFILE *mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+#ifdef DEBUG_METAFILE
+    printf("MF_CreatePenIndirect\n");
+#endif
+    mr->rdSize = (sizeof(METARECORD) + sizeof(LOGPEN) - 2) / 2;
+    mr->rdFunction = META_CREATEPENINDIRECT;
+    memcpy(&(mr->rdParam), logpen, sizeof(LOGPEN));
+    if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
+	return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+    (WORD)(*(mr->rdParam)) = mh->mtNoObjects++;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_TextOut
+ */
+BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count)
+{
+    BOOL rc;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+
+    len = sizeof(METARECORD) + count + 4;
+    if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock(hmr);
+    memset(mr, 0, len);
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = META_TEXTOUT;
+    *(mr->rdParam) = count;
+    memcpy(mr->rdParam + 1, str, count);
+    *(mr->rdParam + (count / 2) + 1) = y;
+    *(mr->rdParam + (count / 2) + 2) = x;
+    rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+    GlobalFree(hmr);
+    return rc;
+}
+
+
+/******************************************************************
+ *         MF_MetaPoly - implements Polygon and Polyline
+ */
+BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count)
+{
+    BOOL rc;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+
+    len = sizeof(METARECORD) + (count * 4); 
+    if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock(hmr);
+    memset(mr, 0, len);
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = func;
+    *(mr->rdParam) = count;
+    memcpy(mr->rdParam + 1, pt, count * 4);
+    rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+    GlobalFree(hmr);
+    return rc;
+}
diff --git a/objects/text.c b/objects/text.c
index a900baa..ae01b20 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -7,7 +7,7 @@
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
 #include <X11/Xatom.h>
-
+#include "windows.h"
 #include "gdi.h"
 
 #define TAB     9
@@ -265,7 +265,7 @@
 	y = dc->w.CursPosY;
     }
 #ifdef DEBUG_TEXT
-    printf( "TextOut: %d,%d '%s'\n", x, y, str );
+    printf( "TextOut: %d,%d '%s', %d\n", x, y, str, count );
 #endif
     x = XLPTODP( dc, x );
     y = YLPTODP( dc, y );
@@ -381,3 +381,25 @@
     
     return TRUE;
 }
+
+/***********************************************************************
+ *		GrayString (USER.185)
+ */
+BOOL GrayString(HDC hdc, HBRUSH hbr, FARPROC gsprc, LPARAM lParam, 
+		INT cch, INT x, INT y, INT cx, INT cy)
+{
+	int s, current_color;
+
+	if (gsprc) {
+		return CallGrayStringProc(gsprc, hdc, lParam, 
+					cch ? cch : lstrlen((LPCSTR) lParam) );
+	} else {
+		current_color = GetTextColor(hdc);
+		SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT) );
+		s = TextOut(hdc, x, y, (LPSTR) lParam, 
+				cch ? cch : lstrlen((LPCSTR) lParam) );
+		SetTextColor(hdc, current_color);
+		
+		return s;
+	}
+}
diff --git a/oem2ansi.trl b/oem2ansi.trl
deleted file mode 100755
index 20ab9f4..0000000
--- a/oem2ansi.trl
+++ /dev/null
Binary files differ
diff --git a/oemansi.exe b/oemansi.exe
deleted file mode 100755
index 46c907f..0000000
--- a/oemansi.exe
+++ /dev/null
Binary files differ
diff --git a/sysres.dll b/sysres.dll
deleted file mode 100755
index 8b55d67..0000000
--- a/sysres.dll
+++ /dev/null
Binary files differ
diff --git a/test/blandmdi.exe b/test/blandmdi.exe
deleted file mode 100644
index 6dc03d5..0000000
--- a/test/blandmdi.exe
+++ /dev/null
Binary files differ
diff --git a/test/widget.exe b/test/widget.exe
deleted file mode 100755
index 6d8fb2f..0000000
--- a/test/widget.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Imakefile b/tools/Imakefile
index c993ef4..f3bac38 100644
--- a/tools/Imakefile
+++ b/tools/Imakefile
@@ -6,4 +6,4 @@
 SimpleProgramTarget(build)
 #else
 SimpleProgramTarget(newbuild)
-#endif
\ No newline at end of file
+#endif
diff --git a/tools/build.c b/tools/build.c
index 9b0eada..176dca0 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include "wine.h"
 
 #ifdef linux
 #define UTEXTSEL 0x23
@@ -28,6 +29,46 @@
 
 #define MAX_ORDINALS	1024
 
+#define PUSH_0		"\tpushl\t$0\n"
+#define PUSH_SS		"\tpushw\t$0\n\tpushw\t%%ss\n"
+#define PUSH_ESP	"\tpushl\t%%esp\n"
+#define PUSH_EFL	"\tpushfl\n"
+#define PUSH_CS		"\tpushw\t$0\n\tpushw\t%%cs\n"
+#define PUSH_EIP	"\tpushl\t$0\n"
+#define PUSH_DS		"\tpushw\t$0\n\tpushw\t%%ds\n"
+#define PUSH_ES		"\tpushw\t$0\n\tpushw\t%%es\n"
+#define PUSH_FS		"\tpushw\t$0\n\tpushw\t%%fs\n"
+#define PUSH_GS		"\tpushw\t$0\n\tpushw\t%%gs\n"
+#define PUSH_EAX	"\tpushl\t%%eax\n"
+#define PUSH_ECX	"\tpushl\t%%ecx\n"
+#define PUSH_EDX	"\tpushl\t%%edx\n"
+#define PUSH_EBX	"\tpushl\t%%ebx\n"
+#define PUSH_EBP	"\tpushl\t%%ebp\n"
+#define PUSH_ESI	"\tpushl\t%%esi\n"
+#define PUSH_EDI	"\tpushl\t%%edi\n"
+
+#define POP_0		"\tadd\t$4,%%esp\n"
+#define POP_SS		"\tpopw\t%%ss\n\tadd\t$2,%%esp\n"
+#define POP_ESP		"\tpopl\t%%esp\n"
+#define POP_EFL		"\tpopfl\n"
+#define POP_CS		"\tpopw\t%%cs\n\tadd\t$2,%%esp\n"
+#define POP_EIP		"\tpopl\t$0\n"
+#define POP_DS		"\tpopw\t%%ds\n\tadd\t$2,%%esp\n"
+#define POP_ES		"\tpopw\t%%es\n\tadd\t$2,%%esp\n"
+#define POP_FS		"\tpopw\t%%fs\n\tadd\t$2,%%esp\n"
+#define POP_GS		"\tpopw\t%%gs\n\tadd\t$2,%%esp\n"
+#define POP_EAX		"\tpopl\t%%eax\n"
+#define POP_ECX		"\tpopl\t%%ecx\n"
+#define POP_EDX		"\tpopl\t%%edx\n"
+#define POP_EBX		"\tpopl\t%%ebx\n"
+#define POP_EBP		"\tpopl\t%%ebp\n"
+#define POP_ESI		"\tpopl\t%%esi\n"
+#define POP_EDI		"\tpopl\t%%edi\n"
+
+char **context_strings;
+char **pop_strings;
+int    n_context_strings;
+
 typedef struct ordinal_definition_s
 {
     int valid;
@@ -551,6 +592,74 @@
     return 0;
 }
 
+InitContext()
+{
+    struct sigcontext_struct context;
+    int i;
+    int j;
+    
+    n_context_strings = sizeof(context) / 4;
+    context_strings   = (char **) malloc(n_context_strings * sizeof(char **));
+    pop_strings       = (char **) malloc(n_context_strings * sizeof(char **));
+    for (i = 0; i < n_context_strings; i++)
+    {
+	context_strings[i] = PUSH_0;
+	pop_strings[i]     = POP_0;
+    }
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esp) / 4;
+    context_strings[i] = PUSH_ESP;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebp) / 4;
+    context_strings[i] = PUSH_EBP;
+    pop_strings[n_context_strings - 1 - i] = POP_EBP;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eip) / 4;
+    context_strings[i] = PUSH_EIP;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_efl) / 4;
+    context_strings[i] = PUSH_EFL;
+    pop_strings[n_context_strings - 1 - i] = POP_EFL;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_es) / 4;
+    context_strings[i] = PUSH_ES;
+    pop_strings[n_context_strings - 1 - i] = POP_ES;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ds) / 4;
+    context_strings[i] = PUSH_DS;
+    pop_strings[n_context_strings - 1 - i] = POP_DS;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_cs) / 4;
+    context_strings[i] = PUSH_CS;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ss) / 4;
+    context_strings[i] = PUSH_SS;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edi) / 4;
+    context_strings[i] = PUSH_EDI;
+    pop_strings[n_context_strings - 1 - i] = POP_EDI;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esi) / 4;
+    context_strings[i] = PUSH_ESI;
+    pop_strings[n_context_strings - 1 - i] = POP_ESI;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebx) / 4;
+    context_strings[i] = PUSH_EBX;
+    pop_strings[n_context_strings - 1 - i] = POP_EBX;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edx) / 4;
+    context_strings[i] = PUSH_EDX;
+    pop_strings[n_context_strings - 1 - i] = POP_EDX;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ecx) / 4;
+    context_strings[i] = PUSH_ECX;
+    pop_strings[n_context_strings - 1 - i] = POP_ECX;
+
+    i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eax) / 4;
+    context_strings[i] = PUSH_EAX;
+    pop_strings[n_context_strings - 1 - i] = POP_EAX;
+}
+
 void
 OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
 {
@@ -584,14 +693,46 @@
     char filename[80];
     char buffer[80];
     char *p;
-    int i;
+    int i, ci;
+    int add_count;
     
     if (argc < 2)
     {
-	fprintf(stderr, "usage: build SPECNAME\n");
+	fprintf(stderr, "usage: build SPECNAME\n       build -p\n");
 	exit(1);
     }
 
+    InitContext();
+
+    if (strcmp("-p", argv[1]) == 0)
+    {
+	fp = fopen("pop.h", "w");
+	add_count = 0;
+	for (i = 0; i < n_context_strings; i++)
+	{
+	    if (strncmp(pop_strings[i], "\tadd\t", 5) == 0)
+	    {
+		add_count += atoi(pop_strings[i] + 6);
+	    }
+	    else
+	    {
+		if (add_count > 0)
+		{
+		    fprintf(fp, "\tadd\t$%d,%%esp\n", add_count);
+		    add_count = 0;
+		}
+		
+		fprintf(fp, pop_strings[i]);
+	    }
+	}
+    
+	if (add_count > 0)
+	    fprintf(fp, "\tadd\t$%d,%%esp\n", add_count);
+		
+	fclose(fp);
+	exit(0);
+    }
+
     SpecFp = fopen(argv[1], "r");
     if (SpecFp == NULL)
     {
@@ -619,10 +760,6 @@
 	if (!odp->valid)
 	{
 	    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-#ifdef BOB_SAYS_NO
-	    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-	    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#endif
 	    fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 	    fprintf(fp, "\tpushw\t$0\n");
 	    fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
@@ -667,61 +804,23 @@
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
 		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
 		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-		fprintf(fp, "\tpushl\t$0\n");			/* cr2     */
-		fprintf(fp, "\tpushl\t$0\n");			/* oldmask */
-		fprintf(fp, "\tpushl\t$0\n");			/* i387    */
-		fprintf(fp, "\tpushw\t$0\n");			/* __ssh   */
-		fprintf(fp, "\tpushw\t%%ss\n");			/* ss      */
-		fprintf(fp, "\tpushl\t%%esp\n");		/* esp     */
-		fprintf(fp, "\tpushfl\n");			/* eflags  */
-		fprintf(fp, "\tpushw\t$0\n");			/* __csh   */
-		fprintf(fp, "\tpushw\t%%cs\n");			/* cs      */
-		fprintf(fp, "\tpushl\t$0\n");			/* eip     */
-		fprintf(fp, "\tpushl\t$0\n");			/* err     */
-		fprintf(fp, "\tpushl\t$0\n");			/* trapno  */
-		fprintf(fp, "\tpushal\n");			/* AX, ... */
-		fprintf(fp, "\tpushw\t$0\n");			/* __dsh   */
-		fprintf(fp, "\tpushw\t%%ds\n");			/* ds      */
-		fprintf(fp, "\tpushw\t$0\n");			/* __esh   */
-		fprintf(fp, "\tpushw\t%%es\n");			/* es      */
-		fprintf(fp, "\tpushw\t$0\n");			/* __fsh   */
-		fprintf(fp, "\tpushw\t%%fs\n");			/* fs      */
-		fprintf(fp, "\tpushw\t$0\n");			/* __gsh   */
-		fprintf(fp, "\tpushw\t%%gs\n");			/* gs      */
+
+		for (ci = 0; ci < n_context_strings; ci++)
+		    fprintf(fp, context_strings[ci]);
+
 		fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
 		fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
-		fprintf(fp, "\tpushl\t88(%%ebp)\n");
+		fprintf(fp, "\tpushl\t%d(%%ebp)\n",
+			sizeof(struct sigcontext_struct));
 		fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-		fprintf(fp, "\tpushw\t$92\n");
+		fprintf(fp, "\tpushw\t$%d\n", 
+			sizeof(struct sigcontext_struct) + 4);
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-#if 0
-		fprintf(fp, "\tpushw\t%%ax\n");
-		fprintf(fp, "\tpushw\t%%cx\n");
-		fprintf(fp, "\tpushw\t%%dx\n");
-		fprintf(fp, "\tpushw\t%%bx\n");
-		fprintf(fp, "\tpushw\t%%sp\n");
-		fprintf(fp, "\tpushw\t%%bp\n");
-		fprintf(fp, "\tpushw\t%%si\n");
-		fprintf(fp, "\tpushw\t%%di\n");
-		fprintf(fp, "\tpushw\t%%ds\n");
-		fprintf(fp, "\tpushw\t%%es\n");
-		fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
-		fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
-		fprintf(fp, "\tpushl\t20(%%ebp)\n");
-		fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
-		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-		fprintf(fp, "\tpushw\t$24\n");
-		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-#endif
 		break;
 
 	      case FUNCTYPE_PASCAL:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-#ifdef BOB_SAYS_NO
-		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#endif
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 		fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
@@ -730,10 +829,6 @@
 	      case FUNCTYPE_C:
 	      default:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-#ifdef BOB_SAYS_NO
-		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#endif
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 		fprintf(fp, "\tpushw\t$0\n");
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
diff --git a/tools/build.c.save b/tools/build.c.save
new file mode 100644
index 0000000..9b0eada
--- /dev/null
+++ b/tools/build.c.save
@@ -0,0 +1,847 @@
+static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
+static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef linux
+#define UTEXTSEL 0x23
+#endif
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#define UTEXTSEL 0x1f
+#endif
+
+#define VARTYPE_BYTE	0
+#define VARTYPE_SIGNEDWORD	0
+#define VARTYPE_WORD	1
+#define VARTYPE_LONG	2
+#define VARTYPE_FARPTR	3
+
+#define FUNCTYPE_PASCAL	16
+#define FUNCTYPE_C	17
+#define FUNCTYPE_REG	19
+
+#define EQUATETYPE_ABS	18
+#define TYPE_RETURN	20
+
+#define MAX_ORDINALS	1024
+
+typedef struct ordinal_definition_s
+{
+    int valid;
+    int type;
+    char export_name[80];
+    void *additional_data;
+} ORDDEF;
+
+typedef struct ordinal_variable_definition_s
+{
+    int n_values;
+    int *values;
+} ORDVARDEF;
+
+typedef struct ordinal_function_definition_s
+{
+    int n_args_16;
+    int arg_types_16[16];
+    int arg_16_offsets[16];
+    int arg_16_size;
+    char internal_name[80];
+    int n_args_32;
+    int arg_indices_32[16];
+} ORDFUNCDEF;
+
+typedef struct ordinal_return_definition_s
+{
+    int arg_size;
+    int ret_value;
+} ORDRETDEF;
+
+ORDDEF OrdinalDefinitions[MAX_ORDINALS];
+
+char LowerDLLName[80];
+char UpperDLLName[80];
+int Limit;
+int DLLId;
+FILE *SpecFp;
+
+char *ParseBuffer = NULL;
+char *ParseNext;
+char ParseSaveChar;
+int Line;
+
+int IsNumberString(char *s)
+{
+    while (*s != '\0')
+	if (!isdigit(*s++))
+	    return 0;
+
+    return 1;
+}
+
+char *strlower(char *s)
+{
+    char *p;
+    
+    for(p = s; *p != '\0'; p++)
+	*p = tolower(*p);
+
+    return s;
+}
+
+char *strupper(char *s)
+{
+    char *p;
+    
+    for(p = s; *p != '\0'; p++)
+	*p = toupper(*p);
+
+    return s;
+}
+
+int stricmp(char *s1, char *s2)
+{
+    if (strlen(s1) != strlen(s2))
+	return -1;
+    
+    while (*s1 != '\0')
+	if (*s1++ != *s2++)
+	    return -1;
+    
+    return 0;
+}
+
+char *
+GetTokenInLine(void)
+{
+    char *p;
+    char *token;
+
+    if (ParseNext != ParseBuffer)
+    {
+	if (ParseSaveChar == '\0')
+	    return NULL;
+	*ParseNext = ParseSaveChar;
+    }
+    
+    /*
+     * Remove initial white space.
+     */
+    for (p = ParseNext; isspace(*p); p++)
+	;
+    
+    if (*p == '\0')
+	return NULL;
+    
+    /*
+     * Find end of token.
+     */
+    token = p++;
+    if (*token != '(' && *token != ')')
+	while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
+	    p++;
+    
+    ParseSaveChar = *p;
+    ParseNext = p;
+    *p = '\0';
+
+    return token;
+}
+
+char *
+GetToken(void)
+{
+    char *token;
+
+    if (ParseBuffer == NULL)
+    {
+	ParseBuffer = malloc(512);
+	ParseNext = ParseBuffer;
+	Line++;
+	while (1)
+	{
+	    if (fgets(ParseBuffer, 511, SpecFp) == NULL)
+		return NULL;
+	    if (ParseBuffer[0] != '#')
+		break;
+	}
+    }
+
+    while ((token = GetTokenInLine()) == NULL)
+    {
+	ParseNext = ParseBuffer;
+	Line++;
+	while (1)
+	{
+	    if (fgets(ParseBuffer, 511, SpecFp) == NULL)
+		return NULL;
+	    if (ParseBuffer[0] != '#')
+		break;
+	}
+    }
+
+    return token;
+}
+
+int
+ParseVariable(int ordinal, int type)
+{
+    ORDDEF *odp;
+    ORDVARDEF *vdp;
+    char export_name[80];
+    char *token;
+    char *endptr;
+    int *value_array;
+    int n_values;
+    int value_array_size;
+    
+    strcpy(export_name, GetToken());
+
+    token = GetToken();
+    if (*token != '(')
+    {
+	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
+	exit(1);
+    }
+
+    n_values = 0;
+    value_array_size = 25;
+    value_array = malloc(sizeof(*value_array) * value_array_size);
+    
+    while ((token = GetToken()) != NULL)
+    {
+	if (*token == ')')
+	    break;
+
+	value_array[n_values++] = strtol(token, &endptr, 0);
+	if (n_values == value_array_size)
+	{
+	    value_array_size += 25;
+	    value_array = realloc(value_array, 
+				  sizeof(*value_array) * value_array_size);
+	}
+	
+	if (endptr == NULL || *endptr != '\0')
+	{
+	    fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
+		    token);
+	    exit(1);
+	}
+    }
+    
+    if (token == NULL)
+    {
+	fprintf(stderr, "%d: End of file in variable declaration\n", Line);
+	exit(1);
+    }
+
+    if (ordinal >= MAX_ORDINALS)
+    {
+	fprintf(stderr, "%d: Ordinal number too large\n", Line);
+	exit(1);
+    }
+    
+    odp = &OrdinalDefinitions[ordinal];
+    odp->valid = 1;
+    odp->type = type;
+    strcpy(odp->export_name, export_name);
+    
+    vdp = malloc(sizeof(*vdp));
+    odp->additional_data = vdp;
+    
+    vdp->n_values = n_values;
+    vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
+
+    return 0;
+}
+
+int
+ParseExportFunction(int ordinal, int type)
+{
+    char *token;
+    ORDDEF *odp;
+    ORDFUNCDEF *fdp;
+    int arg_types[16];
+    int i;
+    int arg_num;
+    int current_offset;
+    int arg_size;
+	
+    
+    if (ordinal >= MAX_ORDINALS)
+    {
+	fprintf(stderr, "%d: Ordinal number too large\n", Line);
+	exit(1);
+    }
+    
+    odp = &OrdinalDefinitions[ordinal];
+    strcpy(odp->export_name, GetToken());
+    odp->valid = 1;
+    odp->type = type;
+    fdp = malloc(sizeof(*fdp));
+    odp->additional_data = fdp;
+
+    token = GetToken();
+    if (*token != '(')
+    {
+	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
+	exit(1);
+    }
+
+    fdp->arg_16_size = 0;
+    for (i = 0; i < 16; i++)
+    {
+	token = GetToken();
+	if (*token == ')')
+	    break;
+
+	if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
+	{
+	    fdp->arg_types_16[i] = VARTYPE_WORD;
+	    fdp->arg_16_size += 2;
+	    fdp->arg_16_offsets[i] = 2;
+	}
+	else if (stricmp(token, "s_byte") == 0 || 
+		 stricmp(token, "s_word") == 0)
+	{
+	    fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
+	    fdp->arg_16_size += 2;
+	    fdp->arg_16_offsets[i] = 2;
+	}
+	else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
+	{
+	    fdp->arg_types_16[i] = VARTYPE_LONG;
+	    fdp->arg_16_size += 4;
+	    fdp->arg_16_offsets[i] = 4;
+	}
+	else if (stricmp(token, "ptr") == 0)
+	{
+	    fdp->arg_types_16[i] = VARTYPE_FARPTR;
+	    fdp->arg_16_size += 4;
+	    fdp->arg_16_offsets[i] = 4;
+	}
+	else
+	{
+	    fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
+	    exit(1);
+	}
+    }
+    fdp->n_args_16 = i;
+
+    if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
+    {
+	current_offset = 0;
+	for (i--; i >= 0; i--)
+	{
+	    arg_size = fdp->arg_16_offsets[i];
+	    fdp->arg_16_offsets[i] = current_offset;
+	    current_offset += arg_size;
+	}
+    }
+    else
+    {
+	current_offset = 0;
+	for (i = 0; i < fdp->n_args_16; i++)
+	{
+	    arg_size = fdp->arg_16_offsets[i];
+	    fdp->arg_16_offsets[i] = current_offset;
+	    current_offset += arg_size;
+	}
+    }
+
+    strcpy(fdp->internal_name, GetToken());
+    token = GetToken();
+    if (*token != '(')
+    {
+	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
+	exit(1);
+    }
+    for (i = 0; i < 16; i++)
+    {
+	token = GetToken();
+	if (*token == ')')
+	    break;
+
+	fdp->arg_indices_32[i] = atoi(token);
+	if (fdp->arg_indices_32[i] < 1 || 
+	    fdp->arg_indices_32[i] > fdp->n_args_16)
+	{
+	    fprintf(stderr, "%d: Bad argument index %d\n", Line,
+		    fdp->arg_indices_32[i]);
+	    exit(1);
+	}
+    }
+    fdp->n_args_32 = i;
+
+    return 0;
+}
+
+int
+ParseEquate(int ordinal)
+{
+    ORDDEF *odp;
+    char *token;
+    char *endptr;
+    int value;
+    
+    if (ordinal >= MAX_ORDINALS)
+    {
+	fprintf(stderr, "%d: Ordinal number too large\n", Line);
+	exit(1);
+    }
+    
+    odp = &OrdinalDefinitions[ordinal];
+    strcpy(odp->export_name, GetToken());
+
+    token = GetToken();
+    value = strtol(token, &endptr, 0);
+    if (endptr == NULL || *endptr != '\0')
+    {
+	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
+		token);
+	exit(1);
+    }
+
+    odp->valid = 1;
+    odp->type = EQUATETYPE_ABS;
+    odp->additional_data = (void *) value;
+
+    return 0;
+}
+
+int
+ParseReturn(int ordinal)
+{
+    ORDDEF *odp;
+    ORDRETDEF *rdp;
+    char *token;
+    char *endptr;
+    int value;
+    
+    if (ordinal >= MAX_ORDINALS)
+    {
+	fprintf(stderr, "%d: Ordinal number too large\n", Line);
+	exit(1);
+    }
+
+    rdp = malloc(sizeof(*rdp));
+    
+    odp = &OrdinalDefinitions[ordinal];
+    strcpy(odp->export_name, GetToken());
+    odp->valid = 1;
+    odp->type = TYPE_RETURN;
+    odp->additional_data = rdp;
+
+    token = GetToken();
+    rdp->arg_size = strtol(token, &endptr, 0);
+    if (endptr == NULL || *endptr != '\0')
+    {
+	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
+		token);
+	exit(1);
+    }
+
+    token = GetToken();
+    rdp->ret_value = strtol(token, &endptr, 0);
+    if (endptr == NULL || *endptr != '\0')
+    {
+	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
+		token);
+	exit(1);
+    }
+
+    return 0;
+}
+
+int
+ParseOrdinal(int ordinal)
+{
+    char *token;
+    
+    token = GetToken();
+    if (token == NULL)
+    {
+	fprintf(stderr, "%d: Expected type after ordinal\n", Line);
+	exit(1);
+    }
+
+    if (stricmp(token, "byte") == 0)
+	return ParseVariable(ordinal, VARTYPE_BYTE);
+    else if (stricmp(token, "word") == 0)
+	return ParseVariable(ordinal, VARTYPE_WORD);
+    else if (stricmp(token, "long") == 0)
+	return ParseVariable(ordinal, VARTYPE_LONG);
+    else if (stricmp(token, "c") == 0)
+	return ParseExportFunction(ordinal, FUNCTYPE_C);
+    else if (stricmp(token, "p") == 0)
+	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
+    else if (stricmp(token, "pascal") == 0)
+	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
+    else if (stricmp(token, "register") == 0)
+	return ParseExportFunction(ordinal, FUNCTYPE_REG);
+    else if (stricmp(token, "equate") == 0)
+	return ParseEquate(ordinal);
+    else if (stricmp(token, "return") == 0)
+	return ParseReturn(ordinal);
+    else
+    {
+	fprintf(stderr, 
+		"%d: Expected type after ordinal, found '%s' instead\n",
+		Line, token);
+	exit(1);
+    }
+}
+
+int
+ParseTopLevel(void)
+{
+    char *token;
+    
+    while ((token = GetToken()) != NULL)
+    {
+	if (stricmp(token, "name") == 0)
+	{
+	    strcpy(LowerDLLName, GetToken());
+	    strlower(LowerDLLName);
+
+	    strcpy(UpperDLLName, LowerDLLName);
+	    strupper(UpperDLLName);
+	}
+	else if (stricmp(token, "id") == 0)
+	{
+	    token = GetToken();
+	    if (!IsNumberString(token))
+	    {
+		fprintf(stderr, "%d: Expected number after id\n", Line);
+		exit(1);
+	    }
+	    
+	    DLLId = atoi(token);
+	}
+	else if (stricmp(token, "length") == 0)
+	{
+	    token = GetToken();
+	    if (!IsNumberString(token))
+	    {
+		fprintf(stderr, "%d: Expected number after length\n", Line);
+		exit(1);
+	    }
+
+	    Limit = atoi(token);
+	}
+	else if (IsNumberString(token))
+	{
+	    int ordinal;
+	    int rv;
+	    
+	    ordinal = atoi(token);
+	    if ((rv = ParseOrdinal(ordinal)) < 0)
+		return rv;
+	}
+	else
+	{
+	    fprintf(stderr, 
+		    "%d: Expected name, id, length or ordinal\n", Line);
+	    exit(1);
+	}
+    }
+
+    return 0;
+}
+
+void
+OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
+{
+    ORDVARDEF *vdp;
+    int i;
+
+    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+
+    vdp = odp->additional_data;
+    for (i = 0; i < vdp->n_values; i++)
+    {
+	if ((i & 7) == 0)
+	    fprintf(fp, "\t%s\t", storage);
+	    
+	fprintf(fp, "%d", vdp->values[i]);
+	
+	if ((i & 7) == 7 || i == vdp->n_values - 1)
+	    fprintf(fp, "\n");
+	else
+	    fprintf(fp, ", ");
+    }
+    fprintf(fp, "\n");
+}
+
+main(int argc, char **argv)
+{
+    ORDDEF *odp;
+    ORDFUNCDEF *fdp;
+    ORDRETDEF *rdp;
+    FILE *fp;
+    char filename[80];
+    char buffer[80];
+    char *p;
+    int i;
+    
+    if (argc < 2)
+    {
+	fprintf(stderr, "usage: build SPECNAME\n");
+	exit(1);
+    }
+
+    SpecFp = fopen(argv[1], "r");
+    if (SpecFp == NULL)
+    {
+	fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
+	exit(1);
+    }
+
+    ParseTopLevel();
+
+    sprintf(filename, "dll_%s.S", LowerDLLName);
+    fp = fopen(filename, "w");
+
+    fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
+    fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
+    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+    fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
+    fprintf(fp, "\tjmp\t_CallTo32\n\n");
+
+    odp = OrdinalDefinitions;
+    for (i = 0; i <= Limit; i++, odp++)
+    {
+	fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
+
+	if (!odp->valid)
+	{
+	    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+#ifdef BOB_SAYS_NO
+	    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+	    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+#endif
+	    fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
+	    fprintf(fp, "\tpushw\t$0\n");
+	    fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
+	}
+	else
+	{
+	    fdp = odp->additional_data;
+	    rdp = odp->additional_data;
+	    
+	    switch (odp->type)
+	    {
+	      case EQUATETYPE_ABS:
+		fprintf(fp, "_%s_Ordinal_%d = %d\n\n", 
+			UpperDLLName, i, (int) odp->additional_data);
+		break;
+
+	      case VARTYPE_BYTE:
+		OutputVariableCode(fp, ".byte", odp);
+		break;
+
+	      case VARTYPE_WORD:
+		OutputVariableCode(fp, ".word", odp);
+		break;
+
+	      case VARTYPE_LONG:
+		OutputVariableCode(fp, ".long", odp);
+		break;
+
+	      case TYPE_RETURN:
+		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+		fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
+		fprintf(fp, "\tmovw\t$%d,%%dx\n", 
+			(rdp->ret_value >> 16) & 0xffff);
+		fprintf(fp, "\t.byte\t0x66\n");
+		if (rdp->arg_size != 0)
+		    fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
+		else
+		    fprintf(fp, "\tlret\n");
+		break;
+
+	      case FUNCTYPE_REG:
+		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+		fprintf(fp, "\tpushl\t$0\n");			/* cr2     */
+		fprintf(fp, "\tpushl\t$0\n");			/* oldmask */
+		fprintf(fp, "\tpushl\t$0\n");			/* i387    */
+		fprintf(fp, "\tpushw\t$0\n");			/* __ssh   */
+		fprintf(fp, "\tpushw\t%%ss\n");			/* ss      */
+		fprintf(fp, "\tpushl\t%%esp\n");		/* esp     */
+		fprintf(fp, "\tpushfl\n");			/* eflags  */
+		fprintf(fp, "\tpushw\t$0\n");			/* __csh   */
+		fprintf(fp, "\tpushw\t%%cs\n");			/* cs      */
+		fprintf(fp, "\tpushl\t$0\n");			/* eip     */
+		fprintf(fp, "\tpushl\t$0\n");			/* err     */
+		fprintf(fp, "\tpushl\t$0\n");			/* trapno  */
+		fprintf(fp, "\tpushal\n");			/* AX, ... */
+		fprintf(fp, "\tpushw\t$0\n");			/* __dsh   */
+		fprintf(fp, "\tpushw\t%%ds\n");			/* ds      */
+		fprintf(fp, "\tpushw\t$0\n");			/* __esh   */
+		fprintf(fp, "\tpushw\t%%es\n");			/* es      */
+		fprintf(fp, "\tpushw\t$0\n");			/* __fsh   */
+		fprintf(fp, "\tpushw\t%%fs\n");			/* fs      */
+		fprintf(fp, "\tpushw\t$0\n");			/* __gsh   */
+		fprintf(fp, "\tpushw\t%%gs\n");			/* gs      */
+		fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
+		fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
+		fprintf(fp, "\tpushl\t88(%%ebp)\n");
+		fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
+		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
+		fprintf(fp, "\tpushw\t$92\n");
+		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
+#if 0
+		fprintf(fp, "\tpushw\t%%ax\n");
+		fprintf(fp, "\tpushw\t%%cx\n");
+		fprintf(fp, "\tpushw\t%%dx\n");
+		fprintf(fp, "\tpushw\t%%bx\n");
+		fprintf(fp, "\tpushw\t%%sp\n");
+		fprintf(fp, "\tpushw\t%%bp\n");
+		fprintf(fp, "\tpushw\t%%si\n");
+		fprintf(fp, "\tpushw\t%%di\n");
+		fprintf(fp, "\tpushw\t%%ds\n");
+		fprintf(fp, "\tpushw\t%%es\n");
+		fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
+		fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
+		fprintf(fp, "\tpushl\t20(%%ebp)\n");
+		fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
+		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
+		fprintf(fp, "\tpushw\t$24\n");
+		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
+#endif
+		break;
+
+	      case FUNCTYPE_PASCAL:
+		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+#ifdef BOB_SAYS_NO
+		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+#endif
+		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
+		fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
+		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
+		break;
+		
+	      case FUNCTYPE_C:
+	      default:
+		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+#ifdef BOB_SAYS_NO
+		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+#endif
+		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
+		fprintf(fp, "\tpushw\t$0\n");
+		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
+		break;
+	    }
+	}
+    }
+
+    fclose(fp);
+
+#ifndef SHORTNAMES
+    sprintf(filename, "dll_%s_tab.c", LowerDLLName);
+#else
+    sprintf(filename, "dtb_%s.c", LowerDLLName);
+#endif
+    fp = fopen(filename, "w");
+
+    fprintf(fp, "#include <stdio.h>\n");
+    fprintf(fp, "#include <stdlib.h>\n");
+    fprintf(fp, "#include \042dlls.h\042\n\n");
+
+    for (i = 0; i <= Limit; i++)
+    {
+	fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
+    }
+    
+    odp = OrdinalDefinitions;
+    for (i = 0; i <= Limit; i++, odp++)
+    {
+	if (odp->valid && 
+	    (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
+	     odp->type == FUNCTYPE_REG))
+	{
+	    fdp = odp->additional_data;
+	    fprintf(fp, "extern int %s();\n", fdp->internal_name);
+	}
+    }
+    
+    fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n", 
+	    UpperDLLName, Limit + 1);
+    fprintf(fp, "{\n");
+    odp = OrdinalDefinitions;
+    for (i = 0; i <= Limit; i++, odp++)
+    {
+	fdp = odp->additional_data;
+
+	if (!odp->valid)
+	    odp->type = -1;
+	
+	switch (odp->type)
+	{
+	  case FUNCTYPE_PASCAL:
+	  case FUNCTYPE_REG:
+	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
+	    fprintf(fp, "\042%s\042, ", odp->export_name);
+	    fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
+#ifdef WINESTAT
+	    fprintf(fp, "0, ");
+#endif	    
+	    fprintf(fp, "%d, ", fdp->n_args_32);
+	    if (fdp->n_args_32 > 0)
+	    {
+		int argnum;
+		
+		fprintf(fp, "\n      {\n");
+		for (argnum = 0; argnum < fdp->n_args_32; argnum++)
+		{
+		    fprintf(fp, "        { %d, %d },\n",
+			    fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
+			    fdp->arg_types_16[argnum]);
+		}
+		fprintf(fp, "      }\n    ");
+	    }
+	    fprintf(fp, "}, \n");
+	    break;
+		
+	  case FUNCTYPE_C:
+	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
+	    fprintf(fp, "\042%s\042, ", odp->export_name);
+	    fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
+#ifdef WINESTAT
+	    fprintf(fp, "0, ");
+#endif	    
+	    fprintf(fp, "%d, ", fdp->n_args_32);
+	    if (fdp->n_args_32 > 0)
+	    {
+		int argnum;
+		
+		fprintf(fp, "\n      {\n");
+		for (argnum = 0; argnum < fdp->n_args_32; argnum++)
+		{
+		    fprintf(fp, "        { %d, %d },\n",
+			    fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
+			    fdp->arg_types_16[argnum]);
+		}
+		fprintf(fp, "      }\n    ");
+	    }
+	    fprintf(fp, "}, \n");
+	    break;
+	    
+	  default:
+	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", 
+		    UTEXTSEL, UpperDLLName, i);
+	    break;
+	}
+    }
+    fprintf(fp, "};\n");
+
+    fclose(fp);
+}
+
diff --git a/windows/Imakefile b/windows/Imakefile
index 9689eff..c5720cb 100644
--- a/windows/Imakefile
+++ b/windows/Imakefile
@@ -13,6 +13,7 @@
 	event.c \
 	focus.c \
 	graphics.c \
+	hook.c \
 	keyboard.c \
 	mapping.c \
 	mdi.c \
diff --git a/windows/caret.c b/windows/caret.c
index 1d85120..c3ed202 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -149,7 +149,7 @@
 /*    if (!Caret.hwnd) return;
 */
 #ifdef DEBUG_CARET
-    printf("DestroyCaret: timerid\n", Caret.timerid);
+    printf("DestroyCaret: timerid=%d\n", Caret.timerid);
 #endif
 
     KillSystemTimer(NULL, Caret.timerid);
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 5163a20..2434840 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -12,6 +12,7 @@
 #include "win.h"
 #include "class.h"
 #include "user.h"
+#include "syscolor.h"
 
 extern LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn );
 extern LONG NC_HandleNCActivate( HWND hwnd, WORD wParam );
@@ -22,7 +23,7 @@
 extern LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt );
 extern LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam );
 extern void NC_TrackSysMenu( HWND hwnd ); /* menu.c */
-extern BOOL ActivateMenuFocus(HWND hWnd); /* menu.c */
+extern BOOL ActivateMenuBarFocus(HWND hWnd); /* menu.c */
 
 
 
@@ -155,16 +156,14 @@
 	    {
 		SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
 		SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
-/*	        hbr = sysClrObjects.hbrScrollbar;
-		UnrealizeObject(hbr); */
-		return GetStockObject(LTGRAY_BRUSH);
+		UnrealizeObject( sysColorObjects.hbrushScrollbar );
+		return sysColorObjects.hbrushScrollbar;
 	    }
 	    else
 	    {
 		SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
 		SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
-/*	        hbr = sysClrObjects.hbrWindow; */
-		return GetStockObject(WHITE_BRUSH);
+		return sysColorObjects.hbrushWindow;
 	    }
 	}
 	
@@ -211,7 +210,7 @@
 	return NC_HandleSysCommand( hwnd, wParam, MAKEPOINT(lParam) );
 
     case WM_SYSKEYDOWN:
-		if (wParam == VK_MENU) ActivateMenuFocus(hwnd);
+		if (wParam == VK_MENU) ActivateMenuBarFocus(hwnd);
 		break;    	
     case WM_SYSKEYUP:
 		break;    	
diff --git a/windows/dialog.c b/windows/dialog.c
index 35dc9f0..379b0b0 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -315,11 +315,10 @@
 
       /* Send initialisation messages and set focus */
 
-    if (dlgInfo->hUserFont) 
-	SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0);
-    SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param );
-/*    if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
-	SetFocus( dlgInfo->hwndFocus ); */
+    if (dlgInfo->hUserFont)
+	SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0 );
+    if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
+	SetFocus( dlgInfo->hwndFocus );
 
     return hwnd;
 }
@@ -332,24 +331,28 @@
 {
     WND * wndPtr;
     DIALOGINFO * dlgInfo;
-    MSG msg;
+    HANDLE msgHandle;
+    MSG* lpmsg;
     int retval;
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
+    if (!(msgHandle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(MSG)))) return -1;
+    lpmsg = (MSG *) USER_HEAP_ADDR( msgHandle );
     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
     ShowWindow( hwnd, SW_SHOW );
 
-    while (GetMessage (&msg, 0, 0, 0))
+    while (MSG_InternalGetMessage( lpmsg, hwnd, MSGF_DIALOGBOX, TRUE ))
     {
-	if (!IsDialogMessage( hwnd, &msg))
+	if (!IsDialogMessage( hwnd, lpmsg))
 	{
-	    TranslateMessage(&msg);
-	    DispatchMessage(&msg);
+	    TranslateMessage( lpmsg );
+	    DispatchMessage( lpmsg );
 	}
 	if (dlgInfo->fEnd) break;
     }
     retval = dlgInfo->msgResult;
     DestroyWindow( hwnd );
+    USER_HEAP_FREE( msgHandle );
     return retval;
 }
 
diff --git a/windows/event.c b/windows/event.c
index 887d025..b69223e 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -332,7 +332,7 @@
 #ifdef DEBUG_KEY
 	    printf("WM_CHAR :   wParam=%X\n", (WORD)Str[0] );
 #endif
-	    PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 );
+	    PostMessage( GetFocus(), WM_CHAR, (WORD)Str[0], keylp.lp2 );
 	}
     }
     else
diff --git a/windows/graphics.c b/windows/graphics.c
index fb3e580..2594c91 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -16,6 +16,7 @@
 #endif
 
 #include "gdi.h"
+#include "syscolor.h"
 
 extern int COLOR_ToPhysical( DC *dc, COLORREF color );
 
@@ -458,7 +459,7 @@
  */
 void DrawFocusRect( HDC hdc, LPRECT rc )
 {
-    HPEN hPen, hOldPen;
+    HPEN hOldPen;
     int oldDrawMode, oldBkMode;
     int left, top, right, bottom;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -469,8 +470,7 @@
     right  = XLPTODP( dc, rc->right );
     bottom = YLPTODP( dc, rc->bottom );
     
-    hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT)); 
-    hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
+    hOldPen = (HPEN)SelectObject(hdc, sysColorObjects.hpenWindowText );
     oldDrawMode = SetROP2(hdc, R2_XORPEN);
     oldBkMode = SetBkMode(hdc, TRANSPARENT);
 
@@ -482,7 +482,6 @@
     SetBkMode(hdc, oldBkMode);
     SetROP2(hdc, oldDrawMode);
     SelectObject(hdc, (HANDLE)hOldPen);
-    DeleteObject((HANDLE)hPen);
 }
 
 
@@ -491,15 +490,11 @@
  */
 void DrawReliefRect( HDC hdc, RECT rect, int thickness, BOOL pressed )
 {
-    HBRUSH hbrushOld, hbrushShadow, hbrushHighlight;
+    HBRUSH hbrushOld;
     int i;
 
-    hbrushShadow = CreateSolidBrush( GetSysColor(COLOR_BTNSHADOW) );
-    hbrushHighlight = CreateSolidBrush( GetSysColor(COLOR_BTNHIGHLIGHT) );
-
-    if (pressed) hbrushOld = SelectObject( hdc, hbrushShadow );
-    else hbrushOld = SelectObject( hdc, hbrushHighlight );
-
+    hbrushOld = SelectObject( hdc, pressed ? sysColorObjects.hbrushBtnShadow :
+			                  sysColorObjects.hbrushBtnHighlight );
     for (i = 0; i < thickness; i++)
     {
 	PatBlt( hdc, rect.left + i, rect.top,
@@ -508,9 +503,8 @@
 	        rect.right - rect.left - i, 1, PATCOPY );
     }
 
-    if (pressed) hbrushOld = SelectObject( hdc, hbrushHighlight );
-    else hbrushOld = SelectObject( hdc, hbrushShadow );
-
+    SelectObject( hdc, pressed ? sysColorObjects.hbrushBtnHighlight :
+		                 sysColorObjects.hbrushBtnShadow );
     for (i = 0; i < thickness; i++)
     {
 	PatBlt( hdc, rect.right - i - 1, rect.top + i,
@@ -520,8 +514,6 @@
     }
 
     SelectObject( hdc, hbrushOld );
-    DeleteObject( hbrushShadow );
-    DeleteObject( hbrushHighlight );
 }
 
 
diff --git a/windows/hook.c b/windows/hook.c
new file mode 100644
index 0000000..20184bc
--- /dev/null
+++ b/windows/hook.c
@@ -0,0 +1,122 @@
+/*
+ * Windows hook functions
+ *
+ * Copyright 1994 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1994";
+
+/* Warning!
+ * HHOOK is not a real handle, but a 32-bit pointer to a HOOKDATA structure.
+ * This is for compatibility with Windows 3.0 where HHOOK was a HOOKPROC.
+ */
+
+#include "hook.h"
+
+
+HHOOK systemHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
+
+  /* Task-specific hooks should probably be in the task structure */
+HHOOK taskHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
+
+
+
+/***********************************************************************
+ *           SetWindowsHook   (USER.121)
+ */
+HHOOK SetWindowsHook( short id, HOOKPROC proc )
+{
+    return SetWindowsHookEx( id, proc, 0, 0 );
+}
+
+
+/***********************************************************************
+ *           UnhookWindowsHook   (USER.234)
+ */
+BOOL UnhookWindowsHook( short id, HHOOK hhook )
+{
+    return UnhookWindowsHookEx( hhook );
+}
+
+
+/***********************************************************************
+ *           DefHookProc   (USER.235)
+ */
+DWORD DefHookProc( short code, WORD wParam, DWORD lParam, HHOOK *hhook )
+{
+    return CallNextHookEx( *hhook, code, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           CallMsgFilter   (USER.123)
+ */
+BOOL CallMsgFilter( LPMSG msg, short code )
+{
+    if (CALL_SYSTEM_HOOK( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
+    else return CALL_TASK_HOOK( WH_MSGFILTER, code, 0, (LPARAM)msg );
+}
+
+
+/***********************************************************************
+ *           SetWindowsHookEx   (USER.291)
+ */
+HHOOK SetWindowsHookEx( short id, HOOKPROC proc, HINSTANCE hinst, HTASK htask )
+{
+    HOOKDATA *data;
+    HANDLE handle;
+    HHOOK *prevHook;
+
+    if ((id < FIRST_HOOK) || (id > LAST_HOOK)) return 0;
+    if (htask)  /* Task-specific hook */
+    {
+	if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
+	    (id == WH_SYSMSGFILTER)) return 0;
+	prevHook = &TASK_HOOK( id );
+    }
+    else  /* System-wide hook */
+    {
+	prevHook = &SYSTEM_HOOK( id );
+    }
+    
+    handle = (HANDLE) USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*data) );
+    if (!handle) return 0;
+    data   = (HOOKDATA *) USER_HEAP_ADDR( handle );
+
+    data->next  = *prevHook;
+    data->proc  = proc;
+    data->id    = id;
+    data->htask = htask;
+    *prevHook   = (HHOOK)data;
+    return (HHOOK)data;
+}
+
+
+/***********************************************************************
+ *           UnhookWindowHookEx   (USER.292)
+ */
+BOOL UnhookWindowsHookEx( HHOOK hhook )
+{
+    HOOKDATA *data = (HOOKDATA *)hhook;
+    HHOOK *prevHook;
+
+    if (!data) return FALSE;
+    prevHook = data->htask ? &TASK_HOOK(data->id) : &SYSTEM_HOOK(data->id);
+    while (*prevHook && (*prevHook != hhook))
+	prevHook = &((HOOKDATA *)*prevHook)->next;
+    if (!*prevHook) return FALSE;
+    *prevHook = data->next;
+    USER_HEAP_FREE( hhook & 0xffff );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CallNextHookEx   (USER.293)
+ */
+DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
+{
+    HOOKDATA *data = (HOOKDATA *)hhook;
+    if (!data->next) return 0;
+    else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );
+}
diff --git a/windows/mdi.c b/windows/mdi.c
index 1912295..ae04cd4 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -10,6 +10,8 @@
 #include "win.h"
 #include "mdi.h"
 #include "user.h"
+#include "sysmetrics.h"
+#include "menu.h"
 
 /* #define DEBUG_MDI /* */
 
@@ -60,10 +62,10 @@
 }
 
 /**********************************************************************
- *					MDICreateClient
+ *					MDICreateChild
  */
 HWND 
-MDICreateClient(WND *w, MDICLIENTINFO *ci, HWND parent, LPMDICREATESTRUCT cs)
+MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPMDICREATESTRUCT cs)
 {
     HWND hwnd;
 
@@ -77,7 +79,7 @@
 			  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, cs->lParam);
+			  w->hInstance, (LPSTR) cs->lParam);
 
     if (hwnd)
     {
@@ -107,10 +109,10 @@
 }
 
 /**********************************************************************
- *					MDIDestroyClient
+ *					MDIDestroyChild
  */
 HWND 
-MDIDestroyClient(WND *w_parent, MDICLIENTINFO *ci, HWND parent, HWND child,
+MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, HWND child,
 		 BOOL flagDestroy)
 {
     MDICHILDINFO  *chi;
@@ -133,7 +135,7 @@
 	if (chi->hwnd == ci->hwndActiveChild)
 	    SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
 
-	USER_HEAP_FREE((HANDLE) chi);
+	USER_HEAP_FREE((HANDLE) (LONG) chi);
 	
 	if (flagDestroy)
 	    DestroyWindow(child);
@@ -145,7 +147,7 @@
 /**********************************************************************
  *					MDIBringChildToTop
  */
-void MDIBringChildToTop(HWND parent, WORD id, WORD by_id)
+void MDIBringChildToTop(HWND parent, WORD id, WORD by_id, BOOL send_to_bottom)
 {
     MDICHILDINFO  *chi;
     MDICLIENTINFO *ci;
@@ -184,9 +186,51 @@
 #endif
 	if (chi != ci->infoActiveChildren)
 	{
-	    SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0, 
-			 SWP_NOMOVE | SWP_NOSIZE );
+	    if (ci->flagChildMaximized)
+	    {
+		RECT rectOldRestore, rect;
 
+		w = WIN_FindWndPtr(chi->hwnd);
+		
+		rectOldRestore = ci->rectRestore;
+		GetWindowRect(chi->hwnd, &ci->rectRestore);
+
+		rect.top    = (ci->rectMaximize.top -
+			       (w->rectClient.top - w->rectWindow.top));
+		rect.bottom = (ci->rectMaximize.bottom + 
+			       (w->rectWindow.bottom - w->rectClient.bottom));
+		rect.left   = (ci->rectMaximize.left - 
+			       (w->rectClient.left - w->rectWindow.left));
+		rect.right  = (ci->rectMaximize.right +
+			       (w->rectWindow.right - w->rectClient.right));
+		w->dwStyle |= WS_MAXIMIZE;
+		SetWindowPos(chi->hwnd, HWND_TOP, rect.left, rect.top, 
+			     rect.right - rect.left + 1, 
+			     rect.bottom - rect.top + 1, 0);
+		SendMessage(chi->hwnd, WM_SIZE, SIZE_MAXIMIZED,
+			    MAKELONG(w->rectClient.right-w->rectClient.left,
+				     w->rectClient.bottom-w->rectClient.top));
+
+		w = WIN_FindWndPtr(ci->hwndActiveChild);
+		w->dwStyle &= ~WS_MAXIMIZE;
+		SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 
+			     rectOldRestore.left, rectOldRestore.top, 
+			     rectOldRestore.right - rectOldRestore.left + 1, 
+			     rectOldRestore.bottom - rectOldRestore.top + 1,
+			     SWP_NOACTIVATE | 
+			     (send_to_bottom ? 0 : SWP_NOZORDER));
+	    }
+	    else
+	    {
+		SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0, 
+			     SWP_NOMOVE | SWP_NOSIZE );
+		if (send_to_bottom)
+		{
+		    SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 0, 0, 0, 0, 
+				 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+		}
+	    }
+		
 	    if (chi->next)
 		chi->next->prev    = chi->prev;
 
@@ -209,6 +253,65 @@
 }
 
 /**********************************************************************
+ *					MDIMaximizeChild
+ */
+LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci)
+{
+    WND *w = WIN_FindWndPtr(child);
+    RECT rect;
+    
+    MDIBringChildToTop(parent, child, FALSE, FALSE);
+    ci->rectRestore = w->rectWindow;
+
+    rect.top    = (ci->rectMaximize.top -
+		   (w->rectClient.top - w->rectWindow.top));
+    rect.bottom = (ci->rectMaximize.bottom + 
+		   (w->rectWindow.bottom - w->rectClient.bottom));
+    rect.left   = (ci->rectMaximize.left - 
+		   (w->rectClient.left - w->rectWindow.left));
+    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);
+    
+    ci->flagChildMaximized = TRUE;
+    
+    SendMessage(child, WM_SIZE, SIZE_MAXIMIZED,
+		MAKELONG(w->rectClient.right-w->rectClient.left,
+			 w->rectClient.bottom-w->rectClient.top));
+    SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
+
+    return 0;
+}
+
+/**********************************************************************
+ *					MDIRestoreChild
+ */
+LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
+{
+    HWND    child;
+    WND    *w      = WIN_FindWndPtr(child);
+    LPRECT  lprect = &ci->rectRestore;
+
+    child = ci->hwndActiveChild;
+    
+    w->dwStyle &= ~WS_MAXIMIZE;
+    SetWindowPos(child, 0, lprect->left, lprect->top, 
+		 lprect->right - lprect->left + 1, 
+		 lprect->bottom - lprect->top + 1,
+		 SWP_NOACTIVATE | SWP_NOZORDER);
+    
+    ci->flagChildMaximized = FALSE;
+
+    SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
+    MDIBringChildToTop(parent, child, FALSE, FALSE);
+
+    return 0;
+}
+
+/**********************************************************************
  *					MDIChildActivated
  */
 LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent)
@@ -250,7 +353,7 @@
     if (chi || ci->nActiveChildren == 0)
     {
 	MDIRecreateMenuList(ci);
-	DrawMenuBar(GetParent(parent));
+	SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
     }
     
     return 0;
@@ -266,10 +369,13 @@
     int           spacing, xsize, ysize;
     int		  x, y;
 
+    if (ci->flagChildMaximized)
+	MDIRestoreChild(parent, ci);
+
     GetClientRect(parent, &rect);
     spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
-    ysize   = abs(rect.bottom - rect.top) - 8 * spacing;
-    xsize   = abs(rect.right  - rect.left) - 8 * spacing;
+    ysize   = rect.bottom - 8 * spacing;
+    xsize   = rect.right  - 8 * spacing;
     
 #ifdef DEBUG_MDI
     fprintf(stderr, 
@@ -302,6 +408,178 @@
 }
 
 /**********************************************************************
+ *					MDITile
+ */
+LONG MDITile(HWND parent, MDICLIENTINFO *ci)
+{
+    MDICHILDINFO *chi;
+    RECT          rect;
+    int           xsize, ysize;
+    int		  x, y;
+    int		  rows, columns;
+    int           r, c;
+    int           i;
+
+    if (ci->flagChildMaximized)
+	MDIRestoreChild(parent, ci);
+
+    GetClientRect(parent, &rect);
+    rows    = (int) sqrt((double) ci->nActiveChildren);
+    columns = ci->nActiveChildren / rows;
+    ysize   = rect.bottom / rows;
+    xsize   = rect.right  / columns;
+    
+    chi     = ci->infoActiveChildren;
+    x       = 0;
+    i       = 0;
+    for (c = 1; c <= columns; c++)
+    {
+	if (c == columns)
+	{
+	    rows  = ci->nActiveChildren - i;
+	    ysize = rect.bottom / rows;
+	}
+
+	y = 0;
+	for (r = 1; r <= rows; r++, i++, chi = chi->next)
+	{
+	    SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize, 
+			 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+
+	    y += ysize;
+	}
+
+	x += xsize;
+    }
+    
+
+    return 0;
+}
+
+/**********************************************************************
+ *					MDIHandleLButton
+ */
+BOOL MDIHandleLButton(HWND hwndFrame, HWND hwndClient, 
+		      WORD wParam, LONG lParam)
+{
+    MDICLIENTINFO *ci;
+    WND           *w;
+    RECT           rect;
+    WORD           x;
+
+    w  = WIN_FindWndPtr(hwndClient);
+    ci = (MDICLIENTINFO *) w->wExtra;
+
+    if (wParam == HTMENU && ci->flagChildMaximized)
+    {
+	x = LOWORD(lParam);
+	
+	NC_GetInsideRect(hwndFrame, &rect);
+	if (x < rect.left + SYSMETRICS_CXSIZE)
+	{
+	    SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND, 
+			SC_CLOSE, lParam);
+	    return TRUE;
+	}
+	else if (x >= rect.right - SYSMETRICS_CXSIZE)
+	{
+	    SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND, 
+			SC_RESTORE, lParam);
+	    return TRUE;
+	}
+    }
+
+    return FALSE;
+}
+
+/**********************************************************************
+ *					MDIPaintMaximized
+ */
+LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
+		       WORD wParam, LONG lParam)
+{
+    static HBITMAP hbitmapClose     = 0;
+    static HBITMAP hbitmapMaximized = 0;
+    
+    MDICLIENTINFO *ci;
+    WND           *w;
+    LONG           rv;
+    HDC            hdc, hdcMem;
+    RECT           rect;
+    WND           *wndPtr = WIN_FindWndPtr(hwndFrame);
+
+    w  = WIN_FindWndPtr(hwndClient);
+    ci = (MDICLIENTINFO *) w->wExtra;
+
+#ifdef DEBUG_MDI
+	fprintf(stderr, 
+		"MDIPaintMaximized: frame %04x,  client %04x"
+		",  max flag %d,  menu %04x\n", 
+		hwndFrame, hwndClient, 
+		ci->flagChildMaximized, wndPtr ? wndPtr->wIDmenu : 0);
+#endif
+
+    if (ci->flagChildMaximized && wndPtr && wndPtr->wIDmenu != 0)
+    {
+	rv = NC_DoNCPaint( hwndFrame, (HRGN) 1, wParam, TRUE);
+    
+	hdc = GetDCEx(hwndFrame, 0, DCX_CACHE | DCX_WINDOW);
+	if (!hdc)
+	    return rv;
+
+	hdcMem = CreateCompatibleDC(hdc);
+
+	if (hbitmapClose == 0)
+	{
+	    hbitmapClose     = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE));
+	    hbitmapMaximized = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
+	}
+
+#ifdef DEBUG_MDI
+	fprintf(stderr, 
+		"MDIPaintMaximized: hdcMem %04x, close bitmap %04x, "
+		"maximized bitmap %04x\n",
+		hdcMem, hbitmapClose, hbitmapMaximized);
+#endif
+
+	NC_GetInsideRect(hwndFrame, &rect);
+	rect.top   += ((wndPtr->dwStyle & WS_CAPTION) ? 
+		       SYSMETRICS_CYSIZE + 1 :  0);
+	SelectObject(hdcMem, hbitmapClose);
+	BitBlt(hdc, rect.left, rect.top + 1, 
+	       SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
+	       hdcMem, 1, 1, SRCCOPY);
+	
+	NC_GetInsideRect(hwndFrame, &rect);
+	rect.top   += ((wndPtr->dwStyle & WS_CAPTION) ? 
+		       SYSMETRICS_CYSIZE + 1 :  0);
+	rect.left   = rect.right - SYSMETRICS_CXSIZE;
+	SelectObject(hdcMem, hbitmapMaximized);
+	BitBlt(hdc, rect.left, rect.top + 1, 
+	       SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
+	       hdcMem, 1, 1, SRCCOPY);
+	
+	NC_GetInsideRect(hwndFrame, &rect);
+	rect.top   += ((wndPtr->dwStyle & WS_CAPTION) ? 
+		       SYSMETRICS_CYSIZE + 1 :  0);
+	rect.left  += SYSMETRICS_CXSIZE;
+	rect.right -= SYSMETRICS_CXSIZE;
+	rect.bottom = rect.top + SYSMETRICS_CYMENU;
+
+	StdDrawMenuBar(hdc, &rect, (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu), 
+		       FALSE);
+	GlobalUnlock(wndPtr->wIDmenu);
+	
+	DeleteDC(hdcMem);
+	ReleaseDC(hwndFrame, hdc);
+    }
+    else
+	DefWindowProc(hwndFrame, message, wParam, lParam);
+
+    return rv;
+}
+
+/**********************************************************************
  *					MDIClientWndProc
  *
  * This function is the handler for all MDI requests.
@@ -313,7 +591,6 @@
     LPCLIENTCREATESTRUCT ccs;
     MDICLIENTINFO       *ci;
     WND                 *w;
-    RECT                 rect;
 
     w  = WIN_FindWndPtr(hwnd);
     ci = (MDICLIENTINFO *) w->wExtra;
@@ -333,23 +610,24 @@
 	ci->flagChildMaximized  = FALSE;
 	w->dwStyle             |= WS_CLIPCHILDREN;
 
-	GetClientRect(w->hwndParent, &rect);
-	MoveWindow(hwnd, 0, 0, rect.right, rect.bottom, 1);
+	GetClientRect(w->hwndParent, &ci->rectMaximize);
+	MoveWindow(hwnd, 0, 0, 
+		   ci->rectMaximize.right, ci->rectMaximize.bottom, 1);
 
 	return 0;
 
       case WM_MDIACTIVATE:
-	MDIBringChildToTop(hwnd, wParam, FALSE);
+	MDIBringChildToTop(hwnd, wParam, FALSE, FALSE);
 	return 0;
 
       case WM_MDICASCADE:
 	return MDICascade(hwnd, ci);
 
       case WM_MDICREATE:
-	return MDICreateClient(w, ci, hwnd, (LPMDICREATESTRUCT) lParam);
+	return MDICreateChild(w, ci, hwnd, (LPMDICREATESTRUCT) lParam);
 
       case WM_MDIDESTROY:
-	return MDIDestroyClient(w, ci, hwnd, wParam, TRUE);
+	return MDIDestroyChild(w, ci, hwnd, wParam, TRUE);
 
       case WM_MDIGETACTIVE:
 	return ((LONG) ci->hwndActiveChild | 
@@ -360,19 +638,35 @@
 	break;
 	
       case WM_MDIMAXIMIZE:
-	ci->flagChildMaximized = TRUE;
-	MDIBringChildToTop(hwnd, wParam, FALSE);
-	return 0;
+	return MDIMaximizeChild(hwnd, wParam, ci);
 
+      case WM_MDINEXT:
+	MDIBringChildToTop(hwnd, wParam, FALSE, TRUE);
+	break;
+	
+      case WM_MDIRESTORE:
+	return MDIRestoreChild(hwnd, ci);
+
+      case WM_MDISETMENU:
+	/* return MDISetMenu(...) */
+	break;
+	
+      case WM_MDITILE:
+	return MDITile(hwnd, ci);
+	
       case WM_NCACTIVATE:
 	SendMessage(ci->hwndActiveChild, message, wParam, lParam);
 	break;
 	
       case WM_PARENTNOTIFY:
 	if (wParam == WM_DESTROY)
-	    return MDIDestroyClient(w, ci, hwnd, LOWORD(lParam), FALSE);
+	    return MDIDestroyChild(w, ci, hwnd, LOWORD(lParam), FALSE);
 	else if (wParam == WM_LBUTTONDOWN)
-	    MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE);
+	    MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE, FALSE);
+	break;
+
+      case WM_SIZE:
+	GetClientRect(w->hwndParent, &ci->rectMaximize);
 	break;
 
     }
@@ -391,12 +685,20 @@
     switch (message)
     {
       case WM_COMMAND:
-	MDIBringChildToTop(hwndMDIClient, wParam, TRUE);
+	MDIBringChildToTop(hwndMDIClient, wParam, TRUE, FALSE);
+	break;
+
+      case WM_NCLBUTTONDOWN:
+	if (MDIHandleLButton(hwnd, hwndMDIClient, wParam, lParam))
+	    return 0;
 	break;
 
       case WM_NCACTIVATE:
 	SendMessage(hwndMDIClient, message, wParam, lParam);
-	break;
+	return MDIPaintMaximized(hwnd, hwndMDIClient, message, wParam, lParam);
+
+      case WM_NCPAINT:
+	return MDIPaintMaximized(hwnd, hwndMDIClient, message, wParam, lParam);
 	
       case WM_SETFOCUS:
 	SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam);
@@ -433,6 +735,18 @@
       case WM_NCPAINT:
 	return NC_DoNCPaint(hwnd, (HRGN)1, 
 			    hwnd == ci->hwndActiveChild);
+
+      case WM_SYSCOMMAND:
+	switch (wParam)
+	{
+	  case SC_MAXIMIZE:
+	    return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, hwnd, 0);
+
+	  case SC_RESTORE:
+	    return SendMessage(GetParent(hwnd), WM_MDIRESTORE, hwnd, 0);
+	}
+	break;
+	
     }
 	
     return DefWindowProc(hwnd, message, wParam, lParam);
diff --git a/windows/message.c b/windows/message.c
index 62fd981..a356f51 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -19,9 +19,11 @@
 #include "win.h"
 #include "wineopts.h"
 #include "sysmetrics.h"
+#include "hook.h"
 
 #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 */
 extern void EVENT_ProcessEvent( XEvent *event );  /* event.c */
@@ -109,8 +111,6 @@
 {
     int pos;
   
-    SpyMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam);
-    
     if (!msgQueue) return FALSE;
     pos = msgQueue->nextFreeMessage;
 
@@ -293,6 +293,7 @@
 	msg->wParam = hittest_result;
 	msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN;
     }
+    
     return TRUE;
 }
 
@@ -552,9 +553,9 @@
 	mask = QS_POSTMESSAGE;  /* Always selectioned */
 	if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
 	if ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) mask |= QS_MOUSE;
-	if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= WM_TIMER;
-	if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= WM_TIMER;
-	if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= WM_PAINT;
+	if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
+	if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
+	if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
     }
     else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT;
 
@@ -672,6 +673,31 @@
 
 
 /***********************************************************************
+ *           MSG_InternalGetMessage
+ *
+ * GetMessage() function for internal use. Behave like GetMessage(),
+ * but also call message filters and optionally send WM_ENTERIDLE messages.
+ * 'hwnd' must be the handle of the dialog or menu window.
+ * 'code' is the message filter value (MSGF_??? codes).
+ */
+BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd, short code, BOOL sendIdle ) 
+{
+    do
+    {
+	if (sendIdle)
+	{
+	    if (MSG_PeekMessage(appMsgQueue, msg, 0, 0, 0, PM_REMOVE, TRUE))
+		continue;
+	    /* FIXME: to which window should we send this? */
+	    /* SendMessage( hwnd, WM_ENTERIDLE, code, (LPARAM)hwnd ); */
+	}
+	MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, PM_REMOVE, FALSE );
+    } while (CallMsgFilter( msg, code ) != 0);
+    return (msg->message != WM_QUIT);
+}
+
+
+/***********************************************************************
  *           PeekMessage   (USER.109)
  */
 BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
@@ -685,7 +711,10 @@
  */
 BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) 
 {
-    return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, PM_REMOVE, FALSE );
+    MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, PM_REMOVE, FALSE );
+    CALL_SYSTEM_HOOK( WH_GETMESSAGE, 0, 0, (LPARAM)msg );
+    CALL_TASK_HOOK( WH_GETMESSAGE, 0, 0, (LPARAM)msg );
+    return (msg->message != WM_QUIT);
 }
 
 
@@ -718,8 +747,6 @@
 {
     WND * wndPtr;
 
-    SpyMessage(hwnd, msg, wParam, lParam);
-    
     wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     return CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam );
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 9a7f85f..078bd00 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -13,6 +13,7 @@
 #include "user.h"
 #include "scroll.h"
 #include "menu.h"
+#include "syscolor.h"
 
 static HBITMAP hbitmapClose = 0;
 static HBITMAP hbitmapMinimize = 0;
@@ -134,7 +135,7 @@
  * but without the borders (if any).
  * The rectangle is in window coordinates (for drawing with GetWindowDC()).
  */
-static void NC_GetInsideRect( HWND hwnd, RECT *rect )
+void NC_GetInsideRect( HWND hwnd, RECT *rect )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -449,7 +450,6 @@
 			    DWORD style, BOOL active )
 {
     RECT r = *rect;
-    HBRUSH hbrushCaption;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     char buffer[256];
 
@@ -467,21 +467,15 @@
     
     if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
     {
-	HBRUSH hbrushWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
-	HBRUSH hbrushOld = SelectObject( hdc, hbrushWindow );
+	HBRUSH hbrushOld = SelectObject( hdc, sysColorObjects.hbrushWindow );
 	PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
 	PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
 	PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
 	r.left++;
 	r.right--;
 	SelectObject( hdc, hbrushOld );
-	DeleteObject( hbrushWindow );
     }
 
-    if (active)
-	hbrushCaption = CreateSolidBrush( GetSysColor(COLOR_ACTIVECAPTION) );
-    else hbrushCaption = CreateSolidBrush( GetSysColor(COLOR_INACTIVECAPTION));
-
     MoveTo( hdc, r.left, r.bottom );
     LineTo( hdc, r.right-1, r.bottom );
 
@@ -503,8 +497,8 @@
 	r.right -= SYSMETRICS_CXSIZE + 1;
     }
 
-    FillRect( hdc, &r, hbrushCaption );
-    DeleteObject( hbrushCaption );
+    FillRect( hdc, &r, active ? sysColorObjects.hbrushActiveCaption : 
+	                        sysColorObjects.hbrushInactiveCaption );
 
     if (GetWindowText( hwnd, buffer, 256 ))
     {
@@ -522,12 +516,10 @@
  * Paint the non-client area.
  * 'hrgn' is the update rgn to use (in client coords) or 1 if no update rgn.
  */
-void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active )
+void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint )
 {
     HDC hdc;
     RECT rect, rect2;
-    HBRUSH hbrushBorder = 0;
-    HPEN hpenFrame = 0;
 
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -564,12 +556,9 @@
     rect.right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
     rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    hpenFrame = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME) );
-    SelectObject( hdc, hpenFrame );
-    if (active)
-	hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) );
-    else hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_INACTIVEBORDER) );
-    SelectObject( hdc, hbrushBorder );
+    SelectObject( hdc, sysColorObjects.hpenWindowFrame );
+    SelectObject( hdc, active ? sysColorObjects.hbrushActiveBorder :
+		                sysColorObjects.hbrushInactiveBorder );
 
     if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME))
     {
@@ -600,7 +589,8 @@
 	CopyRect(&rect2, &rect);
 	/* Default MenuBar height */
 	oldbottom = rect2.bottom = rect2.top + SYSMETRICS_CYMENU; 
-	StdDrawMenuBar(hdc, &rect2, (LPPOPUPMENU)GlobalLock(wndPtr->wIDmenu));
+	StdDrawMenuBar(hdc, &rect2, (LPPOPUPMENU)GlobalLock(wndPtr->wIDmenu),
+		       suppress_menupaint);
 	GlobalUnlock(wndPtr->wIDmenu);
 	/* Reduce ClientRect according to MenuBar height */
 	rect.top += rect2.bottom - oldbottom;
@@ -627,17 +617,14 @@
 
 	if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
 	{
-	    HBRUSH hbrushScroll = CreateSolidBrush( GetSysColor(COLOR_SCROLLBAR) );
 	    RECT r = rect;
 	    r.left = r.right - SYSMETRICS_CXVSCROLL;
 	    r.top  = r.bottom - SYSMETRICS_CYHSCROLL;
-	    FillRect( hdc, &r, hbrushScroll );
+	    FillRect( hdc, &r, sysColorObjects.hbrushScrollbar );
 	}
     }    
 
     ReleaseDC( hwnd, hdc );
-    if (hbrushBorder) DeleteObject( hbrushBorder );
-    if (hpenFrame) DeleteObject( hpenFrame );    
 }
 
 
@@ -648,7 +635,7 @@
  */
 LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn )
 {
-    NC_DoNCPaint( hwnd, hrgn, hwnd == GetActiveWindow() );
+    NC_DoNCPaint( hwnd, hrgn, hwnd == GetActiveWindow(), FALSE );
     return 0;
 }
 
@@ -660,7 +647,7 @@
  */
 LONG NC_HandleNCActivate( HWND hwnd, WORD wParam )
 {
-    NC_DoNCPaint( hwnd, (HRGN)1, wParam );
+    NC_DoNCPaint( hwnd, (HRGN)1, wParam, FALSE );
     return TRUE;
 }
 
diff --git a/windows/syscolor.c b/windows/syscolor.c
index 80b69d5..c92d549 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -12,7 +12,9 @@
 #include <stdlib.h>
 
 #include "windows.h"
+#include "syscolor.h"
 
+struct SysColorObjects sysColorObjects = { 0, };
 
 static char * DefSysColors[] =
 {
@@ -45,6 +47,78 @@
 
 
 /*************************************************************************
+ *             SYSCOLOR_SetColor
+ */
+static void SYSCOLOR_SetColor( int index, COLORREF color )
+{
+    SysColors[index] = color;
+    switch(index)
+    {
+    case COLOR_SCROLLBAR:
+	DeleteObject( sysColorObjects.hbrushScrollbar );
+	sysColorObjects.hbrushScrollbar = CreateSolidBrush( color );
+	break;
+    case COLOR_BACKGROUND:
+	break;
+    case COLOR_ACTIVECAPTION:
+	DeleteObject( sysColorObjects.hbrushActiveCaption );
+	sysColorObjects.hbrushActiveCaption = CreateSolidBrush( color );
+	break;
+    case COLOR_INACTIVECAPTION:
+	DeleteObject( sysColorObjects.hbrushInactiveCaption );
+	sysColorObjects.hbrushInactiveCaption = CreateSolidBrush( color );
+	break;
+    case COLOR_MENU:
+	break;
+    case COLOR_WINDOW:
+	DeleteObject( sysColorObjects.hbrushWindow );
+	sysColorObjects.hbrushWindow = CreateSolidBrush( color );
+	break;
+    case COLOR_WINDOWFRAME:
+	DeleteObject( sysColorObjects.hpenWindowFrame );
+	sysColorObjects.hpenWindowFrame = CreatePen( PS_SOLID, 1, color );
+	break;
+    case COLOR_MENUTEXT:
+	break;
+    case COLOR_WINDOWTEXT:
+	DeleteObject( sysColorObjects.hpenWindowText );
+	sysColorObjects.hpenWindowText = CreatePen( PS_SOLID, 1, color );
+	break;
+    case COLOR_CAPTIONTEXT:
+	break;
+    case COLOR_ACTIVEBORDER:
+	DeleteObject( sysColorObjects.hbrushActiveBorder );
+	sysColorObjects.hbrushActiveBorder = CreateSolidBrush( color );
+	break;
+    case COLOR_INACTIVEBORDER:
+	DeleteObject( sysColorObjects.hbrushInactiveBorder );
+	sysColorObjects.hbrushInactiveBorder = CreateSolidBrush( color );
+	break;
+    case COLOR_APPWORKSPACE:
+    case COLOR_HIGHLIGHT:
+    case COLOR_HIGHLIGHTTEXT:
+	break;
+    case COLOR_BTNFACE:
+	DeleteObject( sysColorObjects.hbrushBtnFace );
+	sysColorObjects.hbrushBtnFace = CreateSolidBrush( color );
+	break;
+    case COLOR_BTNSHADOW:
+	DeleteObject( sysColorObjects.hbrushBtnShadow );
+	sysColorObjects.hbrushBtnShadow = CreateSolidBrush( color );
+	break;
+    case COLOR_GRAYTEXT:
+    case COLOR_BTNTEXT:
+    case COLOR_INACTIVECAPTIONTEXT:
+	break;
+    case COLOR_BTNHIGHLIGHT:
+	DeleteObject( sysColorObjects.hbrushBtnHighlight );
+	sysColorObjects.hbrushBtnHighlight = CreateSolidBrush( color );
+	break;
+    }
+}
+
+
+/*************************************************************************
  *             SYSCOLOR_Init
  */
 void SYSCOLOR_Init()
@@ -57,7 +131,7 @@
     {
 	GetProfileString( "colors", p[0], p[1], buffer, 100 );
 	if (!sscanf( buffer, " %d %d %d", &r, &g, &b )) r = g = b = 0;
-	SysColors[i] = RGB( r, g, b );
+	SYSCOLOR_SetColor( i, RGB(r,g,b) );
     }
 }
 
@@ -85,7 +159,7 @@
 
     for (i = 0; i < nChanges; i++)
     {
-	SysColors[lpSysColor[i]] = lpColorValues[i];
+	SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] );
     }
 
     /* Send WM_SYSCOLORCHANGE message to all windows */
diff --git a/windows/win.c b/windows/win.c
index cfc8e85..6889fe6 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -28,6 +28,7 @@
 
 
 static HWND hwndDesktop = 0;
+static HWND hWndSysModal = 0;
 
 /***********************************************************************
  *           WIN_FindWndPtr
@@ -197,7 +198,6 @@
     wndPtr->dwStyle           = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
     wndPtr->dwExStyle         = 0;
     wndPtr->hdce              = 0;
-    wndPtr->hmenuSystem       = 0;
     wndPtr->VScroll           = NULL;
     wndPtr->HScroll           = NULL;
     wndPtr->wIDmenu           = 0;
@@ -205,6 +205,8 @@
     wndPtr->flags             = 0;
     wndPtr->window            = rootWindow;
     wndPtr->hSysMenu          = 0;
+    wndPtr->hProp	          = 0;
+    wndPtr->hTask	          = 0;
 
       /* Send dummy WM_NCCREATE message */
     SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
@@ -303,28 +305,34 @@
     wndPtr->ptMaxPos.y        = -1;
     wndPtr->hmemTaskQ         = GetTaskQueue(0);
     wndPtr->hrgnUpdate        = 0;
+    wndPtr->hwndPrevActive    = 0;
     wndPtr->hwndLastActive    = 0;
     wndPtr->lpfnWndProc       = classPtr->wc.lpfnWndProc;
     wndPtr->dwStyle           = style;
     wndPtr->dwExStyle         = exStyle;
-    wndPtr->hmenuSystem       = 0;
 #ifdef DEBUG_MENU
     printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n", 
     	menu, instance, classPtr->wc.lpszMenuName); 
 #endif
-    if (menu != 0)
-	wndPtr->wIDmenu       = menu;
-    else {
-	if (classPtr->wc.lpszMenuName != NULL)
-	    wndPtr->wIDmenu   = LoadMenu(instance, classPtr->wc.lpszMenuName);
+	if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
+		if (menu != 0)
+			SetMenu(hwnd, menu);
+		else {
+			if (classPtr->wc.lpszMenuName != NULL)
+				SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
+			else
+				wndPtr->wIDmenu   = 0;
+			}
+		}
 	else
-	    wndPtr->wIDmenu   = 0;
-	}
+		wndPtr->wIDmenu   = menu;
     wndPtr->hText             = 0;
     wndPtr->flags             = 0;
     wndPtr->VScroll           = NULL;
     wndPtr->HScroll           = NULL;
     wndPtr->hSysMenu          = 0;
+    wndPtr->hProp	          = 0;
+    wndPtr->hTask	          = 0;
 
     if (classPtr->wc.cbWndExtra)
 	memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
@@ -449,8 +457,14 @@
     if (hwnd == hwndDesktop) return FALSE;  /* Can't destroy desktop */
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
     if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
-    if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE );
-    if (hwnd == GetFocus()) SetFocus( 0 );
+
+      /* Hide the window */
+
+    if (wndPtr->dwStyle & WS_VISIBLE)
+	SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
+		      SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
+    if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
+	ReleaseCapture();
     WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
 
       /* Send destroy messages and destroy children */
@@ -471,9 +485,6 @@
     if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
     classPtr->cWindows--;
     USER_HEAP_FREE( hwnd );
-/*
-    printf("End of DestroyWindow // hwnd=%04X !\n", hwnd);
-*/
     return TRUE;
 }
 
@@ -944,3 +955,15 @@
     return WIN_EnumChildWin(hwnd, wndenumprc, lParam);         
 }
 
+/*******************************************************************
+ *			SetSysModalWindow		[USER.188]
+ */
+HWND SetSysModalWindow(HWND hWnd)
+{
+	HWND 	hWndOldModal = hWndSysModal;
+	hWndSysModal = hWnd;
+	printf("EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd);
+	return hWndOldModal;
+}
+
+
diff --git a/windows/winpos.c b/windows/winpos.c
index 0534bc8..f236d49 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -425,6 +425,9 @@
     hwndActive = hwnd;
     if (hwndActive)
     {
+	WND *wndPtr = WIN_FindWndPtr( hwndActive );
+	wndPtr->hwndPrevActive = prevActive;
+
 	/* Send WM_ACTIVATEAPP here */
 	SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 );
 	SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE,
@@ -437,8 +440,6 @@
 /***********************************************************************
  *           SetWindowPos   (USER.232)
  */
-/* Unimplemented flags: SWP_NOREDRAW
- */
 /* Note: all this code should be in the DeferWindowPos() routines,
  * and SetWindowPos() should simply call them.  This will be implemented
  * some day...
@@ -599,16 +600,26 @@
 	wndPtr->dwStyle |= WS_VISIBLE;
 	XMapWindow( display, wndPtr->window );
 	MSG_Synchronize();
-	if (!(winPos->flags & SWP_NOREDRAW))
-	    RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE |
-			  RDW_ERASENOW | RDW_FRAME );
-	else RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE );
-	
+	if (winPos->flags & SWP_NOREDRAW)
+	    RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE );
     }
     else if (winPos->flags & SWP_HIDEWINDOW)
     {
 	wndPtr->dwStyle &= ~WS_VISIBLE;
 	XUnmapWindow( display, wndPtr->window );
+	if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
+	    SetFocus( GetParent(hwnd) );  /* Revert focus to parent (if any) */
+	if (hwnd == hwndActive)
+	{
+	      /* Activate previously active window if possible */
+	    HWND newActive = wndPtr->hwndPrevActive;
+	    if (!IsWindow(newActive) || (newActive == hwnd))
+	    {
+		newActive = GetTopWindow(GetDesktopWindow());
+		if (newActive == hwnd) newActive = wndPtr->hwndNext;
+	    }	    
+	    WINPOS_ChangeActiveWindow( newActive, FALSE );
+	}
     }
 
     if (!(winPos->flags & SWP_NOACTIVATE))
diff --git a/wine.ini b/wine.ini
index b2c79af..b1d797f 100644
--- a/wine.ini
+++ b/wine.ini
@@ -1,33 +1,24 @@
-[drives]
-A=/mnt/fd0
-C=/dos
-D=/usr/windows
-E=/home/bob/wine/work
-F=/home/bob/test
-
-[wine]
-Windows=c:\windows
-System=c:\windows\system
-Temp=c:\temp
-Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
-SystemResources=sysres.dll
-
-[serialports]
-Com1=/dev/cua0
-Com2=/dev/cua1
-
-[parallelports]
-Lpt1=/dev/lp0
-
-[spy]
-;;;;; Uncomment the following line to activate spying to the console     ;;;;;
-;File=CON
-
-;;;;; Uncomment the following line to activate spying to the spy.log     ;;;;;
-;File=spy.log
-
-;;;;; List of ; separated (and terminated) msg names to exclude from log ;;;;;
-Exclude=WM_TIMER;WM_SETCURSOR;WM_MOUSEMOVE;
-
-;;;;; List of ; separated (and terminated) msg names to include in log   ;;;;;
-;Include=WM_COMMAND;
+

+[drives]

+A=/mnt/fd0

+C=/dos

+D=/usr/windows

+E=/home/bob/wine/work

+F=/home/bob/test

+

+[wine]

+Windows=c:\windows

+System=c:\windows\system

+Temp=c:\temp

+Path=c:\windows;c:\windows\system;e:\;e:\test;f:\

+SystemResources=sysres.dll

+

+[serialports]

+Com1=/dev/cua0

+Com2=/dev/cua1

+

+[parallelports]

+Lpt1=/dev/lp0

+

+[spy]

+Exclude=WM_SIZE;WM_TIMER;