1 2 #include <precomp.h> 3 #include "gdi_private.h" 4 #undef SetWorldTransform 5 6 #define NDEBUG 7 #include <debug.h> 8 9 WINEDC *get_nulldrv_dc( PHYSDEV dev ); 10 11 BOOL nulldrv_BeginPath( PHYSDEV dev ); 12 BOOL nulldrv_EndPath( PHYSDEV dev ); 13 BOOL nulldrv_AbortPath( PHYSDEV dev ); 14 BOOL nulldrv_CloseFigure( PHYSDEV dev ); 15 BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode ); 16 BOOL nulldrv_FillPath( PHYSDEV dev ); 17 BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev ); 18 BOOL nulldrv_StrokePath( PHYSDEV dev ); 19 BOOL nulldrv_FlattenPath( PHYSDEV dev ); 20 BOOL nulldrv_WidenPath( PHYSDEV dev ); 21 22 static INT i = 0; 23 24 static 25 INT_PTR 26 NULL_Unused() 27 { 28 DPRINT1("NULL_Unused %d\n",i); 29 // __debugbreak(); 30 return 0; 31 } 32 33 static INT NULL_SaveDC(PHYSDEV dev) { return 1; } 34 static BOOL NULL_RestoreDC(PHYSDEV dev, INT level) { return TRUE; } 35 static INT NULL_SetMapMode(PHYSDEV dev, INT iMode) { return 1; } 36 static HFONT NULL_SelectFont(PHYSDEV dev, HFONT hFont, UINT *aa_flags) { return NULL; } 37 static BOOL NULL_SetWindowExtEx(PHYSDEV dev, INT cx, INT cy, SIZE *size) { return TRUE; } 38 static BOOL NULL_SetViewportExtEx(PHYSDEV dev, INT cx, INT cy, SIZE *size) { return TRUE; } 39 static BOOL NULL_SetWindowOrgEx(PHYSDEV dev, INT x, INT y, POINT *pt) { return TRUE; } 40 static BOOL NULL_SetViewportOrgEx(PHYSDEV dev, INT x, INT y, POINT *pt) { return TRUE; } 41 static INT NULL_ExtSelectClipRgn(PHYSDEV dev, HRGN hrgn, INT iMode) { return 1; } 42 static INT NULL_IntersectClipRect(PHYSDEV dev, INT left, INT top, INT right, INT bottom) { return 1; } 43 static INT NULL_OffsetClipRgn(PHYSDEV dev, INT x, INT y) { return SIMPLEREGION; } 44 static INT NULL_ExcludeClipRect(PHYSDEV dev, INT left, INT top, INT right, INT bottom) { return 1; } 45 static BOOL NULL_ExtTextOutW(PHYSDEV dev, INT x, INT y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT cwc, const INT *lpDx) { return TRUE; } 46 static BOOL NULL_ModifyWorldTransform( PHYSDEV dev, const XFORM* xform, DWORD mode ) { return TRUE; } 47 static BOOL NULL_SetWorldTransform( PHYSDEV dev, const XFORM* xform ) { return TRUE; } 48 static BOOL NULL_PolyPolyline(PHYSDEV dev, const POINT *pt, const DWORD *lpt, DWORD cw) { return TRUE; } 49 50 static const struct gdi_dc_funcs DummyPhysDevFuncs = 51 { 52 (PVOID)NULL_Unused, //INT (*pAbortDoc)(PHYSDEV); 53 nulldrv_AbortPath, //BOOL (*pAbortPath)(PHYSDEV); 54 (PVOID)NULL_Unused, //BOOL (*pAlphaBlend)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,BLENDFUNCTION); 55 (PVOID)NULL_Unused, //BOOL (*pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT); 56 (PVOID)NULL_Unused, //BOOL (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); 57 (PVOID)NULL_Unused, //BOOL (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); 58 nulldrv_BeginPath, //BOOL (*pBeginPath)(PHYSDEV); 59 (PVOID)NULL_Unused, //DWORD (*pBlendImage)(PHYSDEV,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,BLENDFUNCTION); 60 (PVOID)NULL_Unused, //BOOL (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); 61 nulldrv_CloseFigure, //BOOL (*pCloseFigure)(PHYSDEV); 62 63 (PVOID)NULL_Unused, //BOOL (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*); 64 (PVOID)NULL_Unused, //BOOL (*pCreateDC)(PHYSDEV*,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*); 65 (PVOID)NULL_Unused, //BOOL (*pDeleteDC)(PHYSDEV); 66 (PVOID)NULL_Unused, //BOOL (*pDeleteObject)(PHYSDEV,HGDIOBJ); 67 (PVOID)NULL_Unused, //DWORD (*pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA); 68 (PVOID)NULL_Unused, //BOOL (*pEllipse)(PHYSDEV,INT,INT,INT,INT); 69 (PVOID)NULL_Unused, //INT (*pEndDoc)(PHYSDEV); 70 (PVOID)NULL_Unused, //INT (*pEndPage)(PHYSDEV); 71 nulldrv_EndPath, //BOOL (*pEndPath)(PHYSDEV); 72 (PVOID)NULL_Unused, //BOOL (*pEnumFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM); 73 74 (PVOID)NULL_Unused, //INT (*pEnumICMProfiles)(PHYSDEV,ICMENUMPROCW,LPARAM); 75 NULL_ExcludeClipRect, //INT (*pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT); 76 (PVOID)NULL_Unused, //INT (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD); 77 (PVOID)NULL_Unused, //INT (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID); 78 (PVOID)NULL_Unused, //BOOL (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT); 79 NULL_ExtSelectClipRgn, //INT (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT); 80 NULL_ExtTextOutW, //BOOL (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*); 81 nulldrv_FillPath, //BOOL (*pFillPath)(PHYSDEV); 82 (PVOID)NULL_Unused, //BOOL (*pFillRgn)(PHYSDEV,HRGN,HBRUSH); 83 nulldrv_FlattenPath, //BOOL (*pFlattenPath)(PHYSDEV); 84 85 (PVOID)NULL_Unused, //BOOL (*pFontIsLinked)(PHYSDEV); 86 (PVOID)NULL_Unused, //BOOL (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT); 87 (PVOID)NULL_Unused, //BOOL (*pGdiComment)(PHYSDEV,UINT,const BYTE*); 88 (PVOID)NULL_Unused, //UINT (*pGetBoundsRect)(PHYSDEV,RECT*,UINT); 89 (PVOID)NULL_Unused, //BOOL (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC); 90 (PVOID)NULL_Unused, //BOOL (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC); 91 (PVOID)NULL_Unused, //BOOL (*pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT); 92 (PVOID)NULL_Unused, //BOOL (*pGetCharWidthInfo)(PHYSDEV,void*); 93 (PVOID)NULL_Unused, //INT (*pGetDeviceCaps)(PHYSDEV,INT); 94 (PVOID)NULL_Unused, //BOOL (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID); 95 (PVOID)NULL_Unused, //DWORD (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD); 96 (PVOID)NULL_Unused, //BOOL (*pGetFontRealizationInfo)(PHYSDEV,void*); 97 (PVOID)NULL_Unused, //DWORD (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET); 98 (PVOID)NULL_Unused, //DWORD (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD); 99 (PVOID)NULL_Unused, //DWORD (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*); 100 (PVOID)NULL_Unused, //BOOL (*pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR); 101 (PVOID)NULL_Unused, //DWORD (*pGetImage)(PHYSDEV,BITMAPINFO*,struct gdi_image_bits*,struct bitblt_coords*); 102 (PVOID)NULL_Unused, //DWORD (*pGetKerningPairs)(PHYSDEV,DWORD,LPKERNINGPAIR); 103 (PVOID)NULL_Unused, //COLORREF (*pGetNearestColor)(PHYSDEV,COLORREF); 104 (PVOID)NULL_Unused, //UINT (*pGetOutlineTextMetrics)(PHYSDEV,UINT,LPOUTLINETEXTMETRICW); 105 (PVOID)NULL_Unused, //COLORREF (*pGetPixel)(PHYSDEV,INT,INT); 106 (PVOID)NULL_Unused, //UINT (*pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY); 107 (PVOID)NULL_Unused, //UINT (*pGetTextCharsetInfo)(PHYSDEV,LPFONTSIGNATURE,DWORD); 108 (PVOID)NULL_Unused, //BOOL (*pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,LPINT); 109 (PVOID)NULL_Unused, //BOOL (*pGetTextExtentExPointI)(PHYSDEV,const WORD*,INT,LPINT); 110 (PVOID)NULL_Unused, //INT (*pGetTextFace)(PHYSDEV,INT,LPWSTR); 111 (PVOID)NULL_Unused, //BOOL (*pGetTextMetrics)(PHYSDEV,TEXTMETRICW*); 112 (PVOID)NULL_Unused, //BOOL (*pGradientFill)(PHYSDEV,TRIVERTEX*,ULONG,void*,ULONG,ULONG); 113 NULL_IntersectClipRect, //INT (*pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT); 114 (PVOID)NULL_Unused, //BOOL (*pInvertRgn)(PHYSDEV,HRGN); 115 (PVOID)NULL_Unused, //BOOL (*pLineTo)(PHYSDEV,INT,INT); 116 NULL_ModifyWorldTransform, //BOOL (*pModifyWorldTransform)(PHYSDEV,const XFORM*,DWORD); 117 (PVOID)NULL_Unused, //BOOL (*pMoveTo)(PHYSDEV,INT,INT); 118 NULL_OffsetClipRgn, //INT (*pOffsetClipRgn)(PHYSDEV,INT,INT); 119 (PVOID)NULL_Unused, //BOOL (*pOffsetViewportOrgEx)(PHYSDEV,INT,INT,POINT*); 120 (PVOID)NULL_Unused, //BOOL (*pOffsetWindowOrgEx)(PHYSDEV,INT,INT,POINT*); 121 (PVOID)NULL_Unused, //BOOL (*pPaintRgn)(PHYSDEV,HRGN); 122 (PVOID)NULL_Unused, //BOOL (*pPatBlt)(PHYSDEV,struct bitblt_coords*,DWORD); 123 (PVOID)NULL_Unused, //BOOL (*pPie)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); 124 (PVOID)NULL_Unused, //BOOL (*pPolyBezier)(PHYSDEV,const POINT*,DWORD); 125 (PVOID)NULL_Unused, //BOOL (*pPolyBezierTo)(PHYSDEV,const POINT*,DWORD); 126 (PVOID)NULL_Unused, //BOOL (*pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD); 127 (PVOID)NULL_Unused, //BOOL (*pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT); 128 NULL_PolyPolyline, //BOOL (*pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD); 129 (PVOID)NULL_Unused, //BOOL (*pPolygon)(PHYSDEV,const POINT*,INT); 130 (PVOID)NULL_Unused, //BOOL (*pPolyline)(PHYSDEV,const POINT*,INT); 131 (PVOID)NULL_Unused, //BOOL (*pPolylineTo)(PHYSDEV,const POINT*,INT); 132 (PVOID)NULL_Unused, //DWORD (*pPutImage)(PHYSDEV,HRGN,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,DWORD); 133 (PVOID)NULL_Unused, //UINT (*pRealizeDefaultPalette)(PHYSDEV); 134 (PVOID)NULL_Unused, //UINT (*pRealizePalette)(PHYSDEV,HPALETTE,BOOL); 135 (PVOID)NULL_Unused, //BOOL (*pRectangle)(PHYSDEV,INT,INT,INT,INT); 136 (PVOID)NULL_Unused, //HDC (*pResetDC)(PHYSDEV,const DEVMODEW*); 137 NULL_RestoreDC, //BOOL (*pRestoreDC)(PHYSDEV,INT); 138 (PVOID)NULL_Unused, //BOOL (*pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT); 139 NULL_SaveDC, //INT (*pSaveDC)(PHYSDEV); 140 (PVOID)NULL_Unused, //BOOL (*pScaleViewportExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*); 141 (PVOID)NULL_Unused, //BOOL (*pScaleWindowExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*); 142 (PVOID)NULL_Unused, //HBITMAP (*pSelectBitmap)(PHYSDEV,HBITMAP); 143 (PVOID)NULL_Unused, //HBRUSH (*pSelectBrush)(PHYSDEV,HBRUSH,const struct brush_pattern*); 144 nulldrv_SelectClipPath, //BOOL (*pSelectClipPath)(PHYSDEV,INT); 145 NULL_SelectFont, //HFONT (*pSelectFont)(PHYSDEV,HFONT,UINT*); 146 (PVOID)NULL_Unused, //HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL); 147 (PVOID)NULL_Unused, //HPEN (*pSelectPen)(PHYSDEV,HPEN,const struct brush_pattern*); 148 (PVOID)NULL_Unused, //INT (*pSetArcDirection)(PHYSDEV,INT); 149 (PVOID)NULL_Unused, //COLORREF (*pSetBkColor)(PHYSDEV,COLORREF); 150 (PVOID)NULL_Unused, //INT (*pSetBkMode)(PHYSDEV,INT); 151 (PVOID)NULL_Unused, //UINT (*pSetBoundsRect)(PHYSDEV,RECT*,UINT); 152 (PVOID)NULL_Unused, //COLORREF (*pSetDCBrushColor)(PHYSDEV, COLORREF); 153 (PVOID)NULL_Unused, //COLORREF (*pSetDCPenColor)(PHYSDEV, COLORREF); 154 (PVOID)NULL_Unused, //INT (*pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,BITMAPINFO*,UINT); 155 (PVOID)NULL_Unused, //VOID (*pSetDeviceClipping)(PHYSDEV,HRGN); 156 (PVOID)NULL_Unused, //BOOL (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID); 157 (PVOID)NULL_Unused, //DWORD (*pSetLayout)(PHYSDEV,DWORD); 158 NULL_SetMapMode, //INT (*pSetMapMode)(PHYSDEV,INT); 159 (PVOID)NULL_Unused, //DWORD (*pSetMapperFlags)(PHYSDEV,DWORD); 160 (PVOID)NULL_Unused, //COLORREF (*pSetPixel)(PHYSDEV,INT,INT,COLORREF); 161 (PVOID)NULL_Unused, //INT (*pSetPolyFillMode)(PHYSDEV,INT); 162 (PVOID)NULL_Unused, //INT (*pSetROP2)(PHYSDEV,INT); 163 (PVOID)NULL_Unused, //INT (*pSetRelAbs)(PHYSDEV,INT); 164 (PVOID)NULL_Unused, //INT (*pSetStretchBltMode)(PHYSDEV,INT); 165 (PVOID)NULL_Unused, //UINT (*pSetTextAlign)(PHYSDEV,UINT); 166 (PVOID)NULL_Unused, //INT (*pSetTextCharacterExtra)(PHYSDEV,INT); 167 (PVOID)NULL_Unused, //COLORREF (*pSetTextColor)(PHYSDEV,COLORREF); 168 (PVOID)NULL_Unused, //BOOL (*pSetTextJustification)(PHYSDEV,INT,INT); 169 NULL_SetViewportExtEx, //BOOL (*pSetViewportExtEx)(PHYSDEV,INT,INT,SIZE*); 170 NULL_SetViewportOrgEx, //BOOL (*pSetViewportOrgEx)(PHYSDEV,INT,INT,POINT*); 171 NULL_SetWindowExtEx, //BOOL (*pSetWindowExtEx)(PHYSDEV,INT,INT,SIZE*); 172 NULL_SetWindowOrgEx, //BOOL (*pSetWindowOrgEx)(PHYSDEV,INT,INT,POINT*); 173 NULL_SetWorldTransform, //BOOL (*pSetWorldTransform)(PHYSDEV,const XFORM*); 174 (PVOID)NULL_Unused, //INT (*pStartDoc)(PHYSDEV,const DOCINFOW*); 175 (PVOID)NULL_Unused, //INT (*pStartPage)(PHYSDEV); 176 (PVOID)NULL_Unused, //BOOL (*pStretchBlt)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,DWORD); 177 (PVOID)NULL_Unused, //INT (*pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void*,BITMAPINFO*,UINT,DWORD); 178 nulldrv_StrokeAndFillPath, //BOOL (*pStrokeAndFillPath)(PHYSDEV); 179 nulldrv_StrokePath, //BOOL (*pStrokePath)(PHYSDEV); 180 (PVOID)NULL_Unused, //BOOL (*pUnrealizePalette)(HPALETTE); 181 nulldrv_WidenPath, //BOOL (*pWidenPath)(PHYSDEV); 182 (PVOID)NULL_Unused, //struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT); 183 0 // UINT priority; 184 }; 185 186 WINEDC *get_nulldrv_dc( PHYSDEV dev ) 187 { 188 return CONTAINING_RECORD( dev, WINEDC, NullPhysDev ); 189 } 190 191 WINEDC* get_physdev_dc( PHYSDEV dev ) 192 { 193 while (dev->funcs != &DummyPhysDevFuncs) 194 dev = dev->next; 195 return get_nulldrv_dc( dev ); 196 } 197 198 static 199 GDILOOBJTYPE 200 ConvertObjectType( 201 WORD wType) 202 { 203 /* Get the GDI object type */ 204 switch (wType) 205 { 206 case OBJ_PEN: return GDILoObjType_LO_PEN_TYPE; 207 case OBJ_BRUSH: return GDILoObjType_LO_BRUSH_TYPE; 208 case OBJ_DC: return GDILoObjType_LO_DC_TYPE; 209 case OBJ_METADC: return GDILoObjType_LO_METADC16_TYPE; 210 case OBJ_PAL: return GDILoObjType_LO_PALETTE_TYPE; 211 case OBJ_FONT: return GDILoObjType_LO_FONT_TYPE; 212 case OBJ_BITMAP: return GDILoObjType_LO_BITMAP_TYPE; 213 case OBJ_REGION: return GDILoObjType_LO_REGION_TYPE; 214 case OBJ_METAFILE: return GDILoObjType_LO_METAFILE16_TYPE; 215 case OBJ_MEMDC: return GDILoObjType_LO_DC_TYPE; 216 case OBJ_EXTPEN: return GDILoObjType_LO_EXTPEN_TYPE; 217 case OBJ_ENHMETADC: return GDILoObjType_LO_ALTDC_TYPE; 218 case OBJ_ENHMETAFILE: return GDILoObjType_LO_METAFILE_TYPE; 219 case OBJ_COLORSPACE: return GDILoObjType_LO_ICMLCS_TYPE; 220 default: return 0; 221 } 222 } 223 224 HGDIOBJ 225 alloc_gdi_handle( 226 PVOID pvObject, 227 WORD wType, 228 const struct gdi_obj_funcs *funcs) 229 { 230 GDILOOBJTYPE eObjType; 231 232 /* Get the GDI object type */ 233 eObjType = ConvertObjectType(wType); 234 if ((eObjType != GDILoObjType_LO_METAFILE_TYPE) && 235 (eObjType != GDILoObjType_LO_METAFILE16_TYPE) && 236 (eObjType != GDILoObjType_LO_METADC16_TYPE)) 237 { 238 /* This is not supported! */ 239 ASSERT(FALSE); 240 return NULL; 241 } 242 243 /* Insert the client object */ 244 return GdiCreateClientObj(pvObject, eObjType); 245 } 246 247 PVOID 248 free_gdi_handle(HGDIOBJ hobj) 249 { 250 /* Should be a client object */ 251 return GdiDeleteClientObj(hobj); 252 } 253 254 PVOID 255 GDI_GetObjPtr( 256 HGDIOBJ hobj, 257 WORD wType) 258 { 259 GDILOOBJTYPE eObjType; 260 261 /* Check if the object type matches */ 262 eObjType = ConvertObjectType(wType); 263 if ((eObjType == 0) || (GDI_HANDLE_GET_TYPE(hobj) != eObjType)) 264 { 265 return NULL; 266 } 267 268 /* Check if we have an ALTDC */ 269 if (eObjType == GDILoObjType_LO_ALTDC_TYPE) 270 { 271 /* Object is stored as LDC */ 272 return GdiGetLDC(hobj); 273 } 274 275 /* Check for client objects */ 276 if ((eObjType == GDILoObjType_LO_METAFILE_TYPE) || 277 (eObjType == GDILoObjType_LO_METAFILE16_TYPE) || 278 (eObjType == GDILoObjType_LO_METADC16_TYPE)) 279 { 280 return GdiGetClientObjLink(hobj); 281 } 282 283 /* This should never happen! */ 284 ASSERT(FALSE); 285 return NULL; 286 } 287 288 VOID 289 GDI_ReleaseObj(HGDIOBJ hobj) 290 { 291 /* We don't do any reference-counting */ 292 } 293 294 WINEDC* 295 alloc_dc_ptr(WORD magic) 296 { 297 WINEDC* pWineDc; 298 299 /* Allocate the Wine DC */ 300 pWineDc = HeapAlloc(GetProcessHeap(), 0, sizeof(*pWineDc)); 301 if (pWineDc == NULL) 302 { 303 return NULL; 304 } 305 306 ZeroMemory(pWineDc, sizeof(*pWineDc)); 307 pWineDc->refcount = 1; 308 pWineDc->hFont = GetStockObject(SYSTEM_FONT); 309 pWineDc->hBrush = GetStockObject(WHITE_BRUSH); 310 pWineDc->hPen = GetStockObject(BLACK_PEN); 311 pWineDc->hPalette = GetStockObject(DEFAULT_PALETTE); 312 313 if (magic == OBJ_ENHMETADC) 314 { 315 /* We create a metafile DC, but we ignore the reference DC, this is 316 handled by the wine code */ 317 pWineDc->hdc = NtGdiCreateMetafileDC(NULL); 318 if (pWineDc->hdc == NULL) 319 { 320 HeapFree(GetProcessHeap(), 0, pWineDc); 321 return NULL; 322 } 323 324 pWineDc->iType = LDC_EMFLDC; 325 326 /* Set the Wine DC as LDC */ 327 GdiSetLDC(pWineDc->hdc, pWineDc); 328 } 329 else if (magic == OBJ_METADC) 330 { 331 pWineDc->hdc = GdiCreateClientObj(pWineDc, GDILoObjType_LO_METADC16_TYPE); 332 if (pWineDc->hdc == NULL) 333 { 334 HeapFree(GetProcessHeap(), 0, pWineDc); 335 return NULL; 336 } 337 } 338 else 339 { 340 // nothing else supported! 341 ASSERT(FALSE); 342 } 343 344 pWineDc->physDev = &pWineDc->NullPhysDev; 345 pWineDc->NullPhysDev.funcs = &DummyPhysDevFuncs; 346 pWineDc->NullPhysDev.next = NULL; 347 348 pWineDc->NullPhysDev.hdc = pWineDc->hdc; 349 return pWineDc; 350 } 351 352 VOID 353 free_dc_ptr(WINEDC* pWineDc) 354 { 355 /* Invoke the DeleteDC callback to clean up the DC */ 356 pWineDc->physDev->funcs->pDeleteDC(pWineDc->physDev); 357 358 /* FIXME */ 359 if (GDI_HANDLE_GET_TYPE(pWineDc->hdc) == GDILoObjType_LO_ALTDC_TYPE) 360 { 361 /* Get rid of the LDC */ 362 ASSERT((WINEDC*)GdiGetLDC(pWineDc->hdc) == pWineDc); 363 GdiSetLDC(pWineDc->hdc, NULL); 364 365 /* Free the DC */ 366 NtGdiDeleteObjectApp(pWineDc->hdc); 367 } 368 else if (GDI_HANDLE_GET_TYPE(pWineDc->hdc) == GDILoObjType_LO_METADC16_TYPE) 369 { 370 GdiDeleteClientObj(pWineDc->hdc); 371 } 372 373 /* Free the Wine DC */ 374 HeapFree(GetProcessHeap(), 0, pWineDc); 375 } 376 377 WINEDC* 378 get_dc_ptr(HDC hdc) 379 { 380 /* Check for EMF DC */ 381 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE) 382 { 383 /* The Wine DC is stored as the LDC */ 384 return (WINEDC*)GdiGetLDC(hdc); 385 } 386 387 /* Check for METADC16 */ 388 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 389 { 390 return GdiGetClientObjLink(hdc); 391 } 392 393 return NULL; 394 } 395 396 VOID 397 release_dc_ptr(WINEDC* dc) 398 { 399 /* We don't do any reference-counting */ 400 } 401 402 void 403 push_dc_driver_ros( 404 PHYSDEV *dev, 405 PHYSDEV physdev, 406 const struct gdi_dc_funcs *funcs) 407 { 408 while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next; 409 physdev->funcs = funcs; 410 physdev->next = *dev; 411 physdev->hdc = CONTAINING_RECORD(dev, WINEDC, physDev)->hdc; 412 *dev = physdev; 413 } 414 415 VOID 416 GDI_hdc_using_object( 417 HGDIOBJ hobj, 418 HDC hdc) 419 { 420 /* Record that we have an object in use by a METADC. We simply link the 421 object to the HDC that we use. Wine API does not give us a way to 422 respond to failure, so we silently ignore it */ 423 if (!GdiCreateClientObjLink(hobj, hdc)) 424 { 425 /* Ignore failure, and return */ 426 DPRINT1("Failed to create link for selected METADC object.\n"); 427 return; 428 } 429 } 430 431 VOID 432 GDI_hdc_not_using_object( 433 HGDIOBJ hobj, 434 HDC hdc) 435 { 436 HDC hdcLink; 437 438 /* Remove the HDC link for the object */ 439 hdcLink = GdiRemoveClientObjLink(hobj); 440 ASSERT(hdcLink == hdc); 441 } 442 443 /*********************************************************************** 444 * bitmap_info_size 445 * 446 * Return the size of the bitmap info structure including color table. 447 */ 448 int 449 bitmap_info_size( 450 const BITMAPINFO * info, 451 WORD coloruse) 452 { 453 unsigned int colors, size, masks = 0; 454 455 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) 456 { 457 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info; 458 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0; 459 return sizeof(BITMAPCOREHEADER) + colors * 460 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD)); 461 } 462 else /* assume BITMAPINFOHEADER */ 463 { 464 if (info->bmiHeader.biClrUsed) colors = min( info->bmiHeader.biClrUsed, 256 ); 465 else colors = info->bmiHeader.biBitCount > 8 ? 0 : 1 << info->bmiHeader.biBitCount; 466 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3; 467 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) ); 468 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD)); 469 } 470 } 471 472 BOOL 473 get_brush_bitmap_info( 474 HBRUSH hbr, 475 PBITMAPINFO pbmi, 476 PVOID *ppvBits, 477 PUINT puUsage) 478 { 479 HBITMAP hbmp; 480 HDC hdc; 481 482 /* Call win32k to get the bitmap handle and color usage */ 483 hbmp = NtGdiGetObjectBitmapHandle(hbr, puUsage); 484 if (hbmp == NULL) 485 return FALSE; 486 487 hdc = GetDC(NULL); 488 if (hdc == NULL) 489 return FALSE; 490 491 /* Initialize the BITMAPINFO */ 492 ZeroMemory(pbmi, sizeof(*pbmi)); 493 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 494 495 /* Retrieve information about the bitmap */ 496 if (!GetDIBits(hdc, hbmp, 0, 0, NULL, pbmi, *puUsage)) 497 return FALSE; 498 499 /* Now allocate a buffer for the bits */ 500 *ppvBits = HeapAlloc(GetProcessHeap(), 0, pbmi->bmiHeader.biSizeImage); 501 if (*ppvBits == NULL) 502 return FALSE; 503 504 /* Retrieve the bitmap bits */ 505 if (!GetDIBits(hdc, hbmp, 0, pbmi->bmiHeader.biHeight, *ppvBits, pbmi, *puUsage)) 506 { 507 HeapFree(GetProcessHeap(), 0, *ppvBits); 508 *ppvBits = NULL; 509 return FALSE; 510 } 511 512 /* GetDIBits doesn't set biClrUsed, but wine code needs it, so we set it */ 513 if (pbmi->bmiHeader.biBitCount <= 8) 514 { 515 pbmi->bmiHeader.biClrUsed = 1 << pbmi->bmiHeader.biBitCount; 516 } 517 518 return TRUE; 519 } 520 521 BOOL 522 WINAPI 523 SetVirtualResolution( 524 HDC hdc, 525 DWORD cxVirtualDevicePixel, 526 DWORD cyVirtualDevicePixel, 527 DWORD cxVirtualDeviceMm, 528 DWORD cyVirtualDeviceMm) 529 { 530 return NtGdiSetVirtualResolution(hdc, 531 cxVirtualDevicePixel, 532 cyVirtualDevicePixel, 533 cxVirtualDeviceMm, 534 cyVirtualDeviceMm); 535 } 536 537 BOOL 538 WINAPI 539 DeleteColorSpace( 540 HCOLORSPACE hcs) 541 { 542 return NtGdiDeleteColorSpace(hcs); 543 } 544 #if 0 545 BOOL 546 WINAPI 547 SetWorldTransformForMetafile( 548 _In_ HDC hdc, 549 _Out_ CONST XFORM *pxform) 550 { 551 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 552 { 553 #if 0 554 //HANDLE_METADC(BOOL, ModifyWorldTransform, FALSE, hdc, pxform, MWT_SET); 555 /* Get the physdev */ 556 physdev = GetPhysDev(hdc); 557 if (physdev == NULL) 558 { 559 DPRINT1("Failed to get physdev for meta DC %p\n", hdc); 560 return FALSE; 561 } 562 563 physdev->funcs->pSetWorldTransform(physdev, pxform); 564 #endif 565 // HACK!!! 566 return TRUE; 567 } 568 569 return SetWorldTransform(hdc, pxform); 570 } 571 #endif 572 void 573 __cdecl 574 _assert ( 575 const char *exp, 576 const char *file, 577 unsigned line) 578 { 579 DbgRaiseAssertionFailure(); 580 } 581 582 /******************************************************************************/ 583 584 static 585 VOID 586 InitBitBltCoords( 587 struct bitblt_coords *coords, 588 HDC hdc, 589 int x, 590 int y, 591 int cx, 592 int cy) 593 { 594 coords->log_x = x; 595 coords->log_y = y; 596 coords->log_width = cx; 597 coords->log_height = cy; 598 coords->layout = GetLayout(hdc); 599 } 600 601 static 602 PHYSDEV 603 GetPhysDev( 604 HDC hdc) 605 { 606 WINEDC *pWineDc; 607 608 pWineDc = get_dc_ptr(hdc); 609 if (pWineDc == NULL) 610 { 611 return NULL; 612 } 613 614 return pWineDc->physDev; 615 } 616 617 static 618 BOOL 619 DRIVER_PatBlt( 620 _In_ PHYSDEV physdev, 621 _In_ HDC hdc, 622 _In_ INT xLeft, 623 _In_ INT yTop, 624 _In_ INT cx, 625 _In_ INT cy, 626 _In_ DWORD dwRop) 627 { 628 struct bitblt_coords coords; 629 630 InitBitBltCoords(&coords, hdc, xLeft, yTop, cx, cy); 631 632 return physdev->funcs->pPatBlt(physdev, &coords, dwRop); 633 } 634 635 static 636 BOOL 637 DRIVER_StretchBlt( 638 _In_ PHYSDEV physdev, 639 _In_ HDC hdcDst, 640 _In_ INT xDst, 641 _In_ INT yDst, 642 _In_ INT cxDst, 643 _In_ INT cyDst, 644 _In_opt_ HDC hdcSrc, 645 _In_ INT xSrc, 646 _In_ INT ySrc, 647 _In_ INT cxSrc, 648 _In_ INT cySrc, 649 _In_ DWORD dwRop) 650 { 651 struct bitblt_coords coordsDst, coordsSrc; 652 struct gdi_physdev physdevSrc = {0}; 653 654 /* Source cannot be a metafile */ 655 if (GDI_HANDLE_GET_TYPE(hdcSrc) != GDILoObjType_LO_DC_TYPE) 656 return FALSE; 657 658 /* Source physdev uses only hdc and func */ 659 physdevSrc.hdc = hdcSrc; 660 661 InitBitBltCoords(&coordsDst, hdcDst, xDst, yDst, cxDst, cyDst); 662 InitBitBltCoords(&coordsSrc, hdcSrc, xSrc, ySrc, cxSrc, cySrc); 663 664 return physdev->funcs->pStretchBlt(physdev, &coordsDst, &physdevSrc, &coordsSrc, dwRop); 665 } 666 667 static 668 BOOL 669 DRIVER_RestoreDC(PHYSDEV physdev, INT level) 670 { 671 WINEDC *pWineDc = get_dc_ptr(physdev->hdc); 672 673 if (GDI_HANDLE_GET_TYPE(physdev->hdc) == GDILoObjType_LO_ALTDC_TYPE) 674 { 675 /* The Restore DC function needs the save level to be set correctly. 676 Note that wine's level is 0 based, while our's is (like win) 1 based. */ 677 pWineDc->saveLevel = GetDCDWord(physdev->hdc, GdiGetEMFRestorDc, 0) - 1; 678 679 /* Fail if the level is not valid */ 680 if ((abs(level) > pWineDc->saveLevel) || (level == 0)) 681 return FALSE; 682 } 683 684 return physdev->funcs->pRestoreDC(physdev,level); 685 } 686 687 static 688 HFONT 689 DRIVER_SelectFont(PHYSDEV physdev, HFONT hFont, UINT *aa_flags) 690 { 691 WINEDC *pWineDc = get_dc_ptr(physdev->hdc); 692 HFONT hOldFont; 693 694 if (!physdev->funcs->pSelectFont(physdev, hFont, aa_flags)) 695 return 0; 696 697 hOldFont = pWineDc->hFont; 698 pWineDc->hFont = hFont; 699 return hOldFont; 700 } 701 702 static 703 HPEN 704 DRIVER_SelectPen(PHYSDEV physdev, HPEN hpen, const struct brush_pattern *pattern) 705 { 706 WINEDC *pWineDc = get_dc_ptr(physdev->hdc); 707 HPEN hOldPen; 708 709 if (!physdev->funcs->pSelectPen(physdev, hpen, pattern)) 710 return 0; 711 712 hOldPen = pWineDc->hPen; 713 pWineDc->hPen = hpen; 714 return hOldPen; 715 } 716 717 static 718 HBRUSH 719 DRIVER_SelectBrush(PHYSDEV physdev, HBRUSH hbrush, const struct brush_pattern *pattern) 720 { 721 WINEDC *pWineDc = get_dc_ptr(physdev->hdc); 722 HBRUSH hOldBrush; 723 724 if (!physdev->funcs->pSelectBrush(physdev, hbrush, pattern)) 725 return 0; 726 727 hOldBrush = pWineDc->hBrush; 728 pWineDc->hBrush = hbrush; 729 return hOldBrush; 730 } 731 732 static 733 HRGN 734 DRIVER_PathToRegion(PHYSDEV physdev) 735 { 736 DPRINT1("DRIVER_PathToRegion\n"); 737 return (HRGN)(ULONG_PTR)physdev->funcs->pAbortPath( physdev ); 738 } 739 740 741 static 742 DWORD_PTR 743 DRIVER_Dispatch( 744 _In_ PHYSDEV physdev, 745 _In_ DCFUNC eFunction, 746 _In_ va_list argptr) 747 { 748 UINT aa_flags = 0; 749 750 /* Note that this is a hack that relies on some assumptions regarding the 751 Windows ABI. It relies on the fact that all vararg functions put their 752 parameters on the stack in the correct order. Additionally it relies 753 on the fact that none of the functions we handle here, pass any 64 754 bit arguments on a 32 bit architecture. */ 755 #define _va_arg_n(p,t,i) (*(t*)((intptr_t*)(p) + i)) 756 757 switch (eFunction) 758 { 759 case DCFUNC_AbortPath: 760 return physdev->funcs->pAbortPath(physdev); 761 case DCFUNC_Arc: 762 return physdev->funcs->pArc(physdev, 763 _va_arg_n(argptr, INT, 0), // left 764 _va_arg_n(argptr, INT, 1), // top 765 _va_arg_n(argptr, INT, 2), // right 766 _va_arg_n(argptr, INT, 3), // bottom 767 _va_arg_n(argptr, INT, 4), // xstart 768 _va_arg_n(argptr, INT, 5), // ystart 769 _va_arg_n(argptr, INT, 6), // xend 770 _va_arg_n(argptr, INT, 7)); // yend 771 case DCFUNC_BeginPath: 772 return physdev->funcs->pBeginPath(physdev); 773 case DCFUNC_Chord: 774 return physdev->funcs->pChord(physdev, 775 _va_arg_n(argptr, INT, 0), 776 _va_arg_n(argptr, INT, 1), 777 _va_arg_n(argptr, INT, 2), 778 _va_arg_n(argptr, INT, 3), 779 _va_arg_n(argptr, INT, 4), 780 _va_arg_n(argptr, INT, 5), 781 _va_arg_n(argptr, INT, 6), 782 _va_arg_n(argptr, INT, 7)); 783 case DCFUNC_CloseFigure: 784 return physdev->funcs->pCloseFigure(physdev); 785 case DCFUNC_Ellipse: 786 return physdev->funcs->pEllipse(physdev, 787 _va_arg_n(argptr, INT, 0), 788 _va_arg_n(argptr, INT, 1), 789 _va_arg_n(argptr, INT, 2), 790 _va_arg_n(argptr, INT, 3)); 791 case DCFUNC_EndPath: 792 return physdev->funcs->pEndPath(physdev); 793 case DCFUNC_ExcludeClipRect: 794 return physdev->funcs->pExcludeClipRect(physdev, 795 _va_arg_n(argptr, INT, 0), 796 _va_arg_n(argptr, INT, 1), 797 _va_arg_n(argptr, INT, 2), 798 _va_arg_n(argptr, INT, 3)); 799 case DCFUNC_ExtEscape: 800 ASSERT(physdev->funcs->pExtEscape != NULL); 801 return physdev->funcs->pExtEscape(physdev, 802 _va_arg_n(argptr, INT, 0), 803 _va_arg_n(argptr, INT, 1), 804 _va_arg_n(argptr, LPCVOID, 2), 805 _va_arg_n(argptr, INT, 3), 806 _va_arg_n(argptr, LPVOID, 4)); 807 case DCFUNC_ExtFloodFill: 808 return physdev->funcs->pExtFloodFill(physdev, 809 _va_arg_n(argptr, INT, 0), 810 _va_arg_n(argptr, INT, 1), 811 _va_arg_n(argptr, COLORREF, 2), 812 _va_arg_n(argptr, UINT, 3)); 813 case DCFUNC_ExtSelectClipRgn: 814 return physdev->funcs->pExtSelectClipRgn(physdev, 815 _va_arg_n(argptr, HRGN, 0), // hrgn 816 _va_arg_n(argptr, INT, 1)); // iMode 817 case DCFUNC_ExtTextOut: 818 return physdev->funcs->pExtTextOut(physdev, 819 _va_arg_n(argptr, INT, 0),// x 820 _va_arg_n(argptr, INT, 1),// y 821 _va_arg_n(argptr, UINT, 2),// fuOptions 822 _va_arg_n(argptr, const RECT *, 3),// lprc, 823 _va_arg_n(argptr, LPCWSTR, 4),// lpString, 824 _va_arg_n(argptr, UINT, 5),// cchString, 825 _va_arg_n(argptr, const INT *, 6));// lpDx); 826 case DCFUNC_FillPath: 827 return physdev->funcs->pFillPath(physdev); 828 case DCFUNC_FillRgn: 829 return physdev->funcs->pFillRgn(physdev, 830 _va_arg_n(argptr, HRGN, 0), 831 _va_arg_n(argptr, HBRUSH, 1)); 832 case DCFUNC_FlattenPath: 833 return physdev->funcs->pFlattenPath(physdev); 834 case DCFUNC_FrameRgn: 835 return physdev->funcs->pFrameRgn(physdev, 836 _va_arg_n(argptr, HRGN, 0), 837 _va_arg_n(argptr, HBRUSH, 1), 838 _va_arg_n(argptr, INT, 2), 839 _va_arg_n(argptr, INT, 3)); 840 case DCFUNC_GetDeviceCaps: 841 return physdev->funcs->pGetDeviceCaps(physdev, va_arg(argptr, INT)); 842 case DCFUNC_GdiComment: 843 return physdev->funcs->pGdiComment(physdev, 844 _va_arg_n(argptr, UINT, 0), 845 _va_arg_n(argptr, const BYTE*, 1)); 846 case DCFUNC_IntersectClipRect: 847 return physdev->funcs->pIntersectClipRect(physdev, 848 _va_arg_n(argptr, INT, 0), 849 _va_arg_n(argptr, INT, 1), 850 _va_arg_n(argptr, INT, 2), 851 _va_arg_n(argptr, INT, 3)); 852 case DCFUNC_InvertRgn: 853 return physdev->funcs->pInvertRgn(physdev, 854 va_arg(argptr, HRGN)); 855 case DCFUNC_LineTo: 856 return physdev->funcs->pLineTo(physdev, 857 _va_arg_n(argptr, INT, 0), 858 _va_arg_n(argptr, INT, 1)); 859 case DCFUNC_ModifyWorldTransform: 860 return physdev->funcs->pModifyWorldTransform(physdev, 861 _va_arg_n(argptr, const XFORM*, 0), 862 _va_arg_n(argptr, DWORD, 1)); 863 case DCFUNC_MoveTo: 864 return physdev->funcs->pMoveTo(physdev, 865 _va_arg_n(argptr, INT, 0), 866 _va_arg_n(argptr, INT, 1)); 867 case DCFUNC_OffsetClipRgn: 868 return physdev->funcs->pOffsetClipRgn(physdev, 869 _va_arg_n(argptr, INT, 0), // hrgn 870 _va_arg_n(argptr, INT, 1)); // iMode 871 case DCFUNC_OffsetViewportOrgEx: 872 return physdev->funcs->pOffsetViewportOrgEx(physdev, 873 _va_arg_n(argptr, INT, 0), // X 874 _va_arg_n(argptr, INT, 1), // Y 875 _va_arg_n(argptr, LPPOINT, 2)); // lpPoint 876 case DCFUNC_OffsetWindowOrgEx: 877 return physdev->funcs->pOffsetWindowOrgEx(physdev, 878 _va_arg_n(argptr, INT, 0), // X 879 _va_arg_n(argptr, INT, 1), // Y 880 _va_arg_n(argptr, LPPOINT, 2)); // lpPoint 881 case DCFUNC_PatBlt: 882 return DRIVER_PatBlt(physdev, 883 physdev->hdc, 884 _va_arg_n(argptr, INT, 0), 885 _va_arg_n(argptr, INT, 1), 886 _va_arg_n(argptr, INT, 2), 887 _va_arg_n(argptr, INT, 3), 888 _va_arg_n(argptr, DWORD, 4)); 889 case DCFUNC_Pie: 890 return physdev->funcs->pPie(physdev, 891 _va_arg_n(argptr, INT, 0), 892 _va_arg_n(argptr, INT, 1), 893 _va_arg_n(argptr, INT, 2), 894 _va_arg_n(argptr, INT, 3), 895 _va_arg_n(argptr, INT, 4), 896 _va_arg_n(argptr, INT, 5), 897 _va_arg_n(argptr, INT, 6), 898 _va_arg_n(argptr, INT, 7)); 899 case DCFUNC_PolyBezier: 900 return physdev->funcs->pPolyBezier(physdev, 901 _va_arg_n(argptr, const POINT*, 0), 902 _va_arg_n(argptr, DWORD, 1)); 903 case DCFUNC_PolyBezierTo: 904 return physdev->funcs->pPolyBezierTo(physdev, 905 _va_arg_n(argptr, const POINT*, 0), 906 _va_arg_n(argptr, DWORD, 1)); 907 case DCFUNC_PolyDraw: 908 return physdev->funcs->pPolyDraw(physdev, 909 _va_arg_n(argptr, const POINT*, 0), 910 _va_arg_n(argptr, const BYTE*, 1), 911 _va_arg_n(argptr, DWORD, 2)); 912 case DCFUNC_Polygon: 913 return physdev->funcs->pPolygon(physdev, 914 _va_arg_n(argptr, const POINT*, 0), 915 _va_arg_n(argptr, INT, 1)); 916 case DCFUNC_Polyline: 917 return physdev->funcs->pPolyline(physdev, 918 _va_arg_n(argptr, const POINT*, 0), 919 _va_arg_n(argptr, INT, 1)); 920 case DCFUNC_PolylineTo: 921 return physdev->funcs->pPolylineTo(physdev, 922 _va_arg_n(argptr, const POINT*, 0), 923 _va_arg_n(argptr, INT, 1)); 924 case DCFUNC_PolyPolygon: 925 return physdev->funcs->pPolyPolygon(physdev, 926 _va_arg_n(argptr, const POINT*, 0), 927 _va_arg_n(argptr, const INT*, 1), 928 _va_arg_n(argptr, DWORD, 2)); 929 case DCFUNC_PolyPolyline: 930 return physdev->funcs->pPolyPolyline(physdev, 931 _va_arg_n(argptr, const POINT*, 0), 932 _va_arg_n(argptr, const DWORD*, 1), 933 _va_arg_n(argptr, DWORD, 2)); 934 case DCFUNC_RealizePalette: 935 if (GDI_HANDLE_GET_TYPE(physdev->hdc) != GDILoObjType_LO_METADC16_TYPE) 936 { 937 UNIMPLEMENTED; 938 return GDI_ERROR; 939 } 940 return physdev->funcs->pRealizePalette(physdev, NULL, FALSE); 941 case DCFUNC_Rectangle: 942 return physdev->funcs->pRectangle(physdev, 943 _va_arg_n(argptr, INT, 0), 944 _va_arg_n(argptr, INT, 1), 945 _va_arg_n(argptr, INT, 2), 946 _va_arg_n(argptr, INT, 3)); 947 case DCFUNC_RestoreDC: 948 return DRIVER_RestoreDC(physdev, va_arg(argptr, INT)); 949 case DCFUNC_RoundRect: 950 return physdev->funcs->pRoundRect(physdev, 951 _va_arg_n(argptr, INT, 0), 952 _va_arg_n(argptr, INT, 1), 953 _va_arg_n(argptr, INT, 2), 954 _va_arg_n(argptr, INT, 3), 955 _va_arg_n(argptr, INT, 4), 956 _va_arg_n(argptr, INT, 5)); 957 958 case DCFUNC_SaveDC: 959 return physdev->funcs->pSaveDC(physdev); 960 case DCFUNC_ScaleViewportExtEx: 961 return physdev->funcs->pScaleViewportExtEx(physdev, 962 _va_arg_n(argptr, INT, 0), // xNum 963 _va_arg_n(argptr, INT, 1), // xDenom 964 _va_arg_n(argptr, INT, 2), // yNum 965 _va_arg_n(argptr, INT, 3), // yDenom 966 _va_arg_n(argptr, LPSIZE, 4)); // lpSize 967 case DCFUNC_ScaleWindowExtEx: 968 return physdev->funcs->pScaleWindowExtEx(physdev, 969 _va_arg_n(argptr, INT, 0), // xNum 970 _va_arg_n(argptr, INT, 1), // xDenom 971 _va_arg_n(argptr, INT, 2), // yNum 972 _va_arg_n(argptr, INT, 3), // yDenom 973 _va_arg_n(argptr, LPSIZE, 4)); // lpSize 974 case DCFUNC_SelectBrush: 975 return (DWORD_PTR)DRIVER_SelectBrush(physdev, va_arg(argptr, HBRUSH), NULL); 976 case DCFUNC_SelectClipPath: 977 return physdev->funcs->pSelectClipPath(physdev, va_arg(argptr, INT)); 978 case DCFUNC_SelectFont: 979 return (DWORD_PTR)DRIVER_SelectFont(physdev, va_arg(argptr, HFONT), &aa_flags); 980 case DCFUNC_SelectPalette: 981 return (DWORD_PTR)physdev->funcs->pSelectPalette(physdev, 982 _va_arg_n(argptr, HPALETTE, 0), 983 _va_arg_n(argptr, BOOL, 1)); 984 case DCFUNC_SelectPen: 985 return (DWORD_PTR)DRIVER_SelectPen(physdev, va_arg(argptr, HPEN), NULL); 986 case DCFUNC_SetDCBrushColor: 987 return physdev->funcs->pSetDCBrushColor(physdev, va_arg(argptr, COLORREF)); 988 case DCFUNC_SetDCPenColor: 989 return physdev->funcs->pSetDCPenColor(physdev, va_arg(argptr, COLORREF)); 990 case DCFUNC_SetDIBitsToDevice: 991 return physdev->funcs->pSetDIBitsToDevice(physdev, 992 _va_arg_n(argptr, INT, 0), 993 _va_arg_n(argptr, INT, 1), 994 _va_arg_n(argptr, DWORD, 2), 995 _va_arg_n(argptr, DWORD, 3), 996 _va_arg_n(argptr, INT, 4), 997 _va_arg_n(argptr, INT, 5), 998 _va_arg_n(argptr, UINT, 6), 999 _va_arg_n(argptr, UINT, 7), 1000 _va_arg_n(argptr, LPCVOID, 8), 1001 _va_arg_n(argptr, BITMAPINFO*, 9), 1002 _va_arg_n(argptr, UINT, 10)); 1003 case DCFUNC_SetBkColor: 1004 return physdev->funcs->pSetBkColor(physdev, va_arg(argptr, COLORREF)); 1005 case DCFUNC_SetBkMode: 1006 return physdev->funcs->pSetBkMode(physdev, va_arg(argptr, INT)); 1007 case DCFUNC_SetLayout: 1008 // FIXME: MF16 is UNIMPLEMENTED 1009 return physdev->funcs->pSetLayout(physdev, 1010 _va_arg_n(argptr, DWORD, 0)); 1011 //case DCFUNC_SetMapMode: 1012 // return physdev->funcs->pSetMapMode(physdev, va_arg(argptr, INT)); 1013 case DCFUNC_SetPixel: 1014 return physdev->funcs->pSetPixel(physdev, 1015 _va_arg_n(argptr, INT, 0), 1016 _va_arg_n(argptr, INT, 1), 1017 _va_arg_n(argptr, COLORREF, 2)); 1018 case DCFUNC_SetPolyFillMode: 1019 return physdev->funcs->pSetPolyFillMode(physdev, va_arg(argptr, INT)); 1020 case DCFUNC_SetROP2: 1021 return physdev->funcs->pSetROP2(physdev, va_arg(argptr, INT)); 1022 case DCFUNC_SetStretchBltMode: 1023 return physdev->funcs->pSetStretchBltMode(physdev, va_arg(argptr, INT)); 1024 case DCFUNC_SetTextAlign: 1025 return physdev->funcs->pSetTextAlign(physdev, va_arg(argptr, UINT)); 1026 case DCFUNC_SetTextCharacterExtra: 1027 return physdev->funcs->pSetTextCharacterExtra(physdev, va_arg(argptr, INT)); 1028 case DCFUNC_SetTextColor: 1029 return physdev->funcs->pSetTextColor(physdev, va_arg(argptr, COLORREF)); 1030 case DCFUNC_SetTextJustification: 1031 return physdev->funcs->pSetTextJustification(physdev, 1032 _va_arg_n(argptr, INT, 0), 1033 _va_arg_n(argptr, INT, 1)); 1034 case DCFUNC_SetViewportExtEx: 1035 return physdev->funcs->pSetViewportExtEx(physdev, 1036 _va_arg_n(argptr, INT, 0), // nXExtent 1037 _va_arg_n(argptr, INT, 1), // nYExtent 1038 _va_arg_n(argptr, LPSIZE, 2)); // lpSize 1039 case DCFUNC_SetViewportOrgEx: 1040 return physdev->funcs->pSetViewportOrgEx(physdev, 1041 _va_arg_n(argptr, INT, 0), // X 1042 _va_arg_n(argptr, INT, 1), // Y 1043 _va_arg_n(argptr, LPPOINT, 2)); // lpPoint 1044 case DCFUNC_SetWindowExtEx: 1045 return physdev->funcs->pSetWindowExtEx(physdev, 1046 _va_arg_n(argptr, INT, 0), // nXExtent 1047 _va_arg_n(argptr, INT, 1), // nYExtent 1048 _va_arg_n(argptr, LPSIZE, 2)); // lpSize 1049 case DCFUNC_SetWindowOrgEx: 1050 return physdev->funcs->pSetWindowOrgEx(physdev, 1051 _va_arg_n(argptr, INT, 0), // X 1052 _va_arg_n(argptr, INT, 1), // Y 1053 _va_arg_n(argptr, LPPOINT, 2)); // lpPoint 1054 1055 case DCFUNC_SetWorldTransform: 1056 return physdev->funcs->pSetWorldTransform(physdev, 1057 va_arg(argptr, const XFORM*)); 1058 1059 case DCFUNC_StretchBlt: 1060 return DRIVER_StretchBlt(physdev, 1061 physdev->hdc, 1062 _va_arg_n(argptr, INT, 0), 1063 _va_arg_n(argptr, INT, 1), 1064 _va_arg_n(argptr, INT, 2), 1065 _va_arg_n(argptr, INT, 3), 1066 _va_arg_n(argptr, HDC, 4), 1067 _va_arg_n(argptr, INT, 5), 1068 _va_arg_n(argptr, INT, 6), 1069 _va_arg_n(argptr, INT, 7), 1070 _va_arg_n(argptr, INT, 8), 1071 _va_arg_n(argptr, DWORD, 9)); 1072 case DCFUNC_StrokeAndFillPath: 1073 return physdev->funcs->pStrokeAndFillPath(physdev); 1074 case DCFUNC_StrokePath: 1075 return physdev->funcs->pStrokePath(physdev); 1076 case DCFUNC_WidenPath: 1077 return physdev->funcs->pWidenPath(physdev); 1078 case DCFUNC_AngleArc: 1079 return physdev->funcs->pAngleArc(physdev, 1080 _va_arg_n(argptr, INT, 0), 1081 _va_arg_n(argptr, INT, 1), 1082 _va_arg_n(argptr, DWORD, 2), 1083 _va_arg_n(argptr, FLOAT, 3), 1084 _va_arg_n(argptr, FLOAT, 4 )); 1085 case DCFUNC_ArcTo: 1086 return physdev->funcs->pArcTo(physdev, 1087 _va_arg_n(argptr, INT, 0), 1088 _va_arg_n(argptr, INT, 1), 1089 _va_arg_n(argptr, INT, 2), 1090 _va_arg_n(argptr, INT, 3), 1091 _va_arg_n(argptr, INT, 4), 1092 _va_arg_n(argptr, INT, 5), 1093 _va_arg_n(argptr, INT, 6), 1094 _va_arg_n(argptr, INT, 7)); 1095 case DCFUNC_GradientFill: 1096 return physdev->funcs->pGradientFill(physdev, 1097 _va_arg_n(argptr, TRIVERTEX *, 0), 1098 _va_arg_n(argptr, ULONG, 1), 1099 _va_arg_n(argptr, void *, 2), 1100 _va_arg_n(argptr, ULONG , 3), 1101 _va_arg_n(argptr, ULONG , 4)); 1102 case DCFUNC_PathToRegion: 1103 return (DWORD_PTR)DRIVER_PathToRegion(physdev); 1104 1105 /* These are not implemented in wine */ 1106 case DCFUNC_AlphaBlend: 1107 case DCFUNC_MaskBlt: 1108 case DCFUNC_PlgBlt: 1109 case DCFUNC_TransparentBlt: 1110 UNIMPLEMENTED; 1111 return 0; 1112 1113 default: 1114 __debugbreak(); 1115 return 0; 1116 } 1117 } 1118 1119 BOOL 1120 METADC_Dispatch( 1121 _In_ DCFUNC eFunction, 1122 _Out_ PDWORD_PTR pdwResult, 1123 _In_ DWORD_PTR dwError, 1124 _In_ HDC hdc, 1125 ...) 1126 { 1127 PHYSDEV physdev; 1128 va_list argptr; 1129 1130 /* Handle only METADC16 and ALTDC */ 1131 if ((GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_ALTDC_TYPE) && 1132 (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_METADC16_TYPE)) 1133 { 1134 /* Let the caller handle it */ 1135 return FALSE; 1136 } 1137 1138 // See if this is other than a METADATA issue. 1139 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE) 1140 { 1141 WINEDC* pwdc = (WINEDC*)GdiGetLDC(hdc); 1142 if (pwdc && pwdc->iType != LDC_EMFLDC) 1143 { 1144 /* Let the caller handle it */ 1145 return FALSE; 1146 } 1147 } 1148 1149 physdev = GetPhysDev(hdc); 1150 if (physdev == NULL) 1151 { 1152 SetLastError(ERROR_INVALID_HANDLE); 1153 *pdwResult = dwError; 1154 return TRUE; 1155 } 1156 1157 i = eFunction; 1158 va_start(argptr, hdc); 1159 *pdwResult = DRIVER_Dispatch(physdev, eFunction, argptr); 1160 va_end(argptr); 1161 i = 0; 1162 1163 /* Return TRUE to indicate that we want to return from the parent */ 1164 return ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) || 1165 (*pdwResult == dwError)); 1166 } 1167 1168 BOOL 1169 WINAPI 1170 METADC_GetAndSetDCDWord( 1171 _Out_ DWORD* pdwResult, 1172 _In_ HDC hdc, 1173 _In_ UINT uFunction, 1174 _In_ DWORD dwIn, 1175 _In_ ULONG ulMFId, 1176 _In_ USHORT usMF16Id, 1177 _In_ DWORD dwError) 1178 { 1179 PHYSDEV physdev; 1180 1181 /* Ignore these, we let wine code handle this */ 1182 UNREFERENCED_PARAMETER(ulMFId); 1183 UNREFERENCED_PARAMETER(usMF16Id); 1184 1185 physdev = GetPhysDev(hdc); 1186 if (physdev == NULL) 1187 { 1188 SetLastError(ERROR_INVALID_HANDLE); 1189 *pdwResult = dwError; 1190 return TRUE; 1191 } 1192 1193 /* Check the function */ 1194 switch (uFunction) 1195 { 1196 case GdiGetSetMapMode: 1197 *pdwResult = physdev->funcs->pSetMapMode(physdev, dwIn); 1198 break; 1199 1200 case GdiGetSetArcDirection: 1201 if (GDI_HANDLE_GET_TYPE(physdev->hdc) == GDILoObjType_LO_METADC16_TYPE) 1202 *pdwResult = 0; 1203 else 1204 *pdwResult = physdev->funcs->pSetArcDirection(physdev, dwIn); 1205 break; 1206 1207 case GdiGetSetRelAbs: 1208 if (GDI_HANDLE_GET_TYPE(physdev->hdc) == GDILoObjType_LO_METADC16_TYPE) 1209 *pdwResult = physdev->funcs->pSetRelAbs(physdev, dwIn); 1210 else 1211 { 1212 UNIMPLEMENTED; 1213 *pdwResult = 0; 1214 } 1215 break; 1216 1217 1218 default: 1219 __debugbreak(); 1220 } 1221 1222 /* Return TRUE to indicate that we want to return from the parent */ 1223 return ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) || 1224 (*pdwResult == dwError)); 1225 } 1226 1227 VOID 1228 WINAPI 1229 METADC_DeleteObject(HGDIOBJ hobj) 1230 { 1231 GDILOOBJTYPE eObjectType; 1232 HDC hdc; 1233 PHYSDEV physdev; 1234 1235 /* Check for one of the types we actually handle here */ 1236 eObjectType = GDI_HANDLE_GET_TYPE(hobj); 1237 if ((eObjectType != GDILoObjType_LO_BRUSH_TYPE) && 1238 (eObjectType != GDILoObjType_LO_PEN_TYPE) && 1239 (eObjectType != GDILoObjType_LO_EXTPEN_TYPE) && 1240 (eObjectType != GDILoObjType_LO_PALETTE_TYPE) && 1241 (eObjectType != GDILoObjType_LO_FONT_TYPE)) 1242 { 1243 return; 1244 } 1245 1246 /* Check if we have a client object link and remove it if it was found. 1247 The link is the HDC that the object was selected into. */ 1248 hdc = GdiRemoveClientObjLink(hobj); 1249 if (hdc == NULL) 1250 { 1251 /* The link was not found, so we are not handling this object here */ 1252 return; 1253 } 1254 1255 /* Get the physdev */ 1256 physdev = GetPhysDev(hdc); 1257 if (physdev == NULL) 1258 { 1259 /* This happens, when the METADC is already closed, when we delete 1260 the object. Simply ignore it */ 1261 DPRINT1("METADC was already closed, cannot delete object. Ignoring.\n"); 1262 return; 1263 } 1264 1265 physdev->funcs->pDeleteObject(physdev, hobj); 1266 } 1267 1268 BOOL 1269 WINAPI 1270 METADC_DeleteDC( 1271 _In_ HDC hdc) 1272 { 1273 /* Only ALTDCs are supported */ 1274 if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_ALTDC_TYPE) 1275 { 1276 DPRINT1("Trying to delete METADC %p\n", hdc); 1277 return FALSE; 1278 } 1279 // FIXME call the driver? 1280 return NtGdiDeleteObjectApp(hdc); 1281 } 1282 1283 INT 1284 WINAPI 1285 METADC16_Escape( 1286 _In_ HDC hdc, 1287 _In_ INT nEscape, 1288 _In_ INT cbInput, 1289 _In_ LPCSTR lpvInData, 1290 _Out_ LPVOID lpvOutData) 1291 { 1292 DWORD_PTR dwResult; 1293 1294 /* Do not record MFCOMMENT */ 1295 if (nEscape == MFCOMMENT) 1296 { 1297 // HACK required by wine code... 1298 //return 1; 1299 } 1300 1301 METADC_Dispatch(DCFUNC_ExtEscape, 1302 &dwResult, 1303 SP_ERROR, 1304 hdc, 1305 nEscape, 1306 cbInput, 1307 lpvInData, 1308 lpvOutData); 1309 1310 return (INT)dwResult; 1311 } 1312