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 horz_res
; /* width in pixels of screen */
46 static int vert_res
; /* height in pixels of screen */
47 static int desktop_horz_res
; /* width in pixels of virtual desktop */
48 static int desktop_vert_res
; /* height in pixels of virtual desktop */
49 static int bits_per_pixel
; /* pixel depth of screen */
50 static int device_data_valid
; /* do the above variables have up-to-date values? */
52 int retina_on
= FALSE
;
54 static CRITICAL_SECTION device_data_section
;
55 static CRITICAL_SECTION_DEBUG critsect_debug
=
57 0, 0, &device_data_section
,
58 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
59 0, 0, { (DWORD_PTR
)(__FILE__
": device_data_section") }
61 static CRITICAL_SECTION device_data_section
= { &critsect_debug
, -1, 0, 0, 0, 0 };
64 static const struct gdi_dc_funcs macdrv_funcs
;
66 /***********************************************************************
67 * compute_desktop_rect
69 static void compute_desktop_rect(void)
71 CGDirectDisplayID displayIDs
[32];
74 desktop_rect
= CGRectNull
;
75 if (CGGetActiveDisplayList(sizeof(displayIDs
)/sizeof(displayIDs
[0]),
76 displayIDs
, &count
) != kCGErrorSuccess
||
79 displayIDs
[0] = CGMainDisplayID();
83 for (i
= 0; i
< count
; i
++)
84 desktop_rect
= CGRectUnion(desktop_rect
, CGDisplayBounds(displayIDs
[i
]));
85 desktop_rect
= cgrect_win_from_mac(desktop_rect
);
89 /***********************************************************************
90 * macdrv_get_desktop_rect
92 * Returns the rectangle encompassing all the screens.
94 CGRect
macdrv_get_desktop_rect(void)
98 EnterCriticalSection(&device_data_section
);
100 if (!device_data_valid
)
102 check_retina_status();
103 compute_desktop_rect();
107 LeaveCriticalSection(&device_data_section
);
109 TRACE("%s\n", wine_dbgstr_cgrect(ret
));
115 /**********************************************************************
118 * Perform initializations needed upon creation of the first device.
120 static void device_init(void)
122 CGDirectDisplayID mainDisplay
= CGMainDisplayID();
123 CGSize size_mm
= CGDisplayScreenSize(mainDisplay
);
124 CGDisplayModeRef mode
= CGDisplayCopyDisplayMode(mainDisplay
);
126 check_retina_status();
128 /* Initialize device caps */
129 horz_size
= size_mm
.width
;
130 vert_size
= size_mm
.height
;
135 CFStringRef pixelEncoding
= CGDisplayModeCopyPixelEncoding(mode
);
137 horz_res
= CGDisplayModeGetWidth(mode
);
138 vert_res
= CGDisplayModeGetHeight(mode
);
142 if (CFEqual(pixelEncoding
, CFSTR(IO32BitDirectPixels
)))
144 else if (CFEqual(pixelEncoding
, CFSTR(IO16BitDirectPixels
)))
146 else if (CFEqual(pixelEncoding
, CFSTR(IO8BitIndexedPixels
)))
148 CFRelease(pixelEncoding
);
151 CGDisplayModeRelease(mode
);
155 horz_res
= CGDisplayPixelsWide(mainDisplay
);
156 vert_res
= CGDisplayPixelsHigh(mainDisplay
);
165 compute_desktop_rect();
166 desktop_horz_res
= desktop_rect
.size
.width
;
167 desktop_vert_res
= desktop_rect
.size
.height
;
169 device_data_valid
= TRUE
;
173 void macdrv_reset_device_metrics(void)
175 EnterCriticalSection(&device_data_section
);
176 device_data_valid
= FALSE
;
177 LeaveCriticalSection(&device_data_section
);
181 static MACDRV_PDEVICE
*create_mac_physdev(void)
183 MACDRV_PDEVICE
*physDev
;
185 EnterCriticalSection(&device_data_section
);
186 if (!device_data_valid
) device_init();
187 LeaveCriticalSection(&device_data_section
);
189 if (!(physDev
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*physDev
)))) return NULL
;
195 /**********************************************************************
196 * CreateDC (MACDRV.@)
198 static BOOL
macdrv_CreateDC(PHYSDEV
*pdev
, LPCWSTR driver
, LPCWSTR device
,
199 LPCWSTR output
, const DEVMODEW
* initData
)
201 MACDRV_PDEVICE
*physDev
= create_mac_physdev();
203 TRACE("pdev %p hdc %p driver %s device %s output %s initData %p\n", pdev
,
204 (*pdev
)->hdc
, debugstr_w(driver
),debugstr_w(device
), debugstr_w(output
),
207 if (!physDev
) return FALSE
;
209 push_dc_driver(pdev
, &physDev
->dev
, &macdrv_funcs
);
214 /**********************************************************************
215 * CreateCompatibleDC (MACDRV.@)
217 static BOOL
macdrv_CreateCompatibleDC(PHYSDEV orig
, PHYSDEV
*pdev
)
219 MACDRV_PDEVICE
*physDev
= create_mac_physdev();
221 TRACE("orig %p orig->hdc %p pdev %p pdev->hdc %p\n", orig
, (orig
? orig
->hdc
: NULL
), pdev
,
222 ((pdev
&& *pdev
) ? (*pdev
)->hdc
: NULL
));
224 if (!physDev
) return FALSE
;
226 push_dc_driver(pdev
, &physDev
->dev
, &macdrv_funcs
);
231 /**********************************************************************
232 * DeleteDC (MACDRV.@)
234 static BOOL
macdrv_DeleteDC(PHYSDEV dev
)
236 MACDRV_PDEVICE
*physDev
= get_macdrv_dev(dev
);
238 TRACE("hdc %p\n", dev
->hdc
);
240 HeapFree(GetProcessHeap(), 0, physDev
);
245 /***********************************************************************
246 * GetDeviceCaps (MACDRV.@)
248 static INT
macdrv_GetDeviceCaps(PHYSDEV dev
, INT cap
)
252 EnterCriticalSection(&device_data_section
);
254 if (!device_data_valid
) device_init();
271 ret
= desktop_horz_res
;
274 ret
= desktop_vert_res
;
277 ret
= bits_per_pixel
;
280 LeaveCriticalSection(&device_data_section
);
281 dev
= GET_NEXT_PHYSDEV( dev
, pGetDeviceCaps
);
282 return dev
->funcs
->pGetDeviceCaps( dev
, cap
);
285 TRACE("cap %d -> %d\n", cap
, ret
);
287 LeaveCriticalSection(&device_data_section
);
292 static const struct gdi_dc_funcs macdrv_funcs
=
294 NULL
, /* pAbortDoc */
295 NULL
, /* pAbortPath */
296 NULL
, /* pAlphaBlend */
297 NULL
, /* pAngleArc */
300 NULL
, /* pBeginPath */
301 NULL
, /* pBlendImage */
303 NULL
, /* pCloseFigure */
304 macdrv_CreateCompatibleDC
, /* pCreateCompatibleDC */
305 macdrv_CreateDC
, /* pCreateDC */
306 macdrv_DeleteDC
, /* pDeleteDC */
307 NULL
, /* pDeleteObject */
308 NULL
, /* pDeviceCapabilities */
313 NULL
, /* pEnumFonts */
314 NULL
, /* pEnumICMProfiles */
315 NULL
, /* pExcludeClipRect */
316 NULL
, /* pExtDeviceMode */
317 NULL
, /* pExtEscape */
318 NULL
, /* pExtFloodFill */
319 NULL
, /* pExtSelectClipRgn */
320 NULL
, /* pExtTextOut */
321 NULL
, /* pFillPath */
323 NULL
, /* pFlattenPath */
324 NULL
, /* pFontIsLinked */
325 NULL
, /* pFrameRgn */
326 NULL
, /* pGdiComment */
327 NULL
, /* pGetBoundsRect */
328 NULL
, /* pGetCharABCWidths */
329 NULL
, /* pGetCharABCWidthsI */
330 NULL
, /* pGetCharWidth */
331 macdrv_GetDeviceCaps
, /* pGetDeviceCaps */
332 macdrv_GetDeviceGammaRamp
, /* pGetDeviceGammaRamp */
333 NULL
, /* pGetFontData */
334 NULL
, /* pGetFontRealizationInfo */
335 NULL
, /* pGetFontUnicodeRanges */
336 NULL
, /* pGetGlyphIndices */
337 NULL
, /* pGetGlyphOutline */
338 NULL
, /* pGetICMProfile */
339 NULL
, /* pGetImage */
340 NULL
, /* pGetKerningPairs */
341 NULL
, /* pGetNearestColor */
342 NULL
, /* pGetOutlineTextMetrics */
343 NULL
, /* pGetPixel */
344 NULL
, /* pGetSystemPaletteEntries */
345 NULL
, /* pGetTextCharsetInfo */
346 NULL
, /* pGetTextExtentExPoint */
347 NULL
, /* pGetTextExtentExPointI */
348 NULL
, /* pGetTextFace */
349 NULL
, /* pGetTextMetrics */
350 NULL
, /* pGradientFill */
351 NULL
, /* pIntersectClipRect */
352 NULL
, /* pInvertRgn */
354 NULL
, /* pModifyWorldTransform */
356 NULL
, /* pOffsetClipRgn */
357 NULL
, /* pOffsetViewportOrg */
358 NULL
, /* pOffsetWindowOrg */
359 NULL
, /* pPaintRgn */
362 NULL
, /* pPolyBezier */
363 NULL
, /* pPolyBezierTo */
364 NULL
, /* pPolyDraw */
365 NULL
, /* pPolyPolygon */
366 NULL
, /* pPolyPolyline */
368 NULL
, /* pPolyline */
369 NULL
, /* pPolylineTo */
370 NULL
, /* pPutImage */
371 NULL
, /* pRealizeDefaultPalette */
372 NULL
, /* pRealizePalette */
373 NULL
, /* pRectangle */
375 NULL
, /* pRestoreDC */
376 NULL
, /* pRoundRect */
378 NULL
, /* pScaleViewportExt */
379 NULL
, /* pScaleWindowExt */
380 NULL
, /* pSelectBitmap */
381 NULL
, /* pSelectBrush */
382 NULL
, /* pSelectClipPath */
383 NULL
, /* pSelectFont */
384 NULL
, /* pSelectPalette */
385 NULL
, /* pSelectPen */
386 NULL
, /* pSetArcDirection */
387 NULL
, /* pSetBkColor */
388 NULL
, /* pSetBkMode */
389 NULL
, /* pSetBoundsRect */
390 NULL
, /* pSetDCBrushColor */
391 NULL
, /* pSetDCPenColor */
392 NULL
, /* pSetDIBitsToDevice */
393 NULL
, /* pSetDeviceClipping */
394 macdrv_SetDeviceGammaRamp
, /* pSetDeviceGammaRamp */
395 NULL
, /* pSetLayout */
396 NULL
, /* pSetMapMode */
397 NULL
, /* pSetMapperFlags */
398 NULL
, /* pSetPixel */
399 NULL
, /* pSetPolyFillMode */
401 NULL
, /* pSetRelAbs */
402 NULL
, /* pSetStretchBltMode */
403 NULL
, /* pSetTextAlign */
404 NULL
, /* pSetTextCharacterExtra */
405 NULL
, /* pSetTextColor */
406 NULL
, /* pSetTextJustification */
407 NULL
, /* pSetViewportExt */
408 NULL
, /* pSetViewportOrg */
409 NULL
, /* pSetWindowExt */
410 NULL
, /* pSetWindowOrg */
411 NULL
, /* pSetWorldTransform */
412 NULL
, /* pStartDoc */
413 NULL
, /* pStartPage */
414 NULL
, /* pStretchBlt */
415 NULL
, /* pStretchDIBits */
416 NULL
, /* pStrokeAndFillPath */
417 NULL
, /* pStrokePath */
418 NULL
, /* pUnrealizePalette */
419 NULL
, /* pWidenPath */
420 macdrv_wine_get_wgl_driver
, /* wine_get_wgl_driver */
421 GDI_PRIORITY_GRAPHICS_DRV
/* priority */
425 /******************************************************************************
426 * macdrv_get_gdi_driver
428 const struct gdi_dc_funcs
* CDECL
macdrv_get_gdi_driver(unsigned int version
)
430 if (version
!= WINE_GDI_DRIVER_VERSION
)
432 ERR("version mismatch, gdi32 wants %u but winemac has %u\n", version
, WINE_GDI_DRIVER_VERSION
);
435 return &macdrv_funcs
;