Release 970202

Sun Feb  2 12:31:03 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/drive.c]
	Fixed SetCurrentDirectory() to also change the current drive.

	* [win32/except.c] [tools/build.c]
	Use Win32 register functions to implement exception handling.
	Fixed UnhandledExceptionFilter.

Fri Jan 31 15:42:41  1997  David Faure  <david.faure@ihamy.insa-lyon.fr>

	* [windows/keyboard.c]
	Added KEYBOARD_GenerateMsg to generate Caps Lock and NumLock events
	Added calls to KEYBOARD_GenerateMsg when the key is pressed/released
	or when the state has changed, out of wine.
	Changed type 3-state 'ToggleKeyState' to boolean. The On/Off is given
	by InputKeyStateTable.

Wed Jan 29 21:53:04 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/*resource.c][if1632/thunk.c]
	EnumResource* added.

	* [loader/pe_resource.] [loader/resource.c]
	SizeofResource32(), LoadAccelerators32() added.

	* [misc/lstr.c]
	FormatMessage %n added.

	* [misc/crtdll.c][include/ctrdll.h][if1632/crtdll.spec]
	_chdrive,_errno,_isctype added.

	* [misc/cpu.c]
	Replaced runtime_cpu by GetSystemInfo().

	* [windows/hook.c][include/hook.h]
	Fixed mapping of hooks to win32/unicode.

	* [windows/keyboard.c] [windows/defwnd.c]
	Updated to win32 standard.
	ALT-<Menukey> fixed.

	* [windows/queue.c]
	GetWindowThreadProcessId() implemented.

Mon Jan 27 16:42:49 1997  John Harvey <john@division.co.uk>

	* [graphics/metafiledrv/*] [graphics/x11drv/*]
	  [objects/bitmap.c] [objects/brush.c] [objects/font.c]
	  [objects/gdiobj.c] [objects/pen.c]
	Moved SelectObject to graphics drivers. Printer support now works
	in a few cases but is definitely not complete. Generic/text driver
	works. The postscript driver works if true type fonts are disabled
	from the control panel. To enable printer support add Printer=on
	to the wine section of your wine.conf file. This causes write not
	to work properly. I know that several other printer drivers do not
	work.

	* [tools/build.c]
	Make .stabs not used for svr4 since it doesn't use GNU assembler.

	* [misc/fontengine.c]
	Make sure a printf doesn't crash the system.

Sat Jan 25 15:53:35 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/metafile.c]
	Fixed some problems with PlayMetaFileRecord().

	* [objects/dc.c]
	hClipRgn gets initialized in GetDCState().

Fri Jan 24 21:22:26 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [debugger/stabs.c]
	Handle file names beginning with '/'.

Fri Jan 24 18:33:04 1997  Robert Pouliot <krynos@clic.net>

	* [*/*]
	Some more patches for OS/2 support.

Fri Jan 24 11:30:41 1997  Bang Jun-Young  <bangjy@nownuri.nowcom.co.kr>

	* [resources/sysres_Ko.rc]
	Updated support for Korean (Ko) language.
diff --git a/ANNOUNCE b/ANNOUNCE
index 50c7bc3..4e2d1f3 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,13 @@
-This is release 970120 of Wine, the MS Windows emulator.  This is still a
+This is release 970202 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-970120: (see ChangeLog for details)
-	- More keyboard improvements.
-	- Some new printer driver functions.
-	- Many fixes to Win32 loader.
-	- Better edit control.
+WHAT'S NEW with Wine-970202: (see ChangeLog for details)
+	- More printer support.
+	- Some new Win32 functions.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -18,10 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970120.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970120.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970120.tar.gz
-  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-970120.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970202.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970202.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970202.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-970202.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 27134ae..cce92fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,92 @@
 ----------------------------------------------------------------------
+Sun Feb  2 12:31:03 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [files/drive.c]
+	Fixed SetCurrentDirectory() to also change the current drive.
+
+	* [win32/except.c] [tools/build.c]
+	Use Win32 register functions to implement exception handling.
+	Fixed UnhandledExceptionFilter.
+
+Fri Jan 31 15:42:41  1997  David Faure  <david.faure@ihamy.insa-lyon.fr>
+
+	* [windows/keyboard.c]
+	Added KEYBOARD_GenerateMsg to generate Caps Lock and NumLock events
+	Added calls to KEYBOARD_GenerateMsg when the key is pressed/released
+	or when the state has changed, out of wine.
+	Changed type 3-state 'ToggleKeyState' to boolean. The On/Off is given
+	by InputKeyStateTable.
+
+Wed Jan 29 21:53:04 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [loader/*resource.c][if1632/thunk.c]
+	EnumResource* added.
+
+	* [loader/pe_resource.] [loader/resource.c]
+	SizeofResource32(), LoadAccelerators32() added.
+
+	* [misc/lstr.c]
+	FormatMessage %n added.
+
+	* [misc/crtdll.c][include/ctrdll.h][if1632/crtdll.spec]
+	_chdrive,_errno,_isctype added.
+
+	* [misc/cpu.c]
+	Replaced runtime_cpu by GetSystemInfo().
+
+	* [windows/hook.c][include/hook.h]
+	Fixed mapping of hooks to win32/unicode.
+
+	* [windows/keyboard.c] [windows/defwnd.c]
+	Updated to win32 standard.
+	ALT-<Menukey> fixed.
+
+	* [windows/queue.c]
+	GetWindowThreadProcessId() implemented.
+
+Mon Jan 27 16:42:49 1997  John Harvey <john@division.co.uk>
+
+	* [graphics/metafiledrv/*] [graphics/x11drv/*]
+	  [objects/bitmap.c] [objects/brush.c] [objects/font.c]
+	  [objects/gdiobj.c] [objects/pen.c]
+	Moved SelectObject to graphics drivers. Printer support now works
+	in a few cases but is definitely not complete. Generic/text driver
+	works. The postscript driver works if true type fonts are disabled
+	from the control panel. To enable printer support add Printer=on
+	to the wine section of your wine.conf file. This causes write not
+	to work properly. I know that several other printer drivers do not
+	work.
+
+	* [tools/build.c]
+	Make .stabs not used for svr4 since it doesn't use GNU assembler.
+
+	* [misc/fontengine.c]
+	Make sure a printf doesn't crash the system.
+
+Sat Jan 25 15:53:35 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [objects/metafile.c]
+	Fixed some problems with PlayMetaFileRecord().
+
+	* [objects/dc.c]
+	hClipRgn gets initialized in GetDCState().
+
+Fri Jan 24 21:22:26 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>
+
+	* [debugger/stabs.c]
+	Handle file names beginning with '/'.
+
+Fri Jan 24 18:33:04 1997  Robert Pouliot <krynos@clic.net>
+
+	* [*/*]
+	Some more patches for OS/2 support.
+
+Fri Jan 24 11:30:41 1997  Bang Jun-Young  <bangjy@nownuri.nowcom.co.kr>
+
+	* [resources/sysres_Ko.rc]
+	Updated support for Korean (Ko) language.
+
+----------------------------------------------------------------------
 Sun Jan 19 11:46:48 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [loader/module.c]
diff --git a/controls/combo.c b/controls/combo.c
index 7259aec..5ece877 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -932,9 +932,14 @@
   int   i, top, height;
 
   top = 0;
+  if (!lphl)
+    return 0;
   hdc = BeginPaint16( hwnd, &ps );
 
