2 * Mac graphics driver initialisation functions
4 * Copyright 1996 Alexandre Julliard
5 * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 WINE_DEFAULT_DEBUG_CHANNEL(macdrv
);
32 struct gdi_physdev dev
;
35 static inline MACDRV_PDEVICE
*get_macdrv_dev(PHYSDEV dev
)
37 return (MACDRV_PDEVICE
*)dev
;
41 /* a few dynamic device caps */
42 static CGRect desktop_rect
; /* virtual desktop rectangle */
43 static int horz_size
; /* horz. size of screen in millimeters */
44 static int vert_size
; /* vert. size of screen in millimeters */
45 static int bits_per_pixel
; /* pixel depth of screen */
46 static int device_data_valid
; /* do the above variables have up-to-date values? */
48 int retina_on
= FALSE
;
50 static CRITICAL_SECTION device_data_section
;
51 static CRITICAL_SECTION_DEBUG critsect_debug
=
53 0, 0, &device_data_section
,
54 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
55 0, 0, { (DWORD_PTR
)(__FILE__
": device_data_section") }
57 static CRITICAL_SECTION device_data_section
= { &critsect_debug
, -1, 0, 0, 0, 0 };
60 static const struct gdi_dc_funcs macdrv_funcs
;
62 /***********************************************************************
63 * compute_desktop_rect
65 static void compute_desktop_rect(void)
67 CGDirectDisplayID displayIDs
[32];
70 desktop_rect
= CGRectNull
;
71 if (CGGetOnlineDisplayList(ARRAY_SIZE(displayIDs
), displayIDs
, &count
) != kCGErrorSuccess
||
74 displayIDs
[0] = CGMainDisplayID();
78 for (i
= 0; i
< count
; i
++)
79 desktop_rect
= CGRectUnion(desktop_rect
, CGDisplayBounds(displayIDs
[i
]));
80 desktop_rect
= cgrect_win_from_mac(desktop_rect
);
84 /***********************************************************************
85 * macdrv_get_desktop_rect
87 * Returns the rectangle encompassing all the screens.
89 CGRect
macdrv_get_desktop_rect(void)
93 EnterCriticalSection(&device_data_section
);
95 if (!device_data_valid
)
97 check_retina_status();
98 compute_desktop_rect();
102 LeaveCriticalSection(&device_data_section
);
104 TRACE("%s\n", wine_dbgstr_cgrect(ret
));
110 /**********************************************************************
113 * Perform initializations needed upon creation of the first device.
115 static void device_init(void)
117 CGDirectDisplayID mainDisplay
= CGMainDisplayID();
118 CGSize size_mm
= CGDisplayScreenSize(mainDisplay
);
119 CGDisplayModeRef mode
= CGDisplayCopyDisplayMode(mainDisplay
);
121 check_retina_status();
123 /* Initialize device caps */
124 horz_size
= size_mm
.width
;
125 vert_size
= size_mm
.height
;
130 CFStringRef pixelEncoding
= CGDisplayModeCopyPixelEncoding(mode
);
134 if (CFEqual(pixelEncoding
, CFSTR(IO32BitDirectPixels
)))
136 else if (CFEqual(pixelEncoding
, CFSTR(IO16BitDirectPixels
)))
138 else if (CFEqual(pixelEncoding
, CFSTR(IO8BitIndexedPixels
)))
140 CFRelease(pixelEncoding
);
143 CGDisplayModeRelease(mode
);
146 compute_desktop_rect();
148 device_data_valid
= TRUE
;
152 void macdrv_reset_device_metrics(void)
154 EnterCriticalSection(&device_data_section
);
155 device_data_valid
= FALSE
;
156 LeaveCriticalSection(&device_data_section
);
160 static MACDRV_PDEVICE
*create_mac_physdev(void)
162 MACDRV_PDEVICE
*physDev
;
164 EnterCriticalSection(&device_data_section
);
165 if (!device_data_valid
) device_init();
166 LeaveCriticalSection(&device_data_section
);
168 if (!(physDev
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*physDev
)))) return NULL
;
174 /**********************************************************************
175 * CreateDC (MACDRV.@)
177 static BOOL CDECL
macdrv_CreateDC(PHYSDEV
*pdev
, LPCWSTR driver
, LPCWSTR device
,
178 LPCWSTR output
, const DEVMODEW
* initData
)
180 MACDRV_PDEVICE
*physDev
= create_mac_physdev();
182 TRACE("pdev %p hdc %p driver %s device %s output %s initData %p\n", pdev
,
183 (*pdev
)->hdc
, debugstr_w(driver
),debugstr_w(device
), debugstr_w(output
),
186 if (!physDev
) return FALSE
;
188 push_dc_driver(pdev
, &physDev
->dev
, &macdrv_funcs
);
193 /**********************************************************************
194 * CreateCompatibleDC (MACDRV.@)
196 static BOOL CDECL
macdrv_CreateCompatibleDC(PHYSDEV orig
, PHYSDEV
*pdev
)
198 MACDRV_PDEVICE
*physDev
= create_mac_physdev();
200 TRACE("orig %p orig->hdc %p pdev %p pdev->hdc %p\n", orig
, (orig
? orig
->hdc
: NULL
), pdev
,
201 ((pdev
&& *pdev
) ? (*pdev
)->hdc
: NULL
));
203 if (!physDev
) return FALSE
;
205 push_dc_driver(pdev
, &physDev
->dev
, &macdrv_funcs
);
210 /**********************************************************************
211 * DeleteDC (MACDRV.@)
213 static BOOL CDECL
macdrv_DeleteDC(PHYSDEV dev
)
215 MACDRV_PDEVICE
*physDev
= get_macdrv_dev(dev
);
217 TRACE("hdc %p\n", dev
->hdc
);
219 HeapFree(GetProcessHeap(), 0, physDev
);
224 /***********************************************************************
225 * GetDeviceCaps (MACDRV.@)
227 static INT CDECL
macdrv_GetDeviceCaps(PHYSDEV dev
, INT cap
)
231 EnterCriticalSection(&device_data_section
);
233 if (!device_data_valid
) device_init();
244 ret
= bits_per_pixel
;
249 LeaveCriticalSection(&device_data_section
);
250 dev
= GET_NEXT_PHYSDEV( dev
, pGetDeviceCaps
);
251 ret
= dev
->funcs
->pGetDeviceCaps( dev
, cap
);
252 if ((cap
== HORZRES
|| cap
== VERTRES
) && retina_on
)
257 TRACE("cap %d -> %d\n", cap
, ret
);
259 LeaveCriticalSection(&device_data_section
);
264 static const struct gdi_dc_funcs macdrv_funcs
=
266 NULL
, /* pAbortDoc */
267 NULL
, /* pAbortPath */
268 NULL
, /* pAlphaBlend */
269 NULL
, /* pAngleArc */
272 NULL
, /* pBeginPath */
273 NULL
, /* pBlendImage */
275 NULL
, /* pCloseFigure */
276 macdrv_CreateCompatibleDC
, /* pCreateCompatibleDC */
277 macdrv_CreateDC
, /* pCreateDC */
278 macdrv_DeleteDC
, /* pDeleteDC */
279 NULL
, /* pDeleteObject */
280 NULL
, /* pDeviceCapabilities */
285 NULL
, /* pEnumFonts */
286 NULL
, /* pEnumICMProfiles */
287 NULL
, /* pExcludeClipRect */
288 NULL
, /* pExtDeviceMode */
289 NULL
, /* pExtEscape */
290 NULL
, /* pExtFloodFill */
291 NULL
, /* pExtSelectClipRgn */
292 NULL
, /* pExtTextOut */
293 NULL
, /* pFillPath */
295 NULL
, /* pFlattenPath */
296 NULL
, /* pFontIsLinked */
297 NULL
, /* pFrameRgn */
298 NULL
, /* pGdiComment */
299 NULL
, /* pGetBoundsRect */
300 NULL
, /* pGetCharABCWidths */
301 NULL
, /* pGetCharABCWidthsI */
302 NULL
, /* pGetCharWidth */
303 NULL
, /* pGetCharWidthInfo */
304 macdrv_GetDeviceCaps
, /* pGetDeviceCaps */
305 macdrv_GetDeviceGammaRamp
, /* pGetDeviceGammaRamp */
306 NULL
, /* pGetFontData */
307 NULL
, /* pGetFontRealizationInfo */
308 NULL
, /* pGetFontUnicodeRanges */
309 NULL
, /* pGetGlyphIndices */
310 NULL
, /* pGetGlyphOutline */
311 NULL
, /* pGetICMProfile */
312 NULL
, /* pGetImage */
313 NULL
, /* pGetKerningPairs */
314 NULL
, /* pGetNearestColor */
315 NULL
, /* pGetOutlineTextMetrics */
316 NULL
, /* pGetPixel */
317 NULL
, /* pGetSystemPaletteEntries */
318 NULL
, /* pGetTextCharsetInfo */
319 NULL
, /* pGetTextExtentExPoint */
320 NULL
, /* pGetTextExtentExPointI */
321 NULL
, /* pGetTextFace */
322 NULL
, /* pGetTextMetrics */
323 NULL
, /* pGradientFill */
324 NULL
, /* pIntersectClipRect */
325 NULL
, /* pInvertRgn */
327 NULL
, /* pModifyWorldTransform */
329 NULL
, /* pOffsetClipRgn */
330 NULL
, /* pOffsetViewportOrg */
331 NULL
, /* pOffsetWindowOrg */
332 NULL
, /* pPaintRgn */
335 NULL
, /* pPolyBezier */
336 NULL
, /* pPolyBezierTo */
337 NULL
, /* pPolyDraw */
338 NULL
, /* pPolyPolygon */
339 NULL
, /* pPolyPolyline */
341 NULL
, /* pPolyline */
342 NULL
, /* pPolylineTo */
343 NULL
, /* pPutImage */
344 NULL
, /* pRealizeDefaultPalette */
345 NULL
, /* pRealizePalette */
346 NULL
, /* pRectangle */
348 NULL
, /* pRestoreDC */
349 NULL
, /* pRoundRect */
351 NULL
, /* pScaleViewportExt */
352 NULL
, /* pScaleWindowExt */
353 NULL
, /* pSelectBitmap */
354 NULL
, /* pSelectBrush */
355 NULL
, /* pSelectClipPath */
356 NULL
, /* pSelectFont */
357 NULL
, /* pSelectPalette */
358 NULL
, /* pSelectPen */
359 NULL
, /* pSetArcDirection */
360 NULL
, /* pSetBkColor */
361 NULL
, /* pSetBkMode */
362 NULL
, /* pSetBoundsRect */
363 NULL
, /* pSetDCBrushColor */
364 NULL
, /* pSetDCPenColor */
365 NULL
, /* pSetDIBitsToDevice */
366 NULL
, /* pSetDeviceClipping */
367 macdrv_SetDeviceGammaRamp
, /* pSetDeviceGammaRamp */
368 NULL
, /* pSetLayout */
369 NULL
, /* pSetMapMode */
370 NULL
, /* pSetMapperFlags */
371 NULL
, /* pSetPixel */
372 NULL
, /* pSetPolyFillMode */
374 NULL
, /* pSetRelAbs */
375 NULL
, /* pSetStretchBltMode */
376 NULL
, /* pSetTextAlign */
377 NULL
, /* pSetTextCharacterExtra */
378 NULL
, /* pSetTextColor */
379 NULL
, /* pSetTextJustification */
380 NULL
, /* pSetViewportExt */
381 NULL
, /* pSetViewportOrg */
382 NULL
, /* pSetWindowExt */
383 NULL
, /* pSetWindowOrg */
384 NULL
, /* pSetWorldTransform */
385 NULL
, /* pStartDoc */
386 NULL
, /* pStartPage */
387 NULL
, /* pStretchBlt */
388 NULL
, /* pStretchDIBits */
389 NULL
, /* pStrokeAndFillPath */
390 NULL
, /* pStrokePath */
391 NULL
, /* pUnrealizePalette */
392 NULL
, /* pWidenPath */
393 NULL
, /* pD3DKMTCheckVidPnExclusiveOwnership */
394 NULL
, /* pD3DKMTSetVidPnSourceOwner */
395 macdrv_wine_get_wgl_driver
, /* wine_get_wgl_driver */
396 macdrv_wine_get_vulkan_driver
, /* wine_get_vulkan_driver */
397 GDI_PRIORITY_GRAPHICS_DRV
/* priority */
401 /******************************************************************************
402 * macdrv_get_gdi_driver
404 const struct gdi_dc_funcs
* CDECL
macdrv_get_gdi_driver(unsigned int version
)
406 if (version
!= WINE_GDI_DRIVER_VERSION
)
408 ERR("version mismatch, gdi32 wants %u but winemac has %u\n", version
, WINE_GDI_DRIVER_VERSION
);
411 return &macdrv_funcs
;