zenilib: zenilib/jni/external/sdl/src/video/cocoa/SDL_cocoamodes.m Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_cocoamodes.m
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 #if SDL_VIDEO_DRIVER_COCOA
24
25 #include "SDL_cocoavideo.h"
26
27 /* We need this for IODisplayCreateInfoDictionary and kIODisplayOnlyPreferredName */
28 #include <IOKit/graphics/IOGraphicsLib.h>
29
30 /* we need this for ShowMenuBar() and HideMenuBar(). */
31 #include <Carbon/Carbon.h>
32
33 /* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */
34 #include <AvailabilityMacros.h>
35
36 static inline void Cocoa_ToggleMenuBar(const BOOL show)
37 {
38 /* !!! FIXME: keep an eye on this.
39 * ShowMenuBar/HideMenuBar is officially unavailable for 64-bit binaries.
40 * It happens to work, as of 10.7, but we're going to see if
41 * we can just simply do without it on newer OSes...
42 */
43 #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__)
44 if (show)
45 ShowMenuBar();
46 else
47 HideMenuBar();
48 #endif
49 }
50
51
52 /* !!! FIXME: clean out the pre-10.6 code when it makes sense to do so. */
53 #define FORCE_OLD_API 0
54
55 #if FORCE_OLD_API
56 #undef MAC_OS_X_VERSION_MIN_REQUIRED
57 #define MAC_OS_X_VERSION_MIN_REQUIRED 1050
58 #endif
59
60 static inline BOOL
61 IS_SNOW_LEOPARD_OR_LATER(_THIS)
62 {
63 #if FORCE_OLD_API
64 return NO;
65 #else
66 return ((((SDL_VideoData *) _this->driverdata))->osversion >= 0x1060);
67 #endif
68 }
69
70 static int
71 CG_SetError(const char *prefix, CGDisplayErr result)
72 {
73 const char *error;
74
75 switch (result) {
76 case kCGErrorFailure:
77 error = "kCGErrorFailure";
78 break;
79 case kCGErrorIllegalArgument:
80 error = "kCGErrorIllegalArgument";
81 break;
82 case kCGErrorInvalidConnection:
83 error = "kCGErrorInvalidConnection";
84 break;
85 case kCGErrorInvalidContext:
86 error = "kCGErrorInvalidContext";
87 break;
88 case kCGErrorCannotComplete:
89 error = "kCGErrorCannotComplete";
90 break;
91 case kCGErrorNotImplemented:
92 error = "kCGErrorNotImplemented";
93 break;
94 case kCGErrorRangeCheck:
95 error = "kCGErrorRangeCheck";
96 break;
97 case kCGErrorTypeCheck:
98 error = "kCGErrorTypeCheck";
99 break;
100 case kCGErrorInvalidOperation:
101 error = "kCGErrorInvalidOperation";
102 break;
103 case kCGErrorNoneAvailable:
104 error = "kCGErrorNoneAvailable";
105 break;
106 default:
107 error = "Unknown Error";
108 break;
109 }
110 return SDL_SetError("%s: %s", prefix, error);
111 }
112
113 static SDL_bool
114 GetDisplayMode(_THIS, const void *moderef, SDL_DisplayMode *mode)
115 {
116 SDL_DisplayModeData *data;
117 long width = 0;
118 long height = 0;
119 long bpp = 0;
120 long refreshRate = 0;
121
122 data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
123 if (!data) {
124 return SDL_FALSE;
125 }
126 data->moderef = moderef;
127
128 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
129 CGDisplayModeRef vidmode = (CGDisplayModeRef) moderef;
130 CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode);
131 width = (long) CGDisplayModeGetWidth(vidmode);
132 height = (long) CGDisplayModeGetHeight(vidmode);
133 refreshRate = (long) CGDisplayModeGetRefreshRate(vidmode);
134
135 if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
136 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
137 bpp = 32;
138 } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
139 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
140 bpp = 16;
141 } else {
142 bpp = 0; /* ignore 8-bit and such for now. */
143 }
144
145 CFRelease(fmt);
146 }
147
148 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
149 if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
150 CFNumberRef number;
151 CFDictionaryRef vidmode = (CFDictionaryRef) moderef;
152 number = CFDictionaryGetValue(vidmode, kCGDisplayWidth);
153 CFNumberGetValue(number, kCFNumberLongType, &width);
154 number = CFDictionaryGetValue(vidmode, kCGDisplayHeight);
155 CFNumberGetValue(number, kCFNumberLongType, &height);
156 number = CFDictionaryGetValue(vidmode, kCGDisplayBitsPerPixel);
157 CFNumberGetValue(number, kCFNumberLongType, &bpp);
158 number = CFDictionaryGetValue(vidmode, kCGDisplayRefreshRate);
159 CFNumberGetValue(number, kCFNumberLongType, &refreshRate);
160 }
161 #endif
162
163 mode->format = SDL_PIXELFORMAT_UNKNOWN;
164 switch (bpp) {
165 case 16:
166 mode->format = SDL_PIXELFORMAT_ARGB1555;
167 break;
168 case 32:
169 mode->format = SDL_PIXELFORMAT_ARGB8888;
170 break;
171 case 8: /* We don't support palettized modes now */
172 default: /* Totally unrecognizable bit depth. */
173 return SDL_FALSE;
174 }
175 mode->w = width;
176 mode->h = height;
177 mode->refresh_rate = refreshRate;
178 mode->driverdata = data;
179 return SDL_TRUE;
180 }
181
182 static inline void
183 Cocoa_ReleaseDisplayMode(_THIS, const void *moderef)
184 {
185 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
186 CGDisplayModeRelease((CGDisplayModeRef) moderef); /* NULL is ok */
187 }
188 }
189
190 static inline void
191 Cocoa_ReleaseDisplayModeList(_THIS, CFArrayRef modelist)
192 {
193 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
194 CFRelease(modelist); /* NULL is ok */
195 }
196 }
197
198 static const char *
199 Cocoa_GetDisplayName(CGDirectDisplayID displayID)
200 {
201 NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
202 NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
203 const char* displayName = NULL;
204
205 if ([localizedNames count] > 0) {
206 displayName = SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
207 }
208 [deviceInfo release];
209 return displayName;
210 }
211
212 void
213 Cocoa_InitModes(_THIS)
214 {
215 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
216 CGDisplayErr result;
217 CGDirectDisplayID *displays;
218 CGDisplayCount numDisplays;
219 int pass, i;
220
221 result = CGGetOnlineDisplayList(0, NULL, &numDisplays);
222 if (result != kCGErrorSuccess) {
223 CG_SetError("CGGetOnlineDisplayList()", result);
224 [pool release];
225 return;
226 }
227 displays = SDL_stack_alloc(CGDirectDisplayID, numDisplays);
228 result = CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
229 if (result != kCGErrorSuccess) {
230 CG_SetError("CGGetOnlineDisplayList()", result);
231 SDL_stack_free(displays);
232 [pool release];
233 return;
234 }
235
236 /* Pick up the primary display in the first pass, then get the rest */
237 for (pass = 0; pass < 2; ++pass) {
238 for (i = 0; i < numDisplays; ++i) {
239 SDL_VideoDisplay display;
240 SDL_DisplayData *displaydata;
241 SDL_DisplayMode mode;
242 const void *moderef = NULL;
243
244 if (pass == 0) {
245 if (!CGDisplayIsMain(displays[i])) {
246 continue;
247 }
248 } else {
249 if (CGDisplayIsMain(displays[i])) {
250 continue;
251 }
252 }
253
254 if (CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay) {
255 continue;
256 }
257
258 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
259 moderef = CGDisplayCopyDisplayMode(displays[i]);
260 }
261
262 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
263 if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
264 moderef = CGDisplayCurrentMode(displays[i]);
265 }
266 #endif
267
268 if (!moderef) {
269 continue;
270 }
271
272 displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
273 if (!displaydata) {
274 Cocoa_ReleaseDisplayMode(_this, moderef);
275 continue;
276 }
277 displaydata->display = displays[i];
278
279 SDL_zero(display);
280 /* this returns a stddup'ed string */
281 display.name = (char *)Cocoa_GetDisplayName(displays[i]);
282 if (!GetDisplayMode (_this, moderef, &mode)) {
283 Cocoa_ReleaseDisplayMode(_this, moderef);
284 SDL_free(display.name);
285 SDL_free(displaydata);
286 continue;
287 }
288
289 display.desktop_mode = mode;
290 display.current_mode = mode;
291 display.driverdata = displaydata;
292 SDL_AddVideoDisplay(&display);
293 SDL_free(display.name);
294 }
295 }
296 SDL_stack_free(displays);
297 [pool release];
298 }
299
300 int
301 Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
302 {
303 SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
304 CGRect cgrect;
305
306 cgrect = CGDisplayBounds(displaydata->display);
307 rect->x = (int)cgrect.origin.x;
308 rect->y = (int)cgrect.origin.y;
309 rect->w = (int)cgrect.size.width;
310 rect->h = (int)cgrect.size.height;
311 return 0;
312 }
313
314 void
315 Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
316 {
317 SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
318 CFArrayRef modes = NULL;
319
320 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
321 modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
322 }
323
324 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
325 if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
326 modes = CGDisplayAvailableModes(data->display);
327 }
328 #endif
329
330 if (modes) {
331 const CFIndex count = CFArrayGetCount(modes);
332 CFIndex i;
333
334 for (i = 0; i < count; i++) {
335 const void *moderef = CFArrayGetValueAtIndex(modes, i);
336 SDL_DisplayMode mode;
337 if (GetDisplayMode(_this, moderef, &mode)) {
338 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
339 CGDisplayModeRetain((CGDisplayModeRef) moderef);
340 }
341 SDL_AddDisplayMode(display, &mode);
342 }
343 }
344
345 Cocoa_ReleaseDisplayModeList(_this, modes);
346 }
347 }
348
349 static CGError
350 Cocoa_SwitchMode(_THIS, CGDirectDisplayID display, const void *mode)
351 {
352 if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
353 return CGDisplaySetDisplayMode(display, (CGDisplayModeRef) mode, NULL);
354 }
355
356 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
357 if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
358 return CGDisplaySwitchToMode(display, (CFDictionaryRef) mode);
359 }
360 #endif
361
362 return kCGErrorFailure;
363 }
364
365 int
366 Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
367 {
368 SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
369 SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
370 CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
371 CGError result;
372
373 /* Fade to black to hide resolution-switching flicker */
374 if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
375 CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
376 }
377
378 if (data == display->desktop_mode.driverdata) {
379 /* Restoring desktop mode */
380 Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
381
382 if (CGDisplayIsMain(displaydata->display)) {
383 CGReleaseAllDisplays();
384 } else {
385 CGDisplayRelease(displaydata->display);
386 }
387
388 if (CGDisplayIsMain(displaydata->display)) {
389 Cocoa_ToggleMenuBar(YES);
390 }
391 } else {
392 /* Put up the blanking window (a window above all other windows) */
393 if (CGDisplayIsMain(displaydata->display)) {
394 /* If we don't capture all displays, Cocoa tries to rearrange windows... *sigh* */
395 result = CGCaptureAllDisplays();
396 } else {
397 result = CGDisplayCapture(displaydata->display);
398 }
399 if (result != kCGErrorSuccess) {
400 CG_SetError("CGDisplayCapture()", result);
401 goto ERR_NO_CAPTURE;
402 }
403
404 /* Do the physical switch */
405 result = Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
406 if (result != kCGErrorSuccess) {
407 CG_SetError("CGDisplaySwitchToMode()", result);
408 goto ERR_NO_SWITCH;
409 }
410
411 /* Hide the menu bar so it doesn't intercept events */
412 if (CGDisplayIsMain(displaydata->display)) {
413 Cocoa_ToggleMenuBar(NO);
414 }
415 }
416
417 /* Fade in again (asynchronously) */
418 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
419 CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
420 CGReleaseDisplayFadeReservation(fade_token);
421 }
422
423 return 0;
424
425 /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
426 ERR_NO_SWITCH:
427 CGDisplayRelease(displaydata->display);
428 ERR_NO_CAPTURE:
429 if (fade_token != kCGDisplayFadeReservationInvalidToken) {
430 CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
431 CGReleaseDisplayFadeReservation(fade_token);
432 }
433 return -1;
434 }
435
436 void
437 Cocoa_QuitModes(_THIS)
438 {
439 int i, j;
440
441 for (i = 0; i < _this->num_displays; ++i) {
442 SDL_VideoDisplay *display = &_this->displays[i];
443 SDL_DisplayModeData *mode;
444
445 if (display->current_mode.driverdata != display->desktop_mode.driverdata) {
446 Cocoa_SetDisplayMode(_this, display, &display->desktop_mode);
447 }
448
449 mode = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
450 Cocoa_ReleaseDisplayMode(_this, mode->moderef);
451
452 for (j = 0; j < display->num_display_modes; j++) {
453 mode = (SDL_DisplayModeData*) display->display_modes[j].driverdata;
454 Cocoa_ReleaseDisplayMode(_this, mode->moderef);
455 }
456
457 }
458 Cocoa_ToggleMenuBar(YES);
459 }
460
461 #endif /* SDL_VIDEO_DRIVER_COCOA */
462
463 /* vi: set ts=4 sw=4 expandtab: */
Cocoa_GetDisplayModes
void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
SDL_DisplayModeData::moderef
const void * moderef
Definition: SDL_cocoamodes.h:33
NULL
#define NULL
Definition: ftobjs.h:61
SDL_DisplayMode::w
int w
Definition: SDL_video.h:56
SDL_stack_free
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:227
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
SDL_VideoDisplay::name
char * name
Definition: SDL_sysvideo.h:115
SDL_TRUE
Definition: SDL_stdinc.h:119
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:314
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
j
int32_t j
Definition: e_log.c:102
SDL_PIXELFORMAT_UNKNOWN
Definition: SDL_pixels.h:149
height
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
SDL_DisplayMode::refresh_rate
int refresh_rate
Definition: SDL_video.h:58
display
char * display
Definition: visualinfo.c:85
SDL_DisplayData::display
CGDirectDisplayID display
Definition: SDL_cocoamodes.h:28
if
if(!yyg->yy_init)
Definition: glslang_lex.cpp:1037
SDL_FALSE
Definition: SDL_stdinc.h:118
SDL_config.h
SDL_AddVideoDisplay
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:568
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_cocoavideo.h
SDL_PIXELFORMAT_ARGB1555
Definition: SDL_pixels.h:188
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
SDL_VideoDisplay::num_display_modes
int num_display_modes
Definition: SDL_sysvideo.h:117
SDL_DisplayModeData
Definition: SDL_cocoamodes.h:31
result
GLuint64EXT * result
Definition: glew.h:12708
Cocoa_SetDisplayMode
int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
int
int
Definition: SDL_systhread.c:37
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
error
FT_Error error
Definition: cffdrivr.c:407
width
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_strdup
DECLSPEC char *SDLCALL SDL_strdup(const char *str)
Definition: SDL_string.c:511
SDL_DisplayMode::driverdata
void * driverdata
Definition: SDL_video.h:59
count
GLint GLsizei count
Definition: gl2ext.h:1011
SDL_VideoDevice::num_displays
int num_displays
Definition: SDL_sysvideo.h:264
SDL_VideoDisplay::display_modes
SDL_DisplayMode * display_modes
Definition: SDL_sysvideo.h:118
SDL_VideoDisplay::current_mode
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
SDL_VideoDevice::displays
SDL_VideoDisplay * displays
Definition: SDL_sysvideo.h:265
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
SDL_malloc
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
SDL_DisplayMode::h
int h
Definition: SDL_video.h:57
SDL_Rect::x
int x
Definition: SDL_rect.h:65
FALSE
#define FALSE
Definition: ftobjs.h:57
SDL_Rect::w
int w
Definition: SDL_rect.h:66
SDL_VideoDisplay
Definition: SDL_sysvideo.h:113
SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:224
SDL_VideoDisplay::desktop_mode
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:119
SDL_Rect::h
int h
Definition: SDL_rect.h:66
SDL_VideoData
Definition: SDL_androidvideo.h:35
SDL_AddDisplayMode
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:666
SDL_stack_alloc
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:226
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
Cocoa_GetDisplayBounds
int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
i
int i
Definition: pngrutil.c:1377
Cocoa_QuitModes
void Cocoa_QuitModes(_THIS)
Cocoa_InitModes
void Cocoa_InitModes(_THIS)
SDL_Rect::y
int y
Definition: SDL_rect.h:65
mode
GLenum mode
Definition: glew.h:2394
TRUE
#define TRUE
Definition: ftobjs.h:53
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:126
BOOL
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC