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