-  if (!IsWindowVisible16(hwnd) || !lphl->bRedrawFlag) {
+  if (!lphl) {
+    fprintf(stdnimp,"CBLPaint: CLBoxGetListHeader returned NULL!\n");
+  }
+  if (!IsWindowVisible16(hwnd) || !lphl || !lphl->bRedrawFlag) {
     EndPaint16(hwnd, &ps);
     return 0;
   }
diff --git a/controls/edit.c b/controls/edit.c
index c8b241d..b333222 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -3450,11 +3450,11 @@
 	BOOL32 shift;
 	BOOL32 control;
 
-	if (GetKeyState(VK_MENU) & 0x8000)
+	if (GetKeyState32(VK_MENU) & 0x8000)
 		return 0;
 
-	shift = GetKeyState(VK_SHIFT) & 0x8000;
-	control = GetKeyState(VK_CONTROL) & 0x8000;
+	shift = GetKeyState32(VK_SHIFT) & 0x8000;
+	control = GetKeyState32(VK_CONTROL) & 0x8000;
 
 	EDIT_GetSel(wndPtr, &s, &e);
 	switch (wParam) {
@@ -3599,7 +3599,7 @@
 	c = EDIT_ColFromWndX(wndPtr, l, x);
 	li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
 	e = li + c;
-	if (GetKeyState(VK_SHIFT) & 0x8000)
+	if (GetKeyState32(VK_SHIFT) & 0x8000)
 		EDIT_GetSel(wndPtr, &s, NULL);
 	else
 		s = e;
diff --git a/controls/listbox.c b/controls/listbox.c
index 006de25..fd8c665 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -349,18 +349,22 @@
     else if (descr->style & LBS_OWNERDRAWVARIABLE)
     {
         INT32 i;
-        if (index < descr->top_item)
-        {
-            for (i = descr->top_item-1; i >= index; i--)
-                rect->top -= descr->items[i].height;
-        }
-        else
-        {
-            for (i = descr->top_item; i < index; i++)
-                rect->top += descr->items[i].height;
-        }
-        rect->bottom = rect->top + descr->items[index].height;
         rect->right += descr->horz_pos;
+        if ((index >= 0) && (index < descr->nb_items))
+        {
+            if (index < descr->top_item)
+            {
+                for (i = descr->top_item-1; i >= index; i--)
+                    rect->top -= descr->items[i].height;
+            }
+            else
+            {
+                for (i = descr->top_item; i < index; i++)
+                    rect->top += descr->items[i].height;
+            }
+            rect->bottom = rect->top + descr->items[index].height;
+
+        }
     }
     else
     {
@@ -1892,7 +1896,7 @@
     if (caret >= 0)
     {
         if ((descr->style & LBS_EXTENDEDSEL) &&
-            !(GetKeyState( VK_SHIFT ) & 0x8000))
+            !(GetKeyState32( VK_SHIFT ) & 0x8000))
             descr->anchor_item = caret;
         LISTBOX_MoveCaret( wnd, descr, caret, TRUE );
         if (descr->style & LBS_NOTIFY)
diff --git a/debugger/break.c b/debugger/break.c
index d84427d..e2265f9 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -208,10 +208,24 @@
 {
     DBG_ADDR addr = *address;
     int num;
+    unsigned int seg2;
     BYTE *p;
 
     DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
 
+    if( addr.type != NULL && addr.type == DEBUG_TypeIntConst )
+      {
+	/*
+	 * We know that we have the actual offset stored somewhere
+	 * else in 32-bit space.  Grab it, and we
+	 * should be all set.
+	 */
+	seg2 = addr.seg;
+	addr.seg = 0;
+	addr.off = DEBUG_GetExprValue(&addr, NULL);
+	addr.seg = seg2;
+      }
+
     if (next_bp < MAX_BREAKPOINTS)
         num = next_bp++;
     else  /* try to find an empty slot */  
diff --git a/debugger/dbg.y b/debugger/dbg.y
index f79a3ff..b87291a 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -14,6 +14,7 @@
 #include "options.h"
 #include "queue.h"
 #include "win.h"
+#include "winnt.h"
 #include "debugger.h"
 
 #include "expr.h"
@@ -289,7 +290,7 @@
     | tENUM tIDENTIFIER		{ $$ = DEBUG_TypeCast(ENUM, $2); }
 
 expr_addr:
-    expr			 { $$ = DEBUG_EvalExpr($1) }
+    expr			 { $$ = DEBUG_EvalExpr($1); }
 
 expr_value:
       expr        { DBG_ADDR addr  = DEBUG_EvalExpr($1);
@@ -348,7 +349,7 @@
  * of expression that is suitable to be used as an lvalue.
  */
 lval_addr:
-    lval			 { $$ = DEBUG_EvalExpr($1) }
+    lval			 { $$ = DEBUG_EvalExpr($1); }
 
 lval:
       lvalue                     { $$ = $1; }
@@ -535,17 +536,6 @@
 
 
 /***********************************************************************
- *           DEBUG_EnterDebugger
- *
- * Force an entry into the debugger.
- */
-void DEBUG_EnterDebugger(void)
-{
-    kill( getpid(), SIGHUP );
-}
-
-
-/***********************************************************************
  *           DebugBreak16   (KERNEL.203)
  */
 void DebugBreak16( CONTEXT *regs )
@@ -560,6 +550,17 @@
 void wine_debug( int signal, SIGCONTEXT *regs )
 {
     DEBUG_SetSigContext( regs );
+#if 0
+    DWORD *stack = (DWORD *)ESP_reg(&DEBUG_context);
+    *(--stack) = 0;
+    *(--stack) = 0;
+    *(--stack) = EH_NONCONTINUABLE;
+    *(--stack) = EXCEPTION_ACCESS_VIOLATION;
+    *(--stack) = EIP_reg(&DEBUG_context);
+    ESP_reg(&DEBUG_context) = (DWORD)stack;
+    EIP_reg(&DEBUG_context) = GetProcAddress32( GetModuleHandle("KERNEL32"),
+                                                "RaiseException" );
+#endif
     DEBUG_Main( signal );
     DEBUG_GetSigContext( regs );
 }
diff --git a/debugger/expr.c b/debugger/expr.c
index 6ef8d37..6968c06 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -418,7 +418,14 @@
       rtn.type = DEBUG_TypeIntConst;
       exp->un.rgister.result = DEBUG_GetRegister(exp->un.rgister.reg);
       rtn.off = (unsigned int) &exp->un.rgister.result;
-      rtn.seg = 0;
+      if( exp->un.rgister.reg == REG_EIP )
+	{
+	  rtn.seg = CS_reg(&DEBUG_context);
+	}
+      else
+	{
+	  rtn.seg = DS_reg(&DEBUG_context);
+	}
       break;
     case EXPR_TYPE_BINOP:
       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
diff --git a/debugger/hash.c b/debugger/hash.c
index 20f3e64..ab63c4a 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -751,17 +751,20 @@
     for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
     {
         if (!(pModule = MODULE_GetPtr( entry.hModule ))) continue;
+        if (pModule->flags & NE_FFLAGS_WIN32) continue;
 
         name = (unsigned char *)pModule + pModule->name_table;
 
+        fprintf( stderr, "Loading symbols from Win16 module %.*s...\n",
+                 *name, name + 1 );
+
         /* First search the resident names */
 
         cpnt = (unsigned char *)pModule + pModule->name_table;
         while (*cpnt)
         {
             cpnt += *cpnt + 1 + sizeof(WORD);
-            sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
-                     *cpnt, *cpnt, cpnt + 1 );
+            sprintf( buffer, "%.*s_%.*s", *name, name + 1, *cpnt, cpnt + 1 );
             if ((address = MODULE_GetEntryPoint( entry.hModule,
                                             *(WORD *)(cpnt + *cpnt + 1) )))
             {
@@ -779,8 +782,7 @@
         while (*cpnt)
         {
             cpnt += *cpnt + 1 + sizeof(WORD);
-            sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
-                     *cpnt, *cpnt, cpnt + 1 );
+            sprintf( buffer, "%.*s_%.*s", *name, name + 1, *cpnt, cpnt + 1 );
             if ((address = MODULE_GetEntryPoint( entry.hModule,
                                                 *(WORD *)(cpnt + *cpnt + 1) )))
             {
diff --git a/debugger/memory.c b/debugger/memory.c
index f629194..9f0cb52 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -146,6 +146,7 @@
     unsigned int	* dump;
     int			  i;
     unsigned char	* pnt;
+    unsigned int	  seg2;
     struct datatype	* testtype;
     unsigned short int	* wdump;
 
@@ -159,13 +160,33 @@
      */
     if( addr.type != NULL )
       {
-	if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
-	DEBUG_TypeDerefPointer(&addr, &testtype);
-	if( testtype != NULL || addr.type == DEBUG_TypeIntConst )
+	if( addr.type == DEBUG_TypeIntConst )
 	  {
+	    /*
+	     * We know that we have the actual offset stored somewhere
+	     * else in 32-bit space.  Grab it, and we
+	     * should be all set.
+	     */
+	    seg2 = addr.seg;
+	    addr.seg = 0;
 	    addr.off = DEBUG_GetExprValue(&addr, NULL);
+	    addr.seg = seg2;
+	  }
+	else
+	  {
+	    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
+	    DEBUG_TypeDerefPointer(&addr, &testtype);
+	    if( testtype != NULL || addr.type == DEBUG_TypeIntConst )
+	      {
+		addr.off = DEBUG_GetExprValue(&addr, NULL);
+	      }
 	  }
       }
+    else if (!addr.seg && !addr.off)
+    {
+	fprintf(stderr,"Invalid expression\n");
+	return;
+    }
 
     if (format != 'i' && count > 1)
     {
diff --git a/debugger/msc.c b/debugger/msc.c
index 90bf0fd..6514f37 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -895,7 +895,7 @@
 
   orig_size = size;
   dbgptr = (LPIMAGE_DEBUG_DIRECTORY) (load_addr + v_addr);
-  for(; size > 0; size -= sizeof(*dbgptr), dbgptr++ )
+  for(; size >= sizeof(*dbgptr); size -= sizeof(*dbgptr), dbgptr++ )
     {
       switch(dbgptr->Type)
 	{
@@ -908,7 +908,7 @@
 
   size = orig_size;
   dbgptr = (LPIMAGE_DEBUG_DIRECTORY) (load_addr + v_addr);
-  for(; size > 0; size -= sizeof(*dbgptr), dbgptr++ )
+  for(; size >= sizeof(*dbgptr); size -= sizeof(*dbgptr), dbgptr++ )
     {
       switch(dbgptr->Type)
 	{
diff --git a/debugger/source.c b/debugger/source.c
index 4ece937..8cad568 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -12,7 +12,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <limits.h>
-#include <strings.h>
+#include <string.h>
 #include <unistd.h>
 #include <malloc.h>
 
diff --git a/debugger/stabs.c b/debugger/stabs.c
index a52c467..8a1bea1 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -11,7 +11,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/mman.h>
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
 
 #include "win.h"
 #include "debugger.h"
@@ -24,6 +26,9 @@
 #ifdef __ELF__
 #include <elf.h>
 #include <link.h>
+#include <sys/mman.h>
+#elif defined(__EMX__)
+#include <a_out.h>
 #else
 #include <a.out.h>
 #endif
@@ -883,7 +888,10 @@
 	    }
 	  else
 	    {
-	      strcat(currpath, ptr);
+	      if (*ptr != '/')
+	        strcat(currpath, ptr);
+	      else
+	        strcpy(currpath, ptr);
 	      subpath = ptr;
 	    }
 	  last_nso = i;
diff --git a/debugger/types.c b/debugger/types.c
index 0b26d50..1bbc6ed 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -11,14 +11,11 @@
 #include <stdlib.h>
 
 #include <assert.h>
-#ifndef __EMX__
-#include <sys/mman.h>
-#endif
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <limits.h>
-#include <strings.h>
+#include <string.h>
 #include <unistd.h>
 #include <malloc.h>
 
diff --git a/files/directory.c b/files/directory.c
index 1c64f74..1abc4b2 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -593,7 +593,8 @@
     lstrcpyn32A( buffer, full_name.short_name, buflen );
     res = full_name.long_name +
               strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
-    if (*res && (buflen > 3)) lstrcpyn32A( buffer + 3, res + 1, buflen - 3 );
+    while (*res == '/') res++;
+    if (buflen > 3) lstrcpyn32A( buffer + 3, res, buflen - 3 );
     for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
     if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
     return *res ? strlen(res) + 2 : 3;
@@ -622,7 +623,8 @@
     lstrcpynAtoW( buffer, full_name.short_name, buflen );
     res = full_name.long_name +
               strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
-    if (*res && (buflen > 3)) lstrcpynAtoW( buffer + 3, res + 1, buflen - 3 );
+    while (*res == '/') res++;
+    if (buflen > 3) lstrcpynAtoW( buffer + 3, res + 1, buflen - 3 );
     for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
     if (lastpart)
     {
diff --git a/files/drive.c b/files/drive.c
index b38f2c1..8b04493 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -678,36 +678,38 @@
  */
 BOOL16 SetCurrentDirectory16( LPCSTR dir )
 {
-    if (dir[0] && (dir[1]==':'))
-    {
-        int drive = tolower( *dir ) - 'a';
-        if (!DRIVE_IsValid(drive))
-        {
-            DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
-            return 0;
-        }
-        dir += 2;
-    }
-    /* FIXME: what about empty strings? Add a \\ ? */
-    return DRIVE_Chdir( DRIVE_GetCurrentDrive(), dir );
+    return SetCurrentDirectory32A( dir );
 }
 
+
 /***********************************************************************
  *           SetCurrentDirectory32A   (KERNEL32.479)
  */
 BOOL32 SetCurrentDirectory32A( LPCSTR dir )
 {
-    /* FIXME: Unauthorized Windows 95 mentions that SetCurrentDirectory 
-     * may change drive and current directory for there is no drive based
-     * currentdir table?
-     */
-    return SetCurrentDirectory16(dir);
+    int drive = DRIVE_GetCurrentDrive();
+
+    if (dir[0] && (dir[1]==':'))
+    {
+        drive = tolower( *dir ) - 'a';
+        if (!DRIVE_IsValid( drive ))
+        {
+            DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+            return FALSE;
+        }
+        dir += 2;
+    }
+    /* FIXME: what about empty strings? Add a \\ ? */
+    if (!DRIVE_Chdir( drive, dir )) return FALSE;
+    if (drive == DRIVE_GetCurrentDrive()) return TRUE;
+    return DRIVE_SetCurrentDrive( drive );
 }
 
+
 /***********************************************************************
  *           SetCurrentDirectory32W   (KERNEL32.480)
  */
-BOOL32 SetCurrentDirectory32W( LPCWSTR dirW)
+BOOL32 SetCurrentDirectory32W( LPCWSTR dirW )
 {
     LPSTR dir = HEAP_strdupWtoA( GetProcessHeap(), 0, dirW );
     BOOL32 res = SetCurrentDirectory32A( dir );
diff --git a/files/file.c b/files/file.c
index b9e2b4a..9e8a042 100644
--- a/files/file.c
+++ b/files/file.c
@@ -435,6 +435,21 @@
     return TRUE;
 }
 
+/***********************************************************************
+ *           CompareFileTime   (KERNEL32.28)
+ */
+INT32 CompareFileTime( LPFILETIME x, LPFILETIME y )
+{
+	if (x->dwHighDateTime > y->dwHighDateTime)
+		return 1;
+	if (x->dwHighDateTime < y->dwHighDateTime)
+		return -1;
+	if (x->dwLowDateTime > y->dwLowDateTime)
+		return 1;
+	if (x->dwLowDateTime < y->dwLowDateTime)
+		return -1;
+	return 0;
+}
 
 /***********************************************************************
  *           FILE_Dup
diff --git a/graphics/metafiledrv/Makefile.in b/graphics/metafiledrv/Makefile.in
index 5246a6c..ff538f2 100644
--- a/graphics/metafiledrv/Makefile.in
+++ b/graphics/metafiledrv/Makefile.in
@@ -10,6 +10,7 @@
 	graphics.c \
 	init.c \
 	mapping.c \
+	objects.c \
 	text.c
 
 all: $(MODULE).o
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index 6545c9e..08dac5d 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -52,7 +52,7 @@
     MFDRV_ScaleViewportExt,          /* pScaleViewportExt */
     MFDRV_ScaleWindowExt,            /* pScaleWindowExt */
     NULL,                            /* pSelectClipRgn */
-    NULL,                            /* pSelectObject */
+    MFDRV_SelectObject,              /* pSelectObject */
     NULL,                            /* pSelectPalette */
     NULL,                            /* pSetBkColor */
     NULL,                            /* pSetBkMode */
diff --git a/graphics/metafiledrv/objects.c b/graphics/metafiledrv/objects.c
new file mode 100644
index 0000000..2c1aa22
--- /dev/null
+++ b/graphics/metafiledrv/objects.c
@@ -0,0 +1,104 @@
+/*
+ * GDI objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "bitmap.h"
+#include "brush.h"
+#include "font.h"
+#include "metafile.h"
+#include "metafiledrv.h"
+#include "pen.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/***********************************************************************
+ *           MFDRV_BITMAP_SelectObject
+ */
+static HBITMAP16 MFDRV_BITMAP_SelectObject( DC * dc, HBITMAP16 hbitmap,
+                                            BITMAPOBJ * bmp )
+{
+    return 0;
+}
+
+
+/***********************************************************************
+ *           MFDRV_BRUSH_SelectObject
+ */
+static HBRUSH32 MFDRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush,
+                                          BRUSHOBJ * brush )
+{
+    LOGBRUSH16 logbrush = { brush->logbrush.lbStyle,
+                            brush->logbrush.lbColor,
+                            brush->logbrush.lbHatch };
+    switch (brush->logbrush.lbStyle)
+    {
+    case BS_SOLID:
+    case BS_HATCHED:
+    case BS_HOLLOW:
+        if (!MF_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
+        break;
+    case BS_PATTERN:
+    case BS_DIBPATTERN:
+        if (!MF_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
+        break;
+    }
+    return 1;  /* FIXME? */
+}
+
+
+/***********************************************************************
+ *           MFDRV_FONT_SelectObject
+ */
+static HFONT16 MFDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
+                                        FONTOBJ * font )
+{
+    HFONT16 prevHandle = dc->w.hFont;
+    if (MF_CreateFontIndirect(dc, hfont, &(font->logfont))) return prevHandle;
+    return 0;
+}
+
+
+/***********************************************************************
+ *           MFDRV_PEN_SelectObject
+ */
+static HPEN32 MFDRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen )
+{
+    HPEN32 prevHandle = dc->w.hPen;
+    LOGPEN16 logpen = { pen->logpen.lopnStyle,
+                        { pen->logpen.lopnWidth.x, pen->logpen.lopnWidth.y },
+                        pen->logpen.lopnColor };
+    if (MF_CreatePenIndirect( dc, hpen, &logpen )) return prevHandle;
+    return 0;
+}
+
+
+/***********************************************************************
+ *           MFDRV_SelectObject
+ */
+HGDIOBJ32 MFDRV_SelectObject( DC *dc, HGDIOBJ32 handle )
+{
+    GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+
+    if (!ptr) return 0;
+    dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", dc->hSelf, handle );
+    
+    switch(ptr->wMagic)
+    {
+      case PEN_MAGIC:
+	  return MFDRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
+      case BRUSH_MAGIC:
+	  return MFDRV_BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
+      case BITMAP_MAGIC:
+	  return MFDRV_BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
+      case FONT_MAGIC:
+	  return MFDRV_FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );	  
+      case REGION_MAGIC:
+	  return (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
+    }
+    return 0;
+}
diff --git a/graphics/x11drv/Makefile.in b/graphics/x11drv/Makefile.in
index 1fd36db..9001dad 100644
--- a/graphics/x11drv/Makefile.in
+++ b/graphics/x11drv/Makefile.in
@@ -7,10 +7,14 @@
 
 C_SRCS = \
 	bitblt.c \
+	bitmap.c \
+	brush.c \
 	clipping.c \
 	font.c \
 	graphics.c \
 	init.c \
+	objects.c \
+	pen.c \
 	text.c
 
 all: $(MODULE).o
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
new file mode 100644
index 0000000..d0cc825
--- /dev/null
+++ b/graphics/x11drv/bitmap.c
@@ -0,0 +1,81 @@
+/*
+ * GDI bitmap objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "gdi.h"
+#include "callback.h"
+#include "dc.h"
+#include "bitmap.h"
+#include "heap.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/***********************************************************************
+ *           X11DRV_BITMAP_Init
+ */
+BOOL32 X11DRV_BITMAP_Init(void)
+{
+    Pixmap tmpPixmap;
+    
+      /* Create the necessary GCs */
+    
+    if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 )))
+    {
+	BITMAP_monoGC = XCreateGC( display, tmpPixmap, 0, NULL );
+	XSetGraphicsExposures( display, BITMAP_monoGC, False );
+	XFreePixmap( display, tmpPixmap );
+    }
+
+    if (screenDepth != 1)
+    {
+	if ((tmpPixmap = XCreatePixmap(display, rootWindow, 1,1,screenDepth)))
+	{
+	    BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL );
+	    XSetGraphicsExposures( display, BITMAP_colorGC, False );
+	    XFreePixmap( display, tmpPixmap );
+	}
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           X11DRV_BITMAP_SelectObject
+ */
+HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap,
+                                      BITMAPOBJ * bmp )
+{
+    HRGN32 hrgn;
+    HBITMAP32 prevHandle = dc->w.hBitmap;
+    
+    if (!(dc->w.flags & DC_MEMORY)) return 0;
+
+    if (dc->w.hVisRgn)
+       SetRectRgn(dc->w.hVisRgn, 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight );
+    else
+    { 
+       hrgn = CreateRectRgn32(0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
+       if (!hrgn) return 0;
+       dc->w.hVisRgn    = hrgn;
+    }
+
+    dc->u.x.drawable = bmp->pixmap;
+    dc->w.hBitmap    = hbitmap;
+
+      /* Change GC depth if needed */
+
+    if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel)
+    {
+	XFreeGC( display, dc->u.x.gc );
+	dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL );
+	dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
+        DC_InitDC( dc );
+    }
+    else CLIPPING_UpdateGCRegion( dc );  /* Just update GC clip region */
+    return prevHandle;
+}
diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c
new file mode 100644
index 0000000..62bc41f
--- /dev/null
+++ b/graphics/x11drv/brush.c
@@ -0,0 +1,270 @@
+/*
+ * GDI brush objects
+ *
+ * Copyright 1993, 1994  Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include "brush.h"
+#include "bitmap.h"
+#include "color.h"
+#include "x11drv.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static const char HatchBrushes[NB_HATCH_STYLES][8] =
+{
+    { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HS_HORIZONTAL */
+    { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HS_VERTICAL   */
+    { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HS_FDIAGONAL  */
+    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HS_BDIAGONAL  */
+    { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HS_CROSS      */
+    { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }  /* HS_DIAGCROSS  */
+};
+
+  /* Levels of each primary for dithering */
+#define PRIMARY_LEVELS  3  
+#define TOTAL_LEVELS    (PRIMARY_LEVELS*PRIMARY_LEVELS*PRIMARY_LEVELS)
+
+ /* Dithering matrix size  */
+#define MATRIX_SIZE     8
+#define MATRIX_SIZE_2   (MATRIX_SIZE*MATRIX_SIZE)
+
+  /* Total number of possible levels for a dithered primary color */
+#define DITHER_LEVELS   (MATRIX_SIZE_2 * (PRIMARY_LEVELS-1) + 1)
+
+  /* Dithering matrix */
+static const int dither_matrix[MATRIX_SIZE_2] =
+{
+     0, 32,  8, 40,  2, 34, 10, 42,
+    48, 16, 56, 24, 50, 18, 58, 26,
+    12, 44,  4, 36, 14, 46,  6, 38,
+    60, 28, 52, 20, 62, 30, 54, 22,
+     3, 35, 11, 43,  1, 33,  9, 41,
+    51, 19, 59, 27, 49, 17, 57, 25,
+    15, 47,  7, 39, 13, 45,  5, 37,
+    63, 31, 55, 23, 61, 29, 53, 21
+};
+
+  /* Mapping between (R,G,B) triples and EGA colors */
+static const int EGAmapping[TOTAL_LEVELS] =
+{
+    0,  /* 000000 -> 000000 */
+    4,  /* 00007f -> 000080 */
+    12, /* 0000ff -> 0000ff */
+    2,  /* 007f00 -> 008000 */
+    6,  /* 007f7f -> 008080 */
+    6,  /* 007fff -> 008080 */
+    10, /* 00ff00 -> 00ff00 */
+    6,  /* 00ff7f -> 008080 */
+    14, /* 00ffff -> 00ffff */
+    1,  /* 7f0000 -> 800000 */
+    5,  /* 7f007f -> 800080 */
+    5,  /* 7f00ff -> 800080 */
+    3,  /* 7f7f00 -> 808000 */
+    8,  /* 7f7f7f -> 808080 */
+    7,  /* 7f7fff -> c0c0c0 */
+    3,  /* 7fff00 -> 808000 */
+    7,  /* 7fff7f -> c0c0c0 */
+    7,  /* 7fffff -> c0c0c0 */
+    9,  /* ff0000 -> ff0000 */
+    5,  /* ff007f -> 800080 */
+    13, /* ff00ff -> ff00ff */
+    3,  /* ff7f00 -> 808000 */
+    7,  /* ff7f7f -> c0c0c0 */
+    7,  /* ff7fff -> c0c0c0 */
+    11, /* ffff00 -> ffff00 */
+    7,  /* ffff7f -> c0c0c0 */
+    15  /* ffffff -> ffffff */
+};
+
+#define PIXEL_VALUE(r,g,b) \
+    COLOR_mapEGAPixel[EGAmapping[((r)*PRIMARY_LEVELS+(g))*PRIMARY_LEVELS+(b)]]
+
+  /* X image for building dithered pixmap */
+static XImage *ditherImage = NULL;
+
+
+/***********************************************************************
+ *           BRUSH_Init
+ *
+ * Create the X image used for dithering.
+ */
+BOOL32 X11DRV_BRUSH_Init(void)
+{
+    XCREATEIMAGE( ditherImage, MATRIX_SIZE, MATRIX_SIZE, screenDepth );
+    return (ditherImage != NULL);
+}
+
+
+/***********************************************************************
+ *           BRUSH_DitherColor
+ */
+static Pixmap BRUSH_DitherColor( DC *dc, COLORREF color )
+{
+    static COLORREF prevColor = 0xffffffff;
+    unsigned int x, y;
+    Pixmap pixmap;
+
+    if (color != prevColor)
+    {
+	int r = GetRValue( color ) * DITHER_LEVELS;
+	int g = GetGValue( color ) * DITHER_LEVELS;
+	int b = GetBValue( color ) * DITHER_LEVELS;
+	const int *pmatrix = dither_matrix;
+
+	for (y = 0; y < MATRIX_SIZE; y++)
+	{
+	    for (x = 0; x < MATRIX_SIZE; x++)
+	    {
+		int d  = *pmatrix++ * 256;
+		int dr = ((r + d) / MATRIX_SIZE_2) / 256;
+		int dg = ((g + d) / MATRIX_SIZE_2) / 256;
+		int db = ((b + d) / MATRIX_SIZE_2) / 256;
+		XPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) );
+	    }
+	}
+	prevColor = color;
+    }
+    
+    pixmap = XCreatePixmap( display, rootWindow,
+			    MATRIX_SIZE, MATRIX_SIZE, screenDepth );
+    XPutImage( display, pixmap, BITMAP_colorGC, ditherImage, 0, 0,
+	       0, 0, MATRIX_SIZE, MATRIX_SIZE );
+    return pixmap;
+}
+
+
+/***********************************************************************
+ *           BRUSH_SelectSolidBrush
+ */
+static void BRUSH_SelectSolidBrush( DC *dc, COLORREF color )
+{
+    if ((dc->w.bitsPerPixel > 1) && (screenDepth <= 8) && !COLOR_IsSolid( color ))
+    {
+	  /* Dithered brush */
+	dc->u.x.brush.pixmap = BRUSH_DitherColor( dc, color );
+	dc->u.x.brush.fillStyle = FillTiled;
+	dc->u.x.brush.pixel = 0;
+    }
+    else
+    {
+	  /* Solid brush */
+	dc->u.x.brush.pixel = COLOR_ToPhysical( dc, color );
+	dc->u.x.brush.fillStyle = FillSolid;
+    }
+}
+
+
+/***********************************************************************
+ *           BRUSH_SelectPatternBrush
+ */
+static BOOL32 BRUSH_SelectPatternBrush( DC * dc, HBITMAP32 hbitmap )
+{
+    BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+    if (!bmp) return FALSE;
+    dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow,
+					  8, 8, bmp->bitmap.bmBitsPixel );
+    XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap,
+	       BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 );
+    
+    if (bmp->bitmap.bmBitsPixel > 1)
+    {
+	dc->u.x.brush.fillStyle = FillTiled;
+	dc->u.x.brush.pixel = 0;  /* Ignored */
+    }
+    else
+    {
+	dc->u.x.brush.fillStyle = FillOpaqueStippled;
+	dc->u.x.brush.pixel = -1;  /* Special case (see DC_SetupGCForBrush) */
+    }
+    return TRUE;
+}
+
+
+
+
+/***********************************************************************
+ *           BRUSH_SelectObject
+ */
+HBRUSH32 X11DRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush, BRUSHOBJ * brush )
+{
+    HBITMAP16 hBitmap;
+    BITMAPINFO * bmpInfo;
+    HBRUSH16 prevHandle = dc->w.hBrush;
+
+    dprintf_gdi(stddeb, "Brush_SelectObject: hdc=%04x hbrush=%04x\n",
+                dc->hSelf,hbrush);
+#ifdef NOTDEF
+    if (dc->header.wMagic == METAFILE_DC_MAGIC)
+    {
+        LOGBRUSH16 logbrush = { brush->logbrush.lbStyle,
+                                brush->logbrush.lbColor,
+                                brush->logbrush.lbHatch };
+	switch (brush->logbrush.lbStyle)
+	{
+	case BS_SOLID:
+	case BS_HATCHED:
+	case BS_HOLLOW:
+	    if (!MF_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
+	    break;
+	case BS_PATTERN:
+	case BS_DIBPATTERN:
+	    if (!MF_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
+	    break;
+	}
+	return 1;  /* FIXME? */
+    }
+#endif    
+    dc->w.hBrush = hbrush;
+
+    if (dc->u.x.brush.pixmap)
+    {
+	XFreePixmap( display, dc->u.x.brush.pixmap );
+	dc->u.x.brush.pixmap = 0;
+    }
+    dc->u.x.brush.style = brush->logbrush.lbStyle;
+    
+    switch(brush->logbrush.lbStyle)
+    {
+      case BS_NULL:
+	dprintf_gdi( stddeb,"BS_NULL\n" );
+	break;
+
+      case BS_SOLID:
+        dprintf_gdi( stddeb,"BS_SOLID\n" );
+	BRUSH_SelectSolidBrush( dc, brush->logbrush.lbColor );
+	break;
+	
+      case BS_HATCHED:
+	dprintf_gdi( stddeb, "BS_HATCHED\n" );
+	dc->u.x.brush.pixel = COLOR_ToPhysical( dc, brush->logbrush.lbColor );
+	dc->u.x.brush.pixmap = XCreateBitmapFromData( display, rootWindow,
+				 HatchBrushes[brush->logbrush.lbHatch], 8, 8 );
+	dc->u.x.brush.fillStyle = FillStippled;
+	break;
+	
+      case BS_PATTERN:
+	dprintf_gdi( stddeb, "BS_PATTERN\n");
+	BRUSH_SelectPatternBrush( dc, (HBRUSH16)brush->logbrush.lbHatch );
+	break;
+
+      case BS_DIBPATTERN:
+	dprintf_gdi( stddeb, "BS_DIBPATTERN\n");
+	if ((bmpInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)brush->logbrush.lbHatch )))
+	{
+	    int size = DIB_BitmapInfoSize( bmpInfo, brush->logbrush.lbColor );
+	    hBitmap = CreateDIBitmap32( dc->hSelf, &bmpInfo->bmiHeader,
+                                        CBM_INIT, ((char *)bmpInfo) + size,
+                                        bmpInfo,
+                                        (WORD)brush->logbrush.lbColor );
+	    BRUSH_SelectPatternBrush( dc, hBitmap );
+	    DeleteObject16( hBitmap );
+	    GlobalUnlock16( (HGLOBAL16)brush->logbrush.lbHatch );	    
+	}
+	
+	break;
+    }
+    
+    return prevHandle;
+}
diff --git a/graphics/x11drv/font.c b/graphics/x11drv/font.c
index 4b816e2..a2f5151 100644
--- a/graphics/x11drv/font.c
+++ b/graphics/x11drv/font.c
@@ -4,9 +4,250 @@
  * Copyright 1996 Alexandre Julliard
  */
 
-#include "windows.h"
-#include "x11drv.h"
-#include "gdi.h"
+#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;
+
+
+/***********************************************************************
+ *           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
@@ -62,4 +303,156 @@
 }
 
 
+/***********************************************************************
+ *           X11DRV_FONT_SelectObject
+ */
+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;
+}
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index a7fd361..6f34f63 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -52,7 +52,7 @@
     NULL,                            /* pScaleViewportExt (optional) */
     NULL,                            /* pScaleWindowExt (optional) */
     NULL,                            /* pSelectClipRgn */
-    NULL,                            /* pSelectObject */
+    X11DRV_SelectObject,             /* pSelectObject */
     NULL,                            /* pSelectPalette */
     NULL,                            /* pSetBkColor */
     NULL,                            /* pSetBkMode */
@@ -84,6 +84,18 @@
  */
 BOOL32 X11DRV_Init(void)
 {
+    /* Create default bitmap */
+
+    if (!X11DRV_BITMAP_Init()) return FALSE;
+
+    /* Initialize brush dithering */
+
+    if (!X11DRV_BRUSH_Init()) return FALSE;
+
+    /* Initialize fonts */
+
+    if (!X11DRV_FONT_Init()) return FALSE;
+
     return DRIVER_RegisterDriver( "DISPLAY", &X11DRV_Funcs );
 }
 
diff --git a/graphics/x11drv/objects.c b/graphics/x11drv/objects.c
new file mode 100644
index 0000000..fb2f0b8
--- /dev/null
+++ b/graphics/x11drv/objects.c
@@ -0,0 +1,50 @@
+/*
+ * GDI objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "bitmap.h"
+#include "brush.h"
+#include "font.h"
+#include "pen.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+extern HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap,
+                                             BITMAPOBJ * bmp );
+extern HBRUSH32 X11DRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush,
+                                           BRUSHOBJ * brush );
+extern HFONT32 X11DRV_FONT_SelectObject( DC * dc, HFONT32 hfont,
+                                         FONTOBJ * font );
+extern HPEN32 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen );
+
+
+/***********************************************************************
+ *           X11DRV_SelectObject
+ */
+HGDIOBJ32 X11DRV_SelectObject( DC *dc, HGDIOBJ32 handle )
+{
+    GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+
+    if (!ptr) return 0;
+    dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", dc->hSelf, handle );
+    
+    switch(ptr->wMagic)
+    {
+      case PEN_MAGIC:
+	  return X11DRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
+      case BRUSH_MAGIC:
+	  return X11DRV_BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
+      case BITMAP_MAGIC:
+	  return X11DRV_BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
+      case FONT_MAGIC:
+	  return X11DRV_FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );	  
+      case REGION_MAGIC:
+	  return (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
+    }
+    return 0;
+}
diff --git a/graphics/x11drv/pen.c b/graphics/x11drv/pen.c
new file mode 100644
index 0000000..8516569
--- /dev/null
+++ b/graphics/x11drv/pen.c
@@ -0,0 +1,51 @@
+/*
+ * GDI pen objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include "pen.h"
+#include "color.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static const char PEN_dash[]       = { 5,3 };      /* -----   -----   -----  */
+static const char PEN_dot[]        = { 1,1 };      /* --  --  --  --  --  -- */
+static const char PEN_dashdot[]    = { 4,3,2,3 };  /* ----   --   ----   --  */
+static const char PEN_dashdotdot[] = { 4,2,2,2,2,2 }; /* ----  --  --  ----  */
+
+/***********************************************************************
+ *           PEN_SelectObject
+ */
+HPEN32 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen )
+{
+    HPEN32 prevHandle = dc->w.hPen;
+
+    dc->w.hPen = hpen;
+    dc->u.x.pen.style = pen->logpen.lopnStyle;
+    dc->u.x.pen.width = pen->logpen.lopnWidth.x * dc->vportExtX / dc->wndExtX;
+    if (dc->u.x.pen.width < 0) dc->u.x.pen.width = -dc->u.x.pen.width;
+    if (dc->u.x.pen.width == 1) dc->u.x.pen.width = 0;  /* Faster */
+    dc->u.x.pen.pixel = COLOR_ToPhysical( dc, pen->logpen.lopnColor );    
+    switch(pen->logpen.lopnStyle)
+    {
+      case PS_DASH:
+	dc->u.x.pen.dashes = (char *)PEN_dash;
+	dc->u.x.pen.dash_len = 2;
+	break;
+      case PS_DOT:
+	dc->u.x.pen.dashes = (char *)PEN_dot;
+	dc->u.x.pen.dash_len = 2;
+	break;
+      case PS_DASHDOT:
+	dc->u.x.pen.dashes = (char *)PEN_dashdot;
+	dc->u.x.pen.dash_len = 4;
+	break;
+      case PS_DASHDOTDOT:
+	dc->u.x.pen.dashes = (char *)PEN_dashdotdot;
+	dc->u.x.pen.dash_len = 6;
+	break;
+    }
+    
+    return prevHandle;
+}
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index e5de231..3f16ec4 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -60,9 +60,6 @@
 	relay.c \
 	thunk.c
 
-ASM_SRCS = \
-	except.S
-
 GEN_ASM_SRCS = \
 	$(SPEC_FILES) \
 	callfrom16.s \
@@ -93,7 +90,4 @@
 callto32.s: $(TOPSRCDIR)/include/callback.h $(BUILD)
 	$(BUILD) -o $@ -callto32 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo32_" | sed 's/.*CallTo32_\(.*\)(.*/\1/' | sort | uniq`
 
-except.o: except.S $(TOPOBJDIR)/include/config.h
-	$(CC) -c $(DIVINCL) -o $*.o $(SRCDIR)/except.S
-
 ### Dependencies:
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index b249b60..a1279f9 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -54,7 +54,7 @@
 049 stub _cexit
 050 stub _cgets
 051 stub _chdir
-052 stub _chdrive
+052 cdecl _chdrive(long) CRTDLL__chdrive
 053 stub _chgsign
 054 stub _chmod
 055 stub _chsize
@@ -79,7 +79,7 @@
 074 stub _endthread
 075 extern _environ_dll CRTDLL_environ_dll
 076 stub _eof
-077 stub _errno
+077 cdecl _errno() CRTDLL__errno
 078 stub _except_handler2
 079 stub _execl
 080 stub _execle
@@ -140,7 +140,7 @@
 135 cdecl _initterm(ptr ptr) CRTDLL__initterm
 136 stub _iob
 137 cdecl _isatty(long) CRTDLL__isatty
-138 stub _isctype
+138 cdecl _isctype(long long) CRTDLL__isctype
 139 stub _ismbbalnum
 140 stub _ismbbalpha
 141 stub _ismbbgraph
@@ -432,7 +432,7 @@
 427 cdecl malloc(ptr) CRTDLL_malloc
 428 stub mblen
 429 stub mbstowcs
-430 stub mbtowc
+430 cdecl mbtowc(long) CRTDLL_mbtowc
 431 cdecl memchr(ptr long long) memchr
 432 cdecl memcmp(ptr ptr long) memcmp
 433 cdecl memcpy(ptr ptr long) memcpy
@@ -510,7 +510,7 @@
 505 stub wcscmp
 506 cdecl wcscoll(ptr ptr) CRTDLL_wcscoll
 507 cdecl wcscpy(ptr ptr) lstrcpy32W
-508 stub wcscspn
+508 cdecl wcscspn(ptr ptr) CRTDLL_wcscspn
 509 stub wcsftime
 510 cdecl wcslen(ptr) lstrlen32W
 511 cdecl wcsncat(ptr ptr long) lstrcatn32W
diff --git a/if1632/except.S b/if1632/except.S
deleted file mode 100644
index cbe05b7..0000000
--- a/if1632/except.S
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Win32 exception assembly functions
- *
- * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
- *
- */
-#include "config.h"
-
-#ifdef NEED_UNDERSCORE_PREFIX
-
-     .globl _EXC_CallUnhandledExceptionFilter
- _EXC_CallUnhandledExceptionFilter:
-
-#else
-
-     .globl EXC_CallUnhandledExceptionFilter
- EXC_CallUnhandledExceptionFilter:
-
-#endif  /* NEED_UNDERSCORE_PREFIX */
-     leal   4(%esp),%eax
-     pushl  %eax
-#ifdef NEED_UNDERSCORE_PREFIX
-     call   *_pTopExcHandler
-#else
-     call   *pTopExcHandler
-#endif  /* NEED_UNDERSCORE_PREFIX */
-     movl   %ebp,%esp
-     ret
-
-
-
-/*******************************************************************
- *
- *        RaiseException           (KERNEL32. 418 )
- *        RtlUnwind                (KERNEL32. 443 )
- *
- * we need to save our context before a call to
- *
- * -RaiseException
- * -RtlUnwind
- *
- * after these functions we need to restore that context structure as
- * the actual context so changes made to the context structure in an
- * exception-handler will be reflected in the context after these
- * functions return. Fortunately both functions have 4 DWORD params.
- * we pass the function to be called as a fifth parameter to ContextCall
- *
- */
-#define CONTEXT_SegSs        -4
-#define CONTEXT_Esp          -8
-#define CONTEXT_EFlags       -12
-#define CONTEXT_SegCs        -16
-#define CONTEXT_Eip          -20
-#define CONTEXT_Ebp          -24
-#define CONTEXT_Eax          -28
-#define CONTEXT_Ecx          -32
-#define CONTEXT_Edx          -36
-#define CONTEXT_Ebx          -40
-#define CONTEXT_Esi          -44
-#define CONTEXT_Edi          -48
-#define CONTEXT_SegDs        -52
-#define CONTEXT_SegEs        -56
-#define CONTEXT_SegFs        -60
-#define CONTEXT_SegGs        -64
-#define FLOAT_Cr0NpxState    -68
-#define FLOAT_RegisterArea   -148
-#define FLOAT_DataSelector   -152
-#define FLOAT_DataOffset     -156
-#define FLOAT_ErrorSelector  -160
-#define FLOAT_ErrorOffset    -164
-#define FLOAT_TagWord        -168
-#define FLOAT_StatusWord     -172
-#define FLOAT_ControlWord    -176
-#define CONTEXT_FloatSave    -176
-#define CONTEXT_Dr7          -180
-#define CONTEXT_Dr6          -184
-#define CONTEXT_Dr3          -188
-#define CONTEXT_Dr2          -192
-#define CONTEXT_Dr1          -196
-#define CONTEXT_Dr0          -200
-#define CONTEXT_ContextFlags -204
-#define CONTEXT              -204
-#define CONTEXTSIZE           204
-#define CONTEXTFLAGS          0x10007
-
-#define ORIG_ESP              16         /** cdecl !!! **/
-#define PARM_ARG4             28
-#define PARM_ARG3             24
-#define PARM_ARG2             20
-#define PARM_ARG1             16
-#define PARM_RETURN           12
-#define PARM_CALLFUNC         8
-#define PARM_EBP              4
-#define PARM_EFLAGS           0
-
-#ifdef NEED_UNDERSCORE_PREFIX
-	.globl _RaiseException
-
- _RaiseException:
-       push   $_EXC_RaiseException
-       jmp    ContextCall
-
-       .globl _RtlUnwind
-
- _RtlUnwind:
-       push   $_EXC_RtlUnwind
-
-#else  /* NEED_UNDERSCORE_PREFIX */
-       .globl RaiseException
-
- RaiseException:
-       push   $EXC_RaiseException
-       jmp    ContextCall
-
-       .globl RtlUnwind
-
- RtlUnwind:
-       push   $EXC_RtlUnwind
-#endif  /* NEED_UNDERSCORE_PREFIX */
-
- ContextCall:
-       pushl  %ebp
-       pushfl
-       movl   %esp, %ebp
-       subl   $CONTEXTSIZE,      %esp
-       movl   %eax, CONTEXT_Eax(%ebp)
-       leal   ORIG_ESP(%ebp), %eax
-       movl   %eax, CONTEXT_Esp(%ebp)
-       movl   PARM_EFLAGS(%ebp), %eax
-       movl   %eax, CONTEXT_EFlags(%ebp)
-       movl   PARM_EBP(%ebp), %eax
-       movl   %eax, CONTEXT_Ebp(%ebp)
-       movl   PARM_RETURN(%ebp), %eax
-       movl   %eax, CONTEXT_Eip(%ebp)
-       movl   %edi, CONTEXT_Edi(%ebp)
-       movl   %esi, CONTEXT_Esi(%ebp)
-       movl   %ebx, CONTEXT_Ebx(%ebp)
-       movl   %edx, CONTEXT_Edx(%ebp)
-       movl   %ecx, CONTEXT_Ecx(%ebp)
-       xorl   %eax, %eax
-       movw   %ss, %ax
-       movl   %eax, CONTEXT_SegSs(%ebp)
-       movw   %cs, %ax
-       movl   %eax, CONTEXT_SegCs(%ebp)
-       movw   %gs, %ax
-       movl   %eax, CONTEXT_SegGs(%ebp)
-       movw   %fs, %ax
-       movl   %eax, CONTEXT_SegFs(%ebp)
-       movw   %es, %ax
-       movl   %eax, CONTEXT_SegEs(%ebp)
-       movw   %ds, %ax
-       movl   %eax, CONTEXT_SegDs(%ebp)
-       fsave  CONTEXT_FloatSave(%ebp)
-       movl   $CONTEXTFLAGS, %eax
-       movl   %eax, CONTEXT_ContextFlags(%ebp)
-       pushl  %ebp
-       leal   CONTEXT(%ebp), %eax
-       pushl  %eax
-       pushl  PARM_ARG4(%ebp)
-       pushl  PARM_ARG3(%ebp)
-       pushl  PARM_ARG2(%ebp)
-       pushl  PARM_ARG1(%ebp)
-       call   *PARM_CALLFUNC(%ebp)
-       addl   $20,%esp
-       popl   %ebp
-       lds    CONTEXT_Esp(%ebp),%edi
-       movl   CONTEXT_Eip(%ebp),%eax
-       movl   %eax,-4(%edi)
-       movl   CONTEXT_EFlags(%ebp),%eax
-       movl   %eax,-8(%edi)
-       movl   CONTEXT_Edi(%ebp),%eax
-       movl   %eax,-12(%edi)
-       movl   CONTEXT_SegDs(%ebp),%eax
-       movw   %ax,%ds
-       movl   CONTEXT_SegEs(%ebp),%eax
-       movw   %ax,%es
-       movl   CONTEXT_SegFs(%ebp),%eax
-       movw   %ax,%fs
-       movl   CONTEXT_SegGs(%ebp),%eax
-       movw   %ax,%gs
-       frstor CONTEXT_FloatSave(%ebp)
-       movl   CONTEXT_Ecx(%ebp),%ecx
-       movl   CONTEXT_Edx(%ebp),%edx
-       movl   CONTEXT_Ebx(%ebp),%ebx
-       movl   CONTEXT_Esi(%ebp),%esi
-       movl   CONTEXT_Eax(%ebp),%eax
-       movl   CONTEXT_Ebp(%ebp),%ebp
-       lea    -12(%edi),%esp
-       popl   %edi
-       popfl
-       ret
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 290fb85..ca8d1f1 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -209,9 +209,9 @@
 281 pascal DrvSetPrinterData(ptr ptr ptr ptr long) DrvSetPrinterData
 282 pascal DrvGetPrinterData(ptr ptr ptr ptr long ptr) DrvGetPrinterData
 299 stub ENGINEGETCHARWIDTHEX
-300 pascal EnginEnumerateFont(ptr segptr long) EngineEnumerateFont
+300 pascal EngineEnumerateFont(ptr segptr long) EngineEnumerateFont
 301 stub ENGINEDELETEFONT
-302 pascal EnginRealizeFont(ptr ptr ptr) EngineRealizeFont
+302 pascal EngineRealizeFont(ptr ptr ptr) EngineRealizeFont
 303 stub ENGINEGETCHARWIDTH
 304 stub ENGINESETFONTCONTEXT
 305 stub ENGINEGETGLYPHBMP
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index c20eeaa..a7033df 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -294,7 +294,7 @@
 0286 stub RemoveFontResourceW
 0287 stdcall ResetDCA(long ptr) ResetDC32A
 0288 stdcall ResetDCW(long ptr) ResetDC32W
-0289 stub ResizePalette
+0289 stdcall ResizePalette(long long) ResizePalette
 0290 stdcall RestoreDC(long long) RestoreDC32
 0291 stdcall RoundRect(long long long long long long long) RoundRect32
 0292 stdcall SaveDC(long) SaveDC32
@@ -332,7 +332,7 @@
 0323 stub SetMetaFileBitsEx
 0324 stub SetMetaRgn
 0325 stub SetMiterLimit
-0326 stub SetPaletteEntries
+0326 stdcall SetPaletteEntries(long long long ptr) SetPaletteEntries
 0327 stdcall SetPixel(long long long long) SetPixel32
 0328 stub SetPixelFormat
 0329 stub SetPixelV
@@ -341,7 +341,7 @@
 0332 stdcall SetRectRgn(long long long long long) SetRectRgn
 0333 stdcall SetRelAbs(long long) SetRelAbs32
 0334 stdcall SetStretchBltMode(long long) SetStretchBltMode32
-0335 stub SetSystemPaletteUse
+0335 stdcall SetSystemPaletteUse(long long) SetSystemPaletteUse
 0336 stdcall SetTextAlign(long long) SetTextAlign32
 0337 stdcall SetTextCharacterExtra(long long) SetTextCharacterExtra32
 0338 stdcall SetTextColor(long long) SetTextColor
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index c7d01b9..d934dad 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -103,7 +103,7 @@
 104 stub GetCodeInfo
 105 pascal16 GetExeVersion() GetExeVersion
 106 pascal SetSwapAreaSize(word) SetSwapAreaSize
-107 pascal16 SetErrorMode(word) SetErrorMode
+107 pascal16 SetErrorMode(word) SetErrorMode16
 108 pascal16 SwitchStackTo(word word word) SwitchStackTo
 109 register SwitchStackBack() SwitchStackBack
 110 pascal16 PatchCodeHandle(word) PatchCodeHandle
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index a9dcba4..fa859e4 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -30,7 +30,7 @@
 0025 stub CmdBatNotification
 0026 stub CommConfigDialogA
 0027 stub CommConfigDialogW
-0028 stub CompareFileTime
+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
@@ -65,7 +65,7 @@
 0060 stub CreateSemaphoreA
 0061 stub CreateSemaphoreW
 0062 stub CreateTapePartition
-0063 stub CreateThread
+0063 stdcall CreateThread(ptr long ptr long long ptr) CreateThread
 0064 stub CreateVirtualBuffer
 0065 stub DebugActiveProcess
 0066 stub DebugBreak
@@ -88,12 +88,12 @@
 0083 stub EnumCalendarInfoW
 0084 stub EnumDateFormatsA
 0085 stub EnumDateFormatsW
-0086 stub EnumResourceLanguagesA
-0087 stub EnumResourceLanguagesW
-0088 stub EnumResourceNamesA
-0089 stub EnumResourceNamesW
-0090 stub EnumResourceTypesA
-0091 stub EnumResourceTypesW
+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
@@ -407,7 +407,7 @@
 0402 stub OpenProfileUserMapping
 0403 stub OpenSemaphoreA
 0404 stub OpenSemaphoreW
-0405 stub OutputDebugStringA
+0405 stdcall OutputDebugStringA(ptr) OutputDebugString
 0406 stub OutputDebugStringW
 0407 stub PeekConsoleInputA
 0408 stub PeekConsoleInputW
@@ -420,7 +420,7 @@
 0415 stdcall QueryPerformanceCounter(ptr) QueryPerformanceCounter
 0416 stub QueryPerformanceFrequency
 0417 stub QueryWin31IniFilesMappedToRegistry
-0418 stdcall RaiseException(long long long ptr) RaiseException
+0418 register RaiseException(long long long ptr) RaiseException
 0419 stdcall ReadConsoleA(long ptr long ptr ptr) ReadConsole32A
 0420 stub ReadConsoleInputA
 0421 stub ReadConsoleInputW
@@ -445,7 +445,7 @@
 0440 stub ResumeThread
 0441 stdcall RtlFillMemory(ptr long long) RtlFillMemory
 0442 stdcall RtlMoveMemory(ptr ptr long) RtlMoveMemory
-0443 stdcall RtlUnwind(ptr long ptr long) RtlUnwind
+0443 register RtlUnwind(ptr long ptr long) RtlUnwind
 0444 stdcall RtlZeroMemory(ptr long) RtlZeroMemory
 0445 stub ScrollConsoleScreenBufferA
 0446 stub ScrollConsoleScreenBufferW
@@ -488,7 +488,7 @@
 0483 stdcall SetEndOfFile(long) SetEndOfFile
 0484 stdcall SetEnvironmentVariableA(ptr ptr) SetEnvironmentVariable32A
 0485 stdcall SetEnvironmentVariableW(ptr ptr) SetEnvironmentVariable32W
-0486 stdcall SetErrorMode(long) SetErrorMode
+0486 stdcall SetErrorMode(long) SetErrorMode32
 0487 	stdcall	SetEvent(long) SetEvent
 0488 stdcall SetFileApisToANSI() SetFileApisToANSI
 0489 stdcall SetFileApisToOEM() SetFileApisToOEM
@@ -518,7 +518,7 @@
 0513 stub SetThreadLocale
 0514 stdcall SetThreadPriority(long long) SetThreadPriority
 0515 stdcall SetTimeZoneInformation(ptr) SetTimeZoneInformation
-0516 stdcall SetUnhandledExceptionFilter(ptr) SetUnhandledExceptionFilter
+0516 stdcall SetUnhandledExceptionFilter(ptr) THUNK_SetUnhandledExceptionFilter
 0517 stub SetVDMCurrentDirectories
 0518 stub SetVolumeLabelA
 0519 stub SetVolumeLabelW
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index ae04afa..e23d3cc 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -4,7 +4,7 @@
 #1	pascal	Inquire
 #2	pascal	Enable
 #3	pascal	Disable
-4   pascal16 ToAscii(word word ptr ptr word) ToAscii
+4   pascal16 ToAscii(word word ptr ptr word) ToAscii16
 5   pascal16 AnsiToOem(ptr ptr) AnsiToOem16
 6   pascal16 OemToAnsi(ptr ptr) OemToAnsi16
 7   return   SetSpeed 2 65535
@@ -12,9 +12,9 @@
 #126	pascal	GetTableSeg
 #127	pascal	NewTable
 128 pascal   OemKeyScan(word) OemKeyScan
-129 pascal16 VkKeyScan(byte) VkKeyScan
-130 pascal16 GetKeyboardType(byte) GetKeyboardType
-131 pascal16 MapVirtualKey(word word) MapVirtualKey
+129 pascal16 VkKeyScan(byte) VkKeyScan16
+130 pascal16 GetKeyboardType(byte) GetKeyboardType16
+131 pascal16 MapVirtualKey(word word) MapVirtualKey16
 132 pascal16 GetKbCodePage() GetKbCodePage
 133 pascal16 GetKeyNameText(long ptr word) GetKeyNameText16
 134 pascal16 AnsiToOemBuff(ptr ptr word) AnsiToOemBuff16
diff --git a/if1632/ntdll.spec b/if1632/ntdll.spec
index 48ece57..45261b4 100644
--- a/if1632/ntdll.spec
+++ b/if1632/ntdll.spec
@@ -863,7 +863,7 @@
 859 stub __eFYL2XP1
 860 stub __eGetStatusWord
 861 stub _alloca_probe
-862 stub _chkstk
+862 return _chkstk 0 0
 863 stub _fltused
 864 stub _ftol
 865 stub _itoa
diff --git a/if1632/relay.c b/if1632/relay.c
index 8de8495..75b4eb8 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -217,28 +217,26 @@
  */
 void RELAY_DebugCallFrom32( int *stack, int nb_args )
 {
-    int *parg;
+    int *parg, i;
 
     if (!debugging_relay) return;
     printf( "Call %s(", BUILTIN_GetEntryPoint32( (void *)stack[-2] ));
-    if (nb_args > 0)
+    for (i = nb_args & 0x7fffffff, parg = &stack[2]; i; parg++, i--)
     {
-        for (parg = &stack[2]; nb_args; parg++, nb_args--)
-        {
-            printf( "%08x", *parg );
-            if (nb_args > 1) printf( "," );
-        }
+        printf( "%08x", *parg );
+        if (i > 1) printf( "," );
     }
     printf( ") ret=%08x\n", stack[1] );
-    if (nb_args == -1)  /* Register function */
+    if (nb_args & 0x80000000)  /* Register function */
     {
         CONTEXT *context = (CONTEXT *)((BYTE *)stack - sizeof(CONTEXT) - 8);
         printf( " EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
                 context->Eax, context->Ebx, context->Ecx, context->Edx,
                 context->Esi, context->Edi );
-        printf( " EBP=%08lx ESP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
-                context->Ebp, context->Esp, context->SegDs, context->SegEs,
-                context->SegFs, context->SegGs, context->EFlags );
+        printf( " EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+                context->Ebp, context->Esp, context->Eip, context->SegDs,
+                context->SegEs, context->SegFs, context->SegGs,
+                context->EFlags );
     }
 }
 
@@ -261,15 +259,16 @@
     if (!debugging_relay) return;
     printf( "Ret  %s() retval=%08x ret=%08x\n",
             BUILTIN_GetEntryPoint32( (void *)stack[-2] ), ret_val, stack[1] );
-    if (nb_args == -1)  /* Register function */
+    if (nb_args & 0x80000000)  /* Register function */
     {
         CONTEXT *context = (CONTEXT *)((BYTE *)stack - sizeof(CONTEXT) - 8);
         printf( " EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
                 context->Eax, context->Ebx, context->Ecx, context->Edx,
                 context->Esi, context->Edi );
-        printf( " EBP=%08lx ESP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
-                context->Ebp, context->Esp, context->SegDs, context->SegEs,
-                context->SegFs, context->SegGs, context->EFlags );
+        printf( " EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+                context->Ebp, context->Esp, context->Eip, context->SegDs,
+                context->SegEs, context->SegFs, context->SegGs,
+                context->EFlags );
     }
 }
 
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 168f2eb..03299d7 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -11,6 +11,7 @@
 #include "module.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "except.h"
 
 typedef void (*RELAY)();
 
@@ -41,7 +42,7 @@
  */
 static THUNK *THUNK_Alloc( FARPROC32 func, RELAY relay )
 {
-    THUNK *thunk = HeapAlloc( SystemHeap, 0, sizeof(*thunk) );
+    THUNK *thunk = HeapAlloc( GetProcessHeap(), 0, sizeof(*thunk) );
     if (thunk)
     {
         thunk->popl_eax   = 0x58;
@@ -73,14 +74,14 @@
  */
 void THUNK_Free( THUNK *thunk )
 {
-    if (HEAP_IsInsideHeap( SystemHeap, 0, thunk ))
+    if (HEAP_IsInsideHeap( GetProcessHeap(), 0, thunk ))
     {
         THUNK **prev = &firstThunk;
         while (*prev && (*prev != thunk)) prev = &(*prev)->next;
         if (*prev)
         {
             *prev = thunk->next;
-            HeapFree( SystemHeap, 0, thunk );
+            HeapFree( GetProcessHeap(), 0, thunk );
             return;
         }
     }
@@ -396,6 +397,60 @@
     return EnumSystemLocales32W( (LOCALE_ENUMPROC32W)&thunk, flags );
 }
 
+/***********************************************************************
+ *           THUNK_EnumResourceLanguages32W   (KERNEL32.87)
+ */
+BOOL32 THUNK_EnumResourceLanguages32W( HMODULE32 hmod,LPCWSTR type,LPCWSTR name,ENUMRESLANGPROC32W func, LONG lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_5 );
+    return EnumResourceLanguages32W( hmod,type,name,(ENUMRESLANGPROC32W)&thunk, lParam );
+}
+
+/***********************************************************************
+ *           THUNK_EnumResourceLanguages32A   (KERNEL32.86)
+ */
+BOOL32 THUNK_EnumResourceLanguages32A( HMODULE32 hmod,LPCSTR type,LPCSTR name,ENUMRESLANGPROC32A func, LONG lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_5 );
+    return EnumResourceLanguages32A( hmod,type,name,(ENUMRESLANGPROC32A)&thunk, lParam );
+}
+
+/***********************************************************************
+ *           THUNK_EnumResourceNames32A   (KERNEL32.88)
+ */
+BOOL32 THUNK_EnumResourceNames32A( HMODULE32 hmod,LPCWSTR type,ENUMRESNAMEPROC32A func, LONG lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_4 );
+    return EnumResourceNames32A( hmod,type,(ENUMRESNAMEPROC32A)&thunk, lParam );
+}
+
+/***********************************************************************
+ *           THUNK_EnumResourceNames32W   (KERNEL32.89)
+ */
+BOOL32 THUNK_EnumResourceNames32W( HMODULE32 hmod,LPCWSTR type,ENUMRESNAMEPROC32W func, LONG lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_4 );
+    return EnumResourceNames32W( hmod,type,(ENUMRESNAMEPROC32W)&thunk, lParam );
+}
+
+/***********************************************************************
+ *           THUNK_EnumResourceTypes32A   (KERNEL32.90)
+ */
+BOOL32 THUNK_EnumResourceTypes32A( HMODULE32 hmod,ENUMRESTYPEPROC32A func, LONG lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_3 );
+    return EnumResourceTypes32A( hmod,(ENUMRESTYPEPROC32A)&thunk, lParam );
+}
+
+/***********************************************************************
+ *           THUNK_EnumResourceTypes32W   (KERNEL32.91)
+ */
+BOOL32 THUNK_EnumResourceTypes32W( HMODULE32 hmod,ENUMRESTYPEPROC32W func, LONG lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_3 );
+    return EnumResourceTypes32W( hmod,(ENUMRESTYPEPROC32W)&thunk, lParam );
+}
+
 
 /***********************************************************************
  *           THUNK_GrayString16   (USER.185)
@@ -464,6 +519,24 @@
 }
 
 
+/*************************************************************
+ *            THUNK_SetUnhandledExceptionFilter   (KERNEL32.516)
+ */
+LPTOP_LEVEL_EXCEPTION_FILTER THUNK_SetUnhandledExceptionFilter(
+                                          LPTOP_LEVEL_EXCEPTION_FILTER filter )
+{
+    LPTOP_LEVEL_EXCEPTION_FILTER old;
+    THUNK *thunk = THUNK_Alloc( (FARPROC16)filter, (RELAY)CallTo32_1 );
+    if (!thunk) return NULL;
+    old = SetUnhandledExceptionFilter( (LPTOP_LEVEL_EXCEPTION_FILTER)thunk );
+    if (!old) return NULL;
+    thunk = (THUNK *)old;
+    old = (LPTOP_LEVEL_EXCEPTION_FILTER)thunk->proc;
+    THUNK_Free( thunk );
+    return old;
+}
+
+
 static FARPROC16 defDCHookProc = NULL;
 
 /***********************************************************************
diff --git a/if1632/user.spec b/if1632/user.spec
index daa24c2..9493ead 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -105,7 +105,7 @@
 103 pascal16 MapDialogRect(word ptr) MapDialogRect16
 104 pascal16 MessageBeep(word) MessageBeep
 105 pascal16 FlashWindow(word word) FlashWindow
-106 pascal16 GetKeyState(word) GetKeyState
+106 pascal16 GetKeyState(word) GetKeyState16
 107 pascal   DefWindowProc(word word word long) DefWindowProc16
 108 pascal16 GetMessage(segptr word word word) GetMessage
 109 pascal16 PeekMessage(ptr word word word word) PeekMessage16
@@ -177,7 +177,7 @@
 175 pascal16 LoadBitmap(word segptr) LoadBitmap16
 176 pascal16 LoadString(word word ptr s_word) LoadString16
 177 pascal16 LoadAccelerators(word segptr) LoadAccelerators16
-178 pascal16 TranslateAccelerator(word word ptr) TranslateAccelerator
+178 pascal16 TranslateAccelerator(word word ptr) TranslateAccelerator16
 179 pascal16 GetSystemMetrics(word) GetSystemMetrics
 180 pascal   GetSysColor(word) GetSysColor
 181 pascal16 SetSysColors(word ptr ptr) SetSysColors
@@ -251,7 +251,7 @@
 246 stub ExitWindowsExec
 247 pascal16 GetCursor() GetCursor
 248 pascal16 GetOpenClipboardWindow() GetOpenClipboardWindow
-249 pascal16 GetAsyncKeyState(word) GetAsyncKeyState
+249 pascal16 GetAsyncKeyState(word) GetAsyncKeyState16
 250 pascal16 GetMenuState(word word word) GetMenuState16
 251 pascal   SendDriverMessage(word word long long) SendDriverMessage
 252 pascal16 OpenDriver(ptr ptr long) OpenDriver
diff --git a/if1632/user32.spec b/if1632/user32.spec
index 7c51012..bf7f131 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -104,7 +104,7 @@
 0097 stub DdeDisconnectList
 0098 stub DdeEnableCallback
 0099 stub DdeFreeDataHandle
-0100 stub DdeFreeStringHandle
+0100 return DdeFreeStringHandle 8 0
 0101 stub DdeGetData
 0102 return DdeGetLastError 4 0
 0103 stub DdeGetQualityOfService
@@ -122,7 +122,7 @@
 0115 stub DdeSetQualityOfService
 0116 stub DdeSetUserHandle
 0117 stub DdeUnaccessData
-0118 stub DdeUninitialize
+0118 return DdeUninitialize 4 0
 0119 stdcall DefDlgProcA(long long long long) DefDlgProc32A
 0120 stdcall DefDlgProcW(long long long long) DefDlgProc32W
 0121 stdcall DefFrameProcA(long long long long long) DefFrameProc32A
@@ -210,7 +210,7 @@
 0203 stub FreeDDElParam
 0204 stdcall GetActiveWindow() GetActiveWindow32
 0205 stdcall GetAppCompatFlags(long) GetAppCompatFlags
-0206 stdcall GetAsyncKeyState(long) GetAsyncKeyState
+0206 stdcall GetAsyncKeyState(long) GetAsyncKeyState32
 0207 stdcall GetCapture() GetCapture32
 0208 stdcall GetCaretBlinkTime() GetCaretBlinkTime32
 0209 stdcall GetCaretPos(ptr) GetCaretPos32
@@ -250,15 +250,15 @@
 0243 stub GetInputState
 0244 stdcall GetInternalWindowPos(long ptr ptr) GetInternalWindowPos32
 0245 stub GetKBCodePage
-0246 stub GetKeyNameTextA
-0247 stub GetKeyNameTextW
-0248 stdcall GetKeyState(long) GetKeyState
+0246 stdcall GetKeyNameTextA(long ptr long) GetKeyNameText32A
+0247 stdcall GetKeyNameTextW(long ptr long) GetKeyNameText32W
+0248 stdcall GetKeyState(long) GetKeyState32
 0249 stub GetKeyboardLayout
 0250 stub GetKeyboardLayoutList
 0251 stub GetKeyboardLayoutNameA
 0252 stub GetKeyboardLayoutNameW
-0253 stub GetKeyboardState
-0254 stub GetKeyboardType
+0253 stdcall GetKeyboardState(ptr) GetKeyboardState
+0254 stdcall GetKeyboardType(long) GetKeyboardType32
 0255 stdcall GetLastActivePopup(long) GetLastActivePopup
 0256 stdcall GetMenu(long) GetMenu32
 0257 stdcall GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions
@@ -275,7 +275,7 @@
 0268 stdcall GetMenuStringW(long long ptr long long) GetMenuString32W
 0269 stdcall GetMessageA(ptr long long long) USER32_GetMessageA
 0270 stub GetMessageExtraInfo
-0271 stub GetMessagePos
+0271 stdcall GetMessagePos() GetMessagePos
 0272 stub GetMessageTime
 0273 stdcall GetMessageW(ptr long long long) USER32_GetMessageA
 0274 stdcall GetNextDlgGroupItem(long long long) GetNextDlgGroupItem32
@@ -313,10 +313,10 @@
 0306 stdcall GetWindowPlacement(long ptr) GetWindowPlacement32
 0307 stdcall GetWindowRect(long ptr) GetWindowRect32
 0308 stdcall GetWindowTextA(long ptr long) GetWindowText32A
-0309 stub GetWindowTextLengthA
-0310 stub GetWindowTextLengthW
+0309 stdcall GetWindowTextLengthA(long) GetWindowTextLength32A
+0310 stdcall GetWindowTextLengthW(long) GetWindowTextLength32W
 0311 stdcall GetWindowTextW(long ptr long) GetWindowText32W
-0312 stub GetWindowThreadProcessId
+0312 stdcall GetWindowThreadProcessId(long ptr) GetWindowThreadProcessId
 0313 stdcall GetWindowWord(long long) GetWindowWord
 0314 stub GrayStringA
 0315 stub GrayStringW
@@ -346,7 +346,7 @@
 0339 stdcall IsClipboardFormatAvailable(long) IsClipboardFormatAvailable
 0340 stub IsDialogMessage
 0341 stdcall IsDialogMessageA(long ptr) IsDialogMessage32A
-0342 stub IsDialogMessageW
+0342 stdcall IsDialogMessageW(long ptr) IsDialogMessage32W
 0343 stdcall IsDlgButtonChecked(long long) IsDlgButtonChecked32
 0344 stdcall IsIconic(long) IsIconic32
 0345 stdcall IsMenu(long) IsMenu32
@@ -386,17 +386,17 @@
 0379 stub LookupIconIdFromDirectoryEx
 0380 stub MBToWCSEx
 0381 stdcall MapDialogRect(long ptr) MapDialogRect32
-0382 stub MapVirtualKeyA
+0382 stdcall MapVirtualKeyA(long long) MapVirtualKey32A
 0383 stub MapVirtualKeyExA
-0384 stub MapVirtualKeyW
+0384 stdcall MapVirtualKeyW(long long) MapVirtualKey32A
 0385 stdcall MapWindowPoints(long long ptr long) MapWindowPoints32
 0386 stub MenuItemFromPoint
 0387 stub MenuWindowProcA
 0388 stub MenuWindowProcW
 0389 stdcall MessageBeep(long) MessageBeep
 0390 stdcall MessageBoxA(long ptr ptr long) MessageBox32A
-0391 stub MessageBoxExA
-0392 stub MessageBoxExW
+0391 stdcall MessageBoxExA(long ptr ptr long long) MessageBoxEx32A
+0392 stdcall MessageBoxExW(long ptr ptr long long) MessageBoxEx32W
 0393 stub MessageBoxIndirectA
 0394 stub MessageBoxIndirectW
 0395 stdcall MessageBoxW(long ptr ptr long) MessageBox32W
@@ -404,7 +404,7 @@
 0397 stdcall ModifyMenuW(long long long long ptr) ModifyMenu32W
 0398 stdcall MoveWindow(long long long long long long) MoveWindow32
 0399 stub MsgWaitForMultipleObjects
-0400 stub OemKeyScan
+0400 stdcall OemKeyScan(long) OemKeyScan
 0401 stdcall OemToCharA(ptr ptr) OemToChar32A
 0402 stdcall OemToCharBuffA(ptr ptr long) OemToCharBuff32A
 0403 stdcall OemToCharBuffW(ptr ptr long) OemToCharBuff32W
@@ -487,7 +487,7 @@
 0480 stdcall SetFocus(long) SetFocus32
 0481 return SetForegroundWindow 4 0
 0482 stdcall SetInternalWindowPos(long long ptr ptr) SetInternalWindowPos32
-0483 stub SetKeyboardState
+0483 stdcall SetKeyboardState(ptr) SetKeyboardState
 0484 stdcall SetLastErrorEx(long long) SetLastErrorEx
 0485 stub SetLogonNotifyWindow
 0486 stdcall SetMenu(long long) SetMenu32
@@ -549,14 +549,14 @@
 0542 stub TabbedTextOutW
 0543 stub TileChildWindows
 0544 stub TileWindows
-0545 stub ToAscii
+0545 stdcall ToAscii32(long long ptr ptr long) ToAscii32
 0546 stub ToAsciiEx
 0547 stub ToUnicode
 0548 stdcall TrackPopupMenu(long long long long long long ptr) TrackPopupMenu32
 0549 stdcall TrackPopupMenuEx(long long long long long ptr) TrackPopupMenuEx
-0550 stdcall TranslateAccelerator(long long ptr) TranslateAccelerator
-0551 stdcall TranslateAcceleratorA(long long ptr) TranslateAccelerator
-0552 stdcall TranslateAcceleratorW(long long ptr) TranslateAccelerator
+0550 stdcall TranslateAccelerator(long long ptr) TranslateAccelerator32
+0551 stdcall TranslateAcceleratorA(long long ptr) TranslateAccelerator32
+0552 stdcall TranslateAcceleratorW(long long ptr) TranslateAccelerator32
 0553 stub TranslateCharsetInfo
 0554 stub TranslateMDISysAccel
 0555 stdcall TranslateMessage(ptr) USER32_TranslateMessage
@@ -576,10 +576,10 @@
 0569 stub UserRegisterWowHandlers
 0570 stdcall ValidateRect(long ptr) ValidateRect32
 0571 stdcall ValidateRgn(long long) ValidateRgn32
-0572 stdcall VkKeyScanA(long) VkKeyScan
+0572 stdcall VkKeyScanA(long) VkKeyScan32A
 0573 stub VkKeyScanExA
 0574 stub VkKeyScanExW
-0575 stub VkKeyScanW
+0575 stdcall VkKeyScanW(long) VkKeyScan32W
 0576 stub WaitForInputIdle
 0577 stub WaitMessage
 0578 stdcall WinHelpA(long ptr long long) WinHelp32A
diff --git a/include/bitmap.h b/include/bitmap.h
index b4a731e..d3896e2 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -7,11 +7,12 @@
 #ifndef __WINE_BITMAP_H
 #define __WINE_BITMAP_H
 
-#include <X11/extensions/XShm.h>
 #include "gdi.h"
 #include "xmalloc.h"
 
 #ifdef PRELIMINARY_WING16_SUPPORT
+/* FIXME: this doesn't belong here */
+#include <X11/extensions/XShm.h>
 
 typedef struct
 {
@@ -52,8 +53,6 @@
 extern INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer );
 extern INT32 BITMAP_GetObject32( BITMAPOBJ * bmp, INT32 count, LPVOID buffer );
 extern BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bitmap );
