[GDI32] Update Gdi Driver Header.
[reactos.git] / win32ss / gdi / gdi32 / wine / rosglue.c
index 0c2464e..b537b90 100644 (file)
@@ -6,11 +6,27 @@
 #define NDEBUG
 #include <debug.h>
 
+WINEDC *get_nulldrv_dc( PHYSDEV dev );
+
+BOOL nulldrv_BeginPath( PHYSDEV dev );
+BOOL nulldrv_EndPath( PHYSDEV dev );
+BOOL nulldrv_AbortPath( PHYSDEV dev );
+BOOL nulldrv_CloseFigure( PHYSDEV dev );
+BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode );
+BOOL nulldrv_FillPath( PHYSDEV dev );
+BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev );
+BOOL nulldrv_StrokePath( PHYSDEV dev );
+BOOL nulldrv_FlattenPath( PHYSDEV dev );
+BOOL nulldrv_WidenPath( PHYSDEV dev );
+
+static INT i = 0;
+
 static
 INT_PTR
 NULL_Unused()
 {
-    __debugbreak();
+    DPRINT1("NULL_Unused %d\n",i);
+    // __debugbreak();
     return 0;
 }
 
@@ -26,19 +42,24 @@ static INT   NULL_ExtSelectClipRgn(PHYSDEV dev, HRGN hrgn, INT iMode) { return 1
 static INT   NULL_IntersectClipRect(PHYSDEV dev, INT left, INT top, INT right, INT bottom) { return 1; }
 static INT   NULL_OffsetClipRgn(PHYSDEV dev, INT x, INT y) { return SIMPLEREGION; }
 static INT   NULL_ExcludeClipRect(PHYSDEV dev, INT left, INT top, INT right, INT bottom) { return 1; }
+static BOOL  NULL_ExtTextOutW(PHYSDEV dev, INT x, INT y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT cwc, const INT *lpDx) { return TRUE; }
+static BOOL  NULL_ModifyWorldTransform( PHYSDEV dev, const XFORM* xform, DWORD mode ) { return TRUE; }
+static BOOL  NULL_SetWorldTransform( PHYSDEV dev, const XFORM* xform ) { return TRUE; }
+static BOOL  NULL_PolyPolyline(PHYSDEV dev, const POINT *pt, const DWORD *lpt, DWORD cw) { return TRUE; }
 
 static const struct gdi_dc_funcs DummyPhysDevFuncs =
 {
     (PVOID)NULL_Unused, //INT      (*pAbortDoc)(PHYSDEV);
-    (PVOID)NULL_Unused, //BOOL     (*pAbortPath)(PHYSDEV);
+    nulldrv_AbortPath,  //BOOL     (*pAbortPath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pAlphaBlend)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,BLENDFUNCTION);
     (PVOID)NULL_Unused, //BOOL     (*pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
     (PVOID)NULL_Unused, //BOOL     (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //BOOL     (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
-    (PVOID)NULL_Unused, //BOOL     (*pBeginPath)(PHYSDEV);
+    nulldrv_BeginPath,  //BOOL     (*pBeginPath)(PHYSDEV);
     (PVOID)NULL_Unused, //DWORD    (*pBlendImage)(PHYSDEV,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,BLENDFUNCTION);
     (PVOID)NULL_Unused, //BOOL     (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
-    (PVOID)NULL_Unused, //BOOL     (*pCloseFigure)(PHYSDEV);
+    nulldrv_CloseFigure, //BOOL     (*pCloseFigure)(PHYSDEV);
+
     (PVOID)NULL_Unused, //BOOL     (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*);
     (PVOID)NULL_Unused, //BOOL     (*pCreateDC)(PHYSDEV*,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
     (PVOID)NULL_Unused, //BOOL     (*pDeleteDC)(PHYSDEV);
@@ -47,29 +68,32 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //BOOL     (*pEllipse)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //INT      (*pEndDoc)(PHYSDEV);
     (PVOID)NULL_Unused, //INT      (*pEndPage)(PHYSDEV);
-    (PVOID)NULL_Unused, //BOOL     (*pEndPath)(PHYSDEV);
+    nulldrv_EndPath,    //BOOL     (*pEndPath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pEnumFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
+
     (PVOID)NULL_Unused, //INT      (*pEnumICMProfiles)(PHYSDEV,ICMENUMPROCW,LPARAM);
     NULL_ExcludeClipRect, //INT      (*pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //INT      (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
     (PVOID)NULL_Unused, //INT      (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
     (PVOID)NULL_Unused, //BOOL     (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
     NULL_ExtSelectClipRgn, //INT      (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
-    (PVOID)NULL_Unused, //BOOL     (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
-    (PVOID)NULL_Unused, //BOOL     (*pFillPath)(PHYSDEV);
+    NULL_ExtTextOutW, //BOOL     (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
+    nulldrv_FillPath,   //BOOL     (*pFillPath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
-    (PVOID)NULL_Unused, //BOOL     (*pFlattenPath)(PHYSDEV);
+    nulldrv_FlattenPath, //BOOL     (*pFlattenPath)(PHYSDEV);
+
     (PVOID)NULL_Unused, //BOOL     (*pFontIsLinked)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
     (PVOID)NULL_Unused, //BOOL     (*pGdiComment)(PHYSDEV,UINT,const BYTE*);
-    (PVOID)NULL_Unused, //BOOL     (*pGdiRealizationInfo)(PHYSDEV,void*);
     (PVOID)NULL_Unused, //UINT     (*pGetBoundsRect)(PHYSDEV,RECT*,UINT);
     (PVOID)NULL_Unused, //BOOL     (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
     (PVOID)NULL_Unused, //BOOL     (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
     (PVOID)NULL_Unused, //BOOL     (*pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
+    (PVOID)NULL_Unused, //BOOL     (*pGetCharWidthInfo)(PHYSDEV,void*);
     (PVOID)NULL_Unused, //INT      (*pGetDeviceCaps)(PHYSDEV,INT);
     (PVOID)NULL_Unused, //BOOL     (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
     (PVOID)NULL_Unused, //DWORD    (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD);
+    (PVOID)NULL_Unused, //BOOL     (*pGetFontRealizationInfo)(PHYSDEV,void*);
     (PVOID)NULL_Unused, //DWORD    (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET);
     (PVOID)NULL_Unused, //DWORD    (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD);
     (PVOID)NULL_Unused, //DWORD    (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*);
@@ -89,7 +113,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     NULL_IntersectClipRect, //INT      (*pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //BOOL     (*pInvertRgn)(PHYSDEV,HRGN);
     (PVOID)NULL_Unused, //BOOL     (*pLineTo)(PHYSDEV,INT,INT);
-    (PVOID)NULL_Unused, //BOOL     (*pModifyWorldTransform)(PHYSDEV,const XFORM*,DWORD);
+    NULL_ModifyWorldTransform, //BOOL     (*pModifyWorldTransform)(PHYSDEV,const XFORM*,DWORD);
     (PVOID)NULL_Unused, //BOOL     (*pMoveTo)(PHYSDEV,INT,INT);
     NULL_OffsetClipRgn, //INT      (*pOffsetClipRgn)(PHYSDEV,INT,INT);
     (PVOID)NULL_Unused, //BOOL     (*pOffsetViewportOrgEx)(PHYSDEV,INT,INT,POINT*);
@@ -101,7 +125,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //BOOL     (*pPolyBezierTo)(PHYSDEV,const POINT*,DWORD);
     (PVOID)NULL_Unused, //BOOL     (*pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD);
     (PVOID)NULL_Unused, //BOOL     (*pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT);
-    (PVOID)NULL_Unused, //BOOL     (*pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD);
+    NULL_PolyPolyline, //BOOL     (*pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD);
     (PVOID)NULL_Unused, //BOOL     (*pPolygon)(PHYSDEV,const POINT*,INT);
     (PVOID)NULL_Unused, //BOOL     (*pPolyline)(PHYSDEV,const POINT*,INT);
     (PVOID)NULL_Unused, //BOOL     (*pPolylineTo)(PHYSDEV,const POINT*,INT);
@@ -110,15 +134,15 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //UINT     (*pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
     (PVOID)NULL_Unused, //BOOL     (*pRectangle)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //HDC      (*pResetDC)(PHYSDEV,const DEVMODEW*);
-    NULL_RestoreDC, //BOOL     (*pRestoreDC)(PHYSDEV,INT);
+    NULL_RestoreDC,     //BOOL     (*pRestoreDC)(PHYSDEV,INT);
     (PVOID)NULL_Unused, //BOOL     (*pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
-    NULL_SaveDC, //INT      (*pSaveDC)(PHYSDEV);
+    NULL_SaveDC,        //INT      (*pSaveDC)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pScaleViewportExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
     (PVOID)NULL_Unused, //BOOL     (*pScaleWindowExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
     (PVOID)NULL_Unused, //HBITMAP  (*pSelectBitmap)(PHYSDEV,HBITMAP);
     (PVOID)NULL_Unused, //HBRUSH   (*pSelectBrush)(PHYSDEV,HBRUSH,const struct brush_pattern*);
-    (PVOID)NULL_Unused, //BOOL     (*pSelectClipPath)(PHYSDEV,INT);
-    NULL_SelectFont, //HFONT    (*pSelectFont)(PHYSDEV,HFONT,UINT*);
+    nulldrv_SelectClipPath, //BOOL     (*pSelectClipPath)(PHYSDEV,INT);
+    NULL_SelectFont,    //HFONT    (*pSelectFont)(PHYSDEV,HFONT,UINT*);
     (PVOID)NULL_Unused, //HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
     (PVOID)NULL_Unused, //HPEN     (*pSelectPen)(PHYSDEV,HPEN,const struct brush_pattern*);
     (PVOID)NULL_Unused, //INT      (*pSetArcDirection)(PHYSDEV,INT);
@@ -131,7 +155,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //VOID     (*pSetDeviceClipping)(PHYSDEV,HRGN);
     (PVOID)NULL_Unused, //BOOL     (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
     (PVOID)NULL_Unused, //DWORD    (*pSetLayout)(PHYSDEV,DWORD);
-    NULL_SetMapMode, //INT      (*pSetMapMode)(PHYSDEV,INT);
+    NULL_SetMapMode,    //INT      (*pSetMapMode)(PHYSDEV,INT);
     (PVOID)NULL_Unused, //DWORD    (*pSetMapperFlags)(PHYSDEV,DWORD);
     (PVOID)NULL_Unused, //COLORREF (*pSetPixel)(PHYSDEV,INT,INT,COLORREF);
     (PVOID)NULL_Unused, //INT      (*pSetPolyFillMode)(PHYSDEV,INT);
@@ -146,19 +170,31 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     NULL_SetViewportOrgEx, //BOOL     (*pSetViewportOrgEx)(PHYSDEV,INT,INT,POINT*);
     NULL_SetWindowExtEx, //BOOL     (*pSetWindowExtEx)(PHYSDEV,INT,INT,SIZE*);
     NULL_SetWindowOrgEx, //BOOL     (*pSetWindowOrgEx)(PHYSDEV,INT,INT,POINT*);
-    (PVOID)NULL_Unused, //BOOL     (*pSetWorldTransform)(PHYSDEV,const XFORM*);
+    NULL_SetWorldTransform, //BOOL     (*pSetWorldTransform)(PHYSDEV,const XFORM*);
     (PVOID)NULL_Unused, //INT      (*pStartDoc)(PHYSDEV,const DOCINFOW*);
     (PVOID)NULL_Unused, //INT      (*pStartPage)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pStretchBlt)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,DWORD);
     (PVOID)NULL_Unused, //INT      (*pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void*,BITMAPINFO*,UINT,DWORD);
-    (PVOID)NULL_Unused, //BOOL     (*pStrokeAndFillPath)(PHYSDEV);
-    (PVOID)NULL_Unused, //BOOL     (*pStrokePath)(PHYSDEV);
+    nulldrv_StrokeAndFillPath, //BOOL     (*pStrokeAndFillPath)(PHYSDEV);
+    nulldrv_StrokePath, //BOOL     (*pStrokePath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pUnrealizePalette)(HPALETTE);
-    (PVOID)NULL_Unused, //BOOL     (*pWidenPath)(PHYSDEV);
+    nulldrv_WidenPath,  //BOOL     (*pWidenPath)(PHYSDEV);
     (PVOID)NULL_Unused, //struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT);
     0 // UINT       priority;
 };
 
+WINEDC *get_nulldrv_dc( PHYSDEV dev )
+{
+    return CONTAINING_RECORD( dev, WINEDC, NullPhysDev );
+}
+
+WINEDC* get_physdev_dc( PHYSDEV dev )
+{
+    while (dev->funcs != &DummyPhysDevFuncs)
+        dev = dev->next;
+    return get_nulldrv_dc( dev );
+}
+
 static
 GDILOOBJTYPE
 ConvertObjectType(
@@ -285,6 +321,8 @@ alloc_dc_ptr(WORD magic)
             return NULL;
         }
 
+        pWineDc->iType = LDC_EMFLDC;
+
         /* Set the Wine DC as LDC */
         GdiSetLDC(pWineDc->hdc, pWineDc);
     }
