21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_COCOA 28 #include <IOKit/graphics/IOGraphicsLib.h> 31 #include <CoreVideo/CVBase.h> 32 #include <CoreVideo/CVDisplayLink.h> 35 #include <Carbon/Carbon.h> 38 #include <AvailabilityMacros.h> 42 Cocoa_ToggleMenuBar(
const BOOL show)
49 #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__) 60 #define FORCE_OLD_API 0 63 #undef MAC_OS_X_VERSION_MIN_REQUIRED 64 #define MAC_OS_X_VERSION_MIN_REQUIRED 1050 68 IS_SNOW_LEOPARD_OR_LATER()
73 return floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5;
78 CG_SetError(
const char *prefix, CGDisplayErr
result)
84 error =
"kCGErrorFailure";
86 case kCGErrorIllegalArgument:
87 error =
"kCGErrorIllegalArgument";
89 case kCGErrorInvalidConnection:
90 error =
"kCGErrorInvalidConnection";
92 case kCGErrorInvalidContext:
93 error =
"kCGErrorInvalidContext";
95 case kCGErrorCannotComplete:
96 error =
"kCGErrorCannotComplete";
98 case kCGErrorNotImplemented:
99 error =
"kCGErrorNotImplemented";
101 case kCGErrorRangeCheck:
102 error =
"kCGErrorRangeCheck";
104 case kCGErrorTypeCheck:
105 error =
"kCGErrorTypeCheck";
107 case kCGErrorInvalidOperation:
108 error =
"kCGErrorInvalidOperation";
110 case kCGErrorNoneAvailable:
111 error =
"kCGErrorNoneAvailable";
114 error =
"Unknown Error";
127 long refreshRate = 0;
135 if (IS_SNOW_LEOPARD_OR_LATER()) {
136 CGDisplayModeRef vidmode = (CGDisplayModeRef) moderef;
137 CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode);
138 width = (long) CGDisplayModeGetWidth(vidmode);
139 height = (long) CGDisplayModeGetHeight(vidmode);
140 refreshRate = (long) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
142 if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
143 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
145 }
else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
146 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
148 }
else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
149 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
158 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 159 if (!IS_SNOW_LEOPARD_OR_LATER()) {
162 CFDictionaryRef vidmode = (CFDictionaryRef) moderef;
163 number = CFDictionaryGetValue(vidmode, kCGDisplayWidth);
164 CFNumberGetValue(number, kCFNumberLongType, &width);
165 number = CFDictionaryGetValue(vidmode, kCGDisplayHeight);
166 CFNumberGetValue(number, kCFNumberLongType, &height);
167 number = CFDictionaryGetValue(vidmode, kCGDisplayBitsPerPixel);
168 CFNumberGetValue(number, kCFNumberLongType, &bpp);
169 number = CFDictionaryGetValue(vidmode, kCGDisplayRefreshRate);
170 CFNumberGetValue(number, kCFNumberDoubleType, &refresh);
171 refreshRate = (long) (refresh + 0.5);
176 if (refreshRate == 0 && link !=
NULL) {
177 CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
178 if ((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0) {
179 refreshRate = (long) ((time.timeScale / (
double) time.timeValue) + 0.5);
207 Cocoa_ReleaseDisplayMode(
_THIS,
const void *moderef)
209 if (IS_SNOW_LEOPARD_OR_LATER()) {
210 CGDisplayModeRelease((CGDisplayModeRef) moderef);
215 Cocoa_ReleaseDisplayModeList(
_THIS, CFArrayRef modelist)
217 if (IS_SNOW_LEOPARD_OR_LATER()) {
223 Cocoa_GetDisplayName(CGDirectDisplayID displayID)
225 CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
226 NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
227 const char* displayName =
NULL;
229 if ([localizedNames
count] > 0) {
230 displayName =
SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
232 CFRelease(deviceInfo);
241 CGDirectDisplayID *displays;
242 CGDisplayCount numDisplays;
245 result = CGGetOnlineDisplayList(0,
NULL, &numDisplays);
246 if (result != kCGErrorSuccess) {
247 CG_SetError(
"CGGetOnlineDisplayList()", result);
251 result = CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
252 if (result != kCGErrorSuccess) {
253 CG_SetError(
"CGGetOnlineDisplayList()", result);
259 for (pass = 0; pass < 2; ++pass) {
260 for (i = 0; i < numDisplays; ++i) {
264 const void *moderef =
NULL;
265 CVDisplayLinkRef link =
NULL;
268 if (!CGDisplayIsMain(displays[i])) {
272 if (CGDisplayIsMain(displays[i])) {
277 if (CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay) {
281 if (IS_SNOW_LEOPARD_OR_LATER()) {
282 moderef = CGDisplayCopyDisplayMode(displays[i]);
285 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 286 if (!IS_SNOW_LEOPARD_OR_LATER()) {
287 moderef = CGDisplayCurrentMode(displays[i]);
297 Cocoa_ReleaseDisplayMode(
_this, moderef);
300 displaydata->
display = displays[i];
302 CVDisplayLinkCreateWithCGDisplay(displays[i], &link);
306 display.
name = (
char *)Cocoa_GetDisplayName(displays[i]);
307 if (!GetDisplayMode(
_this, moderef, link, &mode)) {
308 CVDisplayLinkRelease(link);
309 Cocoa_ReleaseDisplayMode(
_this, moderef);
315 CVDisplayLinkRelease(link);
333 cgrect = CGDisplayBounds(displaydata->
display);
334 rect->
x = (int)cgrect.origin.x;
335 rect->
y = (
int)cgrect.origin.y;
336 rect->
w = (int)cgrect.size.width;
337 rect->
h = (
int)cgrect.size.height;
345 CFArrayRef modes =
NULL;
347 if (IS_SNOW_LEOPARD_OR_LATER()) {
348 modes = CGDisplayCopyAllDisplayModes(data->
display,
NULL);
351 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 352 if (!IS_SNOW_LEOPARD_OR_LATER()) {
353 modes = CGDisplayAvailableModes(data->
display);
358 CVDisplayLinkRef link =
NULL;
359 const CFIndex
count = CFArrayGetCount(modes);
362 CVDisplayLinkCreateWithCGDisplay(data->
display, &link);
364 for (i = 0; i <
count; i++) {
365 const void *moderef = CFArrayGetValueAtIndex(modes, i);
367 if (GetDisplayMode(
_this, moderef, link, &mode)) {
368 if (IS_SNOW_LEOPARD_OR_LATER()) {
369 CGDisplayModeRetain((CGDisplayModeRef) moderef);
375 CVDisplayLinkRelease(link);
376 Cocoa_ReleaseDisplayModeList(
_this, modes);
381 Cocoa_SwitchMode(
_THIS, CGDirectDisplayID display,
const void *mode)
383 if (IS_SNOW_LEOPARD_OR_LATER()) {
384 return CGDisplaySetDisplayMode(display, (CGDisplayModeRef) mode,
NULL);
387 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 388 if (!IS_SNOW_LEOPARD_OR_LATER()) {
389 return CGDisplaySwitchToMode(display, (CFDictionaryRef) mode);
393 return kCGErrorFailure;
401 CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
405 if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
406 CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0,
TRUE);
411 Cocoa_SwitchMode(
_this, displaydata->
display, data->moderef);
413 if (CGDisplayIsMain(displaydata->
display)) {
414 CGReleaseAllDisplays();
416 CGDisplayRelease(displaydata->
display);
419 if (CGDisplayIsMain(displaydata->
display)) {
420 Cocoa_ToggleMenuBar(YES);
424 if (CGDisplayIsMain(displaydata->
display)) {
426 result = CGCaptureAllDisplays();
428 result = CGDisplayCapture(displaydata->
display);
430 if (result != kCGErrorSuccess) {
431 CG_SetError(
"CGDisplayCapture()", result);
436 result = Cocoa_SwitchMode(
_this, displaydata->
display, data->moderef);
437 if (result != kCGErrorSuccess) {
438 CG_SetError(
"CGDisplaySwitchToMode()", result);
443 if (CGDisplayIsMain(displaydata->
display)) {
444 Cocoa_ToggleMenuBar(NO);
449 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
450 CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0,
FALSE);
451 CGReleaseDisplayFadeReservation(fade_token);
458 CGDisplayRelease(displaydata->
display);
460 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
461 CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0,
FALSE);
462 CGReleaseDisplayFadeReservation(fade_token);
477 Cocoa_SetDisplayMode(_this, display, &display->desktop_mode);
489 Cocoa_ToggleMenuBar(YES);
void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
GLint GLint GLsizei width
GLuint GLuint GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
The structure that defines a display mode.
GLint GLint GLsizei GLsizei height
CGDirectDisplayID display
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
static SDL_VideoDevice * _this
int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
#define SDL_stack_alloc(type, count)
SDL_DisplayMode * display_modes
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 in i)
SDL_DisplayMode desktop_mode
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)
A rectangle, with the origin at the upper left.
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)