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