Release 961222

Sun Dec 22 13:30:18 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [graphics/metafiledrv/init.c] [graphisc/metafiledrv/mapping.c]
	Added mapping functions.

	* [if1632/gdi.spec] [objects/*.c] [include/windows.h]
	Added a lot of Win32 functions.

	* [memory/heap.c]
	Added HEAP_strdupAtoW and HEAP_strdupWtoA.

	* [misc/lstr.c] [memory/string.c]
	Moved OEM<->Ansi conversion to string.c. Fixed a couple of bugs.

	* [object/font.c]
	Avoid uppercasing font names.

	* [windows/hook.c]
	Set ds = ss before calling hook procedure.

Sat Dec 21 21:44:17 1996  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [objects/color.c]
	Use colors allocated by other clients. 

	* [windows/caret.c]
	Set default blink time to 500.

	* [windows/win.c] [windows/event.c]
	Delete X context before XDestroyWindow().

	* [windows/keyboard.c]
	Fixed GetKeyState() once more.

Fri Dec 20 08:26:33 1996  Eric Youngdale <eric@sub2304.jic.com>

	* [debugger/*.c]
	Lots of built-in debugger improvements: parse Win32 EXEs debug
 	information, display local variables, source files and line
 	numbers, get symbols directly from the Wine executable, etc.

Tue Dec 17 22:39:42 1996  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [misc/winsock_async.c]
 	Extern declaration added for h_errno.

Tue Dec 17 21:29:34 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/message.c]
	Added two more CBT hook calls: HCBT_CLICKSKIPPED/HCBT_KEYSKIPPED.
diff --git a/ANNOUNCE b/ANNOUNCE
index 835a25a..ba07f17 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,12 +1,13 @@
-This is release 961215 of Wine, the MS Windows emulator.  This is still a
+This is release 961222 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-961215: (see ChangeLog for details)
-	- Tons of new Win32 stuff.
+WHAT'S NEW with Wine-961222: (see ChangeLog for details)
+	- Lots of improvements to the built-in debugger
+	- Yet more Win32 stuff.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -15,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-961215.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961215.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961215.tar.gz
-  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961215.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-961222.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961222.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961222.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961222.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 0379d01..b4e8b84 100644
--- a/BUGS
+++ b/BUGS
@@ -5,7 +5,7 @@
 add new entries and, more importantly, remove those for the 
 bugs you fixed ;-)
 ------------------------------------------------------------
-As of Dec 15 1996 -
+As of Dec 22 1996 -
 
 General:
 
@@ -41,7 +41,6 @@
  * AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple
    times.
  * ScrollWindowEx() is outdated.
- * HCBT_CLICKSKIPPED/HCBT_KEYSKIPPED hook actions are not implemented.
 
 Where to look in source files:
 
diff --git a/ChangeLog b/ChangeLog
index f94bb28..517be68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,56 @@
 ----------------------------------------------------------------------
+Sun Dec 22 13:30:18 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [graphics/metafiledrv/init.c] [graphisc/metafiledrv/mapping.c]
+	Added mapping functions.
+
+	* [if1632/gdi.spec] [objects/*.c] [include/windows.h]
+	Added a lot of Win32 functions.
+
+	* [memory/heap.c]
+	Added HEAP_strdupAtoW and HEAP_strdupWtoA.
+
+	* [misc/lstr.c] [memory/string.c]
+	Moved OEM<->Ansi conversion to string.c. Fixed a couple of bugs.
+
+	* [object/font.c]
+	Avoid uppercasing font names.
+
+	* [windows/hook.c]
+	Set ds = ss before calling hook procedure.
+
+Sat Dec 21 21:44:17 1996  Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [objects/color.c]
+	Use colors allocated by other clients. 
+
+	* [windows/caret.c]
+	Set default blink time to 500.
+
+	* [windows/win.c] [windows/event.c]
+	Delete X context before XDestroyWindow().
+
+	* [windows/keyboard.c]
+	Fixed GetKeyState() once more.
+
+Fri Dec 20 08:26:33 1996  Eric Youngdale <eric@sub2304.jic.com>
+
+	* [debugger/*.c]
+	Lots of built-in debugger improvements: parse Win32 EXEs debug
+ 	information, display local variables, source files and line
+ 	numbers, get symbols directly from the Wine executable, etc.
+
+Tue Dec 17 22:39:42 1996  Philippe De Muyter  <phdm@info.ucl.ac.be>
+
+	* [misc/winsock_async.c]
+ 	Extern declaration added for h_errno.
+
+Tue Dec 17 21:29:34 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [windows/message.c]
+	Added two more CBT hook calls: HCBT_CLICKSKIPPED/HCBT_KEYSKIPPED.
+
+----------------------------------------------------------------------
 Sun Dec 15 16:18:15 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [graphics/x11drv/bitblt.c]
diff --git a/controls/button.c b/controls/button.c
index e53b4c0..b9bbe05 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -264,7 +264,7 @@
     BUTTON_SEND_CTLCOLOR( wndPtr, hDC );
     hOldPen = (HPEN32)SelectObject32(hDC, sysColorObjects.hpenWindowFrame);
     hOldBrush = (HBRUSH32)SelectObject32(hDC, sysColorObjects.hbrushBtnFace);
-    SetBkMode(hDC, TRANSPARENT);
+    SetBkMode32(hDC, TRANSPARENT);
     Rectangle32(hDC, rc.left, rc.top, rc.right, rc.bottom);
     if (action == ODA_DRAWENTIRE)
     {
@@ -339,7 +339,7 @@
 {
     static int Pattern[] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};
     HBITMAP16 hbm  = CreateBitmap(8, 8, 1, 1, Pattern);
-    HDC32 hdcMem = CreateCompatibleDC(hDC);
+    HDC32 hdcMem = CreateCompatibleDC32(hDC);
     HBITMAP16 hbmMem;
     HBRUSH16 hBr;
     RECT32 rect,rc2;
@@ -359,7 +359,7 @@
     PatBlt32( hdcMem,0,0,rect.right,rect.bottom,0xFA0089);
     DeleteObject32( SelectObject32( hdcMem,hBr) );
     BitBlt32(hDC,rect.left,rect.top,rect.right,rect.bottom,hdcMem,0,0,0x990000);
-    DeleteDC( hdcMem);
+    DeleteDC32( hdcMem);
     DeleteObject32( hbmMem );
 }
 
diff --git a/controls/desktop.c b/controls/desktop.c
index b7458b9..8fcde45 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -61,9 +61,9 @@
 	HeapFree( SystemHeap, 0, buffer );
 	return 0;
     }
-    hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
-			      buffer + fileHeader->bfOffBits,
-			      bitmapInfo, DIB_RGB_COLORS );
+    hbitmap = CreateDIBitmap32( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
+                                buffer + fileHeader->bfOffBits,
+                                bitmapInfo, DIB_RGB_COLORS );
     HeapFree( SystemHeap, 0, buffer );
     return hbitmap;
 }
diff --git a/controls/edit.c b/controls/edit.c
index 54aecd4..3cb1372 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -1313,8 +1313,8 @@
 
 	if (!count)
 		return 0;
-	BkColor = GetBkColor(hdc);
-	TextColor = GetTextColor(hdc);
+	BkColor = GetBkColor32(hdc);
+	TextColor = GetTextColor32(hdc);
 	if (rev) {
 		SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
 		SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
diff --git a/controls/menu.c b/controls/menu.c
index fd5bb8a..8e8583d 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -28,7 +28,6 @@
 #include "message.h"
 #include "graphics.h"
 #include "resource.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -585,7 +584,7 @@
     if (lpitem->item_flags & MF_HILITE)
 	FillRect16( hdc, &rect, sysColorObjects.hbrushHighlight );
     else FillRect16( hdc, &rect, sysColorObjects.hbrushMenu );
-    SetBkMode( hdc, TRANSPARENT );
+    SetBkMode32( hdc, TRANSPARENT );
 
       /* Draw the separator bar (if any) */
 
@@ -2250,9 +2249,9 @@
 
     if (IS_STRING_ITEM(flags) && str)
     {
-        LPSTR newstr = STRING32_DupUniToAnsi( str );
+        LPSTR newstr = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
         ret = InsertMenu32A( hMenu, pos, flags, id, newstr );
-        free( newstr );
+        HeapFree( GetProcessHeap(), 0, newstr );
         return ret;
     }
     else return InsertMenu32A( hMenu, pos, flags, id, (LPCSTR)str );
@@ -2386,9 +2385,9 @@
 
     if (IS_STRING_ITEM(flags) && str)
     {
-        LPSTR newstr = STRING32_DupUniToAnsi( str );
+        LPSTR newstr = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
         ret = ModifyMenu32A( hMenu, pos, flags, id, newstr );
-        free( newstr );
+        HeapFree( GetProcessHeap(), 0, newstr );
         return ret;
     }
     else return ModifyMenu32A( hMenu, pos, flags, id, (LPCSTR)str );
diff --git a/controls/oldlbox.c b/controls/oldlbox.c
index d7a7547..c1577ce 100644
--- a/controls/oldlbox.c
+++ b/controls/oldlbox.c
@@ -200,7 +200,7 @@
       int 	OldBkMode;
       DWORD 	dwOldTextColor = 0;
 
-      OldBkMode = SetBkMode(hdc, TRANSPARENT);
+      OldBkMode = SetBkMode32(hdc, TRANSPARENT);
 
       if (itemState != 0) {
 	dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
@@ -220,7 +220,7 @@
 	SetTextColor(hdc, dwOldTextColor);
       }
       
-      SetBkMode(hdc, OldBkMode);
+      SetBkMode32(hdc, OldBkMode);
     }
     else DrawFocusRect16(hdc, rect);
 }
diff --git a/controls/scroll.c b/controls/scroll.c
index 0ffa3b4..ea04e38 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -311,11 +311,11 @@
                                RECT32 *rect, INT32 arrowSize, BOOL32 vertical,
                                BOOL32 top_pressed, BOOL32 bottom_pressed )
 {
-    HDC32 hdcMem = CreateCompatibleDC( hdc );
+    HDC32 hdcMem = CreateCompatibleDC32( hdc );
     HBITMAP32 hbmpPrev = SelectObject32( hdcMem, vertical ?
                                     TOP_ARROW(infoPtr->flags, top_pressed)
                                     : LEFT_ARROW(infoPtr->flags, top_pressed));
-    SetStretchBltMode( hdc, STRETCH_DELETESCANS );
+    SetStretchBltMode32( hdc, STRETCH_DELETESCANS );
     StretchBlt32( hdc, rect->left, rect->top,
                   vertical ? rect->right-rect->left : arrowSize+1,
                   vertical ? arrowSize+1 : rect->bottom-rect->top,
@@ -339,7 +339,7 @@
                       SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
                       SRCCOPY );
     SelectObject32( hdcMem, hbmpPrev );
-    DeleteDC( hdcMem );
+    DeleteDC32( hdcMem );
 }
 
 
diff --git a/controls/status.c b/controls/status.c
index 971651a..ccb188b 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -70,14 +70,14 @@
     /* now draw text */
     if ((style != SBT_OWNERDRAW) && text) {
 	SelectObject32(hdc, sysColorObjects.hpenWindowText);
-	oldbkmode = SetBkMode(hdc, TRANSPARENT);
+	oldbkmode = SetBkMode32(hdc, TRANSPARENT);
 	rt = r;
 	rt.left += 3;
 	DrawText32A(hdc, text, lstrlen32A(text),
 		    &rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
 
 	if (oldbkmode != TRANSPARENT)
-	    SetBkMode(hdc, oldbkmode);
+	    SetBkMode32(hdc, oldbkmode);
     }
 }
 
diff --git a/debugger/Makefile.in b/debugger/Makefile.in
index a01ca75..6a3634c 100644
--- a/debugger/Makefile.in
+++ b/debugger/Makefile.in
@@ -12,7 +12,9 @@
 	hash.c \
 	info.c \
 	memory.c \
+	msc.c	\
 	registers.c \
+	stabs.c	\
 	stack.c
 
 GEN_C_SRCS = \
diff --git a/debugger/break.c b/debugger/break.c
index 7375a75..8c727b4 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -205,7 +205,8 @@
     breakpoints[num].enabled = TRUE;
     breakpoints[num].in_use  = TRUE;
     fprintf( stderr, "Breakpoint %d at ", num );
-    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen );
+    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
+			TRUE );
     fprintf( stderr, "\n" );
 }
 
@@ -258,7 +259,8 @@
         if (breakpoints[i].in_use)
         {
             fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
-            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen );
+            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen,
+				TRUE);
             fprintf( stderr, "\n" );
         }
     }
@@ -290,7 +292,7 @@
     {
         fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
         DEBUG_PrintAddress( &breakpoints[bpnum].addr,
-                            breakpoints[bpnum].addrlen );
+                            breakpoints[bpnum].addrlen, TRUE );
         fprintf( stderr, "\n" );
         return FALSE;
     }
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index ea068b7..cb230c6 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -1010,7 +1010,7 @@
     case LONG:
         {
             DBG_ADDR address = { 0, addr };
-            DEBUG_PrintAddress( &address, db_disasm_16 ? 16 : 32 );
+            DEBUG_PrintAddress( &address, db_disasm_16 ? 16 : 32, TRUE );
         }
         break;
     }
@@ -1457,7 +1457,8 @@
                                        short_addr ? 2 : 4, FALSE );
                         get_value_inc( address.seg, addr,  /* segment */
                                        2, FALSE );
-                        DEBUG_PrintAddress( &address, short_addr ? 16 : 32 );
+                        DEBUG_PrintAddress( &address, short_addr ? 16 : 32, 
+					    TRUE );
                     }
 		    break;
 	    }
diff --git a/debugger/dbg.y b/debugger/dbg.y
index fa505b7..a7ab4f7 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -18,6 +18,7 @@
 
 extern FILE * yyin;
 unsigned int dbg_mode = 0;
+int curr_frame = 0;
 
 static enum exec_mode dbg_exec_mode = EXEC_CONT;
 
@@ -37,11 +38,13 @@
     int              integer;
 }
 
-%token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK
+%token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
 %token tENABLE tDISABLE tBREAK tDELETE tSET tMODE tPRINT tEXAM tDEFINE tABORT
-%token tCLASS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE 
+%token tCLASS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
 %token tNO_SYMBOL tEOL
 %token tSYMBOLFILE
+%token tFRAME
+
 
 %token <string> tIDENTIFIER
 %token <integer> tNUM tFORMAT
@@ -87,12 +90,17 @@
     | tLIST addr tEOL          { DEBUG_List( &$2, 15 ); }
     | tABORT tEOL              { kill(getpid(), SIGABRT); }
     | tSYMBOLFILE tIDENTIFIER tEOL  { DEBUG_ReadSymbolTable( $2 ); }
-    | tDEFINE tIDENTIFIER addr tEOL { DEBUG_AddSymbol( $2, &$3 ); }
+    | tDEFINE tIDENTIFIER addr tEOL { DEBUG_AddSymbol( $2, &$3, NULL ); }
     | tMODE tNUM tEOL          { mode_command($2); }
     | tENABLE tNUM tEOL        { DEBUG_EnableBreakpoint( $2, TRUE ); }
     | tDISABLE tNUM tEOL       { DEBUG_EnableBreakpoint( $2, FALSE ); }
     | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
     | tBACKTRACE tEOL	       { DEBUG_BackTrace(); }
+    | tUP tEOL		       { DEBUG_SetFrame( curr_frame + 1 );  }
+    | tUP tNUM tEOL	       { DEBUG_SetFrame( curr_frame + $2 ); }
+    | tDOWN tEOL	       { DEBUG_SetFrame( curr_frame - 1 );  }
+    | tDOWN tNUM tEOL	       { DEBUG_SetFrame( curr_frame - $2 ); }
+    | tFRAME expr tEOL	       { DEBUG_SetFrame( $2 ); }
     | set_command
     | x_command
     | print_command
@@ -122,6 +130,10 @@
 break_command:
       tBREAK '*' addr tEOL     { DEBUG_AddBreakpoint( &$3 ); }
     | tBREAK symbol tEOL       { DEBUG_AddBreakpoint( &$2 ); }
+    | tBREAK symbol '+' expr tEOL { DBG_ADDR addr = $2;
+                                    addr.off += $4;
+                                    DEBUG_AddBreakpoint( &addr ); 
+                                  }
     | tBREAK tEOL              { DBG_ADDR addr = { CS_reg(DEBUG_context),
                                                    EIP_reg(DEBUG_context) };
                                  DEBUG_AddBreakpoint( &addr );
@@ -137,6 +149,7 @@
     | tINFO tSEGMENTS tEOL      { LDT_Print( 0, -1 ); }
     | tINFO tSTACK tEOL         { DEBUG_InfoStack(); }
     | tINFO tWND expr tEOL      { WIN_DumpWindow( $3 ); } 
+    | tINFO tLOCAL tEOL         { DEBUG_InfoLocals(); }
 
 walk_command:
       tWALK tCLASS tEOL         { CLASS_WalkClasses(); }
@@ -145,12 +158,19 @@
     | tWALK tWND tEOL           { WIN_WalkWindows( 0, 0 ); }
     | tWALK tWND tNUM tEOL      { WIN_WalkWindows( $3, 0 ); }
 
-symbol: tIDENTIFIER   { if (!DEBUG_GetSymbolValue( $1, &$$ ))
-			{
-			   fprintf( stderr, "Symbol %s not found\n", $1 );
-			   YYERROR;
-			}
-		      } 
+symbol:
+    tIDENTIFIER            { if (!DEBUG_GetSymbolValue( $1, -1, &$$ ))
+                             {
+                               fprintf( stderr, "Symbol %s not found\n", $1 );
+                               YYERROR;
+                             }
+                           }
+    | tIDENTIFIER ':' tNUM { if (!DEBUG_GetSymbolValue( $1, $3, &$$ ))
+                             {
+                               fprintf( stderr, "No code at %s:%d\n", $1, $3 );
+                               YYERROR;
+                             }
+                           }
 
 addr:
       expr                       { $$.seg = 0xffffffff; $$.off = $1; }
@@ -159,6 +179,8 @@
 segaddr:
       expr ':' expr              { $$.seg = $1; $$.off = $3; }
     | symbol                     { $$ = $1; }
+    | symbol '+' expr            { $$ = $1; $$.off += $3; }
+    | symbol '-' expr            { $$ = $1; $$.off -= $3; }
 
 expr:
       tNUM                       { $$ = $1; }
@@ -258,9 +280,29 @@
     if (!loaded_symbols)
     {
         loaded_symbols++;
-        PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym",
-                                  SymbolTableFile, sizeof(SymbolTableFile) );
-        DEBUG_ReadSymbolTable( SymbolTableFile );
+	/*
+	 * In some cases we can read the stabs information directly
+	 * from the executable.  If this is the case, we don't need
+	 * to bother with trying to read a symbol file, as the stabs
+	 * also have line number and local variable information.
+	 * As long as gcc is used for the compiler, stabs will
+	 * be the default.  On SVr4, DWARF could be used, but we
+	 * don't grok that yet, and in this case we fall back to using
+	 * the wine.sym file.
+	 */
+	if( DEBUG_ReadExecutableDbgInfo() == FALSE )
+        {
+	    PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym",
+                                     SymbolTableFile, sizeof(SymbolTableFile));
+	    DEBUG_ReadSymbolTable( SymbolTableFile );
+        }
+
+	/*
+	 * Read COFF, MSC, etc debug information that we noted when we
+	 * started up the executable.
+	 */
+	DEBUG_ProcessDeferredDebug();
+
         DEBUG_LoadEntryPoints();
     }
 
@@ -298,7 +340,8 @@
         }
 
         /* Show where we crashed */
-        DEBUG_PrintAddress( &addr, dbg_mode );
+        curr_frame = 0;
+        DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
         fprintf(stderr,":  ");
         if (DBG_CHECK_READ_PTR( &addr, 1 ))
         {
diff --git a/debugger/debug.l b/debugger/debug.l
index 7b8d278..93e0929 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -86,6 +86,10 @@
 $fs     { yylval.reg = REG_FS;  return tREG; }
 $gs     { yylval.reg = REG_GS;  return tREG; }
 
+up				{ return tUP; }
+down|dow|do			{ return tDOWN; }
+frame|fram|fra|fr		{ return tFRAME; }
+locals|local|loca|loc		{ return tLOCAL; }
 info|inf|in			{ return tINFO; }
 show|sho|sh			{ return tINFO; }
 list|lis|li|l			{ return tLIST; }
diff --git a/debugger/hash.c b/debugger/hash.c
index 82609e7..bfbdafa 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -16,13 +16,6 @@
 #include "toolhelp.h"
 #include "xmalloc.h"
 
-struct name_hash
-{
-    struct name_hash * next;
-    char *             name;
-    DBG_ADDR           addr;
-};
-
 #define NR_NAME_HASH 128
 
 static struct name_hash * name_hash_table[NR_NAME_HASH];
@@ -44,7 +37,8 @@
  *
  * Add a symbol to the table.
  */
-void DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr )
+struct name_hash *
+DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source )
 {
     struct name_hash  * new;
     int hash;
@@ -52,12 +46,32 @@
     new = (struct name_hash *) xmalloc(sizeof(struct name_hash));
     new->addr = *addr;
     new->name = xstrdup(name);
+
+    if( source != NULL )
+      {
+	new->sourcefile = xstrdup(source);
+      }
+    else
+      {
+	new->sourcefile = NULL;
+      }
+
+    new->n_lines = 0;
+    new->lines_alloc = 0;
+    new->linetab = NULL;
+
+    new->n_locals = 0;
+    new->locals_alloc = 0;
+    new->local_vars = NULL;
+
     new->next = NULL;
     hash = name_hash(name);
 
     /* Now insert into the hash table */
     new->next = name_hash_table[hash];
     name_hash_table[hash] = new;
+
+    return new;
 }
 
 
@@ -66,9 +80,11 @@
  *
  * Get the address of a named symbol.
  */
-BOOL32 DEBUG_GetSymbolValue( const char * name, DBG_ADDR *addr )
+BOOL32 DEBUG_GetSymbolValue( const char * name, const int lineno, 
+			     DBG_ADDR *addr )
 {
     char buffer[256];
+    int i;
     struct name_hash *nh;
 
     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
@@ -82,8 +98,45 @@
             if (!strcmp(nh->name, buffer)) break;
     }
 
-    if (!nh) return FALSE;
-    *addr = nh->addr;
+    /*
+     * If we don't have anything here, then try and see if this
+     * is a local symbol to the current stack frame.  No matter
+     * what, we have nothing more to do, so we let that function
+     * decide what we ultimately return.
+     */
+    if (!nh) return DEBUG_GetStackSymbolValue(name, addr);
+
+
+    if( lineno == -1 )
+      {
+	*addr = nh->addr;
+      }
+    else
+      {
+	/*
+	 * Search for the specific line number.  If we don't find it,
+	 * then return FALSE.
+	 */
+	if( nh->linetab == NULL )
+	  {
+	    return FALSE;
+	  }
+
+	for(i=0; i < nh->n_lines; i++ )
+	  {
+	    if( nh->linetab[i].line_number == lineno )
+	      {
+		*addr = nh->linetab[i].pc_offset;
+		return TRUE;
+	      }
+	  }
+
+	/*
+	 * This specific line number not found.
+	 */
+	return FALSE;
+      }
+
     return TRUE;
 }
 
@@ -120,14 +173,26 @@
  *           DEBUG_FindNearestSymbol
  *
  * Find the symbol nearest to a given address.
+ * If ebp is specified as non-zero, it means we should dump the argument
+ * list into the string we return as well.
  */
-const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr )
+const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
+				      struct name_hash ** rtn,
+				      unsigned int ebp)
 {
-    static char name_buffer[256];
+    static char name_buffer[MAX_PATH + 256];
+    static char arglist[1024];
+    static char argtmp[256];
     struct name_hash * nearest = NULL;
     struct name_hash * nh;
     unsigned int nearest_address = 0;
+    unsigned	int * ptr;
+    int lineno;
+    char * lineinfo, *sourcefile;
     int i;
+    char linebuff[16];
+
+    *rtn = NULL;
 
     for(i=0; i<NR_NAME_HASH; i++)
     {
@@ -142,11 +207,95 @@
     }
     if (!nearest) return NULL;
 
-    if (addr->off == nearest->addr.off)
-        sprintf( name_buffer, "%s", nearest->name );
+    *rtn = nearest;
+    lineinfo = "";
+    lineno = -1;
+
+    memset(arglist, '\0', sizeof(arglist));
+    if( ebp != 0 )
+      {
+	for(i=0; i < nearest->n_locals; i++ )
+	  {
+	    /*
+	     * If this is a register (offset == 0) or a local
+	     * variable, we don't want to know about it.
+	     */
+	    if( nearest->local_vars[i].offset <= 0 )
+	      {
+		continue;
+	      }
+
+	    ptr = (unsigned int *) (ebp + nearest->local_vars[i].offset);
+	    if( arglist[0] == '\0' )
+	      {
+		arglist[0] = '(';
+	      }
+	    else
+	      {
+		strcat(arglist, ", ");
+	      }
+
+	    sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name,
+		    *ptr);
+	    strcat(arglist, argtmp);
+	  }
+	if( arglist[0] == '(' )
+	  {
+	    strcat(arglist, ")");
+	  }
+      }
+
+    if( (nearest->sourcefile != NULL) && (flag == TRUE)
+	&& (addr->off - nearest->addr.off < 0x100000) )
+      {
+
+	/*
+	 * Try and find the nearest line number to the current offset.
+	 */
+	if( nearest->linetab != NULL )
+	  {
+	    /*
+	     * FIXME - this is an inefficient linear search.  A binary
+	     * search would be better if this gets to be a performance
+	     * bottleneck.
+	     */
+	    for(i=0; i < nearest->n_lines; i++)
+	      {
+		if( addr->off < nearest->linetab[i].pc_offset.off )
+		{
+		  break;
+		}
+		lineno = nearest->linetab[i].line_number;
+	      }
+	  }
+
+	if( lineno != -1 )
+	  {
+	    sprintf(linebuff, ":%d", lineno);
+	    lineinfo = linebuff;
+	  }
+
+        /* Remove the path from the file name */
+        sourcefile = strrchr( nearest->sourcefile, '/' );
+        if (!sourcefile) sourcefile = nearest->sourcefile;
+        else sourcefile++;
+
+	if (addr->off == nearest->addr.off)
+	  sprintf( name_buffer, "%s%s [%s%s]", nearest->name, 
+		   arglist, sourcefile, lineinfo);
+	else
+	  sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name,
+		   addr->off - nearest->addr.off, 
+		   arglist, sourcefile, lineinfo );
+      }
     else
-        sprintf( name_buffer, "%s+0x%lx", nearest->name,
-                addr->off - nearest->addr.off );
+      {
+	if (addr->off == nearest->addr.off)
+	  sprintf( name_buffer, "%s%s", nearest->name, arglist);
+	else
+	  sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
+		   addr->off - nearest->addr.off, arglist);
+      }
     return name_buffer;
 }
 
@@ -194,7 +343,7 @@
         if (!(*cpnt) || *cpnt == '\n') continue;
 		
         nargs = sscanf(buffer, "%lx %c %s", &addr.off, &type, name);
-        DEBUG_AddSymbol( name, &addr );
+        DEBUG_AddSymbol( name, &addr, NULL );
     }
     fclose(symbolfile);
 }
@@ -234,7 +383,7 @@
             {
                 addr.seg = HIWORD(address);
                 addr.off = LOWORD(address);
-                DEBUG_AddSymbol( buffer, &addr );
+                DEBUG_AddSymbol( buffer, &addr, NULL );
             }
         }
 
@@ -252,8 +401,59 @@
             {
                 addr.seg = HIWORD(address);
                 addr.off = LOWORD(address);
-                DEBUG_AddSymbol( buffer, &addr );
+                DEBUG_AddSymbol( buffer, &addr, NULL);
             }
         }
     }
 }
+
+void
+DEBUG_AddLineNumber( struct name_hash * func, int line_num, 
+		     unsigned long offset )
+{
+  if( func == NULL )
+    {
+      return;
+    }
+
+  if( func->n_lines + 1 >= func->lines_alloc )
+    {
+      func->lines_alloc += 32;
+      func->linetab = realloc(func->linetab,
+			      func->lines_alloc * sizeof(WineLineNo));
+    }
+
+  func->linetab[func->n_lines].line_number = line_num;
+  func->linetab[func->n_lines].pc_offset.seg = func->addr.seg;
+  func->linetab[func->n_lines].pc_offset.off = func->addr.off + offset;
+  func->n_lines++;
+}
+
+
+void
+DEBUG_AddLocal( struct name_hash * func, int regno, 
+		int offset,
+		int pc_start,
+		int pc_end,
+		char * name)
+{
+  if( func == NULL )
+    {
+      return;
+    }
+
+  if( func->n_locals + 1 >= func->locals_alloc )
+    {
+      func->locals_alloc += 32;
+      func->local_vars = realloc(func->local_vars,
+			      func->locals_alloc * sizeof(WineLocals));
+    }
+
+  func->local_vars[func->n_locals].regno = regno;
+  func->local_vars[func->n_locals].offset = offset;
+  func->local_vars[func->n_locals].pc_start = pc_start;
+  func->local_vars[func->n_locals].pc_end = pc_end;
+  func->local_vars[func->n_locals].name = xstrdup(name);
+  func->n_locals++;
+}
+
diff --git a/debugger/info.c b/debugger/info.c
index 57d8d27..2abc981 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -76,14 +76,38 @@
  *
  * Print an 16- or 32-bit address, with the nearest symbol if any.
  */
-void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen )
+struct name_hash *
+DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen, int flag )
 {
-    const char *name = DEBUG_FindNearestSymbol( addr );
+    struct name_hash * nh;
+    const char *name = DEBUG_FindNearestSymbol( addr, flag, &nh, 0 );
 
     if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
     if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
     else fprintf( stderr, "0x%08lx", addr->off );
     if (name) fprintf( stderr, " (%s)", name );
+    return nh;
+}
+/***********************************************************************
+ *           DEBUG_PrintAddressAndArgs
+ *
+ * Print an 16- or 32-bit address, with the nearest symbol if any.
+ * Similar to DEBUG_PrintAddress, but we print the arguments to
+ * each function (if known).  This is useful in a backtrace.
+ */
+struct name_hash *
+DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, int addrlen, 
+			   unsigned int ebp, int flag )
+{
+    struct name_hash * nh;
+    const char *name = DEBUG_FindNearestSymbol( addr, flag, &nh, ebp );
+
+    if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
+    if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
+    else fprintf( stderr, "0x%08lx", addr->off );
+    if (name) fprintf( stderr, " (%s)", name );
+
+    return nh;
 }
 
 
@@ -100,19 +124,20 @@
 "The commands accepted by the Wine debugger are a small subset",
 "of the commands that gdb would accept.",
 "The commands currently are:",
-"  break [*<addr>]                      delete break bpnum",
-"  disable bpnum                        enable bpnum",
-"  help                                 quit",
-"  bt                                   cont",
-"  step                                 next",
-"  x <addr>                             print <expr>",
-"  set <reg> = <expr>                   set *<addr> = <expr>",
-"  symbolfile <filename>                define <identifier> <addr>",
-"  list <addr>\n",
+"  break [*<addr>]                        delete break bpnum",
+"  disable bpnum                          enable bpnum",
+"  help                                   quit",
+"  bt                                     cont",
+"  step                                   next",
+"  x <addr>                               print <expr>",
+"  set <reg> = <expr>                     set *<addr> = <expr>",
+"  symbolfile <filename>                  define <identifier> <addr>",
+"  up                                     down\n",
+"  list <addr>                            frame <n>\n",
 
 "Wine-specific commands:",
-"  mode [16,32]                         walk [wnd,class,queue] <handle>",
-"  info [reg,stack,break,segments]      info [wnd, queue] <handle>\n",
+"  mode [16,32]                           walk [wnd,class,queue] <handle>",
+"  info [reg,stack,break,segments,locals] info [wnd, queue] <handle>\n",
 
 "The 'x' command accepts repeat counts and formats (including 'i') in the",
 "same way that gdb does.\n",
@@ -144,7 +169,7 @@
     DBG_FIX_ADDR_SEG( addr, CS_reg(DEBUG_context) );
     while (count-- > 0)
     {
-        DEBUG_PrintAddress( addr, dbg_mode );
+        DEBUG_PrintAddress( addr, dbg_mode, FALSE );
         fprintf( stderr, ":  " );
         if (!DBG_CHECK_READ_PTR( addr, 1 )) return;
         DEBUG_Disasm( addr );
diff --git a/debugger/memory.c b/debugger/memory.c
index a51e915..ee826b4 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -153,7 +153,7 @@
 
     if (format != 'i' && count > 1)
     {
-        DEBUG_PrintAddress( &addr, dbg_mode );
+        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
         fprintf(stderr,": ");
     }
 
@@ -176,7 +176,7 @@
 	case 'i':
 		while (count--)
                 {
-                    DEBUG_PrintAddress( &addr, dbg_mode );
+                    DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
                     fprintf(stderr,": ");
                     if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
                     DEBUG_Disasm( &addr );
@@ -193,7 +193,7 @@
                     if ((i % 8) == 7)
                     {
                         fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode );
+                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
                         fprintf(stderr,": ");
                     }
 		}
@@ -210,7 +210,7 @@
                     if ((i % 8) == 7)
                     {
                         fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode );
+                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
                         fprintf(stderr,": ");
                     }
 		}
@@ -227,7 +227,7 @@
                     if ((i % 8) == 7)
                     {
                         fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode );
+                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
                         fprintf(stderr,": ");
                     }
 		}
@@ -248,7 +248,7 @@
                     if ((i % 32) == 31)
                     {
                         fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode );
+                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
                         fprintf(stderr,": ");
                     }
 		}
@@ -264,7 +264,7 @@
                     if ((i % 16) == 15)
                     {
                         fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode );
+                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
                         fprintf(stderr,": ");
                     }
 		}
diff --git a/debugger/msc.c b/debugger/msc.c
new file mode 100644
index 0000000..dc29ca9
--- /dev/null
+++ b/debugger/msc.c
@@ -0,0 +1,413 @@
+/*
+ * File msc.c - read VC++ debug information from COFF and eventually
+ * from PDB files.
+ *
+ * Copyright (C) 1996, Eric Youngdale.
+ *
+ * Note - this handles reading debug information for 32 bit applications
+ * that run under Windows-NT for example.  I doubt that this would work well
+ * for 16 bit applications, but I don't think it really matters since the
+ * file format is different, and we should never get in here in such cases.
+ */
+
+#include <stdio.h>
+
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <strings.h>
+#include <unistd.h>
+#include <malloc.h>
+
+#include "win.h"
+#include "pe_image.h"
+#include "debugger.h"
+#include "peexe.h"
+#include "xmalloc.h"
+
+/*
+ * For the type CODEVIEW debug directory entries, the debug directory
+ * points to a structure like this.  The cv_name field is the name
+ * of an external .PDB file.
+ */
+struct CodeViewDebug
+{
+	char		    cv_nbtype[8];
+	unsigned int	    cv_timestamp;
+	char		    cv_unknown[4];
+	char		    cv_name[1];
+};
+
+struct MiscDebug {
+    unsigned int       DataType;
+    unsigned int       Length;
+    char	       Unicode;
+    char	       Reserved[3];
+    char	       Data[1];
+};
+
+/*
+ * This is the header that the COFF variety of debug header points to.
+ */
+struct CoffDebug {
+    unsigned int   N_Sym;
+    unsigned int   SymbolOffset;
+    unsigned int   N_Linenum;
+    unsigned int   LinenumberOffset;
+    unsigned int   Unused[4];
+};
+
+struct CoffLinenum {
+	unsigned int	VirtualAddr;
+	unsigned int	Linenum;
+};
+
+struct CoffFiles {
+	unsigned int	startaddr;
+	unsigned int	endaddr;
+	char	      * filename;
+};
+
+
+struct CoffSymbol {
+    union {
+        char    ShortName[8];
+        struct {
+            unsigned int   NotLong;
+            unsigned int   StrTaboff;
+        } Name;
+    } N;
+    unsigned int   Value;
+    short	   SectionNumber;
+    short	   Type;
+    char	   StorageClass;
+    unsigned char  NumberOfAuxSymbols;
+};
+
+struct CoffAuxSection{
+  unsigned int   Length;
+  unsigned short NumberOfRelocations;
+  unsigned short NumberOfLinenumbers;
+  unsigned int   CheckSum;
+  short          Number;
+  char           Selection;
+} Section;
+
+struct deferred_debug_info
+{
+	struct deferred_debug_info	* next;
+	char				* load_addr;
+	char				* dbg_info;
+	int				  dbg_size;
+	struct PE_Debug_dir		* dbgdir;
+	struct pe_data			* pe;
+};
+
+struct deferred_debug_info * dbglist = NULL;
+
+/*
+ * A simple macro that tells us whether a given COFF symbol is a
+ * function or not.
+ */
+#define N_TMASK                             0x0030
+#define IMAGE_SYM_DTYPE_FUNCTION            2
+#define N_BTSHFT                            4
+#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT))
+
+
+/*
+ * This is what we are looking for in the COFF symbols.
+ */
+#define IMAGE_SYM_CLASS_EXTERNAL            0x2
+#define IMAGE_SYM_CLASS_STATIC              0x3
+#define IMAGE_SYM_CLASS_FILE                0x67
+
+/*
+ * In this function, we keep track of deferred debugging information
+ * that we may need later if we were to need to use the internal debugger.
+ * We don't fully process it here for performance reasons.
+ */
+int
+DEBUG_RegisterDebugInfo(int fd, struct pe_data * pe, 
+			int load_addr, u_long v_addr, u_long size)
+{
+  int			  rtn = FALSE;
+  struct PE_Debug_dir	* dbgptr;
+  struct deferred_debug_info * deefer;
+
+  dbgptr = (struct PE_Debug_dir *) (load_addr + v_addr);
+  for(; size > 0; size -= sizeof(*dbgptr), dbgptr++ )
+    {
+      switch(dbgptr->type)
+	{
+	case IMAGE_DEBUG_TYPE_COFF:
+	case IMAGE_DEBUG_TYPE_CODEVIEW:
+	case IMAGE_DEBUG_TYPE_MISC:
+	  /*
+	   * This is usually an indirection to a .DBG file.
+	   * This is similar to (but a slightly older format) from the
+	   * PDB file.
+	   *
+	   * First check to see if the image was 'stripped'.  If so, it
+	   * means that this entry points to a .DBG file.  Otherwise,
+	   * it just points to itself, and we can ignore this.
+	   */
+	  if(    (dbgptr->type == IMAGE_DEBUG_TYPE_MISC)
+	      && (pe->pe_header->coff.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) == 0 )
+	    {
+	      break;
+	    }
+
+	  deefer = (struct deferred_debug_info *) xmalloc(sizeof(*deefer));
+	  deefer->pe = pe;
+
+	  deefer->dbg_info = NULL;
+	  deefer->dbg_size = 0;
+
+	  /*
+	   * Read the important bits.  What we do after this depends
+	   * upon the type, but this is always enough so we are able
+	   * to proceed if we know what we need to do next.
+	   */
+	  deefer->dbg_size = dbgptr->dbgsize;
+	  deefer->dbg_info = (char *) xmalloc(dbgptr->dbgsize);
+	  lseek(fd, dbgptr->dbgoff, SEEK_SET);
+	  read(fd, deefer->dbg_info, deefer->dbg_size);
+
+	  deefer->load_addr = (char *) load_addr;
+	  deefer->dbgdir = dbgptr;
+	  deefer->next = dbglist;
+	  dbglist = deefer;
+	  break;
+	default:
+	}
+    }
+
+  return (rtn);
+
+}
+
+/*
+ * Process COFF debugging information embedded in a Win32 application.
+ *
+ * FIXME - we need to process the source file information and the line
+ * numbers.
+ */
+static
+int
+DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
+{
+  struct CoffAuxSection * aux;
+  struct CoffDebug   * coff;
+  struct CoffSymbol  * coff_sym;
+  struct CoffSymbol  * coff_symbol;
+  struct CoffLinenum * coff_linetab;
+  char		     * coff_strtab;
+  int		       i;
+  DBG_ADDR	       new_addr;
+  int		       rtn = FALSE;
+  int		       naux;
+  char		       namebuff[9];
+  char		     * nampnt;
+  int		       nfiles = 0;
+  int		       nfiles_alloc = 0;
+  struct CoffFiles   * coff_files = NULL;
+  struct CoffFiles   * curr_file = NULL;
+  char		     * this_file;
+  int		       j;
+
+  coff = (struct CoffDebug *) deefer->dbg_info;
+
+  coff_symbol = (struct CoffSymbol *) ((unsigned int) coff + coff->SymbolOffset);
+  coff_linetab = (struct CoffLinenum *) ((unsigned int) coff + coff->LinenumberOffset);
+  coff_strtab = (char *) ((unsigned int) coff_symbol + 18*coff->N_Sym);
+
+  for(i=0; i < coff->N_Sym; i++ )
+    {
+      /*
+       * We do this because some compilers (i.e. gcc) incorrectly
+       * pad the structure up to a 4 byte boundary.  The structure
+       * is really only 18 bytes long, so we have to manually make sure
+       * we get it right.
+       *
+       * FIXME - there must be a way to have autoconf figure out the
+       * correct compiler option for this.  If it is always gcc, that
+       * makes life simpler, but I don't want to force this.
+       */
+      coff_sym = (struct CoffSymbol *) ((unsigned int) coff_symbol + 18*i);
+      naux = coff_sym->NumberOfAuxSymbols;
+
+      if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
+	{
+	  if( nfiles + 1 >= nfiles_alloc )
+	    {
+	      nfiles_alloc += 10;
+	      coff_files = (struct CoffFiles *) realloc( coff_files,
+			nfiles_alloc * sizeof(struct CoffFiles));
+	    }
+	  curr_file = coff_files + nfiles;
+	  nfiles++;
+	  curr_file->startaddr = 0xffffffff;
+	  curr_file->endaddr   = 0;
+	  curr_file->filename =  ((char *) coff_sym) + 18;
+	}
+
+      /*
+       * This guy marks the size and location of the text section
+       * for the current file.  We need to keep track of this so
+       * we can figure out what file the different global functions
+       * go with.
+       */
+      if(    (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
+	  && (naux != 0)
+	  && (coff_sym->SectionNumber == 1) )
+	{
+	  aux = (struct CoffAuxSection *) ((unsigned int) coff_sym + 18);
+	  if( curr_file->startaddr > coff_sym->Value )
+	    {
+	      curr_file->startaddr = coff_sym->Value;
+	    }
+	  
+	  if( curr_file->startaddr > coff_sym->Value )
+	    {
+	      curr_file->startaddr = coff_sym->Value;
+	    }
+	  
+	  if( curr_file->endaddr < coff_sym->Value + aux->Length )
+	    {
+	      curr_file->endaddr = coff_sym->Value + aux->Length;
+	    }
+	  
+	}
+
+      if(    (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
+	  && (naux == 0)
+	  && (coff_sym->SectionNumber == 1) )
+	{
+	  /*
+	   * This is a normal static function when naux == 0.
+	   * Just register it.  The current file is the correct
+	   * one in this instance.
+	   */
+	  if( coff_sym->N.Name.NotLong )
+	    {
+	      memcpy(namebuff, coff_sym->N.ShortName, 8);
+	      namebuff[8] = '\0';
+	      nampnt = &namebuff[0];
+	    }
+	  else
+	    {
+	      nampnt = coff_strtab + coff_sym->N.Name.StrTaboff;
+	    }
+
+	  new_addr.seg = 0;
+	  new_addr.off = (int) (deefer->load_addr + coff_sym->Value);
+	  DEBUG_AddSymbol( nampnt, &new_addr, curr_file->filename );
+	}
+
+      if(    (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
+	  && ISFCN(coff_sym->Type)
+          && (coff_sym->SectionNumber > 0) )
+	{
+	  if( coff_sym->N.Name.NotLong )
+	    {
+	      memcpy(namebuff, coff_sym->N.ShortName, 8);
+	      namebuff[8] = '\0';
+	      nampnt = &namebuff[0];
+	    }
+	  else
+	    {
+	      nampnt = coff_strtab + coff_sym->N.Name.StrTaboff;
+	    }
+
+	  new_addr.seg = 0;
+	  new_addr.off = (int) (deefer->load_addr + coff_sym->Value);
+
+#if 0
+	  fprintf(stderr, "%d: %x %s\n", i, new_addr.off, nampnt);
+#endif
+
+	  /*
+	   * Now we need to figure out which file this guy belongs to.
+	   */
+	  this_file = NULL;
+	  for(j=0; j < nfiles; j++)
+	    {
+	      if( coff_files[j].startaddr <= coff_sym->Value
+		  && coff_files[j].endaddr > coff_sym->Value )
+		{
+		  this_file = coff_files[j].filename;
+		  break;
+		}
+	    }
+	  DEBUG_AddSymbol( nampnt, &new_addr, this_file );
+	}
+	  
+      /*
+       * For now, skip past the aux entries.
+       */
+      i += naux;
+      
+    }
+    
+  rtn = TRUE;
+
+  if( coff_files != NULL )
+    {
+      free(coff_files);
+    }
+
+  return (rtn);
+
+}
+
+int
+DEBUG_ProcessDeferredDebug()
+{
+  struct deferred_debug_info * deefer;
+  struct CodeViewDebug	     * cvd;
+  struct MiscDebug	     * misc;
+
+  for(deefer = dbglist; deefer; deefer = deefer->next)
+    {
+      switch(deefer->dbgdir->type)
+	{
+	case IMAGE_DEBUG_TYPE_COFF:
+	  /*
+	   * Standard COFF debug information that VC++ adds when you
+	   * use /debugtype:both with the linker.
+	   */
+#if 0
+	  fprintf(stderr, "Processing COFF symbols...\n");
+#endif
+	  DEBUG_ProcessCoff(deefer);
+	  break;
+	case IMAGE_DEBUG_TYPE_CODEVIEW:
+	  /*
+	   * This is a pointer to a PDB file of some sort.
+	   */
+	  cvd = (struct CodeViewDebug *) deefer->dbg_info;
+#if 0
+	  fprintf(stderr, "Processing PDB file %s\n", cvd->cv_name);
+#endif
+	  break;
+	case IMAGE_DEBUG_TYPE_MISC:
+	  /*
+	   * A pointer to a .DBG file of some sort.
+	   */
+	  misc = (struct MiscDebug *) deefer->dbg_info;
+#if 0
+	  fprintf(stderr, "Processing DBG file %s\n", misc->Data);
+#endif
+	  break;
+	default:
+	  /*
+	   * We should never get here...
+	   */
+	  break;
+	}
+    }
+  return TRUE;
+}
diff --git a/debugger/registers.c b/debugger/registers.c
index 4545d78..3fc5422 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -46,14 +46,14 @@
         case REG_FS:  FS_reg(DEBUG_context)  = val; break;
 #else
         case REG_FS:
-            fprintf( stderr, "Register %fs not supported on this system\n" );
+            fprintf( stderr, "Register %%fs not supported on this system\n" );
             break;
 #endif
 #ifdef GS_reg
         case REG_GS:  GS_reg(DEBUG_context)  = val; break;
 #else
         case REG_GS:
-            fprintf( stderr, "Register %gs not supported on this system\n" );
+            fprintf( stderr, "Register %%gs not supported on this system\n" );
             break;
 #endif
     }
@@ -97,14 +97,14 @@
         case REG_FS:  return FS_reg(DEBUG_context);
 #else
         case REG_FS:
-            fprintf( stderr, "Register %fs not supported on this system\n" );
+            fprintf( stderr, "Register %%fs not supported on this system\n" );
             return 0;
 #endif
 #ifdef GS_reg
         case REG_GS:  return GS_reg(DEBUG_context);
 #else
         case REG_GS:
-            fprintf( stderr, "Register %gs not supported on this system\n" );
+            fprintf( stderr, "Register %%gs not supported on this system\n" );
             return 0;
 #endif
     }
diff --git a/debugger/stabs.c b/debugger/stabs.c
new file mode 100644
index 0000000..2c238be
--- /dev/null
+++ b/debugger/stabs.c
@@ -0,0 +1,375 @@
+/*
+ * File stabs.c - read stabs information from the wine executable itself.
+ *
+ * Copyright (C) 1996, Eric Youngdale.
+ */
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include "win.h"
+#include "debugger.h"
+
+#ifdef __ELF__
+#include <elf.h>
+#endif
+
+#define N_UNDF		0x00
+#define N_GSYM		0x20
+#define N_FUN		0x24
+#define N_STSYM		0x26
+#define N_LCSYM		0x28
+#define N_MAIN		0x2a
+#define N_ROSYM		0x2c
+#define N_OPT		0x3c
+#define N_RSYM		0x40
+#define N_SLINE		0x44
+#define N_SO		0x64
+#define N_LSYM		0x80
+#define N_BINCL		0x82
+#define N_SOL		0x84
+#define N_PSYM		0xa0
+#define N_EINCL		0xa2
+#define N_LBRAC		0xc0
+#define N_RBRAC		0xe0
+
+
+/*
+ * Set so that we know the main executable name and path.
+ */
+char * DEBUG_argv0;
+
+struct stab_nlist {
+  union {
+    char *n_name;
+    struct stab_nlist *n_next;
+    long n_strx;
+  } n_un;
+  unsigned char n_type;
+  char n_other;
+  short n_desc;
+  unsigned long n_value;
+};
+
+#ifdef __ELF__
+
+int
+DEBUG_ParseStabs(char * addr, Elf32_Shdr * stabsect, Elf32_Shdr * stabstr)
+{
+  int i;
+  int ignore = FALSE;
+  int nstab;
+  struct stab_nlist * stab_ptr;
+  char * strs;
+  char * ptr;
+  char * xptr;
+  char currpath[PATH_MAX];
+  char symname[4096];
+  char * subpath = NULL;
+  DBG_ADDR     new_addr;
+  struct name_hash * curr_func = NULL;
+  int strtabinc;
+
+  nstab = stabsect->sh_size / sizeof(struct stab_nlist);
+  stab_ptr = (struct stab_nlist *) (addr + stabsect->sh_offset);
+  strs  = (char *) (addr + stabstr->sh_offset);
+
+  memset(currpath, 0, sizeof(currpath));
+
+  strtabinc = 0;
+  for(i=0; i < nstab; i++, stab_ptr++ )
+    {
+      ptr = strs + (unsigned int) stab_ptr->n_un.n_name;
+      switch(stab_ptr->n_type)
+	{
+	case N_GSYM:
+	  /*
+	   * These are useless.  They have no value, and you have to
+	   * read the normal symbol table to get the address.  Thus we
+	   * ignore them, and when we process the normal symbol table
+	   * we should do the right thing.
+	   */
+	case N_RBRAC:
+	case N_LBRAC:
+	  /*
+	   * We need to keep track of these so we get symbol scoping
+	   * right for local variables.  For now, we just ignore them.
+	   * The hooks are already there for dealing with this however,
+	   * so all we need to do is to keep count of the nesting level,
+	   * and find the RBRAC for each matching LBRAC.
+	   */
+	  break;
+	case N_LCSYM:
+	case N_STSYM:
+	  /*
+	   * These are static symbols and BSS symbols.
+	   */
+	  new_addr.seg = 0;
+	  new_addr.off = stab_ptr->n_value;
+
+	  strcpy(symname, ptr);
+	  xptr = strchr(symname, ':');
+	  if( xptr != NULL )
+	    {
+	      *xptr = '\0';
+	    }
+	  DEBUG_AddSymbol( symname, &new_addr, currpath );
+	  break;
+	case N_PSYM:
+	  /*
+	   * These are function parameters.
+	   */
+	  if(     (curr_func != NULL)
+	       && (stab_ptr->n_value != 0) )
+	    {
+	      strcpy(symname, ptr);
+	      xptr = strchr(symname, ':');
+	      if( xptr != NULL )
+		{
+		  *xptr = '\0';
+		}
+	      DEBUG_AddLocal(curr_func, 0, 
+			     stab_ptr->n_value, 0, 0, symname);
+	    }
+	  break;
+	case N_RSYM:
+	  if( curr_func != NULL )
+	    {
+	      strcpy(symname, ptr);
+	      xptr = strchr(symname, ':');
+	      if( xptr != NULL )
+		{
+		  *xptr = '\0';
+		}
+	      DEBUG_AddLocal(curr_func, stab_ptr->n_value, 0, 0, 0, symname);
+	    }
+	  break;
+	case N_LSYM:
+	  if(     (curr_func != NULL)
+	       && (stab_ptr->n_value != 0) )
+	    {
+	      strcpy(symname, ptr);
+	      xptr = strchr(symname, ':');
+	      if( xptr != NULL )
+		{
+		  *xptr = '\0';
+		}
+	      DEBUG_AddLocal(curr_func, 0, 
+			     stab_ptr->n_value, 0, 0, symname);
+	    }
+	  break;
+	case N_SLINE:
+	  /*
+	   * This is a line number.  These are always relative to the start
+	   * of the function (N_FUN), and this makes the lookup easier.
+	   */
+	  if( curr_func != NULL )
+	    {
+	      DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc, 
+				  stab_ptr->n_value);
+	    }
+	  break;
+	case N_FUN:
+	  /*
+	   * For now, just declare the various functions.  Later
+	   * on, we will add the line number information and the
+	   * local symbols.
+	   */
+	  if( !ignore )
+	    {
+	      new_addr.seg = 0;
+	      new_addr.off = stab_ptr->n_value;
+	      /*
+	       * Copy the string to a temp buffer so we
+	       * can kill everything after the ':'.  We do
+	       * it this way because otherwise we end up dirtying
+	       * all of the pages related to the stabs, and that
+	       * sucks up swap space like crazy.
+	       */
+	      strcpy(symname, ptr);
+	      xptr = strchr(symname, ':');
+	      if( xptr != NULL )
+		{
+		  *xptr = '\0';
+		}
+	      curr_func = DEBUG_AddSymbol( symname, &new_addr, currpath );
+	    }
+	  else
+	    {
+	      /*
+	       * Don't add line number information for this function
+	       * any more.
+	       */
+	      curr_func = NULL;
+	    }
+	  break;
+	case N_SO:
+	  /*
+	   * This indicates a new source file.  Append the records
+	   * together, to build the correct path name.
+	   */
+	  if( *ptr == '\0' )
+	    {
+	      /*
+	       * Nuke old path.
+	       */
+	      currpath[0] = '\0';
+	      curr_func = NULL;
+	    }
+	  else
+	    {
+	      strcat(currpath, ptr);
+	      subpath = ptr;
+	    }
+	  break;
+	case N_SOL:
+	  /*
+	   * This indicates we are including stuff from an include file.
+	   * If this is the main source, enable the debug stuff, otherwise
+	   * ignore it.
+	   */
+	  if( subpath == NULL || strcmp(ptr, subpath) == 0 )
+	    {
+	      ignore = FALSE;
+	    }
+	  else
+	    {
+	      ignore = TRUE;
+	      curr_func = NULL;
+	    }
+	  break;
+	case N_UNDF:
+	  strs += strtabinc;
+	  strtabinc = stab_ptr->n_value;
+	  curr_func = NULL;
+	  break;
+	case N_OPT:
+	  /*
+	   * Ignore this.  We don't care what it points to.
+	   */
+	  break;
+	case N_BINCL:
+	case N_EINCL:
+	case N_MAIN:
+	  /*
+	   * Always ignore these.  GCC doesn't even generate them.
+	   */
+	  break;
+	default:
+	  break;
+	}
+#if 0
+      fprintf(stderr, "%d %x %s\n", stab_ptr->n_type, 
+	      (unsigned int) stab_ptr->n_value,
+	      strs + (unsigned int) stab_ptr->n_un.n_name);
+#endif
+    }
+  return TRUE;
+}
+
+int
+DEBUG_ReadExecutableDbgInfo(void)
+{
+  int			rtn = FALSE;
+  char		      * exe_name;
+  struct stat		statbuf;
+  int			fd = -1;
+  int			status;
+  char		      * addr = (char *) 0xffffffff;
+  Elf32_Ehdr	      * ehptr;
+  Elf32_Shdr	      * spnt;
+  char		      * shstrtab;
+  int			nsect;
+  int			i;
+  int			stabsect;
+  int			stabstrsect;
+
+  exe_name = DEBUG_argv0;
+
+  /*
+   * Make sure we can stat and open this file.
+   */
+  if( exe_name == NULL )
+    {
+      goto leave;
+    }
+
+  status = stat(exe_name, &statbuf);
+  if( status == -1 )
+    {
+      goto leave;
+    }
+
+  /*
+   * Now open the file, so that we can mmap() it.
+   */
+  fd = open(exe_name, O_RDONLY);
+  if( fd == -1 )
+    {
+      goto leave;
+    }
+
+
+  /*
+   * Now mmap() the file.
+   */
+  addr = mmap(0, statbuf.st_size, PROT_READ, 
+	      MAP_PRIVATE, fd, 0);
+
+  /*
+   * Next, we need to find a few of the internal ELF headers within
+   * this thing.  We need the main executable header, and the section
+   * table.
+   */
+  ehptr = (Elf32_Ehdr *) addr;
+  spnt = (Elf32_Shdr *) (addr + ehptr->e_shoff);
+  nsect = ehptr->e_shnum;
+  shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
+
+  stabsect = stabstrsect = -1;
+
+  for(i=0; i < nsect; i++)
+    {
+      if( strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0 )
+	{
+	  stabsect = i;
+	}
+
+      if( strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0 )
+	{
+	  stabstrsect = i;
+	}
+    }
+
+  if( stabsect == -1 || stabstrsect == -1 )
+    {
+      goto leave;
+    }
+
+  /*
+   * OK, now just parse all of the stabs.
+   */
+  rtn = DEBUG_ParseStabs(addr, spnt + stabsect, spnt + stabstrsect);
+
+leave:
+
+  if( addr != (char *) 0xffffffff )
+    {
+      munmap(addr, statbuf.st_size);
+    }
+
+  if( fd != -1 )
+    {
+      close(fd);
+    }
+
+  return (rtn);
+
+}
+
+#endif  /* __ELF__ */
diff --git a/debugger/stack.c b/debugger/stack.c
index bbf9033..9ac2ea2 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -2,13 +2,35 @@
  * Debugger stack handling
  *
  * Copyright 1995 Alexandre Julliard
+ * Copyright 1996 Eric Youngdale
  */
 
 #include <stdio.h>
+#include <malloc.h>
+#include "xmalloc.h"
 #include "windows.h"
 #include "debugger.h"
 
 
+/*
+ * We keep this info for each frame, so that we can
+ * find local variable information correctly.
+ */
+struct bt_info
+{
+  unsigned int	     eip;
+  unsigned int	     ebp;
+  struct name_hash * frame;
+};
+
+static int nframe;
+static struct bt_info * frames = NULL;
+int curr_frame;
+static char * reg_name[] =
+{
+  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
+};
+
 typedef struct
 {
     WORD bp;
@@ -66,19 +88,45 @@
     if (SS_reg(DEBUG_context) == WINE_DATA_SELECTOR)  /* 32-bit mode */
     {
         addr.seg = 0;
-        fprintf(stderr,"%d ",frameno++);
-        addr.off = EIP_reg(DEBUG_context);
-        DEBUG_PrintAddress( &addr, 32 );
-        fprintf( stderr, "\n" );
         addr.off = EBP_reg(DEBUG_context);
+	nframe = 1;
         while (addr.off)
         {
             FRAME32 *frame = (FRAME32 *)addr.off;
             if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
             if (!frame->ip) break;
-            fprintf(stderr,"%d ",frameno++);
+            addr.off = frame->bp;
+	    nframe++;
+        }
+	if( frames != NULL )
+	  {
+	    free(frames);
+	  }
+
+	frames = (struct bt_info *) xmalloc(nframe 
+					      * sizeof(struct bt_info) );
+        fprintf(stderr,"%s%d ",(curr_frame == 0 ? "=>" : "  "), frameno++);
+        addr.off = EIP_reg(DEBUG_context);
+	frames[0].eip = addr.off;
+        frames[0].frame = DEBUG_PrintAddress( &addr, 32, TRUE );
+        fprintf( stderr, "\n" );
+        addr.off = EBP_reg(DEBUG_context);
+
+	frames[0].ebp = addr.off;
+
+        while (addr.off)
+        {
+            FRAME32 *frame = (FRAME32 *)addr.off;
+            if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
+            if (!frame->ip) break;
+            fprintf(stderr,"%s%d ", (frameno == curr_frame ? "=>" : "  "),
+		    frameno);
             addr.off = frame->ip;
-            DEBUG_PrintAddress( &addr, 32 );
+	    frames[frameno].eip = addr.off;
+	    frames[frameno].ebp = frame->bp;
+            frames[frameno].frame = DEBUG_PrintAddressAndArgs( &addr, 32, 
+							frame->bp, TRUE );
+	    frameno++;
             fprintf( stderr, "\n" );
             addr.off = frame->bp;
         }
@@ -94,7 +142,7 @@
       fprintf( stderr,"%d ", frameno++ );
       addr.seg = cs;
       addr.off = IP_reg(DEBUG_context);
-      DEBUG_PrintAddress( &addr, 16 );
+      DEBUG_PrintAddress( &addr, 16, TRUE );
       fprintf( stderr, "\n" );
       addr.seg = ss;
       addr.off = BP_reg(DEBUG_context) & ~1;
@@ -107,7 +155,7 @@
           fprintf( stderr,"%d ", frameno++ );
           addr.seg = cs;
           addr.off = frame->ip;
-          DEBUG_PrintAddress( &addr, 16 );
+          DEBUG_PrintAddress( &addr, 16, TRUE );
           fprintf( stderr, "\n" );
           addr.seg = ss;
           addr.off = frame->bp & ~1;
@@ -115,3 +163,166 @@
   }
   fprintf( stderr, "\n" );
 }
+
+/***********************************************************************
+ *           DEBUG_GetSymbolValue
+ *
+ * Get the address of a named symbol from the current stack frame.
+ */
+BOOL32 DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr )
+{
+  struct name_hash * curr_func;
+  int		     i;
+
+  /*
+   * If we don't have a valid backtrace, then just return.
+   */
+  if( frames == NULL )
+    {
+      return FALSE;
+    }
+
+  curr_func = frames[curr_frame].frame;
+
+  /*
+   * If we don't know what the current function is, then we also have
+   * nothing to report here.
+   */
+  if( curr_func == NULL )
+    {
+      return FALSE;
+    }
+
+  for(i=0; i < curr_func->n_locals; i++ )
+    {
+      /*
+       * Test the range of validity of the local variable.  This
+       * comes up with RBRAC/LBRAC stabs in particular.
+       */
+      if(    (curr_func->local_vars[i].pc_start != 0)
+	  && ((frames[curr_frame].eip - curr_func->addr.off) 
+	      < curr_func->local_vars[i].pc_start) )
+	{
+	  continue;
+	}
+
+      if(    (curr_func->local_vars[i].pc_end != 0)
+	  && ((frames[curr_frame].eip - curr_func->addr.off) 
+	      > curr_func->local_vars[i].pc_end) )
+	{
+	  continue;
+	}
+
+      if( strcmp(name, curr_func->local_vars[i].name) == 0 )
+	{
+	  /*
+	   * OK, we found it.  Now figure out what to do with this.
+	   */
+	  if( curr_func->local_vars[i].regno != 0 )
+	    {
+	      /*
+	       * Register variable.  We don't know how to treat
+	       * this yet.
+	       */
+	      return FALSE;
+	    }
+
+	  addr->seg = 0;
+	  addr->off = frames[curr_frame].ebp + curr_func->local_vars[i].offset;
+
+	  return TRUE;
+	}
+    }
+  return FALSE;
+}
+
+int
+DEBUG_SetFrame(int newframe)
+{
+  int		rtn = FALSE;
+  /*
+   * Nothing for now.  Add support later.
+   */
+
+  curr_frame = newframe;
+  if( curr_frame < 0 )
+    {
+      curr_frame = 0;
+    }
+
+  if( curr_frame >= nframe )
+    {
+      curr_frame = nframe - 1;
+    }
+
+  rtn = TRUE;
+  return (rtn);
+}
+
+int
+DEBUG_InfoLocals()
+{
+  struct name_hash * curr_func;
+  int		     i;
+  int		rtn = FALSE;
+  unsigned	int * ptr;
+
+  /*
+   * If we don't have a valid backtrace, then just return.
+   */
+  if( frames == NULL )
+    {
+      return FALSE;
+    }
+
+  curr_func = frames[curr_frame].frame;
+
+  /*
+   * If we don't know what the current function is, then we also have
+   * nothing to report here.
+   */
+  if( curr_func == NULL )
+    {
+      return FALSE;
+    }
+
+  for(i=0; i < curr_func->n_locals; i++ )
+    {
+      /*
+       * Test the range of validity of the local variable.  This
+       * comes up with RBRAC/LBRAC stabs in particular.
+       */
+      if(    (curr_func->local_vars[i].pc_start != 0)
+	  && ((frames[curr_frame].eip - curr_func->addr.off) 
+	      < curr_func->local_vars[i].pc_start) )
+	{
+	  continue;
+	}
+
+      if(    (curr_func->local_vars[i].pc_end != 0)
+	  && ((frames[curr_frame].eip - curr_func->addr.off) 
+	      > curr_func->local_vars[i].pc_end) )
+	{
+	  continue;
+	}
+      
+      if( curr_func->local_vars[i].offset == 0 )
+	{
+	  fprintf(stderr, "%s:%s optimized into register $%s \n",
+		  curr_func->name, curr_func->local_vars[i].name,
+		  reg_name[curr_func->local_vars[i].regno]);
+	}
+      else
+	{
+	  ptr = (unsigned int *) (frames[curr_frame].ebp 
+				   + curr_func->local_vars[i].offset);
+	  fprintf(stderr, "%s:%s == 0x%8.8x\n",
+		  curr_func->name, curr_func->local_vars[i].name,
+		  *ptr);
+	}
+    }
+
+  rtn = TRUE;
+
+  return (rtn);
+}
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 237139e..6ce5881 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -21,11 +21,11 @@
 #include "dos_fs.h"
 #include "drive.h"
 #include "file.h"
+#include "heap.h"
 #include "msdos.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
-#include "string32.h"
 
 /* Chars we don't want to see in DOS file names */
 #define INVALID_DOS_CHARS  "*?<>|\"+=,;[] \345"
@@ -877,9 +877,9 @@
  */
 DWORD GetShortPathName32W( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
 {
-    LPSTR longpatha = STRING32_DupUniToAnsi( longpath );
+    LPSTR longpatha = HEAP_strdupWtoA( GetProcessHeap(), 0, longpath );
     LPCSTR dostruename = DOSFS_GetDosTrueName( longpatha, TRUE );
-    free( longpatha );
+    HeapFree( GetProcessHeap(), 0, longpatha );
     lstrcpynAtoW( shortpath, dostruename, shortlen );
     return strlen(dostruename);
 }
diff --git a/files/drive.c b/files/drive.c
index 74b3672..522518c 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -28,11 +28,11 @@
 #include "dos_fs.h"
 #include "drive.h"
 #include "file.h"
+#include "heap.h"
 #include "msdos.h"
 #include "options.h"
 #include "task.h"
 #include "xmalloc.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -529,7 +529,7 @@
 
 
 /***********************************************************************
- *           GetDiskFreeSpaceA   (KERNEL32.206)
+ *           GetDiskFreeSpace32A   (KERNEL32.206)
  */
 BOOL32 GetDiskFreeSpace32A( LPCSTR root, LPDWORD cluster_sectors,
                             LPDWORD sector_bytes, LPDWORD free_clusters,
@@ -562,7 +562,7 @@
 
 
 /***********************************************************************
- *           GetDiskFreeSpaceW   (KERNEL32.207)
+ *           GetDiskFreeSpace32W   (KERNEL32.207)
  */
 BOOL32 GetDiskFreeSpace32W( LPCWSTR root, LPDWORD cluster_sectors,
                             LPDWORD sector_bytes, LPDWORD free_clusters,
@@ -571,10 +571,10 @@
     LPSTR xroot;
     BOOL ret;
 
-    xroot = STRING32_DupUniToAnsi(root);
+    xroot = HEAP_strdupWtoA( GetProcessHeap(), 0, root);
     ret = GetDiskFreeSpace32A( xroot,cluster_sectors, sector_bytes,
                                free_clusters, total_clusters );
-    free( xroot );
+    HeapFree( GetProcessHeap(), 0, xroot );
     return ret;
 }
 
@@ -625,11 +625,9 @@
  */
 UINT32 GetDriveType32W( LPCWSTR root )
 {
-    LPSTR xpath=STRING32_DupUniToAnsi(root);
-    UINT32 ret;
-
-    ret = GetDriveType32A(xpath);
-    free(xpath);
+    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, root );
+    UINT32 ret = GetDriveType32A( xpath );
+    HeapFree( GetProcessHeap(), 0, xpath );
     return ret;
 }
 
@@ -669,12 +667,10 @@
  */
 UINT32 GetCurrentDirectory32W( UINT32 buflen, LPWSTR buf )
 {
-    LPSTR xpath=(char*)xmalloc(buflen+1);
-    UINT32 ret;
-
-    ret = GetCurrentDirectory32A(buflen,xpath);
-    STRING32_AnsiToUni(buf,xpath);
-    free(xpath);
+    LPSTR xpath = HeapAlloc( GetProcessHeap(), 0, buflen+1 );
+    UINT32 ret = GetCurrentDirectory32A( buflen, xpath );
+    lstrcpyAtoW( buf, xpath );
+    HeapFree( GetProcessHeap(), 0, xpath );
     return ret;
 }
 
@@ -715,10 +711,9 @@
  */
 BOOL32 SetCurrentDirectory32W( LPCWSTR dirW)
 {
-    LPSTR dir = STRING32_DupUniToAnsi(dirW);
-    BOOL32  res = SetCurrentDirectory32A(dir);
-    
-    free(dir);
+    LPSTR dir = HEAP_strdupWtoA( GetProcessHeap(), 0, dirW );
+    BOOL32 res = SetCurrentDirectory32A( dir );
+    HeapFree( GetProcessHeap(), 0, dir );
     return res;
 }
 
@@ -831,19 +826,19 @@
                                 DWORD *serial, DWORD *filename_len,
                                 DWORD *flags, LPWSTR fsname, DWORD fsname_len)
 {
-    LPSTR xroot    = root?STRING32_DupUniToAnsi(root):NULL;
-    LPSTR xvolname = label?(char*)xmalloc( label_len ):NULL;
-    LPSTR xfsname  = fsname?(char*)xmalloc( fsname_len ):NULL;
+    LPSTR xroot    = HEAP_strdupWtoA( GetProcessHeap(), 0, root );
+    LPSTR xvolname = label ? HeapAlloc(GetProcessHeap(),0,label_len) : NULL;
+    LPSTR xfsname  = fsname ? HeapAlloc(GetProcessHeap(),0,fsname_len) : NULL;
     BOOL32 ret = GetVolumeInformation32A( xroot, xvolname, label_len, serial,
                                           filename_len, flags, xfsname,
                                           fsname_len );
     if (ret)
     {
-        if (label) STRING32_AnsiToUni( label, xvolname );
-        if (fsname) STRING32_AnsiToUni( fsname, xfsname );
+        if (label) lstrcpyAtoW( label, xvolname );
+        if (fsname) lstrcpyAtoW( fsname, xfsname );
     }
-    if (xroot) free(xroot);
-    if (xvolname) free(xvolname);
-    if (xfsname) free(xfsname);
+    HeapFree( GetProcessHeap(), 0, xroot );
+    HeapFree( GetProcessHeap(), 0, xvolname );
+    HeapFree( GetProcessHeap(), 0, xfsname );
     return ret;
 }
diff --git a/files/file.c b/files/file.c
index fa3177e..5f41ecf 100644
--- a/files/file.c
+++ b/files/file.c
@@ -23,11 +23,11 @@
 #include "dos_fs.h"
 #include "drive.h"
 #include "global.h"
+#include "heap.h"
 #include "msdos.h"
 #include "options.h"
 #include "ldt.h"
 #include "task.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -630,12 +630,12 @@
     UINT32  ret;
 
     if (!path) return 0;
-    patha	= STRING32_DupUniToAnsi(path);
-    prefixa	= STRING32_DupUniToAnsi(prefix);
-    ret 	= GetTempFileName32A( patha, prefixa, unique, buffera );
-    STRING32_AnsiToUni( buffer, buffera );
-    free(patha);
-    free(prefixa);
+    patha   = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
+    prefixa = HEAP_strdupWtoA( GetProcessHeap(), 0, prefix );
+    ret     = GetTempFileName32A( patha, prefixa, unique, buffera );
+    lstrcpyAtoW( buffer, buffera );
+    HeapFree( GetProcessHeap(), 0, patha );
+    HeapFree( GetProcessHeap(), 0, prefixa );
     return ret;
 }
 
@@ -921,29 +921,27 @@
 /***********************************************************************
  *           SearchPath32W   (KERNEL32.448)
  */
-DWORD SearchPath32W(
-	LPCWSTR path,LPCWSTR fn,LPCWSTR ext,DWORD buflen,LPWSTR buf,
-	LPWSTR *lastpart
-) {
-	LPSTR	pathA = path?STRING32_DupUniToAnsi(path):NULL;
-	LPSTR	fnA = STRING32_DupUniToAnsi(fn);
-	LPSTR	extA = ext?STRING32_DupUniToAnsi(fn):NULL;
+DWORD SearchPath32W( LPCWSTR path, LPCWSTR fn, LPCWSTR ext, DWORD buflen,
+                     LPWSTR buf, LPWSTR *lastpart )
+{
+	LPSTR	pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
+	LPSTR	fnA = HEAP_strdupWtoA( GetProcessHeap(), 0, fn );
+	LPSTR	extA = HEAP_strdupWtoA( GetProcessHeap(), 0, ext );
 	LPSTR	lastpartA;
-	LPSTR	bufA = (char*)xmalloc(buflen+1);
+	LPSTR	bufA = HeapAlloc( GetProcessHeap(), 0, buflen + 1 );
 	DWORD	ret;
 
-	ret=SearchPath32A(pathA,fnA,extA,buflen,bufA,&lastpartA);
-	lstrcpynAtoW(buf,bufA,buflen);
-	if (lastpart) {
-		if (lastpartA)
-			*lastpart = buf+(lastpartA-bufA);
-		else
-			*lastpart = NULL;
+	ret = SearchPath32A(pathA,fnA,extA,buflen,bufA,&lastpartA);
+	lstrcpyAtoW( buf, bufA );
+	if (lastpart)
+        {
+            if (lastpartA) *lastpart = buf+(lastpartA-bufA);
+            else *lastpart = NULL;
 	}
-	free(bufA);
-	free(fnA);
-	if (pathA) free(pathA);
-	if (extA) free(extA);
+	HeapFree( GetProcessHeap(), 0, bufA );
+	HeapFree( GetProcessHeap(), 0, fnA );
+	HeapFree( GetProcessHeap(), 0, pathA );
+	HeapFree( GetProcessHeap(), 0, extA );
 	return ret;
 }
 
@@ -1282,9 +1280,9 @@
  */
 BOOL32 DeleteFile32W( LPCWSTR path )
 {
-    LPSTR xpath = STRING32_DupUniToAnsi(path);
+    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
     BOOL32 ret = RemoveDirectory32A( xpath );
-    free(xpath);
+    HeapFree( GetProcessHeap(), 0, xpath );
     return ret;
 }
 
@@ -1328,9 +1326,9 @@
  */
 BOOL32 CreateDirectory32W( LPCWSTR path, LPSECURITY_ATTRIBUTES lpsecattribs )
 {
-    LPSTR xpath = STRING32_DupUniToAnsi(path);
-    BOOL32 ret = CreateDirectory32A(xpath,lpsecattribs);
-    free(xpath);
+    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
+    BOOL32 ret = CreateDirectory32A( xpath, lpsecattribs );
+    HeapFree( GetProcessHeap(), 0, xpath );
     return ret;
 }
 
@@ -1391,9 +1389,9 @@
  */
 BOOL32 RemoveDirectory32W( LPCWSTR path )
 {
-    LPSTR xpath = STRING32_DupUniToAnsi(path);
+    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
     BOOL32 ret = RemoveDirectory32A( xpath );
-    free(xpath);
+    HeapFree( GetProcessHeap(), 0, xpath );
     return ret;
 }
 
diff --git a/files/profile.c b/files/profile.c
index 8b6bf27..2f08849 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -13,8 +13,8 @@
 
 #include "windows.h"
 #include "dos_fs.h"
+#include "heap.h"
 #include "xmalloc.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -649,7 +649,7 @@
  */
 UINT32 GetProfileInt32W( LPCWSTR section, LPCWSTR entry, INT32 def_val )
 {
-    if (!wininiW) wininiW = STRING32_DupAnsiToUni("win.ini");
+    if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
     return GetPrivateProfileInt32W( section, entry, def_val, wininiW );
 }
 
@@ -679,7 +679,7 @@
 INT32 GetProfileString32W( LPCWSTR section,LPCWSTR entry,LPCWSTR def_val,
                            LPWSTR buffer, INT32 len )
 {
-    if (!wininiW) wininiW = STRING32_DupAnsiToUni("win.ini");
+    if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
     return GetPrivateProfileString32W( section, entry, def_val,
                                        buffer, len, wininiW );
 }
@@ -706,7 +706,7 @@
  */
 BOOL32 WriteProfileString32W( LPCWSTR section, LPCWSTR entry, LPCWSTR string )
 {
-    if (!wininiW) wininiW = STRING32_DupAnsiToUni("win.ini");
+    if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
     return WritePrivateProfileString32W( section, entry, string, wininiW );
 }
 
@@ -749,15 +749,13 @@
 UINT32 GetPrivateProfileInt32W( LPCWSTR section, LPCWSTR entry, INT32 def_val,
                                 LPCWSTR filename )
 {
-    LPSTR sectionA=section?STRING32_DupUniToAnsi(section):NULL;
-    LPSTR entryA=entry?STRING32_DupUniToAnsi(entry):NULL;
-    LPSTR filenameA=filename?STRING32_DupUniToAnsi(filename):NULL;
-    UINT32 res;
-
-    res=GetPrivateProfileInt32A(sectionA,entryA,def_val,filenameA);
-    if (sectionA) free(sectionA);
-    if (filenameA) free(filenameA);
-    if (entryA) free(entryA);
+    LPSTR sectionA  = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
+    LPSTR entryA    = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
+    LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    UINT32 res = GetPrivateProfileInt32A(sectionA, entryA, def_val, filenameA);
+    HeapFree( GetProcessHeap(), 0, sectionA );
+    HeapFree( GetProcessHeap(), 0, filenameA );
+    HeapFree( GetProcessHeap(), 0, entryA );
     return res;
 }
 
@@ -785,24 +783,23 @@
 /***********************************************************************
  *           GetPrivateProfileString32W   (KERNEL32.256)
  */
-INT32 GetPrivateProfileString32W( LPCWSTR section,LPCWSTR entry,LPCWSTR def_val,
-                                  LPWSTR buffer,INT32 len,LPCWSTR filename )
+INT32 GetPrivateProfileString32W( LPCWSTR section, LPCWSTR entry,
+                                  LPCWSTR def_val, LPWSTR buffer,
+                                  INT32 len, LPCWSTR filename )
 {
-    LPSTR	sectionA = section?STRING32_DupUniToAnsi(section):NULL;
-    LPSTR	entryA = entry?STRING32_DupUniToAnsi(entry):NULL;
-    LPSTR	filenameA = filename?STRING32_DupUniToAnsi(filename):NULL;
-    LPSTR	def_valA = def_val?STRING32_DupUniToAnsi(def_val):NULL;
-    LPSTR	bufferA = xmalloc(len);
-    INT32	ret;
-
-    ret=GetPrivateProfileString32A(sectionA,entryA,def_valA,bufferA,len,filenameA);
-    if (sectionA) free(sectionA);
-    if (entryA) free(entryA);
-    if (filenameA) free(filenameA);
-    if (def_valA) free(def_valA);
-
+    LPSTR sectionA  = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
+    LPSTR entryA    = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
+    LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    LPSTR def_valA  = HEAP_strdupWtoA( GetProcessHeap(), 0, def_val );
+    LPSTR bufferA   = HeapAlloc( GetProcessHeap(), 0, len );
+    INT32 ret = GetPrivateProfileString32A( sectionA, entryA, def_valA,
+                                            bufferA, len, filenameA );
     lstrcpynAtoW( buffer, bufferA, len );
-    free(bufferA);
+    HeapFree( GetProcessHeap(), 0, sectionA );
+    HeapFree( GetProcessHeap(), 0, entryA );
+    HeapFree( GetProcessHeap(), 0, filenameA );
+    HeapFree( GetProcessHeap(), 0, def_valA );
+    HeapFree( GetProcessHeap(), 0, bufferA);
     return ret;
 }
 
@@ -831,21 +828,19 @@
 /***********************************************************************
  *           WritePrivateProfileString32W   (KERNEL32.583)
  */
-BOOL32 WritePrivateProfileString32W(LPCWSTR section,LPCWSTR entry,LPCWSTR string,
-                                    LPCWSTR filename )
+BOOL32 WritePrivateProfileString32W( LPCWSTR section, LPCWSTR entry,
+                                     LPCWSTR string, LPCWSTR filename )
 {
-    LPSTR sectionA = section?STRING32_DupUniToAnsi(section):NULL;
-    LPSTR entryA = entry?STRING32_DupUniToAnsi(entry):NULL;
-    LPSTR stringA = string?STRING32_DupUniToAnsi(string):NULL;
-    LPSTR filenameA = filename?STRING32_DupUniToAnsi(filename):NULL;
-    BOOL32 res;
-
-    res = WritePrivateProfileString32A(sectionA,entryA,stringA,filenameA);
-
-    if (sectionA) free(sectionA);
-    if (entryA) free(entryA);
-    if (stringA) free(stringA);
-    if (filenameA) free(filenameA);
+    LPSTR sectionA  = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
+    LPSTR entryA    = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
+    LPSTR stringA   = HEAP_strdupWtoA( GetProcessHeap(), 0, string );
+    LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    BOOL32 res = WritePrivateProfileString32A( sectionA, entryA,
+                                               stringA, filenameA );
+    HeapFree( GetProcessHeap(), 0, sectionA );
+    HeapFree( GetProcessHeap(), 0, entryA );
+    HeapFree( GetProcessHeap(), 0, stringA );
+    HeapFree( GetProcessHeap(), 0, filenameA );
     return res;
 }
 
diff --git a/graphics/Makefile.in b/graphics/Makefile.in
index 0db59ed..5339596 100644
--- a/graphics/Makefile.in
+++ b/graphics/Makefile.in
@@ -8,6 +8,7 @@
 C_SRCS = \
 	bitblt.c \
 	driver.c \
+	mapping.c \
 	wing.c
 
 all: $(MODULE).o
diff --git a/graphics/bitblt.c b/graphics/bitblt.c
index 2acda69..eda13f4 100644
--- a/graphics/bitblt.c
+++ b/graphics/bitblt.c
@@ -4,7 +4,7 @@
  * Copyright 1993, 1994  Alexandre Julliard
  */
 
-#include "gdi.h"
+#include "dc.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -15,7 +15,7 @@
 BOOL16 PatBlt16( HDC16 hdc, INT16 left, INT16 top,
                  INT16 width, INT16 height, DWORD rop)
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc || !dc->funcs->pPatBlt) return FALSE;
 
     dprintf_bitblt( stddeb, "PatBlt16: %04x %d,%d %dx%d %06lx\n",
@@ -30,7 +30,7 @@
 BOOL32 PatBlt32( HDC32 hdc, INT32 left, INT32 top,
                  INT32 width, INT32 height, DWORD rop)
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc || !dc->funcs->pPatBlt) return FALSE;
 
     dprintf_bitblt( stddeb, "PatBlt32: %04x %d,%d %dx%d %06lx\n",
@@ -47,9 +47,9 @@
 {
     DC *dcDst, *dcSrc;
 
-    if (!(dcDst = (DC *)GDI_GetObjPtr( hdcDst, DC_MAGIC ))) return FALSE;
+    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
     if (!dcDst->funcs->pBitBlt) return FALSE;
-    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    dcSrc = DC_GetDCPtr( hdcSrc );
 
     dprintf_bitblt(stddeb,
                 "BitBlt16: hdcSrc=%04x %d,%d %d bpp -> hdcDest=%04x %d,%d %dx%dx%d rop=%06lx\n",
@@ -68,9 +68,9 @@
 {
     DC *dcDst, *dcSrc;
 
-    if (!(dcDst = (DC *)GDI_GetObjPtr( hdcDst, DC_MAGIC ))) return FALSE;
+    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
     if (!dcDst->funcs->pBitBlt) return FALSE;
-    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    dcSrc = DC_GetDCPtr( hdcSrc );
 
     dprintf_bitblt(stddeb,
                 "BitBlt32: hdcSrc=%04x %d,%d %d bpp -> hdcDest=%04x %d,%d %dx%dx%d rop=%06lx\n",
@@ -91,9 +91,10 @@
 {
     DC *dcDst, *dcSrc;
 
-    if (!(dcDst = (DC *) GDI_GetObjPtr( hdcDst, DC_MAGIC ))) return FALSE;
+    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
     if (!dcDst->funcs->pStretchBlt) return FALSE;
-    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    dcSrc = DC_GetDCPtr( hdcSrc );
+
     dprintf_bitblt(stddeb,
         "StretchBlt16: %04x %d,%d %dx%dx%d -> %04x %d,%d %dx%dx%d rop=%06lx\n",
                    hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
@@ -115,9 +116,10 @@
 {
     DC *dcDst, *dcSrc;
 
-    if (!(dcDst = (DC *) GDI_GetObjPtr( hdcDst, DC_MAGIC ))) return FALSE;
+    if (!(dcDst = DC_GetDCPtr( hdcDst ))) return FALSE;
     if (!dcDst->funcs->pStretchBlt) return FALSE;
-    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    dcSrc = DC_GetDCPtr( hdcSrc );
+
     dprintf_bitblt(stddeb,
         "StretchBlt32: %04x %d,%d %dx%dx%d -> %04x %d,%d %dx%dx%d rop=%06lx\n",
                    hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
diff --git a/graphics/mapping.c b/graphics/mapping.c
new file mode 100644
index 0000000..e70c1e5
--- /dev/null
+++ b/graphics/mapping.c
@@ -0,0 +1,568 @@
+/*
+ * GDI mapping mode functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <math.h>
+#include "dc.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/***********************************************************************
+ *           MAPPING_FixIsotropic
+ *
+ * Fix viewport extensions for isotropic mode.
+ */
+void MAPPING_FixIsotropic( DC * dc )
+{
+    double xdim = (double)dc->vportExtX * dc->w.devCaps->horzSize /
+	          (dc->w.devCaps->horzRes * dc->wndExtX);
+    double ydim = (double)dc->vportExtY * dc->w.devCaps->vertSize /
+	          (dc->w.devCaps->vertRes * dc->wndExtY);
+    if (xdim > ydim)
+    {
+	dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
+	if (!dc->vportExtX) dc->vportExtX = 1;
+    }
+    else
+    {
+	dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
+	if (!dc->vportExtY) dc->vportExtY = 1;
+    }	
+}
+
+
+/***********************************************************************
+ *           DPtoLP16    (GDI.67)
+ */
+BOOL16 DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    while (count--)
+    {
+	points->x = XDPTOLP( dc, points->x );
+	points->y = YDPTOLP( dc, points->y );
+        points++;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           DPtoLP32    (GDI32.65)
+ */
+BOOL32 DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    while (count--)
+    {
+	points->x = XDPTOLP( dc, points->x );
+	points->y = YDPTOLP( dc, points->y );
+        points++;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LPtoDP16    (GDI.99)
+ */
+BOOL16 LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    while (count--)
+    {
+	points->x = XLPTODP( dc, points->x );
+	points->y = YLPTODP( dc, points->y );
+        points++;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LPtoDP32    (GDI32.247)
+ */
+BOOL32 LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    while (count--)
+    {
+	points->x = XLPTODP( dc, points->x );
+	points->y = YLPTODP( dc, points->y );
+        points++;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetMapMode16    (GDI.3)
+ */
+INT16 SetMapMode16( HDC16 hdc, INT16 mode )
+{
+    return SetMapMode32( hdc, mode );
+}
+
+
+/***********************************************************************
+ *           SetMapMode32    (GDI32.321)
+ */
+INT32 SetMapMode32( HDC32 hdc, INT32 mode )
+{
+    INT32 prevMode;
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return 0;
+    if (dc->funcs->pSetMapMode) return dc->funcs->pSetMapMode( dc, mode );
+
+    dprintf_gdi(stddeb, "SetMapMode: %04x %d\n", hdc, mode );
+    
+    prevMode = dc->w.MapMode;
+    switch(mode)
+    {
+      case MM_TEXT:
+	  dc->wndOrgX   = dc->wndOrgY   = 0;
+	  dc->vportOrgX = dc->vportOrgY = 0;
+	  dc->wndExtX   = 1;
+	  dc->wndExtY   = 1;
+	  dc->vportExtX = 1;
+	  dc->vportExtY = 1;
+	  break;
+	  
+      case MM_LOMETRIC:
+      case MM_ISOTROPIC:
+	  dc->wndOrgX   = dc->wndOrgY   = 0;
+	  dc->vportOrgX = dc->vportOrgY = 0;
+	  dc->wndExtX   = dc->w.devCaps->horzSize;
+	  dc->wndExtY   = dc->w.devCaps->vertSize;
+	  dc->vportExtX = dc->w.devCaps->horzRes / 10;
+	  dc->vportExtY = dc->w.devCaps->vertRes / -10;
+	  break;
+	  
+      case MM_HIMETRIC:
+	  dc->wndOrgX   = dc->wndOrgY   = 0;
+	  dc->vportOrgX = dc->vportOrgY = 0;
+	  dc->wndExtX   = dc->w.devCaps->horzSize * 10;
+	  dc->wndExtY   = dc->w.devCaps->vertSize * 10;
+	  dc->vportExtX = dc->w.devCaps->horzRes / 10;
+	  dc->vportExtY = dc->w.devCaps->vertRes / -10;
+	  break;
+	  
+      case MM_LOENGLISH:
+	  dc->wndOrgX   = dc->wndOrgY   = 0;
+	  dc->vportOrgX = dc->vportOrgY = 0;
+	  dc->wndExtX   = dc->w.devCaps->horzSize;
+	  dc->wndExtY   = dc->w.devCaps->vertSize;
+	  dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
+	  dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
+	  break;	  
+	  
+      case MM_HIENGLISH:
+	  dc->wndOrgX   = dc->wndOrgY   = 0;
+	  dc->vportOrgX = dc->vportOrgY = 0;
+	  dc->wndExtX   = dc->w.devCaps->horzSize * 10;
+	  dc->wndExtY   = dc->w.devCaps->vertSize * 10;
+	  dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
+	  dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
+	  break;
+	  
+      case MM_TWIPS:
+	  dc->wndOrgX   = dc->wndOrgY   = 0;
+	  dc->vportOrgX = dc->vportOrgY = 0;
+	  dc->wndExtX   = 144L * dc->w.devCaps->horzSize / 10;
+	  dc->wndExtY   = 144L * dc->w.devCaps->vertSize / 10;
+	  dc->vportExtX = 254L * dc->w.devCaps->horzRes / 1000;
+	  dc->vportExtY = -254L * dc->w.devCaps->vertRes / 1000;
+	  break;
+	  
+      case MM_ANISOTROPIC:
+	  break;
+
+      default:
+	  return prevMode;
+    }
+    dc->w.MapMode = mode;
+    return prevMode;
+}
+
+
+/***********************************************************************
+ *           SetViewportExt    (GDI.14)
+ */
+DWORD SetViewportExt( HDC16 hdc, INT16 x, INT16 y )
+{
+    SIZE32 size;
+    if (!SetViewportExtEx32( hdc, x, y, &size )) return 0;
+    return MAKELONG( size.cx, size.cy );
+}
+
+
+/***********************************************************************
+ *           SetViewportExtEx16    (GDI.479)
+ */
+BOOL16 SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
+{
+    SIZE32 size32;
+    BOOL16 ret = SetViewportExtEx32( hdc, x, y, &size32 );
+    if (size) CONV_SIZE32TO16( &size32, size );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetViewportExtEx32    (GDI32.340)
+ */
+BOOL32 SetViewportExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pSetViewportExt)
+        return dc->funcs->pSetViewportExt( dc, x, y );
+    if (size)
+    {
+	size->cx = dc->vportExtX;
+	size->cy = dc->vportExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!x || !y) return FALSE;
+    dc->vportExtX = x;
+    dc->vportExtY = y;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetViewportOrg    (GDI.13)
+ */
+DWORD SetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
+{
+    POINT32 pt;
+    if (!SetViewportOrgEx32( hdc, x, y, &pt )) return 0;
+    return MAKELONG( pt.x, pt.y );
+}
+
+
+/***********************************************************************
+ *           SetViewportOrgEx16    (GDI.480)
+ */
+BOOL16 SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
+{
+    POINT32 pt32;
+    BOOL16 ret = SetViewportOrgEx32( hdc, x, y, &pt32 );
+    if (pt) CONV_POINT32TO16( &pt32, pt );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetViewportOrgEx32    (GDI32.341)
+ */
+BOOL32 SetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pSetViewportOrg)
+        return dc->funcs->pSetViewportOrg( dc, x, y );
+    if (pt)
+    {
+	pt->x = dc->vportOrgX;
+	pt->y = dc->vportOrgY;
+    }
+    dc->vportOrgX = x;
+    dc->vportOrgY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetWindowExt    (GDI.12)
+ */
+DWORD SetWindowExt( HDC16 hdc, INT16 x, INT16 y )
+{
+    SIZE32 size;
+    if (!SetWindowExtEx32( hdc, x, y, &size )) return 0;
+    return MAKELONG( size.cx, size.cy );
+}
+
+
+/***********************************************************************
+ *           SetWindowExtEx16    (GDI.481)
+ */
+BOOL16 SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
+{
+    SIZE32 size32;
+    BOOL16 ret = SetWindowExtEx32( hdc, x, y, &size32 );
+    if (size) CONV_SIZE32TO16( &size32, size );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetWindowExtEx32    (GDI32.344)
+ */
+BOOL32 SetWindowExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pSetWindowExt) return dc->funcs->pSetWindowExt( dc, x, y );
+    if (size)
+    {
+	size->cx = dc->wndExtX;
+	size->cy = dc->wndExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!x || !y) return FALSE;
+    dc->wndExtX = x;
+    dc->wndExtY = y;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetWindowOrg    (GDI.11)
+ */
+DWORD SetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
+{
+    POINT32 pt;
+    if (!SetWindowOrgEx32( hdc, x, y, &pt )) return 0;
+    return MAKELONG( pt.x, pt.y );
+}
+
+
+/***********************************************************************
+ *           SetWindowOrgEx16    (GDI.482)
+ */
+BOOL16 SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
+{
+    POINT32 pt32;
+    BOOL16 ret = SetWindowOrgEx32( hdc, x, y, &pt32 );
+    if (pt) CONV_POINT32TO16( &pt32, pt );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetWindowOrgEx32    (GDI32.345)
+ */
+BOOL32 SetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pSetWindowOrg) return dc->funcs->pSetWindowOrg( dc, x, y );
+    if (pt)
+    {
+	pt->x = dc->wndOrgX;
+	pt->y = dc->wndOrgY;
+    }
+    dc->wndOrgX = x;
+    dc->wndOrgY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OffsetViewportOrg    (GDI.17)
+ */
+DWORD OffsetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
+{
+    POINT32 pt;
+    if (!OffsetViewportOrgEx32( hdc, x, y, &pt )) return 0;
+    return MAKELONG( pt.x, pt.y );
+}
+
+
+/***********************************************************************
+ *           OffsetViewportOrgEx16    (GDI.476)
+ */
+BOOL16 OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
+{
+    POINT32 pt32;
+    BOOL16 ret = OffsetViewportOrgEx32( hdc, x, y, &pt32 );
+    if (pt) CONV_POINT32TO16( &pt32, pt );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           OffsetViewportOrgEx32    (GDI32.257)
+ */
+BOOL32 OffsetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pOffsetViewportOrg)
+        return dc->funcs->pOffsetViewportOrg( dc, x, y );
+    if (pt)
+    {
+	pt->x = dc->vportOrgX;
+	pt->y = dc->vportOrgY;
+    }
+    dc->vportOrgX += x;
+    dc->vportOrgY += y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OffsetWindowOrg    (GDI.15)
+ */
+DWORD OffsetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
+{
+    POINT32 pt;
+    if (!OffsetWindowOrgEx32( hdc, x, y, &pt )) return 0;
+    return MAKELONG( pt.x, pt.y );
+}
+
+
+/***********************************************************************
+ *           OffsetWindowOrgEx16    (GDI.477)
+ */
+BOOL16 OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
+{
+    POINT32 pt32;
+    BOOL16 ret = OffsetWindowOrgEx32( hdc, x, y, &pt32 );
+    if (pt) CONV_POINT32TO16( &pt32, pt );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           OffsetWindowOrgEx32    (GDI32.258)
+ */
+BOOL32 OffsetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pOffsetWindowOrg)
+        return dc->funcs->pOffsetWindowOrg( dc, x, y );
+    if (pt)
+    {
+	pt->x = dc->wndOrgX;
+	pt->y = dc->wndOrgY;
+    }
+    dc->wndOrgX += x;
+    dc->wndOrgY += y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ScaleViewportExt    (GDI.18)
+ */
+DWORD ScaleViewportExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
+                        INT16 yNum, INT16 yDenom )
+{
+    SIZE32 size;
+    if (!ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
+        return FALSE;
+    return MAKELONG( size.cx,  size.cy );
+}
+
+
+/***********************************************************************
+ *           ScaleViewportExtEx16    (GDI.484)
+ */
+BOOL16 ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
+                             INT16 yNum, INT16 yDenom, LPSIZE16 size )
+{
+    SIZE32 size32;
+    BOOL16 ret = ScaleViewportExtEx32( hdc, xNum, xDenom, yNum, yDenom,
+                                       &size32 );
+    if (size) CONV_SIZE32TO16( &size32, size );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           ScaleViewportExtEx32    (GDI32.293)
+ */
+BOOL32 ScaleViewportExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
+                             INT32 yNum, INT32 yDenom, LPSIZE32 size )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pScaleViewportExt)
+        return dc->funcs->pScaleViewportExt( dc, xNum, xDenom, yNum, yDenom );
+    if (size)
+    {
+	size->cx = dc->vportExtX;
+	size->cy = dc->vportExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
+    dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
+    dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
+    if (dc->vportExtX == 0) dc->vportExtX = 1;
+    if (dc->vportExtY == 0) dc->vportExtY = 1;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ScaleWindowExt    (GDI.16)
+ */
+DWORD ScaleWindowExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
+		      INT16 yNum, INT16 yDenom )
+{
+    SIZE32 size;
+    if (!ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom, &size ))
+        return FALSE;
+    return MAKELONG( size.cx,  size.cy );
+}
+
+
+/***********************************************************************
+ *           ScaleWindowExtEx16    (GDI.485)
+ */
+BOOL16 ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
+                           INT16 yNum, INT16 yDenom, LPSIZE16 size )
+{
+    SIZE32 size32;
+    BOOL16 ret = ScaleWindowExtEx32( hdc, xNum, xDenom, yNum, yDenom,
+                                     &size32 );
+    if (size) CONV_SIZE32TO16( &size32, size );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           ScaleWindowExtEx32    (GDI32.294)
+ */
+BOOL32 ScaleWindowExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
+                           INT32 yNum, INT32 yDenom, LPSIZE32 size )
+{
+    DC * dc = DC_GetDCPtr( hdc );
+    if (!dc) return FALSE;
+    if (dc->funcs->pScaleWindowExt)
+        return dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom );
+    if (size)
+    {
+	size->cx = dc->wndExtX;
+	size->cy = dc->wndExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
+    dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
+    dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
+    if (dc->wndExtX == 0) dc->wndExtX = 1;
+    if (dc->wndExtY == 0) dc->wndExtY = 1;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
diff --git a/graphics/metafiledrv/Makefile.in b/graphics/metafiledrv/Makefile.in
index 02de44e..1b0a161 100644
--- a/graphics/metafiledrv/Makefile.in
+++ b/graphics/metafiledrv/Makefile.in
@@ -7,7 +7,8 @@
 
 C_SRCS = \
 	bitblt.c \
-	init.c
+	init.c \
+	mapping.c
 
 all: $(MODULE).o
 
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index e8ad11d..f1d3454 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -39,8 +39,8 @@
     NULL,                            /* pLineTo */
     NULL,                            /* pMoveToEx */
     NULL,                            /* pOffsetClipRgn */
-    NULL,                            /* pOffsetViewportOrgEx */
-    NULL,                            /* pOffsetWindowOrgEx */
+    MFDRV_OffsetViewportOrg,         /* pOffsetViewportOrg */
+    MFDRV_OffsetWindowOrg,           /* pOffsetWindowOrg */
     NULL,                            /* pPaintRgn */
     MFDRV_PatBlt,                    /* pPatBlt */
     NULL,                            /* pPie */
@@ -52,8 +52,8 @@
     NULL,                            /* pRestoreDC */
     NULL,                            /* pRoundRect */
     NULL,                            /* pSaveDC */
-    NULL,                            /* pScaleViewportExtEx */
-    NULL,                            /* pScaleWindowExtEx */
+    MFDRV_ScaleViewportExt,          /* pScaleViewportExt */
+    MFDRV_ScaleWindowExt,            /* pScaleWindowExt */
     NULL,                            /* pSelectClipRgn */
     NULL,                            /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -61,7 +61,7 @@
     NULL,                            /* pSetBkMode */
     NULL,                            /* pSetDeviceClipping */
     NULL,                            /* pSetDIBitsToDevice */
-    NULL,                            /* pSetMapMode */
+    MFDRV_SetMapMode,                /* pSetMapMode */
     NULL,                            /* pSetMapperFlags */
     NULL,                            /* pSetPixel */
     NULL,                            /* pSetPolyFillMode */
@@ -72,10 +72,10 @@
     NULL,                            /* pSetTextCharacterExtra */
     NULL,                            /* pSetTextColor */
     NULL,                            /* pSetTextJustification */
-    NULL,                            /* pSetViewportExtEx */
-    NULL,                            /* pSetViewportOrgEx */
-    NULL,                            /* pSetWindowExtEx */
-    NULL,                            /* pSetWindowOrgEx */
+    MFDRV_SetViewportExt,            /* pSetViewportExt */
+    MFDRV_SetViewportOrg,            /* pSetViewportOrg */
+    MFDRV_SetWindowExt,              /* pSetWindowExt */
+    MFDRV_SetWindowOrg,              /* pSetWindowOrg */
     MFDRV_StretchBlt,                /* pStretchBlt */
     NULL,                            /* pStretchDIBits */
     NULL                             /* pTextOut */
@@ -156,13 +156,13 @@
         physDev->mh->mtType = METAFILE_DISK;
         if ((hFile = _lcreat( filename, 0 )) == HFILE_ERROR)
         {
-            DeleteDC( dc->hSelf );
+            DeleteDC32( dc->hSelf );
             return 0;
         }
         if (_lwrite32( hFile, (LPSTR)physDev->mh,
                        sizeof(*physDev->mh)) == HFILE_ERROR)
 	{
-            DeleteDC( dc->hSelf );
+            DeleteDC32( dc->hSelf );
             return 0;
 	}
 	physDev->mh->mtNoParameters = hFile; /* store file descriptor here */
@@ -197,7 +197,7 @@
 
     if (!MF_MetaParam0(dc, META_EOF))
     {
-        DeleteDC( hdc );
+        DeleteDC32( hdc );
 	return 0;
     }	
 
@@ -207,13 +207,13 @@
 	physDev->mh->mtNoParameters = 0;
         if (_llseek(hFile, 0L, 0) == HFILE_ERROR)
         {
-            DeleteDC( hdc );
+            DeleteDC32( hdc );
             return 0;
         }
         if (_lwrite32( hFile, (LPSTR)physDev->mh,
                        sizeof(*physDev->mh)) == HFILE_ERROR)
         {
-            DeleteDC( hdc );
+            DeleteDC32( hdc );
             return 0;
         }
         _lclose(hFile);
@@ -225,7 +225,7 @@
                               physDev->mh->mtSize * sizeof(WORD),
                               GetCurrentPDB(), FALSE, FALSE, FALSE, NULL );
     physDev->mh = NULL;  /* So it won't be deleted */
-    DeleteDC( hdc );
+    DeleteDC32( hdc );
     return hmf;
 }
 
diff --git a/graphics/metafiledrv/mapping.c b/graphics/metafiledrv/mapping.c
new file mode 100644
index 0000000..4e396d1
--- /dev/null
+++ b/graphics/metafiledrv/mapping.c
@@ -0,0 +1,102 @@
+/*
+ * Metafile GDI mapping mode functions
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#include "gdi.h"
+#include "metafile.h"
+#include "metafiledrv.h"
+
+
+/***********************************************************************
+ *           MFDRV_SetMapMode
+ */
+INT32 MFDRV_SetMapMode( DC *dc, INT32 mode )
+{
+    INT32 prevMode = dc->w.MapMode;
+    MF_MetaParam1( dc, META_SETMAPMODE, mode );
+    return prevMode;
+}
+
+
+/***********************************************************************
+ *           MFDRV_SetViewportExt
+ */
+BOOL32 MFDRV_SetViewportExt( DC *dc, INT32 x, INT32 y )
+{
+    MF_MetaParam2( dc, META_SETVIEWPORTEXT, x, y );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_SetViewportOrg
+ */
+BOOL32 MFDRV_SetViewportOrg( DC *dc, INT32 x, INT32 y )
+{
+    MF_MetaParam2( dc, META_SETVIEWPORTORG, x, y );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_SetWindowExt
+ */
+BOOL32 MFDRV_SetWindowExt( DC *dc, INT32 x, INT32 y )
+{
+    MF_MetaParam2( dc, META_SETWINDOWEXT, x, y );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_SetWindowOrg
+ */
+BOOL32 MFDRV_SetWindowOrg( DC *dc, INT32 x, INT32 y )
+{
+    MF_MetaParam2( dc, META_SETWINDOWORG, x, y );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_OffsetViewportOrg
+ */
+BOOL32 MFDRV_OffsetViewportOrg( DC *dc, INT32 x, INT32 y )
+{
+    MF_MetaParam2( dc, META_OFFSETVIEWPORTORG, x, y );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_OffsetWindowOrg
+ */
+BOOL32 MFDRV_OffsetWindowOrg( DC *dc, INT32 x, INT32 y )
+{
+    MF_MetaParam2( dc, META_OFFSETWINDOWORG, x, y );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_ScaleViewportExt
+ */
+BOOL32 MFDRV_ScaleViewportExt( DC *dc, INT32 xNum, INT32 xDenom,
+                               INT32 yNum, INT32 yDenom )
+{
+    MF_MetaParam4( dc, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MFDRV_ScaleWindowExt
+ */
+BOOL32 MFDRV_ScaleWindowExt( DC *dc, INT32 xNum, INT32 xDenom,
+                             INT32 yNum, INT32 yDenom )
+{
+    MF_MetaParam4( dc, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom );
+    return TRUE;
+}
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 10ab2b6..8d05cda 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -61,8 +61,8 @@
     NULL,                            /* pLineTo */
     NULL,                            /* pMoveToEx */
     NULL,                            /* pOffsetClipRgn */
-    NULL,                            /* pOffsetViewportOrgEx */
-    NULL,                            /* pOffsetWindowOrgEx */
+    NULL,                            /* pOffsetViewportOrg (optional) */
+    NULL,                            /* pOffsetWindowOrg (optional) */
     NULL,                            /* pPaintRgn */
     NULL,                            /* pPatBlt */
     NULL,                            /* pPie */
@@ -74,8 +74,8 @@
     NULL,                            /* pRestoreDC */
     NULL,                            /* pRoundRect */
     NULL,                            /* pSaveDC */
-    NULL,                            /* pScaleViewportExtEx */
-    NULL,                            /* pScaleWindowExtEx */
+    NULL,                            /* pScaleViewportExt (optional) */
+    NULL,                            /* pScaleWindowExt (optional) */
     NULL,                            /* pSelectClipRgn */
     NULL,                            /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -83,7 +83,7 @@
     NULL,                            /* pSetBkMode */
     NULL,                            /* pSetDeviceClipping */
     NULL,                            /* pSetDIBitsToDevice */
-    NULL,                            /* pSetMapMode */
+    NULL,                            /* pSetMapMode (optional) */
     NULL,                            /* pSetMapperFlags */
     NULL,                            /* pSetPixel */
     NULL,                            /* pSetPolyFillMode */
@@ -94,10 +94,10 @@
     NULL,                            /* pSetTextCharacterExtra */
     NULL,                            /* pSetTextColor */
     NULL,                            /* pSetTextJustification */
-    NULL,                            /* pSetViewportExtEx */
-    NULL,                            /* pSetViewportOrgEx */
-    NULL,                            /* pSetWindowExtEx */
-    NULL,                            /* pSetWindowOrgEx */
+    NULL,                            /* pSetViewportExt (optional) */
+    NULL,                            /* pSetViewportOrg (optional) */
+    NULL,                            /* pSetWindowExt (optional) */
+    NULL,                            /* pSetWindowOrg (optional) */
     NULL,                            /* pStretchBlt */
     NULL,                            /* pStretchDIBits */
     NULL                             /* pTextOut */
diff --git a/graphics/wing.c b/graphics/wing.c
index 697b5b9..0ed174f 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -67,7 +67,7 @@
   __initWinG();
 
   if( __WinGOK > 0 )
-	return CreateCompatibleDC(NULL);
+	return CreateCompatibleDC16(NULL);
   return (HDC16)NULL;
 }
 
@@ -278,8 +278,8 @@
     ySrc    = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
     xDest   = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
     yDest   = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
-    widDest = widDest * dcDst->w.VportExtX / dcDst->w.WndExtX;
-    heiDest = heiDest * dcDst->w.VportExtY / dcDst->w.WndExtY;
+    widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
+    heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
 
     XSetFunction( display, dcDst->u.x.gc, GXcopy );
     XCopyArea( display, dcSrc->u.x.drawable,
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index 2b0fe3e..c4b4f8c 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -1114,14 +1114,14 @@
 
     xDst      = dcDst->w.DCOrgX + XLPTODP( dcDst, xDst );
     yDst      = dcDst->w.DCOrgY + YLPTODP( dcDst, yDst );
-    widthDst  = widthDst * dcDst->w.VportExtX / dcDst->w.WndExtX;
-    heightDst = heightDst * dcDst->w.VportExtY / dcDst->w.WndExtY;
+    widthDst  = widthDst * dcDst->vportExtX / dcDst->wndExtX;
+    heightDst = heightDst * dcDst->vportExtY / dcDst->wndExtY;
 
     dprintf_bitblt( stddeb, "    vportdst=%d,%d-%d,%d wnddst=%d,%d-%d,%d\n",
-                   dcDst->w.VportOrgX, dcDst->w.VportOrgY,
-                   dcDst->w.VportExtX, dcDst->w.VportExtY,
-                   dcDst->w.WndOrgX, dcDst->w.WndOrgY,
-                   dcDst->w.WndExtX, dcDst->w.WndExtY );
+                    dcDst->vportOrgX, dcDst->vportOrgY,
+                    dcDst->vportExtX, dcDst->vportExtY,
+                    dcDst->wndOrgX, dcDst->wndOrgY,
+                    dcDst->wndExtX, dcDst->wndExtY );
     dprintf_bitblt( stddeb, "    rectdst=%d,%d-%d,%d orgdst=%d,%d\n",
                     xDst, yDst, widthDst, heightDst,
                     dcDst->w.DCOrgX, dcDst->w.DCOrgY );
@@ -1130,14 +1130,14 @@
     {
         xSrc      = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
         ySrc      = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
-        widthSrc  = widthSrc * dcSrc->w.VportExtX / dcSrc->w.WndExtX;
-        heightSrc = heightSrc * dcSrc->w.VportExtY / dcSrc->w.WndExtY;
+        widthSrc  = widthSrc * dcSrc->vportExtX / dcSrc->wndExtX;
+        heightSrc = heightSrc * dcSrc->vportExtY / dcSrc->wndExtY;
         fStretch  = (widthSrc != widthDst) || (heightSrc != heightDst);
         dprintf_bitblt( stddeb,"    vportsrc=%d,%d-%d,%d wndsrc=%d,%d-%d,%d\n",
-                        dcSrc->w.VportOrgX, dcSrc->w.VportOrgY,
-                        dcSrc->w.VportExtX, dcSrc->w.VportExtY,
-                        dcSrc->w.WndOrgX, dcSrc->w.WndOrgY,
-                        dcSrc->w.WndExtX, dcSrc->w.WndExtY );
+                        dcSrc->vportOrgX, dcSrc->vportOrgY,
+                        dcSrc->vportExtX, dcSrc->vportExtY,
+                        dcSrc->wndOrgX, dcSrc->wndOrgY,
+                        dcSrc->wndExtX, dcSrc->wndExtY );
         dprintf_bitblt( stddeb, "    rectsrc=%d,%d-%d,%d orgsrc=%d,%d\n",
                         xSrc, ySrc, widthSrc, heightSrc,
                         dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
diff --git a/graphics/x11drv/font.c b/graphics/x11drv/font.c
index 532d68c..6faebae 100644
--- a/graphics/x11drv/font.c
+++ b/graphics/x11drv/font.c
@@ -20,8 +20,8 @@
     XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
 		  &ascent, &descent, &info );
     size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
-		    * dc->w.WndExtX / dc->w.VportExtX);
+		    * dc->wndExtX / dc->vportExtX);
     size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
-		    * dc->w.WndExtY / dc->w.VportExtY);
+		    * dc->wndExtY / dc->vportExtY);
     return TRUE;
 }
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index e56b3d9..5ceb736 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -39,8 +39,8 @@
     NULL,                            /* pLineTo */
     NULL,                            /* pMoveToEx */
     NULL,                            /* pOffsetClipRgn */
-    NULL,                            /* pOffsetViewportOrgEx */
-    NULL,                            /* pOffsetWindowOrgEx */
+    NULL,                            /* pOffsetViewportOrg (optional) */
+    NULL,                            /* pOffsetWindowOrg (optional) */
     NULL,                            /* pPaintRgn */
     X11DRV_PatBlt,                   /* pPatBlt */
     NULL,                            /* pPie */
@@ -52,8 +52,8 @@
     NULL,                            /* pRestoreDC */
     NULL,                            /* pRoundRect */
     NULL,                            /* pSaveDC */
-    NULL,                            /* pScaleViewportExtEx */
-    NULL,                            /* pScaleWindowExtEx */
+    NULL,                            /* pScaleViewportExt (optional) */
+    NULL,                            /* pScaleWindowExt (optional) */
     NULL,                            /* pSelectClipRgn */
     NULL,                            /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -61,7 +61,7 @@
     NULL,                            /* pSetBkMode */
     X11DRV_SetDeviceClipping,        /* pSetDeviceClipping */
     NULL,                            /* pSetDIBitsToDevice */
-    NULL,                            /* pSetMapMode */
+    NULL,                            /* pSetMapMode (optional) */
     NULL,                            /* pSetMapperFlags */
     NULL,                            /* pSetPixel */
     NULL,                            /* pSetPolyFillMode */
@@ -72,10 +72,10 @@
     NULL,                            /* pSetTextCharacterExtra */
     NULL,                            /* pSetTextColor */
     NULL,                            /* pSetTextJustification */
-    NULL,                            /* pSetViewportExtEx */
-    NULL,                            /* pSetViewportOrgEx */
-    NULL,                            /* pSetWindowExtEx */
-    NULL,                            /* pSetWindowOrgEx */
+    NULL,                            /* pSetViewportExt (optional) */
+    NULL,                            /* pSetViewportOrg (optional) */
+    NULL,                            /* pSetWindowExt (optional) */
+    NULL,                            /* pSetWindowOrg (optional) */
     X11DRV_StretchBlt,               /* pStretchBlt */
     NULL,                            /* pStretchDIBits */
     NULL                             /* pTextOut */
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 9e97789..4d2846b 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -3,15 +3,15 @@
 heap	65488  # 65536 - 16 (instance data) - 32 (stock objects)
 
 1   pascal SetBkColor(word long) SetBkColor
-2   pascal16 SetBkMode(word word) SetBkMode
-3   pascal16 SetMapMode(word word) SetMapMode
-4   pascal16 SetROP2(word word) SetROP2
-5   pascal16 SetRelAbs(word word) SetRelAbs
-6   pascal16 SetPolyFillMode(word word) SetPolyFillMode
-7   pascal16 SetStretchBltMode(word word) SetStretchBltMode
-8   pascal16 SetTextCharacterExtra(word s_word) SetTextCharacterExtra
+2   pascal16 SetBkMode(word word) SetBkMode16
+3   pascal16 SetMapMode(word word) SetMapMode16
+4   pascal16 SetROP2(word word) SetROP216
+5   pascal16 SetRelAbs(word word) SetRelAbs16
+6   pascal16 SetPolyFillMode(word word) SetPolyFillMode16
+7   pascal16 SetStretchBltMode(word word) SetStretchBltMode16
+8   pascal16 SetTextCharacterExtra(word s_word) SetTextCharacterExtra16
 9   pascal SetTextColor(word long) SetTextColor
-10  pascal16 SetTextJustification(word s_word s_word) SetTextJustification
+10  pascal16 SetTextJustification(word s_word s_word) SetTextJustification16
 11  pascal SetWindowOrg(word s_word s_word) SetWindowOrg
 12  pascal SetWindowExt(word s_word s_word) SetWindowExt
 13  pascal SetViewportOrg(word s_word s_word) SetViewportOrg
@@ -34,7 +34,7 @@
 28  pascal16 RoundRect(word s_word s_word s_word s_word s_word s_word)
              RoundRect16
 29  pascal16 PatBlt(word s_word s_word s_word s_word long) PatBlt16
-30  pascal16 SaveDC(word) SaveDC
+30  pascal16 SaveDC(word) SaveDC16
 31  pascal   SetPixel(word s_word s_word long) SetPixel16
 32  pascal16 OffsetClipRgn(word s_word s_word) OffsetClipRgn16
 33  pascal16 TextOut(word s_word s_word ptr word) TextOut16
@@ -45,7 +45,7 @@
 36  pascal16 Polygon (word ptr word) Polygon16
 37  pascal16 Polyline (word ptr word) Polyline16
 38  pascal Escape(word word word segptr segptr) Escape
-39  pascal16 RestoreDC(word s_word) RestoreDC
+39  pascal16 RestoreDC(word s_word) RestoreDC16
 40  pascal16 FillRgn(word word word) FillRgn16
 41  pascal16 FrameRgn(word word word word word) FrameRgn16
 42  pascal16 InvertRgn(word word) InvertRgn16
@@ -58,7 +58,7 @@
 49  pascal16 CreateBitmapIndirect(ptr) CreateBitmapIndirect16
 50  pascal16 CreateBrushIndirect(ptr) CreateBrushIndirect16
 51  pascal16 CreateCompatibleBitmap(word word word) CreateCompatibleBitmap
-52  pascal16 CreateCompatibleDC(word) CreateCompatibleDC
+52  pascal16 CreateCompatibleDC(word) CreateCompatibleDC16
 53  pascal16 CreateDC(ptr ptr ptr ptr) CreateDC16
 54  pascal16 CreateEllipticRgn(s_word s_word s_word s_word) CreateEllipticRgn16
 55  pascal16 CreateEllipticRgnIndirect(ptr) CreateEllipticRgnIndirect16
@@ -74,36 +74,36 @@
 65  pascal16 CreateRectRgnIndirect(ptr) CreateRectRgnIndirect16
 66  pascal16 CreateSolidBrush(long) CreateSolidBrush16
 67  pascal16 DPtoLP(word ptr s_word) DPtoLP16
-68  pascal16 DeleteDC(word) DeleteDC
+68  pascal16 DeleteDC(word) DeleteDC16
 69  pascal16 DeleteObject(word) DeleteObject16
 70  pascal16 EnumFonts(word ptr segptr long) THUNK_EnumFonts16
 71  pascal16 EnumObjects(word word segptr long) THUNK_EnumObjects16
 72  pascal16 EqualRgn(word word) EqualRgn16
 73  pascal16 ExcludeVisRect(word s_word s_word s_word s_word) ExcludeVisRect
 74  pascal GetBitmapBits(word long ptr) GetBitmapBits
-75  pascal GetBkColor(word) GetBkColor
-76  pascal16 GetBkMode(word) GetBkMode
+75  pascal   GetBkColor(word) GetBkColor16
+76  pascal16 GetBkMode(word) GetBkMode16
 77  pascal16 GetClipBox(word ptr) GetClipBox16
-78  pascal GetCurrentPosition(word) GetCurrentPosition
-79  pascal GetDCOrg(word) GetDCOrg
+78  pascal   GetCurrentPosition(word) GetCurrentPosition
+79  pascal   GetDCOrg(word) GetDCOrg
 80  pascal16 GetDeviceCaps(word s_word) GetDeviceCaps
-81  pascal16 GetMapMode(word) GetMapMode
+81  pascal16 GetMapMode(word) GetMapMode16
 82  pascal16 GetObject(word s_word ptr) GetObject16
 83  pascal   GetPixel(word s_word s_word) GetPixel16
-84  pascal16 GetPolyFillMode(word) GetPolyFillMode
-85  pascal16 GetROP2(word) GetROP2
-86  pascal16 GetRelAbs(word) GetRelAbs
+84  pascal16 GetPolyFillMode(word) GetPolyFillMode16
+85  pascal16 GetROP2(word) GetROP216
+86  pascal16 GetRelAbs(word) GetRelAbs16
 87  pascal16 GetStockObject(word) GetStockObject16
-88  pascal16 GetStretchBltMode(word) GetStretchBltMode
-89  pascal16 GetTextCharacterExtra(word) GetTextCharacterExtra
-90  pascal GetTextColor(word) GetTextColor
-91  pascal GetTextExtent(word ptr s_word) GetTextExtent
+88  pascal16 GetStretchBltMode(word) GetStretchBltMode16
+89  pascal16 GetTextCharacterExtra(word) GetTextCharacterExtra16
+90  pascal   GetTextColor(word) GetTextColor16
+91  pascal   GetTextExtent(word ptr s_word) GetTextExtent
 92  pascal16 GetTextFace(word s_word ptr) GetTextFace16
 93  pascal16 GetTextMetrics(word ptr) GetTextMetrics16
-94  pascal GetViewportExt(word) GetViewportExt
-95  pascal GetViewportOrg(word) GetViewportOrg
-96  pascal GetWindowExt(word) GetWindowExt
-97  pascal GetWindowOrg(word) GetWindowOrg
+94  pascal   GetViewportExt(word) GetViewportExt
+95  pascal   GetViewportOrg(word) GetViewportOrg
+96  pascal   GetWindowExt(word) GetWindowExt
+97  pascal   GetWindowOrg(word) GetWindowOrg
 98  pascal16 IntersectVisRect(word s_word s_word s_word s_word)
              IntersectVisRect
 99  pascal16 LPtoDP(word ptr s_word) LPtoDP16
@@ -136,7 +136,7 @@
 149 pascal GetBrushOrg(word) GetBrushOrg
 150 pascal16 UnrealizeObject(word) UnrealizeObject16
 151 pascal16 CopyMetaFile(word ptr) CopyMetaFile
-153 pascal16 CreateIC(ptr ptr ptr ptr) CreateIC
+153 pascal16 CreateIC(ptr ptr ptr ptr) CreateIC16
 154 pascal GetNearestColor(word long) GetNearestColor
 155 stub QueryAbort
 156 pascal16 CreateDiscardableBitmap(word word word) CreateDiscardableBitmap
@@ -216,7 +216,7 @@
 304 stub ENGINESETFONTCONTEXT
 305 stub ENGINEGETGLYPHBMP
 306 stub ENGINEMAKEFONTDIR
-307 pascal16 GetCharABCWidths(word word word ptr) GetCharABCWidths
+307 pascal16 GetCharABCWidths(word word word ptr) GetCharABCWidths16
 308 stub GetOutLineTextMetrics
 309 pascal   GetGlyphOutLine(word word word ptr long ptr ptr) GetGlyphOutLine
 310 pascal16 CreateScalableFontResource(word ptr ptr ptr) CreateScalableFontResource
@@ -229,12 +229,12 @@
 317 stub EngineGetGlyphBmpExt
 330 pascal16 EnumFontFamilies(word ptr segptr long) THUNK_EnumFontFamilies16
 332 pascal16 GetKerningPairs(word word ptr) GetKerningPairs
-345 pascal16 GetTextAlign(word) GetTextAlign
-346 pascal16 SetTextAlign(word word) SetTextAlign
+345 pascal16 GetTextAlign(word) GetTextAlign16
+346 pascal16 SetTextAlign(word word) SetTextAlign16
 348 pascal16 Chord(word s_word s_word s_word s_word s_word s_word
                    s_word s_word) Chord16
 349 pascal SetMapperFlags(word long) SetMapperFlags
-350 pascal16 GetCharWidth(word word word ptr) GetCharWidth
+350 pascal16 GetCharWidth(word word word ptr) GetCharWidth16
 351 pascal16 ExtTextOut(word s_word s_word word ptr ptr word ptr) ExtTextOut16
 352 stub GetPhysicalFontHandle
 353 stub GetAspectRatioFilter
@@ -255,7 +255,7 @@
 374 pascal16 GetSystemPaletteUse(word) GetSystemPaletteUse
 375 pascal16 GetSystemPaletteEntries(word word word ptr)
              GetSystemPaletteEntries
-376 pascal16 ResetDC(word ptr) ResetDC
+376 pascal16 ResetDC(word ptr) ResetDC16
 377 stub STARTDOC
 378 stub ENDDOC
 379 stub STARTPAGE
@@ -274,11 +274,11 @@
 412 pascal16 IsDCCurrentPalette(word) IsDCCurrentPalette
 439 pascal16 StretchDIBits (word s_word s_word s_word s_word s_word s_word
                             s_word s_word ptr ptr word long) StretchDIBits16
-440 pascal16 SetDIBits(word word word word ptr ptr word) SetDIBits
-441 pascal16 GetDIBits(word word word word ptr ptr word) GetDIBits
-442 pascal16 CreateDIBitmap(word ptr long ptr ptr word) CreateDIBitmap
-443 pascal16 SetDIBitsToDevice(word s_word s_word word word word word
-                               word word ptr ptr word) SetDIBitsToDevice
+440 pascal16 SetDIBits(word word word word ptr ptr word) SetDIBits16
+441 pascal16 GetDIBits(word word word word ptr ptr word) GetDIBits16
+442 pascal16 CreateDIBitmap(word ptr long ptr ptr word) CreateDIBitmap16
+443 pascal16 SetDIBitsToDevice(word s_word s_word s_word s_word s_word s_word
+                               word word ptr ptr word) SetDIBitsToDevice16
 444 pascal16 CreateRoundRectRgn(s_word s_word s_word s_word s_word s_word)
              CreateRoundRectRgn16
 445 pascal16 CreateDIBPatternBrush(word word) CreateDIBPatternBrush16
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 7e41277..08f90e6 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -33,13 +33,13 @@
 0028 stub CreateColorSpaceA
 0029 stub CreateColorSpaceW
 0030 stdcall CreateCompatibleBitmap(long long long) CreateCompatibleBitmap
-0031 stdcall CreateCompatibleDC(long) CreateCompatibleDC
+0031 stdcall CreateCompatibleDC(long) CreateCompatibleDC32
 0032 stdcall CreateDCA(ptr ptr ptr ptr) CreateDC32A
 0033 stdcall CreateDCW(ptr ptr ptr ptr) CreateDC32W
 0034 stdcall CreateDIBPatternBrush(long long) CreateDIBPatternBrush32
 0035 stub CreateDIBPatternBrushPt
 0036 stub CreateDIBSection
-0037 stdcall CreateDIBitmap(long ptr long ptr ptr long) CreateDIBitmap
+0037 stdcall CreateDIBitmap(long ptr long ptr ptr long) CreateDIBitmap32
 0038 stdcall CreateDiscardableBitmap(long long long) CreateDiscardableBitmap
 0039 stdcall CreateEllipticRgn(long long long long) CreateEllipticRgn32
 0040 stdcall CreateEllipticRgnIndirect(ptr) CreateEllipticRgnIndirect32
@@ -53,8 +53,8 @@
                         long long long long long ptr) CreateFont32W
 0047 stub CreateHalftonePalette
 0048 stdcall CreateHatchBrush(long long) CreateHatchBrush32
-0049 stdcall CreateICA(ptr ptr ptr ptr) CreateIC
-0050 stub CreateICW
+0049 stdcall CreateICA(ptr ptr ptr ptr) CreateIC32A
+0050 stdcall CreateICW(ptr ptr ptr ptr) CreateIC32W
 0051 stub CreateMetaFileA
 0052 stub CreateMetaFileW
 0053 stdcall CreatePalette(ptr) CreatePalette
@@ -72,7 +72,7 @@
 0064 stdcall CreateSolidBrush(long) CreateSolidBrush32
 0065 stdcall DPtoLP(long ptr long) DPtoLP32
 0066 stub DeleteColorSpace
-0067 stdcall DeleteDC(long) DeleteDC
+0067 stdcall DeleteDC(long) DeleteDC32
 0068 stub DeleteEnhMetaFile
 0069 stub DeleteMetaFile
 0070 stdcall DeleteObject(long)	DeleteObject32
@@ -150,20 +150,20 @@
 0142 stub GetAspectRatioFilterEx
 0143 stdcall GetBitmapBits(long long ptr) GetBitmapBits
 0144 stdcall GetBitmapDimensionEx(long ptr) GetBitmapDimensionEx32
-0145 stdcall GetBkColor(long) GetBkColor
-0146 stub GetBkMode
+0145 stdcall GetBkColor(long) GetBkColor32
+0146 stdcall GetBkMode(long) GetBkMode32
 0147 stub GetBoundsRect
 0148 stdcall GetBrushOrgEx(long ptr) GetBrushOrgEx32
-0149 stub GetCharABCWidthsA
+0149 stdcall GetCharABCWidthsA(long long long ptr) GetCharABCWidths32A
 0150 stub GetCharABCWidthsFloatA
 0151 stub GetCharABCWidthsFloatW
-0152 stub GetCharABCWidthsW
-0153 stdcall GetCharWidth32A(long long long long) GetCharWidth
-0154 stub GetCharWidth32W
-0155 stdcall GetCharWidthA(long long long long) GetCharWidth
+0152 stdcall GetCharABCWidthsW(long long long ptr) GetCharABCWidths32W
+0153 stdcall GetCharWidth32A(long long long long) GetCharWidth32A
+0154 stdcall GetCharWidth32W(long long long long) GetCharWidth32W
+0155 stdcall GetCharWidthA(long long long long) GetCharWidth32A
 0156 stub GetCharWidthFloatA
 0157 stub GetCharWidthFloatW
-0158 stub GetCharWidthW
+0158 stdcall GetCharWidthW(long long long long) GetCharWidth32W
 0159 stub GetCharWidthWOW
 0160 stub GetCharacterPlacementA
 0161 stub GetCharacterPlacementW
@@ -175,7 +175,7 @@
 0167 stdcall GetCurrentPositionEx(long ptr) GetCurrentPositionEx32
 0168 stdcall GetDCOrgEx(long ptr) GetDCOrgEx
 0169 stub GetDIBColorTable
-0170 stub GetDIBits
+0170 stdcall GetDIBits(long long long long ptr ptr long) GetDIBits32
 0171 stdcall GetDeviceCaps(long long) GetDeviceCaps
 0172 stub GetDeviceGammaRamp
 0173 stub GetETM
@@ -201,7 +201,7 @@
 0193 stub GetKerningPairsW
 0194 stub GetLogColorSpaceA
 0195 stub GetLogColorSpaceW
-0196 stub GetMapMode
+0196 stdcall GetMapMode(long) GetMapMode32
 0197 stub GetMetaFileA
 0198 stub GetMetaFileBitsEx
 0199 stub GetMetaFileW
@@ -218,21 +218,21 @@
 0210 stub GetPath
 0211 stdcall GetPixel(long long long) GetPixel32
 0212 stub GetPixelFormat
-0213 stub GetPolyFillMode
-0214 stub GetROP2
+0213 stdcall GetPolyFillMode(long) GetPolyFillMode32
+0214 stdcall GetROP2(long) GetROP232
 0215 stub GetRandomRgn
 0216 stub GetRasterizerCaps
 0217 stub GetRegionData
-0218 stub GetRelAbs
+0218 stdcall GetRelAbs(long) GetRelAbs32
 0219 stdcall GetRgnBox(long ptr) GetRgnBox32
 0220 stdcall GetStockObject(long) GetStockObject32
-0221 stub GetStretchBltMode
+0221 stdcall GetStretchBltMode(long) GetStretchBltMode32
 0222 stdcall GetSystemPaletteEntries(long long long ptr) GetSystemPaletteEntries
 0223 stub GetSystemPaletteUse
-0224 stub GetTextAlign
-0225 stub GetTextCharacterExtra
+0224 stdcall GetTextAlign(long) GetTextAlign32
+0225 stdcall GetTextCharacterExtra(long) GetTextCharacterExtra32
 0226 stub GetTextCharset
-0227 stdcall GetTextColor(long) GetTextColor
+0227 stdcall GetTextColor(long) GetTextColor32
 0228 stdcall GetTextExtentExPointA(long ptr long long ptr ptr ptr) GetTextExtentExPoint32A
 0229 stdcall GetTextExtentExPointW(long ptr long long ptr ptr ptr) GetTextExtentExPoint32W
 0230 stdcall GetTextExtentPoint32A(long ptr long ptr) GetTextExtentPoint32A
@@ -292,12 +292,12 @@
 0284 stub RemoveFontResourceA
 0285 stub RemoveFontResourceTracking
 0286 stub RemoveFontResourceW
-0287 stub ResetDCA
-0288 stub ResetDCW
+0287 stdcall ResetDCA(long ptr) ResetDC32A
+0288 stdcall ResetDCW(long ptr) ResetDC32W
 0289 stub ResizePalette
-0290 stdcall RestoreDC(long long) RestoreDC
+0290 stdcall RestoreDC(long long) RestoreDC32
 0291 stdcall RoundRect(long long long long long long long) RoundRect32
-0292 stdcall SaveDC(long) SaveDC
+0292 stdcall SaveDC(long) SaveDC32
 0293 stdcall ScaleViewportExtEx(long long long long long ptr) ScaleViewportExtEx32
 0294 stdcall ScaleWindowExtEx(long long long long long ptr) ScaleWindowExtEx32
 0295 stub SelectBrushLocal
@@ -311,15 +311,15 @@
 0303 stdcall SetBitmapBits(long long ptr) SetBitmapBits
 0304 stdcall SetBitmapDimensionEx(long long long ptr) SetBitmapDimensionEx32
 0305 stdcall SetBkColor(long long) SetBkColor
-0306 stdcall SetBkMode(long long) SetBkMode
+0306 stdcall SetBkMode(long long) SetBkMode32
 0307 stub SetBoundsRect
 0308 stdcall SetBrushOrgEx(long long long ptr) SetBrushOrgEx
 0309 stub SetColorAdjustment
 0310 stub SetColorSpace
 0311 stub SetDIBColorTable
-0312 stdcall SetDIBits(long long long long ptr ptr long) SetDIBits
+0312 stdcall SetDIBits(long long long long ptr ptr long) SetDIBits32
 0313 stdcall SetDIBitsToDevice(long long long long long long long long long
-                               ptr ptr long) SetDIBitsToDevice
+                               ptr ptr long) SetDIBitsToDevice32
 0314 stub SetDeviceGammaRamp
 0315 stub SetEnhMetaFileBits
 0316 stub SetFontEnumeration
@@ -327,7 +327,7 @@
 0318 stub SetICMMode
 0319 stub SetICMProfileA
 0320 stub SetICMProfileW
-0321 stdcall SetMapMode(long long) SetMapMode
+0321 stdcall SetMapMode(long long) SetMapMode32
 0322 stdcall SetMapperFlags(long long) SetMapperFlags
 0323 stub SetMetaFileBitsEx
 0324 stub SetMetaRgn
@@ -336,16 +336,16 @@
 0327 stdcall SetPixel(long long long long) SetPixel32
 0328 stub SetPixelFormat
 0329 stub SetPixelV
-0330 stub SetPolyFillMode
-0331 stdcall SetROP2(long long) SetROP2
+0330 stdcall SetPolyFillMode(long long) SetPolyFillMode32
+0331 stdcall SetROP2(long long) SetROP232
 0332 stdcall SetRectRgn(long long long long long) SetRectRgn
-0333 stub SetRelAbs
-0334 stdcall SetStretchBltMode(long long) SetStretchBltMode
+0333 stdcall SetRelAbs(long long) SetRelAbs32
+0334 stdcall SetStretchBltMode(long long) SetStretchBltMode32
 0335 stub SetSystemPaletteUse
-0336 stdcall SetTextAlign(long long) SetTextAlign
-0337 stub SetTextCharacterExtra
+0336 stdcall SetTextAlign(long long) SetTextAlign32
+0337 stdcall SetTextCharacterExtra(long long) SetTextCharacterExtra32
 0338 stdcall SetTextColor(long long) SetTextColor
-0339 stub SetTextJustification
+0339 stdcall SetTextJustification(long long long) SetTextJustification32
 0340 stdcall SetViewportExtEx(long long long ptr) SetViewportExtEx32
 0341 stdcall SetViewportOrgEx(long long long ptr) SetViewportOrgEx32
 0342 stub SetVirtualResolution
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index d88895c..ae04afa 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -5,8 +5,8 @@
 #2	pascal	Enable
 #3	pascal	Disable
 4   pascal16 ToAscii(word word ptr ptr word) ToAscii
-5   pascal16 AnsiToOem(ptr ptr) AnsiToOem
-6   pascal16 OemToAnsi(ptr ptr) OemToAnsi
+5   pascal16 AnsiToOem(ptr ptr) AnsiToOem16
+6   pascal16 OemToAnsi(ptr ptr) OemToAnsi16
 7   return   SetSpeed 2 65535
 #100	pascal	ScreenSwitchEnable
 #126	pascal	GetTableSeg
@@ -17,8 +17,8 @@
 131 pascal16 MapVirtualKey(word word) MapVirtualKey
 132 pascal16 GetKbCodePage() GetKbCodePage
 133 pascal16 GetKeyNameText(long ptr word) GetKeyNameText16
-134 pascal16 AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
-135 pascal16 OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
+134 pascal16 AnsiToOemBuff(ptr ptr word) AnsiToOemBuff16
+135 pascal16 OemToAnsiBuff(ptr ptr word) OemToAnsiBuff16
 #136	pascal	EnableKbSysReq
 #137	pascal	GetBiosKeyProc
 
diff --git a/include/color.h b/include/color.h
index cd42b82..8eada96 100644
--- a/include/color.h
+++ b/include/color.h
@@ -14,6 +14,7 @@
 #define PC_SYS_MAPPED   0x10		/* logical palentry is a direct alias for system palentry */
 
 extern HPALETTE16 	COLOR_Init(void);
+extern void		COLOR_Cleanup(void);
 extern COLORREF		COLOR_ToLogical(int pixel);
 extern int 		COLOR_ToPhysical( DC *dc, COLORREF color );
 extern int 		COLOR_SetMapping( PALETTEOBJ* pal, BOOL32 mapOnly );
diff --git a/include/debugger.h b/include/debugger.h
index ebdefc4..306cb18 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -10,6 +10,8 @@
 #include "ldt.h"
 #include "registers.h"
 
+#include "pe_image.h"
+
 #define STEP_FLAG 0x100 /* single step flag */
 
 typedef struct
@@ -18,6 +20,45 @@
     DWORD off;
 } DBG_ADDR;
 
+struct  wine_lines {
+  unsigned long		line_number;
+  DBG_ADDR		pc_offset;
+};
+
+typedef struct wine_lines WineLineNo;
+
+/*
+ * This structure holds information about stack variables, function
+ * parameters, and register variables, which are all local to this
+ * function.
+ */
+struct  wine_locals {
+  unsigned int		regno:8;	/* For register symbols */
+  unsigned int		offset:24;	/* offset from esp/ebp to symbol */
+  unsigned int		pc_start;	/* For RBRAC/LBRAC */
+  unsigned int		pc_end;		/* For RBRAC/LBRAC */
+  char		      * name;		/* Name of symbol */
+};
+
+typedef struct wine_locals WineLocals;
+
+struct name_hash
+{
+    struct name_hash * next;
+    char *             name;
+    char *             sourcefile;
+
+    int		       n_locals;
+    int		       locals_alloc;
+    WineLocals       * local_vars;
+  
+    int		       n_lines;
+    int		       lines_alloc;
+    WineLineNo       * linetab;
+
+    DBG_ADDR           addr;
+};
+
 #define DBG_FIX_ADDR_SEG(addr,default) \
     { if ((addr)->seg == 0xffffffff) (addr)->seg = (default); \
       if (((addr)->seg == WINE_CODE_SELECTOR) || \
@@ -30,13 +71,13 @@
 #define DBG_CHECK_READ_PTR(addr,len) \
     (!DEBUG_IsBadReadPtr((addr),(len)) || \
      (fprintf(stderr,"*** Invalid address "), \
-      DEBUG_PrintAddress((addr),dbg_mode), \
+      DEBUG_PrintAddress((addr),dbg_mode, FALSE), \
       fprintf(stderr,"\n"),0))
 
 #define DBG_CHECK_WRITE_PTR(addr,len) \
     (!DEBUG_IsBadWritePtr((addr),(len)) || \
      (fprintf(stderr,"*** Invalid address "), \
-      DEBUG_PrintAddress(addr,dbg_mode), \
+      DEBUG_PrintAddress(addr,dbg_mode, FALSE), \
       fprintf(stderr,"\n"),0))
 
 #ifdef REG_SP  /* Some Sun includes define this */
@@ -79,18 +120,36 @@
 extern void DEBUG_Disasm( DBG_ADDR *addr );
 
   /* debugger/hash.c */
-extern void DEBUG_AddSymbol( const char *name, const DBG_ADDR *addr );
-extern BOOL32 DEBUG_GetSymbolValue( const char * name, DBG_ADDR *addr );
+extern struct name_hash * DEBUG_AddSymbol( const char *name, 
+					   const DBG_ADDR *addr,
+					   const char * sourcefile);
+extern BOOL32 DEBUG_GetSymbolValue( const char * name, const int lineno,
+				    DBG_ADDR *addr );
 extern BOOL32 DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr );
-extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr );
+extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
+					     struct name_hash ** rtn,
+					     unsigned int ebp);
 extern void DEBUG_ReadSymbolTable( const char * filename );
 extern void DEBUG_LoadEntryPoints(void);
+extern void DEBUG_AddLineNumber( struct name_hash * func, int line_num, 
+		     unsigned long offset );
+extern void DEBUG_AddLocal( struct name_hash * func, int regno, 
+			    int offset,
+			    int pc_start,
+			    int pc_end,
+			    char * name);
+
 
   /* debugger/info.c */
 extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format );
-extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen );
+extern struct name_hash * DEBUG_PrintAddress( const DBG_ADDR *addr, 
+					      int addrlen, int flag );
 extern void DEBUG_Help(void);
 extern void DEBUG_List( DBG_ADDR *addr, int count );
+extern struct name_hash * DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, 
+						     int addrlen, 
+						     unsigned int ebp, 
+						     int flag );
 
   /* debugger/memory.c */
 extern BOOL32 DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size );
@@ -108,6 +167,17 @@
   /* debugger/stack.c */
 extern void DEBUG_InfoStack(void);
 extern void DEBUG_BackTrace(void);
+extern BOOL32 DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr );
+extern int  DEBUG_InfoLocals(void);
+extern int  DEBUG_SetFrame(int newframe);
+
+  /* debugger/stabs.c */
+extern int DEBUG_ReadExecutableDbgInfo(void);
+
+  /* debugger/msc.c */
+extern int DEBUG_RegisterDebugInfo(int, struct pe_data *pe,
+				   int, unsigned long, unsigned long);
+extern int DEBUG_ProcessDeferredDebug(void);
 
   /* debugger/dbg.y */
 extern void DEBUG_EnterDebugger(void);
diff --git a/include/except.h b/include/except.h
index 582a695..0fbd40e 100644
--- a/include/except.h
+++ b/include/except.h
@@ -216,7 +216,4 @@
 
 DWORD UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers);
 
-__PTOP_EXCFILTER SetUnhandledExceptionFilter(
-      LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
-  
 #endif  /* __WINE_EXCEPT_H */
diff --git a/include/gdi.h b/include/gdi.h
index 066bd02..b00988e 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -107,19 +107,11 @@
 
     BYTE          bitsPerPixel;
 
-    WORD          MapMode;
-    short         DCOrgX;            /* DC origin */
-    short         DCOrgY;
-    short         CursPosX;          /* Current position */
-    short         CursPosY;
-    short         WndOrgX;
-    short         WndOrgY;
-    short         WndExtX;
-    short         WndExtY;
-    short         VportOrgX;
-    short         VportOrgY;
-    short         VportExtX;
-    short         VportExtY;
+    INT32         MapMode;
+    INT32         DCOrgX;            /* DC origin */
+    INT32         DCOrgY;
+    INT32         CursPosX;          /* Current position */
+    INT32         CursPosY;
 } WIN_DC_INFO;
 
 typedef X11DRV_PDEVICE X_DC_INFO;  /* Temporary */
@@ -130,10 +122,19 @@
     HDC32          hSelf;            /* Handle to this DC */
     const struct tagDC_FUNCS *funcs; /* DC function table */
     void          *physDev;          /* Physical device (driver-specific) */
-    WORD           saveLevel;
+    INT32          saveLevel;
     DWORD          dwHookData;
     FARPROC16      hookProc;
 
+    INT32          wndOrgX;          /* Window origin */
+    INT32          wndOrgY;
+    INT32          wndExtX;          /* Window extent */
+    INT32          wndExtY;
+    INT32          vportOrgX;        /* Viewport origin */
+    INT32          vportOrgY;
+    INT32          vportExtX;        /* Viewport extent */
+    INT32          vportExtY;
+
     WIN_DC_INFO w;
     union
     {
@@ -168,8 +169,8 @@
     BOOL32     (*pLineTo)(DC*,INT32,INT32);
     BOOL32     (*pMoveToEx)(DC*,INT32,INT32,LPPOINT32);
     INT32      (*pOffsetClipRgn)(DC*,INT32,INT32);
-    BOOL32     (*pOffsetViewportOrgEx)(DC*,INT32,INT32,LPPOINT32);
-    BOOL32     (*pOffsetWindowOrgEx)(DC*,INT32,INT32,LPPOINT32);
+    BOOL32     (*pOffsetViewportOrg)(DC*,INT32,INT32);
+    BOOL32     (*pOffsetWindowOrg)(DC*,INT32,INT32);
     BOOL32     (*pPaintRgn)(DC*,HRGN32);
     BOOL32     (*pPatBlt)(DC*,INT32,INT32,INT32,INT32,DWORD);
     BOOL32     (*pPie)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32);
@@ -181,8 +182,8 @@
     BOOL32     (*pRestoreDC)(DC*,INT32);
     BOOL32     (*pRoundRect)(DC*,INT32,INT32,INT32,INT32,INT32,INT32);
     INT32      (*pSaveDC)(DC*);
-    BOOL32     (*pScaleViewportExtEx)(DC*,INT32,INT32,INT32,INT32,LPSIZE32);
-    BOOL32     (*pScaleWindowExtEx)(DC*,INT32,INT32,INT32,INT32,LPSIZE32);
+    BOOL32     (*pScaleViewportExt)(DC*,INT32,INT32,INT32,INT32);
+    BOOL32     (*pScaleWindowExt)(DC*,INT32,INT32,INT32,INT32);
     INT32      (*pSelectClipRgn)(DC*,HRGN32);
     HANDLE32   (*pSelectObject)(DC*,HANDLE32);
     HPALETTE32 (*pSelectPalette)(DC*,HPALETTE32,BOOL32);
@@ -190,7 +191,7 @@
     WORD       (*pSetBkMode)(DC*,WORD);
     VOID       (*pSetDeviceClipping)(DC*);
     INT32      (*pSetDIBitsToDevice)(DC*,INT32,INT32,DWORD,DWORD,INT32,INT32,UINT32,UINT32,LPCVOID,const BITMAPINFO*,UINT32);
-    WORD       (*pSetMapMode)(DC*,WORD);
+    INT32      (*pSetMapMode)(DC*,INT32);
     DWORD      (*pSetMapperFlags)(DC*,DWORD);
     COLORREF   (*pSetPixel)(DC*,INT32,INT32,COLORREF);
     WORD       (*pSetPolyFillMode)(DC*,WORD);
@@ -201,10 +202,10 @@
     INT32      (*pSetTextCharacterExtra)(DC*,INT32);
     DWORD      (*pSetTextColor)(DC*,DWORD);
     INT32      (*pSetTextJustification)(DC*,INT32,INT32);
-    BOOL32     (*pSetViewportExtEx)(DC*,INT32,INT32,LPSIZE32);
-    BOOL32     (*pSetViewportOrgEx)(DC*,INT32,INT32,LPPOINT32);
-    BOOL32     (*pSetWindowExtEx)(DC*,INT32,INT32,LPSIZE32);
-    BOOL32     (*pSetWindowOrgEx)(DC*,INT32,INT32,LPPOINT32);
+    BOOL32     (*pSetViewportExt)(DC*,INT32,INT32);
+    BOOL32     (*pSetViewportOrg)(DC*,INT32,INT32);
+    BOOL32     (*pSetWindowExt)(DC*,INT32,INT32);
+    BOOL32     (*pSetWindowOrg)(DC*,INT32,INT32);
     BOOL32     (*pStretchBlt)(DC*,INT32,INT32,INT32,INT32,DC*,INT32,INT32,INT32,INT32,DWORD);
     INT32      (*pStretchDIBits)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32,LPSTR,LPBITMAPINFO,WORD,DWORD);
     BOOL32     (*pTextOut)(DC*,INT32,INT32,LPCSTR,INT32);
@@ -259,13 +260,13 @@
   /* Device <-> logical coords conversion */
 
 #define XDPTOLP(dc,x) \
-(((x)-(dc)->w.VportOrgX) * (dc)->w.WndExtX / (dc)->w.VportExtX+(dc)->w.WndOrgX)
+    (((x)-(dc)->vportOrgX) * (dc)->wndExtX / (dc)->vportExtX+(dc)->wndOrgX)
 #define YDPTOLP(dc,y) \
-(((y)-(dc)->w.VportOrgY) * (dc)->w.WndExtY / (dc)->w.VportExtY+(dc)->w.WndOrgY)
+    (((y)-(dc)->vportOrgY) * (dc)->wndExtY / (dc)->vportExtY+(dc)->wndOrgY)
 #define XLPTODP(dc,x) \
-(((x)-(dc)->w.WndOrgX) * (dc)->w.VportExtX / (dc)->w.WndExtX+(dc)->w.VportOrgX)
+    (((x)-(dc)->wndOrgX) * (dc)->vportExtX / (dc)->wndExtX+(dc)->vportOrgX)
 #define YLPTODP(dc,y) \
-(((y)-(dc)->w.WndOrgY) * (dc)->w.VportExtY / (dc)->w.WndExtY+(dc)->w.VportOrgY)
+    (((y)-(dc)->wndOrgY) * (dc)->vportExtY / (dc)->wndExtY+(dc)->vportOrgY)
 
 
   /* GDI local heap */
diff --git a/include/heap.h b/include/heap.h
index e262c09..5cdfdeb 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -17,6 +17,8 @@
 extern SEGPTR HEAP_GetSegptr( HANDLE32 heap, DWORD flags, LPCVOID ptr );
 extern LPSTR HEAP_strdupA( HANDLE32 heap, DWORD flags, LPCSTR str );
 extern LPWSTR HEAP_strdupW( HANDLE32 heap, DWORD flags, LPCWSTR str );
+extern LPWSTR HEAP_strdupAtoW( HANDLE32 heap, DWORD flags, LPCSTR str );
+extern LPSTR HEAP_strdupWtoA( HANDLE32 heap, DWORD flags, LPCWSTR str );
 
 /* SEGPTR helper macros */
 
@@ -26,6 +28,8 @@
          ((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) ))
 #define SEGPTR_STRDUP(str) \
          (HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
+#define SEGPTR_STRDUP_WtoA(str) \
+         (HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
 #define SEGPTR_GET(ptr) \
          (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, (ptr) ) : (SEGPTR)(ptr))
 #define SEGPTR_FREE(ptr) \
diff --git a/include/message.h b/include/message.h
index 622059a..f51efd2 100644
--- a/include/message.h
+++ b/include/message.h
@@ -31,6 +31,7 @@
 extern void EVENT_Synchronize(void);
 extern void EVENT_ProcessEvent( XEvent *event );
 extern void EVENT_RegisterWindow( WND *pWnd );
+extern void EVENT_DestroyWindow( WND *pWnd );
 extern void EVENT_DummyMotionNotify(void);
 
 #endif  /* __WINE_MESSAGE_H */
diff --git a/include/metafiledrv.h b/include/metafiledrv.h
index 14b2da5..91027a8 100644
--- a/include/metafiledrv.h
+++ b/include/metafiledrv.h
@@ -32,5 +32,16 @@
                                 INT32 widthDst, INT32 heightDst,
                                 struct tagDC *dcSrc, INT32 xSrc, INT32 ySrc,
                                 INT32 widthSrc, INT32 heightSrc, DWORD rop );
+extern INT32 MFDRV_SetMapMode( struct tagDC *dc, INT32 mode );
+extern BOOL32 MFDRV_SetViewportExt( struct tagDC *dc, INT32 x, INT32 y );
+extern BOOL32 MFDRV_SetViewportOrg( struct tagDC *dc, INT32 x, INT32 y );
+extern BOOL32 MFDRV_SetWindowExt( struct tagDC *dc, INT32 x, INT32 y );
+extern BOOL32 MFDRV_SetWindowOrg( struct tagDC *dc, INT32 x, INT32 y );
+extern BOOL32 MFDRV_OffsetViewportOrg( struct tagDC *dc, INT32 x, INT32 y );
+extern BOOL32 MFDRV_OffsetWindowOrg( struct tagDC *dc, INT32 x, INT32 y );
+extern BOOL32 MFDRV_ScaleViewportExt( struct tagDC *dc, INT32 xNum,
+                                      INT32 xDenom, INT32 yNum, INT32 yDenom );
+extern BOOL32 MFDRV_ScaleWindowExt( struct tagDC *dc, INT32 xNum, INT32 xDenom,
+                                    INT32 yNum, INT32 yDenom );
 
 #endif  /* __WINE_METAFILEDRV_H */
diff --git a/include/peexe.h b/include/peexe.h
index ff85a08..a7d5474 100644
--- a/include/peexe.h
+++ b/include/peexe.h
@@ -220,6 +220,32 @@
 	short Relocations[1];
 };
 
+/*
+ * The IMAGE_FILE_DEBUG_DIRECTORY data directory points to an array of
+ * these structures.
+ */
+struct PE_Debug_dir
+{
+	u_long		flags;
+	u_long		timestamp;
+	u_short		major;
+	u_short		minor;
+	u_long		type;
+	u_long		dbgsize;
+	u_long		dbgptr;
+	u_long		dbgoff;
+};
+
+/*
+ * The type field above can take these (plus a few other
+ * irrelevant) values.
+ */
+#define IMAGE_DEBUG_TYPE_UNKNOWN	0
+#define IMAGE_DEBUG_TYPE_COFF		1
+#define IMAGE_DEBUG_TYPE_CODEVIEW	2
+#define IMAGE_DEBUG_TYPE_FPO		3
+#define IMAGE_DEBUG_TYPE_MISC		4
+
 #define IMAGE_REL_BASED_ABSOLUTE 		0
 #define IMAGE_REL_BASED_HIGH			1
 #define IMAGE_REL_BASED_LOW				2
diff --git a/include/string32.h b/include/string32.h
index 7791411..f8f234d 100644
--- a/include/string32.h
+++ b/include/string32.h
@@ -10,8 +10,6 @@
 
 #include "wintypes.h"
 
-void	STRING32_UniToAnsi(LPSTR dest,LPCWSTR src);
-void	STRING32_AnsiToUni(LPWSTR dest,LPCSTR src);
 LPSTR	STRING32_DupUniToAnsi(LPCWSTR src);
 LPWSTR	STRING32_DupAnsiToUni(LPCSTR src);
 LPWSTR	STRING32_strdupW(LPCWSTR);
diff --git a/include/windows.h b/include/windows.h
index 1bac570..be336a8 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -4211,14 +4211,17 @@
 WORD       FreeSelector(WORD);
 HANDLE16   GetAtomHandle(ATOM);
 DWORD      GetBitmapDimension(HBITMAP16);
+DWORD      GetBrushOrg(HDC16);
 HANDLE16   GetCodeHandle(FARPROC16);
 INT16      GetCommError(INT16,LPCOMSTAT);
 UINT16     GetCommEventMask(INT16,UINT16);
 VOID       GetCodeInfo(FARPROC16,LPVOID);
 HANDLE16   GetCurrentPDB(void);
+DWORD      GetCurrentPosition(HDC16);
 HTASK16    GetCurrentTask(void);
 DWORD      GetDCHook(HDC16,FARPROC16*);
 DWORD      GetDCOrg(HDC16);
+HDC16      GetDCState(HDC16);
 HWND16     GetDesktopHwnd(void);
 HMODULE16  GetExePtr(HANDLE16);
 WORD       GetExeVersion(void);
@@ -4230,6 +4233,11 @@
 DWORD      GetSelectorLimit(WORD);
 HINSTANCE16 GetTaskDS(void);
 HQUEUE16   GetTaskQueue(HTASK16);
+DWORD      GetTextExtent(HDC16,LPCSTR,INT16);
+DWORD      GetViewportExt(HDC16);
+DWORD      GetViewportOrg(HDC16);
+DWORD      GetWindowExt(HDC16);
+DWORD      GetWindowOrg(HDC16);
 DWORD      GlobalDOSAlloc(DWORD);
 WORD       GlobalDOSFree(WORD);
 void       GlobalFreeAll(HGLOBAL16);
@@ -4239,6 +4247,7 @@
 WORD       GlobalPageLock(HGLOBAL16);
 WORD       GlobalPageUnlock(HGLOBAL16);
 INT16      InitApp(HINSTANCE16);
+HRGN16     InquireVisRgn(HDC16);
 INT16      IntersectVisRect(HDC16,INT16,INT16,INT16,INT16);
 BOOL16     IsGDIObject(HGDIOBJ16);
 BOOL16     IsSharedSelector(HANDLE16);
@@ -4266,6 +4275,8 @@
 DWORD      SetBrushOrg(HDC16,INT16,INT16);
 UINT16*    SetCommEventMask(INT16,UINT16);
 BOOL16     SetDCHook(HDC16,FARPROC16,DWORD);
+DWORD      SetDCOrg(HDC16,INT16,INT16);
+VOID       SetDCState(HDC16,HDC16);
 BOOL16     SetDeskPattern(void);
 VOID       SetPriority(HTASK16,INT16);
 WORD       SetSelectorBase(WORD,DWORD);
@@ -4444,8 +4455,6 @@
 BOOL16     SetCaretBlinkTime(UINT32);
 BOOL16     SetCaretPos(INT32,INT32);
 WORD       SetClassWord(HWND32,INT32,WORD);
-INT16      SetDIBits(HDC32,HBITMAP32,UINT32,UINT32,LPCVOID,const BITMAPINFO*,UINT32);
-INT16      SetDIBitsToDevice(HDC32,INT32,INT32,DWORD,DWORD,INT32,INT32,UINT32,UINT32,LPCVOID,const BITMAPINFO*,UINT32);
 VOID       SetLastError(DWORD);
 VOID       SetLastErrorEx(DWORD,DWORD);
 VOID       SetRectRgn(HRGN32,INT32,INT32,INT32,INT32);
@@ -4474,6 +4483,14 @@
 HGLOBAL16  AllocResource16(HINSTANCE16,HRSRC16,DWORD);
 HGLOBAL32  AllocResource32(HINSTANCE32,HRSRC32,DWORD);
 #define    AllocResource WINELIB_NAME(AllocResource)
+INT16      AnsiToOem16(LPCSTR,LPSTR);
+#define    AnsiToOem32A CharToOem32A
+#define    AnsiToOem32W CharToOem32W
+#define    AnsiToOem WINELIB_NAME_AW(AnsiToOem)
+VOID       AnsiToOemBuff16(LPCSTR,LPSTR,UINT16);
+#define    AnsiToOemBuff32A CharToOemBuff32A
+#define    AnsiToOemBuff32W CharToOemBuff32W
+#define    AnsiToOemBuff WINELIB_NAME_AW(AnsiToOemBuff)
 BOOL16     AppendMenu16(HMENU16,UINT16,UINT16,SEGPTR);
 BOOL32     AppendMenu32A(HMENU32,UINT32,UINT32,LPCSTR);
 BOOL32     AppendMenu32W(HMENU32,UINT32,UINT32,LPCWSTR);
@@ -4529,10 +4546,10 @@
 DWORD      CharUpperBuff32A(LPSTR,DWORD);
 DWORD      CharUpperBuff32W(LPWSTR,DWORD);
 #define    CharUpperBuff WINELIB_NAME_AW(CharUpperBuff)
-BOOL32     CharToOem32A(LPSTR,LPSTR);
+BOOL32     CharToOem32A(LPCSTR,LPSTR);
 BOOL32     CharToOem32W(LPCWSTR,LPSTR);
 #define    CharToOem WINELIB_NAME_AW(CharToOem)
-BOOL32     CharToOemBuff32A(LPSTR,LPSTR,DWORD);
+BOOL32     CharToOemBuff32A(LPCSTR,LPSTR,DWORD);
 BOOL32     CharToOemBuff32W(LPCWSTR,LPSTR,DWORD);
 #define    CharToOemBuff WINELIB_NAME_AW(CharToOemBuff)
 HWND16     ChildWindowFromPoint16(HWND16,POINT16);
@@ -4575,6 +4592,9 @@
 HBRUSH16   CreateBrushIndirect16(const LOGBRUSH16*);
 HBRUSH32   CreateBrushIndirect32(const LOGBRUSH32*);
 #define    CreateBrushIndirect WINELIB_NAME(CreateBrushIndirect)
+HDC16      CreateCompatibleDC16(HDC16);
+HDC32      CreateCompatibleDC32(HDC32);
+#define    CreateCompatibleDC WINELIB_NAME(CreateCompatibleDC)
 HDC16      CreateDC16(LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*);
 HDC32      CreateDC32A(LPCSTR,LPCSTR,LPCSTR,const DEVMODE32A*);
 HDC32      CreateDC32W(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODE32W*);
@@ -4599,6 +4619,11 @@
 HWND32     CreateDialogParam32A(HINSTANCE32,LPCSTR,HWND32,DLGPROC32,LPARAM);
 HWND32     CreateDialogParam32W(HINSTANCE32,LPCWSTR,HWND32,DLGPROC32,LPARAM);
 #define    CreateDialogParam WINELIB_NAME_AW(CreateDialogParam)
+HBITMAP16  CreateDIBitmap16(HDC16,const BITMAPINFOHEADER*,DWORD,LPCVOID,
+                            const BITMAPINFO*,UINT16);
+HBITMAP32  CreateDIBitmap32(HDC32,const BITMAPINFOHEADER*,DWORD,LPCVOID,
+                            const BITMAPINFO*,UINT32);
+#define    CreateDIBitmap WINELIB_NAME(CreateDIBitmap)
 HBRUSH16   CreateDIBPatternBrush16(HGLOBAL16,UINT16);
 HBRUSH32   CreateDIBPatternBrush32(HGLOBAL32,UINT32);
 #define    CreateDIBPatternBrush WINELIB_NAME(CreateDIBPatternBrush)
@@ -4626,6 +4651,10 @@
 HBRUSH16   CreateHatchBrush16(INT16,COLORREF);
 HBRUSH32   CreateHatchBrush32(INT32,COLORREF);
 #define    CreateHatchBrush WINELIB_NAME(CreateHatchBrush)
+HDC16      CreateIC16(LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*);
+HDC32      CreateIC32A(LPCSTR,LPCSTR,LPCSTR,const DEVMODE32A*);
+HDC32      CreateIC32W(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODE32W*);
+#define    CreateIC WINELIB_NAME_AW(CreateIC)
 HDC16      CreateMetaFile16(LPCSTR);
 HDC32      CreateMetaFile32A(LPCSTR);
 HDC32      CreateMetaFile32W(LPCWSTR);
@@ -4691,6 +4720,9 @@
 LRESULT    DefWindowProc32A(HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    DefWindowProc32W(HWND32,UINT32,WPARAM32,LPARAM);
 #define    DefWindowProc WINELIB_NAME_AW(DefWindowProc)
+BOOL16     DeleteDC16(HDC16);
+BOOL32     DeleteDC32(HDC32);
+#define    DeleteDC WINELIB_NAME(DeleteDC)
 BOOL16     DeleteFile16(LPCSTR);
 BOOL32     DeleteFile32A(LPCSTR);
 BOOL32     DeleteFile32W(LPCWSTR);
@@ -4863,6 +4895,12 @@
 BOOL16     GetBrushOrgEx16(HDC16,LPPOINT16);
 BOOL32     GetBrushOrgEx32(HDC32,LPPOINT32);
 #define    GetBrushOrgEx WINELIB_NAME(GetBrushOrgEx)
+COLORREF   GetBkColor16(HDC16);
+COLORREF   GetBkColor32(HDC32);
+#define    GetBkColor WINELIB_NAME(GetBkColor)
+INT16      GetBkMode16(HDC16);
+INT32      GetBkMode32(HDC32);
+#define    GetBkMode WINELIB_NAME(GetBkMode)
 HWND16     GetCapture16(void);
 HWND32     GetCapture32(void);
 #define    GetCapture WINELIB_NAME(GetCapture)
@@ -4872,6 +4910,14 @@
 VOID       GetCaretPos16(LPPOINT16);
 BOOL32     GetCaretPos32(LPPOINT32);
 #define    GetCaretPos WINELIB_NAME(GetCaretPos)
+BOOL16     GetCharABCWidths16(HDC16,UINT16,UINT16,LPABC16);
+BOOL32     GetCharABCWidths32A(HDC32,UINT32,UINT32,LPABC32);
+BOOL32     GetCharABCWidths32W(HDC32,UINT32,UINT32,LPABC32);
+#define    GetCharABCWidths WINELIB_NAME_AW(GetCharABCWidths)
+BOOL16     GetCharWidth16(HDC16,UINT16,UINT16,LPINT16);
+BOOL32     GetCharWidth32A(HDC32,UINT32,UINT32,LPINT32);
+BOOL32     GetCharWidth32W(HDC32,UINT32,UINT32,LPINT32);
+#define    GetCharWidth WINELIB_NAME_AW(GetCharWidth)
 BOOL16     GetClassInfo16(HINSTANCE16,SEGPTR,WNDCLASS16 *);
 BOOL32     GetClassInfo32A(HINSTANCE32,LPCSTR,WNDCLASS32A *);
 BOOL32     GetClassInfo32W(HINSTANCE32,LPCWSTR,WNDCLASS32W *);
@@ -4922,6 +4968,9 @@
 HWND16     GetDesktopWindow16(void);
 HWND32     GetDesktopWindow32(void);
 #define    GetDesktopWindow WINELIB_NAME(GetDesktopWindow)
+INT16      GetDIBits16(HDC16,HBITMAP16,UINT16,UINT16,LPSTR,LPBITMAPINFO,UINT16);
+INT32      GetDIBits32(HDC32,HBITMAP32,UINT32,UINT32,LPSTR,LPBITMAPINFO,UINT32);
+#define    GetDIBits WINELIB_NAME(GetDIBits)
 BOOL16     GetDiskFreeSpace16(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
 BOOL32     GetDiskFreeSpace32A(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
 BOOL32     GetDiskFreeSpace32W(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
@@ -4963,6 +5012,9 @@
 UINT32     GetLogicalDriveStrings32A(UINT32,LPSTR);
 UINT32     GetLogicalDriveStrings32W(UINT32,LPWSTR);
 #define    GetLogicalDriveStrings WINELIB_NAME_AW(GetLogicalDriveStrings)
+INT16      GetMapMode16(HDC16);
+INT32      GetMapMode32(HDC32);
+#define    GetMapMode WINELIB_NAME(GetMapMode)
 INT16      GetModuleFileName16(HINSTANCE16,LPSTR,INT16);
 DWORD      GetModuleFileName32A(HMODULE32,LPSTR,DWORD);
 DWORD      GetModuleFileName32W(HMODULE32,LPWSTR,DWORD);
@@ -4983,6 +5035,9 @@
 COLORREF   GetPixel16(HDC16,INT16,INT16);
 COLORREF   GetPixel32(HDC32,INT32,INT32);
 #define    GetPixel WINELIB_NAME(GetPixel)
+INT16      GetPolyFillMode16(HDC16);
+INT32      GetPolyFillMode32(HDC32);
+#define    GetPolyFillMode WINELIB_NAME(GetPolyFillMode)
 UINT16     GetPrivateProfileInt16(LPCSTR,LPCSTR,INT16,LPCSTR);
 UINT32     GetPrivateProfileInt32A(LPCSTR,LPCSTR,INT32,LPCSTR);
 UINT32     GetPrivateProfileInt32W(LPCWSTR,LPCWSTR,INT32,LPCWSTR);
@@ -5006,9 +5061,15 @@
 HANDLE32   GetProp32A(HWND32,LPCSTR);
 HANDLE32   GetProp32W(HWND32,LPCWSTR);
 #define    GetProp WINELIB_NAME_AW(GetProp)
+INT16      GetRelAbs16(HDC16);
+INT32      GetRelAbs32(HDC32);
+#define    GetRelAbs WINELIB_NAME(GetRelAbs)
 INT16      GetRgnBox16(HRGN16,LPRECT16);
 INT32      GetRgnBox32(HRGN32,LPRECT32);
 #define    GetRgnBox WINELIB_NAME(GetRgnBox)
+INT16      GetROP216(HDC16);
+INT32      GetROP232(HDC32);
+#define    GetROP2 WINELIB_NAME(GetROP2)
 BOOL16     GetScrollInfo16(HWND16,INT16,LPSCROLLINFO);
 BOOL32     GetScrollInfo32(HWND32,INT32,LPSCROLLINFO);
 #define    GetScrollInfo WINELIB_NAME(GetScrollInfo)
@@ -5021,6 +5082,9 @@
 HGDIOBJ16  GetStockObject16(INT16);
 HGDIOBJ32  GetStockObject32(INT32);
 #define    GetStockObject WINELIB_NAME(GetStockObject)
+INT16      GetStretchBltMode16(HDC16);
+INT32      GetStretchBltMode32(HDC32);
+#define    GetStretchBltMode WINELIB_NAME(GetStretchBltMode)
 HBRUSH16   GetSysColorBrush16(INT16);
 HBRUSH32   GetSysColorBrush32(INT32);
 #define    GetSysColorBrush WINELIB_NAME(GetSysColorBrush)
@@ -5038,6 +5102,15 @@
 UINT32     GetTempPath32A(UINT32,LPSTR);
 UINT32     GetTempPath32W(UINT32,LPWSTR);
 #define    GetTempPath WINELIB_NAME_AW(GetTempPath)
+UINT16     GetTextAlign16(HDC16);
+UINT32     GetTextAlign32(HDC32);
+#define    GetTextAlign WINELIB_NAME(GetTextAlign)
+INT16      GetTextCharacterExtra16(HDC16);
+INT32      GetTextCharacterExtra32(HDC32);
+#define    GetTextCharacterExtra WINELIB_NAME(GetTextCharacterExtra)
+COLORREF   GetTextColor16(HDC16);
+COLORREF   GetTextColor32(HDC32);
+#define    GetTextColor WINELIB_NAME(GetTextColor)
 BOOL16     GetTextExtentPoint16(HDC16,LPCSTR,INT16,LPSIZE16);
 BOOL32     GetTextExtentPoint32A(HDC32,LPCSTR,INT32,LPSIZE32);
 BOOL32     GetTextExtentPoint32W(HDC32,LPCWSTR,INT32,LPSIZE32);
@@ -5314,10 +5387,18 @@
 INT16      MulDiv16(INT16,INT16,INT16);
 INT32      MulDiv32(INT32,INT32,INT32);
 #define    MulDiv WINELIB_NAME(MulDiv)
-BOOL32     OemToChar32A(LPSTR,LPSTR);
+INT16      OemToAnsi16(LPCSTR,LPSTR);
+#define    OemToAnsi32A OemToChar32A
+#define    OemToAnsi32W OemToChar32W
+#define    OemToAnsi WINELIB_NAME_AW(OemToAnsi)
+VOID       OemToAnsiBuff16(LPCSTR,LPSTR,UINT16);
+#define    OemToAnsiBuff32A OemToCharBuff32A
+#define    OemToAnsiBuff32W OemToCharBuff32W
+#define    OemToAnsiBuff WINELIB_NAME_AW(OemToAnsiBuff)
+BOOL32     OemToChar32A(LPCSTR,LPSTR);
 BOOL32     OemToChar32W(LPCSTR,LPWSTR);
 #define    OemToChar WINELIB_NAME_AW(OemToChar)
-BOOL32     OemToCharBuff32A(LPSTR,LPSTR,DWORD);
+BOOL32     OemToCharBuff32A(LPCSTR,LPSTR,DWORD);
 BOOL32     OemToCharBuff32W(LPCSTR,LPWSTR,DWORD);
 #define    OemToCharBuff WINELIB_NAME_AW(OemToCharBuff)
 INT16      OffsetClipRgn16(HDC16,INT16,INT16);
@@ -5451,9 +5532,19 @@
 BOOL32     RemoveDirectory32A(LPCSTR);
 BOOL32     RemoveDirectory32W(LPCWSTR);
 #define    RemoveDirectory WINELIB_NAME_AW(RemoveDirectory)
+HDC16      ResetDC16(HDC16,const DEVMODE16 *);
+HDC32      ResetDC32A(HDC32,const DEVMODE32A *);
+HDC32      ResetDC32W(HDC32,const DEVMODE32W *);
+#define    ResetDC WINELIB_NAME_AW(ResetDC)
+BOOL16     RestoreDC16(HDC16,INT16);
+BOOL32     RestoreDC32(HDC32,INT32);
+#define    RestoreDC WINELIB_NAME(RestoreDC)
 BOOL16     RoundRect16(HDC16,INT16,INT16,INT16,INT16,INT16,INT16);
 BOOL32     RoundRect32(HDC32,INT32,INT32,INT32,INT32,INT32,INT32);
 #define    RoundRect WINELIB_NAME(RoundRect)
+INT16      SaveDC16(HDC16);
+INT32      SaveDC32(HDC32);
+#define    SaveDC WINELIB_NAME(SaveDC)
 BOOL16     ScaleViewportExtEx16(HDC16,INT16,INT16,INT16,INT16,LPSIZE16);
 BOOL32     ScaleViewportExtEx32(HDC32,INT32,INT32,INT32,INT32,LPSIZE32);
 #define    ScaleViewportExtEx WINELIB_NAME(ScaleViewportExtEx)
@@ -5493,6 +5584,9 @@
 BOOL16     SetBitmapDimensionEx16(HBITMAP16,INT16,INT16,LPSIZE16);
 BOOL32     SetBitmapDimensionEx32(HBITMAP32,INT32,INT32,LPSIZE32);
 #define    SetBitmapDimensionEx WINELIB_NAME(SetBitmapDimensionEx)
+INT16      SetBkMode16(HDC16,INT16);
+INT32      SetBkMode32(HDC32,INT32);
+#define    SetBkMode WINELIB_NAME(SetBkMode)
 HWND16     SetCapture16(HWND16);
 HWND32     SetCapture32(HWND32);
 #define    SetCapture WINELIB_NAME(SetCapture)
@@ -5509,6 +5603,14 @@
 BOOL16     SetDeskWallPaper16(LPCSTR);
 BOOL32     SetDeskWallPaper32(LPCSTR);
 #define    SetDeskWallPaper WINELIB_NAME(SetDeskWallPaper)
+INT16      SetDIBits16(HDC16,HBITMAP16,UINT16,UINT16,LPCVOID,const BITMAPINFO*,UINT16);
+INT32      SetDIBits32(HDC32,HBITMAP32,UINT32,UINT32,LPCVOID,const BITMAPINFO*,UINT32);
+#define    SetDIBits WINELIB_NAME(SetDIBits)
+INT16      SetDIBitsToDevice16(HDC16,INT16,INT16,INT16,INT16,INT16,INT16,
+                               UINT16,UINT16,LPCVOID,const BITMAPINFO*,UINT16);
+INT32      SetDIBitsToDevice32(HDC32,INT32,INT32,DWORD,DWORD,INT32,INT32,
+                               UINT32,UINT32,LPCVOID,const BITMAPINFO*,UINT32);
+#define    SetDIBitsToDevice WINELIB_NAME(SetDIBitsToDevice)
 void       SetDlgItemInt16(HWND16,INT16,UINT16,BOOL16);
 void       SetDlgItemInt32(HWND32,INT32,UINT32,BOOL32);
 #define    SetDlgItemInt WINELIB_NAME(SetDlgItemInt)
@@ -5532,9 +5634,15 @@
 void       SetInternalWindowPos16(HWND16,UINT16,LPRECT16,LPPOINT16);
 void       SetInternalWindowPos32(HWND32,UINT32,LPRECT32,LPPOINT32);
 #define    SetInternalWindowPos WINELIB_NAME(SetInternalWindowPos)
+INT16      SetMapMode16(HDC16,INT16);
+INT32      SetMapMode32(HDC32,INT32);
+#define    SetMapMode WINELIB_NAME(SetMapMode)
 COLORREF   SetPixel16(HDC16,INT16,INT16,COLORREF);
 COLORREF   SetPixel32(HDC32,INT32,INT32,COLORREF);
 #define    SetPixel WINELIB_NAME(SetPixel)
+INT16      SetPolyFillMode16(HDC16,INT16);
+INT32      SetPolyFillMode32(HDC32,INT32);
+#define    SetPolyFillMode WINELIB_NAME(SetPolyFillMode)
 BOOL16     SetProp16(HWND16,LPCSTR,HANDLE16);
 BOOL32     SetProp32A(HWND32,LPCSTR,HANDLE32);
 BOOL32     SetProp32W(HWND32,LPCWSTR,HANDLE32);
@@ -5545,6 +5653,12 @@
 void       SetRectEmpty16(LPRECT16);
 void       SetRectEmpty32(LPRECT32);
 #define    SetRectEmpty WINELIB_NAME(SetRectEmpty)
+INT16      SetRelAbs16(HDC16,INT16);
+INT32      SetRelAbs32(HDC32,INT32);
+#define    SetRelAbs WINELIB_NAME(SetRelAbs)
+INT16      SetROP216(HDC16,INT16);
+INT32      SetROP232(HDC32,INT32);
+#define    SetROP2 WINELIB_NAME(SetROP2)
 INT16      SetScrollInfo16(HWND16,INT16,const SCROLLINFO*,BOOL16);
 INT32      SetScrollInfo32(HWND32,INT32,const SCROLLINFO*,BOOL32);
 #define    SetScrollInfo WINELIB_NAME(SetScrollInfo)
@@ -5554,12 +5668,24 @@
 void       SetScrollRange16(HWND16,INT16,INT16,INT16,BOOL16);
 BOOL32     SetScrollRange32(HWND32,INT32,INT32,INT32,BOOL32);
 #define    SetScrollRange WINELIB_NAME(SetScrollRange)
+INT16      SetStretchBltMode16(HDC16,INT16);
+INT32      SetStretchBltMode32(HDC32,INT32);
+#define    SetStretchBltMode WINELIB_NAME(SetStretchBltMode)
 HWND16     SetSysModalWindow16(HWND16);
 #define    SetSysModalWindow32(hwnd) ((HWND32)0)
 #define    SetSysModalWindow WINELIB_NAME(SetSysModalWindow)
 UINT16     SetSystemTimer16(HWND16,UINT16,UINT16,TIMERPROC16);
 UINT32     SetSystemTimer32(HWND32,UINT32,UINT32,TIMERPROC32);
 #define    SetSystemTimer WINELIB_NAME(SetSystemTimer)
+UINT16     SetTextAlign16(HDC16,UINT16);
+UINT32     SetTextAlign32(HDC32,UINT32);
+#define    SetTextAlign WINELIB_NAME(SetTextAlign)
+INT16      SetTextCharacterExtra16(HDC16,INT16);
+INT32      SetTextCharacterExtra32(HDC32,INT32);
+#define    SetTextCharacterExtra WINELIB_NAME(SetTextCharacterExtra)
+INT16      SetTextJustification16(HDC16,INT16,INT16);
+BOOL32     SetTextJustification32(HDC32,INT32,INT32);
+#define    SetTextJustification WINELIB_NAME(SetTextJustification)
 UINT16     SetTimer16(HWND16,UINT16,UINT16,TIMERPROC16);
 UINT32     SetTimer32(HWND32,UINT32,UINT32,TIMERPROC32);
 #define    SetTimer WINELIB_NAME(SetTimer)
@@ -5734,6 +5860,8 @@
 INT32      lstrncmp32W(LPCWSTR,LPCWSTR,INT32);
 INT32      lstrncmpi32A(LPCSTR,LPCSTR,INT32);
 INT32      lstrncmpi32W(LPCWSTR,LPCWSTR,INT32);
+LPWSTR     lstrcpyAtoW(LPWSTR,LPCSTR);
+LPSTR      lstrcpyWtoA(LPSTR,LPCWSTR);
 LPWSTR     lstrcpynAtoW(LPWSTR,LPCSTR,INT32);
 LPSTR      lstrcpynWtoA(LPSTR,LPCWSTR,INT32);
 
@@ -5772,8 +5900,6 @@
 UINT       AnsiLowerBuff(LPSTR,UINT);
 SEGPTR     AnsiNext(SEGPTR);
 SEGPTR     AnsiPrev(SEGPTR,SEGPTR);
-INT        AnsiToOem(LPCSTR,LPSTR);
-void       AnsiToOemBuff(LPCSTR,LPSTR,UINT);
 UINT       AnsiUpperBuff(LPSTR,UINT);
 BOOL       AnyPopup(void);
 UINT       ArrangeIconicWindows(HWND);
@@ -5790,18 +5916,14 @@
 HMETAFILE16 CopyMetaFile(HMETAFILE16,LPCSTR);
 INT        CountClipboardFormats(void);
 INT        CountVoiceNotes(INT);
-HDC16      CreateCompatibleDC(HDC16);
 HCURSOR16  CreateCursor(HINSTANCE16,INT,INT,INT,INT,const BYTE*,const BYTE*);
 HGLOBAL16  CreateCursorIconIndirect(HINSTANCE16,CURSORICONINFO*,const BYTE*,const BYTE*);
-HBITMAP16  CreateDIBitmap(HDC16,BITMAPINFOHEADER*,DWORD,LPVOID,BITMAPINFO*,UINT);
-HDC16      CreateIC(LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*);
 HICON16    CreateIcon(HINSTANCE16,INT,INT,BYTE,BYTE,const BYTE*,const BYTE*);
 HMENU16    CreateMenu(void);
 HPALETTE16 CreatePalette(const LOGPALETTE*);
 HMENU16    CreatePopupMenu(void);
 HDWP16     DeferWindowPos(HDWP16,HWND,HWND,INT,INT,INT,INT,UINT);
 ATOM       DeleteAtom(ATOM);
-BOOL       DeleteDC(HDC16);
 BOOL       DeleteMenu(HMENU16,UINT,UINT);
 BOOL       DestroyCursor(HCURSOR16);
 BOOL       DestroyIcon(HICON16);
@@ -5834,21 +5956,13 @@
 DWORD      GetAspectRatioFilter(HDC16);
 int        GetAsyncKeyState(int);
 WORD       GetAtomName(ATOM,LPSTR,short);
-COLORREF   GetBkColor(HDC16);
-WORD       GetBkMode(HDC16);
-DWORD      GetBrushOrg(HDC16);
-BOOL       GetCharABCWidths(HDC16,UINT,UINT,LPABC16);
-BOOL       GetCharWidth(HDC16,WORD,WORD,LPINT16);
 HANDLE16   GetClipboardData(WORD);
 int        GetClipboardFormatName(WORD,LPSTR,short);
 HWND       GetClipboardOwner(void);
 HWND       GetClipboardViewer(void);
 HBRUSH16   GetControlBrush(HWND,HDC16,WORD);
-DWORD      GetCurrentPosition(HDC16);
 DWORD      GetCurrentTime(void);
 HCURSOR16  GetCursor(void);
-HDC16      GetDCState(HDC16);
-int        GetDIBits(HDC16,HBITMAP16,WORD,WORD,LPSTR,LPBITMAPINFO,WORD);
 SEGPTR     GetDOSEnvironment(void);
 int        GetDeviceCaps(HDC16,WORD);
 DWORD      GetDialogBaseUnits(void);
@@ -5865,7 +5979,6 @@
 void       GetKeyboardState(BYTE*);
 int        GetKeyboardType(int);
 HWND       GetLastActivePopup(HWND);
-WORD       GetMapMode(HDC16);
 HMENU16    GetMenu(HWND);
 DWORD      GetMenuCheckMarkDimensions(void);
 INT        GetMenuItemCount(HMENU16);
@@ -5885,13 +5998,9 @@
 HWND       GetNextWindow(HWND,WORD);
 HWND       GetOpenClipboardWindow(void);
 WORD       GetPaletteEntries(HPALETTE16,WORD,WORD,LPPALETTEENTRY);
-WORD       GetPolyFillMode(HDC16);
 int        GetPriorityClipboardFormat(WORD*,short);
 DWORD      GetQueueStatus(UINT);
 BOOL       GetRasterizerCaps(LPRASTERIZER_STATUS,UINT);
-WORD       GetROP2(HDC16);
-WORD       GetRelAbs(HDC16);
-WORD       GetStretchBltMode(HDC16);
 HMENU16    GetSubMenu(HMENU16,short);
 HMENU16    GetSystemMenu(HWND,BOOL);
 int        GetSystemMetrics(WORD);
@@ -5899,20 +6008,12 @@
 WORD       GetSystemPaletteUse(HDC16);
 DWORD      GetTabbedTextExtent(HDC16,LPSTR,int,int,LPINT16);
 BYTE       GetTempDrive(BYTE);
-WORD       GetTextAlign(HDC16);
-short      GetTextCharacterExtra(HDC16);
-COLORREF   GetTextColor(HDC16);
-DWORD      GetTextExtent(HDC16,LPCSTR,short);
 LPINT16    GetThresholdEvent(void);
 int        GetThresholdStatus(void);
 HWND       GetTopWindow(HWND);
-DWORD      GetViewportExt(HDC16);
-DWORD      GetViewportOrg(HDC16);
 BOOL       GetWinDebugInfo(LPWINDEBUGINFO,UINT);
 LONG       GetWinFlags(void);
 HWND       GetWindow(HWND,WORD);
-DWORD      GetWindowExt(HDC16);
-DWORD      GetWindowOrg(HDC16);
 ATOM       GlobalDeleteAtom(ATOM);
 void       GlobalFix(HGLOBAL16);
 BOOL16     GlobalUnWire(HGLOBAL16);
@@ -5922,7 +6023,6 @@
 BOOL       HiliteMenuItem(HWND,HMENU16,UINT,UINT);
 BOOL       InSendMessage(void);
 WORD       InitAtomTable(WORD);
-HRGN32     InquireVisRgn(HDC16);
 void       InvalidateRgn(HWND32,HRGN32,BOOL32);
 BOOL       IsChild(HWND,HWND);
 BOOL       IsClipboardFormatAvailable(WORD);
@@ -5941,8 +6041,6 @@
 void       MessageBeep(WORD);
 BOOL       MoveWindow(HWND,short,short,short,short,BOOL);
 DWORD      OemKeyScan(WORD);
-BOOL       OemToAnsi(LPCSTR,LPSTR);
-void       OemToAnsiBuff(LPCSTR,LPSTR,INT);
 BOOL       OpenClipboard(HWND);
 BOOL       OpenIcon(HWND);
 int        OpenSound(void);
@@ -5963,14 +6061,10 @@
 BOOL       RemoveFontResource(LPSTR);
 BOOL       RemoveMenu(HMENU16,UINT,UINT);
 void       ReplyMessage(LRESULT);
-HDC16      ResetDC(HDC16,LPVOID);
 BOOL       ResizePalette(HPALETTE16,UINT);
-BOOL       RestoreDC(HDC16,short);
-int        SaveDC(HDC16);
 void       ScrollChildren(HWND,UINT,WPARAM16,LPARAM);
 HPALETTE16 SelectPalette(HDC16,HPALETTE16,BOOL);
 HWND       SetActiveWindow(HWND);
-WORD       SetBkMode(HDC16,WORD);
 HANDLE16   SetClipboardData(WORD,HANDLE16);
 HWND       SetClipboardViewer(HWND);
 void       SetConvertHook(BOOL);
@@ -5978,13 +6072,11 @@
 BOOL32     SetCurrentDirectory(LPCSTR);
 HCURSOR16  SetCursor(HCURSOR16);
 void       SetCursorPos(short,short);
-void       SetDCState(HDC16,HDC16);
 void       SetDoubleClickTime(WORD);
 int        SetEnvironment(LPCSTR,LPCSTR,WORD);
 UINT       SetErrorMode(UINT);
 WORD       SetHookFlags(HDC16,WORD);
 void       SetKeyboardState(BYTE*);
-WORD       SetMapMode(HDC16,WORD);
 DWORD      SetMapperFlags(HDC16,DWORD);
 BOOL       SetMenu(HWND,HMENU16);
 BOOL       SetMenuItemBitmaps(HMENU16,UINT,UINT,HBITMAP16,HBITMAP16);
@@ -5992,18 +6084,11 @@
 HMETAFILE16 SetMetaFileBits(HGLOBAL16);
 WORD       SetPaletteEntries(HPALETTE16,WORD,WORD,LPPALETTEENTRY);
 HWND       SetParent(HWND,HWND);
-WORD       SetPolyFillMode(HDC16,WORD);
-WORD       SetROP2(HDC16,WORD);
-WORD       SetRelAbs(HDC16,WORD);
 FARPROC16  SetResourceHandler(HINSTANCE16,LPSTR,FARPROC16);
 int        SetSoundNoise(int,int);
-WORD       SetStretchBltMode(HDC16,WORD);
 LONG       SetSwapAreaSize(WORD);
 void       SetSysColors(int,LPINT16,COLORREF*);
 WORD       SetSystemPaletteUse(HDC16,WORD);
-WORD       SetTextAlign(HDC16,WORD);
-short      SetTextCharacterExtra(HDC16,short);
-short      SetTextJustification(HDC16,short,short);
 int        SetVoiceAccent(int,int,int,int,int);
 int        SetVoiceEnvelope(int,int,int);
 int        SetVoiceNote(int,int,int,int);
diff --git a/library/libres.c b/library/libres.c
index 521f7c2..ebe155d 100644
--- a/library/libres.c
+++ b/library/libres.c
@@ -7,9 +7,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "libres.h"
+#include "heap.h"
 #include "windows.h"
 #include "xmalloc.h"
-#include "string32.h"
 
 typedef struct RLE
 {
@@ -86,16 +86,15 @@
   int nameid=0,typeid;
   ResListE* ResBlock;
   const struct resource* const * Res;
-  LPSTR nameA, typeA;
 
   if(HIWORD(name))
   {
     if(*name=='#')
     {
-      nameA = STRING32_DupUniToAnsi(name);
-      nameid=atoi(nameA+1);
-      free(nameA);
-      name=NULL;
+        LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
+        nameid = atoi(nameA+1);
+        HeapFree( GetProcessHeap(), 0, nameA );
+        name=NULL;
     }
   }
   else
@@ -107,9 +106,9 @@
   {
     if(*type=='#')
     {
-      typeA = STRING32_DupUniToAnsi(type);
-      typeid=atoi(typeA+1);
-      free(typeA);
+        LPSTR typeA = HEAP_strdupWtoA( GetProcessHeap(), 0, type );
+        typeid=atoi(typeA+1);
+        HeapFree( GetProcessHeap(), 0, typeA );
     }
     else
     {
diff --git a/loader/main.c b/loader/main.c
index 3bd649e..b14f691 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -166,10 +166,17 @@
 int main(int argc, char *argv[] )
 {
     extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
+    extern char * DEBUG_argv0;
 
     int i;
     HINSTANCE16 handle;
 
+    /*
+     * Save this so that the internal debugger can get a hold of it if
+     * it needs to.
+     */
+    DEBUG_argv0 = argv[0];
+
     if (!MAIN_WineInit( &argc, argv )) return 1;
     if (!MAIN_Init()) return 1;
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index a99e627..b8c321e 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -114,7 +114,7 @@
 	  daddr.off=load_addr+*functions;
 	  function++;
       }
-      DEBUG_AddSymbol(buffer,&daddr);
+      DEBUG_AddSymbol(buffer,&daddr, NULL);
   }
 }
 
@@ -525,7 +525,11 @@
 
 	if(pe->pe_header->opt_coff.DataDirectory
 		[IMAGE_FILE_DEBUG_DIRECTORY].Size)
-		dprintf_win32(stdnimp,"Debug directory ignored\n");
+	  {
+	    DEBUG_RegisterDebugInfo(fd, pe, load_addr, 
+			pe->pe_header->opt_coff.DataDirectory[IMAGE_FILE_DEBUG_DIRECTORY].Virtual_address,
+			pe->pe_header->opt_coff.DataDirectory[IMAGE_FILE_DEBUG_DIRECTORY].Size);
+	  }
 
 	if(pe->pe_header->opt_coff.DataDirectory
 		[IMAGE_FILE_DESCRIPTION_STRING].Size)
@@ -556,15 +560,16 @@
 				pe->pe_seg[i].Name
 			);
 			daddr.off=load_addr+pe->pe_seg[i].Virtual_Address;
-			DEBUG_AddSymbol(buffer,&daddr);
+			DEBUG_AddSymbol(buffer,&daddr, NULL);
 		}
 		/* add entry point */
 		sprintf(buffer,"%s.EntryPoint",((char*)load_addr)+pe->pe_export->Name);
 		daddr.off=load_addr+pe->pe_header->opt_coff.AddressOfEntryPoint;
-		DEBUG_AddSymbol(buffer,&daddr);
+		DEBUG_AddSymbol(buffer,&daddr, NULL);
 		/* add start of DLL */
 		daddr.off=load_addr;
-		DEBUG_AddSymbol(((char*)load_addr)+pe->pe_export->Name,&daddr);
+		DEBUG_AddSymbol(((char*)load_addr)+pe->pe_export->Name,&daddr,
+				NULL);
 	}
         return pe;
 }
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index c5a6c69..74b74bc 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -17,6 +17,7 @@
 #include "windows.h"
 #include "pe_image.h"
 #include "module.h"
+#include "heap.h"
 #include "handle32.h"
 #include "libres.h"
 #include "resource32.h"
@@ -24,7 +25,6 @@
 #include "neexe.h"
 #include "accel.h"
 #include "xmalloc.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -102,13 +102,13 @@
 	PIMAGE_RESOURCE_DIRECTORY	ret;
 
 	if (HIWORD((DWORD)name))
-		xname	= STRING32_DupAnsiToUni(name);
+		xname	= HEAP_strdupAtoW( GetProcessHeap(), 0, name );
 	else
 		xname	= (LPWSTR)name;
 
 	ret=GetResDirEntryW(resdirptr,xname,root);
 	if (HIWORD((DWORD)name))
-		free(xname);
+            HeapFree( GetProcessHeap(), 0, xname );
 	return ret;
 }
 
diff --git a/loader/resource.c b/loader/resource.c
index 200406f..3ae6821 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -16,6 +16,7 @@
 #include "windows.h"
 #include "gdi.h"
 #include "global.h"
+#include "heap.h"
 #include "neexe.h"
 #include "accel.h"
 #include "module.h"
@@ -23,8 +24,6 @@
 #include "stddebug.h"
 #include "debug.h"
 #include "libres.h"
-#include "string32.h"
-#include "xmalloc.h"
 
 #define PrintId(name) \
     if (HIWORD((DWORD)name)) \
@@ -85,13 +84,17 @@
     LPWSTR xname,xtype;
     HANDLE32 ret;
 
-    if (HIWORD((DWORD)name)) xname = STRING32_DupAnsiToUni(name);
-    else xname = (LPWSTR)name;
-    if (HIWORD((DWORD)type)) xtype = STRING32_DupAnsiToUni(type);
-    else xtype = (LPWSTR)type;
-    ret = FindResourceEx32W(hModule,xname,xtype,lang);
-    if (HIWORD((DWORD)name)) free(xname);
-    if (HIWORD((DWORD)type)) free(xtype);
+    if (HIWORD((DWORD)name))
+        xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+    else
+        xname = (LPWSTR)name;
+    if (HIWORD((DWORD)type))
+        xtype = HEAP_strdupAtoW( GetProcessHeap(), 0, type);
+    else
+        xtype = (LPWSTR)type;
+    ret = FindResourceEx32W( hModule, xname, xtype, lang );
+    if (HIWORD((DWORD)name)) HeapFree( GetProcessHeap(), 0, xname );
+    if (HIWORD((DWORD)type)) HeapFree( GetProcessHeap(), 0, xtype );
     return ret;
 }
 
@@ -494,12 +497,11 @@
 	LPWSTR	 uni;
 	HACCEL32 result;
 	if (HIWORD(lpTableName))
-		uni=STRING32_DupAnsiToUni(lpTableName);
+		uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
 	else
-		uni=(LPWSTR)lpTableName;
-	result=LoadAccelerators32W(instance,uni);
-	if (HIWORD(uni))
-		free(uni);
+		uni = (LPWSTR)lpTableName;
+	result = LoadAccelerators32W(instance,uni);
+	if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
 	return result;
 }
 
@@ -607,13 +609,15 @@
 INT32
 LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen)
 {
-    LPWSTR buffer2 = buffer?(LPWSTR)xmalloc(buflen*2):NULL;
-    INT32 retval = LoadString32W(instance,resource_id,buffer2,buflen);
+    INT32 retval;
+    LPWSTR buffer2 = NULL;
+    if (buffer) buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
+    retval = LoadString32W(instance,resource_id,buffer2,buflen);
 
-    if (!retval) return 0;
-    if (buffer) {
-	STRING32_UniToAnsi(buffer,buffer2);
-	free(buffer2);
+    if (buffer)
+    {
+        lstrcpynWtoA( buffer, buffer2, buflen );
+	HeapFree( GetProcessHeap(), 0, buffer2 );
     }
     return retval;
 }
@@ -712,16 +716,17 @@
 /**********************************************************************
  *	LoadMessage32W	(internal)
  */
-INT32
-LoadMessage32W(
-	HINSTANCE32 instance,UINT32 id,WORD lang,LPWSTR buffer,int buflen
-) {
-    LPSTR buffer2 = buffer?(LPSTR)xmalloc(buflen):NULL;
-    INT32 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
-
-    if (buffer) {
-	STRING32_AnsiToUni(buffer,buffer2);
-	free(buffer2);
+INT32 LoadMessage32W( HINSTANCE32 instance, UINT32 id, WORD lang,
+                      LPWSTR buffer, int buflen )
+{
+    INT32 retval;
+    LPSTR buffer2 = NULL;
+    if (buffer) buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
+    retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
+    if (buffer)
+    {
+        lstrcpynAtoW( buffer, buffer2, buflen );
+	HeapFree( GetProcessHeap(), 0, buffer2 );
     }
     return retval;
 }
diff --git a/loader/signal.c b/loader/signal.c
index a693c7d..9d11530 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -97,17 +97,8 @@
  * 
  * wait4 terminated child processes
  */
-#ifdef linux
-static void SIGNAL_child(int signal, SIGCONTEXT context_struct)
+static void SIGNAL_child(void)
 {
-    SIGCONTEXT *context = &context_struct;
-#elif defined(__svr4__) || defined(_SCO_DS)
-static void SIGNAL_child(int signal, void *siginfo, SIGCONTEXT *context)
-{
-#else
-static void SIGNAL_child(int signal, int code, SIGCONTEXT *context)
-{
-#endif
    wait4( 0, NULL, WNOHANG, NULL);
 }
 
diff --git a/memory/heap.c b/memory/heap.c
index 4e3d1ec..6924de4 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -1225,3 +1225,39 @@
     lstrcpy32W( p, str );
     return p;
 }
+
+
+/***********************************************************************
+ *           HEAP_strdupAtoW
+ */
+LPWSTR HEAP_strdupAtoW( HANDLE32 heap, DWORD flags, LPCSTR str )
+{
+    LPWSTR ret;
+
+    if (!str) return NULL;
+    if (!(ret = HeapAlloc( heap, flags, (lstrlen32A(str)+1) * sizeof(WCHAR) )))
+    {
+        fprintf( stderr, "Virtual memory exhausted.\n" );
+        exit(1);
+    }
+    lstrcpyAtoW( ret, str );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           HEAP_strdupWtoA
+ */
+LPSTR HEAP_strdupWtoA( HANDLE32 heap, DWORD flags, LPCWSTR str )
+{
+    LPSTR ret;
+
+    if (!str) return NULL;
+    if (!(ret = HeapAlloc( heap, flags, lstrlen32W(str) + 1 )))
+    {
+        fprintf( stderr, "Virtual memory exhausted.\n" );
+        exit(1);
+    }
+    lstrcpyWtoA( ret, str );
+    return ret;
+}
diff --git a/memory/string.c b/memory/string.c
index c4b9ad5..fd8d9ea 100644
--- a/memory/string.c
+++ b/memory/string.c
@@ -10,6 +10,45 @@
 #include "windows.h"
 #include "ldt.h"
 
+static const BYTE STRING_Oem2Ansi[256] =
+"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\244"
+"\020\021\022\023\266\247\026\027\030\031\032\033\034\035\036\037"
+"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
+"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
+"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
+"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
+"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
+"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
+"\307\374\351\342\344\340\345\347\352\353\350\357\356\354\304\305"
+"\311\346\306\364\366\362\373\371\377\326\334\242\243\245\120\203"
+"\341\355\363\372\361\321\252\272\277\137\254\275\274\241\253\273"
+"\137\137\137\246\246\246\246\053\053\246\246\053\053\053\053\053"
+"\053\055\055\053\055\053\246\246\053\053\055\055\246\055\053\055"
+"\055\055\055\053\053\053\053\053\053\053\053\137\137\246\137\137"
+"\137\337\137\266\137\137\265\137\137\137\137\137\137\137\137\137"
+"\137\261\137\137\137\137\367\137\260\225\267\137\156\262\137\137";
+
+static const BYTE STRING_Ansi2Oem[256] =
+"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"
+"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
+"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
+"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
+"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
+"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
+"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
+"\200\201\054\237\054\137\375\374\210\045\123\074\117\215\216\217"
+"\220\140\047\042\042\371\055\137\230\231\163\076\157\235\236\131"
+"\040\255\233\234\017\235\335\025\042\143\246\256\252\055\162\137"
+"\370\361\375\063\047\346\024\372\054\061\247\257\254\253\137\250"
+"\101\101\101\101\216\217\222\200\105\220\105\105\111\111\111\111"
+"\104\245\117\117\117\117\231\170\117\125\125\125\232\131\137\341"
+"\205\240\203\141\204\206\221\207\212\202\210\211\215\241\214\213"
+"\144\244\225\242\223\157\224\366\157\227\243\226\201\171\137\230";
+
+#define OEM_TO_ANSI(ch) (STRING_Oem2Ansi[(unsigned char)(ch)])
+#define ANSI_TO_OEM(ch) (STRING_Ansi2Oem[(unsigned char)(ch)])
+
 
 /***********************************************************************
  *           hmemcpy   (KERNEL.348)
@@ -316,6 +355,28 @@
 
 
 /***********************************************************************
+ *           lstrcpyAtoW   (Not a Windows API)
+ */
+LPWSTR lstrcpyAtoW( LPWSTR dst, LPCSTR src )
+{
+    register LPWSTR p = dst;
+    while ((*p++ = (WCHAR)(unsigned char)*src++));
+    return dst;
+}
+
+
+/***********************************************************************
+ *           lstrcpyWtoA   (Not a Windows API)
+ */
+LPSTR lstrcpyWtoA( LPSTR dst, LPCWSTR src )
+{
+    register LPSTR p = dst;
+    while ((*p++ = (CHAR)*src++));
+    return dst;
+}
+
+
+/***********************************************************************
  *           lstrcpynAtoW   (Not a Windows API)
  */
 LPWSTR lstrcpynAtoW( LPWSTR dst, LPCSTR src, INT32 n )
@@ -364,3 +425,122 @@
 {
     memset( ptr, 0, len );
 }
+
+
+/***********************************************************************
+ *           AnsiToOem16   (KEYBOARD.5)
+ */
+INT16 AnsiToOem16( LPCSTR s, LPSTR d )
+{
+    CharToOem32A( s, d );
+    return -1;
+}
+
+
+/***********************************************************************
+ *           OemToAnsi16   (KEYBOARD.6)
+ */
+INT16 OemToAnsi16( LPCSTR s, LPSTR d )
+{
+    OemToChar32A( s, d );
+    return -1;
+}
+
+
+/***********************************************************************
+ *           AnsiToOemBuff16   (KEYBOARD.134)
+ */
+void AnsiToOemBuff16( LPCSTR s, LPSTR d, UINT16 len )
+{
+    CharToOemBuff32A( s, d, len ? len : 65536 );
+}
+
+
+/***********************************************************************
+ *           OemToAnsiBuff16   (KEYBOARD.135)
+ */
+void OemToAnsiBuff16( LPCSTR s, LPSTR d, UINT16 len )
+{
+    OemToCharBuff32A( s, d, len ? len : 65536 );
+}
+
+
+/***********************************************************************
+ *           CharToOem32A   (USER32.36)
+ */
+BOOL32 CharToOem32A( LPCSTR s, LPSTR d )
+{
+    if (!s || !d) return TRUE;
+    while ((*d++ = ANSI_TO_OEM(*s++)));
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CharToOemBuff32A   (USER32.37)
+ */
+BOOL32 CharToOemBuff32A( LPCSTR s, LPSTR d, DWORD len )
+{
+    while (len--) *d++ = ANSI_TO_OEM(*s++);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CharToOemBuff32W   (USER32.38)
+ */
+BOOL32 CharToOemBuff32W( LPCWSTR s, LPSTR d, DWORD len )
+{
+    while (len--) *d++ = ANSI_TO_OEM(*s++);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CharToOem32W   (USER32.39)
+ */
+BOOL32 CharToOem32W( LPCWSTR s, LPSTR d )
+{
+    while ((*d++ = ANSI_TO_OEM(*s++)));
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OemToChar32A   (USER32.401)
+ */
+BOOL32 OemToChar32A( LPCSTR s, LPSTR d )
+{
+    while ((*d++ = OEM_TO_ANSI(*s++)));
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OemToCharBuff32A   (USER32.402)
+ */
+BOOL32 OemToCharBuff32A( LPCSTR s, LPSTR d, DWORD len )
+{
+    while (len--) *d++ = OEM_TO_ANSI(*s++);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OemToCharBuff32W   (USER32.403)
+ */
+BOOL32 OemToCharBuff32W( LPCSTR s, LPWSTR d, DWORD len )
+{
+    while (len--) *d++ = (WCHAR)OEM_TO_ANSI(*s++);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OemToChar32W   (USER32.404)
+ */
+BOOL32 OemToChar32W( LPCSTR s, LPWSTR d )
+{
+    while ((*d++ = (WCHAR)OEM_TO_ANSI(*s++)));
+    return TRUE;
+}
diff --git a/misc/clipboard.c b/misc/clipboard.c
index 47304e3..e3d5a61 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -17,12 +17,12 @@
 #include <X11/Xatom.h>
 #include "windows.h"
 #include "win.h"
+#include "heap.h"
 #include "message.h"
 #include "clipboard.h"
 #include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "string32.h"
 
 #define  CF_REGFORMATBASE 	0xC000
 
@@ -391,9 +391,9 @@
   if( lpstrT )
   {
     if( lpSource->wFormatID == CF_TEXT )
-	AnsiToOemBuff(lpstrS, lpstrT, size);
+	CharToOemBuff32A(lpstrS, lpstrT, size);
     else
-	OemToAnsiBuff(lpstrS, lpstrT, size);
+	OemToCharBuff32A(lpstrS, lpstrT, size);
     dprintf_clipboard(stddeb,"\tgot %s\n", lpstrT);
     return TRUE;
   }
@@ -585,11 +585,9 @@
  */
 UINT32 RegisterClipboardFormat32W( LPCWSTR formatName )
 {
-    LPSTR aFormat;
-    UINT32 ret;
-    aFormat = STRING32_DupUniToAnsi(formatName);
-    ret = RegisterClipboardFormat32A(aFormat);
-    free(aFormat);
+    LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
+    UINT32 ret = RegisterClipboardFormat32A( aFormat );
+    HeapFree( GetProcessHeap(), 0, aFormat );
     return ret;
 }
 
diff --git a/misc/comm.c b/misc/comm.c
index 613957b..ea2735d 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -21,11 +21,11 @@
 
 #include "windows.h"
 #include "comm.h"
+#include "heap.h"
 #include "options.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "handle32.h"
-#include "string32.h"
 
 int commerror = 0, eventmask = 0;
 
@@ -363,9 +363,9 @@
 	BOOL32	ret;
 
 	dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
-	devidA = STRING32_DupUniToAnsi(devid);
+	devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
 	ret=BuildCommDCBAndTimeouts32A(devidA,lpdcb,lptimeouts);
-	free(devidA);
+        HeapFree( GetProcessHeap(), 0, devidA );
 	return ret;
 }
 
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 7e06077..42845d5 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -213,7 +213,7 @@
     HBRUSH32 hBrush;
     HBITMAP16 hBitmap, hPrevBitmap;
     BITMAP16 bm;
-    HDC16 hMemDC;
+    HDC32 hMemDC;
 
     if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
     {
@@ -253,12 +253,12 @@
 	GetObject16( hBitmap, sizeof(bm), &bm );
 	TextOut16(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth, 
                   lpdis->rcItem.top, str, strlen(str));
-	hMemDC = CreateCompatibleDC(lpdis->hDC);
+	hMemDC = CreateCompatibleDC32(lpdis->hDC);
 	hPrevBitmap = SelectObject32(hMemDC, hBitmap);
 	BitBlt32(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
                  bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
 	SelectObject32(hMemDC, hPrevBitmap);
-	DeleteDC(hMemDC);
+	DeleteDC32(hMemDC);
 	if (lpdis->itemState != 0) InvertRect16(lpdis->hDC, &lpdis->rcItem);
         SEGPTR_FREE(str);
 	return TRUE;
@@ -282,12 +282,12 @@
 	GetObject16( hBitmap, sizeof(bm), &bm );
 	TextOut16(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth, 
                   lpdis->rcItem.top, str, strlen(str));
-	hMemDC = CreateCompatibleDC(lpdis->hDC);
+	hMemDC = CreateCompatibleDC32(lpdis->hDC);
 	hPrevBitmap = SelectObject32(hMemDC, hBitmap);
 	BitBlt32( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
                   bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
 	SelectObject32(hMemDC, hPrevBitmap);
-	DeleteDC(hMemDC);
+	DeleteDC32(hMemDC);
 	if (lpdis->itemState != 0) InvertRect16(lpdis->hDC, &lpdis->rcItem);
         SEGPTR_FREE(str);
 	return TRUE;
@@ -1595,7 +1595,7 @@
 
  GetClientRect16(hwnd,&client);
  hdc=GetDC32(hwnd);
- lpp->hdcMem = CreateCompatibleDC(hdc);
+ lpp->hdcMem = CreateCompatibleDC32(hdc);
  lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
  SelectObject32(lpp->hdcMem,lpp->hbmMem);
 
@@ -2153,7 +2153,7 @@
 	  case WM_INITDIALOG:
 	                return CC_WMInitDialog(hDlg,wParam,lParam);
 	  case WM_NCDESTROY:
-	                DeleteDC(lpp->hdcMem); 
+	                DeleteDC32(lpp->hdcMem); 
 	                DeleteObject32(lpp->hbmMem); 
 	                free(lpp);
 	                SetWindowLong32A(hDlg, DWL_USER, 0L); /* we don't need it anymore */
@@ -2579,12 +2579,12 @@
 		  /* FIXME: draw bitmap if truetype usage */
 		if (nFontType&TRUETYPE_FONTTYPE)
 		{
-		  hMemDC = CreateCompatibleDC(lpdi->hDC);
+		  hMemDC = CreateCompatibleDC32(lpdi->hDC);
 		  hBitmap = SelectObject32(hMemDC, hBitmapTT);
 		  BitBlt32(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top,
                            bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
 		  SelectObject32(hMemDC, hBitmap);
-		  DeleteDC(hMemDC);
+		  DeleteDC32(hMemDC);
 		}
 #endif
 		break;
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 5a35026..0d83094 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -22,7 +22,6 @@
 #include "xmalloc.h"
 #include "heap.h"
 #include "crtdll.h"
-#include "string32.h"
 
 UINT32 CRTDLL_argc_dll;         /* CRTDLL.23 */
 LPSTR *CRTDLL_argv_dll;         /* CRTDLL.24 */
diff --git a/misc/lstr.c b/misc/lstr.c
index ece2f03..82d68b0 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -23,42 +23,6 @@
 #define ToLower(c)	tolower(c)
 
 
-static const BYTE Oem2Ansi[256] =
-"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\244"
-"\020\021\022\023\266\247\026\027\030\031\032\033\034\035\036\037"
-"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
-"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
-"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
-"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
-"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
-"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
-"\307\374\351\342\344\340\345\347\352\353\350\357\356\354\304\305"
-"\311\346\306\364\366\362\373\371\377\326\334\242\243\245\120\203"
-"\341\355\363\372\361\321\252\272\277\137\254\275\274\241\253\273"
-"\137\137\137\246\246\246\246\053\053\246\246\053\053\053\053\053"
-"\053\055\055\053\055\053\246\246\053\053\055\055\246\055\053\055"
-"\055\055\055\053\053\053\053\053\053\053\053\137\137\246\137\137"
-"\137\337\137\266\137\137\265\137\137\137\137\137\137\137\137\137"
-"\137\261\137\137\137\137\367\137\260\225\267\137\156\262\137\137";
-
-static const BYTE Ansi2Oem[256] =
-"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"
-"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
-"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
-"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
-"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
-"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
-"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
-"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
-"\200\201\054\237\054\137\375\374\210\045\123\074\117\215\216\217"
-"\220\140\047\042\042\371\055\137\230\231\163\076\157\235\236\131"
-"\040\255\233\234\017\235\335\025\042\143\246\256\252\055\162\137"
-"\370\361\375\063\047\346\024\372\054\061\247\257\254\253\137\250"
-"\101\101\101\101\216\217\222\200\105\220\105\105\111\111\111\111"
-"\104\245\117\117\117\117\231\170\117\125\125\125\232\131\137\341"
-"\205\240\203\141\204\206\221\207\212\202\210\211\215\241\214\213"
-"\144\244\225\242\223\157\224\366\157\227\243\226\201\171\137\230";
-
 /* Funny to divide them between user and kernel. */
 
 /* IsCharAlpha USER 433 */
@@ -203,45 +167,6 @@
 }
 
 
-/* AnsiToOem Keyboard.5 */
-INT AnsiToOem(LPCSTR lpAnsiStr, LPSTR lpOemStr)
-{
-    dprintf_keyboard(stddeb, "AnsiToOem: %s\n", lpAnsiStr);
-    while(*lpAnsiStr){
-	*lpOemStr++=Ansi2Oem[(unsigned char)(*lpAnsiStr++)];
-    }
-    *lpOemStr = 0;
-    return -1;
-}
-
-/* OemToAnsi Keyboard.6 */
-BOOL OemToAnsi(LPCSTR lpOemStr, LPSTR lpAnsiStr)
-{
-    dprintf_keyboard(stddeb, "OemToAnsi: %s\n", lpOemStr);
-    while(*lpOemStr){
-	*lpAnsiStr++=Oem2Ansi[(unsigned char)(*lpOemStr++)];
-    }
-    *lpAnsiStr = 0;
-    return -1;
-}
-
-/* AnsiToOemBuff Keyboard.134 */
-void AnsiToOemBuff(LPCSTR lpAnsiStr, LPSTR lpOemStr, UINT nLength)
-{
-  int i;
-  for(i=0;i<nLength;i++)
-    lpOemStr[i]=Ansi2Oem[(unsigned char)(lpAnsiStr[i])];
-}
-
-/* OemToAnsi Keyboard.135 */
-void OemToAnsiBuff(LPCSTR lpOemStr, LPSTR lpAnsiStr, INT nLength)
-{
-  int i;
-  for(i=0;i<nLength;i++)
-    lpAnsiStr[i]=Oem2Ansi[(unsigned char)(lpOemStr[i])];
-}
-
-
 /***********************************************************************
  *           OutputDebugString   (KERNEL.115)
  */
@@ -518,7 +443,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaW   (USER32.334)
+ *           IsCharLower32A   (USER32.334)
  * FIXME: handle current locale
  */
 BOOL32 IsCharLower32A(CHAR x)
@@ -527,7 +452,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaW   (USER32.335)
+ *           IsCharLower32W   (USER32.335)
  * FIXME: handle current locale
  */
 BOOL32 IsCharLower32W(WCHAR x)
@@ -536,7 +461,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaW   (USER32.336)
+ *           IsCharUpper32A   (USER32.336)
  * FIXME: handle current locale
  */
 BOOL32 IsCharUpper32A(CHAR x)
@@ -545,7 +470,7 @@
 }
 
 /***********************************************************************
- *           IsCharAlphaW   (USER32.337)
+ *           IsCharUpper32W   (USER32.337)
  * FIXME: handle current locale
  */
 BOOL32 IsCharUpper32W(WCHAR x)
@@ -554,86 +479,6 @@
 }
 
 /***********************************************************************
- *           CharToOemA   (USER32.36)
- */
-BOOL32 CharToOem32A(LPSTR s,LPSTR d)
-{
-    if (!s || !d)
-    	return TRUE;
-    AnsiToOem(s,d);
-    return TRUE;
-}
-
-/***********************************************************************
- *           CharToOemBuffA   (USER32.37)
- */
-BOOL32 CharToOemBuff32A(LPSTR s,LPSTR d,DWORD len)
-{
-    AnsiToOemBuff(s,d,len);
-    return TRUE;
-}
-
-/***********************************************************************
- *           CharToOemBuffW   (USER32.38)
- */
-BOOL32 CharToOemBuff32W(LPCWSTR s,LPSTR d,DWORD len)
-{
-    LPSTR	x=STRING32_DupUniToAnsi(s);
-    AnsiToOemBuff(x,d,len);
-    return TRUE;
-}
-
-/***********************************************************************
- *           CharToOemW   (USER32.39)
- */
-BOOL32 CharToOem32W(LPCWSTR s,LPSTR d)
-{
-    LPSTR	x=STRING32_DupUniToAnsi(s);
-    AnsiToOem(x,d);
-    return TRUE;
-}
-
-/***********************************************************************
- *           OemToCharA   (USER32.401)
- */
-BOOL32 OemToChar32A(LPSTR s,LPSTR d)
-{
-    OemToAnsi(s,d);
-    return TRUE;
-}
-
-/***********************************************************************
- *           OemToCharBuffA   (USER32.402)
- */
-BOOL32 OemToCharBuff32A(LPSTR s,LPSTR d,DWORD len)
-{
-    OemToAnsiBuff(s,d,len);
-    return TRUE;
-}
-
-/***********************************************************************
- *           OemToCharBuffW   (USER32.403)
- */
-BOOL32 OemToCharBuff32W(LPCSTR s,LPWSTR d,DWORD len)
-{
-    LPSTR x=(char*)xmalloc(strlen(s));
-    OemToAnsiBuff((LPSTR)s,x,len);
-    STRING32_AnsiToUni(d,x);
-    return TRUE;
-}
-
-/***********************************************************************
- *           OemToCharW   (USER32.404)
- */
-BOOL32 OemToChar32W(LPCSTR s,LPWSTR d)
-{
-    LPSTR x=(char*)xmalloc(strlen(s));
-    OemToAnsi((LPSTR)s,x);
-    STRING32_AnsiToUni(d,x);
-    return TRUE;
-}
-
-/***********************************************************************
  *           FormatMessageA   (KERNEL32.138) Library Version
  * FIXME: missing wrap,FROM_SYSTEM message-loading,
  */
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 1c47990..a48fa0d 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -16,16 +16,13 @@
 #include <sys/stat.h>
 #include "windows.h"
 #include "file.h"
+#include "heap.h"
 #include "ldt.h"
 #include "lzexpand.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
-#include "string32.h"
 
-#define strdupW2A(x)	STRING32_DupUniToAnsi(x)
-#define strdupA2W(x)	STRING32_DupAnsiToUni(x)
-#define strcpyAW(a,b)	STRING32_AnsiToUni(a,b)
 
 /* The readahead length of the decompressor. Reading single bytes
  * using _lread() would be SLOW.
@@ -265,13 +262,12 @@
 	char	*xin,*xout;
 	INT32	ret;
 
-	xout	= malloc(lstrlen32W(in)+3);
-	xin	= strdupW2A(in);
+	xout	= HeapAlloc( GetProcessHeap(), 0, lstrlen32W(in)+3 );
+	xin	= HEAP_strdupWtoA( GetProcessHeap(), 0, in );
 	ret	= GetExpandedName16(xin,xout);
-	if (ret>0)
-		strcpyAW(out,xout);
-	free(xin);
-	free(xout);
+	if (ret>0) lstrcpyAtoW(out,xout);
+	HeapFree( GetProcessHeap(), 0, xin );
+	HeapFree( GetProcessHeap(), 0, xout );
 	return	ret;
 }
 
@@ -530,14 +526,14 @@
 	LPWSTR	yfn;
 	HFILE	ret;
 
-	xfn	= strdupW2A(fn);
+	xfn	= HEAP_strdupWtoA( GetProcessHeap(), 0, fn);
 	ret	= LZOpenFile16(xfn,ofs,mode);
-	free(xfn);
+	HeapFree( GetProcessHeap(), 0, xfn );
 	if (ret!=HFILE_ERROR) {
 		/* ofs->szPathName is an array with the OFSTRUCT */
-		yfn 	= strdupA2W(ofs->szPathName);
+                yfn = HEAP_strdupAtoW( GetProcessHeap(), 0, ofs->szPathName );
 		memcpy(ofs->szPathName,yfn,lstrlen32W(yfn)*2+2);
-		free(yfn);
+                HeapFree( GetProcessHeap(), 0, yfn );
 	}
 	return	ret;
 }
diff --git a/misc/main.c b/misc/main.c
index dfda8c5..754950e 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -18,17 +18,18 @@
 #include <X11/Xutil.h>
 #include <X11/Xlocale.h>
 #include <X11/cursorfont.h>
+#include "heap.h"
 #include "message.h"
 #include "module.h"
 #include "msdos.h"
 #include "windows.h"
+#include "color.h"
 #include "winsock.h"
 #include "options.h"
 #include "desktop.h"
 #include "registers.h"
 #include "shell.h"
 #include "winbase.h"
-#include "string32.h"
 #define DEBUG_DEFINE_VARIABLES
 #include "stddebug.h"
 #include "debug.h"
@@ -602,6 +603,7 @@
 static void called_at_exit(void)
 {
     MAIN_RestoreSetup();
+    COLOR_Cleanup();
     WINSOCK_Shutdown();
 }
 
@@ -764,7 +766,7 @@
 	v->dwMinorVersion = v1.dwMinorVersion;
 	v->dwBuildNumber = v1.dwBuildNumber;
 	v->dwPlatformId = v1.dwPlatformId;
-	STRING32_AnsiToUni(v->szCSDVersion, v1.szCSDVersion);
+        lstrcpyAtoW( v->szCSDVersion, v1.szCSDVersion );
 	return TRUE;
 }
 
@@ -889,12 +891,11 @@
  */
 BOOL32 SetEnvironmentVariable32W( LPCWSTR lpName, LPCWSTR lpValue )
 {
-    LPSTR lpNameA = STRING32_DupUniToAnsi(lpName);
-    LPSTR lpValueA = lpValue?STRING32_DupUniToAnsi(lpValue):NULL;
+    LPSTR lpNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpName );
+    LPSTR lpValueA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpValue );
     BOOL32 ret = SetEnvironmentVariable32A(lpNameA,lpValueA);
-
-    free (lpNameA);
-    if (lpValue) free (lpValueA);
+    HeapFree( GetProcessHeap(), 0, lpNameA );
+    HeapFree( GetProcessHeap(), 0, lpValueA );
     return ret;
 }
 
@@ -936,13 +937,15 @@
  */
 DWORD GetEnvironmentVariable32W( LPWSTR nameW, LPWSTR valW, DWORD size )
 {
-    LPSTR	name = nameW?STRING32_DupUniToAnsi(nameW):NULL;
-    LPSTR	val = valW?(LPSTR)xmalloc(size*2):NULL;
-    DWORD	res = GetEnvironment(name,val,size);
-
-    if (name) free(name);
-    if (val) lstrcpynAtoW(valW,val,size);
-    if (val) free(val);
+    LPSTR name = HEAP_strdupWtoA( GetProcessHeap(), 0, nameW );
+    LPSTR val  = valW ? HeapAlloc( GetProcessHeap(), 0, size ) : NULL;
+    DWORD res  = GetEnvironment( name, val, size );
+    HeapFree( GetProcessHeap(), 0, name );
+    if (val)
+    {
+        lstrcpyAtoW( valW, val );
+        HeapFree( GetProcessHeap(), 0, val );
+    }
     return res;
 }
 
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 8669f50..a6b1e8b 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -7,12 +7,12 @@
 #include <string.h>
 #include <malloc.h>
 #include "windows.h"
+#include "heap.h"
 #include "ole.h"
 #include "options.h"
 #include "winnls.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "string32.h"
 
 /* Locale name to id map. used by EnumSystemLocales, GetLocalInfoA 
  * MUST contain all #defines from winnls.h
@@ -1278,22 +1278,22 @@
 /***********************************************************************
  *              EnumSystemLocales32W                (KERNEL32.93)
  */
-BOOL32
-EnumSystemLocales32W(LOCALE_ENUMPROC32W lpfnLocaleEnum,DWORD flags) {
-	WCHAR	*cp;
+BOOL32 EnumSystemLocales32W( LOCALE_ENUMPROC32W lpfnLocaleEnum, DWORD flags )
+{
 	int	i;
 	BOOL32	ret;
 
 	dprintf_win32(stddeb,"EnumSystemLocales32W(%p,%08lx)\n",
-		lpfnLocaleEnum,flags
-	);
+                      lpfnLocaleEnum,flags );
 	i=0;
-	while (locale_name2id[i].name!=NULL) {
-		cp=(LPWSTR)STRING32_DupAnsiToUni(locale_name2id[i].name);
-		ret=lpfnLocaleEnum(cp);
-		free(cp);
-		if (!ret) break;
-		i++;
+	while (locale_name2id[i].name!=NULL)
+        {
+            LPWSTR cp = HEAP_strdupAtoW( GetProcessHeap(), 0,
+                                         locale_name2id[i].name );
+            ret = lpfnLocaleEnum(cp);
+            HeapFree( GetProcessHeap(), 0, cp );
+            if (!ret) break;
+            i++;
 	}
 	return TRUE;
 }
diff --git a/misc/registry.c b/misc/registry.c
index e208349..ece9fb0 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -20,6 +20,7 @@
 #include "win.h"
 #include "winerror.h"
 #include "file.h"
+#include "heap.h"
 #include "dos_fs.h"
 #include "string32.h"	
 #include "stddebug.h"
@@ -82,11 +83,8 @@
 #define UNICONVMASK	((1<<REG_SZ)|(1<<REG_MULTI_SZ)|(1<<REG_EXPAND_SZ))
 
 #define strdupA2W(x)	STRING32_DupAnsiToUni(x)
-#define strdupW2A(x)	STRING32_DupUniToAnsi(x)
 #define strdupW(x)	STRING32_strdupW(x)
-#define strcmpniW(a,b)	STRING32_lstrcmpniW(a,b)
 #define strchrW(a,c)	STRING32_lstrchrW(a,c)
-#define strcpyWA(a,b)	STRING32_UniToAnsi(a,b)
 
 static struct openhandle {
 	LPKEYSTRUCT	lpkey;
@@ -159,8 +157,8 @@
 		return "<NULL>";
 	if (sub!=0 && sub!=1)
 		return "<W2C:bad sub>";
-	if (unicodedebug[sub]) free(unicodedebug[sub]);
-	unicodedebug[sub]	= strdupW2A(x);
+	if (unicodedebug[sub]) HeapFree( SystemHeap, 0, unicodedebug[sub] );
+	unicodedebug[sub] = HEAP_strdupWtoA( SystemHeap, 0, x );
 	return unicodedebug[sub];
 }
 
@@ -1429,7 +1427,7 @@
 	struct _w31_dirent	*dir;
 	struct _w31_keyent	*key;
 	struct _w31_valent	*val;
-	LPKEYSTRUCT		xlpkey;
+	LPKEYSTRUCT		xlpkey = NULL;
 	LPWSTR			name,value;
 	static char		tail[400];
 
@@ -2132,7 +2130,7 @@
 		if (buf) {
 			if (UNICONVMASK & (1<<(type))) {
 				/* convert UNICODE to ASCII */
-				strcpyWA(lpbData,(LPWSTR)buf);
+				lstrcpyWtoA(lpbData,(LPWSTR)buf);
 				*lpcbData	= myxlen/2;
 			} else {
 				if (myxlen>*lpcbData)
@@ -2536,10 +2534,10 @@
 		ft
 	);
 	if (ret==ERROR_SUCCESS) {
-		strcpyWA(lpszName,lpszNameW);
+		lstrcpyWtoA(lpszName,lpszNameW);
 		*lpcchName=strlen(lpszName);
 		if (lpszClassW) {
-			strcpyWA(lpszClass,lpszClassW);
+			lstrcpyWtoA(lpszClass,lpszClassW);
 			*lpcchClass=strlen(lpszClass);
 		}
 	}
@@ -2677,10 +2675,10 @@
 	);
 
 	if (ret==ERROR_SUCCESS) {
-		strcpyWA(lpszValue,lpszValueW);
+		lstrcpyWtoA(lpszValue,lpszValueW);
 		if (lpbData) {
 			if ((1<<*lpdwType) & UNICONVMASK) {
-				strcpyWA(lpbData,(LPWSTR)lpbDataW);
+				lstrcpyWtoA(lpbData,(LPWSTR)lpbDataW);
 			} else {
 				if (lpcbDataW > *lpcbData)
 					ret	= ERROR_MORE_DATA;
@@ -3009,7 +3007,7 @@
 		ft
 	);
 	if (ret==ERROR_SUCCESS)
-		strcpyWA(lpszClass,lpszClassW);
+		lstrcpyWtoA(lpszClass,lpszClassW);
 	if (lpcchClass)
 		*lpcchClass/=2;
 	if (lpcchMaxSubkey)
diff --git a/misc/shell.c b/misc/shell.c
index 263b9d8..486e733 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -9,6 +9,7 @@
 #include "windows.h"
 #include "file.h"
 #include "shell.h"
+#include "heap.h"
 #include "module.h"
 #include "neexe.h"
 #include "resource.h"
@@ -771,7 +772,7 @@
   LPSTR   lpstr = str;
   LPSTR   lpbstr = lpBuffer;
 
-  AnsiToOem(str,str);
+  CharToOem32A(str,str);
 
   dprintf_reg(stddeb,"DoEnvSubst: accept %s", str);
 
@@ -824,7 +825,7 @@
 
   dprintf_reg(stddeb," return %s\n", str);
 
-  OemToAnsi(str,str);
+  OemToChar32A(str,str);
   free(lpBuffer);
 
   /*  Return str length in the LOWORD
@@ -873,7 +874,8 @@
 	LPWSTR	*argv,s,t;
 	int	i;
 
-	cmdline = (LPWSTR)STRING32_strdupW(cmdline); /* to get writeable copy */
+        /* to get writeable copy */
+	cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
 	s=cmdline;i=0;
 	while (*s) {
 		/* space */
@@ -886,13 +888,13 @@
 		}
 		s++;
 	}
-	argv=(LPWSTR*)xmalloc(sizeof(LPWSTR)*(i+1));
+	argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
 	s=t=cmdline;
 	i=0;
 	while (*s) {
 		if (*s==0x0020) {
 			*s=0;
-			argv[i++]=(LPWSTR)STRING32_strdupW(t);
+			argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
 			*s=0x0020;
 			while (*s && *s==0x0020)
 				s++;
@@ -905,8 +907,8 @@
 		s++;
 	}
 	if (*t)
-		argv[i++]=(LPWSTR)STRING32_strdupW(t);
-	free(cmdline);
+		argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
+	HeapFree( GetProcessHeap(), 0, cmdline );
 	argv[i]=NULL;
 	*numargs=i;
 	return argv;
diff --git a/misc/ver.c b/misc/ver.c
index 3ee1fcd..84740c8 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -11,6 +11,7 @@
 #include "windows.h"
 #include "win.h"
 #include "winerror.h"
+#include "heap.h"
 #include "ver.h"
 #include "lzexpand.h"
 #include "module.h"
@@ -19,15 +20,11 @@
 #include "debug.h"
 #include "xmalloc.h"
 #include "winreg.h"
-#include "string32.h"
 
 #define LZREAD(what) \
   if (sizeof(*what)!=LZRead32(lzfd,what,sizeof(*what))) return 0;
 #define LZTELL(lzfd) LZSeek(lzfd, 0, SEEK_CUR);
 
-#define strdupW2A(x)	STRING32_DupUniToAnsi(x)
-#define strdupA2W(x)	STRING32_DupAnsiToUni(x)
-
 int
 read_ne_header(HFILE lzfd,struct ne_header_s *nehd) {
 	struct	mz_header_s	mzh;
@@ -348,15 +345,12 @@
 }
 
 /* GetFileVersionInfoSize32W			[VERSION.2] */
-DWORD
-GetFileVersionInfoSize32W(LPCWSTR filename,LPDWORD handle) {
-	LPSTR	xfn;
-	DWORD	ret;
-
-	xfn	= strdupW2A(filename);
-	ret=GetFileVersionInfoSize16(xfn,handle);
-	free(xfn);
-	return	ret;
+DWORD GetFileVersionInfoSize32W( LPCWSTR filename, LPDWORD handle )
+{
+    LPSTR xfn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    DWORD ret = GetFileVersionInfoSize16( xfn, handle );
+    HeapFree( GetProcessHeap(), 0, xfn );
+    return ret;
 }
 
 /* GetFileVersionInfo				[VER.7] */
@@ -377,15 +371,13 @@
 }
 
 /* GetFileVersionInfoW				[VERSION.3] */
-DWORD 
-GetFileVersionInfo32W(LPCWSTR filename,DWORD handle,DWORD datasize,LPVOID data){
-	DWORD	ret;
-	LPSTR	fn;
-
-	fn	= strdupW2A(filename);
-	ret	= GetFileVersionInfo16(fn,handle,datasize,data);
-	free(fn);
-	return	ret;
+DWORD GetFileVersionInfo32W( LPCWSTR filename, DWORD handle, DWORD datasize,
+                             LPVOID data)
+{
+    LPSTR fn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    DWORD ret = GetFileVersionInfo16( fn, handle, datasize, data );
+    HeapFree( GetProcessHeap(), 0, fn );
+    return ret;
 }
 
 /* VerFindFile				[VER.8] */
@@ -428,16 +420,21 @@
     LPSTR wfn,wwd,wad,wdd,wcd;
     DWORD ret;
 
-    wfn = strdupW2A(filename);
-    wwd = strdupW2A(windir);
-    wad = strdupW2A(appdir);
-    wcd = (LPSTR)malloc(*pcurdirlen);
-    wdd = (LPSTR)malloc(*pdestdirlen);
-    ret=VerFindFile16(flags,wfn,wwd,wad,wcd,&curdirlen,wdd,&destdirlen);
-    STRING32_AnsiToUni(curdir,wcd);
-    STRING32_AnsiToUni(destdir,wdd);
+    wfn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    wwd = HEAP_strdupWtoA( GetProcessHeap(), 0, windir );
+    wad = HEAP_strdupWtoA( GetProcessHeap(), 0, appdir );
+    wcd = HeapAlloc( GetProcessHeap(), 0, *pcurdirlen );
+    wdd = HeapAlloc( GetProcessHeap(), 0, *pdestdirlen );
+    ret = VerFindFile16(flags,wfn,wwd,wad,wcd,&curdirlen,wdd,&destdirlen);
+    lstrcpynAtoW(curdir,wcd,*pcurdirlen);
+    lstrcpynAtoW(destdir,wdd,*pdestdirlen);
     *pcurdirlen = strlen(wcd);
     *pdestdirlen = strlen(wdd);
+    HeapFree( GetProcessHeap(), 0, wfn );
+    HeapFree( GetProcessHeap(), 0, wwd );
+    HeapFree( GetProcessHeap(), 0, wad );
+    HeapFree( GetProcessHeap(), 0, wcd );
+    HeapFree( GetProcessHeap(), 0, wdd );
     return ret;
 }
 
@@ -473,23 +470,23 @@
 DWORD
 VerInstallFile32W(
 	UINT32 flags,LPCWSTR srcfilename,LPCWSTR destfilename,LPCWSTR srcdir,
-	LPCWSTR destdir,LPWSTR tmpfile,UINT32 *tmpfilelen
-) {
-	LPSTR	wsrcf,wsrcd,wdestf,wdestd,wtmpf;
-	DWORD	ret;
+	LPCWSTR destdir,LPWSTR tmpfile,UINT32 *tmpfilelen )
+{
+    LPSTR wsrcf,wsrcd,wdestf,wdestd,wtmpf;
+    DWORD ret;
 
-	wsrcf	= strdupW2A(srcfilename);
-	wsrcd	= strdupW2A(srcdir);
-	wdestf	= strdupW2A(destfilename);
-	wdestd	= strdupW2A(destdir);
-	wtmpf	= strdupW2A(tmpfile);
-	ret=VerInstallFile32A(flags,wsrcf,wdestf,wsrcd,wdestd,wtmpf,tmpfilelen);
-	free(wsrcf);
-	free(wsrcd);
-	free(wdestf);
-	free(wdestd);
-	free(wtmpf);
-	return ret;
+    wsrcf  = HEAP_strdupWtoA( GetProcessHeap(), 0, srcfilename );
+    wsrcd  = HEAP_strdupWtoA( GetProcessHeap(), 0, srcdir );
+    wdestf = HEAP_strdupWtoA( GetProcessHeap(), 0, destfilename );
+    wdestd = HEAP_strdupWtoA( GetProcessHeap(), 0, destdir );
+    wtmpf  = HEAP_strdupWtoA( GetProcessHeap(), 0, tmpfile );
+    ret = VerInstallFile32A(flags,wsrcf,wdestf,wsrcd,wdestd,wtmpf,tmpfilelen);
+    HeapFree( GetProcessHeap(), 0, wsrcf );
+    HeapFree( GetProcessHeap(), 0, wsrcd );
+    HeapFree( GetProcessHeap(), 0, wdestf );
+    HeapFree( GetProcessHeap(), 0, wdestd );
+    HeapFree( GetProcessHeap(), 0, wtmpf );
+    return ret;
 }
 
 /* FIXME: This table should, of course, be language dependend */
@@ -580,32 +577,25 @@
 DWORD
 VerLanguageName32W(UINT32 langid,LPWSTR langname,UINT32 langnamelen) {
 	int	i;
-	char	*buf;
-	LPWSTR	keyname,result;
+	char	buffer[80];
+	LPWSTR	keyname;
 
 	/* First, check \System\CurrentControlSet\control\Nls\Locale\<langid>
 	 * from the registry. 
 	 */
-	buf=(char*)malloc(strlen("\\System\\CurrentControlSet\\control\\Nls\\Locale\\")+9);
-	sprintf(buf,"\\System\\CurrentControlSet\\control\\Nls\\Locale\\%08x",langid);
-	keyname=strdupA2W(buf);free(buf);
+	sprintf(buffer,"\\System\\CurrentControlSet\\control\\Nls\\Locale\\%08x",langid);
+	keyname = HEAP_strdupAtoW( GetProcessHeap(), 0, buffer );
 	if (ERROR_SUCCESS==RegQueryValue32W(HKEY_LOCAL_MACHINE,keyname,langname,(LPDWORD)&langnamelen)) {
-		free(keyname);
+		HeapFree( GetProcessHeap(), 0, keyname );
 		return langnamelen;
 	}
-	free(keyname);
+        HeapFree( GetProcessHeap(), 0, keyname );
 	/* if that fails, use the interal table */
 	for (i=0;languages[i].langid!=0;i++)
 		if (langid==languages[i].langid)
 			break;
-	result=strdupA2W(languages[i].langname);
-	i=lstrlen32W(result)*sizeof(WCHAR);
-	if (i>langnamelen)
-		i=langnamelen;
-	memcpy(langname,result,i);
-	langname[langnamelen-1]='\0';
-	free(result);
-	return strlen(languages[i].langname); /* same as strlenW(result); */
+        lstrcpyAtoW( langname, languages[i].langname );
+	return strlen(languages[i].langname); /* same as strlenW(langname); */
 }
 
 /* FIXME: UNICODE? */
@@ -729,13 +719,13 @@
 	struct	db	*db;
 	char		*s,*sb;
 
-	sb=strdupW2A(subblock);
+	sb = HEAP_strdupWtoA( GetProcessHeap(), 0, subblock );
 	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(sb)+1);
 	strcpy(s,"VS_VERSION_INFO\\");strcat(s,sb);
 	b=_find_data(block,s);
 	if (b==NULL) {
 		*buflen=0;
-		free(sb);
+		HeapFree( GetProcessHeap(), 0, sb );
 		return 0;
 	}
 	db=(struct db*)b;
@@ -744,7 +734,7 @@
 	b	= b+4+((strlen(db->name)+4)&~3);
 	*buffer	= b;
 	dprintf_ver(stddeb,"	-> %s=%s\n",sb,b);
-	free(sb);
+        HeapFree( GetProcessHeap(), 0, sb );
 	return 1;
 }
 /* 20 GETFILEVERSIONINFORAW */
diff --git a/misc/winsock_async.c b/misc/winsock_async.c
index c97588b..607b9cf 100644
--- a/misc/winsock_async.c
+++ b/misc/winsock_async.c
@@ -15,6 +15,8 @@
 #include <sys/wait.h>
 #include <errno.h>
 
+extern int h_errno;
+
 #include "windows.h"
 #include "winsock.h"
 #include "debug.h"
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 0c535f5..791848d 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -13,7 +13,6 @@
 #include "dc.h"
 #include "bitmap.h"
 #include "heap.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -88,6 +87,9 @@
     BITMAPOBJ * bmpObjPtr;
     HBITMAP16 hbitmap;
 
+    planes = (BYTE)planes;
+    bpp    = (BYTE)bpp;
+
     dprintf_gdi( stddeb, "CreateBitmap: %dx%d, %d colors\n", 
                  width, height, 1 << (planes*bpp) );
 
@@ -294,7 +296,7 @@
  */
 HBITMAP16 LoadBitmap16( HINSTANCE16 instance, SEGPTR name )
 {
-    HBITMAP16 hbitmap = 0;
+    HBITMAP32 hbitmap = 0;
     HDC32 hdc;
     HRSRC16 hRsrc;
     HGLOBAL16 handle;
@@ -323,8 +325,8 @@
     if ((hdc = GetDC32(0)) != 0)
     {
         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
-        hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
-                                  bits, info, DIB_RGB_COLORS );
+        hbitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
+                                    bits, info, DIB_RGB_COLORS );
         ReleaseDC32( 0, hdc );
     }
     FreeResource16( handle );
@@ -356,8 +358,8 @@
     if ((hdc = GetDC32(0)) != 0)
     {
         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
-        hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
-                                  bits, info, DIB_RGB_COLORS );
+        hbitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
+                                    bits, info, DIB_RGB_COLORS );
         ReleaseDC32( 0, hdc );
     }
     return hbitmap;
@@ -370,12 +372,12 @@
 HBITMAP32 LoadBitmap32A( HINSTANCE32 instance, LPCSTR name )
 {
     HBITMAP32 res;
-    if (!HIWORD(name)) res = LoadBitmap32W(instance,(LPWSTR)name);
+    if (!HIWORD(name)) res = LoadBitmap32W( instance, (LPWSTR)name );
     else
     {
-        LPWSTR uni = STRING32_DupAnsiToUni(name);
-        res = LoadBitmap32W(instance,uni);
-        free(uni);
+        LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+        res = LoadBitmap32W( instance, uni );
+        HeapFree( GetProcessHeap(), 0, uni );
     }
     return res;
 }
diff --git a/objects/brush.c b/objects/brush.c
index ecb71cc..5480b85 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -536,9 +536,10 @@
 	if ((bmpInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)brush->logbrush.lbHatch )))
 	{
 	    int size = DIB_BitmapInfoSize( bmpInfo, brush->logbrush.lbColor );
-	    hBitmap = CreateDIBitmap( dc->hSelf, &bmpInfo->bmiHeader, CBM_INIT,
-				      ((char *)bmpInfo) + size, bmpInfo,
-				      (WORD) 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 );	    
diff --git a/objects/clipping.c b/objects/clipping.c
index 787991b..7ca30a9 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -418,6 +418,7 @@
     return ret;
 }
 
+
 /***********************************************************************
  *           GetClipRgn32  (GDI32.163)
  */
diff --git a/objects/color.c b/objects/color.c
index bc1615f..8aaed5c 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -23,14 +23,15 @@
  *				     
  *
  * Windows needs contiguous color space ( from 0 to n ) but 
- * it is possible only with private colormap. Otherwise we
- * have to map DC palette indices to real pixel values.
- * With private colormap it boils down to identity mapping. The
- * other special case is when we have fixed color visual with 
- * screendepth > 8 - we abandon mapping altogether (pixel
- * values can be calculated without X server assistance).
+ * it is possible only with the private colormap. Otherwise we
+ * have to map DC palette indices to real pixel values. With 
+ * private colormaps it boils down to the identity mapping. The
+ * other special case is when we have a fixed color visual with 
+ * the screendepth > 8 - we abandon palette mappings altogether 
+ * because pixel values can be calculated without X server 
+ * assistance.
  *
- * For info about general Windows palette management read
+ * For some info about general Windows palette management read
  * http://198.105.232.5/MSDN/LIBRARY/TECHNOTE/CH3.HTM 
  */
 
@@ -66,6 +67,7 @@
 static PALETTEENTRY* COLOR_sysPal = NULL;    /* current system palette */
 static int COLOR_gapStart = 256;
 static int COLOR_gapEnd = -1;
+static int COLOR_gapFilled = 0;
 
   /* First free dynamic color cell, 0 = full palette, -1 = fixed palette */
 static int            COLOR_firstFree = 0; 
@@ -156,6 +158,15 @@
   COLOR_freeList[j] = 0;
 }
 
+BOOL32 COLOR_CheckSysColor(COLORREF c)
+{
+  int i;
+  for( i = 0; i < NB_RESERVED_COLORS; i++ )
+       if( c == (*(COLORREF*)(__sysPalTemplate + i) & 0x00ffffff) )
+	   return 0;
+  return 1;
+}
+
 void COLOR_FillDefaultColors(void)
 {
  /* initialize unused entries to what Windows uses as a color 
@@ -177,8 +188,9 @@
 
   idx = COLOR_firstFree;
 
-  for (blue = NB_COLORCUBE_START_INDEX; blue < 256 && idx; blue += inc_b )
-    for (green = NB_COLORCUBE_START_INDEX; green < 256 && idx; green += inc_g )
+  if( idx != -1 )
+    for (blue = NB_COLORCUBE_START_INDEX; blue < 256 && idx; blue += inc_b )
+     for (green = NB_COLORCUBE_START_INDEX; green < 256 && idx; green += inc_g )
       for (red = NB_COLORCUBE_START_INDEX; red < 256 && idx; red += inc_r )
       {
 	 /* weird but true */
@@ -212,23 +224,40 @@
 	 idx = COLOR_freeList[idx];
       }
 
-  /* fill the rest with gray for now - only needed for
-   * sparse palette (in seamless mode)
-   */
+  /* try to fill some entries in the "gap" with
+   * what's already in the colormap - they will be
+   * mappable to but not changeable. */
 
-  for ( i = COLOR_gapStart; i <= COLOR_gapEnd; i++ )
+  if( COLOR_gapStart < COLOR_gapEnd && COLOR_PixelToPalette )
   {
-     *(COLORREF*)(COLOR_sysPal + i) = 0x00c0c0c0;
-      if( COLOR_PaletteToPixel )
-	  COLOR_PaletteToPixel[i] = COLOR_PaletteToPixel[7];
+    XColor	xc;
+    int		r, g, b;
+
+    for ( i = 0, idx = COLOR_gapStart; i < 256 && idx <= COLOR_gapEnd; i++ )
+      if( COLOR_PixelToPalette[i] == 0 )
+	{
+	  xc.pixel = i;
+
+	  XQueryColor(display, cSpace.colorMap, &xc);
+	  r = xc.red>>8; g = xc.green>>8; b = xc.blue>>8;
+
+	  if( xc.pixel < 256 && COLOR_CheckSysColor(RGB(r, g, b)) &&
+	      XAllocColor(display, cSpace.colorMap, &xc) )
+	  {
+	     COLOR_PixelToPalette[xc.pixel] = idx;
+	     COLOR_PaletteToPixel[idx] = xc.pixel;
+           *(COLORREF*)(COLOR_sysPal + idx) = RGB(r, g, b);
+	     COLOR_sysPal[idx++].peFlags |= PC_SYS_USED;
+	  }
+	}
+    COLOR_gapFilled = idx - COLOR_gapStart;    
   }
 }
 
 /***********************************************************************
  *           COLOR_BuildPrivateMap/COLOR_BuildSharedMap
  *
- * Executed only one time so we don't care about sloppiness,
- * the rest have to be very tight though...
+ * Allocate colorcells and initialize mapping tables.
  */
 static BOOL COLOR_BuildPrivateMap(CSPACE* cs)
 {
@@ -265,7 +294,7 @@
        color.pixel = i;
        XStoreColor(display, cs->colorMap, &color);
 
-       /* Set EGA mapping if color in the first or last eight */
+       /* Set EGA mapping if color is from the first or last eight */
 
        if (i < 8)
            COLOR_mapEGAPixel[i] = color.pixel;
@@ -287,8 +316,10 @@
    unsigned long        sysPixel[NB_RESERVED_COLORS];
    unsigned long*	pixDynMapping = NULL;
    unsigned long	plane_masks[1];
-   int			i, j;
+   int			i, j, warn = 0;
    int			color_ini_max = 256;
+   int			diff, r, g, b, max = 256, bp = 0, wp = 1;
+   int			step = 1;
 
    /* read "AllocSystemColors" from wine.conf */
 
@@ -309,10 +340,46 @@
         color.flags = DoRed | DoGreen | DoBlue;
 
         if (!XAllocColor( display, cSpace.colorMap, &color ))
-           { 
-             fprintf(stderr, "Warning: Not enough free colors for system palette.\n" );
-             color.pixel = color.red = color.green = color.blue = 0;
-           }
+        { 
+	     XColor	best, c;
+	     
+             if( !warn++ ) 
+	     {
+		  dprintf_palette(stddeb, "Not enough colors for the full system palette.\n");
+
+	          bp = BlackPixel(display, DefaultScreen(display));
+	          wp = WhitePixel(display, DefaultScreen(display));
+
+	          max = (0xffffffff)>>(32 - screenDepth);
+	          if( max > 256 ) 
+	          {
+	  	      step = max/256;
+		      max = 256;
+	          }
+	     }
+
+	     /* reinit color (XAllocColor() may change it)
+	      * and map to the best shared colorcell */
+
+             color.red   = __sysPalTemplate[i].peRed * 65535 / 255;
+             color.green = __sysPalTemplate[i].peGreen * 65535 / 255;
+             color.blue  = __sysPalTemplate[i].peBlue * 65535 / 255;
+
+	     best.pixel = best.red = best.green = best.blue = 0;
+	     for( c.pixel = 0, diff = 0x7fffffff; c.pixel < max; c.pixel += step )
+	     {
+		XQueryColor(display, cSpace.colorMap, &c);
+		r = (c.red - color.red)>>8; 
+		g = (c.green - color.green)>>8; 
+		b = (c.blue - color.blue)>>8;
+		r = r*r + g*g + b*b;
+		if( r < diff ) { best = c; diff = r; }
+	     }
+
+	     if( XAllocColor(display, cSpace.colorMap, &best) )
+		 color.pixel = best.pixel;
+	     else color.pixel = (i < NB_RESERVED_COLORS/2)? bp : wp;
+        }
 
         sysPixel[i] = color.pixel;
 
@@ -327,6 +394,8 @@
             COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel;
      }
 
+   /* now allocate changeable set */
+
    if( !(cSpace.flags & COLOR_FIXED) )  
      {
 	int c_min = 0, c_max = cs->size, c_val;
@@ -389,12 +458,8 @@
 
    dprintf_palette(stddeb,"Shared system palette uses %i colors.\n", cs->size);
 
-   /* Set gap to account for pixel shortage. It has to be right in the center
-    * of the system palette because otherwise raster ops get screwed.
-    * ( if we have 100 color palette and application does invert for pixel 1
-    *   it gets pixel 254 - far beyond our pathetic palette unless these 100
-    *   colors are mapped with the gap in the middle )
-    */
+   /* set gap to account for pixel shortage. It has to be right in the center
+    * of the system palette because otherwise raster ops get screwed. */
 
    if( cs->size >= 256 )
      { COLOR_gapStart = 256; COLOR_gapEnd = -1; }
@@ -407,7 +472,7 @@
 
    COLOR_sysPal = (PALETTEENTRY*)xmalloc(sizeof(PALETTEENTRY)*256);
 
-   /* Setup system palette entry <-> pixel mappings and fill in 20 fixed entries */
+   /* setup system palette entry <-> pixel mappings and fill in 20 fixed entries */
 
    if( screenDepth <= 8 )
      {
@@ -448,7 +513,7 @@
       dprintf_palette(stddeb,"\tindex %i -> pixel %i\n", i, COLOR_PaletteToPixel[i]);
 
       if( COLOR_PixelToPalette )
-        COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
+          COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
    }
 
    if( pixDynMapping ) free(pixDynMapping);
@@ -459,7 +524,7 @@
 /***********************************************************************
  *           COLOR_InitPalette
  *
- * Create the system palette and initialize mapping tables.
+ * Create the system palette.
  */
 static HPALETTE16 COLOR_InitPalette(void)
 {
@@ -482,10 +547,9 @@
     /* Build free list */
 
     if( COLOR_firstFree != -1 )
-    {
 	COLOR_FormatSystemPalette();
-        COLOR_FillDefaultColors();
-    }
+
+    COLOR_FillDefaultColors();
 
     /* create default palette (20 system colors) */
 
@@ -517,7 +581,7 @@
  *
  * Calculate conversion parameters for direct mapped visuals
  */
-void COLOR_Computeshifts(unsigned long maskbits, int *shift, int *max)
+static void COLOR_Computeshifts(unsigned long maskbits, int *shift, int *max)
 {
     int i;
 
@@ -597,6 +661,18 @@
     return COLOR_InitPalette();
 }
 
+/***********************************************************************
+ *           COLOR_Cleanup
+ *
+ * Free external colors we grabbed in the FillDefaultPalette()
+ */
+void COLOR_Cleanup(void)
+{
+  if( COLOR_gapFilled )
+      XFreeColors(display, cSpace.colorMap, 
+		  (unsigned long*)(COLOR_PaletteToPixel + COLOR_gapStart), 
+		  COLOR_gapFilled, 0);
+}
 
 /***********************************************************************
  *           COLOR_IsSolid
@@ -736,25 +812,25 @@
     /* check for hicolor visuals first */
 
     if ( cSpace.flags & COLOR_FIXED && !COLOR_Graymax )
-       {
+    {
          color.red = (pixel >> COLOR_Redshift) & COLOR_Redmax;
          color.green = (pixel >> COLOR_Greenshift) & COLOR_Greenmax;
          color.blue = (pixel >> COLOR_Blueshift) & COLOR_Bluemax;
-       }
-    else if ((screenDepth <= 8) && (pixel < 256) && 
-	    !(cSpace.flags & (COLOR_VIRTUAL | COLOR_FIXED)) )
-        return  ( *(COLORREF*)(COLOR_sysPal + 
-		  ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
-    else
-       {
-         color.pixel = pixel;
-         XQueryColor(display, cSpace.colorMap, &color);
-         return RGB(color.red >> 8, color.green >> 8, color.blue >> 8);
-       }
+         return RGB((color.red * 255)/COLOR_Redmax,
+                    (color.green * 255)/COLOR_Greenmax,
+                    (color.blue * 255)/COLOR_Bluemax);
+    }
 
-    return RGB((color.red * 255)/COLOR_Redmax,
-               (color.green * 255)/COLOR_Greenmax,
-               (color.blue * 255)/COLOR_Bluemax);
+    /* check if we can bypass X */
+
+    if ((screenDepth <= 8) && (pixel < 256) && 
+       !(cSpace.flags & (COLOR_VIRTUAL | COLOR_FIXED)) )
+         return  ( *(COLORREF*)(COLOR_sysPal + 
+		   ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
+
+    color.pixel = pixel;
+    XQueryColor(display, cSpace.colorMap, &color);
+    return RGB(color.red >> 8, color.green >> 8, color.blue >> 8);
 }
 
 
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index df7be52..0ee8657 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -236,7 +236,7 @@
 HGLOBAL16 CURSORICON_LoadHandler( HGLOBAL16 handle, HINSTANCE16 hInstance,
                                   BOOL fCursor )
 {
-    HBITMAP16 hAndBits, hXorBits;
+    HBITMAP32 hAndBits, hXorBits;
     HDC32 hdc;
     int size, sizeAnd, sizeXor;
     POINT16 hotspot = { 0 ,0 };
@@ -292,8 +292,8 @@
         return 0;
     }
 
-    hXorBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
-                               (char*)bmi + size, pInfo, DIB_RGB_COLORS );
+    hXorBits = CreateDIBitmap32( hdc, &pInfo->bmiHeader, CBM_INIT,
+                                 (char*)bmi + size, pInfo, DIB_RGB_COLORS );
 
     /* Fix the bitmap header to load the monochrome mask */
 
@@ -322,8 +322,8 @@
 
     /* Create the AND bitmap */
 
-    hAndBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
-                               bits, pInfo, DIB_RGB_COLORS );
+    hAndBits = CreateDIBitmap32( hdc, &pInfo->bmiHeader, CBM_INIT,
+                                 bits, pInfo, DIB_RGB_COLORS );
     ReleaseDC32( 0, hdc );
 
     /* Now create the CURSORICONINFO structure */
@@ -664,12 +664,12 @@
 BOOL DrawIcon( HDC16 hdc, INT x, INT y, HICON16 hIcon )
 {
     CURSORICONINFO *ptr;
-    HDC16 hMemDC;
+    HDC32 hMemDC;
     HBITMAP16 hXorBits, hAndBits;
     COLORREF oldFg, oldBg;
 
     if (!(ptr = (CURSORICONINFO *)GlobalLock16( hIcon ))) return FALSE;
-    if (!(hMemDC = CreateCompatibleDC( hdc ))) return FALSE;
+    if (!(hMemDC = CreateCompatibleDC32( hdc ))) return FALSE;
     hAndBits = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, (char *)(ptr+1));
     hXorBits = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes,
                              ptr->bBitsPerPixel, (char *)(ptr + 1)
@@ -685,7 +685,7 @@
         BitBlt32(hdc, x, y, ptr->nWidth, ptr->nHeight, hMemDC, 0, 0,SRCINVERT);
         SelectObject32( hMemDC, hBitTemp );
     }
-    DeleteDC( hMemDC );
+    DeleteDC32( hMemDC );
     if (hXorBits) DeleteObject32( hXorBits );
     if (hAndBits) DeleteObject32( hAndBits );
     GlobalUnlock16( hIcon );
diff --git a/objects/dc.c b/objects/dc.c
index 0d05d11..cfe93a1 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -5,17 +5,18 @@
  *
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <stdlib.h>
 #include <string.h>
 #include "gdi.h"
 #include "bitmap.h"
+#include "heap.h"
 #include "metafile.h"
 #include "stddebug.h"
 #include "color.h"
 #include "debug.h"
 #include "font.h"
 #include "xmalloc.h"
-#include "string32.h"
 
 extern void CLIPPING_UpdateGCRegion( DC * dc );     /* objects/clipping.c */
 
@@ -56,15 +57,7 @@
     0,                      /* DCOrgX */
     0,                      /* DCOrgY */
     0,                      /* CursPosX */
-    0,                      /* CursPosY */
-    0,                      /* WndOrgX */
-    0,                      /* WndOrgY */
-    1,                      /* WndExtX */
-    1,                      /* WndExtY */
-    0,                      /* VportOrgX */
-    0,                      /* VportOrgY */
-    1,                      /* VportExtX */
-    1                       /* VportExtY */
+    0                       /* CursPosY */
 };
 
   /* ROP code to GC function conversion */
@@ -158,6 +151,14 @@
     dc->saveLevel  = 0;
     dc->dwHookData = 0L;
     dc->hookProc   = NULL;
+    dc->wndOrgX    = 0;
+    dc->wndOrgY    = 0;
+    dc->wndExtX    = 1;
+    dc->wndExtY    = 1;
+    dc->vportOrgX  = 0;
+    dc->vportOrgY  = 0;
+    dc->vportExtX  = 1;
+    dc->vportExtY  = 1;
 
     memcpy( &dc->w, &DC_defaultValues, sizeof(DC_defaultValues) );
     return dc;
@@ -379,11 +380,49 @@
     dprintf_dc(stddeb, "GetDCState(%04x): returning %04x\n", hdc, handle );
 
     memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
-    memcpy( &newdc->w, &dc->w, sizeof(dc->w) );
+    newdc->w.flags           = dc->w.flags | DC_SAVED;
+    newdc->w.devCaps         = dc->w.devCaps;
+    newdc->w.hPen            = dc->w.hPen;       
+    newdc->w.hBrush          = dc->w.hBrush;     
+    newdc->w.hFont           = dc->w.hFont;      
+    newdc->w.hBitmap         = dc->w.hBitmap;    
+    newdc->w.hFirstBitmap    = dc->w.hFirstBitmap;
+    newdc->w.hDevice         = dc->w.hDevice;
+    newdc->w.hPalette        = dc->w.hPalette;   
+    newdc->w.bitsPerPixel    = dc->w.bitsPerPixel;
+    newdc->w.ROPmode         = dc->w.ROPmode;
+    newdc->w.polyFillMode    = dc->w.polyFillMode;
+    newdc->w.stretchBltMode  = dc->w.stretchBltMode;
+    newdc->w.relAbsMode      = dc->w.relAbsMode;
+    newdc->w.backgroundMode  = dc->w.backgroundMode;
+    newdc->w.backgroundColor = dc->w.backgroundColor;
+    newdc->w.textColor       = dc->w.textColor;
+    newdc->w.backgroundPixel = dc->w.backgroundPixel;
+    newdc->w.textPixel       = dc->w.textPixel;
+    newdc->w.brushOrgX       = dc->w.brushOrgX;
+    newdc->w.brushOrgY       = dc->w.brushOrgY;
+    newdc->w.textAlign       = dc->w.textAlign;
+    newdc->w.charExtra       = dc->w.charExtra;
+    newdc->w.breakTotalExtra = dc->w.breakTotalExtra;
+    newdc->w.breakCount      = dc->w.breakCount;
+    newdc->w.breakExtra      = dc->w.breakExtra;
+    newdc->w.breakRem        = dc->w.breakRem;
+    newdc->w.MapMode         = dc->w.MapMode;
+    newdc->w.DCOrgX          = dc->w.DCOrgX;
+    newdc->w.DCOrgY          = dc->w.DCOrgY;
+    newdc->w.CursPosX        = dc->w.CursPosX;
+    newdc->w.CursPosY        = dc->w.CursPosY;
+    newdc->wndOrgX           = dc->wndOrgX;
+    newdc->wndOrgY           = dc->wndOrgY;
+    newdc->wndExtX           = dc->wndExtX;
+    newdc->wndExtY           = dc->wndExtY;
+    newdc->vportOrgX         = dc->vportOrgX;
+    newdc->vportOrgY         = dc->vportOrgY;
+    newdc->vportExtX         = dc->vportExtX;
+    newdc->vportExtY         = dc->vportExtY;
 
     newdc->hSelf = (HDC32)handle;
     newdc->saveLevel = 0;
-    newdc->w.flags |= DC_SAVED;
 
     newdc->w.hGCClipRgn = 0;
     newdc->w.hVisRgn = CreateRectRgn32( 0, 0, 0, 0 );
@@ -435,14 +474,15 @@
     dc->w.DCOrgY          = dcs->w.DCOrgY;
     dc->w.CursPosX        = dcs->w.CursPosX;
     dc->w.CursPosY        = dcs->w.CursPosY;
-    dc->w.WndOrgX         = dcs->w.WndOrgX;
-    dc->w.WndOrgY         = dcs->w.WndOrgY;
-    dc->w.WndExtX         = dcs->w.WndExtX;
-    dc->w.WndExtY         = dcs->w.WndExtY;
-    dc->w.VportOrgX       = dcs->w.VportOrgX;
-    dc->w.VportOrgY       = dcs->w.VportOrgY;
-    dc->w.VportExtX       = dcs->w.VportExtX;
-    dc->w.VportExtY       = dcs->w.VportExtY;
+
+    dc->wndOrgX           = dcs->wndOrgX;
+    dc->wndOrgY           = dcs->wndOrgY;
+    dc->wndExtX           = dcs->wndExtX;
+    dc->wndExtY           = dcs->wndExtY;
+    dc->vportOrgX         = dcs->vportOrgX;
+    dc->vportOrgY         = dcs->vportOrgY;
+    dc->vportExtX         = dcs->vportExtX;
+    dc->vportExtY         = dcs->vportExtY;
 
     if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
     CombineRgn32( dc->w.hVisRgn, dcs->w.hVisRgn, 0, RGN_COPY );
@@ -456,11 +496,20 @@
 
 
 /***********************************************************************
- *           SaveDC    (GDI.30)
+ *           SaveDC16    (GDI.30)
  */
-int SaveDC( HDC16 hdc )
+INT16 SaveDC16( HDC16 hdc )
 {
-    HDC16 hdcs;
+    return (INT16)SaveDC32( hdc );
+}
+
+
+/***********************************************************************
+ *           SaveDC32    (GDI32.292)
+ */
+INT32 SaveDC32( HDC32 hdc )
+{
+    HDC32 hdcs;
     DC * dc, * dcs;
 
     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -481,9 +530,18 @@
 
 
 /***********************************************************************
- *           RestoreDC    (GDI.39)
+ *           RestoreDC16    (GDI.39)
  */
-BOOL RestoreDC( HDC16 hdc, short level )
+BOOL16 RestoreDC16( HDC16 hdc, INT16 level )
+{
+    return RestoreDC32( hdc, level );
+}
+
+
+/***********************************************************************
+ *           RestoreDC32    (GDI32.290)
+ */
+BOOL32 RestoreDC32( HDC32 hdc, INT32 level )
 {
     DC * dc, * dcs;
 
@@ -498,15 +556,15 @@
 	return TRUE;
     }
     if (level == -1) level = dc->saveLevel;
-    if ((level < 1) || (level > (short)dc->saveLevel)) return FALSE;
+    if ((level < 1) || (level > dc->saveLevel)) return FALSE;
     
-    while ((short)dc->saveLevel >= level)
+    while (dc->saveLevel >= level)
     {
 	HDC16 hdcs = dc->header.hNext;
 	if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return FALSE;
 	dc->header.hNext = dcs->header.hNext;
-	if ((short)--dc->saveLevel < level) SetDCState( hdc, hdcs );
-	DeleteDC( hdcs );
+	if (--dc->saveLevel < level) SetDCState( hdc, hdcs );
+	DeleteDC32( hdcs );
     }
     return TRUE;
 }
@@ -557,24 +615,23 @@
 HDC32 CreateDC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
                    const DEVMODE32W *initData )
 { 
-    LPSTR driverA = driver?STRING32_DupUniToAnsi(driver):NULL;
-    LPSTR deviceA = device?STRING32_DupUniToAnsi(device):NULL;
-    LPSTR outputA = output?STRING32_DupUniToAnsi(output):NULL;
-    HDC32 res;
-
-    res = CreateDC16( driverA, deviceA, outputA, (const DEVMODE16 *)initData );
-    if (driverA) free(driverA);
-    if (deviceA) free(deviceA);
-    if (outputA) free(outputA);
+    LPSTR driverA = HEAP_strdupWtoA( GetProcessHeap(), 0, driver );
+    LPSTR deviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, device );
+    LPSTR outputA = HEAP_strdupWtoA( GetProcessHeap(), 0, output );
+    HDC32 res = CreateDC16( driverA, deviceA, outputA,
+                            (const DEVMODE16 *)initData /*FIXME*/ );
+    HeapFree( GetProcessHeap(), 0, driverA );
+    HeapFree( GetProcessHeap(), 0, deviceA );
+    HeapFree( GetProcessHeap(), 0, outputA );
     return res;
 }
 
 
 /***********************************************************************
- *           CreateIC    (GDI.153)
+ *           CreateIC16    (GDI.153)
  */
-HDC16 CreateIC( LPCSTR driver, LPCSTR device, LPCSTR output,
-                const DEVMODE16* initData )
+HDC16 CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
+                  const DEVMODE16* initData )
 {
       /* Nothing special yet for ICs */
     return CreateDC16( driver, device, output, initData );
@@ -582,12 +639,43 @@
 
 
 /***********************************************************************
- *           CreateCompatibleDC    (GDI.52)
+ *           CreateIC32A    (GDI32.49)
  */
-HDC16 CreateCompatibleDC( HDC16 hdc )
+HDC32 CreateIC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
+                   const DEVMODE32A* initData )
+{
+      /* Nothing special yet for ICs */
+    return CreateDC32A( driver, device, output, initData );
+}
+
+
+/***********************************************************************
+ *           CreateIC32W    (GDI32.50)
+ */
+HDC32 CreateIC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
+                   const DEVMODE32W* initData )
+{
+      /* Nothing special yet for ICs */
+    return CreateDC32W( driver, device, output, initData );
+}
+
+
+/***********************************************************************
+ *           CreateCompatibleDC16    (GDI.52)
+ */
+HDC16 CreateCompatibleDC16( HDC16 hdc )
+{
+    return (HDC16)CreateCompatibleDC32( hdc );
+}
+
+
+/***********************************************************************
+ *           CreateCompatibleDC32   (GDI32.31)
+ */
+HDC32 CreateCompatibleDC32( HDC32 hdc )
 {
     DC *dc, *origDC;
-    HBITMAP16 hbitmap;
+    HBITMAP32 hbitmap;
     const DC_FUNCTIONS *funcs;
 
     if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs;
@@ -613,7 +701,7 @@
     if (dc->funcs->pCreateDC &&
         !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
     {
-        dprintf_dc( stddeb, "CreateDC: creation aborted by device\n" );
+        dprintf_dc(stddeb, "CreateCompatibleDC: creation aborted by device\n");
         DeleteObject32( hbitmap );
         GDI_HEAP_FREE( dc->hSelf );
         return 0;
@@ -625,9 +713,18 @@
 
 
 /***********************************************************************
- *           DeleteDC    (GDI.68)
+ *           DeleteDC16    (GDI.68)
  */
-BOOL DeleteDC( HDC16 hdc )
+BOOL16 DeleteDC16( HDC16 hdc )
+{
+    return DeleteDC32( hdc );
+}
+
+
+/***********************************************************************
+ *           DeleteDC32    (GDI32.67)
+ */
+BOOL32 DeleteDC32( HDC32 hdc )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
@@ -641,7 +738,7 @@
 	if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
 	dc->header.hNext = dcs->header.hNext;
 	dc->saveLevel--;
-	DeleteDC( hdcs );
+	DeleteDC32( hdcs );
     }
     
     if (!(dc->w.flags & DC_SAVED))
@@ -662,11 +759,31 @@
 
 
 /***********************************************************************
- *           ResetDC    (GDI.376)
+ *           ResetDC16    (GDI.376)
  */
-HDC16 ResetDC( HDC16 hdc, /* DEVMODE */ void *devmode )
+HDC16 ResetDC16( HDC16 hdc, const DEVMODE16 *devmode )
 {
-    fprintf( stderr, "ResetDC: empty stub!\n" );
+    fprintf( stderr, "ResetDC16: empty stub!\n" );
+    return hdc;
+}
+
+
+/***********************************************************************
+ *           ResetDC32A    (GDI32.287)
+ */
+HDC32 ResetDC32A( HDC32 hdc, const DEVMODE32A *devmode )
+{
+    fprintf( stderr, "ResetDC32A: empty stub!\n" );
+    return hdc;
+}
+
+
+/***********************************************************************
+ *           ResetDC32W    (GDI32.288)
+ */
+HDC32 ResetDC32W( HDC32 hdc, const DEVMODE32W *devmode )
+{
+    fprintf( stderr, "ResetDC32A: empty stub!\n" );
     return hdc;
 }
 
@@ -732,11 +849,20 @@
 
 
 /***********************************************************************
- *           SetTextAlign    (GDI.346)
+ *           SetTextAlign16    (GDI.346)
  */
-WORD SetTextAlign( HDC16 hdc, WORD textAlign )
+UINT16 SetTextAlign16( HDC16 hdc, UINT16 textAlign )
 {
-    WORD prevAlign;
+    return SetTextAlign32( hdc, textAlign );
+}
+
+
+/***********************************************************************
+ *           SetTextAlign32    (GDI32.336)
+ */
+UINT32 SetTextAlign32( HDC32 hdc, UINT32 textAlign )
+{
+    UINT32 prevAlign;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc)
     {
@@ -753,7 +879,7 @@
 /***********************************************************************
  *           GetDCOrgEx  (GDI32.168)
  */
-BOOL32 GetDCOrgEx(HDC32 hDC, LPPOINT32 lpp)
+BOOL32 GetDCOrgEx( HDC32 hDC, LPPOINT32 lpp )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC );
     if (!dc || !lpp) return FALSE;
@@ -762,7 +888,7 @@
     {
        Window root;
        int w, h, border, depth;
-
+       /* FIXME: this is not correct for managed windows */
        XGetGeometry( display, dc->u.x.drawable, &root,
                     &lpp->x, &lpp->y, &w, &h, &border, &depth );
     }
@@ -787,7 +913,7 @@
 /***********************************************************************
  *           SetDCOrg    (GDI.117)
  */
-DWORD SetDCOrg( HDC16 hdc, short x, short y )
+DWORD SetDCOrg( HDC16 hdc, INT16 x, INT16 y )
 {
     DWORD prevOrg;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
diff --git a/objects/dcvalues.c b/objects/dcvalues.c
index b497558..b90b484 100644
--- a/objects/dcvalues.c
+++ b/objects/dcvalues.c
@@ -5,16 +5,25 @@
  *
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include "gdi.h"
 #include "metafile.h"
 
 
-#define DC_GET_VAL( func_type, func_name, dc_field ) \
+#define DC_GET_VAL_16( func_type, func_name, dc_field ) \
 func_type func_name( HDC16 hdc ) \
 { \
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
     if (!dc) return 0; \
-    return dc->w.dc_field; \
+    return dc->dc_field; \
+}
+
+#define DC_GET_VAL_32( func_type, func_name, dc_field ) \
+func_type func_name( HDC32 hdc ) \
+{ \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if (!dc) return 0; \
+    return dc->dc_field; \
 }
 
 #define DC_GET_X_Y( func_type, func_name, ret_x, ret_y ) \
@@ -22,7 +31,7 @@
 { \
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
     if (!dc) return 0; \
-    return MAKELONG( dc->w.ret_x, dc->w.ret_y ); \
+    return MAKELONG( dc->ret_x, dc->ret_y ); \
 }
 
 #define DC_GET_VAL_EX( func_name, ret_x, ret_y ) \
@@ -30,8 +39,8 @@
 { \
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
     if (!dc) return FALSE; \
-    pt->x = dc->w.ret_x; \
-    pt->y = dc->w.ret_y; \
+    pt->x = dc->ret_x; \
+    pt->y = dc->ret_y; \
     return TRUE; \
 } \
  \
@@ -39,15 +48,15 @@
 { \
     DC * dc = (DC *) GDI_GetObjPtr( (HDC16)hdc, DC_MAGIC ); \
     if (!dc) return FALSE; \
-    pt->x = dc->w.ret_x; \
-    pt->y = dc->w.ret_y; \
+    pt->x = dc->ret_x; \
+    pt->y = dc->ret_y; \
     return TRUE; \
 }
 
-#define DC_SET_MODE( func_name, dc_field, min_val, max_val, meta_func ) \
-WORD func_name( HDC16 hdc, WORD mode ) \
+#define DC_SET_MODE_16( func_name, dc_field, min_val, max_val, meta_func ) \
+INT16 func_name( HDC16 hdc, INT16 mode ) \
 { \
-    WORD prevMode; \
+    INT16 prevMode; \
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
     if ((mode < min_val) || (mode > max_val)) return 0; \
     if (!dc) { \
@@ -56,47 +65,85 @@
 	MF_MetaParam1(dc, meta_func, mode); \
 	return 1; \
     } \
-    prevMode = dc->w.dc_field; \
-    dc->w.dc_field = mode; \
+    prevMode = dc->dc_field; \
+    dc->dc_field = mode; \
+    return prevMode; \
+}
+
+#define DC_SET_MODE_32( func_name, dc_field, min_val, max_val, meta_func ) \
+INT32 func_name( HDC32 hdc, INT32 mode ) \
+{ \
+    INT32 prevMode; \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if ((mode < min_val) || (mode > max_val)) return 0; \
+    if (!dc) { \
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); \
+	if (!dc) return 0; \
+	MF_MetaParam1(dc, meta_func, mode); \
+	return 1; \
+    } \
+    prevMode = dc->dc_field; \
+    dc->dc_field = mode; \
     return prevMode; \
 }
 
 
-DC_SET_MODE( SetBkMode, backgroundMode, TRANSPARENT, OPAQUE,
-	     META_SETBKMODE )                                     /* GDI.2 */
-DC_SET_MODE( SetROP2, ROPmode, R2_BLACK, R2_WHITE, META_SETROP2 ) /* GDI.4 */
-DC_SET_MODE( SetRelAbs, relAbsMode, ABSOLUTE, RELATIVE,
-	     META_SETRELABS )                                     /* GDI.5 */
-DC_SET_MODE( SetPolyFillMode, polyFillMode, ALTERNATE, WINDING,
-	     META_SETPOLYFILLMODE )                               /* GDI.6 */
-DC_SET_MODE( SetStretchBltMode, stretchBltMode,
-	     BLACKONWHITE, COLORONCOLOR, META_SETSTRETCHBLTMODE ) /* GDI.7 */
-DC_GET_VAL( COLORREF, GetBkColor, backgroundColor )               /* GDI.75 */
-DC_GET_VAL( WORD, GetBkMode, backgroundMode )                     /* GDI.76 */
-DC_GET_X_Y( DWORD, GetCurrentPosition, CursPosX, CursPosY )       /* GDI.78 */
-DC_GET_VAL( WORD, GetMapMode, MapMode )                           /* GDI.81 */
-DC_GET_VAL( WORD, GetPolyFillMode, polyFillMode )                 /* GDI.84 */
-DC_GET_VAL( WORD, GetROP2, ROPmode )                              /* GDI.85 */
-DC_GET_VAL( WORD, GetRelAbs, relAbsMode )                         /* GDI.86 */
-DC_GET_VAL( WORD, GetStretchBltMode, stretchBltMode )             /* GDI.88 */
-DC_GET_VAL( COLORREF, GetTextColor, textColor )                   /* GDI.90 */
-DC_GET_X_Y( DWORD, GetViewportExt, VportExtX, VportExtY )         /* GDI.94 */
-DC_GET_X_Y( DWORD, GetViewportOrg, VportOrgX, VportOrgY )         /* GDI.95 */
-DC_GET_X_Y( DWORD, GetWindowExt, WndExtX, WndExtY )               /* GDI.96 */
-DC_GET_X_Y( DWORD, GetWindowOrg, WndOrgX, WndOrgY )               /* GDI.97 */
-DC_GET_VAL( HRGN32, InquireVisRgn, hVisRgn )                      /* GDI.131 */
-DC_GET_X_Y( DWORD, GetBrushOrg, brushOrgX, brushOrgY )            /* GDI.149 */
-DC_GET_VAL( WORD, GetTextAlign, textAlign )                       /* GDI.345 */
-DC_GET_VAL( HFONT16, GetCurLogFont, hFont )                       /* GDI.411 */
-DC_GET_VAL_EX( GetBrushOrgEx, brushOrgX, brushOrgY )              /* GDI.469 */
-DC_GET_VAL_EX( GetCurrentPositionEx, CursPosX, CursPosY )         /* GDI.470 */
-DC_GET_VAL_EX( GetViewportExtEx, VportExtX, VportExtY )           /* GDI.472 */
-DC_GET_VAL_EX( GetViewportOrgEx, VportOrgX, VportOrgY )           /* GDI.473 */
-DC_GET_VAL_EX( GetWindowExtEx, WndExtX, WndExtY )                 /* GDI.474 */
-DC_GET_VAL_EX( GetWindowOrgEx, WndOrgX, WndOrgY )                 /* GDI.475 */
+DC_SET_MODE_16( SetBkMode16, w.backgroundMode, TRANSPARENT,     /* GDI.2     */
+                OPAQUE, META_SETBKMODE )
+DC_SET_MODE_32( SetBkMode32, w.backgroundMode, TRANSPARENT,     /* GDI32.306 */
+                OPAQUE, META_SETBKMODE )
+DC_SET_MODE_16( SetROP216, w.ROPmode, R2_BLACK, R2_WHITE,       /* GDI.4     */
+                META_SETROP2 )
+DC_SET_MODE_32( SetROP232, w.ROPmode, R2_BLACK, R2_WHITE,       /* GDI32.331 */
+                META_SETROP2 )
+DC_SET_MODE_16( SetRelAbs16, w.relAbsMode, ABSOLUTE, RELATIVE,  /* GDI.5     */
+                META_SETRELABS )
+DC_SET_MODE_32( SetRelAbs32, w.relAbsMode, ABSOLUTE, RELATIVE,  /* GDI32.333 */
+                META_SETRELABS )
+DC_SET_MODE_16( SetPolyFillMode16, w.polyFillMode,              /* GDI.6     */
+                ALTERNATE, WINDING, META_SETPOLYFILLMODE )
+DC_SET_MODE_32( SetPolyFillMode32, w.polyFillMode,              /* GDI32.330 */
+                ALTERNATE, WINDING, META_SETPOLYFILLMODE )
+DC_SET_MODE_16( SetStretchBltMode16, w.stretchBltMode,          /* GDI.7     */
+                BLACKONWHITE, COLORONCOLOR, META_SETSTRETCHBLTMODE )
+DC_SET_MODE_32( SetStretchBltMode32, w.stretchBltMode,          /* GDI32.334 */
+                BLACKONWHITE, COLORONCOLOR, META_SETSTRETCHBLTMODE )
+DC_GET_VAL_16( COLORREF, GetBkColor16, w.backgroundColor )      /* GDI.75    */
+DC_GET_VAL_32( COLORREF, GetBkColor32, w.backgroundColor )      /* GDI32.145 */
+DC_GET_VAL_16( INT16, GetBkMode16, w.backgroundMode )           /* GDI.76    */
+DC_GET_VAL_32( INT32, GetBkMode32, w.backgroundMode )           /* GDI32.146 */
+DC_GET_X_Y( DWORD, GetCurrentPosition, w.CursPosX, w.CursPosY ) /* GDI.78    */
+DC_GET_VAL_16( INT16, GetMapMode16, w.MapMode )                 /* GDI.81    */
+DC_GET_VAL_32( INT32, GetMapMode32, w.MapMode )                 /* GDI32.196 */
+DC_GET_VAL_16( INT16, GetPolyFillMode16, w.polyFillMode )       /* GDI.84    */
+DC_GET_VAL_32( INT32, GetPolyFillMode32, w.polyFillMode )       /* GDI32.213 */
+DC_GET_VAL_16( INT16, GetROP216, w.ROPmode )                    /* GDI.85    */
+DC_GET_VAL_32( INT32, GetROP232, w.ROPmode )                    /* GDI32.214 */
+DC_GET_VAL_16( INT16, GetRelAbs16, w.relAbsMode )               /* GDI.86    */
+DC_GET_VAL_32( INT32, GetRelAbs32, w.relAbsMode )               /* GDI32.218 */
+DC_GET_VAL_16( INT16, GetStretchBltMode16, w.stretchBltMode )   /* GDI.88    */
+DC_GET_VAL_32( INT32, GetStretchBltMode32, w.stretchBltMode )   /* GDI32.221 */
+DC_GET_VAL_16( COLORREF, GetTextColor16, w.textColor )          /* GDI.90    */
+DC_GET_VAL_32( COLORREF, GetTextColor32, w.textColor )          /* GDI32.227 */
+DC_GET_X_Y( DWORD, GetViewportExt, vportExtX, vportExtY )       /* GDI.94    */
+DC_GET_X_Y( DWORD, GetViewportOrg, vportOrgX, vportOrgY )       /* GDI.95    */
+DC_GET_X_Y( DWORD, GetWindowExt, wndExtX, wndExtY )             /* GDI.96    */
+DC_GET_X_Y( DWORD, GetWindowOrg, wndOrgX, wndOrgY )             /* GDI.97    */
+DC_GET_VAL_16( HRGN16, InquireVisRgn, w.hVisRgn )               /* GDI.131   */
+DC_GET_X_Y( DWORD, GetBrushOrg, w.brushOrgX, w.brushOrgY )      /* GDI.149   */
+DC_GET_VAL_16( UINT16, GetTextAlign16, w.textAlign )            /* GDI.345   */
+DC_GET_VAL_32( UINT32, GetTextAlign32, w.textAlign )            /* GDI32.224 */
+DC_GET_VAL_16( HFONT16, GetCurLogFont, w.hFont )                /* GDI.411   */
+DC_GET_VAL_EX( GetBrushOrgEx, w.brushOrgX, w.brushOrgY )/* GDI.469 GDI32.148 */
+DC_GET_VAL_EX( GetCurrentPositionEx, w.CursPosX,        /* GDI.470 GDI32.167 */
+               w.CursPosY )
+DC_GET_VAL_EX( GetViewportExtEx, vportExtX, vportExtY ) /* GDI.472 GDI32.239 */
+DC_GET_VAL_EX( GetViewportOrgEx, vportOrgX, vportOrgY ) /* GDI.473 GDI32.240 */
+DC_GET_VAL_EX( GetWindowExtEx, wndExtX, wndExtY )       /* GDI.474 GDI32.242 */
+DC_GET_VAL_EX( GetWindowOrgEx, wndOrgX, wndOrgY )       /* GDI.475 GDI32.243 */
 
 /* this one is wrong - Windows returns region that
    is relative to the device and not to the DC origin */
 
-DC_GET_VAL( HRGN16, GetClipRgn16, hClipRgn )                      /* GDI.173 */
+DC_GET_VAL_16( HRGN16, GetClipRgn16, w.hClipRgn )              /* GDI.173    */
 
diff --git a/objects/dib.c b/objects/dib.c
index 7f37367..66f8d8f 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -4,6 +4,7 @@
  * Copyright 1993,1994  Alexandre Julliard
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <stdio.h>
 #include <stdlib.h>
 #include <X11/Xlib.h>
@@ -134,7 +135,7 @@
                                BITMAPINFO *info )
 {
     int i, colors;
-    BOOL isInfo;
+    BOOL32 isInfo;
     WORD *colorPtr;
     int *colorMapping;
 
@@ -196,10 +197,10 @@
  *
  * SetDIBits for a 1-bit deep DIB.
  */
-static void DIB_SetImageBits_1( WORD lines, BYTE *bits, WORD width,
+static void DIB_SetImageBits_1( DWORD lines, BYTE *bits, DWORD width,
                                 int *colors, XImage *bmpImage )
 {
-    WORD i, x;
+    DWORD i, x;
     BYTE pad, pix;
 
     if (!(width & 31)) pad = 0;
@@ -240,10 +241,10 @@
  *
  * SetDIBits for a 4-bit deep DIB.
  */
-static void DIB_SetImageBits_4( WORD lines, BYTE *bits, WORD width,
+static void DIB_SetImageBits_4( DWORD lines, BYTE *bits, DWORD width,
                                 int *colors, XImage *bmpImage )
 {
-    WORD i, x;
+    DWORD i, x;
     BYTE pad;
 
     if (!(width & 7)) pad = 0;
@@ -274,14 +275,14 @@
  *
  * SetDIBits for a 4-bit deep compressed DIB.
  */
-static void DIB_SetImageBits_RLE4( WORD lines, BYTE *bits, WORD width,
+static void DIB_SetImageBits_RLE4( DWORD lines, BYTE *bits, DWORD width,
                                    int *colors, XImage *bmpImage )
 {
 	int x = 0, c, length;
 	BYTE *begin = bits;
 
         lines--;
-	while ((short)lines >= 0)
+	while ((int)lines >= 0)
         {
 		length = *bits++;
 		if (length) {	/* encoded */
@@ -334,10 +335,10 @@
  *
  * SetDIBits for an 8-bit deep DIB.
  */
-static void DIB_SetImageBits_8( WORD lines, BYTE *bits, WORD width,
+static void DIB_SetImageBits_8( DWORD lines, BYTE *bits, DWORD width,
                                 int *colors, XImage *bmpImage )
 {
-    WORD x;
+    DWORD x;
     BYTE pad = (4 - (width & 3)) & 3;
 
     while (lines--)
@@ -379,11 +380,8 @@
   RleDelta	= 2		/* Delta */
 };
   
-static void DIB_SetImageBits_RLE8(WORD lines, 
-				  BYTE *bits, 
-				  WORD width,
-				  int *colors, 
-				  XImage *bmpImage)
+static void DIB_SetImageBits_RLE8( DWORD lines, BYTE *bits, DWORD width,
+                                   int *colors, XImage *bmpImage )
 {
     int x;			/* X-positon on each line.  Increases. */
     int line;			/* Line #.  Starts at lines-1, decreases */
@@ -535,10 +533,10 @@
  *
  * SetDIBits for a 24-bit deep DIB.
  */
-static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width,
+static void DIB_SetImageBits_24( DWORD lines, BYTE *bits, DWORD width,
 				 DC *dc, XImage *bmpImage )
 {
-    WORD x;
+    DWORD x;
     BYTE pad = (4 - ((width*3) & 3)) & 3;
 
     /* "bits" order is reversed for some reason */
@@ -560,7 +558,7 @@
  * Transfer the bits to an X image.
  * Helper function for SetDIBits() and SetDIBitsToDevice().
  */
-static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits,
+static int DIB_SetImageBits( DC *dc, DWORD lines, WORD depth, LPSTR bits,
                              DWORD infoWidth, WORD infoBpp,
                              BITMAPINFO *info, WORD coloruse,
 			     Drawable drawable, GC gc, int xSrc, int ySrc,
@@ -643,24 +641,36 @@
     HBITMAP32 hBitmap, hOldBitmap;
     HDC32 hdcMem;
 
-    hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
-                              bits, info, wUsage );
-    hdcMem = CreateCompatibleDC( hdc );
+    hBitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
+                                bits, info, wUsage );
+    hdcMem = CreateCompatibleDC32( hdc );
     hOldBitmap = SelectObject32( hdcMem, hBitmap );
     StretchBlt32( hdc, xDst, yDst, widthDst, heightDst,
                   hdcMem, xSrc, ySrc, widthSrc, heightSrc, dwRop );
     SelectObject32( hdcMem, hOldBitmap );
-    DeleteDC( hdcMem );
+    DeleteDC32( hdcMem );
     DeleteObject32( hBitmap );
     return heightSrc;
 }
 
 
 /***********************************************************************
- *           SetDIBits    (GDI.440) (GDI32.312)
+ *           SetDIBits16    (GDI.440)
  */
-INT16 SetDIBits( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan, UINT32 lines,
-                 LPCVOID bits, const BITMAPINFO *info, UINT32 coloruse )
+INT16 SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
+                   UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
+                   UINT16 coloruse )
+{
+    return SetDIBits32( hdc, hbitmap, startscan, lines, bits, info, coloruse );
+}
+
+
+/***********************************************************************
+ *           SetDIBits32   (GDI32.312)
+ */
+INT32 SetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan,
+                   UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
+                   UINT32 coloruse )
 {
     DC * dc;
     BITMAPOBJ * bmp;
@@ -692,12 +702,25 @@
 
 
 /***********************************************************************
- *           SetDIBitsToDevice    (GDI.443) (GDI32.313)
+ *           SetDIBitsToDevice16    (GDI.443)
  */
-INT16 SetDIBitsToDevice( HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx,
-                         DWORD cy, INT32 xSrc, INT32 ySrc, UINT32 startscan,
-                         UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
-                         UINT32 coloruse )
+INT16 SetDIBitsToDevice16( HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
+                           INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
+                           UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
+                           UINT16 coloruse )
+{
+    return SetDIBitsToDevice32( hdc, xDest, yDest, cx, cy, xSrc, ySrc,
+                                startscan, lines, bits, info, coloruse );
+}
+
+
+/***********************************************************************
+ *           SetDIBitsToDevice32   (GDI32.313)
+ */
+INT32 SetDIBitsToDevice32( HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx,
+                           DWORD cy, INT32 xSrc, INT32 ySrc, UINT32 startscan,
+                           UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
+                           UINT32 coloruse )
 {
     DC * dc;
     DWORD width, height;
@@ -737,10 +760,22 @@
 
 
 /***********************************************************************
- *           GetDIBits    (GDI.441)
+ *           GetDIBits16    (GDI.441)
  */
-int GetDIBits( HDC16 hdc, HBITMAP16 hbitmap, WORD startscan, WORD lines,
-	       LPSTR bits, BITMAPINFO * info, WORD coloruse )
+INT16 GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
+                   UINT16 lines, LPSTR bits, BITMAPINFO * info,
+                   UINT16 coloruse )
+{
+    return GetDIBits32( hdc, hbitmap, startscan, lines, bits, info, coloruse );
+}
+
+
+/***********************************************************************
+ *           GetDIBits32    (GDI32.170)
+ */
+INT32 GetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan,
+                   UINT32 lines, LPSTR bits, BITMAPINFO * info,
+                   UINT32 coloruse )
 {
     DC * dc;
     BITMAPOBJ * bmp;
@@ -805,13 +840,25 @@
 
 
 /***********************************************************************
- *           CreateDIBitmap    (GDI.442)
+ *           CreateDIBitmap16    (GDI.442)
  */
-HBITMAP16 CreateDIBitmap( HDC16 hdc, BITMAPINFOHEADER * header, DWORD init,
-                          LPVOID bits, BITMAPINFO * data, UINT coloruse )
+HBITMAP16 CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
+                            DWORD init, LPCVOID bits, const BITMAPINFO * data,
+                            UINT16 coloruse )
 {
-    HBITMAP16 handle;
-    BOOL fColor;
+    return CreateDIBitmap32( hdc, header, init, bits, data, coloruse );
+}
+
+
+/***********************************************************************
+ *           CreateDIBitmap32    (GDI32.37)
+ */
+HBITMAP32 CreateDIBitmap32( HDC32 hdc, const BITMAPINFOHEADER *header,
+                            DWORD init, LPCVOID bits, const BITMAPINFO *data,
+                            UINT32 coloruse )
+{
+    HBITMAP32 handle;
+    BOOL32 fColor;
     DWORD width, height;
     WORD bpp;
 
@@ -866,6 +913,6 @@
     if (!handle) return 0;
 
     if (init == CBM_INIT)
-        SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
+        SetDIBits32( hdc, handle, 0, height, bits, data, coloruse );
     return handle;
 }
diff --git a/objects/font.c b/objects/font.c
index 40f12a2..cc54c0b 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -14,9 +14,9 @@
 #include <string.h>
 #include <X11/Xatom.h>
 #include "font.h"
+#include "heap.h"
 #include "metafile.h"
 #include "options.h"
-#include "string32.h"
 #include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -133,7 +133,7 @@
   int i;
 
   for (i = 1; i < FontSize; i ++)
-    if( !strcmp( winFaceName, FontNames[i].window ) ) {
+    if( !lstrcmpi32A( winFaceName, FontNames[i].window ) ) {
       dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
       return FontNames[i].x11;
     }
@@ -163,7 +163,7 @@
     if (font->lfHeight == -1)
 	height = 0;
     else
-	height = font->lfHeight * dc->w.VportExtX / dc->w.WndExtX;
+	height = font->lfHeight * dc->vportExtX / dc->wndExtX;
     if (height == 0) height = 120;  /* Default height = 12 */
     else if (height < 0)
     {
@@ -180,7 +180,7 @@
         height = (height-2) * -10; 
     }
     else height *= 10;
-    width  = 10 * (font->lfWidth * dc->w.VportExtY / dc->w.WndExtY);
+    width  = 10 * (font->lfWidth * dc->vportExtY / dc->wndExtY);
     if (width < 0) {
 	dprintf_font( stddeb, "FONT_MatchFont: negative width %d(%d)\n",
 		      width, font->lfWidth );
@@ -279,8 +279,8 @@
     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 ;-) */  
-    AnsiUpper(font->lfFaceName);
+    /* we need a font name for function GetTextFace() even if there isn't one ;-) */  
+    /*AnsiUpper(font->lfFaceName);*/
 
     fontStruct = XLoadQueryFont( display, *names );
     XFreeFontNames( names );
@@ -289,6 +289,98 @@
 
 
 /***********************************************************************
+ *           FONT_LOGFONT32AToLOGFONT16
+ */
+static void FONT_LOGFONT32AToLOGFONT16( const LOGFONT32A *font,
+                                        LPLOGFONT16 font16 )
+{
+    font16->lfHeight         = (INT16)font->lfHeight;
+    font16->lfWidth          = (INT16)font->lfWidth;
+    font16->lfEscapement     = (INT16)font->lfEscapement;
+    font16->lfOrientation    = (INT16)font->lfOrientation;
+    font16->lfWeight         = (INT16)font->lfWeight;
+    font16->lfItalic         = font->lfItalic;
+    font16->lfUnderline      = font->lfUnderline;
+    font16->lfStrikeOut      = font->lfStrikeOut;
+    font16->lfCharSet        = font->lfCharSet;
+    font16->lfOutPrecision   = font->lfOutPrecision;
+    font16->lfClipPrecision  = font->lfClipPrecision;
+    font16->lfQuality        = font->lfQuality;
+    font16->lfPitchAndFamily = font->lfPitchAndFamily;
+    lstrcpyn32A( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
+}
+
+
+/***********************************************************************
+ *           FONT_LOGFONT32WToLOGFONT16
+ */
+static void FONT_LOGFONT32WToLOGFONT16( const LOGFONT32W *font,
+                                        LPLOGFONT16 font16 )
+{
+    font16->lfHeight         = (INT16)font->lfHeight;
+    font16->lfWidth          = (INT16)font->lfWidth;
+    font16->lfEscapement     = (INT16)font->lfEscapement;
+    font16->lfOrientation    = (INT16)font->lfOrientation;
+    font16->lfWeight         = (INT16)font->lfWeight;
+    font16->lfItalic         = font->lfItalic;
+    font16->lfUnderline      = font->lfUnderline;
+    font16->lfStrikeOut      = font->lfStrikeOut;
+    font16->lfCharSet        = font->lfCharSet;
+    font16->lfOutPrecision   = font->lfOutPrecision;
+    font16->lfClipPrecision  = font->lfClipPrecision;
+    font16->lfQuality        = font->lfQuality;
+    font16->lfPitchAndFamily = font->lfPitchAndFamily;
+    lstrcpynWtoA( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
+}
+
+
+/***********************************************************************
+ *           FONT_LOGFONT16ToLOGFONT32A
+ */
+static void FONT_LOGFONT16ToLOGFONT32A( LPLOGFONT16 font,
+                                        LPLOGFONT32A font32A )
+{
+    font32A->lfHeight         = (INT32)font->lfHeight;
+    font32A->lfWidth          = (INT32)font->lfWidth;
+    font32A->lfEscapement     = (INT32)font->lfEscapement;
+    font32A->lfOrientation    = (INT32)font->lfOrientation;
+    font32A->lfWeight         = (INT32)font->lfWeight;
+    font32A->lfItalic         = font->lfItalic;
+    font32A->lfUnderline      = font->lfUnderline;
+    font32A->lfStrikeOut      = font->lfStrikeOut;
+    font32A->lfCharSet        = font->lfCharSet;
+    font32A->lfOutPrecision   = font->lfOutPrecision;
+    font32A->lfClipPrecision  = font->lfClipPrecision;
+    font32A->lfQuality        = font->lfQuality;
+    font32A->lfPitchAndFamily = font->lfPitchAndFamily;
+    lstrcpyn32A( font32A->lfFaceName, font->lfFaceName, LF_FACESIZE );
+}
+
+
+/***********************************************************************
+ *           FONT_LOGFONT16ToLOGFONT32W
+ */
+static void FONT_LOGFONT16ToLOGFONT32W( LPLOGFONT16 font,
+                                        LPLOGFONT32W font32W )
+{
+    font32W->lfHeight         = (INT32)font->lfHeight;
+    font32W->lfWidth          = (INT32)font->lfWidth;
+    font32W->lfEscapement     = (INT32)font->lfEscapement;
+    font32W->lfOrientation    = (INT32)font->lfOrientation;
+    font32W->lfWeight         = (INT32)font->lfWeight;
+    font32W->lfItalic         = font->lfItalic;
+    font32W->lfUnderline      = font->lfUnderline;
+    font32W->lfStrikeOut      = font->lfStrikeOut;
+    font32W->lfCharSet        = font->lfCharSet;
+    font32W->lfOutPrecision   = font->lfOutPrecision;
+    font32W->lfClipPrecision  = font->lfClipPrecision;
+    font32W->lfQuality        = font->lfQuality;
+    font32W->lfPitchAndFamily = font->lfPitchAndFamily;
+    lstrcpynAtoW( font32W->lfFaceName, font->lfFaceName, LF_FACESIZE );
+}
+
+
+/***********************************************************************
  *           FONT_GetMetrics
  */
 void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
@@ -356,78 +448,6 @@
     return (DWORD)-1; /* failure */
 }
 
-void
-FONT_LOGFONT32AToLOGFONT16(const LOGFONT32A *font,LPLOGFONT16 font16) {
-    font16->lfHeight         = (INT16)font->lfHeight;
-    font16->lfWidth          = (INT16)font->lfWidth;
-    font16->lfEscapement     = (INT16)font->lfEscapement;
-    font16->lfOrientation    = (INT16)font->lfOrientation;
-    font16->lfWeight         = (INT16)font->lfWeight;
-    font16->lfItalic         = font->lfItalic;
-    font16->lfUnderline      = font->lfUnderline;
-    font16->lfStrikeOut      = font->lfStrikeOut;
-    font16->lfCharSet        = font->lfCharSet;
-    font16->lfOutPrecision   = font->lfOutPrecision;
-    font16->lfClipPrecision  = font->lfClipPrecision;
-    font16->lfQuality        = font->lfQuality;
-    font16->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpyn32A( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
-}
-
-void
-FONT_LOGFONT32WToLOGFONT16(const LOGFONT32W *font,LPLOGFONT16 font16) {
-    font16->lfHeight         = (INT16)font->lfHeight;
-    font16->lfWidth          = (INT16)font->lfWidth;
-    font16->lfEscapement     = (INT16)font->lfEscapement;
-    font16->lfOrientation    = (INT16)font->lfOrientation;
-    font16->lfWeight         = (INT16)font->lfWeight;
-    font16->lfItalic         = font->lfItalic;
-    font16->lfUnderline      = font->lfUnderline;
-    font16->lfStrikeOut      = font->lfStrikeOut;
-    font16->lfCharSet        = font->lfCharSet;
-    font16->lfOutPrecision   = font->lfOutPrecision;
-    font16->lfClipPrecision  = font->lfClipPrecision;
-    font16->lfQuality        = font->lfQuality;
-    font16->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpynWtoA( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
-}
-
-void
-FONT_LOGFONT16ToLOGFONT32A(LPLOGFONT16 font,LPLOGFONT32A font32A) {
-    font32A->lfHeight         = (INT32)font->lfHeight;
-    font32A->lfWidth          = (INT32)font->lfWidth;
-    font32A->lfEscapement     = (INT32)font->lfEscapement;
-    font32A->lfOrientation    = (INT32)font->lfOrientation;
-    font32A->lfWeight         = (INT32)font->lfWeight;
-    font32A->lfItalic         = font->lfItalic;
-    font32A->lfUnderline      = font->lfUnderline;
-    font32A->lfStrikeOut      = font->lfStrikeOut;
-    font32A->lfCharSet        = font->lfCharSet;
-    font32A->lfOutPrecision   = font->lfOutPrecision;
-    font32A->lfClipPrecision  = font->lfClipPrecision;
-    font32A->lfQuality        = font->lfQuality;
-    font32A->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpyn32A( font32A->lfFaceName, font->lfFaceName, LF_FACESIZE );
-}
-
-void
-FONT_LOGFONT16ToLOGFONT32W(LPLOGFONT16 font,LPLOGFONT32W font32W) {
-    font32W->lfHeight         = (INT32)font->lfHeight;
-    font32W->lfWidth          = (INT32)font->lfWidth;
-    font32W->lfEscapement     = (INT32)font->lfEscapement;
-    font32W->lfOrientation    = (INT32)font->lfOrientation;
-    font32W->lfWeight         = (INT32)font->lfWeight;
-    font32W->lfItalic         = font->lfItalic;
-    font32W->lfUnderline      = font->lfUnderline;
-    font32W->lfStrikeOut      = font->lfStrikeOut;
-    font32W->lfCharSet        = font->lfCharSet;
-    font32W->lfOutPrecision   = font->lfOutPrecision;
-    font32W->lfClipPrecision  = font->lfClipPrecision;
-    font32W->lfQuality        = font->lfQuality;
-    font32W->lfPitchAndFamily = font->lfPitchAndFamily;
-    lstrcpynAtoW( font32W->lfFaceName, font->lfFaceName, LF_FACESIZE );
-}
-
 
 /***********************************************************************
  *           CreateScalableFontResource    (GDI.310)
@@ -535,12 +555,12 @@
                        DWORD clippres, DWORD quality, DWORD pitch,
                        LPCWSTR name )
 {
-    LPSTR namea = name ? STRING32_DupUniToAnsi(name) : NULL;
+    LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
     HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
                                          italic, underline, strikeout, charset,
                                          outpres, clippres, quality, pitch,
                                          namea );
-    free(namea);
+    HeapFree( GetProcessHeap(), 0, namea );
     return ret;
 }
 
@@ -748,41 +768,71 @@
 
 
 /***********************************************************************
- *           GetTextCharacterExtra    (GDI.89)
+ *           GetTextCharacterExtra16    (GDI.89)
  */
-short GetTextCharacterExtra( HDC16 hdc )
+INT16 GetTextCharacterExtra16( HDC16 hdc )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
-    return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
-	         / dc->w.VportExtX );
+    return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
+	         / dc->vportExtX );
 }
 
 
 /***********************************************************************
- *           SetTextCharacterExtra    (GDI.8)
+ *           GetTextCharacterExtra32    (GDI32.225)
  */
-short SetTextCharacterExtra( HDC16 hdc, short extra )
+INT32 GetTextCharacterExtra32( HDC32 hdc )
 {
-    short prev;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
-    extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;    
+    return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
+	         / dc->vportExtX );
+}
+
+
+/***********************************************************************
+ *           SetTextCharacterExtra16    (GDI.8)
+ */
+INT16 SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
+{
+    return (INT16)SetTextCharacterExtra32( hdc, extra );
+}
+
+
+/***********************************************************************
+ *           SetTextCharacterExtra32    (GDI32.337)
+ */
+INT32 SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
+{
+    INT32 prev;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;    
     prev = dc->w.charExtra;
     dc->w.charExtra = abs(extra);
-    return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
+    return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
 }
 
 
 /***********************************************************************
- *           SetTextJustification    (GDI.10)
+ *           SetTextJustification16    (GDI.10)
  */
-short SetTextJustification( HDC16 hdc, short extra, short breaks )
+INT16 SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
+{
+    return SetTextJustification32( hdc, extra, breaks );
+}
+
+
+/***********************************************************************
+ *           SetTextJustification32    (GDI32.339)
+ */
+BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
 
-    extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
+    extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
     if (!extra) breaks = 0;
     dc->w.breakTotalExtra = extra;
     dc->w.breakCount = breaks;
@@ -799,6 +849,7 @@
     return 1;
 }
 
+
 /***********************************************************************
  *           GetTextFace16    (GDI.92)
  */
@@ -827,11 +878,10 @@
  */
 INT32 GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
 {
-    LPSTR nameA = (LPSTR)xmalloc(count);
+    LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
     INT32 res = GetTextFace32A(hdc,count,nameA);
-
-    lstrcpynAtoW(name,nameA,count);
-    free(nameA);
+    lstrcpyAtoW( name, nameA );
+    HeapFree( GetProcessHeap(), 0, nameA );
     return res;
 }
 
@@ -839,7 +889,7 @@
 /***********************************************************************
  *           GetTextExtent    (GDI.91)
  */
-DWORD GetTextExtent( HDC16 hdc, LPCSTR str, short count )
+DWORD GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
 {
     SIZE16 size;
     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
@@ -892,9 +942,9 @@
 BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
                               LPSIZE32 size )
 {
-    char *p = STRING32_DupUniToAnsi( str );
+    LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
-    free( p );
+    HeapFree( GetProcessHeap(), 0, p );
     return ret;
 }
 
@@ -967,10 +1017,10 @@
                                 INT32 maxExt, LPINT32 lpnFit, LPINT32 alpDx,
                                 LPSIZE32 size )
 {
-    char *p = STRING32_DupUniToAnsi( str );
+    LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
 					lpnFit, alpDx, size);
-    free( p );
+    HeapFree( GetProcessHeap(), 0, p );
     return ret;
 }
 
@@ -984,18 +1034,18 @@
     memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
 
     metrics->tmAscent  = abs( metrics->tmAscent
-			      * dc->w.WndExtY / dc->w.VportExtY );
+			      * dc->wndExtY / dc->vportExtY );
     metrics->tmDescent = abs( metrics->tmDescent
-			      * dc->w.WndExtY / dc->w.VportExtY );
+			      * dc->wndExtY / dc->vportExtY );
     metrics->tmHeight  = metrics->tmAscent + metrics->tmDescent;
     metrics->tmInternalLeading = abs( metrics->tmInternalLeading
-				      * dc->w.WndExtY / dc->w.VportExtY );
+				      * dc->wndExtY / dc->vportExtY );
     metrics->tmExternalLeading = abs( metrics->tmExternalLeading
-				      * dc->w.WndExtY / dc->w.VportExtY );
+				      * dc->wndExtY / dc->vportExtY );
     metrics->tmMaxCharWidth    = abs( metrics->tmMaxCharWidth 
-				      * dc->w.WndExtX / dc->w.VportExtX );
+				      * dc->wndExtX / dc->vportExtX );
     metrics->tmAveCharWidth    = abs( metrics->tmAveCharWidth
-				      * dc->w.WndExtX / dc->w.VportExtX );
+				      * dc->wndExtX / dc->vportExtX );
 
     dprintf_font(stdnimp,"text metrics:\n
 	InternalLeading = %i
@@ -1117,26 +1167,50 @@
 
  
 /***********************************************************************
- *           GetCharABCWidths   (GDI.307)
+ *           GetCharABCWidths16   (GDI.307)
  */
-BOOL GetCharABCWidths(HDC16 hdc, UINT wFirstChar, UINT wLastChar, LPABC16 lpABC)
+BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
+                           LPABC16 abc )
 {
+    ABC32 abc32;
+    if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
+    abc->abcA = abc32.abcA;
+    abc->abcB = abc32.abcB;
+    abc->abcC = abc32.abcC;
+    return TRUE;
+}
 
+
+/***********************************************************************
+ *           GetCharABCWidths32A   (GDI32.149)
+ */
+BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                            LPABC32 abc )
+{
     /* No TrueType fonts in Wine so far */
-
-    fprintf(stdnimp,"STUB: GetCharABCWidths(%04x,%04x,%04x,%08x)\n",
-			   hdc,wFirstChar,wLastChar,(unsigned)lpABC);
-  
+    fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
+             hdc, firstChar, lastChar, abc );
     return FALSE;
 }
 
 
 /***********************************************************************
- *           GetCharWidth    (GDI.350)
+ *           GetCharABCWidths32W   (GDI32.152)
  */
-BOOL GetCharWidth(HDC16 hdc, WORD wFirstChar, WORD wLastChar, LPINT16 lpBuffer)
+BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                            LPABC32 abc )
 {
-    int i, j;
+    return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
+}
+
+
+/***********************************************************************
+ *           GetCharWidth16    (GDI.350)
+ */
+BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
+                       LPINT16 buffer )
+{
+    int i, width;
     XFontStruct *xfont;
     XCharStruct *cs, *def;
 
@@ -1147,25 +1221,68 @@
     /* fixed font? */
     if (xfont->per_char == NULL)
     {
-	for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
-	    *(lpBuffer + j) = xfont->max_bounds.width;
+	for (i = firstChar; i <= lastChar; i++)
+	    *buffer++ = xfont->max_bounds.width;
 	return TRUE;
     }
 
     CI_GET_DEFAULT_INFO(xfont, def);
 	
-    for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
+    for (i = firstChar; i <= lastChar; i++)
     {
-	CI_GET_CHAR_INFO(xfont, i, def, cs);
-	*(lpBuffer + j) = cs ? cs->width : xfont->max_bounds.width;
-	if (*(lpBuffer + j) < 0)
-	    *(lpBuffer + j) = 0;
+	CI_GET_CHAR_INFO( xfont, i, def, cs );
+        width = cs ? cs->width : xfont->max_bounds.width;
+        *buffer++ = MAX( width, 0 );
     }
     return TRUE;
 }
 
 
 /***********************************************************************
+ *           GetCharWidth32A    (GDI32.155)
+ */
+BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                        LPINT32 buffer )
+{
+    int i, width;
+    XFontStruct *xfont;
+    XCharStruct *cs, *def;
+
+    DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
+    if (!dc) return FALSE;
+    xfont = dc->u.x.font.fstruct;
+    
+    /* fixed font? */
+    if (xfont->per_char == NULL)
+    {
+	for (i = firstChar; i <= lastChar; i++)
+	    *buffer++ = xfont->max_bounds.width;
+	return TRUE;
+    }
+
+    CI_GET_DEFAULT_INFO(xfont, def);
+	
+    for (i = firstChar; i <= lastChar; i++)
+    {
+	CI_GET_CHAR_INFO( xfont, i, def, cs );
+        width = cs ? cs->width : xfont->max_bounds.width;
+        *buffer++ = MAX( width, 0 );
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetCharWidth32W    (GDI32.158)
+ */
+BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
+                        LPINT32 buffer )
+{
+    return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
+}
+
+
+/***********************************************************************
  *           AddFontResource    (GDI.119)
  */
 INT AddFontResource( LPCSTR str )
@@ -1217,8 +1334,8 @@
 
 static int logfcmp(const void *a,const void *b) 
 {
-  return strcmp( (*(LPLOGFONT16 *)a)->lfFaceName,
-                 (*(LPLOGFONT16 *)b)->lfFaceName );
+  return lstrcmpi32A( (*(LPLOGFONT16 *)a)->lfFaceName,
+                      (*(LPLOGFONT16 *)b)->lfFaceName );
 }
 
 void InitFontsList(void)
@@ -1256,11 +1373,7 @@
     dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
 
     ParseFontParms(names[i], 2, str, sizeof(str));
-#if 0
-    /* not necessary because new function FONT_ChkX11Family() */
-    if (strcmp(str, "fixed") == 0) strcat(str, "sys");
-#endif    
-    AnsiUpper(str);
+/*    AnsiUpper(str);*/
     strcpy(lpNewFont->lfFaceName, str);
     ParseFontParms(names[i], 8, str, sizeof(str));
     lpNewFont->lfHeight = atoi(str) / 10;
@@ -1423,7 +1536,7 @@
   }
   lpOldName = NULL;
   strcpy(FaceName,lpLF->lfFaceName);
-  AnsiUpper(lpLF->lfFaceName);
+/*  AnsiUpper(lpLF->lfFaceName);*/
 
   if (lpLogFontList[0] == NULL) InitFontsList();
   for(i = 0; lpLogFontList[i] != NULL; i++) {
@@ -1434,11 +1547,15 @@
 
     /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
     /* lfFaceName */
-    if (FaceName[0]) {
-    	if (strcmp(FaceName,lpLogFontList[i]->lfFaceName))
+    if (FaceName[0])
+    {
+    	if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
 	   continue;
-    } else {
-    	if ((lpOldName!=NULL)&&!strcmp(lpOldName,lpLogFontList[i]->lfFaceName))
+    }
+    else
+    {
+    	if ((lpOldName!=NULL) &&
+            !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
 	   continue;
 	lpOldName=lpLogFontList[i]->lfFaceName;
     }
@@ -1500,7 +1617,7 @@
   }
   lpOldName = NULL;
   strcpy(FaceName,lpLF->lfFaceName);
-  AnsiUpper(lpLF->lfFaceName);
+/*  AnsiUpper(lpLF->lfFaceName);*/
 
   if (lpLogFontList[0] == NULL) InitFontsList();
   for(i = 0; lpLogFontList[i] != NULL; i++) {
@@ -1512,10 +1629,11 @@
     /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
     /* lfFaceName */
     if (FaceName[0]) {
-    	if (strcmp(FaceName,lpLogFontList[i]->lfFaceName))
+    	if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
 	   continue;
     } else {
-    	if ((lpOldName!=NULL)&&!strcmp(lpOldName,lpLogFontList[i]->lfFaceName))
+    	if ((lpOldName!=NULL) &&
+            !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
 	   continue;
 	lpOldName=lpLogFontList[i]->lfFaceName;
     }
@@ -1557,19 +1675,15 @@
   LPSTR	       	lpOldName;
   int	       	nRet = 0;
   int	       	i;
-  LPSTR	lpszFamily=STRING32_DupUniToAnsi(lpLF->lfFaceName);
+  LPSTR	lpszFamily;
   
   dprintf_font(stddeb,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
 	       hDC, lpLF, (DWORD)lpEnumFunc, lpData,reserved);
-  if (lpEnumFunc == 0) {
-    free(lpszFamily);
-    return 0;
-  }
+  if (lpEnumFunc == 0) return 0;
   hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W) );
   lpEnumLogFont = (LPENUMLOGFONTEX32W) GDI_HEAP_LIN_ADDR(hLog);
   if (lpEnumLogFont == NULL) {
     fprintf(stderr,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
-    free(lpszFamily);
     return 0;
   }
   hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W) );
@@ -1577,10 +1691,10 @@
   if (lptm == NULL) {
     GDI_HEAP_FREE(hLog);
     fprintf(stderr,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
-    free(lpszFamily);
     return 0;
   }
   lpOldName = NULL;
+  lpszFamily = HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF->lfFaceName );
   AnsiUpper(lpszFamily);
   if (lpLogFontList[0] == NULL) InitFontsList();
   for(i = 0; lpLogFontList[i] != NULL; i++) {
@@ -1592,18 +1706,19 @@
     /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
     /* lfFaceName */
     if (lpszFamily[0]) {
-    	if (strcmp(lpszFamily,lpLogFontList[i]->lfFaceName))
+    	if (lstrcmpi32A(lpszFamily,lpLogFontList[i]->lfFaceName))
 	   continue;
     } else {
-    	if ((lpOldName!=NULL)&&!strcmp(lpOldName,lpLogFontList[i]->lfFaceName))
+    	if ((lpOldName!=NULL) &&
+            !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
 	   continue;
 	lpOldName=lpLogFontList[i]->lfFaceName;
     }
 
     FONT_LOGFONT16ToLOGFONT32W(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
-    lstrcpynAtoW(lpEnumLogFont->elfFullName,"",1);
-    lstrcpynAtoW(lpEnumLogFont->elfStyle,"",1);
-    lstrcpynAtoW(lpEnumLogFont->elfScript,"",1);
+    lpEnumLogFont->elfFullName[0] = 0;
+    lpEnumLogFont->elfStyle[0] = 0;
+    lpEnumLogFont->elfScript[0] = 0;
     hFont = CreateFontIndirect32W((LPLOGFONT32W)lpEnumLogFont);
     hOldFont = SelectObject32(hDC, hFont);
     GetTextMetrics32W(hDC, (LPTEXTMETRIC32W)lptm);
@@ -1619,7 +1734,7 @@
   }
   GDI_HEAP_FREE(hMet);
   GDI_HEAP_FREE(hLog);
-  free(lpszFamily);
+  HeapFree( GetProcessHeap(), 0, lpszFamily );
   return nRet;
 }
 
diff --git a/objects/metafile.c b/objects/metafile.c
index d1891bb..a912ce8 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -205,7 +205,7 @@
 
     if (!MF_MetaParam0(dc, META_EOF))
     {
-        DeleteDC( hdc );
+        DeleteDC32( hdc );
 	return 0;
     }	
 
@@ -215,12 +215,12 @@
 	mh->mtNoParameters = 0;
         if (_llseek(hFile, 0L, 0) == -1)
         {
-            DeleteDC( hdc );
+            DeleteDC32( hdc );
             return 0;
         }
         if (_lwrite32(hFile, (char *)mh, MFHEADERSIZE) == -1)
         {
-            DeleteDC( hdc );
+            DeleteDC32( hdc );
             return 0;
         }
         _lclose(hFile);
@@ -229,7 +229,7 @@
     hmf = physDev->hMetafile;
     GlobalUnlock16( hmf );
     physDev->hMetafile = 0;  /* So it won't be deleted */
-    DeleteDC( hdc );
+    DeleteDC32( hdc );
     return hmf;
 }
 
@@ -409,27 +409,27 @@
 	break;
 
     case META_SETBKMODE:
-	SetBkMode(hdc, *(mr->rdParam));
+	SetBkMode16(hdc, *(mr->rdParam));
 	break;
 
     case META_SETMAPMODE:
-	SetMapMode(hdc, *(mr->rdParam));
+	SetMapMode16(hdc, *(mr->rdParam));
 	break;
 
     case META_SETROP2:
-	SetROP2(hdc, *(mr->rdParam));
+	SetROP216(hdc, *(mr->rdParam));
 	break;
 
     case META_SETRELABS:
-	SetRelAbs(hdc, *(mr->rdParam));
+	SetRelAbs16(hdc, *(mr->rdParam));
 	break;
 
     case META_SETPOLYFILLMODE:
-	SetPolyFillMode(hdc, *(mr->rdParam));
+	SetPolyFillMode16(hdc, *(mr->rdParam));
 	break;
 
     case META_SETSTRETCHBLTMODE:
-	SetStretchBltMode(hdc, *(mr->rdParam));
+	SetStretchBltMode16(hdc, *(mr->rdParam));
 	break;
 
     case META_SETTEXTCOLOR:
@@ -528,7 +528,7 @@
 	break;
 
     case META_SAVEDC:
-	SaveDC(hdc);
+	SaveDC32(hdc);
 	break;
 
     case META_SETPIXEL:
@@ -561,7 +561,7 @@
 	break;
 
     case META_RESTOREDC:
-	RestoreDC(hdc, *(mr->rdParam));
+	RestoreDC32(hdc, *(mr->rdParam));
 	break;
 
     case META_SELECTOBJECT:
@@ -622,7 +622,7 @@
 	break;
 
     case META_SETTEXTALIGN:
-       	SetTextAlign(hdc, *(mr->rdParam));
+       	SetTextAlign16(hdc, *(mr->rdParam));
 	break;
 
     case META_SELECTPALETTE:
@@ -698,7 +698,7 @@
 
     case META_STRETCHBLT:
       {
-       HDC16 hdcSrc=CreateCompatibleDC(hdc);
+       HDC16 hdcSrc=CreateCompatibleDC16(hdc);
        HBITMAP16 hbitmap=CreateBitmap(mr->rdParam[10], /*Width */
                                       mr->rdParam[11], /*Height*/
                                       mr->rdParam[13], /*Planes*/
@@ -710,13 +710,13 @@
 		    hdcSrc,mr->rdParam[5],mr->rdParam[4],
 		    mr->rdParam[3],mr->rdParam[2],
 		    MAKELONG(mr->rdParam[0],mr->rdParam[1]));
-       DeleteDC(hdcSrc);		    
+       DeleteDC32(hdcSrc);		    
       }
       break;
 
     case META_BITBLT:            /* <-- not yet debugged */
       {
-       HDC16 hdcSrc=CreateCompatibleDC(hdc);
+       HDC16 hdcSrc=CreateCompatibleDC16(hdc);
        HBITMAP16 hbitmap=CreateBitmap(mr->rdParam[7]/*Width */,mr->rdParam[8]/*Height*/,
                             mr->rdParam[10]/*Planes*/,mr->rdParam[11]/*BitsPixel*/,
                             (LPSTR)&mr->rdParam[12]/*bits*/);
@@ -725,7 +725,7 @@
                 mr->rdParam[4],mr->rdParam[3],
                 hdcSrc, mr->rdParam[2],mr->rdParam[1],
                 MAKELONG(0,mr->rdParam[0]));
-       DeleteDC(hdcSrc);		    
+       DeleteDC32(hdcSrc);		    
       }
       break;
 
diff --git a/objects/pen.c b/objects/pen.c
index 83f70c7..9bb51ee 100644
--- a/objects/pen.c
+++ b/objects/pen.c
@@ -123,8 +123,7 @@
     dc->w.hPen = hpen;
 
     dc->u.x.pen.style = pen->logpen.lopnStyle;
-    dc->u.x.pen.width = pen->logpen.lopnWidth.x * dc->w.VportExtX
-	                  / dc->w.WndExtX;
+    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 );    
diff --git a/objects/text.c b/objects/text.c
index 13659b2..e5977c4 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -11,8 +11,8 @@
 #include "dc.h"
 #include "gdi.h"
 #include "callback.h"
+#include "heap.h"
 #include "metafile.h"
-#include "string32.h"
 #include "stddebug.h"
 /* #define DEBUG_TEXT */
 #include "debug.h"
@@ -257,7 +257,7 @@
                               rect, line, len, NULL )) return 0;
             if (prefix_offset != -1)
             {
-                HPEN32 hpen = CreatePen32( PS_SOLID, 1, GetTextColor(hdc) );
+                HPEN32 hpen = CreatePen32( PS_SOLID, 1, GetTextColor32(hdc) );
                 HPEN32 oldPen = SelectObject32( hdc, hpen );
                 MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
                 LineTo32(hdc, x + prefix_end, y + tm.tmAscent + 1 );
@@ -312,9 +312,9 @@
 INT32 DrawText32W( HDC32 hdc, LPCWSTR str, INT32 count,
                    LPRECT32 rect, UINT32 flags )
 {
-    char *p = STRING32_DupUniToAnsi( str );
+    LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     INT32 ret = DrawText32A( hdc, p, count, rect, flags );
-    free(p);
+    HeapFree( GetProcessHeap(), 0, p );
     return ret;
 }
 
@@ -589,9 +589,9 @@
                       const RECT32 *lprect, LPCWSTR str, UINT32 count,
                       const INT32 *lpDx )
 {
-    char *p = STRING32_DupUniToAnsi( str );
+    LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     INT32 ret = ExtTextOut32A( hdc, x, y, flags, lprect, p, count, lpDx );
-    free(p);
+    HeapFree( GetProcessHeap(), 0, p );
     return ret;
 }
 
@@ -634,7 +634,7 @@
 
     if (!cch) cch = lstrlen16( (LPCSTR)PTR_SEG_TO_LIN(lParam) );
     if (gsprc) return gsprc( hdc, lParam, cch );
-    current_color = GetTextColor( hdc );
+    current_color = GetTextColor32( hdc );
     SetTextColor( hdc, GetSysColor(COLOR_GRAYTEXT) );
     ret = TextOut16( hdc, x, y, (LPCSTR)PTR_SEG_TO_LIN(lParam), cch );
     SetTextColor( hdc, current_color );
@@ -691,7 +691,7 @@
             RECT16 r;
             SetRect16( &r, x, y, tabPos, y+HIWORD(extent) );
             ExtTextOut16( hdc, x, y,
-                          GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
+                          GetBkMode32(hdc) == OPAQUE ? ETO_OPAQUE : 0,
                           &r, lpstr, i, NULL );
         }
         x = tabPos;
diff --git a/win32/advapi.c b/win32/advapi.c
index c43ef5b..6ac2101 100644
--- a/win32/advapi.c
+++ b/win32/advapi.c
@@ -49,7 +49,7 @@
 BOOL32
 OpenProcessToken(HANDLE32 process,DWORD desiredaccess,HANDLE32 *thandle)
 {
-	fprintf(stdnimp,"OpenProcessToken(%08lx,%08lx,%p),stub!\n",
+	fprintf(stdnimp,"OpenProcessToken(%08x,%08lx,%p),stub!\n",
 		process,desiredaccess,thandle
 	);
 	return TRUE;
diff --git a/win32/code_page.c b/win32/code_page.c
index f181ad3..da1d7e0 100644
--- a/win32/code_page.c
+++ b/win32/code_page.c
@@ -9,9 +9,9 @@
 #include "windows.h"
 #include "winerror.h"
 #include "winnls.h"
+#include "heap.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "string32.h"
 
 
 /***********************************************************************
@@ -102,14 +102,14 @@
  *              EnumSystemCodePages32W                (KERNEL32.93)
  */
 BOOL32
-EnumSystemCodePages32W(CODEPAGE_ENUMPROC32W lpfnCodePageEnum,DWORD flags) {
-	WCHAR	*cp;
-	dprintf_win32(stddeb,"EnumSystemCodePages32W(%p,%08lx)\n",
-		lpfnCodePageEnum,flags
-	);
+EnumSystemCodePages32W( CODEPAGE_ENUMPROC32W lpfnCodePageEnum, DWORD flags)
+{
+    WCHAR	*cp;
+    dprintf_win32(stddeb,"EnumSystemCodePages32W(%p,%08lx)\n",
+                  lpfnCodePageEnum,flags );
 
-	cp=STRING32_DupAnsiToUni("437");
-	lpfnCodePageEnum(cp);
-	free(cp);
-	return TRUE;
+    cp = HEAP_strdupAtoW( GetProcessHeap(), 0, "437" );
+    lpfnCodePageEnum(cp);
+    HeapFree( GetProcessHeap(), 0, cp );
+    return TRUE;
 }
diff --git a/win32/console.c b/win32/console.c
index 8fb2f66..558b433 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -9,7 +9,7 @@
 #include "windows.h"
 #include "winerror.h"
 #include "wincon.h"
-#include "string32.h"
+#include "heap.h"
 #include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -93,7 +93,7 @@
  */
 BOOL32 SetConsoleMode(HANDLE32 hcon,DWORD mode)
 {
-    fprintf(stdnimp,"SetConsoleMode(%08lx,%08lx)\n",hcon,mode);
+    fprintf(stdnimp,"SetConsoleMode(%08x,%08lx)\n",hcon,mode);
     return TRUE;
 }
 
@@ -189,20 +189,21 @@
 }
 
 /***********************************************************************
- *            SetConsoleTitleA   (KERNEL32.476)
+ *            SetConsoleTitle32A   (KERNEL32.476)
  */
 BOOL32 SetConsoleTitle32A(LPCSTR title)
 {
     fprintf(stderr,"SetConsoleTitle(%s)\n",title);
     return TRUE;
 }
+
 /***********************************************************************
- *            SetConsoleTitleW   (KERNEL32.477)
+ *            SetConsoleTitle32W   (KERNEL32.477)
  */
-BOOL32 SetConsoleTitle32W(LPCWSTR title)
+BOOL32 SetConsoleTitle32W( LPCWSTR title )
 {
-    LPSTR titleA = STRING32_DupUniToAnsi(title);
+    LPSTR titleA = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
     fprintf(stderr,"SetConsoleTitle(%s)\n",titleA);
-    free(titleA);
+    HeapFree( GetProcessHeap(), 0, titleA );
     return TRUE;
 }
diff --git a/win32/cursoricon32.c b/win32/cursoricon32.c
index 14a34bd..40a3251 100644
--- a/win32/cursoricon32.c
+++ b/win32/cursoricon32.c
@@ -32,11 +32,11 @@
 #include "win.h"
 #include "bitmap.h"
 #include "struct32.h"
-#include "string32.h"
+#include "heap.h"
+#include "task.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
-#include "task.h"
 
 /* This dictionary could might eventually become a macro for better reuse */
 struct MAP_DWORD_DWORD{
@@ -328,8 +328,8 @@
         return 0;
     }
 
-    hXorBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
-                               (char*)bmi + size, pInfo, DIB_RGB_COLORS );
+    hXorBits = CreateDIBitmap32( hdc, &pInfo->bmiHeader, CBM_INIT,
+                                 (char*)bmi + size, pInfo, DIB_RGB_COLORS );
 
     /* Fix the bitmap header to load the monochrome mask */
 
@@ -358,8 +358,8 @@
 
     /* Create the AND bitmap */
 
-    hAndBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
-                               bits, pInfo, DIB_RGB_COLORS );
+    hAndBits = CreateDIBitmap32( hdc, &pInfo->bmiHeader, CBM_INIT,
+                                 bits, pInfo, DIB_RGB_COLORS );
     ReleaseDC32( 0, hdc );
 
     /* Now create the CURSORICONINFO structure */
@@ -418,19 +418,19 @@
 		WORD resid;
 		if(HIWORD(name))
 		{
-			LPSTR ansi;
-			ansi=STRING32_DupUniToAnsi(name);
+			LPSTR ansi = HEAP_strdupWtoA(GetProcessHeap(),0,name);
 			if(ansi[0]=='#')	/*Check for '#xxx' name */
 			{
-				resid=atoi(ansi+1);
-				free(ansi);
-			}else{
-				free(ansi);
-				return 0;
+                            resid = atoi(ansi+1);
+                            HeapFree( GetProcessHeap(), 0, ansi );
+			}
+                        else
+                        {
+                            HeapFree( GetProcessHeap(), 0, ansi );
+                            return 0;
 			}
 		}
-		else
-			resid=(WORD)(int)name;
+		else resid = LOWORD(name);
 		return OBM_LoadCursorIcon(resid, fCursor);
 	}
 
@@ -474,10 +474,11 @@
 	HCURSOR32 res=0;
 	if(!HIWORD(name))
 		return LoadCursor32W(hInstance,(LPCWSTR)name);
-	else {
-		LPWSTR uni = STRING32_DupAnsiToUni(name);
-		res = LoadCursor32W(hInstance, uni);
-		free(uni);
+	else
+        {
+            LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+            res = LoadCursor32W(hInstance, uni);
+            HeapFree( GetProcessHeap(), 0, uni);
 	}
 	return res;
 }
@@ -501,10 +502,11 @@
 	HICON32 res=0;
 	if(!HIWORD(name))
 		return LoadIcon32W(hInstance, (LPCWSTR)name);
-	else {
-		LPWSTR uni = STRING32_DupAnsiToUni(name);
-		res = LoadIcon32W(hInstance, uni);
-		free(uni);
+	else
+        {
+            LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+            res = LoadIcon32W( hInstance, uni );
+            HeapFree( GetProcessHeap(), 0, uni );
 	}
 	return res;
 }
diff --git a/win32/file.c b/win32/file.c
index bb74b48..7b9ec58 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -17,8 +17,8 @@
 #include "winbase.h"
 #include "winerror.h"
 #include "file.h"
+#include "heap.h"
 #include "handle32.h"
-#include "string32.h"
 #include "dos_fs.h"
 #include "xmalloc.h"
 #include "stddebug.h"
@@ -50,7 +50,6 @@
 HANDLE32 CreateFileMapping32A(HANDLE32 h,LPSECURITY_ATTRIBUTES ats,
   DWORD pot,  DWORD sh,  DWORD hlow,  LPCSTR lpName )
 {
-    HFILE hfile;
     FILEMAP_OBJECT *filemap_obj;
 
     dprintf_win32(stddeb,"CreateFileMapping32A(%08x,%p,%ld,%ld,%ld,%s)\n",
@@ -82,11 +81,9 @@
 HANDLE32 CreateFileMapping32W(HANDLE32 h,LPSECURITY_ATTRIBUTES ats,
   DWORD pot,  DWORD sh,  DWORD hlow,  LPCWSTR lpName)
 {
-    HANDLE32	res;
-    LPSTR	aname = STRING32_DupUniToAnsi(lpName);
-
-    res = CreateFileMapping32A(h,ats,pot,sh,hlow,aname);
-    free(aname);
+    LPSTR aname = HEAP_strdupWtoA( GetProcessHeap(), 0, lpName );
+    HANDLE32 res = CreateFileMapping32A(h,ats,pot,sh,hlow,aname);
+    HeapFree( GetProcessHeap(), 0, aname );
     return res;
 }
 
@@ -338,11 +335,10 @@
                     LPSECURITY_ATTRIBUTES security, DWORD creation,
                     DWORD attributes, HANDLE32 template)
 {
-    HFILE 	res;
-    LPSTR	afn = STRING32_DupUniToAnsi(filename);
-
-    res = CreateFile32A(afn,access,sharing,security,creation,attributes,template);
-    free(afn);
+    LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    HFILE res = CreateFile32A( afn, access, sharing, security, creation,
+                               attributes, template );
+    HeapFree( GetProcessHeap(), 0, afn );
     return res;
 }
 
@@ -445,12 +441,10 @@
  */
 DWORD GetFileAttributes32W(LPCWSTR lpFileName)
 {
-	LPSTR	afn = STRING32_DupUniToAnsi(lpFileName);
-	DWORD	res;
-
-	res = GetFileAttributes32A(afn);
-	free(afn);
-	return res;
+    LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
+    DWORD res = GetFileAttributes32A( afn );
+    HeapFree( GetProcessHeap(), 0, afn );
+    return res;
 }
 
 
@@ -486,12 +480,10 @@
  */
 BOOL32 SetFileAttributes32W(LPCWSTR lpFileName, DWORD attributes)
 {
-	LPSTR afn = STRING32_DupUniToAnsi(lpFileName);
-	BOOL32	res;
-
-	res = SetFileAttributes32A(afn,attributes);
-	free(afn);
-	return res;
+    LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
+    BOOL32 res = SetFileAttributes32A( afn, attributes );
+    HeapFree( GetProcessHeap(), 0, afn );
+    return res;
 }
 
 /**************************************************************************
@@ -549,14 +541,12 @@
  */
 BOOL32 MoveFile32W(LPCWSTR fn1,LPCWSTR fn2)
 {
-	LPSTR	afn1 = STRING32_DupUniToAnsi(fn1);
-	LPSTR	afn2 = STRING32_DupUniToAnsi(fn2);
-	BOOL32	res;
-
-	res = MoveFile32A(afn1,afn2);
-	free(afn1);
-	free(afn2);
-	return res;
+    LPSTR afn1 = HEAP_strdupWtoA( GetProcessHeap(), 0, fn1 );
+    LPSTR afn2 = HEAP_strdupWtoA( GetProcessHeap(), 0, fn2 );
+    BOOL32 res = MoveFile32A( afn1, afn2 );
+    HeapFree( GetProcessHeap(), 0, afn1 );
+    HeapFree( GetProcessHeap(), 0, afn2 );
+    return res;
 }
 
 VOID SetFileApisToOEM()
@@ -581,7 +571,7 @@
 	OFSTRUCT	of;
 	HFILE		hf1,hf2;
 	char		buffer[2048];
-	int		res,lastread,curlen;
+	int		lastread,curlen;
 
 	fprintf(stddeb,"CopyFile: %s -> %s\n",sourcefn,destfn);
 	hf1 = OpenFile(sourcefn,&of,OF_READ);
@@ -600,16 +590,14 @@
 	while ((lastread=_lread16(hf1,buffer,sizeof(buffer)))>0) {
 		curlen=0;
 		while (curlen<lastread) {
-			int	res;
-
-			res=_lwrite16(hf2,buffer+curlen,lastread-curlen);
+			int res = _lwrite16(hf2,buffer+curlen,lastread-curlen);
 			if (res<=0) break;
 			curlen+=res;
 		}
 	}
 	_lclose(hf1);
 	_lclose(hf2);
-	return res>0;
+	return curlen > 0;
 }
 
 BOOL32
diff --git a/win32/findfile.c b/win32/findfile.c
index 0c6618a..799e5e1 100644
--- a/win32/findfile.c
+++ b/win32/findfile.c
@@ -11,7 +11,6 @@
 #include "winerror.h"
 #include "dos_fs.h"
 #include "heap.h"
-#include "string32.h"
 #include "drive.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -173,8 +172,8 @@
     adata.nFileSizeLow		= data->nFileSizeLow;
     adata.dwReserved0		= data->dwReserved0;
     adata.dwReserved1		= data->dwReserved1;
-    STRING32_UniToAnsi(adata.cFileName,data->cFileName);
-    STRING32_UniToAnsi(adata.cAlternateFileName,data->cAlternateFileName);
+    lstrcpyWtoA(adata.cFileName,data->cFileName);
+    lstrcpyWtoA(adata.cAlternateFileName,data->cAlternateFileName);
     res=FindNextFile32A(handle,&adata);
     if (res) {
 	    data->dwFileAttributes 	= adata.dwFileAttributes;
@@ -185,8 +184,8 @@
 	    data->nFileSizeLow		= adata.nFileSizeLow;
 	    data->dwReserved0		= adata.dwReserved0; 
 	    data->dwReserved1		= adata.dwReserved1;
-	    STRING32_AnsiToUni(data->cFileName,adata.cFileName);
-	    STRING32_AnsiToUni(data->cAlternateFileName,adata.cAlternateFileName);
+	    lstrcpyAtoW(data->cFileName,adata.cFileName);
+	    lstrcpyAtoW(data->cAlternateFileName,adata.cAlternateFileName);
     }
     return res;
 }
@@ -282,11 +281,10 @@
 HANDLE32 FindFirstFile32W(LPCWSTR filename,LPWIN32_FIND_DATA32W data)
 {
     WIN32_FIND_DATA32A	adata;
-    LPSTR		afn = STRING32_DupUniToAnsi(filename);
-    HANDLE32		res;
-
-    res=FindFirstFile32A(afn,&adata);
-    if (res) {
+    LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
+    HANDLE32 res = FindFirstFile32A(afn,&adata);
+    if (res)
+    {
 	data->dwFileAttributes 	= adata.dwFileAttributes;
 	data->ftCreationTime	= adata.ftCreationTime;
 	data->ftLastAccessTime	= adata.ftLastAccessTime;
@@ -295,10 +293,10 @@
 	data->nFileSizeLow	= adata.nFileSizeLow;
 	data->dwReserved0	= adata.dwReserved0; 
 	data->dwReserved1	= adata.dwReserved1;
-	STRING32_AnsiToUni(data->cFileName,adata.cFileName);
-	STRING32_AnsiToUni(data->cAlternateFileName,adata.cAlternateFileName);
+	lstrcpyAtoW(data->cFileName,adata.cFileName);
+	lstrcpyAtoW(data->cAlternateFileName,adata.cAlternateFileName);
     }
-    free(afn);
+    HeapFree( GetProcessHeap(), 0, afn );
     return res;
 }
 
diff --git a/win32/init.c b/win32/init.c
index b61ac47..3eb9ed3 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -11,12 +11,10 @@
 #include "winerror.h"
 #include "handle32.h"
 #include "except.h"
+#include "heap.h"
 #include "task.h"
 #include "stddebug.h"
-#include "string32.h"
-#define DEBUG_WIN32
 #include "debug.h"
-#include "string32.h"
 #include "xmalloc.h"
   
 /* The global error value
@@ -28,9 +26,9 @@
  */
 BOOL CloseHandle(KERNEL_OBJECT *handle)
 {
-    if (handle<0x1000) /* FIXME: hack */
-    	return CloseFileHandle(handle);
-    if (handle==0xFFFFFFFF)
+    if ((int)handle<0x1000) /* FIXME: hack */
+    	return CloseFileHandle((int)handle);
+    if ((int)handle==0xFFFFFFFF)
     	return FALSE;
     switch(handle->magic)
     {
@@ -74,13 +72,11 @@
 
 HMODULE32 WIN32_GetModuleHandleW(LPCWSTR module)
 {
-  HMODULE32 hModule;
-  LPSTR     modulea;
-  if(module==NULL) return WIN32_GetModuleHandleA(NULL);
-  modulea=STRING32_DupUniToAnsi(module);
-  hModule = WIN32_GetModuleHandleA(modulea);
-  free(modulea);
-  return hModule;
+    HMODULE32 hModule;
+    LPSTR modulea = HEAP_strdupWtoA( GetProcessHeap(), 0, module );
+    hModule = WIN32_GetModuleHandleA( modulea );
+    HeapFree( GetProcessHeap(), 0, modulea );
+    return hModule;
 }
 
 
@@ -107,9 +103,9 @@
 VOID GetStartupInfo32W(LPSTARTUPINFO32W lpStartupInfo)
 {
     lpStartupInfo->cb = sizeof(STARTUPINFO32W);
-    lpStartupInfo->lpReserved = STRING32_DupAnsiToUni("<Reserved>");
-    lpStartupInfo->lpDesktop = STRING32_DupAnsiToUni("Desktop");
-    lpStartupInfo->lpTitle = STRING32_DupAnsiToUni("Title");
+    lpStartupInfo->lpReserved = HEAP_strdupAtoW(GetProcessHeap(),0,"<Reserved>");
+    lpStartupInfo->lpDesktop = HEAP_strdupAtoW(GetProcessHeap(), 0, "Desktop");
+    lpStartupInfo->lpTitle = HEAP_strdupAtoW(GetProcessHeap(), 0, "Title");
 
     lpStartupInfo->cbReserved2 = 0;
     lpStartupInfo->lpReserved2 = NULL; /* must be NULL for VC runtime */
@@ -130,8 +126,8 @@
     si->u.x.wProcessorArchitecture	= PROCESSOR_ARCHITECTURE_INTEL;
 
     si->dwPageSize			= 4096; /* 4K */
-    si->lpMinimumApplicationAddress	= 0x40000000;
-    si->lpMaximumApplicationAddress	= 0x80000000;
+    si->lpMinimumApplicationAddress	= (void *)0x40000000;
+    si->lpMaximumApplicationAddress	= (void *)0x80000000;
     si->dwActiveProcessorMask		= 1;
     si->dwNumberOfProcessors		= 1;
 #ifdef WINELIB
diff --git a/win32/newfns.c b/win32/newfns.c
index cab11b9..c7fb4c1 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -36,7 +36,7 @@
 
 DWORD
 GetWindowThreadProcessId(HWND32 hwnd,LPDWORD processid) {
-	fprintf(stdnimp,"GetWindowThreadProcessId(%04lx,%p),stub\n",hwnd,processid);
+	fprintf(stdnimp,"GetWindowThreadProcessId(%04x,%p),stub\n",hwnd,processid);
 	return 0;
 }
 
diff --git a/win32/process.c b/win32/process.c
index 50a0283..2b6f501 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -9,6 +9,7 @@
 #include <unistd.h>
 #include "windows.h"
 #include "winerror.h"
+#include "heap.h"
 #include "handle32.h"
 #include "task.h"
 #include "stddebug.h"
@@ -124,13 +125,10 @@
  */
 HINSTANCE32 LoadLibrary32W(LPCWSTR libnameW)
 {
-	LPSTR libnameA = STRING32_DupUniToAnsi(libnameW);
-	HINSTANCE32 ret;
-
-	ret = LoadLibrary32A(libnameA);
-	free(libnameA);
-	return ret;
-
+    LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
+    HINSTANCE32 ret = LoadLibrary32A( libnameA );
+    HeapFree( GetProcessHeap(), 0, libnameA );
+    return ret;
 }
 
 /***********************************************************************
diff --git a/win32/string32.c b/win32/string32.c
index 011b445..f4a317b 100644
--- a/win32/string32.c
+++ b/win32/string32.c
@@ -15,47 +15,17 @@
 #include "string32.h"
 #include "xmalloc.h"
 
-void STRING32_UniToAnsi(LPSTR dest,LPCWSTR src)
-{
-	static int have_warned=0;
-	while(*src)
-	{
-		if(*src>255 && !have_warned)
-		{
-			fprintf(stderr,"Cannot deal with non-ANSI characters\n");
-			have_warned=1;
-		}
-		*dest++=*src++;
-	}
-	/* copy the terminator */
-	*dest = *src;
-}
-
-/* FIXME: we need to use unsigned char here, for if 
- *        we got chars with the 7th bit set, we will get
- *	  negative integers -> wrong unicode values
- */
-void 
-STRING32_AnsiToUni(LPWSTR dest,LPCSTR src) {
-	unsigned char	*usrc;
-
-	usrc=(unsigned char*)src;
-	while(*usrc)
-		*dest++=*usrc++;
-	*dest = *usrc;
-}
-
 LPSTR STRING32_DupUniToAnsi(LPCWSTR src)
 {
 	LPSTR dest=xmalloc(lstrlen32W(src)+1);
-	STRING32_UniToAnsi(dest,src);
+	lstrcpyWtoA(dest,src);
 	return dest;
 }
 
 LPWSTR STRING32_DupAnsiToUni(LPCSTR src)
 {
 	LPWSTR dest=xmalloc(2*strlen(src)+2);
-	STRING32_AnsiToUni(dest,src);
+	lstrcpyAtoW(dest,src);
 	return dest;
 }
 
diff --git a/win32/user32.c b/win32/user32.c
index 3880aeb..89c1a40 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -16,7 +16,6 @@
 #include "xmalloc.h"
 #include "handle32.h"
 #include "struct32.h"
-#include "string32.h"
 #include "win.h"
 #include "debug.h"
 #include "stddebug.h"
diff --git a/windows/Makefile.in b/windows/Makefile.in
index 5b3343f..5cfa021 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -17,7 +17,6 @@
 	graphics.c \
 	hook.c \
 	keyboard.c \
-	mapping.c \
 	mdi.c \
 	message.c \
 	msgbox.c \
diff --git a/windows/caret.c b/windows/caret.c
index 055bb1b..ca11b7e 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -33,7 +33,7 @@
     CARET_TOGGLE,
 } DISPLAY_CARET;
 
-static CARET Caret;
+static CARET Caret = { 0, 0, FALSE, 0, 0, 2, 12, 0, 500, 0 };
 
 
 /*****************************************************************
@@ -150,7 +150,7 @@
     Caret.x = 0;
     Caret.y = 0;
 
-    Caret.timeout = GetProfileInt32A( "windows", "CursorBlinkRate", 750 );
+    Caret.timeout = GetProfileInt32A( "windows", "CursorBlinkRate", 500 );
     return TRUE;
 }
    
@@ -268,7 +268,6 @@
  */
 UINT32 GetCaretBlinkTime32(void)
 {
-    if (!Caret.hwnd) return 0;
     return Caret.timeout;
 }
 
diff --git a/windows/class.c b/windows/class.c
index d5c3f64..d04e707 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -13,7 +13,6 @@
 #include "dce.h"
 #include "atom.h"
 #include "ldt.h"
-#include "string32.h"
 #include "toolhelp.h"
 #include "winproc.h"
 #include "stddebug.h"
@@ -92,9 +91,7 @@
     if (!classPtr->menuNameA && classPtr->menuNameW)
     {
         /* We need to copy the Unicode string */
-        if ((classPtr->menuNameA = SEGPTR_ALLOC(
-                                        lstrlen32W(classPtr->menuNameW) + 1 )))
-            STRING32_UniToAnsi( classPtr->menuNameA, classPtr->menuNameW );
+        classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
     }
     return classPtr->menuNameA;
 }
@@ -112,9 +109,8 @@
         if (!HIWORD(classPtr->menuNameA))
             return (LPWSTR)classPtr->menuNameA;
         /* Now we need to copy the ASCII string */
-        if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
-                              (strlen(classPtr->menuNameA)+1)*sizeof(WCHAR) )))
-            STRING32_AnsiToUni( classPtr->menuNameW, classPtr->menuNameA );
+        classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
+                                               classPtr->menuNameA );
     }
     return classPtr->menuNameW;
 }
diff --git a/windows/dce.c b/windows/dce.c
index 98bbe81..56889ce 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -85,7 +85,7 @@
 
     SetDCHook(dce->hDC, NULL, 0L);
 
-    DeleteDC( dce->hDC );
+    DeleteDC32( dce->hDC );
     if( dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN) )
 	DeleteObject32(dce->hClipRgn);
     HeapFree( SystemHeap, 0, dce );
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 8b0da40..b666cca 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -12,7 +12,6 @@
 #include "heap.h"
 #include "nonclient.h"
 #include "winpos.h"
-#include "string32.h"
 #include "syscolor.h"
 #include "sysmetrics.h"
 #include "stddebug.h"
@@ -481,9 +480,9 @@
 	    if (cs->lpszName)
             {
                 WND *wndPtr = WIN_FindWndPtr( hwnd );
-                LPSTR str = STRING32_DupUniToAnsi( cs->lpszName );
+                LPSTR str = HEAP_strdupWtoA(GetProcessHeap(), 0, cs->lpszName);
                 DEFWND_SetText( wndPtr, str );
-                free( str );
+                HeapFree( GetProcessHeap(), 0, str );
             }
 	    result = 1;
 	}
@@ -491,18 +490,18 @@
 
     case WM_GETTEXT:
         {
-            LPSTR str = malloc( wParam );
+            LPSTR str = HeapAlloc( GetProcessHeap(), 0, wParam );
             result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
-            STRING32_AnsiToUni( (LPWSTR)lParam, str );
-            free( str );
+            lstrcpynAtoW( (LPWSTR)lParam, str, wParam );
+            HeapFree( GetProcessHeap(), 0, str );
         }
         break;
 
     case WM_SETTEXT:
         {
-            LPSTR str = STRING32_DupUniToAnsi( (LPWSTR)lParam );
+            LPSTR str = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPWSTR)lParam );
             result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
-            free( str );
+            HeapFree( GetProcessHeap(), 0, str );
         }
         break;
 
diff --git a/windows/dialog.c b/windows/dialog.c
index 864495f..bd03f44 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -14,7 +14,6 @@
 #include "heap.h"
 #include "win.h"
 #include "ldt.h"
-#include "string32.h"
 #include "user.h"
 #include "winproc.h"
 #include "message.h"
@@ -73,7 +72,7 @@
 
     if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
     GetTextMetrics16( hdc, &tm );
-    DeleteDC( hdc );
+    DeleteDC32( hdc );
     xBaseUnit = tm.tmAveCharWidth;
     yBaseUnit = tm.tmHeight;
 
@@ -174,12 +173,12 @@
     {
         switch(GET_WORD(p+1))
         {
-            case 0x80: STRING32_AnsiToUni( buffer, "BUTTON" ); break;
-            case 0x81: STRING32_AnsiToUni( buffer, "EDIT" ); break;
-            case 0x82: STRING32_AnsiToUni( buffer, "STATIC" ); break;
-            case 0x83: STRING32_AnsiToUni( buffer, "LISTBOX" ); break;
-            case 0x84: STRING32_AnsiToUni( buffer, "SCROLLBAR" ); break;
-            case 0x85: STRING32_AnsiToUni( buffer, "COMBOBOX" ); break;
+            case 0x80: lstrcpyAtoW( buffer, "Button" ); break;
+            case 0x81: lstrcpyAtoW( buffer, "Edit" ); break;
+            case 0x82: lstrcpyAtoW( buffer, "Static" ); break;
+            case 0x83: lstrcpyAtoW( buffer, "ListBox" ); break;
+            case 0x84: lstrcpyAtoW( buffer, "ScrollBar" ); break;
+            case 0x85: lstrcpyAtoW( buffer, "ComboBox" ); break;
             default:   buffer[0] = '\0'; break;
         }
         info->className = (LPCSTR)buffer;
@@ -653,9 +652,9 @@
 {
     if (HIWORD(name))
     {
-        LPWSTR str = STRING32_DupAnsiToUni( name );
+        LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
         HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param);
-        free( str );
+        HeapFree( GetProcessHeap(), 0, str );
         return hwnd;
     }
     return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param );
@@ -1599,10 +1598,9 @@
                      UINT32 attrib )
 {
     INT32 ret;
-    LPSTR specA = NULL;
-    if (spec) specA = STRING32_DupUniToAnsi(spec);
+    LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
     ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic, attrib, FALSE );
-    if (specA) free( specA );
+    HeapFree( GetProcessHeap(), 0, specA );
     return ret;
 }
 
@@ -1634,9 +1632,8 @@
                              INT32 idStatic, UINT32 attrib )
 {
     INT32 ret;
-    LPSTR specA = NULL;
-    if (spec) specA = STRING32_DupUniToAnsi(spec);
+    LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
     ret = DIALOG_DlgDirList( hDlg, specA, idCBox, idStatic, attrib, FALSE );
-    if (specA) free( specA );
+    HeapFree( GetProcessHeap(), 0, specA );
     return ret;
 }
diff --git a/windows/event.c b/windows/event.c
index 1143c44..d01c38b 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -313,6 +313,17 @@
     XSaveContext( display, pWnd->window, winContext, (char *)pWnd );
 }
 
+/***********************************************************************
+ *           EVENT_DestroyWindow
+ */
+void EVENT_DestroyWindow( WND *pWnd )
+{
+   XEvent xe;
+
+   XDeleteContext( display, pWnd->window, winContext );
+   XDestroyWindow( display, pWnd->window );
+   while( XCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
+}
 
 /***********************************************************************
  *           EVENT_WaitXEvent
@@ -391,9 +402,9 @@
         {
 	  WND*		pWnd;
 	  MESSAGEQUEUE* pQ;
-  
-          if( XFindContext( display, ((XAnyEvent *)&event)->window, winContext, (char **)&pWnd) 
-	      || event.type == NoExpose )  
+
+          if (XFindContext( display, ((XAnyEvent *)&event)->window, winContext,
+                            (char **)&pWnd ) || (event.type == NoExpose))
               continue;
 
 	  /* check for the "safe" hardware events */
@@ -613,7 +624,8 @@
 	keylp.lp1.count = 1;
 	keylp.lp1.code = LOBYTE(event->keycode) - 8;
 	keylp.lp1.extended = (extended ? 1 : 0);
-	keylp.lp1.win_internal = 0;
+	keylp.lp1.win_internal = 0;			/* this has something to do with dialogs, 
+							 * don't remember where I read it - AK */
 	keylp.lp1.context = ( (event->state & Mod1Mask) || 
 			       (InputKeyStateTable[VK_MENU] & 0x80)) ? 1 : 0;
 	keylp.lp1.previous = (KeyDown ? 0 : 1);
diff --git a/windows/graphics.c b/windows/graphics.c
index 9aedf97..caf865e 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -425,8 +425,8 @@
     top    = YLPTODP( dc, top );
     right  = XLPTODP( dc, right );
     bottom = YLPTODP( dc, bottom );
-    ell_width  = abs( ell_width * dc->w.VportExtX / dc->w.WndExtX );
-    ell_height = abs( ell_height * dc->w.VportExtY / dc->w.WndExtY );
+    ell_width  = abs( ell_width * dc->vportExtX / dc->wndExtX );
+    ell_height = abs( ell_height * dc->vportExtY / dc->wndExtY );
 
     /* Fix the coordinates */
 
@@ -819,10 +819,10 @@
 BOOL32 InvertRgn32( HDC32 hdc, HRGN32 hrgn )
 {
     HBRUSH32 prevBrush = SelectObject32( hdc, GetStockObject32(BLACK_BRUSH) );
-    WORD prevROP = SetROP2( hdc, R2_NOT );
+    INT32 prevROP = SetROP232( hdc, R2_NOT );
     BOOL32 retval = PaintRgn32( hdc, hrgn );
     SelectObject32( hdc, prevBrush );
-    SetROP2( hdc, prevROP );
+    SetROP232( hdc, prevROP );
     return retval;
 }
 
@@ -856,8 +856,8 @@
     bottom = YLPTODP( dc, rc->bottom );
     
     hOldPen = SelectObject32( hdc, sysColorObjects.hpenWindowText );
-    oldDrawMode = SetROP2(hdc, R2_XORPEN);
-    oldBkMode = SetBkMode(hdc, TRANSPARENT);
+    oldDrawMode = SetROP232(hdc, R2_XORPEN);
+    oldBkMode = SetBkMode32(hdc, TRANSPARENT);
 
     /* Hack: make sure the XORPEN operation has an effect */
     dc->u.x.pen.pixel = (1 << screenDepth) - 1;
@@ -867,8 +867,8 @@
 		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		        right-left-1, bottom-top-1 );
 
-    SetBkMode(hdc, oldBkMode);
-    SetROP2(hdc, oldDrawMode);
+    SetBkMode32(hdc, oldBkMode);
+    SetROP232(hdc, oldDrawMode);
     SelectObject32(hdc, hOldPen);
 }
 
diff --git a/windows/hook.c b/windows/hook.c
index a64db7c..f5dd48a 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -18,10 +18,10 @@
 #include "windows.h"
 #include "hook.h"
 #include "queue.h"
+#include "stackframe.h"
 #include "user.h"
 #include "heap.h"
 #include "struct32.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -237,14 +237,14 @@
 				      (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
 
 	if (HIWORD(lpcs16->lpszName))
-            lpcbtcw32->lpcs->lpszName = 
-                STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16->lpszName) );
+            lpcbtcw32->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
+                                            PTR_SEG_TO_LIN(lpcs16->lpszName) );
 	else
             lpcbtcw32->lpcs->lpszName = (LPWSTR)lpcs16->lpszName;
 
 	if (HIWORD(lpcs16->lpszClass))
-            lpcbtcw32->lpcs->lpszClass =
-                STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
+            lpcbtcw32->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
+                                           PTR_SEG_TO_LIN(lpcs16->lpszClass) );
 	else
             lpcbtcw32->lpcs->lpszClass = (LPWSTR)lpcs16->lpszClass;
 
@@ -346,9 +346,9 @@
     {
 	LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)lParam;
 	if (HIWORD(lpcbtcw32->lpcs->lpszName))
-	  free( (LPWSTR)lpcbtcw32->lpcs->lpszName );
+            HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
 	if (HIWORD(lpcbtcw32->lpcs->lpszClass))
-	  free( (LPWSTR)lpcbtcw32->lpcs->lpszClass );
+            HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
 	HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
 	HeapFree( SystemHeap, 0, lpcbtcw32 );
     }
@@ -525,6 +525,7 @@
 {
     if (id == WH_CBT && code == HCBT_CREATEWND)
     {
+        LPSTR name, cls;
 	LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
 	LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
 	LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
@@ -533,24 +534,10 @@
 	STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
 				      lpcs16 );
 
-	if (HIWORD(lpcbtcw32->lpcs->lpszName))
-	{
-	    LPSTR str = SEGPTR_ALLOC( lstrlen32W(lpcbtcw32->lpcs->lpszName) );
-	    STRING32_UniToAnsi( str, lpcbtcw32->lpcs->lpszName );
-	    lpcs16->lpszName = SEGPTR_GET( str );
-	}
-	else
-	  lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
-
-	if (HIWORD(lpcbtcw32->lpcs->lpszClass))
-	{
-	    LPSTR str = SEGPTR_ALLOC( lstrlen32W(lpcbtcw32->lpcs->lpszClass) );
-	    STRING32_UniToAnsi( str, lpcbtcw32->lpcs->lpszClass );
-	    lpcs16->lpszClass = SEGPTR_GET( str );
-	}
-	else
-	  lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
-
+        name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
+        cls  = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
+        lpcs16->lpszName  = SEGPTR_GET( name );
+        lpcs16->lpszClass = SEGPTR_GET( cls );
 	lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
 
 	*plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
@@ -670,16 +657,16 @@
 
 	if (HIWORD(lpcbtcwA->lpcs->lpszName))
 	{
-	    lpcbtcwW->lpcs->lpszName =
-	      STRING32_DupAnsiToUni( lpcbtcwA->lpcs->lpszName );
+	    lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
+                                                    lpcbtcwA->lpcs->lpszName );
 	}
 	else
 	  lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
 
 	if (HIWORD(lpcbtcwA->lpcs->lpszClass))
 	{
-	    lpcbtcwW->lpcs->lpszClass =
-	      STRING32_DupAnsiToUni( lpcbtcwA->lpcs->lpszClass);
+	    lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
+                                                   lpcbtcwA->lpcs->lpszClass );
 	}
 	else
 	  lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
@@ -699,9 +686,9 @@
     {
 	LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
 	if (HIWORD(lpcbtcwW->lpcs->lpszName))
-            free( (LPWSTR)lpcbtcwW->lpcs->lpszName );
+            HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
 	if (HIWORD(lpcbtcwW->lpcs->lpszClass))
-            free( (LPWSTR)lpcbtcwW->lpcs->lpszClass );
+            HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
 	HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
 	HeapFree( SystemHeap, 0, lpcbtcwW );
     }
@@ -726,14 +713,14 @@
 	*lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
 
 	if (HIWORD(lpcbtcwW->lpcs->lpszName))
-	  lpcbtcwA->lpcs->lpszName =
-	    STRING32_DupUniToAnsi( lpcbtcwW->lpcs->lpszName );
+	  lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
+                                                    lpcbtcwW->lpcs->lpszName );
 	else
 	  lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
 
 	if (HIWORD(lpcbtcwW->lpcs->lpszClass))
-	  lpcbtcwA->lpcs->lpszClass =
-	    STRING32_DupUniToAnsi( lpcbtcwW->lpcs->lpszClass);
+	  lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
+                                                   lpcbtcwW->lpcs->lpszClass );
 	else
 	  lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
     }
@@ -752,9 +739,9 @@
     {
 	LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
 	if (HIWORD(lpcbtcwA->lpcs->lpszName))
-	  free( (LPSTR)lpcbtcwA->lpcs->lpszName );
+            HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
 	if (HIWORD(lpcbtcwA->lpcs->lpszClass))
-	  free( (LPSTR)lpcbtcwA->lpcs->lpszClass );
+            HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
 	HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
 	HeapFree( SystemHeap, 0, lpcbtcwA );
     }
@@ -947,6 +934,7 @@
     HANDLE16 prevHook;
     HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
     LRESULT ret;
+    WORD old_ds;
 
     WPARAM32 wParamOrig = wParam;
     LPARAM lParamOrig = lParam;
@@ -969,7 +957,11 @@
     dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
                   hook, code, wParam, lParam );
 
+    /* Set DS = SS to call hook procedure */
+    old_ds = CURRENT_DS;
+    CURRENT_DS = IF1632_Saved16_ss;
     ret = data->proc(code, wParam, lParam);
+    CURRENT_DS = old_ds;
 
     dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 0342cb9..d4dcc7f 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -29,16 +29,12 @@
 {
     INT retval;
 
-    if (keycode >= 'a' && keycode <= 'z')
-        keycode += 'A' - 'a';
-    switch(keycode) {
-     case VK_LBUTTON:
-	retval = MouseButtonsStates[0];
-     case VK_MBUTTON:
-	retval = MouseButtonsStates[1];
-     case VK_RBUTTON:
-	retval = MouseButtonsStates[2];
-     default:
+    if( keycode >= VK_LBUTTON && keycode <= VK_RBUTTON )
+	retval = MouseButtonsStates[keycode - VK_LBUTTON];
+    else
+    {
+	if (keycode >= 'a' && keycode <= 'z')
+	    keycode += 'A' - 'a';
 	retval = ( (INT)(QueueKeyStateTable[keycode] & 0x80) << 8 ) |
 		   (INT)(QueueKeyStateTable[keycode] & 0x01);
     }
diff --git a/windows/mapping.c b/windows/mapping.c
deleted file mode 100644
index ed8a1bb..0000000
--- a/windows/mapping.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * GDI mapping mode functions
- *
- * Copyright 1993 Alexandre Julliard
- */
-
-#include <math.h>
-#include "gdi.h"
-#include "metafile.h"
-#include "stddebug.h"
-/* #define DEBUG_GDI */
-#include "debug.h"
-
-
-/***********************************************************************
- *           MAPPING_FixIsotropic
- *
- * Fix viewport extensions for isotropic mode.
- */
-void MAPPING_FixIsotropic( DC * dc )
-{
-    double xdim = (double)dc->w.VportExtX * dc->w.devCaps->horzSize /
-	          (dc->w.devCaps->horzRes * dc->w.WndExtX);
-    double ydim = (double)dc->w.VportExtY * dc->w.devCaps->vertSize /
-	          (dc->w.devCaps->vertRes * dc->w.WndExtY);
-    if (xdim > ydim)
-    {
-	dc->w.VportExtX = dc->w.VportExtX * fabs( ydim / xdim );
-	if (!dc->w.VportExtX) dc->w.VportExtX = 1;
-    }
-    else
-    {
-	dc->w.VportExtY = dc->w.VportExtY * fabs( xdim / ydim );
-	if (!dc->w.VportExtY) dc->w.VportExtY = 1;
-    }	
-}
-
-
-/***********************************************************************
- *           DPtoLP16    (GDI.67)
- */
-BOOL16 DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-
-    while (count--)
-    {
-	points->x = XDPTOLP( dc, points->x );
-	points->y = YDPTOLP( dc, points->y );
-        points++;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           DPtoLP32    (GDI32.65)
- */
-BOOL32 DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-
-    while (count--)
-    {
-	points->x = XDPTOLP( dc, points->x );
-	points->y = YDPTOLP( dc, points->y );
-        points++;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           LPtoDP16    (GDI.99)
- */
-BOOL16 LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-
-    while (count--)
-    {
-	points->x = XLPTODP( dc, points->x );
-	points->y = YLPTODP( dc, points->y );
-        points++;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           LPtoDP32    (GDI32.247)
- */
-BOOL32 LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-
-    while (count--)
-    {
-	points->x = XLPTODP( dc, points->x );
-	points->y = YLPTODP( dc, points->y );
-        points++;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetMapMode    (GDI.3)
- */
-WORD SetMapMode( HDC16 hdc, WORD mode )
-{
-    WORD prevMode;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return 0;
-	MF_MetaParam1(dc, META_SETMAPMODE, mode);
-	return 1;
-    }
-
-    dprintf_gdi(stddeb, "SetMapMode: %04x %d\n", hdc, mode );
-    
-    prevMode = dc->w.MapMode;
-    switch(mode)
-    {
-      case MM_TEXT:
-	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
-	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
-	  dc->w.WndExtX   = 1;
-	  dc->w.WndExtY   = 1;
-	  dc->w.VportExtX = 1;
-	  dc->w.VportExtY = 1;
-	  break;
-	  
-      case MM_LOMETRIC:
-      case MM_ISOTROPIC:
-	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
-	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
-	  dc->w.WndExtX   = dc->w.devCaps->horzSize;
-	  dc->w.WndExtY   = dc->w.devCaps->vertSize;
-	  dc->w.VportExtX = dc->w.devCaps->horzRes / 10;
-	  dc->w.VportExtY = dc->w.devCaps->vertRes / -10;
-	  break;
-	  
-      case MM_HIMETRIC:
-	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
-	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
-	  dc->w.WndExtX   = dc->w.devCaps->horzSize * 10;
-	  dc->w.WndExtY   = dc->w.devCaps->vertSize * 10;
-	  dc->w.VportExtX = dc->w.devCaps->horzRes / 10;
-	  dc->w.VportExtY = dc->w.devCaps->vertRes / -10;
-	  break;
-	  
-      case MM_LOENGLISH:
-	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
-	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
-	  dc->w.WndExtX   = dc->w.devCaps->horzSize;
-	  dc->w.WndExtY   = dc->w.devCaps->vertSize;
-	  dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
-	  dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
-	  break;	  
-	  
-      case MM_HIENGLISH:
-	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
-	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
-	  dc->w.WndExtX   = dc->w.devCaps->horzSize * 10;
-	  dc->w.WndExtY   = dc->w.devCaps->vertSize * 10;
-	  dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
-	  dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
-	  break;
-	  
-      case MM_TWIPS:
-	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
-	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
-	  dc->w.WndExtX   = (short)(144L * dc->w.devCaps->horzSize / 10);
-	  dc->w.WndExtY   = (short)(144L * dc->w.devCaps->vertSize / 10);
-	  dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
-	  dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
-	  break;
-	  
-      case MM_ANISOTROPIC:
-	  break;
-
-      default:
-	  return prevMode;
-    }
-    dc->w.MapMode = mode;
-    return prevMode;
-}
-
-
-/***********************************************************************
- *           SetViewportExt    (GDI.14)
- */
-DWORD SetViewportExt( HDC16 hdc, INT16 x, INT16 y )
-{
-    SIZE16 size;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam2(dc, META_SETVIEWPORTEXT, x, y);
-	return 0;
-    }
-
-    size.cx = dc->w.VportExtX;
-    size.cy = dc->w.VportExtY;
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return MAKELONG( size.cx, size.cy );
-    if (!x || !y) return 0;
-    dc->w.VportExtX = x;
-    dc->w.VportExtY = y;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return MAKELONG( size.cx, size.cy );
-}
-
-
-/***********************************************************************
- *           SetViewportExtEx16    (GDI.479)
- */
-BOOL16 SetViewportExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (size)
-    {
-	size->cx = dc->w.VportExtX;
-	size->cy = dc->w.VportExtY;
-    }
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!x || !y) return FALSE;
-    dc->w.VportExtX = x;
-    dc->w.VportExtY = y;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetViewportExtEx32    (GDI32.340)
- */
-BOOL32 SetViewportExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
-{
-    SIZE16 size16;
-    BOOL16 ret = SetViewportExtEx16( (HDC16)hdc, (INT16)x, (INT16)y, &size16 );
-    if (size) CONV_SIZE16TO32( &size16, size );
-    return ret;
-}
-
-
-/***********************************************************************
- *           SetViewportOrg    (GDI.13)
- */
-DWORD SetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
-{
-    POINT16 pt;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam2(dc, META_SETVIEWPORTORG, x, y);
-	return 0;
-    }
-
-    pt.x = dc->w.VportOrgX;
-    pt.y = dc->w.VportOrgY;
-    dc->w.VportOrgX = x;
-    dc->w.VportOrgY = y;
-    return pt.x | (pt.y << 16);
-}
-
-
-/***********************************************************************
- *           SetViewportOrgEx16    (GDI.480)
- */
-BOOL16 SetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (pt)
-    {
-	pt->x = dc->w.VportOrgX;
-	pt->y = dc->w.VportOrgY;
-    }
-    dc->w.VportOrgX = x;
-    dc->w.VportOrgY = y;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetViewportOrgEx32    (GDI32.341)
- */
-BOOL32 SetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
-{
-    POINT16 pt16;
-    BOOL16 ret = SetViewportOrgEx16( (HDC16)hdc, (INT16)x, (INT16)y, &pt16 );
-    if (pt) CONV_POINT16TO32( &pt16, pt );
-    return ret;
-}
-
-
-/***********************************************************************
- *           SetWindowExt    (GDI.12)
- */
-DWORD SetWindowExt( HDC16 hdc, INT16 x, INT16 y )
-{
-    SIZE16 size;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam2(dc, META_SETWINDOWEXT, x, y);
-	return 0;
-    }
-
-    size.cx = dc->w.WndExtX;
-    size.cy = dc->w.WndExtY;
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return MAKELONG( size.cx, size.cy );
-    if (!x || !y) return 0;
-    dc->w.WndExtX = x;
-    dc->w.WndExtY = y;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return MAKELONG( size.cx, size.cy );
-}
-
-
-/***********************************************************************
- *           SetWindowExtEx16    (GDI.481)
- */
-BOOL16 SetWindowExtEx16( HDC16 hdc, INT16 x, INT16 y, LPSIZE16 size )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (size)
-    {
-	size->cx = dc->w.WndExtX;
-	size->cy = dc->w.WndExtY;
-    }
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!x || !y) return FALSE;
-    dc->w.WndExtX = x;
-    dc->w.WndExtY = y;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetWindowExtEx32    (GDI32.344)
- */
-BOOL32 SetWindowExtEx32( HDC32 hdc, INT32 x, INT32 y, LPSIZE32 size )
-{
-    SIZE16 size16;
-    BOOL16 ret = SetWindowExtEx16( (HDC16)hdc, (INT16)x, (INT16)y, &size16 );
-    if (size) CONV_SIZE16TO32( &size16, size );
-    return ret;
-}
-
-
-/***********************************************************************
- *           SetWindowOrg    (GDI.11)
- */
-DWORD SetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
-{
-    POINT16 pt;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam2(dc, META_SETWINDOWORG, x, y);
-	return 0;
-    }
-
-    pt.x = dc->w.WndOrgX;
-    pt.y = dc->w.WndOrgY;
-    dc->w.WndOrgX = x;
-    dc->w.WndOrgY = y;
-    return MAKELONG( pt.x, pt.y );
-}
-
-
-/***********************************************************************
- *           SetWindowOrgEx16    (GDI.482)
- */
-BOOL16 SetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (pt)
-    {
-	pt->x = dc->w.WndOrgX;
-	pt->y = dc->w.WndOrgY;
-    }
-    dc->w.WndOrgX = x;
-    dc->w.WndOrgY = y;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetWindowOrgEx32    (GDI32.345)
- */
-BOOL32 SetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
-{
-    POINT16 pt16;
-    BOOL16 ret = SetWindowOrgEx16( (HDC16)hdc, (INT16)x, (INT16)y, &pt16 );
-    if (pt) CONV_POINT16TO32( &pt16, pt );
-    return ret;
-}
-
-
-/***********************************************************************
- *           OffsetViewportOrg    (GDI.17)
- */
-DWORD OffsetViewportOrg( HDC16 hdc, INT16 x, INT16 y )
-{
-    POINT16 pt;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam2(dc, META_OFFSETVIEWPORTORG, x, y);
-	return 0;
-    }
-
-    pt.x = dc->w.VportOrgX;
-    pt.y = dc->w.VportOrgY;
-    dc->w.VportOrgX += x;
-    dc->w.VportOrgY += y;
-    return pt.x | (pt.y << 16);
-}
-
-
-/***********************************************************************
- *           OffsetViewportOrgEx16    (GDI.476)
- */
-BOOL16 OffsetViewportOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (pt)
-    {
-	pt->x = dc->w.VportOrgX;
-	pt->y = dc->w.VportOrgY;
-    }
-    dc->w.VportOrgX += x;
-    dc->w.VportOrgY += y;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           OffsetViewportOrgEx32    (GDI32.257)
- */
-BOOL32 OffsetViewportOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
-{
-    POINT16 pt16;
-    BOOL16 ret = OffsetViewportOrgEx16( (HDC16)hdc, (INT16)x, (INT16)y, &pt16);
-    if (pt) CONV_POINT16TO32( &pt16, pt );
-    return ret;
-}
-
-
-/***********************************************************************
- *           OffsetWindowOrg    (GDI.15)
- */
-DWORD OffsetWindowOrg( HDC16 hdc, INT16 x, INT16 y )
-{
-    POINT16 pt;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam2(dc, META_OFFSETWINDOWORG, x, y);
-	return 0;
-    }
-
-    pt.x = dc->w.WndOrgX;
-    pt.y = dc->w.WndOrgY;
-    dc->w.WndOrgX += x;
-    dc->w.WndOrgY += y;
-    return pt.x | (pt.y << 16);
-}
-
-
-/***********************************************************************
- *           OffsetWindowOrgEx16    (GDI.477)
- */
-BOOL16 OffsetWindowOrgEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (pt)
-    {
-	pt->x = dc->w.WndOrgX;
-	pt->y = dc->w.WndOrgY;
-    }
-    dc->w.WndOrgX += x;
-    dc->w.WndOrgY += y;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           OffsetWindowOrgEx32    (GDI32.258)
- */
-BOOL32 OffsetWindowOrgEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
-{
-    POINT16 pt16;
-    BOOL16 ret = OffsetWindowOrgEx16( (HDC16)hdc, (INT16)x, (INT16)y, &pt16 );
-    if (pt) CONV_POINT16TO32( &pt16, pt );
-    return ret;
-}
-
-
-/***********************************************************************
- *           ScaleViewportExt    (GDI.18)
- */
-DWORD ScaleViewportExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
-                        INT16 yNum, INT16 yDenom )
-{
-    SIZE16 size;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam4(dc, META_SCALEVIEWPORTEXT, xNum, xDenom, yNum, yDenom);
-	return 0;
-    }
-
-    size.cx = dc->w.VportExtX;
-    size.cy = dc->w.VportExtY;
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return size.cx | (size.cy << 16);
-    if (!xNum || !xDenom || !xNum || !yDenom) return 0;
-    dc->w.VportExtX = (dc->w.VportExtX * xNum) / xDenom;
-    dc->w.VportExtY = (dc->w.VportExtY * yNum) / yDenom;
-    if (dc->w.VportExtX == 0) dc->w.VportExtX = 1;
-    if (dc->w.VportExtY == 0) dc->w.VportExtY = 1;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return size.cx | (size.cy << 16);
-}
-
-
-/***********************************************************************
- *           ScaleViewportExtEx16    (GDI.484)
- */
-BOOL16 ScaleViewportExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
-                             INT16 yNum, INT16 yDenom, LPSIZE16 size )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (size)
-    {
-	size->cx = dc->w.VportExtX;
-	size->cy = dc->w.VportExtY;
-    }
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
-    dc->w.VportExtX = (dc->w.VportExtX * xNum) / xDenom;
-    dc->w.VportExtY = (dc->w.VportExtY * yNum) / yDenom;
-    if (dc->w.VportExtX == 0) dc->w.VportExtX = 1;
-    if (dc->w.VportExtY == 0) dc->w.VportExtY = 1;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           ScaleViewportExtEx32    (GDI32.293)
- */
-BOOL32 ScaleViewportExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
-                             INT32 yNum, INT32 yDenom, LPSIZE32 size )
-{
-    SIZE16 size16;
-    BOOL16 ret = ScaleViewportExtEx16( (HDC16)hdc, (INT16)xNum, (INT16)xDenom,
-                                       (INT16)yNum, (INT16)yDenom, &size16 );
-    if (size) CONV_SIZE16TO32( &size16, size );
-    return ret;
-}
-
-
-/***********************************************************************
- *           ScaleWindowExt    (GDI.16)
- */
-DWORD ScaleWindowExt( HDC16 hdc, INT16 xNum, INT16 xDenom,
-		      INT16 yNum, INT16 yDenom )
-{
-    SIZE16 size;
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
-	if (!dc) return FALSE;
-	MF_MetaParam4(dc, META_SCALEWINDOWEXT, xNum, xDenom, yNum, yDenom);
-	return 0;
-    }
-
-    size.cx = dc->w.WndExtX;
-    size.cy = dc->w.WndExtY;
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return size.cx | (size.cy << 16);
-    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
-    dc->w.WndExtX = (dc->w.WndExtX * xNum) / xDenom;
-    dc->w.WndExtY = (dc->w.WndExtY * yNum) / yDenom;
-    if (dc->w.WndExtX == 0) dc->w.WndExtX = 1;
-    if (dc->w.WndExtY == 0) dc->w.WndExtY = 1;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return size.cx | (size.cy << 16);
-}
-
-
-/***********************************************************************
- *           ScaleWindowExtEx16    (GDI.485)
- */
-BOOL16 ScaleWindowExtEx16( HDC16 hdc, INT16 xNum, INT16 xDenom,
-                           INT16 yNum, INT16 yDenom, LPSIZE16 size )
-{
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-    if (size)
-    {
-	size->cx = dc->w.WndExtX;
-	size->cy = dc->w.WndExtY;
-    }
-    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
-	return TRUE;
-    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
-    dc->w.WndExtX = (dc->w.WndExtX * xNum) / xDenom;
-    dc->w.WndExtY = (dc->w.WndExtY * yNum) / yDenom;
-    if (dc->w.WndExtX == 0) dc->w.WndExtX = 1;
-    if (dc->w.WndExtY == 0) dc->w.WndExtY = 1;
-    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           ScaleWindowExtEx32    (GDI32.294)
- */
-BOOL32 ScaleWindowExtEx32( HDC32 hdc, INT32 xNum, INT32 xDenom,
-                           INT32 yNum, INT32 yDenom, LPSIZE32 size )
-{
-    SIZE16 size16;
-    BOOL16 ret = ScaleWindowExtEx16( (HDC16)hdc, (INT16)xNum, (INT16)xDenom,
-                                     (INT16)yNum, (INT16)yDenom, &size16 );
-    if (size) CONV_SIZE16TO32( &size16, size );
-    return ret;
-}
diff --git a/windows/mdi.c b/windows/mdi.c
index 684b3fc..e0b2474 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -663,8 +663,8 @@
  */
 HBITMAP16 CreateMDIMenuBitmap(void)
 {
- HDC16 		hDCSrc  = CreateCompatibleDC(0);
- HDC16		hDCDest	= CreateCompatibleDC(hDCSrc);
+ HDC32 		hDCSrc  = CreateCompatibleDC32(0);
+ HDC32		hDCDest	= CreateCompatibleDC32(hDCSrc);
  HBITMAP16	hbClose = LoadBitmap16(0, MAKEINTRESOURCE(OBM_CLOSE) );
  HBITMAP16	hbCopy,hb_src,hb_dest;
 
@@ -680,8 +680,8 @@
 
  DeleteObject32(hbClose);
 
- DeleteDC(hDCDest);
- DeleteDC(hDCSrc);
+ DeleteDC32(hDCDest);
+ DeleteDC32(hDCSrc);
 
  return hbCopy;
 }
diff --git a/windows/message.c b/windows/message.c
index 07e4722..dcfec8d 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -439,6 +439,35 @@
             if (HOOK_IsHooked( WH_JOURNALRECORD ))
                 MSG_JournalRecordMsg( msg );
             QUEUE_RemoveMsg( sysMsgQueue, pos );
+            
+            /* call CBT hook _after_ message removed from queue */
+	    if (HOOK_IsHooked( WH_CBT ))
+	    {
+	    	if (((msg->message >= WM_MOUSEFIRST) &&
+                     (msg->message <= WM_MOUSELAST)) ||
+	    	    ((msg->message >= WM_NCMOUSEFIRST) &&
+                     (msg->message <= WM_NCMOUSELAST)))
+	    	{
+                    MOUSEHOOKSTRUCT16 *hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16);
+                    if (hook)
+                    {
+	    	  	hook->pt           = msg->pt;
+			hook->hwnd         = msg->hwnd;
+			hook->wHitTestCode = (INT16)SendMessage16( msg->hwnd,
+                                            WM_NCHITTEST, 0,
+                                            MAKELONG( msg->pt.x, msg->pt.y ) );
+			hook->dwExtraInfo  = 0;
+			HOOK_CallHooks16( WH_CBT, HCBT_CLICKSKIPPED ,msg->message, 
+                                          (LPARAM)SEGPTR_GET(hook) );
+			SEGPTR_FREE(hook);
+                    }
+                }
+                else 
+                    if ((msg->message >= WM_KEYFIRST) &&
+                        (msg->message <= WM_KEYLAST))
+		   	HOOK_CallHooks16( WH_CBT, HCBT_KEYSKIPPED,
+                                          msg->wParam, msg->lParam );
+            }
         }
         return TRUE;
     }
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 6cfb59f..9708381 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -9,11 +9,11 @@
 #include <malloc.h>
 #include "windows.h"
 #include "dlgs.h"
+#include "heap.h"
 #include "module.h"
 #include "win.h"
 #include "resource.h"
 #include "task.h"
-#include "string32.h"
 
 typedef struct {
   LPCSTR title;
@@ -213,8 +213,8 @@
     MSGBOX mbox;
     int ret;
 
-    mbox.title = title?STRING32_DupUniToAnsi(title):NULL;
-    mbox.text  = text?STRING32_DupUniToAnsi(text):NULL;
+    mbox.title = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
+    mbox.text  = HEAP_strdupWtoA( GetProcessHeap(), 0, text );
     mbox.type  = type;
 
     fprintf(stderr,"MessageBox(%s,%s)\n",mbox.text,mbox.title);
@@ -225,8 +225,8 @@
                                   MODULE_GetWndProcEntry16("SystemMessageBoxProc"),
                                   (LONG)&mbox );
     SYSRES_FreeResource( handle );
-    if (title) free(mbox.title);
-    if (text) free(mbox.text);
+    HeapFree( GetProcessHeap(), 0, mbox.title );
+    HeapFree( GetProcessHeap(), 0, mbox.text );
     return ret;
 }
 
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 423cb4f..4c6a2d5 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -436,20 +436,20 @@
 void NC_DrawSysButton( HWND hwnd, HDC16 hdc, BOOL down )
 {
     RECT16 rect;
-    HDC16 hdcMem;
-    HBITMAP16 hbitmap;
+    HDC32 hdcMem;
+    HBITMAP32 hbitmap;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
     if( !(wndPtr->flags & WIN_MANAGED) )
     {
       NC_GetInsideRect( hwnd, &rect );
-      hdcMem = CreateCompatibleDC( hdc );
+      hdcMem = CreateCompatibleDC32( hdc );
       hbitmap = SelectObject32( hdcMem, hbitmapClose );
       BitBlt32(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
                hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
                down ? NOTSRCCOPY : SRCCOPY );
       SelectObject32( hdcMem, hbitmap );
-      DeleteDC( hdcMem );
+      DeleteDC32( hdcMem );
     }
 }
 
@@ -649,7 +649,7 @@
     {
 	if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
 	else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
-	SetBkMode( hdc, TRANSPARENT );
+	SetBkMode32( hdc, TRANSPARENT );
 	DrawText16( hdc, buffer, -1, &r,
                     DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
     }
diff --git a/windows/property.c b/windows/property.c
index 876bd58..0762558 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -5,11 +5,9 @@
  */
 
 #define NO_TRANSITION_TYPES  /* This file is Win32-clean */
-#include <stdlib.h>
 #include <string.h>
 #include "win.h"
 #include "heap.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -83,9 +81,9 @@
     HANDLE32 ret;
 
     if (!HIWORD(str)) return GetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
-    strA = STRING32_DupUniToAnsi( str );
+    strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     ret = GetProp32A( hwnd, strA );
-    free( strA );
+    HeapFree( GetProcessHeap(), 0, strA );
     return ret;
 }
 
@@ -141,9 +139,9 @@
 
     if (!HIWORD(str))
         return SetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str), handle );
-    strA = STRING32_DupUniToAnsi( str );
+    strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     ret = SetProp32A( hwnd, strA, handle );
-    free( strA );
+    HeapFree( GetProcessHeap(), 0, strA );
     return ret;
 }
 
@@ -205,9 +203,9 @@
 
     if (!HIWORD(str))
         return RemoveProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
-    strA = STRING32_DupUniToAnsi( str );
+    strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
     ret = RemoveProp32A( hwnd, strA );
-    free( strA );
+    HeapFree( GetProcessHeap(), 0, strA );
     return ret;
 }
 
@@ -324,9 +322,9 @@
                       prop->handle, prop->string );
         if (HIWORD(prop->string))
         {
-            LPWSTR str = STRING32_DupAnsiToUni( prop->string );
+            LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, prop->string );
             ret = func( hwnd, str, prop->handle, lParam );
-            free( str );
+            HeapFree( GetProcessHeap(), 0, str );
         }
         else
             ret = func( hwnd, (LPCWSTR)(UINT32)LOWORD( prop->string ),
diff --git a/windows/win.c b/windows/win.c
index 05f52b8..aae3d6d 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -22,7 +22,6 @@
 #include "menu.h"
 #include "message.h"
 #include "nonclient.h"
-#include "string32.h"
 #include "queue.h"
 #include "winpos.h"
 #include "color.h"
@@ -363,7 +362,7 @@
     if (!(wndPtr->dwStyle & WS_CHILD))
        if (wndPtr->wIDmenu) DestroyMenu( (HMENU16)wndPtr->wIDmenu );
     if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
-    if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
+    if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
     if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
 
     WINPROC_FreeProc( wndPtr->winproc );
@@ -919,9 +918,9 @@
     {
     	if (HIWORD(className))
         {
-            LPSTR cn = STRING32_DupUniToAnsi(className);
+            LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
             fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
-            free(cn);
+            HeapFree( GetProcessHeap(), 0, cn );
 	}
         else
             fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
@@ -1221,9 +1220,9 @@
         /* with this name exists either. */
         if (!(atom = GlobalFindAtom32W( className ))) return 0;
     }
-    buffer = title ? STRING32_DupUniToAnsi( title ) : NULL;
+    buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
     hwnd = WIN_FindWindow( 0, 0, atom, buffer );
-    if (buffer) free( buffer );
+    HeapFree( GetProcessHeap(), 0, buffer );
     return hwnd;
 }
 
diff --git a/windows/winproc.c b/windows/winproc.c
index 2fa5f5d..6cbe823 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -12,7 +12,6 @@
 #include "ldt.h"
 #include "registers.h"
 #include "stackframe.h"
-#include "string32.h"
 #include "struct32.h"
 #include "win.h"
 #include "winproc.h"
@@ -360,7 +359,7 @@
         }
         return 1;
     case WM_SETTEXT:
-        *plparam = (LPARAM)STRING32_DupAnsiToUni( (LPCSTR)*plparam );
+        *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
         return (*plparam ? 1 : -1);
     case WM_NCCREATE:
     case WM_CREATE:
@@ -370,9 +369,11 @@
             if (!cs) return -1;
             *cs = *(CREATESTRUCT32W *)*plparam;
             if (HIWORD(cs->lpszName))
-                cs->lpszName = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszName );
+                cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
+                                                (LPCSTR)cs->lpszName );
             if (HIWORD(cs->lpszClass))
-                cs->lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszClass );
+                cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
+                                                 (LPCSTR)cs->lpszClass );
             *plparam = (LPARAM)cs;
         }
         return 1;
@@ -383,9 +384,11 @@
             if (!cs) return -1;
             *cs = *(MDICREATESTRUCT32W *)*plparam;
             if (HIWORD(cs->szClass))
-                cs->szClass = STRING32_DupAnsiToUni( (LPCSTR)cs->szClass );
+                cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
+                                               (LPCSTR)cs->szClass );
             if (HIWORD(cs->szTitle))
-                cs->szTitle = STRING32_DupAnsiToUni( (LPCSTR)cs->szTitle );
+                cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
+                                               (LPCSTR)cs->szTitle );
             *plparam = (LPARAM)cs;
         }
         return 1;
@@ -421,22 +424,26 @@
         }
         break;
     case WM_SETTEXT:
-        free( (void *)lParam );
+        HeapFree( SystemHeap, 0, (void *)lParam );
         break;
     case WM_NCCREATE:
     case WM_CREATE:
         {
             CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
-            if (HIWORD(cs->lpszName)) free( (LPVOID)cs->lpszName );
-            if (HIWORD(cs->lpszClass)) free( (LPVOID)cs->lpszClass );
+            if (HIWORD(cs->lpszName))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
             HeapFree( SystemHeap, 0, cs );
         }
         break;
     case WM_MDICREATE:
         {
             MDICREATESTRUCT32W *cs = (MDICREATESTRUCT32W *)lParam;
-            if (HIWORD(cs->szTitle)) free( (LPVOID)cs->szTitle );
-            if (HIWORD(cs->szClass)) free( (LPVOID)cs->szClass );
+            if (HIWORD(cs->szTitle))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
+            if (HIWORD(cs->szClass))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
             HeapFree( SystemHeap, 0, cs );
         }
         break;
@@ -464,7 +471,7 @@
         }
         return 1;
     case WM_SETTEXT:
-        *plparam = (LPARAM)STRING32_DupUniToAnsi( (LPCWSTR)*plparam );
+        *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
         return (*plparam ? 1 : -1);
     case WM_NCCREATE:
     case WM_CREATE:
@@ -474,9 +481,11 @@
             if (!cs) return -1;
             *cs = *(CREATESTRUCT32A *)*plparam;
             if (HIWORD(cs->lpszName))
-                cs->lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs->lpszName );
+                cs->lpszName  = HEAP_strdupWtoA( SystemHeap, 0,
+                                                 (LPCWSTR)cs->lpszName );
             if (HIWORD(cs->lpszClass))
-                cs->lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs->lpszClass);
+                cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
+                                                 (LPCWSTR)cs->lpszClass);
             *plparam = (LPARAM)cs;
         }
         return 1;
@@ -487,9 +496,11 @@
             if (!cs) return -1;
             *cs = *(MDICREATESTRUCT32A *)*plparam;
             if (HIWORD(cs->szTitle))
-                cs->szTitle = STRING32_DupUniToAnsi( (LPCWSTR)cs->szTitle );
+                cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
+                                               (LPCWSTR)cs->szTitle );
             if (HIWORD(cs->szClass))
-                cs->szClass = STRING32_DupUniToAnsi( (LPCWSTR)cs->szClass );
+                cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
+                                               (LPCWSTR)cs->szClass );
             *plparam = (LPARAM)cs;
         }
         return 1;
@@ -525,22 +536,26 @@
         }
         break;
     case WM_SETTEXT:
-        free( (void *)lParam );
+        HeapFree( SystemHeap, 0, (void *)lParam );
         break;
     case WM_NCCREATE:
     case WM_CREATE:
         {
             CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
-            if (HIWORD(cs->lpszName)) free( (LPVOID)cs->lpszName );
-            if (HIWORD(cs->lpszClass)) free( (LPVOID)cs->lpszClass );
+            if (HIWORD(cs->lpszName))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
             HeapFree( SystemHeap, 0, cs );
         }
         break;
     case WM_MDICREATE:
         {
             MDICREATESTRUCT32A *cs = (MDICREATESTRUCT32A *)lParam;
-            if (HIWORD(cs->szTitle)) free( (LPVOID)cs->szTitle );
-            if (HIWORD(cs->szClass)) free( (LPVOID)cs->szClass );
+            if (HIWORD(cs->szTitle))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
+            if (HIWORD(cs->szClass))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
             HeapFree( SystemHeap, 0, cs );
         }
         break;
@@ -868,9 +883,11 @@
             cs->lpszName  = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
             cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
             if (HIWORD(cs->lpszName))
-                cs->lpszName = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszName );
+                cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
+                                                (LPCSTR)cs->lpszName );
             if (HIWORD(cs->lpszClass))
-                cs->lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs->lpszClass );
+                cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
+                                                 (LPCSTR)cs->lpszClass );
             *(LPARAM *)(cs + 1) = *plparam;  /* Store the previous lParam */
             *plparam = (LPARAM)cs;
         }
@@ -887,9 +904,11 @@
             cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
             cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
             if (HIWORD(cs->szTitle))
-                cs->szTitle = STRING32_DupAnsiToUni( (LPCSTR)cs->szTitle );
+                cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
+                                               (LPCSTR)cs->szTitle );
             if (HIWORD(cs->szClass))
-                cs->szClass = STRING32_DupAnsiToUni( (LPCSTR)cs->szClass );
+                cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
+                                               (LPCSTR)cs->szClass );
             *(LPARAM *)(cs + 1) = *plparam;  /* Store the previous lParam */
             *plparam = (LPARAM)cs;
         }
@@ -921,8 +940,10 @@
             lParam = *(LPARAM *)(cs + 1);
             STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs,
                                     (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
-            if (HIWORD(cs->lpszName)) free( (LPVOID)cs->lpszName );
-            if (HIWORD(cs->lpszClass)) free( (LPVOID)cs->lpszClass );
+            if (HIWORD(cs->lpszName))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
+            if (HIWORD(cs->lpszClass))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
             HeapFree( SystemHeap, 0, cs );
         }
         break;
@@ -932,8 +953,10 @@
             lParam = *(LPARAM *)(cs + 1);
             STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs,
                                  (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
-            if (HIWORD(cs->szTitle)) free( (LPVOID)cs->szTitle );
-            if (HIWORD(cs->szClass)) free( (LPVOID)cs->szClass );
+            if (HIWORD(cs->szTitle))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
+            if (HIWORD(cs->szClass))
+                HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
             HeapFree( SystemHeap, 0, cs );
         }
         break;
@@ -1376,9 +1399,8 @@
     case LB_DIR32:
     case LB_ADDFILE32:
         {
-            LPSTR str = SEGPTR_ALLOC( lstrlen32W((LPWSTR)*plparam) + 1 );
+            LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
             if (!str) return -1;
-            STRING32_UniToAnsi( str, (LPWSTR)*plparam );
             *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING32);
             *pwparam16 = (WPARAM16)LOWORD(wParam32);
             *plparam   = (LPARAM)SEGPTR_GET(str);
@@ -1389,23 +1411,14 @@
         {
             CREATESTRUCT16 *cs;
             CREATESTRUCT32W *cs32 = (CREATESTRUCT32W *)*plparam;
+            LPSTR name, cls;
 
             if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
             STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A *)cs32, cs );
-            if (HIWORD(cs32->lpszName))
-            {
-                LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->lpszName) + 1 );
-                STRING32_UniToAnsi( name, cs32->lpszName );
-                cs->lpszName = SEGPTR_GET(name);
-            }
-            else cs->lpszName = (SEGPTR)cs32->lpszName;
-            if (HIWORD(cs32->lpszClass))
-            {
-                LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->lpszClass) + 1 );
-                STRING32_UniToAnsi( name, cs32->lpszClass );
-                cs->lpszClass = SEGPTR_GET(name);
-            }
-            else cs->lpszClass = (SEGPTR)cs32->lpszClass;
+            name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
+            cls  = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
+            cs->lpszName  = SEGPTR_GET(name);
+            cs->lpszClass = SEGPTR_GET(cls);
             *pmsg16    = (UINT16)msg32;
             *pwparam16 = (WPARAM16)LOWORD(wParam32);
             *plparam   = (LPARAM)SEGPTR_GET(cs);
@@ -1415,23 +1428,14 @@
         {
             MDICREATESTRUCT16 *cs;
             MDICREATESTRUCT32W *cs32 = (MDICREATESTRUCT32W *)*plparam;
+            LPSTR name, cls;
 
             if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
             STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A *)cs32, cs );
-            if (HIWORD(cs32->szTitle))
-            {
-                LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->szTitle) + 1 );
-                STRING32_UniToAnsi( name, cs32->szTitle );
-                cs->szTitle = SEGPTR_GET(name);
-            }
-            else cs->szTitle = (SEGPTR)cs32->szTitle;
-            if (HIWORD(cs32->szClass))
-            {
-                LPSTR name = SEGPTR_ALLOC( lstrlen32W(cs32->szClass) + 1 );
-                STRING32_UniToAnsi( name, cs32->szClass );
-                cs->szClass = SEGPTR_GET(name);
-            }
-            else cs->szClass = (SEGPTR)cs32->szClass;
+            name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
+            cls  = SEGPTR_STRDUP_WtoA( cs32->szClass );
+            cs->szTitle = SEGPTR_GET(name);
+            cs->szClass = SEGPTR_GET(cls);
             *pmsg16    = (UINT16)msg32;
             *pwparam16 = (WPARAM16)LOWORD(wParam32);
             *plparam   = (LPARAM)SEGPTR_GET(cs);
@@ -1439,9 +1443,8 @@
         return 1;
     case WM_SETTEXT:
         {
-            LPSTR str = SEGPTR_ALLOC( lstrlen32W((LPWSTR)*plparam) + 1 );
+            LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
             if (!str) return -1;
-            STRING32_UniToAnsi( str, (LPWSTR)*plparam );
             *pmsg16    = (UINT16)msg32;
             *pwparam16 = (WPARAM16)LOWORD(wParam32);
             *plparam   = (LPARAM)SEGPTR_GET(str);
@@ -1467,7 +1470,7 @@
         {
             LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lParam);
             lParam = *((LPARAM *)str - 1);
-            STRING32_AnsiToUni( (LPWSTR)lParam, str );
+            lstrcpyAtoW( (LPWSTR)lParam, str );
             SEGPTR_FREE( (LPARAM *)str - 1 );
         }
         break;