-extern HBITMAP16 BITMAP_SelectObject( DC * dc, HBITMAP16 hbitmap,
-                                      BITMAPOBJ * bmp );
 
   /* objects/dib.c */
 extern int DIB_GetImageWidthBytes( int width, int depth );
diff --git a/include/brush.h b/include/brush.h
index f03ad8f..8c136d9 100644
--- a/include/brush.h
+++ b/include/brush.h
@@ -16,10 +16,10 @@
     LOGBRUSH32  logbrush;
 } BRUSHOBJ;
 
-extern BOOL32 BRUSH_Init(void);
+#define NB_HATCH_STYLES  6
+
 extern INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer );
 extern INT32 BRUSH_GetObject32( BRUSHOBJ * brush, INT32 count, LPSTR buffer );
 extern BOOL32 BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush );
-extern HBRUSH32 BRUSH_SelectObject(DC * dc, HBRUSH32 hbrush, BRUSHOBJ * brush);
 
 #endif  /* __WINE_BRUSH_H */
diff --git a/include/callback.h b/include/callback.h
index 2f603c2..9dcf165 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -77,6 +77,7 @@
 extern LONG CallTo32_2( FARPROC32, DWORD, DWORD );
 extern LONG CallTo32_3( FARPROC32, DWORD, DWORD, DWORD );
 extern LONG CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD );
+extern LONG CallTo32_5( FARPROC32, DWORD, DWORD, DWORD, DWORD, DWORD );
 
 #define CallTaskStart32( func ) \
     CallTo32_0( func )
diff --git a/include/crtdll.h b/include/crtdll.h
index 916e9b4..c5d9f4e 100644
--- a/include/crtdll.h
+++ b/include/crtdll.h
@@ -10,4 +10,16 @@
 #define CRTDLL_LC_MIN		LC_ALL
 #define CRTDLL_LC_MAX		LC_TIME
 
+/* ctype defines */
+#define CRTDLL_UPPER		0x1
+#define CRTDLL_LOWER		0x2
+#define CRTDLL_DIGIT		0x4
+#define CRTDLL_SPACE		0x8
+#define CRTDLL_PUNCT		0x10
+#define CRTDLL_CONTROL		0x20
+#define CRTDLL_BLANK		0x40
+#define CRTDLL_HEX		0x80
+#define CRTDLL_LEADBYTE		0x8000
+#define CRTDLL_ALPHA		(0x0100|CRTDLL_UPPER|CRTDLL_LOWER)
+
 #endif
diff --git a/include/debugger.h b/include/debugger.h
index 91f5121..1a1f02a 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -309,7 +309,6 @@
 extern void DEBUG_NukePath(void);
 
   /* debugger/dbg.y */
-extern void DEBUG_EnterDebugger(void);
 extern void wine_debug( int signal, SIGCONTEXT *regs );
 
 #endif  /* __WINE_DEBUGGER_H */
diff --git a/include/except.h b/include/except.h
index ff68c39..d55146b 100644
--- a/include/except.h
+++ b/include/except.h
@@ -7,129 +7,6 @@
 #define __WINE_EXCEPT_H
 
 #include "winnt.h"
-/*
- * exception codes
- */
- 
-#define STATUS_WAIT_0                    0x00000000
-#define STATUS_ABANDONED_WAIT_0          0x00000080
-#define STATUS_USER_APC                  0x000000C0
-#define STATUS_TIMEOUT                   0x00000102
-#define STATUS_PENDING                   0x00000103
-#define STATUS_DATATYPE_MISALIGNMENT     0x80000002
-#define STATUS_BREAKPOINT                0x80000003
-#define STATUS_SINGLE_STEP               0x80000004
-#define STATUS_ACCESS_VIOLATION          0xC0000005
-#define STATUS_IN_PAGE_ERROR             0xC0000006
-#define STATUS_NO_MEMORY                 0xC0000017
-#define STATUS_ILLEGAL_INSTRUCTION       0xC000001D
-#define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025
-#define STATUS_INVALID_DISPOSITION       0xC0000026
-#define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008C
-#define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008D
-#define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008E
-#define STATUS_FLOAT_INEXACT_RESULT      0xC000008F
-#define STATUS_FLOAT_INVALID_OPERATION   0xC0000090
-#define STATUS_FLOAT_OVERFLOW            0xC0000091
-#define STATUS_FLOAT_STACK_CHECK         0xC0000092
-#define STATUS_FLOAT_UNDERFLOW           0xC0000093
-#define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094
-#define STATUS_INTEGER_OVERFLOW          0xC0000095
-#define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096
-#define STATUS_STACK_OVERFLOW            0xC00000FD
-#define STATUS_CONTROL_C_EXIT            0xC000013A
-
-#define EXCEPTION_ACCESS_VIOLATION      STATUS_ACCESS_VIOLATION
-#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
-#define EXCEPTION_BREAKPOINT            STATUS_BREAKPOINT
-#define EXCEPTION_SINGLE_STEP           STATUS_SINGLE_STEP
-#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
-#define EXCEPTION_FLT_DENORMAL_OPERAND  STATUS_FLOAT_DENORMAL_OPERAND
-#define EXCEPTION_FLT_DIVIDE_BY_ZERO    STATUS_FLOAT_DIVIDE_BY_ZERO
-#define EXCEPTION_FLT_INEXACT_RESULT    STATUS_FLOAT_INEXACT_RESULT
-#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
-#define EXCEPTION_FLT_OVERFLOW          STATUS_FLOAT_OVERFLOW
-#define EXCEPTION_FLT_STACK_CHECK       STATUS_FLOAT_STACK_CHECK
-#define EXCEPTION_FLT_UNDERFLOW         STATUS_FLOAT_UNDERFLOW
-#define EXCEPTION_INT_DIVIDE_BY_ZERO    STATUS_INTEGER_DIVIDE_BY_ZERO
-#define EXCEPTION_INT_OVERFLOW          STATUS_INTEGER_OVERFLOW
-#define EXCEPTION_PRIV_INSTRUCTION      STATUS_PRIVILEGED_INSTRUCTION
-#define EXCEPTION_IN_PAGE_ERROR         STATUS_IN_PAGE_ERROR
-
-/*
- * return values from the actual exception handlers
- */
-
-#define ExceptionContinueExecution 0
-#define ExceptionContinueSearch    1
-#define ExceptionNestedException   2
-#define ExceptionCollidedUnwind    3
- 
-/*
- * return values from filters in except() and from UnhandledExceptionFilter
- */
- 
-#define EXCEPTION_EXECUTE_HANDLER        1
-#define EXCEPTION_CONTINUE_SEARCH        0
-#define EXCEPTION_CONTINUE_EXECUTION    -1
-
-/*
- * from OS/2 2.0 exception handling
- * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD
- */
-
-#define EH_NONCONTINUABLE   0x01
-#define EH_UNWINDING        0x02
-#define EH_EXIT_UNWIND      0x04
-#define EH_STACK_INVALID    0x08
-#define EH_NESTED_CALL      0x10
-
-#define EXCEPTION_CONTINUABLE        0
-#define EXCEPTION_NONCONTINUABLE     EH_NONCONTINUABLE
- 
-/*
- * The exception record used by Win32 to give additional information 
- * about exception to exception handlers.
- */
-
-#define EXCEPTION_MAXIMUM_PARAMETERS 15
-
-typedef struct __EXCEPTION_RECORD
-{
-    DWORD    ExceptionCode;
-    DWORD    ExceptionFlags;
-    struct __EXCEPTION_RECORD *ExceptionRecord;
-
-    LPVOID   ExceptionAddress;
-    DWORD    NumberParameters;
-    DWORD    ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
-} EXCEPTION_RECORD;
-
-typedef struct __EXCEPTION_RECORD_MIN
-{
-    DWORD    ExceptionCode;
-    DWORD    ExceptionFlags;
-    struct __EXCEPTION_RECORD *ExceptionRecord;
-
-    LPVOID   ExceptionAddress;
-    DWORD    NumberParameters;
-    DWORD    ExceptionInformation[0];
-} EXCEPTION_RECORD_MIN;
-
-typedef struct __EXCEPTION_RECORD *PEXCEPTION_RECORD;
-
-/*
- * The exception pointers structure passed to exception filters
- * in except() and the UnhandledExceptionFilter().
- */
- 
-typedef struct __EXCEPTION_POINTERS 
-{
-  PEXCEPTION_RECORD  ExceptionRecord;
-  PCONTEXT           ContextRecord;
-} EXCEPTION_POINTERS;
-
-typedef struct __EXCEPTION_POINTERS *PEXCEPTION_POINTERS;
 
 /*
  * the function pointer to a exception handler
@@ -144,16 +21,6 @@
                                       LPVOID                     pdispatcher);
 
 /*
- * function pointer to a UnhandledExceptionFilter();
- */
-
-typedef long (*__PTOP_EXCFILTER)
-                   (PEXCEPTION_POINTERS ExceptionInfo);
-
-typedef __PTOP_EXCFILTER PTOP_LEVER_EXCEPTION_FILTER;
-typedef __PTOP_EXCFILTER LPTOP_LEVEL_EXCEPTION_FILTER;
-                                 
-/*
  * The exception frame, used for registering exception handlers 
  * Win32 cares only about this, but compilers generally emit 
  * larger exception frames for their own use.
@@ -163,37 +30,16 @@
 {
   struct __EXCEPTION_FRAME *Prev;
   PEXCEPTION_HANDLER       Handler;
-} EXCEPTION_FRAME;
-
-typedef struct __EXCEPTION_FRAME *PEXCEPTION_FRAME;
-
-extern PEXCEPTION_FRAME  TebExceptionFrame asm("%fs:0");
-
-#define EXC_GetFrame()   TebExceptionFrame
-#define EXC_SetFrame(a) (TebExceptionFrame=(a))
+} EXCEPTION_FRAME, *PEXCEPTION_FRAME;
 
 /*
  * Function definitions  
  */
  
-void EXC_RaiseException(DWORD exccode, DWORD excflags, 
-                        DWORD nargs, const LPDWORD pargs,
-                        PCONTEXT pcontext); 
+void RaiseException(DWORD exccode, DWORD excflags, 
+                    DWORD nargs, const LPDWORD pargs,
+                    PCONTEXT pcontext /* Wine additional parameter */ ); 
                         
-void EXC_RtlUnwind( PEXCEPTION_FRAME pestframe,
-                    LPVOID unusedEIP,
-                    PEXCEPTION_RECORD pexcrec,
-                    DWORD contextEAX,
-                    PCONTEXT pcontext );
-                    
-DWORD EXC_CallUnhandledExceptionFilter( PEXCEPTION_RECORD precord,
-                                        PCONTEXT          pcontext);
-
-void EXC_Init(void);
-
-BOOL RaiseException(DWORD exccode, DWORD excflags,
-                    DWORD nargs, const LPDWORD pargs);
-
 /*
  *  this undocumented function is called when an exception
  *  handler wants all the frames to be unwound. RtlUnwind
@@ -208,11 +54,10 @@
  *  context.   
  */
 
-BOOL RtlUnwind( PEXCEPTION_FRAME pestframe,
+void RtlUnwind( PEXCEPTION_FRAME pestframe,
                 LPVOID unusedEIP,
                 PEXCEPTION_RECORD pexcrec,
-                DWORD contextEAX );
-
-DWORD UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers);
+                DWORD contextEAX,
+                PCONTEXT pcontext /* Wine additional parameter */ );
 
 #endif  /* __WINE_EXCEPT_H */
diff --git a/include/font.h b/include/font.h
index 641d029..12456ad 100644
--- a/include/font.h
+++ b/include/font.h
@@ -20,6 +20,10 @@
 
 #pragma pack(4)
 
+#define FONTCACHE 	32	/* dynamic font cache size */
+#define MAX_FONTS	256
+extern LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
+
 /* may be switched... */
 #define GGO_BITMAP	0x4F4D
 #define GGO_NATIVE	0x4F50
@@ -43,6 +47,9 @@
 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 HFONT16 FONT_SelectObject( DC * dc, HFONT16 hfont, FONTOBJ * font );
+extern int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz);
+extern void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
+                            TEXTMETRIC16 * metrics );
+
 
 #endif /* __WINE_FONT_H */
diff --git a/include/hook.h b/include/hook.h
index 21c0196..b9ea056 100644
--- a/include/hook.h
+++ b/include/hook.h
@@ -9,11 +9,12 @@
 
 #include "windows.h"
 
-#define HOOK_WIN16   0x0
-#define HOOK_WIN32   0x1
-#define HOOK_UNICODE 0x2
+#define HOOK_WIN16	0x0
+#define HOOK_WIN32A	0x1
+#define HOOK_WIN32W	0x2
 
-#define HOOK_MAPTYPE (HOOK_WIN32 | HOOK_UNICODE)
+/* hook type mask */
+#define HOOK_MAPTYPE (3)
 
 extern HOOKPROC16 HOOK_GetProc16( HHOOK hhook );
 extern BOOL32 HOOK_IsHooked( INT16 id );
diff --git a/include/metafiledrv.h b/include/metafiledrv.h
index dfb4b92..a8e67a9 100644
--- a/include/metafiledrv.h
+++ b/include/metafiledrv.h
@@ -66,6 +66,7 @@
 extern BOOL32 MFDRV_Polygon( struct tagDC *dc, LPPOINT32 pt, INT32 count );
 extern BOOL32 MFDRV_PolyPolygon( struct tagDC *dc, LPPOINT32 pt, LPINT32 counts,
 				 UINT32 polygons);
+extern HGDIOBJ32 MFDRV_SelectObject( DC *dc, HGDIOBJ32 handle );
 extern BOOL32 MFDRV_ExtFloodFill( struct tagDC *dc, INT32 x, INT32 y,
 				  COLORREF color, UINT32 fillType );
 extern BOOL32 MFDRV_ExtTextOut( struct tagDC *dc, INT32 x, INT32 y,
diff --git a/include/miscemu.h b/include/miscemu.h
index bacc10e..04e523a 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -35,9 +35,6 @@
 /* msdos/int1a.c */
 extern DWORD INT1A_GetTicksSinceMidnight(void);
 
-/* misc/cpu.c */
-extern int runtime_cpu(void);
-
 #define INT_BARF(context,num) \
     fprintf( stderr, "int%x: unknown/not implemented parameters:\n" \
                      "int%x: AX %04x, BX %04x, CX %04x, DX %04x, " \
diff --git a/include/pe_image.h b/include/pe_image.h
index 1130ba8..12f6895 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -23,5 +23,15 @@
 extern int PE_unloadImage(HMODULE32 hModule);
 extern FARPROC32 PE_FindExportedFunction(struct pe_data *pe, LPCSTR funcName);
 extern void my_wcstombs(char * result, u_short * source, int len);
+extern PE_EnumResourceTypes32A(HMODULE32,ENUMRESTYPEPROC32A,LONG);
+extern PE_EnumResourceTypes32W(HMODULE32,ENUMRESTYPEPROC32W,LONG);
+extern PE_EnumResourceNames32A(HMODULE32,LPCSTR,ENUMRESNAMEPROC32A,LONG);
+extern PE_EnumResourceNames32W(HMODULE32,LPCWSTR,ENUMRESNAMEPROC32W,LONG);
+extern PE_EnumResourceLanguages32A(HMODULE32,LPCSTR,LPCSTR,ENUMRESLANGPROC32A,LONG);
+extern PE_EnumResourceLanguages32W(HMODULE32,LPCWSTR,LPCWSTR,ENUMRESLANGPROC32W,LONG);
+extern HRSRC32 PE_FindResourceEx32W(HINSTANCE32,LPCWSTR,LPCWSTR,WORD);
+extern DWORD PE_SizeofResource32(HINSTANCE32,HRSRC32);
+extern HGLOBAL32 PE_LoadResource32(HINSTANCE32,HRSRC32);
+extern void PE_InitializeDLLs(HMODULE16);
 
 #endif /* __WINE_PE_IMAGE_H */
diff --git a/include/pen.h b/include/pen.h
index ab4f5b2..effed43 100644
--- a/include/pen.h
+++ b/include/pen.h
@@ -18,6 +18,5 @@
 
 extern INT16 PEN_GetObject16( PENOBJ * pen, INT16 count, LPSTR buffer );
 extern INT32 PEN_GetObject32( PENOBJ * pen, INT32 count, LPSTR buffer );
-extern HPEN32 PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen );
 
 #endif  /* __WINE_PEN_H */
diff --git a/include/process.h b/include/process.h
index 2c018e7..dc6b421 100644
--- a/include/process.h
+++ b/include/process.h
@@ -9,6 +9,7 @@
 
 #include "windows.h"
 #include "winbase.h"
+#include "winnt.h"
 #include "handle32.h"
 #include "task.h"
 
@@ -82,7 +83,7 @@
     DWORD            process_dword;    /* 90 Unknown */
     struct _PDB32   *group;            /* 94 Process group */
     void            *exe_modref;       /* 98 MODREF for the process EXE */
-    void            *top_exc_filter;   /* 9c Top exception filter */
+    LPTOP_LEVEL_EXCEPTION_FILTER top_filter; /* 9c Top exception filter */
     DWORD            priority;         /* a0 Priority level */
     HANDLE32         heap_list;        /* a4 Head of process heap list */
     void            *heap_handles;     /* a8 Head of heap handles list */
diff --git a/include/selectors.h b/include/selectors.h
index f807403..673a2f5 100644
--- a/include/selectors.h
+++ b/include/selectors.h
@@ -40,9 +40,9 @@
 #define WINE_CODE_SELECTOR 0x17
 #endif  /* svr4 || SCO_DS */
 
-#ifdef __EMX__
-#define WINE_DATA_SELECTOR 0x00 /* FIXME: This is wrong */
-#define WINE_CODE_SELECTOR 0x00
+#ifdef __EMX__ /* Is this always true? */
+#define WINE_DATA_SELECTOR 0x53
+#define WINE_CODE_SELECTOR 0x5b
 #endif  /* OS/2 */
 
 #else  /* WINELIB */
diff --git a/include/sigcontext.h b/include/sigcontext.h
index 157bd91..55c60c2 100644
--- a/include/sigcontext.h
+++ b/include/sigcontext.h
@@ -59,7 +59,40 @@
 #endif  /* svr4 || SCO_DS */
 
 #ifdef __EMX__
-typedef struct CONTEXTRECORD SIGCONTEXT;
+typedef unsigned long ULONG;
+typedef unsigned short USHORT;
+typedef struct _fpreg		/* Note 1 */
+{
+  ULONG	 losig;
+  ULONG	 hisig;
+  USHORT signexp;
+} FPREG;
+typedef FPREG *PFPREG;
+
+typedef struct _CONTEXT		/* Note 1 */
+{
+  ULONG ContextFlags;
+  ULONG ctx_env[7];
+  FPREG ctx_stack[8];
+  ULONG ctx_SegGs;
+  ULONG ctx_SegFs;
+  ULONG ctx_SegEs;
+  ULONG ctx_SegDs;
+  ULONG ctx_RegEdi;
+  ULONG ctx_RegEsi;
+  ULONG ctx_RegEax;
+  ULONG ctx_RegEbx;
+  ULONG ctx_RegEcx;
+  ULONG ctx_RegEdx;
+  ULONG ctx_RegEbp;
+  ULONG ctx_RegEip;
+  ULONG ctx_SegCs;
+  ULONG ctx_EFlags;
+  ULONG ctx_RegEsp;
+  ULONG ctx_SegSs;
+} SIGCONTEXT;
+/*typedef CONTEXTRECORD *PCONTEXTRECORD;*/
+
 #endif  /* __EMX__ */
 
 
@@ -138,12 +171,12 @@
 #define EDI_sig(context)     ((context)->ctx_RegEdi)
 #define EBP_sig(context)     ((context)->ctx_RegEbp)
 #define ESP_sig(context)     ((context)->ctx_RegEsp)
-#define CS_sig(context)      ((context)->ctx_SegCS)
-#define DS_sig(context)      ((context)->ctx_SegDS)
-#define ES_sig(context)      ((context)->ctx_SegES)
-#define SS_sig(context)      ((context)->ctx_SegSS)
-#define FS_sig(context)      ((context)->ctx_SegFS)
-#define GS_sig(context)      ((context)->ctx_SegGS)
+#define CS_sig(context)      ((context)->ctx_SegCs)
+#define DS_sig(context)      ((context)->ctx_SegDs)
+#define ES_sig(context)      ((context)->ctx_SegEs)
+#define SS_sig(context)      ((context)->ctx_SegSs)
+#define FS_sig(context)      ((context)->ctx_SegFs)
+#define GS_sig(context)      ((context)->ctx_SegGs)
 #define EFL_sig(context)     ((context)->ctx_EFlags)
 #define EIP_sig(context)     ((context)->ctx_RegEip)
 
diff --git a/include/thread.h b/include/thread.h
index 11d9cbb..ec3fa4a 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -8,6 +8,7 @@
 #define __WINE_THREAD_H
 
 #include "process.h"
+#include "winnt.h"
 
 /* Thread exception block */
 typedef struct _TEB
@@ -35,7 +36,7 @@
     K32OBJ       header;         /*  00 Kernel object header */
     PDB32       *process;        /*  08 Process owning this thread */
     K32OBJ      *event;          /*  0c Thread event */
-    TEB          teb;            /*  10 Thread information block */
+    TEB          teb;            /*  10 Thread exception block */
     PDB32       *process2;       /*  40 Same as offset 08 (?) */
     DWORD        flags;          /*  44 Flags */
     DWORD        exit_code;      /*  48 Termination status */
@@ -52,7 +53,7 @@
     DWORD        last_error;     /*  70 Last error code */
     void        *debugger_CB;    /*  74 Debugger context block */
     DWORD        debug_thread;   /*  78 Thread debugging this one (?) */
-    void        *context;        /*  7c Thread register context */
+    void        *pcontext;       /*  7c Thread register context */
     DWORD        unknown3[3];    /*  80 Unknown */
     WORD         current_ss;     /*  8c Another 16-bit stack selector */
     WORD         pad2;           /*  8e */
@@ -69,11 +70,14 @@
     K32OBJ      *win16_mutex;    /* 1e8 Pointer to Win16 mutex */
     K32OBJ      *win32_mutex;    /* 1ec Pointer to KERNEL32 mutex */
     K32OBJ      *crit_section2;  /* 1f0 Another critical section */
-    DWORD        unknown6[2];    /* 1f4 Unknown */
+    DWORD        unknown6[3];    /* 1f4 Unknown */
+    /* The following are Wine-specific fields */
+    CONTEXT      context;        /* 200 Thread context */
 } THDB;
 
 
-extern THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size );
+extern THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size,
+                            LPTHREAD_START_ROUTINE start_addr );
 extern void THREAD_Destroy( K32OBJ *ptr );
 
 extern THDB *pCurrentThread;
diff --git a/include/winbase.h b/include/winbase.h
index e277353..919124f 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -38,12 +38,6 @@
 #define FS_CASE_IS_PRESERVED            FILE_CASE_PRESERVED_NAMES
 #define FS_UNICODE_STORED_ON_DISK       FILE_UNICODE_ON_DISK
 
-struct _EXCEPTION_POINTERS;
-
-typedef LONG (TOP_LEVEL_EXCEPTION_FILTER)(struct _EXCEPTION_POINTERS *);
-
-TOP_LEVEL_EXCEPTION_FILTER *SetUnhandledExceptionFilter(TOP_LEVEL_EXCEPTION_FILTER *func);
-
 /*WINAPI int  SetErrorMode(int);*/
 
 #define STATUS_SUCCESS                   0x00000000
diff --git a/include/windows.h b/include/windows.h
index 4d71ced..338bf13 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1825,6 +1825,12 @@
 #define OF_EXIST              0x4000
 #define OF_REOPEN             0x8000
 
+/* SetErrorMode values */
+#define SEM_FAILCRITICALERRORS      0x0001
+#define SEM_NOGPFAULTERRORBOX       0x0002
+#define SEM_NOALIGNMENTFAULTEXCEPT  0x0004
+#define SEM_NOOPENFILEERRORBOX      0x8000
+
 /* GetTempFileName() Flags */
 #define TF_FORCEDRIVE	        0x80
 
@@ -3667,7 +3673,11 @@
 #define VK_X                0x58
 #define VK_Y                0x59
 #define VK_Z                0x5A
-/*                          0x5B-0x5F  Undefined */
+
+#define VK_LWIN             0x5B
+#define VK_RWIN             0x5C
+#define VK_APPS             0x5D
+/*                          0x5E-0x5F Unassigned */
 #define VK_NUMPAD0          0x60
 #define VK_NUMPAD1          0x61
 #define VK_NUMPAD2          0x62
@@ -3711,16 +3721,37 @@
 /*                          0x88-0x8F  Unassigned */
 #define VK_NUMLOCK          0x90
 #define VK_SCROLL           0x91
-/*                          0x92-0xB9  Unassigned */
+/*                          0x92-0x9F  Unassigned */
+/*
+ * differencing between right and left shift/control/alt key.
+ * Used only by GetAsyncKeyState() and GetKeyState().
+ */
+#define VK_LSHIFT           0xA0
+#define VK_RSHIFT           0xA1
+#define VK_LCONTROL         0xA2
+#define VK_RCONTROL         0xA3
+#define VK_LMENU            0xA4
+#define VK_RMENU            0xA5
+/*                          0xA6-0xB9  Unassigned */
 /*                          0xBA-0xC0  OEM specific */
 /*                          0xC1-0xDA  Unassigned */
 /*                          0xDB-0xE4  OEM specific */
