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