diff --git a/ANNOUNCE b/ANNOUNCE
index 0ede2e6db8cb8e279872f890a81f04ba71fad215..20b0e35f0131ad511ef1a97e391e3152568aa6f8 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 @@ Because of lags created by using mirror, this message may reach you before
 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 1252d8a8659a0c68bee3673088ed77a1f85385ae..f706ac64987706db48af10dfa52eb10180fc37b6 100644
--- a/BUGS
+++ b/BUGS
@@ -5,12 +5,11 @@ done something for one of the problems. You are encouraged to
 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 @@ General:
 	  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 ebe3a6efe7325605ef4c5f797049e3af0607830f..f8b8b962a0a83b84a3b857d6bda9976ce23ba3be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,170 @@
+----------------------------------------------------------------------
+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>
 
diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS
index f376a22d92afdd2d27cff660a51eb0771b4b5cec..14b47e13d9766080d893169bb52b0d7a45b7a073 100644
--- a/DEVELOPERS-HINTS
+++ b/DEVELOPERS-HINTS
@@ -239,3 +239,13 @@ not yet implemented functions.
 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 5dd7ba7a892676e08053c94ce34def4c2d89c94e..17bb9ec7af45858518fd9143c824608d5cba214e 100644
--- a/README
+++ b/README
@@ -74,6 +74,9 @@ Note: the path of the file will also be added to the path when
 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 09188b5f1bab0a1746679c400d9b4003477f5a6e..3379b18ea9027114ab2a27f75e4bde49b71d90e8 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -10,6 +10,7 @@ C_SRCS = \
 	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 cd1a6b5eb1f948821f4ceac0c66b851b36dd4440..3771933c39a11983903d9363f6d645d71501f09b 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -152,7 +152,8 @@ static void CBCalcPlacement( LPHEADCOMBO lphc,
 
        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 0000000000000000000000000000000000000000..18640861e9ba7f93d2c7db0b64857d7d908d46b8
--- /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 48b181f393363a07402cce23184e78d9eec12034..516fb24ab5827de75115af1630ed3ca4645a9573 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1731,12 +1731,9 @@ static LRESULT LISTBOX_HandleLButtonUp( WND *wnd, LB_DESCR *descr )
     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 729bd6dca20c447a805720c12cbf26a12dc5a2d1..7efc7650302efb1ed963d47b9ce66fd9a1984612 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -30,6 +30,8 @@ extern LRESULT ListBoxWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                                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 @@ static WNDCLASS32A WIDGETS_BuiltinClasses32[BIC32_NB_CLASSES] =
       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 b913c7050379df05f4e2a5e0f3f2af9fcbafbd49..cc6d35dcaa451fae0aba10f2d8effbf61c9e49d6 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -546,6 +546,17 @@ static void DEBUG_Main( int signal )
 }
 
 
+/***********************************************************************
+ *           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)
  */
diff --git a/debugger/dbgmain.c b/debugger/dbgmain.c
index 7c1992b65e6bad9f2a8b722e9a1c29c4ea1706c0..04cf7acc1f1fbbbcaf38b89895e239dcc325ca86 100644
--- a/debugger/dbgmain.c
+++ b/debugger/dbgmain.c
@@ -170,7 +170,7 @@ struct deferred_debug_info
 	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 @@ struct CodeViewDebug
 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 @@ test_pdbstuff()
   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 366887765018098658b8523e8859b06a2d698bc0..61bab5a6a9779c92f402aad9c35cd17a8acad505 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -2135,7 +2135,7 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename)
   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 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename)
 
   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 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename)
 
   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 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename)
 		   * 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 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename)
 		   * 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 0000000000000000000000000000000000000000..323761311231472decba51391694b7de6212429b
--- /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 8cff4cb37e95510f3601211204e9467f25f40739..9308036c00512311f0aed54a9151de41913a7f05 100644
--- a/documentation/user_module
+++ b/documentation/internals
@@ -1,3 +1,13 @@
+KERNEL MODULE
+=============
+
+...
+
+GDI MODULE
+==========
+
+...
+
 USER MODULE
 ===========
 
@@ -20,11 +30,11 @@ located in windows/, controls/, and misc/ directories.
    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 @@ located in windows/, controls/, and misc/ directories.
    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 @@ located in windows/, controls/, and misc/ directories.
 
    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 @@ located in windows/, controls/, and misc/ directories.
        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 38a84c8da1c6960dca755cffe076969c3e467cf3..5bb8b3547e4851aaf3368faa01df68ed14c3ae7a 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -809,6 +809,8 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result,
 
     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 1ff6c2167b9e97f52cbc41fc56d41eed79b8fa53..1625f399ff0556574216b8e0960665c3d934e35b 100644
--- a/files/file.c
+++ b/files/file.c
@@ -129,8 +129,10 @@ int FILE_GetUnixHandle( HFILE32 hFile )
  */
 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 @@ void FILE_SetDosError(void)
         DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort, EL_Unknown );
         break;
     }
+    errno = save_errno;
 }
 
 
