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";
106 int width = (int) CGDisplayModeGetWidth(vidmode);
107 int height = (int) CGDisplayModeGetHeight(vidmode);
115 #ifdef MAC_OS_X_VERSION_10_8
116 if (modelist !=
NULL &&
floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) {
117 int pixelW = (int) CGDisplayModeGetPixelWidth(vidmode);
118 int pixelH = (int) CGDisplayModeGetPixelHeight(vidmode);
120 if (width == pixelW && height == pixelH) {
121 CFIndex modescount = CFArrayGetCount(modelist);
123 for (
int i = 0;
i < modescount;
i++) {
124 CGDisplayModeRef othermode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modelist,
i);
126 if (CFEqual(vidmode, othermode)) {
130 int otherW = (int) CGDisplayModeGetWidth(othermode);
131 int otherH = (int) CGDisplayModeGetHeight(othermode);
133 int otherpixelW = (int) CGDisplayModeGetPixelWidth(othermode);
134 int otherpixelH = (int) CGDisplayModeGetPixelHeight(othermode);
136 if (width == otherW && height == otherH && (otherpixelW != otherW || otherpixelH != otherH)) {
150 fmt = CGDisplayModeCopyPixelEncoding(vidmode);
151 refreshRate = (int) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
153 if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
154 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
156 }
else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
157 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
159 }
else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
160 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
169 if (refreshRate == 0 && link !=
NULL) {
170 CVTime
time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
171 if ((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0) {
172 refreshRate = (int) ((time.timeScale / (
double) time.timeValue) + 0.5);
200 Cocoa_GetDisplayName(CGDirectDisplayID displayID)
202 CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
203 NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
204 const char* displayName =
NULL;
206 if ([localizedNames
count] > 0) {
207 displayName =
SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
209 CFRelease(deviceInfo);
218 CGDirectDisplayID *displays;
219 CGDisplayCount numDisplays;
222 result = CGGetOnlineDisplayList(0,
NULL, &numDisplays);
223 if (result != kCGErrorSuccess) {
224 CG_SetError(
"CGGetOnlineDisplayList()", result);
228 result = CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
229 if (result != kCGErrorSuccess) {
230 CG_SetError(
"CGGetOnlineDisplayList()", result);
236 for (pass = 0; pass < 2; ++pass) {
237 for (i = 0; i < numDisplays; ++i) {
241 CGDisplayModeRef moderef =
NULL;
242 CVDisplayLinkRef link =
NULL;
245 if (!CGDisplayIsMain(displays[i])) {
249 if (CGDisplayIsMain(displays[i])) {
254 if (CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay) {
258 moderef = CGDisplayCopyDisplayMode(displays[i]);
266 CGDisplayModeRelease(moderef);
269 displaydata->
display = displays[i];
271 CVDisplayLinkCreateWithCGDisplay(displays[i], &link);
275 display.
name = (
char *)Cocoa_GetDisplayName(displays[i]);
276 if (!GetDisplayMode(
_this, moderef,
NULL, link, &mode)) {
277 CVDisplayLinkRelease(link);
278 CGDisplayModeRelease(moderef);
284 CVDisplayLinkRelease(link);
302 cgrect = CGDisplayBounds(displaydata->
display);
303 rect->
x = (int)cgrect.origin.x;
304 rect->
y = (
int)cgrect.origin.y;
305 rect->
w = (int)cgrect.size.width;
306 rect->
h = (
int)cgrect.size.height;
314 const CGDirectDisplayID cgdisplay = displaydata->
display;
315 NSArray *screens = [NSScreen screens];
319 for (NSScreen *i
in screens) {
320 const CGDirectDisplayID thisDisplay = (CGDirectDisplayID) [[[i deviceDescription] objectForKey:
@"NSScreenNumber"] unsignedIntValue];
321 if (thisDisplay == cgdisplay) {
332 const CGRect cgrect = CGDisplayBounds(cgdisplay);
333 const NSRect
frame = [screen visibleFrame];
337 rect->
x = (int)(cgrect.origin.x + frame.origin.x);
338 rect->
y = (int)(cgrect.origin.y + frame.origin.y);
339 rect->
w = (int)frame.size.width;
340 rect->
h = (
int)frame.size.height;
348 const float MM_IN_INCH = 25.4f;
352 CGSize displaySize = CGDisplayScreenSize(data->
display);
353 int pixelWidth = (int) CGDisplayPixelsWide(data->
display);
354 int pixelHeight = (int) CGDisplayPixelsHigh(data->
display);
357 *ddpi =
SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH);
360 *hdpi = pixelWidth * MM_IN_INCH / displaySize.width;
363 *vdpi = pixelHeight * MM_IN_INCH / displaySize.height;
373 CFDictionaryRef dict =
NULL;
381 #ifdef MAC_OS_X_VERSION_10_8
382 if (
floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) {
383 const CFStringRef dictkeys[] = {kCGDisplayShowDuplicateLowResolutionModes};
384 const CFBooleanRef dictvalues[] = {kCFBooleanTrue};
385 dict = CFDictionaryCreate(
NULL,
386 (
const void **)dictkeys,
387 (
const void **)dictvalues,
389 &kCFCopyStringDictionaryKeyCallBacks,
390 &kCFTypeDictionaryValueCallBacks);
394 modes = CGDisplayCopyAllDisplayModes(data->
display, dict);
401 CVDisplayLinkRef link =
NULL;
402 const CFIndex
count = CFArrayGetCount(modes);
405 CVDisplayLinkCreateWithCGDisplay(data->
display, &link);
407 for (i = 0; i <
count; i++) {
408 CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
410 if (GetDisplayMode(
_this, moderef, modes, link, &mode)) {
411 CGDisplayModeRetain(moderef);
416 CVDisplayLinkRelease(link);
426 CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
430 if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
431 CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0,
TRUE);
436 CGDisplaySetDisplayMode(displaydata->
display, data->moderef,
NULL);
438 if (CGDisplayIsMain(displaydata->
display)) {
439 CGReleaseAllDisplays();
441 CGDisplayRelease(displaydata->
display);
444 if (CGDisplayIsMain(displaydata->
display)) {
445 Cocoa_ToggleMenuBar(YES);
449 if (CGDisplayIsMain(displaydata->
display)) {
451 result = CGCaptureAllDisplays();
453 result = CGDisplayCapture(displaydata->
display);
455 if (result != kCGErrorSuccess) {
456 CG_SetError(
"CGDisplayCapture()", result);
461 result = CGDisplaySetDisplayMode(displaydata->
display, data->moderef,
NULL);
462 if (result != kCGErrorSuccess) {
463 CG_SetError(
"CGDisplaySwitchToMode()", result);
468 if (CGDisplayIsMain(displaydata->
display)) {
469 Cocoa_ToggleMenuBar(NO);
474 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
475 CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0,
FALSE);
476 CGReleaseDisplayFadeReservation(fade_token);
483 CGDisplayRelease(displaydata->
display);
485 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
486 CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0,
FALSE);
487 CGReleaseDisplayFadeReservation(fade_token);
502 Cocoa_SetDisplayMode(_this, display, &display->desktop_mode);
506 CGDisplayModeRelease(mode->
moderef);
510 CGDisplayModeRelease(mode->
moderef);
514 Cocoa_ToggleMenuBar(YES);
void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
EGLSurface EGLnsecsANDROID time
GLuint GLuint GLsizei count
The structure that defines a display mode.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
CGDirectDisplayID display
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
GLint GLint GLsizei width
int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
static SDL_VideoDevice * _this
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
#define SDL_stack_alloc(type, count)
SDL_DisplayMode * display_modes
int Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hpdi, float *vdpi)
SDL_DisplayMode current_mode
SDL_VideoDisplay * displays
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
#define SDL_assert(condition)
SDL_DisplayMode desktop_mode
GLint GLint GLsizei GLsizei height
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
#define SDL_stack_free(data)
void Cocoa_QuitModes(_THIS)
void Cocoa_InitModes(_THIS)
float SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches)
A rectangle, with the origin at the upper left.