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