-/*                          0xE5       Unassigned */
+
+#define VK_PROCESSKEY       0xE5
+
 /*                          0xE6       OEM specific */
 /*                          0xE7-0xE8  Unassigned */
 /*                          0xE9-0xF5  OEM specific */
-/*                          0xF6-0xFE  Unassigned */
 
+#define VK_ATTN             0xF6
+#define VK_CRSEL            0xF7
+#define VK_EXSEL            0xF8
+#define VK_EREOF            0xF9
+#define VK_PLAY             0xFA
+#define VK_ZOOM             0xFB
+#define VK_NONAME           0xFC
+#define VK_PA1              0xFD
+#define VK_OEM_CLEAR        0xFE
   
 #define LMEM_FIXED          0   
 #define LMEM_MOVEABLE       0x0002
@@ -4597,6 +4628,21 @@
 
 #define PR_JOBSTATUS	0x0000
 
+typedef BOOL32 (*ENUMRESTYPEPROC32A)(HMODULE32 hModule, LPSTR type,LONG lParam);
+typedef BOOL32 (*ENUMRESTYPEPROC32W)(HMODULE32 hModule, LPWSTR type,LONG lParam);
+typedef BOOL32 (*ENUMRESNAMEPROC32A)(HMODULE32 hModule, LPCSTR type,
+				LPSTR name,LONG lParam);
+typedef BOOL32 (*ENUMRESNAMEPROC32W)(HMODULE32 hModule, LPCWSTR type,
+				LPWSTR name,LONG lParam);
+typedef BOOL32 (*ENUMRESLANGPROC32A)(HMODULE32 hModule, LPCSTR type,
+				LPCSTR name,WORD lang,LONG lParam);
+typedef BOOL32 (*ENUMRESLANGPROC32W)(HMODULE32 hModule, LPCWSTR type,
+				LPCWSTR name,WORD lang,LONG lParam);
+
+DECL_WINELIB_TYPE_AW(ENUMRESTYPEPROC);
+DECL_WINELIB_TYPE_AW(ENUMRESNAMEPROC);
+DECL_WINELIB_TYPE_AW(ENUMRESLANGPROC);
+
 #pragma pack(4)
 
 /* Declarations for functions that exist only in Win16 */
@@ -4637,6 +4683,7 @@
 HWND16     GetDesktopHwnd(void);
 HMODULE16  GetExePtr(HANDLE16);
 WORD       GetExeVersion(void);
+INT16      GetKbCodePage(VOID);
 INT16      GetInstanceData(HINSTANCE16,WORD,INT16);
 BOOL16     GetModuleName(HINSTANCE16,LPSTR,INT16);
 FARPROC16  GetMouseEventProc(void);
@@ -4650,6 +4697,7 @@
 DWORD      GetViewportOrg(HDC16);
 DWORD      GetWindowExt(HDC16);
 DWORD      GetWindowOrg(HDC16);
+DWORD      GetWinFlags(void);
 DWORD      GlobalDOSAlloc(DWORD);
 WORD       GlobalDOSFree(WORD);
 void       GlobalFreeAll(HGLOBAL16);
@@ -4720,6 +4768,7 @@
 BOOL32     CopyFile32A(LPCSTR,LPCSTR,BOOL32);
 BOOL32     CopyFile32W(LPCWSTR,LPCWSTR,BOOL32);
 #define    CopyFile WINELIB_NAME_AW(CopyFile)
+INT32      CompareFileTime(LPFILETIME,LPFILETIME);
 HFILE32    CreateFile32A(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE32);
 HFILE32    CreateFile32W(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE32);
 #define    CreateFile WINELIB_NAME_AW(CreateFile)
@@ -4730,6 +4779,15 @@
 INT32      EnumPropsEx32A(HWND32,PROPENUMPROCEX32A,LPARAM);
 INT32      EnumPropsEx32W(HWND32,PROPENUMPROCEX32W,LPARAM);
 #define    EnumPropsEx WINELIB_NAME_AW(EnumPropsEx)
+BOOL32     EnumResourceLanguages32A(HMODULE32,LPCSTR,LPCSTR,ENUMRESLANGPROC32A,LONG);
+BOOL32     EnumResourceLanguages32W(HMODULE32,LPCWSTR,LPCWSTR,ENUMRESLANGPROC32W,LONG);
+#define    EnumResourceLanguages WINELIB_NAME_AW(EnumResourceLanguages)
+BOOL32     EnumResourceNames32A(HMODULE32,LPCSTR,ENUMRESNAMEPROC32A,LONG);
+BOOL32     EnumResourceNames32W(HMODULE32,LPCWSTR,ENUMRESNAMEPROC32W,LONG);
+#define    EnumResourceNames WINELIB_NAME_AW(EnumResourceNames)
+BOOL32     EnumResourceTypes32A(HMODULE32,ENUMRESTYPEPROC32A,LONG);
+BOOL32     EnumResourceTypes32W(HMODULE32,ENUMRESTYPEPROC32W,LONG);
+#define    EnumResourceTypes WINELIB_NAME_AW(EnumResourceTypes)
 BOOL32     EnumSystemCodePages32A(CODEPAGE_ENUMPROC32A,DWORD);
 BOOL32     EnumSystemCodePages32W(CODEPAGE_ENUMPROC32W,DWORD);
 #define    EnumSystemCodePages WINELIB_NAME_AW(EnumSystemCodePages)
@@ -4787,6 +4845,7 @@
 VOID       GetSystemTime(LPSYSTEMTIME);
 LCID       GetThreadLocale();
 INT32      GetThreadPriority(HANDLE32);
+DWORD      GetWindowThreadProcessId(HWND32,LPDWORD);
 VOID       GlobalMemoryStatus(LPMEMORYSTATUS);
 LPVOID     HeapAlloc(HANDLE32,DWORD,DWORD);
 DWORD      HeapCompact(HANDLE32,DWORD);
@@ -4803,6 +4862,9 @@
 BOOL32     IsValidLocale(DWORD,DWORD);
 BOOL32     LocalFileTimeToFileTime(const FILETIME*,LPFILETIME);
 LPVOID     MapViewOfFileEx(HANDLE32,DWORD,DWORD,DWORD,DWORD,DWORD);
+INT32      MessageBoxEx32A(HWND32,LPCSTR,LPCSTR,UINT32,WORD);
+INT32      MessageBoxEx32W(HWND32,LPCWSTR,LPCWSTR,UINT32,WORD);
+#define    MessageBoxEx WINELIB_NAME_AW(MessageBoxEx)
 BOOL32     MoveFile32A(LPCSTR,LPCSTR);
 BOOL32     MoveFile32W(LPCWSTR,LPCWSTR);
 #define    MoveFile WINELIB_NAME_AW(MoveFile)
@@ -4883,6 +4945,7 @@
 LONG       GetBitmapBits(HBITMAP32,LONG,LPVOID);
 WORD       GetClassWord(HWND32,INT32);
 DWORD      GetDialogBaseUnits(void);
+VOID       GetKeyboardState(LPBYTE);
 DWORD      GetLastError(void);
 DWORD      GetMenuCheckMarkDimensions(void);
 COLORREF   GetSysColor(INT32);
@@ -4891,7 +4954,8 @@
 WORD       GetWindowWord(HWND32,INT32);
 BOOL16     HideCaret(HWND32);
 BOOL16     IsWindow(HWND32);
-void       LZDone(void);
+VOID       LZDone(void);
+DWORD      OemKeyScan(WORD);
 UINT16     RealizePalette(HDC32);
 DWORD      RegCloseKey(HKEY);
 DWORD      RegFlushKey(HKEY);
@@ -4901,6 +4965,7 @@
 BOOL16     SetCaretBlinkTime(UINT32);
 BOOL16     SetCaretPos(INT32,INT32);
 WORD       SetClassWord(HWND32,INT32,WORD);
+VOID       SetKeyboardState(LPBYTE);
 VOID       SetLastError(DWORD);
 VOID       SetRectRgn(HRGN32,INT32,INT32,INT32,INT32);
 COLORREF   SetTextColor(HDC32,COLORREF);
@@ -5419,6 +5484,9 @@
 HWND16     GetActiveWindow16(void);
 HWND32     GetActiveWindow32(void);
 #define    GetActiveWindow WINELIB_NAME(GetActiveWindow)
+WORD       GetAsyncKeyState16(INT16);
+WORD       GetAsyncKeyState32(INT32);
+#define    GetAsyncKeyState WINELIB_NAME(GetAsyncKeyState)
 BOOL16     GetBitmapDimensionEx16(HBITMAP16,LPSIZE16);
 BOOL32     GetBitmapDimensionEx32(HBITMAP32,LPSIZE32);
 #define    GetBitmapDimensionEx WINELIB_NAME(GetBitmapDimensionEx)
@@ -5544,10 +5612,16 @@
 UINT16     GetInternalWindowPos16(HWND16,LPRECT16,LPPOINT16);
 UINT32     GetInternalWindowPos32(HWND32,LPRECT32,LPPOINT32);
 #define    GetInternalWindowPos WINELIB_NAME(GetInternalWindowPos)
+INT16      GetKeyboardType16(INT16);
+INT32      GetKeyboardType32(INT32);
+#define    GetKeyboardType WINELIB_NAME(GetKeyboardType)
 INT16      GetKeyNameText16(LONG,LPSTR,INT16);
 INT32      GetKeyNameText32A(LONG,LPSTR,INT32);
 INT32      GetKeyNameText32W(LONG,LPWSTR,INT32);
 #define    GetKeyNameText WINELIB_NAME_AW(GetKeyNameText)
+WORD       GetKeyState16(INT16);
+WORD       GetKeyState32(INT32);
+#define    GetKeyState WINELIB_NAME(GetKeyState)
 UINT32     GetLogicalDriveStrings32A(UINT32,LPSTR);
 UINT32     GetLogicalDriveStrings32W(UINT32,LPWSTR);
 #define    GetLogicalDriveStrings WINELIB_NAME_AW(GetLogicalDriveStrings)
@@ -5979,6 +6053,10 @@
 LONG       LZSeek16(HFILE16,LONG,INT16);
 LONG       LZSeek32(HFILE32,LONG,INT32);
 #define    LZSeek WINELIB_NAME(LZSeek)
+UINT16     MapVirtualKey16(UINT16,UINT16);
+UINT32     MapVirtualKey32A(UINT32,UINT32);
+UINT32     MapVirtualKey32W(UINT32,UINT32);
+#define    MapVirtualKey WINELIB_NAME_AW(MapVirtualKey)
 FARPROC16  MakeProcInstance16(FARPROC16,HANDLE16);
 #define    MakeProcInstance32(proc,inst) (proc)
 #define    MakeProcInstance WINELIB_NAME(MakeProcInstance)
@@ -6227,6 +6305,10 @@
 INT16      SetCommState16(LPDCB16);
 BOOL32     SetCommState32(INT32,LPDCB32);
 #define    SetCommState WINELIB_NAME(SetCommState)
+BOOL16     SetCurrentDirectory16(LPCSTR);
+BOOL32     SetCurrentDirectory32A(LPCSTR);
+BOOL32     SetCurrentDirectory32W(LPCWSTR);
+#define    SetCurrentDirectory WINELIB_NAME_AW(SetCurrentDirectory)
 BOOL16     SetDeskWallPaper16(LPCSTR);
 BOOL32     SetDeskWallPaper32(LPCSTR);
 #define    SetDeskWallPaper WINELIB_NAME(SetDeskWallPaper)
@@ -6245,6 +6327,9 @@
 void       SetDlgItemText32A(HWND32,INT32,LPCSTR);
 void       SetDlgItemText32W(HWND32,INT32,LPCWSTR);
 #define    SetDlgItemText WINELIB_NAME_AW(SetDlgItemText)
+UINT16     SetErrorMode16(UINT16);
+UINT32     SetErrorMode32(UINT32);
+#define    SetErrorMode WINELIB_NAME(SetErrorMode)
 BOOL16     SetFileAttributes16(LPCSTR,DWORD);
 BOOL32     SetFileAttributes32A(LPCSTR,DWORD);
 BOOL32     SetFileAttributes32W(LPCWSTR,DWORD);
@@ -6366,6 +6451,9 @@
 BOOL16     ShowWindow16(HWND16,INT16);
 BOOL32     ShowWindow32(HWND32,INT32);
 #define    ShowWindow WINELIB_NAME(ShowWindow)
+DWORD      SizeofResource16(HMODULE16,HRSRC16);
+DWORD      SizeofResource32(HMODULE32,HRSRC32);
+#define    SizeofResource WINELIB_NAME(SizeofResource)
 BOOL16     StretchBlt16(HDC16,INT16,INT16,INT16,INT16,HDC16,INT16,INT16,
                         INT16,INT16,DWORD);
 BOOL32     StretchBlt32(HDC32,INT32,INT32,INT32,INT32,HDC32,INT32,INT32,
@@ -6387,9 +6475,15 @@
 BOOL32     TextOut32A(HDC32,INT32,INT32,LPCSTR,INT32);
 BOOL32     TextOut32W(HDC32,INT32,INT32,LPCWSTR,INT32);
 #define    TextOut WINELIB_NAME_AW(TextOut)
+INT16      ToAscii16(UINT16,UINT16,LPBYTE,LPVOID,UINT16);
+INT32      ToAscii32(UINT32,UINT32,LPBYTE,LPWORD,UINT32);
+#define    ToAscii WINELIB_NAME(ToAscii)
 BOOL16     TrackPopupMenu16(HMENU16,UINT16,INT16,INT16,INT16,HWND16,const RECT16*);
 BOOL32     TrackPopupMenu32(HMENU32,UINT32,INT32,INT32,INT32,HWND32,const RECT32*);
 #define    TrackPopupMenu WINELIB_NAME(TrackPopupMenu)
+INT16      TranslateAccelerator16(HWND16,HACCEL16,LPMSG16);
+INT32      TranslateAccelerator32(HWND32,HACCEL32,LPMSG32);
+#define    TranslateAccelerator WINELIB_NAME(TranslateAccelerator)
 INT16      TransmitCommChar16(INT16,CHAR);
 BOOL32     TransmitCommChar32(INT32,CHAR);
 #define    TransmitCommChar WINELIB_NAME(TransmitCommChar)
@@ -6434,6 +6528,10 @@
 DWORD      VerQueryValue32A(LPVOID,LPCSTR,LPVOID*,UINT32*);
 DWORD      VerQueryValue32W(LPVOID,LPCWSTR,LPVOID*,UINT32*);
 #define    VerQueryValue WINELIB_NAME_AW(VerQueryValue)
+WORD       VkKeyScan16(CHAR);
+WORD       VkKeyScan32A(CHAR);
+WORD       VkKeyScan32W(WCHAR);
+#define    VkKeyScan WINELIB_NAME_AW(VkKeyScan)
 HWND16     WindowFromDC16(HDC16);
 HWND32     WindowFromDC32(HDC32);
 #define    WindowFromDC WINELIB_NAME(WindowFromDC)
@@ -6529,6 +6627,7 @@
 INT32      LoadMessage32A(HINSTANCE32,UINT32,WORD,LPSTR,INT32);
 INT32      LoadMessage32W(HINSTANCE32,UINT32,WORD,LPWSTR,INT32);
 SEGPTR     WIN16_GlobalLock16(HGLOBAL16);
+SEGPTR     WIN16_LockResource(HGLOBAL16);
 INT32      lstrncmp32A(LPCSTR,LPCSTR,INT32);
 INT32      lstrncmp32W(LPCWSTR,LPCWSTR,INT32);
 INT32      lstrncmpi32A(LPCSTR,LPCSTR,INT32);
@@ -6604,7 +6703,6 @@
 UINT       GDIRealizePalette(HDC16);
 HPALETTE16 GDISelectPalette(HDC16,HPALETTE16,WORD);
 DWORD      GetAspectRatioFilter(HDC16);
-int        GetAsyncKeyState(int);
 WORD       GetAtomName(ATOM,LPSTR,short);
 HANDLE16   GetClipboardData(WORD);
 int        GetClipboardFormatName(WORD,LPSTR,short);
@@ -6622,9 +6720,6 @@
 BOOL       GetInputState(void);
 int        GetKBCodePage(void);
 int        GetKerningPairs(HDC16,int,LPKERNINGPAIR16);
-INT        GetKeyState(INT);
-void       GetKeyboardState(BYTE*);
-int        GetKeyboardType(int);
 HWND       GetLastActivePopup(HWND);
 BOOL       GetMessage(SEGPTR,HWND,UINT,UINT);
 LONG       GetMessageExtraInfo(void);
@@ -6649,7 +6744,6 @@
 LPINT16    GetThresholdEvent(void);
 int        GetThresholdStatus(void);
 BOOL       GetWinDebugInfo(LPWINDEBUGINFO,UINT);
-LONG       GetWinFlags(void);
 ATOM       GlobalDeleteAtom(ATOM);
 void       GlobalFix(HGLOBAL16);
 BOOL16     GlobalUnWire(HGLOBAL16);
@@ -6663,9 +6757,7 @@
 BOOL       IsValidMetaFile(HMETAFILE16);
 HINSTANCE16 LoadModule(LPCSTR,LPVOID);
 FARPROC16  LocalNotify(FARPROC16);
-WORD       MapVirtualKey(WORD,WORD);
 void       MessageBeep(WORD);
-DWORD      OemKeyScan(WORD);
 BOOL       OpenClipboard(HWND);
 BOOL       OpenIcon(HWND);
 int        OpenSound(void);
@@ -6692,14 +6784,11 @@
 HWND       SetClipboardViewer(HWND);
 void       SetConvertHook(BOOL);
 BOOL       SetConvertParams(int,int);
-BOOL32     SetCurrentDirectory(LPCSTR);
 HCURSOR16  SetCursor(HCURSOR16);
 void       SetCursorPos(short,short);
 void       SetDoubleClickTime(WORD);
 int        SetEnvironment(LPCSTR,LPCSTR,WORD);
-UINT       SetErrorMode(UINT);
 WORD       SetHookFlags(HDC16,WORD);
-void       SetKeyboardState(BYTE*);
 DWORD      SetMapperFlags(HDC16,DWORD);
 BOOL       SetMessageQueue(int);
 HMETAFILE16 SetMetaFileBits(HGLOBAL16);
@@ -6719,20 +6808,15 @@
 HINSTANCE16 ShellExecute(HWND,LPCSTR,LPCSTR,LPSTR,LPCSTR,INT);
 int        ShowCursor(BOOL);
 void       ShowOwnedPopups(HWND,BOOL);
-DWORD      SizeofResource(HMODULE16,HRSRC16);
 int        StartSound(void);
 int        StopSound(void);
 BOOL       SwapMouseButton(BOOL);
 void       SwapRecording(WORD);
 int        SyncAllVoices(void);
 LONG       TabbedTextOut(HDC16,short,short,LPSTR,short,short,LPINT16,short);
-int        ToAscii(WORD,WORD,LPSTR,LPVOID,WORD);
-INT16      TranslateAccelerator(HWND,HACCEL16,LPMSG16);
 BOOL       TranslateMDISysAccel(HWND,LPMSG16);
 BOOL       TranslateMessage(LPMSG16);
 int        UpdateColors(HDC16);
-WORD       VkKeyScan(WORD);
-SEGPTR     WIN16_LockResource(HGLOBAL16);
 void       WaitMessage(void);
 int        WaitSoundState(int);
 
diff --git a/include/winnt.h b/include/winnt.h
index 55a96a8..4bd7387 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -139,6 +139,126 @@
 
 #endif  /* __WINE__ */
 
+/*
+ * Exception codes
+ */
+ 
+#define STATUS_WAIT_0                    0x00000000
+#define STATUS_ABANDONED_WAIT_0          0x00000080
+#define STATUS_USER_APC                  0x000000C0
+#define STATUS_TIMEOUT                   0x00000102
+#define STATUS_PENDING                   0x00000103
+#define STATUS_DATATYPE_MISALIGNMENT     0x80000002
+#define STATUS_BREAKPOINT                0x80000003
+#define STATUS_SINGLE_STEP               0x80000004
+#define STATUS_ACCESS_VIOLATION          0xC0000005
+#define STATUS_IN_PAGE_ERROR             0xC0000006
+#define STATUS_NO_MEMORY                 0xC0000017
+#define STATUS_ILLEGAL_INSTRUCTION       0xC000001D
+#define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025
+#define STATUS_INVALID_DISPOSITION       0xC0000026
+#define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008C
+#define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008D
+#define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008E
+#define STATUS_FLOAT_INEXACT_RESULT      0xC000008F
+#define STATUS_FLOAT_INVALID_OPERATION   0xC0000090
+#define STATUS_FLOAT_OVERFLOW            0xC0000091
+#define STATUS_FLOAT_STACK_CHECK         0xC0000092
+#define STATUS_FLOAT_UNDERFLOW           0xC0000093
+#define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094
+#define STATUS_INTEGER_OVERFLOW          0xC0000095
+#define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096
+#define STATUS_STACK_OVERFLOW            0xC00000FD
+#define STATUS_CONTROL_C_EXIT            0xC000013A
+
+#define EXCEPTION_ACCESS_VIOLATION      STATUS_ACCESS_VIOLATION
+#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
+#define EXCEPTION_BREAKPOINT            STATUS_BREAKPOINT
+#define EXCEPTION_SINGLE_STEP           STATUS_SINGLE_STEP
+#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
+#define EXCEPTION_FLT_DENORMAL_OPERAND  STATUS_FLOAT_DENORMAL_OPERAND
+#define EXCEPTION_FLT_DIVIDE_BY_ZERO    STATUS_FLOAT_DIVIDE_BY_ZERO
+#define EXCEPTION_FLT_INEXACT_RESULT    STATUS_FLOAT_INEXACT_RESULT
+#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
+#define EXCEPTION_FLT_OVERFLOW          STATUS_FLOAT_OVERFLOW
+#define EXCEPTION_FLT_STACK_CHECK       STATUS_FLOAT_STACK_CHECK
+#define EXCEPTION_FLT_UNDERFLOW         STATUS_FLOAT_UNDERFLOW
+#define EXCEPTION_INT_DIVIDE_BY_ZERO    STATUS_INTEGER_DIVIDE_BY_ZERO
+#define EXCEPTION_INT_OVERFLOW          STATUS_INTEGER_OVERFLOW
+#define EXCEPTION_PRIV_INSTRUCTION      STATUS_PRIVILEGED_INSTRUCTION
+#define EXCEPTION_IN_PAGE_ERROR         STATUS_IN_PAGE_ERROR
+
+/*
+ * Return values from the actual exception handlers
+ */
+
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch    1
+#define ExceptionNestedException   2
+#define ExceptionCollidedUnwind    3
+ 
+/*
+ * Return values from filters in except() and from UnhandledExceptionFilter
+ */
+ 
+#define EXCEPTION_EXECUTE_HANDLER        1
+#define EXCEPTION_CONTINUE_SEARCH        0
+#define EXCEPTION_CONTINUE_EXECUTION    -1
+
+/*
+ * From OS/2 2.0 exception handling
+ * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD
+ */
+
+#define EH_NONCONTINUABLE   0x01
+#define EH_UNWINDING        0x02
+#define EH_EXIT_UNWIND      0x04
+#define EH_STACK_INVALID    0x08
+#define EH_NESTED_CALL      0x10
+
+#define EXCEPTION_CONTINUABLE        0
+#define EXCEPTION_NONCONTINUABLE     EH_NONCONTINUABLE
+ 
+/*
+ * The exception record used by Win32 to give additional information 
+ * about exception to exception handlers.
+ */
+
+#define EXCEPTION_MAXIMUM_PARAMETERS 15
+
+typedef struct __EXCEPTION_RECORD
+{
+    DWORD    ExceptionCode;
+    DWORD    ExceptionFlags;
+    struct __EXCEPTION_RECORD *ExceptionRecord;
+
+    LPVOID   ExceptionAddress;
+    DWORD    NumberParameters;
+    DWORD    ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
+
+/*
+ * The exception pointers structure passed to exception filters
+ * in except() and the UnhandledExceptionFilter().
+ */
+ 
+typedef struct _EXCEPTION_POINTERS 
+{
+  PEXCEPTION_RECORD  ExceptionRecord;
+  PCONTEXT           ContextRecord;
+} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
+
+/*
+ * function pointer to a exception filter
+ */
+
+typedef LONG (*PTOP_LEVEL_EXCEPTION_FILTER)(PEXCEPTION_POINTERS ExceptionInfo);
+typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
+
+DWORD UnhandledExceptionFilter( PEXCEPTION_POINTERS epointers );
+LPTOP_LEVEL_EXCEPTION_FILTER
+SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER filter );
+
 /* Language IDs */
 
 #define LANG_NEUTRAL                     0x00
diff --git a/include/x11drv.h b/include/x11drv.h
index 127441d..a08831e 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -90,6 +90,8 @@
 extern BOOL32 X11DRV_PolyPolygon( struct tagDC *dc, LPPOINT32 pt,
 				  LPINT32 counts, UINT32 polygons);
 
+extern HGDIOBJ32 X11DRV_SelectObject( struct tagDC *dc, HGDIOBJ32 handle );
+
 extern BOOL32 X11DRV_ExtFloodFill( struct tagDC *dc, INT32 x, INT32 y,
 				   COLORREF color, UINT32 fillType );
 extern BOOL32 X11DRV_ExtTextOut( struct tagDC *dc, INT32 x, INT32 y,
@@ -97,4 +99,10 @@
 				 LPCSTR str, UINT32 count, const INT32 *lpDx );
 
 
+/* X11 driver internal functions */
+
+extern BOOL32 X11DRV_BITMAP_Init(void);
+extern BOOL32 X11DRV_BRUSH_Init(void);
+extern BOOL32 X11DRV_FONT_Init(void);
+
 #endif  /* __WINE_X11DRV_H */
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 8b94554..a9986a4 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -84,7 +84,3 @@
   return NULL;
 }
 
-void DEBUG_EnterDebugger(void)
-{
-}
-
diff --git a/loader/main.c b/loader/main.c
index f78ee78..1c1ee9c 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -61,7 +61,6 @@
     extern BOOL32 WIN16DRV_Init(void);
     extern BOOL32 SIGNAL_Init(void);
     extern BOOL32 WIDGETS_Init(void);
-    extern int KERN32_Init(void);
 
     int queueSize;
 
@@ -144,9 +143,6 @@
     /* Initialize message spying */
     if (!SPY_Init()) return 0;
 
-      /* Initialize Win32 data structures */
-    if (!KERN32_Init()) return 0;
-
       /* Create system message queue */
     queueSize = GetProfileInt32A( "windows", "TypeAhead", 120 );
     if (!QUEUE_CreateSysMsgQueue( queueSize )) return 0;
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 9d4816c..d30b09b 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -17,9 +17,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
-#ifndef __EMX__
-#include <sys/mman.h>
-#endif
 #include "windows.h"
 #include "winbase.h"
 #include "callback.h"
@@ -65,14 +62,14 @@
       if (i<pe_exports->NumberOfNames) {
 	  ename=(char*)RVA(*name++);
 	  dprintf_win32(stddeb,"%-32s %4d    %8.8lx (%8.8lx)\n",ename,*ordinal,functions[*ordinal],*function);
-	  sprintf(buffer,"%s.%s",Module,ename);
+	  sprintf(buffer,"%s_%s",Module,ename);
 	  daddr.off=RVA(functions[*ordinal]);
 	  ordinal++;
 	  function++;
       } else {
       	  /* ordinals/names no longer valid, but we still got functions */
 	  dprintf_win32(stddeb,"%-32s %4s    %8s %8.8lx\n","","","",*function);
-	  sprintf(buffer,"%s.%d",Module,i);
+	  sprintf(buffer,"%s_%d",Module,i);
 	  daddr.off=RVA(*functions);
 	  function++;
       }
@@ -541,7 +538,7 @@
 	if (pe->pe_export) {
 		/* add start of sections as debugsymbols */
 		for(i=0;i<pe->pe_header->FileHeader.NumberOfSections;i++) {
-			sprintf(buffer,"%s.%s",
+			sprintf(buffer,"%s_%s",
 				(char*)RVA(pe->pe_export->Name),
 				pe->pe_seg[i].Name
 			);
@@ -549,7 +546,7 @@
 			DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
 		}
 		/* add entry point */
-		sprintf(buffer,"%s.EntryPoint",(char*)RVA(pe->pe_export->Name));
+		sprintf(buffer,"%s_EntryPoint",(char*)RVA(pe->pe_export->Name));
 		daddr.off=RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
 		DEBUG_AddSymbol(buffer,&daddr, NULL, SYM_WIN32 | SYM_FUNC);
 		/* add start of DLL */
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 7c7e6af..08655d0 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -8,8 +8,7 @@
  * Based on the Win16 resource handling code in loader/resource.c
  * Copyright 1993 Robert J. Amstadt
  * Copyright 1995 Alexandre Julliard
- *
- * This is not even at ALPHA level yet. Don't expect it to work!
+ * Copyright 1997 Marcus Meissner
  */
 
 #include <sys/types.h>
@@ -18,22 +17,28 @@
 #include "pe_image.h"
 #include "module.h"
 #include "heap.h"
-#include "handle32.h"
 #include "libres.h"
 #include "stackframe.h"
 #include "neexe.h"
-#include "accel.h"
-#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
-#define PrintIdA(name) \
-    if (HIWORD((DWORD)name)) \
-        dprintf_resource( stddeb, "'%s'", name); \
-    else \
-        dprintf_resource( stddeb, "#%04x", LOWORD(name)); 
-#define PrintIdW(name)
-#define PrintId(name)
+/**********************************************************************
+ *  HMODULE32toPE_MODULE 
+ *
+ * small helper function to get a PE_MODULE from a passed HMODULE32
+ */
+static PE_MODULE*
+HMODULE32toPE_MODULE(HMODULE32 hmod) {
+	NE_MODULE	*pModule;
+
+	if (!hmod) hmod = GetTaskDS(); /* FIXME: correct? */
+	hmod = GetExePtr( hmod );  /* In case we were passed an hInstance */
+
+	if (!(pModule = MODULE_GetPtr( hmod ))) return 0;
+	if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
+	return pModule->pe_module;
+}
 
 /**********************************************************************
  *	    GetResDirEntryW
@@ -87,50 +92,18 @@
 }
 
 /**********************************************************************
- *	    GetResDirEntryA
- *
- *	Helper function - goes down one level of PE resource tree
- *
- */
-LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(LPIMAGE_RESOURCE_DIRECTORY resdirptr,
-					   LPCSTR name,
-					   DWORD root)
-{
-	LPWSTR				xname;
-	LPIMAGE_RESOURCE_DIRECTORY	ret;
-
-	if (HIWORD((DWORD)name))
-		xname	= HEAP_strdupAtoW( GetProcessHeap(), 0, name );
-	else
-		xname	= (LPWSTR)name;
-
-	ret=GetResDirEntryW(resdirptr,xname,root);
-	if (HIWORD((DWORD)name))
-            HeapFree( GetProcessHeap(), 0, xname );
-	return ret;
-}
-
-/**********************************************************************
  *	    PE_FindResourceEx32W
  */
 HANDLE32 PE_FindResourceEx32W(
 	HINSTANCE32 hModule,LPCWSTR name,LPCWSTR type,WORD lang
 ) {
-    PE_MODULE *pe;
-    NE_MODULE *pModule;
     LPIMAGE_RESOURCE_DIRECTORY resdirptr;
     DWORD root;
     HANDLE32 result;
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hModule);
 
-    hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
-    dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
-    PrintId( type );
-    dprintf_resource( stddeb, " name=" );
-    PrintId( name );
-    dprintf_resource( stddeb, "\n" );
-    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
-    if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;  /* FIXME? */
-    if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
+    if (!pe || !pe->pe_resource)
+    	return 0;
 
     resdirptr = pe->pe_resource;
     root = (DWORD) resdirptr;
@@ -151,18 +124,287 @@
  */
 HANDLE32 PE_LoadResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
 {
-    NE_MODULE *pModule;
-    PE_MODULE *pe;
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hModule);
 
-    if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
-    hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
-    dprintf_resource(stddeb, "PE_LoadResource32: module=%04x res=%04x\n",
-                     hModule, hRsrc );
+    if (!pe || !pe->pe_resource)
+    	return 0;
+    if (!hRsrc)
+   	 return 0;
+    return (HANDLE32) (pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+}
+
+
+/**********************************************************************
+ *	    PE_SizeofResource32
+ */
+void
+_check_ptr(DWORD x,DWORD start,LPDWORD lastmax) {
+	if ((x>start) && (x<*lastmax))
+		*lastmax=x;
+}
+
+static void
+walk_resdir(DWORD loadaddr,DWORD rootresdir,DWORD xres,DWORD data,DWORD lvl,LPDWORD max){
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DATA_ENTRY		dataent;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    int	i;
+
+    if (lvl==3) {
+    	dataent = (LPIMAGE_RESOURCE_DATA_ENTRY)(rootresdir+xres);
+	_check_ptr(loadaddr+dataent->OffsetToData,data,max);
+	return;
+    }
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)(rootresdir+xres);
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++)
+	walk_resdir(loadaddr,rootresdir,(lvl==2)?et[i].u2.OffsetToData:et[i].u2.s.OffsetToDirectory,data,lvl+1,max);
+}
+
+DWORD PE_SizeofResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
+{
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hModule);
+    DWORD	max,data;
+    IMAGE_DATA_DIRECTORY	dir;
+
+    if (!pe || !pe->pe_resource)
+    	return 0;
     if (!hRsrc) return 0;
 
