21 #include "../../SDL_internal.h"
24 #if SDL_VIDEO_DRIVER_COCOA
29 #include <IOKit/graphics/IOGraphicsLib.h>
32 #include <CoreVideo/CVBase.h>
33 #include <CoreVideo/CVDisplayLink.h>
36 #include <Carbon/Carbon.h>
39 #include <AvailabilityMacros.h>
43 Cocoa_ToggleMenuBar(
const BOOL show)
50 #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__)
60 CG_SetError(
const char *prefix, CGDisplayErr
result)
66 error =
"kCGErrorFailure";
68 case kCGErrorIllegalArgument:
69 error =
"kCGErrorIllegalArgument";
71 case kCGErrorInvalidConnection:
72 error =
"kCGErrorInvalidConnection";
74 case kCGErrorInvalidContext:
75 error =
"kCGErrorInvalidContext";
77 case kCGErrorCannotComplete:
78 error =
"kCGErrorCannotComplete";
80 case kCGErrorNotImplemented:
81 error =
"kCGErrorNotImplemented";
83 case kCGErrorRangeCheck:
84 error =
"kCGErrorRangeCheck";
86 case kCGErrorTypeCheck:
87 error =
"kCGErrorTypeCheck";
89 case kCGErrorInvalidOperation:
90 error =
"kCGErrorInvalidOperation";
92 case kCGErrorNoneAvailable:
93 error =
"kCGErrorNoneAvailable";
96 error =
"Unknown Error";
116 data->moderef = vidmode;
118 fmt = CGDisplayModeCopyPixelEncoding(vidmode);
119 width = (int) CGDisplayModeGetWidth(vidmode);
120 height = (int) CGDisplayModeGetHeight(vidmode);
121 refreshRate = (int) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
123 if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
124 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
126 }
else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
127 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
129 }
else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
130 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
139 if (refreshRate == 0 && link !=
NULL) {
140 CVTime
time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
141 if ((
time.flags & kCVTimeIsIndefinite) == 0 &&
time.timeValue != 0) {
142 refreshRate = (int) ((
time.timeScale / (
double)
time.timeValue) + 0.5);
164 mode->refresh_rate = refreshRate;
170 Cocoa_GetDisplayName(CGDirectDisplayID displayID)
172 CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
173 NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
174 const char* displayName =
NULL;
176 if ([localizedNames
count] > 0) {
177 displayName =
SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
179 CFRelease(deviceInfo);
188 CGDirectDisplayID *displays;
189 CGDisplayCount numDisplays;
192 result = CGGetOnlineDisplayList(0,
NULL, &numDisplays);
193 if (
result != kCGErrorSuccess) {
194 CG_SetError(
"CGGetOnlineDisplayList()",
result);
198 result = CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
199 if (
result != kCGErrorSuccess) {
200 CG_SetError(
"CGGetOnlineDisplayList()",
result);
206 for (pass = 0; pass < 2; ++pass) {
207 for (
i = 0;
i < numDisplays; ++
i) {
211 CGDisplayModeRef moderef =
NULL;
212 CVDisplayLinkRef link =
NULL;
215 if (!CGDisplayIsMain(displays[
i])) {
219 if (CGDisplayIsMain(displays[
i])) {
224 if (CGDisplayMirrorsDisplay(displays[
i]) != kCGNullDirectDisplay) {
228 moderef = CGDisplayCopyDisplayMode(displays[
i]);
236 CGDisplayModeRelease(moderef);
239 displaydata->
display = displays[i];
241 CVDisplayLinkCreateWithCGDisplay(displays[
i], &link);
245 display.
name = (
char *)Cocoa_GetDisplayName(displays[
i]);
246 if (!GetDisplayMode(
_this, moderef, link, &
mode)) {
247 CVDisplayLinkRelease(link);
248 CGDisplayModeRelease(moderef);
254 CVDisplayLinkRelease(link);
272 cgrect = CGDisplayBounds(displaydata->
display);
273 rect->
x = (int)cgrect.origin.x;
274 rect->
y = (
int)cgrect.origin.y;
275 rect->
w = (int)cgrect.size.width;
276 rect->
h = (
int)cgrect.size.height;
284 const CGDirectDisplayID cgdisplay = displaydata->
display;
285 NSArray *screens = [NSScreen screens];
289 for (NSScreen *
i in screens) {
290 const CGDirectDisplayID thisDisplay = (CGDirectDisplayID) [[[
i deviceDescription] objectForKey:
@"NSScreenNumber"] unsignedIntValue];
291 if (thisDisplay == cgdisplay) {
302 const CGRect cgrect = CGDisplayBounds(cgdisplay);
303 const NSRect
frame = [screen visibleFrame];
307 rect->
x = (int)(cgrect.origin.x +
frame.origin.x);
308 rect->
y = (int)(cgrect.origin.y +
frame.origin.y);
318 const float MM_IN_INCH = 25.4f;
322 CGSize displaySize = CGDisplayScreenSize(
data->display);
323 int pixelWidth = (int) CGDisplayPixelsWide(
data->display);
324 int pixelHeight = (int) CGDisplayPixelsHigh(
data->display);
327 *ddpi =
SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH);
330 *hdpi = pixelWidth * MM_IN_INCH / displaySize.width;
333 *vdpi = pixelHeight * MM_IN_INCH / displaySize.height;
343 CVDisplayLinkRef link =
NULL;
344 CGDisplayModeRef desktopmoderef;
348 CVDisplayLinkCreateWithCGDisplay(
data->display, &link);
350 desktopmoderef = CGDisplayCopyDisplayMode(
data->display);
358 if (desktopmoderef && GetDisplayMode(
_this, desktopmoderef, link, &desktopmode)) {
360 CGDisplayModeRelease(desktopmoderef);
364 CGDisplayModeRelease(desktopmoderef);
367 modes = CGDisplayCopyAllDisplayModes(
data->display,
NULL);
371 const CFIndex
count = CFArrayGetCount(modes);
374 CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes,
i);
377 if (GetDisplayMode(
_this, moderef, link, &
mode)) {
379 CGDisplayModeRetain(moderef);
389 CVDisplayLinkRelease(link);
397 CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
401 if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
402 CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0,
TRUE);
409 if (CGDisplayIsMain(displaydata->
display)) {
410 CGReleaseAllDisplays();
412 CGDisplayRelease(displaydata->
display);
415 if (CGDisplayIsMain(displaydata->
display)) {
416 Cocoa_ToggleMenuBar(YES);
420 if (CGDisplayIsMain(displaydata->
display)) {
422 result = CGCaptureAllDisplays();
426 if (
result != kCGErrorSuccess) {
427 CG_SetError(
"CGDisplayCapture()",
result);
433 if (
result != kCGErrorSuccess) {
434 CG_SetError(
"CGDisplaySwitchToMode()",
result);
439 if (CGDisplayIsMain(displaydata->
display)) {
440 Cocoa_ToggleMenuBar(NO);
445 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
446 CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0,
FALSE);
447 CGReleaseDisplayFadeReservation(fade_token);
454 CGDisplayRelease(displaydata->
display);
456 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
457 CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0,
FALSE);
458 CGReleaseDisplayFadeReservation(fade_token);
473 Cocoa_SetDisplayMode(_this, display, &display->desktop_mode);
477 CGDisplayModeRelease(
mode->moderef);
481 CGDisplayModeRelease(
mode->moderef);
485 Cocoa_ToggleMenuBar(YES);