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/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 */