-    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
-    if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;  /* FIXME? */
-    if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
-    return (HANDLE32) (pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+    max=(DWORD)-1;
+    dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
+    if(dir.Size)
+    	max=(DWORD)pe->pe_resource+dir.Size;
+
+    data=((DWORD)pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+    walk_resdir(pe->load_addr,(DWORD)pe->pe_resource,0,data,0,&max);
+    return max-data;
+}
+
+/**********************************************************************
+ *	    PE_EnumResourceTypes32A
+ */
+BOOL32
+PE_EnumResourceTypes32A(HMODULE32 hmod,ENUMRESTYPEPROC32A lpfun,LONG lparam) {
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hmod);
+    int		i;
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    BOOL32	ret;
+    HANDLE32	heap = GetProcessHeap();	
+
+    if (!pe || !pe->pe_resource)
+    	return FALSE;
+
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    ret = FALSE;
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+    	LPSTR	name;
+
+	if (HIWORD(et[i].u1.Name))
+		name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name));
+	else
+		name = (LPSTR)et[i].u1.Name;
+	ret = lpfun(hmod,name,lparam);
+	if (HIWORD(name))
+		HeapFree(heap,0,name);
+	if (!ret)
+		break;
+    }
+    return ret;
+}
+
+/**********************************************************************
+ *	    PE_EnumResourceTypes32W
+ */
+BOOL32
+PE_EnumResourceTypes32W(HMODULE32 hmod,ENUMRESTYPEPROC32W lpfun,LONG lparam) {
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hmod);
+    int		i;
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    BOOL32	ret;
+
+    if (!pe || !pe->pe_resource)
+    	return FALSE;
+
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    ret = FALSE;
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+	LPWSTR	type;
+    	if (HIWORD(et[i].u1.Name))
+		type = (LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name);
+	else
+		type = (LPWSTR)et[i].u1.Name;
+
+	ret = lpfun(hmod,type,lparam);
+	if (!ret)
+		break;
+    }
+    return ret;
+}
+
+/**********************************************************************
+ *	    PE_EnumResourceNames32A
+ */
+BOOL32
+PE_EnumResourceNames32A(
+	HMODULE32 hmod,LPCSTR type,ENUMRESNAMEPROC32A lpfun,LONG lparam
+) {
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hmod);
+    int		i;
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    BOOL32	ret;
+    HANDLE32	heap = GetProcessHeap();	
+    LPWSTR	typeW;
+
+    if (!pe || !pe->pe_resource)
+    	return FALSE;
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+    if (HIWORD(type))
+	typeW = HEAP_strdupAtoW(heap,0,type);
+    else
+	typeW = (LPWSTR)type;
+    resdir = GetResDirEntryW(resdir,typeW,(DWORD)pe->pe_resource);
+    if (HIWORD(typeW))
+    	HeapFree(heap,0,typeW);
+    if (!resdir)
+    	return FALSE;
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    ret = FALSE;
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+    	LPSTR	name;
+
+	if (HIWORD(et[i].u1.Name))
+	    name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name));
+	else
+	    name = (LPSTR)et[i].u1.Name;
+	ret = lpfun(hmod,type,name,lparam);
+	if (HIWORD(name)) HeapFree(heap,0,name);
+	if (!ret)
+		break;
+    }
+    return ret;
+}
+
+/**********************************************************************
+ *	    PE_EnumResourceNames32W
+ */
+BOOL32
+PE_EnumResourceNames32W(
+	HMODULE32 hmod,LPCWSTR type,ENUMRESNAMEPROC32W lpfun,LONG lparam
+) {
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hmod);
+    int		i;
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    BOOL32	ret;
+
+    if (!pe || !pe->pe_resource)
+    	return FALSE;
+
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+    resdir = GetResDirEntryW(resdir,type,(DWORD)pe->pe_resource);
+    if (!resdir)
+    	return FALSE;
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    ret = FALSE;
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+	LPWSTR	name;
+    	if (HIWORD(et[i].u1.Name))
+		name = (LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name);
+	else
+		name = (LPWSTR)et[i].u1.Name;
+	ret = lpfun(hmod,type,name,lparam);
+	if (!ret)
+		break;
+    }
+    return ret;
+}
+
+/**********************************************************************
+ *	    PE_EnumResourceNames32A
+ */
+BOOL32
+PE_EnumResourceLanguages32A(
+	HMODULE32 hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROC32A lpfun,
+	LONG lparam
+) {
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hmod);
+    int		i;
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    BOOL32	ret;
+    HANDLE32	heap = GetProcessHeap();	
+    LPWSTR	nameW,typeW;
+
+    if (!pe || !pe->pe_resource)
+    	return FALSE;
+
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+    if (HIWORD(name))
+	nameW = HEAP_strdupAtoW(heap,0,name);
+    else
+    	nameW = (LPWSTR)name;
+    resdir = GetResDirEntryW(resdir,nameW,(DWORD)pe->pe_resource);
+    if (HIWORD(nameW))
+    	HeapFree(heap,0,nameW);
+    if (!resdir)
+    	return FALSE;
+    if (HIWORD(type))
+	typeW = HEAP_strdupAtoW(heap,0,type);
+    else
+	typeW = (LPWSTR)type;
+    resdir = GetResDirEntryW(resdir,typeW,(DWORD)pe->pe_resource);
+    if (HIWORD(typeW))
+    	HeapFree(heap,0,typeW);
+    if (!resdir)
+    	return FALSE;
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    ret = FALSE;
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+    	/* languages are just ids... I hope */
+	ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
+	if (!ret)
+		break;
+    }
+    return ret;
+}
+
+/**********************************************************************
+ *	    PE_EnumResourceLanguages32W
+ */
+BOOL32
+PE_EnumResourceLanguages32W(
+	HMODULE32 hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROC32W lpfun,
+	LONG lparam
+) {
+    PE_MODULE	*pe = HMODULE32toPE_MODULE(hmod);
+    int		i;
+    LPIMAGE_RESOURCE_DIRECTORY		resdir;
+    LPIMAGE_RESOURCE_DIRECTORY_ENTRY	et;
+    BOOL32	ret;
+
+    if (!pe || !pe->pe_resource)
+    	return FALSE;
+
+    resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+    resdir = GetResDirEntryW(resdir,name,(DWORD)pe->pe_resource);
+    if (!resdir)
+    	return FALSE;
+    resdir = GetResDirEntryW(resdir,type,(DWORD)pe->pe_resource);
+    if (!resdir)
+    	return FALSE;
+    et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+    ret = FALSE;
+    for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+	ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
+	if (!ret)
+		break;
+    }
+    return ret;
 }
 #endif
diff --git a/loader/resource.c b/loader/resource.c
index de289b6..d2f50fe 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -345,8 +345,12 @@
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n",
                      hModule, hRsrc );
+#ifndef WINELIB
+    return PE_SizeofResource32(hModule,hRsrc);
+#else
     fprintf(stderr,"SizeofResource32: not implemented\n");
     return 0;
+#endif
 }
 
 
@@ -441,10 +445,15 @@
 
 /**********************************************************************
  *			LoadAccelerators32W	[USER.177]
+ * The image layout seems to look like this (not 100% sure):
+ * 00:	BYTE	type		type of accelerator
+ * 01:	BYTE	pad		(to WORD boundary)
+ * 02:	WORD	event
+ * 04:	WORD	IDval		
+ * 06:	WORD	pad		(to DWORD boundary)
  */
 HACCEL32 LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
 {
-#if 0
     HACCEL32 	hAccel;
     HGLOBAL32 	rsc_mem;
     HRSRC32 hRsrc;
@@ -471,11 +480,12 @@
     lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
     lpAccelTbl->wCount = 0;
     for (i = 0; i < n; i++) {
-	lpAccelTbl->tbl[i].type = *(lp++);
+	lpAccelTbl->tbl[i].type = *lp;
+	lp += 2;
 	lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
 	lp += 2;
 	lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
-	lp += 2;
+	lp += 4;
     	if (lpAccelTbl->tbl[i].wEvent == 0) break;
 	dprintf_accel(stddeb,
 		"Accelerator #%u / event=%04X id=%04X type=%02X \n", 
@@ -486,10 +496,6 @@
     GlobalUnlock16(hAccel);
     FreeResource32(rsc_mem);
     return hAccel;
-#else
-	fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
-	return 0x100;  /* Return something anyway */
-#endif
 }
 
 HACCEL32 LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
@@ -744,3 +750,51 @@
 	fprintf(stderr,"SetResourceHandler(%04x,0x%04x,%p), empty STUB!\n",instance,LOWORD(s),farproc);
     return NULL;
 }
+
+#ifndef WINELIB
+/**********************************************************************
+ *	EnumResourceTypesA	(KERNEL32.90)
+ */
+BOOL32
+EnumResourceTypes32A(HMODULE32 hmodule,ENUMRESTYPEPROC32A lpfun,LONG lParam) {
+    return PE_EnumResourceTypes32A(hmodule,lpfun,lParam);
+}
+
+/**********************************************************************
+ *	EnumResourceTypesW	(KERNEL32.91)
+ */
+BOOL32
+EnumResourceTypes32W(HMODULE32 hmodule,ENUMRESTYPEPROC32W lpfun,LONG lParam) {
+    return PE_EnumResourceTypes32W(hmodule,lpfun,lParam);
+}
+
+/**********************************************************************
+ *	EnumResourceNamesA	(KERNEL32.88)
+ */
+BOOL32
+EnumResourceNames32A(HMODULE32 hmodule,LPCSTR type,ENUMRESNAMEPROC32A lpfun,LONG lParam) {
+    return PE_EnumResourceNames32A(hmodule,type,lpfun,lParam);
+}
+/**********************************************************************
+ *	EnumResourceNamesW	(KERNEL32.89)
+ */
+BOOL32
+EnumResourceNames32W(HMODULE32 hmodule,LPCWSTR type,ENUMRESNAMEPROC32W lpfun,LONG lParam) {
+    return PE_EnumResourceNames32W(hmodule,type,lpfun,lParam);
+}
+
+/**********************************************************************
+ *	EnumResourceLanguagesA	(KERNEL32.86)
+ */
+BOOL32
+EnumResourceLanguages32A(HMODULE32 hmodule,LPCSTR type,LPCSTR name,ENUMRESLANGPROC32A lpfun,LONG lParam) {
+    return PE_EnumResourceLanguages32A(hmodule,type,name,lpfun,lParam);
+}
+/**********************************************************************
+ *	EnumResourceLanguagesW	(KERNEL32.87)
+ */
+BOOL32
+EnumResourceLanguages32W(HMODULE32 hmodule,LPCWSTR type,LPCWSTR name,ENUMRESLANGPROC32W lpfun,LONG lParam) {
+    return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);
+}
+#endif  /* WINELIB */
diff --git a/loader/signal.c b/loader/signal.c
index 2d97ed5..769b510 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -143,7 +143,6 @@
 static void SIGNAL_fault(int signal, int code, SIGCONTEXT *context)
 {
 #endif
-#ifndef __EMX__ /* FIXME: XX_sig(constext)=pointer to incomplete type (EMX) */
     if (CS_sig(context) == WINE_CODE_SELECTOR)
     {
         fprintf( stderr, "Segmentation fault in Wine program (%x:%lx)."
@@ -157,7 +156,6 @@
                  CS_sig(context), EIP_sig(context) );
     }
     wine_debug( signal, context );
-#endif
 }
 
 
diff --git a/loader/task.c b/loader/task.c
index 0b721e6..864abad 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -361,7 +361,6 @@
         /* FIXME: all this is an ugly hack */
 
         extern void InitTask( CONTEXT *context );
-        extern void PE_InitializeDLLs( HMODULE16 hModule );
 
         InitTask( NULL );
         InitApp( pTask->hModule );
@@ -536,7 +535,15 @@
     /* Create the Win32 part of the task */
 
     pdb32 = PROCESS_Create( pTask );
-    pTask->thdb = THREAD_Create( pdb32, 0 );
+    if (pModule->flags & NE_FFLAGS_WIN32)
+    {
+        LPTHREAD_START_ROUTINE start =
+            (LPTHREAD_START_ROUTINE)(pModule->pe_module->load_addr +
+            pModule->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint);
+        pTask->thdb = THREAD_Create( pdb32, 0, start );
+    }
+    else
+        pTask->thdb = THREAD_Create( pdb32, 0, NULL );
 
     /* Create the 32-bit stack frame */
 
@@ -1274,21 +1281,31 @@
 
 
 /***********************************************************************
- *           SetErrorMode   (KERNEL.107)
+ *           SetErrorMode16   (KERNEL.107)
  */
-UINT SetErrorMode( UINT mode )
+UINT16 SetErrorMode16( UINT16 mode )
 {
     TDB *pTask;
-    UINT oldMode;
+    UINT16 oldMode;
 
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
     oldMode = pTask->error_mode;
     pTask->error_mode = mode;
+    pTask->thdb->process->error_mode = mode;
     return oldMode;
 }
 
 
 /***********************************************************************
+ *           SetErrorMode32   (KERNEL32.486)
+ */
+UINT32 SetErrorMode32( UINT32 mode )
+{
+    return SetErrorMode16( (UINT16)mode );
+}
+
+
+/***********************************************************************
  *           GetDOSEnvironment   (KERNEL.131)
  */
 SEGPTR GetDOSEnvironment(void)
diff --git a/memory/selector.c b/memory/selector.c
index 49a1309..9d76477 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -13,7 +13,7 @@
 #include "debug.h"
 
 
-#define FIRST_LDT_ENTRY_TO_ALLOC  6
+#define FIRST_LDT_ENTRY_TO_ALLOC  17
 
 
 /***********************************************************************
diff --git a/misc/comm.c b/misc/comm.c
index 91b2161..adf2197 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -858,7 +858,7 @@
 			commerror = IE_BAUDRATE;
 			return -1;
 	}
-#else
+#elif !defined(__EMX__)
         switch (lpdcb->BaudRate) {
                 case 110:
                 case CBR_110:
@@ -1059,7 +1059,7 @@
 			commerror = IE_BAUDRATE;
 			return FALSE;
 	}
-#else
+#elif !defined(__EMX__)
         switch (lpdcb->BaudRate) {
                 case 110:
                 case CBR_110:
@@ -1194,6 +1194,7 @@
 		return -1;
 	}
 	lpdcb->Id = fd;
+#ifndef __EMX__
 #ifdef CBAUD
         switch (port.c_cflag & CBAUD) {
 #else
@@ -1227,7 +1228,7 @@
 			lpdcb->BaudRate = 38400;
 			break;
 	}
-
+#endif
 	switch (port.c_cflag & CSIZE) {
 		case CS5:
 			lpdcb->ByteSize = 5;
@@ -1312,6 +1313,7 @@
 		commerror = WinError();	
 		return FALSE;
 	}
+#ifndef __EMX__
 #ifdef CBAUD
         switch (port.c_cflag & CBAUD) {
 #else
@@ -1345,7 +1347,7 @@
 			lpdcb->BaudRate = 38400;
 			break;
 	}
-
+#endif
 	switch (port.c_cflag & CSIZE) {
 		case CS5:
 			lpdcb->ByteSize = 5;
diff --git a/misc/cpu.c b/misc/cpu.c
index f5d10e8..43a9642 100644
--- a/misc/cpu.c
+++ b/misc/cpu.c
@@ -2,6 +2,7 @@
  * What processor?
  *
  * Copyright 1995 Morten Welinder
+ * Copyright 1997 Marcus Meissner
  */
 
 #include <stdio.h>
@@ -9,39 +10,93 @@
 #include <string.h>
 #include "windows.h"
 
-int runtime_cpu (void)
+VOID
+GetSystemInfo(LPSYSTEM_INFO si)
 {
-#ifndef __i386__
-    return 5;  /* Might as well pretend to be a Pentium... */
-#else  /* __i386__ */
-  static int cache = 0;
+	static int cache = 0;
+	static SYSTEM_INFO cachedsi;
+
+	if (cache) {
+		memcpy(si,&cachedsi,sizeof(*si));
+		return;
+	}
+
+	/* choose sensible defaults ...
+	 * FIXME: perhaps overrideable with precompiler flags?
+	 */
+	cachedsi.u.x.wProcessorArchitecture	= PROCESSOR_ARCHITECTURE_INTEL;
+	cachedsi.dwPageSize 			= 4096;
+
+	/* FIXME: better values for the two entries below... */
+	cachedsi.lpMinimumApplicationAddress	= (void *)0x40000000;
+	cachedsi.lpMaximumApplicationAddress	= (void *)0x80000000;
+	cachedsi.dwActiveProcessorMask		= 1;
+	cachedsi.dwNumberOfProcessors		= 1;
+	cachedsi.dwProcessorType		= PROCESSOR_INTEL_386;
+	cachedsi.dwAllocationGranularity	= 8;
+	cachedsi.wProcessorLevel		= 3; /* 386 */
+	cachedsi.wProcessorRevision		= 0;
+
+	cache = 1; /* even if there is no more info, we now have a cacheentry */
+	memcpy(si,&cachedsi,sizeof(*si));
 
 #ifdef linux
-  if (!cache)
-    {
-      FILE *f = fopen ("/proc/cpuinfo", "r");
-
-      cache = 3;  /* Default.  */
-
-      if (f)
 	{
-	  char info[5], value[5];
-	  while (fscanf (f, " %4s%*s : %4s%*s", info, value) == 2)
-	    if (!lstrcmpi32A(info, "cpu"))
-	      {
-		if (isdigit (value[0]) && value[1] == '8'
-		    && value[2] == '6' && value[3] == 0)
-		  {
-		    cache = value[0] - '0';
-		    break;
-		  }
-	      }
-	  fclose (f);
+	char line[200],info[200],value[200],junk[200];
+	FILE *f = fopen ("/proc/cpuinfo", "r");
+
+	if (!f)
+		return;
+	while (fgets(line,200,f)!=NULL) {
+		if (sscanf(line,"%s%[ \t:]%s",info,junk,value)!=3)
+			continue;
+		if (!lstrncmpi32A(line, "cpu",3)) {
+			if (	isdigit (value[0]) && value[1] == '8' && 
+				value[2] == '6' && value[3] == 0
+			) {
+				switch (value[0] - '0') {
+				case 3:
+					cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
+					cachedsi.wProcessorLevel= 3;
+					break;
+				case 4:
+					cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
+					cachedsi.wProcessorLevel= 4;
+					break;
+				case 5:
+					cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+					cachedsi.wProcessorLevel= 5;
+					break;
+				case 6: /* FIXME does the PPro have a special type? */
+					cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+					cachedsi.wProcessorLevel= 5;
+					break;
+				default:
+					break;
+				}
+			}
+		}
+		if (!lstrncmpi32A(info,"processor",9)) {
+			/* processor number counts up...*/
+			int	x;
+
+			if (sscanf(value,"%d",&x))
+				if (x+1>cachedsi.dwNumberOfProcessors)
+					cachedsi.dwNumberOfProcessors=x+1;
+		}
+		if (!lstrncmpi32A(info,"stepping",8)) {
+			int	x;
+
+			if (sscanf(value,"%d",&x))
+				cachedsi.wProcessorRevision = x;
+		}
 	}
-    }
-  return cache;
+	fclose (f);
+	}
+	memcpy(si,&cachedsi,sizeof(*si));
+	return;
+#else  /* linux */
+	/* FIXME: how do we do this on other systems? */
+	return;
 #endif  /* linux */
-  /* FIXME: how do we do this on other systems? */
-  return 3;
-#endif  /* __i386__ */
 }
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 5909a53..98fc384 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -22,6 +22,7 @@
 #include "xmalloc.h"
 #include "heap.h"
 #include "crtdll.h"
+#include "drive.h"
 
 UINT32 CRTDLL_argc_dll;         /* CRTDLL.23 */
 LPSTR *CRTDLL_argv_dll;         /* CRTDLL.24 */
@@ -764,6 +765,23 @@
 }
 
 /*********************************************************************
+ *                  wcscspn           (CRTDLL.508)
+ */
+INT32 CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
+{
+	LPWSTR	s,t;
+
+	s=str;
+	do {
+		t=reject;
+		while (*t) { if (*t==*s) break;t++;}
+		if (*t) break;
+		s++;
+	} while (*s);
+	return s-str; /* nr of wchars */
+}
+
+/*********************************************************************
  *                  wcschr           (CRTDLL.504)
  */
 LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
@@ -868,3 +886,58 @@
 	fprintf(stdnimp,"CRTDLL.atexit(%p), STUB.\n",x);
 	return 0; /* successful */
 }
+
+/*********************************************************************
+ *                  mbtowc           (CRTDLL.430)
+ * FIXME: check multibyte support
+ */
+WCHAR
+CRTDLL_mbtowc(CHAR a) {
+	return a;
+}
+
+/*********************************************************************
+ *                  _isctype           (CRTDLL.138)
+ */
+BOOL32
+CRTDLL__isctype(CHAR x,CHAR type) {
+	if ((type & CRTDLL_SPACE) && isspace(x))
+		return TRUE;
+	if ((type & CRTDLL_PUNCT) && ispunct(x))
+		return TRUE;
+	if ((type & CRTDLL_LOWER) && islower(x))
+		return TRUE;
+	if ((type & CRTDLL_UPPER) && isupper(x))
+		return TRUE;
+	if ((type & CRTDLL_ALPHA) && isalpha(x))
+		return TRUE;
+	if ((type & CRTDLL_DIGIT) && isdigit(x))
+		return TRUE;
+	if ((type & CRTDLL_CONTROL) && iscntrl(x))
+		return TRUE;
+	/* check CRTDLL_LEADBYTE */
+	return FALSE;
+}
+
+/*********************************************************************
+ *                  _chdrive           (CRTDLL.52)
+ */
+BOOL32
+CRTDLL__chdrive(INT32 newdrive) {
+	/* FIXME: generates errnos */
+	return DRIVE_SetCurrentDrive(newdrive);
+}
+
+/*********************************************************************
+ *                  _errno           (CRTDLL.52)
+ * Yes, this is a function.
+ */
+LPINT32
+CRTDLL__errno() {
+	static	int crtdllerrno;
+	extern int LastErrorToErrno(DWORD);
+
+	/* FIXME: we should set the error at the failing function call time */
+	crtdllerrno = LastErrorToErrno(GetLastError());
+	return &crtdllerrno;
+}
diff --git a/misc/fontengine.c b/misc/fontengine.c
index d999807..376b7f7 100644
--- a/misc/fontengine.c
+++ b/misc/fontengine.c
@@ -11,7 +11,7 @@
 WORD 
 EngineEnumerateFont(LPSTR fontname, FARPROC16 proc, DWORD data )
 {
-    printf("In engineEnumerateFont for %s\n",fontname);
+    printf("In engineEnumerateFont for %s\n",(fontname)?fontname:"NULL");
     return 0;
 }
 #ifdef NOTDEF
diff --git a/misc/keyboard.c b/misc/keyboard.c
deleted file mode 100644
index 25c7771..0000000
--- a/misc/keyboard.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
-static char RCSId[] = "$Id: keyboard.c,v 1.2 1993/09/13 18:52:02 scott Exp $";
-static char Copyright[] = "Copyright  Scott A. Laird, Erik Bos  1993, 1994";
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "windows.h"
-#include "keyboard.h"
-#include "stddebug.h"
-/* #define DEBUG_KEYBOARD */
-#include "debug.h"
-#include "xmalloc.h"
-
-
-struct KeyTableEntry {
-	int virtualkey;
-	int ASCII;
-	int scancode;
-	const char *name;
-};
-
-static const struct KeyTableEntry KeyTable[] =
-{
-	{ VK_CANCEL,	0x3,	0,	"" },
-	{ VK_BACK,	0x8,	0xe,	"Backspace" },
-	{ VK_TAB,	0x9,	0xf,	"Tab" },
-	{ VK_CLEAR,	0,	0x4c,	"Clear" },
-	{ VK_RETURN,	0xd,	0x1c,	"Enter" },
-	{ VK_SHIFT,	0,	0x2a,	"Shift" },
-	{ VK_CONTROL,	0,	0x1d,	"Ctrl" },
-	{ VK_MENU,	0,	0x38,	"Alt" },
-	{ VK_CAPITAL,	0,	0x3a,	"Caps Lock" },
-	{ VK_ESCAPE,	0x1b,	0x1,	"Esc" },
-	{ VK_SPACE,	0x20,	0x39,	"Space" },
-	{ VK_PRIOR,	0,	0x49,	"Page Up" },
-	{ VK_NEXT,	0,	0x51,	"Page Down" },
-	{ VK_END,	0,	0x4f,	"End" },
-	{ VK_HOME,	0,	0x47,	"Home" },
-	{ VK_LEFT,	0,	0x4b,	"Left Arrow" },
-	{ VK_UP,	0,	0x48,	"Up Arrow" },
-	{ VK_RIGHT,	0,	0x4d,	"Right Arrow" },
-	{ VK_DOWN,	0,	0x50,	"Down Arrow" },
-	{ VK_INSERT,	0,	0x52,	"Ins" },
-	{ VK_DELETE,	0,	0x53,	"Del" },
-	{ VK_0,		0x30,	0xb,	"0" },
-	{ VK_1,		0x31,	0x2,	"1" },
-	{ VK_2,		0x32,	0x3,	"2" },
-	{ VK_3,		0x33,	0x4,	"3" },
-	{ VK_4,		0x34,	0x5,	"4" },
-	{ VK_5,		0x35,	0x6,	"5" },
-	{ VK_6,		0x36,	0x7,	"6" },
-	{ VK_7,		0x37,	0x8,	"7" },
-	{ VK_8,		0x38,	0x9,	"8" },
-	{ VK_9,		0x39,	0xa,	"9" },
-	{ VK_A,		0x41,	0x1e,	"A" },
-	{ VK_B,		0x42,	0x30,	"B" },
-	{ VK_C,		0x43,	0x2e,	"C" },
-	{ VK_D,		0x44,	0x20,	"D" },
-	{ VK_E,		0x45,	0x12,	"E" },
-	{ VK_F,		0x46,	0x21,	"F" },
-	{ VK_G,		0x47,	0x22,	"G" },
-	{ VK_H,		0x48,	0x23,	"H" },
-	{ VK_I,		0x49,	0x17,	"I" },
-	{ VK_J,		0x4a,	0x24,	"J" },
-	{ VK_K,		0x4b,	0x25,	"K" },
-	{ VK_L,		0x4c,	0x26,	"L" },
-	{ VK_M,		0x4d,	0x32,	"M" },
-	{ VK_N,		0x4e,	0x31,	"N" },
-	{ VK_O,		0x4f,	0x18,	"O" },
-	{ VK_P,		0x50,	0x19,	"P" },
-	{ VK_Q,		0x51,	0x10,	"Q" },
-	{ VK_R,		0x52,	0x13,	"R" },
-	{ VK_S,		0x53,	0x1f,	"S" },
-	{ VK_T,		0x54,	0x14,	"T" },
-	{ VK_U,		0x55,	0x16,	"U" },
-	{ VK_V,		0x56,	0x2f,	"V" },
-	{ VK_W,		0x57,	0x11,	"W" },
-	{ VK_X,		0x58,	0x2d,	"X" },
-	{ VK_Y,		0x59,	0x15,	"Y" },
-	{ VK_Z,		0x5a,	0x2c,	"Z" },
-	{ VK_NUMPAD0,	0,	0x52,	"Num 0" },
-	{ VK_NUMPAD1,	0,	0x4f,	"Num 1" },
-	{ VK_NUMPAD2,	0,	0x50,	"Num 2" },
-	{ VK_NUMPAD3,	0,	0x51,	"Num 3" },
-	{ VK_NUMPAD4,	0,	0x4b,	"Num 4" },
-	{ VK_NUMPAD5,	0,	0x4c,	"Num 5" },
-	{ VK_NUMPAD6,	0,	0x4d,	"Num 6" },
-	{ VK_NUMPAD7,	0,	0x47,	"Num 7" },
-	{ VK_NUMPAD8,	0,	0x48,	"Num 8" },
-	{ VK_NUMPAD9,	0,	0x49,	"Num 9" },
-	{ VK_MULTIPLY,	0x2a,	0x37,	"Num *" },
-	{ VK_ADD,	0x2b,	0x4e,	"Num +" },
-	{ VK_SEPARATOR,	0,	0,	"" },
-	{ VK_SUBTRACT,	0x2d,	0x4a,	"Num -" },
-	{ VK_DECIMAL,	0x2e,	0x53,	"Num Del" },
-	{ VK_DIVIDE,	0x2f,	0,	"Num /" },
-	{ VK_F1,	0,	0x3b,	"F1" },
-	{ VK_F2,	0,	0x3c,	"F2" },
-	{ VK_F3,	0,	0x3d,	"F3" },
-	{ VK_F4,	0,	0x3e,	"F4" },
-	{ VK_F5,	0,	0x3f,	"F5" },
-	{ VK_F6,	0,	0x40,	"F6" },
-	{ VK_F7,	0,	0x41,	"F7" },
-	{ VK_F8,	0,	0x42,	"F8" },
-	{ VK_F9,	0,	0x43,	"F9" },
-	{ VK_F10,	0,	0x44,	"F10" },
-	{ VK_F11,	0,	0x57,	"F11" },
-	{ VK_F12,	0,	0x58,	"F12" },
-	{ VK_NUMLOCK,	0,	0x45,	"Num Lock" },
-	{ VK_SCROLL,	0,	0x46,	"Scroll Lock" },
-	/* Allowable ranges for OEM-specific virtual-key codes */
-/*	-		    0xBA-0xC0		OEM specific */
-	{ 0xba,		0x3b,	0x27,	";" },
-	{ 0xbb,		0x3d,	0xd,	"=" },
-	{ 0xbc,		0x2c,	0x33,	"," },
-	{ 0xbd,		0x2d,	0xc,	"-" },
-	{ 0xbe,		0x2e,	0x34,	"." },
-	{ 0xbf,		0x2f,	0x35,	"/" },
-	{ 0xc0,		0x60,	0x29,	"`" },
-/*	-		    0xDB-0xE4		OEM specific */
-	{ 0xdb,		0x5b,	0x1a,	"[" },
-	{ 0xdc,		0x5c,	0x2b,	"\\" },
-	{ 0xdd,		0x5d,	0x1b,	"]" },
-	{ 0xde,		0x27,	0x28,	"'" },
-	{ 0xe2,		0x5c,	0x56,	"\\" },
-/*	-		    0xE6		OEM specific */
-/*	-		    0xE9-0xF5		OEM specific */
-};
-
-#define KeyTableSize	sizeof(KeyTable) / sizeof(struct KeyTableEntry)
-
-int ToAscii(WORD wVirtKey, WORD wScanCode, LPSTR lpKeyState, 
-	LPVOID lpChar, WORD wFlags) 
-{
-#if 1
-	return EVENT_ToAscii(wVirtKey, wScanCode, lpKeyState, lpChar, wFlags);
-#else
-	char shift = lpKeyState[VK_SHIFT] < 0;
-	int i;
-
-    	dprintf_keyboard(stddeb, "ToAscii (%x,%x) -> ", wVirtKey, wScanCode);
-
-	/* FIXME: codepage is broken */
-
-	*(BYTE*)lpChar = 0;
-	switch (wVirtKey)
-	  {
-#define vkcase2(k1,k2,val) case val : *(BYTE*)lpChar = shift ? k2 : k1; break;
-#define vkcase(k, val) vkcase2(val, k, val)
-	  WINE_VKEY_MAPPINGS
-#undef vkcase
-#undef vkcase2
-	  default :
-	    for (i = 0 ; ; i++) 
-	      {
-	      if (i == KeyTableSize)
-		{
-		  dprintf_keyboard(stddeb, "0\n");
-		  return 0;
-		}
-	      if (KeyTable[i].virtualkey == wVirtKey)  
-	        {
-		  if (!isprint(KeyTable[i].ASCII) && !isspace(KeyTable[i].ASCII))
-		    {
-		      dprintf_keyboard(stddeb, "0\n");
-		      return 0;
-		    }
-		  dprintf_keyboard(stddeb,"\"%s\" ", KeyTable[i].name);
-
-		  *(BYTE*)lpChar = KeyTable[i].ASCII;
-		  *(((BYTE*)lpChar) + 1) = 0;
-
-		  if (isalpha(*(BYTE*)lpChar))
-		    if( (lpKeyState[VK_CAPITAL]<0 && !lpKeyState[VK_SHIFT]) ||
-			(!lpKeyState[VK_CAPITAL] && lpKeyState[VK_SHIFT]<0) )
-			*(BYTE*)lpChar = toupper( *(BYTE*)lpChar );
-		    else
-			*(BYTE*)lpChar = tolower( *(BYTE*)lpChar );
-		  break;
-	        }
-	     }
-	  }
-	if (lpKeyState[VK_CONTROL] < 0)
-	  *(BYTE*)lpChar = *(BYTE*)lpChar & 0x1f;
-	dprintf_keyboard(stddeb, "1 (%x)\n", *(BYTE*)lpChar);
-	return 1;
-#endif
-}
-
-DWORD OemKeyScan(WORD wOemChar)
-{
-    dprintf_keyboard(stddeb,"*OemKeyScan (%d)\n",wOemChar);
-
-	return wOemChar;
-}
-
-/* VkKeyScan translates an ANSI character to a virtual-key and shift code
- * for the current keyboard.
- * FIXME high-order byte should yield :
- *	0	Unshifted
- *	1	Shift
- *	2	Ctrl
- *	3-5	Shift-key combinations that are not used for characters
- *	6	Ctrl-Alt
- *	7	Ctrl-Alt-Shift
- *	I.e. :	Shift = 1, Ctrl = 2, Alt = 4.
- */
-
-WORD VkKeyScan(WORD cChar)
-{
-	int i;
-	
-    	dprintf_keyboard(stddeb,"VkKeyScan (%d)\n",cChar);
-	
-	for (i = 0 ; i != KeyTableSize ; i++) 
-		if (KeyTable[i].ASCII == cChar)
-			return KeyTable[i].virtualkey;
-
-	return -1;
-}
-
-WORD VkKeyScan32W(WORD cChar)
-{
-	/* lower part of cChar is used anyway */
-	return VkKeyScan(cChar);
-}
-
-int GetKeyboardType(int nTypeFlag)
-{
-  dprintf_keyboard(stddeb,"GetKeyboardType(%d)\n",nTypeFlag);
-  switch(nTypeFlag)
-    {
-    case 0:      /* Keyboard type */
-      return 4;    /* AT-101 */
-      break;
-    case 1:      /* Keyboard Subtype */
-      return 0;    /* There are no defined subtypes */
-      break;
-    case 2:      /* Number of F-keys */
-      return 12;   /* We're doing an 101 for now, so return 12 F-keys */
-      break;
-    default:     
-      fprintf(stderr, "Unknown type on GetKeyboardType\n");
-      return 0;    /* The book says 0 here, so 0 */
-    }
-}
-
-/* MapVirtualKey translates keycodes from one format to another. */
-
-WORD MapVirtualKey(WORD wCode, WORD wMapType)
-{
-	int i;
-	
-	switch(wMapType) {
-		case 0:	/* vkey-code to scan-code */
-			for (i = 0 ; i != KeyTableSize ; i++) 
-				if (KeyTable[i].virtualkey == wCode) 
-					return KeyTable[i].scancode;
-			return 0;
-
-		case 1: /* scan-code to vkey-code */
-			for (i = 0 ; i != KeyTableSize ; i++) 
-				if (KeyTable[i].scancode == wCode) 
-					return KeyTable[i].virtualkey;
-			return 0;
-
-		case 2: /* vkey-code to unshifted ANSI code */
-			/* FIXME : what does unshifted mean ? 'a' or 'A' ? */
-			for (i = 0 ; i != KeyTableSize ; i++) 
-				if (KeyTable[i].virtualkey == wCode) 
-					return KeyTable[i].ASCII;
-			return 0;
-
-		default: /* reserved */
-			fprintf(stderr, "MapVirtualKey: unknown wMapType %d !\n",
-				wMapType);
-			return 0;	
-	}
-	return 0;
-}
-
-int GetKbCodePage(void)
-{
-    	dprintf_keyboard(stddeb,"GetKbCodePage()\n");
-	return 850;
-}
-
-/****************************************************************************
- *	GetKeyNameText32W   (USER32.247)
- */
-INT32 GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
-{
-	LPSTR buf = xmalloc(nSize);
-	int	res = GetKeyNameText32A(lParam,buf,nSize);
-
-	lstrcpynAtoW(lpBuffer,buf,nSize);
-	free(buf);
-	return res;
-}
-
-/****************************************************************************
- *	GetKeyNameText32A   (USER32.246)
- */
-INT32 GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
-{
-	return GetKeyNameText16(lParam,lpBuffer,nSize);
-}
-
-/****************************************************************************
- *	GetKeyNameText16   (KEYBOARD.133)
- */
-INT16 GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
-{
-	int i;
-	
-    	dprintf_keyboard(stddeb,"GetKeyNameText(%ld,<ptr>,%d)\n",lParam,nSize);
-
-	lParam >>= 16;
-	lParam &= 0xff;
-
-	for (i = 0 ; i != KeyTableSize ; i++) 
-		if (KeyTable[i].scancode == lParam)  {
-			lstrcpyn32A( lpBuffer, KeyTable[i].name, nSize );
-			return strlen(lpBuffer);
-		}
-
-	*lpBuffer = 0;
-	return 0;
-}
diff --git a/misc/lstr.c b/misc/lstr.c
index e8a683d..5ea4509 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -567,6 +567,11 @@
 					HeapFree(GetProcessHeap(),0,sprintfbuf);
 					HeapFree(GetProcessHeap(),0,fmtstr);
 					break;
+				case 'n':
+					/* FIXME: perhaps add \r too? */
+					ADD_TO_T('\n');
+					f++;
+					break;
 				case '0':
 					nolinefeed=1;
 					f++;
@@ -760,6 +765,11 @@
 					HeapFree(GetProcessHeap(),0,sprintfbuf);
 					HeapFree(GetProcessHeap(),0,fmtstr);
 					break;
+				case 'n':
+					/* FIXME: perhaps add \r too? */
+					ADD_TO_T('\n');
+					f++;
+					break;
 				case '0':
 					nolinefeed=1;
 					f++;
diff --git a/misc/main.c b/misc/main.c
index 14608d0..5790976 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -774,15 +774,17 @@
 /***********************************************************************
  *	GetWinFlags (KERNEL.132)
  */