@@ -239,6 +242,9 @@ HFILE32 FILE_Open( LPCSTR path, INT32 mode )
     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 @@ static HFILE32 FILE_Create( LPCSTR path, int mode, int unique )
 
     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 @@ BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info )
 {
     struct stat st;
 
+    if (!unixName || !info) return FALSE;
+
     if (stat( unixName, &st ) == -1)
     {
         FILE_SetDosError();
@@ -358,6 +368,8 @@ DWORD GetFileInformationByHandle( HFILE32 hFile,
     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 @@ DWORD GetFileAttributes32A( LPCSTR name )
     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 @@ BOOL32 GetFileTime( HFILE32 hFile, FILETIME *lpCreationTime,
  */
 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 @@ UINT32 GetTempFileName32A( LPCSTR path, LPCSTR prefix, UINT32 unique,
     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 @@ static HFILE32 FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode,
     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 06b8b70783ecbf48b8f51a59c9244a69d9ecec12..d537a8ebb8e0b16932dc383c13425e37e4d1f1d3 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -116,7 +116,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section )
 
     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 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
         }
         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 @@ int PROFILE_LoadWineIni(void)
 }
 
 
+/***********************************************************************
+ *           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 ce6a39575251d1ecae2eb65810005166b2260ee8..bad5182a6f78b8556df8a6c98e4e0288a05c66b9 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -478,7 +478,7 @@ void DrawFocusRect16( HDC16 hdc, const RECT16* rc )
 /***********************************************************************
  *           DrawFocusRect32    (USER32.155)
  *
- * FIXME: should use Rectangle32!
+ * FIXME: PatBlt(PATINVERT) with background brush.
  */
 void DrawFocusRect32( HDC32 hdc, const RECT32* rc )
 {
@@ -747,10 +747,10 @@ BOOL32 DrawEdge32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
 /**********************************************************************
  *          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 @@ BOOL16 DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
 /**********************************************************************
  *          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 db761f1d1c32df0d8daf5341fd17bf3a80932b51..85edff40fad342d33ced7b2a23c8772b58a7b19f 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -19,11 +19,6 @@ BOOL32 WIN16DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
 {
     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 @@ BOOL32 WIN16DRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
 
     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 da9e60b8940a1a3e048abc2f8d18a564a1062c46..ff4805986ab00ab64d3804570b9e7458704974eb 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 @@ BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
     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 @@ BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
 	   &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 @@ BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
 
 #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 @@ static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput,
     {
 	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 @@ static PPRINTJOB FindPrintJobFromHandle(HANDLE16 hHandle)
 /* 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
+    {
+        while (*psCmdP && isspace(*psCmdP))
+        {
+            psCmdP++;
+        };
+        if (!*psCmdP)
+            return -1;
+    }
+    if (*psCmdP == '|')
     {
-	printf("Failed to create spool file %s, errno = %d\n", szSpoolFile, errno);
+        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 28647420f9f5a7485795278e58ad7fd0666b57e6..672dc89e948712f6c867ab7a79bbff4dad92460f 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -433,8 +433,8 @@ BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
  * 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 @@ DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
 	
 	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_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
 
 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 @@ DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
 	
 	/* 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 @@ DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
                                            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 903d6c85b1a258c15452e61bdb25dfc49eebbc92..6d1876ebd4996970d24e5d7d37181f2d52f63d09 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -22,14 +22,9 @@ BOOL32 WIN16DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
 {
     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 @@ BOOL32 WIN16DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
     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 @@ BOOL32 WIN16DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
 
 	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 @@ BOOL32 WIN16DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
         }
         
     }
-        
+#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 daa860c0168892e2a4fbd1a2a3a9c23af2727784..d7fc1fd6271c41c47d67e78024fad709a2becdde 100644
--- a/graphics/x11drv/Makefile.in
+++ b/graphics/x11drv/Makefile.in
@@ -10,7 +10,7 @@ C_SRCS = \
 	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 7826db64c93e1abc26f1b9dd9a20c076287eb794..0000000000000000000000000000000000000000
--- 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 bceeb1088a7969080dcebbc457ef136158802a4d..0d7496f6fae8c44f761de819d2e3910bd94ab47a 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 @@ static const DC_FUNCTIONS X11DRV_Funcs =
     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 @@ static const DC_FUNCTIONS X11DRV_Funcs =
     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 @@ BOOL32 X11DRV_Init(void)
 
     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 @@ static BOOL32 X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
 {
     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 @@ static BOOL32 X11DRV_DeleteDC( DC *dc )
     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 561cb5ebbe0b5a493918a6fe5f3ef503983056e9..cc7249d2b3fb77cb612bf76749fb3f068b93e86c 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 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
                    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 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
 	/* 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 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
                 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 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
 
       /* 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 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
 		   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 0000000000000000000000000000000000000000..60aa82fe959ae52d33257474155121a7bf9895a0
--- /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 fb584e4dde4e80761b4eb43973a4e986d2bb0af0..4a88641e02b8a3d03b560f1a023205eb1a3b3b40 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 @@ base	1
 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 @@ base	1
 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 @@ base	1
 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 @@ base	1
 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 44b86eee1f05d26af4e848ced0f904379f213bd9..288e3633010418f72aa939dedcb1229bcde35b2a 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -148,9 +148,9 @@ static BUILTIN_DLL BuiltinDLLs[] =
     /* 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 90b502c5380b58a744613abea6db74c7bc3583e9..7e6131e6e6603c09b27e628e31f5933242a26ab7 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -144,7 +144,7 @@ base	1
 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 3721737a9efb4eef27c081b6e4b781fdd71bf2f2..af3761c89177fe1d44e7a8f89fec9b95ec28f5be 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -225,7 +225,7 @@ type	win16
 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 @@ type	win16
 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 @@ type	win16
 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 23d4f31eb44272cc22ab574816e7534057d5158d..a08067005ef740638524c00f99dea5f0bcba9f54 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -2,687 +2,841 @@ name	kernel32
 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 15a75a033842d88a12dc2ad8203e55a5aa738266..3acba591a35958fae0024060acda4bbbb3b5dac1 100644
--- a/if1632/mpr.spec
+++ b/if1632/mpr.spec
@@ -3,7 +3,7 @@ type win32
 
 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 42d9ef2bc0d550886862e762a3751389d4e9be28..eeee134888bc21d7144b588c7b27ca09816f5aba 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -886,7 +886,7 @@ base	0
 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 8e8a15f81f26a2b37f83131ccea5afa234c9aa23..7f478f1bd7aa8182f7b811219378d3f8545fb44d 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 @@ INT16 Throw( LPCATCHBUF lpbuf, INT16 retval )
     }
     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 3961ed710d3484bd035bbee4eb83694900bee032..37ce932b218d298a17f7d24826b212cbdb6f0f2c 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -51,7 +51,7 @@ type	win16
              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 c7597e291d812852188d67073f2bd7625fd15139..798e01c787b29cfd369b8d3f895e93c041a1e8e3 100644
--- a/if1632/wsock32.spec
+++ b/if1632/wsock32.spec
@@ -41,7 +41,7 @@ base	0
 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 94be6f31f0675d00c970939b2aa2770d7595532c..985c877a35fc96384a64bf170766cf6d3e7690f4 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 528fd66f44d2ea6b026d836a006a52e098962184..cae411c2ecfadaf66f95986f4d69976f57689bf3 100644
--- a/include/font.h
+++ b/include/font.h
@@ -21,15 +21,9 @@ typedef struct
 #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 5b3dcb3048898a8b2c89d8e77267bd7ce1abcdc3..42d66cb0cff732e58a4a075d9641adb9f7a912ce 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -34,7 +34,7 @@ typedef struct tagGDIOBJHDR
 } GDIOBJHDR;
 
 
-typedef struct
+typedef struct tagDeviceCaps
 {
     WORD   version;       /*   0: driver version */
     WORD   technology;    /*   2: device technology */
@@ -153,7 +153,7 @@ typedef struct tagDC_FUNCS
     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 4915730eee36586d76f828c0f702d165d3c8db1e..812580c090a3d662393e30d97e2fb1adc7fd7d40 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 532681ff685ef93518491327d93db05583553796..dba7cffe132f3b53ce09c94f3dfa8548b54f342a 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -32,6 +32,7 @@ extern FARPROC16 INT_GetHandler( BYTE intnum );
 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 cc138fe360822c496750d8ee59dd65935daaa5f0..29cb8ea75827d8e8973854c3cd5ec759d6ef1d69 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -186,9 +186,9 @@ typedef struct {
     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 @@ typedef struct {
     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 @@ typedef struct {
     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 @@ typedef struct {
     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 @@ typedef struct {
 #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 @@ typedef struct {
 #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 e425573d872e4a7e6dc53af896c9470bf837fa4e..757b46f3fda538d6d0e45ad4bcd004c1f4c7237d 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 */
-};
-
-#define MZ_SIGNATURE  ('M' | ('Z' << 8))
+	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	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 @@ struct ne_header_s
     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 64b8da16b96467705fa66e7cb38f6b7694aa3058..63fe119e314da810e11ee4f34b2ffdd2b6134331 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 36bfb5c09845886e132aa4d9b8db064766e5ef79..21f9d7a82db371dad7cdcfc3a9350ded5dfb8e49 100644
--- a/include/options.h
+++ b/include/options.h
@@ -72,5 +72,6 @@ extern int PROFILE_GetWineIniString( const char *section, const char *key_name,
                                      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 7729f939696b2149d87b4ae1b9945e13ecaa61d3..c913fd13bbe351fad76f245d4d947904e0263c97 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 @@ typedef struct
     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 d60affc973e6a6d6cbe30bd1f2309a6874482c6d..c716f6121228e1e7a3d17ea4e08b87fce143cdef 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 @@ typedef struct _IMAGE_BASE_RELOCATION
 	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 @@ typedef struct _IMAGE_TLS_DIRECTORY {
  * 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 80fe77d59fb5137552af92d96a26ae06a33b7496..de88be1794fb88f2ab5ed884e444b6876c80f781 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -95,6 +95,5 @@ extern int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND32 hwnd,
 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 4d5de2fc27c8c388bcffafd44541ff6c15978687..371d05fbcc850be33a5b4eaac3c681a37e4d673e 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 fbf21a8b5293f8943b383d068945ad62ab893d9c..eaf30eca85a0fc07e92b9e300ec24ff229f6479f 100644
--- a/include/toolhelp.h
+++ b/include/toolhelp.h
@@ -274,7 +274,7 @@ BOOL16 NotifyRegister(HTASK16 htask,FARPROC16 lpfnCallback,WORD wFlags);
 #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 @@ struct {
 
 /* called when loading/starting a DLL */
 #define NFY_STARTDLL	3
-struct {
+typedef struct {
     DWORD      dwSize;
     HMODULE16  hModule;
     WORD       wCS;
@@ -304,7 +304,7 @@ struct {
 
 /* RIP? debugevent */
 #define NFY_RIP		7
-struct {
+typedef struct {
 	DWORD	dwSize;
 	WORD	wIP;
 	WORD	wCS;
@@ -331,7 +331,7 @@ struct {
 
 /* log errors */
 #define NFY_LOGERROR	12
-struct {
+typedef struct {
 	DWORD	dwSize;
 	UINT16	wErrCode;
 	VOID   *lpInfo; /* depends on wErrCode */
@@ -339,7 +339,7 @@ struct {
 
 /* 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 d6269672064808f749f1f34cdb5dc95ac29b42d6..05342f26c362542dd680af081e7806006c171430 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 aabfe63645d23541f93729e68094282d76a84be2..ed9e1bc2bf3d82f2ffe9f74c6cd72a03d60642b0 100644
--- a/include/win.h
+++ b/include/win.h
@@ -40,6 +40,7 @@ typedef enum
     BIC32_SCROLL,
     BIC32_DESKTOP,
     BIC32_DIALOG,
+    BIC32_ICONTITLE,
     BIC32_NB_CLASSES
 } BUILTIN_CLASS32;
 
@@ -62,9 +63,6 @@ typedef struct tagWND
     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 @@ typedef struct tagWND
     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 @@ typedef struct tagWND
 #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 04df416cec3c3a709bcbf2b68aa67fc9c743a6cc..f7d144c8e0de33030e2ddc9ef5ebff8e3b7c573a 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -165,13 +165,13 @@ extern WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
 		       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 @@ extern HGDIOBJ32 WIN16DRV_SelectObject( DC *dc, HGDIOBJ32 handle );
 
 
 
+/*
+ * 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 dbfb29e7109a0bc6fdbc3bb087a1848f5df9e323..dc3a49457b4b8ee45f256b446886dda887ea219f 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -235,9 +235,11 @@ typedef struct
 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 @@ DECL_WINELIB_TYPE(LPLOGBRUSH);
 #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 @@ typedef struct
 #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 (*FONTENUMPROCEX32A)(LPENUMLOGFONTEX32A,LPNEWTEXTMETRICEX32A,UINT3
 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 @@ typedef struct tagCOMSTAT
 #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 @@ typedef struct
 #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 INT16 (*MFENUMPROC16)(HDC16,HANDLETABLE16*,METARECORD*,INT16,LPARAM);
 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 @@ typedef struct
 #define DBF_APPLICATION     0x0008
 #define DBF_DRIVER          0x0010
 
+#endif /* NOLOGERROR */
+
 /* Win32-specific structures */
 
 typedef struct {
@@ -4532,6 +4685,8 @@ typedef struct _ULARGE_INTEGER
     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 @@ typedef struct
 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     IsSharedSelector(HANDLE16);
 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 be21ee2600fc6df407f7e2146eedaf5d2553d241..44f9e8879040d710d439e74b82e1f6273799a0cd 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -25,7 +25,11 @@ typedef struct
     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 26336c92fca277bd4c223de09873a27935603781..da3588f857f62669889b11b740a9d945ad8c232a 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -30,11 +30,7 @@ typedef struct
 } 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 @@ typedef struct
     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_GetTextExtentPoint( struct tagDC *dc, LPCSTR str,
 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_ExtTextOut( struct tagDC *dc, INT32 x, INT32 y,
 
 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 0000000000000000000000000000000000000000..c87064ec7e18657fd5d3a0ae799ac8e75fea5570
--- /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 934ac2befe631649fe4e0392efcef49308d8d3ca..5245618114005c6f89591651d54af666e09077ff 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 8fd8b5d25440b4d32284d25279b16737d103696e..24b98a39c5dd35429c612f6a7717e08c537b601c 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -110,6 +110,9 @@ int MAIN_Init(void)
       /* 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 19bb6d0cf4a68883d477cf7ce71ff0e79d4244c6..8a54aa2be236d6c93d090d7ad0e4b9aa39fbeeb1 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -38,7 +38,7 @@ static HMODULE16 hCachedModule = 0;  /* Module cached by MODULE_OpenFile */
 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 @@ NE_MODULE *MODULE_GetPtr( HMODULE16 hModule )
 /***********************************************************************
  *           MODULE_DumpModule
  */
-void MODULE_DumpModule( HMODULE16 hmodule )
+void MODULE_DumpModule( HMODULE16 hModule )
 {
     int i, ordinal;
     SEGTABLEENTRY *pSeg;
@@ -55,15 +55,15 @@ void MODULE_DumpModule( HMODULE16 hmodule )
     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 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
     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 @@ HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
     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 @@ HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
     /* 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 @@ HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
  */
 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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
 
     _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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
         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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
     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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
     /* 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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
     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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
     /* 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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
     /* 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 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
  */
 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 @@ HINSTANCE32 WinExec32( LPCSTR lpCmdLine, UINT32 nCmdShow )
     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 d5f1e8005d205bef7a3c4c5913cbd0677d75cdc4..1937fdde2145dc355de76058ce61683e6a550981 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -270,7 +270,7 @@ BOOL32 NE_LoadSegment( HMODULE16 hModule, WORD segnum )
 	    
 	  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 @@ BOOL32 NE_LoadSegment( HMODULE16 hModule, WORD segnum )
 
         /* 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 @@ BOOL32 NE_LoadSegment( HMODULE16 hModule, WORD segnum )
 	    
 	  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 1e74f48afc8afc0fb84022e2d1a8e1bc260ffd9d..0616e6f28bb8bbac5c664bcf3ca6bfd2922bd7fe 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -40,7 +40,7 @@ static void PE_InitDLL(HMODULE16 hModule, DWORD type, LPVOID lpReserved);
 
 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 @@ void dump_exports(IMAGE_EXPORT_DIRECTORY * pe_exports, unsigned int load_addr)
 	  daddr.off=RVA(*functions);
 	  function++;
       }
-      while ((s=strchr(buffer,'.'))) *s='_';
       DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
   }
 }
@@ -360,7 +359,7 @@ static void do_relocations(struct pe_data *pe)
  *			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 @@ static struct pe_data *PE_LoadImage( int fd, HMODULE16 hModule, WORD offset )
 	IMAGE_DATA_DIRECTORY	dir;
 	char			buffer[200];
 	DBG_ADDR		daddr;
+	char			*modname;
 
 	daddr.seg=0;
 	daddr.type = NULL;
@@ -379,6 +379,30 @@ static struct pe_data *PE_LoadImage( int fd, HMODULE16 hModule, WORD offset )
 	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 @@ problem needs to be fixed properly at some stage */
 		dprintf_win32(stdnimp,"Unknown directory 15 ignored\n");
 
 	if(pe->pe_reloc) do_relocations(pe);
-	if(pe->pe_import) fixup_imports(pe, hModule);
+
+	/* 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) {
-		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='_';
+	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';
+	}
+
+	/* 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 start of DLL */
-		daddr.off=load_addr;
-		DEBUG_AddSymbol((char*) RVA(pe->pe_export->Name),&daddr,
-				NULL, SYM_WIN32 | SYM_FUNC);
 	}
-        return pe;
+	/* 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 @@ HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LOADPARAMS* params )
     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 @@ HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LOADPARAMS* params )
     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 8ada240edd304652ca9a5dfa848d0e0a8a1c6aa0..899e5775490f3983f39b68872b7c50354a02bea6 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 FARPROC16 TASK_RescheduleProc;
 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 @@ HMODULE16 GetExePtr( HANDLE16 handle )
       /* 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 2e3a6c016d266141749a8cce285b7b5770ab32df..2aa42bad53c0ee49958a63d0e09a92fb46a5ae7c 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 @@ BOOL32 VIRTUAL_Init(void)
 
 #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 @@ BOOL32 VIRTUAL_Init(void)
                 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 1d16edbb7eba46b5c81dcd5f8053139f0a9a7104..08b87e120ee2cc2a7c86d0fbdf894af64977c826 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -11,6 +11,7 @@ C_SRCS = \
 	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 adf21972055a32e49943e509a82eae505c42adef..9572070141d093bbbc73fed49afc85c16bf49447 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 OpenComm(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
  */
 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 FlushComm(INT16 fd,INT16 fnQueue)
  */
 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	*SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
  */
 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 0000000000000000000000000000000000000000..f4f2837c83b21499d459cf35dc33b3dc4ab0f625
--- /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 7f565caf8f9b546ab1a99105741402cb16bf38dd..7228e67deb71a23a984f89c97e593a385cf47f5d 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -534,10 +534,11 @@ FormatMessage32A(
 		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 @@ FormatMessage32A(
 						}
 					} 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.
-						 */
-						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);
+					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++);
+						/* 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)
+						 */
+						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 48d67e469edf90835e87ccb8c29de589b0f5a172..384096e2c516925ecb041eb61a0fecbdf8544cfb 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -204,7 +204,7 @@ void LZDone(void)
  */
 INT16 GetExpandedName16( LPCSTR in, LPSTR out )
 {
-    return GetExpandedName32A( in, out );
+    return (INT16)GetExpandedName32A( in, out );
 }
 
 
@@ -230,17 +230,16 @@ INT32 GetExpandedName32A( LPCSTR in, LPSTR out )
 	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 57832ad3ac4a7852b53e071fcc546924c3de148b..84ab9cfec8fa905359e0b99b6329d9ed3275a263 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -817,6 +817,8 @@ DWORD GetWinFlags(void)
     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 @@ BOOL16 SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
 
 	        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 62f9f857952fbc79f4706e34a7a094562655b989..6c7b674f8001204951b2202fcc01ff940f32ff3e 100644
--- a/misc/mpr.c
+++ b/misc/mpr.c
@@ -21,3 +21,15 @@ WNetGetCachedPassword(
 	);
 	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 64e44f9abe058a400a0106ad849b15abc816d083..9583c3843ce389e9f004eb716ac42f1d1a2359a1 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -40,7 +40,7 @@ DWORD
 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 @@ DWORD
 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 f67ca32aae860a99f84e54144a2bf74b659c40e2..041fc8bef511767a4c1321e986aa825bdc913abf 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -476,23 +476,23 @@ BOOL32 ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
 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 @@ static BYTE* SHELL_GetResourceTable(HFILE32 hFile)
       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 3216f4a855bdb4658008f377aa77fe0382e795d9..65490b9778f6526cfcaffc22d167d36f54536f40 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -508,15 +508,41 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] =
           NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
     "WM_COALESCE_LAST", 
-
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    
+    /* 0x03a0 */
+    "MM_JOY1MOVE", 
+    "MM_JOY2MOVE", 
+    "MM_JOY1ZMOVE", 
+    "MM_JOY2ZMOVE", 
+                            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 @@ void SPY_ExitMessage( INT32 iFlag, HWND32 hWnd, UINT32 msg, LRESULT lReturn )
 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 bd3d0b2b7f07afcbccd70d9855cfab05488530d2..70690b8125a65d79a5061582174684255bc28389 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 @@ read_ne_header(HFILE32 lzfd,struct ne_header_s *nehd) {
 
 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 @@ find_ne_resource(
 /* 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 @@ DWORD
 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 @@ DWORD GetFileVersionInfo32W( LPCWSTR filename, DWORD handle, DWORD datasize,
     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 926c51491f2ca91928848c1951a79c38732d1610..7f4c314f39fb8c8c31e6d9f2c49b1e052f3d31f5 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 WSASetBlockingHook16(FARPROC16 lpBlockFunc)
   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 @@ FARPROC16 WSASetBlockingHook16(FARPROC16 lpBlockFunc)
 
 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 @@ INT16 WSAUnhookBlockingHook(void)
   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 7e41ce82169120d9abfa75769dcd15bc93c1b573..e33487af70264eb58dca2805c2de6268ecb4d0a6 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 @@ static BYTE cmosimage[64] =
   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 @@ static BYTE cmosimage[64] =
 DWORD IO_inport( int port, int count )
 {
     DWORD res = 0;
-    BYTE b;
+    BYTE b;    
+
+#ifdef linux    
+    if (do_direct_port_access) iopl(3);
+#endif
 
-    dprintf_int(stddeb, "IO: %d bytes from port 0x%02x\n", count, port );
+    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 @@ void IO_outport( int port, int count, DWORD value )
     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 31af3189617be851f54aa9e89ff03cd9c67eccce..517325f699b5c63176eb1f9fb8e0581dbaca91fc 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -87,15 +87,39 @@ static DWORD WAVE_NotifyClient(UINT16 wDevID, WORD wMsg,
 {
 	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;
-
-	if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
+	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;
+
+	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 @@ static DWORD WAVE_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lp
 		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 @@ static DWORD WAVE_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lp
 	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 @@ static DWORD WAVE_mciCue(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpPar
    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_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpP
 */
 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_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
 */
 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 @@ static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
 	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 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 	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 wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 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 @@ static DWORD wodClose(WORD wDevID)
 /**************************************************************************
 * 				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 @@ static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 	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 @@ static DWORD wodRestart(WORD wDevID)
 	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 @@ DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
 		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 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 	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 widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 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 @@ static DWORD widStart(WORD wDevID)
 		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 @@ static DWORD widStart(WORD wDevID)
 		count++;
 		}
 	dprintf_mciwave(stddeb,"widStart // end of recording !\n");
-	fflush(stdout);
+	fflush(stddeb);
 	return MMSYSERR_NOERROR;
 }
 
@@ -1658,6 +1712,8 @@ DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
 			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 @@ LONG WAVE_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
 			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 429f2b23658345fa59987913fb94374ab15ec0ac..be6c70678b72a2241f4019f247823a116c4ee7eb 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -350,13 +350,13 @@ MCISTR_Open(_MCISTR_PROTO_) {
 	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 @@ struct	_MCISTR_cmdtable {
 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 @@ DWORD mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString,
 	}
 	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 a4446e34136fd7aa312bd49f2b333c6cfd6c8a6d..4706a454549f48152294fce4e9bd3887540e1453 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 10d780dfd4a240a6b613ba78c45d7173d1454ef7..e8d094ab736d4ca5c0f2b789d7af7f63e8eec937 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 @@ LRESULT DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
 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 @@ BOOL16 DriverCallback(DWORD dwCallBack, UINT16 uFlags, HANDLE16 hDev,
 			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 @@ DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS lpParms)
 
 /**************************************************************************
 * 				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 @@ DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
 		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 waveOutGetNumDevs()
 */
 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 @@ UINT16 waveOutOpen(HWAVEOUT16 * lphWaveOut, UINT16 uDeviceID,
 	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 @@ UINT16 waveOutGetID(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID)
 	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 @@ UINT16 waveInOpen(HWAVEIN16 * lphWaveIn, UINT16 uDeviceID,
 		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 mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo, DWORD dwOpenFlags)
 	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 @@ HMMIO16 mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo, DWORD dwOpenFlags)
 	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 @@ HMMIO16 mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo, DWORD dwOpenFlags)
 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 mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch)
 {
 	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 @@ LONG mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
 {
 	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 @@ LONG mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
 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 mmioGetInfo(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags)
 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 mmioSetInfo(HMMIO16 hmmio, const MMIOINFO * lpmmioinfo, UINT16 uFlags)
 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 mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer,
 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 @@ UINT16 mmioAdvance(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags)
 {
 	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 @@ UINT16 mmioAdvance(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT16 uFlags)
 */
 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 @@ FOURCC mmioStringToFOURCC(LPCSTR sz, UINT16 uFlags)
 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 @@ LPMMIOPROC mmioInstallIOProc(FOURCC fccIOProc,
 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 @@ UINT16 mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 	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 @@ UINT16 mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 		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 @@ UINT16 mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 				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 @@ UINT16 mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 	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 mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 */
 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 mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
 */
 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 mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
 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 f9fa0c50f8805495761dea91c59a8c277339d371..d8c591704178a0cd826010993e56afbc9281a756 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -37,6 +37,14 @@ typedef struct tagTIMERENTRY {
 
 static LPTIMERENTRY lpTimerList = NULL;
 
+/*
+ * FIXME
+ * is this the minimum resolution ? 
+ */
+#define MMSYSTIME_MININTERVAL (33)
+#define MMSYSTIME_MAXINTERVAL (65535)
+
+
 /**************************************************************************
  *           TIME_MMSysTimeCallback
  */
@@ -44,7 +52,7 @@ static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
                                     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 @@ static void StartMMTime()
 	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 @@ WORD timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
     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 timeKillEvent(WORD wID)
  */
 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 timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
  */
 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 timeBeginPeriod(WORD wPeriod)
  */
 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 @@ WORD timeEndPeriod(WORD wPeriod)
  */
 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 3442d91c01b1cf8a8b9ecba676218441c030a86b..074359d90bb93502d912b9e039460f449abf3f1c 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 @@ typedef struct
     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 @@ static int COLOR_Graymax    = 0;
  * 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 @@ UINT16 COLOR_GetSystemPaletteFlags(void)
     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 @@ BOOL32 COLOR_CheckSysColor(COLORREF c)
   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 @@ static BOOL32 COLOR_BuildSharedMap(CSPACE* cs)
    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 @@ static void COLOR_Computeshifts(unsigned long maskbits, int *shift, int *max)
 /***********************************************************************
  *           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 @@ HPALETTE16 COLOR_Init(void)
     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 @@ COLORREF COLOR_ToLogical(int pixel)
 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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color )
 
           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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color )
             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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color )
 	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 6d31cd8d387cea9b6184c1746c974c444e5326f4..4f25c906d271e95ab2ca1179dc04753afad897eb 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 @@ BOOL32 DC_SetupGCForPen( DC * dc )
 
     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_SetupGCForPen( DC * dc )
  */
 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 a951745c432e6b012f827f829330a2308e325c52..94743dbc49841ef058240e7308bb9423a9d05cbf 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -49,6 +49,9 @@ int DIB_GetXImageWidthBytes( int width, int depth )
 {
     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 @@ int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
     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 @@ static int DIB_SetImageBits( DC *dc, DWORD lines, WORD depth, LPSTR bits,
 
       /* 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 3ac17db2314e49dff2f07e9347b66818ac16ca16..e79c6b6352e038427eb41b459211af0658ebb357 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 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 )
-{
-    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 );
-}
-
-
-/***********************************************************************
- *           FONT_LOGFONT32WToLOGFONT16
- */
-static void FONT_LOGFONT32WToLOGFONT16( const LOGFONT32W *font,
-                                        LPLOGFONT16 font16 )
-{
-    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 );
-}
-
-
-/***********************************************************************
- *           FONT_LOGFONT16ToLOGFONT32A
- */
-static void FONT_LOGFONT16ToLOGFONT32A( LPLOGFONT16 font,
-                                        LPLOGFONT32A font32A )
-{
-    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 );
-}
+#define ENUM_UNICODE	0x00000001
 
+typedef struct
+{
+  LPLOGFONT16           lpLogFontParam;
+  FONTENUMPROCEX16      lpEnumFunc;
+  LPARAM                lpData;
 
-/***********************************************************************
- *           FONT_LOGFONT16ToLOGFONT32W
- */
-static void FONT_LOGFONT16ToLOGFONT32W( LPLOGFONT16 font,
-                                        LPLOGFONT32W font32W )
-{
-    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 );
-}
+  LPNEWTEXTMETRICEX16   lpTextMetric;
+  LPENUMLOGFONTEX16     lpLogFont;
+  SEGPTR                segTextMetric;
+  SEGPTR                segLogFont;
+} fontEnum16;
 
+typedef struct
+{
+  LPLOGFONT32W          lpLogFontParam;
+  FONTENUMPROC32W       lpEnumFunc;
+  LPARAM                lpData;
 
+  LPNEWTEXTMETRICEX32W  lpTextMetric;
+  LPENUMLOGFONTEX32W    lpLogFont;
+  DWORD                 dwFlags;
+} fontEnum32;
+ 
 /***********************************************************************
- *           FONT_GetMetrics
+ *              LOGFONT conversion functions.
  */
-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;
+static void __logfont32to16( INT16* plf16, INT32* plf32 )
+{
+    int  i;
+    for( i = 0; i < 5; i++ ) *plf16++ = *plf32++;
+   *((INT32*)plf16)++ = *plf32++;
+   *((INT32*)plf16)   = *plf32;
 }
 
-
-/***********************************************************************
- *           GetGlyphOutline16    (GDI.309)
- */
-DWORD GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
-                         LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
-                         LPVOID lpBuffer, const MAT2 *lpmat2 )
+static void __logfont16to32( INT32* plf32, INT16* plf16 )
 {
-    fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
-             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
-    return (DWORD)-1; /* failure */
+    int i;
+    for( i = 0; i < 5; i++ ) *plf32++ = *plf16++;
+   *plf32++ = *((INT32*)plf16)++;
+   *plf32   = *((INT32*)plf16);
 }
 
-
-/***********************************************************************
- *           GetGlyphOutline32A    (GDI32.186)
- */
-DWORD GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
-                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
-                         LPVOID lpBuffer, const MAT2 *lpmat2 )
+void FONT_LogFont32ATo16( const LOGFONT32A* 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 );
+    lstrcpyn32A( 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_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 )
 {
-    fprintf( stdnimp,"GetGlyphOutLine32W(%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 );
 }
 
-
-/***********************************************************************
- *           CreateScalableFontResource16   (GDI.310)
- */
-BOOL16 CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
-                                     LPCSTR fontFile, LPCSTR path )
+void FONT_LogFont16To32A( LPLOGFONT16 font16, LPLOGFONT32A font32 )
 {
-    return CreateScalableFontResource32A( fHidden, lpszResourceFile,
-                                          fontFile, path );
+  __logfont16to32( (INT32*)font32, (INT16*)font16 );
+    lstrcpyn32A( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
 }
 
-/***********************************************************************
- *           CreateScalableFontResource32A   (GDI32.62)
- */
-BOOL32 CreateScalableFontResource32A( DWORD fHidden, LPCSTR lpszResourceFile,
-                                      LPCSTR lpszFontFile,
-                                      LPCSTR lpszCurrentPath )
+void FONT_LogFont16To32W( LPLOGFONT16 font16, LPLOGFONT32W font32 )
 {
-    /* 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 */
+  __logfont16to32( (INT32*)font32, (INT16*)font16 );
+    lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
 }
 
-
 /***********************************************************************
- *           CreateScalableFontResource32W   (GDI32.63)
- */
-BOOL32 CreateScalableFontResource32W( DWORD fHidden, LPCWSTR lpszResourceFile,
-                                      LPCWSTR lpszFontFile,
-                                      LPCWSTR lpszCurrentPath )
-{
-    fprintf(stdnimp,"CreateScalableFontResource32W(%ld,%p,%p,%p) // empty stub\n",
-            fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
-    return FALSE; /* create failed */
+ *              TEXTMETRIC conversion functions.
+ */
+void FONT_TextMetric32Ato16( LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
+{
+    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
+}
+
+void FONT_TextMetric32Wto16( LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
+{
+    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 )
+	{
+	    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);
+	}
     }
-    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;
-}
+    else fprintf(stderr,"CreateFontIndirect(NULL) => NULL\n");
 
+    return hFont;
+}
 
 /***********************************************************************
  *           CreateFontIndirect32A   (GDI32.44)
@@ -312,12 +210,10 @@ HFONT32 CreateFontIndirect32A( const LOGFONT32A *font )
 {
     LOGFONT16 font16;
 
-    FONT_LOGFONT32AToLOGFONT16(font,&font16);
-
+    FONT_LogFont32ATo16( font, &font16 );
     return CreateFontIndirect16( &font16 );
 }
 
-
 /***********************************************************************
  *           CreateFontIndirect32W   (GDI32.45)
  */
@@ -325,11 +221,10 @@ HFONT32 CreateFontIndirect32W( const LOGFONT32W *font )
 {
     LOGFONT16 font16;
 
-    FONT_LOGFONT32WToLOGFONT16(font,&font16);
+    FONT_LogFont32WTo16( font, &font16 );
     return CreateFontIndirect16( &font16 );
 }
 
-
 /***********************************************************************
  *           CreateFont16    (GDI.56)
  */
@@ -338,16 +233,17 @@ HFONT16 CreateFont16( INT16 height, INT16 width, INT16 esc, INT16 orient,
                       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 @@ HFONT32 CreateFont32A( INT32 height, INT32 width, INT32 esc, INT32 orient,
                                   clippres, quality, pitch, name );
 }
 
-
 /*************************************************************************
  *           CreateFont32W    (GDI32.46)
  */
@@ -391,7 +286,6 @@ INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
     return count;
 }
 
-
 /***********************************************************************
  *           FONT_GetObject32A
  */
@@ -399,22 +293,7 @@ INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
 {
     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 @@ INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
 }
 
 
+/***********************************************************************
+ *              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 @@ INT16 GetTextCharacterExtra16( HDC16 hdc )
     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 @@ INT32 GetTextCharacterExtra32( HDC32 hdc )
     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 SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
     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 @@ BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
     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 @@ BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
  */
 INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
 {
-	return GetTextFace32A(hdc,count,name);
+        return GetTextFace32A(hdc,count,name);
 }
 
 /***********************************************************************
@@ -579,7 +659,7 @@ BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
     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 @@ BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
         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 @@ BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
     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 @@ BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
  *           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 @@ BOOL32 GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
                                 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)
+    int index, nFit, extent;
+    SIZE32 tSize;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+    if (!dc)
     {
-      if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
-	return FALSE;
+	if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
+	    return FALSE;
     }
-  if (!dc->funcs->pGetTextExtentPoint) return FALSE;
+    if (!dc->funcs->pGetTextExtentPoint) return FALSE;
 
-  size->cx=0; size->cy=0;
-  for(index=0;index<count;index++)
+    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;
+ 	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",
+    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 @@ BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
 {
     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 @@ BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
  */
 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 @@ BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
  */
 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,110 +821,43 @@ BOOL32 GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
 {
     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;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetMapperFlags16    (GDI.349)
- */
-DWORD SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
-{
-    return SetMapperFlags32( hDC, dwFlag );
-}
-
-
-/***********************************************************************
- *           SetMapperFlags32    (GDI32.322)
- */
-DWORD SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
-{
-    dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n", 
-		 hDC, dwFlag); 
-    return 0L;
-}
-
- 
-/***********************************************************************
- *           GetCharABCWidths16   (GDI.307)
- */
-BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
-                           LPABC16 abc )
-{
-    ABC32 abc32;
-    if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
-    abc->abcA = abc32.abcA;
-    abc->abcB = abc32.abcB;
-    abc->abcC = abc32.abcC;
+    FONT_TextMetric32Ato32W( &tm, metrics );
     return TRUE;
 }
 
 
-/***********************************************************************
- *           GetCharABCWidths32A   (GDI32.149)
- */
-BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
-                            LPABC32 abc )
-{
-    /* No TrueType fonts in Wine so far */
-    fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
-             hdc, firstChar, lastChar, abc );
-    return FALSE;
-}
-
-
-/***********************************************************************
- *           GetCharABCWidths32W   (GDI32.152)
- */
-BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
-                            LPABC32 abc )
-{
-    return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
-}
-
-
 /***********************************************************************
  *           GetCharWidth16    (GDI.350)
  */
 BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
                        LPINT16 buffer )
 {
-    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)
+    BOOL32	retVal = FALSE;
+
+    if( firstChar != lastChar )
     {
-	for (i = firstChar; i <= lastChar; i++)
+	LPINT32	buf32 = (LPINT32)HeapAlloc(SystemHeap, 0,
+				 sizeof(INT32)*(1 + (lastChar - firstChar)));
+	if( buf32 )
 	{
-	    *buffer++ = *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);
 	}
     }
-    free (obuf32);
+    else
+    {
+	INT32 chWidth;
+	retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
+	*buffer = chWidth;
+    }
     return retVal;
 }
 
@@ -897,7 +871,7 @@ BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
     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;
     }
 
@@ -919,502 +893,140 @@ BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
 }
 
 
-/***********************************************************************
- *           AddFontResource16    (GDI.119)
+
+/* FIXME: all following APIs *******************************************
+ *
+ *
+ *           SetMapperFlags16    (GDI.349)
  */
-INT16 AddFontResource16( LPCSTR str )
+DWORD SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
 {
-    return AddFontResource32A( str );
+    return SetMapperFlags32( hDC, dwFlag );
 }
 
 
 /***********************************************************************
- *           AddFontResource32A    (GDI32.2)
+ *           SetMapperFlags32    (GDI32.322)
  */
-INT32 AddFontResource32A( LPCSTR str )
+DWORD SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
 {
-    if (HIWORD(str))
-        fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
-    else
-        fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
-    return 1;
+    dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
+                 hDC, dwFlag);
+    return 0L;
 }
 
 
 /***********************************************************************
- *           AddFontResource32W    (GDI32.4)
+ *           GetCharABCWidths16   (GDI.307)
  */
-INT32 AddFontResource32W( LPCWSTR str )
+BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
+                           LPABC16 abc )
 {
-    fprintf( stdnimp, "STUB: AddFontResource32W(%p)\n", str );
-    return 1;
+    ABC32 abc32;
+    if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
+    abc->abcA = abc32.abcA;
+    abc->abcB = abc32.abcB;
+    abc->abcC = abc32.abcC;
+    return TRUE;
 }
 
 
 /***********************************************************************
- *           RemoveFontResource16    (GDI.136)
+ *           GetCharABCWidths32A   (GDI32.149)
  */
-BOOL16 RemoveFontResource16( LPCSTR str )
+BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                            LPABC32 abc )
 {
-    return RemoveFontResource32A( str );
+    /* No TrueType fonts in Wine so far */
+    fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
+             hdc, firstChar, lastChar, abc );
+    return FALSE;
 }
 
 
 /***********************************************************************
- *           RemoveFontResource32A    (GDI32.284)
+ *           GetCharABCWidths32W   (GDI32.152)
  */
-BOOL32 RemoveFontResource32A( LPCSTR str )
+BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                            LPABC32 abc )
 {
-    if (HIWORD(str))
-        fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
-    else
-        fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
-    return TRUE;
+    return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
 }
 
 
 /***********************************************************************
- *           RemoveFontResource32W    (GDI32.286)
+ *           GetGlyphOutline16    (GDI.309)
  */
-BOOL32 RemoveFontResource32W( LPCWSTR str )
+DWORD GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
+                         LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
+                         LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-    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);
+    fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+    return (DWORD)-1; /* failure */
 }
 
-/*************************************************************************
- *				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]
+/***********************************************************************
+ *           GetGlyphOutline32A    (GDI32.186)
  */
-INT32 EnumFonts32A(HDC32 hDC, LPCSTR lpFaceName, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
+DWORD GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
+                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
+                         LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-  return EnumFontFamilies32A(hDC,lpFaceName,lpEnumFunc,lpData);
+    fprintf( stdnimp,"GetGlyphOutLine32A(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+    return (DWORD)-1; /* failure */
 }
 
-/*************************************************************************
- *				EnumFontsA			[GDI32.84]
+/***********************************************************************
+ *           GetGlyphOutline32W    (GDI32.187)
  */
-INT32 EnumFonts32W(HDC32 hDC, LPCWSTR lpFaceName, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
+DWORD GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
+                         LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
+                         LPVOID lpBuffer, const MAT2 *lpmat2 )
 {
-  return EnumFontFamilies32W(hDC,lpFaceName,lpEnumFunc,lpData);
+    fprintf( stdnimp,"GetGlyphOutLine32W(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+             hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+    return (DWORD)-1; /* failure */
 }
 
-/*************************************************************************
- *				EnumFontFamilies	[GDI.330]
+/***********************************************************************
+ *           CreateScalableFontResource16   (GDI.310)
  */
-INT16 EnumFontFamilies16(HDC16 hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
+BOOL16 CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
+                                     LPCSTR fontFile, LPCSTR path )
 {
-  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);
+    return CreateScalableFontResource32A( fHidden, lpszResourceFile,
+                                          fontFile, path );
 }
 
-/*************************************************************************
- *				EnumFontFamiliesA	[GDI32.80]
+/***********************************************************************
+ *           CreateScalableFontResource32A   (GDI32.62)
  */
-INT32 EnumFontFamilies32A(HDC32 hDC, LPCSTR lpszFamily, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
+BOOL32 CreateScalableFontResource32A( DWORD fHidden, LPCSTR lpszResourceFile,
+                                      LPCSTR lpszFontFile,
+                                      LPCSTR lpszCurrentPath )
 {
-  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);
+    /* 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 */
 }
 
-/*************************************************************************
- *				EnumFontFamiliesW	[GDI32.83]
+/***********************************************************************
+ *           CreateScalableFontResource32W   (GDI32.63)
  */
-INT32 EnumFontFamilies32W(HDC32 hDC, LPCWSTR lpszFamilyW, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
+BOOL32 CreateScalableFontResource32W( DWORD fHidden, LPCWSTR lpszResourceFile,
+                                      LPCWSTR lpszFontFile,
+                                      LPCWSTR lpszCurrentPath )
 {
-  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 @@ BOOL16 GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes )
  */
 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 @@ BOOL32 GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes )
 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 @@ INT16 GetKerningPairs16( HDC16 hDC, INT16 cPairs,
 }
 
 
+
 /*************************************************************************
  *             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 @@ DWORD GetKerningPairs32W( HDC32 hDC, DWORD cPairs,
 {
     return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );
 }
+
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 89aad658d6c1aa5eac9ef04ab108222acece3952..52c8bd5a1784465f84a2dfa6b17a9ea42af3d713 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -100,14 +100,14 @@ static FONTOBJ AnsiVarFont =
 {
     { 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 @@ static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
     (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 @@ static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
  */
 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 5c5da99185152e38082f50f6db3c7bc6a2fd439e..87e0b34494cd99432354dce6a9ee650e27ca9e65 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -304,18 +304,29 @@ BOOL16 EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf, MFENUMPROC16 lpEnumFunc,
 {
     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 @@ BOOL16 EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf, MFENUMPROC16 lpEnumFunc,
     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 @@ BOOL16 EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf, MFENUMPROC16 lpEnumFunc,
 	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 @@ BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
     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 @@ BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
     *(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 75e11a616e6f2d030b09efca8c07d61ecebc4264..74207b8a25285d074b899910d7d5fa21b2947545 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>
@@ -27,6 +29,45 @@ static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
 static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
 
 
+/***********************************************************************
+ *           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
  */
diff --git a/objects/region.c b/objects/region.c
index 3575132b6a10299e51498128ef3fd040b58d0b39..9148e6d4613fc554d3d76f04552bc5f0a24b8c03 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 8e1fac08a16d2bcf5ed523b7cbd11b08a4272b23..4a78235a5ab706e911615169128db9dd9e82caa6 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 52e380e5e8b15273d6249f8eea37c2d25dce3e9d..f7ecaebb09233c220a57ee803694f7a4d7bb4080 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -8,7 +8,7 @@ ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 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 0000000000000000000000000000000000000000..3d5963c153805755ed5bc3fcee6df72df821abb1
--- /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 68686d5e6f4cb68c3e7ccc3acba481478545ad89..6e9db2929d933f8ee7002d8267676b7a2321cfa4 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 @@ BOOL32 SetStdHandle( DWORD std_handle, HANDLE32 handle )
     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 33907ab8d417e911bda12038f12899602abeaac3..ad4ff27f04aebb3f7eaf718c43d633d7b05ea131 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -63,7 +63,7 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size,
     /* 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 6d9008cdd30a0d3268e868b420beed750ee1b835..53e67802b6d5d2b22ea2f1e506a6310dab24073c 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -704,7 +704,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
     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 @@ static int BuildModule32( FILE *outfile )
     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 8e889e6fff04f50917afeb30352db703e0daf4df..679511681c29ab22977cad391bfc26400d325c9a 100644
--- a/tools/fnt2bdf.c
+++ b/tools/fnt2bdf.c
@@ -34,6 +34,7 @@ extern char*   g_lpstrCharSet;
 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 @@ static char*    errorEmpty = "No fonts found.\n";
 
 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 @@ char*   lpChar;
 
   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 parse_fnt_data(unsigned char* file_buffer, int length)
 
     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 dump_bdf( fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
   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 dump_bdf_hdr(FILE* fs, fnt_fontS* cpe_font_struct, unsigned char* file_buffe
 {
 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 @@ int     l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
       /* 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 @@ int     l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
 
       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 @@ void parse_options(int argc, char **argv)
     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 @@ void parse_options(int argc, char **argv)
 
 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 @@ int get_resource_table(int fd, unsigned char** lpdata, int fsize)
   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 @@ int get_resource_table(int fd, unsigned char** lpdata, int fsize)
 
     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 @@ int get_resource_table(int fd, unsigned char** lpdata, int fsize)
     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 2fe54f2bafb21511c4c19c917ebea0238cebce16..9bb1ca796d6115655a6b932dd2db510b653347fc 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"
 
@@ -54,6 +55,19 @@ OpenProcessToken(HANDLE32 process,DWORD desiredaccess,HANDLE32 *thandle)
 	return TRUE;
 }
 
+/***********************************************************************
+ *           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]
  */
@@ -72,3 +86,43 @@ AdjustTokenPrivileges(HANDLE32 TokenHandle,BOOL32 DisableAllPrivileges,
 {
 	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 d0b25aea7a7fd9a675ad1984f2ba8f41e6715b4e..e8e506daaf07fb49b94aeb9dac8567db58d73959 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -215,3 +215,25 @@ BOOL32 FlushConsoleInputBuffer(HANDLE32 hConsoleInput){
     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 d4e9276d2bda36e873048693c5465477e8e6943e..ce261c0b81fe2140032f51d40a687b0706eadd86 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -112,30 +112,30 @@ void CLIPBOARD_DisOwn(WND* pWnd)
 {
   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 1694a79b8fefde3f246eece041a3fb0d82e8ffe7..850359ad72e6f0812a4a805ebc36be7c621c2502 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -171,7 +171,9 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
                                       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 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
 	{
 	    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 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
         }
         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 f59cbd9d2629c07765755685a320c6d0838ac3ed..40243102c19f9a321890c02a08f2309ca8211d8d 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -501,7 +501,7 @@ HWND32 DIALOG_CreateIndirect( HINSTANCE32 hInst, LPCSTR dlgTemplate,
           /* (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 @@ static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg,
     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 fa01908939b06f522a2b77f85065a7ae4d275707..c03c98cf0688f4d90bb9d253b894260843af9aba 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -813,16 +813,16 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
 	}
     }
 
-    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 e301cbf2128bbc7e6dff883d04e1fd2305052836..581d091170e83c18b7a7083119ab616ea06b6501 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -179,10 +179,8 @@ static HWND16 MDI_GetWindow(WND  *clientWnd, HWND16 hWnd, WORD wTo )
             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 @@ static LONG MDI_ChildActivate( WND *clientPtr, HWND16 hWndChild )
     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 HBITMAP16 CreateMDIMenuBitmap(void)
  */
 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;
+
+	    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;
+	    ysize   = rect.bottom / rows;
+	    xsize   = rect.right  / columns;
     
-    	x       = 0;
-    	i       = 0;
-
-    	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;
-    	}
+	    for (x = i = 0, c = 1; c <= columns && *ppWnd; c++)
+	    {
+	        if (c == columns)
+		{
+		    rows  = total - i;
+		    ysize = rect.bottom / rows;
+		}
+
+		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 @@ BOOL32 TranslateMDISysAccel32( HWND32 hwndClient, LPMSG32 msg )
 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 80c3e5c0aeb0f830c4d665faaa97c575f606b2cf..5b70ee282a3a0db16f0fc99975623b5dd98fa3a9 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -1013,7 +1013,7 @@ LRESULT SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam)
     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 @@ LRESULT SendMessage32A(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 
     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 @@ LRESULT SendMessage32W(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
 
     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 08ff98ba9e0a3f4cf181f78b4f6ae1223c2aef5a..5237a529a2afc214b00aa6e58779334503731e21 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -150,86 +150,6 @@ BOOL32 AdjustWindowRectEx32( LPRECT32 rect, DWORD style,
 }
 
 
-/*******************************************************************
- *         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 @@ static void NC_DrawCaption( HDC32 hdc, RECT32 *rect, HWND32 hwnd,
  *
  * 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 @@ void NC_DoNCPaint( HWND32 hwnd, HRGN32 clip, BOOL32 suppress_menupaint )
  */
 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 @@ LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
 
     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 @@ BOOL32 NC_GetSysPopupPos( WND* wndPtr, RECT32* rect )
  *           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 @@ static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
 
       /* 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 @@ static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
 
     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 @@ static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
 		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 @@ static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
     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 @@ static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
 
     /* 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 @@ LONG NC_HandleNCLButtonDown( HWND32 hwnd, WPARAM16 wParam, LPARAM lParam )
     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 1196b8f8756d2b8f3e5c77a29b6cf2dde0ba9e09..48f0d513c2ff15408f7620e49f1da4f59df3ed96 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 @@ HBRUSH16 GetControlBrush( HWND16 hwnd, HDC16 hdc, UINT16 control )
  * 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 @@ BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
                     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 231761a38799dbf2ba82aa5dc5ebca3c67ef471a..72cd9b0d83943082fb5fb455c5d5b6136d637b93 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 @@ BOOL32 ExitWindowsEx( UINT32 flags, DWORD reserved )
         
     /* 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 f093af15691c958b596ccdbde8427134d828ac42..087f942e5e74699d87cc740eee869cff25d22acd 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -43,11 +43,13 @@ static HWND32 hwndSysModal = 0;
 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 @@ void WIN_DumpWindow( HWND32 hwnd )
              "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 @@ void WIN_DumpWindow( HWND32 hwnd )
              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 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
 
     /* 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 @@ BOOL32 WIN_CreateDesktopWindow(void)
 
     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 @@ BOOL32 WIN_CreateDesktopWindow(void)
     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 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
     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 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
 
     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 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
     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 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
 
             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 @@ WORD GetWindowWord32( HWND32 hwnd, INT32 offset )
     {
         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 @@ BOOL32 IsWindowVisible32( HWND32 hwnd )
  *
  * 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 @@ HWND32 GetLastActivePopup32( HWND32 hwnd )
 /*******************************************************************
  *           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 @@ BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
     /* 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 @@ BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
     /* 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 @@ static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
     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 @@ BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
     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 @@ BOOL16 DragDetect16( HWND16 hWnd, POINT16 pt )
  */
 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 @@ BOOL32 DragDetect32( HWND32 hWnd, POINT32 pt )
 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; 
+    }
 
- SetCapture32(hWnd);
- ShowCursor32( TRUE );
+    lpDragInfo->hWnd   = hWnd;
+    lpDragInfo->hScope = 0;
+    lpDragInfo->wFlags = wObj;
+    lpDragInfo->hList  = szList; /* near pointer! */
+    lpDragInfo->hOfStruct = hOfStruct;
+    lpDragInfo->l = 0L; 
 
- while( !dragDone )
-  {
-    WaitMessage();
+    SetCapture32(hWnd);
+    ShowCursor32( TRUE );
 
-    if( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
-	 continue;
+    do
+    {
+	do{  WaitMessage(); }
+	while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
 
-   *(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);
-
-    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 )
+	if( hCurrentCursor )
+	    SetCursor32(hCurrentCursor);
+
+	/* 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);
-
+	else
+	    if( hCurrentWnd )
+	        SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
 
-    /* check if we're done */
-    if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
-	dragDone = TRUE;
-  }
+    } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
 
- ReleaseCapture();
- ShowCursor32( FALSE );
+    ReleaseCapture();
+    ShowCursor32( FALSE );
 
- if( hCursor )
- {
-     SetCursor32( hOldCursor );
-     if (hDragCursor) DestroyCursor32( hDragCursor );
- }
+    if( hCursor )
+    {
+	SetCursor32( hOldCursor );
+	if (hDragCursor) DestroyCursor32( hDragCursor );
+    }
 
- if( hCurrentCursor != hBummer ) 
-	dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT, 
-                               (WPARAM16)hWnd, (LPARAM)spDragInfo );
- GlobalFree16(hDragInfo);
+    if( hCurrentCursor != hBummer ) 
+	msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT, 
+				   (WPARAM16)hWnd, (LPARAM)spDragInfo );
+    else
+        msg.lParam = 0;
+    GlobalFree16(hDragInfo);
 
- return dwRet;
+    return (DWORD)(msg.lParam);
 }
 
diff --git a/windows/winhelp.c b/windows/winhelp.c
index f087247f0d3d6eb8e03f4b30677ed2808b295860..49ae2ca1698e499c3c4b5b8ad159d58df208e462 100644
--- a/windows/winhelp.c
+++ b/windows/winhelp.c
@@ -76,7 +76,7 @@ BOOL32 WinHelp32A( HWND32 hWnd, LPCSTR lpHelpFile, UINT32 wCommand,
 			return FALSE;
 	}
 	if(lpHelpFile)
-		nlen =  strlen(lpHelpFile)+1;
+		nlen = strlen(lpHelpFile)+1;
 	else
 		nlen = 0;
 	size = sizeof(WINHELP) + nlen + dsize;
@@ -84,10 +84,12 @@ BOOL32 WinHelp32A( HWND32 hWnd, LPCSTR lpHelpFile, UINT32 wCommand,
 	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 9b90564d2ce9db5208315574e20cc89bdb25298a..3c4a46958e3af4fcc4b8757629624e619ed9a060 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 @@ extern BOOL32   DCE_InvalidateDCE(WND*, RECT16* );
 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 = SYSMETRICS_CXICONSPACING;
+    yspacing = SYSMETRICS_CYICONSPACING;
 
-    xspacing = yspacing = 70;  /* FIXME: This should come from WIN.INI */
     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 @@ void WINPOS_FindIconPos( HWND32 hwnd )
                 }
                 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 @@ void WINPOS_FindIconPos( HWND32 hwnd )
 
 
 /***********************************************************************
- *           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 @@ UINT32 ArrangeIconicWindows32( HWND32 parent )
     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 @@ void MapWindowPoints32( HWND32 hwndFrom, HWND32 hwndTo,
 
 
 /***********************************************************************
- *           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 @@ BOOL32 IsZoomed32(HWND32 hWnd)
  */
 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 SetActiveWindow32( HWND32 hwnd )
     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;
@@ -617,6 +657,247 @@ BOOL32 MoveWindow32(
     return SetWindowPos32( hwnd, 0, x, y, cx, cy, flags );
 }
 
+/***********************************************************************
+ *           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)
  */
@@ -629,11 +910,10 @@ BOOL16 ShowWindow16( HWND16 hwnd, INT16 cmd )
  */
 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 @@ BOOL32 ShowWindow32( HWND32 hwnd, INT32 cmd )
     {
         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 @@ BOOL32 ShowWindow32( HWND32 hwnd, INT32 cmd )
 
     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 @@ BOOL32 ShowWindow32( HWND32 hwnd, INT32 cmd )
     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 @@ BOOL32 ShowWindow32( HWND32 hwnd, INT32 cmd )
 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,125 +1037,204 @@ UINT16 GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd, LPPOINT16 ptIcon)
 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;
 }
 
-
 /***********************************************************************
- *           SetInternalWindowPos16   (USER.461)
+ *           GetWindowPlacement16   (USER.370)
  */
-void SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
-                             LPRECT16 rect, LPPOINT16 pt )
+BOOL16 GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
 {
-    WINDOWPLACEMENT16 wndpl;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    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 );
+    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;
 }
 
 
 /***********************************************************************
- *           SetInternalWindowPos32   (USER32.482)
+ *           GetWindowPlacement32   (USER32.306)
  */
-void SetInternalWindowPos32( HWND32 hwnd, UINT32 showCmd,
-                             LPRECT32 rect, LPPOINT32 pt )
+BOOL32 GetWindowPlacement32( HWND32 hwnd, WINDOWPLACEMENT32 *pwpl32 )
 {
-    WINDOWPLACEMENT32 wndpl;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    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 );
+    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;
 }
 
 
 /***********************************************************************
- *           GetWindowPlacement16   (USER.370)
+ *           WINPOS_SetPlacement
  */
-BOOL16 GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
+static BOOL32 WINPOS_SetPlacement( HWND32 hwnd, const WINDOWPLACEMENT16 *wndpl,
+						UINT32 flags )
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
+    WND *pWnd = WIN_FindWndPtr( hwnd );
+    if( pWnd )
+    {
+	LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
+			     *(LPPOINT16)&pWnd->rectWindow.left, &pWnd->rectWindow );
 
-    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;
+	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;
 }
 
 
 /***********************************************************************
- *           GetWindowPlacement32   (USER32.306)
+ *           SetWindowPlacement16   (USER.371)
  */
-BOOL32 GetWindowPlacement32( HWND32 hwnd, WINDOWPLACEMENT32 *wndpl )
+BOOL16 SetWindowPlacement16( HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl )
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
+    return WINPOS_SetPlacement( hwnd, wndpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
+}
 
-    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;
+/***********************************************************************
+ *           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;
 }
 
 
 /***********************************************************************
- *           SetWindowPlacement16   (USER.371)
+ *           SetInternalWindowPos16   (USER.461)
  */
-BOOL16 SetWindowPlacement16( HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl )
+void SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
+                             LPRECT16 rect, LPPOINT16 pt )
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
+    if( IsWindow16(hwnd) )
+    {
+	WINDOWPLACEMENT16 wndpl;
+	UINT32 flags;
 
-    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;
+	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 );
+    }
 }
 
 
 /***********************************************************************
- *           SetWindowPlacement32   (USER32.518)
+ *           SetInternalWindowPos32   (USER32.482)
  */
