xref: /reactos/win32ss/gdi/gdi32/wine/rosglue.c (revision fc16259f)
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 GDILOOBJTYPE
ConvertObjectType(WORD wType)11 ConvertObjectType(
12     WORD wType)
13 {
14     /* Get the GDI object type */
15     switch (wType)
16     {
17         case OBJ_PEN: return GDILoObjType_LO_PEN_TYPE;
18         case OBJ_BRUSH: return GDILoObjType_LO_BRUSH_TYPE;
19         case OBJ_DC: return GDILoObjType_LO_DC_TYPE;
20         case OBJ_METADC: return GDILoObjType_LO_METADC16_TYPE;
21         case OBJ_PAL: return GDILoObjType_LO_PALETTE_TYPE;
22         case OBJ_FONT: return GDILoObjType_LO_FONT_TYPE;
23         case OBJ_BITMAP: return GDILoObjType_LO_BITMAP_TYPE;
24         case OBJ_REGION: return GDILoObjType_LO_REGION_TYPE;
25         case OBJ_METAFILE: return GDILoObjType_LO_METAFILE16_TYPE;
26         case OBJ_MEMDC: return GDILoObjType_LO_DC_TYPE;
27         case OBJ_EXTPEN: return GDILoObjType_LO_EXTPEN_TYPE;
28         case OBJ_ENHMETADC: return GDILoObjType_LO_ALTDC_TYPE;
29         case OBJ_ENHMETAFILE: return GDILoObjType_LO_METAFILE_TYPE;
30         case OBJ_COLORSPACE: return GDILoObjType_LO_ICMLCS_TYPE;
31         default: return 0;
32     }
33 }
34 
35 HGDIOBJ
alloc_gdi_handle(PVOID pvObject,WORD wType,const struct gdi_obj_funcs * funcs)36 alloc_gdi_handle(
37     PVOID pvObject,
38     WORD wType,
39     const struct gdi_obj_funcs *funcs)
40 {
41     GDILOOBJTYPE eObjType;
42 
43     /* Get the GDI object type */
44     eObjType = ConvertObjectType(wType);
45     if ((eObjType != GDILoObjType_LO_METAFILE_TYPE) &&
46         (eObjType != GDILoObjType_LO_METAFILE16_TYPE) &&
47         (eObjType != GDILoObjType_LO_METADC16_TYPE))
48     {
49         /* This is not supported! */
50         ASSERT(FALSE);
51         return NULL;
52     }
53 
54     /* Insert the client object */
55     return GdiCreateClientObj(pvObject, eObjType);
56 }
57 
58 PVOID
free_gdi_handle(HGDIOBJ hobj)59 free_gdi_handle(HGDIOBJ hobj)
60 {
61     /* Should be a client object */
62     return GdiDeleteClientObj(hobj);
63 }
64 
65 PVOID
GDI_GetObjPtr(HGDIOBJ hobj,WORD wType)66 GDI_GetObjPtr(
67     HGDIOBJ hobj,
68     WORD wType)
69 {
70     GDILOOBJTYPE eObjType;
71 
72     /* Check if the object type matches */
73     eObjType = ConvertObjectType(wType);
74     if ((eObjType == 0) || (GDI_HANDLE_GET_TYPE(hobj) != eObjType))
75     {
76         return NULL;
77     }
78 
79     /* Check if we have an ALTDC */
80     if (eObjType == GDILoObjType_LO_ALTDC_TYPE)
81     {
82         /* Object is stored as LDC */
83         return GdiGetLDC(hobj);
84     }
85 
86     /* Check for client objects */
87     if ((eObjType == GDILoObjType_LO_METAFILE_TYPE) ||
88         (eObjType == GDILoObjType_LO_METAFILE16_TYPE) ||
89         (eObjType == GDILoObjType_LO_METADC16_TYPE))
90     {
91         return GdiGetClientObjLink(hobj);
92     }
93 
94     /* This should never happen! */
95     ASSERT(FALSE);
96     return NULL;
97 }
98 
99 VOID
GDI_ReleaseObj(HGDIOBJ hobj)100 GDI_ReleaseObj(HGDIOBJ hobj)
101 {
102     /* We don't do any reference-counting */
103 }
104 
105 WINEDC*
alloc_dc_ptr(WORD magic)106 alloc_dc_ptr(WORD magic)
107 {
108     WINEDC* pWineDc;
109 
110     /* Allocate the Wine DC */
111     pWineDc = HeapAlloc(GetProcessHeap(), 0, sizeof(*pWineDc));
112     if (pWineDc == NULL)
113     {
114         return NULL;
115     }
116 
117     ZeroMemory(pWineDc, sizeof(*pWineDc));
118     pWineDc->hBrush = GetStockObject(WHITE_BRUSH);
119     pWineDc->hPen = GetStockObject(BLACK_PEN);
120 
121     if (magic == OBJ_ENHMETADC)
122     {
123         /* We create a metafile DC, but we ignore the reference DC, this is
124            handled by the wine code */
125         pWineDc->hdc = NtGdiCreateMetafileDC(NULL);
126         if (pWineDc->hdc == NULL)
127         {
128             HeapFree(GetProcessHeap(), 0, pWineDc);
129             return NULL;
130         }
131 
132         pWineDc->iType = LDC_EMFLDC;
133 
134         /* Set the Wine DC as LDC */
135         GdiSetLDC(pWineDc->hdc, pWineDc);
136     }
137     else
138     {
139         // nothing else supported!
140         ASSERT(FALSE);
141     }
142 
143     return pWineDc;
144 }
145 
146 WINEDC*
get_dc_ptr(HDC hdc)147 get_dc_ptr(HDC hdc)
148 {
149     /* Check for EMF DC */
150     if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE)
151     {
152         /* The Wine DC is stored as the LDC */
153         return (WINEDC*)GdiGetLDC(hdc);
154     }
155 
156     /* Check for METADC16 */
157     if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
158     {
159         return GdiGetClientObjLink(hdc);
160     }
161 
162     return NULL;
163 }
164 
165 VOID
GDI_hdc_using_object(HGDIOBJ hobj,HDC hdc)166 GDI_hdc_using_object(
167     HGDIOBJ hobj,
168     HDC hdc)
169 {
170     /* Record that we have an object in use by a METADC. We simply link the
171        object to the HDC that we use. Wine API does not give us a way to
172        respond to failure, so we silently ignore it */
173     if (!GdiCreateClientObjLink(hobj, hdc))
174     {
175         /* Ignore failure, and return */
176         DPRINT1("Failed to create link for selected METADC object.\n");
177         return;
178     }
179 }
180 
181 VOID
GDI_hdc_not_using_object(HGDIOBJ hobj,HDC hdc)182 GDI_hdc_not_using_object(
183     HGDIOBJ hobj,
184     HDC hdc)
185 {
186     HDC hdcLink;
187 
188     /* Remove the HDC link for the object */
189     hdcLink = GdiRemoveClientObjLink(hobj);
190     ASSERT(hdcLink == hdc);
191 }
192 
193 /***********************************************************************
194  *           bitmap_info_size
195  *
196  * Return the size of the bitmap info structure including color table.
197  */
198 int
bitmap_info_size(const BITMAPINFO * info,WORD coloruse)199 bitmap_info_size(
200     const BITMAPINFO * info,
201     WORD coloruse)
202 {
203     unsigned int colors, size, masks = 0;
204 
205     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
206     {
207         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
208         colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
209         return sizeof(BITMAPCOREHEADER) + colors *
210              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
211     }
212     else  /* assume BITMAPINFOHEADER */
213     {
214         if (info->bmiHeader.biClrUsed) colors = min( info->bmiHeader.biClrUsed, 256 );
215         else colors = info->bmiHeader.biBitCount > 8 ? 0 : 1 << info->bmiHeader.biBitCount;
216         if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
217         size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
218         return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
219     }
220 }
221 
222 BOOL
get_brush_bitmap_info(HBRUSH hbr,PBITMAPINFO pbmi,PVOID pvBits,PUINT puUsage)223 get_brush_bitmap_info(
224     HBRUSH hbr,
225     PBITMAPINFO pbmi,
226     PVOID pvBits,
227     PUINT puUsage)
228 {
229     HBITMAP hbmp;
230     HDC hdc;
231     PVOID Bits;
232 
233     /* Call win32k to get the bitmap handle and color usage */
234     hbmp = NtGdiGetObjectBitmapHandle(hbr, puUsage);
235     if (hbmp == NULL)
236         return FALSE;
237 
238     hdc = GetDC(NULL);
239     if (hdc == NULL)
240         return FALSE;
241 
242     /* Initialize the BITMAPINFO */
243     ZeroMemory(pbmi, sizeof(*pbmi));
244     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
245 
246     /* Retrieve information about the bitmap */
247     if (!GetDIBits(hdc, hbmp, 0, 0, NULL, pbmi, *puUsage))
248         return FALSE;
249 
250     if (pvBits)
251     {
252         /* Now allocate a buffer for the bits */
253         Bits = HeapAlloc(GetProcessHeap(), 0, pbmi->bmiHeader.biSizeImage);
254         if (Bits == NULL)
255             return FALSE;
256 
257         /* Retrieve the bitmap bits */
258         if (!GetDIBits(hdc, hbmp, 0, pbmi->bmiHeader.biHeight, Bits, pbmi, *puUsage))
259         {
260             HeapFree(GetProcessHeap(), 0, Bits);
261             return FALSE;
262         }
263 
264         CopyMemory( pvBits, Bits, pbmi->bmiHeader.biSizeImage );
265 
266     }
267 
268     /* GetDIBits doesn't set biClrUsed, but wine code needs it, so we set it */
269     if (pbmi->bmiHeader.biBitCount <= 8)
270     {
271         pbmi->bmiHeader.biClrUsed =  1 << pbmi->bmiHeader.biBitCount;
272     }
273     return TRUE;
274 }
275 
276 BOOL
277 WINAPI
SetVirtualResolution(HDC hdc,DWORD cxVirtualDevicePixel,DWORD cyVirtualDevicePixel,DWORD cxVirtualDeviceMm,DWORD cyVirtualDeviceMm)278 SetVirtualResolution(
279     HDC hdc,
280     DWORD cxVirtualDevicePixel,
281     DWORD cyVirtualDevicePixel,
282     DWORD cxVirtualDeviceMm,
283     DWORD cyVirtualDeviceMm)
284 {
285     return NtGdiSetVirtualResolution(hdc,
286                                      cxVirtualDevicePixel,
287                                      cyVirtualDevicePixel,
288                                      cxVirtualDeviceMm,
289                                      cyVirtualDeviceMm);
290 }
291 
292 BOOL
293 WINAPI
DeleteColorSpace(HCOLORSPACE hcs)294 DeleteColorSpace(
295     HCOLORSPACE hcs)
296 {
297     return NtGdiDeleteColorSpace(hcs);
298 }
299 void
300 __cdecl
_assert(const char * exp,const char * file,unsigned line)301 _assert (
302     const char *exp,
303     const char *file,
304     unsigned line)
305 {
306     DbgRaiseAssertionFailure();
307 }
308 
309 /******************************************************************************/
310 BOOL
311 WINAPI
METADC_SetD(_In_ HDC hdc,_In_ DWORD dwIn,_In_ USHORT usMF16Id)312 METADC_SetD(
313      _In_ HDC hdc,
314      _In_ DWORD dwIn,
315      _In_ USHORT usMF16Id
316 )
317 {
318     switch(usMF16Id)
319     {
320     case META_SETMAPMODE:
321         return METADC_SetMapMode(hdc, dwIn);
322     case META_SETRELABS:
323         return METADC_SetRelAbs(hdc, dwIn);
324     default:
325         return FALSE;
326     }
327 }
328 
329 BOOL
330 WINAPI
EMFDC_SetD(_In_ PLDC pldc,_In_ DWORD dwIn,_In_ ULONG ulMFId)331 EMFDC_SetD(
332     _In_ PLDC pldc,
333     _In_ DWORD dwIn,
334     _In_ ULONG ulMFId)
335 {
336     switch(ulMFId)
337     {
338     case EMR_SETMAPMODE:
339         return EMFDC_SetMapMode( pldc, dwIn);
340     case EMR_SETARCDIRECTION:
341         return EMFDC_SetArcDirection( pldc, dwIn);
342     default:
343         return FALSE;
344     }
345 }
346 
347 extern void METADC_DeleteObject( HDC hdc, HGDIOBJ obj );
348 extern void emfdc_delete_object( HDC hdc, HGDIOBJ obj );
349 
350 VOID
351 WINAPI
METADC_RosGlueDeleteObject(HGDIOBJ hobj)352 METADC_RosGlueDeleteObject(HGDIOBJ hobj)
353 {
354     GDILOOBJTYPE eObjectType;
355     HDC hdc;
356 
357     /* Check for one of the types we actually handle here */
358     eObjectType = GDI_HANDLE_GET_TYPE(hobj);
359     if ((eObjectType != GDILoObjType_LO_BRUSH_TYPE) &&
360         (eObjectType != GDILoObjType_LO_PEN_TYPE) &&
361         (eObjectType != GDILoObjType_LO_EXTPEN_TYPE) &&
362         (eObjectType != GDILoObjType_LO_PALETTE_TYPE) &&
363         (eObjectType != GDILoObjType_LO_FONT_TYPE))
364     {
365         return;
366     }
367 
368     /* Check if we have a client object link and remove it if it was found.
369        The link is the HDC that the object was selected into. */
370     hdc = GdiRemoveClientObjLink(hobj);
371     if (hdc == NULL)
372     {
373         DPRINT1("the link was not found\n");
374         /* The link was not found, so we are not handling this object here */
375         return;
376     }
377 
378     if ( GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE ) METADC_DeleteObject( hdc, hobj );
379 
380     if ( GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE )
381     {
382         LDC* pWineDc = GdiGetLDC(hdc);
383         if ( pWineDc )
384         {
385             emfdc_delete_object( hdc, hobj );
386         }
387     }
388 }
389 
390 BOOL
391 WINAPI
METADC_RosGlueDeleteDC(_In_ HDC hdc)392 METADC_RosGlueDeleteDC(
393     _In_ HDC hdc)
394 {
395     LDC* pWineDc = NULL;
396 
397     if ( GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE )
398     {
399         return METADC_DeleteDC(hdc);
400     }
401 
402     if ( GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE )
403     {
404         pWineDc = GdiGetLDC(hdc);
405 
406         if ( pWineDc )
407         {
408             // Handle Printer LDC
409             if (pWineDc->iType != LDC_EMFLDC)
410             {
411                //return IntDeleteDC(hdc);
412             }
413 
414             EMFDC_DeleteDC( pWineDc );
415 
416             /* Get rid of the LDC */
417             ASSERT(GdiGetLDC(pWineDc->hDC) == pWineDc);
418             GdiSetLDC(pWineDc->hDC, NULL);
419 
420             /* Free the Wine DC */
421             HeapFree(GetProcessHeap(), 0, pWineDc);
422         }
423     }
424 
425     return NtGdiDeleteObjectApp(hdc);
426 }
427 
428