-LONG GetWinFlags(void)
+DWORD GetWinFlags(void)
 {
   static const long cpuflags[5] =
     { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
+  SYSTEM_INFO	si;
+  long result = 0,cpuflag;
 
-  long result = 0;
+  GetSystemInfo(&si);
 
   /* There doesn't seem to be any Pentium flag.  */
-  long cpuflag = cpuflags[MIN (runtime_cpu (), 4)];
+  cpuflag = cpuflags[MIN (si.wProcessorLevel, 4)];
 
   switch(Options.mode) {
   case MODE_STANDARD:
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 3df0148..61a1b1f 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -1273,7 +1273,8 @@
 			retString);
 		return 0;
 	}
-	lstrcpyn32A(buf,retString,len);
+	if (buf)
+		lstrcpyn32A(buf,retString,len);
 	return strlen(retString)+1;
 }
 
@@ -1286,9 +1287,9 @@
 	int i;
 	LPSTR abuf = (LPSTR) wbuf;
 	INT32 n = GetLocaleInfoA(lcid, LCType, abuf, len);
-	for (i = n; i > 0; --i) {
-		wbuf[i] = abuf[i];
-	}
+	if (wbuf)
+		for (i = n; i > 0; --i)
+			wbuf[i] = abuf[i];
 	return n;
 }
 
diff --git a/misc/port.c b/misc/port.c
index 3eec824..b16ff0f 100644
--- a/misc/port.c
+++ b/misc/port.c
@@ -9,6 +9,9 @@
 #include <sys/time.h>
 
 #ifndef HAVE_USLEEP
+#ifdef __EMX__
+unsigned int usleep (unsigned int useconds) { DosSleep(useconds); }
+#else
 unsigned int usleep (unsigned int useconds)
 {
     struct timeval delay;
@@ -19,6 +22,7 @@
     select( 0, 0, 0, 0, &delay );
     return 0;
 }
+#endif
 #endif /* HAVE_USLEEP */
 
 #ifndef HAVE_MEMMOVE
diff --git a/misc/winsock.c b/misc/winsock.c
index 336c3fc..5fc4db7 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -18,6 +18,7 @@
 #endif
 #if defined(__EMX__)
 #include <sys/so_ioctl.h>
+#include <sys/param.h>
 #endif
 #include <sys/msg.h>
 #include <sys/wait.h>
@@ -1741,8 +1742,12 @@
 #ifdef EDQUOT
 	case EDQUOT:		return WSAEDQUOT;
 #endif
+#ifdef ESTALE
 	case ESTALE:		return WSAESTALE;
+#endif
+#ifdef EREMOTE
 	case EREMOTE:		return WSAEREMOTE;
+#endif
 
        /* just in case we ever get here and there are no problems */
 	case 0:			return 0;
diff --git a/misc/winsock_async.c b/misc/winsock_async.c
index 863f2ff..64433f4 100644
--- a/misc/winsock_async.c
+++ b/misc/winsock_async.c
@@ -14,6 +14,13 @@
 #include <sys/msg.h>
 #include <sys/wait.h>
 #include <errno.h>
+#ifdef __EMX__
+#include <sys/so_ioctl.h>
+#include <sys/param.h>
+#endif
+#ifndef FASYNC
+#define FASYNC FIOASYNC
+#endif
 #ifdef __svr4__
 #include <sys/file.h>
 #include <sys/filio.h>
@@ -42,7 +49,9 @@
 {
     int fd_flags;
 
+#ifndef __EMX__
     fcntl(fd, F_SETOWN, getpid());
+#endif
 
     fd_flags = fcntl(fd, F_GETFL, 0);
     if (fcntl(fd, F_SETFL, (async)? fd_flags | FASYNC
@@ -213,7 +222,9 @@
   {
      write(async_ctl.ws_aop->fd[1], &async_ctl.lLength, sizeof(unsigned) );
      write(async_ctl.ws_aop->fd[1], async_ctl.buffer, async_ctl.lLength );
+#ifndef __EMX__
      kill(getppid(), SIGIO);    /* simulate async I/O */
+#endif
 #if __WS_ASYNC_DEBUG
   printf("handler - notify aop [%d, buf %d]\n", async_ctl.lLength, async_ctl.ws_aop->buflen);
 #endif
@@ -419,7 +430,9 @@
         (h_errno < 0) ? (unsigned)WSAMAKEASYNCREPLY( 0, wsaErrno() )
                       : (unsigned)WSAMAKEASYNCREPLY( 0, wsaHerrno() );
      write(async_ctl.ws_aop->fd[1], &async_ctl.lLength, sizeof(unsigned) );
+#ifndef __EMX__
      kill(getppid(), SIGIO);    /* simulate async I/O */
+#endif
      pause();
 }
 
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 092d500..2c46b59 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -354,12 +354,16 @@
         break;
 
     case 0x0400:  /* Get DPMI version */
-        AX_reg(context) = 0x005a;  /* DPMI version 0.90 */
-        BX_reg(context) = 0x0005;  /* Flags: 32-bit, virtual memory */
-        CL_reg(context) = runtime_cpu ();
-        DX_reg(context) = 0x0102;  /* Master/slave interrupt controller base*/
-        break;
+    	{
+	    SYSTEM_INFO si;
 
+	    GetSystemInfo(&si);
+	    AX_reg(context) = 0x005a;  /* DPMI version 0.90 */
+	    BX_reg(context) = 0x0005;  /* Flags: 32-bit, virtual memory */
+	    CL_reg(context) = si.wProcessorLevel;
+	    DX_reg(context) = 0x0102;  /* Master/slave interrupt controller base*/
+	    break;
+	}
     case 0x0500:  /* Get free memory information */
         {
             MEMMANINFO mmi;
diff --git a/msdos/int2f.c b/msdos/int2f.c
index 23eb9ab..9cfd796 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -121,16 +121,20 @@
 
     /* FIXME: is this right?  Specs say that this should only be callable
        in real (v86) mode which we never enter.  */
-    case 0x87:  /* DPMI installation check */
-        AX_reg(context) = 0x0000; /* DPMI Installed */
-        BX_reg(context) = 0x0001; /* 32bits available */
-        CL_reg(context) = runtime_cpu();
-        DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
-        SI_reg(context) = 0;      /* # of para. of DOS extended private data */
-        ES_reg(context) = 0;      /* ES:DI is DPMI switch entry point */
-        DI_reg(context) = 0;
-        break;
+    case 0x87: /* DPMI installation check */
+        {
+	    SYSTEM_INFO si;
 
+	    GetSystemInfo(&si);
+	    AX_reg(context) = 0x0000; /* DPMI Installed */
+            BX_reg(context) = 0x0001; /* 32bits available */
+            CL_reg(context) = si.wProcessorLevel;
+            DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
+            SI_reg(context) = 0;      /* # of para. of DOS extended private data */
+            ES_reg(context) = 0;      /* ES:DI is DPMI switch entry point */
+            DI_reg(context) = 0;
+            break;
+        }
     case 0x8a:  /* DPMI get vendor-specific API entry point. */
 	/* The 1.0 specs say this should work with all 0.9 hosts.  */
 	break;
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 791848d..1d81b16 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -27,33 +27,6 @@
 
 extern void CLIPPING_UpdateGCRegion( DC * dc );  /* objects/clipping.c */
 
-/***********************************************************************
- *           BITMAP_Init
- */
-BOOL32 BITMAP_Init(void)
-{
-    Pixmap tmpPixmap;
-    
-      /* Create the necessary GCs */
-    
-    if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 )))
-    {
-	BITMAP_monoGC = XCreateGC( display, tmpPixmap, 0, NULL );
-	XSetGraphicsExposures( display, BITMAP_monoGC, False );
-	XFreePixmap( display, tmpPixmap );
-    }
-
-    if (screenDepth != 1)
-    {
-	if ((tmpPixmap = XCreatePixmap(display, rootWindow, 1,1,screenDepth)))
-	{
-	    BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL );
-	    XSetGraphicsExposures( display, BITMAP_colorGC, False );
-	    XFreePixmap( display, tmpPixmap );
-	}
-    }
-    return TRUE;
-}
 
 
 /***********************************************************************
@@ -441,41 +414,6 @@
 }
     
 
-/***********************************************************************
- *           BITMAP_SelectObject
- */
-HBITMAP16 BITMAP_SelectObject( DC * dc, HBITMAP16 hbitmap,
-                               BITMAPOBJ * bmp )
-{
-    HRGN32 hrgn;
-    HBITMAP16 prevHandle = dc->w.hBitmap;
-    
-    if (!(dc->w.flags & DC_MEMORY)) return 0;
-
-    if (dc->w.hVisRgn)
-       SetRectRgn(dc->w.hVisRgn, 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight );
-    else
-    { 
-       hrgn = CreateRectRgn32(0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
-       if (!hrgn) return 0;
-       dc->w.hVisRgn    = hrgn;
-    }
-
-    dc->u.x.drawable = bmp->pixmap;
-    dc->w.hBitmap    = hbitmap;
-
-      /* Change GC depth if needed */
-
-    if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel)
-    {
-	XFreeGC( display, dc->u.x.gc );
-	dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL );
-	dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
-        DC_InitDC( dc );
-    }
-    else CLIPPING_UpdateGCRegion( dc );  /* Just update GC clip region */
-    return prevHandle;
-}
 
 /***********************************************************************
  *           CreateDiscardableBitmap    (GDI.156) (GDI32.38)
diff --git a/objects/brush.c b/objects/brush.c
index 70f7143..eb8bca2 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -13,130 +13,6 @@
 #include "stddebug.h"
 #include "debug.h"
 
-#define NB_HATCH_STYLES  6
-
-static const char HatchBrushes[NB_HATCH_STYLES][8] =
-{
-    { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HS_HORIZONTAL */
-    { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HS_VERTICAL   */
-    { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HS_FDIAGONAL  */
-    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HS_BDIAGONAL  */
-    { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HS_CROSS      */
-    { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }  /* HS_DIAGCROSS  */
-};
-
-  /* Levels of each primary for dithering */
-#define PRIMARY_LEVELS  3  
-#define TOTAL_LEVELS    (PRIMARY_LEVELS*PRIMARY_LEVELS*PRIMARY_LEVELS)
-
- /* Dithering matrix size  */
-#define MATRIX_SIZE     8
-#define MATRIX_SIZE_2   (MATRIX_SIZE*MATRIX_SIZE)
-
-  /* Total number of possible levels for a dithered primary color */
-#define DITHER_LEVELS   (MATRIX_SIZE_2 * (PRIMARY_LEVELS-1) + 1)
-
-  /* Dithering matrix */
-static const int dither_matrix[MATRIX_SIZE_2] =
-{
-     0, 32,  8, 40,  2, 34, 10, 42,
-    48, 16, 56, 24, 50, 18, 58, 26,
-    12, 44,  4, 36, 14, 46,  6, 38,
-    60, 28, 52, 20, 62, 30, 54, 22,
-     3, 35, 11, 43,  1, 33,  9, 41,
-    51, 19, 59, 27, 49, 17, 57, 25,
-    15, 47,  7, 39, 13, 45,  5, 37,
-    63, 31, 55, 23, 61, 29, 53, 21
-};
-
-  /* Mapping between (R,G,B) triples and EGA colors */
-static const int EGAmapping[TOTAL_LEVELS] =
-{
-    0,  /* 000000 -> 000000 */
-    4,  /* 00007f -> 000080 */
-    12, /* 0000ff -> 0000ff */
-    2,  /* 007f00 -> 008000 */
-    6,  /* 007f7f -> 008080 */
-    6,  /* 007fff -> 008080 */
-    10, /* 00ff00 -> 00ff00 */
-    6,  /* 00ff7f -> 008080 */
-    14, /* 00ffff -> 00ffff */
-    1,  /* 7f0000 -> 800000 */
-    5,  /* 7f007f -> 800080 */
-    5,  /* 7f00ff -> 800080 */
-    3,  /* 7f7f00 -> 808000 */
-    8,  /* 7f7f7f -> 808080 */
-    7,  /* 7f7fff -> c0c0c0 */
-    3,  /* 7fff00 -> 808000 */
-    7,  /* 7fff7f -> c0c0c0 */
-    7,  /* 7fffff -> c0c0c0 */
-    9,  /* ff0000 -> ff0000 */
-    5,  /* ff007f -> 800080 */
-    13, /* ff00ff -> ff00ff */
-    3,  /* ff7f00 -> 808000 */
-    7,  /* ff7f7f -> c0c0c0 */
-    7,  /* ff7fff -> c0c0c0 */
-    11, /* ffff00 -> ffff00 */
-    7,  /* ffff7f -> c0c0c0 */
-    15  /* ffffff -> ffffff */
-};
-
-#define PIXEL_VALUE(r,g,b) \
-    COLOR_mapEGAPixel[EGAmapping[((r)*PRIMARY_LEVELS+(g))*PRIMARY_LEVELS+(b)]]
-
-  /* X image for building dithered pixmap */
-static XImage *ditherImage = NULL;
-
-
-/***********************************************************************
- *           BRUSH_Init
- *
- * Create the X image used for dithering.
- */
-BOOL32 BRUSH_Init(void)
-{
-    XCREATEIMAGE( ditherImage, MATRIX_SIZE, MATRIX_SIZE, screenDepth );
-    return (ditherImage != NULL);
-}
-
-
-/***********************************************************************
- *           BRUSH_DitherColor
- */
-Pixmap BRUSH_DitherColor( DC *dc, COLORREF color )
-{
-    static COLORREF prevColor = 0xffffffff;
-    unsigned int x, y;
-    Pixmap pixmap;
-
-    if (color != prevColor)
-    {
-	int r = GetRValue( color ) * DITHER_LEVELS;
-	int g = GetGValue( color ) * DITHER_LEVELS;
-	int b = GetBValue( color ) * DITHER_LEVELS;
-	const int *pmatrix = dither_matrix;
-
-	for (y = 0; y < MATRIX_SIZE; y++)
-	{
-	    for (x = 0; x < MATRIX_SIZE; x++)
-	    {
-		int d  = *pmatrix++ * 256;
-		int dr = ((r + d) / MATRIX_SIZE_2) / 256;
-		int dg = ((g + d) / MATRIX_SIZE_2) / 256;
-		int db = ((b + d) / MATRIX_SIZE_2) / 256;
-		XPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) );
-	    }
-	}
-	prevColor = color;
-    }
-    
-    pixmap = XCreatePixmap( display, rootWindow,
-			    MATRIX_SIZE, MATRIX_SIZE, screenDepth );
-    XPutImage( display, pixmap, BITMAP_colorGC, ditherImage, 0, 0,
-	       0, 0, MATRIX_SIZE, MATRIX_SIZE );
-    return pixmap;
-}
-
 
 /***********************************************************************
  *           CreateBrushIndirect16    (GDI.50)
@@ -418,134 +294,3 @@
 }
 
 
-/***********************************************************************
- *           BRUSH_SelectSolidBrush
- */
-static void BRUSH_SelectSolidBrush( DC *dc, COLORREF color )
-{
-    if ((dc->w.bitsPerPixel > 1) && (screenDepth <= 8) && !COLOR_IsSolid( color ))
-    {
-	  /* Dithered brush */
-	dc->u.x.brush.pixmap = BRUSH_DitherColor( dc, color );
-	dc->u.x.brush.fillStyle = FillTiled;
-	dc->u.x.brush.pixel = 0;
-    }
-    else
-    {
-	  /* Solid brush */
-	dc->u.x.brush.pixel = COLOR_ToPhysical( dc, color );
-	dc->u.x.brush.fillStyle = FillSolid;
-    }
-}
-
-
-/***********************************************************************
- *           BRUSH_SelectPatternBrush
- */
-static BOOL32 BRUSH_SelectPatternBrush( DC * dc, HBITMAP32 hbitmap )
-{
-    BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
-    if (!bmp) return FALSE;
-    dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow,
-					  8, 8, bmp->bitmap.bmBitsPixel );
-    XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap,
-	       BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 );
-    
-    if (bmp->bitmap.bmBitsPixel > 1)
-    {
-	dc->u.x.brush.fillStyle = FillTiled;
-	dc->u.x.brush.pixel = 0;  /* Ignored */
-    }
-    else
-    {
-	dc->u.x.brush.fillStyle = FillOpaqueStippled;
-	dc->u.x.brush.pixel = -1;  /* Special case (see DC_SetupGCForBrush) */
-    }
-    return TRUE;
-}
-
-
-
-/***********************************************************************
- *           BRUSH_SelectObject
- */
-HBRUSH32 BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush, BRUSHOBJ * brush )
-{
-    HBITMAP16 hBitmap;
-    BITMAPINFO * bmpInfo;
-    HBRUSH16 prevHandle = dc->w.hBrush;
-
-    dprintf_gdi(stddeb, "Brush_SelectObject: hdc=%04x hbrush=%04x\n",
-                dc->hSelf,hbrush);
-    if (dc->header.wMagic == METAFILE_DC_MAGIC)
-    {
-        LOGBRUSH16 logbrush = { brush->logbrush.lbStyle,
-                                brush->logbrush.lbColor,
-                                brush->logbrush.lbHatch };
-	switch (brush->logbrush.lbStyle)
-	{
-	case BS_SOLID:
-	case BS_HATCHED:
-	case BS_HOLLOW:
-	    if (!MF_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
-	    break;
-	case BS_PATTERN:
-	case BS_DIBPATTERN:
-	    if (!MF_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
-	    break;
-	}
-	return 1;  /* FIXME? */
-    }
-    
-    dc->w.hBrush = hbrush;
-
-    if (dc->u.x.brush.pixmap)
-    {
-	XFreePixmap( display, dc->u.x.brush.pixmap );
-	dc->u.x.brush.pixmap = 0;
-    }
-    dc->u.x.brush.style = brush->logbrush.lbStyle;
-    
-    switch(brush->logbrush.lbStyle)
-    {
-      case BS_NULL:
-	dprintf_gdi( stddeb,"BS_NULL\n" );
-	break;
-
-      case BS_SOLID:
-        dprintf_gdi( stddeb,"BS_SOLID\n" );
-	BRUSH_SelectSolidBrush( dc, brush->logbrush.lbColor );
-	break;
-	
-      case BS_HATCHED:
-	dprintf_gdi( stddeb, "BS_HATCHED\n" );
-	dc->u.x.brush.pixel = COLOR_ToPhysical( dc, brush->logbrush.lbColor );
-	dc->u.x.brush.pixmap = XCreateBitmapFromData( display, rootWindow,
-				 HatchBrushes[brush->logbrush.lbHatch], 8, 8 );
-	dc->u.x.brush.fillStyle = FillStippled;
-	break;
-	
-      case BS_PATTERN:
-	dprintf_gdi( stddeb, "BS_PATTERN\n");
-	BRUSH_SelectPatternBrush( dc, (HBRUSH16)brush->logbrush.lbHatch );
-	break;
-
-      case BS_DIBPATTERN:
-	dprintf_gdi( stddeb, "BS_DIBPATTERN\n");
-	if ((bmpInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)brush->logbrush.lbHatch )))
-	{
-	    int size = DIB_BitmapInfoSize( bmpInfo, brush->logbrush.lbColor );
-	    hBitmap = CreateDIBitmap32( dc->hSelf, &bmpInfo->bmiHeader,
-                                        CBM_INIT, ((char *)bmpInfo) + size,
-                                        bmpInfo,
-                                        (WORD)brush->logbrush.lbColor );
-	    BRUSH_SelectPatternBrush( dc, hBitmap );
-	    DeleteObject16( hBitmap );
-	    GlobalUnlock16( (HGLOBAL16)brush->logbrush.lbHatch );	    
-	}
-	
-	break;
-    }
-    
-    return prevHandle;
-}
diff --git a/objects/dc.c b/objects/dc.c
index d3363de..02bc5ce 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -432,6 +432,8 @@
 	newdc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
 	CombineRgn32( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
     }
+    else
+	newdc->w.hClipRgn = 0;
     return handle;
 }
 
diff --git a/objects/font.c b/objects/font.c
index 2489e4d..b4a3a32 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -21,11 +21,8 @@
 #include "stddebug.h"
 #include "debug.h"
 
-#define FONTCACHE 	32	/* dynamic font cache size */
-#define MAX_FONTS	256
-static LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
+LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
 
-static int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz);
 
 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
 			     (((cs)->rbearing|(cs)->lbearing| \
@@ -54,238 +51,8 @@
 #define CI_GET_DEFAULT_INFO(fs,cs) \
   CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
 
-struct FontStructure {
-	char *window;
-	char *x11;
-} FontNames[32];
-int FontSize;
 
 
-/***********************************************************************
- *           FONT_Init
- */
-BOOL32 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)
-      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;
-}
-
 
 /***********************************************************************
  *           FONT_LOGFONT32AToLOGFONT16
@@ -604,165 +371,6 @@
 }
 
 
-/***********************************************************************
- *           FONT_SelectObject
- */
-HFONT16 FONT_SelectObject( DC * dc, HFONT16 hfont, FONTOBJ * font )
-{
-    static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
-
-    static struct {
-		HFONT16		id;
-		LOGFONT16	logfont;
-		int		access;
-		int		used;
-		X_PHYSFONT	cacheFont; } cacheFonts[FONTCACHE], *cacheFontsMin;
-    int 	i;
-
-    X_PHYSFONT * stockPtr;
-    HFONT16 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 (dc->header.wMagic == METAFILE_DC_MAGIC)
-      if (MF_CreateFontIndirect(dc, hfont, &(font->logfont)))
-	return prevHandle;
-      else
-	return 0;
-
-    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;
-}
 
 
 /***********************************************************************
@@ -1277,7 +885,10 @@
  */
 INT AddFontResource( LPCSTR str )
 {
-    fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
+    if (HIWORD(str))
+        fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
+    else
+        fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
     return 1;
 }
 
@@ -1287,15 +898,17 @@
  */
 BOOL RemoveFontResource( LPSTR str )
 {
-    fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
+    if (HIWORD(str))
+        fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
+    else
+        fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
     return TRUE;
 }
 
-
 /*************************************************************************
- *				ParseFontParms		[internal]
+ *				FONT_ParseFontParms		[internal]
  */
-int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
+int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
 {
 	int 	i;
 	if (lpFont == NULL) return 0;
@@ -1318,6 +931,7 @@
 }
 
 
+
 /*************************************************************************
  *				InitFontsList		[internal]
  */
@@ -1362,11 +976,11 @@
   for (i = 0; i < count; i++) {
     dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
 
-    ParseFontParms(names[i], 2, str, sizeof(str));
+    FONT_ParseFontParms(names[i], 2, str, sizeof(str));
     strcpy(lpNewFont->lfFaceName, str);
-    ParseFontParms(names[i], 8, str, sizeof(str));
+    FONT_ParseFontParms(names[i], 8, str, sizeof(str));
     lpNewFont->lfHeight = atoi(str) / 10;
-    ParseFontParms(names[i], 12, str, sizeof(str));
+    FONT_ParseFontParms(names[i], 12, str, sizeof(str));
     lpNewFont->lfWidth = atoi(str) / 10;
     lpNewFont->lfEscapement = 0;
     lpNewFont->lfOrientation = 0;
@@ -1374,7 +988,7 @@
     lpNewFont->lfItalic = 0;
     lpNewFont->lfUnderline = 0;
     lpNewFont->lfStrikeOut = 0;
-    ParseFontParms(names[i], 13, str, sizeof(str));
+    FONT_ParseFontParms(names[i], 13, str, sizeof(str));
     if (strcmp(str, "iso8859") == 0)  {
       lpNewFont->lfCharSet = ANSI_CHARSET;
     } else  {
@@ -1383,7 +997,7 @@
     lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
     lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
     lpNewFont->lfQuality = DEFAULT_QUALITY;
-    ParseFontParms(names[i], 11, str, sizeof(str));
+    FONT_ParseFontParms(names[i], 11, str, sizeof(str));
     switch(str[0]) {
      case 'p':
       lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
@@ -1570,6 +1184,7 @@
   return nRet;
 }
 
+
 /*************************************************************************
  *				EnumFontFamiliesExA	[GDI32.81]
  * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
@@ -1755,3 +1370,4 @@
     for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
     return 0;
 }
+
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 96f7e47..0359343 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -167,18 +167,6 @@
     if (!(hpalette = COLOR_Init())) return FALSE;
     StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LIN_ADDR( hpalette );
 
-      /* Create default bitmap */
-
-    if (!BITMAP_Init()) return FALSE;
-
-      /* Initialize brush dithering */
-
-    if (!BRUSH_Init()) return FALSE;
-
-      /* Initialize fonts */
-
-    if (!FONT_Init()) return FALSE;
-
     return TRUE;
 }
 
@@ -388,37 +376,10 @@
  */
 HGDIOBJ32 SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
 {
-    GDIOBJHDR * ptr = NULL;
-    DC * dc;
-    
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc || !dc->funcs->pSelectObject) return 0;
     dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", hdc, handle );
-    if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
-      ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
-    else 
-      ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
-    if (!ptr) return 0;
-    
-    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return 0;
-    }
-    
-    switch(ptr->wMagic)
-    {
-      case PEN_MAGIC:
-	  return PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
-      case BRUSH_MAGIC:
-	  return BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
-      case BITMAP_MAGIC:
-	  return BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
-      case FONT_MAGIC:
-	  return FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );	  
-      case REGION_MAGIC:
-	  return (HGDIOBJ16)SelectClipRgn16( hdc, handle );
-    }
-    return 0;
+    return dc->funcs->pSelectObject( dc, handle );
 }
 
 
diff --git a/objects/metafile.c b/objects/metafile.c
index c7ee25d..0174c92 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -262,9 +262,18 @@
     HGLOBAL16 hHT;
     int offset = 0;
     WORD i;
+    HPEN32 hPen;
+    HBRUSH32 hBrush;
+    HFONT32 hFont;
+    DC *dc;
 
     dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
-    
+
+    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);
@@ -281,6 +290,10 @@
 	PlayMetaFileRecord(hdc, ht, mr, mh->mtNoObjects);
     }
 
+    SelectObject32(hdc, hBrush);
+    SelectObject32(hdc, hPen);
+    SelectObject32(hdc, hFont);
+
     /* free objects in handle table */
     for(i = 0; i < mh->mtNoObjects; i++)
       if(*(ht->objectHandle + i) != 0)
@@ -364,7 +377,7 @@
       break;
 
     case META_SETBKCOLOR:
