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