-BOOL32 SetWindowPlacement32( HWND32 hwnd, const WINDOWPLACEMENT32 *wndpl )
+void SetInternalWindowPos32( HWND32 hwnd, UINT32 showCmd,
+                             LPRECT32 rect, LPPOINT32 pt )
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
+    if( IsWindow32(hwnd) )
+    {
+	WINDOWPLACEMENT16 wndpl;
+	UINT32 flags;
 
-    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;
+	wndpl.length  = sizeof(wndpl);
+	wndpl.showCmd = showCmd;
+	wndpl.flags = flags = 0;
+
+	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 @@ static void WINPOS_ForceXWindowRaise( WND* pWnd )
  */
 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 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
     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 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
     {
         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 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
 	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 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
 	 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 @@ BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd)
       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 @@ LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
     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 @@ LONG WINPOS_HandleWindowPosChanging32( WND *wndPtr, WINDOWPOS32 *winpos )
     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 @@ HWND32 WINPOS_ReorderOwnedPopups(HWND32 hwndInsertAfter,WND* wndPtr,WORD flags)
  * 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 @@ BOOL32 SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter, INT32 x, INT32 y,
 
     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 b121e27d08d76834cd1fdbcecfa0f7fb10428bfb..1eff79326097c71bd989713b4fb9d7819b912e64 100644
--- a/wine.ini
+++ b/wine.ini
@@ -31,6 +31,12 @@ Path=/tmp
 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 @@ SymbolTableFile=./wine.sym
 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 @@ Com4=/dev/modem
 [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;