-	SetBkColor(hdc, *(mr->rdParam));
+	SetBkColor(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
 	break;
 
     case META_SETBKMODE:
@@ -429,7 +442,7 @@
 	break;
 
     case META_LINETO:
-	LineTo32(hdc, *(mr->rdParam + 1), *(mr->rdParam));
+	LineTo32(hdc, (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_MOVETO:
@@ -447,36 +460,38 @@
 	break;
 
     case META_ARC:
-	Arc32(hdc, *(mr->rdParam + 7), *(mr->rdParam + 6), *(mr->rdParam + 5),
-              *(mr->rdParam + 4), *(mr->rdParam + 3), *(mr->rdParam + 2),
-              *(mr->rdParam + 1), *(mr->rdParam));
+	Arc32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
+	      (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
+	      (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+             (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_ELLIPSE:
-	Ellipse32(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
-                  *(mr->rdParam + 1), *(mr->rdParam));
+	Ellipse32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+                  (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_FLOODFILL:
-	FloodFill32(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
-                    MAKELONG(*(mr->rdParam + 1), *(mr->rdParam)));
+	FloodFill32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+                    MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
 	break;
 
     case META_PIE:
-	Pie32(hdc, *(mr->rdParam + 7), *(mr->rdParam + 6), *(mr->rdParam + 5),
-              *(mr->rdParam + 4), *(mr->rdParam + 3), *(mr->rdParam + 2),
-              *(mr->rdParam + 1), *(mr->rdParam));
+	Pie32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
+	      (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
+	      (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+             (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_RECTANGLE:
-	Rectangle32(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
-                    *(mr->rdParam + 1), *(mr->rdParam));
+	Rectangle32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+                    (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_ROUNDRECT:
-	RoundRect32(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
-                    *(mr->rdParam + 3), *(mr->rdParam + 2),
-                    *(mr->rdParam + 1), *(mr->rdParam));
+	RoundRect32(hdc, (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
+                    (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+                    (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_PATBLT:
@@ -490,8 +505,8 @@
 	break;
 
     case META_SETPIXEL:
-	SetPixel32(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
-                   MAKELONG(*(mr->rdParam + 1), *(mr->rdParam)));
+	SetPixel32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+                   MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
 	break;
 
     case META_OFFSETCLIPRGN:
@@ -519,7 +534,7 @@
 	break;
 
     case META_RESTOREDC:
-	RestoreDC32(hdc, *(mr->rdParam));
+	RestoreDC32(hdc, (INT16)*(mr->rdParam));
 	break;
 
     case META_SELECTOBJECT:
@@ -527,9 +542,10 @@
 	break;
 
     case META_CHORD:
-	Chord32(hdc, *(mr->rdParam + 7), *(mr->rdParam + 6), *(mr->rdParam+5),
-                *(mr->rdParam + 4), *(mr->rdParam + 3), *(mr->rdParam + 2),
-                *(mr->rdParam + 1), *(mr->rdParam));
+	Chord32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
+		(INT16)*(mr->rdParam+5), (INT16)*(mr->rdParam + 4),
+		(INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
+               (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
 	break;
 
     case META_CREATEPATTERNBRUSH:
@@ -677,9 +693,9 @@
                             mr->rdParam[10]/*Planes*/,mr->rdParam[11]/*BitsPixel*/,
                             (LPSTR)&mr->rdParam[12]/*bits*/);
        SelectObject32(hdcSrc,hbitmap);
-       BitBlt32(hdc,mr->rdParam[6],mr->rdParam[5],
-                mr->rdParam[4],mr->rdParam[3],
-                hdcSrc, mr->rdParam[2],mr->rdParam[1],
+       BitBlt32(hdc,(INT16)mr->rdParam[6],(INT16)mr->rdParam[5],
+                (INT16)mr->rdParam[4],(INT16)mr->rdParam[3],
+                hdcSrc, (INT16)mr->rdParam[2],(INT16)mr->rdParam[1],
                 MAKELONG(0,mr->rdParam[0]));
        DeleteDC32(hdcSrc);		    
       }
@@ -771,7 +787,7 @@
 	    return FALSE;
         break;
     default:
-        fprintf( stderr, "Uknown metafile type %d\n", physDev->mh->mtType );
+        fprintf( stderr, "Unknown metafile type %d\n", physDev->mh->mtType );
         return FALSE;
     }
 
diff --git a/objects/pen.c b/objects/pen.c
index 9bb51ee..2cca576 100644
--- a/objects/pen.c
+++ b/objects/pen.c
@@ -12,10 +12,6 @@
 #include "debug.h"
 
 
-static const char PEN_dash[]       = { 5,3 };      /* -----   -----   -----  */
-static const char PEN_dot[]        = { 1,1 };      /* --  --  --  --  --  -- */
-static const char PEN_dashdot[]    = { 4,3,2,3 };  /* ----   --   ----   --  */
-static const char PEN_dashdotdot[] = { 4,2,2,2,2,2 }; /* ----  --  --  ----  */
 
 /***********************************************************************
  *           CreatePen16    (GDI.61)
@@ -102,50 +98,3 @@
     return count;
 }
 
-
-/***********************************************************************
- *           PEN_SelectObject
- */
-HPEN32 PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen )
-{
-    HPEN32 prevHandle = dc->w.hPen;
-
-    if (dc->header.wMagic == METAFILE_DC_MAGIC)
-    {
-        LOGPEN16 logpen = { pen->logpen.lopnStyle,
-                            { pen->logpen.lopnWidth.x,
-                              pen->logpen.lopnWidth.y },
-                            pen->logpen.lopnColor };
-        if (MF_CreatePenIndirect( dc, hpen, &logpen )) return prevHandle;
-        else return 0;
-    }
-
-    dc->w.hPen = hpen;
-
-    dc->u.x.pen.style = pen->logpen.lopnStyle;
-    dc->u.x.pen.width = pen->logpen.lopnWidth.x * dc->vportExtX / dc->wndExtX;
-    if (dc->u.x.pen.width < 0) dc->u.x.pen.width = -dc->u.x.pen.width;
-    if (dc->u.x.pen.width == 1) dc->u.x.pen.width = 0;  /* Faster */
-    dc->u.x.pen.pixel = COLOR_ToPhysical( dc, pen->logpen.lopnColor );    
-    switch(pen->logpen.lopnStyle)
-    {
-      case PS_DASH:
-	dc->u.x.pen.dashes = (char *)PEN_dash;
-	dc->u.x.pen.dash_len = 2;
-	break;
-      case PS_DOT:
-	dc->u.x.pen.dashes = (char *)PEN_dot;
-	dc->u.x.pen.dash_len = 2;
-	break;
-      case PS_DASHDOT:
-	dc->u.x.pen.dashes = (char *)PEN_dashdot;
-	dc->u.x.pen.dash_len = 4;
-	break;
-      case PS_DASHDOTDOT:
-	dc->u.x.pen.dashes = (char *)PEN_dashdotdot;
-	dc->u.x.pen.dash_len = 6;
-	break;
-    }
-    
-    return prevHandle;
-}
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog
index d24c29a..aeea3e2 100644
--- a/programs/progman/ChangeLog
+++ b/programs/progman/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jan 24 11:21:30 1997  Bang Jun-Young  <bangjy@nownuri.nowcom.co.kr>
+
+	* [Ko.rc] (new)
+	Added Korean language support.
+
 Mon Jul 22 20:30:11 1996  Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
 
 	* [Fi.rc] (new)
diff --git a/programs/progman/Ko.rc b/programs/progman/Ko.rc
new file mode 100644
index 0000000..d6d92a4
--- /dev/null
+++ b/programs/progman/Ko.rc
@@ -0,0 +1,119 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#define LANGUAGE_ID                  Ko
+#define LANGUAGE_NUMBER              6
+#define LANGUAGE_MENU_ITEM           "&Korean"
+
+/* Menu */
+
+#define MENU_FILE                    "ÆÄÀÏ(&F)"
+#define MENU_FILE_NEW                "»õ ÆÄÀÏ(&N)..."
+#define MENU_FILE_OPEN               "¿­±â(&P)\tEnter"
+#define MENU_FILE_MOVE               "À̵¿(&M)...\tF7"
+#define MENU_FILE_COPY               "º¹»ç(&C)...\tF8"
+#define MENU_FILE_DELETE             "»èÁ¦(&D)\tEntf"
+#define MENU_FILE_ATTRIBUTES         "¼Ó¼º(&A)...\tAlt+Enter"
+#define MENU_FILE_EXECUTE            "½ÇÇà(&E)..."
+#define MENU_FILE_EXIT               "À©µµ¿ì Á¾·á(&X)..."
+
+#define MENU_OPTIONS                 "¿É¼Ç(&O)"
+#define MENU_OPTIONS_AUTO_ARRANGE    "ÀÚµ¿ Á¤·Ä(&A)"
+#define MENU_OPTIONS_MIN_ON_RUN      "½ÇÇà½Ã ¾ÆÀÌÄÜÀ¸·Î µÊ(&M)"
+#define MENU_OPTIONS_SAVE_SETTINGS   "Á¾·á½Ã ¼³Á¤ ³»¿ë ÀúÀå(&S)"
+
+#define MENU_WINDOWS                 "â(&W)"
+#define MENU_WINDOWS_OVERLAP         "Áßø(&O)\tShift+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE    "ºÐÇÒ(&S)\tShift+F4"
+#define MENU_WINDOWS_ARRANGE         "¾ÆÀÌÄÜ Á¤·Ä(&A)"
+
+#define MENU_LANGUAGE                "¾ð¾î(&L)"
+
+#define MENU_HELP                    "µµ¿ò¸»(&H)"
+#define MENU_HELP_CONTENTS           "¸ñÂ÷(&C)"
+#define MENU_HELP_SEARCH             "ã±â(&S)..."
+#define MENU_HELP_HELP_ON_HELP       "µµ¿ò¸» »ç¿ë¹ý(&H)"
+#define MENU_HELP_TUTORIAL           "ÀÚ½À¼­(&T)"
+
+#define MENU_INFO                    "Á¤º¸(&I)..."
+#define MENU_INFO_LICENSE            "¶óÀ̼¾½º(&L)"
+#define MENU_INFO_NO_WARRANTY        "¹«º¸Áõ(&N)"
+#define MENU_INFO_ABOUT_WINE         "¿ÍÀο¡ °üÇÏ¿©(&A)"
+
+/* Dialogs */
+
+#define DIALOG_OK                    "È®ÀÎ"
+#define DIALOG_CANCEL                "Ãë¼Ò"
+#define DIALOG_BROWSE                "°Ë»ö(&B)"
+#define DIALOG_HELP                  "µµ¿ò¸»(&H)"
+
+#define DIALOG_NEW_CAPTION           "»õ ÇÁ·Î±×·¥ °³Ã¼"
+#define DIALOG_NEW_NEW               "»õ °³Ã¼"
+#define DIALOG_NEW_GROUP             "ÇÁ·Î±×·¥ ±×·ì(&G)"
+#define DIALOG_NEW_PROGRAM           "ÇÁ·Î±×·¥(&P)"
+
+#define DIALOG_MOVE_CAPTION          "ÇÁ·Î±×·¥ À̵¿"
+#define DIALOG_MOVE_PROGRAM          "ÇÁ·Î±×·¥ À̵¿:"
+#define DIALOG_MOVE_FROM_GROUP       "À̵¿ Àü:"
+#define DIALOG_MOVE_TO_GROUP         "À̵¿ ÈÄ(&T):"
+
+#define DIALOG_COPY_CAPTION          "ÇÁ·Î±×·¥ º¹»ç"
+#define DIALOG_COPY_PROGRAM          "ÇÁ·Î±×·¥ º¹»ç:"
+#define DIALOG_COPY_FROM_GROUP       DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP         DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_CAPTION         "ÇÁ·Î±×·¥ ±×·ì ¼Ó¼º"
+#define DIALOG_GROUP_DESCRIPTION     "¼³¸í(&D):"
+#define DIALOG_GROUP_FILE            "±×·ì ÆÄÀÏ(&G):"
+
+#define DIALOG_PROGRAM_CAPTION       "ÇÁ·Î±×·¥ ¼Ó¼º"
+#define DIALOG_PROGRAM_DESCRIPTION   DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE  "¸í·ÉÇà(&C):"
+#define DIALOG_PROGRAM_DIRECTORY     "ÀÛ¾÷ µð·ºÅ丮(&W):"
+#define DIALOG_PROGRAM_HOT_KEY       "Å° Á¶ÇÕ(&K):"
+#define DIALOG_PROGRAM_SYMBOL        "¾ÆÀÌÄÜÀ¸·Î(&S)"
+#define DIALOG_PROGRAM_OTHER_SYMBOL  "´Ù¸¥ ¾ÆÀÌÄÜ(&O)..."
+
+#define DIALOG_SYMBOL_CAPTION        "¾ÆÀÌÄÜ ¼±ÅÃ"
+#define DIALOG_SYMBOL_FILE           "ÆÄÀϸí(&F):"
+#define DIALOG_SYMBOL_CURRENT        "ÇöÀç ¾ÆÀÌÄÜ(&C):"
+
+#define DIALOG_EXECUTE_CAPTION       "ÇÁ·Î±×·¥ ½ÇÇà"
+#define DIALOG_EXECUTE_COMMAND_LINE  DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL        DIALOG_PROGRAM_SYMBOL
+
+/* Strings */
+
+#define STRING_PROGRAM_MANAGER            "ÇÁ·Î±×·¥ °ü¸®ÀÚ"
+#define STRING_ERROR                      "¿À·ù"
+#define STRING_WARNING                    "°æ°í"
+#define STRING_INFO                       "Á¤º¸"
+#define STRING_DELETE                     "»èÁ¦"
+#define STRING_DELETE_GROUP_s             "±×·ì `%s'¸¦ »èÁ¦ÇÒ±î¿ä?"
+#define STRING_DELETE_PROGRAM_s           "ÇÁ·Î±×·¥ `%s'¸¦ »èÁ¦ÇÒ±î¿ä?"
+#define STRING_NOT_IMPLEMENTED            "±¸ÇöµÇÁö ¾Ê¾ÒÀ½"
+#define STRING_FILE_READ_ERROR_s          "`%s' Àб⠿À·ù"
+#define STRING_FILE_WRITE_ERROR_s         "`%s' ¾²±â ¿À·ù"
+
+#define STRING_GRPFILE_READ_ERROR_s       "\
+±×·ì ÆÄÀÏ `%s'¸¦ ¿­ ¼ö ¾ø½À´Ï´Ù.\n\
+Çѹø ´õ ½ÃµµÇØ º¼±î¿ä?"
+
+#define STRING_OUT_OF_MEMORY              "¸Þ¸ð¸® ºÎÁ·"
+#define STRING_WINHELP_ERROR              "µµ¿ò¸»ÀÌ ¾ø½À´Ï´Ù"
+#define STRING_UNKNOWN_FEATURE_s          "%s¿¡ ¾Ë ¼ö ¾ø´Â ±â´ÉÀÌ ÀÖÀ½"
+#define STRING_FILE_NOT_OVERWRITTEN_s     "ÆÄÀÏ `%s'°¡ Á¸ÀçÇÕ´Ï´Ù. µ¤¾î¾²Áö ¾Ê½À´Ï´Ù."
+#define STRING_SAVE_GROUP_AS_s            "¿ø·¡ ÆÄÀÏÀ» µ¤¾î¾²´Â °ÍÀ» ¸·±â À§ÇØ ±×·ìÀ» `%s'·Î ÀúÀåÇÕ´Ï´Ù"
+
+#define STRING_NO_HOT_KEY                 "¾øÀ½"
+
+#define STRING_ALL_FILES                  "¸ðµç ÆÄÀÏ (*.*)"
+#define STRING_PROGRAMS                   "ÇÁ·Î±×·¥"
+#define STRING_LIBRARIES_DLL              "¶óÀ̺귯¸® (*.dll)"
+#define STRING_SYMBOL_FILES               "¾ÆÀÌÄÜ ÆÄÀÏ"
+#define STRING_SYMBOLS_ICO                "¾ÆÀÌÄÜ (*.ico)"
+
+#include "Xx.rc"
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index ea2e954..16d1167 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -8,7 +8,7 @@
 DEFS      = -I$(SRCDIR)
 RCFLAGS   = -w32
 
-LANGUAGES   = En De Fr Fi
+LANGUAGES   = En De Fr Fi Ko
 LICENSELANG = En
 
 # Installation infos
diff --git a/programs/winhelp/ChangeLog b/programs/winhelp/ChangeLog
index aa692bc..f86e4c6 100644
--- a/programs/winhelp/ChangeLog
+++ b/programs/winhelp/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jan 24 11:27:37 1997  Bang Jun-Young  <bangjy@nownuri.nowcom.co.kr>
+
+	* [Ko.rc] (new)
+	Added Korean language support.
+
 Mon Jul 22 20:30:11 1996  Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
 
 	* [Fi.rc] (new)
diff --git a/programs/winhelp/Ko.rc b/programs/winhelp/Ko.rc
new file mode 100644
index 0000000..4bb23ae
--- /dev/null
+++ b/programs/winhelp/Ko.rc
@@ -0,0 +1,48 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+/* This file is not yet complete !! */
+
+#define LANGUAGE_ID                  Ko
+#define LANGUAGE_NUMBER              6
+
+/* Menu */
+
+#define MENU_FILE                    "ÆÄÀÏ(&F)"
+#define MENU_FILE_OPEN               "¿­±â(&O)..."
+#define MENU_FILE_PRINT              "Àμâ(&P)"
+#define MENU_FILE_PRINTER_SETUP      "ÇÁ¸°ÅÍ ¼³Á¤(&S)..."
+#define MENU_FILE_EXIT               "Á¾·á(&E)"
+
+#define MENU_EDIT                    "ÆíÁý(&E)"
+#define MENU_EDIT_COPY_DIALOG        "º¹»ç(&C)..."
+#define MENU_EDIT_ANNOTATE           "ÁÖ¼®(&A)..."
+
+#define MENU_BOOKMARK                "Ã¥°¥ÇÇ(&B)"
+#define MENU_BOOKMARK_DEFINE         "Á¤ÀÇ(&D)..."
+
+#define MENU_HELP                    "µµ¿ò¸»(&H)"
+#define MENU_HELP_ON_HELP            "µµ¿ò¸» »ç¿ë¹ý(&O)"
+#define MENU_HELP_ON_TOP             "Ç×»ó À§(&T)"
+#define MENU_HELP_INFO               "Á¤º¸(&I)..."
+#define MENU_HELP_ABOUT_WINE         "¿ÍÀο¡ °üÇÏ¿©(&A)"
+
+/* Strings */
+
+#define STRING_WINE_HELP             "¿ÍÀÎ µµ¿ò¸»"
+#define STRING_ERROR                 "¿À·ù"
+#define STRING_WARNING               "°æ°í"
+#define STRING_INFO                  "Á¤º¸"
+#define STRING_NOT_IMPLEMENTED       "±¸ÇöµÇÁö ¾Ê¾ÒÀ½"
+#define STRING_HLPFILE_ERROR_s       "µµ¿ò¸» ÆÄÀÏ `%s'¸¦ Àд µµÁß ¿À·ù ¹ß»ý"
+#define STRING_CONTENTS              "¸ñÂ÷(&C)"
+#define STRING_SEARCH                "ã±â(&S)"
+#define STRING_BACK                  "µÚ·Î(&B)"
+#define STRING_HISTORY               "È÷½ºÅ丮(&H)"
+#define STRING_ALL_FILES             "¸ðµç ÆÄÀÏ (*.*)"
+#define STRING_HELP_FILES_HLP        "µµ¿ò¸» ÆÄÀÏ (*.hlp)"
+
+#include "Xx.rc"
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index d70b716..56ed29a 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -7,7 +7,7 @@
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 RCFLAGS   = -w32
 
-LANGUAGES   = En De Fr Fi
+LANGUAGES   = En De Fr Fi Ko
 
 # Installation infos
 
diff --git a/resources/sysres_It.rc b/resources/sysres_It.rc
index afa6d03..d32bb8b 100644
--- a/resources/sysres_It.rc
+++ b/resources/sysres_It.rc
@@ -17,14 +17,14 @@
 {
 	POPUP ""
 	BEGIN
-		MENUITEM "&Undo", EM_UNDO32
+                MENUITEM "&Annulla", EM_UNDO32
 		MENUITEM SEPARATOR
-		MENUITEM "Cu&t", WM_CUT
-		MENUITEM "&Copy", WM_COPY
-		MENUITEM "&Paste", WM_PASTE
-		MENUITEM "&Delete", WM_CLEAR
+                MENUITEM "&Taglia", WM_CUT
+                MENUITEM "&Copia", WM_COPY
+                MENUITEM "&Incolla", WM_PASTE
+                MENUITEM "&Elimina", WM_CLEAR
 		MENUITEM SEPARATOR
-		MENUITEM "Select &All", EM_SETSEL32
+                MENUITEM "Sele&ziona tutto", EM_SETSEL32
 	END
 }
 
@@ -91,7 +91,7 @@
  LTEXT "&Unita':", 1091, 110, 104, 92, 9
  COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
  DEFPUSHBUTTON "Salva come", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Cancel", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Annulla", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
  PUSHBUTTON "&Help", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
  CHECKBOX "&Read Only", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
 }
diff --git a/resources/sysres_Ko.rc b/resources/sysres_Ko.rc
index ab26d06..646c8c3 100644
--- a/resources/sysres_Ko.rc
+++ b/resources/sysres_Ko.rc
@@ -3,8 +3,8 @@
  MENUITEM "º¹±Í(&R)", 61728
  MENUITEM "À̵¿(&M)", 61456
  MENUITEM "Å©±â º¯°æ(&S)", 61440
- MENUITEM "Ãà¼Ò(&N)", 61472
- MENUITEM "È®´ë(&M)", 61488
+ MENUITEM "¾ÆÀÌÄÜ Ç¥½Ã(&N)", 61472
+ MENUITEM "Àüü È­¸é Ç¥½Ã(&M)", 61488
  MENUITEM SEPARATOR
  MENUITEM "´Ý±â(&C)\tAlt-F4", 61536
  MENUITEM SEPARATOR
@@ -17,14 +17,14 @@
 {
 	POPUP ""
 	BEGIN
-		MENUITEM "&Undo", EM_UNDO32
+		MENUITEM "½ÇÇà Ãë¼Ò(&U)", EM_UNDO32
 		MENUITEM SEPARATOR
-		MENUITEM "Cu&t", WM_CUT
-		MENUITEM "&Copy", WM_COPY
-		MENUITEM "&Paste", WM_PASTE
-		MENUITEM "&Delete", WM_CLEAR
+		MENUITEM "À߶󳻱â(&T)", WM_CUT
+		MENUITEM "º¹»ç(&C)", WM_COPY
+		MENUITEM "ºÙ¿©³Ö±â(&P)", WM_PASTE
+		MENUITEM "»èÁ¦(&D)", WM_CLEAR
 		MENUITEM SEPARATOR
-		MENUITEM "Select &All", EM_SETSEL32
+		MENUITEM "Àüü ¼±ÅÃ(&A)", EM_SETSEL32
 	END
 }
 
@@ -33,7 +33,7 @@
 BEGIN
 	ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
 	LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
-	PUSHBUTTON "½ÂÀÎ(&O)", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+	PUSHBUTTON "È®ÀÎ(&O)", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
 	PUSHBUTTON "Ãë¼Ò(&C)", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
 	PUSHBUTTON "Áß´Ü(&A)", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
 	PUSHBUTTON "Àç½Ãµµ(&R)", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
@@ -47,7 +47,7 @@
 CAPTION "%s¿¡ °üÇÏ¿©"
 FONT 10, "System"
 {
- DEFPUSHBUTTON "½ÂÀÎ", 1, 91, 250, 40, 14
+ DEFPUSHBUTTON "È®ÀÎ", 1, 91, 250, 40, 14
  CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 215, 210
  LTEXT "Text", 100, 11, 40, 200, 200, SS_NOPREFIX | WS_GROUP
  ICON "", 1088, 195, 10, 18, 20
@@ -131,7 +131,7 @@
  LTEXT "[¾øÀ½]", 1088, 35, 35, 120, 9
  RADIOBUTTON "ÁöÁ¤µÈ Àμâ±â(&P)", 1057, 16, 50, 80, 12
  COMBOBOX 1136, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "½ÂÀÎ", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "È®ÀÎ", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
  PUSHBUTTON "Ãë¼Ò", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
  PUSHBUTTON "¼³Á¤(&S)", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
  GROUPBOX "¹æÇâ", 1073, 6, 85, 100, 50, BS_GROUPBOX
@@ -154,7 +154,7 @@
 {
  LTEXT "±ÛÀÚü:", 1088, 6, 6, 40, 9
  LTEXT "", 1089, 60, 6, 150, 9
- DEFPUSHBUTTON "½ÂÀÎ", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "È®ÀÎ", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
  PUSHBUTTON "Ãë¼Ò", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
 }
 
@@ -184,7 +184,7 @@
  CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116
  CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
  CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
- DEFPUSHBUTTON "½ÂÀÎ",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "È®ÀÎ",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
  PUSHBUTTON "Ãë¼Ò", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
  PUSHBUTTON "µµ¿ò¸»", 1038,100,166, 44, 14
  PUSHBUTTON "»ç¿ëÀÚ»ö¿¡ Ãß°¡(&A)",    712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
diff --git a/scheduler/thread.c b/scheduler/thread.c
index acc64a1..0b48efe 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -5,6 +5,7 @@
  */
 
 #include <assert.h>
+#include <stdio.h>
 #include "thread.h"
 #include "winerror.h"
 #include "heap.h"
@@ -13,11 +14,31 @@
 
 THDB *pCurrentThread = NULL;
 
+/***********************************************************************
+ *           THREAD_GetPtr
+ *
+ * Return a pointer to a thread object. The object count must be decremented
+ * when no longer used.
+ */
+static THDB *THREAD_GetPtr( HANDLE32 handle )
+{
+    THDB *thread;
+
+    if (handle == 0xfffffffe)  /* Self-thread handle */
+    {
+        thread = (THDB *)GetCurrentThreadId();
+        K32OBJ_IncCount( &thread->header );
+    }
+    else thread = (THDB *)PROCESS_GetObjPtr( handle, K32OBJ_THREAD );
+    return thread;
+}
+
 
 /***********************************************************************
  *           THREAD_Create
  */
-THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size )
+THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size,
+                     LPTHREAD_START_ROUTINE start_addr )
 {
     THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) );
     if (!thdb) return NULL;
@@ -49,6 +70,19 @@
     thdb->teb_sel = SELECTOR_AllocBlock( &thdb->teb, 0x1000, SEGMENT_DATA,
                                          TRUE, FALSE );
     if (!thdb->teb_sel) goto error;
+
+    /* Initialize the thread context */
+
+    thdb->pcontext        = &thdb->context;
+    thdb->context.SegCs   = WINE_CODE_SELECTOR;
+    thdb->context.SegDs   = WINE_DATA_SELECTOR;
+    thdb->context.SegEs   = WINE_DATA_SELECTOR;
+    thdb->context.SegFs   = thdb->teb_sel;
+    thdb->context.SegGs   = WINE_DATA_SELECTOR;
+    thdb->context.SegSs   = WINE_DATA_SELECTOR;
+    thdb->context.Eip     = (DWORD)start_addr;
+    thdb->context.Esp     = (DWORD)thdb->teb.stack_top;
+
     return thdb;
 
 error:
@@ -73,6 +107,30 @@
 
 
 /***********************************************************************
+ *           CreateThread   (KERNEL32.63)
+ *
+ * The only thing missing here is actually getting the thread to run ;-)
+ */
+HANDLE32 CreateThread( LPSECURITY_ATTRIBUTES attribs, DWORD stack,
+                       LPTHREAD_START_ROUTINE start, LPVOID param,
+                       DWORD flags, LPDWORD id )
+{
+    HANDLE32 handle;
+    THDB *thread = THREAD_Create( pCurrentProcess, stack, start );
+    if (!thread) return INVALID_HANDLE_VALUE32;
+    handle = PROCESS_AllocHandle( &thread->header, 0 );
+    if (handle == INVALID_HANDLE_VALUE32)
+    {
+        THREAD_Destroy( &thread->header );
+        return INVALID_HANDLE_VALUE32;
+    }
+    *id = (DWORD)thread;
+    fprintf( stderr, "CreateThread: stub\n" );
+    return handle;
+}
+
+
+/***********************************************************************
  *           GetCurrentThread   (KERNEL32.200)
  */
 HANDLE32 GetCurrentThread(void)
@@ -219,7 +277,11 @@
  */
 BOOL32 GetThreadContext( HANDLE32 handle, CONTEXT *context )
 {
-    return FALSE;
+    THDB *thread = (THDB*)PROCESS_GetObjPtr( handle, K32OBJ_THREAD );
+    if (!thread) return FALSE;
+    *context = thread->context;
+    K32OBJ_DecCount( &thread->header );
+    return TRUE;
 }
 
 
@@ -231,34 +293,31 @@
     EAX_reg(context) = GetSelectorBase( FS_reg(context) );
 }
 
+
 /**********************************************************************
  *           GetThreadPriority   (KERNEL32.296)
  */
-INT32
-GetThreadPriority(HANDLE32 hthread) {
+INT32 GetThreadPriority(HANDLE32 hthread)
+{
     THDB *thread;
     INT32 ret;
     
-    ret = 0;
-    thread = (THDB*)PROCESS_GetObjPtr(hthread,K32OBJ_THREAD);
-    if (thread) {
-    	ret = thread->delta_priority;
-	K32OBJ_DecCount((K32OBJ*)thread);
-    }
+    if (!(thread = THREAD_GetPtr( hthread ))) return 0;
+    ret = thread->delta_priority;
+    K32OBJ_DecCount( &thread->header );
     return ret;
 }
 
+
 /**********************************************************************
  *           SetThreadPriority   (KERNEL32.514)
  */
-BOOL32
-SetThreadPriority(HANDLE32 hthread,INT32 priority) {
+BOOL32 SetThreadPriority(HANDLE32 hthread,INT32 priority)
+{
     THDB *thread;
     
-    thread = (THDB*)PROCESS_GetObjPtr(hthread,K32OBJ_THREAD);
-    if (thread) {
-	thread->delta_priority = priority;
-	K32OBJ_DecCount((K32OBJ*)thread);
-    }
+    if (!(thread = THREAD_GetPtr( hthread ))) return FALSE;
+    thread->delta_priority = priority;
+    K32OBJ_DecCount( &thread->header );
     return TRUE;
 }
diff --git a/tools/build.c b/tools/build.c
index 866aaf0..e88e24e 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -26,6 +26,12 @@
 # define PREFIX
 #endif
 
+#if defined(__GNUC__) && !defined(__svr4__)
+# define USE_STABS
+#else
+# undef USE_STABS
+#endif
+
 typedef enum
 {
     TYPE_INVALID,
@@ -980,7 +986,7 @@
 
     fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
     fprintf( outfile, "\t.file\t\"%s\"\n", specfile );
-#ifdef __GNUC__
+#ifdef USE_STABS
     getcwd(buffer, sizeof(buffer));
 
     /*
@@ -1008,14 +1014,14 @@
         case TYPE_STUB:
         case TYPE_REGISTER:
             fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
-#ifdef __GNUC__
+#ifdef USE_STABS
 	    fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n", 
 		     DLLName, i,
 		     odp->lineno, DLLName, i);
 #endif
 
             fprintf( outfile, "%s_%d:\n", DLLName, i );
-#ifdef __GNUC__
+#ifdef USE_STABS
 	    fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
 #endif
 
@@ -1138,7 +1144,7 @@
     fprintf( outfile, "\t.long Code_Start\n" );       /* Code start */
     fprintf( outfile, "\t.long Functions\n" );        /* Functions */
     fprintf( outfile, "\t.long FuncNames\n" );        /* Function names */
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
     fprintf( outfile, ".Letext:\n");
@@ -1324,7 +1330,7 @@
     /* Function header */
 
     fprintf( outfile, "\n\t.align 4\n" );
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, ".stabs \"CallTo32_LargeStack:F1\",36,0,0," PREFIX "CallTo32_LargeStack\n");
 #endif
     fprintf( outfile, "\t.globl " PREFIX "CallTo32_LargeStack\n" );
@@ -1603,7 +1609,7 @@
     /* Function header */
 
     fprintf( outfile, "\n\t.align 4\n" );
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, ".stabs \"CallFrom16_%s:F1\",36,0,0," PREFIX "CallFrom16_%s\n", 
 	     profile, profile);
 #endif
@@ -1822,7 +1828,7 @@
     /* Function header */
 
     fprintf( outfile, "\n\t.align 4\n" );
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, ".stabs \"CallTo16_%s:F1\",36,0,0," PREFIX "CallTo16_%s\n", 
 	     profile, profile);
 #endif
@@ -2067,7 +2073,8 @@
 /*******************************************************************
  *         RestoreContext32
  *
- * Restore the registers from the context structure
+ * Restore the registers from the context structure.
+ * All registers except %cs and %ss are restored.
  */
 static void RestoreContext32( FILE *outfile )
 {
@@ -2076,15 +2083,23 @@
     fprintf( outfile, "\tleal %d(%%ebp),%%esp\n", -sizeof(CONTEXT)-8 );
     fprintf( outfile, "\tfrstor %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
 
-    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eip) );
-    fprintf( outfile, "\tmovl %%eax,4(%%ebp)\n" ); /* %eip at time of call */
-    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Ebp) );
-    fprintf( outfile, "\tmovl %%eax,0(%%ebp)\n" ); /* %ebp at time of call */
-
     /* Store flags over the relay addr */
     fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(EFlags) );
     fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", sizeof(CONTEXT) );
 
+    /* Get the new stack addr */
+    fprintf( outfile, "\tmovl %d(%%esp),%%ebx\n", CONTEXTOFFSET(Esp) );
+
+    /* Set eip and ebp value onto the new stack */
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eip) );
+    fprintf( outfile, "\tmovl %%eax,-4(%%ebx)\n" ); /* %eip at time of call */
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Ebp) );
+    fprintf( outfile, "\tmovl %%eax,-8(%%ebx)\n" ); /* %ebp at time of call */
+
+    /* Set ebp to point to the new stack */
+    fprintf( outfile, "\tleal -8(%%ebx),%%ebp\n" );
+
+    /* Restore all registers */
     fprintf( outfile, "\taddl $%d,%%esp\n",
              sizeof(FLOATING_SAVE_AREA) + 7 * sizeof(DWORD) );
     fprintf( outfile, "\tpopl %%eax\n" );
@@ -2153,7 +2168,7 @@
     /* Function header */
 
     fprintf( outfile, "\n\t.align 4\n" );
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, ".stabs \"CallFrom32_%s:F1\",36,0,0," PREFIX "CallFrom32_%s\n", 
 	     profile, profile);
 #endif
@@ -2182,11 +2197,17 @@
         fprintf( outfile, "\tpushl %%eax\n" );
     }
 
+    /* Set %es = %ds */
+
+    fprintf( outfile, "\tmovw %%ds,%%ax\n" );
+    fprintf( outfile, "\tmovw %%ax,%%es\n" );
+
     /* Print the debugging info */
 
     if (debugging)
     {
-        fprintf( outfile, "\tpushl $%d\n", reg_func ? -1 : args); /* Nb args */
+        fprintf( outfile, "\tpushl $%d\n",  /* Nb args */
+                 reg_func ? args | 0x80000000 : args);
         fprintf( outfile, "\tpushl %%ebp\n" );
         fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom32\n" );
         fprintf( outfile, "\tadd $8, %%esp\n" );
@@ -2194,8 +2215,6 @@
 
     /* Call the function */
 
-    fprintf( outfile, "\tpushw %%ds\n" );
-    fprintf( outfile, "\tpopw %%es\n" );  /* Set %es = %ds */
     fprintf( outfile, "\tcall -4(%%ebp)\n" );
 
     /* Print the debugging info */
@@ -2203,7 +2222,8 @@
     if (debugging)
     {
         fprintf( outfile, "\tpushl %%eax\n" );
-        fprintf( outfile, "\tpushl $%d\n", reg_func ? -1 : args); /* Nb args */
+        fprintf( outfile, "\tpushl $%d\n",  /* Nb args */
+                 reg_func ? args | 0x80000000 : args);
         fprintf( outfile, "\tpushl %%ebp\n" );
         fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom32Ret\n" );
         fprintf( outfile, "\tpopl %%eax\n" );
@@ -2244,7 +2264,7 @@
     /* Function header */
 
     fprintf( outfile, "\n\t.align 4\n" );
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, ".stabs \"CallTo32_%d:F1\",36,0,0," PREFIX "CallTo32_%d\n", 
 	     args, args);
 #endif
@@ -2316,7 +2336,7 @@
     fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
     fprintf( outfile, "\t.text\n" );
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.file\t\"%s\"\n", outname );
     getcwd(buffer, sizeof(buffer));
 
@@ -2351,7 +2371,7 @@
         }
     }
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
     fprintf( outfile, ".Letext:\n");
@@ -2376,7 +2396,7 @@
     fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
     fprintf( outfile, "\t.text\n" );
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.file\t\"%s\"\n", outname );
     getcwd(buffer, sizeof(buffer));
 
@@ -2405,7 +2425,7 @@
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_End\n" );
     fprintf( outfile, PREFIX "CALLTO16_End:\n" );
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
     fprintf( outfile, ".Letext:\n");
@@ -2430,7 +2450,7 @@
     fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
     fprintf( outfile, "\t.text\n" );
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.file\t\"%s\"\n", outname );
     getcwd(buffer, sizeof(buffer));
 
@@ -2449,7 +2469,7 @@
 
     for (i = 2; i < argc; i++) BuildCallFrom32Func( outfile, argv[i] );
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
     fprintf( outfile, ".Letext:\n");
@@ -2481,7 +2501,7 @@
      * names as an indication that we should just step through it to whatever
      * is on the other side.
      */
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.file\t\"%s\"\n", outname );
     getcwd(buffer, sizeof(buffer));
 
@@ -2500,7 +2520,7 @@
 
     for (i = 2; i < argc; i++) BuildCallTo32Func( outfile, atoi(argv[i]) );
 
-#ifdef __GNUC__
+#ifdef USE_STABS
     fprintf( outfile, "\t.text\n");
     fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
     fprintf( outfile, ".Letext:\n");
diff --git a/win32/error.c b/win32/error.c
index 44e86f7..b32eca4 100644
--- a/win32/error.c
+++ b/win32/error.c
@@ -109,3 +109,20 @@
 
     return rc;
 }
+
+int LastErrorToErrno(DWORD lasterror)
+{
+    int rc = 0; /* no error */
+    int i = 0;
+
+    while(errno_xlat_table[i].errno != -1)
+    {
+        if(errno_xlat_table[i].win32err == lasterror )
+        {
+            rc = errno_xlat_table[i].errno;
+            break;
+        }
+        i++;
+    }
+    return rc;
+}
diff --git a/win32/except.c b/win32/except.c
index 50186ee..90a28fb 100644
--- a/win32/except.c
+++ b/win32/except.c
@@ -30,35 +30,31 @@
  *   information in UnhandledExceptionFilter.
  *
  */
-#ifndef WINELIB
 
+#include <assert.h>
 #include <stdio.h>
 #include "windows.h"
 #include "winerror.h"
+#include "ldt.h"
+#include "process.h"
+#include "thread.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "except.h"
 
-LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler = NULL;
+#define TEB_EXCEPTION_FRAME(pcontext) \
+    ((PEXCEPTION_FRAME)((TEB *)GET_SEL_BASE((pcontext)->SegFs))->except)
 
-void EXC_Init(void)
-{
-    pTopExcHandler = (LPTOP_LEVEL_EXCEPTION_FILTER)GetProcAddress32(
-                                                 GetModuleHandle("KERNEL32"),
-                                                 "UnhandledExceptionFilter" );
-}
 
-/*
- *       EXC_RtlUnwind
+/*******************************************************************
+ *         RtlUnwind  (KERNEL32.443)
  *
  *  This function is undocumented. This is the general idea of 
- *  RtlUnwind, though. Note that error handling is not yet implemented
- *  
+ *  RtlUnwind, though. Note that error handling is not yet implemented.
  */
-
-void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame,LPVOID unusedEip, 
-                   PEXCEPTION_RECORD pRecord, DWORD returnEax,
-                   PCONTEXT pcontext)
+void RtlUnwind( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip, 
+                PEXCEPTION_RECORD pRecord, DWORD returnEax,
+                PCONTEXT pcontext /* Wine additional parameter */ )
 {   
    EXCEPTION_RECORD record;
    DWORD            dispatch;
@@ -69,12 +65,12 @@
    /* build an exception record, if we do not have one */
    if(!pRecord)
    {
-     record.ExceptionCode=   0xC0000026;  /* invalid disposition */ 
-     record.ExceptionFlags=  0;
-     record.ExceptionRecord= NULL;
-     record.ExceptionAddress=(LPVOID) pcontext->Eip; 
-     record.NumberParameters= 0;
-     pRecord=&record;     
+     record.ExceptionCode    = STATUS_INVALID_DISPOSITION;
+     record.ExceptionFlags   = 0;
+     record.ExceptionRecord  = NULL;
+     record.ExceptionAddress = (LPVOID)pcontext->Eip; 
+     record.NumberParameters = 0;
+     pRecord = &record;
    }
 
    if(pEndFrame)
@@ -83,39 +79,39 @@
      pRecord->ExceptionFlags|=EH_UNWINDING | EH_EXIT_UNWIND;
   
    /* get chain of exception frames */      
-   while((TebExceptionFrame!=NULL)&&
-         (TebExceptionFrame!=((void *)-1)) &&
-         (TebExceptionFrame!=pEndFrame))
+   while ((TEB_EXCEPTION_FRAME(pcontext) != NULL) &&
+          (TEB_EXCEPTION_FRAME(pcontext) != ((void *)0xffffffff)) &&
+          (TEB_EXCEPTION_FRAME(pcontext) != pEndFrame))
    {
-       dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
-                                           (int) TebExceptionFrame->Handler);
+       dprintf_win32( stddeb, "calling exception handler at 0x%x\n",
+                      (int)TEB_EXCEPTION_FRAME(pcontext)->Handler );
 
        dispatch=0;       
-       retval=TebExceptionFrame->Handler(pRecord, TebExceptionFrame,
-                                         pcontext, &dispatch);
+       retval = TEB_EXCEPTION_FRAME(pcontext)->Handler( pRecord,
+                                                TEB_EXCEPTION_FRAME(pcontext),
+                                                pcontext, &dispatch);
                                          
        dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
                               retval, (int) dispatch);
   
-       if(retval==ExceptionCollidedUnwind)
-          TebExceptionFrame=(LPVOID) dispatch;
-       else if(TebExceptionFrame!=pEndFrame)
-          TebExceptionFrame=TebExceptionFrame->Prev;
+       if (retval == ExceptionCollidedUnwind)
+           TEB_EXCEPTION_FRAME(pcontext) = (LPVOID)dispatch;
+       else if (TEB_EXCEPTION_FRAME(pcontext) != pEndFrame)
+           TEB_EXCEPTION_FRAME(pcontext) = TEB_EXCEPTION_FRAME(pcontext)->Prev;
        else
           break;  
    }
 }
 
-/*
- *    EXC_RaiseException
- *
+
+/*******************************************************************
+ *         RaiseException  (KERNEL32.418)
  */
- 
-VOID EXC_RaiseException(DWORD dwExceptionCode,
+void RaiseException(DWORD dwExceptionCode,
 		    DWORD dwExceptionFlags,
 		    DWORD cArguments,
 		    const LPDWORD lpArguments,
-		    PCONTEXT pcontext)
+		    PCONTEXT pcontext /* Wine additional parameter */ )
 {
     PEXCEPTION_FRAME    pframe; 
     EXCEPTION_RECORD    record;
@@ -131,13 +127,13 @@
     record.NumberParameters    = cArguments;
     record.ExceptionAddress    = (LPVOID) pcontext->Eip;
     
-    for(i=0;i<cArguments;i++)
-       record.ExceptionInformation[i]=lpArguments[i];
+    if (lpArguments) for( i = 0; i < cArguments; i++)
+        record.ExceptionInformation[i] = lpArguments[i];
     
     /* get chain of exception frames */    
     
-    retval=ExceptionContinueSearch;    
-    pframe=TebExceptionFrame;
+    retval = ExceptionContinueSearch;    
+    pframe = TEB_EXCEPTION_FRAME( pcontext );
     
     while((pframe!=NULL)&&(pframe!=((void *)0xFFFFFFFF)))
     {
@@ -154,62 +150,47 @@
        pframe=pframe->Prev;
    }
 
-   if(retval!=ExceptionContinueExecution)
+   if (retval!=ExceptionContinueExecution)
    {    
-      retval=EXC_CallUnhandledExceptionFilter(&record,pcontext);
-      if(retval!=EXCEPTION_CONTINUE_EXECUTION)
-      {
-         dprintf_win32(stddeb,"no handler wanted to handle "
-                              "the exception, exiting\n"     );
-         ExitProcess(dwExceptionCode); /* what status should be used here ? */         
-      }                   
-   } 
+       /* FIXME: what should we do here? */
+       dprintf_win32(stddeb,"no handler wanted to handle the exception, exiting\n");
+       ExitProcess(dwExceptionCode); /* what status should be used here ? */
+   }
 }
 
+
 /*******************************************************************
- *         UnhandledExceptionFilter (KERNEL32.537)
- * 
- *  This is the unhandled exception code. 
- *  Actually, this should show up a dialog box, with all kinds of
- *  fancy debugging information. It does nothing now!
+ *         UnhandledExceptionFilter   (KERNEL32.537)
  */
