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