winemac.drv: Take all online monitors into account when computing desktop rect.
[wine/zf.git] / dlls / winemac.drv / gdi.c
blob0acddc1dd9819793ada3ccd50dea0b15eae355ee
1 /*
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
22 #include "config.h"
24 #include "macdrv.h"
25 #include "winreg.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
30 typedef struct
32 struct gdi_physdev dev;
33 } MACDRV_PDEVICE;
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];
68 uint32_t count, i;
70 desktop_rect = CGRectNull;
71 if (CGGetOnlineDisplayList(ARRAY_SIZE(displayIDs), displayIDs, &count) != kCGErrorSuccess ||
72 !count)
74 displayIDs[0] = CGMainDisplayID();
75 count = 1;
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)
91 CGRect ret;
93 EnterCriticalSection(&device_data_section);
95 if (!device_data_valid)
97 check_retina_status();
98 compute_desktop_rect();
100 ret = desktop_rect;
102 LeaveCriticalSection(&device_data_section);
104 TRACE("%s\n", wine_dbgstr_cgrect(ret));
106 return ret;
110 /**********************************************************************
111 * device_init
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;
127 bits_per_pixel = 32;
128 if (mode)
130 CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
132 if (pixelEncoding)
134 if (CFEqual(pixelEncoding, CFSTR(IO32BitDirectPixels)))
135 bits_per_pixel = 32;
136 else if (CFEqual(pixelEncoding, CFSTR(IO16BitDirectPixels)))
137 bits_per_pixel = 16;
138 else if (CFEqual(pixelEncoding, CFSTR(IO8BitIndexedPixels)))
139 bits_per_pixel = 8;
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;
170 return physDev;
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),
184 initData);
186 if (!physDev) return FALSE;
188 push_dc_driver(pdev, &physDev->dev, &macdrv_funcs);
189 return TRUE;
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);
206 return TRUE;
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);
220 return TRUE;
224 /***********************************************************************
225 * GetDeviceCaps (MACDRV.@)
227 static INT CDECL macdrv_GetDeviceCaps(PHYSDEV dev, INT cap)
229 INT ret;
231 EnterCriticalSection(&device_data_section);
233 if (!device_data_valid) device_init();
235 switch(cap)
237 case HORZSIZE:
238 ret = horz_size;
239 break;
240 case VERTSIZE:
241 ret = vert_size;
242 break;
243 case BITSPIXEL:
244 ret = bits_per_pixel;
245 break;
246 case HORZRES:
247 case VERTRES:
248 default:
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)
253 ret *= 2;
254 return ret;
257 TRACE("cap %d -> %d\n", cap, ret);
259 LeaveCriticalSection(&device_data_section);
260 return ret;
264 static const struct gdi_dc_funcs macdrv_funcs =
266 NULL, /* pAbortDoc */
267 NULL, /* pAbortPath */
268 NULL, /* pAlphaBlend */
269 NULL, /* pAngleArc */
270 NULL, /* pArc */
271 NULL, /* pArcTo */
272 NULL, /* pBeginPath */
273 NULL, /* pBlendImage */
274 NULL, /* pChord */
275 NULL, /* pCloseFigure */
276 macdrv_CreateCompatibleDC, /* pCreateCompatibleDC */
277 macdrv_CreateDC, /* pCreateDC */
278 macdrv_DeleteDC, /* pDeleteDC */
279 NULL, /* pDeleteObject */
280 NULL, /* pDeviceCapabilities */
281 NULL, /* pEllipse */
282 NULL, /* pEndDoc */
283 NULL, /* pEndPage */
284 NULL, /* pEndPath */
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 */
294 NULL, /* pFillRgn */
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 */
326 NULL, /* pLineTo */
327 NULL, /* pModifyWorldTransform */
328 NULL, /* pMoveTo */
329 NULL, /* pOffsetClipRgn */
330 NULL, /* pOffsetViewportOrg */
331 NULL, /* pOffsetWindowOrg */
332 NULL, /* pPaintRgn */
333 NULL, /* pPatBlt */
334 NULL, /* pPie */
335 NULL, /* pPolyBezier */
336 NULL, /* pPolyBezierTo */
337 NULL, /* pPolyDraw */
338 NULL, /* pPolyPolygon */
339 NULL, /* pPolyPolyline */
340 NULL, /* pPolygon */
341 NULL, /* pPolyline */
342 NULL, /* pPolylineTo */
343 NULL, /* pPutImage */
344 NULL, /* pRealizeDefaultPalette */
345 NULL, /* pRealizePalette */
346 NULL, /* pRectangle */
347 NULL, /* pResetDC */
348 NULL, /* pRestoreDC */
349 NULL, /* pRoundRect */
350 NULL, /* pSaveDC */
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 */
373 NULL, /* pSetROP2 */
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);
409 return NULL;
411 return &macdrv_funcs;