- 
 DWORD UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
 {
-   PEXCEPTION_RECORD pRecord;
-   PCONTEXT          pContext;
-   
-   pRecord=epointers->ExceptionRecord;
-   pContext=epointers->ContextRecord;
-   
-   if(pRecord->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND) )
-   {
-      dprintf_win32(stddeb,"UnhandledExceptionFilter: exiting\n");
-      ExitProcess(pRecord->ExceptionCode);            
-   }
-   else
-   {
-      RtlUnwind(0,pRecord,0,-1 );
-   }
-   
-   /* 
-    * This is just to avoid a warning, code should not get here 
-    * if it does, EXC_RaiseException will terminate it. 
-    */
-   return EXCEPTION_CONTINUE_SEARCH;
+    char message[80];
+
+    /* FIXME: Should check if the process is being debugged */
+
+    if (pCurrentProcess && pCurrentProcess->top_filter)
+    {
+        DWORD ret = pCurrentProcess->top_filter( epointers );
+        if (ret != EXCEPTION_CONTINUE_SEARCH) return ret;
+    }
+
+    /* FIXME: Should check the current error mode */
+
+    sprintf( message, "Unhandled exception 0x%08lx at address 0x%08lx.",
+             epointers->ExceptionRecord->ExceptionCode,
+             (DWORD)epointers->ExceptionRecord->ExceptionAddress );
+    MessageBox32A( 0, message, "Error", MB_OK | MB_ICONHAND );
+    return EXCEPTION_EXECUTE_HANDLER;
 }
 
+
 /*************************************************************
- *    SetUnhandledExceptionFilter    (KERNEL32.516)
- *  
- *
+ *            SetUnhandledExceptionFilter   (KERNEL32.516)
  */
-  
-LPTOP_LEVEL_EXCEPTION_FILTER 
-        SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter)
-{  
-   pTopExcHandler=efilter;
-   return efilter;
+LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
+                                          LPTOP_LEVEL_EXCEPTION_FILTER filter )
+{
+    LPTOP_LEVEL_EXCEPTION_FILTER old = pCurrentProcess->top_filter;
+    pCurrentProcess->top_filter = filter;
+    return old;
 }
-
-#endif  /* WINELIB */
diff --git a/win32/init.c b/win32/init.c
index 7509da9..18e14ef 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -7,6 +7,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <malloc.h>
 #include "windows.h"
 #include "winerror.h"
 #include "handle32.h"
@@ -85,56 +86,6 @@
 }
 
 /***********************************************************************
- *              GetStartupInfoA         (KERNEL32.284)
- * FIXME: perhaps supply better values. 
- *        add other architectures for WINELIB.
- */
-VOID
-GetSystemInfo(LPSYSTEM_INFO si) {
-    WORD cpu;
-    
-    si->u.x.wProcessorArchitecture	= PROCESSOR_ARCHITECTURE_INTEL;
-
-    si->dwPageSize			= 4096; /* 4K */
-    si->lpMinimumApplicationAddress	= (void *)0x40000000;
-    si->lpMaximumApplicationAddress	= (void *)0x80000000;
-    si->dwActiveProcessorMask		= 1;
-    si->dwNumberOfProcessors		= 1;
-#ifdef WINELIB
-    /* FIXME: perhaps check compilation defines ... */
-    si->dwProcessorType			= PROCESSOR_INTEL_386;
-    cpu = 3;
-#else
-    cpu = runtime_cpu();
-    switch (cpu) {
-    case 4: si->dwProcessorType		= PROCESSOR_INTEL_486;
-	    break;
-    case 5: si->dwProcessorType		= PROCESSOR_INTEL_PENTIUM;
-	    break;
-    case 3:
-    default: si->dwProcessorType	= PROCESSOR_INTEL_386;
-	    break;
-    }
-#endif
-    si->dwAllocationGranularity		= 8; /* hmm? */
-    si->wProcessorLevel			= cpu;
-    si->wProcessorRevision		= 0; /* FIXME, see SDK */
-}
-
-/* Initialize whatever internal data structures we need.
- *
- * Returns 1 on success, 0 on failure.
- */
-int KERN32_Init(void)
-{
-#ifndef WINELIB
-    /* Initialize exception handling */
-    EXC_Init();
-#endif
-    return 1;
-}
-
-/***********************************************************************
  *              GetComputerNameA         (KERNEL32.165)
  */
 BOOL32
diff --git a/win32/newfns.c b/win32/newfns.c
index 4bea247..1bc9a98 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -24,12 +24,6 @@
 	return TRUE;
 }
 
-DWORD
-GetWindowThreadProcessId(HWND32 hwnd,LPDWORD processid) {
-	fprintf(stdnimp,"GetWindowThreadProcessId(%04x,%p),stub\n",hwnd,processid);
-	return 0;
-}
-
 /****************************************************************************
  *		DisableThreadLibraryCalls (KERNEL32.74)
  */
diff --git a/win32/process.c b/win32/process.c
index a8534ff..e403cde 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -11,6 +11,7 @@
 #include "winerror.h"
 #include "heap.h"
 #include "handle32.h"
+#include "pe_image.h"
 #include "stddebug.h"
 #include "debug.h"
 
diff --git a/windows/caret.c b/windows/caret.c
index da49ee4..2419d96 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -172,9 +172,9 @@
     dprintf_caret(stddeb,"DestroyCaret: hwnd=%04x, timerid=%d\n",
 		Caret.hwnd, Caret.timerid);
 
-    DeleteObject32( Caret.hBrush );
     CARET_KillTimer();
     CARET_DisplayCaret(CARET_OFF);
+    DeleteObject32( Caret.hBrush );
     Caret.hwnd = 0;
     return TRUE;
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index c393eb7..d408432 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -260,7 +260,7 @@
 	else if( wParam == VK_F10 )
 	         iF10Key = 1;
 	     else
-	         if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 )
+	         if( wParam == VK_ESCAPE && (GetKeyState32(VK_SHIFT) & 0x8000))
 		     SendMessage16( wndPtr->hwndSelf, WM_SYSCOMMAND,
                                     (WPARAM16)SC_KEYMENU, (LPARAM)VK_SPACE);
 	break;
diff --git a/windows/dialog.c b/windows/dialog.c
index 5fbd4ee..7be07fe 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -5,10 +5,12 @@
  */
 
 #include <ctype.h>
+#include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
 #include "windows.h"
 #include "dialog.h"
 #include "drive.h"
@@ -904,7 +906,7 @@
             if (!(dlgCode & DLGC_WANTTAB))
             {
                 SendMessage16( hwndDlg, WM_NEXTDLGCTL,
-                             (GetKeyState(VK_SHIFT) & 0x8000), 0 );
+                             (GetKeyState32(VK_SHIFT) & 0x8000), 0 );
                 return TRUE;
             }
             break;
diff --git a/windows/hook.c b/windows/hook.c
index e7a073d..1a9b793 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -990,7 +990,7 @@
     HOOKDATA *data;
     if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
     if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
-    if (data->flags & HOOK_WIN32) return NULL;
+    if ((data->flags & HOOK_MAPTYPE) != HOOK_WIN16) return NULL;
     return (HOOKPROC16)data->proc;
 }
 
@@ -1033,7 +1033,7 @@
 
     if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
     if (!(hook = HOOK_FindValidHook(hook))) return 0;
-    return HOOK_CallHook( hook, HOOK_WIN32, code, wParam, lParam );
+    return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
 }
 
 /***********************************************************************
@@ -1048,7 +1048,7 @@
 
     if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
     if (!(hook = HOOK_FindValidHook(hook))) return 0;
-    return HOOK_CallHook( hook, HOOK_WIN32 | HOOK_UNICODE, code, wParam,
+    return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
 			  lParam );
 }
 
@@ -1173,7 +1173,7 @@
     /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
     HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
 
-    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
+    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, hTask );
     return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
 }
 
@@ -1190,8 +1190,7 @@
     /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
     HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
 
-    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE,
-				    hInst, hTask );
+    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, hTask );
     return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
 }
 
@@ -1221,7 +1220,7 @@
     else
       hTask = LOWORD(dwThreadID);
 
-    handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
+    handle = HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, hTask );
     return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
 }
 
@@ -1240,7 +1239,7 @@
     else
       hTask = LOWORD(dwThreadID);
 
-    handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE, hInst, hTask );
+    handle = HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, hTask );
     return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
 }
 
@@ -1340,7 +1339,7 @@
     oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
     fromtype = oldhook->flags & HOOK_MAPTYPE;
 
-    if (!(fromtype & HOOK_WIN32))
+    if (fromtype == HOOK_WIN16)
       fprintf(stderr, "CallNextHookEx32: called from 16bit hook!\n");
 
     return HOOK_CallHook( next, fromtype, code, wParam, lParam );
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 12c3fce..f83cc16 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -6,6 +6,7 @@
  * Copyright 1997 David Faure
  *
  */
+#define NO_TRANSITION_TYPES
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -26,6 +27,7 @@
 #include "debug.h"
 #include "xmalloc.h"
 #include "accel.h"
+#include "struct32.h"
 
 BOOL32 MouseButtonsStates[3];
 BOOL32 AsyncMouseButtonsStates[3];
@@ -54,8 +56,6 @@
     unsigned long lp2;
 } KEYLP;
 
-typedef enum {OFF,INTERM,ON} ToggleKeyState;
-
 /* Keyboard translation tables */
 static const int special_key[] =
 {
@@ -269,6 +269,50 @@
     return TRUE;
 }
 
+static BOOL32 NumState=FALSE, CapsState=FALSE;
+
+void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, XKeyEvent * event, KEYLP localkeylp )
+{
+  BOOL32 * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
+
+  if (*State) {
+    /* The INTERMEDIARY state means : just after a 'press' event, if a 'release' event comes,
+       don't treat it. It's from the same key press. Then the state goes to ON.
+       And from there, a 'release' event will switch off the toggle key. */
+    *State=FALSE;
+    dprintf_keyboard(stddeb,"INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,InputKeyStateTable[vkey]);
+  } else
+    {
+	if ( InputKeyStateTable[vkey] & 0x1 ) /* it was ON */
+	  {
+	    if (Evtype!=KeyPress)
+	      {
+		dprintf_keyboard(stddeb,"ON + KeyRelease => generating DOWN and UP messages.\n");
+		localkeylp.lp1.previous = 0; /* ? */
+		localkeylp.lp1.transition = 0;
+		hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2, event->x_root - desktopX,
+				event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+		hardware_event( WM_KEYUP, vkey, localkeylp.lp2, event->x_root - desktopX,
+				event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+		*State=FALSE;
+		InputKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */ 
+	      } 
+	  }
+	else /* it was OFF */
+	  if (Evtype==KeyPress)
+	    {
+	      dprintf_keyboard(stddeb,"OFF + Keypress => generating DOWN and UP messages.\n");
+	      hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2, event->x_root - desktopX,
+			      event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+	      localkeylp.lp1.previous = 1;
+	      localkeylp.lp1.transition = 1;
+	      hardware_event( WM_KEYUP, vkey, localkeylp.lp2, event->x_root - desktopX,
+			      event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
+	      *State=TRUE; /* Goes to intermediary state before going to ON */
+	      InputKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
+	    }
+    }
+}
 
 /***********************************************************************
  *           KEYBOARD_HandleEvent
@@ -282,11 +326,7 @@
     KeySym keysym;
     WORD vkey = 0;
     KEYLP keylp;
-    WORD message;
-    static BOOL force_extended = FALSE; /* hack for AltGr translation */
-    BOOL DontPropagate;
-    ToggleKeyState * State;
-    static ToggleKeyState NumState=OFF, CapsState=OFF;
+    static BOOL32 force_extended = FALSE; /* hack for AltGr translation */
 
     int ascii_chars = XLookupString(event, Str, 1, &keysym, &cs);
 
@@ -318,21 +358,14 @@
                 keysym, ksname, ascii_chars, Str[0] & 0xff, Str);
 	}
 
-#if 0
-    /* Ctrl-Alt-Return enters the debugger */
-    if ((keysym == XK_Return) && (event->type == KeyPress) &&
-        (event->state & ControlMask) && (event->state & Mod1Mask))
-        DEBUG_EnterDebugger();
-#endif
-
     vkey = EVENT_event_to_vkey(event);
     if (force_extended) vkey |= 0x100;
 
     dprintf_key(stddeb, "keycode 0x%x converted to vkey 0x%x\n",
 		    event->keycode, vkey);
 
-    if (vkey)
-    {
+   if (vkey)
+   {
     keylp.lp1.count = 1;
     keylp.lp1.code = LOBYTE(event->keycode) - 8;
     keylp.lp1.extended = (vkey & 0x100 ? 1 : 0);
@@ -341,75 +374,60 @@
 				/* it's '1' under windows, when a dialog box appears
 				 * and you press one of the underlined keys - DF*/
     vkey &= 0xff;
-    if (event->type == KeyPress)
-    {
-	keylp.lp1.previous = (InputKeyStateTable[vkey] & 0x80) != 0;
-        if (!(InputKeyStateTable[vkey] & 0x80))
-            InputKeyStateTable[vkey] ^= 0x01;
-	InputKeyStateTable[vkey] |= 0x80;
-	keylp.lp1.transition = 0;
-	message = (InputKeyStateTable[VK_MENU] & 0x80)
-		    && !(InputKeyStateTable[VK_CONTROL] & 0x80)
-			 ? WM_SYSKEYDOWN : WM_KEYDOWN;
-    }
-    else
-    {
-	UINT sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
-			&& !(InputKeyStateTable[VK_CONTROL] & 0x80)
-			&& (force_extended == FALSE); /* for Alt from AltGr */
 
-	InputKeyStateTable[vkey] &= ~0x80; 
-	keylp.lp1.previous = 1;
-	keylp.lp1.transition = 1;
-	message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
-    }
-    keylp.lp1.context = ( (event->state & Mod1Mask)  || 
-			  (InputKeyStateTable[VK_MENU] & 0x80)) ? 1 : 0;
-    DontPropagate = FALSE;
-    if ((vkey==VK_NUMLOCK) || (vkey==VK_CAPITAL))
+    switch(vkey)
+    {
+    case VK_NUMLOCK:    
+      KEYBOARD_GenerateMsg(VK_NUMLOCK,event->type,event,keylp); break;
+    case VK_CAPITAL:
+      dprintf_keyboard(stddeb,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,InputKeyStateTable[vkey]);
+      KEYBOARD_GenerateMsg(VK_CAPITAL,event->type,event,keylp); 
+      dprintf_keyboard(stddeb,"State after : %#.2x\n",InputKeyStateTable[vkey]);
+      break;
+    default:
       {
-	
-	switch (*( State = (vkey==VK_NUMLOCK? &NumState : &CapsState))) {
-	case OFF:if (event->type==KeyPress)
+	WORD message;
+	if (event->type == KeyPress)
 	  {
-	    dprintf_keyboard(stddeb,"OFF + Keypress => DOWN and UP generated. \n");
-	    hardware_event( message, vkey, keylp.lp2, event->x_root - desktopX,
-			    event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
-	    message += WM_KEYUP - WM_KEYDOWN; /* create a *UP message from the *DOWN one */
+	    keylp.lp1.previous = (InputKeyStateTable[vkey] & 0x80) != 0;
+	    if (!(InputKeyStateTable[vkey] & 0x80))
+	      InputKeyStateTable[vkey] ^= 0x01;
+	    InputKeyStateTable[vkey] |= 0x80;
+	    keylp.lp1.transition = 0;
+	    message = (InputKeyStateTable[VK_MENU] & 0x80)
+	      && !(InputKeyStateTable[VK_CONTROL] & 0x80)
+	      ? WM_SYSKEYDOWN : WM_KEYDOWN;
+	  }
+	else
+	  {
+            BOOL32 sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
+                && !(InputKeyStateTable[VK_CONTROL] & 0x80)
+                && (force_extended == FALSE); /* for Alt from AltGr */
+	    
+	    InputKeyStateTable[vkey] &= ~0x80; 
 	    keylp.lp1.previous = 1;
 	    keylp.lp1.transition = 1;
-	    *State = INTERM;
-	  } break;
-	case INTERM:
-	  /* The 'INTERM' state means : just after a 'press' event, if a 'release' event comes,
-	     don't "propagate" it. It's from the same key press. Then the state goes to ON.
-	     And from there, a 'release' event will switch off the toggle key. */
-	  DontPropagate = TRUE;
-	  *State=ON;
-	  InputKeyStateTable[vkey] |= 0x01; /* force to 'on' event if a release event was received */
-	  dprintf_keyboard(stddeb,"INTERM : don\'t propagate press/release of toggle key. InputKeyStateTable[%#x] = %#x",vkey,InputKeyStateTable[vkey]);
-	  break;
-	case ON: if (event->type==KeyPress) DontPropagate = TRUE; else
+	    message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
+	  }
+	keylp.lp1.context = ( (event->state & Mod1Mask)  || 
+			      (InputKeyStateTable[VK_MENU] & 0x80)) ? 1 : 0;
+	if (!(InputKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
+	  { 
+	    dprintf_keyboard(stddeb,"Adjusting NumLock state. \n");
+	    KEYBOARD_GenerateMsg(VK_NUMLOCK,KeyPress,event,keylp);
+	    KEYBOARD_GenerateMsg(VK_NUMLOCK,KeyRelease,event,keylp);
+	  }
+	if (!(InputKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
 	  {
-	    KEYLP downkeylp = keylp;
-	    dprintf_keyboard(stddeb,"ON + KeyRelease => generating DOWN msg before the UP\n");
-	    message += WM_KEYDOWN - WM_KEYUP; /* create the *DOWN from the *UP */
-	    downkeylp.lp1.previous = 0; /* ? */
-	    downkeylp.lp1.transition = 0;
-	    hardware_event( message, vkey, downkeylp.lp2, event->x_root - desktopX,
-			    event->y_root - desktopY, event->time - MSG_WineStartTicks, 0);
-	    message += WM_KEYUP - WM_KEYDOWN; /* back to the UP message */
-            *State=OFF;
-	  } break;
-	}
-	dprintf_keyboard(stddeb,"Internal State : %d (0=OFF 1=INTERM 2=ON). InputTable state : %#x \n",*State,InputKeyStateTable[vkey]);
-      } else {
-	if (NumState == INTERM) NumState = ON;
-	if (CapsState == INTERM) CapsState = ON;
-      }
-    
-    if (!DontPropagate)
-      {
+	    dprintf_keyboard(stddeb,"Adjusting Caps Lock state. State before %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
+	    KEYBOARD_GenerateMsg(VK_CAPITAL,KeyPress,event,keylp);
+	    KEYBOARD_GenerateMsg(VK_CAPITAL,KeyRelease,event,keylp);
+	    dprintf_keyboard(stddeb,"State after %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
+	  }
+	/* End of intermediary states. */
+	NumState = FALSE;
+	CapsState = FALSE;
+
 	dprintf_key(stddeb,"            wParam=%04X, lParam=%08lX\n", 
 		    vkey, keylp.lp2 );
 	dprintf_key(stddeb,"            InputKeyState=%X\n",
@@ -419,18 +437,27 @@
 			event->y_root - desktopY, event->time - MSG_WineStartTicks, 0 );
       }
     }
+   }
 }
 
 
 /**********************************************************************
  *		GetKeyState			[USER.106]
+ */
+WORD GetKeyState16(INT16 vkey)
+{
+    return GetKeyState32(vkey);
+}
+
+/**********************************************************************
+ *		GetKeyState			[USER32.248]
  * An application calls the GetKeyState function in response to a
  * keyboard-input message.  This function retrieves the state of the key
  * at the time the input message was generated.  (SDK 3.1 Vol 2. p 390)
  */
-INT GetKeyState(INT vkey)
+WORD GetKeyState32(INT32 vkey)
 {
-    INT retval;
+    INT32 retval;
 
     switch (vkey)
 	{
@@ -446,20 +473,20 @@
 	default :
 	    if (vkey >= 'a' && vkey <= 'z')
 		vkey += 'A' - 'a';
-	    retval = ( (INT)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
-		       (INT)(QueueKeyStateTable[vkey] & 0x01);
+	    retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
+		       (WORD)(QueueKeyStateTable[vkey] & 0x01);
 	}
     dprintf_key(stddeb, "GetKeyState(0x%x) -> %x\n", vkey, retval);
     return retval;
 }
 
 /**********************************************************************
- *		GetKeyboardState			[USER.222]
+ *		GetKeyboardState	[USER.222][USER32.253]
  * An application calls the GetKeyboardState function in response to a
  * keyboard-input message.  This function retrieves the state of the keyboard
  * at the time the input message was generated.  (SDK 3.1 Vol 2. p 387)
  */
-void GetKeyboardState(BYTE *lpKeyState)
+VOID GetKeyboardState(LPBYTE lpKeyState)
 {
     dprintf_key(stddeb, "GetKeyboardState()\n");
     if (lpKeyState != NULL) {
@@ -471,9 +498,9 @@
 }
 
 /**********************************************************************
- *      SetKeyboardState            [USER.223]
+ *      SetKeyboardState            [USER.223][USER32.483]
  */
-void SetKeyboardState(BYTE *lpKeyState)
+VOID SetKeyboardState(LPBYTE lpKeyState)
 {
     dprintf_key(stddeb, "SetKeyboardState()\n");
     if (lpKeyState != NULL) {
@@ -485,7 +512,7 @@
 }
 
 /**********************************************************************
- *            GetAsyncKeyState        (USER.249)
+ *            GetAsyncKeyState        (USER32.206)
  *
  *	Determine if a key is or was pressed.  retval has high-order 
  * bit set to 1 if currently pressed, low-order bit set to 1 if key has
@@ -497,7 +524,7 @@
  * mouse or key had been depressed since the last call to 
  * GetAsyncKeyState.
  */
-int GetAsyncKeyState(int nKey)
+WORD GetAsyncKeyState32(INT32 nKey)
 {
     short retval;	
 
@@ -527,17 +554,34 @@
     return retval;
 }
 
+/**********************************************************************
+ *            GetAsyncKeyState        (USER.249)
+ */
+WORD GetAsyncKeyState16(INT16 nKey)
+{
+    return GetAsyncKeyState32(nKey);
+}
+
+
 
 /**********************************************************************
  *			TranslateAccelerator 	[USER.178]
  *
  * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
  */
-INT16 TranslateAccelerator(HWND hWnd, HACCEL16 hAccel, LPMSG16 msg)
+INT32 TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
+{
+    MSG16	msg16;
+
+    STRUCT32_MSG32to16(msg,&msg16);
+    return TranslateAccelerator16(hWnd,hAccel,&msg16);
+}
+	
+INT16 TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
 {
     ACCELHEADER	*lpAccelTbl;
     int 	i;
-    BOOL sendmsg;
+    BOOL32 sendmsg;
     
     if (hAccel == 0 || msg == NULL) return 0;
     if (msg->message != WM_KEYDOWN &&
@@ -567,12 +611,12 @@
       {
        if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) 
        {
-	INT mask = 0;
+	INT32 mask = 0;
         dprintf_accel(stddeb,"found accel for virt_key %04x (scan %04x)",
   	                       msg->wParam,0xff & HIWORD(msg->lParam));                
-	if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
-	if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
-	if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
+	if(GetKeyState32(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
+	if(GetKeyState32(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
+	if(GetKeyState32(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
 	if(mask == (lpAccelTbl->tbl[i].type &
 			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL)))
           sendmsg=TRUE;			    
@@ -672,6 +716,9 @@
 }
 
 
+/******************************************************************************
+ *    	OemKeyScan			[KEYBOARD.128][USER32.400]
+ */
 DWORD OemKeyScan(WORD wOemChar)
 {
     dprintf_keyboard(stddeb,"*OemKeyScan (%d)\n",wOemChar);
@@ -679,6 +726,9 @@
     return wOemChar;
 }
 
+/******************************************************************************
+ *    	VkKeyScanA			[USER32.572]
+ */
 /* VkKeyScan translates an ANSI character to a virtual-key and shift code
  * for the current keyboard.
  * FIXME high-order byte should yield :
@@ -691,7 +741,7 @@
  *	I.e. :	Shift = 1, Ctrl = 2, Alt = 4.
  */
 
-WORD VkKeyScan(WORD cChar)
+WORD VkKeyScan32A(CHAR cChar)
 {
 	KeyCode keycode;
     	dprintf_keyboard(stddeb,"VkKeyScan '%c'(%d) ",cChar,cChar);
@@ -706,13 +756,34 @@
 	return keyc2vkey[keycode];
 }
 
-WORD VkKeyScan32W(WORD cChar)
+/******************************************************************************
+ *    	VkKeyScan			[KEYBOARD.129]
+ */
+WORD VkKeyScan16(CHAR cChar)
 {
-	/* lower part of cChar is used anyway */
-	return VkKeyScan(cChar);
+	return VkKeyScan32A(cChar);
 }
 
-int GetKeyboardType(int nTypeFlag)
+/******************************************************************************
+ *    	VkKeyScanW			[USER32.575]
+ */
+WORD VkKeyScan32W(WCHAR cChar)
+{
+	return VkKeyScan32A((CHAR)cChar); /* FIXME: check unicode */
+}
+
+/******************************************************************************
+ *    	GetKeyboardType			[KEYBOARD.130]
+ */
+INT16 GetKeyboardType16(INT16 nTypeFlag)
+{
+  return GetKeyboardType32(nTypeFlag);
+}
+
+/******************************************************************************
+ *    	GetKeyboardType			[USER32.254]
+ */
+INT32 GetKeyboardType32(INT32 nTypeFlag)
 {
   dprintf_keyboard(stddeb,"GetKeyboardType(%d)\n",nTypeFlag);
   switch(nTypeFlag)
@@ -732,9 +803,26 @@
     }
 }
 
-/* MapVirtualKey translates keycodes from one format to another. */
 
-WORD MapVirtualKey(WORD wCode, WORD wMapType)
+/******************************************************************************
+ *    	MapVirtualKeyA			[USER32.382]
+ */
+UINT32 MapVirtualKey32A(UINT32 code, UINT32 maptype) {
+	return MapVirtualKey16(code,maptype);
+}
+
+/******************************************************************************
+ *    	MapVirtualKeyA			[USER32.384]
+ */
+UINT32 MapVirtualKey32W(UINT32 code, UINT32 maptype) {
+	return MapVirtualKey16(code,maptype);
+}
+
+/******************************************************************************
+ *    	MapVirtualKeyA			[KEYBOARD.131]
+ * MapVirtualKey translates keycodes from one format to another
+ */
+UINT16 MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
 {
 #define returnMVK(value) { dprintf_keyboard(stddeb,"returning 0x%x.\n",value); return value; }
 
@@ -762,7 +850,7 @@
 			char s[2];
 			e.display = display;
 			e.state = 0; /* unshifted */
-			e.keycode = MapVirtualKey( wCode, 0);
+			e.keycode = MapVirtualKey16( wCode, 0);
 			if (!XLookupString(&e, s , 2 , &keysym, NULL))
 			  returnMVK (*s);
 			
@@ -776,7 +864,10 @@
 	return 0;
 }
 
-int GetKbCodePage(void)
+/****************************************************************************
+ *	GetKbCodePage   (KEYBOARD.132)
+ */
+INT16 GetKbCodePage(VOID)
 {
     	dprintf_keyboard(stddeb,"GetKbCodePage()\n");
 	return 850;
@@ -827,13 +918,27 @@
 	return 0;
 }
 
-int ToAscii(WORD wVirtKey, WORD wScanCode, LPSTR lpKeyState, 
-	LPVOID lpChar, WORD wFlags) 
+
+/****************************************************************************
+ *	ToAscii   (KEYBOARD.4)
+ */
+INT16 ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, 
+	LPVOID lpChar, UINT16 flags) 
 {
+    return ToAscii32(virtKey,scanCode,lpKeyState,lpChar,flags);
+}
+
+/****************************************************************************
+ *	ToAscii   (USER32.545)
+ */
+INT32 ToAscii32(
+	UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
+	LPWORD lpChar,UINT32 flags
+) {
     XKeyEvent e;
     KeySym keysym;
     static XComposeStatus cs;
-    int ret;
+    INT32 ret;
     WORD keyc;
 
     e.display = display;
@@ -841,26 +946,26 @@
     for (keyc=min_keycode; keyc<=max_keycode; keyc++)
       { /* this could be speeded up by making another table, an array of struct vkey,keycode
 	 * (vkey -> keycode) with vkeys sorted .... but it takes memory (512*3 bytes)!  DF */
-	if ((keyc2vkey[keyc] & 0xFF)== wVirtKey) /* no need to make a more precise test (with the extended bit correctly set above wVirtKey ... VK* are different enough... */
+	if ((keyc2vkey[keyc] & 0xFF)== virtKey) /* no need to make a more precise test (with the extended bit correctly set above virtKey ... VK* are different enough... */
 	  {
-	    if ((e.keycode) && ((wVirtKey<0x10) || (wVirtKey>0x12))) 
+	    if ((e.keycode) && ((virtKey<0x10) || (virtKey>0x12))) 
 		/* it's normal to have 2 shift, control, and alt ! */
 		dprintf_keyboard(stddeb,"ToAscii : The keycodes %X and %X are matching the same vkey %X\n",
-				 e.keycode,keyc,wVirtKey);
+				 e.keycode,keyc,virtKey);
 	    e.keycode = keyc;
 	  }
       }
     if ((!e.keycode) && (lpKeyState[VK_NUMLOCK] & 0x01)) 
       {
-	if ((wVirtKey>=VK_NUMPAD0) && (wVirtKey<=VK_NUMPAD9))
-	  e.keycode = XKeysymToKeycode(e.display, wVirtKey-VK_NUMPAD0+XK_KP_0);
-	if (wVirtKey==VK_DECIMAL)
+	if ((virtKey>=VK_NUMPAD0) && (virtKey<=VK_NUMPAD9))
+	  e.keycode = XKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
+	if (virtKey==VK_DECIMAL)
 	  e.keycode = XKeysymToKeycode(e.display, XK_KP_Decimal);
       }
     if (!e.keycode)
       {
-	fprintf(stderr,"ToAscii : Unknown virtual key %X !!! \n",wVirtKey);
-	return wVirtKey; /* whatever */
+	fprintf(stderr,"ToAscii : Unknown virtual key %X !!! \n",virtKey);
+	return virtKey; /* whatever */
       }
     e.state = 0;
     if (lpKeyState[VK_SHIFT] & 0x80)
@@ -876,8 +981,8 @@
     if (lpKeyState[VK_NUMLOCK] & 0x01)
 	e.state |= NumLockMask;
     dprintf_key(stddeb, "ToAscii(%04X, %04X) : faked state = %X\n",
-		wVirtKey, wScanCode, e.state);
-    ret = XLookupString(&e, lpChar, 2, &keysym, &cs);
+		virtKey, scanCode, e.state);
+    ret = XLookupString(&e, (LPVOID)lpChar, 2, &keysym, &cs);
     if (ret == 0)
 	{
 	BYTE dead_char = 0;
@@ -922,8 +1027,8 @@
 		{
 		fprintf(stderr, "Please report : no char for keysym %04lX (%s) :\n",
 			keysym, ksname);
-		fprintf(stderr, "  wVirtKey = %X, wScanCode = %X, keycode = %X, state = %X\n",
-			wVirtKey, wScanCode, e.keycode, e.state);
+		fprintf(stderr, "  virtKey = %X, scanCode = %X, keycode = %X, state = %X\n",
+			virtKey, scanCode, e.keycode, e.state);
 		}
 	    }
 	}
diff --git a/windows/mdi.c b/windows/mdi.c
index 558f9ce..317c8ae 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -1573,12 +1573,12 @@
   
   if( wnd->dwStyle & WS_DISABLED ) return 0;
    
-  if ((GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
+  if ((GetKeyState32(VK_CONTROL) & 0x8000) && !(GetKeyState32(VK_MENU) & 0x8000))
     switch( msg->wParam )
       {
 	case VK_F6:
 	case VK_SEPARATOR:
-	     wParam = ( GetKeyState(VK_SHIFT) & 0x8000 )? SC_NEXTWINDOW: SC_PREVWINDOW;
+	     wParam = ( GetKeyState32(VK_SHIFT) & 0x8000 )? SC_NEXTWINDOW: SC_PREVWINDOW;
 	     break;
 	case VK_RBUTTON:
 	     wParam = SC_CLOSE; 
diff --git a/windows/message.c b/windows/message.c
index 7358f4b..4ceb269 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -1223,8 +1223,8 @@
 		msg->wParam, HIWORD(msg->lParam) );
 
 	/* FIXME : should handle ToAscii yielding 2 */
-	switch (ToAscii(msg->wParam, HIWORD(msg->lParam),
-		(LPSTR)&QueueKeyStateTable, wparam, 0)) 
+	switch (ToAscii32(msg->wParam, HIWORD(msg->lParam),
+		QueueKeyStateTable,(LPWORD)wparam, 0)) 
 	    {
 	    case 1 :
 		message = message == WM_KEYDOWN ? WM_CHAR : WM_SYSCHAR;
diff --git a/windows/msgbox.c b/windows/msgbox.c
index f5a5d26..1ad540d 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -197,6 +197,9 @@
 INT32 MessageBox32A( HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type )
 {
     MSGBOX mbox;
+
+    if (!text) text="<WINE-NULL>";
+    if (!title) title="<WINE-NULL>";
     mbox.title = title;
     mbox.text  = text;
     mbox.type  = type;
@@ -221,6 +224,26 @@
 
 
 /**************************************************************************
+ *           MessageBoxEx32A   (USER32.391)
+ */
+INT32
+MessageBoxEx32A(HWND32 hWnd,LPCSTR text,LPCSTR title,UINT32 type,WORD langid) {
+    /* ignore language id for now */
+    return MessageBox32A(hWnd,text,title,type);
+}
+
+/**************************************************************************
+ *           MessageBoxEx32W   (USER32.392)
+ */
+INT32
+MessageBoxEx32W(HWND32 hWnd,LPCWSTR text,LPCWSTR title,UINT32 type,WORD langid)
+{
+    /* ignore language id for now */
+    return MessageBox32W(hWnd,text,title,type);
+}
+
+
+/**************************************************************************
  *           FatalAppExit16   (KERNEL.137)
  */
 void FatalAppExit16( UINT16 action, LPCSTR str )
@@ -247,3 +270,5 @@
     MessageBox32W( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
     TASK_KillCurrentTask(0);
 }
+
+
diff --git a/windows/queue.c b/windows/queue.c
index 83a8c7d..709fa02 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -11,6 +11,8 @@
 #include "task.h"
 #include "win.h"
 #include "hook.h"
+#include "thread.h"
+#include "process.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -668,6 +670,29 @@
     return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
 }
 
+/***********************************************************************
+ *           GetWindowThreadProcessId   (USER32.312)
+ */
+DWORD
+GetWindowThreadProcessId(HWND32 hwnd,LPDWORD process) {
+    HTASK16 htask;
+    TDB	*tdb;
+
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+    if (!wndPtr) return 0;
+    htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
+    tdb = (TDB*)GlobalLock16(htask);
+    if (!tdb) return 0;
+    if (tdb->thdb) {
+    	if (process)
+		*process = (DWORD)tdb->thdb->process;
+	return (DWORD)tdb->thdb;
+    }
+    return 0;
+
+}
+
 
 /***********************************************************************
  *           SetMessageQueue   (USER.266)
diff --git a/windows/win.c b/windows/win.c
index 31ceffd..5d96ee1 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -309,7 +309,7 @@
 static void WIN_DestroyWindow( WND* wndPtr )
 {
     HWND hwnd = wndPtr->hwndSelf;
-    WND* pWnd,*pNext;
+    WND *pWnd;
 
     dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
 
@@ -320,10 +320,10 @@
 	
     /* free child windows */
 
-    pNext = wndPtr->child;
-    while( (pWnd = pNext) )
+    while ((pWnd = wndPtr->child))
     {
-        pNext = pWnd->next;
+        /* Make sure the linked list remains coherent */
+        wndPtr->child = pWnd->next;
         WIN_DestroyWindow( pWnd );
     }