@@ -367,6 +405,7 @@ push_dc_driver_ros(
     PHYSDEV physdev,
     const struct gdi_dc_funcs *funcs)
 {
+    while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next;
     physdev->funcs = funcs;
     physdev->next = *dev;
     physdev->hdc = CONTAINING_RECORD(dev, WINEDC, physDev)->hdc;
@@ -401,13 +440,33 @@ GDI_hdc_not_using_object(
     ASSERT(hdcLink == hdc);
 }
 
+/***********************************************************************
+ *           bitmap_info_size
+ *
+ * Return the size of the bitmap info structure including color table.
+ */
 int
 bitmap_info_size(
     const BITMAPINFO * info,
     WORD coloruse)
 {
-    __debugbreak();
-    return 0;
+    unsigned int colors, size, masks = 0;
+
+    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+    {
+        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
+        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
+        return sizeof(BITMAPCOREHEADER) + colors *
+             ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+    }
+    else  /* assume BITMAPINFOHEADER */
+    {
+        if (info->bmiHeader.biClrUsed) colors = min( info->bmiHeader.biClrUsed, 256 );
+        else colors = info->bmiHeader.biBitCount > 8 ? 0 : 1 << info->bmiHeader.biBitCount;
+        if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+        size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+        return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+    }
 }
 
 BOOL
@@ -482,7 +541,7 @@ DeleteColorSpace(
 {
     return NtGdiDeleteColorSpace(hcs);
 }
-
+#if 0
 BOOL
 WINAPI
 SetWorldTransformForMetafile(
@@ -509,7 +568,7 @@ SetWorldTransformForMetafile(
 
     return SetWorldTransform(hdc, pxform);
 }
-
+#endif
 void
 __cdecl
 _assert (
@@ -520,23 +579,6 @@ _assert (
     DbgRaiseAssertionFailure();
 }
 
-#if defined(_MSC_VER) && (DBG != 1)
-
-/* MSVC uses its own in this case. */
-#else
-
-double
-__cdecl
-atan2(
-    double y,
-    double x)
-{
-    __debugbreak();
-    return 0.;
-}
-
-#endif
-
 /******************************************************************************/
 
 static
@@ -687,6 +729,15 @@ DRIVER_SelectBrush(PHYSDEV physdev, HBRUSH hbrush, const struct brush_pattern *p
     return hOldBrush;
 }
 
+static
+HRGN
+DRIVER_PathToRegion(PHYSDEV physdev)
+{
+    DPRINT1("DRIVER_PathToRegion\n");
+    return (HRGN)(ULONG_PTR)physdev->funcs->pAbortPath( physdev );
+}
+
+
 static
 DWORD_PTR
 DRIVER_Dispatch(
@@ -854,10 +905,8 @@ DRIVER_Dispatch(
                                                  _va_arg_n(argptr, const POINT*, 0),
                                                  _va_arg_n(argptr, DWORD, 1));
         case DCFUNC_PolyDraw:
-            DPRINT1("DCFUNC_PolyDraw not implemented\n");
-            return FALSE;
-            return physdev->funcs->pPolyDraw(physdev,
-                                             _va_arg_n(argptr, const POINT*, 1),
+           return physdev->funcs->pPolyDraw(physdev,
+                                             _va_arg_n(argptr, const POINT*, 0),
                                              _va_arg_n(argptr, const BYTE*, 1),
                                              _va_arg_n(argptr, DWORD, 2));
         case DCFUNC_Polygon:
@@ -869,8 +918,6 @@ DRIVER_Dispatch(
                                              _va_arg_n(argptr, const POINT*, 0),
                                              _va_arg_n(argptr, INT, 1));
         case DCFUNC_PolylineTo:
-            DPRINT1("DCFUNC_PolylineTo not implemented\n");
-            return FALSE;
             return physdev->funcs->pPolylineTo(physdev,
                                                _va_arg_n(argptr, const POINT*, 0),
                                                _va_arg_n(argptr, INT, 1));
@@ -1004,6 +1051,11 @@ DRIVER_Dispatch(
                                                    _va_arg_n(argptr, INT, 0), // X
                                                    _va_arg_n(argptr, INT, 1), // Y
                                                    _va_arg_n(argptr, LPPOINT, 2)); // lpPoint
+
+        case DCFUNC_SetWorldTransform:
+            return physdev->funcs->pSetWorldTransform(physdev,
+                                                      va_arg(argptr, const XFORM*));
+
         case DCFUNC_StretchBlt:
             return DRIVER_StretchBlt(physdev,
                                      physdev->hdc,
@@ -1023,15 +1075,36 @@ DRIVER_Dispatch(
             return physdev->funcs->pStrokePath(physdev);
         case DCFUNC_WidenPath:
             return physdev->funcs->pWidenPath(physdev);
-
-
-        /* These are not implemented in wine */
-        case DCFUNC_AlphaBlend:
         case DCFUNC_AngleArc:
+            return physdev->funcs->pAngleArc(physdev,
+                                             _va_arg_n(argptr, INT, 0),
+                                             _va_arg_n(argptr, INT, 1),
+                                             _va_arg_n(argptr, DWORD, 2),
+                                             _va_arg_n(argptr, FLOAT, 3),
+                                             _va_arg_n(argptr, FLOAT, 4 ));
         case DCFUNC_ArcTo:
+            return physdev->funcs->pArcTo(physdev,
+                                          _va_arg_n(argptr, INT, 0),
+                                          _va_arg_n(argptr, INT, 1),
+                                          _va_arg_n(argptr, INT, 2),
+                                          _va_arg_n(argptr, INT, 3),
+                                          _va_arg_n(argptr, INT, 4),
+                                          _va_arg_n(argptr, INT, 5),
+                                          _va_arg_n(argptr, INT, 6),
+                                          _va_arg_n(argptr, INT, 7));
         case DCFUNC_GradientFill:
-        case DCFUNC_MaskBlt:
+            return physdev->funcs->pGradientFill(physdev,
+                                                 _va_arg_n(argptr, TRIVERTEX *, 0), 
+                                                 _va_arg_n(argptr, ULONG, 1),
+                                                 _va_arg_n(argptr, void *, 2),
+                                                 _va_arg_n(argptr, ULONG , 3),
+                                                 _va_arg_n(argptr, ULONG , 4));
         case DCFUNC_PathToRegion:
+            return (DWORD_PTR)DRIVER_PathToRegion(physdev);
+
+        /* These are not implemented in wine */
+        case DCFUNC_AlphaBlend:
+        case DCFUNC_MaskBlt:
         case DCFUNC_PlgBlt:
         case DCFUNC_TransparentBlt:
             UNIMPLEMENTED;
@@ -1062,6 +1135,17 @@ METADC_Dispatch(
         return FALSE;
     }
 
+    // See if this is other than a METADATA issue.
+    if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE)
+    {
+       WINEDC* pwdc = (WINEDC*)GdiGetLDC(hdc);
+       if (pwdc && pwdc->iType != LDC_EMFLDC)
+       {
+          /* Let the caller handle it */
+          return FALSE;
+       }
+    }
+
     physdev = GetPhysDev(hdc);
     if (physdev == NULL)
     {
@@ -1070,9 +1154,11 @@ METADC_Dispatch(
         return TRUE;
     }
 
+    i = eFunction;
     va_start(argptr, hdc);
     *pdwResult = DRIVER_Dispatch(physdev, eFunction, argptr);
     va_end(argptr);
+    i = 0;
 
     /* Return TRUE to indicate that we want to return from the parent  */
     return ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) ||
@@ -1113,7 +1199,7 @@ METADC_GetAndSetDCDWord(
 
         case GdiGetSetArcDirection:
             if (GDI_HANDLE_GET_TYPE(physdev->hdc) == GDILoObjType_LO_METADC16_TYPE)
-                pdwResult = 0;
+                *pdwResult = 0;
             else
                 *pdwResult = physdev->funcs->pSetArcDirection(physdev, dwIn);
             break;