Release 970616

Sat Jun 14 13:05:23 1997  Andreas Mohr <100.30936@germany.net>

	* [include/mmsystem.h]
	Avoided infinite loop in audio code when accessing
 	WAVEOUTCAPS/WAVEINCAPS/MIDIOUTCAPS/AUXCAPS with rigid variable
 	offsets (I applied WINE_PACKED).

	* [*/*]
	Added "WARNING:" and "ERROR:" to some printf's.
	Just grep for them with '-debugmsg +all'.

	* [multimedia/audio.c] [multimedia/mmsystem.c]
	Implemented wave callbacks: window and function callback.
	Fixed problem with WAVE_NotifyClient().
	Misc fixes.

	* [windows/winhelp.c]
	Fixed problem with windows help telling "Help topic doesn't exist".
	But this problem still remains when using Winword.

Wed Jun 11 09:14:20 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [wine.ini]
	New 'fonts' section format. Read documentation/fonts.

	* [controls/icontitle.c] [windows/winpos.c] [windows/nonclient.c]
	  [windows/win.c] [include/win.h]
	Implemented icon titles.

	* [graphics/x11drv/xfont.c] [objects/font.c] [objects/dc.c]
	  [include/x11drv.h] [include/x11font.h] [documentation/fonts]
	Rewrote font mapper from scratch.

	* [tools/fnt2bdf.c]
	Bug fixes. REPLACE FONTS CREATED BY THE PREVIOUS VERSIONS.

	* [windows/defwnd.c] [windows/nonclient.c]
	Word document window activation fix.

	* [windows/mdi.c] [windows/win.c]
	Replaced WCL lists with WIN_BuildWinArray().

Mon Jun  9 23:51:16 1997  Andrew Taylor <andrew@riscan.com>

	* [misc/error.c] [include/windows.h] [if1632/kernel.spec]
	Implemented LogParamError, LogError functions.

Tue Jun  3 23:46:04 1997  Michiel van Loon <mfvl@xs4all.nl>

	* [include/mmsystem.h] [multimedia/audio.c]
	Constants for asynchronous play and record.

	* [multimedia/time.c]
	Filled in some empty functions.

	* [multimedia/mmsystem.c]
	Fixed bugs in waveOutOpen.

	* [multimedia/mmsystem.c] [multimedia/audio.c]
	Implemented Window Callback for wave output at least.

	* [files/file.c]
	Corrected bug in FileDosSetError.
	NULL pointer checking added.

	* [misc/spy.c]
	Added Multimedia messages to SPY_GetMsgName.

Tue Jun 3 22:34:30 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [debugger/*.c][include/peexe.h][loader/*.c][tools/build.c]
	  [tools/fnt2bdf.c][library/sup.c]
	IMAGE_* structs/defines changed fit better to SDK naming
	Don't load non-i386 PE executables.
	%fs should already be initialised for the FIRST loaded PE module.

	* [if1632/advapi.spec][win32/advapi.c]
	Some small stubs added to bring win32 setup.exe a bit farther.

	* [if1632/kernel32.spec][scheduler/process.c]
	Adapted to match win95 kernel32.dll ordinals (NT doesn't use
 	ordinal import), some ordinal only exported functions added.

	* [if1632/relay.c]
	Added CallProc32W.

	* [misc/lzexpand.c]
	Fixed return values of GetExpandedName* (thanks to Andreas Mohr).

	* [objects/dib.c]
	Everything with more than 8 bit of color is a truecolor mode
	and doesn't have a colormap.

Tue Jun  3 09:24:53 1997  John Harvey <john@division.co.uk>

	* [graphics/win16drv/font.c] [graphics/win16drv/init.c]
	  [graphics/win16drv/prtdrv.c] [graphics/win16drv/text.c]
	  [include/win16drv.h]
	Changed some structures that are passed to and from the 16 bit
 	drivers to be allocated on the global heap.
	Implemented Escape(Control) 0x100 GetExtTextData properly to
	stop word from crashing.
	Postscript driver now prints on complete page instead of top
	left corner.
	Print spooling implemented.

	* [loader/module.c]
	MODULE_GetOrdinal changed char buffer to unsigned char to stop
	a loop that was happening when running the font control
	program from the control panel.

Sun Jun  1 19:05:02 1997  Peter Schlaile <up9n@rz.uni-karlsruhe.de>

	* [include/miscemu.h] [loader/main.c] [msdos/ioports.c]
	Added support for direct io port access.

Fri May 30 16:18:35 1997  David A. Cuthbert <dacut@dssc3353.ece.cmu.edu>

	* [misc/ver.c]
	Implemented VerFindFile16.

Tue May 27 22:00:39 1997  Rick Richardson <rick@dgii.com>

	* [misc/comm.c]
	Fixed GetCommError and GetCommEventMask.

Tue May 27  9:10:53 1997  Georg Beyerle <gbeyerle@awi-potsdam.de>

	* [scheduler/thread.c]
	Minor fix in thread database initialization.

Mon May 26 19:46:34 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [objects/dc.c]
	In DC_SetupGCForPen, avoid to draw in GXxor mode with a 0 mask.

Mon May 26 15:22:42 1997  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [loader/pe_image.c]
	Add code for modules that co-reference each other. Photodex's
	agds.exe (cpic32) has two dll's that make calls into each other.

Mon May 26 13:38:16 1997  Jody Goldberg <jodyg@idt.net>

	* [memory/virtual.c]
	Dont use stdio when reading /proc/self/maps.  It causes problems
	with libc6.

	* [windows/dialog.c]
	Translate messages in IsDialogMessage when DLGC_WANTMESSAGE
	is used.

Sun May 25 17:02:21 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/metafile.c]
	Resource cleanup in EnumMetaFile(). This was one reason Word was
	crashing after long periods of use. (Thanks to Chris Underhill for
	the logs)

Sun May 25 14:59:33 1997  Jimen Ching  <jching@flex.com>

	* [multimedia/mcistring.c]
	Initial support for compound MCI commands.
	Use case-insensitive compare for 'alias' and 'element' keywords.
	Fixed pointer copy of args keywords array.
diff --git a/ANNOUNCE b/ANNOUNCE
index 0ede2e6..20b0e35 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,16 @@
-This is release 970525 of Wine, the MS Windows emulator.  This is still a
+This is release 970616 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-970525: (see ChangeLog for details)
-	- Many fixes to multimedia code.
-	- Better menus.
+WHAT'S NEW with Wine-970616: (see ChangeLog for details)
+	- More improvements to multimedia code.
+	- New font mapper.
+	- Icon titles.
+	- Print spooling.
+	- Direct I/O ports access.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -16,10 +19,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970525.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970525.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970525.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-970525.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970616.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970616.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970616.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-970616.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 1252d8a..f706ac6 100644
--- a/BUGS
+++ b/BUGS
@@ -5,12 +5,11 @@
 add new entries and, more importantly, remove those for the 
 bugs you fixed ;-)
 ------------------------------------------------------------
-As of March 10 1997 -
+As of June 1997 -
 
 General:
 
- * Font mapping is too generic. No soft font loading, no rotated 
-   text support, incorrect metrics. [alex@amadeus.pharm.sunysb.edu]
+ * TrueType, .FON rasterizer.
 
  * No thread/process/kernel-object support in Win32 code. 
 
@@ -32,20 +31,23 @@
 	  properties.
 
  * No manual pages describing the various Windows calls.
+	- You can find information about most of the Win32 API calls
+          on the www.microsoft.com (go to 'search').
 
 Miscellaneous:
 
+ * New font mapping scheme can be improved.
+
  * "Cursor XXXX has more than 1 bpp!"
 
  * 32-bit Freecell segfaults when started from the Progman (looks like
    a problem with cards.dll).
 
- * Edit controls are prone to show blank space when, in fact, there is a
-   text there.
+ * Margins in edit controls are too wide.
 
  * SGI window manager treats Wine windows as topmost.
 
- * Write shows blank space instead of Paintbrush OLE1 object.
+ * Write shows blank space instead of Paintbrush OLE1 object ( GetDIBits()? ).
 
  * AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple
    times.
diff --git a/ChangeLog b/ChangeLog
index ebe3a6e..f8b8b96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,171 @@
 ----------------------------------------------------------------------
+Sat Jun 14 13:05:23 1997  Andreas Mohr <100.30936@germany.net>
+
+	* [include/mmsystem.h]
+	Avoided infinite loop in audio code when accessing
+ 	WAVEOUTCAPS/WAVEINCAPS/MIDIOUTCAPS/AUXCAPS with rigid variable
+ 	offsets (I applied WINE_PACKED).
+
+	* [*/*]
+	Added "WARNING:" and "ERROR:" to some printf's.
+	Just grep for them with '-debugmsg +all'.
+
+	* [multimedia/audio.c] [multimedia/mmsystem.c]
+	Implemented wave callbacks: window and function callback.
+	Fixed problem with WAVE_NotifyClient().
+	Misc fixes.
+
+	* [windows/winhelp.c]
+	Fixed problem with windows help telling "Help topic doesn't exist".
+	But this problem still remains when using Winword.
+
+Wed Jun 11 09:14:20 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [wine.ini]
+	New 'fonts' section format. Read documentation/fonts.
+
+	* [controls/icontitle.c] [windows/winpos.c] [windows/nonclient.c]
+	  [windows/win.c] [include/win.h]
+	Implemented icon titles.
+
+	* [graphics/x11drv/xfont.c] [objects/font.c] [objects/dc.c]
+	  [include/x11drv.h] [include/x11font.h] [documentation/fonts]
+	Rewrote font mapper from scratch.
+
+	* [tools/fnt2bdf.c]
+	Bug fixes. REPLACE FONTS CREATED BY THE PREVIOUS VERSIONS.
+
+	* [windows/defwnd.c] [windows/nonclient.c]
+	Word document window activation fix.
+
+	* [windows/mdi.c] [windows/win.c]
+	Replaced WCL lists with WIN_BuildWinArray().
+
+Mon Jun  9 23:51:16 1997  Andrew Taylor <andrew@riscan.com>
+
+	* [misc/error.c] [include/windows.h] [if1632/kernel.spec]
+	Implemented LogParamError, LogError functions.
+
+Tue Jun  3 23:46:04 1997  Michiel van Loon <mfvl@xs4all.nl>
+
+	* [include/mmsystem.h] [multimedia/audio.c]
+	Constants for asynchronous play and record.
+
+	* [multimedia/time.c]
+	Filled in some empty functions.
+
+	* [multimedia/mmsystem.c]
+	Fixed bugs in waveOutOpen.
+
+	* [multimedia/mmsystem.c] [multimedia/audio.c]
+	Implemented Window Callback for wave output at least.
+
+	* [files/file.c]
+	Corrected bug in FileDosSetError.
+	NULL pointer checking added.
+
+	* [misc/spy.c]
+	Added Multimedia messages to SPY_GetMsgName.
+
+Tue Jun 3 22:34:30 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [debugger/*.c][include/peexe.h][loader/*.c][tools/build.c]
+	  [tools/fnt2bdf.c][library/sup.c]
+	IMAGE_* structs/defines changed fit better to SDK naming
+	Don't load non-i386 PE executables.
+	%fs should already be initialised for the FIRST loaded PE module.
+
+	* [if1632/advapi.spec][win32/advapi.c]
+	Some small stubs added to bring win32 setup.exe a bit farther.
+
+	* [if1632/kernel32.spec][scheduler/process.c]
+	Adapted to match win95 kernel32.dll ordinals (NT doesn't use
+ 	ordinal import), some ordinal only exported functions added.
+
+	* [if1632/relay.c]
+	Added CallProc32W.
+
+	* [misc/lzexpand.c]
+	Fixed return values of GetExpandedName* (thanks to Andreas Mohr).
+
+	* [objects/dib.c]
+	Everything with more than 8 bit of color is a truecolor mode
+	and doesn't have a colormap.
+
+Tue Jun  3 09:24:53 1997  John Harvey <john@division.co.uk>
+
+	* [graphics/win16drv/font.c] [graphics/win16drv/init.c]
+	  [graphics/win16drv/prtdrv.c] [graphics/win16drv/text.c]
+	  [include/win16drv.h]
+	Changed some structures that are passed to and from the 16 bit
+ 	drivers to be allocated on the global heap.
+	Implemented Escape(Control) 0x100 GetExtTextData properly to
+	stop word from crashing.
+	Postscript driver now prints on complete page instead of top
+	left corner.
+	Print spooling implemented.
+
+	* [loader/module.c]
+	MODULE_GetOrdinal changed char buffer to unsigned char to stop
+	a loop that was happening when running the font control
+	program from the control panel.
+
+Sun Jun  1 19:05:02 1997  Peter Schlaile <up9n@rz.uni-karlsruhe.de>
+
+	* [include/miscemu.h] [loader/main.c] [msdos/ioports.c]
+	Added support for direct io port access.
+
+Fri May 30 16:18:35 1997  David A. Cuthbert <dacut@dssc3353.ece.cmu.edu>
+
+	* [misc/ver.c]
+	Implemented VerFindFile16.
+
+Tue May 27 22:00:39 1997  Rick Richardson <rick@dgii.com>
+
+	* [misc/comm.c]
+	Fixed GetCommError and GetCommEventMask.
+
+Tue May 27  9:10:53 1997  Georg Beyerle <gbeyerle@awi-potsdam.de>
+
+	* [scheduler/thread.c]
+	Minor fix in thread database initialization.
+
+Mon May 26 19:46:34 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>
+
+	* [objects/dc.c]
+	In DC_SetupGCForPen, avoid to draw in GXxor mode with a 0 mask.
+
+Mon May 26 15:22:42 1997  Bruce Milner <Bruce.Milner@genetics.utah.edu>
+
+	* [loader/pe_image.c]
+	Add code for modules that co-reference each other. Photodex's
+	agds.exe (cpic32) has two dll's that make calls into each other.
+
+Mon May 26 13:38:16 1997  Jody Goldberg <jodyg@idt.net>
+
+	* [memory/virtual.c]
+	Dont use stdio when reading /proc/self/maps.  It causes problems
+	with libc6.
+
+	* [windows/dialog.c]
+	Translate messages in IsDialogMessage when DLGC_WANTMESSAGE
+	is used.
+
+Sun May 25 17:02:21 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [objects/metafile.c]
+	Resource cleanup in EnumMetaFile(). This was one reason Word was
+	crashing after long periods of use. (Thanks to Chris Underhill for
+	the logs)
+
+Sun May 25 14:59:33 1997  Jimen Ching  <jching@flex.com>
+
+	* [multimedia/mcistring.c]
+	Initial support for compound MCI commands.
+	Use case-insensitive compare for 'alias' and 'element' keywords.
+	Fixed pointer copy of args keywords array.
+
+----------------------------------------------------------------------
 Tue May 20 19:20:23 1997  Pablo Saratxaga <srtxg@linux.chanae.stben.be>
 
 	* [resources/sysres_Es.rc]
diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS
index f376a22..14b47e1 100644
--- a/DEVELOPERS-HINTS
+++ b/DEVELOPERS-HINTS
@@ -239,3 +239,13 @@
 You have to start tools/make_debug only if you introduced a new macro,
 e.g.  dprintf_win32s - not if you just changed one of the #define
 DEBUG_XXX's in include/stddebug.h or in a specific file.
+
+MORE INFO
+=========
+
+1. http://www.sonic.net/~undoc/bookstore.html
+
+2. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner".
+
+3. You might want to check out BYTE from December 1983 as well :-)
+
diff --git a/README b/README
index 5dd7ba7..17bb9ec 100644
--- a/README
+++ b/README
@@ -74,6 +74,9 @@
 Have a nice game of solitaire, but be careful.  Emulation isn't perfect.
 So, occasionally it may crash.
 
+UPDATE: Windows 95 components are known to cause more crashes compared
+        to the equivalent Windows 3.1 libraries.
+
 
 5. GETTING MORE INFORMATION
 
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 09188b5..3379b18 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -10,6 +10,7 @@
 	combo.c \
 	desktop.c \
 	edit.c \
+	icontitle.c \
 	listbox.c \
 	menu.c \
 	scroll.c \
diff --git a/controls/combo.c b/controls/combo.c
index cd1a6b5..3771933 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -152,7 +152,8 @@
 
        if( lphc->hFont ) hPrevFont = SelectObject16( hDC, lphc->hFont );
    
-       GetTextExtentPoint16( hDC, "X", 1, &size);
+       GetTextExtentPoint16( hDC, "0", 1, &size);
+
        size.cy += size.cy / 4 + 4 * SYSMETRICS_CYBORDER;
 
        if( hPrevFont ) SelectObject16( hDC, hPrevFont );
diff --git a/controls/icontitle.c b/controls/icontitle.c
new file mode 100644
index 0000000..1864086
--- /dev/null
+++ b/controls/icontitle.c
@@ -0,0 +1,244 @@
+/*
+ * Icontitle window class.
+ *
+ * Copyright 1997 Alex Korobka
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "windows.h"
+#include "sysmetrics.h"
+#include "syscolor.h"
+#include "win.h"
+#include "desktop.h"
+#include "graphics.h"
+#include "heap.h"
+
+static  LPCSTR	emptyTitleText = "<...>";
+
+	BOOL32	bMultiLineTitle;
+	HFONT32	hIconTitleFont;
+
+/***********************************************************************
+ *           ICONTITLE_Init
+ */
+BOOL32 ICONTITLE_Init(void)
+{
+    LOGFONT16 logFont;
+
+    SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0, &logFont, 0 );
+    SystemParametersInfo16( SPI_GETICONTITLEWRAP, 0, &bMultiLineTitle, 0 );
+    hIconTitleFont = CreateFontIndirect16( &logFont );
+    return (hIconTitleFont) ? TRUE : FALSE;
+}
+
+/***********************************************************************
+ *           ICONTITLE_Create
+ */
+HWND32 ICONTITLE_Create( WND* wnd )
+{
+    WND* wndPtr;
+    HWND32 hWnd;
+
+    if( wnd->dwStyle & WS_CHILD )
+	hWnd = CreateWindowEx32A( 0, ICONTITLE_CLASS_ATOM, NULL,
+				  WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 1, 1,
+				  wnd->parent->hwndSelf, 0, wnd->hInstance, NULL );
+    else
+	hWnd = CreateWindowEx32A( 0, ICONTITLE_CLASS_ATOM, NULL,
+				  WS_CLIPSIBLINGS, 0, 0, 1, 1,
+				  wnd->hwndSelf, 0, wnd->hInstance, NULL );
+    wndPtr = WIN_FindWndPtr( hWnd );
+    if( wndPtr )
+    {
+	wndPtr->owner = wnd;	/* MDI depends on this */
+	wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER);
+	if( wnd->dwStyle & WS_DISABLED ) wndPtr->dwStyle |= WS_DISABLED;
+	return hWnd;
+    }
+    return 0;
+}
+
+/***********************************************************************
+ *           ICONTITLE_GetTitlePos
+ */
+static BOOL32 ICONTITLE_GetTitlePos( WND* wnd, LPRECT32 lpRect )
+{
+    LPSTR str;
+    int length = lstrlen32A( wnd->owner->text );
+
+    if( length )
+    {
+	str = HeapAlloc( GetProcessHeap(), 0, length + 1 );
+	lstrcpy32A( str, wnd->owner->text );
+	while( str[length - 1] == ' ' ) /* remove trailing spaces */
+	{ 
+	    str[--length] = '\0';
+	    if( !length )
+	    {
+		HeapFree( GetProcessHeap(), 0, str );
+		break;
+	    }
+	}
+    }
+    if( !length ) 
+    {
+	str = (LPSTR)emptyTitleText;
+	length = lstrlen32A( str );
+    }
+
+    if( str )
+    {
+	HDC32 hDC = GetDC32( wnd->hwndSelf );
+	if( hDC )
+	{
+	    HFONT32 hPrevFont = SelectObject32( hDC, hIconTitleFont );
+
+	    SetRect32( lpRect, 0, 0, sysMetrics[SM_CXICONSPACING] -
+		       SYSMETRICS_CXBORDER * 2, SYSMETRICS_CYBORDER * 2 );
+
+	    DrawText32A( hDC, str, length, lpRect, DT_CALCRECT |
+			 DT_CENTER | DT_NOPREFIX | DT_WORDBREAK |
+			 (( bMultiLineTitle ) ? 0 : DT_SINGLELINE) );
+
+	    SelectObject32( hDC, hPrevFont );
+	    ReleaseDC32( wnd->hwndSelf, hDC );
+
+	    lpRect->right += 4 * SYSMETRICS_CXBORDER - lpRect->left;
+	    lpRect->left = wnd->owner->rectWindow.left + SYSMETRICS_CXICON / 2 -
+				      (lpRect->right - lpRect->left) / 2;
+	    lpRect->bottom -= lpRect->top;
+	    lpRect->top = wnd->owner->rectWindow.top + SYSMETRICS_CYICON;
+	}
+	if( str != emptyTitleText ) HeapFree( GetProcessHeap(), 0, str );
+	return ( hDC ) ? TRUE : FALSE;
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           ICONTITLE_Paint
+ */
+static BOOL32 ICONTITLE_Paint( WND* wnd, HDC32 hDC, BOOL32 bActive )
+{
+    HFONT32 hPrevFont;
+    HBRUSH32 hBrush = 0;
+    COLORREF textColor = 0;
+
+    if( bActive )
+    {
+	hBrush = sysColorObjects.hbrushActiveCaption;
+	textColor = GetSysColor32(COLOR_CAPTIONTEXT);
+    }
+    else 
+    {
+	if( wnd->dwStyle & WS_CHILD ) 
+	{ 
+	    hBrush = wnd->parent->class->hbrBackground;
+	    if( hBrush )
+	    {
+		INT32 level;
+		LOGBRUSH32 logBrush;
+		GetObject32A( hBrush, sizeof(logBrush), &logBrush );
+		level = GetRValue(logBrush.lbColor) +
+			   GetGValue(logBrush.lbColor) +
+			      GetBValue(logBrush.lbColor);
+		if( level < (0x7F * 3) )
+		    textColor = RGB( 0xFF, 0xFF, 0xFF );
+	    }
+	    else
+		hBrush = GetStockObject32( WHITE_BRUSH );
+	}
+	else
+	{
+	    hBrush = GetStockObject32( BLACK_BRUSH );
+	    textColor = RGB( 0xFF, 0xFF, 0xFF );    
+	}
+    }
+
+    FillWindow( wnd->parent->hwndSelf, wnd->hwndSelf, hDC, hBrush );
+
+    hPrevFont = SelectObject32( hDC, hIconTitleFont );
+    if( hPrevFont )
+    {
+        RECT16  rect;
+	INT32	length;
+	char	buffer[80];
+
+	rect.left = rect.top = 0;
+	rect.right = wnd->rectWindow.right - wnd->rectWindow.left;
+	rect.bottom = wnd->rectWindow.bottom - wnd->rectWindow.top;
+
+	length = GetWindowText32A( wnd->owner->hwndSelf, buffer, 80 );
+        SetTextColor32( hDC, textColor );
+        SetBkMode32( hDC, TRANSPARENT );
+	
+	DrawText16( hDC, buffer, length, &rect, DT_CENTER | DT_NOPREFIX |
+		    DT_WORDBREAK | ((bMultiLineTitle) ? 0 : DT_SINGLELINE) ); 
+
+	SelectObject32( hDC, hPrevFont );
+    }
+    return ( hPrevFont ) ? TRUE : FALSE;
+}
+
+/***********************************************************************
+ *           IconTitleWndProc
+ */
+LRESULT IconTitleWndProc( HWND32 hWnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam )
+{
+    WND *wnd = WIN_FindWndPtr( hWnd );
+
+    switch( msg )
+    {
+	case WM_NCHITTEST:
+	     return HTCAPTION;
+
+	case WM_NCMOUSEMOVE:
+	case WM_NCLBUTTONDBLCLK:
+	     return SendMessage32A( wnd->owner->hwndSelf, msg, wParam, lParam );	
+
+	case WM_ACTIVATE:
+	     if( wParam ) SetActiveWindow32( wnd->owner->hwndSelf );
+	     /* fall through */
+
+	case WM_CLOSE:
+	     return 0;
+
+	case WM_SHOWWINDOW:
+	     if( wnd && wParam )
+	     {
+		 RECT32 titleRect;
+
+		 ICONTITLE_GetTitlePos( wnd, &titleRect );
+		 if( wnd->owner->next != wnd )	/* keep icon title behind the owner */
+		     SetWindowPos32( hWnd, wnd->owner->hwndSelf, 
+				     titleRect.left, titleRect.top,
+				     titleRect.right, titleRect.bottom, SWP_NOACTIVATE );
+		 else
+		     SetWindowPos32( hWnd, 0, titleRect.left, titleRect.top,
+				     titleRect.right, titleRect.bottom, 
+				     SWP_NOACTIVATE | SWP_NOZORDER );
+	     }
+	     return 0;
+
+	case WM_ERASEBKGND:
+	     if( wnd )
+	     {
+		 WND* iconWnd = wnd->owner;
+
+		 if( iconWnd->dwStyle & WS_CHILD )
+		     lParam = SendMessage32A( iconWnd->hwndSelf, WM_ISACTIVEICON, 0, 0 );
+		 else
+		     lParam = (iconWnd->hwndSelf == GetActiveWindow16());
+
+		 if( ICONTITLE_Paint( wnd, (HDC32)wParam, (BOOL32)lParam ) )
+		     ValidateRect32( hWnd, NULL );
+	         return 1;
+	     }
+    }
+
+    return DefWindowProc32A( hWnd, msg, wParam, lParam );
+}
+
+
diff --git a/controls/listbox.c b/controls/listbox.c
index 48b181f..516fb24 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1731,12 +1731,9 @@
     if (LISTBOX_Timer != LB_TIMER_NONE)
         KillSystemTimer32( wnd->hwndSelf, LB_TIMER_ID );
     LISTBOX_Timer = LB_TIMER_NONE;
-    if (GetCapture32() == wnd->hwndSelf) 
-    {
-	ReleaseCapture();
-        if (descr->style & LBS_NOTIFY)
-            SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
-    }
+    if (GetCapture32() == wnd->hwndSelf) ReleaseCapture();
+    if (descr->style & LBS_NOTIFY)
+        SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
     return 0;
 }
 
diff --git a/controls/widgets.c b/controls/widgets.c
index 729bd6d..7efc765 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -30,6 +30,8 @@
                                LPARAM lParam );
 extern LRESULT PopupMenuWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                                  LPARAM lParam );
+extern LRESULT IconTitleWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
+				 LPARAM lParam );
 
 /* Win16 class info */
 
@@ -85,7 +87,10 @@
       0, 0, IDC_ARROW, 0, 0, DESKTOP_CLASS_NAME },
     /* BIC32_DIALOG */
     { CS_GLOBALCLASS | CS_SAVEBITS, DefDlgProc32A, 0, DLGWINDOWEXTRA,
-      0, 0, IDC_ARROW, 0, 0, DIALOG_CLASS_NAME }
+      0, 0, IDC_ARROW, 0, 0, DIALOG_CLASS_NAME },
+    /* BIC32_ICONTITLE */
+    { CS_GLOBALCLASS, IconTitleWndProc, 0, 0, 
+      0, 0, IDC_ARROW, 0, 0, ICONTITLE_CLASS_NAME }
 };
 
 static ATOM bicAtomTable[BIC32_NB_CLASSES];
diff --git a/debugger/dbg.y b/debugger/dbg.y
index b913c70..cc6d35d 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -547,6 +547,17 @@
 
 
 /***********************************************************************
+ *           DebugBreak32   (KERNEL32)
+ */
+void DebugBreak32( CONTEXT *regs )
+{
+    const char *module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
+    fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
+    DEBUG_context = *regs;
+    DEBUG_Main( SIGTRAP );
+}
+
+/***********************************************************************
  *           DebugBreak16   (KERNEL.203)
  */
 void DebugBreak16( CONTEXT *regs )
diff --git a/debugger/dbgmain.c b/debugger/dbgmain.c
index 7c1992b..04cf7ac 100644
--- a/debugger/dbgmain.c
+++ b/debugger/dbgmain.c
@@ -170,7 +170,7 @@
 	char				* module_name;
 	char				* dbg_info;
 	int				  dbg_size;
-	struct PE_Debug_dir		* dbgdir;
+	LPIMAGE_DEBUG_DIRECTORY		  dbgdir;
 	struct pe_data			* pe;
         LPIMAGE_SECTION_HEADER            sectp;
 	int				  nsect;
@@ -189,7 +189,7 @@
 test_pdbstuff()
 {
   struct deferred_debug_info deefer;
-  struct PE_Debug_dir	dinfo;
+  IMAGE_DEBUG_DIRECTORY dinfo;
   struct CodeViewDebug cdebug;
   IMAGE_SECTION_HEADER  sects[10];
 
@@ -199,7 +199,7 @@
   memset(&sects, 0, sizeof(sects));
 
   deefer.dbg_info = (char *) &cdebug;
-  dinfo.timestamp = 812932395;
+  dinfo.TimeStamp = 812932395;
   cdebug.cv_timestamp = 833392137  /* 841951397 */;
   deefer.dbgdir = &dinfo;
   deefer.sectp = sects;
diff --git a/debugger/msc.c b/debugger/msc.c
index 3668877..61bab5a 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -2135,7 +2135,7 @@
   char			      * codeview;
   struct CV4_DirHead	      * codeview_dir;
   struct CV4_DirEnt	      * codeview_dent;
-  struct PE_Debug_dir	      * dbghdr;
+  LPIMAGE_DEBUG_DIRECTORY	dbghdr;
   struct deferred_debug_info    deefer2;
   int				fd = -1;
   int				i;
@@ -2187,7 +2187,7 @@
 
   fprintf(stderr, "Processing symbols from %s...\n", filename);
 
-  dbghdr = (struct PE_Debug_dir *) (  addr + sizeof(*pdbg) 
+  dbghdr = (LPIMAGE_DEBUG_DIRECTORY) (  addr + sizeof(*pdbg) 
 		 + pdbg->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) 
 		 + pdbg->ExportedNamesSize);
 
@@ -2196,7 +2196,7 @@
 
   for( i=0; i < pdbg->DebugDirectorySize / sizeof(*pdbg); i++, dbghdr++ )
     {
-      switch(dbghdr->type)
+      switch(dbghdr->Type)
 		{
 		case IMAGE_DEBUG_TYPE_COFF:
 		  /*
@@ -2204,8 +2204,8 @@
 		   * COFF stuff embedded within the DBG file.
 		   */
 		  memset((char *) &deefer2, 0, sizeof(deefer2));
-		  deefer2.dbg_info = (addr + dbghdr->dbgoff);
-		  deefer2.dbg_size = dbghdr->dbgsize;
+		  deefer2.dbg_info = (addr + dbghdr->PointerToRawData);
+		  deefer2.dbg_size = dbghdr->SizeOfData;
 		  deefer2.load_addr = deefer->load_addr;
 
 		  DEBUG_ProcessCoff(&deefer2);
@@ -2218,7 +2218,7 @@
 		   * have lots of internal similarities, but the overall
 		   * format and structure is quite different.
 		   */
-		  codeview = (addr + dbghdr->dbgoff);
+		  codeview = (addr + dbghdr->PointerToRawData);
 
 		  /*
 		   * The first thing in the codeview section should be
diff --git a/documentation/fonts b/documentation/fonts
new file mode 100644
index 0000000..3237613
--- /dev/null
+++ b/documentation/fonts
@@ -0,0 +1,111 @@
+
+How To Convert Windows Fonts
+============================
+
+If you have access to Windows installation you should use 
+fnt2bdf utility (found in the 'tools)' directory to convert
+bitmap fonts (SYSTEM.FON, SSERIFE.FON, and SERIFE.FON) into 
+the format that X Window System can recognize.
+
+Step 1. Extract bitmap fonts with 'fnt2bdf'.
+
+Step 2. Convert .bdf files produced by the Step 1 into
+	.pcf files with 'bdftopcf'.
+
+Step 3. Copy .pcf files to the font server directory which
+	is usually /usr/lib/X11/fonts/misc (you will probably 
+        need superuser privileges).
+
+Step 4. Run 'mkfontdir' for the directory you copied fonts to.
+	If you are already in X you should run 'xset fp rehash' 
+        to make X server aware of the new fonts.
+
+Wine can get by without these fonts but 'the look and feel'
+will be quite different. 
+
+What to do with TrueType fonts? There are several commercial
+font tools that can convert them to the Type1 format but the 
+quality of the resulting fonts is far from stellar. The other
+way to use them is to get a font server capable of rendering 
+TrueType (Caldera has one).
+
+However, there is a possibility of the native TrueType support 
+via FreeType renderer in the future (hint, hint :-)
+
+
+WINE.CONF And Font Mapper
+=========================
+
+Many Windows applications assume that fonts included in original Windows 3.1 
+distribution (Arial, Times New Roman, MS Sans Serif, etc.) are always present. 
+In order to make font mapper choose a closely related font you can add aliases
+to the [fonts] section.
+
+AliasN = [Windows font], [X font] <, optional "mask X font" flag>
+
+Example:
+
+Alias0 = System, --international-, mask
+Alias1 = Arial, -adobe-helvetica-
+Alias2 = Times New Roman, -adobe-times-
+...
+
+Comments:
+    There must be no gaps in the sequence {0, ..., N} otherwise all aliases
+    after the first gap won't be read.
+
+    Usually font mapper translates X font names into font names visible to
+    Windows programs in the following fashion:
+
+    X font			Converted name
+
+    -adobe-helvetica-...	"Helvetica"
+    -adobe-utopia-...		"Utopia"
+    -misc-fixed-...		"Fixed"
+    -...
+    -sony-fixed-...		"Sony Fixed"  (already have "Fixed")
+    -...
+
+    Only converted names appear in the font selection dialogs. However, 
+    if there is an alias with the "mask" flag set converted name will be 
+    replaced by this alias.
+
+    --international-		"System"
+
+    Nonmasking aliases are translated only when program asks for a font
+    with the name that matches an alias.
+
+    If you do not have an access to Windows fonts mentioned in the first 
+    paragraph you should try to substitute them with similar X fonts.
+
+    Alias.. = System, ...bold font without serifs
+    Alias.. = MS Sans Serif, ...helvetica-like font
+
+Also, some Windows applications request fonts without specifying the 
+typeface name of the font. Font table starts with Arial in most Windows 
+installations, however X font table starts with whatever is the first line 
+in the fonts.dir.  Therefore WINE uses the following entry to determine 
+which font to check first.
+
+Default = ...
+
+Comments:
+    It is better to have a scalable font family (bolds and italics included) 
+    as the default choice because mapper checks all available fonts until 
+    requested height and other attributes match perfectly or the end of the 
+    font table is reached.
+
+
+Cached Font Metrics
+===================
+
+WINE stores detailed information about available fonts in the ~/.wine/.cachedmetrics
+file. You can copy it elsewhere and add this entry to the [fonts] section 
+in the WINE.CONF:
+
+FontMetrics = <file with metrics>
+
+If WINE detects changes in the X font configuration it will rebuild font
+metrics from scratch and then it will overwrite ~/.wine/.cachedmetrics with 
+the new information. This process can take a while.
+
diff --git a/documentation/user_module b/documentation/internals
similarity index 97%
rename from documentation/user_module
rename to documentation/internals
index 8cff4cb..9308036 100644
--- a/documentation/user_module
+++ b/documentation/internals
@@ -1,3 +1,13 @@
+KERNEL MODULE
+=============
+
+...
+
+GDI MODULE
+==========
+
+...
+
 USER MODULE
 ===========
 
@@ -20,11 +30,11 @@
    ancestor link (wnd->parent) points to the desktop window.
 
    Desktop window			- root window
-    |     \      '-.
-    |      \        '-.
+    |     \      `-.
+    |      \        `-.
    popup -> wnd1  ->  wnd2		- top level windows    
-    |       \   '-.      '-.
-    |        \     '-.      '-.
+    |       \   `-.      `-.
+    |        \     `-.      `-.
    child1  child2 -> child3  child4     - child windows
   
    Horizontal arrows denote sibling relationship, vertical lines
@@ -36,7 +46,7 @@
    sibling list (they are not topmost). Child windows are confined to the
    client area of their parent windows (client area is where window gets
    to do its own drawing, non-client area consists of caption, menu, borders,
-   intrinsic scrollbars, and minimize/maximize/close buttons). 
+   intrinsic scrollbars, and minimize/maximize/close/help buttons). 
   
    Another fairly important concept is "z-order". It is derived from
    the ancestor/child hierarchy and is used to determine "above/below"
@@ -50,7 +60,7 @@
 
    Wine specifics: in default and managed mode each top-level window
    gets its own X counterpart with desktop window being basically a 
-   fake stub. In desktop mode, however, only desktop window has X
+   fake stub. In desktop mode, however, only desktop window has an X
    window associated with it.
 
 2. Messaging subsystem
@@ -214,3 +224,4 @@
        queue for sent messages. Another issue is what to do with messages 
        sent to the sender when it is blocked inside its own SendMessage. 
 
+
diff --git a/documentation/wine_os2.txt b/documentation/wine_os2
similarity index 100%
rename from documentation/wine_os2.txt
rename to documentation/wine_os2
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 38a84c8..5bb8b35 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -809,6 +809,8 @@
 
     dprintf_dosfs( stddeb, "GetFullPathName: converting %s\n", name );
 
+    if (!name || !result) return 0;
+
     if ((drive = DOSFS_GetPathDrive( &name )) == -1) return 0;
     p = buffer;
     *p++ = 'A' + drive;
diff --git a/files/file.c b/files/file.c
index 1ff6c21..1625f39 100644
--- a/files/file.c
+++ b/files/file.c
@@ -129,8 +129,10 @@
  */
 void FILE_SetDosError(void)
 {
+    int save_errno = errno; /* errno gets overwritten by printf */
+
     dprintf_file(stddeb, "FILE_SetDosError: errno = %d\n", errno );
-    switch (errno)
+    switch (save_errno)
     {
     case EAGAIN:
         DOS_ERROR( ER_ShareViolation, EC_Temporary, SA_Retry, EL_Disk );
@@ -167,6 +169,7 @@
         DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort, EL_Unknown );
         break;
     }
+    errno = save_errno;
 }
 
 
@@ -239,6 +242,9 @@
     const char *unixName;
 
     dprintf_file(stddeb, "FILE_Open: '%s' %04x\n", path, mode );
+
+    if (!path) return HFILE_ERROR32;
+
     if ((unixName = DOSFS_IsDevice( path )) != NULL)
     {
         dprintf_file( stddeb, "FILE_Open: opening device '%s'\n", unixName );
@@ -271,6 +277,8 @@
 
     dprintf_file(stddeb, "FILE_Create: '%s' %04x %d\n", path, mode, unique );
 
+    if (!path) return INVALID_HANDLE_VALUE32;
+
     if ((unixName = DOSFS_IsDevice( path )) != NULL)
     {
         dprintf_file(stddeb, "FILE_Create: creating device '%s'!\n", unixName);
@@ -338,6 +346,8 @@
 {
     struct stat st;
 
+    if (!unixName || !info) return FALSE;
+
     if (stat( unixName, &st ) == -1)
     {
         FILE_SetDosError();
@@ -358,6 +368,8 @@
     DWORD ret = 0;
     struct stat st;
 
+    if (!info) return 0;
+
     if (!(file = FILE_GetFile( hFile ))) return 0;
     if (fstat( file->unix_handle, &st ) == -1) FILE_SetDosError();
     else
@@ -387,6 +399,8 @@
     DOS_FULL_NAME full_name;
     BY_HANDLE_FILE_INFORMATION info;
 
+    if (name == NULL) return -1;
+
     if (!DOSFS_GetFullName( name, TRUE, &full_name )) return -1;
     if (!FILE_Stat( full_name.long_name, &info )) return -1;
     return info.dwFileAttributes;
@@ -436,6 +450,8 @@
  */
 INT32 CompareFileTime( LPFILETIME x, LPFILETIME y )
 {
+        if (!x || !y) return -1;
+
 	if (x->dwHighDateTime > y->dwHighDateTime)
 		return 1;
 	if (x->dwHighDateTime < y->dwHighDateTime)
@@ -521,7 +537,8 @@
     LPSTR p;
     UINT32 num = unique ? (unique & 0xffff) : time(NULL) & 0xffff;
 
-    if (!path) return 0;
+    if ( !path || !prefix || !buffer ) return 0;
+
     strcpy( buffer, path );
     p = buffer + strlen(buffer);
     /* add a \, if there isn't one ... */
@@ -604,6 +621,13 @@
     char *p;
     int unixMode;
 
+    if (!name || !ofs) return HFILE_ERROR32;
+
+    if (!name) {
+	fprintf(stderr, "ERROR: FILE_DoOpenFile() called with `name' set to NULL ! Please debug.\n");
+ 
+	return HFILE_ERROR32;
+    }
     ofs->cBytes = sizeof(OFSTRUCT);
     ofs->nErrCode = 0;
     if (mode & OF_REOPEN) name = ofs->szPathName;
diff --git a/files/profile.c b/files/profile.c
index 06b8b70..d537a8e 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -116,7 +116,7 @@
 
     for ( ; section; section = section->next)
     {
-        if (section->name) fprintf( file, "[%s]\r\n", section->name );
+        if (section->name) fprintf( file, "\r\n[%s]\r\n", section->name );
         for (key = section->key; key; key = key->next)
         {
             fprintf( file, "%s", key->name );
@@ -211,7 +211,7 @@
         }
         key = HEAP_xalloc( SystemHeap, 0, sizeof(*key) );
         key->name  = HEAP_strdupA( SystemHeap, 0, p );
-        key->value = HEAP_strdupA( SystemHeap, 0, p2 );
+        key->value = p2 ? HEAP_strdupA( SystemHeap, 0, p2 ) : NULL;
         key->next  = NULL;
         *prev_key  = key;
         prev_key = &key->next;
@@ -642,6 +642,33 @@
 }
 
 
+/***********************************************************************
+ *           PROFILE_GetStringItem
+ *
+ *  Convenience function that turns a string 'xxx, yyy, zzz' into 
+ *  the 'xxx\0 yyy, zzz' and returns a pointer to the 'yyy, zzz'.
+ */
+char* PROFILE_GetStringItem( char* start )
+{
+    char* lpchX, *lpch;
+
+    for (lpchX = start, lpch = NULL; *lpchX != '\0'; lpchX++ )
+    {
+        if( isspace( *lpchX ) ) lpch = lpch ? lpch : lpchX;
+        else lpch = NULL;
+
+        if( *lpchX == ',' )
+        {
+            if( lpch ) *lpch = '\0'; else *lpchX = '\0';
+            while( *(++lpchX) )
+                if( !isspace(*lpchX) ) return lpchX;
+        }
+    }
+    if( lpch ) *lpch = '\0';
+    return NULL;
+}
+
+
 /********************* API functions **********************************/
 
 /***********************************************************************
diff --git a/graphics/painting.c b/graphics/painting.c
index ce6a395..bad5182 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -478,7 +478,7 @@
 /***********************************************************************
  *           DrawFocusRect32    (USER32.155)
  *
- * FIXME: should use Rectangle32!
+ * FIXME: PatBlt(PATINVERT) with background brush.
  */
 void DrawFocusRect32( HDC32 hdc, const RECT32* rc )
 {
@@ -747,10 +747,10 @@
 /**********************************************************************
  *          DrawFrameControl16  (USER.656)
  */
-BOOL16 DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
+BOOL16 DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
 {
     fprintf( stdnimp,"DrawFrameControl16(%x,%p,%d,%x), empty stub!\n",
-             hdc,rc,edge,flags );
+             hdc,rc,uType,uState );
     return TRUE;
 }
 
@@ -758,9 +758,9 @@
 /**********************************************************************
  *          DrawFrameControl32  (USER32.157)
  */
-BOOL32 DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
+BOOL32 DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 uState )
 {
     fprintf( stdnimp,"DrawFrameControl32(%x,%p,%d,%x), empty stub!\n",
-             hdc,rc,edge,flags );
+             hdc,rc,uType,uState );
     return TRUE;
 }
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index db761f1..85edff4 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -19,11 +19,6 @@
 {
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
     DWORD dwRet;
-    extern DRAWMODE DrawMode;
-    LPDRAWMODE lpDrawMode = &DrawMode;
-    TEXTXFORM16 TextXForm;
-    LPTEXTXFORM16 lpTextXForm = &TextXForm;
-    InitTextXForm(lpTextXForm);
     
     printf("LPGDI_GetTextExtPoint: %04x %s %d %p\n", dc->hSelf, str, count, size);
 
@@ -37,8 +32,8 @@
 
     dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
 			      NULL, str, 
-			      -count,  physDev->segptrFontInfo, lpDrawMode, 
-			      lpTextXForm, NULL, NULL, 0);
+			      -count,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
+			      win16drv_SegPtr_TextXForm, NULL, NULL, 0);
     printf("LPGDI_GetTextExtPoint: cx=0x%x, cy=0x%x Ret 0x%lx\n", size->cx, size->cy, dwRet);
 
     return TRUE;
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index da9e60b..ff48059 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -27,19 +28,19 @@
 typedef struct
 {
   SHORT nSize;
-  LPVOID lpindata;
-  LPVOID lpFont;
-  LPVOID lpXForm;
-  LPVOID lpDrawMode;
+  SEGPTR lpindata;
+  SEGPTR lpFont;
+  SEGPTR lpXForm;
+  SEGPTR lpDrawMode;
 } EXTTEXTDATA, *LPEXTTEXTDATA;
 #pragma pack(4)
 
-#if 0
-static BOOL16 windrvExtTextOut16( DC *dc, INT16 x, INT16 y, UINT16 flags, const RECT16 * lprect,
-                                 LPCSTR str, UINT16 count, const INT16 *lpDx);
-#endif
+SEGPTR		win16drv_SegPtr_TextXForm;
+LPTEXTXFORM16 	win16drv_TextXFormP;
+SEGPTR		win16drv_SegPtr_DrawMode;
+LPDRAWMODE 	win16drv_DrawModeP;
 
-DRAWMODE DrawMode;
+
 static BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
                                  LPCSTR output, const DEVMODE16* initData );
 static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput, 
@@ -222,10 +223,8 @@
     int nPDEVICEsize;
     PDEVICE_HEADER *pPDH;
     WIN16DRV_PDEVICE *physDev;
-    LPDRAWMODE lpDrawMode = &DrawMode;
 
     /* Realizing fonts */
-    TEXTXFORM16 TextXForm;
     int nSize;
     char printerEnabled[20];
     PROFILE_GetWineIniString( "wine", "printer", "off",
@@ -339,21 +338,24 @@
 	   &pLPD->paPrinterFonts[0].tm, 
 	   sizeof(TEXTMETRIC16));
 
+    win16drv_SegPtr_TextXForm = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(TEXTXFORM16)));
+    win16drv_TextXFormP = PTR_SEG_TO_LIN(win16drv_SegPtr_TextXForm);
+    
+    InitTextXForm(win16drv_TextXFormP);
 #ifdef SUPPORT_REALIZED_FONTS
     /* TTD should calculate this */
-    InitTextXForm(&TextXForm);
     
     /* First get the size of the realized font */
     nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, OBJ_FONT,
 				 &pLPD->paPrinterFonts[0], NULL, 
-				 NULL);
+				 0);
     
     physDev->segptrFontInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
     /* Realize the font */
     PRTDRV_RealizeObject(physDev->segptrPDEVICE, OBJ_FONT,
 			 &pLPD->paPrinterFonts[0], 
 			 (LPVOID)physDev->segptrFontInfo, 
-			 &TextXForm);
+			 win16drv_SegPtr_TextXForm);
     /* Quick look at structure */
     if (physDev->segptrFontInfo)
     {  
@@ -368,7 +370,10 @@
 
 #endif
     /* TTD Lots more to do here */
-    InitDrawMode(lpDrawMode);
+    win16drv_SegPtr_DrawMode = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(DRAWMODE)));
+    win16drv_DrawModeP = PTR_SEG_TO_LIN(win16drv_SegPtr_DrawMode);
+    
+    InitDrawMode(win16drv_DrawModeP);
 
     return TRUE;
 }
@@ -389,23 +394,29 @@
     {
 	switch(nEscape)
 	{
-	  case 0x9:
+	  case SETABORTPROC:
 	    printf("Escape: SetAbortProc ignored\n");
 	    break;
-	case 0x100:
+
+	  case GETEXTENDEDTEXTMETRICS:
 	  {
-	    LPEXTTEXTDATA textData =  PTR_SEG_TO_LIN(lpInData);
-	    printf("Got in data 0x%lx textData 0x%p\n",lpInData, textData);
-	    printf("size %d in 0x%p:0x%p font 0x%p:0x%p xform 0x%p:0x%p drawm 0x%p:0x%p\n",
-		   textData->nSize,
-		   textData->lpindata,PTR_SEG_TO_LIN(textData->lpindata),
-		   textData->lpFont,PTR_SEG_TO_LIN(textData->lpFont),
-		   textData->lpXForm,PTR_SEG_TO_LIN(textData->lpXForm),
-		   textData->lpDrawMode,PTR_SEG_TO_LIN(textData->lpDrawMode));
+	    SEGPTR newInData =  WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(EXTTEXTDATA)));
+            EXTTEXTDATA *textData = (EXTTEXTDATA *)(PTR_SEG_TO_LIN(newInData));
+
+	    textData->nSize = cbInput;
+	    textData->lpindata = lpInData;
+	    textData->lpFont = physDev->segptrFontInfo;
+	    textData->lpXForm = win16drv_SegPtr_TextXForm;
+	    textData->lpDrawMode = win16drv_SegPtr_DrawMode;
+	    nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
+				  newInData, lpOutData);
+	    GlobalFree16(newInData);
+            
 	  }
-	    break;
+        break;
+        
 	  default:
-	    nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape, 
+	    nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
 				  lpInData, lpOutData);
 	}
     }
@@ -540,19 +551,58 @@
 /* TTD Need to do some DOS->UNIX file conversion here */
 static int CreateSpoolFile(LPSTR pszOutput)
 {
-    int fd;
-    char szSpoolFile[32];
+    int fd=-1;
+    char psCmd[1024];
+    char *psCmdP = psCmd;
 
     /* TTD convert the 'output device' into a spool file name */
 
     if (pszOutput == NULL || *pszOutput == '\0')
-	strcpy(szSpoolFile,"lp.out");
-    else
-	strcpy(szSpoolFile, pszOutput);
+      return -1;
 
-    if ((fd = open(szSpoolFile, O_CREAT | O_TRUNC | O_WRONLY , 0600)) < 0)
+    PROFILE_GetWineIniString( "spooler", pszOutput, "",
+                              psCmd, sizeof(psCmd) );
+    printf("Got printerSpoolCOmmand \"%s\"\n",psCmd);
+    if (!*psCmd)
+        psCmdP = pszOutput;
+    else
     {
-	printf("Failed to create spool file %s, errno = %d\n", szSpoolFile, errno);
+        while (*psCmdP && isspace(*psCmdP))
+        {
+            psCmdP++;
+        };
+        if (!*psCmdP)
+            return -1;
+    }
+    if (*psCmdP == '|')
+    {
+        int fds[2];
+        if (pipe(fds))
+            return -1;
+        if (fork() == 0)
+        {
+            psCmdP++;
+
+            printf("In child need to exec %s\n",psCmdP);
+            close(0);
+            dup2(fds[0],0);
+            close (fds[1]);
+            system(psCmdP);
+            exit(0);
+            
+        }
+        close (fds[0]);
+        fd = fds[1];
+        printf("Need to execut a command and pipe the output to it\n");
+    }
+    else
+    {
+        printf("Just assume its a file\n");
+
+        if ((fd = open(psCmdP, O_CREAT | O_TRUNC | O_WRONLY , 0600)) < 0)
+        {
+            printf("Failed to create spool file %s, errno = %d\n", psCmdP, errno);
+        }
     }
     return fd;
 }
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 2864742..672dc89 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -433,8 +433,8 @@
  * RealizeObject (ordinal 10)
  */
 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle, 
-		    LPVOID lpInObj, LPVOID lpOutObj,
-                    LPTEXTXFORM16 lpTextXForm)
+                           LPVOID lpInObj, LPVOID lpOutObj,
+                           SEGPTR lpTextXForm)
 {
     WORD dwRet = 0;
     LOADED_PRINTER_DRIVER *pLPD = NULL;
@@ -473,14 +473,7 @@
 	
 	lP4 = (LONG)lpOutObj;
 
-	if (lpTextXForm != NULL)
-	{
-	    lP5 = SegPtr;
-	    nSize = sizeof(TEXTXFORM16);
-	    AddData(&SegPtr, lpTextXForm, nSize, Limit);	
-	}
-	else
-	  lP5 = 0L;
+        lP5 = lpTextXForm;
 
 	dwRet = CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT], 
                                     lP1, wP2, lP3, lP4, lP5);
@@ -493,8 +486,8 @@
 
 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
                         RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, 
-                        SEGPTR lpFontInfo, LPDRAWMODE lpDrawMode, 
-                        LPTEXTXFORM16 lpTextXForm, SHORT *lpCharWidths,
+                        SEGPTR lpFontInfo, SEGPTR lpDrawMode, 
+                        SEGPTR lpTextXForm, SHORT *lpCharWidths,
                         RECT16 *     lpOpaqueRect, WORD wOptions)
 {
     DWORD dwRet = 0;
@@ -550,27 +543,8 @@
 	
 	/* This should be realized by the driver, so in 16bit data area */
 	lP7 = lpFontInfo;
-	
-	if (lpDrawMode != NULL)
-	{
-	    lP8 = SegPtr;
-	    nSize = sizeof(DRAWMODE);
-            dprintf_win16drv(stddeb, "adding lpDrawMode\n");
-            
-	    AddData(&SegPtr, lpDrawMode, nSize, Limit);	
-	}
-	else
-	  lP8 = 0L;
-	
-	if (lpTextXForm != NULL)
-	{
-	    lP9 = SegPtr;
-	    nSize = sizeof(TEXTXFORM16);
-            dprintf_win16drv(stddeb, "Adding TextXForm\n");
-	    AddData(&SegPtr, lpTextXForm, nSize, Limit);	
-	}
-	else
-	  lP9 = 0L;
+        lP8 = lpDrawMode;
+        lP9 = lpTextXForm;
 	
 	if (lpCharWidths != NULL) 
 	  dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: Char widths not supported\n");
@@ -595,9 +569,9 @@
                                            lP1, wP2, wP3, lP4, 
 					   lP5, iP6, lP7, lP8, lP9, lP10,
 					   lP11, wP12);
-        if (lpDrawMode)
-            GetParamData(lP8, lpDrawMode, sizeof(DRAWMODE));
     }
     dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: return %lx\n", dwRet);
     return dwRet;
 }
+
+
diff --git a/graphics/win16drv/text.c b/graphics/win16drv/text.c
index 903d6c8..6d1876e 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -22,14 +22,9 @@
 {
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
     BOOL32 bRet = 1;
-    extern DRAWMODE DrawMode;
-    LPDRAWMODE lpDrawMode = &DrawMode;
-    TEXTXFORM16 TextXForm;
-    LPTEXTXFORM16 lpTextXForm = &TextXForm;
-    RECT16 rcClipRect;
-    RECT16 * lpClipRect = &rcClipRect;
-    RECT16 rcOpaqueRect;
-    RECT16 *lpOpaqueRect = &rcOpaqueRect;
+    RECT16	 clipRect;
+    RECT16 	 opaqueRect;
+    RECT16 	*lpOpaqueRect = NULL; 
     WORD wOptions = 0;
     WORD wCount = count;
 
@@ -43,7 +38,6 @@
     dprintf_win16drv(stddeb, "WIN16DRV_ExtTextOut: %04x %d %d %x %p %*s %p\n", dc->hSelf, x, y, 
 	   flags,  lprect, count > 0 ? count : 8, str, lpDx);
 
-    InitTextXForm(lpTextXForm);
 
     if (bInit == FALSE)
     {
@@ -51,50 +45,30 @@
 
 	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
 				  NULL, " ", 
-				  -1,  physDev->segptrFontInfo, lpDrawMode, 
-				  lpTextXForm, NULL, NULL, 0);
+				  -1,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
+				  win16drv_SegPtr_TextXForm, NULL, NULL, 0);
 	bInit = TRUE;
     }
 
     if (dc != NULL)   
     {
 	DWORD dwRet;
-/*
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
-				  NULL, "0", 
-				  -1,  physDev->segptrFontInfo, lpDrawMode, 
-				  lpTextXForm, NULL, NULL, 0);
-
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
-				  NULL, str, -wCount,
-				  physDev->segptrFontInfo, lpDrawMode, 
-				  lpTextXForm, NULL, NULL, 0);
-*/
+	clipRect.left = 0;
+	clipRect.top = 0;
+        
+	clipRect.right = dc->w.devCaps->horzRes;
+	clipRect.bottom = dc->w.devCaps->vertRes;
+        if (lprect)
+        {
+            opaqueRect.left = lprect->left;
+            opaqueRect.top = lprect->top;
+            opaqueRect.right = lprect->right;
+            opaqueRect.bottom = lprect->bottom;
+            lpOpaqueRect = &opaqueRect;
+            
+        }
+        
 #ifdef NOTDEF
-	lpClipRect->left = lprect->left ;
-	lpClipRect->top = lprect->top;
-	lpClipRect->right = lprect->right;
-	lpClipRect->bottom = lprect->bottom;
-        dprintf_win16drv(stddeb, "WIN16DRV_ExtTextOut Clip rect left %d top %d rigt %d bottom %d\n",
-                         lpClipRect->left,lpClipRect->top,lpClipRect->right,lpClipRect->bottom);
-#endif
-	lpClipRect->left = 0;
-	lpClipRect->top = 0;
-	lpClipRect->right = 0x3fc;
-	lpClipRect->bottom = 0x630;
-        dprintf_win16drv(stddeb, "WIN16DRV_ExtTextOut Clip rect left %d top %d rigt %d bottom %d\n",
-                         lpClipRect->left,lpClipRect->top,lpClipRect->right,lpClipRect->bottom);
-	lpOpaqueRect->left = x;
-	lpOpaqueRect->top = y;
-	lpOpaqueRect->right = 0x3a1;
-	lpOpaqueRect->bottom = 0x01;
-        printf("drawmode ropt 0x%x bkMode 0x%x bkColor 0x%lx textColor 0x%lx tbbreakExtra 0x%x breakextra 0x%x\n",
-               lpDrawMode->Rop2,    lpDrawMode->bkMode,    lpDrawMode->bkColor,
-               lpDrawMode->TextColor,    lpDrawMode->TBreakExtra,    lpDrawMode->BreakExtra);
-        printf("breakerr 0x%x breakrem 0x%x breakcount 0x%x chextra 0x%x lbkcolor 0x%lx ltextcolor 0x%lx\n",
-               lpDrawMode->BreakErr,    lpDrawMode->BreakRem,    lpDrawMode->BreakCount,
-               lpDrawMode->CharExtra,	   lpDrawMode->LbkColor,    lpDrawMode->LTextColor);
-
     {
         RECT16 rcPageSize;
 	FONTINFO16 *p = (FONTINFO16 *)PTR_SEG_TO_LIN(physDev->segptrFontInfo);
@@ -121,18 +95,12 @@
         }
         
     }
-        
+#endif        
 
 	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, x, y, 
-				  lpClipRect, str, 
-				  wCount,  physDev->segptrFontInfo, lpDrawMode, 
-				  lpTextXForm, NULL, NULL, wOptions);
-/*
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, x, y, 
-				  lpClipRect, str, 
-				  wCount,  physDev->segptrFontInfo, lpDrawMode, 
-				  lpTextXForm, lpDx, NULL, flags);
-*/
+				  &clipRect, str, 
+				  wCount,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
+				  win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect, wOptions);
     }
     return bRet;
 }
diff --git a/graphics/x11drv/Makefile.in b/graphics/x11drv/Makefile.in
index daa860c..d7fc1fd 100644
--- a/graphics/x11drv/Makefile.in
+++ b/graphics/x11drv/Makefile.in
@@ -10,7 +10,7 @@
 	bitmap.c \
 	brush.c \
 	clipping.c \
-	font.c \
+	xfont.c \
 	graphics.c \
 	init.c \
 	objects.c \
diff --git a/graphics/x11drv/font.c b/graphics/x11drv/font.c
deleted file mode 100644
index 7826db6..0000000
--- a/graphics/x11drv/font.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * X11 driver font functions
- *
- * Copyright 1996 Alexandre Julliard
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xatom.h>
-#include "font.h"
-#include "heap.h"
-#include "metafile.h"
-#include "options.h"
-#include "xmalloc.h"
-#include "stddebug.h"
-#include "debug.h"
-
-
-struct FontStructure {
-	char *window;
-	char *x11;
-} FontNames[32];
-int FontSize;
-
-#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
-			     (((cs)->rbearing|(cs)->lbearing| \
-			       (cs)->ascent|(cs)->descent) == 0))
-
-/* 
- * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
- * character.  If the character is in the column and exists, then return the
- * appropriate metrics (note that fonts with common per-character metrics will
- * return min_bounds).  If none of these hold true, try again with the default
- * char.
- */
-#define CI_GET_CHAR_INFO(fs,col,def,cs) \
-{ \
-    cs = def; \
-    if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
-	if (fs->per_char == NULL) { \
-	    cs = &fs->min_bounds; \
-	} else { \
-	    cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
-	    if (CI_NONEXISTCHAR(cs)) cs = def; \
-	} \
-    } \
-}
-
-#define CI_GET_DEFAULT_INFO(fs,cs) \
-  CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
-
-
-/***********************************************************************
- *           X11DRV_FONT_Init
- */
-BOOL32 X11DRV_FONT_Init( void )
-{
-  char  temp[1024];
-  LPSTR ptr;
-  int i;
-
-  if (PROFILE_GetWineIniString( "fonts", NULL, "*", temp, sizeof(temp) ) > 2 )
-  {
-    for( ptr = temp, i = 1; strlen(ptr) != 0; ptr += strlen(ptr) + 1 )
-      if( strcmp( ptr, "default" ) )
-	FontNames[i++].window = xstrdup( ptr );
-    FontSize = i;
-
-    for( i = 1; i < FontSize; i++ )
-    {
-        PROFILE_GetWineIniString( "fonts", FontNames[i].window, "*",
-                                  temp, sizeof(temp) );
-        FontNames[i].x11 = xstrdup( temp );
-    }
-    PROFILE_GetWineIniString( "fonts", "default", "*", temp, sizeof(temp) );
-    FontNames[0].x11 = xstrdup( temp );
-
-  } else {
-    FontNames[0].window = NULL; FontNames[0].x11 = "*-helvetica";
-    FontNames[1].window = "ms sans serif"; FontNames[1].x11 = "*-helvetica";
-    FontNames[2].window = "ms serif"; FontNames[2].x11 = "*-times";
-    FontNames[3].window = "fixedsys"; FontNames[3].x11 = "*-fixed";
-    FontNames[4].window = "arial"; FontNames[4].x11 = "*-helvetica";
-    FontNames[5].window = "helv"; FontNames[5].x11 = "*-helvetica";
-    FontNames[6].window = "roman"; FontNames[6].x11 = "*-times";
-    FontNames[7].window = "system"; FontNames[7].x11 = "*-helvetica";
-    FontSize = 8;
-  }
-  return TRUE;
-}
-/***********************************************************************
- *           FONT_ChkX11Family
- *
- * returns a valid X11 equivalent if a Windows face name 
- * is like a X11 family  - or NULL if translation is needed
- */
-static char *FONT_ChkX11Family(char *winFaceName )
-{
-  static char x11fam[32+2];   /* will be returned */
-  int i;
-
-  for(i = 0; lpLogFontList[i] != NULL; i++)
-    if( !lstrcmpi32A(winFaceName, lpLogFontList[i]->lfFaceName) )
-    {
-	strcpy(x11fam,"*-");
-	return strcat(x11fam,winFaceName);
-    }    
-  return NULL;               /* a FONT_TranslateName() call is needed */
-}
-
-
-
-/***********************************************************************
- *           FONT_TranslateName
- *
- * Translate a Windows face name to its X11 equivalent.
- * This will probably have to be customizable.
- */
-static const char *FONT_TranslateName( char *winFaceName )
-{
-  int i;
-
-  for (i = 1; i < FontSize; i ++)
-    if( !lstrcmpi32A( winFaceName, FontNames[i].window ) ) {
-      dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
-      return FontNames[i].x11;
-    }
-  return FontNames[0].x11;
-}
-
-
-/***********************************************************************
- *           FONT_MatchFont
- *
- * Find a X font matching the logical font.
- */
-static XFontStruct * FONT_MatchFont( LOGFONT16 * font, DC * dc )
-{
-    char pattern[100];
-    const char *family, *weight, *charset;
-    char **names;
-    char slant, oldspacing, spacing;
-    int width, height, oldheight, count;
-    XFontStruct * fontStruct;
-    
-    dprintf_font(stddeb,
-	"FONT_MatchFont(H,W = %d,%d; Weight = %d; Italic = %d; FaceName = '%s'\n",
-	font->lfHeight, font->lfWidth, font->lfWeight, font->lfItalic, font->lfFaceName);
-    weight = (font->lfWeight > 550) ? "bold" : "medium";
-    slant = font->lfItalic ? 'i' : 'r';
-    if (font->lfHeight == -1)
-	height = 0;
-    else
-	height = font->lfHeight * dc->vportExtX / dc->wndExtX;
-    if (height == 0) height = 120;  /* Default height = 12 */
-    else if (height < 0)
-    {
-        /* If height is negative, it means the height of the characters */
-        /* *without* the internal leading. So we adjust it a bit to     */
-        /* compensate. 5/4 seems to give good results for small fonts.  */
-	/* 
-         * J.M.: This causes wrong font size for bigger fonts e.g. in Winword & Write 
-        height = 10 * (-height * 9 / 8);
-	 * may be we have to use an non linear function
-	*/
-	/* assume internal leading is 2 pixels. Else small fonts will become
-         * very small. */
-        height = (height-2) * -10; 
-    }
-    else height *= 10;
-    width  = 10 * (font->lfWidth * dc->vportExtY / dc->wndExtY);
-    if (width < 0) {
-	dprintf_font( stddeb, "FONT_MatchFont: negative width %d(%d)\n",
-		      width, font->lfWidth );
-	width = -width;
-    }
-
-    spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
-	      (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
-    
-  
-    charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
-    if (*font->lfFaceName) {
-	family = FONT_ChkX11Family(font->lfFaceName);
-	/*--do _not_ translate if lfFaceName is family from X11  A.K.*/
-	if (!family) 
-	  family = FONT_TranslateName( font->lfFaceName );
-	/* FIX ME: I don't if that's correct but it works J.M. */
-	spacing = '*';
-	}
-    else switch(font->lfPitchAndFamily & 0xf0)
-    {
-    case FF_ROMAN:
-      family = FONT_TranslateName( "roman" );
-      break;
-    case FF_SWISS:
-      family = FONT_TranslateName( "swiss" );
-      break;
-    case FF_MODERN:
-      family = FONT_TranslateName( "modern" );
-      break;
-    case FF_SCRIPT:
-      family = FONT_TranslateName( "script" );
-      break;
-    case FF_DECORATIVE:
-      family = FONT_TranslateName( "decorative" );
-      break;
-    default:
-      family = "*-*";
-      break;
-    }
-    sprintf( pattern, "-%s-%s-*-normal-*-*-*-*-*-*-*-%s",
-	    family, weight, charset);
-    dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
-    names = XListFonts( display, pattern, 1, &count );
-    if (names) XFreeFontNames( names );
-    else
-    {
-        if (strcmp(family, "*-*") == 0)
-        {
-            fprintf(stderr, "FONT_MatchFont(%s) : returning NULL\n", pattern);
-            return NULL;
-        }
-        else family = "*-*";
-    }
-    oldheight = height;
-    oldspacing = spacing;
-    while (TRUE) {
-	    /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
-	    if ( width == 0 )
-	      sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
-		      family, weight, slant, height, spacing, charset);
-	    else
-	      sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
-		      family, weight, slant, height, spacing, width, charset);
-	    dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
-	    names = XListFonts( display, pattern, 1, &count );
-	    if (count > 0) break;
-            if (spacing == 'm') /* try 'c' if no 'm' found */ {
-
-                spacing = 'c';
-                continue;
-            } else if (spacing == 'p') /* try '*' if no 'p' found */ {
-                spacing = '*';
-                continue;
-            }
-            spacing = oldspacing;
-            height -= 10;		
-            if (height < 10) {
-                if (slant == 'i') {
-		    /* try oblique if no italic font */
-		    slant = 'o';
-		    height = oldheight;
-		    continue;
-		}
-		if (spacing == 'm' && strcmp(family, "*-*") != 0) {
-		    /* If a fixed spacing font could not be found, ignore
-		     * the family */
-		    family = "*-*";
-		    height = oldheight;
-		    continue;
-		}
-                fprintf(stderr, "FONT_MatchFont(%s) : returning NULL\n", pattern);
-		return NULL;
-            }
-    }
-    dprintf_font(stddeb,"        Found '%s'\n", *names );
-    if (!*font->lfFaceName)
-        FONT_ParseFontParms(*names, 2, font->lfFaceName , LF_FACESIZE-1);
-    /* we need a font name for function GetTextFace() even if there isn't one ;-) */  
-
-    fontStruct = XLoadQueryFont( display, *names );
-    XFreeFontNames( names );
-    return fontStruct;
-}
-
-
-/***********************************************************************
- *           X11DRV_GetTextExtentPoint
- */
-BOOL32 X11DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
-                                  LPSIZE32 size )
-{
-    int dir, ascent, descent;
-    XCharStruct info;
-
-    XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
-		  &ascent, &descent, &info );
-    size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
-		    * dc->wndExtX / dc->vportExtX);
-    size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
-		    * dc->wndExtY / dc->vportExtY);
-    return TRUE;
-}
-
-BOOL32 X11DRV_GetTextMetrics(DC *dc, TEXTMETRIC32A *metrics)
-{
-    
-    metrics->tmWeight           = dc->u.x.font.metrics.tmWeight;
-    metrics->tmOverhang         = dc->u.x.font.metrics.tmOverhang;
-    metrics->tmDigitizedAspectX = dc->u.x.font.metrics.tmDigitizedAspectX;
-    metrics->tmDigitizedAspectY = dc->u.x.font.metrics.tmDigitizedAspectY;
-    metrics->tmFirstChar        = dc->u.x.font.metrics.tmFirstChar;
-    metrics->tmLastChar         = dc->u.x.font.metrics.tmLastChar;
-    metrics->tmDefaultChar      = dc->u.x.font.metrics.tmDefaultChar;
-    metrics->tmBreakChar        = dc->u.x.font.metrics.tmBreakChar;
-    metrics->tmItalic           = dc->u.x.font.metrics.tmItalic;
-    metrics->tmUnderlined       = dc->u.x.font.metrics.tmUnderlined;
-    metrics->tmStruckOut        = dc->u.x.font.metrics.tmStruckOut;
-    metrics->tmPitchAndFamily   = dc->u.x.font.metrics.tmPitchAndFamily;
-    metrics->tmCharSet          = dc->u.x.font.metrics.tmCharSet;
-
-    metrics->tmAscent  = abs( dc->u.x.font.metrics.tmAscent
-			      * dc->wndExtY / dc->vportExtY );
-    metrics->tmDescent = abs( dc->u.x.font.metrics.tmDescent
-			      * dc->wndExtY / dc->vportExtY );
-    metrics->tmHeight  = dc->u.x.font.metrics.tmAscent + dc->u.x.font.metrics.tmDescent;
-    metrics->tmInternalLeading = abs( dc->u.x.font.metrics.tmInternalLeading
-				      * dc->wndExtY / dc->vportExtY );
-    metrics->tmExternalLeading = abs( dc->u.x.font.metrics.tmExternalLeading
-				      * dc->wndExtY / dc->vportExtY );
-    metrics->tmMaxCharWidth    = abs( dc->u.x.font.metrics.tmMaxCharWidth 
-				      * dc->wndExtX / dc->vportExtX );
-    metrics->tmAveCharWidth    = abs( dc->u.x.font.metrics.tmAveCharWidth
-				      * dc->wndExtX / dc->vportExtX );
-
-    return TRUE;
-    
-}
-
-
-/***********************************************************************
- *           X11DRV_FONT_SelectObject
- *
- * FIXME: the fonts should not be cached by hfont only, because
- * metrics may be different in an other DC.
- */
-HFONT32 X11DRV_FONT_SelectObject( DC * dc, HFONT32 hfont, FONTOBJ * font )
-{
-    static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
-
-    static struct {
-		HFONT32		id;
-		LOGFONT16	logfont;
-		int		access;
-		int		used;
-		X_PHYSFONT	cacheFont; } cacheFonts[FONTCACHE], *cacheFontsMin;
-    int 	i;
-
-    X_PHYSFONT * stockPtr;
-    HFONT32 prevHandle = dc->w.hFont;
-    XFontStruct * fontStruct;
-    dprintf_font(stddeb,"FONT_SelectObject(%p, %04x, %p)\n", dc, hfont, font);
-
-#if 0 /* From the code in SelectObject, this can not happen */
-      /* Load font if necessary */
-    if (!font)
-    {
-	HFONT16 hnewfont;
-
-	hnewfont = CreateFont16(10, 7, 0, 0, FW_DONTCARE,
-			      FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
-			      DEFAULT_QUALITY, FF_DONTCARE, "*" );
-	font = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hnewfont );
-    }
-#endif
-
-    if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
-	stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
-    else {
-	stockPtr = NULL;
-	/*
-	 * Ok, It's not a stock font but 
-	 * may be it's cached in dynamic cache
-	 */
-	for(i=0; i<FONTCACHE; i++) /* search for same handle */
-	     if (cacheFonts[i].id==hfont) { /* Got the handle */
-		/*
-		 * Check if Handle matches the font 
-		 */
-		if(memcmp(&cacheFonts[i].logfont,&(font->logfont), sizeof(LOGFONT16))) {
-			/* No: remove handle id from dynamic font cache */
-			cacheFonts[i].access=0;
-			cacheFonts[i].used=0;
-			cacheFonts[i].id=0;
-			/* may be there is an unused handle which contains the font */
-			for(i=0; i<FONTCACHE; i++) {
-				if((cacheFonts[i].used == 0) &&
-				  (memcmp(&cacheFonts[i].logfont,&(font->logfont), sizeof(LOGFONT16)))== 0) {
-					/* got it load from cache and set new handle id */
-					stockPtr = &cacheFonts[i].cacheFont;
-					cacheFonts[i].access=1;
-					cacheFonts[i].used=1;
-					cacheFonts[i].id=hfont;
-					dprintf_font(stddeb,"FONT_SelectObject: got font from unused handle\n");
-					break;
-					}
-				}
-	
-			}
-		else {
-			/* Yes: load from dynamic font cache */
-			stockPtr = &cacheFonts[i].cacheFont;
-			cacheFonts[i].access++;
-			cacheFonts[i].used++;
-			}
-		break;
-		}
-	}
-    if (!stockPtr || !stockPtr->fstruct)
-    {
-	if (!(fontStruct = FONT_MatchFont( &font->logfont, dc )))
-        {
-              /* If it is not a stock font, we can simply return 0 */
-            if (!stockPtr) return 0;
-              /* Otherwise we must try to find a substitute */
-            dprintf_font(stddeb,"Loading font 'fixed' for %04x\n", hfont );
-            font->logfont.lfPitchAndFamily &= ~VARIABLE_PITCH;
-            font->logfont.lfPitchAndFamily |= FIXED_PITCH;
-            fontStruct = XLoadQueryFont( display, "fixed" );
-            if (!fontStruct)
-            {
-                fprintf( stderr, "No system font could be found. Please check your font path.\n" );
-                exit( 1 );
-            }
-        }
-    }
-    else
-    {
-	fontStruct = stockPtr->fstruct;
-	dprintf_font(stddeb,
-                     "FONT_SelectObject: Loaded font from cache %04x %p\n",
-		     hfont, fontStruct );
-    }	
-
-      /* Unuse previous font */
-	for (i=0; i < FONTCACHE; i++) {
-		if (cacheFonts[i].id == prevHandle) {
-			if(cacheFonts[i].used == 0)
-				fprintf(stderr, "Trying to decrement a use count of 0.\n");
-			else 
-				cacheFonts[i].used--;
-		}
-	}
-
-      /* Store font */
-    dc->w.hFont = hfont;
-    if (stockPtr)
-    {
-	if (!stockPtr->fstruct)
-	{
-	    stockPtr->fstruct = fontStruct;
-	    FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
-	}
-	memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
-    }
-    else
-    {
-	/* 
-	 * Check in cacheFont
-	 */
-	cacheFontsMin=NULL;
-	for (i=0; i < FONTCACHE; i++) {
-		if (cacheFonts[i].used==0) 
-			if ((!cacheFontsMin) || ((cacheFontsMin) && (cacheFontsMin->access > cacheFonts[i].access)))
-				cacheFontsMin=&cacheFonts[i];
-		}
-	if (!cacheFontsMin) {
-		fprintf(stderr,"No unused font cache entry !!!!\n" );
-		return prevHandle;
-	}
-	if (cacheFontsMin->id!=0) {
-		dprintf_font(stddeb,
-			"FONT_SelectObject: Freeing %04x \n",cacheFontsMin->id );
-		XFreeFont( display, cacheFontsMin->cacheFont.fstruct );
-		}
-	cacheFontsMin->cacheFont.fstruct = fontStruct;
-	FONT_GetMetrics( &font->logfont, fontStruct, &cacheFontsMin->cacheFont.metrics );
-	cacheFontsMin->access=1;
-	cacheFontsMin->used=1;
-	cacheFontsMin->id=hfont;
-	memcpy( &dc->u.x.font, &(cacheFontsMin->cacheFont), sizeof(cacheFontsMin->cacheFont) );
-	memcpy(&cacheFontsMin->logfont,&(font->logfont), sizeof(LOGFONT16));
-
-    }
-    return prevHandle;
-}
-
-/***********************************************************************
- *           GetCharWidth32A    (GDI32.155)
- */
-BOOL32 X11DRV_GetCharWidth( DC *dc, UINT32 firstChar, UINT32 lastChar,
-			    LPINT32 buffer )
-{
-    int i, width;
-    XFontStruct *xfont;
-    XCharStruct *cs, *def;
-
-    xfont = dc->u.x.font.fstruct;
-    
-    /* fixed font? */
-    if (xfont->per_char == NULL)
-    {
-	for (i = firstChar; i <= lastChar; i++)
-	    *buffer++ = xfont->max_bounds.width;
-	return TRUE;
-    }
-
-    CI_GET_DEFAULT_INFO(xfont, def);
-	
-    for (i = firstChar; i <= lastChar; i++)
-    {
-	CI_GET_CHAR_INFO( xfont, i, def, cs );
-        width = cs ? cs->width : xfont->max_bounds.width;
-        *buffer++ = MAX( width, 0 );
-    }
-    return TRUE;
-}
-
-
-
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index bceeb10..0d7496f 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -6,14 +6,16 @@
 
 #include <string.h>
 #include "x11drv.h"
+#include "color.h"
 #include "bitmap.h"
-#include "gdi.h"
-
 
 static BOOL32 X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
                                LPCSTR output, const DEVMODE16* initData );
 static BOOL32 X11DRV_DeleteDC( DC *dc );
 
+static INT32 X11DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput,
+                            SEGPTR lpInData, SEGPTR lpOutData );
+
 static const DC_FUNCTIONS X11DRV_Funcs =
 {
     X11DRV_Arc,                      /* pArc */
@@ -23,13 +25,13 @@
     X11DRV_DeleteDC,                 /* pDeleteDC */
     NULL,                            /* pDeleteObject */
     X11DRV_Ellipse,                  /* pEllipse */
-    NULL,                            /* pEnumDeviceFonts */
-    NULL,                            /* pEscape */
+    X11DRV_EnumDeviceFonts,          /* pEnumDeviceFonts */
+    X11DRV_Escape,                   /* pEscape */
     NULL,                            /* pExcludeClipRect */
     NULL,                            /* pExcludeVisRect */
     X11DRV_ExtFloodFill,             /* pExtFloodFill */
     X11DRV_ExtTextOut,               /* pExtTextOut */
-    NULL,                            /* pGetCharWidth */
+    X11DRV_GetCharWidth,             /* pGetCharWidth */
     X11DRV_GetPixel,                 /* pGetPixel */
     X11DRV_GetTextExtentPoint,       /* pGetTextExtentPoint */
     X11DRV_GetTextMetrics,           /* pGetTextMetrics */
@@ -79,13 +81,65 @@
     NULL                             /* pStretchDIBits */
 };
 
-static DeviceCaps X11DRV_DevCaps;
+static DeviceCaps X11DRV_DevCaps = {
+/* version */		0, 
+/* technology */	DT_RASDISPLAY,
+/* size, resolution */	0, 0, 0, 0, 0, 
+/* device objects */	1, 16 + 6, 16, 0, 0, 100, 0,	
+/* curve caps */	CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
+			CC_WIDE | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT,
+/* line caps */		LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+			LC_STYLED | LC_WIDESTYLED | LC_INTERIORS,
+/* polygon caps */	PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
+			PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS,
+/* text caps */		0,
+/* regions */		CP_REGION,
+/* raster caps */	RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
+			RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS,
+/* aspects */		36, 36, 51,
+/* pad1 */		{ 0 },
+/* log pixels */	0, 0, 
+/* pad2 */		{ 0 },
+/* palette size */	0,
+/* ..etc */		0, 0 };
 
 /**********************************************************************
  *	     X11DRV_Init
  */
 BOOL32 X11DRV_Init(void)
 {
+    extern BOOL32 COLOR_Init();
+
+    /* FIXME: colormap management should be merged with the X11DRV */
+
+    if( !COLOR_Init() ) return FALSE;
+
+    /* Finish up device caps */
+
+#if 0
+    printf("Display:\nHeight = %-4i pxl, %-4i mm\nWidth  = %-4i pxl, %-4i mm\n",
+	    HeightOfScreen(screen), HeightMMOfScreen(screen),
+	    WidthOfScreen(screen), WidthMMOfScreen(screen) );
+#endif
+
+    X11DRV_DevCaps.version = 0x300;
+    X11DRV_DevCaps.horzSize = WidthMMOfScreen(screen) * screenWidth / WidthOfScreen(screen);
+    X11DRV_DevCaps.vertSize = HeightMMOfScreen(screen) * screenHeight / HeightOfScreen(screen);
+    X11DRV_DevCaps.horzRes = screenWidth;
+    X11DRV_DevCaps.vertRes = screenHeight;
+    X11DRV_DevCaps.bitsPixel = screenDepth;
+
+    if( COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL ) 
+	X11DRV_DevCaps.sizePalette = 0;
+    else
+    {
+	X11DRV_DevCaps.rasterCaps |= RC_PALETTE;
+	X11DRV_DevCaps.sizePalette = DefaultVisual(display,DefaultScreen(display))->map_entries;
+    }
+
+    X11DRV_DevCaps.logPixelsX = (int)(X11DRV_DevCaps.horzRes * 25.4 / X11DRV_DevCaps.horzSize);
+    X11DRV_DevCaps.logPixelsY = (int)(X11DRV_DevCaps.vertRes * 25.4 / X11DRV_DevCaps.vertSize);
+
     /* Create default bitmap */
 
     if (!X11DRV_BITMAP_Init()) return FALSE;
@@ -94,14 +148,13 @@
 
     if (!X11DRV_BRUSH_Init()) return FALSE;
 
-    /* Initialize fonts */
+    /* Initialize fonts and text caps */
 
-    if (!X11DRV_FONT_Init()) return FALSE;
+    if (!X11DRV_FONT_Init( &X11DRV_DevCaps )) return FALSE;
 
     return DRIVER_RegisterDriver( "DISPLAY", &X11DRV_Funcs );
 }
 
-
 /**********************************************************************
  *	     X11DRV_CreateDC
  */
@@ -110,8 +163,6 @@
 {
     X11DRV_PDEVICE *physDev;
 
-    if (!X11DRV_DevCaps.version) DC_FillDevCaps( &X11DRV_DevCaps );
-
     physDev = &dc->u.x;  /* for now */
 
     memset( physDev, 0, sizeof(*physDev) );
@@ -157,3 +208,24 @@
     XFreeGC( display, physDev->gc );
     return TRUE;
 }
+
+/**********************************************************************
+ *           X11DRV_Escape
+ */
+static INT32 X11DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput,
+                            SEGPTR lpInData, SEGPTR lpOutData )
+{
+    switch( nEscape )
+    {
+	case GETSCALINGFACTOR:
+	     if( lpOutData )
+	     {
+		 LPPOINT16 lppt = (LPPOINT16)PTR_SEG_TO_LIN(lpOutData);
+		 lppt->x = lppt->y = 0;	/* no device scaling */
+		 return 1;
+	     }
+	     break;
+    }
+    return 0;
+}
+
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index 561cb5e..cc7249d 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -12,7 +12,7 @@
 #include "gdi.h"
 /*#include "callback.h"*/
 #include "heap.h"
-#include "x11drv.h"
+#include "x11font.h"
 #include "stddebug.h"
 /* #define DEBUG_TEXT */
 #include "debug.h"
@@ -32,21 +32,29 @@
                    const RECT32 *lprect, LPCSTR str, UINT32 count,
                    const INT32 *lpDx )
 {
-    HRGN32	hRgnClip = 0;
-    int 	dir, ascent, descent, i;
-    XCharStruct info;
-    XFontStruct *font;
-    RECT32 	rect;
+    HRGN32		hRgnClip = 0;
+    int 		dir, ascent, descent, i;
+    fontObject*		pfo;
+    XCharStruct 	info;
+    XFontStruct*	font;
+    RECT32 		rect;
+    char		dfBreakChar, lfUnderline, lfStrikeOut;
 
     if (!DC_SetupGCForText( dc )) return TRUE;
-    font = dc->u.x.font.fstruct;
 
-    dprintf_text(stddeb,"ExtTextOut: hdc=%04x %d,%d '%.*s', %d  flags=%d\n",
-                 dc->hSelf, x, y, (int)count, str, count, flags);
+    pfo = XFONT_GetFontObject( dc->u.x.font );
+    font = pfo->fs;
+
+    dfBreakChar = (char)pfo->fi->df.dfBreakChar;
+    lfUnderline = (pfo->fo_flags & FO_SYNTH_UNDERLINE) ? 1 : 0;
+    lfStrikeOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT) ? 1 : 0;
+
+    dprintf_text(stddeb,"ExtTextOut: hdc=%04x df=%04x %d,%d '%.*s', %d  flags=%d\n",
+                 dc->hSelf, (UINT16)(dc->u.x.font), x, y, (int)count, str, count, flags);
+
     if (lprect != NULL) dprintf_text(stddeb, "\trect=(%d,%d- %d,%d)\n",
                                      lprect->left, lprect->top,
                                      lprect->right, lprect->bottom );
-
       /* Setup coordinates */
 
     if (dc->w.textAlign & TA_UPDATECP)
@@ -106,7 +114,7 @@
 	/* sum lpDx array and add the width of last character */
 
         info.width = XTextWidth( font, str + count - 1, 1) + dc->w.charExtra;
-        if (str[count-1] == (char)dc->u.x.font.metrics.tmBreakChar)
+        if (str[count-1] == dfBreakChar)
             info.width += dc->w.breakExtra;
 
         for (i = 0; i < count; i++) info.width += lpDx[i];
@@ -211,7 +219,7 @@
                 else
                 {
                     delta += dc->w.charExtra;
-                    if (str[i] == (char)dc->u.x.font.metrics.tmBreakChar)
+                    if (str[i] == (char)dfBreakChar)
                         delta += dc->w.breakExtra;
                 }
                 pitem->nchars++;
@@ -227,9 +235,10 @@
 
       /* Draw underline and strike-out if needed */
 
-    if (dc->u.x.font.metrics.tmUnderlined)
+    if (lfUnderline)
     {
 	long linePos, lineWidth;       
+
 	if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
 	    linePos = font->descent-1;
 	if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
@@ -241,7 +250,7 @@
 		   dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
 		   dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos );
     }
-    if (dc->u.x.font.metrics.tmStruckOut)
+    if (lfStrikeOut)
     {
 	long lineAscent, lineDescent;
 	if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
new file mode 100644
index 0000000..60aa82f
--- /dev/null
+++ b/graphics/x11drv/xfont.c
@@ -0,0 +1,2024 @@
+/*
+ * X11 physical font objects
+ *
+ * Copyright 1997 Alex Korobka
+ *
+ * TODO: Mapping algorithm tweaks, FO_SYNTH_... flags (ExtTextOut() will
+ *	 have to be changed for that), dynamic font loading (FreeType).
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include "heap.h"
+#include "options.h"
+#include "x11font.h"
+#include "font.h"
+#include "stddebug.h"
+#include "debug.h"
+
+#define DEBUG_FONT_INIT		1
+
+#define X_PFONT_MAGIC		(0xFADE0000)
+#define X_FMC_MAGIC		(0x0000CAFE)
+
+#define MAX_FONT_FAMILIES	64
+#define MAX_LFD_LENGTH		128
+
+#define REMOVE_SUBSETS		1
+#define UNMARK_SUBSETS		0
+
+#define DEF_SCALABLE_HEIGHT	24
+#define DEF_SCALABLE_DP		240
+
+#define FF_FAMILY       (FF_MODERN | FF_SWISS | FF_ROMAN | FF_DECORATIVE | FF_SCRIPT)
+
+typedef struct __fontAlias
+{
+  LPSTR			faTypeFace;
+  LPSTR			faAlias;
+  struct __fontAlias*	next;
+} fontAlias;
+
+static fontAlias aliasTable[2] = { 
+			{ "Helvetica", "Helv", &aliasTable[1] },
+			{ "Times", "Tms Rmn", NULL } 
+			};
+
+UINT16			XTextCaps = TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
+				    TC_SA_DOUBLE | TC_SA_INTEGER | TC_SA_CONTIN |
+			 	    TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
+
+			/* X11R6 adds TC_SF_X_YINDEP, maybe more... */
+
+static const char*	INIWinePrefix = "/.wine";
+static const char*	INIFontMetrics = "/.cachedmetrics";
+static const char*	INIFontSection = "fonts";
+static const char*	INISubSection = "Alias";
+static const char*	INIDefault = "Default";
+
+static const char*	LFDSeparator = "*-";
+static const char*	iso8859Encoding = "iso8859-";
+static const char*	iso646Encoding = "iso646.1991-";
+static const char*	ansiEncoding = "ansi-";
+static fontResource*	fontList = NULL; 	
+static unsigned		DefResolution = 0;
+
+static fontObject*      fontCache = NULL;		/* array */
+static int		fontCacheSize = FONTCACHE;
+static int		fontLF = -1, fontMRU = -1;	/* last free, most recently used */
+
+#define __PFONT(pFont)     ( fontCache + ((UINT32)(pFont) & 0x0000FFFF) )
+#define CHECK_PFONT(pFont) ( (((UINT32)(pFont) & 0xFFFF0000) == X_PFONT_MAGIC) &&\
+			     (((UINT32)(pFont) & 0x0000FFFF) < fontCacheSize) )
+
+static INT32 XFONT_IsSubset(fontInfo*, fontInfo*);
+static void  XFONT_CheckFIList(fontResource*, fontInfo*, int subset_action);
+static void  XFONT_GrowFreeList(int start, int end);
+
+/***********************************************************************
+ *           Helper macros from X distribution
+ */
+
+#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
+			     (((cs)->rbearing|(cs)->lbearing| \
+			       (cs)->ascent|(cs)->descent) == 0))
+
+#define CI_GET_CHAR_INFO(fs,col,def,cs) \
+{ \
+    cs = def; \
+    if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
+	if (fs->per_char == NULL) { \
+	    cs = &fs->min_bounds; \
+	} else { \
+	    cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
+	    if (CI_NONEXISTCHAR(cs)) cs = def; \
+	} \
+    } \
+}
+
+#define CI_GET_DEFAULT_INFO(fs,cs) \
+  CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
+
+/***********************************************************************
+ *           Checksums
+ */
+static UINT16   __lfCheckSum( LPLOGFONT16 plf )
+{
+    CHAR        font[LF_FACESIZE];
+    UINT16      checksum = 0;
+    UINT16      i;
+
+#define ptr ((UINT16*)plf)
+   for( i = 0; i < 9; i++ ) checksum ^= *ptr++;
+#undef ptr
+   i = 0;
+#define ptr ((CHAR*)plf)
+   do { font[i++] = tolower(*ptr); } while (*ptr++);
+   for( ptr = font, i >>= 1; i > 0; i-- ) 
+#undef ptr
+#define ptr ((UINT16*)plf)
+        checksum ^= *ptr++;
+#undef ptr
+   return checksum;
+}
+
+static UINT16   __genericCheckSum( UINT16* ptr, int size )
+{
+   UINT16	checksum = 0;
+   unsigned	i;
+
+   for( i = 0, size >>= 1; i < size; i++ ) checksum ^= *ptr++;
+   return checksum;
+}
+
+/*************************************************************************
+ *           LFD parse/compose routines
+ */
+static char* LFD_Advance(LPSTR lpFont, UINT16 uParmsNo)
+{
+  int 	j = 0;
+  char*	lpch = lpFont;
+
+  for( ; j < uParmsNo && *lpch; lpch++ ) if( *lpch == LFDSeparator[1] ) j++;
+  return lpch;
+}
+
+static void LFD_GetWeight( fontInfo* fi, LPSTR lpStr, int j)
+{
+  if( j == 1 && *lpStr == '0' )
+      fi->fi_flags |= FI_POLYWEIGHT;
+  else if( j == 4 )
+       {
+         if( !lstrncmpi32A( "bold", lpStr, 4) )
+           fi->df.dfWeight = FW_BOLD; 
+	 else if( !lstrncmpi32A( "demi", lpStr, 4) )
+	 {
+	   fi->fi_flags |= FI_FW_DEMI;
+	   fi->df.dfWeight = FW_DEMIBOLD;
+	 }
+	 else if( !lstrncmpi32A( "book", lpStr, 4) )
+	 {
+	   fi->fi_flags |= FI_FW_BOOK;
+	   fi->df.dfWeight = FW_REGULAR;
+	 }
+       }
+  else if( j == 5 )
+       {
+         if( !lstrncmpi32A( "light", lpStr, 5) )
+	   fi->df.dfWeight = FW_LIGHT;
+         else if( !lstrncmpi32A( "black", lpStr, 5) )
+	   fi->df.dfWeight = FW_BLACK;
+       }
+  else if( j == 6 && !lstrncmpi32A( "medium", lpStr, 6) )
+      fi->df.dfWeight = FW_REGULAR; 
+  else if( j == 8 && !lstrncmpi32A( "demibold", lpStr, 8) )
+      fi->df.dfWeight = FW_DEMIBOLD; 
+  else
+      fi->df.dfWeight = FW_DONTCARE; /* FIXME: try to get something
+				      * from the weight property */
+}
+
+static int LFD_GetSlant( fontInfo* fi, LPSTR lpStr, int l)
+{
+    if( l == 1 )
+    {
+	switch( tolower( *lpStr ) )
+	{
+	    case '0':  fi->fi_flags |= FI_POLYSLANT;	/* haven't seen this one yet */
+	    default:
+	    case 'r':  fi->df.dfItalic = 0;
+		       break;
+	    case 'o':
+		       fi->fi_flags |= FI_OBLIQUE;
+	    case 'i':  fi->df.dfItalic = 1;
+		       break;
+	}
+	return 0;
+    }
+    return 1;
+}
+
+/*************************************************************************
+ *           LFD_InitFontInfo
+ *
+ * Fill in some fields in the fontInfo struct.
+ */
+static int LFD_InitFontInfo( fontInfo* fi, LPSTR lpstr )
+{
+   LPSTR	lpch;
+   int    	i, j, dec_style_check, scalability;
+   UINT16 	tmp[3];
+
+   memset(fi, 0, sizeof(fontInfo) );
+
+/* weight name - */
+   lpch = LFD_Advance( lpstr, 1);
+   if( !*lpch ) return FALSE;
+   j = lpch - lpstr - 1;
+   LFD_GetWeight( fi, lpstr, j );
+
+/* slant - */
+   lpch = LFD_Advance( lpstr = lpch, 1);
+   if( !*lpch ) return FALSE;
+   j = lpch - lpstr - 1;
+   dec_style_check = LFD_GetSlant( fi, lpstr, j );
+
+/* width name - */
+   lpch = LFD_Advance( lpstr = lpch, 1);
+   if( !*lpch ) return FALSE;
+   if( lstrncmpi32A( "normal", lpstr, 6) )	/* XXX 'narrow', 'condensed', etc... */
+       dec_style_check = TRUE;
+   else
+       fi->fi_flags |= FI_NORMAL;
+
+/* style - */
+   lpch = LFD_Advance( lpstr = lpch, 1);
+   if( !*lpch ) return FALSE;
+   j = lpch - lpstr - 1;
+   if( j > 3 )	/* find out is there "sans" or "script" */
+   {
+	j = 0;
+	*(lpch - 1) = '\0';
+
+	if( strstr(lpstr, "sans") ) 
+	{ 
+	    fi->df.dfPitchAndFamily |= FF_SWISS; 
+	    j = 1; 
+	}
+	if( strstr(lpstr, "script") ) 
+	{ 
+	    fi->df.dfPitchAndFamily |= FF_SCRIPT; 
+	    j = 1; 
+	}
+	if( !j && dec_style_check ) 
+	    fi->df.dfPitchAndFamily |= FF_DECORATIVE;
+	*(lpch - 1) = LFDSeparator[1];
+   }
+
+/* pixel height, decipoint height, and res_x */
+
+   for( i = scalability = 0; i < 3; i++ )
+   {
+     lpch = LFD_Advance( lpstr = lpch, 1);
+     if( !*lpch ) return FALSE;
+     if( lpch - lpstr == 1 || lpch - lpstr > 4 ) return FALSE; /* ridiculous */
+
+    *(lpch - 1) = '\0';
+     if( !(tmp[i] = atoi(lpstr)) ) scalability++;
+    *(lpch - 1) = LFDSeparator[1];
+   }
+   if( scalability == 3 ) 	/* Type1 */
+   {
+     fi->fi_flags |= FI_SCALABLE;
+     fi->lfd_height = DEF_SCALABLE_HEIGHT; fi->lfd_decipoints = DEF_SCALABLE_DP;
+     fi->lfd_resolution = DefResolution;
+   }
+   else if( scalability == 0 )	/* Bitmap */
+   {
+     fi->lfd_height = tmp[0]; fi->lfd_decipoints = tmp[1]; 
+     fi->lfd_resolution = tmp[2];
+   }
+   else return FALSE; /* #$%^!!! X11R6 mutant garbage */
+
+/* res_y - skip, spacing - */
+   lpstr = LFD_Advance( lpch, 1);
+   switch( *lpstr )
+   {
+     case '\0': return FALSE;
+
+     case 'p': fi->fi_flags |= FI_VARIABLEPITCH;
+	       break;
+     case 'c': fi->df.dfPitchAndFamily |= FF_MODERN;
+	       fi->fi_flags |= FI_FIXEDEX;
+	       /* fall through */
+     case 'm': fi->fi_flags |= FI_FIXEDPITCH;
+	       break;
+     default:
+	       fi->df.dfPitchAndFamily |= DEFAULT_PITCH | FF_DONTCARE;
+   }
+   lpstr = LFD_Advance(lpstr, 1);
+   if( !*lpstr ) return FALSE;
+
+/* average width - */
+   lpch = LFD_Advance( lpstr, 1);
+   if( !*lpch ) return FALSE;
+   if( lpch - lpstr == 1 || lpch - lpstr > 4 ) return FALSE; /* ridiculous */
+  *(lpch - 1) = '\0'; 
+   if( !(fi->lfd_width = atoi(lpstr)) && !scalability ) return FALSE;
+  *(lpch - 1) = LFDSeparator[1];
+
+/* charset registry, charset encoding - */
+   if( strstr(lpch, "jisx") || strstr(lpch, "ksc") ) return FALSE;	/* 2-byte stuff */
+
+   if( strstr(lpch, iso8859Encoding) )
+   {
+     fi->fi_flags |= FI_ENC_ISO8859;
+     fi->df.dfCharSet = ANSI_CHARSET;
+   }
+   else if( strstr(lpch, iso646Encoding) )
+   {
+     fi->fi_flags |= FI_ENC_ISO646;
+     fi->df.dfCharSet = ANSI_CHARSET;
+   }
+   else if( strstr(lpch, ansiEncoding) )	/* font2bdf produces -ansi-0 LFD */
+   {
+     fi->fi_flags |= FI_ENC_ANSI;
+     fi->df.dfCharSet = ANSI_CHARSET;
+   }
+   else if( strstr(lpch, "fontspecific") )
+     fi->df.dfCharSet = SYMBOL_CHARSET;
+   else
+     fi->df.dfCharSet = OEM_CHARSET;		/* FIXME: -cp126-.. from fnt2bdf */
+   
+   return TRUE;					
+}
+
+/*************************************************************************
+ *           LFD_ComposeLFD
+ */
+static BOOL32  LFD_ComposeLFD( fontObject* fo, 
+			       INT32 height, LPSTR lpLFD, UINT32 uRelax )
+{
+   int		h, w, ch, point = 0;
+   char*	lpch; 
+   const char*  lpEncoding = NULL;
+
+   lstrcpy32A( lpLFD, fo->fr->resource );
+
+/* add weight */
+   switch( fo->fi->df.dfWeight )
+   {
+	case FW_BOLD:
+		strcat( lpLFD, "bold" ); break;
+	case FW_REGULAR:
+		if( fo->fi->fi_flags & FI_FW_BOOK )
+		    strcat( lpLFD, "book" );
+		else
+		    strcat( lpLFD, "medium" );
+		break;
+	case FW_DEMIBOLD:
+		strcat( lpLFD, "demi" );
+		if( !( fo->fi->fi_flags & FI_FW_DEMI) )
+		     strcat ( lpLFD, "bold" );
+		break;
+	case FW_BLACK:
+		strcat( lpLFD, "black" ); break;
+	case FW_LIGHT:
+		strcat( lpLFD, "light" ); break;
+	default:
+		strcat( lpLFD, "*" );
+   }
+
+/* add slant */
+   if( fo->fi->df.dfItalic )
+       if( fo->fi->fi_flags & FI_OBLIQUE )
+	   strcat( lpLFD, "-o" );
+       else
+	   strcat( lpLFD, "-i" );
+   else 
+       strcat( lpLFD, (uRelax < 4) ? "-r" : "-*" );
+
+/* add width style and skip serifs */
+   if( fo->fi->fi_flags & FI_NORMAL )
+       strcat( lpLFD, "-normal-*-");
+   else
+       strcat( lpLFD, "-*-*-" );
+
+/* add pixelheight, pointheight, and resolution 
+ *
+ * FIXME: fill in lpXForm and lpPixmap for rotated fonts
+ */
+   if( fo->fo_flags & FO_SYNTH_HEIGHT ) h = fo->fi->lfd_height;
+   else h = (fo->fi->lfd_height * height) / fo->fi->df.dfPixHeight;
+
+   if( fo->lf.lfWidth && (XTextCaps & TC_SF_X_YINDEP) 
+	              && !(fo->fo_flags & FO_SYNTH_WIDTH) )
+       point = (fo->fi->lfd_decipoints * fo->lf.lfWidth) / fo->fi->df.dfAvgWidth;
+
+/* spacing and width */
+
+   if( fo->fi->fi_flags & FI_FIXEDPITCH ) 
+       w = ( fo->fi->fi_flags & FI_FIXEDEX ) ? 'c' : 'm';
+   else 
+       w = ( fo->fi->fi_flags & FI_VARIABLEPITCH ) ? 'p' : LFDSeparator[0]; 
+
+/* encoding, not quite there yet */
+
+   if( fo->fi->df.dfCharSet == ANSI_CHARSET )
+   {
+	if( fo->fi->fi_flags & FI_ENC_ISO8859 )
+	     lpEncoding = iso8859Encoding;
+	else if( fo->fi->fi_flags & FI_ENC_ISO646 )
+	     lpEncoding = iso646Encoding;
+	else lpEncoding = ansiEncoding;
+   } else    lpEncoding = LFDSeparator;
+
+   lpch = lpLFD + lstrlen32A(lpLFD);
+   ch = (fo->fi->fi_flags & FI_SCALABLE) ? '0' : LFDSeparator[0];
+
+   switch( uRelax )
+   {
+       /* RealizeFont() will call us repeatedly with increasing uRelax 
+	* until XLoadFont() succeeds. */
+
+       case 0: 
+	    if( point )
+	    {
+	        sprintf( lpch, "%i-%i-%i-%c-%c-*-%s*", h, point, 
+			 fo->fi->lfd_resolution, ch, w, lpEncoding );
+	        break;
+	    }
+	    /* fall through */
+
+       case 1: 
+	    sprintf( lpch, "%i-*-%i-%c-%c-*-%s*", h, 
+			fo->fi->lfd_resolution, ch, w, lpEncoding );
+	    break;
+
+       case 2:
+	    sprintf( lpch, "%i-*-%i-%c-*-*-%s*",
+			h, fo->fi->lfd_resolution, ch, lpEncoding );
+	    break;
+
+       case 3:
+	    sprintf( lpch, "%i-*-%i-%c-*-*-%s*", fo->fi->lfd_height,
+			fo->fi->lfd_resolution, ch, lpEncoding );
+	    break;
+
+       default:
+	    sprintf( lpch, "%i-*-*-*-*-*-%s*", fo->fi->lfd_height, lpEncoding );
+   }
+
+   dprintf_font(stddeb,"\tLFD: %s\n", lpLFD );
+   return TRUE;
+}
+
+
+/***********************************************************************
+ *		X Font Resources
+ *
+ * font info		- http://www.microsoft.com/kb/articles/q65/1/23.htm
+ * Windows font metrics	- http://www.microsoft.com/kb/articles/q32/6/67.htm
+ */
+static BOOL32 XFONT_GetLeading( LPIFONTINFO16 pFI, XFontStruct* x_fs, INT32* pIL, INT32* pEL )
+{
+    unsigned long height;
+    unsigned min = (unsigned char)pFI->dfFirstChar;
+    unsigned max = (unsigned char)pFI->dfLastChar;
+    BOOL32 bHaveCapHeight = (pFI->dfCharSet == ANSI_CHARSET && 'X' >= min && 'X' <= max );
+
+    if( pEL ) *pEL = 0;
+    if( XGetFontProperty(x_fs, XA_CAP_HEIGHT, &height) == False )
+    {
+	if( x_fs->per_char )
+	    if( bHaveCapHeight )
+		height = x_fs->per_char['X' - min].ascent;
+	    else
+		if (x_fs->ascent >= x_fs->max_bounds.ascent)
+		    height = x_fs->max_bounds.ascent;
+		else
+		{
+		    height = x_fs->ascent;
+		    if( pEL )
+			*pEL = x_fs->max_bounds.ascent - height;
+		}
+	else 
+	    height = x_fs->min_bounds.ascent;
+    }
+
+   *pIL = x_fs->ascent - height;
+    return (bHaveCapHeight && x_fs->per_char);
+}
+
+static INT32 XFONT_GetAvgCharWidth( LPIFONTINFO16 pFI, XFontStruct* x_fs)
+{
+    unsigned min = (unsigned char)pFI->dfFirstChar;
+    unsigned max = (unsigned char)pFI->dfLastChar;
+
+    if( x_fs->per_char )
+    {
+	int  width, chars, j;
+	for( j = 0, width = 0, chars = 0, max -= min; j <= max; j++ )
+            if( !CI_NONEXISTCHAR(x_fs->per_char + j) )
+            {
+                width += x_fs->per_char[j].width;
+                chars++;
+            }
+	return (width / chars);
+    }
+    /* uniform width */
+    return x_fs->min_bounds.width;
+}
+
+/***********************************************************************
+ *              XFONT_SetFontMetric
+ *
+ * Initializes IFONTINFO16. dfHorizRes and dfVertRes must be already set.
+ */
+static void XFONT_SetFontMetric(fontInfo* fi, fontResource* fr, XFontStruct* xfs)
+{
+    unsigned	 min, max;
+    INT32	 el, il;
+
+    fi->df.dfFirstChar = (BYTE)(min = xfs->min_char_or_byte2);
+    fi->df.dfLastChar = (BYTE)(max = xfs->max_char_or_byte2);
+
+    fi->df.dfDefaultChar = (BYTE)xfs->default_char;
+    fi->df.dfBreakChar = (BYTE)(( ' ' < min || ' ' > max) ? xfs->default_char: ' ');
+
+    fi->df.dfPixHeight = (INT16)((fi->df.dfAscent = (INT16)xfs->ascent) + xfs->descent);
+    fi->df.dfPixWidth = (xfs->per_char) ? 0 : xfs->min_bounds.width;
+    fi->df.dfMaxWidth = (INT16)abs(xfs->max_bounds.width);
+
+    if( XFONT_GetLeading( &fi->df, xfs, &il, &el ) )
+        fi->df.dfAvgWidth = (INT16)xfs->per_char['X' - min].width;
+    else
+        fi->df.dfAvgWidth = (INT16)XFONT_GetAvgCharWidth( &fi->df, xfs);
+
+    fi->df.dfInternalLeading = (INT16)il;
+    fi->df.dfExternalLeading = (INT16)el;
+
+    fi->df.dfPoints = (INT16)(((INT32)(fi->df.dfPixHeight - 
+				       fi->df.dfInternalLeading) * 72) / fi->df.dfVertRes);
+
+    if( xfs->min_bounds.width != xfs->max_bounds.width )
+        fi->df.dfPitchAndFamily |= TMPF_FIXED_PITCH; /* au contraire! */
+    if( fi->fi_flags & FI_SCALABLE ) 
+    {
+	fi->df.dfType = DEVICE_FONTTYPE;
+        fi->df.dfPitchAndFamily |= TMPF_DEVICE;
+    } 
+    else if( fi->fi_flags & FI_TRUETYPE )
+	fi->df.dfType = TRUETYPE_FONTTYPE;
+    else
+	fi->df.dfType = RASTER_FONTTYPE;
+
+    fi->df.dfFace = fr->lfFaceName;
+}
+
+/***********************************************************************
+ *              XFONT_GetTextMetric
+ */
+static void XFONT_GetTextMetric( fontObject* pfo, LPTEXTMETRIC32A pTM )
+{
+    LPIFONTINFO16 pdf = &pfo->fi->df;
+
+    pTM->tmAscent = pfo->fs->ascent;
+    pTM->tmDescent = pfo->fs->descent;
+    pTM->tmHeight = pTM->tmAscent + pTM->tmDescent;
+
+    pTM->tmAveCharWidth = pfo->foAvgCharWidth;
+    pTM->tmMaxCharWidth = abs(pfo->fs->max_bounds.width);
+
+    pTM->tmInternalLeading = pfo->foInternalLeading;
+    pTM->tmExternalLeading = pdf->dfExternalLeading;
+
+    pTM->tmStruckOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT )
+			? 1 : pdf->dfStrikeOut;
+    pTM->tmUnderlined = (pfo->fo_flags & FO_SYNTH_UNDERLINE )
+			? 1 : pdf->dfUnderline;
+
+    pTM->tmOverhang = 0;
+    if( pfo->fo_flags & FO_SYNTH_ITALIC ) 
+    {
+	pTM->tmOverhang += pTM->tmHeight/3;
+	pTM->tmItalic = 1;
+    } else 
+	pTM->tmItalic = pdf->dfItalic;
+
+    pTM->tmWeight = pdf->dfWeight;
+    if( pfo->fo_flags & FO_SYNTH_BOLD ) 
+    {
+	pTM->tmOverhang++; 
+	pTM->tmWeight += 100;
+    } 
+
+    *(INT32*)&pTM->tmFirstChar = *(INT32*)&pdf->dfFirstChar;
+
+    pTM->tmCharSet = pdf->dfCharSet;
+    pTM->tmPitchAndFamily = pdf->dfPitchAndFamily;
+    pTM->tmDigitizedAspectX = pdf->dfHorizRes;
+    pTM->tmDigitizedAspectY = pdf->dfVertRes;
+}
+
+/***********************************************************************
+ *              XFONT_GetFontMetric
+ *
+ * Retrieve font metric info (enumeration).
+ */
+static UINT32 XFONT_GetFontMetric( fontInfo* pfi, LPENUMLOGFONTEX16 pLF,
+                                                  LPNEWTEXTMETRIC16 pTM )
+{
+    memset( pLF, 0, sizeof(*pLF) );
+    memset( pTM, 0, sizeof(*pTM) );
+
+#define plf ((LPLOGFONT16)pLF)
+    plf->lfHeight    = pTM->tmHeight       = pfi->df.dfPixHeight;
+    plf->lfWidth     = pTM->tmAveCharWidth = pfi->df.dfAvgWidth;
+    plf->lfWeight    = pTM->tmWeight       = pfi->df.dfWeight;
+    plf->lfItalic    = pTM->tmItalic       = pfi->df.dfItalic;
+    plf->lfUnderline = pTM->tmUnderlined   = pfi->df.dfUnderline;
+    plf->lfStrikeOut = pTM->tmStruckOut    = pfi->df.dfStrikeOut;
+    plf->lfCharSet   = pTM->tmCharSet      = pfi->df.dfCharSet;
+
+    /* convert pitch values */
+
+    pTM->tmPitchAndFamily = pfi->df.dfPitchAndFamily;
+    plf->lfPitchAndFamily = (pfi->df.dfPitchAndFamily & 0xF1) + 1;
+
+    lstrcpyn32A( plf->lfFaceName, pfi->df.dfFace, LF_FACESIZE );
+#undef plf
+
+    pTM->tmAscent = pfi->df.dfAscent;
+    pTM->tmDescent = pTM->tmHeight - pTM->tmAscent;
+    pTM->tmInternalLeading = pfi->df.dfInternalLeading;
+    pTM->tmMaxCharWidth = pfi->df.dfMaxWidth;
+    pTM->tmDigitizedAspectX = pfi->df.dfHorizRes;
+    pTM->tmDigitizedAspectY = pfi->df.dfVertRes;
+
+    *(INT32*)&pTM->tmFirstChar = *(INT32*)&pfi->df.dfFirstChar;
+
+    /* return font type */
+
+    return pfi->df.dfType;
+}
+
+
+/***********************************************************************
+ *           XFONT_FixupFlags
+ * 
+ * dfPitchAndFamily flags for some common typefaces.
+ */
+static BYTE XFONT_FixupFlags( LPCSTR lfFaceName )
+{
+   switch( lfFaceName[0] )
+   {
+        case 'h':
+        case 'H': if(!lstrcmpi32A(lfFaceName, "Helvetica") )
+                    return FF_SWISS;
+                  break;
+        case 'c':
+        case 'C': if(!lstrcmpi32A(lfFaceName, "Courier") )
+                    return FF_ROMAN;
+                  break;
+        case 'p':
+        case 'P': if( !lstrcmpi32A(lfFaceName,"Palatino") )
+                    return FF_ROMAN;
+                  break;
+        case 't':
+        case 'T': if(!lstrncmpi32A(lfFaceName, "Times", 5) )
+                    return FF_ROMAN;
+                  break;
+        case 'u':
+        case 'U': if(!lstrcmpi32A(lfFaceName, "Utopia") )
+                    return FF_ROMAN;
+                  break;
+        case 'z':
+        case 'Z': if(!lstrcmpi32A(lfFaceName, "Zapf Dingbats") )
+                    return FF_DECORATIVE;
+   }
+   return 0;
+}
+
+
+/***********************************************************************
+ *           XFONT_WindowsNames
+ *
+ * Build generic Windows aliases for X font names.
+ *
+ * -misc-fixed- -> "Fixed"
+ * -sony-fixed- -> "Sony Fixed", etc...
+ */
+static void XFONT_WindowsNames( char* buffer )
+{
+    fontResource* fr, *pfr;
+    char* 	lpstr, *lpch;
+    int		i, up;
+    BYTE	bFamilyStyle;
+
+    for( fr = fontList; fr ; fr = fr->next )
+    {
+	if( fr->fr_flags & FR_NAMESET ) continue;     /* skip already assigned */
+
+	lpstr = LFD_Advance(fr->resource, 2);
+	i = lpstr - LFD_Advance( lpstr, 1 );
+
+	for( pfr = fontList; pfr != fr ; pfr = pfr->next )
+	    if( pfr->fr_flags & FR_NAMESET )
+	    {
+		lpch = LFD_Advance(pfr->resource, 2);
+
+		/* check if already have the same face name */
+
+		if( !lstrncmp32A(lpch, lpstr, i) ) break;
+	    }
+	if( pfr != fr )  /* prepend vendor name */
+	    lpstr = fr->resource + 1;
+
+	for( i = 0, up = 1, lpch = fr->lfFaceName; *lpstr && i < 32;
+					        lpch++, lpstr++, i++ )
+	{
+	    if( *lpstr == LFDSeparator[1] || *lpstr == ' ' ) 
+	    { 
+		*lpch = ' '; 
+		up = 1; continue; 
+	    }
+            else if( isalpha(*lpstr) && up )
+	    { 
+		*lpch = toupper(*lpstr); 
+		up = 0; continue; 
+	    }
+	    *lpch = *lpstr;
+	}
+	while (*(lpch - 1) == ' ') *(--lpch) = '\0';
+
+	if( (bFamilyStyle = XFONT_FixupFlags( fr->lfFaceName )) )
+	{
+	    fontInfo* fi;
+	    for( fi = fr->fi ; fi ; fi = fi->next )
+		fi->df.dfPitchAndFamily |= bFamilyStyle;
+	}
+
+#ifdef DEBUG_FONT_INIT
+	dprintf_font(stddeb,"typeface \'%s\'\n", fr->lfFaceName);
+#endif
+	fr->fr_flags |= FR_NAMESET;
+    }
+
+    if( PROFILE_GetWineIniString( INIFontSection, INIDefault, "", buffer, 128 ) )
+    {
+	while( *buffer && isspace(*buffer) ) buffer++;
+	for( fr = NULL, pfr = fontList; pfr; pfr = pfr->next )
+	{
+	     i = lstrlen32A( pfr->resource );
+	     if( !lstrncmpi32A( pfr->resource, buffer, i) )
+	     {
+		 if( fr )
+		 {
+		     fr->next = pfr->next;
+		     pfr->next = fontList;
+		     fontList = pfr;
+		 }
+		 break;
+	     }
+	     fr = pfr;
+	}
+    }
+}
+
+/***********************************************************************
+ *           XFONT_CreateAlias
+ */
+static fontAlias* XFONT_CreateAlias( LPCSTR lpTypeFace, LPCSTR lpAlias )
+{
+    fontAlias* pfa = aliasTable;
+    int j = lstrlen32A(lpTypeFace) + 1;
+
+    while( pfa->next ) pfa = pfa->next;
+    pfa->next = HeapAlloc( SystemHeap, 0, sizeof(fontAlias) +
+					  j + lstrlen32A(lpAlias) + 1 );
+    if((pfa = pfa->next))
+    {
+	pfa->next = NULL;
+	pfa->faTypeFace = (LPSTR)(pfa + 1);
+	lstrcpy32A( pfa->faTypeFace, lpTypeFace );
+        pfa->faAlias = pfa->faTypeFace + j;
+        lstrcpy32A( pfa->faAlias, lpAlias );
+
+#ifdef DEBUG_FONT_INIT
+        dprintf_font(stddeb, "\tadded alias '%s' for %s\n", lpAlias, lpTypeFace );
+#endif
+	return pfa;
+    }
+    return NULL;
+}
+
+/***********************************************************************
+ *           XFONT_LoadAliases
+ *
+ * Read user-defined aliases from wine.conf. Format is as follows
+ *
+ * Alias# = [Windows font name],[LFD font name], <substitute original name>
+ *
+ * Example:
+ *   Alias0 = Arial, -adobe-helvetica- 
+ *   Alias1 = Times New Roman, -bitstream-courier-, 1
+ *   ...
+ */
+static void XFONT_LoadAliases( char** buffer, int buf_size )
+{
+    char  subsection[32];
+    int	  i = 0;
+
+    if( buf_size < 128 )
+	*buffer = HeapReAlloc(SystemHeap, 0, *buffer, 256 );
+    do
+    {
+	wsprintf32A( subsection, "%s%i", INISubSection, i++ );
+
+	if( PROFILE_GetWineIniString( INIFontSection, subsection, "", *buffer, 128 ) )
+	{
+	    char* lpchX, *lpchW = *buffer;
+
+	    while( isspace(*lpchW) ) lpchW++;
+	    lpchX = PROFILE_GetStringItem( lpchW );
+
+	    if( lpchX )
+	    {
+		fontResource* fr;
+
+		for (fr = fontList; fr ; fr = fr->next)
+		{
+		    int j;
+
+		    j = lstrlen32A( fr->resource );
+
+		    if( !lstrncmpi32A( fr->resource, lpchX, j) )
+		    {
+			char* lpch = PROFILE_GetStringItem( lpchX );
+
+			if( lpch )
+			{
+#ifdef DEBUG_FONT_INIT
+                            dprintf_font(stddeb, "\tsubstituted '%s' with %s\n",
+							fr->lfFaceName, lpchW );
+#endif
+			    lstrcpyn32A( fr->lfFaceName, lpchW, LF_FACESIZE );
+			    fr->fr_flags |= FR_NAMESET;
+			}
+		        else
+			{
+			    /* create new entry in the alias table */
+			    XFONT_CreateAlias(fr->lfFaceName, lpchW);
+			}
+			break;
+		    }
+		}
+	    }
+	    else fprintf(stderr, "XFONT_Init: malformed font alias '%s'\n", *buffer );
+	}
+	else break;
+    } while(TRUE);
+}
+
+/***********************************************************************
+ *           XFONT_UserMetricsCache
+ * 
+ * Returns expanded name for the ~/.wine/.cachedmetrics file.
+ */
+static char* XFONT_UserMetricsCache( char* buffer, int* buf_size )
+{
+    struct passwd* pwd;
+
+    pwd = getpwuid(getuid());
+    if( pwd && pwd->pw_dir )
+    {
+	int i = lstrlen32A( pwd->pw_dir ) + lstrlen32A( INIWinePrefix ) + lstrlen32A( INIFontMetrics ) + 2;
+	if( i > *buf_size ) buffer = (char*) HeapReAlloc( SystemHeap, 0, buffer, *buf_size = i );
+	lstrcpy32A( buffer, pwd->pw_dir );
+	strcat( buffer, INIWinePrefix );
+	strcat( buffer, INIFontMetrics );
+    } else buffer[0] = '\0';
+    return buffer;
+}
+
+
+/***********************************************************************
+ *           XFONT_ReadCachedMetrics
+ */
+static BOOL32 XFONT_ReadCachedMetrics( int fd, unsigned x_checksum, int x_count )
+{
+    if( fd >= 0 )
+    {
+	unsigned u;
+	int i, j;
+
+	/* read checksums */
+	read( fd, &u, sizeof(unsigned) );
+	read( fd, &i, sizeof(int) );
+
+	if( u == x_checksum && i == x_count )
+	{
+	    off_t length, offset = 3 * sizeof(int);
+
+            /* read total size */
+	    read( fd, &i, sizeof(int) );
+	    length = lseek( fd, 0, SEEK_END );
+
+	    if( length == (i + offset) )
+	    {
+		lseek( fd, offset, SEEK_SET );
+		fontList = (fontResource*)HeapAlloc( SystemHeap, 0, i);
+		if( fontList )
+		{
+		    fontResource* 	pfr = fontList;
+		    fontInfo* 		pfi = NULL;
+
+		    dprintf_font(stddeb,"Reading cached font metrics:\n");
+
+		    read( fd, fontList, i); /* read all metrics at once */
+		    while( offset < length )
+		    {
+			offset += sizeof(fontResource) + sizeof(fontInfo);
+			pfr->fi = pfi = (fontInfo*)(pfr + 1);
+			j = 1;
+			while( TRUE )
+			{
+			   if( offset > length ||
+			      (int)(pfi->next) != j++ ) goto fail;
+
+			   pfi->df.dfFace = pfr->lfFaceName;
+			   pfi->next = pfi + 1;
+
+			   if( j > pfr->count ) break;
+
+			   pfi = pfi->next;
+			   offset += sizeof(fontInfo);
+			}
+			pfi->next = NULL;
+			if( pfr->next )
+			{
+			    pfr->next = (fontResource*)(pfi + 1);
+			    pfr = pfr->next;
+			} 
+			else break;
+		    }
+		    if( pfr->next == NULL &&
+			*(int*)(pfi + 1) == X_FMC_MAGIC )
+		    {
+			/* read LFD stubs */
+			char* lpch = (char*)((int*)(pfi + 1) + 1);
+			offset += sizeof(int);
+			for( pfr = fontList; pfr; pfr = pfr->next )
+			{
+			    dprintf_font(stddeb,"\t%s, %i instances\n", lpch, pfr->count );
+			    pfr->resource = lpch;
+			    while( TRUE )
+			    { 
+				if( ++offset > length ) goto fail;
+				if( !*lpch++ ) break;
+			    }
+			}
+			close( fd );
+			return TRUE;
+		    }
+		}
+	    }
+	}
+fail:
+	if( fontList ) HeapFree( SystemHeap, 0, fontList );
+	fontList = NULL;
+	close( fd );
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           XFONT_WriteCachedMetrics
+ */
+static BOOL32 XFONT_WriteCachedMetrics( int fd, unsigned x_checksum, int x_count, int n_ff )
+{
+    fontResource* pfr;
+    fontInfo* pfi;
+
+    if( fd >= 0 )
+    {
+        int  i, j, k;
+
+        /* font metrics file:
+         *
+         * +0000 x_checksum
+         * +0004 x_count
+         * +0008 total size to load
+         * +000C prepackaged font metrics
+	 * ...
+	 * +...x 	X_FMC_MAGIC
+	 * +...x + 4 	LFD stubs
+         */
+
+	write( fd, &x_checksum, sizeof(unsigned) );
+	write( fd, &x_count, sizeof(int) );
+
+	for( j = i = 0, pfr = fontList; pfr; pfr = pfr->next ) 
+	{
+	    i += lstrlen32A( pfr->resource ) + 1;
+	    j += pfr->count;
+	}
+        i += n_ff * sizeof(fontResource) + j * sizeof(fontInfo) + sizeof(int);
+	write( fd, &i, sizeof(int) );
+
+	dprintf_font(stddeb,"Writing font cache:\n");
+
+	for( pfr = fontList; pfr; pfr = pfr->next )
+	{
+	    fontInfo fi;
+
+	    dprintf_font(stddeb,"\t%s, %i instances\n", pfr->resource, pfr->count );
+
+	    i = write( fd, pfr, sizeof(fontResource) );
+	    if( i == sizeof(fontResource) ) 
+	    {
+		for( k = 1, pfi = pfr->fi; pfi; pfi = pfi->next )
+		{
+		    memcpy( &fi, pfi, sizeof(fi) );
+
+		    fi.df.dfFace = NULL;
+		    fi.next = (fontInfo*)k;	/* loader checks this */
+
+		    j = write( fd, &fi, sizeof(fi) );
+		    k++;
+		}
+	        if( j == sizeof(fontInfo) ) continue;
+	    }
+	    break;
+	}
+        if( i == sizeof(fontResource) && j == sizeof(fontInfo) )
+	{
+	    i = j = X_FMC_MAGIC;
+	    write( fd, &i, sizeof(int) );
+	    for( pfr = fontList; pfr && i == j; pfr = pfr->next )
+	    {
+	        i = lstrlen32A( pfr->resource ) + 1;
+		j = write( fd, pfr->resource, i );
+	    }
+	}
+	close( fd );
+	return ( i == j );
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           X11DRV_FONT_Init
+ *
+ * Initialize font resource list and allocate font cache.
+ */
+BOOL32 X11DRV_FONT_Init( DeviceCaps* pDevCaps )
+{
+  XFontStruct*	x_fs;
+  fontResource* fr, *pfr;
+  fontInfo*	fi, *pfi;
+  unsigned	x_checksum;
+  int		i, j, k, x_count, fd = -1, buf_size = 0;
+  char*		lpstr, *lpch, *lpmetrics, *buffer;
+  char**	x_pattern;
+
+  DefResolution = PROFILE_GetWineIniInt( INIFontSection, "Resolution", 0 );
+  if( !DefResolution ) DefResolution = pDevCaps->logPixelsY;
+
+  i = abs(DefResolution - 72);
+  j = abs(DefResolution - 75);
+  k = abs(DefResolution - 100);
+
+  if( i < j ) DefResolution = ( i < k ) ? 72 : 100;
+  else DefResolution = ( j < k ) ? 75 : 100;
+      
+  x_pattern = XListFonts(display, "*", MAX_FONT_FAMILIES * 16, &x_count );
+
+  dprintf_font(stddeb,"Font Mapper: initializing %i fonts [LPY=%i, DR=%i]\n", 
+				    x_count, pDevCaps->logPixelsY, DefResolution);
+  for( i = x_checksum = 0; i < x_count; i++ )
+  {
+#if 0
+     printf("%i\t: %s\n", i, x_pattern[i] );
+#endif
+
+     j = lstrlen32A( x_pattern[i] );
+     if( j ) x_checksum ^= __genericCheckSum( (UINT16*)(x_pattern[i]), j );
+  }
+  x_checksum |= X_PFONT_MAGIC;
+
+  buf_size = 128;
+  buffer = HeapAlloc( SystemHeap, 0, buf_size );
+  lpmetrics = NULL;
+
+  /* deal with systemwide font metrics cache */
+
+  if( PROFILE_GetWineIniString( INIFontSection, "FontMetrics", "", buffer, 128 ) )
+      fd = open( buffer, O_RDONLY );
+
+  if( XFONT_ReadCachedMetrics(fd, x_checksum, x_count) == FALSE )
+  {
+      /* try per-user */
+      buffer = XFONT_UserMetricsCache( buffer, &buf_size );
+      if( buffer[0] )
+      {
+	  fd = open( buffer, O_RDONLY );
+	  if( XFONT_ReadCachedMetrics(fd, x_checksum, x_count) == FALSE )
+	      lpmetrics = HEAP_strdupA( SystemHeap, 0, buffer ); /* update later on */
+      }
+  }
+
+  fi = NULL;
+  if( fontList == NULL )	/* build metrics from scratch */
+  {
+     int n_ff;
+     char* typeface;
+
+     for( i = n_ff = 0; i < x_count; i++ )
+     {
+	typeface = lpch = x_pattern[i];
+
+	lpch = LFD_Advance(typeface, 3); /* extra '-' in the beginning */
+	if( !*lpch ) continue;
+
+	lpstr = lpch; 
+	j = lpch - typeface;	/* resource name length */
+
+	/* find a family to insert into */
+
+	for( pfr = NULL, fr = fontList; fr; fr = fr->next )
+	{
+	   if( !lstrncmpi32A(fr->resource, typeface, j) && 
+	       lstrlen32A(fr->resource) == j ) break;
+	   pfr = fr;
+	}  
+
+	if( !fi ) fi = (fontInfo*) HeapAlloc(SystemHeap, 0, sizeof(fontInfo));
+
+	if( !fr ) /* add new family */
+	{
+	   if( n_ff++ > MAX_FONT_FAMILIES ) break;
+
+	   if( !LFD_InitFontInfo( fi, lpstr) ) continue;
+
+	   fr = (fontResource*) HeapAlloc(SystemHeap, 0, sizeof(fontResource)); 
+	   memset(fr, 0, sizeof(fontResource));
+	   fr->resource = (char*) HeapAlloc(SystemHeap, 0, j + 1 );
+	   lstrcpyn32A( fr->resource, typeface, j + 1 );
+
+#ifdef DEBUG_FONT_INIT
+	   dprintf_font(stddeb,"    family: %s\n", fr->resource );
+#endif
+
+	   if( pfr ) pfr->next = fr;
+	   else fontList = fr;
+	}
+	else if( !LFD_InitFontInfo( fi, lpstr) ) continue;
+
+	/* check if we already have something better than "fi" */
+
+	for( pfi = fr->fi, j = 0; pfi && j <= 0; pfi = pfi->next ) 
+           if( (j = XFONT_IsSubset( pfi, fi )) < 0 ) 
+	       pfi->fi_flags |= FI_SUBSET; /* superseded by "fi" */
+	if( j > 0 ) continue;
+
+	/* add new font instance "fi" to the "fr" font resource */
+
+	if( fi->fi_flags & FI_SCALABLE )
+	{
+	    /* set scalable font height to 24 to get an origin for extrapolation */
+
+	   j = lstrlen32A(typeface);  j += 0x10;
+	   if( j > buf_size ) 
+	       buffer = (char*)HeapReAlloc( SystemHeap, 0, buffer, buf_size = j );
+
+	   lpch = LFD_Advance(typeface, 7);
+	   memcpy( buffer, typeface, (j = lpch - typeface) );
+	   lpch = LFD_Advance(lpch, 4);
+	   sprintf( buffer + j, "%d-%d-%d-*-%c-*-", fi->lfd_height,
+                            fi->lfd_decipoints, fi->lfd_resolution,
+                                        (*lpch == '-')?'*':*lpch );
+	   lpch = LFD_Advance(lpch, 2);
+	   strcat( lpstr = buffer, lpch);
+	}
+	else lpstr = typeface;
+
+	if( (x_fs = XLoadQueryFont(display, lpstr)) )
+	{
+	   fi->df.dfHorizRes = pDevCaps->logPixelsX;
+           fi->df.dfVertRes = pDevCaps->logPixelsY;
+
+	   XFONT_SetFontMetric( fi, fr, x_fs );
+           XFreeFont( display, x_fs );
+
+#ifdef DEBUG_FONT_INIT
+	   dprintf_font(stddeb,"\t[% 2ipt] '%s'\n", fi->df.dfPoints, typeface );
+#endif
+	   XFONT_CheckFIList( fr, fi, REMOVE_SUBSETS );
+	   fi = NULL;	/* preventing reuse */
+        }
+        else
+        {
+           fprintf(stderr, "FONT_Init: failed to load %s\n", lpstr );
+
+           XFONT_CheckFIList( fr, fi, UNMARK_SUBSETS );
+        }
+     }
+
+     if( lpmetrics )	 /* update cached metrics */
+     {
+	 fd = open( lpmetrics, O_CREAT | O_TRUNC | O_RDWR, 0644 ); /* -rw-r--r-- */
+	 if( XFONT_WriteCachedMetrics( fd, x_checksum, x_count, n_ff ) == FALSE )
+	     if( fd ) remove( lpmetrics );	/* couldn't write entire file */
+	 HeapFree( SystemHeap, 0, lpmetrics );
+     }
+  }
+
+  if( fi ) HeapFree(SystemHeap, 0, fi);
+  XFreeFontNames(x_pattern);
+
+  /* check if we're dealing with X11 R6 server */
+
+  lstrcpy32A(buffer, "-*-*-*-*-normal-*-[12 0 0 12]-*-72-*-*-*-iso8859-1");
+  if( (x_fs = XLoadQueryFont(display, buffer)) )
+  {
+       XTextCaps |= TC_SF_X_YINDEP;
+       XFreeFont(display, x_fs);
+  }
+
+  XFONT_WindowsNames( buffer );
+  XFONT_LoadAliases( &buffer, buf_size );
+  HeapFree(SystemHeap, 0, buffer);
+
+
+  /* fontList initialization is over, allocate X font cache */
+
+  fontCache = (fontObject*) HeapAlloc(SystemHeap, 0, fontCacheSize * sizeof(fontObject));
+  XFONT_GrowFreeList(0, fontCacheSize - 1);
+
+#ifdef DEBUG_FONT_INIT
+        dprintf_font(stddeb,"done!\n");
+#endif
+
+  /* update text caps parameter */
+
+  pDevCaps->textCaps = XTextCaps;
+  return TRUE;
+}
+
+
+/***********************************************************************
+ *           X Font Matching
+ *
+ * Compare two fonts (only parameters set by the XFONT_InitFontInfo()).
+ */
+static INT32 XFONT_IsSubset(fontInfo* match, fontInfo* fi)
+{
+  INT32           m;
+
+  /* 0 - keep both, 1 - keep match, -1 - keep fi */
+
+  m = (BYTE*)&fi->df.dfPixWidth - (BYTE*)&fi->df.dfItalic;
+  if( memcmp(&match->df.dfItalic, &fi->df.dfItalic, m )) return 0;
+
+  if( (!((fi->fi_flags & FI_SCALABLE) + (match->fi_flags & FI_SCALABLE))
+       && fi->lfd_height != match->lfd_height) ||
+      (!((fi->fi_flags & FI_POLYWEIGHT) + (match->fi_flags & FI_POLYWEIGHT))
+       && fi->df.dfWeight != match->df.dfWeight) ) return 0;
+
+  m = (int)(match->fi_flags & (FI_POLYWEIGHT | FI_SCALABLE)) -
+      (int)(fi->fi_flags & (FI_SCALABLE | FI_POLYWEIGHT));
+
+  if( m == (FI_POLYWEIGHT - FI_SCALABLE) ||
+      m == (FI_SCALABLE - FI_POLYWEIGHT) ) return 0;	/* keep both */
+  else if( m >= 0 ) return 1;	/* 'match' is better */
+
+  return -1;			/* 'fi' is better */
+}
+
+/***********************************************************************
+ *            XFONT_Match
+ *
+ * Compute the matching score between the logical font and the device font.
+ *
+ * contributions from highest to lowest:
+ *      charset
+ *      fixed pitch
+ *      height
+ *      family flags (only when the facename is not present)
+ *      width
+ *      weight, italics, underlines, strikeouts
+ *
+ * NOTE: you can experiment with different penalty weights to see what happens.
+ * http://premium.microsoft.com/msdn/library/techart/f30/f34/f40/d4d/sa8bf.htm
+ */
+static UINT32 XFONT_Match( fontMatch* pfm )
+{
+   fontInfo*    pfi = pfm->pfi;         /* device font to match */
+   LPLOGFONT16  plf = pfm->plf;         /* wanted logical font */
+   UINT32       penalty = 0;
+   BOOL32       bR6 = pfm->flags & FO_MATCH_XYINDEP;    /* from TextCaps */
+   BOOL32       bScale = pfi->fi_flags & FI_SCALABLE;
+   INT32        d, h;
+
+   dprintf_font( stddeb,"\t[ %-2ipt h=%-3i w=%-3i %s%s]", pfi->df.dfPoints,
+		 pfi->df.dfPixHeight, pfi->df.dfAvgWidth,
+		(pfi->df.dfWeight > 400) ? "Bold " : "Normal ",
+		(pfi->df.dfItalic) ? "Italic" : "" );
+
+   pfm->flags = 0;
+
+   if( plf->lfCharSet != DEFAULT_CHARSET &&
+       plf->lfCharSet != pfi->df.dfCharSet ) penalty += 0x200;
+
+   /* TMPF_FIXED_PITCH means exactly the opposite */
+
+   if( plf->lfPitchAndFamily & FIXED_PITCH ) 
+   {
+      if( pfi->df.dfPitchAndFamily & TMPF_FIXED_PITCH ) penalty += 0x100;
+   }
+   else if( !(pfi->df.dfPitchAndFamily & TMPF_FIXED_PITCH) ) penalty += 0x2;
+
+   if( plf->lfHeight > 0 )
+       d = (h = pfi->df.dfPixHeight) - plf->lfHeight;
+   else if( plf->lfHeight < -1 )
+       d = (h = pfi->df.dfPoints) + plf->lfHeight;
+   else d = h = 0;	
+
+   if( d && plf->lfHeight )
+   {
+       UINT16	height = ( plf->lfHeight > 0 ) ? plf->lfHeight
+			 : ((-plf->lfHeight * pfi->df.dfPixHeight) / h);
+       if( bScale ) pfm->height = height;
+       else if( (plf->lfQuality != PROOF_QUALITY) && bR6 )
+       {
+	   if( d > 0 ) 	/* do not shrink raster fonts */
+	   {
+	       pfm->height = pfi->df.dfPixHeight;
+	       penalty += (pfi->df.dfPixHeight - height) * 0x4;
+	   }
+	   else 	/* expand only in integer multiples */
+	   {
+	       pfm->height = height - height%pfi->df.dfPixHeight;
+	       penalty += (height - pfm->height) * pfm->height / height;
+	   }
+       }
+       else /* can't be scaled at all */
+       {
+           if( plf->lfQuality != PROOF_QUALITY) pfm->flags |= FO_SYNTH_HEIGHT;
+           pfm->height = pfi->df.dfPixHeight;
+           penalty += (d > 0)? d * 0x8 : -d * 0x10;
+       }
+   } else pfm->height = pfi->df.dfPixHeight;
+
+   if((pfm->flags & FO_MATCH_PAF) &&
+      (plf->lfPitchAndFamily & FF_FAMILY) != (pfi->df.dfPitchAndFamily & FF_FAMILY) )
+       penalty += 0x10;
+
+   if( plf->lfWidth )
+   {
+       if( bR6 && bScale ) h = 0; 
+       else
+       {
+	   /* FIXME: not complete */
+
+	   pfm->flags |= FO_SYNTH_WIDTH;
+	   h = abs(plf->lfWidth - (pfm->height * pfi->df.dfAvgWidth)/pfi->df.dfPixHeight);
+       }
+       penalty += h * ( d ) ? 0x2 : 0x1 ;
+   }
+   else if( !(pfi->fi_flags & FI_NORMAL) ) penalty++;
+
+   if( pfi->lfd_resolution != DefResolution ) penalty++;
+
+   if( plf->lfWeight != FW_DONTCARE )
+   {
+       penalty += abs(plf->lfWeight - pfi->df.dfWeight) / 40;
+       if( plf->lfWeight > pfi->df.dfWeight ) pfm->flags |= FO_SYNTH_BOLD;
+   } else if( pfi->df.dfWeight >= FW_BOLD ) penalty++;	/* choose normal by default */
+
+   if( plf->lfItalic != pfi->df.dfItalic )
+   {
+       penalty += 0x4;
+       pfm->flags |= FO_SYNTH_ITALIC;
+   }
+
+   if( plf->lfUnderline ) pfm->flags |= FO_SYNTH_UNDERLINE;
+   if( plf->lfStrikeOut ) pfm->flags |= FO_SYNTH_STRIKEOUT;
+
+   dprintf_font(stddeb,"-> %i\n", penalty );
+
+   return penalty;
+}
+
+/***********************************************************************
+ *            XFONT_MatchFIList
+ *
+ * Scan a particular font resource for the best match.
+ */
+static UINT32 XFONT_MatchFIList( fontMatch* pfm )
+{
+  BOOL32        skipRaster = (pfm->flags & FO_MATCH_NORASTER);
+  UINT32        current_score, score = (UINT32)(-1);
+  fontMatch     fm = *pfm;
+
+  for( fm.pfi = pfm->pfr->fi; fm.pfi && score; fm.pfi = fm.pfi->next )
+  {
+     if( skipRaster && !(fm.pfi->fi_flags & FI_SCALABLE) )
+         continue;
+
+     current_score = XFONT_Match( &fm );
+     if( score > current_score )
+     {
+        memcpy( pfm, &fm, sizeof(fontMatch) );
+        score = current_score;
+     }
+  }
+  return score;
+}
+
+/***********************************************************************
+ *            XFONT_CheckAliasTable
+ */
+static LPSTR XFONT_CheckAliasTable( LPSTR lpAlias )
+{
+    fontAlias* fa;
+
+    for( fa = aliasTable; fa; fa = fa->next )
+	if( !lstrcmpi32A( fa->faAlias, lpAlias ) ) return fa->faTypeFace;
+    return NULL;
+}
+
+/***********************************************************************
+ *            XFONT_CheckFIList
+ *
+ * REMOVE_SUBSETS - attach new fi and purge subsets
+ * UNMARK_SUBSETS - remove subset flags from all fi entries
+ */
+static void XFONT_CheckFIList( fontResource* fr, fontInfo* fi, int action)
+{
+  int		i = 0;
+  fontInfo*     pfi, *prev;
+
+  for( prev = NULL, pfi = fr->fi; pfi; )
+  {
+    if( action == REMOVE_SUBSETS )
+    {
+        if( pfi->fi_flags & FI_SUBSET )
+        {
+	    fontInfo* subset = pfi;
+
+	    i++;
+	    fr->count--;
+            if( prev ) prev->next = pfi = pfi->next;
+            else fr->fi = pfi = pfi->next;
+	    HeapFree( SystemHeap, 0, subset );
+	    continue;
+        }
+    }
+    else pfi->fi_flags &= ~FI_SUBSET;
+
+    prev = pfi; 
+    pfi = pfi->next;
+  }
+
+  if( action == REMOVE_SUBSETS )	/* also add the superset */
+  {
+    if( fi->fi_flags & FI_SCALABLE )
+    {
+        fi->next = fr->fi;
+        fr->fi = fi;
+    }
+    else if( prev ) prev->next = fi; else fr->fi = fi;
+    fr->count++;
+  }
+
+#ifdef DEBUG_FONT_INIT
+  if( i ) dprintf_font(stddeb,"\t    purged %i subsets [%i]\n", i , fr->count);
+#endif
+}
+
+/***********************************************************************
+ *            XFONT_FindFIList
+ */
+static fontResource* XFONT_FindFIList( fontResource* pfr, const char* pTypeFace )
+{
+  while( pfr )
+  {
+    if( !lstrcmpi32A( pfr->lfFaceName, pTypeFace ) ) break;
+    pfr = pfr->next;
+  }
+  return pfr;
+}
+
+/***********************************************************************
+ *          XFONT_MatchDeviceFont
+ *
+ * Scan font resource tree.
+ */
+static BOOL32 XFONT_MatchDeviceFont( fontResource* start, fontMatch* pfm )
+{
+    fontMatch           fm = *pfm;
+
+    pfm->pfi = NULL;
+    if( fm.plf->lfFaceName[0] )
+    {
+	LPSTR str = XFONT_CheckAliasTable( fm.plf->lfFaceName );
+        fm.pfr = XFONT_FindFIList( start, str ? str : fm.plf->lfFaceName );
+    }
+
+    if( fm.pfr )        /* match family */
+    {
+	dprintf_font(stddeb, "%s\n", fm.pfr->lfFaceName );
+
+        XFONT_MatchFIList( &fm );
+        *pfm = fm;
+    }
+
+    if( !pfm->pfi )      /* match all available fonts */
+    {
+        UINT32          current_score, score = (UINT32)(-1);
+
+        fm.flags |= FO_MATCH_PAF;
+        for( start = fontList; start && score; start = start->next )
+        {
+            fm.pfr = start;
+	    dprintf_font(stddeb, "%s\n", fm.pfr->lfFaceName );
+
+            current_score = XFONT_MatchFIList( &fm );
+            if( current_score < score )
+            {
+                score = current_score;
+                *pfm = fm;
+            }
+        }
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           X Font Cache
+ */
+static void XFONT_GrowFreeList(int start, int end)
+{
+   /* add all entries from 'start' up to and including 'end' */
+
+   memset( fontCache + start, 0, (end - start + 1) * sizeof(fontObject) );
+
+   fontCache[end].lru = fontLF;
+   fontCache[end].count = -1;
+   fontLF = start;
+   while( start < end )
+   {
+	fontCache[start].count = -1;
+	fontCache[start].lru = start + 1;
+	start++;
+   } 
+}
+
+static fontObject* XFONT_LookupCachedFont( LPLOGFONT16 plf, UINT16* checksum )
+{
+    UINT16	cs = __lfCheckSum( plf );
+    int		i = fontMRU, prev = -1;
+   
+   *checksum = cs;
+    while( i >= 0 )
+    {
+	if( fontCache[i].lfchecksum == cs &&
+	  !(fontCache[i].fo_flags & FO_REMOVED) )
+	{
+	    /* FIXME: something more intelligent here */
+
+	    if( !memcmp( plf, &fontCache[i].lf,
+			 sizeof(LOGFONT16) - LF_FACESIZE ) &&
+		!lstrncmpi32A( plf->lfFaceName, fontCache[i].lf.lfFaceName, 
+							    LF_FACESIZE ) )
+	    {
+		/* remove temporarily from the lru list */
+
+		if( prev >= 0 )
+		    fontCache[prev].lru = fontCache[i].lru;
+		else 
+		    fontMRU = (INT16)fontCache[i].lru;
+		return (fontCache + i);
+	    }
+	}
+	prev = i;
+	i = (INT16)fontCache[i].lru;
+    }
+    return NULL;
+}
+
+static fontObject* XFONT_GetCacheEntry()
+{
+    int		i;
+
+    if( fontLF == -1 )
+    {
+	int	prev_i, prev_j, j;
+
+	dprintf_font(stddeb,"font cache is full\n");
+
+	/* lookup the least recently used font */
+
+	for( prev_i = prev_j = j = -1, i = fontMRU; i >= 0; i = (INT16)fontCache[i].lru )
+	{
+	    if( fontCache[i].count <= 0 &&
+	      !(fontCache[i].fo_flags & FO_SYSTEM) )
+	    {
+		prev_j = prev_i;
+		j = i;
+	    }
+	    prev_i = i;
+	}
+
+	if( j >= 0 )	/* unload font */
+	{
+	    /* detach from the lru list */
+
+	    dprintf_font(stddeb,"\tfreeing entry %i\n", j );
+
+	    if( prev_j >= 0 )
+		fontCache[prev_j].lru = fontCache[j].lru;
+	    else fontMRU = (INT16)fontCache[j].lru;
+
+	    /* FIXME: lpXForm, lpPixmap */
+	    XFreeFont( display, fontCache[j].fs );
+
+	    memset( fontCache + j, 0, sizeof(fontObject) );
+	    return (fontCache + j);
+	}
+	else		/* expand cache */
+	{
+	    fontObject*	newCache;
+
+	    prev_i = fontCacheSize + FONTCACHE;
+
+	    dprintf_font(stddeb,"\tgrowing font cache from %i to %i\n", fontCacheSize, prev_i );
+
+	    if( (newCache = (fontObject*)HeapReAlloc(SystemHeap, 0,  
+						     fontCache, prev_i)) )
+	    {
+		i = fontCacheSize;
+		fontCacheSize  = prev_i;
+		fontCache = newCache;
+		XFONT_GrowFreeList( i, fontCacheSize - 1);
+	    } 
+	    else return NULL;
+	}
+    }
+
+    /* detach from the free list */
+
+    i = fontLF;
+    fontLF = (INT16)fontCache[i].lru;
+    fontCache[i].count = 0;
+    return (fontCache + i);
+}
+
+static int XFONT_ReleaseCacheEntry(fontObject* pfo)
+{
+    UINT32	u = (UINT32)(pfo - fontCache);
+
+    if( u < fontCacheSize ) return (--fontCache[u].count);
+    return -1;
+}
+
+/***********************************************************************
+ *           X Device Font Objects
+ */
+static X_PHYSFONT XFONT_RealizeFont( LPLOGFONT16 plf )
+{
+    UINT16	checksum;
+    fontObject* pfo = XFONT_LookupCachedFont( plf, &checksum );
+
+    if( !pfo )
+    {
+	fontMatch	fm = { NULL, NULL, 0, 0, plf};
+	INT32		i, index;
+
+	if( XTextCaps & TC_SF_X_YINDEP ) fm.flags = FO_MATCH_XYINDEP;
+
+	/* allocate new font cache entry */
+
+	if( (pfo = XFONT_GetCacheEntry()) )
+	{
+	    LPSTR	lpLFD = HeapAlloc( GetProcessHeap(), 0, MAX_LFD_LENGTH );
+	    
+	    if( lpLFD ) /* initialize entry and load font */
+	    {
+		UINT32	uRelaxLevel = 0;
+
+		dprintf_font(stddeb,"XRealizeFont: (%u) '%s' h=%i weight=%i %s\n",
+				     plf->lfCharSet, plf->lfFaceName, plf->lfHeight, 
+				     plf->lfWeight, (plf->lfItalic) ? "Italic" : "" );
+
+		XFONT_MatchDeviceFont( fontList, &fm );
+
+		pfo->fr = fm.pfr;
+		pfo->fi = fm.pfi;
+		pfo->fo_flags = fm.flags & ~FO_MATCH_MASK;
+
+		memcpy( &pfo->lf, plf, sizeof(LOGFONT16) );
+		pfo->lfchecksum = checksum;
+
+		do
+		{
+		    LFD_ComposeLFD( pfo, fm.height, lpLFD, uRelaxLevel++ );
+		    if( (pfo->fs = XLoadQueryFont( display, lpLFD )) ) break;
+		} while( uRelaxLevel );
+
+		if( XFONT_GetLeading( &pfo->fi->df, pfo->fs, &i, NULL ) )
+		    pfo->foAvgCharWidth = (INT16)pfo->fs->per_char['X' - pfo->fs->min_char_or_byte2].width;
+		else
+		    pfo->foAvgCharWidth = (INT16)XFONT_GetAvgCharWidth( &pfo->fi->df, pfo->fs );
+		pfo->foInternalLeading = (INT16)i;
+
+		/* FIXME: If we've got a soft font or
+		 * there are FO_SYNTH_... flags for the
+		 * non PROOF_QUALITY request, the engine
+		 * should rasterize characters into mono
+		 * pixmaps and store them in the pfo->lpPixmap
+		 * array (pfo->fs should be updated as well).
+		 * X11DRV_ExtTextOut() must be heavily modified 
+		 * to support pixmap blitting and FO_SYNTH_...
+		 * styles.
+		 */
+
+		pfo->lpXForm = NULL;
+		pfo->lpPixmap = NULL;
+
+		HeapFree( GetProcessHeap(), 0, lpLFD );
+	    } 
+	    else /* attach back to the free list */
+	    {
+		pfo->count = -1;
+		pfo->lru = fontLF;
+		fontLF = (pfo - fontCache);
+		pfo = NULL;
+	    }
+	}
+
+	if( !pfo ) /* couldn't get a new entry, get one of the cached fonts */
+	{
+	    UINT32		current_score, score = (UINT32)(-1);
+
+	    i = index = fontMRU; 
+	    fm.flags |= FO_MATCH_PAF;
+            do
+            {
+		pfo = fontCache + i;
+		fm.pfr = pfo->fr; fm.pfi = pfo->fi;
+
+                current_score = XFONT_Match( &fm );
+                if( current_score < score ) index = i;
+
+	        i =  pfo->lru;
+            } while( i >= 0 );
+	    pfo = fontCache + index;
+	    pfo->count++;
+	    return (X_PHYSFONT)(X_PFONT_MAGIC | index);
+	}
+    }
+ 
+    /* attach at the head of the lru list */
+
+    pfo->count++;
+    pfo->lru = fontMRU;
+    fontMRU = (pfo - fontCache);
+
+    dprintf_font(stddeb,"physfont %i\n", fontMRU);
+
+    return (X_PHYSFONT)(X_PFONT_MAGIC | fontMRU);
+}
+
+/***********************************************************************
+ *           XFONT_GetFontObject
+ */
+fontObject* XFONT_GetFontObject( X_PHYSFONT pFont )
+{
+    if( CHECK_PFONT(pFont) ) return __PFONT(pFont);
+    return NULL;
+}
+
+/***********************************************************************
+ *           XFONT_GetFontStruct
+ */
+XFontStruct* XFONT_GetFontStruct( X_PHYSFONT pFont )
+{
+    if( CHECK_PFONT(pFont) ) return __PFONT(pFont)->fs;
+    return NULL;
+}
+
+/***********************************************************************
+ *           XFONT_GetFontInfo
+ */
+LPIFONTINFO16 XFONT_GetFontInfo( X_PHYSFONT pFont )
+{
+    if( CHECK_PFONT(pFont) ) return &(__PFONT(pFont)->fi->df);
+    return NULL;
+}
+
+
+
+/* X11DRV Interface ****************************************************
+ *                                                                     *
+ * Exposed via the dc->funcs dispatch table.                           *
+ *                                                                     *
+ ***********************************************************************/
+/***********************************************************************
+ *           X11DRV_FONT_SelectObject
+ */
+HFONT32 X11DRV_FONT_SelectObject( DC* dc, HFONT32 hfont, FONTOBJ* font )
+{
+    HFONT32 hPrevFont = 0;
+
+    if( CHECK_PFONT(dc->u.x.font) ) 
+        XFONT_ReleaseCacheEntry( __PFONT(dc->u.x.font) );
+
+    dc->u.x.font = XFONT_RealizeFont( &font->logfont );
+    hPrevFont = dc->w.hFont;
+    dc->w.hFont = hfont;
+
+    return hPrevFont;
+}
+
+
+/***********************************************************************
+ *
+ *           X11DRV_EnumDeviceFonts
+ */
+BOOL32	X11DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
+				        DEVICEFONTENUMPROC proc, LPARAM lp )
+{
+    ENUMLOGFONTEX16	lf;
+    NEWTEXTMETRIC16	tm;
+    fontResource* 	pfr = fontList;
+    BOOL32	  	b, bRet = 0;
+
+    if( plf->lfFaceName[0] )
+    {
+	pfr = XFONT_FindFIList( pfr, plf->lfFaceName );
+	if( pfr )
+	{
+	    fontInfo*	pfi;
+	    for( pfi = pfr->fi; pfi; pfi = pfi->next )
+		if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm, 
+			XFONT_GetFontMetric( pfi, &lf, &tm ), lp )) )
+		     bRet = b;
+		else break;
+	}
+    }
+    else
+	for( ; pfr ; pfr = pfr->next )
+	    if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm, 
+		       XFONT_GetFontMetric( pfr->fi, &lf, &tm ), lp )) )
+		 bRet = b;
+	    else break;
+
+    return bRet;
+}
+
+
+/***********************************************************************
+ *           X11DRV_GetTextExtentPoint
+ */
+BOOL32 X11DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
+                                  LPSIZE32 size )
+{
+    XFontStruct* pfs = XFONT_GetFontStruct( dc->u.x.font );
+    if( pfs )
+    {
+	int dir, ascent, descent;
+	XCharStruct info;
+
+	XTextExtents( pfs, str, count, &dir, &ascent, &descent, &info );
+	size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
+						* dc->wndExtX / dc->vportExtX);
+	size->cy = abs((pfs->ascent + pfs->descent) * dc->wndExtY / dc->vportExtY);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           X11DRV_GetTextMetrics
+ */
+BOOL32 X11DRV_GetTextMetrics(DC *dc, TEXTMETRIC32A *metrics)
+{
+    if( CHECK_PFONT(dc->u.x.font) )
+    {
+	fontObject* pfo = __PFONT(dc->u.x.font);
+	XFONT_GetTextMetric( pfo, metrics );
+	return TRUE;
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           X11DRV_GetCharWidth
+ */
+BOOL32 X11DRV_GetCharWidth( DC *dc, UINT32 firstChar, UINT32 lastChar,
+                            LPINT32 buffer )
+{
+    XFontStruct* xfs = XFONT_GetFontStruct( dc->u.x.font );
+
+    if( xfs )
+    {
+	int i;
+
+	if (xfs->per_char == NULL)
+	    for (i = firstChar; i <= lastChar; i++)
+		*buffer++ = xfs->min_bounds.width;
+	else
+	{
+	    XCharStruct *cs, *def;
+	    static XCharStruct	__null_char = { 0, 0, 0, 0, 0, 0 };
+
+	    CI_GET_CHAR_INFO(xfs, xfs->default_char, &__null_char, def);
+
+	    for (i = firstChar; i <= lastChar; i++)
+	    {
+		if (i >= xfs->min_char_or_byte2 && i <= xfs->max_char_or_byte2)
+		{
+		    cs = &xfs->per_char[(i - xfs->min_char_or_byte2)]; 
+		    if (CI_NONEXISTCHAR(cs)) cs = def; 
+  		} else cs = def;
+		*buffer++ = MAX( cs->width, 0 );
+	    }
+	}
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *								       *
+ *           Font Resource API					       *
+ *								       *
+ ***********************************************************************/
+/***********************************************************************
+ *           AddFontResource16    (GDI.119)
+ *
+ *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
+ *
+ *  FIXME: Load header and find the best-matching font in the fontList;
+ * 	   fixup dfPoints if all metrics are identical, otherwise create
+ *	   new fontAlias. When soft font support is ready this will
+ *	   simply create a new fontResource ('filename' will go into
+ *	   the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
+ *	   flag set. 
+ */
+INT16 AddFontResource16( LPCSTR filename )
+{
+    return AddFontResource32A( filename );
+}
+
+
+/***********************************************************************
+ *           AddFontResource32A    (GDI32.2)
+ */
+INT32 AddFontResource32A( LPCSTR str )
+{
+    if (HIWORD(str))	/* font file */
+        fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
+    else		/* font resource handle */
+        fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           AddFontResource32W    (GDI32.4)
+ */
+INT32 AddFontResource32W( LPCWSTR str )
+{
+    fprintf( stdnimp, "STUB: AddFontResource32W(%p)\n", str );
+    return 1;
+}
+
+/***********************************************************************
+ *           RemoveFontResource16    (GDI.136)
+ */
+BOOL16 RemoveFontResource16( LPCSTR str )
+{
+    return RemoveFontResource32A( str );
+}
+
+
+/***********************************************************************
+ *           RemoveFontResource32A    (GDI32.284)
+ */
+BOOL32 RemoveFontResource32A( LPCSTR str )
+{
+    if (HIWORD(str))
+        fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
+    else
+        fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           RemoveFontResource32W    (GDI32.286)
+ */
+BOOL32 RemoveFontResource32W( LPCWSTR str )
+{
+    fprintf( stdnimp, "STUB: RemoveFontResource32W(%p)\n", str );
+    return TRUE;
+}
+
+
diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec
index fb584e4..4a88641 100644
--- a/if1632/advapi32.spec
+++ b/if1632/advapi32.spec
@@ -1,6 +1,6 @@
 name	advapi32
 type	win32
-base	1
+base	0
 
 0000 stub AbortSystemShutdownA
 0001 stub AbortSystemShutdownW
@@ -14,7 +14,7 @@
 0009 stub AdjustTokenGroups
 0010 stub AdjustTokenPrivileges
 0011 stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr) AllocateAndInitializeSid
-0012 stub AllocateLocallyUniqueId
+0012 stdcall AllocateLocallyUniqueId(ptr) AllocateLocallyUniqueId
 0013 stub AreAllAccessesGranted
 0014 stub AreAnyAccessesGranted
 0015 stub BackupEventLogA
@@ -68,7 +68,7 @@
 0063 stdcall GetSidLengthRequired(long) GetSidLengthRequired
 0064 stdcall GetSidSubAuthority(ptr long) GetSidSubAuthority
 0065 stdcall GetSidSubAuthorityCount(ptr) GetSidSubAuthorityCount
-0066 stub GetTokenInformation
+0066 stdcall GetTokenInformation(long long ptr long ptr) GetTokenInformation
 0067 stdcall GetUserNameA(ptr ptr) GetUserName32A
 0068 stdcall GetUserNameW(ptr ptr) GetUserName32W
 0069 stub ImpersonateLoggedOnUser
@@ -112,11 +112,11 @@
 0107 stub OpenEventLogA
 0108 stub OpenEventLogW
 0109 stdcall OpenProcessToken(long long ptr) OpenProcessToken
-0110 stub OpenSCManagerA
-0111 stub OpenSCManagerW
+0110 stdcall OpenSCManagerA(ptr ptr long) OpenSCManagerA
+0111 stdcall OpenSCManagerW(ptr ptr long) OpenSCManagerW
 0112 stub OpenServiceA
 0113 stub OpenServiceW
-0114 stub OpenThreadToken
+0114 stdcall OpenThreadToken(long long long ptr) OpenThreadToken
 0115 stub PrivilegeCheck
 0116 stub PrivilegedServiceAuditAlarmA
 0117 stub PrivilegedServiceAuditAlarmW
@@ -188,7 +188,7 @@
 0183 stub SetFileSecurityW
 0184 stub SetKernelObjectSecurity
 0185 stub SetPrivateObjectSecurity
-0186 stub SetSecurityDescriptorDacl
+0186 stdcall SetSecurityDescriptorDacl(ptr long ptr long) RtlSetDaclSecurityDescriptor
 0187 stub SetSecurityDescriptorGroup
 0188 stub SetSecurityDescriptorOwner
 0189 stub SetSecurityDescriptorSacl
diff --git a/if1632/builtin.c b/if1632/builtin.c
index 44b86ee..288e363 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -148,9 +148,9 @@
     /* Win32 DLLs */
     { &ADVAPI32_Descriptor, 0 },
     { &COMCTL32_Descriptor, DLL_FLAG_NOT_USED },
-    { &COMDLG32_Descriptor, 0 },
+    { &COMDLG32_Descriptor, DLL_FLAG_NOT_USED },
     { &CRTDLL_Descriptor,   0 },
-    { &OLE32_Descriptor,    0 },
+    { &OLE32_Descriptor,    DLL_FLAG_NOT_USED },
     { &GDI32_Descriptor,    0 },
     { &KERNEL32_Descriptor, DLL_FLAG_ALWAYS_USED },
     { &LZ32_Descriptor,     0 },
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 90b502c..7e6131e 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -144,7 +144,7 @@
 0136 stub GdiPlayScript
 0137 stub GdiReleaseLocalDC
 0138 stub GdiSetAttrs
-0139 stub GdiSetBatchLimit
+0139 return GdiSetBatchLimit 4 1
 0140 stub GdiSetServerAttr
 0141 stub GetArcDirection
 0142 stub GetAspectRatioFilterEx
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 3721737..af3761c 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -225,7 +225,7 @@
 227 pascal   RegFlushKey(long) RegFlushKey
 228 stub K228
 229 stub K229
-230 stub GlobalSmartPageLock
+230 pascal GlobalSmartPageLock(word) GlobalPageLock #?
 231 stub GlobalSmartPageUnlock
 232 stub RegLoadKey
 233 stub RegUnloadKey
@@ -243,8 +243,8 @@
 319 stub FlushCachedFileHandle
 320 pascal16 IsTask(word) IsTask
 323 return IsRomModule 2 0
-324 stub LogError
-325 stub LogParamError
+324 pascal16 LogError(word ptr) LogError
+325 pascal16 LogParamError(word ptr ptr) LogParamError
 326 return IsRomFile 2 0
 327 stub KERNEL_327
 328 stub _DebugOutput
@@ -320,7 +320,7 @@
 514 stub FreeLibrary32W
 515 pascal GetProcAddress32W(long ptr) GetProcAddress32
 516 stub GetVDMPointer32W
-517 stub CallProc32W
+517 pascal CallProc32W() WIN16_CallProc32W
 518 stub CallProcEx32W
 519 stub KERNEL_519
 522 stub KERNEL_522
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 23d4f31..a080670 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -2,687 +2,841 @@
 type	win32
 base	1
 
-0000 stdcall AddAtomA(ptr) AddAtom32A
-0001 stdcall AddAtomW(ptr) AddAtom32W
-0002 stub AddConsoleAliasA
-0003 stub AddConsoleAliasW
-0004 stub AllocConsole
-0005 stdcall AreFileApisANSI() AreFileApisANSI
-0006 stub BackupRead
-0007 stub BackupSeek
-0008 stub BackupWrite
-0009 stub BaseAttachCompleteThunk
-0010 stub BasepDebugDump
-0011 stdcall Beep(long long) Beep
-0012 stub BeginUpdateResourceA
-0013 stub BeginUpdateResourceW
-0014 stdcall BuildCommDCBA(ptr ptr) BuildCommDCB32A
-0015 stdcall BuildCommDCBAndTimeoutsA(ptr ptr ptr) BuildCommDCBAndTimeouts32A
-0016 stdcall BuildCommDCBAndTimeoutsW(ptr ptr ptr) BuildCommDCBAndTimeouts32W
-0017 stdcall BuildCommDCBW(ptr ptr) BuildCommDCB32W
-0018 stub CallNamedPipeA
-0019 stub CallNamedPipeW
-0020 stdcall ClearCommBreak(long) ClearCommBreak32
-0021 stdcall ClearCommError(long ptr ptr) ClearCommError
-0022 stub CloseConsoleHandle
-0023 stdcall CloseHandle(long) CloseHandle
-0024 stub CloseProfileUserMapping
-0025 stub CmdBatNotification
-0026 stub CommConfigDialogA
-0027 stub CommConfigDialogW
-0028 stdcall CompareFileTime(ptr ptr) CompareFileTime
-0029 stdcall CompareStringA(long long ptr long ptr long) CompareString32A
-0030 stdcall CompareStringW(long long ptr long ptr long) CompareString32W
-0031 stub ConnectNamedPipe
-0032 stub ConsoleMenuControl
-0033 stub ConsoleSubst
-0034 stub ContinueDebugEvent
-0035 stub ConvertDefaultLocale
-0036 stdcall CopyFileA(ptr ptr long) CopyFile32A
-0037 stdcall CopyFileW(ptr ptr long) CopyFile32W
-0038 stub CreateConsoleScreenBuffer
-0039 stdcall CreateDirectoryA(ptr ptr) CreateDirectory32A
-0040 stdcall CreateDirectoryExA(ptr ptr ptr) CreateDirectoryEx32A
-0041 stdcall CreateDirectoryExW(ptr ptr ptr) CreateDirectoryEx32W
-0042 stdcall CreateDirectoryW(ptr ptr) CreateDirectory32W
-0043 stdcall CreateEventA(ptr long long ptr) CreateEvent32A
-0044 stdcall CreateEventW(ptr long long ptr) CreateEvent32W
-0045 stdcall CreateFileA(ptr long long ptr long long long) CreateFile32A
-0046 stdcall CreateFileMappingA(long ptr long long long ptr) CreateFileMapping32A
-0047 stdcall CreateFileMappingW(long ptr long long long ptr) CreateFileMapping32W
-0048 stdcall CreateFileW(ptr long long ptr long long long) CreateFile32W
-0049 stub CreateIoCompletionPort
-0050 stub CreateMailslotA
-0051 stub CreateMailslotW
-0052 stdcall CreateMutexA(ptr long ptr) CreateMutex32A
-0053 stdcall CreateMutexW(ptr long ptr) CreateMutex32W
-0054 stub CreateNamedPipeA
-0055 stub CreateNamedPipeW
-0056 stub CreatePipe
-0057 stdcall CreateProcessA(ptr ptr ptr ptr long long ptr ptr ptr ptr) CreateProcess32A
-0058 stub CreateProcessW
-0059 stub CreateRemoteThread
-0060 stdcall CreateSemaphoreA(ptr long long ptr) CreateSemaphore32A
-0061 stdcall CreateSemaphoreW(ptr long long ptr) CreateSemaphore32W
-0062 stub CreateTapePartition
-0063 stdcall CreateThread(ptr long ptr long long ptr) CreateThread
-0064 stub CreateVirtualBuffer
-0065 stub DebugActiveProcess
-0066 stub DebugBreak
-0067 stub DefineDosDeviceA
-0068 stub DefineDosDeviceW
-0069 stdcall DeleteAtom(long) DeleteAtom32
-0070 stdcall DeleteCriticalSection(ptr)	DeleteCriticalSection
-0071 stdcall DeleteFileA(ptr) DeleteFile32A
-0072 stdcall DeleteFileW(ptr) DeleteFile32W
-0073 stub DeviceIoControl
-0074 stdcall DisableThreadLibraryCalls(long) DisableThreadLibraryCalls
-0075 stub DisconnectNamedPipe
-0076 stdcall DosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime
-0077 stub DuplicateConsoleHandle
-0078 	stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle
-0079 stub EndUpdateResourceA
-0080 stub EndUpdateResourceW
-0081 stdcall EnterCriticalSection(ptr)	EnterCriticalSection
-0082 stub EnumCalendarInfoA
-0083 stub EnumCalendarInfoW
-0084 stub EnumDateFormatsA
-0085 stub EnumDateFormatsW
-0086 stdcall EnumResourceLanguagesA(long ptr ptr ptr long) THUNK_EnumResourceLanguages32A
-0087 stdcall EnumResourceLanguagesW(long ptr ptr ptr long) THUNK_EnumResourceLanguages32W
-0088 stdcall EnumResourceNamesA(long ptr ptr long) THUNK_EnumResourceNames32A
-0089 stdcall EnumResourceNamesW(long ptr ptr long) THUNK_EnumResourceNames32W
-0090 stdcall EnumResourceTypesA(long ptr long) THUNK_EnumResourceTypes32A
-0091 stdcall EnumResourceTypesW(long ptr long) THUNK_EnumResourceTypes32W
-0092 stdcall EnumSystemCodePagesA(ptr long) THUNK_EnumSystemCodePages32A
-0093 stdcall EnumSystemCodePagesW(ptr long) THUNK_EnumSystemCodePages32W
-0094 stdcall EnumSystemLocalesA(ptr long) THUNK_EnumSystemLocales32A
-0095 stdcall EnumSystemLocalesW(ptr long) THUNK_EnumSystemLocales32W
-0096 stub EnumTimeFormatsA
-0097 stub EnumTimeFormatsW
-0098 stub EraseTape
-0099 stdcall EscapeCommFunction(long long) EscapeCommFunction32
-0100 stdcall ExitProcess(long) ExitProcess
-0101 stub ExitThread
-0102 stub ExitVDM
-0103 stdcall ExpandEnvironmentStringsA(ptr ptr long) ExpandEnvironmentStrings32A
-0104 stdcall ExpandEnvironmentStringsW(ptr ptr long) ExpandEnvironmentStrings32W
-0105 stub ExpungeConsoleCommandHistoryA
-0106 stub ExpungeConsoleCommandHistoryW
-0107 stub ExtendVirtualBuffer
-0108 stdcall FatalAppExitA(long ptr) FatalAppExit32A
-0109 stdcall FatalAppExitW(long ptr) FatalAppExit32W
-0110 stub FatalExit
-0111 stdcall FileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime
-0112 stdcall FileTimeToLocalFileTime(ptr ptr) FileTimeToLocalFileTime
-0113 stdcall FileTimeToSystemTime(ptr ptr) FileTimeToSystemTime
-0114 stub FillConsoleOutputAttribute
-0115 stub FillConsoleOutputCharacterA
-0116 stub FillConsoleOutputCharacterW
-0117 stdcall FindAtomA(ptr) FindAtom32A
-0118 stdcall FindAtomW(ptr) FindAtom32W
-0119 stdcall FindClose(long) FindClose32
-0120 stub FindCloseChangeNotification
-0121 stub FindFirstChangeNotificationA
-0122 stub FindFirstChangeNotificationW
-0123 stdcall FindFirstFileA(ptr ptr) FindFirstFile32A
-0124 stdcall FindFirstFileW(ptr ptr) FindFirstFile32W
-0125 stub FindNextChangeNotification
-0126 stdcall FindNextFileA(long ptr) FindNextFile32A
-0127 stdcall FindNextFileW(long ptr) FindNextFile32W
-0128 stdcall FindResourceA(long ptr ptr) FindResource32A
-0129 stdcall FindResourceExA(long ptr ptr long) FindResourceEx32A
-0130 stdcall FindResourceExW(long ptr ptr long) FindResourceEx32W
-0131 stdcall FindResourceW(long ptr ptr) FindResource32W
-0132 stdcall FlushConsoleInputBuffer(long) FlushConsoleInputBuffer
-0133 stdcall FlushFileBuffers(long) FlushFileBuffers
-0134 stub FlushInstructionCache
-0135 stub FlushViewOfFile
-0136 stub FoldStringA
-0137 stub FoldStringW
-0138 stdcall FormatMessageA() WIN32_FormatMessage32A
-0139 stdcall FormatMessageW() WIN32_FormatMessage32W
-0140 stub FreeConsole
-0141 stdcall FreeEnvironmentStringsA(ptr) FreeEnvironmentStrings32A
-0142 stdcall FreeEnvironmentStringsW(ptr) FreeEnvironmentStrings32W
-0143 stdcall FreeLibrary(long) FreeLibrary32
-0144 stub FreeLibraryAndExitThread
-0145 stdcall FreeResource(long) FreeResource32
-0146 stub FreeVirtualBuffer
-0147 stub GenerateConsoleCtrlEvent
-0148    stdcall GetACP() GetACP
-0149 stdcall GetAtomNameA(long ptr long) GetAtomName32A
-0150 stdcall GetAtomNameW(long ptr long) GetAtomName32W
-0151 stub GetBinaryType
-0152 stub GetBinaryTypeA
-0153 stub GetBinaryTypeW
-0154 stdcall GetCPInfo(long ptr) GetCPInfo
-0155 stub GetCommConfig
-0156 stdcall GetCommMask(long ptr) GetCommMask
-0157 stub GetCommModemStatus
-0158 stub GetCommProperties
-0159 stdcall GetCommState(long ptr) GetCommState32
-0160 stdcall GetCommTimeouts(long ptr) GetCommTimeouts
-0161 stdcall GetCommandLineA() GetCommandLine32A
-0162 stdcall GetCommandLineW() GetCommandLine32W
-0163 stub GetCompressedFileSizeA
-0164 stub GetCompressedFileSizeW
-0165 stdcall GetComputerNameA(ptr ptr) GetComputerName32A
-0166 stdcall GetComputerNameW(ptr ptr) GetComputerName32W
-0167 stub GetConsoleAliasA
-0168 stub GetConsoleAliasExesA
-0169 stub GetConsoleAliasExesLengthA
-0170 stub GetConsoleAliasExesLengthW
-0171 stub GetConsoleAliasExesW
-0172 stub GetConsoleAliasW
-0173 stub GetConsoleAliasesA
-0174 stub GetConsoleAliasesLengthA
-0175 stub GetConsoleAliasesLengthW
-0176 stub GetConsoleAliasesW
-0177 stdcall GetConsoleCP() GetConsoleCP
-0178 stub GetConsoleCommandHistoryA
-0179 stub GetConsoleCommandHistoryLengthA
-0180 stub GetConsoleCommandHistoryLengthW
-0181 stub GetConsoleCommandHistoryW
-0182 stub GetConsoleCursorInfo
-0183 stub GetConsoleDisplayMode
-0184 stub GetConsoleFontInfo
-0185 stub GetConsoleFontSize
-0186 stub GetConsoleHardwareState
-0187 stub GetConsoleInputWaitHandle
-0188 stdcall GetConsoleMode(long ptr) GetConsoleMode
-0189 stdcall GetConsoleOutputCP() GetConsoleOutputCP
-0190 stdcall GetConsoleScreenBufferInfo(long ptr) GetConsoleScreenBufferInfo
-0191 stdcall GetConsoleTitleA(ptr long) GetConsoleTitle32A
-0192 stdcall GetConsoleTitleW(ptr long) GetConsoleTitle32W
-0193 stub GetCurrencyFormatA
-0194 stub GetCurrencyFormatW
-0195 stub GetCurrentConsoleFont
-0196 stdcall GetCurrentDirectoryA(long ptr) GetCurrentDirectory32A
-0197 stdcall GetCurrentDirectoryW(long ptr) GetCurrentDirectory32W
-0198 stdcall GetCurrentProcess() GetCurrentProcess
-0199 stdcall GetCurrentProcessId() GetCurrentProcessId
-0200 stdcall GetCurrentThread() GetCurrentThread
-0201 stdcall GetCurrentThreadId() GetCurrentThreadId
-0202 stub GetDateFormatA
-0203 stub GetDateFormatW
-0204 stub GetDefaultCommConfigA
-0205 stub GetDefaultCommConfigW
-0206 	stdcall GetDiskFreeSpaceA(ptr ptr ptr ptr ptr) GetDiskFreeSpace32A
-0207 	stdcall GetDiskFreeSpaceW(ptr ptr ptr ptr ptr) GetDiskFreeSpace32W
-0208 stdcall GetDriveTypeA(ptr) GetDriveType32A
-0209 stdcall GetDriveTypeW(ptr) GetDriveType32W
-0210 stdcall GetEnvironmentStrings() GetEnvironmentStrings32A
-0211 stdcall GetEnvironmentStringsA() GetEnvironmentStrings32A
-0212 stdcall GetEnvironmentStringsW() GetEnvironmentStrings32W
-0213 stdcall GetEnvironmentVariableA(ptr ptr long) GetEnvironmentVariable32A
-0214 stdcall GetEnvironmentVariableW(ptr ptr long) GetEnvironmentVariable32W
-0215 stub GetExitCodeProcess
-0216 stub GetExitCodeThread
-0217 stdcall GetFileAttributesA(ptr) GetFileAttributes32A
-0218 stdcall GetFileAttributesW(ptr) GetFileAttributes32W
-0219 stdcall GetFileInformationByHandle(long ptr) GetFileInformationByHandle
-0220 stdcall GetFileSize(long ptr) GetFileSize
-0221 stdcall GetFileTime(long ptr ptr ptr) GetFileTime
-0222 stdcall GetFileType(long) GetFileType
-0223 stdcall GetFullPathNameA(ptr long ptr ptr) GetFullPathName32A
-0224 stdcall GetFullPathNameW(ptr long ptr ptr) GetFullPathName32W
-0225 stub GetHandleInformation
-0226 stdcall GetLargestConsoleWindowSize(long) GetLargestConsoleWindowSize
-0227 stdcall GetLastError() GetLastError
-0228 stdcall GetLocalTime(ptr) GetLocalTime
-0229 stdcall GetLocaleInfoA(long long ptr long) GetLocaleInfoA
-0230 stdcall GetLocaleInfoW(long long ptr long) GetLocaleInfo32W
-0231 stdcall GetLogicalDriveStringsA(long ptr) GetLogicalDriveStrings32A
-0232 stdcall GetLogicalDriveStringsW(long ptr) GetLogicalDriveStrings32W
-0233 stdcall GetLogicalDrives() GetLogicalDrives
-0234 stub GetMailslotInfo
-0235 stdcall GetModuleFileNameA(long ptr long) GetModuleFileName32A
-0236 stdcall GetModuleFileNameW(long ptr long) GetModuleFileName32W
-0237 stdcall GetModuleHandleA(ptr) WIN32_GetModuleHandleA
-0238 stdcall GetModuleHandleW(ptr) WIN32_GetModuleHandleW
-0239 stub GetNamedPipeHandleStateA
-0240 stub GetNamedPipeHandleStateW
-0241 stub GetNamedPipeInfo
-0242 stub GetNextVDMCommand
-0243 stub GetNumberFormatA
-0244 stub GetNumberFormatW
-0245 stub GetNumberOfConsoleFonts
-0246 stub GetNumberOfConsoleInputEvents
-0247 stub GetNumberOfConsoleMouseButtons
-0248    stdcall GetOEMCP() GetOEMCP
-0249 stub GetOverlappedResult
-0250 stdcall GetPriorityClass(long) GetPriorityClass
-0251 stdcall GetPrivateProfileIntA(ptr ptr long ptr) GetPrivateProfileInt32A
-0252 stdcall GetPrivateProfileIntW(ptr ptr long ptr) GetPrivateProfileInt32W
-0253 stub GetPrivateProfileSectionA
-0254 stub GetPrivateProfileSectionW
-0255 stdcall GetPrivateProfileStringA(ptr ptr ptr ptr long ptr) GetPrivateProfileString32A
-0256 stdcall GetPrivateProfileStringW(ptr ptr ptr ptr long ptr) GetPrivateProfileString32W
-0257 stdcall GetProcAddress(long ptr) GetProcAddress32
-0258 stdcall GetProcessAffinityMask(long ptr ptr)	GetProcessAffinityMask
-0259 stdcall GetProcessHeap() GetProcessHeap
-0260 stub GetProcessHeaps
-0261 stub GetProcessShutdownParameters
-0262 stdcall GetProcessTimes(long ptr ptr ptr ptr) GetProcessTimes
-0263 stub GetProcessWorkingSetSize
-0264 stdcall GetProfileIntA(ptr ptr long) GetProfileInt32A
-0265 stdcall GetProfileIntW(ptr ptr long) GetProfileInt32W
-0266 stub GetProfileSectionA
-0267 stub GetProfileSectionW
-0268 stdcall GetProfileStringA(ptr ptr ptr ptr long) GetProfileString32A
-0269 stdcall GetProfileStringW(ptr ptr ptr ptr long) GetProfileString32W
-0270 stub GetQueuedCompletionStatus
-0271 stdcall GetShortPathNameA(ptr ptr long) GetShortPathName32A
-0272 stdcall GetShortPathNameW(ptr ptr long) GetShortPathName32W
-0273 stdcall GetStartupInfoA(ptr) GetStartupInfo32A
-0274 stdcall GetStartupInfoW(ptr) GetStartupInfo32W
-0275 stdcall GetStdHandle(long)	GetStdHandle
-0276 stdcall GetStringTypeA(long long ptr long ptr) GetStringType32A
-0277 stdcall GetStringTypeExA(long long ptr long ptr) GetStringTypeEx32A
-0278 stdcall GetStringTypeExW(long long ptr long ptr) GetStringTypeEx32W
-0279 stdcall GetStringTypeW(long ptr long ptr) GetStringType32W
-0280 stdcall GetSystemDefaultLCID() GetSystemDefaultLCID
-0281 stdcall GetSystemDefaultLangID() GetSystemDefaultLangID
-0282 stdcall GetSystemDirectoryA(ptr long) GetSystemDirectory32A
-0283 stdcall GetSystemDirectoryW(ptr long) GetSystemDirectory32W
-0284 stdcall GetSystemInfo(ptr) GetSystemInfo
-0285 	stdcall GetSystemTime(ptr) GetSystemTime
-0286 stub GetSystemTimeAdjustment
-0287 stub GetTapeParameters
-0288 stub GetTapePosition
-0289 stub GetTapeStatus
-0290 stdcall GetTempFileNameA(ptr ptr long ptr) GetTempFileName32A
-0291 stdcall GetTempFileNameW(ptr ptr long ptr) GetTempFileName32W
-0292 stdcall GetTempPathA(long ptr) GetTempPath32A
-0293 stdcall GetTempPathW(long ptr) GetTempPath32W
-0294 stdcall GetThreadContext(long ptr) GetThreadContext
-0295 stdcall GetThreadLocale() GetThreadLocale
-0296 stdcall GetThreadPriority(long) GetThreadPriority
-0297 stub GetThreadSelectorEntry
-0298 stub GetThreadTimes
-0299 stdcall GetTickCount() GetTickCount
-0300 stub GetTimeFormatA
-0301 stub GetTimeFormatW
-0302    stdcall GetTimeZoneInformation(ptr) GetTimeZoneInformation
-0303 stdcall GetUserDefaultLCID() GetUserDefaultLCID
-0304 stdcall GetUserDefaultLangID() GetUserDefaultLangID
-0305 stub GetVDMCurrentDirectories
-0306 stdcall GetVersion() GetVersion32
-0307 stdcall GetVersionExA(ptr) GetVersionEx32A
-0308 stdcall GetVersionExW(ptr) GetVersionEx32W
-0309 stdcall GetVolumeInformationA(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32A
-0310 stdcall GetVolumeInformationW(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32W
-0311 stdcall GetWindowsDirectoryA(ptr long) GetWindowsDirectory32A
-0312 stdcall GetWindowsDirectoryW(ptr long) GetWindowsDirectory32W
-0313 stdcall GlobalAddAtomA(ptr) GlobalAddAtom32A
-0314 stdcall GlobalAddAtomW(ptr) GlobalAddAtom32W
-0315 stdcall GlobalAlloc(long long) GlobalAlloc32
-0316 stdcall GlobalCompact(long) GlobalCompact32
-0317 stdcall GlobalDeleteAtom(long) GlobalDeleteAtom
-0318 stdcall GlobalFindAtomA(ptr) GlobalFindAtom32A
-0319 stdcall GlobalFindAtomW(ptr) GlobalFindAtom32W
-0320 stdcall GlobalFix(long) GlobalFix32
-0321 stdcall GlobalFlags(long) GlobalFlags32
-0322 stdcall GlobalFree(long) GlobalFree32
-0323 stdcall GlobalGetAtomNameA(long ptr long) GlobalGetAtomName32A
-0324 stdcall GlobalGetAtomNameW(long ptr long) GlobalGetAtomName32W
-0325 stdcall GlobalHandle(ptr) GlobalHandle32
-0326 stdcall GlobalLock(long) GlobalLock32
-0327 stdcall GlobalMemoryStatus(ptr) GlobalMemoryStatus
-0328 stdcall GlobalReAlloc(long long long) GlobalReAlloc32
-0329 stdcall GlobalSize(long) GlobalSize32
-0330 stdcall GlobalUnWire(long) GlobalUnWire32
-0331 stdcall GlobalUnfix(long) GlobalUnfix32
-0332 stdcall GlobalUnlock(long) GlobalUnlock32
-0333 stdcall GlobalWire(long) GlobalWire32
-0334 stdcall HeapAlloc(long long long) HeapAlloc
-0335 stdcall HeapCompact(long long) HeapCompact
-0336 stdcall HeapCreate(long long long)	HeapCreate
-0337 stdcall HeapDestroy(long) HeapDestroy
-0338 stdcall HeapFree(long long ptr) HeapFree
-0339 stdcall HeapLock(long) HeapLock
-0340 stdcall HeapReAlloc(long long ptr long) HeapReAlloc
-0341 stdcall HeapSize(long long ptr) HeapSize
-0342 stdcall HeapUnlock(long) HeapUnlock
-0343 stdcall HeapValidate(long long ptr) HeapValidate
-0344 stdcall HeapWalk(long ptr) HeapWalk
-0345 stub InitAtomTable
-0346 stdcall InitializeCriticalSection(ptr) InitializeCriticalSection
-0347 stdcall InterlockedDecrement(ptr) InterlockedDecrement
-0348 stdcall InterlockedExchange(ptr) InterlockedExchange
-0349 stdcall InterlockedIncrement(ptr) InterlockedIncrement
-0350 stub InvalidateConsoleDIBits
-0351 stdcall IsBadCodePtr(ptr long) IsBadCodePtr32
-0352 stdcall IsBadHugeReadPtr(ptr long) IsBadHugeReadPtr32
-0353 stdcall IsBadHugeWritePtr(ptr long) IsBadHugeWritePtr32
-0354 stdcall IsBadReadPtr(ptr long) IsBadReadPtr32
-0355 stdcall IsBadStringPtrA(ptr long) IsBadStringPtr32A
-0356 stdcall IsBadStringPtrW(ptr long) IsBadStringPtr32W
-0357 stdcall IsBadWritePtr(ptr long) IsBadWritePtr32
-0358 stdcall IsDBCSLeadByte(long) IsDBCSLeadByte32
-0359 stdcall IsDBCSLeadByteEx(long long) IsDBCSLeadByteEx
-0360 stdcall IsValidCodePage(long) IsValidCodePage
-0361 stdcall IsValidLocale(long long) IsValidLocale
-0362 stub LCMapStringA
-0363 stub LCMapStringW
-0364 stdcall LeaveCriticalSection(ptr)	LeaveCriticalSection
-0365 stdcall LoadLibraryA(ptr) LoadLibrary32A
-0366 stub LoadLibraryExA
-0367 stub LoadLibraryExW
-0368 stdcall LoadLibraryW(ptr) LoadLibrary32W
-0369 stub LoadModule
-0370 stdcall LoadResource(long long) LoadResource32
-0371 stdcall LocalAlloc(long long) LocalAlloc32
-0372 stdcall LocalCompact(long) LocalCompact32
-0373 stdcall LocalFileTimeToFileTime(ptr ptr) LocalFileTimeToFileTime
-0374 stdcall LocalFlags(long) LocalFlags32
-0375 stdcall LocalFree(long) LocalFree32
-0376 stdcall LocalHandle(ptr) LocalHandle32
-0377 stdcall LocalLock(long) LocalLock32
-0378 stdcall LocalReAlloc(long long long) LocalReAlloc32
-0379 stdcall LocalShrink(long long) LocalShrink32
-0380 stdcall LocalSize(long) LocalSize32
-0381 stdcall LocalUnlock(long) LocalUnlock32
-0382 stdcall LockFile(long long long long long) LockFile
-0383 stub LockFileEx
-0384 stdcall LockResource(long) LockResource32
-0385 stdcall MapViewOfFile(long long long long long) MapViewOfFile
-0386 stdcall MapViewOfFileEx(long long long long long ptr) MapViewOfFileEx
-0387 stdcall MoveFileA(ptr ptr) MoveFile32A
-0388 stub MoveFileExA
-0389 stub MoveFileExW
-0390 stdcall MoveFileW(ptr ptr) MoveFile32W
-0391 stdcall MulDiv(long long long) MulDiv32
-0392 stdcall MultiByteToWideChar(long long ptr long ptr long) MultiByteToWideChar
-0393 stub OpenConsoleW
-0394 stdcall OpenEventA(long long ptr) OpenEvent32A
-0395 stdcall OpenEventW(long long ptr) OpenEvent32W
-0396 stdcall OpenFile(ptr ptr long) OpenFile32
-0397 stdcall OpenFileMappingA(long long ptr) OpenFileMapping32A
-0398 stdcall OpenFileMappingW(long long ptr) OpenFileMapping32W
-0399 stdcall OpenMutexA(long long ptr) OpenMutex32A
-0400 stdcall OpenMutexW(long long ptr) OpenMutex32W
-0401 stub OpenProcess
-0402 stub OpenProfileUserMapping
-0403 stdcall OpenSemaphoreA(long long ptr) OpenSemaphore32A
-0404 stdcall OpenSemaphoreW(long long ptr) OpenSemaphore32W
-0405 stdcall OutputDebugStringA(ptr) OutputDebugString32A
-0406 stub OutputDebugStringW
-0407 stub PeekConsoleInputA
-0408 stub PeekConsoleInputW
-0409 stub PeekNamedPipe
-0410 stub PrepareTape
-0411 stub PulseEvent
-0412 stub PurgeComm
-0413 stdcall QueryDosDeviceA(ptr ptr long) QueryDosDevice32A
-0414 stdcall QueryDosDeviceW(ptr ptr long) QueryDosDevice32W
-0415 stdcall QueryPerformanceCounter(ptr) QueryPerformanceCounter
-0416 stub QueryPerformanceFrequency
-0417 stub QueryWin31IniFilesMappedToRegistry
-0418 register RaiseException(long long long ptr) RaiseException
-0419 stdcall ReadConsoleA(long ptr long ptr ptr) ReadConsole32A
-0420 stub ReadConsoleInputA
-0421 stub ReadConsoleInputW
-0422 stub ReadConsoleOutputA
-0423 stub ReadConsoleOutputAttribute
-0424 stub ReadConsoleOutputCharacterA
-0425 stub ReadConsoleOutputCharacterW
-0426 stub ReadConsoleOutputW
-0427 stdcall ReadConsoleW(long ptr long ptr ptr) ReadConsole32W
-0428 stdcall ReadFile(long ptr long ptr ptr) ReadFile
-0429 stub ReadFileEx
-0430 stub ReadProcessMemory
-0431 stub RegisterConsoleVDM
-0432 stub RegisterWaitForInputIdle
-0433 stub RegisterWowBaseHandlers
-0434 stub RegisterWowExec
-0435 	stdcall ReleaseMutex(long) ReleaseMutex
-0436 stdcall ReleaseSemaphore(long long ptr) ReleaseSemaphore
-0437 stdcall RemoveDirectoryA(ptr) RemoveDirectory32A
-0438 stdcall RemoveDirectoryW(ptr) RemoveDirectory32W
-0439 	stdcall ResetEvent(long) ResetEvent
-0440 stub ResumeThread
-0441 stdcall RtlFillMemory(ptr long long) RtlFillMemory
-0442 stdcall RtlMoveMemory(ptr ptr long) RtlMoveMemory
-0443 register RtlUnwind(ptr long ptr long) RtlUnwind
-0444 stdcall RtlZeroMemory(ptr long) RtlZeroMemory
-0445 stub ScrollConsoleScreenBufferA
-0446 stub ScrollConsoleScreenBufferW
-0447 stdcall SearchPathA(ptr ptr ptr long ptr ptr) SearchPath32A
-0448 stdcall SearchPathW(ptr ptr ptr long ptr ptr) SearchPath32W
-0449 stdcall SetCommBreak(long) SetCommBreak32
-0450 stub SetCommConfig
-0451 stdcall SetCommMask(long ptr) SetCommMask
-0452 stdcall SetCommState(long ptr) SetCommState32
-0453 stdcall SetCommTimeouts(long ptr) SetCommTimeouts
-0454 stub SetComputerNameA
-0455 stub SetComputerNameW
-0456 stub SetConsoleActiveScreenBuffer
-0457 stub SetConsoleCP
-0458 stub SetConsoleCommandHistoryMode
-0459 stdcall SetConsoleCtrlHandler(ptr long) SetConsoleCtrlHandler
-0460 stub SetConsoleCursor
-0461 stub SetConsoleCursorInfo
-0462 stub SetConsoleCursorPosition
-0463 stub SetConsoleDisplayMode
-0464 stub SetConsoleFont
-0465 stub SetConsoleHardwareState
-0466 stub SetConsoleKeyShortcuts
-0467 stub SetConsoleMaximumWindowSize
-0468 stub SetConsoleMenuClose
-0469 stdcall SetConsoleMode(long long) SetConsoleMode
-0470 stub SetConsoleNumberOfCommandsA
-0471 stub SetConsoleNumberOfCommandsW
-0472 stub SetConsoleOutputCP
-0473 stub SetConsolePalette
-0474 stub SetConsoleScreenBufferSize
-0475 stub SetConsoleTextAttribute
-0476 stdcall SetConsoleTitleA(ptr) SetConsoleTitle32A
-0477 stdcall SetConsoleTitleW(ptr) SetConsoleTitle32W
-0478 stub SetConsoleWindowInfo
-0479 stdcall SetCurrentDirectoryA(ptr) SetCurrentDirectory32A
-0480 stdcall SetCurrentDirectoryW(ptr) SetCurrentDirectory32W
-0481 stub SetDefaultCommConfigA
-0482 stub SetDefaultCommConfigW
-0483 stdcall SetEndOfFile(long) SetEndOfFile
-0484 stdcall SetEnvironmentVariableA(ptr ptr) SetEnvironmentVariable32A
-0485 stdcall SetEnvironmentVariableW(ptr ptr) SetEnvironmentVariable32W
-0486 stdcall SetErrorMode(long) SetErrorMode32
-0487 	stdcall	SetEvent(long) SetEvent
-0488 stdcall SetFileApisToANSI() SetFileApisToANSI
-0489 stdcall SetFileApisToOEM() SetFileApisToOEM
-0490 stdcall SetFileAttributesA(ptr long) SetFileAttributes32A
-0491 stdcall SetFileAttributesW(ptr long) SetFileAttributes32W
-0492 stdcall SetFilePointer(long long ptr long) SetFilePointer
-0493 stdcall SetFileTime(long ptr ptr ptr) SetFileTime
-0494 stdcall SetHandleCount(long) SetHandleCount32
-0495 stub SetHandleInformation
-0496 stub SetLastConsoleEventActive
-0497 stdcall SetLastError(long) SetLastError
-0498 stub SetLocalTime
-0499 stdcall SetLocaleInfoA(long long ptr) SetLocaleInfoA
-0500 stub SetLocaleInfoW
-0501 stub SetMailslotInfo
-0502 stub SetNamedPipeHandleState
-0503 stdcall SetPriorityClass(long long) SetPriorityClass
-0504 stub SetProcessShutdownParameters
-0505 stub SetProcessWorkingSetSize
-0506 stdcall SetStdHandle(long long) SetStdHandle
-0507 stdcall SetSystemTime(ptr) SetSystemTime
-0508 stub SetSystemTimeAdjustment
-0509 stub SetTapeParameters
-0510 stub SetTapePosition
-0511 stdcall SetThreadAffinityMask(long long)	SetThreadAffinityMask
-0512 stub SetThreadContext
-0513 stub SetThreadLocale
-0514 stdcall SetThreadPriority(long long) SetThreadPriority
-0515 stdcall SetTimeZoneInformation(ptr) SetTimeZoneInformation
-0516 stdcall SetUnhandledExceptionFilter(ptr) THUNK_SetUnhandledExceptionFilter
-0517 stub SetVDMCurrentDirectories
-0518 stub SetVolumeLabelA
-0519 stub SetVolumeLabelW
-0520 stub SetupComm
-0521 stub ShowConsoleCursor
-0522 stdcall SizeofResource(long long) SizeofResource32
-0523 	stdcall Sleep(long) Sleep
-0524 stub SleepEx
-0525 stub SuspendThread
-0526 stdcall SystemTimeToFileTime(ptr ptr) SystemTimeToFileTime
-0527 stub SystemTimeToTzSpecificLocalTime
-0528 stub TerminateProcess
-0529 stub TerminateThread
-0530 stdcall TlsAlloc()	TlsAlloc
-0531 stdcall TlsFree(long) TlsFree
-0532 stdcall TlsGetValue(long) TlsGetValue
-0533 stdcall TlsSetValue(long ptr) TlsSetValue
-0534 stub TransactNamedPipe
-0535 stdcall TransmitCommChar(long long) TransmitCommChar32
-0536 stub TrimVirtualBuffer
-0537 stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
-0538 stdcall UnlockFile(long long long long long) UnlockFile
-0539 stub UnlockFileEx
-0540 stdcall UnmapViewOfFile(ptr) UnmapViewOfFile
-0541 stub UpdateResourceA
-0542 stub UpdateResourceW
-0543 stub VDMConsoleOperation
-0544 stub VDMOperationStarted
-0545 stub VerLanguageNameA
-0546 stub VerLanguageNameW
-0547 stub VerifyConsoleIoHandle
-0548 stdcall VirtualAlloc(ptr long long long) VirtualAlloc
-0549 stub VirtualBufferExceptionHandler
-0550 stdcall VirtualFree(ptr long long) VirtualFree
-0551 stdcall VirtualLock(ptr long) VirtualLock
-0552 stdcall VirtualProtect(ptr long long ptr) VirtualProtect
-0553 stdcall VirtualProtectEx(long ptr long long ptr) VirtualProtectEx
-0554 stdcall VirtualQuery(ptr ptr long) VirtualQuery
-0555 stdcall VirtualQueryEx(long ptr ptr long) VirtualQueryEx
-0556 stdcall VirtualUnlock(ptr long) VirtualUnlock
-0557 stub WaitCommEvent
-0558 stub WaitForDebugEvent
-0559 stub WaitForMultipleObjects
-0560 stub WaitForMultipleObjectsEx
-0561 	stdcall WaitForSingleObject(long long) WaitForSingleObject
-0562 stub WaitForSingleObjectEx
-0563 stub WaitNamedPipeA
-0564 stub WaitNamedPipeW
-0565 stdcall WideCharToMultiByte(long long ptr long ptr long ptr ptr)	WideCharToMultiByte
-0566 stdcall WinExec(ptr long) WinExec32
-0567 stdcall WriteConsoleA(long ptr long ptr ptr) WriteConsole32A
-0568 stub WriteConsoleInputA
-0569 stub WriteConsoleInputVDMA
-0570 stub WriteConsoleInputVDMW
-0571 stub WriteConsoleInputW
-0572 stub WriteConsoleOutputA
-0573 stub WriteConsoleOutputAttribute
-0574 stub WriteConsoleOutputCharacterA
-0575 stub WriteConsoleOutputCharacterW
-0576 stub WriteConsoleOutputW
-0577 stdcall WriteConsoleW(long ptr long ptr ptr) WriteConsole32W
-0578 stdcall WriteFile(long ptr long ptr ptr) WriteFile
-0579 stub WriteFileEx
-0580 stub WritePrivateProfileSectionA
-0581 stub WritePrivateProfileSectionW
-0582 stdcall WritePrivateProfileStringA(ptr ptr ptr ptr) WritePrivateProfileString32A
-0583 stdcall WritePrivateProfileStringW(ptr ptr ptr ptr) WritePrivateProfileString32W
-0584 stub WriteProcessMemory
-0585 stub WriteProfileSectionA
-0586 stub WriteProfileSectionW
-0587 stdcall WriteProfileStringA(ptr ptr ptr) WriteProfileString32A
-0588 stdcall WriteProfileStringW(ptr ptr ptr) WriteProfileString32W
-0589 stub WriteTapemark
-0590 stdcall _hread(long ptr long) _hread32
-0591 stdcall _hwrite(long ptr long) _hwrite32
-0592 stdcall _lclose(long) _lclose32
-0593 stdcall _lcreat(ptr long) _lcreat32
-0594 stdcall _llseek(long long long) _llseek32
-0595 stdcall _lopen(ptr long) _lopen32
-0596 stdcall _lread(long ptr long) _lread32
-0597 stdcall _lwrite(long ptr long) _lwrite32
-0598 stdcall lstrcat(ptr ptr) lstrcat32A
-0599 stdcall lstrcatA(ptr ptr) lstrcat32A
-0600 stdcall lstrcatW(ptr ptr) lstrcat32W
-0601 stdcall lstrcmp(ptr ptr) lstrcmp32A
-0602 stdcall lstrcmpA(ptr ptr) lstrcmp32A
-0603 stdcall lstrcmpW(ptr ptr) lstrcmp32W
-0604 stdcall lstrcmpi(ptr ptr) lstrcmpi32A
-0605 stdcall lstrcmpiA(ptr ptr) lstrcmpi32A
-0606 stdcall lstrcmpiW(ptr ptr) lstrcmpi32W
-0607 stdcall lstrcpy(ptr ptr) lstrcpy32A
-0608 stdcall lstrcpyA(ptr ptr) lstrcpy32A
-0609 stdcall lstrcpyW(ptr ptr) lstrcpy32W
-0610 stdcall lstrcpyn(ptr ptr long) lstrcpyn32A
-0611 stdcall lstrcpynA(ptr ptr long) lstrcpyn32A
-0612 stdcall lstrcpynW(ptr ptr long) lstrcpyn32W
-0613 stdcall lstrlen(ptr) lstrlen32A
-0614 stdcall lstrlenA(ptr) lstrlen32A
-0615 stdcall lstrlenW(ptr) lstrlen32W
-#late additions
-0616 stub GetPrivateProfileSectionNamesA
-0617 stub GetPrivateProfileSectionNamesW
-0618 stub GetPrivateProfileStructA
-0619 stub GetPrivateProfileStructW
-0620 stub GetProcessVersion
-0621    stdcall GetSystemPowerStatus(ptr) GetSystemPowerStatus
-0622 stub GetSystemTimeAsFileTime
-0623 stub HeapCreateTagsW
-0624 stub HeapExtend
-0625 stub HeapQueryTagW
-0626 stub HeapSummary
-0627 stub HeapUsage
-0628 stub IsDebuggerPresent
-0629 stub PostQueuedCompletionStatus
-0630    stdcall SetSystemPowerState(long long) SetSystemPowerState
-0631 stub WritePrivateProfileStructA
-0632 stub WritePrivateProfileStructW
-0633 stdcall MakeCriticalSectionGlobal(ptr) MakeCriticalSectionGlobal
-#extra late additions
-0634 stdcall ThunkConnect32(ptr ptr ptr ptr ptr ptr) ThunkConnect32
-0636 stub SUnMapLS
-0637 stub SMapLS
-0638 stdcall ReinitializeCriticalSection(ptr) ReinitializeCriticalSection
-0639 stub FT_Thunk
-0640 stub FT_Exit20
-0641 stub SMapLS_IP_EBP_12
-0642 stub SUnMapLS_IP_EBP_12
-0643 stub MapSLFix
-0644 stub UnMapSLFixArray
-0645 stub dprintf
-0646 stub CreateToolhelp32Snapshot
-0647 stub Module32First
-0648 stub Module32Next
-0649 stub Process32First
-0650 stub Process32Next
-0651 stub Thread32First
-0652 stub Thread32Next
-0653 stub RegisterServiceProcess
-0654 stub QueueUserAPC
-0655 stub ConvertToGlobalHandle
-0656 stub SMapLS_IP_EBP_8
-0657 stub SMapLS_IP_EBP_16
-0658 stub SMapLS_IP_EBP_20
-0659 stub SUnMapLS_IP_EBP_8
-0660 stub SUnMapLS_IP_EBP_16
-0661 stub SUnMapLS_IP_EBP_20
-0662 stdcall MapSL(long) MapSL
-0663 stub K32Thk1632Epilog
-0664 stub K32Thk1632Prolog
-0665 stub GetProcessFlags
-0666 stub SMapLS_IP_EBP_24
-0667 stub SUnMapLS_IP_EBP_24
-0668 stub SMapLS_IP_EBP_32
-0669 stub SUnMapLS_IP_EBP_32
-0670 stub SMapLS_IP_EBP_28
-0671 stub SUnMapLS_IP_EBP_28
-0672 stub SMapLS_IP_EBP_40
-0673 stub SUnMapLS_IP_EBP_40
-0674 stub FreeSLCallback
-0675 stub AllocSLCallback
-0676 stub Callback28
-0677 stub UninitializeCriticalSection
-0678 stub FT_Exit4
-0679 stdcall MapLS(ptr) MapLS
-0680 stdcall UnMapLS(long) UnMapLS
-0681 stub OpenVxDHandle
-0682 stub FT_Exit12
+# Functions exported by the Win95 kernel32.dll 
+# (these need to have these exact ordinals, for some win95 dlls 
+#  import kernel32.dll by ordinal)
+# the base is NOT included in these ordinals
+
+# undocumented ordinal only calls (names taken from k32exp.h by Andrew
+# Schulman.
+0  stub VxDCall0
+1  stub VxDCall0
+2  stub VxDCall0
+3  stub VxDCall0
+4  stub VxDCall0
+5  stub VxDCall0
+6  stub VxDCall0
+7  stub VxDCall0
+8  stub VxDCall0
+ 
+9  stub _KERNEL32_stringconv1 #ansi2oem or reverse?
+ 
+17  stdcall _KERNEL32_18(long long) _KERNEL32_18
+18  stub _KERNEL32_getheapsegment
+ 
+30  stub _KERNEL32_31
+ 
+34  stub LoadLibrary16
+35  stub FreeLibrary16
+36  stub GetProcAddress16
+ 
+39  stub _KERNEL32_40
+
+42  return _KERNEL32_43 20 0
+44  stub _KERNEL32_45
+ 
+49  stdcall AddAtomA(ptr) AddAtom32A
+
+51  register _KERNEL32_52(long) _KERNEL32_52
+
+# WOW calls
+53  stub WOWCallback16
+54  stub WOWCallback16Ex
+55  stub WOWGetVDMPointer
+56  stub WOWHandle32
+57  stub WOWHandle16
+58  stub WOWGlobalAlloc16
+59  stub WOWGlobalLock16
+60  stub WOWGlobalUnlock16
+61  stub WOWGlobalFree16
+62  stub WOWGlobalAllocLock16
+63  stub WOWGlobalUnlockFree16
+64  stub WOWGlobalLockSize16
+65  stub WOWYield16
+66  stub WOWDirectedYield16
+67  stub WOWGetVDMPointerFix
+68  stub WOWGetVDMPointerUnfix
+69  stub WOW32_1
+ 
+71  stub RtlLargeIntegerAdd
+72  stub RtlEnlargedIntegerMultiply
+73  stub RtlEnlargedUnsignedMultiply
+74  stub RtlEnlargedUnsignedDivide
+75  stub RtlExtendedLargeIntegerDivide
+76  stub RtlExtendedMagicDivide
+77  stub RtlExtendedIntegerMultiply
+78  stub RtlLargeIntegerShiftLeft
+79  stub RtlLargeIntegerShiftRight
+80  stub RtlLargeIntegerArithmeticShift
+81  stub RtlLargeIntegerNegate
+82  stub RtlLargeIntegerSubtract
+83  stub RtlConvertLongToLargeInteger
+84  stub RtlConvertUlongToLargeInteger
+
+86  stub _KERNEL32_87
+87  stub _KERNEL32_88
+
+90  stub _KERNEL32_90
+91  stub _KERNEL32_91
+92  stdcall GETPWIN16LOCK(ptr) GetPWinLock
+96  stub ENTERSYSLEVEL
+97  stub LEAVESYSLEVEL
+98  stub _KERNEL32_98
+99  stub _KERNEL32_99
+100 stub _KERNEL32_100
+
+
+101   stdcall AddAtomW(ptr) AddAtom32W
+102   stub AllocConsole
+103   stub AllocLSCallback
+104   stub AllocSLCallback
+105   stdcall AreFileApisANSI() AreFileApisANSI
+106   stub BackupRead
+107   stub BackupSeek
+108   stub BackupWrite
+109   stdcall Beep(long long) Beep
+110   stub BeginUpdateResourceA
+111   stub BeginUpdateResourceW
+112   stdcall BuildCommDCBA(ptr ptr) BuildCommDCB32A
+113   stdcall BuildCommDCBAndTimeoutsA(ptr ptr ptr) BuildCommDCBAndTimeouts32A
+114   stdcall BuildCommDCBAndTimeoutsW(ptr ptr ptr) BuildCommDCBAndTimeouts32W
+115   stdcall BuildCommDCBW(ptr ptr) BuildCommDCB32W
+116   stub CallNamedPipeA
+117   stub CallNamedPipeW
+118   stub Callback12
+119   stub Callback16
+120   stub Callback20
+121   stub Callback24
+122   stub Callback28
+123   stub Callback32
+124   stub Callback36
+125   stub Callback40
+126   stub Callback44
+127   stub Callback48
+128   stub Callback4
+129   stub Callback52
+130   stub Callback56
+131   stub Callback60
+132   stub Callback64
+133   stub Callback8
+134   stdcall ClearCommBreak(long) ClearCommBreak32
+135   stdcall ClearCommError(long ptr ptr) ClearCommError
+136   stdcall CloseHandle(long) CloseHandle
+137   stub CloseProfileUserMapping
+138   stub CloseSystemHandle
+139   stub CommConfigDialogA
+140   stub CommConfigDialogW
+141   stdcall CompareFileTime(ptr ptr) CompareFileTime
+142   stdcall CompareStringA(long long ptr long ptr long) CompareString32A
+143   stdcall CompareStringW(long long ptr long ptr long) CompareString32W
+144   stub ConnectNamedPipe
+145   stdcall ContinueDebugEvent(long long long) ContinueDebugEvent
+146   stub ConvertDefaultLocale
+147   stub ConvertToGlobalHandle
+148   stdcall CopyFileA(ptr ptr long) CopyFile32A
+149   stdcall CopyFileW(ptr ptr long) CopyFile32W
+150   stub CreateConsoleScreenBuffer
+151   stdcall CreateDirectoryA(ptr ptr) CreateDirectory32A
+152   stdcall CreateDirectoryExA(ptr ptr ptr) CreateDirectoryEx32A
+153   stdcall CreateDirectoryExW(ptr ptr ptr) CreateDirectoryEx32W
+154   stdcall CreateDirectoryW(ptr ptr) CreateDirectory32W
+155   stdcall CreateEventA(ptr long long ptr) CreateEvent32A
+156   stdcall CreateEventW(ptr long long ptr) CreateEvent32W
+157   stdcall CreateFileA(ptr long long ptr long long long) CreateFile32A
+158   stdcall CreateFileMappingA(long ptr long long long ptr) CreateFileMapping32A
+159   stdcall CreateFileMappingW(long ptr long long long ptr) CreateFileMapping32W
+160   stdcall CreateFileW(ptr long long ptr long long long) CreateFile32W
+161   stub CreateIoCompletionPort
+162   stub CreateKernelThread
+163   stub CreateMailslotA
+164   stub CreateMailslotW
+165   stdcall CreateMutexA(ptr long ptr) CreateMutex32A
+166   stdcall CreateMutexW(ptr long ptr) CreateMutex32W
+167   stub CreateNamedPipeA
+168   stub CreateNamedPipeW
+169   stub CreatePipe
+170   stdcall CreateProcessA(ptr ptr ptr ptr long long ptr ptr ptr ptr) CreateProcess32A
+171   stub CreateProcessW
+172   stub CreateRemoteThread
+173   stdcall CreateSemaphoreA(ptr long long ptr) CreateSemaphore32A
+174   stdcall CreateSemaphoreW(ptr long long ptr) CreateSemaphore32W
+175   stub CreateSocketHandle
+176   stub CreateTapePartition
+177   stdcall CreateThread(ptr long ptr long long ptr) CreateThread
+178   stub CreateToolhelp32Snapshot
+179   stub DebugActiveProcess
+180   stdcall DebugBreak() DebugBreak32
+181   stub DefineDosDeviceA
+182   stub DefineDosDeviceW
+183   stdcall DeleteAtom(long) DeleteAtom32
+184   stdcall DeleteCriticalSection(ptr)	DeleteCriticalSection
+185   stdcall DeleteFileA(ptr) DeleteFile32A
+186   stdcall DeleteFileW(ptr) DeleteFile32W
+187   stub DeviceIoControl
+188   stdcall DisableThreadLibraryCalls(long) DisableThreadLibraryCalls
+189   stub DisconnectNamedPipe
+190   stdcall DosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime
+191   stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle
+192   stub EndUpdateResourceA
+193   stub EndUpdateResourceW
+194   stdcall EnterCriticalSection(ptr)	EnterCriticalSection
+195   stub EnumCalendarInfoA
+196   stub EnumCalendarInfoW
+197   stub EnumDateFormatsA
+198   stub EnumDateFormatsW
+199   stdcall EnumResourceLanguagesA(long ptr ptr ptr long) THUNK_EnumResourceLanguages32A
+200   stdcall EnumResourceLanguagesW(long ptr ptr ptr long) THUNK_EnumResourceLanguages32W
+201   stdcall EnumResourceNamesA(long ptr ptr long) THUNK_EnumResourceNames32A
+202   stdcall EnumResourceNamesW(long ptr ptr long) THUNK_EnumResourceNames32W
+203   stdcall EnumResourceTypesA(long ptr long) THUNK_EnumResourceTypes32A
+204   stdcall EnumResourceTypesW(long ptr long) THUNK_EnumResourceTypes32W
+205   stdcall EnumSystemCodePagesA(ptr long) THUNK_EnumSystemCodePages32A
+206   stdcall EnumSystemCodePagesW(ptr long) THUNK_EnumSystemCodePages32W
+207   stdcall EnumSystemLocalesA(ptr long) THUNK_EnumSystemLocales32A
+208   stdcall EnumSystemLocalesW(ptr long) THUNK_EnumSystemLocales32W
+209   stub EnumTimeFormatsA
+210   stub EnumTimeFormatsW
+211   stub EraseTape
+212   stdcall EscapeCommFunction(long long) EscapeCommFunction32
+213   stdcall ExitProcess(long) ExitProcess
+214   stub ExitThread
+215   stdcall ExpandEnvironmentStringsA(ptr ptr long) ExpandEnvironmentStrings32A
+216   stdcall ExpandEnvironmentStringsW(ptr ptr long) ExpandEnvironmentStrings32W
+217   stub FT_Exit0
+218   stub FT_Exit12
+219   stub FT_Exit16
+220   stub FT_Exit20
+221   stub FT_Exit24
+222   stub FT_Exit28
+223   stub FT_Exit32
+224   stub FT_Exit36
+226   stub FT_Exit40
+227   stub FT_Exit44
+228   stub FT_Exit48
+225   stub FT_Exit4
+229   stub FT_Exit52
+230   stub FT_Exit56
+231   stub FT_Exit8
+232   stub FT_Prolog
+233   stub FT_Thunk
+234   stdcall FatalAppExitA(long ptr) FatalAppExit32A
+235   stdcall FatalAppExitW(long ptr) FatalAppExit32W
+236   stub FatalExit
+237   stdcall FileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime
+238   stdcall FileTimeToLocalFileTime(ptr ptr) FileTimeToLocalFileTime
+239   stdcall FileTimeToSystemTime(ptr ptr) FileTimeToSystemTime
+240   stub FillConsoleOutputAttribute
+241   stub FillConsoleOutputCharacterA
+242   stub FillConsoleOutputCharacterW
+243   stdcall FindAtomA(ptr) FindAtom32A
+244   stdcall FindAtomW(ptr) FindAtom32W
+246   stub FindCloseChangeNotification
+245   stdcall FindClose(long) FindClose32
+247   stub FindFirstChangeNotificationA
+248   stub FindFirstChangeNotificationW
+249   stdcall FindFirstFileA(ptr ptr) FindFirstFile32A
+250   stdcall FindFirstFileW(ptr ptr) FindFirstFile32W
+251   stub FindNextChangeNotification
+252   stdcall FindNextFileA(long ptr) FindNextFile32A
+253   stdcall FindNextFileW(long ptr) FindNextFile32W
+254   stdcall FindResourceA(long ptr ptr) FindResource32A
+255   stdcall FindResourceExA(long ptr ptr long) FindResourceEx32A
+256   stdcall FindResourceExW(long ptr ptr long) FindResourceEx32W
+257   stdcall FindResourceW(long ptr ptr) FindResource32W
+258   stdcall FlushConsoleInputBuffer(long) FlushConsoleInputBuffer
+259   stdcall FlushFileBuffers(long) FlushFileBuffers
+260   stub FlushInstructionCache
+261   stub FlushViewOfFile
+262   stub FoldStringA
+263   stub FoldStringW
+264   stdcall FormatMessageA() WIN32_FormatMessage32A
+265   stdcall FormatMessageW() WIN32_FormatMessage32W
+266   stub FreeConsole
+267   stdcall FreeEnvironmentStringsA(ptr) FreeEnvironmentStrings32A
+268   stdcall FreeEnvironmentStringsW(ptr) FreeEnvironmentStrings32W
+269   stub FreeLSCallback
+271   stub FreeLibraryAndExitThread
+270   stdcall FreeLibrary(long) FreeLibrary32
+272   stdcall FreeResource(long) FreeResource32
+273   stub FreeSLCallback
+274   stub GenerateConsoleCtrlEvent
+275   stdcall GetACP() GetACP
+276   stdcall GetAtomNameA(long ptr long) GetAtomName32A
+277   stdcall GetAtomNameW(long ptr long) GetAtomName32W
+278   stub GetBinaryType
+279   stub GetBinaryTypeA
+280   stub GetBinaryTypeW
+281   stdcall GetCPInfo(long ptr) GetCPInfo
+282   stub GetCommConfig
+283   stdcall GetCommMask(long ptr) GetCommMask
+284   stub GetCommModemStatus
+285   stub GetCommProperties
+286   stdcall GetCommState(long ptr) GetCommState32
+287   stdcall GetCommTimeouts(long ptr) GetCommTimeouts
+288   stdcall GetCommandLineA() GetCommandLine32A
+289   stdcall GetCommandLineW() GetCommandLine32W
+290   stub GetCompressedFileSizeA
+291   stub GetCompressedFileSizeW
+292   stdcall GetComputerNameA(ptr ptr) GetComputerName32A
+293   stdcall GetComputerNameW(ptr ptr) GetComputerName32W
+294   stdcall GetConsoleCP() GetConsoleCP
+296   stdcall GetConsoleMode(long ptr) GetConsoleMode
+297   stdcall GetConsoleOutputCP() GetConsoleOutputCP
+298   stdcall GetConsoleScreenBufferInfo(long ptr) GetConsoleScreenBufferInfo
+299   stdcall GetConsoleTitleA(ptr long) GetConsoleTitle32A
+300   stdcall GetConsoleTitleW(ptr long) GetConsoleTitle32W
+301   stub GetCurrencyFormatA
+302   stub GetCurrencyFormatW
+303   stdcall GetCurrentDirectoryA(long ptr) GetCurrentDirectory32A
+304   stdcall GetCurrentDirectoryW(long ptr) GetCurrentDirectory32W
+305   stdcall GetCurrentProcess() GetCurrentProcess
+306   stdcall GetCurrentProcessId() GetCurrentProcessId
+307   stdcall GetCurrentThread() GetCurrentThread
+308   stdcall GetCurrentThreadId() GetCurrentThreadId
+309   stub GetDateFormatA
+310   stub GetDateFormatW
+311   stub GetDaylightFlag
+312   stub GetDefaultCommConfigA
+313   stub GetDefaultCommConfigW
+314   stdcall GetDiskFreeSpaceA(ptr ptr ptr ptr ptr) GetDiskFreeSpace32A
+315   stdcall GetDiskFreeSpaceW(ptr ptr ptr ptr ptr) GetDiskFreeSpace32W
+316   stdcall GetDriveTypeA(ptr) GetDriveType32A
+317   stdcall GetDriveTypeW(ptr) GetDriveType32W
+319   stdcall GetEnvironmentStringsA() GetEnvironmentStrings32A
+320   stdcall GetEnvironmentStringsW() GetEnvironmentStrings32W
+318   stdcall GetEnvironmentStrings() GetEnvironmentStrings32A
+321   stdcall GetEnvironmentVariableA(ptr ptr long) GetEnvironmentVariable32A
+322   stdcall GetEnvironmentVariableW(ptr ptr long) GetEnvironmentVariable32W
+323   stub GetErrorMode
+324   stub GetExitCodeProcess
+325   stub GetExitCodeThread
+326   stdcall GetFileAttributesA(ptr) GetFileAttributes32A
+327   stdcall GetFileAttributesW(ptr) GetFileAttributes32W
+328   stdcall GetFileInformationByHandle(long ptr) GetFileInformationByHandle
+329   stdcall GetFileSize(long ptr) GetFileSize
+330   stdcall GetFileTime(long ptr ptr ptr) GetFileTime
+331   stdcall GetFileType(long) GetFileType
+332   stdcall GetFullPathNameA(ptr long ptr ptr) GetFullPathName32A
+333   stdcall GetFullPathNameW(ptr long ptr ptr) GetFullPathName32W
+334   stub GetHandleContext
+335   stub GetHandleInformation
+336   stub GetLSCallbackTarget
+337   stub GetLSCallbackTemplate
+338   stdcall GetLargestConsoleWindowSize(long) GetLargestConsoleWindowSize
+339   stdcall GetLastError() GetLastError
+340   stdcall GetLocalTime(ptr) GetLocalTime
+341   stdcall GetLocaleInfoA(long long ptr long) GetLocaleInfoA
+342   stdcall GetLocaleInfoW(long long ptr long) GetLocaleInfo32W
+343   stdcall GetLogicalDriveStringsA(long ptr) GetLogicalDriveStrings32A
+344   stdcall GetLogicalDriveStringsW(long ptr) GetLogicalDriveStrings32W
+345   stdcall GetLogicalDrives() GetLogicalDrives
+346   stub GetMailslotInfo
+347   stdcall GetModuleFileNameA(long ptr long) GetModuleFileName32A
+348   stdcall GetModuleFileNameW(long ptr long) GetModuleFileName32W
+349   stdcall GetModuleHandleA(ptr) WIN32_GetModuleHandleA
+350   stdcall GetModuleHandleW(ptr) WIN32_GetModuleHandleW
+351   stub GetNamedPipeHandleStateA
+352   stub GetNamedPipeHandleStateW
+353   stub GetNamedPipeInfo
+354   stub GetNumberFormatA
+355   stub GetNumberFormatW
+356   stdcall GetNumberOfConsoleInputEvents(long ptr) GetNumberOfConsoleInputEvents
+357   stub GetNumberOfConsoleMouseButtons
+358   stdcall GetOEMCP() GetOEMCP
+359   stub GetOverlappedResult
+360   stdcall GetPriorityClass(long) GetPriorityClass
+361   stdcall GetPrivateProfileIntA(ptr ptr long ptr) GetPrivateProfileInt32A
+362   stdcall GetPrivateProfileIntW(ptr ptr long ptr) GetPrivateProfileInt32W
+363   stub GetPrivateProfileSectionA
+364   stub GetPrivateProfileSectionNamesA
+365   stub GetPrivateProfileSectionNamesW
+366   stub GetPrivateProfileSectionW
+367   stdcall GetPrivateProfileStringA(ptr ptr ptr ptr long ptr) GetPrivateProfileString32A
+368   stdcall GetPrivateProfileStringW(ptr ptr ptr ptr long ptr) GetPrivateProfileString32W
+369   stub GetPrivateProfileStructA
+370   stub GetPrivateProfileStructW
+371   stdcall GetProcAddress(long ptr) GetProcAddress32
+372   stdcall GetProcessAffinityMask(long ptr ptr)	GetProcessAffinityMask
+373   stub GetProcessFlags
+374   stdcall GetProcessHeap() GetProcessHeap
+375   stub GetProcessHeaps
+376   stub GetProcessShutdownParameters
+377   stdcall GetProcessTimes(long ptr ptr ptr ptr) GetProcessTimes
+378   stdcall GetProcessVersion(long) GetProcessVersion
+379   stub GetProcessWorkingSetSize
+380   stub GetProductName
+381   stdcall GetProfileIntA(ptr ptr long) GetProfileInt32A
+382   stdcall GetProfileIntW(ptr ptr long) GetProfileInt32W
+383   stub GetProfileSectionA
+384   stub GetProfileSectionW
+385   stdcall GetProfileStringA(ptr ptr ptr ptr long) GetProfileString32A
+386   stdcall GetProfileStringW(ptr ptr ptr ptr long) GetProfileString32W
+387   stub GetQueuedCompletionStatus
+388   stub GetSLCallbackTarget
+389   stub GetSLCallbackTemplate
+390   stdcall GetShortPathNameA(ptr ptr long) GetShortPathName32A
+391   stdcall GetShortPathNameW(ptr ptr long) GetShortPathName32W
+392   stdcall GetStartupInfoA(ptr) GetStartupInfo32A
+393   stdcall GetStartupInfoW(ptr) GetStartupInfo32W
+394   stdcall GetStdHandle(long)	GetStdHandle
+395   stdcall GetStringTypeA(long long ptr long ptr) GetStringType32A
+396   stdcall GetStringTypeExA(long long ptr long ptr) GetStringTypeEx32A
+397   stdcall GetStringTypeExW(long long ptr long ptr) GetStringTypeEx32W
+398   stdcall GetStringTypeW(long ptr long ptr) GetStringType32W
+399   stdcall GetSystemDefaultLCID() GetSystemDefaultLCID
+400   stdcall GetSystemDefaultLangID() GetSystemDefaultLangID
+401   stdcall GetSystemDirectoryA(ptr long) GetSystemDirectory32A
+402   stdcall GetSystemDirectoryW(ptr long) GetSystemDirectory32W
+403   stdcall GetSystemInfo(ptr) GetSystemInfo
+404   stdcall GetSystemPowerStatus(ptr) GetSystemPowerStatus
+405   stdcall GetSystemTime(ptr) GetSystemTime
+406   stub GetSystemTimeAdjustment
+407   stub GetSystemTimeAsFileTime
+408   stub GetTapeParameters
+409   stub GetTapePosition
+410   stub GetTapeStatus
+411   stdcall GetTempFileNameA(ptr ptr long ptr) GetTempFileName32A
+412   stdcall GetTempFileNameW(ptr ptr long ptr) GetTempFileName32W
+413   stdcall GetTempPathA(long ptr) GetTempPath32A
+414   stdcall GetTempPathW(long ptr) GetTempPath32W
+415   stdcall GetThreadContext(long ptr) GetThreadContext
+416   stdcall GetThreadLocale() GetThreadLocale
+417   stdcall GetThreadPriority(long) GetThreadPriority
+418   stub GetThreadSelectorEntry
+419   stub GetThreadTimes
+420   stdcall GetTickCount() GetTickCount
+421   stub GetTimeFormatA
+422   stub GetTimeFormatW
+423   stdcall GetTimeZoneInformation(ptr) GetTimeZoneInformation
+424   stdcall GetUserDefaultLCID() GetUserDefaultLCID
+425   stdcall GetUserDefaultLangID() GetUserDefaultLangID
+426   stdcall GetVersion() GetVersion32
+427   stdcall GetVersionExA(ptr) GetVersionEx32A
+428   stdcall GetVersionExW(ptr) GetVersionEx32W
+429   stdcall GetVolumeInformationA(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32A
+430   stdcall GetVolumeInformationW(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32W
+431   stdcall GetWindowsDirectoryA(ptr long) GetWindowsDirectory32A
+432   stdcall GetWindowsDirectoryW(ptr long) GetWindowsDirectory32W
+433   stdcall GlobalAddAtomA(ptr) GlobalAddAtom32A
+434   stdcall GlobalAddAtomW(ptr) GlobalAddAtom32W
+435   stdcall GlobalAlloc(long long) GlobalAlloc32
+436   stdcall GlobalCompact(long) GlobalCompact32
+437   stdcall GlobalDeleteAtom(long) GlobalDeleteAtom
+438   stdcall GlobalFindAtomA(ptr) GlobalFindAtom32A
+439   stdcall GlobalFindAtomW(ptr) GlobalFindAtom32W
+440   stdcall GlobalFix(long) GlobalFix32
+441   stdcall GlobalFlags(long) GlobalFlags32
+442   stdcall GlobalFree(long) GlobalFree32
+443   stdcall GlobalGetAtomNameA(long ptr long) GlobalGetAtomName32A
+444   stdcall GlobalGetAtomNameW(long ptr long) GlobalGetAtomName32W
+445   stdcall GlobalHandle(ptr) GlobalHandle32
+446   stdcall GlobalLock(long) GlobalLock32
+447   stdcall GlobalMemoryStatus(ptr) GlobalMemoryStatus
+448   stdcall GlobalReAlloc(long long long) GlobalReAlloc32
+449   stdcall GlobalSize(long) GlobalSize32
+450   stdcall GlobalUnWire(long) GlobalUnWire32
+451   stdcall GlobalUnfix(long) GlobalUnfix32
+452   stdcall GlobalUnlock(long) GlobalUnlock32
+453   stdcall GlobalWire(long) GlobalWire32
+454   stub Heap32First
+455   stub Heap32ListFirst
+456   stub Heap32ListNext
+457   stub Heap32Next
+458   stdcall HeapAlloc(long long long) HeapAlloc
+459   stdcall HeapCompact(long long) HeapCompact
+460   stdcall HeapCreate(long long long)	HeapCreate
+461   stdcall HeapDestroy(long) HeapDestroy
+462   stdcall HeapFree(long long ptr) HeapFree
+463   stdcall HeapLock(long) HeapLock
+464   stdcall HeapReAlloc(long long ptr long) HeapReAlloc
+466   stdcall HeapSize(long long ptr) HeapSize
+467   stdcall HeapUnlock(long) HeapUnlock
+468   stdcall HeapValidate(long long ptr) HeapValidate
+469   stdcall HeapWalk(long ptr) HeapWalk
+470   stub InitAtomTable
+471   stdcall InitializeCriticalSection(ptr) InitializeCriticalSection
+472   stdcall InterlockedDecrement(ptr) InterlockedDecrement
+473   stdcall InterlockedExchange(ptr) InterlockedExchange
+474   stdcall InterlockedIncrement(ptr) InterlockedIncrement
+475   stub InvalidateNLSCache
+476   stdcall IsBadCodePtr(ptr long) IsBadCodePtr32
+477   stdcall IsBadHugeReadPtr(ptr long) IsBadHugeReadPtr32
+478   stdcall IsBadHugeWritePtr(ptr long) IsBadHugeWritePtr32
+479   stdcall IsBadReadPtr(ptr long) IsBadReadPtr32
+480   stdcall IsBadStringPtrA(ptr long) IsBadStringPtr32A
+481   stdcall IsBadStringPtrW(ptr long) IsBadStringPtr32W
+482   stdcall IsBadWritePtr(ptr long) IsBadWritePtr32
+483   stdcall IsDBCSLeadByte(long) IsDBCSLeadByte32
+484   stdcall IsDBCSLeadByteEx(long long) IsDBCSLeadByteEx
+485   stub IsLSCallback
+486   stub IsSLCallback
+487   stdcall IsValidCodePage(long) IsValidCodePage
+488   stdcall IsValidLocale(long long) IsValidLocale
+489   stub K32Thk1632Epilog
+490   stub K32Thk1632Prolog
+491   stub LCMapStringA
+492   stub LCMapStringW
+493   stdcall LeaveCriticalSection(ptr)	LeaveCriticalSection
+494   stdcall LoadLibraryA(ptr) LoadLibrary32A
+495   stub LoadLibraryExA
+496   stub LoadLibraryExW
+497   stdcall LoadLibraryW(ptr) LoadLibrary32W
+498   stub LoadModule
+499   stdcall LoadResource(long long) LoadResource32
+500   stdcall LocalAlloc(long long) LocalAlloc32
+501   stdcall LocalCompact(long) LocalCompact32
+502   stdcall LocalFileTimeToFileTime(ptr ptr) LocalFileTimeToFileTime
+503   stdcall LocalFlags(long) LocalFlags32
+504   stdcall LocalFree(long) LocalFree32
+505   stdcall LocalHandle(ptr) LocalHandle32
+506   stdcall LocalLock(long) LocalLock32
+507   stdcall LocalReAlloc(long long long) LocalReAlloc32
+508   stdcall LocalShrink(long long) LocalShrink32
+509   stdcall LocalSize(long) LocalSize32
+510   stdcall LocalUnlock(long) LocalUnlock32
+511   stdcall LockFile(long long long long long) LockFile
+512   stub LockFileEx
+513   stdcall LockResource(long) LockResource32
+514   stdcall MakeCriticalSectionGlobal(ptr) MakeCriticalSectionGlobal
+515   stub MapHInstLS
+516   stub MapHInstLS_PN
+517   stub MapHInstSL
+518   stub MapHInstSL_PN
+519   stub MapHModuleLS
+520   stub MapHModuleSL
+521   stdcall MapLS(ptr) MapLS
+643   stdcall MapSL(long) MapSL
+523   stub MapSLFix
+522   stub MapSL
+524   stdcall MapViewOfFile(long long long long long) MapViewOfFile
+525   stdcall MapViewOfFileEx(long long long long long ptr) MapViewOfFileEx
+526   stub Module32First
+527   stub Module32Next
+528   stdcall MoveFileA(ptr ptr) MoveFile32A
+529   stub MoveFileExA
+530   stub MoveFileExW
+531   stdcall MoveFileW(ptr ptr) MoveFile32W
+532   stdcall MulDiv(long long long) MulDiv32
+533   stdcall MultiByteToWideChar(long long ptr long ptr long) MultiByteToWideChar
+535   stdcall OpenEventA(long long ptr) OpenEvent32A
+536   stdcall OpenEventW(long long ptr) OpenEvent32W
+537   stdcall OpenFile(ptr ptr long) OpenFile32
+538   stdcall OpenFileMappingA(long long ptr) OpenFileMapping32A
+539   stdcall OpenFileMappingW(long long ptr) OpenFileMapping32W
+540   stdcall OpenMutexA(long long ptr) OpenMutex32A
+541   stdcall OpenMutexW(long long ptr) OpenMutex32W
+542   stub OpenProcess
+543   stub OpenProfileUserMapping
+544   stdcall OpenSemaphoreA(long long ptr) OpenSemaphore32A
+545   stdcall OpenSemaphoreW(long long ptr) OpenSemaphore32W
+546   stub OpenVxDHandle
+547   stdcall OutputDebugStringA(ptr) OutputDebugString32A
+548   stdcall OutputDebugStringW(ptr) OutputDebugString32W
+549   stub PeekConsoleInputA
+550   stub PeekConsoleInputW
+551   stub PeekNamedPipe
+552   stub PostQueuedCompletionStatus
+553   stub PrepareTape
+554   stub Process32First
+555   stub Process32Next
+556   stub PulseEvent
+557   stub PurgeComm
+558   stub QT_Thunk
+559   stdcall QueryDosDeviceA(ptr ptr long) QueryDosDevice32A
+560   stdcall QueryDosDeviceW(ptr ptr long) QueryDosDevice32W
+561   stub QueryNumberOfEventLogRecords
+562   stub QueryOldestEventLogRecord
+563   stdcall QueryPerformanceCounter(ptr) QueryPerformanceCounter
+564   stub QueryPerformanceFrequency
+565   stub QueueUserAPC
+566   register RaiseException(long long long ptr) RaiseException
+567   stdcall ReadConsoleA(long ptr long ptr ptr) ReadConsole32A
+568   stub ReadConsoleInputA
+569   stub ReadConsoleInputW
+570   stub ReadConsoleOutputA
+571   stub ReadConsoleOutputAttribute
+572   stub ReadConsoleOutputCharacterA
+573   stub ReadConsoleOutputCharacterW
+574   stub ReadConsoleOutputW
+575   stdcall ReadConsoleW(long ptr long ptr ptr) ReadConsole32W
+576   stdcall ReadFile(long ptr long ptr ptr) ReadFile
+577   stub ReadFileEx
+578   stub ReadProcessMemory
+579   stub RegisterServiceProcess
+580   stdcall ReinitializeCriticalSection(ptr) ReinitializeCriticalSection
+581   stdcall ReleaseMutex(long) ReleaseMutex
+582   stdcall ReleaseSemaphore(long long ptr) ReleaseSemaphore
+583   stdcall RemoveDirectoryA(ptr) RemoveDirectory32A
+584   stdcall RemoveDirectoryW(ptr) RemoveDirectory32W
+585   stdcall ResetEvent(long) ResetEvent
+586   stub ResumeThread
+587   stdcall RtlFillMemory(ptr long long) RtlFillMemory
+588   stdcall RtlMoveMemory(ptr ptr long) RtlMoveMemory
+589   register RtlUnwind(ptr long ptr long) RtlUnwind
+590   stdcall RtlZeroMemory(ptr long) RtlZeroMemory
+591   stub SMapLS
+592   stub SMapLS_IP_EBP_12
+593   stub SMapLS_IP_EBP_16
+594   stub SMapLS_IP_EBP_20
+595   stub SMapLS_IP_EBP_24
+596   stub SMapLS_IP_EBP_28
+597   stub SMapLS_IP_EBP_32
+598   stub SMapLS_IP_EBP_36
+599   stub SMapLS_IP_EBP_40
+600   stub SMapLS_IP_EBP_8
+601   stub SUnMapLS
+602   stub SUnMapLS_IP_EBP_12
+603   stub SUnMapLS_IP_EBP_16
+604   stub SUnMapLS_IP_EBP_20
+605   stub SUnMapLS_IP_EBP_24
+606   stub SUnMapLS_IP_EBP_28
+607   stub SUnMapLS_IP_EBP_32
+608   stub SUnMapLS_IP_EBP_36
+609   stub SUnMapLS_IP_EBP_40
+610   stub SUnMapLS_IP_EBP_8
+611   stub ScrollConsoleScreenBufferA
+612   stub ScrollConsoleScreenBufferW
+613   stdcall SearchPathA(ptr ptr ptr long ptr ptr) SearchPath32A
+614   stdcall SearchPathW(ptr ptr ptr long ptr ptr) SearchPath32W
+615   stdcall SetCommBreak(long) SetCommBreak32
+616   stub SetCommConfig
+617   stdcall SetCommMask(long ptr) SetCommMask
+618   stdcall SetCommState(long ptr) SetCommState32
+619   stdcall SetCommTimeouts(long ptr) SetCommTimeouts
+620   stub SetComputerNameA
+621   stub SetComputerNameW
+622   stub SetConsoleActiveScreenBuffer
+623   stub SetConsoleCP
+624   stdcall SetConsoleCtrlHandler(ptr long) SetConsoleCtrlHandler
+625   stub SetConsoleCursorInfo
+626   stdcall SetConsoleCursorPosition(long long) SetConsoleCursorPosition
+627   stdcall SetConsoleMode(long long) SetConsoleMode
+628   stub SetConsoleOutputCP
+629   stub SetConsoleScreenBufferSize
+630   stub SetConsoleTextAttribute
+631   stdcall SetConsoleTitleA(ptr) SetConsoleTitle32A
+632   stdcall SetConsoleTitleW(ptr) SetConsoleTitle32W
+633   stub SetConsoleWindowInfo
+634   stdcall SetCurrentDirectoryA(ptr) SetCurrentDirectory32A
+635   stdcall SetCurrentDirectoryW(ptr) SetCurrentDirectory32W
+636   stub SetDaylightFlag
+637   stub SetDefaultCommConfigA
+638   stub SetDefaultCommConfigW
+639   stdcall SetEndOfFile(long) SetEndOfFile
+640   stdcall SetEnvironmentVariableA(ptr ptr) SetEnvironmentVariable32A
+641   stdcall SetEnvironmentVariableW(ptr ptr) SetEnvironmentVariable32W
+642   stdcall SetErrorMode(long) SetErrorMode32
+643   stdcall	SetEvent(long) SetEvent
+644   stdcall SetFileApisToANSI() SetFileApisToANSI
+645   stdcall SetFileApisToOEM() SetFileApisToOEM
+646   stdcall SetFileAttributesA(ptr long) SetFileAttributes32A
+647   stdcall SetFileAttributesW(ptr long) SetFileAttributes32W
+648   stdcall SetFilePointer(long long ptr long) SetFilePointer
+649   stdcall SetFileTime(long ptr ptr ptr) SetFileTime
+650   stub SetHandleContext
+651   stdcall SetHandleCount(long) SetHandleCount32
+652   stub SetHandleInformation
+653   stdcall SetLastError(long) SetLastError
+654   stub SetLocalTime
+655   stdcall SetLocaleInfoA(long long ptr) SetLocaleInfoA
+656   stub SetLocaleInfoW
+657   stub SetMailslotInfo
+658   stub SetNamedPipeHandleState
+659   stdcall SetPriorityClass(long long) SetPriorityClass
+660   stub SetProcessShutdownParameters
+661   stub SetProcessWorkingSetSize
+662   stdcall SetStdHandle(long long) SetStdHandle
+663   stdcall SetSystemPowerState(long long) SetSystemPowerState
+664   stdcall SetSystemTime(ptr) SetSystemTime
+665   stub SetSystemTimeAdjustment
+666   stub SetTapeParameters
+667   stub SetTapePosition
+668   stdcall SetThreadAffinityMask(long long)	SetThreadAffinityMask
+669   stub SetThreadContext
+670   stub SetThreadLocale
+671   stdcall SetThreadPriority(long long) SetThreadPriority
+672   stdcall SetTimeZoneInformation(ptr) SetTimeZoneInformation
+673   stdcall SetUnhandledExceptionFilter(ptr) THUNK_SetUnhandledExceptionFilter
+674   stub SetVolumeLabelA
+675   stub SetVolumeLabelW
+676   stub SetupComm
+677   stdcall SizeofResource(long long) SizeofResource32
+678   stdcall Sleep(long) Sleep
+679   stub SleepEx
+680   stub SuspendThread
+681   stdcall SystemTimeToFileTime(ptr ptr) SystemTimeToFileTime
+682   stub SystemTimeToTzSpecificLocalTime
+683   stub TerminateProcess
+684   stub TerminateThread
+685   stub Thread32First
+686   stub Thread32Next
+687   stdcall ThunkConnect32(ptr ptr ptr ptr ptr ptr) ThunkConnect32
+688   stdcall TlsAlloc()	TlsAlloc
+690   stdcall TlsFree(long) TlsFree
+691   stub TlsFreeInternal
+692   stdcall TlsGetValue(long) TlsGetValue
+693   stdcall TlsSetValue(long ptr) TlsSetValue
+694   stub Toolhelp32ReadProcessMemory
+695   stub TransactNamedPipe
+696   stdcall TransmitCommChar(long long) TransmitCommChar32
+697   stub UTRegister
+698   stub UTUnRegister
+699   stdcall UnMapLS(long) UnMapLS
+700   stub UnMapSLFixArray
+701   stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
+702   stub UninitializeCriticalSection
+703   stdcall UnlockFile(long long long long long) UnlockFile
+704   stub UnlockFileEx
+705   stdcall UnmapViewOfFile(ptr) UnmapViewOfFile
+706   stub UpdateResourceA
+707   stub UpdateResourceW
+708   stub VerLanguageNameA
+709   stub VerLanguageNameW
+710   stdcall VirtualAlloc(ptr long long long) VirtualAlloc
+711   stdcall VirtualFree(ptr long long) VirtualFree
+712   stdcall VirtualLock(ptr long) VirtualLock
+713   stdcall VirtualProtect(ptr long long ptr) VirtualProtect
+714   stdcall VirtualProtectEx(long ptr long long ptr) VirtualProtectEx
+715   stdcall VirtualQuery(ptr ptr long) VirtualQuery
+716   stdcall VirtualQueryEx(long ptr ptr long) VirtualQueryEx
+717   stdcall VirtualUnlock(ptr long) VirtualUnlock
+718   stub WaitCommEvent
+719   stub WaitForDebugEvent
+720   stub WaitForMultipleObjects
+721   stub WaitForMultipleObjectsEx
+722   stdcall WaitForSingleObject(long long) WaitForSingleObject
+723   stub WaitForSingleObjectEx
+724   stub WaitNamedPipeA
+725   stub WaitNamedPipeW
+726   stdcall WideCharToMultiByte(long long ptr long ptr long ptr ptr)	WideCharToMultiByte
+727   stdcall WinExec(ptr long) WinExec32
+728   stdcall WriteConsoleA(long ptr long ptr ptr) WriteConsole32A
+729   stub WriteConsoleInputA
+730   stub WriteConsoleInputW
+731   stub WriteConsoleOutputA
+732   stub WriteConsoleOutputAttribute
+733   stub WriteConsoleOutputCharacterA
+734   stub WriteConsoleOutputCharacterW
+735   stub WriteConsoleOutputW
+736   stdcall WriteConsoleW(long ptr long ptr ptr) WriteConsole32W
+737   stdcall WriteFile(long ptr long ptr ptr) WriteFile
+738   stub WriteFileEx
+739   stub WritePrivateProfileSectionA
+740   stub WritePrivateProfileSectionW
+741   stdcall WritePrivateProfileStringA(ptr ptr ptr ptr) WritePrivateProfileString32A
+742   stdcall WritePrivateProfileStringW(ptr ptr ptr ptr) WritePrivateProfileString32W
+743   stub WritePrivateProfileStructA
+744   stub WritePrivateProfileStructW
+745   stub WriteProcessMemory
+746   stub WriteProfileSectionA
+747   stub WriteProfileSectionW
+748   stdcall WriteProfileStringA(ptr ptr ptr) WriteProfileString32A
+749   stdcall WriteProfileStringW(ptr ptr ptr) WriteProfileString32W
+750   stub WriteTapemark
+751   stub _DebugOut
+752   stub _DebugPrintf
+753   stdcall _hread(long ptr long) _hread32
+754   stdcall _hwrite(long ptr long) _hwrite32
+755   stdcall _lclose(long) _lclose32
+756   stdcall _lcreat(ptr long) _lcreat32
+757   stdcall _llseek(long long long) _llseek32
+758   stdcall _lopen(ptr long) _lopen32
+759   stdcall _lread(long ptr long) _lread32
+760   stdcall _lwrite(long ptr long) _lwrite32
+761   stub dprintf
+762   stdcall lstrcat(ptr ptr) lstrcat32A
+763   stdcall lstrcatA(ptr ptr) lstrcat32A
+764   stdcall lstrcatW(ptr ptr) lstrcat32W
+765   stdcall lstrcmp(ptr ptr) lstrcmp32A
+766   stdcall lstrcmpA(ptr ptr) lstrcmp32A
+767   stdcall lstrcmpW(ptr ptr) lstrcmp32W
+768   stdcall lstrcmpi(ptr ptr) lstrcmpi32A
+769   stdcall lstrcmpiA(ptr ptr) lstrcmpi32A
+770   stdcall lstrcmpiW(ptr ptr) lstrcmpi32W
+771   stdcall lstrcpy(ptr ptr) lstrcpy32A
+772   stdcall lstrcpyA(ptr ptr) lstrcpy32A
+773   stdcall lstrcpyW(ptr ptr) lstrcpy32W
+774   stdcall lstrcpyn(ptr ptr long) lstrcpyn32A
+775   stdcall lstrcpynA(ptr ptr long) lstrcpyn32A
+776   stdcall lstrcpynW(ptr ptr long) lstrcpyn32W
+777   stdcall lstrlen(ptr) lstrlen32A
+778   stdcall lstrlenA(ptr) lstrlen32A
+779   stdcall lstrlenW(ptr) lstrlen32W
+# 
+# Functions exported by kernel32.dll in NT 3.51
+# 
+780   stub AddConsoleAliasA
+781   stub AddConsoleAliasW
+782   stub BaseAttachCompleteThunk
+783   stub BasepDebugDump
+784   stub CloseConsoleHandle
+785   stub CmdBatNotification
+786   stub ConsoleMenuControl
+787   stub ConsoleSubst
+788   stub CreateVirtualBuffer
+789   stub ExitVDM
+790   stub ExpungeConsoleCommandHistoryA
+791   stub ExpungeConsoleCommandHistoryW
+792   stub ExtendVirtualBuffer
+793   stub FreeVirtualBuffer
+794   stub GetConsoleAliasA
+795   stub GetConsoleAliasExesA
+796   stub GetConsoleAliasExesLengthA
+797   stub GetConsoleAliasExesLengthW
+798   stub GetConsoleAliasExesW
+799   stub GetConsoleAliasW
+800   stub GetConsoleAliasesA
+801   stub GetConsoleAliasesLengthA
+802   stub GetConsoleAliasesLengthW
+803   stub GetConsoleAliasesW
+804   stub GetConsoleCommandHistoryA
+805   stub GetConsoleCommandHistoryLengthA
+806   stub GetConsoleCommandHistoryLengthW
+807   stub GetConsoleCommandHistoryW
+808   stub GetConsoleCursorInfo
+809   stub GetConsoleCursorInfo
+810   stub GetConsoleDisplayMode
+811   stub GetConsoleFontInfo
+812   stub GetConsoleFontSize
+813   stub GetConsoleHardwareState
+814   stub GetConsoleInputWaitHandle
+815   stub GetCurrentConsoleFont
+816   stub GetNextVDMCommand
+817   stub GetNumberOfConsoleFonts
+818   stub GetVDMCurrentDirectories
+819   stub HeapCreateTagsW
+820   stub HeapExtend
+821   stub HeapQueryTagW
+822   stub HeapSetFlags
+823   stub HeapSummary
+824   stub HeapUsage
+825   stub InvalidateConsoleDIBits
+826   stub IsDebuggerPresent
+827   stub NotifyNLSUserCache
+828   stub OpenConsoleW
+829   stub QueryWin31IniFilesMappedToRegistry
+830   stub RegisterConsoleVDM
+831   stub RegisterWaitForInputIdle
+832   stub RegisterWowBaseHandlers
+833   stub RegisterWowExec
+834   stub SetConsoleCommandHistoryMode
+835   stub SetConsoleCursor
+836   stub SetConsoleDisplayMode
+837   stub SetConsoleFont
+838   stub SetConsoleHardwareState
+839   stub SetConsoleKeyShortcuts
+840   stub SetConsoleMaximumWindowSize
+841   stub SetConsoleMenuClose
+842   stub SetConsoleNumberOfCommandsA
+843   stub SetConsoleNumberOfCommandsW
+844   stub SetConsolePalette
+845   stub SetLastConsoleEventActive
+846   stub SetVDMCurrentDirectories
+847   stub ShowConsoleCursor
+848   stub TrimVirtualBuffer
+849   stub VDMConsoleOperation
+850   stub VDMOperationStarted
+851   stub VerifyConsoleIoHandle
+852   stub VirtualBufferExceptionHandler
+853   stub WriteConsoleInputVDMA
+854   stub WriteConsoleInputVDMW
diff --git a/if1632/mpr.spec b/if1632/mpr.spec
index 15a75a0..3acba59 100644
--- a/if1632/mpr.spec
+++ b/if1632/mpr.spec
@@ -3,7 +3,7 @@
 
 0009 stub DllCanUnloadNow
 0010 stub DllGetClassObject
-0025 stub MultinetGetConnectionPerformanceA
+0025 stdcall MultinetGetConnectionPerformanceA(ptr ptr) MultinetGetConnectionPerformance32A
 0026 stub MultinetGetConnectionPerformanceW
 0027 stub MultinetGetErrorTextA
 0028 stub MultinetGetErrorTextW
diff --git a/if1632/ntdll.spec b/if1632/ntdll.spec
index 42d9ef2..eeee134 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -886,7 +886,7 @@
 882 stub _wcsupr
 883 stub abs
 884 stub atan
-885 stub atoi
+885 stdcall atoi(ptr) CRTDLL_atoi
 886 stub atol
 887 stub ceil
 888 stub cos
diff --git a/if1632/relay.c b/if1632/relay.c
index 8e8a15f..7f478f1 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -10,6 +10,8 @@
 #include "module.h"
 #include "stackframe.h"
 #include "task.h"
+#include "callback.h"
+#include "xmalloc.h"
 #include "stddebug.h"
 /* #define DEBUG_RELAY */
 #include "debug.h"
@@ -373,3 +375,51 @@
     }
     return retval;
 }
+
+/**********************************************************************
+ *	     CallProc32W    (KERNEL.56)
+ */
+DWORD
+WIN16_CallProc32W() {
+	DWORD *win_stack = (DWORD *)CURRENT_STACK16->args;
+	DWORD	nrofargs = win_stack[0];
+	DWORD	argconvmask = win_stack[1];
+	FARPROC32	proc32 = (FARPROC32)win_stack[2];
+	DWORD	*args,ret;
+	int	i;
+
+	fprintf(stderr,"CallProc32W(%ld,%ld,%p,args[",nrofargs,argconvmask,proc32);
+	args = (DWORD*)xmalloc(sizeof(DWORD)*nrofargs);
+	for (i=nrofargs;i--;) {
+		if (argconvmask & (1<<i)) {
+			args[nrofargs-i] = (DWORD)PTR_SEG_TO_LIN(win_stack[3+i]);
+			fprintf(stderr,"%08lx(%p),",win_stack[3+i],PTR_SEG_TO_LIN(win_stack[3+i]));
+		} else {
+			args[nrofargs-i] = win_stack[3+i];
+			fprintf(stderr,"%ld,",win_stack[3+i]);
+		}
+	}
+	fprintf(stderr,"]) - ");
+	switch (nrofargs) {
+	case 0: ret = CallTo32_0(proc32);
+		break;
+	case 1:	ret = CallTo32_1(proc32,args[0]);
+		break;
+	case 2:	ret = CallTo32_2(proc32,args[0],args[1]);
+		break;
+	case 3:	ret = CallTo32_3(proc32,args[0],args[1],args[2]);
+		break;
+	case 4:	ret = CallTo32_4(proc32,args[0],args[1],args[2],args[3]);
+		break;
+	case 5:	ret = CallTo32_5(proc32,args[0],args[1],args[2],args[3],args[4]);
+		break;
+	default:
+		/* FIXME: should go up to 32  arguments */
+		fprintf(stderr,"CallProc32W: unsupported number of arguments %ld, please report.\n",nrofargs);
+		ret = 0;
+		break;
+	}
+	fprintf(stderr,"returns %08lx\n",ret);
+	free(args);
+	return ret;
+}
diff --git a/if1632/winsock.spec b/if1632/winsock.spec
index 3961ed7..37ce932 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -51,7 +51,7 @@
              WSAAsyncGetServByName
 108 pascal16 WSACancelAsyncRequest(word) WSACancelAsyncRequest
 109 pascal16 WSASetBlockingHook(segptr) WSASetBlockingHook16
-110 pascal16 WSAUnhookBlockingHook() WSAUnhookBlockingHook
+110 pascal16 WSAUnhookBlockingHook() WSAUnhookBlockingHook16
 111 pascal16 WSAGetLastError() WSAGetLastError
 112 pascal   WSASetLastError(word) WSASetLastError
 113 pascal16 WSACancelBlockingCall() WSACancelBlockingCall
diff --git a/if1632/wsock32.spec b/if1632/wsock32.spec
index c7597e2..798e01c 100644
--- a/if1632/wsock32.spec
+++ b/if1632/wsock32.spec
@@ -41,7 +41,7 @@
 107 stub WSAAsyncGetServByName
 108 stub WSACancelAsyncRequest
 109 stdcall WSASetBlockingHook(ptr) WSASetBlockingHook32
-110 stub WSAUnhookBlockingHook
+110 stdcall WSAUnhookBlockingHook() WSAUnhookBlockingHook32
 111 stub WSAGetLastError
 112 stub WSASetLastError
 113 stub WSACancelBlockingCall
diff --git a/include/color.h b/include/color.h
index 94be6f3..985c877 100644
--- a/include/color.h
+++ b/include/color.h
@@ -14,7 +14,6 @@
 #define PC_SYS_RESERVED 0x40		/* system palentry is not to be mapped to */
 #define PC_SYS_MAPPED   0x10		/* logical palentry is a direct alias for system palentry */
 
-extern HPALETTE16 COLOR_Init(void);
 extern void	  COLOR_Cleanup(void);
 extern COLORREF	  COLOR_ToLogical(int pixel);
 extern int 	  COLOR_ToPhysical( DC *dc, COLORREF color );
diff --git a/include/font.h b/include/font.h
index 528fd66..cae411c 100644
--- a/include/font.h
+++ b/include/font.h
@@ -21,15 +21,9 @@
 #pragma pack(4)
 
 #define FONTCACHE 	32	/* dynamic font cache size */
-#define MAX_FONTS	256
-extern LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
 
-extern BOOL32 FONT_Init( void );
-extern INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer );
-extern INT32 FONT_GetObject32A( FONTOBJ * font, INT32 count, LPSTR buffer );
-extern int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz);
-extern void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
-                            TEXTMETRIC16 * metrics );
-
+extern BOOL32 FONT_Init( UINT16* pTextCaps );
+extern INT16  FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer );
+extern INT32  FONT_GetObject32A( FONTOBJ * font, INT32 count, LPSTR buffer );
 
 #endif /* __WINE_FONT_H */
diff --git a/include/gdi.h b/include/gdi.h
index 5b3dcb304..42d66cb 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -34,7 +34,7 @@
 } GDIOBJHDR;
 
 
-typedef struct
+typedef struct tagDeviceCaps
 {
     WORD   version;       /*   0: driver version */
     WORD   technology;    /*   2: device technology */
@@ -153,7 +153,7 @@
     BOOL32     (*pDeleteDC)(DC*);
     BOOL32     (*pDeleteObject)(HGDIOBJ16);
     BOOL32     (*pEllipse)(DC*,INT32,INT32,INT32,INT32);
-    BOOL32     (*pEnumDeviceFonts)(DC*,LPLOGFONT32A,FONTENUMPROCEX32A,LPARAM);
+    BOOL32     (*pEnumDeviceFonts)(DC*,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
     INT32      (*pEscape)(DC*,INT32,INT32,SEGPTR,SEGPTR);
     INT32      (*pExcludeClipRect)(DC*,INT32,INT32,INT32,INT32);
     INT32      (*pExcludeVisRect)(DC*,INT32,INT32,INT32,INT32);
diff --git a/include/mdi.h b/include/mdi.h
index 4915730..812580c 100644
--- a/include/mdi.h
+++ b/include/mdi.h
@@ -23,12 +23,6 @@
 extern LRESULT MDIClientWndProc(HWND16 hwnd, UINT16 message, 
 				WPARAM16 wParam, LPARAM lParam); /* mdi.c */
 
-typedef struct tagMDIWCL
-{
-  HWND16	 	 hChild;
-  struct tagMDIWCL	*prev;
-} MDIWCL;
-
 typedef struct 
 {
     UINT16   	nActiveChildren;
diff --git a/include/miscemu.h b/include/miscemu.h
index 532681f..dba7cff 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -32,6 +32,7 @@
 extern void INT_SetHandler( BYTE intnum, FARPROC16 handler );
 
 /* msdos/ioports.c */
+extern void IO_port_init (void);
 extern DWORD IO_inport( int port, int count );
 extern void IO_outport( int port, int count, DWORD value );
 
diff --git a/include/mmsystem.h b/include/mmsystem.h
index cc138fe..29cb8ea 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -186,9 +186,9 @@
     UINT16    wPid;                  /* product ID */
     VERSION vDriverVersion;        /* version of the driver */
     char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
-    DWORD   dwFormats;             /* formats supported */
+    DWORD   dwFormats WINE_PACKED;             /* formats supported */
     UINT16    wChannels;             /* number of sources supported */
-    DWORD   dwSupport;             /* functionality supported by driver */
+    DWORD   dwSupport WINE_PACKED;             /* functionality supported by driver */
 } WAVEOUTCAPS, *LPWAVEOUTCAPS;
 
 #define WAVECAPS_PITCH          0x0001   /* supports pitch control */
@@ -202,7 +202,7 @@
     UINT16    wPid;                    /* product ID */
     VERSION vDriverVersion;          /* version of the driver */
     char    szPname[MAXPNAMELEN];    /* product name (NULL terminated string) */
-    DWORD   dwFormats;               /* formats supported */
+    DWORD   dwFormats WINE_PACKED;               /* formats supported */
     UINT16    wChannels;               /* number of channels supported */
 } WAVEINCAPS, *LPWAVEINCAPS;
 
@@ -335,7 +335,7 @@
     UINT16    wVoices;               /* # of voices (internal synth only) */
     UINT16    wNotes;                /* max # of notes (internal synth only) */
     UINT16    wChannelMask;          /* channels used (internal synth only) */
-    DWORD   dwSupport;             /* functionality supported by driver */
+    DWORD   dwSupport WINE_PACKED;             /* functionality supported by driver */
 } MIDIOUTCAPS, *LPMIDIOUTCAPS;
 
 #define MOD_MIDIPORT    1  /* output port */
@@ -423,7 +423,7 @@
     VERSION vDriverVersion;        /* version of the driver */
     char    szPname[MAXPNAMELEN];  /* product name (NULL terminated string) */
     UINT16    wTechnology;           /* type of device */
-    DWORD   dwSupport;             /* functionality supported by driver */
+    DWORD   dwSupport WINE_PACKED;             /* functionality supported by driver */
 } AUXCAPS, *LPAUXCAPS;
 
 #define AUXCAPS_CDAUDIO    1       /* audio from internal CD-ROM drive */
@@ -1364,6 +1364,7 @@
 #define WODM_GETPLAYBACKRATE  18
 #define WODM_SETPLAYBACKRATE  19
 #define WODM_BREAKLOOP        20
+#define WODM_STOP             21
 
 #define WIDM_GETNUMDEVS  50
 #define WIDM_GETDEVCAPS  51
@@ -1376,6 +1377,7 @@
 #define WIDM_STOP        58
 #define WIDM_RESET       59
 #define WIDM_GETPOS      60
+#define WIDM_PAUSE       61
 
 #define MODM_GETNUMDEVS		1
 #define MODM_GETDEVCAPS		2
diff --git a/include/neexe.h b/include/neexe.h
index e425573..757b46f 100644
--- a/include/neexe.h
+++ b/include/neexe.h
@@ -7,22 +7,44 @@
 #include "wintypes.h"
 
 /*
- * Old MZ header for DOS programs.  Actually just a couple of fields
- * from it, so that we can find the start of the NE header.
+ * Old MZ header for DOS programs.
+ * We check only the magic and the e_lfanew offset to the new executable
+ * header.
  */
-struct mz_header_s
+typedef struct
 {
-    WORD mz_magic;         /* MZ Header signature */
-    BYTE  dont_care[0x3a];  /* MZ Header stuff */
-    WORD ne_offset;        /* Offset to extended header */
-};
+	WORD	e_magic;	/* MZ Header signature */
+	WORD	e_cblp;		/* Bytes on last page of file */
+	WORD	e_cp;		/* Pages in file */
+	WORD	e_crlc;		/* Relocations */
+	WORD	e_cparhdr;	/* Size of header in paragraphs */
+	WORD	e_minalloc;	/* Minimum extra paragraphs needed */
+	WORD	e_maxalloc;	/* Maximum extra paragraphs needed */
+	WORD	e_ss;		/* Initial (relative) SS value */
+	WORD	e_sp;		/* Initial SP value */
+	WORD	e_csum;		/* Checksum */
+	WORD	e_ip;		/* Initial IP value */
+	WORD	e_cs;		/* Initial (relative) CS value */
+	WORD	e_lfarlc;	/* File address of relocation table */
+	WORD	e_ovno;		/* Overlay number */
+	WORD	e_res[4];	/* Reserved words */
+	WORD	e_oemid;	/* OEM identifier (for e_oeminfo) */
+	WORD	e_oeminfo;	/* OEM information; e_oemid specific */
+	WORD	e_res2[10];	/* Reserved words */
+	WORD	e_lfanew;	/* Offset to extended header */
+} IMAGE_DOS_HEADER,*LPIMAGE_DOS_HEADER;
 
-#define MZ_SIGNATURE  ('M' | ('Z' << 8))
+#define	IMAGE_DOS_SIGNATURE	0x5A4D		/* MZ */
+#define	IMAGE_OS2_SIGNATURE	0x454E		/* NE */
+#define	IMAGE_OS2_SIGNATURE_LE	0x454C		/* LE */
+#define	IMAGE_VXD_SIGNATURE	0x454C		/* LE */
+#define	IMAGE_NT_SIGNATURE	0x00004550	/* PE00 */
 
 /*
  * This is the Windows executable (NE) header.
+ * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way.
  */
-struct ne_header_s
+typedef struct 
 {
     WORD  ne_magic;             /* 00 NE signature 'NE' */
     BYTE  linker_version;	/* 02 Linker version number */
@@ -56,10 +78,7 @@
     WORD  fastload_length;	/* 3a Length of fast load area */
     WORD  reserved2;		/* 3c Reserved by Microsoft */
     WORD  expect_version;	/* 3e Expected Windows version number */
-};
-
-#define NE_SIGNATURE  ('N' | ('E' << 8))
-#define PE_SIGNATURE  ('P' | ('E' << 8))
+} IMAGE_OS2_HEADER,*LPIMAGE_OS2_HEADER;
 
 /*
  * NE Header FORMAT FLAGS
diff --git a/include/nonclient.h b/include/nonclient.h
index 64b8da1..63fe119 100644
--- a/include/nonclient.h
+++ b/include/nonclient.h
@@ -9,9 +9,6 @@
 
 #include "win.h"
 
-extern void NC_GetMinMaxInfo( WND *pWnd, POINT16 *maxSize, POINT16 *maxPos,
-                              POINT16 *minTrack, POINT16 *maxTrack );
-extern void NC_DoNCPaint( HWND32 hwnd, HRGN32 clip, BOOL32 suppress_menupaint);
 extern LONG NC_HandleNCPaint( HWND32 hwnd , HRGN32 clip);
 extern LONG NC_HandleNCActivate( WND *pwnd, WPARAM16 wParam );
 extern LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect );
diff --git a/include/options.h b/include/options.h
index 36bfb5c..21f9d7a 100644
--- a/include/options.h
+++ b/include/options.h
@@ -72,5 +72,6 @@
                                      const char *def, char *buffer, int len );
 extern int PROFILE_GetWineIniInt( const char *section, const char *key_name,
                                   int def );
+extern char* PROFILE_GetStringItem( char* );
 
 #endif  /* __WINE_OPTIONS_H */
diff --git a/include/palette.h b/include/palette.h
index 7729f93..c913fd1 100644
--- a/include/palette.h
+++ b/include/palette.h
@@ -9,6 +9,8 @@
 
 #include "gdi.h"
 
+#define NB_RESERVED_COLORS              20 /* number of fixed colors in system palette */
+
   /* GDI logical palette object */
 typedef struct
 {
@@ -17,6 +19,7 @@
     LOGPALETTE  logpalette; /* _MUST_ be the last field */
 } PALETTEOBJ;
 
+extern HPALETTE16 PALETTE_Init();
 extern int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer );
 extern BOOL32 PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette );
 extern BOOL32 PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette);
diff --git a/include/peexe.h b/include/peexe.h
index d60affc..c716f61 100644
--- a/include/peexe.h
+++ b/include/peexe.h
@@ -5,15 +5,16 @@
 #define __WINE_PEEXE_H
 
 #include "wintypes.h"
+#include "neexe.h"
 
 typedef struct _IMAGE_FILE_HEADER {
-	WORD	Machine;
-	WORD	NumberOfSections;
-	DWORD	TimeDateStamp;
-	DWORD	PointerToSymbolTable;
-	DWORD	NumberOfSymbols;
-	WORD	SizeOfOptionalHeader;
-	WORD	Characteristics;
+	WORD	Machine;			/* 00 */
+	WORD	NumberOfSections;		/* 02 */
+	DWORD	TimeDateStamp;			/* 04 */
+	DWORD	PointerToSymbolTable;		/* 08 */
+	DWORD	NumberOfSymbols;		/* 0c */
+	WORD	SizeOfOptionalHeader;		/* 10 */
+	WORD	Characteristics;		/* 12 */
 } IMAGE_FILE_HEADER,*LPIMAGE_FILE_HEADER;
 
 #define	IMAGE_SIZEOF_FILE_HEADER	20
@@ -328,17 +329,6 @@
 	WORD	TypeOffset[1];
 } IMAGE_BASE_RELOCATION,*LPIMAGE_BASE_RELOCATION;
 
-typedef struct _IMAGE_DEBUG_DIRECTORY {
-	DWORD	Characteristics;
-	DWORD	TimeDateStamp;
-	WORD	MajorVersion;
-	WORD	MinorVersion;
-	DWORD	Type;
-	DWORD	SizeOfData;
-	DWORD	AddressOfRawData;
-	DWORD	PointerToRawData;
-} IMAGE_DEBUG_DIRECTORY,*LPIMAGE_DEBUG_DIRECTORY;
-
 typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
 	DWORD	Characteristics;
 	DWORD	TimeDateStamp;
@@ -373,17 +363,16 @@
  * The IMAGE_DEBUG_DIRECTORY data directory points to an array of
  * these structures.
  */
-struct PE_Debug_dir
-{
-	u_long		flags;
-	u_long		timestamp;
-	u_short		major;
-	u_short		minor;
-	u_long		type;
-	u_long		dbgsize;
-	u_long		dbgptr;
-	u_long		dbgoff;
-};
+typedef struct _IMAGE_DEBUG_DIRECTORY {
+	DWORD	Characteristics;
+	DWORD	TimeDateStamp;
+	WORD	MajorVersion;
+	WORD	MinorVersion;
+	DWORD	Type;
+	DWORD	SizeOfData;
+	DWORD	AddressOfRawData;
+	DWORD	PointerToRawData;
+} IMAGE_DEBUG_DIRECTORY,*LPIMAGE_DEBUG_DIRECTORY;
 
 /*
  * The type field above can take these (plus a few other
diff --git a/include/queue.h b/include/queue.h
index 80fe77d..de88be1 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -95,6 +95,5 @@
 extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos );
 extern void hardware_event( WORD message, WORD wParam, LONG lParam,
 			    int xPos, int yPos, DWORD time, DWORD extraInfo );
-extern void QUEUE_FlushMessages( HQUEUE16 hQueue );
 
 #endif  /* __WINE_QUEUE_H */
diff --git a/include/sysmetrics.h b/include/sysmetrics.h
index 4d5de2f..371d05f 100644
--- a/include/sysmetrics.h
+++ b/include/sysmetrics.h
@@ -53,13 +53,9 @@
 #ifdef WIN_95_LOOK
 #define SYSMETRICS_CXMINTRACK       112
 #define SYSMETRICS_CYMINTRACK        27
-#define SYSMETRICS_CXICONSPACING     75
-#define SYSMETRICS_CYICONSPACING     75
 #else
 #define SYSMETRICS_CXMINTRACK       100
 #define SYSMETRICS_CYMINTRACK        28
-#define SYSMETRICS_CXICONSPACING     20
-#define SYSMETRICS_CYICONSPACING     20
 #endif
 
   /* Some non-constant system metrics */
@@ -73,6 +69,8 @@
 #define SYSMETRICS_CXDOUBLECLK         sysMetrics[SM_CXDOUBLECLK]
 #define SYSMETRICS_CYDOUBLECLK         sysMetrics[SM_CYDOUBLECLK]
 #define SYSMETRICS_MENUDROPALIGNMENT   sysMetrics[SM_MENUDROPALIGNMENT]
+#define SYSMETRICS_CXICONSPACING       sysMetrics[SM_CXICONSPACING]
+#define SYSMETRICS_CYICONSPACING       sysMetrics[SM_CYICONSPACING]
 
 extern void SYSMETRICS_Init(void);
 extern short sysMetrics[SM_CMETRICS+1];
diff --git a/include/toolhelp.h b/include/toolhelp.h
index fbf21a8..eaf30ec 100644
--- a/include/toolhelp.h
+++ b/include/toolhelp.h
@@ -274,7 +274,7 @@
 #define NFY_UNKNOWN	0
 #define NFY_LOADSEG	1
 /* DATA is a pointer to following struct: */
-struct {
+typedef struct {
 	DWORD	dwSize;
 	WORD	wSelector;
 	WORD	wSegNum;
@@ -286,7 +286,7 @@
 
 /* called when loading/starting a DLL */
 #define NFY_STARTDLL	3
-struct {
+typedef struct {
     DWORD      dwSize;
     HMODULE16  hModule;
     WORD       wCS;
@@ -304,7 +304,7 @@
 
 /* RIP? debugevent */
 #define NFY_RIP		7
-struct {
+typedef struct {
 	DWORD	dwSize;
 	WORD	wIP;
 	WORD	wCS;
@@ -331,7 +331,7 @@
 
 /* log errors */
 #define NFY_LOGERROR	12
-struct {
+typedef struct {
 	DWORD	dwSize;
 	UINT16	wErrCode;
 	VOID   *lpInfo; /* depends on wErrCode */
@@ -339,7 +339,7 @@
 
 /* called for parameter errors? */
 #define NFY_LOGPARAMERROR	13
-struct {
+typedef struct {
     DWORD       dwSize;
     UINT16      wErrCode;
     FARPROC16   lpfnErrorAddr;
diff --git a/include/ver.h b/include/ver.h
index d626967..05342f2 100644
--- a/include/ver.h
+++ b/include/ver.h
@@ -83,7 +83,7 @@
 	/* output (returned) */
 #define	VFF_CURNEDEST		0x0001
 #define	VFF_FILEINUSE		0x0002
-#define	VFF_BUFFTOSMALL		0x0003
+#define	VFF_BUFFTOOSMALL	0x0004
 
 /* VerInstallFile Flags */
 	/* input */
diff --git a/include/win.h b/include/win.h
index aabfe63..ed9e1bc 100644
--- a/include/win.h
+++ b/include/win.h
@@ -40,6 +40,7 @@
     BIC32_SCROLL,
     BIC32_DESKTOP,
     BIC32_DIALOG,
+    BIC32_ICONTITLE,
     BIC32_NB_CLASSES
 } BUILTIN_CLASS32;
 
@@ -62,9 +63,6 @@
     HINSTANCE16    hInstance;     /* Window hInstance (from CreateWindow) */
     RECT16         rectClient;    /* Client area rel. to parent client area */
     RECT16         rectWindow;    /* Whole window rel. to parent client area */
-    RECT16         rectNormal;    /* Window rect. when in normal state */
-    POINT16        ptIconPos;     /* Icon position */
-    POINT16        ptMaxPos;      /* Maximized window position */
     LPSTR          text;          /* Window text */
     void          *pVScroll;      /* Vertical scroll-bar info */
     void          *pHScroll;      /* Horizontal scroll-bar info */
@@ -83,6 +81,14 @@
     DWORD          wExtra[1];     /* Window extra bytes */
 } WND;
 
+typedef struct
+{
+    RECT16	   rectNormal;
+    POINT16	   ptIconPos;
+    POINT16	   ptMaxPos;
+    HWND16	   hwndIconTitle;
+} INTERNALPOS, *LPINTERNALPOS;
+
   /* WND flags values */
 #define WIN_NEEDS_BEGINPAINT   0x0001 /* WM_PAINT sent to window */
 #define WIN_NEEDS_ERASEBKGND   0x0002 /* WM_ERASEBKGND must be sent to window*/
@@ -97,34 +103,42 @@
 #define WIN_ISWIN32            0x0400 /* Understands Win32 messages */
 #define WIN_SAVEUNDER_OVERRIDE 0x0800
 
+  /* BuildWinArray() flags */
+#define BWA_SKIPDISABLED	0x0001
+#define BWA_SKIPHIDDEN		0x0002
+#define BWA_SKIPOWNED		0x0004
+#define BWA_SKIPICONIC		0x0008
+
   /* Window functions */
-extern WND *WIN_FindWndPtr( HWND32 hwnd );
-extern WND *WIN_GetDesktop(void);
-extern void WIN_DumpWindow( HWND32 hwnd );
-extern void WIN_WalkWindows( HWND32 hwnd, int indent );
+extern WND*   WIN_FindWndPtr( HWND32 hwnd );
+extern WND*   WIN_GetDesktop(void);
+extern void   WIN_DumpWindow( HWND32 hwnd );
+extern void   WIN_WalkWindows( HWND32 hwnd, int indent );
 extern Window WIN_GetXWindow( HWND32 hwnd );
 extern BOOL32 WIN_UnlinkWindow( HWND32 hwnd );
 extern BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter );
 extern HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue );
-extern void WIN_SendParentNotify( HWND32 hwnd, WORD event,
-                                  WORD idChild, LPARAM lValue );
-extern void WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew );
+extern void   WIN_SendParentNotify( HWND32 hwnd, WORD event,
+                                    WORD idChild, LPARAM lValue );
+extern void   WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew );
 extern BOOL32 WIN_CreateDesktopWindow(void);
 extern HWND32 WIN_GetTopParent( HWND32 hwnd );
 extern BOOL32 WIN_IsWindowDrawable(WND*, BOOL32 );
 extern HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd );
-extern WND **WIN_BuildWinArray( WND *wndPtr );
+extern WND**  WIN_BuildWinArray( WND *wndPtr, UINT32 bwa, UINT32* pnum );
 
-extern void DEFWND_SetText( WND *wndPtr, LPCSTR text );  /* windows/defwnd.c */
+extern void DEFWND_SetText( WND *wndPtr, LPCSTR text );		      /* windows/defwnd.c */
 
-extern void PROPERTY_RemoveWindowProps( WND *pWnd );   /* windows/property.c */
+extern void PROPERTY_RemoveWindowProps( WND *pWnd );  		      /* windows/property.c */
 
 extern BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
                                   HRGN32 hrgnUpdate, UINT32 flags,
-                                  UINT32 control );    /* windows/painting.c */
+                                  UINT32 control );		      /* windows/painting.c */
 
 extern BOOL32 WIDGETS_IsControl32( WND* pWnd, BUILTIN_CLASS32 cls );  /* controls/widgets.c */
 
+extern HWND32 ICONTITLE_Create( WND* );				      /* controls/icontitle.c */
+
 extern Display * display;
 extern Screen * screen;
 extern Window rootWindow;
diff --git a/include/win16drv.h b/include/win16drv.h
index 04df416..f7d144c 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -165,13 +165,13 @@
 		       FARPROC16 lpCallbackFunc, LPVOID lpClientData);
 extern DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle, 
 				  LPVOID lpInObj, LPVOID lpOutObj,
-				  LPTEXTXFORM16 lpTextXForm);
+				  SEGPTR lpTextXForm);
 
 extern BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle, FARPROC16 lpfn, LPVOID lpb);
 extern DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
 			       RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, 
-			       SEGPTR lpFontInfo, LPDRAWMODE lpDrawMode, 
-			       LPTEXTXFORM16 lpTextXForm, SHORT *lpCharWidths,
+			       SEGPTR lpFontInfo,SEGPTR lpDrawMode, 
+			       SEGPTR lpTextXForm, SHORT *lpCharWidths,
 			       RECT16 *     lpOpaqueRect, WORD wOptions);
 
 
@@ -191,4 +191,12 @@
 
 
 
+/*
+ * Wine 16bit driver global variables
+ */
+extern SEGPTR		win16drv_SegPtr_TextXForm;
+extern LPTEXTXFORM16 	win16drv_TextXFormP;
+extern SEGPTR		win16drv_SegPtr_DrawMode;
+extern LPDRAWMODE 	win16drv_DrawModeP;
+
 #endif  /* __WINE_WIN16DRV_H */
diff --git a/include/windows.h b/include/windows.h
index dbfb29e..dc3a494 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -235,9 +235,11 @@
 DECL_WINELIB_TYPE_AW(MDICREATESTRUCT);
 DECL_WINELIB_TYPE_AW(LPMDICREATESTRUCT);
 
-#define MDITILE_VERTICAL    0    
-#define MDITILE_HORIZONTAL  1
-#define MDIS_ALLCHILDSTYLES 0x0001
+#define MDITILE_VERTICAL     0x0000   
+#define MDITILE_HORIZONTAL   0x0001
+#define MDITILE_SKIPDISABLED 0x0002
+
+#define MDIS_ALLCHILDSTYLES  0x0001
 
 typedef struct {
     DWORD   styleOld;
@@ -980,6 +982,10 @@
 #define LF_FACESIZE     32
 #define LF_FULLFACESIZE 64
 
+#define RASTER_FONTTYPE     0x0001
+#define DEVICE_FONTTYPE     0x0002
+#define TRUETYPE_FONTTYPE   0x0004
+
 typedef struct
 {
     INT16  lfHeight;
@@ -1168,7 +1174,15 @@
 #define SYMBOL_CHARSET	      2
 #define SHIFTJIS_CHARSET      128
 #define HANGEUL_CHARSET       129
+#define GB2313_CHARSET        134
 #define CHINESEBIG5_CHARSET   136
+#define GREEK_CHARSET         161	/* CP1253 */
+#define TURKISH_CHARSET       162	/* CP1254, -iso8859-9 */
+#define HEBREW_CHARSET        177	/* CP1255 */
+#define ARABIC_CHARSET        178	/* CP1256 */
+#define BALTIC_CHARSET        186	/* CP1257 */
+#define RUSSIAN_CHARSET       204	/* CP1251 */
+#define EE_CHARSET	      238	/* CP1250, -iso8859-2 */
 #define OEM_CHARSET	      255
 
   /* lfOutPrecision values */
@@ -1405,8 +1419,8 @@
 typedef INT32 (*FONTENUMPROCEX32W)(LPENUMLOGFONTEX32W,LPNEWTEXTMETRICEX32W,UINT32,LPARAM);
 DECL_WINELIB_TYPE_AW(FONTENUMPROCEX);
 
-  /* tmPitchAndFamily values */
-#define TMPF_FIXED_PITCH    1
+  /* tmPitchAndFamily bits */
+#define TMPF_FIXED_PITCH    1		/* means variable pitch */
 #define TMPF_VECTOR	    2
 #define TMPF_TRUETYPE	    4
 #define TMPF_DEVICE	    8
@@ -2304,6 +2318,7 @@
 #define	WF_SMALLFRAME	0x0200
 #define	WF_80x87	0x0400
 #define	WF_PAGING	0x0800
+#define	WF_HASCPUID     0x2000
 #define	WF_WIN32WOW     0x4000	/* undoc */
 #define	WF_WLO          0x8000
 
@@ -2917,6 +2932,50 @@
 #define BF_DIAGONAL_ENDBOTTOMLEFT   (BF_DIAGONAL | BF_BOTTOM | BF_LEFT)
 #define BF_DIAGONAL_ENDBOTTOMRIGHT  (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT)
 
+/* DrawFrameControl() uType's */
+
+#define DFC_CAPTION             1
+#define DFC_MENU                2
+#define DFC_SCROLL              3
+#define DFC_BUTTON              4
+
+/* uState's */
+
+#define DFCS_CAPTIONCLOSE       0x0000
+#define DFCS_CAPTIONMIN         0x0001
+#define DFCS_CAPTIONMAX         0x0002
+#define DFCS_CAPTIONRESTORE     0x0003
+#define DFCS_CAPTIONHELP        0x0004		/* Windows 95 only */
+
+#define DFCS_MENUARROW          0x0000
+#define DFCS_MENUCHECK          0x0001
+#define DFCS_MENUBULLET         0x0002
+#define DFCS_MENUARROWRIGHT     0x0004
+
+#define DFCS_SCROLLUP            0x0000
+#define DFCS_SCROLLDOWN          0x0001
+#define DFCS_SCROLLLEFT          0x0002
+#define DFCS_SCROLLRIGHT         0x0003
+#define DFCS_SCROLLCOMBOBOX      0x0005
+#define DFCS_SCROLLSIZEGRIP      0x0008
+#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010
+
+#define DFCS_BUTTONCHECK        0x0000
+#define DFCS_BUTTONRADIOIMAGE   0x0001
+#define DFCS_BUTTONRADIOMASK    0x0002		/* to draw nonsquare button */
+#define DFCS_BUTTONRADIO        0x0004
+#define DFCS_BUTTON3STATE       0x0008
+#define DFCS_BUTTONPUSH         0x0010
+
+/* additional state of the control */
+
+#define DFCS_INACTIVE           0x0100
+#define DFCS_PUSHED             0x0200
+#define DFCS_CHECKED            0x0400
+#define DFCS_ADJUSTRECT         0x2000		/* exclude surrounding edge */
+#define DFCS_FLAT               0x4000
+#define DFCS_MONO               0x8000
+
 /* Window Styles */
 #define WS_OVERLAPPED    0x00000000L
 #define WS_POPUP         0x80000000L
@@ -4093,6 +4152,98 @@
 typedef INT32 (*MFENUMPROC32)(HDC32,HANDLETABLE32*,METARECORD*,INT32,LPARAM);
 DECL_WINELIB_TYPE(MFENUMPROC);
 
+#ifndef NOLOGERROR
+
+/* LogParamError and LogError values */
+
+/* Error modifier bits */
+#define ERR_WARNING             0x8000
+#define ERR_PARAM               0x4000
+
+#define ERR_SIZE_MASK           0x3000
+#define ERR_BYTE                0x1000
+#define ERR_WORD                0x2000
+#define ERR_DWORD               0x3000
+
+/* LogParamError() values */
+
+/* Generic parameter values */
+#define ERR_BAD_VALUE           0x6001
+#define ERR_BAD_FLAGS           0x6002
+#define ERR_BAD_INDEX           0x6003
+#define ERR_BAD_DVALUE          0x7004
+#define ERR_BAD_DFLAGS          0x7005
+#define ERR_BAD_DINDEX          0x7006
+#define ERR_BAD_PTR             0x7007
+#define ERR_BAD_FUNC_PTR        0x7008
+#define ERR_BAD_SELECTOR        0x6009
+#define ERR_BAD_STRING_PTR      0x700a
+#define ERR_BAD_HANDLE          0x600b
+
+/* KERNEL parameter errors */
+#define ERR_BAD_HINSTANCE       0x6020
+#define ERR_BAD_HMODULE         0x6021
+#define ERR_BAD_GLOBAL_HANDLE   0x6022
+#define ERR_BAD_LOCAL_HANDLE    0x6023
+#define ERR_BAD_ATOM            0x6024
+#define ERR_BAD_HFILE           0x6025
+
+/* USER parameter errors */
+#define ERR_BAD_HWND            0x6040
+#define ERR_BAD_HMENU           0x6041
+#define ERR_BAD_HCURSOR         0x6042
+#define ERR_BAD_HICON           0x6043
+#define ERR_BAD_HDWP            0x6044
+#define ERR_BAD_CID             0x6045
+#define ERR_BAD_HDRVR           0x6046
+
+/* GDI parameter errors */
+#define ERR_BAD_COORDS          0x7060
+#define ERR_BAD_GDI_OBJECT      0x6061
+#define ERR_BAD_HDC             0x6062
+#define ERR_BAD_HPEN            0x6063
+#define ERR_BAD_HFONT           0x6064
+#define ERR_BAD_HBRUSH          0x6065
+#define ERR_BAD_HBITMAP         0x6066
+#define ERR_BAD_HRGN            0x6067
+#define ERR_BAD_HPALETTE        0x6068
+#define ERR_BAD_HMETAFILE       0x6069
+
+
+/* LogError() values */
+
+/* KERNEL errors */
+#define ERR_GALLOC              0x0001
+#define ERR_GREALLOC            0x0002
+#define ERR_GLOCK               0x0003
+#define ERR_LALLOC              0x0004
+#define ERR_LREALLOC            0x0005
+#define ERR_LLOCK               0x0006
+#define ERR_ALLOCRES            0x0007
+#define ERR_LOCKRES             0x0008
+#define ERR_LOADMODULE          0x0009
+
+/* USER errors */
+#define ERR_CREATEDLG           0x0040
+#define ERR_CREATEDLG2          0x0041
+#define ERR_REGISTERCLASS       0x0042
+#define ERR_DCBUSY              0x0043
+#define ERR_CREATEWND           0x0044
+#define ERR_STRUCEXTRA          0x0045
+#define ERR_LOADSTR             0x0046
+#define ERR_LOADMENU            0x0047
+#define ERR_NESTEDBEGINPAINT    0x0048
+#define ERR_BADINDEX            0x0049
+#define ERR_CREATEMENU          0x004a
+
+/* GDI errors */
+#define ERR_CREATEDC            0x0080
+#define ERR_CREATEMETA          0x0081
+#define ERR_DELOBJSELECTED      0x0082
+#define ERR_SELBITMAP           0x0083
+
+
+
 /* Debugging support (DEBUG SYSTEM ONLY) */
 typedef struct
 {
@@ -4141,6 +4292,8 @@
 #define DBF_APPLICATION     0x0008
 #define DBF_DRIVER          0x0010
 
+#endif /* NOLOGERROR */
+
 /* Win32-specific structures */
 
 typedef struct {
@@ -4532,6 +4685,8 @@
     DWORD    HighPart;
 } ULARGE_INTEGER,*LPULARGE_INTEGER;
 
+typedef LARGE_INTEGER LUID,*LPLUID; /* locally unique ids */
+
 /* SetLastErrorEx types */
 #define	SLE_ERROR	0x00000001
 #define	SLE_MINORERROR	0x00000002
@@ -4814,6 +4969,39 @@
 DECL_WINELIB_TYPE_AW(DOCINFO);
 DECL_WINELIB_TYPE_AW(LPDOCINFO);
 
+typedef struct {
+	DWORD	dwScope;
+	DWORD	dwType;
+	DWORD	dwDisplayType;
+	DWORD	dwUsage;
+	LPSTR	lpLocalName;
+	LPSTR	lpRemoteName;
+	LPSTR	lpComment ;
+	LPSTR	lpProvider;
+} NETRESOURCE32A,*LPNETRESOURCE32A;
+
+typedef struct {
+	DWORD	dwScope;
+	DWORD	dwType;
+	DWORD	dwDisplayType;
+	DWORD	dwUsage;
+	LPWSTR	lpLocalName;
+	LPWSTR	lpRemoteName;
+	LPWSTR	lpComment ;
+	LPWSTR	lpProvider;
+} NETRESOURCE32W,*LPNETRESOURCE32W;
+
+DECL_WINELIB_TYPE_AW(NETRESOURCE);
+DECL_WINELIB_TYPE_AW(LPNETRESOURCE);
+
+typedef struct {
+	DWORD	cbStructure;
+	DWORD	dwFlags;
+	DWORD	dwSpeed;
+	DWORD	dwDelay;
+	DWORD	dwOptDataSize;
+} NETCONNECTINFOSTRUCT,*LPNETCONNECTINFOSTRUCT;
+
 #pragma pack(4)
 
 /* Declarations for functions that exist only in Win16 */
@@ -4899,6 +5087,8 @@
 BOOL16     IsTask(HTASK16);
 HTASK16    IsTaskLocked(void);
 BOOL16     IsValidMetaFile(HMETAFILE16);
+VOID       LogError(UINT16, LPVOID);
+VOID       LogParamError(UINT16,FARPROC16,LPVOID);
 BOOL16     LocalInit(HANDLE16,WORD,WORD);
 FARPROC16  LocalNotify(FARPROC16);
 HTASK16    LockCurrentTask(BOOL16);
diff --git a/include/winpos.h b/include/winpos.h
index be21ee2..44f9e88 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -25,7 +25,11 @@
     WINDOWPOS32 winPos[1];
 } DWP;
 
-extern void WINPOS_FindIconPos( HWND32 hwnd );
+extern BOOL32 WINPOS_RedrawIconTitle( HWND32 hWnd );
+extern BOOL32 WINPOS_ShowIconTitle( WND* pWnd, BOOL32 bShow );
+extern void   WINPOS_GetMinMaxInfo( WND* pWnd, POINT16 *maxSize, POINT16 *maxPos,
+                                    POINT16 *minTrack, POINT16 *maxTrack );
+extern UINT16 WINPOS_MinMaximize( WND* pWnd, UINT16 cmd, LPRECT16 lpPos);
 extern BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse,
                                       BOOL32 fChangeFocus );
 extern BOOL32 WINPOS_ChangeActiveWindow( HWND32 hwnd, BOOL32 mouseMsg );
diff --git a/include/x11drv.h b/include/x11drv.h
index 26336c9..da3588f 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -30,11 +30,7 @@
 } X_PHYSBRUSH;
 
   /* X physical font */
-typedef struct
-{
-    XFontStruct * fstruct;
-    TEXTMETRIC16  metrics;
-} X_PHYSFONT;
+typedef UINT32	 X_PHYSFONT;
 
   /* X physical device */
 typedef struct
@@ -46,13 +42,18 @@
     X_PHYSBRUSH   brush;
 } X11DRV_PDEVICE;
 
+typedef INT32 (*DEVICEFONTENUMPROC)(LPENUMLOGFONT16,LPNEWTEXTMETRIC16,UINT16,LPARAM);
+
 /* Wine driver X11 functions */
 
 struct tagDC;
+struct tagDeviceCaps;
 
 extern BOOL32 X11DRV_BitBlt( struct tagDC *dcDst, INT32 xDst, INT32 yDst,
                              INT32 width, INT32 height, struct tagDC *dcSrc,
                              INT32 xSrc, INT32 ySrc, DWORD rop );
+extern BOOL32 X11DRV_EnumDeviceFonts( struct tagDC *dc, LPLOGFONT16 plf,
+				      DEVICEFONTENUMPROC dfeproc, LPARAM lp );
 extern BOOL32 X11DRV_GetCharWidth( struct tagDC *dc, UINT32 firstChar,
                                    UINT32 lastChar, LPINT32 buffer );
 extern BOOL32 X11DRV_GetTextExtentPoint( struct tagDC *dc, LPCSTR str,
@@ -60,7 +61,7 @@
 extern BOOL32 X11DRV_GetTextMetrics(struct tagDC *dc, TEXTMETRIC32A *metrics);
 extern BOOL32 X11DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
                              INT32 width, INT32 height, DWORD rop );
-extern VOID X11DRV_SetDeviceClipping(struct tagDC *dc);
+extern VOID   X11DRV_SetDeviceClipping(struct tagDC *dc);
 extern BOOL32 X11DRV_StretchBlt( struct tagDC *dcDst, INT32 xDst, INT32 yDst,
                                  INT32 widthDst, INT32 heightDst,
                                  struct tagDC *dcSrc, INT32 xSrc, INT32 ySrc,
@@ -105,6 +106,6 @@
 
 extern BOOL32 X11DRV_BITMAP_Init(void);
 extern BOOL32 X11DRV_BRUSH_Init(void);
-extern BOOL32 X11DRV_FONT_Init(void);
+extern BOOL32 X11DRV_FONT_Init( struct tagDeviceCaps* );
 
 #endif  /* __WINE_X11DRV_H */
diff --git a/include/x11font.h b/include/x11font.h
new file mode 100644
index 0000000..c87064e
--- /dev/null
+++ b/include/x11font.h
@@ -0,0 +1,178 @@
+/*
+ * X11 physical font definitions
+ *
+ * Copyright 1997 Alex Korobka
+ */
+
+#ifndef __WINE_X11FONT_H
+#define __WINE_X11FONT_H
+
+#include "gdi.h"
+
+#pragma pack(1)
+
+/* this is a part of the font resource header, should 
+ * make it easier to implement dynamic softfont loading */
+
+typedef struct
+{
+    INT16	dfType;
+    INT16	dfPoints;
+    INT16	dfVertRes;
+    INT16	dfHorizRes;
+    INT16	dfAscent;
+    INT16	dfInternalLeading;
+    INT16	dfExternalLeading;
+    CHAR	dfItalic;
+    CHAR	dfUnderline;
+    CHAR	dfStrikeOut;
+    INT16	dfWeight;
+    CHAR	dfCharSet;
+    INT16	dfPixWidth;
+    INT16	dfPixHeight;
+    CHAR	dfPitchAndFamily;
+    INT16	dfAvgWidth;
+    INT16	dfMaxWidth;
+    CHAR	dfFirstChar;
+    CHAR	dfLastChar;
+    CHAR	dfDefaultChar;
+    CHAR	dfBreakChar;
+    INT16	dfWidthBytes;
+    LPCSTR	dfDevice;
+    LPCSTR	dfFace;
+} IFONTINFO16, *LPIFONTINFO16;
+
+#pragma pack(4)
+
+/* internal flags */
+
+#define FI_POLYWEIGHT	    0x0001
+#define FI_POLYSLANT 	    0x0002
+#define FI_OBLIQUE	    0x0004
+#define FI_SCALABLE  	    0x0008
+#define FI_FW_BOOK	    0x0010
+#define FI_FW_DEMI	    0x0020
+#define FI_VARIABLEPITCH    0x0040
+#define FI_FIXEDPITCH       0x0080
+
+#define FI_ENC_ISO8859	    0x0100
+#define FI_ENC_ISO646	    0x0200
+#define FI_ENC_ANSI	    0x0400
+
+#define FI_FIXEDEX	    0x1000
+#define FI_NORMAL	    0x2000
+#define FI_SUBSET 	    0x4000
+#define FI_TRUETYPE	    0x8000
+
+typedef struct tagFontInfo
+{
+    struct tagFontInfo*		next;
+    UINT16			fi_flags;
+
+ /* LFD parameters can be quite different from the actual metrics */
+
+    UINT16			lfd_height;
+    UINT16			lfd_width;
+    UINT16			lfd_decipoints;
+    UINT16			lfd_resolution;
+
+    IFONTINFO16			df;
+} fontInfo;
+
+/* Font resource list for EnumFont() purposes */
+
+#define FR_SOFTFONT         0x1000              /* - .FON or .FOT file */
+#define FR_SOFTRESOURCE     0x2000              /* - resource handle */
+#define FR_REMOVED          0x4000              /* delayed remove */
+#define FR_NAMESET          0x8000
+
+typedef struct tagFontResource
+{
+  struct tagFontResource*	next;
+  UINT16			fr_flags;
+  UINT16			count;
+  fontInfo*			fi;
+  char*                         resource;
+  CHAR				lfFaceName[LF_FACESIZE];
+} fontResource;
+
+#define FO_RESOURCE_MASK	0x000F
+#define FO_SYSTEM		0x0001		/* resident in cache */
+#define FO_SOFTFONT		0x0002		/* installed at runtime */
+#define FO_SHARED		0x0004		/* MITSHM */
+#define FO_REMOVED		0x0008		/* remove when count falls to 0 */
+
+#define FO_MATCH_MASK		0x00F0
+#define FO_MATCH_NORASTER	0x0010
+#define FO_MATCH_PAF		0x0020
+#define FO_MATCH_XYINDEP	0x0040
+
+#define FO_SYNTH_MASK		0xFF00
+#define FO_SYNTH_HEIGHT   	0x2000
+#define FO_SYNTH_WIDTH		0x4000
+#define FO_SYNTH_ROTATE 	0x8000
+#define FO_SYNTH_BOLD		0x0100
+#define FO_SYNTH_ITALIC		0x0200
+#define FO_SYNTH_UNDERLINE	0x0400
+#define FO_SYNTH_STRIKEOUT	0x0800
+
+/* Realized screen font */
+
+typedef struct 
+{
+  XFontStruct*          fs;			/* text metrics */
+  fontResource*         fr;			/* font family */
+  fontInfo*		fi;			/* font instance info */
+  LPMAT2*		lpXForm;		/* optional transformation matrix */
+  Pixmap*               lpPixmap;		/* optional character bitmasks for synth fonts */
+
+  INT16			foInternalLeading;
+  INT16			foAvgCharWidth;
+  UINT16		fo_flags;
+
+  /* font cache housekeeping */
+
+  UINT16                count;
+  UINT16                lru;
+  UINT16                lfchecksum;
+  LOGFONT16             lf;
+} fontObject;
+
+typedef struct
+{
+  fontResource*		pfr;
+  fontInfo*		pfi;
+  UINT16		height;
+  UINT16		flags;
+  LPLOGFONT16		plf;
+} fontMatch;
+
+typedef struct
+{
+  LPLOGFONT16		lpLogFontParam;
+  FONTENUMPROC16	lpEnumFunc;
+  LPARAM		lpData;
+
+  LPNEWTEXTMETRICEX16	lpTextMetric;
+  LPENUMLOGFONTEX16	lpLogFont;
+  SEGPTR		segTextMetric;
+  SEGPTR		segLogFont;
+} fontEnum16;
+
+typedef struct
+{
+  LPLOGFONT32W		lpLogFontParam;
+  FONTENUMPROC32W	lpEnumFunc;
+  LPARAM		lpData;
+
+  LPNEWTEXTMETRICEX32W  lpTextMetric;
+  LPENUMLOGFONTEX32W    lpLogFont;
+  DWORD			dwFlags;
+} fontEnum32;
+
+extern fontObject* XFONT_GetFontObject( X_PHYSFONT pFont );
+extern XFontStruct* XFONT_GetFontStruct( X_PHYSFONT pFont );
+extern LPIFONTINFO16 XFONT_GetFontInfo( X_PHYSFONT pFont );
+
+#endif __WINE_X11FONT_H 
+
diff --git a/library/sup.c b/library/sup.c
index 934ac2b..5245618 100644
--- a/library/sup.c
+++ b/library/sup.c
@@ -14,15 +14,31 @@
 #define LOADSHORT(x) LOAD(x); TAB->x = CONV_SHORT (TAB->x);
 #define LOADLONG(x) LOAD(x);  TAB->x = CONV_LONG (TAB->x);
 
-void load_mz_header (int fd, struct mz_header_s *mz_header)
+void load_mz_header (int fd, LPIMAGE_DOS_HEADER mz_header)
 {
 #define TAB mz_header
-	LOAD (mz_magic);
-    LOAD (dont_care);
-    LOADSHORT (ne_offset);
+	LOAD(e_magic);
+	LOADSHORT(e_cblp);
+	LOADSHORT(e_cp);
+	LOADSHORT(e_crlc);
+	LOADSHORT(e_cparhdr);
+	LOADSHORT(e_minalloc);
+	LOADSHORT(e_maxalloc);
+	LOADSHORT(e_ss);
+	LOADSHORT(e_sp);
+	LOADSHORT(e_csum);
+	LOADSHORT(e_ip);
+	LOADSHORT(e_cs);
+	LOADSHORT(e_lfarlc);
+	LOADSHORT(e_ovno);
+	LOAD(e_res);
+	LOADSHORT(e_oemid);
+	LOADSHORT(e_oeminfo);
+	LOAD(e_res2);
+	LOADLONG(e_lfanew);
 }
 
-void load_ne_header (int fd, struct ne_header_s *ne_header)
+void load_ne_header (int fd, LPIMAGE_OS2_HEADER ne_header)
 {
 #undef TAB
 #define TAB ne_header
diff --git a/loader/main.c b/loader/main.c
index 8fd8b5d..24b98a3 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -110,6 +110,9 @@
       /* Initialize communications */
     COMM_Init();
 
+      /* Initialize IO-port permissions */
+    IO_port_init();
+
       /* registry initialisation */
     SHELL_LoadRegistry();
     
diff --git a/loader/module.c b/loader/module.c
index 19bb6d0..8a54aa2 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -38,7 +38,7 @@
 NE_MODULE *MODULE_GetPtr( HMODULE16 hModule )
 {
     NE_MODULE *pModule = (NE_MODULE *)GlobalLock16( hModule );
-    if (!pModule || (pModule->magic != NE_SIGNATURE) ||
+    if (!pModule || (pModule->magic != IMAGE_OS2_SIGNATURE) ||
         (pModule->self != hModule)) return NULL;
     return pModule;
 }
@@ -47,7 +47,7 @@
 /***********************************************************************
  *           MODULE_DumpModule
  */
-void MODULE_DumpModule( HMODULE16 hmodule )
+void MODULE_DumpModule( HMODULE16 hModule )
 {
     int i, ordinal;
     SEGTABLEENTRY *pSeg;
@@ -55,15 +55,15 @@
     WORD *pword;
     NE_MODULE *pModule;
 
-    if (!(pModule = MODULE_GetPtr( hmodule )))
+    if (!(pModule = MODULE_GetPtr( hModule )))
     {
-        fprintf( stderr, "**** %04x is not a module handle\n", hmodule );
+        fprintf( stderr, "**** %04x is not a module handle\n", hModule );
         return;
     }
 
       /* Dump the module info */
 
-    printf( "Module %04x:\n", hmodule );
+    printf( "Module %04x:\n", hModule );
     printf( "count=%d flags=%04x heap=%d stack=%d\n",
             pModule->count, pModule->flags,
             pModule->heap_size, pModule->stack_size );
@@ -364,7 +364,7 @@
     HMODULE16 hModule;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegment;
-    char *pStr;
+    char *pStr,*basename,*s;
 
     INT32 of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName)
                     + strlen(ofs->szPathName) + 1;
@@ -385,7 +385,7 @@
     pModule = (NE_MODULE *)GlobalLock16( hModule );
 
     /* Set all used entries */
-    pModule->magic            = NE_SIGNATURE;
+    pModule->magic            = IMAGE_OS2_SIGNATURE;
     pModule->count            = 1;
     pModule->next             = 0;
     pModule->flags            = 0;
@@ -420,7 +420,19 @@
     /* Module name */
     pStr = (char *)pSegment;
     pModule->name_table = (int)pStr - (int)pModule;
-    strcpy( pStr, "\x08W32SXXXX" );
+    /* strcpy( pStr, "\x08W32SXXXX" ); */
+    basename = strrchr(ofs->szPathName,'\\');
+    if (!basename) 
+	    	basename=ofs->szPathName;
+    else
+	    	basename++;
+    basename=strdup(basename);
+    if ((s=strchr(basename,'.')))
+	    	*s='\0';
+    *pStr = strlen(basename);
+    if (*pStr>8) *pStr=8;
+    strncpy( pStr+1, basename, 8 );
+    free(basename);
     pStr += 9;
 
     /* All tables zero terminated */
@@ -437,8 +449,8 @@
  */
 static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
 {
-    struct mz_header_s mz_header;
-    struct ne_header_s ne_header;
+    IMAGE_DOS_HEADER mz_header;
+    IMAGE_OS2_HEADER ne_header;
     int size;
     HMODULE16 hModule;
     NE_MODULE *pModule;
@@ -456,15 +468,15 @@
 
     _llseek32( hFile, 0, SEEK_SET );
     if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
-        (mz_header.mz_magic != MZ_SIGNATURE))
+        (mz_header.e_magic != IMAGE_DOS_SIGNATURE))
         return (HMODULE16)11;  /* invalid exe */
 
-    _llseek32( hFile, mz_header.ne_offset, SEEK_SET );
+    _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
     if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
         return (HMODULE16)11;  /* invalid exe */
 
-    if (ne_header.ne_magic == PE_SIGNATURE) return (HMODULE16)21;  /* win32 exe */
-    if (ne_header.ne_magic != NE_SIGNATURE) return (HMODULE16)11;  /* invalid exe */
+    if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21;  /* win32 exe */
+    if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11;  /* invalid exe */
 
     /* We now have a valid NE header */
 
@@ -537,7 +549,7 @@
         int i;
         struct ne_segment_table_entry_s *pSeg;
 
-        if (!READ( mz_header.ne_offset + ne_header.segment_tab_offset,
+        if (!READ( mz_header.e_lfanew + ne_header.segment_tab_offset,
              ne_header.n_segment_tab * sizeof(struct ne_segment_table_entry_s),
              buffer ))
         {
@@ -566,7 +578,7 @@
     if (ne_header.resource_tab_offset < ne_header.rname_tab_offset)
     {
         pModule->res_table = (int)pData - (int)pModule;
-        if (!READ(mz_header.ne_offset + ne_header.resource_tab_offset,
+        if (!READ(mz_header.e_lfanew + ne_header.resource_tab_offset,
                   ne_header.rname_tab_offset - ne_header.resource_tab_offset,
                   pData )) return (HMODULE16)11;  /* invalid exe */
         pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset;
@@ -576,7 +588,7 @@
     /* Get the resident names table */
 
     pModule->name_table = (int)pData - (int)pModule;
-    if (!READ( mz_header.ne_offset + ne_header.rname_tab_offset,
+    if (!READ( mz_header.e_lfanew + ne_header.rname_tab_offset,
                ne_header.moduleref_tab_offset - ne_header.rname_tab_offset,
                pData ))
     {
@@ -591,7 +603,7 @@
     if (ne_header.n_mod_ref_tab > 0)
     {
         pModule->modref_table = (int)pData - (int)pModule;
-        if (!READ( mz_header.ne_offset + ne_header.moduleref_tab_offset,
+        if (!READ( mz_header.e_lfanew + ne_header.moduleref_tab_offset,
                   ne_header.n_mod_ref_tab * sizeof(WORD),
                   pData ))
         {
@@ -606,7 +618,7 @@
     /* Get the imported names table */
 
     pModule->import_table = (int)pData - (int)pModule;
-    if (!READ( mz_header.ne_offset + ne_header.iname_tab_offset, 
+    if (!READ( mz_header.e_lfanew + ne_header.iname_tab_offset, 
                ne_header.entry_tab_offset - ne_header.iname_tab_offset,
                pData ))
     {
@@ -619,7 +631,7 @@
     /* Get the entry table */
 
     pModule->entry_table = (int)pData - (int)pModule;
-    if (!READ( mz_header.ne_offset + ne_header.entry_tab_offset,
+    if (!READ( mz_header.e_lfanew + ne_header.entry_tab_offset,
                ne_header.entry_tab_length,
                pData ))
     {
@@ -685,7 +697,7 @@
  */
 WORD MODULE_GetOrdinal( HMODULE16 hModule, const char *name )
 {
-    char buffer[256], *cpnt;
+    unsigned char buffer[256], *cpnt;
     BYTE len;
     NE_MODULE *pModule;
 
@@ -1452,6 +1464,8 @@
     char *p, *cmdline, filename[256];
     static int use_load_module = 1;
 
+    if (!lpCmdLine)
+        return 2;  /* File not found */
     if (!(cmdShowHandle = GlobalAlloc16( 0, 2 * sizeof(WORD) )))
         return 8;  /* Out of memory */
     if (!(cmdLineHandle = GlobalAlloc16( 0, 256 )))
diff --git a/loader/ne_image.c b/loader/ne_image.c
index d5f1e80..1937fdd 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -270,7 +270,7 @@
 	    
 	  default:
 	    dprintf_fixup(stddeb,
-		   "%d: ADDR TYPE %d,  TYPE %d,  OFFSET %04x,  ",
+		   "WARNING: %d: ADDR TYPE %d,  unknown TYPE %d,  OFFSET %04x,  ",
 		   i + 1, rep->address_type, rep->relocation_type, 
 		   rep->offset);
 	    dprintf_fixup(stddeb,"TARGET %04x %04x\n", 
@@ -283,9 +283,9 @@
 
         /* Apparently, high bit of address_type is sometimes set; */
         /* we ignore it for now */
-	if (rep->address_type & 0x80)
-            fprintf( stderr, "Warning: reloc addr type = 0x%02x\n",
-                     rep->address_type );
+	if (rep->address_type > NE_RADDR_OFFSET32)
+            fprintf( stderr, "WARNING: module %s: unknown reloc addr type = 0x%02x. Please report.\n",
+                     MODULE_GetModuleName(hModule), rep->address_type );
 
 	switch (rep->address_type & 0x7f)
 	{
@@ -345,7 +345,7 @@
 	    
 	  default:
 	    dprintf_fixup(stddeb,
-		   "%d: ADDR TYPE %d,  TYPE %d,  OFFSET %04x,  ",
+		   "WARNING: %d: unknown ADDR TYPE %d,  TYPE %d,  OFFSET %04x,  ",
 		   i + 1, rep->address_type, rep->relocation_type, 
 		   rep->offset);
 	    dprintf_fixup(stddeb,
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 1e74f48..0616e6f 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -40,7 +40,7 @@
 
 void dump_exports(IMAGE_EXPORT_DIRECTORY * pe_exports, unsigned int load_addr)
 { 
-  char		*Module,*s;
+  char		*Module;
   int		i;
   u_short	*ordinal;
   u_long	*function,*functions;
@@ -76,7 +76,6 @@
 	  daddr.off=RVA(*functions);
 	  function++;
       }
-      while ((s=strchr(buffer,'.'))) *s='_';
       DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
   }
 }
@@ -360,7 +359,7 @@
  *			PE_LoadImage
  * Load one PE format executable into memory
  */
-static struct pe_data *PE_LoadImage( int fd, HMODULE16 hModule, WORD offset )
+static void PE_LoadImage( struct pr_data **ret_pe, int fd, HMODULE16 hModule, WORD offset, OFSTRUCT *ofs )
 {
 	struct pe_data		*pe;
 	int			i, result;
@@ -368,6 +367,7 @@
 	IMAGE_DATA_DIRECTORY	dir;
 	char			buffer[200];
 	DBG_ADDR		daddr;
+	char			*modname;
 
 	daddr.seg=0;
 	daddr.type = NULL;
@@ -379,6 +379,30 @@
 	lseek( fd, offset, SEEK_SET);
 	read( fd, pe->pe_header, sizeof(IMAGE_NT_HEADERS));
 
+	if (pe->pe_header->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
+		fprintf(stderr,"trying to load PE image for unsupported architecture (");
+		switch (pe->pe_header->FileHeader.Machine) {
+		case IMAGE_FILE_MACHINE_UNKNOWN:
+			fprintf(stderr,"Unknown");break;
+		case IMAGE_FILE_MACHINE_I860:
+			fprintf(stderr,"I860");break;
+		case IMAGE_FILE_MACHINE_R3000:
+			fprintf(stderr,"R3000");break;
+		case IMAGE_FILE_MACHINE_R4000:
+			fprintf(stderr,"R4000");break;
+		case IMAGE_FILE_MACHINE_R10000:
+			fprintf(stderr,"R10000");break;
+		case IMAGE_FILE_MACHINE_ALPHA:
+			fprintf(stderr,"Alpha");break;
+		case IMAGE_FILE_MACHINE_POWERPC:
+			fprintf(stderr,"PowerPC");break;
+		default:
+			fprintf(stderr,"Unknown-%04x",pe->pe_header->FileHeader.Machine);break;
+		}
+		fprintf(stderr,")\n");
+		return;
+	}
+
 /* FIXME: this is a *horrible* hack to make COMDLG32.DLL load OK. The
 problem needs to be fixed properly at some stage */
 
@@ -539,33 +563,39 @@
 		dprintf_win32(stdnimp,"Unknown directory 15 ignored\n");
 
 	if(pe->pe_reloc) do_relocations(pe);
-	if(pe->pe_import) fixup_imports(pe, hModule);
-	if(pe->pe_export) dump_exports(pe->pe_export,load_addr);
-  		
-	if (pe->pe_export) {
-		char	*s;
 
-		/* add start of sections as debugsymbols */
-		for(i=0;i<pe->pe_header->FileHeader.NumberOfSections;i++) {
-			sprintf(buffer,"%s_%s",
-				(char*)RVA(pe->pe_export->Name),
-				pe->pe_seg[i].Name
-			);
-			daddr.off= RVA(pe->pe_seg[i].VirtualAddress);
-      			while ((s=strchr(buffer,'.'))) *s='_';
-			DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-		}
-		/* add entry point */
-		sprintf(buffer,"%s_EntryPoint",(char*)RVA(pe->pe_export->Name));
-		daddr.off=RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
-      		while ((s=strchr(buffer,'.'))) *s='_';
-		DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
-		/* add start of DLL */
-		daddr.off=load_addr;
-		DEBUG_AddSymbol((char*) RVA(pe->pe_export->Name),&daddr,
-				NULL, SYM_WIN32 | SYM_FUNC);
+	/* Do exports before imports because fixup_imports
+	 * may load a module that references this module.
+	 */
+
+	if(pe->pe_export) dump_exports(pe->pe_export,load_addr);
+	*ret_pe = pe;	/* make export list available for GetProcAddress */
+	if(pe->pe_import) fixup_imports(pe, hModule);
+  		
+	if (pe->pe_export)
+		modname = (char*)RVA(pe->pe_export->Name);
+	else {
+		char *s;
+		modname = s = ofs->szPathName;
+		while (s=strchr(modname,'\\'))
+			modname = s+1;
+		if ((s=strchr(modname,'.')))
+			*s='\0';
 	}
-        return pe;
+
+	/* add start of sections as debugsymbols */
+	for(i=0;i<pe->pe_header->FileHeader.NumberOfSections;i++) {
+		sprintf(buffer,"%s_%s",modname,pe->pe_seg[i].Name);
+		daddr.off= RVA(pe->pe_seg[i].VirtualAddress);
+		DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
+	}
+	/* add entry point */
+	sprintf(buffer,"%s_EntryPoint",modname);
+	daddr.off=RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
+	DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
+	/* add start of DLL */
+	daddr.off=load_addr;
+	DEBUG_AddSymbol(modname,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
 }
 
 HINSTANCE16 MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params);
@@ -575,7 +605,7 @@
     HMODULE16 hModule;
     HINSTANCE16 hInstance;
     NE_MODULE *pModule;
-    struct mz_header_s mz_header;
+    IMAGE_DOS_HEADER mz_header;
     int fd;
 
     if ((hModule = MODULE_CreateDummyModule( ofs )) < 32) return hModule;
@@ -588,7 +618,9 @@
     lseek( fd, 0, SEEK_SET );
     read( fd, &mz_header, sizeof(mz_header) );
 
-    pModule->pe_module = PE_LoadImage( fd, hModule, mz_header.ne_offset );
+    PE_LoadImage( &pModule->pe_module, fd, hModule, mz_header.e_lfanew, ofs );
+    if (!pModule->pe_module)
+    	return 21;
     close( fd );
 
     hInstance = MODULE_CreateInstance( hModule, params );
diff --git a/loader/task.c b/loader/task.c
index 8ada240..899e577 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -28,6 +28,7 @@
 #include "thread.h"
 #include "toolhelp.h"
 #include "winnt.h"
+#include "thread.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "dde_proc.h"
@@ -71,14 +72,20 @@
 static HGLOBAL16 TASK_CreateDOSEnvironment(void);
 static void	 TASK_YieldToSystem(TDB*);
 
+static THDB TASK_SystemTHDB;
 /***********************************************************************
  *           TASK_Init
  */
 BOOL32 TASK_Init(void)
 {
+
     TASK_RescheduleProc = MODULE_GetWndProcEntry16( "TASK_Reschedule" );
     if (!(hDOSEnvironment = TASK_CreateDOSEnvironment()))
         fprintf( stderr, "Not enough memory for DOS Environment\n" );
+    TASK_SystemTHDB.teb_sel = SELECTOR_AllocBlock( &TASK_SystemTHDB, 0x1000, SEGMENT_DATA, TRUE, FALSE );
+#ifndef WINELIB
+    __asm__ __volatile__("movw %w0,%%fs"::"r"(TASK_SystemTHDB.teb_sel));
+#endif
     return (hDOSEnvironment != 0);
 }
 
@@ -1429,13 +1436,13 @@
       /* Check for module handle */
 
     if (!(ptr = GlobalLock16( handle ))) return 0;
-    if (((NE_MODULE *)ptr)->magic == NE_SIGNATURE) return handle;
+    if (((NE_MODULE *)ptr)->magic == IMAGE_OS2_SIGNATURE) return handle;
 
       /* Check the owner for module handle */
 
     owner = FarGetOwner( handle );
     if (!(ptr = GlobalLock16( owner ))) return 0;
-    if (((NE_MODULE *)ptr)->magic == NE_SIGNATURE) return owner;
+    if (((NE_MODULE *)ptr)->magic == IMAGE_OS2_SIGNATURE) return owner;
 
       /* Search for this handle and its owner inside all tasks */
 
diff --git a/memory/virtual.c b/memory/virtual.c
index 2e3a6c0..2aa42ba 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
@@ -373,16 +374,28 @@
 
 #ifdef linux
     {
-	FILE *f = fopen( "/proc/self/maps", "r" );
-        if (f)
+        /* Do not use stdio here since it may temporarily change the size
+         * of some segments (ie libc6 adds 0x1000 per open FILE)
+         */
+        int fd = open ("/proc/self/maps", O_RDONLY);
+        if (fd >= 0)
         {
             char buffer[80];
-            while (fgets( buffer, sizeof(buffer), f ))
+
+            for (;;)
             {
                 int start, end, offset;
                 char r, w, x, p;
                 BYTE vprot = VPROT_COMMITTED;
 
+                char * ptr = buffer;
+                int count = sizeof(buffer);
+                while (1 == read(fd, ptr, 1) && *ptr != '\n' && --count > 0)
+                    ptr++;
+
+                if (*ptr != '\n') break;
+                *ptr = '\0';
+
                 sscanf( buffer, "%x-%x %c%c%c%c %x",
                         &start, &end, &r, &w, &x, &p, &offset );
                 if (r == 'r') vprot |= VPROT_READ;
@@ -392,7 +405,7 @@
                 VIRTUAL_CreateView( start, end - start, 0,
                                     VFLAG_SYSTEM, vprot, NULL );
             }
-            fclose( f );
+            close (fd);
         }
     }
 #endif  /* linux */
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 1d16edb..08b87e1 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -11,6 +11,7 @@
 	compobj.c \
 	crtdll.c \
 	cpu.c \
+	error.c \
 	lstr.c \
 	lzexpand.c \
 	main.c \
diff --git a/misc/comm.c b/misc/comm.c
index adf2197..9572070 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -4,6 +4,13 @@
  * Copyright 1996 Marcus Meissner
  * FIXME: use HFILEs instead of unixfds
  *	  the win32 functions here get HFILEs already.
+ *
+ * May 26, 1997.  Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
+ * - ptr->fd wasn't getting cleared on close.
+ * - GetCommEventMask() and GetCommError() didn't do much of anything.
+ *   IMHO, they are still wrong, but they at least implement the RXCHAR
+ *   event and return I/O queue sizes, which makes the app I'm interested
+ *   in (analog devices EZKIT DSP development system) work.
  */
 
 #include <stdio.h>
@@ -16,6 +23,8 @@
 #include <sys/stat.h>
 #if defined(__NetBSD__) || defined(__FreeBSD__)
 #include <sys/ioctl.h>
+#else
+#include <sys/ioctl.h>
 #endif
 #include <unistd.h>
 
@@ -27,6 +36,10 @@
 #include "debug.h"
 #include "handle32.h"
 
+/*
+ * [RER] These are globals are wrong.  They should be in DosDeviceStruct
+ * on a per port basis.
+ */
 int commerror = 0, eventmask = 0;
 
 struct DosDeviceStruct COM[MAX_PORTS];
@@ -445,7 +458,16 @@
  */
 INT16 CloseComm(INT16 fd)
 {
+	struct DosDeviceStruct *ptr;
+
     	dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return -1;
+	}
+
+	ptr->fd = 0;	/* [RER] Really, -1 would be a better value */
+
 	if (close(fd) == -1) {
 		commerror = WinError();
 		return -1;
@@ -709,10 +731,26 @@
  */
 INT16 GetCommError(INT16 fd,LPCOMSTAT lpStat)
 {
-	int temperror;
+	int		temperror;
+	unsigned long	cnt;
+	int		rc;
+
+	lpStat->status = 0;
+
+	rc = ioctl(fd, TIOCOUTQ, &cnt);
+	lpStat->cbOutQue = cnt;
+
+	rc = ioctl(fd, TIOCINQ, &cnt);
+	lpStat->cbInQue = cnt;
 
     	dprintf_comm(stddeb,
-		"GetCommError: fd %d (current error %d)\n", fd, commerror);
+		"GetCommError: fd %d, error %d, lpStat %d %d %d\n",
+		fd, commerror,
+		lpStat->status, lpStat->cbInQue, lpStat->cbOutQue);
+	/*
+	 * [RER] I have no idea what the following is trying to accomplish.
+	 * [RER] It is certainly not what the reference manual suggests.
+	 */
 	temperror = commerror;
 	commerror = 0;
 	return(temperror);
@@ -747,10 +785,43 @@
  */
 UINT16 GetCommEventMask(INT16 fd,UINT16 fnEvtClear)
 {
+	int	events = 0;
+
     	dprintf_comm(stddeb,
 		"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
+
+	/*
+	 *	Determine if any characters are available
+	 */
+	if (fnEvtClear & EV_RXCHAR)
+	{
+		int		rc;
+		unsigned long	cnt;
+
+		rc = ioctl(fd, TIOCINQ, &cnt);
+		if (cnt) events |= EV_RXCHAR;
+
+		dprintf_comm(stddeb,
+			"GetCommEventMask: rxchar %ld\n", cnt);
+	}
+
+	/*
+	 *	There are other events that need to be checked for
+	 */
+	/* TODO */
+
+	dprintf_comm(stddeb,
+		"GetCommEventMask: return events %d\n", events);
+	return events;
+
+	/*
+	 * [RER] The following was gibberish
+	 */
+#if 0
+	tempmask = eventmask;
 	eventmask &= ~fnEvtClear;
 	return eventmask;
+#endif
 }
 
 /*****************************************************************************
diff --git a/misc/error.c b/misc/error.c
new file mode 100644
index 0000000..f4f2837
--- /dev/null
+++ b/misc/error.c
@@ -0,0 +1,165 @@
+/*
+ * Log internal errors 
+ *
+ * Copyright 1997 Andrew Taylor
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "windows.h"
+#include "stddebug.h"
+#include "debug.h"
+
+#ifdef DEBUG_RUNTIME
+
+#define ErrorString(manifest) { manifest, # manifest }
+
+const struct {
+	int constant;
+	const char *name;
+} ErrorStrings[] = {
+
+	ErrorString(ERR_GALLOC),
+	ErrorString(ERR_GREALLOC),
+	ErrorString(ERR_GLOCK),
+	ErrorString(ERR_LALLOC),
+	ErrorString(ERR_LREALLOC),
+	ErrorString(ERR_LLOCK),
+	ErrorString(ERR_ALLOCRES),
+	ErrorString(ERR_LOCKRES),
+	ErrorString(ERR_LOADMODULE),
+	ErrorString(ERR_CREATEDLG),
+	ErrorString(ERR_CREATEDLG2),
+	ErrorString(ERR_REGISTERCLASS),
+	ErrorString(ERR_DCBUSY),
+	ErrorString(ERR_CREATEWND),
+	ErrorString(ERR_STRUCEXTRA),
+	ErrorString(ERR_LOADSTR),
+	ErrorString(ERR_LOADMENU),
+	ErrorString(ERR_NESTEDBEGINPAINT),
+	ErrorString(ERR_BADINDEX),
+	ErrorString(ERR_CREATEMENU),
+	ErrorString(ERR_CREATEDC),
+	ErrorString(ERR_CREATEMETA),
+	ErrorString(ERR_DELOBJSELECTED),
+	ErrorString(ERR_SELBITMAP)
+};
+
+#define ErrorStringCount (sizeof(ErrorStrings) / sizeof(ErrorStrings[0]))
+
+const struct {
+	int constant;
+	const char *name;
+} ParamErrorStrings[] = {
+
+	ErrorString(ERR_BAD_VALUE),
+	ErrorString(ERR_BAD_FLAGS),
+	ErrorString(ERR_BAD_INDEX),
+	ErrorString(ERR_BAD_DVALUE),
+	ErrorString(ERR_BAD_DFLAGS),
+	ErrorString(ERR_BAD_DINDEX),
+	ErrorString(ERR_BAD_PTR),
+	ErrorString(ERR_BAD_FUNC_PTR),
+	ErrorString(ERR_BAD_SELECTOR),
+	ErrorString(ERR_BAD_STRING_PTR),
+	ErrorString(ERR_BAD_HANDLE),
+	ErrorString(ERR_BAD_HINSTANCE),
+	ErrorString(ERR_BAD_HMODULE),
+	ErrorString(ERR_BAD_GLOBAL_HANDLE),
+	ErrorString(ERR_BAD_LOCAL_HANDLE),
+	ErrorString(ERR_BAD_ATOM),
+	ErrorString(ERR_BAD_HFILE),
+	ErrorString(ERR_BAD_HWND),
+	ErrorString(ERR_BAD_HMENU),
+	ErrorString(ERR_BAD_HCURSOR),
+	ErrorString(ERR_BAD_HICON),
+	ErrorString(ERR_BAD_HDWP),
+	ErrorString(ERR_BAD_CID),
+	ErrorString(ERR_BAD_HDRVR),
+	ErrorString(ERR_BAD_COORDS),
+	ErrorString(ERR_BAD_GDI_OBJECT),
+	ErrorString(ERR_BAD_HDC),
+	ErrorString(ERR_BAD_HPEN),
+	ErrorString(ERR_BAD_HFONT),
+	ErrorString(ERR_BAD_HBRUSH),
+	ErrorString(ERR_BAD_HBITMAP),
+	ErrorString(ERR_BAD_HRGN),
+	ErrorString(ERR_BAD_HPALETTE),
+	ErrorString(ERR_BAD_HMETAFILE)
+};
+
+#define ParamErrorStringCount (sizeof(ParamErrorStrings) / sizeof(ParamErrorStrings[0]))
+
+#endif /* DEBUG_RUNTIME */
+
+/***********************************************************************
+*	GetErrorString (internal)
+*/
+static const char *GetErrorString(UINT16 uErr) {
+	static char buffer[80];
+
+#ifdef DEBUG_RUNTIME
+	int i;
+
+	for (i = 0; i < ErrorStringCount; i++) {
+		if (uErr == ErrorStrings[i].constant)
+			return ErrorStrings[i].name;
+	}
+#endif
+
+	sprintf(buffer, "%x", uErr);
+	return buffer;
+}
+
+
+/***********************************************************************
+*	GetParamErrorString (internal)
+*/
+static const char *GetParamErrorString(UINT16 uErr) {
+	static char buffer[80];
+
+	if (uErr & ERR_WARNING) {
+		strcpy(buffer, "ERR_WARNING | ");
+		uErr &= ~ERR_WARNING;
+	} else
+		buffer[0] = '\0';
+
+#ifdef DEBUG_RUNTIME
+	{
+		int i;
+
+		for (i = 0; i < ParamErrorStringCount; i++) {
+			if (uErr == ParamErrorStrings[i].constant) {
+				strcat(buffer, ParamErrorStrings[i].name);
+				return buffer;
+			}
+		}
+	}
+#endif
+
+	sprintf(buffer + strlen(buffer), "%x", uErr);
+	return buffer;
+}
+
+
+/***********************************************************************
+*	LogError (KERNEL.324)
+*/
+VOID LogError(UINT16 uErr, LPVOID lpvInfo) {
+	fprintf(stddeb, "LogError(%s, %p)\n", 
+		GetErrorString(uErr), lpvInfo);
+}
+
+
+/***********************************************************************
+*	LogParamError (KERNEL.325)
+*/
+void LogParamError(UINT16 uErr, FARPROC16 lpfn, LPVOID lpvParam) {
+	/* FIXME: is it possible to get the module name/function
+	 * from the lpfn param?
+	 */
+	fprintf(stddeb, "LogParamError(%s, %p, %p)\n", 
+		GetParamErrorString(uErr), lpfn, lpvParam);
+}
diff --git a/misc/lstr.c b/misc/lstr.c
index 7f565ca..7228e67 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -534,10 +534,11 @@
 		while (*f) {
 			if (*f=='%') {
 				int	insertnr;
-				char	*fmtstr,*sprintfbuf,*x;
+				char	*fmtstr,*sprintfbuf,*x,*lastf;
 				DWORD	*argliststart;
 
 				fmtstr = NULL;
+				lastf = f;
 				f++;
 				if (!*f) {
 					ADD_TO_T('%');
@@ -573,26 +574,35 @@
 						}
 					} else
 						fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
-					if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
-						argliststart=args+insertnr-1;
-					else
-						/* FIXME: not sure that this is
-						 * correct for unix-c-varargs.
+					if (args) {
+						if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
+							argliststart=args+insertnr-1;
+						else
+							/* FIXME: not sure that this is
+							 * correct for unix-c-varargs.
+							 */
+							argliststart=((DWORD*)&args)+insertnr-1;
+
+						if (fmtstr[strlen(fmtstr)]=='s')
+							sprintfbuf=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1);
+						else
+							sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
+
+						/* CMF - This makes a BIG assumption about va_list */
+						vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
+						x=sprintfbuf;
+						while (*x) {
+							ADD_TO_T(*x++);
+						}
+						HeapFree(GetProcessHeap(),0,sprintfbuf);
+					} else {
+						/* NULL args - copy formatstr 
+						 * (probably wrong)
 						 */
-						argliststart=((DWORD*)&args)+insertnr-1;
-
-					if (fmtstr[strlen(fmtstr)]=='s')
-						sprintfbuf=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1);
-					else
-						sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
-
-					/* CMF - This makes a BIG assumption about va_list */
-					vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
-					x=sprintfbuf;
-					while (*x) {
-						ADD_TO_T(*x++);
+						while (lastf<f) {
+							ADD_TO_T(*lastf++);
+						}
 					}
-					HeapFree(GetProcessHeap(),0,sprintfbuf);
 					HeapFree(GetProcessHeap(),0,fmtstr);
 					break;
 				case 'n':
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 48d67e4..384096e 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -204,7 +204,7 @@
  */
 INT16 GetExpandedName16( LPCSTR in, LPSTR out )
 {
-    return GetExpandedName32A( in, out );
+    return (INT16)GetExpandedName32A( in, out );
 }
 
 
@@ -230,17 +230,16 @@
 	dprintf_file(stddeb,"GetExpandedName(%s)\n",in);
 	fd=OpenFile32(in,&ofs,OF_READ);
 	if (fd==HFILE_ERROR32)
-		return LZERROR_BADINHANDLE;
+		return (INT32)(INT16)LZERROR_BADINHANDLE;
+	strcpy(out,in);
 	ret=read_header(fd,&head);
 	if (ret<=0) {
+		/* not a LZ compressed file, so the expanded name is the same
+		 * as the input name */
 		_lclose32(fd);
-		return LZERROR_BADINHANDLE;
+		return 1;
 	}
 
-	/* This line will crash if the caller hasn't allocated enough memory
-	 * for us.
-	 */
-	strcpy(out,in);
 
 	/* look for directory prefix and skip it. */
 	s=out;
diff --git a/misc/main.c b/misc/main.c
index 57832ad..84ab9cf 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -817,6 +817,8 @@
     fprintf(stderr, "Unknown mode set? This shouldn't happen. Check GetWinFlags()!\n");
     break;
   }
+  if (si.wProcessorLevel>=4)
+      result |= WF_HASCPUID;
   if( getVersionEx.dwPlatformId == VER_PLATFORM_WIN32_NT )
       result |= WF_WIN32WOW; /* undocumented WF_WINNT */
   return result;
@@ -1060,9 +1062,12 @@
 
 	        case SPI_GETICONTITLELOGFONT: 
 	        {
-                    /* FIXME GetProfileString32A( "?", "?", "?" ) */
                     LPLOGFONT16 lpLogFont = (LPLOGFONT16)lpvParam;
-                    lpLogFont->lfHeight = 10;
+
+		    GetProfileString32A("Desktop", "IconTitleFaceName", "Helvetica", 
+					lpLogFont->lfFaceName, LF_FACESIZE );
+                    lpLogFont->lfHeight = -GetProfileInt32A("Desktop","IconTitleSize", 8);
+
                     lpLogFont->lfWidth = 0;
                     lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
                     lpLogFont->lfWeight = FW_NORMAL;
diff --git a/misc/mpr.c b/misc/mpr.c
index 62f9f85..6c7b674 100644
--- a/misc/mpr.c
+++ b/misc/mpr.c
@@ -21,3 +21,15 @@
 	);
 	return 0;
 }
+
+DWORD
+MultinetGetConnectionPerformance32A(
+	LPNETRESOURCE32A lpNetResource,
+	LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct
+) {
+	fprintf(stdnimp,"MultinetGetConnectionPerformance(%p,%p)\n",
+			lpNetResource,
+			lpNetConnectInfoStruct
+	);
+	return 1;
+}
diff --git a/misc/printdrv.c b/misc/printdrv.c
index 64e44f9..9583c38 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -40,7 +40,7 @@
 DrvGetPrinterData(LPSTR lpPrinter, LPSTR lpProfile, LPDWORD lpType,
                   LPBYTE lpPrinterData, int cbData, LPDWORD lpNeeded)
 {
-    fprintf(stderr,"In DrvGetPrinterData printer %s profile %s lpType %p \n",
+    fprintf(stderr,"In DrvGetPrinterData printer %p profile %p lpType %p \n",
            lpPrinter, lpProfile, lpType);
     return 0;
 }
@@ -51,7 +51,7 @@
 DrvSetPrinterData(LPSTR lpPrinter, LPSTR lpProfile, LPDWORD lpType,
                   LPBYTE lpPrinterData, DWORD dwSize)
 {
-    fprintf(stderr,"In DrvSetPrinterData printer %s profile %s lpType %p \n",
+    fprintf(stderr,"In DrvSetPrinterData printer %p profile %p lpType %p \n",
            lpPrinter, lpProfile, lpType);
     return 0;
 }
diff --git a/misc/shell.c b/misc/shell.c
index f67ca32..041fc8b 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -476,23 +476,23 @@
 static BYTE* SHELL_GetResourceTable(HFILE32 hFile)
 {
   BYTE*              pTypeInfo = NULL;
-  struct mz_header_s mz_header;
-  struct ne_header_s ne_header;
+  IMAGE_DOS_HEADER	mz_header;
+  IMAGE_OS2_HEADER	ne_header;
   int		     size;
   
   _llseek32( hFile, 0, SEEK_SET );
   if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
-      (mz_header.mz_magic != MZ_SIGNATURE)) return (BYTE*)-1;
+      (mz_header.e_magic != IMAGE_DOS_SIGNATURE)) return (BYTE*)-1;
 
-  _llseek32( hFile, mz_header.ne_offset, SEEK_SET );
+  _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
   if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
       return NULL;
 
-  if (ne_header.ne_magic == PE_SIGNATURE) 
+  if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) 
      { fprintf(stdnimp,"Win32s FIXME: file %s line %i\n", __FILE__, __LINE__ );
        return NULL; }
 
-  if (ne_header.ne_magic != NE_SIGNATURE) return NULL;
+  if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return NULL;
 
   size = ne_header.rname_tab_offset - ne_header.resource_tab_offset;
 
@@ -501,7 +501,7 @@
       pTypeInfo = (BYTE*)HeapAlloc( GetProcessHeap(), 0, size);
       if( pTypeInfo ) 
       {
-          _llseek32(hFile, mz_header.ne_offset+ne_header.resource_tab_offset, SEEK_SET);
+          _llseek32(hFile, mz_header.e_lfanew+ne_header.resource_tab_offset, SEEK_SET);
           if( _lread32( hFile, (char*)pTypeInfo, size) != size )
           { 
 	      HeapFree( GetProcessHeap(), 0, pTypeInfo); 
diff --git a/misc/spy.c b/misc/spy.c
index 3216f4a..65490b9 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -508,15 +508,41 @@
           NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
     "WM_COALESCE_LAST", 
+    
+    /* 0x03a0 */
+    "MM_JOY1MOVE", 
+    "MM_JOY2MOVE", 
+    "MM_JOY1ZMOVE", 
+    "MM_JOY2ZMOVE", 
+                            NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    /* 0x03b0 */
+    NULL, NULL, NULL, NULL, NULL, 
+    "MM_JOY1BUTTONDOWN", 
+    "MM_JOY2BUTTONDOWN", 
+    "MM_JOY1BUTTONUP",
+    "MM_JOY2BUTTONUP",
+    "MM_MCINOTIFY",
+                NULL, 
+    "MM_WOM_OPEN",
+    "MM_WOM_CLOSE",
+    "MM_WOM_DONE",
+    "MM_WIM_OPEN",
+    "MM_WIM_CLOSE",
 
     /* 0x03c0 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "MM_WIM_DATA",
+    "MM_MIM_OPEN",
+    "MM_MIM_CLOSE",
+    "MM_MIM_DATA",
+    "MM_MIM_LONGDATA",
+    "MM_MIM_ERROR",
+    "MM_MIM_LONGERROR",
+    "MM_MOM_OPEN",
+    "MM_MOM_CLOSE",
+    "MM_MOM_DONE",
+                NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
@@ -666,7 +692,7 @@
 int SPY_Init(void)
 {
     int i;
-    char buffer[512];
+    char buffer[1024];
 
     PROFILE_GetWineIniString( "Spy", "Include", "", buffer, sizeof(buffer) );
     if (buffer[0] && strcmp( buffer, "INCLUDEALL" ))
diff --git a/misc/ver.c b/misc/ver.c
index bd3d0b2..70690b8 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
+#include <unistd.h>
 #include "windows.h"
 #include "win.h"
 #include "winerror.h"
@@ -24,19 +25,156 @@
   if (sizeof(*what)!=LZRead32(lzfd,what,sizeof(*what))) return 0;
 #define LZTELL(lzfd) LZSeek32(lzfd, 0, SEEK_CUR);
 
+/******************************************************************************
+ *
+ *   void  dprintf_ver_string(
+ *      char const * prologue,
+ *      char const * teststring,
+ *      char const * epilogue )
+ *
+ *   This function will print via dprintf_ver to stddeb the prologue string,
+ *   followed by the address of teststring and the string it contains if
+ *   teststring is non-null or "(null)" otherwise, and then the epilogue
+ *   string.
+ *
+ *   Revision history
+ *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
+ *         Original implementation
+ *
+ *****************************************************************************/
+
+static void  dprintf_ver_string(
+    char const * prologue,
+    char const * teststring,
+    char const * epilogue )
+{
+    dprintf_ver(stddeb, "%s", prologue);
+    
+    if(teststring)
+	dprintf_ver(stddeb, "%p (\"%s\")", (void const *) teststring,
+		    teststring);
+    else
+	dprintf_ver(stddeb, "(null)");
+
+    dprintf_ver(stddeb, "%s", epilogue);
+
+    return;
+}
+
+/******************************************************************************
+ *
+ *   int  testFileExistence(
+ *      char const * path,
+ *      char const * file )
+ *
+ *   Tests whether a given path/file combination exists.  If the file does
+ *   not exist, the return value is zero.  If it does exist, the return
+ *   value is non-zero.
+ *
+ *   Revision history
+ *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
+ *         Original implementation
+ *
+ *****************************************************************************/
+
+static int  testFileExistence(
+   char const * path,
+   char const * file )
+{
+    char  filename[1024];
+    int  filenamelen;
+    OFSTRUCT  fileinfo;
+    int  retval;
+
+    fileinfo.cBytes = sizeof(OFSTRUCT);
+
+    strcpy(filename, path);
+    filenamelen = strlen(filename);
+
+    /* Add a trailing \ if necessary */
+    if(filenamelen) {
+	if(filename[filenamelen - 1] != '\\')
+	    strcat(filename, "\\");
+    }
+    else /* specify the current directory */
+	strcpy(filename, ".\\");
+
+    /* Create the full pathname */
+    strcat(filename, file);
+
+    if(OpenFile32(filename, &fileinfo, OF_EXIST) == HFILE_ERROR32)
+	retval = 0;
+    else
+	retval = 1;
+
+    return  retval;
+}
+
+/******************************************************************************
+ *
+ *   int  testFileExclusiveExistence(
+ *      char const * path,
+ *      char const * file )
+ *
+ *   Tests whether a given path/file combination exists and ensures that no
+ *   other programs have handles to the given file.  If the file does not
+ *   exist or is open, the return value is zero.  If it does exist, the
+ *   return value is non-zero.
+ *
+ *   Revision history
+ *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
+ *         Original implementation
+ *
+ *****************************************************************************/
+
+static int  testFileExclusiveExistence(
+   char const * path,
+   char const * file )
+{
+    char  filename[1024];
+    int  filenamelen;
+    OFSTRUCT  fileinfo;
+    int  retval;
+
+    fileinfo.cBytes = sizeof(OFSTRUCT);
+
+    strcpy(filename, path);
+    filenamelen = strlen(filename);
+
+    /* Add a trailing \ if necessary */
+    if(filenamelen) {
+	if(filename[filenamelen - 1] != '\\')
+	    strcat(filename, "\\");
+    }
+    else /* specify the current directory */
+	strcpy(filename, ".\\");
+
+    /* Create the full pathname */
+    strcat(filename, file);
+
+    if(OpenFile32(filename, &fileinfo, OF_EXIST | OF_SHARE_EXCLUSIVE) ==
+       HFILE_ERROR32)
+	retval = 0;
+    else
+	retval = 1;
+
+    return retval;
+}
+
+
 int
-read_ne_header(HFILE32 lzfd,struct ne_header_s *nehd) {
-	struct	mz_header_s	mzh;
+read_ne_header(HFILE32 lzfd,LPIMAGE_OS2_HEADER nehd) {
+	IMAGE_DOS_HEADER	mzh;
 
 	LZSeek32(lzfd,0,SEEK_SET);
 	if (sizeof(mzh)!=LZRead32(lzfd,&mzh,sizeof(mzh)))
 		return 0;
-	if (mzh.mz_magic!=MZ_SIGNATURE)
+	if (mzh.e_magic!=IMAGE_DOS_SIGNATURE)
 		return 0;
-	LZSeek32(lzfd,mzh.ne_offset,SEEK_SET);
+	LZSeek32(lzfd,mzh.e_lfanew,SEEK_SET);
 	LZREAD(nehd);
-	if (nehd->ne_magic == NE_SIGNATURE) {
-		LZSeek32(lzfd,mzh.ne_offset,SEEK_SET);
+	if (nehd->ne_magic == IMAGE_OS2_SIGNATURE) {
+		LZSeek32(lzfd,mzh.e_lfanew,SEEK_SET);
 		return 1;
 	}
 	fprintf(stderr,"misc/ver.c:read_ne_header:can't handle PE files yet.\n");
@@ -47,7 +185,7 @@
 
 int
 find_ne_resource(
-	HFILE32 lzfd,struct ne_header_s *nehd,SEGPTR typeid,SEGPTR resid,
+	HFILE32 lzfd,LPIMAGE_OS2_HEADER nehd,SEGPTR typeid,SEGPTR resid,
 	BYTE **resdata,int *reslen,DWORD *off
 ) {
 	NE_TYPEINFO	ti;
@@ -164,11 +302,11 @@
 /* GetFileResourceSize				[VER.2] */
 DWORD
 GetFileResourceSize(LPCSTR filename,SEGPTR restype,SEGPTR resid,LPDWORD off) {
-	HFILE32	lzfd;
-	OFSTRUCT	ofs;
-	BYTE	*resdata;
-	int	reslen;
-	struct	ne_header_s	nehd;
+	HFILE32			lzfd;
+	OFSTRUCT		ofs;
+	BYTE			*resdata;
+	int			reslen;
+	IMAGE_OS2_HEADER	nehd;
 
 	dprintf_ver(stddeb,"GetFileResourceSize(%s,%lx,%lx,%p)\n",
 		filename,(LONG)restype,(LONG)resid,off
@@ -194,11 +332,11 @@
 GetFileResource(LPCSTR filename,SEGPTR restype,SEGPTR resid,
 		DWORD off,DWORD datalen,LPVOID data
 ) {
-	HFILE32	lzfd;
-	OFSTRUCT	ofs;
-	BYTE	*resdata;
-	int	reslen=datalen;
-	struct	ne_header_s	nehd;
+	HFILE32			lzfd;
+	OFSTRUCT		ofs;
+	BYTE			*resdata;
+	int			reslen=datalen;
+	IMAGE_OS2_HEADER	nehd;
 	dprintf_ver(stddeb,"GetFileResource(%s,%lx,%lx,%ld,%ld,%p)\n",
 		filename,(LONG)restype,(LONG)resid,off,datalen,data
 	);
@@ -380,20 +518,175 @@
     return ret;
 }
 
-/* VerFindFile				[VER.8] */
-DWORD
-VerFindFile16(
-	UINT16 flags,LPCSTR filename,LPCSTR windir,LPCSTR appdir,
-	LPSTR curdir,UINT16 *curdirlen,LPSTR destdir,UINT16 *destdirlen
-) {
-	dprintf_ver(stddeb,"VerFindFile(%x,%s,%s,%s,%p,%d,%p,%d)\n",
-		flags,filename,windir,appdir,curdir,*curdirlen,destdir,*destdirlen
-	);
-	strcpy(curdir,"Z:\\ROOT\\.WINE\\");/*FIXME*/
-	*curdirlen=strlen(curdir);
-	strcpy(destdir,"Z:\\ROOT\\.WINE\\");/*FIXME*/
-	*destdirlen=strlen(destdir);
-	return 0;
+/*****************************************************************************
+ *
+ *   VerFindFile() [VER.8]
+ *   Determines where to install a file based on whether it locates another
+ *   version of the file in the system.  The values VerFindFile returns are
+ *   used in a subsequent call to the VerInstallFile function.
+ *
+ *   Revision history:
+ *      30-May-1997   Dave Cuthbert (dacut@ece.cmu.edu)
+ *         Reimplementation of VerFindFile from original stub.
+ *
+ ****************************************************************************/
+
+DWORD VerFindFile16(
+    UINT16 flags,
+    LPCSTR lpszFilename,
+    LPCSTR lpszWinDir,
+    LPCSTR lpszAppDir,
+    LPSTR lpszCurDir,
+    UINT16 *lpuCurDirLen,
+    LPSTR lpszDestDir,
+    UINT16 *lpuDestDirLen )
+{
+    DWORD  retval;
+    char  curDir[256];
+    char  destDir[256];
+    unsigned int  curDirSizeReq;
+    unsigned int  destDirSizeReq;
+
+    retval = 0;
+
+    /* Print out debugging information */
+    dprintf_ver(stddeb, "VerFindFile() called with parameters:\n"
+		"\tflags = %x", flags);
+    if(flags & VFFF_ISSHAREDFILE)
+	dprintf_ver(stddeb, " (VFFF_ISSHAREDFILE)\n");
+    else
+	dprintf_ver(stddeb, "\n");
+
+    dprintf_ver_string("\tlpszFilename = ", lpszFilename, "\n");
+    dprintf_ver_string("\tlpszWinDir = ", lpszWinDir, "\n");
+    dprintf_ver_string("\tlpszAppDir = ", lpszAppDir, "\n");
+
+    dprintf_ver(stddeb, "\tlpszCurDir = %p\n", lpszCurDir);
+    if(lpuCurDirLen)
+	dprintf_ver(stddeb, "\tlpuCurDirLen = %p (%u)\n",
+		    lpuCurDirLen, *lpuCurDirLen);
+    else
+	dprintf_ver(stddeb, "\tlpuCurDirLen = (null)\n");
+
+    dprintf_ver(stddeb, "\tlpszDestDir = %p\n", lpszDestDir);
+    if(lpuDestDirLen)
+	dprintf_ver(stddeb, "\tlpuDestDirLen = %p (%u)\n",
+		    lpuDestDirLen, *lpuDestDirLen);
+
+    /* Figure out where the file should go; shared files default to the
+       system directory */
+
+    strcpy(curDir, "");
+    strcpy(destDir, "");
+
+    if(flags & VFFF_ISSHAREDFILE && !getuid()) {
+	GetSystemDirectory32A(destDir, 256);
+
+	/* Were we given a filename?  If so, try to find the file. */
+	if(lpszFilename) {
+	    if(testFileExistence(destDir, lpszFilename)) {
+		strcpy(curDir, destDir);
+
+		if(!testFileExclusiveExistence(destDir, lpszFilename))
+		    retval |= VFF_FILEINUSE;
+	    }
+	    else if(lpszAppDir && testFileExistence(lpszAppDir,
+						    lpszFilename)) {
+		strcpy(curDir, lpszAppDir);
+		retval |= VFF_CURNEDEST;
+
+		if(!testFileExclusiveExistence(lpszAppDir, lpszFilename))
+		    retval |= VFF_FILEINUSE;
+	    }
+	}
+    }
+    else if(!(flags & VFFF_ISSHAREDFILE)) { /* not a shared file */
+	if(lpszAppDir) {
+	    char  systemDir[256];
+	    GetSystemDirectory32A(systemDir, 256);
+
+	    strcpy(destDir, lpszAppDir);
+
+	    if(lpszFilename) {
+		if(testFileExistence(lpszAppDir, lpszFilename)) {
+		    strcpy(curDir, lpszAppDir);
+
+		    if(!testFileExclusiveExistence(lpszAppDir, lpszFilename))
+			retval |= VFF_FILEINUSE;
+		}
+		else if(testFileExistence(systemDir, lpszFilename)) {
+		    strcpy(curDir, systemDir);
+		    retval |= VFF_CURNEDEST;
+
+		    if(!testFileExclusiveExistence(systemDir, lpszFilename))
+			retval |= VFF_FILEINUSE;
+		}
+	    }
+	}
+    }
+
+    curDirSizeReq = strlen(curDir) + 1;
+    destDirSizeReq = strlen(destDir) + 1;
+
+
+
+    /* Make sure that the pointers to the size of the buffers are
+       valid; if not, do NOTHING with that buffer.  If that pointer
+       is valid, then make sure that the buffer pointer is valid, too! */
+
+    if(lpuDestDirLen && lpszDestDir) {
+	if(*lpuDestDirLen < destDirSizeReq) {
+	    retval |= VFF_BUFFTOOSMALL;
+	    strncpy(lpszDestDir, destDir, *lpuDestDirLen - 1);
+	    lpszDestDir[*lpuDestDirLen - 1] = '\0';
+	}
+	else
+	    strcpy(lpszDestDir, destDir);
+
+	*lpuDestDirLen = destDirSizeReq;
+    }
+    
+    if(lpuCurDirLen && lpszCurDir) {
+	if(*lpuCurDirLen < curDirSizeReq) {
+	    retval |= VFF_BUFFTOOSMALL;
+	    strncpy(lpszCurDir, curDir, *lpuCurDirLen - 1);
+	    lpszCurDir[*lpuCurDirLen - 1] = '\0';
+	}
+	else
+	    strcpy(lpszCurDir, curDir);
+
+	*lpuCurDirLen = curDirSizeReq;
+    }
+
+    dprintf_ver(stddeb, "VerFindFile() ret = %lu ",
+		retval);
+
+    if(retval) {
+	dprintf_ver(stddeb, "( ");
+
+	if(retval & VFF_CURNEDEST)
+	    dprintf_ver(stddeb, "VFF_CURNEDEST ");
+	if(retval & VFF_FILEINUSE)
+	    dprintf_ver(stddeb, "VFF_FILEINUSE ");
+	if(retval & VFF_BUFFTOOSMALL)
+	    dprintf_ver(stddeb, "VFF_BUFFTOOSMALL ");
+
+	dprintf_ver(stddeb, ")");
+    }
+
+    dprintf_ver_string("\n\t(Exit) lpszCurDir = ", lpszCurDir, "\n");
+    if(lpuCurDirLen)
+	dprintf_ver(stddeb, "\t(Exit) lpuCurDirLen = %p (%u)\n",
+		    lpuCurDirLen, *lpuCurDirLen);
+    else
+	dprintf_ver(stddeb, "\t(Exit) lpuCurDirLen = (null)\n");
+
+    dprintf_ver_string("\t(Exit) lpszDestDir = ", lpszDestDir, "\n");
+    if(lpuDestDirLen)
+	dprintf_ver(stddeb, "\t(Exit) lpuDestDirLen = %p (%u)\n",
+		    lpuDestDirLen, *lpuDestDirLen);
+
+    return retval;
 }
 
 /* VerFindFileA						[VERSION.5] */
diff --git a/misc/winsock.c b/misc/winsock.c
index 926c514..7f4c314 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -3,6 +3,13 @@
  * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
  * 
  * (C) 1993,1994,1996 John Brezak, Erik Bos, Alex Korobka.
+ *
+ * TODO: Merge Async...() handling with X event loop by adding 
+ *	 thread/task fdset to select(2) in windows/event.c.
+ *       Also fork dns lookup helper during the startup (with a pipe 
+ *	 for communication) and make it fork for a database request
+ *	 instead of forking the main process (i.e. something like 
+ *	 Netscape 4.0).
  */
  
 #include <stdio.h>
@@ -1446,7 +1453,7 @@
   FARPROC16		prev;
   LPWSINFO              pwsi = wsi_find(GetCurrentTask());
 
-  dprintf_winsock(stddeb, "WS_SetBlockingHook(%08x): hook %08x\n", 
+  dprintf_winsock(stddeb, "WS_SetBlockingHook16(%08x): hook %08x\n", 
 			  (unsigned)pwsi, (unsigned) lpBlockFunc);
 
   if( pwsi ) { 
@@ -1459,11 +1466,11 @@
 
 FARPROC32 WSASetBlockingHook32(FARPROC32 lpBlockFunc)
 {
-    fprintf( stderr, "Empty stub WSASetBlockingHook32(%p)\n", lpBlockFunc );
-    return NULL;
+  fprintf( stderr, "WSASetBlockingHook32(%p): empty stub\n", lpBlockFunc );
+  return NULL;
 }
 
-INT16 WSAUnhookBlockingHook(void)
+INT16 WSAUnhookBlockingHook16(void)
 {
   LPWSINFO              pwsi = wsi_find(GetCurrentTask());
 
@@ -1472,6 +1479,12 @@
   return SOCKET_ERROR;
 }
 
+INT32 WSAUnhookBlockingHook32(void)
+{
+  fprintf( stderr, "WSAUnhookBlockingHook32(): empty stub\n");
+  return NULL;
+}
+
 VOID
 WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,LPDWORD x5,LPDWORD x6) 
 {
diff --git a/msdos/ioports.c b/msdos/ioports.c
index 7e41ce8..e33487a 100644
--- a/msdos/ioports.c
+++ b/msdos/ioports.c
@@ -10,6 +10,13 @@
      fix that, I guess.
 */
 
+#ifdef linux
+#include <ctype.h>
+#include <unistd.h>
+#include <asm/io.h>
+#include <string.h>
+#include "options.h"
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,6 +40,117 @@
   0x1b, 0x7b, 0x21, 0x00, 0x00, 0x00, 0x05, 0x5f
 };
 
+#ifdef linux
+char do_direct_port_access = 0;
+char port_permissions[0x10000];
+#endif
+
+/**********************************************************************
+ *	    IO_port_init
+ */
+
+/* set_IO_permissions(int val1, int val)
+ * Helper function for IO_port_init
+ */
+#ifdef linux
+void set_IO_permissions(int val1, int val, char rw)
+{
+	int j;
+	if (val1 != -1) {
+		if (val == -1) val = 0x3ff;		
+		for (j = val1; j <= val; j++)
+			port_permissions[j] |= rw;		
+
+		do_direct_port_access = 1;
+
+		val1 = -1;
+	} else if (val != -1) {		
+		do_direct_port_access = 1;
+
+		port_permissions[val] |= rw;
+	}
+
+}
+
+/* do_IO_port_init_read_or_write(char* temp, char rw)
+ * Helper function for IO_port_init
+ */
+
+void do_IO_port_init_read_or_write(char* temp, char rw)
+{
+	int val, val1, i, len;
+	if (!strcasecmp(temp, "all")) {
+		fprintf(stderr, "Warning!!! Granting FULL IO port access to"
+			" windoze programs!\nWarning!!! "
+			"*** THIS IS NOT AT ALL "
+			"RECOMMENDED!!! ***\n");
+		for (i=0; i < sizeof(port_permissions); i++)
+			port_permissions[i] |= rw;
+
+	} else if (!(!strcmp(temp, "*") || *temp == '\0')) {
+		len = strlen(temp);
+		val = -1;
+		val1 = -1;		
+		for (i = 0; i < len; i++) {
+			switch (temp[i]) {
+			case '0':
+				if (temp[i+1] == 'x' || temp[i+1] == 'X') {
+					sscanf(temp+i, "%x", &val);
+					i += 2;
+				} else {
+					sscanf(temp+i, "%d", &val);
+				}
+				while (isxdigit(temp[i]))
+					i++;
+				i--;
+				break;
+			case ',':
+			case ' ':
+			case '\t':
+				set_IO_permissions(val1, val, rw);
+				val1 = -1; val = -1;
+				break;
+			case '-':
+				val1 = val;
+				if (val1 == -1) val1 = 0;
+				break;
+			default:
+				if (temp[i] >= '0' && temp[i] <= '9') {
+					sscanf(temp+i, "%d", &val);
+					while (isdigit(temp[i]))
+						i++;
+				}
+			}
+		}
+		set_IO_permissions(val1, val, rw);		
+	}
+}
+
+#endif
+
+void IO_port_init()
+{
+#ifdef linux
+	char temp[1024];
+
+	memset(port_permissions, 0, sizeof(port_permissions));
+	do_direct_port_access = 0;
+
+	/* Can we do that? */
+	if (!iopl(3)) {
+		iopl(0);
+
+		PROFILE_GetWineIniString( "ports", "read", "*",
+					 temp, sizeof(temp) );
+		do_IO_port_init_read_or_write(temp, 1);
+		PROFILE_GetWineIniString( "ports", "write", "*",
+					 temp, sizeof(temp) );
+		do_IO_port_init_read_or_write(temp, 2);
+	}
+
+
+#endif
+}
 
 /**********************************************************************
  *	    IO_inport
@@ -40,27 +158,46 @@
 DWORD IO_inport( int port, int count )
 {
     DWORD res = 0;
-    BYTE b;
+    BYTE b;    
 
-    dprintf_int(stddeb, "IO: %d bytes from port 0x%02x\n", count, port );
+#ifdef linux    
+    if (do_direct_port_access) iopl(3);
+#endif
+
+    dprintf_int(stddeb, "IO: %d bytes from port 0x%02x ", count, port );
 
     while (count-- > 0)
     {
-        switch (port++)
-	{
-	case 0x70:
-            b = cmosaddress;
-            break;
-	case 0x71:
-            b = cmosimage[cmosaddress & 0x3f];
-            break;
-	default:
-            fprintf( stderr, "Direct I/O read attempted from port %x\n", port);
-            b = 0xff;
-            break;
-	}
-        res = (res << 8) | b;
+#ifdef linux
+	    if(port_permissions[port] & 1) {		    
+		    b = inb(port);
+	    } else 
+#endif
+	    {
+		    switch (port)
+		    {
+		    case 0x70:
+			    b = cmosaddress;
+			    break;
+		    case 0x71:
+			    b = cmosimage[cmosaddress & 0x3f];
+			    break;
+		    default:
+			    fprintf( stderr, 
+				    "Direct I/O read attempted "
+				    "from port %x\n", port);
+			    b = 0xff;
+			    break;
+		    }
+	    }
+
+	    port++;
+	    res = (res << 8) | b;
     }
+#ifdef linux
+    if (do_direct_port_access) iopl(0);
+#endif
+    dprintf_int(stddeb, "( 0x%x )\n", res );
     return res;
 }
 
@@ -75,21 +212,37 @@
     dprintf_int( stddeb, "IO: 0x%lx (%d bytes) to port 0x%02x\n",
                  value, count, port );
 
+#ifdef linux
+    if (do_direct_port_access) iopl(3);
+#endif
+
     while (count-- > 0)
     {
         b = value & 0xff;
         value >>= 8;
-        switch (port++)
+#ifdef linux
+	if (port_permissions[port] & 2) {
+		outb(b, port);
+	} else 
+#endif
 	{
-	case 0x70:
-            cmosaddress = b & 0x7f;
-            break;
-	case 0x71:
-            cmosimage[cmosaddress & 0x3f] = b;
-            break;
-	default:
-            fprintf( stderr, "Direct I/O write attempted to port %x\n", port );
-            break;
+		switch (port)
+		{
+		case 0x70:
+			cmosaddress = b & 0x7f;
+			break;
+		case 0x71:
+			cmosimage[cmosaddress & 0x3f] = b;
+			break;
+		default:
+			fprintf( stderr, "Direct I/O write attempted "
+				"to port %x\n", port );
+			break;
+		}
 	}
+	port++;
     }
+#ifdef linux
+    if (do_direct_port_access) iopl(0);
+#endif
 }
diff --git a/multimedia/audio.c b/multimedia/audio.c
index 31af318..517325f 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -87,15 +87,39 @@
 {
 	dprintf_mciwave(stddeb,"WAVE_NotifyClient // wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID, wMsg, dwParam1, dwParam2);
 
-	if (wDevID > MAX_WAVOUTDRV) return MCIERR_INTERNAL;
+	switch (wMsg) {
+	case WOM_OPEN:
+	case WOM_CLOSE:
+	case WOM_DONE:
+	  if (wDevID > MAX_WAVOUTDRV) return MCIERR_INTERNAL;
+	  
+	  if (WOutDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
+		WOutDev[wDevID].waveDesc.dwCallBack, 
+		WOutDev[wDevID].wFlags, 
+		WOutDev[wDevID].waveDesc.hWave, 
+                wMsg, 
+		WOutDev[wDevID].waveDesc.dwInstance, 
+                dwParam1, 
+                dwParam2)) {
+	    dprintf_mciwave(stddeb,"WAVE_NotifyClient // can't notify client !\n");
+	    return MMSYSERR_NOERROR;
+	  }
+	  break;
 
-	if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
+	case WIM_OPEN:
+	case WIM_CLOSE:
+	case WIM_DATA:
+	  if (wDevID > MAX_WAVINDRV) return MCIERR_INTERNAL;
+	  
+	  if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
 		WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags, 
 		WInDev[wDevID].waveDesc.hWave, wMsg, 
 		WInDev[wDevID].waveDesc.dwInstance, dwParam1, dwParam2)) {
-		dprintf_mciwave(stddeb,"WAVE_NotifyClient // can't notify client !\n");
-		return MMSYSERR_NOERROR;
-		}
+	    dprintf_mciwave(stddeb,"WAVE_NotifyClient // can't notify client !\n");
+	    return MMSYSERR_NOERROR;
+	  }
+	  break;
+	}
         return 0;
 }
 
@@ -139,7 +163,7 @@
 		lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
 		dprintf_mciwave(stddeb,"WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
 						lpstrElementName);
-		if (strlen(lpstrElementName) > 0) {
+		if ( lpstrElementName && (strlen(lpstrElementName) > 0)) {
 			strcpy(str, lpstrElementName);
 			CharUpper32A(str);
 			MCIWavDev[wDevID].hFile = mmioOpen(str, NULL, 
@@ -156,7 +180,9 @@
 	memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
 	MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
 	lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
+
 	hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
+	if (hDesc == 0) return MCIERR_INTERNAL;   /* is this right ? */
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
 	lpDesc->hWave = 0;
 /*
@@ -240,8 +266,8 @@
    MCI_WAVE_INPUT flag. No explicit check on MCI_WAVE_OUTPUT is done since that
    is the default.
 
-   The flags MCI_NOTIFY (and the callback parameter in lpParms) and MCI_WAIT are
-   ignored
+   The flags MCI_NOTIFY (and the callback parameter in lpParms) and MCI_WAIT
+   are ignored
 */
 
         DWORD          dwRet;
@@ -484,10 +510,17 @@
 */
 static DWORD WAVE_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+        DWORD dwRet;
+
 	dprintf_mciwave(stddeb,
 		"WAVE_mciStop(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
-	return 0;
+	if (MCIWavDev[wDevID].fInput)
+	  dwRet = widMessage(wDevID, WIDM_STOP, 0, dwFlags, (DWORD)lpParms);
+	else
+	  dwRet = wodMessage(wDevID, WODM_STOP, 0, dwFlags, (DWORD)lpParms);
+	  
+	return dwRet;
 }
 
 
@@ -496,10 +529,17 @@
 */
 static DWORD WAVE_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+        DWORD dwRet;
+
 	dprintf_mciwave(stddeb,
 		"WAVE_mciPause(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
-	return 0;
+	if (MCIWavDev[wDevID].fInput)
+	  dwRet = widMessage(wDevID, WIDM_PAUSE, 0, dwFlags, (DWORD)lpParms);
+	else
+	  dwRet = wodMessage(wDevID, WODM_PAUSE, 0, dwFlags, (DWORD)lpParms);
+
+	return dwRet;
 }
 
 
@@ -794,6 +834,7 @@
 	lpCaps->wPid = 0x0001; 	/* Product ID */
 	strcpy(lpCaps->szPname, "Linux WAVOUT Driver");
 #endif
+	lpCaps->vDriverVersion = 0x0100;
 	lpCaps->dwFormats = 0x00000000;
 	lpCaps->dwSupport = WAVECAPS_VOLUME;
 	lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
@@ -892,7 +933,6 @@
 	memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // lpDesc->lpFormat = %p\n",lpDesc->lpFormat);
         lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); 
-/*	lpFormat = lpDesc->lpFormat; */
 	dprintf_mciwave(stddeb,"Linux 'wodOpen' // lpFormat = %p\n",lpFormat);
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 		dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad format %04X !\n",
@@ -941,6 +981,7 @@
 static DWORD wodClose(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
+	if (wDevID > MAX_WAVOUTDRV) return MMSYSERR_INVALPARAM;
 	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
@@ -959,10 +1000,12 @@
 /**************************************************************************
 * 				wodWrite			[internal]
 */
-static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
+static DWORD wodWrite(WORD wDevID, DWORD lpWH, DWORD dwSize)
 {
 	int		count;
-	LPSTR	lpData;
+	LPSTR	        lpData;
+	LPWAVEHDR       lpWaveHdr = (LPWAVEHDR)PTR_SEG_TO_LIN(lpWH);
+
 	dprintf_mciwave(stddeb,"wodWrite(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
         dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't play !\n");
@@ -988,7 +1031,7 @@
 	WOutDev[wDevID].dwTotalPlayed += count;
 	lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
 	lpWaveHdr->dwFlags |= WHDR_DONE;
-	if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
+	if (WAVE_NotifyClient(wDevID, WOM_DONE, lpWH, 0) != MMSYSERR_NOERROR) {
 		dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't notify client !\n");
 		return MMSYSERR_INVALPARAM;
 		}
@@ -1044,7 +1087,13 @@
 	if (WOutDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'wodRestart' // can't restart !\n");
 		return MMSYSERR_NOTENABLED;
-		}
+	}
+	/* FIXME: is NotifyClient with WOM_DONE right ? (Comet Busters 1.3.3 needs this notification) */
+       	if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
+               	dprintf_mciwave(stddeb,"Linux 'wodRestart' // can't notify client !\n");
+               	return MMSYSERR_INVALPARAM;
+        }
+
 	return MMSYSERR_NOERROR;
 }
 
@@ -1181,9 +1230,11 @@
 		case WODM_CLOSE:
 			return wodClose(wDevID);
 		case WODM_WRITE:
-			return wodWrite(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
+			return wodWrite(wDevID, dwParam1, dwParam2);
 		case WODM_PAUSE:
 			return 0L;
+	        case WODM_STOP:
+			return 0L;
 		case WODM_GETPOS:
 			return wodGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_BREAKLOOP:
@@ -1344,7 +1395,6 @@
 	WInDev[wDevID].dwTotalRecorded = 0;
 	memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
         lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); 
-/*        lpFormat = lpDesc->lpFormat; */
 	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 		dprintf_mciwave(stddeb,"Linux 'widOpen' // Bad format %04X !\n",
 					lpFormat->wFormatTag);
@@ -1387,6 +1437,7 @@
 static DWORD widClose(WORD wDevID)
 {
 	dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
+	if (wDevID > MAX_WAVINDRV) return MMSYSERR_INVALPARAM;
 	if (WInDev[wDevID].unixdev == 0) {
 		dprintf_mciwave(stddeb,"Linux 'widClose' // can't close !\n");
 		return MMSYSERR_NOTENABLED;
@@ -1521,6 +1572,9 @@
 		WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
 		lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
 		lpWIHdr->dwFlags |= WHDR_DONE;
+
+/* FIXME here should be a segmented address in stead of lpWIHdr */
+
 		if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) != 
 			MMSYSERR_NOERROR) {
 			dprintf_mciwave(stddeb,	"Linux 'widStart' // can't notify client !\n");
@@ -1530,7 +1584,7 @@
 		count++;
 		}
 	dprintf_mciwave(stddeb,"widStart // end of recording !\n");
-	fflush(stdout);
+	fflush(stddeb);
 	return MMSYSERR_NOERROR;
 }
 
@@ -1658,6 +1712,8 @@
 			return widReset(wDevID);
 		case WIDM_START:
 			return widStart(wDevID);
+		case WIDM_PAUSE:
+			return widStop(wDevID);
 		case WIDM_STOP:
 			return widStop(wDevID);
 		default:
@@ -1728,6 +1784,42 @@
 			return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
 			return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
+
+                case MCI_LOAD:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_SAVE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_SEEK:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_FREEZE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_PUT:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_REALIZE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_UNFREEZE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_UPDATE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_WHERE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_WINDOW:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_STEP:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_SPIN:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_ESCAPE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_COPY:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_CUT:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_DELETE:
+			return MMSYSERR_NOTSUPPORTED;
+		case MCI_PASTE:
+			return MMSYSERR_NOTSUPPORTED;
+
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index 429f2b2..be6c706 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -350,13 +350,13 @@
 	i=0;
 	while (i<nrofkeywords) {
 		FLAG1("shareable",MCI_OPEN_SHAREABLE);
-		if (!strcmp(keywords[i],"alias") && (i+1<nrofkeywords)) {
+		if (!STRCMP(keywords[i],"alias") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_OPEN_ALIAS;
 			pU->openParams.lpstrAlias=SEGPTR_GET(SEGPTR_STRDUP(keywords[i+1]));
 			i+=2;
 			continue;
 		}
-		if (!strcmp(keywords[i],"element") && (i+1<nrofkeywords)) {
+		if (!STRCMP(keywords[i],"element") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_OPEN_ELEMENT;
 			pU->openParams.lpstrElementName=SEGPTR_GET(SEGPTR_STRDUP(keywords[i+1]));
 			i+=2;
@@ -2104,7 +2104,7 @@
 DWORD mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString, 
 	UINT16 uReturnLength, HWND16 hwndCallback)
 {
-	char	*cmd,*dev,*args,**keywords;
+	char	*cmd,*dev,*args,**keywords,*filename;
 	WORD	uDevTyp=0,wDevID=0;
 	DWORD	dwFlags;
 	int	res=0,i,nrofkeywords;
@@ -2143,16 +2143,23 @@
 	}
 	dwFlags = 0; /* default flags */
 	for (i=0;i<nrofkeywords;) {
+		if (!STRCMP(keywords[i],"type")) {
+			filename = dev;
+			dev = keywords[i+1];
+			memcpy(keywords+i,keywords+(i+2),(nrofkeywords-i-2)*sizeof(char *));
+			nrofkeywords -= 2;
+			continue;
+		}
 		if (!STRCMP(keywords[i],"wait")) {
 			dwFlags |= MCI_WAIT;
-			memcpy(keywords+i,keywords+(i+1),nrofkeywords-i-1);
+			memcpy(keywords+i,keywords+(i+1),(nrofkeywords-i-1)*sizeof(char *));
 			nrofkeywords--;
 			continue;
 		}
 		if (!STRCMP(keywords[i],"notify")) {
 			/* how should we callback?  I don't know. */
 			/*dwFlags |= MCI_NOTIFY;*/
-			memcpy(keywords+i,keywords+(i+1),nrofkeywords-i-1);
+			memcpy(keywords+i,keywords+(i+1),(nrofkeywords-i-1)*sizeof(char *));
 			nrofkeywords--;
 			continue;
 		}
diff --git a/multimedia/midi.c b/multimedia/midi.c
index a4446e3..4706a45 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -5,7 +5,10 @@
  */
 
 #include <stdio.h>
+#include <errno.h>
+#include <string.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -23,6 +26,7 @@
 #include <linux/soundcard.h>
 #elif __FreeBSD__
 #include <machine/soundcard.h>
+#include <sys/errno.h>
 #endif
 
 #if defined(linux) || defined(__FreeBSD__)
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 10d780d..e8d094a 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -14,6 +14,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include "windows.h"
+#include "win.h"
 #include "heap.h"
 #include "ldt.h"
 #include "user.h"
@@ -23,6 +24,7 @@
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
+#include "callback.h"
 
 static int	InstalledCount;
 static int	InstalledListLen;
@@ -269,6 +271,8 @@
 BOOL16 DriverCallback(DWORD dwCallBack, UINT16 uFlags, HANDLE16 hDev, 
 		WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
 {
+	LPWAVEOPENDESC	lpDesc;
+
 	dprintf_mmsys(stddeb, "DriverCallback(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
 		dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
 	switch(uFlags & DCB_TYPEMASK) {
@@ -276,7 +280,14 @@
 			dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_NULL !\n");
 			break;
 		case DCB_WINDOW:
-			dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_WINDOW !\n");
+			dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_WINDOW = %04lX!\n",dwCallBack);
+			if (!IsWindow32(dwCallBack)) return FALSE;
+			dprintf_mmsys(stddeb, "DriverCallback() // Device Handle = %04X\n", hDev);
+			lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDev);
+			if (lpDesc == NULL) return FALSE;
+
+			dprintf_mmsys(stddeb, "DriverCallback() // Before PostMessage16\n");
+			PostMessage16((HWND16)dwCallBack, wMsg, hDev, dwParam1);
 			break;
 		case DCB_TASK:
 			dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_TASK !\n");
@@ -855,7 +866,8 @@
 
 /**************************************************************************
 * 				mciSound				[internal]
-*/
+*  not used anymore ??
+
 DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
 {
 	if (lpParms == NULL) return MCIERR_INTERNAL;
@@ -863,7 +875,8 @@
 		dprintf_mci(stddeb, "MCI_SOUND // file='%s' !\n", lpParms->lpstrSoundName);
 	return MCIERR_INVALID_DEVICE_ID;
 }
-
+*
+*/
 
 static const char *_mciCommandToString(UINT16 wMsg)
 {
@@ -1464,6 +1477,8 @@
 */
 UINT16 waveOutGetDevCaps(UINT16 uDeviceID, WAVEOUTCAPS * lpCaps, UINT16 uSize)
 {
+	if (uDeviceID > waveOutGetNumDevs() - 1) return MMSYSERR_BADDEVICEID;
+	if (uDeviceID == (UINT16)WAVE_MAPPER) return MMSYSERR_BADDEVICEID; /* FIXME: do we have a wave mapper ? */
 	dprintf_mmsys(stddeb, "waveOutGetDevCaps\n");
 	return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
 }
@@ -1579,17 +1594,17 @@
 	lpDesc->dwInstance = dwInstance;
 	while(uDeviceID < MAXWAVEDRIVERS) {
 		dwRet = wodMessage(uDeviceID, WODM_OPEN, 
-			lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
+			lpDesc->dwInstance, (DWORD)lp16Desc, dwFlags);
 		if (dwRet == MMSYSERR_NOERROR) break;
 		if (!bMapperFlg) break;
 		uDeviceID++;
 		dprintf_mmsys(stddeb, "waveOutOpen	// WAVE_MAPPER mode ! try next driver...\n");
 		}
+	lpDesc->uDeviceID = uDeviceID;  /* save physical Device ID */
 	if (dwFlags & WAVE_FORMAT_QUERY) {
 		dprintf_mmsys(stddeb, "waveOutOpen	// End of WAVE_FORMAT_QUERY !\n");
-		waveOutClose(hWaveOut);
+		dwRet = waveOutClose(hWaveOut);
 		}
-	lpDesc->uDeviceID = uDeviceID;  /* save physical Device ID */
 	return dwRet;
 }
 
@@ -1791,9 +1806,6 @@
 	lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
 	if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
 	if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-/*
-	*lpuDeviceID = lpParms->wDeviceID; 
-*/
 	*lpuDeviceID = lpDesc->uDeviceID;
         return 0;
 }
@@ -1884,6 +1896,7 @@
 		uDeviceID++;
 		dprintf_mmsys(stddeb, "waveInOpen	// WAVE_MAPPER mode ! try next driver...\n");
 		}
+	lpDesc->uDeviceID = uDeviceID;
 	if (dwFlags & WAVE_FORMAT_QUERY) {
 		dprintf_mmsys(stddeb, "waveInOpen	// End of WAVE_FORMAT_QUERY !\n");
 		waveInClose(hWaveIn);
@@ -2074,7 +2087,13 @@
 	HMMIO16		hmmio;
 	OFSTRUCT	ofs;
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
+	dprintf_mmio(stddeb, "mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
+        if (!szFileName)
+        {
+            /* FIXME: should load memory file if szFileName == NULL */
+            fprintf(stderr, "WARNING: mmioOpen(): szFileName == NULL (memory file ???)\n");
+            return 0;
+ 	}
 	hFile = OpenFile32(szFileName, &ofs, dwOpenFlags);
 	if (hFile == -1) return 0;
 	hmmio = GlobalAlloc16(GMEM_MOVEABLE, sizeof(MMIOINFO));
@@ -2084,7 +2103,7 @@
 	lpmminfo->hmmio = hmmio;
 	lpmminfo->dwReserved2 = hFile;
 	GlobalUnlock16(hmmio);
-	dprintf_mmsys(stddeb, "mmioOpen // return hmmio=%04X\n", hmmio);
+	dprintf_mmio(stddeb, "mmioOpen // return hmmio=%04X\n", hmmio);
 	return hmmio;
 }
 
@@ -2095,7 +2114,7 @@
 UINT16 mmioClose(HMMIO16 hmmio, UINT16 uFlags)
 {
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioClose(%04X, %04X);\n", hmmio, uFlags);
+	dprintf_mmio(stddeb, "mmioClose(%04X, %04X);\n", hmmio, uFlags);
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	_lclose32((HFILE32)lpmminfo->dwReserved2);
@@ -2131,7 +2150,7 @@
 {
 	LONG		count;
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
+	dprintf_mmio(stddeb, "mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	count = _lwrite32(LOWORD(lpmminfo->dwReserved2), (LPSTR)pch, cch);
@@ -2146,10 +2165,10 @@
 {
 	int		count;
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioSeek(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
+	dprintf_mmio(stddeb, "mmioSeek(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) {
-		dprintf_mmsys(stddeb, "mmioSeek // can't lock hmmio=%04X !\n", hmmio);
+		dprintf_mmio(stddeb, "mmioSeek // can't lock hmmio=%04X !\n", hmmio);
 		return 0;
 		}
 	count = _llseek32((HFILE32)lpmminfo->dwReserved2, lOffset, iOrigin);
@@ -2163,7 +2182,7 @@
 UINT16 mmioGetInfo(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags)
 {
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioGetInfo\n");
+	dprintf_mmio(stddeb, "mmioGetInfo\n");
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO));
@@ -2177,7 +2196,7 @@
 UINT16 mmioSetInfo(HMMIO16 hmmio, const MMIOINFO * lpmmioinfo, UINT16 uFlags)
 {
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioSetInfo\n");
+	dprintf_mmio(stddeb, "mmioSetInfo\n");
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	GlobalUnlock16(hmmio);
@@ -2190,7 +2209,7 @@
 UINT16 mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, 
 						LONG cchBuffer, UINT16 uFlags)
 {
-	dprintf_mmsys(stddeb, "mmioSetBuffer // empty stub \n");
+	dprintf_mmio(stddeb, "mmioSetBuffer // empty stub \n");
 	return 0;
 }
 
@@ -2200,7 +2219,7 @@
 UINT16 mmioFlush(HMMIO16 hmmio, UINT16 uFlags)
 {
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioFlush(%04X, %04X)\n", hmmio, uFlags);
+	dprintf_mmio(stddeb, "mmioFlush(%04X, %04X)\n", hmmio, uFlags);
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	GlobalUnlock16(hmmio);
@@ -2214,7 +2233,7 @@
 {
 	int		count = 0;
 	LPMMIOINFO	lpmminfo;
-	dprintf_mmsys(stddeb, "mmioAdvance\n");
+	dprintf_mmio(stddeb, "mmioAdvance\n");
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	if (uFlags == MMIO_READ) {
@@ -2236,7 +2255,7 @@
 */
 FOURCC mmioStringToFOURCC(LPCSTR sz, UINT16 uFlags)
 {
-	dprintf_mmsys(stddeb, "mmioStringToFOURCC // empty stub \n");
+	dprintf_mmio(stddeb, "mmioStringToFOURCC // empty stub \n");
 	return 0;
 }
 
@@ -2246,7 +2265,7 @@
 LPMMIOPROC mmioInstallIOProc(FOURCC fccIOProc, 
 				LPMMIOPROC pIOProc, DWORD dwFlags)
 {
-	dprintf_mmsys(stddeb, "mmioInstallIOProc // empty stub \n");
+	dprintf_mmio(stddeb, "mmioInstallIOProc // empty stub \n");
 	return 0;
 }
 
@@ -2256,7 +2275,7 @@
 LRESULT mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
 					    LPARAM lParam1, LPARAM lParam2)
 {
-	dprintf_mmsys(stddeb, "mmioSendMessage // empty stub \n");
+	dprintf_mmio(stddeb, "mmioSendMessage // empty stub \n");
 	return 0;
 }
 
@@ -2275,6 +2294,7 @@
 	if (lpmminfo == NULL) return 0;
 	dwfcc = lpck->ckid;
 	dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX\n", dwfcc);
+	dprintf_mmio(stddeb, "mmioDescend // hfile = %ld\n", lpmminfo->dwReserved2);
 	dwOldPos = _llseek32((HFILE32)lpmminfo->dwReserved2, 0, SEEK_CUR);
 	dprintf_mmio(stddeb, "mmioDescend // dwOldPos=%ld\n", dwOldPos);
 	if (lpckParent != NULL) {
@@ -2282,14 +2302,26 @@
 		dwOldPos = _llseek32((HFILE32)lpmminfo->dwReserved2,
 					lpckParent->dwDataOffset, SEEK_SET);
 		}
+/*
+
+   It seems to be that FINDRIFF should not be treated the same as the 
+   other FINDxxx so I treat it as a MMIO_FINDxxx
+
 	if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) || 
 		(uFlags & MMIO_FINDLIST)) {
+*/
+	if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDLIST)) {
 		dprintf_mmio(stddeb, "mmioDescend // MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
 		while (TRUE) {
-			if (_lread32((HFILE32)lpmminfo->dwReserved2, (LPSTR)lpck, 
-					sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
+		        size_t ix;
+
+			ix =_lread32((HFILE32)lpmminfo->dwReserved2, (LPSTR)lpck, sizeof(MMCKINFO));
+			dprintf_mmio(stddeb, "mmioDescend // after _lread32 ix = %d req = %d, errno = %d\n",ix,sizeof(MMCKINFO),errno);
+			if (ix < sizeof(MMCKINFO)) {
+
 				_llseek32((HFILE32)lpmminfo->dwReserved2, dwOldPos, SEEK_SET);
 				GlobalUnlock16(hmmio);
+				dprintf_mmio(stddeb, "mmioDescend // return ChunkNotFound\n");
 				return MMIOERR_CHUNKNOTFOUND;
 				}
 			dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX ckid=%08lX cksize=%08lX !\n", 
@@ -2306,6 +2338,7 @@
 				sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
                     _llseek32((HFILE32)lpmminfo->dwReserved2, dwOldPos, SEEK_SET);
 			GlobalUnlock16(hmmio);
+ 		        dprintf_mmio(stddeb, "mmioDescend // return ChunkNotFound 2nd\n");
 			return MMIOERR_CHUNKNOTFOUND;
 			}
 		}
@@ -2317,7 +2350,7 @@
 	GlobalUnlock16(hmmio);
 	dprintf_mmio(stddeb, "mmioDescend // lpck->ckid=%08lX lpck->cksize=%ld !\n", 
 								lpck->ckid, lpck->cksize);
-	dprintf_mmsys(stddeb, "mmioDescend // lpck->fccType=%08lX !\n", lpck->fccType);
+	dprintf_mmio(stddeb, "mmioDescend // lpck->fccType=%08lX !\n", lpck->fccType);
 	return 0;
 }
 
@@ -2326,7 +2359,7 @@
 */
 UINT16 mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
 {
-	dprintf_mmsys(stddeb, "mmioAscend // empty stub !\n");
+	dprintf_mmio(stddeb, "mmioAscend // empty stub !\n");
 	return 0;
 }
 
@@ -2335,7 +2368,7 @@
 */
 UINT16 mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
 {
-	dprintf_mmsys(stddeb, "mmioCreateChunk // empty stub \n");
+	dprintf_mmio(stddeb, "mmioCreateChunk // empty stub \n");
 	return 0;
 }
 
@@ -2346,7 +2379,7 @@
 UINT16 mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
      MMIOINFO * lpmmioinfo, DWORD dwRenameFlags)
 {
-	dprintf_mmsys(stddeb, "mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
+	dprintf_mmio(stddeb, "mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
 			szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
 	return 0;
 }
diff --git a/multimedia/time.c b/multimedia/time.c
index f9fa0c5..d8c5917 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -37,6 +37,14 @@
 
 static LPTIMERENTRY lpTimerList = NULL;
 
+/*
+ * FIXME
+ * is this the minimum resolution ? 
+ */
+#define MMSYSTIME_MININTERVAL (33)
+#define MMSYSTIME_MAXINTERVAL (65535)
+
+
 /**************************************************************************
  *           TIME_MMSysTimeCallback
  */
@@ -44,7 +52,7 @@
                                     UINT32 id, DWORD dwTime )
 {
     LPTIMERENTRY lpTimer = lpTimerList;
-    mmSysTimeMS.u.ms += 33;
+    mmSysTimeMS.u.ms += MMSYSTIME_MININTERVAL;
     mmSysTimeSMPTE.u.smpte.frame++;
     while (lpTimer != NULL) {
 	lpTimer->wCurTime--;
@@ -99,7 +107,7 @@
 	mmSysTimeSMPTE.u.smpte.frame = 0;
 	mmSysTimeSMPTE.u.smpte.fps = 0;
 	mmSysTimeSMPTE.u.smpte.dummy = 0;
-	SetTimer32( 0, 1, 33, TIME_MMSysTimeCallback );
+	SetTimer32( 0, 1, MMSYSTIME_MININTERVAL, TIME_MMSysTimeCallback );
     }
 }
 
@@ -111,6 +119,8 @@
     dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
     if (!mmTimeStarted)
 	StartMMTime();
+    lpTime->wType = TIME_MS;
+    lpTime->u.ms = mmSysTimeMS.u.ms;
     return 0;
 }
 
@@ -185,7 +195,11 @@
  */
 WORD timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
 {
-    dprintf_mmsys(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
+    dprintf_mmtime(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
+    if (!mmTimeStarted)
+	StartMMTime();
+    lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
+    lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
     return 0;
 }
 
@@ -194,9 +208,11 @@
  */
 WORD timeBeginPeriod(WORD wPeriod)
 {
-    dprintf_mmsys(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
+    dprintf_mmtime(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
     if (!mmTimeStarted)
 	StartMMTime();
+    if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL) 
+        return TIMERR_NOCANDO;
     return 0;
 }
 
@@ -205,7 +221,9 @@
  */
 WORD timeEndPeriod(WORD wPeriod)
 {
-    dprintf_mmsys(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
+    dprintf_mmtime(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
+    if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL) 
+        return TIMERR_NOCANDO;
     return 0;
 }
 
@@ -214,8 +232,9 @@
  */
 DWORD timeGetTime()
 {
-    dprintf_mmsys(stddeb, "timeGetTime(); !\n");
+    dprintf_mmtime(stddeb, "timeGetTime(); !\n");
     if (!mmTimeStarted)
 	StartMMTime();
-    return 0;
+    dprintf_mmtime(stddeb, "timeGetTime() // Time = %ld\n",mmSysTimeMS.u.ms);
+    return mmSysTimeMS.u.ms;
 }
diff --git a/objects/color.c b/objects/color.c
index 3442d91..074359d 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -31,8 +31,8 @@
  * because pixel values can be calculated without X server 
  * assistance.
  *
- * For some info about general Windows palette management read
- * http://198.105.232.5/MSDN/LIBRARY/TECHNOTE/CH3.HTM 
+ * Windows palette manager is described in the
+ * http://premium.microsoft.com/msdn/library/techart/f30/f34/f40/d4d/sa942.htm
  */
 
 typedef struct
@@ -41,7 +41,8 @@
     UINT16      size;
     UINT16      flags;
     INT32	monoPlane;	 /* bit plane different for white and black pixels */
-    BOOL32	bWhiteOn;	 /* monoPlane bit is 1 for the white pixel */
+
+    INT32	(*mapColor)( DC*, COLORREF );
 } CSPACE;
 
 static CSPACE cSpace = {0, 0, 0};
@@ -61,7 +62,6 @@
  * currently inactive window it changes only DC palette mappings.
  */
 
-#define NB_RESERVED_COLORS  		20 /* number of fixed colors in system palette */
 #define NB_COLORCUBE_START_INDEX	63
 
 Visual* 		visual = NULL;
@@ -143,6 +143,11 @@
     return cSpace.flags;
 }
 
+const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
+{
+    return __sysPalTemplate;
+}
+
 COLORREF COLOR_GetSystemPaletteEntry(UINT32 i)
 {
  return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
@@ -176,7 +181,10 @@
   return 1;
 }
 
-void COLOR_FillDefaultColors(void)
+/***********************************************************************
+ *      Colormap Initialization
+ */
+static void COLOR_FillDefaultColors(void)
 {
  /* initialize unused entries to what Windows uses as a color 
   * cube - based on Greg Kreider's code. 
@@ -530,58 +538,6 @@
    return TRUE;
 }
 
-
-/***********************************************************************
- *           COLOR_InitPalette
- *
- * Create the system palette.
- */
-static HPALETTE16 COLOR_InitPalette(void)
-{
-    int 		i;
-    HPALETTE16 		hpalette;
-    LOGPALETTE * 	palPtr;
-    PALETTEOBJ*         palObj;
-
-    memset(COLOR_freeList, 0, 256*sizeof(unsigned char));
-
-    if (cSpace.flags & COLOR_PRIVATE)
-	COLOR_BuildPrivateMap( &cSpace );
-    else
-	COLOR_BuildSharedMap( &cSpace );
-
-    /* Build free list */
-
-    if( COLOR_firstFree != -1 )
-	COLOR_FormatSystemPalette();
-
-    COLOR_FillDefaultColors();
-
-    /* create default palette (20 system colors) */
-
-    palPtr = xmalloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
-    if (!palPtr) return FALSE;
-
-    palPtr->palVersion = 0x300;
-    palPtr->palNumEntries = NB_RESERVED_COLORS;
-    for( i = 0; i < NB_RESERVED_COLORS; i ++ )
-    {
-        palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
-        palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
-        palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
-        palPtr->palPalEntry[i].peFlags = 0;  
-    }
-    hpalette = CreatePalette16( palPtr );
-
-    palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
-
-    palObj->mapping = xmalloc( sizeof(int) * 20 );
-
-    free( palPtr );
-    return hpalette;
-}
-
-
 /***********************************************************************
  *	     COLOR_Computeshifts
  *
@@ -609,10 +565,9 @@
 /***********************************************************************
  *           COLOR_Init
  *
- * Initialize color map and system palette.
- *
+ * Initialize color management.
  */
-HPALETTE16 COLOR_Init(void)
+BOOL32 COLOR_Init(void)
 {
     int	mask, white, black;
 
@@ -680,7 +635,21 @@
     dprintf_palette(stddeb," visual class %i (%i)\n", 
 		    visual->class, cSpace.monoPlane);
 
-    return COLOR_InitPalette();
+    memset(COLOR_freeList, 0, 256*sizeof(unsigned char));
+
+    if (cSpace.flags & COLOR_PRIVATE)
+        COLOR_BuildPrivateMap( &cSpace );
+    else
+        COLOR_BuildSharedMap( &cSpace );
+
+    /* Build free list */
+
+    if( COLOR_firstFree != -1 )
+        COLOR_FormatSystemPalette();
+
+    COLOR_FillDefaultColors();
+
+    return TRUE;
 }
 
 /***********************************************************************
@@ -868,31 +837,8 @@
 int COLOR_ToPhysical( DC *dc, COLORREF color )
 {
     WORD 		 index = 0;
-    unsigned char	 spec_type;
     HPALETTE16		 hPal = (dc)? dc->w.hPalette: STOCK_DEFAULT_PALETTE;
-
-    spec_type = color >> 24;
-
-    if( spec_type == 0xff )
-    {
-	spec_type = 0; /* 'write' seems to need that for 'Page 1' text */
-	color &= 0xffffff;
-    }
-
-    if( spec_type > 2 )
-    {  
-	dprintf_palette(stddeb, "COLOR_ToPhysical : invalid RGB specifier for: %08lx\n", color);
-	spec_type = 0;
-    }
-
-    if (dc && (dc->w.bitsPerPixel == 1) && (spec_type == 0))
-    {
-	/* monochrome */
-        if (((color >> 16) & 0xff) +
-            ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2)
-             return 1;   /* white */
-        else return 0;   /* black */
-    }
+    unsigned char	 spec_type = color >> 24;
 
     if ( cSpace.flags & COLOR_FIXED )
     {
@@ -919,7 +865,7 @@
 
           case 1: /* PALETTEINDEX */
 
-            if ( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
+            if( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
             {
                 fprintf(stderr, "\tRGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
                 return 0;
@@ -928,11 +874,16 @@
             if( palPtr->mapping ) return palPtr->mapping[idx];
 
 	    color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
+	    break;
 
-	    /* fall through and out */
+	  default:
+	    color &= 0xffffff;
+	    /* fall through to RGB */
 
 	  case 0: /* RGB */
-	  default:
+	    if( dc && (dc->w.bitsPerPixel == 1) )
+		return (((color >> 16) & 0xff) +
+			((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
 	}
 
         red = GetRValue(color); green = GetGValue(color); blue = GetBValue(color);
@@ -965,7 +916,14 @@
 	switch(spec_type)	/* we have to peruse DC and system palette */
     	{
 	    default:
+		color &= 0xffffff;
+		/* fall through to RGB */
+
        	    case 0:  /* RGB */
+		if( dc && (dc->w.bitsPerPixel == 1) )
+		    return (((color >> 16) & 0xff) +
+			    ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
+
 	    	index = COLOR_PaletteLookupPixel( COLOR_sysPal, 256, 
 						  COLOR_PaletteToPixel, color, FALSE);
 
diff --git a/objects/dc.c b/objects/dc.c
index 6d31cd8..4f25c90 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -14,6 +14,7 @@
 #include "color.h"
 #include "debug.h"
 #include "font.h"
+#include "x11font.h"
 
 extern void CLIPPING_UpdateGCRegion( DC * dc );     /* objects/clipping.c */
 
@@ -301,17 +302,28 @@
 
     if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc); 
 
-    if ((screenDepth <= 8) &&  /* FIXME: Should check for palette instead */
-        ((dc->w.ROPmode == R2_BLACK) || (dc->w.ROPmode == R2_WHITE)))
+    switch (dc->w.ROPmode)
     {
-        val.function   = GXcopy;
-        val.foreground = COLOR_ToPhysical( NULL, (dc->w.ROPmode == R2_BLACK) ?
-                                               RGB(0,0,0) : RGB(255,255,255) );
-    }
-    else
-    {
-        val.function   = DC_XROPfunction[dc->w.ROPmode-1];
-        val.foreground = dc->u.x.pen.pixel;
+    case R2_BLACK :
+	val.foreground = BlackPixel(display, DefaultScreen(display));
+	val.function = GXcopy;
+	break;
+    case R2_WHITE :
+	val.foreground = WhitePixel(display, DefaultScreen(display));
+	val.function = GXcopy;
+	break;
+    case R2_XORPEN :
+	val.foreground = dc->u.x.pen.pixel;
+	/* It is very unlikely someone wants to XOR with 0 */
+	/* This fixes the rubber-drawings in paintbrush */
+	if (val.foreground == 0)
+	    val.foreground = BlackPixel(display, DefaultScreen(display))
+			    ^ WhitePixel(display, DefaultScreen(display));
+	val.function = GXxor;
+	break;
+    default :
+	val.foreground = dc->u.x.pen.pixel;
+	val.function   = DC_XROPfunction[dc->w.ROPmode-1];
     }
     val.background = dc->w.backgroundPixel;
     val.fill_style = FillSolid;
@@ -341,25 +353,27 @@
  */
 BOOL32 DC_SetupGCForText( DC * dc )
 {
-    XGCValues val;
+    XFontStruct* xfs = XFONT_GetFontStruct( dc->u.x.font );
 
-    if (!dc->u.x.font.fstruct)
+    if( xfs )
     {
-        fprintf( stderr, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
-        return FALSE;
-    }
-   
-    if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
+	XGCValues val;
 
-    val.function   = GXcopy;  /* Text is always GXcopy */
-    val.foreground = dc->w.textPixel;
-    val.background = dc->w.backgroundPixel;
-    val.fill_style = FillSolid;
-    val.font       = dc->u.x.font.fstruct->fid;
-    XChangeGC( display, dc->u.x.gc, 
-	       GCFunction | GCForeground | GCBackground | GCFillStyle |
-	       GCFont, &val );
-    return TRUE;
+	if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
+
+	val.function   = GXcopy;  /* Text is always GXcopy */
+	val.foreground = dc->w.textPixel;
+	val.background = dc->w.backgroundPixel;
+	val.fill_style = FillSolid;
+	val.font       = xfs->fid;
+
+	XChangeGC( display, dc->u.x.gc,
+		   GCFunction | GCForeground | GCBackground | GCFillStyle |
+		   GCFont, &val );
+	return TRUE;
+    } 
+    fprintf( stderr, "DC_SetupGCForText: physical font failure\n" );
+    return FALSE;
 }
 
 
diff --git a/objects/dib.c b/objects/dib.c
index a951745..94743db 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -49,6 +49,9 @@
 {
     int		i;
 
+    if (!ximageDepthTable[0]) {
+	    DIB_Init();
+    }
     for( i = 0; bitmapDepthTable[i] ; i++ )
 	 if( bitmapDepthTable[i] == depth )
 	     return (4 * ((width * ximageDepthTable[i] + 31)/32));
@@ -97,14 +100,14 @@
     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
     {
         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
-        colors = (core->bcBitCount != 24) ? 1 << core->bcBitCount : 0;
+        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
         return sizeof(BITMAPCOREHEADER) + colors *
              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
     }
     else  /* assume BITMAPINFOHEADER */
     {
         colors = info->bmiHeader.biClrUsed;
-        if (!colors && (info->bmiHeader.biBitCount != 24))
+        if (!colors && (info->bmiHeader.biBitCount <= 8))
             colors = 1 << info->bmiHeader.biBitCount;
         return sizeof(BITMAPINFOHEADER) + colors *
                ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
@@ -590,10 +593,12 @@
 
       /* Build the color mapping table */
 
-    if (infoBpp == 24) colorMapping = NULL;
-    else
+    if (infoBpp > 8) {
+	    	colorMapping = NULL;
+    } else {
         if (!(colorMapping = DIB_BuildColorMap( dc, coloruse, depth, info )))
             return 0;
+    }
 
     if( dc->w.flags & DC_DIRTY ) CLIPPING_UpdateGCRegion(dc);
 
diff --git a/objects/font.c b/objects/font.c
index 3ac17db..e79c6b6 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -2,308 +2,206 @@
  * GDI font objects
  *
  * Copyright 1993 Alexandre Julliard
- *
- * Enhacements by Juergen Marquardt 1996
- *
- * Implementation of a second font cache which 
- * will be updated dynamically
+ *           1997 Alex Korobka
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <X11/Xatom.h>
 #include "font.h"
 #include "heap.h"
 #include "metafile.h"
 #include "options.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
-LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
+#define ENUM_UNICODE	0x00000001
 
-
-#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
-			     (((cs)->rbearing|(cs)->lbearing| \
-			       (cs)->ascent|(cs)->descent) == 0))
-
-/* 
- * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
- * character.  If the character is in the column and exists, then return the
- * appropriate metrics (note that fonts with common per-character metrics will
- * return min_bounds).  If none of these hold true, try again with the default
- * char.
- */
-#define CI_GET_CHAR_INFO(fs,col,def,cs) \
-{ \
-    cs = def; \
-    if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
-	if (fs->per_char == NULL) { \
-	    cs = &fs->min_bounds; \
-	} else { \
-	    cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
-	    if (CI_NONEXISTCHAR(cs)) cs = def; \
-	} \
-    } \
-}
-
-#define CI_GET_DEFAULT_INFO(fs,cs) \
-  CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
-
-
-
-
-/***********************************************************************
- *           FONT_LOGFONT32AToLOGFONT16
- */
-static void FONT_LOGFONT32AToLOGFONT16( const LOGFONT32A *font,
-                                        LPLOGFONT16 font16 )
+typedef struct
 {
-    font16->lfHeight         = (INT16)font->lfHeight;
-    font16->lfWidth          = (INT16)font->lfWidth;
-    font16->lfEscapement     = (INT16)font->lfEscapement;
-    font16->lfOrientation    = (INT16)font->lfOrientation;
-    font16->lfWeight         = (INT16)font->lfWeight;
-    font16->lfItalic         = font->lfItalic;
-    font16->lfUnderline      = font->lfUnderline;
-    font16->lfStrikeOut      = font->lfStrikeOut;
-    font16->lfCharSet        = font->lfCharSet;
-    font16->lfOutPrecision   = font->lfOutPrecision;
-    font16->lfClipPrecision  = font->lfClipPrecision;
-    font16->lfQuality        = font->lfQuality;
-    font16->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpyn32A( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
-}
+  LPLOGFONT16           lpLogFontParam;
+  FONTENUMPROCEX16      lpEnumFunc;
+  LPARAM                lpData;
 
+  LPNEWTEXTMETRICEX16   lpTextMetric;
+  LPENUMLOGFONTEX16     lpLogFont;
+  SEGPTR                segTextMetric;
+  SEGPTR                segLogFont;
+} fontEnum16;
 
-/***********************************************************************
- *           FONT_LOGFONT32WToLOGFONT16
- */
-static void FONT_LOGFONT32WToLOGFONT16( const LOGFONT32W *font,
-                                        LPLOGFONT16 font16 )
+typedef struct
 {
-    font16->lfHeight         = (INT16)font->lfHeight;
-    font16->lfWidth          = (INT16)font->lfWidth;
-    font16->lfEscapement     = (INT16)font->lfEscapement;
-    font16->lfOrientation    = (INT16)font->lfOrientation;
-    font16->lfWeight         = (INT16)font->lfWeight;
-    font16->lfItalic         = font->lfItalic;
-    font16->lfUnderline      = font->lfUnderline;
-    font16->lfStrikeOut      = font->lfStrikeOut;
-    font16->lfCharSet        = font->lfCharSet;
-    font16->lfOutPrecision   = font->lfOutPrecision;
-    font16->lfClipPrecision  = font->lfClipPrecision;
-    font16->lfQuality        = font->lfQuality;
-    font16->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpynWtoA( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
-}
+  LPLOGFONT32W          lpLogFontParam;
+  FONTENUMPROC32W       lpEnumFunc;
+  LPARAM                lpData;
 
-
+  LPNEWTEXTMETRICEX32W  lpTextMetric;
+  LPENUMLOGFONTEX32W    lpLogFont;
+  DWORD                 dwFlags;
+} fontEnum32;
+ 
 /***********************************************************************
- *           FONT_LOGFONT16ToLOGFONT32A
+ *              LOGFONT conversion functions.
  */
-static void FONT_LOGFONT16ToLOGFONT32A( LPLOGFONT16 font,
-                                        LPLOGFONT32A font32A )
+static void __logfont32to16( INT16* plf16, INT32* plf32 )
 {
-    font32A->lfHeight         = (INT32)font->lfHeight;
-    font32A->lfWidth          = (INT32)font->lfWidth;
-    font32A->lfEscapement     = (INT32)font->lfEscapement;
-    font32A->lfOrientation    = (INT32)font->lfOrientation;
-    font32A->lfWeight         = (INT32)font->lfWeight;
-    font32A->lfItalic         = font->lfItalic;
-    font32A->lfUnderline      = font->lfUnderline;
-    font32A->lfStrikeOut      = font->lfStrikeOut;
-    font32A->lfCharSet        = font->lfCharSet;
-    font32A->lfOutPrecision   = font->lfOutPrecision;
-    font32A->lfClipPrecision  = font->lfClipPrecision;
-    font32A->lfQuality        = font->lfQuality;
-    font32A->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpyn32A( font32A->lfFaceName, font->lfFaceName, LF_FACESIZE );
+    int  i;
+    for( i = 0; i < 5; i++ ) *plf16++ = *plf32++;
+   *((INT32*)plf16)++ = *plf32++;
+   *((INT32*)plf16)   = *plf32;
 }
 
-
-/***********************************************************************
- *           FONT_LOGFONT16ToLOGFONT32W
- */
-static void FONT_LOGFONT16ToLOGFONT32W( LPLOGFONT16 font,
-                                        LPLOGFONT32W font32W )
+static void __logfont16to32( INT32* plf32, INT16* plf16 )
 {
-    font32W->lfHeight         = (INT32)font->lfHeight;
-    font32W->lfWidth          = (INT32)font->lfWidth;
-    font32W->lfEscapement     = (INT32)font->lfEscapement;
-    font32W->lfOrientation    = (INT32)font->lfOrientation;
-    font32W->lfWeight         = (INT32)font->lfWeight;
-    font32W->lfItalic         = font->lfItalic;
-    font32W->lfUnderline      = font->lfUnderline;
-    font32W->lfStrikeOut      = font->lfStrikeOut;
-    font32W->lfCharSet        = font->lfCharSet;
-    font32W->lfOutPrecision   = font->lfOutPrecision;
-    font32W->lfClipPrecision  = font->lfClipPrecision;
-    font32W->lfQuality        = font->lfQuality;
-    font32W->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpynAtoW( font32W->lfFaceName, font->lfFaceName, LF_FACESIZE );
+    int i;
+    for( i = 0; i < 5; i++ ) *plf32++ = *plf16++;
+   *plf32++ = *((INT32*)plf16)++;
+   *plf32   = *((INT32*)plf16);
 }
 
-
-/***********************************************************************
- *           FONT_GetMetrics
- */
-void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
-		      TEXTMETRIC16 * metrics )
-{    
-    int average, i, count;
-    unsigned long prop;
-	
-    metrics->tmAscent  = xfont->ascent;
-    metrics->tmDescent = xfont->descent;
-    metrics->tmHeight  = xfont->ascent + xfont->descent;
-
-    metrics->tmInternalLeading  = 0;
-    if (XGetFontProperty( xfont, XA_CAP_HEIGHT, &prop ))
-	metrics->tmInternalLeading = xfont->ascent+xfont->descent-(INT16)prop;
-
-    metrics->tmExternalLeading  = 0;
-    metrics->tmMaxCharWidth     = xfont->max_bounds.width;
-    metrics->tmWeight           = logfont->lfWeight;
-    metrics->tmItalic           = logfont->lfItalic;
-    metrics->tmUnderlined       = logfont->lfUnderline;
-    metrics->tmStruckOut        = logfont->lfStrikeOut;
-    metrics->tmFirstChar        = xfont->min_char_or_byte2;
-    metrics->tmLastChar         = xfont->max_char_or_byte2;
-    metrics->tmDefaultChar      = xfont->default_char;
-    metrics->tmBreakChar        = ' ';
-    metrics->tmCharSet          = logfont->lfCharSet;
-    metrics->tmOverhang         = 0;
-    metrics->tmDigitizedAspectX = 1;
-    metrics->tmDigitizedAspectY = 1;
-    metrics->tmPitchAndFamily   = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
-
-    /* TMPF_FIXED_PITCH bit means variable pitch...Don't you love Microsoft? */
-    if (xfont->min_bounds.width != xfont->max_bounds.width)
-        metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
-
-    if (!xfont->per_char) average = metrics->tmMaxCharWidth;
-    else
-    {
-	XCharStruct * charPtr = xfont->per_char;
-	average = count = 0;
-	for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
-	{
-	    if (!CI_NONEXISTCHAR( charPtr ))
-	    {
-		average += charPtr->width;
-		count++;
-	    }
-	    charPtr++;
-	}
-	if (count) average = (average + count/2) / count;
-    }
-    metrics->tmAveCharWidth = average;
-}
-
-
-/***********************************************************************
- *           GetGlyphOutline16    (GDI.309)
- */
-DWORD GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
-                         LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
-                         LPVOID lpBuffer, const MAT2 *lpmat2 )
+void FONT_LogFont32ATo16( const LOGFONT32A* font32, LPLOGFONT16 font16 )
 {
-    fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
-             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
-    return (DWORD)-1; /* failure */
+  __logfont32to16( (INT16*)font16, (INT32*)font32 );
+    lstrcpyn32A( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
 }
 
-
-/***********************************************************************
- *           GetGlyphOutline32A    (GDI32.186)
- */
-DWORD GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
-                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
-                         LPVOID lpBuffer, const MAT2 *lpmat2 )
+void FONT_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 )
 {
-    fprintf( stdnimp,"GetGlyphOutLine32A(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
-             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
-    return (DWORD)-1; /* failure */
+  __logfont32to16( (INT16*)font16, (INT32*)font32 );
+    lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
 }
 
-
-/***********************************************************************
- *           GetGlyphOutline32W    (GDI32.187)
- */
-DWORD GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
-                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
-                         LPVOID lpBuffer, const MAT2 *lpmat2 )
+void FONT_LogFont16To32A( LPLOGFONT16 font16, LPLOGFONT32A font32 )
 {
-    fprintf( stdnimp,"GetGlyphOutLine32W(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
-             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
-    return (DWORD)-1; /* failure */
+  __logfont16to32( (INT32*)font32, (INT16*)font16 );
+    lstrcpyn32A( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
 }
 
-
-/***********************************************************************
- *           CreateScalableFontResource16   (GDI.310)
- */
-BOOL16 CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
-                                     LPCSTR fontFile, LPCSTR path )
+void FONT_LogFont16To32W( LPLOGFONT16 font16, LPLOGFONT32W font32 )
 {
-    return CreateScalableFontResource32A( fHidden, lpszResourceFile,
-                                          fontFile, path );
+  __logfont16to32( (INT32*)font32, (INT16*)font16 );
+    lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
 }
 
 /***********************************************************************
- *           CreateScalableFontResource32A   (GDI32.62)
+ *              TEXTMETRIC conversion functions.
  */
-BOOL32 CreateScalableFontResource32A( DWORD fHidden, LPCSTR lpszResourceFile,
-                                      LPCSTR lpszFontFile,
-                                      LPCSTR lpszCurrentPath )
+void FONT_TextMetric32Ato16( LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
 {
-    /* fHidden=1 - only visible for the calling app, read-only, not
-     * enumbered with EnumFonts/EnumFontFamilies
-     * lpszCurrentPath can be NULL
-     */
-    fprintf(stdnimp,"CreateScalableFontResource(%ld,%s,%s,%s) // empty stub\n",
-            fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
-    return FALSE; /* create failed */
+    int         i;
+    INT16*      pi16 = (INT16*)ptm16;
+
+   *(INT32*)&ptm16->tmFirstChar = *(INT32*)&ptm32->tmFirstChar;
+   *(INT32*)&ptm16->tmItalic = *(INT32*)&ptm32->tmItalic;
+   *(INT16*)&ptm16->tmPitchAndFamily = *(INT16*)&ptm32->tmPitchAndFamily;
+#define pi32 ((INT32*)ptm32)
+    for( i = 0; i < 8; i++ ) *pi16++ = *pi32++;
+    ptm16->tmOverhang = pi32[0];
+    ptm16->tmDigitizedAspectX = pi32[1];
+    ptm16->tmDigitizedAspectY = pi32[2];
+#undef  pi32
 }
 
-
-/***********************************************************************
- *           CreateScalableFontResource32W   (GDI32.63)
- */
-BOOL32 CreateScalableFontResource32W( DWORD fHidden, LPCWSTR lpszResourceFile,
-                                      LPCWSTR lpszFontFile,
-                                      LPCWSTR lpszCurrentPath )
+void FONT_TextMetric32Wto16( LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
 {
-    fprintf(stdnimp,"CreateScalableFontResource32W(%ld,%p,%p,%p) // empty stub\n",
-            fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
-    return FALSE; /* create failed */
+    int         i;
+    INT16*      pi16 = (INT16*)ptm16;
+
+    ptm16->tmFirstChar = ptm32->tmFirstChar;
+    ptm16->tmLastChar = ptm32->tmLastChar;
+    ptm16->tmDefaultChar = ptm32->tmDefaultChar;
+    ptm16->tmBreakChar = ptm32->tmBreakChar;
+   *(INT32*)&ptm16->tmItalic = *(INT32*)&ptm32->tmItalic;
+   *(INT16*)&ptm16->tmPitchAndFamily = *(INT16*)&ptm32->tmPitchAndFamily;
+#define pi32 ((INT32*)ptm32)
+    for( i = 0; i < 8; i++ ) *pi16++ = *pi32++;
+    ptm16->tmOverhang = pi32[0];
+    ptm16->tmDigitizedAspectX = pi32[1];
+    ptm16->tmDigitizedAspectY = pi32[2];
+#undef  pi32
 }
 
+void FONT_TextMetric16to32A( LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 )
+{
+    int         i;
+    INT16*      pi16 = (INT16*)ptm16;
+
+   *(INT32*)&ptm32->tmFirstChar = *(INT32*)&ptm16->tmFirstChar;
+   *(INT32*)&ptm32->tmItalic = *(INT32*)&ptm16->tmItalic;
+   *(INT16*)&ptm32->tmPitchAndFamily = *(INT16*)&ptm16->tmPitchAndFamily;
+#define pi32 ((INT32*)ptm32)
+    for( i = 0; i < 8; i++ ) *pi32++ = *pi16++;
+    pi32[0] = ptm16->tmOverhang;
+    pi32[1] = ptm16->tmDigitizedAspectX;
+    pi32[2] = ptm16->tmDigitizedAspectY;
+#undef  pi32
+}
+
+void FONT_TextMetric16to32W( LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 )
+{
+    int         i;
+    INT16*      pi16 = (INT16*)ptm16;
+
+    ptm32->tmFirstChar = ptm16->tmFirstChar;
+    ptm32->tmLastChar = ptm16->tmLastChar;
+    ptm32->tmDefaultChar = ptm16->tmDefaultChar;
+    ptm32->tmBreakChar = ptm16->tmBreakChar;
+   *(INT32*)&ptm32->tmItalic = *(INT32*)&ptm16->tmItalic;
+   *(INT16*)&ptm32->tmPitchAndFamily = *(INT16*)&ptm16->tmPitchAndFamily;
+#define pi32 ((INT32*)ptm32)
+    for( i = 0; i < 8; i++ ) *pi32++ = *pi16++;
+    pi32[0] = ptm16->tmOverhang;
+    pi32[1] = ptm16->tmDigitizedAspectX;
+    pi32[2] = ptm16->tmDigitizedAspectY;
+#undef  pi32
+}
+
+void FONT_TextMetric32Ato32W( LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W )
+{
+    int         i;
+#define pi32A ((INT32*)ptm32A)
+#define pi32W ((INT32*)ptm32W)
+    for( i = 0; i < 8; i++ ) *pi32W++ = *pi32A++;
+#undef pi32W
+#undef pi32A
+#define pch32A ((BYTE*)ptm32A)
+#define pch32W ((WCHAR*)ptm32W)
+   for( i = 0; i < 4; i++ ) *pch32W++ = *pch32A++;
+#undef pch32W
+#define pch32W ((BYTE*)ptm32W)
+   for( i = 0; i < 5; i++ ) *pch32W++ = *pch32A++;
+#undef pch32W
+#undef pch32A
+}
 
 /***********************************************************************
  *           CreateFontIndirect16   (GDI.57)
  */
 HFONT16 CreateFontIndirect16( const LOGFONT16 *font )
 {
-    FONTOBJ * fontPtr;
-    HFONT16 hfont;
+    HFONT16 hFont = 0;
 
-    if (!font)
+    if (font)
     {
-	fprintf(stderr,"CreateFontIndirect: font is NULL : returning NULL\n");
-	return 0;
-    }
-    hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
-    if (!hfont) return 0;
-    fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
-    memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
-    dprintf_font(stddeb,"CreateFontIndirect(%p (%d,%d)); return %04x\n",
-	font, font->lfHeight, font->lfWidth, hfont);
-    return hfont;
-}
+	hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
+	if( hFont )
+	{
+	    FONTOBJ* fontPtr;
+	    fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hFont );
+	    memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
 
+	    dprintf_font(stddeb,"CreateFontIndirect(%i %i) '%s' %s %s => %04x\n",
+				 font->lfHeight, font->lfWidth, 
+				 font->lfFaceName ? font->lfFaceName : "NULL",
+				 font->lfWeight > 400 ? "Bold" : "",
+				 font->lfItalic ? "Italic" : "",
+				 hFont);
+	}
+    }
+    else fprintf(stderr,"CreateFontIndirect(NULL) => NULL\n");
+
+    return hFont;
+}
 
 /***********************************************************************
  *           CreateFontIndirect32A   (GDI32.44)
@@ -312,12 +210,10 @@
 {
     LOGFONT16 font16;
 
-    FONT_LOGFONT32AToLOGFONT16(font,&font16);
-
+    FONT_LogFont32ATo16( font, &font16 );
     return CreateFontIndirect16( &font16 );
 }
 
-
 /***********************************************************************
  *           CreateFontIndirect32W   (GDI32.45)
  */
@@ -325,11 +221,10 @@
 {
     LOGFONT16 font16;
 
-    FONT_LOGFONT32WToLOGFONT16(font,&font16);
+    FONT_LogFont32WTo16( font, &font16 );
     return CreateFontIndirect16( &font16 );
 }
 
-
 /***********************************************************************
  *           CreateFont16    (GDI.56)
  */
@@ -338,16 +233,17 @@
                       BYTE strikeout, BYTE charset, BYTE outpres,
                       BYTE clippres, BYTE quality, BYTE pitch, LPCSTR name )
 {
-    LOGFONT16 logfont = {height, width, esc, orient, weight, italic, underline,
-                      strikeout, charset, outpres, clippres, quality, pitch, };
-    dprintf_font(stddeb,"CreateFont16(%d,%d)\n", height, width);
-    if (name) lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
-    else logfont.lfFaceName[0] = '\0';
+    LOGFONT16 logfont = { height, width, esc, orient, weight, italic, underline,
+                          strikeout, charset, outpres, clippres, quality, pitch, };
+
+    dprintf_font(stddeb,"CreateFont16('%s',%d,%d)\n", name, height, width);
+    if (name) 
+	lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
+    else 
+	logfont.lfFaceName[0] = '\0';
     return CreateFontIndirect16( &logfont );
 }
 
-
-
 /*************************************************************************
  *           CreateFont32A    (GDI32.43)
  */
@@ -361,7 +257,6 @@
                                   clippres, quality, pitch, name );
 }
 
-
 /*************************************************************************
  *           CreateFont32W    (GDI32.46)
  */
@@ -391,7 +286,6 @@
     return count;
 }
 
-
 /***********************************************************************
  *           FONT_GetObject32A
  */
@@ -399,22 +293,7 @@
 {
     LOGFONT32A fnt32;
 
-    memset(&fnt32, 0, sizeof(fnt32));
-    fnt32.lfHeight         = font->logfont.lfHeight;
-    fnt32.lfWidth          = font->logfont.lfWidth;
-    fnt32.lfEscapement     = font->logfont.lfEscapement;
-    fnt32.lfOrientation    = font->logfont.lfOrientation;
-    fnt32.lfWeight         = font->logfont.lfWeight;
-    fnt32.lfItalic         = font->logfont.lfItalic;
-    fnt32.lfUnderline      = font->logfont.lfUnderline;
-    fnt32.lfStrikeOut      = font->logfont.lfStrikeOut;
-    fnt32.lfCharSet        = font->logfont.lfCharSet;
-    fnt32.lfOutPrecision   = font->logfont.lfOutPrecision;
-    fnt32.lfClipPrecision  = font->logfont.lfClipPrecision;
-    fnt32.lfQuality        = font->logfont.lfQuality;
-    fnt32.lfPitchAndFamily = font->logfont.lfPitchAndFamily;
-    strncpy( fnt32.lfFaceName, font->logfont.lfFaceName,
-             sizeof(fnt32.lfFaceName) );
+    FONT_LogFont16To32A( &font->logfont, &fnt32 );
 
     if (count > sizeof(fnt32)) count = sizeof(fnt32);
     memcpy( buffer, &fnt32, count );
@@ -422,6 +301,207 @@
 }
 
 
+/***********************************************************************
+ *              FONT_EnumInstance16
+ *
+ * Called by the device driver layer to pass font info
+ * down to the application.
+ */
+static INT32 FONT_EnumInstance16( LPENUMLOGFONT16 plf, 
+				  LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
+{
+#define pfe ((fontEnum16*)lp)
+    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
+	pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
+    {
+	memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
+	memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
+
+        return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
+    }
+#undef pfe
+    return 1;
+}
+
+/***********************************************************************
+ *              FONT_EnumInstance32
+ */
+static INT32 FONT_EnumInstance32( LPENUMLOGFONT16 plf,
+				  LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
+{
+    /* lfCharSet is at the same offset in both LOGFONT32A and LOGFONT32W */
+
+#define pfe ((fontEnum32*)lp)
+    if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
+	pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
+    {
+	/* convert font metrics */
+
+	if( pfe->dwFlags & ENUM_UNICODE )
+	{
+	    FONT_LogFont16To32W( &plf->elfLogFont, (LPLOGFONT32W)(pfe->lpLogFont) );
+	    FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32W)(pfe->lpTextMetric) );
+	}
+	else
+	{
+	    FONT_LogFont16To32A( &plf->elfLogFont, (LPLOGFONT32A)pfe->lpLogFont );
+	    FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32A)pfe->lpTextMetric );
+	}
+
+        return pfe->lpEnumFunc( (LPENUMLOGFONT32W)pfe->lpLogFont, 
+				(LPNEWTEXTMETRIC32W)pfe->lpTextMetric, fType, pfe->lpData );
+    }
+#undef pfe
+    return 1;
+}
+
+/***********************************************************************
+ *              EnumFontFamiliesEx16	(GDI.613)
+ */
+INT16 EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf, FONTENUMPROCEX16 efproc, LPARAM lParam, DWORD dwFlags)
+{
+    INT16	retVal = 0;
+    DC* 	dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
+
+    if( dc && dc->funcs->pEnumDeviceFonts )
+    {
+	LPNEWTEXTMETRICEX16	lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
+	if( lptm16 )
+	{
+	    LPENUMLOGFONTEX16	lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
+	    if( lplf16 )
+	    {
+		fontEnum16	fe16 = { plf, efproc, lParam, lptm16, lplf16, 
+					 SEGPTR_GET(lptm16), SEGPTR_GET(lplf16) };
+
+		retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
+
+		SEGPTR_FREE(lplf16);
+	    }
+	    SEGPTR_FREE(lptm16);
+	}
+    }
+    return retVal;
+}
+
+/***********************************************************************
+ *		FONT_EnumFontFamiliesEx32
+ */
+static INT32 FONT_EnumFontFamiliesEx32( HDC32 hDC, LPLOGFONT32W plf, FONTENUMPROC32W efproc, 
+					           LPARAM lParam, DWORD dwUnicode)
+{
+    DC*		dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
+
+    if( dc && dc->funcs->pEnumDeviceFonts )
+    {
+	LOGFONT16		lf16;
+	NEWTEXTMETRICEX32W 	tm32w;
+	ENUMLOGFONTEX32W	lf32w;
+	fontEnum32		fe32 = { plf, efproc, lParam, &tm32w, &lf32w, dwUnicode }; 
+
+	/* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
+
+	if( plf->lfFaceName[0] )
+	{
+	    if( dwUnicode )
+		lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
+	    else
+		lstrcpyn32A( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
+	}
+	else lf16.lfFaceName[0] = '\0';
+	lf16.lfCharSet = plf->lfCharSet;
+
+	return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance32, (LPARAM)&fe32 );
+    }
+    return 0;
+}
+
+/***********************************************************************
+ *              EnumFontFamiliesEx32W	(GDI32.82)
+ */
+INT32 EnumFontFamiliesEx32W( HDC32 hDC, LPLOGFONT32W plf, FONTENUMPROCEX32W efproc, 
+					LPARAM lParam, DWORD dwFlags )
+{
+    return  FONT_EnumFontFamiliesEx32( hDC, plf, (FONTENUMPROC32W)efproc, 
+						  lParam, ENUM_UNICODE );
+}
+
+/***********************************************************************
+ *              EnumFontFamiliesEx32A	(GDI32.81)
+ */
+INT32 EnumFontFamiliesEx32A( HDC32 hDC, LPLOGFONT32A plf, FONTENUMPROCEX32A efproc, 
+					LPARAM lParam, DWORD dwFlags)
+{
+    return  FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)plf, 
+				      (FONTENUMPROC32W)efproc, lParam, 0);
+}
+
+/***********************************************************************
+ *              EnumFontFamilies16	(GDI.330)
+ */
+INT16 EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily, FONTENUMPROC16 efproc, LPARAM lpData )
+{
+    LOGFONT16	lf;
+
+    lf.lfCharSet = DEFAULT_CHARSET;
+    if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
+    else lf.lfFaceName[0] = '\0';
+
+    return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
+}
+
+/***********************************************************************
+ *              EnumFontFamilies32A	(GDI32.80)
+ */
+INT32 EnumFontFamilies32A( HDC32 hDC, LPCSTR lpFamily, FONTENUMPROC32A efproc, LPARAM lpData )
+{
+    LOGFONT32A	lf;
+
+    lf.lfCharSet = DEFAULT_CHARSET;
+    if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
+    else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
+
+    return FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)&lf, 
+					   (FONTENUMPROC32W)efproc, lpData, 0 );
+}
+
+/***********************************************************************
+ *              EnumFontFamilies32W	(GDI32.83)
+ */
+INT32 EnumFontFamilies32W( HDC32 hDC, LPCWSTR lpFamily, FONTENUMPROC32W efproc, LPARAM lpData )
+{
+    LOGFONT32W  lf;
+
+    lf.lfCharSet = DEFAULT_CHARSET;
+    if( lpFamily ) lstrcpyn32W( lf.lfFaceName, lpFamily, LF_FACESIZE );
+    else lf.lfFaceName[0] = 0;
+
+    return FONT_EnumFontFamiliesEx32( hDC, &lf, efproc, lpData, ENUM_UNICODE );
+}
+
+/***********************************************************************
+ *              EnumFonts16		(GDI.70)
+ */
+INT16 EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc, LPARAM lpData )
+{
+    return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
+}
+
+/***********************************************************************
+ *              EnumFonts32A		(GDI32.84)
+ */
+INT32 EnumFonts32A( HDC32 hDC, LPCSTR lpName, FONTENUMPROC32A efproc, LPARAM lpData )
+{
+    return EnumFontFamilies32A( hDC, lpName, efproc, lpData );
+}
+
+/***********************************************************************
+ *              EnumFonts32W		(GDI32.85)
+ */
+INT32 EnumFonts32W( HDC32 hDC, LPCWSTR lpName, FONTENUMPROC32W efproc, LPARAM lpData )
+{
+    return EnumFontFamilies32W( hDC, lpName, efproc, lpData );
+}
 
 
 /***********************************************************************
@@ -432,7 +512,7 @@
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
-	         / dc->vportExtX );
+                 / dc->vportExtX );
 }
 
 
@@ -444,7 +524,7 @@
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
-	         / dc->vportExtX );
+                 / dc->vportExtX );
 }
 
 
@@ -465,7 +545,7 @@
     INT32 prev;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
-    extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;    
+    extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
     prev = dc->w.charExtra;
     dc->w.charExtra = abs(extra);
     return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
@@ -494,14 +574,14 @@
     dc->w.breakTotalExtra = extra;
     dc->w.breakCount = breaks;
     if (breaks)
-    {	
-	dc->w.breakExtra = extra / breaks;
-	dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
+    {
+        dc->w.breakExtra = extra / breaks;
+        dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
     }
     else
     {
-	dc->w.breakExtra = 0;
-	dc->w.breakRem   = 0;
+        dc->w.breakExtra = 0;
+        dc->w.breakRem   = 0;
     }
     return 1;
 }
@@ -512,7 +592,7 @@
  */
 INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
 {
-	return GetTextFace32A(hdc,count,name);
+        return GetTextFace32A(hdc,count,name);
 }
 
 /***********************************************************************
@@ -579,7 +659,7 @@
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc)
     {
-	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
+        if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
             return FALSE;
     }
 
@@ -588,7 +668,7 @@
         return FALSE;
 
     dprintf_font(stddeb,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
-		 hdc, count, str, count, size, size->cx, size->cy );
+                 hdc, count, str, count, size, size->cx, size->cy );
     return TRUE;
 }
 
@@ -605,11 +685,12 @@
     return ret;
 }
 
+
 /***********************************************************************
  *           GetTextExtentPoint32ABuggy    (GDI32.232)
  */
 BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
-				   LPSIZE32 size )
+                                   LPSIZE32 size )
 {
     dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
     return GetTextExtentPoint32A( hdc, str, count, size );
@@ -619,7 +700,7 @@
  *           GetTextExtentPoint32WBuggy    (GDI32.233)
  */
 BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
-				   LPSIZE32 size )
+                                   LPSIZE32 size )
 {
     dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
     return GetTextExtentPoint32W( hdc, str, count, size );
@@ -633,39 +714,40 @@
                                 INT32 maxExt,LPINT32 lpnFit, LPINT32 alpDx,
                                 LPSIZE32 size )
 {
-  int index;
-  SIZE32 tSize;
-  int nFit=0;
-  int extent=0;
-  DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-  if (!dc)
-    {
-      if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-	return FALSE;
-    }
-  if (!dc->funcs->pGetTextExtentPoint) return FALSE;
+    int index, nFit, extent;
+    SIZE32 tSize;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
 
-  size->cx=0; size->cy=0;
-  for(index=0;index<count;index++)
+    if (!dc)
     {
-      if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
-      if(extent+tSize.cx<maxExt)
-	{
-	  extent+=tSize.cx;
-	  nFit++;
-	  str++;
-	  if(alpDx) alpDx[index]=extent;
-	  if(tSize.cy > size->cy) size->cy=tSize.cy;
-	}
-      else break;
+	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
+	    return FALSE;
     }
-  size->cx=extent;
-  *lpnFit=nFit;
-  dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
+    if (!dc->funcs->pGetTextExtentPoint) return FALSE;
+
+    size->cx = size->cy = nFit = extent = 0;
+    for(index = 0; index < count; index++)
+    {
+ 	if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
+	if( extent+tSize.cx < maxExt )
+        {
+	    extent+=tSize.cx;
+	    nFit++;
+	    str++;
+	    if( alpDx ) alpDx[index] = extent;
+	    if( tSize.cy > size->cy ) size->cy = tSize.cy;
+        }
+        else break;
+    }
+    size->cx = extent;
+   *lpnFit = nFit;
+
+    dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
                hdc,count,str,maxExt,nFit, size->cx,size->cy);
-  return TRUE;
+    return TRUE;
 }
 
+
 /***********************************************************************
  *           GetTextExtentExPoint32W    (GDI32.229)
  */
@@ -676,7 +758,7 @@
 {
     LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
-					lpnFit, alpDx, size);
+                                        lpnFit, alpDx, size);
     HeapFree( GetProcessHeap(), 0, p );
     return ret;
 }
@@ -686,29 +768,10 @@
  */
 BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
 {
-    TEXTMETRIC32A tm;
-    
-    if (!GetTextMetrics32A( (HDC32)hdc, &tm )) return FALSE;
-    metrics->tmHeight           = tm.tmHeight;
-    metrics->tmAscent           = tm.tmAscent;
-    metrics->tmDescent          = tm.tmDescent;
-    metrics->tmInternalLeading  = tm.tmInternalLeading;
-    metrics->tmExternalLeading  = tm.tmExternalLeading;
-    metrics->tmAveCharWidth     = tm.tmAveCharWidth;
-    metrics->tmMaxCharWidth     = tm.tmMaxCharWidth;
-    metrics->tmWeight           = tm.tmWeight;
-    metrics->tmOverhang         = tm.tmOverhang;
-    metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
-    metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
-    metrics->tmFirstChar        = tm.tmFirstChar;
-    metrics->tmLastChar         = tm.tmLastChar;
-    metrics->tmDefaultChar      = tm.tmDefaultChar;
-    metrics->tmBreakChar        = tm.tmBreakChar;
-    metrics->tmItalic           = tm.tmItalic;
-    metrics->tmUnderlined       = tm.tmUnderlined;
-    metrics->tmStruckOut        = tm.tmStruckOut;
-    metrics->tmPitchAndFamily   = tm.tmPitchAndFamily;
-    metrics->tmCharSet          = tm.tmCharSet;
+    TEXTMETRIC32A tm32;
+
+    if (!GetTextMetrics32A( (HDC32)hdc, &tm32 )) return FALSE;
+    FONT_TextMetric32Ato16( &tm32, metrics );
     return TRUE;
 }
 
@@ -718,57 +781,35 @@
  */
 BOOL32 GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
 {
-DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc)
     {
-	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
+        if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
             return FALSE;
     }
 
     if (!dc->funcs->pGetTextMetrics ||
         !dc->funcs->pGetTextMetrics( dc,metrics ))
         return FALSE;
-    dprintf_font(stdnimp,"text metrics:\n
-	InternalLeading = %i
-	ExternalLeading = %i
-	MaxCharWidth = %i
-	Weight = %i
-	Italic = %i
-	Underlined = %i
-	StruckOut = %i
-	FirstChar = %i
-	LastChar = %i
-	DefaultChar = %i
-	BreakChar = %i
-	CharSet = %i
-	Overhang = %i
-	DigitizedAspectX = %i
-	DigitizedAspectY = %i
-	AveCharWidth = %i
-	MaxCharWidth = %i
-	Ascent = %i
-	Descent = %i
-	Height = %i\n",
-                 metrics->tmInternalLeading,
-                 metrics->tmExternalLeading,
-                 metrics->tmMaxCharWidth,
-                 metrics->tmWeight,
-                 metrics->tmItalic,
-                 metrics->tmUnderlined,
-                 metrics->tmStruckOut,
-                 metrics->tmFirstChar,
-                 metrics->tmLastChar,
-                 metrics->tmDefaultChar,
-                 metrics->tmBreakChar,
-                 metrics->tmCharSet,
-                 metrics->tmOverhang,
-                 metrics->tmDigitizedAspectX,
-                 metrics->tmDigitizedAspectY,
-                 metrics->tmAveCharWidth,
-                 metrics->tmMaxCharWidth,
-                 metrics->tmAscent,
-                 metrics->tmDescent,
-                 metrics->tmHeight);
+
+    dprintf_font(stdnimp,"text metrics:
+    Weight = %03i\t FirstChar = %03i\t AveCharWidth = %i
+    Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %i
+    UnderLined = %01i\t DefaultChar = %03i\t Overhang = %i
+    StruckOut = %01i\t BreakChar = %03i\t CharSet = %i
+    --------------------
+    InternalLeading = %i
+    Ascent = %i
+    Descent = %i
+    Height = %i\n",
+    metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
+    metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
+    metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
+    metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
+    metrics->tmInternalLeading,
+    metrics->tmAscent,
+    metrics->tmDescent,
+    metrics->tmHeight );
     return TRUE;
 }
 
@@ -780,31 +821,82 @@
 {
     TEXTMETRIC32A tm;
     if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
-    metrics->tmHeight           = tm.tmHeight;
-    metrics->tmAscent           = tm.tmAscent;
-    metrics->tmDescent          = tm.tmDescent;
-    metrics->tmInternalLeading  = tm.tmInternalLeading;
-    metrics->tmExternalLeading  = tm.tmExternalLeading;
-    metrics->tmAveCharWidth     = tm.tmAveCharWidth;
-    metrics->tmMaxCharWidth     = tm.tmMaxCharWidth;
-    metrics->tmWeight           = tm.tmWeight;
-    metrics->tmOverhang         = tm.tmOverhang;
-    metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
-    metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
-    metrics->tmFirstChar        = tm.tmFirstChar;
-    metrics->tmLastChar         = tm.tmLastChar;
-    metrics->tmDefaultChar      = tm.tmDefaultChar;
-    metrics->tmBreakChar        = tm.tmBreakChar;
-    metrics->tmItalic           = tm.tmItalic;
-    metrics->tmUnderlined       = tm.tmUnderlined;
-    metrics->tmStruckOut        = tm.tmStruckOut;
-    metrics->tmPitchAndFamily   = tm.tmPitchAndFamily;
-    metrics->tmCharSet          = tm.tmCharSet;
+    FONT_TextMetric32Ato32W( &tm, metrics );
     return TRUE;
 }
 
 
 /***********************************************************************
+ *           GetCharWidth16    (GDI.350)
+ */
+BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
+                       LPINT16 buffer )
+{
+    BOOL32	retVal = FALSE;
+
+    if( firstChar != lastChar )
+    {
+	LPINT32	buf32 = (LPINT32)HeapAlloc(SystemHeap, 0,
+				 sizeof(INT32)*(1 + (lastChar - firstChar)));
+	if( buf32 )
+	{
+	    LPINT32	obuf32 = buf32;
+	    int		i;
+
+            retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
+	    if (retVal)
+	    {
+		for (i = firstChar; i <= lastChar; i++)
+		    *buffer++ = *buf32++;
+	    }
+	    HeapFree(SystemHeap, 0, obuf32);
+	}
+    }
+    else
+    {
+	INT32 chWidth;
+	retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
+	*buffer = chWidth;
+    }
+    return retVal;
+}
+
+
+/***********************************************************************
+ *           GetCharWidth32A    (GDI32.155)
+ */
+BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                        LPINT32 buffer )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc)
+    {
+        if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
+            return FALSE;
+    }
+
+    if (!dc->funcs->pGetCharWidth ||
+        !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
+        return FALSE;
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetCharWidth32W    (GDI32.158)
+ */
+BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                        LPINT32 buffer )
+{
+    return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
+}
+
+
+
+/* FIXME: all following APIs *******************************************
+ *
+ *
  *           SetMapperFlags16    (GDI.349)
  */
 DWORD SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
@@ -818,12 +910,12 @@
  */
 DWORD SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
 {
-    dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n", 
-		 hDC, dwFlag); 
+    dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
+                 hDC, dwFlag);
     return 0L;
 }
 
- 
+
 /***********************************************************************
  *           GetCharABCWidths16   (GDI.307)
  */
@@ -863,558 +955,78 @@
 
 
 /***********************************************************************
- *           GetCharWidth16    (GDI.350)
+ *           GetGlyphOutline16    (GDI.309)
  */
-BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
-                       LPINT16 buffer )
+DWORD GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
+                         LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
+                         LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    LPINT32	 buf32 = (LPINT32)xmalloc(sizeof(INT32)*(1 + (lastChar-firstChar)));
-    LPINT32	 obuf32;
-    BOOL32	 retVal;
-    int		 i;
-    if (!buf32)
-      return FALSE;
-    obuf32 = buf32;
-    retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
-    if (retVal)
-    {
-	for (i = firstChar; i <= lastChar; i++)
-	{
-	    *buffer++ = *buf32++;
-	}
-    }
-    free (obuf32);
-    return retVal;
+    fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+    return (DWORD)-1; /* failure */
 }
 
 
 /***********************************************************************
- *           GetCharWidth32A    (GDI32.155)
+ *           GetGlyphOutline32A    (GDI32.186)
  */
-BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
-                        LPINT32 buffer )
+DWORD GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
+                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
+                         LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc)
-    {
-	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-            return FALSE;
-    }
-
-    if (!dc->funcs->pGetCharWidth ||
-        !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
-        return FALSE;
-
-    return TRUE;
+    fprintf( stdnimp,"GetGlyphOutLine32A(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+    return (DWORD)-1; /* failure */
 }
 
-
 /***********************************************************************
- *           GetCharWidth32W    (GDI32.158)
+ *           GetGlyphOutline32W    (GDI32.187)
  */
-BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
-                        LPINT32 buffer )
+DWORD GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
+                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
+                         LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
+    fprintf( stdnimp,"GetGlyphOutLine32W(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+    return (DWORD)-1; /* failure */
 }
 
-
 /***********************************************************************
- *           AddFontResource16    (GDI.119)
+ *           CreateScalableFontResource16   (GDI.310)
  */
-INT16 AddFontResource16( LPCSTR str )
+BOOL16 CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
+                                     LPCSTR fontFile, LPCSTR path )
 {
-    return AddFontResource32A( str );
+    return CreateScalableFontResource32A( fHidden, lpszResourceFile,
+                                          fontFile, path );
 }
 
-
 /***********************************************************************
- *           AddFontResource32A    (GDI32.2)
+ *           CreateScalableFontResource32A   (GDI32.62)
  */
-INT32 AddFontResource32A( LPCSTR str )
+BOOL32 CreateScalableFontResource32A( DWORD fHidden, LPCSTR lpszResourceFile,
+                                      LPCSTR lpszFontFile,
+                                      LPCSTR lpszCurrentPath )
 {
-    if (HIWORD(str))
-        fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
-    else
-        fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
-    return 1;
+    /* fHidden=1 - only visible for the calling app, read-only, not
+     * enumbered with EnumFonts/EnumFontFamilies
+     * lpszCurrentPath can be NULL
+     */
+    fprintf(stdnimp,"CreateScalableFontResource(%ld,%s,%s,%s) // empty stub\n",
+            fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
+    return FALSE; /* create failed */
 }
 
-
 /***********************************************************************
- *           AddFontResource32W    (GDI32.4)
+ *           CreateScalableFontResource32W   (GDI32.63)
  */
-INT32 AddFontResource32W( LPCWSTR str )
+BOOL32 CreateScalableFontResource32W( DWORD fHidden, LPCWSTR lpszResourceFile,
+                                      LPCWSTR lpszFontFile,
+                                      LPCWSTR lpszCurrentPath )
 {
-    fprintf( stdnimp, "STUB: AddFontResource32W(%p)\n", str );
-    return 1;
-}
-
-
-/***********************************************************************
- *           RemoveFontResource16    (GDI.136)
- */
-BOOL16 RemoveFontResource16( LPCSTR str )
-{
-    return RemoveFontResource32A( str );
-}
-
-
-/***********************************************************************
- *           RemoveFontResource32A    (GDI32.284)
- */
-BOOL32 RemoveFontResource32A( LPCSTR str )
-{
-    if (HIWORD(str))
-        fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
-    else
-        fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           RemoveFontResource32W    (GDI32.286)
- */
-BOOL32 RemoveFontResource32W( LPCWSTR str )
-{
-    fprintf( stdnimp, "STUB: RemoveFontResource32W(%p)\n", str );
-    return TRUE;
-}
-
-
-/*************************************************************************
- *				FONT_ParseFontParms		[internal]
- */
-int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
-{
-	int 	i;
-	if (lpFont == NULL) return 0;
-	if (lpRetStr == NULL) return 0;
-	for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
-		if (*lpFont == '-') i++;
-		lpFont++;
-		}
-	if (i == wParmsNo) {
-		if (*lpFont == '-') lpFont++;
-		wMaxSiz--;
-		for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
-			*(lpRetStr + i) = *lpFont++;
-		*(lpRetStr + i) = '\0';
-		return i;
-		}
-	else
-		lpRetStr[0] = '\0';
-	return 0;
-}
-
-
-
-/*************************************************************************
- *				InitFontsList		[internal]
- */
-
-static int logfcmp(const void *a,const void *b) 
-{
-  return lstrcmpi32A( (*(LPLOGFONT16 *)a)->lfFaceName,
-                      (*(LPLOGFONT16 *)b)->lfFaceName );
-}
-
-void InitFontsList(void)
-{
-  char 	str[32];
-  char 	pattern[100];
-  char 	*family, *weight, *charset;
-  char 	**names;
-  char 	slant, spacing;
-  int 	i, count;
-  LPLOGFONT16 lpNewFont;
-
-  dprintf_font(stddeb,"InitFontsList !\n");
-
-  weight = "medium";
-  slant = 'r';
-  spacing = '*';
-  charset = "*";
-  family = "*-*";
-
-  sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
-	  family, weight, slant, spacing, charset);
-  names = XListFonts( display, pattern, MAX_FONTS, &count );
-  dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
-
-  lpNewFont = malloc((sizeof(LOGFONT16)+LF_FACESIZE)*count);
-  if (lpNewFont == NULL) {
-      dprintf_font(stddeb,
-		   "InitFontsList // Error alloc new font structure !\n");
-      XFreeFontNames(names);
-      return;
-  }
-
-  for (i = 0; i < count; i++) {
-    dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
-
-    FONT_ParseFontParms(names[i], 2, str, sizeof(str));
-    strcpy(lpNewFont->lfFaceName, str);
-    FONT_ParseFontParms(names[i], 8, str, sizeof(str));
-    lpNewFont->lfHeight = atoi(str) / 10;
-    FONT_ParseFontParms(names[i], 12, str, sizeof(str));
-    lpNewFont->lfWidth = atoi(str) / 10;
-    lpNewFont->lfEscapement = 0;
-    lpNewFont->lfOrientation = 0;
-    lpNewFont->lfWeight = FW_REGULAR;
-    lpNewFont->lfItalic = 0;
-    lpNewFont->lfUnderline = 0;
-    lpNewFont->lfStrikeOut = 0;
-    FONT_ParseFontParms(names[i], 13, str, sizeof(str));
-    if (strcmp(str, "iso8859") == 0)  {
-      lpNewFont->lfCharSet = ANSI_CHARSET;
-    } else  {
-      lpNewFont->lfCharSet = OEM_CHARSET;
-    }
-    lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
-    lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
-    lpNewFont->lfQuality = DEFAULT_QUALITY;
-    FONT_ParseFontParms(names[i], 11, str, sizeof(str));
-    switch(str[0]) {
-     case 'p':
-      lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
-      break;
-     case 'm':
-     case 'c':
-      lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
-      break;
-     default:
-      lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
-      break;
-    }
-    dprintf_font( stddeb,
-		  "InitFontsList // lpNewFont->lfHeight=%d\n",
-		  lpNewFont->lfHeight );
-    dprintf_font( stddeb,
-		  "InitFontsList // lpNewFont->lfWidth=%d\n",
-		  lpNewFont->lfWidth );
-    dprintf_font( stddeb,
-		  "InitFontsList // lfFaceName='%s'\n",
-		  lpNewFont->lfFaceName );
-    lpLogFontList[i] = lpNewFont;
-    lpNewFont = (LPLOGFONT16)
-      ((char *)lpNewFont + sizeof(LOGFONT16)+LF_FACESIZE);
-  }
-  lpLogFontList[i] = NULL;
-
-  qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
-  XFreeFontNames(names);
-}
-
-/*************************************************************************
- *				EnumFonts			[GDI.70]
- * We reuse EnumFontFamilies* for the callback function get the same
- * structs (+ extra stuff at the end which will be ignored by the enum funcs)
- */
-INT16 EnumFonts16(HDC16 hDC, LPCSTR lpFaceName, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
-{
-  return EnumFontFamilies16(hDC,lpFaceName,lpEnumFunc,lpData);
-}
-
-/*************************************************************************
- *				EnumFontsA			[GDI32.84]
- */
-INT32 EnumFonts32A(HDC32 hDC, LPCSTR lpFaceName, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
-{
-  return EnumFontFamilies32A(hDC,lpFaceName,lpEnumFunc,lpData);
-}
-
-/*************************************************************************
- *				EnumFontsA			[GDI32.84]
- */
-INT32 EnumFonts32W(HDC32 hDC, LPCWSTR lpFaceName, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
-{
-  return EnumFontFamilies32W(hDC,lpFaceName,lpEnumFunc,lpData);
-}
-
-/*************************************************************************
- *				EnumFontFamilies	[GDI.330]
- */
-INT16 EnumFontFamilies16(HDC16 hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
-{
-  LOGFONT16	LF;
-
-  if (lpszFamily)
-     strcpy(LF.lfFaceName,lpszFamily);
-  else
-     LF.lfFaceName[0]='\0';
-  LF.lfCharSet = DEFAULT_CHARSET;
-
-  return EnumFontFamiliesEx16(hDC,&LF,(FONTENUMPROCEX16)lpEnumFunc,lpData,0);
-}
-
-/*************************************************************************
- *				EnumFontFamiliesA	[GDI32.80]
- */
-INT32 EnumFontFamilies32A(HDC32 hDC, LPCSTR lpszFamily, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
-{
-  LOGFONT32A	LF;
-
-  if (lpszFamily)
-     strcpy(LF.lfFaceName,lpszFamily);
-  else
-     LF.lfFaceName[0]='\0';
-  LF.lfCharSet = DEFAULT_CHARSET;
-
-  return EnumFontFamiliesEx32A(hDC,&LF,(FONTENUMPROCEX32A)lpEnumFunc,lpData,0);
-}
-
-/*************************************************************************
- *				EnumFontFamiliesW	[GDI32.83]
- */
-INT32 EnumFontFamilies32W(HDC32 hDC, LPCWSTR lpszFamilyW, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
-{
-  LOGFONT32W	LF;
-
-  if (lpszFamilyW)
-  	lstrcpy32W(LF.lfFaceName,lpszFamilyW);
-  else
-  	LF.lfFaceName[0]=0;
-  LF.lfCharSet = DEFAULT_CHARSET;
-  return EnumFontFamiliesEx32W(hDC,&LF,(FONTENUMPROCEX32W)lpEnumFunc,lpData,0);
-}
-
-/*************************************************************************
- *				EnumFontFamiliesEx	[GDI.618]
- * FIXME: fill the rest of the NEWTEXTMETRICEX and ENUMLOGFONTEX structures.
- *        (applies to all EnumFontFamiliesEx*)
- *        winelib/16 support.
- */
-INT16 EnumFontFamiliesEx16(HDC16 hDC, LPLOGFONT16 lpLF, FONTENUMPROCEX16 lpEnumFunc, LPARAM lpData,DWORD reserved)
-{
-  HLOCAL16     	hLog;
-  HLOCAL16     	hMet;
-  HFONT16 hFont;
-  HFONT16 hOldFont;
-  LPENUMLOGFONTEX16 lpEnumLogFont;
-  LPNEWTEXTMETRICEX16 lptm;
-  LPSTR	       	lpOldName;
-  char	       	FaceName[LF_FACESIZE];
-  int	       	nRet = 0;
-  int	       	i;
-  
-  dprintf_font(stddeb,"EnumFontFamiliesEx(%04x, '%s', %08lx, %08lx, %08lx)\n",
-	       hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData, reserved);
-  if (lpEnumFunc == 0) return 0;
-  hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX16) );
-  lpEnumLogFont = (LPENUMLOGFONTEX16) GDI_HEAP_LIN_ADDR(hLog);
-  if (lpEnumLogFont == NULL) {
-    fprintf(stderr,"EnumFontFamiliesEx // can't alloc LOGFONT struct !\n");
-    return 0;
-  }
-  hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX16) );
-  lptm = (LPNEWTEXTMETRICEX16) GDI_HEAP_LIN_ADDR(hMet);
-  if (lptm == NULL) {
-    GDI_HEAP_FREE(hLog);
-    fprintf(stderr,"EnumFontFamiliesEx // can't alloc TEXTMETRIC struct !\n");
-    return 0;
-  }
-  lpOldName = NULL;
-  strcpy(FaceName,lpLF->lfFaceName);
-
-  if (lpLogFontList[0] == NULL) InitFontsList();
-  for(i = 0; lpLogFontList[i] != NULL; i++) {
-    /* lfCharSet */
-    if (lpLF->lfCharSet!=DEFAULT_CHARSET)
-    	if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
-	   continue;
-
-    /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
-    /* lfFaceName */
-    if (FaceName[0])
-    {
-    	if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
-	   continue;
-    }
-    else
-    {
-    	if ((lpOldName!=NULL) &&
-            !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
-	   continue;
-	lpOldName=lpLogFontList[i]->lfFaceName;
-    }
-
-    memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT16));
-    strcpy(lpEnumLogFont->elfFullName,"");
-    strcpy(lpEnumLogFont->elfStyle,"");
-    hFont = CreateFontIndirect16((LPLOGFONT16)lpEnumLogFont);
-    hOldFont = SelectObject32(hDC, hFont);
-    GetTextMetrics16(hDC, (LPTEXTMETRIC16)lptm);
-    SelectObject32(hDC, hOldFont);
-    DeleteObject32(hFont);
-    dprintf_font(stddeb, "EnumFontFamiliesEx // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
-    
-    nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
-                       0, lpData );
-    if (nRet == 0) {
-      dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
-      break;
-    }
-  }
-  GDI_HEAP_FREE(hMet);
-  GDI_HEAP_FREE(hLog);
-  return nRet;
-}
-
-
-/*************************************************************************
- *				EnumFontFamiliesExA	[GDI32.81]
- * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
- */
-INT32 EnumFontFamiliesEx32A(HDC32 hDC, LPLOGFONT32A lpLF,FONTENUMPROCEX32A lpEnumFunc, LPARAM lpData,DWORD reserved)
-{
-  HLOCAL16     	hLog;
-  HLOCAL16     	hMet;
-  HFONT32	hFont;
-  HFONT32	hOldFont;
-  LPENUMLOGFONTEX32A	lpEnumLogFont;
-  LPNEWTEXTMETRICEX32A	lptm;
-  LPSTR	       	lpOldName;
-  char	       	FaceName[LF_FACESIZE];
-  int	       	nRet = 0;
-  int	       	i;
-  
-  dprintf_font(stddeb,"EnumFontFamilies32A(%04x, %p, %08lx, %08lx, %08lx)\n",
-	       hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData,reserved);
-  if (lpEnumFunc == 0) return 0;
-  hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32A) );
-  lpEnumLogFont = (LPENUMLOGFONTEX32A) GDI_HEAP_LIN_ADDR(hLog);
-  if (lpEnumLogFont == NULL) {
-    fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
-    return 0;
-  }
-  hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32A) );
-  lptm = (LPNEWTEXTMETRICEX32A) GDI_HEAP_LIN_ADDR(hMet);
-  if (lptm == NULL) {
-    GDI_HEAP_FREE(hLog);
-    fprintf(stderr,"EnumFontFamilies32A // can't alloc TEXTMETRIC struct !\n");
-    return 0;
-  }
-  lpOldName = NULL;
-  strcpy(FaceName,lpLF->lfFaceName);
-
-  if (lpLogFontList[0] == NULL) InitFontsList();
-  for(i = 0; lpLogFontList[i] != NULL; i++) {
-    /* lfCharSet */
-    if (lpLF->lfCharSet!=DEFAULT_CHARSET)
-    	if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
-	   continue;
-
-    /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
-    /* lfFaceName */
-    if (FaceName[0]) {
-    	if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
-	   continue;
-    } else {
-    	if ((lpOldName!=NULL) &&
-            !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
-	   continue;
-	lpOldName=lpLogFontList[i]->lfFaceName;
-    }
-
-    FONT_LOGFONT16ToLOGFONT32A(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
-    strcpy(lpEnumLogFont->elfFullName,"");
-    strcpy(lpEnumLogFont->elfStyle,"");
-    strcpy(lpEnumLogFont->elfScript,"");
-    hFont = CreateFontIndirect32A((LPLOGFONT32A)lpEnumLogFont);
-    hOldFont = SelectObject32(hDC, hFont);
-    GetTextMetrics32A(hDC, (LPTEXTMETRIC32A)lptm);
-    SelectObject32(hDC, hOldFont);
-    DeleteObject32(hFont);
-    dprintf_font(stddeb, "EnumFontFamiliesEx32A // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
-    
-    nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
-    if (nRet == 0) {
-      dprintf_font(stddeb,"EnumFontFamiliesEx32A // EnumEnd requested by application !\n");
-      break;
-    }
-  }
-  GDI_HEAP_FREE(hMet);
-  GDI_HEAP_FREE(hLog);
-  return nRet;
-}
-
-
-/*************************************************************************
- *				EnumFontFamiliesW	[GDI32.82]
- */
-INT32 EnumFontFamiliesEx32W(HDC32 hDC, LPLOGFONT32W lpLF, FONTENUMPROCEX32W lpEnumFunc, LPARAM lpData, DWORD reserved)
-{
-  HLOCAL16     	hLog;
-  HLOCAL16     	hMet;
-  HFONT32	hFont;
-  HFONT32	hOldFont;
-  LPENUMLOGFONTEX32W	lpEnumLogFont;
-  LPNEWTEXTMETRICEX32W	lptm;
-  LPSTR	       	lpOldName;
-  int	       	nRet = 0;
-  int	       	i;
-  LPSTR	lpszFamily;
-  
-  dprintf_font(stddeb,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
-	       hDC, lpLF, (DWORD)lpEnumFunc, lpData,reserved);
-  if (lpEnumFunc == 0) return 0;
-  hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W) );
-  lpEnumLogFont = (LPENUMLOGFONTEX32W) GDI_HEAP_LIN_ADDR(hLog);
-  if (lpEnumLogFont == NULL) {
-    fprintf(stderr,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
-    return 0;
-  }
-  hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W) );
-  lptm = (LPNEWTEXTMETRICEX32W) GDI_HEAP_LIN_ADDR(hMet);
-  if (lptm == NULL) {
-    GDI_HEAP_FREE(hLog);
-    fprintf(stderr,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
-    return 0;
-  }
-  lpOldName = NULL;
-  lpszFamily = HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF->lfFaceName );
-  if (lpLogFontList[0] == NULL) InitFontsList();
-  for(i = 0; lpLogFontList[i] != NULL; i++) {
-    /* lfCharSet */
-    if (lpLF->lfCharSet!=DEFAULT_CHARSET)
-    	if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
-	   continue;
-
-    /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
-    /* lfFaceName */
-    if (lpszFamily[0]) {
-    	if (lstrcmpi32A(lpszFamily,lpLogFontList[i]->lfFaceName))
-	   continue;
-    } else {
-    	if ((lpOldName!=NULL) &&
-            !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
-	   continue;
-	lpOldName=lpLogFontList[i]->lfFaceName;
-    }
-
-    FONT_LOGFONT16ToLOGFONT32W(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
-    lpEnumLogFont->elfFullName[0] = 0;
-    lpEnumLogFont->elfStyle[0] = 0;
-    lpEnumLogFont->elfScript[0] = 0;
-    hFont = CreateFontIndirect32W((LPLOGFONT32W)lpEnumLogFont);
-    hOldFont = SelectObject32(hDC, hFont);
-    GetTextMetrics32W(hDC, (LPTEXTMETRIC32W)lptm);
-    SelectObject32(hDC, hOldFont);
-    DeleteObject32(hFont);
-    dprintf_font(stddeb, "EnumFontFamilies32W // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
-    
-    nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
-    if (nRet == 0) {
-      dprintf_font(stddeb,"EnumFontFamilies32W // EnumEnd requested by application !\n");
-      break;
-    }
-  }
-  GDI_HEAP_FREE(hMet);
-  GDI_HEAP_FREE(hLog);
-  HeapFree( GetProcessHeap(), 0, lpszFamily );
-  return nRet;
+    fprintf(stdnimp,"CreateScalableFontResource32W(%ld,%p,%p,%p) // empty stub\n",
+            fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
+    return FALSE; /* create failed */
 }
 
 
@@ -1432,9 +1044,8 @@
  */
 BOOL32 GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes )
 {
-  /* This is not much more than a dummy */
   RASTERIZER_STATUS rs;
-  
+
   rs.nSize = sizeof(rs);
   rs.wFlags = 0;
   rs.nLanguageID = 0;
@@ -1448,10 +1059,7 @@
 INT16 GetKerningPairs16( HDC16 hDC, INT16 cPairs,
                          LPKERNINGPAIR16 lpKerningPairs )
 {
-    /* This has to be dealt with when proper font handling is in place 
-     *
-     * At this time kerning is ignored (set to 0)
-     */
+    /* At this time kerning is ignored (set to 0) */
     int i;
     fprintf(stdnimp,"GetKerningPairs16: almost empty stub!\n");
     for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
@@ -1459,16 +1067,13 @@
 }
 
 
+
 /*************************************************************************
  *             GetKerningPairs32A   (GDI32.192)
  */
 DWORD GetKerningPairs32A( HDC32 hDC, DWORD cPairs,
                           LPKERNINGPAIR32 lpKerningPairs )
 {
-    /* This has to be dealt with when proper font handling is in place 
-     *
-     * At this time kerning is ignored (set to 0)
-     */
     int i;
     fprintf(stdnimp,"GetKerningPairs32: almost empty stub!\n");
     for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
@@ -1484,3 +1089,4 @@
 {
     return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );
 }
+
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 89aad65..52c8bd5 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -100,14 +100,14 @@
 {
     { 0, FONT_MAGIC, 1 },   /* header */
     { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
+      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
 };
 
 static FONTOBJ SystemFont =
 {
-    { 0, FONT_MAGIC, 1 },   /* header */
+    { 0, FONT_MAGIC, 1 },
     { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
-      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
+      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
 };
 
 static FONTOBJ DeviceDefaultFont =
@@ -142,7 +142,7 @@
     (GDIOBJHDR *) &AnsiVarFont,
     (GDIOBJHDR *) &SystemFont,
     (GDIOBJHDR *) &DeviceDefaultFont,
-    NULL,            /* DEFAULT_PALETTE created by COLOR_Init */
+    NULL,            /* DEFAULT_PALETTE created by PALETTE_Init */
     (GDIOBJHDR *) &SystemFixedFont
 };
 
@@ -154,21 +154,26 @@
  */
 BOOL32 GDI_Init(void)
 {
-    HPALETTE16 hpalette;
     extern BOOL32 X11DRV_Init(void);
     extern BOOL32 DIB_Init(void);
 
     /* Initialize drivers */
 
-    if (!X11DRV_Init()) return FALSE;
-    if (!DIB_Init()) return FALSE;
+    DIB_Init();	/* always before X11DRV_Init() */
 
-      /* Create default palette */
+    if( X11DRV_Init() )
+    {
+	/* Create default palette */
 
-    if (!(hpalette = COLOR_Init())) return FALSE;
-    StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LIN_ADDR( hpalette );
+	HPALETTE16 hpalette = PALETTE_Init();
 
-    return TRUE;
+	if( hpalette )
+	{
+	    StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LIN_ADDR( hpalette );
+	    return TRUE;
+	}
+    }
+    return FALSE;
 }
 
 
diff --git a/objects/metafile.c b/objects/metafile.c
index 5c5da99..87e0b34 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -304,18 +304,29 @@
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
+    HANDLETABLE16 *ht;
     HGLOBAL16 hHT;
-    SEGPTR ht, spRecord;
+    SEGPTR spht, spRecord;
     int offset = 0;
-  
+    WORD i;
+    HPEN32 hPen;
+    HBRUSH32 hBrush;
+    HFONT32 hFont;
+    DC *dc;
+    
     dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
 		     hdc, hmf, (DWORD)lpEnumFunc, lpData);
+
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    hPen = dc->w.hPen;
+    hBrush = dc->w.hBrush;
+    hFont = dc->w.hFont;
    
     /* create the handle table */
     
     hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
 		     sizeof(HANDLETABLE16) * mh->mtNoObjects);
-    ht = WIN16_GlobalLock16(hHT);
+    spht = WIN16_GlobalLock16(hHT);
    
     offset = mh->mtHeaderSize * 2;
     
@@ -325,7 +336,7 @@
     while (offset < (mh->mtSize * 2))
     {
 	mr = (METARECORD *)((char *)mh + offset);
-        if (!lpEnumFunc( hdc, (HANDLETABLE16 *)ht,
+        if (!lpEnumFunc( hdc, (HANDLETABLE16 *)spht,
                          (METARECORD *)((UINT32)spRecord + offset),
                          mh->mtNoObjects, (LONG)lpData))
 	    break;
@@ -333,6 +344,17 @@
 	offset += (mr->rdSize * 2);
     }
 
+    SelectObject32(hdc, hBrush);
+    SelectObject32(hdc, hPen);
+    SelectObject32(hdc, hFont);
+
+    ht = (HANDLETABLE16 *)GlobalLock16(hHT);
+
+    /* free objects in handle table */
+    for(i = 0; i < mh->mtNoObjects; i++)
+      if(*(ht->objectHandle + i) != 0)
+        DeleteObject32(*(ht->objectHandle + i));
+
     /* free handle table */
     GlobalFree16(hHT);
 
@@ -1165,9 +1187,13 @@
     DWORD len;
     HGLOBAL16 hmr;
     METARECORD *mr;
-
+    
+    if((!flags && rect) || (flags && !rect))
+	fprintf(stderr, "MF_ExtTextOut: Inconsistent flags and rect\n");
     len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
-	    + sizeof(UINT16) + sizeof(RECT16);
+	    + sizeof(UINT16);
+    if(rect)
+        len += sizeof(RECT16);
     if (lpDx)
      len+=count*sizeof(INT16);
     if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
@@ -1182,9 +1208,10 @@
     *(mr->rdParam + 2) = count;
     *(mr->rdParam + 3) = flags;
     if (rect) memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
-    memcpy(mr->rdParam + 8, str, count);
+    memcpy(mr->rdParam + (rect ? 8 : 4), str, count);
     if (lpDx)
-     memcpy(mr->rdParam + 8+ ((count + 1) >> 1),lpDx,count*sizeof(INT16));
+     memcpy(mr->rdParam + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
+      count*sizeof(INT16));
     ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
     GlobalFree16(hmr);
     return ret;
diff --git a/objects/palette.c b/objects/palette.c
index 75e11a6..74207b8 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -4,6 +4,8 @@
  * Copyright 1993,1994 Alexandre Julliard
  * Copyright 1996 Alex Korobka
  *
+ * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
+ * Information in the "Undocumented Windows" is incorrect.
  */
 
 #include <stdlib.h>
@@ -28,6 +30,45 @@
 
 
 /***********************************************************************
+ *           PALETTE_Init
+ *
+ * Create the system palette.
+ */
+HPALETTE16 PALETTE_Init(void)
+{
+    extern const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void);
+
+    int                 i;
+    HPALETTE16          hpalette;
+    LOGPALETTE *        palPtr;
+    PALETTEOBJ*         palObj;
+    const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();
+
+    /* create default palette (20 system colors) */
+
+    palPtr = xmalloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
+    if (!palPtr) return FALSE;
+
+    palPtr->palVersion = 0x300;
+    palPtr->palNumEntries = NB_RESERVED_COLORS;
+    for( i = 0; i < NB_RESERVED_COLORS; i ++ )
+    {
+        palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
+        palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
+        palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
+        palPtr->palPalEntry[i].peFlags = 0;
+    }
+    hpalette = CreatePalette16( palPtr );
+
+    palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+
+    palObj->mapping = xmalloc( sizeof(int) * 20 );
+
+    free( palPtr );
+    return hpalette;
+}
+
+/***********************************************************************
  *           PALETTE_ValidateFlags
  */
 void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
diff --git a/objects/region.c b/objects/region.c
index 3575132..9148e6d 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -2,6 +2,8 @@
  * GDI region objects
  *
  * Copyright 1993, 1994, 1995 Alexandre Julliard
+ *
+ * RGNOBJ is documented in the Dr. Dobbs Journal March 1993.
  */
 
 #include <stdlib.h>
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog
index 8e1fac0..4a78235 100644
--- a/programs/progman/ChangeLog
+++ b/programs/progman/ChangeLog
@@ -1,3 +1,8 @@
+Tue Jun  3 07:34:26 1997  Marcel Baur <mbaur@g26.ethz.ch>
+
+	* [Va.rc] (new)
+	Added Vallader (Rumantsch Ladin) language support.
+
 Wed Feb 12 00:58:37 1997  Elker Cavina <elker@mail.asianet.it>
 
 	* [It.rc] (new)
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index 52e380e..f7ecaeb 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -8,7 +8,7 @@
 DEFS      = -I$(SRCDIR)
 RCFLAGS   = -w32
 
-LANGUAGES   = En De Fr Fi Ko Hu It
+LANGUAGES   = En De Fr Fi Ko Hu It Va
 LICENSELANG = En
 
 # Installation infos
diff --git a/programs/progman/Va.rc b/programs/progman/Va.rc
new file mode 100644
index 0000000..3d5963c
--- /dev/null
+++ b/programs/progman/Va.rc
@@ -0,0 +1,124 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ *
+ * Rumantsch Ladin (Vallader) added by mbaur@g26.ethz.ch
+ *
+ */
+
+#define LANGUAGE_ID                  Rl
+#define LANGUAGE_NUMBER              2
+#define LANGUAGE_MENU_ITEM           "&Vallader"
+
+/* Menu */
+
+#define MENU_FILE                    "&Datoteca"
+#define MENU_FILE_NEW                "&Nouv..."
+#define MENU_FILE_OPEN               "&Rivir\tEndataziun"
+#define MENU_FILE_MOVE               "&Spostar...\tF7"
+#define MENU_FILE_COPY               "&Copchar...\tF8"
+#define MENU_FILE_DELETE             "S&tüder\tDel"
+#define MENU_FILE_ATTRIBUTES         "&Particularitads...\tAlt+Endataziun"
+#define MENU_FILE_EXECUTE            "&Esegnir..."
+#define MENU_FILE_EXIT               "&Finir WINE..."
+
+#define MENU_OPTIONS                 "&Opziuns"
+#define MENU_OPTIONS_AUTO_ARRANGE    "Ordinar &automaticamaing"
+#define MENU_OPTIONS_MIN_ON_RUN      "&Simbol davo'l cummainzamaint dal program"
+#define MENU_OPTIONS_SAVE_SETTINGS   "Arcunar conzepziuns a la &finischina"
+
+#define MENU_WINDOWS                 "&Fanestra"
+#define MENU_WINDOWS_OVERLAP         "&cruschond\tShift+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE    "ün &dasper l'oter\tShift+F4"
+#define MENU_WINDOWS_ARRANGE         "&ordinar ils simbols"
+
+#define MENU_LANGUAGE                "&Lingun"
+
+#define MENU_HELP                    "&Agüd"
+#define MENU_HELP_CONTENTS           "&Cuntgnü"
+#define MENU_HELP_SEARCH             "&Tscherchar..."
+#define MENU_HELP_HELP_ON_HELP       "&Douvrar l'agüd"
+#define MENU_HELP_TUTORIAL           "&Program d'imprender"
+
+#define MENU_INFO                    "Inf&ormaziun..."
+#define MENU_INFO_LICENSE            "&Liceza"
+#define MENU_INFO_NO_WARRANTY        "&INGUENA GARANZIA"
+#define MENU_INFO_ABOUT_WINE         "&Davart WINE"
+
+/* Dialogs */
+
+#define DIALOG_OK                    "OK"
+#define DIALOG_CANCEL                "Far giö quint"
+#define DIALOG_BROWSE                "&Tscherchar tras..."
+#define DIALOG_HELP                  "&Agüd"
+
+#define DIALOG_NEW_CAPTION           "Nouv proget da program"
+#define DIALOG_NEW_NEW               "Nouv"
+#define DIALOG_NEW_GROUP             "&Gruppa da programs"
+#define DIALOG_NEW_PROGRAM           "&Program"
+
+#define DIALOG_MOVE_CAPTION          "Spostar il program"
+#define DIALOG_MOVE_PROGRAM          "Spostar il program:"
+#define DIALOG_MOVE_FROM_GROUP       "&Da la gruppa:"
+#define DIALOG_MOVE_TO_GROUP         "&In gruppa:"
+
+#define DIALOG_COPY_CAPTION          "Copchar il program"
+#define DIALOG_COPY_PROGRAM          "Copchar il program:"
+#define DIALOG_COPY_FROM_GROUP       DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP         DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_CAPTION         "Particularitads da las gruppas"
+#define DIALOG_GROUP_DESCRIPTION     "&Descripziun:"
+#define DIALOG_GROUP_FILE            "Dato&teca:"
+
+#define DIALOG_PROGRAM_CAPTION       "Particularitads dal program"
+#define DIALOG_PROGRAM_DESCRIPTION   DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE  "&Lingia da cumonds:"
+#define DIALOG_PROGRAM_DIRECTORY     "&Register da lavuors:"
+#define DIALOG_PROGRAM_HOT_KEY       "&Cumbinaziun:"
+#define DIALOG_PROGRAM_SYMBOL        "Sco Si&mbol"
+#define DIALOG_PROGRAM_OTHER_SYMBOL  "Oter &Simbol..."
+
+#define DIALOG_SYMBOL_CAPTION        "Tscherner Simbol"
+#define DIALOG_SYMBOL_FILE           "&Nom da la Datoteca:"
+#define DIALOG_SYMBOL_CURRENT        "Simbol &actual:"
+
+#define DIALOG_EXECUTE_CAPTION       "Eseguir program"
+#define DIALOG_EXECUTE_COMMAND_LINE  DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL        DIALOG_PROGRAM_SYMBOL
+
+/* Strings */
+
+#define STRING_PROGRAM_MANAGER            "Manager da programs"
+#define STRING_ERROR                      "SBAGL"
+#define STRING_WARNING                    "ATTENTIUN"
+#define STRING_INFO                       "Infuormaziun"
+#define STRING_DELETE                     "Stüder"
+#define STRING_DELETE_GROUP_s             "Stüder la gruppa da programs `%s' ?"
+#define STRING_DELETE_PROGRAM_s           "Stüder il program `%s' ?"
+#define STRING_NOT_IMPLEMENTED            "Na implementa"
+#define STRING_FILE_READ_ERROR_s          "Sbagl cun leger `%s'"
+#define STRING_FILE_WRITE_ERROR_s         "Sbagl cun scriver `%s'"
+
+#define STRING_GRPFILE_READ_ERROR_s       "\
+La datoteca da gruppas da program '%s' nu po gnir rivida.\n\
+Esa da prouar inavant da chargiar quista\n"
+
+#define STRING_OUT_OF_MEMORY              "Massa paca memoria"
+#define STRING_WINHELP_ERROR              "Ingün agüd a disposiziun"
+#define STRING_UNKNOWN_FEATURE_s          "Funcziun incuntschainta in %s"
+#define STRING_FILE_NOT_OVERWRITTEN_s     "Datoteca `%s' exista fingià. Ella nu vegn."
+#define STRING_SAVE_GROUP_AS_s            "\
+La gruppa vegn sgürada cul nom '%s' per evitar \
+cha la datoteca originala vegna surscritta."
+
+#define STRING_NO_HOT_KEY                 "Ingiüna"
+
+#define STRING_ALL_FILES                  "Tuot las datotecas (*.*)"
+#define STRING_PROGRAMS                   "Programs"
+#define STRING_LIBRARIES_DLL              "Bibliotecas (*.dll)"
+#define STRING_SYMBOL_FILES               "Datotecas da simbols"
+#define STRING_SYMBOLS_ICO                "Simbols (*.ico)"
+
+#include "Xx.rc"
diff --git a/scheduler/process.c b/scheduler/process.c
index 68686d5..6e9db29 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -12,6 +12,7 @@
 #include "file.h"
 #include "heap.h"
 #include "task.h"
+#include "thread.h"
 #include "winerror.h"
 
 PDB32 *pCurrentProcess = NULL;
@@ -786,3 +787,123 @@
     SetLastError( ERROR_INVALID_PARAMETER );
     return FALSE;
 }
+
+/***********************************************************************
+ *           _KERNEL32_18    (KERNEL32.18,Win95)
+ * 'Of course you cannot directly access Windows internal structures'
+ */
+extern THDB *pCurrentThread;
+DWORD
+_KERNEL32_18(DWORD processid,DWORD action) {
+	PDB32	*process;
+	TDB	*pTask;
+
+	action+=56;
+	fprintf(stderr,"_KERNEL32_18(%ld,%ld+0x38)\n",processid,action);
+	if (action>56)
+		return 0;
+	if (!processid) {
+		process=pCurrentProcess;
+		/* check if valid process */
+	} else
+		process=(PDB32*)pCurrentProcess; /* decrypt too, if needed */
+	switch (action) {
+	case 0:	/* return app compat flags */
+		pTask = (TDB*)GlobalLock16(process->task);
+		if (!pTask)
+			return 0;
+		return pTask->compat_flags;
+	case 4:	/* returns offset 0xb8 of process struct... dunno what it is */
+		return 0;
+	case 8:	/* return hinstance16 */
+		pTask = (TDB*)GlobalLock16(process->task);
+		if (!pTask)
+			return 0;
+		return pTask->hInstance;
+	case 12:/* return expected windows version */
+		pTask = (TDB*)GlobalLock16(process->task);
+		if (!pTask)
+			return 0;
+		return pTask->version;
+	case 16:/* return uncrypted pointer to current thread */
+		return (DWORD)pCurrentThread;
+	case 20:/* return uncrypted pointer to process */
+		return (DWORD)process;
+	case 24:/* return stdoutput handle from startupinfo */
+		return (DWORD)(process->env_db->startup_info->hStdOutput);
+	case 28:/* return stdinput handle from startupinfo */
+		return (DWORD)(process->env_db->startup_info->hStdInput);
+	case 32:/* get showwindow flag from startupinfo */
+		return (DWORD)(process->env_db->startup_info->wShowWindow);
+	case 36:{/* return startup x and y sizes */
+		LPSTARTUPINFO32A si = process->env_db->startup_info;
+		DWORD x,y;
+
+		x=si->dwXSize;if (x==0x80000000) x=0x8000;
+		y=si->dwYSize;if (y==0x80000000) y=0x8000;
+		return (y<<16)+x;
+	}
+	case 40:{/* return startup x and y */
+		LPSTARTUPINFO32A si = process->env_db->startup_info;
+		DWORD x,y;
+
+		x=si->dwX;if (x==0x80000000) x=0x8000;
+		y=si->dwY;if (y==0x80000000) y=0x8000;
+		return (y<<16)+x;
+	}
+	case 44:/* return startup flags */
+		return process->env_db->startup_info->dwFlags;
+	case 48:/* return uncrypted pointer to parent process (if any) */
+		return (DWORD)process->parent;
+	case 52:/* return process flags */
+		return process->flags;
+	case 56:/* unexplored */
+		return 0;
+	default:
+		fprintf(stderr,"_KERNEL32_18:unknown offset (%ld)\n",action);
+		return 0;
+	}
+	/* shouldn't come here */
+}
+
+VOID /* FIXME */
+_KERNEL32_52(DWORD arg1,CONTEXT *regs) {
+	SEGPTR *str = SEGPTR_STRDUP("ThkBuf");
+
+	fprintf(stderr,"_KERNE32_52(arg1=%08lx,%08lx)\n",arg1,EDI_reg(regs));
+
+	EAX_reg(regs) = GetProcAddress16(EDI_reg(regs),SEGPTR_GET(str));
+	fprintf(stderr,"	GetProcAddress16(\"ThkBuf\") returns %08lx\n",
+			EAX_reg(regs)
+	);
+	SEGPTR_FREE(str);
+}
+
+/***********************************************************************
+ *           GetPWinLock    (KERNEL32) FIXME
+ */
+VOID
+GetPWinLock(CRITICAL_SECTION **lock) {
+	static CRITICAL_SECTION plock;
+	fprintf(stderr,"GetPWinlock(%p)\n",lock);
+	*lock = &plock;
+}
+
+/***********************************************************************
+ *           GetProcessVersion    (KERNEL32)
+ */
+DWORD
+GetProcessVersion(DWORD processid) {
+	PDB32	*process;
+	TDB	*pTask;
+
+	if (!processid) {
+		process=pCurrentProcess;
+		/* check if valid process */
+	} else
+		process=(PDB32*)pCurrentProcess; /* decrypt too, if needed */
+	pTask = (TDB*)GlobalLock16(process->task);
+	if (!pTask)
+		return 0;
+	return (pTask->version&0xff) | (((pTask->version >>8) & 0xff)<<16);
+}
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 33907ab..ad4ff27 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -63,7 +63,7 @@
     /* Set a guard page at the bottom of the stack */
     VirtualProtect( thdb->stack_base, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD,
                     &old_prot );
-    thdb->teb.stack_top   = (char *)thdb->stack_base + stack_size - 1;
+    thdb->teb.stack_top   = (char *)thdb->stack_base + stack_size;
     thdb->teb.stack_low   = thdb->stack_base;
     thdb->exit_stack      = thdb->teb.stack_top;
 
diff --git a/tools/build.c b/tools/build.c
index 6d9008c..53e6780 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -704,7 +704,7 @@
     buffer = xmalloc( 0x10000 );
 
     pModule = (NE_MODULE *)buffer;
-    pModule->magic = NE_SIGNATURE;
+    pModule->magic = IMAGE_OS2_SIGNATURE;
     pModule->count = 1;
     pModule->next = 0;
     pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN | NE_FFLAGS_LIBMODULE;
@@ -887,7 +887,7 @@
     buffer = xmalloc( 0x10000 );
 
     pModule = (NE_MODULE *)buffer;
-    pModule->magic = NE_SIGNATURE;
+    pModule->magic = IMAGE_OS2_SIGNATURE;
     pModule->count = 1;
     pModule->next = 0;
     pModule->dgroup_entry = 0;
diff --git a/tools/fnt2bdf.c b/tools/fnt2bdf.c
index 8e889e6..6795116 100644
--- a/tools/fnt2bdf.c
+++ b/tools/fnt2bdf.c
@@ -34,6 +34,7 @@
 char*	g_lpstrFileName = NULL;
 char*	g_lpstrCharSet = NULL;
 char*   g_lpstrInputFile = NULL;
+int     g_outputPoints = 0;
 
 static char*	errorDLLRead = "Unable to read Windows DLL.\n";
 static char*    errorFNTRead = "Unable to read .FNT file.\n";
@@ -47,9 +48,10 @@
 
 void usage()
 {
-    printf("Usage: font2bdf [-c charset] [-o basename] [input file]\n");
-    printf("  -c charset\tuse this charset name for OEM_CHARSET fonts\n");
+    printf("Usage: fnt2bdf [-t] [-c charset] [-o basename] [input file]\n");
+    printf("  -c charset\tcharset name for OEM_CHARSET fonts\n");
     printf("  -f basename\tbasic output filename\n");
+    printf("  -t \t\toutput files by point size instead of pixel height\n");
     printf("  input file\tMSWindows .fon, .fnt, .dll, or .exe file.\n");
     printf("\nExample:\n  fnt2bdf -c winsys vgasys.fnt\n\n");
     exit(-1);
@@ -110,7 +112,8 @@
 
   lpChar = name + strlen( name );
   sprintf(lpChar, "%d-%d.bdf", return_data_value(dfShort, cpe_font_struct->hdr.dfWeight),
-                               return_data_value(dfShort, cpe_font_struct->hdr.dfPoints) );
+          (g_outputPoints) ? return_data_value(dfShort, cpe_font_struct->hdr.dfPoints)
+			   : return_data_value(dfShort, cpe_font_struct->hdr.dfPixHeight) );
   return 0;
 }
 
@@ -136,7 +139,7 @@
 
     int l_fchar = return_data_value(dfChar, cpe_font_struct.hdr.dfFirstChar),
         l_lchar = return_data_value(dfChar, cpe_font_struct.hdr.dfLastChar); 
-    int l_len   = l_lchar-l_fchar, l_ptr = MAP_BEG;
+    int l_len   = l_lchar - l_fchar + 1, l_ptr = MAP_BEG;
 
     /* malloc size = (# chars) * sizeof(WinCharS) */
 
@@ -174,7 +177,7 @@
   int     l_fchar = return_data_value(dfChar, cpe_font_struct->hdr.dfFirstChar), 
           l_lchar = return_data_value(dfChar, cpe_font_struct->hdr.dfLastChar); 
 
-  int     l_len = l_lchar-l_fchar,
+  int     l_len = l_lchar-l_fchar + 1,
           l_hgt = return_data_value(dfChar, cpe_font_struct->hdr.dfPixHeight); 
   int	  l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
   char    l_filename[256];
@@ -279,7 +282,7 @@
 {
 int     l_fchar = return_data_value(dfChar, cpe_font_struct->hdr.dfFirstChar), 
         l_lchar = return_data_value(dfChar, cpe_font_struct->hdr.dfLastChar);
-int     l_len = l_lchar - l_fchar;
+int     l_len = l_lchar - l_fchar + 1;
 int     l_nameoffset = return_data_value(dfLong, cpe_font_struct->hdr.dfFace);
 int 	l_cellheight = return_data_value(dfShort, cpe_font_struct->hdr.dfPixHeight);
 int     l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
@@ -333,7 +336,7 @@
       /* spacing */
 
       if( return_data_value(dfShort, cpe_font_struct->hdr.dfPixWidth) ) fputs("c-", fs);
-      else fputs("m-", fs);
+      else fputs("p-", fs);
 	
       /* average width */
 
@@ -343,15 +346,27 @@
 
       switch( cpe_font_struct->hdr.dfCharSet[0] )
       {
-	case ANSI_CHARSET: fputs("ansi-0\n", fs); break;
+	/* Microsoft just had to invent its own charsets! */
+
+	case ANSI_CHARSET: 	fputs("ansi-0\n", fs); break;
+	case GREEK_CHARSET: 	fputs("cp125-3\n", fs); break;
+	case TURKISH_CHARSET: 	fputs("iso8859-9", fs); break;
+	case HEBREW_CHARSET: 	fputs("cp125-5", fs); break;
+	case ARABIC_CHARSET: 	fputs("cp125-6", fs); break;
+	case BALTIC_CHARSET: 	fputs("cp125-7", fs); break;
+	case RUSSIAN_CHARSET: 	fputs("cp125-1", fs); break;
+	case EE_CHARSET: 	fputs("iso8859-2", fs); break; 
+	case SYMBOL_CHARSET: 	fputs("misc-fontspecific\n", fs); break;
+	case SHIFTJIS_CHARSET: 	fputs("jisx0208.1983-0\n", fs); break;
+	case DEFAULT_CHARSET:	fputs("iso8859-1\n", fs); break;
+
 	default:
-	case DEFAULT_CHARSET: fputs("iso8859-1\n", fs); break;
-	case SYMBOL_CHARSET: fputs("misc-fontspecific\n", fs); break;
-	case SHIFTJIS_CHARSET: fputs("jisx0208.1983-0\n", fs); break;
 	case OEM_CHARSET: 
 		if( !g_lpstrCharSet ) 
-		{ fputs("Undefined OEM charset, use -c option.\n", stderr); 
-		  return ERROR_DATA; }
+		{ 
+		    fputs("Undefined charset, use -c option.\n", stderr); 
+		    return ERROR_DATA; 
+		}
 	        fprintf(fs, "%s\n", g_lpstrCharSet);
       }
     }
@@ -397,14 +412,24 @@
     case 4:
     case 5:
     case 6:
+    case 7:
+    case 8:
 	 for( i = 1; i < argc - 1; i++ )
 	 {
 	   if( argv[i][0] != '-' ||
 	       strlen(argv[i]) != 2 ) break;
 
-	   if( argv[i][1] == 'c' ) { g_lpstrCharSet = argv[i+1]; }
+	   if( argv[i][1] == 'c' ) 
+	       g_lpstrCharSet = argv[i+1];
 	   else 
-	   if( argv[i][1] == 'f' ) { g_lpstrFileName = argv[i+1]; }
+	   if( argv[i][1] == 'f' ) 
+	       g_lpstrFileName = argv[i+1];
+	   else
+	   if( argv[i][1] == 't' )
+	   {
+	      g_outputPoints = 1;
+	      continue;
+	   }
 	   else
 	   usage();
 
@@ -424,8 +449,8 @@
 
 int get_resource_table(int fd, unsigned char** lpdata, int fsize)
 {
-  struct mz_header_s mz_header;
-  struct ne_header_s ne_header;
+  IMAGE_DOS_HEADER mz_header;
+  IMAGE_OS2_HEADER ne_header;
   short		     s, offset, size, retval;
 
  
@@ -434,11 +459,11 @@
   if( read(fd, &mz_header, sizeof(mz_header)) != sizeof(mz_header) ) 
       return FILE_ERROR;
 
-  s = return_data_value(dfShort, &mz_header.mz_magic);
+  s = return_data_value(dfShort, &mz_header.e_magic);
 
-  if( s == MZ_SIGNATURE) 		/* looks like .dll file so far... */
+  if( s == IMAGE_DOS_SIGNATURE)		/* looks like .dll file so far... */
   {
-    s = return_data_value(dfShort, &mz_header.ne_offset);
+    s = return_data_value(dfShort, &mz_header.e_lfanew);
     lseek( fd, s, SEEK_SET );
 
     if( read(fd, &ne_header, sizeof(ne_header)) != sizeof(ne_header) )
@@ -446,12 +471,12 @@
 
     s = return_data_value(dfShort, &ne_header.ne_magic);
 
-    if( s == PE_SIGNATURE)
+    if( s == IMAGE_NT_SIGNATURE)
     {
        fprintf( stderr, "Do not know how to handle 32-bit Windows DLLs.\n");
        return FILE_ERROR; 
     }
-    else if ( s != NE_SIGNATURE) return FILE_ERROR;
+    else if ( s != IMAGE_OS2_SIGNATURE) return FILE_ERROR;
 
     s = return_data_value(dfShort, &ne_header.resource_tab_offset);
     size = return_data_value(dfShort, &ne_header.rname_tab_offset);
@@ -459,14 +484,14 @@
     if( size > fsize ) return FILE_ERROR;
 
     size -= s;
-    offset = s + return_data_value(dfShort, &mz_header.ne_offset);
+    offset = s + return_data_value(dfShort, &mz_header.e_lfanew);
 
     if( size <= sizeof(NE_TYPEINFO) ) return FILE_ERROR;
     retval = FILE_DLL;
   }
   else if( s == 0x300 || s == 0x200 )		/* maybe .fnt ? */
   {
-    size = return_data_value(dfLong, &mz_header.dont_care);
+    size = return_data_value(dfLong, (char*)&mz_header+2);
 
     if( size != fsize ) return FILE_ERROR;
     offset  = 0;
diff --git a/win32/advapi.c b/win32/advapi.c
index 2fe54f2..9bb1ca7 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -9,6 +9,7 @@
 #include "windows.h"
 #include "winerror.h"
 #include "shell.h"
+#include "heap.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -55,6 +56,19 @@
 }
 
 /***********************************************************************
+ *           OpenThreadToken		[ADVAPI32.114]
+ */
+BOOL32
+OpenThreadToken(
+	HANDLE32 thread,DWORD desiredaccess,BOOL32 openasself,HANDLE32 *thandle
+) {
+	fprintf(stdnimp,"OpenThreadToken(%08x,%08lx,%d,%p),stub!\n",
+		thread,desiredaccess,openasself,thandle
+	);
+	return TRUE;
+}
+
+/***********************************************************************
  *           LookupPrivilegeValueA   [ADVAPI32.90]
  */
 BOOL32
@@ -72,3 +86,43 @@
 {
 	return TRUE;
 }
+
+/***********************************************************************
+ *           GetTokenInformation	[ADVAPI32.66]
+ */
+BOOL32
+GetTokenInformation(
+	HANDLE32 token,/*TOKEN_INFORMATION_CLASS*/ DWORD tokeninfoclass,LPVOID tokeninfo,
+	DWORD tokeninfolength,LPDWORD retlen
+) {
+	fprintf(stderr,"GetTokenInformation(%08lx,%d,%p,%ld,%p)\n",
+		token,tokeninfoclass,tokeninfo,tokeninfolength,retlen
+	);
+	return TRUE;
+}
+
+/*SC_HANDLE*/
+DWORD
+OpenSCManagerA(LPCSTR machine,LPCSTR dbname,DWORD desiredaccess)
+{
+	fprintf(stderr,"OpenSCManagerA(%s,%s,%08lx)\n",machine,dbname,desiredaccess);
+	return 0;
+}
+
+DWORD
+OpenSCManagerW(LPCWSTR machine,LPCWSTR dbname,DWORD desiredaccess)
+{
+	LPSTR	machineA = HEAP_strdupWtoA(GetProcessHeap(),0,machine);
+	LPSTR	dbnameA = HEAP_strdupWtoA(GetProcessHeap(),0,dbname);
+	fprintf(stderr,"OpenSCManagerW(%s,%s,%08lx)\n",machineA,dbnameA,desiredaccess);
+	HeapFree(GetProcessHeap(),0,machineA);
+	HeapFree(GetProcessHeap(),0,dbnameA);
+	return 0;
+}
+
+BOOL32
+AllocateLocallyUniqueId(LPLUID lpluid) {
+	lpluid->LowPart = time(NULL);
+	lpluid->HighPart = 0;
+	return TRUE;
+}
diff --git a/win32/console.c b/win32/console.c
index d0b25ae..e8e506d 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -215,3 +215,25 @@
     fprintf(stderr,"FlushConsoleInputBuffer(%d)\n",hConsoleInput);
     return TRUE;
 }
+
+BOOL32
+SetConsoleCursorPosition(HANDLE32 hcons,COORD c) {
+    /* x are columns, y rows */
+    if (!c.y) {
+    	fprintf(stderr,"\r");
+	if (c.x)
+		fprintf(stderr,"[%dC",c.x);
+	return TRUE;
+    }
+    /* handle rest of the cases */
+    return FALSE;
+}
+
+/***********************************************************************
+ *            GetNumberOfConsoleInputEvents   (KERNEL32.246)
+ */
+BOOL32
+GetNumberOfConsoleInputEvents(HANDLE32 hcon,LPDWORD nrofevents) {
+	*nrofevents = 1;
+	return TRUE;
+}
diff --git a/windows/clipboard.c b/windows/clipboard.c
index d4e9276..ce261c0 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -112,30 +112,30 @@
 {
   LPCLIPFORMAT lpFormat = ClipFormats;
 
-  dprintf_clipboard(stddeb,"DisOwn: clipboard owner = %04x, sw = %08x\n", 
+  dprintf_clipboard(stddeb,"DisOwn: clipboard owner = %04x, selection = %08x\n", 
 				hWndClipOwner, (unsigned)selectionWindow);
 
   if( pWnd->hwndSelf == hWndClipOwner)
   {
-    SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
+      SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
 
-    /* check if all formats were rendered */
+      /* check if all formats were rendered */
 
-    while(lpFormat)
-    { 
-       if( lpFormat->wDataPresent && !lpFormat->hData )
+      while(lpFormat)
+      { 
+         if( lpFormat->wDataPresent && !lpFormat->hData )
 	 {
 	   dprintf_clipboard(stddeb,"\tdata missing for clipboard format %i\n", lpFormat->wFormatID); 
 	   lpFormat->wDataPresent = 0;
 	 }
-       lpFormat = lpFormat->NextFormat;
-    }
-    hWndClipOwner = 0;
+         lpFormat = lpFormat->NextFormat;
+      }
+      hWndClipOwner = 0;
   }
 
   /* now try to salvage current selection from being destroyed by X */
 
-  CLIPBOARD_CheckSelection(pWnd);
+  if( pWnd->window ) CLIPBOARD_CheckSelection(pWnd);
 }
 
 /**************************************************************************
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 1694a79..850359a 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -171,7 +171,9 @@
                                       WM_MOUSEACTIVATE, wParam, lParam );
 	    if (ret) return ret;
 	}
-	return MA_ACTIVATE;
+
+	/* Caption clicks are handled by the NC_HandleNCLButtonDown() */ 
+	return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
 
     case WM_ACTIVATE:
 	if (LOWORD(wParam) != WA_INACTIVE) SetFocus32( wndPtr->hwndSelf );
@@ -182,19 +184,6 @@
 	{
 	    if (!wndPtr->class->hbrBackground) return 0;
 
-	    /* FIXME: should fill icon text with hbrushActiveCaption 
-		      instead of this */
-
-	    if (wndPtr->dwStyle & WS_MINIMIZE )
-	    {
-		 if( wndPtr->flags & WIN_NCACTIVATED )
-		 {
-		   FillWindow( GetParent16(wndPtr->hwndSelf), wndPtr->hwndSelf,
-                               (HDC16)wParam, sysColorObjects.hbrushActiveCaption );
-		   return 1;
-		 }
-	    }
-
 	    if (wndPtr->class->hbrBackground <= (HBRUSH16)(COLOR_MAX+1))
             {
                 HBRUSH32 hbrush = CreateSolidBrush32( 
@@ -355,6 +344,9 @@
         }
         break;
 
+    case WM_ISACTIVEICON:
+	return ((wndPtr->flags & WIN_NCACTIVATED) != 0);
+
     case WM_QUERYOPEN:
     case WM_QUERYENDSESSION:
 	return 1;
diff --git a/windows/dialog.c b/windows/dialog.c
index f59cbd9..4024310 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -501,7 +501,7 @@
           /* (see CreateFont() documentation in the Windows SDK).   */
 	hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
 			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
-			    DEFAULT_QUALITY, FF_DONTCARE,
+			    PROOF_QUALITY, FF_DONTCARE,
                             template.faceName );  /* FIXME: win32 */
 	if (hFont)
 	{
@@ -908,7 +908,7 @@
     dlgCode = SendMessage32A( hwnd, WM_GETDLGCODE, 0, 0 );
     if (dlgCode & DLGC_WANTMESSAGE)
     {
-        *dispatch = TRUE;
+        *translate = *dispatch = TRUE;
         return TRUE;
     }
 
diff --git a/windows/event.c b/windows/event.c
index fa01908..c03c98c 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -813,16 +813,16 @@
 	}
     }
 
-    if(rprop==None) 
+    if(rprop == None) 
        dprintf_event(stddeb,"Request for %s ignored\n", XGetAtomName(display,event->target));
 
-    result.type=SelectionNotify;
-    result.display=display;
-    result.requestor=request;
-    result.selection=event->selection;
-    result.property=rprop;
-    result.target=event->target;
-    result.time=event->time;
+    result.type = SelectionNotify;
+    result.display = display;
+    result.requestor = request;
+    result.selection = event->selection;
+    result.property = rprop;
+    result.target = event->target;
+    result.time = event->time;
     XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
 }
 
diff --git a/windows/mdi.c b/windows/mdi.c
index e301cbf..581d091 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -179,10 +179,8 @@
             break;
         }
 
-	/* we are not interested in owned popups */
-        if ( !pWnd->owner &&
-	     (pWnd->dwStyle & WS_VISIBLE) &&
-            !(pWnd->dwStyle & WS_DISABLED))  /* found one */
+        if ( !pWnd->owner && (pWnd->dwStyle & 
+			     (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE )
         {
             pWndLast = pWnd;
             if (!wTo) break;
@@ -606,60 +604,6 @@
     return 1;
 }
 
-/**********************************************************************
- *			MDI_BuildWCL
- *
- *  iTotal returns number of children available for tiling or cascading
- */
-static MDIWCL* MDI_BuildWCL(WND* clientWnd, UINT16* iTotal)
-{
-    MDIWCL *listTop,*listNext;
-    WND    *childWnd;
-
-    if (!(listTop = (MDIWCL*)malloc( sizeof(MDIWCL) ))) return NULL;
-
-    listTop->hChild = clientWnd->child ? clientWnd->child->hwndSelf : 0;
-    listTop->prev   = NULL;
-    *iTotal 	    = 1;
-
-    /* build linked list from top child to bottom */
-
-    childWnd  =  WIN_FindWndPtr( listTop->hChild );
-    while( childWnd && childWnd->next )
-    {
-	listNext = (MDIWCL*)xmalloc(sizeof(MDIWCL));
-	
-	/* FIXME: pay attention to MDITILE_SKIPDISABLED 
-	 *        when WIN_ISWIN32 is set.
-	 */
-	if( (childWnd->dwStyle & WS_DISABLED) ||
-	    (childWnd->dwStyle & WS_MINIMIZE) ||
-	    !(childWnd->dwStyle & WS_VISIBLE)   )
-	{
-	    listTop->hChild = 0;
-	    (*iTotal)--;
-	}
-
-	listNext->hChild = childWnd->next->hwndSelf;
-	listNext->prev   = listTop;
-	listTop          = listNext;
-	(*iTotal)++;
-
-	childWnd  =  childWnd->next;
-    }
-
-    if( (childWnd->dwStyle & WS_DISABLED) ||
-	(childWnd->dwStyle & WS_MINIMIZE) ||
-	!(childWnd->dwStyle & WS_VISIBLE)   )
-    {
-	listTop->hChild = 0;
-	(*iTotal)--;
-    }
- 
-    return listTop;
-}
-
-
 /* -------------------- MDI client window functions ------------------- */
 
 /**********************************************************************
@@ -695,142 +639,115 @@
  */
 static LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
 {
-	MDIWCL	*listTop,*listPrev;
-	INT16	delta = 0, n = 0;
-	UINT16	iToPosition = 0;
-	POINT16	pos[2];
+    WND**	ppWnd;
+    UINT32	total;
   
     if (ci->hwndChildMaximized)
         ShowWindow16( ci->hwndChildMaximized, SW_NORMAL);
 
     if (ci->nActiveChildren == 0) return 0;
 
-    if (!(listTop = MDI_BuildWCL(clientWnd,&iToPosition))) return 0;
-
-    if( iToPosition < ci->nActiveChildren ) 
-        delta = 2 * SYSMETRICS_CYICONSPACING + SYSMETRICS_CYICON;
-
-    /* walk list and move windows */
-    while ( listTop )
+    if ((ppWnd = WIN_BuildWinArray(clientWnd, BWA_SKIPHIDDEN | BWA_SKIPOWNED | 
+					      BWA_SKIPICONIC, &total)))
     {
-	dprintf_mdi(stddeb, "MDICascade: move %04x to (%d,%d) size [%d,%d]\n", 
-                    listTop->hChild, pos[0].x, pos[0].y, pos[1].x, pos[1].y);
+	WND**	heapPtr = ppWnd;
+	if( total )
+	{
+	    INT16	delta = 0, n = 0;
+	    POINT16	pos[2];
+	    if( total < ci->nActiveChildren )
+		delta = SYSMETRICS_CYICONSPACING + SYSMETRICS_CYICON;
 
-	if( listTop->hChild )
-        {
-            MDI_CalcDefaultChildPos(clientWnd, n++, pos, delta);
-            SetWindowPos32(listTop->hChild, 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
-                           SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
-        }
+	    /* walk the list and move windows */
+	    while ( *ppWnd )
+	    {
+		dprintf_mdi(stddeb, "MDICascade: move %04x to (%d,%d) size [%d,%d]\n", 
+                            (*ppWnd)->hwndSelf, pos[0].x, pos[0].y, pos[1].x, pos[1].y);
 
-	listPrev = listTop->prev;
-	free(listTop);
-	listTop = listPrev;
+		MDI_CalcDefaultChildPos(clientWnd, n++, pos, delta);
+		SetWindowPos32((*ppWnd)->hwndSelf, 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
+					      SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+		ppWnd++;
+	    }
+	}
+	HeapFree( SystemHeap, 0, heapPtr );
     }
 
-    if( iToPosition < ci->nActiveChildren )
-        ArrangeIconicWindows32( clientWnd->hwndSelf );
-
+    if( total < ci->nActiveChildren ) ArrangeIconicWindows32( clientWnd->hwndSelf );
     return 0;
 }
 
 /**********************************************************************
  *					MDITile
- *
  */
 static LONG MDITile(WND* wndClient, MDICLIENTINFO *ci,WORD wParam)
 {
-    MDIWCL       *listTop,*listPrev;
-    RECT16        rect;
-    int           xsize, ysize;
-    int		  x, y;
-    int		  rows, columns;
-    int           r, c;
-    int           i;
-    UINT16	  iToPosition = 0;
+    WND**	ppWnd;
+    UINT32	total = 0;
 
     if (ci->hwndChildMaximized)
 	ShowWindow16(ci->hwndChildMaximized, SW_NORMAL);
 
     if (ci->nActiveChildren == 0) return 0;
 
-    listTop = MDI_BuildWCL(wndClient, &iToPosition);
+    ppWnd = WIN_BuildWinArray(wndClient, BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
+	    ((wParam & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
 
-    dprintf_mdi(stddeb,"MDITile: %i windows to tile\n",iToPosition);
+    dprintf_mdi(stddeb,"MDITile: %u windows to tile\n", total);
 
-    if( !listTop ) return 0;
-
-    /* tile children */
-    if ( iToPosition )
+    if( ppWnd )
     {
-        rect = wndClient->rectClient;
-    	rows    = (int) sqrt((double) iToPosition);
-    	columns = iToPosition / rows;
+	WND**	heapPtr = ppWnd;
 
-        if (wParam == MDITILE_HORIZONTAL)  /* version >= 3.1 */
-        {
-            i=rows;
-            rows=columns;  /* exchange r and c */
-            columns=i;
-        }
+	if( total )
+	{
+	    RECT16	rect;
+	    int		x, y, xsize, ysize;
+	    int		rows, columns, r, c, i;
 
-    	/* hack */
-    	if( iToPosition != ci->nActiveChildren)
-        {
-            y = rect.bottom - 2 * SYSMETRICS_CYICONSPACING - SYSMETRICS_CYICON;
-            rect.bottom = ( y - SYSMETRICS_CYICON < rect.top )? rect.bottom: y;
-        }
+	    rect    = wndClient->rectClient;
+	    rows    = (int) sqrt((double)total);
+	    columns = total / rows;
 
-    	ysize   = rect.bottom / rows;
-    	xsize   = rect.right  / columns;
+	    if( wParam & MDITILE_HORIZONTAL )  /* version >= 3.1 */
+	    {
+	        i = rows;
+	        rows = columns;  /* exchange r and c */
+	        columns = i;
+	    }
+
+	    if( total != ci->nActiveChildren)
+	    {
+	        y = rect.bottom - 2 * SYSMETRICS_CYICONSPACING - SYSMETRICS_CYICON;
+	        rect.bottom = ( y - SYSMETRICS_CYICON < rect.top )? rect.bottom: y;
+	    }
+
+	    ysize   = rect.bottom / rows;
+	    xsize   = rect.right  / columns;
     
-    	x       = 0;
-    	i       = 0;
+	    for (x = i = 0, c = 1; c <= columns && *ppWnd; c++)
+	    {
+	        if (c == columns)
+		{
+		    rows  = total - i;
+		    ysize = rect.bottom / rows;
+		}
 
-    	for (c = 1; c <= columns; c++)
-    	{
-            if (c == columns)
-            {
-                rows  = iToPosition - i;
-                ysize = rect.bottom / rows;
-            }
-
-            y = 0;
-            for (r = 1; r <= rows; r++, i++)
-            {
-                /* shouldn't happen but... */
-                if( !listTop )
-                    break;
-                
-                /* skip iconized childs from tiling */
-                while (!listTop->hChild)
-                {
-    	            listPrev = listTop->prev;
-    	            free(listTop);
-    	            listTop = listPrev;
-    	        }                
-                SetWindowPos32(listTop->hChild, 0, x, y, xsize, ysize, 
-                               SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
-                y += ysize;
-    	        listPrev = listTop->prev;
-    	        free(listTop);
-    	        listTop = listPrev;
-            }
-            x += xsize;
-    	}
+		y = 0;
+		for (r = 1; r <= rows && *ppWnd; r++, i++)
+		{
+		    SetWindowPos32((*ppWnd)->hwndSelf, 0, x, y, xsize, ysize, 
+				   SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+                    y += ysize;
+		    ppWnd++;
+		}
+		x += xsize;
+	    }
+	}
+	HeapFree( SystemHeap, 0, heapPtr );
     }
   
-    /* free the rest if any */
-    while( listTop )
-    {
-        listPrev = listTop->prev;
-        free(listTop);
-        listTop = listPrev;
-    }
-    
-    if (iToPosition < ci->nActiveChildren )
-        ArrangeIconicWindows32( wndClient->hwndSelf );
-
+    if( total < ci->nActiveChildren ) ArrangeIconicWindows32( wndClient->hwndSelf );
     return 0;
 }
 
@@ -1607,9 +1524,6 @@
 BOOL16 TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
 {
     WND* clientWnd = WIN_FindWndPtr( hwndClient);
-    WND* wnd;
-    MDICLIENTINFO     *ci     = NULL;
-    WPARAM16	       wParam = 0;
 
     if( clientWnd && (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN))
     {
diff --git a/windows/message.c b/windows/message.c
index 80c3e5c..5b70ee2 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -1013,7 +1013,7 @@
     if (hwnd == HWND_BROADCAST)
     {
         dprintf_msg(stddeb,"SendMessage // HWND_BROADCAST !\n");
-        list = WIN_BuildWinArray( WIN_GetDesktop() );
+        list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL );
         for (ppWnd = list; *ppWnd; ppWnd++)
         {
             wndPtr = *ppWnd;
@@ -1099,7 +1099,7 @@
 
     if (hwnd == HWND_BROADCAST)
     {
-        list = WIN_BuildWinArray( WIN_GetDesktop() );
+        list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL );
         for (ppWnd = list; *ppWnd; ppWnd++)
         {
             wndPtr = *ppWnd;
@@ -1148,7 +1148,7 @@
 
     if (hwnd == HWND_BROADCAST)
     {
-        list = WIN_BuildWinArray( WIN_GetDesktop() );
+        list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL );
         for (ppWnd = list; *ppWnd; ppWnd++)
         {
             wndPtr = *ppWnd;
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 08ff98b..5237a52 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -150,86 +150,6 @@
 }
 
 
-/*******************************************************************
- *         NC_GetMinMaxInfo
- *
- * Get the minimized and maximized information for a window.
- */
-void NC_GetMinMaxInfo( WND *wndPtr, POINT16 *maxSize, POINT16 *maxPos,
-                       POINT16 *minTrack, POINT16 *maxTrack )
-{
-    MINMAXINFO16 *MinMax;
-    short xinc, yinc;
-
-    if (!(MinMax = SEGPTR_NEW(MINMAXINFO16))) return;
-
-      /* Compute default values */
-
-    MinMax->ptMaxSize.x = SYSMETRICS_CXSCREEN;
-    MinMax->ptMaxSize.y = SYSMETRICS_CYSCREEN;
-    MinMax->ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
-    MinMax->ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
-    MinMax->ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
-    MinMax->ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
-
-    if (wndPtr->flags & WIN_MANAGED) xinc = yinc = 0;
-    else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
-    {
-        xinc = SYSMETRICS_CXDLGFRAME;
-        yinc = SYSMETRICS_CYDLGFRAME;
-    }
-    else
-    {
-        xinc = yinc = 0;
-	if (HAS_THICKFRAME(wndPtr->dwStyle))
-        {
-            xinc += SYSMETRICS_CXFRAME;
-            yinc += SYSMETRICS_CYFRAME;
-        }
-	if (wndPtr->dwStyle & WS_BORDER)
-        {
-            xinc += SYSMETRICS_CXBORDER;
-            yinc += SYSMETRICS_CYBORDER;
-        }
-    }
-    MinMax->ptMaxSize.x += 2 * xinc;
-    MinMax->ptMaxSize.y += 2 * yinc;
-
-    /* Note: The '+' in the following test should really be a ||, but
-     * that would cause gcc-2.7.0 to generate incorrect code.
-     */
-    if ((wndPtr->ptMaxPos.x != -1) + (wndPtr->ptMaxPos.y != -1))
-        MinMax->ptMaxPosition = wndPtr->ptMaxPos;
-    else
-    {
-        MinMax->ptMaxPosition.x = -xinc;
-        MinMax->ptMaxPosition.y = -yinc;
-    }
-
-    SendMessage16( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0,
-                   (LPARAM)SEGPTR_GET(MinMax) );
-
-      /* Some sanity checks */
-
-    dprintf_nonclient(stddeb, 
-		      "NC_GetMinMaxInfo: %d %d / %d %d / %d %d / %d %d\n",
-		      MinMax->ptMaxSize.x, MinMax->ptMaxSize.y,
-                      MinMax->ptMaxPosition.x, MinMax->ptMaxPosition.y,
-		      MinMax->ptMaxTrackSize.x, MinMax->ptMaxTrackSize.y,
-		      MinMax->ptMinTrackSize.x, MinMax->ptMinTrackSize.y);
-    MinMax->ptMaxTrackSize.x = MAX( MinMax->ptMaxTrackSize.x,
-				   MinMax->ptMinTrackSize.x );
-    MinMax->ptMaxTrackSize.y = MAX( MinMax->ptMaxTrackSize.y,
-				   MinMax->ptMinTrackSize.y );
-    
-    if (maxSize) *maxSize = MinMax->ptMaxSize;
-    if (maxPos) *maxPos = MinMax->ptMaxPosition;
-    if (minTrack) *minTrack = MinMax->ptMinTrackSize;
-    if (maxTrack) *maxTrack = MinMax->ptMaxTrackSize;
-    SEGPTR_FREE(MinMax);
-}
-
-
 /***********************************************************************
  *           NC_HandleNCCalcSize
  *
@@ -664,15 +584,14 @@
  *
  * Paint the non-client area. clip is currently unused.
  */
-void NC_DoNCPaint( HWND32 hwnd, HRGN32 clip, BOOL32 suppress_menupaint )
+void NC_DoNCPaint( WND* wndPtr, HRGN32 clip, BOOL32 suppress_menupaint )
 {
     HDC32 hdc;
     RECT32 rect;
     BOOL32 active;
+    HWND32 hwnd = wndPtr->hwndSelf;
 
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    if (!wndPtr || wndPtr->dwStyle & WS_MINIMIZE ||
+    if ( wndPtr->dwStyle & WS_MINIMIZE ||
 	!WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
 
     active  = wndPtr->flags & WIN_NCACTIVATED;
@@ -757,7 +676,15 @@
  */
 LONG NC_HandleNCPaint( HWND32 hwnd , HRGN32 clip)
 {
-    NC_DoNCPaint( hwnd, clip, FALSE );
+    WND* wndPtr = WIN_FindWndPtr( hwnd );
+
+    if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
+    {
+	if( wndPtr->dwStyle & WS_MINIMIZE )
+	    WINPOS_RedrawIconTitle( hwnd );
+	else 
+	    NC_DoNCPaint( wndPtr, clip, FALSE );
+    }
     return 0;
 }
 
@@ -776,13 +703,13 @@
 
     if( wStateChange )
     {
-      if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
-      else wndPtr->flags &= ~WIN_NCACTIVATED;
+	if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
+	else wndPtr->flags &= ~WIN_NCACTIVATED;
 
-      if( wndPtr->dwStyle & WS_MINIMIZE )
-	PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW, 0 );
-      else
-	NC_DoNCPaint( wndPtr->hwndSelf, (HRGN32)1, FALSE );
+	if( wndPtr->dwStyle & WS_MINIMIZE ) 
+	    WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
+	else
+	    NC_DoNCPaint( wndPtr, (HRGN32)1, FALSE );
     }
     return TRUE;
 }
@@ -868,6 +795,7 @@
  *           NC_TrackSysMenu
  *
  * Track a mouse button press on the system menu.
+ * TODO: Unify with NC_TrackMinMaxBox() (and without InternalGetMessage() calls).
  */
 static void NC_TrackSysMenu( HWND32 hwnd, POINT16 pt )
 {
@@ -1053,7 +981,7 @@
 
       /* Get min/max info */
 
-    NC_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
+    WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
     sizingRect = wndPtr->rectWindow;
     if (wndPtr->dwStyle & WS_CHILD)
 	GetClientRect16( wndPtr->parent->hwndSelf, &mouseRect );
@@ -1096,15 +1024,17 @@
 
     if( iconic )
     {
-      HICON16 hIcon = (wndPtr->class->hIcon)
+	HICON16 hIcon = (wndPtr->class->hIcon)
                       ? wndPtr->class->hIcon
                       : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
-      if( hIcon )
-      {
-        hDragCursor =  CURSORICON_IconToCursor( hIcon, TRUE );
-        hOldCursor = SetCursor32(hDragCursor);
-        ShowCursor32( TRUE );
-      } else iconic = FALSE;
+	if( hIcon )
+	{
+	    hDragCursor =  CURSORICON_IconToCursor( hIcon, TRUE );
+	    hOldCursor = SetCursor32(hDragCursor);
+	    ShowCursor32( TRUE );
+	} 
+	else iconic = FALSE;
+	WINPOS_ShowIconTitle( wndPtr, FALSE );
     }
 
     if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
@@ -1158,8 +1088,8 @@
 		else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
 		if( !iconic )
 		{
-		  NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
-		  NC_DrawMovingFrame( hdc, &newRect, thickframe );
+		    NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
+		    NC_DrawMovingFrame( hdc, &newRect, thickframe );
 		}
 		capturePoint = pt;
 		sizingRect = newRect;
@@ -1170,12 +1100,12 @@
     ReleaseCapture();
     if( iconic )
     {
-      ShowCursor32( FALSE );
-      SetCursor32(hOldCursor);
-      if( hDragCursor ) DestroyCursor32( hDragCursor );
+	ShowCursor32( FALSE );
+	SetCursor32(hOldCursor);
+	if( hDragCursor ) DestroyCursor32( hDragCursor );
     }
     else
-      NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
+	NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
 
     if (wndPtr->dwStyle & WS_CHILD)
         ReleaseDC32( wndPtr->parent->hwndSelf, hdc );
@@ -1204,22 +1134,21 @@
 
     /* Single click brings up the system menu when iconized */
 
-    if (!moved && (wndPtr->dwStyle & WS_MINIMIZE))
+    if( moved )
     {
-        NC_TrackSysMenu( hwnd, pt );
-        return;
-    }
+	if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return;
 
-      /* If Esc key, don't move the window */
-    if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return;
-
-    if (hittest != HTCAPTION)
+	/* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
 	SetWindowPos32( hwnd, 0, sizingRect.left, sizingRect.top,
-		        sizingRect.right - sizingRect.left,
-		        sizingRect.bottom - sizingRect.top,
-		        SWP_NOACTIVATE | SWP_NOZORDER );
-    else SetWindowPos32( hwnd, 0, sizingRect.left, sizingRect.top, 0, 0,
-		         SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER );
+			sizingRect.right - sizingRect.left,
+			sizingRect.bottom - sizingRect.top,
+		      ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
+    }
+    if( wndPtr->dwStyle & WS_MINIMIZE )
+    {
+	WINPOS_ShowIconTitle( wndPtr, TRUE );
+	if( !moved ) NC_TrackSysMenu( hwnd, pt );
+    }
 }
 
 
@@ -1332,7 +1261,10 @@
     switch(wParam)  /* Hit test */
     {
     case HTCAPTION:
-	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
+
+	if( WINPOS_SetActiveWindow(WIN_GetTopParent(hwnd), TRUE, TRUE)
+	    || (GetActiveWindow32() == WIN_GetTopParent(hwnd)) )
+		SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
 	break;
 
     case HTSYSMENU:
diff --git a/windows/painting.c b/windows/painting.c
index 1196b8f..48f0d51 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -2,6 +2,10 @@
  * Window painting functions
  *
  * Copyright 1993, 1994, 1995 Alexandre Julliard
+ *
+ * FIXME: Do not repaint full nonclient area all the time. Instead, compute 
+ *	  intersection with hrgnUpdate (which should be moved from client to 
+ *	  window coords as well, lookup 'the pain' comment in the winpos.c).
  */
 
 #include <stdio.h>
@@ -244,6 +248,8 @@
  * wParam         = flags
  * LOWORD(lParam) = hrgnClip
  * HIWORD(lParam) = hwndSkip  (not used; always NULL)
+ *
+ * All in all, a prime candidate for a rewrite.
  */
 BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
                            HRGN32 hrgnUpdate, UINT32 flags, UINT32 control )
@@ -409,39 +415,43 @@
                     return TRUE;
                 }
            }
-           list = WIN_BuildWinArray( wndPtr );
-           for (ppWnd = list; *ppWnd; ppWnd++)
-           {
-               wndPtr = *ppWnd;
-               if (!IsWindow32(wndPtr->hwndSelf)) continue;
-               if (wndPtr->dwStyle & WS_VISIBLE)
-	       {
-                   SetRectRgn32( hrgn, wndPtr->rectWindow.left,
-                                 wndPtr->rectWindow.top,
-                                 wndPtr->rectWindow.right,
-                                 wndPtr->rectWindow.bottom );
-                   if (!CombineRgn32( hrgn, hrgn, hrgnUpdate, RGN_AND ))
-                       continue;
-                   OffsetRgn32( hrgn, -wndPtr->rectClient.left,
-                                      -wndPtr->rectClient.top );
-                   PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags,
-                                       RDW_C_USEHRGN );
-               }
+           if( (list = WIN_BuildWinArray( wndPtr, 0, NULL )) )
+	   {
+		for (ppWnd = list; *ppWnd; ppWnd++)
+		{
+		    wndPtr = *ppWnd;
+		    if (!IsWindow32(wndPtr->hwndSelf)) continue;
+		    if (wndPtr->dwStyle & WS_VISIBLE)
+		    {
+			SetRectRgn32( hrgn, 
+				wndPtr->rectWindow.left, wndPtr->rectWindow.top, 
+				wndPtr->rectWindow.right, wndPtr->rectWindow.bottom );
+			if (CombineRgn32( hrgn, hrgn, hrgnUpdate, RGN_AND ))
+			{
+			    OffsetRgn32( hrgn, -wndPtr->rectClient.left,
+                                        -wndPtr->rectClient.top );
+			    PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags,
+                                         RDW_C_USEHRGN );
+			}
+		    }
+		}
+		HeapFree( SystemHeap, 0, list );
 	   }
-	   HeapFree( SystemHeap, 0, list );
 	   DeleteObject32( hrgn );
 	   if (control & RDW_C_DELETEHRGN) DeleteObject32( hrgnUpdate );
 	}
         else
         {
-           list = WIN_BuildWinArray( wndPtr );
-           for (ppWnd = list; *ppWnd; ppWnd++)
-           {
-               wndPtr = *ppWnd;
-               if (IsWindow32( wndPtr->hwndSelf ))
-                   PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
-	   }
-	   HeapFree( SystemHeap, 0, list );
+	    if( (list = WIN_BuildWinArray( wndPtr, 0, NULL )) )
+	    {
+		for (ppWnd = list; *ppWnd; ppWnd++)
+		{
+		    wndPtr = *ppWnd;
+		    if (IsWindow32( wndPtr->hwndSelf ))
+			PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
+		}
+	        HeapFree( SystemHeap, 0, list );
+	    }
 	}
 
     }
diff --git a/windows/user.c b/windows/user.c
index 231761a..72cd9b0 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -18,6 +18,7 @@
 #include "debug.h"
 #include "toolhelp.h"
 #include "message.h"
+#include "shell.h"
 
 WORD USER_HeapSel = 0;
 
@@ -178,7 +179,7 @@
         
     /* We have to build a list of all windows first, as in EnumWindows */
 
-    if (!(list = WIN_BuildWinArray( WIN_GetDesktop() ))) return FALSE;
+    if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL ))) return FALSE;
 
     /* Send a WM_QUERYENDSESSION message to every window */
 
diff --git a/windows/win.c b/windows/win.c
index f093af1..087f942 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -43,11 +43,13 @@
 static WORD wDragWidth = 4;
 static WORD wDragHeight= 3;
 
+extern BOOL32 ICONTITLE_Init(void);
 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
 extern HCURSOR16 CURSORICON_IconToCursor(HICON16, BOOL32);
 extern HWND32 CARET_GetHwnd(void);
+extern BOOL32 WINPOS_CreateInternalPosAtom(void);
+extern void   WINPOS_CheckInternalPos(HWND32);
 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
-extern void   WINPOS_CheckActive(HWND32);
 extern BOOL32 EVENT_CheckFocus(void);
 
 /***********************************************************************
@@ -97,7 +99,7 @@
              "next=%p  child=%p  parent=%p  owner=%p  class=%p '%s'\n"
              "inst=%04x  taskQ=%04x  updRgn=%04x  active=%04x dce=%p  idmenu=%04x\n"
              "style=%08lx  exstyle=%08lx  wndproc=%08x  text='%s'\n"
-             "client=%d,%d-%d,%d  window=%d,%d-%d,%d  iconpos=%d,%d  maxpos=%d,%d\n"
+             "client=%d,%d-%d,%d  window=%d,%d-%d,%d"
              "sysmenu=%04x  flags=%04x  props=%p  vscroll=%p  hscroll=%p\n",
              ptr->next, ptr->child, ptr->parent, ptr->owner,
              ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
@@ -106,8 +108,7 @@
              ptr->text ? ptr->text : "",
              ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
              ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
-             ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
-             ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
+             ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
              ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
 
     if (ptr->class->cbWndExtra)
@@ -329,7 +330,7 @@
 
     /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
 
-    WINPOS_CheckActive( hwnd );
+    WINPOS_CheckInternalPos( hwnd );
     if( hwnd == GetCapture32()) ReleaseCapture();
 
     /* free resources associated with the window */
@@ -404,7 +405,9 @@
 
     dprintf_win(stddeb,"Creating desktop window\n");
 
-    if (!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
+    if (!ICONTITLE_Init() ||
+	!WINPOS_CreateInternalPosAtom() ||
+	!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
 	return FALSE;
 
     hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
@@ -424,11 +427,6 @@
     pWndDesktop->rectWindow.right  = SYSMETRICS_CXSCREEN;
     pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
     pWndDesktop->rectClient        = pWndDesktop->rectWindow;
-    pWndDesktop->rectNormal        = pWndDesktop->rectWindow;
-    pWndDesktop->ptIconPos.x       = -1;
-    pWndDesktop->ptIconPos.y       = -1;
-    pWndDesktop->ptMaxPos.x        = -1;
-    pWndDesktop->ptMaxPos.y        = -1;
     pWndDesktop->text              = NULL;
     pWndDesktop->hmemTaskQ         = 0; /* Desktop does not belong to a task */
     pWndDesktop->hrgnUpdate        = 0;
@@ -555,10 +553,6 @@
     wndPtr->dwMagic        = WND_MAGIC;
     wndPtr->hwndSelf       = hwnd;
     wndPtr->hInstance      = cs->hInstance;
-    wndPtr->ptIconPos.x    = -1;
-    wndPtr->ptIconPos.y    = -1;
-    wndPtr->ptMaxPos.x     = -1;
-    wndPtr->ptMaxPos.y     = -1;
     wndPtr->text           = NULL;
     wndPtr->hmemTaskQ      = GetTaskQueue(0);
     wndPtr->hrgnUpdate     = 0;
@@ -621,7 +615,7 @@
 
     if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
     {
-        NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
+        WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
         if (maxSize.x < cs->cx) cs->cx = maxSize.x;
         if (maxSize.y < cs->cy) cs->cy = maxSize.y;
         if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
@@ -635,7 +629,6 @@
     wndPtr->rectWindow.right  = cs->x + cs->cx;
     wndPtr->rectWindow.bottom = cs->y + cs->cy;
     wndPtr->rectClient        = wndPtr->rectWindow;
-    wndPtr->rectNormal        = wndPtr->rectWindow;
 
     /* Create the X window (only for top-level windows, and then only */
     /* when there's no desktop window) */
@@ -753,20 +746,18 @@
 
             if (wndPtr->dwStyle & WS_MINIMIZE)
             {
-                /* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
-
-                wndPtr->dwStyle &= ~WS_MAXIMIZE;
-                WINPOS_FindIconPos( hwnd );
-                SetWindowPos32( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
-                        SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                        SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0)  );
+		RECT16 newPos;
+                wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
+		WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
+                SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
+                                SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0));
             }
             else if (wndPtr->dwStyle & WS_MAXIMIZE)
             {
-                /* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
-
-                NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
-                SetWindowPos32( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
+		RECT16 newPos;
+		wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
+		WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
+                SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
                     ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
             }
 
@@ -1380,7 +1371,7 @@
     {
         if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
         {
-            fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
+            fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
             return 0;
         }
         return *(WORD *)(((char *)wndPtr->wExtra) + offset);
@@ -1823,9 +1814,9 @@
  *
  * hwnd is drawable when it is visible, all parents are not
  * minimized, and it is itself not minimized unless we are
- * trying to draw icon and the default class icon is set.
+ * trying to draw its default class icon.
  */
-BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
+BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
 {
   if( (wnd->dwStyle & WS_MINIMIZE &&
        icon && wnd->class->hIcon) ||
@@ -1967,28 +1958,52 @@
 /*******************************************************************
  *           WIN_BuildWinArray
  *
- * Build an array of pointers to all children of a given window.
- * The array must be freed with HeapFree(SystemHeap).
+ * Build an array of pointers to the children of a given window.
+ * The array must be freed with HeapFree(SystemHeap). Return NULL
+ * when no windows are found.
  */
-WND **WIN_BuildWinArray( WND *wndPtr )
+WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
 {
     WND **list, **ppWnd;
     WND *pWnd;
-    INT32 count;
+    UINT32 count, skipOwned, skipHidden;
+    DWORD skipFlags;
+
+    skipHidden = bwaFlags & BWA_SKIPHIDDEN;
+    skipOwned = bwaFlags & BWA_SKIPOWNED;
+    skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
+    if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
 
     /* First count the windows */
 
     if (!wndPtr) wndPtr = pWndDesktop;
-    for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) count++;
-    count++;  /* For the terminating NULL */
+    for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) 
+    {
+	if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
+	if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
+    }
 
-    /* Now build the list of all windows */
+    if( count )
+    {
+	/* Now build the list of all windows */
 
-    if (!(list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * count )))
-        return NULL;
-    for (pWnd = wndPtr->child, ppWnd = list; pWnd; pWnd = pWnd->next)
-        *ppWnd++ = pWnd;
-    *ppWnd = NULL;
+	if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
+	{
+	    for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
+	    {
+		if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
+		if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
+		{
+		   *ppWnd++ = pWnd;
+		    count++;
+		}
+	    }
+	   *ppWnd = NULL;
+	}
+	else count = 0;
+    } else list = NULL;
+
+    if( pTotal ) *pTotal = count;
     return list;
 }
 
@@ -2004,7 +2019,7 @@
     /* unpleasant side-effects, for instance if the callback  */
     /* function changes the Z-order of the windows.           */
 
-    if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
+    if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
 
     /* Now call the callback function for every window */
 
@@ -2039,7 +2054,7 @@
     /* This function is the same as EnumWindows(),    */
     /* except for an added check on the window queue. */
 
-    if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
+    if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
 
     /* Now call the callback function for every window */
 
@@ -2077,17 +2092,17 @@
     WND **childList;
     BOOL16 ret = FALSE;
 
-    while (*ppWnd)
+    for ( ; *ppWnd; ppWnd++)
     {
         /* Make sure that the window still exists */
         if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
         /* Build children list first */
-        if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
+        if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
+            return FALSE;
         if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
         ret = WIN_EnumChildWindows( childList, func, lParam );
         HeapFree( SystemHeap, 0, childList );
         if (!ret) return FALSE;
-        ppWnd++;
     }
     return TRUE;
 }
@@ -2101,7 +2116,7 @@
     WND **list, *pParent;
 
     if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
-    if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
+    if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
     WIN_EnumChildWindows( list, func, lParam );
     HeapFree( SystemHeap, 0, list );
     return TRUE;
@@ -2300,39 +2315,38 @@
  */
 BOOL32 DragDetect32( HWND32 hWnd, POINT32 pt )
 {
-  MSG16 msg;
-  RECT16  rect;
+    MSG16 msg;
+    RECT16  rect;
 
-  rect.left = pt.x - wDragWidth;
-  rect.right = pt.x + wDragWidth;
+    rect.left = pt.x - wDragWidth;
+    rect.right = pt.x + wDragWidth;
 
-  rect.top = pt.y - wDragHeight;
-  rect.bottom = pt.y + wDragHeight;
+    rect.top = pt.y - wDragHeight;
+    rect.bottom = pt.y + wDragHeight;
 
-  SetCapture32(hWnd);
+    SetCapture32(hWnd);
 
-  while(1)
-   {
-        while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
-         {
-           if( msg.message == WM_LBUTTONUP )
+    while(1)
+    {
+	while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
+        {
+            if( msg.message == WM_LBUTTONUP )
+	    {
+		ReleaseCapture();
+		return 0;
+            }
+            if( msg.message == WM_MOUSEMOVE )
+	    {
+		if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
                 {
-                  ReleaseCapture();
-                  return 0;
+		    ReleaseCapture();
+		    return 1;
                 }
-           if( msg.message == WM_MOUSEMOVE )
-		{
-                  if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
-                    {
-                      ReleaseCapture();
-                      return 1;
-                    }
-		}
-         }
-        WaitMessage();
-   }
-
-  return 0;
+	    }
+        }
+	WaitMessage();
+    }
+    return 0;
 }
 
 /******************************************************************************
@@ -2341,119 +2355,110 @@
 DWORD DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
                     HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
 {
- MSG16	 	msg;
- LPDRAGINFO	lpDragInfo;
- SEGPTR		spDragInfo;
- HCURSOR16 	hDragCursor=0, hOldCursor=0, hBummer=0;
- HGLOBAL16	hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
- WND           *wndPtr = WIN_FindWndPtr(hWnd);
- DWORD		dwRet = 0;
- short	 	dragDone = 0;
- HCURSOR16	hCurrentCursor = 0;
- HWND16		hCurrentWnd = 0;
- BOOL16		b;
+    MSG16	msg;
+    LPDRAGINFO	lpDragInfo;
+    SEGPTR	spDragInfo;
+    HCURSOR16 	hDragCursor=0, hOldCursor=0, hBummer=0;
+    HGLOBAL16	hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
+    WND        *wndPtr = WIN_FindWndPtr(hWnd);
+    HCURSOR16	hCurrentCursor = 0;
+    HWND16	hCurrentWnd = 0;
 
- lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
- spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
+    lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
+    spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
 
- if( !lpDragInfo || !spDragInfo ) return 0L;
+    if( !lpDragInfo || !spDragInfo ) return 0L;
 
- hBummer = LoadCursor16(0,IDC_BUMMER);
+    hBummer = LoadCursor16(0, IDC_BUMMER);
 
- if( !hBummer || !wndPtr )
-   {
+    if( !hBummer || !wndPtr )
+    {
         GlobalFree16(hDragInfo);
         return 0L;
-   }
+    }
 
- if(hCursor)
-   {
+    if(hCursor)
+    {
 	if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
-	  {
-	   GlobalFree16(hDragInfo);
-	   return 0L;
-	  }
+	{
+	    GlobalFree16(hDragInfo);
+	    return 0L;
+	}
 
 	if( hDragCursor == hCursor ) hDragCursor = 0;
 	else hCursor = hDragCursor;
 
 	hOldCursor = SetCursor32(hDragCursor);
-   }
+    }
 
- lpDragInfo->hWnd   = hWnd;
- lpDragInfo->hScope = 0;
- lpDragInfo->wFlags = wObj;
- lpDragInfo->hList  = szList; /* near pointer! */
- lpDragInfo->hOfStruct = hOfStruct;
- lpDragInfo->l = 0L; 
+    lpDragInfo->hWnd   = hWnd;
+    lpDragInfo->hScope = 0;
+    lpDragInfo->wFlags = wObj;
+    lpDragInfo->hList  = szList; /* near pointer! */
+    lpDragInfo->hOfStruct = hOfStruct;
+    lpDragInfo->l = 0L; 
 
- SetCapture32(hWnd);
- ShowCursor32( TRUE );
+    SetCapture32(hWnd);
+    ShowCursor32( TRUE );
 
- while( !dragDone )
-  {
-    WaitMessage();
+    do
+    {
+	do{  WaitMessage(); }
+	while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
 
-    if( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
-	 continue;
+       *(lpDragInfo+1) = *lpDragInfo;
 
-   *(lpDragInfo+1) = *lpDragInfo;
+	lpDragInfo->pt = msg.pt;
 
-    lpDragInfo->pt = msg.pt;
+	/* update DRAGINFO struct */
+	dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
 
-    /* update DRAGINFO struct */
-    dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
-
-    if( (b = DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE)) > 0 )
-	 hCurrentCursor = hCursor;
-    else
+	if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
+	    hCurrentCursor = hCursor;
+	else
         {
-         hCurrentCursor = hBummer;
-         lpDragInfo->hScope = 0;
+            hCurrentCursor = hBummer;
+            lpDragInfo->hScope = 0;
 	}
-    if( hCurrentCursor )
-        SetCursor32(hCurrentCursor);
+	if( hCurrentCursor )
+	    SetCursor32(hCurrentCursor);
 
-    dprintf_msg(stddeb,"drag: got %04x\n", b);
-
-    /* send WM_DRAGLOOP */
-    SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer) , 
-	                            (LPARAM) spDragInfo );
-    /* send WM_DRAGSELECT or WM_DRAGMOVE */
-    if( hCurrentWnd != lpDragInfo->hScope )
+	/* send WM_DRAGLOOP */
+	SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer), 
+	                                  (LPARAM) spDragInfo );
+	/* send WM_DRAGSELECT or WM_DRAGMOVE */
+	if( hCurrentWnd != lpDragInfo->hScope )
 	{
-	 if( hCurrentWnd )
-	   SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0, 
+	    if( hCurrentWnd )
+	        SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0, 
 		       (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
 				        HIWORD(spDragInfo)) );
-	 hCurrentWnd = lpDragInfo->hScope;
-	 if( hCurrentWnd )
-           SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo); 
+	    hCurrentWnd = lpDragInfo->hScope;
+	    if( hCurrentWnd )
+                SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo); 
 	}
+	else
+	    if( hCurrentWnd )
+	        SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
+
+    } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
+
+    ReleaseCapture();
+    ShowCursor32( FALSE );
+
+    if( hCursor )
+    {
+	SetCursor32( hOldCursor );
+	if (hDragCursor) DestroyCursor32( hDragCursor );
+    }
+
+    if( hCurrentCursor != hBummer ) 
+	msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT, 
+				   (WPARAM16)hWnd, (LPARAM)spDragInfo );
     else
-	if( hCurrentWnd )
-	   SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
+        msg.lParam = 0;
+    GlobalFree16(hDragInfo);
 
-
-    /* check if we're done */
-    if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
-	dragDone = TRUE;
-  }
-
- ReleaseCapture();
- ShowCursor32( FALSE );
-
- if( hCursor )
- {
-     SetCursor32( hOldCursor );
-     if (hDragCursor) DestroyCursor32( hDragCursor );
- }
-
- if( hCurrentCursor != hBummer ) 
-	dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT, 
-                               (WPARAM16)hWnd, (LPARAM)spDragInfo );
- GlobalFree16(hDragInfo);
-
- return dwRet;
+    return (DWORD)(msg.lParam);
 }
 
diff --git a/windows/winhelp.c b/windows/winhelp.c
index f087247..49ae2ca 100644
--- a/windows/winhelp.c
+++ b/windows/winhelp.c
@@ -76,7 +76,7 @@
 			return FALSE;
 	}
 	if(lpHelpFile)
-		nlen =  strlen(lpHelpFile)+1;
+		nlen = strlen(lpHelpFile)+1;
 	else
 		nlen = 0;
 	size = sizeof(WINHELP) + nlen + dsize;
@@ -84,10 +84,12 @@
 	lpwh = GlobalLock16(hwh);
 	lpwh->size = size;
 	lpwh->command = wCommand;
+	lpwh->data = dwData;
 	if(nlen) {
-		lpwh->ofsFilename = sizeof(WINHELP);
 		strcpy(((char*)lpwh) + sizeof(WINHELP),lpHelpFile);
-	}
+		lpwh->ofsFilename = sizeof(WINHELP);
+ 	} else
+		lpwh->ofsFilename = 0;
 	if(dsize) {
 		memcpy(((char*)lpwh)+sizeof(WINHELP)+nlen,(LPSTR)dwData,dsize);
 		lpwh->ofsData = sizeof(WINHELP)+nlen;
diff --git a/windows/winpos.c b/windows/winpos.c
index 9b90564..3c4a469 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -2,7 +2,7 @@
  * Window position related functions.
  *
  * Copyright 1993, 1994, 1995 Alexandre Julliard
- *                       1995,1996 Alex Korobka
+ *                       1995, 1996 Alex Korobka
  */
 
 #include <X11/Xlib.h>
@@ -24,6 +24,14 @@
 /* #define DEBUG_WIN */
 #include "debug.h"
 
+#define HAS_DLGFRAME(style,exStyle) \
+    (((exStyle) & WS_EX_DLGMODALFRAME) || \
+     (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
+
+#define HAS_THICKFRAME(style) \
+    (((style) & WS_THICKFRAME) && \
+     !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
+
 #define  SWP_AGG_NOGEOMETRYCHANGE \
     (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
 #define  SWP_AGG_NOPOSCHANGE \
@@ -31,6 +39,12 @@
 #define  SWP_AGG_STATUSFLAGS \
     (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
 
+#define EMPTYPOINT(pt)          ((*(LONG*)&(pt)) == -1)
+
+#define PLACE_MIN		0x0001
+#define PLACE_MAX		0x0002
+#define PLACE_RECT		0x0004
+
 #define SMC_NOCOPY		0x0001
 #define SMC_NOPARENTERASE	0x0002
 #define SMC_DRAWFRAME		0x0004
@@ -48,46 +62,66 @@
 static HWND32 hwndActive      = 0;  /* Currently active window */
 static HWND32 hwndPrevActive  = 0;  /* Previously active window */
 
+static LPCSTR atomInternalPos;
+
 extern MESSAGEQUEUE* pActiveQueue;
 
 /***********************************************************************
- *           WINPOS_CheckActive
+ *           WINPOS_CreateInternalPosAtom
  */
-void WINPOS_CheckActive( HWND32 hwnd )
+BOOL32 WINPOS_CreateInternalPosAtom()
 {
-  if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
-  if( hwnd == hwndActive )
-  {
-      hwndActive = 0; 
-      dprintf_win(stddeb,"\tattempt to activate destroyed window!\n");
-  }
+    LPSTR str = "SysIP";
+    atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtom32A(str);
+    return (atomInternalPos) ? TRUE : FALSE;
+}
+
+/***********************************************************************
+ *           WINPOS_CheckInternalPos
+ *
+ * Called when a window is destroyed.
+ */
+void WINPOS_CheckInternalPos( HWND32 hwnd )
+{
+    LPINTERNALPOS lpPos = (LPINTERNALPOS) GetProp32A( hwnd, atomInternalPos );
+
+    if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
+    if( hwnd == hwndActive )
+    {
+	hwndActive = 0; 
+	dprintf_win(stddeb,"\tattempt to activate destroyed window!\n");
+    }
+
+    if( lpPos )
+    {
+	if( IsWindow32(lpPos->hwndIconTitle) ) 
+	    DestroyWindow32( lpPos->hwndIconTitle );
+	HeapFree( SystemHeap, 0, lpPos );
+    }
 }
 
 /***********************************************************************
  *           WINPOS_FindIconPos
  *
  * Find a suitable place for an iconic window.
- * The new position is stored into wndPtr->ptIconPos.
  */
-void WINPOS_FindIconPos( HWND32 hwnd )
+static POINT16 WINPOS_FindIconPos( WND* wndPtr, POINT16 pt )
 {
     RECT16 rectParent;
     short x, y, xspacing, yspacing;
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
 
-    if (!wndPtr || !wndPtr->parent) return;
     GetClientRect16( wndPtr->parent->hwndSelf, &rectParent );
-    if ((wndPtr->ptIconPos.x >= rectParent.left) &&
-        (wndPtr->ptIconPos.x + SYSMETRICS_CXICON < rectParent.right) &&
-        (wndPtr->ptIconPos.y >= rectParent.top) &&
-        (wndPtr->ptIconPos.y + SYSMETRICS_CYICON < rectParent.bottom))
-        return;  /* The icon already has a suitable position */
+    if ((pt.x >= rectParent.left) && (pt.x + SYSMETRICS_CXICON < rectParent.right) &&
+        (pt.y >= rectParent.top) && (pt.y + SYSMETRICS_CYICON < rectParent.bottom))
+        return pt;  /* The icon already has a suitable position */
 
-    xspacing = yspacing = 70;  /* FIXME: This should come from WIN.INI */
+    xspacing = SYSMETRICS_CXICONSPACING;
+    yspacing = SYSMETRICS_CYICONSPACING;
+
     y = rectParent.bottom;
     for (;;)
     {
-        for (x = rectParent.left; x<=rectParent.right-xspacing; x += xspacing)
+        for (x = rectParent.left; x <= rectParent.right-xspacing; x += xspacing)
         {
               /* Check if another icon already occupies this spot */
             WND *childPtr = wndPtr->parent->child;
@@ -103,12 +137,11 @@
                 }
                 childPtr = childPtr->next;
             }
-            if (!childPtr)
+            if (!childPtr) /* No window was found, so it's OK for us */
             {
-                  /* No window was found, so it's OK for us */
-                wndPtr->ptIconPos.x = x + (xspacing - SYSMETRICS_CXICON) / 2;
-                wndPtr->ptIconPos.y = y - (yspacing + SYSMETRICS_CYICON) / 2;
-                return;
+		pt.x = x + (xspacing - SYSMETRICS_CXICON) / 2;
+		pt.y = y - (yspacing + SYSMETRICS_CYICON) / 2;
+		return pt;
             }
         }
         y -= yspacing;
@@ -117,13 +150,14 @@
 
 
 /***********************************************************************
- *           ArrangeIconicWindows   (USER32.6)
+ *           ArrangeIconicWindows16   (USER.170)
  */
-UINT16 ArrangeIconicWindows16( HWND16 parent) {
+UINT16 ArrangeIconicWindows16( HWND16 parent) 
+{
     return ArrangeIconicWindows32(parent);
 }
 /***********************************************************************
- *           ArrangeIconicWindows   (USER.170)
+ *           ArrangeIconicWindows32   (USER32.6)
  */
 UINT32 ArrangeIconicWindows32( HWND32 parent )
 {
@@ -134,15 +168,20 @@
     GetClientRect32( parent, &rectParent );
     x = rectParent.left;
     y = rectParent.bottom;
-    xspacing = yspacing = 70;  /* FIXME: This should come from WIN.INI */
+    xspacing = SYSMETRICS_CXICONSPACING;
+    yspacing = SYSMETRICS_CYICONSPACING;
+
     hwndChild = GetWindow32( parent, GW_CHILD );
     while (hwndChild)
     {
-        if (IsIconic32( hwndChild ))
+        if( IsIconic32( hwndChild ) )
         {
+	    WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), FALSE );
             SetWindowPos32( hwndChild, 0, x + (xspacing - SYSMETRICS_CXICON) / 2,
-                            y - (yspacing + SYSMETRICS_CYICON) / 2, 0, 0,
-                            SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE );
+                            y - yspacing - SYSMETRICS_CYICON/2, 0, 0,
+                            SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+	    if( IsWindow32(hwndChild) )
+	        WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), TRUE );
             if (x <= rectParent.right - xspacing) x += xspacing;
             else
             {
@@ -497,14 +536,14 @@
 
 
 /***********************************************************************
- *           IsIconic   (USER.31)
+ *           IsIconic16   (USER.31)
  */
 BOOL16 IsIconic16(HWND16 hWnd)
 {
     return IsIconic32(hWnd);
 }
 /***********************************************************************
- *           IsIconic   (USER32.344)
+ *           IsIconic32   (USER32.344)
  */
 BOOL32 IsIconic32(HWND32 hWnd)
 {
@@ -537,21 +576,22 @@
  */
 HWND16 GetActiveWindow16(void)
 {
-    return GetActiveWindow32();
+    return (HWND16)hwndActive;
 }
+
 /*******************************************************************
  *         GetActiveWindow    (USER32.204)
  */
 HWND32 GetActiveWindow32(void)
 {
-    return hwndActive;
+    return (HWND32)hwndActive;
 }
 
 
 /*******************************************************************
- *         WINPOS_IsGoodEnough
+ *         WINPOS_CanActivate
  */
-static BOOL32 WINPOS_IsGoodEnough(WND* pWnd)
+static BOOL32 WINPOS_CanActivate(WND* pWnd)
 {
  return (pWnd) ? ((!(pWnd->dwStyle & WS_DISABLED) &&
                      pWnd->dwStyle & WS_VISIBLE ) ? TRUE : FALSE) : FALSE;
@@ -573,7 +613,7 @@
     HWND32 prev = hwndActive;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    if ( !WINPOS_IsGoodEnough(wndPtr) ) return 0;
+    if ( !WINPOS_CanActivate(wndPtr) ) return 0;
 
     WINPOS_SetActiveWindow( hwnd, 0, 0 );
     return prev;
@@ -618,6 +658,247 @@
 }
 
 /***********************************************************************
+ *           WINPOS_InitInternalPos
+ */
+static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT16 pt, 
+					     LPRECT16 restoreRect )
+{
+    LPINTERNALPOS lpPos = (LPINTERNALPOS) GetProp32A( wnd->hwndSelf, atomInternalPos );
+    if( !lpPos )
+    {
+	/* this happens when the window is minimized/maximized 
+	 * for the first time (rectWindow is not adjusted yet) */
+
+	lpPos = HeapAlloc( SystemHeap, 0, sizeof(INTERNALPOS) );
+	if( !lpPos ) return NULL;
+
+	SetProp32A( wnd->hwndSelf, atomInternalPos, (HANDLE32)lpPos );
+	lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
+	lpPos->rectNormal = wnd->rectWindow;
+	*(UINT32*)&lpPos->ptIconPos = *(UINT32*)&lpPos->ptMaxPos = 0xFFFFFFFF;
+    }
+
+    if( wnd->dwStyle & WS_MINIMIZE ) 
+	lpPos->ptIconPos = pt;
+    else if( wnd->dwStyle & WS_MAXIMIZE ) 
+	lpPos->ptMaxPos = pt;
+    else if( restoreRect ) 
+	lpPos->rectNormal = *restoreRect;
+
+    return lpPos;
+}
+
+/***********************************************************************
+ *           WINPOS_RedrawIconTitle
+ */
+BOOL32 WINPOS_RedrawIconTitle( HWND32 hWnd )
+{
+    LPINTERNALPOS lpPos = (LPINTERNALPOS)GetProp32A( hWnd, atomInternalPos );
+    if( lpPos )
+    {
+	if( lpPos->hwndIconTitle )
+	{
+	    SendMessage32A( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
+	    InvalidateRect32( lpPos->hwndIconTitle, NULL, TRUE );
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/***********************************************************************
+ *           WINPOS_ShowIconTitle
+ */
+BOOL32 WINPOS_ShowIconTitle( WND* pWnd, BOOL32 bShow )
+{
+    LPINTERNALPOS lpPos = (LPINTERNALPOS)GetProp32A( pWnd->hwndSelf, atomInternalPos );
+
+    if( lpPos && !(pWnd->flags & WIN_MANAGED))
+    {
+	HWND16 hWnd = lpPos->hwndIconTitle;
+
+	dprintf_win(stddeb,"ShowIconTitle: 0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) );
+
+	if( !hWnd )
+	    lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd );
+	if( bShow )
+        {
+	    pWnd = WIN_FindWndPtr(hWnd);
+
+	    if( !(pWnd->dwStyle & WS_VISIBLE) )
+	    {
+		SendMessage16( hWnd, WM_SHOWWINDOW, TRUE, 0 );
+		SetWindowPos32( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+			        SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
+	    }
+	}
+	else ShowWindow32( hWnd, SW_HIDE );
+    }
+    return FALSE;
+}
+
+/*******************************************************************
+ *           WINPOS_GetMinMaxInfo
+ *
+ * Get the minimized and maximized information for a window.
+ */
+void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT16 *maxSize, POINT16 *maxPos,
+			   POINT16 *minTrack, POINT16 *maxTrack )
+{
+    LPINTERNALPOS lpPos;
+    MINMAXINFO16 *MinMax;
+    short xinc, yinc;
+
+    if (!(MinMax = SEGPTR_NEW(MINMAXINFO16))) return;
+
+      /* Compute default values */
+
+    MinMax->ptMaxSize.x = SYSMETRICS_CXSCREEN;
+    MinMax->ptMaxSize.y = SYSMETRICS_CYSCREEN;
+    MinMax->ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
+    MinMax->ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
+    MinMax->ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
+    MinMax->ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
+
+    if (wndPtr->flags & WIN_MANAGED) xinc = yinc = 0;
+    else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+    {
+        xinc = SYSMETRICS_CXDLGFRAME;
+        yinc = SYSMETRICS_CYDLGFRAME;
+    }
+    else
+    {
+        xinc = yinc = 0;
+        if (HAS_THICKFRAME(wndPtr->dwStyle))
+        {
+            xinc += SYSMETRICS_CXFRAME;
+            yinc += SYSMETRICS_CYFRAME;
+        }
+        if (wndPtr->dwStyle & WS_BORDER)
+        {
+            xinc += SYSMETRICS_CXBORDER;
+            yinc += SYSMETRICS_CYBORDER;
+        }
+    }
+    MinMax->ptMaxSize.x += 2 * xinc;
+    MinMax->ptMaxSize.y += 2 * yinc;
+
+    lpPos = (LPINTERNALPOS)GetProp32A( wndPtr->hwndSelf, atomInternalPos );
+    if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
+	MinMax->ptMaxPosition = lpPos->ptMaxPos;
+    else
+    {
+        MinMax->ptMaxPosition.x = -xinc;
+        MinMax->ptMaxPosition.y = -yinc;
+    }
+
+    SendMessage16( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0,
+                   (LPARAM)SEGPTR_GET(MinMax) );
+
+      /* Some sanity checks */
+
+    dprintf_win(stddeb,"GetMinMaxInfo: %d %d / %d %d / %d %d / %d %d\n",
+                      MinMax->ptMaxSize.x, MinMax->ptMaxSize.y,
+                      MinMax->ptMaxPosition.x, MinMax->ptMaxPosition.y,
+                      MinMax->ptMaxTrackSize.x, MinMax->ptMaxTrackSize.y,
+                      MinMax->ptMinTrackSize.x, MinMax->ptMinTrackSize.y);
+    MinMax->ptMaxTrackSize.x = MAX( MinMax->ptMaxTrackSize.x,
+                                   MinMax->ptMinTrackSize.x );
+    MinMax->ptMaxTrackSize.y = MAX( MinMax->ptMaxTrackSize.y,
+                                   MinMax->ptMinTrackSize.y );
+
+    if (maxSize) *maxSize = MinMax->ptMaxSize;
+    if (maxPos) *maxPos = MinMax->ptMaxPosition;
+    if (minTrack) *minTrack = MinMax->ptMinTrackSize;
+    if (maxTrack) *maxTrack = MinMax->ptMaxTrackSize;
+    SEGPTR_FREE(MinMax);
+}
+
+/***********************************************************************
+ *           WINPOS_MinMaximize
+ *
+ * Fill in lpRect and return additional flags to be used with SetWindowPos().
+ * This function assumes that 'cmd' is different from the current window
+ * state.
+ */
+UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
+{
+    UINT16	  swpFlags = 0;
+    POINT16	  size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top };
+    LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size, &wndPtr->rectWindow );
+
+    dprintf_win(stddeb,"MinMaximize: 0x%04x %u\n", wndPtr->hwndSelf, cmd );
+
+    if( lpPos && !HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd) )
+    {
+	if( wndPtr->dwStyle & WS_MINIMIZE )
+	{
+	    if( !SendMessage32A( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
+		return (SWP_NOSIZE | SWP_NOMOVE);
+	    swpFlags |= SWP_NOCOPYBITS;
+	}
+	switch( cmd )
+	{
+	    case SW_MINIMIZE:
+		 if( wndPtr->dwStyle & WS_MAXIMIZE)
+		 {
+		     wndPtr->flags |= WIN_RESTORE_MAX;
+		     wndPtr->dwStyle &= ~WS_MAXIMIZE;
+                 }
+                 else
+		     wndPtr->flags &= ~WIN_RESTORE_MAX;
+		 wndPtr->dwStyle |= WS_MINIMIZE;
+
+		 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
+
+		 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
+				    SYSMETRICS_CXICON, SYSMETRICS_CYICON );
+		 swpFlags |= SWP_NOCOPYBITS;
+		 break;
+
+	    case SW_MAXIMIZE:
+		 WINPOS_GetMinMaxInfo( wndPtr, &size, &lpPos->ptMaxPos, NULL, NULL );
+
+		 if( wndPtr->dwStyle & WS_MINIMIZE )
+		 {
+		     WINPOS_ShowIconTitle( wndPtr, FALSE );
+		     wndPtr->dwStyle &= ~WS_MINIMIZE;
+		 }
+                 wndPtr->dwStyle |= WS_MAXIMIZE;
+
+		 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
+				    size.x, size.y );
+		 break;
+
+	    case SW_RESTORE:
+		 if( wndPtr->dwStyle & WS_MINIMIZE )
+		 {
+		     wndPtr->dwStyle &= ~WS_MINIMIZE;
+		     WINPOS_ShowIconTitle( wndPtr, FALSE );
+		     if( wndPtr->flags & WIN_RESTORE_MAX)
+		     {
+			 /* Restore to maximized position */
+			 WINPOS_GetMinMaxInfo( wndPtr, &size, &lpPos->ptMaxPos, NULL, NULL );
+			 wndPtr->dwStyle |= WS_MAXIMIZE;
+		     }
+		 } 
+		 else 
+		     if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
+ 		     else wndPtr->dwStyle &= ~WS_MAXIMIZE;
+
+		 /* Restore to normal position */
+
+		*lpRect = lpPos->rectNormal; 
+		 lpRect->right -= lpRect->left; 
+		 lpRect->bottom -= lpRect->top;
+
+		 break;
+	}
+    } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
+    return swpFlags;
+}
+
+/***********************************************************************
  *           ShowWindow   (USER.42)
  */
 BOOL16 ShowWindow16( HWND16 hwnd, INT16 cmd ) 
@@ -629,11 +910,10 @@
  */
 BOOL32 ShowWindow32( HWND32 hwnd, INT32 cmd ) 
 {    
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    BOOL32 wasVisible, showFlag;
-    POINT16 maxSize;
-    int swpflags = 0;
-    short x = 0, y = 0, cx = 0, cy = 0;
+    WND* 	wndPtr = WIN_FindWndPtr( hwnd );
+    BOOL32 	wasVisible, showFlag;
+    RECT16 	newPos = {0, 0, 0, 0};
+    int 	swp = 0;
 
     if (!wndPtr) return FALSE;
 
@@ -645,139 +925,49 @@
     {
         case SW_HIDE:
             if (!wasVisible) return FALSE;
-	    swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
+	    swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
 		        SWP_NOACTIVATE | SWP_NOZORDER;
 	    break;
 
 	case SW_SHOWMINNOACTIVE:
-            swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
+            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
             /* fall through */
 	case SW_SHOWMINIMIZED:
-            swpflags |= SWP_SHOWWINDOW;
+            swp |= SWP_SHOWWINDOW;
             /* fall through */
 	case SW_MINIMIZE:
-            swpflags |= SWP_FRAMECHANGED;
-            if (!(wndPtr->dwStyle & WS_MINIMIZE))
-            {
-		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
-		    return 0;
-
-                if (wndPtr->dwStyle & WS_MAXIMIZE)
-                {
-                    wndPtr->flags |= WIN_RESTORE_MAX;
-                    wndPtr->dwStyle &= ~WS_MAXIMIZE;
-                }
-                else
-                {
-                    wndPtr->flags &= ~WIN_RESTORE_MAX;
-                    wndPtr->rectNormal = wndPtr->rectWindow;
-                }
-                wndPtr->dwStyle |= WS_MINIMIZE;
-                WINPOS_FindIconPos( hwnd );
-                x  = wndPtr->ptIconPos.x;
-                y  = wndPtr->ptIconPos.y;
-                cx = SYSMETRICS_CXICON;
-                cy = SYSMETRICS_CYICON;
-		swpflags |= SWP_NOCOPYBITS;
-            }
-            else swpflags |= SWP_NOSIZE | SWP_NOMOVE;
+            swp |= SWP_FRAMECHANGED;
+            if( !(wndPtr->dwStyle & WS_MINIMIZE) )
+		 swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
 	    break;
 
-	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE: */
-            swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
-            if (!(wndPtr->dwStyle & WS_MAXIMIZE))
-            {
-		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
-		    return 0;
-
-                  /* Store the current position and find the maximized size */
-                if (!(wndPtr->dwStyle & WS_MINIMIZE))
-                    wndPtr->rectNormal = wndPtr->rectWindow; 
-
-                NC_GetMinMaxInfo( wndPtr, &maxSize,
-                                  &wndPtr->ptMaxPos, NULL, NULL );
-                x  = wndPtr->ptMaxPos.x;
-                y  = wndPtr->ptMaxPos.y;
-
-		if( wndPtr->dwStyle & WS_MINIMIZE )
-		    if( !SendMessage32A( hwnd, WM_QUERYOPEN, 0, 0L ) )
-			{
-		         swpflags |= SWP_NOSIZE | SWP_NOMOVE;
-			 break;
-			}
-		    else swpflags |= SWP_NOCOPYBITS;
-
-                cx = maxSize.x;
-                cy = maxSize.y;
-                wndPtr->dwStyle &= ~WS_MINIMIZE;
-                wndPtr->dwStyle |= WS_MAXIMIZE;
-            }
-            else swpflags |= SWP_NOSIZE | SWP_NOMOVE;
+	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
+            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+            if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
+		 swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
             break;
 
 	case SW_SHOWNA:
-            swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
+            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
             /* fall through */
 	case SW_SHOW:
-	    swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
 	    break;
 
 	case SW_SHOWNOACTIVATE:
-            swpflags |= SWP_NOZORDER;
-            if (GetActiveWindow32()) swpflags |= SWP_NOACTIVATE;
+            swp |= SWP_NOZORDER;
+            if (GetActiveWindow32()) swp |= SWP_NOACTIVATE;
             /* fall through */
 	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
 	case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
 	case SW_RESTORE:
-	    swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+	    swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
 
-            if (wndPtr->dwStyle & WS_MINIMIZE)
-            {
-		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
-		    return 0;
-
-                if( !SendMessage16( hwnd, WM_QUERYOPEN, 0, 0L) )
-                  {
-                    swpflags |= SWP_NOSIZE | SWP_NOMOVE;
-                    break;
-                  }
-                wndPtr->ptIconPos.x = wndPtr->rectWindow.left;
-                wndPtr->ptIconPos.y = wndPtr->rectWindow.top;
-                wndPtr->dwStyle &= ~WS_MINIMIZE;
-                if (wndPtr->flags & WIN_RESTORE_MAX)
-                {
-                    /* Restore to maximized position */
-                    NC_GetMinMaxInfo( wndPtr, &maxSize, &wndPtr->ptMaxPos,
-                                      NULL, NULL );
-                    x  = wndPtr->ptMaxPos.x;
-                    y  = wndPtr->ptMaxPos.y;
-                    cx = maxSize.x;
-                    cy = maxSize.y;
-                   wndPtr->dwStyle |= WS_MAXIMIZE;
-                }
-                else  /* Restore to normal position */
-                {
-                    x  = wndPtr->rectNormal.left;
-                    y  = wndPtr->rectNormal.top;
-                    cx = wndPtr->rectNormal.right - wndPtr->rectNormal.left;
-                    cy = wndPtr->rectNormal.bottom - wndPtr->rectNormal.top;
-                }
-		swpflags |= SWP_NOCOPYBITS;
-            }
-            else if (wndPtr->dwStyle & WS_MAXIMIZE)
-            {
-		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
-		    return 0;
-
-                wndPtr->ptMaxPos.x = wndPtr->rectWindow.left;
-                wndPtr->ptMaxPos.y = wndPtr->rectWindow.top;
-                wndPtr->dwStyle &= ~WS_MAXIMIZE;
-                x  = wndPtr->rectNormal.left;
-                y  = wndPtr->rectNormal.top;
-                cx = wndPtr->rectNormal.right - wndPtr->rectNormal.left;
-                cy = wndPtr->rectNormal.bottom - wndPtr->rectNormal.top;
-            }
-            else swpflags |= SWP_NOSIZE | SWP_NOMOVE;
+            if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
+		 swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
 	    break;
     }
 
@@ -790,7 +980,7 @@
 
     if ((wndPtr->dwStyle & WS_CHILD) &&
         !IsWindowVisible32( wndPtr->parent->hwndSelf ) &&
-        (swpflags & SWP_NOSIZE) && (swpflags & SWP_NOMOVE))
+        (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
     {
         /* Don't call SetWindowPos32() on invisible child windows */
         if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
@@ -799,10 +989,11 @@
     else
     {
         /* We can't activate a child window */
-        if (wndPtr->dwStyle & WS_CHILD)
-            swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
-        SetWindowPos32( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
+        if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+        SetWindowPos32( hwnd, HWND_TOP, 
+			newPos.left, newPos.top, newPos.right, newPos.bottom, swp );
         if (!IsWindow32( hwnd )) return wasVisible;
+	else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
     }
 
     if (wndPtr->flags & WIN_NEED_SIZE)
@@ -830,10 +1021,13 @@
 UINT16 GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd, LPPOINT16 ptIcon)
 {
     WINDOWPLACEMENT16 wndpl;
-    if (!GetWindowPlacement16( hwnd, &wndpl )) return 0;
-    if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
-    if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
-    return wndpl.showCmd;
+    if (GetWindowPlacement16( hwnd, &wndpl )) 
+    {
+	if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
+	if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
+	return wndpl.showCmd;
+    }
+    return 0;
 }
 
 
@@ -843,10 +1037,142 @@
 UINT32 GetInternalWindowPos32( HWND32 hwnd, LPRECT32 rectWnd, LPPOINT32 ptIcon)
 {
     WINDOWPLACEMENT32 wndpl;
-    if (!GetWindowPlacement32( hwnd, &wndpl )) return 0;
-    if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
-    if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
-    return wndpl.showCmd;
+    if (GetWindowPlacement32( hwnd, &wndpl ))
+    {
+	if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
+	if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
+	return wndpl.showCmd;
+    }
+    return 0;
+}
+
+/***********************************************************************
+ *           GetWindowPlacement16   (USER.370)
+ */
+BOOL16 GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
+{
+    WND *pWnd = WIN_FindWndPtr( hwnd );
+    if( pWnd )
+    {
+	LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
+			     *(LPPOINT16)&pWnd->rectWindow.left, &pWnd->rectWindow );
+	wndpl->length  = sizeof(*wndpl);
+	if( pWnd->dwStyle & WS_MINIMIZE )
+	    wndpl->showCmd = SW_SHOWMAXIMIZED;
+	else 
+	    wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE )
+			     ? SW_SHOWMINIMIZED : SW_SHOWNORMAL ;
+	if( pWnd->flags & WIN_RESTORE_MAX )
+	    wndpl->flags = WPF_RESTORETOMAXIMIZED;
+	else
+	    wndpl->flags = 0;
+	wndpl->ptMinPosition = lpPos->ptIconPos;
+	wndpl->ptMaxPosition = lpPos->ptMaxPos;
+	wndpl->rcNormalPosition = lpPos->rectNormal;
+	return TRUE;
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           GetWindowPlacement32   (USER32.306)
+ */
+BOOL32 GetWindowPlacement32( HWND32 hwnd, WINDOWPLACEMENT32 *pwpl32 )
+{
+    if( pwpl32 )
+    {
+	WINDOWPLACEMENT16 wpl;
+	wpl.length = sizeof(wpl);
+        if( GetWindowPlacement16( hwnd, &wpl ) )
+	{
+	    pwpl32->length = sizeof(*pwpl32);
+	    pwpl32->flags = wpl.flags;
+	    pwpl32->showCmd = wpl.showCmd;
+	    CONV_POINT16TO32( &wpl.ptMinPosition, &pwpl32->ptMinPosition );
+	    CONV_POINT16TO32( &wpl.ptMaxPosition, &pwpl32->ptMaxPosition );
+	    CONV_RECT16TO32( &wpl.rcNormalPosition, &pwpl32->rcNormalPosition );
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           WINPOS_SetPlacement
+ */
+static BOOL32 WINPOS_SetPlacement( HWND32 hwnd, const WINDOWPLACEMENT16 *wndpl,
+						UINT32 flags )
+{
+    WND *pWnd = WIN_FindWndPtr( hwnd );
+    if( pWnd )
+    {
+	LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
+			     *(LPPOINT16)&pWnd->rectWindow.left, &pWnd->rectWindow );
+
+	if( flags & PLACE_MIN ) lpPos->ptIconPos = wndpl->ptMinPosition;
+	if( flags & PLACE_MAX ) lpPos->ptMaxPos = wndpl->ptMaxPosition;
+	if( flags & PLACE_RECT) lpPos->rectNormal = wndpl->rcNormalPosition;
+
+	if( pWnd->dwStyle & WS_MINIMIZE )
+	{
+	    WINPOS_ShowIconTitle( pWnd, FALSE );
+	    if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
+		SetWindowPos32( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
+				0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+	} 
+	else if( pWnd->dwStyle & WS_MAXIMIZE )
+	{
+	    if( !EMPTYPOINT(lpPos->ptMaxPos) )
+		SetWindowPos32( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
+				0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+	}
+	else if( flags & PLACE_RECT )
+		SetWindowPos32( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
+				lpPos->rectNormal.right - lpPos->rectNormal.left,
+				lpPos->rectNormal.bottom - lpPos->rectNormal.top,
+				SWP_NOZORDER | SWP_NOACTIVATE );
+
+	ShowWindow32( hwnd, wndpl->showCmd );
+	if( IsWindow32(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
+	{
+	    if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd, TRUE );
+
+	    /* SDK: ...valid only the next time... */
+	    if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
+	}
+	return TRUE;
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           SetWindowPlacement16   (USER.371)
+ */
+BOOL16 SetWindowPlacement16( HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl )
+{
+    return WINPOS_SetPlacement( hwnd, wndpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
+}
+
+/***********************************************************************
+ *           SetWindowPlacement32   (USER32.518)
+ */
+BOOL32 SetWindowPlacement32( HWND32 hwnd, const WINDOWPLACEMENT32 *pwpl32 )
+{
+    if( pwpl32 )
+    {
+	WINDOWPLACEMENT16 wpl = { sizeof(WINDOWPLACEMENT16), 
+		pwpl32->flags, pwpl32->showCmd, { pwpl32->ptMinPosition.x,
+		pwpl32->ptMinPosition.y }, { pwpl32->ptMaxPosition.x,
+		pwpl32->ptMaxPosition.y }, { pwpl32->rcNormalPosition.left,
+		pwpl32->rcNormalPosition.top, pwpl32->rcNormalPosition.right,
+		pwpl32->rcNormalPosition.bottom } };
+
+        return WINPOS_SetPlacement( hwnd, &wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
+    }
+    return FALSE;
 }
 
 
@@ -856,16 +1182,28 @@
 void SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
                              LPRECT16 rect, LPPOINT16 pt )
 {
-    WINDOWPLACEMENT16 wndpl;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    if( IsWindow16(hwnd) )
+    {
+	WINDOWPLACEMENT16 wndpl;
+	UINT32 flags;
 
-    wndpl.length  = sizeof(wndpl);
-    wndpl.flags   = (pt != NULL) ? WPF_SETMINPOSITION : 0;
-    wndpl.showCmd = showCmd;
-    if (pt) wndpl.ptMinPosition = *pt;
-    wndpl.rcNormalPosition = (rect != NULL) ? *rect : wndPtr->rectNormal;
-    wndpl.ptMaxPosition = wndPtr->ptMaxPos;
-    SetWindowPlacement16( hwnd, &wndpl );
+	wndpl.length  = sizeof(wndpl);
+	wndpl.showCmd = showCmd;
+	wndpl.flags = flags = 0;
+
+	if( pt )
+	{
+	    flags |= PLACE_MIN;
+	    wndpl.flags |= WPF_SETMINPOSITION;
+	    wndpl.ptMinPosition = *pt;
+	}
+	if( rect )
+	{
+	    flags |= PLACE_RECT;
+	    wndpl.rcNormalPosition = *rect;
+	}
+	WINPOS_SetPlacement( hwnd, &wndpl, flags );
+    }
 }
 
 
@@ -875,93 +1213,28 @@
 void SetInternalWindowPos32( HWND32 hwnd, UINT32 showCmd,
                              LPRECT32 rect, LPPOINT32 pt )
 {
-    WINDOWPLACEMENT32 wndpl;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    if( IsWindow32(hwnd) )
+    {
+	WINDOWPLACEMENT16 wndpl;
+	UINT32 flags;
 
-    wndpl.length  = sizeof(wndpl);
-    wndpl.flags   = (pt != NULL) ? WPF_SETMINPOSITION : 0;
-    wndpl.showCmd = showCmd;
-    if (pt) wndpl.ptMinPosition = *pt;
-    if (rect) wndpl.rcNormalPosition = *rect;
-    else CONV_RECT16TO32( &wndPtr->rectNormal, &wndpl.rcNormalPosition );
-    CONV_POINT16TO32( &wndPtr->ptMaxPos, &wndpl.ptMaxPosition );
-    SetWindowPlacement32( hwnd, &wndpl );
-}
+	wndpl.length  = sizeof(wndpl);
+	wndpl.showCmd = showCmd;
+	wndpl.flags = flags = 0;
 
-
-/***********************************************************************
- *           GetWindowPlacement16   (USER.370)
- */
-BOOL16 GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
-
-    wndpl->length  = sizeof(*wndpl);
-    wndpl->flags   = 0;
-    wndpl->showCmd = IsZoomed16(hwnd) ? SW_SHOWMAXIMIZED : 
-	             (IsIconic16(hwnd) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL);
-    wndpl->ptMinPosition = wndPtr->ptIconPos;
-    wndpl->ptMaxPosition = wndPtr->ptMaxPos;
-    wndpl->rcNormalPosition = wndPtr->rectNormal;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GetWindowPlacement32   (USER32.306)
- */
-BOOL32 GetWindowPlacement32( HWND32 hwnd, WINDOWPLACEMENT32 *wndpl )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
-
-    wndpl->length  = sizeof(*wndpl);
-    wndpl->flags   = 0;
-    wndpl->showCmd = IsZoomed32(hwnd) ? SW_SHOWMAXIMIZED : 
-	             (IsIconic32(hwnd) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL);
-    CONV_POINT16TO32( &wndPtr->ptIconPos, &wndpl->ptMinPosition );
-    CONV_POINT16TO32( &wndPtr->ptMaxPos, &wndpl->ptMaxPosition );
-    CONV_RECT16TO32( &wndPtr->rectNormal, &wndpl->rcNormalPosition );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetWindowPlacement16   (USER.371)
- */
-BOOL16 SetWindowPlacement16( HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
-
-    if (wndpl->flags & WPF_SETMINPOSITION)
-	wndPtr->ptIconPos = wndpl->ptMinPosition;
-    if ((wndpl->flags & WPF_RESTORETOMAXIMIZED) &&
-	(wndpl->showCmd == SW_SHOWMINIMIZED)) wndPtr->flags |= WIN_RESTORE_MAX;
-    wndPtr->ptMaxPos   = wndpl->ptMaxPosition;
-    wndPtr->rectNormal = wndpl->rcNormalPosition;
-    ShowWindow16( hwnd, wndpl->showCmd );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetWindowPlacement32   (USER32.518)
- */
-BOOL32 SetWindowPlacement32( HWND32 hwnd, const WINDOWPLACEMENT32 *wndpl )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
-
-    if (wndpl->flags & WPF_SETMINPOSITION)
-	CONV_POINT32TO16( &wndpl->ptMinPosition, &wndPtr->ptIconPos );
-    if ((wndpl->flags & WPF_RESTORETOMAXIMIZED) &&
-	(wndpl->showCmd == SW_SHOWMINIMIZED)) wndPtr->flags |= WIN_RESTORE_MAX;
-    CONV_POINT32TO16( &wndpl->ptMaxPosition, &wndPtr->ptMaxPos );
-    CONV_RECT32TO16( &wndpl->rcNormalPosition, &wndPtr->rectNormal );
-    ShowWindow32( hwnd, wndpl->showCmd );
-    return TRUE;
+	if( pt )
+	{
+            flags |= PLACE_MIN;
+            wndpl.flags |= WPF_SETMINPOSITION;
+            CONV_POINT32TO16( pt, &wndpl.ptMinPosition );
+	}
+	if( rect )
+	{
+            flags |= PLACE_RECT;
+            CONV_RECT32TO16( rect, &wndpl.rcNormalPosition );
+	}
+        WINPOS_SetPlacement( hwnd, &wndpl, flags );
+    }
 }
 
 
@@ -1000,22 +1273,22 @@
  */
 BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
 {
-    WND                   *wndPtr          = WIN_FindWndPtr(hWnd);
-    WND                   *wndTemp         = WIN_FindWndPtr(hwndActive);
-    CBTACTIVATESTRUCT16   *cbtStruct;
-    WORD                   wIconized=0;
-    HQUEUE16 hOldActiveQueue = (pActiveQueue)?pActiveQueue->self:0;
-    HQUEUE16 hNewActiveQueue;
+    CBTACTIVATESTRUCT16* cbtStruct;
+    WND*     wndPtr, *wndTemp;
+    HQUEUE16 hOldActiveQueue, hNewActiveQueue;
+    WORD     wIconized = 0;
 
     /* paranoid checks */
-    if( hWnd == GetDesktopWindow32() || hWnd == hwndActive )
-	return 0;
+    if( hWnd == GetDesktopWindow32() || hWnd == hwndActive ) return 0;
 
 /* if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
 	return 0;
         */
 
-    if( wndTemp )
+    wndPtr = WIN_FindWndPtr(hWnd);
+    hOldActiveQueue = (pActiveQueue)?pActiveQueue->self : 0;
+
+    if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
 	wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
     else
 	dprintf_win(stddeb,"WINPOS_ActivateWindow: no current active window.\n");
@@ -1063,15 +1336,8 @@
     if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
 	SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM16)hWnd, 0L );
 
-    /* if prev wnd is minimized redraw icon title 
-  if( hwndPrevActive )
-    {
-        wndTemp = WIN_FindWndPtr( WIN_GetTopParent( hwndPrevActive ) );
-        if(wndTemp)
-          if(wndTemp->dwStyle & WS_MINIMIZE)
-            RedrawIconTitle(hwndPrevActive); 
-      } 
-  */
+    /* if prev wnd is minimized redraw icon title */
+    if( IsIconic32( hwndPrevActive ) ) WINPOS_RedrawIconTitle(hwndPrevActive);
 
     /* managed windows will get ConfigureNotify event */  
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
@@ -1093,7 +1359,7 @@
     {
         WND **list, **ppWnd;
 
-        if ((list = WIN_BuildWinArray( WIN_GetDesktop() )))
+        if ((list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
         {
             for (ppWnd = list; *ppWnd; ppWnd++)
             {
@@ -1109,7 +1375,7 @@
 	pActiveQueue = (hNewActiveQueue)
 		       ? (MESSAGEQUEUE*) GlobalLock16(hNewActiveQueue) : NULL;
 
-        if ((list = WIN_BuildWinArray( WIN_GetDesktop() )))
+        if ((list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
         {
             for (ppWnd = list; *ppWnd; ppWnd++)
             {
@@ -1156,14 +1422,9 @@
 	 wndPtr->window && !(wndPtr->flags & WIN_MANAGED) )
 	WINPOS_ForceXWindowRaise(wndPtr);
 
-    /* if active wnd is minimized redraw icon title 
-  if( hwndActive )
-      {
-        wndPtr = WIN_FindWndPtr(hwndActive);
-        if(wndPtr->dwStyle & WS_MINIMIZE)
-           RedrawIconTitle(hwndActive);
-    }
-  */
+    /* if active wnd is minimized redraw icon title */
+    if( IsIconic32(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
+
     return (hWnd == hwndActive);
 }
 
@@ -1185,14 +1446,14 @@
       return 0;
 
   if( pWnd->dwStyle & WS_POPUP &&
-      WINPOS_IsGoodEnough( pWnd->owner ) ) pWndTo = pWnd->owner;
+      WINPOS_CanActivate( pWnd->owner ) ) pWndTo = pWnd->owner;
   else
   {
     WND* pWndPtr = pWnd;
 
     pWndTo = WIN_FindWndPtr(hwndPrevActive);
 
-    while( !WINPOS_IsGoodEnough(pWndTo) ) 
+    while( !WINPOS_CanActivate(pWndTo) ) 
     {
       /* by now owned windows should've been taken care of */
 
@@ -1296,7 +1557,7 @@
     if ((wndPtr->dwStyle & WS_THICKFRAME) ||
 	((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
     {
-	NC_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
+	WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
 	winpos->cx = MIN( winpos->cx, maxSize.x );
 	winpos->cy = MIN( winpos->cy, maxSize.y );
     }
@@ -1316,7 +1577,7 @@
     if ((wndPtr->dwStyle & WS_THICKFRAME) ||
 	((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
     {
-	NC_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
+	WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
 	winpos->cx = MIN( winpos->cx, maxSize.x );
 	winpos->cy = MIN( winpos->cy, maxSize.y );
     }
@@ -1459,6 +1720,9 @@
  * visible regions are in window coordinates
  * update regions are in window client coordinates
  * client and window rectangles are in parent client coordinates
+ *
+ * FIXME: Move visible and update regions to the same coordinate system
+ *	 (either parent client or window). This is a lot of work though.
  */
 static UINT32 WINPOS_SizeMoveClean(WND* Wnd, HRGN32 oldVisRgn, LPRECT16 lpOldWndRect, LPRECT16 lpOldClientRect, UINT32 uFlags )
 {
@@ -2030,7 +2294,8 @@
 
     if (wndPtr->window) EVENT_Synchronize();  /* Wait for all expose events */
 
-    EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
+    if (!GetCapture32())
+        EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
 
     if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
     {
diff --git a/wine.ini b/wine.ini
index b121e27..1eff793 100644
--- a/wine.ini
+++ b/wine.ini
@@ -31,6 +31,12 @@
 Type=hd
 Label=Tmp Drive
 
+[Drive F]
+Path=${HOME}
+Type=network
+Label=Home
+Filesystem=unix
+
 [wine]
 Windows=c:\windows
 System=c:\windows\system
@@ -42,17 +48,11 @@
 AllocSystemColors=100
 
 [fonts]
-system=*-helvetica
-mssansserif=*-helvetica
-msserif=*-times
-courier new=adobe-courier
-times new roman=adobe-times
-symbol=adobe-symbol
-fixedsys=*-fixed
-arial=*-helvetica
-helv=*-helvetica
-roman=*-times
-default=*-*
+; see documentation/fonts
+;Alias0 = System, --international-
+;Alias1 = MS Sans Serif, -adobe-helvetica-
+;Alias2 = Arial, -adobe-helvetica-, subst
+;Alias3 = Times New Roman, -adobe-times-, subst
 
 [serialports]
 Com1=/dev/cua0
@@ -63,5 +63,14 @@
 [parallelports]
 Lpt1=/dev/lp0
 
+[spooler]
+LPT1:=|lpr
+LPT2:=|gs -sDEVICE=bj200 -sOutputFile=/tmp/fred -q -
+LPT3:=/dev/lp3
+
+[ports]
+;read=0x779,0x379,0x280-0x2a0
+;write=0x779,0x379,0x280-0x2a0
+
 [spy]
 Exclude=WM_SIZE;WM_TIMER;